github-issue-tower-defence-management 1.191.0 → 1.193.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 (26) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/bin/adapter/entry-points/console/consoleOperationApi.js +9 -2
  3. package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
  4. package/bin/adapter/entry-points/console/ui-dist/assets/{index-B22eMy23.js → index-RaFqjB7u.js} +3 -3
  5. package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
  6. package/bin/domain/usecases/StartPreparationUseCase.js +58 -20
  7. package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/adapter/entry-points/console/consoleOperationApi.test.ts +19 -5
  10. package/src/adapter/entry-points/console/consoleOperationApi.ts +18 -1
  11. package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +35 -1
  12. package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +13 -1
  13. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.stories.tsx +7 -0
  14. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.test.tsx +82 -0
  15. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.tsx +23 -3
  16. package/src/adapter/entry-points/console/ui/src/features/console/logic/operations.ts +4 -3
  17. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +79 -0
  18. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.tsx +19 -3
  19. package/src/adapter/entry-points/console/ui-dist/assets/{index-B22eMy23.js → index-RaFqjB7u.js} +3 -3
  20. package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
  21. package/src/domain/usecases/StartPreparationUseCase.test.ts +104 -1
  22. package/src/domain/usecases/StartPreparationUseCase.ts +121 -31
  23. package/types/adapter/entry-points/console/consoleOperationApi.d.ts +1 -0
  24. package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
  25. package/types/domain/usecases/StartPreparationUseCase.d.ts +10 -1
  26. package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>TDPM Console</title>
7
- <script type="module" crossorigin src="/assets/index-B22eMy23.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-RaFqjB7u.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-CLHvrafO.css">
9
9
  </head>
10
10
  <body>
@@ -1,4 +1,7 @@
1
- import { StartPreparationUseCase } from './StartPreparationUseCase';
1
+ import {
2
+ SPAWN_CANDIDATE_BRANCH_SOURCE_CONCURRENCY,
3
+ StartPreparationUseCase,
4
+ } from './StartPreparationUseCase';
2
5
  import {
3
6
  IssueRepository,
4
7
  RelatedPullRequest,
@@ -7283,3 +7286,103 @@ describe('StartPreparationUseCase.getTokenConcurrentLimit', () => {
7283
7286
  expect(useCase.getTokenConcurrentLimit(0.1, 0.1, 0.01)).toBe(1);
7284
7287
  });
7285
7288
  });
