terminalhire 0.39.9 → 0.40.0
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/approved-claims-badge.js +28 -0
- package/dist/bin/approved-claims-sync.js +51 -0
- package/dist/bin/claim-push-bg.js +10 -0
- package/dist/bin/founder-paid-badge.js +35 -0
- package/dist/bin/founder-pin.js +7 -0
- package/dist/bin/jpi-bounties.js +118 -38
- package/dist/bin/jpi-claim.js +121 -23
- package/dist/bin/jpi-contribute.js +10 -0
- package/dist/bin/jpi-dispatch.js +225 -12
- package/dist/bin/jpi-hub.js +61 -34
- package/dist/bin/jpi-mcp.js +100 -14
- package/dist/bin/jpi-refresh.js +242 -36
- package/dist/bin/jpi-repo.js +10 -0
- package/dist/bin/jpi-statusline.js +25 -12
- package/dist/src/claims.js +10 -0
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// bin/approved-claims-badge.js
|
|
2
|
+
function normalizeIds(claimIds) {
|
|
3
|
+
if (!Array.isArray(claimIds)) return [];
|
|
4
|
+
return [...new Set(claimIds.filter((id) => typeof id === "string" && id !== ""))].sort();
|
|
5
|
+
}
|
|
6
|
+
function computeApprovedClaims(claimIds, previous) {
|
|
7
|
+
const approved = normalizeIds(claimIds);
|
|
8
|
+
const prior = previous && Array.isArray(previous.acknowledged) ? new Set(previous.acknowledged) : /* @__PURE__ */ new Set();
|
|
9
|
+
const acknowledged = approved.filter((id) => prior.has(id));
|
|
10
|
+
return { count: approved.length - acknowledged.length, acknowledged };
|
|
11
|
+
}
|
|
12
|
+
function acknowledgeApprovedClaim(claimId, previous) {
|
|
13
|
+
const prior = previous && Array.isArray(previous.acknowledged) ? previous.acknowledged : [];
|
|
14
|
+
if (typeof claimId !== "string" || claimId === "") {
|
|
15
|
+
const acknowledged2 = [...new Set(prior)].sort();
|
|
16
|
+
const count2 = previous && typeof previous.count === "number" ? previous.count : 0;
|
|
17
|
+
return { count: count2, acknowledged: acknowledged2 };
|
|
18
|
+
}
|
|
19
|
+
const acknowledged = [.../* @__PURE__ */ new Set([...prior, claimId])].sort();
|
|
20
|
+
const prevCount = previous && typeof previous.count === "number" ? previous.count : 0;
|
|
21
|
+
const alreadyKnown = prior.includes(claimId);
|
|
22
|
+
const count = alreadyKnown ? prevCount : Math.max(0, prevCount - 1);
|
|
23
|
+
return { count, acknowledged };
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
acknowledgeApprovedClaim,
|
|
27
|
+
computeApprovedClaims
|
|
28
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// bin/approved-claims-sync.js
|
|
2
|
+
var CLAIM_SYNC_BASE = "https://terminalhire.com";
|
|
3
|
+
function approvalsSyncGate({ autoMarkerExists, tokenFileExists }) {
|
|
4
|
+
if (!autoMarkerExists || !tokenFileExists) return { sync: false, reason: "not-opted-in" };
|
|
5
|
+
return { sync: true, reason: "ok" };
|
|
6
|
+
}
|
|
7
|
+
function approvalsNudgeGate({ autoMarkerExists, tokenFileExists, awaitingApproval }) {
|
|
8
|
+
if (approvalsSyncGate({ autoMarkerExists, tokenFileExists }).sync) return false;
|
|
9
|
+
return Number.isInteger(awaitingApproval) && awaitingApproval > 0;
|
|
10
|
+
}
|
|
11
|
+
function buildApprovalsNudge(awaitingApproval) {
|
|
12
|
+
if (!Number.isInteger(awaitingApproval) || awaitingApproval <= 0) return null;
|
|
13
|
+
const n = awaitingApproval;
|
|
14
|
+
return ` \u26A0 ${n} claim${n === 1 ? "" : "s"} awaiting founder approval \u2014 terminalhire cannot check in the background until you enrol:
|
|
15
|
+
terminalhire claim --push --keep-updated (or check one now: terminalhire claim slice <id>)`;
|
|
16
|
+
}
|
|
17
|
+
async function syncApprovedClaims({
|
|
18
|
+
readAutoMarker,
|
|
19
|
+
readPushTokenEnc,
|
|
20
|
+
readPrevious,
|
|
21
|
+
fetchImpl = fetch,
|
|
22
|
+
computeApprovedClaims,
|
|
23
|
+
timeoutMs = 15e3
|
|
24
|
+
} = {}) {
|
|
25
|
+
try {
|
|
26
|
+
const marker = readAutoMarker();
|
|
27
|
+
const token = await readPushTokenEnc();
|
|
28
|
+
if (!approvalsSyncGate({ autoMarkerExists: !!marker, tokenFileExists: !!token }).sync) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const res = await fetchImpl(`${CLAIM_SYNC_BASE}/api/claim/approvals`, {
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers: { "Content-Type": "application/json" },
|
|
34
|
+
body: JSON.stringify({ pushToken: token }),
|
|
35
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
36
|
+
});
|
|
37
|
+
if (!res || !res.ok) return null;
|
|
38
|
+
const body = await res.json();
|
|
39
|
+
const claimIds = body && Array.isArray(body.claimIds) ? body.claimIds : null;
|
|
40
|
+
if (!claimIds) return null;
|
|
41
|
+
return computeApprovedClaims(claimIds, readPrevious());
|
|
42
|
+
} catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
approvalsNudgeGate,
|
|
48
|
+
approvalsSyncGate,
|
|
49
|
+
buildApprovalsNudge,
|
|
50
|
+
syncApprovedClaims
|
|
51
|
+
};
|
|
@@ -92,6 +92,7 @@ var claims_exports = {};
|
|
|
92
92
|
__export(claims_exports, {
|
|
93
93
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
94
94
|
acceptedPRRate: () => acceptedPRRate,
|
|
95
|
+
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
95
96
|
findClaim: () => findClaim,
|
|
96
97
|
listClaims: () => listClaims,
|
|
97
98
|
nextPolledState: () => nextPolledState,
|
|
@@ -273,6 +274,15 @@ function removeClaimIfStakeMatches(id, expectedStakePostedAt) {
|
|
|
273
274
|
return true;
|
|
274
275
|
});
|
|
275
276
|
}
|
|
277
|
+
function countAwaitingFounderApproval(claims = readClaims()) {
|
|
278
|
+
try {
|
|
279
|
+
return claims.filter(
|
|
280
|
+
(c) => c.approval?.mode === "approval-only" && c.approval?.state === "pending"
|
|
281
|
+
).length;
|
|
282
|
+
} catch {
|
|
283
|
+
return 0;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
276
286
|
function acceptedPRRate(claims = readClaims()) {
|
|
277
287
|
const total = claims.length;
|
|
278
288
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// bin/founder-pin.js
|
|
2
|
+
function isPinnedFounderBounty(j) {
|
|
3
|
+
return j?.bounty?.bountySource === "founder" && j?.bounty?.claimable === true;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// bin/founder-paid-badge.js
|
|
7
|
+
function openPaidIds(index) {
|
|
8
|
+
const jobs = index && index.jobs || [];
|
|
9
|
+
const ids = [];
|
|
10
|
+
for (const j of jobs) {
|
|
11
|
+
if (!j || typeof j.id !== "string") continue;
|
|
12
|
+
if (isPinnedFounderBounty(j)) ids.push(j.id);
|
|
13
|
+
}
|
|
14
|
+
return [...new Set(ids)].sort();
|
|
15
|
+
}
|
|
16
|
+
function gate(openIds, seenIds) {
|
|
17
|
+
const seen = new Set(seenIds);
|
|
18
|
+
const acknowledged = openIds.filter((id) => seen.has(id));
|
|
19
|
+
return { count: openIds.length - acknowledged.length, acknowledged };
|
|
20
|
+
}
|
|
21
|
+
function computeFounderPaid(index, previous) {
|
|
22
|
+
const open = openPaidIds(index);
|
|
23
|
+
const prior = previous && previous.acknowledged;
|
|
24
|
+
if (!Array.isArray(prior)) return { count: 0, acknowledged: open };
|
|
25
|
+
return gate(open, prior);
|
|
26
|
+
}
|
|
27
|
+
function acknowledgeFounderPaid({ shown = [], open = [], previous } = {}) {
|
|
28
|
+
const prior = previous && Array.isArray(previous.acknowledged) ? previous.acknowledged : [];
|
|
29
|
+
return gate(openPaidIds({ jobs: open }), [...prior, ...openPaidIds({ jobs: shown })]);
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
acknowledgeFounderPaid,
|
|
33
|
+
computeFounderPaid,
|
|
34
|
+
openPaidIds
|
|
35
|
+
};
|
package/dist/bin/jpi-bounties.js
CHANGED
|
@@ -1258,7 +1258,7 @@ async function fetchOwnedRepoTraction(login, token) {
|
|
|
1258
1258
|
for (const r of enrichCandidates) {
|
|
1259
1259
|
r.externalContributors = await repoExternalContributorCount(login, r.name, login, token);
|
|
1260
1260
|
}
|
|
1261
|
-
const
|
|
1261
|
+
const gate2 = qualifiesMaintainer(
|
|
1262
1262
|
ranked.map((r) => ({
|
|
1263
1263
|
name: r.name,
|
|
1264
1264
|
stars: r.stars,
|
|
@@ -1267,15 +1267,15 @@ async function fetchOwnedRepoTraction(login, token) {
|
|
|
1267
1267
|
fork: false
|
|
1268
1268
|
}))
|
|
1269
1269
|
);
|
|
1270
|
-
const best =
|
|
1270
|
+
const best = gate2.qualifies ? ranked.find((r) => r.name === gate2.bestRepoName) ?? null : null;
|
|
1271
1271
|
return {
|
|
1272
1272
|
status: "ok",
|
|
1273
1273
|
totalStars,
|
|
1274
1274
|
totalForks,
|
|
1275
1275
|
reposWithStars,
|
|
1276
1276
|
top: ranked.slice(0, TRACTION_TOP_N),
|
|
1277
|
-
qualifies:
|
|
1278
|
-
bestRepoName:
|
|
1277
|
+
qualifies: gate2.qualifies,
|
|
1278
|
+
bestRepoName: gate2.bestRepoName,
|
|
1279
1279
|
bestRepoExternalContributors: best ? best.externalContributors : null,
|
|
1280
1280
|
bestRepoStars: best ? best.stars : null,
|
|
1281
1281
|
computedAt
|
|
@@ -10405,6 +10405,58 @@ var init_state_dir = __esm({
|
|
|
10405
10405
|
}
|
|
10406
10406
|
});
|
|
10407
10407
|
|
|
10408
|
+
// bin/cache-store.js
|
|
10409
|
+
var cache_store_exports = {};
|
|
10410
|
+
__export(cache_store_exports, {
|
|
10411
|
+
readCacheEntry: () => readCacheEntry,
|
|
10412
|
+
updateIndexCache: () => updateIndexCache
|
|
10413
|
+
});
|
|
10414
|
+
import { readFileSync as readFileSync2, writeFileSync, renameSync } from "fs";
|
|
10415
|
+
import { join as join2 } from "path";
|
|
10416
|
+
import { homedir } from "os";
|
|
10417
|
+
function readCacheEntry() {
|
|
10418
|
+
try {
|
|
10419
|
+
return JSON.parse(readFileSync2(INDEX_CACHE_FILE, "utf8"));
|
|
10420
|
+
} catch {
|
|
10421
|
+
return null;
|
|
10422
|
+
}
|
|
10423
|
+
}
|
|
10424
|
+
function updateIndexCache(patch) {
|
|
10425
|
+
ensureStateDir(TERMINALHIRE_DIR);
|
|
10426
|
+
const existing = readCacheEntry() ?? {};
|
|
10427
|
+
const entry = {
|
|
10428
|
+
...existing,
|
|
10429
|
+
...patch,
|
|
10430
|
+
schemaVersion: SCHEMA_VERSION2,
|
|
10431
|
+
ts: Date.now()
|
|
10432
|
+
};
|
|
10433
|
+
const tmp = `${INDEX_CACHE_FILE}.${process.pid}.${tmpCounter++}.tmp`;
|
|
10434
|
+
writeFileSync(tmp, JSON.stringify(entry), "utf8");
|
|
10435
|
+
renameSync(tmp, INDEX_CACHE_FILE);
|
|
10436
|
+
return entry;
|
|
10437
|
+
}
|
|
10438
|
+
var TERMINALHIRE_DIR, INDEX_CACHE_FILE, SCHEMA_VERSION2, tmpCounter;
|
|
10439
|
+
var init_cache_store = __esm({
|
|
10440
|
+
"bin/cache-store.js"() {
|
|
10441
|
+
"use strict";
|
|
10442
|
+
init_state_dir();
|
|
10443
|
+
TERMINALHIRE_DIR = process.env.TERMINALHIRE_DIR || join2(homedir(), ".terminalhire");
|
|
10444
|
+
INDEX_CACHE_FILE = join2(TERMINALHIRE_DIR, "index-cache.json");
|
|
10445
|
+
SCHEMA_VERSION2 = 1;
|
|
10446
|
+
tmpCounter = 0;
|
|
10447
|
+
}
|
|
10448
|
+
});
|
|
10449
|
+
|
|
10450
|
+
// bin/founder-pin.js
|
|
10451
|
+
function isPinnedFounderBounty(j) {
|
|
10452
|
+
return j?.bounty?.bountySource === "founder" && j?.bounty?.claimable === true;
|
|
10453
|
+
}
|
|
10454
|
+
var init_founder_pin = __esm({
|
|
10455
|
+
"bin/founder-pin.js"() {
|
|
10456
|
+
"use strict";
|
|
10457
|
+
}
|
|
10458
|
+
});
|
|
10459
|
+
|
|
10408
10460
|
// src/test-race-barrier.ts
|
|
10409
10461
|
import { closeSync as closeSync2, constants as constants2, existsSync, lstatSync, openSync as openSync2 } from "fs";
|
|
10410
10462
|
import { join as join3 } from "path";
|
|
@@ -11072,6 +11124,7 @@ var claims_exports = {};
|
|
|
11072
11124
|
__export(claims_exports, {
|
|
11073
11125
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
11074
11126
|
acceptedPRRate: () => acceptedPRRate,
|
|
11127
|
+
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
11075
11128
|
findClaim: () => findClaim,
|
|
11076
11129
|
listClaims: () => listClaims,
|
|
11077
11130
|
nextPolledState: () => nextPolledState,
|
|
@@ -11253,6 +11306,15 @@ function removeClaimIfStakeMatches(id, expectedStakePostedAt) {
|
|
|
11253
11306
|
return true;
|
|
11254
11307
|
});
|
|
11255
11308
|
}
|
|
11309
|
+
function countAwaitingFounderApproval(claims = readClaims()) {
|
|
11310
|
+
try {
|
|
11311
|
+
return claims.filter(
|
|
11312
|
+
(c) => c.approval?.mode === "approval-only" && c.approval?.state === "pending"
|
|
11313
|
+
).length;
|
|
11314
|
+
} catch {
|
|
11315
|
+
return 0;
|
|
11316
|
+
}
|
|
11317
|
+
}
|
|
11256
11318
|
function acceptedPRRate(claims = readClaims()) {
|
|
11257
11319
|
const total = claims.length;
|
|
11258
11320
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
@@ -11301,44 +11363,52 @@ var init_claims = __esm({
|
|
|
11301
11363
|
}
|
|
11302
11364
|
});
|
|
11303
11365
|
|
|
11366
|
+
// bin/founder-paid-badge.js
|
|
11367
|
+
var founder_paid_badge_exports = {};
|
|
11368
|
+
__export(founder_paid_badge_exports, {
|
|
11369
|
+
acknowledgeFounderPaid: () => acknowledgeFounderPaid,
|
|
11370
|
+
computeFounderPaid: () => computeFounderPaid,
|
|
11371
|
+
openPaidIds: () => openPaidIds
|
|
11372
|
+
});
|
|
11373
|
+
function openPaidIds(index) {
|
|
11374
|
+
const jobs = index && index.jobs || [];
|
|
11375
|
+
const ids = [];
|
|
11376
|
+
for (const j of jobs) {
|
|
11377
|
+
if (!j || typeof j.id !== "string") continue;
|
|
11378
|
+
if (isPinnedFounderBounty(j)) ids.push(j.id);
|
|
11379
|
+
}
|
|
11380
|
+
return [...new Set(ids)].sort();
|
|
11381
|
+
}
|
|
11382
|
+
function gate(openIds, seenIds) {
|
|
11383
|
+
const seen = new Set(seenIds);
|
|
11384
|
+
const acknowledged = openIds.filter((id) => seen.has(id));
|
|
11385
|
+
return { count: openIds.length - acknowledged.length, acknowledged };
|
|
11386
|
+
}
|
|
11387
|
+
function computeFounderPaid(index, previous) {
|
|
11388
|
+
const open = openPaidIds(index);
|
|
11389
|
+
const prior = previous && previous.acknowledged;
|
|
11390
|
+
if (!Array.isArray(prior)) return { count: 0, acknowledged: open };
|
|
11391
|
+
return gate(open, prior);
|
|
11392
|
+
}
|
|
11393
|
+
function acknowledgeFounderPaid({ shown = [], open = [], previous } = {}) {
|
|
11394
|
+
const prior = previous && Array.isArray(previous.acknowledged) ? previous.acknowledged : [];
|
|
11395
|
+
return gate(openPaidIds({ jobs: open }), [...prior, ...openPaidIds({ jobs: shown })]);
|
|
11396
|
+
}
|
|
11397
|
+
var init_founder_paid_badge = __esm({
|
|
11398
|
+
"bin/founder-paid-badge.js"() {
|
|
11399
|
+
"use strict";
|
|
11400
|
+
init_founder_pin();
|
|
11401
|
+
}
|
|
11402
|
+
});
|
|
11403
|
+
|
|
11304
11404
|
// bin/jpi-bounties.js
|
|
11305
11405
|
init_src();
|
|
11406
|
+
init_cache_store();
|
|
11306
11407
|
import { readFileSync as readFileSync6 } from "fs";
|
|
11307
11408
|
import { join as join9 } from "path";
|
|
11308
11409
|
import { homedir as homedir6 } from "os";
|
|
11309
11410
|
import { createInterface } from "readline";
|
|
11310
11411
|
|
|
11311
|
-
// bin/cache-store.js
|
|
11312
|
-
init_state_dir();
|
|
11313
|
-
import { readFileSync as readFileSync2, writeFileSync, renameSync } from "fs";
|
|
11314
|
-
import { join as join2 } from "path";
|
|
11315
|
-
import { homedir } from "os";
|
|
11316
|
-
var TERMINALHIRE_DIR = process.env.TERMINALHIRE_DIR || join2(homedir(), ".terminalhire");
|
|
11317
|
-
var INDEX_CACHE_FILE = join2(TERMINALHIRE_DIR, "index-cache.json");
|
|
11318
|
-
var SCHEMA_VERSION2 = 1;
|
|
11319
|
-
var tmpCounter = 0;
|
|
11320
|
-
function readCacheEntry() {
|
|
11321
|
-
try {
|
|
11322
|
-
return JSON.parse(readFileSync2(INDEX_CACHE_FILE, "utf8"));
|
|
11323
|
-
} catch {
|
|
11324
|
-
return null;
|
|
11325
|
-
}
|
|
11326
|
-
}
|
|
11327
|
-
function updateIndexCache(patch) {
|
|
11328
|
-
ensureStateDir(TERMINALHIRE_DIR);
|
|
11329
|
-
const existing = readCacheEntry() ?? {};
|
|
11330
|
-
const entry = {
|
|
11331
|
-
...existing,
|
|
11332
|
-
...patch,
|
|
11333
|
-
schemaVersion: SCHEMA_VERSION2,
|
|
11334
|
-
ts: Date.now()
|
|
11335
|
-
};
|
|
11336
|
-
const tmp = `${INDEX_CACHE_FILE}.${process.pid}.${tmpCounter++}.tmp`;
|
|
11337
|
-
writeFileSync(tmp, JSON.stringify(entry), "utf8");
|
|
11338
|
-
renameSync(tmp, INDEX_CACHE_FILE);
|
|
11339
|
-
return entry;
|
|
11340
|
-
}
|
|
11341
|
-
|
|
11342
11412
|
// bin/sanitize.js
|
|
11343
11413
|
var CONTROL_CHARS = /[\x00-\x1f\x7f-\x9f]/g;
|
|
11344
11414
|
function sanitizeText(s) {
|
|
@@ -11371,6 +11441,7 @@ function linkTitle(title, url) {
|
|
|
11371
11441
|
}
|
|
11372
11442
|
|
|
11373
11443
|
// bin/jpi-bounties.js
|
|
11444
|
+
init_founder_pin();
|
|
11374
11445
|
var TERMINALHIRE_DIR6 = process.env.TERMINALHIRE_DIR || join9(homedir6(), ".terminalhire");
|
|
11375
11446
|
var INDEX_CACHE_FILE2 = join9(TERMINALHIRE_DIR6, "index-cache.json");
|
|
11376
11447
|
var INDEX_TTL_MS = 15 * 60 * 1e3;
|
|
@@ -11447,9 +11518,6 @@ ${i + 1}. ${linkTitle(job.title, job.url)} [${ref}]`);
|
|
|
11447
11518
|
claimed ? ` \u2192 claimed by you \u2014 terminalhire claim status ${job.id}` : ` \u2192 terminalhire claim ${ref}`
|
|
11448
11519
|
);
|
|
11449
11520
|
}
|
|
11450
|
-
function isPinnedFounderBounty(j) {
|
|
11451
|
-
return j?.bounty?.bountySource === "founder" && j?.bounty?.claimable === true;
|
|
11452
|
-
}
|
|
11453
11521
|
function rankBounties(bounties, { rankMode = "winnability", scoreOf = () => 0 } = {}) {
|
|
11454
11522
|
const legacy = rankMode === "legacy";
|
|
11455
11523
|
const pin = (j) => isPinnedFounderBounty(j) ? 1 : 0;
|
|
@@ -11593,6 +11661,18 @@ async function run() {
|
|
|
11593
11661
|
continuityNote
|
|
11594
11662
|
);
|
|
11595
11663
|
}
|
|
11664
|
+
try {
|
|
11665
|
+
const { acknowledgeFounderPaid: acknowledgeFounderPaid2 } = await Promise.resolve().then(() => (init_founder_paid_badge(), founder_paid_badge_exports));
|
|
11666
|
+
const { readCacheEntry: readCacheEntry2 } = await Promise.resolve().then(() => (init_cache_store(), cache_store_exports));
|
|
11667
|
+
updateIndexCache({
|
|
11668
|
+
founderPaid: acknowledgeFounderPaid2({
|
|
11669
|
+
shown,
|
|
11670
|
+
open: bounties,
|
|
11671
|
+
previous: (readCacheEntry2() ?? {}).founderPaid
|
|
11672
|
+
})
|
|
11673
|
+
});
|
|
11674
|
+
} catch {
|
|
11675
|
+
}
|
|
11596
11676
|
if (!SHOW_ALL && bounties.length > shown.length) {
|
|
11597
11677
|
console.log(
|
|
11598
11678
|
`
|
package/dist/bin/jpi-claim.js
CHANGED
|
@@ -10433,6 +10433,7 @@ var claims_exports = {};
|
|
|
10433
10433
|
__export(claims_exports, {
|
|
10434
10434
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
10435
10435
|
acceptedPRRate: () => acceptedPRRate,
|
|
10436
|
+
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
10436
10437
|
findClaim: () => findClaim,
|
|
10437
10438
|
listClaims: () => listClaims,
|
|
10438
10439
|
nextPolledState: () => nextPolledState,
|
|
@@ -10614,6 +10615,15 @@ function removeClaimIfStakeMatches(id, expectedStakePostedAt) {
|
|
|
10614
10615
|
return true;
|
|
10615
10616
|
});
|
|
10616
10617
|
}
|
|
10618
|
+
function countAwaitingFounderApproval(claims = readClaims()) {
|
|
10619
|
+
try {
|
|
10620
|
+
return claims.filter(
|
|
10621
|
+
(c) => c.approval?.mode === "approval-only" && c.approval?.state === "pending"
|
|
10622
|
+
).length;
|
|
10623
|
+
} catch {
|
|
10624
|
+
return 0;
|
|
10625
|
+
}
|
|
10626
|
+
}
|
|
10617
10627
|
function acceptedPRRate(claims = readClaims()) {
|
|
10618
10628
|
const total = claims.length;
|
|
10619
10629
|
const merged = claims.filter((c) => c.state === "merged").length;
|
|
@@ -25572,6 +25582,83 @@ var init_progress = __esm({
|
|
|
25572
25582
|
}
|
|
25573
25583
|
});
|
|
25574
25584
|
|
|
25585
|
+
// bin/approved-claims-badge.js
|
|
25586
|
+
var approved_claims_badge_exports = {};
|
|
25587
|
+
__export(approved_claims_badge_exports, {
|
|
25588
|
+
acknowledgeApprovedClaim: () => acknowledgeApprovedClaim,
|
|
25589
|
+
computeApprovedClaims: () => computeApprovedClaims
|
|
25590
|
+
});
|
|
25591
|
+
function normalizeIds(claimIds) {
|
|
25592
|
+
if (!Array.isArray(claimIds)) return [];
|
|
25593
|
+
return [...new Set(claimIds.filter((id) => typeof id === "string" && id !== ""))].sort();
|
|
25594
|
+
}
|
|
25595
|
+
function computeApprovedClaims(claimIds, previous) {
|
|
25596
|
+
const approved = normalizeIds(claimIds);
|
|
25597
|
+
const prior = previous && Array.isArray(previous.acknowledged) ? new Set(previous.acknowledged) : /* @__PURE__ */ new Set();
|
|
25598
|
+
const acknowledged = approved.filter((id) => prior.has(id));
|
|
25599
|
+
return { count: approved.length - acknowledged.length, acknowledged };
|
|
25600
|
+
}
|
|
25601
|
+
function acknowledgeApprovedClaim(claimId, previous) {
|
|
25602
|
+
const prior = previous && Array.isArray(previous.acknowledged) ? previous.acknowledged : [];
|
|
25603
|
+
if (typeof claimId !== "string" || claimId === "") {
|
|
25604
|
+
const acknowledged2 = [...new Set(prior)].sort();
|
|
25605
|
+
const count2 = previous && typeof previous.count === "number" ? previous.count : 0;
|
|
25606
|
+
return { count: count2, acknowledged: acknowledged2 };
|
|
25607
|
+
}
|
|
25608
|
+
const acknowledged = [.../* @__PURE__ */ new Set([...prior, claimId])].sort();
|
|
25609
|
+
const prevCount = previous && typeof previous.count === "number" ? previous.count : 0;
|
|
25610
|
+
const alreadyKnown = prior.includes(claimId);
|
|
25611
|
+
const count = alreadyKnown ? prevCount : Math.max(0, prevCount - 1);
|
|
25612
|
+
return { count, acknowledged };
|
|
25613
|
+
}
|
|
25614
|
+
var init_approved_claims_badge = __esm({
|
|
25615
|
+
"bin/approved-claims-badge.js"() {
|
|
25616
|
+
"use strict";
|
|
25617
|
+
}
|
|
25618
|
+
});
|
|
25619
|
+
|
|
25620
|
+
// bin/cache-store.js
|
|
25621
|
+
var cache_store_exports = {};
|
|
25622
|
+
__export(cache_store_exports, {
|
|
25623
|
+
readCacheEntry: () => readCacheEntry,
|
|
25624
|
+
updateIndexCache: () => updateIndexCache
|
|
25625
|
+
});
|
|
25626
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync9, renameSync as renameSync5 } from "fs";
|
|
25627
|
+
import { join as join16 } from "path";
|
|
25628
|
+
import { homedir as homedir10 } from "os";
|
|
25629
|
+
function readCacheEntry() {
|
|
25630
|
+
try {
|
|
25631
|
+
return JSON.parse(readFileSync10(INDEX_CACHE_FILE, "utf8"));
|
|
25632
|
+
} catch {
|
|
25633
|
+
return null;
|
|
25634
|
+
}
|
|
25635
|
+
}
|
|
25636
|
+
function updateIndexCache(patch) {
|
|
25637
|
+
ensureStateDir(TERMINALHIRE_DIR10);
|
|
25638
|
+
const existing = readCacheEntry() ?? {};
|
|
25639
|
+
const entry = {
|
|
25640
|
+
...existing,
|
|
25641
|
+
...patch,
|
|
25642
|
+
schemaVersion: SCHEMA_VERSION2,
|
|
25643
|
+
ts: Date.now()
|
|
25644
|
+
};
|
|
25645
|
+
const tmp = `${INDEX_CACHE_FILE}.${process.pid}.${tmpCounter++}.tmp`;
|
|
25646
|
+
writeFileSync9(tmp, JSON.stringify(entry), "utf8");
|
|
25647
|
+
renameSync5(tmp, INDEX_CACHE_FILE);
|
|
25648
|
+
return entry;
|
|
25649
|
+
}
|
|
25650
|
+
var TERMINALHIRE_DIR10, INDEX_CACHE_FILE, SCHEMA_VERSION2, tmpCounter;
|
|
25651
|
+
var init_cache_store = __esm({
|
|
25652
|
+
"bin/cache-store.js"() {
|
|
25653
|
+
"use strict";
|
|
25654
|
+
init_state_dir();
|
|
25655
|
+
TERMINALHIRE_DIR10 = process.env.TERMINALHIRE_DIR || join16(homedir10(), ".terminalhire");
|
|
25656
|
+
INDEX_CACHE_FILE = join16(TERMINALHIRE_DIR10, "index-cache.json");
|
|
25657
|
+
SCHEMA_VERSION2 = 1;
|
|
25658
|
+
tmpCounter = 0;
|
|
25659
|
+
}
|
|
25660
|
+
});
|
|
25661
|
+
|
|
25575
25662
|
// src/acceptance-score.ts
|
|
25576
25663
|
var acceptance_score_exports = {};
|
|
25577
25664
|
__export(acceptance_score_exports, {
|
|
@@ -25764,9 +25851,9 @@ var init_audit2 = __esm({
|
|
|
25764
25851
|
|
|
25765
25852
|
// bin/jpi-claim.js
|
|
25766
25853
|
init_src();
|
|
25767
|
-
import { readFileSync as
|
|
25768
|
-
import { join as
|
|
25769
|
-
import { homedir as
|
|
25854
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync10, mkdirSync as mkdirSync3, existsSync as existsSync8, rmSync as rmSync5, readdirSync as readdirSync2 } from "fs";
|
|
25855
|
+
import { join as join17, dirname as dirname6, isAbsolute as isAbsolute3, resolve as pathResolve } from "path";
|
|
25856
|
+
import { homedir as homedir11, hostname as osHostname } from "os";
|
|
25770
25857
|
import { execFile as execFile3 } from "child_process";
|
|
25771
25858
|
import { promisify as promisify3 } from "util";
|
|
25772
25859
|
import { createInterface as createInterface2 } from "readline";
|
|
@@ -25944,13 +26031,13 @@ async function shouldNudgeUnpushed() {
|
|
|
25944
26031
|
}
|
|
25945
26032
|
|
|
25946
26033
|
// bin/jpi-claim.js
|
|
25947
|
-
var
|
|
25948
|
-
var
|
|
25949
|
-
var CLAIM_PUSH_MARKER =
|
|
25950
|
-
var REPO_CONTINUITY_NUDGE_MARKER =
|
|
26034
|
+
var TERMINALHIRE_DIR11 = process.env.TERMINALHIRE_DIR || join17(homedir11(), ".terminalhire");
|
|
26035
|
+
var INDEX_CACHE_FILE2 = join17(TERMINALHIRE_DIR11, "index-cache.json");
|
|
26036
|
+
var CLAIM_PUSH_MARKER = join17(TERMINALHIRE_DIR11, "claim-push.json");
|
|
26037
|
+
var REPO_CONTINUITY_NUDGE_MARKER = join17(TERMINALHIRE_DIR11, "repo-continuity-nudged.json");
|
|
25951
26038
|
function readNudgedClaimIds() {
|
|
25952
26039
|
try {
|
|
25953
|
-
const raw = JSON.parse(
|
|
26040
|
+
const raw = JSON.parse(readFileSync11(REPO_CONTINUITY_NUDGE_MARKER, "utf8"));
|
|
25954
26041
|
return new Set(Array.isArray(raw.claimIds) ? raw.claimIds : []);
|
|
25955
26042
|
} catch {
|
|
25956
26043
|
return /* @__PURE__ */ new Set();
|
|
@@ -25960,8 +26047,8 @@ function markClaimNudged(id) {
|
|
|
25960
26047
|
try {
|
|
25961
26048
|
const ids = readNudgedClaimIds();
|
|
25962
26049
|
ids.add(id);
|
|
25963
|
-
ensureStateDir(
|
|
25964
|
-
|
|
26050
|
+
ensureStateDir(TERMINALHIRE_DIR11);
|
|
26051
|
+
writeFileSync10(REPO_CONTINUITY_NUDGE_MARKER, JSON.stringify({ claimIds: [...ids] }), "utf8");
|
|
25965
26052
|
} catch {
|
|
25966
26053
|
}
|
|
25967
26054
|
}
|
|
@@ -26169,8 +26256,8 @@ function pickExistingPr(prListJson, ghUser) {
|
|
|
26169
26256
|
return match2 && typeof match2.url === "string" ? match2.url : null;
|
|
26170
26257
|
}
|
|
26171
26258
|
function readClaimablePool() {
|
|
26172
|
-
if (!existsSync8(
|
|
26173
|
-
const entry = JSON.parse(
|
|
26259
|
+
if (!existsSync8(INDEX_CACHE_FILE2)) return [];
|
|
26260
|
+
const entry = JSON.parse(readFileSync11(INDEX_CACHE_FILE2, "utf8"));
|
|
26174
26261
|
const bounties = (entry?.index?.jobs ?? []).filter((j) => j.source === "bounty");
|
|
26175
26262
|
const contributions = (entry?.index?.contribute ?? []).filter((j) => j.source === "contribute");
|
|
26176
26263
|
return [...bounties, ...contributions];
|
|
@@ -27513,7 +27600,7 @@ async function cmdAttach(id, worktree, branch) {
|
|
|
27513
27600
|
function workDirFor(repoFullName, issueNumber) {
|
|
27514
27601
|
const [owner, repo] = String(repoFullName).split("/");
|
|
27515
27602
|
const suffix = issueNumber ? `-${issueNumber}` : "";
|
|
27516
|
-
return
|
|
27603
|
+
return join17(homedir11(), "terminalhire", "work", `${owner}-${repo}${suffix}`);
|
|
27517
27604
|
}
|
|
27518
27605
|
function startBranchFor(repoFullName, issueNumber) {
|
|
27519
27606
|
const repo = String(repoFullName).split("/")[1] || "claim";
|
|
@@ -27630,7 +27717,7 @@ terminalhire claim: not started \u2014 starting forks ${claim.repoFullName} to y
|
|
|
27630
27717
|
);
|
|
27631
27718
|
process.exit(1);
|
|
27632
27719
|
}
|
|
27633
|
-
mkdirSync3(
|
|
27720
|
+
mkdirSync3(join17(homedir11(), "terminalhire", "work"), { recursive: true });
|
|
27634
27721
|
const { createProgress: createProgress2, parseGitProgress: parseGitProgress2, splitProgressChunk: splitProgressChunk2, shStream: shStream2 } = await Promise.resolve().then(() => (init_progress(), progress_exports));
|
|
27635
27722
|
const progress = createProgress2();
|
|
27636
27723
|
let forkFullName;
|
|
@@ -27759,7 +27846,7 @@ function founderPostingIdOf(claim) {
|
|
|
27759
27846
|
}
|
|
27760
27847
|
function sliceWorkDirFor(claimLocalId) {
|
|
27761
27848
|
const safe = String(claimLocalId).replace(/[^A-Za-z0-9._-]/g, "-");
|
|
27762
|
-
return
|
|
27849
|
+
return join17(homedir11(), "terminalhire", "work", `slice-${safe}`);
|
|
27763
27850
|
}
|
|
27764
27851
|
function renderServerRefusal(status, body) {
|
|
27765
27852
|
const code = body && typeof body.error === "string" ? body.error : null;
|
|
@@ -27783,9 +27870,9 @@ function writeSliceFiles(destDir, files) {
|
|
|
27783
27870
|
const unavailable = [];
|
|
27784
27871
|
for (const f of files) {
|
|
27785
27872
|
if (typeof f.content === "string") {
|
|
27786
|
-
const abs =
|
|
27873
|
+
const abs = join17(destDir, f.path);
|
|
27787
27874
|
mkdirSync3(dirname6(abs), { recursive: true });
|
|
27788
|
-
|
|
27875
|
+
writeFileSync10(abs, f.content, "utf8");
|
|
27789
27876
|
written.push(f.path);
|
|
27790
27877
|
} else {
|
|
27791
27878
|
unavailable.push({ path: f.path, reason: f.unavailableReason || "(no reason given)" });
|
|
@@ -27944,6 +28031,17 @@ async function cmdSlice(id, flags = {}) {
|
|
|
27944
28031
|
}
|
|
27945
28032
|
mkdirSync3(dest, { recursive: true });
|
|
27946
28033
|
const { written, unavailable } = writeSliceFiles(dest, body.files);
|
|
28034
|
+
try {
|
|
28035
|
+
const { acknowledgeApprovedClaim: acknowledgeApprovedClaim2 } = await Promise.resolve().then(() => (init_approved_claims_badge(), approved_claims_badge_exports));
|
|
28036
|
+
const { readCacheEntry: readCacheEntry2, updateIndexCache: updateIndexCache2 } = await Promise.resolve().then(() => (init_cache_store(), cache_store_exports));
|
|
28037
|
+
updateIndexCache2({
|
|
28038
|
+
approvedClaims: acknowledgeApprovedClaim2(
|
|
28039
|
+
claim.approval.claimId,
|
|
28040
|
+
(readCacheEntry2() ?? {}).approvedClaims
|
|
28041
|
+
)
|
|
28042
|
+
});
|
|
28043
|
+
} catch {
|
|
28044
|
+
}
|
|
27947
28045
|
console.log(`
|
|
27948
28046
|
\u2713 Slice received: ${body.title ?? claim.title}`);
|
|
27949
28047
|
console.log(
|
|
@@ -28388,7 +28486,7 @@ async function cmdSubmit(id, flags = {}) {
|
|
|
28388
28486
|
const head = `${ghUser}:${claim.branch}`;
|
|
28389
28487
|
const title = flags.title || claim.title;
|
|
28390
28488
|
const noBody = Boolean(flags["no-body"]);
|
|
28391
|
-
const prBodyPath =
|
|
28489
|
+
const prBodyPath = join17(wt, "PR-BODY.md");
|
|
28392
28490
|
const bodySource = pickBodySource({
|
|
28393
28491
|
bodyFileFlag: flags["body-file"],
|
|
28394
28492
|
noBody,
|
|
@@ -28398,7 +28496,7 @@ async function cmdSubmit(id, flags = {}) {
|
|
|
28398
28496
|
let bodyDescr;
|
|
28399
28497
|
if (bodySource === "body-file") {
|
|
28400
28498
|
try {
|
|
28401
|
-
bodyText =
|
|
28499
|
+
bodyText = readFileSync11(flags["body-file"], "utf8");
|
|
28402
28500
|
} catch (err) {
|
|
28403
28501
|
console.error(
|
|
28404
28502
|
`terminalhire claim: could not read --body-file '${flags["body-file"]}': ${err.message ?? err}`
|
|
@@ -28407,7 +28505,7 @@ async function cmdSubmit(id, flags = {}) {
|
|
|
28407
28505
|
}
|
|
28408
28506
|
bodyDescr = `--body-file ${flags["body-file"]}`;
|
|
28409
28507
|
} else if (bodySource === "pr-body") {
|
|
28410
|
-
bodyText =
|
|
28508
|
+
bodyText = readFileSync11(prBodyPath, "utf8");
|
|
28411
28509
|
bodyDescr = "PR-BODY.md (auto-detected)";
|
|
28412
28510
|
} else {
|
|
28413
28511
|
bodyDescr = "(default: Closes + disclosure)";
|
|
@@ -28623,14 +28721,14 @@ function claimSleep(ms) {
|
|
|
28623
28721
|
}
|
|
28624
28722
|
function readClaimPushMarker() {
|
|
28625
28723
|
try {
|
|
28626
|
-
return existsSync8(CLAIM_PUSH_MARKER) ? JSON.parse(
|
|
28724
|
+
return existsSync8(CLAIM_PUSH_MARKER) ? JSON.parse(readFileSync11(CLAIM_PUSH_MARKER, "utf8")) : null;
|
|
28627
28725
|
} catch {
|
|
28628
28726
|
return null;
|
|
28629
28727
|
}
|
|
28630
28728
|
}
|
|
28631
28729
|
function writeClaimPushMarker(marker) {
|
|
28632
|
-
ensureStateDir(
|
|
28633
|
-
|
|
28730
|
+
ensureStateDir(TERMINALHIRE_DIR11);
|
|
28731
|
+
writeFileSync10(CLAIM_PUSH_MARKER, JSON.stringify(marker, null, 2) + "\n", "utf8");
|
|
28634
28732
|
}
|
|
28635
28733
|
function clearClaimPushMarker() {
|
|
28636
28734
|
try {
|
|
@@ -3517,6 +3517,7 @@ var claims_exports = {};
|
|
|
3517
3517
|
__export(claims_exports, {
|
|
3518
3518
|
PUSHED_CLAIM_FIELDS: () => PUSHED_CLAIM_FIELDS,
|
|
3519
3519
|
acceptedPRRate: () => acceptedPRRate,
|
|
3520
|
+
countAwaitingFounderApproval: () => countAwaitingFounderApproval,
|
|
3520
3521
|
findClaim: () => findClaim,
|
|
3521
3522
|
listClaims: () => listClaims,
|
|
3522
3523
|
nextPolledState: () => nextPolledState,
|
|
@@ -3698,6 +3699,15 @@ function removeClaimIfStakeMatches(id, expectedStakePostedAt) {
|
|
|
3698
3699
|
return true;
|
|
3699
3700
|
});
|
|
3700
3701
|
}
|
|
3702
|
+
function countAwaitingFounderApproval(claims = readClaims()) {
|
|
3703
|
+
try {
|
|
3704
|
+
return claims.filter(
|
|
3705
|
+
(c) => c.approval?.mode === "approval-only" && c.approval?.state === "pending"
|
|
3706
|
+
).length;
|
|
3707
|
+
} catch {
|
|
3708
|
+
return 0;
|
|
3709
|
+
}
|
|
3710
|
+
}
|
|
3701
3711
|
function acceptedPRRate(claims = readClaims()) {
|
|
3702
3712
|
const total = claims.length;
|
|
3703
3713
|
const merged = claims.filter((c) => c.state === "merged").length;
|