@kynver-app/runtime 0.1.11 → 0.1.13
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 +114 -36
- package/dist/cli.js.map +4 -4
- package/dist/index.js +114 -36
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -381,12 +381,12 @@ var DEFAULT_CRITICAL_FREE_BYTES = 15 * 1024 * 1024 * 1024;
|
|
|
381
381
|
var DEFAULT_MAX_USED_PERCENT = 80;
|
|
382
382
|
var DEFAULT_HARD_MAX_USED_PERCENT = 90;
|
|
383
383
|
function observeRunnerDiskGate(input = {}) {
|
|
384
|
-
const
|
|
384
|
+
const path15 = input.diskPath?.trim() || "/";
|
|
385
385
|
const warnBelowBytes = input.diskFreeWarnBytes ?? DEFAULT_WARN_FREE_BYTES;
|
|
386
386
|
const criticalBelowBytes = input.diskFreeCriticalBytes ?? DEFAULT_CRITICAL_FREE_BYTES;
|
|
387
387
|
const maxUsedPercent = input.diskMaxUsedPercent ?? DEFAULT_MAX_USED_PERCENT;
|
|
388
388
|
const hardMaxUsedPercent = input.diskHardMaxUsedPercent ?? DEFAULT_HARD_MAX_USED_PERCENT;
|
|
389
|
-
const stats = statfsSync(
|
|
389
|
+
const stats = statfsSync(path15);
|
|
390
390
|
const freeBytes = Number(stats.bavail) * Number(stats.bsize);
|
|
391
391
|
const totalBytes = Number(stats.blocks) * Number(stats.bsize);
|
|
392
392
|
const usedPercent = totalBytes > 0 ? (totalBytes - freeBytes) / totalBytes * 100 : 100;
|
|
@@ -406,7 +406,7 @@ function observeRunnerDiskGate(input = {}) {
|
|
|
406
406
|
}
|
|
407
407
|
return {
|
|
408
408
|
ok,
|
|
409
|
-
path:
|
|
409
|
+
path: path15,
|
|
410
410
|
freeBytes,
|
|
411
411
|
totalBytes,
|
|
412
412
|
usedPercent,
|
|
@@ -419,10 +419,12 @@ function observeRunnerDiskGate(input = {}) {
|
|
|
419
419
|
}
|
|
420
420
|
|
|
421
421
|
// src/resource-gate.ts
|
|
422
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
422
423
|
import os from "node:os";
|
|
423
424
|
import path5 from "node:path";
|
|
424
425
|
|
|
425
426
|
// src/run-store.ts
|
|
427
|
+
import { existsSync as existsSync4, readdirSync as readdirSync2 } from "node:fs";
|
|
426
428
|
import path4 from "node:path";
|
|
427
429
|
|
|
428
430
|
// src/paths.ts
|
|
@@ -458,6 +460,20 @@ function loadRun(id) {
|
|
|
458
460
|
const { runsDir } = getPaths();
|
|
459
461
|
return readJson(path4.join(runDir(runsDir, safeSlug(id)), "run.json"));
|
|
460
462
|
}
|
|
463
|
+
function listRunRecords() {
|
|
464
|
+
const { runsDir } = getPaths();
|
|
465
|
+
if (!existsSync4(runsDir)) return [];
|
|
466
|
+
const runs = [];
|
|
467
|
+
for (const entry of readdirSync2(runsDir, { withFileTypes: true })) {
|
|
468
|
+
if (!entry.isDirectory()) continue;
|
|
469
|
+
const run = readJson(
|
|
470
|
+
path4.join(runsDir, entry.name, "run.json"),
|
|
471
|
+
void 0
|
|
472
|
+
);
|
|
473
|
+
if (run?.id) runs.push(run);
|
|
474
|
+
}
|
|
475
|
+
return runs;
|
|
476
|
+
}
|
|
461
477
|
function loadWorker(runId, name) {
|
|
462
478
|
const { runsDir } = getPaths();
|
|
463
479
|
return readJson(
|
|
@@ -478,7 +494,7 @@ function runDirectory(id) {
|
|
|
478
494
|
}
|
|
479
495
|
|
|
480
496
|
// src/heartbeat.ts
|
|
481
|
-
import { existsSync as
|
|
497
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
|
|
482
498
|
function parseHeartbeat(file) {
|
|
483
499
|
const result = {
|
|
484
500
|
heartbeatCount: 0,
|
|
@@ -487,7 +503,7 @@ function parseHeartbeat(file) {
|
|
|
487
503
|
lastHeartbeatSummary: null,
|
|
488
504
|
heartbeatBlocker: null
|
|
489
505
|
};
|
|
490
|
-
if (!
|
|
506
|
+
if (!existsSync5(file)) return result;
|
|
491
507
|
const lines = readFileSync3(file, "utf8").split("\n").filter(Boolean);
|
|
492
508
|
for (const line of lines) {
|
|
493
509
|
const entry = safeJson(line);
|
|
@@ -503,7 +519,7 @@ function parseHeartbeat(file) {
|
|
|
503
519
|
}
|
|
504
520
|
|
|
505
521
|
// src/stream.ts
|
|
506
|
-
import { existsSync as
|
|
522
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "node:fs";
|
|
507
523
|
function parseClaudeStream(file) {
|
|
508
524
|
const result = {
|
|
509
525
|
firstEventAt: null,
|
|
@@ -512,7 +528,7 @@ function parseClaudeStream(file) {
|
|
|
512
528
|
finalResult: null,
|
|
513
529
|
error: null
|
|
514
530
|
};
|
|
515
|
-
if (!
|
|
531
|
+
if (!existsSync6(file)) return result;
|
|
516
532
|
const lines = readFileSync4(file, "utf8").split("\n").filter(Boolean);
|
|
517
533
|
for (const line of lines) {
|
|
518
534
|
const event = safeJson(line);
|
|
@@ -805,13 +821,23 @@ function computeAutoMaxWorkers(totalMemBytes, opts = {}) {
|
|
|
805
821
|
const raw = Math.max(1, Math.floor(budgetBytes / perWorkerMemBytes));
|
|
806
822
|
return Math.min(raw, AUTO_MAX_WORKERS_CEILING);
|
|
807
823
|
}
|
|
808
|
-
function
|
|
809
|
-
|
|
824
|
+
function readAvailableMemBytes() {
|
|
825
|
+
if (process.platform === "linux") {
|
|
826
|
+
try {
|
|
827
|
+
const meminfo = readFileSync5("/proc/meminfo", "utf8");
|
|
828
|
+
const match = meminfo.match(/^MemAvailable:\s+(\d+)\s*kB/m);
|
|
829
|
+
if (match) return Number(match[1]) * 1024;
|
|
830
|
+
} catch {
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
return os.freemem();
|
|
834
|
+
}
|
|
835
|
+
function countActiveWorkersForRun(run) {
|
|
810
836
|
let active = 0;
|
|
811
837
|
for (const name of Object.keys(run.workers || {})) {
|
|
812
838
|
const worker = readJson(
|
|
813
839
|
path5.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
|
|
814
|
-
|
|
840
|
+
void 0
|
|
815
841
|
);
|
|
816
842
|
if (!worker) continue;
|
|
817
843
|
const status = computeWorkerStatus(worker);
|
|
@@ -821,14 +847,19 @@ function countActiveWorkers(runId) {
|
|
|
821
847
|
}
|
|
822
848
|
return active;
|
|
823
849
|
}
|
|
850
|
+
function countActiveWorkersGlobal() {
|
|
851
|
+
let active = 0;
|
|
852
|
+
for (const run of listRunRecords()) active += countActiveWorkersForRun(run);
|
|
853
|
+
return active;
|
|
854
|
+
}
|
|
824
855
|
function observeRunnerResourceGate(input) {
|
|
825
856
|
const { perWorkerMemBytes, memReserveBytes, memUtilization, configuredMaxWorkers } = resolveResourceConfig(
|
|
826
857
|
input.config,
|
|
827
858
|
input.configuredMaxWorkersOverride
|
|
828
859
|
);
|
|
829
860
|
const totalMemBytes = input.totalMemBytes ?? os.totalmem();
|
|
830
|
-
const freeMemBytes = input.freeMemBytes ??
|
|
831
|
-
const activeWorkers = input.activeWorkers ??
|
|
861
|
+
const freeMemBytes = input.freeMemBytes ?? readAvailableMemBytes();
|
|
862
|
+
const activeWorkers = input.activeWorkers ?? countActiveWorkersGlobal();
|
|
832
863
|
const budgetBytes = Math.max(0, Math.floor(totalMemBytes * memUtilization) - memReserveBytes);
|
|
833
864
|
const capacityFromTotal = Math.max(0, Math.floor(budgetBytes / perWorkerMemBytes));
|
|
834
865
|
const capacityFromFree = Math.max(0, Math.floor(Math.max(0, freeMemBytes - memReserveBytes) / perWorkerMemBytes));
|
|
@@ -836,13 +867,13 @@ function observeRunnerResourceGate(input) {
|
|
|
836
867
|
const targetCap = configuredMaxWorkers ?? autoCap;
|
|
837
868
|
const maxConcurrentWorkers = Math.max(0, Math.min(targetCap, capacityFromTotal));
|
|
838
869
|
const slotsByCapacity = Math.max(0, maxConcurrentWorkers - activeWorkers);
|
|
839
|
-
const slotsByFreeMem =
|
|
870
|
+
const slotsByFreeMem = capacityFromFree;
|
|
840
871
|
const slotsAvailable = Math.min(slotsByCapacity, slotsByFreeMem);
|
|
841
872
|
let reason = null;
|
|
842
873
|
if (slotsAvailable <= 0) {
|
|
843
874
|
if (activeWorkers >= maxConcurrentWorkers) {
|
|
844
875
|
reason = `at worker limit (${activeWorkers}/${maxConcurrentWorkers} running)`;
|
|
845
|
-
} else if (capacityFromFree <=
|
|
876
|
+
} else if (capacityFromFree <= 0) {
|
|
846
877
|
reason = "insufficient free memory \u2014 waiting for workers to finish";
|
|
847
878
|
} else {
|
|
848
879
|
reason = "no worker slots available";
|
|
@@ -865,7 +896,7 @@ function observeRunnerResourceGate(input) {
|
|
|
865
896
|
}
|
|
866
897
|
|
|
867
898
|
// src/supervisor.ts
|
|
868
|
-
import { existsSync as
|
|
899
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3 } from "node:fs";
|
|
869
900
|
import path7 from "node:path";
|
|
870
901
|
|
|
871
902
|
// src/prompt.ts
|
|
@@ -938,19 +969,19 @@ var claudeProvider = {
|
|
|
938
969
|
};
|
|
939
970
|
|
|
940
971
|
// src/providers/cursor.ts
|
|
941
|
-
import { closeSync as closeSync2, existsSync as
|
|
972
|
+
import { closeSync as closeSync2, existsSync as existsSync7, openSync as openSync2, readdirSync as readdirSync3 } from "node:fs";
|
|
942
973
|
import { spawn as spawn2 } from "node:child_process";
|
|
943
974
|
import path6 from "node:path";
|
|
944
975
|
var DEFAULT_CURSOR_MODEL = "composer-2.5";
|
|
945
976
|
function latestVersionDir(versionsRoot) {
|
|
946
|
-
if (!
|
|
947
|
-
const versions =
|
|
977
|
+
if (!existsSync7(versionsRoot)) return null;
|
|
978
|
+
const versions = readdirSync3(versionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && /^\d{4}\.\d/.test(entry.name)).map((entry) => entry.name).sort((a, b) => b.localeCompare(a));
|
|
948
979
|
return versions[0] ? path6.join(versionsRoot, versions[0]) : null;
|
|
949
980
|
}
|
|
950
981
|
function resolveBundledCursor(versionDir) {
|
|
951
982
|
const nodeExe = path6.join(versionDir, "node.exe");
|
|
952
983
|
const indexJs = path6.join(versionDir, "index.js");
|
|
953
|
-
if (!
|
|
984
|
+
if (!existsSync7(nodeExe) || !existsSync7(indexJs)) return null;
|
|
954
985
|
return { executable: nodeExe, prefixArgs: [indexJs], shell: false, detached: true };
|
|
955
986
|
}
|
|
956
987
|
function resolveWindowsCursorSpawn(agentBin) {
|
|
@@ -973,7 +1004,7 @@ function resolveAgentBin() {
|
|
|
973
1004
|
if (configured) return configured;
|
|
974
1005
|
if (process.platform === "win32") {
|
|
975
1006
|
const localAgent = path6.join(process.env.LOCALAPPDATA || "", "cursor-agent", "agent.cmd");
|
|
976
|
-
if (
|
|
1007
|
+
if (existsSync7(localAgent)) return localAgent;
|
|
977
1008
|
}
|
|
978
1009
|
return "agent";
|
|
979
1010
|
}
|
|
@@ -1042,8 +1073,11 @@ function resolveWorkerProvider(name) {
|
|
|
1042
1073
|
|
|
1043
1074
|
// src/supervisor.ts
|
|
1044
1075
|
function spawnWorkerProcess(run, opts) {
|
|
1045
|
-
const
|
|
1046
|
-
if (!
|
|
1076
|
+
const rawName = typeof opts.name === "string" ? opts.name.trim() : "";
|
|
1077
|
+
if (!rawName || rawName === "undefined" || rawName === "null") {
|
|
1078
|
+
throw new Error(`worker name is required and must be a real identifier (got: ${JSON.stringify(opts.name)})`);
|
|
1079
|
+
}
|
|
1080
|
+
const name = safeSlug(rawName);
|
|
1047
1081
|
if (run.workers?.[name]) throw new Error(`worker already exists in run ${run.id}: ${name}`);
|
|
1048
1082
|
if (!opts.task) throw new Error(`missing task text for worker ${name}`);
|
|
1049
1083
|
const { worktreesDir } = getPaths();
|
|
@@ -1051,7 +1085,7 @@ function spawnWorkerProcess(run, opts) {
|
|
|
1051
1085
|
mkdirSync3(workerDir, { recursive: true });
|
|
1052
1086
|
const worktreePath = path7.join(worktreesDir, run.id, name);
|
|
1053
1087
|
const branch = opts.branch || `agent/${run.id}/${name}`;
|
|
1054
|
-
if (
|
|
1088
|
+
if (existsSync8(worktreePath)) throw new Error(`worktree path already exists: ${worktreePath}`);
|
|
1055
1089
|
git(run.repo, ["fetch", "origin", "--prune"], { allowFailure: true });
|
|
1056
1090
|
git(run.repo, ["worktree", "add", "-b", branch, worktreePath, run.baseCommit], { throwError: true });
|
|
1057
1091
|
const stdoutPath = path7.join(workerDir, "stdout.jsonl");
|
|
@@ -1113,6 +1147,11 @@ function spawnWorkerProcess(run, opts) {
|
|
|
1113
1147
|
}
|
|
1114
1148
|
function startWorker(args) {
|
|
1115
1149
|
const run = loadRun(String(args.run));
|
|
1150
|
+
const name = typeof args.name === "string" ? args.name.trim() : "";
|
|
1151
|
+
if (!name) {
|
|
1152
|
+
console.error("worker start failed: --name is required");
|
|
1153
|
+
process.exit(1);
|
|
1154
|
+
}
|
|
1116
1155
|
const task = args.task ? String(args.task) : readMaybeFile(args.taskFile ? String(args.taskFile) : void 0);
|
|
1117
1156
|
if (!task) {
|
|
1118
1157
|
console.error("missing --task or --task-file");
|
|
@@ -1120,7 +1159,7 @@ function startWorker(args) {
|
|
|
1120
1159
|
}
|
|
1121
1160
|
try {
|
|
1122
1161
|
const worker = spawnWorkerProcess(run, {
|
|
1123
|
-
name
|
|
1162
|
+
name,
|
|
1124
1163
|
task,
|
|
1125
1164
|
ownedPaths: args.owned ? String(args.owned).split(",").map((s) => s.trim()).filter(Boolean) : [],
|
|
1126
1165
|
model: args.model ? String(args.model) : void 0,
|
|
@@ -1347,14 +1386,14 @@ function validateTailLines(lines) {
|
|
|
1347
1386
|
}
|
|
1348
1387
|
|
|
1349
1388
|
// src/worktree.ts
|
|
1350
|
-
import { existsSync as
|
|
1389
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4 } from "node:fs";
|
|
1351
1390
|
import path9 from "node:path";
|
|
1352
1391
|
function createRun(args) {
|
|
1353
1392
|
const repo = validateRepo(required(String(args.repo || ""), "--repo"));
|
|
1354
1393
|
ensureGitRepo(repo);
|
|
1355
1394
|
const id = args.id ? validateRunId(String(args.id)) : timestampSlug(String(args.name || "run"));
|
|
1356
1395
|
const dir = runDirectory(id);
|
|
1357
|
-
if (
|
|
1396
|
+
if (existsSync9(dir)) failExists(`run already exists: ${id}`);
|
|
1358
1397
|
mkdirSync4(dir, { recursive: true });
|
|
1359
1398
|
const base = String(args.base || "origin/main");
|
|
1360
1399
|
const baseCommit = git(repo, ["rev-parse", base]).trim();
|
|
@@ -1373,7 +1412,7 @@ function createRun(args) {
|
|
|
1373
1412
|
}
|
|
1374
1413
|
function listRuns() {
|
|
1375
1414
|
const { runsDir } = getPaths();
|
|
1376
|
-
const rows = listRunIds(runsDir).map((id) => readJson(path9.join(runDirectory(id), "run.json"),
|
|
1415
|
+
const rows = listRunIds(runsDir).map((id) => readJson(path9.join(runDirectory(id), "run.json"), void 0)).filter(Boolean).map((run) => ({
|
|
1377
1416
|
id: run.id,
|
|
1378
1417
|
name: run.name,
|
|
1379
1418
|
status: run.status,
|
|
@@ -1401,7 +1440,7 @@ async function sweepRun(args) {
|
|
|
1401
1440
|
for (const name of Object.keys(run.workers || {})) {
|
|
1402
1441
|
const worker = readJson(
|
|
1403
1442
|
path10.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
|
|
1404
|
-
|
|
1443
|
+
void 0
|
|
1405
1444
|
);
|
|
1406
1445
|
if (!worker || !worker.dispatched || !worker.taskId) continue;
|
|
1407
1446
|
const status = computeWorkerStatus(worker);
|
|
@@ -1541,7 +1580,7 @@ function runStatus(args) {
|
|
|
1541
1580
|
const workers = names.map((name) => {
|
|
1542
1581
|
const worker = readJson(
|
|
1543
1582
|
path11.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
|
|
1544
|
-
|
|
1583
|
+
void 0
|
|
1545
1584
|
);
|
|
1546
1585
|
if (!worker) {
|
|
1547
1586
|
return { worker: name, status: "missing", attention: "needs_attention", attentionReason: "worker.json not found" };
|
|
@@ -1611,10 +1650,48 @@ import { mkdirSync as mkdirSync5, realpathSync } from "node:fs";
|
|
|
1611
1650
|
import { fileURLToPath } from "node:url";
|
|
1612
1651
|
|
|
1613
1652
|
// src/pipeline-tick.ts
|
|
1614
|
-
import
|
|
1653
|
+
import path14 from "node:path";
|
|
1615
1654
|
|
|
1616
|
-
// src/
|
|
1655
|
+
// src/finalize.ts
|
|
1617
1656
|
import path12 from "node:path";
|
|
1657
|
+
var ACTIVE_RUN_STATUSES = /* @__PURE__ */ new Set(["running", "dispatching", "pending", "queued"]);
|
|
1658
|
+
function terminalStatusFor(run) {
|
|
1659
|
+
const names = Object.keys(run.workers || {});
|
|
1660
|
+
if (names.length === 0) return "failed";
|
|
1661
|
+
let anyAlive = false;
|
|
1662
|
+
let anyResult = false;
|
|
1663
|
+
for (const name of names) {
|
|
1664
|
+
const worker = readJson(
|
|
1665
|
+
path12.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
|
|
1666
|
+
void 0
|
|
1667
|
+
);
|
|
1668
|
+
if (!worker) continue;
|
|
1669
|
+
const status = computeWorkerStatus(worker);
|
|
1670
|
+
if (status.alive && !status.finalResult) {
|
|
1671
|
+
anyAlive = true;
|
|
1672
|
+
break;
|
|
1673
|
+
}
|
|
1674
|
+
if (status.finalResult) anyResult = true;
|
|
1675
|
+
}
|
|
1676
|
+
if (anyAlive) return null;
|
|
1677
|
+
return anyResult ? "completed" : "failed";
|
|
1678
|
+
}
|
|
1679
|
+
function finalizeStaleRuns() {
|
|
1680
|
+
const finalized = [];
|
|
1681
|
+
for (const run of listRunRecords()) {
|
|
1682
|
+
if (!ACTIVE_RUN_STATUSES.has(run.status)) continue;
|
|
1683
|
+
const next = terminalStatusFor(run);
|
|
1684
|
+
if (!next || next === run.status) continue;
|
|
1685
|
+
const from = run.status;
|
|
1686
|
+
run.status = next;
|
|
1687
|
+
saveRun(run);
|
|
1688
|
+
finalized.push({ runId: run.id, from, to: next });
|
|
1689
|
+
}
|
|
1690
|
+
return finalized;
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
// src/plan-progress-daemon-sync.ts
|
|
1694
|
+
import path13 from "node:path";
|
|
1618
1695
|
|
|
1619
1696
|
// src/plan-progress-sync.ts
|
|
1620
1697
|
async function syncPlanProgress(args) {
|
|
@@ -1638,8 +1715,8 @@ async function syncActiveWorkerPlanProgress(runId, args) {
|
|
|
1638
1715
|
const outcomes = [];
|
|
1639
1716
|
for (const name of Object.keys(run.workers || {})) {
|
|
1640
1717
|
const worker = readJson(
|
|
1641
|
-
|
|
1642
|
-
|
|
1718
|
+
path13.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
|
|
1719
|
+
void 0
|
|
1643
1720
|
);
|
|
1644
1721
|
if (!worker?.dispatched || !worker.taskId) continue;
|
|
1645
1722
|
const status = computeWorkerStatus(worker);
|
|
@@ -1692,13 +1769,12 @@ async function completeFinishedWorkers(runId, args) {
|
|
|
1692
1769
|
const outcomes = [];
|
|
1693
1770
|
for (const name of Object.keys(run.workers || {})) {
|
|
1694
1771
|
const worker = readJson(
|
|
1695
|
-
|
|
1696
|
-
|
|
1772
|
+
path14.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
|
|
1773
|
+
void 0
|
|
1697
1774
|
);
|
|
1698
1775
|
if (!worker?.dispatched || !worker.taskId) continue;
|
|
1699
1776
|
const status = computeWorkerStatus(worker);
|
|
1700
1777
|
if (!isFinishedWorkerStatus(status)) continue;
|
|
1701
|
-
if (!status.finalResult) continue;
|
|
1702
1778
|
const result = await tryCompleteWorker({
|
|
1703
1779
|
run: runId,
|
|
1704
1780
|
name,
|
|
@@ -1726,6 +1802,7 @@ async function runPipelineTick(args) {
|
|
|
1726
1802
|
const agentOsId = String(required(String(args.agentOsId || ""), "--agent-os-id"));
|
|
1727
1803
|
const execute = args.execute !== false && args.execute !== "false";
|
|
1728
1804
|
runStatus({ run: runId });
|
|
1805
|
+
const finalizedStaleRuns = finalizeStaleRuns();
|
|
1729
1806
|
const completedWorkers = await completeFinishedWorkers(runId, args);
|
|
1730
1807
|
const planProgressSync = await syncActiveWorkerPlanProgress(runId, args);
|
|
1731
1808
|
const workspacePrefs = await fetchWorkspaceRuntimePreferences(agentOsId, args);
|
|
@@ -1767,6 +1844,7 @@ async function runPipelineTick(args) {
|
|
|
1767
1844
|
execute,
|
|
1768
1845
|
resourceGate,
|
|
1769
1846
|
completedWorkers,
|
|
1847
|
+
finalizedStaleRuns,
|
|
1770
1848
|
planProgressSync,
|
|
1771
1849
|
operatorTick,
|
|
1772
1850
|
sweep,
|