@oss-autopilot/core 0.44.2 → 0.44.15

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.
Files changed (43) hide show
  1. package/dist/cli-registry.js +61 -0
  2. package/dist/cli.bundle.cjs +101 -127
  3. package/dist/cli.bundle.cjs.map +4 -4
  4. package/dist/commands/daily.d.ts +6 -1
  5. package/dist/commands/daily.js +29 -64
  6. package/dist/commands/dashboard-data.d.ts +22 -1
  7. package/dist/commands/dashboard-data.js +85 -62
  8. package/dist/commands/dashboard-lifecycle.js +39 -2
  9. package/dist/commands/dashboard-scripts.d.ts +1 -1
  10. package/dist/commands/dashboard-scripts.js +2 -1
  11. package/dist/commands/dashboard-server.d.ts +2 -1
  12. package/dist/commands/dashboard-server.js +120 -81
  13. package/dist/commands/dashboard-templates.js +15 -69
  14. package/dist/commands/override.d.ts +21 -0
  15. package/dist/commands/override.js +35 -0
  16. package/dist/core/checklist-analysis.js +3 -1
  17. package/dist/core/daily-logic.d.ts +13 -10
  18. package/dist/core/daily-logic.js +79 -166
  19. package/dist/core/display-utils.d.ts +4 -0
  20. package/dist/core/display-utils.js +53 -54
  21. package/dist/core/errors.d.ts +8 -0
  22. package/dist/core/errors.js +26 -0
  23. package/dist/core/github-stats.d.ts +3 -3
  24. package/dist/core/github-stats.js +15 -7
  25. package/dist/core/index.d.ts +2 -2
  26. package/dist/core/index.js +2 -2
  27. package/dist/core/issue-conversation.js +2 -2
  28. package/dist/core/issue-discovery.d.ts +0 -5
  29. package/dist/core/issue-discovery.js +4 -11
  30. package/dist/core/issue-vetting.d.ts +0 -2
  31. package/dist/core/issue-vetting.js +31 -45
  32. package/dist/core/pr-monitor.d.ts +26 -3
  33. package/dist/core/pr-monitor.js +106 -93
  34. package/dist/core/state.d.ts +22 -1
  35. package/dist/core/state.js +50 -1
  36. package/dist/core/test-utils.js +6 -16
  37. package/dist/core/types.d.ts +51 -38
  38. package/dist/core/types.js +8 -0
  39. package/dist/core/utils.d.ts +2 -0
  40. package/dist/core/utils.js +5 -1
  41. package/dist/formatters/json.d.ts +1 -13
  42. package/dist/formatters/json.js +1 -13
  43. package/package.json +2 -2