7289
+
7290
+ describe('StartPreparationUseCase.fetchSpawnCandidateBranchSources', () => {
7291
+ const buildRelatedPullRequest = (url: string): RelatedPullRequest => ({
7292
+ url,
7293
+ branchName: 'feature',
7294
+ createdAt: new Date('2026-01-01T00:00:00Z'),
7295
+ isDraft: false,
7296
+ isConflicted: false,
7297
+ mergeable: 'MERGEABLE',
7298
+ isPassedAllCiJob: true,
7299
+ isCiStateSuccess: true,
7300
+ isResolvedAllReviewComments: true,
7301
+ isBranchOutOfDate: false,
7302
+ missingRequiredCheckNames: [],
7303
+ });
7304
+
7305
+ const buildUseCase = (
7306
+ issueRepositoryOverrides: Partial<
7307
+ ConstructorParameters<typeof StartPreparationUseCase>[1]
7308
+ >,
7309
+ ): StartPreparationUseCase =>
7310
+ new StartPreparationUseCase(
7311
+ {
7312
+ getByUrl: jest.fn(),
7313
+ createField: jest.fn(),
7314
+ updateAgentList: jest.fn(),
7315
+ },
7316
+ {
7317
+ getStoryObjectMap: jest.fn(),
7318
+ getAllOpened: jest.fn(),
7319
+ updateStatus: jest.fn(),
7320
+ findRelatedOpenPRs: jest.fn(),
7321
+ getOpenPullRequest: jest.fn(),
7322
+ closePullRequest: jest.fn(),
7323
+ deletePullRequestBranch: jest.fn(),
7324
+ createCommentByUrl: jest.fn(),
7325
+ setIssueAgentField: jest.fn(),
7326
+ removeLabel: jest.fn(),
7327
+ ...issueRepositoryOverrides,
7328
+ },
7329
+ { runCommand: jest.fn() },
7330
+ {
7331
+ ensureObservable: jest.fn(),
7332
+ getAvailableTokenUsages: jest.fn(),
7333
+ getTokenInFlightCounts: jest.fn(),
7334
+ proxyBaseUrl: jest.fn(),
7335
+ },
7336
+ {
7337
+ listSpawns: jest.fn().mockReturnValue([]),
7338
+ listRunningIssueUrls: jest.fn().mockReturnValue([]),
7339
+ },
7340
+ );
7341
+
7342
+ it('looks up related open pull requests for issue urls concurrently up to the configured limit', async () => {
7343
+ const issueUrls = Array.from(
7344
+ { length: 20 },
7345
+ (_, index) => `https://github.com/owner/repo/issues/${index + 1}`,
7346
+ );
7347
+ let inFlightCount = 0;
7348
+ let observedMaxInFlight = 0;
7349
+ const findRelatedOpenPRs = jest.fn(async (issueUrl: string) => {
7350
+ inFlightCount += 1;
7351
+ observedMaxInFlight = Math.max(observedMaxInFlight, inFlightCount);
7352
+ await new Promise((resolve) => setTimeout(resolve, 1));
7353
+ inFlightCount -= 1;
7354
+ return [buildRelatedPullRequest(issueUrl.replace('/issues/', '/pull/'))];
7355
+ });
7356
+ const useCase = buildUseCase({ findRelatedOpenPRs });
7357
+
7358
+ const branchSources =
7359
+ await useCase.fetchSpawnCandidateBranchSources(issueUrls);
7360
+
7361
+ expect(findRelatedOpenPRs).toHaveBeenCalledTimes(20);
7362
+ expect(observedMaxInFlight).toBe(SPAWN_CANDIDATE_BRANCH_SOURCE_CONCURRENCY);
7363
+ expect(branchSources.size).toBe(20);
7364
+ for (const issueUrl of issueUrls) {
7365
+ expect(branchSources.get(issueUrl)?.relatedOpenPullRequests).toHaveLength(
7366
+ 1,
7367
+ );
7368
+ expect(branchSources.get(issueUrl)?.openPullRequest).toBeNull();
7369
+ }
7370
+ });
7371
+
7372
+ it('resolves pull request urls through the open pull request lookup instead of the timeline query', async () => {
7373
+ const prUrl = 'https://github.com/owner/repo/pull/7';
7374
+ const openPullRequest = buildRelatedPullRequest(prUrl);
7375
+ const getOpenPullRequest = jest.fn().mockResolvedValue(openPullRequest);
7376
+ const findRelatedOpenPRs = jest.fn();
7377
+ const useCase = buildUseCase({ getOpenPullRequest, findRelatedOpenPRs });
7378
+
7379
+ const branchSources = await useCase.fetchSpawnCandidateBranchSources([
7380
+ prUrl,
7381
+ ]);
7382
+
7383
+ expect(getOpenPullRequest).toHaveBeenCalledWith(prUrl);
7384
+ expect(findRelatedOpenPRs).not.toHaveBeenCalled();
7385
+ expect(branchSources.get(prUrl)?.openPullRequest).toBe(openPullRequest);
7386
+ expect(branchSources.get(prUrl)?.relatedOpenPullRequests).toEqual([]);
7387
+ });
7388
+ });
@@ -1,4 +1,8 @@
1
- import { IssueRepository } from './adapter-interfaces/IssueRepository';
1
+ import {
2
+ IssueRepository,
3
+ RelatedPullRequest,
4
+ } from './adapter-interfaces/IssueRepository';
5
+ import { Issue } from '../entities/Issue';
2
6
  import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
