github-issue-tower-defence-management 2.5.1 → 2.6.1

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 (44) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +3 -1
  3. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  4. package/bin/adapter/entry-points/handlers/tokenExhaustionHandover.js +2 -1
  5. package/bin/adapter/entry-points/handlers/tokenExhaustionHandover.js.map +1 -1
  6. package/bin/adapter/repositories/BrowserGitHubProjectRepository.js +94 -0
  7. package/bin/adapter/repositories/BrowserGitHubProjectRepository.js.map +1 -0
  8. package/bin/adapter/repositories/GitHubIssueCheckpointRepository.js +37 -0
  9. package/bin/adapter/repositories/GitHubIssueCheckpointRepository.js.map +1 -0
  10. package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js +9 -1
  11. package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js.map +1 -1
  12. package/bin/domain/usecases/TokenExhaustionHandoverUseCase.js +10 -2
  13. package/bin/domain/usecases/TokenExhaustionHandoverUseCase.js.map +1 -1
  14. package/bin/domain/usecases/adapter-interfaces/IssueCheckpointRepository.js +3 -0
  15. package/bin/domain/usecases/adapter-interfaces/IssueCheckpointRepository.js.map +1 -0
  16. package/bin/domain/usecases/adapter-interfaces/StatusDefaultRepository.js +3 -0
  17. package/bin/domain/usecases/adapter-interfaces/StatusDefaultRepository.js.map +1 -0
  18. package/package.json +2 -1
  19. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +7 -0
  20. package/src/adapter/entry-points/handlers/tokenExhaustionHandover.ts +2 -0
  21. package/src/adapter/repositories/BrowserGitHubProjectRepository.test.ts +108 -0
  22. package/src/adapter/repositories/BrowserGitHubProjectRepository.ts +118 -0
  23. package/src/adapter/repositories/GitHubIssueCheckpointRepository.test.ts +51 -0
  24. package/src/adapter/repositories/GitHubIssueCheckpointRepository.ts +47 -0
  25. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.test.ts +143 -0
  26. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.ts +21 -0
  27. package/src/domain/usecases/TokenExhaustionHandoverUseCase.test.ts +87 -3
  28. package/src/domain/usecases/TokenExhaustionHandoverUseCase.ts +14 -1
  29. package/src/domain/usecases/adapter-interfaces/IssueCheckpointRepository.ts +3 -0
  30. package/src/domain/usecases/adapter-interfaces/StatusDefaultRepository.ts +5 -0
  31. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  32. package/types/adapter/entry-points/handlers/tokenExhaustionHandover.d.ts.map +1 -1
  33. package/types/adapter/repositories/BrowserGitHubProjectRepository.d.ts +10 -0
  34. package/types/adapter/repositories/BrowserGitHubProjectRepository.d.ts.map +1 -0
  35. package/types/adapter/repositories/GitHubIssueCheckpointRepository.d.ts +8 -0
  36. package/types/adapter/repositories/GitHubIssueCheckpointRepository.d.ts.map +1 -0
  37. package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts +3 -1
  38. package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts.map +1 -1
  39. package/types/domain/usecases/TokenExhaustionHandoverUseCase.d.ts +3 -1
  40. package/types/domain/usecases/TokenExhaustionHandoverUseCase.d.ts.map +1 -1
  41. package/types/domain/usecases/adapter-interfaces/IssueCheckpointRepository.d.ts +4 -0
  42. package/types/domain/usecases/adapter-interfaces/IssueCheckpointRepository.d.ts.map +1 -0
  43. package/types/domain/usecases/adapter-interfaces/StatusDefaultRepository.d.ts +5 -0
  44. package/types/domain/usecases/adapter-interfaces/StatusDefaultRepository.d.ts.map +1 -0
@@ -1,6 +1,7 @@
1
1
  import { FieldOption } from '../entities/Project';
2
2
  import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
3
3
  import { IssueRepository } from './adapter-interfaces/IssueRepository';
