github-issue-tower-defence-management 1.143.2 → 1.143.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bin/adapter/entry-points/console/ui-dist/assets/index-1G1iHxrl.css +2 -0
  3. package/bin/adapter/entry-points/console/ui-dist/assets/index-vdcFItOm.js +81 -0
  4. package/bin/adapter/entry-points/console/ui-dist/index.html +2 -2
  5. package/bin/domain/usecases/StartPreparationUseCase.js +23 -3
  6. package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/adapter/entry-points/console/ui/src/features/console/components/shared/ConsoleClipboardCopyButton.test.tsx +34 -0
  9. package/src/adapter/entry-points/console/ui/src/features/console/components/shared/ConsoleClipboardCopyButton.tsx +29 -6
  10. package/src/adapter/entry-points/console/ui/src/features/console/logic/clipboard.test.ts +90 -0
  11. package/src/adapter/entry-points/console/ui/src/features/console/logic/clipboard.ts +37 -0
  12. package/src/adapter/entry-points/console/ui-dist/assets/index-1G1iHxrl.css +2 -0
  13. package/src/adapter/entry-points/console/ui-dist/assets/index-vdcFItOm.js +81 -0
  14. package/src/adapter/entry-points/console/ui-dist/index.html +2 -2
  15. package/src/domain/usecases/StartPreparationUseCase.test.ts +44 -0
  16. package/src/domain/usecases/StartPreparationUseCase.ts +40 -3
  17. package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
  18. package/bin/adapter/entry-points/console/ui-dist/assets/index-BWy8G--c.js +0 -81
  19. package/bin/adapter/entry-points/console/ui-dist/assets/index-Bp-p-XOs.css +0 -2
  20. package/src/adapter/entry-points/console/ui-dist/assets/index-BWy8G--c.js +0 -81
  21. package/src/adapter/entry-points/console/ui-dist/assets/index-Bp-p-XOs.css +0 -2
@@ -4,8 +4,8 @@
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-BWy8G--c.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-Bp-p-XOs.css">
7
+ <script type="module" crossorigin src="/assets/index-vdcFItOm.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-1G1iHxrl.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -189,6 +189,50 @@ describe('StartPreparationUseCase', () => {
189
189
  ]);
190
190
  });
191
191
 