@@ -3,6 +3,7 @@
3
3
  * Extracted from PRMonitor to isolate statistics-gathering API calls (#263).
4
4
  */
5
5
  import { extractOwnerRepo, parseGitHubUrl, isOwnRepo } from './utils.js';
6
+ import { isBelowMinStars } from './types.js';
6
7
  import { debug, warn } from './logger.js';
7
8
  import { getHttpCache } from './http-cache.js';
8
9
  const MODULE = 'github-stats';
@@ -39,13 +40,14 @@ function isCachedPRCounts(v) {
39
40
  * string (e.g. mergedAt or closedAt) used for monthly counts and daily activity.
40
41
  * Return an empty string to skip histogram tracking for that item.
41
42
  */
42
- async function fetchUserPRCounts(octokit, githubUsername, query, label, accumulateRepo) {
43
+ async function fetchUserPRCounts(octokit, githubUsername, query, label, accumulateRepo, starFilter) {
43
44
  if (!githubUsername) {
44
45
  return emptyPRCountsResult();
45
46
  }
46
47
  // Check for a fresh cached result (avoids 10-20 paginated API calls)
47
48
  const cache = getHttpCache();
48
- const cacheKey = `pr-counts:${label}:${githubUsername}`;
49
+ const minStarsSuffix = starFilter ? `:stars${starFilter.minStars}` : '';
50
+ const cacheKey = `pr-counts:v3:${label}:${githubUsername}${minStarsSuffix}`;
49
51
  const cached = cache.getIfFresh(cacheKey, PR_COUNTS_CACHE_TTL_MS);
50
52
  if (cached && isCachedPRCounts(cached)) {
51
53
  debug(MODULE, `Using cached ${label} PR counts for @${githubUsername}`);
@@ -66,7 +68,7 @@ async function fetchUserPRCounts(octokit, githubUsername, query, label, accumula
66
68
  let totalCount;
67
69
  while (true) {
68
70
  const { data } = await octokit.search.issuesAndPullRequests({
69
- q: `is:pr ${query} author:${githubUsername}`,
71
+ q: `is:pr ${query} author:${githubUsername} -user:${githubUsername}`,
70
72
  sort: 'updated',
71
73
  order: 'desc',
72
74
  per_page: 100,
@@ -86,6 +88,12 @@ async function fetchUserPRCounts(octokit, githubUsername, query, label, accumula
86
88
  continue;
87
89
  // Note: excludeRepos/excludeOrgs are intentionally NOT filtered here.
88
90
  // Those filters control issue discovery/search, not historical statistics.
91
+ // Skip repos below the minimum star threshold (#576).
92
+ // Repos with unknown star counts (not yet fetched) are included — they'll be
93
+ // filtered on the next run once star data is cached in repoScores.
94
+ if (starFilter && isBelowMinStars(starFilter.knownStarCounts.get(repo), starFilter.minStars)) {
95
+ continue;
96
+ }
89
97
  // Per-repo accumulation + get primary date for histograms
90
98
  const primaryDate = accumulateRepo(repos, repo, item);
91
99
  // Monthly histogram for primary date (merged/closed)
@@ -135,7 +143,7 @@ async function fetchUserPRCounts(octokit, githubUsername, query, label, accumula
135
143
  * Fetch merged PR counts and latest merge dates per repository for the configured user.
136
144
  * Also builds a monthly histogram of all merges for the contribution timeline.
137
145
  */
138
- export function fetchUserMergedPRCounts(octokit, githubUsername) {
146
+ export function fetchUserMergedPRCounts(octokit, githubUsername, starFilter) {
139
147
  return fetchUserPRCounts(octokit, githubUsername, 'is:merged', 'merged', (repos, repo, item) => {
140
148
  if (!item.pull_request?.merged_at) {
141
149
  warn(MODULE, `merged_at missing for merged PR ${item.html_url}${item.closed_at ? ', falling back to closed_at' : ', no date available'}`);
@@ -152,17 +160,17 @@ export function fetchUserMergedPRCounts(octokit, githubUsername) {
152
160
  repos.set(repo, { count: 1, lastMergedAt: mergedAt });
153
161
  }
154
162
  return mergedAt;
155
- });
163
+ }, starFilter);
156
164
  }
157
165
  /**
158
166
  * Fetch closed-without-merge PR counts per repository for the configured user.
159
167
  * Used to populate closedWithoutMergeCount in repo scores for accurate merge rate.
160
168
  */
161
- export function fetchUserClosedPRCounts(octokit, githubUsername) {
169
+ export function fetchUserClosedPRCounts(octokit, githubUsername, starFilter) {
162
170
  return fetchUserPRCounts(octokit, githubUsername, 'is:closed is:unmerged', 'closed', (repos, repo, item) => {
163
171
  repos.set(repo, (repos.get(repo) || 0) + 1);
164
172
  return item.closed_at || '';
165
- });
173
+ }, starFilter);
166
174
  }
167
175
  /**
168
176
  * Shared helper: search for recent PRs and filter out own repos, excluded repos/orgs.
@@ -8,8 +8,8 @@ export { IssueDiscovery, type IssueCandidate, type SearchPriority, isDocOnlyIssu
8
8
  export { IssueConversationMonitor } from './issue-conversation.js';
9
9
  export { isBotAuthor, isAcknowledgmentComment } from './comment-utils.js';
10
10
  export { getOctokit, checkRateLimit, type RateLimitInfo } from './github.js';
11
- export { parseGitHubUrl, daysBetween, splitRepo, isOwnRepo, getCLIVersion, getDataDir, getStatePath, getBackupDir, getCacheDir, getDashboardPath, formatRelativeTime, byDateDescending, getGitHubToken, getGitHubTokenAsync, requireGitHubToken, resetGitHubTokenCache, } from './utils.js';
12
- export { OssAutopilotError, ConfigurationError, ValidationError, errorMessage, getHttpStatusCode } from './errors.js';
11
+ export { parseGitHubUrl, daysBetween, splitRepo, isOwnRepo, getCLIVersion, getDataDir, getStatePath, getBackupDir, getCacheDir, getDashboardPath, formatRelativeTime, byDateDescending, getGitHubToken, getGitHubTokenAsync, requireGitHubToken, resetGitHubTokenCache, DEFAULT_CONCURRENCY, } from './utils.js';
12
+ export { OssAutopilotError, ConfigurationError, ValidationError, errorMessage, getHttpStatusCode, isRateLimitError, isRateLimitOrAuthError, } from './errors.js';
13
13
  export { enableDebug, isDebugEnabled, debug, info, warn, timed } from './logger.js';
14
14
  export { HttpCache, getHttpCache, cachedRequest, type CacheEntry } from './http-cache.js';
15
15
  export { CRITICAL_STATUSES, computeRepoSignals, groupPRsByRepo, assessCapacity, collectActionableIssues, computeActionMenu, toShelvedPRRef, formatActionHint, formatBriefSummary, formatSummary, printDigest, } from './daily-logic.js';
@@ -8,8 +8,8 @@ export { IssueDiscovery, isDocOnlyIssue, applyPerRepoCap, DOC_ONLY_LABELS, } fro
8
8
  export { IssueConversationMonitor } from './issue-conversation.js';
9
9
  export { isBotAuthor, isAcknowledgmentComment } from './comment-utils.js';
10
10
  export { getOctokit, checkRateLimit } from './github.js';
11
- export { parseGitHubUrl, daysBetween, splitRepo, isOwnRepo, getCLIVersion, getDataDir, getStatePath, getBackupDir, getCacheDir, getDashboardPath, formatRelativeTime, byDateDescending, getGitHubToken, getGitHubTokenAsync, requireGitHubToken, resetGitHubTokenCache, } from './utils.js';
12
- export { OssAutopilotError, ConfigurationError, ValidationError, errorMessage, getHttpStatusCode } from './errors.js';
11
+ export { parseGitHubUrl, daysBetween, splitRepo, isOwnRepo, getCLIVersion, getDataDir, getStatePath, getBackupDir, getCacheDir, getDashboardPath, formatRelativeTime, byDateDescending, getGitHubToken, getGitHubTokenAsync, requireGitHubToken, resetGitHubTokenCache, DEFAULT_CONCURRENCY, } from './utils.js';
12
+ export { OssAutopilotError, ConfigurationError, ValidationError, errorMessage, getHttpStatusCode, isRateLimitError, isRateLimitOrAuthError, } from './errors.js';
13
13
  export { enableDebug, isDebugEnabled, debug, info, warn, timed } from './logger.js';
14
14
  export { HttpCache, getHttpCache, cachedRequest } from './http-cache.js';
15
15
  export { CRITICAL_STATUSES, computeRepoSignals, groupPRsByRepo, assessCapacity, collectActionableIssues, computeActionMenu, toShelvedPRRef, formatActionHint, formatBriefSummary, formatSummary, printDigest, } from './daily-logic.js';
@@ -9,12 +9,12 @@ import { getOctokit } from './github.js';
9
9
  import { isBotAuthor, isAcknowledgmentComment } from './comment-utils.js';
10
10
  import { paginateAll } from './pagination.js';
11
11
  import { getStateManager } from './state.js';
12
- import { daysBetween, splitRepo, extractOwnerRepo, isOwnRepo } from './utils.js';
12
+ import { daysBetween, splitRepo, extractOwnerRepo, isOwnRepo, DEFAULT_CONCURRENCY } from './utils.js';
13
13
  import { runWorkerPool } from './concurrency.js';
14
14
  import { ConfigurationError, errorMessage } from './errors.js';
15
15
  import { debug, warn } from './logger.js';
16
16
  const MODULE = 'issue-conversation';
17
- const MAX_CONCURRENT_REQUESTS = 5;
17
+ const MAX_CONCURRENT_REQUESTS = DEFAULT_CONCURRENCY;
18
18
  /** Associations that indicate someone with repo-level permissions. */
19
19
  const MAINTAINER_ASSOCIATIONS = new Set(['OWNER', 'MEMBER', 'COLLABORATOR']);
20
20
  export class IssueConversationMonitor {
@@ -65,11 +65,6 @@ export declare class IssueDiscovery {
65
65
  * Split repos into batches of the specified size.
66
66
  */
67
67
  private batchRepos;
68
- /**
69
- * Check if an error is a GitHub rate limit error (429 or rate-limit 403).
70
- * Static proxy kept for backward compatibility with tests.
71
- */
72
- static isRateLimitError(error: unknown): boolean;
73
68
  /**
74
69
  * Vet a specific issue (delegates to IssueVetter).
75
70
  */
@@ -12,7 +12,7 @@ import { getOctokit, checkRateLimit } from './github.js';
12
12
  import { getStateManager } from './state.js';
13
13
  import { daysBetween, getDataDir } from './utils.js';
14
14
  import { DEFAULT_CONFIG } from './types.js';
15
- import { ValidationError, errorMessage, getHttpStatusCode } from './errors.js';
15
+ import { ValidationError, errorMessage, getHttpStatusCode, isRateLimitError } from './errors.js';
16
16
  import { debug, info, warn } from './logger.js';
17
17
  import { getHttpCache, cachedTimeBased } from './http-cache.js';
18
18
  import { isDocOnlyIssue, detectLabelFarmingRepos, applyPerRepoCap } from './issue-filtering.js';
@@ -328,7 +328,7 @@ export class IssueDiscovery {
328
328
  catch (error) {
329
329
  const errMsg = errorMessage(error);
330
330
  phase2Error = errMsg;
331
- if (IssueVetter.isRateLimitError(error)) {
331
+ if (isRateLimitError(error)) {
332
332
  rateLimitHitDuringSearch = true;
333
333
  }
334
334
  warn(MODULE, `Error in general issue search: ${errMsg}`);
@@ -370,7 +370,7 @@ export class IssueDiscovery {
370
370
  catch (error) {
371
371
  const errMsg = errorMessage(error);
372
372
  phase3Error = errMsg;
373
- if (IssueVetter.isRateLimitError(error)) {
373
+ if (isRateLimitError(error)) {
374
374
  rateLimitHitDuringSearch = true;
375
375
  }
376
376
  warn(MODULE, `Error in maintained-repo search: ${errMsg}`);
@@ -464,7 +464,7 @@ export class IssueDiscovery {
464
464
  }
465
465
  catch (error) {
466
466
  failedBatches++;
467
- if (IssueVetter.isRateLimitError(error)) {
467
+ if (isRateLimitError(error)) {
468
468
  rateLimitFailures++;
469
469
  }
470
470
  const batchRepos = batch.join(', ');
@@ -489,13 +489,6 @@ export class IssueDiscovery {
489
489
  }
490
490
  return batches;
491
491
  }
492
- /**
493
- * Check if an error is a GitHub rate limit error (429 or rate-limit 403).
494
- * Static proxy kept for backward compatibility with tests.
495
- */
496
- static isRateLimitError(error) {
497
- return IssueVetter.isRateLimitError(error);
498
- }
499
492
  /**
500
493
  * Vet a specific issue (delegates to IssueVetter).
501
494
  */
@@ -29,8 +29,6 @@ export declare class IssueVetter {
29
29
  allFailed: boolean;
30
30
  rateLimitHit: boolean;
31
31
  }>;
32
- /** Check if an error is a GitHub rate limit error (429 or rate-limit 403). */
33
- static isRateLimitError(error: unknown): boolean;
34
32
  checkNoExistingPR(owner: string, repo: string, issueNumber: number): Promise<CheckResult>;
35
33
  /**
36
34
  * Check how many merged PRs the authenticated user has in a repo.
@@ -5,14 +5,13 @@
5
5
  * Extracted from issue-discovery.ts (#356) to isolate vetting logic.
6
6
  */
7
7
  import { paginateAll } from './pagination.js';
8
- import { parseGitHubUrl, daysBetween } from './utils.js';
9
- import { ValidationError, errorMessage, getHttpStatusCode } from './errors.js';
8
+ import { parseGitHubUrl, daysBetween, DEFAULT_CONCURRENCY } from './utils.js';
9
+ import { ValidationError, errorMessage, isRateLimitError } from './errors.js';
10
10
  import { warn } from './logger.js';
11
11
  import { getHttpCache, cachedRequest, cachedTimeBased } from './http-cache.js';
12
12
  import { calculateRepoQualityBonus, calculateViabilityScore } from './issue-scoring.js';
13
13
  const MODULE = 'issue-vetting';
14
- // Concurrency limit for parallel API calls
15
- const MAX_CONCURRENT_REQUESTS = 5;
14
+ const MAX_CONCURRENT_REQUESTS = DEFAULT_CONCURRENCY;
16
15
  // Cache for contribution guidelines (expires after 1 hour, max 100 entries)
17
16
  const guidelinesCache = new Map();
18
17
  const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
@@ -233,7 +232,7 @@ export class IssueVetter {
233
232
  */
234
233
  async vetIssuesParallel(urls, maxResults, priority) {
235
234
  const candidates = [];
236
- const pending = [];
235
+ const pending = new Map();
237
236
  let failedVettingCount = 0;
238
237
  let rateLimitFailures = 0;
239
238
  let attemptedCount = 0;
@@ -253,21 +252,20 @@ export class IssueVetter {
253
252
  })
254
253
  .catch((error) => {
255
254
  failedVettingCount++;
256
- if (IssueVetter.isRateLimitError(error)) {
255
+ if (isRateLimitError(error)) {
257
256
  rateLimitFailures++;
258
257
  }
259
258
  warn(MODULE, `Error vetting issue ${url}:`, errorMessage(error));
260
- });
261
- pending.push(task);
262
- // Limit concurrency
263
- if (pending.length >= MAX_CONCURRENT_REQUESTS) {
264
- // Wait for at least one to complete, then remove it
265
- const completed = await Promise.race(pending.map((p, i) => p.then(() => i)));
266
- pending.splice(completed, 1);
259
+ })
260
+ .finally(() => pending.delete(url));
261
+ pending.set(url, task);
262
+ // Limit concurrency wait for at least one to complete before launching more
263
+ if (pending.size >= MAX_CONCURRENT_REQUESTS) {
264
+ await Promise.race(pending.values());
267
265
  }
268
266
  }
269
267
  // Wait for remaining
270
- await Promise.allSettled(pending);
268
+ await Promise.allSettled(pending.values());
271
269
  const allFailed = failedVettingCount === attemptedCount && attemptedCount > 0;
272
270
  if (allFailed) {
273
271
  warn(MODULE, `All ${attemptedCount} issue(s) failed vetting. ` +
@@ -275,17 +273,6 @@ export class IssueVetter {
275
273
  }
276
274
  return { candidates: candidates.slice(0, maxResults), allFailed, rateLimitHit: rateLimitFailures > 0 };
277
275
  }
278
- /** Check if an error is a GitHub rate limit error (429 or rate-limit 403). */
279
- static isRateLimitError(error) {
280
- const status = getHttpStatusCode(error);
281
- if (status === 429)
282
- return true;
283
- if (status === 403) {
284
- const msg = errorMessage(error).toLowerCase();
285
- return msg.includes('rate limit');
286
- }
287
- return false;
288
- }
289
276
  async checkNoExistingPR(owner, repo, issueNumber) {
290
277
  try {
291
278
  // Search for PRs that mention this issue
@@ -447,26 +434,25 @@ export class IssueVetter {
447
434
  return cached.guidelines;
448
435
  }
449
436
  const filesToCheck = ['CONTRIBUTING.md', '.github/CONTRIBUTING.md', 'docs/CONTRIBUTING.md', 'contributing.md'];
450
- for (const file of filesToCheck) {
451
- try {
452
- const { data } = await this.octokit.repos.getContent({
453
- owner,
454
- repo,
455
- path: file,
456
- });
457
- if ('content' in data) {
458
- const content = Buffer.from(data.content, 'base64').toString('utf-8');
459
- const guidelines = this.parseContributionGuidelines(content);
460
- // Cache the result and prune if needed
461
- guidelinesCache.set(cacheKey, { guidelines, fetchedAt: Date.now() });
462
- pruneCache();
463
- return guidelines;
464
- }
437
+ // Probe all paths in parallel — take the first success in priority order
438
+ const results = await Promise.allSettled(filesToCheck.map((file) => this.octokit.repos.getContent({ owner, repo, path: file }).then(({ data }) => {
439
+ if ('content' in data) {
440
+ return Buffer.from(data.content, 'base64').toString('utf-8');
441
+ }
442
+ return null;
443
+ })));
444
+ for (let i = 0; i < results.length; i++) {
445
+ const result = results[i];
446
+ if (result.status === 'fulfilled' && result.value) {
447
+ const guidelines = this.parseContributionGuidelines(result.value);
448
+ guidelinesCache.set(cacheKey, { guidelines, fetchedAt: Date.now() });
449
+ pruneCache();
450
+ return guidelines;
465
451
  }
466
- catch (error) {
467
- // File not found is expected; only log unexpected errors
468
- if (error instanceof Error && !error.message.includes('404') && !error.message.includes('Not Found')) {
469
- warn(MODULE, `Unexpected error fetching ${file} from ${owner}/${repo}: ${error.message}`);
452
+ if (result.status === 'rejected') {
453
+ const msg = result.reason instanceof Error ? result.reason.message : String(result.reason);
454
+ if (!msg.includes('404') && !msg.includes('Not Found')) {
455
+ warn(MODULE, `Unexpected error fetching ${filesToCheck[i]} from ${owner}/${repo}: ${msg}`);
470
456
  }
471
457
  }
472
458
  }
@@ -523,7 +509,7 @@ export class IssueVetter {
523
509
  if (!body || body.length < 50)
524
510
  return false;
525
511
  // Check for clear structure
526
- const hasSteps = /\d+\.|[-*]\s/.test(body);
512
+ const hasSteps = /\d\.|[-*]\s/.test(body);
527
513
  const hasCodeBlock = /```/.test(body);
528
514
  const hasExpectedBehavior = /expect|should|must|want/i.test(body);
529
515
  // Must have at least two indicators of clarity
@@ -11,7 +11,7 @@
11
11
  * - display-utils.ts: Display label computation
12
12
  * - github-stats.ts: Merged/closed PR counts and star fetching
13
13
  */
14
- import { FetchedPR, DailyDigest, ClosedPR, MergedPR } from './types.js';
14
+ import { FetchedPR, DailyDigest, ClosedPR, MergedPR, StarFilter } from './types.js';
15
15
  import { type PRCountsResult } from './github-stats.js';
16
16
  export { computeDisplayLabel } from './display-utils.js';
17
17
  export { classifyCICheck, classifyFailingChecks } from './ci-analysis.js';
@@ -46,6 +46,29 @@ export declare class PRMonitor {
46
46
  * Determine the overall status of a PR
47
47
  */
48
48
  private determineStatus;
49
+ /**
50
+ * CI-fix bots that push commits as a direct result of the contributor's push (#568).
51
+ * Their commits represent contributor work and should count as addressing feedback.
52
+ * This is intentionally an allowlist — not all `[bot]` accounts are CI-fix bots
53
+ * (e.g. dependabot[bot] and renovate[bot] open their own PRs).
54
+ * Values must be lowercase — lookup uses .toLowerCase() for case-insensitive matching.
55
+ */
56
+ private static readonly CI_FIX_BOTS;
57
+ /**
58
+ * Check whether the HEAD commit was authored by the contributor (#547).
59
+ * Returns true when the author matches, when the author is a known CI-fix
60
+ * bot (#568), or when author info is unavailable (graceful degradation).
61
+ */
62
+ private isContributorCommit;
63
+ /** Minimum gap (ms) between maintainer comment and contributor commit for
64
+ * the commit to count as "addressing" the feedback (#547). Prevents false
65
+ * positives from race conditions, clock skew, and in-flight pushes. */
66
+ private static readonly MIN_RESPONSE_GAP_MS;
67
+ /**
68
+ * Check whether the contributor's commit is meaningfully after the maintainer's
69
+ * comment — i.e. the commit timestamp is at least MIN_RESPONSE_GAP_MS later (#547).
70
+ */
71
+ private isCommitAfterComment;
49
72
  /**
50
73
  * Check if PR has merge conflict
51
74
  */
@@ -60,7 +83,7 @@ export declare class PRMonitor {
60
83
  * Fetch merged PR counts and latest merge dates per repository for the configured user.
61
84
  * Delegates to github-stats module.
62
85
  */
63
- fetchUserMergedPRCounts(): Promise<PRCountsResult<{
86
+ fetchUserMergedPRCounts(starFilter?: StarFilter): Promise<PRCountsResult<{
64
87
  count: number;
65
88
  lastMergedAt: string;
66
89
  }>>;
@@ -68,7 +91,7 @@ export declare class PRMonitor {
68
91
  * Fetch closed-without-merge PR counts per repository for the configured user.
69
92
  * Delegates to github-stats module.
70
93
  */
71
- fetchUserClosedPRCounts(): Promise<PRCountsResult<number>>;
94
+ fetchUserClosedPRCounts(starFilter?: StarFilter): Promise<PRCountsResult<number>>;
72
95
  /**
73
96
  * Fetch GitHub star counts for a list of repositories.
74
97
  * Delegates to github-stats module.