@kynver-app/runtime 0.1.108 → 0.1.116

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 (39) hide show
  1. package/dist/bootstrap.d.ts +1 -0
  2. package/dist/cleanup-git-rev-cache.d.ts +5 -0
  3. package/dist/cleanup-git-status-cache.d.ts +5 -0
  4. package/dist/cleanup-guards.d.ts +2 -0
  5. package/dist/cleanup-index-status.d.ts +8 -1
  6. package/dist/cleanup-run-liveness.d.ts +8 -1
  7. package/dist/cli.js +1929 -468
  8. package/dist/cli.js.map +4 -4
  9. package/dist/daemon-heartbeat.d.ts +20 -0
  10. package/dist/daemon-keeper.d.ts +21 -0
  11. package/dist/daemon-platform-guard.d.ts +2 -0
  12. package/dist/device-login.d.ts +8 -0
  13. package/dist/index.js +2636 -1151
  14. package/dist/index.js.map +4 -4
  15. package/dist/landing/cli-auth.d.ts +5 -1
  16. package/dist/landing/land-pr.d.ts +8 -0
  17. package/dist/provider-evidence/collect.d.ts +18 -0
  18. package/dist/provider-evidence/exec.d.ts +5 -0
  19. package/dist/provider-evidence/index.d.ts +7 -0
  20. package/dist/provider-evidence/recipes-github.d.ts +4 -0
  21. package/dist/provider-evidence/recipes-vercel.d.ts +2 -0
  22. package/dist/provider-evidence/registry.d.ts +6 -0
  23. package/dist/provider-evidence/types.d.ts +48 -0
  24. package/dist/provider-evidence/wanted-store.d.ts +5 -0
  25. package/dist/providers/codex.d.ts +7 -2
  26. package/dist/providers/hermes-codex.d.ts +5 -2
  27. package/dist/server/cleanup.js +560 -164
  28. package/dist/server/cleanup.js.map +4 -4
  29. package/dist/server/default-repo.js +298 -68
  30. package/dist/server/default-repo.js.map +4 -4
  31. package/dist/server/memory-cost-enforce.js +11 -1
  32. package/dist/server/memory-cost-enforce.js.map +3 -3
  33. package/dist/server/monitor.js +356 -128
  34. package/dist/server/monitor.js.map +4 -4
  35. package/dist/server/worker-policy.js +304 -49
  36. package/dist/server/worker-policy.js.map +4 -4
  37. package/dist/status.d.ts +18 -0
  38. package/dist/worker-ops.d.ts +4 -0
  39. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,22 +1,13 @@
1
1
  #!/usr/bin/env node