192
+ it('keeps an issue out of Preparation when the aw command exits non-zero', async () => {
193
+ const awaitingIssues: Issue[] = [
194
+ createMockIssue({
195
+ url: 'url1',
196
+ title: 'Issue 1',
197
+ labels: ['category:impl'],
198
+ status: 'Awaiting Workspace',
199
+ }),
200
+ ];
201
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
202
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
203
+ createMockStoryObjectMap(awaitingIssues),
204
+ );
205
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
206
+ stdout: 'The URL includes test-repository. Exiting.',
207
+ stderr: '',
208
+ exitCode: 1,
209
+ });
210
+
211
+ await useCase.run({
212
+ projectUrl: 'https://github.com/user/repo',
213
+ defaultAgentName: 'agent1',
214
+ defaultLlmModelName: 'claude-opus',
215
+ fallbackLlmModelName: null,
216
+ defaultLlmAgentName: null,
217
+ configFilePath: '/path/to/config.yml',
218
+ maximumPreparingIssuesCount: null,
219
+ utilizationPercentageThreshold: 90,
220
+ allowedIssueAuthors: ['testuser'],
221
+ manager: 'manager-user',
222
+ codexHomeCandidates: null,
223
+ labelsAsLlmAgentName: null,
224
+ });
225
+
226
+ expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
227
+ expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(2);
228
+ expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('2');
229
+ expect(mockIssueRepository.updateStatus.mock.calls[1][2]).toBe('1');
230
+ expect(mockIssueRepository.updateStatus.mock.calls[1][1]).toMatchObject({
231
+ url: 'url1',
232
+ });
233
+ expect(awaitingIssues[0].status).toBe('Awaiting Workspace');
234
+ });
235
+
192
236
  it('skips an issue whose URL is already in the running worker list', async () => {
193
237
  const runningUrl = 'https://github.com/user/repo/issues/1';
194
238
  const awaitingIssues: Issue[] = [
@@ -370,6 +370,9 @@ export class StartPreparationUseCase {
370
370
  );
371
371
  return { rotationOrder };
372
372
  }
373
+ const awaitingWorkspaceStatusOption = project.status.statuses.find(
374
+ (s) => s.name === AWAITING_WORKSPACE_STATUS_NAME,
375
+ );
373
376
 
374
377
  const runningIssueUrls = new Set(
375
378
  this.takeOwnershipSpawnRepository.listRunningIssueUrls(),
@@ -571,8 +574,29 @@ export class StartPreparationUseCase {
571
574
  );
572
575
  issue.status = PREPARATION_STATUS_NAME;
573
576
 
577
+ const revertToAwaitingWorkspace = async (
578
+ reason: string,
579
+ ): Promise<void> => {
580
+ console.error(
581
+ `Reverting ${issue.url} to ${AWAITING_WORKSPACE_STATUS_NAME} because no worker was spawned: ${reason}`,
582
+ );
583
+ if (!awaitingWorkspaceStatusOption) {
584
+ console.error(
585
+ `Awaiting Workspace status option '${AWAITING_WORKSPACE_STATUS_NAME}' not found in project. ${issue.url} stays in ${PREPARATION_STATUS_NAME} without a worker.`,
586
+ );
587
+ return;
588
+ }
589
+ await this.issueRepository.updateStatus(
590
+ project,
591
+ issue,
592
+ awaitingWorkspaceStatusOption.id,
593
+ );
594
+ issue.status = AWAITING_WORKSPACE_STATUS_NAME;
595
+ };
596
+
574
597
  let spawnEnv: Record<string, string> | undefined;
575
598
  let routedModelName: string | null = null;
599
+ let selectedTokenName: string | null = null;
576
600
  if (rotationTokens !== null && proxyBaseUrl !== null) {
577
601
  const tokenWithSoonestResetAmongAvailable = selectedTokensWithLimits
578
602
  .map((t) => ({
@@ -592,12 +616,14 @@ export class StartPreparationUseCase {
592
616
  return b.remaining - a.remaining;
593
617
  })[0];
594
618
  if (tokenWithSoonestResetAmongAvailable === undefined) {
619
+ await revertToAwaitingWorkspace(
620
+ 'every Claude OAuth token reached its concurrent worker limit',
621
+ );
595
622
  break;
596
623
  }
597
624
  const selected = tokenWithSoonestResetAmongAvailable.token;
598
625
  routedModelName = tokenWithSoonestResetAmongAvailable.model;
599
- spawnedInThisRunByToken[selected] =
600
- (spawnedInThisRunByToken[selected] ?? 0) + 1;
626
+ selectedTokenName = selected;
601
627
  spawnEnv = {
602
628
  CLAUDE_CODE_OAUTH_TOKEN: selected,
603
629
  ANTHROPIC_BASE_URL: proxyBaseUrl,
@@ -609,6 +635,7 @@ export class StartPreparationUseCase {
609
635
  console.error(
610
636
  `No LLM model configured for issue ${issue.url}. Provide --defaultLlmModelName or add an llm-model: label.`,
611
637
  );
638
+ await revertToAwaitingWorkspace('no LLM model is configured');
612
639
  continue;
613
640
  }
614
641
  const awArgs: string[] = [
@@ -630,11 +657,21 @@ export class StartPreparationUseCase {
630
657
  ];
631
658
  awArgs.push('--codexHome', codexHome);
632
659
  }
633
- await this.localCommandRunner.runCommand(
660
+ const spawnResult = await this.localCommandRunner.runCommand(
634
661
  'aw',
635
662
  awArgs,
636
663
  spawnEnv ? { env: spawnEnv } : undefined,
637
664
  );
665
+ if (spawnResult.exitCode !== 0) {
666
+ await revertToAwaitingWorkspace(
667
+ `aw exited with ${spawnResult.exitCode}. stdout: ${spawnResult.stdout} stderr: ${spawnResult.stderr}`,
668
+ );
669
+ continue;
670
+ }
671
+ if (selectedTokenName !== null) {
672
+ spawnedInThisRunByToken[selectedTokenName] =
673
+ (spawnedInThisRunByToken[selectedTokenName] ?? 0) + 1;
674
+ }
638
675
  startedInThisRunCount++;
639
676
  updatedCurrentPreparationIssueCount++;
640
677
  }
@@ -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,4BAA4B,EAAE,MAAM,mDAAmD,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAShE,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE,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;IAC3B,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAWhC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,0BAA0B;IAC3C,OAAO,CAAC,QAAQ,CAAC,4BAA4B;gBAd5B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EACtD,eAAe,EAAE,IAAI,CACpC,eAAe,EACb,mBAAmB,GACnB,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,kBAAkB,GAClB,yBAAyB,GACzB,oBAAoB,CACvB,EACgB,kBAAkB,EAAE,kBAAkB,EACtC,0BAA0B,EAAE,0BAA0B,EACtD,4BAA4B,EAAE,4BAA4B;IAG7E,OAAO,CAAC,uBAAuB,CAK7B;IAEF,OAAO,CAAC,gBAAgB,CAGgC;IAExD,OAAO,CAAC,0BAA0B,CAQhC;IAEF,OAAO,CAAC,mBAAmB,CAqBzB;IAEF,OAAO,CAAC,yBAAyB,CAc/B;IAEF,OAAO,CAAC,wCAAwC,CAqB9C;IAEF,OAAO,CAAC,sBAAsB,CAS5B;IAEF,uBAAuB,GACrB,qBAAqB,MAAM,EAC3B,qBAAqB,MAAM,KAC1B,MAAM,CAUP;IAEF,OAAO,CAAC,oBAAoB,CA4E1B;IAEF,kBAAkB,GAChB,aAAa,gBAAgB,EAAE,EAC/B,gCAAgC,MAAM,EACtC,WAAW,MAAM,GAAG,IAAI,KACvB,kBAAkB,EAAE,CAqDrB;IAEF,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;QACpC,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,OAAO,EAAE,MAAM,CAAC;QAChB,mBAAmB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACrC,oBAAoB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KACvC,KAAG,OAAO,CAAC;QAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAA;KAAE,CAAC,CAoVzD;CACH"}
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,4BAA4B,EAAE,MAAM,mDAAmD,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAShE,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE,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;IAC3B,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAWhC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,0BAA0B;IAC3C,OAAO,CAAC,QAAQ,CAAC,4BAA4B;gBAd5B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EACtD,eAAe,EAAE,IAAI,CACpC,eAAe,EACb,mBAAmB,GACnB,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,kBAAkB,GAClB,yBAAyB,GACzB,oBAAoB,CACvB,EACgB,kBAAkB,EAAE,kBAAkB,EACtC,0BAA0B,EAAE,0BAA0B,EACtD,4BAA4B,EAAE,4BAA4B;IAG7E,OAAO,CAAC,uBAAuB,CAK7B;IAEF,OAAO,CAAC,gBAAgB,CAGgC;IAExD,OAAO,CAAC,0BAA0B,CAQhC;IAEF,OAAO,CAAC,mBAAmB,CAqBzB;IAEF,OAAO,CAAC,yBAAyB,CAc/B;IAEF,OAAO,CAAC,wCAAwC,CAqB9C;IAEF,OAAO,CAAC,sBAAsB,CAS5B;IAEF,uBAAuB,GACrB,qBAAqB,MAAM,EAC3B,qBAAqB,MAAM,KAC1B,MAAM,CAUP;IAEF,OAAO,CAAC,oBAAoB,CA4E1B;IAEF,kBAAkB,GAChB,aAAa,gBAAgB,EAAE,EAC/B,gCAAgC,MAAM,EACtC,WAAW,MAAM,GAAG,IAAI,KACvB,kBAAkB,EAAE,CAqDrB;IAEF,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;QACpC,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,OAAO,EAAE,MAAM,CAAC;QAChB,mBAAmB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACrC,oBAAoB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KACvC,KAAG,OAAO,CAAC;QAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAA;KAAE,CAAC,CAyXzD;CACH"}