package-installer-cli 1.3.0 → 1.3.2
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.
- checksums.yaml +4 -4
- data/dist/commands/add.js +24 -15
- data/dist/commands/analyze.js +4 -4
- data/dist/commands/cache.js +1 -2
- data/dist/commands/check.js +160 -134
- data/dist/commands/clean.js +4 -3
- data/dist/commands/clone.js +0 -1
- data/dist/commands/create.js +3 -1
- data/dist/commands/deploy.js +1 -3
- data/dist/commands/doctor.js +1 -2
- data/dist/commands/env.js +2 -3
- data/dist/commands/update.js +0 -1
- data/dist/commands/upgrade-cli.js +1 -3
- data/dist/index.js +8 -6
- data/dist/utils/banner.js +2 -2
- data/dist/utils/featureInstaller.js +11 -5
- data/dist/utils/helpFormatter.js +9 -2
- data/dist/utils/languageConfig.js +0 -29
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cea62d79600dea627bd56027e3957cf9dcb9aea7714a42a1becad34f9206c73c
|
|
4
|
+
data.tar.gz: 5c81b035b59925817350c8ea8d69b43264ba0d6bc1ad88454768b4a102c3df6b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c5648ee659a9fba908c339ea65bf798d4540d726427eaac63ac0fcf288ae8ce7bb1fba253883bcf24cbe369ded23614b64b282cceba5dc91acee89d8a305dfd7
|
|
7
|
+
data.tar.gz: 969feb40b0130d1a0a213084a5f8f8edb95a09b2fb530a69b4aee57329c4dc715a0d007a103dca22b02edd48d9ea3a29c30fa84afc0b5640f4f347119d78fa31
|
data/dist/commands/add.js
CHANGED
|
@@ -5,10 +5,11 @@ import boxen from 'boxen';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import { createStandardHelp } from '../utils/helpFormatter.js';
|
|
8
|
-
import { addFeature, detectProjectStack, SUPPORTED_FEATURES } from '../utils/featureInstaller.js';
|
|
8
|
+
import { addFeature, detectProjectStack, SUPPORTED_FEATURES, ensureFeaturesLoaded } from '../utils/featureInstaller.js';
|
|
9
9
|
import { historyManager } from '../utils/historyManager.js';
|
|
10
10
|
import { cacheProjectData } from '../utils/cacheManager.js';
|
|
11
11
|
import { getFeaturesJsonPath, getFeaturesPath } from '../utils/pathResolver.js';
|
|
12
|
+
import { displayCommandBanner } from '../utils/banner.js';
|
|
12
13
|
/**
|
|
13
14
|
* Helper function to capitalize strings
|
|
14
15
|
*/
|
|
@@ -18,7 +19,13 @@ function capitalize(str) {
|
|
|
18
19
|
/**
|
|
19
20
|
* Get features.json configuration with new jsonPath structure
|
|
20
21
|
*/
|
|
22
|
+
// Cache for features config to avoid repeated file reads
|
|
23
|
+
let featuresConfigCache = null;
|
|
21
24
|
async function getFeaturesConfig() {
|
|
25
|
+
// Return cached config if available
|
|
26
|
+
if (featuresConfigCache) {
|
|
27
|
+
return featuresConfigCache;
|
|
28
|
+
}
|
|
22
29
|
try {
|
|
23
30
|
// Use the centralized path resolver
|
|
24
31
|
const featuresPath = getFeaturesJsonPath();
|
|
@@ -42,12 +49,12 @@ async function getFeaturesConfig() {
|
|
|
42
49
|
};
|
|
43
50
|
}
|
|
44
51
|
else {
|
|
45
|
-
|
|
52
|
+
// Silently skip missing files to avoid console spam
|
|
46
53
|
processedConfig[featureName] = featureConfig;
|
|
47
54
|
}
|
|
48
55
|
}
|
|
49
56
|
catch (error) {
|
|
50
|
-
|
|
57
|
+
// Silently handle errors to avoid console spam
|
|
51
58
|
processedConfig[featureName] = featureConfig;
|
|
52
59
|
}
|
|
53
60
|
}
|
|
@@ -56,13 +63,16 @@ async function getFeaturesConfig() {
|
|
|
56
63
|
processedConfig[featureName] = featureConfig;
|
|
57
64
|
}
|
|
58
65
|
}
|
|
59
|
-
|
|
66
|
+
// Cache the processed config
|
|
67
|
+
featuresConfigCache = { features: processedConfig };
|
|
68
|
+
return featuresConfigCache;
|
|
60
69
|
}
|
|
61
|
-
|
|
62
|
-
|
|
70
|
+
// Return empty config without warning to avoid console spam
|
|
71
|
+
featuresConfigCache = { features: {} };
|
|
72
|
+
return featuresConfigCache;
|
|
63
73
|
}
|
|
64
74
|
catch (error) {
|
|
65
|
-
|
|
75
|
+
// Return fallback config without warning
|
|
66
76
|
return { features: {} };
|
|
67
77
|
}
|
|
68
78
|
}
|
|
@@ -88,6 +98,7 @@ async function getSubFeatures(category) {
|
|
|
88
98
|
* List available features from features.json with descriptions
|
|
89
99
|
*/
|
|
90
100
|
async function listAvailableFeatures() {
|
|
101
|
+
await ensureFeaturesLoaded();
|
|
91
102
|
const featuresConfig = await getFeaturesConfig();
|
|
92
103
|
if (!featuresConfig.features || Object.keys(featuresConfig.features).length === 0) {
|
|
93
104
|
console.log(chalk.yellow('⚠️ No features found in configuration'));
|
|
@@ -269,6 +280,7 @@ function showEnhancedSetupInstructions(feature, provider) {
|
|
|
269
280
|
* Show help for add command
|
|
270
281
|
*/
|
|
271
282
|
export async function showAddHelp() {
|
|
283
|
+
await ensureFeaturesLoaded();
|
|
272
284
|
const featuresConfig = await getFeaturesConfig();
|
|
273
285
|
const availableFeatures = Object.keys(featuresConfig.features || {});
|
|
274
286
|
const helpConfig = {
|
|
@@ -281,8 +293,7 @@ export async function showAddHelp() {
|
|
|
281
293
|
],
|
|
282
294
|
options: [
|
|
283
295
|
{ flag: '-l, --list', description: 'List all available features' },
|
|
284
|
-
{ flag: '-v, --verbose', description: 'Show detailed output' }
|
|
285
|
-
{ flag: '-h, --help', description: 'Show this help message' }
|
|
296
|
+
{ flag: '-v, --verbose', description: 'Show detailed output' }
|
|
286
297
|
],
|
|
287
298
|
examples: [
|
|
288
299
|
{ command: 'add', description: 'Interactive feature selection' },
|
|
@@ -334,21 +345,19 @@ export async function showAddHelp() {
|
|
|
334
345
|
*/
|
|
335
346
|
export async function addCommand(feature, provider, options = {}) {
|
|
336
347
|
try {
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
await showAddHelp();
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
348
|
+
// Ensure features are loaded first
|
|
349
|
+
await ensureFeaturesLoaded();
|
|
342
350
|
// Handle list flag
|
|
343
351
|
if (options.list || feature === '--list' || feature === '-l') {
|
|
344
352
|
await listAvailableFeatures();
|
|
345
353
|
return;
|
|
346
354
|
}
|
|
355
|
+
// Display command banner
|
|
356
|
+
displayCommandBanner('Add', 'Add new features to your project with integrated templates and configurations');
|
|
347
357
|
// Initialize history manager
|
|
348
358
|
await historyManager.init();
|
|
349
359
|
// Show disclaimer
|
|
350
360
|
showFeatureDisclaimer();
|
|
351
|
-
console.log(chalk.hex('#9c88ff')('\n🔮 Adding features to your project...'));
|
|
352
361
|
// Use provided project path or current directory
|
|
353
362
|
const projectPath = options.projectPath || process.cwd();
|
|
354
363
|
let projectInfo;
|
data/dist/commands/analyze.js
CHANGED
|
@@ -8,7 +8,8 @@ import os from 'os';
|
|
|
8
8
|
import gradientString from 'gradient-string';
|
|
9
9
|
import boxen from 'boxen';
|
|
10
10
|
import { createStandardHelp } from '../utils/helpFormatter.js';
|
|
11
|
-
import {
|
|
11
|
+
import { displayCommandBanner } from '../utils/banner.js';
|
|
12
|
+
import { displaySystemInfo, displaySuccessMessage } from '../utils/dashboard.js';
|
|
12
13
|
import { HistoryManager } from '../utils/historyManager.js';
|
|
13
14
|
/**
|
|
14
15
|
* Display help for analyze command using standardized format
|
|
@@ -25,8 +26,7 @@ export function showAnalyzeHelp() {
|
|
|
25
26
|
options: [
|
|
26
27
|
{ flag: '--export', description: 'Export analytics data to JSON file' },
|
|
27
28
|
{ flag: '--reset', description: 'Reset analytics history' },
|
|
28
|
-
{ flag: '--detailed', description: 'Show detailed analytics breakdown' }
|
|
29
|
-
{ flag: '-h, --help', description: 'Show this help message' }
|
|
29
|
+
{ flag: '--detailed', description: 'Show detailed analytics breakdown' }
|
|
30
30
|
],
|
|
31
31
|
examples: [
|
|
32
32
|
{ command: 'analyze', description: 'Show complete analytics dashboard' },
|
|
@@ -65,7 +65,7 @@ export async function analyzeCommand(options = {}) {
|
|
|
65
65
|
showAnalyzeHelp();
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
displayCommandBanner('Analytics', 'Comprehensive project analytics and usage insights');
|
|
69
69
|
const historyManager = new HistoryManager();
|
|
70
70
|
try {
|
|
71
71
|
// Load analytics data from history.json
|
data/dist/commands/cache.js
CHANGED
|
@@ -26,8 +26,7 @@ export function showCacheHelp() {
|
|
|
26
26
|
{ flag: '--clear [type]', description: 'Clear cache (optional type)' },
|
|
27
27
|
{ flag: '--info', description: 'Show cache information' },
|
|
28
28
|
{ flag: '--optimize', description: 'Optimize cache' },
|
|
29
|
-
{ flag: '--size', description: 'Show cache size only' }
|
|
30
|
-
{ flag: '-h, --help', description: 'Show this help message' }
|
|
29
|
+
{ flag: '--size', description: 'Show cache size only' }
|
|
31
30
|
],
|
|
32
31
|
examples: [
|
|
33
32
|
{ command: 'cache stats', description: 'Show cache statistics' },
|
data/dist/commands/check.js
CHANGED
|
@@ -2,12 +2,12 @@ import { exec } from 'child_process';
|
|
|
2
2
|
import { promisify } from 'util';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import ora from 'ora';
|
|
5
|
-
import boxen from 'boxen';
|
|
6
5
|
import fs from 'fs-extra';
|
|
7
6
|
import path from 'path';
|
|
8
7
|
import semver from 'semver';
|
|
9
8
|
import https from 'https';
|
|
10
9
|
import { createStandardHelp } from '../utils/helpFormatter.js';
|
|
10
|
+
import { displayCommandBanner } from '../utils/banner.js';
|
|
11
11
|
import { getSupportedLanguages, getLanguageConfig } from '../utils/languageConfig.js';
|
|
12
12
|
const execAsync = promisify(exec);
|
|
13
13
|
// Generate PROJECT_TYPES from shared language configuration with enhanced registry support
|
|
@@ -31,6 +31,14 @@ const PROJECT_TYPES = getSupportedLanguages().map(lang => {
|
|
|
31
31
|
registryUrl = 'https://pypi.org';
|
|
32
32
|
packageInfoUrl = (packageName) => `https://pypi.org/pypi/${packageName}/json`;
|
|
33
33
|
break;
|
|
34
|
+
case 'ruby':
|
|
35
|
+
registryUrl = 'https://rubygems.org';
|
|
36
|
+
packageInfoUrl = (packageName) => `https://rubygems.org/api/v1/gems/${packageName}.json`;
|
|
37
|
+
break;
|
|
38
|
+
case 'go':
|
|
39
|
+
registryUrl = 'https://proxy.golang.org';
|
|
40
|
+
packageInfoUrl = (packageName) => `https://proxy.golang.org/${packageName}/@v/list`;
|
|
41
|
+
break;
|
|
34
42
|
default:
|
|
35
43
|
// For unsupported languages, we'll try npm registry as fallback
|
|
36
44
|
registryUrl = 'https://registry.npmjs.org';
|
|
@@ -380,7 +388,6 @@ export function showCheckHelp() {
|
|
|
380
388
|
'check [options]'
|
|
381
389
|
],
|
|
382
390
|
options: [
|
|
383
|
-
{ flag: '-h, --help', description: 'Display help for this command' },
|
|
384
391
|
{ flag: '-v, --verbose', description: 'Show detailed information for all packages' }
|
|
385
392
|
],
|
|
386
393
|
examples: [
|
|
@@ -394,11 +401,11 @@ export function showCheckHelp() {
|
|
|
394
401
|
{
|
|
395
402
|
title: 'Supported Package Managers',
|
|
396
403
|
items: [
|
|
397
|
-
'npm, pnpm, yarn (
|
|
404
|
+
'npm, pnpm, yarn (JavaScript/TypeScript)',
|
|
398
405
|
'pip, pipenv, poetry (Python)',
|
|
399
406
|
'cargo (Rust)',
|
|
400
407
|
'go modules (Go)',
|
|
401
|
-
'
|
|
408
|
+
'gem, bundler (Ruby)'
|
|
402
409
|
]
|
|
403
410
|
}
|
|
404
411
|
],
|
|
@@ -427,6 +434,8 @@ export async function checkCommand(packageName, options) {
|
|
|
427
434
|
packageName = undefined;
|
|
428
435
|
}
|
|
429
436
|
try {
|
|
437
|
+
// Display command banner
|
|
438
|
+
displayCommandBanner('Check', 'Check package versions and updates for your project dependencies');
|
|
430
439
|
console.log('\n' + chalk.hex('#f39c12')('🔍 Starting package check...'));
|
|
431
440
|
if (packageName && packageName !== '--verbose' && packageName !== '-v') {
|
|
432
441
|
await checkSinglePackage(packageName, isVerbose);
|
|
@@ -459,7 +468,36 @@ async function checkSinglePackage(packageName, verbose = false) {
|
|
|
459
468
|
async function checkProjectPackages(verbose = false) {
|
|
460
469
|
const spinner = ora('Analyzing project dependencies...').start();
|
|
461
470
|
try {
|
|
462
|
-
|
|
471
|
+
// Detect ALL project types instead of just one
|
|
472
|
+
const allProjectTypes = await detectAllProjectTypes();
|
|
473
|
+
if (allProjectTypes.length === 0) {
|
|
474
|
+
spinner.fail(chalk.hex('#ff4757')('❌ No supported project configuration files found'));
|
|
475
|
+
console.log(chalk.hex('#95afc0')('💡 Supported files: package.json, tsconfig.json, Cargo.toml, requirements.txt, pyproject.toml, go.mod, Gemfile'));
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
spinner.succeed(chalk.hex('#10ac84')(`✅ Detected ${allProjectTypes.length} project type(s): ${allProjectTypes.map(pt => pt.name).join(', ')}`));
|
|
479
|
+
// Process each project type separately
|
|
480
|
+
for (let i = 0; i < allProjectTypes.length; i++) {
|
|
481
|
+
const projectType = allProjectTypes[i];
|
|
482
|
+
const isMultiProject = allProjectTypes.length > 1;
|
|
483
|
+
if (isMultiProject) {
|
|
484
|
+
console.log('\n' + chalk.hex('#667eea')('═'.repeat(80)));
|
|
485
|
+
console.log(chalk.hex('#667eea')(`📋 Analyzing ${projectType.name} Dependencies (${i + 1}/${allProjectTypes.length})`));
|
|
486
|
+
console.log(chalk.hex('#667eea')('═'.repeat(80)));
|
|
487
|
+
}
|
|
488
|
+
await analyzeSingleProjectType(projectType, verbose, isMultiProject);
|
|
489
|
+
}
|
|
490
|
+
return; // Exit early since we've processed all project types
|
|
491
|
+
}
|
|
492
|
+
catch (error) {
|
|
493
|
+
spinner.fail(chalk.hex('#ff4757')(`❌ Failed to analyze projects: ${error.message}`));
|
|
494
|
+
throw error;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
// New function to analyze a single project type
|
|
498
|
+
async function analyzeSingleProjectType(projectType, verbose, isMultiProject = false) {
|
|
499
|
+
const spinner = ora(`Analyzing ${projectType.name} dependencies...`).start();
|
|
500
|
+
try {
|
|
463
501
|
let dependencies = {};
|
|
464
502
|
if (!projectType) {
|
|
465
503
|
spinner.warn('No supported project files found in current directory');
|
|
@@ -470,10 +508,8 @@ async function checkProjectPackages(verbose = false) {
|
|
|
470
508
|
console.log(chalk.gray('\n Or specify a package name: pi check <package-name>'));
|
|
471
509
|
return;
|
|
472
510
|
}
|
|
473
|
-
// Get fresh dependencies
|
|
474
|
-
|
|
475
|
-
dependencies = await getDependenciesForProject(projectType);
|
|
476
|
-
}
|
|
511
|
+
// Get fresh dependencies
|
|
512
|
+
dependencies = await getDependenciesForProject(projectType);
|
|
477
513
|
if (Object.keys(dependencies).length === 0) {
|
|
478
514
|
spinner.warn(`No dependencies found in ${projectType.name} project`);
|
|
479
515
|
return;
|
|
@@ -484,77 +520,73 @@ async function checkProjectPackages(verbose = false) {
|
|
|
484
520
|
try {
|
|
485
521
|
const info = await getEnhancedPackageInfo(name, version, projectType);
|
|
486
522
|
packageInfos.push(info);
|
|
523
|
+
spinner.text = `✔ Retrieved info for ${name}`;
|
|
487
524
|
}
|
|
488
525
|
catch (error) {
|
|
489
526
|
console.warn(`⚠️ Could not check ${name}`);
|
|
490
527
|
}
|
|
491
528
|
}
|
|
492
|
-
spinner.succeed(
|
|
493
|
-
// Cache the package check results
|
|
494
|
-
|
|
495
|
-
|
|
529
|
+
spinner.succeed(`✔ Checked ${packageInfos.length} ${projectType.name} packages`);
|
|
530
|
+
// Cache the package check results (optional)
|
|
531
|
+
try {
|
|
532
|
+
await cachePackageCheckResults?.(packageInfos, projectType);
|
|
533
|
+
}
|
|
534
|
+
catch (error) {
|
|
535
|
+
// Caching is optional, continue without it
|
|
536
|
+
}
|
|
537
|
+
displayPackageInfo(packageInfos, projectType, verbose, isMultiProject);
|
|
496
538
|
}
|
|
497
539
|
catch (error) {
|
|
498
|
-
spinner.fail(
|
|
540
|
+
spinner.fail(`Failed to analyze ${projectType.name} dependencies`);
|
|
499
541
|
throw error;
|
|
500
542
|
}
|
|
501
543
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
const
|
|
506
|
-
|
|
544
|
+
// New function to detect ALL project types in a directory
|
|
545
|
+
async function detectAllProjectTypes() {
|
|
546
|
+
console.log(chalk.gray('🔍 Detecting all project types...'));
|
|
547
|
+
const foundTypes = [];
|
|
548
|
+
const foundFiles = [];
|
|
549
|
+
// Priority order for detection - check most common files first (supported languages only)
|
|
550
|
+
const priorityFiles = ['package.json', 'tsconfig.json', 'Cargo.toml', 'requirements.txt', 'pyproject.toml', 'go.mod', 'Gemfile'];
|
|
551
|
+
// Check all priority files in current directory
|
|
507
552
|
for (const priorityFile of priorityFiles) {
|
|
508
553
|
const filePath = path.join(process.cwd(), priorityFile);
|
|
509
|
-
console.log(chalk.gray(` Checking
|
|
554
|
+
console.log(chalk.gray(` Checking: ${filePath}`));
|
|
510
555
|
if (await fs.pathExists(filePath)) {
|
|
511
556
|
console.log(chalk.green(` ✅ Found: ${priorityFile}`));
|
|
557
|
+
foundFiles.push(priorityFile);
|
|
512
558
|
// Find the project type that matches this file
|
|
513
559
|
const matchingType = PROJECT_TYPES.find(type => type.files.includes(priorityFile));
|
|
514
|
-
if (matchingType) {
|
|
560
|
+
if (matchingType && !foundTypes.find(t => t.name === matchingType.name)) {
|
|
515
561
|
console.log(chalk.green(` 📦 Detected: ${matchingType.name}`));
|
|
516
|
-
|
|
562
|
+
foundTypes.push(matchingType);
|
|
517
563
|
}
|
|
518
564
|
}
|
|
519
565
|
}
|
|
520
|
-
//
|
|
566
|
+
// Check for additional files in each detected project type
|
|
521
567
|
for (const projectType of PROJECT_TYPES) {
|
|
522
|
-
|
|
568
|
+
if (foundTypes.find(t => t.name === projectType.name))
|
|
569
|
+
continue; // Already found
|
|
523
570
|
for (const file of projectType.files) {
|
|
524
571
|
if (priorityFiles.includes(file))
|
|
525
572
|
continue; // Already checked
|
|
526
|
-
// Check in current directory first
|
|
527
573
|
const filePath = path.join(process.cwd(), file);
|
|
528
574
|
if (await fs.pathExists(filePath)) {
|
|
529
|
-
console.log(chalk.green(` ✅ Found: ${file}`));
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
// Third pass: check subdirectories
|
|
535
|
-
try {
|
|
536
|
-
const currentDirContents = await fs.readdir(process.cwd());
|
|
537
|
-
for (const item of currentDirContents) {
|
|
538
|
-
const itemPath = path.join(process.cwd(), item);
|
|
539
|
-
const stats = await fs.stat(itemPath);
|
|
540
|
-
if (stats.isDirectory()) {
|
|
541
|
-
for (const priorityFile of priorityFiles) {
|
|
542
|
-
const configPath = path.join(itemPath, priorityFile);
|
|
543
|
-
if (await fs.pathExists(configPath)) {
|
|
544
|
-
console.log(chalk.green(` ✅ Found in subdirectory: ${item}/${priorityFile}`));
|
|
545
|
-
const matchingType = PROJECT_TYPES.find(type => type.files.includes(priorityFile));
|
|
546
|
-
if (matchingType)
|
|
547
|
-
return matchingType;
|
|
548
|
-
}
|
|
575
|
+
console.log(chalk.green(` ✅ Found additional: ${file}`));
|
|
576
|
+
foundFiles.push(file);
|
|
577
|
+
if (!foundTypes.find(t => t.name === projectType.name)) {
|
|
578
|
+
console.log(chalk.green(` 📦 Detected: ${projectType.name}`));
|
|
579
|
+
foundTypes.push(projectType);
|
|
549
580
|
}
|
|
550
581
|
}
|
|
551
582
|
}
|
|
552
583
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
584
|
+
return foundTypes;
|
|
585
|
+
}
|
|
586
|
+
async function detectProjectType() {
|
|
587
|
+
// This function now uses detectAllProjectTypes and returns the first one for backward compatibility
|
|
588
|
+
const allTypes = await detectAllProjectTypes();
|
|
589
|
+
return allTypes.length > 0 ? allTypes[0] : null;
|
|
558
590
|
}
|
|
559
591
|
async function getDependenciesForProject(projectType) {
|
|
560
592
|
console.log(chalk.gray(`📋 Looking for dependencies in ${projectType.name} project...`));
|
|
@@ -689,8 +721,8 @@ async function getPackageInfo(packageName, currentVersion, projectType) {
|
|
|
689
721
|
try {
|
|
690
722
|
// Clean up version string (remove ^ ~ and similar prefixes)
|
|
691
723
|
const cleanCurrentVersion = currentVersion?.replace(/[\^~>=<]/, '') || 'unknown';
|
|
692
|
-
// Enhanced NPM registry support
|
|
693
|
-
if (type.name === '
|
|
724
|
+
// Enhanced NPM registry support
|
|
725
|
+
if (type.name === 'JavaScript' || type.name === 'TypeScript') {
|
|
694
726
|
const response = await fetch(`https://registry.npmjs.org/${packageName}`);
|
|
695
727
|
if (!response.ok) {
|
|
696
728
|
throw new Error(`Package ${packageName} not found in NPM registry`);
|
|
@@ -799,101 +831,95 @@ async function getPackageInfo(packageName, currentVersion, projectType) {
|
|
|
799
831
|
throw new Error(`Failed to fetch info for ${packageName}: ${error.message}`);
|
|
800
832
|
}
|
|
801
833
|
}
|
|
802
|
-
function displayPackageInfo(packages, projectType, verbose = false) {
|
|
834
|
+
function displayPackageInfo(packages, projectType, verbose = false, isMultiProject = false) {
|
|
803
835
|
if (packages.length === 0) {
|
|
804
836
|
console.log(chalk.yellow('📦 No packages to display'));
|
|
805
837
|
return;
|
|
806
838
|
}
|
|
807
|
-
console.log('\n' + chalk.hex('#00d2d3')('📊 Package Analysis Results'));
|
|
808
|
-
console.log(chalk.gray('─'.repeat(60)));
|
|
809
839
|
const outdatedPackages = packages.filter(pkg => pkg.needsUpdate);
|
|
810
840
|
const deprecatedPackages = packages.filter(pkg => pkg.isDeprecated);
|
|
811
841
|
const upToDatePackages = packages.filter(pkg => !pkg.needsUpdate && !pkg.isDeprecated);
|
|
812
|
-
//
|
|
813
|
-
console.log(
|
|
814
|
-
console.log(
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
}
|
|
821
|
-
// Show severity breakdown
|
|
842
|
+
// Compact summary header
|
|
843
|
+
console.log('\n' + chalk.hex('#00d2d3')('📊 Package Analysis Results'));
|
|
844
|
+
console.log(chalk.gray('─'.repeat(80)));
|
|
845
|
+
const summary = [
|
|
846
|
+
`${chalk.hex('#10ac84')('✅')} ${upToDatePackages.length} up-to-date`,
|
|
847
|
+
outdatedPackages.length > 0 ? `${chalk.hex('#f39c12')('⚠️')} ${outdatedPackages.length} need updates` : null,
|
|
848
|
+
deprecatedPackages.length > 0 ? `${chalk.hex('#ff4757')('🚨')} ${deprecatedPackages.length} deprecated` : null
|
|
849
|
+
].filter(Boolean).join(' • ');
|
|
850
|
+
console.log(`${chalk.bold(`Total: ${packages.length}`)} • ${summary}`);
|
|
822
851
|
if (projectType) {
|
|
823
|
-
console.log(
|
|
824
|
-
}
|
|
825
|
-
// Determine how many packages to show
|
|
826
|
-
const packagesToShow = verbose ? packages : packages.slice(0,
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
})
|
|
854
|
-
}
|
|
855
|
-
// Show remaining packages
|
|
856
|
-
if (!verbose && packages.length >
|
|
857
|
-
const remaining = packages.length -
|
|
858
|
-
const remainingOutdated = packages.
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
852
|
+
console.log(`${chalk.hex('#00d2d3')('📋')} ${projectType.name} (${chalk.cyan(projectType.packageManager)})`);
|
|
853
|
+
}
|
|
854
|
+
// Determine how many packages to show
|
|
855
|
+
const packagesToShow = verbose ? packages : packages.slice(0, 12);
|
|
856
|
+
// Group packages by status for better organization
|
|
857
|
+
const groupedPackages = [
|
|
858
|
+
...deprecatedPackages.slice(0, verbose ? deprecatedPackages.length : 3),
|
|
859
|
+
...outdatedPackages.slice(0, verbose ? outdatedPackages.length : 8),
|
|
860
|
+
...upToDatePackages.slice(0, verbose ? upToDatePackages.length : 6)
|
|
861
|
+
].slice(0, verbose ? packages.length : 12);
|
|
862
|
+
if (groupedPackages.length > 0) {
|
|
863
|
+
console.log('\n');
|
|
864
|
+
// Compact table format
|
|
865
|
+
groupedPackages.forEach((pkg, index) => {
|
|
866
|
+
const statusIcon = pkg.isDeprecated ? '🚨' : pkg.needsUpdate ? '⚠️' : '✅';
|
|
867
|
+
const statusColor = pkg.isDeprecated ? '#ff4757' : pkg.needsUpdate ? '#f39c12' : '#10ac84';
|
|
868
|
+
// Format version comparison compactly
|
|
869
|
+
const versionText = pkg.needsUpdate && pkg.latestVersion !== 'unknown'
|
|
870
|
+
? `${chalk.dim(pkg.currentVersion)} → ${chalk.hex(statusColor)(pkg.latestVersion)}`
|
|
871
|
+
: chalk.dim(pkg.currentVersion);
|
|
872
|
+
// Truncate name and description for compact view
|
|
873
|
+
const name = pkg.name.length > 25 ? pkg.name.slice(0, 22) + '...' : pkg.name;
|
|
874
|
+
const desc = pkg.description
|
|
875
|
+
? (pkg.description.length > 50 ? pkg.description.slice(0, 47) + '...' : pkg.description)
|
|
876
|
+
: chalk.dim('No description');
|
|
877
|
+
console.log(`${statusIcon} ${chalk.bold(name.padEnd(25))} ${versionText.padEnd(20)} ${chalk.gray(desc)}`);
|
|
878
|
+
// Show deprecation warning inline
|
|
879
|
+
if (pkg.isDeprecated && pkg.deprecatedMessage) {
|
|
880
|
+
console.log(` ${chalk.hex('#ff4757')('⚠️')} ${chalk.dim(pkg.deprecatedMessage.slice(0, 80))}`);
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
// Show remaining packages summary when not in verbose mode
|
|
885
|
+
if (!verbose && packages.length > 12) {
|
|
886
|
+
const remaining = packages.length - groupedPackages.length;
|
|
887
|
+
const remainingOutdated = packages.filter(pkg => pkg.needsUpdate && !groupedPackages.includes(pkg)).length;
|
|
888
|
+
const remainingUpToDate = packages.filter(pkg => !pkg.needsUpdate && !pkg.isDeprecated && !groupedPackages.includes(pkg)).length;
|
|
889
|
+
console.log('\n' + chalk.gray('─'.repeat(80)));
|
|
890
|
+
const hiddenSummary = [
|
|
891
|
+
remainingUpToDate > 0 ? `${chalk.hex('#10ac84')('✅')} ${remainingUpToDate} more up-to-date` : null,
|
|
892
|
+
remainingOutdated > 0 ? `${chalk.hex('#f39c12')('⚠️')} ${remainingOutdated} more need updates` : null
|
|
893
|
+
].filter(Boolean).join(' • ');
|
|
894
|
+
if (hiddenSummary) {
|
|
895
|
+
console.log(`${chalk.dim(`+${remaining} hidden:`)} ${hiddenSummary}`);
|
|
865
896
|
}
|
|
897
|
+
// Show sample of remaining package names
|
|
866
898
|
if (remainingOutdated > 0) {
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
console.log(` ${chalk.gray('Packages:')} ${outdatedNames.join(', ')}${outdatedNames.length < remainingOutdated ? '...' : ''}`);
|
|
899
|
+
const sampleNames = packages.filter(pkg => pkg.needsUpdate && !groupedPackages.includes(pkg))
|
|
900
|
+
.slice(0, 4).map(pkg => pkg.name).join(', ');
|
|
901
|
+
console.log(`${chalk.dim('Outdated:')} ${sampleNames}${remainingOutdated > 4 ? '...' : ''}`);
|
|
871
902
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
903
|
+
console.log(`\n${chalk.cyan('💡')} Use ${chalk.bold('--verbose')} to see all ${packages.length} packages`);
|
|
904
|
+
}
|
|
905
|
+
// Compact recommendations section
|
|
906
|
+
if (outdatedPackages.length > 0 || deprecatedPackages.length > 0) {
|
|
907
|
+
console.log('\n' + chalk.hex('#667eea')('💡 Quick Actions:'));
|
|
908
|
+
console.log(chalk.gray('─'.repeat(40)));
|
|
909
|
+
if (deprecatedPackages.length > 0) {
|
|
910
|
+
console.log(`${chalk.hex('#ff4757')('🚨')} ${deprecatedPackages.length} deprecated - replace immediately`);
|
|
911
|
+
deprecatedPackages.slice(0, 3).forEach(pkg => {
|
|
912
|
+
console.log(` • ${chalk.red(pkg.name)} ${chalk.gray(pkg.deprecatedMessage ? '- ' + pkg.deprecatedMessage.slice(0, 50) + '...' : '')}`);
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
if (outdatedPackages.length > 0 && projectType) {
|
|
916
|
+
console.log(`${chalk.hex('#f39c12')('⚠️')} ${outdatedPackages.length} need updates - Run: ${chalk.cyan(projectType.getUpdateCommand())}`);
|
|
917
|
+
}
|
|
918
|
+
if (packages.length > 50) {
|
|
919
|
+
console.log(`${chalk.hex('#95afc0')('📦')} Large dependency count (${packages.length}) - consider optimization`);
|
|
877
920
|
}
|
|
878
|
-
console.log(`\n ${chalk.cyan('💡 Tip:')} Use ${chalk.bold('--verbose')} to see detailed info for all ${packages.length} packages`);
|
|
879
|
-
}
|
|
880
|
-
// Enhanced recommendations section
|
|
881
|
-
console.log('\n' + chalk.hex('#00d2d3')('💡 Recommendations:'));
|
|
882
|
-
console.log(chalk.gray('─'.repeat(30)));
|
|
883
|
-
if (deprecatedPackages.length > 0) {
|
|
884
|
-
console.log(`${chalk.hex('#ff4757')('🚨 URGENT:')} Replace ${deprecatedPackages.length} deprecated package(s) immediately`);
|
|
885
|
-
deprecatedPackages.slice(0, 3).forEach(pkg => {
|
|
886
|
-
console.log(` • ${chalk.red(pkg.name)} ${chalk.gray(pkg.deprecatedMessage ? '- ' + pkg.deprecatedMessage.slice(0, 50) + '...' : '')}`);
|
|
887
|
-
});
|
|
888
|
-
}
|
|
889
|
-
if (outdatedPackages.length > 0 && projectType) {
|
|
890
|
-
console.log(`${chalk.hex('#f39c12')('⚠️ UPDATE:')} ${outdatedPackages.length} package(s) need updating`);
|
|
891
|
-
console.log(` Run: ${chalk.cyan(projectType.getUpdateCommand())}`);
|
|
892
|
-
}
|
|
893
|
-
if (packages.length > 50) {
|
|
894
|
-
console.log(`${chalk.hex('#95afc0')('📦 INFO:')} Large dependency count (${packages.length}) - consider reviewing for optimization`);
|
|
895
921
|
}
|
|
896
|
-
console.log(chalk.gray(`\
|
|
922
|
+
console.log(chalk.gray(`\nLast checked: ${new Date().toLocaleString()}`));
|
|
897
923
|
}
|
|
898
924
|
/**
|
|
899
925
|
* Cache package check results for performance
|
data/dist/commands/clean.js
CHANGED
|
@@ -6,6 +6,7 @@ import ora from 'ora';
|
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { createStandardHelp } from '../utils/helpFormatter.js';
|
|
9
|
+
import { displayCommandBanner } from '../utils/banner.js';
|
|
9
10
|
/**
|
|
10
11
|
* Display help for clean command
|
|
11
12
|
*/
|
|
@@ -25,8 +26,7 @@ export function showCleanHelp() {
|
|
|
25
26
|
{ flag: '--logs', description: 'Clean log files and debug outputs' },
|
|
26
27
|
{ flag: '--all', description: 'Clean everything (safe operation)' },
|
|
27
28
|
{ flag: '--deep', description: 'Deep clean (includes lock files)' },
|
|
28
|
-
{ flag: '--dry-run', description: 'Preview what would be cleaned' }
|
|
29
|
-
{ flag: '-h, --help', description: 'Show this help message' }
|
|
29
|
+
{ flag: '--dry-run', description: 'Preview what would be cleaned' }
|
|
30
30
|
],
|
|
31
31
|
examples: [
|
|
32
32
|
{ command: 'clean --build', description: 'Clean build directories only' },
|
|
@@ -65,7 +65,8 @@ export async function cleanCommand(options = {}) {
|
|
|
65
65
|
showCleanHelp();
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
// Display command banner
|
|
69
|
+
displayCommandBanner('Clean', 'Clean development artifacts, caches, and temporary files from your project');
|
|
69
70
|
console.log(chalk.hex('#ffa502')('🧹 Project Cleaner\n'));
|
|
70
71
|
const projectPath = process.cwd();
|
|
71
72
|
const isDryRun = options['dryRun'] || options['dry-run'];
|
data/dist/commands/clone.js
CHANGED
|
@@ -16,7 +16,6 @@ export function showCloneHelp() {
|
|
|
16
16
|
'clone [options]'
|
|
17
17
|
],
|
|
18
18
|
options: [
|
|
19
|
-
{ flag: '-h, --help', description: 'Display help for this command' },
|
|
20
19
|
{ flag: '--offline', description: 'Use cached templates if available' },
|
|
21
20
|
{ flag: '--no-deps', description: 'Skip dependency installation' },
|
|
22
21
|
{ flag: '--no-git', description: 'Skip git initialization' },
|
data/dist/commands/create.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { createStandardHelp } from '../utils/helpFormatter.js';
|
|
7
|
+
import { displayCommandBanner } from '../utils/banner.js';
|
|
7
8
|
import { promptProjectName, promptFrameworkSelection, promptLanguageSelection, promptTemplateSelection, promptFrameworkOptions, promptTemplateConfirmation, promptFeatureSelection, hasFrameworkOptions, hasUIOptions, hasBundlerOptions, shouldShowTemplates } from '../utils/prompts.js';
|
|
8
9
|
import { resolveTemplatePath, generateTemplateName, templateExists, getFrameworkConfig } from '../utils/templateResolver.js';
|
|
9
10
|
import { createProjectFromTemplate, installDependenciesForCreate } from '../utils/templateCreator.js';
|
|
@@ -22,7 +23,6 @@ export function showCreateHelp() {
|
|
|
22
23
|
'create [options]'
|
|
23
24
|
],
|
|
24
25
|
options: [
|
|
25
|
-
{ flag: '-h, --help', description: 'Display help for this command' },
|
|
26
26
|
{ flag: '--show-cache', description: 'Show cached preferences' },
|
|
27
27
|
{ flag: '--clear-cache', description: 'Clear cached preferences' }
|
|
28
28
|
],
|
|
@@ -79,6 +79,8 @@ export async function createProject(providedName, options) {
|
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
try {
|
|
82
|
+
// Display command banner
|
|
83
|
+
displayCommandBanner('Create', 'Create stunning web applications with integrated templates and features');
|
|
82
84
|
console.log('\n' + chalk.hex('#10ac84')('🚀 Welcome to Package Installer CLI!'));
|
|
83
85
|
console.log(chalk.hex('#95afc0')('Let\'s create something amazing together...'));
|
|
84
86
|
// Step 1: Get project name (prompt if not provided)
|
data/dist/commands/deploy.js
CHANGED
|
@@ -14,9 +14,7 @@ export function showDeployHelp() {
|
|
|
14
14
|
emoji: '🚀',
|
|
15
15
|
description: 'Deploy your projects to various cloud platforms seamlessly.\nThis feature is currently under development!',
|
|
16
16
|
usage: ['pi deploy'],
|
|
17
|
-
options: [
|
|
18
|
-
{ flag: '-h, --help', description: 'Display help for this command' }
|
|
19
|
-
],
|
|
17
|
+
options: [],
|
|
20
18
|
examples: [
|
|
21
19
|
{ command: 'pi deploy', description: 'Deploy current project' },
|
|
22
20
|
{ command: 'pi deploy --help', description: 'Show this help message' }
|
data/dist/commands/doctor.js
CHANGED
|
@@ -192,8 +192,7 @@ export function showDoctorHelp() {
|
|
|
192
192
|
{ flag: '--node', description: 'Check Node.js and npm setup only' },
|
|
193
193
|
{ flag: '--deps', description: 'Check project dependencies only' },
|
|
194
194
|
{ flag: '--tools', description: 'Check development tools only' },
|
|
195
|
-
{ flag: '--verbose', description: 'Show detailed diagnostic information' }
|
|
196
|
-
{ flag: '-h, --help', description: 'Show this help message' }
|
|
195
|
+
{ flag: '--verbose', description: 'Show detailed diagnostic information' }
|
|
197
196
|
],
|
|
198
197
|
examples: [
|
|
199
198
|
{ command: 'pi doctor', description: 'Complete health check' },
|
data/dist/commands/env.js
CHANGED
|
@@ -106,7 +106,7 @@ function checkEnvironmentVariables() {
|
|
|
106
106
|
async function generateEnvTemplate(projectPath) {
|
|
107
107
|
try {
|
|
108
108
|
const projectInfo = await detectProjectStack(projectPath);
|
|
109
|
-
const envPath = path.join(projectPath, '.env
|
|
109
|
+
const envPath = path.join(projectPath, '.env');
|
|
110
110
|
let envContent = `# Environment Configuration
|
|
111
111
|
# Generated by Package Installer CLI
|
|
112
112
|
|
|
@@ -222,8 +222,7 @@ export function showEnvironmentHelp() {
|
|
|
222
222
|
{ flag: '--generate', description: 'Generate .env template for project' },
|
|
223
223
|
{ flag: '--validate', description: 'Validate existing .env file' },
|
|
224
224
|
{ flag: '--export', description: 'Export environment info to file' },
|
|
225
|
-
{ flag: '--system', description: 'Show system information only' }
|
|
226
|
-
{ flag: '-h, --help', description: 'Show this help message' }
|
|
225
|
+
{ flag: '--system', description: 'Show system information only' }
|
|
227
226
|
],
|
|
228
227
|
examples: [
|
|
229
228
|
{ command: 'env', description: 'Interactive environment analysis' },
|
data/dist/commands/update.js
CHANGED
|
@@ -731,7 +731,6 @@ export function showUpdateHelp() {
|
|
|
731
731
|
'u [options] # alias'
|
|
732
732
|
],
|
|
733
733
|
options: [
|
|
734
|
-
{ flag: '-h, --help', description: 'Show this help message' },
|
|
735
734
|
{ flag: '--latest', description: 'Update to latest versions (breaking changes possible)' }
|
|
736
735
|
],
|
|
737
736
|
examples: [
|
|
@@ -19,9 +19,7 @@ export function showUpgradeHelp() {
|
|
|
19
19
|
emoji: '🚀',
|
|
20
20
|
description: 'Update Package Installer CLI to the latest version with intelligent upgrade management.\nIncludes breaking change detection and version compatibility checks!',
|
|
21
21
|
usage: ['pi upgrade-cli'],
|
|
22
|
-
options: [
|
|
23
|
-
{ flag: '-h, --help', description: 'Display help for this command' }
|
|
24
|
-
],
|
|
22
|
+
options: [],
|
|
25
23
|
examples: [
|
|
26
24
|
{ command: 'pi upgrade-cli', description: 'Smart upgrade with breaking change detection' },
|
|
27
25
|
{ command: 'pi upgrade-cli --help', description: 'Show this help message' }
|
data/dist/index.js
CHANGED
|
@@ -16,8 +16,10 @@ import { updateCommand, showUpdateHelp } from './commands/update.js';
|
|
|
16
16
|
import { analyzeCommand, showAnalyzeHelp } from './commands/analyze.js';
|
|
17
17
|
import { deployCommand, showDeployHelp } from './commands/deploy.js';
|
|
18
18
|
import { cleanCommand, showCleanHelp } from './commands/clean.js';
|
|
19
|
+
import { cacheCommand, showCacheHelp } from './commands/cache.js';
|
|
19
20
|
import { environmentCommand, showEnvironmentHelp } from './commands/env.js';
|
|
20
21
|
import { doctorCommand, showDoctorHelp } from './commands/doctor.js';
|
|
22
|
+
// Import utilities
|
|
21
23
|
import { initializeCache } from './utils/cacheManager.js';
|
|
22
24
|
import { displayBanner, displayCommandBanner } from './utils/banner.js';
|
|
23
25
|
import { getPackageJsonPath } from './utils/pathResolver.js';
|
|
@@ -155,11 +157,16 @@ program
|
|
|
155
157
|
.argument('[provider]', chalk.hex('#95afc0')('Provider for the feature (optional)'))
|
|
156
158
|
.option('-l, --list', chalk.hex('#95afc0')('List all available features'))
|
|
157
159
|
.option('-v, --verbose', chalk.hex('#95afc0')('Show detailed output'))
|
|
160
|
+
.option('-h, --help', chalk.hex('#95afc0')('Display help for this command'))
|
|
158
161
|
.on('--help', () => {
|
|
159
162
|
showAddHelp();
|
|
160
163
|
})
|
|
161
164
|
.action(async (feature, provider, options) => {
|
|
162
165
|
try {
|
|
166
|
+
if (options.help) {
|
|
167
|
+
showAddHelp();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
163
170
|
await addCommand(feature, provider, options);
|
|
164
171
|
}
|
|
165
172
|
catch (error) {
|
|
@@ -169,6 +176,7 @@ program
|
|
|
169
176
|
// UPGRADE-CLI COMMAND - Update CLI to latest version
|
|
170
177
|
program
|
|
171
178
|
.command('upgrade-cli')
|
|
179
|
+
.alias('upgrade')
|
|
172
180
|
.description(chalk.hex('#ff6b6b')('🚀 ') + chalk.hex('#fd79a8')('Update Package Installer CLI to the latest version'))
|
|
173
181
|
.on('--help', () => {
|
|
174
182
|
showUpgradeHelp();
|
|
@@ -195,10 +203,6 @@ program
|
|
|
195
203
|
})
|
|
196
204
|
.action(async (options) => {
|
|
197
205
|
try {
|
|
198
|
-
if (options.help) {
|
|
199
|
-
showAnalyzeHelp();
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
206
|
await analyzeCommand(options);
|
|
203
207
|
}
|
|
204
208
|
catch (error) {
|
|
@@ -310,12 +314,10 @@ program
|
|
|
310
314
|
.option('--size', 'Show cache size information')
|
|
311
315
|
.option('-h, --help', 'Show help for cache command')
|
|
312
316
|
.on('--help', async () => {
|
|
313
|
-
const { showCacheHelp } = await import('./commands/cache.js');
|
|
314
317
|
showCacheHelp();
|
|
315
318
|
})
|
|
316
319
|
.action(async (subcommand, type, options) => {
|
|
317
320
|
try {
|
|
318
|
-
const { cacheCommand } = await import('./commands/cache.js');
|
|
319
321
|
await cacheCommand(subcommand, type, options);
|
|
320
322
|
}
|
|
321
323
|
catch (error) {
|
data/dist/utils/banner.js
CHANGED
|
@@ -10,8 +10,8 @@ import { getPackageVersion } from './utils.js';
|
|
|
10
10
|
* Generate the main CLI banner with gradient colors
|
|
11
11
|
*/
|
|
12
12
|
export function generateBanner() {
|
|
13
|
-
const packageGradient = gradient(['#
|
|
14
|
-
const installerGradient = gradient(['#
|
|
13
|
+
const packageGradient = gradient(['#0072ff', '#00c6ff', '#4facfe']);
|
|
14
|
+
const installerGradient = gradient(['#00c6ff', '#0072ff', '#667eea']);
|
|
15
15
|
return boxen(packageGradient(' ██████╗ █████╗ ██████╗██╗ ██╗ █████╗ ██████╗ ███████╗') + '\n' +
|
|
16
16
|
packageGradient(' ██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██╔══██╗██╔════╝ ██╔════╝') + '\n' +
|
|
17
17
|
packageGradient(' ██████╔╝███████║██║ █████╔╝ ███████║██║ ███╗█████╗ ') + '\n' +
|
|
@@ -29,7 +29,6 @@ async function loadFeatures() {
|
|
|
29
29
|
const featuresConfig = featuresData.features || featuresData;
|
|
30
30
|
// Get available features using the centralized function
|
|
31
31
|
const availableFeatures = await getAvailableFeatures();
|
|
32
|
-
console.log(chalk.gray(`📦 Loading ${availableFeatures.length} available features...`));
|
|
33
32
|
// Process each feature and load its individual JSON file
|
|
34
33
|
for (const [featureName, config] of Object.entries(featuresConfig)) {
|
|
35
34
|
const featureConfig = config;
|
|
@@ -89,10 +88,17 @@ async function loadFeatures() {
|
|
|
89
88
|
console.warn(chalk.yellow('⚠️ Could not load features.json, using fallback configuration'));
|
|
90
89
|
}
|
|
91
90
|
}
|
|
92
|
-
//
|
|
93
|
-
|
|
91
|
+
// Lazy loading flag
|
|
92
|
+
let featuresLoaded = false;
|
|
93
|
+
// Lazy load features when needed
|
|
94
|
+
async function ensureFeaturesLoaded() {
|
|
95
|
+
if (!featuresLoaded) {
|
|
96
|
+
await loadFeatures();
|
|
97
|
+
featuresLoaded = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
94
100
|
// Export for use in other modules
|
|
95
|
-
export { SUPPORTED_FEATURES };
|
|
101
|
+
export { SUPPORTED_FEATURES, ensureFeaturesLoaded };
|
|
96
102
|
// Re-export path utilities for backward compatibility
|
|
97
103
|
export { getCliRootPath } from './pathResolver.js';
|
|
98
104
|
/**
|
|
@@ -348,7 +354,7 @@ export async function addFeature(featureName, provider, projectPath = process.cw
|
|
|
348
354
|
const spinner = ora(chalk.hex('#9c88ff')(`Adding ${featureName} feature...`)).start();
|
|
349
355
|
try {
|
|
350
356
|
// Ensure features are loaded
|
|
351
|
-
await
|
|
357
|
+
await ensureFeaturesLoaded();
|
|
352
358
|
// Validate project path exists
|
|
353
359
|
if (!await fs.pathExists(projectPath)) {
|
|
354
360
|
throw new Error(`Project path does not exist: ${projectPath}`);
|
data/dist/utils/helpFormatter.js
CHANGED
|
@@ -25,13 +25,20 @@ export function createStandardHelp(config) {
|
|
|
25
25
|
});
|
|
26
26
|
helpContent += '\n';
|
|
27
27
|
// Options
|
|
28
|
+
helpContent += chalk.cyan('Options:') + '\n';
|
|
29
|
+
// Check if help flag already exists
|
|
30
|
+
const hasHelpFlag = config.options && config.options.some(option => option.flag.includes('-h') || option.flag.includes('--help'));
|
|
31
|
+
// Add custom options first
|
|
28
32
|
if (config.options && config.options.length > 0) {
|
|
29
|
-
helpContent += chalk.cyan('Options:') + '\n';
|
|
30
33
|
config.options.forEach(option => {
|
|
31
34
|
helpContent += chalk.gray(` ${option.flag.padEnd(20)} ${option.description}`) + '\n';
|
|
32
35
|
});
|
|
33
|
-
helpContent += '\n';
|
|
34
36
|
}
|
|
37
|
+
// Add the global help flag only if it doesn't already exist
|
|
38
|
+
if (!hasHelpFlag) {
|
|
39
|
+
helpContent += chalk.gray(` -h, --help`.padEnd(20) + ' Show this help message') + '\n';
|
|
40
|
+
}
|
|
41
|
+
helpContent += '\n';
|
|
35
42
|
// Examples
|
|
36
43
|
if (config.examples && config.examples.length > 0) {
|
|
37
44
|
helpContent += chalk.cyan('Examples:') + '\n';
|
|
@@ -872,35 +872,6 @@ export const ENHANCED_LANGUAGE_CONFIGS = {
|
|
|
872
872
|
]
|
|
873
873
|
}
|
|
874
874
|
},
|
|
875
|
-
// Continue with other languages - abbreviated for space
|
|
876
|
-
nodejs: {
|
|
877
|
-
name: 'nodejs',
|
|
878
|
-
displayName: 'Node.js',
|
|
879
|
-
description: 'JavaScript runtime built on Chrome\'s V8 engine',
|
|
880
|
-
icon: '💚',
|
|
881
|
-
category: 'web',
|
|
882
|
-
maturity: 'stable',
|
|
883
|
-
packageManagers: [],
|
|
884
|
-
configFiles: [],
|
|
885
|
-
buildFiles: [],
|
|
886
|
-
sourceFileExtensions: ['.js', '.mjs'],
|
|
887
|
-
frameworkDetection: [],
|
|
888
|
-
toolchain: {
|
|
889
|
-
interpreter: { name: 'Node.js', command: 'node', optional: false, description: 'JavaScript runtime' }
|
|
890
|
-
},
|
|
891
|
-
ecosystem: {
|
|
892
|
-
registry: { name: 'npm', url: 'https://npmjs.com' },
|
|
893
|
-
community: { github: { repos: 0, stars: 0 }, stackoverflow: { questions: 0, activity: 'high' } },
|
|
894
|
-
learning: [],
|
|
895
|
-
trends: { githubStars: 0, stackoverflowQuestions: 0, jobPostings: 0, trendDirection: 'stable' }
|
|
896
|
-
},
|
|
897
|
-
compatibility: {
|
|
898
|
-
operatingSystems: ['windows', 'macos', 'linux'],
|
|
899
|
-
architectures: ['x64', 'arm64'],
|
|
900
|
-
containers: true,
|
|
901
|
-
cloud: []
|
|
902
|
-
}
|
|
903
|
-
},
|
|
904
875
|
go: {
|
|
905
876
|
name: 'go',
|
|
906
877
|
displayName: 'Go',
|