@kynver-app/runtime 0.1.108 → 0.1.116

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/bootstrap.d.ts +1 -0
  2. package/dist/cleanup-git-rev-cache.d.ts +5 -0
  3. package/dist/cleanup-git-status-cache.d.ts +5 -0
  4. package/dist/cleanup-guards.d.ts +2 -0
  5. package/dist/cleanup-index-status.d.ts +8 -1
  6. package/dist/cleanup-run-liveness.d.ts +8 -1
  7. package/dist/cli.js +1929 -468
  8. package/dist/cli.js.map +4 -4
  9. package/dist/daemon-heartbeat.d.ts +20 -0
  10. package/dist/daemon-keeper.d.ts +21 -0
  11. package/dist/daemon-platform-guard.d.ts +2 -0
  12. package/dist/device-login.d.ts +8 -0
  13. package/dist/index.js +2636 -1151
  14. package/dist/index.js.map +4 -4
  15. package/dist/landing/cli-auth.d.ts +5 -1
  16. package/dist/landing/land-pr.d.ts +8 -0
  17. package/dist/provider-evidence/collect.d.ts +18 -0
  18. package/dist/provider-evidence/exec.d.ts +5 -0
  19. package/dist/provider-evidence/index.d.ts +7 -0
  20. package/dist/provider-evidence/recipes-github.d.ts +4 -0
  21. package/dist/provider-evidence/recipes-vercel.d.ts +2 -0
  22. package/dist/provider-evidence/registry.d.ts +6 -0
  23. package/dist/provider-evidence/types.d.ts +48 -0
  24. package/dist/provider-evidence/wanted-store.d.ts +5 -0
  25. package/dist/providers/codex.d.ts +7 -2
  26. package/dist/providers/hermes-codex.d.ts +5 -2
  27. package/dist/server/cleanup.js +560 -164
  28. package/dist/server/cleanup.js.map +4 -4
  29. package/dist/server/default-repo.js +298 -68
  30. package/dist/server/default-repo.js.map +4 -4
  31. package/dist/server/memory-cost-enforce.js +11 -1
  32. package/dist/server/memory-cost-enforce.js.map +3 -3
  33. package/dist/server/monitor.js +356 -128
  34. package/dist/server/monitor.js.map +4 -4
  35. package/dist/server/worker-policy.js +304 -49
  36. package/dist/server/worker-policy.js.map +4 -4
  37. package/dist/status.d.ts +18 -0
  38. package/dist/worker-ops.d.ts +4 -0
  39. package/package.json +1 -1
@@ -1,18 +1,7 @@
1
- // src/cleanup.ts
2
- import path23 from "node:path";
3
-
4
- // src/paths.ts
5
- import { existsSync as existsSync8 } from "node:fs";
6
- import { homedir as homedir3 } from "node:os";
7
- import path6 from "node:path";
8
-
9
- // src/config.ts
10
- import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "node:fs";
11
- import { homedir as homedir2, totalmem } from "node:os";
12
- import path5 from "node:path";
13
-
14
- // src/git.ts
15
- import { spawnSync } from "node:child_process";
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __esm = (fn, res) => function __init() {
3
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
+ };
16
5
 
17
6
  // src/util.ts
18
7
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
@@ -21,6 +10,10 @@ function fail(message) {
21
10
  console.error(message);
22
11
  process.exit(1);
23
12
  }
