@skunkceo/cli 2.0.2 → 2.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/bin/skunk.js +174 -0
- package/package.json +1 -1
package/bin/skunk.js
CHANGED
|
@@ -66,6 +66,15 @@ switch (command) {
|
|
|
66
66
|
case 'plugins':
|
|
67
67
|
listPlugins();
|
|
68
68
|
break;
|
|
69
|
+
case 'status':
|
|
70
|
+
checkStatus();
|
|
71
|
+
break;
|
|
72
|
+
case 'versions':
|
|
73
|
+
showVersions(null);
|
|
74
|
+
break;
|
|
75
|
+
case 'version':
|
|
76
|
+
showVersions(args[1]);
|
|
77
|
+
break;
|
|
69
78
|
case 'update':
|
|
70
79
|
handleUpdate();
|
|
71
80
|
break;
|
|
@@ -359,6 +368,168 @@ Pro versions: skunk install plugin <name>-pro --license=XXXX${colors.reset}
|
|
|
359
368
|
`);
|
|
360
369
|
}
|
|
361
370
|
|
|
371
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
372
|
+
// Status - Check plugin versions
|
|
373
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
374
|
+
|
|
375
|
+
async function checkStatus() {
|
|
376
|
+
console.log('Checking plugin versions...\n');
|
|
377
|
+
|
|
378
|
+
// Fetch latest versions from API
|
|
379
|
+
const versionsUrl = 'https://skunkglobal.com/api/plugins/versions';
|
|
380
|
+
|
|
381
|
+
try {
|
|
382
|
+
const latestVersions = await new Promise((resolve, reject) => {
|
|
383
|
+
https.get(versionsUrl, { headers: { 'User-Agent': 'skunk-cli' } }, (res) => {
|
|
384
|
+
let data = '';
|
|
385
|
+
res.on('data', chunk => data += chunk);
|
|
386
|
+
res.on('end', () => {
|
|
387
|
+
try {
|
|
388
|
+
resolve(JSON.parse(data));
|
|
389
|
+
} catch (e) {
|
|
390
|
+
reject(new Error('Invalid response'));
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}).on('error', reject);
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
if (!latestVersions.plugins) {
|
|
397
|
+
error('Failed to fetch version info');
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Check if we're in a WordPress context (wp or studio available)
|
|
402
|
+
const hasWpCli = commandExists('wp');
|
|
403
|
+
const hasStudio = commandExists('studio');
|
|
404
|
+
const inWordPress = hasWpCli || hasStudio;
|
|
405
|
+
|
|
406
|
+
// Get installed versions if in WordPress context
|
|
407
|
+
let installedVersions = {};
|
|
408
|
+
if (inWordPress) {
|
|
409
|
+
try {
|
|
410
|
+
const cmd = hasStudio ? 'studio wp plugin list --format=json' : 'wp plugin list --format=json';
|
|
411
|
+
const output = execSync(cmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] });
|
|
412
|
+
const plugins = JSON.parse(output);
|
|
413
|
+
|
|
414
|
+
for (const p of plugins) {
|
|
415
|
+
// Map WP plugin slugs to our slugs
|
|
416
|
+
if (p.name === 'skunk-crm' || p.name === 'skunkcrm') {
|
|
417
|
+
installedVersions['skunkcrm'] = p.version;
|
|
418
|
+
} else if (p.name === 'skunk-forms' || p.name === 'skunkforms') {
|
|
419
|
+
installedVersions['skunkforms'] = p.version;
|
|
420
|
+
} else if (p.name === 'skunk-pages' || p.name === 'skunkpages') {
|
|
421
|
+
installedVersions['skunkpages'] = p.version;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
} catch (e) {
|
|
425
|
+
// Couldn't get installed versions, that's ok
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
console.log(`${colors.bright}Plugin${colors.reset} ${colors.bright}Latest${colors.reset} ${inWordPress ? `${colors.bright}Installed${colors.reset}` : ''}`);
|
|
430
|
+
console.log('─'.repeat(inWordPress ? 50 : 30));
|
|
431
|
+
|
|
432
|
+
// Show free plugins
|
|
433
|
+
for (const [slug, info] of Object.entries(latestVersions.plugins)) {
|
|
434
|
+
if (info.type === 'free') {
|
|
435
|
+
const installed = installedVersions[slug];
|
|
436
|
+
const latestV = info.version;
|
|
437
|
+
|
|
438
|
+
let status = '';
|
|
439
|
+
if (installed) {
|
|
440
|
+
if (installed === latestV) {
|
|
441
|
+
status = `${colors.green}${installed}${colors.reset} ✓`;
|
|
442
|
+
} else {
|
|
443
|
+
status = `${colors.yellow}${installed}${colors.reset} → ${latestV}`;
|
|
444
|
+
}
|
|
445
|
+
} else if (inWordPress) {
|
|
446
|
+
status = `${colors.dim}not installed${colors.reset}`;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const padding = ' '.repeat(Math.max(0, 16 - slug.length));
|
|
450
|
+
const vPadding = ' '.repeat(Math.max(0, 10 - latestV.length));
|
|
451
|
+
console.log(`${slug}${padding}${latestV}${vPadding}${status}`);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
console.log('');
|
|
456
|
+
|
|
457
|
+
// Show if updates available
|
|
458
|
+
const hasUpdates = Object.entries(installedVersions).some(([slug, v]) => {
|
|
459
|
+
const latest = latestVersions.plugins[slug];
|
|
460
|
+
return latest && latest.version !== v;
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
if (hasUpdates) {
|
|
464
|
+
console.log(`${colors.yellow}Updates available!${colors.reset} Run:`);
|
|
465
|
+
console.log(` skunk install plugin <name>\n`);
|
|
466
|
+
} else if (Object.keys(installedVersions).length > 0) {
|
|
467
|
+
console.log(`${colors.green}All plugins up to date!${colors.reset}\n`);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
} catch (e) {
|
|
471
|
+
error('Failed to check versions: ' + e.message);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
476
|
+
// Versions - Simple version lookup
|
|
477
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
478
|
+
|
|
479
|
+
async function showVersions(plugin) {
|
|
480
|
+
const versionsUrl = 'https://skunkglobal.com/api/plugins/versions';
|
|
481
|
+
|
|
482
|
+
try {
|
|
483
|
+
const data = await new Promise((resolve, reject) => {
|
|
484
|
+
https.get(versionsUrl, { headers: { 'User-Agent': 'skunk-cli' } }, (res) => {
|
|
485
|
+
let body = '';
|
|
486
|
+
res.on('data', chunk => body += chunk);
|
|
487
|
+
res.on('end', () => {
|
|
488
|
+
try {
|
|
489
|
+
resolve(JSON.parse(body));
|
|
490
|
+
} catch (e) {
|
|
491
|
+
reject(new Error('Invalid response'));
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
}).on('error', reject);
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
if (!data.plugins) {
|
|
498
|
+
error('Failed to fetch versions');
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Single plugin lookup
|
|
503
|
+
if (plugin) {
|
|
504
|
+
// Normalize: skunkcrm, crm, skunk-crm all -> skunkcrm
|
|
505
|
+
const slug = plugin.replace(/^skunk-?/, '').toLowerCase();
|
|
506
|
+
const fullSlug = `skunk${slug}`;
|
|
507
|
+
|
|
508
|
+
const info = data.plugins[fullSlug] || data.plugins[slug];
|
|
509
|
+
|
|
510
|
+
if (info) {
|
|
511
|
+
console.log(info.version);
|
|
512
|
+
} else {
|
|
513
|
+
error(`Unknown plugin: ${plugin}`);
|
|
514
|
+
console.log(`\n${colors.dim}Available: skunkcrm, skunkforms, skunkpages${colors.reset}`);
|
|
515
|
+
}
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// All plugins
|
|
520
|
+
console.log('');
|
|
521
|
+
for (const [slug, info] of Object.entries(data.plugins)) {
|
|
522
|
+
if (info.type === 'free') {
|
|
523
|
+
console.log(`${info.name}: ${colors.cyan}${info.version}${colors.reset}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
console.log('');
|
|
527
|
+
|
|
528
|
+
} catch (e) {
|
|
529
|
+
error('Failed to fetch versions: ' + e.message);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
362
533
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
363
534
|
// Update
|
|
364
535
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -420,6 +591,9 @@ ${colors.bright}Usage:${colors.reset}
|
|
|
420
591
|
skunk list List installed skills
|
|
421
592
|
skunk available List available skills
|
|
422
593
|
skunk plugins List available plugins
|
|
594
|
+
skunk status Check plugin versions (+ compare if in WP site)
|
|
595
|
+
skunk versions Show latest versions of all plugins
|
|
596
|
+
skunk version <plugin> Show latest version of a specific plugin
|
|
423
597
|
skunk update Update CLI and refresh skills
|
|
424
598
|
skunk help Show this help
|
|
425
599
|
|