terminalhire 0.40.2 → 0.40.4
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/claim-push-bg.js +18 -1
- package/dist/bin/founder-paid-badge.js +1 -2
- package/dist/bin/jpi-bounties.js +20 -4
- package/dist/bin/jpi-claim.js +56 -3
- package/dist/bin/jpi-contribute.js +19 -2
- package/dist/bin/jpi-dispatch.js +86 -10
- package/dist/bin/jpi-hub.js +20 -3
- package/dist/bin/jpi-jobs.js +1 -1
- package/dist/bin/jpi-mcp.js +57 -4
- package/dist/bin/jpi-refresh.js +44 -4
- package/dist/bin/jpi-repo.js +18 -1
- package/dist/src/claims.js +17 -0
- package/package.json +1 -1
|
@@ -90,6 +90,7 @@ var init_state_dir = __esm({
|
|
|
90
90
|
// src/claims.ts
|
|
91
91
|
var claims_exports = {};
|
|
92
92
|
__export(claims_exports, {
|
|
93
|
+
CLAIM_STATES: () => CLAIM_STATES,
|
|
93
94
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
94
95
|
acceptedPRRate: () => acceptedPRRate,
|
|
95
96
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
@@ -288,7 +289,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
288
289
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
289
290
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
290
291
|
}
|
|
291
|
-
var TERMINALHIRE_DIR3, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
292
|
+
var TERMINALHIRE_DIR3, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
292
293
|
var init_claims = __esm({
|
|
293
294
|
"src/claims.ts"() {
|
|
294
295
|
"use strict";
|
|
@@ -299,6 +300,22 @@ var init_claims = __esm({
|
|
|
299
300
|
LOCK_STALE_MS = Number(process.env.TERMINALHIRE_LOCK_STALE_MS) || 1e4;
|
|
300
301
|
LOCK_RETRY_MS = Number(process.env.TERMINALHIRE_LOCK_RETRY_MS) || 25;
|
|
301
302
|
LOCK_TIMEOUT_MS = Number(process.env.TERMINALHIRE_LOCK_TIMEOUT_MS) || 5e3;
|
|
303
|
+
CLAIM_STATES = Object.freeze([
|
|
304
|
+
"claimed",
|
|
305
|
+
// recorded, not started
|
|
306
|
+
"working",
|
|
307
|
+
// background executor running / work in progress
|
|
308
|
+
"in-review",
|
|
309
|
+
// gate ran / dev reviewing the diff
|
|
310
|
+
"ready",
|
|
311
|
+
// passed review, cleared to submit
|
|
312
|
+
"submitted",
|
|
313
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
314
|
+
"merged",
|
|
315
|
+
// PR merged — accepted; counts toward the metric
|
|
316
|
+
"abandoned"
|
|
317
|
+
// released, or PR closed unmerged
|
|
318
|
+
]);
|
|
302
319
|
PUSHED_CLAIM_FIELDS = [
|
|
303
320
|
"kind",
|
|
304
321
|
"repoFullName",
|
|
@@ -21,8 +21,7 @@ function gate(openIds, seenIds) {
|
|
|
21
21
|
function computeFounderPaid(index, previous) {
|
|
22
22
|
const open = openPaidIds(index);
|
|
23
23
|
const prior = previous && previous.acknowledged;
|
|
24
|
-
|
|
25
|
-
return gate(open, prior);
|
|
24
|
+
return gate(open, Array.isArray(prior) ? prior : []);
|
|
26
25
|
}
|
|
27
26
|
function acknowledgeFounderPaid({ shown = [], open = [], previous } = {}) {
|
|
28
27
|
const prior = previous && Array.isArray(previous.acknowledged) ? previous.acknowledged : [];
|
package/dist/bin/jpi-bounties.js
CHANGED
|
@@ -11122,6 +11122,7 @@ var init_repo_experience = __esm({
|
|
|
11122
11122
|
// src/claims.ts
|
|
11123
11123
|
var claims_exports = {};
|
|
11124
11124
|
__export(claims_exports, {
|
|
11125
|
+
CLAIM_STATES: () => CLAIM_STATES,
|
|
11125
11126
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
11126
11127
|
acceptedPRRate: () => acceptedPRRate,
|
|
11127
11128
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
@@ -11320,7 +11321,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
11320
11321
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
11321
11322
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
11322
11323
|
}
|
|
11323
|
-
var TERMINALHIRE_DIR5, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
11324
|
+
var TERMINALHIRE_DIR5, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
11324
11325
|
var init_claims = __esm({
|
|
11325
11326
|
"src/claims.ts"() {
|
|
11326
11327
|
"use strict";
|
|
@@ -11331,6 +11332,22 @@ var init_claims = __esm({
|
|
|
11331
11332
|
LOCK_STALE_MS = Number(process.env.TERMINALHIRE_LOCK_STALE_MS) || 1e4;
|
|
11332
11333
|
LOCK_RETRY_MS = Number(process.env.TERMINALHIRE_LOCK_RETRY_MS) || 25;
|
|
11333
11334
|
LOCK_TIMEOUT_MS = Number(process.env.TERMINALHIRE_LOCK_TIMEOUT_MS) || 5e3;
|
|
11335
|
+
CLAIM_STATES = Object.freeze([
|
|
11336
|
+
"claimed",
|
|
11337
|
+
// recorded, not started
|
|
11338
|
+
"working",
|
|
11339
|
+
// background executor running / work in progress
|
|
11340
|
+
"in-review",
|
|
11341
|
+
// gate ran / dev reviewing the diff
|
|
11342
|
+
"ready",
|
|
11343
|
+
// passed review, cleared to submit
|
|
11344
|
+
"submitted",
|
|
11345
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
11346
|
+
"merged",
|
|
11347
|
+
// PR merged — accepted; counts toward the metric
|
|
11348
|
+
"abandoned"
|
|
11349
|
+
// released, or PR closed unmerged
|
|
11350
|
+
]);
|
|
11334
11351
|
PUSHED_CLAIM_FIELDS = [
|
|
11335
11352
|
"kind",
|
|
11336
11353
|
"repoFullName",
|
|
@@ -11387,8 +11404,7 @@ function gate(openIds, seenIds) {
|
|
|
11387
11404
|
function computeFounderPaid(index, previous) {
|
|
11388
11405
|
const open = openPaidIds(index);
|
|
11389
11406
|
const prior = previous && previous.acknowledged;
|
|
11390
|
-
|
|
11391
|
-
return gate(open, prior);
|
|
11407
|
+
return gate(open, Array.isArray(prior) ? prior : []);
|
|
11392
11408
|
}
|
|
11393
11409
|
function acknowledgeFounderPaid({ shown = [], open = [], previous } = {}) {
|
|
11394
11410
|
const prior = previous && Array.isArray(previous.acknowledged) ? previous.acknowledged : [];
|
|
@@ -11465,7 +11481,7 @@ function readIndexCache() {
|
|
|
11465
11481
|
}
|
|
11466
11482
|
}
|
|
11467
11483
|
function writeIndexCache(index) {
|
|
11468
|
-
updateIndexCache({ index });
|
|
11484
|
+
updateIndexCache({ index, indexETag: "" });
|
|
11469
11485
|
}
|
|
11470
11486
|
async function fetchIndex() {
|
|
11471
11487
|
const cached = readIndexCache();
|
package/dist/bin/jpi-claim.js
CHANGED
|
@@ -10431,6 +10431,7 @@ var init_state_dir = __esm({
|
|
|
10431
10431
|
// src/claims.ts
|
|
10432
10432
|
var claims_exports = {};
|
|
10433
10433
|
__export(claims_exports, {
|
|
10434
|
+
CLAIM_STATES: () => CLAIM_STATES,
|
|
10434
10435
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
10435
10436
|
acceptedPRRate: () => acceptedPRRate,
|
|
10436
10437
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
@@ -10629,7 +10630,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
10629
10630
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
10630
10631
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
10631
10632
|
}
|
|
10632
|
-
var TERMINALHIRE_DIR2, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
10633
|
+
var TERMINALHIRE_DIR2, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
10633
10634
|
var init_claims = __esm({
|
|
10634
10635
|
"src/claims.ts"() {
|
|
10635
10636
|
"use strict";
|
|
@@ -10640,6 +10641,22 @@ var init_claims = __esm({
|
|
|
10640
10641
|
LOCK_STALE_MS = Number(process.env.TERMINALHIRE_LOCK_STALE_MS) || 1e4;
|
|
10641
10642
|
LOCK_RETRY_MS = Number(process.env.TERMINALHIRE_LOCK_RETRY_MS) || 25;
|
|
10642
10643
|
LOCK_TIMEOUT_MS = Number(process.env.TERMINALHIRE_LOCK_TIMEOUT_MS) || 5e3;
|
|
10644
|
+
CLAIM_STATES = Object.freeze([
|
|
10645
|
+
"claimed",
|
|
10646
|
+
// recorded, not started
|
|
10647
|
+
"working",
|
|
10648
|
+
// background executor running / work in progress
|
|
10649
|
+
"in-review",
|
|
10650
|
+
// gate ran / dev reviewing the diff
|
|
10651
|
+
"ready",
|
|
10652
|
+
// passed review, cleared to submit
|
|
10653
|
+
"submitted",
|
|
10654
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
10655
|
+
"merged",
|
|
10656
|
+
// PR merged — accepted; counts toward the metric
|
|
10657
|
+
"abandoned"
|
|
10658
|
+
// released, or PR closed unmerged
|
|
10659
|
+
]);
|
|
10643
10660
|
PUSHED_CLAIM_FIELDS = [
|
|
10644
10661
|
"kind",
|
|
10645
10662
|
"repoFullName",
|
|
@@ -26705,6 +26722,38 @@ function printMetric(rate) {
|
|
|
26705
26722
|
console.log(`
|
|
26706
26723
|
\u{1F4CA} Accepted-PR rate: ${rate.merged}/${rate.total} claims merged (${pct}%)`);
|
|
26707
26724
|
}
|
|
26725
|
+
var SUBMIT_ACCEPTS = Object.freeze(["working", "ready"]);
|
|
26726
|
+
function nextStepFor(c) {
|
|
26727
|
+
const founder = Boolean(c.approval);
|
|
26728
|
+
switch (c.state) {
|
|
26729
|
+
case "claimed":
|
|
26730
|
+
return founder ? { cmd: `terminalhire claim slice ${c.id}`, why: "collect your granted work slice" } : { cmd: `terminalhire claim start ${c.id}`, why: "fork + clone into a worktree" };
|
|
26731
|
+
// NOT grouped with the two below. `cmdSubmit` accepts 'working' and 'ready'
|
|
26732
|
+
// and nothing else, so pointing an 'in-review' claim at submit would hand the
|
|
26733
|
+
// developer a command that exits 1 — and submit's own refusal then advises
|
|
26734
|
+
// `claim start`, which a founder claim can never use either. Two dead ends in
|
|
26735
|
+
// a row is worse than the silence this block replaced.
|
|
26736
|
+
case "in-review":
|
|
26737
|
+
return {
|
|
26738
|
+
cmd: `terminalhire claim update ${c.id} ready`,
|
|
26739
|
+
why: "clear the review gate \u2014 submit only accepts working/ready"
|
|
26740
|
+
};
|
|
26741
|
+
case "working":
|
|
26742
|
+
case "ready":
|
|
26743
|
+
return { cmd: `terminalhire claim submit ${c.id}`, why: "push the branch + open the PR" };
|
|
26744
|
+
case "submitted":
|
|
26745
|
+
return founder ? { cmd: `terminalhire claim runs ${c.id} --watch`, why: "read the CI result" } : { cmd: `terminalhire claim status ${c.id}`, why: "poll the PR merge state" };
|
|
26746
|
+
default:
|
|
26747
|
+
return null;
|
|
26748
|
+
}
|
|
26749
|
+
}
|
|
26750
|
+
function printNextSteps(list) {
|
|
26751
|
+
const steps = list.map(nextStepFor).filter(Boolean);
|
|
26752
|
+
if (steps.length === 0) return;
|
|
26753
|
+
const width = Math.max(...steps.map((s) => s.cmd.length));
|
|
26754
|
+
console.log("\n Next:");
|
|
26755
|
+
for (const s of steps) console.log(` ${s.cmd.padEnd(width)} \u2014 ${s.why}`);
|
|
26756
|
+
}
|
|
26708
26757
|
async function resolveBounty(arg) {
|
|
26709
26758
|
let bountyId, title, repoFullName, issueUrl, amountUSD, source, openPRsAtDiscovery, indexNativeId;
|
|
26710
26759
|
let founderPosting = false;
|
|
@@ -27276,6 +27325,7 @@ ${list.length} ${active ? "active " : ""}claim${list.length === 1 ? "" : "s"}:
|
|
|
27276
27325
|
console.log(` id: ${c.id}${pr}`);
|
|
27277
27326
|
}
|
|
27278
27327
|
printMetric(claims.acceptedPRRate());
|
|
27328
|
+
printNextSteps(list);
|
|
27279
27329
|
try {
|
|
27280
27330
|
if (await shouldNudgeUnpushed()) {
|
|
27281
27331
|
console.log(
|
|
@@ -27424,7 +27474,7 @@ async function cmdStatus(id) {
|
|
|
27424
27474
|
}
|
|
27425
27475
|
async function cmdUpdate(id, state, prUrl) {
|
|
27426
27476
|
const claims = await Promise.resolve().then(() => (init_claims(), claims_exports));
|
|
27427
|
-
const VALID =
|
|
27477
|
+
const VALID = claims.CLAIM_STATES;
|
|
27428
27478
|
if (!id || !state || !VALID.includes(state)) {
|
|
27429
27479
|
console.error("Usage: terminalhire claim update <id> <state> [prUrl]");
|
|
27430
27480
|
console.error(" state: " + VALID.join(" | "));
|
|
@@ -28284,7 +28334,7 @@ async function cmdSubmit(id, flags = {}) {
|
|
|
28284
28334
|
console.error(`terminalhire claim: no claim with id '${id}'.`);
|
|
28285
28335
|
process.exit(1);
|
|
28286
28336
|
}
|
|
28287
|
-
if (
|
|
28337
|
+
if (!SUBMIT_ACCEPTS.includes(claim.state)) {
|
|
28288
28338
|
console.error(
|
|
28289
28339
|
`terminalhire claim: ${id} is '${claim.state}'. Submit runs once work has started ('working', via 'claim start') or the review gate cleared it ('ready'). Start it first:
|
|
28290
28340
|
terminalhire claim start ${id}`
|
|
@@ -29236,6 +29286,7 @@ async function run() {
|
|
|
29236
29286
|
export {
|
|
29237
29287
|
AI_DISCLOSURE_NOTE,
|
|
29238
29288
|
CLAIM_CONSENT_VERSION,
|
|
29289
|
+
SUBMIT_ACCEPTS,
|
|
29239
29290
|
backgroundEnableFailed,
|
|
29240
29291
|
buildAssignmentComment,
|
|
29241
29292
|
buildPatchSubmission,
|
|
@@ -29261,9 +29312,11 @@ export {
|
|
|
29261
29312
|
listMergedPRsReferencingIssue,
|
|
29262
29313
|
listOpenPRsReferencingIssue,
|
|
29263
29314
|
matchReferencingPrs,
|
|
29315
|
+
nextStepFor,
|
|
29264
29316
|
normalizeIntent,
|
|
29265
29317
|
pickBodySource,
|
|
29266
29318
|
pickExistingPr,
|
|
29319
|
+
printNextSteps,
|
|
29267
29320
|
renderRunView,
|
|
29268
29321
|
renderServerRefusal,
|
|
29269
29322
|
resolveBounty,
|
|
@@ -3515,6 +3515,7 @@ var init_repo_experience = __esm({
|
|
|
3515
3515
|
// src/claims.ts
|
|
3516
3516
|
var claims_exports = {};
|
|
3517
3517
|
__export(claims_exports, {
|
|
3518
|
+
CLAIM_STATES: () => CLAIM_STATES,
|
|
3518
3519
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
3519
3520
|
acceptedPRRate: () => acceptedPRRate,
|
|
3520
3521
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
@@ -3713,7 +3714,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
3713
3714
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
3714
3715
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
3715
3716
|
}
|
|
3716
|
-
var TERMINALHIRE_DIR7, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
3717
|
+
var TERMINALHIRE_DIR7, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
3717
3718
|
var init_claims = __esm({
|
|
3718
3719
|
"src/claims.ts"() {
|
|
3719
3720
|
"use strict";
|
|
@@ -3724,6 +3725,22 @@ var init_claims = __esm({
|
|
|
3724
3725
|
LOCK_STALE_MS = Number(process.env.TERMINALHIRE_LOCK_STALE_MS) || 1e4;
|
|
3725
3726
|
LOCK_RETRY_MS = Number(process.env.TERMINALHIRE_LOCK_RETRY_MS) || 25;
|
|
3726
3727
|
LOCK_TIMEOUT_MS = Number(process.env.TERMINALHIRE_LOCK_TIMEOUT_MS) || 5e3;
|
|
3728
|
+
CLAIM_STATES = Object.freeze([
|
|
3729
|
+
"claimed",
|
|
3730
|
+
// recorded, not started
|
|
3731
|
+
"working",
|
|
3732
|
+
// background executor running / work in progress
|
|
3733
|
+
"in-review",
|
|
3734
|
+
// gate ran / dev reviewing the diff
|
|
3735
|
+
"ready",
|
|
3736
|
+
// passed review, cleared to submit
|
|
3737
|
+
"submitted",
|
|
3738
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
3739
|
+
"merged",
|
|
3740
|
+
// PR merged — accepted; counts toward the metric
|
|
3741
|
+
"abandoned"
|
|
3742
|
+
// released, or PR closed unmerged
|
|
3743
|
+
]);
|
|
3727
3744
|
PUSHED_CLAIM_FIELDS = [
|
|
3728
3745
|
"kind",
|
|
3729
3746
|
"repoFullName",
|
|
@@ -4095,7 +4112,7 @@ function readIndexCache() {
|
|
|
4095
4112
|
}
|
|
4096
4113
|
}
|
|
4097
4114
|
function writeIndexCache(index) {
|
|
4098
|
-
updateIndexCache({ index });
|
|
4115
|
+
updateIndexCache({ index, indexETag: "" });
|
|
4099
4116
|
}
|
|
4100
4117
|
async function fetchIndex(fetchImpl, useCache = true) {
|
|
4101
4118
|
if (useCache) {
|
package/dist/bin/jpi-dispatch.js
CHANGED
|
@@ -13710,7 +13710,7 @@ function readIndexCache() {
|
|
|
13710
13710
|
}
|
|
13711
13711
|
}
|
|
13712
13712
|
function writeIndexCache(index) {
|
|
13713
|
-
updateIndexCache({ index });
|
|
13713
|
+
updateIndexCache({ index, indexETag: "" });
|
|
13714
13714
|
}
|
|
13715
13715
|
async function fetchIndex() {
|
|
13716
13716
|
const cached2 = readIndexCache();
|
|
@@ -14859,6 +14859,7 @@ var init_repo_experience = __esm({
|
|
|
14859
14859
|
// src/claims.ts
|
|
14860
14860
|
var claims_exports = {};
|
|
14861
14861
|
__export(claims_exports, {
|
|
14862
|
+
CLAIM_STATES: () => CLAIM_STATES,
|
|
14862
14863
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
14863
14864
|
acceptedPRRate: () => acceptedPRRate,
|
|
14864
14865
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
@@ -15057,7 +15058,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
15057
15058
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
15058
15059
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
15059
15060
|
}
|
|
15060
|
-
var TERMINALHIRE_DIR11, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS2, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
15061
|
+
var TERMINALHIRE_DIR11, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS2, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
15061
15062
|
var init_claims = __esm({
|
|
15062
15063
|
"src/claims.ts"() {
|
|
15063
15064
|
"use strict";
|
|
@@ -15068,6 +15069,22 @@ var init_claims = __esm({
|
|
|
15068
15069
|
LOCK_STALE_MS2 = Number(process.env.TERMINALHIRE_LOCK_STALE_MS) || 1e4;
|
|
15069
15070
|
LOCK_RETRY_MS = Number(process.env.TERMINALHIRE_LOCK_RETRY_MS) || 25;
|
|
15070
15071
|
LOCK_TIMEOUT_MS = Number(process.env.TERMINALHIRE_LOCK_TIMEOUT_MS) || 5e3;
|
|
15072
|
+
CLAIM_STATES = Object.freeze([
|
|
15073
|
+
"claimed",
|
|
15074
|
+
// recorded, not started
|
|
15075
|
+
"working",
|
|
15076
|
+
// background executor running / work in progress
|
|
15077
|
+
"in-review",
|
|
15078
|
+
// gate ran / dev reviewing the diff
|
|
15079
|
+
"ready",
|
|
15080
|
+
// passed review, cleared to submit
|
|
15081
|
+
"submitted",
|
|
15082
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
15083
|
+
"merged",
|
|
15084
|
+
// PR merged — accepted; counts toward the metric
|
|
15085
|
+
"abandoned"
|
|
15086
|
+
// released, or PR closed unmerged
|
|
15087
|
+
]);
|
|
15071
15088
|
PUSHED_CLAIM_FIELDS = [
|
|
15072
15089
|
"kind",
|
|
15073
15090
|
"repoFullName",
|
|
@@ -15124,8 +15141,7 @@ function gate(openIds, seenIds) {
|
|
|
15124
15141
|
function computeFounderPaid(index, previous) {
|
|
15125
15142
|
const open3 = openPaidIds(index);
|
|
15126
15143
|
const prior = previous && previous.acknowledged;
|
|
15127
|
-
|
|
15128
|
-
return gate(open3, prior);
|
|
15144
|
+
return gate(open3, Array.isArray(prior) ? prior : []);
|
|
15129
15145
|
}
|
|
15130
15146
|
function acknowledgeFounderPaid({ shown = [], open: open3 = [], previous } = {}) {
|
|
15131
15147
|
const prior = previous && Array.isArray(previous.acknowledged) ? previous.acknowledged : [];
|
|
@@ -15165,7 +15181,7 @@ function readIndexCache2() {
|
|
|
15165
15181
|
}
|
|
15166
15182
|
}
|
|
15167
15183
|
function writeIndexCache2(index) {
|
|
15168
|
-
updateIndexCache({ index });
|
|
15184
|
+
updateIndexCache({ index, indexETag: "" });
|
|
15169
15185
|
}
|
|
15170
15186
|
async function fetchIndex2() {
|
|
15171
15187
|
const cached2 = readIndexCache2();
|
|
@@ -15659,7 +15675,7 @@ function readIndexCache3() {
|
|
|
15659
15675
|
}
|
|
15660
15676
|
}
|
|
15661
15677
|
function writeIndexCache3(index) {
|
|
15662
|
-
updateIndexCache({ index });
|
|
15678
|
+
updateIndexCache({ index, indexETag: "" });
|
|
15663
15679
|
}
|
|
15664
15680
|
async function fetchIndex3(fetchImpl, useCache = true) {
|
|
15665
15681
|
if (useCache) {
|
|
@@ -30463,6 +30479,7 @@ var jpi_claim_exports = {};
|
|
|
30463
30479
|
__export(jpi_claim_exports, {
|
|
30464
30480
|
AI_DISCLOSURE_NOTE: () => AI_DISCLOSURE_NOTE,
|
|
30465
30481
|
CLAIM_CONSENT_VERSION: () => CLAIM_CONSENT_VERSION,
|
|
30482
|
+
SUBMIT_ACCEPTS: () => SUBMIT_ACCEPTS,
|
|
30466
30483
|
backgroundEnableFailed: () => backgroundEnableFailed,
|
|
30467
30484
|
buildAssignmentComment: () => buildAssignmentComment,
|
|
30468
30485
|
buildPatchSubmission: () => buildPatchSubmission,
|
|
@@ -30488,9 +30505,11 @@ __export(jpi_claim_exports, {
|
|
|
30488
30505
|
listMergedPRsReferencingIssue: () => listMergedPRsReferencingIssue,
|
|
30489
30506
|
listOpenPRsReferencingIssue: () => listOpenPRsReferencingIssue,
|
|
30490
30507
|
matchReferencingPrs: () => matchReferencingPrs,
|
|
30508
|
+
nextStepFor: () => nextStepFor,
|
|
30491
30509
|
normalizeIntent: () => normalizeIntent,
|
|
30492
30510
|
pickBodySource: () => pickBodySource,
|
|
30493
30511
|
pickExistingPr: () => pickExistingPr,
|
|
30512
|
+
printNextSteps: () => printNextSteps,
|
|
30494
30513
|
renderRunView: () => renderRunView,
|
|
30495
30514
|
renderServerRefusal: () => renderServerRefusal,
|
|
30496
30515
|
resolveBounty: () => resolveBounty,
|
|
@@ -31167,6 +31186,37 @@ function printMetric(rate) {
|
|
|
31167
31186
|
console.log(`
|
|
31168
31187
|
\u{1F4CA} Accepted-PR rate: ${rate.merged}/${rate.total} claims merged (${pct2}%)`);
|
|
31169
31188
|
}
|
|
31189
|
+
function nextStepFor(c) {
|
|
31190
|
+
const founder = Boolean(c.approval);
|
|
31191
|
+
switch (c.state) {
|
|
31192
|
+
case "claimed":
|
|
31193
|
+
return founder ? { cmd: `terminalhire claim slice ${c.id}`, why: "collect your granted work slice" } : { cmd: `terminalhire claim start ${c.id}`, why: "fork + clone into a worktree" };
|
|
31194
|
+
// NOT grouped with the two below. `cmdSubmit` accepts 'working' and 'ready'
|
|
31195
|
+
// and nothing else, so pointing an 'in-review' claim at submit would hand the
|
|
31196
|
+
// developer a command that exits 1 — and submit's own refusal then advises
|
|
31197
|
+
// `claim start`, which a founder claim can never use either. Two dead ends in
|
|
31198
|
+
// a row is worse than the silence this block replaced.
|
|
31199
|
+
case "in-review":
|
|
31200
|
+
return {
|
|
31201
|
+
cmd: `terminalhire claim update ${c.id} ready`,
|
|
31202
|
+
why: "clear the review gate \u2014 submit only accepts working/ready"
|
|
31203
|
+
};
|
|
31204
|
+
case "working":
|
|
31205
|
+
case "ready":
|
|
31206
|
+
return { cmd: `terminalhire claim submit ${c.id}`, why: "push the branch + open the PR" };
|
|
31207
|
+
case "submitted":
|
|
31208
|
+
return founder ? { cmd: `terminalhire claim runs ${c.id} --watch`, why: "read the CI result" } : { cmd: `terminalhire claim status ${c.id}`, why: "poll the PR merge state" };
|
|
31209
|
+
default:
|
|
31210
|
+
return null;
|
|
31211
|
+
}
|
|
31212
|
+
}
|
|
31213
|
+
function printNextSteps(list) {
|
|
31214
|
+
const steps = list.map(nextStepFor).filter(Boolean);
|
|
31215
|
+
if (steps.length === 0) return;
|
|
31216
|
+
const width = Math.max(...steps.map((s) => s.cmd.length));
|
|
31217
|
+
console.log("\n Next:");
|
|
31218
|
+
for (const s of steps) console.log(` ${s.cmd.padEnd(width)} \u2014 ${s.why}`);
|
|
31219
|
+
}
|
|
31170
31220
|
async function resolveBounty(arg) {
|
|
31171
31221
|
let bountyId, title, repoFullName, issueUrl, amountUSD, source, openPRsAtDiscovery, indexNativeId;
|
|
31172
31222
|
let founderPosting = false;
|
|
@@ -31738,6 +31788,7 @@ ${list.length} ${active ? "active " : ""}claim${list.length === 1 ? "" : "s"}:
|
|
|
31738
31788
|
console.log(` id: ${c.id}${pr}`);
|
|
31739
31789
|
}
|
|
31740
31790
|
printMetric(claims.acceptedPRRate());
|
|
31791
|
+
printNextSteps(list);
|
|
31741
31792
|
try {
|
|
31742
31793
|
if (await shouldNudgeUnpushed()) {
|
|
31743
31794
|
console.log(
|
|
@@ -31885,7 +31936,7 @@ async function cmdStatus(id) {
|
|
|
31885
31936
|
}
|
|
31886
31937
|
async function cmdUpdate(id, state, prUrl) {
|
|
31887
31938
|
const claims = await Promise.resolve().then(() => (init_claims(), claims_exports));
|
|
31888
|
-
const VALID =
|
|
31939
|
+
const VALID = claims.CLAIM_STATES;
|
|
31889
31940
|
if (!id || !state || !VALID.includes(state)) {
|
|
31890
31941
|
console.error("Usage: terminalhire claim update <id> <state> [prUrl]");
|
|
31891
31942
|
console.error(" state: " + VALID.join(" | "));
|
|
@@ -32743,7 +32794,7 @@ async function cmdSubmit(id, flags = {}) {
|
|
|
32743
32794
|
console.error(`terminalhire claim: no claim with id '${id}'.`);
|
|
32744
32795
|
process.exit(1);
|
|
32745
32796
|
}
|
|
32746
|
-
if (
|
|
32797
|
+
if (!SUBMIT_ACCEPTS.includes(claim.state)) {
|
|
32747
32798
|
console.error(
|
|
32748
32799
|
`terminalhire claim: ${id} is '${claim.state}'. Submit runs once work has started ('working', via 'claim start') or the review gate cleared it ('ready'). Start it first:
|
|
32749
32800
|
terminalhire claim start ${id}`
|
|
@@ -33692,7 +33743,7 @@ async function run7() {
|
|
|
33692
33743
|
process.exit(1);
|
|
33693
33744
|
}
|
|
33694
33745
|
}
|
|
33695
|
-
var TERMINALHIRE_DIR17, INDEX_CACHE_FILE5, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL6, CLAIM_SYNC_BASE2, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, GH_API3, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS;
|
|
33746
|
+
var TERMINALHIRE_DIR17, INDEX_CACHE_FILE5, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL6, CLAIM_SYNC_BASE2, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, GH_API3, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, SUBMIT_ACCEPTS, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS;
|
|
33696
33747
|
var init_jpi_claim = __esm({
|
|
33697
33748
|
"bin/jpi-claim.js"() {
|
|
33698
33749
|
"use strict";
|
|
@@ -33724,6 +33775,7 @@ var init_jpi_claim = __esm({
|
|
|
33724
33775
|
STAKE_POST_TIMEOUT_MS = 3e4;
|
|
33725
33776
|
STAKE_POSTING_GRACE_MS = STAKE_POST_TIMEOUT_MS + 15e3;
|
|
33726
33777
|
TAKE_BOT_REPOS = /* @__PURE__ */ new Set(["paradedb/paradedb"]);
|
|
33778
|
+
SUBMIT_ACCEPTS = Object.freeze(["working", "ready"]);
|
|
33727
33779
|
ISSUE_OUTCOME_TERMINAL = /* @__PURE__ */ new Set(["own-merge", "other-merge", "closed-unmerged"]);
|
|
33728
33780
|
RUNS_POLL_INTERVAL_MS = 15e3;
|
|
33729
33781
|
RUNS_POLL_ATTEMPTS = 20;
|
|
@@ -63850,18 +63902,41 @@ import { hostname, homedir as osHomedir } from "os";
|
|
|
63850
63902
|
async function run26() {
|
|
63851
63903
|
try {
|
|
63852
63904
|
let index;
|
|
63905
|
+
let indexETag;
|
|
63906
|
+
const cachedForRevalidation = readCacheEntry() ?? {};
|
|
63907
|
+
let sendValidator = typeof cachedForRevalidation.indexETag === "string" && cachedForRevalidation.indexETag !== "";
|
|
63853
63908
|
for (let attempt2 = 1; ; attempt2++) {
|
|
63854
63909
|
try {
|
|
63855
63910
|
const res = await fetch(`${API_URL8}/api/index`, {
|
|
63856
63911
|
signal: AbortSignal.timeout(15e3),
|
|
63857
|
-
headers: { Accept: "application/json" }
|
|
63912
|
+
headers: sendValidator ? { Accept: "application/json", "If-None-Match": cachedForRevalidation.indexETag } : { Accept: "application/json" }
|
|
63858
63913
|
});
|
|
63914
|
+
if (res.status === 304) {
|
|
63915
|
+
const cached2 = cachedForRevalidation.index;
|
|
63916
|
+
if (cached2 && Array.isArray(cached2.jobs)) {
|
|
63917
|
+
index = cached2;
|
|
63918
|
+
indexETag = cachedForRevalidation.indexETag;
|
|
63919
|
+
break;
|
|
63920
|
+
}
|
|
63921
|
+
sendValidator = false;
|
|
63922
|
+
if (attempt2 >= 2) {
|
|
63923
|
+
process.stderr.write(
|
|
63924
|
+
"terminalhire refresh: 304 with no usable cached index \u2014 giving up this tick\n"
|
|
63925
|
+
);
|
|
63926
|
+
process.exit(1);
|
|
63927
|
+
}
|
|
63928
|
+
process.stderr.write(
|
|
63929
|
+
"terminalhire refresh: 304 but the cached index is unusable (re-fetching in full)\n"
|
|
63930
|
+
);
|
|
63931
|
+
continue;
|
|
63932
|
+
}
|
|
63859
63933
|
if (!res.ok) {
|
|
63860
63934
|
process.stderr.write(`terminalhire refresh: index fetch failed (HTTP ${res.status})
|
|
63861
63935
|
`);
|
|
63862
63936
|
process.exit(1);
|
|
63863
63937
|
}
|
|
63864
63938
|
index = await res.json();
|
|
63939
|
+
indexETag = res.headers.get("etag") ?? "";
|
|
63865
63940
|
break;
|
|
63866
63941
|
} catch (err) {
|
|
63867
63942
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -64139,6 +64214,7 @@ async function run26() {
|
|
|
64139
64214
|
};
|
|
64140
64215
|
if (founderPaid) cacheEntry.founderPaid = founderPaid;
|
|
64141
64216
|
if (approvedClaims) cacheEntry.approvedClaims = approvedClaims;
|
|
64217
|
+
cacheEntry.indexETag = indexETag ?? "";
|
|
64142
64218
|
updateIndexCache(cacheEntry);
|
|
64143
64219
|
try {
|
|
64144
64220
|
const { readSpinnerConfig: readSpinnerConfig2, renderRefreshSurface: renderRefreshSurface2 } = await Promise.resolve().then(() => (init_spinner(), spinner_exports));
|
package/dist/bin/jpi-hub.js
CHANGED
|
@@ -462,6 +462,7 @@ var init_state_dir = __esm({
|
|
|
462
462
|
// src/claims.ts
|
|
463
463
|
var claims_exports = {};
|
|
464
464
|
__export(claims_exports, {
|
|
465
|
+
CLAIM_STATES: () => CLAIM_STATES,
|
|
465
466
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
466
467
|
acceptedPRRate: () => acceptedPRRate,
|
|
467
468
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
@@ -660,7 +661,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
660
661
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
661
662
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
662
663
|
}
|
|
663
|
-
var TERMINALHIRE_DIR, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
664
|
+
var TERMINALHIRE_DIR, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
664
665
|
var init_claims = __esm({
|
|
665
666
|
"src/claims.ts"() {
|
|
666
667
|
"use strict";
|
|
@@ -671,6 +672,22 @@ var init_claims = __esm({
|
|
|
671
672
|
LOCK_STALE_MS = Number(process.env.TERMINALHIRE_LOCK_STALE_MS) || 1e4;
|
|
672
673
|
LOCK_RETRY_MS = Number(process.env.TERMINALHIRE_LOCK_RETRY_MS) || 25;
|
|
673
674
|
LOCK_TIMEOUT_MS = Number(process.env.TERMINALHIRE_LOCK_TIMEOUT_MS) || 5e3;
|
|
675
|
+
CLAIM_STATES = Object.freeze([
|
|
676
|
+
"claimed",
|
|
677
|
+
// recorded, not started
|
|
678
|
+
"working",
|
|
679
|
+
// background executor running / work in progress
|
|
680
|
+
"in-review",
|
|
681
|
+
// gate ran / dev reviewing the diff
|
|
682
|
+
"ready",
|
|
683
|
+
// passed review, cleared to submit
|
|
684
|
+
"submitted",
|
|
685
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
686
|
+
"merged",
|
|
687
|
+
// PR merged — accepted; counts toward the metric
|
|
688
|
+
"abandoned"
|
|
689
|
+
// released, or PR closed unmerged
|
|
690
|
+
]);
|
|
674
691
|
PUSHED_CLAIM_FIELDS = [
|
|
675
692
|
"kind",
|
|
676
693
|
"repoFullName",
|
|
@@ -12541,7 +12558,7 @@ function readIndexCache() {
|
|
|
12541
12558
|
}
|
|
12542
12559
|
}
|
|
12543
12560
|
function writeIndexCache(index) {
|
|
12544
|
-
updateIndexCache({ index });
|
|
12561
|
+
updateIndexCache({ index, indexETag: "" });
|
|
12545
12562
|
}
|
|
12546
12563
|
async function fetchIndex() {
|
|
12547
12564
|
const cached = readIndexCache();
|
|
@@ -12626,7 +12643,7 @@ function readIndexCache2() {
|
|
|
12626
12643
|
}
|
|
12627
12644
|
}
|
|
12628
12645
|
function writeIndexCache2(index) {
|
|
12629
|
-
updateIndexCache({ index });
|
|
12646
|
+
updateIndexCache({ index, indexETag: "" });
|
|
12630
12647
|
}
|
|
12631
12648
|
async function fetchIndex2() {
|
|
12632
12649
|
const cached = readIndexCache2();
|
package/dist/bin/jpi-jobs.js
CHANGED
|
@@ -12141,7 +12141,7 @@ function readIndexCache() {
|
|
|
12141
12141
|
}
|
|
12142
12142
|
}
|
|
12143
12143
|
function writeIndexCache(index) {
|
|
12144
|
-
updateIndexCache({ index });
|
|
12144
|
+
updateIndexCache({ index, indexETag: "" });
|
|
12145
12145
|
}
|
|
12146
12146
|
async function fetchIndex() {
|
|
12147
12147
|
const cached = readIndexCache();
|
package/dist/bin/jpi-mcp.js
CHANGED
|
@@ -10903,6 +10903,7 @@ var init_policy_acks = __esm({
|
|
|
10903
10903
|
// src/claims.ts
|
|
10904
10904
|
var claims_exports = {};
|
|
10905
10905
|
__export(claims_exports, {
|
|
10906
|
+
CLAIM_STATES: () => CLAIM_STATES,
|
|
10906
10907
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
10907
10908
|
acceptedPRRate: () => acceptedPRRate,
|
|
10908
10909
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
@@ -11101,7 +11102,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
11101
11102
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
11102
11103
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
11103
11104
|
}
|
|
11104
|
-
var TERMINALHIRE_DIR5, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
11105
|
+
var TERMINALHIRE_DIR5, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
11105
11106
|
var init_claims = __esm({
|
|
11106
11107
|
"src/claims.ts"() {
|
|
11107
11108
|
"use strict";
|
|
@@ -11112,6 +11113,22 @@ var init_claims = __esm({
|
|
|
11112
11113
|
LOCK_STALE_MS = Number(process.env.TERMINALHIRE_LOCK_STALE_MS) || 1e4;
|
|
11113
11114
|
LOCK_RETRY_MS = Number(process.env.TERMINALHIRE_LOCK_RETRY_MS) || 25;
|
|
11114
11115
|
LOCK_TIMEOUT_MS = Number(process.env.TERMINALHIRE_LOCK_TIMEOUT_MS) || 5e3;
|
|
11116
|
+
CLAIM_STATES = Object.freeze([
|
|
11117
|
+
"claimed",
|
|
11118
|
+
// recorded, not started
|
|
11119
|
+
"working",
|
|
11120
|
+
// background executor running / work in progress
|
|
11121
|
+
"in-review",
|
|
11122
|
+
// gate ran / dev reviewing the diff
|
|
11123
|
+
"ready",
|
|
11124
|
+
// passed review, cleared to submit
|
|
11125
|
+
"submitted",
|
|
11126
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
11127
|
+
"merged",
|
|
11128
|
+
// PR merged — accepted; counts toward the metric
|
|
11129
|
+
"abandoned"
|
|
11130
|
+
// released, or PR closed unmerged
|
|
11131
|
+
]);
|
|
11115
11132
|
PUSHED_CLAIM_FIELDS = [
|
|
11116
11133
|
"kind",
|
|
11117
11134
|
"repoFullName",
|
|
@@ -26046,6 +26063,7 @@ var jpi_claim_exports = {};
|
|
|
26046
26063
|
__export(jpi_claim_exports, {
|
|
26047
26064
|
AI_DISCLOSURE_NOTE: () => AI_DISCLOSURE_NOTE,
|
|
26048
26065
|
CLAIM_CONSENT_VERSION: () => CLAIM_CONSENT_VERSION,
|
|
26066
|
+
SUBMIT_ACCEPTS: () => SUBMIT_ACCEPTS,
|
|
26049
26067
|
backgroundEnableFailed: () => backgroundEnableFailed,
|
|
26050
26068
|
buildAssignmentComment: () => buildAssignmentComment,
|
|
26051
26069
|
buildPatchSubmission: () => buildPatchSubmission,
|
|
@@ -26071,9 +26089,11 @@ __export(jpi_claim_exports, {
|
|
|
26071
26089
|
listMergedPRsReferencingIssue: () => listMergedPRsReferencingIssue,
|
|
26072
26090
|
listOpenPRsReferencingIssue: () => listOpenPRsReferencingIssue,
|
|
26073
26091
|
matchReferencingPrs: () => matchReferencingPrs,
|
|
26092
|
+
nextStepFor: () => nextStepFor,
|
|
26074
26093
|
normalizeIntent: () => normalizeIntent,
|
|
26075
26094
|
pickBodySource: () => pickBodySource,
|
|
26076
26095
|
pickExistingPr: () => pickExistingPr,
|
|
26096
|
+
printNextSteps: () => printNextSteps,
|
|
26077
26097
|
renderRunView: () => renderRunView,
|
|
26078
26098
|
renderServerRefusal: () => renderServerRefusal,
|
|
26079
26099
|
resolveBounty: () => resolveBounty,
|
|
@@ -26750,6 +26770,37 @@ function printMetric(rate) {
|
|
|
26750
26770
|
console.log(`
|
|
26751
26771
|
\u{1F4CA} Accepted-PR rate: ${rate.merged}/${rate.total} claims merged (${pct}%)`);
|
|
26752
26772
|
}
|
|
26773
|
+
function nextStepFor(c) {
|
|
26774
|
+
const founder = Boolean(c.approval);
|
|
26775
|
+
switch (c.state) {
|
|
26776
|
+
case "claimed":
|
|
26777
|
+
return founder ? { cmd: `terminalhire claim slice ${c.id}`, why: "collect your granted work slice" } : { cmd: `terminalhire claim start ${c.id}`, why: "fork + clone into a worktree" };
|
|
26778
|
+
// NOT grouped with the two below. `cmdSubmit` accepts 'working' and 'ready'
|
|
26779
|
+
// and nothing else, so pointing an 'in-review' claim at submit would hand the
|
|
26780
|
+
// developer a command that exits 1 — and submit's own refusal then advises
|
|
26781
|
+
// `claim start`, which a founder claim can never use either. Two dead ends in
|
|
26782
|
+
// a row is worse than the silence this block replaced.
|
|
26783
|
+
case "in-review":
|
|
26784
|
+
return {
|
|
26785
|
+
cmd: `terminalhire claim update ${c.id} ready`,
|
|
26786
|
+
why: "clear the review gate \u2014 submit only accepts working/ready"
|
|
26787
|
+
};
|
|
26788
|
+
case "working":
|
|
26789
|
+
case "ready":
|
|
26790
|
+
return { cmd: `terminalhire claim submit ${c.id}`, why: "push the branch + open the PR" };
|
|
26791
|
+
case "submitted":
|
|
26792
|
+
return founder ? { cmd: `terminalhire claim runs ${c.id} --watch`, why: "read the CI result" } : { cmd: `terminalhire claim status ${c.id}`, why: "poll the PR merge state" };
|
|
26793
|
+
default:
|
|
26794
|
+
return null;
|
|
26795
|
+
}
|
|
26796
|
+
}
|
|
26797
|
+
function printNextSteps(list) {
|
|
26798
|
+
const steps = list.map(nextStepFor).filter(Boolean);
|
|
26799
|
+
if (steps.length === 0) return;
|
|
26800
|
+
const width = Math.max(...steps.map((s) => s.cmd.length));
|
|
26801
|
+
console.log("\n Next:");
|
|
26802
|
+
for (const s of steps) console.log(` ${s.cmd.padEnd(width)} \u2014 ${s.why}`);
|
|
26803
|
+
}
|
|
26753
26804
|
async function resolveBounty(arg) {
|
|
26754
26805
|
let bountyId, title, repoFullName, issueUrl, amountUSD, source, openPRsAtDiscovery, indexNativeId;
|
|
26755
26806
|
let founderPosting = false;
|
|
@@ -27321,6 +27372,7 @@ ${list.length} ${active ? "active " : ""}claim${list.length === 1 ? "" : "s"}:
|
|
|
27321
27372
|
console.log(` id: ${c.id}${pr}`);
|
|
27322
27373
|
}
|
|
27323
27374
|
printMetric(claims.acceptedPRRate());
|
|
27375
|
+
printNextSteps(list);
|
|
27324
27376
|
try {
|
|
27325
27377
|
if (await shouldNudgeUnpushed()) {
|
|
27326
27378
|
console.log(
|
|
@@ -27468,7 +27520,7 @@ async function cmdStatus(id) {
|
|
|
27468
27520
|
}
|
|
27469
27521
|
async function cmdUpdate(id, state, prUrl) {
|
|
27470
27522
|
const claims = await Promise.resolve().then(() => (init_claims(), claims_exports));
|
|
27471
|
-
const VALID =
|
|
27523
|
+
const VALID = claims.CLAIM_STATES;
|
|
27472
27524
|
if (!id || !state || !VALID.includes(state)) {
|
|
27473
27525
|
console.error("Usage: terminalhire claim update <id> <state> [prUrl]");
|
|
27474
27526
|
console.error(" state: " + VALID.join(" | "));
|
|
@@ -28326,7 +28378,7 @@ async function cmdSubmit(id, flags = {}) {
|
|
|
28326
28378
|
console.error(`terminalhire claim: no claim with id '${id}'.`);
|
|
28327
28379
|
process.exit(1);
|
|
28328
28380
|
}
|
|
28329
|
-
if (
|
|
28381
|
+
if (!SUBMIT_ACCEPTS.includes(claim.state)) {
|
|
28330
28382
|
console.error(
|
|
28331
28383
|
`terminalhire claim: ${id} is '${claim.state}'. Submit runs once work has started ('working', via 'claim start') or the review gate cleared it ('ready'). Start it first:
|
|
28332
28384
|
terminalhire claim start ${id}`
|
|
@@ -29275,7 +29327,7 @@ async function run() {
|
|
|
29275
29327
|
process.exit(1);
|
|
29276
29328
|
}
|
|
29277
29329
|
}
|
|
29278
|
-
var TERMINALHIRE_DIR11, INDEX_CACHE_FILE2, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL, CLAIM_SYNC_BASE, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, GH_API2, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS;
|
|
29330
|
+
var TERMINALHIRE_DIR11, INDEX_CACHE_FILE2, CLAIM_PUSH_MARKER, REPO_CONTINUITY_NUDGE_MARKER, API_URL, CLAIM_SYNC_BASE, CLAIM_CONSENT_VERSION, CLAIM_POLL_INTERVAL_MS, CLAIM_POLL_TIMEOUT_MS, GH_API2, GH_HEADERS2, CONTENTION_HINT, AI_DISCLOSURE_NOTE, pExecFile, VALUE_FLAGS, ASSIGNMENT_MARKER, STAKE_MARKER, STANDDOWN_MARKER, OUR_MARKERS, STAKE_POST_TIMEOUT_MS, STAKE_POSTING_GRACE_MS, TAKE_BOT_REPOS, SUBMIT_ACCEPTS, ISSUE_OUTCOME_TERMINAL, RUNS_POLL_INTERVAL_MS, RUNS_POLL_ATTEMPTS;
|
|
29279
29331
|
var init_jpi_claim = __esm({
|
|
29280
29332
|
"bin/jpi-claim.js"() {
|
|
29281
29333
|
"use strict";
|
|
@@ -29307,6 +29359,7 @@ var init_jpi_claim = __esm({
|
|
|
29307
29359
|
STAKE_POST_TIMEOUT_MS = 3e4;
|
|
29308
29360
|
STAKE_POSTING_GRACE_MS = STAKE_POST_TIMEOUT_MS + 15e3;
|
|
29309
29361
|
TAKE_BOT_REPOS = /* @__PURE__ */ new Set(["paradedb/paradedb"]);
|
|
29362
|
+
SUBMIT_ACCEPTS = Object.freeze(["working", "ready"]);
|
|
29310
29363
|
ISSUE_OUTCOME_TERMINAL = /* @__PURE__ */ new Set(["own-merge", "other-merge", "closed-unmerged"]);
|
|
29311
29364
|
RUNS_POLL_INTERVAL_MS = 15e3;
|
|
29312
29365
|
RUNS_POLL_ATTEMPTS = 20;
|
package/dist/bin/jpi-refresh.js
CHANGED
|
@@ -12283,6 +12283,7 @@ var init_github_auth = __esm({
|
|
|
12283
12283
|
// src/claims.ts
|
|
12284
12284
|
var claims_exports = {};
|
|
12285
12285
|
__export(claims_exports, {
|
|
12286
|
+
CLAIM_STATES: () => CLAIM_STATES,
|
|
12286
12287
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
12287
12288
|
acceptedPRRate: () => acceptedPRRate,
|
|
12288
12289
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
@@ -12481,7 +12482,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
12481
12482
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
12482
12483
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
12483
12484
|
}
|
|
12484
|
-
var TERMINALHIRE_DIR8, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS2, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
12485
|
+
var TERMINALHIRE_DIR8, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS2, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
12485
12486
|
var init_claims = __esm({
|
|
12486
12487
|
"src/claims.ts"() {
|
|
12487
12488
|
"use strict";
|
|
@@ -12492,6 +12493,22 @@ var init_claims = __esm({
|
|
|
12492
12493
|
LOCK_STALE_MS2 = Number(process.env.TERMINALHIRE_LOCK_STALE_MS) || 1e4;
|
|
12493
12494
|
LOCK_RETRY_MS = Number(process.env.TERMINALHIRE_LOCK_RETRY_MS) || 25;
|
|
12494
12495
|
LOCK_TIMEOUT_MS = Number(process.env.TERMINALHIRE_LOCK_TIMEOUT_MS) || 5e3;
|
|
12496
|
+
CLAIM_STATES = Object.freeze([
|
|
12497
|
+
"claimed",
|
|
12498
|
+
// recorded, not started
|
|
12499
|
+
"working",
|
|
12500
|
+
// background executor running / work in progress
|
|
12501
|
+
"in-review",
|
|
12502
|
+
// gate ran / dev reviewing the diff
|
|
12503
|
+
"ready",
|
|
12504
|
+
// passed review, cleared to submit
|
|
12505
|
+
"submitted",
|
|
12506
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
12507
|
+
"merged",
|
|
12508
|
+
// PR merged — accepted; counts toward the metric
|
|
12509
|
+
"abandoned"
|
|
12510
|
+
// released, or PR closed unmerged
|
|
12511
|
+
]);
|
|
12495
12512
|
PUSHED_CLAIM_FIELDS = [
|
|
12496
12513
|
"kind",
|
|
12497
12514
|
"repoFullName",
|
|
@@ -12739,8 +12756,7 @@ function gate(openIds, seenIds) {
|
|
|
12739
12756
|
function computeFounderPaid(index, previous) {
|
|
12740
12757
|
const open = openPaidIds(index);
|
|
12741
12758
|
const prior = previous && previous.acknowledged;
|
|
12742
|
-
|
|
12743
|
-
return gate(open, prior);
|
|
12759
|
+
return gate(open, Array.isArray(prior) ? prior : []);
|
|
12744
12760
|
}
|
|
12745
12761
|
function acknowledgeFounderPaid({ shown = [], open = [], previous } = {}) {
|
|
12746
12762
|
const prior = previous && Array.isArray(previous.acknowledged) ? previous.acknowledged : [];
|
|
@@ -13310,18 +13326,41 @@ var MMR_K = 8;
|
|
|
13310
13326
|
async function run() {
|
|
13311
13327
|
try {
|
|
13312
13328
|
let index;
|
|
13329
|
+
let indexETag;
|
|
13330
|
+
const cachedForRevalidation = readCacheEntry() ?? {};
|
|
13331
|
+
let sendValidator = typeof cachedForRevalidation.indexETag === "string" && cachedForRevalidation.indexETag !== "";
|
|
13313
13332
|
for (let attempt = 1; ; attempt++) {
|
|
13314
13333
|
try {
|
|
13315
13334
|
const res = await fetch(`${API_URL2}/api/index`, {
|
|
13316
13335
|
signal: AbortSignal.timeout(15e3),
|
|
13317
|
-
headers: { Accept: "application/json" }
|
|
13336
|
+
headers: sendValidator ? { Accept: "application/json", "If-None-Match": cachedForRevalidation.indexETag } : { Accept: "application/json" }
|
|
13318
13337
|
});
|
|
13338
|
+
if (res.status === 304) {
|
|
13339
|
+
const cached = cachedForRevalidation.index;
|
|
13340
|
+
if (cached && Array.isArray(cached.jobs)) {
|
|
13341
|
+
index = cached;
|
|
13342
|
+
indexETag = cachedForRevalidation.indexETag;
|
|
13343
|
+
break;
|
|
13344
|
+
}
|
|
13345
|
+
sendValidator = false;
|
|
13346
|
+
if (attempt >= 2) {
|
|
13347
|
+
process.stderr.write(
|
|
13348
|
+
"terminalhire refresh: 304 with no usable cached index \u2014 giving up this tick\n"
|
|
13349
|
+
);
|
|
13350
|
+
process.exit(1);
|
|
13351
|
+
}
|
|
13352
|
+
process.stderr.write(
|
|
13353
|
+
"terminalhire refresh: 304 but the cached index is unusable (re-fetching in full)\n"
|
|
13354
|
+
);
|
|
13355
|
+
continue;
|
|
13356
|
+
}
|
|
13319
13357
|
if (!res.ok) {
|
|
13320
13358
|
process.stderr.write(`terminalhire refresh: index fetch failed (HTTP ${res.status})
|
|
13321
13359
|
`);
|
|
13322
13360
|
process.exit(1);
|
|
13323
13361
|
}
|
|
13324
13362
|
index = await res.json();
|
|
13363
|
+
indexETag = res.headers.get("etag") ?? "";
|
|
13325
13364
|
break;
|
|
13326
13365
|
} catch (err) {
|
|
13327
13366
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -13599,6 +13638,7 @@ async function run() {
|
|
|
13599
13638
|
};
|
|
13600
13639
|
if (founderPaid) cacheEntry.founderPaid = founderPaid;
|
|
13601
13640
|
if (approvedClaims) cacheEntry.approvedClaims = approvedClaims;
|
|
13641
|
+
cacheEntry.indexETag = indexETag ?? "";
|
|
13602
13642
|
updateIndexCache(cacheEntry);
|
|
13603
13643
|
try {
|
|
13604
13644
|
const { readSpinnerConfig: readSpinnerConfig2, renderRefreshSurface: renderRefreshSurface2 } = await Promise.resolve().then(() => (init_spinner(), spinner_exports));
|
package/dist/bin/jpi-repo.js
CHANGED
|
@@ -1824,6 +1824,7 @@ var init_repo_experience = __esm({
|
|
|
1824
1824
|
// src/claims.ts
|
|
1825
1825
|
var claims_exports = {};
|
|
1826
1826
|
__export(claims_exports, {
|
|
1827
|
+
CLAIM_STATES: () => CLAIM_STATES,
|
|
1827
1828
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
1828
1829
|
acceptedPRRate: () => acceptedPRRate,
|
|
1829
1830
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
@@ -2022,7 +2023,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
2022
2023
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
2023
2024
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
2024
2025
|
}
|
|
2025
|
-
var TERMINALHIRE_DIR4, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
2026
|
+
var TERMINALHIRE_DIR4, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS;
|
|
2026
2027
|
var init_claims = __esm({
|
|
2027
2028
|
"src/claims.ts"() {
|
|
2028
2029
|
"use strict";
|
|
@@ -2033,6 +2034,22 @@ var init_claims = __esm({
|
|
|
2033
2034
|
LOCK_STALE_MS = Number(process.env.TERMINALHIRE_LOCK_STALE_MS) || 1e4;
|
|
2034
2035
|
LOCK_RETRY_MS = Number(process.env.TERMINALHIRE_LOCK_RETRY_MS) || 25;
|
|
2035
2036
|
LOCK_TIMEOUT_MS = Number(process.env.TERMINALHIRE_LOCK_TIMEOUT_MS) || 5e3;
|
|
2037
|
+
CLAIM_STATES = Object.freeze([
|
|
2038
|
+
"claimed",
|
|
2039
|
+
// recorded, not started
|
|
2040
|
+
"working",
|
|
2041
|
+
// background executor running / work in progress
|
|
2042
|
+
"in-review",
|
|
2043
|
+
// gate ran / dev reviewing the diff
|
|
2044
|
+
"ready",
|
|
2045
|
+
// passed review, cleared to submit
|
|
2046
|
+
"submitted",
|
|
2047
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
2048
|
+
"merged",
|
|
2049
|
+
// PR merged — accepted; counts toward the metric
|
|
2050
|
+
"abandoned"
|
|
2051
|
+
// released, or PR closed unmerged
|
|
2052
|
+
]);
|
|
2036
2053
|
PUSHED_CLAIM_FIELDS = [
|
|
2037
2054
|
"kind",
|
|
2038
2055
|
"repoFullName",
|
package/dist/src/claims.js
CHANGED
|
@@ -99,6 +99,22 @@ function withClaimsLock(fn) {
|
|
|
99
99
|
rmSync(LOCK_DIR, { recursive: true, force: true });
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
+
var CLAIM_STATES = Object.freeze([
|
|
103
|
+
"claimed",
|
|
104
|
+
// recorded, not started
|
|
105
|
+
"working",
|
|
106
|
+
// background executor running / work in progress
|
|
107
|
+
"in-review",
|
|
108
|
+
// gate ran / dev reviewing the diff
|
|
109
|
+
"ready",
|
|
110
|
+
// passed review, cleared to submit
|
|
111
|
+
"submitted",
|
|
112
|
+
// PR opened on the source platform (awaiting maintainer)
|
|
113
|
+
"merged",
|
|
114
|
+
// PR merged — accepted; counts toward the metric
|
|
115
|
+
"abandoned"
|
|
116
|
+
// released, or PR closed unmerged
|
|
117
|
+
]);
|
|
102
118
|
var PUSHED_CLAIM_FIELDS = [
|
|
103
119
|
"kind",
|
|
104
120
|
"repoFullName",
|
|
@@ -269,6 +285,7 @@ function acceptedPRRate(claims = readClaims()) {
|
|
|
269
285
|
return { merged, total, rate: total === 0 ? 0 : merged / total };
|
|
270
286
|
}
|
|
271
287
|
export {
|
|
288
|
+
CLAIM_STATES,
|
|
272
289
|
PUSHED_CLAIM_FIELDS,
|
|
273
290
|
acceptedPRRate,
|
|
274
291
|
countAwaitingFounderApproval,
|
package/package.json
CHANGED