inup 1.4.5 → 1.4.7

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.
@@ -47,24 +47,34 @@ class InputHandler {
47
47
  }
48
48
  return;
49
49
  }
50
- // Check for '/' character to enter filter mode (only in normal mode, not in modal or already in filter)
51
- if (str === '/' && !uiState.showInfoModal && !uiState.filterMode) {
52
- this.onAction({ type: 'enter_filter_mode' });
50
+ // Check for '/' character to handle filter mode (only when not in modal)
51
+ if (str === '/' && !uiState.showInfoModal) {
52
+ if (uiState.filterMode) {
53
+ // Apply search (exit filter mode but keep the filter)
54
+ this.onAction({ type: 'exit_filter_mode' });
55
+ }
56
+ else {
57
+ // Enter filter mode - preserve query if one exists (to edit it)
58
+ this.onAction({ type: 'enter_filter_mode', preserveQuery: !!uiState.filterQuery });
59
+ }
53
60
  return;
54
61
  }
55
62
  // Handle filter mode input
56
63
  if (uiState.filterMode) {
64
+ // Check for escape key (either via key.name or raw escape character)
65
+ if ((key && key.name === 'escape') || str === '\x1b') {
66
+ // Escape clears the filter and exits filter mode
67
+ this.onAction({ type: 'exit_filter_mode', clearQuery: true });
68
+ return;
69
+ }
57
70
  if (key) {
58
71
  switch (key.name) {
59
- case 'escape':
60
- this.onAction({ type: 'exit_filter_mode' });
61
- return;
62
72
  case 'backspace':
63
73
  case 'delete':
64
74
  this.onAction({ type: 'filter_backspace' });
65
75
  return;
66
76
  case 'return':
67
- // Exit filter mode but keep the filter applied
77
+ // Apply search (exit filter mode but keep the filter)
68
78
  this.onAction({ type: 'exit_filter_mode' });
69
79
  return;
70
80
  case 'up':
@@ -116,10 +126,7 @@ class InputHandler {
116
126
  // Check if any packages are selected
117
127
  const selectedCount = states.filter((s) => s.selectedOption !== 'none').length;
118
128
  if (selectedCount === 0) {
119
- // Show warning and stay in selection mode
120
- console.log('\n' +
121
- '\x1b[33m⚠️ No packages selected. Press ↑/↓ to navigate and ←/→ to select versions, or ESC to exit.\x1b[39m');
122
- // Re-render will happen automatically
129
+ // Do nothing if no packages selected
123
130
  return;
124
131
  }
125
132
  this.cleanup();
@@ -164,13 +171,15 @@ class InputHandler {
164
171
  this.onAction({ type: 'toggle_theme_modal' });
165
172
  break;
166
173
  case 'escape':
167
- // Check if modal is open - if so, close it; otherwise cancel
174
+ // Close modal if open
168
175
  if (uiState.showInfoModal) {
169
176
  this.onAction({ type: 'toggle_info_modal' });
170
177
  }
171
- else {
172
- this.onAction({ type: 'cancel' });
178
+ else if (uiState.filterQuery) {
179
+ // Clear filter if one is applied
180
+ this.onAction({ type: 'exit_filter_mode', clearQuery: true });
173
181
  }
182
+ // Otherwise do nothing - Escape no longer exits the CLI
174
183
  break;
175
184
  }
176
185
  }
@@ -178,11 +187,7 @@ class InputHandler {
178
187
  this.onAction({ type: 'resize', height });
179
188
  }
180
189
  cleanup() {
181
- utils_1.CursorUtils.show();
182
- if (process.stdin.setRawMode) {
183
- process.stdin.setRawMode(false);
184
- }
185
- process.stdin.pause();
190
+ utils_1.CursorUtils.cleanup();
186
191
  }
187
192
  }
188
193
  exports.InputHandler = InputHandler;
@@ -219,11 +224,7 @@ class ConfirmationInputHandler {
219
224
  }
220
225
  }
221
226
  cleanup() {
222
- utils_1.CursorUtils.show();
223
- if (process.stdin.setRawMode) {
224
- process.stdin.setRawMode(false);
225
- }
226
- process.stdin.pause();
227
+ utils_1.CursorUtils.cleanup();
227
228
  }
228
229
  }
229
230
  exports.ConfirmationInputHandler = ConfirmationInputHandler;
@@ -7,12 +7,9 @@ exports.renderPackageInfoLoading = renderPackageInfoLoading;
7
7
  exports.renderPackageInfoModal = renderPackageInfoModal;
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const themes_colors_1 = require("../themes-colors");
10
- /**
11
- * Remove ANSI color codes from a string for length calculation
12
- */
13
- function stripAnsi(str) {
14
- return str.replace(/\u001b\[[0-9;]*m/g, '');
15
- }
10
+ const utils_1 = require("../utils");
11
+ // Use shared ANSI stripping utility
12
+ const stripAnsi = utils_1.VersionUtils.stripAnsi;
16
13
  /**
17
14
  * Format a number for display (e.g., 1000000 -> "1M", 1000 -> "1K")
18
15
  */
@@ -213,6 +213,12 @@ function renderInterface(states, currentRow, scrollOffset, maxVisibleItems, forc
213
213
  const padding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(filterDisplay));
214
214
  output.push(filterDisplay + ' '.repeat(padding));
215
215
  }
216
+ else if (filterQuery) {
217
+ // Show applied filter when not in filter mode but filter is active
218
+ const filterDisplay = ' ' + chalk_1.default.bold.white('Search: ') + (0, themes_colors_1.getThemeColor)('primary')(filterQuery) + (0, themes_colors_1.getThemeColor)('textSecondary')(' (press / to edit)');
219
+ const padding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(filterDisplay));
220
+ output.push(filterDisplay + ' '.repeat(padding));
221
+ }
216
222
  else {
217
223
  // Show instructions when not filtering
218
224
  output.push(' ' +
@@ -249,51 +255,54 @@ function renderInterface(states, currentRow, scrollOffset, maxVisibleItems, forc
249
255
  const endItem = Math.min(scrollOffset + maxVisibleItems, totalVisualItems);
250
256
  let statusLine = '';
251
257
  if (filterMode) {
252
- // In filter mode, show ESC to exit filter
258
+ // In filter mode, show Enter to apply and ESC to clear
253
259
  if (totalPackages === 0) {
254
260
  statusLine = (0, themes_colors_1.getThemeColor)('warning')(`No matches found`) +
255
261
  ' ' +
256
- (0, themes_colors_1.getThemeColor)('textSecondary')('Esc ') +
257
- (0, themes_colors_1.getThemeColor)('textSecondary')('Clear filter');
262
+ chalk_1.default.bold.white('Esc ') + chalk_1.default.gray('Clear');
258
263
  }
259
264
  else if (totalVisualItems > maxVisibleItems) {
260
- statusLine = (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing ${chalk_1.default.white(startItem)}-${chalk_1.default.white(endItem)} of ${chalk_1.default.white(totalPackages)} matches (${chalk_1.default.white(totalBeforeFilter)} total)`) +
265
+ statusLine = (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing ${chalk_1.default.white(startItem)}-${chalk_1.default.white(endItem)} of ${chalk_1.default.white(totalPackages)} matches`) +
261
266
  ' ' +
262
- (0, themes_colors_1.getThemeColor)('textSecondary')('Esc ') +
263
- (0, themes_colors_1.getThemeColor)('textSecondary')('Clear filter');
267
+ chalk_1.default.bold.white('Enter ') + chalk_1.default.gray('Apply') +
268
+ ' ' +
269
+ chalk_1.default.bold.white('Esc ') + chalk_1.default.gray('Clear');
264
270
  }
265
271
  else {
266
- statusLine = (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing all ${chalk_1.default.white(totalPackages)} matches (${chalk_1.default.white(totalBeforeFilter)} total)`) +
272
+ statusLine = (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing all ${chalk_1.default.white(totalPackages)} matches`) +
273
+ ' ' +
274
+ chalk_1.default.bold.white('Enter ') + chalk_1.default.gray('Apply') +
267
275
  ' ' +
268
- (0, themes_colors_1.getThemeColor)('textSecondary')('Esc ') +
269
- (0, themes_colors_1.getThemeColor)('textSecondary')('Clear filter');
276
+ chalk_1.default.bold.white('Esc ') + chalk_1.default.gray('Clear');
270
277
  }
271
278
  }
272
279
  else if (totalPackages < totalBeforeFilter) {
273
280
  // Filter is applied but not in filter mode
274
281
  if (totalVisualItems > maxVisibleItems) {
275
- statusLine = (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing ${chalk_1.default.white(startItem)}-${chalk_1.default.white(endItem)} of ${chalk_1.default.white(totalPackages)} matches (${chalk_1.default.white(totalBeforeFilter)} total)`) +
282
+ statusLine = (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing ${chalk_1.default.white(startItem)}-${chalk_1.default.white(endItem)} of ${chalk_1.default.white(totalPackages)} matches`) +
283
+ ' ' +
284
+ chalk_1.default.bold.white('D/P/O ') + chalk_1.default.gray('Filter') +
276
285
  ' ' +
277
- (0, themes_colors_1.getThemeColor)('textSecondary')('/ ') +
278
- (0, themes_colors_1.getThemeColor)('textSecondary')('Edit filter') +
286
+ chalk_1.default.bold.white('M ') + chalk_1.default.gray('Minor') +
279
287
  ' ' +
280
- (0, themes_colors_1.getThemeColor)('textSecondary')('Enter ') +
281
- (0, themes_colors_1.getThemeColor)('textSecondary')('Confirm') +
288
+ chalk_1.default.bold.white('L ') + chalk_1.default.gray('All') +
282
289
  ' ' +
283
- (0, themes_colors_1.getThemeColor)('textSecondary')('Esc ') +
284
- (0, themes_colors_1.getThemeColor)('textSecondary')('Cancel');
290
+ chalk_1.default.bold.white('U ') + chalk_1.default.gray('None') +
291
+ ' ' +
292
+ chalk_1.default.bold.white('Esc ') + chalk_1.default.gray('Clear');
285
293
  }
286
294
  else {
287
- statusLine = (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing all ${chalk_1.default.white(totalPackages)} matches (${chalk_1.default.white(totalBeforeFilter)} total)`) +
295
+ statusLine = (0, themes_colors_1.getThemeColor)('textSecondary')(`Showing all ${chalk_1.default.white(totalPackages)} matches`) +
296
+ ' ' +
297
+ chalk_1.default.bold.white('D/P/O ') + chalk_1.default.gray('Filter') +
298
+ ' ' +
299
+ chalk_1.default.bold.white('M ') + chalk_1.default.gray('Minor') +
288
300
  ' ' +
289
- (0, themes_colors_1.getThemeColor)('textSecondary')('/ ') +
290
- chalk_1.default.gray('Edit filter') +
301
+ chalk_1.default.bold.white('L ') + chalk_1.default.gray('All') +
291
302
  ' ' +
292
- chalk_1.default.gray('Enter ') +
293
- chalk_1.default.gray('Confirm') +
303
+ chalk_1.default.bold.white('U ') + chalk_1.default.gray('None') +
294
304
  ' ' +
295
- chalk_1.default.gray('Esc ') +
296
- chalk_1.default.gray('Cancel');
305
+ chalk_1.default.bold.white('Esc ') + chalk_1.default.gray('Clear');
297
306
  }
298
307
  }
299
308
  else {
@@ -301,23 +310,18 @@ function renderInterface(states, currentRow, scrollOffset, maxVisibleItems, forc
301
310
  if (totalVisualItems > maxVisibleItems) {
302
311
  statusLine = chalk_1.default.gray(`Showing ${chalk_1.default.white(startItem)}-${chalk_1.default.white(endItem)} of ${chalk_1.default.white(totalPackages)} packages`) +
303
312
  ' ' +
304
- chalk_1.default.gray('Enter ') +
305
- chalk_1.default.gray('Confirm') +
306
- ' ' +
307
- chalk_1.default.gray('Esc ') +
308
- chalk_1.default.gray('Cancel');
313
+ chalk_1.default.bold.white('Enter ') + chalk_1.default.gray('Confirm');
309
314
  }
310
315
  else {
311
316
  statusLine = chalk_1.default.gray(`Showing all ${chalk_1.default.white(totalPackages)} packages`) +
312
317
  ' ' +
313
- chalk_1.default.gray('Enter ') +
314
- chalk_1.default.gray('Confirm') +
315
- ' ' +
316
- chalk_1.default.gray('Esc ') +
317
- chalk_1.default.gray('Cancel');
318
+ chalk_1.default.bold.white('Enter ') + chalk_1.default.gray('Confirm');
318
319
  }
319
320
  }
320
- output.push(' ' + statusLine);
321
+ // Pad status line to terminal width to clear any leftover characters
322
+ const statusLineFull = ' ' + statusLine;
323
+ const statusPadding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(statusLineFull));
324
+ output.push(statusLineFull + ' '.repeat(statusPadding));
321
325
  output.push('');
322
326
  // Render visible items
323
327
  if (renderableItems && renderableItems.length > 0) {
@@ -21,13 +21,17 @@ class FilterManager {
21
21
  getFilterQuery() {
22
22
  return this.state.filterQuery;
23
23
  }
24
- enterFilterMode() {
24
+ enterFilterMode(preserveQuery = false) {
25
25
  this.state.filterMode = true;
26
- this.state.filterQuery = '';
26
+ if (!preserveQuery) {
27
+ this.state.filterQuery = '';
28
+ }
27
29
  }
28
- exitFilterMode() {
30
+ exitFilterMode(clearQuery = false) {
29
31
  this.state.filterMode = false;
30
- this.state.filterQuery = '';
32
+ if (clearQuery) {
33
+ this.state.filterQuery = '';
34
+ }
31
35
  }
32
36
  updateFilterQuery(query) {
33
37
  this.state.filterQuery = query;
@@ -161,12 +161,12 @@ class StateManager {
161
161
  this.renderState.forceFullRender = true;
162
162
  }
163
163
  // Filter delegation
164
- enterFilterMode() {
165
- this.filterManager.enterFilterMode();
164
+ enterFilterMode(preserveQuery = false) {
165
+ this.filterManager.enterFilterMode(preserveQuery);
166
166
  // Use incremental render for search mode toggle (no blink)
167
167
  }
168
- exitFilterMode() {
169
- this.filterManager.exitFilterMode();
168
+ exitFilterMode(clearQuery = false) {
169
+ this.filterManager.exitFilterMode(clearQuery);
170
170
  this.navigationManager.setCurrentRow(0);
171
171
  this.navigationManager.setScrollOffset(0);
172
172
  // Use incremental render for search mode toggle (no blink)
@@ -89,6 +89,39 @@ const themeColorDefinitions = {
89
89
  text: '#ABB2BF',
90
90
  textSecondary: '#5C6370',
91
91
  },
92
+ gruvbox: {
93
+ bg: '#282828',
94
+ primary: '#83A598',
95
+ secondary: '#D3869B',
96
+ success: '#B8BB26',
97
+ warning: '#FABD2F',
98
+ error: '#FB4934',
99
+ border: '#504945',
100
+ text: '#EBDBB2',
101
+ textSecondary: '#A89984',
102
+ },
103
+ solarized: {
104
+ bg: '#002B36',
105
+ primary: '#268BD2',
106
+ secondary: '#D33682',
107
+ success: '#859900',
108
+ warning: '#B58900',
109
+ error: '#DC322F',
110
+ border: '#073642',
111
+ text: '#839496',
112
+ textSecondary: '#657B83',
113
+ },
114
+ github: {
115
+ bg: '#0D1117',
116
+ primary: '#58A6FF',
117
+ secondary: '#BC8CFF',
118
+ success: '#3FB950',
119
+ warning: '#D29922',
120
+ error: '#F85149',
121
+ border: '#30363D',
122
+ text: '#C9D1D9',
123
+ textSecondary: '#8B949E',
124
+ },
92
125
  };
93
126
  // Helper to apply color - handles both hex and named colors
94
127
  function applyColor(color, text) {
package/dist/ui/themes.js CHANGED
@@ -13,6 +13,9 @@ const themesMetadata = {
13
13
  monokai: 'Monokai',
14
14
  tokyonight: 'Tokyo Night',
15
15
  onedark: 'One Dark',
16
+ gruvbox: 'Gruvbox',
17
+ solarized: 'Solarized',
18
+ github: 'GitHub',
16
19
  };
17
20
  // Theme definitions
18
21
  exports.themes = Object.entries(themesMetadata).reduce((acc, [key, name]) => {
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  /**
3
- * Cursor utility functions for terminal control
3
+ * Cursor and terminal utility functions
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CursorUtils = void 0;
6
+ exports.ConsoleUtils = exports.CursorUtils = void 0;
7
7
  exports.CursorUtils = {
8
8
  /**
9
9
  * Hide the cursor in the terminal
@@ -29,5 +29,37 @@ exports.CursorUtils = {
29
29
  clearToEndOfScreen() {
30
30
  process.stdout.write('\x1b[J');
31
31
  },
32
+ /**
33
+ * Clean up terminal state - restore cursor and disable raw mode.
34
+ * Used when exiting interactive mode.
35
+ */
36
+ cleanup() {
37
+ exports.CursorUtils.show();
38
+ if (process.stdin.setRawMode) {
39
+ process.stdin.setRawMode(false);
40
+ }
41
+ process.stdin.pause();
42
+ },
43
+ };
44
+ /**
45
+ * Console utilities for progress display and line clearing
46
+ */
47
+ exports.ConsoleUtils = {
48
+ /**
49
+ * Default line width for clearing progress messages
50
+ */
51
+ LINE_WIDTH: 80,
52
+ /**
53
+ * Show a progress message on the current line (overwrites previous content)
54
+ */
55
+ showProgress(message) {
56
+ process.stdout.write(`\r${' '.repeat(exports.ConsoleUtils.LINE_WIDTH)}\r${message}`);
57
+ },
58
+ /**
59
+ * Clear the current progress line
60
+ */
61
+ clearProgress() {
62
+ process.stdout.write('\r' + ' '.repeat(exports.ConsoleUtils.LINE_WIDTH) + '\r');
63
+ },
32
64
  };
33
65
  //# sourceMappingURL=cursor.js.map
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CursorUtils = exports.VersionUtils = void 0;
3
+ exports.ConsoleUtils = exports.CursorUtils = exports.VersionUtils = void 0;
4
4
  var version_1 = require("./version");
5
5
  Object.defineProperty(exports, "VersionUtils", { enumerable: true, get: function () { return version_1.VersionUtils; } });
6
6
  var cursor_1 = require("./cursor");
7
7
  Object.defineProperty(exports, "CursorUtils", { enumerable: true, get: function () { return cursor_1.CursorUtils; } });
8
+ Object.defineProperty(exports, "ConsoleUtils", { enumerable: true, get: function () { return cursor_1.ConsoleUtils; } });
8
9
  //# sourceMappingURL=index.js.map
@@ -5,6 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.VersionUtils = void 0;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
+ /**
9
+ * ANSI escape code pattern for stripping terminal colors
10
+ */
11
+ const ANSI_PATTERN = /\u001b\[[0-9;]*m/g;
8
12
  class VersionUtils {
9
13
  static applyVersionPrefix(originalSpecifier, targetVersion) {
10
14
  // Extract prefix from original specifier (^ or ~)
@@ -13,9 +17,17 @@ class VersionUtils {
13
17
  // Return target version with same prefix
14
18
  return prefix + targetVersion;
15
19
  }
20
+ /**
21
+ * Strip ANSI escape codes from a string
22
+ */
23
+ static stripAnsi(str) {
24
+ return str.replace(ANSI_PATTERN, '');
25
+ }
26
+ /**
27
+ * Get the visual length of a string (excluding ANSI codes)
28
+ */
16
29
  static getVisualLength(str) {
17
- // Strip ANSI escape codes to get visual length
18
- return str.replace(/\u001b\[[0-9;]*m/g, '').length;
30
+ return VersionUtils.stripAnsi(str).length;
19
31
  }
20
32
  /**
21
33
  * Truncate text with ellipsis in the middle if it exceeds maxLength
@@ -35,7 +47,7 @@ class VersionUtils {
35
47
  const startLength = Math.ceil(availableLength / 2);
36
48
  const endLength = Math.floor(availableLength / 2);
37
49
  // Extract raw text without ANSI codes to calculate positions
38
- const rawText = str.replace(/\u001b\[[0-9;]*m/g, '');
50
+ const rawText = VersionUtils.stripAnsi(str);
39
51
  const start = rawText.substring(0, startLength);
40
52
  const end = rawText.substring(rawText.length - endLength);
41
53
  return start + ellipsis + end;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.debugLog = void 0;
4
+ exports.enableDebugLogging = enableDebugLogging;
5
+ exports.isDebugEnabled = isDebugEnabled;
6
+ exports.getDebugLogPath = getDebugLogPath;
7
+ const fs_1 = require("fs");
8
+ const path_1 = require("path");
9
+ let _enabled = false;
10
+ let _logFile = null;
11
+ const pad = (n, width = 2) => String(n).padStart(width, '0');
12
+ function timestamp() {
13
+ const d = new Date();
14
+ return (`${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ` +
15
+ `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${pad(d.getMilliseconds(), 3)}`);
16
+ }
17
+ function getLogFile() {
18
+ if (!_logFile) {
19
+ const d = new Date();
20
+ const dateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
21
+ _logFile = (0, path_1.join)(`inup-debug-${dateStr}.log`);
22
+ // Write a header so the file is easy to identify
23
+ (0, fs_1.writeFileSync)(_logFile, `=== inup debug log started at ${timestamp()} ===\n`, { flag: 'a' });
24
+ }
25
+ return _logFile;
26
+ }
27
+ function enableDebugLogging() {
28
+ _enabled = true;
29
+ const file = getLogFile();
30
+ // Print the path so the user knows where to look
31
+ process.stderr.write(`[inup] debug logging enabled → ${file}\n`);
32
+ }
33
+ function isDebugEnabled() {
34
+ return _enabled;
35
+ }
36
+ function getDebugLogPath() {
37
+ return _logFile;
38
+ }
39
+ function write(level, context, message, extra) {
40
+ if (!_enabled)
41
+ return;
42
+ let line = `[${timestamp()}] [${level}] [${context}] ${message}`;
43
+ if (extra !== undefined) {
44
+ if (extra instanceof Error) {
45
+ line += ` | ${extra.name}: ${extra.message}`;
46
+ if (extra.stack) {
47
+ const stackLines = extra.stack.split('\n').slice(1, 4).join(' | ');
48
+ line += ` | ${stackLines}`;
49
+ }
50
+ }
51
+ else if (typeof extra === 'object') {
52
+ try {
53
+ line += ` | ${JSON.stringify(extra)}`;
54
+ }
55
+ catch {
56
+ line += ` | [unserializable]`;
57
+ }
58
+ }
59
+ else {
60
+ line += ` | ${extra}`;
61
+ }
62
+ }
63
+ line += '\n';
64
+ try {
65
+ (0, fs_1.appendFileSync)(getLogFile(), line);
66
+ }
67
+ catch {
68
+ // Never crash the app because of debug logging
69
+ }
70
+ }
71
+ exports.debugLog = {
72
+ info: (context, message, extra) => write('INFO', context, message, extra),
73
+ warn: (context, message, extra) => write('WARN', context, message, extra),
74
+ error: (context, message, extra) => write('ERROR', context, message, extra),
75
+ /** Log elapsed time since a start timestamp obtained via Date.now() */
76
+ perf: (context, label, startMs, extra) => {
77
+ const elapsed = Date.now() - startMs;
78
+ write('PERF', context, `${label} — ${elapsed}ms`, extra);
79
+ },
80
+ };
81
+ //# sourceMappingURL=debug-logger.js.map
@@ -21,6 +21,7 @@ exports.collectAllDependenciesAsync = exports.readPackageJsonAsync = void 0;
21
21
  __exportStar(require("./filesystem"), exports);
22
22
  __exportStar(require("./exec"), exports);
23
23
  __exportStar(require("./version"), exports);
24
+ __exportStar(require("./debug-logger"), exports);
24
25
  // Re-export async functions for convenience
25
26
  var filesystem_1 = require("./filesystem");
26
27
  Object.defineProperty(exports, "readPackageJsonAsync", { enumerable: true, get: function () { return filesystem_1.readPackageJsonAsync; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inup",
3
- "version": "1.4.5",
3
+ "version": "1.4.7",
4
4
  "description": "Interactive CLI tool for upgrading dependencies with ease. Auto-detects and works with npm, yarn, pnpm, and bun. Inspired by yarn upgrade-interactive. Supports monorepos, workspaces, and batch upgrades.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {