github-issue-tower-defence-management 1.67.6 → 1.68.0
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/CHANGELOG.md +7 -0
- package/README.md +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +23 -2
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/domain/usecases/StartPreparationUseCase.test.ts +358 -31
- package/src/domain/usecases/StartPreparationUseCase.ts +56 -2
- package/types/domain/usecases/StartPreparationUseCase.d.ts +2 -0
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.68.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.67.6...v1.68.0) (2026-05-29)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **rotation:** prefer tokens with shortest remaining 7d window so weekly quota is not wasted at reset ([ae6dc73](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/ae6dc73f457e2b79a0b2bc29832037379227512c)), closes [#710](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/710)
|
|
7
|
+
|
|
1
8
|
## [1.67.6](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.67.5...v1.67.6) (2026-05-29)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -213,7 +213,7 @@ When `claudeCodeOauthTokenListJsonPath` is set, `startDaemon` distributes prepar
|
|
|
213
213
|
|
|
214
214
|
2. Local reverse proxy (`127.0.0.1:8787`): on each `startDaemon` run, the daemon TCP-probes the port. If nothing responds, it spawns a detached child running `bin/adapter/proxy/proxyEntry.js`. The proxy forwards every request to `api.anthropic.com`, observes the `anthropic-ratelimit-unified-*` response headers, and writes them to a per-token cache file at `${XDG_CACHE_HOME:-~/.cache}/tdpm/ratelimit/<sha256-of-token>.json`. The cache file stores the latest 5-hour and 7-day utilization, reset epochs, and the unified, 5-hour, and 7-day statuses (used to detect `blocked` and `rejected` state per window). In addition to the unified headers, the proxy inspects the streamed response body for `rate_limit` events (objects carrying `rateLimitType`, `status`, and `resetsAt`) and records the model-specific weekly limits — at minimum `seven_day_sonnet` and `seven_day` — per token. These model-specific weekly limits are exposed only in the response body, never in the unified headers, so a token can appear healthy on `anthropic-ratelimit-unified-7d-*` while its Sonnet weekly limit is exhausted.
|
|
215
215
|
|
|
216
|
-
3. Selection: before spawning each `aw` job, the daemon reads every token's cache file. A cached observation is treated as expired once its reset epoch has passed: when the current time is past the 5-hour reset, that token's 5-hour utilization is treated as `0` and any 5-hour-window rejection is cleared; likewise, when the 7-day reset has passed, the 7-day utilization is treated as `0` and any 7-day-window rejection is cleared; a model-specific weekly limit rejection is cleared once that limit's `resetsAt` has passed. This stale-reset expiry prevents a token that has actually recovered from being locked out of rotation forever (an excluded token receives no new requests, so the proxy never re-observes it). After expiry normalization, tokens whose status is `blocked`, whose remaining (non-expired) rejection is still active, whose 5-hour utilization meets or exceeds the configured threshold, or whose weekly limit for the model that will be used is rejected are excluded. The model name maps to a limit type: a model name containing `sonnet` maps to `seven_day_sonnet`, one containing `opus` maps to `seven_day_opus`, otherwise `seven_day`; the generic `seven_day` rejection also excludes regardless of model. The remaining eligible tokens are sorted by 7-day
|
|
216
|
+
3. Selection: before spawning each `aw` job, the daemon reads every token's cache file. A cached observation is treated as expired once its reset epoch has passed: when the current time is past the 5-hour reset, that token's 5-hour utilization is treated as `0` and any 5-hour-window rejection is cleared; likewise, when the 7-day reset has passed, the 7-day utilization is treated as `0` and any 7-day-window rejection is cleared; a model-specific weekly limit rejection is cleared once that limit's `resetsAt` has passed. This stale-reset expiry prevents a token that has actually recovered from being locked out of rotation forever (an excluded token receives no new requests, so the proxy never re-observes it). After expiry normalization, tokens whose status is `blocked`, whose remaining (non-expired) rejection is still active, whose 5-hour utilization meets or exceeds the configured threshold, or whose weekly limit for the model that will be used is rejected are excluded. The model name maps to a limit type: a model name containing `sonnet` maps to `seven_day_sonnet`, one containing `opus` maps to `seven_day_opus`, otherwise `seven_day`; the generic `seven_day` rejection also excludes regardless of model. The remaining eligible tokens are sorted by time until the 7-day reset deadline ascending (soonest 7-day reset first, so quota that would otherwise expire unused is consumed first), with 5-hour utilization ascending as the tiebreaker. The 7-day reset deadline for a given spawn is read from the per-model weekly limit entry in `modelWeeklyLimits` matching the model that will be used (`seven_day_sonnet`, `seven_day_opus`, or the generic `seven_day`); when no such entry is present on a token, that token is treated as having an infinite deadline and sorts last. Each token's per-run concurrent preparation slot count is determined by its 7-day utilization: at or below 80%, the token receives the full six concurrent slots; above 80%, the slot count is reduced proportionally — specifically `ceil(6 × (1 − 7d_util) / 0.2)` — with a minimum of 1 slot at any utilization level, so near-exhausted tokens still participate rather than being cut off entirely. Tokens are dispatched round-robin across their available slots, with the token whose 7-day reset is soonest selected preferentially. The effective preparation limit for a run is the lesser of the sum of all eligible tokens' slot counts and the explicit `maximumPreparingIssuesCount` (which defaults to 6). When a token list is configured but no eligible token remains after filtering, preparation is skipped for that run. The selected token and the proxy URL (`http://127.0.0.1:8787`) are passed to the child `aw` process as `CLAUDE_CODE_OAUTH_TOKEN` and `ANTHROPIC_BASE_URL` environment variables. The child inherits the parent process's environment, so no further wiring is required inside `aw`.
|
|
217
217
|
|
|
218
218
|
When `claudeCodeOauthTokenListJsonPath` is unset, no proxy is started and `aw` runs with whatever `CLAUDE_CODE_OAUTH_TOKEN` and `ANTHROPIC_BASE_URL` are already in the environment.
|
|
219
219
|
|
|
@@ -25,6 +25,25 @@ class StartPreparationUseCase {
|
|
|
25
25
|
const general = usage.modelWeeklyLimits['seven_day'];
|
|
26
26
|
return general !== undefined && general.rejected;
|
|
27
27
|
};
|
|
28
|
+
this.secondsUntilSevenDayReset = (usage, weeklyLimitType, nowEpochSeconds) => {
|
|
29
|
+
const specific = usage.modelWeeklyLimits[weeklyLimitType];
|
|
30
|
+
if (specific !== undefined) {
|
|
31
|
+
return specific.resetsAt - nowEpochSeconds;
|
|
32
|
+
}
|
|
33
|
+
const general = usage.modelWeeklyLimits['seven_day'];
|
|
34
|
+
if (general !== undefined) {
|
|
35
|
+
return general.resetsAt - nowEpochSeconds;
|
|
36
|
+
}
|
|
37
|
+
return Number.POSITIVE_INFINITY;
|
|
38
|
+
};
|
|
39
|
+
this.compareBySevenDayDeadlineThenUtilization = (a, b, weeklyLimitType, nowEpochSeconds) => {
|
|
40
|
+
const aSecondsUntilReset = this.secondsUntilSevenDayReset(a, weeklyLimitType, nowEpochSeconds);
|
|
41
|
+
const bSecondsUntilReset = this.secondsUntilSevenDayReset(b, weeklyLimitType, nowEpochSeconds);
|
|
42
|
+
if (aSecondsUntilReset !== bSecondsUntilReset) {
|
|
43
|
+
return aSecondsUntilReset - bSecondsUntilReset;
|
|
44
|
+
}
|
|
45
|
+
return a.fiveHourUtilization - b.fiveHourUtilization;
|
|
46
|
+
};
|
|
28
47
|
this.getTokenConcurrentLimit = (sevenDayUtilization) => {
|
|
29
48
|
if (sevenDayUtilization < SEVEN_DAY_THROTTLE_START_THRESHOLD) {
|
|
30
49
|
return SEVEN_DAY_NORMAL_CONCURRENT_LIMIT;
|
|
@@ -34,12 +53,13 @@ class StartPreparationUseCase {
|
|
|
34
53
|
};
|
|
35
54
|
this.selectRotationTokens = (tokenUsages, utilizationPercentageThreshold, modelName, maxConcurrent) => {
|
|
36
55
|
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
56
|
+
const nowEpochSeconds = Date.now() / 1000;
|
|
37
57
|
const eligibleTokens = tokenUsages
|
|
38
58
|
.filter((usage) => !usage.blocked)
|
|
39
59
|
.filter((usage) => !usage.rejected)
|
|
40
60
|
.filter((usage) => !this.isModelWeeklyLimitRejected(usage, weeklyLimitType))
|
|
41
61
|
.filter((usage) => usage.fiveHourUtilization * 100 < utilizationPercentageThreshold)
|
|
42
|
-
.sort((a, b) => a
|
|
62
|
+
.sort((a, b) => this.compareBySevenDayDeadlineThenUtilization(a, b, weeklyLimitType, nowEpochSeconds));
|
|
43
63
|
if (eligibleTokens.length === 0) {
|
|
44
64
|
return { tokens: [], effectiveCap: 0 };
|
|
45
65
|
}
|
|
@@ -62,12 +82,13 @@ class StartPreparationUseCase {
|
|
|
62
82
|
};
|
|
63
83
|
this.buildRotationOrder = (tokenUsages, utilizationPercentageThreshold, modelName) => {
|
|
64
84
|
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
85
|
+
const nowEpochSeconds = Date.now() / 1000;
|
|
65
86
|
const selectedTokens = tokenUsages
|
|
66
87
|
.filter((usage) => !usage.blocked)
|
|
67
88
|
.filter((usage) => !usage.rejected)
|
|
68
89
|
.filter((usage) => !this.isModelWeeklyLimitRejected(usage, weeklyLimitType))
|
|
69
90
|
.filter((usage) => usage.fiveHourUtilization * 100 < utilizationPercentageThreshold)
|
|
70
|
-
.sort((a, b) => a
|
|
91
|
+
.sort((a, b) => this.compareBySevenDayDeadlineThenUtilization(a, b, weeklyLimitType, nowEpochSeconds));
|
|
71
92
|
const selectedTokenValues = new Set(selectedTokens.map((u) => u.token));
|
|
72
93
|
const excluded = tokenUsages
|
|
73
94
|
.filter((usage) => !selectedTokenValues.has(usage.token))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StartPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
|
|
7
7
|
import { LocalCommandRunner } from './adapter-interfaces/LocalCommandRunner';
|
|
8
8
|
import { ClaudeTokenUsageRepository } from './adapter-interfaces/ClaudeTokenUsageRepository';
|
|
9
|
+
import { ClaudeTokenUsage } from '../entities/ClaudeTokenUsage';
|
|
9
10
|
import { Issue } from '../entities/Issue';
|
|
10
11
|
import { Project } from '../entities/Project';
|
|
11
12
|
import { StoryObjectMap } from '../entities/StoryObjectMap';
|
|
@@ -2450,7 +2451,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2450
2451
|
).toHaveLength(0);
|
|
2451
2452
|
});
|
|
2452
2453
|
|
|
2453
|
-
it('should pick the token with the
|
|
2454
|
+
it('should pick the token with the soonest 7-day reset deadline first', async () => {
|
|
2454
2455
|
const awaitingIssue = createMockIssue({
|
|
2455
2456
|
url: 'url1',
|
|
2456
2457
|
title: 'Issue 1',
|
|
@@ -2468,24 +2469,35 @@ describe('StartPreparationUseCase', () => {
|
|
|
2468
2469
|
stderr: '',
|
|
2469
2470
|
exitCode: 0,
|
|
2470
2471
|
});
|
|
2472
|
+
const nowEpochSeconds = Math.floor(Date.now() / 1000);
|
|
2471
2473
|
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
2472
2474
|
{
|
|
2473
|
-
name: 'token-
|
|
2474
|
-
token: 'token-
|
|
2475
|
+
name: 'token-far-reset',
|
|
2476
|
+
token: 'token-far-reset',
|
|
2475
2477
|
fiveHourUtilization: 0.1,
|
|
2476
2478
|
sevenDayUtilization: 0.7,
|
|
2477
2479
|
blocked: false,
|
|
2478
2480
|
rejected: false,
|
|
2479
|
-
modelWeeklyLimits: {
|
|
2481
|
+
modelWeeklyLimits: {
|
|
2482
|
+
seven_day_opus: {
|
|
2483
|
+
rejected: false,
|
|
2484
|
+
resetsAt: nowEpochSeconds + 100 * 3600,
|
|
2485
|
+
},
|
|
2486
|
+
},
|
|
2480
2487
|
},
|
|
2481
2488
|
{
|
|
2482
|
-
name: 'token-
|
|
2483
|
-
token: 'token-
|
|
2489
|
+
name: 'token-soon-reset',
|
|
2490
|
+
token: 'token-soon-reset',
|
|
2484
2491
|
fiveHourUtilization: 0.5,
|
|
2485
2492
|
sevenDayUtilization: 0.2,
|
|
2486
2493
|
blocked: false,
|
|
2487
2494
|
rejected: false,
|
|
2488
|
-
modelWeeklyLimits: {
|
|
2495
|
+
modelWeeklyLimits: {
|
|
2496
|
+
seven_day_opus: {
|
|
2497
|
+
rejected: false,
|
|
2498
|
+
resetsAt: nowEpochSeconds + 20 * 3600,
|
|
2499
|
+
},
|
|
2500
|
+
},
|
|
2489
2501
|
},
|
|
2490
2502
|
]);
|
|
2491
2503
|
|
|
@@ -2505,7 +2517,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2505
2517
|
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
2506
2518
|
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
2507
2519
|
env: {
|
|
2508
|
-
CLAUDE_CODE_OAUTH_TOKEN: 'token-
|
|
2520
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'token-soon-reset',
|
|
2509
2521
|
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
2510
2522
|
},
|
|
2511
2523
|
});
|
|
@@ -2706,7 +2718,7 @@ describe('StartPreparationUseCase', () => {
|
|
|
2706
2718
|
consoleWarnSpy.mockRestore();
|
|
2707
2719
|
});
|
|
2708
2720
|
|
|
2709
|
-
it('should sort tokens by 7-day
|
|
2721
|
+
it('should sort tokens by 7-day reset deadline ascending when all have full process capacity', async () => {
|
|
2710
2722
|
const awaitingIssues: Issue[] = [
|
|
2711
2723
|
createMockIssue({
|
|
2712
2724
|
url: 'url1',
|
|
@@ -2742,33 +2754,49 @@ describe('StartPreparationUseCase', () => {
|
|
|
2742
2754
|
stderr: '',
|
|
2743
2755
|
exitCode: 0,
|
|
2744
2756
|
});
|
|
2757
|
+
const nowEpochSeconds = Math.floor(Date.now() / 1000);
|
|
2745
2758
|
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
2746
2759
|
{
|
|
2747
|
-
name: 'token-7d-mid',
|
|
2748
|
-
token: 'token-7d-mid',
|
|
2760
|
+
name: 'token-7d-mid-reset',
|
|
2761
|
+
token: 'token-7d-mid-reset',
|
|
2749
2762
|
fiveHourUtilization: 0.1,
|
|
2750
2763
|
sevenDayUtilization: 0.5,
|
|
2751
2764
|
blocked: false,
|
|
2752
2765
|
rejected: false,
|
|
2753
|
-
modelWeeklyLimits: {
|
|
2766
|
+
modelWeeklyLimits: {
|
|
2767
|
+
seven_day_opus: {
|
|
2768
|
+
rejected: false,
|
|
2769
|
+
resetsAt: nowEpochSeconds + 50 * 3600,
|
|
2770
|
+
},
|
|
2771
|
+
},
|
|
2754
2772
|
},
|
|
2755
2773
|
{
|
|
2756
|
-
name: 'token-7d-
|
|
2757
|
-
token: 'token-7d-
|
|
2774
|
+
name: 'token-7d-soon-reset',
|
|
2775
|
+
token: 'token-7d-soon-reset',
|
|
2758
2776
|
fiveHourUtilization: 0.5,
|
|
2759
2777
|
sevenDayUtilization: 0.1,
|
|
2760
2778
|
blocked: false,
|
|
2761
2779
|
rejected: false,
|
|
2762
|
-
modelWeeklyLimits: {
|
|
2780
|
+
modelWeeklyLimits: {
|
|
2781
|
+
seven_day_opus: {
|
|
2782
|
+
rejected: false,
|
|
2783
|
+
resetsAt: nowEpochSeconds + 10 * 3600,
|
|
2784
|
+
},
|
|
2785
|
+
},
|
|
2763
2786
|
},
|
|
2764
2787
|
{
|
|
2765
|
-
name: 'token-7d-
|
|
2766
|
-
token: 'token-7d-
|
|
2788
|
+
name: 'token-7d-far-reset',
|
|
2789
|
+
token: 'token-7d-far-reset',
|
|
2767
2790
|
fiveHourUtilization: 0.3,
|
|
2768
2791
|
sevenDayUtilization: 0.7,
|
|
2769
2792
|
blocked: false,
|
|
2770
2793
|
rejected: false,
|
|
2771
|
-
modelWeeklyLimits: {
|
|
2794
|
+
modelWeeklyLimits: {
|
|
2795
|
+
seven_day_opus: {
|
|
2796
|
+
rejected: false,
|
|
2797
|
+
resetsAt: nowEpochSeconds + 150 * 3600,
|
|
2798
|
+
},
|
|
2799
|
+
},
|
|
2772
2800
|
},
|
|
2773
2801
|
]);
|
|
2774
2802
|
|
|
@@ -2787,13 +2815,13 @@ describe('StartPreparationUseCase', () => {
|
|
|
2787
2815
|
|
|
2788
2816
|
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(3);
|
|
2789
2817
|
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toMatchObject({
|
|
2790
|
-
env: { CLAUDE_CODE_OAUTH_TOKEN: 'token-7d-
|
|
2818
|
+
env: { CLAUDE_CODE_OAUTH_TOKEN: 'token-7d-soon-reset' },
|
|
2791
2819
|
});
|
|
2792
2820
|
expect(mockLocalCommandRunner.runCommand.mock.calls[1][2]).toMatchObject({
|
|
2793
|
-
env: { CLAUDE_CODE_OAUTH_TOKEN: 'token-7d-mid' },
|
|
2821
|
+
env: { CLAUDE_CODE_OAUTH_TOKEN: 'token-7d-mid-reset' },
|
|
2794
2822
|
});
|
|
2795
2823
|
expect(mockLocalCommandRunner.runCommand.mock.calls[2][2]).toMatchObject({
|
|
2796
|
-
env: { CLAUDE_CODE_OAUTH_TOKEN: 'token-7d-
|
|
2824
|
+
env: { CLAUDE_CODE_OAUTH_TOKEN: 'token-7d-far-reset' },
|
|
2797
2825
|
});
|
|
2798
2826
|
});
|
|
2799
2827
|
|
|
@@ -3399,6 +3427,294 @@ describe('StartPreparationUseCase', () => {
|
|
|
3399
3427
|
},
|
|
3400
3428
|
});
|
|
3401
3429
|
});
|
|
3430
|
+
|
|
3431
|
+
it('should pick the token whose 7-day reset is sooner before the token whose 7-day reset is farther', async () => {
|
|
3432
|
+
const awaitingIssue = createMockIssue({
|
|
3433
|
+
url: 'url1',
|
|
3434
|
+
title: 'Issue 1',
|
|
3435
|
+
labels: ['category:impl'],
|
|
3436
|
+
status: 'Awaiting Workspace',
|
|
3437
|
+
number: 1,
|
|
3438
|
+
itemId: 'item-1',
|
|
3439
|
+
});
|
|
3440
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
3441
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
3442
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
3443
|
+
);
|
|
3444
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
3445
|
+
stdout: '',
|
|
3446
|
+
stderr: '',
|
|
3447
|
+
exitCode: 0,
|
|
3448
|
+
});
|
|
3449
|
+
const nowEpochSeconds = Math.floor(Date.now() / 1000);
|
|
3450
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
3451
|
+
{
|
|
3452
|
+
name: 'token-b-far-reset',
|
|
3453
|
+
token: 'token-b-far-reset',
|
|
3454
|
+
fiveHourUtilization: 0.1,
|
|
3455
|
+
sevenDayUtilization: 0.1,
|
|
3456
|
+
blocked: false,
|
|
3457
|
+
rejected: false,
|
|
3458
|
+
modelWeeklyLimits: {
|
|
3459
|
+
seven_day_opus: {
|
|
3460
|
+
rejected: false,
|
|
3461
|
+
resetsAt: nowEpochSeconds + 100 * 3600,
|
|
3462
|
+
},
|
|
3463
|
+
},
|
|
3464
|
+
},
|
|
3465
|
+
{
|
|
3466
|
+
name: 'token-a-soon-reset',
|
|
3467
|
+
token: 'token-a-soon-reset',
|
|
3468
|
+
fiveHourUtilization: 0.1,
|
|
3469
|
+
sevenDayUtilization: 0.1,
|
|
3470
|
+
blocked: false,
|
|
3471
|
+
rejected: false,
|
|
3472
|
+
modelWeeklyLimits: {
|
|
3473
|
+
seven_day_opus: {
|
|
3474
|
+
rejected: false,
|
|
3475
|
+
resetsAt: nowEpochSeconds + 20 * 3600,
|
|
3476
|
+
},
|
|
3477
|
+
},
|
|
3478
|
+
},
|
|
3479
|
+
]);
|
|
3480
|
+
|
|
3481
|
+
await useCase.run({
|
|
3482
|
+
projectUrl: 'https://github.com/user/repo',
|
|
3483
|
+
defaultAgentName: 'agent1',
|
|
3484
|
+
defaultLlmModelName: 'claude-opus',
|
|
3485
|
+
defaultLlmAgentName: null,
|
|
3486
|
+
configFilePath: '/path/to/config.yml',
|
|
3487
|
+
maximumPreparingIssuesCount: null,
|
|
3488
|
+
utilizationPercentageThreshold: 90,
|
|
3489
|
+
allowedIssueAuthors: null,
|
|
3490
|
+
codexHomeCandidates: null,
|
|
3491
|
+
allowIssueCacheMinutes: 0,
|
|
3492
|
+
});
|
|
3493
|
+
|
|
3494
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
3495
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
3496
|
+
env: {
|
|
3497
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'token-a-soon-reset',
|
|
3498
|
+
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
3499
|
+
},
|
|
3500
|
+
});
|
|
3501
|
+
});
|
|
3502
|
+
|
|
3503
|
+
it('should exclude a blocked token even when it has a sooner 7-day reset than an eligible token', async () => {
|
|
3504
|
+
const awaitingIssue = createMockIssue({
|
|
3505
|
+
url: 'url1',
|
|
3506
|
+
title: 'Issue 1',
|
|
3507
|
+
labels: ['category:impl'],
|
|
3508
|
+
status: 'Awaiting Workspace',
|
|
3509
|
+
number: 1,
|
|
3510
|
+
itemId: 'item-1',
|
|
3511
|
+
});
|
|
3512
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
3513
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
3514
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
3515
|
+
);
|
|
3516
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
3517
|
+
stdout: '',
|
|
3518
|
+
stderr: '',
|
|
3519
|
+
exitCode: 0,
|
|
3520
|
+
});
|
|
3521
|
+
const nowEpochSeconds = Math.floor(Date.now() / 1000);
|
|
3522
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
3523
|
+
{
|
|
3524
|
+
name: 'token-a-blocked-soon-reset',
|
|
3525
|
+
token: 'token-a-blocked-soon-reset',
|
|
3526
|
+
fiveHourUtilization: 0.1,
|
|
3527
|
+
sevenDayUtilization: 0.1,
|
|
3528
|
+
blocked: true,
|
|
3529
|
+
rejected: false,
|
|
3530
|
+
modelWeeklyLimits: {
|
|
3531
|
+
seven_day_opus: {
|
|
3532
|
+
rejected: false,
|
|
3533
|
+
resetsAt: nowEpochSeconds + 20 * 3600,
|
|
3534
|
+
},
|
|
3535
|
+
},
|
|
3536
|
+
},
|
|
3537
|
+
{
|
|
3538
|
+
name: 'token-b-far-reset',
|
|
3539
|
+
token: 'token-b-far-reset',
|
|
3540
|
+
fiveHourUtilization: 0.1,
|
|
3541
|
+
sevenDayUtilization: 0.1,
|
|
3542
|
+
blocked: false,
|
|
3543
|
+
rejected: false,
|
|
3544
|
+
modelWeeklyLimits: {
|
|
3545
|
+
seven_day_opus: {
|
|
3546
|
+
rejected: false,
|
|
3547
|
+
resetsAt: nowEpochSeconds + 100 * 3600,
|
|
3548
|
+
},
|
|
3549
|
+
},
|
|
3550
|
+
},
|
|
3551
|
+
]);
|
|
3552
|
+
|
|
3553
|
+
await useCase.run({
|
|
3554
|
+
projectUrl: 'https://github.com/user/repo',
|
|
3555
|
+
defaultAgentName: 'agent1',
|
|
3556
|
+
defaultLlmModelName: 'claude-opus',
|
|
3557
|
+
defaultLlmAgentName: null,
|
|
3558
|
+
configFilePath: '/path/to/config.yml',
|
|
3559
|
+
maximumPreparingIssuesCount: null,
|
|
3560
|
+
utilizationPercentageThreshold: 90,
|
|
3561
|
+
allowedIssueAuthors: null,
|
|
3562
|
+
codexHomeCandidates: null,
|
|
3563
|
+
allowIssueCacheMinutes: 0,
|
|
3564
|
+
});
|
|
3565
|
+
|
|
3566
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
3567
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
3568
|
+
env: {
|
|
3569
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'token-b-far-reset',
|
|
3570
|
+
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
3571
|
+
},
|
|
3572
|
+
});
|
|
3573
|
+
});
|
|
3574
|
+
|
|
3575
|
+
it('should place a token whose 7-day reset is unknown after a token whose 7-day reset is known', async () => {
|
|
3576
|
+
const awaitingIssues: Issue[] = [
|
|
3577
|
+
createMockIssue({
|
|
3578
|
+
url: 'url1',
|
|
3579
|
+
title: 'Issue 1',
|
|
3580
|
+
labels: ['category:impl'],
|
|
3581
|
+
status: 'Awaiting Workspace',
|
|
3582
|
+
number: 1,
|
|
3583
|
+
itemId: 'item-1',
|
|
3584
|
+
}),
|
|
3585
|
+
createMockIssue({
|
|
3586
|
+
url: 'url2',
|
|
3587
|
+
title: 'Issue 2',
|
|
3588
|
+
labels: ['category:impl'],
|
|
3589
|
+
status: 'Awaiting Workspace',
|
|
3590
|
+
number: 2,
|
|
3591
|
+
itemId: 'item-2',
|
|
3592
|
+
}),
|
|
3593
|
+
];
|
|
3594
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
3595
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
3596
|
+
createMockStoryObjectMap(awaitingIssues),
|
|
3597
|
+
);
|
|
3598
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
3599
|
+
stdout: '',
|
|
3600
|
+
stderr: '',
|
|
3601
|
+
exitCode: 0,
|
|
3602
|
+
});
|
|
3603
|
+
const nowEpochSeconds = Math.floor(Date.now() / 1000);
|
|
3604
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
3605
|
+
{
|
|
3606
|
+
name: 'token-a-unknown-reset',
|
|
3607
|
+
token: 'token-a-unknown-reset',
|
|
3608
|
+
fiveHourUtilization: 0.1,
|
|
3609
|
+
sevenDayUtilization: 0.1,
|
|
3610
|
+
blocked: false,
|
|
3611
|
+
rejected: false,
|
|
3612
|
+
modelWeeklyLimits: {},
|
|
3613
|
+
},
|
|
3614
|
+
{
|
|
3615
|
+
name: 'token-b-known-soon-reset',
|
|
3616
|
+
token: 'token-b-known-soon-reset',
|
|
3617
|
+
fiveHourUtilization: 0.1,
|
|
3618
|
+
sevenDayUtilization: 0.1,
|
|
3619
|
+
blocked: false,
|
|
3620
|
+
rejected: false,
|
|
3621
|
+
modelWeeklyLimits: {
|
|
3622
|
+
seven_day_opus: {
|
|
3623
|
+
rejected: false,
|
|
3624
|
+
resetsAt: nowEpochSeconds + 20 * 3600,
|
|
3625
|
+
},
|
|
3626
|
+
},
|
|
3627
|
+
},
|
|
3628
|
+
]);
|
|
3629
|
+
|
|
3630
|
+
await useCase.run({
|
|
3631
|
+
projectUrl: 'https://github.com/user/repo',
|
|
3632
|
+
defaultAgentName: 'agent1',
|
|
3633
|
+
defaultLlmModelName: 'claude-opus',
|
|
3634
|
+
defaultLlmAgentName: null,
|
|
3635
|
+
configFilePath: '/path/to/config.yml',
|
|
3636
|
+
maximumPreparingIssuesCount: null,
|
|
3637
|
+
utilizationPercentageThreshold: 90,
|
|
3638
|
+
allowedIssueAuthors: null,
|
|
3639
|
+
codexHomeCandidates: null,
|
|
3640
|
+
allowIssueCacheMinutes: 0,
|
|
3641
|
+
});
|
|
3642
|
+
|
|
3643
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(2);
|
|
3644
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toMatchObject({
|
|
3645
|
+
env: { CLAUDE_CODE_OAUTH_TOKEN: 'token-b-known-soon-reset' },
|
|
3646
|
+
});
|
|
3647
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[1][2]).toMatchObject({
|
|
3648
|
+
env: { CLAUDE_CODE_OAUTH_TOKEN: 'token-a-unknown-reset' },
|
|
3649
|
+
});
|
|
3650
|
+
});
|
|
3651
|
+
|
|
3652
|
+
it('should fall back to 5-hour utilization ascending as tiebreaker when 7-day reset deadlines are identical', async () => {
|
|
3653
|
+
const awaitingIssue = createMockIssue({
|
|
3654
|
+
url: 'url1',
|
|
3655
|
+
title: 'Issue 1',
|
|
3656
|
+
labels: ['category:impl'],
|
|
3657
|
+
status: 'Awaiting Workspace',
|
|
3658
|
+
number: 1,
|
|
3659
|
+
itemId: 'item-1',
|
|
3660
|
+
});
|
|
3661
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
3662
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
3663
|
+
createMockStoryObjectMap([awaitingIssue]),
|
|
3664
|
+
);
|
|
3665
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
3666
|
+
stdout: '',
|
|
3667
|
+
stderr: '',
|
|
3668
|
+
exitCode: 0,
|
|
3669
|
+
});
|
|
3670
|
+
const nowEpochSeconds = Math.floor(Date.now() / 1000);
|
|
3671
|
+
const sharedResetsAt = nowEpochSeconds + 50 * 3600;
|
|
3672
|
+
mockClaudeTokenUsageRepository.getAvailableTokenUsages.mockResolvedValue([
|
|
3673
|
+
{
|
|
3674
|
+
name: 'token-busy-5h',
|
|
3675
|
+
token: 'token-busy-5h',
|
|
3676
|
+
fiveHourUtilization: 0.6,
|
|
3677
|
+
sevenDayUtilization: 0.1,
|
|
3678
|
+
blocked: false,
|
|
3679
|
+
rejected: false,
|
|
3680
|
+
modelWeeklyLimits: {
|
|
3681
|
+
seven_day_opus: { rejected: false, resetsAt: sharedResetsAt },
|
|
3682
|
+
},
|
|
3683
|
+
},
|
|
3684
|
+
{
|
|
3685
|
+
name: 'token-idle-5h',
|
|
3686
|
+
token: 'token-idle-5h',
|
|
3687
|
+
fiveHourUtilization: 0.1,
|
|
3688
|
+
sevenDayUtilization: 0.1,
|
|
3689
|
+
blocked: false,
|
|
3690
|
+
rejected: false,
|
|
3691
|
+
modelWeeklyLimits: {
|
|
3692
|
+
seven_day_opus: { rejected: false, resetsAt: sharedResetsAt },
|
|
3693
|
+
},
|
|
3694
|
+
},
|
|
3695
|
+
]);
|
|
3696
|
+
|
|
3697
|
+
await useCase.run({
|
|
3698
|
+
projectUrl: 'https://github.com/user/repo',
|
|
3699
|
+
defaultAgentName: 'agent1',
|
|
3700
|
+
defaultLlmModelName: 'claude-opus',
|
|
3701
|
+
defaultLlmAgentName: null,
|
|
3702
|
+
configFilePath: '/path/to/config.yml',
|
|
3703
|
+
maximumPreparingIssuesCount: null,
|
|
3704
|
+
utilizationPercentageThreshold: 90,
|
|
3705
|
+
allowedIssueAuthors: null,
|
|
3706
|
+
codexHomeCandidates: null,
|
|
3707
|
+
allowIssueCacheMinutes: 0,
|
|
3708
|
+
});
|
|
3709
|
+
|
|
3710
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
3711
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][2]).toEqual({
|
|
3712
|
+
env: {
|
|
3713
|
+
CLAUDE_CODE_OAUTH_TOKEN: 'token-idle-5h',
|
|
3714
|
+
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8787',
|
|
3715
|
+
},
|
|
3716
|
+
});
|
|
3717
|
+
});
|
|
3402
3718
|
});
|
|
3403
3719
|
|
|
3404
3720
|
describe('StartPreparationUseCase.buildRotationOrder', () => {
|
|
@@ -3444,25 +3760,36 @@ describe('StartPreparationUseCase.buildRotationOrder', () => {
|
|
|
3444
3760
|
mockClaudeTokenUsageRepositoryForRotation,
|
|
3445
3761
|
);
|
|
3446
3762
|
|
|
3447
|
-
it('lists selected tokens first in ascending 7-day
|
|
3448
|
-
const
|
|
3763
|
+
it('lists selected tokens first in ascending 7-day reset deadline order then excluded tokens', () => {
|
|
3764
|
+
const nowEpochSeconds = Math.floor(Date.now() / 1000);
|
|
3765
|
+
const tokenUsages: ClaudeTokenUsage[] = [
|
|
3449
3766
|
{
|
|
3450
|
-
name: '
|
|
3451
|
-
token: 'sk-ant-
|
|
3767
|
+
name: 'far-7d-reset',
|
|
3768
|
+
token: 'sk-ant-far',
|
|
3452
3769
|
fiveHourUtilization: 0.1,
|
|
3453
3770
|
sevenDayUtilization: 0.8,
|
|
3454
3771
|
blocked: false,
|
|
3455
3772
|
rejected: false,
|
|
3456
|
-
modelWeeklyLimits: {
|
|
3773
|
+
modelWeeklyLimits: {
|
|
3774
|
+
seven_day: {
|
|
3775
|
+
rejected: false,
|
|
3776
|
+
resetsAt: nowEpochSeconds + 100 * 3600,
|
|
3777
|
+
},
|
|
3778
|
+
},
|
|
3457
3779
|
},
|
|
3458
3780
|
{
|
|
3459
|
-
name: '
|
|
3460
|
-
token: 'sk-ant-
|
|
3781
|
+
name: 'soon-7d-reset',
|
|
3782
|
+
token: 'sk-ant-soon',
|
|
3461
3783
|
fiveHourUtilization: 0.5,
|
|
3462
3784
|
sevenDayUtilization: 0.1,
|
|
3463
3785
|
blocked: false,
|
|
3464
3786
|
rejected: false,
|
|
3465
|
-
modelWeeklyLimits: {
|
|
3787
|
+
modelWeeklyLimits: {
|
|
3788
|
+
seven_day: {
|
|
3789
|
+
rejected: false,
|
|
3790
|
+
resetsAt: nowEpochSeconds + 20 * 3600,
|
|
3791
|
+
},
|
|
3792
|
+
},
|
|
3466
3793
|
},
|
|
3467
3794
|
{
|
|
3468
3795
|
name: 'blocked-token',
|
|
@@ -3476,8 +3803,8 @@ describe('StartPreparationUseCase.buildRotationOrder', () => {
|
|
|
3476
3803
|
];
|
|
3477
3804
|
const result = useCase.buildRotationOrder(tokenUsages, 90, null);
|
|
3478
3805
|
|
|
3479
|
-
expect(result[0].name).toBe('
|
|
3480
|
-
expect(result[1].name).toBe('
|
|
3806
|
+
expect(result[0].name).toBe('soon-7d-reset');
|
|
3807
|
+
expect(result[1].name).toBe('far-7d-reset');
|
|
3481
3808
|
expect(result[2].name).toBe('blocked-token');
|
|
3482
3809
|
expect(result[2].blocked).toBe(true);
|
|
3483
3810
|
expect(result[2].thresholdExcluded).toBe(false);
|
|
@@ -53,6 +53,44 @@ export class StartPreparationUseCase {
|
|
|
53
53
|
return general !== undefined && general.rejected;
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
+
private secondsUntilSevenDayReset = (
|
|
57
|
+
usage: ClaudeTokenUsage,
|
|
58
|
+
weeklyLimitType: string,
|
|
59
|
+
nowEpochSeconds: number,
|
|
60
|
+
): number => {
|
|
61
|
+
const specific = usage.modelWeeklyLimits[weeklyLimitType];
|
|
62
|
+
if (specific !== undefined) {
|
|
63
|
+
return specific.resetsAt - nowEpochSeconds;
|
|
64
|
+
}
|
|
65
|
+
const general = usage.modelWeeklyLimits['seven_day'];
|
|
66
|
+
if (general !== undefined) {
|
|
67
|
+
return general.resetsAt - nowEpochSeconds;
|
|
68
|
+
}
|
|
69
|
+
return Number.POSITIVE_INFINITY;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
private compareBySevenDayDeadlineThenUtilization = (
|
|
73
|
+
a: ClaudeTokenUsage,
|
|
74
|
+
b: ClaudeTokenUsage,
|
|
75
|
+
weeklyLimitType: string,
|
|
76
|
+
nowEpochSeconds: number,
|
|
77
|
+
): number => {
|
|
78
|
+
const aSecondsUntilReset = this.secondsUntilSevenDayReset(
|
|
79
|
+
a,
|
|
80
|
+
weeklyLimitType,
|
|
81
|
+
nowEpochSeconds,
|
|
82
|
+
);
|
|
83
|
+
const bSecondsUntilReset = this.secondsUntilSevenDayReset(
|
|
84
|
+
b,
|
|
85
|
+
weeklyLimitType,
|
|
86
|
+
nowEpochSeconds,
|
|
87
|
+
);
|
|
88
|
+
if (aSecondsUntilReset !== bSecondsUntilReset) {
|
|
89
|
+
return aSecondsUntilReset - bSecondsUntilReset;
|
|
90
|
+
}
|
|
91
|
+
return a.fiveHourUtilization - b.fiveHourUtilization;
|
|
92
|
+
};
|
|
93
|
+
|
|
56
94
|
private getTokenConcurrentLimit = (sevenDayUtilization: number): number => {
|
|
57
95
|
if (sevenDayUtilization < SEVEN_DAY_THROTTLE_START_THRESHOLD) {
|
|
58
96
|
return SEVEN_DAY_NORMAL_CONCURRENT_LIMIT;
|
|
@@ -72,6 +110,7 @@ export class StartPreparationUseCase {
|
|
|
72
110
|
maxConcurrent: number,
|
|
73
111
|
): { tokens: string[]; effectiveCap: number } => {
|
|
74
112
|
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
113
|
+
const nowEpochSeconds = Date.now() / 1000;
|
|
75
114
|
const eligibleTokens = tokenUsages
|
|
76
115
|
.filter((usage) => !usage.blocked)
|
|
77
116
|
.filter((usage) => !usage.rejected)
|
|
@@ -82,7 +121,14 @@ export class StartPreparationUseCase {
|
|
|
82
121
|
(usage) =>
|
|
83
122
|
usage.fiveHourUtilization * 100 < utilizationPercentageThreshold,
|
|
84
123
|
)
|
|
85
|
-
.sort((a, b) =>
|
|
124
|
+
.sort((a, b) =>
|
|
125
|
+
this.compareBySevenDayDeadlineThenUtilization(
|
|
126
|
+
a,
|
|
127
|
+
b,
|
|
128
|
+
weeklyLimitType,
|
|
129
|
+
nowEpochSeconds,
|
|
130
|
+
),
|
|
131
|
+
);
|
|
86
132
|
|
|
87
133
|
if (eligibleTokens.length === 0) {
|
|
88
134
|
return { tokens: [], effectiveCap: 0 };
|
|
@@ -115,6 +161,7 @@ export class StartPreparationUseCase {
|
|
|
115
161
|
modelName: string | null,
|
|
116
162
|
): RotationOrderEntry[] => {
|
|
117
163
|
const weeklyLimitType = this.weeklyLimitTypeForModel(modelName);
|
|
164
|
+
const nowEpochSeconds = Date.now() / 1000;
|
|
118
165
|
const selectedTokens = tokenUsages
|
|
119
166
|
.filter((usage) => !usage.blocked)
|
|
120
167
|
.filter((usage) => !usage.rejected)
|
|
@@ -125,7 +172,14 @@ export class StartPreparationUseCase {
|
|
|
125
172
|
(usage) =>
|
|
126
173
|
usage.fiveHourUtilization * 100 < utilizationPercentageThreshold,
|
|
127
174
|
)
|
|
128
|
-
.sort((a, b) =>
|
|
175
|
+
.sort((a, b) =>
|
|
176
|
+
this.compareBySevenDayDeadlineThenUtilization(
|
|
177
|
+
a,
|
|
178
|
+
b,
|
|
179
|
+
weeklyLimitType,
|
|
180
|
+
nowEpochSeconds,
|
|
181
|
+
),
|
|
182
|
+
);
|
|
129
183
|
const selectedTokenValues = new Set(selectedTokens.map((u) => u.token));
|
|
130
184
|
const excluded: RotationOrderEntry[] = tokenUsages
|
|
131
185
|
.filter((usage) => !selectedTokenValues.has(usage.token))
|
|
@@ -18,6 +18,8 @@ export declare class StartPreparationUseCase {
|
|
|
18
18
|
constructor(projectRepository: Pick<ProjectRepository, 'getByUrl'>, issueRepository: Pick<IssueRepository, 'getStoryObjectMap' | 'updateStatus' | 'findRelatedOpenPRs' | 'getOpenPullRequest' | 'closePullRequest' | 'deletePullRequestBranch' | 'createCommentByUrl'>, localCommandRunner: LocalCommandRunner, claudeTokenUsageRepository: ClaudeTokenUsageRepository);
|
|
19
19
|
private weeklyLimitTypeForModel;
|
|
20
20
|
private isModelWeeklyLimitRejected;
|
|
21
|
+
private secondsUntilSevenDayReset;
|
|
22
|
+
private compareBySevenDayDeadlineThenUtilization;
|
|
21
23
|
private getTokenConcurrentLimit;
|
|
22
24
|
private selectRotationTokens;
|
|
23
25
|
buildRotationOrder: (tokenUsages: ClaudeTokenUsage[], utilizationPercentageThreshold: number, modelName: string | null) => RotationOrderEntry[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAShE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAUhC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,0BAA0B;gBAZ1B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EACtD,eAAe,EAAE,IAAI,CACpC,eAAe,EACb,mBAAmB,GACnB,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,kBAAkB,GAClB,yBAAyB,GACzB,oBAAoB,CACvB,EACgB,kBAAkB,EAAE,kBAAkB,EACtC,0BAA0B,EAAE,0BAA0B;IAGzE,OAAO,CAAC,uBAAuB,CAK7B;IAEF,OAAO,CAAC,0BAA0B,CAQhC;IAEF,OAAO,CAAC,uBAAuB,CAU7B;IAEF,OAAO,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"StartPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAShE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAUhC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,0BAA0B;gBAZ1B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EACtD,eAAe,EAAE,IAAI,CACpC,eAAe,EACb,mBAAmB,GACnB,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,kBAAkB,GAClB,yBAAyB,GACzB,oBAAoB,CACvB,EACgB,kBAAkB,EAAE,kBAAkB,EACtC,0BAA0B,EAAE,0BAA0B;IAGzE,OAAO,CAAC,uBAAuB,CAK7B;IAEF,OAAO,CAAC,0BAA0B,CAQhC;IAEF,OAAO,CAAC,yBAAyB,CAc/B;IAEF,OAAO,CAAC,wCAAwC,CAoB9C;IAEF,OAAO,CAAC,uBAAuB,CAU7B;IAEF,OAAO,CAAC,oBAAoB,CAkD1B;IAEF,kBAAkB,GAChB,aAAa,gBAAgB,EAAE,EAC/B,gCAAgC,MAAM,EACtC,WAAW,MAAM,GAAG,IAAI,KACvB,kBAAkB,EAAE,CA6CrB;IAEF,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,cAAc,EAAE,MAAM,CAAC;QACvB,2BAA2B,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3C,8BAA8B,EAAE,MAAM,CAAC;QACvC,mBAAmB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACrC,mBAAmB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACrC,sBAAsB,EAAE,MAAM,CAAC;KAChC,KAAG,OAAO,CAAC;QAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAA;KAAE,CAAC,CAmPzD;CACH"}
|