package-installer-cli 1.2.0 → 1.3.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.
@@ -2,41 +2,49 @@
2
2
  * Upgrade CLI command - Updates Package Installer CLI to the latest version
3
3
  */
4
4
  import chalk from 'chalk';
5
- import gradient from 'gradient-string';
6
5
  import boxen from 'boxen';
7
6
  import ora from 'ora';
8
7
  import inquirer from 'inquirer';
9
8
  import { exec } from 'child_process';
10
9
  import { promisify } from 'util';
11
10
  import semver from 'semver';
11
+ import { createStandardHelp } from '../utils/helpFormatter.js';
12
12
  const execAsync = promisify(exec);
13
13
  /**
14
14
  * Display help for upgrade-cli command
15
15
  */
16
16
  export function showUpgradeHelp() {
17
- const piGradient = gradient(['#00c6ff', '#0072ff']);
18
- const headerGradient = gradient(['#4facfe', '#00f2fe']);
19
- console.log('\n' + boxen(headerGradient('🚀 Package Installer CLI - Upgrade Command Help') + '\n\n' +
20
- chalk.white('Update Package Installer CLI to the latest version with intelligent upgrade management.') + '\n' +
21
- chalk.white('Includes breaking change detection and version compatibility checks!') + '\n\n' +
22
- chalk.cyan('Usage:') + '\n' +
23
- chalk.white(` ${piGradient('pi')} ${chalk.hex('#10ac84')('upgrade-cli')}`) + '\n\n' +
24
- chalk.cyan('Options:') + '\n' +
25
- chalk.gray(' -h, --help Display help for this command') + '\n\n' +
26
- chalk.cyan('Examples:') + '\n' +
27
- chalk.gray(` ${piGradient('pi')} ${chalk.hex('#10ac84')('upgrade-cli')} # Smart upgrade with breaking change detection`) + '\n' +
28
- chalk.gray(` ${piGradient('pi')} ${chalk.hex('#10ac84')('upgrade-cli')} ${chalk.hex('#ff6b6b')('--help')} # Show this help message`) + '\n\n' +
29
- chalk.hex('#00d2d3')('💡 Enhanced Features:') + '\n' +
30
- chalk.hex('#95afc0')(' • Semantic version analysis and breaking change detection') + '\n' +
31
- chalk.hex('#95afc0')(' • Interactive confirmation for major version upgrades') + '\n' +
32
- chalk.hex('#95afc0')(' • Automatic @latest tag installation for maximum compatibility') + '\n' +
33
- chalk.hex('#95afc0')(' Package size and release date information') + '\n' +
34
- chalk.hex('#95afc0')(' Comprehensive upgrade verification and rollback guidance'), {
35
- padding: 1,
36
- borderStyle: 'round',
37
- borderColor: 'cyan',
38
- backgroundColor: '#0a0a0a'
39
- }));
17
+ const helpConfig = {
18
+ commandName: 'upgrade-cli',
19
+ emoji: '🚀',
20
+ description: 'Update Package Installer CLI to the latest version with intelligent upgrade management.\nIncludes breaking change detection and version compatibility checks!',
21
+ usage: ['pi upgrade-cli'],
22
+ options: [
23
+ { flag: '-h, --help', description: 'Display help for this command' }
24
+ ],
25
+ examples: [
26
+ { command: 'pi upgrade-cli', description: 'Smart upgrade with breaking change detection' },
27
+ { command: 'pi upgrade-cli --help', description: 'Show this help message' }
28
+ ],
29
+ additionalSections: [
30
+ {
31
+ title: '💡 Enhanced Features',
32
+ items: [
33
+ '• Semantic version analysis and breaking change detection',
34
+ '• Interactive confirmation for major version upgrades',
35
+ '• Automatic @latest tag installation for maximum compatibility',
36
+ '• Package size and release date information',
37
+ '• Comprehensive upgrade verification and rollback guidance'
38
+ ]
39
+ }
40
+ ],
41
+ tips: [
42
+ 'CLI will prompt for confirmation on major version upgrades',
43
+ 'Breaking changes are automatically detected and explained',
44
+ 'Use npm install -g package-installer-cli@<version> to rollback'
45
+ ]
46
+ };
47
+ createStandardHelp(helpConfig);
40
48
  }