3
7
  import { LocalCommandRunner } from './adapter-interfaces/LocalCommandRunner';
4
8
  import { ClaudeTokenUsageRepository } from './adapter-interfaces/ClaudeTokenUsageRepository';
@@ -19,6 +23,19 @@ const SEVEN_DAY_THROTTLE_START_THRESHOLD = 0.8;
19
23
  const FIVE_HOUR_THROTTLE_START_THRESHOLD = 0.8;
20
24
  export const DEFAULT_FALLBACK_LLM_MODEL_NAME = 'claude-opus-4-8';
21
25
  const LLM_AGENT_LABEL_PREFIX = 'llm-agent:';
26
+ export const SPAWN_CANDIDATE_BRANCH_SOURCE_CONCURRENCY = 8;
27
+
28
+ export type SpawnCandidateExclusionReason =
29
+ | 'dependedIssueUrls'
30
+ | 'futureNextActionDate'
31
+ | 'nextActionHourNotReached'
32
+ | 'authorNotAllowed'
33
+ | 'notAssignedToManager';
34
+
35
+ export type SpawnCandidateBranchSource = {
36
+ openPullRequest: RelatedPullRequest | null;
37
+ relatedOpenPullRequests: RelatedPullRequest[];
38
+ };
22
39
 
23
40
  export const agentNameFromDesignation = (designation: string): string =>
24
41
  designation.startsWith(LLM_AGENT_LABEL_PREFIX)
@@ -173,6 +190,79 @@ export class StartPreparationUseCase {
173
190
  );
174
191
  };
175
192
 
