terminalhire 0.42.11 → 0.42.13
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/index-revalidate.js +138 -0
- package/dist/bin/jpi-bounties.js +179 -61
- package/dist/bin/jpi-claim.js +507 -43
- package/dist/bin/jpi-dispatch.js +680 -69
- package/dist/bin/jpi-hub.js +192 -62
- package/dist/bin/jpi-jobs.js +178 -59
- package/dist/bin/jpi-mcp.js +508 -44
- package/dist/bin/jpi-run.js +353 -28
- package/package.json +1 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// bin/index-revalidate.js
|
|
2
|
+
var PULSE_TIMEOUT_MS = 2e3;
|
|
3
|
+
var INDEX_TIMEOUT_WARM_MS = 5e3;
|
|
4
|
+
var INDEX_TIMEOUT_COLD_MS = 1e4;
|
|
5
|
+
function usableMember(member) {
|
|
6
|
+
return typeof member === "object" && member !== null && !Array.isArray(member) && Array.isArray(member.tags);
|
|
7
|
+
}
|
|
8
|
+
function usableIndex(index) {
|
|
9
|
+
if (!index || typeof index !== "object" || Array.isArray(index)) return false;
|
|
10
|
+
if (!Array.isArray(index.jobs) || !index.jobs.every(usableMember)) return false;
|
|
11
|
+
if (index.contribute !== void 0) {
|
|
12
|
+
if (!Array.isArray(index.contribute) || !index.contribute.every(usableMember)) return false;
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
function deadlineFetch(fetchImpl, url, { headers, timeoutMs }) {
|
|
17
|
+
const controller = new AbortController();
|
|
18
|
+
const timer = setTimeout(() => controller.abort(new Error("deadline exceeded")), timeoutMs);
|
|
19
|
+
timer.unref?.();
|
|
20
|
+
const promise = Promise.resolve(fetchImpl(url, { headers, signal: controller.signal })).finally(
|
|
21
|
+
() => clearTimeout(timer)
|
|
22
|
+
);
|
|
23
|
+
return { promise, abort: () => controller.abort(new Error("superseded")) };
|
|
24
|
+
}
|
|
25
|
+
function cacheFallbackNotice(source, cachedAt, now = Date.now()) {
|
|
26
|
+
if (source !== "cache-fallback") return null;
|
|
27
|
+
const base = "terminalhire: could not refresh the list \u2014 showing cached results";
|
|
28
|
+
if (typeof cachedAt !== "number" || !Number.isFinite(cachedAt)) return `${base}.`;
|
|
29
|
+
const minutes = Math.floor(Math.max(0, now - cachedAt) / 6e4);
|
|
30
|
+
if (minutes < 1) return `${base} from moments ago.`;
|
|
31
|
+
if (minutes < 60) return `${base} from ${minutes}m ago.`;
|
|
32
|
+
const hours = Math.floor(minutes / 60);
|
|
33
|
+
return `${base} from ${hours}h ago.`;
|
|
34
|
+
}
|
|
35
|
+
async function revalidateIndex({
|
|
36
|
+
apiUrl,
|
|
37
|
+
fetchImpl,
|
|
38
|
+
readEntry,
|
|
39
|
+
writeEntry,
|
|
40
|
+
pulseTimeoutMs = PULSE_TIMEOUT_MS,
|
|
41
|
+
indexTimeoutWarmMs = INDEX_TIMEOUT_WARM_MS,
|
|
42
|
+
indexTimeoutColdMs = INDEX_TIMEOUT_COLD_MS
|
|
43
|
+
}) {
|
|
44
|
+
let entry = {};
|
|
45
|
+
try {
|
|
46
|
+
entry = readEntry() ?? {};
|
|
47
|
+
} catch {
|
|
48
|
+
}
|
|
49
|
+
const cached = usableIndex(entry.index) ? entry.index : null;
|
|
50
|
+
const cachedAt = cached && typeof entry.ts === "number" ? entry.ts : null;
|
|
51
|
+
const indexTimeoutMs = cached ? indexTimeoutWarmMs : indexTimeoutColdMs;
|
|
52
|
+
const headers = { Accept: "application/json" };
|
|
53
|
+
if (cached && typeof entry.indexETag === "string" && entry.indexETag !== "") {
|
|
54
|
+
headers["If-None-Match"] = entry.indexETag;
|
|
55
|
+
}
|
|
56
|
+
const pulseCall = deadlineFetch(fetchImpl, `${apiUrl}/api/pulse`, {
|
|
57
|
+
headers: { Accept: "application/json" },
|
|
58
|
+
timeoutMs: pulseTimeoutMs
|
|
59
|
+
});
|
|
60
|
+
const speculative = deadlineFetch(fetchImpl, `${apiUrl}/api/index`, {
|
|
61
|
+
headers,
|
|
62
|
+
timeoutMs: indexTimeoutMs
|
|
63
|
+
});
|
|
64
|
+
const speculativeSettled = speculative.promise.then(
|
|
65
|
+
(res2) => ({ ok: true, res: res2 }),
|
|
66
|
+
(err) => ({ ok: false, err })
|
|
67
|
+
);
|
|
68
|
+
let latestPostedAt = null;
|
|
69
|
+
try {
|
|
70
|
+
const res2 = await pulseCall.promise;
|
|
71
|
+
if (res2.ok) {
|
|
72
|
+
const pulse = await res2.json();
|
|
73
|
+
latestPostedAt = pulse?.latestPostedAt ?? null;
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
const bust = latestPostedAt !== null && entry.latestPostedAt !== latestPostedAt;
|
|
78
|
+
let outcome;
|
|
79
|
+
let reachedOrigin = false;
|
|
80
|
+
if (bust) {
|
|
81
|
+
speculative.abort();
|
|
82
|
+
const bustCall = deadlineFetch(fetchImpl, `${apiUrl}/api/index`, {
|
|
83
|
+
// `no-cache` forces revalidation against the origin; the validator rides along
|
|
84
|
+
// so a genuinely unchanged body still costs a 304 rather than a full download.
|
|
85
|
+
headers: { ...headers, "Cache-Control": "no-cache" },
|
|
86
|
+
timeoutMs: indexTimeoutMs
|
|
87
|
+
});
|
|
88
|
+
try {
|
|
89
|
+
outcome = { ok: true, res: await bustCall.promise };
|
|
90
|
+
reachedOrigin = true;
|
|
91
|
+
} catch (err) {
|
|
92
|
+
const spec = await speculativeSettled;
|
|
93
|
+
outcome = spec.ok ? spec : { ok: false, err };
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
outcome = await speculativeSettled;
|
|
97
|
+
}
|
|
98
|
+
const fellBack = (reason) => cached ? { index: cached, source: "cache-fallback", reason, cachedAt } : { index: null, source: "none", reason, cachedAt };
|
|
99
|
+
if (!outcome.ok) {
|
|
100
|
+
const err = outcome.err;
|
|
101
|
+
return fellBack(err instanceof Error ? err.message : String(err));
|
|
102
|
+
}
|
|
103
|
+
const res = outcome.res;
|
|
104
|
+
try {
|
|
105
|
+
if (res.status === 304 && cached) {
|
|
106
|
+
if (reachedOrigin && latestPostedAt && latestPostedAt !== entry.latestPostedAt) {
|
|
107
|
+
try {
|
|
108
|
+
writeEntry({ latestPostedAt });
|
|
109
|
+
} catch {
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { index: cached, source: "cache-304", reason: null, cachedAt };
|
|
113
|
+
}
|
|
114
|
+
if (!res.ok) {
|
|
115
|
+
return fellBack(`/api/index returned ${res.status}`);
|
|
116
|
+
}
|
|
117
|
+
const body = await res.json();
|
|
118
|
+
if (!usableIndex(body)) {
|
|
119
|
+
return fellBack("/api/index returned a body that will not render");
|
|
120
|
+
}
|
|
121
|
+
const patch = { index: body, indexETag: res.headers.get("etag") ?? "" };
|
|
122
|
+
if (reachedOrigin && latestPostedAt) patch.latestPostedAt = latestPostedAt;
|
|
123
|
+
try {
|
|
124
|
+
writeEntry(patch);
|
|
125
|
+
} catch {
|
|
126
|
+
}
|
|
127
|
+
return { index: body, source: "fresh", reason: null, cachedAt };
|
|
128
|
+
} catch (err) {
|
|
129
|
+
return fellBack(err instanceof Error ? err.message : String(err));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export {
|
|
133
|
+
INDEX_TIMEOUT_COLD_MS,
|
|
134
|
+
INDEX_TIMEOUT_WARM_MS,
|
|
135
|
+
PULSE_TIMEOUT_MS,
|
|
136
|
+
cacheFallbackNotice,
|
|
137
|
+
revalidateIndex
|
|
138
|
+
};
|
package/dist/bin/jpi-bounties.js
CHANGED
|
@@ -10550,52 +10550,6 @@ var init_state_dir = __esm({
|
|
|
10550
10550
|
}
|
|
10551
10551
|
});
|
|
10552
10552
|
|
|
10553
|
-
// bin/cache-store.js
|
|
10554
|
-
var cache_store_exports = {};
|
|
10555
|
-
__export(cache_store_exports, {
|
|
10556
|
-
readCacheEntry: () => readCacheEntry,
|
|
10557
|
-
updateIndexCache: () => updateIndexCache,
|
|
10558
|
-
writeIndexCache: () => writeIndexCache
|
|
10559
|
-
});
|
|
10560
|
-
import { readFileSync as readFileSync2, writeFileSync, renameSync } from "fs";
|
|
10561
|
-
import { join as join2 } from "path";
|
|
10562
|
-
import { homedir } from "os";
|
|
10563
|
-
function readCacheEntry() {
|
|
10564
|
-
try {
|
|
10565
|
-
return JSON.parse(readFileSync2(INDEX_CACHE_FILE, "utf8"));
|
|
10566
|
-
} catch {
|
|
10567
|
-
return null;
|
|
10568
|
-
}
|
|
10569
|
-
}
|
|
10570
|
-
function updateIndexCache(patch) {
|
|
10571
|
-
ensureStateDir(TERMINALHIRE_DIR);
|
|
10572
|
-
const existing = readCacheEntry() ?? {};
|
|
10573
|
-
const entry = {
|
|
10574
|
-
...existing,
|
|
10575
|
-
...patch,
|
|
10576
|
-
schemaVersion: SCHEMA_VERSION2,
|
|
10577
|
-
ts: Date.now()
|
|
10578
|
-
};
|
|
10579
|
-
const tmp = `${INDEX_CACHE_FILE}.${process.pid}.${tmpCounter++}.tmp`;
|
|
10580
|
-
writeFileSync(tmp, JSON.stringify(entry), "utf8");
|
|
10581
|
-
renameSync(tmp, INDEX_CACHE_FILE);
|
|
10582
|
-
return entry;
|
|
10583
|
-
}
|
|
10584
|
-
function writeIndexCache(index) {
|
|
10585
|
-
return updateIndexCache({ index, indexETag: "" });
|
|
10586
|
-
}
|
|
10587
|
-
var TERMINALHIRE_DIR, INDEX_CACHE_FILE, SCHEMA_VERSION2, tmpCounter;
|
|
10588
|
-
var init_cache_store = __esm({
|
|
10589
|
-
"bin/cache-store.js"() {
|
|
10590
|
-
"use strict";
|
|
10591
|
-
init_state_dir();
|
|
10592
|
-
TERMINALHIRE_DIR = process.env.TERMINALHIRE_DIR || join2(homedir(), ".terminalhire");
|
|
10593
|
-
INDEX_CACHE_FILE = join2(TERMINALHIRE_DIR, "index-cache.json");
|
|
10594
|
-
SCHEMA_VERSION2 = 1;
|
|
10595
|
-
tmpCounter = 0;
|
|
10596
|
-
}
|
|
10597
|
-
});
|
|
10598
|
-
|
|
10599
10553
|
// bin/founder-pin.js
|
|
10600
10554
|
function isPinnedFounderBounty(j) {
|
|
10601
10555
|
return j?.bounty?.bountySource === "founder" && j?.bounty?.claimable === true;
|
|
@@ -12021,8 +11975,168 @@ function formatCents(cents) {
|
|
|
12021
11975
|
return cents % 100 === 0 ? `$${cents / 100}` : `$${(cents / 100).toFixed(2)}`;
|
|
12022
11976
|
}
|
|
12023
11977
|
|
|
12024
|
-
// bin/
|
|
12025
|
-
|
|
11978
|
+
// bin/cache-store.js
|
|
11979
|
+
init_state_dir();
|
|
11980
|
+
import { readFileSync as readFileSync2, writeFileSync, renameSync } from "fs";
|
|
11981
|
+
import { join as join2 } from "path";
|
|
11982
|
+
import { homedir } from "os";
|
|
11983
|
+
var TERMINALHIRE_DIR = process.env.TERMINALHIRE_DIR || join2(homedir(), ".terminalhire");
|
|
11984
|
+
var INDEX_CACHE_FILE = join2(TERMINALHIRE_DIR, "index-cache.json");
|
|
11985
|
+
var SCHEMA_VERSION2 = 1;
|
|
11986
|
+
var tmpCounter = 0;
|
|
11987
|
+
function readCacheEntry() {
|
|
11988
|
+
try {
|
|
11989
|
+
return JSON.parse(readFileSync2(INDEX_CACHE_FILE, "utf8"));
|
|
11990
|
+
} catch {
|
|
11991
|
+
return null;
|
|
11992
|
+
}
|
|
11993
|
+
}
|
|
11994
|
+
function updateIndexCache(patch) {
|
|
11995
|
+
ensureStateDir(TERMINALHIRE_DIR);
|
|
11996
|
+
const existing = readCacheEntry() ?? {};
|
|
11997
|
+
const entry = {
|
|
11998
|
+
...existing,
|
|
11999
|
+
...patch,
|
|
12000
|
+
schemaVersion: SCHEMA_VERSION2,
|
|
12001
|
+
ts: Date.now()
|
|
12002
|
+
};
|
|
12003
|
+
const tmp = `${INDEX_CACHE_FILE}.${process.pid}.${tmpCounter++}.tmp`;
|
|
12004
|
+
writeFileSync(tmp, JSON.stringify(entry), "utf8");
|
|
12005
|
+
renameSync(tmp, INDEX_CACHE_FILE);
|
|
12006
|
+
return entry;
|
|
12007
|
+
}
|
|
12008
|
+
|
|
12009
|
+
// bin/index-revalidate.js
|
|
12010
|
+
var PULSE_TIMEOUT_MS = 2e3;
|
|
12011
|
+
var INDEX_TIMEOUT_WARM_MS = 5e3;
|
|
12012
|
+
var INDEX_TIMEOUT_COLD_MS = 1e4;
|
|
12013
|
+
function usableMember(member) {
|
|
12014
|
+
return typeof member === "object" && member !== null && !Array.isArray(member) && Array.isArray(member.tags);
|
|
12015
|
+
}
|
|
12016
|
+
function usableIndex(index) {
|
|
12017
|
+
if (!index || typeof index !== "object" || Array.isArray(index)) return false;
|
|
12018
|
+
if (!Array.isArray(index.jobs) || !index.jobs.every(usableMember)) return false;
|
|
12019
|
+
if (index.contribute !== void 0) {
|
|
12020
|
+
if (!Array.isArray(index.contribute) || !index.contribute.every(usableMember)) return false;
|
|
12021
|
+
}
|
|
12022
|
+
return true;
|
|
12023
|
+
}
|
|
12024
|
+
function deadlineFetch(fetchImpl, url, { headers, timeoutMs }) {
|
|
12025
|
+
const controller = new AbortController();
|
|
12026
|
+
const timer = setTimeout(() => controller.abort(new Error("deadline exceeded")), timeoutMs);
|
|
12027
|
+
timer.unref?.();
|
|
12028
|
+
const promise = Promise.resolve(fetchImpl(url, { headers, signal: controller.signal })).finally(
|
|
12029
|
+
() => clearTimeout(timer)
|
|
12030
|
+
);
|
|
12031
|
+
return { promise, abort: () => controller.abort(new Error("superseded")) };
|
|
12032
|
+
}
|
|
12033
|
+
function cacheFallbackNotice(source, cachedAt, now = Date.now()) {
|
|
12034
|
+
if (source !== "cache-fallback") return null;
|
|
12035
|
+
const base = "terminalhire: could not refresh the list \u2014 showing cached results";
|
|
12036
|
+
if (typeof cachedAt !== "number" || !Number.isFinite(cachedAt)) return `${base}.`;
|
|
12037
|
+
const minutes = Math.floor(Math.max(0, now - cachedAt) / 6e4);
|
|
12038
|
+
if (minutes < 1) return `${base} from moments ago.`;
|
|
12039
|
+
if (minutes < 60) return `${base} from ${minutes}m ago.`;
|
|
12040
|
+
const hours = Math.floor(minutes / 60);
|
|
12041
|
+
return `${base} from ${hours}h ago.`;
|
|
12042
|
+
}
|
|
12043
|
+
async function revalidateIndex({
|
|
12044
|
+
apiUrl,
|
|
12045
|
+
fetchImpl,
|
|
12046
|
+
readEntry,
|
|
12047
|
+
writeEntry,
|
|
12048
|
+
pulseTimeoutMs = PULSE_TIMEOUT_MS,
|
|
12049
|
+
indexTimeoutWarmMs = INDEX_TIMEOUT_WARM_MS,
|
|
12050
|
+
indexTimeoutColdMs = INDEX_TIMEOUT_COLD_MS
|
|
12051
|
+
}) {
|
|
12052
|
+
let entry = {};
|
|
12053
|
+
try {
|
|
12054
|
+
entry = readEntry() ?? {};
|
|
12055
|
+
} catch {
|
|
12056
|
+
}
|
|
12057
|
+
const cached = usableIndex(entry.index) ? entry.index : null;
|
|
12058
|
+
const cachedAt = cached && typeof entry.ts === "number" ? entry.ts : null;
|
|
12059
|
+
const indexTimeoutMs = cached ? indexTimeoutWarmMs : indexTimeoutColdMs;
|
|
12060
|
+
const headers = { Accept: "application/json" };
|
|
12061
|
+
if (cached && typeof entry.indexETag === "string" && entry.indexETag !== "") {
|
|
12062
|
+
headers["If-None-Match"] = entry.indexETag;
|
|
12063
|
+
}
|
|
12064
|
+
const pulseCall = deadlineFetch(fetchImpl, `${apiUrl}/api/pulse`, {
|
|
12065
|
+
headers: { Accept: "application/json" },
|
|
12066
|
+
timeoutMs: pulseTimeoutMs
|
|
12067
|
+
});
|
|
12068
|
+
const speculative = deadlineFetch(fetchImpl, `${apiUrl}/api/index`, {
|
|
12069
|
+
headers,
|
|
12070
|
+
timeoutMs: indexTimeoutMs
|
|
12071
|
+
});
|
|
12072
|
+
const speculativeSettled = speculative.promise.then(
|
|
12073
|
+
(res2) => ({ ok: true, res: res2 }),
|
|
12074
|
+
(err) => ({ ok: false, err })
|
|
12075
|
+
);
|
|
12076
|
+
let latestPostedAt = null;
|
|
12077
|
+
try {
|
|
12078
|
+
const res2 = await pulseCall.promise;
|
|
12079
|
+
if (res2.ok) {
|
|
12080
|
+
const pulse = await res2.json();
|
|
12081
|
+
latestPostedAt = pulse?.latestPostedAt ?? null;
|
|
12082
|
+
}
|
|
12083
|
+
} catch {
|
|
12084
|
+
}
|
|
12085
|
+
const bust = latestPostedAt !== null && entry.latestPostedAt !== latestPostedAt;
|
|
12086
|
+
let outcome;
|
|
12087
|
+
let reachedOrigin = false;
|
|
12088
|
+
if (bust) {
|
|
12089
|
+
speculative.abort();
|
|
12090
|
+
const bustCall = deadlineFetch(fetchImpl, `${apiUrl}/api/index`, {
|
|
12091
|
+
// `no-cache` forces revalidation against the origin; the validator rides along
|
|
12092
|
+
// so a genuinely unchanged body still costs a 304 rather than a full download.
|
|
12093
|
+
headers: { ...headers, "Cache-Control": "no-cache" },
|
|
12094
|
+
timeoutMs: indexTimeoutMs
|
|
12095
|
+
});
|
|
12096
|
+
try {
|
|
12097
|
+
outcome = { ok: true, res: await bustCall.promise };
|
|
12098
|
+
reachedOrigin = true;
|
|
12099
|
+
} catch (err) {
|
|
12100
|
+
const spec = await speculativeSettled;
|
|
12101
|
+
outcome = spec.ok ? spec : { ok: false, err };
|
|
12102
|
+
}
|
|
12103
|
+
} else {
|
|
12104
|
+
outcome = await speculativeSettled;
|
|
12105
|
+
}
|
|
12106
|
+
const fellBack = (reason) => cached ? { index: cached, source: "cache-fallback", reason, cachedAt } : { index: null, source: "none", reason, cachedAt };
|
|
12107
|
+
if (!outcome.ok) {
|
|
12108
|
+
const err = outcome.err;
|
|
12109
|
+
return fellBack(err instanceof Error ? err.message : String(err));
|
|
12110
|
+
}
|
|
12111
|
+
const res = outcome.res;
|
|
12112
|
+
try {
|
|
12113
|
+
if (res.status === 304 && cached) {
|
|
12114
|
+
if (reachedOrigin && latestPostedAt && latestPostedAt !== entry.latestPostedAt) {
|
|
12115
|
+
try {
|
|
12116
|
+
writeEntry({ latestPostedAt });
|
|
12117
|
+
} catch {
|
|
12118
|
+
}
|
|
12119
|
+
}
|
|
12120
|
+
return { index: cached, source: "cache-304", reason: null, cachedAt };
|
|
12121
|
+
}
|
|
12122
|
+
if (!res.ok) {
|
|
12123
|
+
return fellBack(`/api/index returned ${res.status}`);
|
|
12124
|
+
}
|
|
12125
|
+
const body = await res.json();
|
|
12126
|
+
if (!usableIndex(body)) {
|
|
12127
|
+
return fellBack("/api/index returned a body that will not render");
|
|
12128
|
+
}
|
|
12129
|
+
const patch = { index: body, indexETag: res.headers.get("etag") ?? "" };
|
|
12130
|
+
if (reachedOrigin && latestPostedAt) patch.latestPostedAt = latestPostedAt;
|
|
12131
|
+
try {
|
|
12132
|
+
writeEntry(patch);
|
|
12133
|
+
} catch {
|
|
12134
|
+
}
|
|
12135
|
+
return { index: body, source: "fresh", reason: null, cachedAt };
|
|
12136
|
+
} catch (err) {
|
|
12137
|
+
return fellBack(err instanceof Error ? err.message : String(err));
|
|
12138
|
+
}
|
|
12139
|
+
}
|
|
12026
12140
|
|
|
12027
12141
|
// bin/sanitize.js
|
|
12028
12142
|
var WHITESPACE_CONTROLS = /[\t\n\v\f\r]+/g;
|
|
@@ -12178,14 +12292,20 @@ function readIndexCache() {
|
|
|
12178
12292
|
return null;
|
|
12179
12293
|
}
|
|
12180
12294
|
}
|
|
12181
|
-
async function fetchIndex() {
|
|
12182
|
-
const
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12188
|
-
|
|
12295
|
+
async function fetchIndex(quiet = false) {
|
|
12296
|
+
const { index, reason, source, cachedAt } = await revalidateIndex({
|
|
12297
|
+
apiUrl: API_URL2,
|
|
12298
|
+
fetchImpl: (url, init) => fetch(url, init),
|
|
12299
|
+
readEntry: readCacheEntry,
|
|
12300
|
+
writeEntry: updateIndexCache
|
|
12301
|
+
});
|
|
12302
|
+
if (!quiet) {
|
|
12303
|
+
const notice = cacheFallbackNotice(source, cachedAt);
|
|
12304
|
+
if (notice) process.stderr.write(`${notice}
|
|
12305
|
+
`);
|
|
12306
|
+
}
|
|
12307
|
+
if (index) return index;
|
|
12308
|
+
throw new Error(reason ?? "/api/index returned no usable index");
|
|
12189
12309
|
}
|
|
12190
12310
|
function prompt2(question) {
|
|
12191
12311
|
const rl = createInterface2({ input: process.stdin, output: process.stdout });
|
|
@@ -12326,7 +12446,7 @@ function classifyEmptyStatus({ preFilterCount, postFilterCount, priced }) {
|
|
|
12326
12446
|
}
|
|
12327
12447
|
async function getBounties({ quiet = false, offline = false, priced = PRICED_ONLY } = {}) {
|
|
12328
12448
|
if (!quiet) console.log(`Fetching bounty index from ${API_URL2}/api/index...`);
|
|
12329
|
-
const index = offline ? readIndexCache() : await fetchIndex();
|
|
12449
|
+
const index = offline ? readIndexCache() : await fetchIndex(quiet);
|
|
12330
12450
|
if (offline && !index) return { status: "no-cache" };
|
|
12331
12451
|
let bounties = (index.jobs ?? []).filter((j) => j.source === "bounty");
|
|
12332
12452
|
if (PRICED_ONLY) bounties = bounties.filter((j) => j.bounty?.amountUSD != null);
|
|
@@ -12378,10 +12498,9 @@ async function run() {
|
|
|
12378
12498
|
try {
|
|
12379
12499
|
if (args.length === 0) {
|
|
12380
12500
|
try {
|
|
12381
|
-
const { readCacheEntry: readCacheEntry2 } = await Promise.resolve().then(() => (init_cache_store(), cache_store_exports));
|
|
12382
12501
|
const { getSurfaceLeadOverride: getSurfaceLeadOverride2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
12383
12502
|
const { founderRows: founderRows2, resolveSurfaceLead: resolveSurfaceLead2 } = await Promise.resolve().then(() => (init_founder_surface(), founder_surface_exports));
|
|
12384
|
-
const surface = (
|
|
12503
|
+
const surface = (readCacheEntry() ?? {}).founderSurface;
|
|
12385
12504
|
if (resolveSurfaceLead2(getSurfaceLeadOverride2(), surface) === "founder") {
|
|
12386
12505
|
const rows = founderRows2(surface, "bounties");
|
|
12387
12506
|
console.log("\n\u26A1 Your TerminalHire postings\n");
|
|
@@ -12449,12 +12568,11 @@ async function run() {
|
|
|
12449
12568
|
}
|
|
12450
12569
|
try {
|
|
12451
12570
|
const { acknowledgeFounderPaid: acknowledgeFounderPaid2 } = await Promise.resolve().then(() => (init_founder_paid_badge(), founder_paid_badge_exports));
|
|
12452
|
-
const { readCacheEntry: readCacheEntry2 } = await Promise.resolve().then(() => (init_cache_store(), cache_store_exports));
|
|
12453
12571
|
updateIndexCache({
|
|
12454
12572
|
founderPaid: acknowledgeFounderPaid2({
|
|
12455
12573
|
shown,
|
|
12456
12574
|
open: bounties,
|
|
12457
|
-
previous: (
|
|
12575
|
+
previous: (readCacheEntry() ?? {}).founderPaid
|
|
12458
12576
|
})
|
|
12459
12577
|
});
|
|
12460
12578
|
} catch {
|