npm-cli-gh-issue-preparator 1.15.1 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.16.0](https://github.com/HiromiShikata/npm-cli-gh-issue-preparator/compare/v1.15.1...v1.16.0) (2026-02-24)
2
+
3
+
4
+ ### Features
5
+
6
+ * **core:** add utilizationPercentageThreshold CLI option to startDaemon ([746aaba](https://github.com/HiromiShikata/npm-cli-gh-issue-preparator/commit/746aaba045108e2e8d10846562958ebe5923e2dd))
7
+
1
8
  ## [1.15.1](https://github.com/HiromiShikata/npm-cli-gh-issue-preparator/compare/v1.15.0...v1.15.1) (2026-02-24)
2
9
 
3
10
 
@@ -31,6 +31,7 @@ program
31
31
  .requiredOption('--configFilePath <path>', 'Path to config file for tower defence management')
32
32
  .option('--logFilePath <path>', 'Path to log file')
33
33
  .option('--maximumPreparingIssuesCount <count>', 'Maximum number of issues in preparation status (default: 6)')
34
+ .option('--utilizationPercentageThreshold <percentage>', 'Claude usage percentage threshold for skipping preparation (default: 90)')
34
35
  .action(async (options) => {
35
36
  const token = process.env.GH_TOKEN;
36
37
  if (!token) {
@@ -58,6 +59,17 @@ program
58
59
  }
59
60
  maximumPreparingIssuesCount = parsedCount;
60
61
  }
62
+ let utilizationPercentageThreshold = 90;
63
+ if (options.utilizationPercentageThreshold !== undefined) {
64
+ const parsedThreshold = Number(options.utilizationPercentageThreshold);
65
+ if (!Number.isFinite(parsedThreshold) ||
66
+ parsedThreshold < 0 ||
67
+ parsedThreshold > 100) {
68
+ console.error('Invalid value for --utilizationPercentageThreshold. It must be a number between 0 and 100.');
69
+ process.exit(1);
70
+ }
71
+ utilizationPercentageThreshold = parsedThreshold;
72
+ }
61
73
  await useCase.run({
62
74
  projectUrl: options.projectUrl,
63
75
  awaitingWorkspaceStatus: options.awaitingWorkspaceStatus,
@@ -65,6 +77,7 @@ program
65
77
  defaultAgentName: options.defaultAgentName,
66
78
  logFilePath: options.logFilePath,
67
79
  maximumPreparingIssuesCount,
80
+ utilizationPercentageThreshold,
68
81
  });
69
82
  });
70
83
  program
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";;;;;;;AACA,oDAA4B;AAC5B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,yCAAoC;AACpC,8FAA2F;AAC3F,0HAAuH;AACvH,gGAA6F;AAC7F,sFAAmF;AACnF,oGAAiG;AACjG,kGAA+F;AAC/F,sFAAmF;AACnF,0FAAuF;AAuBvF,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAwLrB,0BAAO;AAvLhB,OAAO;KACJ,IAAI,CAAC,6BAA6B,CAAC;KACnC,WAAW,CAAC,mCAAmC,CAAC,CAAC;AAEpD,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,uCAAuC,CAAC;KACpD,cAAc,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;KAC1D,cAAc,CACb,oCAAoC,EACpC,sCAAsC,CACvC;KACA,cAAc,CACb,8BAA8B,EAC9B,kCAAkC,CACnC;KACA,cAAc,CAAC,2BAA2B,EAAE,oBAAoB,CAAC;KACjE,cAAc,CACb,yBAAyB,EACzB,kDAAkD,CACnD;KACA,MAAM,CAAC,sBAAsB,EAAE,kBAAkB,CAAC;KAClD,MAAM,CACL,uCAAuC,EACvC,6DAA6D,CAC9D;KACA,MAAM,CACL,+CAA+C,EAC/C,0EAA0E,CAC3E;KACA,MAAM,CAAC,KAAK,EAAE,OAA2B,EAAE,EAAE;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,6DAA6B,CACzD,OAAO,CAAC,cAAc,EACtB,KAAK,CACN,CAAC;IACF,MAAM,2BAA2B,GAAG,IAAI,yDAA2B,CACjE,OAAO,CAAC,cAAc,EACtB,KAAK,CACN,CAAC;IACF,MAAM,sBAAsB,GAAG,IAAI,+CAAsB,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,gBAAgB,GAAG,IAAI,mDAAwB,EAAE,CAAC;IACxD,MAAM,kBAAkB,GAAG,IAAI,+CAAsB,EAAE,CAAC;IAExD,MAAM,OAAO,GAAG,IAAI,iDAAuB,CACzC,iBAAiB,EACjB;QACE,YAAY,EAAE,2BAA2B,CAAC,YAAY,CAAC,IAAI,CACzD,2BAA2B,CAC5B;QACD,iBAAiB,EAAE,2BAA2B,CAAC,iBAAiB,CAAC,IAAI,CACnE,2BAA2B,CAC5B;QACD,MAAM,EAAE,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC;KACnE,EACD,gBAAgB,EAChB,kBAAkB,CACnB,CAAC;IAEF,IAAI,2BAA2B,GAAkB,IAAI,CAAC;IACtD,IAAI,OAAO,CAAC,2BAA2B,KAAK,SAAS,EAAE,CAAC;QACtD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QAChE,IACE,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC7B,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC;YAC9B,WAAW,IAAI,CAAC,EAChB,CAAC;YACD,OAAO,CAAC,KAAK,CACX,iFAAiF,CAClF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,2BAA2B,GAAG,WAAW,CAAC;IAC5C,CAAC;IAED,IAAI,8BAA8B,GAAG,EAAE,CAAC;IACxC,IAAI,OAAO,CAAC,8BAA8B,KAAK,SAAS,EAAE,CAAC;QACzD,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;QACvE,IACE,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;YACjC,eAAe,GAAG,CAAC;YACnB,eAAe,GAAG,GAAG,EACrB,CAAC;YACD,OAAO,CAAC,KAAK,CACX,4FAA4F,CAC7F,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,8BAA8B,GAAG,eAAe,CAAC;IACnD,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,uBAAuB,EAAE,OAAO,CAAC,uBAAuB;QACxD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,2BAA2B;QAC3B,8BAA8B;KAC/B,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,gCAAgC,CAAC;KACzC,WAAW,CAAC,2CAA2C,CAAC;KACxD,cAAc,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;KAC1D,cAAc,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;KACtD,cAAc,CACb,8BAA8B,EAC9B,kCAAkC,CACnC;KACA,cAAc,CACb,oCAAoC,EACpC,sCAAsC,CACvC;KACA,cAAc,CACb,uCAAuC,EACvC,0CAA0C,CAC3C;KACA,cAAc,CACb,yBAAyB,EACzB,kDAAkD,CACnD;KACA,MAAM,CACL,kCAAkC,EAClC,yEAAyE,CAC1E;KACA,MAAM,CAAC,KAAK,EAAE,OAA8B,EAAE,EAAE;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,6DAA6B,CACzD,OAAO,CAAC,cAAc,EACtB,KAAK,CACN,CAAC;IACF,MAAM,sBAAsB,GAAG,IAAI,+CAAsB,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,sBAAsB,GAAG,IAAI,2DAA4B,CAAC,KAAK,CAAC,CAAC;IAEvE,MAAM,OAAO,GAAG,IAAI,6EAAqC,CACvD,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,CACvB,CAAC;IAEF,IAAI,sBAAsB,GAAG,CAAC,CAAC;IAC/B,IAAI,OAAO,CAAC,sBAAsB,KAAK,SAAS,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACtD,IACE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YACxB,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;YACzB,MAAM,IAAI,CAAC,EACX,CAAC;YACD,OAAO,CAAC,KAAK,CACX,4EAA4E,CAC7E,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,sBAAsB,GAAG,MAAM,CAAC;IAClC,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,uBAAuB,EAAE,OAAO,CAAC,uBAAuB;QACxD,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;QAC9D,sBAAsB;KACvB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,0BAA0B;AAC1B,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5C,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC"}
@@ -10,7 +10,7 @@ class StartPreparationUseCase {
10
10
  this.run = async (params) => {
11
11
  try {
12
12
  const claudeUsages = await this.claudeRepository.getUsage();
13
- if (claudeUsages.some((usage) => usage.utilizationPercentage > 90)) {
13
+ if (claudeUsages.some((usage) => usage.utilizationPercentage > params.utilizationPercentageThreshold)) {
14
14
  console.warn('Claude usage limit exceeded. Skipping starting preparation.');
15
15
  return;
16
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"StartPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"StartPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "npm-cli-gh-issue-preparator",
3
- "version": "1.15.1",
3
+ "version": "1.16.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "scripts": {
@@ -78,6 +78,7 @@ describe('CLI', () => {
78
78
  defaultAgentName: 'agent1',
79
79
  logFilePath: undefined,
80
80
  maximumPreparingIssuesCount: null,
81
+ utilizationPercentageThreshold: 90,
81
82
  });
82
83
  });
83
84
 
@@ -118,6 +119,7 @@ describe('CLI', () => {
118
119
  defaultAgentName: 'agent1',
119
120
  logFilePath: '/path/to/log.txt',
120
121
  maximumPreparingIssuesCount: null,
122
+ utilizationPercentageThreshold: 90,
121
123
  });
122
124
  });
123
125
 
@@ -158,6 +160,7 @@ describe('CLI', () => {
158
160
  defaultAgentName: 'agent1',
159
161
  logFilePath: undefined,
160
162
  maximumPreparingIssuesCount: 10,
163
+ utilizationPercentageThreshold: 90,
161
164
  });
162
165
  });
