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.
- package/dist/bin/claim-push-bg.js +2 -2
- package/dist/bin/jpi-bounties.js +237 -15
- package/dist/bin/jpi-chat-read.js +10 -2
- package/dist/bin/jpi-chat.js +10 -2
- package/dist/bin/jpi-claim.js +6550 -129
- package/dist/bin/jpi-contribute.js +10 -2
- package/dist/bin/jpi-devs.js +237 -15
- package/dist/bin/jpi-dispatch.js +590 -78
- package/dist/bin/jpi-inbox.js +10 -2
- package/dist/bin/jpi-init.js +235 -13
- package/dist/bin/jpi-intro.js +10 -2
- package/dist/bin/jpi-jobs.js +237 -15
- package/dist/bin/jpi-learn.js +10 -2
- package/dist/bin/jpi-login.js +237 -15
- package/dist/bin/jpi-profile.js +10 -2
- package/dist/bin/jpi-project.js +235 -13
- package/dist/bin/jpi-refresh.js +237 -15
- package/dist/bin/jpi-save.js +10 -2
- package/dist/bin/jpi-sync.js +10 -2
- package/dist/bin/jpi-trajectory.js +10 -2
- package/dist/src/chat-client.js +2 -2
- package/dist/src/chat-keystore.js +2 -2
- package/dist/src/github-auth.js +2 -2
- package/dist/src/intro.js +10 -2
- package/dist/src/profile.js +2 -2
- package/dist/src/trajectory.js +10 -2
- package/package.json +1 -1
|
@@ -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 {
|
package/dist/bin/jpi-bounties.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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 {
|
package/dist/bin/jpi-chat.js
CHANGED
|
@@ -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 {
|