inup 1.6.6 → 1.6.8

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 (110) hide show
  1. package/README.md +25 -2
  2. package/dist/{interactive-ui.js → app/interactive-ui.js} +34 -21
  3. package/dist/{core → app}/upgrade-runner.js +18 -22
  4. package/dist/cli.js +19 -18
  5. package/dist/{services → features/audit}/background-audit.js +2 -2
  6. package/dist/features/{headless/vulnerability-audit.js → audit/headless-audit.js} +8 -11
  7. package/dist/features/audit/index.js +36 -0
  8. package/dist/{ui/presenters/vulnerability.js → features/audit/presenter.js} +1 -3
  9. package/dist/{ui/controllers → features/audit}/vulnerability-audit-controller.js +14 -8
  10. package/dist/{services → features/audit}/vulnerability-checker.js +9 -10
  11. package/dist/features/changelog/clients/github-client.js +41 -21
  12. package/dist/features/changelog/clients/npm-registry-client.js +16 -2
  13. package/dist/features/changelog/index.js +1 -1
  14. package/dist/features/changelog/services/package-metadata-service.js +6 -2
  15. package/dist/features/changelog/services/release-notes-service.js +9 -12
  16. package/dist/features/changelog/types.js +3 -0
  17. package/dist/features/debug/index.js +3 -4
  18. package/dist/features/debug/{services/perf-logger.js → perf-logger.js} +15 -15
  19. package/dist/features/debug/types.js +3 -0
  20. package/dist/features/headless/headless-runner.js +32 -19
  21. package/dist/features/headless/index.js +2 -5
  22. package/dist/features/headless/report.js +2 -0
  23. package/dist/features/interactive/controllers/index.js +6 -0
  24. package/dist/{ui → features/interactive}/controllers/package-info-modal-controller.js +3 -3
  25. package/dist/features/interactive/index.js +21 -0
  26. package/dist/{ui → features/interactive}/input-handler.js +6 -6
  27. package/dist/{ui → features/interactive}/modal/index.js +1 -1
  28. package/dist/{ui → features/interactive}/modal/layout.js +5 -5
  29. package/dist/{ui/renderer/package-list.js → features/interactive/modal/package-info-sections/index.js} +3 -3
  30. package/dist/{ui → features/interactive}/modal/package-info-sections/release-notes.js +1 -1
  31. package/dist/{ui → features/interactive}/modal/package-info-sections/sections.js +55 -24
  32. package/dist/{ui → features/interactive}/modal/package-info-sections/text.js +6 -6
  33. package/dist/{ui → features/interactive}/modal/package-info.js +33 -18
  34. package/dist/features/interactive/modal/types.js +3 -0
  35. package/dist/{ui → features/interactive}/presenters/health.js +2 -2
  36. package/dist/{ui → features/interactive}/renderer/confirmation.js +6 -3
  37. package/dist/{ui → features/interactive}/renderer/help-modal.js +3 -3
  38. package/dist/{ui → features/interactive}/renderer/index.js +3 -4
  39. package/dist/{types.js → features/interactive/renderer/package-list/index.js} +3 -4
  40. package/dist/{ui → features/interactive}/renderer/package-list/interface.js +15 -16
  41. package/dist/{ui → features/interactive}/renderer/package-list/rows.js +31 -25
  42. package/dist/features/{debug → interactive}/renderer/performance-modal.js +3 -3
  43. package/dist/{ui/utils/version.js → features/interactive/renderer/version-format.js} +9 -13
  44. package/dist/{ui → features/interactive}/session/action-dispatcher.js +2 -2
  45. package/dist/{ui → features/interactive}/session/index.js +5 -4
  46. package/dist/{ui → features/interactive}/session/interactive-session.js +44 -23
  47. package/dist/{ui → features/interactive}/session/selection-state-builder.js +25 -9
  48. package/dist/{ui → features/interactive}/state/filter-manager.js +3 -3
  49. package/dist/{ui → features/interactive}/state/index.js +7 -7
  50. package/dist/{ui → features/interactive}/state/state-manager.js +10 -8
  51. package/dist/{ui → features/interactive}/state/theme-manager.js +7 -5
  52. package/dist/{ui → features/interactive}/themes-colors.js +3 -1
  53. package/dist/features/upgrade/index.js +8 -0
  54. package/dist/{core → features/upgrade}/package-detector.js +96 -37
  55. package/dist/{core → features/upgrade}/upgrader.js +84 -35
  56. package/dist/index.js +2 -2
  57. package/dist/{config → shared/config}/package-meta.js +1 -1
  58. package/dist/{config → shared/config}/project-config.js +10 -8
  59. package/dist/{utils/config.js → shared/config/user-config.js} +11 -11
  60. package/dist/{utils → shared}/debug-logger.js +9 -9
  61. package/dist/{utils → shared}/exec.js +4 -4
  62. package/dist/{ui/modal/package-info-sections.js → shared/fs/index.js} +4 -3
  63. package/dist/{utils/filesystem → shared/fs}/io.js +3 -4
  64. package/dist/shared/fs/paths.js +19 -0
  65. package/dist/{utils/filesystem → shared/fs}/scan.js +23 -20
  66. package/dist/{utils → shared}/git.js +3 -3
  67. package/dist/{services → shared}/http/etag-store.js +56 -4
  68. package/dist/{services → shared}/http/resizable-semaphore.js +3 -1
  69. package/dist/{utils → shared}/local-env.js +8 -8
  70. package/dist/{services/package-manager-detector.js → shared/package-manager.js} +26 -25
  71. package/dist/shared/pnpm-catalogs.js +138 -0
  72. package/dist/{services → shared/registry}/npm-registry.js +54 -33
  73. package/dist/shared/registry/registry-config.js +76 -0
  74. package/dist/{services → shared/registry}/version-checker.js +25 -26
  75. package/dist/{ui/utils → shared/terminal}/cursor.js +1 -1
  76. package/dist/{ui/utils → shared/terminal}/index.js +5 -7
  77. package/dist/{ui/utils → shared/terminal}/terminal-input.js +5 -0
  78. package/dist/shared/terminal/text.js +48 -0
  79. package/dist/shared/types/index.js +20 -0
  80. package/dist/{utils/version.js → shared/versions.js} +45 -30
  81. package/package.json +21 -8
  82. package/dist/core/index.js +0 -23
  83. package/dist/features/changelog/types/changelog.types.js +0 -3
  84. package/dist/features/debug/types/debug.types.js +0 -3
  85. package/dist/services/index.js +0 -25
  86. package/dist/ui/controllers/index.js +0 -8
  87. package/dist/ui/index.js +0 -27
  88. package/dist/ui/presenters/index.js +0 -11
  89. package/dist/ui/utils/text.js +0 -76
  90. package/dist/utils/filesystem/paths.js +0 -19
  91. package/dist/utils/filesystem.js +0 -20
  92. package/dist/utils/index.js +0 -34
  93. /package/dist/{ui/modal → features/audit}/types.js +0 -0
  94. /package/dist/features/debug/{services/performance-tracker.js → performance-tracker.js} +0 -0
  95. /package/dist/{ui → features/interactive}/keymap.js +0 -0
  96. /package/dist/{ui → features/interactive}/modal/theme-selector.js +0 -0
  97. /package/dist/{ui → features/interactive}/state/modal-manager.js +0 -0
  98. /package/dist/{ui → features/interactive}/state/navigation-manager.js +0 -0
  99. /package/dist/{ui → features/interactive}/themes.js +0 -0
  100. /package/dist/{config → shared/config}/constants.js +0 -0
  101. /package/dist/{config → shared/config}/index.js +0 -0
  102. /package/dist/{utils → shared}/engines.js +0 -0
  103. /package/dist/{services → shared}/http/adaptive-controller.js +0 -0
  104. /package/dist/{services → shared}/http/inflight.js +0 -0
  105. /package/dist/{services → shared}/http/retry.js +0 -0
  106. /package/dist/{utils → shared}/manifest.js +0 -0
  107. /package/dist/{utils → shared/terminal}/color.js +0 -0
  108. /package/dist/{types → shared/types}/domain.js +0 -0
  109. /package/dist/{types → shared/types}/streaming.js +0 -0
  110. /package/dist/{types → shared/types}/ui.js +0 -0