163
166
 
@@ -309,6 +312,158 @@ describe('CLI', () => {
309
312
  processExitSpy.mockRestore();
310
313
  });
311
314
 
315
+ it('should pass custom utilizationPercentageThreshold to StartPreparationUseCase when provided', async () => {
316
+ const mockRun = jest.fn().mockResolvedValue(undefined);
317
+ const MockedStartPreparationUseCase = jest.mocked(StartPreparationUseCase);
318
+
319
+ MockedStartPreparationUseCase.mockImplementation(function (
320
+ this: StartPreparationUseCase,
321
+ ) {
322
+ this.run = mockRun;
323
+ return this;
324
+ });
325
+
326
+ await program.parseAsync([
327
+ 'node',
328
+ 'test',
329
+ 'startDaemon',
330
+ '--projectUrl',
331
+ 'https://github.com/test/project',
332
+ '--awaitingWorkspaceStatus',
333
+ 'Awaiting',
334
+ '--preparationStatus',
335
+ 'Preparing',
336
+ '--defaultAgentName',
337
+ 'agent1',
338
+ '--configFilePath',
339
+ '/path/to/config.yml',
340
+ '--utilizationPercentageThreshold',
341
+ '75',
342
+ ]);
343
+
344
+ expect(mockRun).toHaveBeenCalledTimes(1);
345
+ expect(mockRun).toHaveBeenCalledWith({
346
+ projectUrl: 'https://github.com/test/project',
347
+ awaitingWorkspaceStatus: 'Awaiting',
348
+ preparationStatus: 'Preparing',
349
+ defaultAgentName: 'agent1',
350
+ logFilePath: undefined,
351
+ maximumPreparingIssuesCount: null,
352
+ utilizationPercentageThreshold: 75,
353
+ });
354
+ });
355
+
356
+ it('should exit with error for non-numeric utilizationPercentageThreshold', async () => {
357
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
358
+ const processExitSpy = jest
359
+ .spyOn(process, 'exit')
360
+ .mockImplementation(() => {
361
+ throw new Error('process.exit called');
362
+ });
363
+
364
+ await expect(
365
+ program.parseAsync([
366
+ 'node',
367
+ 'test',
368
+ 'startDaemon',
369
+ '--projectUrl',
370
+ 'https://github.com/test/project',
371
+ '--awaitingWorkspaceStatus',
372
+ 'Awaiting',
373
+ '--preparationStatus',
374
+ 'Preparing',
375
+ '--defaultAgentName',
376
+ 'agent1',
377
+ '--configFilePath',
378
+ '/path/to/config.yml',
379
+ '--utilizationPercentageThreshold',
380
+ 'abc',
381
+ ]),
382
+ ).rejects.toThrow('process.exit called');
383
+
384
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
385
+ 'Invalid value for --utilizationPercentageThreshold. It must be a number between 0 and 100.',
386
+ );
387
+ expect(processExitSpy).toHaveBeenCalledWith(1);
388
+
389
+ consoleErrorSpy.mockRestore();
390
+ processExitSpy.mockRestore();
391
+ });
392
+
393
+ it('should exit with error for negative utilizationPercentageThreshold', async () => {
394
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
395
+ const processExitSpy = jest
396
+ .spyOn(process, 'exit')
397
+ .mockImplementation(() => {
398
+ throw new Error('process.exit called');
399
+ });
400
+
401
+ await expect(
402
+ program.parseAsync([
403
+ 'node',
404
+ 'test',
405
+ 'startDaemon',
406
+ '--projectUrl',
407
+ 'https://github.com/test/project',
408
+ '--awaitingWorkspaceStatus',
409
+ 'Awaiting',
410
+ '--preparationStatus',
411
+ 'Preparing',
412
+ '--defaultAgentName',
413
+ 'agent1',
414
+ '--configFilePath',
415
+ '/path/to/config.yml',
416
+ '--utilizationPercentageThreshold',
417
+ '-5',
418
+ ]),
419
+ ).rejects.toThrow('process.exit called');
420
+
421
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
422
+ 'Invalid value for --utilizationPercentageThreshold. It must be a number between 0 and 100.',
423
+ );
424
+ expect(processExitSpy).toHaveBeenCalledWith(1);
425
+
426
+ consoleErrorSpy.mockRestore();
427
+ processExitSpy.mockRestore();
428
+ });
429
+
430
+ it('should exit with error for utilizationPercentageThreshold over 100', async () => {
431
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
432
+ const processExitSpy = jest
433
+ .spyOn(process, 'exit')
434
+ .mockImplementation(() => {
435
+ throw new Error('process.exit called');
436
+ });
437
+
438
+ await expect(
439
+ program.parseAsync([
440
+ 'node',
441
+ 'test',
442
+ 'startDaemon',
443
+ '--projectUrl',
444
+ 'https://github.com/test/project',
445
+ '--awaitingWorkspaceStatus',
446
+ 'Awaiting',
447
+ '--preparationStatus',
448
+ 'Preparing',
449
+ '--defaultAgentName',
450
+ 'agent1',
451
+ '--configFilePath',
452
+ '/path/to/config.yml',
453
+ '--utilizationPercentageThreshold',
454
+ '101',
455
+ ]),
456
+ ).rejects.toThrow('process.exit called');
457
+
458
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
459
+ 'Invalid value for --utilizationPercentageThreshold. It must be a number between 0 and 100.',
460
+ );
461
+ expect(processExitSpy).toHaveBeenCalledWith(1);
462
+
463
+ consoleErrorSpy.mockRestore();
464
+ processExitSpy.mockRestore();
465
+ });
466
+
312
467
  it('should pass correct parameters to NotifyFinishedIssuePreparationUseCase', async () => {
313
468
  const mockRun = jest.fn().mockResolvedValue(undefined);
314
469
  const MockedNotifyFinishedUseCase = jest.mocked(
@@ -19,6 +19,7 @@ type StartDaemonOptions = {
19
19
  defaultAgentName: string;
20
20
  logFilePath?: string;
21
21
  maximumPreparingIssuesCount?: string;
22
+ utilizationPercentageThreshold?: string;
22
23
  configFilePath: string;
23
24
  };
24
25
 
@@ -59,6 +60,10 @@ program
59
60
  '--maximumPreparingIssuesCount <count>',
60
61
  'Maximum number of issues in preparation status (default: 6)',
61
62
  )
63
+ .option(
64
+ '--utilizationPercentageThreshold <percentage>',
65
+ 'Claude usage percentage threshold for skipping preparation (default: 90)',
66
+ )
62
67
  .action(async (options: StartDaemonOptions) => {
63
68
  const token = process.env.GH_TOKEN;
64
69
  if (!token) {
@@ -109,6 +114,22 @@ program
109
114
  maximumPreparingIssuesCount = parsedCount;
110
115
  }
111
116
 
117
+ let utilizationPercentageThreshold = 90;
118
+ if (options.utilizationPercentageThreshold !== undefined) {
119
+ const parsedThreshold = Number(options.utilizationPercentageThreshold);
120
+ if (
121
+ !Number.isFinite(parsedThreshold) ||
122
+ parsedThreshold < 0 ||
123
+ parsedThreshold > 100
124
+ ) {
125
+ console.error(
126
+ 'Invalid value for --utilizationPercentageThreshold. It must be a number between 0 and 100.',
127
+ );
128
+ process.exit(1);
129
+ }
130
+ utilizationPercentageThreshold = parsedThreshold;
131
+ }
132
+
112
133
  await useCase.run({
113
134
  projectUrl: options.projectUrl,
114
135
  awaitingWorkspaceStatus: options.awaitingWorkspaceStatus,
@@ -116,6 +137,7 @@ program
116
137
  defaultAgentName: options.defaultAgentName,
117
138
  logFilePath: options.logFilePath,
118
139
  maximumPreparingIssuesCount,
140
+ utilizationPercentageThreshold,
119
141
  });
120
142
  });
121
143
 
@@ -130,6 +130,7 @@ describe('StartPreparationUseCase', () => {
130
130
  preparationStatus: 'Preparation',
131
131
  defaultAgentName: 'agent1',
132
132
  maximumPreparingIssuesCount: null,
133
+ utilizationPercentageThreshold: 90,
133
134
  });
134
135
  expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
135
136
  expect(mockIssueRepository.update.mock.calls[0][0]).toMatchObject({
@@ -173,6 +174,7 @@ describe('StartPreparationUseCase', () => {
173
174
  preparationStatus: 'Preparation',
174
175
  defaultAgentName: 'agent1',
175
176
  maximumPreparingIssuesCount: null,
177
+ utilizationPercentageThreshold: 90,
176
178
  });
177
179
  // Both awaiting issues should be updated (forward iteration: url1 first, then url2)
178
180
  expect(mockIssueRepository.update.mock.calls).toHaveLength(2);
@@ -225,6 +227,7 @@ describe('StartPreparationUseCase', () => {
225
227
  preparationStatus: 'Preparation',
226
228
  defaultAgentName: 'agent1',
227
229
  maximumPreparingIssuesCount: null,
230
+ utilizationPercentageThreshold: 90,
228
231
  });
229
232
  // Loop doesn't run because we're already at max (6 >= 6)
230
233
  expect(mockIssueRepository.update.mock.calls).toHaveLength(0);
@@ -256,6 +259,7 @@ describe('StartPreparationUseCase', () => {
256
259
  defaultAgentName: 'agent1',
257
260
  logFilePath: '/path/to/log.txt',
258
261
  maximumPreparingIssuesCount: null,
262
+ utilizationPercentageThreshold: 90,
259
263
  });
260
264
  expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
261
265
  expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe(
@@ -287,6 +291,7 @@ describe('StartPreparationUseCase', () => {
287
291
  preparationStatus: 'Preparation',
288
292
  defaultAgentName: 'agent1',
289
293
  maximumPreparingIssuesCount: null,
294
+ utilizationPercentageThreshold: 90,
290
295
  });
291
296
  expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
292
297
  expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe(
@@ -319,6 +324,7 @@ describe('StartPreparationUseCase', () => {
319
324
  preparationStatus: 'Preparation',
320
325
  defaultAgentName: 'agent1',
321
326
  maximumPreparingIssuesCount: null,
327
+ utilizationPercentageThreshold: 90,
322
328
  });
323
329
  // No issues are in 'Awaiting Workspace' status, so no updates should happen
324
330
  expect(mockIssueRepository.update.mock.calls).toHaveLength(0);
@@ -349,6 +355,7 @@ describe('StartPreparationUseCase', () => {
349
355
  preparationStatus: 'Preparation',
350
356
  defaultAgentName: 'agent1',
351
357
  maximumPreparingIssuesCount: 3,
358
+ utilizationPercentageThreshold: 90,
352
359
  });
353
360
  expect(mockIssueRepository.update.mock.calls).toHaveLength(3);
354
361
  expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(3);
@@ -378,6 +385,7 @@ describe('StartPreparationUseCase', () => {
378
385
  preparationStatus: 'Preparation',
379
386
  defaultAgentName: 'agent1',
380
387
  maximumPreparingIssuesCount: null,
388
+ utilizationPercentageThreshold: 90,
381
389
  });
382
390
  expect(mockIssueRepository.update.mock.calls).toHaveLength(6);
383
391
  expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(6);
@@ -443,6 +451,7 @@ describe('StartPreparationUseCase', () => {
443
451
  preparationStatus: 'Preparation',
444
452
  defaultAgentName: 'agent1',
445
453
  maximumPreparingIssuesCount: null,
454
+ utilizationPercentageThreshold: 90,
446
455
  });
447
456
 
448
457
  // The blocked issue should be skipped (continue statement), but the blocker issue itself should be processed
@@ -494,6 +503,7 @@ describe('StartPreparationUseCase', () => {
494
503
  preparationStatus: 'Preparation',
495
504
  defaultAgentName: 'agent1',
496
505
  maximumPreparingIssuesCount: null,
506
+ utilizationPercentageThreshold: 90,
497
507
  });
498
508
 
499
509
  // The blocker issue should be processed since it's the blocker itself
@@ -562,6 +572,7 @@ describe('StartPreparationUseCase', () => {
562
572
  preparationStatus: 'Preparation',
563
573
  defaultAgentName: 'agent1',
564
574
  maximumPreparingIssuesCount: null,
575
+ utilizationPercentageThreshold: 90,
565
576
  });
566
577
 
567
578
  // The awaiting issue should be processed since there are no blockers (undefined returned empty array [])
@@ -597,6 +608,7 @@ describe('StartPreparationUseCase', () => {
597
608
  preparationStatus: 'Preparation',
598
609
  defaultAgentName: 'agent1',
599
610
  maximumPreparingIssuesCount: null,
611
+ utilizationPercentageThreshold: 90,
600
612
  });
601
613
 
602
614
  expect(mockIssueRepository.update.mock.calls).toHaveLength(0);
@@ -635,6 +647,7 @@ describe('StartPreparationUseCase', () => {
635
647
  preparationStatus: 'Preparation',
636
648
  defaultAgentName: 'agent1',
637
649
  maximumPreparingIssuesCount: null,
650
+ utilizationPercentageThreshold: 90,
638
651
  });
639
652
 
640
653
  expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
@@ -653,6 +666,7 @@ describe('StartPreparationUseCase', () => {
653
666
  preparationStatus: 'Preparation',
654
667
  defaultAgentName: 'agent1',
655
668
  maximumPreparingIssuesCount: null,
669
+ utilizationPercentageThreshold: 90,
656
670
  });
657
671
 
658
672
  expect(mockProjectRepository.getByUrl).not.toHaveBeenCalled();
@@ -690,6 +704,77 @@ describe('StartPreparationUseCase', () => {
690
704
  preparationStatus: 'Preparation',
691
705
  defaultAgentName: 'agent1',
692
706
  maximumPreparingIssuesCount: null,
707
+ utilizationPercentageThreshold: 90,
708
+ });
709
+
710
+ expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
711
+ expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
712
+ });
713
+
714
+ it('should skip preparation when Claude usage exceeds custom threshold', async () => {
715
+ mockClaudeRepository.getUsage.mockResolvedValue([
716
+ { hour: 5, utilizationPercentage: 75, resetsAt: new Date() },
717
+ ]);
718
+
719
+ const awaitingIssues: Issue[] = [
720
+ createMockIssue({
721
+ url: 'url1',
722
+ title: 'Issue 1',
723
+ labels: [],
724
+ status: 'Awaiting Workspace',
725
+ }),
726
+ ];
727
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
728
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
729
+ createMockStoryObjectMap(awaitingIssues),
730
+ );
731
+ mockIssueRepository.getAllOpened.mockResolvedValueOnce(awaitingIssues);
732
+
733
+ await useCase.run({
734
+ projectUrl: 'https://github.com/user/repo',
735
+ awaitingWorkspaceStatus: 'Awaiting Workspace',
736
+ preparationStatus: 'Preparation',
737
+ defaultAgentName: 'agent1',
738
+ maximumPreparingIssuesCount: null,
739
+ utilizationPercentageThreshold: 70,
740
+ });
741
+
742
+ expect(mockIssueRepository.update.mock.calls).toHaveLength(0);
743
+ expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
744
+ expect(mockProjectRepository.getByUrl).not.toHaveBeenCalled();
745
+ });
746
+
747
+ it('should proceed with preparation when Claude usage is under custom threshold', async () => {
748
+ mockClaudeRepository.getUsage.mockResolvedValue([
749
+ { hour: 5, utilizationPercentage: 75, resetsAt: new Date() },
750
+ ]);
751
+
752
+ const awaitingIssues: Issue[] = [
753
+ createMockIssue({
754
+ url: 'url1',
755
+ title: 'Issue 1',
756
+ labels: ['category:impl'],
757
+ status: 'Awaiting Workspace',
758
+ }),
759
+ ];
760
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
761
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
762
+ createMockStoryObjectMap(awaitingIssues),
763
+ );
764
+ mockIssueRepository.getAllOpened.mockResolvedValueOnce(awaitingIssues);
765
+ mockLocalCommandRunner.runCommand.mockResolvedValue({
766
+ stdout: '',
767
+ stderr: '',
768
+ exitCode: 0,
769
+ });
770
+
771
+ await useCase.run({
772
+ projectUrl: 'https://github.com/user/repo',
773
+ awaitingWorkspaceStatus: 'Awaiting Workspace',
774
+ preparationStatus: 'Preparation',
775
+ defaultAgentName: 'agent1',
776
+ maximumPreparingIssuesCount: null,
777
+ utilizationPercentageThreshold: 80,
693
778
  });
694
779
 
695
780
  expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
@@ -732,6 +817,7 @@ describe('StartPreparationUseCase', () => {
732
817
  preparationStatus: 'Preparation',
733
818
  defaultAgentName: 'agent1',
734
819
  maximumPreparingIssuesCount: null,
820
+ utilizationPercentageThreshold: 90,
735
821
  });
736
822
 
737
823
  expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
@@ -785,6 +871,7 @@ describe('StartPreparationUseCase', () => {
785
871
  preparationStatus: 'Preparation',
786
872
  defaultAgentName: 'agent1',
787
873
  maximumPreparingIssuesCount: null,
874
+ utilizationPercentageThreshold: 90,
788
875
  });
789
876
 
790
877
  expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
@@ -841,6 +928,7 @@ describe('StartPreparationUseCase', () => {
841
928
  preparationStatus: 'Preparation',
842
929
  defaultAgentName: 'agent1',
843
930
  maximumPreparingIssuesCount: null,
931
+ utilizationPercentageThreshold: 90,
844
932
  });
845
933
 
846
934
  expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
@@ -886,6 +974,7 @@ describe('StartPreparationUseCase', () => {
886
974
  preparationStatus: 'Preparation',
887
975
  defaultAgentName: 'agent1',
888
976
  maximumPreparingIssuesCount: null,
977
+ utilizationPercentageThreshold: 90,
889
978
  });
890
979
 
891
980
  expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
@@ -931,6 +1020,7 @@ describe('StartPreparationUseCase', () => {
931
1020
  preparationStatus: 'Preparation',
932
1021
  defaultAgentName: 'agent1',
933
1022
  maximumPreparingIssuesCount: null,
1023
+ utilizationPercentageThreshold: 90,
934
1024
  });
935
1025
 
936
1026
  expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
@@ -976,6 +1066,7 @@ describe('StartPreparationUseCase', () => {
976
1066
  preparationStatus: 'Preparation',
977
1067
  defaultAgentName: 'agent1',
978
1068
  maximumPreparingIssuesCount: null,
1069
+ utilizationPercentageThreshold: 90,
979
1070
  });
980
1071
 
981
1072
  expect(mockIssueRepository.update.mock.calls).toHaveLength(1);
@@ -23,10 +23,16 @@ export class StartPreparationUseCase {
23
23
  defaultAgentName: string;
24
24
  logFilePath?: string;
25
25
  maximumPreparingIssuesCount: number | null;
26
+ utilizationPercentageThreshold: number;
26
27
  }): Promise<void> => {
27
28
  try {
28
29
  const claudeUsages = await this.claudeRepository.getUsage();
29
- if (claudeUsages.some((usage) => usage.utilizationPercentage > 90)) {
30
+ if (
31
+ claudeUsages.some(
32
+ (usage) =>
33
+ usage.utilizationPercentage > params.utilizationPercentageThreshold,
34
+ )
35
+ ) {
30
36
  console.warn(
31
37
  'Claude usage limit exceeded. Skipping starting preparation.',
32
38
  );
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAmK9B,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAwL9B,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -16,6 +16,7 @@ export declare class StartPreparationUseCase {
16
16
  defaultAgentName: string;
17
17
  logFilePath?: string;
18
18
  maximumPreparingIssuesCount: number | null;
19
+ utilizationPercentageThreshold: number;
19
20
  }) => Promise<void>;
20
21
  createWorkflowBockerIsues: (storyObjectMap: StoryObjectMap) => {
21
22
  orgRepo: string;
@@ -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;AAE7E,OAAO,EAAe,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAEzE,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAIhC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;gBANlB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EACtD,eAAe,EAAE,IAAI,CACpC,eAAe,EACf,cAAc,GAAG,mBAAmB,GAAG,QAAQ,CAChD,EACgB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,EACpD,kBAAkB,EAAE,kBAAkB;IAGzD,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,uBAAuB,EAAE,MAAM,CAAC;QAChC,iBAAiB,EAAE,MAAM,CAAC;QAC1B,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,2BAA2B,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5C,KAAG,OAAO,CAAC,IAAI,CAAC,CAyFf;IACF,yBAAyB,GACvB,gBAAgB,cAAc,KAC7B;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,EAAE,MAAM,EAAE,CAAC;KAC5B,EAAE,CAyBD;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;AAE7E,OAAO,EAAe,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAEzE,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAIhC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;gBANlB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EACtD,eAAe,EAAE,IAAI,CACpC,eAAe,EACf,cAAc,GAAG,mBAAmB,GAAG,QAAQ,CAChD,EACgB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,EACpD,kBAAkB,EAAE,kBAAkB;IAGzD,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,uBAAuB,EAAE,MAAM,CAAC;QAChC,iBAAiB,EAAE,MAAM,CAAC;QAC1B,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,2BAA2B,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3C,8BAA8B,EAAE,MAAM,CAAC;KACxC,KAAG,OAAO,CAAC,IAAI,CAAC,CA8Ff;IACF,yBAAyB,GACvB,gBAAgB,cAAc,KAC7B;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,EAAE,MAAM,EAAE,CAAC;KAC5B,EAAE,CAyBD;CACH"}