@kynver-app/runtime 0.1.112 → 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.
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,8 +134,49 @@ 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
181
  const res = spawnSync(
179
182
  "git",
@@ -297,6 +300,13 @@ function unknownAncestry(base, error, head = null) {
297
300
  error
298
301
  };
299
302
  }
303
+ var init_git = __esm({
304
+ "src/git.ts"() {
305
+ "use strict";
306
+ init_util();
307
+ init_worker_env();
308
+ }
309
+ });
300
310
 
301
311
  // src/path-values.ts
302
312
  import { homedir } from "node:os";
@@ -326,15 +336,17 @@ function redactHomePath(value) {
326
336
  function displayUserPath(value) {
327
337
  return redactHomePath(value);
328
338
  }
339
+ var init_path_values = __esm({
340
+ "src/path-values.ts"() {
341
+ "use strict";
342
+ }
343
+ });
329
344
 
330
345
  // src/default-repo-discovery.ts
331
- var WELL_KNOWN_REPO_DIRS = [
332
- "Kynver",
333
- "repos/Kynver",
334
- "repos/kynver-source-main",
335
- "code/Kynver",
336
- "projects/Kynver"
337
- ];
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";
338
350
  function readPackageName(repoRoot) {
339
351
  const pkgPath = path3.join(repoRoot, "package.json");
340
352
  if (!existsSync2(pkgPath)) return null;
@@ -399,6 +411,21 @@ function discoverDefaultRepoCandidates(opts) {
399
411
  function discoverDefaultRepo(opts) {
400
412
  return discoverDefaultRepoCandidates(opts)[0] ?? null;
401
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
+ });
402
429
 
403
430
  // src/box-identity.ts
404
431
  function normalizeWorkerPoolBoxKind(raw) {
@@ -448,9 +475,11 @@ function resolveBoxIdentity(env = process.env, config = {}) {
448
475
  function resolveBoxKindFromConfig(config = {}, env = process.env) {
449
476
  return resolveBoxIdentity(env, config).boxKind;
450
477
  }
451
-
452
- // src/resource-gate.ts
453
- import os2 from "node:os";
478
+ var init_box_identity = __esm({
479
+ "src/box-identity.ts"() {
480
+ "use strict";
481
+ }
482
+ });
454
483
 
455
484
  // src/bounded-build/meminfo.ts
456
485
  import { readFileSync as readFileSync3 } from "node:fs";
@@ -471,18 +500,14 @@ function readMemAvailableBytes(meminfoText) {
471
500
  }
472
501
  return os.freemem();
473
502
  }
474
-
475
- // src/resource-gate.ts
476
- import path7 from "node:path";
477
-
478
- // src/disk-gate.ts
479
- import { statfsSync as statfsSync2 } from "node:fs";
503
+ var init_meminfo = __esm({
504
+ "src/bounded-build/meminfo.ts"() {
505
+ "use strict";
506
+ }
507
+ });
480
508
 
481
509
  // src/wsl-host.ts
482
510
  import { existsSync as existsSync3, readFileSync as readFileSync4, statfsSync } from "node:fs";
483
- var DEFAULT_WSL_HOST_WARN_FREE_BYTES = 25 * 1024 * 1024 * 1024;
484
- var DEFAULT_WSL_HOST_CRITICAL_FREE_BYTES = 12 * 1024 * 1024 * 1024;
485
- var DEFAULT_WSL_HOST_MOUNT = "/mnt/c";
486
511
  function isWslHost() {
487
512
  if (process.platform !== "linux") return false;
488
513
  for (const probe of ["/proc/sys/kernel/osrelease", "/proc/version"]) {
@@ -498,23 +523,23 @@ function isWslHost() {
498
523
  function observeWslHostDisk(options = {}) {
499
524
  const wsl = options.forceWsl === void 0 ? isWslHost() : options.forceWsl;
500
525
  if (!wsl) return null;
501
- 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;
502
527
  const warnBelowBytes = options.wslHostFreeWarnBytes ?? DEFAULT_WSL_HOST_WARN_FREE_BYTES;
503
528
  const criticalBelowBytes = options.wslHostFreeCriticalBytes ?? DEFAULT_WSL_HOST_CRITICAL_FREE_BYTES;
504
529
  const statfs = options.statfs ?? statfsSync;
505
530
  let stats;
506
531
  try {
507
- stats = statfs(path71);
532
+ stats = statfs(path73);
508
533
  } catch (error) {
509
534
  return {
510
535
  ok: false,
511
- path: path71,
536
+ path: path73,
512
537
  freeBytes: 0,
513
538
  totalBytes: 0,
514
539
  usedPercent: 100,
515
540
  warnBelowBytes,
516
541
  criticalBelowBytes,
517
- reason: `Windows host disk probe failed at ${path71}: ${error.message}`,
542
+ reason: `Windows host disk probe failed at ${path73}: ${error.message}`,
518
543
  probeError: error.message
519
544
  };
520
545
  }
@@ -528,11 +553,11 @@ function observeWslHostDisk(options = {}) {
528
553
  let reason = null;
529
554
  if (!ok) {
530
555
  const tag = criticalFree ? "critical" : "warning";
531
- 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()}`;
532
557
  }
533
558
  return {
534
559
  ok,
535
- path: path71,
560
+ path: path73,
536
561
  freeBytes,
537
562
  totalBytes,
538
563
  usedPercent,
@@ -545,19 +570,25 @@ function observeWslHostDisk(options = {}) {
545
570
  function summarizeWslRecoverySteps() {
546
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.";
547
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
+ });
548
582
 
549
583
  // src/disk-gate.ts
550
- var DEFAULT_WARN_FREE_BYTES = 30 * 1024 * 1024 * 1024;
551
- var DEFAULT_CRITICAL_FREE_BYTES = 15 * 1024 * 1024 * 1024;
552
- var DEFAULT_MAX_USED_PERCENT = 80;
553
- var DEFAULT_HARD_MAX_USED_PERCENT = 90;
584
+ import { statfsSync as statfsSync2 } from "node:fs";
554
585
  function observeRunnerDiskGate(input = {}) {
555
- const path71 = input.diskPath?.trim() || "/";
586
+ const path73 = input.diskPath?.trim() || "/";
556
587
  const warnBelowBytes = input.diskFreeWarnBytes ?? DEFAULT_WARN_FREE_BYTES;
557
588
  const criticalBelowBytes = input.diskFreeCriticalBytes ?? DEFAULT_CRITICAL_FREE_BYTES;
558
589
  const maxUsedPercent = input.diskMaxUsedPercent ?? DEFAULT_MAX_USED_PERCENT;
559
590
  const hardMaxUsedPercent = input.diskHardMaxUsedPercent ?? DEFAULT_HARD_MAX_USED_PERCENT;
560
- const stats = statfsSync2(path71);
591
+ const stats = statfsSync2(path73);
561
592
  const freeBytes = Number(stats.bavail) * Number(stats.bsize);
562
593
  const totalBytes = Number(stats.blocks) * Number(stats.bsize);
563
594
  const usedPercent = totalBytes > 0 ? (totalBytes - freeBytes) / totalBytes * 100 : 100;
@@ -580,7 +611,7 @@ function observeRunnerDiskGate(input = {}) {
580
611
  }
581
612
  return {
582
613
  ok,
583
- path: path71,
614
+ path: path73,
584
615
  freeBytes,
585
616
  totalBytes,
586
617
  usedPercent,
@@ -592,17 +623,22 @@ function observeRunnerDiskGate(input = {}) {
592
623
  wslHost
593
624
  };
594
625
  }
595
-
596
- // src/run-store.ts
597
- import { existsSync as existsSync5, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
598
- 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
+ });
599
637
 
600
638
  // src/paths.ts
601
639
  import { existsSync as existsSync4 } from "node:fs";
602
640
  import { homedir as homedir3 } from "node:os";
603
641
  import path4 from "node:path";
604
- var LEGACY_ROOT = path4.join(homedir3(), ".openclaw", "harness");
605
- var HARNESS_LAYOUT_DIR_NAMES = /* @__PURE__ */ new Set(["runs", "worktrees"]);
606
642
  function normalizeHarnessRoot(root) {
607
643
  let resolved = path4.resolve(resolveUserPath(root.trim()));
608
644
  while (HARNESS_LAYOUT_DIR_NAMES.has(path4.basename(resolved))) {
@@ -637,8 +673,21 @@ function getHarnessPaths() {
637
673
  function runDir(runsDir, id) {
638
674
  return path4.join(runsDir, safeSlug(id));
639
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
+ });
640
687
 
641
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";
642
691
  function getPaths() {
643
692
  return getHarnessPaths();
644
693
  }
@@ -696,6 +745,13 @@ function runDirectory(id) {
696
745
  function runDirectoryAt(harnessRoot, id) {
697
746
  return runDir(harnessRunsDir(harnessRoot), safeSlug(id));
698
747
  }
748
+ var init_run_store = __esm({
749
+ "src/run-store.ts"() {
750
+ "use strict";
751
+ init_paths();
752
+ init_util();
753
+ }
754
+ });
699
755
 
700
756
  // src/run-worker-index.ts
701
757
  import { existsSync as existsSync6, readdirSync as readdirSync3 } from "node:fs";
@@ -713,12 +769,13 @@ function listRunWorkerNames(run) {
713
769
  }
714
770
  return [...names];
715
771
  }
716
-
717
- // src/harness-worker-active.ts
718
- import { readFileSync as readFileSync7 } from "node:fs";
719
-
720
- // src/heartbeat.ts
721
- 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
+ });
722
779
 
723
780
  // src/heartbeat-final-result.ts
724
781
  function tryParseJsonObject(text) {
@@ -769,9 +826,14 @@ function terminalFinalResultFromHeartbeatRow(row) {
769
826
  if (embedded) return embedded;
770
827
  return summary;
771
828
  }
829
+ var init_heartbeat_final_result = __esm({
830
+ "src/heartbeat-final-result.ts"() {
831
+ "use strict";
832
+ }
833
+ });
772
834
 
773
835
  // src/heartbeat.ts
774
- var HEARTBEAT_FUTURE_SKEW_MS = 6e4;
836
+ import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
775
837
  function isTerminalHeartbeatPhase(phase) {
776
838
  return phase === "complete";
777
839
  }
@@ -834,29 +896,17 @@ function parseHeartbeat(file) {
834
896
  }
835
897
  return result;
836
898
  }
837
-
838
- // src/stream.ts
839
- 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
+ });
840
908
 
841
909
  // src/repo-search.ts
842
- var RG_BINARIES = /* @__PURE__ */ new Set(["rg", "ripgrep", "grep"]);
843
- var RG_OPTS_WITH_VALUE = /* @__PURE__ */ new Set([
844
- "-e",
845
- "--regexp",
846
- "-f",
847
- "--file",
848
- "-m",
849
- "--max-count",
850
- "-A",
851
- "--after-context",
852
- "-B",
853
- "--before-context",
854
- "-C",
855
- "--context",
856
- "-g",
857
- "--glob",
858
- "--iglob"
859
- ]);
860
910
  function binaryName(token) {
861
911
  if (!token) return null;
862
912
  const base = token.split("/").pop() ?? token;
@@ -1055,11 +1105,32 @@ function diagnoseRepoSearchFailure(input) {
1055
1105
  }
1056
1106
  return null;
1057
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
+ });
1058
1132
 
1059
1133
  // src/shell-command-outcome.ts
1060
- var NPM_AUDIT_RE = /\bnpm\s+audit\b/i;
1061
- var RG_CMD_RE = /\b(rg|ripgrep)\b/i;
1062
- var RG_REAL_ERROR_RE = /\b(error|invalid|unknown|panic|not found)\b/i;
1063
1134
  function tidy(text, max = 200) {
1064
1135
  const one = text.replace(/\s+/g, " ").trim();
1065
1136
  return one.length > max ? `${one.slice(0, max - 1)}\u2026` : one;
@@ -1263,8 +1334,19 @@ function classifyShellCommandOutcome(input) {
1263
1334
  summary: `command failed (exit ${input.exitCode}): ${tail}`
1264
1335
  };
1265
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
+ });
1266
1347
 
1267
1348
  // src/stream.ts
1349
+ import { existsSync as existsSync8, readFileSync as readFileSync6 } from "node:fs";
1268
1350
  function eventTimestampIso(event) {
1269
1351
  const tsMs = event.timestamp_ms;
1270
1352
  return event.timestamp || event.ts || (tsMs ? new Date(tsMs).toISOString() : void 0);
@@ -1430,38 +1512,15 @@ function summarizeEvent(event) {
1430
1512
  }
1431
1513
  return void 0;
1432
1514
  }
1515
+ var init_stream = __esm({
1516
+ "src/stream.ts"() {
1517
+ "use strict";
1518
+ init_shell_command_outcome();
1519
+ init_util();
1520
+ }
1521
+ });
1433
1522
 
1434
1523
  // src/exit-classify.ts
1435
- var FAILURE_PATTERNS = [
1436
- {
1437
- test: /\b(?:invalid|unknown|unsupported|unrecognized)\b[^.\n]*\bmodel\b/i,
1438
- label: "provider rejected the requested model"
1439
- },
1440
- {
1441
- test: /\bmodel\b[^.\n]*\b(?:not\s+(?:found|supported|available|recognized|valid)|is\s+not\s+valid|does\s+not\s+exist)/i,
1442
- label: "provider rejected the requested model"
1443
- },
1444
- {
1445
- test: /\b(?:did you mean|available models|choose (?:a|one of)|supported models)\b/i,
1446
- label: "provider rejected the requested model"
1447
- },
1448
- {
1449
- test: /model preflight failed/i,
1450
- label: "model/provider preflight failed"
1451
- },
1452
- {
1453
- test: /\b(?:command not found|ENOENT|is the .*CLI on PATH|executable not found|no such file or directory)\b/i,
1454
- label: "provider CLI is missing or not on PATH"
1455
- },
1456
- {
1457
- test: /\bfailed to spawn\b/i,
1458
- label: "provider failed to spawn the worker process"
1459
- },
1460
- {
1461
- test: /\b(?:not logged in|unauthorized|authentication (?:failed|required)|invalid api key|missing api key|401)\b/i,
1462
- label: "provider authentication failed"
1463
- }
1464
- ];
1465
1524
  function tidy2(errorText, max = 240) {
1466
1525
  const oneLine2 = errorText.replace(/\s+/g, " ").trim();
1467
1526
  return oneLine2.length > max ? `${oneLine2.slice(0, max - 1)}\u2026` : oneLine2;
@@ -1476,6 +1535,42 @@ function classifyExitFailure(errorText) {
1476
1535
  }
1477
1536
  return null;
1478
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
+ });
1479
1574
 
1480
1575
  // src/exited-salvage.ts
1481
1576
  function trimOrNull(value) {
@@ -1534,6 +1629,11 @@ function assessExitedWorkerSalvage(input) {
1534
1629
  attentionReason: buildAttentionReason(kind, uncommittedCount, headCommit)
1535
1630
  };
1536
1631
  }
1632
+ var init_exited_salvage = __esm({
1633
+ "src/exited-salvage.ts"() {
1634
+ "use strict";
1635
+ }
1636
+ });
1537
1637
 
1538
1638
  // src/landing-gate.ts
1539
1639
  function trimOrNull2(value) {
@@ -1579,6 +1679,11 @@ function landingAttentionReason(verdict) {
1579
1679
  if (!verdict.blocked) return void 0;
1580
1680
  return verdict.detail ?? verdict.reason ?? "dirty_worktree_no_pr";
1581
1681
  }
1682
+ var init_landing_gate = __esm({
1683
+ "src/landing-gate.ts"() {
1684
+ "use strict";
1685
+ }
1686
+ });
1582
1687
 
1583
1688
  // src/worker-final-result-embed.ts
1584
1689
  function tryParseJsonObject2(text) {
@@ -1628,6 +1733,11 @@ function extractEmbeddedWorkerFinalResultRecord(value) {
1628
1733
  }
1629
1734
  return best;
1630
1735
  }
1736
+ var init_worker_final_result_embed = __esm({
1737
+ "src/worker-final-result-embed.ts"() {
1738
+ "use strict";
1739
+ }
1740
+ });
1631
1741
 
1632
1742
  // src/landing-contract-gate.ts
1633
1743
  function trimOrNull3(value) {
@@ -1787,10 +1897,14 @@ function landingContractAttentionReason(verdict) {
1787
1897
  if (!verdict.blocked) return void 0;
1788
1898
  return verdict.detail ?? verdict.reason;
1789
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
+ });
1790
1906
 
1791
1907
  // src/status.ts
1792
- var NO_START_MS = 18e4;
1793
- var STALE_MS = 6e5;
1794
1908
  function computeAttention(input) {
1795
1909
  const now = Date.now();
1796
1910
  if (input.completionBlocker && !isSkippedTerminalCompletionBlocker(input.completionBlocker)) {
@@ -1982,7 +2096,15 @@ function computeWorkerStatus(worker, options = {}) {
1982
2096
  changedFiles,
1983
2097
  gitAncestry,
1984
2098
  instructionPolicyFingerprint: worker.instructionPolicyFingerprint ?? null,
1985
- 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
1986
2108
  };
1987
2109
  }
1988
2110
  function isFinishedWorkerStatus(status) {
@@ -2004,8 +2126,26 @@ function deriveRunStatus(fallback, workers) {
2004
2126
  if (workers.some((w) => w.status === "running")) return "running";
2005
2127
  return fallback;
2006
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
+ });
2007
2146
 
2008
2147
  // src/harness-worker-active.ts
2148
+ import { readFileSync as readFileSync7 } from "node:fs";
2009
2149
  function pidCommandLine(pid) {
2010
2150
  if (!pid || process.platform !== "linux") return null;
2011
2151
  try {
@@ -2031,12 +2171,16 @@ function isActiveHarnessWorker(worker) {
2031
2171
  if (status.alive && !workerProcessMatchesRecord(worker)) return false;
2032
2172
  return status.alive && !status.finalResult && status.attention.state !== "done";
2033
2173
  }
2174
+ var init_harness_worker_active = __esm({
2175
+ "src/harness-worker-active.ts"() {
2176
+ "use strict";
2177
+ init_status();
2178
+ }
2179
+ });
2034
2180
 
2035
2181
  // src/resource-gate.ts
2036
- var DEFAULT_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
2037
- var DEFAULT_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
2038
- var DEFAULT_MEM_UTILIZATION = 0.85;
2039
- var AUTO_MAX_WORKERS_CEILING = 64;
2182
+ import os2 from "node:os";
2183
+ import path7 from "node:path";
2040
2184
  function positiveInt(value, fallback) {
2041
2185
  const n = Number(value);
2042
2186
  if (!Number.isFinite(n) || n <= 0) return fallback;
@@ -2142,6 +2286,25 @@ function observeRunnerResourceGate(input) {
2142
2286
  ...diskGate ? { diskGate } : {}
2143
2287
  };
2144
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
+ });
2145
2308
 
2146
2309
  // src/worker-cap-source.ts
2147
2310
  function positiveInt2(value, fallback) {
@@ -2213,12 +2376,113 @@ function recommendSetupWorkerCap(input = {}) {
2213
2376
  diskFreeBytes: input.diskFreeBytes ?? null
2214
2377
  };
2215
2378
  }
2379
+ var init_worker_cap_source = __esm({
2380
+ "src/worker-cap-source.ts"() {
2381
+ "use strict";
2382
+ init_resource_gate();
2383
+ }
2384
+ });
2216
2385
 
2217
- // src/config.ts
2386
+ // src/device-login.ts
2387
+ var device_login_exports = {};
2388
+ __export(device_login_exports, {
2389
+ runDeviceLogin: () => runDeviceLogin
2390
+ });
2218
2391
  import os3 from "node:os";
2219
- var CONFIG_DIR = path8.join(homedir4(), ".kynver");
2220
- var CONFIG_FILE = path8.join(CONFIG_DIR, "config.json");
2221
- 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";
2222
2486
  function loadUserConfig() {
2223
2487
  if (!existsSync9(CONFIG_FILE)) return {};
2224
2488
  try {
@@ -2257,8 +2521,6 @@ function inferSetupFields(existing, args) {
2257
2521
  ...typeof args.agentOsSlug === "string" ? { agentOsSlug: args.agentOsSlug } : existing.agentOsSlug ? { agentOsSlug: existing.agentOsSlug } : {}
2258
2522
  };
2259
2523
  }
2260
- var SETUP_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
2261
- var SETUP_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
2262
2524
  function resolveSetupWorkerConfig(existing, args, totalMemBytes = totalmem()) {
2263
2525
  const maxWorkersRaw = typeof args.maxWorkers === "string" ? args.maxWorkers : typeof args.maxConcurrentWorkers === "string" ? args.maxConcurrentWorkers : void 0;
2264
2526
  const explicitBoxKindArg = typeof args.boxKind === "string" ? args.boxKind : typeof args["box-kind"] === "string" ? String(args["box-kind"]) : void 0;
@@ -2479,7 +2741,7 @@ async function runSetup(args) {
2479
2741
  diskPath: typeof args.diskPath === "string" ? args.diskPath : "/"
2480
2742
  });
2481
2743
  const capRecommendation = recommendSetupWorkerCap({
2482
- totalMemBytes: os3.totalmem(),
2744
+ totalMemBytes: os4.totalmem(),
2483
2745
  diskPath: diskGate.path,
2484
2746
  diskGateOk: diskGate.ok,
2485
2747
  diskFreeBytes: diskGate.freeBytes,
@@ -2528,10 +2790,104 @@ async function runSetup(args) {
2528
2790
  }
2529
2791
  async function runLogin(args) {
2530
2792
  const apiKey = typeof args.apiKey === "string" ? args.apiKey : process.env.KYNVER_API_KEY;
2531
- if (!apiKey) failConfig("kynver login requires --api-key or KYNVER_API_KEY");
2532
- 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);
2533
2801
  console.log(JSON.stringify({ ok: true, credentialsPath: displayUserPath(CREDENTIALS_FILE) }, null, 2));
2534
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();
2535
2891
 
2536
2892
  // src/callback-headers.ts
2537
2893
  function buildHarnessCallbackHeaders(secret) {
@@ -2555,6 +2911,7 @@ function buildHarnessCallbackHeaders(secret) {
2555
2911
  }
2556
2912
 
2557
2913
  // src/callbacks.ts
2914
+ init_config();
2558
2915
  function callbackTimeoutMs() {
2559
2916
  const parsed = Number(process.env.KYNVER_CALLBACK_TIMEOUT_MS);
2560
2917
  if (Number.isFinite(parsed) && parsed > 0) return Math.floor(parsed);
@@ -2768,6 +3125,12 @@ function resolveDispatchNextLaneFilter(raw) {
2768
3125
  return normalizeDispatchNextLaneFilter(raw) ?? "any";
2769
3126
  }
2770
3127
 
3128
+ // src/dispatch.ts
3129
+ init_disk_gate();
3130
+ init_resource_gate();
3131
+ init_run_store();
3132
+ init_run_store();
3133
+
2771
3134
  // src/model-routing-task-enrich.ts
2772
3135
  function taskString(task, key) {
2773
3136
  const v = task[key];
@@ -2817,6 +3180,9 @@ function enrichTaskForModelRouting(task) {
2817
3180
  return { ...task, roleLane };
2818
3181
  }
2819
3182
 
3183
+ // src/model-routing.ts
3184
+ init_config();
3185
+
2820
3186
  // src/worker-provider-policy.ts
2821
3187
  var DEFAULT_WORKER_PROVIDER = "cursor";
2822
3188
  var CLAUDE_FAMILY = /* @__PURE__ */ new Set(["claude", "opus", "anthropic"]);
@@ -3480,6 +3846,8 @@ function resolveOrchestrationRouting(input) {
3480
3846
  }
3481
3847
 
3482
3848
  // src/providers/claude.ts
3849
+ init_worker_env();
3850
+ init_util();
3483
3851
  import { closeSync, openSync } from "node:fs";
3484
3852
  import { spawn } from "node:child_process";
3485
3853
 
@@ -3617,13 +3985,17 @@ var claudeProvider = {
3617
3985
  };
3618
3986
 
3619
3987
  // src/providers/codex.ts
3988
+ init_worker_env();
3989
+ init_util();
3620
3990
  import { closeSync as closeSync3, existsSync as existsSync15, openSync as openSync3 } from "node:fs";
3621
3991
  import { spawn as spawn3 } from "node:child_process";
3622
3992
 
3623
3993
  // src/providers/hermes-codex.ts
3994
+ init_worker_env();
3995
+ init_util();
3624
3996
  import { closeSync as closeSync2, openSync as openSync2 } from "node:fs";
3625
3997
  import { spawn as spawn2 } from "node:child_process";
3626
- 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";
3627
3999
  function hermesWorkerEnv() {
3628
4000
  return scrubWorkerEnv({
3629
4001
  ...process.env,
@@ -3691,7 +4063,10 @@ var hermesCodexProvider = {
3691
4063
  };
3692
4064
 
3693
4065
  // src/providers/codex.ts
3694
- 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();
3695
4070
  function resolveCodexBin() {
3696
4071
  return process.env.KYNVER_CODEX_BIN?.trim() || process.env.CODEX_BIN?.trim() || "codex";
3697
4072
  }
@@ -3943,7 +4318,11 @@ function readHarnessRetryLimits() {
3943
4318
  }
3944
4319
 
3945
4320
  // src/lease-renewal.ts
4321
+ init_config();
3946
4322
  import path14 from "node:path";
4323
+ init_run_store();
4324
+ init_status();
4325
+ init_util();
3947
4326
 
3948
4327
  // src/harness-lease-owner.ts
3949
4328
  var HARNESS_LEASE_PREFIX = "kynver-harness:";
@@ -3979,12 +4358,14 @@ function resolveHarnessLeaseOwnerForRenewal(input) {
3979
4358
  }
3980
4359
 
3981
4360
  // src/runner-identity.ts
3982
- import os5 from "node:os";
4361
+ import os7 from "node:os";
3983
4362
 
3984
4363
  // src/box-resource-snapshot-shared.ts
3985
- import os4 from "node:os";
4364
+ init_box_identity();
4365
+ init_box_identity();
4366
+ import os6 from "node:os";
3986
4367
  function defaultBoxId(boxKind, hostLabel) {
3987
- 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";
3988
4369
  return `${boxKind}:${host}`;
3989
4370
  }
3990
4371
 
@@ -3995,10 +4376,10 @@ function trimOrNull5(value) {
3995
4376
  }
3996
4377
  function resolveRunnerPresencePayload(input = {}) {
3997
4378
  const env = input.env ?? process.env;
3998
- 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();
3999
4380
  return {
4000
4381
  runnerId,
4001
- hostname: trimOrNull5(env.HOSTNAME) ?? os5.hostname(),
4382
+ hostname: trimOrNull5(env.HOSTNAME) ?? os7.hostname(),
4002
4383
  profile: trimOrNull5(env.KYNVER_RUNNER_PROFILE) ?? trimOrNull5(env.OPENCLAW_RUNNER_PROFILE),
4003
4384
  harnessRepo: trimOrNull5(env.KYNVER_HARNESS_REPO) ?? trimOrNull5(env.KYNVER_DEFAULT_REPO),
4004
4385
  runId: input.runId ?? null
@@ -4083,6 +4464,9 @@ function hasLiveWorkerForTask(runId, taskId) {
4083
4464
  }
4084
4465
 
4085
4466
  // src/supervisor.ts
4467
+ init_git();
4468
+ init_run_store();
4469
+ init_run_store();
4086
4470
  import { existsSync as existsSync19, mkdirSync as mkdirSync4 } from "node:fs";
4087
4471
  import path21 from "node:path";
4088
4472
 
@@ -4232,10 +4616,18 @@ function buildPrompt(input) {
4232
4616
  ].join("\n");
4233
4617
  }
4234
4618
 
4619
+ // src/supervisor.ts
4620
+ init_util();
4621
+
4622
+ // src/providers/registry.ts
4623
+ init_config();
4624
+
4235
4625
  // src/providers/cursor.ts
4626
+ init_util();
4627
+ init_worker_env();
4236
4628
  import { closeSync as closeSync4, existsSync as existsSync17, mkdirSync as mkdirSync3, openSync as openSync4, statSync as statSync4, unlinkSync } from "node:fs";
4237
4629
  import { spawn as spawn4 } from "node:child_process";
4238
- import os6 from "node:os";
4630
+ import os8 from "node:os";
4239
4631
  import path16 from "node:path";
4240
4632
 
4241
4633
  // src/providers/cursor-windows.ts
@@ -4346,7 +4738,7 @@ function positiveIntEnv(name, fallback) {
4346
4738
  return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : fallback;
4347
4739
  }
4348
4740
  function cursorStartLockPath() {
4349
- 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");
4350
4742
  mkdirSync3(root, { recursive: true });
4351
4743
  return path16.join(root, "cursor-agent-start.lock");
4352
4744
  }
@@ -4472,12 +4864,14 @@ function resolveWorkerProvider(name) {
4472
4864
  }
4473
4865
 
4474
4866
  // src/auto-complete.ts
4867
+ init_util();
4475
4868
  import { spawn as spawn5 } from "node:child_process";
4476
4869
  import { existsSync as existsSync18, openSync as openSync5, closeSync as closeSync5 } from "node:fs";
4477
4870
  import path20 from "node:path";
4478
4871
  import { fileURLToPath as fileURLToPath2 } from "node:url";
4479
4872
 
4480
4873
  // src/completion-ack.ts
4874
+ init_run_store();
4481
4875
  function hasCompletionAck(worker) {
4482
4876
  return Boolean(worker.completionReportedAt?.trim());
4483
4877
  }
@@ -4505,7 +4899,12 @@ function hasTerminalCompletionAck(worker) {
4505
4899
  return hasCompletionAck(worker) && !shouldReplayHarnessCompletion(worker);
4506
4900
  }
4507
4901
 
4902
+ // src/auto-complete.ts
4903
+ init_run_store();
4904
+ init_status();
4905
+
4508
4906
  // src/worker-ops.ts
4907
+ init_config();
4509
4908
  import path19 from "node:path";
4510
4909
 
4511
4910
  // src/completion-response.ts
@@ -4547,6 +4946,10 @@ function completionPostSucceeded(summary) {
4547
4946
  return summary.taskAdvanced;
4548
4947
  }
4549
4948
 
4949
+ // src/worker-ops.ts
4950
+ init_run_store();
4951
+ init_exited_salvage();
4952
+
4550
4953
  // src/harness-expert-review.ts
4551
4954
  var EXPERT_LANE_REVIEW_REF = "expert-lane-pr-review:";
4552
4955
  var PLAN_REVIEW_EXECUTOR_REF = "plan-review-task";
@@ -4714,6 +5117,7 @@ function normalizeOwnerRepo(value) {
4714
5117
  }
4715
5118
 
4716
5119
  // src/pr-handoff/pr-handoff-gh.ts
5120
+ init_git();
4717
5121
  function capture(bin, cwd, args) {
4718
5122
  try {
4719
5123
  const res = spawnSync3(bin, args, { cwd, encoding: "utf8" });
@@ -5084,6 +5488,10 @@ function ensurePrReadyHandoff(input, exec = defaultPrHandoffExec) {
5084
5488
  };
5085
5489
  }
5086
5490
 
5491
+ // src/worker-ops.ts
5492
+ init_status();
5493
+ init_stream();
5494
+
5087
5495
  // src/material-worktree-changes.ts
5088
5496
  function materialWorktreeChanges(changedFiles) {
5089
5497
  return changedFiles.filter((line) => {
@@ -5126,8 +5534,8 @@ function dirtyPathsCoveredByDisposableRemoval(changedFiles, removed) {
5126
5534
  if (removed.length === 0) return false;
5127
5535
  const removedSet = new Set(removed.map((p) => normalizeRelativePath(p)));
5128
5536
  return material.every((line) => {
5129
- const path71 = normalizeRelativePath(pathFromGitStatusLine(line));
5130
- return removedSet.has(path71);
5537
+ const path73 = normalizeRelativePath(pathFromGitStatusLine(line));
5538
+ return removedSet.has(path73);
5131
5539
  });
5132
5540
  }
5133
5541
 
@@ -5212,6 +5620,9 @@ function assessWorktreeCompletionHandoff(input) {
5212
5620
  }
5213
5621
 
5214
5622
  // src/worker-lifecycle.ts
5623
+ init_run_store();
5624
+ init_status();
5625
+ init_util();
5215
5626
  import path17 from "node:path";
5216
5627
  var TASK_LEFT_RUNNING = /* @__PURE__ */ new Set([
5217
5628
  "awaiting_review",
@@ -5303,7 +5714,11 @@ function syncCompletionAcknowledgedFromOperatorTick(runId, operatorTick) {
5303
5714
  return synced;
5304
5715
  }
5305
5716
 
5717
+ // src/worker-ops.ts
5718
+ init_util();
5719
+
5306
5720
  // src/validate.ts
5721
+ init_util();
5307
5722
  import path18 from "node:path";
5308
5723
  var RUN_ID_RE = /^[a-z0-9][a-z0-9._-]{0,127}$/i;
5309
5724
  var WORKER_NAME_RE = /^[a-z0-9][a-z0-9._-]{0,63}$/i;
@@ -6076,6 +6491,7 @@ function stopWorker(args) {
6076
6491
  }
6077
6492
 
6078
6493
  // src/auto-complete.ts
6494
+ init_util();
6079
6495
  var DEFAULT_POLL_MS = 5e3;
6080
6496
  var DEFAULT_MAX_TOTAL_MS = 6 * 60 * 60 * 1e3;
6081
6497
  var DEFAULT_COMPLETE_ATTEMPTS = 3;
@@ -6260,6 +6676,7 @@ function spawnCompletionSidecar(opts) {
6260
6676
  }
6261
6677
 
6262
6678
  // src/repair-target-worktree.ts
6679
+ init_git();
6263
6680
  function addWorktreeForRepairBranch(repo, worktreePath, branch) {
6264
6681
  git(repo, ["fetch", "origin", branch, "--prune"], { allowFailure: true });
6265
6682
  const remoteRef = `origin/${branch}`;
@@ -6273,6 +6690,8 @@ function addWorktreeForRepairBranch(repo, worktreePath, branch) {
6273
6690
  }
6274
6691
 
6275
6692
  // src/supervisor.ts
6693
+ init_box_identity();
6694
+ init_config();
6276
6695
  function spawnWorkerProcess(run, opts) {
6277
6696
  const rawName = typeof opts.name === "string" ? opts.name.trim() : "";
6278
6697
  if (!rawName || rawName === "undefined" || rawName === "null") {
@@ -6366,6 +6785,10 @@ function spawnWorkerProcess(run, opts) {
6366
6785
  else process.env.KYNVER_HARNESS_AGENT_OS_ID = prevHarnessAgentOsId;
6367
6786
  }
6368
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);
6369
6792
  const worker = {
6370
6793
  name,
6371
6794
  runId: run.id,
@@ -6401,6 +6824,9 @@ function spawnWorkerProcess(run, opts) {
6401
6824
  ...opts.taskPrUrl ? { taskPrUrl: String(opts.taskPrUrl) } : {},
6402
6825
  ...opts.repairTargetPrUrl ? { repairTargetPrUrl: String(opts.repairTargetPrUrl) } : {},
6403
6826
  ...opts.repairTargetBranch ? { repairTargetBranch: String(opts.repairTargetBranch) } : {},
6827
+ boxKind: boxIdentity.boxKind,
6828
+ boxId,
6829
+ runtimeId,
6404
6830
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
6405
6831
  };
6406
6832
  saveWorker(run.id, worker);
@@ -6499,6 +6925,9 @@ async function startWorker(args) {
6499
6925
  }
6500
6926
 
6501
6927
  // src/active-harness-workers.ts
6928
+ init_run_store();
6929
+ init_harness_worker_active();
6930
+ init_util();
6502
6931
  import path22 from "node:path";
6503
6932
  function workerWriteSetFields(worker) {
6504
6933
  const ownedPaths = Array.isArray(worker.ownedPaths) ? worker.ownedPaths.filter((p) => typeof p === "string") : [];
@@ -6531,6 +6960,9 @@ function collectRunActiveHarnessWorkers(runId) {
6531
6960
  return out;
6532
6961
  }
6533
6962
 
6963
+ // src/dispatch.ts
6964
+ init_util();
6965
+
6534
6966
  // src/plan-persist/body-hash.ts
6535
6967
  import { createHash as createHash2 } from "node:crypto";
6536
6968
  function hashPlanBody(body) {
@@ -6544,6 +6976,9 @@ function hashSummary(summary) {
6544
6976
  return createHash2("sha256").update(trimmed, "utf8").digest("hex");
6545
6977
  }
6546
6978
 
6979
+ // src/plan-persist/agentos-api.ts
6980
+ init_config();
6981
+
6547
6982
  // src/plan-persist/errors.ts
6548
6983
  var PlanPersistError = class extends Error {
6549
6984
  kind;
@@ -7208,11 +7643,11 @@ function classifyChecks(statusCheckRollup) {
7208
7643
  continue;
7209
7644
  }
7210
7645
  if (state && SUCCESSFUL_CHECK_CONCLUSIONS.has(state)) continue;
7211
- if (state && state !== "PENDING") {
7646
+ if (state && state !== "PENDING" && state !== "EXPECTED") {
7212
7647
  failed.push(`${checkName(check3)}=${state}`);
7213
7648
  continue;
7214
7649
  }
7215
- if (state === "PENDING") {
7650
+ if (state === "PENDING" || state === "EXPECTED") {
7216
7651
  pending.push(`${checkName(check3)}=${state}`);
7217
7652
  continue;
7218
7653
  }
@@ -7239,8 +7674,8 @@ var LOCAL_VERIFICATION_RE = /typecheck|npm run (test|build|typecheck)|vitest|tsc
7239
7674
  var DOCS_TITLE_RE = /^docs[(:]/i;
7240
7675
  var DOCS_BODY_RE = /docs[- ]only|documentation only|no[- ]code change|no code changes|low[- ]risk|plan tracker only|markdown only/i;
7241
7676
  function runtimeVerificationEvidenceSufficient(input) {
7242
- const title = typeof input.title === "string" ? input.title : "";
7243
- const body = typeof input.body === "string" ? input.body : "";
7677
+ const title = typeof input.title === "string" ? input.title.trim() : "";
7678
+ const body = typeof input.body === "string" ? input.body.trim() : "";
7244
7679
  const docsLowRisk = DOCS_TITLE_RE.test(title) || DOCS_BODY_RE.test(body);
7245
7680
  const structuredSection = STRUCTURED_SECTION_RE.test(body);
7246
7681
  const localVerification = LOCAL_VERIFICATION_RE.test(body);
@@ -7392,40 +7827,56 @@ async function executeLandPrMerge(input) {
7392
7827
  "--squash"
7393
7828
  ]);
7394
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
+ }
7395
7839
  return {
7396
7840
  prUrl: before.url || prTarget,
7397
7841
  outcome: "blocked",
7398
7842
  reason: mergeRes.stderr || mergeRes.stdout || "gh pr merge failed"
7399
7843
  };
7400
7844
  }
7401
- const after = ghJson(exec, cwd, [
7402
- "pr",
7403
- "view",
7404
- target,
7405
- ...repoArgs(input.repo),
7406
- "--json",
7407
- "number,url,mergedAt,mergeCommit,state"
7408
- ]);
7409
- if (after.state !== "MERGED" && !after.mergedAt) {
7410
- return {
7411
- prUrl: after.url || before.url || prTarget,
7412
- outcome: "blocked",
7413
- reason: `PR #${after.number} did not verify as merged after gh pr merge`
7414
- };
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 {
7415
7854
  }
7416
- const repo = resolveRepo(exec, cwd, input.repo);
7417
- deleteRemoteBranch(exec, cwd, repo, before.headRefName);
7418
- removeBranchWorktrees(cwd, before.headRefName);
7419
- const mergeCommit = after.mergeCommit?.oid ?? null;
7420
7855
  return {
7421
- prUrl: after.url || before.url || prTarget,
7856
+ prUrl: after?.url || before.url || prTarget,
7422
7857
  outcome: "merged",
7423
- mergeCommit,
7424
- 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)"}`
7425
7860
  };
7426
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
+ }
7427
7877
 
7428
7878
  // src/landing/land-pr-completion-post.ts
7879
+ init_config();
7429
7880
  async function postLandPrHarnessCompletion(input) {
7430
7881
  const secret = await resolveCallbackSecretWithMint(input.secret, input.agentOsId, {
7431
7882
  baseUrl: input.baseUrl
@@ -7710,6 +8161,15 @@ async function dispatchRun(args) {
7710
8161
  async function runLandPrClaimed(decision) {
7711
8162
  const task = decision.task;
7712
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
+ }
7713
8173
  const prUrl = task.prUrl ? String(task.prUrl) : "";
7714
8174
  if (!prUrl) {
7715
8175
  return abortClaimedSpawn(task, "land_pr task missing prUrl");
@@ -7971,8 +8431,15 @@ async function dispatchRun(args) {
7971
8431
  }
7972
8432
  }
7973
8433
 
8434
+ // src/cli.ts
8435
+ init_run_store();
8436
+
7974
8437
  // src/sweep.ts
8438
+ init_config();
7975
8439
  import path26 from "node:path";
8440
+ init_run_store();
8441
+ init_status();
8442
+ init_util();
7976
8443
  async function sweepRun(args) {
7977
8444
  const pipeline = args.pipeline === true || args.pipeline === "true";
7978
8445
  try {
@@ -8033,10 +8500,14 @@ async function sweepRun(args) {
8033
8500
  }
8034
8501
 
8035
8502
  // src/worktree.ts
8503
+ init_git();
8504
+ init_run_store();
8036
8505
  import { existsSync as existsSync25, mkdirSync as mkdirSync6 } from "node:fs";
8037
8506
  import path35 from "node:path";
8038
8507
 
8039
8508
  // src/run-list.ts
8509
+ init_run_store();
8510
+ init_run_worker_index();
8040
8511
  import { existsSync as existsSync24, readFileSync as readFileSync11 } from "node:fs";
8041
8512
  import path34 from "node:path";
8042
8513
 
@@ -8044,6 +8515,10 @@ import path34 from "node:path";
8044
8515
  import path33 from "node:path";
8045
8516
 
8046
8517
  // src/finalize.ts
8518
+ init_run_store();
8519
+ init_run_worker_index();
8520
+ init_status();
8521
+ init_util();
8047
8522
  import path27 from "node:path";
8048
8523
  var ACTIVE_RUN_STATUSES = /* @__PURE__ */ new Set([
8049
8524
  "running",
@@ -8101,11 +8576,21 @@ function finalizeStaleRuns() {
8101
8576
  return finalized;
8102
8577
  }
8103
8578
 
8579
+ // src/stale-reconcile.ts
8580
+ init_run_store();
8581
+ init_run_worker_index();
8582
+ init_status();
8583
+ init_util();
8584
+
8104
8585
  // src/worker-metadata-reconcile.ts
8586
+ init_heartbeat();
8587
+ init_stream();
8105
8588
  import { existsSync as existsSync23, lstatSync, readdirSync as readdirSync7, readlinkSync, renameSync as renameSync2, rmSync } from "node:fs";
8106
8589
  import path31 from "node:path";
8107
8590
 
8108
8591
  // src/worker-metadata-paths.ts
8592
+ init_paths();
8593
+ init_util();
8109
8594
  import path28 from "node:path";
8110
8595
  var NESTED_RUNS = `${path28.sep}runs${path28.sep}runs${path28.sep}`;
8111
8596
  function hasNestedRunsSegment(filePath) {
@@ -8153,6 +8638,9 @@ import { existsSync as existsSync22, readdirSync as readdirSync6, statSync as st
8153
8638
  import path30 from "node:path";
8154
8639
 
8155
8640
  // src/default-repo.ts
8641
+ init_config();
8642
+ init_default_repo_discovery();
8643
+ init_path_values();
8156
8644
  import path29 from "node:path";
8157
8645
  function expandConfiguredRepo(value) {
8158
8646
  return path29.resolve(resolveUserPath(value.trim()));
@@ -8203,6 +8691,10 @@ function formatResolvedDefaultRepo(resolved) {
8203
8691
  }
8204
8692
 
8205
8693
  // src/run-metadata-retention.ts
8694
+ init_heartbeat();
8695
+ init_paths();
8696
+ init_run_store();
8697
+ init_util();
8206
8698
  var RUN_METADATA_ACTIVE_SIGNAL_MS = 15 * 60 * 1e3;
8207
8699
  function isHarnessRunMetadataPath(targetPath, harnessRoot) {
8208
8700
  const resolved = path30.resolve(targetPath);
@@ -8343,6 +8835,8 @@ function collectFilesystemLiveRunKeys(harnessRoot, now = Date.now()) {
8343
8835
  }
8344
8836
 
8345
8837
  // src/worker-metadata-reconcile.ts
8838
+ init_run_store();
8839
+ init_util();
8346
8840
  function materializeSymlinkedRunDir(harnessRoot, runId) {
8347
8841
  const canonical = canonicalRunDir(harnessRoot, runId);
8348
8842
  let stat;
@@ -8625,6 +9119,12 @@ function reconcileWorkerMetadata() {
8625
9119
  }
8626
9120
 
8627
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();
8628
9128
  import { execFileSync } from "node:child_process";
8629
9129
  import path32 from "node:path";
8630
9130
  function normalizePrUrl3(url) {
@@ -8951,6 +9451,8 @@ function reconcileRunsCli() {
8951
9451
  }
8952
9452
 
8953
9453
  // src/run-list.ts
9454
+ init_status();
9455
+ init_util();
8954
9456
  function heartbeatByteLength(heartbeatPath) {
8955
9457
  if (!heartbeatPath || !existsSync24(heartbeatPath)) return 0;
8956
9458
  try {
@@ -9066,6 +9568,7 @@ function listRunsCli() {
9066
9568
  }
9067
9569
 
9068
9570
  // src/worktree.ts
9571
+ init_util();
9069
9572
  function resolveCreateRunRepo(args) {
9070
9573
  const explicit = typeof args.repo === "string" ? args.repo.trim() : "";
9071
9574
  if (explicit) return explicit;
@@ -9105,6 +9608,8 @@ function failExists(message) {
9105
9608
  }
9106
9609
 
9107
9610
  // src/discard-disposable.ts
9611
+ init_run_store();
9612
+ init_status();
9108
9613
  import { existsSync as existsSync26, rmSync as rmSync2 } from "node:fs";
9109
9614
  import path36 from "node:path";
9110
9615
  function normalizeRelativePath2(value) {
@@ -9158,8 +9663,14 @@ function discardDisposableCli(args) {
9158
9663
  if (!result.ok) process.exit(1);
9159
9664
  }
9160
9665
 
9666
+ // src/daemon.ts
9667
+ init_config();
9668
+
9161
9669
  // src/daemon-box-identity.ts
9162
- import os7 from "node:os";
9670
+ init_config();
9671
+ init_box_identity();
9672
+ init_worker_cap_source();
9673
+ import os9 from "node:os";
9163
9674
  function emitDaemonIdentityMessage(level, message) {
9164
9675
  console.error(JSON.stringify({ event: "daemon_identity", level, message }));
9165
9676
  }
@@ -9167,7 +9678,7 @@ function validateDaemonInstallIdentity(config = loadUserConfig(), env = process.
9167
9678
  const box = resolveBoxIdentity(env, config);
9168
9679
  const cap = resolveWorkerCap({
9169
9680
  config,
9170
- totalMemBytes: os7.totalmem(),
9681
+ totalMemBytes: os9.totalmem(),
9171
9682
  env
9172
9683
  });
9173
9684
  const warnings = [...box.warnings];
@@ -9197,6 +9708,47 @@ function validateDaemonInstallIdentity(config = loadUserConfig(), env = process.
9197
9708
  };
9198
9709
  }
9199
9710
 
9711
+ // src/daemon-heartbeat.ts
9712
+ import { mkdirSync as mkdirSync7, readFileSync as readFileSync12, renameSync as renameSync3, writeFileSync as writeFileSync4 } from "node:fs";
9713
+ import { homedir as homedir11 } from "node:os";
9714
+ import path37 from "node:path";
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
+
9200
9752
  // src/daemon-platform-guard.ts
9201
9753
  function envFlag(name) {
9202
9754
  const raw = process.env[name]?.trim().toLowerCase();
@@ -9216,9 +9768,10 @@ function assertNativeDaemonAllowed() {
9216
9768
  }
9217
9769
 
9218
9770
  // src/cron/cron-env.ts
9771
+ init_config();
9219
9772
  import { existsSync as existsSync27 } from "node:fs";
9220
- import { homedir as homedir11 } from "node:os";
9221
- import path37 from "node:path";
9773
+ import { homedir as homedir12 } from "node:os";
9774
+ import path38 from "node:path";
9222
9775
  function envFlag2(name, defaultValue) {
9223
9776
  const raw = process.env[name]?.trim().toLowerCase();
9224
9777
  if (!raw) return defaultValue;
@@ -9234,7 +9787,7 @@ function envInt(name, fallback, min = 1) {
9234
9787
  function defaultKynverCronStorePath() {
9235
9788
  const explicit = process.env.KYNVER_CRON_STORE_PATH?.trim() || process.env.OPENCLAW_CRON_STORE_PATH?.trim();
9236
9789
  if (explicit) return explicit;
9237
- return path37.join(homedir11(), ".kynver", "agent-os-cron.json");
9790
+ return path38.join(homedir12(), ".kynver", "agent-os-cron.json");
9238
9791
  }
9239
9792
  function defaultKynverCronStatePath(storePath = defaultKynverCronStorePath()) {
9240
9793
  const explicit = process.env.KYNVER_CRON_TICK_STATE_PATH?.trim();
@@ -9307,12 +9860,13 @@ async function fireKynverCronJob(input) {
9307
9860
  }
9308
9861
 
9309
9862
  // src/cron/cron-lock.ts
9310
- 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";
9311
9865
  var STALE_LOCK_MS = 10 * 6e4;
9312
9866
  function readLockInfo(lockPath) {
9313
9867
  if (!existsSync28(lockPath)) return null;
9314
9868
  try {
9315
- const parsed = JSON.parse(readFileSync12(lockPath, "utf8"));
9869
+ const parsed = JSON.parse(readFileSync13(lockPath, "utf8"));
9316
9870
  if (typeof parsed.pid === "number" && typeof parsed.at === "string") return parsed;
9317
9871
  } catch {
9318
9872
  return null;
@@ -9343,7 +9897,7 @@ function tryAcquireCronTickLock(lockPath) {
9343
9897
  }
9344
9898
  try {
9345
9899
  const fd = openSync6(lockPath, "wx");
9346
- writeFileSync4(
9900
+ writeFileSync5(
9347
9901
  fd,
9348
9902
  JSON.stringify({ pid: process.pid, at: (/* @__PURE__ */ new Date()).toISOString() }),
9349
9903
  "utf8"
@@ -9476,7 +10030,7 @@ async function loadCronJobs(storePath = defaultKynverCronStorePath()) {
9476
10030
  // src/cron/cron-tick-state.ts
9477
10031
  import { randomBytes } from "node:crypto";
9478
10032
  import { promises as fs2 } from "node:fs";
9479
- import path38 from "node:path";
10033
+ import path39 from "node:path";
9480
10034
  var EMPTY = { version: 1, jobs: {} };
9481
10035
  async function readFileIfExists2(filePath) {
9482
10036
  try {
@@ -9503,7 +10057,7 @@ async function loadCronTickState(statePath) {
9503
10057
  return parseCronTickState(raw);
9504
10058
  }
9505
10059
  async function writeStateAtomic(statePath, state) {
9506
- await fs2.mkdir(path38.dirname(statePath), { recursive: true });
10060
+ await fs2.mkdir(path39.dirname(statePath), { recursive: true });
9507
10061
  const suffix = randomBytes(6).toString("hex");
9508
10062
  const tmp = `${statePath}.tmp-${process.pid}-${Date.now()}-${suffix}`;
9509
10063
  await fs2.writeFile(tmp, `${JSON.stringify(state, null, 2)}
@@ -9679,8 +10233,12 @@ async function runKynverCronTick(opts = {}) {
9679
10233
  }
9680
10234
  }
9681
10235
 
10236
+ // src/daemon.ts
10237
+ init_util();
10238
+
9682
10239
  // src/pipeline-tick.ts
9683
- import path56 from "node:path";
10240
+ import path58 from "node:path";
10241
+ init_config();
9684
10242
 
9685
10243
  // src/pipeline-dispatch.ts
9686
10244
  var RESERVED_REVIEW_STARTS = 1;
@@ -9810,11 +10368,16 @@ function resolvePipelineMaxStarts(resourceGate, operatorTick) {
9810
10368
  };
9811
10369
  }
9812
10370
 
10371
+ // src/pipeline-tick.ts
10372
+ init_resource_gate();
10373
+
9813
10374
  // src/box-resource-snapshot.ts
9814
- import os8 from "node:os";
10375
+ init_config();
10376
+ init_box_identity();
10377
+ import os10 from "node:os";
9815
10378
  function buildBoxResourceSnapshotFromGate(gate, input = {}) {
9816
10379
  const boxKind = (input.boxKind ?? resolveBoxKindFromConfig(loadUserConfig())).trim().toLowerCase() || "forge";
9817
- const hostLabel = input.hostLabel ?? os8.hostname();
10380
+ const hostLabel = input.hostLabel ?? os10.hostname();
9818
10381
  const boxId = input.boxId ?? defaultBoxId(boxKind, hostLabel);
9819
10382
  return {
9820
10383
  boxId,
@@ -9835,10 +10398,20 @@ function buildBoxResourceSnapshotFromGate(gate, input = {}) {
9835
10398
  };
9836
10399
  }
9837
10400
 
10401
+ // src/pipeline-tick.ts
10402
+ init_run_store();
10403
+ init_exited_salvage();
10404
+ init_status();
10405
+ init_util();
10406
+
9838
10407
  // src/plan-progress-daemon-sync.ts
9839
- import path39 from "node:path";
10408
+ init_status();
10409
+ init_run_store();
10410
+ init_util();
10411
+ import path40 from "node:path";
9840
10412
 
9841
10413
  // src/plan-progress-sync.ts
10414
+ init_config();
9842
10415
  async function syncPlanProgress(args) {
9843
10416
  const base = resolveBaseUrl(args.baseUrl);
9844
10417
  const secret = await resolveCallbackSecretWithMint(args.secret, args.agentOsId, { baseUrl: base });
@@ -9860,7 +10433,7 @@ async function syncActiveWorkerPlanProgress(runId, args) {
9860
10433
  const outcomes = [];
9861
10434
  for (const name of Object.keys(run.workers || {})) {
9862
10435
  const worker = readJson(
9863
- path39.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
10436
+ path40.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
9864
10437
  void 0
9865
10438
  );
9866
10439
  if (!worker?.dispatched || !worker.taskId) continue;
@@ -9888,6 +10461,8 @@ async function syncActiveWorkerPlanProgress(runId, args) {
9888
10461
  }
9889
10462
 
9890
10463
  // src/workspace-runtime-config.ts
10464
+ init_config();
10465
+ init_box_identity();
9891
10466
  function shouldApplyWorkspaceRuntimePreferences(env = process.env) {
9892
10467
  const config = loadUserConfig();
9893
10468
  return resolveBoxKindFromConfig(config, env) !== "forge";
@@ -9916,11 +10491,21 @@ async function fetchWorkspaceRuntimePreferences(agentOsId, args) {
9916
10491
  }
9917
10492
  }
9918
10493
 
10494
+ // src/pipeline-tick.ts
10495
+ init_config();
10496
+ init_box_identity();
10497
+
9919
10498
  // src/cleanup.ts
9920
- import path53 from "node:path";
10499
+ init_paths();
10500
+ import path54 from "node:path";
9921
10501
 
9922
10502
  // src/cleanup-guards.ts
9923
- 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();
9924
10509
 
9925
10510
  // src/cleanup-build-cache-paths.ts
9926
10511
  var HARNESS_BUILD_CACHE_RELATIVE_PATHS = [
@@ -9976,6 +10561,7 @@ function isPrOrUnmergedWork(status) {
9976
10561
  }
9977
10562
 
9978
10563
  // src/cleanup-index-status.ts
10564
+ init_util();
9979
10565
  function indexedWorktreeStatus(entry) {
9980
10566
  if (!entry.status) {
9981
10567
  entry.status = computeWorkerStatus(entry.worker, {
@@ -10052,7 +10638,15 @@ function resolveWorktreeGuardStatus(entry, ctx) {
10052
10638
  return indexedWorktreeStatus(entry);
10053
10639
  }
10054
10640
 
10641
+ // src/cleanup-guards.ts
10642
+ init_status();
10643
+
10644
+ // src/cleanup-run-liveness.ts
10645
+ init_status();
10646
+
10055
10647
  // src/cleanup-completion-blocker.ts
10648
+ init_landing_gate();
10649
+ init_status();
10056
10650
  function completionBlockerBlocksWorktreeRemoval(indexed, status) {
10057
10651
  const blocker = typeof indexed.worker.completionBlocker === "string" ? indexed.worker.completionBlocker.trim() : "";
10058
10652
  if (!blocker) return false;
@@ -10072,6 +10666,7 @@ function completionBlockerBlocksWorktreeRemoval(indexed, status) {
10072
10666
  }
10073
10667
 
10074
10668
  // src/cleanup-run-liveness.ts
10669
+ init_util();
10075
10670
  var TERMINAL_WORKER_JSON_STATUSES = /* @__PURE__ */ new Set([
10076
10671
  "done",
10077
10672
  "exited",
@@ -10173,7 +10768,7 @@ function skipWorktreeRemoval(input) {
10173
10768
  function skipDependencyCacheRemoval(input) {
10174
10769
  const { indexed, nodeModulesAgeMs, ageMs, worktreePath, activeWorktreePaths, diskPressure } = input;
10175
10770
  if (!diskPressure && ageMs < nodeModulesAgeMs) return "below_age_threshold";
10176
- if (activeWorktreePaths.has(path40.resolve(worktreePath))) return "active_worker";
10771
+ if (activeWorktreePaths.has(path41.resolve(worktreePath))) return "active_worker";
10177
10772
  if (indexed && isWorkerProcessLive(indexed)) return "active_worker";
10178
10773
  if (indexed && indexedWorktreeHasMaterialChanges(indexed, input.gitStatusCache)) {
10179
10774
  return "dirty_worktree";
@@ -10202,11 +10797,11 @@ var LIVE_SKIP_REASONS = /* @__PURE__ */ new Set([
10202
10797
  function collectPreservedLivePaths(actions, skips) {
10203
10798
  const out = [];
10204
10799
  const seen = /* @__PURE__ */ new Set();
10205
- const push = (path71, reason, detail) => {
10206
- const key = `${path71}\0${reason}`;
10800
+ const push = (path73, reason, detail) => {
10801
+ const key = `${path73}\0${reason}`;
10207
10802
  if (seen.has(key) || out.length >= MAX_PRESERVED_LIVE_PATH_SAMPLES) return;
10208
10803
  seen.add(key);
10209
- out.push({ path: path71, reason, ...detail ? { detail } : {} });
10804
+ out.push({ path: path73, reason, ...detail ? { detail } : {} });
10210
10805
  };
10211
10806
  for (const skip2 of skips) {
10212
10807
  if (!LIVE_SKIP_REASONS.has(skip2.reason)) continue;
@@ -10222,11 +10817,14 @@ function collectPreservedLivePaths(actions, skips) {
10222
10817
 
10223
10818
  // src/cleanup-run-directory.ts
10224
10819
  import { existsSync as existsSync30, readdirSync as readdirSync9, statSync as statSync7 } from "node:fs";
10225
- import path42 from "node:path";
10820
+ import path43 from "node:path";
10226
10821
 
10227
10822
  // src/cleanup-active-worktrees.ts
10823
+ init_run_store();
10824
+ init_paths();
10228
10825
  import { existsSync as existsSync29, readdirSync as readdirSync8, statSync as statSync6 } from "node:fs";
10229
- import path41 from "node:path";
10826
+ import path42 from "node:path";
10827
+ init_util();
10230
10828
  function workerHasRecentHarnessActivity(worker, now) {
10231
10829
  const paths = [worker.heartbeatPath, worker.stdoutPath, worker.stderrPath];
10232
10830
  for (const target of paths) {
@@ -10252,11 +10850,11 @@ function collectActiveWorktreeGuards(harnessRoots, now = Date.now()) {
10252
10850
  let runHasLive = false;
10253
10851
  for (const name of Object.keys(run.workers || {})) {
10254
10852
  const worker = readJson(
10255
- path41.join(runDirectoryAt(harnessRoot, run.id), "workers", safeSlug(name), "worker.json"),
10853
+ path42.join(runDirectoryAt(harnessRoot, run.id), "workers", safeSlug(name), "worker.json"),
10256
10854
  void 0
10257
10855
  );
10258
10856
  if (!worker?.worktreePath) continue;
10259
- const worktreePath = path41.resolve(worker.worktreePath);
10857
+ const worktreePath = path42.resolve(worker.worktreePath);
10260
10858
  if (!isActiveHarnessWorker2(worker, now)) continue;
10261
10859
  runHasLive = true;
10262
10860
  activeWorktreePaths.add(worktreePath);
@@ -10275,6 +10873,7 @@ function isWorktreeOnLiveRun(worktreePath, harnessRoot, runId, liveRunKeys) {
10275
10873
  }
10276
10874
 
10277
10875
  // src/cleanup-run-directory.ts
10876
+ init_util();
10278
10877
  function pathAgeMs(target, now) {
10279
10878
  try {
10280
10879
  const mtime = statSync7(target).mtimeMs;
@@ -10284,7 +10883,7 @@ function pathAgeMs(target, now) {
10284
10883
  }
10285
10884
  }
10286
10885
  function loadRunStatus(harnessRoot, runId) {
10287
- const runPath = path42.join(harnessRoot, "runs", runId, "run.json");
10886
+ const runPath = path43.join(harnessRoot, "runs", runId, "run.json");
10288
10887
  if (!existsSync30(runPath)) return null;
10289
10888
  return readJson(runPath, null);
10290
10889
  }
@@ -10322,7 +10921,7 @@ function scanStaleRunDirectoryCandidates(opts) {
10322
10921
  if (!runEntry.isDirectory()) continue;
10323
10922
  const runId = runEntry.name;
10324
10923
  if (opts.runIdFilter && runId !== opts.runIdFilter) continue;
10325
- const runPath = path42.join(opts.worktreesDir, runId);
10924
+ const runPath = path43.join(opts.worktreesDir, runId);
10326
10925
  if (!runDirectoryIsEmpty(runPath)) continue;
10327
10926
  candidates.push({
10328
10927
  kind: "remove_run_directory",
@@ -10337,12 +10936,13 @@ function scanStaleRunDirectoryCandidates(opts) {
10337
10936
  }
10338
10937
 
10339
10938
  // src/cleanup-execute.ts
10939
+ init_git();
10340
10940
  import { existsSync as existsSync33, rmSync as rmSync4 } from "node:fs";
10341
10941
 
10342
10942
  // src/cleanup-dir-size.ts
10343
10943
  import { execFileSync as execFileSync2 } from "node:child_process";
10344
10944
  import { existsSync as existsSync31, readdirSync as readdirSync10, statSync as statSync8 } from "node:fs";
10345
- import path43 from "node:path";
10945
+ import path44 from "node:path";
10346
10946
  var DEFAULT_DU_TIMEOUT_MS = 2500;
10347
10947
  function directorySizeBytesDu(root, timeoutMs = DEFAULT_DU_TIMEOUT_MS) {
10348
10948
  if (!existsSync31(root)) return 0;
@@ -10376,7 +10976,7 @@ function directorySizeBytes(root, maxEntries = 5e4) {
10376
10976
  }
10377
10977
  for (const name of entries) {
10378
10978
  if (seen++ > maxEntries) return null;
10379
- const full = path43.join(current, name);
10979
+ const full = path44.join(current, name);
10380
10980
  let st;
10381
10981
  try {
10382
10982
  st = statSync8(full);
@@ -10392,6 +10992,7 @@ function directorySizeBytes(root, maxEntries = 5e4) {
10392
10992
 
10393
10993
  // src/cleanup-remove-path.ts
10394
10994
  import { existsSync as existsSync32, rmSync as rmSync3 } from "node:fs";
10995
+ init_paths();
10395
10996
 
10396
10997
  // src/cleanup-path-ownership.ts
10397
10998
  import { lstatSync as lstatSync2, readdirSync as readdirSync11 } from "node:fs";
@@ -10427,20 +11028,20 @@ function pathHasForeignOwnedEntry(targetPath, maxEntries = 32) {
10427
11028
 
10428
11029
  // src/cleanup-privileged-remove.ts
10429
11030
  import { spawnSync as spawnSync6 } from "node:child_process";
10430
- import path45 from "node:path";
11031
+ import path46 from "node:path";
10431
11032
 
10432
11033
  // src/cleanup-harness-path-validate.ts
10433
- import path44 from "node:path";
11034
+ import path45 from "node:path";
10434
11035
  function isHarnessDependencyCachePath(targetPath, harnessRoot, worktreesDir, cacheDirName) {
10435
- const resolved = path44.resolve(targetPath);
10436
- const suffix = `${path44.sep}${cacheDirName}`;
11036
+ const resolved = path45.resolve(targetPath);
11037
+ const suffix = `${path45.sep}${cacheDirName}`;
10437
11038
  const cachePath = resolved.endsWith(suffix) ? resolved : null;
10438
11039
  if (!cachePath) return "path_outside_harness";
10439
- const rel = path44.relative(worktreesDir, cachePath);
10440
- if (rel.startsWith("..") || path44.isAbsolute(rel)) return "path_outside_harness";
10441
- 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);
10442
11043
  if (parts.length < 3 || parts[parts.length - 1] !== cacheDirName) return "path_outside_harness";
10443
- if (!resolved.startsWith(path44.resolve(harnessRoot))) return "path_outside_harness";
11044
+ if (!resolved.startsWith(path45.resolve(harnessRoot))) return "path_outside_harness";
10444
11045
  return null;
10445
11046
  }
10446
11047
  function isHarnessNodeModulesPath(targetPath, harnessRoot, worktreesDir) {
@@ -10450,16 +11051,16 @@ function isHarnessNextCachePath(targetPath, harnessRoot, worktreesDir) {
10450
11051
  return isHarnessDependencyCachePath(targetPath, harnessRoot, worktreesDir, ".next");
10451
11052
  }
10452
11053
  function isHarnessBuildCachePath(targetPath, harnessRoot, worktreesDir) {
10453
- const resolved = path44.resolve(targetPath);
10454
- const relToWt = path44.relative(worktreesDir, resolved);
10455
- if (relToWt.startsWith("..") || path44.isAbsolute(relToWt)) return "path_outside_harness";
10456
- 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);
10457
11058
  if (parts.length < 3) return "path_outside_harness";
10458
- if (!resolved.startsWith(path44.resolve(harnessRoot))) return "path_outside_harness";
11059
+ if (!resolved.startsWith(path45.resolve(harnessRoot))) return "path_outside_harness";
10459
11060
  return null;
10460
11061
  }
10461
11062
  function isHarnessGeneratedCachePath(targetPath, harnessRoot, worktreesDir) {
10462
- const resolved = path44.resolve(targetPath);
11063
+ const resolved = path45.resolve(targetPath);
10463
11064
  return isHarnessNodeModulesPath(resolved, harnessRoot, worktreesDir) === null || isHarnessNextCachePath(resolved, harnessRoot, worktreesDir) === null || isHarnessBuildCachePath(resolved, harnessRoot, worktreesDir) === null;
10464
11065
  }
10465
11066
 
@@ -10493,12 +11094,12 @@ function tryPrivilegedReclaimHarnessCache(targetPath, harnessRoot, worktreesDir)
10493
11094
  "chown",
10494
11095
  "-R",
10495
11096
  `${effectiveUid}:${effectiveGid}`,
10496
- path45.resolve(targetPath)
11097
+ path46.resolve(targetPath)
10497
11098
  ]);
10498
11099
  if (chown.ok) {
10499
11100
  return { ok: true, method: "chown_then_rm" };
10500
11101
  }
10501
- const rm = runSudoNonInteractive(["rm", "-rf", path45.resolve(targetPath)]);
11102
+ const rm = runSudoNonInteractive(["rm", "-rf", path46.resolve(targetPath)]);
10502
11103
  if (rm.ok) {
10503
11104
  return { ok: true, method: "sudo_rm" };
10504
11105
  }
@@ -10700,7 +11301,7 @@ function removeWorktree(candidate, execute) {
10700
11301
 
10701
11302
  // src/cleanup-scan.ts
10702
11303
  import { existsSync as existsSync34, readdirSync as readdirSync12, statSync as statSync9 } from "node:fs";
10703
- import path46 from "node:path";
11304
+ import path47 from "node:path";
10704
11305
  function pathAgeMs2(target, now) {
10705
11306
  try {
10706
11307
  const mtime = statSync9(target).mtimeMs;
@@ -10710,16 +11311,16 @@ function pathAgeMs2(target, now) {
10710
11311
  }
10711
11312
  }
10712
11313
  function isPathInside(child, parent) {
10713
- const rel = path46.relative(parent, child);
10714
- return rel === "" || !rel.startsWith("..") && !path46.isAbsolute(rel);
11314
+ const rel = path47.relative(parent, child);
11315
+ return rel === "" || !rel.startsWith("..") && !path47.isAbsolute(rel);
10715
11316
  }
10716
11317
  function collectBuildCacheForWorktree(worktreePath, opts, seen, meta) {
10717
11318
  const out = [];
10718
11319
  for (const rel of HARNESS_BUILD_CACHE_RELATIVE_PATHS) {
10719
11320
  if (rel === ".next") continue;
10720
- const target = path46.join(worktreePath, rel);
11321
+ const target = path47.join(worktreePath, rel);
10721
11322
  if (!existsSync34(target)) continue;
10722
- const resolved = path46.resolve(target);
11323
+ const resolved = path47.resolve(target);
10723
11324
  if (seen.has(resolved)) continue;
10724
11325
  if (!isPathInside(resolved, opts.harnessRoot)) continue;
10725
11326
  seen.add(resolved);
@@ -10751,10 +11352,10 @@ function scanBuildCacheCandidates(opts) {
10751
11352
  if (!opts.includeOrphans || !existsSync34(opts.worktreesDir)) return candidates;
10752
11353
  for (const runEntry of readdirSync12(opts.worktreesDir, { withFileTypes: true })) {
10753
11354
  if (!runEntry.isDirectory()) continue;
10754
- const runPath = path46.join(opts.worktreesDir, runEntry.name);
11355
+ const runPath = path47.join(opts.worktreesDir, runEntry.name);
10755
11356
  for (const workerEntry of readdirSync12(runPath, { withFileTypes: true })) {
10756
11357
  if (!workerEntry.isDirectory()) continue;
10757
- const worktreePath = path46.join(runPath, workerEntry.name);
11358
+ const worktreePath = path47.join(runPath, workerEntry.name);
10758
11359
  candidates.push(
10759
11360
  ...collectBuildCacheForWorktree(worktreePath, opts, seen, {
10760
11361
  runId: runEntry.name,
@@ -10792,12 +11393,12 @@ function scanWorktreeCandidates(opts) {
10792
11393
  if (!orphanEnabled || !existsSync34(opts.worktreesDir)) return candidates;
10793
11394
  const indexedPaths = /* @__PURE__ */ new Set();
10794
11395
  for (const entry of opts.index.values()) {
10795
- indexedPaths.add(path46.resolve(entry.worktreePath));
11396
+ indexedPaths.add(path47.resolve(entry.worktreePath));
10796
11397
  }
10797
11398
  for (const runEntry of readdirSync12(opts.worktreesDir, { withFileTypes: true })) {
10798
11399
  if (!runEntry.isDirectory()) continue;
10799
11400
  if (opts.runIdFilter && runEntry.name !== opts.runIdFilter) continue;
10800
- const runPath = path46.join(opts.worktreesDir, runEntry.name);
11401
+ const runPath = path47.join(opts.worktreesDir, runEntry.name);
10801
11402
  let workerEntries;
10802
11403
  try {
10803
11404
  workerEntries = readdirSync12(runPath, { withFileTypes: true });
@@ -10806,7 +11407,7 @@ function scanWorktreeCandidates(opts) {
10806
11407
  }
10807
11408
  for (const workerEntry of workerEntries) {
10808
11409
  if (!workerEntry.isDirectory()) continue;
10809
- const worktreePath = path46.resolve(path46.join(runPath, workerEntry.name));
11410
+ const worktreePath = path47.resolve(path47.join(runPath, workerEntry.name));
10810
11411
  if (seen.has(worktreePath)) continue;
10811
11412
  if (indexedPaths.has(worktreePath)) continue;
10812
11413
  if (!isPathInside(worktreePath, opts.harnessRoot)) continue;
@@ -10826,7 +11427,7 @@ function scanWorktreeCandidates(opts) {
10826
11427
 
10827
11428
  // src/cleanup-dependency-scan.ts
10828
11429
  import { existsSync as existsSync35, readdirSync as readdirSync13, statSync as statSync10 } from "node:fs";
10829
- import path47 from "node:path";
11430
+ import path48 from "node:path";
10830
11431
  var DEPENDENCY_CACHE_DIRS = [
10831
11432
  { dirName: "node_modules", kind: "remove_node_modules" },
10832
11433
  { dirName: ".next", kind: "remove_next_cache" }
@@ -10840,12 +11441,12 @@ function pathAgeMs3(target, now) {
10840
11441
  }
10841
11442
  }
10842
11443
  function isPathInside2(child, parent) {
10843
- const rel = path47.relative(parent, child);
10844
- return rel === "" || !rel.startsWith("..") && !path47.isAbsolute(rel);
11444
+ const rel = path48.relative(parent, child);
11445
+ return rel === "" || !rel.startsWith("..") && !path48.isAbsolute(rel);
10845
11446
  }
10846
11447
  function pushCandidate2(candidates, seen, opts, targetPath, kind, meta) {
10847
11448
  if (!existsSync35(targetPath)) return;
10848
- const resolved = path47.resolve(targetPath);
11449
+ const resolved = path48.resolve(targetPath);
10849
11450
  if (seen.has(resolved)) return;
10850
11451
  if (!isPathInside2(resolved, opts.harnessRoot)) return;
10851
11452
  seen.add(resolved);
@@ -10862,7 +11463,7 @@ function pushCandidate2(candidates, seen, opts, targetPath, kind, meta) {
10862
11463
  }
10863
11464
  function scanWorktreeDependencyCaches(candidates, seen, opts, worktreePath, meta) {
10864
11465
  for (const entry of DEPENDENCY_CACHE_DIRS) {
10865
- 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);
10866
11467
  }
10867
11468
  }
10868
11469
  function scanDependencyCacheCandidates(opts) {
@@ -10880,7 +11481,7 @@ function scanDependencyCacheCandidates(opts) {
10880
11481
  for (const runEntry of readdirSync13(opts.worktreesDir, { withFileTypes: true })) {
10881
11482
  if (!runEntry.isDirectory()) continue;
10882
11483
  if (opts.runIdFilter && runEntry.name !== opts.runIdFilter) continue;
10883
- const runPath = path47.join(opts.worktreesDir, runEntry.name);
11484
+ const runPath = path48.join(opts.worktreesDir, runEntry.name);
10884
11485
  let workerEntries;
10885
11486
  try {
10886
11487
  workerEntries = readdirSync13(runPath, { withFileTypes: true });
@@ -10889,7 +11490,7 @@ function scanDependencyCacheCandidates(opts) {
10889
11490
  }
10890
11491
  for (const workerEntry of workerEntries) {
10891
11492
  if (!workerEntry.isDirectory()) continue;
10892
- const worktreePath = path47.join(runPath, workerEntry.name);
11493
+ const worktreePath = path48.join(runPath, workerEntry.name);
10893
11494
  scanWorktreeDependencyCaches(candidates, seen, opts, worktreePath, {
10894
11495
  runId: runEntry.name,
10895
11496
  worker: workerEntry.name
@@ -10900,8 +11501,9 @@ function scanDependencyCacheCandidates(opts) {
10900
11501
  }
10901
11502
 
10902
11503
  // src/cleanup-duplicate-worktrees.ts
11504
+ init_git();
10903
11505
  import { existsSync as existsSync36, statSync as statSync11 } from "node:fs";
10904
- import path48 from "node:path";
11506
+ import path49 from "node:path";
10905
11507
  function pathAgeMs4(target, now) {
10906
11508
  try {
10907
11509
  const mtime = statSync11(target).mtimeMs;
@@ -10931,8 +11533,8 @@ function parseWorktreePorcelain(output) {
10931
11533
  return records;
10932
11534
  }
10933
11535
  function isUnderWorktreesDir(worktreePath, worktreesDir) {
10934
- const rel = path48.relative(path48.resolve(worktreesDir), path48.resolve(worktreePath));
10935
- 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);
10936
11538
  }
10937
11539
  function isCleanWorktree(worktreePath, repoRoot) {
10938
11540
  try {
@@ -10948,11 +11550,11 @@ function scanDuplicateWorktreeCandidates(opts) {
10948
11550
  if (!opts.includeOrphans || !existsSync36(opts.worktreesDir)) return [];
10949
11551
  const repos = /* @__PURE__ */ new Set();
10950
11552
  for (const entry of opts.index.values()) {
10951
- if (entry.run.repo) repos.add(path48.resolve(entry.run.repo));
11553
+ if (entry.run.repo) repos.add(path49.resolve(entry.run.repo));
10952
11554
  }
10953
11555
  const indexedPaths = /* @__PURE__ */ new Set();
10954
11556
  for (const entry of opts.index.values()) {
10955
- indexedPaths.add(path48.resolve(entry.worktreePath));
11557
+ indexedPaths.add(path49.resolve(entry.worktreePath));
10956
11558
  }
10957
11559
  const candidates = [];
10958
11560
  const seen = /* @__PURE__ */ new Set();
@@ -10965,15 +11567,15 @@ function scanDuplicateWorktreeCandidates(opts) {
10965
11567
  }
10966
11568
  const worktrees = parseWorktreePorcelain(porcelain);
10967
11569
  for (const wt of worktrees) {
10968
- const resolved = path48.resolve(wt.path);
10969
- if (resolved === path48.resolve(repoRoot)) continue;
11570
+ const resolved = path49.resolve(wt.path);
11571
+ if (resolved === path49.resolve(repoRoot)) continue;
10970
11572
  if (!isUnderWorktreesDir(resolved, opts.worktreesDir)) continue;
10971
11573
  if (indexedPaths.has(resolved)) continue;
10972
11574
  if (seen.has(resolved)) continue;
10973
11575
  if (!existsSync36(resolved)) continue;
10974
11576
  if (!isCleanWorktree(resolved, repoRoot)) continue;
10975
- const rel = path48.relative(opts.worktreesDir, resolved);
10976
- const parts = rel.split(path48.sep);
11577
+ const rel = path49.relative(opts.worktreesDir, resolved);
11578
+ const parts = rel.split(path49.sep);
10977
11579
  const runId = parts[0];
10978
11580
  const worker = parts[1] ?? "unknown";
10979
11581
  seen.add(resolved);
@@ -10992,12 +11594,14 @@ function scanDuplicateWorktreeCandidates(opts) {
10992
11594
  }
10993
11595
 
10994
11596
  // src/cleanup-worktree-index.ts
10995
- import path49 from "node:path";
11597
+ init_run_store();
11598
+ init_util();
11599
+ import path50 from "node:path";
10996
11600
  function buildWorktreeIndexAt(harnessRoot) {
10997
11601
  const index = /* @__PURE__ */ new Map();
10998
11602
  for (const run of listRunRecordsForHarnessRoot(harnessRoot)) {
10999
11603
  for (const name of Object.keys(run.workers || {})) {
11000
- const workerPath = path49.join(
11604
+ const workerPath = path50.join(
11001
11605
  runDirectoryAt(harnessRoot, run.id),
11002
11606
  "workers",
11003
11607
  safeSlug(name),
@@ -11005,9 +11609,9 @@ function buildWorktreeIndexAt(harnessRoot) {
11005
11609
  );
11006
11610
  const worker = readJson(workerPath, void 0);
11007
11611
  if (!worker?.worktreePath) continue;
11008
- index.set(path49.resolve(worker.worktreePath), {
11612
+ index.set(path50.resolve(worker.worktreePath), {
11009
11613
  harnessRoot,
11010
- worktreePath: path49.resolve(worker.worktreePath),
11614
+ worktreePath: path50.resolve(worker.worktreePath),
11011
11615
  runId: run.id,
11012
11616
  workerName: name,
11013
11617
  run,
@@ -11076,15 +11680,16 @@ function resolvePipelineHarnessRetention(runId) {
11076
11680
  }
11077
11681
 
11078
11682
  // src/cleanup-orphan-safety.ts
11683
+ init_git();
11079
11684
  import { existsSync as existsSync37, statSync as statSync12 } from "node:fs";
11080
- import path50 from "node:path";
11685
+ import path51 from "node:path";
11081
11686
  var DEFAULT_HEARTBEAT_FRESH_MS = 30 * 60 * 1e3;
11082
11687
  function assessOrphanWorktreeSafety(input) {
11083
11688
  const now = input.now ?? Date.now();
11084
11689
  const heartbeatFreshMs = input.heartbeatFreshMs ?? DEFAULT_HEARTBEAT_FRESH_MS;
11085
11690
  if (!existsSync37(input.worktreePath)) return null;
11086
11691
  if (input.runId && input.workerName) {
11087
- const heartbeatPath = path50.join(
11692
+ const heartbeatPath = path51.join(
11088
11693
  input.harnessRoot,
11089
11694
  "runs",
11090
11695
  input.runId,
@@ -11098,7 +11703,7 @@ function assessOrphanWorktreeSafety(input) {
11098
11703
  } catch {
11099
11704
  }
11100
11705
  }
11101
- const gitDir = path50.join(input.worktreePath, ".git");
11706
+ const gitDir = path51.join(input.worktreePath, ".git");
11102
11707
  if (!existsSync37(gitDir)) return null;
11103
11708
  const porcelain = gitCapture(input.worktreePath, ["status", "--porcelain"]);
11104
11709
  if (porcelain.status !== 0) return "pr_or_unmerged_commits";
@@ -11128,8 +11733,9 @@ function assessOrphanWorktreeSafety(input) {
11128
11733
  }
11129
11734
 
11130
11735
  // src/harness-storage-snapshot.ts
11736
+ init_paths();
11131
11737
  import { existsSync as existsSync38, readdirSync as readdirSync14, statSync as statSync13 } from "node:fs";
11132
- import path51 from "node:path";
11738
+ import path52 from "node:path";
11133
11739
  function harnessStorageSnapshot(opts = {}) {
11134
11740
  const harnessRoot = normalizeHarnessRoot(opts.harnessRoot ?? resolveHarnessRoot());
11135
11741
  const worktreesDir = harnessWorktreesDir(harnessRoot);
@@ -11167,7 +11773,7 @@ function harnessStorageSnapshot(opts = {}) {
11167
11773
  for (const runEntry of entries) {
11168
11774
  if (!runEntry.isDirectory()) continue;
11169
11775
  runCount += 1;
11170
- const runPath = path51.join(worktreesDir, runEntry.name);
11776
+ const runPath = path52.join(worktreesDir, runEntry.name);
11171
11777
  try {
11172
11778
  const st = statSync13(runPath);
11173
11779
  oldestMs = oldestMs === null ? st.mtimeMs : Math.min(oldestMs, st.mtimeMs);
@@ -11202,12 +11808,13 @@ function harnessStorageSnapshot(opts = {}) {
11202
11808
  }
11203
11809
 
11204
11810
  // src/cleanup-harness-roots.ts
11811
+ init_paths();
11205
11812
  import { existsSync as existsSync39 } from "node:fs";
11206
- import { homedir as homedir12 } from "node:os";
11207
- import path52 from "node:path";
11813
+ import { homedir as homedir13 } from "node:os";
11814
+ import path53 from "node:path";
11208
11815
  var WELL_KNOWN_HARNESS_SCAN_ROOTS = [
11209
11816
  "/var/tmp/kynver-harness",
11210
- path52.join(homedir12(), ".openclaw", "harness")
11817
+ path53.join(homedir13(), ".openclaw", "harness")
11211
11818
  ];
11212
11819
  function addRoot(seen, roots, candidate) {
11213
11820
  if (!candidate?.trim()) return;
@@ -11229,7 +11836,7 @@ function resolveHarnessScanRoots(options = {}) {
11229
11836
  for (const candidate of extra ?? []) addRoot(seen, roots, candidate);
11230
11837
  if (shouldScanWellKnownRoots(options)) {
11231
11838
  for (const candidate of WELL_KNOWN_HARNESS_SCAN_ROOTS) {
11232
- const resolved = path52.resolve(candidate);
11839
+ const resolved = path53.resolve(candidate);
11233
11840
  if (!seen.has(resolved) && existsSync39(resolved)) addRoot(seen, roots, resolved);
11234
11841
  }
11235
11842
  }
@@ -11237,6 +11844,7 @@ function resolveHarnessScanRoots(options = {}) {
11237
11844
  }
11238
11845
 
11239
11846
  // src/cleanup-disk-pressure.ts
11847
+ init_disk_gate();
11240
11848
  function envFlag4(name) {
11241
11849
  const v = process.env[name];
11242
11850
  return v === "1" || v === "true" || v === "yes";
@@ -11286,6 +11894,7 @@ function emitCleanupProgress(phase, detail) {
11286
11894
  }
11287
11895
 
11288
11896
  // src/cleanup-git-rev-cache.ts
11897
+ init_git();
11289
11898
  var CleanupGitRevCache = class {
11290
11899
  aheadOfMain = /* @__PURE__ */ new Map();
11291
11900
  countAheadOfMain(worktreePath, base = "origin/main") {
@@ -11304,6 +11913,7 @@ var CleanupGitRevCache = class {
11304
11913
  };
11305
11914
 
11306
11915
  // src/cleanup-git-status-cache.ts
11916
+ init_git();
11307
11917
  var CleanupGitStatusCache = class {
11308
11918
  cache = /* @__PURE__ */ new Map();
11309
11919
  porcelain(worktreePath) {
@@ -11415,9 +12025,9 @@ function mergeWorktreeIndexes(scanRoots) {
11415
12025
  }
11416
12026
  function worktreePathForCandidate(candidate, worktreesDir) {
11417
12027
  if (candidate.runId && candidate.worker) {
11418
- return path53.join(worktreesDir, candidate.runId, candidate.worker);
12028
+ return path54.join(worktreesDir, candidate.runId, candidate.worker);
11419
12029
  }
11420
- return path53.resolve(candidate.path, "..");
12030
+ return path54.resolve(candidate.path, "..");
11421
12031
  }
11422
12032
  function runHarnessCleanup(options = {}) {
11423
12033
  let retention = resolveHarnessRetention(options);
@@ -11446,7 +12056,7 @@ function runHarnessCleanup(options = {}) {
11446
12056
  for (const harnessRoot of paths.scanRoots) {
11447
12057
  if (atSweepCap()) break;
11448
12058
  emitCleanupProgress("root", harnessRoot);
11449
- const worktreesDir = path53.join(harnessRoot, "worktrees");
12059
+ const worktreesDir = path54.join(harnessRoot, "worktrees");
11450
12060
  const scanOpts = {
11451
12061
  harnessRoot,
11452
12062
  worktreesDir,
@@ -11466,7 +12076,7 @@ function runHarnessCleanup(options = {}) {
11466
12076
  if (dependencyProcessed % 50 === 0) {
11467
12077
  emitCleanupProgress("dependency", `${dependencyProcessed}/${dependencyCandidates.length} evaluated`);
11468
12078
  }
11469
- const resolved = path53.resolve(raw.path);
12079
+ const resolved = path54.resolve(raw.path);
11470
12080
  if (processedPaths.has(resolved)) continue;
11471
12081
  processedPaths.add(resolved);
11472
12082
  const candidate = { ...raw, path: resolved };
@@ -11477,7 +12087,7 @@ function runHarnessCleanup(options = {}) {
11477
12087
  continue;
11478
12088
  }
11479
12089
  const worktreePath = worktreePathForCandidate(candidate, worktreesDir);
11480
- const indexed = index.get(path53.resolve(worktreePath)) ?? null;
12090
+ const indexed = index.get(path54.resolve(worktreePath)) ?? null;
11481
12091
  const guardReason = skipDependencyCacheRemoval({
11482
12092
  indexed,
11483
12093
  includeOrphans: true,
@@ -11502,7 +12112,7 @@ function runHarnessCleanup(options = {}) {
11502
12112
  }
11503
12113
  for (const raw of scanBuildCacheCandidates(scanOpts)) {
11504
12114
  if (atSweepCap()) break;
11505
- const resolved = path53.resolve(raw.path);
12115
+ const resolved = path54.resolve(raw.path);
11506
12116
  if (processedPaths.has(resolved)) continue;
11507
12117
  processedPaths.add(resolved);
11508
12118
  const candidate = { ...raw, path: resolved };
@@ -11513,7 +12123,7 @@ function runHarnessCleanup(options = {}) {
11513
12123
  continue;
11514
12124
  }
11515
12125
  const worktreePath = worktreePathForCandidate(candidate, worktreesDir);
11516
- const indexed = index.get(path53.resolve(worktreePath)) ?? null;
12126
+ const indexed = index.get(path54.resolve(worktreePath)) ?? null;
11517
12127
  const guardReason = skipBuildCacheRemoval({
11518
12128
  indexed,
11519
12129
  includeOrphans: true,
@@ -11549,11 +12159,11 @@ function runHarnessCleanup(options = {}) {
11549
12159
  if (worktreeProcessed % 50 === 0) {
11550
12160
  emitCleanupProgress("worktrees", `${worktreeProcessed}/${worktreeCandidates.length} evaluated`);
11551
12161
  }
11552
- const resolved = path53.resolve(raw.path);
12162
+ const resolved = path54.resolve(raw.path);
11553
12163
  if (worktreeSeen.has(resolved)) continue;
11554
12164
  worktreeSeen.add(resolved);
11555
12165
  const candidate = { ...raw, path: resolved };
11556
- const indexed = index.get(path53.resolve(candidate.path)) ?? null;
12166
+ const indexed = index.get(path54.resolve(candidate.path)) ?? null;
11557
12167
  const orphanSafety = indexed ? null : assessOrphanWorktreeSafety({
11558
12168
  worktreePath: candidate.path,
11559
12169
  harnessRoot,
@@ -11563,7 +12173,7 @@ function runHarnessCleanup(options = {}) {
11563
12173
  });
11564
12174
  const guardSkip = skipWorktreeRemoval({
11565
12175
  indexed,
11566
- worktreePath: path53.resolve(candidate.path),
12176
+ worktreePath: path54.resolve(candidate.path),
11567
12177
  includeOrphans: retention.includeOrphans,
11568
12178
  worktreesAgeMs: retention.worktreesAgeMs,
11569
12179
  terminalWorktreesAgeMs: retention.terminalWorktreesAgeMs,
@@ -11595,11 +12205,11 @@ function runHarnessCleanup(options = {}) {
11595
12205
  now: paths.now
11596
12206
  })) {
11597
12207
  if (atSweepCap()) break;
11598
- const resolved = path53.resolve(raw.path);
12208
+ const resolved = path54.resolve(raw.path);
11599
12209
  if (processedPaths.has(resolved)) continue;
11600
12210
  processedPaths.add(resolved);
11601
12211
  const candidate = { ...raw, path: resolved };
11602
- const runId = candidate.runId ?? path53.basename(resolved);
12212
+ const runId = candidate.runId ?? path54.basename(resolved);
11603
12213
  const dirSkip = skipRunDirectoryRemoval({
11604
12214
  harnessRoot,
11605
12215
  runId,
@@ -11734,12 +12344,13 @@ function isPipelineCleanupEnabled() {
11734
12344
 
11735
12345
  // src/installed-package-versions.ts
11736
12346
  import { readFile } from "node:fs/promises";
11737
- import { homedir as homedir13 } from "node:os";
11738
- import path55 from "node:path";
12347
+ import { homedir as homedir14 } from "node:os";
12348
+ import path56 from "node:path";
11739
12349
 
11740
12350
  // src/memory-cost-package-version-guard.ts
11741
- import { existsSync as existsSync40, readFileSync as readFileSync13 } from "node:fs";
11742
- 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";
11743
12354
  var MEMORY_COST_PACKAGE_MIN_VERSIONS = {
11744
12355
  "@kynver-app/runtime": "0.1.83",
11745
12356
  "@kynver-app/openclaw-agent-os": "0.1.43",
@@ -11790,7 +12401,7 @@ function maxSemver(versions) {
11790
12401
  }
11791
12402
  function readPackageJsonVersion(packageJsonPath) {
11792
12403
  try {
11793
- const parsed = JSON.parse(readFileSync13(packageJsonPath, "utf8"));
12404
+ const parsed = JSON.parse(readFileSync14(packageJsonPath, "utf8"));
11794
12405
  return typeof parsed.version === "string" && parsed.version.trim() ? parsed.version.trim() : null;
11795
12406
  } catch {
11796
12407
  return null;
@@ -11801,8 +12412,8 @@ function resolveRepoRoot(cwd, explicitRepoRoot) {
11801
12412
  (value) => Boolean(value?.trim())
11802
12413
  );
11803
12414
  for (const candidate of candidates) {
11804
- const resolved = path54.resolve(candidate);
11805
- 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"))) {
11806
12417
  return resolved;
11807
12418
  }
11808
12419
  }
@@ -11815,7 +12426,7 @@ function probeRepoPackageVersions(input = {}) {
11815
12426
  if (!repoRoot) return {};
11816
12427
  const out = {};
11817
12428
  for (const packageName of MEMORY_COST_MANAGED_PACKAGES) {
11818
- const packageJsonPath = path54.join(repoRoot, REPO_PACKAGE_JSON_RELATIVE[packageName]);
12429
+ const packageJsonPath = path55.join(repoRoot, REPO_PACKAGE_JSON_RELATIVE[packageName]);
11819
12430
  const version = readPackageJsonVersion(packageJsonPath);
11820
12431
  if (!version) continue;
11821
12432
  out[packageName] = { version, source: "repo", path: packageJsonPath };
@@ -11934,13 +12545,13 @@ function unique(values) {
11934
12545
  return [...new Set(values.filter((value) => Boolean(value)))];
11935
12546
  }
11936
12547
  function moduleRoots() {
11937
- const home = homedir13();
11938
- const openClawPrefix = trim(process.env.KYNVER_OPENCLAW_NPM_ROOT) ?? trim(process.env.OPENCLAW_NPM_ROOT) ?? path55.join(home, ".openclaw", "npm");
11939
- 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"));
11940
12551
  return unique([
11941
- path55.join(openClawPrefix, "lib", "node_modules"),
11942
- path55.join(openClawPrefix, "node_modules"),
11943
- 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")
11944
12555
  ]);
11945
12556
  }
11946
12557
  async function readVersion(packageJsonPath) {
@@ -11956,7 +12567,7 @@ function installedPackageJsonCandidates(packageName) {
11956
12567
  const seen = /* @__PURE__ */ new Set();
11957
12568
  const out = [];
11958
12569
  for (const root of roots) {
11959
- const candidate = path55.join(root, packageName, "package.json");
12570
+ const candidate = path56.join(root, packageName, "package.json");
11960
12571
  if (seen.has(candidate)) continue;
11961
12572
  seen.add(candidate);
11962
12573
  out.push(candidate);
@@ -11981,13 +12592,355 @@ async function collectInstalledPackageVersions(observedAt = (/* @__PURE__ */ new
11981
12592
  return out;
11982
12593
  }
11983
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
+
11984
12937
  // src/pipeline-tick.ts
11985
12938
  async function completeFinishedWorkers(runId, args) {
11986
12939
  const run = loadRun(runId);
11987
12940
  const outcomes = [];
11988
12941
  for (const name of Object.keys(run.workers || {})) {
11989
12942
  const worker = readJson(
11990
- path56.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
12943
+ path58.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
11991
12944
  void 0
11992
12945
  );
11993
12946
  if (!worker?.taskId || worker.localOnly) continue;
@@ -12020,6 +12973,13 @@ async function postOperatorTick(agentOsId, runId, resourceGate, args, harnessCle
12020
12973
  const url = `${base}/api/agent-os/by-id/${encodeURIComponent(agentOsId)}/operator/tick`;
12021
12974
  const packageVersions = await collectInstalledPackageVersions();
12022
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
+ }
12023
12983
  const res = await postJson(url, secret, {
12024
12984
  agentOsId,
12025
12985
  runId,
@@ -12034,9 +12994,27 @@ async function postOperatorTick(agentOsId, runId, resourceGate, args, harnessCle
12034
12994
  ...harnessCleanup ? { harnessCleanup } : {},
12035
12995
  runnerPresence: resolveRunnerPresencePayload({ runId }),
12036
12996
  activeHarnessWorkers,
12037
- ...harnessCleanup ? { harnessCleanup } : {}
12997
+ ...evidenceCollection && evidenceCollection.items.length > 0 ? { providerEvidence: evidenceCollection.items } : {}
12038
12998
  });
12039
- 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
+ };
12040
13018
  }
12041
13019
  async function runPipelineTick(args) {
12042
13020
  const runId = String(required(String(args.run || ""), "--run"));
@@ -12184,6 +13162,7 @@ async function runDaemon(args) {
12184
13162
  const cronEnv = resolveKynverCronEnv();
12185
13163
  while (!stopping) {
12186
13164
  try {
13165
+ writeDaemonHeartbeat({ agentOsId, runId });
12187
13166
  if (cronEnv.tickEnabled) {
12188
13167
  const cronTick = await runKynverCronTick({
12189
13168
  env: cronEnv,
@@ -12210,8 +13189,140 @@ async function runDaemon(args) {
12210
13189
  console.error(JSON.stringify({ event: "daemon_stop", runId, agentOsId }));
12211
13190
  }
12212
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
+
12213
13323
  // src/plan-progress.ts
12214
- import path60 from "node:path";
13324
+ init_config();
13325
+ import path62 from "node:path";
12215
13326
 
12216
13327
  // src/bounded-build/constants.ts
12217
13328
  var DEFAULT_BUILD_MEM_BUDGET_BYTES = 1536 * 1024 * 1024;
@@ -12220,6 +13331,9 @@ var DEFAULT_NODE_OLD_SPACE_SIZE_MB = 1024;
12220
13331
  var DEFAULT_SYSTEMD_MEMORY_MAX = "1.5G";
12221
13332
  var DEFAULT_SYSTEMD_MEMORY_SWAP_MAX = "2G";
12222
13333
 
13334
+ // src/bounded-build/index.ts
13335
+ init_meminfo();
13336
+
12223
13337
  // src/bounded-build/node-options.ts
12224
13338
  var MAX_OLD_SPACE_RE = /--max-old-space-size=(\d+)/;
12225
13339
  function parsePositiveInt(value, fallback) {
@@ -12249,7 +13363,7 @@ function formatNodeOptionsFlag(mb = resolveNodeOldSpaceSizeMb()) {
12249
13363
  }
12250
13364
 
12251
13365
  // src/bounded-build/systemd-wrap.ts
12252
- import { spawnSync as spawnSync7 } from "node:child_process";
13366
+ import { spawnSync as spawnSync8 } from "node:child_process";
12253
13367
  var systemdAvailableCache;
12254
13368
  function isSystemdRunAvailable() {
12255
13369
  if (process.env.KYNVER_BUILD_SKIP_SYSTEMD === "1" || process.env.KYNVER_BUILD_SKIP_SYSTEMD === "true") {
@@ -12260,7 +13374,7 @@ function isSystemdRunAvailable() {
12260
13374
  systemdAvailableCache = false;
12261
13375
  return false;
12262
13376
  }
12263
- 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"] });
12264
13378
  systemdAvailableCache = res.status === 0;
12265
13379
  return systemdAvailableCache;
12266
13380
  }
@@ -12284,7 +13398,9 @@ function buildSystemdRunArgv(opts) {
12284
13398
  }
12285
13399
 
12286
13400
  // src/bounded-build/admission.ts
12287
- import { spawnSync as spawnSync8 } from "node:child_process";
13401
+ init_config();
13402
+ import { spawnSync as spawnSync9 } from "node:child_process";
13403
+ init_meminfo();
12288
13404
  function positiveInt4(value, fallback) {
12289
13405
  const n = Number(value);
12290
13406
  if (!Number.isFinite(n) || n <= 0) return fallback;
@@ -12320,7 +13436,7 @@ function assessBuildAdmission(opts = {}) {
12320
13436
  }
12321
13437
  function sleepMs2(ms) {
12322
13438
  if (ms <= 0) return;
12323
- 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);`], {
12324
13440
  stdio: "ignore"
12325
13441
  });
12326
13442
  }
@@ -12341,33 +13457,34 @@ function waitForBuildAdmission(timeoutMs, pollMs = 2e3, opts = {}) {
12341
13457
  }
12342
13458
 
12343
13459
  // src/bounded-build/exec.ts
12344
- import { spawnSync as spawnSync10 } from "node:child_process";
13460
+ import { spawnSync as spawnSync11 } from "node:child_process";
12345
13461
 
12346
13462
  // src/heavy-verification/slot.ts
13463
+ init_util();
12347
13464
  import {
12348
13465
  closeSync as closeSync7,
12349
13466
  existsSync as existsSync41,
12350
- mkdirSync as mkdirSync8,
13467
+ mkdirSync as mkdirSync9,
12351
13468
  openSync as openSync7,
12352
13469
  readdirSync as readdirSync15,
12353
- readFileSync as readFileSync14,
13470
+ readFileSync as readFileSync15,
12354
13471
  unlinkSync as unlinkSync4,
12355
- writeFileSync as writeFileSync5
13472
+ writeFileSync as writeFileSync6
12356
13473
  } from "node:fs";
12357
- import path58 from "node:path";
13474
+ import path60 from "node:path";
12358
13475
 
12359
13476
  // src/heavy-verification/paths.ts
12360
- import { mkdirSync as mkdirSync7 } from "node:fs";
12361
- import path57 from "node:path";
13477
+ import { mkdirSync as mkdirSync8 } from "node:fs";
13478
+ import path59 from "node:path";
12362
13479
  function resolveHeavyVerificationRoot() {
12363
- return path57.join(resolveKynverStateRoot(), "heavy-verification");
13480
+ return path59.join(resolveKynverStateRoot(), "heavy-verification");
12364
13481
  }
12365
13482
  function heavyVerificationSlotsDir() {
12366
- return path57.join(resolveHeavyVerificationRoot(), "slots");
13483
+ return path59.join(resolveHeavyVerificationRoot(), "slots");
12367
13484
  }
12368
13485
  function ensureHeavyVerificationDirs() {
12369
13486
  const dir = heavyVerificationSlotsDir();
12370
- mkdirSync7(dir, { recursive: true });
13487
+ mkdirSync8(dir, { recursive: true });
12371
13488
  return dir;
12372
13489
  }
12373
13490
 
@@ -12392,12 +13509,12 @@ function indexedSlotId(index) {
12392
13509
  return `slot-${index}`;
12393
13510
  }
12394
13511
  function slotFilePath(slotId, slotsDir = heavyVerificationSlotsDir()) {
12395
- return path58.join(slotsDir, `${slotId}.json`);
13512
+ return path60.join(slotsDir, `${slotId}.json`);
12396
13513
  }
12397
13514
  function readSlotRecord(filePath) {
12398
13515
  if (!existsSync41(filePath)) return null;
12399
13516
  try {
12400
- const parsed = JSON.parse(readFileSync14(filePath, "utf8"));
13517
+ const parsed = JSON.parse(readFileSync15(filePath, "utf8"));
12401
13518
  if (typeof parsed.slotId === "string" && typeof parsed.pid === "number" && typeof parsed.acquiredAt === "string" && typeof parsed.command === "string") {
12402
13519
  return parsed;
12403
13520
  }
@@ -12422,7 +13539,7 @@ function reclaimStaleSlot(filePath, staleMs) {
12422
13539
  }
12423
13540
  }
12424
13541
  function ensureSlotsDir(slotsDir) {
12425
- mkdirSync8(slotsDir, { recursive: true });
13542
+ mkdirSync9(slotsDir, { recursive: true });
12426
13543
  return slotsDir;
12427
13544
  }
12428
13545
  function reclaimStaleHeavyVerificationSlots(opts = {}) {
@@ -12431,7 +13548,7 @@ function reclaimStaleHeavyVerificationSlots(opts = {}) {
12431
13548
  let reclaimed = 0;
12432
13549
  for (const name of readdirSync15(slotsDir)) {
12433
13550
  if (!name.endsWith(".json")) continue;
12434
- const filePath = path58.join(slotsDir, name);
13551
+ const filePath = path60.join(slotsDir, name);
12435
13552
  const before = existsSync41(filePath);
12436
13553
  reclaimStaleSlot(filePath, staleMs);
12437
13554
  if (before && !existsSync41(filePath)) reclaimed += 1;
@@ -12445,7 +13562,7 @@ function listActiveHeavyVerificationSlots(opts = {}) {
12445
13562
  const active = [];
12446
13563
  for (const name of readdirSync15(slotsDir)) {
12447
13564
  if (!name.endsWith(".json")) continue;
12448
- const record = readSlotRecord(path58.join(slotsDir, name));
13565
+ const record = readSlotRecord(path60.join(slotsDir, name));
12449
13566
  if (record && !slotIsStale(record, staleMs)) active.push(record);
12450
13567
  }
12451
13568
  return active;
@@ -12487,7 +13604,7 @@ function tryAcquireHeavyVerificationSlot(command, opts = {}) {
12487
13604
  };
12488
13605
  try {
12489
13606
  const fd = openSync7(filePath, "wx");
12490
- writeFileSync5(fd, JSON.stringify(record, null, 2), "utf8");
13607
+ writeFileSync6(fd, JSON.stringify(record, null, 2), "utf8");
12491
13608
  closeSync7(fd);
12492
13609
  const activeSlots2 = countActiveHeavyVerificationSlots({ slotsDir, staleMs });
12493
13610
  return {
@@ -12547,10 +13664,10 @@ function assessHeavyVerificationGate(command, opts = {}) {
12547
13664
  }
12548
13665
 
12549
13666
  // src/heavy-verification/gate.ts
12550
- import { spawnSync as spawnSync9 } from "node:child_process";
13667
+ import { spawnSync as spawnSync10 } from "node:child_process";
12551
13668
  function sleepMs3(ms) {
12552
13669
  if (ms <= 0) return;
12553
- 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);`], {
12554
13671
  stdio: "ignore"
12555
13672
  });
12556
13673
  }
@@ -12565,11 +13682,12 @@ function waitForHeavyVerificationSlot(command, timeoutMs, pollMs = 2e3, opts = {
12565
13682
  }
12566
13683
 
12567
13684
  // src/harness-worktree-build-guard.ts
12568
- import path59 from "node:path";
13685
+ init_paths();
13686
+ import path61 from "node:path";
12569
13687
  function isPathUnderHarnessWorktree(cwd) {
12570
13688
  const worktreesDir = harnessWorktreesDir(resolveHarnessRoot());
12571
- const rel = path59.relative(worktreesDir, path59.resolve(cwd));
12572
- 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);
12573
13691
  }
12574
13692
  function assessHarnessWorktreeBuildGuard(cwd) {
12575
13693
  if (!isPathUnderHarnessWorktree(cwd)) return { ok: true };
@@ -12593,7 +13711,7 @@ function envArgv(env) {
12593
13711
  return out;
12594
13712
  }
12595
13713
  function runSpawn(argv, opts) {
12596
- const res = spawnSync10(argv[0], argv.slice(1), {
13714
+ const res = spawnSync11(argv[0], argv.slice(1), {
12597
13715
  cwd: opts.cwd,
12598
13716
  env: opts.env,
12599
13717
  encoding: "utf8",
@@ -12719,6 +13837,7 @@ function runHarnessVerifyCommands(cwd, commands = DEFAULT_HARNESS_VERIFY_COMMAND
12719
13837
  }
12720
13838
 
12721
13839
  // src/plan-progress.ts
13840
+ init_util();
12722
13841
  function parseEvidenceArg(raw) {
12723
13842
  const idx = raw.indexOf(":");
12724
13843
  if (idx <= 0) throw new Error(`invalid --evidence ${raw} (expected type:value)`);
@@ -12781,7 +13900,7 @@ async function emitPlanProgress(args) {
12781
13900
  }
12782
13901
  function verifyPlanLocal(args) {
12783
13902
  const worktree = required(args.worktree ? String(args.worktree) : void 0, "worktree");
12784
- const cwd = path60.resolve(worktree);
13903
+ const cwd = path62.resolve(worktree);
12785
13904
  const summary = runHarnessVerifyCommands(cwd);
12786
13905
  const emitJson = args.json === true || args.json === "true";
12787
13906
  const payload = { passed: summary.passed, worktree: cwd, steps: summary.steps };
@@ -12830,9 +13949,10 @@ async function verifyPlan(args) {
12830
13949
  }
12831
13950
 
12832
13951
  // src/harness-verify-cli.ts
12833
- import path61 from "node:path";
13952
+ import path63 from "node:path";
13953
+ init_util();
12834
13954
  function runHarnessVerifyCli(args) {
12835
- 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"));
12836
13956
  const emitJson = args.json === true || args.json === "true" || args.emitJson === true || args.emitJson === "true";
12837
13957
  const commands = [];
12838
13958
  const rawCmd = args.command;
@@ -12877,7 +13997,9 @@ function runHarnessVerifyCli(args) {
12877
13997
  }
12878
13998
 
12879
13999
  // src/plan-persist-cli.ts
12880
- import { readFileSync as readFileSync15 } from "node:fs";
14000
+ init_config();
14001
+ import { readFileSync as readFileSync16 } from "node:fs";
14002
+ init_util();
12881
14003
  var OPERATIONS = ["create", "add_version", "update_metadata"];
12882
14004
  var FAILURE_KINDS = [
12883
14005
  "approval_guard",
@@ -12889,7 +14011,7 @@ var FAILURE_KINDS = [
12889
14011
  function readBodyArg(args) {
12890
14012
  const bodyFile = args.bodyFile ? String(args.bodyFile) : void 0;
12891
14013
  if (bodyFile) {
12892
- return { body: readFileSync15(bodyFile, "utf8"), bodyPathHint: bodyFile };
14014
+ return { body: readFileSync16(bodyFile, "utf8"), bodyPathHint: bodyFile };
12893
14015
  }
12894
14016
  const inline = args.body ? String(args.body) : void 0;
12895
14017
  if (inline) return { body: inline };
@@ -13040,9 +14162,14 @@ function formatMonitorTickNotice(tick) {
13040
14162
  }
13041
14163
 
13042
14164
  // src/monitor/monitor.service.ts
13043
- import path63 from "node:path";
14165
+ import path65 from "node:path";
14166
+ init_run_store();
14167
+ init_status();
14168
+ init_util();
13044
14169
 
13045
14170
  // src/monitor/monitor.classify.ts
14171
+ init_status();
14172
+ init_util();
13046
14173
  function classifyWorkerHealth(input) {
13047
14174
  const { worker, status, taskLease } = input;
13048
14175
  const leaseOwner = taskLease?.leaseOwner ?? null;
@@ -13092,19 +14219,21 @@ function classifyWorkerHealth(input) {
13092
14219
  }
13093
14220
 
13094
14221
  // src/monitor/monitor.store.ts
13095
- import { existsSync as existsSync42, mkdirSync as mkdirSync9, readdirSync as readdirSync16, unlinkSync as unlinkSync5 } from "node:fs";
13096
- 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";
13097
14226
  function monitorsDir() {
13098
14227
  const { harnessRoot } = getHarnessPaths();
13099
- const dir = path62.join(harnessRoot, "monitors");
13100
- mkdirSync9(dir, { recursive: true });
14228
+ const dir = path64.join(harnessRoot, "monitors");
14229
+ mkdirSync10(dir, { recursive: true });
13101
14230
  return dir;
13102
14231
  }
13103
14232
  function monitorIdFor(runId, workerName) {
13104
14233
  return workerName ? `${safeSlug(runId)}--${safeSlug(workerName)}` : safeSlug(runId);
13105
14234
  }
13106
14235
  function monitorPath(monitorId) {
13107
- return path62.join(monitorsDir(), `${monitorId}.json`);
14236
+ return path64.join(monitorsDir(), `${monitorId}.json`);
13108
14237
  }
13109
14238
  function loadMonitorSession(monitorId) {
13110
14239
  return readJson(monitorPath(monitorId), void 0);
@@ -13125,7 +14254,7 @@ function listMonitorSessions() {
13125
14254
  for (const name of readdirSync16(dir)) {
13126
14255
  if (!name.endsWith(".json")) continue;
13127
14256
  const session = readJson(
13128
- path62.join(dir, name),
14257
+ path64.join(dir, name),
13129
14258
  void 0
13130
14259
  );
13131
14260
  if (!session?.monitorId) continue;
@@ -13145,6 +14274,7 @@ function listMonitorSessions() {
13145
14274
  }
13146
14275
 
13147
14276
  // src/monitor/monitor.terminal.ts
14277
+ init_status();
13148
14278
  function assessAutoCompleteEligibility(input) {
13149
14279
  const { worker, status } = input;
13150
14280
  const blockers = [];
@@ -13188,6 +14318,7 @@ function assessAutoCompleteEligibility(input) {
13188
14318
  }
13189
14319
 
13190
14320
  // src/monitor/monitor.task-lease.ts
14321
+ init_config();
13191
14322
  async function fetchTaskLeasesForWorkers(input) {
13192
14323
  const out = /* @__PURE__ */ new Map();
13193
14324
  const agentOsId = input.agentOsId?.trim();
@@ -13216,7 +14347,7 @@ async function fetchTaskLeasesForWorkers(input) {
13216
14347
  // src/monitor/monitor.service.ts
13217
14348
  function workerRecord2(runId, name) {
13218
14349
  return readJson(
13219
- path63.join(runDirectory(runId), "workers", safeSlug(name), "worker.json"),
14350
+ path65.join(runDirectory(runId), "workers", safeSlug(name), "worker.json"),
13220
14351
  void 0
13221
14352
  );
13222
14353
  }
@@ -13386,6 +14517,7 @@ async function monitorAutoCompleteCli(args) {
13386
14517
  }
13387
14518
 
13388
14519
  // src/monitor/monitor-loop.ts
14520
+ init_util();
13389
14521
  var DEFAULT_POLL_MS2 = 5e3;
13390
14522
  var DEFAULT_MAX_TOTAL_MS2 = 6 * 60 * 60 * 1e3;
13391
14523
  async function runMonitorLoop(args) {
@@ -13421,19 +14553,21 @@ async function runMonitorLoop(args) {
13421
14553
  }
13422
14554
 
13423
14555
  // src/monitor/monitor-spawn.ts
13424
- import { spawn as spawn6 } from "node:child_process";
14556
+ init_util();
14557
+ init_paths();
14558
+ import { spawn as spawn7 } from "node:child_process";
13425
14559
  import { closeSync as closeSync8, existsSync as existsSync43, openSync as openSync8 } from "node:fs";
13426
- import path64 from "node:path";
14560
+ import path66 from "node:path";
13427
14561
  import { fileURLToPath as fileURLToPath3 } from "node:url";
13428
14562
  function resolveDefaultCliPath2() {
13429
- return path64.join(fileURLToPath3(new URL(".", import.meta.url)), "cli.js");
14563
+ return path66.join(fileURLToPath3(new URL(".", import.meta.url)), "cli.js");
13430
14564
  }
13431
14565
  function spawnMonitorSidecar(opts) {
13432
14566
  const cliPath = opts.cliPath ?? resolveDefaultCliPath2();
13433
14567
  if (!existsSync43(cliPath)) return void 0;
13434
14568
  const monitorId = monitorIdFor(opts.runId, opts.workerName);
13435
14569
  const { harnessRoot } = getHarnessPaths();
13436
- const logPath = path64.join(harnessRoot, "monitors", `${monitorId}.log`);
14570
+ const logPath = path66.join(harnessRoot, "monitors", `${monitorId}.log`);
13437
14571
  let logFd;
13438
14572
  try {
13439
14573
  logFd = openSync8(logPath, "a");
@@ -13467,7 +14601,7 @@ function spawnMonitorSidecar(opts) {
13467
14601
  logFd ?? "ignore"
13468
14602
  ];
13469
14603
  try {
13470
- const child = spawn6(
14604
+ const child = spawn7(
13471
14605
  nodeExecutable,
13472
14606
  args,
13473
14607
  hiddenSpawnOptions({
@@ -13502,6 +14636,7 @@ function spawnMonitorSidecar(opts) {
13502
14636
  }
13503
14637
 
13504
14638
  // src/monitor/monitor-cli.ts
14639
+ init_util();
13505
14640
  async function startMonitorCli(args) {
13506
14641
  const runId = String(args.run || "");
13507
14642
  required(runId, "--run");
@@ -13553,7 +14688,7 @@ async function monitorTickCli(args) {
13553
14688
  }
13554
14689
 
13555
14690
  // src/package-version.ts
13556
- import { existsSync as existsSync44, readFileSync as readFileSync16 } from "node:fs";
14691
+ import { existsSync as existsSync44, readFileSync as readFileSync17 } from "node:fs";
13557
14692
  import { dirname, join } from "node:path";
13558
14693
  import { fileURLToPath as fileURLToPath4 } from "node:url";
13559
14694
  function resolvePackageRoot(moduleUrl) {
@@ -13568,7 +14703,7 @@ function resolvePackageRoot(moduleUrl) {
13568
14703
  }
13569
14704
  function readOwnPackageVersion(moduleUrl = import.meta.url) {
13570
14705
  const pkgPath = join(resolvePackageRoot(moduleUrl), "package.json");
13571
- const pkg = JSON.parse(readFileSync16(pkgPath, "utf8"));
14706
+ const pkg = JSON.parse(readFileSync17(pkgPath, "utf8"));
13572
14707
  if (typeof pkg.version !== "string" || !pkg.version.trim()) {
13573
14708
  throw new Error(`Missing package.json version at ${pkgPath}`);
13574
14709
  }
@@ -13635,6 +14770,7 @@ function shouldEnforceMemoryCostPackageGuardCli(scope, action) {
13635
14770
  }
13636
14771
 
13637
14772
  // src/run-resolve.ts
14773
+ init_util();
13638
14774
  function resolveHarnessRunByName(runName) {
13639
14775
  const name = runName.trim();
13640
14776
  if (!name) return null;
@@ -13659,7 +14795,11 @@ function resolveHarnessRunCli(args) {
13659
14795
  }
13660
14796
 
13661
14797
  // src/post-restart-unblock.ts
13662
- import path65 from "node:path";
14798
+ init_run_store();
14799
+ init_status();
14800
+ init_util();
14801
+ init_config();
14802
+ import path67 from "node:path";
13663
14803
  function skip(runId, worker, taskId, agentOsId, leaseOwner, reason) {
13664
14804
  return { runId, worker, taskId, agentOsId, leaseOwner, action: "skipped", reason };
13665
14805
  }
@@ -13672,7 +14812,7 @@ async function postRestartUnblock(args) {
13672
14812
  const errors = [];
13673
14813
  for (const run of listRunRecords()) {
13674
14814
  for (const name of Object.keys(run.workers ?? {})) {
13675
- 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");
13676
14816
  const worker = readJson(workerPath, void 0);
13677
14817
  if (!worker) {
13678
14818
  skipped.push(skip(run.id, name, "", "", "", "worker.json missing"));
@@ -13784,9 +14924,11 @@ async function postRestartUnblockCli(args) {
13784
14924
  }
13785
14925
 
13786
14926
  // src/default-repo-cli.ts
13787
- import path66 from "node:path";
13788
- import { homedir as homedir14 } from "node:os";
13789
- 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");
13790
14932
  function ensureDefaultRepo(opts) {
13791
14933
  const existing = loadUserConfig();
13792
14934
  const resolved = resolveDefaultRepo({ ...opts, config: existing });
@@ -13867,16 +15009,19 @@ function summarizeResolvedDefaultRepo(resolved) {
13867
15009
  }
13868
15010
 
13869
15011
  // src/doctor/runtime-takeover.ts
13870
- import path68 from "node:path";
15012
+ import path70 from "node:path";
15013
+ init_path_values();
13871
15014
 
13872
15015
  // src/doctor/runtime-takeover.probes.ts
13873
- import { accessSync, constants, existsSync as existsSync45, readFileSync as readFileSync17 } from "node:fs";
13874
- import { homedir as homedir15 } from "node:os";
13875
- import path67 from "node:path";
13876
- 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();
13877
15022
  function captureCommand(bin, args) {
13878
15023
  try {
13879
- const res = spawnSync11(bin, args, { encoding: "utf8" });
15024
+ const res = spawnSync12(bin, args, { encoding: "utf8" });
13880
15025
  const stdout = (res.stdout || "").trim();
13881
15026
  const stderr = (res.stderr || "").trim();
13882
15027
  const ok = res.status === 0;
@@ -13914,15 +15059,15 @@ var defaultRuntimeTakeoverProbes = {
13914
15059
  commandOnPath: (bin) => captureCommand(process.platform === "win32" ? "where" : "which", [bin]),
13915
15060
  kynverVersion: (bin) => captureCommand(bin, ["--version"]),
13916
15061
  loadConfig: () => loadUserConfig(),
13917
- configFilePath: () => path67.join(homedir15(), ".kynver", "config.json"),
13918
- credentialsFilePath: () => path67.join(homedir15(), ".kynver", "credentials"),
15062
+ configFilePath: () => path69.join(homedir16(), ".kynver", "config.json"),
15063
+ credentialsFilePath: () => path69.join(homedir16(), ".kynver", "credentials"),
13919
15064
  readCredentials: () => {
13920
- const credPath = path67.join(homedir15(), ".kynver", "credentials");
15065
+ const credPath = path69.join(homedir16(), ".kynver", "credentials");
13921
15066
  if (!existsSync45(credPath)) {
13922
15067
  return { hasApiKey: false };
13923
15068
  }
13924
15069
  try {
13925
- const parsed = JSON.parse(readFileSync17(credPath, "utf8"));
15070
+ const parsed = JSON.parse(readFileSync18(credPath, "utf8"));
13926
15071
  return {
13927
15072
  hasApiKey: Boolean(parsed.apiKey?.trim()),
13928
15073
  runnerTokenPrefix: tokenPrefix(parsed.runnerToken),
@@ -13952,7 +15097,7 @@ var defaultRuntimeTakeoverProbes = {
13952
15097
  })()
13953
15098
  }),
13954
15099
  harnessRoot: () => resolveHarnessRoot(),
13955
- legacyOpenclawHarnessRoot: () => path67.join(homedir15(), ".openclaw", "harness"),
15100
+ legacyOpenclawHarnessRoot: () => path69.join(homedir16(), ".openclaw", "harness"),
13956
15101
  pathExists: (target) => existsSync45(target),
13957
15102
  pathWritable: (target) => isWritable(target)
13958
15103
  };
@@ -14359,8 +15504,8 @@ function assessVercelDeployEvidence(probes) {
14359
15504
  }
14360
15505
  function assessHarnessDirs(probes) {
14361
15506
  const harnessRoot = probes.harnessRoot();
14362
- const runsDir = path68.join(harnessRoot, "runs");
14363
- const worktreesDir = path68.join(harnessRoot, "worktrees");
15507
+ const runsDir = path70.join(harnessRoot, "runs");
15508
+ const worktreesDir = path70.join(harnessRoot, "worktrees");
14364
15509
  const displayHarnessRoot = redactHomePath(harnessRoot);
14365
15510
  const displayRunsDir = redactHomePath(runsDir);
14366
15511
  const displayWorktreesDir = redactHomePath(worktreesDir);
@@ -14536,6 +15681,7 @@ function runRuntimeTakeoverDoctorCli(args = {}) {
14536
15681
  }
14537
15682
 
14538
15683
  // src/command-center-contract-cli.ts
15684
+ init_config();
14539
15685
  async function runCommandCenterContractCli(args) {
14540
15686
  const config = loadUserConfig();
14541
15687
  const agentOsId = (args.agentOsId ? String(args.agentOsId) : config.agentOsId) || "";
@@ -14566,6 +15712,9 @@ async function runCommandCenterContractCli(args) {
14566
15712
  console.log(JSON.stringify(res.response, null, 2));
14567
15713
  }
14568
15714
 
15715
+ // src/scheduler-cutover-cli.ts
15716
+ init_path_values();
15717
+
14569
15718
  // src/scheduler-cutover.ts
14570
15719
  var DEPLOYMENT_SCHEDULER_CUTOVER_STEPS = [
14571
15720
  "Vercel/hosted: set KYNVER_SCHEDULER_PROVIDER=qstash",
@@ -14624,9 +15773,10 @@ function applySchedulerCutoverAttestation(config) {
14624
15773
  }
14625
15774
 
14626
15775
  // src/scheduler-cutover-cli.ts
14627
- import path69 from "node:path";
14628
- import { homedir as homedir16 } from "node:os";
14629
- 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");
14630
15780
  function runSchedulerCutoverCheckCli(json = false) {
14631
15781
  const config = loadUserConfig();
14632
15782
  const report = assessSchedulerCutover(config);
@@ -14764,7 +15914,12 @@ async function runCronTickCli(args) {
14764
15914
  }
14765
15915
 
14766
15916
  // src/lane/landing-maintainer-tick.ts
14767
- 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();
14768
15923
 
14769
15924
  // src/lane/lane-spec.ts
14770
15925
  var LANDING_MAINTAINER_LANE_SPEC = {
@@ -14776,10 +15931,10 @@ var LANDING_MAINTAINER_LANE_SPEC = {
14776
15931
  };
14777
15932
 
14778
15933
  // src/lane/landing-maintainer-local.ts
14779
- import { spawnSync as spawnSync12 } from "node:child_process";
14780
- import path70 from "node:path";
15934
+ import { spawnSync as spawnSync13 } from "node:child_process";
15935
+ import path72 from "node:path";
14781
15936
  function runLandingWrapper(prNumber, repoRoot, execute) {
14782
- const script = path70.join(repoRoot, LANDING_MAINTAINER_LANE_SPEC.landScript);
15937
+ const script = path72.join(repoRoot, LANDING_MAINTAINER_LANE_SPEC.landScript);
14783
15938
  const args = [script, String(prNumber), ...LANDING_MAINTAINER_LANE_SPEC.landScriptArgs];
14784
15939
  if (!execute) {
14785
15940
  return {
@@ -14790,7 +15945,7 @@ function runLandingWrapper(prNumber, repoRoot, execute) {
14790
15945
  stderr: ""
14791
15946
  };
14792
15947
  }
14793
- const result = spawnSync12("node", args, {
15948
+ const result = spawnSync13("node", args, {
14794
15949
  cwd: repoRoot,
14795
15950
  encoding: "utf8",
14796
15951
  timeout: 10 * 60 * 1e3
@@ -14805,7 +15960,7 @@ function runLandingWrapper(prNumber, repoRoot, execute) {
14805
15960
  }
14806
15961
  function resolveLandingMaintainerRepoRoot(args) {
14807
15962
  const explicit = args.repoPath ? String(args.repoPath).trim() : "";
14808
- if (explicit) return path70.resolve(explicit);
15963
+ if (explicit) return path72.resolve(explicit);
14809
15964
  const resolved = resolveDefaultRepo();
14810
15965
  return resolved?.repo ?? process.cwd();
14811
15966
  }
@@ -14824,7 +15979,7 @@ async function runLandingMaintainerLaneTick(args) {
14824
15979
  ...buildBoxResourceSnapshotFromGate(resourceGate, {
14825
15980
  harnessRunId: runId,
14826
15981
  boxKind: resolveBoxKindFromConfig(loadUserConfig()),
14827
- hostLabel: os9.hostname()
15982
+ hostLabel: os11.hostname()
14828
15983
  }),
14829
15984
  providerHealthy: resourceGate.ok,
14830
15985
  authorizedForRepair: resourceGate.ok,
@@ -14928,10 +16083,11 @@ function usage(code = 0) {
14928
16083
  out(
14929
16084
  [
14930
16085
  "Usage:",
14931
- " 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)",
14932
16088
  " kynver runner credential [--agent-os-id ID] [--base-url URL]",
14933
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]",
14934
- " 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]",
14935
16091
  " kynver status --run RUN_ID [--blocked] [--running] [--task TASK_ID] [--worker WORKER] [--full] # top-level compact run status",
14936
16092
  " kynver run create [--repo /path/repo] [--name name] [--base origin/main]",
14937
16093
  " kynver run list",
@@ -14992,8 +16148,8 @@ async function main(argv = process.argv.slice(2)) {
14992
16148
  if (action && isHelpFlag(action) || rest.some(isHelpFlag)) return usage(0);
14993
16149
  const args = parseArgs(rest);
14994
16150
  const { runsDir, worktreesDir } = getPaths();
14995
- mkdirSync10(runsDir, { recursive: true });
14996
- mkdirSync10(worktreesDir, { recursive: true });
16151
+ mkdirSync11(runsDir, { recursive: true });
16152
+ mkdirSync11(worktreesDir, { recursive: true });
14997
16153
  if (scope === "daemon") {
14998
16154
  assertNativeDaemonAllowed();
14999
16155
  }
@@ -15013,10 +16169,16 @@ async function main(argv = process.argv.slice(2)) {
15013
16169
  });
15014
16170
  }
15015
16171
  if (scope === "login") return void await runLogin(args);
16172
+ if (scope === "bootstrap") return void await runBootstrap(args);
15016
16173
  if (scope === "status") return runStatus(args);
15017
16174
  if (scope === "runner" && action === "credential") return void await mintRunnerCredential(args);
15018
16175
  if (scope === "setup") return void await runSetup(args);
15019
- 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
+ }
15020
16182
  if (scope === "plan" && action === "progress") return void await emitPlanProgress(args);
15021
16183
  if (scope === "plan" && action === "verify") return void await verifyPlan(args);
15022
16184
  if (scope === "harness" && action === "verify") return runHarnessVerifyCli(args);