@reneturcios/greenlight 0.3.10 → 0.4.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/digest.js ADDED
@@ -0,0 +1,541 @@
1
+ /**
2
+ * Repo-level maintainer digest. The guard answers "what is wrong with THIS
3
+ * PR"; the digest answers "what needs my attention across my whole repo":
4
+ * PR races (two open PRs fixing one issue), claimed-by-other conflicts,
5
+ * stale claims, and assignment-gate conflicts.
6
+ *
7
+ * Four sections, all evidence-carrying, all degradable. A section that
8
+ * cannot be computed says so and why, never silently empty.
9
+ *
10
+ * API budget discipline (unauthenticated: 60 calls/hr): the digest is
11
+ * front-loaded with cheap list calls. Issue comments — the expensive part
12
+ * — are fetched ONLY for linked issues whose issue metadata shows
13
+ * comments > 0, and full timeline walks only happen for candidate stale
14
+ * claims, never for every issue. Each fetch step below names its own
15
+ * budget behavior.
16
+ */
17
+ import { apiGet, fetchComments, fetchLinkedPRs, fetchContributing } from "./github.js";
18
+ import { parseGates } from "./gates.js";
19
+ import { detectClaims, isBotAuthor } from "./claims.js";
20
+ import { extractLinkedIssueNumbers, extractCrossRepoIssues, splitIssueClaims } from "./guard.js";
21
+ export const DIGEST_VERSION = "0.4.0";
22
+ /** Default cap for list fetches; --limit overrides. The true total is always reported. */
23
+ export const DEFAULT_DIGEST_LIMIT = 50;
24
+ /** A claim on an open issue with no open PR after this many days is stale. */
25
+ export const STALE_CLAIM_DAYS = 14;
26
+ /** At this age the suggested action flips from "nudge" to "release". */
27
+ export const RELEASE_CLAIM_DAYS = 30;
28
+ /* ------------------------------------------------------------------ */
29
+ /* Pure section builders */
30
+ /* ------------------------------------------------------------------ */
31
+ /**
32
+ * Issue keys a PR links to: same-repo closing links plus cross-repo
33
+ * closing references (guard's extractors, reused exactly).
34
+ */
35
+ export function extractPRIssueKeys(pull, prOwner, prRepo) {
36
+ const out = [];
37
+ const seen = new Set();
38
+ for (const n of extractLinkedIssueNumbers(pull.title, pull.body, pull.headRef)) {
39
+ const label = `#${n}`;
40
+ if (!seen.has(label)) {
41
+ seen.add(label);
42
+ out.push({ owner: prOwner, repo: prRepo, number: n, label });
43
+ }
44
+ }
45
+ for (const r of extractCrossRepoIssues(pull.title, pull.body, prOwner, prRepo)) {
46
+ const label = `${r.owner}/${r.repo}#${r.number}`;
47
+ if (!seen.has(label.toLowerCase())) {
48
+ seen.add(label.toLowerCase());
49
+ out.push({ owner: r.owner, repo: r.repo, number: r.number, label });
50
+ }
51
+ }
52
+ return out;
53
+ }
54
+ /** Group open PRs by issue key; groups of 2+ are races. */
55
+ export function groupPRsByIssue(prs, prOwner, prRepo) {
56
+ const groups = new Map();
57
+ for (const pr of prs) {
58
+ for (const key of extractPRIssueKeys(pr, prOwner, prRepo)) {
59
+ const mapKey = `${key.owner.toLowerCase()}/${key.repo.toLowerCase()}#${key.number}`;
60
+ const g = groups.get(mapKey);
61
+ if (g) {
62
+ if (!g.prs.some((p) => p.number === pr.number))
63
+ g.prs.push(pr);
64
+ }
65
+ else {
66
+ groups.set(mapKey, { key, prs: [pr] });
67
+ }
68
+ }
69
+ }
70
+ return groups;
71
+ }
72
+ function earliestOf(items, by) {
73
+ let best = null;
74
+ for (const item of items) {
75
+ if (!best || by(item) < by(best))
76
+ best = item;
77
+ }
78
+ return best;
79
+ }
80
+ /**
81
+ * One race: earliest claim (author + date) and earliest PR opened, with a
82
+ * one-line arbitration summary. Pure: issue comments and PR groups are
83
+ * injected.
84
+ */
85
+ export function buildRace(group, issueTitle, issueUrl, comments, now = new Date()) {
86
+ const claims = detectClaims("", comments, now).filter((c) => !isBotAuthor(c.author));
87
+ claims.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
88
+ const first = claims[0] ?? null;
89
+ const firstPr = earliestOf(group.prs, (p) => p.createdAt) ?? group.prs[0];
90
+ const otherPrs = group.prs.filter((p) => p.number !== firstPr.number);
91
+ const arbitration = [
92
+ first
93
+ ? `first claim: @${first.author} on ${first.createdAt.slice(0, 10)}`
94
+ : "no claim comments on this issue",
95
+ `first PR opened: #${firstPr.number} by @${firstPr.author} on ${firstPr.createdAt.slice(0, 10)}`,
96
+ otherPrs.length > 0
97
+ ? `the other PR(s) duplicate effort: ${otherPrs.map((p) => `#${p.number} by @${p.author}`).join(", ")}`
98
+ : "no other PRs",
99
+ ].join("; ");
100
+ return {
101
+ issue: group.key,
102
+ issueTitle,
103
+ issueUrl,
104
+ prs: [...group.prs].sort((a, b) => a.number - b.number),
105
+ earliestClaim: first
106
+ ? { author: first.author, createdAt: first.createdAt, strength: first.strength, phrase: first.phrase }
107
+ : null,
108
+ arbitration,
109
+ };
110
+ }
111
+ /**
112
+ * Claimed-by-other conflicts: open PRs whose linked issue carries a claim
113
+ * by someone other than the PR author that predates the PR. Pure: per-issue
114
+ * comments and author are injected; splitIssueClaims (guard) does the
115
+ * actual matching.
116
+ */
117
+ export function buildClaimConflicts(args) {
118
+ const conflicts = [];
119
+ for (const pr of args.prs) {
120
+ for (const key of extractPRIssueKeys(pr, args.prOwner, args.prRepo)) {
121
+ const mapKey = `${key.owner.toLowerCase()}/${key.repo.toLowerCase()}#${key.number}`;
122
+ const data = args.issueData.get(mapKey);
123
+ if (!data)
124
+ continue;
125
+ const { foreign } = splitIssueClaims(data.author, data.comments, pr.author, pr.createdAt, key.number);
126
+ if (foreign.length > 0) {
127
+ conflicts.push({ pr, issue: key, issueTitle: data.title, issueUrl: data.url, foreignClaims: foreign });
128
+ }
129
+ }
130
+ }
131
+ return conflicts;
132
+ }
133
+ /**
134
+ * Stale claims: open issues with a claim older than STALE_CLAIM_DAYS and
135
+ * NO open PR linked in the issue's timeline. Pure: claims come from
136
+ * injected comments; the timeline result is injected as LinkedPR[].
137
+ */
138
+ export function buildStaleClaims(candidates, now = new Date()) {
139
+ const out = [];
140
+ for (const c of candidates) {
141
+ const claims = detectClaims("", c.comments, now).filter((x) => !isBotAuthor(x.author));
142
+ const hasOpenPR = c.linkedPRs.some((pr) => pr.state === "open");
143
+ if (hasOpenPR)
144
+ continue;
145
+ for (const claim of claims) {
146
+ if (claim.ageDays >= STALE_CLAIM_DAYS) {
147
+ out.push({
148
+ issue: c.key,
149
+ issueTitle: c.title,
150
+ issueUrl: c.url,
151
+ claimant: claim.author,
152
+ claimDate: claim.createdAt,
153
+ ageDays: claim.ageDays,
154
+ action: claim.ageDays >= RELEASE_CLAIM_DAYS ? "release the claim" : `nudge @${claim.author}`,
155
+ });
156
+ }
157
+ }
158
+ }
159
+ out.sort((a, b) => b.ageDays - a.ageDays);
160
+ return out;
161
+ }
162
+ /**
163
+ * Assignment-gate conflicts: only runs when the repo's gates say
164
+ * assignment is required. A PR whose author is not among the issue's
165
+ * assignees is flagged; "assigned to nobody" is its own flavor.
166
+ */
167
+ export function buildAssignmentConflicts(args) {
168
+ if (!args.assignmentRequired)
169
+ return [];
170
+ const conflicts = [];
171
+ for (const pr of args.prs) {
172
+ for (const key of extractPRIssueKeys(pr, args.prOwner, args.prRepo)) {
173
+ const mapKey = `${key.owner.toLowerCase()}/${key.repo.toLowerCase()}#${key.number}`;
174
+ const data = args.assigneesByIssue.get(mapKey);
175
+ if (!data)
176
+ continue;
177
+ const mine = data.assignees.some((a) => a.toLowerCase() === pr.author.toLowerCase());
178
+ if (!mine) {
179
+ conflicts.push({ pr, issue: key, issueTitle: data.title, issueUrl: data.url, assignees: data.assignees });
180
+ }
181
+ }
182
+ }
183
+ return conflicts;
184
+ }
185
+ /* ------------------------------------------------------------------ */
186
+ /* Rendering */
187
+ /* ------------------------------------------------------------------ */
188
+ function plural(n, one, many) {
189
+ return n === 1 ? one : many;
190
+ }
191
+ export function buildDigestSummary(args) {
192
+ const capped = args.trueOpenPRs !== null && args.trueOpenPRs > args.prCap
193
+ ? ` (showing ${args.prCap} of ${args.trueOpenPRs} open PRs)`
194
+ : "";
195
+ return `Digest for ${args.repo}${capped}: ${args.races} ${plural(args.races, "race", "races")}, ${args.claimConflicts} claimed-by-other ${plural(args.claimConflicts, "conflict", "conflicts")}, ${args.staleClaims} stale ${plural(args.staleClaims, "claim", "claims")}, ${args.assignmentConflicts} assignment ${plural(args.assignmentConflicts, "conflict", "conflicts")}`;
196
+ }
197
+ export function renderDigestMarkdown(result) {
198
+ const lines = [`# ${result.summary}`, ""];
199
+ if (result.races.length > 0) {
200
+ lines.push(`## PR races (${result.races.length})`);
201
+ for (const race of result.races) {
202
+ lines.push(`### ${race.issue.label}: ${race.issueTitle}`);
203
+ lines.push(`- ${race.issueUrl}`);
204
+ lines.push(`- open PRs: ${race.prs.map((p) => `#${p.number} by @${p.author} ("${p.title.slice(0, 60)}")`).join("; ")}`);
205
+ lines.push(`- arbitration: ${race.arbitration}`);
206
+ lines.push("");
207
+ }
208
+ }
209
+ // Conflicts are strong foreign claims (someone actually claimed the work).
210
+ // Soft foreign claims ("happy to help", "interested in this") render as
211
+ // "possible interest", not conflicts: live runs showed soft patterns
212
+ // matching polite offers that are not claims of work.
213
+ const strongConflicts = result.claimConflicts.filter((c) => c.foreignClaims.some((f) => f.strength === "strong"));
214
+ const softOnly = result.claimConflicts.filter((c) => !c.foreignClaims.some((f) => f.strength === "strong"));
215
+ if (result.claimConflicts.length > 0) {
216
+ lines.push(`## Claimed-by-other conflicts (${strongConflicts.length})`);
217
+ for (const c of strongConflicts) {
218
+ lines.push(`- PR #${c.pr.number} by @${c.pr.author} fixes ${c.issue.label} ("${c.issueTitle.slice(0, 60)}") but ${c.foreignClaims
219
+ .filter((f) => f.strength === "strong")
220
+ .map((f) => `@${f.author} claimed it on ${f.createdAt.slice(0, 10)}`)
221
+ .join("; ")}`);
222
+ lines.push(` ${c.issueUrl}`);
223
+ }
224
+ if (softOnly.length > 0) {
225
+ lines.push("");
226
+ lines.push(`Possible interest (soft claims, not firm):`);
227
+ for (const c of softOnly) {
228
+ lines.push(`- PR #${c.pr.number} by @${c.pr.author} fixes ${c.issue.label}: ${c.foreignClaims
229
+ .map((f) => `@${f.author} on ${f.createdAt.slice(0, 10)} ("${f.phrase}")`)
230
+ .join("; ")}`);
231
+ }
232
+ }
233
+ lines.push("");
234
+ }
235
+ if (result.staleClaims.length > 0) {
236
+ lines.push(`## Stale claims (${result.staleClaims.length})`);
237
+ for (const s of result.staleClaims) {
238
+ lines.push(`- ${s.issue.label} "${s.issueTitle.slice(0, 60)}": @${s.claimant} claimed on ${s.claimDate.slice(0, 10)} (${s.ageDays} days ago), no open PR — suggested action: ${s.action}`);
239
+ lines.push(` ${s.issueUrl}`);
240
+ }
241
+ lines.push("");
242
+ }
243
+ if (result.assignmentConflicts.length > 0) {
244
+ lines.push(`## Assignment-gate conflicts (${result.assignmentConflicts.length})`);
245
+ for (const a of result.assignmentConflicts) {
246
+ const assigneeText = a.assignees.length > 0 ? `assigned to ${a.assignees.map((x) => `@${x}`).join(", ")}` : "assigned to nobody";
247
+ lines.push(`- PR #${a.pr.number} by @${a.pr.author} fixes ${a.issue.label} which is ${assigneeText} (repo requires assignment before a PR)`);
248
+ lines.push(` ${a.issueUrl}`);
249
+ }
250
+ lines.push("");
251
+ }
252
+ if (result.degraded.length > 0) {
253
+ lines.push(`## Could not compute`);
254
+ for (const d of result.degraded)
255
+ lines.push(`- ${d.section}: ${d.note}`);
256
+ lines.push("");
257
+ }
258
+ const zero = result.races.length === 0 && result.claimConflicts.length === 0 && result.staleClaims.length === 0 && result.assignmentConflicts.length === 0;
259
+ if (zero && result.degraded.length === 0) {
260
+ lines.push("_Nothing needs attention:_ no PR races, no claimed-by-other conflicts, no stale claims, no assignment conflicts.");
261
+ lines.push("");
262
+ }
263
+ lines.push("---");
264
+ lines.push(`_Generated with [Greenlight digest](https://github.com/CloudCorpRecords/greenlight) v${DIGEST_VERSION}; findings are signals, verify before acting._`);
265
+ return lines.join("\n");
266
+ }
267
+ /**
268
+ * Budget notes (the live layer):
269
+ * - listOpenPRs: 1 pulls call (+ up to 5 pages at limit 50); the true total
270
+ * comes from one search call. Cached per repo for the 6h CLI window.
271
+ * - listOpenIssues: same shape against the issues endpoint (PRs filtered
272
+ * out via the pull_request key). Same true-total treatment.
273
+ * - fetchIssueMeta: 1 call per distinct linked issue (title, author,
274
+ * assignees, comments count). NOT called for issues with no PR linked.
275
+ * - fetchIssueComments: called only when meta.commentsCount > 0 AND the
276
+ * section needs claims. Never for comment-less issues.
277
+ * - fetchLinkedPRs (timeline + search): called only for candidate stale
278
+ * claims, never for every issue.
279
+ */
280
+ async function defaultListOpenPRs(owner, repo, limit) {
281
+ const prs = [];
282
+ let total = null;
283
+ try {
284
+ // Newest first: the cap keeps the most recent open PRs, which is what a
285
+ // maintainer triages. The summary always states the cap and the true
286
+ // total, so nothing is silently dropped.
287
+ const data = (await apiGet(`/repos/${owner}/${repo}/pulls?state=open&sort=created&direction=desc&per_page=${Math.min(limit, 100)}&page=1`));
288
+ for (const p of data ?? []) {
289
+ prs.push({
290
+ number: Number(p.number),
291
+ title: String(p.title ?? ""),
292
+ body: String(p.body ?? ""),
293
+ author: String(p.user?.login ?? ""),
294
+ headRef: String(p.head?.ref ?? ""),
295
+ createdAt: String(p.created_at ?? ""),
296
+ url: String(p.html_url ?? `https://github.com/${owner}/${repo}/pull/${p.number}`),
297
+ });
298
+ if (prs.length >= limit)
299
+ break;
300
+ }
301
+ }
302
+ catch {
303
+ return { prs: [], total: null };
304
+ }
305
+ try {
306
+ const q = encodeURIComponent(`repo:${owner}/${repo} type:pr state:open`);
307
+ const search = (await apiGet(`/search/issues?q=${q}&per_page=1`));
308
+ total = typeof search.total_count === "number" ? search.total_count : null;
309
+ }
310
+ catch {
311
+ // total stays null: the summary states the cap without the true total
312
+ }
313
+ return { prs, total };
314
+ }
315
+ async function defaultListOpenIssues(owner, repo, limit) {
316
+ let data = [];
317
+ let total = null;
318
+ try {
319
+ data = (await apiGet(`/repos/${owner}/${repo}/issues?state=open&per_page=${Math.min(limit, 100)}&page=1`));
320
+ // The issues endpoint returns PRs too; the digest only wants issues.
321
+ data = (data ?? []).filter((i) => !i.pull_request);
322
+ }
323
+ catch {
324
+ return { issues: [], total: null };
325
+ }
326
+ try {
327
+ const q = encodeURIComponent(`repo:${owner}/${repo} type:issue state:open`);
328
+ const search = (await apiGet(`/search/issues?q=${q}&per_page=1`));
329
+ total = typeof search.total_count === "number" ? search.total_count : null;
330
+ }
331
+ catch {
332
+ // total stays null
333
+ }
334
+ return { issues: data.slice(0, limit), total };
335
+ }
336
+ async function defaultFetchIssueMeta(owner, repo, number) {
337
+ const issue = (await apiGet(`/repos/${owner}/${repo}/issues/${number}`));
338
+ return {
339
+ number,
340
+ title: String(issue.title ?? ""),
341
+ state: String(issue.state ?? ""),
342
+ author: String(issue.user?.login ?? ""),
343
+ url: String(issue.html_url ?? `https://github.com/${owner}/${repo}/issues/${number}`),
344
+ commentsCount: typeof issue.comments === "number" ? issue.comments : 0,
345
+ assignees: (issue.assignees ?? []).map((a) => String(a.login ?? "")),
346
+ };
347
+ }
348
+ /**
349
+ * Full digest for owner/repo. Best-effort throughout: a section whose
350
+ * data cannot be read is recorded in `degraded` with the reason, never
351
+ * presented as a clean zero.
352
+ */
353
+ export async function digestRepo(owner, repo, limit, deps = {}, opts = {}) {
354
+ const now = opts.now ?? new Date();
355
+ const listOpenPRs = deps.listOpenPRs ?? defaultListOpenPRs;
356
+ const listOpenIssues = deps.listOpenIssues ?? defaultListOpenIssues;
357
+ const fetchIssueMeta = deps.fetchIssueMeta ?? defaultFetchIssueMeta;
358
+ const fetchIssueComments = deps.fetchIssueComments ?? fetchComments;
359
+ const fetchRepoLinkedPRs = deps.fetchLinkedPRs ?? fetchLinkedPRs;
360
+ const fetchRepoContributing = deps.fetchContributing ?? fetchContributing;
361
+ const degraded = [];
362
+ // 1. The cheap lists first (2-3 calls total).
363
+ const { prs, total: trueOpenPRs } = await listOpenPRs(owner, repo, limit);
364
+ const { issues: openIssues, total: trueOpenIssues } = await listOpenIssues(owner, repo, limit);
365
+ let contributing;
366
+ try {
367
+ contributing = await fetchRepoContributing(owner, repo);
368
+ }
369
+ catch {
370
+ contributing = undefined;
371
+ }
372
+ const races = [];
373
+ const claimConflicts = [];
374
+ const staleClaims = [];
375
+ const assignmentConflicts = [];
376
+ // 2. Linked issues across open PRs. One meta call per DISTINCT linked
377
+ // issue (not per PR): budget discipline for race/conflict sections.
378
+ const groups = groupPRsByIssue(prs, owner, repo);
379
+ const metaByKey = new Map();
380
+ const metaKey = (k) => `${k.owner.toLowerCase()}/${k.repo.toLowerCase()}#${k.number}`;
381
+ const fetchMeta = async (key) => {
382
+ const m = metaKey(key);
383
+ const cached = metaByKey.get(m);
384
+ if (cached)
385
+ return cached;
386
+ try {
387
+ const meta = await fetchIssueMeta(key.owner, key.repo, key.number);
388
+ metaByKey.set(m, meta);
389
+ return meta;
390
+ }
391
+ catch {
392
+ degraded.push({ section: `issue ${key.label}`, note: "issue metadata could not be read" });
393
+ return null;
394
+ }
395
+ };
396
+ const fetchCommentsIfAny = async (key, meta) => {
397
+ // Comments are the expensive part: skip entirely when the issue has none.
398
+ if (meta.commentsCount <= 0)
399
+ return [];
400
+ try {
401
+ return await fetchIssueComments(key.owner, key.repo, key.number);
402
+ }
403
+ catch {
404
+ degraded.push({ section: `issue ${key.label}`, note: "comments could not be read; claim checks skipped for this issue" });
405
+ return [];
406
+ }
407
+ };
408
+ // 3. Races: only groups of 2+ open PRs need issue data.
409
+ // A group keyed on a number that resolves to a PR (not an issue) is not
410
+ // a race: skip it with a note instead of reporting a phantom race.
411
+ const raceGroups = [...groups.values()].filter((g) => g.prs.length >= 2);
412
+ // Group keys that resolve to PRs, not issues, are skipped in every
413
+ // section that treats them as issues (races, claimed-by-other,
414
+ // assignment). Stale claims come from the issues endpoint, which is
415
+ // already PR-filtered.
416
+ const notIssueKeys = new Set();
417
+ for (const group of raceGroups) {
418
+ const meta = await fetchMeta(group.key);
419
+ if (meta && meta.url.includes("/pull/")) {
420
+ degraded.push({ section: `race ${group.key.label}`, note: "skipped: resolves to a PR, not an issue" });
421
+ notIssueKeys.add(metaKey(group.key));
422
+ continue;
423
+ }
424
+ const comments = meta ? await fetchCommentsIfAny(group.key, meta) : [];
425
+ races.push(buildRace(group, meta?.title ?? "(title unavailable)", meta?.url ?? `https://github.com/${group.key.owner}/${group.key.repo}/issues/${group.key.number}`, comments, now));
426
+ }
427
+ // 4. Claimed-by-other conflicts: meta + comments only for distinct
428
+ // linked issues that have comments. Claim-free issues cost one meta
429
+ // call and no comment call.
430
+ {
431
+ const issueData = new Map();
432
+ for (const { key } of groups.values()) {
433
+ if (notIssueKeys.has(metaKey(key)))
434
+ continue;
435
+ const meta = await fetchMeta(key);
436
+ if (!meta)
437
+ continue;
438
+ const comments = await fetchCommentsIfAny(key, meta);
439
+ issueData.set(metaKey(key), { key, title: meta.title, url: meta.url, author: meta.author, comments });
440
+ }
441
+ for (const c of buildClaimConflicts({ prs, prOwner: owner, prRepo: repo, issueData })) {
442
+ claimConflicts.push(c);
443
+ }
444
+ }
445
+ // 5. Stale claims: comments fetched only for open issues with
446
+ // commentsCount > 0; the timeline walk (fetchLinkedPRs) only for
447
+ // candidates that actually carry a claim older than 14 days.
448
+ {
449
+ const candidates = [];
450
+ for (const item of openIssues) {
451
+ const number = Number(item.number);
452
+ const commentsCount = typeof item.comments === "number" ? item.comments : 0;
453
+ if (commentsCount <= 0)
454
+ continue;
455
+ let comments;
456
+ try {
457
+ comments = await fetchIssueComments(owner, repo, number);
458
+ }
459
+ catch {
460
+ degraded.push({ section: `stale-claims #${number}`, note: "comments could not be read; this issue was skipped" });
461
+ continue;
462
+ }
463
+ const claims = detectClaims(String(item.user?.login ?? ""), comments).filter((c) => !isBotAuthor(c.author));
464
+ if (!claims.some((c) => c.ageDays >= STALE_CLAIM_DAYS))
465
+ continue;
466
+ let linked = [];
467
+ try {
468
+ linked = await fetchRepoLinkedPRs(owner, repo, number);
469
+ }
470
+ catch {
471
+ linked = [];
472
+ degraded.push({ section: `stale-claims #${number}`, note: "timeline could not be read; assuming no linked PRs" });
473
+ }
474
+ candidates.push({
475
+ key: { owner, repo, number, label: `#${number}` },
476
+ title: String(item.title ?? ""),
477
+ url: String(item.html_url ?? `https://github.com/${owner}/${repo}/issues/${number}`),
478
+ comments,
479
+ linkedPRs: linked,
480
+ });
481
+ }
482
+ for (const s of buildStaleClaims(candidates, now))
483
+ staleClaims.push(s);
484
+ }
485
+ // 6. Assignment-gate conflicts: only when the repo's gates require
486
+ // assignment. Assignees come from the meta already fetched above;
487
+ // no new calls beyond those.
488
+ {
489
+ let assignmentRequired = false;
490
+ try {
491
+ const gates = parseGates(contributing, { collaboratorsOnlyPolicy: false });
492
+ assignmentRequired = gates.some((g) => g.kind === "assignment_required" && g.detected);
493
+ }
494
+ catch {
495
+ degraded.push({ section: "assignment conflicts", note: "repo gates could not be parsed" });
496
+ }
497
+ if (assignmentRequired) {
498
+ const assigneesByIssue = new Map();
499
+ for (const { key } of groups.values()) {
500
+ if (notIssueKeys.has(metaKey(key)))
501
+ continue;
502
+ const meta = metaByKey.get(metaKey(key));
503
+ if (!meta)
504
+ continue;
505
+ assigneesByIssue.set(metaKey(key), { key, title: meta.title, url: meta.url, assignees: meta.assignees });
506
+ }
507
+ for (const c of buildAssignmentConflicts({ prs, prOwner: owner, prRepo: repo, assignmentRequired, assigneesByIssue })) {
508
+ assignmentConflicts.push(c);
509
+ }
510
+ }
511
+ }
512
+ const summary = buildDigestSummary({
513
+ repo: `${owner}/${repo}`,
514
+ races: races.length,
515
+ // The header counts strong-claim conflicts; soft interest is noted in
516
+ // the section body, not counted as a conflict.
517
+ claimConflicts: claimConflicts.filter((c) => c.foreignClaims.some((f) => f.strength === "strong")).length,
518
+ staleClaims: staleClaims.length,
519
+ assignmentConflicts: assignmentConflicts.length,
520
+ prCap: limit,
521
+ trueOpenPRs,
522
+ });
523
+ const result = {
524
+ repo: `${owner}/${repo}`,
525
+ races,
526
+ claimConflicts,
527
+ staleClaims,
528
+ assignmentConflicts,
529
+ degraded,
530
+ summary,
531
+ prCap: limit,
532
+ trueOpenPRs,
533
+ issueCap: limit,
534
+ trueOpenIssues,
535
+ hasRaces: races.length > 0,
536
+ markdown: "",
537
+ };
538
+ result.markdown = renderDigestMarkdown(result);
539
+ return result;
540
+ }
541
+ //# sourceMappingURL=digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"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"}
@@ -28,3 +28,10 @@
28
28
  */
29
29
  import type { FrictionReport, RepoSignals } from "./types.js";
30
30
  export declare function scoreFriction(signals: RepoSignals): FrictionReport;
31
+ /**
32
+ * The repo_friction pipeline as one callable: gates from CONTRIBUTING and
33
+ * house rules, starter-issue count, and merge velocity as a best-effort
34
+ * signal. Shared by the CLI, the MCP repo_friction tool, and the
35
+ * protocol preflight (which pairs it with the issue status).
36
+ */
37
+ export declare function fetchFrictionSummary(owner: string, repo: string): Promise<FrictionReport>;
package/dist/friction.js CHANGED
@@ -1,4 +1,7 @@
1
1
  import { gateLabel } from "./gates.js";
2
+ import { fetchContributing, detectRepoPolicy, countStarterIssues, } from "./github.js";
3
+ import { parseGates } from "./gates.js";
4
+ import { fetchMergeVelocity } from "./merge-velocity.js";
2
5
  const GATE_WEIGHTS = {
3
6
  assignment_required: -25,
4
7
  vouch_required: -35,
@@ -53,4 +56,37 @@ export function scoreFriction(signals) {
53
56
  signals,
54
57
  };
55
58
  }
59
+ /**
60
+ * The repo_friction pipeline as one callable: gates from CONTRIBUTING and
61
+ * house rules, starter-issue count, and merge velocity as a best-effort
62
+ * signal. Shared by the CLI, the MCP repo_friction tool, and the
63
+ * protocol preflight (which pairs it with the issue status).
64
+ */
65
+ export async function fetchFrictionSummary(owner, repo) {
66
+ const [contributing, policy, starterCount] = await Promise.all([
67
+ fetchContributing(owner, repo),
68
+ detectRepoPolicy(owner, repo),
69
+ countStarterIssues(owner, repo),
70
+ ]);
71
+ const gates = parseGates(contributing, { collaboratorsOnlyPolicy: policy.collaboratorsOnly });
72
+ const report = scoreFriction({
73
+ owner,
74
+ repo,
75
+ gates,
76
+ externalPRMergeRate: null,
77
+ medianFirstReviewHours: null,
78
+ maintainerIssueResponseHours: null,
79
+ openGoodFirstIssueCount: starterCount,
80
+ note: "live",
81
+ });
82
+ // Merge velocity is a signal, never a score input. Best-effort: silent
83
+ // when it fails.
84
+ try {
85
+ report.mergeVelocity = await fetchMergeVelocity(owner, repo);
86
+ }
87
+ catch {
88
+ report.mergeVelocity = null;
89
+ }
90
+ return report;
91
+ }
56
92
  //# sourceMappingURL=friction.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"friction.js","sourceRoot":"","sources":["../src/friction.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"friction.js","sourceRoot":"","sources":["../src/friction.ts"],"names":[],"mappings":"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"}