claude-git-hooks 2.15.5 → 2.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.
@@ -6,7 +6,7 @@
6
6
  * Reuses same logic as bump-version --update-changelog
7
7
  */
8
8
 
9
- import { getCurrentVersion, detectProjectType } from '../utils/version-manager.js';
9
+ import { discoverVersionFiles } from '../utils/version-manager.js';
10
10
  import { generateChangelogEntry, updateChangelogFile } from '../utils/changelog-generator.js';
11
11
  import { getConfig } from '../config.js';
12
12
  import { showInfo, showSuccess, showWarning, showError } from '../utils/interactive-ui.js';
@@ -84,10 +84,10 @@ export async function runGenerateChangelog(args) {
84
84
  let version = options.version;
85
85
 
86
86
  if (!version) {
87
- const projectType = detectProjectType();
87
+ const discovery = discoverVersionFiles();
88
88
 
89
- if (projectType === 'none') {
90
- showError('No version files found (package.json or pom.xml)');
89
+ if (discovery.files.length === 0) {
90
+ showError('No version files found');
91
91
  console.log('');
92
92
  console.log('Specify version manually:');
93
93
  console.log(' claude-hooks generate-changelog 2.7.0');
@@ -95,8 +95,7 @@ export async function runGenerateChangelog(args) {
95
95
  process.exit(1);
96
96
  }
97
97
 
98
- const versions = getCurrentVersion(projectType);
99
- version = versions.resolved;
98
+ version = discovery.resolvedVersion;
100
99
 
101
100
  if (!version) {
102
101
  showError('Could not determine version');
@@ -343,6 +343,99 @@ const showDetailedIssues = (result) => {
343
343
  console.log('═══════════════════════════════════════════════════════════════');
344
344
  };
345
345
 
346
+ /**
347
+ * Prompt user with toggle list (checkbox-style selection)
348
+ * Why: Allow multi-select for version files or other items
349
+ *
350
+ * @param {string} message - Header message
351
+ * @param {Array<{key: string, label: string, selected: boolean}>} items - Items to select
352
+ * @returns {Promise<string[]>} - Array of selected item keys
353
+ */
354
+ export const promptToggleList = async (message, items) => {
355
+ const rl = readline.createInterface({
356
+ input: process.stdin,
357
+ output: process.stdout
358
+ });
359
+
360
+ // Clone items to track selection state
361
+ const state = items.map(item => ({
362
+ key: item.key,
363
+ label: item.label,
364
+ selected: item.selected !== undefined ? item.selected : true
365
+ }));
366
+
367
+ /**
368
+ * Display current selection state
369
+ */
370
+ const displayList = () => {
371
+ console.clear();
372
+ console.log('');
373
+ console.log(message);
374
+ console.log('');
375
+
376
+ state.forEach((item, index) => {
377
+ const checkbox = item.selected ? '✓' : '✗';
378
+ const num = index + 1;
379
+ console.log(` [${num}] ${checkbox} ${item.label}`);
380
+ });
381
+
382
+ console.log('');
383
+ console.log('Type number to toggle, Enter to confirm');
384
+ console.log('');
385
+ };
386
+
387
+ return new Promise((resolve) => {
388
+ displayList();
389
+
390
+ const askForInput = () => {
391
+ rl.question('Toggle file #: ', (answer) => {
392
+ const trimmed = answer.trim();
393
+
394
+ // Empty input = confirm and exit
395
+ if (!trimmed) {
396
+ rl.close();
397
+ const selectedKeys = state
398
+ .filter(item => item.selected)
399
+ .map(item => item.key);
400
+
401
+ logger.debug('interactive-ui - promptToggleList', 'Selection confirmed', {
402
+ selectedKeys
403
+ });
404
+
405
+ resolve(selectedKeys);
406
+ return;
407
+ }
408
+
409
+ // Parse number input
410
+ const num = parseInt(trimmed, 10);
411
+
412
+ if (!isNaN(num) && num >= 1 && num <= state.length) {
413
+ // Toggle the selected item
414
+ const index = num - 1;
415
+ state[index].selected = !state[index].selected;
416
+
417
+ logger.debug('interactive-ui - promptToggleList', 'Toggled item', {
418
+ index,
419
+ key: state[index].key,
420
+ selected: state[index].selected
421
+ });
422
+
423
+ // Redisplay and ask again
424
+ displayList();
425
+ askForInput();
426
+ } else {
427
+ // Invalid input, show message and ask again
428
+ console.log(`Invalid input. Enter a number between 1 and ${state.length}, or press Enter to confirm.`);
429
+ console.log('');
430
+ askForInput();
431
+ }
432
+ });
433
+ };
434
+
435
+ askForInput();
436
+ });
437
+ };
438
+
346
439
  /**
347
440
  * Prompt user to confirm commit with non-blocking issues
348
441
  * Why: Give developers control to abort and fix issues immediately