github-issue-tower-defence-management 1.194.2 → 1.196.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.
Files changed (38) hide show
  1. package/.github/workflows/codeql.yml +2 -2
  2. package/CHANGELOG.md +19 -0
  3. package/README.md +2 -2
  4. package/bin/adapter/entry-points/cli/fleetConfig.js +2 -0
  5. package/bin/adapter/entry-points/cli/fleetConfig.js.map +1 -1
  6. package/bin/adapter/entry-points/handlers/OauthTokenSelectHandler.js +1 -1
  7. package/bin/adapter/entry-points/handlers/OauthTokenSelectHandler.js.map +1 -1
  8. package/bin/domain/usecases/LiveSessionOauthTokenSelectUseCase.js +17 -2
  9. package/bin/domain/usecases/LiveSessionOauthTokenSelectUseCase.js.map +1 -1
  10. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +36 -0
  11. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
  12. package/bin/domain/usecases/OauthTokenSelectUseCase.js +18 -10
  13. package/bin/domain/usecases/OauthTokenSelectUseCase.js.map +1 -1
  14. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +23 -3
  15. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
  16. package/package.json +2 -2
  17. package/src/adapter/entry-points/cli/fleetConfig.test.ts +33 -1
  18. package/src/adapter/entry-points/cli/fleetConfig.ts +16 -0
  19. package/src/adapter/entry-points/handlers/OauthTokenSelectHandler.test.ts +78 -0
  20. package/src/adapter/entry-points/handlers/OauthTokenSelectHandler.ts +2 -0
  21. package/src/domain/usecases/LiveSessionOauthTokenSelectUseCase.test.ts +137 -17
  22. package/src/domain/usecases/LiveSessionOauthTokenSelectUseCase.ts +30 -2
  23. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +346 -0
  24. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +64 -0
  25. package/src/domain/usecases/OauthTokenSelectUseCase.test.ts +99 -0
  26. package/src/domain/usecases/OauthTokenSelectUseCase.ts +30 -5
  27. package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +400 -1
  28. package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +44 -3
  29. package/types/adapter/entry-points/cli/fleetConfig.d.ts.map +1 -1
  30. package/types/adapter/entry-points/handlers/OauthTokenSelectHandler.d.ts.map +1 -1
  31. package/types/domain/usecases/LiveSessionOauthTokenSelectUseCase.d.ts +3 -0
  32. package/types/domain/usecases/LiveSessionOauthTokenSelectUseCase.d.ts.map +1 -1
  33. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +1 -0
  34. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
  35. package/types/domain/usecases/OauthTokenSelectUseCase.d.ts +7 -1
  36. package/types/domain/usecases/OauthTokenSelectUseCase.d.ts.map +1 -1
  37. package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts +1 -0
  38. package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
@@ -816,7 +816,7 @@ describe('RevertOrphanedPreparationUseCase', () => {
816
816
  );
817
817
  });
818
818
 