193
+ spawnCandidateExclusionReasonOf = (
194
+ issue: Issue,
195
+ allowedIssueAuthors: string[] | null,
196
+ manager: string,
197
+ now: Date,
198
+ ): SpawnCandidateExclusionReason | null => {
199
+ if (issue.dependedIssueUrls.length > 0) {
200
+ return 'dependedIssueUrls';
201
+ }
202
+ if (issueReactivationTriggerIsPending(issue, now)) {
203
+ const startOfTomorrow = new Date(
204
+ Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1),
205
+ );
206
+ return issue.nextActionDate !== null &&
207
+ issue.nextActionDate >= startOfTomorrow
208
+ ? 'futureNextActionDate'
209
+ : 'nextActionHourNotReached';
210
+ }
211
+ if (
212
+ allowedIssueAuthors === null ||
213
+ allowedIssueAuthors.length === 0 ||
214
+ !allowedIssueAuthors.includes(issue.author)
215
+ ) {
216
+ return 'authorNotAllowed';
217
+ }
218
+ if (!issue.assignees.includes(manager)) {
219
+ return 'notAssignedToManager';
220
+ }
221
+ return null;
222
+ };
223
+
224
+ fetchSpawnCandidateBranchSources = async (
225
+ issueUrls: string[],
226
+ ): Promise<Map<string, SpawnCandidateBranchSource>> => {
227
+ const branchSourceByIssueUrl = new Map<
228
+ string,
229
+ SpawnCandidateBranchSource
230
+ >();
231
+ let nextIndex = 0;
232
+ const fetchSequentially = async (): Promise<void> => {
233
+ while (nextIndex < issueUrls.length) {
234
+ const issueUrl = issueUrls[nextIndex];
235
+ nextIndex += 1;
236
+ branchSourceByIssueUrl.set(
237
+ issueUrl,
238
+ issueUrl.includes('/pull/')
239
+ ? {
240
+ openPullRequest:
241
+ await this.issueRepository.getOpenPullRequest(issueUrl),
242
+ relatedOpenPullRequests: [],
243
+ }
244
+ : {
245
+ openPullRequest: null,
246
+ relatedOpenPullRequests:
247
+ await this.issueRepository.findRelatedOpenPRs(issueUrl),
248
+ },
249
+ );
250
+ }
251
+ };
252
+ await Promise.all(
253
+ Array.from(
254
+ {
255
+ length: Math.min(
256
+ SPAWN_CANDIDATE_BRANCH_SOURCE_CONCURRENCY,
257
+ issueUrls.length,
258
+ ),
259
+ },
260
+ fetchSequentially,
261
+ ),
262
+ );
263
+ return branchSourceByIssueUrl;
264
+ };
265
+
176
266
  private selectRotationTokens = (
177
267
  tokenUsages: ClaudeTokenUsage[],
178
268
  utilizationPercentageThreshold: number,
@@ -437,6 +527,21 @@ export class StartPreparationUseCase {
437
527
 
438
528
  const now = new Date();
439
529
 
530
+ const branchSourceByIssueUrl = await this.fetchSpawnCandidateBranchSources(
531
+ awaitingWorkspaceIssues
532
+ .filter(
533
+ (issue) =>
534
+ !runningIssueUrls.has(issue.url) &&
535
+ this.spawnCandidateExclusionReasonOf(
536
+ issue,
537
+ params.allowedIssueAuthors,
538
+ params.manager,
539
+ now,
540
+ ) === null,
541
+ )
542
+ .map((issue) => issue.url),
543
+ );
544
+
440
545
  for (
441
546
  let i = 0;
442
547
  i < awaitingWorkspaceIssues.length &&
@@ -452,34 +557,21 @@ export class StartPreparationUseCase {
452
557
  console.warn(`Skipping ${issue.url}: worker already running.`);
453
558
  continue;
454
559
  }
455
- if (issueReactivationTriggerIsPending(issue, now)) {
456
- const startOfTomorrow = new Date(
457
- Date.UTC(
458
- now.getUTCFullYear(),
459
- now.getUTCMonth(),
460
- now.getUTCDate() + 1,
461
- ),
462
- );
463
- if (
464
- issue.nextActionDate !== null &&
465
- issue.nextActionDate >= startOfTomorrow
466
- ) {
467
- exclusionCounts.futureNextActionDate++;
468
- } else {
469
- exclusionCounts.nextActionHourNotReached++;
470
- }
471
- continue;
472
- }
473
- if (
474
- params.allowedIssueAuthors === null ||
475
- params.allowedIssueAuthors.length === 0 ||
476
- !params.allowedIssueAuthors.includes(issue.author)
477
- ) {
478
- exclusionCounts.authorNotAllowed++;
560
+ const exclusionReason = this.spawnCandidateExclusionReasonOf(
561
+ issue,
562
+ params.allowedIssueAuthors,
563
+ params.manager,
564
+ now,
565
+ );
566
+ if (exclusionReason !== null) {
567
+ exclusionCounts[exclusionReason]++;
479
568
  continue;
480
569
  }
481
- if (!issue.assignees.includes(params.manager)) {
482
- exclusionCounts.notAssignedToManager++;
570
+ const branchSource = branchSourceByIssueUrl.get(issue.url);
571
+ if (branchSource === undefined) {
572
+ console.error(
573
+ `Skipping ${issue.url}: no branch source was prefetched for this spawn candidate.`,
574
+ );
483
575
  continue;
484
576
  }
485
577
  await adoptIssueAgentDesignationLabel(
@@ -538,7 +630,7 @@ export class StartPreparationUseCase {
538
630
  const isPrUrl = issue.url.includes('/pull/');
539
631
  let branchName: string;
540
632
  if (isPrUrl) {
541
- const pr = await this.issueRepository.getOpenPullRequest(issue.url);
633
+ const pr = branchSource.openPullRequest;
542
634
  if (pr === null) {
543
635
  console.warn(
544
636
  `Skipping non-OPEN PR ${issue.url}: wrapper requires an open PR.`,
@@ -551,9 +643,7 @@ export class StartPreparationUseCase {
551
643
  }
552
644
  branchName = pr.branchName;
553
645
  } else {
554
- const relatedPRs = await this.issueRepository.findRelatedOpenPRs(
555
- issue.url,
556
- );
646
+ const relatedPRs = branchSource.relatedOpenPullRequests;
557
647
  const sameRepoRelatedPRs = relatedPRs.filter((pr) => {
558
648
  const match = /^https?:\/\/[^/]+\/([^/]+\/[^/]+)\//.exec(pr.url);
559
649
  return match === null || match[1] === issue.nameWithOwner;
@@ -3,6 +3,7 @@ import type { IssueAttachmentRepository } from '../../../domain/usecases/adapter
3
3
  import type { IssueRepository } from '../../../domain/usecases/adapter-interfaces/IssueRepository';
4
4
  import type { ProjectRepository } from '../../../domain/usecases/adapter-interfaces/ProjectRepository';
5
5
  export declare const AWAITING_WORKSPACE_STATUS_NAME = "awaiting workspace";
6
+ export declare const CONFLICT_RETURNED_MESSAGE = "Auto Status Check: CONFLICT\nThis pull request has a merge conflict and has been returned to Awaiting Workspace.";
6
7
  export declare const IN_TMUX_BY_HUMAN_STATUS_NAME = "in tmux by human";
7
8
  export declare const CHORE_LABEL_NAME = "chore";
8
9
  export type ConsoleProjectBinding = {
@@ -1 +1 @@
1
- {"version":3,"file":"consoleOperationApi.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/consoleOperationApi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"consoleOperationApi.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/consoleOperationApi.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,17 @@
1
- import { IssueRepository } from './adapter-interfaces/IssueRepository';
1
+ import { IssueRepository, RelatedPullRequest } from './adapter-interfaces/IssueRepository';
2
+ import { Issue } from '../entities/Issue';
2
3
  import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
3
4
  import { LocalCommandRunner } from './adapter-interfaces/LocalCommandRunner';
4
5
  import { ClaudeTokenUsageRepository } from './adapter-interfaces/ClaudeTokenUsageRepository';
5
6
  import { TakeOwnershipSpawnRepository } from './adapter-interfaces/TakeOwnershipSpawnRepository';
6
7
  import { ClaudeTokenUsage } from '../entities/ClaudeTokenUsage';
7
8
  export declare const DEFAULT_FALLBACK_LLM_MODEL_NAME = "claude-opus-4-8";
9
+ export declare const SPAWN_CANDIDATE_BRANCH_SOURCE_CONCURRENCY = 8;
10
+ export type SpawnCandidateExclusionReason = 'dependedIssueUrls' | 'futureNextActionDate' | 'nextActionHourNotReached' | 'authorNotAllowed' | 'notAssignedToManager';
11
+ export type SpawnCandidateBranchSource = {
12
+ openPullRequest: RelatedPullRequest | null;
13
+ relatedOpenPullRequests: RelatedPullRequest[];
14
+ };
8
15
  export declare const agentNameFromDesignation: (designation: string) => string;
9
16
  export type RotationOrderEntry = {
10
17
  name: string;
@@ -29,6 +36,8 @@ export declare class StartPreparationUseCase {
29
36
  private compareBySevenDayDeadlineThenUtilization;
30
37
  private taperedConcurrentLimit;
31
38
  getTokenConcurrentLimit: (fiveHourUtilization: number, sevenDayUtilization: number, selectionWeight?: number) => number;
39
+ spawnCandidateExclusionReasonOf: (issue: Issue, allowedIssueAuthors: string[] | null, manager: string, now: Date) => SpawnCandidateExclusionReason | null;
40
+ fetchSpawnCandidateBranchSources: (issueUrls: string[]) => Promise<Map<string, SpawnCandidateBranchSource>>;
32
41
  private selectRotationTokens;
33
42
  buildRotationOrder: (tokenUsages: ClaudeTokenUsage[], utilizationPercentageThreshold: number, modelName: string | null) => RotationOrderEntry[];
34
43
  run: (params: {
@@ -1 +1 @@
1
- {"version":3,"file":"StartPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"StartPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}