4
+ import { StatusDefaultRepository } from './adapter-interfaces/StatusDefaultRepository';
4
5
  import {
5
6
  AWAITING_WORKSPACE_STATUS_NAME,
6
7
  DONE_STATUS_NAME,
@@ -24,6 +25,10 @@ export class SetupTowerDefenceProjectUseCase {
24
25
  IssueRepository,
25
26
  'getAllIssues' | 'updateStatus'
26
27
  >,
28
+ private readonly statusDefaultRepository: Pick<
29
+ StatusDefaultRepository,
30
+ 'setStatusFieldDefault'
31
+ >,
27
32
  ) {}
28
33
 
29
34
  private static readonly LEGACY_STATUS_NAMES: Readonly<
@@ -117,6 +122,9 @@ export class SetupTowerDefenceProjectUseCase {
117
122
  }
118
123
  }
119
124
 
125
+ const awaitingWorkspaceOptionId: string | undefined =
126
+ awaitingWorkspaceStatus?.id;
127
+
120
128
  const hasMigratedFromName = existing.some((s) =>
121
129
  SetupTowerDefenceProjectUseCase.MIGRATED_FROM_NAMES.has(s.name),
122
130
  );
@@ -126,6 +134,12 @@ export class SetupTowerDefenceProjectUseCase {
126
134
  existing,
127
135
  )
128
136
  ) {
137
+ if (awaitingWorkspaceOptionId !== undefined) {
138
+ await this.statusDefaultRepository.setStatusFieldDefault(
139
+ project,
140
+ awaitingWorkspaceOptionId,
141
+ );
142
+ }
129
143
  return;
130
144
  }
131
145
 
@@ -172,6 +186,13 @@ export class SetupTowerDefenceProjectUseCase {
172
186
  ];
173
187
 
174
188
  await this.projectRepository.updateStatusList(project, newStatusList);
189
+
190
+ if (awaitingWorkspaceOptionId !== undefined) {
191
+ await this.statusDefaultRepository.setStatusFieldDefault(
192
+ project,
193
+ awaitingWorkspaceOptionId,
194
+ );
195
+ }
175
196
  };
176
197
 
