github-issue-tower-defence-management 1.44.3 → 1.44.5
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/.github/workflows/api-created_issue_pr.yml +8 -1
- package/.github/workflows/umino-project.yml +26 -13
- package/CHANGELOG.md +15 -0
- package/bin/adapter/entry-points/cli/index.js +1 -0
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/repositories/OauthProxyClaudeRepository.js +5 -0
- package/bin/adapter/repositories/OauthProxyClaudeRepository.js.map +1 -1
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +2 -2
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
- package/bin/domain/usecases/HandleScheduledEventUseCase.js +1 -0
- package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +2 -2
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +4 -6
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.test.ts +2 -0
- package/src/adapter/entry-points/cli/index.ts +1 -0
- package/src/adapter/repositories/OauthProxyClaudeRepository.test.ts +56 -1
- package/src/adapter/repositories/OauthProxyClaudeRepository.ts +12 -0
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +5 -2
- package/src/domain/usecases/HandleScheduledEventUseCase.ts +1 -0
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +8 -4
- package/src/domain/usecases/StartPreparationUseCase.test.ts +76 -79
- package/src/domain/usecases/StartPreparationUseCase.ts +10 -8
- package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +4 -1
- package/types/adapter/repositories/OauthProxyClaudeRepository.d.ts.map +1 -1
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +1 -1
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts +2 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts +1 -1
- package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts.map +1 -1
|
@@ -117,7 +117,7 @@ describe('OauthProxyClaudeRepository', () => {
|
|
|
117
117
|
],
|
|
118
118
|
},
|
|
119
119
|
{
|
|
120
|
-
name: 'synthesises hour:168 100% entry when overage-status is rejected and no existing entry is at 100%',
|
|
120
|
+
name: 'synthesises hour:168 100% entry when overage-status is rejected with out_of_credits reason and no existing entry is at 100%',
|
|
121
121
|
fileExists: true,
|
|
122
122
|
fileContent: JSON.stringify({
|
|
123
123
|
headers: {
|
|
@@ -142,6 +142,61 @@ describe('OauthProxyClaudeRepository', () => {
|
|
|
142
142
|
},
|
|
143
143
|
],
|
|
144
144
|
},
|
|
145
|
+
{
|
|
146
|
+
name: 'synthesises hour:168 100% entry when overage-status is rejected without disabled-reason header',
|
|
147
|
+
fileExists: true,
|
|
148
|
+
fileContent: JSON.stringify({
|
|
149
|
+
headers: {
|
|
150
|
+
'anthropic-ratelimit-unified-7d-utilization': '0.88',
|
|
151
|
+
'anthropic-ratelimit-unified-7d-reset': '1772769600',
|
|
152
|
+
'anthropic-ratelimit-unified-overage-status': 'rejected',
|
|
153
|
+
},
|
|
154
|
+
ts: 1234567890,
|
|
155
|
+
}),
|
|
156
|
+
expected: [
|
|
157
|
+
{
|
|
158
|
+
hour: 168,
|
|
159
|
+
utilizationPercentage: 88,
|
|
160
|
+
resetsAt: new Date(1772769600 * 1000),
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
hour: 168,
|
|
164
|
+
utilizationPercentage: 100,
|
|
165
|
+
resetsAt: new Date(1772769600 * 1000),
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: 'does not synthesise entry when overage-status is rejected but overage-disabled-reason is org_level_disabled_until',
|
|
171
|
+
fileExists: true,
|
|
172
|
+
fileContent: JSON.stringify({
|
|
173
|
+
headers: {
|
|
174
|
+
'anthropic-ratelimit-unified-status': 'allowed',
|
|
175
|
+
'anthropic-ratelimit-unified-5h-status': 'allowed',
|
|
176
|
+
'anthropic-ratelimit-unified-5h-utilization': '0.10',
|
|
177
|
+
'anthropic-ratelimit-unified-5h-reset': '1772575200',
|
|
178
|
+
'anthropic-ratelimit-unified-7d-status': 'allowed',
|
|
179
|
+
'anthropic-ratelimit-unified-7d-utilization': '0.05',
|
|
180
|
+
'anthropic-ratelimit-unified-7d-reset': '1772769600',
|
|
181
|
+
'anthropic-ratelimit-unified-overage-status': 'rejected',
|
|
182
|
+
'anthropic-ratelimit-unified-overage-disabled-reason':
|
|
183
|
+
'org_level_disabled_until',
|
|
184
|
+
},
|
|
185
|
+
ts: 1234567890,
|
|
186
|
+
}),
|
|
187
|
+
expected: [
|
|
188
|
+
{
|
|
189
|
+
hour: 5,
|
|
190
|
+
utilizationPercentage: 10,
|
|
191
|
+
resetsAt: new Date(1772575200 * 1000),
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
hour: 168,
|
|
195
|
+
utilizationPercentage: 5,
|
|
196
|
+
resetsAt: new Date(1772769600 * 1000),
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
},
|
|
145
200
|
{
|
|
146
201
|
name: 'does not synthesise entry when overage-status is absent',
|
|
147
202
|
fileExists: true,
|
|
@@ -8,8 +8,12 @@ type ProxyFileHeaders = {
|
|
|
8
8
|
'anthropic-ratelimit-unified-5h-reset'?: string;
|
|
9
9
|
'anthropic-ratelimit-unified-7d-reset'?: string;
|
|
10
10
|
'anthropic-ratelimit-unified-overage-status'?: string;
|
|
11
|
+
'anthropic-ratelimit-unified-overage-disabled-reason'?: string;
|
|
11
12
|
};
|
|
12
13
|
|
|
14
|
+
const OVERAGE_DISABLED_REASONS_INDICATING_AVAILABLE_PLAN_QUOTA: ReadonlySet<string> =
|
|
15
|
+
new Set(['org_level_disabled_until']);
|
|
16
|
+
|
|
13
17
|
type ProxyFile = {
|
|
14
18
|
headers?: ProxyFileHeaders;
|
|
15
19
|
};
|
|
@@ -86,8 +90,16 @@ export class OauthProxyClaudeRepository implements ClaudeRepository {
|
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
const overageStatus = headers['anthropic-ratelimit-unified-overage-status'];
|
|
93
|
+
const overageDisabledReason =
|
|
94
|
+
headers['anthropic-ratelimit-unified-overage-disabled-reason'];
|
|
95
|
+
const overageDisabledReasonIndicatesAvailablePlanQuota =
|
|
96
|
+
overageDisabledReason !== undefined &&
|
|
97
|
+
OVERAGE_DISABLED_REASONS_INDICATING_AVAILABLE_PLAN_QUOTA.has(
|
|
98
|
+
overageDisabledReason,
|
|
99
|
+
);
|
|
89
100
|
if (
|
|
90
101
|
overageStatus === 'rejected' &&
|
|
102
|
+
!overageDisabledReasonIndicatesAvailablePlanQuota &&
|
|
91
103
|
!usages.some((u) => u.utilizationPercentage >= 100)
|
|
92
104
|
) {
|
|
93
105
|
usages.push({
|
|
@@ -874,8 +874,11 @@ export class ApiV3CheerioRestIssueRepository
|
|
|
874
874
|
return issues.filter((issue) => !issue.isClosed);
|
|
875
875
|
};
|
|
876
876
|
|
|
877
|
-
getStoryObjectMap = async (
|
|
878
|
-
|
|
877
|
+
getStoryObjectMap = async (
|
|
878
|
+
project: Project,
|
|
879
|
+
allowCacheMinutes: number,
|
|
880
|
+
): Promise<StoryObjectMap> => {
|
|
881
|
+
const { issues } = await this.getAllIssues(project.id, allowCacheMinutes);
|
|
879
882
|
const storyObjectMap: StoryObjectMap = new Map();
|
|
880
883
|
const targetStories = project.story?.stories || [];
|
|
881
884
|
for (const story of targetStories) {
|
|
@@ -363,6 +363,7 @@ ${JSON.stringify(e)}
|
|
|
363
363
|
input.startPreparation.utilizationPercentageThreshold ?? 90,
|
|
364
364
|
allowedIssueAuthors: input.startPreparation.allowedIssueAuthors ?? null,
|
|
365
365
|
codexHomeCandidates: input.startPreparation.codexHomeCandidates ?? null,
|
|
366
|
+
allowIssueCacheMinutes: input.allowIssueCacheMinutes,
|
|
366
367
|
});
|
|
367
368
|
}
|
|
368
369
|
if (input.notifyFinishedPreparation) {
|
|
@@ -96,8 +96,10 @@ export class NotifyFinishedIssuePreparationUseCase {
|
|
|
96
96
|
|
|
97
97
|
if (issue.dependedIssueUrls.length === 0) {
|
|
98
98
|
try {
|
|
99
|
-
const storyObjectMap =
|
|
100
|
-
|
|
99
|
+
const storyObjectMap = await this.issueRepository.getStoryObjectMap(
|
|
100
|
+
project,
|
|
101
|
+
0,
|
|
102
|
+
);
|
|
101
103
|
for (const storyObject of storyObjectMap.values()) {
|
|
102
104
|
const towerDefenceIssue = storyObject.issues.find(
|
|
103
105
|
(i) => i.url === issue.url,
|
|
@@ -354,8 +356,10 @@ export class NotifyFinishedIssuePreparationUseCase {
|
|
|
354
356
|
}
|
|
355
357
|
|
|
356
358
|
try {
|
|
357
|
-
const storyObjectMap =
|
|
358
|
-
|
|
359
|
+
const storyObjectMap = await this.issueRepository.getStoryObjectMap(
|
|
360
|
+
project,
|
|
361
|
+
0,
|
|
362
|
+
);
|
|
359
363
|
|
|
360
364
|
const isWorkflowBlocker = Array.from(storyObjectMap.entries()).some(
|
|
361
365
|
([storyName, storyObject]) =>
|