github-issue-tower-defence-management 1.116.2 → 1.116.4

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 (39) hide show
  1. package/.github/workflows/commit-lint.yml +1 -1
  2. package/.github/workflows/configs/commitlint.config.cjs +32 -0
  3. package/.github/workflows/umino-project.yml +9 -3
  4. package/CHANGELOG.md +7 -0
  5. package/README.md +2 -2
  6. package/bin/adapter/repositories/ProcClaudeLiveSessionRepository.js +18 -6
  7. package/bin/adapter/repositories/ProcClaudeLiveSessionRepository.js.map +1 -1
  8. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +74 -49
  9. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
  10. package/bin/adapter/repositories/issue/githubRateLimitRetry.js +77 -0
  11. package/bin/adapter/repositories/issue/githubRateLimitRetry.js.map +1 -0
  12. package/bin/domain/usecases/LiveSessionOauthTokenSelectUseCase.js +6 -6
  13. package/bin/domain/usecases/LiveSessionOauthTokenSelectUseCase.js.map +1 -1
  14. package/bin/domain/usecases/OauthTokenSelectUseCase.js +1 -1
  15. package/bin/domain/usecases/OauthTokenSelectUseCase.js.map +1 -1
  16. package/package.json +1 -1
  17. package/renovate.json +1 -0
  18. package/src/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.test.ts +9 -9
  19. package/src/adapter/repositories/ProcClaudeLiveSessionRepository.test.ts +69 -7
  20. package/src/adapter/repositories/ProcClaudeLiveSessionRepository.ts +19 -8
  21. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +111 -0
  22. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +243 -193
  23. package/src/adapter/repositories/issue/githubRateLimitRetry.test.ts +167 -0
  24. package/src/adapter/repositories/issue/githubRateLimitRetry.ts +105 -0
  25. package/src/domain/usecases/LiveSessionOauthTokenSelectUseCase.test.ts +25 -3
  26. package/src/domain/usecases/LiveSessionOauthTokenSelectUseCase.ts +7 -7
  27. package/src/domain/usecases/OauthTokenSelectUseCase.test.ts +13 -4
  28. package/src/domain/usecases/OauthTokenSelectUseCase.ts +1 -1
  29. package/src/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.ts +1 -1
  30. package/types/adapter/repositories/ProcClaudeLiveSessionRepository.d.ts +1 -0
  31. package/types/adapter/repositories/ProcClaudeLiveSessionRepository.d.ts.map +1 -1
  32. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +4 -1
  33. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
  34. package/types/adapter/repositories/issue/githubRateLimitRetry.d.ts +10 -0
  35. package/types/adapter/repositories/issue/githubRateLimitRetry.d.ts.map +1 -0
  36. package/types/domain/usecases/OauthTokenSelectUseCase.d.ts +1 -1
  37. package/types/domain/usecases/OauthTokenSelectUseCase.d.ts.map +1 -1
  38. package/types/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.d.ts +1 -1
  39. package/types/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.d.ts.map +1 -1