819
- it('should advance orphaned issue with non-developer agent field to Awaiting Quality Check when no conflicting PR exists', async () => {
819
+ it('should advance orphaned issue with non-developer agent field to Awaiting Quality Check when no linked PRs exist', async () => {
820
820
  const stuckIssue = createMockIssue({
821
821
  url: 'https://github.com/user/repo/issues/10',
822
822
  status: 'Preparation',
@@ -2133,6 +2133,405 @@ describe('RevertOrphanedPreparationUseCase', () => {
2133
2133
  });
2134
2134
  });
2135
2135
 
2136
+ describe('non-developer agent CI failure reassignment', () => {
2137
+ const makeProjectWithDeveloper = (developerName = 'developer') => {
2138
+ const project = createMockProject();
2139
+ project.agent = {
2140
+ name: 'Agent',
2141
+ fieldId: 'agent-field-id',
2142
+ options: [
2143
+ {
2144
+ id: 'opt-developer',
2145
+ name: developerName,
2146
+ color: 'GRAY',
2147
+ description: '',
2148
+ },
2149
+ ],
2150
+ };
2151
+ return project;
2152
+ };
2153
+
2154
+ it('should return to Awaiting Workspace and reassign to developer when chore agent has exactly one linked PR with failing CI', async () => {
2155
+ const projectWithDeveloper = makeProjectWithDeveloper();
2156
+ mockProjectRepository.findProjectIdByUrl.mockResolvedValue('project-1');
2157
+ mockProjectRepository.getProject.mockResolvedValue(projectWithDeveloper);
2158
+ mockProjectRepository.getByUrl.mockResolvedValue(projectWithDeveloper);
2159
+ const stuckIssue = createMockIssue({
2160
+ url: 'https://github.com/user/repo/issues/10',
2161
+ status: 'Preparation',
2162
+ labels: [],
2163
+ agent: 'chore',
2164
+ });
2165
+ mockIssueRepository.getAllIssues.mockResolvedValue({
2166
+ project: projectWithDeveloper,
2167
+ issues: [stuckIssue],
2168
+ cacheUsed: false,
2169
+ });
2170
+ mockIssueRepository.get.mockImplementation(async (issueUrl: string) =>
2171
+ createMockIssue({
2172
+ url: issueUrl,
2173
+ status: 'Preparation',
2174
+ agent: 'chore',
2175
+ }),
2176
+ );
2177
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
2178
+ stdout: '',
2179
+ stderr: '',
2180
+ exitCode: 1,
2181
+ });
2182
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2183
+ {
2184
+ author: 'bot',
2185
+ content: 'From: :robot: agent report',
2186
+ createdAt: new Date(),
2187
+ },
2188
+ ]);
2189
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2190
+ {
2191
+ ...createPassingPr(),
2192
+ url: 'https://github.com/user/repo/pull/99',
2193
+ isPassedAllCiJob: false,
2194
+ isCiStateSuccess: false,
2195
+ },
2196
+ ]);
2197
+
2198
+ await useCase.run({
2199
+ projectUrl: 'https://github.com/user/repo',
2200
+ preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2201
+ thresholdForAutoReject: 3,
2202
+ });
2203
+
2204
+ expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([
2205
+ [stuckIssue.url, projectWithDeveloper, 'opt-developer'],
2206
+ ]);
2207
+ expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2208
+ expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
2209
+ expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(
2210
+ 1,
2211
+ );
2212
+ expect(
2213
+ mockIssueCommentRepository.createComment.mock.calls[0][1],
2214
+ ).toContain('ANY_CI_JOB_FAILED_OR_IN_PROGRESS');
2215
+ expect(
2216
+ mockIssueCommentRepository.createComment.mock.calls[0][1],
2217
+ ).toContain('https://github.com/user/repo/pull/99');
2218
+ });
2219
+
2220
+ it('should advance to Awaiting Quality Check when chore agent has exactly one linked PR where all CI passes', async () => {
2221
+ const stuckIssue = createMockIssue({
2222
+ url: 'https://github.com/user/repo/issues/10',
2223
+ status: 'Preparation',
2224
+ labels: [],
2225
+ agent: 'chore',
2226
+ });
2227
+ mockIssueRepository.getAllIssues.mockResolvedValue({
2228
+ project: mockProject,
2229
+ issues: [stuckIssue],
2230
+ cacheUsed: false,
2231
+ });
2232
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
2233
+ stdout: '',
2234
+ stderr: '',
2235
+ exitCode: 1,
2236
+ });
2237
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2238
+ {
2239
+ author: 'bot',
2240
+ content: 'From: :robot: agent report',
2241
+ createdAt: new Date(),
2242
+ },
2243
+ ]);
2244
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2245
+ createPassingPr(),
2246
+ ]);
2247
+
2248
+ await useCase.run({
2249
+ projectUrl: 'https://github.com/user/repo',
2250
+ preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2251
+ thresholdForAutoReject: 3,
2252
+ });
2253
+
2254
+ expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2255
+ expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2256
+ expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
2257
+ });
2258
+
2259
+ it('should advance to Awaiting Quality Check when chore agent has no linked PRs', async () => {
2260
+ const stuckIssue = createMockIssue({
2261
+ url: 'https://github.com/user/repo/issues/10',
2262
+ status: 'Preparation',
2263
+ labels: [],
2264
+ agent: 'chore',
2265
+ });
2266
+ mockIssueRepository.getAllIssues.mockResolvedValue({
2267
+ project: mockProject,
2268
+ issues: [stuckIssue],
2269
+ cacheUsed: false,
2270
+ });
2271
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
2272
+ stdout: '',
2273
+ stderr: '',
2274
+ exitCode: 1,
2275
+ });
2276
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2277
+ {
2278
+ author: 'bot',
2279
+ content: 'From: :robot: agent report',
2280
+ createdAt: new Date(),
2281
+ },
2282
+ ]);
2283
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
2284
+
2285
+ await useCase.run({
2286
+ projectUrl: 'https://github.com/user/repo',
2287
+ preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2288
+ thresholdForAutoReject: 3,
2289
+ });
2290
+
2291
+ expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2292
+ expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2293
+ expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
2294
+ });
2295
+
2296
+ it('should not trigger the new path when developer agent has a failing CI PR', async () => {
2297
+ const stuckIssue = createMockIssue({
2298
+ url: 'https://github.com/user/repo/issues/10',
2299
+ status: 'Preparation',
2300
+ labels: ['llm-agent:developer'],
2301
+ agent: 'developer',
2302
+ });
2303
+ mockIssueRepository.getAllIssues.mockResolvedValue({
2304
+ project: mockProject,
2305
+ issues: [stuckIssue],
2306
+ cacheUsed: false,
2307
+ });
2308
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
2309
+ stdout: '',
2310
+ stderr: '',
2311
+ exitCode: 1,
2312
+ });
2313
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2314
+ {
2315
+ author: 'bot',
2316
+ content: 'From: :robot: agent report',
2317
+ createdAt: new Date(),
2318
+ },
2319
+ ]);
2320
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2321
+ {
2322
+ ...createPassingPr(),
2323
+ isPassedAllCiJob: false,
2324
+ isCiStateSuccess: false,
2325
+ },
2326
+ ]);
2327
+
2328
+ await useCase.run({
2329
+ projectUrl: 'https://github.com/user/repo',
2330
+ preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2331
+ thresholdForAutoReject: 3,
2332
+ });
2333
+
2334
+ expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2335
+ expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2336
+ expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
2337
+ });
2338
+
2339
+ it('should not trigger the new path when agent is pr-reviewer and PR has failing CI', async () => {
2340
+ const stuckIssue = createMockIssue({
2341
+ url: 'https://github.com/user/repo/issues/10',
2342
+ status: 'Preparation',
2343
+ labels: [],
2344
+ agent: 'pr-reviewer',
2345
+ });
2346
+ mockIssueRepository.getAllIssues.mockResolvedValue({
2347
+ project: mockProject,
2348
+ issues: [stuckIssue],
2349
+ cacheUsed: false,
2350
+ });
2351
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
2352
+ stdout: '',
2353
+ stderr: '',
2354
+ exitCode: 1,
2355
+ });
2356
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2357
+ {
2358
+ author: 'bot',
2359
+ content: 'From: :robot: agent report',
2360
+ createdAt: new Date(),
2361
+ },
2362
+ ]);
2363
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2364
+ {
2365
+ ...createPassingPr(),
2366
+ isPassedAllCiJob: false,
2367
+ isCiStateSuccess: false,
2368
+ },
2369
+ ]);
2370
+
2371
+ await useCase.run({
2372
+ projectUrl: 'https://github.com/user/repo',
2373
+ preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2374
+ thresholdForAutoReject: 3,
2375
+ });
2376
+
2377
+ expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2378
+ expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2379
+ expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
2380
+ });
2381
+
2382
+ it('should not trigger the new path when agent is null and PR has failing CI', async () => {
2383
+ const stuckIssue = createMockIssue({
2384
+ url: 'https://github.com/user/repo/issues/10',
2385
+ status: 'Preparation',
2386
+ labels: [],
2387
+ agent: null,
2388
+ });
2389
+ mockIssueRepository.getAllIssues.mockResolvedValue({
2390
+ project: mockProject,
2391
+ issues: [stuckIssue],
2392
+ cacheUsed: false,
2393
+ });
2394
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
2395
+ stdout: '',
2396
+ stderr: '',
2397
+ exitCode: 1,
2398
+ });
2399
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2400
+ {
2401
+ author: 'bot',
2402
+ content: 'From: :robot: agent report',
2403
+ createdAt: new Date(),
2404
+ },
2405
+ ]);
2406
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2407
+ {
2408
+ ...createPassingPr(),
2409
+ isPassedAllCiJob: false,
2410
+ isCiStateSuccess: false,
2411
+ },
2412
+ ]);
2413
+
2414
+ await useCase.run({
2415
+ projectUrl: 'https://github.com/user/repo',
2416
+ preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2417
+ thresholdForAutoReject: 3,
2418
+ });
2419
+
2420
+ expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2421
+ expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2422
+ expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
2423
+ });
2424
+
2425
+ it('should not trigger the new path when chore agent has two linked PRs both with failing CI', async () => {
2426
+ const stuckIssue = createMockIssue({
2427
+ url: 'https://github.com/user/repo/issues/10',
2428
+ status: 'Preparation',
2429
+ labels: [],
2430
+ agent: 'chore',
2431
+ });
2432
+ mockIssueRepository.getAllIssues.mockResolvedValue({
2433
+ project: mockProject,
2434
+ issues: [stuckIssue],
2435
+ cacheUsed: false,
2436
+ });
2437
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
2438
+ stdout: '',
2439
+ stderr: '',
2440
+ exitCode: 1,
2441
+ });
2442
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2443
+ {
2444
+ author: 'bot',
2445
+ content: 'From: :robot: agent report',
2446
+ createdAt: new Date(),
2447
+ },
2448
+ ]);
2449
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2450
+ {
2451
+ ...createPassingPr(),
2452
+ url: 'https://github.com/user/repo/pull/99',
2453
+ isPassedAllCiJob: false,
2454
+ },
2455
+ {
2456
+ ...createPassingPr(),
2457
+ url: 'https://github.com/user/repo/pull/100',
2458
+ isPassedAllCiJob: false,
2459
+ },
2460
+ ]);
2461
+
2462
+ await useCase.run({
2463
+ projectUrl: 'https://github.com/user/repo',
2464
+ preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2465
+ thresholdForAutoReject: 3,
2466
+ });
2467
+
2468
+ expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2469
+ expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2470
+ expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
2471
+ });
2472
+
2473
+ it('should reassign to the configured developerAgentName when chore agent has a failing CI PR', async () => {
2474
+ const projectWithCustomDeveloper =
2475
+ makeProjectWithDeveloper('custom-developer');
2476
+ mockProjectRepository.findProjectIdByUrl.mockResolvedValue('project-1');
2477
+ mockProjectRepository.getProject.mockResolvedValue(
2478
+ projectWithCustomDeveloper,
2479
+ );
2480
+ mockProjectRepository.getByUrl.mockResolvedValue(
2481
+ projectWithCustomDeveloper,
2482
+ );
2483
+ const stuckIssue = createMockIssue({
2484
+ url: 'https://github.com/user/repo/issues/10',
2485
+ status: 'Preparation',
2486
+ labels: [],
2487
+ agent: 'chore',
2488
+ });
2489
+ mockIssueRepository.getAllIssues.mockResolvedValue({
2490
+ project: projectWithCustomDeveloper,
2491
+ issues: [stuckIssue],
2492
+ cacheUsed: false,
2493
+ });
2494
+ mockIssueRepository.get.mockImplementation(async (issueUrl: string) =>
2495
+ createMockIssue({
2496
+ url: issueUrl,
2497
+ status: 'Preparation',
2498
+ agent: 'chore',
2499
+ }),
2500
+ );
2501
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
2502
+ stdout: '',
2503
+ stderr: '',
2504
+ exitCode: 1,
2505
+ });
2506
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2507
+ {
2508
+ author: 'bot',
2509
+ content: 'From: :robot: agent report',
2510
+ createdAt: new Date(),
2511
+ },
2512
+ ]);
2513
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2514
+ {
2515
+ ...createPassingPr(),
2516
+ url: 'https://github.com/user/repo/pull/99',
2517
+ isPassedAllCiJob: false,
2518
+ isCiStateSuccess: false,
2519
+ },
2520
+ ]);
2521
+
2522
+ await useCase.run({
2523
+ projectUrl: 'https://github.com/user/repo',
2524
+ preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2525
+ thresholdForAutoReject: 3,
2526
+ developerAgentName: 'custom-developer',
2527
+ });
2528
+
2529
+ expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([
2530
+ [stuckIssue.url, projectWithCustomDeveloper, 'opt-developer'],
2531
+ ]);
2532
+ });
2533
+ });
2534
+
2136
2535
  it('should revert orphaned issue to Awaiting Workspace and not throw when getCommentsFromIssue returns 404', async () => {
2137
2536
  const stuckIssue = createMockIssue({
2138
2537
  url: 'https://github.com/user/repo/issues/10',
@@ -44,7 +44,8 @@ type OrphanedPreparationOutcome =
44
44
  | 'advanceToQualityCheck'
45
45
  | 'returnToLabelSelectedAgent'
46
46
  | 'returnToOwnerApprovalCycle'
47
- | 'reject';
47
+ | 'reject'
48
+ | 'reassignToDeveloper';
48
49
 
49
50
  export class RevertOrphanedPreparationUseCase {
50
51
  constructor(
@@ -84,6 +85,7 @@ export class RevertOrphanedPreparationUseCase {
84
85
  labelsNotRequiringPullRequest?: string[] | null;
85
86
  allowedIssueAuthors?: string[] | null;
86
87
  ownerApprovalTimeoutCycles?: number | null;
88
+ developerAgentName?: string | null;
87
89
  }): Promise<void> => {
88
90
  const projectId = await this.projectRepository.findProjectIdByUrl(
89
91
  params.projectUrl,
@@ -129,10 +131,11 @@ export class RevertOrphanedPreparationUseCase {
129
131
  if (!isOrphaned) {
130
132
  continue;
131
133
  }
132
- const { outcome, comments } = await this.evaluateOutcome(
134
+ const { outcome, comments, ciFailingPrUrl } = await this.evaluateOutcome(
133
135
  issue,
134
136
  resolveLabelsNotRequiringPullRequest(params),
135
137
  params.allowedIssueAuthors,
138
+ params.developerAgentName,
136
139
  );
137
140
  const isStillInPreparation = await this.isStillInPreparation(
138
141
  issue,
@@ -242,6 +245,32 @@ export class RevertOrphanedPreparationUseCase {
242
245
  }
243
246
  continue;
244
247
  }
248
+ if (outcome === 'reassignToDeveloper' && ciFailingPrUrl) {
249
+ const effectiveDeveloperAgentName =
250
+ params.developerAgentName ?? 'developer';
251
+ const agentOptionId = await ensureAgentOptionAndGetId(
252
+ this.projectRepository,
253
+ project,
254
+ effectiveDeveloperAgentName,
255
+ );
256
+ if (agentOptionId !== null) {
257
+ await this.issueRepository.setIssueAgentField(
258
+ issue.url,
259
+ project,
260
+ agentOptionId,
261
+ );
262
+ }
263
+ await this.issueRepository.updateStatus(
264
+ project,
265
+ issue,
266
+ awaitingWorkspaceStatusOption.id,
267
+ );
268
+ await this.issueCommentRepository.createComment(
269
+ issue,
270
+ `Auto Status Check: REJECTED\n- ANY_CI_JOB_FAILED_OR_IN_PROGRESS: ${ciFailingPrUrl}`,
271
+ );
272
+ continue;
273
+ }
245
274
  if (outcome === 'returnToLabelSelectedAgent') {
246
275
  await this.issueRepository.updateStatus(
247
276
  project,
@@ -340,9 +369,11 @@ export class RevertOrphanedPreparationUseCase {
340
369
  issue: Issue,
341
370
  labelsNotRequiringPullRequest: string[],
342
371
  allowedIssueAuthors: string[] | null | undefined,
372
+ developerAgentName?: string | null,
343
373
  ): Promise<{
344
374
  outcome: OrphanedPreparationOutcome;
345
375
  comments: Comment[];
376
+ ciFailingPrUrl?: string;
346
377
  }> => {
347
378
  if (issue.isClosed) {
348
379
  return { outcome: 'advanceToQualityCheck', comments: [] };
@@ -404,8 +435,9 @@ export class RevertOrphanedPreparationUseCase {
404
435
  const categoryLabels = issue.labels.filter((label) =>
405
436
  label.startsWith('category:'),
406
437
  );
438
+ const effectiveDeveloperName = developerAgentName ?? 'developer';
407
439
  const isNonDeveloperAgent =
408
- issue.agent != null && issue.agent !== 'developer';
440
+ issue.agent != null && issue.agent !== effectiveDeveloperName;
409
441
  const hasLabelNotRequiringPullRequest = issue.labels.some((label) =>
410
442
  labelsNotRequiringPullRequest.includes(label),
411
443
  );
@@ -420,6 +452,15 @@ export class RevertOrphanedPreparationUseCase {
420
452
  if (prsToCheck.some((pr) => pr.isConflicted)) {
421
453
  return { outcome: 'reject', comments };
422
454
  }
455
+ if (isNonDeveloperAgent && issue.agent !== 'pr-reviewer') {
456
+ if (prsToCheck.length === 1 && !prsToCheck[0].isPassedAllCiJob) {
457
+ return {
458
+ outcome: 'reassignToDeveloper',
459
+ comments,
460
+ ciFailingPrUrl: prsToCheck[0].url,
461
+ };
462
+ }
463
+ }
423
464
  return { outcome: 'advanceToQualityCheck', comments };
424
465
  }
425
466
 
@@ -1 +1 @@
1
- {"version":3,"file":"fleetConfig.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/fleetConfig.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,sCAAsC,EACvC,MAAM,6DAA6D,CAAC;AAErE,eAAO,MAAM,2CAA2C,sBAAsB,CAAC;AAE/E,eAAO,MAAM,8CAA8C,mCACzB,CAAC;AAEnC,eAAO,MAAM,0BAA0B,GACrC,UAAU,MAAM,GAAG,IAAI,KACtB,MAAM,GAAG,IAUX,CAAC;AAwDF,eAAO,MAAM,0CAA0C,GACrD,qBAAqB,MAAM,GAAG,IAAI,KACjC,sCA0BF,CAAC"}
1
+ {"version":3,"file":"fleetConfig.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/fleetConfig.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,sCAAsC,EACvC,MAAM,6DAA6D,CAAC;AAErE,eAAO,MAAM,2CAA2C,sBAAsB,CAAC;AAE/E,eAAO,MAAM,8CAA8C,mCACzB,CAAC;AAEnC,eAAO,MAAM,0BAA0B,GACrC,UAAU,MAAM,GAAG,IAAI,KACtB,MAAM,GAAG,IAUX,CAAC;AAwDF,eAAO,MAAM,0CAA0C,GACrD,qBAAqB,MAAM,GAAG,IAAI,KACjC,sCA0CF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"OauthTokenSelectHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/OauthTokenSelectHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,uBAAuB,EACvB,KAAK,eAAe,EACrB,MAAM,kDAAkD,CAAC;AAQ1D,MAAM,MAAM,4BAA4B,GAAG;IACzC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAKF,eAAO,MAAM,wBAAwB,GACnC,cAAc,MAAM,GAAG,IAAI,KAC1B,MAAM,GAAG,IASX,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,mBAAmB,MAAM,GAAG,IAAI,KAC/B,MASF,CAAC;AAEF,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,GAAE,uBAAuD,EAChE,MAAM,GAAE,eAA6B;IAGxD,MAAM,GACJ,OAAO,4BAA4B,KAClC,6BAA6B,CAgE9B;IAEF,OAAO,CAAC,iBAAiB,CAuBvB;CACH"}
1
+ {"version":3,"file":"OauthTokenSelectHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/OauthTokenSelectHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,uBAAuB,EACvB,KAAK,eAAe,EACrB,MAAM,kDAAkD,CAAC;AAQ1D,MAAM,MAAM,4BAA4B,GAAG;IACzC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAKF,eAAO,MAAM,wBAAwB,GACnC,cAAc,MAAM,GAAG,IAAI,KAC1B,MAAM,GAAG,IASX,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,mBAAmB,MAAM,GAAG,IAAI,KAC/B,MASF,CAAC;AAEF,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,GAAE,uBAAuD,EAChE,MAAM,GAAE,eAA6B;IAGxD,MAAM,GACJ,OAAO,4BAA4B,KAClC,6BAA6B,CAiE9B;IAEF,OAAO,CAAC,iBAAiB,CAuBvB;CACH"}
@@ -3,6 +3,8 @@ import { type OauthTokenCandidate, OauthTokenSelectUseCase } from './OauthTokenS
3
3
  export type LiveSessionOauthTokenSelectionSettings = {
4
4
  maxConcurrentSessionCount: number;
5
5
  fullSpeedFiveHourFreeRatio: number;
6
+ minFiveHourFreeRatio: number;
7
+ minSevenDayFreeRatio: number;
6
8
  };
7
9
  export declare const DEFAULT_LIVE_SESSION_OAUTH_TOKEN_SELECTION_SETTINGS: LiveSessionOauthTokenSelectionSettings;
8
10
  export declare const liveSessionConcurrentLimitOf: (fiveHourFreeRatio: number, selectionWeight: number, settings: LiveSessionOauthTokenSelectionSettings) => number;
@@ -26,6 +28,7 @@ export declare class LiveSessionOauthTokenSelectUseCase {
26
28
  private readonly rateLimitSelectUseCase;
27
29
  constructor(rateLimitSelectUseCase?: OauthTokenSelectUseCase);
28
30
  run: (candidates: OauthTokenCandidate[], liveSessions: ClaudeLiveSession[], nowEpochSeconds: number, settings: LiveSessionOauthTokenSelectionSettings) => LiveSessionOauthTokenSelectResult;
31
+ private liveSessionExclusionReason;
29
32
  private preferred;
30
33
  private liveSessionCountByToken;
31
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"LiveSessionOauthTokenSelectUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/LiveSessionOauthTokenSelectUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AAC1F,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EAExB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,sCAAsC,GAAG;IACnD,yBAAyB,EAAE,MAAM,CAAC;IAClC,0BAA0B,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,eAAO,MAAM,mDAAmD,EAAE,sCAI/D,CAAC;AAEJ,eAAO,MAAM,4BAA4B,GACvC,mBAAmB,MAAM,EACzB,iBAAiB,MAAM,EACvB,UAAU,sCAAsC,KAC/C,MAaF,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,OAAO,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,qCAAqC,EAAE,CAAC;CAClD,CAAC;AAEF,qBAAa,kCAAkC;IAE3C,OAAO,CAAC,QAAQ,CAAC,sBAAsB;gBAAtB,sBAAsB,GAAE,uBAAuD;IAGlG,GAAG,GACD,YAAY,mBAAmB,EAAE,EACjC,cAAc,iBAAiB,EAAE,EACjC,iBAAiB,MAAM,EACvB,UAAU,sCAAsC,KAC/C,iCAAiC,CAgDlC;IAEF,OAAO,CAAC,SAAS,CAgBf;IAEF,OAAO,CAAC,uBAAuB,CAe7B;CACH"}
1
+ {"version":3,"file":"LiveSessionOauthTokenSelectUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/LiveSessionOauthTokenSelectUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AAC1F,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EAExB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,sCAAsC,GAAG;IACnD,yBAAyB,EAAE,MAAM,CAAC;IAClC,0BAA0B,EAAE,MAAM,CAAC;IACnC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,mDAAmD,EAAE,sCAM/D,CAAC;AAEJ,eAAO,MAAM,4BAA4B,GACvC,mBAAmB,MAAM,EACzB,iBAAiB,MAAM,EACvB,UAAU,sCAAsC,KAC/C,MAaF,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,OAAO,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,qCAAqC,EAAE,CAAC;CAClD,CAAC;AAEF,qBAAa,kCAAkC;IAE3C,OAAO,CAAC,QAAQ,CAAC,sBAAsB;gBAAtB,sBAAsB,GAAE,uBAAuD;IAGlG,GAAG,GACD,YAAY,mBAAmB,EAAE,EACjC,cAAc,iBAAiB,EAAE,EACjC,iBAAiB,MAAM,EACvB,UAAU,sCAAsC,KAC/C,iCAAiC,CAsDlC;IAEF,OAAO,CAAC,0BAA0B,CAgBhC;IAEF,OAAO,CAAC,SAAS,CAgBf;IAEF,OAAO,CAAC,uBAAuB,CAe7B;CACH"}
@@ -42,6 +42,7 @@ export declare class NotifyFinishedIssuePreparationUseCase {
42
42
  private collectRejections;
43
43
  private reportBodyHasNextStep;
44
44
  private setDependedIssueUrlForAllOpenPRs;
45
+ private resolveLinkedPrWithCiFailure;
45
46
  private resolveOpenPrsForPrItem;
46
47
  private sendWorkflowBlockerNotification;
47
48
  private resolveConsoleTargetTab;
@@ -1 +1 @@
1
- {"version":3,"file":"NotifyFinishedIssuePreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NotifyFinishedIssuePreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"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"}
@@ -29,14 +29,20 @@ export type OauthTokenSelectResult = {
29
29
  selected: OauthTokenCandidate | null;
30
30
  metrics: OauthTokenCandidateMetrics[];
31
31
  };
32
+ export type OauthTokenSelectionThresholds = {
33
+ fiveHourMinFreeRatio: number;
34
+ sevenDayMinFreeRatio: number;
35
+ };
32
36
  export declare const FIVE_HOUR_MIN_FREE_RATIO = 0.25;
33
37
  export declare const SEVEN_DAY_MIN_FREE_RATIO = 0.03;
38
+ export declare const DEFAULT_OAUTH_TOKEN_SELECTION_THRESHOLDS: OauthTokenSelectionThresholds;
39
+ export declare const CL_SCRIPT_OAUTH_TOKEN_SELECTION_THRESHOLDS: OauthTokenSelectionThresholds;
34
40
  export declare const SEVEN_DAY_WINDOW_HOURS = 168;
35
41
  export declare const MIN_HOURS_TO_RESET = 1;
36
42
  export declare const sevenDayUrgencyFactor: (sevenDayFreeRatio: number, sevenDayEndEpoch: number, nowEpochSeconds: number) => number;
37
43
  export declare const selectWeightedCandidate: <Entry>(eligible: Entry[], weightOf: (entry: Entry) => number, deterministicBest: Entry, random: SelectionRandom) => Entry;
38
44
  export declare class OauthTokenSelectUseCase {
39
- run: (candidates: OauthTokenCandidate[], nowEpochSeconds: number, random?: SelectionRandom) => OauthTokenSelectResult;
45
+ run: (candidates: OauthTokenCandidate[], nowEpochSeconds: number, random?: SelectionRandom, thresholds?: OauthTokenSelectionThresholds) => OauthTokenSelectResult;
40
46
  private evaluate;
41
47
  private exclusionReason;
42
48
  private fiveHourFreeRatio;
@@ -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;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC;AAE3C,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,eAAO,MAAM,iBAAiB,GAAI,WAAW,mBAAmB,KAAG,MAGlE,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;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB,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,OAAO,CAAC;AAC7C,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAGpC,eAAO,MAAM,qBAAqB,GAChC,mBAAmB,MAAM,EACzB,kBAAkB,MAAM,EACxB,iBAAiB,MAAM,KACtB,MAMF,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,KAAK,EAC3C,UAAU,KAAK,EAAE,EACjB,UAAU,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,EAClC,mBAAmB,KAAK,EACxB,QAAQ,eAAe,KACtB,KAkBF,CAAC;AAEF,qBAAa,uBAAuB;IAClC,GAAG,GACD,YAAY,mBAAmB,EAAE,EACjC,iBAAiB,MAAM,EACvB,SAAQ,eAA6B,KACpC,sBAAsB,CAwCvB;IAEF,OAAO,CAAC,QAAQ,CAiCd;IAEF,OAAO,CAAC,eAAe,CAuBrB;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;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC;AAE3C,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,eAAO,MAAM,iBAAiB,GAAI,WAAW,mBAAmB,KAAG,MAGlE,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;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,0BAA0B,EAAE,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAKF,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,eAAO,MAAM,wCAAwC,EAAE,6BAIpD,CAAC;AAEJ,eAAO,MAAM,0CAA0C,EAAE,6BAItD,CAAC;AAEJ,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAGpC,eAAO,MAAM,qBAAqB,GAChC,mBAAmB,MAAM,EACzB,kBAAkB,MAAM,EACxB,iBAAiB,MAAM,KACtB,MAMF,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,KAAK,EAC3C,UAAU,KAAK,EAAE,EACjB,UAAU,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,EAClC,mBAAmB,KAAK,EACxB,QAAQ,eAAe,KACtB,KAkBF,CAAC;AAEF,qBAAa,uBAAuB;IAClC,GAAG,GACD,YAAY,mBAAmB,EAAE,EACjC,iBAAiB,MAAM,EACvB,SAAQ,eAA6B,EACrC,aAAY,6BAAwE,KACnF,sBAAsB,CA4CvB;IAEF,OAAO,CAAC,QAAQ,CAmCd;IAEF,OAAO,CAAC,eAAe,CAwBrB;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"}
@@ -20,6 +20,7 @@ export declare class RevertOrphanedPreparationUseCase {
20
20
  labelsNotRequiringPullRequest?: string[] | null;
21
21
  allowedIssueAuthors?: string[] | null;
22
22
  ownerApprovalTimeoutCycles?: number | null;
23
+ developerAgentName?: string | null;
23
24
  }) => Promise<void>;
24
25
  private isStillInPreparation;
25
26
  private evaluateOutcome;
@@ -1 +1 @@
1
- {"version":3,"file":"RevertOrphanedPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/RevertOrphanedPreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AA0C7E,qBAAa,gCAAgC;IAEzC,QAAQ,CAAC,iBAAiB,EAAE,IAAI,CAC9B,iBAAiB,EACf,oBAAoB,GACpB,YAAY,GACZ,aAAa,GACb,UAAU,GACV,iBAAiB,CACpB;IACD,QAAQ,CAAC,eAAe,EAAE,IAAI,CAC5B,eAAe,EACb,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,KAAK,GACL,oBAAoB,CACvB;IACD,QAAQ,CAAC,sBAAsB,EAAE,IAAI,CACnC,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC;IACD,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB;gBArBtC,iBAAiB,EAAE,IAAI,CAC9B,iBAAiB,EACf,oBAAoB,GACpB,YAAY,GACZ,aAAa,GACb,UAAU,GACV,iBAAiB,CACpB,EACQ,eAAe,EAAE,IAAI,CAC5B,eAAe,EACb,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,KAAK,GACL,oBAAoB,CACvB,EACQ,sBAAsB,EAAE,IAAI,CACnC,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC,EACQ,kBAAkB,EAAE,kBAAkB;IAGjD,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,8BAA8B,EAAE,MAAM,CAAC;QACvC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3C,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACvC,6BAA6B,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAChD,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACtC,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5C,KAAG,OAAO,CAAC,IAAI,CAAC,CAmOf;IAEF,OAAO,CAAC,oBAAoB,CAqB1B;IAEF,OAAO,CAAC,eAAe,CAwGrB;IAEF,OAAO,CAAC,uBAAuB,CAQ7B;IAEF,OAAO,CAAC,qBAAqB,CAyB3B;IAEF,OAAO,CAAC,eAAe,CA6BrB;IAEF,OAAO,CAAC,YAAY,CA+BlB;CACH"}
1
+ {"version":3,"file":"RevertOrphanedPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/RevertOrphanedPreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AA2C7E,qBAAa,gCAAgC;IAEzC,QAAQ,CAAC,iBAAiB,EAAE,IAAI,CAC9B,iBAAiB,EACf,oBAAoB,GACpB,YAAY,GACZ,aAAa,GACb,UAAU,GACV,iBAAiB,CACpB;IACD,QAAQ,CAAC,eAAe,EAAE,IAAI,CAC5B,eAAe,EACb,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,KAAK,GACL,oBAAoB,CACvB;IACD,QAAQ,CAAC,sBAAsB,EAAE,IAAI,CACnC,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC;IACD,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB;gBArBtC,iBAAiB,EAAE,IAAI,CAC9B,iBAAiB,EACf,oBAAoB,GACpB,YAAY,GACZ,aAAa,GACb,UAAU,GACV,iBAAiB,CACpB,EACQ,eAAe,EAAE,IAAI,CAC5B,eAAe,EACb,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,KAAK,GACL,oBAAoB,CACvB,EACQ,sBAAsB,EAAE,IAAI,CACnC,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC,EACQ,kBAAkB,EAAE,kBAAkB;IAGjD,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,8BAA8B,EAAE,MAAM,CAAC;QACvC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3C,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACvC,6BAA6B,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAChD,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACtC,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3C,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACpC,KAAG,OAAO,CAAC,IAAI,CAAC,CA8Pf;IAEF,OAAO,CAAC,oBAAoB,CAqB1B;IAEF,OAAO,CAAC,eAAe,CAoHrB;IAEF,OAAO,CAAC,uBAAuB,CAQ7B;IAEF,OAAO,CAAC,qBAAqB,CAyB3B;IAEF,OAAO,CAAC,eAAe,CA6BrB;IAEF,OAAO,CAAC,YAAY,CA+BlB;CACH"}