2
-
3
- // src/cli.ts
4
- import { mkdirSync as mkdirSync10, realpathSync } from "node:fs";
5
- import { fileURLToPath as fileURLToPath5 } from "node:url";
6
-
7
- // src/config.ts
8
- import { existsSync as existsSync9, mkdirSync as mkdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync2 } from "node:fs";
9
- import { homedir as homedir4, totalmem } from "node:os";
10
- import path8 from "node:path";
11
-
12
- // src/default-repo-discovery.ts
13
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
14
- import { homedir as homedir2 } from "node:os";
15
- import path3 from "node:path";
16
- import { fileURLToPath } from "node:url";
17
-
18
- // src/git.ts
19
- import { spawnSync } from "node:child_process";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __esm = (fn, res) => function __init() {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
20
11
 
21
12
  // src/util.ts
22
13
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
@@ -125,42 +116,13 @@ function latestIso(values) {
125
116
  function secsAgo(ms) {
126
117
  return Math.max(0, Math.round((Date.now() - ms) / 1e3));
127
118
  }
119
+ var init_util = __esm({
120
+ "src/util.ts"() {
121
+ "use strict";
122
+ }
123
+ });
128
124
 
129
125
  // src/worker-env.ts
130
- var FORBIDDEN_WORKER_ENV_KEYS = [
131
- "ANTHROPIC_API_KEY",
132
- "ANALYST_API_KEY",
133
- "RECRUITER_API_KEY",
134
- "AUTH_SECRET",
135
- "NEXTAUTH_SECRET",
136
- "DATABASE_URL",
137
- "PRODUCTION_DATABASE_URL",
138
- "KYNVER_PRODUCTION_DATABASE_URL",
139
- "REDIS_URL",
140
- "GOOGLE_CLIENT_SECRET",
141
- "GITHUB_CLIENT_SECRET",
142
- "KYNVER_API_KEY",
143
- "KYNVER_SERVICE_SECRET",
144
- "KYNVER_RUNTIME_SECRET",
145
- "KYNVER_CRON_SECRET",
146
- "OPENCLAW_CRON_SECRET",
147
- "QSTASH_TOKEN",
148
- "QSTASH_CURRENT_SIGNING_KEY",
149
- "QSTASH_NEXT_SIGNING_KEY",
150
- "TOOL_SECRETS_KEK",
151
- "TOOL_EXECUTOR_DISPATCH_SECRET",
152
- "CLOUDFLARE_API_TOKEN",
153
- "STRIPE_SECRET_KEY",
154
- "STRIPE_WEBHOOK_SECRET",
155
- "STRIPE_IDENTITY_WEBHOOK_SECRET",
156
- "VOYAGE_API_KEY",
157
- "PERPLEXITY_API_KEY",
158
- "FRED_API_KEY",
159
- "FMP_API_KEY",
160
- "CURSOR_API_KEY"
161
- ];
162
- var FORBIDDEN_KEY_SET = new Set(FORBIDDEN_WORKER_ENV_KEYS);
163
- var FORBIDDEN_SUFFIXES = ["_SECRET", "_API_KEY"];
164
126
  function isForbiddenWorkerEnvKey(key) {
165
127
  if (FORBIDDEN_KEY_SET.has(key)) return true;
166
128
  return FORBIDDEN_SUFFIXES.some((suffix) => key.endsWith(suffix));
@@ -172,10 +134,55 @@ function scrubWorkerEnv(env) {
172
134
  }
173
135
  return next;
174
136
  }
137
+ var FORBIDDEN_WORKER_ENV_KEYS, FORBIDDEN_KEY_SET, FORBIDDEN_SUFFIXES;
138
+ var init_worker_env = __esm({
139
+ "src/worker-env.ts"() {
140
+ "use strict";
141
+ FORBIDDEN_WORKER_ENV_KEYS = [
142
+ "ANTHROPIC_API_KEY",
143
+ "ANALYST_API_KEY",
144
+ "RECRUITER_API_KEY",
145
+ "AUTH_SECRET",
146
+ "NEXTAUTH_SECRET",
147
+ "DATABASE_URL",
148
+ "PRODUCTION_DATABASE_URL",
149
+ "KYNVER_PRODUCTION_DATABASE_URL",
150
+ "REDIS_URL",
151
+ "GOOGLE_CLIENT_SECRET",
152
+ "GITHUB_CLIENT_SECRET",
153
+ "KYNVER_API_KEY",
154
+ "KYNVER_SERVICE_SECRET",
155
+ "KYNVER_RUNTIME_SECRET",
156
+ "KYNVER_CRON_SECRET",
157
+ "OPENCLAW_CRON_SECRET",
158
+ "QSTASH_TOKEN",
159
+ "QSTASH_CURRENT_SIGNING_KEY",
160
+ "QSTASH_NEXT_SIGNING_KEY",
161
+ "TOOL_SECRETS_KEK",
162
+ "TOOL_EXECUTOR_DISPATCH_SECRET",
163
+ "CLOUDFLARE_API_TOKEN",
164
+ "STRIPE_SECRET_KEY",
165
+ "STRIPE_WEBHOOK_SECRET",
166
+ "STRIPE_IDENTITY_WEBHOOK_SECRET",
167
+ "VOYAGE_API_KEY",
168
+ "PERPLEXITY_API_KEY",
169
+ "FRED_API_KEY",
170
+ "FMP_API_KEY",
171
+ "CURSOR_API_KEY"
172
+ ];
173
+ FORBIDDEN_KEY_SET = new Set(FORBIDDEN_WORKER_ENV_KEYS);
174
+ FORBIDDEN_SUFFIXES = ["_SECRET", "_API_KEY"];
175
+ }
176
+ });
175
177
 
176
178
  // src/git.ts
179
+ import { spawnSync } from "node:child_process";
177
180
  function git(cwd, args, options = {}) {
178
- const res = spawnSync("git", args, { cwd, encoding: "utf8" });
181
+ const res = spawnSync(
182
+ "git",
183
+ args,
184
+ hiddenSpawnOptions({ cwd, encoding: "utf8" })
185
+ );
179
186
  if (res.status !== 0 && !options.allowFailure) {
180
187
  const message = `git ${args.join(" ")} failed: ${res.stderr || res.stdout}`;
181
188
  if (options.throwError) throw new Error(message);
@@ -191,7 +198,11 @@ function gitStatusShort(worktreePath) {
191
198
  }
192
199
  function gitCapture(cwd, args) {
193
200
  try {
194
- const res = spawnSync("git", args, { cwd, encoding: "utf8" });
201
+ const res = spawnSync(
202
+ "git",
203
+ args,
204
+ hiddenSpawnOptions({ cwd, encoding: "utf8" })
205
+ );
195
206
  return {
196
207
  status: res.status,
197
208
  stdout: res.stdout || "",
@@ -289,6 +300,13 @@ function unknownAncestry(base, error, head = null) {
289
300
  error
290
301
  };
291
302
  }
303
+ var init_git = __esm({
304
+ "src/git.ts"() {
305
+ "use strict";
306
+ init_util();
307
+ init_worker_env();
308
+ }
309
+ });
292
310
 
293
311
  // src/path-values.ts
294
312
  import { homedir } from "node:os";
@@ -318,15 +336,17 @@ function redactHomePath(value) {
318
336
  function displayUserPath(value) {
319
337
  return redactHomePath(value);
320
338
  }
339
+ var init_path_values = __esm({
340
+ "src/path-values.ts"() {
341
+ "use strict";
342
+ }
343
+ });
321
344
 
322
345
  // src/default-repo-discovery.ts
323
- var WELL_KNOWN_REPO_DIRS = [
324
- "Kynver",
325
- "repos/Kynver",
326
- "repos/kynver-source-main",
327
- "code/Kynver",
328
- "projects/Kynver"
329
- ];
346
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
347
+ import { homedir as homedir2 } from "node:os";
348
+ import path3 from "node:path";
349
+ import { fileURLToPath } from "node:url";
330
350
  function readPackageName(repoRoot) {
331
351
  const pkgPath = path3.join(repoRoot, "package.json");
332
352
  if (!existsSync2(pkgPath)) return null;
@@ -391,6 +411,21 @@ function discoverDefaultRepoCandidates(opts) {
391
411
  function discoverDefaultRepo(opts) {
392
412
  return discoverDefaultRepoCandidates(opts)[0] ?? null;
393
413
  }
414
+ var WELL_KNOWN_REPO_DIRS;
415
+ var init_default_repo_discovery = __esm({
416
+ "src/default-repo-discovery.ts"() {
417
+ "use strict";
418
+ init_git();
419
+ init_path_values();
420
+ WELL_KNOWN_REPO_DIRS = [
421
+ "Kynver",
422
+ "repos/Kynver",
423
+ "repos/kynver-source-main",
424
+ "code/Kynver",
425
+ "projects/Kynver"
426
+ ];
427
+ }
428
+ });
394
429
 
395
430
  // src/box-identity.ts
396
431
  function normalizeWorkerPoolBoxKind(raw) {
@@ -440,9 +475,11 @@ function resolveBoxIdentity(env = process.env, config = {}) {
440
475
  function resolveBoxKindFromConfig(config = {}, env = process.env) {
441
476
  return resolveBoxIdentity(env, config).boxKind;
442
477
  }
443
-
444
- // src/resource-gate.ts
445
- import os2 from "node:os";
478
+ var init_box_identity = __esm({
479
+ "src/box-identity.ts"() {
480
+ "use strict";
481
+ }
482
+ });
446
483
 
447
484
  // src/bounded-build/meminfo.ts
448
485
  import { readFileSync as readFileSync3 } from "node:fs";
@@ -463,18 +500,14 @@ function readMemAvailableBytes(meminfoText) {
463
500
  }
464
501
  return os.freemem();
465
502
  }
466
-
467
- // src/resource-gate.ts
468
- import path7 from "node:path";
469
-
470
- // src/disk-gate.ts
471
- import { statfsSync as statfsSync2 } from "node:fs";
503
+ var init_meminfo = __esm({
504
+ "src/bounded-build/meminfo.ts"() {
505
+ "use strict";
506
+ }
507
+ });
472
508
 
473
509
  // src/wsl-host.ts
474
510
  import { existsSync as existsSync3, readFileSync as readFileSync4, statfsSync } from "node:fs";
475
- var DEFAULT_WSL_HOST_WARN_FREE_BYTES = 25 * 1024 * 1024 * 1024;
476
- var DEFAULT_WSL_HOST_CRITICAL_FREE_BYTES = 12 * 1024 * 1024 * 1024;
477
- var DEFAULT_WSL_HOST_MOUNT = "/mnt/c";
478
511
  function isWslHost() {
479
512
  if (process.platform !== "linux") return false;
480
513
  for (const probe of ["/proc/sys/kernel/osrelease", "/proc/version"]) {
@@ -490,23 +523,23 @@ function isWslHost() {
490
523
  function observeWslHostDisk(options = {}) {
491
524
  const wsl = options.forceWsl === void 0 ? isWslHost() : options.forceWsl;
492
525
  if (!wsl) return null;
493
- const path71 = options.wslHostMount?.trim() || process.env.KYNVER_WSL_HOST_MOUNT?.trim() || DEFAULT_WSL_HOST_MOUNT;
526
+ const path73 = options.wslHostMount?.trim() || process.env.KYNVER_WSL_HOST_MOUNT?.trim() || DEFAULT_WSL_HOST_MOUNT;
494
527
  const warnBelowBytes = options.wslHostFreeWarnBytes ?? DEFAULT_WSL_HOST_WARN_FREE_BYTES;
495
528
  const criticalBelowBytes = options.wslHostFreeCriticalBytes ?? DEFAULT_WSL_HOST_CRITICAL_FREE_BYTES;
496
529
  const statfs = options.statfs ?? statfsSync;
497
530
  let stats;
498
531
  try {
499
- stats = statfs(path71);
532
+ stats = statfs(path73);
500
533
  } catch (error) {
501
534
  return {
502
535
  ok: false,
503
- path: path71,
536
+ path: path73,
504
537
  freeBytes: 0,
505
538
  totalBytes: 0,
506
539
  usedPercent: 100,
507
540
  warnBelowBytes,
508
541
  criticalBelowBytes,
509
- reason: `Windows host disk probe failed at ${path71}: ${error.message}`,
542
+ reason: `Windows host disk probe failed at ${path73}: ${error.message}`,
510
543
  probeError: error.message
511
544
  };
512
545
  }
@@ -520,11 +553,11 @@ function observeWslHostDisk(options = {}) {
520
553
  let reason = null;
521
554
  if (!ok) {
522
555
  const tag = criticalFree ? "critical" : "warning";
523
- reason = `Windows host disk ${path71} at ${tag}: ${freeGiB} GiB free (<${(criticalFree ? criticalBelowBytes : warnBelowBytes) / 1024 / 1024 / 1024} GiB); WSL VHDX cannot grow safely. ${summarizeWslRecoverySteps()}`;
556
+ reason = `Windows host disk ${path73} at ${tag}: ${freeGiB} GiB free (<${(criticalFree ? criticalBelowBytes : warnBelowBytes) / 1024 / 1024 / 1024} GiB); WSL VHDX cannot grow safely. ${summarizeWslRecoverySteps()}`;
524
557
  }
525
558
  return {
526
559
  ok,
527
- path: path71,
560
+ path: path73,
528
561
  freeBytes,
529
562
  totalBytes,
530
563
  usedPercent,
@@ -537,19 +570,25 @@ function observeWslHostDisk(options = {}) {
537
570
  function summarizeWslRecoverySteps() {
538
571
  return "Recovery: 1) free Windows C: (empty Recycle Bin / Storage Sense / clear %TEMP%); 2) shut down WSL (`wsl --shutdown`) then compact the VHDX (`Optimize-VHD` or `diskpart compact vdisk`); 3) clear local node_modules / .next / harness worktrees before restarting workers. Full runbook: docs/runbooks/wsl-disk-pressure.md.";
539
572
  }
573
+ var DEFAULT_WSL_HOST_WARN_FREE_BYTES, DEFAULT_WSL_HOST_CRITICAL_FREE_BYTES, DEFAULT_WSL_HOST_MOUNT;
574
+ var init_wsl_host = __esm({
575
+ "src/wsl-host.ts"() {
576
+ "use strict";
577
+ DEFAULT_WSL_HOST_WARN_FREE_BYTES = 25 * 1024 * 1024 * 1024;
578
+ DEFAULT_WSL_HOST_CRITICAL_FREE_BYTES = 12 * 1024 * 1024 * 1024;
579
+ DEFAULT_WSL_HOST_MOUNT = "/mnt/c";
580
+ }
581
+ });
540
582
 
541
583
  // src/disk-gate.ts
542
- var DEFAULT_WARN_FREE_BYTES = 30 * 1024 * 1024 * 1024;
543
- var DEFAULT_CRITICAL_FREE_BYTES = 15 * 1024 * 1024 * 1024;
544
- var DEFAULT_MAX_USED_PERCENT = 80;
545
- var DEFAULT_HARD_MAX_USED_PERCENT = 90;
584
+ import { statfsSync as statfsSync2 } from "node:fs";
546
585
  function observeRunnerDiskGate(input = {}) {
547
- const path71 = input.diskPath?.trim() || "/";
586
+ const path73 = input.diskPath?.trim() || "/";
548
587
  const warnBelowBytes = input.diskFreeWarnBytes ?? DEFAULT_WARN_FREE_BYTES;
549
588
  const criticalBelowBytes = input.diskFreeCriticalBytes ?? DEFAULT_CRITICAL_FREE_BYTES;
550
589
  const maxUsedPercent = input.diskMaxUsedPercent ?? DEFAULT_MAX_USED_PERCENT;
551
590
  const hardMaxUsedPercent = input.diskHardMaxUsedPercent ?? DEFAULT_HARD_MAX_USED_PERCENT;
552
- const stats = statfsSync2(path71);
591
+ const stats = statfsSync2(path73);
553
592
  const freeBytes = Number(stats.bavail) * Number(stats.bsize);
554
593
  const totalBytes = Number(stats.blocks) * Number(stats.bsize);
555
594
  const usedPercent = totalBytes > 0 ? (totalBytes - freeBytes) / totalBytes * 100 : 100;
@@ -572,7 +611,7 @@ function observeRunnerDiskGate(input = {}) {
572
611
  }
573
612
  return {
574
613
  ok,
575
- path: path71,
614
+ path: path73,
576
615
  freeBytes,
577
616
  totalBytes,
578
617
  usedPercent,
@@ -584,17 +623,22 @@ function observeRunnerDiskGate(input = {}) {
584
623
  wslHost
585
624
  };
586
625
  }
587
-
588
- // src/run-store.ts
589
- import { existsSync as existsSync5, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
590
- import path5 from "node:path";
626
+ var DEFAULT_WARN_FREE_BYTES, DEFAULT_CRITICAL_FREE_BYTES, DEFAULT_MAX_USED_PERCENT, DEFAULT_HARD_MAX_USED_PERCENT;
627
+ var init_disk_gate = __esm({
628
+ "src/disk-gate.ts"() {
629
+ "use strict";
630
+ init_wsl_host();
631
+ DEFAULT_WARN_FREE_BYTES = 30 * 1024 * 1024 * 1024;
632
+ DEFAULT_CRITICAL_FREE_BYTES = 15 * 1024 * 1024 * 1024;
633
+ DEFAULT_MAX_USED_PERCENT = 80;
634
+ DEFAULT_HARD_MAX_USED_PERCENT = 90;
635
+ }
636
+ });
591
637
 
592
638
  // src/paths.ts
593
639
  import { existsSync as existsSync4 } from "node:fs";
594
640
  import { homedir as homedir3 } from "node:os";
595
641
  import path4 from "node:path";
596
- var LEGACY_ROOT = path4.join(homedir3(), ".openclaw", "harness");
597
- var HARNESS_LAYOUT_DIR_NAMES = /* @__PURE__ */ new Set(["runs", "worktrees"]);
598
642
  function normalizeHarnessRoot(root) {
599
643
  let resolved = path4.resolve(resolveUserPath(root.trim()));
600
644
  while (HARNESS_LAYOUT_DIR_NAMES.has(path4.basename(resolved))) {
@@ -629,8 +673,21 @@ function getHarnessPaths() {
629
673
  function runDir(runsDir, id) {
630
674
  return path4.join(runsDir, safeSlug(id));
631
675
  }
676
+ var LEGACY_ROOT, HARNESS_LAYOUT_DIR_NAMES;
677
+ var init_paths = __esm({
678
+ "src/paths.ts"() {
679
+ "use strict";
680
+ init_config();
681
+ init_path_values();
682
+ init_util();
683
+ LEGACY_ROOT = path4.join(homedir3(), ".openclaw", "harness");
684
+ HARNESS_LAYOUT_DIR_NAMES = /* @__PURE__ */ new Set(["runs", "worktrees"]);
685
+ }
686
+ });
632
687
 
633
688
  // src/run-store.ts
689
+ import { existsSync as existsSync5, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
690
+ import path5 from "node:path";
634
691
  function getPaths() {
635
692
  return getHarnessPaths();
636
693
  }
@@ -688,6 +745,13 @@ function runDirectory(id) {
688
745
  function runDirectoryAt(harnessRoot, id) {
689
746
  return runDir(harnessRunsDir(harnessRoot), safeSlug(id));
690
747
  }
748
+ var init_run_store = __esm({
749
+ "src/run-store.ts"() {
750
+ "use strict";
751
+ init_paths();
752
+ init_util();
753
+ }
754
+ });
691
755
 
692
756
  // src/run-worker-index.ts
693
757
  import { existsSync as existsSync6, readdirSync as readdirSync3 } from "node:fs";
@@ -705,12 +769,13 @@ function listRunWorkerNames(run) {
705
769
  }
706
770
  return [...names];
707
771
  }
708
-
709
- // src/harness-worker-active.ts
710
- import { readFileSync as readFileSync7 } from "node:fs";
711
-
712
- // src/heartbeat.ts
713
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
772
+ var init_run_worker_index = __esm({
773
+ "src/run-worker-index.ts"() {
774
+ "use strict";
775
+ init_run_store();
776
+ init_util();
777
+ }
778
+ });
714
779
 
715
780
  // src/heartbeat-final-result.ts
716
781
  function tryParseJsonObject(text) {
@@ -761,9 +826,14 @@ function terminalFinalResultFromHeartbeatRow(row) {
761
826
  if (embedded) return embedded;
762
827
  return summary;
763
828
  }
829
+ var init_heartbeat_final_result = __esm({
830
+ "src/heartbeat-final-result.ts"() {
831
+ "use strict";
832
+ }
833
+ });
764
834
 
765
835
  // src/heartbeat.ts
766
- var HEARTBEAT_FUTURE_SKEW_MS = 6e4;
836
+ import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
767
837
  function isTerminalHeartbeatPhase(phase) {
768
838
  return phase === "complete";
769
839
  }
@@ -826,29 +896,17 @@ function parseHeartbeat(file) {
826
896
  }
827
897
  return result;
828
898
  }
829
-
830
- // src/stream.ts
831
- import { existsSync as existsSync8, readFileSync as readFileSync6 } from "node:fs";
899
+ var HEARTBEAT_FUTURE_SKEW_MS;
900
+ var init_heartbeat = __esm({
901
+ "src/heartbeat.ts"() {
902
+ "use strict";
903
+ init_heartbeat_final_result();
904
+ init_util();
905
+ HEARTBEAT_FUTURE_SKEW_MS = 6e4;
906
+ }
907
+ });
832
908
 
833
909
  // src/repo-search.ts
834
- var RG_BINARIES = /* @__PURE__ */ new Set(["rg", "ripgrep", "grep"]);
835
- var RG_OPTS_WITH_VALUE = /* @__PURE__ */ new Set([
836
- "-e",
837
- "--regexp",
838
- "-f",
839
- "--file",
840
- "-m",
841
- "--max-count",
842
- "-A",
843
- "--after-context",
844
- "-B",
845
- "--before-context",
846
- "-C",
847
- "--context",
848
- "-g",
849
- "--glob",
850
- "--iglob"
851
- ]);
852
910
  function binaryName(token) {
853
911
  if (!token) return null;
854
912
  const base = token.split("/").pop() ?? token;
@@ -1047,11 +1105,32 @@ function diagnoseRepoSearchFailure(input) {
1047
1105
  }
1048
1106
  return null;
1049
1107
  }
1108
+ var RG_BINARIES, RG_OPTS_WITH_VALUE;
1109
+ var init_repo_search = __esm({
1110
+ "src/repo-search.ts"() {
1111
+ "use strict";
1112
+ RG_BINARIES = /* @__PURE__ */ new Set(["rg", "ripgrep", "grep"]);
1113
+ RG_OPTS_WITH_VALUE = /* @__PURE__ */ new Set([
1114
+ "-e",
1115
+ "--regexp",
1116
+ "-f",
1117
+ "--file",
1118
+ "-m",
1119
+ "--max-count",
1120
+ "-A",
1121
+ "--after-context",
1122
+ "-B",
1123
+ "--before-context",
1124
+ "-C",
1125
+ "--context",
1126
+ "-g",
1127
+ "--glob",
1128
+ "--iglob"
1129
+ ]);
1130
+ }
1131
+ });
1050
1132
 
1051
1133
  // src/shell-command-outcome.ts
1052
- var NPM_AUDIT_RE = /\bnpm\s+audit\b/i;
1053
- var RG_CMD_RE = /\b(rg|ripgrep)\b/i;
1054
- var RG_REAL_ERROR_RE = /\b(error|invalid|unknown|panic|not found)\b/i;
1055
1134
  function tidy(text, max = 200) {
1056
1135
  const one = text.replace(/\s+/g, " ").trim();
1057
1136
  return one.length > max ? `${one.slice(0, max - 1)}\u2026` : one;
@@ -1255,8 +1334,19 @@ function classifyShellCommandOutcome(input) {
1255
1334
  summary: `command failed (exit ${input.exitCode}): ${tail}`
1256
1335
  };
1257
1336
  }
1337
+ var NPM_AUDIT_RE, RG_CMD_RE, RG_REAL_ERROR_RE;
1338
+ var init_shell_command_outcome = __esm({
1339
+ "src/shell-command-outcome.ts"() {
1340
+ "use strict";
1341
+ init_repo_search();
1342
+ NPM_AUDIT_RE = /\bnpm\s+audit\b/i;
1343
+ RG_CMD_RE = /\b(rg|ripgrep)\b/i;
1344
+ RG_REAL_ERROR_RE = /\b(error|invalid|unknown|panic|not found)\b/i;
1345
+ }
1346
+ });
1258
1347
 
1259
1348
  // src/stream.ts
1349
+ import { existsSync as existsSync8, readFileSync as readFileSync6 } from "node:fs";
1260
1350
  function eventTimestampIso(event) {
1261
1351
  const tsMs = event.timestamp_ms;
1262
1352
  return event.timestamp || event.ts || (tsMs ? new Date(tsMs).toISOString() : void 0);
@@ -1422,38 +1512,15 @@ function summarizeEvent(event) {
1422
1512
  }
1423
1513
  return void 0;
1424
1514
  }
1515
+ var init_stream = __esm({
1516
+ "src/stream.ts"() {
1517
+ "use strict";
1518
+ init_shell_command_outcome();
1519
+ init_util();
1520
+ }
1521
+ });
1425
1522
 
1426
1523
  // src/exit-classify.ts
1427
- var FAILURE_PATTERNS = [
1428
- {
1429
- test: /\b(?:invalid|unknown|unsupported|unrecognized)\b[^.\n]*\bmodel\b/i,
1430
- label: "provider rejected the requested model"
1431
- },
1432
- {
1433
- test: /\bmodel\b[^.\n]*\b(?:not\s+(?:found|supported|available|recognized|valid)|is\s+not\s+valid|does\s+not\s+exist)/i,
1434
- label: "provider rejected the requested model"
1435
- },
1436
- {
1437
- test: /\b(?:did you mean|available models|choose (?:a|one of)|supported models)\b/i,
1438
- label: "provider rejected the requested model"
1439
- },
1440
- {
1441
- test: /model preflight failed/i,
1442
- label: "model/provider preflight failed"
1443
- },
1444
- {
1445
- test: /\b(?:command not found|ENOENT|is the .*CLI on PATH|executable not found|no such file or directory)\b/i,
1446
- label: "provider CLI is missing or not on PATH"
1447
- },
1448
- {
1449
- test: /\bfailed to spawn\b/i,
1450
- label: "provider failed to spawn the worker process"
1451
- },
1452
- {
1453
- test: /\b(?:not logged in|unauthorized|authentication (?:failed|required)|invalid api key|missing api key|401)\b/i,
1454
- label: "provider authentication failed"
1455
- }
1456
- ];
1457
1524
  function tidy2(errorText, max = 240) {
1458
1525
  const oneLine2 = errorText.replace(/\s+/g, " ").trim();
1459
1526
  return oneLine2.length > max ? `${oneLine2.slice(0, max - 1)}\u2026` : oneLine2;
@@ -1468,6 +1535,42 @@ function classifyExitFailure(errorText) {
1468
1535
  }
1469
1536
  return null;
1470
1537
  }
1538
+ var FAILURE_PATTERNS;
1539
+ var init_exit_classify = __esm({
1540
+ "src/exit-classify.ts"() {
1541
+ "use strict";
1542
+ FAILURE_PATTERNS = [
1543
+ {
1544
+ test: /\b(?:invalid|unknown|unsupported|unrecognized)\b[^.\n]*\bmodel\b/i,
1545
+ label: "provider rejected the requested model"
1546
+ },
1547
+ {
1548
+ test: /\bmodel\b[^.\n]*\b(?:not\s+(?:found|supported|available|recognized|valid)|is\s+not\s+valid|does\s+not\s+exist)/i,
1549
+ label: "provider rejected the requested model"
1550
+ },
1551
+ {
1552
+ test: /\b(?:did you mean|available models|choose (?:a|one of)|supported models)\b/i,
1553
+ label: "provider rejected the requested model"
1554
+ },
1555
+ {
1556
+ test: /model preflight failed/i,
1557
+ label: "model/provider preflight failed"
1558
+ },
1559
+ {
1560
+ test: /\b(?:command not found|ENOENT|is the .*CLI on PATH|executable not found|no such file or directory)\b/i,
1561
+ label: "provider CLI is missing or not on PATH"
1562
+ },
1563
+ {
1564
+ test: /\bfailed to spawn\b/i,
1565
+ label: "provider failed to spawn the worker process"
1566
+ },
1567
+ {
1568
+ test: /\b(?:not logged in|unauthorized|authentication (?:failed|required)|invalid api key|missing api key|401)\b/i,
1569
+ label: "provider authentication failed"
1570
+ }
1571
+ ];
1572
+ }
1573
+ });
1471
1574
 
1472
1575
  // src/exited-salvage.ts
1473
1576
  function trimOrNull(value) {
@@ -1526,6 +1629,11 @@ function assessExitedWorkerSalvage(input) {
1526
1629
  attentionReason: buildAttentionReason(kind, uncommittedCount, headCommit)
1527
1630
  };
1528
1631
  }
1632
+ var init_exited_salvage = __esm({
1633
+ "src/exited-salvage.ts"() {
1634
+ "use strict";
1635
+ }
1636
+ });
1529
1637
 
1530
1638
  // src/landing-gate.ts
1531
1639
  function trimOrNull2(value) {
@@ -1571,6 +1679,11 @@ function landingAttentionReason(verdict) {
1571
1679
  if (!verdict.blocked) return void 0;
1572
1680
  return verdict.detail ?? verdict.reason ?? "dirty_worktree_no_pr";
1573
1681
  }
1682
+ var init_landing_gate = __esm({
1683
+ "src/landing-gate.ts"() {
1684
+ "use strict";
1685
+ }
1686
+ });
1574
1687
 
1575
1688
  // src/worker-final-result-embed.ts
1576
1689
  function tryParseJsonObject2(text) {
@@ -1620,6 +1733,11 @@ function extractEmbeddedWorkerFinalResultRecord(value) {
1620
1733
  }
1621
1734
  return best;
1622
1735
  }
1736
+ var init_worker_final_result_embed = __esm({
1737
+ "src/worker-final-result-embed.ts"() {
1738
+ "use strict";
1739
+ }
1740
+ });
1623
1741
 
1624
1742
  // src/landing-contract-gate.ts
1625
1743
  function trimOrNull3(value) {
@@ -1779,10 +1897,14 @@ function landingContractAttentionReason(verdict) {
1779
1897
  if (!verdict.blocked) return void 0;
1780
1898
  return verdict.detail ?? verdict.reason;
1781
1899
  }
1900
+ var init_landing_contract_gate = __esm({
1901
+ "src/landing-contract-gate.ts"() {
1902
+ "use strict";
1903
+ init_worker_final_result_embed();
1904
+ }
1905
+ });
1782
1906
 
1783
1907
  // src/status.ts
1784
- var NO_START_MS = 18e4;
1785
- var STALE_MS = 6e5;
1786
1908
  function computeAttention(input) {
1787
1909
  const now = Date.now();
1788
1910
  if (input.completionBlocker && !isSkippedTerminalCompletionBlocker(input.completionBlocker)) {
@@ -1974,7 +2096,15 @@ function computeWorkerStatus(worker, options = {}) {
1974
2096
  changedFiles,
1975
2097
  gitAncestry,
1976
2098
  instructionPolicyFingerprint: worker.instructionPolicyFingerprint ?? null,
1977
- instructionPolicyEvidence: worker.instructionPolicyEvidence ?? null
2099
+ instructionPolicyEvidence: worker.instructionPolicyEvidence ?? null,
2100
+ model: worker.model ?? worker.orchestrationAudit?.model ?? null,
2101
+ provider: worker.orchestrationAudit?.provider ?? null,
2102
+ boxKind: worker.boxKind ?? null,
2103
+ boxId: worker.boxId ?? null,
2104
+ runtimeId: worker.runtimeId ?? null,
2105
+ personaSlug: worker.personaSlug ?? null,
2106
+ dispatched: worker.dispatched ?? null,
2107
+ localOnly: worker.localOnly ?? null
1978
2108
  };
1979
2109
  }
1980
2110
  function isFinishedWorkerStatus(status) {
@@ -1996,8 +2126,26 @@ function deriveRunStatus(fallback, workers) {
1996
2126
  if (workers.some((w) => w.status === "running")) return "running";
1997
2127
  return fallback;
1998
2128
  }
2129
+ var NO_START_MS, STALE_MS;
2130
+ var init_status = __esm({
2131
+ "src/status.ts"() {
2132
+ "use strict";
2133
+ init_heartbeat();
2134
+ init_stream();
2135
+ init_exit_classify();
2136
+ init_exited_salvage();
2137
+ init_git();
2138
+ init_landing_gate();
2139
+ init_landing_contract_gate();
2140
+ init_worker_final_result_embed();
2141
+ init_util();
2142
+ NO_START_MS = 18e4;
2143
+ STALE_MS = 6e5;
2144
+ }
2145
+ });
1999
2146
 
2000
2147
  // src/harness-worker-active.ts
2148
+ import { readFileSync as readFileSync7 } from "node:fs";
2001
2149
  function pidCommandLine(pid) {
2002
2150
  if (!pid || process.platform !== "linux") return null;
2003
2151
  try {
@@ -2023,12 +2171,16 @@ function isActiveHarnessWorker(worker) {
2023
2171
  if (status.alive && !workerProcessMatchesRecord(worker)) return false;
2024
2172
  return status.alive && !status.finalResult && status.attention.state !== "done";
2025
2173
  }
2174
+ var init_harness_worker_active = __esm({
2175
+ "src/harness-worker-active.ts"() {
2176
+ "use strict";
2177
+ init_status();
2178
+ }
2179
+ });
2026
2180
 
2027
2181
  // src/resource-gate.ts
2028
- var DEFAULT_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
2029
- var DEFAULT_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
2030
- var DEFAULT_MEM_UTILIZATION = 0.85;
2031
- var AUTO_MAX_WORKERS_CEILING = 64;
2182
+ import os2 from "node:os";
2183
+ import path7 from "node:path";
2032
2184
  function positiveInt(value, fallback) {
2033
2185
  const n = Number(value);
2034
2186
  if (!Number.isFinite(n) || n <= 0) return fallback;
@@ -2134,6 +2286,25 @@ function observeRunnerResourceGate(input) {
2134
2286
  ...diskGate ? { diskGate } : {}
2135
2287
  };
2136
2288
  }
2289
+ var DEFAULT_PER_WORKER_MEM_BYTES, DEFAULT_MEM_RESERVE_BYTES, DEFAULT_MEM_UTILIZATION, AUTO_MAX_WORKERS_CEILING;
2290
+ var init_resource_gate = __esm({
2291
+ "src/resource-gate.ts"() {
2292
+ "use strict";
2293
+ init_meminfo();
2294
+ init_config();
2295
+ init_box_identity();
2296
+ init_worker_cap_source();
2297
+ init_disk_gate();
2298
+ init_run_store();
2299
+ init_run_worker_index();
2300
+ init_harness_worker_active();
2301
+ init_util();
2302
+ DEFAULT_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
2303
+ DEFAULT_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
2304
+ DEFAULT_MEM_UTILIZATION = 0.85;
2305
+ AUTO_MAX_WORKERS_CEILING = 64;
2306
+ }
2307
+ });
2137
2308
 
2138
2309
  // src/worker-cap-source.ts
2139
2310
  function positiveInt2(value, fallback) {
@@ -2205,12 +2376,113 @@ function recommendSetupWorkerCap(input = {}) {
2205
2376
  diskFreeBytes: input.diskFreeBytes ?? null
2206
2377
  };
2207
2378
  }
2379
+ var init_worker_cap_source = __esm({
2380
+ "src/worker-cap-source.ts"() {
2381
+ "use strict";
2382
+ init_resource_gate();
2383
+ }
2384
+ });
2208
2385
 
2209
- // src/config.ts
2386
+ // src/device-login.ts
2387
+ var device_login_exports = {};
2388
+ __export(device_login_exports, {
2389
+ runDeviceLogin: () => runDeviceLogin
2390
+ });
2210
2391
  import os3 from "node:os";
2211
- var CONFIG_DIR = path8.join(homedir4(), ".kynver");
2212
- var CONFIG_FILE = path8.join(CONFIG_DIR, "config.json");
2213
- var CREDENTIALS_FILE = path8.join(CONFIG_DIR, "credentials");
2392
+ function resolveDeviceBaseUrl(args) {
2393
+ const raw = (typeof args.apiBaseUrl === "string" ? args.apiBaseUrl : void 0) || (typeof args.baseUrl === "string" ? args.baseUrl : void 0) || process.env.KYNVER_API_URL || loadUserConfig().apiBaseUrl;
2394
+ return raw ? trimTrailingSlash(String(raw)) : void 0;
2395
+ }
2396
+ async function sleep(ms) {
2397
+ await new Promise((resolve) => setTimeout(resolve, ms));
2398
+ }
2399
+ async function runDeviceLogin(args) {
2400
+ const base = resolveDeviceBaseUrl(args);
2401
+ if (!base) {
2402
+ console.error(
2403
+ "kynver login (device flow) requires a Kynver URL \u2014 pass --api-base-url https://your-kynver-site, set KYNVER_API_URL, or run `kynver setup` first."
2404
+ );
2405
+ return { ok: false };
2406
+ }
2407
+ const clientName = `${os3.hostname()} (${os3.platform()})`;
2408
+ let start;
2409
+ try {
2410
+ const res = await fetch(`${base}/api/auth/device/code`, {
2411
+ method: "POST",
2412
+ headers: { "Content-Type": "application/json" },
2413
+ body: JSON.stringify({ clientName })
2414
+ });
2415
+ if (!res.ok) {
2416
+ console.error(`Could not start device authorization (${res.status}).`);
2417
+ return { ok: false };
2418
+ }
2419
+ start = await res.json();
2420
+ } catch (err) {
2421
+ console.error(`Could not reach ${base}: ${err.message}`);
2422
+ return { ok: false };
2423
+ }
2424
+ const verifyUrl = start.verification_uri_complete || start.verification_uri;
2425
+ console.log("");
2426
+ console.log(" Authorize this machine:");
2427
+ console.log(` 1. Open: ${verifyUrl}`);
2428
+ console.log(` 2. Confirm the code: ${start.user_code}`);
2429
+ console.log("");
2430
+ console.log(" Waiting for approval\u2026");
2431
+ const deadline = Date.now() + start.expires_in * 1e3;
2432
+ let intervalMs = Math.max(1, start.interval) * 1e3;
2433
+ while (Date.now() < deadline) {
2434
+ await sleep(intervalMs);
2435
+ let body;
2436
+ try {
2437
+ const res = await fetch(`${base}/api/auth/device/token`, {
2438
+ method: "POST",
2439
+ headers: { "Content-Type": "application/json" },
2440
+ body: JSON.stringify({ device_code: start.device_code })
2441
+ });
2442
+ body = await res.json().catch(() => ({}));
2443
+ } catch {
2444
+ continue;
2445
+ }
2446
+ switch (body.status) {
2447
+ case "approved":
2448
+ if (body.api_key) {
2449
+ saveApiKey(body.api_key);
2450
+ console.log(" Approved \u2014 this machine is now linked to your Kynver account.");
2451
+ return { ok: true, apiKey: body.api_key };
2452
+ }
2453
+ return { ok: false };
2454
+ case "slow_down":
2455
+ intervalMs += 2e3;
2456
+ break;
2457
+ case "authorization_pending":
2458
+ if (typeof body.interval === "number") intervalMs = Math.max(intervalMs, body.interval * 1e3);
2459
+ break;
2460
+ case "access_denied":
2461
+ console.error(" Request was denied in the browser.");
2462
+ return { ok: false };
2463
+ case "expired_token":
2464
+ console.error(" The code expired before it was approved. Run `kynver login` again.");
2465
+ return { ok: false };
2466
+ default:
2467
+ break;
2468
+ }
2469
+ }
2470
+ console.error(" Timed out waiting for approval. Run `kynver login` again.");
2471
+ return { ok: false };
2472
+ }
2473
+ var init_device_login = __esm({
2474
+ "src/device-login.ts"() {
2475
+ "use strict";
2476
+ init_config();
2477
+ init_util();
2478
+ }
2479
+ });
2480
+
2481
+ // src/config.ts
2482
+ import { existsSync as existsSync9, mkdirSync as mkdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync2 } from "node:fs";
2483
+ import { homedir as homedir4, totalmem } from "node:os";
2484
+ import path8 from "node:path";
2485
+ import os4 from "node:os";
2214
2486
  function loadUserConfig() {
2215
2487
  if (!existsSync9(CONFIG_FILE)) return {};
2216
2488
  try {
@@ -2249,8 +2521,6 @@ function inferSetupFields(existing, args) {
2249
2521
  ...typeof args.agentOsSlug === "string" ? { agentOsSlug: args.agentOsSlug } : existing.agentOsSlug ? { agentOsSlug: existing.agentOsSlug } : {}
2250
2522
  };
2251
2523
  }
2252
- var SETUP_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
2253
- var SETUP_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
2254
2524
  function resolveSetupWorkerConfig(existing, args, totalMemBytes = totalmem()) {
2255
2525
  const maxWorkersRaw = typeof args.maxWorkers === "string" ? args.maxWorkers : typeof args.maxConcurrentWorkers === "string" ? args.maxConcurrentWorkers : void 0;
2256
2526
  const explicitBoxKindArg = typeof args.boxKind === "string" ? args.boxKind : typeof args["box-kind"] === "string" ? String(args["box-kind"]) : void 0;
@@ -2471,7 +2741,7 @@ async function runSetup(args) {
2471
2741
  diskPath: typeof args.diskPath === "string" ? args.diskPath : "/"
2472
2742
  });
2473
2743
  const capRecommendation = recommendSetupWorkerCap({
2474
- totalMemBytes: os3.totalmem(),
2744
+ totalMemBytes: os4.totalmem(),
2475
2745
  diskPath: diskGate.path,
2476
2746
  diskGateOk: diskGate.ok,
2477
2747
  diskFreeBytes: diskGate.freeBytes,
@@ -2520,10 +2790,104 @@ async function runSetup(args) {
2520
2790
  }
2521
2791
  async function runLogin(args) {
2522
2792
  const apiKey = typeof args.apiKey === "string" ? args.apiKey : process.env.KYNVER_API_KEY;
2523
- if (!apiKey) failConfig("kynver login requires --api-key or KYNVER_API_KEY");
2524
- saveApiKey(apiKey);
2793
+ if (apiKey) {
2794
+ saveApiKey(apiKey);
2795
+ console.log(JSON.stringify({ ok: true, credentialsPath: displayUserPath(CREDENTIALS_FILE) }, null, 2));
2796
+ return;
2797
+ }
2798
+ const { runDeviceLogin: runDeviceLogin2 } = await Promise.resolve().then(() => (init_device_login(), device_login_exports));
2799
+ const result = await runDeviceLogin2(args);
2800
+ if (!result.ok) process.exit(1);
2525
2801
  console.log(JSON.stringify({ ok: true, credentialsPath: displayUserPath(CREDENTIALS_FILE) }, null, 2));
2526
2802
  }
2803
+ var CONFIG_DIR, CONFIG_FILE, CREDENTIALS_FILE, SETUP_PER_WORKER_MEM_BYTES, SETUP_MEM_RESERVE_BYTES;
2804
+ var init_config = __esm({
2805
+ "src/config.ts"() {
2806
+ "use strict";
2807
+ init_default_repo_discovery();
2808
+ init_path_values();
2809
+ init_util();
2810
+ init_box_identity();
2811
+ init_worker_cap_source();
2812
+ init_disk_gate();
2813
+ CONFIG_DIR = path8.join(homedir4(), ".kynver");
2814
+ CONFIG_FILE = path8.join(CONFIG_DIR, "config.json");
2815
+ CREDENTIALS_FILE = path8.join(CONFIG_DIR, "credentials");
2816
+ SETUP_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
2817
+ SETUP_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
2818
+ }
2819
+ });
2820
+
2821
+ // src/cli.ts
2822
+ init_config();
2823
+ import { mkdirSync as mkdirSync11, realpathSync } from "node:fs";
2824
+ import { fileURLToPath as fileURLToPath5 } from "node:url";
2825
+
2826
+ // src/bootstrap.ts
2827
+ init_config();
2828
+ init_util();
2829
+ init_device_login();
2830
+ import os5 from "node:os";
2831
+ function resolveBootstrapBaseUrl(args) {
2832
+ const raw = (typeof args.apiBaseUrl === "string" ? args.apiBaseUrl : void 0) || (typeof args.baseUrl === "string" ? args.baseUrl : void 0) || process.env.KYNVER_API_URL || loadUserConfig().apiBaseUrl;
2833
+ return raw ? trimTrailingSlash(String(raw)) : void 0;
2834
+ }
2835
+ async function fetchPrimaryAgentOs(base, apiKey) {
2836
+ const res = await fetch(`${base}/api/agent-os`, {
2837
+ headers: { Authorization: `Bearer ${apiKey}` }
2838
+ });
2839
+ if (!res.ok) return null;
2840
+ const body = await res.json().catch(() => null);
2841
+ if (!body?.primarySlug) return null;
2842
+ const match = body.items?.find((it) => it.slug === body.primarySlug);
2843
+ if (match?.id && match.slug) return { id: match.id, slug: match.slug };
2844
+ return { id: "", slug: body.primarySlug };
2845
+ }
2846
+ async function runBootstrap(args) {
2847
+ const base = resolveBootstrapBaseUrl(args);
2848
+ if (!base) {
2849
+ console.error(
2850
+ "kynver bootstrap requires a Kynver URL \u2014 pass --api-base-url https://your-kynver-site or set KYNVER_API_URL."
2851
+ );
2852
+ process.exit(1);
2853
+ }
2854
+ if (!loadApiKey()) {
2855
+ if (typeof args.apiKey === "string") {
2856
+ saveApiKey(args.apiKey);
2857
+ } else {
2858
+ const login = await runDeviceLogin({ ...args, apiBaseUrl: base });
2859
+ if (!login.ok) process.exit(1);
2860
+ }
2861
+ }
2862
+ const apiKey = loadApiKey();
2863
+ if (!apiKey) {
2864
+ console.error("No API key after login \u2014 aborting.");
2865
+ process.exit(1);
2866
+ }
2867
+ const primary = await fetchPrimaryAgentOs(base, apiKey);
2868
+ if (!primary) {
2869
+ console.error(
2870
+ "Could not resolve your AgentOS workspace from the account. Confirm this account has AgentOS access, then retry."
2871
+ );
2872
+ process.exit(1);
2873
+ }
2874
+ const setupArgs = {
2875
+ ...args,
2876
+ apiBaseUrl: base,
2877
+ agentOsSlug: primary.slug,
2878
+ ...primary.id ? { agentOsId: primary.id } : {},
2879
+ // Best-effort repo discovery unless the caller pinned one.
2880
+ ...typeof args.repo === "string" ? {} : { discoverRepo: true }
2881
+ };
2882
+ await runSetup(setupArgs);
2883
+ console.log("");
2884
+ console.log(` Bootstrap complete \u2014 ${os5.hostname()} is linked to workspace "${primary.slug}".`);
2885
+ console.log(" Next: run autonomous work with `kynver daemon --run <RUN_ID> --agent-os-id <AOS_ID> --execute`");
2886
+ console.log(" (create a run first with `kynver run create --repo /path/to/repo`).");
2887
+ }
2888
+
2889
+ // src/dispatch.ts
2890
+ init_config();
2527
2891
 
2528
2892
  // src/callback-headers.ts
2529
2893
  function buildHarnessCallbackHeaders(secret) {
@@ -2547,6 +2911,7 @@ function buildHarnessCallbackHeaders(secret) {
2547
2911
  }
2548
2912
 
2549
2913
  // src/callbacks.ts
2914
+ init_config();
2550
2915
  function callbackTimeoutMs() {
2551
2916
  const parsed = Number(process.env.KYNVER_CALLBACK_TIMEOUT_MS);
2552
2917
  if (Number.isFinite(parsed) && parsed > 0) return Math.floor(parsed);
@@ -2760,6 +3125,12 @@ function resolveDispatchNextLaneFilter(raw) {
2760
3125
  return normalizeDispatchNextLaneFilter(raw) ?? "any";
2761
3126
  }
2762
3127
 
3128
+ // src/dispatch.ts
3129
+ init_disk_gate();
3130
+ init_resource_gate();
3131
+ init_run_store();
3132
+ init_run_store();
3133
+
2763
3134
  // src/model-routing-task-enrich.ts
2764
3135
  function taskString(task, key) {
2765
3136
  const v = task[key];
@@ -2809,6 +3180,9 @@ function enrichTaskForModelRouting(task) {
2809
3180
  return { ...task, roleLane };
2810
3181
  }
2811
3182
 
3183
+ // src/model-routing.ts
3184
+ init_config();
3185
+
2812
3186
  // src/worker-provider-policy.ts
2813
3187
  var DEFAULT_WORKER_PROVIDER = "cursor";
2814
3188
  var CLAUDE_FAMILY = /* @__PURE__ */ new Set(["claude", "opus", "anthropic"]);
@@ -3472,6 +3846,8 @@ function resolveOrchestrationRouting(input) {
3472
3846
  }
3473
3847
 
3474
3848
  // src/providers/claude.ts
3849
+ init_worker_env();
3850
+ init_util();
3475
3851
  import { closeSync, openSync } from "node:fs";
3476
3852
  import { spawn } from "node:child_process";
3477
3853
 
@@ -3609,13 +3985,17 @@ var claudeProvider = {
3609
3985
  };
3610
3986
 
3611
3987
  // src/providers/codex.ts
3988
+ init_worker_env();
3989
+ init_util();
3612
3990
  import { closeSync as closeSync3, existsSync as existsSync15, openSync as openSync3 } from "node:fs";
3613
3991
  import { spawn as spawn3 } from "node:child_process";
3614
3992
 
3615
3993
  // src/providers/hermes-codex.ts
3994
+ init_worker_env();
3995
+ init_util();
3616
3996
  import { closeSync as closeSync2, openSync as openSync2 } from "node:fs";
3617
3997
  import { spawn as spawn2 } from "node:child_process";
3618
- var HERMES_OPENAI_CODEX_DEFAULT_MODEL = "gpt-5.4";
3998
+ var HERMES_OPENAI_CODEX_DEFAULT_MODEL = process.env.KYNVER_CODEX_DEFAULT_MODEL?.trim() || "gpt-5.4";
3619
3999
  function hermesWorkerEnv() {
3620
4000
  return scrubWorkerEnv({
3621
4001
  ...process.env,
@@ -3683,7 +4063,10 @@ var hermesCodexProvider = {
3683
4063
  };
3684
4064
 
3685
4065
  // src/providers/codex.ts
3686
- var CODEX_DEFAULT_MODEL = "gpt-5.4";
4066
+ function resolveCodexDefaultModel() {
4067
+ return process.env.KYNVER_CODEX_DEFAULT_MODEL?.trim() || "gpt-5.4";
4068
+ }
4069
+ var CODEX_DEFAULT_MODEL = resolveCodexDefaultModel();
3687
4070
  function resolveCodexBin() {
3688
4071
  return process.env.KYNVER_CODEX_BIN?.trim() || process.env.CODEX_BIN?.trim() || "codex";
3689
4072
  }
@@ -3935,7 +4318,11 @@ function readHarnessRetryLimits() {
3935
4318
  }
3936
4319
 
3937
4320
  // src/lease-renewal.ts
4321
+ init_config();
3938
4322
  import path14 from "node:path";
4323
+ init_run_store();
4324
+ init_status();
4325
+ init_util();
3939
4326
 
3940
4327
  // src/harness-lease-owner.ts
3941
4328
  var HARNESS_LEASE_PREFIX = "kynver-harness:";
@@ -3971,12 +4358,14 @@ function resolveHarnessLeaseOwnerForRenewal(input) {
3971
4358
  }
3972
4359
 
3973
4360
  // src/runner-identity.ts
3974
- import os5 from "node:os";
4361
+ import os7 from "node:os";
3975
4362
 
3976
4363
  // src/box-resource-snapshot-shared.ts
3977
- import os4 from "node:os";
4364
+ init_box_identity();
4365
+ init_box_identity();
4366
+ import os6 from "node:os";
3978
4367
  function defaultBoxId(boxKind, hostLabel) {
3979
- const host = (hostLabel ?? os4.hostname()).trim().toLowerCase().replace(/\s+/g, "-") || "unknown-host";
4368
+ const host = (hostLabel ?? os6.hostname()).trim().toLowerCase().replace(/\s+/g, "-") || "unknown-host";
3980
4369
  return `${boxKind}:${host}`;
3981
4370
  }
3982
4371
 
@@ -3987,10 +4376,10 @@ function trimOrNull5(value) {
3987
4376
  }
3988
4377
  function resolveRunnerPresencePayload(input = {}) {
3989
4378
  const env = input.env ?? process.env;
3990
- const runnerId = trimOrNull5(env.KYNVER_RUNTIME_ID) ?? trimOrNull5(env.OPENCLAW_RUNTIME_ID) ?? trimOrNull5(env.HOSTNAME) ?? os5.hostname();
4379
+ const runnerId = trimOrNull5(env.KYNVER_RUNTIME_ID) ?? trimOrNull5(env.OPENCLAW_RUNTIME_ID) ?? trimOrNull5(env.HOSTNAME) ?? os7.hostname();
3991
4380
  return {
3992
4381
  runnerId,
3993
- hostname: trimOrNull5(env.HOSTNAME) ?? os5.hostname(),
4382
+ hostname: trimOrNull5(env.HOSTNAME) ?? os7.hostname(),
3994
4383
  profile: trimOrNull5(env.KYNVER_RUNNER_PROFILE) ?? trimOrNull5(env.OPENCLAW_RUNNER_PROFILE),
3995
4384
  harnessRepo: trimOrNull5(env.KYNVER_HARNESS_REPO) ?? trimOrNull5(env.KYNVER_DEFAULT_REPO),
3996
4385
  runId: input.runId ?? null
@@ -4075,6 +4464,9 @@ function hasLiveWorkerForTask(runId, taskId) {
4075
4464
  }
4076
4465
 
4077
4466
  // src/supervisor.ts
4467
+ init_git();
4468
+ init_run_store();
4469
+ init_run_store();
4078
4470
  import { existsSync as existsSync19, mkdirSync as mkdirSync4 } from "node:fs";
4079
4471
  import path21 from "node:path";
4080
4472
 
@@ -4224,10 +4616,18 @@ function buildPrompt(input) {
4224
4616
  ].join("\n");
4225
4617
  }
4226
4618
 
4619
+ // src/supervisor.ts
4620
+ init_util();
4621
+
4622
+ // src/providers/registry.ts
4623
+ init_config();
4624
+
4227
4625
  // src/providers/cursor.ts
4626
+ init_util();
4627
+ init_worker_env();
4228
4628
  import { closeSync as closeSync4, existsSync as existsSync17, mkdirSync as mkdirSync3, openSync as openSync4, statSync as statSync4, unlinkSync } from "node:fs";
4229
4629
  import { spawn as spawn4 } from "node:child_process";
4230
- import os6 from "node:os";
4630
+ import os8 from "node:os";
4231
4631
  import path16 from "node:path";
4232
4632
 
4233
4633
  // src/providers/cursor-windows.ts
@@ -4338,7 +4738,7 @@ function positiveIntEnv(name, fallback) {
4338
4738
  return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : fallback;
4339
4739
  }
4340
4740
  function cursorStartLockPath() {
4341
- const root = process.env.KYNVER_CURSOR_START_LOCK_DIR?.trim() || path16.join(os6.homedir(), ".kynver", "locks");
4741
+ const root = process.env.KYNVER_CURSOR_START_LOCK_DIR?.trim() || path16.join(os8.homedir(), ".kynver", "locks");
4342
4742
  mkdirSync3(root, { recursive: true });
4343
4743
  return path16.join(root, "cursor-agent-start.lock");
4344
4744
  }
@@ -4464,12 +4864,14 @@ function resolveWorkerProvider(name) {
4464
4864
  }
4465
4865
 
4466
4866
  // src/auto-complete.ts
4867
+ init_util();
4467
4868
  import { spawn as spawn5 } from "node:child_process";
4468
4869
  import { existsSync as existsSync18, openSync as openSync5, closeSync as closeSync5 } from "node:fs";
4469
4870
  import path20 from "node:path";
4470
4871
  import { fileURLToPath as fileURLToPath2 } from "node:url";
4471
4872
 
4472
4873
  // src/completion-ack.ts
4874
+ init_run_store();
4473
4875
  function hasCompletionAck(worker) {
4474
4876
  return Boolean(worker.completionReportedAt?.trim());
4475
4877
  }
@@ -4497,7 +4899,12 @@ function hasTerminalCompletionAck(worker) {
4497
4899
  return hasCompletionAck(worker) && !shouldReplayHarnessCompletion(worker);
4498
4900
  }
4499
4901
 
4902
+ // src/auto-complete.ts
4903
+ init_run_store();
4904
+ init_status();
4905
+
4500
4906
  // src/worker-ops.ts
4907
+ init_config();
4501
4908
  import path19 from "node:path";
4502
4909
 
4503
4910
  // src/completion-response.ts
@@ -4539,6 +4946,10 @@ function completionPostSucceeded(summary) {
4539
4946
  return summary.taskAdvanced;
4540
4947
  }
4541
4948
 
4949
+ // src/worker-ops.ts
4950
+ init_run_store();
4951
+ init_exited_salvage();
4952
+
4542
4953
  // src/harness-expert-review.ts
4543
4954
  var EXPERT_LANE_REVIEW_REF = "expert-lane-pr-review:";
4544
4955
  var PLAN_REVIEW_EXECUTOR_REF = "plan-review-task";
@@ -4706,6 +5117,7 @@ function normalizeOwnerRepo(value) {
4706
5117
  }
4707
5118
 
4708
5119
  // src/pr-handoff/pr-handoff-gh.ts
5120
+ init_git();
4709
5121
  function capture(bin, cwd, args) {
4710
5122
  try {
4711
5123
  const res = spawnSync3(bin, args, { cwd, encoding: "utf8" });
@@ -5076,6 +5488,10 @@ function ensurePrReadyHandoff(input, exec = defaultPrHandoffExec) {
5076
5488
  };
5077
5489
  }
5078
5490
 
5491
+ // src/worker-ops.ts
5492
+ init_status();
5493
+ init_stream();
5494
+
5079
5495
  // src/material-worktree-changes.ts
5080
5496
  function materialWorktreeChanges(changedFiles) {
5081
5497
  return changedFiles.filter((line) => {
@@ -5118,8 +5534,8 @@ function dirtyPathsCoveredByDisposableRemoval(changedFiles, removed) {
5118
5534
  if (removed.length === 0) return false;
5119
5535
  const removedSet = new Set(removed.map((p) => normalizeRelativePath(p)));
5120
5536
  return material.every((line) => {
5121
- const path71 = normalizeRelativePath(pathFromGitStatusLine(line));
5122
- return removedSet.has(path71);
5537
+ const path73 = normalizeRelativePath(pathFromGitStatusLine(line));
5538
+ return removedSet.has(path73);
5123
5539
  });
5124
5540
  }
5125
5541
 
@@ -5204,6 +5620,9 @@ function assessWorktreeCompletionHandoff(input) {
5204
5620
  }
5205
5621
 
5206
5622
  // src/worker-lifecycle.ts
5623
+ init_run_store();
5624
+ init_status();
5625
+ init_util();
5207
5626
  import path17 from "node:path";
5208
5627
  var TASK_LEFT_RUNNING = /* @__PURE__ */ new Set([
5209
5628
  "awaiting_review",
@@ -5295,7 +5714,11 @@ function syncCompletionAcknowledgedFromOperatorTick(runId, operatorTick) {
5295
5714
  return synced;
5296
5715
  }
5297
5716
 
5717
+ // src/worker-ops.ts
5718
+ init_util();
5719
+
5298
5720
  // src/validate.ts
5721
+ init_util();
5299
5722
  import path18 from "node:path";
5300
5723
  var RUN_ID_RE = /^[a-z0-9][a-z0-9._-]{0,127}$/i;
5301
5724
  var WORKER_NAME_RE = /^[a-z0-9][a-z0-9._-]{0,63}$/i;
@@ -5648,32 +6071,98 @@ function workerStatus(args) {
5648
6071
  writeJson(path19.join(worker.workerDir, "last-status.json"), status);
5649
6072
  console.log(JSON.stringify(status, null, 2));
5650
6073
  }
6074
+ function buildWorkerListDrilldownCommands(runId) {
6075
+ return {
6076
+ full: `kynver worker list --run ${runId} --full`,
6077
+ blocked: `kynver worker list --run ${runId} --blocked`,
6078
+ running: `kynver worker list --run ${runId} --running`,
6079
+ task: `kynver worker list --run ${runId} --task <task-id>`,
6080
+ worker: `kynver worker list --run ${runId} --worker <worker>`,
6081
+ runFull: `kynver run status --run ${runId} --full`,
6082
+ workerFull: `kynver worker status --run ${runId} --name <worker>`,
6083
+ workerTail: `kynver worker tail --run ${runId} --name <worker> --lines 80`
6084
+ };
6085
+ }
6086
+ function asOptionalArg(value) {
6087
+ if (typeof value !== "string") return void 0;
6088
+ const trimmed = value.trim();
6089
+ return trimmed.length ? trimmed : void 0;
6090
+ }
6091
+ function activeWorkerFilters(args) {
6092
+ const filters = {};
6093
+ if (args.blocked === true || args.blocked === "true") filters.blocked = true;
6094
+ if (args.running === true || args.running === "true") filters.running = true;
6095
+ const task = asOptionalArg(args.task ?? args.taskId);
6096
+ if (task) filters.task = task;
6097
+ const worker = asOptionalArg(args.worker ?? args.name);
6098
+ if (worker) filters.worker = worker;
6099
+ const status = asOptionalArg(args.status);
6100
+ if (status) filters.status = status;
6101
+ return filters;
6102
+ }
6103
+ function workerMatchesFilters(worker, filters) {
6104
+ if (filters.blocked) {
6105
+ const attention = typeof worker.attention === "string" ? worker.attention : "";
6106
+ const status = typeof worker.status === "string" ? worker.status : "";
6107
+ if (!(attention === "blocked" || attention === "needs_attention" || attention === "stale" || status === "blocked")) {
6108
+ return false;
6109
+ }
6110
+ }
6111
+ if (filters.running) {
6112
+ if (!(worker.status === "running" && worker.attention !== "blocked" && worker.attention !== "needs_attention")) {
6113
+ return false;
6114
+ }
6115
+ }
6116
+ if (typeof filters.task === "string" && worker.taskId !== filters.task) return false;
6117
+ if (typeof filters.worker === "string" && worker.worker !== filters.worker) return false;
6118
+ if (typeof filters.status === "string" && worker.status !== filters.status) return false;
6119
+ return true;
6120
+ }
6121
+ function applyWorkerFilters(board, args) {
6122
+ const filters = activeWorkerFilters(args);
6123
+ if (Object.keys(filters).length === 0) return board;
6124
+ const workers = board.workers.filter((worker) => workerMatchesFilters(worker, filters));
6125
+ const filtered = {
6126
+ ...board,
6127
+ workerCount: workers.length,
6128
+ needsAttention: workers.filter((w) => w.attention && w.attention !== "ok" && w.attention !== "done").map((w) => w.worker),
6129
+ workers,
6130
+ activeFilters: filters
6131
+ };
6132
+ if (board.summary) {
6133
+ filtered.summary = {
6134
+ statusCounts: countBy(workers, "status"),
6135
+ attentionCounts: countBy(workers, "attention"),
6136
+ lifecycleCounts: countBy(workers, "lifecycleStage")
6137
+ };
6138
+ }
6139
+ if (board.controller) filtered.controller = buildControllerSummary(workers);
6140
+ return filtered;
6141
+ }
5651
6142
  function workerList(args) {
5652
6143
  const runId = resolveRunTargetArg(args);
5653
- const explicitCompact = args.compact === true || args.compact === "true";
5654
6144
  const explicitFull = args.full === true || args.full === "true";
5655
- const run = loadRun(runId);
5656
- const workerCount = Object.keys(run.workers || {}).length;
5657
- const compact = explicitCompact || !explicitFull && workerCount > 100;
5658
- const board = compact ? buildCompactRunBoard(runId) : buildRunBoard(runId);
5659
- const autoCompact = compact && !explicitCompact;
5660
- const outputWorkers = autoCompact ? board.workers.filter((worker) => worker.attention && worker.attention !== "done" && worker.attention !== "ok") : board.workers;
6145
+ const board = applyWorkerFilters(explicitFull ? buildRunBoard(runId) : buildCompactRunBoard(runId), args);
6146
+ const outputWorkers = board.workers;
5661
6147
  console.log(
5662
6148
  JSON.stringify(
5663
6149
  {
5664
6150
  runId: board.runId,
5665
6151
  status: board.status,
6152
+ projection: explicitFull ? "full" : "compact",
5666
6153
  workerCount: board.workerCount,
5667
- ...autoCompact ? {
5668
- compact: true,
5669
- compactReason: "large-worker-board",
5670
- omittedWorkerCount: board.workers.length - outputWorkers.length,
5671
- fullCommand: `kynver worker list --run ${runId} --json --full`,
5672
- compactCommand: `kynver worker list --run ${runId} --json --compact`
6154
+ ...board.activeFilters ? { activeFilters: board.activeFilters } : {},
6155
+ ...!explicitFull ? {
6156
+ resultContract: {
6157
+ projection: "compact",
6158
+ rawWorkerPayloadsOmitted: true,
6159
+ deepDetailAvailableVia: ["--full", "worker status", "worker tail", "run status --full"]
6160
+ },
6161
+ drilldownCommands: buildWorkerListDrilldownCommands(runId)
5673
6162
  } : {},
5674
6163
  needsAttention: board.needsAttention,
5675
- ...compact && "summary" in board ? { summary: board.summary } : {},
5676
- ...compact && "controller" in board ? { controller: board.controller } : {},
6164
+ ..."summary" in board ? { summary: board.summary } : {},
6165
+ ..."controller" in board ? { controller: board.controller } : {},
5677
6166
  workers: outputWorkers
5678
6167
  },
5679
6168
  null,
@@ -5941,9 +6430,33 @@ async function publishHarnessBoardSnapshot(args, source) {
5941
6430
  authRefreshFailure: res.authRefreshFailure
5942
6431
  };
5943
6432
  }
6433
+ function buildRunStatusDrilldownCommands(runId) {
6434
+ return {
6435
+ full: `kynver run status --run ${runId} --full`,
6436
+ blocked: `kynver status --run ${runId} --blocked`,
6437
+ running: `kynver status --run ${runId} --running`,
6438
+ task: `kynver status --run ${runId} --task <task-id>`,
6439
+ worker: `kynver status --run ${runId} --worker <worker>`,
6440
+ workersFull: `kynver worker list --run ${runId} --full`,
6441
+ workerFull: `kynver worker status --run ${runId} --name <worker>`,
6442
+ workerTail: `kynver worker tail --run ${runId} --name <worker> --lines 80`,
6443
+ monitorTick: `kynver monitor status --run ${runId} --tick`
6444
+ };
6445
+ }
5944
6446
  function runStatus(args) {
5945
- const compact = args.compact === true || args.compact === "true";
5946
- const board = compact ? buildCompactRunBoard(resolveRunTargetArg(args)) : buildRunBoard(resolveRunTargetArg(args));
6447
+ const runId = resolveRunTargetArg(args);
6448
+ const explicitFull = args.full === true || args.full === "true";
6449
+ const board = applyWorkerFilters(explicitFull ? buildRunBoard(runId) : buildCompactRunBoard(runId), args);
6450
+ board.projection = explicitFull ? "full" : "compact";
6451
+ if (!explicitFull) {
6452
+ board.resultContract = {
6453
+ projection: "compact",
6454
+ rawWorkerPayloadsOmitted: true,
6455
+ omittedWorkerFields: ["finalResult", "changedFiles", "gitAncestry", "completionResponse", "stdout/stderr tails"],
6456
+ deepDetailAvailableVia: ["--full", "worker status", "worker tail", "monitor status --tick"]
6457
+ };
6458
+ board.drilldownCommands = buildRunStatusDrilldownCommands(runId);
6459
+ }
5947
6460
  console.log(JSON.stringify(board, null, 2));
5948
6461
  }
5949
6462
  function tailWorker(args) {
@@ -5978,6 +6491,7 @@ function stopWorker(args) {
5978
6491
  }
5979
6492
 
5980
6493
  // src/auto-complete.ts
6494
+ init_util();
5981
6495
  var DEFAULT_POLL_MS = 5e3;
5982
6496
  var DEFAULT_MAX_TOTAL_MS = 6 * 60 * 60 * 1e3;
5983
6497
  var DEFAULT_COMPLETE_ATTEMPTS = 3;
@@ -6162,6 +6676,7 @@ function spawnCompletionSidecar(opts) {
6162
6676
  }
6163
6677
 
6164
6678
  // src/repair-target-worktree.ts
6679
+ init_git();
6165
6680
  function addWorktreeForRepairBranch(repo, worktreePath, branch) {
6166
6681
  git(repo, ["fetch", "origin", branch, "--prune"], { allowFailure: true });
6167
6682
  const remoteRef = `origin/${branch}`;
@@ -6175,6 +6690,8 @@ function addWorktreeForRepairBranch(repo, worktreePath, branch) {
6175
6690
  }
6176
6691
 
6177
6692
  // src/supervisor.ts
6693
+ init_box_identity();
6694
+ init_config();
6178
6695
  function spawnWorkerProcess(run, opts) {
6179
6696
  const rawName = typeof opts.name === "string" ? opts.name.trim() : "";
6180
6697
  if (!rawName || rawName === "undefined" || rawName === "null") {
@@ -6268,6 +6785,10 @@ function spawnWorkerProcess(run, opts) {
6268
6785
  else process.env.KYNVER_HARNESS_AGENT_OS_ID = prevHarnessAgentOsId;
6269
6786
  }
6270
6787
  const model = resolveModelFallback(started.model, launchModel, provider.defaultModel);
6788
+ const config = loadUserConfig();
6789
+ const boxIdentity = resolveBoxIdentity(process.env, config);
6790
+ const runtimeId = resolveRunnerPresencePayload().runnerId;
6791
+ const boxId = defaultBoxId(boxIdentity.boxKind);
6271
6792
  const worker = {
6272
6793
  name,
6273
6794
  runId: run.id,
@@ -6303,6 +6824,9 @@ function spawnWorkerProcess(run, opts) {
6303
6824
  ...opts.taskPrUrl ? { taskPrUrl: String(opts.taskPrUrl) } : {},
6304
6825
  ...opts.repairTargetPrUrl ? { repairTargetPrUrl: String(opts.repairTargetPrUrl) } : {},
6305
6826
  ...opts.repairTargetBranch ? { repairTargetBranch: String(opts.repairTargetBranch) } : {},
6827
+ boxKind: boxIdentity.boxKind,
6828
+ boxId,
6829
+ runtimeId,
6306
6830
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
6307
6831
  };
6308
6832
  saveWorker(run.id, worker);
@@ -6401,6 +6925,9 @@ async function startWorker(args) {
6401
6925
  }
6402
6926
 
6403
6927
  // src/active-harness-workers.ts
6928
+ init_run_store();
6929
+ init_harness_worker_active();
6930
+ init_util();
6404
6931
  import path22 from "node:path";
6405
6932
  function workerWriteSetFields(worker) {
6406
6933
  const ownedPaths = Array.isArray(worker.ownedPaths) ? worker.ownedPaths.filter((p) => typeof p === "string") : [];
@@ -6433,6 +6960,9 @@ function collectRunActiveHarnessWorkers(runId) {
6433
6960
  return out;
6434
6961
  }
6435
6962
 
6963
+ // src/dispatch.ts
6964
+ init_util();
6965
+
6436
6966
  // src/plan-persist/body-hash.ts
6437
6967
  import { createHash as createHash2 } from "node:crypto";
6438
6968
  function hashPlanBody(body) {
@@ -6446,6 +6976,9 @@ function hashSummary(summary) {
6446
6976
  return createHash2("sha256").update(trimmed, "utf8").digest("hex");
6447
6977
  }
6448
6978
 
6979
+ // src/plan-persist/agentos-api.ts
6980
+ init_config();
6981
+
6449
6982
  // src/plan-persist/errors.ts
6450
6983
  var PlanPersistError = class extends Error {
6451
6984
  kind;
@@ -7081,6 +7614,10 @@ var READY_MERGE_STATES = /* @__PURE__ */ new Set(["CLEAN", "HAS_HOOKS"]);
7081
7614
  function repoArgs(repo) {
7082
7615
  return repo?.trim() ? ["--repo", repo.trim()] : [];
7083
7616
  }
7617
+ function repoFromPrUrl(prUrl) {
7618
+ const m = /github\.com\/([^/]+)\/([^/]+)\/pull\/\d+/i.exec(prUrl.trim());
7619
+ return m ? `${m[1]}/${m[2]}` : null;
7620
+ }
7084
7621
  function ghJson(exec, cwd, args) {
7085
7622
  const res = exec.gh(cwd, args);
7086
7623
  if (res.status !== 0) {
@@ -7106,11 +7643,11 @@ function classifyChecks(statusCheckRollup) {
7106
7643
  continue;
7107
7644
  }
7108
7645
  if (state && SUCCESSFUL_CHECK_CONCLUSIONS.has(state)) continue;
7109
- if (state && state !== "PENDING") {
7646
+ if (state && state !== "PENDING" && state !== "EXPECTED") {
7110
7647
  failed.push(`${checkName(check3)}=${state}`);
7111
7648
  continue;
7112
7649
  }
7113
- if (state === "PENDING") {
7650
+ if (state === "PENDING" || state === "EXPECTED") {
7114
7651
  pending.push(`${checkName(check3)}=${state}`);
7115
7652
  continue;
7116
7653
  }
@@ -7136,14 +7673,21 @@ var STRUCTURED_SECTION_RE = /^##\s*(test\s*plan|verification|test\s*evidence|ver
7136
7673
  var LOCAL_VERIFICATION_RE = /typecheck|npm run (test|build|typecheck)|vitest|tsc\b|verify-pr-local|local verify|local-verify|tests? (pass|green)|build green|node --test/i;
7137
7674
  var DOCS_TITLE_RE = /^docs[(:]/i;
7138
7675
  var DOCS_BODY_RE = /docs[- ]only|documentation only|no[- ]code change|no code changes|low[- ]risk|plan tracker only|markdown only/i;
7139
- function assertVerificationEvidence(pr) {
7140
- const title = typeof pr.title === "string" ? pr.title : "";
7141
- const body = typeof pr.body === "string" ? pr.body : "";
7676
+ function runtimeVerificationEvidenceSufficient(input) {
7677
+ const title = typeof input.title === "string" ? input.title.trim() : "";
7678
+ const body = typeof input.body === "string" ? input.body.trim() : "";
7142
7679
  const docsLowRisk = DOCS_TITLE_RE.test(title) || DOCS_BODY_RE.test(body);
7143
7680
  const structuredSection = STRUCTURED_SECTION_RE.test(body);
7144
7681
  const localVerification = LOCAL_VERIFICATION_RE.test(body);
7145
- const vercelOk = vercelCheckSuccess(pr.statusCheckRollup);
7146
- if (docsLowRisk || structuredSection || localVerification || vercelOk) return;
7682
+ return docsLowRisk || structuredSection || localVerification || input.vercelCheckSuccess === true;
7683
+ }
7684
+ function assertVerificationEvidence(pr) {
7685
+ const sufficient = runtimeVerificationEvidenceSufficient({
7686
+ title: pr.title,
7687
+ body: pr.body,
7688
+ vercelCheckSuccess: vercelCheckSuccess(pr.statusCheckRollup)
7689
+ });
7690
+ if (sufficient) return;
7147
7691
  throw new Error(
7148
7692
  `PR #${pr.number} lacks landing verification evidence \u2014 add ## Test plan / ## Verification with local commands, Vercel preview, or docs/no-code rationale`
7149
7693
  );
@@ -7244,6 +7788,14 @@ async function executeLandPrMerge(input) {
7244
7788
  "mergeCommit"
7245
7789
  ].join(",")
7246
7790
  ]);
7791
+ if (before.state === "MERGED" || before.mergedAt) {
7792
+ return {
7793
+ prUrl: before.url || prTarget,
7794
+ outcome: "skipped",
7795
+ mergeCommit: before.mergeCommit?.oid ?? null,
7796
+ reason: `PR #${before.number} is already merged \u2014 land_pr no-op (redelivery)`
7797
+ };
7798
+ }
7247
7799
  const notReadyReason = landingReadinessError(before);
7248
7800
  if (notReadyReason) {
7249
7801
  if (input.skipNotReady) {
@@ -7275,40 +7827,56 @@ async function executeLandPrMerge(input) {
7275
7827
  "--squash"
7276
7828
  ]);
7277
7829
  if (mergeRes.status !== 0) {
7830
+ const raced = viewMergedState(exec, cwd, target, input.repo);
7831
+ if (raced) {
7832
+ return {
7833
+ prUrl: raced.url || before.url || prTarget,
7834
+ outcome: "skipped",
7835
+ mergeCommit: raced.mergeCommit?.oid ?? null,
7836
+ reason: `PR #${before.number} is already merged \u2014 merged by another lane during land_pr (race)`
7837
+ };
7838
+ }
7278
7839
  return {
7279
7840
  prUrl: before.url || prTarget,
7280
7841
  outcome: "blocked",
7281
7842
  reason: mergeRes.stderr || mergeRes.stdout || "gh pr merge failed"
7282
7843
  };
7283
7844
  }
7284
- const after = ghJson(exec, cwd, [
7285
- "pr",
7286
- "view",
7287
- target,
7288
- ...repoArgs(input.repo),
7289
- "--json",
7290
- "number,url,mergedAt,mergeCommit,state"
7291
- ]);
7292
- if (after.state !== "MERGED" && !after.mergedAt) {
7293
- return {
7294
- prUrl: after.url || before.url || prTarget,
7295
- outcome: "blocked",
7296
- reason: `PR #${after.number} did not verify as merged after gh pr merge`
7297
- };
7845
+ let after = viewMergedState(exec, cwd, target, input.repo);
7846
+ if (!after) {
7847
+ after = viewMergedState(exec, cwd, target, input.repo);
7848
+ }
7849
+ try {
7850
+ const repo = resolveRepo(exec, cwd, input.repo);
7851
+ deleteRemoteBranch(exec, cwd, repo, before.headRefName);
7852
+ removeBranchWorktrees(cwd, before.headRefName);
7853
+ } catch {
7298
7854
  }
7299
- const repo = resolveRepo(exec, cwd, input.repo);
7300
- deleteRemoteBranch(exec, cwd, repo, before.headRefName);
7301
- removeBranchWorktrees(cwd, before.headRefName);
7302
- const mergeCommit = after.mergeCommit?.oid ?? null;
7303
7855
  return {
7304
- prUrl: after.url || before.url || prTarget,
7856
+ prUrl: after?.url || before.url || prTarget,
7305
7857
  outcome: "merged",
7306
- mergeCommit,
7307
- reason: `Daemon land_pr merged PR #${after.number}`
7858
+ mergeCommit: after?.mergeCommit?.oid ?? null,
7859
+ reason: `Daemon land_pr merged PR #${before.number}${after ? "" : " (post-merge view unavailable \u2014 merge verified by gh exit 0)"}`
7308
7860
  };
7309
7861
  }
7862
+ function viewMergedState(exec, cwd, target, repo) {
7863
+ try {
7864
+ const view = ghJson(exec, cwd, [
7865
+ "pr",
7866
+ "view",
7867
+ target,
7868
+ ...repoArgs(repo),
7869
+ "--json",
7870
+ "number,url,mergedAt,mergeCommit,state"
7871
+ ]);
7872
+ return view.state === "MERGED" || view.mergedAt ? view : null;
7873
+ } catch {
7874
+ return null;
7875
+ }
7876
+ }
7310
7877
 
7311
7878
  // src/landing/land-pr-completion-post.ts
7879
+ init_config();
7312
7880
  async function postLandPrHarnessCompletion(input) {
7313
7881
  const secret = await resolveCallbackSecretWithMint(input.secret, input.agentOsId, {
7314
7882
  baseUrl: input.baseUrl
@@ -7593,12 +8161,25 @@ async function dispatchRun(args) {
7593
8161
  async function runLandPrClaimed(decision) {
7594
8162
  const task = decision.task;
7595
8163
  const taskId = String(task.id);
8164
+ if (exactTargetMode && !exactTargetIds.has(taskId)) {
8165
+ return abortClaimedSpawn(
8166
+ task,
8167
+ "exact_target_mismatch: dispatch-next returned a different task than requested",
8168
+ {
8169
+ requestedTargetTaskIds: [...exactTargetIds]
8170
+ }
8171
+ );
8172
+ }
7596
8173
  const prUrl = task.prUrl ? String(task.prUrl) : "";
7597
8174
  if (!prUrl) {
7598
8175
  return abortClaimedSpawn(task, "land_pr task missing prUrl");
7599
8176
  }
7600
8177
  try {
7601
- const report = await executeLandPrMerge({ prUrl, cwd: process.cwd() });
8178
+ const report = await executeLandPrMerge({
8179
+ prUrl,
8180
+ repo: repoFromPrUrl(prUrl),
8181
+ cwd: run.repo
8182
+ });
7602
8183
  const post = await postLandPrHarnessCompletion({
7603
8184
  baseUrl: base,
7604
8185
  secret,
@@ -7625,6 +8206,27 @@ async function dispatchRun(args) {
7625
8206
  return abortClaimedSpawn(task, error.message);
7626
8207
  }
7627
8208
  }
8209
+ async function releaseDuplicateLocalClaim(task) {
8210
+ const error = "duplicate_dispatch_prevented: live local worker already owns this task";
8211
+ const release = await releaseDispatchClaimAfterSpawnFailure({
8212
+ baseUrl: base,
8213
+ secret,
8214
+ agentOsId,
8215
+ taskId: String(task.id),
8216
+ leaseOwner,
8217
+ failureDetail: error
8218
+ });
8219
+ outcomes.push({
8220
+ taskId: task.id,
8221
+ started: false,
8222
+ error,
8223
+ alreadyRunning: true,
8224
+ nonFatal: true,
8225
+ released: release.released,
8226
+ releaseResponse: release.releaseResponse
8227
+ });
8228
+ return false;
8229
+ }
7628
8230
  async function spawnClaimed(decision) {
7629
8231
  const task = decision.task;
7630
8232
  const harnessContext = readHarnessWorkerContext(decision);
@@ -7646,10 +8248,7 @@ async function dispatchRun(args) {
7646
8248
  );
7647
8249
  }
7648
8250
  if (hasLiveWorkerForTask(run.id, taskId)) {
7649
- return abortClaimedSpawn(
7650
- task,
7651
- "duplicate_dispatch_prevented: live local worker already owns this task"
7652
- );
8251
+ return releaseDuplicateLocalClaim(task);
7653
8252
  }
7654
8253
  const attempt = Number(task.attempt) || 1;
7655
8254
  if (attempt > retryLimits.maxTaskAttempts) {
@@ -7819,11 +8418,12 @@ async function dispatchRun(args) {
7819
8418
  diskGate: result.diskGate,
7820
8419
  resourceGate: result.resourceGate
7821
8420
  };
8421
+ const fatalOutcome = (outcome) => !outcome.started && outcome.nonFatal !== true;
7822
8422
  if (pipeline) {
7823
- return { ok: !outcomes.some((o) => !o.started), ...summary };
8423
+ return { ok: !outcomes.some(fatalOutcome), ...summary };
7824
8424
  }
7825
8425
  console.log(JSON.stringify(summary, null, 2));
7826
- if (outcomes.some((o) => !o.started)) process.exit(1);
8426
+ if (outcomes.some(fatalOutcome)) process.exit(1);
7827
8427
  } catch (error) {
7828
8428
  if (pipeline) return { ok: false, error: error.message };
7829
8429
  console.error(`run dispatch failed: ${error.message}`);
@@ -7831,8 +8431,15 @@ async function dispatchRun(args) {
7831
8431
  }
7832
8432
  }
7833
8433
 
8434
+ // src/cli.ts
8435
+ init_run_store();
8436
+
7834
8437
  // src/sweep.ts
8438
+ init_config();
7835
8439
  import path26 from "node:path";
8440
+ init_run_store();
8441
+ init_status();
8442
+ init_util();
7836
8443
  async function sweepRun(args) {
7837
8444
  const pipeline = args.pipeline === true || args.pipeline === "true";
7838
8445
  try {
@@ -7893,10 +8500,14 @@ async function sweepRun(args) {
7893
8500
  }
7894
8501
 
7895
8502
  // src/worktree.ts
8503
+ init_git();
8504
+ init_run_store();
7896
8505
  import { existsSync as existsSync25, mkdirSync as mkdirSync6 } from "node:fs";
7897
8506
  import path35 from "node:path";
7898
8507
 
7899
8508
  // src/run-list.ts
8509
+ init_run_store();
8510
+ init_run_worker_index();
7900
8511
  import { existsSync as existsSync24, readFileSync as readFileSync11 } from "node:fs";
7901
8512
  import path34 from "node:path";
7902
8513
 
@@ -7904,6 +8515,10 @@ import path34 from "node:path";
7904
8515
  import path33 from "node:path";
7905
8516
 
7906
8517
  // src/finalize.ts
8518
+ init_run_store();
8519
+ init_run_worker_index();
8520
+ init_status();
8521
+ init_util();
7907
8522
  import path27 from "node:path";
7908
8523
  var ACTIVE_RUN_STATUSES = /* @__PURE__ */ new Set([
7909
8524
  "running",
@@ -7961,11 +8576,21 @@ function finalizeStaleRuns() {
7961
8576
  return finalized;
7962
8577
  }
7963
8578
 
8579
+ // src/stale-reconcile.ts
8580
+ init_run_store();
8581
+ init_run_worker_index();
8582
+ init_status();
8583
+ init_util();
8584
+
7964
8585
  // src/worker-metadata-reconcile.ts
8586
+ init_heartbeat();
8587
+ init_stream();
7965
8588
  import { existsSync as existsSync23, lstatSync, readdirSync as readdirSync7, readlinkSync, renameSync as renameSync2, rmSync } from "node:fs";
7966
8589
  import path31 from "node:path";
7967
8590
 
7968
8591
  // src/worker-metadata-paths.ts
8592
+ init_paths();
8593
+ init_util();
7969
8594
  import path28 from "node:path";
7970
8595
  var NESTED_RUNS = `${path28.sep}runs${path28.sep}runs${path28.sep}`;
7971
8596
  function hasNestedRunsSegment(filePath) {
@@ -8013,6 +8638,9 @@ import { existsSync as existsSync22, readdirSync as readdirSync6, statSync as st
8013
8638
  import path30 from "node:path";
8014
8639
 
8015
8640
  // src/default-repo.ts
8641
+ init_config();
8642
+ init_default_repo_discovery();
8643
+ init_path_values();
8016
8644
  import path29 from "node:path";
8017
8645
  function expandConfiguredRepo(value) {
8018
8646
  return path29.resolve(resolveUserPath(value.trim()));
@@ -8063,6 +8691,10 @@ function formatResolvedDefaultRepo(resolved) {
8063
8691
  }
8064
8692
 
8065
8693
  // src/run-metadata-retention.ts
8694
+ init_heartbeat();
8695
+ init_paths();
8696
+ init_run_store();
8697
+ init_util();
8066
8698
  var RUN_METADATA_ACTIVE_SIGNAL_MS = 15 * 60 * 1e3;
8067
8699
  function isHarnessRunMetadataPath(targetPath, harnessRoot) {
8068
8700
  const resolved = path30.resolve(targetPath);
@@ -8203,6 +8835,8 @@ function collectFilesystemLiveRunKeys(harnessRoot, now = Date.now()) {
8203
8835
  }
8204
8836
 
8205
8837
  // src/worker-metadata-reconcile.ts
8838
+ init_run_store();
8839
+ init_util();
8206
8840
  function materializeSymlinkedRunDir(harnessRoot, runId) {
8207
8841
  const canonical = canonicalRunDir(harnessRoot, runId);
8208
8842
  let stat;
@@ -8485,6 +9119,12 @@ function reconcileWorkerMetadata() {
8485
9119
  }
8486
9120
 
8487
9121
  // src/local-pr-attention-reconcile.ts
9122
+ init_heartbeat();
9123
+ init_worker_final_result_embed();
9124
+ init_status();
9125
+ init_run_store();
9126
+ init_run_worker_index();
9127
+ init_util();
8488
9128
  import { execFileSync } from "node:child_process";
8489
9129
  import path32 from "node:path";
8490
9130
  function normalizePrUrl3(url) {
@@ -8811,6 +9451,8 @@ function reconcileRunsCli() {
8811
9451
  }
8812
9452
 
8813
9453
  // src/run-list.ts
9454
+ init_status();
9455
+ init_util();
8814
9456
  function heartbeatByteLength(heartbeatPath) {
8815
9457
  if (!heartbeatPath || !existsSync24(heartbeatPath)) return 0;
8816
9458
  try {
@@ -8926,6 +9568,7 @@ function listRunsCli() {
8926
9568
  }
8927
9569
 
8928
9570
  // src/worktree.ts
9571
+ init_util();
8929
9572
  function resolveCreateRunRepo(args) {
8930
9573
  const explicit = typeof args.repo === "string" ? args.repo.trim() : "";
8931
9574
  if (explicit) return explicit;
@@ -8965,6 +9608,8 @@ function failExists(message) {
8965
9608
  }
8966
9609
 
8967
9610
  // src/discard-disposable.ts
9611
+ init_run_store();
9612
+ init_status();
8968
9613
  import { existsSync as existsSync26, rmSync as rmSync2 } from "node:fs";
8969
9614
  import path36 from "node:path";
8970
9615
  function normalizeRelativePath2(value) {
@@ -9018,8 +9663,14 @@ function discardDisposableCli(args) {
9018
9663
  if (!result.ok) process.exit(1);
9019
9664
  }
9020
9665
 
9666
+ // src/daemon.ts
9667
+ init_config();
9668
+
9021
9669
  // src/daemon-box-identity.ts
9022
- import os7 from "node:os";
9670
+ init_config();
9671
+ init_box_identity();
9672
+ init_worker_cap_source();
9673
+ import os9 from "node:os";
9023
9674
  function emitDaemonIdentityMessage(level, message) {
9024
9675
  console.error(JSON.stringify({ event: "daemon_identity", level, message }));
9025
9676
  }
@@ -9027,7 +9678,7 @@ function validateDaemonInstallIdentity(config = loadUserConfig(), env = process.
9027
9678
  const box = resolveBoxIdentity(env, config);
9028
9679
  const cap = resolveWorkerCap({
9029
9680
  config,
9030
- totalMemBytes: os7.totalmem(),
9681
+ totalMemBytes: os9.totalmem(),
9031
9682
  env
9032
9683
  });
9033
9684
  const warnings = [...box.warnings];
@@ -9057,11 +9708,71 @@ function validateDaemonInstallIdentity(config = loadUserConfig(), env = process.
9057
9708
  };
9058
9709
  }
9059
9710
 
9060
- // src/cron/cron-env.ts
9061
- import { existsSync as existsSync27 } from "node:fs";
9711
+ // src/daemon-heartbeat.ts
9712
+ import { mkdirSync as mkdirSync7, readFileSync as readFileSync12, renameSync as renameSync3, writeFileSync as writeFileSync4 } from "node:fs";
9062
9713
  import { homedir as homedir11 } from "node:os";
9063
9714
  import path37 from "node:path";
9064
- function envFlag(name, defaultValue) {
9715
+ function daemonHeartbeatPath(agentOsId) {
9716
+ const safe = agentOsId.replace(/[^A-Za-z0-9_-]/g, "_");
9717
+ return path37.join(homedir11(), ".kynver", `daemon-heartbeat-${safe}.json`);
9718
+ }
9719
+ function writeDaemonHeartbeat(input) {
9720
+ try {
9721
+ const file = daemonHeartbeatPath(input.agentOsId);
9722
+ mkdirSync7(path37.dirname(file), { recursive: true });
9723
+ const beat = {
9724
+ observedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString(),
9725
+ pid: process.pid,
9726
+ runId: input.runId,
9727
+ agentOsId: input.agentOsId
9728
+ };
9729
+ const tmp = `${file}.tmp-${process.pid}`;
9730
+ writeFileSync4(tmp, JSON.stringify(beat), "utf8");
9731
+ renameSync3(tmp, file);
9732
+ } catch {
9733
+ }
9734
+ }
9735
+ function readDaemonHeartbeat(agentOsId) {
9736
+ try {
9737
+ const raw = readFileSync12(daemonHeartbeatPath(agentOsId), "utf8");
9738
+ const parsed = JSON.parse(raw);
9739
+ if (typeof parsed?.observedAt !== "string") return null;
9740
+ return parsed;
9741
+ } catch {
9742
+ return null;
9743
+ }
9744
+ }
9745
+ function isDaemonHeartbeatStale(beat, stallMs, nowMs = Date.now()) {
9746
+ if (!beat) return false;
9747
+ const observed = Date.parse(beat.observedAt);
9748
+ if (Number.isNaN(observed)) return true;
9749
+ return nowMs - observed > stallMs;
9750
+ }
9751
+
9752
+ // src/daemon-platform-guard.ts
9753
+ function envFlag(name) {
9754
+ const raw = process.env[name]?.trim().toLowerCase();
9755
+ return raw === "1" || raw === "true" || raw === "yes" || raw === "on";
9756
+ }
9757
+ function assertNativeDaemonAllowed() {
9758
+ if (process.platform !== "win32") return;
9759
+ if (envFlag("KYNVER_DAEMON_ALLOW_NATIVE_WINDOWS")) return;
9760
+ console.error(
9761
+ JSON.stringify({
9762
+ event: "daemon_start_blocked",
9763
+ reason: "native_windows_console_flash",
9764
+ remedy: "Run the daemon inside WSL: .\\scripts\\start-tier2-wsl.ps1 \u2014 or set KYNVER_DAEMON_ALLOW_NATIVE_WINDOWS=1 to override (flashes visible consoles)."
9765
+ })
9766
+ );
9767
+ process.exit(1);
9768
+ }
9769
+
9770
+ // src/cron/cron-env.ts
9771
+ init_config();
9772
+ import { existsSync as existsSync27 } from "node:fs";
9773
+ import { homedir as homedir12 } from "node:os";
9774
+ import path38 from "node:path";
9775
+ function envFlag2(name, defaultValue) {
9065
9776
  const raw = process.env[name]?.trim().toLowerCase();
9066
9777
  if (!raw) return defaultValue;
9067
9778
  if (raw === "0" || raw === "false" || raw === "no" || raw === "off") return false;
@@ -9076,7 +9787,7 @@ function envInt(name, fallback, min = 1) {
9076
9787
  function defaultKynverCronStorePath() {
9077
9788
  const explicit = process.env.KYNVER_CRON_STORE_PATH?.trim() || process.env.OPENCLAW_CRON_STORE_PATH?.trim();
9078
9789
  if (explicit) return explicit;
9079
- return path37.join(homedir11(), ".kynver", "agent-os-cron.json");
9790
+ return path38.join(homedir12(), ".kynver", "agent-os-cron.json");
9080
9791
  }
9081
9792
  function defaultKynverCronStatePath(storePath = defaultKynverCronStorePath()) {
9082
9793
  const explicit = process.env.KYNVER_CRON_TICK_STATE_PATH?.trim();
@@ -9097,14 +9808,14 @@ function resolveKynverCronEnv() {
9097
9808
  const secret = resolveKynverCronSecret();
9098
9809
  const credsReady = Boolean(fireBaseUrl && secret);
9099
9810
  const storeExists = existsSync27(storePath);
9100
- const defaultEnabled = credsReady && (storeExists || envFlag("KYNVER_CRON_TICK_FORCE", false));
9811
+ const defaultEnabled = credsReady && (storeExists || envFlag2("KYNVER_CRON_TICK_FORCE", false));
9101
9812
  return {
9102
9813
  storePath,
9103
9814
  statePath,
9104
9815
  lockPath: `${statePath}.lock`,
9105
9816
  fireBaseUrl,
9106
9817
  secret,
9107
- tickEnabled: envFlag("KYNVER_CRON_TICK_ENABLED", defaultEnabled),
9818
+ tickEnabled: envFlag2("KYNVER_CRON_TICK_ENABLED", defaultEnabled),
9108
9819
  tickIntervalMs: envInt("KYNVER_CRON_TICK_INTERVAL_MS", 6e4, 5e3),
9109
9820
  missedRunPolicy: process.env.KYNVER_CRON_MISSED_RUN_POLICY?.trim().toLowerCase() === "skip" ? "skip" : "catch_up",
9110
9821
  maxCatchUpPerTick: envInt("KYNVER_CRON_MAX_CATCH_UP_PER_TICK", 3, 0),
@@ -9149,12 +9860,13 @@ async function fireKynverCronJob(input) {
9149
9860
  }
9150
9861
 
9151
9862
  // src/cron/cron-lock.ts
9152
- import { closeSync as closeSync6, existsSync as existsSync28, openSync as openSync6, readFileSync as readFileSync12, unlinkSync as unlinkSync3, writeFileSync as writeFileSync4 } from "node:fs";
9863
+ init_util();
9864
+ import { closeSync as closeSync6, existsSync as existsSync28, openSync as openSync6, readFileSync as readFileSync13, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
9153
9865
  var STALE_LOCK_MS = 10 * 6e4;
9154
9866
  function readLockInfo(lockPath) {
9155
9867
  if (!existsSync28(lockPath)) return null;
9156
9868
  try {
9157
- const parsed = JSON.parse(readFileSync12(lockPath, "utf8"));
9869
+ const parsed = JSON.parse(readFileSync13(lockPath, "utf8"));
9158
9870
  if (typeof parsed.pid === "number" && typeof parsed.at === "string") return parsed;
9159
9871
  } catch {
9160
9872
  return null;
@@ -9185,7 +9897,7 @@ function tryAcquireCronTickLock(lockPath) {
9185
9897
  }
9186
9898
  try {
9187
9899
  const fd = openSync6(lockPath, "wx");
9188
- writeFileSync4(
9900
+ writeFileSync5(
9189
9901
  fd,
9190
9902
  JSON.stringify({ pid: process.pid, at: (/* @__PURE__ */ new Date()).toISOString() }),
9191
9903
  "utf8"
@@ -9318,7 +10030,7 @@ async function loadCronJobs(storePath = defaultKynverCronStorePath()) {
9318
10030
  // src/cron/cron-tick-state.ts
9319
10031
  import { randomBytes } from "node:crypto";
9320
10032
  import { promises as fs2 } from "node:fs";
9321
- import path38 from "node:path";
10033
+ import path39 from "node:path";
9322
10034
  var EMPTY = { version: 1, jobs: {} };
9323
10035
  async function readFileIfExists2(filePath) {
9324
10036
  try {
@@ -9345,7 +10057,7 @@ async function loadCronTickState(statePath) {
9345
10057
  return parseCronTickState(raw);
9346
10058
  }
9347
10059
  async function writeStateAtomic(statePath, state) {
9348
- await fs2.mkdir(path38.dirname(statePath), { recursive: true });
10060
+ await fs2.mkdir(path39.dirname(statePath), { recursive: true });
9349
10061
  const suffix = randomBytes(6).toString("hex");
9350
10062
  const tmp = `${statePath}.tmp-${process.pid}-${Date.now()}-${suffix}`;
9351
10063
  await fs2.writeFile(tmp, `${JSON.stringify(state, null, 2)}
@@ -9521,8 +10233,12 @@ async function runKynverCronTick(opts = {}) {
9521
10233
  }
9522
10234
  }
9523
10235
 
10236
+ // src/daemon.ts
10237
+ init_util();
10238
+
9524
10239
  // src/pipeline-tick.ts
9525
- import path56 from "node:path";
10240
+ import path58 from "node:path";
10241
+ init_config();
9526
10242
 
9527
10243
  // src/pipeline-dispatch.ts
9528
10244
  var RESERVED_REVIEW_STARTS = 1;
@@ -9652,11 +10368,16 @@ function resolvePipelineMaxStarts(resourceGate, operatorTick) {
9652
10368
  };
9653
10369
  }
9654
10370
 
10371
+ // src/pipeline-tick.ts
10372
+ init_resource_gate();
10373
+
9655
10374
  // src/box-resource-snapshot.ts
9656
- import os8 from "node:os";
10375
+ init_config();
10376
+ init_box_identity();
10377
+ import os10 from "node:os";
9657
10378
  function buildBoxResourceSnapshotFromGate(gate, input = {}) {
9658
10379
  const boxKind = (input.boxKind ?? resolveBoxKindFromConfig(loadUserConfig())).trim().toLowerCase() || "forge";
9659
- const hostLabel = input.hostLabel ?? os8.hostname();
10380
+ const hostLabel = input.hostLabel ?? os10.hostname();
9660
10381
  const boxId = input.boxId ?? defaultBoxId(boxKind, hostLabel);
9661
10382
  return {
9662
10383
  boxId,
@@ -9677,10 +10398,20 @@ function buildBoxResourceSnapshotFromGate(gate, input = {}) {
9677
10398
  };
9678
10399
  }
9679
10400
 
10401
+ // src/pipeline-tick.ts
10402
+ init_run_store();
10403
+ init_exited_salvage();
10404
+ init_status();
10405
+ init_util();
10406
+
9680
10407
  // src/plan-progress-daemon-sync.ts
9681
- import path39 from "node:path";
10408
+ init_status();
10409
+ init_run_store();
10410
+ init_util();
10411
+ import path40 from "node:path";
9682
10412
 
9683
10413
  // src/plan-progress-sync.ts
10414
+ init_config();
9684
10415
  async function syncPlanProgress(args) {
9685
10416
  const base = resolveBaseUrl(args.baseUrl);
9686
10417
  const secret = await resolveCallbackSecretWithMint(args.secret, args.agentOsId, { baseUrl: base });
@@ -9702,7 +10433,7 @@ async function syncActiveWorkerPlanProgress(runId, args) {
9702
10433
  const outcomes = [];
9703
10434
  for (const name of Object.keys(run.workers || {})) {
9704
10435
  const worker = readJson(
9705
- path39.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
10436
+ path40.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
9706
10437
  void 0
9707
10438
  );
9708
10439
  if (!worker?.dispatched || !worker.taskId) continue;
@@ -9730,6 +10461,8 @@ async function syncActiveWorkerPlanProgress(runId, args) {
9730
10461
  }
9731
10462
 
9732
10463
  // src/workspace-runtime-config.ts
10464
+ init_config();
10465
+ init_box_identity();
9733
10466
  function shouldApplyWorkspaceRuntimePreferences(env = process.env) {
9734
10467
  const config = loadUserConfig();
9735
10468
  return resolveBoxKindFromConfig(config, env) !== "forge";
@@ -9758,11 +10491,21 @@ async function fetchWorkspaceRuntimePreferences(agentOsId, args) {
9758
10491
  }
9759
10492
  }
9760
10493
 
10494
+ // src/pipeline-tick.ts
10495
+ init_config();
10496
+ init_box_identity();
10497
+
9761
10498
  // src/cleanup.ts
9762
- import path53 from "node:path";
10499
+ init_paths();
10500
+ import path54 from "node:path";
9763
10501
 
9764
10502
  // src/cleanup-guards.ts
9765
- import path40 from "node:path";
10503
+ init_landing_gate();
10504
+ import path41 from "node:path";
10505
+
10506
+ // src/cleanup-index-status.ts
10507
+ init_git();
10508
+ init_status();
9766
10509
 
9767
10510
  // src/cleanup-build-cache-paths.ts
9768
10511
  var HARNESS_BUILD_CACHE_RELATIVE_PATHS = [
@@ -9791,23 +10534,6 @@ function materialWorktreeChanges2(changedFiles) {
9791
10534
  });
9792
10535
  }
9793
10536
 
9794
- // src/cleanup-index-status.ts
9795
- function indexedWorktreeStatus(entry) {
9796
- if (!entry.status) {
9797
- entry.status = computeWorkerStatus(entry.worker, {
9798
- base: entry.run.base,
9799
- baseCommit: entry.run.baseCommit
9800
- });
9801
- }
9802
- return entry.status;
9803
- }
9804
- function indexedWorktreeHasMaterialChanges(entry) {
9805
- if (entry.status) {
9806
- return materialWorktreeChanges2(entry.status.changedFiles).length > 0;
9807
- }
9808
- return materialWorktreeChanges2(gitStatusShort(entry.worktreePath)).length > 0;
9809
- }
9810
-
9811
10537
  // src/cleanup-worktree-salvage.ts
9812
10538
  function prUrlFromFinalResult(finalResult) {
9813
10539
  if (typeof finalResult === "string") {
@@ -9834,7 +10560,93 @@ function isPrOrUnmergedWork(status) {
9834
10560
  return false;
9835
10561
  }
9836
10562
 
10563
+ // src/cleanup-index-status.ts
10564
+ init_util();
10565
+ function indexedWorktreeStatus(entry) {
10566
+ if (!entry.status) {
10567
+ entry.status = computeWorkerStatus(entry.worker, {
10568
+ base: entry.run.base,
10569
+ baseCommit: entry.run.baseCommit
10570
+ });
10571
+ }
10572
+ return entry.status;
10573
+ }
10574
+ function indexedWorktreeHasMaterialChanges(entry, gitStatusCache) {
10575
+ if (entry.status) {
10576
+ return materialWorktreeChanges2(entry.status.changedFiles).length > 0;
10577
+ }
10578
+ const porcelain = gitStatusCache ? gitStatusCache.porcelain(entry.worktreePath) : gitStatusShort(entry.worktreePath);
10579
+ return materialWorktreeChanges2(porcelain).length > 0;
10580
+ }
10581
+ function finalResultFromWorkerJson(entry) {
10582
+ const snapshot = entry.worker.completionSnapshot?.finalResult;
10583
+ if (snapshot !== void 0 && snapshot !== null) return snapshot;
10584
+ if (entry.worker.taskPrUrl) {
10585
+ return { prUrl: entry.worker.taskPrUrl };
10586
+ }
10587
+ return null;
10588
+ }
10589
+ function resolveWorktreeGuardStatus(entry, ctx) {
10590
+ if (entry.status) return entry.status;
10591
+ const worker = entry.worker;
10592
+ const completionAcknowledged = typeof worker.completionReportedAt === "string" && worker.completionReportedAt.trim().length > 0;
10593
+ const workerJsonTerminal = Boolean(worker.status && ["done", "exited", "blocked", "failed", "abandoned"].includes(worker.status)) || completionAcknowledged;
10594
+ const finalResult = finalResultFromWorkerJson(entry);
10595
+ if (workerJsonTerminal && !isPidAlive(worker.pid)) {
10596
+ const changedFiles = ctx?.gitStatusCache ? ctx.gitStatusCache.porcelain(entry.worktreePath) : gitStatusShort(entry.worktreePath);
10597
+ const baseLabel = entry.run.baseCommit?.trim() || entry.run.base?.trim() || "origin/main";
10598
+ const ahead = ctx?.gitRevCache?.countAheadOfMain(entry.worktreePath, baseLabel);
10599
+ const gitAncestry = ahead === 0 ? {
10600
+ checked: true,
10601
+ base: baseLabel,
10602
+ relation: "synced"
10603
+ } : computeGitAncestry(entry.worktreePath, {
10604
+ base: entry.run.base,
10605
+ baseCommit: entry.run.baseCommit
10606
+ });
10607
+ const status = {
10608
+ runId: entry.runId,
10609
+ worker: entry.workerName,
10610
+ pid: worker.pid,
10611
+ alive: false,
10612
+ status: worker.status ?? (completionAcknowledged ? "done" : "exited"),
10613
+ attention: { state: completionAcknowledged ? "done" : "stale" },
10614
+ branch: worker.branch,
10615
+ worktreePath: entry.worktreePath,
10616
+ ownedPaths: worker.ownedPaths,
10617
+ stdoutBytes: 0,
10618
+ stderrBytes: 0,
10619
+ heartbeatBytes: 0,
10620
+ firstEventAt: null,
10621
+ lastEventAt: null,
10622
+ lastActivityAt: worker.completionReportedAt ?? null,
10623
+ currentTool: null,
10624
+ heartbeatCount: 0,
10625
+ lastHeartbeatAt: null,
10626
+ lastHeartbeatPhase: null,
10627
+ lastHeartbeatSummary: null,
10628
+ heartbeatBlocker: null,
10629
+ changedFiles,
10630
+ gitAncestry,
10631
+ finalResult,
10632
+ completionBlocker: typeof worker.completionBlocker === "string" ? worker.completionBlocker.trim() || null : null,
10633
+ prUrl: worker.repairTargetPrUrl ?? worker.taskPrUrl ?? prUrlFromFinalResult(finalResult)
10634
+ };
10635
+ entry.status = status;
10636
+ return status;
10637
+ }
10638
+ return indexedWorktreeStatus(entry);
10639
+ }
10640
+
10641
+ // src/cleanup-guards.ts
10642
+ init_status();
10643
+
10644
+ // src/cleanup-run-liveness.ts
10645
+ init_status();
10646
+
9837
10647
  // src/cleanup-completion-blocker.ts
10648
+ init_landing_gate();
10649
+ init_status();
9838
10650
  function completionBlockerBlocksWorktreeRemoval(indexed, status) {
9839
10651
  const blocker = typeof indexed.worker.completionBlocker === "string" ? indexed.worker.completionBlocker.trim() : "";
9840
10652
  if (!blocker) return false;
@@ -9854,13 +10666,29 @@ function completionBlockerBlocksWorktreeRemoval(indexed, status) {
9854
10666
  }
9855
10667
 
9856
10668
  // src/cleanup-run-liveness.ts
10669
+ init_util();
10670
+ var TERMINAL_WORKER_JSON_STATUSES = /* @__PURE__ */ new Set([
10671
+ "done",
10672
+ "exited",
10673
+ "blocked",
10674
+ "failed",
10675
+ "abandoned"
10676
+ ]);
9857
10677
  function deriveRunTerminal(indexed, ctx) {
9858
10678
  if (ctx) return ctx.runTerminalCache.derive(indexed.run);
9859
10679
  return deriveTerminalRunStatus(indexed.run);
9860
10680
  }
9861
10681
  function isWorkerProcessLive(indexed) {
9862
10682
  if (isPidAlive(indexed.worker.pid)) return true;
9863
- if (!indexed.worker.pid) return indexedWorktreeStatus(indexed).alive;
10683
+ if (typeof indexed.worker.completionReportedAt === "string" && indexed.worker.completionReportedAt.trim().length > 0) {
10684
+ return false;
10685
+ }
10686
+ const workerStatus2 = indexed.worker.status;
10687
+ if (workerStatus2 && TERMINAL_WORKER_JSON_STATUSES.has(workerStatus2)) return false;
10688
+ if (!indexed.worker.pid) {
10689
+ if (workerStatus2 !== "running") return false;
10690
+ return indexedWorktreeStatus(indexed).alive;
10691
+ }
9864
10692
  return false;
9865
10693
  }
9866
10694
  function isRunStaleActive(indexed, ctx) {
@@ -9869,6 +10697,10 @@ function isRunStaleActive(indexed, ctx) {
9869
10697
  }
9870
10698
  function runBlocksWorktreeRemoval(indexed, ctx) {
9871
10699
  if (isWorkerProcessLive(indexed)) return true;
10700
+ const workerStatus2 = indexed.worker.status;
10701
+ if (workerStatus2 && TERMINAL_WORKER_JSON_STATUSES.has(workerStatus2) && !indexed.worker.completionBlocker) {
10702
+ return false;
10703
+ }
9872
10704
  const status = indexedWorktreeStatus(indexed);
9873
10705
  if (completionBlockerBlocksWorktreeRemoval(indexed, status)) return true;
9874
10706
  if (isFinishedWorkerStatus(status)) return false;
@@ -9887,7 +10719,7 @@ function effectiveWorktreeAgeMs(input) {
9887
10719
  if (input.liveness && isRunStaleActive(indexed, input.liveness)) {
9888
10720
  return terminalWorktreesAgeMs;
9889
10721
  }
9890
- if (input.liveness && isFinishedWorkerStatus(indexedWorktreeStatus(indexed)) && !isWorkerProcessLive(indexed)) {
10722
+ if (input.liveness && isFinishedWorkerStatus(resolveWorktreeGuardStatus(indexed, input.liveness)) && !isWorkerProcessLive(indexed)) {
9891
10723
  return terminalWorktreesAgeMs;
9892
10724
  }
9893
10725
  return worktreesAgeMs;
@@ -9901,8 +10733,13 @@ function skipWorktreeRemoval(input) {
9901
10733
  const ageThresholdMs = effectiveWorktreeAgeMs(input);
9902
10734
  if (worktreesAgeMs <= 0 && !includeOrphans && ageThresholdMs <= 0) return "worktrees_disabled";
9903
10735
  if (ageThresholdMs > 0 && ageMs < ageThresholdMs) return "below_age_threshold";
9904
- const status = indexedWorktreeStatus(indexed);
9905
10736
  if (isWorkerProcessLive(indexed)) return "active_worker";
10737
+ if (indexedWorktreeHasMaterialChanges(indexed, input.liveness?.gitStatusCache)) {
10738
+ return "dirty_worktree";
10739
+ }
10740
+ const ahead = input.liveness?.gitRevCache?.countAheadOfMain(input.worktreePath);
10741
+ if (ahead !== null && ahead !== void 0 && ahead > 0) return "pr_or_unmerged_commits";
10742
+ const status = resolveWorktreeGuardStatus(indexed, input.liveness);
9906
10743
  if (completionBlockerBlocksWorktreeRemoval(indexed, status)) return "completion_blocked";
9907
10744
  if (runBlocksWorktreeRemoval(indexed, input.liveness)) return "run_still_active";
9908
10745
  if (!isFinishedWorkerStatus(status)) return "run_still_active";
@@ -9931,9 +10768,11 @@ function skipWorktreeRemoval(input) {
9931
10768
  function skipDependencyCacheRemoval(input) {
9932
10769
  const { indexed, nodeModulesAgeMs, ageMs, worktreePath, activeWorktreePaths, diskPressure } = input;
9933
10770
  if (!diskPressure && ageMs < nodeModulesAgeMs) return "below_age_threshold";
9934
- if (activeWorktreePaths.has(path40.resolve(worktreePath))) return "active_worker";
10771
+ if (activeWorktreePaths.has(path41.resolve(worktreePath))) return "active_worker";
9935
10772
  if (indexed && isWorkerProcessLive(indexed)) return "active_worker";
9936
- if (indexed && indexedWorktreeHasMaterialChanges(indexed)) return "dirty_worktree";
10773
+ if (indexed && indexedWorktreeHasMaterialChanges(indexed, input.gitStatusCache)) {
10774
+ return "dirty_worktree";
10775
+ }
9937
10776
  return null;
9938
10777
  }
9939
10778
  function skipBuildCacheRemoval(input) {
@@ -9958,11 +10797,11 @@ var LIVE_SKIP_REASONS = /* @__PURE__ */ new Set([
9958
10797
  function collectPreservedLivePaths(actions, skips) {
9959
10798
  const out = [];
9960
10799
  const seen = /* @__PURE__ */ new Set();
9961
- const push = (path71, reason, detail) => {
9962
- const key = `${path71}\0${reason}`;
10800
+ const push = (path73, reason, detail) => {
10801
+ const key = `${path73}\0${reason}`;
9963
10802
  if (seen.has(key) || out.length >= MAX_PRESERVED_LIVE_PATH_SAMPLES) return;
9964
10803
  seen.add(key);
9965
- out.push({ path: path71, reason, ...detail ? { detail } : {} });
10804
+ out.push({ path: path73, reason, ...detail ? { detail } : {} });
9966
10805
  };
9967
10806
  for (const skip2 of skips) {
9968
10807
  if (!LIVE_SKIP_REASONS.has(skip2.reason)) continue;
@@ -9978,11 +10817,14 @@ function collectPreservedLivePaths(actions, skips) {
9978
10817
 
9979
10818
  // src/cleanup-run-directory.ts
9980
10819
  import { existsSync as existsSync30, readdirSync as readdirSync9, statSync as statSync7 } from "node:fs";
9981
- import path42 from "node:path";
10820
+ import path43 from "node:path";
9982
10821
 
9983
10822
  // src/cleanup-active-worktrees.ts
10823
+ init_run_store();
10824
+ init_paths();
9984
10825
  import { existsSync as existsSync29, readdirSync as readdirSync8, statSync as statSync6 } from "node:fs";
9985
- import path41 from "node:path";
10826
+ import path42 from "node:path";
10827
+ init_util();
9986
10828
  function workerHasRecentHarnessActivity(worker, now) {
9987
10829
  const paths = [worker.heartbeatPath, worker.stdoutPath, worker.stderrPath];
9988
10830
  for (const target of paths) {
@@ -10008,11 +10850,11 @@ function collectActiveWorktreeGuards(harnessRoots, now = Date.now()) {
10008
10850
  let runHasLive = false;
10009
10851
  for (const name of Object.keys(run.workers || {})) {
10010
10852
  const worker = readJson(
10011
- path41.join(runDirectoryAt(harnessRoot, run.id), "workers", safeSlug(name), "worker.json"),
10853
+ path42.join(runDirectoryAt(harnessRoot, run.id), "workers", safeSlug(name), "worker.json"),
10012
10854
  void 0
10013
10855
  );
10014
10856
  if (!worker?.worktreePath) continue;
10015
- const worktreePath = path41.resolve(worker.worktreePath);
10857
+ const worktreePath = path42.resolve(worker.worktreePath);
10016
10858
  if (!isActiveHarnessWorker2(worker, now)) continue;
10017
10859
  runHasLive = true;
10018
10860
  activeWorktreePaths.add(worktreePath);
@@ -10031,6 +10873,7 @@ function isWorktreeOnLiveRun(worktreePath, harnessRoot, runId, liveRunKeys) {
10031
10873
  }
10032
10874
 
10033
10875
  // src/cleanup-run-directory.ts
10876
+ init_util();
10034
10877
  function pathAgeMs(target, now) {
10035
10878
  try {
10036
10879
  const mtime = statSync7(target).mtimeMs;
@@ -10040,7 +10883,7 @@ function pathAgeMs(target, now) {
10040
10883
  }
10041
10884
  }
10042
10885
  function loadRunStatus(harnessRoot, runId) {
10043
- const runPath = path42.join(harnessRoot, "runs", runId, "run.json");
10886
+ const runPath = path43.join(harnessRoot, "runs", runId, "run.json");
10044
10887
  if (!existsSync30(runPath)) return null;
10045
10888
  return readJson(runPath, null);
10046
10889
  }
@@ -10078,7 +10921,7 @@ function scanStaleRunDirectoryCandidates(opts) {
10078
10921
  if (!runEntry.isDirectory()) continue;
10079
10922
  const runId = runEntry.name;
10080
10923
  if (opts.runIdFilter && runId !== opts.runIdFilter) continue;
10081
- const runPath = path42.join(opts.worktreesDir, runId);
10924
+ const runPath = path43.join(opts.worktreesDir, runId);
10082
10925
  if (!runDirectoryIsEmpty(runPath)) continue;
10083
10926
  candidates.push({
10084
10927
  kind: "remove_run_directory",
@@ -10093,12 +10936,13 @@ function scanStaleRunDirectoryCandidates(opts) {
10093
10936
  }
10094
10937
 
10095
10938
  // src/cleanup-execute.ts
10939
+ init_git();
10096
10940
  import { existsSync as existsSync33, rmSync as rmSync4 } from "node:fs";
10097
10941
 
10098
10942
  // src/cleanup-dir-size.ts
10099
10943
  import { execFileSync as execFileSync2 } from "node:child_process";
10100
10944
  import { existsSync as existsSync31, readdirSync as readdirSync10, statSync as statSync8 } from "node:fs";
10101
- import path43 from "node:path";
10945
+ import path44 from "node:path";
10102
10946
  var DEFAULT_DU_TIMEOUT_MS = 2500;
10103
10947
  function directorySizeBytesDu(root, timeoutMs = DEFAULT_DU_TIMEOUT_MS) {
10104
10948
  if (!existsSync31(root)) return 0;
@@ -10132,7 +10976,7 @@ function directorySizeBytes(root, maxEntries = 5e4) {
10132
10976
  }
10133
10977
  for (const name of entries) {
10134
10978
  if (seen++ > maxEntries) return null;
10135
- const full = path43.join(current, name);
10979
+ const full = path44.join(current, name);
10136
10980
  let st;
10137
10981
  try {
10138
10982
  st = statSync8(full);
@@ -10148,6 +10992,7 @@ function directorySizeBytes(root, maxEntries = 5e4) {
10148
10992
 
10149
10993
  // src/cleanup-remove-path.ts
10150
10994
  import { existsSync as existsSync32, rmSync as rmSync3 } from "node:fs";
10995
+ init_paths();
10151
10996
 
10152
10997
  // src/cleanup-path-ownership.ts
10153
10998
  import { lstatSync as lstatSync2, readdirSync as readdirSync11 } from "node:fs";
@@ -10183,20 +11028,20 @@ function pathHasForeignOwnedEntry(targetPath, maxEntries = 32) {
10183
11028
 
10184
11029
  // src/cleanup-privileged-remove.ts
10185
11030
  import { spawnSync as spawnSync6 } from "node:child_process";
10186
- import path45 from "node:path";
11031
+ import path46 from "node:path";
10187
11032
 
10188
11033
  // src/cleanup-harness-path-validate.ts
10189
- import path44 from "node:path";
11034
+ import path45 from "node:path";
10190
11035
  function isHarnessDependencyCachePath(targetPath, harnessRoot, worktreesDir, cacheDirName) {
10191
- const resolved = path44.resolve(targetPath);
10192
- const suffix = `${path44.sep}${cacheDirName}`;
11036
+ const resolved = path45.resolve(targetPath);
11037
+ const suffix = `${path45.sep}${cacheDirName}`;
10193
11038
  const cachePath = resolved.endsWith(suffix) ? resolved : null;
10194
11039
  if (!cachePath) return "path_outside_harness";
10195
- const rel = path44.relative(worktreesDir, cachePath);
10196
- if (rel.startsWith("..") || path44.isAbsolute(rel)) return "path_outside_harness";
10197
- const parts = rel.split(path44.sep);
11040
+ const rel = path45.relative(worktreesDir, cachePath);
11041
+ if (rel.startsWith("..") || path45.isAbsolute(rel)) return "path_outside_harness";
11042
+ const parts = rel.split(path45.sep);
10198
11043
  if (parts.length < 3 || parts[parts.length - 1] !== cacheDirName) return "path_outside_harness";
10199
- if (!resolved.startsWith(path44.resolve(harnessRoot))) return "path_outside_harness";
11044
+ if (!resolved.startsWith(path45.resolve(harnessRoot))) return "path_outside_harness";
10200
11045
  return null;
10201
11046
  }
10202
11047
  function isHarnessNodeModulesPath(targetPath, harnessRoot, worktreesDir) {
@@ -10206,16 +11051,16 @@ function isHarnessNextCachePath(targetPath, harnessRoot, worktreesDir) {
10206
11051
  return isHarnessDependencyCachePath(targetPath, harnessRoot, worktreesDir, ".next");
10207
11052
  }
10208
11053
  function isHarnessBuildCachePath(targetPath, harnessRoot, worktreesDir) {
10209
- const resolved = path44.resolve(targetPath);
10210
- const relToWt = path44.relative(worktreesDir, resolved);
10211
- if (relToWt.startsWith("..") || path44.isAbsolute(relToWt)) return "path_outside_harness";
10212
- const parts = relToWt.split(path44.sep);
11054
+ const resolved = path45.resolve(targetPath);
11055
+ const relToWt = path45.relative(worktreesDir, resolved);
11056
+ if (relToWt.startsWith("..") || path45.isAbsolute(relToWt)) return "path_outside_harness";
11057
+ const parts = relToWt.split(path45.sep);
10213
11058
  if (parts.length < 3) return "path_outside_harness";
10214
- if (!resolved.startsWith(path44.resolve(harnessRoot))) return "path_outside_harness";
11059
+ if (!resolved.startsWith(path45.resolve(harnessRoot))) return "path_outside_harness";
10215
11060
  return null;
10216
11061
  }
10217
11062
  function isHarnessGeneratedCachePath(targetPath, harnessRoot, worktreesDir) {
10218
- const resolved = path44.resolve(targetPath);
11063
+ const resolved = path45.resolve(targetPath);
10219
11064
  return isHarnessNodeModulesPath(resolved, harnessRoot, worktreesDir) === null || isHarnessNextCachePath(resolved, harnessRoot, worktreesDir) === null || isHarnessBuildCachePath(resolved, harnessRoot, worktreesDir) === null;
10220
11065
  }
10221
11066
 
@@ -10249,12 +11094,12 @@ function tryPrivilegedReclaimHarnessCache(targetPath, harnessRoot, worktreesDir)
10249
11094
  "chown",
10250
11095
  "-R",
10251
11096
  `${effectiveUid}:${effectiveGid}`,
10252
- path45.resolve(targetPath)
11097
+ path46.resolve(targetPath)
10253
11098
  ]);
10254
11099
  if (chown.ok) {
10255
11100
  return { ok: true, method: "chown_then_rm" };
10256
11101
  }
10257
- const rm = runSudoNonInteractive(["rm", "-rf", path45.resolve(targetPath)]);
11102
+ const rm = runSudoNonInteractive(["rm", "-rf", path46.resolve(targetPath)]);
10258
11103
  if (rm.ok) {
10259
11104
  return { ok: true, method: "sudo_rm" };
10260
11105
  }
@@ -10456,7 +11301,7 @@ function removeWorktree(candidate, execute) {
10456
11301
 
10457
11302
  // src/cleanup-scan.ts
10458
11303
  import { existsSync as existsSync34, readdirSync as readdirSync12, statSync as statSync9 } from "node:fs";
10459
- import path46 from "node:path";
11304
+ import path47 from "node:path";
10460
11305
  function pathAgeMs2(target, now) {
10461
11306
  try {
10462
11307
  const mtime = statSync9(target).mtimeMs;
@@ -10466,16 +11311,16 @@ function pathAgeMs2(target, now) {
10466
11311
  }
10467
11312
  }
10468
11313
  function isPathInside(child, parent) {
10469
- const rel = path46.relative(parent, child);
10470
- return rel === "" || !rel.startsWith("..") && !path46.isAbsolute(rel);
11314
+ const rel = path47.relative(parent, child);
11315
+ return rel === "" || !rel.startsWith("..") && !path47.isAbsolute(rel);
10471
11316
  }
10472
11317
  function collectBuildCacheForWorktree(worktreePath, opts, seen, meta) {
10473
11318
  const out = [];
10474
11319
  for (const rel of HARNESS_BUILD_CACHE_RELATIVE_PATHS) {
10475
11320
  if (rel === ".next") continue;
10476
- const target = path46.join(worktreePath, rel);
11321
+ const target = path47.join(worktreePath, rel);
10477
11322
  if (!existsSync34(target)) continue;
10478
- const resolved = path46.resolve(target);
11323
+ const resolved = path47.resolve(target);
10479
11324
  if (seen.has(resolved)) continue;
10480
11325
  if (!isPathInside(resolved, opts.harnessRoot)) continue;
10481
11326
  seen.add(resolved);
@@ -10507,10 +11352,10 @@ function scanBuildCacheCandidates(opts) {
10507
11352
  if (!opts.includeOrphans || !existsSync34(opts.worktreesDir)) return candidates;
10508
11353
  for (const runEntry of readdirSync12(opts.worktreesDir, { withFileTypes: true })) {
10509
11354
  if (!runEntry.isDirectory()) continue;
10510
- const runPath = path46.join(opts.worktreesDir, runEntry.name);
11355
+ const runPath = path47.join(opts.worktreesDir, runEntry.name);
10511
11356
  for (const workerEntry of readdirSync12(runPath, { withFileTypes: true })) {
10512
11357
  if (!workerEntry.isDirectory()) continue;
10513
- const worktreePath = path46.join(runPath, workerEntry.name);
11358
+ const worktreePath = path47.join(runPath, workerEntry.name);
10514
11359
  candidates.push(
10515
11360
  ...collectBuildCacheForWorktree(worktreePath, opts, seen, {
10516
11361
  runId: runEntry.name,
@@ -10548,12 +11393,12 @@ function scanWorktreeCandidates(opts) {
10548
11393
  if (!orphanEnabled || !existsSync34(opts.worktreesDir)) return candidates;
10549
11394
  const indexedPaths = /* @__PURE__ */ new Set();
10550
11395
  for (const entry of opts.index.values()) {
10551
- indexedPaths.add(path46.resolve(entry.worktreePath));
11396
+ indexedPaths.add(path47.resolve(entry.worktreePath));
10552
11397
  }
10553
11398
  for (const runEntry of readdirSync12(opts.worktreesDir, { withFileTypes: true })) {
10554
11399
  if (!runEntry.isDirectory()) continue;
10555
11400
  if (opts.runIdFilter && runEntry.name !== opts.runIdFilter) continue;
10556
- const runPath = path46.join(opts.worktreesDir, runEntry.name);
11401
+ const runPath = path47.join(opts.worktreesDir, runEntry.name);
10557
11402
  let workerEntries;
10558
11403
  try {
10559
11404
  workerEntries = readdirSync12(runPath, { withFileTypes: true });
@@ -10562,7 +11407,7 @@ function scanWorktreeCandidates(opts) {
10562
11407
  }
10563
11408
  for (const workerEntry of workerEntries) {
10564
11409
  if (!workerEntry.isDirectory()) continue;
10565
- const worktreePath = path46.resolve(path46.join(runPath, workerEntry.name));
11410
+ const worktreePath = path47.resolve(path47.join(runPath, workerEntry.name));
10566
11411
  if (seen.has(worktreePath)) continue;
10567
11412
  if (indexedPaths.has(worktreePath)) continue;
10568
11413
  if (!isPathInside(worktreePath, opts.harnessRoot)) continue;
@@ -10582,7 +11427,7 @@ function scanWorktreeCandidates(opts) {
10582
11427
 
10583
11428
  // src/cleanup-dependency-scan.ts
10584
11429
  import { existsSync as existsSync35, readdirSync as readdirSync13, statSync as statSync10 } from "node:fs";
10585
- import path47 from "node:path";
11430
+ import path48 from "node:path";
10586
11431
  var DEPENDENCY_CACHE_DIRS = [
10587
11432
  { dirName: "node_modules", kind: "remove_node_modules" },
10588
11433
  { dirName: ".next", kind: "remove_next_cache" }
@@ -10596,12 +11441,12 @@ function pathAgeMs3(target, now) {
10596
11441
  }
10597
11442
  }
10598
11443
  function isPathInside2(child, parent) {
10599
- const rel = path47.relative(parent, child);
10600
- return rel === "" || !rel.startsWith("..") && !path47.isAbsolute(rel);
11444
+ const rel = path48.relative(parent, child);
11445
+ return rel === "" || !rel.startsWith("..") && !path48.isAbsolute(rel);
10601
11446
  }
10602
11447
  function pushCandidate2(candidates, seen, opts, targetPath, kind, meta) {
10603
11448
  if (!existsSync35(targetPath)) return;
10604
- const resolved = path47.resolve(targetPath);
11449
+ const resolved = path48.resolve(targetPath);
10605
11450
  if (seen.has(resolved)) return;
10606
11451
  if (!isPathInside2(resolved, opts.harnessRoot)) return;
10607
11452
  seen.add(resolved);
@@ -10618,7 +11463,7 @@ function pushCandidate2(candidates, seen, opts, targetPath, kind, meta) {
10618
11463
  }
10619
11464
  function scanWorktreeDependencyCaches(candidates, seen, opts, worktreePath, meta) {
10620
11465
  for (const entry of DEPENDENCY_CACHE_DIRS) {
10621
- pushCandidate2(candidates, seen, opts, path47.join(worktreePath, entry.dirName), entry.kind, meta);
11466
+ pushCandidate2(candidates, seen, opts, path48.join(worktreePath, entry.dirName), entry.kind, meta);
10622
11467
  }
10623
11468
  }
10624
11469
  function scanDependencyCacheCandidates(opts) {
@@ -10636,7 +11481,7 @@ function scanDependencyCacheCandidates(opts) {
10636
11481
  for (const runEntry of readdirSync13(opts.worktreesDir, { withFileTypes: true })) {
10637
11482
  if (!runEntry.isDirectory()) continue;
10638
11483
  if (opts.runIdFilter && runEntry.name !== opts.runIdFilter) continue;
10639
- const runPath = path47.join(opts.worktreesDir, runEntry.name);
11484
+ const runPath = path48.join(opts.worktreesDir, runEntry.name);
10640
11485
  let workerEntries;
10641
11486
  try {
10642
11487
  workerEntries = readdirSync13(runPath, { withFileTypes: true });
@@ -10645,7 +11490,7 @@ function scanDependencyCacheCandidates(opts) {
10645
11490
  }
10646
11491
  for (const workerEntry of workerEntries) {
10647
11492
  if (!workerEntry.isDirectory()) continue;
10648
- const worktreePath = path47.join(runPath, workerEntry.name);
11493
+ const worktreePath = path48.join(runPath, workerEntry.name);
10649
11494
  scanWorktreeDependencyCaches(candidates, seen, opts, worktreePath, {
10650
11495
  runId: runEntry.name,
10651
11496
  worker: workerEntry.name
@@ -10656,8 +11501,9 @@ function scanDependencyCacheCandidates(opts) {
10656
11501
  }
10657
11502
 
10658
11503
  // src/cleanup-duplicate-worktrees.ts
11504
+ init_git();
10659
11505
  import { existsSync as existsSync36, statSync as statSync11 } from "node:fs";
10660
- import path48 from "node:path";
11506
+ import path49 from "node:path";
10661
11507
  function pathAgeMs4(target, now) {
10662
11508
  try {
10663
11509
  const mtime = statSync11(target).mtimeMs;
@@ -10687,8 +11533,8 @@ function parseWorktreePorcelain(output) {
10687
11533
  return records;
10688
11534
  }
10689
11535
  function isUnderWorktreesDir(worktreePath, worktreesDir) {
10690
- const rel = path48.relative(path48.resolve(worktreesDir), path48.resolve(worktreePath));
10691
- return rel !== "" && !rel.startsWith("..") && !path48.isAbsolute(rel);
11536
+ const rel = path49.relative(path49.resolve(worktreesDir), path49.resolve(worktreePath));
11537
+ return rel !== "" && !rel.startsWith("..") && !path49.isAbsolute(rel);
10692
11538
  }
10693
11539
  function isCleanWorktree(worktreePath, repoRoot) {
10694
11540
  try {
@@ -10704,11 +11550,11 @@ function scanDuplicateWorktreeCandidates(opts) {
10704
11550
  if (!opts.includeOrphans || !existsSync36(opts.worktreesDir)) return [];
10705
11551
  const repos = /* @__PURE__ */ new Set();
10706
11552
  for (const entry of opts.index.values()) {
10707
- if (entry.run.repo) repos.add(path48.resolve(entry.run.repo));
11553
+ if (entry.run.repo) repos.add(path49.resolve(entry.run.repo));
10708
11554
  }
10709
11555
  const indexedPaths = /* @__PURE__ */ new Set();
10710
11556
  for (const entry of opts.index.values()) {
10711
- indexedPaths.add(path48.resolve(entry.worktreePath));
11557
+ indexedPaths.add(path49.resolve(entry.worktreePath));
10712
11558
  }
10713
11559
  const candidates = [];
10714
11560
  const seen = /* @__PURE__ */ new Set();
@@ -10721,15 +11567,15 @@ function scanDuplicateWorktreeCandidates(opts) {
10721
11567
  }
10722
11568
  const worktrees = parseWorktreePorcelain(porcelain);
10723
11569
  for (const wt of worktrees) {
10724
- const resolved = path48.resolve(wt.path);
10725
- if (resolved === path48.resolve(repoRoot)) continue;
11570
+ const resolved = path49.resolve(wt.path);
11571
+ if (resolved === path49.resolve(repoRoot)) continue;
10726
11572
  if (!isUnderWorktreesDir(resolved, opts.worktreesDir)) continue;
10727
11573
  if (indexedPaths.has(resolved)) continue;
10728
11574
  if (seen.has(resolved)) continue;
10729
11575
  if (!existsSync36(resolved)) continue;
10730
11576
  if (!isCleanWorktree(resolved, repoRoot)) continue;
10731
- const rel = path48.relative(opts.worktreesDir, resolved);
10732
- const parts = rel.split(path48.sep);
11577
+ const rel = path49.relative(opts.worktreesDir, resolved);
11578
+ const parts = rel.split(path49.sep);
10733
11579
  const runId = parts[0];
10734
11580
  const worker = parts[1] ?? "unknown";
10735
11581
  seen.add(resolved);
@@ -10748,12 +11594,14 @@ function scanDuplicateWorktreeCandidates(opts) {
10748
11594
  }
10749
11595
 
10750
11596
  // src/cleanup-worktree-index.ts
10751
- import path49 from "node:path";
11597
+ init_run_store();
11598
+ init_util();
11599
+ import path50 from "node:path";
10752
11600
  function buildWorktreeIndexAt(harnessRoot) {
10753
11601
  const index = /* @__PURE__ */ new Map();
10754
11602
  for (const run of listRunRecordsForHarnessRoot(harnessRoot)) {
10755
11603
  for (const name of Object.keys(run.workers || {})) {
10756
- const workerPath = path49.join(
11604
+ const workerPath = path50.join(
10757
11605
  runDirectoryAt(harnessRoot, run.id),
10758
11606
  "workers",
10759
11607
  safeSlug(name),
@@ -10761,9 +11609,9 @@ function buildWorktreeIndexAt(harnessRoot) {
10761
11609
  );
10762
11610
  const worker = readJson(workerPath, void 0);
10763
11611
  if (!worker?.worktreePath) continue;
10764
- index.set(path49.resolve(worker.worktreePath), {
11612
+ index.set(path50.resolve(worker.worktreePath), {
10765
11613
  harnessRoot,
10766
- worktreePath: path49.resolve(worker.worktreePath),
11614
+ worktreePath: path50.resolve(worker.worktreePath),
10767
11615
  runId: run.id,
10768
11616
  workerName: name,
10769
11617
  run,
@@ -10775,7 +11623,7 @@ function buildWorktreeIndexAt(harnessRoot) {
10775
11623
  }
10776
11624
 
10777
11625
  // src/cleanup-retention-config.ts
10778
- function envFlag2(name) {
11626
+ function envFlag3(name) {
10779
11627
  const v = process.env[name];
10780
11628
  return v === "1" || v === "true" || v === "yes";
10781
11629
  }
@@ -10786,17 +11634,17 @@ function envMs(name, fallback) {
10786
11634
  return Number.isFinite(n) && n >= 0 ? n : fallback;
10787
11635
  }
10788
11636
  function resolveHarnessRetention(options = {}) {
10789
- const execute = options.execute === true || options.execute !== false && envFlag2("KYNVER_CLEANUP_EXECUTE");
10790
- const finalizeStaleRuns2 = options.finalizeStaleRuns !== false && !envFlag2("KYNVER_CLEANUP_SKIP_FINALIZE");
11637
+ const execute = options.execute === true || options.execute !== false && envFlag3("KYNVER_CLEANUP_EXECUTE");
11638
+ const finalizeStaleRuns2 = options.finalizeStaleRuns !== false && !envFlag3("KYNVER_CLEANUP_SKIP_FINALIZE");
10791
11639
  const nodeModulesAgeMs = options.nodeModulesAgeMs ?? envMs("KYNVER_CLEANUP_NODE_MODULES_AGE_MS", DEFAULT_NODE_MODULES_AGE_MS);
10792
11640
  const worktreesAgeMs = options.worktreesAgeMs ?? envMs("KYNVER_CLEANUP_WORKTREES_AGE_MS", 0);
10793
11641
  const terminalWorktreesAgeMs = options.terminalWorktreesAgeMs ?? envMs("KYNVER_CLEANUP_TERMINAL_WORKTREES_AGE_MS", DEFAULT_TERMINAL_WORKTREES_AGE_MS);
10794
11642
  const runDirectoriesAgeMs = options.runDirectoriesAgeMs ?? envMs("KYNVER_CLEANUP_RUN_DIRECTORIES_AGE_MS", DEFAULT_RUN_DIRECTORIES_AGE_MS);
10795
11643
  const maxActionsPerSweep = options.maxActionsPerSweep ?? envMs("KYNVER_CLEANUP_MAX_ACTIONS_PER_SWEEP", DEFAULT_MAX_ACTIONS_PER_SWEEP);
10796
- const includeOrphans = options.includeOrphans === true || envFlag2("KYNVER_CLEANUP_INCLUDE_ORPHANS");
10797
- const scopeAll = envFlag2("KYNVER_CLEANUP_SCOPE_ALL") || process.env.KYNVER_CLEANUP_SCOPE === "all";
11644
+ const includeOrphans = options.includeOrphans === true || envFlag3("KYNVER_CLEANUP_INCLUDE_ORPHANS");
11645
+ const scopeAll = envFlag3("KYNVER_CLEANUP_SCOPE_ALL") || process.env.KYNVER_CLEANUP_SCOPE === "all";
10798
11646
  const runIdFilter = scopeAll ? options.runIdFilter : options.runIdFilter ?? (process.env.KYNVER_CLEANUP_RUN_ID || void 0);
10799
- const accountBytes = options.accountBytes !== false && !envFlag2("KYNVER_CLEANUP_SKIP_BYTE_ACCOUNTING");
11647
+ const accountBytes = options.accountBytes !== false && !envFlag3("KYNVER_CLEANUP_SKIP_BYTE_ACCOUNTING");
10800
11648
  const storageCapEnv = envMs("KYNVER_CLEANUP_STORAGE_ENTRY_CAP", 2e3);
10801
11649
  const storagePerRunEntryCap = options.storagePerRunEntryCap !== void 0 ? options.storagePerRunEntryCap : accountBytes ? storageCapEnv > 0 ? storageCapEnv : null : null;
10802
11650
  const byteCapEnv = envMs("KYNVER_CLEANUP_BYTE_ENTRY_CAP", 2e3);
@@ -10832,15 +11680,16 @@ function resolvePipelineHarnessRetention(runId) {
10832
11680
  }
10833
11681
 
10834
11682
  // src/cleanup-orphan-safety.ts
11683
+ init_git();
10835
11684
  import { existsSync as existsSync37, statSync as statSync12 } from "node:fs";
10836
- import path50 from "node:path";
11685
+ import path51 from "node:path";
10837
11686
  var DEFAULT_HEARTBEAT_FRESH_MS = 30 * 60 * 1e3;
10838
11687
  function assessOrphanWorktreeSafety(input) {
10839
11688
  const now = input.now ?? Date.now();
10840
11689
  const heartbeatFreshMs = input.heartbeatFreshMs ?? DEFAULT_HEARTBEAT_FRESH_MS;
10841
11690
  if (!existsSync37(input.worktreePath)) return null;
10842
11691
  if (input.runId && input.workerName) {
10843
- const heartbeatPath = path50.join(
11692
+ const heartbeatPath = path51.join(
10844
11693
  input.harnessRoot,
10845
11694
  "runs",
10846
11695
  input.runId,
@@ -10854,7 +11703,7 @@ function assessOrphanWorktreeSafety(input) {
10854
11703
  } catch {
10855
11704
  }
10856
11705
  }
10857
- const gitDir = path50.join(input.worktreePath, ".git");
11706
+ const gitDir = path51.join(input.worktreePath, ".git");
10858
11707
  if (!existsSync37(gitDir)) return null;
10859
11708
  const porcelain = gitCapture(input.worktreePath, ["status", "--porcelain"]);
10860
11709
  if (porcelain.status !== 0) return "pr_or_unmerged_commits";
@@ -10884,8 +11733,9 @@ function assessOrphanWorktreeSafety(input) {
10884
11733
  }
10885
11734
 
10886
11735
  // src/harness-storage-snapshot.ts
11736
+ init_paths();
10887
11737
  import { existsSync as existsSync38, readdirSync as readdirSync14, statSync as statSync13 } from "node:fs";
10888
- import path51 from "node:path";
11738
+ import path52 from "node:path";
10889
11739
  function harnessStorageSnapshot(opts = {}) {
10890
11740
  const harnessRoot = normalizeHarnessRoot(opts.harnessRoot ?? resolveHarnessRoot());
10891
11741
  const worktreesDir = harnessWorktreesDir(harnessRoot);
@@ -10923,7 +11773,7 @@ function harnessStorageSnapshot(opts = {}) {
10923
11773
  for (const runEntry of entries) {
10924
11774
  if (!runEntry.isDirectory()) continue;
10925
11775
  runCount += 1;
10926
- const runPath = path51.join(worktreesDir, runEntry.name);
11776
+ const runPath = path52.join(worktreesDir, runEntry.name);
10927
11777
  try {
10928
11778
  const st = statSync13(runPath);
10929
11779
  oldestMs = oldestMs === null ? st.mtimeMs : Math.min(oldestMs, st.mtimeMs);
@@ -10958,12 +11808,13 @@ function harnessStorageSnapshot(opts = {}) {
10958
11808
  }
10959
11809
 
10960
11810
  // src/cleanup-harness-roots.ts
11811
+ init_paths();
10961
11812
  import { existsSync as existsSync39 } from "node:fs";
10962
- import { homedir as homedir12 } from "node:os";
10963
- import path52 from "node:path";
11813
+ import { homedir as homedir13 } from "node:os";
11814
+ import path53 from "node:path";
10964
11815
  var WELL_KNOWN_HARNESS_SCAN_ROOTS = [
10965
11816
  "/var/tmp/kynver-harness",
10966
- path52.join(homedir12(), ".openclaw", "harness")
11817
+ path53.join(homedir13(), ".openclaw", "harness")
10967
11818
  ];
10968
11819
  function addRoot(seen, roots, candidate) {
10969
11820
  if (!candidate?.trim()) return;
@@ -10985,7 +11836,7 @@ function resolveHarnessScanRoots(options = {}) {
10985
11836
  for (const candidate of extra ?? []) addRoot(seen, roots, candidate);
10986
11837
  if (shouldScanWellKnownRoots(options)) {
10987
11838
  for (const candidate of WELL_KNOWN_HARNESS_SCAN_ROOTS) {
10988
- const resolved = path52.resolve(candidate);
11839
+ const resolved = path53.resolve(candidate);
10989
11840
  if (!seen.has(resolved) && existsSync39(resolved)) addRoot(seen, roots, resolved);
10990
11841
  }
10991
11842
  }
@@ -10993,7 +11844,8 @@ function resolveHarnessScanRoots(options = {}) {
10993
11844
  }
10994
11845
 
10995
11846
  // src/cleanup-disk-pressure.ts
10996
- function envFlag3(name) {
11847
+ init_disk_gate();
11848
+ function envFlag4(name) {
10997
11849
  const v = process.env[name];
10998
11850
  return v === "1" || v === "true" || v === "yes";
10999
11851
  }
@@ -11016,7 +11868,7 @@ function observeCleanupDiskPressure(input = {}) {
11016
11868
  }
11017
11869
  function applyDiskPressureToRetention(retention, pressure) {
11018
11870
  if (!pressure.pressured) return retention;
11019
- const executeOnPressure = retention.execute || !envFlag3("KYNVER_CLEANUP_DRY_RUN_ON_PRESSURE");
11871
+ const executeOnPressure = retention.execute || !envFlag4("KYNVER_CLEANUP_DRY_RUN_ON_PRESSURE");
11020
11872
  return {
11021
11873
  ...retention,
11022
11874
  execute: executeOnPressure,
@@ -11041,6 +11893,39 @@ function emitCleanupProgress(phase, detail) {
11041
11893
  console.error(`[kynver cleanup] ${phase}${suffix}`);
11042
11894
  }
11043
11895
 
11896
+ // src/cleanup-git-rev-cache.ts
11897
+ init_git();
11898
+ var CleanupGitRevCache = class {
11899
+ aheadOfMain = /* @__PURE__ */ new Map();
11900
+ countAheadOfMain(worktreePath, base = "origin/main") {
11901
+ const key = `${worktreePath}\0${base}`;
11902
+ if (this.aheadOfMain.has(key)) return this.aheadOfMain.get(key) ?? null;
11903
+ const result = gitCapture(worktreePath, ["rev-list", "--count", `${base}..HEAD`]);
11904
+ if (result.status !== 0) {
11905
+ this.aheadOfMain.set(key, null);
11906
+ return null;
11907
+ }
11908
+ const count = Number(result.stdout.trim());
11909
+ const parsed = Number.isFinite(count) ? count : null;
11910
+ this.aheadOfMain.set(key, parsed);
11911
+ return parsed;
11912
+ }
11913
+ };
11914
+
11915
+ // src/cleanup-git-status-cache.ts
11916
+ init_git();
11917
+ var CleanupGitStatusCache = class {
11918
+ cache = /* @__PURE__ */ new Map();
11919
+ porcelain(worktreePath) {
11920
+ const resolved = worktreePath;
11921
+ const cached = this.cache.get(resolved);
11922
+ if (cached !== void 0) return cached;
11923
+ const lines = gitStatusShort(resolved);
11924
+ this.cache.set(resolved, lines);
11925
+ return lines;
11926
+ }
11927
+ };
11928
+
11044
11929
  // src/cleanup-run-terminal-cache.ts
11045
11930
  var CleanupRunTerminalCache = class {
11046
11931
  cache = /* @__PURE__ */ new Map();
@@ -11140,9 +12025,9 @@ function mergeWorktreeIndexes(scanRoots) {
11140
12025
  }
11141
12026
  function worktreePathForCandidate(candidate, worktreesDir) {
11142
12027
  if (candidate.runId && candidate.worker) {
11143
- return path53.join(worktreesDir, candidate.runId, candidate.worker);
12028
+ return path54.join(worktreesDir, candidate.runId, candidate.worker);
11144
12029
  }
11145
- return path53.resolve(candidate.path, "..");
12030
+ return path54.resolve(candidate.path, "..");
11146
12031
  }
11147
12032
  function runHarnessCleanup(options = {}) {
11148
12033
  let retention = resolveHarnessRetention(options);
@@ -11158,7 +12043,11 @@ function runHarnessCleanup(options = {}) {
11158
12043
  emitCleanupProgress("index", "building worktree index");
11159
12044
  const index = mergeWorktreeIndexes(paths.scanRoots);
11160
12045
  emitCleanupProgress("index", `${index.size} indexed worktree(s)`);
11161
- const liveness = { runTerminalCache: new CleanupRunTerminalCache() };
12046
+ const liveness = {
12047
+ runTerminalCache: new CleanupRunTerminalCache(),
12048
+ gitStatusCache: new CleanupGitStatusCache(),
12049
+ gitRevCache: new CleanupGitRevCache()
12050
+ };
11162
12051
  const skips = [];
11163
12052
  const actions = [];
11164
12053
  const processedPaths = /* @__PURE__ */ new Set();
@@ -11167,7 +12056,7 @@ function runHarnessCleanup(options = {}) {
11167
12056
  for (const harnessRoot of paths.scanRoots) {
11168
12057
  if (atSweepCap()) break;
11169
12058
  emitCleanupProgress("root", harnessRoot);
11170
- const worktreesDir = path53.join(harnessRoot, "worktrees");
12059
+ const worktreesDir = path54.join(harnessRoot, "worktrees");
11171
12060
  const scanOpts = {
11172
12061
  harnessRoot,
11173
12062
  worktreesDir,
@@ -11178,9 +12067,16 @@ function runHarnessCleanup(options = {}) {
11178
12067
  index,
11179
12068
  now: paths.now
11180
12069
  };
11181
- for (const raw of scanDependencyCacheCandidates(scanOpts)) {
12070
+ const dependencyCandidates = scanDependencyCacheCandidates(scanOpts);
12071
+ emitCleanupProgress("dependency", `${dependencyCandidates.length} cache candidate(s) at ${harnessRoot}`);
12072
+ let dependencyProcessed = 0;
12073
+ for (const raw of dependencyCandidates) {
11182
12074
  if (atSweepCap()) break;
11183
- const resolved = path53.resolve(raw.path);
12075
+ dependencyProcessed += 1;
12076
+ if (dependencyProcessed % 50 === 0) {
12077
+ emitCleanupProgress("dependency", `${dependencyProcessed}/${dependencyCandidates.length} evaluated`);
12078
+ }
12079
+ const resolved = path54.resolve(raw.path);
11184
12080
  if (processedPaths.has(resolved)) continue;
11185
12081
  processedPaths.add(resolved);
11186
12082
  const candidate = { ...raw, path: resolved };
@@ -11191,7 +12087,7 @@ function runHarnessCleanup(options = {}) {
11191
12087
  continue;
11192
12088
  }
11193
12089
  const worktreePath = worktreePathForCandidate(candidate, worktreesDir);
11194
- const indexed = index.get(path53.resolve(worktreePath)) ?? null;
12090
+ const indexed = index.get(path54.resolve(worktreePath)) ?? null;
11195
12091
  const guardReason = skipDependencyCacheRemoval({
11196
12092
  indexed,
11197
12093
  includeOrphans: true,
@@ -11199,7 +12095,8 @@ function runHarnessCleanup(options = {}) {
11199
12095
  ageMs: candidate.ageMs,
11200
12096
  worktreePath,
11201
12097
  activeWorktreePaths: activeGuards.activeWorktreePaths,
11202
- diskPressure: retention.diskPressure
12098
+ diskPressure: retention.diskPressure,
12099
+ gitStatusCache: liveness.gitStatusCache
11203
12100
  });
11204
12101
  if (guardReason) {
11205
12102
  recordSkip(skips, candidate.path, guardReason);
@@ -11215,7 +12112,7 @@ function runHarnessCleanup(options = {}) {
11215
12112
  }
11216
12113
  for (const raw of scanBuildCacheCandidates(scanOpts)) {
11217
12114
  if (atSweepCap()) break;
11218
- const resolved = path53.resolve(raw.path);
12115
+ const resolved = path54.resolve(raw.path);
11219
12116
  if (processedPaths.has(resolved)) continue;
11220
12117
  processedPaths.add(resolved);
11221
12118
  const candidate = { ...raw, path: resolved };
@@ -11226,7 +12123,7 @@ function runHarnessCleanup(options = {}) {
11226
12123
  continue;
11227
12124
  }
11228
12125
  const worktreePath = worktreePathForCandidate(candidate, worktreesDir);
11229
- const indexed = index.get(path53.resolve(worktreePath)) ?? null;
12126
+ const indexed = index.get(path54.resolve(worktreePath)) ?? null;
11230
12127
  const guardReason = skipBuildCacheRemoval({
11231
12128
  indexed,
11232
12129
  includeOrphans: true,
@@ -11234,7 +12131,8 @@ function runHarnessCleanup(options = {}) {
11234
12131
  ageMs: candidate.ageMs,
11235
12132
  worktreePath,
11236
12133
  activeWorktreePaths: activeGuards.activeWorktreePaths,
11237
- diskPressure: retention.diskPressure
12134
+ diskPressure: retention.diskPressure,
12135
+ gitStatusCache: liveness.gitStatusCache
11238
12136
  });
11239
12137
  if (guardReason) {
11240
12138
  recordSkip(skips, candidate.path, guardReason);
@@ -11254,13 +12152,18 @@ function runHarnessCleanup(options = {}) {
11254
12152
  ];
11255
12153
  emitCleanupProgress("worktrees", `${worktreeCandidates.length} candidate(s) at ${harnessRoot}`);
11256
12154
  const worktreeSeen = /* @__PURE__ */ new Set();
12155
+ let worktreeProcessed = 0;
11257
12156
  for (const raw of worktreeCandidates) {
11258
12157
  if (atSweepCap()) break;
11259
- const resolved = path53.resolve(raw.path);
12158
+ worktreeProcessed += 1;
12159
+ if (worktreeProcessed % 50 === 0) {
12160
+ emitCleanupProgress("worktrees", `${worktreeProcessed}/${worktreeCandidates.length} evaluated`);
12161
+ }
12162
+ const resolved = path54.resolve(raw.path);
11260
12163
  if (worktreeSeen.has(resolved)) continue;
11261
12164
  worktreeSeen.add(resolved);
11262
12165
  const candidate = { ...raw, path: resolved };
11263
- const indexed = index.get(path53.resolve(candidate.path)) ?? null;
12166
+ const indexed = index.get(path54.resolve(candidate.path)) ?? null;
11264
12167
  const orphanSafety = indexed ? null : assessOrphanWorktreeSafety({
11265
12168
  worktreePath: candidate.path,
11266
12169
  harnessRoot,
@@ -11270,7 +12173,7 @@ function runHarnessCleanup(options = {}) {
11270
12173
  });
11271
12174
  const guardSkip = skipWorktreeRemoval({
11272
12175
  indexed,
11273
- worktreePath: path53.resolve(candidate.path),
12176
+ worktreePath: path54.resolve(candidate.path),
11274
12177
  includeOrphans: retention.includeOrphans,
11275
12178
  worktreesAgeMs: retention.worktreesAgeMs,
11276
12179
  terminalWorktreesAgeMs: retention.terminalWorktreesAgeMs,
@@ -11302,11 +12205,11 @@ function runHarnessCleanup(options = {}) {
11302
12205
  now: paths.now
11303
12206
  })) {
11304
12207
  if (atSweepCap()) break;
11305
- const resolved = path53.resolve(raw.path);
12208
+ const resolved = path54.resolve(raw.path);
11306
12209
  if (processedPaths.has(resolved)) continue;
11307
12210
  processedPaths.add(resolved);
11308
12211
  const candidate = { ...raw, path: resolved };
11309
- const runId = candidate.runId ?? path53.basename(resolved);
12212
+ const runId = candidate.runId ?? path54.basename(resolved);
11310
12213
  const dirSkip = skipRunDirectoryRemoval({
11311
12214
  harnessRoot,
11312
12215
  runId,
@@ -11441,12 +12344,13 @@ function isPipelineCleanupEnabled() {
11441
12344
 
11442
12345
  // src/installed-package-versions.ts
11443
12346
  import { readFile } from "node:fs/promises";
11444
- import { homedir as homedir13 } from "node:os";
11445
- import path55 from "node:path";
12347
+ import { homedir as homedir14 } from "node:os";
12348
+ import path56 from "node:path";
11446
12349
 
11447
12350
  // src/memory-cost-package-version-guard.ts
11448
- import { existsSync as existsSync40, readFileSync as readFileSync13 } from "node:fs";
11449
- import path54 from "node:path";
12351
+ init_default_repo_discovery();
12352
+ import { existsSync as existsSync40, readFileSync as readFileSync14 } from "node:fs";
12353
+ import path55 from "node:path";
11450
12354
  var MEMORY_COST_PACKAGE_MIN_VERSIONS = {
11451
12355
  "@kynver-app/runtime": "0.1.83",
11452
12356
  "@kynver-app/openclaw-agent-os": "0.1.43",
@@ -11497,7 +12401,7 @@ function maxSemver(versions) {
11497
12401
  }
11498
12402
  function readPackageJsonVersion(packageJsonPath) {
11499
12403
  try {
11500
- const parsed = JSON.parse(readFileSync13(packageJsonPath, "utf8"));
12404
+ const parsed = JSON.parse(readFileSync14(packageJsonPath, "utf8"));
11501
12405
  return typeof parsed.version === "string" && parsed.version.trim() ? parsed.version.trim() : null;
11502
12406
  } catch {
11503
12407
  return null;
@@ -11508,8 +12412,8 @@ function resolveRepoRoot(cwd, explicitRepoRoot) {
11508
12412
  (value) => Boolean(value?.trim())
11509
12413
  );
11510
12414
  for (const candidate of candidates) {
11511
- const resolved = path54.resolve(candidate);
11512
- if (existsSync40(path54.join(resolved, "packages/kynver-runtime/package.json")) && existsSync40(path54.join(resolved, "package.json"))) {
12415
+ const resolved = path55.resolve(candidate);
12416
+ if (existsSync40(path55.join(resolved, "packages/kynver-runtime/package.json")) && existsSync40(path55.join(resolved, "package.json"))) {
11513
12417
  return resolved;
11514
12418
  }
11515
12419
  }
@@ -11522,7 +12426,7 @@ function probeRepoPackageVersions(input = {}) {
11522
12426
  if (!repoRoot) return {};
11523
12427
  const out = {};
11524
12428
  for (const packageName of MEMORY_COST_MANAGED_PACKAGES) {
11525
- const packageJsonPath = path54.join(repoRoot, REPO_PACKAGE_JSON_RELATIVE[packageName]);
12429
+ const packageJsonPath = path55.join(repoRoot, REPO_PACKAGE_JSON_RELATIVE[packageName]);
11526
12430
  const version = readPackageJsonVersion(packageJsonPath);
11527
12431
  if (!version) continue;
11528
12432
  out[packageName] = { version, source: "repo", path: packageJsonPath };
@@ -11641,13 +12545,13 @@ function unique(values) {
11641
12545
  return [...new Set(values.filter((value) => Boolean(value)))];
11642
12546
  }
11643
12547
  function moduleRoots() {
11644
- const home = homedir13();
11645
- const openClawPrefix = trim(process.env.KYNVER_OPENCLAW_NPM_ROOT) ?? trim(process.env.OPENCLAW_NPM_ROOT) ?? path55.join(home, ".openclaw", "npm");
11646
- const npmGlobalRoot = trim(process.env.KYNVER_NPM_GLOBAL_ROOT) ?? trim(process.env.KYNVER_NPM_GLOBAL_MODULES_ROOT) ?? (trim(process.env.NPM_CONFIG_PREFIX) ? path55.join(trim(process.env.NPM_CONFIG_PREFIX), "lib", "node_modules") : path55.join(home, ".npm-global", "lib", "node_modules"));
12548
+ const home = homedir14();
12549
+ const openClawPrefix = trim(process.env.KYNVER_OPENCLAW_NPM_ROOT) ?? trim(process.env.OPENCLAW_NPM_ROOT) ?? path56.join(home, ".openclaw", "npm");
12550
+ const npmGlobalRoot = trim(process.env.KYNVER_NPM_GLOBAL_ROOT) ?? trim(process.env.KYNVER_NPM_GLOBAL_MODULES_ROOT) ?? (trim(process.env.NPM_CONFIG_PREFIX) ? path56.join(trim(process.env.NPM_CONFIG_PREFIX), "lib", "node_modules") : path56.join(home, ".npm-global", "lib", "node_modules"));
11647
12551
  return unique([
11648
- path55.join(openClawPrefix, "lib", "node_modules"),
11649
- path55.join(openClawPrefix, "node_modules"),
11650
- npmGlobalRoot.endsWith("node_modules") ? npmGlobalRoot : path55.join(npmGlobalRoot, "lib", "node_modules")
12552
+ path56.join(openClawPrefix, "lib", "node_modules"),
12553
+ path56.join(openClawPrefix, "node_modules"),
12554
+ npmGlobalRoot.endsWith("node_modules") ? npmGlobalRoot : path56.join(npmGlobalRoot, "lib", "node_modules")
11651
12555
  ]);
11652
12556
  }
11653
12557
  async function readVersion(packageJsonPath) {
@@ -11663,7 +12567,7 @@ function installedPackageJsonCandidates(packageName) {
11663
12567
  const seen = /* @__PURE__ */ new Set();
11664
12568
  const out = [];
11665
12569
  for (const root of roots) {
11666
- const candidate = path55.join(root, packageName, "package.json");
12570
+ const candidate = path56.join(root, packageName, "package.json");
11667
12571
  if (seen.has(candidate)) continue;
11668
12572
  seen.add(candidate);
11669
12573
  out.push(candidate);
@@ -11688,13 +12592,355 @@ async function collectInstalledPackageVersions(observedAt = (/* @__PURE__ */ new
11688
12592
  return out;
11689
12593
  }
11690
12594
 
12595
+ // src/provider-evidence/exec.ts
12596
+ import { spawnSync as spawnSync7 } from "node:child_process";
12597
+ var DEFAULT_CLI_TIMEOUT_MS = 1e4;
12598
+ var MAX_CLI_BUFFER_BYTES = 4 * 1024 * 1024;
12599
+ var defaultCliRunner = (cmd, args, opts) => {
12600
+ try {
12601
+ const result = spawnSync7(cmd, args, {
12602
+ encoding: "utf8",
12603
+ stdio: ["ignore", "pipe", "pipe"],
12604
+ timeout: opts?.timeoutMs ?? DEFAULT_CLI_TIMEOUT_MS,
12605
+ maxBuffer: MAX_CLI_BUFFER_BYTES
12606
+ });
12607
+ return {
12608
+ ok: result.status === 0,
12609
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
12610
+ stderr: typeof result.stderr === "string" ? result.stderr : ""
12611
+ };
12612
+ } catch (err) {
12613
+ return { ok: false, stdout: "", stderr: err instanceof Error ? err.message : String(err) };
12614
+ }
12615
+ };
12616
+ function runCliJson(run, cmd, args) {
12617
+ const result = run(cmd, args);
12618
+ if (!result.ok || !result.stdout.trim()) return null;
12619
+ try {
12620
+ return JSON.parse(result.stdout);
12621
+ } catch {
12622
+ return null;
12623
+ }
12624
+ }
12625
+
12626
+ // src/provider-evidence/types.ts
12627
+ function providerEvidenceKey(provider, kind, subject) {
12628
+ return `${provider} ${kind} ${subject}`;
12629
+ }
12630
+ function parseCommitEvidenceSubject(subject) {
12631
+ const at = subject.lastIndexOf("@");
12632
+ if (at <= 0 || at === subject.length - 1) return null;
12633
+ const repo = subject.slice(0, at);
12634
+ const sha = subject.slice(at + 1);
12635
+ if (!/^[^/\s]+\/[^/\s]+$/.test(repo) || !/^[0-9a-f]{7,40}$/i.test(sha)) return null;
12636
+ return { repo, sha };
12637
+ }
12638
+ function parsePrUrlSubject(subject) {
12639
+ const m = subject.trim().match(/[/:]([^/]+\/[^/]+)\/(?:pull|pulls|merge_requests|pull-requests)\/(\d+)/i);
12640
+ if (!m) return null;
12641
+ const number = Number(m[2]);
12642
+ if (!Number.isFinite(number) || number <= 0) return null;
12643
+ return { repo: m[1], number };
12644
+ }
12645
+
12646
+ // src/provider-evidence/recipes-github.ts
12647
+ var MAX_BODY_CHARS = 8e3;
12648
+ var MAX_STATUS_ROWS = 30;
12649
+ var MAX_CHECK_RUNS = 100;
12650
+ var MAX_CHANGED_FILES = 400;
12651
+ function githubCliAvailable(run) {
12652
+ if (process.env.GITHUB_TOKEN?.trim() || process.env.GH_TOKEN?.trim()) return true;
12653
+ return run("gh", ["auth", "token"]).ok;
12654
+ }
12655
+ function asRecord4(value) {
12656
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
12657
+ }
12658
+ function pickStatusRows(value) {
12659
+ if (!Array.isArray(value)) return [];
12660
+ return value.map((raw) => asRecord4(raw)).filter((row) => row !== null).slice(0, MAX_STATUS_ROWS).map((row) => ({
12661
+ context: row.context ?? null,
12662
+ state: row.state ?? null,
12663
+ target_url: row.target_url ?? null,
12664
+ description: row.description ?? null
12665
+ }));
12666
+ }
12667
+ function fetchCombinedStatus(run, repo, sha) {
12668
+ const status = runCliJson(run, "gh", [
12669
+ "api",
12670
+ `repos/${repo}/commits/${sha}/status`
12671
+ ]);
12672
+ if (!status) return null;
12673
+ return { state: status.state ?? null, statuses: pickStatusRows(status.statuses) };
12674
+ }
12675
+ var githubPrSnapshotRecipe = {
12676
+ provider: "github",
12677
+ kind: "pr_snapshot",
12678
+ version: "1",
12679
+ isAvailable: githubCliAvailable,
12680
+ collect(subject, run) {
12681
+ const parsed = parsePrUrlSubject(subject);
12682
+ if (!parsed) return null;
12683
+ const pull = runCliJson(run, "gh", [
12684
+ "api",
12685
+ `repos/${parsed.repo}/pulls/${parsed.number}`
12686
+ ]);
12687
+ if (!pull) return null;
12688
+ const head = asRecord4(pull.head);
12689
+ const headSha = typeof head?.sha === "string" ? head.sha : null;
12690
+ const user = asRecord4(pull.user);
12691
+ const headRepoOwner = asRecord4(asRecord4(head?.repo)?.owner);
12692
+ const body = typeof pull.body === "string" ? pull.body.slice(0, MAX_BODY_CHARS) : null;
12693
+ let checkRuns = [];
12694
+ let combinedStatus = {
12695
+ state: null,
12696
+ statuses: []
12697
+ };
12698
+ if (headSha) {
12699
+ const runs = runCliJson(run, "gh", [
12700
+ "api",
12701
+ `repos/${parsed.repo}/commits/${headSha}/check-runs?per_page=100`
12702
+ ]);
12703
+ if (Array.isArray(runs?.check_runs)) {
12704
+ checkRuns = runs.check_runs.map((raw) => asRecord4(raw)).filter((row) => row !== null).slice(0, MAX_CHECK_RUNS).map((row) => ({
12705
+ name: row.name ?? null,
12706
+ status: row.status ?? null,
12707
+ conclusion: row.conclusion ?? null
12708
+ }));
12709
+ }
12710
+ combinedStatus = fetchCombinedStatus(run, parsed.repo, headSha) ?? combinedStatus;
12711
+ }
12712
+ const filesResult = run("gh", [
12713
+ "api",
12714
+ "--paginate",
12715
+ `repos/${parsed.repo}/pulls/${parsed.number}/files?per_page=100`,
12716
+ "--jq",
12717
+ ".[].filename"
12718
+ ]);
12719
+ const changedFiles = filesResult.ok ? filesResult.stdout.split("\n").map((line) => line.trim()).filter(Boolean).slice(0, MAX_CHANGED_FILES) : [];
12720
+ return {
12721
+ pull: {
12722
+ html_url: pull.html_url ?? null,
12723
+ title: pull.title ?? null,
12724
+ body,
12725
+ user: { login: user?.login ?? null },
12726
+ state: pull.state ?? null,
12727
+ draft: pull.draft ?? null,
12728
+ merged: pull.merged ?? null,
12729
+ merged_at: pull.merged_at ?? null,
12730
+ merge_commit_sha: pull.merge_commit_sha ?? null,
12731
+ mergeable: pull.mergeable ?? null,
12732
+ mergeable_state: pull.mergeable_state ?? null,
12733
+ head: {
12734
+ sha: headSha,
12735
+ ref: head?.ref ?? null,
12736
+ repo: { owner: { login: headRepoOwner?.login ?? null } }
12737
+ }
12738
+ },
12739
+ checkRuns,
12740
+ combinedStatus,
12741
+ changedFiles
12742
+ };
12743
+ }
12744
+ };
12745
+ var githubCommitStatusRecipe = {
12746
+ provider: "github",
12747
+ kind: "commit_status",
12748
+ version: "1",
12749
+ isAvailable: githubCliAvailable,
12750
+ collect(subject, run) {
12751
+ const parsed = parseCommitEvidenceSubject(subject);
12752
+ if (!parsed) return null;
12753
+ return fetchCombinedStatus(run, parsed.repo, parsed.sha);
12754
+ }
12755
+ };
12756
+ var githubBranchReachabilityRecipe = {
12757
+ provider: "github",
12758
+ kind: "branch_reachability",
12759
+ version: "1",
12760
+ isAvailable: githubCliAvailable,
12761
+ collect(subject, run) {
12762
+ const parsed = parseCommitEvidenceSubject(subject);
12763
+ if (!parsed) return null;
12764
+ const repoMeta = runCliJson(run, "gh", [
12765
+ "api",
12766
+ `repos/${parsed.repo}`
12767
+ ]);
12768
+ const defaultBranch = typeof repoMeta?.default_branch === "string" && repoMeta.default_branch.trim() ? repoMeta.default_branch.trim() : null;
12769
+ if (!defaultBranch) return null;
12770
+ const compare = runCliJson(run, "gh", [
12771
+ "api",
12772
+ `repos/${parsed.repo}/compare/${encodeURIComponent(defaultBranch)}...${parsed.sha}`
12773
+ ]);
12774
+ if (!compare) return null;
12775
+ const compareStatus = typeof compare.status === "string" ? compare.status : null;
12776
+ return {
12777
+ defaultBranch,
12778
+ compareStatus,
12779
+ reachable: compareStatus === "identical" || compareStatus === "behind"
12780
+ };
12781
+ }
12782
+ };
12783
+
12784
+ // src/provider-evidence/recipes-vercel.ts
12785
+ var MAX_DEPLOYMENT_ROWS = 5;
12786
+ var STATE_PATTERN = /\b(READY|ERROR|BUILDING|QUEUED|CANCELED|INITIALIZING)\b/i;
12787
+ var URL_PATTERN = /https:\/\/[^\s]+/;
12788
+ var vercelDeploymentStatusRecipe = {
12789
+ provider: "vercel",
12790
+ kind: "deployment_status",
12791
+ version: "1",
12792
+ isAvailable(run) {
12793
+ return run("vercel", ["whoami"]).ok;
12794
+ },
12795
+ collect(subject, run) {
12796
+ const parsed = parseCommitEvidenceSubject(subject);
12797
+ if (!parsed) return null;
12798
+ const result = run("vercel", [
12799
+ "list",
12800
+ "--prod",
12801
+ "--meta",
12802
+ `githubCommitSha=${parsed.sha}`
12803
+ ]);
12804
+ if (!result.ok) return null;
12805
+ const deployments = [];
12806
+ for (const line of result.stdout.split("\n")) {
12807
+ const url = line.match(URL_PATTERN)?.[0];
12808
+ if (!url) continue;
12809
+ const state = line.match(STATE_PATTERN)?.[1]?.toUpperCase() ?? null;
12810
+ deployments.push({ url, state });
12811
+ if (deployments.length >= MAX_DEPLOYMENT_ROWS) break;
12812
+ }
12813
+ return { found: deployments.length > 0, deployments };
12814
+ }
12815
+ };
12816
+
12817
+ // src/provider-evidence/registry.ts
12818
+ var _recipes = [];
12819
+ function registerEvidenceCollector(recipe) {
12820
+ if (_recipes.some((r) => r.provider === recipe.provider && r.kind === recipe.kind)) return;
12821
+ _recipes.push(recipe);
12822
+ }
12823
+ function getEvidenceCollector(provider, kind) {
12824
+ return _recipes.find((r) => r.provider === provider && r.kind === kind) ?? null;
12825
+ }
12826
+ function registerDefaultEvidenceCollectors() {
12827
+ registerEvidenceCollector(githubPrSnapshotRecipe);
12828
+ registerEvidenceCollector(githubCommitStatusRecipe);
12829
+ registerEvidenceCollector(githubBranchReachabilityRecipe);
12830
+ registerEvidenceCollector(vercelDeploymentStatusRecipe);
12831
+ }
12832
+
12833
+ // src/provider-evidence/collect.ts
12834
+ var DEFAULT_MAX_SUBJECTS_PER_TICK = 8;
12835
+ var DEFAULT_DEADLINE_MS = 25e3;
12836
+ function collectProviderEvidence(wanted, opts = {}) {
12837
+ registerDefaultEvidenceCollectors();
12838
+ const run = opts.run ?? defaultCliRunner;
12839
+ const now = opts.now ?? (() => /* @__PURE__ */ new Date());
12840
+ const maxSubjects = opts.maxSubjects ?? DEFAULT_MAX_SUBJECTS_PER_TICK;
12841
+ const deadline = Date.now() + (opts.deadlineMs ?? DEFAULT_DEADLINE_MS);
12842
+ const seen = /* @__PURE__ */ new Set();
12843
+ const deduped = wanted.filter((w) => {
12844
+ const key = providerEvidenceKey(w.provider, w.kind, w.subject);
12845
+ if (seen.has(key)) return false;
12846
+ seen.add(key);
12847
+ return true;
12848
+ });
12849
+ const offset = deduped.length > 0 ? Math.floor(now().getTime() / 6e4) % deduped.length : 0;
12850
+ const rotated = deduped.map((_, i) => deduped[(offset + i) % deduped.length]);
12851
+ const window = rotated.slice(0, maxSubjects);
12852
+ const summary = {
12853
+ attempted: 0,
12854
+ collected: 0,
12855
+ items: [],
12856
+ skipped: []
12857
+ };
12858
+ const availability = /* @__PURE__ */ new Map();
12859
+ for (const item of window) {
12860
+ if (Date.now() > deadline) {
12861
+ summary.skipped.push({ ...item, reason: "budget_exhausted" });
12862
+ continue;
12863
+ }
12864
+ const recipe = getEvidenceCollector(item.provider, item.kind);
12865
+ if (!recipe) {
12866
+ summary.skipped.push({ ...item, reason: "no_recipe" });
12867
+ continue;
12868
+ }
12869
+ const availKey = `${recipe.provider} ${recipe.kind}`;
12870
+ let available = availability.get(availKey);
12871
+ if (available === void 0) {
12872
+ available = recipe.isAvailable(run);
12873
+ availability.set(availKey, available);
12874
+ }
12875
+ if (!available) {
12876
+ summary.skipped.push({ ...item, reason: "provider_unavailable" });
12877
+ continue;
12878
+ }
12879
+ summary.attempted += 1;
12880
+ const payload = recipe.collect(item.subject, run);
12881
+ if (payload === null || payload === void 0) {
12882
+ summary.skipped.push({ ...item, reason: "collect_failed" });
12883
+ continue;
12884
+ }
12885
+ summary.collected += 1;
12886
+ summary.items.push({
12887
+ provider: item.provider,
12888
+ kind: item.kind,
12889
+ subject: item.subject,
12890
+ payload,
12891
+ observedAt: now().toISOString(),
12892
+ collectorVersion: recipe.version
12893
+ });
12894
+ }
12895
+ return summary;
12896
+ }
12897
+
12898
+ // src/provider-evidence/wanted-store.ts
12899
+ init_run_store();
12900
+ init_util();
12901
+ import path57 from "node:path";
12902
+ var WANTED_FILE = "provider-evidence-wanted.json";
12903
+ function wantedFilePath(runId) {
12904
+ return path57.join(runDirectory(runId), WANTED_FILE);
12905
+ }
12906
+ function parseWantedItems(value) {
12907
+ if (!Array.isArray(value)) return [];
12908
+ const out = [];
12909
+ for (const raw of value) {
12910
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
12911
+ const row = raw;
12912
+ const provider = typeof row.provider === "string" ? row.provider.trim() : "";
12913
+ const kind = typeof row.kind === "string" ? row.kind.trim() : "";
12914
+ const subject = typeof row.subject === "string" ? row.subject.trim() : "";
12915
+ if (!provider || !kind || !subject) continue;
12916
+ out.push({ provider, kind, subject });
12917
+ }
12918
+ return out;
12919
+ }
12920
+ function loadPersistedProviderEvidenceWanted(runId) {
12921
+ const persisted = readJson(wantedFilePath(runId), null);
12922
+ return parseWantedItems(persisted?.wanted);
12923
+ }
12924
+ function persistProviderEvidenceWanted(runId, wanted) {
12925
+ writeJson(wantedFilePath(runId), {
12926
+ savedAt: (/* @__PURE__ */ new Date()).toISOString(),
12927
+ wanted
12928
+ });
12929
+ }
12930
+ function extractProviderEvidenceWanted(tickResponse) {
12931
+ if (!tickResponse || typeof tickResponse !== "object" || Array.isArray(tickResponse)) return null;
12932
+ const wanted = tickResponse.providerEvidenceWanted;
12933
+ if (!Array.isArray(wanted)) return null;
12934
+ return parseWantedItems(wanted);
12935
+ }
12936
+
11691
12937
  // src/pipeline-tick.ts
11692
12938
  async function completeFinishedWorkers(runId, args) {
11693
12939
  const run = loadRun(runId);
11694
12940
  const outcomes = [];
11695
12941
  for (const name of Object.keys(run.workers || {})) {
11696
12942
  const worker = readJson(
11697
- path56.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
12943
+ path58.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
11698
12944
  void 0
11699
12945
  );
11700
12946
  if (!worker?.taskId || worker.localOnly) continue;
@@ -11727,6 +12973,13 @@ async function postOperatorTick(agentOsId, runId, resourceGate, args, harnessCle
11727
12973
  const url = `${base}/api/agent-os/by-id/${encodeURIComponent(agentOsId)}/operator/tick`;
11728
12974
  const packageVersions = await collectInstalledPackageVersions();
11729
12975
  const activeHarnessWorkers = collectRunActiveHarnessWorkers(runId);
12976
+ let evidenceCollection = null;
12977
+ try {
12978
+ const evidenceWanted = loadPersistedProviderEvidenceWanted(runId);
12979
+ evidenceCollection = evidenceWanted.length > 0 ? collectProviderEvidence(evidenceWanted) : null;
12980
+ } catch {
12981
+ evidenceCollection = null;
12982
+ }
11730
12983
  const res = await postJson(url, secret, {
11731
12984
  agentOsId,
11732
12985
  runId,
@@ -11741,9 +12994,27 @@ async function postOperatorTick(agentOsId, runId, resourceGate, args, harnessCle
11741
12994
  ...harnessCleanup ? { harnessCleanup } : {},
11742
12995
  runnerPresence: resolveRunnerPresencePayload({ runId }),
11743
12996
  activeHarnessWorkers,
11744
- ...harnessCleanup ? { harnessCleanup } : {}
12997
+ ...evidenceCollection && evidenceCollection.items.length > 0 ? { providerEvidence: evidenceCollection.items } : {}
11745
12998
  });
11746
- return { ok: res.ok, httpStatus: res.status, response: res.response };
12999
+ const nextWanted = extractProviderEvidenceWanted(res.response);
13000
+ if (nextWanted) {
13001
+ try {
13002
+ persistProviderEvidenceWanted(runId, nextWanted);
13003
+ } catch {
13004
+ }
13005
+ }
13006
+ return {
13007
+ ok: res.ok,
13008
+ httpStatus: res.status,
13009
+ response: res.response,
13010
+ ...evidenceCollection ? {
13011
+ providerEvidence: {
13012
+ attempted: evidenceCollection.attempted,
13013
+ collected: evidenceCollection.collected,
13014
+ skipped: evidenceCollection.skipped.length
13015
+ }
13016
+ } : {}
13017
+ };
11747
13018
  }
11748
13019
  async function runPipelineTick(args) {
11749
13020
  const runId = String(required(String(args.run || ""), "--run"));
@@ -11851,6 +13122,7 @@ async function awaitDaemonBackoff(ms, isStopping) {
11851
13122
  }
11852
13123
  }
11853
13124
  async function runDaemon(args) {
13125
+ assertNativeDaemonAllowed();
11854
13126
  const runId = String(required(String(args.run || ""), "--run"));
11855
13127
  const agentOsId = String(required(String(args.agentOsId || loadUserConfig().agentOsId || ""), "--agent-os-id"));
11856
13128
  const execute = args.execute !== false && args.execute !== "false";
@@ -11890,6 +13162,7 @@ async function runDaemon(args) {
11890
13162
  const cronEnv = resolveKynverCronEnv();
11891
13163
  while (!stopping) {
11892
13164
  try {
13165
+ writeDaemonHeartbeat({ agentOsId, runId });
11893
13166
  if (cronEnv.tickEnabled) {
11894
13167
  const cronTick = await runKynverCronTick({
11895
13168
  env: cronEnv,
@@ -11916,8 +13189,140 @@ async function runDaemon(args) {
11916
13189
  console.error(JSON.stringify({ event: "daemon_stop", runId, agentOsId }));
11917
13190
  }
11918
13191
 
13192
+ // src/daemon-keeper.ts
13193
+ init_config();
13194
+ import { spawn as spawn6 } from "node:child_process";
13195
+ init_util();
13196
+ var DEFAULT_STALL_MS = 15 * 6e4;
13197
+ var STARTUP_GRACE_MS = 2 * 6e4;
13198
+ var KILL_GRACE_MS = 1e4;
13199
+ var BACKOFF_BASE_MS = 5e3;
13200
+ var BACKOFF_CAP_MS = 5 * 6e4;
13201
+ var HEALTHY_RESET_MS = 30 * 6e4;
13202
+ var POLL_MS = 5e3;
13203
+ function resolveKeeperStallMs(flag, env = process.env) {
13204
+ const fromFlag = typeof flag === "string" ? Number.parseInt(flag, 10) : NaN;
13205
+ if (Number.isFinite(fromFlag) && fromFlag > 0) return fromFlag;
13206
+ const fromEnv = Number.parseInt(env.KYNVER_DAEMON_STALL_MS ?? "", 10);
13207
+ if (Number.isFinite(fromEnv) && fromEnv > 0) return fromEnv;
13208
+ return DEFAULT_STALL_MS;
13209
+ }
13210
+ function shouldRunDaemonKeeper(args, env = process.env) {
13211
+ if (args.keeperChild === true || args.keeperChild === "true") return false;
13212
+ if (args.noSupervise === true || args.noSupervise === "true") return false;
13213
+ if (args.supervised === "false") return false;
13214
+ const envFlag5 = (env.KYNVER_DAEMON_SUPERVISED ?? "").trim().toLowerCase();
13215
+ if (envFlag5 === "0" || envFlag5 === "false" || envFlag5 === "no" || envFlag5 === "off") {
13216
+ return false;
13217
+ }
13218
+ return true;
13219
+ }
13220
+ function nextKeeperBackoffMs(consecutiveFailures, base = BACKOFF_BASE_MS, cap = BACKOFF_CAP_MS) {
13221
+ const exp = Math.min(Math.max(consecutiveFailures, 1) - 1, 10);
13222
+ return Math.min(base * 2 ** exp, cap);
13223
+ }
13224
+ function keeperRunWasHealthy(startedAtMs, endedAtMs, healthyMs = HEALTHY_RESET_MS) {
13225
+ return endedAtMs - startedAtMs >= healthyMs;
13226
+ }
13227
+ function keeperLog(event, detail = {}) {
13228
+ console.error(JSON.stringify({ event: `daemon_keeper_${event}`, ...detail }));
13229
+ }
13230
+ function buildKeeperChildArgv(argv) {
13231
+ const out = [];
13232
+ for (let i = 0; i < argv.length; i += 1) {
13233
+ const arg = argv[i];
13234
+ if (arg === "--supervised" || arg === "--no-supervise" || arg === "--keeper-child") continue;
13235
+ if (arg === "--stall-ms") {
13236
+ if (i + 1 < argv.length && !argv[i + 1].startsWith("--")) i += 1;
13237
+ continue;
13238
+ }
13239
+ if (arg.startsWith("--stall-ms=") || arg.startsWith("--supervised=")) continue;
13240
+ out.push(arg);
13241
+ }
13242
+ out.push("--keeper-child");
13243
+ return out;
13244
+ }
13245
+ async function runDaemonKeeper(args, rawArgv = process.argv.slice(2)) {
13246
+ const agentOsId = String(
13247
+ required(String(args.agentOsId || loadUserConfig().agentOsId || ""), "--agent-os-id")
13248
+ );
13249
+ const stallMs = resolveKeeperStallMs(args.stallMs);
13250
+ const childArgv = buildKeeperChildArgv(rawArgv);
13251
+ const cliEntry = process.argv[1];
13252
+ let stopping = false;
13253
+ let child = null;
13254
+ let consecutiveFailures = 0;
13255
+ const stop = (signal) => {
13256
+ stopping = true;
13257
+ keeperLog("stop", { signal });
13258
+ if (child?.pid) child.kill(signal);
13259
+ };
13260
+ process.on("SIGINT", () => stop("SIGINT"));
13261
+ process.on("SIGTERM", () => stop("SIGTERM"));
13262
+ keeperLog("start", { agentOsId, stallMs, childArgv });
13263
+ while (!stopping) {
13264
+ const startedAt = Date.now();
13265
+ let exited = false;
13266
+ let exitCode = null;
13267
+ let exitSignal = null;
13268
+ child = spawn6(process.execPath, [cliEntry, ...childArgv], {
13269
+ stdio: "inherit",
13270
+ env: process.env
13271
+ });
13272
+ keeperLog("child_spawned", { pid: child.pid ?? null });
13273
+ child.on("exit", (code, signal) => {
13274
+ exited = true;
13275
+ exitCode = code;
13276
+ exitSignal = signal;
13277
+ });
13278
+ while (!exited && !stopping) {
13279
+ await sleepMsAsync(POLL_MS);
13280
+ if (exited || stopping) break;
13281
+ if (Date.now() - startedAt < STARTUP_GRACE_MS) continue;
13282
+ const beat = readDaemonHeartbeat(agentOsId);
13283
+ const ownBeat = beat && beat.pid === child.pid ? beat : null;
13284
+ if (ownBeat && isDaemonHeartbeatStale(ownBeat, stallMs)) {
13285
+ keeperLog("stall_detected", {
13286
+ pid: child.pid ?? null,
13287
+ lastBeatAt: ownBeat.observedAt,
13288
+ stallMs
13289
+ });
13290
+ child.kill("SIGTERM");
13291
+ await sleepMsAsync(KILL_GRACE_MS);
13292
+ if (!exited) child.kill("SIGKILL");
13293
+ break;
13294
+ }
13295
+ if (!ownBeat && Date.now() - startedAt > stallMs + STARTUP_GRACE_MS) {
13296
+ keeperLog("no_heartbeat_detected", { pid: child.pid ?? null, stallMs });
13297
+ child.kill("SIGTERM");
13298
+ await sleepMsAsync(KILL_GRACE_MS);
13299
+ if (!exited) child.kill("SIGKILL");
13300
+ break;
13301
+ }
13302
+ }
13303
+ while (!exited && !stopping) {
13304
+ await sleepMsAsync(POLL_MS);
13305
+ }
13306
+ if (stopping) break;
13307
+ const endedAt = Date.now();
13308
+ if (keeperRunWasHealthy(startedAt, endedAt)) consecutiveFailures = 0;
13309
+ consecutiveFailures += 1;
13310
+ const backoff = nextKeeperBackoffMs(consecutiveFailures);
13311
+ keeperLog("child_exited", {
13312
+ code: exitCode,
13313
+ signal: exitSignal,
13314
+ uptimeMs: endedAt - startedAt,
13315
+ consecutiveFailures,
13316
+ respawnInMs: backoff
13317
+ });
13318
+ await sleepMsAsync(backoff);
13319
+ }
13320
+ keeperLog("stopped", { agentOsId });
13321
+ }
13322
+
11919
13323
  // src/plan-progress.ts
11920
- import path60 from "node:path";
13324
+ init_config();
13325
+ import path62 from "node:path";
11921
13326
 
11922
13327
  // src/bounded-build/constants.ts
11923
13328
  var DEFAULT_BUILD_MEM_BUDGET_BYTES = 1536 * 1024 * 1024;
@@ -11926,6 +13331,9 @@ var DEFAULT_NODE_OLD_SPACE_SIZE_MB = 1024;
11926
13331
  var DEFAULT_SYSTEMD_MEMORY_MAX = "1.5G";
11927
13332
  var DEFAULT_SYSTEMD_MEMORY_SWAP_MAX = "2G";
11928
13333
 
13334
+ // src/bounded-build/index.ts
13335
+ init_meminfo();
13336
+
11929
13337
  // src/bounded-build/node-options.ts
11930
13338
  var MAX_OLD_SPACE_RE = /--max-old-space-size=(\d+)/;
11931
13339
  function parsePositiveInt(value, fallback) {
@@ -11955,7 +13363,7 @@ function formatNodeOptionsFlag(mb = resolveNodeOldSpaceSizeMb()) {
11955
13363
  }
11956
13364
 
11957
13365
  // src/bounded-build/systemd-wrap.ts
11958
- import { spawnSync as spawnSync7 } from "node:child_process";
13366
+ import { spawnSync as spawnSync8 } from "node:child_process";
11959
13367
  var systemdAvailableCache;
11960
13368
  function isSystemdRunAvailable() {
11961
13369
  if (process.env.KYNVER_BUILD_SKIP_SYSTEMD === "1" || process.env.KYNVER_BUILD_SKIP_SYSTEMD === "true") {
@@ -11966,7 +13374,7 @@ function isSystemdRunAvailable() {
11966
13374
  systemdAvailableCache = false;
11967
13375
  return false;
11968
13376
  }
11969
- const res = spawnSync7("systemd-run", ["--version"], { encoding: "utf8", stdio: ["ignore", "ignore", "pipe"] });
13377
+ const res = spawnSync8("systemd-run", ["--version"], { encoding: "utf8", stdio: ["ignore", "ignore", "pipe"] });
11970
13378
  systemdAvailableCache = res.status === 0;
11971
13379
  return systemdAvailableCache;
11972
13380
  }
@@ -11990,7 +13398,9 @@ function buildSystemdRunArgv(opts) {
11990
13398
  }
11991
13399
 
11992
13400
  // src/bounded-build/admission.ts
11993
- import { spawnSync as spawnSync8 } from "node:child_process";
13401
+ init_config();
13402
+ import { spawnSync as spawnSync9 } from "node:child_process";
13403
+ init_meminfo();
11994
13404
  function positiveInt4(value, fallback) {
11995
13405
  const n = Number(value);
11996
13406
  if (!Number.isFinite(n) || n <= 0) return fallback;
@@ -12026,7 +13436,7 @@ function assessBuildAdmission(opts = {}) {
12026
13436
  }
12027
13437
  function sleepMs2(ms) {
12028
13438
  if (ms <= 0) return;
12029
- spawnSync8(process.execPath, ["-e", `const d=Date.now()+${Math.floor(ms)};while(Date.now()<d);`], {
13439
+ spawnSync9(process.execPath, ["-e", `const d=Date.now()+${Math.floor(ms)};while(Date.now()<d);`], {
12030
13440
  stdio: "ignore"
12031
13441
  });
12032
13442
  }
@@ -12047,33 +13457,34 @@ function waitForBuildAdmission(timeoutMs, pollMs = 2e3, opts = {}) {
12047
13457
  }
12048
13458
 
12049
13459
  // src/bounded-build/exec.ts
12050
- import { spawnSync as spawnSync10 } from "node:child_process";
13460
+ import { spawnSync as spawnSync11 } from "node:child_process";
12051
13461
 
12052
13462
  // src/heavy-verification/slot.ts
13463
+ init_util();
12053
13464
  import {
12054
13465
  closeSync as closeSync7,
12055
13466
  existsSync as existsSync41,
12056
- mkdirSync as mkdirSync8,
13467
+ mkdirSync as mkdirSync9,
12057
13468
  openSync as openSync7,
12058
13469
  readdirSync as readdirSync15,
12059
- readFileSync as readFileSync14,
13470
+ readFileSync as readFileSync15,
12060
13471
  unlinkSync as unlinkSync4,
12061
- writeFileSync as writeFileSync5
13472
+ writeFileSync as writeFileSync6
12062
13473
  } from "node:fs";
12063
- import path58 from "node:path";
13474
+ import path60 from "node:path";
12064
13475
 
12065
13476
  // src/heavy-verification/paths.ts
12066
- import { mkdirSync as mkdirSync7 } from "node:fs";
12067
- import path57 from "node:path";
13477
+ import { mkdirSync as mkdirSync8 } from "node:fs";
13478
+ import path59 from "node:path";
12068
13479
  function resolveHeavyVerificationRoot() {
12069
- return path57.join(resolveKynverStateRoot(), "heavy-verification");
13480
+ return path59.join(resolveKynverStateRoot(), "heavy-verification");
12070
13481
  }
12071
13482
  function heavyVerificationSlotsDir() {
12072
- return path57.join(resolveHeavyVerificationRoot(), "slots");
13483
+ return path59.join(resolveHeavyVerificationRoot(), "slots");
12073
13484
  }
12074
13485
  function ensureHeavyVerificationDirs() {
12075
13486
  const dir = heavyVerificationSlotsDir();
12076
- mkdirSync7(dir, { recursive: true });
13487
+ mkdirSync8(dir, { recursive: true });
12077
13488
  return dir;
12078
13489
  }
12079
13490
 
@@ -12098,12 +13509,12 @@ function indexedSlotId(index) {
12098
13509
  return `slot-${index}`;
12099
13510
  }
12100
13511
  function slotFilePath(slotId, slotsDir = heavyVerificationSlotsDir()) {
12101
- return path58.join(slotsDir, `${slotId}.json`);
13512
+ return path60.join(slotsDir, `${slotId}.json`);
12102
13513
  }
12103
13514
  function readSlotRecord(filePath) {
12104
13515
  if (!existsSync41(filePath)) return null;
12105
13516
  try {
12106
- const parsed = JSON.parse(readFileSync14(filePath, "utf8"));
13517
+ const parsed = JSON.parse(readFileSync15(filePath, "utf8"));
12107
13518
  if (typeof parsed.slotId === "string" && typeof parsed.pid === "number" && typeof parsed.acquiredAt === "string" && typeof parsed.command === "string") {
12108
13519
  return parsed;
12109
13520
  }
@@ -12128,7 +13539,7 @@ function reclaimStaleSlot(filePath, staleMs) {
12128
13539
  }
12129
13540
  }
12130
13541
  function ensureSlotsDir(slotsDir) {
12131
- mkdirSync8(slotsDir, { recursive: true });
13542
+ mkdirSync9(slotsDir, { recursive: true });
12132
13543
  return slotsDir;
12133
13544
  }
12134
13545
  function reclaimStaleHeavyVerificationSlots(opts = {}) {
@@ -12137,7 +13548,7 @@ function reclaimStaleHeavyVerificationSlots(opts = {}) {
12137
13548
  let reclaimed = 0;
12138
13549
  for (const name of readdirSync15(slotsDir)) {
12139
13550
  if (!name.endsWith(".json")) continue;
12140
- const filePath = path58.join(slotsDir, name);
13551
+ const filePath = path60.join(slotsDir, name);
12141
13552
  const before = existsSync41(filePath);
12142
13553
  reclaimStaleSlot(filePath, staleMs);
12143
13554
  if (before && !existsSync41(filePath)) reclaimed += 1;
@@ -12151,7 +13562,7 @@ function listActiveHeavyVerificationSlots(opts = {}) {
12151
13562
  const active = [];
12152
13563
  for (const name of readdirSync15(slotsDir)) {
12153
13564
  if (!name.endsWith(".json")) continue;
12154
- const record = readSlotRecord(path58.join(slotsDir, name));
13565
+ const record = readSlotRecord(path60.join(slotsDir, name));
12155
13566
  if (record && !slotIsStale(record, staleMs)) active.push(record);
12156
13567
  }
12157
13568
  return active;
@@ -12193,7 +13604,7 @@ function tryAcquireHeavyVerificationSlot(command, opts = {}) {
12193
13604
  };
12194
13605
  try {
12195
13606
  const fd = openSync7(filePath, "wx");
12196
- writeFileSync5(fd, JSON.stringify(record, null, 2), "utf8");
13607
+ writeFileSync6(fd, JSON.stringify(record, null, 2), "utf8");
12197
13608
  closeSync7(fd);
12198
13609
  const activeSlots2 = countActiveHeavyVerificationSlots({ slotsDir, staleMs });
12199
13610
  return {
@@ -12253,10 +13664,10 @@ function assessHeavyVerificationGate(command, opts = {}) {
12253
13664
  }
12254
13665
 
12255
13666
  // src/heavy-verification/gate.ts
12256
- import { spawnSync as spawnSync9 } from "node:child_process";
13667
+ import { spawnSync as spawnSync10 } from "node:child_process";
12257
13668
  function sleepMs3(ms) {
12258
13669
  if (ms <= 0) return;
12259
- spawnSync9(process.execPath, ["-e", `const d=Date.now()+${Math.floor(ms)};while(Date.now()<d);`], {
13670
+ spawnSync10(process.execPath, ["-e", `const d=Date.now()+${Math.floor(ms)};while(Date.now()<d);`], {
12260
13671
  stdio: "ignore"
12261
13672
  });
12262
13673
  }
@@ -12271,11 +13682,12 @@ function waitForHeavyVerificationSlot(command, timeoutMs, pollMs = 2e3, opts = {
12271
13682
  }
12272
13683
 
12273
13684
  // src/harness-worktree-build-guard.ts
12274
- import path59 from "node:path";
13685
+ init_paths();
13686
+ import path61 from "node:path";
12275
13687
  function isPathUnderHarnessWorktree(cwd) {
12276
13688
  const worktreesDir = harnessWorktreesDir(resolveHarnessRoot());
12277
- const rel = path59.relative(worktreesDir, path59.resolve(cwd));
12278
- return rel.length > 0 && !rel.startsWith("..") && !path59.isAbsolute(rel);
13689
+ const rel = path61.relative(worktreesDir, path61.resolve(cwd));
13690
+ return rel.length > 0 && !rel.startsWith("..") && !path61.isAbsolute(rel);
12279
13691
  }
12280
13692
  function assessHarnessWorktreeBuildGuard(cwd) {
12281
13693
  if (!isPathUnderHarnessWorktree(cwd)) return { ok: true };
@@ -12299,7 +13711,7 @@ function envArgv(env) {
12299
13711
  return out;
12300
13712
  }
12301
13713
  function runSpawn(argv, opts) {
12302
- const res = spawnSync10(argv[0], argv.slice(1), {
13714
+ const res = spawnSync11(argv[0], argv.slice(1), {
12303
13715
  cwd: opts.cwd,
12304
13716
  env: opts.env,
12305
13717
  encoding: "utf8",
@@ -12425,6 +13837,7 @@ function runHarnessVerifyCommands(cwd, commands = DEFAULT_HARNESS_VERIFY_COMMAND
12425
13837
  }
12426
13838
 
12427
13839
  // src/plan-progress.ts
13840
+ init_util();
12428
13841
  function parseEvidenceArg(raw) {
12429
13842
  const idx = raw.indexOf(":");
12430
13843
  if (idx <= 0) throw new Error(`invalid --evidence ${raw} (expected type:value)`);
@@ -12487,7 +13900,7 @@ async function emitPlanProgress(args) {
12487
13900
  }
12488
13901
  function verifyPlanLocal(args) {
12489
13902
  const worktree = required(args.worktree ? String(args.worktree) : void 0, "worktree");
12490
- const cwd = path60.resolve(worktree);
13903
+ const cwd = path62.resolve(worktree);
12491
13904
  const summary = runHarnessVerifyCommands(cwd);
12492
13905
  const emitJson = args.json === true || args.json === "true";
12493
13906
  const payload = { passed: summary.passed, worktree: cwd, steps: summary.steps };
@@ -12536,9 +13949,10 @@ async function verifyPlan(args) {
12536
13949
  }
12537
13950
 
12538
13951
  // src/harness-verify-cli.ts
12539
- import path61 from "node:path";
13952
+ import path63 from "node:path";
13953
+ init_util();
12540
13954
  function runHarnessVerifyCli(args) {
12541
- const cwd = path61.resolve(required(args.worktree ? String(args.worktree) : void 0, "worktree"));
13955
+ const cwd = path63.resolve(required(args.worktree ? String(args.worktree) : void 0, "worktree"));
12542
13956
  const emitJson = args.json === true || args.json === "true" || args.emitJson === true || args.emitJson === "true";
12543
13957
  const commands = [];
12544
13958
  const rawCmd = args.command;
@@ -12583,7 +13997,9 @@ function runHarnessVerifyCli(args) {
12583
13997
  }
12584
13998
 
12585
13999
  // src/plan-persist-cli.ts
12586
- import { readFileSync as readFileSync15 } from "node:fs";
14000
+ init_config();
14001
+ import { readFileSync as readFileSync16 } from "node:fs";
14002
+ init_util();
12587
14003
  var OPERATIONS = ["create", "add_version", "update_metadata"];
12588
14004
  var FAILURE_KINDS = [
12589
14005
  "approval_guard",
@@ -12595,7 +14011,7 @@ var FAILURE_KINDS = [
12595
14011
  function readBodyArg(args) {
12596
14012
  const bodyFile = args.bodyFile ? String(args.bodyFile) : void 0;
12597
14013
  if (bodyFile) {
12598
- return { body: readFileSync15(bodyFile, "utf8"), bodyPathHint: bodyFile };
14014
+ return { body: readFileSync16(bodyFile, "utf8"), bodyPathHint: bodyFile };
12599
14015
  }
12600
14016
  const inline = args.body ? String(args.body) : void 0;
12601
14017
  if (inline) return { body: inline };
@@ -12746,9 +14162,14 @@ function formatMonitorTickNotice(tick) {
12746
14162
  }
12747
14163
 
12748
14164
  // src/monitor/monitor.service.ts
12749
- import path63 from "node:path";
14165
+ import path65 from "node:path";
14166
+ init_run_store();
14167
+ init_status();
14168
+ init_util();
12750
14169
 
12751
14170
  // src/monitor/monitor.classify.ts
14171
+ init_status();
14172
+ init_util();
12752
14173
  function classifyWorkerHealth(input) {
12753
14174
  const { worker, status, taskLease } = input;
12754
14175
  const leaseOwner = taskLease?.leaseOwner ?? null;
@@ -12798,19 +14219,21 @@ function classifyWorkerHealth(input) {
12798
14219
  }
12799
14220
 
12800
14221
  // src/monitor/monitor.store.ts
12801
- import { existsSync as existsSync42, mkdirSync as mkdirSync9, readdirSync as readdirSync16, unlinkSync as unlinkSync5 } from "node:fs";
12802
- import path62 from "node:path";
14222
+ init_paths();
14223
+ init_util();
14224
+ import { existsSync as existsSync42, mkdirSync as mkdirSync10, readdirSync as readdirSync16, unlinkSync as unlinkSync5 } from "node:fs";
14225
+ import path64 from "node:path";
12803
14226
  function monitorsDir() {
12804
14227
  const { harnessRoot } = getHarnessPaths();
12805
- const dir = path62.join(harnessRoot, "monitors");
12806
- mkdirSync9(dir, { recursive: true });
14228
+ const dir = path64.join(harnessRoot, "monitors");
14229
+ mkdirSync10(dir, { recursive: true });
12807
14230
  return dir;
12808
14231
  }
12809
14232
  function monitorIdFor(runId, workerName) {
12810
14233
  return workerName ? `${safeSlug(runId)}--${safeSlug(workerName)}` : safeSlug(runId);
12811
14234
  }
12812
14235
  function monitorPath(monitorId) {
12813
- return path62.join(monitorsDir(), `${monitorId}.json`);
14236
+ return path64.join(monitorsDir(), `${monitorId}.json`);
12814
14237
  }
12815
14238
  function loadMonitorSession(monitorId) {
12816
14239
  return readJson(monitorPath(monitorId), void 0);
@@ -12831,7 +14254,7 @@ function listMonitorSessions() {
12831
14254
  for (const name of readdirSync16(dir)) {
12832
14255
  if (!name.endsWith(".json")) continue;
12833
14256
  const session = readJson(
12834
- path62.join(dir, name),
14257
+ path64.join(dir, name),
12835
14258
  void 0
12836
14259
  );
12837
14260
  if (!session?.monitorId) continue;
@@ -12851,6 +14274,7 @@ function listMonitorSessions() {
12851
14274
  }
12852
14275
 
12853
14276
  // src/monitor/monitor.terminal.ts
14277
+ init_status();
12854
14278
  function assessAutoCompleteEligibility(input) {
12855
14279
  const { worker, status } = input;
12856
14280
  const blockers = [];
@@ -12894,6 +14318,7 @@ function assessAutoCompleteEligibility(input) {
12894
14318
  }
12895
14319
 
12896
14320
  // src/monitor/monitor.task-lease.ts
14321
+ init_config();
12897
14322
  async function fetchTaskLeasesForWorkers(input) {
12898
14323
  const out = /* @__PURE__ */ new Map();
12899
14324
  const agentOsId = input.agentOsId?.trim();
@@ -12922,7 +14347,7 @@ async function fetchTaskLeasesForWorkers(input) {
12922
14347
  // src/monitor/monitor.service.ts
12923
14348
  function workerRecord2(runId, name) {
12924
14349
  return readJson(
12925
- path63.join(runDirectory(runId), "workers", safeSlug(name), "worker.json"),
14350
+ path65.join(runDirectory(runId), "workers", safeSlug(name), "worker.json"),
12926
14351
  void 0
12927
14352
  );
12928
14353
  }
@@ -13092,6 +14517,7 @@ async function monitorAutoCompleteCli(args) {
13092
14517
  }
13093
14518
 
13094
14519
  // src/monitor/monitor-loop.ts
14520
+ init_util();
13095
14521
  var DEFAULT_POLL_MS2 = 5e3;
13096
14522
  var DEFAULT_MAX_TOTAL_MS2 = 6 * 60 * 60 * 1e3;
13097
14523
  async function runMonitorLoop(args) {
@@ -13127,19 +14553,21 @@ async function runMonitorLoop(args) {
13127
14553
  }
13128
14554
 
13129
14555
  // src/monitor/monitor-spawn.ts
13130
- import { spawn as spawn6 } from "node:child_process";
14556
+ init_util();
14557
+ init_paths();
14558
+ import { spawn as spawn7 } from "node:child_process";
13131
14559
  import { closeSync as closeSync8, existsSync as existsSync43, openSync as openSync8 } from "node:fs";
13132
- import path64 from "node:path";
14560
+ import path66 from "node:path";
13133
14561
  import { fileURLToPath as fileURLToPath3 } from "node:url";
13134
14562
  function resolveDefaultCliPath2() {
13135
- return path64.join(fileURLToPath3(new URL(".", import.meta.url)), "cli.js");
14563
+ return path66.join(fileURLToPath3(new URL(".", import.meta.url)), "cli.js");
13136
14564
  }
13137
14565
  function spawnMonitorSidecar(opts) {
13138
14566
  const cliPath = opts.cliPath ?? resolveDefaultCliPath2();
13139
14567
  if (!existsSync43(cliPath)) return void 0;
13140
14568
  const monitorId = monitorIdFor(opts.runId, opts.workerName);
13141
14569
  const { harnessRoot } = getHarnessPaths();
13142
- const logPath = path64.join(harnessRoot, "monitors", `${monitorId}.log`);
14570
+ const logPath = path66.join(harnessRoot, "monitors", `${monitorId}.log`);
13143
14571
  let logFd;
13144
14572
  try {
13145
14573
  logFd = openSync8(logPath, "a");
@@ -13173,7 +14601,7 @@ function spawnMonitorSidecar(opts) {
13173
14601
  logFd ?? "ignore"
13174
14602
  ];
13175
14603
  try {
13176
- const child = spawn6(
14604
+ const child = spawn7(
13177
14605
  nodeExecutable,
13178
14606
  args,
13179
14607
  hiddenSpawnOptions({
@@ -13208,6 +14636,7 @@ function spawnMonitorSidecar(opts) {
13208
14636
  }
13209
14637
 
13210
14638
  // src/monitor/monitor-cli.ts
14639
+ init_util();
13211
14640
  async function startMonitorCli(args) {
13212
14641
  const runId = String(args.run || "");
13213
14642
  required(runId, "--run");
@@ -13259,7 +14688,7 @@ async function monitorTickCli(args) {
13259
14688
  }
13260
14689
 
13261
14690
  // src/package-version.ts
13262
- import { existsSync as existsSync44, readFileSync as readFileSync16 } from "node:fs";
14691
+ import { existsSync as existsSync44, readFileSync as readFileSync17 } from "node:fs";
13263
14692
  import { dirname, join } from "node:path";
13264
14693
  import { fileURLToPath as fileURLToPath4 } from "node:url";
13265
14694
  function resolvePackageRoot(moduleUrl) {
@@ -13274,7 +14703,7 @@ function resolvePackageRoot(moduleUrl) {
13274
14703
  }
13275
14704
  function readOwnPackageVersion(moduleUrl = import.meta.url) {
13276
14705
  const pkgPath = join(resolvePackageRoot(moduleUrl), "package.json");
13277
- const pkg = JSON.parse(readFileSync16(pkgPath, "utf8"));
14706
+ const pkg = JSON.parse(readFileSync17(pkgPath, "utf8"));
13278
14707
  if (typeof pkg.version !== "string" || !pkg.version.trim()) {
13279
14708
  throw new Error(`Missing package.json version at ${pkgPath}`);
13280
14709
  }
@@ -13341,6 +14770,7 @@ function shouldEnforceMemoryCostPackageGuardCli(scope, action) {
13341
14770
  }
13342
14771
 
13343
14772
  // src/run-resolve.ts
14773
+ init_util();
13344
14774
  function resolveHarnessRunByName(runName) {
13345
14775
  const name = runName.trim();
13346
14776
  if (!name) return null;
@@ -13365,7 +14795,11 @@ function resolveHarnessRunCli(args) {
13365
14795
  }
13366
14796
 
13367
14797
  // src/post-restart-unblock.ts
13368
- import path65 from "node:path";
14798
+ init_run_store();
14799
+ init_status();
14800
+ init_util();
14801
+ init_config();
14802
+ import path67 from "node:path";
13369
14803
  function skip(runId, worker, taskId, agentOsId, leaseOwner, reason) {
13370
14804
  return { runId, worker, taskId, agentOsId, leaseOwner, action: "skipped", reason };
13371
14805
  }
@@ -13378,7 +14812,7 @@ async function postRestartUnblock(args) {
13378
14812
  const errors = [];
13379
14813
  for (const run of listRunRecords()) {
13380
14814
  for (const name of Object.keys(run.workers ?? {})) {
13381
- const workerPath = path65.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json");
14815
+ const workerPath = path67.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json");
13382
14816
  const worker = readJson(workerPath, void 0);
13383
14817
  if (!worker) {
13384
14818
  skipped.push(skip(run.id, name, "", "", "", "worker.json missing"));
@@ -13490,9 +14924,11 @@ async function postRestartUnblockCli(args) {
13490
14924
  }
13491
14925
 
13492
14926
  // src/default-repo-cli.ts
13493
- import path66 from "node:path";
13494
- import { homedir as homedir14 } from "node:os";
13495
- var CONFIG_FILE2 = path66.join(homedir14(), ".kynver", "config.json");
14927
+ init_path_values();
14928
+ init_config();
14929
+ import path68 from "node:path";
14930
+ import { homedir as homedir15 } from "node:os";
14931
+ var CONFIG_FILE2 = path68.join(homedir15(), ".kynver", "config.json");
13496
14932
  function ensureDefaultRepo(opts) {
13497
14933
  const existing = loadUserConfig();
13498
14934
  const resolved = resolveDefaultRepo({ ...opts, config: existing });
@@ -13573,16 +15009,19 @@ function summarizeResolvedDefaultRepo(resolved) {
13573
15009
  }
13574
15010
 
13575
15011
  // src/doctor/runtime-takeover.ts
13576
- import path68 from "node:path";
15012
+ import path70 from "node:path";
15013
+ init_path_values();
13577
15014
 
13578
15015
  // src/doctor/runtime-takeover.probes.ts
13579
- import { accessSync, constants, existsSync as existsSync45, readFileSync as readFileSync17 } from "node:fs";
13580
- import { homedir as homedir15 } from "node:os";
13581
- import path67 from "node:path";
13582
- import { spawnSync as spawnSync11 } from "node:child_process";
15016
+ init_config();
15017
+ import { accessSync, constants, existsSync as existsSync45, readFileSync as readFileSync18 } from "node:fs";
15018
+ import { homedir as homedir16 } from "node:os";
15019
+ import path69 from "node:path";
15020
+ import { spawnSync as spawnSync12 } from "node:child_process";
15021
+ init_paths();
13583
15022
  function captureCommand(bin, args) {
13584
15023
  try {
13585
- const res = spawnSync11(bin, args, { encoding: "utf8" });
15024
+ const res = spawnSync12(bin, args, { encoding: "utf8" });
13586
15025
  const stdout = (res.stdout || "").trim();
13587
15026
  const stderr = (res.stderr || "").trim();
13588
15027
  const ok = res.status === 0;
@@ -13620,15 +15059,15 @@ var defaultRuntimeTakeoverProbes = {
13620
15059
  commandOnPath: (bin) => captureCommand(process.platform === "win32" ? "where" : "which", [bin]),
13621
15060
  kynverVersion: (bin) => captureCommand(bin, ["--version"]),
13622
15061
  loadConfig: () => loadUserConfig(),
13623
- configFilePath: () => path67.join(homedir15(), ".kynver", "config.json"),
13624
- credentialsFilePath: () => path67.join(homedir15(), ".kynver", "credentials"),
15062
+ configFilePath: () => path69.join(homedir16(), ".kynver", "config.json"),
15063
+ credentialsFilePath: () => path69.join(homedir16(), ".kynver", "credentials"),
13625
15064
  readCredentials: () => {
13626
- const credPath = path67.join(homedir15(), ".kynver", "credentials");
15065
+ const credPath = path69.join(homedir16(), ".kynver", "credentials");
13627
15066
  if (!existsSync45(credPath)) {
13628
15067
  return { hasApiKey: false };
13629
15068
  }
13630
15069
  try {
13631
- const parsed = JSON.parse(readFileSync17(credPath, "utf8"));
15070
+ const parsed = JSON.parse(readFileSync18(credPath, "utf8"));
13632
15071
  return {
13633
15072
  hasApiKey: Boolean(parsed.apiKey?.trim()),
13634
15073
  runnerTokenPrefix: tokenPrefix(parsed.runnerToken),
@@ -13658,7 +15097,7 @@ var defaultRuntimeTakeoverProbes = {
13658
15097
  })()
13659
15098
  }),
13660
15099
  harnessRoot: () => resolveHarnessRoot(),
13661
- legacyOpenclawHarnessRoot: () => path67.join(homedir15(), ".openclaw", "harness"),
15100
+ legacyOpenclawHarnessRoot: () => path69.join(homedir16(), ".openclaw", "harness"),
13662
15101
  pathExists: (target) => existsSync45(target),
13663
15102
  pathWritable: (target) => isWritable(target)
13664
15103
  };
@@ -13831,12 +15270,12 @@ function assessRuntimeTakeoverScheduler(env, ctx) {
13831
15270
  return check({
13832
15271
  id: "hotspot_openclaw_scheduler",
13833
15272
  label: "Scheduler provider (runtime daemon vs OpenClaw cron)",
13834
- status: "pass",
13835
- summary: "KYNVER_SCHEDULER_PROVIDER unset on hosted deployment; scheduler resolves to kynver-cron (Kynver-owned, not OpenClaw)",
13836
- remediation: "For production hosted AgentOS schedules, set QSTASH_TOKEN and KYNVER_SCHEDULER_PROVIDER=qstash on the Kynver server. Dev/harness hosts may rely on kynver-cron or `kynver daemon` without OpenClaw.",
15273
+ status: "warn",
15274
+ summary: "Hosted deployment with no QSTASH_TOKEN and no KYNVER_SCHEDULER_PROVIDER \u2014 kynver-cron is an in-process stub here and will NOT fire; no firing scheduler is configured",
15275
+ remediation: "Set QSTASH_TOKEN + KYNVER_SCHEDULER_PROVIDER=qstash on the Kynver server for hosted AgentOS schedules. Only use kynver-cron when a `kynver daemon` (or local cron store) actually owns firing on this box.",
13837
15276
  details: {
13838
15277
  schedulerProvider: null,
13839
- resolvedFallback: "kynver-cron",
15278
+ resolvedFallback: "none",
13840
15279
  qstashTokenPresent: false,
13841
15280
  hostedDeployment
13842
15281
  }
@@ -14065,8 +15504,8 @@ function assessVercelDeployEvidence(probes) {
14065
15504
  }
14066
15505
  function assessHarnessDirs(probes) {
14067
15506
  const harnessRoot = probes.harnessRoot();
14068
- const runsDir = path68.join(harnessRoot, "runs");
14069
- const worktreesDir = path68.join(harnessRoot, "worktrees");
15507
+ const runsDir = path70.join(harnessRoot, "runs");
15508
+ const worktreesDir = path70.join(harnessRoot, "worktrees");
14070
15509
  const displayHarnessRoot = redactHomePath(harnessRoot);
14071
15510
  const displayRunsDir = redactHomePath(runsDir);
14072
15511
  const displayWorktreesDir = redactHomePath(worktreesDir);
@@ -14242,6 +15681,7 @@ function runRuntimeTakeoverDoctorCli(args = {}) {
14242
15681
  }
14243
15682
 
14244
15683
  // src/command-center-contract-cli.ts
15684
+ init_config();
14245
15685
  async function runCommandCenterContractCli(args) {
14246
15686
  const config = loadUserConfig();
14247
15687
  const agentOsId = (args.agentOsId ? String(args.agentOsId) : config.agentOsId) || "";
@@ -14272,6 +15712,9 @@ async function runCommandCenterContractCli(args) {
14272
15712
  console.log(JSON.stringify(res.response, null, 2));
14273
15713
  }
14274
15714
 
15715
+ // src/scheduler-cutover-cli.ts
15716
+ init_path_values();
15717
+
14275
15718
  // src/scheduler-cutover.ts
14276
15719
  var DEPLOYMENT_SCHEDULER_CUTOVER_STEPS = [
14277
15720
  "Vercel/hosted: set KYNVER_SCHEDULER_PROVIDER=qstash",
@@ -14330,9 +15773,10 @@ function applySchedulerCutoverAttestation(config) {
14330
15773
  }
14331
15774
 
14332
15775
  // src/scheduler-cutover-cli.ts
14333
- import path69 from "node:path";
14334
- import { homedir as homedir16 } from "node:os";
14335
- var CONFIG_FILE3 = path69.join(homedir16(), ".kynver", "config.json");
15776
+ init_config();
15777
+ import path71 from "node:path";
15778
+ import { homedir as homedir17 } from "node:os";
15779
+ var CONFIG_FILE3 = path71.join(homedir17(), ".kynver", "config.json");
14336
15780
  function runSchedulerCutoverCheckCli(json = false) {
14337
15781
  const config = loadUserConfig();
14338
15782
  const report = assessSchedulerCutover(config);
@@ -14470,7 +15914,12 @@ async function runCronTickCli(args) {
14470
15914
  }
14471
15915
 
14472
15916
  // src/lane/landing-maintainer-tick.ts
14473
- import os9 from "node:os";
15917
+ init_config();
15918
+ import os11 from "node:os";
15919
+ init_config();
15920
+ init_box_identity();
15921
+ init_resource_gate();
15922
+ init_util();
14474
15923
 
14475
15924
  // src/lane/lane-spec.ts
14476
15925
  var LANDING_MAINTAINER_LANE_SPEC = {
@@ -14482,10 +15931,10 @@ var LANDING_MAINTAINER_LANE_SPEC = {
14482
15931
  };
14483
15932
 
14484
15933
  // src/lane/landing-maintainer-local.ts
14485
- import { spawnSync as spawnSync12 } from "node:child_process";
14486
- import path70 from "node:path";
15934
+ import { spawnSync as spawnSync13 } from "node:child_process";
15935
+ import path72 from "node:path";
14487
15936
  function runLandingWrapper(prNumber, repoRoot, execute) {
14488
- const script = path70.join(repoRoot, LANDING_MAINTAINER_LANE_SPEC.landScript);
15937
+ const script = path72.join(repoRoot, LANDING_MAINTAINER_LANE_SPEC.landScript);
14489
15938
  const args = [script, String(prNumber), ...LANDING_MAINTAINER_LANE_SPEC.landScriptArgs];
14490
15939
  if (!execute) {
14491
15940
  return {
@@ -14496,7 +15945,7 @@ function runLandingWrapper(prNumber, repoRoot, execute) {
14496
15945
  stderr: ""
14497
15946
  };
14498
15947
  }
14499
- const result = spawnSync12("node", args, {
15948
+ const result = spawnSync13("node", args, {
14500
15949
  cwd: repoRoot,
14501
15950
  encoding: "utf8",
14502
15951
  timeout: 10 * 60 * 1e3
@@ -14511,7 +15960,7 @@ function runLandingWrapper(prNumber, repoRoot, execute) {
14511
15960
  }
14512
15961
  function resolveLandingMaintainerRepoRoot(args) {
14513
15962
  const explicit = args.repoPath ? String(args.repoPath).trim() : "";
14514
- if (explicit) return path70.resolve(explicit);
15963
+ if (explicit) return path72.resolve(explicit);
14515
15964
  const resolved = resolveDefaultRepo();
14516
15965
  return resolved?.repo ?? process.cwd();
14517
15966
  }
@@ -14530,7 +15979,7 @@ async function runLandingMaintainerLaneTick(args) {
14530
15979
  ...buildBoxResourceSnapshotFromGate(resourceGate, {
14531
15980
  harnessRunId: runId,
14532
15981
  boxKind: resolveBoxKindFromConfig(loadUserConfig()),
14533
- hostLabel: os9.hostname()
15982
+ hostLabel: os11.hostname()
14534
15983
  }),
14535
15984
  providerHealthy: resourceGate.ok,
14536
15985
  authorizedForRepair: resourceGate.ok,
@@ -14634,18 +16083,20 @@ function usage(code = 0) {
14634
16083
  out(
14635
16084
  [
14636
16085
  "Usage:",
14637
- " kynver login --api-key KEY",
16086
+ " kynver login [--api-key KEY] [--api-base-url URL] (omit --api-key to authorize in the browser)",
16087
+ " kynver bootstrap [--api-base-url URL] [--api-key KEY] [--repo PATH] (login + setup + runner credential in one shot)",
14638
16088
  " kynver runner credential [--agent-os-id ID] [--base-url URL]",
14639
16089
  " kynver setup [--api-base-url URL] [--agent-os-id ID] [--agent-os-slug SLUG] [--box-kind forge|ghost] [--repo PATH] [--discover-repo] [--max-workers N] [--provider claude|cursor]",
14640
- " kynver daemon --run RUN_ID --agent-os-id AOS_ID [--execute] [--interval-ms MS]",
16090
+ " kynver daemon --run RUN_ID --agent-os-id AOS_ID [--execute] [--interval-ms MS] [--stall-ms MS] [--no-supervise]",
16091
+ " kynver status --run RUN_ID [--blocked] [--running] [--task TASK_ID] [--worker WORKER] [--full] # top-level compact run status",
14641
16092
  " kynver run create [--repo /path/repo] [--name name] [--base origin/main]",
14642
16093
  " kynver run list",
14643
16094
  " kynver run resolve --name RUN_NAME",
14644
- " kynver run status --run RUN_ID [--json] [--compact]",
16095
+ " kynver run status --run RUN_ID [--full] # defaults to compact shallow map with drill-down commands",
14645
16096
  " kynver run dispatch --run RUN_ID --agent-os-id AOS_ID [--base-url URL] [--secret SECRET] [--execute] [--lane any|implementation|review|landing] [--target-task-id TASK_ID] [--executor harness] [--max-starts 1] [--lease-ms MS] [--owned path[,path]] [--model claude-opus-4-8] [--disk-path /] [--reconcile-stale-blockers]",
14646
16097
  " kynver run sweep --run RUN_ID --agent-os-id AOS_ID [--base-url URL] [--secret SECRET] [--grace-ms MS]",
14647
16098
  ' kynver worker start --run RUN_ID --name worker --task "..." [--owned path[,path]] [--model MODEL] [--provider claude|cursor] [--agent-os-id AOS_ID] [--task-id TASK_ID] [--wait]',
14648
- " kynver worker list --run RUN_ID [--json] [--compact] [--full]",
16099
+ " kynver worker list --run RUN_ID [--full] # defaults to compact shallow map with drill-down commands",
14649
16100
  " kynver worker status --run RUN_ID --name worker",
14650
16101
  " kynver worker tail --run RUN_ID --name worker [--lines 40] [--raw]",
14651
16102
  " kynver worker stop --run RUN_ID --name worker",
@@ -14697,8 +16148,11 @@ async function main(argv = process.argv.slice(2)) {
14697
16148
  if (action && isHelpFlag(action) || rest.some(isHelpFlag)) return usage(0);
14698
16149
  const args = parseArgs(rest);
14699
16150
  const { runsDir, worktreesDir } = getPaths();
14700
- mkdirSync10(runsDir, { recursive: true });
14701
- mkdirSync10(worktreesDir, { recursive: true });
16151
+ mkdirSync11(runsDir, { recursive: true });
16152
+ mkdirSync11(worktreesDir, { recursive: true });
16153
+ if (scope === "daemon") {
16154
+ assertNativeDaemonAllowed();
16155
+ }
14702
16156
  if (shouldEnforceMemoryCostPackageGuardCli(scope, action)) {
14703
16157
  let repoRoot;
14704
16158
  const runId = args.run ? String(args.run).trim() : "";
@@ -14715,9 +16169,16 @@ async function main(argv = process.argv.slice(2)) {
14715
16169
  });
14716
16170
  }
14717
16171
  if (scope === "login") return void await runLogin(args);
16172
+ if (scope === "bootstrap") return void await runBootstrap(args);
16173
+ if (scope === "status") return runStatus(args);
14718
16174
  if (scope === "runner" && action === "credential") return void await mintRunnerCredential(args);
14719
16175
  if (scope === "setup") return void await runSetup(args);
14720
- if (scope === "daemon") return void await runDaemon(args);
16176
+ if (scope === "daemon") {
16177
+ if (shouldRunDaemonKeeper(args)) {
16178
+ return void await runDaemonKeeper(args);
16179
+ }
16180
+ return void await runDaemon(args);
16181
+ }
14721
16182
  if (scope === "plan" && action === "progress") return void await emitPlanProgress(args);
14722
16183
  if (scope === "plan" && action === "verify") return void await verifyPlan(args);
14723
16184
  if (scope === "harness" && action === "verify") return runHarnessVerifyCli(args);