terminalhire 0.26.0 → 0.26.2

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.
@@ -1226,6 +1226,187 @@ var init_rigor = __esm({
1226
1226
  }
1227
1227
  });
1228
1228
 
1229
+ // ../../packages/core/src/gh-governor.ts
1230
+ function readReqGapMs() {
1231
+ const raw = process.env["CONTRIB_REQ_GAP_MS"];
1232
+ if (raw == null) return DEFAULT_REQ_GAP_MS;
1233
+ const n = Number.parseInt(raw, 10);
1234
+ if (Number.isNaN(n)) return DEFAULT_REQ_GAP_MS;
1235
+ return Math.min(Math.max(n, 0), 1e3);
1236
+ }
1237
+ function readBuildBudgetMs() {
1238
+ const raw = process.env["CONTRIB_BUILD_BUDGET_MS"];
1239
+ if (raw == null) return DEFAULT_BUILD_BUDGET_MS;
1240
+ const n = Number.parseInt(raw, 10);
1241
+ if (Number.isNaN(n)) return DEFAULT_BUILD_BUDGET_MS;
1242
+ return Math.min(Math.max(n, MIN_BUILD_BUDGET_MS), MAX_BUILD_BUDGET_MS);
1243
+ }
1244
+ function makeDefaultGovernorConfig(o) {
1245
+ return {
1246
+ paceEnabled: o.paceEnabled,
1247
+ gapMs: readReqGapMs(),
1248
+ budgetMs: readBuildBudgetMs(),
1249
+ sleep: o.sleep ?? realSleep,
1250
+ now: o.now ?? Date.now,
1251
+ probeTimeoutMs: o.probeTimeoutMs ?? (o.paceEnabled ? PROBE_TIMEOUT_MS : null)
1252
+ };
1253
+ }
1254
+ function makeGitHubGovernor(fetchImpl, cfg) {
1255
+ const startedAt = cfg.now();
1256
+ let lastRequestAt = 0;
1257
+ let pacedMs = 0;
1258
+ let secondaryHits = 0;
1259
+ let aborted = false;
1260
+ let secondaryAborted = false;
1261
+ let budgetAborted = false;
1262
+ let gqlCost = 0;
1263
+ let gqlRemaining = null;
1264
+ let coreHealthyAtStart = false;
1265
+ async function noteAndMaybeBackOff(res) {
1266
+ if (res.status !== 403) return;
1267
+ const remaining = res.headers.get("x-ratelimit-remaining");
1268
+ const retryAfter = res.headers.get("retry-after");
1269
+ const positiveSecondary = retryAfter != null || remaining != null && remaining !== "0";
1270
+ const isSecondary = positiveSecondary || coreHealthyAtStart;
1271
+ if (!isSecondary) return;
1272
+ await recordSecondaryStrike(retryAfter);
1273
+ }
1274
+ async function recordSecondaryStrike(retryAfter) {
1275
+ secondaryHits++;
1276
+ if (secondaryHits >= 2) {
1277
+ aborted = true;
1278
+ secondaryAborted = true;
1279
+ return;
1280
+ }
1281
+ if (cfg.paceEnabled) {
1282
+ const trimmed = (retryAfter ?? "").trim();
1283
+ const parsed = trimmed.length === 0 ? Number.NaN : Number(trimmed);
1284
+ const sec = Number.isNaN(parsed) ? SECONDARY_BACKOFF_CAP_S : Math.min(Math.max(parsed, 0), SECONDARY_BACKOFF_CAP_S);
1285
+ const remainingBudget = Math.max(0, cfg.budgetMs - (cfg.now() - startedAt));
1286
+ await cfg.sleep(Math.min(sec * 1e3, remainingBudget));
1287
+ }
1288
+ }
1289
+ async function noteGraphQLAndMaybeBackOff(res, body) {
1290
+ const b = body ?? {};
1291
+ const rl = b.data?.rateLimit;
1292
+ if (rl) {
1293
+ if (typeof rl.cost === "number") gqlCost += rl.cost;
1294
+ if (typeof rl.remaining === "number") gqlRemaining = rl.remaining;
1295
+ }
1296
+ const remainingHdr = res.headers?.get("x-ratelimit-remaining") ?? null;
1297
+ const retryAfter = res.headers?.get("retry-after") ?? null;
1298
+ const headerRate = retryAfter != null || remainingHdr === "0";
1299
+ const errs = Array.isArray(b.errors) ? b.errors : [];
1300
+ const bodyRate = errs.some((e) => e?.type === "RATE_LIMITED" || /rate limit/i.test(String(e?.message ?? ""))) || typeof rl?.remaining === "number" && rl.remaining <= 0;
1301
+ if (headerRate || bodyRate) await recordSecondaryStrike(retryAfter);
1302
+ }
1303
+ async function preflight() {
1304
+ if (aborted) return false;
1305
+ if (cfg.now() - startedAt >= cfg.budgetMs) {
1306
+ aborted = true;
1307
+ budgetAborted = true;
1308
+ return false;
1309
+ }
1310
+ if (cfg.paceEnabled && cfg.gapMs > 0) {
1311
+ const wait = cfg.gapMs - (cfg.now() - lastRequestAt);
1312
+ if (wait > 0) {
1313
+ await cfg.sleep(wait);
1314
+ pacedMs += wait;
1315
+ if (cfg.now() - startedAt >= cfg.budgetMs) {
1316
+ aborted = true;
1317
+ budgetAborted = true;
1318
+ return false;
1319
+ }
1320
+ }
1321
+ lastRequestAt = cfg.now();
1322
+ }
1323
+ return true;
1324
+ }
1325
+ async function get(url, init) {
1326
+ if (!await preflight()) return null;
1327
+ try {
1328
+ const res = await fetchImpl(url, init);
1329
+ await noteAndMaybeBackOff(res);
1330
+ return res;
1331
+ } catch {
1332
+ return null;
1333
+ }
1334
+ }
1335
+ async function graphql(url, init) {
1336
+ if (!await preflight()) return null;
1337
+ let res;
1338
+ try {
1339
+ res = await fetchImpl(url, init);
1340
+ } catch {
1341
+ return null;
1342
+ }
1343
+ let body;
1344
+ try {
1345
+ body = await res.json();
1346
+ } catch {
1347
+ return null;
1348
+ }
1349
+ await noteGraphQLAndMaybeBackOff(res, body);
1350
+ if (!res.ok) return null;
1351
+ return body;
1352
+ }
1353
+ async function probe(url, init) {
1354
+ const bound = cfg.probeTimeoutMs;
1355
+ let timer;
1356
+ const fetchP = fetchImpl(url, init).then(
1357
+ (r) => r,
1358
+ () => null
1359
+ );
1360
+ try {
1361
+ const res = bound == null ? await fetchP : await Promise.race([
1362
+ fetchP,
1363
+ new Promise((resolve) => {
1364
+ timer = setTimeout(() => resolve(null), bound);
1365
+ })
1366
+ ]);
1367
+ if (!res || !res.ok) return null;
1368
+ return await res.json();
1369
+ } catch {
1370
+ return null;
1371
+ } finally {
1372
+ if (timer) clearTimeout(timer);
1373
+ }
1374
+ }
1375
+ function setSecondaryHint(coreHealthy) {
1376
+ coreHealthyAtStart = coreHealthy;
1377
+ }
1378
+ function getStats() {
1379
+ return {
1380
+ pacedMs,
1381
+ secondaryAborted: secondaryAborted ? 1 : 0,
1382
+ budgetAborted: budgetAborted ? 1 : 0,
1383
+ elapsedMs: cfg.now() - startedAt,
1384
+ gqlCost,
1385
+ gqlRemaining
1386
+ };
1387
+ }
1388
+ function tripped() {
1389
+ return secondaryAborted;
1390
+ }
1391
+ function budgetExhausted() {
1392
+ return budgetAborted || cfg.now() - startedAt >= cfg.budgetMs;
1393
+ }
1394
+ return { get, graphql, probe, setSecondaryHint, getStats, tripped, budgetExhausted };
1395
+ }
1396
+ var DEFAULT_REQ_GAP_MS, SECONDARY_BACKOFF_CAP_S, DEFAULT_BUILD_BUDGET_MS, MIN_BUILD_BUDGET_MS, MAX_BUILD_BUDGET_MS, PROBE_TIMEOUT_MS, realSleep;
1397
+ var init_gh_governor = __esm({
1398
+ "../../packages/core/src/gh-governor.ts"() {
1399
+ "use strict";
1400
+ DEFAULT_REQ_GAP_MS = 75;
1401
+ SECONDARY_BACKOFF_CAP_S = 30;
1402
+ DEFAULT_BUILD_BUDGET_MS = 9e4;
1403
+ MIN_BUILD_BUDGET_MS = 1e4;
1404
+ MAX_BUILD_BUDGET_MS = 9e4;
1405
+ PROBE_TIMEOUT_MS = 3e3;
1406
+ realSleep = (ms) => new Promise((r) => setTimeout(r, ms));
1407
+ }
1408
+ });
1409
+
1229
1410
  // ../../packages/core/src/github.ts
1230
1411
  function ghHeaders(token) {
1231
1412
  const headers = {
@@ -1706,11 +1887,9 @@ async function fetchRepoReceptivity(fullName, opts = {}) {
1706
1887
  const doFetch = opts.fetchImpl ?? fetch;
1707
1888
  const now = opts.now ?? Date.now();
1708
1889
  try {
1709
- const res = await doFetch(
1710
- `https://api.github.com/repos/${fullName}/pulls?state=closed&per_page=50&sort=updated&direction=desc`,
1711
- { headers: ghHeaders(opts.token) }
1712
- );
1713
- if (!res.ok) return null;
1890
+ const url = `https://api.github.com/repos/${fullName}/pulls?state=closed&per_page=50&sort=updated&direction=desc`;
1891
+ const res = opts.governor ? await opts.governor.get(url, { headers: ghHeaders(opts.token) }) : await doFetch(url, { headers: ghHeaders(opts.token) });
1892
+ if (!res || !res.ok) return null;
1714
1893
  const prs = await res.json();
1715
1894
  if (!Array.isArray(prs)) return null;
1716
1895
  const external = prs.filter(isExternalAuthor);
@@ -1795,25 +1974,34 @@ function parseGitHubRef(url) {
1795
1974
  if (!m) return null;
1796
1975
  return { owner: m[1], repo: m[2], number: parseInt(m[4], 10), kind: m[3] === "pull" ? "pull" : "issue" };
1797
1976
  }
1798
- async function ghGraphQL(query, variables, token, signal) {
1799
- const res = await fetch("https://api.github.com/graphql", {
1977
+ async function ghGraphQL(query, variables, token, signal, governor) {
1978
+ const init = {
1800
1979
  method: "POST",
1801
1980
  headers: { ...ghHeaders(token), "Content-Type": "application/json" },
1802
1981
  body: JSON.stringify({ query, variables }),
1803
1982
  signal
1804
- });
1983
+ };
1984
+ if (governor) {
1985
+ const json2 = await governor.graphql(GITHUB_GRAPHQL_URL, init);
1986
+ if (json2 === null) return null;
1987
+ if (json2.errors?.length) throw new Error("GitHub GraphQL errors: " + JSON.stringify(json2.errors));
1988
+ return json2;
1989
+ }
1990
+ const res = await fetch(GITHUB_GRAPHQL_URL, init);
1805
1991
  if (!res.ok) throw new Error(`GitHub GraphQL: HTTP ${res.status}`);
1806
1992
  const json = await res.json();
1807
1993
  if (json.errors?.length) throw new Error("GitHub GraphQL errors: " + JSON.stringify(json.errors));
1808
1994
  return json;
1809
1995
  }
1810
- async function resolveClosingIssues(owner, name, number, body, token, signal) {
1996
+ async function resolveClosingIssues(owner, name, number, body, token, signal, governor) {
1811
1997
  if (token) {
1812
1998
  try {
1813
- const q = `query($o:String!,$n:String!,$p:Int!){repository(owner:$o,name:$n){pullRequest(number:$p){closingIssuesReferences(first:20){nodes{number}}}}}`;
1814
- const r = await ghGraphQL(q, { o: owner, n: name, p: number }, token, signal);
1815
- const nodes = r.data?.repository?.pullRequest?.closingIssuesReferences?.nodes ?? [];
1816
- return { closesIssues: nodes.map((x) => x.number), linkageSource: "graphql" };
1999
+ const q = `query($o:String!,$n:String!,$p:Int!){repository(owner:$o,name:$n){pullRequest(number:$p){closingIssuesReferences(first:20){nodes{number}}}}rateLimit{cost remaining}}`;
2000
+ const r = await ghGraphQL(q, { o: owner, n: name, p: number }, token, signal, governor);
2001
+ if (r) {
2002
+ const nodes = r.data?.repository?.pullRequest?.closingIssuesReferences?.nodes ?? [];
2003
+ return { closesIssues: nodes.map((x) => x.number), linkageSource: "graphql" };
2004
+ }
1817
2005
  } catch {
1818
2006
  }
1819
2007
  }
@@ -1823,11 +2011,19 @@ async function resolveClosingIssues(owner, name, number, body, token, signal) {
1823
2011
  while ((m = re.exec(body)) !== null) nums.add(parseInt(m[1], 10));
1824
2012
  return { closesIssues: [...nums], linkageSource: nums.size ? "body-keyword" : "none" };
1825
2013
  }
1826
- async function fetchPRScoringFacts(prUrl, token, signal) {
2014
+ function makeScoringGovernor(governor) {
2015
+ return governor ?? makeGitHubGovernor(
2016
+ ((url, init) => fetch(url, init)),
2017
+ makeDefaultGovernorConfig({ paceEnabled: false })
2018
+ );
2019
+ }
2020
+ async function fetchPRScoringFacts(prUrl, token, signal, governor) {
1827
2021
  const ref = parseGitHubRef(prUrl);
1828
2022
  if (!ref || ref.kind !== "pull") return null;
1829
2023
  const { owner, repo, number } = ref;
1830
2024
  const sig = signal ?? AbortSignal.timeout(1e4);
2025
+ const gov = makeScoringGovernor(governor);
2026
+ if (gov.tripped() || gov.budgetExhausted()) return null;
1831
2027
  let pr;
1832
2028
  try {
1833
2029
  pr = await ghFetch(`/repos/${owner}/${repo}/pulls/${number}`, token, sig);
@@ -1835,22 +2031,26 @@ async function fetchPRScoringFacts(prUrl, token, signal) {
1835
2031
  return null;
1836
2032
  }
1837
2033
  let repoMeta = null;
1838
- try {
1839
- repoMeta = await ghFetch(`/repos/${owner}/${repo}`, token, sig);
1840
- } catch {
2034
+ if (!gov.tripped() && !gov.budgetExhausted()) {
2035
+ try {
2036
+ repoMeta = await ghFetch(`/repos/${owner}/${repo}`, token, sig);
2037
+ } catch {
2038
+ }
1841
2039
  }
1842
- const contributors = await repoContributorCount(owner, repo, token, sig);
1843
- const { closesIssues, linkageSource } = await resolveClosingIssues(owner, repo, number, pr.body ?? "", token, sig);
2040
+ const contributors = gov.tripped() || gov.budgetExhausted() ? null : await repoContributorCount(owner, repo, token, sig);
2041
+ const { closesIssues, linkageSource } = await resolveClosingIssues(owner, repo, number, pr.body ?? "", token, sig, gov);
1844
2042
  let reviewerAssociations;
1845
- try {
1846
- const reviews = await ghFetch(
1847
- `/repos/${owner}/${repo}/pulls/${number}/reviews?per_page=100`,
1848
- token,
1849
- sig
1850
- );
1851
- reviewerAssociations = reviews.map((r) => r.author_association);
1852
- } catch {
1853
- reviewerAssociations = void 0;
2043
+ if (!gov.tripped() && !gov.budgetExhausted()) {
2044
+ try {
2045
+ const reviews = await ghFetch(
2046
+ `/repos/${owner}/${repo}/pulls/${number}/reviews?per_page=100`,
2047
+ token,
2048
+ sig
2049
+ );
2050
+ reviewerAssociations = reviews.map((r) => r.author_association);
2051
+ } catch {
2052
+ reviewerAssociations = void 0;
2053
+ }
1854
2054
  }
1855
2055
  return {
1856
2056
  repo: `${owner}/${repo}`,
@@ -1877,7 +2077,7 @@ async function fetchPRScoringFacts(prUrl, token, signal) {
1877
2077
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
1878
2078
  };
1879
2079
  }
1880
- var TRACTION_TOP_N, MAINTAINER_ENRICH_MAX, CANDIDATE_PR_PAGE, MAX_ENRICH_PRS, OPEN_PR_PAGE, TRANSIENT_META_ERROR, RESUME_DECAY_HALF_LIFE_MS, RESUME_MIN_SCORE, RECEPTIVITY_RECENCY_DAYS, RECEPTIVITY_RECENCY_FLOOR;
2080
+ var TRACTION_TOP_N, MAINTAINER_ENRICH_MAX, CANDIDATE_PR_PAGE, MAX_ENRICH_PRS, OPEN_PR_PAGE, TRANSIENT_META_ERROR, RESUME_DECAY_HALF_LIFE_MS, RESUME_MIN_SCORE, RECEPTIVITY_RECENCY_DAYS, RECEPTIVITY_RECENCY_FLOOR, GITHUB_GRAPHQL_URL;
1881
2081
  var init_github = __esm({
1882
2082
  "../../packages/core/src/github.ts"() {
1883
2083
  "use strict";
@@ -1885,6 +2085,7 @@ var init_github = __esm({
1885
2085
  init_contribution_gate();
1886
2086
  init_contribution_gate();
1887
2087
  init_rigor();
2088
+ init_gh_governor();
1888
2089
  TRACTION_TOP_N = 6;
1889
2090
  MAINTAINER_ENRICH_MAX = 25;
1890
2091
  CANDIDATE_PR_PAGE = 50;
@@ -1895,6 +2096,7 @@ var init_github = __esm({
1895
2096
  RESUME_MIN_SCORE = 0.05;
1896
2097
  RECEPTIVITY_RECENCY_DAYS = 180;
1897
2098
  RECEPTIVITY_RECENCY_FLOOR = 0.1;
2099
+ GITHUB_GRAPHQL_URL = "https://api.github.com/graphql";
1898
2100
  }
1899
2101
  });
1900
2102
 
@@ -1975,34 +2177,45 @@ function mergeSoftCoverage(covMap, softTags, cap) {
1975
2177
  }
1976
2178
  return covMap;
1977
2179
  }
2180
+ function tagKernel(job, ctx) {
2181
+ const { expanded, covMap, maxDevScore, skillTags } = ctx;
2182
+ const details = [];
2183
+ let jobMatchScore = 0;
2184
+ let jobMaxScore = 0;
2185
+ const devCovByTag = /* @__PURE__ */ new Map();
2186
+ for (const tag of job.tags) {
2187
+ const w = backgroundIdf(tag);
2188
+ jobMaxScore += w;
2189
+ const covHit = covMap.get(tag);
2190
+ if (covHit) jobMatchScore += w * Math.pow(covHit.weight, SHARPEN);
2191
+ const fpHit = expanded.get(tag);
2192
+ if (fpHit) {
2193
+ const credit = Math.pow(fpHit.weight, SHARPEN);
2194
+ details.push({ tag, weight: fpHit.weight, via: fpHit.via });
2195
+ if (credit > (devCovByTag.get(fpHit.via) ?? 0)) devCovByTag.set(fpHit.via, credit);
2196
+ }
2197
+ }
2198
+ let devScore = 0;
2199
+ for (const t of skillTags) devScore += backgroundIdf(t) * (devCovByTag.get(t) ?? 0);
2200
+ const devCov = maxDevScore > 0 ? Math.min(1, devScore / maxDevScore) : 0;
2201
+ const jobCov = jobMaxScore > 0 ? Math.min(1, jobMatchScore / jobMaxScore) : 0;
2202
+ return { tagComponent: harmonicMean(devCov, jobCov), details };
2203
+ }
2204
+ function relevanceScore(fp, job, softTags = []) {
2205
+ const expanded = expandWeighted(fp.skillTags);
2206
+ const covMap = softTags.length > 0 ? mergeSoftCoverage(new Map(expanded), softTags, INTEREST_CAP) : expanded;
2207
+ const maxDevScore = fp.skillTags.reduce((acc, t) => acc + backgroundIdf(t), 0);
2208
+ return tagKernel(job, { expanded, covMap, maxDevScore, skillTags: fp.skillTags }).tagComponent;
2209
+ }
1978
2210
  function match(fp, jobs, limit = 5, now = Date.now(), opts = {}) {
1979
2211
  const idfOf = backgroundIdf;
1980
2212
  const expanded = expandWeighted(fp.skillTags);
1981
2213
  const covMap = opts.softTags && opts.softTags.length > 0 ? mergeSoftCoverage(new Map(expanded), opts.softTags, INTEREST_CAP) : expanded;
1982
2214
  const maxDevScore = fp.skillTags.reduce((acc, t) => acc + idfOf(t), 0);
2215
+ const ctx = { expanded, covMap, maxDevScore, skillTags: fp.skillTags };
1983
2216
  const candidates = jobs.filter((j) => passesFilters(fp, j));
1984
2217
  const scored = candidates.map((job) => {
1985
- const details = [];
1986
- let jobMatchScore = 0;
1987
- let jobMaxScore = 0;
1988
- const devCovByTag = /* @__PURE__ */ new Map();
1989
- for (const tag of job.tags) {
1990
- const w = idfOf(tag);
1991
- jobMaxScore += w;
1992
- const covHit = covMap.get(tag);
1993
- if (covHit) jobMatchScore += w * Math.pow(covHit.weight, SHARPEN);
1994
- const fpHit = expanded.get(tag);
1995
- if (fpHit) {
1996
- const credit = Math.pow(fpHit.weight, SHARPEN);
1997
- details.push({ tag, weight: fpHit.weight, via: fpHit.via });
1998
- if (credit > (devCovByTag.get(fpHit.via) ?? 0)) devCovByTag.set(fpHit.via, credit);
1999
- }
2000
- }
2001
- let devScore = 0;
2002
- for (const t of fp.skillTags) devScore += idfOf(t) * (devCovByTag.get(t) ?? 0);
2003
- const devCov = maxDevScore > 0 ? Math.min(1, devScore / maxDevScore) : 0;
2004
- const jobCov = jobMaxScore > 0 ? Math.min(1, jobMatchScore / jobMaxScore) : 0;
2005
- const tagComponent = harmonicMean(devCov, jobCov);
2218
+ const { tagComponent, details } = tagKernel(job, ctx);
2006
2219
  if (tagComponent === 0) return null;
2007
2220
  const coreTags = job.coreTags ?? coreTagsFromTitle(job.title);
2008
2221
  let coreComponent = tagComponent;
@@ -3537,6 +3750,7 @@ function hasContentSignal(title, body, labels) {
3537
3750
  ${body}`;
3538
3751
  if (CONTENT_ADD_RE.test(text)) return true;
3539
3752
  if (ADD_TO_CORPUS_RE.test(text)) return true;
3753
+ if (NUMBERED_SEED_RE.test(title)) return true;
3540
3754
  if (TRANSLATE_RE.test(text)) return true;
3541
3755
  if (TYPO_RE.test(text)) return true;
3542
3756
  return false;
@@ -3552,7 +3766,7 @@ function classifyContributionKind(input) {
3552
3766
  function looksLikeContentTask(input) {
3553
3767
  return classifyContributionKind(input) === "content";
3554
3768
  }
3555
- var CONTENT_LABEL_RE, CODE_LABEL_RE, CODE_TERM_RE, CODE_EXCEPTION_RE, CODE_FENCE_RE, FILE_PATH_RE, CONTENT_ADD_RE, ADD_TO_CORPUS_RE, TRANSLATE_RE, TYPO_RE;
3769
+ var CONTENT_LABEL_RE, CODE_LABEL_RE, CODE_TERM_RE, CODE_EXCEPTION_RE, CODE_FENCE_RE, FILE_PATH_RE, CONTENT_NOUN_STRONG, CONTENT_NOUN_BROAD, CONTENT_ADD_RE, NUMBERED_SEED_RE, ADD_TO_CORPUS_RE, TRANSLATE_RE, TYPO_RE;
3556
3770
  var init_contribution_classify = __esm({
3557
3771
  "../../packages/core/src/feeds/contribution-classify.ts"() {
3558
3772
  "use strict";
@@ -3562,7 +3776,16 @@ var init_contribution_classify = __esm({
3562
3776
  CODE_EXCEPTION_RE = /exception|stacktrace|segfault|traceback/i;
3563
3777
  CODE_FENCE_RE = /```|(?:^|\n)\s{4,}\S/;
3564
3778
  FILE_PATH_RE = /\b[\w./-]+\.(?:ts|tsx|js|jsx|mjs|cjs|py|rb|go|rs|java|kt|scala|c|cc|cpp|cxx|h|hpp|cs|php|swift|m|mm|sh|bash|zsh|sql|graphql|proto|css|scss|sass|less|vue|svelte|toml|ini|gradle|dockerfile)\b/i;
3565
- CONTENT_ADD_RE = /\badd(?:ing|s)?\s+(?:\w+\s+){0,4}?(?:proverbs?|words?|phrases?|sayings?|quotes?|quotations?|translations?|entry|entries|definitions?|terms?|idioms?|synonyms?|antonyms?|acronyms?|abbreviations?)\b/i;
3779
+ CONTENT_NOUN_STRONG = String.raw`proverbs?|words?|phrases?|sayings?|quotes?|quotations?|translations?|entry|entries|definitions?|terms?|idioms?|synonyms?|antonyms?|acronyms?|abbreviations?`;
3780
+ CONTENT_NOUN_BROAD = String.raw`trivia\s+questions?|grammar\s+points?|trivia|facts?|quiz(?:zes)?|flash\s?cards?|vocab(?:ulary)?|lessons?|kanji`;
3781
+ CONTENT_ADD_RE = new RegExp(
3782
+ String.raw`\badd(?:ing|s)?\s+(?:\w+\s+){0,4}?(?:${CONTENT_NOUN_STRONG})\b`,
3783
+ "i"
3784
+ );
3785
+ NUMBERED_SEED_RE = new RegExp(
3786
+ String.raw`\badd(?:ing|s)?\s+(?:\w+\s+){0,4}?(?:${CONTENT_NOUN_STRONG}|${CONTENT_NOUN_BROAD})\s*#?\s*\d{1,3}\s*$`,
3787
+ "i"
3788
+ );
3566
3789
  ADD_TO_CORPUS_RE = /\badd\b[\s\S]*?\bto\s+(?:the\s+)?(?:word\s?list|dictionary|glossary|phrasebook)\b/i;
3567
3790
  TRANSLATE_RE = /\b(?:translate|translating|translation|localize|localise|localization|localisation)\b/i;
3568
3791
  TYPO_RE = /\bfix(?:ing)?\s+(?:a\s+|the\s+|some\s+)?typos?\b/i;
@@ -3570,20 +3793,6 @@ var init_contribution_classify = __esm({
3570
3793
  });
3571
3794
 
3572
3795
  // ../../packages/core/src/feeds/contributions.ts
3573
- function readReqGapMs() {
3574
- const raw = process.env["CONTRIB_REQ_GAP_MS"];
3575
- if (raw == null) return DEFAULT_REQ_GAP_MS;
3576
- const n = Number.parseInt(raw, 10);
3577
- if (Number.isNaN(n)) return DEFAULT_REQ_GAP_MS;
3578
- return Math.min(Math.max(n, 0), 1e3);
3579
- }
3580
- function readBuildBudgetMs() {
3581
- const raw = process.env["CONTRIB_BUILD_BUDGET_MS"];
3582
- if (raw == null) return DEFAULT_BUILD_BUDGET_MS;
3583
- const n = Number.parseInt(raw, 10);
3584
- if (Number.isNaN(n)) return DEFAULT_BUILD_BUDGET_MS;
3585
- return Math.min(Math.max(n, MIN_BUILD_BUDGET_MS), MAX_BUILD_BUDGET_MS);
3586
- }
3587
3796
  function authHeaders2() {
3588
3797
  const token = process.env["GITHUB_TOKEN"] ?? process.env["GH_TOKEN"];
3589
3798
  const h = {
@@ -3605,57 +3814,9 @@ function repoFullNameFromApiUrl2(url) {
3605
3814
  return m ? `${m[1]}/${m[2]}` : null;
3606
3815
  }
3607
3816
  function makeClient(fetchImpl, cfg) {
3608
- const startedAt = cfg.now();
3609
- let lastRequestAt = 0;
3610
- let pacedMs = 0;
3611
- let secondaryHits = 0;
3612
- let aborted = false;
3613
- let secondaryAborted = false;
3614
- let budgetAborted = false;
3615
- let coreHealthyAtStart = false;
3616
- async function noteAndMaybeBackOff(res) {
3617
- if (res.status !== 403) return;
3618
- const remaining = res.headers.get("x-ratelimit-remaining");
3619
- const retryAfter = res.headers.get("retry-after");
3620
- const positiveSecondary = retryAfter != null || remaining != null && remaining !== "0";
3621
- const isSecondary = positiveSecondary || coreHealthyAtStart;
3622
- if (!isSecondary) return;
3623
- secondaryHits++;
3624
- if (secondaryHits >= 2) {
3625
- aborted = true;
3626
- secondaryAborted = true;
3627
- return;
3628
- }
3629
- if (cfg.paceEnabled) {
3630
- const trimmed = (retryAfter ?? "").trim();
3631
- const parsed = trimmed.length === 0 ? Number.NaN : Number(trimmed);
3632
- const sec = Number.isNaN(parsed) ? SECONDARY_BACKOFF_CAP_S : Math.min(Math.max(parsed, 0), SECONDARY_BACKOFF_CAP_S);
3633
- const remaining2 = Math.max(0, cfg.budgetMs - (cfg.now() - startedAt));
3634
- await cfg.sleep(Math.min(sec * 1e3, remaining2));
3635
- }
3636
- }
3817
+ const gov = makeGitHubGovernor(fetchImpl, cfg);
3637
3818
  async function raw(path) {
3638
- if (aborted) return null;
3639
- if (cfg.now() - startedAt > cfg.budgetMs) {
3640
- aborted = true;
3641
- budgetAborted = true;
3642
- return null;
3643
- }
3644
- if (cfg.paceEnabled && cfg.gapMs > 0) {
3645
- const wait = cfg.gapMs - (cfg.now() - lastRequestAt);
3646
- if (wait > 0) {
3647
- await cfg.sleep(wait);
3648
- pacedMs += wait;
3649
- }
3650
- lastRequestAt = cfg.now();
3651
- }
3652
- try {
3653
- const res = await fetchImpl(`${GITHUB_API2}${path}`, { headers: authHeaders2() });
3654
- await noteAndMaybeBackOff(res);
3655
- return res;
3656
- } catch {
3657
- return null;
3658
- }
3819
+ return gov.get(`${GITHUB_API2}${path}`, { headers: authHeaders2() });
3659
3820
  }
3660
3821
  async function json(path) {
3661
3822
  const res = await raw(path);
@@ -3669,41 +3830,9 @@ function makeClient(fetchImpl, cfg) {
3669
3830
  }
3670
3831
  }
3671
3832
  async function probe(path) {
3672
- const bound = cfg.probeTimeoutMs;
3673
- let timer;
3674
- const fetchP = fetchImpl(`${GITHUB_API2}${path}`, {
3675
- headers: authHeaders2()
3676
- }).then(
3677
- (r) => r,
3678
- () => null
3679
- );
3680
- try {
3681
- const res = bound == null ? await fetchP : await Promise.race([
3682
- fetchP,
3683
- new Promise((resolve) => {
3684
- timer = setTimeout(() => resolve(null), bound);
3685
- })
3686
- ]);
3687
- if (!res || !res.ok) return null;
3688
- return await res.json();
3689
- } catch {
3690
- return null;
3691
- } finally {
3692
- if (timer) clearTimeout(timer);
3693
- }
3833
+ return gov.probe(`${GITHUB_API2}${path}`, { headers: authHeaders2() });
3694
3834
  }
3695
- function setSecondaryHint(coreHealthy) {
3696
- coreHealthyAtStart = coreHealthy;
3697
- }
3698
- function getStats() {
3699
- return {
3700
- pacedMs,
3701
- secondaryAborted: secondaryAborted ? 1 : 0,
3702
- budgetAborted: budgetAborted ? 1 : 0,
3703
- elapsedMs: cfg.now() - startedAt
3704
- };
3705
- }
3706
- return { raw, json, probe, setSecondaryHint, getStats };
3835
+ return { raw, json, probe, setSecondaryHint: gov.setSecondaryHint, getStats: gov.getStats };
3707
3836
  }
3708
3837
  async function contributorCount(client, fullName) {
3709
3838
  const res = await client.raw(`/repos/${fullName}/contributors?per_page=1&anon=false`);
@@ -3802,10 +3931,63 @@ async function aggregateContributions(opts = {}) {
3802
3931
  const repoCache = /* @__PURE__ */ new Map();
3803
3932
  const contribCache = /* @__PURE__ */ new Map();
3804
3933
  const prRefsCache = /* @__PURE__ */ new Map();
3934
+ const xbuild = opts.repoMetaCache;
3935
+ const servedFromXbuild = /* @__PURE__ */ new Set();
3936
+ const persistedXbuild = /* @__PURE__ */ new Set();
3937
+ const xbuildTried = /* @__PURE__ */ new Set();
3938
+ async function primeFromXbuild(key, fullName) {
3939
+ if (!xbuild || xbuildTried.has(key)) return;
3940
+ xbuildTried.add(key);
3941
+ if (repoCache.has(key) && contribCache.has(key)) return;
3942
+ let cached = null;
3943
+ try {
3944
+ cached = await xbuild.get(key);
3945
+ } catch {
3946
+ return;
3947
+ }
3948
+ if (!cached) return;
3949
+ if (!repoCache.has(key)) {
3950
+ const owner = fullName.split("/")[0] ?? "";
3951
+ repoCache.set(key, {
3952
+ full_name: fullName,
3953
+ stargazers_count: cached.stars,
3954
+ archived: cached.archived,
3955
+ disabled: cached.disabled,
3956
+ fork: cached.fork,
3957
+ language: cached.language,
3958
+ owner: { login: owner }
3959
+ });
3960
+ }
3961
+ if (!contribCache.has(key)) {
3962
+ contribCache.set(key, cached.contributors);
3963
+ servedFromXbuild.add(key);
3964
+ }
3965
+ }
3966
+ async function persistRepoMeta(fullName, repo, contributors) {
3967
+ if (!xbuild) return;
3968
+ const key = repoKey(fullName);
3969
+ if (servedFromXbuild.has(key) || persistedXbuild.has(key)) return;
3970
+ if (contributors === void 0) return;
3971
+ persistedXbuild.add(key);
3972
+ try {
3973
+ await xbuild.set(key, {
3974
+ stars: repo.stargazers_count,
3975
+ contributors,
3976
+ language: repo.language,
3977
+ archived: repo.archived,
3978
+ fork: repo.fork,
3979
+ disabled: repo.disabled
3980
+ });
3981
+ } catch {
3982
+ }
3983
+ }
3805
3984
  async function repoMeta(fullName) {
3806
3985
  const key = repoKey(fullName);
3807
3986
  const hit = repoCache.get(key);
3808
3987
  if (hit !== void 0) return hit;
3988
+ await primeFromXbuild(key, fullName);
3989
+ const primed = repoCache.get(key);
3990
+ if (primed !== void 0) return primed;
3809
3991
  const r = await client.json(`/repos/${fullName}`) ?? null;
3810
3992
  repoCache.set(key, r);
3811
3993
  return r;
@@ -3813,6 +3995,8 @@ async function aggregateContributions(opts = {}) {
3813
3995
  async function repoContribCount(fullName) {
3814
3996
  const key = repoKey(fullName);
3815
3997
  if (contribCache.has(key)) return contribCache.get(key);
3998
+ await primeFromXbuild(key, fullName);
3999
+ if (contribCache.has(key)) return contribCache.get(key);
3816
4000
  const n = await contributorCount(client, fullName);
3817
4001
  contribCache.set(key, n);
3818
4002
  return n;
@@ -3839,14 +4023,18 @@ async function aggregateContributions(opts = {}) {
3839
4023
  if (isDenylistedRepo(fullName)) continue;
3840
4024
  if (isAssigned(issue)) continue;
3841
4025
  if ((perRepo.get(repoKey(fullName)) ?? 0) >= MAX_BOUNTIES_PER_DISCOVERED_REPO) continue;
4026
+ const title = decodeEntities(issue.title).trim();
4027
+ const body = issue.body ? decodeEntities(issue.body) : "";
4028
+ const labels = labelNames2(issue.labels);
4029
+ if (looksLikeContentTask({ title, body, labels })) continue;
3842
4030
  const repo = await repoMeta(fullName);
3843
4031
  if (!repo) {
3844
4032
  metaNull++;
3845
4033
  continue;
3846
4034
  }
3847
- const title = decodeEntities(issue.title).trim();
3848
4035
  const contributors = await repoContribCount(fullName);
3849
4036
  if (contributors === void 0) contribUndefined++;
4037
+ await persistRepoMeta(fullName, repo, contributors);
3850
4038
  if (!passesContributionGate({
3851
4039
  fullName,
3852
4040
  stars: repo.stargazers_count,
@@ -3858,13 +4046,9 @@ async function aggregateContributions(opts = {}) {
3858
4046
  continue;
3859
4047
  }
3860
4048
  if (repo.disabled) continue;
3861
- const body = issue.body ? decodeEntities(issue.body) : "";
3862
- const labels = labelNames2(issue.labels);
3863
- if (looksLikeContentTask({ title, body, labels })) continue;
3864
4049
  const prRefs = await repoPRRefs(fullName);
3865
4050
  if (prRefs === null) prRefsNull++;
3866
- if (prRefs && prRefs.has(issue.number)) continue;
3867
- const openPRsAtDiscovery = prRefs ? 0 : void 0;
4051
+ const openPRsAtDiscovery = prRefs ? prRefs.has(issue.number) ? 1 : 0 : void 0;
3868
4052
  const tags = normalize(
3869
4053
  tokenize4([title, repo.language ?? "", labels.join(" "), body.slice(0, 2e3)].join(" "))
3870
4054
  );
@@ -3955,6 +4139,7 @@ async function aggregateContributions(opts = {}) {
3955
4139
  if (repo.disabled) continue;
3956
4140
  const contributors = await repoContribCount(fullName);
3957
4141
  if (contributors === void 0) contribUndefined++;
4142
+ await persistRepoMeta(fullName, repo, contributors);
3958
4143
  if (repo.archived || repo.fork || repo.stargazers_count < MIN_STARS || contributors === void 0 || contributors < MIN_CONTRIBUTORS) {
3959
4144
  continue;
3960
4145
  }
@@ -3987,8 +4172,7 @@ async function aggregateContributions(opts = {}) {
3987
4172
  if (looksLikeContentTask({ title, body, labels })) continue;
3988
4173
  const prRefs = await repoPRRefs(fullName);
3989
4174
  if (prRefs === null) prRefsNull++;
3990
- if (prRefs && prRefs.has(issue.number)) continue;
3991
- const openPRsAtDiscovery = prRefs ? 0 : void 0;
4175
+ const openPRsAtDiscovery = prRefs ? prRefs.has(issue.number) ? 1 : 0 : void 0;
3992
4176
  const tags = normalize(
3993
4177
  tokenize4([title, repo.language ?? "", labels.join(" "), body.slice(0, 2e3)].join(" "))
3994
4178
  );
@@ -4019,9 +4203,9 @@ async function aggregateContributions(opts = {}) {
4019
4203
  const core = rl?.core ? `${rl.core.remaining}/${rl.core.limit}` : "n/a";
4020
4204
  const search = rl?.search ? `${rl.search.remaining}/${rl.search.limit}` : "n/a";
4021
4205
  const noToken = !(process.env["GITHUB_TOKEN"] ?? process.env["GH_TOKEN"]);
4022
- const { pacedMs, secondaryAborted, budgetAborted, elapsedMs } = client.getStats();
4206
+ const { pacedMs, secondaryAborted, budgetAborted, elapsedMs, gqlCost, gqlRemaining } = client.getStats();
4023
4207
  console.info(
4024
- `[contribute] build metrics \u2014 scanned=${issues.length} reposDistinct=${repoCache.size} emitted=${jobs.length} discovered=${discoveredEmitted} metaNull=${metaNull} contribUndefined=${contribUndefined} prRefsNull=${prRefsNull} paced=${pacedMs} secondaryAborted=${secondaryAborted} budgetAborted=${budgetAborted} core=${core} search=${search} elapsed=${elapsedMs}` + (noToken ? " (NO TOKEN \u2192 60/hr)" : "")
4208
+ `[contribute] build metrics \u2014 scanned=${issues.length} reposDistinct=${repoCache.size} emitted=${jobs.length} discovered=${discoveredEmitted} metaNull=${metaNull} contribUndefined=${contribUndefined} prRefsNull=${prRefsNull} paced=${pacedMs} secondaryAborted=${secondaryAborted} budgetAborted=${budgetAborted} core=${core} search=${search} gqlCost=${gqlCost} gqlRemaining=${gqlRemaining ?? "n/a"} elapsed=${elapsedMs}` + (noToken ? " (NO TOKEN \u2192 60/hr)" : "")
4025
4209
  );
4026
4210
  if (discoveryBudgetStopped) {
4027
4211
  console.warn(
@@ -4031,7 +4215,7 @@ async function aggregateContributions(opts = {}) {
4031
4215
  }
4032
4216
  return jobs;
4033
4217
  }
4034
- var GITHUB_API2, DEFAULT_REQ_GAP_MS, SECONDARY_BACKOFF_CAP_S, DEFAULT_BUILD_BUDGET_MS, MIN_BUILD_BUDGET_MS, MAX_BUILD_BUDGET_MS, PROBE_TIMEOUT_MS, realSleep, CONTRIB_LABEL_QUERIES, CONTRIB_LANGUAGE_QUERIES, CONTRIB_SEARCH_QUERIES, SEARCH_PER_PAGE2, MAX_CONTRIB_ITEMS, MAX_CONTRIB_ISSUES_SCANNED, MAX_DISCOVERED_REPOS, MAX_ISSUES_PER_DISCOVERED_REPO, DISCOVERY_REPOS_PER_TERM, DISCOVERY_VOCAB_TERMS, DISCOVERY_ISSUE_LABELS, repoKey;
4218
+ var GITHUB_API2, CONTRIB_LABEL_QUERIES, CONTRIB_LANGUAGE_QUERIES, CONTRIB_SEARCH_QUERIES, SEARCH_PER_PAGE2, MAX_CONTRIB_ITEMS, MAX_CONTRIB_ISSUES_SCANNED, MAX_DISCOVERED_REPOS, MAX_ISSUES_PER_DISCOVERED_REPO, DISCOVERY_REPOS_PER_TERM, DISCOVERY_VOCAB_TERMS, DISCOVERY_ISSUE_LABELS, repoKey;
4035
4219
  var init_contributions = __esm({
4036
4220
  "../../packages/core/src/feeds/contributions.ts"() {
4037
4221
  "use strict";
@@ -4042,14 +4226,8 @@ var init_contributions = __esm({
4042
4226
  init_contribution_classify();
4043
4227
  init_github_bounties();
4044
4228
  init_http();
4229
+ init_gh_governor();
4045
4230
  GITHUB_API2 = "https://api.github.com";
4046
- DEFAULT_REQ_GAP_MS = 75;
4047
- SECONDARY_BACKOFF_CAP_S = 30;
4048
- DEFAULT_BUILD_BUDGET_MS = 9e4;
4049
- MIN_BUILD_BUDGET_MS = 1e4;
4050
- MAX_BUILD_BUDGET_MS = 9e4;
4051
- PROBE_TIMEOUT_MS = 3e3;
4052
- realSleep = (ms) => new Promise((r) => setTimeout(r, ms));
4053
4231
  CONTRIB_LABEL_QUERIES = [
4054
4232
  'label:"good first issue" type:issue state:open',
4055
4233
  'label:"good-first-issue" type:issue state:open',
@@ -4267,12 +4445,22 @@ async function enrichWinnability(jobs, contribute, w) {
4267
4445
  const repos = [...byRepo.keys()].sort((a, b) => starsOf(b) - starsOf(a));
4268
4446
  const scored = repos.slice(0, maxRepos);
4269
4447
  const cappedOut = repos.length - scored.length;
4448
+ const gov = w.governor ?? makeGitHubGovernor(
4449
+ w.fetchImpl ?? fetch,
4450
+ makeDefaultGovernorConfig({ paceEnabled: !w.fetchImpl })
4451
+ );
4452
+ let stoppedEarly = false;
4270
4453
  for (const repo of scored) {
4454
+ if (gov.tripped() || gov.budgetExhausted()) {
4455
+ stoppedEarly = true;
4456
+ break;
4457
+ }
4271
4458
  const targets = byRepo.get(repo) ?? [];
4272
4459
  const receptivity = await fetchRepoReceptivity(repo, {
4273
4460
  token: w.token,
4274
4461
  fetchImpl: w.fetchImpl,
4275
- now
4462
+ now,
4463
+ governor: gov
4276
4464
  });
4277
4465
  const stars = starsOf(repo);
4278
4466
  const prev = priorStars[repo];
@@ -4301,6 +4489,12 @@ async function enrichWinnability(jobs, contribute, w) {
4301
4489
  }
4302
4490
  }
4303
4491
  }
4492
+ if (stoppedEarly) {
4493
+ const reason = gov.tripped() ? "secondary-abuse breaker" : "wall-clock budget";
4494
+ console.warn(
4495
+ `[winnability] receptivity governor stopped the loop \u2014 ${reason} tripped; remaining repos left un-scored (legacy ranking). Governed egress halted to avoid prolonging the GitHub rate-limit window.`
4496
+ );
4497
+ }
4304
4498
  if (cappedOut > 0) {
4305
4499
  console.warn(
4306
4500
  `[winnability] receptivity cap hit \u2014 scored ${scored.length}/${repos.length} repos (${cappedOut} beyond maxRepos=${maxRepos} left un-scored, legacy ranking)`
@@ -4343,6 +4537,7 @@ var init_indexer = __esm({
4343
4537
  init_contributions();
4344
4538
  init_partners();
4345
4539
  init_github();
4540
+ init_gh_governor();
4346
4541
  init_winnability();
4347
4542
  }
4348
4543
  });
@@ -7938,6 +8133,7 @@ __export(src_exports, {
7938
8133
  MERGE_PROBABILITY: () => MERGE_PROBABILITY,
7939
8134
  MIN_CONTRIBUTORS: () => MIN_CONTRIBUTORS,
7940
8135
  MIN_STARS: () => MIN_STARS,
8136
+ PROBE_TIMEOUT_MS: () => PROBE_TIMEOUT_MS,
7941
8137
  RIGOR: () => RIGOR,
7942
8138
  STRONG_MATCH_THRESHOLD: () => STRONG_MATCH_THRESHOLD,
7943
8139
  SYNONYMS: () => SYNONYMS,
@@ -8009,6 +8205,9 @@ __export(src_exports, {
8009
8205
  lever: () => lever,
8010
8206
  loadPartnerRoles: () => loadPartnerRoles,
8011
8207
  looksLikeEngRole: () => looksLikeEngRole,
8208
+ makeDefaultGovernorConfig: () => makeDefaultGovernorConfig,
8209
+ makeGitHubGovernor: () => makeGitHubGovernor,
8210
+ makeScoringGovernor: () => makeScoringGovernor,
8012
8211
  match: () => match,
8013
8212
  mergeProbability: () => mergeProbability,
8014
8213
  mmrRerank: () => mmrRerank,
@@ -8021,8 +8220,12 @@ __export(src_exports, {
8021
8220
  passesMaturityGate: () => passesMaturityGate,
8022
8221
  personCardToJob: () => personCardToJob,
8023
8222
  projectCardToJob: () => projectCardToJob,
8223
+ readBuildBudgetMs: () => readBuildBudgetMs,
8224
+ readReqGapMs: () => readReqGapMs,
8225
+ realSleep: () => realSleep,
8024
8226
  recordClick: () => recordClick,
8025
8227
  rejectExtraIntroFields: () => rejectExtraIntroFields,
8228
+ relevanceScore: () => relevanceScore,
8026
8229
  revealIntroContacts: () => revealIntroContacts,
8027
8230
  safetyNumber: () => safetyNumber,
8028
8231
  sameLogin: () => sameLogin,
@@ -8049,6 +8252,7 @@ var init_src = __esm({
8049
8252
  init_winnability();
8050
8253
  init_partners();
8051
8254
  init_github();
8255
+ init_gh_governor();
8052
8256
  init_credit();
8053
8257
  init_intro();
8054
8258
  init_directoryThreshold();
@@ -8069,9 +8273,9 @@ var init_keytar = __esm({
8069
8273
  }
8070
8274
  });
8071
8275
 
8072
- // node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/agent-a4d8b1364e2f66adc/node_modules/keytar/build/Release/keytar.node
8276
+ // node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node
8073
8277
  var require_keytar = __commonJS({
8074
- "node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/agent-a4d8b1364e2f66adc/node_modules/keytar/build/Release/keytar.node"(exports, module) {
8278
+ "node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node"(exports, module) {
8075
8279
  "use strict";
8076
8280
  init_keytar();
8077
8281
  try {