@pratik7368patil/anchor-core 0.1.12 → 0.1.13

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/index.d.ts CHANGED
@@ -244,6 +244,14 @@ type FetchPullRequestsProgress = {
244
244
  total: number;
245
245
  prNumber: number;
246
246
  detailConcurrency: number;
247
+ } | {
248
+ stage: "github_rate_limited";
249
+ repo: string;
250
+ waitSeconds: number;
251
+ retryAt: string;
252
+ reason: string;
253
+ request: string;
254
+ attempt: number;
247
255
  };
248
256
  type IndexPullRequestsProgress = {
249
257
  stage: "indexing_pull_request";
@@ -738,6 +746,45 @@ declare const DEMO_CODE_FILES: Record<string, string>;
738
746
 
739
747
  declare function createGitHubClient(token: string): Octokit;
740
748
 
749
+ type GitHubRateLimitProgress = {
750
+ waitSeconds: number;
751
+ retryAt: string;
752
+ reason: string;
753
+ request: string;
754
+ attempt: number;
755
+ };
756
+ type GitHubRateLimitController = {
757
+ onRateLimit?: (progress: GitHubRateLimitProgress) => void;
758
+ sleep?: (milliseconds: number) => Promise<void>;
759
+ now?: () => number;
760
+ blockedUntilMs?: number;
761
+ };
762
+ type GitHubRateLimitErrorLike = {
763
+ status?: number;
764
+ message?: string;
765
+ response?: {
766
+ headers?: Record<string, string | number | undefined>;
767
+ };
768
+ };
769
+ type GitHubResponse<T> = {
770
+ data: T;
771
+ headers: Record<string, string | number | undefined>;
772
+ };
773
+ declare function isGitHubRateLimitError(error: unknown): error is GitHubRateLimitErrorLike;
774
+ declare function getGitHubRateLimitDelayMs(error: GitHubRateLimitErrorLike, attempt: number, now?: number): {
775
+ delayMs: number;
776
+ reason: string;
777
+ };
778
+ declare function requestWithGitHubRateLimit<T>(request: () => Promise<T>, options: {
779
+ controller: GitHubRateLimitController;
780
+ requestName: string;
781
+ maxRetries?: number;
782
+ }): Promise<T>;
783
+ declare function paginateWithGitHubRateLimit<T>(requestPage: (page: number) => Promise<GitHubResponse<T[]>>, options: {
784
+ controller: GitHubRateLimitController;
785
+ requestName: string;
786
+ }): Promise<T[]>;
787
+
741
788
  type FetchPullRequestsOptions = {
742
789
  token: string;
743
790
  repo: string;
@@ -751,7 +798,7 @@ declare function resolvePullRequestFetchLimit(options: Pick<FetchPullRequestsOpt
751
798
  declare function resolvePullRequestDetailConcurrency(options: Pick<FetchPullRequestsOptions, "detailConcurrency">): number;
752
799
  declare function fetchMergedPullRequests(options: FetchPullRequestsOptions): Promise<PullRequestRecord[]>;
753
800
 
754
- declare function fetchPullRequestDetails(octokit: Octokit, repoFullName: string, pullNumber: number): Promise<PullRequestRecord>;
801
+ declare function fetchPullRequestDetails(octokit: Octokit, repoFullName: string, pullNumber: number, controller?: GitHubRateLimitController): Promise<PullRequestRecord>;
755
802
 
756
803
  type DoctorOptions = {
757
804
  cwd: string;
@@ -766,4 +813,4 @@ declare function getAnchorIndexHealth(cwd: string): AnchorIndexHealth & {
766
813
  indexStatus: IndexStatus;
767
814
  };
768
815
 
769
- export { ANCHOR_CURSOR_RULE, type AnchorContextInput, type AnchorDatabase, type AnchorExplainFileInput, type AnchorIndexHealth, type AnchorReviewDiffInput, type ArchitectureArea, type ArchitectureCheckInput, type ArchitectureComponent, type ArchitectureContextInput, type ArchitectureIndexData, type ArchitecturePattern, type ArchitectureQueryInput, type ChunkableCodeFile, type CodeChunk, type CodeFileDiscoveryResult, type CodeFileRecord, type CodeImport, type CodeIndexProgress, type CodeIndexSummary, type ConfidenceLevel, type CoverageGrade, type CoverageInput, type CoverageReport, type CurrentCodeSnapshot, type CursorMcpConfig, DEFAULT_MAX_CODE_FILE_BYTES, DEMO_CODE_FILES, DEMO_PULL_REQUESTS, DEMO_REPO, type DiscoveredCodeFile, type DoctorCheck, type DoctorOptions, type DoctorReport, type EvidenceRef, type FetchPullRequestsOptions, type FetchPullRequestsProgress, type FormattedResult, type FreshnessResult, type FreshnessStatus, type GitHubRepo, type GitHubTokenResolution, type GitHubTokenResolverOptions, type GitHubTokenSource, type IndexPullRequestsProgress, type IndexRunRecord, type IndexStatus, type IndexSummary, type LocalEmbeddingProvider, type PullRequestComment, type PullRequestCommit, type PullRequestFile, type PullRequestPerson, type PullRequestRecord, type RankedArchitecturePattern, type RankedCodeChunk, type RankedRegressionEvent, type RankedTeamRule, type RankedTestFile, type RankedWisdomUnit, type RegressionEvent, type RulesAddInput, type RulesAddResult, type RulesEvidenceCheckResult, type RulesInitResult, type RulesSuggestOptions, SCHEMA_SQL, type SearchHistoryInput, type SemanticStatus, type SourceType, type SuggestedPrompt, TEAM_RULES_FILE, type TeamRule, type TeamRuleSuggestion, type TeamRulesValidationResult, type TestFileRecord, type TestLink, type WisdomCategory, type WisdomUnit, addTeamRule, anchorMcpEntry, architectureFilesFromDiff, buildAnchorContextResult, buildArchitectureIndex, buildFtsQuery, buildQueryTerms, calculateCoverage, canonicalizeText, categorizeWisdom, checkArchitecture, checkSchema, checkTeamRuleEvidence, chunkCodeFile, chunkHistoricalText, claimKeyFor, clampMaxResults, classifyArchitectureArea, clipSentence, confidenceAtLeast, confidenceLevelFor, confidenceRank, confidenceReasonsFor, countValidTeamRules, createGitHubClient, defaultDatabasePath, detectGitHubRepo, detectGitRoot, discoverCodeFiles, emptyCodeIndexSummary, ensureAnchorGitExclude, ensureCursorConfig, ensureCursorRule, ensureRepository, ensureTeamRulesFile, evaluateFreshness, evaluateIndexHealth, evidenceForWisdom, explainFile, extractCodeImports, extractCodeSymbols, extractRegressionEvents, extractSymbols, extractWisdomUnits, fetchMergedPullRequests, fetchPullRequestDetails, filesFromDiff, formatAnchorContext, formatIndexStatus, formatSearchHistory, getAnchorIndexHealth, getArchitectureContext, getIndexStatus, getLastSyncTime, getSemanticStatus, getSuggestedPromptTexts, getSuggestedPrompts, getWisdomCategoryCounts, githubAuthFixMessage, hasHighSignalLanguage, indexCodebase, indexPullRequests, inferTestAwareness, initializeSchema, isHardExcludedCodePath, isTestFilePath, loadCurrentCodeSnapshot, loadTeamRulesFile, mergeAnchorMcpConfig, normalizePullRequest, openAnchorDatabase, parseGitHubRemote, rankArchitecturePatterns, rankCodeChunks, rankRegressionEvents, rankRelevantTests, rankTeamRules, rankWisdomUnits, recordIndexRun, redactSecrets, redactedHistoricalText, replaceCodeIndex, resolveGitHubToken, resolvePullRequestDetailConcurrency, resolvePullRequestFetchLimit, reviewDiff, runDoctor, sanitizeHistoricalText, shouldSyncSince, sourceTypeLabel, stripPromptInjection, suggestTeamRules, tokenizeSearchText, truncateText, uniqueStrings, updateSyncState, upsertPullRequest, validateTeamRulesFile };
816
+ export { ANCHOR_CURSOR_RULE, type AnchorContextInput, type AnchorDatabase, type AnchorExplainFileInput, type AnchorIndexHealth, type AnchorReviewDiffInput, type ArchitectureArea, type ArchitectureCheckInput, type ArchitectureComponent, type ArchitectureContextInput, type ArchitectureIndexData, type ArchitecturePattern, type ArchitectureQueryInput, type ChunkableCodeFile, type CodeChunk, type CodeFileDiscoveryResult, type CodeFileRecord, type CodeImport, type CodeIndexProgress, type CodeIndexSummary, type ConfidenceLevel, type CoverageGrade, type CoverageInput, type CoverageReport, type CurrentCodeSnapshot, type CursorMcpConfig, DEFAULT_MAX_CODE_FILE_BYTES, DEMO_CODE_FILES, DEMO_PULL_REQUESTS, DEMO_REPO, type DiscoveredCodeFile, type DoctorCheck, type DoctorOptions, type DoctorReport, type EvidenceRef, type FetchPullRequestsOptions, type FetchPullRequestsProgress, type FormattedResult, type FreshnessResult, type FreshnessStatus, type GitHubRateLimitController, type GitHubRateLimitErrorLike, type GitHubRateLimitProgress, type GitHubRepo, type GitHubTokenResolution, type GitHubTokenResolverOptions, type GitHubTokenSource, type IndexPullRequestsProgress, type IndexRunRecord, type IndexStatus, type IndexSummary, type LocalEmbeddingProvider, type PullRequestComment, type PullRequestCommit, type PullRequestFile, type PullRequestPerson, type PullRequestRecord, type RankedArchitecturePattern, type RankedCodeChunk, type RankedRegressionEvent, type RankedTeamRule, type RankedTestFile, type RankedWisdomUnit, type RegressionEvent, type RulesAddInput, type RulesAddResult, type RulesEvidenceCheckResult, type RulesInitResult, type RulesSuggestOptions, SCHEMA_SQL, type SearchHistoryInput, type SemanticStatus, type SourceType, type SuggestedPrompt, TEAM_RULES_FILE, type TeamRule, type TeamRuleSuggestion, type TeamRulesValidationResult, type TestFileRecord, type TestLink, type WisdomCategory, type WisdomUnit, addTeamRule, anchorMcpEntry, architectureFilesFromDiff, buildAnchorContextResult, buildArchitectureIndex, buildFtsQuery, buildQueryTerms, calculateCoverage, canonicalizeText, categorizeWisdom, checkArchitecture, checkSchema, checkTeamRuleEvidence, chunkCodeFile, chunkHistoricalText, claimKeyFor, clampMaxResults, classifyArchitectureArea, clipSentence, confidenceAtLeast, confidenceLevelFor, confidenceRank, confidenceReasonsFor, countValidTeamRules, createGitHubClient, defaultDatabasePath, detectGitHubRepo, detectGitRoot, discoverCodeFiles, emptyCodeIndexSummary, ensureAnchorGitExclude, ensureCursorConfig, ensureCursorRule, ensureRepository, ensureTeamRulesFile, evaluateFreshness, evaluateIndexHealth, evidenceForWisdom, explainFile, extractCodeImports, extractCodeSymbols, extractRegressionEvents, extractSymbols, extractWisdomUnits, fetchMergedPullRequests, fetchPullRequestDetails, filesFromDiff, formatAnchorContext, formatIndexStatus, formatSearchHistory, getAnchorIndexHealth, getArchitectureContext, getGitHubRateLimitDelayMs, getIndexStatus, getLastSyncTime, getSemanticStatus, getSuggestedPromptTexts, getSuggestedPrompts, getWisdomCategoryCounts, githubAuthFixMessage, hasHighSignalLanguage, indexCodebase, indexPullRequests, inferTestAwareness, initializeSchema, isGitHubRateLimitError, isHardExcludedCodePath, isTestFilePath, loadCurrentCodeSnapshot, loadTeamRulesFile, mergeAnchorMcpConfig, normalizePullRequest, openAnchorDatabase, paginateWithGitHubRateLimit, parseGitHubRemote, rankArchitecturePatterns, rankCodeChunks, rankRegressionEvents, rankRelevantTests, rankTeamRules, rankWisdomUnits, recordIndexRun, redactSecrets, redactedHistoricalText, replaceCodeIndex, requestWithGitHubRateLimit, resolveGitHubToken, resolvePullRequestDetailConcurrency, resolvePullRequestFetchLimit, reviewDiff, runDoctor, sanitizeHistoricalText, shouldSyncSince, sourceTypeLabel, stripPromptInjection, suggestTeamRules, tokenizeSearchText, truncateText, uniqueStrings, updateSyncState, upsertPullRequest, validateTeamRulesFile };
package/dist/index.js CHANGED
@@ -4554,28 +4554,168 @@ function createGitHubClient(token) {
4554
4554
  });
4555
4555
  }
4556
4556
 
4557
+ // src/github/rate-limit.ts
4558
+ function isGitHubRateLimitError(error) {
4559
+ const candidate = error;
4560
+ if (candidate.status !== 403 && candidate.status !== 429) return false;
4561
+ const message = candidate.message?.toLowerCase() ?? "";
4562
+ const headers = candidate.response?.headers ?? {};
4563
+ return candidate.status === 429 || headers["retry-after"] !== void 0 || headers["x-ratelimit-remaining"] === "0" || message.includes("rate limit") || message.includes("secondary limit");
4564
+ }
4565
+ function getGitHubRateLimitDelayMs(error, attempt, now = Date.now()) {
4566
+ const headers = error.response?.headers ?? {};
4567
+ const retryAfter = Number(headers["retry-after"]);
4568
+ if (Number.isFinite(retryAfter) && retryAfter > 0) {
4569
+ return {
4570
+ delayMs: Math.ceil(retryAfter * 1e3),
4571
+ reason: `retry-after header requested ${Math.ceil(retryAfter)} seconds`
4572
+ };
4573
+ }
4574
+ const remaining = String(headers["x-ratelimit-remaining"] ?? "");
4575
+ const reset = Number(headers["x-ratelimit-reset"]);
4576
+ if (remaining === "0" && Number.isFinite(reset) && reset > 0) {
4577
+ const resetDelayMs = Math.max(0, reset * 1e3 - now);
4578
+ return {
4579
+ delayMs: Math.ceil(resetDelayMs + 2e3),
4580
+ reason: `primary rate limit resets at ${new Date(reset * 1e3).toISOString()}`
4581
+ };
4582
+ }
4583
+ const backoffSeconds = Math.min(900, 60 * 2 ** Math.max(0, attempt - 1));
4584
+ return {
4585
+ delayMs: backoffSeconds * 1e3,
4586
+ reason: `secondary rate limit backoff for ${backoffSeconds} seconds`
4587
+ };
4588
+ }
4589
+ async function sleep(milliseconds) {
4590
+ await new Promise((resolve) => setTimeout(resolve, milliseconds));
4591
+ }
4592
+ async function waitForGlobalBlock(controller) {
4593
+ const now = controller.now?.() ?? Date.now();
4594
+ const waitMs = Math.max(0, (controller.blockedUntilMs ?? 0) - now);
4595
+ if (waitMs > 0) {
4596
+ await (controller.sleep ?? sleep)(waitMs);
4597
+ }
4598
+ }
4599
+ async function requestWithGitHubRateLimit(request, options) {
4600
+ const maxRetries = options.maxRetries ?? 8;
4601
+ for (let attempt = 1; ; attempt += 1) {
4602
+ await waitForGlobalBlock(options.controller);
4603
+ try {
4604
+ return await request();
4605
+ } catch (error) {
4606
+ if (!isGitHubRateLimitError(error) || attempt > maxRetries) throw error;
4607
+ const now = options.controller.now?.() ?? Date.now();
4608
+ const { delayMs, reason } = getGitHubRateLimitDelayMs(error, attempt, now);
4609
+ const retryAtMs = now + delayMs;
4610
+ options.controller.blockedUntilMs = Math.max(
4611
+ options.controller.blockedUntilMs ?? 0,
4612
+ retryAtMs
4613
+ );
4614
+ options.controller.onRateLimit?.({
4615
+ waitSeconds: Math.ceil(delayMs / 1e3),
4616
+ retryAt: new Date(retryAtMs).toISOString(),
4617
+ reason,
4618
+ request: options.requestName,
4619
+ attempt
4620
+ });
4621
+ await (options.controller.sleep ?? sleep)(delayMs);
4622
+ }
4623
+ }
4624
+ }
4625
+ function hasNextPage(headers) {
4626
+ return String(headers.link ?? "").includes('rel="next"');
4627
+ }
4628
+ async function paginateWithGitHubRateLimit(requestPage, options) {
4629
+ const results = [];
4630
+ for (let page = 1; ; page += 1) {
4631
+ const response = await requestWithGitHubRateLimit(() => requestPage(page), {
4632
+ controller: options.controller,
4633
+ requestName: `${options.requestName} page ${page}`
4634
+ });
4635
+ results.push(...response.data);
4636
+ if (!hasNextPage(response.headers) && response.data.length < 100) break;
4637
+ if (!hasNextPage(response.headers) && response.data.length === 0) break;
4638
+ if (!hasNextPage(response.headers)) break;
4639
+ }
4640
+ return results;
4641
+ }
4642
+
4557
4643
  // src/github/fetch-pr-details.ts
4558
- async function fetchPullRequestDetails(octokit, repoFullName, pullNumber) {
4644
+ async function fetchPullRequestDetails(octokit, repoFullName, pullNumber, controller = {}) {
4559
4645
  const [owner, repo] = repoFullName.split("/");
4560
4646
  if (!owner || !repo) throw new Error(`Invalid repo '${repoFullName}'. Expected owner/name.`);
4561
- const [{ data: pull }, files, reviews, reviewComments, issueComments, commits] = await Promise.all([
4562
- octokit.pulls.get({ owner, repo, pull_number: pullNumber }),
4563
- octokit.paginate(octokit.pulls.listFiles, { owner, repo, pull_number: pullNumber, per_page: 100 }),
4564
- octokit.paginate(octokit.pulls.listReviews, { owner, repo, pull_number: pullNumber, per_page: 100 }),
4565
- octokit.paginate(octokit.pulls.listReviewComments, {
4647
+ const { data: pull } = await requestWithGitHubRateLimit(
4648
+ () => octokit.pulls.get({ owner, repo, pull_number: pullNumber }),
4649
+ {
4650
+ controller,
4651
+ requestName: `GET /repos/${repoFullName}/pulls/${pullNumber}`
4652
+ }
4653
+ );
4654
+ const files = await paginateWithGitHubRateLimit(
4655
+ (page) => octokit.pulls.listFiles({
4656
+ owner,
4657
+ repo,
4658
+ pull_number: pullNumber,
4659
+ per_page: 100,
4660
+ page
4661
+ }),
4662
+ {
4663
+ controller,
4664
+ requestName: `GET /repos/${repoFullName}/pulls/${pullNumber}/files`
4665
+ }
4666
+ );
4667
+ const reviews = await paginateWithGitHubRateLimit(
4668
+ (page) => octokit.pulls.listReviews({
4566
4669
  owner,
4567
4670
  repo,
4568
4671
  pull_number: pullNumber,
4569
- per_page: 100
4672
+ per_page: 100,
4673
+ page
4570
4674
  }),
4571
- octokit.paginate(octokit.issues.listComments, {
4675
+ {
4676
+ controller,
4677
+ requestName: `GET /repos/${repoFullName}/pulls/${pullNumber}/reviews`
4678
+ }
4679
+ );
4680
+ const reviewComments = await paginateWithGitHubRateLimit(
4681
+ (page) => octokit.pulls.listReviewComments({
4682
+ owner,
4683
+ repo,
4684
+ pull_number: pullNumber,
4685
+ per_page: 100,
4686
+ page
4687
+ }),
4688
+ {
4689
+ controller,
4690
+ requestName: `GET /repos/${repoFullName}/pulls/${pullNumber}/comments`
4691
+ }
4692
+ );
4693
+ const issueComments = await paginateWithGitHubRateLimit(
4694
+ (page) => octokit.issues.listComments({
4572
4695
  owner,
4573
4696
  repo,
4574
4697
  issue_number: pullNumber,
4575
- per_page: 100
4698
+ per_page: 100,
4699
+ page
4576
4700
  }),
4577
- octokit.paginate(octokit.pulls.listCommits, { owner, repo, pull_number: pullNumber, per_page: 100 })
4578
- ]);
4701
+ {
4702
+ controller,
4703
+ requestName: `GET /repos/${repoFullName}/issues/${pullNumber}/comments`
4704
+ }
4705
+ );
4706
+ const commits = await paginateWithGitHubRateLimit(
4707
+ (page) => octokit.pulls.listCommits({
4708
+ owner,
4709
+ repo,
4710
+ pull_number: pullNumber,
4711
+ per_page: 100,
4712
+ page
4713
+ }),
4714
+ {
4715
+ controller,
4716
+ requestName: `GET /repos/${repoFullName}/pulls/${pullNumber}/commits`
4717
+ }
4718
+ );
4579
4719
  return {
4580
4720
  repo: repoFullName,
4581
4721
  number: pull.number,
@@ -4648,7 +4788,12 @@ async function fetchPullRequestDetailsConcurrently(options) {
4648
4788
  prNumber: pullNumber,
4649
4789
  detailConcurrency: options.detailConcurrency
4650
4790
  });
4651
- results[index] = await fetchPullRequestDetails(options.octokit, options.repo, pullNumber);
4791
+ results[index] = await fetchPullRequestDetails(
4792
+ options.octokit,
4793
+ options.repo,
4794
+ pullNumber,
4795
+ options.controller
4796
+ );
4652
4797
  completed += 1;
4653
4798
  options.onProgress?.({
4654
4799
  stage: "fetched_pull_request_details",
@@ -4674,10 +4819,18 @@ async function fetchMergedPullRequests(options) {
4674
4819
  const octokit = createGitHubClient(options.token);
4675
4820
  const limit = resolvePullRequestFetchLimit(options);
4676
4821
  const detailConcurrency = resolvePullRequestDetailConcurrency(options);
4822
+ const rateLimitController = {
4823
+ onRateLimit: (progress) => options.onProgress?.({
4824
+ stage: "github_rate_limited",
4825
+ repo: options.repo,
4826
+ ...progress
4827
+ })
4828
+ };
4677
4829
  const sinceTime = options.since ? Date.parse(options.since) : void 0;
4678
4830
  const pullNumbers = [];
4679
4831
  let scannedPullRequests = 0;
4680
4832
  let reachedSinceBoundary = false;
4833
+ let page = 1;
4681
4834
  options.onProgress?.({
4682
4835
  stage: "discovering_pull_requests",
4683
4836
  repo: options.repo,
@@ -4685,14 +4838,22 @@ async function fetchMergedPullRequests(options) {
4685
4838
  limit,
4686
4839
  since: options.since
4687
4840
  });
4688
- for await (const response of octokit.paginate.iterator(octokit.pulls.list, {
4689
- owner,
4690
- repo,
4691
- state: "closed",
4692
- sort: "updated",
4693
- direction: "desc",
4694
- per_page: 100
4695
- })) {
4841
+ while (true) {
4842
+ const response = await requestWithGitHubRateLimit(
4843
+ () => octokit.pulls.list({
4844
+ owner,
4845
+ repo,
4846
+ state: "closed",
4847
+ sort: "updated",
4848
+ direction: "desc",
4849
+ per_page: 100,
4850
+ page
4851
+ }),
4852
+ {
4853
+ controller: rateLimitController,
4854
+ requestName: `GET /repos/${options.repo}/pulls page ${page}`
4855
+ }
4856
+ );
4696
4857
  scannedPullRequests += response.data.length;
4697
4858
  for (const pull of response.data) {
4698
4859
  if (sinceTime && Date.parse(pull.updated_at) < sinceTime) {
@@ -4711,7 +4872,11 @@ async function fetchMergedPullRequests(options) {
4711
4872
  scannedPullRequests,
4712
4873
  matchedMergedPullRequests: pullNumbers.length
4713
4874
  });
4714
- if (reachedSinceBoundary || limit !== void 0 && pullNumbers.length >= limit) break;
4875
+ const hasNextPage2 = String(response.headers.link ?? "").includes('rel="next"');
4876
+ if (reachedSinceBoundary || limit !== void 0 && pullNumbers.length >= limit || !hasNextPage2) {
4877
+ break;
4878
+ }
4879
+ page += 1;
4715
4880
  }
4716
4881
  options.onProgress?.({
4717
4882
  stage: "discovered_pull_requests",
@@ -4726,6 +4891,7 @@ async function fetchMergedPullRequests(options) {
4726
4891
  repo: options.repo,
4727
4892
  pullNumbers,
4728
4893
  detailConcurrency,
4894
+ controller: rateLimitController,
4729
4895
  onProgress: options.onProgress
4730
4896
  });
4731
4897
  }
@@ -4974,6 +5140,7 @@ export {
4974
5140
  formatSearchHistory,
4975
5141
  getAnchorIndexHealth,
4976
5142
  getArchitectureContext,
5143
+ getGitHubRateLimitDelayMs,
4977
5144
  getIndexStatus,
4978
5145
  getLastSyncTime,
4979
5146
  getSemanticStatus,
@@ -4986,6 +5153,7 @@ export {
4986
5153
  indexPullRequests,
4987
5154
  inferTestAwareness,
4988
5155
  initializeSchema,
5156
+ isGitHubRateLimitError,
4989
5157
  isHardExcludedCodePath,
4990
5158
  isTestFilePath,
4991
5159
  loadCurrentCodeSnapshot,
@@ -4993,6 +5161,7 @@ export {
4993
5161
  mergeAnchorMcpConfig,
4994
5162
  normalizePullRequest,
4995
5163
  openAnchorDatabase,
5164
+ paginateWithGitHubRateLimit,
4996
5165
  parseGitHubRemote,
4997
5166
  rankArchitecturePatterns,
4998
5167
  rankCodeChunks,
@@ -5004,6 +5173,7 @@ export {
5004
5173
  redactSecrets,
5005
5174
  redactedHistoricalText,
5006
5175
  replaceCodeIndex,
5176
+ requestWithGitHubRateLimit,
5007
5177
  resolveGitHubToken,
5008
5178
  resolvePullRequestDetailConcurrency,
5009
5179
  resolvePullRequestFetchLimit,