13
+ function hiddenSpawnOptions(opts) {
14
+ if (process.platform !== "win32") return opts;
15
+ return { windowsHide: true, ...opts };
16
+ }
24
17
  function safeJson(line) {
25
18
  try {
26
19
  return JSON.parse(line);
@@ -88,45 +81,61 @@ function latestIso(values) {
88
81
  function secsAgo(ms) {
89
82
  return Math.max(0, Math.round((Date.now() - ms) / 1e3));
90
83
  }
84
+ var init_util = __esm({
85
+ "src/util.ts"() {
86
+ "use strict";
87
+ }
88
+ });
91
89
 
92
90
  // src/worker-env.ts
93
- var FORBIDDEN_WORKER_ENV_KEYS = [
94
- "ANTHROPIC_API_KEY",
95
- "ANALYST_API_KEY",
96
- "RECRUITER_API_KEY",
97
- "AUTH_SECRET",
98
- "NEXTAUTH_SECRET",
99
- "DATABASE_URL",
100
- "PRODUCTION_DATABASE_URL",
101
- "KYNVER_PRODUCTION_DATABASE_URL",
102
- "REDIS_URL",
103
- "GOOGLE_CLIENT_SECRET",
104
- "GITHUB_CLIENT_SECRET",
105
- "KYNVER_API_KEY",
106
- "KYNVER_SERVICE_SECRET",
107
- "KYNVER_RUNTIME_SECRET",
108
- "KYNVER_CRON_SECRET",
109
- "OPENCLAW_CRON_SECRET",
110
- "QSTASH_TOKEN",
111
- "QSTASH_CURRENT_SIGNING_KEY",
112
- "QSTASH_NEXT_SIGNING_KEY",
113
- "TOOL_SECRETS_KEK",
114
- "TOOL_EXECUTOR_DISPATCH_SECRET",
115
- "CLOUDFLARE_API_TOKEN",
116
- "STRIPE_SECRET_KEY",
117
- "STRIPE_WEBHOOK_SECRET",
118
- "STRIPE_IDENTITY_WEBHOOK_SECRET",
119
- "VOYAGE_API_KEY",
120
- "PERPLEXITY_API_KEY",
121
- "FRED_API_KEY",
122
- "FMP_API_KEY",
123
- "CURSOR_API_KEY"
124
- ];
125
- var FORBIDDEN_KEY_SET = new Set(FORBIDDEN_WORKER_ENV_KEYS);
91
+ var FORBIDDEN_WORKER_ENV_KEYS, FORBIDDEN_KEY_SET;
92
+ var init_worker_env = __esm({
93
+ "src/worker-env.ts"() {
94
+ "use strict";
95
+ FORBIDDEN_WORKER_ENV_KEYS = [
96
+ "ANTHROPIC_API_KEY",
97
+ "ANALYST_API_KEY",
98
+ "RECRUITER_API_KEY",
99
+ "AUTH_SECRET",
100
+ "NEXTAUTH_SECRET",
101
+ "DATABASE_URL",
102
+ "PRODUCTION_DATABASE_URL",
103
+ "KYNVER_PRODUCTION_DATABASE_URL",
104
+ "REDIS_URL",
105
+ "GOOGLE_CLIENT_SECRET",
106
+ "GITHUB_CLIENT_SECRET",
107
+ "KYNVER_API_KEY",
108
+ "KYNVER_SERVICE_SECRET",
109
+ "KYNVER_RUNTIME_SECRET",
110
+ "KYNVER_CRON_SECRET",
111
+ "OPENCLAW_CRON_SECRET",
112
+ "QSTASH_TOKEN",
113
+ "QSTASH_CURRENT_SIGNING_KEY",
114
+ "QSTASH_NEXT_SIGNING_KEY",
115
+ "TOOL_SECRETS_KEK",
116
+ "TOOL_EXECUTOR_DISPATCH_SECRET",
117
+ "CLOUDFLARE_API_TOKEN",
118
+ "STRIPE_SECRET_KEY",
119
+ "STRIPE_WEBHOOK_SECRET",
120
+ "STRIPE_IDENTITY_WEBHOOK_SECRET",
121
+ "VOYAGE_API_KEY",
122
+ "PERPLEXITY_API_KEY",
123
+ "FRED_API_KEY",
124
+ "FMP_API_KEY",
125
+ "CURSOR_API_KEY"
126
+ ];
127
+ FORBIDDEN_KEY_SET = new Set(FORBIDDEN_WORKER_ENV_KEYS);
128
+ }
129
+ });
126
130
 
127
131
  // src/git.ts
132
+ import { spawnSync } from "node:child_process";
128
133
  function git(cwd, args, options = {}) {
129
- const res = spawnSync("git", args, { cwd, encoding: "utf8" });
134
+ const res = spawnSync(
135
+ "git",
136
+ args,
137
+ hiddenSpawnOptions({ cwd, encoding: "utf8" })
138
+ );
130
139
  if (res.status !== 0 && !options.allowFailure) {
131
140
  const message = `git ${args.join(" ")} failed: ${res.stderr || res.stdout}`;
132
141
  if (options.throwError) throw new Error(message);
@@ -139,7 +148,11 @@ function gitStatusShort(worktreePath) {
139
148
  }
140
149
  function gitCapture(cwd, args) {
141
150
  try {
142
- const res = spawnSync("git", args, { cwd, encoding: "utf8" });
151
+ const res = spawnSync(
152
+ "git",
153
+ args,
154
+ hiddenSpawnOptions({ cwd, encoding: "utf8" })
155
+ );
143
156
  return {
144
157
  status: res.status,
145
158
  stdout: res.stdout || "",
@@ -237,6 +250,13 @@ function unknownAncestry(base, error, head = null) {
237
250
  error
238
251
  };
239
252
  }
253
+ var init_git = __esm({
254
+ "src/git.ts"() {
255
+ "use strict";
256
+ init_util();
257
+ init_worker_env();
258
+ }
259
+ });
240
260
 
241
261
  // src/path-values.ts
242
262
  import { homedir } from "node:os";
@@ -251,15 +271,37 @@ function expandHomePath(value) {
251
271
  function resolveUserPath(value) {
252
272
  return path2.resolve(expandHomePath(value));
253
273
  }
274
+ var init_path_values = __esm({
275
+ "src/path-values.ts"() {
276
+ "use strict";
277
+ }
278
+ });
254
279
 
255
- // src/disk-gate.ts
256
- import { statfsSync as statfsSync2 } from "node:fs";
280
+ // src/default-repo-discovery.ts
281
+ var init_default_repo_discovery = __esm({
282
+ "src/default-repo-discovery.ts"() {
283
+ "use strict";
284
+ init_git();
285
+ init_path_values();
286
+ }
287
+ });
288
+
289
+ // src/box-identity.ts
290
+ var init_box_identity = __esm({
291
+ "src/box-identity.ts"() {
292
+ "use strict";
293
+ }
294
+ });
295
+
296
+ // src/bounded-build/meminfo.ts
297
+ var init_meminfo = __esm({
298
+ "src/bounded-build/meminfo.ts"() {
299
+ "use strict";
300
+ }
301
+ });
257
302
 
258
303
  // src/wsl-host.ts
259
304
  import { existsSync as existsSync2, readFileSync as readFileSync2, statfsSync } from "node:fs";
260
- var DEFAULT_WSL_HOST_WARN_FREE_BYTES = 25 * 1024 * 1024 * 1024;
261
- var DEFAULT_WSL_HOST_CRITICAL_FREE_BYTES = 12 * 1024 * 1024 * 1024;
262
- var DEFAULT_WSL_HOST_MOUNT = "/mnt/c";
263
305
  function isWslHost() {
264
306
  if (process.platform !== "linux") return false;
265
307
  for (const probe of ["/proc/sys/kernel/osrelease", "/proc/version"]) {
@@ -322,12 +364,18 @@ function observeWslHostDisk(options = {}) {
322
364
  function summarizeWslRecoverySteps() {
323
365
  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.";
324
366
  }
367
+ var DEFAULT_WSL_HOST_WARN_FREE_BYTES, DEFAULT_WSL_HOST_CRITICAL_FREE_BYTES, DEFAULT_WSL_HOST_MOUNT;
368
+ var init_wsl_host = __esm({
369
+ "src/wsl-host.ts"() {
370
+ "use strict";
371
+ DEFAULT_WSL_HOST_WARN_FREE_BYTES = 25 * 1024 * 1024 * 1024;
372
+ DEFAULT_WSL_HOST_CRITICAL_FREE_BYTES = 12 * 1024 * 1024 * 1024;
373
+ DEFAULT_WSL_HOST_MOUNT = "/mnt/c";
374
+ }
375
+ });
325
376
 
326
377
  // src/disk-gate.ts
327
- var DEFAULT_WARN_FREE_BYTES = 30 * 1024 * 1024 * 1024;
328
- var DEFAULT_CRITICAL_FREE_BYTES = 15 * 1024 * 1024 * 1024;
329
- var DEFAULT_MAX_USED_PERCENT = 80;
330
- var DEFAULT_HARD_MAX_USED_PERCENT = 90;
378
+ import { statfsSync as statfsSync2 } from "node:fs";
331
379
  function observeRunnerDiskGate(input = {}) {
332
380
  const path24 = input.diskPath?.trim() || "/";
333
381
  const warnBelowBytes = input.diskFreeWarnBytes ?? DEFAULT_WARN_FREE_BYTES;
@@ -369,6 +417,17 @@ function observeRunnerDiskGate(input = {}) {
369
417
  wslHost
370
418
  };
371
419
  }
420
+ var DEFAULT_WARN_FREE_BYTES, DEFAULT_CRITICAL_FREE_BYTES, DEFAULT_MAX_USED_PERCENT, DEFAULT_HARD_MAX_USED_PERCENT;
421
+ var init_disk_gate = __esm({
422
+ "src/disk-gate.ts"() {
423
+ "use strict";
424
+ init_wsl_host();
425
+ DEFAULT_WARN_FREE_BYTES = 30 * 1024 * 1024 * 1024;
426
+ DEFAULT_CRITICAL_FREE_BYTES = 15 * 1024 * 1024 * 1024;
427
+ DEFAULT_MAX_USED_PERCENT = 80;
428
+ DEFAULT_HARD_MAX_USED_PERCENT = 90;
429
+ }
430
+ });
372
431
 
373
432
  // src/run-store.ts
374
433
  import { existsSync as existsSync3, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
@@ -416,6 +475,13 @@ function runDirectory(id) {
416
475
  function runDirectoryAt(harnessRoot, id) {
417
476
  return runDir(harnessRunsDir(harnessRoot), safeSlug(id));
418
477
  }
478
+ var init_run_store = __esm({
479
+ "src/run-store.ts"() {
480
+ "use strict";
481
+ init_paths();
482
+ init_util();
483
+ }
484
+ });
419
485
 
420
486
  // src/run-worker-index.ts
421
487
  import { existsSync as existsSync4, readdirSync as readdirSync3 } from "node:fs";
@@ -433,9 +499,13 @@ function listRunWorkerNames(run) {
433
499
  }
434
500
  return [...names];
435
501
  }
436
-
437
- // src/heartbeat.ts
438
- import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
502
+ var init_run_worker_index = __esm({
503
+ "src/run-worker-index.ts"() {
504
+ "use strict";
505
+ init_run_store();
506
+ init_util();
507
+ }
508
+ });
439
509
 
440
510
  // src/heartbeat-final-result.ts
441
511
  function tryParseJsonObject(text) {
@@ -486,9 +556,14 @@ function terminalFinalResultFromHeartbeatRow(row) {
486
556
  if (embedded) return embedded;
487
557
  return summary;
488
558
  }
559
+ var init_heartbeat_final_result = __esm({
560
+ "src/heartbeat-final-result.ts"() {
561
+ "use strict";
562
+ }
563
+ });
489
564
 
490
565
  // src/heartbeat.ts
491
- var HEARTBEAT_FUTURE_SKEW_MS = 6e4;
566
+ import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
492
567
  function isTerminalHeartbeatPhase(phase) {
493
568
  return phase === "complete";
494
569
  }
@@ -551,29 +626,17 @@ function parseHeartbeat(file) {
551
626
  }
552
627
  return result;
553
628
  }
554
-
555
- // src/stream.ts
556
- import { existsSync as existsSync6, readFileSync as readFileSync4 } from "node:fs";
629
+ var HEARTBEAT_FUTURE_SKEW_MS;
630
+ var init_heartbeat = __esm({
631
+ "src/heartbeat.ts"() {
632
+ "use strict";
633
+ init_heartbeat_final_result();
634
+ init_util();
635
+ HEARTBEAT_FUTURE_SKEW_MS = 6e4;
636
+ }
637
+ });
557
638
 
558
639
  // src/repo-search.ts
559
- var RG_BINARIES = /* @__PURE__ */ new Set(["rg", "ripgrep", "grep"]);
560
- var RG_OPTS_WITH_VALUE = /* @__PURE__ */ new Set([
561
- "-e",
562
- "--regexp",
563
- "-f",
564
- "--file",
565
- "-m",
566
- "--max-count",
567
- "-A",
568
- "--after-context",
569
- "-B",
570
- "--before-context",
571
- "-C",
572
- "--context",
573
- "-g",
574
- "--glob",
575
- "--iglob"
576
- ]);
577
640
  function binaryName(token) {
578
641
  if (!token) return null;
579
642
  const base = token.split("/").pop() ?? token;
@@ -772,11 +835,32 @@ function diagnoseRepoSearchFailure(input) {
772
835
  }
773
836
  return null;
774
837
  }
838
+ var RG_BINARIES, RG_OPTS_WITH_VALUE;
839
+ var init_repo_search = __esm({
840
+ "src/repo-search.ts"() {
841
+ "use strict";
842
+ RG_BINARIES = /* @__PURE__ */ new Set(["rg", "ripgrep", "grep"]);
843
+ 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
+ }
861
+ });
775
862
 
776
863
  // src/shell-command-outcome.ts
777
- var NPM_AUDIT_RE = /\bnpm\s+audit\b/i;
778
- var RG_CMD_RE = /\b(rg|ripgrep)\b/i;
779
- var RG_REAL_ERROR_RE = /\b(error|invalid|unknown|panic|not found)\b/i;
780
864
  function tidy(text, max = 200) {
781
865
  const one = text.replace(/\s+/g, " ").trim();
782
866
  return one.length > max ? `${one.slice(0, max - 1)}\u2026` : one;
@@ -980,8 +1064,19 @@ function classifyShellCommandOutcome(input) {
980
1064
  summary: `command failed (exit ${input.exitCode}): ${tail}`
981
1065
  };
982
1066
  }
1067
+ var NPM_AUDIT_RE, RG_CMD_RE, RG_REAL_ERROR_RE;
1068
+ var init_shell_command_outcome = __esm({
1069
+ "src/shell-command-outcome.ts"() {
1070
+ "use strict";
1071
+ init_repo_search();
1072
+ NPM_AUDIT_RE = /\bnpm\s+audit\b/i;
1073
+ RG_CMD_RE = /\b(rg|ripgrep)\b/i;
1074
+ RG_REAL_ERROR_RE = /\b(error|invalid|unknown|panic|not found)\b/i;
1075
+ }
1076
+ });
983
1077
 
984
1078
  // src/stream.ts
1079
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "node:fs";
985
1080
  function eventTimestampIso(event) {
986
1081
  const tsMs = event.timestamp_ms;
987
1082
  return event.timestamp || event.ts || (tsMs ? new Date(tsMs).toISOString() : void 0);
@@ -1082,38 +1177,15 @@ function parseHarnessStream(file) {
1082
1177
  }
1083
1178
  return result;
1084
1179
  }
1180
+ var init_stream = __esm({
1181
+ "src/stream.ts"() {
1182
+ "use strict";
1183
+ init_shell_command_outcome();
1184
+ init_util();
1185
+ }
1186
+ });
1085
1187
 
1086
1188
  // src/exit-classify.ts
1087
- var FAILURE_PATTERNS = [
1088
- {
1089
- test: /\b(?:invalid|unknown|unsupported|unrecognized)\b[^.\n]*\bmodel\b/i,
1090
- label: "provider rejected the requested model"
1091
- },
1092
- {
1093
- test: /\bmodel\b[^.\n]*\b(?:not\s+(?:found|supported|available|recognized|valid)|is\s+not\s+valid|does\s+not\s+exist)/i,
1094
- label: "provider rejected the requested model"
1095
- },
1096
- {
1097
- test: /\b(?:did you mean|available models|choose (?:a|one of)|supported models)\b/i,
1098
- label: "provider rejected the requested model"
1099
- },
1100
- {
1101
- test: /model preflight failed/i,
1102
- label: "model/provider preflight failed"
1103
- },
1104
- {
1105
- test: /\b(?:command not found|ENOENT|is the .*CLI on PATH|executable not found|no such file or directory)\b/i,
1106
- label: "provider CLI is missing or not on PATH"
1107
- },
1108
- {
1109
- test: /\bfailed to spawn\b/i,
1110
- label: "provider failed to spawn the worker process"
1111
- },
1112
- {
1113
- test: /\b(?:not logged in|unauthorized|authentication (?:failed|required)|invalid api key|missing api key|401)\b/i,
1114
- label: "provider authentication failed"
1115
- }
1116
- ];
1117
1189
  function tidy2(errorText, max = 240) {
1118
1190
  const oneLine2 = errorText.replace(/\s+/g, " ").trim();
1119
1191
  return oneLine2.length > max ? `${oneLine2.slice(0, max - 1)}\u2026` : oneLine2;
@@ -1128,6 +1200,42 @@ function classifyExitFailure(errorText) {
1128
1200
  }
1129
1201
  return null;
1130
1202
  }
1203
+ var FAILURE_PATTERNS;
1204
+ var init_exit_classify = __esm({
1205
+ "src/exit-classify.ts"() {
1206
+ "use strict";
1207
+ FAILURE_PATTERNS = [
1208
+ {
1209
+ test: /\b(?:invalid|unknown|unsupported|unrecognized)\b[^.\n]*\bmodel\b/i,
1210
+ label: "provider rejected the requested model"
1211
+ },
1212
+ {
1213
+ test: /\bmodel\b[^.\n]*\b(?:not\s+(?:found|supported|available|recognized|valid)|is\s+not\s+valid|does\s+not\s+exist)/i,
1214
+ label: "provider rejected the requested model"
1215
+ },
1216
+ {
1217
+ test: /\b(?:did you mean|available models|choose (?:a|one of)|supported models)\b/i,
1218
+ label: "provider rejected the requested model"
1219
+ },
1220
+ {
1221
+ test: /model preflight failed/i,
1222
+ label: "model/provider preflight failed"
1223
+ },
1224
+ {
1225
+ test: /\b(?:command not found|ENOENT|is the .*CLI on PATH|executable not found|no such file or directory)\b/i,
1226
+ label: "provider CLI is missing or not on PATH"
1227
+ },
1228
+ {
1229
+ test: /\bfailed to spawn\b/i,
1230
+ label: "provider failed to spawn the worker process"
1231
+ },
1232
+ {
1233
+ test: /\b(?:not logged in|unauthorized|authentication (?:failed|required)|invalid api key|missing api key|401)\b/i,
1234
+ label: "provider authentication failed"
1235
+ }
1236
+ ];
1237
+ }
1238
+ });
1131
1239
 
1132
1240
  // src/exited-salvage.ts
1133
1241
  function trimOrNull(value) {
@@ -1186,6 +1294,11 @@ function assessExitedWorkerSalvage(input) {
1186
1294
  attentionReason: buildAttentionReason(kind, uncommittedCount, headCommit)
1187
1295
  };
1188
1296
  }
1297
+ var init_exited_salvage = __esm({
1298
+ "src/exited-salvage.ts"() {
1299
+ "use strict";
1300
+ }
1301
+ });
1189
1302
 
1190
1303
  // src/landing-gate.ts
1191
1304
  function trimOrNull2(value) {
@@ -1231,6 +1344,11 @@ function landingAttentionReason(verdict) {
1231
1344
  if (!verdict.blocked) return void 0;
1232
1345
  return verdict.detail ?? verdict.reason ?? "dirty_worktree_no_pr";
1233
1346
  }
1347
+ var init_landing_gate = __esm({
1348
+ "src/landing-gate.ts"() {
1349
+ "use strict";
1350
+ }
1351
+ });
1234
1352
 
1235
1353
  // src/worker-final-result-embed.ts
1236
1354
  function tryParseJsonObject2(text) {
@@ -1280,6 +1398,11 @@ function extractEmbeddedWorkerFinalResultRecord(value) {
1280
1398
  }
1281
1399
  return best;
1282
1400
  }
1401
+ var init_worker_final_result_embed = __esm({
1402
+ "src/worker-final-result-embed.ts"() {
1403
+ "use strict";
1404
+ }
1405
+ });
1283
1406
 
1284
1407
  // src/landing-contract-gate.ts
1285
1408
  function trimOrNull3(value) {
@@ -1439,10 +1562,14 @@ function landingContractAttentionReason(verdict) {
1439
1562
  if (!verdict.blocked) return void 0;
1440
1563
  return verdict.detail ?? verdict.reason;
1441
1564
  }
1565
+ var init_landing_contract_gate = __esm({
1566
+ "src/landing-contract-gate.ts"() {
1567
+ "use strict";
1568
+ init_worker_final_result_embed();
1569
+ }
1570
+ });
1442
1571
 
1443
1572
  // src/status.ts
1444
- var NO_START_MS = 18e4;
1445
- var STALE_MS = 6e5;
1446
1573
  function computeAttention(input) {
1447
1574
  const now = Date.now();
1448
1575
  if (input.completionBlocker && !isSkippedTerminalCompletionBlocker(input.completionBlocker)) {
@@ -1634,7 +1761,15 @@ function computeWorkerStatus(worker, options = {}) {
1634
1761
  changedFiles,
1635
1762
  gitAncestry,
1636
1763
  instructionPolicyFingerprint: worker.instructionPolicyFingerprint ?? null,
1637
- instructionPolicyEvidence: worker.instructionPolicyEvidence ?? null
1764
+ instructionPolicyEvidence: worker.instructionPolicyEvidence ?? null,
1765
+ model: worker.model ?? worker.orchestrationAudit?.model ?? null,
1766
+ provider: worker.orchestrationAudit?.provider ?? null,
1767
+ boxKind: worker.boxKind ?? null,
1768
+ boxId: worker.boxId ?? null,
1769
+ runtimeId: worker.runtimeId ?? null,
1770
+ personaSlug: worker.personaSlug ?? null,
1771
+ dispatched: worker.dispatched ?? null,
1772
+ localOnly: worker.localOnly ?? null
1638
1773
  };
1639
1774
  }
1640
1775
  function isFinishedWorkerStatus(status) {
@@ -1647,15 +1782,63 @@ function isLandingBlockedWorkerStatus(status) {
1647
1782
  if (!status.finalResult) return false;
1648
1783
  return status.attention.state === "needs_attention" || status.attention.state === "blocked";
1649
1784
  }
1785
+ var NO_START_MS, STALE_MS;
1786
+ var init_status = __esm({
1787
+ "src/status.ts"() {
1788
+ "use strict";
1789
+ init_heartbeat();
1790
+ init_stream();
1791
+ init_exit_classify();
1792
+ init_exited_salvage();
1793
+ init_git();
1794
+ init_landing_gate();
1795
+ init_landing_contract_gate();
1796
+ init_worker_final_result_embed();
1797
+ init_util();
1798
+ NO_START_MS = 18e4;
1799
+ STALE_MS = 6e5;
1800
+ }
1801
+ });
1802
+
1803
+ // src/harness-worker-active.ts
1804
+ var init_harness_worker_active = __esm({
1805
+ "src/harness-worker-active.ts"() {
1806
+ "use strict";
1807
+ init_status();
1808
+ }
1809
+ });
1650
1810
 
1651
1811
  // src/resource-gate.ts
1652
- var DEFAULT_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
1653
- var DEFAULT_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
1812
+ var DEFAULT_PER_WORKER_MEM_BYTES, DEFAULT_MEM_RESERVE_BYTES;
1813
+ var init_resource_gate = __esm({
1814
+ "src/resource-gate.ts"() {
1815
+ "use strict";
1816
+ init_meminfo();
1817
+ init_config();
1818
+ init_box_identity();
1819
+ init_worker_cap_source();
1820
+ init_disk_gate();
1821
+ init_run_store();
1822
+ init_run_worker_index();
1823
+ init_harness_worker_active();
1824
+ init_util();
1825
+ DEFAULT_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
1826
+ DEFAULT_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
1827
+ }
1828
+ });
1829
+
1830
+ // src/worker-cap-source.ts
1831
+ var init_worker_cap_source = __esm({
1832
+ "src/worker-cap-source.ts"() {
1833
+ "use strict";
1834
+ init_resource_gate();
1835
+ }
1836
+ });
1654
1837
 
1655
1838
  // src/config.ts
1656
- var CONFIG_DIR = path5.join(homedir2(), ".kynver");
1657
- var CONFIG_FILE = path5.join(CONFIG_DIR, "config.json");
1658
- var CREDENTIALS_FILE = path5.join(CONFIG_DIR, "credentials");
1839
+ import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "node:fs";
1840
+ import { homedir as homedir2, totalmem } from "node:os";
1841
+ import path5 from "node:path";
1659
1842
  function loadUserConfig() {
1660
1843
  if (!existsSync7(CONFIG_FILE)) return {};
1661
1844
  try {
@@ -1664,12 +1847,28 @@ function loadUserConfig() {
1664
1847
  return {};
1665
1848
  }
1666
1849
  }
1667
- var SETUP_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
1668
- var SETUP_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
1850
+ var CONFIG_DIR, CONFIG_FILE, CREDENTIALS_FILE, SETUP_PER_WORKER_MEM_BYTES, SETUP_MEM_RESERVE_BYTES;
1851
+ var init_config = __esm({
1852
+ "src/config.ts"() {
1853
+ "use strict";
1854
+ init_default_repo_discovery();
1855
+ init_path_values();
1856
+ init_util();
1857
+ init_box_identity();
1858
+ init_worker_cap_source();
1859
+ init_disk_gate();
1860
+ CONFIG_DIR = path5.join(homedir2(), ".kynver");
1861
+ CONFIG_FILE = path5.join(CONFIG_DIR, "config.json");
1862
+ CREDENTIALS_FILE = path5.join(CONFIG_DIR, "credentials");
1863
+ SETUP_PER_WORKER_MEM_BYTES = 500 * 1024 * 1024;
1864
+ SETUP_MEM_RESERVE_BYTES = 4 * 1024 * 1024 * 1024;
1865
+ }
1866
+ });
1669
1867
 
1670
1868
  // src/paths.ts
1671
- var LEGACY_ROOT = path6.join(homedir3(), ".openclaw", "harness");
1672
- var HARNESS_LAYOUT_DIR_NAMES = /* @__PURE__ */ new Set(["runs", "worktrees"]);
1869
+ import { existsSync as existsSync8 } from "node:fs";
1870
+ import { homedir as homedir3 } from "node:os";
1871
+ import path6 from "node:path";
1673
1872
  function normalizeHarnessRoot(root) {
1674
1873
  let resolved = path6.resolve(resolveUserPath(root.trim()));
1675
1874
  while (HARNESS_LAYOUT_DIR_NAMES.has(path6.basename(resolved))) {
@@ -1704,10 +1903,30 @@ function getHarnessPaths() {
1704
1903
  function runDir(runsDir, id) {
1705
1904
  return path6.join(runsDir, safeSlug(id));
1706
1905
  }
1906
+ var LEGACY_ROOT, HARNESS_LAYOUT_DIR_NAMES;
1907
+ var init_paths = __esm({
1908
+ "src/paths.ts"() {
1909
+ "use strict";
1910
+ init_config();
1911
+ init_path_values();
1912
+ init_util();
1913
+ LEGACY_ROOT = path6.join(homedir3(), ".openclaw", "harness");
1914
+ HARNESS_LAYOUT_DIR_NAMES = /* @__PURE__ */ new Set(["runs", "worktrees"]);
1915
+ }
1916
+ });
1917
+
1918
+ // src/cleanup.ts
1919
+ init_paths();
1920
+ import path23 from "node:path";
1707
1921
 
1708
1922
  // src/cleanup-guards.ts
1923
+ init_landing_gate();
1709
1924
  import path8 from "node:path";
1710
1925
 
1926
+ // src/cleanup-index-status.ts
1927
+ init_git();
1928
+ init_status();
1929
+
1711
1930
  // src/cleanup-build-cache-paths.ts
1712
1931
  var HARNESS_BUILD_CACHE_RELATIVE_PATHS = [
1713
1932
  ".next",
@@ -1735,7 +1954,34 @@ function materialWorktreeChanges(changedFiles) {
1735
1954
  });
1736
1955
  }
1737
1956
 
1957
+ // src/cleanup-worktree-salvage.ts
1958
+ function prUrlFromFinalResult(finalResult) {
1959
+ if (typeof finalResult === "string") {
1960
+ const match = finalResult.match(/https:\/\/github\.com\/[^\s]+\/pull\/\d+/i);
1961
+ return match?.[0] ?? null;
1962
+ }
1963
+ if (finalResult && typeof finalResult === "object") {
1964
+ const obj = finalResult;
1965
+ for (const key of ["prUrl", "pr_url", "pullRequestUrl"]) {
1966
+ const value = obj[key];
1967
+ if (typeof value === "string" && value.trim()) return value.trim();
1968
+ }
1969
+ }
1970
+ return null;
1971
+ }
1972
+ function isPrOrUnmergedWork(status) {
1973
+ const relation = status.gitAncestry?.relation;
1974
+ if (relation === "merged" || relation === "synced") {
1975
+ return materialWorktreeChanges(status.changedFiles).length > 0;
1976
+ }
1977
+ if (prUrlFromFinalResult(status.finalResult)) return true;
1978
+ if (relation === "ahead" || relation === "diverged") return true;
1979
+ if (status.changedFiles.length > 0 && status.finalResult) return true;
1980
+ return false;
1981
+ }
1982
+
1738
1983
  // src/cleanup-index-status.ts
1984
+ init_util();
1739
1985
  function indexedWorktreeStatus(entry) {
1740
1986
  if (!entry.status) {
1741
1987
  entry.status = computeWorkerStatus(entry.worker, {
@@ -1745,14 +1991,81 @@ function indexedWorktreeStatus(entry) {
1745
1991
  }
1746
1992
  return entry.status;
1747
1993
  }
1748
- function indexedWorktreeHasMaterialChanges(entry) {
1994
+ function indexedWorktreeHasMaterialChanges(entry, gitStatusCache) {
1749
1995
  if (entry.status) {
1750
1996
  return materialWorktreeChanges(entry.status.changedFiles).length > 0;
1751
1997
  }
1752
- return materialWorktreeChanges(gitStatusShort(entry.worktreePath)).length > 0;
1998
+ const porcelain = gitStatusCache ? gitStatusCache.porcelain(entry.worktreePath) : gitStatusShort(entry.worktreePath);
1999
+ return materialWorktreeChanges(porcelain).length > 0;
2000
+ }
2001
+ function finalResultFromWorkerJson(entry) {
2002
+ const snapshot = entry.worker.completionSnapshot?.finalResult;
2003
+ if (snapshot !== void 0 && snapshot !== null) return snapshot;
2004
+ if (entry.worker.taskPrUrl) {
2005
+ return { prUrl: entry.worker.taskPrUrl };
2006
+ }
2007
+ return null;
2008
+ }
2009
+ function resolveWorktreeGuardStatus(entry, ctx) {
2010
+ if (entry.status) return entry.status;
2011
+ const worker = entry.worker;
2012
+ const completionAcknowledged = typeof worker.completionReportedAt === "string" && worker.completionReportedAt.trim().length > 0;
2013
+ const workerJsonTerminal = Boolean(worker.status && ["done", "exited", "blocked", "failed", "abandoned"].includes(worker.status)) || completionAcknowledged;
2014
+ const finalResult = finalResultFromWorkerJson(entry);
2015
+ if (workerJsonTerminal && !isPidAlive(worker.pid)) {
2016
+ const changedFiles = ctx?.gitStatusCache ? ctx.gitStatusCache.porcelain(entry.worktreePath) : gitStatusShort(entry.worktreePath);
2017
+ const baseLabel = entry.run.baseCommit?.trim() || entry.run.base?.trim() || "origin/main";
2018
+ const ahead = ctx?.gitRevCache?.countAheadOfMain(entry.worktreePath, baseLabel);
2019
+ const gitAncestry = ahead === 0 ? {
2020
+ checked: true,
2021
+ base: baseLabel,
2022
+ relation: "synced"
2023
+ } : computeGitAncestry(entry.worktreePath, {
2024
+ base: entry.run.base,
2025
+ baseCommit: entry.run.baseCommit
2026
+ });
2027
+ const status = {
2028
+ runId: entry.runId,
2029
+ worker: entry.workerName,
2030
+ pid: worker.pid,
2031
+ alive: false,
2032
+ status: worker.status ?? (completionAcknowledged ? "done" : "exited"),
2033
+ attention: { state: completionAcknowledged ? "done" : "stale" },
2034
+ branch: worker.branch,
2035
+ worktreePath: entry.worktreePath,
2036
+ ownedPaths: worker.ownedPaths,
2037
+ stdoutBytes: 0,
2038
+ stderrBytes: 0,
2039
+ heartbeatBytes: 0,
2040
+ firstEventAt: null,
2041
+ lastEventAt: null,
2042
+ lastActivityAt: worker.completionReportedAt ?? null,
2043
+ currentTool: null,
2044
+ heartbeatCount: 0,
2045
+ lastHeartbeatAt: null,
2046
+ lastHeartbeatPhase: null,
2047
+ lastHeartbeatSummary: null,
2048
+ heartbeatBlocker: null,
2049
+ changedFiles,
2050
+ gitAncestry,
2051
+ finalResult,
2052
+ completionBlocker: typeof worker.completionBlocker === "string" ? worker.completionBlocker.trim() || null : null,
2053
+ prUrl: worker.repairTargetPrUrl ?? worker.taskPrUrl ?? prUrlFromFinalResult(finalResult)
2054
+ };
2055
+ entry.status = status;
2056
+ return status;
2057
+ }
2058
+ return indexedWorktreeStatus(entry);
1753
2059
  }
1754
2060
 
2061
+ // src/cleanup-guards.ts
2062
+ init_status();
2063
+
1755
2064
  // src/finalize.ts
2065
+ init_run_store();
2066
+ init_run_worker_index();
2067
+ init_status();
2068
+ init_util();
1756
2069
  import path7 from "node:path";
1757
2070
  var ACTIVE_RUN_STATUSES = /* @__PURE__ */ new Set([
1758
2071
  "running",
@@ -1810,33 +2123,12 @@ function finalizeStaleRuns() {
1810
2123
  return finalized;
1811
2124
  }
1812
2125
 
1813
- // src/cleanup-worktree-salvage.ts
1814
- function prUrlFromFinalResult(finalResult) {
1815
- if (typeof finalResult === "string") {
1816
- const match = finalResult.match(/https:\/\/github\.com\/[^\s]+\/pull\/\d+/i);
1817
- return match?.[0] ?? null;
1818
- }
1819
- if (finalResult && typeof finalResult === "object") {
1820
- const obj = finalResult;
1821
- for (const key of ["prUrl", "pr_url", "pullRequestUrl"]) {
1822
- const value = obj[key];
1823
- if (typeof value === "string" && value.trim()) return value.trim();
1824
- }
1825
- }
1826
- return null;
1827
- }
1828
- function isPrOrUnmergedWork(status) {
1829
- const relation = status.gitAncestry?.relation;
1830
- if (relation === "merged" || relation === "synced") {
1831
- return materialWorktreeChanges(status.changedFiles).length > 0;
1832
- }
1833
- if (prUrlFromFinalResult(status.finalResult)) return true;
1834
- if (relation === "ahead" || relation === "diverged") return true;
1835
- if (status.changedFiles.length > 0 && status.finalResult) return true;
1836
- return false;
1837
- }
2126
+ // src/cleanup-run-liveness.ts
2127
+ init_status();
1838
2128
 
1839
2129
  // src/cleanup-completion-blocker.ts
2130
+ init_landing_gate();
2131
+ init_status();
1840
2132
  function completionBlockerBlocksWorktreeRemoval(indexed, status) {
1841
2133
  const blocker = typeof indexed.worker.completionBlocker === "string" ? indexed.worker.completionBlocker.trim() : "";
1842
2134
  if (!blocker) return false;
@@ -1856,13 +2148,29 @@ function completionBlockerBlocksWorktreeRemoval(indexed, status) {
1856
2148
  }
1857
2149
 
1858
2150
  // src/cleanup-run-liveness.ts
2151
+ init_util();
2152
+ var TERMINAL_WORKER_JSON_STATUSES = /* @__PURE__ */ new Set([
2153
+ "done",
2154
+ "exited",
2155
+ "blocked",
2156
+ "failed",
2157
+ "abandoned"
2158
+ ]);
1859
2159
  function deriveRunTerminal(indexed, ctx) {
1860
2160
  if (ctx) return ctx.runTerminalCache.derive(indexed.run);
1861
2161
  return deriveTerminalRunStatus(indexed.run);
1862
2162
  }
1863
2163
  function isWorkerProcessLive(indexed) {
1864
2164
  if (isPidAlive(indexed.worker.pid)) return true;
1865
- if (!indexed.worker.pid) return indexedWorktreeStatus(indexed).alive;
2165
+ if (typeof indexed.worker.completionReportedAt === "string" && indexed.worker.completionReportedAt.trim().length > 0) {
2166
+ return false;
2167
+ }
2168
+ const workerStatus = indexed.worker.status;
2169
+ if (workerStatus && TERMINAL_WORKER_JSON_STATUSES.has(workerStatus)) return false;
2170
+ if (!indexed.worker.pid) {
2171
+ if (workerStatus !== "running") return false;
2172
+ return indexedWorktreeStatus(indexed).alive;
2173
+ }
1866
2174
  return false;
1867
2175
  }
1868
2176
  function isRunStaleActive(indexed, ctx) {
@@ -1871,6 +2179,10 @@ function isRunStaleActive(indexed, ctx) {
1871
2179
  }
1872
2180
  function runBlocksWorktreeRemoval(indexed, ctx) {
1873
2181
  if (isWorkerProcessLive(indexed)) return true;
2182
+ const workerStatus = indexed.worker.status;
2183
+ if (workerStatus && TERMINAL_WORKER_JSON_STATUSES.has(workerStatus) && !indexed.worker.completionBlocker) {
2184
+ return false;
2185
+ }
1874
2186
  const status = indexedWorktreeStatus(indexed);
1875
2187
  if (completionBlockerBlocksWorktreeRemoval(indexed, status)) return true;
1876
2188
  if (isFinishedWorkerStatus(status)) return false;
@@ -1889,7 +2201,7 @@ function effectiveWorktreeAgeMs(input) {
1889
2201
  if (input.liveness && isRunStaleActive(indexed, input.liveness)) {
1890
2202
  return terminalWorktreesAgeMs;
1891
2203
  }
1892
- if (input.liveness && isFinishedWorkerStatus(indexedWorktreeStatus(indexed)) && !isWorkerProcessLive(indexed)) {
2204
+ if (input.liveness && isFinishedWorkerStatus(resolveWorktreeGuardStatus(indexed, input.liveness)) && !isWorkerProcessLive(indexed)) {
1893
2205
  return terminalWorktreesAgeMs;
1894
2206
  }
1895
2207
  return worktreesAgeMs;
@@ -1903,8 +2215,13 @@ function skipWorktreeRemoval(input) {
1903
2215
  const ageThresholdMs = effectiveWorktreeAgeMs(input);
1904
2216
  if (worktreesAgeMs <= 0 && !includeOrphans && ageThresholdMs <= 0) return "worktrees_disabled";
1905
2217
  if (ageThresholdMs > 0 && ageMs < ageThresholdMs) return "below_age_threshold";
1906
- const status = indexedWorktreeStatus(indexed);
1907
2218
  if (isWorkerProcessLive(indexed)) return "active_worker";
2219
+ if (indexedWorktreeHasMaterialChanges(indexed, input.liveness?.gitStatusCache)) {
2220
+ return "dirty_worktree";
2221
+ }
2222
+ const ahead = input.liveness?.gitRevCache?.countAheadOfMain(input.worktreePath);
2223
+ if (ahead !== null && ahead !== void 0 && ahead > 0) return "pr_or_unmerged_commits";
2224
+ const status = resolveWorktreeGuardStatus(indexed, input.liveness);
1908
2225
  if (completionBlockerBlocksWorktreeRemoval(indexed, status)) return "completion_blocked";
1909
2226
  if (runBlocksWorktreeRemoval(indexed, input.liveness)) return "run_still_active";
1910
2227
  if (!isFinishedWorkerStatus(status)) return "run_still_active";
@@ -1935,7 +2252,9 @@ function skipDependencyCacheRemoval(input) {
1935
2252
  if (!diskPressure && ageMs < nodeModulesAgeMs) return "below_age_threshold";
1936
2253
  if (activeWorktreePaths.has(path8.resolve(worktreePath))) return "active_worker";
1937
2254
  if (indexed && isWorkerProcessLive(indexed)) return "active_worker";
1938
- if (indexed && indexedWorktreeHasMaterialChanges(indexed)) return "dirty_worktree";
2255
+ if (indexed && indexedWorktreeHasMaterialChanges(indexed, input.gitStatusCache)) {
2256
+ return "dirty_worktree";
2257
+ }
1939
2258
  return null;
1940
2259
  }
1941
2260
  function skipBuildCacheRemoval(input) {
@@ -1983,6 +2302,8 @@ import { existsSync as existsSync11, readdirSync as readdirSync6, statSync as st
1983
2302
  import path12 from "node:path";
1984
2303
 
1985
2304
  // src/cleanup-active-worktrees.ts
2305
+ init_run_store();
2306
+ init_paths();
1986
2307
  import { existsSync as existsSync10, readdirSync as readdirSync5, statSync as statSync4 } from "node:fs";
1987
2308
  import path11 from "node:path";
1988
2309
 
@@ -1990,7 +2311,19 @@ import path11 from "node:path";
1990
2311
  import { existsSync as existsSync9, readdirSync as readdirSync4, statSync as statSync3 } from "node:fs";
1991
2312
  import path10 from "node:path";
1992
2313
 
2314
+ // src/default-repo.ts
2315
+ init_config();
2316
+ init_default_repo_discovery();
2317
+ init_path_values();
2318
+
2319
+ // src/run-metadata-retention.ts
2320
+ init_heartbeat();
2321
+ init_paths();
2322
+ init_run_store();
2323
+
1993
2324
  // src/worker-metadata-paths.ts
2325
+ init_paths();
2326
+ init_util();
1994
2327
  import path9 from "node:path";
1995
2328
  var NESTED_RUNS = `${path9.sep}runs${path9.sep}runs${path9.sep}`;
1996
2329
  function workerArtifactPaths(workerDir) {
@@ -2004,6 +2337,7 @@ function workerArtifactPaths(workerDir) {
2004
2337
  }
2005
2338
 
2006
2339
  // src/run-metadata-retention.ts
2340
+ init_util();
2007
2341
  var RUN_METADATA_ACTIVE_SIGNAL_MS = 15 * 60 * 1e3;
2008
2342
  function isHarnessRunMetadataPath(targetPath, harnessRoot) {
2009
2343
  const resolved = path10.resolve(targetPath);
@@ -2075,6 +2409,7 @@ function collectFilesystemLiveRunKeys(harnessRoot, now = Date.now()) {
2075
2409
  }
2076
2410
 
2077
2411
  // src/cleanup-active-worktrees.ts
2412
+ init_util();
2078
2413
  function workerHasRecentHarnessActivity(worker, now) {
2079
2414
  const paths = [worker.heartbeatPath, worker.stdoutPath, worker.stderrPath];
2080
2415
  for (const target of paths) {
@@ -2123,6 +2458,7 @@ function isWorktreeOnLiveRun(worktreePath, harnessRoot, runId, liveRunKeys) {
2123
2458
  }
2124
2459
 
2125
2460
  // src/cleanup-run-directory.ts
2461
+ init_util();
2126
2462
  function pathAgeMs(target, now) {
2127
2463
  try {
2128
2464
  const mtime = statSync5(target).mtimeMs;
@@ -2185,6 +2521,7 @@ function scanStaleRunDirectoryCandidates(opts) {
2185
2521
  }
2186
2522
 
2187
2523
  // src/cleanup-execute.ts
2524
+ init_git();
2188
2525
  import { existsSync as existsSync14, rmSync as rmSync2 } from "node:fs";
2189
2526
 
2190
2527
  // src/cleanup-dir-size.ts
@@ -2240,6 +2577,7 @@ function directorySizeBytes(root, maxEntries = 5e4) {
2240
2577
 
2241
2578
  // src/cleanup-remove-path.ts
2242
2579
  import { existsSync as existsSync13, rmSync } from "node:fs";
2580
+ init_paths();
2243
2581
 
2244
2582
  // src/cleanup-path-ownership.ts
2245
2583
  import { lstatSync, readdirSync as readdirSync8 } from "node:fs";
@@ -2748,6 +3086,7 @@ function scanDependencyCacheCandidates(opts) {
2748
3086
  }
2749
3087
 
2750
3088
  // src/cleanup-duplicate-worktrees.ts
3089
+ init_git();
2751
3090
  import { existsSync as existsSync17, statSync as statSync9 } from "node:fs";
2752
3091
  import path18 from "node:path";
2753
3092
  function pathAgeMs4(target, now) {
@@ -2840,6 +3179,8 @@ function scanDuplicateWorktreeCandidates(opts) {
2840
3179
  }
2841
3180
 
2842
3181
  // src/cleanup-worktree-index.ts
3182
+ init_run_store();
3183
+ init_util();
2843
3184
  import path19 from "node:path";
2844
3185
  function buildWorktreeIndexAt(harnessRoot) {
2845
3186
  const index = /* @__PURE__ */ new Map();
@@ -2910,6 +3251,7 @@ function resolveHarnessRetention(options = {}) {
2910
3251
  }
2911
3252
 
2912
3253
  // src/cleanup-orphan-safety.ts
3254
+ init_git();
2913
3255
  import { existsSync as existsSync18, statSync as statSync10 } from "node:fs";
2914
3256
  import path20 from "node:path";
2915
3257
  var DEFAULT_HEARTBEAT_FRESH_MS = 30 * 60 * 1e3;
@@ -2962,6 +3304,7 @@ function assessOrphanWorktreeSafety(input) {
2962
3304
  }
2963
3305
 
2964
3306
  // src/harness-storage-snapshot.ts
3307
+ init_paths();
2965
3308
  import { existsSync as existsSync19, readdirSync as readdirSync11, statSync as statSync11 } from "node:fs";
2966
3309
  import path21 from "node:path";
2967
3310
  function harnessStorageSnapshot(opts = {}) {
@@ -3036,6 +3379,7 @@ function harnessStorageSnapshot(opts = {}) {
3036
3379
  }
3037
3380
 
3038
3381
  // src/cleanup-harness-roots.ts
3382
+ init_paths();
3039
3383
  import { existsSync as existsSync20 } from "node:fs";
3040
3384
  import { homedir as homedir4 } from "node:os";
3041
3385
  import path22 from "node:path";
@@ -3071,6 +3415,7 @@ function resolveHarnessScanRoots(options = {}) {
3071
3415
  }
3072
3416
 
3073
3417
  // src/cleanup-disk-pressure.ts
3418
+ init_disk_gate();
3074
3419
  function envFlag2(name) {
3075
3420
  const v = process.env[name];
3076
3421
  return v === "1" || v === "true" || v === "yes";
@@ -3119,6 +3464,39 @@ function emitCleanupProgress(phase, detail) {
3119
3464
  console.error(`[kynver cleanup] ${phase}${suffix}`);
3120
3465
  }
3121
3466
 
3467
+ // src/cleanup-git-rev-cache.ts
3468
+ init_git();
3469
+ var CleanupGitRevCache = class {
3470
+ aheadOfMain = /* @__PURE__ */ new Map();
3471
+ countAheadOfMain(worktreePath, base = "origin/main") {
3472
+ const key = `${worktreePath}\0${base}`;
3473
+ if (this.aheadOfMain.has(key)) return this.aheadOfMain.get(key) ?? null;
3474
+ const result = gitCapture(worktreePath, ["rev-list", "--count", `${base}..HEAD`]);
3475
+ if (result.status !== 0) {
3476
+ this.aheadOfMain.set(key, null);
3477
+ return null;
3478
+ }
3479
+ const count = Number(result.stdout.trim());
3480
+ const parsed = Number.isFinite(count) ? count : null;
3481
+ this.aheadOfMain.set(key, parsed);
3482
+ return parsed;
3483
+ }
3484
+ };
3485
+
3486
+ // src/cleanup-git-status-cache.ts
3487
+ init_git();
3488
+ var CleanupGitStatusCache = class {
3489
+ cache = /* @__PURE__ */ new Map();
3490
+ porcelain(worktreePath) {
3491
+ const resolved = worktreePath;
3492
+ const cached = this.cache.get(resolved);
3493
+ if (cached !== void 0) return cached;
3494
+ const lines = gitStatusShort(resolved);
3495
+ this.cache.set(resolved, lines);
3496
+ return lines;
3497
+ }
3498
+ };
3499
+
3122
3500
  // src/cleanup-run-terminal-cache.ts
3123
3501
  var CleanupRunTerminalCache = class {
3124
3502
  cache = /* @__PURE__ */ new Map();
@@ -3236,7 +3614,11 @@ function runHarnessCleanup(options = {}) {
3236
3614
  emitCleanupProgress("index", "building worktree index");
3237
3615
  const index = mergeWorktreeIndexes(paths.scanRoots);
3238
3616
  emitCleanupProgress("index", `${index.size} indexed worktree(s)`);
3239
- const liveness = { runTerminalCache: new CleanupRunTerminalCache() };
3617
+ const liveness = {
3618
+ runTerminalCache: new CleanupRunTerminalCache(),
3619
+ gitStatusCache: new CleanupGitStatusCache(),
3620
+ gitRevCache: new CleanupGitRevCache()
3621
+ };
3240
3622
  const skips = [];
3241
3623
  const actions = [];
3242
3624
  const processedPaths = /* @__PURE__ */ new Set();
@@ -3256,8 +3638,15 @@ function runHarnessCleanup(options = {}) {
3256
3638
  index,
3257
3639
  now: paths.now
3258
3640
  };
3259
- for (const raw of scanDependencyCacheCandidates(scanOpts)) {
3641
+ const dependencyCandidates = scanDependencyCacheCandidates(scanOpts);
3642
+ emitCleanupProgress("dependency", `${dependencyCandidates.length} cache candidate(s) at ${harnessRoot}`);
3643
+ let dependencyProcessed = 0;
3644
+ for (const raw of dependencyCandidates) {
3260
3645
  if (atSweepCap()) break;
3646
+ dependencyProcessed += 1;
3647
+ if (dependencyProcessed % 50 === 0) {
3648
+ emitCleanupProgress("dependency", `${dependencyProcessed}/${dependencyCandidates.length} evaluated`);
3649
+ }
3261
3650
  const resolved = path23.resolve(raw.path);
3262
3651
  if (processedPaths.has(resolved)) continue;
3263
3652
  processedPaths.add(resolved);
@@ -3277,7 +3666,8 @@ function runHarnessCleanup(options = {}) {
3277
3666
  ageMs: candidate.ageMs,
3278
3667
  worktreePath,
3279
3668
  activeWorktreePaths: activeGuards.activeWorktreePaths,
3280
- diskPressure: retention.diskPressure
3669
+ diskPressure: retention.diskPressure,
3670
+ gitStatusCache: liveness.gitStatusCache
3281
3671
  });
3282
3672
  if (guardReason) {
3283
3673
  recordSkip(skips, candidate.path, guardReason);
@@ -3312,7 +3702,8 @@ function runHarnessCleanup(options = {}) {
3312
3702
  ageMs: candidate.ageMs,
3313
3703
  worktreePath,
3314
3704
  activeWorktreePaths: activeGuards.activeWorktreePaths,
3315
- diskPressure: retention.diskPressure
3705
+ diskPressure: retention.diskPressure,
3706
+ gitStatusCache: liveness.gitStatusCache
3316
3707
  });
3317
3708
  if (guardReason) {
3318
3709
  recordSkip(skips, candidate.path, guardReason);
@@ -3332,8 +3723,13 @@ function runHarnessCleanup(options = {}) {
3332
3723
  ];
3333
3724
  emitCleanupProgress("worktrees", `${worktreeCandidates.length} candidate(s) at ${harnessRoot}`);
3334
3725
  const worktreeSeen = /* @__PURE__ */ new Set();
3726
+ let worktreeProcessed = 0;
3335
3727
  for (const raw of worktreeCandidates) {
3336
3728
  if (atSweepCap()) break;
3729
+ worktreeProcessed += 1;
3730
+ if (worktreeProcessed % 50 === 0) {
3731
+ emitCleanupProgress("worktrees", `${worktreeProcessed}/${worktreeCandidates.length} evaluated`);
3732
+ }
3337
3733
  const resolved = path23.resolve(raw.path);
3338
3734
  if (worktreeSeen.has(resolved)) continue;
3339
3735
  worktreeSeen.add(resolved);