pcu 1.1.9 → 1.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pcu",
3
- "version": "1.1.9",
3
+ "version": "1.2.0",
4
4
  "description": "CLI application for pnpm-catalog-updates",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -32,24 +32,22 @@
32
32
  "clean": "rimraf dist bin/*.js"
33
33
  },
34
34
  "dependencies": {
35
- "@clack/prompts": "catalog:",
36
- "@inquirer/core": "catalog:",
37
- "@pcu/core": "workspace:*",
38
- "@pcu/utils": "workspace:*",
39
- "boxen": "catalog:",
40
- "chalk": "catalog:",
41
- "cli-table3": "catalog:",
42
- "commander": "catalog:",
43
- "fs-extra": "catalog:",
44
- "glob": "catalog:",
45
- "inquirer": "catalog:",
46
- "lodash": "catalog:",
47
- "npm-registry-fetch": "catalog:",
48
- "ora": "catalog:",
49
- "pacote": "catalog:",
50
- "rxjs": "catalog:",
51
- "semver": "catalog:",
52
- "yaml": "catalog:"
35
+ "@clack/prompts": "^1.1.0",
36
+ "@inquirer/core": "^11.1.5",
37
+ "boxen": "^8.0.1",
38
+ "chalk": "^5.6.2",
39
+ "cli-table3": "^0.6.5",
40
+ "commander": "^14.0.3",
41
+ "fs-extra": "^11.3.4",
42
+ "glob": "^13.0.6",
43
+ "inquirer": "^13.3.0",
44
+ "lodash": "^4.17.23",
45
+ "npm-registry-fetch": "^19.1.1",
46
+ "ora": "^9.3.0",
47
+ "pacote": "^21.5.0",
48
+ "rxjs": "^7.8.2",
49
+ "semver": "^7.7.4",
50
+ "yaml": "^2.8.2"
53
51
  },
54
52
  "devDependencies": {
55
53
  "@types/inquirer": "catalog:",
@@ -78,9 +76,11 @@
78
76
  "homepage": "https://pcu-cli.dev",
79
77
  "repository": {
80
78
  "type": "git",
81
- "url": "https://github.com/houko/pnpm-catalog-updates.git",
79
+ "url": "https://github.com/yldm-tech/pnpm-catalog-updates.git",
82
80
  "directory": "apps/cli"
83
81
  },
84
- "peerDependencies": {},
82
+ "peerDependencies": {
83
+ "pnpm": ">=9"
84
+ },
85
85
  "optionalDependencies": {}
86
86
  }
@@ -61,6 +61,7 @@ export interface GlobalOptions {
61
61
  workspace?: string
62
62
  verbose?: boolean
63
63
  noColor?: boolean
64
+ ci?: boolean
64
65
  }
65
66
 
