@kynver-app/runtime 0.1.106 → 0.1.108
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 +381 -16
- package/dist/cli.js.map +4 -4
- package/dist/index.js +383 -18
- package/dist/index.js.map +4 -4
- package/dist/landing/cli-auth.d.ts +7 -0
- package/dist/landing/land-pr-completion-post.d.ts +12 -0
- package/dist/landing/land-pr.d.ts +20 -0
- package/dist/verify-live/verify-live-prompt.d.ts +2 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7439,6 +7439,325 @@ async function releaseDispatchClaimAfterSpawnFailure(input) {
|
|
|
7439
7439
|
};
|
|
7440
7440
|
}
|
|
7441
7441
|
|
|
7442
|
+
// src/landing/land-pr.ts
|
|
7443
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
7444
|
+
|
|
7445
|
+
// src/landing/cli-auth.ts
|
|
7446
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
7447
|
+
function ensureGitHubTokenFromCliAuth() {
|
|
7448
|
+
if (process.env.GITHUB_TOKEN?.trim() || process.env.GH_TOKEN?.trim()) {
|
|
7449
|
+
return {
|
|
7450
|
+
source: "env",
|
|
7451
|
+
configured: true,
|
|
7452
|
+
reason: "GitHub token already configured in environment"
|
|
7453
|
+
};
|
|
7454
|
+
}
|
|
7455
|
+
const result = spawnSync4("gh", ["auth", "token"], {
|
|
7456
|
+
encoding: "utf8",
|
|
7457
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
7458
|
+
});
|
|
7459
|
+
if (result.status !== 0) {
|
|
7460
|
+
const reason = typeof result.stderr === "string" && result.stderr.trim() ? result.stderr.trim() : "gh auth token failed; run `gh auth login` on this machine";
|
|
7461
|
+
return { source: "missing", configured: false, reason };
|
|
7462
|
+
}
|
|
7463
|
+
const token = typeof result.stdout === "string" ? result.stdout.trim() : "";
|
|
7464
|
+
if (!token) {
|
|
7465
|
+
return {
|
|
7466
|
+
source: "missing",
|
|
7467
|
+
configured: false,
|
|
7468
|
+
reason: "gh auth token returned an empty token; run `gh auth login` on this machine"
|
|
7469
|
+
};
|
|
7470
|
+
}
|
|
7471
|
+
process.env.GH_TOKEN = token;
|
|
7472
|
+
return {
|
|
7473
|
+
source: "gh-cli",
|
|
7474
|
+
configured: true,
|
|
7475
|
+
reason: "Using local GitHub CLI auth for daemon land_pr merge"
|
|
7476
|
+
};
|
|
7477
|
+
}
|
|
7478
|
+
|
|
7479
|
+
// src/landing/land-pr.ts
|
|
7480
|
+
var SUCCESSFUL_CHECK_CONCLUSIONS = /* @__PURE__ */ new Set(["SUCCESS", "SKIPPED", "NEUTRAL"]);
|
|
7481
|
+
var READY_MERGE_STATES = /* @__PURE__ */ new Set(["CLEAN", "HAS_HOOKS"]);
|
|
7482
|
+
function repoArgs(repo) {
|
|
7483
|
+
return repo?.trim() ? ["--repo", repo.trim()] : [];
|
|
7484
|
+
}
|
|
7485
|
+
function ghJson(exec, cwd, args) {
|
|
7486
|
+
const res = exec.gh(cwd, args);
|
|
7487
|
+
if (res.status !== 0) {
|
|
7488
|
+
throw new Error(res.stderr || res.stdout || `gh ${args.join(" ")} failed`);
|
|
7489
|
+
}
|
|
7490
|
+
return JSON.parse(res.stdout || "{}");
|
|
7491
|
+
}
|
|
7492
|
+
function checkName(check3) {
|
|
7493
|
+
return typeof check3.name === "string" && check3.name || typeof check3.context === "string" && check3.context || typeof check3.workflowName === "string" && check3.workflowName || "unknown check";
|
|
7494
|
+
}
|
|
7495
|
+
function classifyChecks(statusCheckRollup) {
|
|
7496
|
+
const checks = Array.isArray(statusCheckRollup) ? statusCheckRollup : [];
|
|
7497
|
+
const pending = [];
|
|
7498
|
+
const failed = [];
|
|
7499
|
+
for (const raw of checks) {
|
|
7500
|
+
const check3 = raw && typeof raw === "object" ? raw : {};
|
|
7501
|
+
const conclusion = typeof check3.conclusion === "string" ? check3.conclusion.toUpperCase() : "";
|
|
7502
|
+
const status = typeof check3.status === "string" ? check3.status.toUpperCase() : "";
|
|
7503
|
+
const state = typeof check3.state === "string" ? check3.state.toUpperCase() : "";
|
|
7504
|
+
if (conclusion && SUCCESSFUL_CHECK_CONCLUSIONS.has(conclusion)) continue;
|
|
7505
|
+
if (conclusion) {
|
|
7506
|
+
failed.push(`${checkName(check3)}=${conclusion}`);
|
|
7507
|
+
continue;
|
|
7508
|
+
}
|
|
7509
|
+
if (state && SUCCESSFUL_CHECK_CONCLUSIONS.has(state)) continue;
|
|
7510
|
+
if (state && state !== "PENDING") {
|
|
7511
|
+
failed.push(`${checkName(check3)}=${state}`);
|
|
7512
|
+
continue;
|
|
7513
|
+
}
|
|
7514
|
+
if (state === "PENDING") {
|
|
7515
|
+
pending.push(`${checkName(check3)}=${state}`);
|
|
7516
|
+
continue;
|
|
7517
|
+
}
|
|
7518
|
+
if (status && status !== "COMPLETED") {
|
|
7519
|
+
pending.push(`${checkName(check3)}=${status}`);
|
|
7520
|
+
continue;
|
|
7521
|
+
}
|
|
7522
|
+
pending.push(`${checkName(check3)}=PENDING`);
|
|
7523
|
+
}
|
|
7524
|
+
return { pending, failed };
|
|
7525
|
+
}
|
|
7526
|
+
function vercelCheckSuccess(statusCheckRollup) {
|
|
7527
|
+
const checks = Array.isArray(statusCheckRollup) ? statusCheckRollup : [];
|
|
7528
|
+
return checks.some((raw) => {
|
|
7529
|
+
const check3 = raw && typeof raw === "object" ? raw : {};
|
|
7530
|
+
const name = typeof check3.name === "string" && check3.name || typeof check3.context === "string" && check3.context || "";
|
|
7531
|
+
const conclusion = typeof check3.conclusion === "string" ? check3.conclusion.toUpperCase() : "";
|
|
7532
|
+
const state = typeof check3.state === "string" ? check3.state.toUpperCase() : "";
|
|
7533
|
+
return /^vercel/i.test(name) && (conclusion === "SUCCESS" || state === "SUCCESS");
|
|
7534
|
+
});
|
|
7535
|
+
}
|
|
7536
|
+
var STRUCTURED_SECTION_RE = /^##\s*(test\s*plan|verification|test\s*evidence|verify)\b/im;
|
|
7537
|
+
var LOCAL_VERIFICATION_RE = /typecheck|npm run (test|build|typecheck)|vitest|tsc\b|verify-pr-local|local verify|local-verify|tests? (pass|green)|build green|node --test/i;
|
|
7538
|
+
var DOCS_TITLE_RE = /^docs[(:]/i;
|
|
7539
|
+
var DOCS_BODY_RE = /docs[- ]only|documentation only|no[- ]code change|no code changes|low[- ]risk|plan tracker only|markdown only/i;
|
|
7540
|
+
function assertVerificationEvidence(pr) {
|
|
7541
|
+
const title = typeof pr.title === "string" ? pr.title : "";
|
|
7542
|
+
const body = typeof pr.body === "string" ? pr.body : "";
|
|
7543
|
+
const docsLowRisk = DOCS_TITLE_RE.test(title) || DOCS_BODY_RE.test(body);
|
|
7544
|
+
const structuredSection = STRUCTURED_SECTION_RE.test(body);
|
|
7545
|
+
const localVerification = LOCAL_VERIFICATION_RE.test(body);
|
|
7546
|
+
const vercelOk = vercelCheckSuccess(pr.statusCheckRollup);
|
|
7547
|
+
if (docsLowRisk || structuredSection || localVerification || vercelOk) return;
|
|
7548
|
+
throw new Error(
|
|
7549
|
+
`PR #${pr.number} lacks landing verification evidence \u2014 add ## Test plan / ## Verification with local commands, Vercel preview, or docs/no-code rationale`
|
|
7550
|
+
);
|
|
7551
|
+
}
|
|
7552
|
+
function assertLandingReady(pr) {
|
|
7553
|
+
if (pr.state !== "OPEN") throw new Error(`PR #${pr.number} is ${pr.state}, not OPEN`);
|
|
7554
|
+
if (pr.isDraft) throw new Error(`PR #${pr.number} is still a draft`);
|
|
7555
|
+
if (!READY_MERGE_STATES.has(pr.mergeStateStatus)) {
|
|
7556
|
+
throw new Error(`PR #${pr.number} mergeStateStatus is ${pr.mergeStateStatus}`);
|
|
7557
|
+
}
|
|
7558
|
+
const checks = classifyChecks(pr.statusCheckRollup);
|
|
7559
|
+
if (checks.failed.length > 0) {
|
|
7560
|
+
throw new Error(`PR #${pr.number} has failing checks: ${checks.failed.join(", ")}`);
|
|
7561
|
+
}
|
|
7562
|
+
if (checks.pending.length > 0) {
|
|
7563
|
+
throw new Error(`PR #${pr.number} has pending checks: ${checks.pending.join(", ")}`);
|
|
7564
|
+
}
|
|
7565
|
+
assertVerificationEvidence(pr);
|
|
7566
|
+
}
|
|
7567
|
+
function landingReadinessError(pr) {
|
|
7568
|
+
try {
|
|
7569
|
+
assertLandingReady(pr);
|
|
7570
|
+
return null;
|
|
7571
|
+
} catch (err) {
|
|
7572
|
+
return err instanceof Error ? err.message : String(err);
|
|
7573
|
+
}
|
|
7574
|
+
}
|
|
7575
|
+
function deleteRemoteBranch(exec, cwd, repo, branch) {
|
|
7576
|
+
if (!branch?.trim()) return;
|
|
7577
|
+
const refPath = encodeURI(`heads/${branch}`);
|
|
7578
|
+
exec.gh(cwd, ["api", "-X", "DELETE", `repos/${repo}/git/refs/${refPath}`]);
|
|
7579
|
+
}
|
|
7580
|
+
function resolveRepo(exec, cwd, repo) {
|
|
7581
|
+
if (repo?.trim()) return repo.trim();
|
|
7582
|
+
const res = exec.gh(cwd, ["repo", "view", "--json", "nameWithOwner"]);
|
|
7583
|
+
if (res.status !== 0) throw new Error(res.stderr || "Could not resolve GitHub repo");
|
|
7584
|
+
const parsed = JSON.parse(res.stdout || "{}");
|
|
7585
|
+
if (!parsed.nameWithOwner) throw new Error("Could not resolve GitHub repo");
|
|
7586
|
+
return parsed.nameWithOwner;
|
|
7587
|
+
}
|
|
7588
|
+
function removeBranchWorktrees(cwd, branch) {
|
|
7589
|
+
if (!branch?.trim()) return;
|
|
7590
|
+
const list = spawnSync5("git", ["worktree", "list", "--porcelain"], {
|
|
7591
|
+
cwd,
|
|
7592
|
+
encoding: "utf8"
|
|
7593
|
+
});
|
|
7594
|
+
if (list.status !== 0) return;
|
|
7595
|
+
const lines = String(list.stdout || "").split(/\r?\n/);
|
|
7596
|
+
let currentPath = null;
|
|
7597
|
+
let currentBranch = null;
|
|
7598
|
+
for (const line of lines) {
|
|
7599
|
+
if (line.startsWith("worktree ")) {
|
|
7600
|
+
currentPath = line.slice("worktree ".length).trim();
|
|
7601
|
+
currentBranch = null;
|
|
7602
|
+
continue;
|
|
7603
|
+
}
|
|
7604
|
+
if (line.startsWith("branch ") && currentPath) {
|
|
7605
|
+
currentBranch = line.slice("branch ".length).trim();
|
|
7606
|
+
if (currentBranch.endsWith(`/${branch}`)) {
|
|
7607
|
+
spawnSync5("git", ["worktree", "remove", "--force", currentPath], {
|
|
7608
|
+
cwd,
|
|
7609
|
+
encoding: "utf8"
|
|
7610
|
+
});
|
|
7611
|
+
}
|
|
7612
|
+
}
|
|
7613
|
+
}
|
|
7614
|
+
}
|
|
7615
|
+
async function executeLandPrMerge(input) {
|
|
7616
|
+
const cwd = input.cwd ?? process.cwd();
|
|
7617
|
+
const exec = input.exec ?? defaultPrHandoffExec;
|
|
7618
|
+
const prTarget = input.prUrl.trim();
|
|
7619
|
+
if (!prTarget) throw new Error("prUrl is required");
|
|
7620
|
+
const auth = ensureGitHubTokenFromCliAuth();
|
|
7621
|
+
if (!auth.configured) {
|
|
7622
|
+
return {
|
|
7623
|
+
prUrl: prTarget,
|
|
7624
|
+
outcome: "blocked",
|
|
7625
|
+
reason: auth.reason
|
|
7626
|
+
};
|
|
7627
|
+
}
|
|
7628
|
+
const before = ghJson(exec, cwd, [
|
|
7629
|
+
"pr",
|
|
7630
|
+
"view",
|
|
7631
|
+
prTarget,
|
|
7632
|
+
...repoArgs(input.repo),
|
|
7633
|
+
"--json",
|
|
7634
|
+
[
|
|
7635
|
+
"number",
|
|
7636
|
+
"url",
|
|
7637
|
+
"title",
|
|
7638
|
+
"body",
|
|
7639
|
+
"state",
|
|
7640
|
+
"isDraft",
|
|
7641
|
+
"mergeStateStatus",
|
|
7642
|
+
"statusCheckRollup",
|
|
7643
|
+
"headRefName",
|
|
7644
|
+
"mergedAt",
|
|
7645
|
+
"mergeCommit"
|
|
7646
|
+
].join(",")
|
|
7647
|
+
]);
|
|
7648
|
+
const notReadyReason = landingReadinessError(before);
|
|
7649
|
+
if (notReadyReason) {
|
|
7650
|
+
if (input.skipNotReady) {
|
|
7651
|
+
return {
|
|
7652
|
+
prUrl: before.url || prTarget,
|
|
7653
|
+
outcome: "skipped",
|
|
7654
|
+
reason: notReadyReason
|
|
7655
|
+
};
|
|
7656
|
+
}
|
|
7657
|
+
return {
|
|
7658
|
+
prUrl: before.url || prTarget,
|
|
7659
|
+
outcome: "blocked",
|
|
7660
|
+
reason: notReadyReason
|
|
7661
|
+
};
|
|
7662
|
+
}
|
|
7663
|
+
if (input.dryRun) {
|
|
7664
|
+
return {
|
|
7665
|
+
prUrl: before.url || prTarget,
|
|
7666
|
+
outcome: "skipped",
|
|
7667
|
+
reason: "dry-run: PR is ready to merge"
|
|
7668
|
+
};
|
|
7669
|
+
}
|
|
7670
|
+
const target = String(before.number);
|
|
7671
|
+
const mergeRes = exec.gh(cwd, [
|
|
7672
|
+
"pr",
|
|
7673
|
+
"merge",
|
|
7674
|
+
target,
|
|
7675
|
+
...repoArgs(input.repo),
|
|
7676
|
+
"--squash"
|
|
7677
|
+
]);
|
|
7678
|
+
if (mergeRes.status !== 0) {
|
|
7679
|
+
return {
|
|
7680
|
+
prUrl: before.url || prTarget,
|
|
7681
|
+
outcome: "blocked",
|
|
7682
|
+
reason: mergeRes.stderr || mergeRes.stdout || "gh pr merge failed"
|
|
7683
|
+
};
|
|
7684
|
+
}
|
|
7685
|
+
const after = ghJson(exec, cwd, [
|
|
7686
|
+
"pr",
|
|
7687
|
+
"view",
|
|
7688
|
+
target,
|
|
7689
|
+
...repoArgs(input.repo),
|
|
7690
|
+
"--json",
|
|
7691
|
+
"number,url,mergedAt,mergeCommit,state"
|
|
7692
|
+
]);
|
|
7693
|
+
if (after.state !== "MERGED" && !after.mergedAt) {
|
|
7694
|
+
return {
|
|
7695
|
+
prUrl: after.url || before.url || prTarget,
|
|
7696
|
+
outcome: "blocked",
|
|
7697
|
+
reason: `PR #${after.number} did not verify as merged after gh pr merge`
|
|
7698
|
+
};
|
|
7699
|
+
}
|
|
7700
|
+
const repo = resolveRepo(exec, cwd, input.repo);
|
|
7701
|
+
deleteRemoteBranch(exec, cwd, repo, before.headRefName);
|
|
7702
|
+
removeBranchWorktrees(cwd, before.headRefName);
|
|
7703
|
+
const mergeCommit = after.mergeCommit?.oid ?? null;
|
|
7704
|
+
return {
|
|
7705
|
+
prUrl: after.url || before.url || prTarget,
|
|
7706
|
+
outcome: "merged",
|
|
7707
|
+
mergeCommit,
|
|
7708
|
+
reason: `Daemon land_pr merged PR #${after.number}`
|
|
7709
|
+
};
|
|
7710
|
+
}
|
|
7711
|
+
|
|
7712
|
+
// src/landing/land-pr-completion-post.ts
|
|
7713
|
+
async function postLandPrHarnessCompletion(input) {
|
|
7714
|
+
const secret = await resolveCallbackSecretWithMint(input.secret, input.agentOsId, {
|
|
7715
|
+
baseUrl: input.baseUrl
|
|
7716
|
+
});
|
|
7717
|
+
const taskId = String(input.task.id);
|
|
7718
|
+
const url = `${input.baseUrl}/api/agent-os/by-id/${encodeURIComponent(input.agentOsId)}/harness/completion`;
|
|
7719
|
+
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7720
|
+
const body = {
|
|
7721
|
+
source: "kynver-harness",
|
|
7722
|
+
agentOsId: input.agentOsId,
|
|
7723
|
+
runId: input.runId,
|
|
7724
|
+
workerName: `land-pr-${taskId}`,
|
|
7725
|
+
taskId,
|
|
7726
|
+
leaseToken: input.task.leaseToken ?? null,
|
|
7727
|
+
startedAt: finishedAt,
|
|
7728
|
+
finishedAt,
|
|
7729
|
+
status: {
|
|
7730
|
+
finalResult: input.report,
|
|
7731
|
+
prUrl: input.report.prUrl,
|
|
7732
|
+
summary: input.report.reason,
|
|
7733
|
+
leaseToken: input.task.leaseToken ?? null
|
|
7734
|
+
},
|
|
7735
|
+
workerInjection: null
|
|
7736
|
+
};
|
|
7737
|
+
const result = await postJsonWithCredentialRefresh(url, secret, body, {
|
|
7738
|
+
agentOsId: input.agentOsId,
|
|
7739
|
+
baseUrl: input.baseUrl
|
|
7740
|
+
});
|
|
7741
|
+
return { ok: result.ok, status: result.status };
|
|
7742
|
+
}
|
|
7743
|
+
|
|
7744
|
+
// src/verify-live/verify-live-prompt.ts
|
|
7745
|
+
function formatVerifyLiveCompletionContract() {
|
|
7746
|
+
return [
|
|
7747
|
+
"## verify_live completion contract",
|
|
7748
|
+
"Finish with a JSON finalResult object:",
|
|
7749
|
+
"{",
|
|
7750
|
+
' "prUrl": "<landed pr>",',
|
|
7751
|
+
' "outcome": "passed" | "failed" | "skipped" | "no_mcp_surface",',
|
|
7752
|
+
' "reason": "<human summary>",',
|
|
7753
|
+
' "mergeCommit": "<sha optional>",',
|
|
7754
|
+
' "mcpCalls": [{ "tool": "<name>", "ok": true, "summary": "..." }]',
|
|
7755
|
+
"}",
|
|
7756
|
+
"",
|
|
7757
|
+
"Drive the feature MCP tools against live production. Do not mark passed without exercising the MCP surface."
|
|
7758
|
+
].join("\n");
|
|
7759
|
+
}
|
|
7760
|
+
|
|
7442
7761
|
// src/dispatch.ts
|
|
7443
7762
|
var DEFAULT_DISPATCH_LEASE_MS = 60 * 60 * 1e3;
|
|
7444
7763
|
function readAdmissionExhaustion(result) {
|
|
@@ -7496,6 +7815,9 @@ function buildDispatchTaskText(task, agentOsId) {
|
|
|
7496
7815
|
`Board linkage: agentOsId=${agentOsId}, taskId=${task.id}, attempt=${task.attempt}, executor=${task.executor}${task.executorRef ? `, executorRef=${task.executorRef}` : ""}.`,
|
|
7497
7816
|
"This worker was dispatched from the AgentOS board. The harness reports your completion back to the board when you finish."
|
|
7498
7817
|
];
|
|
7818
|
+
if (task.executor === "verify_live") {
|
|
7819
|
+
lines.push("", formatVerifyLiveCompletionContract());
|
|
7820
|
+
}
|
|
7499
7821
|
const outboxRef = extractPlanOutboxFromTask(task);
|
|
7500
7822
|
if (outboxRef?.outboxId) {
|
|
7501
7823
|
const item = loadOutboxById(outboxRef.outboxId);
|
|
@@ -7529,6 +7851,12 @@ function requestedTargetTaskIds(args) {
|
|
|
7529
7851
|
async function dispatchRun(args) {
|
|
7530
7852
|
const pipeline = args.pipeline === true || args.pipeline === "true";
|
|
7531
7853
|
try {
|
|
7854
|
+
let isLandPrDecision2 = function(decision) {
|
|
7855
|
+
if (decision.landPrDispatch === true) return true;
|
|
7856
|
+
const task = decision.task;
|
|
7857
|
+
return task?.executor === "land_pr";
|
|
7858
|
+
};
|
|
7859
|
+
var isLandPrDecision = isLandPrDecision2;
|
|
7532
7860
|
const run = loadRun(String(required(String(args.run || ""), "--run")));
|
|
7533
7861
|
const agentOsId = String(required(String(args.agentOsId || ""), "--agent-os-id"));
|
|
7534
7862
|
const base = resolveBaseUrl(args.baseUrl ? String(args.baseUrl) : void 0);
|
|
@@ -7663,6 +7991,41 @@ async function dispatchRun(args) {
|
|
|
7663
7991
|
});
|
|
7664
7992
|
return false;
|
|
7665
7993
|
}
|
|
7994
|
+
async function runLandPrClaimed(decision) {
|
|
7995
|
+
const task = decision.task;
|
|
7996
|
+
const taskId = String(task.id);
|
|
7997
|
+
const prUrl = task.prUrl ? String(task.prUrl) : "";
|
|
7998
|
+
if (!prUrl) {
|
|
7999
|
+
return abortClaimedSpawn(task, "land_pr task missing prUrl");
|
|
8000
|
+
}
|
|
8001
|
+
try {
|
|
8002
|
+
const report = await executeLandPrMerge({ prUrl, cwd: process.cwd() });
|
|
8003
|
+
const post = await postLandPrHarnessCompletion({
|
|
8004
|
+
baseUrl: base,
|
|
8005
|
+
secret,
|
|
8006
|
+
agentOsId,
|
|
8007
|
+
runId: run.id,
|
|
8008
|
+
task,
|
|
8009
|
+
report
|
|
8010
|
+
});
|
|
8011
|
+
outcomes.push({
|
|
8012
|
+
taskId,
|
|
8013
|
+
started: true,
|
|
8014
|
+
landPr: true,
|
|
8015
|
+
outcome: report.outcome,
|
|
8016
|
+
completionStatus: post.status
|
|
8017
|
+
});
|
|
8018
|
+
if (!post.ok) {
|
|
8019
|
+
return abortClaimedSpawn(
|
|
8020
|
+
task,
|
|
8021
|
+
`land_pr completion POST failed (HTTP ${post.status})`
|
|
8022
|
+
);
|
|
8023
|
+
}
|
|
8024
|
+
return true;
|
|
8025
|
+
} catch (error) {
|
|
8026
|
+
return abortClaimedSpawn(task, error.message);
|
|
8027
|
+
}
|
|
8028
|
+
}
|
|
7666
8029
|
async function spawnClaimed(decision) {
|
|
7667
8030
|
const task = decision.task;
|
|
7668
8031
|
const harnessContext = readHarnessWorkerContext(decision);
|
|
@@ -7780,7 +8143,8 @@ async function dispatchRun(args) {
|
|
|
7780
8143
|
}
|
|
7781
8144
|
let shouldContinueDispatch = true;
|
|
7782
8145
|
for (const decision of result.started) {
|
|
7783
|
-
|
|
8146
|
+
const admitted = isLandPrDecision2(decision) ? await runLandPrClaimed(decision) : await spawnClaimed(decision);
|
|
8147
|
+
shouldContinueDispatch = admitted && shouldContinueDispatch;
|
|
7784
8148
|
}
|
|
7785
8149
|
skipped.push(
|
|
7786
8150
|
...result.skipped ?? []
|
|
@@ -7818,7 +8182,8 @@ async function dispatchRun(args) {
|
|
|
7818
8182
|
if (started.length === 0) break;
|
|
7819
8183
|
for (const decision of started) {
|
|
7820
8184
|
if (outcomes.length >= cappedStarts) break;
|
|
7821
|
-
|
|
8185
|
+
const admitted = isLandPrDecision2(decision) ? await runLandPrClaimed(decision) : await spawnClaimed(decision);
|
|
8186
|
+
shouldContinueDispatch = admitted && shouldContinueDispatch;
|
|
7822
8187
|
if (!shouldContinueDispatch) break;
|
|
7823
8188
|
}
|
|
7824
8189
|
}
|
|
@@ -8248,7 +8613,7 @@ function discoverProductionDbEnvFilePaths(options = {}) {
|
|
|
8248
8613
|
}
|
|
8249
8614
|
|
|
8250
8615
|
// src/db-credential-resolver.ts
|
|
8251
|
-
import { execFileSync, spawnSync as
|
|
8616
|
+
import { execFileSync, spawnSync as spawnSync6 } from "node:child_process";
|
|
8252
8617
|
import * as fs2 from "node:fs";
|
|
8253
8618
|
import * as path29 from "node:path";
|
|
8254
8619
|
|
|
@@ -8334,7 +8699,7 @@ function defaultNeonConnectionString(args) {
|
|
|
8334
8699
|
if (args.pooled) argv.push("--pooled");
|
|
8335
8700
|
let stdout;
|
|
8336
8701
|
try {
|
|
8337
|
-
const result =
|
|
8702
|
+
const result = spawnSync6(neonBin, argv, {
|
|
8338
8703
|
encoding: "utf8",
|
|
8339
8704
|
env: process.env,
|
|
8340
8705
|
timeout: 3e4
|
|
@@ -10126,7 +10491,7 @@ function pathHasForeignOwnedEntry(targetPath, maxEntries = 32) {
|
|
|
10126
10491
|
}
|
|
10127
10492
|
|
|
10128
10493
|
// src/cleanup-privileged-remove.ts
|
|
10129
|
-
import { spawnSync as
|
|
10494
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
10130
10495
|
import path46 from "node:path";
|
|
10131
10496
|
|
|
10132
10497
|
// src/cleanup-harness-path-validate.ts
|
|
@@ -10171,7 +10536,7 @@ function resolvePrivilegedCleanupMode() {
|
|
|
10171
10536
|
return "auto";
|
|
10172
10537
|
}
|
|
10173
10538
|
function runSudoNonInteractive(argv) {
|
|
10174
|
-
const res =
|
|
10539
|
+
const res = spawnSync7("sudo", ["-n", ...argv], {
|
|
10175
10540
|
encoding: "utf8",
|
|
10176
10541
|
stdio: ["ignore", "pipe", "pipe"]
|
|
10177
10542
|
});
|
|
@@ -12349,7 +12714,7 @@ function formatNodeOptionsFlag(mb = resolveNodeOldSpaceSizeMb()) {
|
|
|
12349
12714
|
}
|
|
12350
12715
|
|
|
12351
12716
|
// src/bounded-build/systemd-wrap.ts
|
|
12352
|
-
import { spawnSync as
|
|
12717
|
+
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
12353
12718
|
var systemdAvailableCache;
|
|
12354
12719
|
function isSystemdRunAvailable() {
|
|
12355
12720
|
if (process.env.KYNVER_BUILD_SKIP_SYSTEMD === "1" || process.env.KYNVER_BUILD_SKIP_SYSTEMD === "true") {
|
|
@@ -12360,7 +12725,7 @@ function isSystemdRunAvailable() {
|
|
|
12360
12725
|
systemdAvailableCache = false;
|
|
12361
12726
|
return false;
|
|
12362
12727
|
}
|
|
12363
|
-
const res =
|
|
12728
|
+
const res = spawnSync8("systemd-run", ["--version"], { encoding: "utf8", stdio: ["ignore", "ignore", "pipe"] });
|
|
12364
12729
|
systemdAvailableCache = res.status === 0;
|
|
12365
12730
|
return systemdAvailableCache;
|
|
12366
12731
|
}
|
|
@@ -12384,7 +12749,7 @@ function buildSystemdRunArgv(opts) {
|
|
|
12384
12749
|
}
|
|
12385
12750
|
|
|
12386
12751
|
// src/bounded-build/admission.ts
|
|
12387
|
-
import { spawnSync as
|
|
12752
|
+
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
12388
12753
|
function positiveInt4(value, fallback) {
|
|
12389
12754
|
const n = Number(value);
|
|
12390
12755
|
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
@@ -12420,7 +12785,7 @@ function assessBuildAdmission(opts = {}) {
|
|
|
12420
12785
|
}
|
|
12421
12786
|
function sleepMs2(ms) {
|
|
12422
12787
|
if (ms <= 0) return;
|
|
12423
|
-
|
|
12788
|
+
spawnSync9(process.execPath, ["-e", `const d=Date.now()+${Math.floor(ms)};while(Date.now()<d);`], {
|
|
12424
12789
|
stdio: "ignore"
|
|
12425
12790
|
});
|
|
12426
12791
|
}
|
|
@@ -12441,7 +12806,7 @@ function waitForBuildAdmission(timeoutMs, pollMs = 2e3, opts = {}) {
|
|
|
12441
12806
|
}
|
|
12442
12807
|
|
|
12443
12808
|
// src/bounded-build/exec.ts
|
|
12444
|
-
import { spawnSync as
|
|
12809
|
+
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
12445
12810
|
|
|
12446
12811
|
// src/heavy-verification/slot.ts
|
|
12447
12812
|
import {
|
|
@@ -12647,10 +13012,10 @@ function assessHeavyVerificationGate(command, opts = {}) {
|
|
|
12647
13012
|
}
|
|
12648
13013
|
|
|
12649
13014
|
// src/heavy-verification/gate.ts
|
|
12650
|
-
import { spawnSync as
|
|
13015
|
+
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
12651
13016
|
function sleepMs3(ms) {
|
|
12652
13017
|
if (ms <= 0) return;
|
|
12653
|
-
|
|
13018
|
+
spawnSync10(process.execPath, ["-e", `const d=Date.now()+${Math.floor(ms)};while(Date.now()<d);`], {
|
|
12654
13019
|
stdio: "ignore"
|
|
12655
13020
|
});
|
|
12656
13021
|
}
|
|
@@ -12693,7 +13058,7 @@ function envArgv(env) {
|
|
|
12693
13058
|
return out;
|
|
12694
13059
|
}
|
|
12695
13060
|
function runSpawn(argv, opts) {
|
|
12696
|
-
const res =
|
|
13061
|
+
const res = spawnSync11(argv[0], argv.slice(1), {
|
|
12697
13062
|
cwd: opts.cwd,
|
|
12698
13063
|
env: opts.env,
|
|
12699
13064
|
encoding: "utf8",
|
|
@@ -14096,10 +14461,10 @@ import path70 from "node:path";
|
|
|
14096
14461
|
import { accessSync, constants, existsSync as existsSync47, readFileSync as readFileSync19 } from "node:fs";
|
|
14097
14462
|
import { homedir as homedir16 } from "node:os";
|
|
14098
14463
|
import path69 from "node:path";
|
|
14099
|
-
import { spawnSync as
|
|
14464
|
+
import { spawnSync as spawnSync12 } from "node:child_process";
|
|
14100
14465
|
function captureCommand(bin, args) {
|
|
14101
14466
|
try {
|
|
14102
|
-
const res =
|
|
14467
|
+
const res = spawnSync12(bin, args, { encoding: "utf8" });
|
|
14103
14468
|
const stdout = (res.stdout || "").trim();
|
|
14104
14469
|
const stderr = (res.stderr || "").trim();
|
|
14105
14470
|
const ok = res.status === 0;
|
|
@@ -14999,7 +15364,7 @@ var LANDING_MAINTAINER_LANE_SPEC = {
|
|
|
14999
15364
|
};
|
|
15000
15365
|
|
|
15001
15366
|
// src/lane/landing-maintainer-local.ts
|
|
15002
|
-
import { spawnSync as
|
|
15367
|
+
import { spawnSync as spawnSync13 } from "node:child_process";
|
|
15003
15368
|
import path72 from "node:path";
|
|
15004
15369
|
function runLandingWrapper(prNumber, repoRoot, execute) {
|
|
15005
15370
|
const script = path72.join(repoRoot, LANDING_MAINTAINER_LANE_SPEC.landScript);
|
|
@@ -15013,7 +15378,7 @@ function runLandingWrapper(prNumber, repoRoot, execute) {
|
|
|
15013
15378
|
stderr: ""
|
|
15014
15379
|
};
|
|
15015
15380
|
}
|
|
15016
|
-
const result =
|
|
15381
|
+
const result = spawnSync13("node", args, {
|
|
15017
15382
|
cwd: repoRoot,
|
|
15018
15383
|
encoding: "utf8",
|
|
15019
15384
|
timeout: 10 * 60 * 1e3
|