@@ -0,0 +1,167 @@
1
+ import {
2
+ hasRateLimitSignals,
3
+ computeBoundedBackoffMs,
4
+ computeRateLimitResetIso,
5
+ fetchWithGitHubRateLimitRetry,
6
+ RATE_LIMIT_MAX_RETRIES,
7
+ RATE_LIMIT_TOTAL_BACKOFF_CAP_MS,
8
+ } from './githubRateLimitRetry';
9
+
10
+ describe('githubRateLimitRetry', () => {
11
+ describe('hasRateLimitSignals', () => {
12
+ it('detects a 403 with x-ratelimit-remaining: 0', () => {
13
+ const headers = new Headers({ 'x-ratelimit-remaining': '0' });
14
+ expect(hasRateLimitSignals(403, headers, '')).toBe(true);
15
+ });
16
+
17
+ it('detects a 429 with a Retry-After header', () => {
18
+ const headers = new Headers({ 'retry-after': '2' });
19
+ expect(hasRateLimitSignals(429, headers, '')).toBe(true);
20
+ });
21
+
22
+ it('detects a secondary rate limit message in the body', () => {
23
+ const headers = new Headers();
24
+ expect(
25
+ hasRateLimitSignals(
26
+ 403,
27
+ headers,
28
+ JSON.stringify({
29
+ message: 'You have exceeded a secondary rate limit',
30
+ }),
31
+ ),
32
+ ).toBe(true);
33
+ });
34
+
35
+ it('does not flag a 403 without any rate-limit signal', () => {
36
+ const headers = new Headers({ 'x-ratelimit-remaining': '4999' });
37
+ expect(
38
+ hasRateLimitSignals(
39
+ 403,
40
+ headers,
41
+ JSON.stringify({ message: 'Resource not accessible by integration' }),
42
+ ),
43
+ ).toBe(false);
44
+ });
45
+
46
+ it('does not flag non-403/429 statuses', () => {
47
+ const headers = new Headers({ 'retry-after': '2' });
48
+ expect(hasRateLimitSignals(404, headers, 'rate limit')).toBe(false);
49
+ });
50
+ });
51
+
52
+ describe('computeBoundedBackoffMs', () => {
53
+ it('grows exponentially from the base when no Retry-After is present', () => {
54
+ const headers = new Headers();
55
+ expect(computeBoundedBackoffMs(headers, 0, 0)).toBe(250);
56
+ expect(computeBoundedBackoffMs(headers, 1, 0)).toBe(500);
57
+ expect(computeBoundedBackoffMs(headers, 2, 0)).toBe(1000);
58
+ });
59
+
60
+ it('honors Retry-After only within the remaining budget', () => {
61
+ const headers = new Headers({ 'retry-after': '2' });
62
+ expect(computeBoundedBackoffMs(headers, 0, 0)).toBe(2000);
63
+ });
64
+
65
+ it('caps the wait so the total never exceeds the budget', () => {
66
+ const headers = new Headers({ 'retry-after': '3600' });
67
+ expect(computeBoundedBackoffMs(headers, 0, 4000)).toBe(
68
+ RATE_LIMIT_TOTAL_BACKOFF_CAP_MS - 4000,
69
+ );
70
+ });
71
+
72
+ it('returns 0 when the backoff budget is exhausted', () => {
73
+ const headers = new Headers({ 'retry-after': '3600' });
74
+ expect(
75
+ computeBoundedBackoffMs(headers, 0, RATE_LIMIT_TOTAL_BACKOFF_CAP_MS),
76
+ ).toBe(0);
77
+ });
78
+ });
79
+
80
+ describe('computeRateLimitResetIso', () => {
81
+ it('converts the x-ratelimit-reset epoch seconds to an ISO timestamp', () => {
82
+ const headers = new Headers({ 'x-ratelimit-reset': '1700000000' });
83
+ expect(computeRateLimitResetIso(headers)).toBe(
84
+ new Date(1700000000 * 1000).toISOString(),
85
+ );
86
+ });
87
+
88
+ it('returns null when no reset header is present', () => {
89
+ expect(computeRateLimitResetIso(new Headers())).toBeNull();
90
+ });
91
+ });
92
+
93
+ describe('fetchWithGitHubRateLimitRetry', () => {
94
+ const rateLimitResponse = (): Response =>
95
+ new Response(JSON.stringify({ message: 'API rate limit exceeded' }), {
96
+ status: 403,
97
+ headers: { 'x-ratelimit-remaining': '0' },
98
+ });
99
+
100
+ it('retries a rate-limit response and resolves with the eventual success', async () => {
101
+ const sleep = jest.fn().mockResolvedValue(undefined);
102
+ const request = jest
103
+ .fn<Promise<Response>, []>()
104
+ .mockResolvedValueOnce(rateLimitResponse())
105
+ .mockResolvedValueOnce(
106
+ new Response(JSON.stringify({ ok: true }), { status: 200 }),
107
+ );
108
+
109
+ const response = await fetchWithGitHubRateLimitRetry(request, sleep);
110
+
111
+ expect(response.status).toBe(200);
112
+ expect(request).toHaveBeenCalledTimes(2);
113
+ expect(sleep).toHaveBeenCalledTimes(1);
114
+ });
115
+
116
+ it('does not retry a genuine permission 403 without rate-limit signals', async () => {
117
+ const sleep = jest.fn().mockResolvedValue(undefined);
118
+ const request = jest.fn<Promise<Response>, []>().mockResolvedValue(
119
+ new Response(
120
+ JSON.stringify({
121
+ message: 'Resource not accessible by integration',
122
+ }),
123
+ { status: 403, headers: { 'x-ratelimit-remaining': '4999' } },
124
+ ),
125
+ );
126
+
127
+ const response = await fetchWithGitHubRateLimitRetry(request, sleep);
128
+
129
+ expect(response.status).toBe(403);
130
+ expect(request).toHaveBeenCalledTimes(1);
131
+ expect(sleep).not.toHaveBeenCalled();
132
+ });
133
+
134
+ it('stops retrying after the bounded retry cap and never blocks past the budget', async () => {
135
+ const sleeps: number[] = [];
136
+ const sleep = jest.fn(async (milliseconds: number) => {
137
+ sleeps.push(milliseconds);
138
+ });
139
+ const request = jest
140
+ .fn<Promise<Response>, []>()
141
+ .mockResolvedValue(rateLimitResponse());
142
+
143
+ const response = await fetchWithGitHubRateLimitRetry(request, sleep);
144
+
145
+ expect(response.status).toBe(403);
146
+ expect(request).toHaveBeenCalledTimes(RATE_LIMIT_MAX_RETRIES + 1);
147
+ expect(sleep).toHaveBeenCalledTimes(RATE_LIMIT_MAX_RETRIES);
148
+ const totalSlept = sleeps.reduce((sum, value) => sum + value, 0);
149
+ expect(totalSlept).toBeLessThanOrEqual(RATE_LIMIT_TOTAL_BACKOFF_CAP_MS);
150
+ });
151
+
152
+ it('preserves the response body for the caller after inspecting it for signals', async () => {
153
+ const sleep = jest.fn().mockResolvedValue(undefined);
154
+ const request = jest
155
+ .fn<Promise<Response>, []>()
156
+ .mockResolvedValueOnce(rateLimitResponse())
157
+ .mockResolvedValueOnce(
158
+ new Response(JSON.stringify({ value: 'final' }), { status: 200 }),
159
+ );
160
+
161
+ const response = await fetchWithGitHubRateLimitRetry(request, sleep);
162
+ const body: unknown = await response.json();
163
+
164
+ expect(body).toEqual({ value: 'final' });
165
+ });
166
+ });
167
+ });
@@ -0,0 +1,105 @@
1
+ export const RATE_LIMIT_MAX_RETRIES = 3;
2
+ export const RATE_LIMIT_TOTAL_BACKOFF_CAP_MS = 5000;
3
+ export const RATE_LIMIT_BASE_BACKOFF_MS = 250;
4
+
5
+ const RATE_LIMIT_MESSAGE_PATTERN = /rate limit|secondary rate limit|abuse/i;
6
+
7
+ export type Sleep = (milliseconds: number) => Promise<void>;
8
+
9
+ export const realSleep: Sleep = (milliseconds) =>
10
+ new Promise((resolve) => setTimeout(resolve, milliseconds));
11
+
12
+ const parseNonNegativeIntegerHeader = (value: string | null): number | null => {
13
+ if (value === null) {
14
+ return null;
15
+ }
16
+ const trimmed = value.trim();
17
+ if (!/^\d+$/.test(trimmed)) {
18
+ return null;
19
+ }
20
+ const parsed = Number.parseInt(trimmed, 10);
21
+ return Number.isFinite(parsed) ? parsed : null;
22
+ };
23
+
24
+ export const hasRateLimitSignals = (
25
+ status: number,
26
+ headers: Headers,
27
+ bodyText: string,
28
+ ): boolean => {
29
+ if (status !== 403 && status !== 429) {
30
+ return false;
31
+ }
32
+ if (
33
+ parseNonNegativeIntegerHeader(headers.get('x-ratelimit-remaining')) === 0
34
+ ) {
35
+ return true;
36
+ }
37
+ if (headers.get('retry-after') !== null) {
38
+ return true;
39
+ }
40
+ return RATE_LIMIT_MESSAGE_PATTERN.test(bodyText);
41
+ };
42
+
43
+ export const computeRateLimitResetIso = (headers: Headers): string | null => {
44
+ const resetEpochSeconds = parseNonNegativeIntegerHeader(
45
+ headers.get('x-ratelimit-reset'),
46
+ );
47
+ if (resetEpochSeconds === null) {
48
+ return null;
49
+ }
50
+ return new Date(resetEpochSeconds * 1000).toISOString();
51
+ };
52
+
53
+ export const computeBoundedBackoffMs = (
54
+ headers: Headers,
55
+ attempt: number,
56
+ elapsedMs: number,
57
+ ): number => {
58
+ const remainingBudgetMs = RATE_LIMIT_TOTAL_BACKOFF_CAP_MS - elapsedMs;
59
+ if (remainingBudgetMs <= 0) {
60
+ return 0;
61
+ }
62
+ const exponentialMs = RATE_LIMIT_BASE_BACKOFF_MS * Math.pow(2, attempt);
63
+ const retryAfterSeconds = parseNonNegativeIntegerHeader(
64
+ headers.get('retry-after'),
65
+ );
66
+ const requestedMs =
67
+ retryAfterSeconds !== null ? retryAfterSeconds * 1000 : exponentialMs;
68
+ return Math.min(requestedMs, remainingBudgetMs);
69
+ };
70
+
71
+ export const fetchWithGitHubRateLimitRetry = async (
72
+ request: () => Promise<Response>,
73
+ sleep: Sleep = realSleep,
74
+ now: () => number = Date.now,
75
+ ): Promise<Response> => {
76
+ const startMs = now();
77
+ let attempt = 0;
78
+ for (;;) {
79
+ const response = await request();
80
+ if (response.ok) {
81
+ return response;
82
+ }
83
+ const bodyText = await response.clone().text();
84
+ if (
85
+ attempt >= RATE_LIMIT_MAX_RETRIES ||
86
+ !hasRateLimitSignals(response.status, response.headers, bodyText)
87
+ ) {
88
+ return response;
89
+ }
90
+ const elapsedMs = now() - startMs;
91
+ const backoffMs = computeBoundedBackoffMs(
92
+ response.headers,
93
+ attempt,
94
+ elapsedMs,
95
+ );
96
+ if (backoffMs <= 0) {
97
+ return response;
98
+ }
99
+ console.log(
100
+ `GitHub returned ${response.status} (rate limit). Backing off ${backoffMs}ms before retry ${attempt + 1}/${RATE_LIMIT_MAX_RETRIES}.`,
101
+ );
102
+ await sleep(backoffMs);
103
+ attempt++;
104
+ }
105
+ };
@@ -32,9 +32,9 @@ const candidate = (
32
32
  unifiedRejected,
33
33
  });
