@reneturcios/greenlight 0.5.0 → 0.6.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.
@@ -0,0 +1,218 @@
1
+ /**
2
+ * The contributor passport. Reads the Claim Ledger's public API for the
3
+ * account's protocol claims (held, completed, expired, queued, over-cap)
4
+ * and the GitHub search API for merged PRs, and renders one honest page.
5
+ *
6
+ * If the Ledger has no file for the account, it says so plainly: a
7
+ * passport starts with your first protocol claim.
8
+ */
9
+ import { createRequire } from "node:module";
10
+ const GREENLIGHT_VERSION = (() => {
11
+ try {
12
+ return createRequire(import.meta.url)("../package.json").version;
13
+ }
14
+ catch {
15
+ return "unknown";
16
+ }
17
+ })();
18
+ export function ledgerBaseUrl() {
19
+ const env = process.env["GREENLIGHT_LEDGER_URL"];
20
+ return (env && env.trim().length > 0 ? env : "https://cloudcorprecords.github.io/claim-ledger").replace(/\/+$/, "");
21
+ }
22
+ /**
23
+ * Normalize a Ledger account payload defensively: the Ledger is our own
24
+ * API and its fields can drift, so unknown shapes degrade to empties
25
+ * rather than crashing. Whatever is normalized is stated as coming from
26
+ * the Ledger; whatever is absent is stated as absent.
27
+ */
28
+ export function normalizeAccount(login, raw) {
29
+ const empty = { login, activeClaims: [], queuedClaims: [], completedCount: null, expiredCount: null, overCap: null };
30
+ if (!raw || typeof raw !== "object")
31
+ return empty;
32
+ const r = raw;
33
+ const normClaim = (c) => {
34
+ if (!c || typeof c !== "object")
35
+ return null;
36
+ const o = c;
37
+ const repo = typeof o["repo"] === "string"
38
+ ? o["repo"]
39
+ : typeof o["owner"] === "string" && typeof o["repo_name"] === "string"
40
+ ? `${o["owner"]}/${o["repo_name"]}`
41
+ : "unknown/unknown";
42
+ const issue = typeof o["issue"] === "number" ? o["issue"] : typeof o["number"] === "number" ? o["number"] : 0;
43
+ return {
44
+ repo,
45
+ issue,
46
+ url: typeof o["url"] === "string" && o["url"]
47
+ ? o["url"]
48
+ : issue > 0 && repo !== "unknown/unknown"
49
+ ? `https://github.com/${repo}/issues/${issue}`
50
+ : "",
51
+ claimedAt: typeof o["claimed_at"] === "string" ? o["claimed_at"] : typeof o["claimedAt"] === "string" ? o["claimedAt"] : "",
52
+ expiresAt: typeof o["expires_at"] === "string" ? o["expires_at"] : typeof o["expiresAt"] === "string" ? o["expiresAt"] : "",
53
+ state: typeof o["state"] === "string" ? o["state"] : "active",
54
+ commentUrl: typeof o["comment_url"] === "string" ? o["comment_url"] : typeof o["commentUrl"] === "string" ? o["commentUrl"] : null,
55
+ };
56
+ };
57
+ const arr = (v) => (Array.isArray(v) ? v.map(normClaim).filter((c) => c !== null) : []);
58
+ const num = (v) => (typeof v === "number" ? v : null);
59
+ const bool = (v) => (typeof v === "boolean" ? v : null);
60
+ return {
61
+ login,
62
+ activeClaims: arr(r["active_claims"] ?? r["activeClaims"] ?? r["claims"]),
63
+ queuedClaims: arr(r["queued_claims"] ?? r["queuedClaims"] ?? r["queue"]),
64
+ completedCount: num(r["completed_count"] ?? r["completedClaims"]),
65
+ expiredCount: num(r["expired_count"] ?? r["expiredClaims"]),
66
+ overCap: bool(r["over_cap"] ?? r["overCap"]),
67
+ };
68
+ }
69
+ async function defaultFetchAccount(login) {
70
+ const url = `${ledgerBaseUrl()}/v1/accounts/${encodeURIComponent(login)}.json`;
71
+ let res;
72
+ try {
73
+ res = await fetch(url);
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ if (res.status === 404)
79
+ return null;
80
+ if (!res.ok)
81
+ return null;
82
+ try {
83
+ return normalizeAccount(login, await res.json());
84
+ }
85
+ catch {
86
+ return null;
87
+ }
88
+ }
89
+ async function defaultFetchClaimDetail(repo, issue) {
90
+ const url = `${ledgerBaseUrl()}/v1/issues/${repo}/${issue}/status.json`;
91
+ try {
92
+ const res = await fetch(url);
93
+ if (!res.ok)
94
+ return null;
95
+ const data = (await res.json());
96
+ const claim = data.claim;
97
+ if (!claim || typeof claim !== "object")
98
+ return null;
99
+ return {
100
+ claimedAt: typeof claim.claimed_at === "string" ? claim.claimed_at : "",
101
+ expiresAt: typeof claim.expires_at === "string" ? claim.expires_at : "",
102
+ commentUrl: typeof claim.comment_url === "string" ? claim.comment_url : null,
103
+ };
104
+ }
105
+ catch {
106
+ return null;
107
+ }
108
+ }
109
+ async function defaultFetchMergedCount(login) {
110
+ const q = encodeURIComponent(`author:${login} type:pr is:merged`);
111
+ try {
112
+ const res = await fetch(`https://api.github.com/search/issues?q=${q}&per_page=1`, {
113
+ headers: { "User-Agent": "greenlight", Accept: "application/vnd.github+json" },
114
+ });
115
+ if (!res.ok)
116
+ return null;
117
+ const data = (await res.json());
118
+ return typeof data.total_count === "number" ? data.total_count : null;
119
+ }
120
+ catch {
121
+ return null;
122
+ }
123
+ }
124
+ function claimLine(c) {
125
+ const dates = [c.claimedAt.slice(0, 10), c.expiresAt.slice(0, 10)].filter((d) => d.length > 0).join(" -> ");
126
+ return `${c.repo}#${c.issue} (${c.state}${dates ? `, ${dates}` : ""}) ${c.commentUrl ? c.commentUrl : c.url}`;
127
+ }
128
+ export async function buildPassport(login, deps = {}, now = new Date()) {
129
+ const fetchAccount = deps.fetchAccount ?? defaultFetchAccount;
130
+ const fetchMergedCount = deps.fetchMergedCount ?? defaultFetchMergedCount;
131
+ const fetchClaimDetail = deps.fetchClaimDetail ?? defaultFetchClaimDetail;
132
+ const account = await fetchAccount(login).catch(() => null);
133
+ const mergedPrs = await fetchMergedCount(login).catch(() => null);
134
+ if (!account) {
135
+ const markdown = [
136
+ `# Contributor passport: @${login}`,
137
+ "",
138
+ "No passport file for this account in the Claim Ledger yet.",
139
+ "",
140
+ "Your passport starts with your first protocol claim: claim an issue with the Greenlight protocol marker " +
141
+ "(`greenlight claim` drafts it for you) and the Ledger indexes it within 15 minutes.",
142
+ "",
143
+ `Ledger: ${ledgerBaseUrl()}. Merged PRs on GitHub: ${mergedPrs === null ? "unknown (lookup failed)" : mergedPrs}.`,
144
+ "",
145
+ `_Passport generated by Greenlight v${GREENLIGHT_VERSION}._`,
146
+ ].join("\n");
147
+ return {
148
+ login,
149
+ found: false,
150
+ account: null,
151
+ mergedPrs,
152
+ honorRatio: "no ledger history",
153
+ markdown,
154
+ json: { login, found: false, mergedPrs, ledger: ledgerBaseUrl() },
155
+ };
156
+ }
157
+ // Enrich claims with dates from the per-issue status files. Each
158
+ // enrichment is independent and best-effort: a missing file leaves the
159
+ // claim exactly as the account file described it.
160
+ const enrich = async (claims) => Promise.all(claims.map(async (c) => {
161
+ if (c.issue <= 0)
162
+ return c;
163
+ const detail = await fetchClaimDetail(c.repo, c.issue).catch(() => null);
164
+ if (!detail)
165
+ return c;
166
+ return {
167
+ ...c,
168
+ claimedAt: c.claimedAt || detail.claimedAt,
169
+ expiresAt: c.expiresAt || detail.expiresAt,
170
+ commentUrl: c.commentUrl ?? detail.commentUrl,
171
+ };
172
+ }));
173
+ account.activeClaims = await enrich(account.activeClaims);
174
+ account.queuedClaims = await enrich(account.queuedClaims);
175
+ const completed = account.completedCount ?? account.activeClaims.filter((c) => c.state === "completed").length;
176
+ const expired = account.expiredCount ?? account.activeClaims.filter((c) => c.state === "expired").length;
177
+ const historyKnown = account.completedCount !== null || account.expiredCount !== null || account.activeClaims.some((c) => c.state === "completed" || c.state === "expired");
178
+ const honorRatio = !historyKnown || completed + expired === 0
179
+ ? "no completed/expired history in the ledger yet"
180
+ : `${completed} completed vs ${expired} expired (${Math.round((completed / (completed + expired)) * 100)}% completed)`;
181
+ const lines = [];
182
+ lines.push(`# Contributor passport: @${login}`);
183
+ lines.push("");
184
+ lines.push("## Claim Protocol record");
185
+ lines.push(`Active protocol claims: ${account.activeClaims.length}`);
186
+ for (const c of account.activeClaims)
187
+ lines.push(`- ${claimLine(c)}`);
188
+ lines.push(`Queued behind others: ${account.queuedClaims.length}`);
189
+ for (const c of account.queuedClaims)
190
+ lines.push(`- ${claimLine(c)}`);
191
+ lines.push(`Claim honor record: ${honorRatio}`);
192
+ lines.push(`Over the active-claim cap: ${account.overCap === null ? "not reported by the ledger" : account.overCap ? "yes (squatting flag)" : "no"}`);
193
+ lines.push("");
194
+ lines.push("## GitHub record");
195
+ lines.push(`Merged PRs: ${mergedPrs === null ? "unknown (lookup failed)" : mergedPrs}`);
196
+ lines.push("");
197
+ lines.push(`Ledger: ${ledgerBaseUrl()}. Checked ${now.toISOString().slice(0, 10)}.`);
198
+ lines.push(`_Passport generated by Greenlight v${GREENLIGHT_VERSION}._`);
199
+ return {
200
+ login,
201
+ found: true,
202
+ account,
203
+ mergedPrs,
204
+ honorRatio,
205
+ markdown: lines.join("\n"),
206
+ json: {
207
+ login,
208
+ found: true,
209
+ ledger: ledgerBaseUrl(),
210
+ activeClaims: account.activeClaims,
211
+ queuedClaims: account.queuedClaims,
212
+ honorRatio,
213
+ overCap: account.overCap,
214
+ mergedPrs,
215
+ },
216
+ };
217
+ }
218
+ //# sourceMappingURL=passport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passport.js","sourceRoot":"","sources":["../src/passport.ts"],"names":[],"mappings":"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"}
@@ -29,7 +29,7 @@ without it the tools still work but share the small anonymous budget.
29
29
  ## Verify it worked
30
30
 
31
31
  Ask the agent: "list your MCP tools." You should see the `greenlight`
32
- server with all 13 tools:
32
+ server with all 15 tools:
33
33
 
34
34
  - `check_issue` — verdict on whether an issue is landable (GO / RISKY / TAKEN / GATED / STALE)
35
35
  - `scan_repo` — find starter issues worth working in a repo
@@ -44,6 +44,8 @@ server with all 13 tools:
44
44
  - `claim_status` — Claim Protocol pre-flight for one issue: who holds it, until when, who is queued, competing PRs, gates, whether the repo honors the protocol
45
45
  - `preflight` — the one-call answer: claim_status plus the repo friction summary
46
46
  - `verify_comment` — draft the verified-finding comment for maintainer-only repos (draft only, never posts)
47
+ - `babysit_prs` — watch your open PRs: one prioritized action list (needs you now, waiting on them, quiet), diffed against stored watermarks
48
+ - `evidence_pack` — the Verified PR evidence pack for one PR: guard verdict, CI triage, review triage, protocol status of linked issues, every claim citing its source
47
49
 
48
50
  ## Format notes
49
51
 
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "test": "tsx --test test/*.test.ts"
26
26
  },
27
27
  "type": "module",
28
- "version": "0.5.0",
28
+ "version": "0.6.0",
29
29
  "mcpName": "io.github.CloudCorpRecords/greenlight",
30
30
  "publishConfig": {
31
31
  "access": "public"
package/server.json CHANGED
@@ -6,13 +6,13 @@
6
6
  "url": "https://github.com/CloudCorpRecords/greenlight",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.5.0",
9
+ "version": "0.6.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "registryBaseUrl": "https://registry.npmjs.org",
14
14
  "identifier": "@reneturcios/greenlight",
15
- "version": "0.5.0",
15
+ "version": "0.6.0",
16
16
  "runtimeHint": "npx",
17
17
  "packageArguments": [
18
18
  {