66
67
  /**
@@ -235,7 +236,10 @@ function createCommandAction<TOptions>(
235
236
 
236
237
  // Handle interactive mode if collector is provided
237
238
  if (config.interactiveCollector) {
238
- const isInteractive = (options as Record<string, unknown>).interactive === true
239
+ const isCiMode = (globalOptions as Record<string, unknown>).ci === true
240
+ const isInteractive = isCiMode
241
+ ? false
242
+ : (options as Record<string, unknown>).interactive === true
239
243
  const noMeaningfulOptions = !hasProvidedOptions(
240
244
  options as Record<string, unknown>,
241
245
  command,
@@ -277,6 +281,21 @@ export function registerCommands(
277
281
  serviceFactory: LazyServiceFactory,
278
282
  packageJson: { version: string }
279
283
  ): void {
284
+ // Global CI mode option - enables non-interactive mode with sensible defaults
285
+ program
286
+ .option(
287
+ '--ci',
288
+ 'Enable CI mode for non-interactive execution. Skips all prompts and uses sensible defaults.',
289
+ false
290
+ )
291
+ .hook('preAction', (thisCommand) => {
292
+ const opts = thisCommand.opts()
293
+ if (opts.ci) {
294
+ // Force no color in CI mode for better compatibility
295
+ opts.noColor = true
296
+ }
297
+ })
298
+
280
299
  // Check command
281
300
  program
282
301
  .command('check')
@@ -764,7 +783,7 @@ ${t('cli.help.tipLabel')} ${t('cli.help.tipContent', { locale: I18n.getLocale()
764
783
  cliOutput.print(chalk.gray(t('command.selfUpdate.restartHint')))
765
784
  } else {
766
785
  cliOutput.error(chalk.red(t('command.selfUpdate.failed')))
767
- cliOutput.print(chalk.gray('You can manually update with: npm install -g pcu@latest'))
786
+ cliOutput.print(chalk.gray(t('command.selfUpdate.manualHint')))
768
787
  exitProcess(1)
769
788
  }
770
789
  } catch (error) {
@@ -772,7 +791,7 @@ ${t('cli.help.tipLabel')} ${t('cli.help.tipContent', { locale: I18n.getLocale()
772
791
  if (globalOptions.verbose) {
773
792
  cliOutput.error(error)
774
793
  }
775
- cliOutput.print(chalk.gray('You can manually update with: npm install -g pcu@latest'))
794
+ cliOutput.print(chalk.gray(t('command.selfUpdate.manualHint')))
776
795
  exitProcess(1)
777
796
  }
778
797
  }
@@ -339,7 +339,9 @@ catalogs:
339
339
  lines.push('')
340
340
  lines.push(StyledText.muted(t('command.init.step5')))
341
341
  lines.push(StyledText.muted(' https://pnpm.io/workspaces'))
342
- lines.push(StyledText.muted(' https://github.com/houko/pnpm-catalog-updates#configuration'))
342
+ lines.push(
343
+ StyledText.muted(' https://github.com/yldm-tech/pnpm-catalog-updates#configuration')
344
+ )
343
345
 
344
346
  cliOutput.print(lines.join('\n'))
345
347
  }
package/src/cli/index.ts CHANGED
@@ -118,35 +118,54 @@ async function handleVersionFlag(
118
118
  ): Promise<void> {
119
119
  if (!args.includes('--version')) return
120
120
 
121
- cliOutput.print(getPackageJson().version)
121
+ const pkg = getPackageJson()
122
+ const version = pkg.version
122
123
 
123
124
  // Check for updates if not in CI and enabled in config
124
125
  if (VersionChecker.shouldCheckForUpdates() && config.advanced?.checkForUpdates !== false) {
125
126
  try {
126
- cliOutput.print(chalk.gray(t('cli.checkingUpdates')))
127
- const versionResult = await VersionChecker.checkVersion(getPackageJson().version, {
127
+ // Show version with checking status on same line
128
+ process.stdout.write(
129
+ `${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)} ${chalk.gray(t('cli.checkingUpdates'))}`
130
+ )
131
+
132
+ const versionResult = await VersionChecker.checkVersion(version, {
128
133
  skipPrompt: false,
129
- timeout: 5000, // Longer timeout for explicit version check
134
+ timeout: 5000,
130
135
  })
131
136
 
132
- if (versionResult.shouldPrompt) {
137
+ // Clear the checking message and show final result
138
+ process.stdout.write('\r\x1b[K') // Clear current line
139
+
140
+ if (versionResult.shouldPrompt && versionResult.latestVersion) {
141
+ cliOutput.print(
142
+ `${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)} ${chalk.yellow(`-> v${versionResult.latestVersion} ${t('cli.available')}`)}`
143
+ )
133
144
  const didUpdate = await VersionChecker.promptAndUpdate(versionResult)
134
145
  if (didUpdate) {
135
146
  cliOutput.print(chalk.blue(t('cli.runAgain')))
136
147
  exitWithCleanup(0)
137
148
  }
138
- } else if (versionResult.isLatest) {
139
- cliOutput.print(chalk.green(t('cli.latestVersion')))
149
+ } else {
150
+ cliOutput.print(
151
+ `${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)} ${chalk.green(t('cli.latestVersion'))}`
152
+ )
140
153
  }
141
154
  } catch (error) {
142
- // Silently fail update check for version command
155
+ // Clear line and show version without update status
156
+ process.stdout.write('\r\x1b[K')
157
+ cliOutput.print(`${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)}`)
158
+
143
159
  logger.debug('Version flag update check failed', {
144
160
  error: error instanceof Error ? error.message : error,
145
161
  })
146
162
  if (args.includes('-v') || args.includes('--verbose')) {
147
- cliOutput.warn(chalk.yellow(`⚠️ ${t('cli.couldNotCheckUpdates')}`), error)
163
+ cliOutput.warn(chalk.yellow(` ${t('cli.couldNotCheckUpdates')}`), error)
148
164
  }
149
165
  }
166
+ } else {
167
+ // No update check, just show version
168
+ cliOutput.print(`${chalk.cyan('pcu')} ${chalk.bold(`v${version}`)}`)
150
169
  }
151
170
 
152
171
  exitWithCleanup(0)
@@ -272,7 +272,7 @@ export class InteractiveOptionsCollector {
272
272
  message: t('interactive.analyze.packageName'),
273
273
  placeholder: 'lodash, react, ...',
274
274
  validate: (value) => {
275
- if (!value.trim()) return t('interactive.analyze.packageNameRequired')
275
+ if (!value?.trim()) return t('interactive.analyze.packageNameRequired')
276
276
  return undefined
277
277
  },
278
278
  })
@@ -103,7 +103,7 @@ export class InteractivePrompts {
103
103
 
104
104
  const answers = await inquirer.prompt([
105
105
  {
106
- type: 'list',
106
+ type: 'select',
107
107
  name: 'catalog',
108
108
  message: StyledText.iconCatalog(t('prompt.selectCatalog')),
109
109
  choices,
@@ -128,7 +128,7 @@ export class InteractivePrompts {
128
128
 
129
129
  const answers = await inquirer.prompt([
130
130
  {
131
- type: 'list',
131
+ type: 'select',
132
132
  name: 'strategy',
133
133
  message: StyledText.iconUpdate(t('prompt.selectUpdateStrategy')),
134
134
  choices: strategies,
@@ -168,7 +168,7 @@ export class InteractivePrompts {
168
168
  ): Promise<string> {
169
169
  const answers = await inquirer.prompt([
170
170
  {
171
- type: 'list',
171
+ type: 'select',
172
172
  name: 'package',
173
173
  message,
174
174
  choices: packages.map((pkg) => ({ name: pkg, value: pkg })),
@@ -191,7 +191,7 @@ export class InteractivePrompts {
191
191
 
192
192
  const answers = await inquirer.prompt([
193
193
  {
194
- type: 'list',
194
+ type: 'select',
195
195
  name: 'path',
196
196
  message: t('prompt.selectWorkspace'),
197
197
  choices,
@@ -221,7 +221,7 @@ export class InteractivePrompts {
221
221
 
222
222
  const answers = await inquirer.prompt([
223
223
  {
224
- type: 'list',
224
+ type: 'select',
225
225
  name: 'selected',
226
226
  message: t('prompt.browsePath', { path: currentPath }),
227
227
  choices,
@@ -271,7 +271,7 @@ export class InteractivePrompts {
271
271
  */
