terminalhire 0.42.17 → 0.42.18
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 +40 -2
- package/dist/bin/jpi-bounties.js +40 -2
- package/dist/bin/jpi-claim.js +287 -32
- package/dist/bin/jpi-contribute.js +40 -2
- package/dist/bin/jpi-dispatch.js +291 -37
- package/dist/bin/jpi-hub.js +43 -6
- package/dist/bin/jpi-mcp.js +288 -33
- package/dist/bin/jpi-refresh.js +40 -2
- package/dist/bin/jpi-repo.js +40 -2
- package/dist/src/claims.js +39 -1
- package/package.json +1 -1
|
@@ -91,10 +91,14 @@ var init_state_dir = __esm({
|
|
|
91
91
|
var claims_exports = {};
|
|
92
92
|
__export(claims_exports, {
|
|
93
93
|
CLAIM_STATES: () => CLAIM_STATES,
|
|
94
|
+
CLAIM_TURN_LABEL_WIDTH: () => CLAIM_TURN_LABEL_WIDTH,
|
|
94
95
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
95
96
|
acceptedPRRate: () => acceptedPRRate,
|
|
97
|
+
claimTurn: () => claimTurn,
|
|
98
|
+
claimTurnLabel: () => claimTurnLabel,
|
|
96
99
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
97
100
|
findClaim: () => findClaim,
|
|
101
|
+
formatAcceptedPRRate: () => formatAcceptedPRRate,
|
|
98
102
|
listClaims: () => listClaims,
|
|
99
103
|
nextPolledState: () => nextPolledState,
|
|
100
104
|
readClaims: () => readClaims,
|
|
@@ -149,6 +153,12 @@ function withClaimsLock(fn) {
|
|
|
149
153
|
rmSync2(LOCK_DIR, { recursive: true, force: true });
|
|
150
154
|
}
|
|
151
155
|
}
|
|
156
|
+
function claimTurn(state) {
|
|
157
|
+
return CLAIM_TURN_BY_STATE[state] ?? "you";
|
|
158
|
+
}
|
|
159
|
+
function claimTurnLabel(state) {
|
|
160
|
+
return CLAIM_TURN_LABEL[claimTurn(state)];
|
|
161
|
+
}
|
|
152
162
|
function toPushedClaim(claim) {
|
|
153
163
|
return {
|
|
154
164
|
kind: claim.kind,
|
|
@@ -303,9 +313,18 @@ function countAwaitingFounderApproval(claims = readClaims()) {
|
|
|
303
313
|
function acceptedPRRate(claims = readClaims()) {
|
|
304
314
|
const total = claims.length;
|
|
305
315
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
306
|
-
|
|
316
|
+
const decided = claims.filter((c) => DECIDED_STATES.has(c.state)).length;
|
|
317
|
+
return { merged, decided, inFlight: total - decided, total, rate: decided === 0 ? 0 : merged / decided };
|
|
318
|
+
}
|
|
319
|
+
function formatAcceptedPRRate(rate) {
|
|
320
|
+
const inFlight = rate.inFlight > 0 ? ` \xB7 ${rate.inFlight} in flight` : "";
|
|
321
|
+
if (rate.decided === 0) {
|
|
322
|
+
return `Accepted-PR rate: no claims decided yet${inFlight}`;
|
|
323
|
+
}
|
|
324
|
+
const pct = Math.round(rate.rate * 100);
|
|
325
|
+
return `Accepted-PR rate: ${rate.merged}/${rate.decided} decided claims merged (${pct}%)${inFlight}`;
|
|
307
326
|
}
|
|
308
|
-
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, WHITESPACE_CONTROLS, CONTROL_CHARS;
|
|
327
|
+
var TERMINALHIRE_DIR3, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, CLAIM_TURN_BY_STATE, CLAIM_TURN_LABEL, CLAIM_TURN_LABEL_WIDTH, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS, WHITESPACE_CONTROLS, CONTROL_CHARS, DECIDED_STATES;
|
|
309
328
|
var init_claims = __esm({
|
|
310
329
|
"src/claims.ts"() {
|
|
311
330
|
"use strict";
|
|
@@ -332,6 +351,24 @@ var init_claims = __esm({
|
|
|
332
351
|
"abandoned"
|
|
333
352
|
// released, or PR closed unmerged
|
|
334
353
|
]);
|
|
354
|
+
CLAIM_TURN_BY_STATE = Object.freeze({
|
|
355
|
+
claimed: "you",
|
|
356
|
+
working: "you",
|
|
357
|
+
"in-review": "you",
|
|
358
|
+
ready: "you",
|
|
359
|
+
submitted: "poster",
|
|
360
|
+
merged: "merged",
|
|
361
|
+
abandoned: "closed"
|
|
362
|
+
});
|
|
363
|
+
CLAIM_TURN_LABEL = Object.freeze({
|
|
364
|
+
you: "waiting on you",
|
|
365
|
+
poster: "waiting on poster",
|
|
366
|
+
merged: "merged",
|
|
367
|
+
closed: "closed"
|
|
368
|
+
});
|
|
369
|
+
CLAIM_TURN_LABEL_WIDTH = Math.max(
|
|
370
|
+
...Object.values(CLAIM_TURN_LABEL).map((label) => label.length)
|
|
371
|
+
);
|
|
335
372
|
PUSHED_CLAIM_FIELDS = [
|
|
336
373
|
"kind",
|
|
337
374
|
"repoFullName",
|
|
@@ -363,6 +400,7 @@ var init_claims = __esm({
|
|
|
363
400
|
};
|
|
364
401
|
WHITESPACE_CONTROLS = /[\t\n\v\f\r]+/g;
|
|
365
402
|
CONTROL_CHARS = /[\x00-\x1f\x7f-\x9f]/g;
|
|
403
|
+
DECIDED_STATES = /* @__PURE__ */ new Set(["merged", "abandoned"]);
|
|
366
404
|
}
|
|
367
405
|
});
|
|
368
406
|
|
package/dist/bin/jpi-bounties.js
CHANGED
|
@@ -11254,10 +11254,14 @@ var init_repo_experience = __esm({
|
|
|
11254
11254
|
var claims_exports = {};
|
|
11255
11255
|
__export(claims_exports, {
|
|
11256
11256
|
CLAIM_STATES: () => CLAIM_STATES,
|
|
11257
|
+
CLAIM_TURN_LABEL_WIDTH: () => CLAIM_TURN_LABEL_WIDTH,
|
|
11257
11258
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
11258
11259
|
acceptedPRRate: () => acceptedPRRate,
|
|
11260
|
+
claimTurn: () => claimTurn,
|
|
11261
|
+
claimTurnLabel: () => claimTurnLabel,
|
|
11259
11262
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
11260
11263
|
findClaim: () => findClaim,
|
|
11264
|
+
formatAcceptedPRRate: () => formatAcceptedPRRate,
|
|
11261
11265
|
listClaims: () => listClaims,
|
|
11262
11266
|
nextPolledState: () => nextPolledState,
|
|
11263
11267
|
readClaims: () => readClaims,
|
|
@@ -11312,6 +11316,12 @@ function withClaimsLock(fn) {
|
|
|
11312
11316
|
rmSync2(LOCK_DIR, { recursive: true, force: true });
|
|
11313
11317
|
}
|
|
11314
11318
|
}
|
|
11319
|
+
function claimTurn(state) {
|
|
11320
|
+
return CLAIM_TURN_BY_STATE[state] ?? "you";
|
|
11321
|
+
}
|
|
11322
|
+
function claimTurnLabel(state) {
|
|
11323
|
+
return CLAIM_TURN_LABEL[claimTurn(state)];
|
|
11324
|
+
}
|
|
11315
11325
|
function toPushedClaim(claim) {
|
|
11316
11326
|
return {
|
|
11317
11327
|
kind: claim.kind,
|
|
@@ -11466,9 +11476,18 @@ function countAwaitingFounderApproval(claims = readClaims()) {
|
|
|
11466
11476
|
function acceptedPRRate(claims = readClaims()) {
|
|
11467
11477
|
const total = claims.length;
|
|
11468
11478
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
11469
|
-
|
|
11479
|
+
const decided = claims.filter((c) => DECIDED_STATES.has(c.state)).length;
|
|
11480
|
+
return { merged, decided, inFlight: total - decided, total, rate: decided === 0 ? 0 : merged / decided };
|
|
11481
|
+
}
|
|
11482
|
+
function formatAcceptedPRRate(rate) {
|
|
11483
|
+
const inFlight = rate.inFlight > 0 ? ` \xB7 ${rate.inFlight} in flight` : "";
|
|
11484
|
+
if (rate.decided === 0) {
|
|
11485
|
+
return `Accepted-PR rate: no claims decided yet${inFlight}`;
|
|
11486
|
+
}
|
|
11487
|
+
const pct = Math.round(rate.rate * 100);
|
|
11488
|
+
return `Accepted-PR rate: ${rate.merged}/${rate.decided} decided claims merged (${pct}%)${inFlight}`;
|
|
11470
11489
|
}
|
|
11471
|
-
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, WHITESPACE_CONTROLS2, CONTROL_CHARS2;
|
|
11490
|
+
var TERMINALHIRE_DIR5, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, CLAIM_TURN_BY_STATE, CLAIM_TURN_LABEL, CLAIM_TURN_LABEL_WIDTH, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS, WHITESPACE_CONTROLS2, CONTROL_CHARS2, DECIDED_STATES;
|
|
11472
11491
|
var init_claims = __esm({
|
|
11473
11492
|
"src/claims.ts"() {
|
|
11474
11493
|
"use strict";
|
|
@@ -11495,6 +11514,24 @@ var init_claims = __esm({
|
|
|
11495
11514
|
"abandoned"
|
|
11496
11515
|
// released, or PR closed unmerged
|
|
11497
11516
|
]);
|
|
11517
|
+
CLAIM_TURN_BY_STATE = Object.freeze({
|
|
11518
|
+
claimed: "you",
|
|
11519
|
+
working: "you",
|
|
11520
|
+
"in-review": "you",
|
|
11521
|
+
ready: "you",
|
|
11522
|
+
submitted: "poster",
|
|
11523
|
+
merged: "merged",
|
|
11524
|
+
abandoned: "closed"
|
|
11525
|
+
});
|
|
11526
|
+
CLAIM_TURN_LABEL = Object.freeze({
|
|
11527
|
+
you: "waiting on you",
|
|
11528
|
+
poster: "waiting on poster",
|
|
11529
|
+
merged: "merged",
|
|
11530
|
+
closed: "closed"
|
|
11531
|
+
});
|
|
11532
|
+
CLAIM_TURN_LABEL_WIDTH = Math.max(
|
|
11533
|
+
...Object.values(CLAIM_TURN_LABEL).map((label) => label.length)
|
|
11534
|
+
);
|
|
11498
11535
|
PUSHED_CLAIM_FIELDS = [
|
|
11499
11536
|
"kind",
|
|
11500
11537
|
"repoFullName",
|
|
@@ -11526,6 +11563,7 @@ var init_claims = __esm({
|
|
|
11526
11563
|
};
|
|
11527
11564
|
WHITESPACE_CONTROLS2 = /[\t\n\v\f\r]+/g;
|
|
11528
11565
|
CONTROL_CHARS2 = /[\x00-\x1f\x7f-\x9f]/g;
|
|
11566
|
+
DECIDED_STATES = /* @__PURE__ */ new Set(["merged", "abandoned"]);
|
|
11529
11567
|
}
|
|
11530
11568
|
});
|
|
11531
11569
|
|
package/dist/bin/jpi-claim.js
CHANGED
|
@@ -10563,10 +10563,14 @@ var init_state_dir = __esm({
|
|
|
10563
10563
|
var claims_exports = {};
|
|
10564
10564
|
__export(claims_exports, {
|
|
10565
10565
|
CLAIM_STATES: () => CLAIM_STATES,
|
|
10566
|
+
CLAIM_TURN_LABEL_WIDTH: () => CLAIM_TURN_LABEL_WIDTH,
|
|
10566
10567
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
10567
10568
|
acceptedPRRate: () => acceptedPRRate,
|
|
10569
|
+
claimTurn: () => claimTurn,
|
|
10570
|
+
claimTurnLabel: () => claimTurnLabel,
|
|
10568
10571
|
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
10569
10572
|
findClaim: () => findClaim,
|
|
10573
|
+
formatAcceptedPRRate: () => formatAcceptedPRRate,
|
|
10570
10574
|
listClaims: () => listClaims,
|
|
10571
10575
|
nextPolledState: () => nextPolledState,
|
|
10572
10576
|
readClaims: () => readClaims,
|
|
@@ -10621,6 +10625,12 @@ function withClaimsLock(fn) {
|
|
|
10621
10625
|
rmSync(LOCK_DIR, { recursive: true, force: true });
|
|
10622
10626
|
}
|
|
10623
10627
|
}
|
|
10628
|
+
function claimTurn(state) {
|
|
10629
|
+
return CLAIM_TURN_BY_STATE[state] ?? "you";
|
|
10630
|
+
}
|
|
10631
|
+
function claimTurnLabel(state) {
|
|
10632
|
+
return CLAIM_TURN_LABEL[claimTurn(state)];
|
|
10633
|
+
}
|
|
10624
10634
|
function toPushedClaim(claim) {
|
|
10625
10635
|
return {
|
|
10626
10636
|
kind: claim.kind,
|
|
@@ -10775,9 +10785,18 @@ function countAwaitingFounderApproval(claims = readClaims()) {
|
|
|
10775
10785
|
function acceptedPRRate(claims = readClaims()) {
|
|
10776
10786
|
const total = claims.length;
|
|
10777
10787
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
10778
|
-
|
|
10788
|
+
const decided = claims.filter((c) => DECIDED_STATES.has(c.state)).length;
|
|
10789
|
+
return { merged, decided, inFlight: total - decided, total, rate: decided === 0 ? 0 : merged / decided };
|
|
10790
|
+
}
|
|
10791
|
+
function formatAcceptedPRRate(rate) {
|
|
10792
|
+
const inFlight = rate.inFlight > 0 ? ` \xB7 ${rate.inFlight} in flight` : "";
|
|
10793
|
+
if (rate.decided === 0) {
|
|
10794
|
+
return `Accepted-PR rate: no claims decided yet${inFlight}`;
|
|
10795
|
+
}
|
|
10796
|
+
const pct = Math.round(rate.rate * 100);
|
|
10797
|
+
return `Accepted-PR rate: ${rate.merged}/${rate.decided} decided claims merged (${pct}%)${inFlight}`;
|
|
10779
10798
|
}
|
|
10780
|
-
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, WHITESPACE_CONTROLS2, CONTROL_CHARS2;
|
|
10799
|
+
var TERMINALHIRE_DIR2, CLAIMS_FILE, LOCK_DIR, LOCK_STALE_MS, LOCK_RETRY_MS, LOCK_TIMEOUT_MS, CLAIM_STATES, CLAIM_TURN_BY_STATE, CLAIM_TURN_LABEL, CLAIM_TURN_LABEL_WIDTH, PUSHED_CLAIM_FIELDS, TERMINAL_STATES, POLL_TRANSITIONS, WHITESPACE_CONTROLS2, CONTROL_CHARS2, DECIDED_STATES;
|
|
10781
10800
|
var init_claims = __esm({
|
|
10782
10801
|
"src/claims.ts"() {
|
|
10783
10802
|
"use strict";
|
|
@@ -10804,6 +10823,24 @@ var init_claims = __esm({
|
|
|
10804
10823
|
"abandoned"
|
|
10805
10824
|
// released, or PR closed unmerged
|
|
10806
10825
|
]);
|
|
10826
|
+
CLAIM_TURN_BY_STATE = Object.freeze({
|
|
10827
|
+
claimed: "you",
|
|
10828
|
+
working: "you",
|
|
10829
|
+
"in-review": "you",
|
|
10830
|
+
ready: "you",
|
|
10831
|
+
submitted: "poster",
|
|
10832
|
+
merged: "merged",
|
|
10833
|
+
abandoned: "closed"
|
|
10834
|
+
});
|
|
10835
|
+
CLAIM_TURN_LABEL = Object.freeze({
|
|
10836
|
+
you: "waiting on you",
|
|
10837
|
+
poster: "waiting on poster",
|
|
10838
|
+
merged: "merged",
|
|
10839
|
+
closed: "closed"
|
|
10840
|
+
});
|
|
10841
|
+
CLAIM_TURN_LABEL_WIDTH = Math.max(
|
|
10842
|
+
...Object.values(CLAIM_TURN_LABEL).map((label) => label.length)
|
|
10843
|
+
);
|
|
10807
10844
|
PUSHED_CLAIM_FIELDS = [
|
|
10808
10845
|
"kind",
|
|
10809
10846
|
"repoFullName",
|
|
@@ -10835,6 +10872,7 @@ var init_claims = __esm({
|
|
|
10835
10872
|
};
|
|
10836
10873
|
WHITESPACE_CONTROLS2 = /[\t\n\v\f\r]+/g;
|
|
10837
10874
|
CONTROL_CHARS2 = /[\x00-\x1f\x7f-\x9f]/g;
|
|
10875
|
+
DECIDED_STATES = /* @__PURE__ */ new Set(["merged", "abandoned"]);
|
|
10838
10876
|
}
|
|
10839
10877
|
});
|
|
10840
10878
|
|
|
@@ -34740,7 +34778,9 @@ var VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
|
34740
34778
|
"intent",
|
|
34741
34779
|
"eta",
|
|
34742
34780
|
"dir",
|
|
34743
|
-
"open"
|
|
34781
|
+
"open",
|
|
34782
|
+
"reason",
|
|
34783
|
+
"note"
|
|
34744
34784
|
]);
|
|
34745
34785
|
function parseArgs(argv) {
|
|
34746
34786
|
const flags = {};
|
|
@@ -35307,9 +35347,8 @@ function fmtClaimAmount(c) {
|
|
|
35307
35347
|
return c.kind === "contribution" ? "contribution" : fmtAmount(c.amountUSD);
|
|
35308
35348
|
}
|
|
35309
35349
|
function printMetric(rate) {
|
|
35310
|
-
const pct = Math.round(rate.rate * 100);
|
|
35311
35350
|
console.log(`
|
|
35312
|
-
\u{1F4CA}
|
|
35351
|
+
\u{1F4CA} ${formatAcceptedPRRate(rate)}`);
|
|
35313
35352
|
}
|
|
35314
35353
|
var SUBMIT_ACCEPTS = Object.freeze(["working", "ready"]);
|
|
35315
35354
|
var REVISE_RECOVERY_STATES = Object.freeze(["working", "in-review", "ready"]);
|
|
@@ -36417,11 +36456,12 @@ ${list.length} ${active ? "active " : ""}claim${list.length === 1 ? "" : "s"}:
|
|
|
36417
36456
|
`);
|
|
36418
36457
|
for (const c of list) {
|
|
36419
36458
|
const pr = c.prUrl ? ` \xB7 ${c.prUrl}` : "";
|
|
36420
|
-
console.log(` [${c.state}] ${fmtClaimAmount(c)} \xB7 ${c.title}`);
|
|
36421
|
-
console.log(` id: ${c.id}${pr}`);
|
|
36459
|
+
console.log(` [${claimTurnLabel(c.state)}] ${fmtClaimAmount(c)} \xB7 ${c.title}`);
|
|
36460
|
+
console.log(` id: ${c.id} \xB7 ${c.state}${pr}`);
|
|
36422
36461
|
}
|
|
36423
36462
|
printMetric(claims.acceptedPRRate());
|
|
36424
36463
|
printNextSteps(list);
|
|
36464
|
+
printResolveHint(list, console.log);
|
|
36425
36465
|
try {
|
|
36426
36466
|
if (await shouldNudgeUnpushed()) {
|
|
36427
36467
|
console.log(
|
|
@@ -36525,23 +36565,24 @@ async function syncFounderApprovals(claimsModule, targets) {
|
|
|
36525
36565
|
return { pushToken, approvalsChecked, approvalsUnavailable };
|
|
36526
36566
|
}
|
|
36527
36567
|
function founderClaimStanding(claim, approvalsChecked) {
|
|
36568
|
+
const turn = claimTurnLabel(claim.state);
|
|
36528
36569
|
switch (claim.state) {
|
|
36529
36570
|
case "merged":
|
|
36530
|
-
return
|
|
36571
|
+
return `${turn} \u2014 accepted by the poster`;
|
|
36531
36572
|
case "abandoned":
|
|
36532
|
-
return
|
|
36573
|
+
return `${turn} \u2014 rejected, or released locally`;
|
|
36533
36574
|
case "submitted":
|
|
36534
|
-
return
|
|
36575
|
+
return `${turn} \u2014 CI and the verdict: ${nextStep(`terminalhire claim runs ${claim.id}`)}`;
|
|
36535
36576
|
case "working":
|
|
36536
36577
|
case "in-review":
|
|
36537
36578
|
case "ready":
|
|
36538
|
-
return
|
|
36579
|
+
return `${turn} \u2014 approved, slice received (${claim.state})`;
|
|
36539
36580
|
default:
|
|
36540
36581
|
break;
|
|
36541
36582
|
}
|
|
36542
|
-
if (claim.approval?.mode === "open") return
|
|
36543
|
-
if (claim.approval?.state === "granted") return
|
|
36544
|
-
return approvalsChecked ? "
|
|
36583
|
+
if (claim.approval?.mode === "open") return `${turn} \u2014 slice ready (no approval required)`;
|
|
36584
|
+
if (claim.approval?.state === "granted") return `${turn} \u2014 approved, slice ready`;
|
|
36585
|
+
return approvalsChecked ? "waiting on poster \u2014 approval not granted yet" : `${turn} \u2014 registered locally, approval not checked`;
|
|
36545
36586
|
}
|
|
36546
36587
|
async function cmdStatus(id) {
|
|
36547
36588
|
const claims = await Promise.resolve().then(() => (init_claims(), claims_exports));
|
|
@@ -36719,8 +36760,26 @@ async function cmdUpdate(id, state, prUrl) {
|
|
|
36719
36760
|
console.log(`Updated ${id} \u2192 ${state}${prUrl ? ` (PR: ${prUrl})` : ""}`);
|
|
36720
36761
|
await beatFounderPresence(updated);
|
|
36721
36762
|
}
|
|
36722
|
-
|
|
36723
|
-
|
|
36763
|
+
function printReleaseIsLocalOnly(id, claim, log, standDownOutcome = null) {
|
|
36764
|
+
log("");
|
|
36765
|
+
log(" Release updates this machine \u2014 terminalhire is not told, so the poster hears");
|
|
36766
|
+
log(" nothing about it.");
|
|
36767
|
+
if (standDownOutcome === "posted") {
|
|
36768
|
+
log(" Your stand-down comment did go to the issue on GitHub.");
|
|
36769
|
+
} else if (standDownOutcome === "failed") {
|
|
36770
|
+
log(" Your stand-down comment was attempted and errored, so whether it reached the");
|
|
36771
|
+
log(" issue is unknown. Check it there.");
|
|
36772
|
+
}
|
|
36773
|
+
if (claim?.approval?.claimId) {
|
|
36774
|
+
log(" To tell the poster why you are handing it back, run this first:");
|
|
36775
|
+
log(` terminalhire claim resolve ${id} --reason <reason>`);
|
|
36776
|
+
}
|
|
36777
|
+
log("");
|
|
36778
|
+
}
|
|
36779
|
+
async function cmdRelease(id, flags = {}, deps = {}) {
|
|
36780
|
+
const claims = deps.claimsModule ?? await Promise.resolve().then(() => (init_claims(), claims_exports));
|
|
36781
|
+
const log = deps.log ?? console.log;
|
|
36782
|
+
const standDown = deps.standDown ?? offerStandDown;
|
|
36724
36783
|
if (!id) {
|
|
36725
36784
|
console.error("Usage: terminalhire claim release <id> [--force]");
|
|
36726
36785
|
process.exit(1);
|
|
@@ -36739,24 +36798,39 @@ async function cmdRelease(id, flags = {}) {
|
|
|
36739
36798
|
}
|
|
36740
36799
|
let standDownOutcome = null;
|
|
36741
36800
|
if (target && target.stake && target.stake.branch === "contested") {
|
|
36742
|
-
const outcome = await
|
|
36801
|
+
const outcome = await standDown(target);
|
|
36743
36802
|
standDownOutcome = outcome;
|
|
36744
|
-
if (outcome === "skipped" || outcome === "failed") {
|
|
36803
|
+
if (outcome === "skipped" || outcome === "failed" || outcome === "unchecked") {
|
|
36745
36804
|
if (!flags.force) {
|
|
36746
|
-
|
|
36747
|
-
|
|
36748
|
-
Not released \u2014
|
|
36749
|
-
|
|
36750
|
-
|
|
36751
|
-
|
|
36752
|
-
|
|
36753
|
-
`
|
|
36805
|
+
log("");
|
|
36806
|
+
if (outcome === "failed") {
|
|
36807
|
+
log(` Not released \u2014 whether your stand-down comment on ${id} reached the issue is`);
|
|
36808
|
+
log(" unknown: the post errored after it went out.");
|
|
36809
|
+
log(" Read the issue before writing one by hand \u2014 it may already be there.");
|
|
36810
|
+
log(" Once the issue reads as stood down, release:");
|
|
36811
|
+
} else if (outcome === "unchecked") {
|
|
36812
|
+
log(` Not released \u2014 whether your stake comment on ${id} ever reached the issue`);
|
|
36813
|
+
log(" is unknown: the post errored, and the issue could not be read to check.");
|
|
36814
|
+
log(" Read the issue. If your comment is there, reply that you are standing");
|
|
36815
|
+
log(" down; then release:");
|
|
36816
|
+
} else {
|
|
36817
|
+
log(
|
|
36818
|
+
` Not released \u2014 ${id} still has a public stake on the issue and nothing has retracted it.`
|
|
36819
|
+
);
|
|
36820
|
+
log(" Retract it, then release:");
|
|
36821
|
+
}
|
|
36822
|
+
log(` terminalhire claim release ${id} # at a real terminal`);
|
|
36823
|
+
log(
|
|
36824
|
+
outcome === "failed" ? ` terminalhire claim release ${id} --force # release anyway; delivery stays unknown` : outcome === "unchecked" ? ` terminalhire claim release ${id} --force # release anyway; standing unknown` : ` terminalhire claim release ${id} --force # release anyway, stake stays up`
|
|
36754
36825
|
);
|
|
36755
36826
|
return;
|
|
36756
36827
|
}
|
|
36757
|
-
|
|
36828
|
+
log(
|
|
36829
|
+
outcome === "failed" ? " (--force \u2014 releasing without knowing whether your stand-down comment landed)" : outcome === "unchecked" ? " (--force \u2014 releasing; whether your stake comment ever landed is unknown)" : " (--force \u2014 releasing with the public stake still standing)"
|
|
36830
|
+
);
|
|
36758
36831
|
}
|
|
36759
36832
|
}
|
|
36833
|
+
if (target) printReleaseIsLocalOnly(id, target, log, standDownOutcome);
|
|
36760
36834
|
const expectedStake = standDownOutcome === "absent" ? null : target?.stake?.postedAt ?? null;
|
|
36761
36835
|
const removed = claims.removeClaimIfStakeMatches(id, expectedStake);
|
|
36762
36836
|
if (!removed && claims.findClaim(id)) {
|
|
@@ -36798,7 +36872,7 @@ async function offerStandDown(claim) {
|
|
|
36798
36872
|
console.log(
|
|
36799
36873
|
` (couldn't reach ${repoFullName}#${number} to check whether your comment posted \u2014 check it manually; the claim is kept so the stake isn't lost)`
|
|
36800
36874
|
);
|
|
36801
|
-
return "
|
|
36875
|
+
return "unchecked";
|
|
36802
36876
|
}
|
|
36803
36877
|
}
|
|
36804
36878
|
if (!process.stdin.isTTY) {
|
|
@@ -36820,7 +36894,7 @@ async function offerStandDown(claim) {
|
|
|
36820
36894
|
return "posted";
|
|
36821
36895
|
} catch (err) {
|
|
36822
36896
|
console.log(
|
|
36823
|
-
` (
|
|
36897
|
+
` (the stand-down post errored: ${err.stderr || err.message || err}. It may still have landed \u2014 read ${repoFullName}#${number} before writing one by hand.)`
|
|
36824
36898
|
);
|
|
36825
36899
|
return "failed";
|
|
36826
36900
|
}
|
|
@@ -36969,7 +37043,13 @@ async function cmdStart(id, flags = {}) {
|
|
|
36969
37043
|
if (!claim) {
|
|
36970
37044
|
const b = await resolveBounty(id);
|
|
36971
37045
|
if (!b) {
|
|
36972
|
-
const {
|
|
37046
|
+
const {
|
|
37047
|
+
recovered,
|
|
37048
|
+
reason,
|
|
37049
|
+
id: recoveredId,
|
|
37050
|
+
linkedHost,
|
|
37051
|
+
currentHost
|
|
37052
|
+
} = await recoverHeldClaim(id, flags);
|
|
36973
37053
|
if (recovered) {
|
|
36974
37054
|
claim = recovered;
|
|
36975
37055
|
id = recoveredId;
|
|
@@ -37034,7 +37114,9 @@ async function cmdStart(id, flags = {}) {
|
|
|
37034
37114
|
if (!chainedFromRecord) {
|
|
37035
37115
|
console.log(`
|
|
37036
37116
|
${sanitizeText(claim.title)}`);
|
|
37037
|
-
console.log(
|
|
37117
|
+
console.log(
|
|
37118
|
+
"\n No fork was attempted \u2014 terminalhire postings are never forked or cloned. Your"
|
|
37119
|
+
);
|
|
37038
37120
|
console.log(" work slice is delivered through terminalhire, and your patch goes back the");
|
|
37039
37121
|
console.log(" same way.");
|
|
37040
37122
|
}
|
|
@@ -39315,6 +39397,162 @@ async function acknowledgeNotesQuietly(notes) {
|
|
|
39315
39397
|
} catch {
|
|
39316
39398
|
}
|
|
39317
39399
|
}
|
|
39400
|
+
var CLAIM_RESOLUTION_REASONS = [
|
|
39401
|
+
"not-my-stack",
|
|
39402
|
+
"out-of-time",
|
|
39403
|
+
"already-implemented",
|
|
39404
|
+
"repo-does-not-build",
|
|
39405
|
+
"brief-insufficient"
|
|
39406
|
+
];
|
|
39407
|
+
var POSTING_LEVEL_RESOLUTION_REASONS = [
|
|
39408
|
+
"already-implemented",
|
|
39409
|
+
"repo-does-not-build",
|
|
39410
|
+
"brief-insufficient"
|
|
39411
|
+
];
|
|
39412
|
+
var RESOLUTION_REASON_BLURB = {
|
|
39413
|
+
"not-my-stack": "this is not the kind of work you take",
|
|
39414
|
+
"out-of-time": "you ran out of time for it",
|
|
39415
|
+
"already-implemented": "the repo already has this",
|
|
39416
|
+
"repo-does-not-build": "the repo will not build, so nobody can finish it",
|
|
39417
|
+
"brief-insufficient": "the brief does not say enough to do the work"
|
|
39418
|
+
};
|
|
39419
|
+
function isPostingLevelResolutionReason(reason) {
|
|
39420
|
+
return POSTING_LEVEL_RESOLUTION_REASONS.includes(reason);
|
|
39421
|
+
}
|
|
39422
|
+
function resolutionReasonHelpLines() {
|
|
39423
|
+
const lines = [];
|
|
39424
|
+
const width = Math.max(...CLAIM_RESOLUTION_REASONS.map((r) => r.length));
|
|
39425
|
+
const halves = [
|
|
39426
|
+
["These take the posting off the market until the poster acts:", true],
|
|
39427
|
+
["These hand it back for someone else:", false]
|
|
39428
|
+
];
|
|
39429
|
+
for (const [heading, postingLevel] of halves) {
|
|
39430
|
+
lines.push(` ${heading}`);
|
|
39431
|
+
for (const reason of CLAIM_RESOLUTION_REASONS) {
|
|
39432
|
+
if (isPostingLevelResolutionReason(reason) !== postingLevel) continue;
|
|
39433
|
+
lines.push(` ${reason.padEnd(width)} ${RESOLUTION_REASON_BLURB[reason] ?? ""}`);
|
|
39434
|
+
}
|
|
39435
|
+
lines.push("");
|
|
39436
|
+
}
|
|
39437
|
+
return lines;
|
|
39438
|
+
}
|
|
39439
|
+
function resolveUsageLines() {
|
|
39440
|
+
return [
|
|
39441
|
+
'Usage: terminalhire claim resolve <id> --reason <reason> [--note "..."]',
|
|
39442
|
+
"",
|
|
39443
|
+
" Hand a claim back and tell the poster why. Needs `terminalhire link`.",
|
|
39444
|
+
"",
|
|
39445
|
+
...resolutionReasonHelpLines()
|
|
39446
|
+
];
|
|
39447
|
+
}
|
|
39448
|
+
function printResolveHint(list, log) {
|
|
39449
|
+
const resolvable = list.filter(
|
|
39450
|
+
(c) => c?.approval?.claimId && !["merged", "abandoned"].includes(c.state)
|
|
39451
|
+
);
|
|
39452
|
+
if (resolvable.length === 0) return;
|
|
39453
|
+
log("");
|
|
39454
|
+
log(" Cannot finish one of these? Say why, and the poster hears it:");
|
|
39455
|
+
log(` terminalhire claim resolve <id> --reason <reason> (\`--help\` lists them)`);
|
|
39456
|
+
}
|
|
39457
|
+
async function cmdResolve(id, flags = {}, deps = {}) {
|
|
39458
|
+
const log = deps.log ?? console.log;
|
|
39459
|
+
const err = deps.err ?? console.error;
|
|
39460
|
+
const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
|
|
39461
|
+
const askImpl = deps.ask ?? ask;
|
|
39462
|
+
const isTTY = deps.isTTY ?? Boolean(process.stdin.isTTY);
|
|
39463
|
+
if (flags.help) {
|
|
39464
|
+
for (const line of resolveUsageLines()) log(line);
|
|
39465
|
+
return 0;
|
|
39466
|
+
}
|
|
39467
|
+
if (!id) {
|
|
39468
|
+
for (const line of resolveUsageLines()) err(line);
|
|
39469
|
+
return 1;
|
|
39470
|
+
}
|
|
39471
|
+
const claims = deps.claimsModule ?? await Promise.resolve().then(() => (init_claims(), claims_exports));
|
|
39472
|
+
const claim = claims.findClaim(id);
|
|
39473
|
+
if (!claim) {
|
|
39474
|
+
err(`terminalhire claim resolve: no claim with id '${id}'.`);
|
|
39475
|
+
return 1;
|
|
39476
|
+
}
|
|
39477
|
+
const claimId = claim.approval?.claimId ?? null;
|
|
39478
|
+
if (!claimId) {
|
|
39479
|
+
err(`terminalhire claim resolve: '${id}' is not a terminalhire posting, so there is`);
|
|
39480
|
+
err(" no poster to tell. Use `terminalhire claim release` to drop it locally.");
|
|
39481
|
+
return 1;
|
|
39482
|
+
}
|
|
39483
|
+
let reason = typeof flags.reason === "string" ? flags.reason.trim() : "";
|
|
39484
|
+
if (!reason) {
|
|
39485
|
+
if (!isTTY) {
|
|
39486
|
+
err("terminalhire claim resolve: --reason is required when there is no terminal.");
|
|
39487
|
+
for (const line of resolutionReasonHelpLines()) err(line);
|
|
39488
|
+
return 1;
|
|
39489
|
+
}
|
|
39490
|
+
log("");
|
|
39491
|
+
log(` Handing back ${id}. Why?`);
|
|
39492
|
+
log("");
|
|
39493
|
+
for (const line of resolutionReasonHelpLines()) log(line);
|
|
39494
|
+
reason = (await askImpl(" reason: ")).trim();
|
|
39495
|
+
}
|
|
39496
|
+
if (!CLAIM_RESOLUTION_REASONS.includes(reason)) {
|
|
39497
|
+
err(`terminalhire claim resolve: '${reason}' is not one of the reasons.`);
|
|
39498
|
+
for (const line of resolutionReasonHelpLines()) err(line);
|
|
39499
|
+
return 1;
|
|
39500
|
+
}
|
|
39501
|
+
const linked = deps.cookie ? { cookie: deps.cookie, mismatch: null } : webSessionCookieForHost(CLAIM_SYNC_BASE4);
|
|
39502
|
+
if (linked.mismatch) {
|
|
39503
|
+
err(
|
|
39504
|
+
`terminalhire claim resolve: your session was minted by ${linked.mismatch.linkedHost}, and this is ${linked.mismatch.currentHost}. Run \`terminalhire link\` against this one.`
|
|
39505
|
+
);
|
|
39506
|
+
return 1;
|
|
39507
|
+
}
|
|
39508
|
+
if (!linked.cookie) {
|
|
39509
|
+
err("terminalhire claim resolve: needs a linked session. Run `terminalhire link` first.");
|
|
39510
|
+
return 1;
|
|
39511
|
+
}
|
|
39512
|
+
const note = typeof flags.note === "string" && flags.note.trim() ? flags.note.trim() : null;
|
|
39513
|
+
const body = { bountyId: founderPostingIdOf(claim), claimId, reason };
|
|
39514
|
+
if (note) body.note = note;
|
|
39515
|
+
let res;
|
|
39516
|
+
try {
|
|
39517
|
+
res = await fetchImpl(`${CLAIM_SYNC_BASE4}/api/claim/resolution`, {
|
|
39518
|
+
method: "POST",
|
|
39519
|
+
headers: {
|
|
39520
|
+
"Content-Type": "application/json",
|
|
39521
|
+
Cookie: `${GH_SESSION_COOKIE}=${linked.cookie}`
|
|
39522
|
+
},
|
|
39523
|
+
body: JSON.stringify(body),
|
|
39524
|
+
signal: AbortSignal.timeout(15e3)
|
|
39525
|
+
});
|
|
39526
|
+
} catch {
|
|
39527
|
+
err("terminalhire claim resolve: could not reach terminalhire just now. Nothing changed.");
|
|
39528
|
+
return 1;
|
|
39529
|
+
}
|
|
39530
|
+
let answer = null;
|
|
39531
|
+
try {
|
|
39532
|
+
answer = await res.json();
|
|
39533
|
+
} catch {
|
|
39534
|
+
}
|
|
39535
|
+
if (!res.ok) {
|
|
39536
|
+
if (res.status === 401) {
|
|
39537
|
+
err("terminalhire claim resolve: terminalhire did not recognise your session.");
|
|
39538
|
+
err(" Run `terminalhire link` and try again.");
|
|
39539
|
+
return 1;
|
|
39540
|
+
}
|
|
39541
|
+
const message = typeof answer?.error === "string" && answer.error ? answer.error : `terminalhire answered ${res.status}`;
|
|
39542
|
+
err(`terminalhire claim resolve: ${message}`);
|
|
39543
|
+
return 1;
|
|
39544
|
+
}
|
|
39545
|
+
const suspended = typeof answer?.postingSuspended === "boolean" ? answer.postingSuspended : isPostingLevelResolutionReason(reason);
|
|
39546
|
+
log("");
|
|
39547
|
+
log(` \u2713 Handed ${id} back \u2014 reason: ${reason}`);
|
|
39548
|
+
log(
|
|
39549
|
+
suspended ? " The posting is off the market until the poster acts on it." : " The posting is open again for someone else."
|
|
39550
|
+
);
|
|
39551
|
+
log("");
|
|
39552
|
+
log(` The local record is still here. To drop it: terminalhire claim release ${id}`);
|
|
39553
|
+
log("");
|
|
39554
|
+
return 0;
|
|
39555
|
+
}
|
|
39318
39556
|
async function run() {
|
|
39319
39557
|
const verb = process.argv[2];
|
|
39320
39558
|
const rawArgs = process.argv.slice(3).map((a) => a === "-y" ? "--yes" : a);
|
|
@@ -39374,6 +39612,15 @@ async function run() {
|
|
|
39374
39612
|
case "release":
|
|
39375
39613
|
await cmdRelease(positional[0], flags);
|
|
39376
39614
|
break;
|
|
39615
|
+
// Sits beside `release` because that is where a developer giving up on a claim
|
|
39616
|
+
// already looks, and the two are the local and the told-the-poster halves of the
|
|
39617
|
+
// same act. `cmdResolve` returns its exit code rather than calling process.exit,
|
|
39618
|
+
// so its refusals can be tested without spawning a process.
|
|
39619
|
+
case "resolve": {
|
|
39620
|
+
const code = await cmdResolve(positional[0], flags);
|
|
39621
|
+
if (code !== 0) process.exit(code);
|
|
39622
|
+
break;
|
|
39623
|
+
}
|
|
39377
39624
|
case "audit":
|
|
39378
39625
|
await cmdAudit(positional[0], flags);
|
|
39379
39626
|
break;
|
|
@@ -39382,7 +39629,7 @@ async function run() {
|
|
|
39382
39629
|
break;
|
|
39383
39630
|
default:
|
|
39384
39631
|
console.error(
|
|
39385
|
-
`terminalhire claim: unknown verb '${verb ?? ""}'. Expected: preview | record | start | attach | slice | list | status | update | submit | runs | notes | audit | release`
|
|
39632
|
+
`terminalhire claim: unknown verb '${verb ?? ""}'. Expected: preview | record | start | attach | slice | list | status | update | submit | runs | notes | audit | release | resolve`
|
|
39386
39633
|
);
|
|
39387
39634
|
process.exit(1);
|
|
39388
39635
|
}
|
|
@@ -39397,8 +39644,10 @@ export {
|
|
|
39397
39644
|
BRIEF_DIR,
|
|
39398
39645
|
BRIEF_REL_PATH,
|
|
39399
39646
|
CLAIM_CONSENT_VERSION,
|
|
39647
|
+
CLAIM_RESOLUTION_REASONS,
|
|
39400
39648
|
CLOSED_STATES,
|
|
39401
39649
|
OPENABLE_AGENTS,
|
|
39650
|
+
POSTING_LEVEL_RESOLUTION_REASONS,
|
|
39402
39651
|
PUSH_TOKEN_REFUSAL,
|
|
39403
39652
|
REVISE_RECOVERY_STATES,
|
|
39404
39653
|
SUBMIT_ACCEPTS,
|
|
@@ -39417,6 +39666,8 @@ export {
|
|
|
39417
39666
|
cloneFullTierRepo,
|
|
39418
39667
|
cmdPush,
|
|
39419
39668
|
cmdRecord,
|
|
39669
|
+
cmdRelease,
|
|
39670
|
+
cmdResolve,
|
|
39420
39671
|
cmdRuns,
|
|
39421
39672
|
cmdSlice,
|
|
39422
39673
|
cmdSliceFullTier,
|
|
@@ -39439,6 +39690,7 @@ export {
|
|
|
39439
39690
|
indexNativeIdForShortRef,
|
|
39440
39691
|
inferSubmitClaim,
|
|
39441
39692
|
isContested,
|
|
39693
|
+
isPostingLevelResolutionReason,
|
|
39442
39694
|
isStrayArgShortRefClaim,
|
|
39443
39695
|
isTerminalRunStatus,
|
|
39444
39696
|
isVerblessShortRefClaim,
|
|
@@ -39455,12 +39707,15 @@ export {
|
|
|
39455
39707
|
pickExistingPr,
|
|
39456
39708
|
pickStartableClaim,
|
|
39457
39709
|
printNextSteps,
|
|
39710
|
+
printReleaseIsLocalOnly,
|
|
39711
|
+
printResolveHint,
|
|
39458
39712
|
readCredentialDisposition,
|
|
39459
39713
|
recoverHeldClaim,
|
|
39460
39714
|
renderAutoConsent,
|
|
39461
39715
|
renderClaimHistory,
|
|
39462
39716
|
renderRunView,
|
|
39463
39717
|
renderServerRefusal,
|
|
39718
|
+
resolutionReasonHelpLines,
|
|
39464
39719
|
resolveBounty,
|
|
39465
39720
|
resolveDeliveryDir,
|
|
39466
39721
|
resolveSubmitWorktree,
|