34
34
 
35
- const session = (name: string, sessionId: string): ClaudeLiveSession => ({
35
+ const session = (name: string, sessionKey: string): ClaudeLiveSession => ({
36
36
  token: `fake-token-${name}`,
37
- sessionId,
37
+ sessionKey,
38
38
  });
39
39
 
40
40
  describe('LiveSessionOauthTokenSelectUseCase', () => {
@@ -98,7 +98,7 @@ describe('LiveSessionOauthTokenSelectUseCase', () => {
98
98
  expect(blocked?.liveSessionCount).toBe(0);
99
99
  });
100
100
 
101
- it('counts distinct session ids and dedupes child processes sharing one session', () => {
101
+ it('counts distinct session keys and dedupes child processes sharing one session key', () => {
102
102
  const result = useCase.run(
103
103
  [
104
104
  candidate('oneSession', snapshot({ sevenDayReset: NOW + 2 * DAY })),
@@ -121,6 +121,28 @@ describe('LiveSessionOauthTokenSelectUseCase', () => {
121
121
  expect(twoSessions?.liveSessionCount).toBe(2);
122
122
  });
123
123
 
124
+ it('counts resumed sessions keyed by config dir so they are not under-counted', () => {
125
+ const result = useCase.run(
126
+ [
127
+ candidate('resumedHeavy', snapshot({ sevenDayReset: NOW + 2 * DAY })),
128
+ candidate('fresh', snapshot({ sevenDayReset: NOW + 6 * DAY })),
129
+ ],
130
+ [
131
+ session('resumedHeavy', '/home/user/.config/claude-1'),
132
+ session('resumedHeavy', '/home/user/.config/claude-1'),
133
+ session('resumedHeavy', '/home/user/.config/claude-2'),
134
+ session('fresh', 'session-fresh'),
135
+ ],
136
+ NOW,
137
+ );
138
+
139
+ expect(result.selected?.name).toBe('fresh');
140
+ const resumedHeavy = result.metrics.find((m) => m.name === 'resumedHeavy');
141
+ const fresh = result.metrics.find((m) => m.name === 'fresh');
142
+ expect(resumedHeavy?.liveSessionCount).toBe(2);
143
+ expect(fresh?.liveSessionCount).toBe(1);
144
+ });
145
+
124
146
  it('returns null selection when no token passes the rate-limit filter', () => {
125
147
  const result = useCase.run(
126
148
  [candidate('blocked', snapshot({ fiveHourUtilization: 0.9 }))],
@@ -84,16 +84,16 @@ export class LiveSessionOauthTokenSelectUseCase {
84
84
  private liveSessionCountByToken = (
85
85
  liveSessions: ClaudeLiveSession[],
86
86
  ): Map<string, number> => {
87
- const sessionIdsByToken = new Map<string, Set<string>>();
87
+ const sessionKeysByToken = new Map<string, Set<string>>();
88
88
  for (const liveSession of liveSessions) {
89
- const sessionIds =
90
- sessionIdsByToken.get(liveSession.token) ?? new Set<string>();
91
- sessionIds.add(liveSession.sessionId);
92
- sessionIdsByToken.set(liveSession.token, sessionIds);
89
+ const sessionKeys =
90
+ sessionKeysByToken.get(liveSession.token) ?? new Set<string>();
91
+ sessionKeys.add(liveSession.sessionKey);
92
+ sessionKeysByToken.set(liveSession.token, sessionKeys);
93
93
  }
94
94
  const countByToken = new Map<string, number>();
95
- for (const [token, sessionIds] of sessionIdsByToken.entries()) {
96
- countByToken.set(token, sessionIds.size);
95
+ for (const [token, sessionKeys] of sessionKeysByToken.entries()) {
96
+ countByToken.set(token, sessionKeys.size);
97
97
  }
98
98
  return countByToken;
99
99
  };
@@ -81,11 +81,11 @@ describe('OauthTokenSelectUseCase', () => {
81
81
  expect(result.selected?.name).toBe('boundary');
82
82
  });
83
83
 
84
- it('excludes a token whose 7d window is less than 30% free', () => {
84
+ it('excludes a token whose 7d window is less than 7% free', () => {
85
85
  const result = useCase.run(
86
86
  [
87
- candidate('busy7d', snapshot({ sevenDayUtilization: 0.71 })),
88
- candidate('ok', snapshot({ sevenDayUtilization: 0.7 })),
87
+ candidate('busy7d', snapshot({ sevenDayUtilization: 0.94 })),
88
+ candidate('ok', snapshot({ sevenDayUtilization: 0.92 })),
89
89
  ],
90
90
  NOW,
91
91
  );
@@ -96,6 +96,15 @@ describe('OauthTokenSelectUseCase', () => {
96
96
  expect(busy?.exclusionReason).toContain('7d window');
97
97
  });
98
98
 
99
+ it('treats a 7d window with at least 7% free as eligible (boundary)', () => {
100
+ const result = useCase.run(
101
+ [candidate('boundary', snapshot({ sevenDayUtilization: 0.92 }))],
102
+ NOW,
103
+ );
104
+
105
+ expect(result.selected?.name).toBe('boundary');
106
+ });
107
+
99
108
  it('treats a token with no snapshot as fully free', () => {
100
109
  const result = useCase.run([candidate('fresh', null)], NOW);
101
110
 
@@ -154,7 +163,7 @@ describe('OauthTokenSelectUseCase', () => {
154
163
  const result = useCase.run(
155
164
  [
156
165
  candidate('busy', snapshot({ fiveHourUtilization: 0.9 })),
157
- candidate('alsoBusy', snapshot({ sevenDayUtilization: 0.9 })),
166
+ candidate('alsoBusy', snapshot({ sevenDayUtilization: 0.95 })),
158
167
  ],
159
168
  NOW,
160
169
  );
@@ -31,7 +31,7 @@ const SECONDS_PER_DAY = 86400;
31
31
  const SEVEN_DAYS_IN_SECONDS = 7 * SECONDS_PER_DAY;
32
32
 
33
33
  export const FIVE_HOUR_MIN_FREE_RATIO = 0.6;
34
- export const SEVEN_DAY_MIN_FREE_RATIO = 0.3;
34
+ export const SEVEN_DAY_MIN_FREE_RATIO = 0.07;
35
35
 
36
36
  export class OauthTokenSelectUseCase {
37
37
  run = (
@@ -1,6 +1,6 @@
1
1
  export type ClaudeLiveSession = {
2
2
  token: string;
3
- sessionId: string;
3
+ sessionKey: string;
4
4
  };
5
5
 
6
6
  export interface ClaudeLiveSessionRepository {
@@ -5,6 +5,7 @@ export declare class ProcClaudeLiveSessionRepository implements ClaudeLiveSessio
5
5
  listLiveSessions: () => ClaudeLiveSession[];
6
6
  private listProcessIdDirectories;
7
7
  private readLiveSession;
8
+ private deriveSessionKey;
8
9
  private isClaudeProcess;
9
10
  private readEnviron;
10
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ProcClaudeLiveSessionRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/ProcClaudeLiveSessionRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,sEAAsE,CAAC;AAiB9E,qBAAa,+BAAgC,YAAW,2BAA2B;IAE/E,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,GAAE,MAA+B;IAGjE,gBAAgB,QAAO,iBAAiB,EAAE,CASxC;IAEF,OAAO,CAAC,wBAAwB,CAQ9B;IAEF,OAAO,CAAC,eAAe,CAqBrB;IAEF,OAAO,CAAC,eAAe,CAgBrB;IAEF,OAAO,CAAC,WAAW,CA4BjB;CACH"}
1
+ {"version":3,"file":"ProcClaudeLiveSessionRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/ProcClaudeLiveSessionRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,sEAAsE,CAAC;AAkB9E,qBAAa,+BAAgC,YAAW,2BAA2B;IAE/E,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,GAAE,MAA+B;IAGjE,gBAAgB,QAAO,iBAAiB,EAAE,CASxC;IAEF,OAAO,CAAC,wBAAwB,CAQ9B;IAEF,OAAO,CAAC,eAAe,CAmBrB;IAEF,OAAO,CAAC,gBAAgB,CAUtB;IAEF,OAAO,CAAC,eAAe,CAgBrB;IAEF,OAAO,CAAC,WAAW,CA4BjB;CACH"}
@@ -9,6 +9,7 @@ import { LocalStorageCacheRepository } from '../LocalStorageCacheRepository';
9
9
  import { BaseGitHubRepository } from '../BaseGitHubRepository';
10
10
  import { LocalStorageRepository } from '../LocalStorageRepository';
11
11
  import { Member } from '../../../domain/entities/Member';
12
+ import { Sleep } from './githubRateLimitRetry';
12
13
  export declare class ApiV3CheerioRestIssueRepository extends BaseGitHubRepository implements IssueRepository {
13
14
  readonly apiV3IssueRepository: Pick<ApiV3IssueRepository, 'searchIssue'>;
14
15
  readonly restIssueRepository: Pick<RestIssueRepository, 'createNewIssue' | 'updateIssue' | 'createComment' | 'getIssue' | 'updateLabels' | 'removeLabel' | 'updateAssigneeList'>;
@@ -16,7 +17,9 @@ export declare class ApiV3CheerioRestIssueRepository extends BaseGitHubRepositor
16
17
  readonly localStorageCacheRepository: Pick<LocalStorageCacheRepository, 'getLatest' | 'set'>;
17
18
  readonly localStorageRepository: LocalStorageRepository;
18
19
  readonly ghToken: string;
19
- constructor(apiV3IssueRepository: Pick<ApiV3IssueRepository, 'searchIssue'>, restIssueRepository: Pick<RestIssueRepository, 'createNewIssue' | 'updateIssue' | 'createComment' | 'getIssue' | 'updateLabels' | 'removeLabel' | 'updateAssigneeList'>, graphqlProjectItemRepository: Pick<GraphqlProjectItemRepository, 'fetchProjectItems' | 'fetchProjectItemByUrl' | 'updateProjectField' | 'clearProjectField' | 'updateProjectTextField' | 'addIssueToProject'>, localStorageCacheRepository: Pick<LocalStorageCacheRepository, 'getLatest' | 'set'>, localStorageRepository: LocalStorageRepository, ghToken?: string);
20
+ readonly sleep: Sleep;
21
+ constructor(apiV3IssueRepository: Pick<ApiV3IssueRepository, 'searchIssue'>, restIssueRepository: Pick<RestIssueRepository, 'createNewIssue' | 'updateIssue' | 'createComment' | 'getIssue' | 'updateLabels' | 'removeLabel' | 'updateAssigneeList'>, graphqlProjectItemRepository: Pick<GraphqlProjectItemRepository, 'fetchProjectItems' | 'fetchProjectItemByUrl' | 'updateProjectField' | 'clearProjectField' | 'updateProjectTextField' | 'addIssueToProject'>, localStorageCacheRepository: Pick<LocalStorageCacheRepository, 'getLatest' | 'set'>, localStorageRepository: LocalStorageRepository, ghToken?: string, sleep?: Sleep);
22
+ private fetchWithRateLimitRetry;
20
23
  updateStatus: (project: Project, issue: Issue, statusId: string) => Promise<void>;
21
24
  convertProjectItemToIssue: (item: ProjectItem) => Issue;
22
25
  getAllIssuesFromCache: (cacheKey: string, allowCacheMinutes: number) => Promise<Issue[] | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"ApiV3CheerioRestIssueRepository.d.ts","sourceRoot":"","sources":["../../../../src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ApiV3CheerioRestIssueRepository.d.ts","sourceRoot":"","sources":["../../../../src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const RATE_LIMIT_MAX_RETRIES = 3;
2
+ export declare const RATE_LIMIT_TOTAL_BACKOFF_CAP_MS = 5000;
3
+ export declare const RATE_LIMIT_BASE_BACKOFF_MS = 250;
4
+ export type Sleep = (milliseconds: number) => Promise<void>;
5
+ export declare const realSleep: Sleep;
6
+ export declare const hasRateLimitSignals: (status: number, headers: Headers, bodyText: string) => boolean;
7
+ export declare const computeRateLimitResetIso: (headers: Headers) => string | null;
8
+ export declare const computeBoundedBackoffMs: (headers: Headers, attempt: number, elapsedMs: number) => number;
9
+ export declare const fetchWithGitHubRateLimitRetry: (request: () => Promise<Response>, sleep?: Sleep, now?: () => number) => Promise<Response>;
10
+ //# sourceMappingURL=githubRateLimitRetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubRateLimitRetry.d.ts","sourceRoot":"","sources":["../../../../src/adapter/repositories/issue/githubRateLimitRetry.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,IAAI,CAAC;AACxC,eAAO,MAAM,+BAA+B,OAAO,CAAC;AACpD,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAI9C,MAAM,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5D,eAAO,MAAM,SAAS,EAAE,KACqC,CAAC;AAc9D,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,EACd,SAAS,OAAO,EAChB,UAAU,MAAM,KACf,OAaF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,SAAS,OAAO,KAAG,MAAM,GAAG,IAQpE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,SAAS,OAAO,EAChB,SAAS,MAAM,EACf,WAAW,MAAM,KAChB,MAYF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,EAChC,QAAO,KAAiB,EACxB,MAAK,MAAM,MAAiB,KAC3B,OAAO,CAAC,QAAQ,CA8BlB,CAAC"}
@@ -24,7 +24,7 @@ export type OauthTokenSelectResult = {
24
24
  metrics: OauthTokenCandidateMetrics[];
25
25
  };
26
26
  export declare const FIVE_HOUR_MIN_FREE_RATIO = 0.6;
27
- export declare const SEVEN_DAY_MIN_FREE_RATIO = 0.3;
27
+ export declare const SEVEN_DAY_MIN_FREE_RATIO = 0.07;
28
28
  export declare class OauthTokenSelectUseCase {
29
29
  run: (candidates: OauthTokenCandidate[], nowEpochSeconds: number) => OauthTokenSelectResult;
30
30
  private evaluate;
@@ -1 +1 @@
1
- {"version":3,"file":"OauthTokenSelectUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/OauthTokenSelectUseCase.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,wBAAwB,GAAG;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAC1C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,0BAA0B,EAAE,CAAC;CACvC,CAAC;AAKF,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAE5C,qBAAa,uBAAuB;IAClC,GAAG,GACD,YAAY,mBAAmB,EAAE,EACjC,iBAAiB,MAAM,KACtB,sBAAsB,CAoBvB;IAEF,OAAO,CAAC,QAAQ,CAgCd;IAEF,OAAO,CAAC,eAAe,CAmBrB;IAEF,OAAO,CAAC,iBAAiB,CAWvB;IAEF,OAAO,CAAC,iBAAiB,CAWvB;IAEF,OAAO,CAAC,gBAAgB,CActB;IAEF,OAAO,CAAC,aAAa,CAGwC;IAE7D,OAAO,CAAC,wBAAwB,CAG9B;IAEF,OAAO,CAAC,SAAS,CAAsD;CACxE"}
1
+ {"version":3,"file":"OauthTokenSelectUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/OauthTokenSelectUseCase.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,wBAAwB,GAAG;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAC1C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,0BAA0B,EAAE,CAAC;CACvC,CAAC;AAKF,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,qBAAa,uBAAuB;IAClC,GAAG,GACD,YAAY,mBAAmB,EAAE,EACjC,iBAAiB,MAAM,KACtB,sBAAsB,CAoBvB;IAEF,OAAO,CAAC,QAAQ,CAgCd;IAEF,OAAO,CAAC,eAAe,CAmBrB;IAEF,OAAO,CAAC,iBAAiB,CAWvB;IAEF,OAAO,CAAC,iBAAiB,CAWvB;IAEF,OAAO,CAAC,gBAAgB,CActB;IAEF,OAAO,CAAC,aAAa,CAGwC;IAE7D,OAAO,CAAC,wBAAwB,CAG9B;IAEF,OAAO,CAAC,SAAS,CAAsD;CACxE"}
@@ -1,6 +1,6 @@
1
1
  export type ClaudeLiveSession = {
2
2
  token: string;
3
- sessionId: string;
3
+ sessionKey: string;
4
4
  };
5
5
  export interface ClaudeLiveSessionRepository {
6
6
  listLiveSessions: () => ClaudeLiveSession[];
@@ -1 +1 @@
1
- {"version":3,"file":"ClaudeLiveSessionRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,2BAA2B;IAC1C,gBAAgB,EAAE,MAAM,iBAAiB,EAAE,CAAC;CAC7C"}
1
+ {"version":3,"file":"ClaudeLiveSessionRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,2BAA2B;IAC1C,gBAAgB,EAAE,MAAM,iBAAiB,EAAE,CAAC;CAC7C"}