272
272
  async selectTheme(): Promise<string | null> {
273
273
  const answers = await inquirer.prompt({
274
- type: 'list',
274
+ type: 'select',
275
275
  name: 'theme',
276
276
  message: t('prompt.selectTheme'),
277
277
  choices: [
@@ -294,7 +294,7 @@ export class InteractivePrompts {
294
294
  cliOutput.print(chalk.bold.blue(`\n${t('prompt.configWizard')}\n`))
295
295
 
296
296
  const themeAnswer = await inquirer.prompt({
297
- type: 'list',
297
+ type: 'select',
298
298
  name: 'theme',
299
299
  message: t('prompt.selectTheme'),
300
300
  choices: [
@@ -321,7 +321,7 @@ export class InteractivePrompts {
321
321
  })
322
322
 
323
323
  const strategyAnswer = await inquirer.prompt({
324
- type: 'list',
324
+ type: 'select',
325
325
  name: 'updateStrategy',
326
326
  message: t('prompt.defaultStrategy'),
327
327
  choices: [
@@ -398,7 +398,7 @@ export class InteractivePrompts {
398
398
 
399
399
  const answers = await inquirer.prompt([
400
400
  {
401
- type: 'list',
401
+ type: 'select',
402
402
  name: 'action',
403
403
  message: StyledText.iconError(t('prompt.errorMessage', { error })),
404
404
  choices: options,
@@ -544,7 +544,7 @@ export class InteractiveCommandBuilder {
544
544
  }> {
545
545
  const baseCommand = await inquirer.prompt([
546
546
  {
547
- type: 'list',
547
+ type: 'select',
548
548
  name: 'command',
549
549
  message: t('prompt.whatToDo'),
550
550
  choices: [
@@ -561,7 +561,7 @@ export class InteractiveCommandBuilder {
561
561
  // Common options
562
562
  const common = await inquirer.prompt([
563
563
  {
564
- type: 'list',
564
+ type: 'select',
565
565
  name: 'format',
566
566
  message: t('prompt.outputFormat'),
567
567
  choices: [