41
49
  /**
42
50
  * Get current CLI version
data/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import { addCommand, showAddHelp } from './commands/add.js';
14
14
  import { showUpgradeHelp, upgradeCliCommand } from './commands/upgrade-cli.js';
15
15
  import { updateCommand, showUpdateHelp } from './commands/update.js';
16
16
  import { analyzeCommand, showAnalyzeHelp } from './commands/analyze.js';
17
- import { deployCommand } from './commands/deploy.js';
17
+ import { deployCommand, showDeployHelp } from './commands/deploy.js';
18
18
  import { cleanCommand, showCleanHelp } from './commands/clean.js';
19
19
  import { environmentCommand, showEnvironmentHelp } from './commands/env.js';
20
20
  import { doctorCommand, showDoctorHelp } from './commands/doctor.js';
@@ -93,12 +93,18 @@ program
93
93
  .command('check')
94
94
  .description(chalk.hex('#f39c12')('🔍 ') + chalk.hex('#ffa500')('Check package versions and get update suggestions'))
95
95
  .argument('[package-name]', chalk.hex('#95afc0')('Specific package to check (optional)'))
96
+ .option('-v, --verbose', 'Show detailed information for all packages')
97
+ .option('-h, --help', 'Display help for this command')
96
98
  .on('--help', () => {
97
99
  showCheckHelp();
98
100
  })
99
- .action(async (packageName) => {
101
+ .action(async (packageName, options) => {
100
102
  try {
101
- await checkCommand(packageName);
103
+ if (options.help) {
104
+ showCheckHelp();
105
+ return;
106
+ }
107
+ await checkCommand(packageName, options);
102
108
  }
103
109
  catch (error) {
104
110
  handleCommandError('check packages', error);
@@ -110,10 +116,21 @@ program
110
116
  .description(chalk.hex('#00d2d3')('📥 ') + chalk.hex('#00cec9')('Clone repositories from GitHub, GitLab, BitBucket & SourceHut'))
111
117
  .argument('[user/repo]', chalk.hex('#95afc0')('Repository in format "user/repo" or "provider:user/repo"'))
112
118
  .argument('[project-name]', chalk.hex('#95afc0')('Custom project name (defaults to repo name)'))
119
+ .option('-h, --help', 'Display help for this command')
120
+ .option('--offline', 'Use cached templates if available')
121
+ .option('--no-deps', 'Skip dependency installation')
122
+ .option('--no-git', 'Skip git initialization')
123
+ .option('--shallow', 'Create shallow clone (faster)')
124
+ .option('--branch <name>', 'Clone specific branch')
125
+ .option('--template', 'Treat as template repository')
113
126
  .on('--help', () => {
114
127
  showCloneHelp();
115
128
  })
116
- .action(async (userRepo, projectName) => {
129
+ .action(async (userRepo, projectName, options) => {
130
+ if (options.help) {
131
+ showCloneHelp();
132
+ return;
133
+ }
117
134
  if (!userRepo) {
118
135
  console.log('\n' + chalk.hex('#ff4757')('❌ Error: Repository is required'));
119
136
  console.log(chalk.hex('#95afc0')(' Format: user/repo or provider:user/repo'));
@@ -124,7 +141,7 @@ program
124
141
  return;
125
142
  }
126
143
  try {
127
- await cloneRepo(userRepo, projectName);
144
+ await cloneRepo(userRepo, projectName, options);
128
145
  }
129
146
  catch (error) {
130
147
  handleCommandError('clone repository', error);
@@ -167,13 +184,22 @@ program
167
184
  // ANALYZE COMMAND - Terminal dashboard with analytics
168
185
  program
169
186
  .command('analyze')
187
+ .alias('stats')
170
188
  .description(chalk.hex('#667eea')('📊 ') + chalk.hex('#4facfe')('Show CLI usage analytics and framework statistics'))
189
+ .option('--export', 'Export analytics data to JSON file')
190
+ .option('--reset', 'Reset analytics history')
191
+ .option('--detailed', 'Show detailed analytics breakdown')
192
+ .option('-h, --help', 'Show this help message')
171
193
  .on('--help', () => {
172
194
  showAnalyzeHelp();
173
195
  })
174
- .action(async () => {
196
+ .action(async (options) => {
175
197
  try {
176
- await analyzeCommand();
198
+ if (options.help) {
199
+ showAnalyzeHelp();
200
+ return;
201
+ }
202
+ await analyzeCommand(options);
177
203
  }
178
204
  catch (error) {
179
205
  handleCommandError('show analytics', error);
@@ -183,14 +209,16 @@ program
183
209
  program
184
210
  .command('update')
185
211
  .alias('u')
186
- .description(chalk.hex('#ff6b6b')('🔄 ') + chalk.hex('#fd79a8')('Update CLI, dependencies, and cache'))
212
+ .description(chalk.hex('#ff6b6b')('🔄 ') + chalk.hex('#fd79a8')('Update project dependencies with breaking change detection'))
213
+ .argument('[packages]', chalk.hex('#95afc0')('Comma-separated list of packages to update (optional)'))
214
+ .option('--latest', 'Update to latest versions (may include breaking changes)')
187
215
  .option('-h, --help', 'Show help for update command')
188
216
  .on('--help', () => {
189
217
  showUpdateHelp();
190
218
  })
191
- .action(async (options) => {
219
+ .action(async (packages, options) => {
192
220
  try {
193
- await updateCommand(options);
221
+ await updateCommand(packages, options);
194
222
  }
195
223
  catch (error) {
196
224
  handleCommandError('update', error);
@@ -204,15 +232,20 @@ program
204
232
  .option('--node-modules', 'Clean node_modules directories')
205
233
  .option('--build', 'Clean build/dist directories')
206
234
  .option('--cache', 'Clean package manager caches')
207
- .option('--logs', 'Clean log files')
208
- .option('--all', 'Clean everything (safe)')
235
+ .option('--logs', 'Clean log files and debug outputs')
236
+ .option('--all', 'Clean everything (safe operation)')
209
237
  .option('--deep', 'Deep clean (includes lock files)')
210
238
  .option('--dry-run', 'Preview what would be cleaned')
239
+ .option('-h, --help', 'Show help for clean command')
211
240
  .on("--help", () => {
212
241
  showCleanHelp();
213
242
  })
214
243
  .action(async (options) => {
215
244
  try {
245
+ if (options.help) {
246
+ showCleanHelp();
247
+ return;
248
+ }
216
249
  displayCommandBanner('clean', 'Clean development artifacts and caches');
217
250
  await cleanCommand(options);
218
251
  }
@@ -270,10 +303,20 @@ program
270
303
  .description(chalk.hex('#00d2d3')('🗄️ ') + chalk.hex('#0084ff')('Manage CLI cache system'))
271
304
  .argument('[subcommand]', 'Cache subcommand (stats, clear, info, optimize)')
272
305
  .argument('[type]', 'Type for clear command (projects, analysis, packages, templates, system, all)')
273
- .action(async (subcommand, type) => {
306
+ .option('--stats', 'Show cache statistics')
307
+ .option('--clear [type]', 'Clear cache (optionally specify type)')
308
+ .option('--info', 'Show cache configuration')
309
+ .option('--optimize', 'Optimize cache performance')
310
+ .option('--size', 'Show cache size information')
311
+ .option('-h, --help', 'Show help for cache command')
312
+ .on('--help', async () => {
313
+ const { showCacheHelp } = await import('./commands/cache.js');
314
+ showCacheHelp();
315
+ })
316
+ .action(async (subcommand, type, options) => {
274
317
  try {
275
318
  const { cacheCommand } = await import('./commands/cache.js');
276
- await cacheCommand(subcommand, type);
319
+ await cacheCommand(subcommand, type, options);
277
320
  }
278
321
  catch (error) {
279
322
  handleCommandError('cache', error);
@@ -284,7 +327,7 @@ program
284
327
  .command('deploy')
285
328
  .description(chalk.hex('#ff9a9e')('🚀 ') + chalk.hex('#fd79a8')('Deploy your project (Coming Soon)'))
286
329
  .on('--help', () => {
287
- // Help is handled in the command file
330
+ showDeployHelp();
288
331
  })
289
332
  .action(async () => {
290
333
  try {
data/dist/utils/banner.js CHANGED
@@ -66,7 +66,7 @@ export function displayCommandBanner(commandName, description) {
66
66
  const commandGradient = gradient(['#4facfe', '#00f2fe']);
67
67
  console.log('\n' + boxen(commandGradient(`🚀 ${commandName.toUpperCase()} COMMAND`) + '\n\n' +
68
68
  chalk.white(description) + '\n\n' +
69
- chalk.hex('#00d2d3')('💡 Package Installer CLI v3.2.0') + ' • ' +
69
+ chalk.hex('#00d2d3')(`💡 Package Installer CLI v${getPackageVersion()}`) + ' • ' +
70
70
  chalk.hex('#95afc0')('Fast • Smart • Feature-Rich'), {
71
71
  padding: 1,
72
72
  borderStyle: 'round',
@@ -1,77 +1,50 @@
1
1
  /**
2
2
  * Cache Manager - Centralized caching operations for Package Installer CLI
3
+ * Simplified version focusing on essential caching functionality only
3
4
  */
