@kynver-app/runtime 0.1.105 → 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 +386 -19
- package/dist/cli.js.map +4 -4
- package/dist/index.js +389 -22
- 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/server/cleanup.js.map +1 -1
- package/dist/server/default-repo.js.map +1 -1
- package/dist/server/memory-cost-enforce.js.map +1 -1
- package/dist/verify-live/verify-live-prompt.d.ts +2 -0
- package/dist/worker-persona-catalog.js +2 -2
- package/dist/worker-persona-catalog.js.map +2 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -311,7 +311,9 @@ function redactHomePath(value) {
|
|
|
311
311
|
if (resolved.startsWith(`${home}${path2.sep}`)) {
|
|
312
312
|
return `~/${path2.relative(home, resolved).split(path2.sep).join("/")}`;
|
|
313
313
|
}
|
|
314
|
-
|
|
314
|
+
const posix = resolved.replace(/\\/g, "/");
|
|
315
|
+
const redacted = posix.replace(/^\/home\/[^/]+(?=\/|$)/, "~").replace(/^\/Users\/[^/]+(?=\/|$)/, "~").replace(/^[A-Za-z]:\/home\/[^/]+(?=\/|$)/i, "~").replace(/^[A-Za-z]:\/Users\/[^/]+(?=\/|$)/i, "~");
|
|
316
|
+
return redacted;
|
|
315
317
|
}
|
|
316
318
|
function displayUserPath(value) {
|
|
317
319
|
return redactHomePath(value);
|
|
@@ -2696,14 +2698,14 @@ var WORKER_PERSONA_CATALOG = [
|
|
|
2696
2698
|
{
|
|
2697
2699
|
slug: "lorentz",
|
|
2698
2700
|
displayName: "Lorentz",
|
|
2699
|
-
description: "
|
|
2701
|
+
description: "Deep/adversarial review lane expert for risk, correctness, and safety gates. Run adversarial review and validation gating.",
|
|
2700
2702
|
dispatchLane: "review",
|
|
2701
2703
|
defaultRoleLane: "report_reviewer"
|
|
2702
2704
|
},
|
|
2703
2705
|
{
|
|
2704
2706
|
slug: "dalton",
|
|
2705
2707
|
displayName: "Dalton",
|
|
2706
|
-
description: "Landing
|
|
2708
|
+
description: "Landing-only \u2014 merge-ready handoff and final verification evidence; no implementation ownership.",
|
|
2707
2709
|
dispatchLane: "landing",
|
|
2708
2710
|
defaultRoleLane: "implementer"
|
|
2709
2711
|
}
|
|
@@ -7036,6 +7038,325 @@ async function releaseDispatchClaimAfterSpawnFailure(input) {
|
|
|
7036
7038
|
};
|
|
7037
7039
|
}
|
|
7038
7040
|
|
|
7041
|
+
// src/landing/land-pr.ts
|
|
7042
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
7043
|
+
|
|
7044
|
+
// src/landing/cli-auth.ts
|
|
7045
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
7046
|
+
function ensureGitHubTokenFromCliAuth() {
|
|
7047
|
+
if (process.env.GITHUB_TOKEN?.trim() || process.env.GH_TOKEN?.trim()) {
|
|
7048
|
+
return {
|
|
7049
|
+
source: "env",
|
|
7050
|
+
configured: true,
|
|
7051
|
+
reason: "GitHub token already configured in environment"
|
|
7052
|
+
};
|
|
7053
|
+
}
|
|
7054
|
+
const result = spawnSync4("gh", ["auth", "token"], {
|
|
7055
|
+
encoding: "utf8",
|
|
7056
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
7057
|
+
});
|
|
7058
|
+
if (result.status !== 0) {
|
|
7059
|
+
const reason = typeof result.stderr === "string" && result.stderr.trim() ? result.stderr.trim() : "gh auth token failed; run `gh auth login` on this machine";
|
|
7060
|
+
return { source: "missing", configured: false, reason };
|
|
7061
|
+
}
|
|
7062
|
+
const token = typeof result.stdout === "string" ? result.stdout.trim() : "";
|
|
7063
|
+
if (!token) {
|
|
7064
|
+
return {
|
|
7065
|
+
source: "missing",
|
|
7066
|
+
configured: false,
|
|
7067
|
+
reason: "gh auth token returned an empty token; run `gh auth login` on this machine"
|
|
7068
|
+
};
|
|
7069
|
+
}
|
|
7070
|
+
process.env.GH_TOKEN = token;
|
|
7071
|
+
return {
|
|
7072
|
+
source: "gh-cli",
|
|
7073
|
+
configured: true,
|
|
7074
|
+
reason: "Using local GitHub CLI auth for daemon land_pr merge"
|
|
7075
|
+
};
|
|
7076
|
+
}
|
|
7077
|
+
|
|
7078
|
+
// src/landing/land-pr.ts
|
|
7079
|
+
var SUCCESSFUL_CHECK_CONCLUSIONS = /* @__PURE__ */ new Set(["SUCCESS", "SKIPPED", "NEUTRAL"]);
|
|
7080
|
+
var READY_MERGE_STATES = /* @__PURE__ */ new Set(["CLEAN", "HAS_HOOKS"]);
|
|
7081
|
+
function repoArgs(repo) {
|
|
7082
|
+
return repo?.trim() ? ["--repo", repo.trim()] : [];
|
|
7083
|
+
}
|
|
7084
|
+
function ghJson(exec, cwd, args) {
|
|
7085
|
+
const res = exec.gh(cwd, args);
|
|
7086
|
+
if (res.status !== 0) {
|
|
7087
|
+
throw new Error(res.stderr || res.stdout || `gh ${args.join(" ")} failed`);
|
|
7088
|
+
}
|
|
7089
|
+
return JSON.parse(res.stdout || "{}");
|
|
7090
|
+
}
|
|
7091
|
+
function checkName(check3) {
|
|
7092
|
+
return typeof check3.name === "string" && check3.name || typeof check3.context === "string" && check3.context || typeof check3.workflowName === "string" && check3.workflowName || "unknown check";
|
|
7093
|
+
}
|
|
7094
|
+
function classifyChecks(statusCheckRollup) {
|
|
7095
|
+
const checks = Array.isArray(statusCheckRollup) ? statusCheckRollup : [];
|
|
7096
|
+
const pending = [];
|
|
7097
|
+
const failed = [];
|
|
7098
|
+
for (const raw of checks) {
|
|
7099
|
+
const check3 = raw && typeof raw === "object" ? raw : {};
|
|
7100
|
+
const conclusion = typeof check3.conclusion === "string" ? check3.conclusion.toUpperCase() : "";
|
|
7101
|
+
const status = typeof check3.status === "string" ? check3.status.toUpperCase() : "";
|
|
7102
|
+
const state = typeof check3.state === "string" ? check3.state.toUpperCase() : "";
|
|
7103
|
+
if (conclusion && SUCCESSFUL_CHECK_CONCLUSIONS.has(conclusion)) continue;
|
|
7104
|
+
if (conclusion) {
|
|
7105
|
+
failed.push(`${checkName(check3)}=${conclusion}`);
|
|
7106
|
+
continue;
|
|
7107
|
+
}
|
|
7108
|
+
if (state && SUCCESSFUL_CHECK_CONCLUSIONS.has(state)) continue;
|
|
7109
|
+
if (state && state !== "PENDING") {
|
|
7110
|
+
failed.push(`${checkName(check3)}=${state}`);
|
|
7111
|
+
continue;
|
|
7112
|
+
}
|
|
7113
|
+
if (state === "PENDING") {
|
|
7114
|
+
pending.push(`${checkName(check3)}=${state}`);
|
|
7115
|
+
continue;
|
|
7116
|
+
}
|
|
7117
|
+
if (status && status !== "COMPLETED") {
|
|
7118
|
+
pending.push(`${checkName(check3)}=${status}`);
|
|
7119
|
+
continue;
|
|
7120
|
+
}
|
|
7121
|
+
pending.push(`${checkName(check3)}=PENDING`);
|
|
7122
|
+
}
|
|
7123
|
+
return { pending, failed };
|
|
7124
|
+
}
|
|
7125
|
+
function vercelCheckSuccess(statusCheckRollup) {
|
|
7126
|
+
const checks = Array.isArray(statusCheckRollup) ? statusCheckRollup : [];
|
|
7127
|
+
return checks.some((raw) => {
|
|
7128
|
+
const check3 = raw && typeof raw === "object" ? raw : {};
|
|
7129
|
+
const name = typeof check3.name === "string" && check3.name || typeof check3.context === "string" && check3.context || "";
|
|
7130
|
+
const conclusion = typeof check3.conclusion === "string" ? check3.conclusion.toUpperCase() : "";
|
|
7131
|
+
const state = typeof check3.state === "string" ? check3.state.toUpperCase() : "";
|
|
7132
|
+
return /^vercel/i.test(name) && (conclusion === "SUCCESS" || state === "SUCCESS");
|
|
7133
|
+
});
|
|
7134
|
+
}
|
|
7135
|
+
var STRUCTURED_SECTION_RE = /^##\s*(test\s*plan|verification|test\s*evidence|verify)\b/im;
|
|
7136
|
+
var LOCAL_VERIFICATION_RE = /typecheck|npm run (test|build|typecheck)|vitest|tsc\b|verify-pr-local|local verify|local-verify|tests? (pass|green)|build green|node --test/i;
|
|
7137
|
+
var DOCS_TITLE_RE = /^docs[(:]/i;
|
|
7138
|
+
var DOCS_BODY_RE = /docs[- ]only|documentation only|no[- ]code change|no code changes|low[- ]risk|plan tracker only|markdown only/i;
|
|
7139
|
+
function assertVerificationEvidence(pr) {
|
|
7140
|
+
const title = typeof pr.title === "string" ? pr.title : "";
|
|
7141
|
+
const body = typeof pr.body === "string" ? pr.body : "";
|
|
7142
|
+
const docsLowRisk = DOCS_TITLE_RE.test(title) || DOCS_BODY_RE.test(body);
|
|
7143
|
+
const structuredSection = STRUCTURED_SECTION_RE.test(body);
|
|
7144
|
+
const localVerification = LOCAL_VERIFICATION_RE.test(body);
|
|
7145
|
+
const vercelOk = vercelCheckSuccess(pr.statusCheckRollup);
|
|
7146
|
+
if (docsLowRisk || structuredSection || localVerification || vercelOk) return;
|
|
7147
|
+
throw new Error(
|
|
7148
|
+
`PR #${pr.number} lacks landing verification evidence \u2014 add ## Test plan / ## Verification with local commands, Vercel preview, or docs/no-code rationale`
|
|
7149
|
+
);
|
|
7150
|
+
}
|
|
7151
|
+
function assertLandingReady(pr) {
|
|
7152
|
+
if (pr.state !== "OPEN") throw new Error(`PR #${pr.number} is ${pr.state}, not OPEN`);
|
|
7153
|
+
if (pr.isDraft) throw new Error(`PR #${pr.number} is still a draft`);
|
|
7154
|
+
if (!READY_MERGE_STATES.has(pr.mergeStateStatus)) {
|
|
7155
|
+
throw new Error(`PR #${pr.number} mergeStateStatus is ${pr.mergeStateStatus}`);
|
|
7156
|
+
}
|
|
7157
|
+
const checks = classifyChecks(pr.statusCheckRollup);
|
|
7158
|
+
if (checks.failed.length > 0) {
|
|
7159
|
+
throw new Error(`PR #${pr.number} has failing checks: ${checks.failed.join(", ")}`);
|
|
7160
|
+
}
|
|
7161
|
+
if (checks.pending.length > 0) {
|
|
7162
|
+
throw new Error(`PR #${pr.number} has pending checks: ${checks.pending.join(", ")}`);
|
|
7163
|
+
}
|
|
7164
|
+
assertVerificationEvidence(pr);
|
|
7165
|
+
}
|
|
7166
|
+
function landingReadinessError(pr) {
|
|
7167
|
+
try {
|
|
7168
|
+
assertLandingReady(pr);
|
|
7169
|
+
return null;
|
|
7170
|
+
} catch (err) {
|
|
7171
|
+
return err instanceof Error ? err.message : String(err);
|
|
7172
|
+
}
|
|
7173
|
+
}
|
|
7174
|
+
function deleteRemoteBranch(exec, cwd, repo, branch) {
|
|
7175
|
+
if (!branch?.trim()) return;
|
|
7176
|
+
const refPath = encodeURI(`heads/${branch}`);
|
|
7177
|
+
exec.gh(cwd, ["api", "-X", "DELETE", `repos/${repo}/git/refs/${refPath}`]);
|
|
7178
|
+
}
|
|
7179
|
+
function resolveRepo(exec, cwd, repo) {
|
|
7180
|
+
if (repo?.trim()) return repo.trim();
|
|
7181
|
+
const res = exec.gh(cwd, ["repo", "view", "--json", "nameWithOwner"]);
|
|
7182
|
+
if (res.status !== 0) throw new Error(res.stderr || "Could not resolve GitHub repo");
|
|
7183
|
+
const parsed = JSON.parse(res.stdout || "{}");
|
|
7184
|
+
if (!parsed.nameWithOwner) throw new Error("Could not resolve GitHub repo");
|
|
7185
|
+
return parsed.nameWithOwner;
|
|
7186
|
+
}
|
|
7187
|
+
function removeBranchWorktrees(cwd, branch) {
|
|
7188
|
+
if (!branch?.trim()) return;
|
|
7189
|
+
const list = spawnSync5("git", ["worktree", "list", "--porcelain"], {
|
|
7190
|
+
cwd,
|
|
7191
|
+
encoding: "utf8"
|
|
7192
|
+
});
|
|
7193
|
+
if (list.status !== 0) return;
|
|
7194
|
+
const lines = String(list.stdout || "").split(/\r?\n/);
|
|
7195
|
+
let currentPath = null;
|
|
7196
|
+
let currentBranch = null;
|
|
7197
|
+
for (const line of lines) {
|
|
7198
|
+
if (line.startsWith("worktree ")) {
|
|
7199
|
+
currentPath = line.slice("worktree ".length).trim();
|
|
7200
|
+
currentBranch = null;
|
|
7201
|
+
continue;
|
|
7202
|
+
}
|
|
7203
|
+
if (line.startsWith("branch ") && currentPath) {
|
|
7204
|
+
currentBranch = line.slice("branch ".length).trim();
|
|
7205
|
+
if (currentBranch.endsWith(`/${branch}`)) {
|
|
7206
|
+
spawnSync5("git", ["worktree", "remove", "--force", currentPath], {
|
|
7207
|
+
cwd,
|
|
7208
|
+
encoding: "utf8"
|
|
7209
|
+
});
|
|
7210
|
+
}
|
|
7211
|
+
}
|
|
7212
|
+
}
|
|
7213
|
+
}
|
|
7214
|
+
async function executeLandPrMerge(input) {
|
|
7215
|
+
const cwd = input.cwd ?? process.cwd();
|
|
7216
|
+
const exec = input.exec ?? defaultPrHandoffExec;
|
|
7217
|
+
const prTarget = input.prUrl.trim();
|
|
7218
|
+
if (!prTarget) throw new Error("prUrl is required");
|
|
7219
|
+
const auth = ensureGitHubTokenFromCliAuth();
|
|
7220
|
+
if (!auth.configured) {
|
|
7221
|
+
return {
|
|
7222
|
+
prUrl: prTarget,
|
|
7223
|
+
outcome: "blocked",
|
|
7224
|
+
reason: auth.reason
|
|
7225
|
+
};
|
|
7226
|
+
}
|
|
7227
|
+
const before = ghJson(exec, cwd, [
|
|
7228
|
+
"pr",
|
|
7229
|
+
"view",
|
|
7230
|
+
prTarget,
|
|
7231
|
+
...repoArgs(input.repo),
|
|
7232
|
+
"--json",
|
|
7233
|
+
[
|
|
7234
|
+
"number",
|
|
7235
|
+
"url",
|
|
7236
|
+
"title",
|
|
7237
|
+
"body",
|
|
7238
|
+
"state",
|
|
7239
|
+
"isDraft",
|
|
7240
|
+
"mergeStateStatus",
|
|
7241
|
+
"statusCheckRollup",
|
|
7242
|
+
"headRefName",
|
|
7243
|
+
"mergedAt",
|
|
7244
|
+
"mergeCommit"
|
|
7245
|
+
].join(",")
|
|
7246
|
+
]);
|
|
7247
|
+
const notReadyReason = landingReadinessError(before);
|
|
7248
|
+
if (notReadyReason) {
|
|
7249
|
+
if (input.skipNotReady) {
|
|
7250
|
+
return {
|
|
7251
|
+
prUrl: before.url || prTarget,
|
|
7252
|
+
outcome: "skipped",
|
|
7253
|
+
reason: notReadyReason
|
|
7254
|
+
};
|
|
7255
|
+
}
|
|
7256
|
+
return {
|
|
7257
|
+
prUrl: before.url || prTarget,
|
|
7258
|
+
outcome: "blocked",
|
|
7259
|
+
reason: notReadyReason
|
|
7260
|
+
};
|
|
7261
|
+
}
|
|
7262
|
+
if (input.dryRun) {
|
|
7263
|
+
return {
|
|
7264
|
+
prUrl: before.url || prTarget,
|
|
7265
|
+
outcome: "skipped",
|
|
7266
|
+
reason: "dry-run: PR is ready to merge"
|
|
7267
|
+
};
|
|
7268
|
+
}
|
|
7269
|
+
const target = String(before.number);
|
|
7270
|
+
const mergeRes = exec.gh(cwd, [
|
|
7271
|
+
"pr",
|
|
7272
|
+
"merge",
|
|
7273
|
+
target,
|
|
7274
|
+
...repoArgs(input.repo),
|
|
7275
|
+
"--squash"
|
|
7276
|
+
]);
|
|
7277
|
+
if (mergeRes.status !== 0) {
|
|
7278
|
+
return {
|
|
7279
|
+
prUrl: before.url || prTarget,
|
|
7280
|
+
outcome: "blocked",
|
|
7281
|
+
reason: mergeRes.stderr || mergeRes.stdout || "gh pr merge failed"
|
|
7282
|
+
};
|
|
7283
|
+
}
|
|
7284
|
+
const after = ghJson(exec, cwd, [
|
|
7285
|
+
"pr",
|
|
7286
|
+
"view",
|
|
7287
|
+
target,
|
|
7288
|
+
...repoArgs(input.repo),
|
|
7289
|
+
"--json",
|
|
7290
|
+
"number,url,mergedAt,mergeCommit,state"
|
|
7291
|
+
]);
|
|
7292
|
+
if (after.state !== "MERGED" && !after.mergedAt) {
|
|
7293
|
+
return {
|
|
7294
|
+
prUrl: after.url || before.url || prTarget,
|
|
7295
|
+
outcome: "blocked",
|
|
7296
|
+
reason: `PR #${after.number} did not verify as merged after gh pr merge`
|
|
7297
|
+
};
|
|
7298
|
+
}
|
|
7299
|
+
const repo = resolveRepo(exec, cwd, input.repo);
|
|
7300
|
+
deleteRemoteBranch(exec, cwd, repo, before.headRefName);
|
|
7301
|
+
removeBranchWorktrees(cwd, before.headRefName);
|
|
7302
|
+
const mergeCommit = after.mergeCommit?.oid ?? null;
|
|
7303
|
+
return {
|
|
7304
|
+
prUrl: after.url || before.url || prTarget,
|
|
7305
|
+
outcome: "merged",
|
|
7306
|
+
mergeCommit,
|
|
7307
|
+
reason: `Daemon land_pr merged PR #${after.number}`
|
|
7308
|
+
};
|
|
7309
|
+
}
|
|
7310
|
+
|
|
7311
|
+
// src/landing/land-pr-completion-post.ts
|
|
7312
|
+
async function postLandPrHarnessCompletion(input) {
|
|
7313
|
+
const secret = await resolveCallbackSecretWithMint(input.secret, input.agentOsId, {
|
|
7314
|
+
baseUrl: input.baseUrl
|
|
7315
|
+
});
|
|
7316
|
+
const taskId = String(input.task.id);
|
|
7317
|
+
const url = `${input.baseUrl}/api/agent-os/by-id/${encodeURIComponent(input.agentOsId)}/harness/completion`;
|
|
7318
|
+
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7319
|
+
const body = {
|
|
7320
|
+
source: "kynver-harness",
|
|
7321
|
+
agentOsId: input.agentOsId,
|
|
7322
|
+
runId: input.runId,
|
|
7323
|
+
workerName: `land-pr-${taskId}`,
|
|
7324
|
+
taskId,
|
|
7325
|
+
leaseToken: input.task.leaseToken ?? null,
|
|
7326
|
+
startedAt: finishedAt,
|
|
7327
|
+
finishedAt,
|
|
7328
|
+
status: {
|
|
7329
|
+
finalResult: input.report,
|
|
7330
|
+
prUrl: input.report.prUrl,
|
|
7331
|
+
summary: input.report.reason,
|
|
7332
|
+
leaseToken: input.task.leaseToken ?? null
|
|
7333
|
+
},
|
|
7334
|
+
workerInjection: null
|
|
7335
|
+
};
|
|
7336
|
+
const result = await postJsonWithCredentialRefresh(url, secret, body, {
|
|
7337
|
+
agentOsId: input.agentOsId,
|
|
7338
|
+
baseUrl: input.baseUrl
|
|
7339
|
+
});
|
|
7340
|
+
return { ok: result.ok, status: result.status };
|
|
7341
|
+
}
|
|
7342
|
+
|
|
7343
|
+
// src/verify-live/verify-live-prompt.ts
|
|
7344
|
+
function formatVerifyLiveCompletionContract() {
|
|
7345
|
+
return [
|
|
7346
|
+
"## verify_live completion contract",
|
|
7347
|
+
"Finish with a JSON finalResult object:",
|
|
7348
|
+
"{",
|
|
7349
|
+
' "prUrl": "<landed pr>",',
|
|
7350
|
+
' "outcome": "passed" | "failed" | "skipped" | "no_mcp_surface",',
|
|
7351
|
+
' "reason": "<human summary>",',
|
|
7352
|
+
' "mergeCommit": "<sha optional>",',
|
|
7353
|
+
' "mcpCalls": [{ "tool": "<name>", "ok": true, "summary": "..." }]',
|
|
7354
|
+
"}",
|
|
7355
|
+
"",
|
|
7356
|
+
"Drive the feature MCP tools against live production. Do not mark passed without exercising the MCP surface."
|
|
7357
|
+
].join("\n");
|
|
7358
|
+
}
|
|
7359
|
+
|
|
7039
7360
|
// src/dispatch.ts
|
|
7040
7361
|
var DEFAULT_DISPATCH_LEASE_MS = 60 * 60 * 1e3;
|
|
7041
7362
|
function readAdmissionExhaustion(result) {
|
|
@@ -7093,6 +7414,9 @@ function buildDispatchTaskText(task, agentOsId) {
|
|
|
7093
7414
|
`Board linkage: agentOsId=${agentOsId}, taskId=${task.id}, attempt=${task.attempt}, executor=${task.executor}${task.executorRef ? `, executorRef=${task.executorRef}` : ""}.`,
|
|
7094
7415
|
"This worker was dispatched from the AgentOS board. The harness reports your completion back to the board when you finish."
|
|
7095
7416
|
];
|
|
7417
|
+
if (task.executor === "verify_live") {
|
|
7418
|
+
lines.push("", formatVerifyLiveCompletionContract());
|
|
7419
|
+
}
|
|
7096
7420
|
const outboxRef = extractPlanOutboxFromTask(task);
|
|
7097
7421
|
if (outboxRef?.outboxId) {
|
|
7098
7422
|
const item = loadOutboxById(outboxRef.outboxId);
|
|
@@ -7126,6 +7450,12 @@ function requestedTargetTaskIds(args) {
|
|
|
7126
7450
|
async function dispatchRun(args) {
|
|
7127
7451
|
const pipeline = args.pipeline === true || args.pipeline === "true";
|
|
7128
7452
|
try {
|
|
7453
|
+
let isLandPrDecision2 = function(decision) {
|
|
7454
|
+
if (decision.landPrDispatch === true) return true;
|
|
7455
|
+
const task = decision.task;
|
|
7456
|
+
return task?.executor === "land_pr";
|
|
7457
|
+
};
|
|
7458
|
+
var isLandPrDecision = isLandPrDecision2;
|
|
7129
7459
|
const run = loadRun(String(required(String(args.run || ""), "--run")));
|
|
7130
7460
|
const agentOsId = String(required(String(args.agentOsId || ""), "--agent-os-id"));
|
|
7131
7461
|
const base = resolveBaseUrl(args.baseUrl ? String(args.baseUrl) : void 0);
|
|
@@ -7260,6 +7590,41 @@ async function dispatchRun(args) {
|
|
|
7260
7590
|
});
|
|
7261
7591
|
return false;
|
|
7262
7592
|
}
|
|
7593
|
+
async function runLandPrClaimed(decision) {
|
|
7594
|
+
const task = decision.task;
|
|
7595
|
+
const taskId = String(task.id);
|
|
7596
|
+
const prUrl = task.prUrl ? String(task.prUrl) : "";
|
|
7597
|
+
if (!prUrl) {
|
|
7598
|
+
return abortClaimedSpawn(task, "land_pr task missing prUrl");
|
|
7599
|
+
}
|
|
7600
|
+
try {
|
|
7601
|
+
const report = await executeLandPrMerge({ prUrl, cwd: process.cwd() });
|
|
7602
|
+
const post = await postLandPrHarnessCompletion({
|
|
7603
|
+
baseUrl: base,
|
|
7604
|
+
secret,
|
|
7605
|
+
agentOsId,
|
|
7606
|
+
runId: run.id,
|
|
7607
|
+
task,
|
|
7608
|
+
report
|
|
7609
|
+
});
|
|
7610
|
+
outcomes.push({
|
|
7611
|
+
taskId,
|
|
7612
|
+
started: true,
|
|
7613
|
+
landPr: true,
|
|
7614
|
+
outcome: report.outcome,
|
|
7615
|
+
completionStatus: post.status
|
|
7616
|
+
});
|
|
7617
|
+
if (!post.ok) {
|
|
7618
|
+
return abortClaimedSpawn(
|
|
7619
|
+
task,
|
|
7620
|
+
`land_pr completion POST failed (HTTP ${post.status})`
|
|
7621
|
+
);
|
|
7622
|
+
}
|
|
7623
|
+
return true;
|
|
7624
|
+
} catch (error) {
|
|
7625
|
+
return abortClaimedSpawn(task, error.message);
|
|
7626
|
+
}
|
|
7627
|
+
}
|
|
7263
7628
|
async function spawnClaimed(decision) {
|
|
7264
7629
|
const task = decision.task;
|
|
7265
7630
|
const harnessContext = readHarnessWorkerContext(decision);
|
|
@@ -7377,7 +7742,8 @@ async function dispatchRun(args) {
|
|
|
7377
7742
|
}
|
|
7378
7743
|
let shouldContinueDispatch = true;
|
|
7379
7744
|
for (const decision of result.started) {
|
|
7380
|
-
|
|
7745
|
+
const admitted = isLandPrDecision2(decision) ? await runLandPrClaimed(decision) : await spawnClaimed(decision);
|
|
7746
|
+
shouldContinueDispatch = admitted && shouldContinueDispatch;
|
|
7381
7747
|
}
|
|
7382
7748
|
skipped.push(
|
|
7383
7749
|
...result.skipped ?? []
|
|
@@ -7415,7 +7781,8 @@ async function dispatchRun(args) {
|
|
|
7415
7781
|
if (started.length === 0) break;
|
|
7416
7782
|
for (const decision of started) {
|
|
7417
7783
|
if (outcomes.length >= cappedStarts) break;
|
|
7418
|
-
|
|
7784
|
+
const admitted = isLandPrDecision2(decision) ? await runLandPrClaimed(decision) : await spawnClaimed(decision);
|
|
7785
|
+
shouldContinueDispatch = admitted && shouldContinueDispatch;
|
|
7419
7786
|
if (!shouldContinueDispatch) break;
|
|
7420
7787
|
}
|
|
7421
7788
|
}
|
|
@@ -9815,7 +10182,7 @@ function pathHasForeignOwnedEntry(targetPath, maxEntries = 32) {
|
|
|
9815
10182
|
}
|
|
9816
10183
|
|
|
9817
10184
|
// src/cleanup-privileged-remove.ts
|
|
9818
|
-
import { spawnSync as
|
|
10185
|
+
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
9819
10186
|
import path45 from "node:path";
|
|
9820
10187
|
|
|
9821
10188
|
// src/cleanup-harness-path-validate.ts
|
|
@@ -9860,7 +10227,7 @@ function resolvePrivilegedCleanupMode() {
|
|
|
9860
10227
|
return "auto";
|
|
9861
10228
|
}
|
|
9862
10229
|
function runSudoNonInteractive(argv) {
|
|
9863
|
-
const res =
|
|
10230
|
+
const res = spawnSync6("sudo", ["-n", ...argv], {
|
|
9864
10231
|
encoding: "utf8",
|
|
9865
10232
|
stdio: ["ignore", "pipe", "pipe"]
|
|
9866
10233
|
});
|
|
@@ -11588,7 +11955,7 @@ function formatNodeOptionsFlag(mb = resolveNodeOldSpaceSizeMb()) {
|
|
|
11588
11955
|
}
|
|
11589
11956
|
|
|
11590
11957
|
// src/bounded-build/systemd-wrap.ts
|
|
11591
|
-
import { spawnSync as
|
|
11958
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
11592
11959
|
var systemdAvailableCache;
|
|
11593
11960
|
function isSystemdRunAvailable() {
|
|
11594
11961
|
if (process.env.KYNVER_BUILD_SKIP_SYSTEMD === "1" || process.env.KYNVER_BUILD_SKIP_SYSTEMD === "true") {
|
|
@@ -11599,7 +11966,7 @@ function isSystemdRunAvailable() {
|
|
|
11599
11966
|
systemdAvailableCache = false;
|
|
11600
11967
|
return false;
|
|
11601
11968
|
}
|
|
11602
|
-
const res =
|
|
11969
|
+
const res = spawnSync7("systemd-run", ["--version"], { encoding: "utf8", stdio: ["ignore", "ignore", "pipe"] });
|
|
11603
11970
|
systemdAvailableCache = res.status === 0;
|
|
11604
11971
|
return systemdAvailableCache;
|
|
11605
11972
|
}
|
|
@@ -11623,7 +11990,7 @@ function buildSystemdRunArgv(opts) {
|
|
|
11623
11990
|
}
|
|
11624
11991
|
|
|
11625
11992
|
// src/bounded-build/admission.ts
|
|
11626
|
-
import { spawnSync as
|
|
11993
|
+
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
11627
11994
|
function positiveInt4(value, fallback) {
|
|
11628
11995
|
const n = Number(value);
|
|
11629
11996
|
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
@@ -11659,7 +12026,7 @@ function assessBuildAdmission(opts = {}) {
|
|
|
11659
12026
|
}
|
|
11660
12027
|
function sleepMs2(ms) {
|
|
11661
12028
|
if (ms <= 0) return;
|
|
11662
|
-
|
|
12029
|
+
spawnSync8(process.execPath, ["-e", `const d=Date.now()+${Math.floor(ms)};while(Date.now()<d);`], {
|
|
11663
12030
|
stdio: "ignore"
|
|
11664
12031
|
});
|
|
11665
12032
|
}
|
|
@@ -11680,7 +12047,7 @@ function waitForBuildAdmission(timeoutMs, pollMs = 2e3, opts = {}) {
|
|
|
11680
12047
|
}
|
|
11681
12048
|
|
|
11682
12049
|
// src/bounded-build/exec.ts
|
|
11683
|
-
import { spawnSync as
|
|
12050
|
+
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
11684
12051
|
|
|
11685
12052
|
// src/heavy-verification/slot.ts
|
|
11686
12053
|
import {
|
|
@@ -11886,10 +12253,10 @@ function assessHeavyVerificationGate(command, opts = {}) {
|
|
|
11886
12253
|
}
|
|
11887
12254
|
|
|
11888
12255
|
// src/heavy-verification/gate.ts
|
|
11889
|
-
import { spawnSync as
|
|
12256
|
+
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
11890
12257
|
function sleepMs3(ms) {
|
|
11891
12258
|
if (ms <= 0) return;
|
|
11892
|
-
|
|
12259
|
+
spawnSync9(process.execPath, ["-e", `const d=Date.now()+${Math.floor(ms)};while(Date.now()<d);`], {
|
|
11893
12260
|
stdio: "ignore"
|
|
11894
12261
|
});
|
|
11895
12262
|
}
|
|
@@ -11932,7 +12299,7 @@ function envArgv(env) {
|
|
|
11932
12299
|
return out;
|
|
11933
12300
|
}
|
|
11934
12301
|
function runSpawn(argv, opts) {
|
|
11935
|
-
const res =
|
|
12302
|
+
const res = spawnSync10(argv[0], argv.slice(1), {
|
|
11936
12303
|
cwd: opts.cwd,
|
|
11937
12304
|
env: opts.env,
|
|
11938
12305
|
encoding: "utf8",
|
|
@@ -13212,10 +13579,10 @@ import path68 from "node:path";
|
|
|
13212
13579
|
import { accessSync, constants, existsSync as existsSync45, readFileSync as readFileSync17 } from "node:fs";
|
|
13213
13580
|
import { homedir as homedir15 } from "node:os";
|
|
13214
13581
|
import path67 from "node:path";
|
|
13215
|
-
import { spawnSync as
|
|
13582
|
+
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
13216
13583
|
function captureCommand(bin, args) {
|
|
13217
13584
|
try {
|
|
13218
|
-
const res =
|
|
13585
|
+
const res = spawnSync11(bin, args, { encoding: "utf8" });
|
|
13219
13586
|
const stdout = (res.stdout || "").trim();
|
|
13220
13587
|
const stderr = (res.stderr || "").trim();
|
|
13221
13588
|
const ok = res.status === 0;
|
|
@@ -14115,7 +14482,7 @@ var LANDING_MAINTAINER_LANE_SPEC = {
|
|
|
14115
14482
|
};
|
|
14116
14483
|
|
|
14117
14484
|
// src/lane/landing-maintainer-local.ts
|
|
14118
|
-
import { spawnSync as
|
|
14485
|
+
import { spawnSync as spawnSync12 } from "node:child_process";
|
|
14119
14486
|
import path70 from "node:path";
|
|
14120
14487
|
function runLandingWrapper(prNumber, repoRoot, execute) {
|
|
14121
14488
|
const script = path70.join(repoRoot, LANDING_MAINTAINER_LANE_SPEC.landScript);
|
|
@@ -14129,7 +14496,7 @@ function runLandingWrapper(prNumber, repoRoot, execute) {
|
|
|
14129
14496
|
stderr: ""
|
|
14130
14497
|
};
|
|
14131
14498
|
}
|
|
14132
|
-
const result =
|
|
14499
|
+
const result = spawnSync12("node", args, {
|
|
14133
14500
|
cwd: repoRoot,
|
|
14134
14501
|
encoding: "utf8",
|
|
14135
14502
|
timeout: 10 * 60 * 1e3
|