terminalhire 0.42.41 → 0.42.42
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/bin/jpi-claim.js +106 -7
- package/dist/bin/jpi-dispatch.js +107 -8
- package/dist/bin/jpi-mcp.js +107 -8
- package/dist/bin/jpi-run.js +107 -8
- package/package.json +1 -1
package/dist/bin/jpi-claim.js
CHANGED
|
@@ -31049,7 +31049,8 @@ var init_result = __esm({
|
|
|
31049
31049
|
"leakState",
|
|
31050
31050
|
"venue",
|
|
31051
31051
|
"refusalOrigin",
|
|
31052
|
-
"stoppedAt"
|
|
31052
|
+
"stoppedAt",
|
|
31053
|
+
"installFrozen"
|
|
31053
31054
|
];
|
|
31054
31055
|
RENDER_NONE = null;
|
|
31055
31056
|
FIELD_VIEWS = {
|
|
@@ -31114,7 +31115,10 @@ var init_result = __esm({
|
|
|
31114
31115
|
// side refused in words a developer reads.
|
|
31115
31116
|
refusalOrigin: RENDER_NONE,
|
|
31116
31117
|
// Only when the run did not pass: on a green run "the last step" is just the last step.
|
|
31117
|
-
stoppedAt: (r) => r.stoppedAt === null || r.outcome === "completed" ? null : `last step ${r.stoppedAt} (the last package script named in the output)
|
|
31118
|
+
stoppedAt: (r) => r.stoppedAt === null || r.outcome === "completed" ? null : `last step ${r.stoppedAt} (the last package script named in the output)`,
|
|
31119
|
+
// The run already prints the unfrozen note while it runs (`installUnfrozenNote`); this is
|
|
31120
|
+
// the record of it for the worker and the intake.
|
|
31121
|
+
installFrozen: RENDER_NONE
|
|
31118
31122
|
};
|
|
31119
31123
|
}
|
|
31120
31124
|
});
|
|
@@ -35152,6 +35156,10 @@ function nodeInstallCommand(repo) {
|
|
|
35152
35156
|
return null;
|
|
35153
35157
|
}
|
|
35154
35158
|
function lockfileGaps(repo) {
|
|
35159
|
+
const read = readLockfileGaps(repo);
|
|
35160
|
+
return read === null || read.missing.length === 0 ? null : { lockfile: read.lockfile, missing: read.missing };
|
|
35161
|
+
}
|
|
35162
|
+
function readLockfileGaps(repo) {
|
|
35155
35163
|
const pkg = readJsonObject(repo, "package.json");
|
|
35156
35164
|
if (pkg === null)
|
|
35157
35165
|
return null;
|
|
@@ -35178,7 +35186,7 @@ function lockfileGaps(repo) {
|
|
|
35178
35186
|
missing.push(`${n}@${r} (${dir})`);
|
|
35179
35187
|
}
|
|
35180
35188
|
}
|
|
35181
|
-
return
|
|
35189
|
+
return { lockfile, missing, rootRead: rootListing !== null };
|
|
35182
35190
|
}
|
|
35183
35191
|
function wantedDependencies(pkg) {
|
|
35184
35192
|
const wanted = [];
|
|
@@ -37679,7 +37687,9 @@ function refusedRun(fields) {
|
|
|
37679
37687
|
venue: null,
|
|
37680
37688
|
refusalOrigin: fields.origin,
|
|
37681
37689
|
// No test step ran, so there is no output to read a step from.
|
|
37682
|
-
stoppedAt: null
|
|
37690
|
+
stoppedAt: null,
|
|
37691
|
+
// Refused before any install step ran.
|
|
37692
|
+
installFrozen: null
|
|
37683
37693
|
};
|
|
37684
37694
|
}
|
|
37685
37695
|
function refusalOriginOf(refusal2) {
|
|
@@ -37763,7 +37773,29 @@ function installUnfrozenNote(spec) {
|
|
|
37763
37773
|
const u = spec.installUnfrozen;
|
|
37764
37774
|
if (u === void 0)
|
|
37765
37775
|
return null;
|
|
37766
|
-
return `${u.lockfile} does not list ${u.missing.join(", ")}, so the install ran as \`${String(spec.installCommand)}\` without its frozen-lockfile check.
|
|
37776
|
+
return `${u.lockfile} does not list ${u.missing.join(", ")}, so the install ran as \`${String(spec.installCommand)}\` without its frozen-lockfile check. Include the updated ${u.lockfile} in the patch, or regenerate it before merging.`;
|
|
37777
|
+
}
|
|
37778
|
+
function isFrozenInstallCommand(command) {
|
|
37779
|
+
const lead = /^(?:(?:sudo|time)\s+|env(?:\s+[A-Za-z_]\w*=\S*)*\s+)*/.exec(command)?.[0] ?? "";
|
|
37780
|
+
const install = command.slice(lead.length).split(/;|&&|\|\|/)[0]?.trim() ?? "";
|
|
37781
|
+
if (/^npm ci(\s|$)/.test(install))
|
|
37782
|
+
return true;
|
|
37783
|
+
if (/^(yarn|pnpm|bun)\b/.test(install) && /\s--frozen-lockfile(?=\s|$)/.test(install)) {
|
|
37784
|
+
return true;
|
|
37785
|
+
}
|
|
37786
|
+
return /^yarn\b/.test(install) && /\s--immutable(?=\s|$)/.test(install);
|
|
37787
|
+
}
|
|
37788
|
+
function installFrozenFor(spec, install) {
|
|
37789
|
+
if (install === null)
|
|
37790
|
+
return null;
|
|
37791
|
+
const launched = install.exitCode !== INSTALL_NEVER_STARTED && (install.exitCode !== null || install.timedOut);
|
|
37792
|
+
if (!launched)
|
|
37793
|
+
return null;
|
|
37794
|
+
if (spec.runtime !== "node")
|
|
37795
|
+
return null;
|
|
37796
|
+
if (spec.installUnfrozen !== void 0)
|
|
37797
|
+
return false;
|
|
37798
|
+
return isFrozenInstallCommand(install.command);
|
|
37767
37799
|
}
|
|
37768
37800
|
async function verifyWorkingDiff(req) {
|
|
37769
37801
|
const ctx = {
|
|
@@ -38132,7 +38164,8 @@ async function runVerification(req, ctx) {
|
|
|
38132
38164
|
// A run that reached a verdict was not refused, so neither side refused it.
|
|
38133
38165
|
refusalOrigin: null,
|
|
38134
38166
|
// Read from the full test output, not `outputTail`, which is an excerpt.
|
|
38135
|
-
stoppedAt: readStoppedAt(verdict.test?.stdout ?? "", verdict.test?.stderr ?? "")
|
|
38167
|
+
stoppedAt: readStoppedAt(verdict.test?.stdout ?? "", verdict.test?.stderr ?? ""),
|
|
38168
|
+
installFrozen: installFrozenFor(spec, verdict.install)
|
|
38136
38169
|
};
|
|
38137
38170
|
let later = null;
|
|
38138
38171
|
if (req.screenshots !== void 0) {
|
|
@@ -38331,7 +38364,7 @@ async function prepareBaseTree(o) {
|
|
|
38331
38364
|
throw err;
|
|
38332
38365
|
}
|
|
38333
38366
|
}
|
|
38334
|
-
var ThRunError, OUTPUT_TAIL_BYTES, LOCKFILE_READ_CAP, FULL_COMMIT_ID, ALLOWED_URL_SCHEMES, SCP_STYLE, URL_SCHEME, WINDOWS_ABSOLUTE, UNC_PATH, TRANSPORT_REASON, SHA_REASON, FULL_SHA, MIN_GIT_VERSION_FOR_END_OF_OPTIONS, CloneUnavailableError, GIT_ENV_ALLOWLIST, credentialFreeHomeDir, SSH_ISOLATION_ARGS, WITHHELD_SEGMENT, UNPARSEABLE_TARGET, DEFERRED_GATE_TIMEOUT_MS, FAILURE_LINE, REDACTED_TARGET_REPO, REDACTED_TARGET_SHA;
|
|
38367
|
+
var ThRunError, OUTPUT_TAIL_BYTES, LOCKFILE_READ_CAP, FULL_COMMIT_ID, ALLOWED_URL_SCHEMES, SCP_STYLE, URL_SCHEME, WINDOWS_ABSOLUTE, UNC_PATH, TRANSPORT_REASON, SHA_REASON, FULL_SHA, MIN_GIT_VERSION_FOR_END_OF_OPTIONS, CloneUnavailableError, GIT_ENV_ALLOWLIST, credentialFreeHomeDir, SSH_ISOLATION_ARGS, WITHHELD_SEGMENT, UNPARSEABLE_TARGET, DEFERRED_GATE_TIMEOUT_MS, FAILURE_LINE, REDACTED_TARGET_REPO, REDACTED_TARGET_SHA, INSTALL_NEVER_STARTED;
|
|
38335
38368
|
var init_thrun = __esm({
|
|
38336
38369
|
"../../packages/envrun/dist/thrun.js"() {
|
|
38337
38370
|
"use strict";
|
|
@@ -38420,6 +38453,7 @@ var init_thrun = __esm({
|
|
|
38420
38453
|
FAILURE_LINE = /^(?:[ \t]*(?:not ok |FAILED |FAIL )|E {3}|# fail [1-9])/m;
|
|
38421
38454
|
REDACTED_TARGET_REPO = "(refused before the target was accepted)";
|
|
38422
38455
|
REDACTED_TARGET_SHA = "(refused)";
|
|
38456
|
+
INSTALL_NEVER_STARTED = 125;
|
|
38423
38457
|
}
|
|
38424
38458
|
});
|
|
38425
38459
|
|
|
@@ -39321,6 +39355,7 @@ __export(dist_exports, {
|
|
|
39321
39355
|
imageRepo: () => imageRepo,
|
|
39322
39356
|
imageVariantFor: () => imageVariantFor,
|
|
39323
39357
|
installCommandFor: () => installCommandFor,
|
|
39358
|
+
installFrozenFor: () => installFrozenFor,
|
|
39324
39359
|
installLocalMigrationTooling: () => installLocalMigrationTooling,
|
|
39325
39360
|
installUnfrozenNote: () => installUnfrozenNote,
|
|
39326
39361
|
isBookkeepingTable: () => isBookkeepingTable,
|
|
@@ -44169,6 +44204,67 @@ async function uploadClaimScreenshots(intake, uploads) {
|
|
|
44169
44204
|
);
|
|
44170
44205
|
}
|
|
44171
44206
|
}
|
|
44207
|
+
var DEPENDENCY_SECTIONS2 = [
|
|
44208
|
+
"dependencies",
|
|
44209
|
+
"devDependencies",
|
|
44210
|
+
"optionalDependencies",
|
|
44211
|
+
"peerDependencies"
|
|
44212
|
+
];
|
|
44213
|
+
var SENDABLE_LOCKFILES = [
|
|
44214
|
+
["package-lock.json", "npm install"],
|
|
44215
|
+
["yarn.lock", "yarn install"]
|
|
44216
|
+
];
|
|
44217
|
+
async function packageJsonAt(wt, rev, path5) {
|
|
44218
|
+
let text;
|
|
44219
|
+
try {
|
|
44220
|
+
({ stdout: text } = await pExecFile("git", ["-C", wt, "show", `${rev}:${path5}`], {
|
|
44221
|
+
shell: false,
|
|
44222
|
+
maxBuffer: 16 * 1024 * 1024
|
|
44223
|
+
}));
|
|
44224
|
+
} catch {
|
|
44225
|
+
return {};
|
|
44226
|
+
}
|
|
44227
|
+
try {
|
|
44228
|
+
const parsed = JSON.parse(String(text));
|
|
44229
|
+
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
44230
|
+
} catch {
|
|
44231
|
+
return null;
|
|
44232
|
+
}
|
|
44233
|
+
}
|
|
44234
|
+
function sectionKey(pkg, section) {
|
|
44235
|
+
const value = pkg[section];
|
|
44236
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
44237
|
+
return JSON.stringify(value ?? null);
|
|
44238
|
+
}
|
|
44239
|
+
return JSON.stringify(Object.keys(value).sort().map((k) => [k, value[k]]));
|
|
44240
|
+
}
|
|
44241
|
+
async function patchChangesDependencies(wt, base, touched) {
|
|
44242
|
+
for (const path5 of touched) {
|
|
44243
|
+
if (path5.split("/").pop() !== "package.json") continue;
|
|
44244
|
+
const before = await packageJsonAt(wt, base, path5);
|
|
44245
|
+
const after = await packageJsonAt(wt, "HEAD", path5);
|
|
44246
|
+
if (before === null || after === null) continue;
|
|
44247
|
+
if (DEPENDENCY_SECTIONS2.some((s) => sectionKey(before, s) !== sectionKey(after, s))) return true;
|
|
44248
|
+
}
|
|
44249
|
+
return false;
|
|
44250
|
+
}
|
|
44251
|
+
async function dependencyLockfileWarnings(wt, base, touched) {
|
|
44252
|
+
if (!await patchChangesDependencies(wt, base, touched)) return [];
|
|
44253
|
+
const warnings = [];
|
|
44254
|
+
for (const [lockfile, cmd] of SENDABLE_LOCKFILES) {
|
|
44255
|
+
let present;
|
|
44256
|
+
try {
|
|
44257
|
+
present = (await sh("git", ["-C", wt, "ls-tree", "--name-only", base, "--", lockfile])).trim() === lockfile;
|
|
44258
|
+
} catch {
|
|
44259
|
+
present = false;
|
|
44260
|
+
}
|
|
44261
|
+
if (!present || touched.includes(lockfile)) continue;
|
|
44262
|
+
warnings.push(
|
|
44263
|
+
` \u26A0 package.json changes dependencies, but ${lockfile} is not in this patch. The run will install without its frozen-lockfile check. Run \`${cmd}\` and commit ${lockfile} to keep it frozen.`
|
|
44264
|
+
);
|
|
44265
|
+
}
|
|
44266
|
+
return warnings;
|
|
44267
|
+
}
|
|
44172
44268
|
async function submitFounderPatch({ claims, claim, id, wt, flags }) {
|
|
44173
44269
|
let roots;
|
|
44174
44270
|
try {
|
|
@@ -44219,6 +44315,9 @@ async function submitFounderPatch({ claims, claim, id, wt, flags }) {
|
|
|
44219
44315
|
);
|
|
44220
44316
|
process.exit(1);
|
|
44221
44317
|
}
|
|
44318
|
+
const lockfileWarnings = await dependencyLockfileWarnings(wt, base, touched);
|
|
44319
|
+
if (lockfileWarnings.length > 0) console.log(`
|
|
44320
|
+
${lockfileWarnings.join("\n")}`);
|
|
44222
44321
|
const authorName = await sh("git", ["-C", wt, "log", "-1", "--format=%an"]);
|
|
44223
44322
|
const authorEmail = await sh("git", ["-C", wt, "log", "-1", "--format=%ae"]);
|
|
44224
44323
|
const shots = flags.screenshots === void 0 ? null : loadClaimScreenshots(flags.screenshots);
|
package/dist/bin/jpi-dispatch.js
CHANGED
|
@@ -36824,7 +36824,8 @@ var init_result = __esm({
|
|
|
36824
36824
|
"leakState",
|
|
36825
36825
|
"venue",
|
|
36826
36826
|
"refusalOrigin",
|
|
36827
|
-
"stoppedAt"
|
|
36827
|
+
"stoppedAt",
|
|
36828
|
+
"installFrozen"
|
|
36828
36829
|
];
|
|
36829
36830
|
RENDER_NONE = null;
|
|
36830
36831
|
FIELD_VIEWS = {
|
|
@@ -36889,7 +36890,10 @@ var init_result = __esm({
|
|
|
36889
36890
|
// side refused in words a developer reads.
|
|
36890
36891
|
refusalOrigin: RENDER_NONE,
|
|
36891
36892
|
// Only when the run did not pass: on a green run "the last step" is just the last step.
|
|
36892
|
-
stoppedAt: (r) => r.stoppedAt === null || r.outcome === "completed" ? null : `last step ${r.stoppedAt} (the last package script named in the output)
|
|
36893
|
+
stoppedAt: (r) => r.stoppedAt === null || r.outcome === "completed" ? null : `last step ${r.stoppedAt} (the last package script named in the output)`,
|
|
36894
|
+
// The run already prints the unfrozen note while it runs (`installUnfrozenNote`); this is
|
|
36895
|
+
// the record of it for the worker and the intake.
|
|
36896
|
+
installFrozen: RENDER_NONE
|
|
36893
36897
|
};
|
|
36894
36898
|
}
|
|
36895
36899
|
});
|
|
@@ -40927,6 +40931,10 @@ function nodeInstallCommand(repo) {
|
|
|
40927
40931
|
return null;
|
|
40928
40932
|
}
|
|
40929
40933
|
function lockfileGaps(repo) {
|
|
40934
|
+
const read = readLockfileGaps(repo);
|
|
40935
|
+
return read === null || read.missing.length === 0 ? null : { lockfile: read.lockfile, missing: read.missing };
|
|
40936
|
+
}
|
|
40937
|
+
function readLockfileGaps(repo) {
|
|
40930
40938
|
const pkg = readJsonObject(repo, "package.json");
|
|
40931
40939
|
if (pkg === null)
|
|
40932
40940
|
return null;
|
|
@@ -40953,7 +40961,7 @@ function lockfileGaps(repo) {
|
|
|
40953
40961
|
missing.push(`${n}@${r} (${dir})`);
|
|
40954
40962
|
}
|
|
40955
40963
|
}
|
|
40956
|
-
return
|
|
40964
|
+
return { lockfile, missing, rootRead: rootListing !== null };
|
|
40957
40965
|
}
|
|
40958
40966
|
function wantedDependencies(pkg) {
|
|
40959
40967
|
const wanted = [];
|
|
@@ -43454,7 +43462,9 @@ function refusedRun(fields) {
|
|
|
43454
43462
|
venue: null,
|
|
43455
43463
|
refusalOrigin: fields.origin,
|
|
43456
43464
|
// No test step ran, so there is no output to read a step from.
|
|
43457
|
-
stoppedAt: null
|
|
43465
|
+
stoppedAt: null,
|
|
43466
|
+
// Refused before any install step ran.
|
|
43467
|
+
installFrozen: null
|
|
43458
43468
|
};
|
|
43459
43469
|
}
|
|
43460
43470
|
function refusalOriginOf(refusal2) {
|
|
@@ -43538,7 +43548,29 @@ function installUnfrozenNote(spec) {
|
|
|
43538
43548
|
const u = spec.installUnfrozen;
|
|
43539
43549
|
if (u === void 0)
|
|
43540
43550
|
return null;
|
|
43541
|
-
return `${u.lockfile} does not list ${u.missing.join(", ")}, so the install ran as \`${String(spec.installCommand)}\` without its frozen-lockfile check.
|
|
43551
|
+
return `${u.lockfile} does not list ${u.missing.join(", ")}, so the install ran as \`${String(spec.installCommand)}\` without its frozen-lockfile check. Include the updated ${u.lockfile} in the patch, or regenerate it before merging.`;
|
|
43552
|
+
}
|
|
43553
|
+
function isFrozenInstallCommand(command) {
|
|
43554
|
+
const lead = /^(?:(?:sudo|time)\s+|env(?:\s+[A-Za-z_]\w*=\S*)*\s+)*/.exec(command)?.[0] ?? "";
|
|
43555
|
+
const install = command.slice(lead.length).split(/;|&&|\|\|/)[0]?.trim() ?? "";
|
|
43556
|
+
if (/^npm ci(\s|$)/.test(install))
|
|
43557
|
+
return true;
|
|
43558
|
+
if (/^(yarn|pnpm|bun)\b/.test(install) && /\s--frozen-lockfile(?=\s|$)/.test(install)) {
|
|
43559
|
+
return true;
|
|
43560
|
+
}
|
|
43561
|
+
return /^yarn\b/.test(install) && /\s--immutable(?=\s|$)/.test(install);
|
|
43562
|
+
}
|
|
43563
|
+
function installFrozenFor(spec, install) {
|
|
43564
|
+
if (install === null)
|
|
43565
|
+
return null;
|
|
43566
|
+
const launched = install.exitCode !== INSTALL_NEVER_STARTED && (install.exitCode !== null || install.timedOut);
|
|
43567
|
+
if (!launched)
|
|
43568
|
+
return null;
|
|
43569
|
+
if (spec.runtime !== "node")
|
|
43570
|
+
return null;
|
|
43571
|
+
if (spec.installUnfrozen !== void 0)
|
|
43572
|
+
return false;
|
|
43573
|
+
return isFrozenInstallCommand(install.command);
|
|
43542
43574
|
}
|
|
43543
43575
|
async function verifyWorkingDiff(req) {
|
|
43544
43576
|
const ctx = {
|
|
@@ -43907,7 +43939,8 @@ async function runVerification(req, ctx) {
|
|
|
43907
43939
|
// A run that reached a verdict was not refused, so neither side refused it.
|
|
43908
43940
|
refusalOrigin: null,
|
|
43909
43941
|
// Read from the full test output, not `outputTail`, which is an excerpt.
|
|
43910
|
-
stoppedAt: readStoppedAt(verdict.test?.stdout ?? "", verdict.test?.stderr ?? "")
|
|
43942
|
+
stoppedAt: readStoppedAt(verdict.test?.stdout ?? "", verdict.test?.stderr ?? ""),
|
|
43943
|
+
installFrozen: installFrozenFor(spec, verdict.install)
|
|
43911
43944
|
};
|
|
43912
43945
|
let later = null;
|
|
43913
43946
|
if (req.screenshots !== void 0) {
|
|
@@ -44106,7 +44139,7 @@ async function prepareBaseTree(o) {
|
|
|
44106
44139
|
throw err;
|
|
44107
44140
|
}
|
|
44108
44141
|
}
|
|
44109
|
-
var ThRunError, OUTPUT_TAIL_BYTES, LOCKFILE_READ_CAP, FULL_COMMIT_ID, ALLOWED_URL_SCHEMES, SCP_STYLE, URL_SCHEME, WINDOWS_ABSOLUTE, UNC_PATH, TRANSPORT_REASON, SHA_REASON, FULL_SHA, MIN_GIT_VERSION_FOR_END_OF_OPTIONS, CloneUnavailableError, GIT_ENV_ALLOWLIST, credentialFreeHomeDir, SSH_ISOLATION_ARGS, WITHHELD_SEGMENT, UNPARSEABLE_TARGET, DEFERRED_GATE_TIMEOUT_MS, FAILURE_LINE, REDACTED_TARGET_REPO, REDACTED_TARGET_SHA;
|
|
44142
|
+
var ThRunError, OUTPUT_TAIL_BYTES, LOCKFILE_READ_CAP, FULL_COMMIT_ID, ALLOWED_URL_SCHEMES, SCP_STYLE, URL_SCHEME, WINDOWS_ABSOLUTE, UNC_PATH, TRANSPORT_REASON, SHA_REASON, FULL_SHA, MIN_GIT_VERSION_FOR_END_OF_OPTIONS, CloneUnavailableError, GIT_ENV_ALLOWLIST, credentialFreeHomeDir, SSH_ISOLATION_ARGS, WITHHELD_SEGMENT, UNPARSEABLE_TARGET, DEFERRED_GATE_TIMEOUT_MS, FAILURE_LINE, REDACTED_TARGET_REPO, REDACTED_TARGET_SHA, INSTALL_NEVER_STARTED;
|
|
44110
44143
|
var init_thrun = __esm({
|
|
44111
44144
|
"../../packages/envrun/dist/thrun.js"() {
|
|
44112
44145
|
"use strict";
|
|
@@ -44195,6 +44228,7 @@ var init_thrun = __esm({
|
|
|
44195
44228
|
FAILURE_LINE = /^(?:[ \t]*(?:not ok |FAILED |FAIL )|E {3}|# fail [1-9])/m;
|
|
44196
44229
|
REDACTED_TARGET_REPO = "(refused before the target was accepted)";
|
|
44197
44230
|
REDACTED_TARGET_SHA = "(refused)";
|
|
44231
|
+
INSTALL_NEVER_STARTED = 125;
|
|
44198
44232
|
}
|
|
44199
44233
|
});
|
|
44200
44234
|
|
|
@@ -45096,6 +45130,7 @@ __export(dist_exports, {
|
|
|
45096
45130
|
imageRepo: () => imageRepo,
|
|
45097
45131
|
imageVariantFor: () => imageVariantFor,
|
|
45098
45132
|
installCommandFor: () => installCommandFor,
|
|
45133
|
+
installFrozenFor: () => installFrozenFor,
|
|
45099
45134
|
installLocalMigrationTooling: () => installLocalMigrationTooling,
|
|
45100
45135
|
installUnfrozenNote: () => installUnfrozenNote,
|
|
45101
45136
|
isBookkeepingTable: () => isBookkeepingTable,
|
|
@@ -49429,6 +49464,57 @@ async function uploadClaimScreenshots(intake, uploads) {
|
|
|
49429
49464
|
);
|
|
49430
49465
|
}
|
|
49431
49466
|
}
|
|
49467
|
+
async function packageJsonAt(wt, rev, path6) {
|
|
49468
|
+
let text;
|
|
49469
|
+
try {
|
|
49470
|
+
({ stdout: text } = await pExecFile("git", ["-C", wt, "show", `${rev}:${path6}`], {
|
|
49471
|
+
shell: false,
|
|
49472
|
+
maxBuffer: 16 * 1024 * 1024
|
|
49473
|
+
}));
|
|
49474
|
+
} catch {
|
|
49475
|
+
return {};
|
|
49476
|
+
}
|
|
49477
|
+
try {
|
|
49478
|
+
const parsed = JSON.parse(String(text));
|
|
49479
|
+
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
49480
|
+
} catch {
|
|
49481
|
+
return null;
|
|
49482
|
+
}
|
|
49483
|
+
}
|
|
49484
|
+
function sectionKey(pkg, section2) {
|
|
49485
|
+
const value = pkg[section2];
|
|
49486
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
49487
|
+
return JSON.stringify(value ?? null);
|
|
49488
|
+
}
|
|
49489
|
+
return JSON.stringify(Object.keys(value).sort().map((k) => [k, value[k]]));
|
|
49490
|
+
}
|
|
49491
|
+
async function patchChangesDependencies(wt, base, touched) {
|
|
49492
|
+
for (const path6 of touched) {
|
|
49493
|
+
if (path6.split("/").pop() !== "package.json") continue;
|
|
49494
|
+
const before = await packageJsonAt(wt, base, path6);
|
|
49495
|
+
const after = await packageJsonAt(wt, "HEAD", path6);
|
|
49496
|
+
if (before === null || after === null) continue;
|
|
49497
|
+
if (DEPENDENCY_SECTIONS2.some((s) => sectionKey(before, s) !== sectionKey(after, s))) return true;
|
|
49498
|
+
}
|
|
49499
|
+
return false;
|
|
49500
|
+
}
|
|
49501
|
+
async function dependencyLockfileWarnings(wt, base, touched) {
|
|
49502
|
+
if (!await patchChangesDependencies(wt, base, touched)) return [];
|
|
49503
|
+
const warnings = [];
|
|
49504
|
+
for (const [lockfile, cmd] of SENDABLE_LOCKFILES) {
|
|
49505
|
+
let present;
|
|
49506
|
+
try {
|
|
49507
|
+
present = (await sh("git", ["-C", wt, "ls-tree", "--name-only", base, "--", lockfile])).trim() === lockfile;
|
|
49508
|
+
} catch {
|
|
49509
|
+
present = false;
|
|
49510
|
+
}
|
|
49511
|
+
if (!present || touched.includes(lockfile)) continue;
|
|
49512
|
+
warnings.push(
|
|
49513
|
+
` \u26A0 package.json changes dependencies, but ${lockfile} is not in this patch. The run will install without its frozen-lockfile check. Run \`${cmd}\` and commit ${lockfile} to keep it frozen.`
|
|
49514
|
+
);
|
|
49515
|
+
}
|
|
49516
|
+
return warnings;
|
|
49517
|
+
}
|
|
49432
49518
|
async function submitFounderPatch({ claims, claim, id, wt, flags }) {
|
|
49433
49519
|
let roots;
|
|
49434
49520
|
try {
|
|
@@ -49479,6 +49565,9 @@ async function submitFounderPatch({ claims, claim, id, wt, flags }) {
|
|
|
49479
49565
|
);
|
|
49480
49566
|
process.exit(1);
|
|
49481
49567
|
}
|
|
49568
|
+
const lockfileWarnings = await dependencyLockfileWarnings(wt, base, touched);
|
|
49569
|
+
if (lockfileWarnings.length > 0) console.log(`
|
|
49570
|
+
${lockfileWarnings.join("\n")}`);
|
|
49482
49571
|
const authorName = await sh("git", ["-C", wt, "log", "-1", "--format=%an"]);
|
|
49483
49572
|
const authorEmail = await sh("git", ["-C", wt, "log", "-1", "--format=%ae"]);
|
|
49484
49573
|
const shots = flags.screenshots === void 0 ? null : loadClaimScreenshots(flags.screenshots);
|
|
@@ -50988,7 +51077,7 @@ async function run7() {
|
|
|
50988
51077
|
process.exit(1);
|
|
50989
51078
|
}
|
|
50990
51079
|
}
|
|
50991
|
-
var TERMINALHIRE_DIR17, INDEX_CACHE_FILE5, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL6, CLAIM_SYNC_BASE4, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, CLAIM_SYNC_WRITE_TIMEOUT_MS, GH_API3, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, BASELINE_STATUSES, MIN_TEST_BUDGET_MINUTES, MAX_TEST_BUDGET_MINUTES, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, SUBMIT_ACCEPTS, REVISE_RECOVERY_STATES, CLOSED_STATES, GH_SESSION_COOKIE4, PUSH_TOKEN_REFUSAL, SYNC_BACKGROUND_PUSH_ACTIVE_FIELD, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS, OPENABLE_AGENTS, BRIEF_DIR, BRIEF_REL_PATH, VERIFY_REL_PATH, AGENTS_REL_PATH, BRIEF_EXCLUDE_LINE, PACK_SAFE_ID, CLAIM_EVENT_LABEL, LINE_BREAKS, CONTROL_CHARS3, FOUNDER_POSTING_ID, CLAIM_SCREENSHOT_PUT_TIMEOUT_MS, CLAIM_RESOLUTION_REASONS, SETUP_FAILED_REQUIREMENTS, POSTING_LEVEL_RESOLUTION_REASONS, RESOLUTION_REASON_BLURB;
|
|
51080
|
+
var TERMINALHIRE_DIR17, INDEX_CACHE_FILE5, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL6, CLAIM_SYNC_BASE4, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, CLAIM_SYNC_WRITE_TIMEOUT_MS, GH_API3, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, BASELINE_STATUSES, MIN_TEST_BUDGET_MINUTES, MAX_TEST_BUDGET_MINUTES, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, SUBMIT_ACCEPTS, REVISE_RECOVERY_STATES, CLOSED_STATES, GH_SESSION_COOKIE4, PUSH_TOKEN_REFUSAL, SYNC_BACKGROUND_PUSH_ACTIVE_FIELD, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS, OPENABLE_AGENTS, BRIEF_DIR, BRIEF_REL_PATH, VERIFY_REL_PATH, AGENTS_REL_PATH, BRIEF_EXCLUDE_LINE, PACK_SAFE_ID, CLAIM_EVENT_LABEL, LINE_BREAKS, CONTROL_CHARS3, FOUNDER_POSTING_ID, CLAIM_SCREENSHOT_PUT_TIMEOUT_MS, DEPENDENCY_SECTIONS2, SENDABLE_LOCKFILES, CLAIM_RESOLUTION_REASONS, SETUP_FAILED_REQUIREMENTS, POSTING_LEVEL_RESOLUTION_REASONS, RESOLUTION_REASON_BLURB;
|
|
50992
51081
|
var init_jpi_claim = __esm({
|
|
50993
51082
|
"bin/jpi-claim.js"() {
|
|
50994
51083
|
"use strict";
|
|
@@ -51121,6 +51210,16 @@ var init_jpi_claim = __esm({
|
|
|
51121
51210
|
CONTROL_CHARS3 = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
51122
51211
|
FOUNDER_POSTING_ID = /^fb_[A-Za-z0-9_-]{1,80}$/;
|
|
51123
51212
|
CLAIM_SCREENSHOT_PUT_TIMEOUT_MS = 2e4;
|
|
51213
|
+
DEPENDENCY_SECTIONS2 = [
|
|
51214
|
+
"dependencies",
|
|
51215
|
+
"devDependencies",
|
|
51216
|
+
"optionalDependencies",
|
|
51217
|
+
"peerDependencies"
|
|
51218
|
+
];
|
|
51219
|
+
SENDABLE_LOCKFILES = [
|
|
51220
|
+
["package-lock.json", "npm install"],
|
|
51221
|
+
["yarn.lock", "yarn install"]
|
|
51222
|
+
];
|
|
51124
51223
|
CLAIM_RESOLUTION_REASONS = [
|
|
51125
51224
|
"not-my-stack",
|
|
51126
51225
|
"out-of-time",
|
package/dist/bin/jpi-mcp.js
CHANGED
|
@@ -31590,7 +31590,8 @@ var init_result = __esm({
|
|
|
31590
31590
|
"leakState",
|
|
31591
31591
|
"venue",
|
|
31592
31592
|
"refusalOrigin",
|
|
31593
|
-
"stoppedAt"
|
|
31593
|
+
"stoppedAt",
|
|
31594
|
+
"installFrozen"
|
|
31594
31595
|
];
|
|
31595
31596
|
RENDER_NONE = null;
|
|
31596
31597
|
FIELD_VIEWS = {
|
|
@@ -31655,7 +31656,10 @@ var init_result = __esm({
|
|
|
31655
31656
|
// side refused in words a developer reads.
|
|
31656
31657
|
refusalOrigin: RENDER_NONE,
|
|
31657
31658
|
// Only when the run did not pass: on a green run "the last step" is just the last step.
|
|
31658
|
-
stoppedAt: (r) => r.stoppedAt === null || r.outcome === "completed" ? null : `last step ${r.stoppedAt} (the last package script named in the output)
|
|
31659
|
+
stoppedAt: (r) => r.stoppedAt === null || r.outcome === "completed" ? null : `last step ${r.stoppedAt} (the last package script named in the output)`,
|
|
31660
|
+
// The run already prints the unfrozen note while it runs (`installUnfrozenNote`); this is
|
|
31661
|
+
// the record of it for the worker and the intake.
|
|
31662
|
+
installFrozen: RENDER_NONE
|
|
31659
31663
|
};
|
|
31660
31664
|
}
|
|
31661
31665
|
});
|
|
@@ -35693,6 +35697,10 @@ function nodeInstallCommand(repo) {
|
|
|
35693
35697
|
return null;
|
|
35694
35698
|
}
|
|
35695
35699
|
function lockfileGaps(repo) {
|
|
35700
|
+
const read = readLockfileGaps(repo);
|
|
35701
|
+
return read === null || read.missing.length === 0 ? null : { lockfile: read.lockfile, missing: read.missing };
|
|
35702
|
+
}
|
|
35703
|
+
function readLockfileGaps(repo) {
|
|
35696
35704
|
const pkg = readJsonObject(repo, "package.json");
|
|
35697
35705
|
if (pkg === null)
|
|
35698
35706
|
return null;
|
|
@@ -35719,7 +35727,7 @@ function lockfileGaps(repo) {
|
|
|
35719
35727
|
missing.push(`${n}@${r} (${dir})`);
|
|
35720
35728
|
}
|
|
35721
35729
|
}
|
|
35722
|
-
return
|
|
35730
|
+
return { lockfile, missing, rootRead: rootListing !== null };
|
|
35723
35731
|
}
|
|
35724
35732
|
function wantedDependencies(pkg) {
|
|
35725
35733
|
const wanted = [];
|
|
@@ -38220,7 +38228,9 @@ function refusedRun(fields) {
|
|
|
38220
38228
|
venue: null,
|
|
38221
38229
|
refusalOrigin: fields.origin,
|
|
38222
38230
|
// No test step ran, so there is no output to read a step from.
|
|
38223
|
-
stoppedAt: null
|
|
38231
|
+
stoppedAt: null,
|
|
38232
|
+
// Refused before any install step ran.
|
|
38233
|
+
installFrozen: null
|
|
38224
38234
|
};
|
|
38225
38235
|
}
|
|
38226
38236
|
function refusalOriginOf(refusal2) {
|
|
@@ -38304,7 +38314,29 @@ function installUnfrozenNote(spec) {
|
|
|
38304
38314
|
const u = spec.installUnfrozen;
|
|
38305
38315
|
if (u === void 0)
|
|
38306
38316
|
return null;
|
|
38307
|
-
return `${u.lockfile} does not list ${u.missing.join(", ")}, so the install ran as \`${String(spec.installCommand)}\` without its frozen-lockfile check.
|
|
38317
|
+
return `${u.lockfile} does not list ${u.missing.join(", ")}, so the install ran as \`${String(spec.installCommand)}\` without its frozen-lockfile check. Include the updated ${u.lockfile} in the patch, or regenerate it before merging.`;
|
|
38318
|
+
}
|
|
38319
|
+
function isFrozenInstallCommand(command) {
|
|
38320
|
+
const lead = /^(?:(?:sudo|time)\s+|env(?:\s+[A-Za-z_]\w*=\S*)*\s+)*/.exec(command)?.[0] ?? "";
|
|
38321
|
+
const install = command.slice(lead.length).split(/;|&&|\|\|/)[0]?.trim() ?? "";
|
|
38322
|
+
if (/^npm ci(\s|$)/.test(install))
|
|
38323
|
+
return true;
|
|
38324
|
+
if (/^(yarn|pnpm|bun)\b/.test(install) && /\s--frozen-lockfile(?=\s|$)/.test(install)) {
|
|
38325
|
+
return true;
|
|
38326
|
+
}
|
|
38327
|
+
return /^yarn\b/.test(install) && /\s--immutable(?=\s|$)/.test(install);
|
|
38328
|
+
}
|
|
38329
|
+
function installFrozenFor(spec, install) {
|
|
38330
|
+
if (install === null)
|
|
38331
|
+
return null;
|
|
38332
|
+
const launched = install.exitCode !== INSTALL_NEVER_STARTED && (install.exitCode !== null || install.timedOut);
|
|
38333
|
+
if (!launched)
|
|
38334
|
+
return null;
|
|
38335
|
+
if (spec.runtime !== "node")
|
|
38336
|
+
return null;
|
|
38337
|
+
if (spec.installUnfrozen !== void 0)
|
|
38338
|
+
return false;
|
|
38339
|
+
return isFrozenInstallCommand(install.command);
|
|
38308
38340
|
}
|
|
38309
38341
|
async function verifyWorkingDiff(req) {
|
|
38310
38342
|
const ctx = {
|
|
@@ -38673,7 +38705,8 @@ async function runVerification(req, ctx) {
|
|
|
38673
38705
|
// A run that reached a verdict was not refused, so neither side refused it.
|
|
38674
38706
|
refusalOrigin: null,
|
|
38675
38707
|
// Read from the full test output, not `outputTail`, which is an excerpt.
|
|
38676
|
-
stoppedAt: readStoppedAt(verdict.test?.stdout ?? "", verdict.test?.stderr ?? "")
|
|
38708
|
+
stoppedAt: readStoppedAt(verdict.test?.stdout ?? "", verdict.test?.stderr ?? ""),
|
|
38709
|
+
installFrozen: installFrozenFor(spec, verdict.install)
|
|
38677
38710
|
};
|
|
38678
38711
|
let later = null;
|
|
38679
38712
|
if (req.screenshots !== void 0) {
|
|
@@ -38872,7 +38905,7 @@ async function prepareBaseTree(o) {
|
|
|
38872
38905
|
throw err;
|
|
38873
38906
|
}
|
|
38874
38907
|
}
|
|
38875
|
-
var ThRunError, OUTPUT_TAIL_BYTES, LOCKFILE_READ_CAP, FULL_COMMIT_ID, ALLOWED_URL_SCHEMES, SCP_STYLE, URL_SCHEME, WINDOWS_ABSOLUTE, UNC_PATH, TRANSPORT_REASON, SHA_REASON, FULL_SHA, MIN_GIT_VERSION_FOR_END_OF_OPTIONS, CloneUnavailableError, GIT_ENV_ALLOWLIST, credentialFreeHomeDir, SSH_ISOLATION_ARGS, WITHHELD_SEGMENT, UNPARSEABLE_TARGET, DEFERRED_GATE_TIMEOUT_MS, FAILURE_LINE, REDACTED_TARGET_REPO, REDACTED_TARGET_SHA;
|
|
38908
|
+
var ThRunError, OUTPUT_TAIL_BYTES, LOCKFILE_READ_CAP, FULL_COMMIT_ID, ALLOWED_URL_SCHEMES, SCP_STYLE, URL_SCHEME, WINDOWS_ABSOLUTE, UNC_PATH, TRANSPORT_REASON, SHA_REASON, FULL_SHA, MIN_GIT_VERSION_FOR_END_OF_OPTIONS, CloneUnavailableError, GIT_ENV_ALLOWLIST, credentialFreeHomeDir, SSH_ISOLATION_ARGS, WITHHELD_SEGMENT, UNPARSEABLE_TARGET, DEFERRED_GATE_TIMEOUT_MS, FAILURE_LINE, REDACTED_TARGET_REPO, REDACTED_TARGET_SHA, INSTALL_NEVER_STARTED;
|
|
38876
38909
|
var init_thrun = __esm({
|
|
38877
38910
|
"../../packages/envrun/dist/thrun.js"() {
|
|
38878
38911
|
"use strict";
|
|
@@ -38961,6 +38994,7 @@ var init_thrun = __esm({
|
|
|
38961
38994
|
FAILURE_LINE = /^(?:[ \t]*(?:not ok |FAILED |FAIL )|E {3}|# fail [1-9])/m;
|
|
38962
38995
|
REDACTED_TARGET_REPO = "(refused before the target was accepted)";
|
|
38963
38996
|
REDACTED_TARGET_SHA = "(refused)";
|
|
38997
|
+
INSTALL_NEVER_STARTED = 125;
|
|
38964
38998
|
}
|
|
38965
38999
|
});
|
|
38966
39000
|
|
|
@@ -39862,6 +39896,7 @@ __export(dist_exports, {
|
|
|
39862
39896
|
imageRepo: () => imageRepo,
|
|
39863
39897
|
imageVariantFor: () => imageVariantFor,
|
|
39864
39898
|
installCommandFor: () => installCommandFor,
|
|
39899
|
+
installFrozenFor: () => installFrozenFor,
|
|
39865
39900
|
installLocalMigrationTooling: () => installLocalMigrationTooling,
|
|
39866
39901
|
installUnfrozenNote: () => installUnfrozenNote,
|
|
39867
39902
|
isBookkeepingTable: () => isBookkeepingTable,
|
|
@@ -44195,6 +44230,57 @@ async function uploadClaimScreenshots(intake, uploads) {
|
|
|
44195
44230
|
);
|
|
44196
44231
|
}
|
|
44197
44232
|
}
|
|
44233
|
+
async function packageJsonAt(wt, rev, path5) {
|
|
44234
|
+
let text;
|
|
44235
|
+
try {
|
|
44236
|
+
({ stdout: text } = await pExecFile("git", ["-C", wt, "show", `${rev}:${path5}`], {
|
|
44237
|
+
shell: false,
|
|
44238
|
+
maxBuffer: 16 * 1024 * 1024
|
|
44239
|
+
}));
|
|
44240
|
+
} catch {
|
|
44241
|
+
return {};
|
|
44242
|
+
}
|
|
44243
|
+
try {
|
|
44244
|
+
const parsed = JSON.parse(String(text));
|
|
44245
|
+
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
44246
|
+
} catch {
|
|
44247
|
+
return null;
|
|
44248
|
+
}
|
|
44249
|
+
}
|
|
44250
|
+
function sectionKey(pkg, section) {
|
|
44251
|
+
const value = pkg[section];
|
|
44252
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
44253
|
+
return JSON.stringify(value ?? null);
|
|
44254
|
+
}
|
|
44255
|
+
return JSON.stringify(Object.keys(value).sort().map((k) => [k, value[k]]));
|
|
44256
|
+
}
|
|
44257
|
+
async function patchChangesDependencies(wt, base, touched) {
|
|
44258
|
+
for (const path5 of touched) {
|
|
44259
|
+
if (path5.split("/").pop() !== "package.json") continue;
|
|
44260
|
+
const before = await packageJsonAt(wt, base, path5);
|
|
44261
|
+
const after = await packageJsonAt(wt, "HEAD", path5);
|
|
44262
|
+
if (before === null || after === null) continue;
|
|
44263
|
+
if (DEPENDENCY_SECTIONS2.some((s) => sectionKey(before, s) !== sectionKey(after, s))) return true;
|
|
44264
|
+
}
|
|
44265
|
+
return false;
|
|
44266
|
+
}
|
|
44267
|
+
async function dependencyLockfileWarnings(wt, base, touched) {
|
|
44268
|
+
if (!await patchChangesDependencies(wt, base, touched)) return [];
|
|
44269
|
+
const warnings = [];
|
|
44270
|
+
for (const [lockfile, cmd] of SENDABLE_LOCKFILES) {
|
|
44271
|
+
let present;
|
|
44272
|
+
try {
|
|
44273
|
+
present = (await sh("git", ["-C", wt, "ls-tree", "--name-only", base, "--", lockfile])).trim() === lockfile;
|
|
44274
|
+
} catch {
|
|
44275
|
+
present = false;
|
|
44276
|
+
}
|
|
44277
|
+
if (!present || touched.includes(lockfile)) continue;
|
|
44278
|
+
warnings.push(
|
|
44279
|
+
` \u26A0 package.json changes dependencies, but ${lockfile} is not in this patch. The run will install without its frozen-lockfile check. Run \`${cmd}\` and commit ${lockfile} to keep it frozen.`
|
|
44280
|
+
);
|
|
44281
|
+
}
|
|
44282
|
+
return warnings;
|
|
44283
|
+
}
|
|
44198
44284
|
async function submitFounderPatch({ claims, claim, id, wt, flags }) {
|
|
44199
44285
|
let roots;
|
|
44200
44286
|
try {
|
|
@@ -44245,6 +44331,9 @@ async function submitFounderPatch({ claims, claim, id, wt, flags }) {
|
|
|
44245
44331
|
);
|
|
44246
44332
|
process.exit(1);
|
|
44247
44333
|
}
|
|
44334
|
+
const lockfileWarnings = await dependencyLockfileWarnings(wt, base, touched);
|
|
44335
|
+
if (lockfileWarnings.length > 0) console.log(`
|
|
44336
|
+
${lockfileWarnings.join("\n")}`);
|
|
44248
44337
|
const authorName = await sh("git", ["-C", wt, "log", "-1", "--format=%an"]);
|
|
44249
44338
|
const authorEmail = await sh("git", ["-C", wt, "log", "-1", "--format=%ae"]);
|
|
44250
44339
|
const shots = flags.screenshots === void 0 ? null : loadClaimScreenshots(flags.screenshots);
|
|
@@ -45754,7 +45843,7 @@ async function run() {
|
|
|
45754
45843
|
process.exit(1);
|
|
45755
45844
|
}
|
|
45756
45845
|
}
|
|
45757
|
-
var TERMINALHIRE_DIR11, INDEX_CACHE_FILE2, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL, CLAIM_SYNC_BASE4, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, CLAIM_SYNC_WRITE_TIMEOUT_MS, GH_API2, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, BASELINE_STATUSES, MIN_TEST_BUDGET_MINUTES, MAX_TEST_BUDGET_MINUTES, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, SUBMIT_ACCEPTS, REVISE_RECOVERY_STATES, CLOSED_STATES, GH_SESSION_COOKIE, PUSH_TOKEN_REFUSAL, SYNC_BACKGROUND_PUSH_ACTIVE_FIELD, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS, OPENABLE_AGENTS, BRIEF_DIR, BRIEF_REL_PATH, VERIFY_REL_PATH, AGENTS_REL_PATH, BRIEF_EXCLUDE_LINE, PACK_SAFE_ID, CLAIM_EVENT_LABEL, LINE_BREAKS, CONTROL_CHARS3, FOUNDER_POSTING_ID, CLAIM_SCREENSHOT_PUT_TIMEOUT_MS, CLAIM_RESOLUTION_REASONS, SETUP_FAILED_REQUIREMENTS, POSTING_LEVEL_RESOLUTION_REASONS, RESOLUTION_REASON_BLURB;
|
|
45846
|
+
var TERMINALHIRE_DIR11, INDEX_CACHE_FILE2, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL, CLAIM_SYNC_BASE4, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, CLAIM_SYNC_WRITE_TIMEOUT_MS, GH_API2, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, BASELINE_STATUSES, MIN_TEST_BUDGET_MINUTES, MAX_TEST_BUDGET_MINUTES, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, SUBMIT_ACCEPTS, REVISE_RECOVERY_STATES, CLOSED_STATES, GH_SESSION_COOKIE, PUSH_TOKEN_REFUSAL, SYNC_BACKGROUND_PUSH_ACTIVE_FIELD, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS, OPENABLE_AGENTS, BRIEF_DIR, BRIEF_REL_PATH, VERIFY_REL_PATH, AGENTS_REL_PATH, BRIEF_EXCLUDE_LINE, PACK_SAFE_ID, CLAIM_EVENT_LABEL, LINE_BREAKS, CONTROL_CHARS3, FOUNDER_POSTING_ID, CLAIM_SCREENSHOT_PUT_TIMEOUT_MS, DEPENDENCY_SECTIONS2, SENDABLE_LOCKFILES, CLAIM_RESOLUTION_REASONS, SETUP_FAILED_REQUIREMENTS, POSTING_LEVEL_RESOLUTION_REASONS, RESOLUTION_REASON_BLURB;
|
|
45758
45847
|
var init_jpi_claim = __esm({
|
|
45759
45848
|
"bin/jpi-claim.js"() {
|
|
45760
45849
|
"use strict";
|
|
@@ -45887,6 +45976,16 @@ var init_jpi_claim = __esm({
|
|
|
45887
45976
|
CONTROL_CHARS3 = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
45888
45977
|
FOUNDER_POSTING_ID = /^fb_[A-Za-z0-9_-]{1,80}$/;
|
|
45889
45978
|
CLAIM_SCREENSHOT_PUT_TIMEOUT_MS = 2e4;
|
|
45979
|
+
DEPENDENCY_SECTIONS2 = [
|
|
45980
|
+
"dependencies",
|
|
45981
|
+
"devDependencies",
|
|
45982
|
+
"optionalDependencies",
|
|
45983
|
+
"peerDependencies"
|
|
45984
|
+
];
|
|
45985
|
+
SENDABLE_LOCKFILES = [
|
|
45986
|
+
["package-lock.json", "npm install"],
|
|
45987
|
+
["yarn.lock", "yarn install"]
|
|
45988
|
+
];
|
|
45890
45989
|
CLAIM_RESOLUTION_REASONS = [
|
|
45891
45990
|
"not-my-stack",
|
|
45892
45991
|
"out-of-time",
|
package/dist/bin/jpi-run.js
CHANGED
|
@@ -5424,7 +5424,8 @@ var init_result = __esm({
|
|
|
5424
5424
|
"leakState",
|
|
5425
5425
|
"venue",
|
|
5426
5426
|
"refusalOrigin",
|
|
5427
|
-
"stoppedAt"
|
|
5427
|
+
"stoppedAt",
|
|
5428
|
+
"installFrozen"
|
|
5428
5429
|
];
|
|
5429
5430
|
RENDER_NONE = null;
|
|
5430
5431
|
FIELD_VIEWS = {
|
|
@@ -5489,7 +5490,10 @@ var init_result = __esm({
|
|
|
5489
5490
|
// side refused in words a developer reads.
|
|
5490
5491
|
refusalOrigin: RENDER_NONE,
|
|
5491
5492
|
// Only when the run did not pass: on a green run "the last step" is just the last step.
|
|
5492
|
-
stoppedAt: (r) => r.stoppedAt === null || r.outcome === "completed" ? null : `last step ${r.stoppedAt} (the last package script named in the output)
|
|
5493
|
+
stoppedAt: (r) => r.stoppedAt === null || r.outcome === "completed" ? null : `last step ${r.stoppedAt} (the last package script named in the output)`,
|
|
5494
|
+
// The run already prints the unfrozen note while it runs (`installUnfrozenNote`); this is
|
|
5495
|
+
// the record of it for the worker and the intake.
|
|
5496
|
+
installFrozen: RENDER_NONE
|
|
5493
5497
|
};
|
|
5494
5498
|
}
|
|
5495
5499
|
});
|
|
@@ -9527,6 +9531,10 @@ function nodeInstallCommand(repo) {
|
|
|
9527
9531
|
return null;
|
|
9528
9532
|
}
|
|
9529
9533
|
function lockfileGaps(repo) {
|
|
9534
|
+
const read = readLockfileGaps(repo);
|
|
9535
|
+
return read === null || read.missing.length === 0 ? null : { lockfile: read.lockfile, missing: read.missing };
|
|
9536
|
+
}
|
|
9537
|
+
function readLockfileGaps(repo) {
|
|
9530
9538
|
const pkg = readJsonObject(repo, "package.json");
|
|
9531
9539
|
if (pkg === null)
|
|
9532
9540
|
return null;
|
|
@@ -9553,7 +9561,7 @@ function lockfileGaps(repo) {
|
|
|
9553
9561
|
missing.push(`${n}@${r} (${dir})`);
|
|
9554
9562
|
}
|
|
9555
9563
|
}
|
|
9556
|
-
return
|
|
9564
|
+
return { lockfile, missing, rootRead: rootListing !== null };
|
|
9557
9565
|
}
|
|
9558
9566
|
function wantedDependencies(pkg) {
|
|
9559
9567
|
const wanted = [];
|
|
@@ -12229,7 +12237,9 @@ function refusedRun(fields) {
|
|
|
12229
12237
|
venue: null,
|
|
12230
12238
|
refusalOrigin: fields.origin,
|
|
12231
12239
|
// No test step ran, so there is no output to read a step from.
|
|
12232
|
-
stoppedAt: null
|
|
12240
|
+
stoppedAt: null,
|
|
12241
|
+
// Refused before any install step ran.
|
|
12242
|
+
installFrozen: null
|
|
12233
12243
|
};
|
|
12234
12244
|
}
|
|
12235
12245
|
function refusalOriginOf(refusal2) {
|
|
@@ -12313,7 +12323,29 @@ function installUnfrozenNote(spec) {
|
|
|
12313
12323
|
const u = spec.installUnfrozen;
|
|
12314
12324
|
if (u === void 0)
|
|
12315
12325
|
return null;
|
|
12316
|
-
return `${u.lockfile} does not list ${u.missing.join(", ")}, so the install ran as \`${String(spec.installCommand)}\` without its frozen-lockfile check.
|
|
12326
|
+
return `${u.lockfile} does not list ${u.missing.join(", ")}, so the install ran as \`${String(spec.installCommand)}\` without its frozen-lockfile check. Include the updated ${u.lockfile} in the patch, or regenerate it before merging.`;
|
|
12327
|
+
}
|
|
12328
|
+
function isFrozenInstallCommand(command) {
|
|
12329
|
+
const lead = /^(?:(?:sudo|time)\s+|env(?:\s+[A-Za-z_]\w*=\S*)*\s+)*/.exec(command)?.[0] ?? "";
|
|
12330
|
+
const install = command.slice(lead.length).split(/;|&&|\|\|/)[0]?.trim() ?? "";
|
|
12331
|
+
if (/^npm ci(\s|$)/.test(install))
|
|
12332
|
+
return true;
|
|
12333
|
+
if (/^(yarn|pnpm|bun)\b/.test(install) && /\s--frozen-lockfile(?=\s|$)/.test(install)) {
|
|
12334
|
+
return true;
|
|
12335
|
+
}
|
|
12336
|
+
return /^yarn\b/.test(install) && /\s--immutable(?=\s|$)/.test(install);
|
|
12337
|
+
}
|
|
12338
|
+
function installFrozenFor(spec, install) {
|
|
12339
|
+
if (install === null)
|
|
12340
|
+
return null;
|
|
12341
|
+
const launched = install.exitCode !== INSTALL_NEVER_STARTED && (install.exitCode !== null || install.timedOut);
|
|
12342
|
+
if (!launched)
|
|
12343
|
+
return null;
|
|
12344
|
+
if (spec.runtime !== "node")
|
|
12345
|
+
return null;
|
|
12346
|
+
if (spec.installUnfrozen !== void 0)
|
|
12347
|
+
return false;
|
|
12348
|
+
return isFrozenInstallCommand(install.command);
|
|
12317
12349
|
}
|
|
12318
12350
|
async function verifyWorkingDiff(req) {
|
|
12319
12351
|
const ctx = {
|
|
@@ -12682,7 +12714,8 @@ async function runVerification(req, ctx) {
|
|
|
12682
12714
|
// A run that reached a verdict was not refused, so neither side refused it.
|
|
12683
12715
|
refusalOrigin: null,
|
|
12684
12716
|
// Read from the full test output, not `outputTail`, which is an excerpt.
|
|
12685
|
-
stoppedAt: readStoppedAt(verdict.test?.stdout ?? "", verdict.test?.stderr ?? "")
|
|
12717
|
+
stoppedAt: readStoppedAt(verdict.test?.stdout ?? "", verdict.test?.stderr ?? ""),
|
|
12718
|
+
installFrozen: installFrozenFor(spec, verdict.install)
|
|
12686
12719
|
};
|
|
12687
12720
|
let later = null;
|
|
12688
12721
|
if (req.screenshots !== void 0) {
|
|
@@ -12881,7 +12914,7 @@ async function prepareBaseTree(o) {
|
|
|
12881
12914
|
throw err;
|
|
12882
12915
|
}
|
|
12883
12916
|
}
|
|
12884
|
-
var ThRunError, OUTPUT_TAIL_BYTES, LOCKFILE_READ_CAP, FULL_COMMIT_ID, ALLOWED_URL_SCHEMES, SCP_STYLE, URL_SCHEME, WINDOWS_ABSOLUTE, UNC_PATH, TRANSPORT_REASON, SHA_REASON, FULL_SHA, MIN_GIT_VERSION_FOR_END_OF_OPTIONS, CloneUnavailableError, GIT_ENV_ALLOWLIST, credentialFreeHomeDir, SSH_ISOLATION_ARGS, WITHHELD_SEGMENT, UNPARSEABLE_TARGET, DEFERRED_GATE_TIMEOUT_MS, FAILURE_LINE, REDACTED_TARGET_REPO, REDACTED_TARGET_SHA;
|
|
12917
|
+
var ThRunError, OUTPUT_TAIL_BYTES, LOCKFILE_READ_CAP, FULL_COMMIT_ID, ALLOWED_URL_SCHEMES, SCP_STYLE, URL_SCHEME, WINDOWS_ABSOLUTE, UNC_PATH, TRANSPORT_REASON, SHA_REASON, FULL_SHA, MIN_GIT_VERSION_FOR_END_OF_OPTIONS, CloneUnavailableError, GIT_ENV_ALLOWLIST, credentialFreeHomeDir, SSH_ISOLATION_ARGS, WITHHELD_SEGMENT, UNPARSEABLE_TARGET, DEFERRED_GATE_TIMEOUT_MS, FAILURE_LINE, REDACTED_TARGET_REPO, REDACTED_TARGET_SHA, INSTALL_NEVER_STARTED;
|
|
12885
12918
|
var init_thrun = __esm({
|
|
12886
12919
|
"../../packages/envrun/dist/thrun.js"() {
|
|
12887
12920
|
"use strict";
|
|
@@ -12970,6 +13003,7 @@ var init_thrun = __esm({
|
|
|
12970
13003
|
FAILURE_LINE = /^(?:[ \t]*(?:not ok |FAILED |FAIL )|E {3}|# fail [1-9])/m;
|
|
12971
13004
|
REDACTED_TARGET_REPO = "(refused before the target was accepted)";
|
|
12972
13005
|
REDACTED_TARGET_SHA = "(refused)";
|
|
13006
|
+
INSTALL_NEVER_STARTED = 125;
|
|
12973
13007
|
}
|
|
12974
13008
|
});
|
|
12975
13009
|
|
|
@@ -13871,6 +13905,7 @@ __export(dist_exports, {
|
|
|
13871
13905
|
imageRepo: () => imageRepo,
|
|
13872
13906
|
imageVariantFor: () => imageVariantFor,
|
|
13873
13907
|
installCommandFor: () => installCommandFor,
|
|
13908
|
+
installFrozenFor: () => installFrozenFor,
|
|
13874
13909
|
installLocalMigrationTooling: () => installLocalMigrationTooling,
|
|
13875
13910
|
installUnfrozenNote: () => installUnfrozenNote,
|
|
13876
13911
|
isBookkeepingTable: () => isBookkeepingTable,
|
|
@@ -44188,6 +44223,57 @@ async function uploadClaimScreenshots(intake, uploads) {
|
|
|
44188
44223
|
);
|
|
44189
44224
|
}
|
|
44190
44225
|
}
|
|
44226
|
+
async function packageJsonAt(wt, rev, path5) {
|
|
44227
|
+
let text;
|
|
44228
|
+
try {
|
|
44229
|
+
({ stdout: text } = await pExecFile("git", ["-C", wt, "show", `${rev}:${path5}`], {
|
|
44230
|
+
shell: false,
|
|
44231
|
+
maxBuffer: 16 * 1024 * 1024
|
|
44232
|
+
}));
|
|
44233
|
+
} catch {
|
|
44234
|
+
return {};
|
|
44235
|
+
}
|
|
44236
|
+
try {
|
|
44237
|
+
const parsed = JSON.parse(String(text));
|
|
44238
|
+
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
44239
|
+
} catch {
|
|
44240
|
+
return null;
|
|
44241
|
+
}
|
|
44242
|
+
}
|
|
44243
|
+
function sectionKey(pkg, section) {
|
|
44244
|
+
const value = pkg[section];
|
|
44245
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
44246
|
+
return JSON.stringify(value ?? null);
|
|
44247
|
+
}
|
|
44248
|
+
return JSON.stringify(Object.keys(value).sort().map((k) => [k, value[k]]));
|
|
44249
|
+
}
|
|
44250
|
+
async function patchChangesDependencies(wt, base, touched) {
|
|
44251
|
+
for (const path5 of touched) {
|
|
44252
|
+
if (path5.split("/").pop() !== "package.json") continue;
|
|
44253
|
+
const before = await packageJsonAt(wt, base, path5);
|
|
44254
|
+
const after = await packageJsonAt(wt, "HEAD", path5);
|
|
44255
|
+
if (before === null || after === null) continue;
|
|
44256
|
+
if (DEPENDENCY_SECTIONS2.some((s) => sectionKey(before, s) !== sectionKey(after, s))) return true;
|
|
44257
|
+
}
|
|
44258
|
+
return false;
|
|
44259
|
+
}
|
|
44260
|
+
async function dependencyLockfileWarnings(wt, base, touched) {
|
|
44261
|
+
if (!await patchChangesDependencies(wt, base, touched)) return [];
|
|
44262
|
+
const warnings = [];
|
|
44263
|
+
for (const [lockfile, cmd] of SENDABLE_LOCKFILES) {
|
|
44264
|
+
let present;
|
|
44265
|
+
try {
|
|
44266
|
+
present = (await sh("git", ["-C", wt, "ls-tree", "--name-only", base, "--", lockfile])).trim() === lockfile;
|
|
44267
|
+
} catch {
|
|
44268
|
+
present = false;
|
|
44269
|
+
}
|
|
44270
|
+
if (!present || touched.includes(lockfile)) continue;
|
|
44271
|
+
warnings.push(
|
|
44272
|
+
` \u26A0 package.json changes dependencies, but ${lockfile} is not in this patch. The run will install without its frozen-lockfile check. Run \`${cmd}\` and commit ${lockfile} to keep it frozen.`
|
|
44273
|
+
);
|
|
44274
|
+
}
|
|
44275
|
+
return warnings;
|
|
44276
|
+
}
|
|
44191
44277
|
async function submitFounderPatch({ claims, claim, id, wt, flags }) {
|
|
44192
44278
|
let roots;
|
|
44193
44279
|
try {
|
|
@@ -44238,6 +44324,9 @@ async function submitFounderPatch({ claims, claim, id, wt, flags }) {
|
|
|
44238
44324
|
);
|
|
44239
44325
|
process.exit(1);
|
|
44240
44326
|
}
|
|
44327
|
+
const lockfileWarnings = await dependencyLockfileWarnings(wt, base, touched);
|
|
44328
|
+
if (lockfileWarnings.length > 0) console.log(`
|
|
44329
|
+
${lockfileWarnings.join("\n")}`);
|
|
44241
44330
|
const authorName = await sh("git", ["-C", wt, "log", "-1", "--format=%an"]);
|
|
44242
44331
|
const authorEmail = await sh("git", ["-C", wt, "log", "-1", "--format=%ae"]);
|
|
44243
44332
|
const shots = flags.screenshots === void 0 ? null : loadClaimScreenshots(flags.screenshots);
|
|
@@ -45747,7 +45836,7 @@ async function run() {
|
|
|
45747
45836
|
process.exit(1);
|
|
45748
45837
|
}
|
|
45749
45838
|
}
|
|
45750
|
-
var TERMINALHIRE_DIR11, INDEX_CACHE_FILE2, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL, CLAIM_SYNC_BASE4, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, CLAIM_SYNC_WRITE_TIMEOUT_MS, GH_API2, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, BASELINE_STATUSES, MIN_TEST_BUDGET_MINUTES, MAX_TEST_BUDGET_MINUTES, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, SUBMIT_ACCEPTS, REVISE_RECOVERY_STATES, CLOSED_STATES, GH_SESSION_COOKIE, PUSH_TOKEN_REFUSAL, SYNC_BACKGROUND_PUSH_ACTIVE_FIELD, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS, OPENABLE_AGENTS, BRIEF_DIR, BRIEF_REL_PATH, VERIFY_REL_PATH, AGENTS_REL_PATH, BRIEF_EXCLUDE_LINE, PACK_SAFE_ID, CLAIM_EVENT_LABEL, LINE_BREAKS, CONTROL_CHARS3, FOUNDER_POSTING_ID, CLAIM_SCREENSHOT_PUT_TIMEOUT_MS, CLAIM_RESOLUTION_REASONS, SETUP_FAILED_REQUIREMENTS, POSTING_LEVEL_RESOLUTION_REASONS, RESOLUTION_REASON_BLURB;
|
|
45839
|
+
var TERMINALHIRE_DIR11, INDEX_CACHE_FILE2, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL, CLAIM_SYNC_BASE4, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, CLAIM_SYNC_WRITE_TIMEOUT_MS, GH_API2, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, BASELINE_STATUSES, MIN_TEST_BUDGET_MINUTES, MAX_TEST_BUDGET_MINUTES, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, SUBMIT_ACCEPTS, REVISE_RECOVERY_STATES, CLOSED_STATES, GH_SESSION_COOKIE, PUSH_TOKEN_REFUSAL, SYNC_BACKGROUND_PUSH_ACTIVE_FIELD, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS, OPENABLE_AGENTS, BRIEF_DIR, BRIEF_REL_PATH, VERIFY_REL_PATH, AGENTS_REL_PATH, BRIEF_EXCLUDE_LINE, PACK_SAFE_ID, CLAIM_EVENT_LABEL, LINE_BREAKS, CONTROL_CHARS3, FOUNDER_POSTING_ID, CLAIM_SCREENSHOT_PUT_TIMEOUT_MS, DEPENDENCY_SECTIONS2, SENDABLE_LOCKFILES, CLAIM_RESOLUTION_REASONS, SETUP_FAILED_REQUIREMENTS, POSTING_LEVEL_RESOLUTION_REASONS, RESOLUTION_REASON_BLURB;
|
|
45751
45840
|
var init_jpi_claim = __esm({
|
|
45752
45841
|
"bin/jpi-claim.js"() {
|
|
45753
45842
|
"use strict";
|
|
@@ -45880,6 +45969,16 @@ var init_jpi_claim = __esm({
|
|
|
45880
45969
|
CONTROL_CHARS3 = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
45881
45970
|
FOUNDER_POSTING_ID = /^fb_[A-Za-z0-9_-]{1,80}$/;
|
|
45882
45971
|
CLAIM_SCREENSHOT_PUT_TIMEOUT_MS = 2e4;
|
|
45972
|
+
DEPENDENCY_SECTIONS2 = [
|
|
45973
|
+
"dependencies",
|
|
45974
|
+
"devDependencies",
|
|
45975
|
+
"optionalDependencies",
|
|
45976
|
+
"peerDependencies"
|
|
45977
|
+
];
|
|
45978
|
+
SENDABLE_LOCKFILES = [
|
|
45979
|
+
["package-lock.json", "npm install"],
|
|
45980
|
+
["yarn.lock", "yarn install"]
|
|
45981
|
+
];
|
|
45883
45982
|
CLAIM_RESOLUTION_REASONS = [
|
|
45884
45983
|
"not-my-stack",
|
|
45885
45984
|
"out-of-time",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "terminalhire",
|
|
3
|
-
"version": "0.42.
|
|
3
|
+
"version": "0.42.42",
|
|
4
4
|
"description": "Developer jobs and paid bounties, matched in the terminal — ambient matches in the Claude Code spinner. Claim a scoped bounty and get paid when the poster accepts it.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|