4
5
  import { cacheManager as cacheManagerInstance } from './cacheUtils.js';
5
6
  import fs from 'fs-extra';
6
7
  import path from 'path';
7
- import chalk from 'chalk';
8
8
  // Export the cache manager instance
9
9
  export const cacheManager = cacheManagerInstance;
10
10
  /**
11
11
  * Initialize cache system on CLI startup
12
12
  */
13
13
  export async function initializeCache() {
14
- await cacheManagerInstance.init();
15
- }
16
- /**
17
- * Get cached project
18
- */
19
- export async function getCachedProject(projectPath) {
20
14
  try {
21
- const cache = cacheManagerInstance.getCache();
22
- const cached = cache.projects.find((p) => p.path === projectPath);
23
- return cached || null;
15
+ await cacheManagerInstance.init();
24
16
  }
25
17
  catch (error) {
26
- return null;
18
+ // Silent fail - cache will work in memory mode
27
19
  }
28
20
  }
29
21
  /**
30
- * Cache project data (simplified)
22
+ * Get cached template files (simplified - returns null for now)
31
23
  */
32
- export async function cacheProjectData(projectPath, name, language, framework, dependencies, size) {
33
- try {
34
- // For now, just cache basic project info without complex dependencies
35
- console.log(chalk.gray(`📊 Caching project data for ${name}`));
36
- }
37
- catch (error) {
38
- console.warn('Failed to cache project data:', error);
39
- }
24
+ export async function getCachedTemplateFiles(templateName) {
25
+ // Simplified implementation - just return null for now
26
+ return null;
40
27
  }
41
28
  /**
42
- * Get cached template files (simplified)
29
+ * Cache template files (simplified - no-op for now)
43
30
  */
44
- export async function getCachedTemplateFiles(templateName) {
45
- try {
46
- const cache = cacheManagerInstance.getCache();
47
- const template = cache.templateFiles.find((t) => t.templateName === templateName);
48
- return template || null;
49
- }
50
- catch (error) {
51
- return null;
52
- }
31
+ export async function cacheTemplateFiles(templateName, templatePath, files) {
32
+ // Simplified implementation - no-op for now
33
+ // This reduces complexity and memory usage
53
34
  }
54
35
  /**
55
- * Cache template files (simplified)
36
+ * Update template usage statistics (simplified - no-op for now)
56
37
  */
57
- export async function cacheTemplateFiles(templateName, templatePath, files, size) {
58
- try {
59
- console.log(chalk.gray(`📊 Caching template files for ${templateName}`));
60
- }
61
- catch (error) {
62
- console.warn('Failed to cache template files:', error);
63
- }
38
+ export async function updateTemplateUsage(templateName, framework, language) {
39
+ // Simplified implementation - no-op for now
40
+ // This reduces complexity and memory usage
64
41
  }
65
42
  /**
66
- * Update template usage statistics (simplified)
43
+ * Cache project data (simplified - no-op for now)
67
44
  */
68
- export async function updateTemplateUsage(templateName, framework, language, features) {
69
- try {
70
- console.log(chalk.gray(`📊 Recording template usage: ${templateName}`));
71
- }
72
- catch (error) {
73
- console.warn('Failed to update template usage:', error);
74
- }
45
+ export async function cacheProjectData(projectPath, name, type) {
46
+ // Simplified implementation - no-op for now
47
+ // This reduces complexity and memory usage
75
48
  }
76
49
  /**
77
50
  * Get directory size utility function
@@ -80,18 +53,24 @@ export async function getDirectorySize(dirPath) {
80
53
  try {
81
54
  let totalSize = 0;
82
55
  async function calculateSize(currentPath) {
83
- const stats = await fs.stat(currentPath);
84
- if (stats.isFile()) {
85
- totalSize += stats.size;
86
- }
87
- else if (stats.isDirectory()) {
88
- const items = await fs.readdir(currentPath);
89
- for (const item of items) {
90
- if (!['node_modules', '.git', 'dist', 'build'].includes(item)) {
91
- await calculateSize(path.join(currentPath, item));
56
+ try {
57
+ const stats = await fs.stat(currentPath);
58
+ if (stats.isFile()) {
59
+ totalSize += stats.size;
60
+ }
61
+ else if (stats.isDirectory()) {
62
+ const items = await fs.readdir(currentPath);
63
+ for (const item of items) {
64
+ // Skip large directories to avoid performance issues
65
+ if (!['node_modules', '.git', 'dist', 'build', 'target', '.cache'].includes(item)) {
66
+ await calculateSize(path.join(currentPath, item));
67
+ }
92
68
  }
93
69
  }
94
70
  }
71
+ catch (error) {
72
+ // Skip files/directories that can't be accessed
73
+ }
95
74
  }
96
75
  await calculateSize(dirPath);
97
76
  return totalSize;
@@ -101,98 +80,52 @@ export async function getDirectorySize(dirPath) {
101
80
  }
102
81
  }
103
82
  /**
104
- * Read template files for caching
105
- */
106
- export async function readTemplateFiles(templatePath) {
107
- const files = {};
108
- async function readFiles(currentPath, relativePath = '') {
109
- try {
110
- const items = await fs.readdir(currentPath, { withFileTypes: true });
111
- for (const item of items) {
112
- const fullPath = path.join(currentPath, item.name);
113
- const relativeItemPath = path.join(relativePath, item.name);
114
- if (item.isFile()) {
115
- // Skip binary files and large files
116
- const stats = await fs.stat(fullPath);
117
- if (stats.size < 1024 * 1024) { // Skip files larger than 1MB
118
- const content = await fs.readFile(fullPath, 'utf-8').catch(() => null);
119
- if (content !== null) {
120
- files[relativeItemPath] = content;
121
- }
122
- }
123
- }
124
- else if (item.isDirectory() && !['node_modules', '.git', 'dist', 'build'].includes(item.name)) {
125
- await readFiles(fullPath, relativeItemPath);
126
- }
127
- }
128
- }
129
- catch (error) {
130
- // Skip directories that can't be read
131
- }
132
- }
133
- await readFiles(templatePath);
134
- return files;
135
- }
136
- /**
137
- * Create project from cached template
138
- */
139
- export async function createProjectFromCachedTemplate(projectName, cachedTemplate) {
140
- const projectPath = path.resolve(process.cwd(), projectName);
141
- // Create project directory
142
- await fs.ensureDir(projectPath);
143
- // Write cached files
144
- if (cachedTemplate.files) {
145
- for (const [filePath, content] of Object.entries(cachedTemplate.files)) {
146
- const fullPath = path.join(projectPath, filePath);
147
- await fs.ensureDir(path.dirname(fullPath));
148
- await fs.writeFile(fullPath, content);
149
- }
150
- }
151
- return projectPath;
152
- }
153
- /**
154
- * Get cache statistics
83
+ * Get cache statistics (simplified)
155
84
  */
156
85
  export function getCacheStats() {
157
86
  try {
158
- return cacheManagerInstance.getAdvancedStats();
87
+ const cache = cacheManagerInstance.getCache();
88
+ return {
89
+ projects: cache.projects || [],
90
+ templates: cache.templates || [],
91
+ templateFiles: cache.templateFiles || [],
92
+ features: cache.features || [],
93
+ hits: 0,
94
+ misses: 0
95
+ };
159
96
  }
160
97
  catch (error) {
161
98
  return {
162
- cache: { hitRate: '0%', size: 0 },
163
- health: { status: 'Unknown' },
164
- performance: {}
99
+ projects: [],
100
+ templates: [],
101
+ templateFiles: [],
102
+ features: [],
103
+ hits: 0,
104
+ misses: 0
165
105
  };
166
106
  }
167
107
  }
168
108
  /**
169
- * Get cache status
109
+ * Get cache status (simplified)
170
110
  */
171
111
  export function getCacheStatus() {
172
112
  try {
173
- const stats = getCacheStats();
174
113
  const cache = cacheManagerInstance.getCache();
175
114
  return {
176
- isHealthy: stats.health?.status === 'Healthy',
177
- hitRate: 0,
115
+ initialized: true,
116
+ version: cache.version || '1.0.0',
178
117
  totalProjects: cache.projects?.length || 0,
179
118
  totalTemplates: cache.templates?.length || 0,
180
- totalFeatures: cache.features?.length || 0,
181
- recentProjects: [],
182
- performance: stats.performance || {},
183
- size: stats.cache?.size || 0
119
+ totalFeatures: cache.features?.length || 0
184
120
  };
185
121
  }
186
122
  catch (error) {
187
123
  return {
188
- isHealthy: false,
189
- hitRate: 0,
124
+ initialized: false,
125
+ version: '1.0.0',
190
126
  totalProjects: 0,
191
127
  totalTemplates: 0,
192
- totalFeatures: 0,
193
- recentProjects: [],
194
- performance: {},
195
- size: 0
128
+ totalFeatures: 0
196
129
  };
197
130
  }
198
131
  }
@@ -292,7 +292,6 @@ function extractInstalledPackages(output, language) {
292
292
  switch (language) {
293
293
  case 'javascript':
294
294
  case 'typescript':
295
- case 'nodejs':
296
295
  // Parse npm/yarn/pnpm/bun output
297
296
  const jsMatches = output.match(/(?:added|installed)\s+(.+?)(?:\s|$)/gi);
298
297
  if (jsMatches) {
@@ -387,7 +386,6 @@ export async function installPackages(projectPath, language, packages, options =
387
386
  switch (language) {
388
387
  case 'javascript':
389
388
  case 'typescript':
390
- case 'nodejs':
391
389
  const flags = [
392
390
  isDev ? (packageManager.name === 'npm' ? '--save-dev' : packageManager.name === 'yarn' ? '--dev' : '--save-dev') : '',
393
391
  exact ? '--save-exact' : '',