@reneturcios/greenlight 0.3.3 → 0.3.5
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/README.md +22 -2
- package/dist/bounty.d.ts +26 -0
- package/dist/bounty.js +48 -0
- package/dist/bounty.js.map +1 -0
- package/dist/ci-triage.d.ts +85 -0
- package/dist/ci-triage.js +335 -0
- package/dist/ci-triage.js.map +1 -0
- package/dist/claims.js +4 -0
- package/dist/claims.js.map +1 -1
- package/dist/cli.js +47 -0
- package/dist/cli.js.map +1 -1
- package/dist/github.d.ts +23 -1
- package/dist/github.js +85 -22
- package/dist/github.js.map +1 -1
- package/dist/index.js +21 -1
- package/dist/index.js.map +1 -1
- package/dist/merge-velocity.d.ts +22 -0
- package/dist/merge-velocity.js +49 -0
- package/dist/merge-velocity.js.map +1 -0
- package/dist/server-side.d.ts +21 -0
- package/dist/server-side.js +68 -0
- package/dist/server-side.js.map +1 -0
- package/dist/types.d.ts +24 -0
- package/dist/verdict.d.ts +16 -0
- package/dist/verdict.js +75 -0
- package/dist/verdict.js.map +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -85,8 +85,17 @@ npx @reneturcios/greenlight scan PrefectHQ/fastmcp
|
|
|
85
85
|
# Friction score for a repo
|
|
86
86
|
npx @reneturcios/greenlight friction triggerdotdev/trigger.dev
|
|
87
87
|
|
|
88
|
+
# CI triage for a red PR: is each failing check yours or pre-existing?
|
|
89
|
+
npx @reneturcios/greenlight ci https://github.com/reticlehq/reticle/pull/1620
|
|
90
|
+
|
|
91
|
+
# [pre-existing] install-gate (windows-latest)
|
|
92
|
+
# same check failing on base: 2 of 3 recent base runs, last at 2026-10-14T10:00:00Z
|
|
93
|
+
|
|
94
|
+
# [external-blocker] Vercel - Authorization required
|
|
95
|
+
# check name matches the Vercel deploy/auth pattern; this failure is infrastructure, not the PR
|
|
96
|
+
|
|
88
97
|
# JSON output for scripting
|
|
89
|
-
npx @reneturcios/greenlight
|
|
98
|
+
npx @reneturcios/greenlight ci <pr-url> --json
|
|
90
99
|
```
|
|
91
100
|
|
|
92
101
|
Real examples from our vetting:
|
|
@@ -114,7 +123,11 @@ The verdict engine is deterministic (no LLM) and checks, in order:
|
|
|
114
123
|
11. An open PR referenced in a non-author comment whose title/body mentions the issue number: downgrades an otherwise-GO verdict to **RISKY** with the `comment-mentioned-pr` flag ("may already cover part of this issue"). Neither can produce **TAKEN**; only closing PRs do that. Fix-announcement comments ("/attempt #N" commands or "Submitted fix for ... in <PR url>" narratives, often linking PRs in sibling repos) get the same downgrade under their own reason quoting the PR URL, with the `attempt-linked-pr` flag, even when the PR never names the issue. `/attempt` comments also register as strong claims.
|
|
115
124
|
12. **Partially-addressed**: merged PRs that reference the issue number (comment-mentioned or linked), or maintainer comments signaling part of the work already shipped ("Half addressed by #905, leaving this open for half B", "Shipped in v3.1.0" next to the issue reference). A plain **GO** hides the scoping work this needs, so the flag `partially-addressed` is added, an otherwise-GO verdict is capped at **RISKY** with a reason like "part of this issue already shipped (PR #905, merged); scope your work to what remains". Never **TAKEN**.
|
|
116
125
|
|
|
117
|
-
Claim detection scans comments for explicit claim phrases, in-progress signals ("fix ready", "PR incoming", "opened a PR"), and soft offers ("happy to fix"). Bot authors are ignored, as are issue reporters unless they announce a ready fix. Scoped claims ("taking the remaining fallback ask", "claiming this half") are recorded as partial: a fresh partial claim downgrades an otherwise-GO verdict to RISKY with a reason naming the claimer and the scope, never TAKEN. PR references (#NNN) in non-author comments are cross-checked against the PR API: an open referenced PR that mentions the issue downgrades GO to RISKY with the `comment-mentioned-pr` flag, and a merged one feeds rule 12 above.
|
|
126
|
+
Claim detection scans comments for explicit claim phrases, in-progress signals ("fix ready", "PR incoming", "opened a PR"), and soft offers ("happy to fix", "take a look at this one"). Bot authors are ignored, as are issue reporters unless they announce a ready fix. Soft claims now carry their comment date, so the verdict can show how old they are (the `weak-claim` flag, warning only). Scoped claims ("taking the remaining fallback ask", "claiming this half") are recorded as partial: a fresh partial claim downgrades an otherwise-GO verdict to RISKY with a reason naming the claimer and the scope, never TAKEN. PR references (#NNN) in non-author comments are cross-checked against the PR API: an open referenced PR that mentions the issue downgrades GO to RISKY with the `comment-mentioned-pr` flag, and a merged one feeds rule 12 above.
|
|
127
|
+
|
|
128
|
+
### v0.3.4: never race blind
|
|
129
|
+
|
|
130
|
+
One evening, five of twelve claimed issues were already taken. The races were not in the comments: they were in the issue timelines, where GitHub records PRs that reference the issue even when their bodies never say "closes #N". So `check` now reads the timeline. An open cross-referenced PR caps the verdict at **TAKEN** with the PR URL and title quoted. A merged one adds a "the issue may already be fixed, verify what shipped" note instead, capped at **RISKY**, because a merged PR can fix only part of an issue. Also new: emoji-proof fix-announcement matching ("Opened #NNN", "🤖 ..." prefixes), bounty-liveness warnings (dead platforms like Algora are named, unverified bounties are flagged, and bounties never raise a verdict), and a `possibly-server-side` warning when the issue's quoted error text does not exist anywhere in the repo. The `friction` command gains one more line when computable: the share of recent merged PRs written by outsiders and the median time to merge, straight from the API.
|
|
118
131
|
|
|
119
132
|
Friction score starts at 100 and subtracts gate weights (assignment -25, vouch -35, collaborators-only -50, paused unsolicited PRs -40, external PRs auto-closed -50, discussion-first -10, claim-first -5, CLA/DCO -5 each), adjusts for external PR merge rate and review/response times when computable, and adds up to +10 for open good-first-issues. Unknown signals stay null and are skipped, never guessed. See `src/friction.ts` for the exact formula.
|
|
120
133
|
|
|
@@ -142,9 +155,14 @@ Tools:
|
|
|
142
155
|
* `claim_issue` - verdict-gated claim comment (dry run unless `execute: true`)
|
|
143
156
|
* `prep_issue` - fork and branch check plus a local PREP.md checklist with the repo's learned conventions (dry run unless `execute: true`)
|
|
144
157
|
* `open_pr` - DCO-aware PR opening from a fork branch (dry run unless `execute: true`)
|
|
158
|
+
* `ci_triage` - classify each failing check on a PR as pre-existing, likely-yours, indeterminate (with a stated lean), or external-blocker, by comparing against the base branch's recent check history
|
|
145
159
|
|
|
146
160
|
Run it locally: `npm run dev` (MCP entry is `src/index.ts`; CLI is `src/cli.ts`).
|
|
147
161
|
|
|
162
|
+
### v0.3.5: CI triage (solve-first)
|
|
163
|
+
|
|
164
|
+
The first solve-side command. On a red PR, `ci` fetches the PR's base and head, collects the failing check runs (with the first failure lines from annotations when it can), and builds the same checks' history from the five most recent base-branch commits. Each failing check gets one line with its class and the evidence: `pre-existing` (same check failing on base, with counts and the last failure time), `likely-yours` (failing on head, passing on base, and the PR touches files that relate to the check), `indeterminate` (no base signal to compare), or `external-blocker` (Vercel/Netlify/deploy-preview auth failures, infrastructure not the PR). Indeterminate checks always state their lean: not touching the check's area leans pre-existing, touching it leans yours, with the reason spelled out. A verdict line closes it out: ALL PRE-EXISTING, HAS LIKELY-YOURS, INDETERMINATE, or NO FAILURES.
|
|
165
|
+
|
|
148
166
|
## Automation
|
|
149
167
|
|
|
150
168
|
Greenlight 0.2.0 automates the contribution pipeline its author ran by hand
|
|
@@ -204,6 +222,8 @@ npm run build
|
|
|
204
222
|
|
|
205
223
|
## Roadmap (Later)
|
|
206
224
|
|
|
225
|
+
* Review-response triage: gather every bot and human review thread on a PR, classify each finding (real, noise, needs a decision) with the code context, draft the reply or fix list (solve-first, next after CI triage)
|
|
226
|
+
* Claim-to-PR prep scaffolding: emit the per-repo work order (house rules, CLA method and link, changeset conventions, fork/branch names) from one `prep` pass
|
|
207
227
|
* Browser extension that scores issues inline on github.com
|
|
208
228
|
* Hosted dashboard of the friction index, refreshed on a schedule
|
|
209
229
|
* Maintainer GitHub Action that auto-labels claim comments
|
package/dist/bounty.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounty-liveness classification. A bounty is context for the contributor,
|
|
3
|
+
* never evidence of landability, so this module never raises a verdict: it
|
|
4
|
+
* only classifies what the issue advertises.
|
|
5
|
+
*
|
|
6
|
+
* Motivation: algora.io 404s and its public API returns zero items (dead
|
|
7
|
+
* since 2025), yet thousands of GitHub issues still wear its bounty labels;
|
|
8
|
+
* onyx#2281 carried a $250 "bounty" with ~30 competing PRs and no live
|
|
9
|
+
* platform behind it. Chasing a dead bounty is wasted work.
|
|
10
|
+
*/
|
|
11
|
+
export type BountyFlag = "bounty-platform-dead" | "bounty-unverified";
|
|
12
|
+
export interface BountySignal {
|
|
13
|
+
/** Lowercased platform name when one is named, e.g. "algora". */
|
|
14
|
+
platform?: string;
|
|
15
|
+
/** The advertised amount when visible, e.g. "$250" or "125 USDC". */
|
|
16
|
+
amount?: string;
|
|
17
|
+
/** Null when the platform is named and not known-dead. */
|
|
18
|
+
flag: BountyFlag | null;
|
|
19
|
+
/** Evidence string for the flag, or "" when flag is null. */
|
|
20
|
+
evidence: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function detectBounty(input: {
|
|
23
|
+
labels: string[];
|
|
24
|
+
title: string;
|
|
25
|
+
body?: string;
|
|
26
|
+
}): BountySignal | null;
|
package/dist/bounty.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounty-liveness classification. A bounty is context for the contributor,
|
|
3
|
+
* never evidence of landability, so this module never raises a verdict: it
|
|
4
|
+
* only classifies what the issue advertises.
|
|
5
|
+
*
|
|
6
|
+
* Motivation: algora.io 404s and its public API returns zero items (dead
|
|
7
|
+
* since 2025), yet thousands of GitHub issues still wear its bounty labels;
|
|
8
|
+
* onyx#2281 carried a $250 "bounty" with ~30 competing PRs and no live
|
|
9
|
+
* platform behind it. Chasing a dead bounty is wasted work.
|
|
10
|
+
*/
|
|
11
|
+
const DEAD_PLATFORMS = {
|
|
12
|
+
algora: "algora.io 404s and its public API returns zero items (dead since 2025)",
|
|
13
|
+
};
|
|
14
|
+
const PLATFORM_RE = /(algora|opire|issuehunt|polar|gitcoin|oss[-.]?hunter|bountysource)/i;
|
|
15
|
+
function normalizePlatform(name) {
|
|
16
|
+
return name.toLowerCase().replace(/[-.]/g, "");
|
|
17
|
+
}
|
|
18
|
+
export function detectBounty(input) {
|
|
19
|
+
const text = [...input.labels, input.title, input.body ?? ""].join("\n");
|
|
20
|
+
const signalsBounty = /\bbounty\b/i.test(text) ||
|
|
21
|
+
/💎/.test(text) ||
|
|
22
|
+
(/\$\s?\d[\d,]*/.test(text) && /bounty|reward|paid|usdc/i.test(text)) ||
|
|
23
|
+
/\b\d[\d,]*\s*usdc\b/i.test(text);
|
|
24
|
+
if (!signalsBounty)
|
|
25
|
+
return null;
|
|
26
|
+
const pm = PLATFORM_RE.exec(text);
|
|
27
|
+
const platform = pm ? normalizePlatform(pm[1]) : undefined;
|
|
28
|
+
const am = /\$\s?(\d[\d,]*)|(\d[\d,]*)\s*usdc/i.exec(text);
|
|
29
|
+
const amount = am ? am[0].trim() : undefined;
|
|
30
|
+
if (platform && DEAD_PLATFORMS[platform]) {
|
|
31
|
+
return {
|
|
32
|
+
platform,
|
|
33
|
+
amount,
|
|
34
|
+
flag: "bounty-platform-dead",
|
|
35
|
+
evidence: `bounty names "${platform}", which is dead: ${DEAD_PLATFORMS[platform]}`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (!platform) {
|
|
39
|
+
return {
|
|
40
|
+
platform: undefined,
|
|
41
|
+
amount,
|
|
42
|
+
flag: "bounty-unverified",
|
|
43
|
+
evidence: "bounty advertised but no identifiable platform or payer in the issue",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return { platform, amount, flag: null, evidence: "" };
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=bounty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounty.js","sourceRoot":"","sources":["../src/bounty.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAeH,MAAM,cAAc,GAA2B;IAC7C,MAAM,EAAE,wEAAwE;CACjF,CAAC;AAEF,MAAM,WAAW,GAAG,qEAAqE,CAAC;AAE1F,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAI5B;IACC,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,aAAa,GACjB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAEhC,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,MAAM,EAAE,GAAG,oCAAoC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAE7C,IAAI,QAAQ,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,OAAO;YACL,QAAQ;YACR,MAAM;YACN,IAAI,EAAE,sBAAsB;YAC5B,QAAQ,EAAE,iBAAiB,QAAQ,qBAAqB,cAAc,CAAC,QAAQ,CAAC,EAAE;SACnF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,QAAQ,EAAE,SAAS;YACnB,MAAM;YACN,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE,sEAAsE;SACjF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type CiCheckClass = "pre-existing" | "likely-yours" | "indeterminate" | "external-blocker";
|
|
2
|
+
export type CiTriageVerdict = "ALL PRE-EXISTING" | "HAS LIKELY-YOURS" | "INDETERMINATE" | "NO FAILURES";
|
|
3
|
+
/** A failing check run on the PR head. */
|
|
4
|
+
export interface HeadCheck {
|
|
5
|
+
name: string;
|
|
6
|
+
conclusion: string;
|
|
7
|
+
detailsUrl?: string;
|
|
8
|
+
/** First meaningful failure lines from check-run annotations, best-effort. */
|
|
9
|
+
failureLines?: string[];
|
|
10
|
+
}
|
|
11
|
+
/** One check-run result from the base branch's recent window. */
|
|
12
|
+
export interface BaseCheckRecord {
|
|
13
|
+
name: string;
|
|
14
|
+
conclusion: string;
|
|
15
|
+
completedAt: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ClassifiedCheck {
|
|
18
|
+
name: string;
|
|
19
|
+
conclusion: string;
|
|
20
|
+
class: CiCheckClass;
|
|
21
|
+
/** Human-readable evidence: base status, times, or the linked file. */
|
|
22
|
+
evidence: string;
|
|
23
|
+
/** On indeterminate only: which way it leans and why is in evidence. */
|
|
24
|
+
lean?: "pre-existing" | "yours";
|
|
25
|
+
failureLines?: string[];
|
|
26
|
+
detailsUrl?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface CiTriageInput {
|
|
29
|
+
prUrl: string;
|
|
30
|
+
prTitle: string;
|
|
31
|
+
baseRef: string;
|
|
32
|
+
baseSha: string;
|
|
33
|
+
headSha: string;
|
|
34
|
+
headChecks: HeadCheck[];
|
|
35
|
+
baseRecords: BaseCheckRecord[];
|
|
36
|
+
changedFiles: string[];
|
|
37
|
+
}
|
|
38
|
+
export interface CiTriageResult {
|
|
39
|
+
pr: string;
|
|
40
|
+
title: string;
|
|
41
|
+
baseRef: string;
|
|
42
|
+
baseSha: string;
|
|
43
|
+
headSha: string;
|
|
44
|
+
checks: ClassifiedCheck[];
|
|
45
|
+
verdict: CiTriageVerdict;
|
|
46
|
+
}
|
|
47
|
+
/** Matrix suffixes ("name (windows-latest)") are family, not identity. */
|
|
48
|
+
export declare function stripMatrix(name: string): string;
|
|
49
|
+
/** Case and whitespace are noise; the matrix suffix is kept so exact
|
|
50
|
+
* variants match first and families match second. */
|
|
51
|
+
export declare function normalizeCheckName(name: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Files the PR touched that plausibly relate to a check, by path-token or
|
|
54
|
+
* semantic-token match. Explainable by design: the caller quotes the
|
|
55
|
+
* returned paths as the link evidence.
|
|
56
|
+
*/
|
|
57
|
+
export declare function checkTouchesFiles(checkName: string, files: string[]): string[];
|
|
58
|
+
/**
|
|
59
|
+
* Classify one failing head check against base records and changed files.
|
|
60
|
+
* now is injected so tests pin ages.
|
|
61
|
+
*/
|
|
62
|
+
export declare function classifyCheck(head: HeadCheck, baseRecords: BaseCheckRecord[], changedFiles: string[]): ClassifiedCheck;
|
|
63
|
+
/** Roll up per-check classes into the one-line verdict. */
|
|
64
|
+
export declare function triageVerdict(checks: ClassifiedCheck[]): CiTriageVerdict;
|
|
65
|
+
/** The pure engine: classify every failing head check, then roll up. */
|
|
66
|
+
export declare function classifyCiTriage(input: CiTriageInput): CiTriageResult;
|
|
67
|
+
export interface PullDetail {
|
|
68
|
+
title: string;
|
|
69
|
+
baseRef: string;
|
|
70
|
+
baseSha: string;
|
|
71
|
+
headSha: string;
|
|
72
|
+
changedFiles: string[];
|
|
73
|
+
}
|
|
74
|
+
/** Test seam: every network call behind a named function. */
|
|
75
|
+
export interface CiTriageDeps {
|
|
76
|
+
fetchPull?: (owner: string, repo: string, number: number) => Promise<PullDetail>;
|
|
77
|
+
fetchHeadChecks?: (owner: string, repo: string, headSha: string) => Promise<HeadCheck[]>;
|
|
78
|
+
fetchBaseRecords?: (owner: string, repo: string, baseRef: string) => Promise<BaseCheckRecord[]>;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Full triage for a PR URL. Best-effort: if the base window cannot be
|
|
82
|
+
* read, every check is classified without base data (indeterminate with a
|
|
83
|
+
* lean) rather than erroring.
|
|
84
|
+
*/
|
|
85
|
+
export declare function triagePr(prUrl: string, deps?: CiTriageDeps): Promise<CiTriageResult>;
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CI failure triage. Answers the question every contributor asks on a red
|
|
3
|
+
* PR: "is this failure mine or pre-existing?"
|
|
4
|
+
*
|
|
5
|
+
* The classifier is a pure function over injected data (no network), so
|
|
6
|
+
* the rules are unit-testable and pinned to the campaign's real cases:
|
|
7
|
+
*
|
|
8
|
+
* - reticle #1620: windows install-gate failing identically on base
|
|
9
|
+
* (leftover-process flake) -> pre-existing
|
|
10
|
+
* - reticle #1633: fixture-based test failing in an untouched package,
|
|
11
|
+
* same check intermittent on base -> pre-existing
|
|
12
|
+
* - a unit-test check failing only on head in a package the PR touched
|
|
13
|
+
* -> likely-yours
|
|
14
|
+
* - Vercel "Authorization required" -> external-blocker (not the PR)
|
|
15
|
+
*
|
|
16
|
+
* Rule order per failing head check:
|
|
17
|
+
* 1. external-blocker: the check name matches a known deploy/auth
|
|
18
|
+
* pattern (Vercel, Netlify, deploy previews). Evidence quotes the match.
|
|
19
|
+
* 2. pre-existing: the same check name failed in the recent base
|
|
20
|
+
* window (exact variant first, then the matrix family, e.g. a windows
|
|
21
|
+
* install-gate flake with no exact-variant history). Evidence quotes
|
|
22
|
+
* base failure counts and the last failure time.
|
|
23
|
+
* 3. likely-yours: failing on head, passing (or absent but with base
|
|
24
|
+
* history present) on base, AND the PR touches files plausibly
|
|
25
|
+
* related to the check (path token or semantic token match).
|
|
26
|
+
* 4. indeterminate: failing on head with no base signal to compare
|
|
27
|
+
* against. Carries a lean ("pre-existing" when the PR does not touch
|
|
28
|
+
* the check's area, "yours" when it does) and says why.
|
|
29
|
+
*
|
|
30
|
+
* The live fetch layer is best-effort: base history and annotations each
|
|
31
|
+
* degrade to "no evidence" on failure rather than guessing.
|
|
32
|
+
*/
|
|
33
|
+
import { apiGet, parsePullUrl } from "./github.js";
|
|
34
|
+
/** Conclusions that count as "this check failed". "stale" (superseded by a newer push) is not a failure. */
|
|
35
|
+
const FAILING = new Set(["failure", "timed_out", "action_required"]);
|
|
36
|
+
/** Check-name patterns that mean the failure is infrastructure, not the PR. */
|
|
37
|
+
const EXTERNAL_PATTERNS = [
|
|
38
|
+
{ pattern: /vercel/i, label: "Vercel" },
|
|
39
|
+
{ pattern: /netlify/i, label: "Netlify" },
|
|
40
|
+
{ pattern: /authorization required/i, label: "authorization required" },
|
|
41
|
+
{ pattern: /deploy(ment)?\s*(preview|check)?/i, label: "deploy" },
|
|
42
|
+
{ pattern: /preview/i, label: "preview" },
|
|
43
|
+
{ pattern: /cloudflare pages/i, label: "Cloudflare Pages" },
|
|
44
|
+
];
|
|
45
|
+
/** Matrix suffixes ("name (windows-latest)") are family, not identity. */
|
|
46
|
+
export function stripMatrix(name) {
|
|
47
|
+
return name.replace(/\s*\([^)]*\)\s*/g, " ").replace(/\s+/g, " ").trim();
|
|
48
|
+
}
|
|
49
|
+
/** Case and whitespace are noise; the matrix suffix is kept so exact
|
|
50
|
+
* variants match first and families match second. */
|
|
51
|
+
export function normalizeCheckName(name) {
|
|
52
|
+
return name.toLowerCase().replace(/\s+/g, " ").trim();
|
|
53
|
+
}
|
|
54
|
+
/** Path segments that describe CI environments, not code areas. Ignored for file linking. */
|
|
55
|
+
const ENV_TOKENS = new Set([
|
|
56
|
+
"windows", "macos", "ubuntu", "linux", "node", "nodejs", "python", "npm", "pnpm", "yarn",
|
|
57
|
+
"run", "ci", "on", "the", "with", "and", "or", "e2e",
|
|
58
|
+
]);
|
|
59
|
+
/** Check-name tokens that semantically relate to file shapes. */
|
|
60
|
+
const SEMANTIC_TOKENS = [
|
|
61
|
+
{ tokens: new Set(["lint", "eslint", "prettier", "format"]), fileTest: /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|rb)$/i },
|
|
62
|
+
{ tokens: new Set(["test", "tests", "unit", "spec", "jest", "vitest", "mocha", "pytest", "coverage"]), fileTest: /(^|\/)(test|tests|__tests__|spec)\b|\.test\.|\.spec\./i },
|
|
63
|
+
{ tokens: new Set(["typecheck", "tsc", "mypy", "pyright"]), fileTest: /\.(ts|tsx|py)$/i },
|
|
64
|
+
{ tokens: new Set(["build", "compile"]), fileTest: /\.(ts|tsx|js|jsx|py|go|rs)$/i },
|
|
65
|
+
];
|
|
66
|
+
const MAX_LINKED_EVIDENCE = 3;
|
|
67
|
+
/**
|
|
68
|
+
* Files the PR touched that plausibly relate to a check, by path-token or
|
|
69
|
+
* semantic-token match. Explainable by design: the caller quotes the
|
|
70
|
+
* returned paths as the link evidence.
|
|
71
|
+
*/
|
|
72
|
+
export function checkTouchesFiles(checkName, files) {
|
|
73
|
+
const tokens = checkName
|
|
74
|
+
.toLowerCase()
|
|
75
|
+
.split(/[^a-z0-9]+/)
|
|
76
|
+
.filter((t) => t.length > 2 && !ENV_TOKENS.has(t));
|
|
77
|
+
const linked = new Set();
|
|
78
|
+
for (const file of files) {
|
|
79
|
+
const fl = file.toLowerCase();
|
|
80
|
+
const segs = fl.split("/");
|
|
81
|
+
const stem = (segs.pop() ?? "").replace(/\.[a-z0-9]+$/, "");
|
|
82
|
+
for (const t of tokens) {
|
|
83
|
+
if (stem.includes(t)) {
|
|
84
|
+
linked.add(file);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
if (segs.some((s) => s === t || (t.length > 4 && s.includes(t)))) {
|
|
88
|
+
linked.add(file);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
if (SEMANTIC_TOKENS.some((g) => g.tokens.has(t) && g.fileTest.test(fl))) {
|
|
92
|
+
linked.add(file);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return [...linked].slice(0, MAX_LINKED_EVIDENCE);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Classify one failing head check against base records and changed files.
|
|
101
|
+
* now is injected so tests pin ages.
|
|
102
|
+
*/
|
|
103
|
+
export function classifyCheck(head, baseRecords, changedFiles) {
|
|
104
|
+
const name = head.name;
|
|
105
|
+
for (const { pattern, label } of EXTERNAL_PATTERNS) {
|
|
106
|
+
if (pattern.test(name)) {
|
|
107
|
+
return {
|
|
108
|
+
name,
|
|
109
|
+
conclusion: head.conclusion,
|
|
110
|
+
class: "external-blocker",
|
|
111
|
+
evidence: `check name matches the ${label} deploy/auth pattern; this failure is infrastructure, not the PR`,
|
|
112
|
+
detailsUrl: head.detailsUrl,
|
|
113
|
+
failureLines: head.failureLines,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const wanted = normalizeCheckName(name);
|
|
118
|
+
const family = stripMatrix(wanted);
|
|
119
|
+
const baseForCheck = baseRecords.filter((r) => normalizeCheckName(r.name) === wanted);
|
|
120
|
+
const baseFamilyFailures = baseRecords.filter((r) => FAILING.has(r.conclusion) && stripMatrix(normalizeCheckName(r.name)) === family);
|
|
121
|
+
const baseFailures = baseForCheck.filter((r) => FAILING.has(r.conclusion));
|
|
122
|
+
if (baseFailures.length > 0) {
|
|
123
|
+
baseFailures.sort((a, b) => (a.completedAt < b.completedAt ? 1 : -1));
|
|
124
|
+
const total = baseForCheck.length;
|
|
125
|
+
const lastAt = baseFailures[0].completedAt ? `, last at ${baseFailures[0].completedAt}` : "";
|
|
126
|
+
return {
|
|
127
|
+
name,
|
|
128
|
+
conclusion: head.conclusion,
|
|
129
|
+
class: "pre-existing",
|
|
130
|
+
evidence: `same check failing on base: ${baseFailures.length} of ${total} recent base run${total === 1 ? "" : "s"}${lastAt}`,
|
|
131
|
+
detailsUrl: head.detailsUrl,
|
|
132
|
+
failureLines: head.failureLines,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (baseFamilyFailures.length > 0) {
|
|
136
|
+
baseFamilyFailures.sort((a, b) => (a.completedAt < b.completedAt ? 1 : -1));
|
|
137
|
+
const familyRuns = baseRecords.filter((r) => stripMatrix(normalizeCheckName(r.name)) === family).length;
|
|
138
|
+
const lastAt = baseFamilyFailures[0].completedAt ? `, last at ${baseFamilyFailures[0].completedAt}` : "";
|
|
139
|
+
return {
|
|
140
|
+
name,
|
|
141
|
+
conclusion: head.conclusion,
|
|
142
|
+
class: "pre-existing",
|
|
143
|
+
evidence: `check family "${family}" failing on base: ${baseFamilyFailures.length} of ${familyRuns} family runs${lastAt}`,
|
|
144
|
+
detailsUrl: head.detailsUrl,
|
|
145
|
+
failureLines: head.failureLines,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const linked = checkTouchesFiles(name, changedFiles);
|
|
149
|
+
if (baseForCheck.length > 0 && linked.length > 0) {
|
|
150
|
+
return {
|
|
151
|
+
name,
|
|
152
|
+
conclusion: head.conclusion,
|
|
153
|
+
class: "likely-yours",
|
|
154
|
+
evidence: `passing on base but failing on head, and the PR touches ${linked.join(", ")} which relates to this check`,
|
|
155
|
+
detailsUrl: head.detailsUrl,
|
|
156
|
+
failureLines: head.failureLines,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (linked.length > 0) {
|
|
160
|
+
return {
|
|
161
|
+
name,
|
|
162
|
+
conclusion: head.conclusion,
|
|
163
|
+
class: "indeterminate",
|
|
164
|
+
lean: "yours",
|
|
165
|
+
evidence: `no base history for this check to compare against; the PR touches ${linked.join(", ")} which relates to it, so it leans yours`,
|
|
166
|
+
detailsUrl: head.detailsUrl,
|
|
167
|
+
failureLines: head.failureLines,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
name,
|
|
172
|
+
conclusion: head.conclusion,
|
|
173
|
+
class: "indeterminate",
|
|
174
|
+
lean: "pre-existing",
|
|
175
|
+
evidence: `no base history for this check to compare against; none of the PR's files relate to it, so it leans pre-existing (an unrelated flake is more likely than a new failure caused by this PR)`,
|
|
176
|
+
detailsUrl: head.detailsUrl,
|
|
177
|
+
failureLines: head.failureLines,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/** Roll up per-check classes into the one-line verdict. */
|
|
181
|
+
export function triageVerdict(checks) {
|
|
182
|
+
if (checks.length === 0)
|
|
183
|
+
return "NO FAILURES";
|
|
184
|
+
if (checks.some((c) => c.class === "likely-yours"))
|
|
185
|
+
return "HAS LIKELY-YOURS";
|
|
186
|
+
if (checks.some((c) => c.class === "indeterminate"))
|
|
187
|
+
return "INDETERMINATE";
|
|
188
|
+
return "ALL PRE-EXISTING";
|
|
189
|
+
}
|
|
190
|
+
/** The pure engine: classify every failing head check, then roll up. */
|
|
191
|
+
export function classifyCiTriage(input) {
|
|
192
|
+
const checks = input.headChecks.map((h) => classifyCheck(h, input.baseRecords, input.changedFiles));
|
|
193
|
+
return {
|
|
194
|
+
pr: input.prUrl,
|
|
195
|
+
title: input.prTitle,
|
|
196
|
+
baseRef: input.baseRef,
|
|
197
|
+
baseSha: input.baseSha,
|
|
198
|
+
headSha: input.headSha,
|
|
199
|
+
checks,
|
|
200
|
+
verdict: triageVerdict(checks),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
async function fetchPullFiles(owner, repo, number) {
|
|
204
|
+
const files = [];
|
|
205
|
+
for (let page = 1; page <= 5; page++) {
|
|
206
|
+
const data = (await apiGet(`/repos/${owner}/${repo}/pulls/${number}/files?per_page=100&page=${page}`));
|
|
207
|
+
for (const f of data ?? []) {
|
|
208
|
+
if (typeof f.filename === "string")
|
|
209
|
+
files.push(f.filename);
|
|
210
|
+
}
|
|
211
|
+
if ((data ?? []).length < 100)
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
return files;
|
|
215
|
+
}
|
|
216
|
+
async function defaultFetchPull(owner, repo, number) {
|
|
217
|
+
const p = (await apiGet(`/repos/${owner}/${repo}/pulls/${number}`));
|
|
218
|
+
return {
|
|
219
|
+
title: String(p.title ?? ""),
|
|
220
|
+
baseRef: String(p.base?.ref ?? ""),
|
|
221
|
+
baseSha: String(p.base?.sha ?? ""),
|
|
222
|
+
headSha: String(p.head?.sha ?? ""),
|
|
223
|
+
changedFiles: await fetchPullFiles(owner, repo, number),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
const ANNOTATION_FETCH_LIMIT = 6;
|
|
227
|
+
async function fetchFailureLines(owner, repo, checkRunId) {
|
|
228
|
+
try {
|
|
229
|
+
const data = (await apiGet(`/repos/${owner}/${repo}/check-runs/${checkRunId}/annotations?per_page=50`));
|
|
230
|
+
const lines = [];
|
|
231
|
+
for (const a of data ?? []) {
|
|
232
|
+
const level = String(a.annotation_level ?? "");
|
|
233
|
+
if (level !== "failure" && level !== "error")
|
|
234
|
+
continue;
|
|
235
|
+
const msg = String(a.message ?? "").trim();
|
|
236
|
+
if (msg)
|
|
237
|
+
lines.push(msg.split("\n")[0].slice(0, 240));
|
|
238
|
+
if (lines.length >= 3)
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
return lines;
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
return [];
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async function defaultFetchHeadChecks(owner, repo, headSha) {
|
|
248
|
+
const data = (await apiGet(`/repos/${owner}/${repo}/commits/${headSha}/check-runs?per_page=100`));
|
|
249
|
+
const failing = (data.check_runs ?? []).filter((c) => c.status === "completed" && FAILING.has(String(c.conclusion ?? "")));
|
|
250
|
+
const out = [];
|
|
251
|
+
let annotationBudget = ANNOTATION_FETCH_LIMIT;
|
|
252
|
+
for (const c of failing) {
|
|
253
|
+
const id = typeof c.id === "number" ? c.id : undefined;
|
|
254
|
+
let failureLines;
|
|
255
|
+
if (id !== undefined && annotationBudget > 0) {
|
|
256
|
+
annotationBudget -= 1;
|
|
257
|
+
const lines = await fetchFailureLines(owner, repo, id);
|
|
258
|
+
if (lines.length > 0)
|
|
259
|
+
failureLines = lines;
|
|
260
|
+
}
|
|
261
|
+
out.push({
|
|
262
|
+
name: String(c.name ?? "unnamed check"),
|
|
263
|
+
conclusion: String(c.conclusion ?? "unknown"),
|
|
264
|
+
detailsUrl: typeof c.details_url === "string" ? c.details_url : undefined,
|
|
265
|
+
failureLines,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return out;
|
|
269
|
+
}
|
|
270
|
+
/** How many recent base-branch commits to inspect for each check's history. */
|
|
271
|
+
const BASE_COMMIT_WINDOW = 5;
|
|
272
|
+
async function defaultFetchBaseRecords(owner, repo, baseRef) {
|
|
273
|
+
const records = [];
|
|
274
|
+
let commits;
|
|
275
|
+
try {
|
|
276
|
+
commits = (await apiGet(`/repos/${owner}/${repo}/commits?sha=${encodeURIComponent(baseRef)}&per_page=${BASE_COMMIT_WINDOW}`));
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return records;
|
|
280
|
+
}
|
|
281
|
+
for (const commit of commits ?? []) {
|
|
282
|
+
const sha = typeof commit.sha === "string" ? commit.sha : undefined;
|
|
283
|
+
if (!sha)
|
|
284
|
+
continue;
|
|
285
|
+
try {
|
|
286
|
+
const data = (await apiGet(`/repos/${owner}/${repo}/commits/${sha}/check-runs?per_page=100`));
|
|
287
|
+
for (const c of data.check_runs ?? []) {
|
|
288
|
+
if (c.status !== "completed" || !c.conclusion)
|
|
289
|
+
continue;
|
|
290
|
+
records.push({
|
|
291
|
+
name: String(c.name ?? "unnamed check"),
|
|
292
|
+
conclusion: String(c.conclusion),
|
|
293
|
+
completedAt: typeof c.completed_at === "string" ? c.completed_at : "",
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
// One bad commit in the window is not the whole story; keep going.
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// completedAt: check-runs list on commits lacks completed_at in some shapes;
|
|
302
|
+
// fall back to "recent run" ordering when absent.
|
|
303
|
+
return records;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Full triage for a PR URL. Best-effort: if the base window cannot be
|
|
307
|
+
* read, every check is classified without base data (indeterminate with a
|
|
308
|
+
* lean) rather than erroring.
|
|
309
|
+
*/
|
|
310
|
+
export async function triagePr(prUrl, deps = {}) {
|
|
311
|
+
const { owner, repo, number } = parsePullUrl(prUrl);
|
|
312
|
+
const fetchPull = deps.fetchPull ?? defaultFetchPull;
|
|
313
|
+
const fetchHeadChecks = deps.fetchHeadChecks ?? defaultFetchHeadChecks;
|
|
314
|
+
const fetchBaseRecords = deps.fetchBaseRecords ?? defaultFetchBaseRecords;
|
|
315
|
+
const pull = await fetchPull(owner, repo, number);
|
|
316
|
+
const headChecks = await fetchHeadChecks(owner, repo, pull.headSha);
|
|
317
|
+
let baseRecords;
|
|
318
|
+
try {
|
|
319
|
+
baseRecords = await fetchBaseRecords(owner, repo, pull.baseRef);
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
baseRecords = [];
|
|
323
|
+
}
|
|
324
|
+
return classifyCiTriage({
|
|
325
|
+
prUrl,
|
|
326
|
+
prTitle: pull.title,
|
|
327
|
+
baseRef: pull.baseRef,
|
|
328
|
+
baseSha: pull.baseSha,
|
|
329
|
+
headSha: pull.headSha,
|
|
330
|
+
headChecks,
|
|
331
|
+
baseRecords,
|
|
332
|
+
changedFiles: pull.changedFiles,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=ci-triage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-triage.js","sourceRoot":"","sources":["../src/ci-triage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAuDnD,4GAA4G;AAC5G,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAErE,+EAA+E;AAC/E,MAAM,iBAAiB,GAA8C;IACnE,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE;IACvC,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE;IACzC,EAAE,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,wBAAwB,EAAE;IACvE,EAAE,OAAO,EAAE,mCAAmC,EAAE,KAAK,EAAE,QAAQ,EAAE;IACjE,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE;IACzC,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,kBAAkB,EAAE;CAC5D,CAAC;AAEF,0EAA0E;AAC1E,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC3E,CAAC;AAED;qDACqD;AACrD,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM;IACxF,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK;CACrD,CAAC,CAAC;AAEH,iEAAiE;AACjE,MAAM,eAAe,GAAqD;IACxE,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,yCAAyC,EAAE;IAClH,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,wDAAwD,EAAE;IAC3K,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE;IACzF,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,8BAA8B,EAAE;CACpF,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,KAAe;IAClE,MAAM,MAAM,GAAG,SAAS;SACrB,WAAW,EAAE;SACb,KAAK,CAAC,YAAY,CAAC;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC5D,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACjB,MAAM;YACR,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACjB,MAAM;YACR,CAAC;YACD,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACxE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACjB,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAe,EACf,WAA8B,EAC9B,YAAsB;IAEtB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,iBAAiB,EAAE,CAAC;QACnD,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,IAAI;gBACJ,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,KAAK,EAAE,kBAAkB;gBACzB,QAAQ,EAAE,0BAA0B,KAAK,kEAAkE;gBAC3G,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;aAChC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC;IACtF,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAM,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,MAAM,CACvF,CAAC;IACF,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3E,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC;QAClC,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO;YACL,IAAI;YACJ,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,cAAc;YACrB,QAAQ,EAAE,+BAA+B,YAAY,CAAC,MAAM,OAAO,KAAK,mBAAmB,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,EAAE;YAC5H,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IACD,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QACxG,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,kBAAkB,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzG,OAAO;YACL,IAAI;YACJ,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,cAAc;YACrB,QAAQ,EAAE,iBAAiB,MAAM,sBAAsB,kBAAkB,CAAC,MAAM,OAAO,UAAU,eAAe,MAAM,EAAE;YACxH,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACrD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,OAAO;YACL,IAAI;YACJ,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,cAAc;YACrB,QAAQ,EAAE,2DAA2D,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B;YACpH,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,IAAI;YACJ,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,qEAAqE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,yCAAyC;YACzI,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI;QACJ,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,KAAK,EAAE,eAAe;QACtB,IAAI,EAAE,cAAc;QACpB,QAAQ,EAAE,2LAA2L;QACrM,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,aAAa,CAAC,MAAyB;IACrD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC;IAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC;QAAE,OAAO,kBAAkB,CAAC;IAC9E,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,eAAe,CAAC;QAAE,OAAO,eAAe,CAAC;IAC5E,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,KAAoB;IACnD,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IACpG,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,KAAK;QACf,KAAK,EAAE,KAAK,CAAC,OAAO;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM;QACN,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC;KAC/B,CAAC;AACJ,CAAC;AAyCD,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,IAAY,EAAE,MAAc;IACvE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,UAAU,KAAK,IAAI,IAAI,UAAU,MAAM,4BAA4B,IAAI,EAAE,CAAC,CAAkB,CAAC;QACxH,KAAK,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;YAC3B,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,GAAG;YAAE,MAAM;IACvC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,KAAa,EAAE,IAAY,EAAE,MAAc;IACzE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,UAAU,KAAK,IAAI,IAAI,UAAU,MAAM,EAAE,CAAC,CAAgB,CAAC;IACnF,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;QAClC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;QAClC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;QAClC,YAAY,EAAE,MAAM,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAEjC,KAAK,UAAU,iBAAiB,CAAC,KAAa,EAAE,IAAY,EAAE,UAAkB;IAC9E,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CACxB,UAAU,KAAK,IAAI,IAAI,eAAe,UAAU,0BAA0B,CAC3E,CAAwB,CAAC;QAC1B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;YAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,OAAO;gBAAE,SAAS;YACvD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3C,IAAI,GAAG;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACtD,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;gBAAE,MAAM;QAC/B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,KAAa,EAAE,IAAY,EAAE,OAAe;IAChF,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,UAAU,KAAK,IAAI,IAAI,YAAY,OAAO,0BAA0B,CAAC,CAE/F,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,MAAM,CAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAC3E,CAAC;IACF,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,IAAI,gBAAgB,GAAG,sBAAsB,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACvD,IAAI,YAAkC,CAAC;QACvC,IAAI,EAAE,KAAK,SAAS,IAAI,gBAAgB,GAAG,CAAC,EAAE,CAAC;YAC7C,gBAAgB,IAAI,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YACvD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,YAAY,GAAG,KAAK,CAAC;QAC7C,CAAC;QACD,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC;YACvC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,SAAS,CAAC;YAC7C,UAAU,EAAE,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;YACzE,YAAY;SACb,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,+EAA+E;AAC/E,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,KAAK,UAAU,uBAAuB,CAAC,KAAa,EAAE,IAAY,EAAE,OAAe;IACjF,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,IAAI,OAAiC,CAAC;IACtC,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,MAAM,CACrB,UAAU,KAAK,IAAI,IAAI,gBAAgB,kBAAkB,CAAC,OAAO,CAAC,aAAa,kBAAkB,EAAE,CACpG,CAA6B,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;QACpE,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,UAAU,KAAK,IAAI,IAAI,YAAY,GAAG,0BAA0B,CAAC,CAE3F,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;gBACtC,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,CAAC,UAAU;oBAAE,SAAS;gBACxD,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC;oBACvC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;oBAChC,WAAW,EAAE,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;iBACtE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;QACrE,CAAC;IACH,CAAC;IACD,6EAA6E;IAC7E,kDAAkD;IAClD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAa,EAAE,OAAqB,EAAE;IACnE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,gBAAgB,CAAC;IACrD,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,sBAAsB,CAAC;IACvE,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,uBAAuB,CAAC;IAE1E,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACpE,IAAI,WAA8B,CAAC;IACnC,IAAI,CAAC;QACH,WAAW,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,WAAW,GAAG,EAAE,CAAC;IACnB,CAAC;IAED,OAAO,gBAAgB,CAAC;QACtB,KAAK;QACL,OAAO,EAAE,IAAI,CAAC,KAAK;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,UAAU;QACV,WAAW;QACX,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/claims.js
CHANGED
|
@@ -30,6 +30,10 @@ const SOFT_PATTERNS = [
|
|
|
30
30
|
{ name: "interested", regex: /\binterested in (working on|taking|this)\b/i, strength: "soft" },
|
|
31
31
|
{ name: "looking-into", regex: /\blooking into this\b/i, strength: "soft" },
|
|
32
32
|
{ name: "have-fork", regex: /\b(my fork|on my fork|branch on my fork)\b/i, strength: "soft" },
|
|
33
|
+
// "I'm going to take a look at this one" — actualbudget/actual#6643 (2026-10-15):
|
|
34
|
+
// pnlabs-dev posted this two months ago and nothing landed. A soft claim
|
|
35
|
+
// with a date, so its age can be weighed; it never caps the verdict alone.
|
|
36
|
+
{ name: "take-a-look", regex: /\b(take a|taking a) look at this/i, strength: "soft" },
|
|
33
37
|
];
|
|
34
38
|
// Scoped claims: the author takes part of the issue, not the whole thing.
|
|
35
39
|
// Seen on reticlehq/reticle#691 ("Taking the remaining fallback ask") where
|
package/dist/claims.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claims.js","sourceRoot":"","sources":["../src/claims.ts"],"names":[],"mappings":"AAiBA,0EAA0E;AAC1E,MAAM,eAAe,GAAmB;IACtC,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,6CAA6C,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACpG,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,6BAA6B,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACnF,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,+BAA+B,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACpF,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACvE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,4CAA4C,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAC9F,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,6CAA6C,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAChG,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,8BAA8B,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAChF,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,qCAAqC,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACvF,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACxE,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,yBAAyB,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACjF,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,gEAAgE,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACpH,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,4CAA4C,EAAE,QAAQ,EAAE,QAAQ,EAAE;IACjG,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,qDAAqD,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAC1G,0FAA0F;IAC1F,yFAAyF;IACzF,mFAAmF;IACnF,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,2EAA2E,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAChI,sFAAsF;IACtF,yFAAyF;IACzF,sFAAsF;IACtF,iFAAiF;IACjF,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,0BAA0B,EAAE,QAAQ,EAAE,QAAQ,EAAE;CACnF,CAAC;AAEF,8FAA8F;AAC9F,MAAM,aAAa,GAAmB;IACpC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,gCAAgC,EAAE,QAAQ,EAAE,MAAM,EAAE;IACjF,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,EAAE;IACjE,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,6CAA6C,EAAE,QAAQ,EAAE,MAAM,EAAE;IAC9F,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,EAAE;IAC3E,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,6CAA6C,EAAE,QAAQ,EAAE,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"claims.js","sourceRoot":"","sources":["../src/claims.ts"],"names":[],"mappings":"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"}
|