177
198
  private static hasRequiredStatusesInCanonicalOrder = (
@@ -9,6 +9,7 @@ import {
9
9
  import { ClaudeHandoverSession } from '../entities/ClaudeHandoverSession';
10
10
  import { TokenExhaustionHandoverState } from '../entities/TokenExhaustionHandoverState';
11
11
  import { ClaudeHandoverSessionRepository } from './adapter-interfaces/ClaudeHandoverSessionRepository';
12
+ import { IssueCheckpointRepository } from './adapter-interfaces/IssueCheckpointRepository';
12
13
  import { ProcessSignalRepository } from './adapter-interfaces/ProcessSignalRepository';
13
14
  import { TmuxSessionRepository } from './adapter-interfaces/TmuxSessionRepository';
14
15
  import {
@@ -121,6 +122,9 @@ describe('TokenExhaustionHandoverUseCase', () => {
121
122
  >
122
123
  >;
123
124
  let processSignalRepository: Mocked<ProcessSignalRepository>;
125
+ let issueCheckpointRepository: Mocked<
126
+ Pick<IssueCheckpointRepository, 'postCheckpoint'>
127
+ >;
124
128
 
125
129
  const exhaustedFiveHour = (): TokenModelWeeklyLimit[] => [];
126
130
 
@@ -146,12 +150,16 @@ describe('TokenExhaustionHandoverUseCase', () => {
146
150
  terminateProcess: jest.fn(),
147
151
  killProcess: jest.fn(),
148
152
  };
153
+ issueCheckpointRepository = {
154
+ postCheckpoint: jest.fn().mockResolvedValue(undefined),
155
+ };
149
156
 
150
157
  useCase = new TokenExhaustionHandoverUseCase(
151
158
  handoverSessionRepository,
152
159
  snapshotRepository,
153
160
  tmuxSessionRepository,
154
161
  processSignalRepository,
162
+ issueCheckpointRepository,
155
163
  );
156
164
  });
157
165
 
@@ -330,7 +338,7 @@ describe('TokenExhaustionHandoverUseCase', () => {
330
338
  );
331
339
  });
332
340
 
333
- it('sends SIGTERM to an impl subagent on first detection', async () => {
341
+ it('posts a checkpoint comment to the task issue on first detection of an impl subagent with a known issue URL', async () => {
334
342
  handoverSessionRepository.listHandoverSessions.mockReturnValue([
335
343
  implSubagentSession(),
336
344
  ]);
@@ -341,10 +349,78 @@ describe('TokenExhaustionHandoverUseCase', () => {
341
349
 
342
350
  const result = await useCase.run(defaultInput());
343
351
 
352
+ expect(issueCheckpointRepository.postCheckpoint).toHaveBeenCalledWith(
353
+ ISSUE_URL,
354
+ );
355
+ expect(processSignalRepository.terminateProcess).not.toHaveBeenCalled();
356
+ expect(tmuxSessionRepository.sendKeys).not.toHaveBeenCalled();
357
+ expect(result.state.entries[`pid:${IMPL_PID}`]).toEqual({
358
+ signaledAtEpoch: nowEpochSeconds,
359
+ pid: IMPL_PID,
360
+ });
361
+ });
362
+
363
+ it('sends SIGTERM immediately when the impl subagent has no issue URL', async () => {
364
+ const noUrlSession: ClaudeHandoverSession = {
365
+ ...implSubagentSession(),
366
+ issueUrl: null,
367
+ };
368
+ handoverSessionRepository.listHandoverSessions.mockReturnValue([
369
+ noUrlSession,
370
+ ]);
371
+ snapshotRepository.listSnapshots.mockReturnValue([
372
+ snapshot(TOKEN_EXHAUSTED, { fiveHourUtilization: 0.95 }),
373
+ snapshot(TOKEN_FRESH),
374
+ ]);
375
+ const logSpy = jest.spyOn(console, 'log');
376
+
377
+ const result = await useCase.run(defaultInput());
378
+
344
379
  expect(processSignalRepository.terminateProcess).toHaveBeenCalledWith(
345
380
  IMPL_PID,
346
381
  );
347
- expect(tmuxSessionRepository.sendKeys).not.toHaveBeenCalled();
382
+ expect(issueCheckpointRepository.postCheckpoint).not.toHaveBeenCalled();
383
+ expect(logSpy).toHaveBeenCalledWith(
384
+ expect.stringContaining('no issue URL'),
385
+ );
386
+ expect(result.state.entries[`pid:${IMPL_PID}`]).toEqual({
387
+ signaledAtEpoch: nowEpochSeconds,
388
+ pid: IMPL_PID,
389
+ });
390
+ });
391
+
392
+ it('does not create a state entry when postCheckpoint throws, so the next cycle retries', async () => {
393
+ handoverSessionRepository.listHandoverSessions.mockReturnValue([
394
+ implSubagentSession(),
395
+ ]);
396
+ snapshotRepository.listSnapshots.mockReturnValue([
397
+ snapshot(TOKEN_EXHAUSTED, { fiveHourUtilization: 0.95 }),
398
+ snapshot(TOKEN_FRESH),
399
+ ]);
400
+ issueCheckpointRepository.postCheckpoint.mockRejectedValue(
401
+ new Error('network error'),
402
+ );
403
+
404
+ const result = await useCase.run(defaultInput());
405
+
406
+ expect(result.state.entries[`pid:${IMPL_PID}`]).toBeUndefined();
407
+ expect(result.newlyHandoverSentSessionNames).toEqual([]);
408
+ });
409
+
410
+ it('creates a state entry after postCheckpoint succeeds', async () => {
411
+ handoverSessionRepository.listHandoverSessions.mockReturnValue([
412
+ implSubagentSession(),
413
+ ]);
414
+ snapshotRepository.listSnapshots.mockReturnValue([
415
+ snapshot(TOKEN_EXHAUSTED, { fiveHourUtilization: 0.95 }),
416
+ snapshot(TOKEN_FRESH),
417
+ ]);
418
+
419
+ const result = await useCase.run(defaultInput());
420
+
421
+ expect(issueCheckpointRepository.postCheckpoint).toHaveBeenCalledWith(
422
+ ISSUE_URL,
423
+ );
348
424
  expect(result.state.entries[`pid:${IMPL_PID}`]).toEqual({
349
425
  signaledAtEpoch: nowEpochSeconds,
350
426
  pid: IMPL_PID,
@@ -521,7 +597,7 @@ describe('TokenExhaustionHandoverUseCase', () => {
521
597
  expect(result.killedSessionNames).toEqual([BARE_NAME]);
522
598
  });
523
599
 
524
- it('SIGKILLs an impl subagent that is still alive after the grace period', async () => {
600
+ it('SIGTERMs then SIGKILLs an impl subagent that is still alive after the grace period', async () => {
525
601
  handoverSessionRepository.listHandoverSessions.mockReturnValue([
526
602
  implSubagentSession(),
527
603
  ]);
@@ -547,6 +623,14 @@ describe('TokenExhaustionHandoverUseCase', () => {
547
623
  }),
548
624
  );
549
625
 
626
+ const terminateOrder =
627
+ processSignalRepository.terminateProcess.mock.invocationCallOrder[0];
628
+ const killOrder =
629
+ processSignalRepository.killProcess.mock.invocationCallOrder[0];
630
+ expect(terminateOrder).toBeLessThan(killOrder);
631
+ expect(processSignalRepository.terminateProcess).toHaveBeenCalledWith(
632
+ IMPL_PID,
633
+ );
550
634
  expect(processSignalRepository.killProcess).toHaveBeenCalledWith(IMPL_PID);
551
635
  expect(result.terminatedPids).toEqual([IMPL_PID]);
552
636
  });
@@ -4,6 +4,7 @@ import {
4
4
  TokenExhaustionHandoverStateEntry,
5
5
  } from '../entities/TokenExhaustionHandoverState';
6
6
  import { ClaudeHandoverSessionRepository } from './adapter-interfaces/ClaudeHandoverSessionRepository';
7
+ import { IssueCheckpointRepository } from './adapter-interfaces/IssueCheckpointRepository';
7
8
  import { ProcessSignalRepository } from './adapter-interfaces/ProcessSignalRepository';
8
9
  import { TmuxSessionRepository } from './adapter-interfaces/TmuxSessionRepository';
9
10
  import {
@@ -73,6 +74,10 @@ export class TokenExhaustionHandoverUseCase {
73
74
  | 'launchBareNameLeaderSession'
74
75
  >,
75
76
  private readonly processSignalRepository: ProcessSignalRepository,
77
+ private readonly issueCheckpointRepository: Pick<
78
+ IssueCheckpointRepository,
79
+ 'postCheckpoint'
80
+ >,
76
81
  ) {}
77
82
 
78
83
  run = async (
@@ -245,7 +250,14 @@ export class TokenExhaustionHandoverUseCase {
245
250
  input: TokenExhaustionHandoverInput,
246
251
  ): Promise<void> => {
247
252
  if (session.kind === 'implSubagent') {
248
- this.processSignalRepository.terminateProcess(session.pid);
253
+ if (session.issueUrl !== null) {
254
+ await this.issueCheckpointRepository.postCheckpoint(session.issueUrl);
255
+ } else {
256
+ console.log(
257
+ `Token exhaustion handover: sending SIGTERM to impl subagent pid=${session.pid} (no issue URL, cannot post checkpoint)`,
258
+ );
259
+ this.processSignalRepository.terminateProcess(session.pid);
260
+ }
249
261
  return;
250
262
  }
251
263
  if (session.sessionName === null) {
@@ -263,6 +275,7 @@ export class TokenExhaustionHandoverUseCase {
263
275
  entry: TokenExhaustionHandoverStateEntry,
264
276
  ): Promise<void> => {
265
277
  if (session.kind === 'implSubagent') {
278
+ this.processSignalRepository.terminateProcess(entry.pid);
266
279
  this.processSignalRepository.killProcess(entry.pid);
267
280
  return;
268
281
  }
@@ -0,0 +1,3 @@
1
+ export interface IssueCheckpointRepository {
2
+ postCheckpoint(issueUrl: string): Promise<void>;
3
+ }
@@ -0,0 +1,5 @@
1
+ import { Project } from '../../entities/Project';
2
+
3
+ export interface StatusDefaultRepository {
4
+ setStatusFieldDefault(project: Project, optionId: string): Promise<void>;
5
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAsDA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AA0D3D,qBAAa,kCAAkC;IAC7C,MAAM,GACJ,gBAAgB,MAAM,EACtB,UAAU,OAAO,EACjB,6BAA4B,MAAM,EAAE,GAAG,IAAW,KACjD,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,eAAe,EAAE,IAAI,EAAE,CAAC;KACzB,GAAG,IAAI,CAAC,CAy1BP;CACH"}
1
+ {"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAsDA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AA2D3D,qBAAa,kCAAkC;IAC7C,MAAM,GACJ,gBAAgB,MAAM,EACtB,UAAU,OAAO,EACjB,6BAA4B,MAAM,EAAE,GAAG,IAAW,KACjD,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,eAAe,EAAE,IAAI,EAAE,CAAC;KACzB,GAAG,IAAI,CAAC,CA+1BP;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"tokenExhaustionHandover.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/tokenExhaustionHandover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gEAAgE,CAAC;AAgBpG,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,6BAA6B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,6BAA6B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,QAAQ,6BAA6B,KACpC,OAAO,CAAC,IAAI,CAgDd,CAAC"}
1
+ {"version":3,"file":"tokenExhaustionHandover.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/tokenExhaustionHandover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gEAAgE,CAAC;AAiBpG,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,6BAA6B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,6BAA6B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,QAAQ,6BAA6B,KACpC,OAAO,CAAC,IAAI,CAiDd,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Project } from '../../domain/entities/Project';
2
+ import { StatusDefaultRepository } from '../../domain/usecases/adapter-interfaces/StatusDefaultRepository';
3
+ export declare class BrowserGitHubProjectRepository implements Pick<StatusDefaultRepository, 'setStatusFieldDefault'> {
4
+ private readonly username;
5
+ private readonly password;
6
+ private readonly totpSecret;
7
+ constructor(username: string | undefined, password: string | undefined, totpSecret: string | undefined);
8
+ setStatusFieldDefault: (project: Project, optionId: string) => Promise<void>;
9
+ }
10
+ //# sourceMappingURL=BrowserGitHubProjectRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserGitHubProjectRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/BrowserGitHubProjectRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kEAAkE,CAAC;AAkC3G,qBAAa,8BAA+B,YAAW,IAAI,CACzD,uBAAuB,EACvB,uBAAuB,CACxB;IAEG,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAFV,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,UAAU,EAAE,MAAM,GAAG,SAAS;IAGjD,qBAAqB,GACnB,SAAS,OAAO,EAChB,UAAU,MAAM,KACf,OAAO,CAAC,IAAI,CAAC,CAkEd;CACH"}
@@ -0,0 +1,8 @@
1
+ import { IssueCheckpointRepository } from '../../domain/usecases/adapter-interfaces/IssueCheckpointRepository';
2
+ export declare class GitHubIssueCheckpointRepository implements IssueCheckpointRepository {
3
+ private readonly ghToken;
4
+ constructor(ghToken: string);
5
+ postCheckpoint: (issueUrl: string) => Promise<void>;
6
+ private parseIssueUrl;
7
+ }
8
+ //# sourceMappingURL=GitHubIssueCheckpointRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubIssueCheckpointRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/GitHubIssueCheckpointRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,oEAAoE,CAAC;AAK/G,qBAAa,+BAAgC,YAAW,yBAAyB;IACnE,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAE5C,cAAc,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAqBtD;IAEF,OAAO,CAAC,aAAa,CAcnB;CACH"}
@@ -1,9 +1,11 @@
1
1
  import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
2
2
  import { IssueRepository } from './adapter-interfaces/IssueRepository';
3
+ import { StatusDefaultRepository } from './adapter-interfaces/StatusDefaultRepository';
3
4
  export declare class SetupTowerDefenceProjectUseCase {
4
5
  private readonly projectRepository;
5
6
  private readonly issueRepository;
6
- constructor(projectRepository: Pick<ProjectRepository, 'getByUrl' | 'updateStatusList'>, issueRepository: Pick<IssueRepository, 'getAllIssues' | 'updateStatus'>);
7
+ private readonly statusDefaultRepository;
8
+ constructor(projectRepository: Pick<ProjectRepository, 'getByUrl' | 'updateStatusList'>, issueRepository: Pick<IssueRepository, 'getAllIssues' | 'updateStatus'>, statusDefaultRepository: Pick<StatusDefaultRepository, 'setStatusFieldDefault'>);
7
9
  private static readonly LEGACY_STATUS_NAMES;
8
10
  private static readonly UNREAD_MIGRATED_STATUS_NAME;
9
11
  private static readonly MIGRATED_FROM_NAMES;
@@ -1 +1 @@
1
- {"version":3,"file":"SetupTowerDefenceProjectUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/SetupTowerDefenceProjectUseCase.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAcvE,qBAAa,+BAA+B;IAExC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAIlC,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAJf,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,UAAU,GAAG,kBAAkB,CAChC,EACgB,eAAe,EAAE,IAAI,CACpC,eAAe,EACf,cAAc,GAAG,cAAc,CAChC;IAGH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAMzC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,2BAA2B,CAAqB;IAExE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAMxC;IAEH,GAAG,GAAU,QAAQ;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,KAAG,OAAO,CAAC,IAAI,CAAC,CAgIzD;IAEF,OAAO,CAAC,MAAM,CAAC,mCAAmC,CAgBhD;CACH"}
1
+ {"version":3,"file":"SetupTowerDefenceProjectUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/SetupTowerDefenceProjectUseCase.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAcvF,qBAAa,+BAA+B;IAExC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAIlC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAIhC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;gBARvB,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,UAAU,GAAG,kBAAkB,CAChC,EACgB,eAAe,EAAE,IAAI,CACpC,eAAe,EACf,cAAc,GAAG,cAAc,CAChC,EACgB,uBAAuB,EAAE,IAAI,CAC5C,uBAAuB,EACvB,uBAAuB,CACxB;IAGH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAMzC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,2BAA2B,CAAqB;IAExE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAMxC;IAEH,GAAG,GAAU,QAAQ;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,KAAG,OAAO,CAAC,IAAI,CAAC,CAgJzD;IAEF,OAAO,CAAC,MAAM,CAAC,mCAAmC,CAgBhD;CACH"}
@@ -1,5 +1,6 @@
1
1
  import { TokenExhaustionHandoverState } from '../entities/TokenExhaustionHandoverState';
2
2
  import { ClaudeHandoverSessionRepository } from './adapter-interfaces/ClaudeHandoverSessionRepository';
3
+ import { IssueCheckpointRepository } from './adapter-interfaces/IssueCheckpointRepository';
3
4
  import { ProcessSignalRepository } from './adapter-interfaces/ProcessSignalRepository';
4
5
  import { TmuxSessionRepository } from './adapter-interfaces/TmuxSessionRepository';
5
6
  import { TokenRateLimitSnapshotRepository } from './adapter-interfaces/TokenRateLimitSnapshotRepository';
@@ -34,7 +35,8 @@ export declare class TokenExhaustionHandoverUseCase {
34
35
  private readonly snapshotRepository;
35
36
  private readonly tmuxSessionRepository;
36
37
  private readonly processSignalRepository;
37
- constructor(handoverSessionRepository: Pick<ClaudeHandoverSessionRepository, 'listHandoverSessions'>, snapshotRepository: Pick<TokenRateLimitSnapshotRepository, 'listSnapshots'>, tmuxSessionRepository: Pick<TmuxSessionRepository, 'sendKeys' | 'killSession' | 'listLiveSessionNames' | 'launchBareNameLeaderSession'>, processSignalRepository: ProcessSignalRepository);
38
+ private readonly issueCheckpointRepository;
39
+ constructor(handoverSessionRepository: Pick<ClaudeHandoverSessionRepository, 'listHandoverSessions'>, snapshotRepository: Pick<TokenRateLimitSnapshotRepository, 'listSnapshots'>, tmuxSessionRepository: Pick<TmuxSessionRepository, 'sendKeys' | 'killSession' | 'listLiveSessionNames' | 'launchBareNameLeaderSession'>, processSignalRepository: ProcessSignalRepository, issueCheckpointRepository: Pick<IssueCheckpointRepository, 'postCheckpoint'>);
38
40
  run: (input: TokenExhaustionHandoverInput) => Promise<TokenExhaustionHandoverResult>;
39
41
  private needsRelaunch;
40
42
  private relaunchBareNameLeader;
@@ -1 +1 @@
1
- {"version":3,"file":"TokenExhaustionHandoverUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/TokenExhaustionHandoverUseCase.ts"],"names":[],"mappings":"AACA,OAAO,EACL,4BAA4B,EAE7B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,+BAA+B,EAAE,MAAM,sDAAsD,CAAC;AACvG,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAGL,gCAAgC,EACjC,MAAM,uDAAuD,CAAC;AAE/D,eAAO,MAAM,yCAAyC,ubACgY,CAAC;AAEvb,eAAO,MAAM,0DAA0D,yjBACif,CAAC;AAEzjB,eAAO,MAAM,6CAA6C,MAAM,CAAC;AACjE,eAAO,MAAM,iDAAiD,MAAM,CAAC;AACrE,eAAO,MAAM,sDAAsD,OAAO,CAAC;AAC3E,eAAO,MAAM,yCAAyC,MAAM,CAAC;AAC7D,eAAO,MAAM,yCAAyC,OAAO,CAAC;AAC9D,eAAO,MAAM,iDAAiD,OAAO,CAAC;AACtE,eAAO,MAAM,iDAAiD,OAAO,CAAC;AAYtE,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,4BAA4B,CAAC;IACpC,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,6BAA6B,EAAE,MAAM,EAAE,CAAC;IACxC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,uCAAuC,EAAE,MAAM,EAAE,CAAC;IAClD,KAAK,EAAE,4BAA4B,CAAC;CACrC,CAAC;AAEF,qBAAa,8BAA8B;IAEvC,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAI1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAInC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAOtC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;gBAfvB,yBAAyB,EAAE,IAAI,CAC9C,+BAA+B,EAC/B,sBAAsB,CACvB,EACgB,kBAAkB,EAAE,IAAI,CACvC,gCAAgC,EAChC,eAAe,CAChB,EACgB,qBAAqB,EAAE,IAAI,CAC1C,qBAAqB,EACnB,UAAU,GACV,aAAa,GACb,sBAAsB,GACtB,6BAA6B,CAChC,EACgB,uBAAuB,EAAE,uBAAuB;IAGnE,GAAG,GACD,OAAO,4BAA4B,KAClC,OAAO,CAAC,6BAA6B,CAAC,CAmJvC;IAEF,OAAO,CAAC,aAAa,CACwC;IAE7D,OAAO,CAAC,sBAAsB,CAS5B;IAEF,OAAO,CAAC,YAAY,CAgBlB;IAEF,OAAO,CAAC,SAAS,CAoBf;IAEF,OAAO,CAAC,WAAW,CAGiC;IAEpD,OAAO,CAAC,WAAW,CAC2B;IAE9C,OAAO,CAAC,uBAAuB,CAe7B;IAEF,OAAO,CAAC,gBAAgB,CAgFtB;IAEF,OAAO,CAAC,SAAS,CASf;IAEF,OAAO,CAAC,OAAO,CAQb;IAEF,OAAO,CAAC,cAAc,CAcpB;CACH"}
1
+ {"version":3,"file":"TokenExhaustionHandoverUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/TokenExhaustionHandoverUseCase.ts"],"names":[],"mappings":"AACA,OAAO,EACL,4BAA4B,EAE7B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,+BAA+B,EAAE,MAAM,sDAAsD,CAAC;AACvG,OAAO,EAAE,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAC3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAGL,gCAAgC,EACjC,MAAM,uDAAuD,CAAC;AAE/D,eAAO,MAAM,yCAAyC,ubACgY,CAAC;AAEvb,eAAO,MAAM,0DAA0D,yjBACif,CAAC;AAEzjB,eAAO,MAAM,6CAA6C,MAAM,CAAC;AACjE,eAAO,MAAM,iDAAiD,MAAM,CAAC;AACrE,eAAO,MAAM,sDAAsD,OAAO,CAAC;AAC3E,eAAO,MAAM,yCAAyC,MAAM,CAAC;AAC7D,eAAO,MAAM,yCAAyC,OAAO,CAAC;AAC9D,eAAO,MAAM,iDAAiD,OAAO,CAAC;AACtE,eAAO,MAAM,iDAAiD,OAAO,CAAC;AAYtE,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,4BAA4B,CAAC;IACpC,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,6BAA6B,EAAE,MAAM,EAAE,CAAC;IACxC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,uCAAuC,EAAE,MAAM,EAAE,CAAC;IAClD,KAAK,EAAE,4BAA4B,CAAC;CACrC,CAAC;AAEF,qBAAa,8BAA8B;IAEvC,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAI1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAInC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAOtC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,yBAAyB;gBAhBzB,yBAAyB,EAAE,IAAI,CAC9C,+BAA+B,EAC/B,sBAAsB,CACvB,EACgB,kBAAkB,EAAE,IAAI,CACvC,gCAAgC,EAChC,eAAe,CAChB,EACgB,qBAAqB,EAAE,IAAI,CAC1C,qBAAqB,EACnB,UAAU,GACV,aAAa,GACb,sBAAsB,GACtB,6BAA6B,CAChC,EACgB,uBAAuB,EAAE,uBAAuB,EAChD,yBAAyB,EAAE,IAAI,CAC9C,yBAAyB,EACzB,gBAAgB,CACjB;IAGH,GAAG,GACD,OAAO,4BAA4B,KAClC,OAAO,CAAC,6BAA6B,CAAC,CAmJvC;IAEF,OAAO,CAAC,aAAa,CACwC;IAE7D,OAAO,CAAC,sBAAsB,CAS5B;IAEF,OAAO,CAAC,YAAY,CAuBlB;IAEF,OAAO,CAAC,SAAS,CAqBf;IAEF,OAAO,CAAC,WAAW,CAGiC;IAEpD,OAAO,CAAC,WAAW,CAC2B;IAE9C,OAAO,CAAC,uBAAuB,CAe7B;IAEF,OAAO,CAAC,gBAAgB,CAgFtB;IAEF,OAAO,CAAC,SAAS,CASf;IAEF,OAAO,CAAC,OAAO,CAQb;IAEF,OAAO,CAAC,cAAc,CAcpB;CACH"}
@@ -0,0 +1,4 @@
1
+ export interface IssueCheckpointRepository {
2
+ postCheckpoint(issueUrl: string): Promise<void>;
3
+ }
4
+ //# sourceMappingURL=IssueCheckpointRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IssueCheckpointRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/IssueCheckpointRepository.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD"}
@@ -0,0 +1,5 @@
1
+ import { Project } from '../../entities/Project';
2
+ export interface StatusDefaultRepository {
3
+ setStatusFieldDefault(project: Project, optionId: string): Promise<void>;
4
+ }
5
+ //# sourceMappingURL=StatusDefaultRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusDefaultRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/StatusDefaultRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,MAAM,WAAW,uBAAuB;IACtC,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E"}