@@ -8,12 +8,12 @@ exports.renderPackageLine = renderPackageLine;
8
8
  exports.renderSectionHeader = renderSectionHeader;
9
9
  exports.renderSpacer = renderSpacer;
10
10
  const chalk_1 = __importDefault(require("chalk"));
11
- const utils_1 = require("../../utils");
12
- const themes_colors_1 = require("../../themes-colors");
13
- const vulnerability_1 = require("../../presenters/vulnerability");
11
+ const audit_1 = require("../../../audit");
14
12
  const health_1 = require("../../presenters/health");
13
+ const themes_colors_1 = require("../../themes-colors");
14
+ const version_format_1 = require("../version-format");
15
15
  function padLineToWidth(line, terminalWidth) {
16
- const padding = Math.max(0, terminalWidth - utils_1.VersionUtils.getVisualLength(line));
16
+ const padding = Math.max(0, terminalWidth - version_format_1.VersionUtils.getVisualLength(line));
17
17
  return line + ' '.repeat(padding);
18
18
  }
19
19
  function getTypeBadge(type) {
@@ -24,11 +24,14 @@ function getTypeBadge(type) {
24
24
  return (0, themes_colors_1.getThemeColor)('textSecondary')('[P]');
25
25
  case 'optionalDependencies':
26
26
  return (0, themes_colors_1.getThemeColor)('textSecondary')('[O]');
27
- case 'dependencies':
28
27
  default:
29
28
  return '';
30
29
  }
31
30
  }
