MCPcopy Create free account
hub / github.com/anthropics/claude-code / closeExpired

Function closeExpired

scripts/sweep.ts:92–154  ·  view source on GitHub ↗
(owner: string, repo: string)

Source from the content-addressed store, hash-verified

90}
91
92async function closeExpired(owner: string, repo: string) {
93 let closed = 0;
94
95 for (const { label, days, reason } of lifecycle) {
96 const cutoff = new Date();
97 cutoff.setDate(cutoff.getDate() - days);
98 console.log(`\n=== ${label} (${days}d timeout) ===`);
99
100 for (let page = 1; page <= 10; page++) {
101 const issues = await githubRequest<any[]>(
102 `/repos/${owner}/${repo}/issues?state=open&labels=${label}&sort=updated&direction=asc&per_page=100&page=${page}`
103 );
104 if (issues.length === 0) break;
105
106 for (const issue of issues) {
107 if (issue.pull_request) continue;
108 if (issue.locked) continue;
109
110 const thumbsUp = issue.reactions?.["+1"] ?? 0;
111 if (thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;
112
113 const base = `/repos/${owner}/${repo}/issues/${issue.number}`;
114
115 const events = await githubRequest<any[]>(`${base}/events?per_page=100`);
116
117 const labeledAt = events
118 .filter((e) => e.event === "labeled" && e.label?.name === label)
119 .map((e) => new Date(e.created_at))
120 .pop();
121
122 if (!labeledAt || labeledAt > cutoff) continue;
123
124 // Skip if a non-bot user commented after the label was applied.
125 // The triage workflow should remove lifecycle labels on human
126 // activity, but check here too as a safety net.
127 const comments = await githubRequest<any[]>(
128 `${base}/comments?since=${labeledAt.toISOString()}&per_page=100`
129 );
130 const hasHumanComment = comments.some(
131 (c) => c.user && c.user.type !== "Bot"
132 );
133 if (hasHumanComment) {
134 console.log(
135 `#${issue.number}: skipping (human activity after ${label} label)`
136 );
137 continue;
138 }
139
140 if (DRY_RUN) {
141 const age = Math.floor((Date.now() - labeledAt.getTime()) / 86400000);
142 console.log(`#${issue.number}: would close (${label}, ${age}d old) — ${issue.title}`);
143 } else {
144 await githubRequest(`${base}/comments`, "POST", { body: CLOSE_MESSAGE(reason) });
145 await githubRequest(base, "PATCH", { state: "closed", state_reason: "not_planned" });
146 console.log(`#${issue.number}: closed (${label})`);
147 }
148 closed++;
149 }

Callers 1

sweep.tsFile · 0.85

Calls 2

CLOSE_MESSAGEFunction · 0.85
githubRequestFunction · 0.70

Tested by

no test coverage detected