terminalhire 0.21.0 → 0.22.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.
@@ -45,9 +45,9 @@ var init_keytar = __esm({
45
45
  }
46
46
  });
47
47
 
48
- // node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node
48
+ // node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/claim-frictionless/node_modules/keytar/build/Release/keytar.node
49
49
  var require_keytar = __commonJS({
50
- "node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node"(exports, module) {
50
+ "node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/claim-frictionless/node_modules/keytar/build/Release/keytar.node"(exports, module) {
51
51
  "use strict";
52
52
  init_keytar();
53
53
  try {
@@ -761,9 +761,9 @@ function ghHeaders(token) {
761
761
  if (token) headers["Authorization"] = `Bearer ${token}`;
762
762
  return headers;
763
763
  }
764
- async function ghFetch(path, token) {
764
+ async function ghFetch(path, token, signal) {
765
765
  const url = `https://api.github.com${path}`;
766
- const res = await fetch(url, { headers: ghHeaders(token) });
766
+ const res = await fetch(url, { headers: ghHeaders(token), signal });
767
767
  if (!res.ok) {
768
768
  throw new Error(`GitHub API ${path}: HTTP ${res.status} ${res.statusText}`);
769
769
  }
@@ -812,6 +812,7 @@ async function fetchGitHubProfile(login, token) {
812
812
  } catch {
813
813
  }
814
814
  return {
815
+ id: user.id,
815
816
  login: user.login,
816
817
  name: user.name ?? void 0,
817
818
  publicEmail: user.email ?? void 0,
@@ -888,8 +889,8 @@ async function fetchOwnedRepoTraction(login, token) {
888
889
  computedAt
889
890
  };
890
891
  }
891
- async function ghFetchRaw(path, token) {
892
- return fetch(`https://api.github.com${path}`, { headers: ghHeaders(token) });
892
+ async function ghFetchRaw(path, token, signal) {
893
+ return fetch(`https://api.github.com${path}`, { headers: ghHeaders(token), signal });
893
894
  }
894
895
  function parseRepoUrl(repoUrl) {
895
896
  const m = repoUrl.match(/\/repos\/([^/]+)\/([^/]+)\/?$/);
@@ -908,11 +909,12 @@ async function fetchOwnedOrgs(token) {
908
909
  return /* @__PURE__ */ new Set();
909
910
  }
910
911
  }
911
- async function repoContributorCount(owner, name, token) {
912
+ async function repoContributorCount(owner, name, token, signal) {
912
913
  try {
913
914
  const res = await ghFetchRaw(
914
915
  `/repos/${owner}/${name}/contributors?per_page=1&anon=false`,
915
- token
916
+ token,
917
+ signal
916
918
  );
917
919
  if (!res.ok) return void 0;
918
920
  const link = res.headers.get("link");
@@ -1180,6 +1182,77 @@ function deriveResumeTrend(cred, repoRecency, now = Date.now()) {
1180
1182
  }
1181
1183
  return scored.sort((a, b) => b.weight - a.weight).slice(0, 12).map((s) => s.t);
1182
1184
  }
1185
+ function parseGitHubRef(url) {
1186
+ const m = String(url ?? "").match(/github\.com\/([^/]+)\/([^/]+)\/(issues|pull)\/(\d+)/);
1187
+ if (!m) return null;
1188
+ return { owner: m[1], repo: m[2], number: parseInt(m[4], 10), kind: m[3] === "pull" ? "pull" : "issue" };
1189
+ }
1190
+ async function ghGraphQL(query, variables, token, signal) {
1191
+ const res = await fetch("https://api.github.com/graphql", {
1192
+ method: "POST",
1193
+ headers: { ...ghHeaders(token), "Content-Type": "application/json" },
1194
+ body: JSON.stringify({ query, variables }),
1195
+ signal
1196
+ });
1197
+ if (!res.ok) throw new Error(`GitHub GraphQL: HTTP ${res.status}`);
1198
+ const json = await res.json();
1199
+ if (json.errors?.length) throw new Error("GitHub GraphQL errors: " + JSON.stringify(json.errors));
1200
+ return json;
1201
+ }
1202
+ async function resolveClosingIssues(owner, name, number, body, token, signal) {
1203
+ if (token) {
1204
+ try {
1205
+ const q = `query($o:String!,$n:String!,$p:Int!){repository(owner:$o,name:$n){pullRequest(number:$p){closingIssuesReferences(first:20){nodes{number}}}}}`;
1206
+ const r = await ghGraphQL(q, { o: owner, n: name, p: number }, token, signal);
1207
+ const nodes = r.data?.repository?.pullRequest?.closingIssuesReferences?.nodes ?? [];
1208
+ return { closesIssues: nodes.map((x) => x.number), linkageSource: "graphql" };
1209
+ } catch {
1210
+ }
1211
+ }
1212
+ const nums = /* @__PURE__ */ new Set();
1213
+ const re = /\b(?:clos(?:e|es|ed)|fix(?:es|ed)?|resolv(?:e|es|ed))\s+#(\d+)/gi;
1214
+ let m;
1215
+ while ((m = re.exec(body)) !== null) nums.add(parseInt(m[1], 10));
1216
+ return { closesIssues: [...nums], linkageSource: nums.size ? "body-keyword" : "none" };
1217
+ }
1218
+ async function fetchPRScoringFacts(prUrl, token, signal) {
1219
+ const ref = parseGitHubRef(prUrl);
1220
+ if (!ref || ref.kind !== "pull") return null;
1221
+ const { owner, repo, number } = ref;
1222
+ const sig = signal ?? AbortSignal.timeout(1e4);
1223
+ let pr;
1224
+ try {
1225
+ pr = await ghFetch(`/repos/${owner}/${repo}/pulls/${number}`, token, sig);
1226
+ } catch {
1227
+ return null;
1228
+ }
1229
+ let repoMeta = null;
1230
+ try {
1231
+ repoMeta = await ghFetch(`/repos/${owner}/${repo}`, token, sig);
1232
+ } catch {
1233
+ }
1234
+ const contributors = await repoContributorCount(owner, repo, token, sig);
1235
+ const { closesIssues, linkageSource } = await resolveClosingIssues(owner, repo, number, pr.body ?? "", token, sig);
1236
+ return {
1237
+ repo: `${owner}/${repo}`,
1238
+ prNumber: number,
1239
+ prUrl: pr.html_url,
1240
+ merged: pr.merged === true,
1241
+ mergedAt: pr.merged_at ?? null,
1242
+ authorId: pr.user?.id ?? null,
1243
+ authorLogin: pr.user?.login ?? null,
1244
+ mergedById: pr.merged_by?.id ?? null,
1245
+ mergedByLogin: pr.merged_by?.login ?? null,
1246
+ closesIssues,
1247
+ linkageSource,
1248
+ repoStars: repoMeta?.stargazers_count ?? null,
1249
+ repoContributors: contributors ?? null,
1250
+ repoArchived: !!repoMeta?.archived,
1251
+ repoFork: !!repoMeta?.fork,
1252
+ repoPrivate: !!repoMeta?.private,
1253
+ fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
1254
+ };
1255
+ }
1183
1256
  var TRACTION_TOP_N, CANDIDATE_PR_PAGE, OPEN_PR_PAGE, TRANSIENT_META_ERROR, RESUME_DECAY_HALF_LIFE_MS, RESUME_MIN_SCORE;
1184
1257
  var init_github = __esm({
1185
1258
  "../../packages/core/src/github.ts"() {
@@ -2867,6 +2940,20 @@ var init_contribution_classify = __esm({
2867
2940
  });
2868
2941
 
2869
2942
  // ../../packages/core/src/feeds/contributions.ts
2943
+ function readReqGapMs() {
2944
+ const raw = process.env["CONTRIB_REQ_GAP_MS"];
2945
+ if (raw == null) return DEFAULT_REQ_GAP_MS;
2946
+ const n = Number.parseInt(raw, 10);
2947
+ if (Number.isNaN(n)) return DEFAULT_REQ_GAP_MS;
2948
+ return Math.min(Math.max(n, 0), 1e3);
2949
+ }
2950
+ function readBuildBudgetMs() {
2951
+ const raw = process.env["CONTRIB_BUILD_BUDGET_MS"];
2952
+ if (raw == null) return DEFAULT_BUILD_BUDGET_MS;
2953
+ const n = Number.parseInt(raw, 10);
2954
+ if (Number.isNaN(n)) return DEFAULT_BUILD_BUDGET_MS;
2955
+ return Math.min(Math.max(n, MIN_BUILD_BUDGET_MS), MAX_BUILD_BUDGET_MS);
2956
+ }
2870
2957
  function authHeaders2() {
2871
2958
  const token = process.env["GITHUB_TOKEN"] ?? process.env["GH_TOKEN"];
2872
2959
  const h = {
@@ -2887,10 +2974,55 @@ function repoFullNameFromApiUrl2(url) {
2887
2974
  const m = url.match(/\/repos\/([^/]+)\/([^/]+)\/?$/);
2888
2975
  return m ? `${m[1]}/${m[2]}` : null;
2889
2976
  }
2890
- function makeClient(fetchImpl) {
2977
+ function makeClient(fetchImpl, cfg) {
2978
+ const startedAt = cfg.now();
2979
+ let lastRequestAt = 0;
2980
+ let pacedMs = 0;
2981
+ let secondaryHits = 0;
2982
+ let aborted = false;
2983
+ let secondaryAborted = false;
2984
+ let budgetAborted = false;
2985
+ let coreHealthyAtStart = false;
2986
+ async function noteAndMaybeBackOff(res) {
2987
+ if (res.status !== 403) return;
2988
+ const remaining = res.headers.get("x-ratelimit-remaining");
2989
+ const retryAfter = res.headers.get("retry-after");
2990
+ const positiveSecondary = retryAfter != null || remaining != null && remaining !== "0";
2991
+ const isSecondary = positiveSecondary || coreHealthyAtStart;
2992
+ if (!isSecondary) return;
2993
+ secondaryHits++;
2994
+ if (secondaryHits >= 2) {
2995
+ aborted = true;
2996
+ secondaryAborted = true;
2997
+ return;
2998
+ }
2999
+ if (cfg.paceEnabled) {
3000
+ const trimmed = (retryAfter ?? "").trim();
3001
+ const parsed = trimmed.length === 0 ? Number.NaN : Number(trimmed);
3002
+ const sec = Number.isNaN(parsed) ? SECONDARY_BACKOFF_CAP_S : Math.min(Math.max(parsed, 0), SECONDARY_BACKOFF_CAP_S);
3003
+ const remaining2 = Math.max(0, cfg.budgetMs - (cfg.now() - startedAt));
3004
+ await cfg.sleep(Math.min(sec * 1e3, remaining2));
3005
+ }
3006
+ }
2891
3007
  async function raw(path) {
3008
+ if (aborted) return null;
3009
+ if (cfg.now() - startedAt > cfg.budgetMs) {
3010
+ aborted = true;
3011
+ budgetAborted = true;
3012
+ return null;
3013
+ }
3014
+ if (cfg.paceEnabled && cfg.gapMs > 0) {
3015
+ const wait = cfg.gapMs - (cfg.now() - lastRequestAt);
3016
+ if (wait > 0) {
3017
+ await cfg.sleep(wait);
3018
+ pacedMs += wait;
3019
+ }
3020
+ lastRequestAt = cfg.now();
3021
+ }
2892
3022
  try {
2893
- return await fetchImpl(`${GITHUB_API2}${path}`, { headers: authHeaders2() });
3023
+ const res = await fetchImpl(`${GITHUB_API2}${path}`, { headers: authHeaders2() });
3024
+ await noteAndMaybeBackOff(res);
3025
+ return res;
2894
3026
  } catch {
2895
3027
  return null;
2896
3028
  }
@@ -2906,7 +3038,42 @@ function makeClient(fetchImpl) {
2906
3038
  return null;
2907
3039
  }
2908
3040
  }
2909
- return { raw, json };
3041
+ async function probe(path) {
3042
+ const bound = cfg.probeTimeoutMs;
3043
+ let timer;
3044
+ const fetchP = fetchImpl(`${GITHUB_API2}${path}`, {
3045
+ headers: authHeaders2()
3046
+ }).then(
3047
+ (r) => r,
3048
+ () => null
3049
+ );
3050
+ try {
3051
+ const res = bound == null ? await fetchP : await Promise.race([
3052
+ fetchP,
3053
+ new Promise((resolve) => {
3054
+ timer = setTimeout(() => resolve(null), bound);
3055
+ })
3056
+ ]);
3057
+ if (!res || !res.ok) return null;
3058
+ return await res.json();
3059
+ } catch {
3060
+ return null;
3061
+ } finally {
3062
+ if (timer) clearTimeout(timer);
3063
+ }
3064
+ }
3065
+ function setSecondaryHint(coreHealthy) {
3066
+ coreHealthyAtStart = coreHealthy;
3067
+ }
3068
+ function getStats() {
3069
+ return {
3070
+ pacedMs,
3071
+ secondaryAborted: secondaryAborted ? 1 : 0,
3072
+ budgetAborted: budgetAborted ? 1 : 0,
3073
+ elapsedMs: cfg.now() - startedAt
3074
+ };
3075
+ }
3076
+ return { raw, json, probe, setSecondaryHint, getStats };
2910
3077
  }
2911
3078
  async function contributorCount(client, fullName) {
2912
3079
  const res = await client.raw(`/repos/${fullName}/contributors?per_page=1&anon=false`);
@@ -2936,7 +3103,7 @@ ${pr.body ?? ""}`.matchAll(/#(\d+)\b/g)) {
2936
3103
  return refs;
2937
3104
  }
2938
3105
  async function fetchRateLimit(client) {
2939
- const r = await client.json("/rate_limit");
3106
+ const r = await client.probe("/rate_limit");
2940
3107
  return r?.resources ?? null;
2941
3108
  }
2942
3109
  async function searchContribIssues(client, queries) {
@@ -2955,8 +3122,21 @@ async function searchContribIssues(client, queries) {
2955
3122
  );
2956
3123
  }
2957
3124
  async function aggregateContributions(opts = {}) {
2958
- const client = makeClient(opts.fetchImpl ?? fetchWithTimeout);
3125
+ const paceEnabled = opts.paceEnabled ?? !opts.fetchImpl;
3126
+ const client = makeClient(opts.fetchImpl ?? fetchWithTimeout, {
3127
+ paceEnabled,
3128
+ gapMs: readReqGapMs(),
3129
+ budgetMs: readBuildBudgetMs(),
3130
+ sleep: opts.sleepImpl ?? realSleep,
3131
+ now: opts.nowImpl ?? Date.now,
3132
+ // Bound the unguarded probe on the REAL network only; injected-fetch tests get
3133
+ // null so the probe stays deterministic (and its shared spy sleeper untouched).
3134
+ probeTimeoutMs: opts.fetchImpl ? null : PROBE_TIMEOUT_MS
3135
+ });
2959
3136
  const queries = opts.queries ?? CONTRIB_SEARCH_QUERIES;
3137
+ const startRl = await fetchRateLimit(client);
3138
+ const coreHealthyAtStart = (startRl?.core?.remaining ?? 0) >= 500;
3139
+ client.setSecondaryHint(coreHealthyAtStart);
2960
3140
  const issues = (await searchContribIssues(client, queries)).slice(0, MAX_CONTRIB_ISSUES_SCANNED);
2961
3141
  const repoCache = /* @__PURE__ */ new Map();
2962
3142
  const contribCache = /* @__PURE__ */ new Map();
@@ -3063,13 +3243,14 @@ async function aggregateContributions(opts = {}) {
3063
3243
  const core = rl?.core ? `${rl.core.remaining}/${rl.core.limit}` : "n/a";
3064
3244
  const search = rl?.search ? `${rl.search.remaining}/${rl.search.limit}` : "n/a";
3065
3245
  const noToken = !(process.env["GITHUB_TOKEN"] ?? process.env["GH_TOKEN"]);
3246
+ const { pacedMs, secondaryAborted, budgetAborted, elapsedMs } = client.getStats();
3066
3247
  console.info(
3067
- `[contribute] build metrics \u2014 scanned=${issues.length} reposDistinct=${repoCache.size} emitted=${jobs.length} metaNull=${metaNull} contribUndefined=${contribUndefined} prRefsNull=${prRefsNull} core=${core} search=${search}` + (noToken ? " (NO TOKEN \u2192 60/hr)" : "")
3248
+ `[contribute] build metrics \u2014 scanned=${issues.length} reposDistinct=${repoCache.size} emitted=${jobs.length} metaNull=${metaNull} contribUndefined=${contribUndefined} prRefsNull=${prRefsNull} paced=${pacedMs} secondaryAborted=${secondaryAborted} budgetAborted=${budgetAborted} core=${core} search=${search} elapsed=${elapsedMs}` + (noToken ? " (NO TOKEN \u2192 60/hr)" : "")
3068
3249
  );
3069
3250
  }
3070
3251
  return jobs;
3071
3252
  }
3072
- var GITHUB_API2, CONTRIB_LABEL_QUERIES, CONTRIB_LANGUAGE_QUERIES, CONTRIB_SEARCH_QUERIES, SEARCH_PER_PAGE2, MAX_CONTRIB_ITEMS, MAX_CONTRIB_ISSUES_SCANNED;
3253
+ 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;
3073
3254
  var init_contributions = __esm({
3074
3255
  "../../packages/core/src/feeds/contributions.ts"() {
3075
3256
  "use strict";
@@ -3081,6 +3262,13 @@ var init_contributions = __esm({
3081
3262
  init_github_bounties();
3082
3263
  init_http();
3083
3264
  GITHUB_API2 = "https://api.github.com";
3265
+ DEFAULT_REQ_GAP_MS = 75;
3266
+ SECONDARY_BACKOFF_CAP_S = 30;
3267
+ DEFAULT_BUILD_BUDGET_MS = 9e4;
3268
+ MIN_BUILD_BUDGET_MS = 1e4;
3269
+ MAX_BUILD_BUDGET_MS = 9e4;
3270
+ PROBE_TIMEOUT_MS = 3e3;
3271
+ realSleep = (ms) => new Promise((r) => setTimeout(r, ms));
3084
3272
  CONTRIB_LABEL_QUERIES = [
3085
3273
  'label:"good first issue" type:issue state:open',
3086
3274
  'label:"good-first-issue" type:issue state:open',
@@ -3197,6 +3385,36 @@ var init_indexer = __esm({
3197
3385
  }
3198
3386
  });
3199
3387
 
3388
+ // ../../packages/core/src/credit.ts
3389
+ function verifyClaimCredit(claim, facts) {
3390
+ const reasons = [];
3391
+ const fail = (code, message) => reasons.push({ code, message });
3392
+ const norm = (r) => r.trim().toLowerCase();
3393
+ if (norm(facts.repo) !== norm(claim.repo))
3394
+ fail("repo-mismatch", `PR is in ${facts.repo}, claim is against ${claim.repo}`);
3395
+ if (!facts.merged) fail("not-merged", `PR #${facts.prNumber} is not merged`);
3396
+ if (facts.authorId == null || facts.authorId !== claim.claimantId)
3397
+ fail("author-mismatch", `PR author id ${facts.authorId} !== claimant id ${claim.claimantId}`);
3398
+ if (facts.merged && facts.mergedById != null && facts.authorId != null && facts.mergedById === facts.authorId)
3399
+ fail("self-merged", `PR was merged by its own author (id ${facts.authorId})`);
3400
+ if (claim.claimedIssueNumber != null) {
3401
+ if (facts.closesIssues.length === 0)
3402
+ fail("issue-linkage-missing", `PR closes no issue; claim names #${claim.claimedIssueNumber}`);
3403
+ else if (!facts.closesIssues.includes(claim.claimedIssueNumber))
3404
+ fail(
3405
+ "issue-linkage-mismatch",
3406
+ `PR closes ${facts.closesIssues.map((n) => "#" + n).join(", ")}; claim names #${claim.claimedIssueNumber}`
3407
+ );
3408
+ }
3409
+ if (reasons.length === 0) reasons.push({ code: "ok", message: "all credit predicates hold" });
3410
+ return { ok: reasons.every((r) => r.code === "ok"), reasons };
3411
+ }
3412
+ var init_credit = __esm({
3413
+ "../../packages/core/src/credit.ts"() {
3414
+ "use strict";
3415
+ }
3416
+ });
3417
+
3200
3418
  // ../../packages/core/src/intro.ts
3201
3419
  function buildIntroPayload(input) {
3202
3420
  const payload = {
@@ -6790,6 +7008,7 @@ __export(src_exports, {
6790
7008
  fetchGitHubProfile: () => fetchGitHubProfile,
6791
7009
  fetchOpenExternalPRs: () => fetchOpenExternalPRs,
6792
7010
  fetchOwnedRepoTraction: () => fetchOwnedRepoTraction,
7011
+ fetchPRScoringFacts: () => fetchPRScoringFacts,
6793
7012
  fetchRepoRecency: () => fetchRepoRecency,
6794
7013
  flattenTiers: () => flattenTiers,
6795
7014
  funnelCounts: () => funnelCounts,
@@ -6820,6 +7039,7 @@ __export(src_exports, {
6820
7039
  opire: () => opire,
6821
7040
  opportunityShortToken: () => opportunityShortToken,
6822
7041
  pageMatches: () => pageMatches,
7042
+ parseGitHubRef: () => parseGitHubRef,
6823
7043
  passesContributionGate: () => passesContributionGate,
6824
7044
  passesMaturityGate: () => passesMaturityGate,
6825
7045
  personCardToJob: () => personCardToJob,
@@ -6836,6 +7056,7 @@ __export(src_exports, {
6836
7056
  validateGraph: () => validateGraph,
6837
7057
  validateIntroPayload: () => validateIntroPayload,
6838
7058
  validateTargetContact: () => validateTargetContact,
7059
+ verifyClaimCredit: () => verifyClaimCredit,
6839
7060
  workable: () => workable,
6840
7061
  wwr: () => wwr
6841
7062
  });
@@ -6850,6 +7071,7 @@ var init_src = __esm({
6850
7071
  init_indexer();
6851
7072
  init_partners();
6852
7073
  init_github();
7074
+ init_credit();
6853
7075
  init_intro();
6854
7076
  init_directoryThreshold();
6855
7077
  init_chatCrypto();
@@ -6868,9 +7090,9 @@ var init_keytar = __esm({
6868
7090
  }
6869
7091
  });
6870
7092
 
6871
- // node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node
7093
+ // node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/claim-frictionless/node_modules/keytar/build/Release/keytar.node
6872
7094
  var require_keytar = __commonJS({
6873
- "node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node"(exports, module) {
7095
+ "node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/claim-frictionless/node_modules/keytar/build/Release/keytar.node"(exports, module) {
6874
7096
  "use strict";
6875
7097
  init_keytar();
6876
7098
  try {
@@ -810,6 +810,13 @@ var init_indexer = __esm({
810
810
  }
811
811
  });
812
812
 
813
+ // ../../packages/core/src/credit.ts
814
+ var init_credit = __esm({
815
+ "../../packages/core/src/credit.ts"() {
816
+ "use strict";
817
+ }
818
+ });
819
+
813
820
  // ../../packages/core/src/intro.ts
814
821
  var INTRO_ALLOWED_FIELDS, INTRO_ALLOWED_SET, INTRO_PENDING_TTL_MS, INTRO_ACCEPTED_TTL_MS;
815
822
  var init_intro = __esm({
@@ -3949,6 +3956,7 @@ var init_src = __esm({
3949
3956
  init_indexer();
3950
3957
  init_partners();
3951
3958
  init_github();
3959
+ init_credit();
3952
3960
  init_intro();
3953
3961
  init_directoryThreshold();
3954
3962
  init_chatCrypto();
@@ -3967,9 +3975,9 @@ var init_keytar = __esm({
3967
3975
  }
3968
3976
  });
3969
3977
 
3970
- // node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node
3978
+ // node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/claim-frictionless/node_modules/keytar/build/Release/keytar.node
3971
3979
  var require_keytar = __commonJS({
3972
- "node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node"(exports, module) {
3980
+ "node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/claim-frictionless/node_modules/keytar/build/Release/keytar.node"(exports, module) {
3973
3981
  "use strict";
3974
3982
  init_keytar();
3975
3983
  try {
@@ -827,6 +827,13 @@ var init_indexer = __esm({
827
827
  }
828
828
  });
829
829
 
830
+ // ../../packages/core/src/credit.ts
831
+ var init_credit = __esm({
832
+ "../../packages/core/src/credit.ts"() {
833
+ "use strict";
834
+ }
835
+ });
836
+
830
837
  // ../../packages/core/src/intro.ts
831
838
  function buildIntroPayload(input) {
832
839
  const payload = {
@@ -3977,6 +3984,7 @@ var init_src = __esm({
3977
3984
  init_indexer();
3978
3985
  init_partners();
3979
3986
  init_github();
3987
+ init_credit();
3980
3988
  init_intro();
3981
3989
  init_directoryThreshold();
3982
3990
  init_chatCrypto();
@@ -3995,9 +4003,9 @@ var init_keytar = __esm({
3995
4003
  }
3996
4004
  });
3997
4005
 
3998
- // node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node
4006
+ // node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/claim-frictionless/node_modules/keytar/build/Release/keytar.node
3999
4007
  var require_keytar = __commonJS({
4000
- "node-file:/Users/ericgang/job-placement-inline/node_modules/keytar/build/Release/keytar.node"(exports, module) {
4008
+ "node-file:/Users/ericgang/job-placement-inline/.claude/worktrees/claim-frictionless/node_modules/keytar/build/Release/keytar.node"(exports, module) {
4001
4009
  "use strict";
4002
4010
  init_keytar();
4003
4011
  try {