31
+ /** Marks entries whose range lives in a pnpm catalog (pnpm-workspace.yaml), not a package.json. */
32
+ function getCatalogBadge(catalog) {
33
+ return catalog ? (0, themes_colors_1.getThemeColor)('textSecondary')('[C]') : '';
34
+ }
32
35
  function renderPackageLine(state, _index, isCurrentRow, terminalWidth = 80, options = {}) {
33
36
  const prefix = isCurrentRow ? (0, themes_colors_1.getThemeColor)('success')('❯ ') : ' ';
34
37
  let packageName;
@@ -40,10 +43,10 @@ function renderPackageLine(state, _index, isCurrentRow, terminalWidth = 80, opti
40
43
  if (isCurrentRow) {
41
44
  packageName =
42
45
  chalk_1.default.bold((0, themes_colors_1.getThemeColor)('packageAuthor')(author)) +
43
- (0, themes_colors_1.getThemeColor)('packageName')('/' + packagePart);
46
+ (0, themes_colors_1.getThemeColor)('packageName')(`/${packagePart}`);
44
47
  }
45
48
  else {
46
- packageName = chalk_1.default.bold.white(author) + chalk_1.default.white('/' + packagePart);
49
+ packageName = chalk_1.default.bold.white(author) + chalk_1.default.white(`/${packagePart}`);
47
50
  }
48
51
  }
49
52
  else {
@@ -74,7 +77,7 @@ function renderPackageLine(state, _index, isCurrentRow, terminalWidth = 80, opti
74
77
  }
75
78
  else if (state.hasRangeUpdate) {
76
79
  rangeDot = isRangeSelected ? (0, themes_colors_1.getThemeColor)('dot')('●') : (0, themes_colors_1.getThemeColor)('dotEmpty')('○');
77
- const rangeVersionWithPrefix = utils_1.VersionUtils.applyVersionPrefix(state.currentVersionSpecifier, state.rangeVersion);
80
+ const rangeVersionWithPrefix = version_format_1.VersionUtils.applyVersionPrefix(state.currentVersionSpecifier, state.rangeVersion);
78
81
  rangeVersionText = (0, themes_colors_1.getThemeColor)('versionRange')(rangeVersionWithPrefix);
79
82
  }
80
83
  else {
@@ -93,7 +96,7 @@ function renderPackageLine(state, _index, isCurrentRow, terminalWidth = 80, opti
93
96
  }
94
97
  else if (state.hasMajorUpdate) {
95
98
  latestDot = isLatestSelected ? (0, themes_colors_1.getThemeColor)('dot')('●') : (0, themes_colors_1.getThemeColor)('dotEmpty')('○');
96
- const latestVersionWithPrefix = utils_1.VersionUtils.applyVersionPrefix(state.currentVersionSpecifier, state.latestVersion);
99
+ const latestVersionWithPrefix = version_format_1.VersionUtils.applyVersionPrefix(state.currentVersionSpecifier, state.latestVersion);
97
100
  latestVersionText = (0, themes_colors_1.getThemeColor)('versionLatest')(latestVersionWithPrefix);
98
101
  }
99
102
  else {
@@ -110,44 +113,47 @@ function renderPackageLine(state, _index, isCurrentRow, terminalWidth = 80, opti
110
113
  const prefixWidth = 2;
111
114
  const availableForPackageName = terminalWidth - prefixWidth - otherColumnsWidth - 1;
112
115
  const packageNameWidth = Math.min(maxPackageNameWidth, Math.max(minPackageNameWidth, availableForPackageName));
113
- const badgeWidth = state.type === 'dependencies' ? 0 : 3;
114
- const truncatedName = utils_1.VersionUtils.truncateMiddle(state.name, packageNameWidth - 1 - badgeWidth);
116
+ // Trailing badges each occupy 3 columns: the dep-type marker ([D]/[P]/[O])
117
+ // and the pnpm-catalog marker ([C]); both may be present at once.
118
+ const badgeWidth = (state.type === 'dependencies' ? 0 : 3) + (state.catalog ? 3 : 0);
119
+ const truncatedName = version_format_1.VersionUtils.truncateMiddle(state.name, packageNameWidth - 1 - badgeWidth);
115
120
  const shouldShowDashes = (paddingAmount) => paddingAmount > 2;
116
121
  const dashColor = isCurrentRow ? chalk_1.default.white : chalk_1.default.gray;
117
122
  const displayName = truncatedName !== state.name ? truncatedName : packageName;
118
123
  const typeBadge = getTypeBadge(state.type);
119
- const shouldShowVulnerability = (0, vulnerability_1.shouldDisplayVulnerabilityForDependency)(state.type, options);
120
- const vulnBadge = shouldShowVulnerability ? (0, vulnerability_1.getVulnerabilityBadge)(state.vulnerability) : '';
121
- const vulnBadgeWidth = vulnBadge ? utils_1.VersionUtils.getVisualLength(vulnBadge) + 1 : 0;
124
+ const shouldShowVulnerability = (0, audit_1.shouldDisplayVulnerabilityForDependency)(state.type, options);
125
+ const vulnBadge = shouldShowVulnerability ? (0, audit_1.getVulnerabilityBadge)(state.vulnerability) : '';
126
+ const vulnBadgeWidth = vulnBadge ? version_format_1.VersionUtils.getVisualLength(vulnBadge) + 1 : 0;
122
127
  // Deprecation / engines-incompatibility marker (independent of dep type).
123
128
  const healthBadge = (0, health_1.getHealthBadge)(state);
124
- const healthBadgeWidth = healthBadge ? utils_1.VersionUtils.getVisualLength(healthBadge) + 1 : 0;
125
- const nameLength = utils_1.VersionUtils.getVisualLength(truncatedName);
129
+ const healthBadgeWidth = healthBadge ? version_format_1.VersionUtils.getVisualLength(healthBadge) + 1 : 0;
130
+ const nameLength = version_format_1.VersionUtils.getVisualLength(truncatedName);
126
131
  const namePadding = Math.max(0, packageNameWidth - nameLength - 1 - badgeWidth - vulnBadgeWidth - healthBadgeWidth);
127
132
  const nameDashes = shouldShowDashes(namePadding)
128
133
  ? dashColor('-').repeat(namePadding)
129
134
  : ' '.repeat(namePadding);
130
135
  const vulnSuffix = vulnBadge ? ` ${vulnBadge}` : '';
131
136
  const healthSuffix = healthBadge ? ` ${healthBadge}` : '';
132
- const packageNameSection = typeBadge
133
- ? `${displayName} ${nameDashes}${vulnSuffix}${healthSuffix}${typeBadge}`
137
+ const trailingBadges = `${getCatalogBadge(state.catalog)}${typeBadge}`;
138
+ const packageNameSection = trailingBadges
139
+ ? `${displayName} ${nameDashes}${vulnSuffix}${healthSuffix}${trailingBadges}`
134
140
  : `${displayName} ${nameDashes}${vulnSuffix}${healthSuffix}`;
135
141
  const currentSection = `${currentDot} ${currentVersion}`;
136
- const currentSectionLength = utils_1.VersionUtils.getVisualLength(currentSection) + 1;
142
+ const currentSectionLength = version_format_1.VersionUtils.getVisualLength(currentSection) + 1;
137
143
  const currentPadding = Math.max(0, currentColumnWidth - currentSectionLength);
138
144
  const currentPaddingText = shouldShowDashes(currentPadding)
139
145
  ? dashColor('-').repeat(currentPadding)
140
146
  : ' '.repeat(currentPadding);
141
- const currentWithPadding = currentSection + ' ' + currentPaddingText;
147
+ const currentWithPadding = `${currentSection} ${currentPaddingText}`;
142
148
  let rangeSection = '';
143
149
  if (isPending || isFailed || state.hasRangeUpdate) {
144
150
  rangeSection = `${rangeDot} ${rangeVersionText}`;
145
- const rangeSectionLength = utils_1.VersionUtils.getVisualLength(rangeSection) + 1;
151
+ const rangeSectionLength = version_format_1.VersionUtils.getVisualLength(rangeSection) + 1;
146
152
  const rangePadding = Math.max(0, rangeColumnWidth - rangeSectionLength);
147
153
  const rangePaddingText = shouldShowDashes(rangePadding)
148
154
  ? dashColor('-').repeat(rangePadding)
149
155
  : ' '.repeat(rangePadding);
150
- rangeSection += ' ' + rangePaddingText;
156
+ rangeSection += ` ${rangePaddingText}`;
151
157
  }
152
158
  else {
153
159
  rangeSection = ' '.repeat(rangeColumnWidth);
@@ -155,12 +161,12 @@ function renderPackageLine(state, _index, isCurrentRow, terminalWidth = 80, opti
155
161
  let latestSection = '';
156
162
  if (isPending || isFailed || state.hasMajorUpdate) {
157
163
  latestSection = `${latestDot} ${latestVersionText}`;
158
- const latestSectionLength = utils_1.VersionUtils.getVisualLength(latestSection) + 1;
164
+ const latestSectionLength = version_format_1.VersionUtils.getVisualLength(latestSection) + 1;
159
165
  const latestPadding = Math.max(0, latestColumnWidth - latestSectionLength);
160
166
  const latestPaddingText = shouldShowDashes(latestPadding)
161
167
  ? dashColor('-').repeat(latestPadding)
162
168
  : ' '.repeat(latestPadding);
163
- latestSection += ' ' + latestPaddingText;
169
+ latestSection += ` ${latestPaddingText}`;
164
170
  }
165
171
  else {
166
172
  latestSection = ' '.repeat(latestColumnWidth);
@@ -169,7 +175,7 @@ function renderPackageLine(state, _index, isCurrentRow, terminalWidth = 80, opti
169
175
  }
170
176
  function renderSectionHeader(title, sectionType) {
171
177
  const colorFn = sectionType === 'main' ? chalk_1.default.cyan : sectionType === 'peer' ? chalk_1.default.magenta : chalk_1.default.yellow;
172
- return ' ' + colorFn.bold(title);
178
+ return ` ${colorFn.bold(title)}`;
173
179
  }
174
180
  function renderSpacer() {
175
181
  return '';
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.renderPerformanceModal = renderPerformanceModal;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
- const modal_1 = require("../../../ui/modal");
8
+ const modal_1 = require("../modal");
9
9
  function formatMs(value) {
10
10
  if (value === undefined || value === null)
11
11
  return chalk_1.default.gray('—');
@@ -122,7 +122,7 @@ function renderPerformanceModal(snapshot, terminalWidth = 80, terminalHeight = 2
122
122
  for (let i = 0; i < topPadding; i++) {
123
123
  lines.push('');
124
124
  }
125
- lines.push(' '.repeat(padding) + chalk_1.default.gray('╭' + '─'.repeat(modalWidth - 2) + '╮'));
125
+ lines.push(' '.repeat(padding) + chalk_1.default.gray(`╭${'─'.repeat(modalWidth - 2)}╮`));
126
126
  for (const section of pinned) {
127
127
  for (const row of section.rows) {
128
128
  lines.push((0, modal_1.renderModalRow)(padding, modalWidth, row));
@@ -146,7 +146,7 @@ function renderPerformanceModal(snapshot, terminalWidth = 80, terminalHeight = 2
146
146
  if (footer) {
147
147
  lines.push((0, modal_1.renderModalRow)(padding, modalWidth, footer));
148
148
  }
149
- lines.push(' '.repeat(padding) + chalk_1.default.gray('╰' + '─'.repeat(modalWidth - 2) + '╯'));
149
+ lines.push(' '.repeat(padding) + chalk_1.default.gray(`╰${'─'.repeat(modalWidth - 2)}╯`));
150
150
  return {
151
151
  lines,
152
152
  maxScrollOffset: maxScroll,
@@ -3,19 +3,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.VersionUtils = exports.getVisualLength = exports.stripAnsi = void 0;
7
- exports.applyVersionPrefix = applyVersionPrefix;
6
+ exports.VersionUtils = exports.stripAnsi = exports.getVisualLength = exports.applyVersionPrefix = void 0;
8
7
  exports.truncateMiddle = truncateMiddle;
9
8
  exports.formatVersionDiff = formatVersionDiff;
10
9
  const chalk_1 = __importDefault(require("chalk"));
11
- const text_1 = require("./text");
12
- Object.defineProperty(exports, "stripAnsi", { enumerable: true, get: function () { return text_1.stripAnsi; } });
10
+ const text_1 = require("../../../shared/terminal/text");
13
11
  Object.defineProperty(exports, "getVisualLength", { enumerable: true, get: function () { return text_1.getVisualLength; } });
14
- function applyVersionPrefix(originalSpecifier, targetVersion) {
15
- const prefixMatch = originalSpecifier.match(/^([^\d]+)/);
16
- const prefix = prefixMatch ? prefixMatch[1] : '';
17
- return prefix + targetVersion;
18
- }
12
+ Object.defineProperty(exports, "stripAnsi", { enumerable: true, get: function () { return text_1.stripAnsi; } });
13
+ const versions_1 = require("../../../shared/versions");
14
+ Object.defineProperty(exports, "applyVersionPrefix", { enumerable: true, get: function () { return versions_1.applyVersionPrefix; } });
19
15
  function truncateMiddle(str, maxLength) {
20
16
  const visualLength = (0, text_1.getVisualLength)(str);
21
17
  if (visualLength <= maxLength) {
@@ -34,8 +30,8 @@ function formatVersionDiff(current, target, colorFn) {
34
30
  if (current === target) {
35
31
  return chalk_1.default.white(target);
36
32
  }
37
- const currentParts = current.split('.').map((part) => parseInt(part) || 0);
38
- const targetParts = target.split('.').map((part) => parseInt(part) || 0);
33
+ const currentParts = current.split('.').map((part) => parseInt(part, 10) || 0);
34
+ const targetParts = target.split('.').map((part) => parseInt(part, 10) || 0);
39
35
  let firstDiffSegment = -1;
40
36
  const maxLength = Math.max(currentParts.length, targetParts.length);
41
37
  for (let i = 0; i < maxLength; i++) {
@@ -67,10 +63,10 @@ function formatVersionDiff(current, target, colorFn) {
67
63
  return result.join('');
68
64
  }
69
65
  exports.VersionUtils = {
70
- applyVersionPrefix,
66
+ applyVersionPrefix: versions_1.applyVersionPrefix,
71
67
  truncateMiddle,
72
68
  formatVersionDiff,
73
69
  stripAnsi: text_1.stripAnsi,
74
70
  getVisualLength: text_1.getVisualLength,
75
71
  };
76
- //# sourceMappingURL=version.js.map
72
+ //# sourceMappingURL=version-format.js.map
@@ -96,7 +96,7 @@ function dispatchAction(action, ctx) {
96
96
  renderInterface();
97
97
  if (stateManager.getInfoModalSessionId() === modalSessionId &&
98
98
  packageInfoModalController.getVersionCount(currentState) > 0) {
99
- packageInfoModalController.loadVersionAtIndex(currentState, 0, () => {
99
+ void packageInfoModalController.loadVersionAtIndex(currentState, 0, () => {
100
100
  if (!isResolved())
101
101
  renderInterface();
102
102
  });
@@ -158,7 +158,7 @@ function dispatchAction(action, ctx) {
158
158
  if (newIndex >= 0) {
159
159
  stateManager.resetInfoModalScroll();
160
160
  if (!packageInfoModalController.isVersionLoaded(currentState, newIndex)) {
161
- packageInfoModalController.loadVersionAtIndex(currentState, newIndex, () => {
161
+ void packageInfoModalController.loadVersionAtIndex(currentState, newIndex, () => {
162
162
  if (!isResolved())
163
163
  renderInterface();
164
164
  });
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.dispatchAction = exports.deduplicatePackages = exports.createUpgradeChoices = exports.createPendingSelectionStates = exports.createSelectionStates = exports.runInteractiveSession = void 0;
3
+ exports.selectionKey = exports.deduplicatePackages = exports.createUpgradeChoices = exports.createSelectionStates = exports.createPendingSelectionStates = exports.runInteractiveSession = exports.dispatchAction = void 0;
4
+ var action_dispatcher_1 = require("./action-dispatcher");
5
+ Object.defineProperty(exports, "dispatchAction", { enumerable: true, get: function () { return action_dispatcher_1.dispatchAction; } });
4
6
  var interactive_session_1 = require("./interactive-session");
5
7
  Object.defineProperty(exports, "runInteractiveSession", { enumerable: true, get: function () { return interactive_session_1.runInteractiveSession; } });
6
8
  var selection_state_builder_1 = require("./selection-state-builder");
7
- Object.defineProperty(exports, "createSelectionStates", { enumerable: true, get: function () { return selection_state_builder_1.createSelectionStates; } });
8
9
  Object.defineProperty(exports, "createPendingSelectionStates", { enumerable: true, get: function () { return selection_state_builder_1.createPendingSelectionStates; } });
10
+ Object.defineProperty(exports, "createSelectionStates", { enumerable: true, get: function () { return selection_state_builder_1.createSelectionStates; } });
9
11
  Object.defineProperty(exports, "createUpgradeChoices", { enumerable: true, get: function () { return selection_state_builder_1.createUpgradeChoices; } });
10
12
  Object.defineProperty(exports, "deduplicatePackages", { enumerable: true, get: function () { return selection_state_builder_1.deduplicatePackages; } });
11
- var action_dispatcher_1 = require("./action-dispatcher");
12
- Object.defineProperty(exports, "dispatchAction", { enumerable: true, get: function () { return action_dispatcher_1.dispatchAction; } });
13
+ Object.defineProperty(exports, "selectionKey", { enumerable: true, get: function () { return selection_state_builder_1.selectionKey; } });
13
14
  //# sourceMappingURL=index.js.map
@@ -5,12 +5,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.runInteractiveSession = runInteractiveSession;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
- const index_1 = require("../index");
9
- const cursor_1 = require("../utils/cursor");
10
- const themes_colors_1 = require("../themes-colors");
11
- const debug_1 = require("../../features/debug");
8
+ const user_config_1 = require("../../../shared/config/user-config");
9
+ const terminal_1 = require("../../../shared/terminal");
10
+ const cursor_1 = require("../../../shared/terminal/cursor");
11
+ const debug_1 = require("../../debug");
12
+ const input_handler_1 = require("../input-handler");
12
13
  const help_modal_1 = require("../renderer/help-modal");
13
- const config_1 = require("../../utils/config");
14
+ const performance_modal_1 = require("../renderer/performance-modal");
15
+ const state_1 = require("../state");
16
+ const themes_colors_1 = require("../themes-colors");
14
17
  const action_dispatcher_1 = require("./action-dispatcher");
15
18
  function getTerminalHeight() {
16
19
  if (process.stdout.isTTY && typeof process.stdout.rows === 'number' && process.stdout.rows > 0) {
@@ -21,7 +24,7 @@ function getTerminalHeight() {
21
24
  async function runInteractiveSession(selectionStates, packageManager, renderer, packageInfoModalController, vulnerabilityAuditController, options, onRefreshViewReady, loadingProgress, attachRefresh) {
22
25
  return new Promise((resolve) => {
23
26
  const states = selectionStates;
24
- const stateManager = new index_1.StateManager(0, getTerminalHeight(), config_1.configManager.getFilters() ?? undefined);
27
+ const stateManager = new state_1.StateManager(0, getTerminalHeight(), user_config_1.configManager.getFilters() ?? undefined);
25
28
  let isResolved = false;
26
29
  let ownsAlternateScreen = false;
27
30
  const vulnerabilityDisplayOptions = options;
@@ -32,19 +35,24 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
32
35
  let previousModalViewportLineCount = null;
33
36
  stateManager.setRenderableItems([]);
34
37
  const claimInteractiveScreen = () => {
38
+ // Claimed exactly once per session; the guard is a safety net in case a
39
+ // future caller re-claims.
40
+ /* v8 ignore start */
35
41
  if (ownsAlternateScreen)
36
42
  return;
37
- index_1.ConsoleUtils.clearProgress();
38
- index_1.CursorUtils.enterAlternateScreen();
39
- index_1.CursorUtils.clearScreen();
43
+ /* v8 ignore stop */
44
+ terminal_1.ConsoleUtils.clearProgress();
45
+ terminal_1.CursorUtils.enterAlternateScreen();
46
+ terminal_1.CursorUtils.clearScreen();
40
47
  ownsAlternateScreen = true;
41
48
  };
42
49
  const releaseInteractiveScreen = () => {
43
50
  if (!ownsAlternateScreen)
44
51
  return;
45
- index_1.CursorUtils.exitAlternateScreen();
52
+ terminal_1.CursorUtils.exitAlternateScreen();
46
53
  ownsAlternateScreen = false;
47
54
  };
55
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: matches ANSI escape sequences by design
48
56
  const resetAnsiPattern = /\x1b\[(?:0|49)m/g;
49
57
  const packageListRenderOptions = {
50
58
  showPeerDependencyVulnerabilities: options.showPeerDependencyVulnerabilities,
@@ -62,9 +70,9 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
62
70
  closeHelp: key('? / Esc ') + hint('Close'),
63
71
  };
64
72
  const buildModalHeaderLines = (shortcutLabel) => [
65
- ' ' + chalk_1.default.bold('🚀 ') + (0, themes_colors_1.coloredInupLogo)(),
73
+ ` ${chalk_1.default.bold('🚀 ')}${(0, themes_colors_1.coloredInupLogo)()}`,
66
74
  '',
67
- ' ' + shortcutLabel,
75
+ ` ${shortcutLabel}`,
68
76
  '',
69
77
  ];
70
78
  const buildRemainingViewport = (terminalWidth, terminalHeight, usedLines) => {
@@ -74,8 +82,12 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
74
82
  };
75
83
  const applyBackgroundToLine = (line, bgCode) => `${bgCode}${line.replace(resetAnsiPattern, (match) => `${match}${bgCode}`)}${(0, themes_colors_1.getTerminalResetCode)()}`;
76
84
  const writeFrame = (lines, bgCode) => {
85
+ // Viewports are always padded to the terminal height, so an empty frame
86
+ // cannot occur today; guard kept so a future caller cannot emit garbage.
87
+ /* v8 ignore start */
77
88
  if (lines.length === 0)
78
89
  return;
90
+ /* v8 ignore stop */
79
91
  process.stdout.write(lines.map((line) => applyBackgroundToLine(line, bgCode)).join('\n'));
80
92
  };
81
93
  const renderViewport = (lines, terminalWidth, terminalHeight, bgCode) => {
@@ -89,8 +101,8 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
89
101
  const viewportLineCount = buildModalHeaderLines(shortcutLabel).length + modalLines.length;
90
102
  const shouldClearBeforeRender = previousViewportMode !== mode || previousModalViewportLineCount !== viewportLineCount;
91
103
  if (shouldClearBeforeRender) {
92
- index_1.CursorUtils.clearScreen();
93
- index_1.CursorUtils.hide();
104
+ terminal_1.CursorUtils.clearScreen();
105
+ terminal_1.CursorUtils.hide();
94
106
  }
95
107
  renderViewport([...buildModalHeaderLines(shortcutLabel), ...modalLines], terminalWidth, terminalHeight, bgCode);
96
108
  previousViewportMode = mode;
@@ -104,11 +116,11 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
104
116
  const bgCode = (0, themes_colors_1.getTerminalBgColorCode)();
105
117
  process.stdout.write(bgCode);
106
118
  if (uiState.forceFullRender) {
107
- index_1.CursorUtils.clearScreen();
108
- index_1.CursorUtils.hide();
119
+ terminal_1.CursorUtils.clearScreen();
120
+ terminal_1.CursorUtils.hide();
109
121
  }
110
122
  else {
111
- index_1.CursorUtils.moveToHome();
123
+ terminal_1.CursorUtils.moveToHome();
112
124
  }
113
125
  if (uiState.showThemeModal) {
114
126
  const terminalWidth = process.stdout.columns || 80;
@@ -135,7 +147,7 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
135
147
  const terminalWidth = process.stdout.columns || 80;
136
148
  const terminalHeight = getTerminalHeight();
137
149
  const snapshot = (0, debug_1.getPerformanceTracker)().snapshot();
138
- const result = (0, debug_1.renderPerformanceModal)(snapshot, terminalWidth, Math.max(8, terminalHeight - 4), uiState.debugModalScrollOffset);
150
+ const result = (0, performance_modal_1.renderPerformanceModal)(snapshot, terminalWidth, Math.max(8, terminalHeight - 4), uiState.debugModalScrollOffset);
139
151
  debugModalMaxScrollOffset = result.maxScrollOffset;
140
152
  stateManager.clampDebugModalScrollOffset(debugModalMaxScrollOffset);
141
153
  const debugHints = [
@@ -187,6 +199,9 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
187
199
  };
188
200
  // Safety net: restore terminal if the process exits without going through finalizeSelection.
189
201
  // Only synchronous writes work in an 'exit' handler, but that's all we need here.
202
+ // Coverage: the body only runs during a real process 'exit' event, which
203
+ // cannot be fired safely inside the test process.
204
+ /* v8 ignore start */
190
205
  const emergencyCleanup = () => {
191
206
  if (ownsAlternateScreen) {
192
207
  process.stdout.write(cursor_1.RAW_EXIT_ALT_SCREEN);
@@ -196,10 +211,11 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
196
211
  process.stdin.setRawMode(false);
197
212
  }
198
213
  };
214
+ /* v8 ignore stop */
199
215
  process.on('exit', emergencyCleanup);
200
216
  let cleanupInteractiveSession = () => {
201
217
  process.stdout.write((0, themes_colors_1.getTerminalResetCode)());
202
- index_1.CursorUtils.show();
218
+ terminal_1.CursorUtils.show();
203
219
  process.stdin.off('keypress', keypressHandler);
204
220
  process.stdin.pause();
205
221
  process.off('SIGWINCH', handleResize);
@@ -209,7 +225,7 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
209
225
  onRefreshViewReady?.(undefined);
210
226
  packageInfoModalController.cancel();
211
227
  // Remember the view filters for next launch (best-effort, never throws).
212
- config_1.configManager.setFilters(stateManager.getFilterSnapshot());
228
+ user_config_1.configManager.setFilters(stateManager.getFilterSnapshot());
213
229
  releaseInteractiveScreen();
214
230
  cleanupInteractiveSession();
215
231
  process.off('exit', emergencyCleanup);
@@ -221,7 +237,7 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
221
237
  const handleCancel = () => {
222
238
  finalizeSelection(states.map((s) => ({ ...s, selectedOption: 'none' })));
223
239
  };
224
- const inputHandler = new index_1.InputHandler(stateManager, (action) => (0, action_dispatcher_1.dispatchAction)(action, {
240
+ const inputHandler = new input_handler_1.InputHandler(stateManager, (action) => (0, action_dispatcher_1.dispatchAction)(action, {
225
241
  stateManager,
226
242
  states,
227
243
  vulnerabilityDisplayOptions,
@@ -249,25 +265,30 @@ async function runInteractiveSession(selectionStates, packageManager, renderer,
249
265
  renderInterface();
250
266
  }
251
267
  });
252
- const keypressSession = index_1.TerminalInput.startKeypressSession(keypressHandler);
268
+ const keypressSession = terminal_1.TerminalInput.startKeypressSession(keypressHandler);
253
269
  const previousCleanup = cleanupInteractiveSession;
254
270
  cleanupInteractiveSession = () => {
255
271
  keypressSession.close();
256
272
  previousCleanup();
257
273
  };
258
274
  process.on('SIGWINCH', handleResize);
275
+ // The state manager was constructed with getTerminalHeight() in this same
276
+ // tick, so the height cannot have changed yet; kept as a safety net for a
277
+ // future async gap between construction and startup.
278
+ /* v8 ignore start */
259
279
  const currentHeight = getTerminalHeight();
260
280
  if (stateManager.updateTerminalHeight(currentHeight)) {
261
281
  const initialFiltered = stateManager.getFilteredStates(states, vulnerabilityDisplayOptions);
262
282
  stateManager.resetForResize(initialFiltered.length);
263
283
  }
284
+ /* v8 ignore stop */
264
285
  renderInterface();
265
286
  vulnerabilityAuditController.enqueueStates(states, () => {
266
287
  if (!isResolved)
267
288
  renderInterface();
268
289
  });
269
290
  }
270
- catch (error) {
291
+ catch {
271
292
  onRefreshViewReady?.(undefined);
272
293
  process.off('exit', emergencyCleanup);
273
294
  releaseInteractiveScreen();
@@ -33,25 +33,36 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.selectionKey = selectionKey;
36
37
  exports.deduplicatePackages = deduplicatePackages;
37
38
  exports.createSelectionStates = createSelectionStates;
38
39
  exports.createPendingSelectionStates = createPendingSelectionStates;
39
40
  exports.createUpgradeChoices = createUpgradeChoices;
40
41
  const semver = __importStar(require("semver"));
41
- const utils_1 = require("../utils");
42
+ const versions_1 = require("../../../shared/versions");
43
+ /**
44
+ * Identity of a selectable row. Catalog entries carry the catalog name so a
45
+ * pnpm catalog entry never merges with a direct dependency that happens to have
46
+ * the same name/range/type — they are written to different files.
47
+ */
48
+ function selectionKey(name, versionSpecifier, type, catalog) {
49
+ const base = `${name}@${versionSpecifier}@${type}`;
50
+ return catalog ? `${base}@catalog:${catalog}` : base;
51
+ }
42
52
  function deduplicatePackages(packages) {
43
53
  const uniquePackages = new Map();
44
54
  for (const pkg of packages) {
45
- const key = `${pkg.name}@${pkg.currentVersion}@${pkg.type}`;
46
- if (!uniquePackages.has(key)) {
55
+ const key = selectionKey(pkg.name, pkg.currentVersion, pkg.type, pkg.catalog);
56
+ const existing = uniquePackages.get(key);
57
+ if (existing) {
58
+ existing.packageJsonPaths.add(pkg.packageJsonPath);
59
+ }
60
+ else {
47
61
  uniquePackages.set(key, {
48
62
  pkg,
49
63
  packageJsonPaths: new Set([pkg.packageJsonPath]),
50
64
  });
51
65
  }
52
- else {
53
- uniquePackages.get(key).packageJsonPaths.add(pkg.packageJsonPath);
54
- }
55
66
  }
56
67
  return new Map(Array.from(uniquePackages.entries()).sort(([, a], [, b]) => {
57
68
  const aIsScoped = a.pkg.name.startsWith('@');
@@ -70,7 +81,7 @@ function createSelectionStates(packages, getCachedSummary, previousSelections, i
70
81
  const currentClean = semver.coerce(pkg.currentVersion)?.version || pkg.currentVersion;
71
82
  const rangeClean = semver.coerce(pkg.rangeVersion)?.version || pkg.rangeVersion;
72
83
  const latestClean = semver.coerce(pkg.latestVersion)?.version || pkg.latestVersion;
73
- const key = `${pkg.name}@${pkg.currentVersion}@${pkg.type}`;
84
+ const key = selectionKey(pkg.name, pkg.currentVersion, pkg.type, pkg.catalog);
74
85
  const previousSelection = previousSelections?.get(key) || 'none';
75
86
  return {
76
87
  name: pkg.name,
@@ -85,6 +96,9 @@ function createSelectionStates(packages, getCachedSummary, previousSelections, i
85
96
  hasRangeUpdate: pkg.hasRangeUpdate,
86
97
  hasMajorUpdate: pkg.hasMajorUpdate,
87
98
  type: pkg.type,
99
+ catalog: pkg.catalog,
100
+ catalogEntries: pkg.catalogEntries,
101
+ catalogReferencedBy: pkg.catalogReferencedBy,
88
102
  deprecated: pkg.deprecated,
89
103
  enginesNode: pkg.enginesNode,
90
104
  vulnerability: getCachedSummary(pkg.name, pkg.currentVersion, pkg.type),
@@ -103,7 +117,7 @@ function createPendingSelectionStates(packages, getCachedSummary, previousSelect
103
117
  })));
104
118
  return Array.from(uniquePackages.values()).map(({ pkg, packageJsonPaths }) => {
105
119
  const currentClean = semver.coerce(pkg.currentVersion)?.version || pkg.currentVersion;
106
- const key = `${pkg.name}@${pkg.currentVersion}@${pkg.type}`;
120
+ const key = selectionKey(pkg.name, pkg.currentVersion, pkg.type, pkg.catalog);
107
121
  const previousSelection = previousSelections?.get(key) || 'none';
108
122
  return {
109
123
  name: pkg.name,
@@ -118,6 +132,7 @@ function createPendingSelectionStates(packages, getCachedSummary, previousSelect
118
132
  hasRangeUpdate: false,
119
133
  hasMajorUpdate: false,
120
134
  type: pkg.type,
135
+ catalog: pkg.catalog,
121
136
  vulnerability: getCachedSummary(pkg.name, pkg.currentVersion, pkg.type),
122
137
  };
123
138
  });
@@ -131,7 +146,7 @@ function createUpgradeChoices(selectedStates, saveExact = false) {
131
146
  // Preserve the original range prefix (^/~) by default; --save-exact writes the bare version.
132
147
  const targetVersionWithPrefix = saveExact
133
148
  ? targetVersion
134
- : (0, utils_1.applyVersionPrefix)(state.currentVersionSpecifier, targetVersion);
149
+ : (0, versions_1.applyVersionPrefix)(state.currentVersionSpecifier, targetVersion);
135
150
  const pathsToUpdate = state.packageJsonPaths || [state.packageJsonPath];
136
151
  pathsToUpdate.forEach((packageJsonPath) => {
137
152
  choices.push({
@@ -141,6 +156,7 @@ function createUpgradeChoices(selectedStates, saveExact = false) {
141
156
  upgradeType: state.selectedOption,
142
157
  targetVersion: targetVersionWithPrefix,
143
158
  currentVersionSpecifier: state.currentVersionSpecifier,
159
+ catalog: state.catalog,
144
160
  });
145
161
  });
146
162
  });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FilterManager = void 0;
4
- const vulnerability_1 = require("../presenters/vulnerability");
4
+ const audit_1 = require("../../audit");
5
5
  class FilterManager {
6
6
  state;
7
7
  constructor(initial) {
@@ -92,7 +92,7 @@ class FilterManager {
92
92
  if (activeTypes.length === 0)
93
93
  return 'None';
94
94
  const label = activeTypes.join(', ');
95
- return this.state.showOnlyVulnerable ? label + ' (vulnerable only)' : label;
95
+ return this.state.showOnlyVulnerable ? `${label} (vulnerable only)` : label;
96
96
  }
97
97
  getFilteredStates(allStates, options = {}) {
98
98
  let filtered = allStates;
@@ -118,7 +118,7 @@ class FilterManager {
118
118
  });
119
119
  // Apply vulnerability filter
120
120
  if (this.state.showOnlyVulnerable) {
121
- filtered = filtered.filter((state) => (0, vulnerability_1.shouldDisplayVulnerabilityForDependency)(state.type, options) &&
121
+ filtered = filtered.filter((state) => (0, audit_1.shouldDisplayVulnerabilityForDependency)(state.type, options) &&
122
122
  !!state.vulnerability &&
123
123
  state.vulnerability.count > 0);
124
124
  }
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FilterManager = exports.ModalManager = exports.NavigationManager = exports.StateManager = void 0;
4
- var state_manager_1 = require("./state-manager");
5
- Object.defineProperty(exports, "StateManager", { enumerable: true, get: function () { return state_manager_1.StateManager; } });
6
- var navigation_manager_1 = require("./navigation-manager");
7
- Object.defineProperty(exports, "NavigationManager", { enumerable: true, get: function () { return navigation_manager_1.NavigationManager; } });
8
- var modal_manager_1 = require("./modal-manager");
9
- Object.defineProperty(exports, "ModalManager", { enumerable: true, get: function () { return modal_manager_1.ModalManager; } });
3
+ exports.StateManager = exports.NavigationManager = exports.ModalManager = exports.FilterManager = void 0;
10
4
  var filter_manager_1 = require("./filter-manager");
11
5
  Object.defineProperty(exports, "FilterManager", { enumerable: true, get: function () { return filter_manager_1.FilterManager; } });
6
+ var modal_manager_1 = require("./modal-manager");
7
+ Object.defineProperty(exports, "ModalManager", { enumerable: true, get: function () { return modal_manager_1.ModalManager; } });
8
+ var navigation_manager_1 = require("./navigation-manager");
9
+ Object.defineProperty(exports, "NavigationManager", { enumerable: true, get: function () { return navigation_manager_1.NavigationManager; } });
10
+ var state_manager_1 = require("./state-manager");
11
+ Object.defineProperty(exports, "StateManager", { enumerable: true, get: function () { return state_manager_1.StateManager; } });
12
12
  //# sourceMappingURL=index.js.map