myaidev-method 0.3.2 → 0.3.4

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 (80) hide show
  1. package/.claude-plugin/plugin.json +52 -48
  2. package/DEV_WORKFLOW_GUIDE.md +6 -6
  3. package/MCP_INTEGRATION.md +4 -4
  4. package/README.md +81 -64
  5. package/TECHNICAL_ARCHITECTURE.md +112 -18
  6. package/USER_GUIDE.md +57 -40
  7. package/bin/cli.js +49 -127
  8. package/dist/mcp/gutenberg-converter.js +667 -413
  9. package/dist/mcp/wordpress-server.js +1558 -1181
  10. package/extension.json +3 -3
  11. package/package.json +2 -1
  12. package/skills/content-writer/SKILL.md +130 -178
  13. package/skills/infographic/SKILL.md +191 -0
  14. package/skills/myaidev-analyze/SKILL.md +242 -0
  15. package/skills/myaidev-analyze/agents/dependency-mapper-agent.md +236 -0
  16. package/skills/myaidev-analyze/agents/pattern-detector-agent.md +240 -0
  17. package/skills/myaidev-analyze/agents/structure-scanner-agent.md +171 -0
  18. package/skills/myaidev-analyze/agents/tech-profiler-agent.md +291 -0
  19. package/skills/myaidev-architect/SKILL.md +389 -0
  20. package/skills/myaidev-architect/agents/compliance-checker-agent.md +287 -0
  21. package/skills/myaidev-architect/agents/requirements-analyst-agent.md +194 -0
  22. package/skills/myaidev-architect/agents/system-designer-agent.md +315 -0
  23. package/skills/myaidev-coder/SKILL.md +291 -0
  24. package/skills/myaidev-coder/agents/implementer-agent.md +185 -0
  25. package/skills/myaidev-coder/agents/integration-agent.md +168 -0
  26. package/skills/myaidev-coder/agents/pattern-scanner-agent.md +161 -0
  27. package/skills/myaidev-coder/agents/self-reviewer-agent.md +168 -0
  28. package/skills/myaidev-debug/SKILL.md +308 -0
  29. package/skills/myaidev-debug/agents/fix-agent-debug.md +317 -0
  30. package/skills/myaidev-debug/agents/hypothesis-agent.md +226 -0
  31. package/skills/myaidev-debug/agents/investigator-agent.md +250 -0
  32. package/skills/myaidev-debug/agents/symptom-collector-agent.md +231 -0
  33. package/skills/myaidev-documenter/SKILL.md +194 -0
  34. package/skills/myaidev-documenter/agents/code-reader-agent.md +172 -0
  35. package/skills/myaidev-documenter/agents/doc-validator-agent.md +174 -0
  36. package/skills/myaidev-documenter/agents/doc-writer-agent.md +379 -0
  37. package/skills/myaidev-migrate/SKILL.md +300 -0
  38. package/skills/myaidev-migrate/agents/migration-planner-agent.md +237 -0
  39. package/skills/myaidev-migrate/agents/migration-writer-agent.md +248 -0
  40. package/skills/myaidev-migrate/agents/schema-analyzer-agent.md +190 -0
  41. package/skills/myaidev-performance/SKILL.md +270 -0
  42. package/skills/myaidev-performance/agents/benchmark-agent.md +281 -0
  43. package/skills/myaidev-performance/agents/optimizer-agent.md +277 -0
  44. package/skills/myaidev-performance/agents/profiler-agent.md +252 -0
  45. package/skills/myaidev-refactor/SKILL.md +296 -0
  46. package/skills/myaidev-refactor/agents/refactor-executor-agent.md +221 -0
  47. package/skills/myaidev-refactor/agents/refactor-planner-agent.md +213 -0
  48. package/skills/myaidev-refactor/agents/regression-guard-agent.md +242 -0
  49. package/skills/myaidev-refactor/agents/smell-detector-agent.md +233 -0
  50. package/skills/myaidev-reviewer/SKILL.md +385 -0
  51. package/skills/myaidev-reviewer/agents/auto-fixer-agent.md +238 -0
  52. package/skills/myaidev-reviewer/agents/code-analyst-agent.md +220 -0
  53. package/skills/myaidev-reviewer/agents/security-scanner-agent.md +262 -0
  54. package/skills/myaidev-tester/SKILL.md +331 -0
  55. package/skills/myaidev-tester/agents/coverage-analyst-agent.md +163 -0
  56. package/skills/myaidev-tester/agents/tdd-driver-agent.md +242 -0
  57. package/skills/myaidev-tester/agents/test-runner-agent.md +176 -0
  58. package/skills/myaidev-tester/agents/test-strategist-agent.md +154 -0
  59. package/skills/myaidev-tester/agents/test-writer-agent.md +242 -0
  60. package/skills/myaidev-workflow/SKILL.md +567 -0
  61. package/skills/myaidev-workflow/agents/analyzer-agent.md +317 -0
  62. package/skills/myaidev-workflow/agents/coordinator-agent.md +253 -0
  63. package/skills/security-auditor/SKILL.md +1 -1
  64. package/skills/skill-builder/SKILL.md +417 -0
  65. package/src/cli/commands/addon.js +146 -135
  66. package/src/cli/commands/auth.js +9 -1
  67. package/src/config/workflows.js +11 -6
  68. package/src/lib/ascii-banner.js +3 -3
  69. package/src/lib/update-manager.js +120 -61
  70. package/src/mcp/gutenberg-converter.js +667 -413
  71. package/src/mcp/wordpress-server.js +1558 -1181
  72. package/src/statusline/statusline.sh +279 -0
  73. package/src/templates/claude/CLAUDE.md +124 -0
  74. package/skills/sparc-architect/SKILL.md +0 -127
  75. package/skills/sparc-coder/SKILL.md +0 -90
  76. package/skills/sparc-documenter/SKILL.md +0 -155
  77. package/skills/sparc-reviewer/SKILL.md +0 -138
  78. package/skills/sparc-tester/SKILL.md +0 -100
  79. package/skills/sparc-workflow/SKILL.md +0 -130
  80. /package/{marketplace.json → .claude-plugin/marketplace.json} +0 -0
@@ -9,6 +9,11 @@ import { createHash } from 'crypto';
9
9
  * Handles intelligent updates with conflict resolution
10
10
  */
11
11
 
12
+ /** Pluralize helper: returns "1 file" or "N files" */
13
+ function pf(count) {
14
+ return `${count} file${count === 1 ? '' : 's'}`;
15
+ }
16
+
12
17
  /**
13
18
  * Display ASCII art branding banner
14
19
  */
@@ -234,7 +239,11 @@ export async function updateComponent(componentType, projectDir, cliType, source
234
239
  break;
235
240
  case 'mcp':
236
241
  targetDir = path.join(projectDir, `.${cliType}`, 'mcp');
237
- sourceSubDir = path.join(sourceDir, '.claude', 'mcp');
242
+ sourceSubDir = path.join(sourceDir, 'src', 'mcp');
243
+ break;
244
+ case 'config':
245
+ targetDir = path.join(projectDir, `.${cliType}`);
246
+ sourceSubDir = path.join(sourceDir, 'src', 'templates', 'claude');
238
247
  break;
239
248
  case 'docs':
240
249
  targetDir = projectDir;
@@ -417,6 +426,10 @@ async function getLineCount(filePath) {
417
426
  async function getComponentFiles(componentType, dir) {
418
427
  if (!await fs.pathExists(dir)) return [];
419
428
 
429
+ if (componentType === 'config') {
430
+ return ['CLAUDE.md'];
431
+ }
432
+
420
433
  if (componentType === 'docs') {
421
434
  return ['USER_GUIDE.md', 'PUBLISHING_GUIDE.md', 'COOLIFY_DEPLOYMENT.md', 'DEV_WORKFLOW_GUIDE.md',
422
435
  'MCP_INTEGRATION.md', 'WORDPRESS_ADMIN_SCRIPTS.md', 'TECHNICAL_ARCHITECTURE.md',
@@ -488,7 +501,11 @@ export async function generateChangeSummary(components, projectDir, cliType, sou
488
501
  break;
489
502
  case 'mcp':
490
503
  targetDir = path.join(projectDir, `.${cliType}`, 'mcp');
491
- sourceSubDir = path.join(sourceDir, '.claude', 'mcp');
504
+ sourceSubDir = path.join(sourceDir, 'src', 'mcp');
505
+ break;
506
+ case 'config':
507
+ targetDir = path.join(projectDir, `.${cliType}`);
508
+ sourceSubDir = path.join(sourceDir, 'src', 'templates', 'claude');
492
509
  break;
493
510
  case 'docs':
494
511
  targetDir = projectDir;
@@ -592,16 +609,41 @@ export function displayChangeSummary(summary, currentVersion, newVersion) {
592
609
  // Change summary
593
610
  console.log(chalk.cyan('║') + chalk.white.bold(' 📊 CHANGE SUMMARY'.padEnd(boxWidth)) + chalk.cyan('║'));
594
611
 
595
- const unchangedLine = ` ├─ ✅ Unchanged: ${summary.unchanged.length} files (auto-skip)`;
596
- const newLine = ` ├─ 🆕 New files: ${summary.new.length} files (auto-add)`;
597
- const modifiedLine = ` ├─ ⚠️ Modified: ${summary.modified.length} files (need decision)`;
598
- const deletedLine = ` └─ 🗑️ Removed: ${summary.deleted.length} files (optional delete)`;
612
+ const unchangedLine = ` ├─ ✅ Unchanged: ${pf(summary.unchanged.length)} (no action needed)`;
613
+ const newLine = ` ├─ 🆕 New: ${pf(summary.new.length)} (will be added)`;
614
+ const modifiedLine = ` ├─ ⚠️ Modified: ${pf(summary.modified.length)} (need decision)`;
615
+ const deletedLine = ` └─ 🗑️ Removed: ${pf(summary.deleted.length)} (optional cleanup)`;
599
616
 
600
617
  console.log(chalk.cyan('║') + chalk.gray(unchangedLine.padEnd(boxWidth)) + chalk.cyan('║'));
601
618
  console.log(chalk.cyan('║') + chalk.green(newLine.padEnd(boxWidth)) + chalk.cyan('║'));
602
619
  console.log(chalk.cyan('║') + chalk.yellow(modifiedLine.padEnd(boxWidth)) + chalk.cyan('║'));
603
620
  console.log(chalk.cyan('║') + chalk.red(deletedLine.padEnd(boxWidth)) + chalk.cyan('║'));
604
621
 
622
+ // Show new skills if any (users care about what's new)
623
+ const newSkills = summary.new
624
+ .filter(f => f.componentType === 'skills' && f.file.endsWith('SKILL.md'))
625
+ .map(f => f.file.split('/')[0]);
626
+ if (newSkills.length > 0) {
627
+ console.log(chalk.cyan('║') + ' '.repeat(boxWidth) + chalk.cyan('║'));
628
+ const newSkillsLabel = ` 🎯 New skills available:`;
629
+ console.log(chalk.cyan('║') + chalk.white.bold(newSkillsLabel.padEnd(boxWidth)) + chalk.cyan('║'));
630
+ // Wrap skill names into lines that fit the box (max ~63 chars per line)
631
+ const maxLineLen = boxWidth - 6; // " " prefix + 1 padding
632
+ let currentLine = '';
633
+ for (let i = 0; i < newSkills.length; i++) {
634
+ const separator = currentLine ? ', ' : '';
635
+ if ((currentLine + separator + newSkills[i]).length > maxLineLen) {
636
+ console.log(chalk.cyan('║') + chalk.green(` ${currentLine}`.padEnd(boxWidth)) + chalk.cyan('║'));
637
+ currentLine = newSkills[i];
638
+ } else {
639
+ currentLine += separator + newSkills[i];
640
+ }
641
+ }
642
+ if (currentLine) {
643
+ console.log(chalk.cyan('║') + chalk.green(` ${currentLine}`.padEnd(boxWidth)) + chalk.cyan('║'));
644
+ }
645
+ }
646
+
605
647
  // Show modified files by category if any
606
648
  if (summary.modified.length > 0) {
607
649
  console.log(chalk.cyan('║') + ' '.repeat(boxWidth) + chalk.cyan('║'));
@@ -612,7 +654,7 @@ export function displayChangeSummary(summary, currentVersion, newVersion) {
612
654
  if (data.modified.length === 0) continue;
613
655
 
614
656
  const catName = category.toUpperCase();
615
- const catLine = ` │ ${catName} (${data.modified.length} files)`;
657
+ const catLine = ` │ ${catName} (${pf(data.modified.length)})`;
616
658
  console.log(chalk.cyan('║') + chalk.white.bold(catLine.padEnd(boxWidth)) + chalk.cyan('║'));
617
659
 
618
660
  for (let i = 0; i < data.modified.length && i < 3; i++) {
@@ -708,7 +750,7 @@ export async function promptCategoryDecision(category, files) {
708
750
  const botBorder = '╚' + '═'.repeat(boxWidth) + '╝';
709
751
 
710
752
  console.log(chalk.cyan(topBorder));
711
- console.log(chalk.cyan('║') + chalk.white.bold(` ${category.toUpperCase()} (${files.length} modified files)`.padEnd(boxWidth)) + chalk.cyan('║'));
753
+ console.log(chalk.cyan('║') + chalk.white.bold(` ${category.toUpperCase()} (${pf(files.length)} modified)`.padEnd(boxWidth)) + chalk.cyan('║'));
712
754
  console.log(chalk.cyan(midBorder));
713
755
 
714
756
  for (let i = 0; i < files.length; i++) {
@@ -730,9 +772,9 @@ export async function promptCategoryDecision(category, files) {
730
772
  name: 'decision',
731
773
  message: `What would you like to do with ${category.toUpperCase()}?`,
732
774
  choices: [
733
- { name: `Keep all my customizations (skip ${files.length} files)`, value: 'keep' },
734
- { name: `Update all (replace ${files.length} files, backup originals)`, value: 'update' },
735
- { name: `Review these ${files.length} files individually`, value: 'individual' }
775
+ { name: `Keep all my customizations (skip ${pf(files.length)})`, value: 'keep' },
776
+ { name: `Update all (replace ${pf(files.length)}, backup originals)`, value: 'update' },
777
+ { name: `Review ${files.length === 1 ? 'this file' : `these ${files.length} files`} individually`, value: 'individual' }
736
778
  ]
737
779
  }
738
780
  ]);
@@ -755,32 +797,24 @@ export async function executeSmartUpdate(summary, backupDir, options = {}) {
755
797
  backedUp: []
756
798
  };
757
799
 
758
- // Add all new files
800
+ // Add all new files — always show progress
759
801
  for (const f of summary.new) {
760
802
  await fs.ensureDir(path.dirname(f.targetPath));
761
803
  await fs.copy(f.sourcePath, f.targetPath);
762
804
  results.added.push(f.file);
763
- if (options.verbose) {
764
- console.log(chalk.green(` ➕ ${f.file} (new)`));
765
- }
805
+ console.log(chalk.green(` ➕ ${f.file}`));
766
806
  }
767
807
 
768
- // Keep all modified files (smart = preserve customizations)
808
+ // Keep all modified files (smart = preserve customizations) — always show
769
809
  for (const f of summary.modified) {
770
- // Create backup
771
810
  const backupPath = path.join(backupDir, f.componentType, f.file);
772
811
  await fs.ensureDir(path.dirname(backupPath));
773
812
  await fs.copy(f.targetPath, backupPath);
774
813
  results.backedUp.push(f.file);
775
814
  results.kept.push(f.file);
776
- if (options.verbose) {
777
- console.log(chalk.gray(` 🛡️ ${f.file} (kept, backup created)`));
778
- }
815
+ console.log(chalk.gray(` 🛡️ ${f.file} (kept, backup created)`));
779
816
  }
780
817
 
781
- // Update unchanged files (they're identical so no-op, but count them)
782
- results.updated = summary.unchanged.map(f => f.file);
783
-
784
818
  return results;
785
819
  }
786
820
 
@@ -799,30 +833,24 @@ export async function executeAcceptAll(summary, backupDir, options = {}) {
799
833
  backedUp: []
800
834
  };
801
835
 
802
- // Add all new files
836
+ // Add all new files — always show progress
803
837
  for (const f of summary.new) {
804
838
  await fs.ensureDir(path.dirname(f.targetPath));
805
839
  await fs.copy(f.sourcePath, f.targetPath);
806
840
  results.added.push(f.file);
807
- if (options.verbose) {
808
- console.log(chalk.green(` ➕ ${f.file} (new)`));
809
- }
841
+ console.log(chalk.green(` ➕ ${f.file}`));
810
842
  }
811
843
 
812
- // Replace all modified files with backups
844
+ // Replace all modified files with backups — always show progress
813
845
  for (const f of summary.modified) {
814
- // Create backup
815
846
  const backupPath = path.join(backupDir, f.componentType, f.file);
816
847
  await fs.ensureDir(path.dirname(backupPath));
817
848
  await fs.copy(f.targetPath, backupPath);
818
849
  results.backedUp.push(f.file);
819
850
 
820
- // Replace with new version
821
851
  await fs.copy(f.sourcePath, f.targetPath);
822
852
  results.updated.push(f.file);
823
- if (options.verbose) {
824
- console.log(chalk.blue(` ✅ ${f.file} (updated, backup created)`));
825
- }
853
+ console.log(chalk.blue(` ✅ ${f.file} (updated)`));
826
854
  }
827
855
 
828
856
  return results;
@@ -842,22 +870,18 @@ export async function executeKeepAll(summary, options = {}) {
842
870
  backedUp: []
843
871
  };
844
872
 
845
- // Add all new files
873
+ // Add all new files — always show progress
846
874
  for (const f of summary.new) {
847
875
  await fs.ensureDir(path.dirname(f.targetPath));
848
876
  await fs.copy(f.sourcePath, f.targetPath);
849
877
  results.added.push(f.file);
850
- if (options.verbose) {
851
- console.log(chalk.green(` ➕ ${f.file} (new)`));
852
- }
878
+ console.log(chalk.green(` ➕ ${f.file}`));
853
879
  }
854
880
 
855
- // Keep all modified files
881
+ // Keep all modified files — always show
856
882
  results.kept = summary.modified.map(f => f.file);
857
- if (options.verbose) {
858
- for (const f of summary.modified) {
859
- console.log(chalk.gray(` 🛡️ ${f.file} (kept)`));
860
- }
883
+ for (const f of summary.modified) {
884
+ console.log(chalk.gray(` 🛡️ ${f.file} (kept)`));
861
885
  }
862
886
 
863
887
  return results;
@@ -958,34 +982,69 @@ export function displayUpdateResults(results, backupDir, newVersion) {
958
982
  console.log(chalk.green('║') + chalk.white.bold(' ✅ Update Complete! '.padEnd(boxWidth)) + chalk.green('║'));
959
983
  console.log(chalk.green(midBorder));
960
984
 
961
- console.log(chalk.green('║') + chalk.white.bold(' 📊 Results:'.padEnd(boxWidth)) + chalk.green('║'));
985
+ const totalChanges = results.updated.length + results.added.length + results.kept.length;
962
986
 
963
- if (results.updated.length > 0) {
964
- const line = ` ├─ Updated: ${results.updated.length} files`;
965
- console.log(chalk.green('║') + chalk.blue(line.padEnd(boxWidth)) + chalk.green('║'));
966
- }
987
+ if (totalChanges === 0) {
988
+ console.log(chalk.green('║') + chalk.white(' Everything is already current — no changes needed.'.padEnd(boxWidth)) + chalk.green('║'));
989
+ } else {
990
+ console.log(chalk.green('║') + chalk.white.bold(' 📊 Results:'.padEnd(boxWidth)) + chalk.green('║'));
967
991
 
968
- if (results.kept.length > 0) {
969
- const line = ` ├─ Kept: ${results.kept.length} files (your customizations preserved)`;
970
- console.log(chalk.green('') + chalk.gray(line.padEnd(boxWidth)) + chalk.green('║'));
971
- }
992
+ const lines = [];
993
+ if (results.updated.length > 0) {
994
+ lines.push({ color: 'blue', text: `Updated: ${pf(results.updated.length)}` });
995
+ }
996
+ if (results.kept.length > 0) {
997
+ lines.push({ color: 'gray', text: `Kept: ${pf(results.kept.length)} (your customizations preserved)` });
998
+ }
999
+ if (results.added.length > 0) {
1000
+ lines.push({ color: 'green', text: `Added: ${pf(results.added.length)}` });
1001
+ }
1002
+ if (results.backedUp.length > 0) {
1003
+ const relativePath = path.relative(process.cwd(), backupDir);
1004
+ lines.push({ color: 'yellow', text: `Backed up: ${pf(results.backedUp.length)} → ${relativePath}/` });
1005
+ }
972
1006
 
973
- if (results.added.length > 0) {
974
- const line = ` ├─ Added: ${results.added.length} new files`;
975
- console.log(chalk.green('║') + chalk.green(line.padEnd(boxWidth)) + chalk.green('║'));
976
- }
1007
+ for (let i = 0; i < lines.length; i++) {
1008
+ const prefix = i === lines.length - 1 ? '└─' : '├─';
1009
+ const line = ` ${prefix} ${lines[i].text}`;
1010
+ console.log(chalk.green('║') + chalk[lines[i].color](line.padEnd(boxWidth)) + chalk.green('║'));
1011
+ }
977
1012
 
978
- if (results.backedUp.length > 0) {
979
- const relativePath = path.relative(process.cwd(), backupDir);
980
- const line = ` └─ Backed up: ${results.backedUp.length} files → ${relativePath}/`;
981
- console.log(chalk.green('║') + chalk.yellow(line.padEnd(boxWidth)) + chalk.green(''));
1013
+ // Show new skills that were added
1014
+ const newSkills = results.added
1015
+ .filter(f => f.endsWith('SKILL.md'))
1016
+ .map(f => f.split('/')[0]);
1017
+ if (newSkills.length > 0) {
1018
+ console.log(chalk.green('║') + ' '.repeat(boxWidth) + chalk.green('║'));
1019
+ const label = ` 🎯 New skills installed:`;
1020
+ console.log(chalk.green('║') + chalk.white.bold(label.padEnd(boxWidth)) + chalk.green('║'));
1021
+ const maxLineLen = boxWidth - 6;
1022
+ let currentLine = '';
1023
+ for (let i = 0; i < newSkills.length; i++) {
1024
+ const separator = currentLine ? ', ' : '';
1025
+ if ((currentLine + separator + newSkills[i]).length > maxLineLen) {
1026
+ console.log(chalk.green('║') + chalk.cyan(` ${currentLine}`.padEnd(boxWidth)) + chalk.green('║'));
1027
+ currentLine = newSkills[i];
1028
+ } else {
1029
+ currentLine += separator + newSkills[i];
1030
+ }
1031
+ }
1032
+ if (currentLine) {
1033
+ console.log(chalk.green('║') + chalk.cyan(` ${currentLine}`.padEnd(boxWidth)) + chalk.green('║'));
1034
+ }
1035
+ }
982
1036
  }
983
1037
 
984
1038
  console.log(chalk.green('║') + ' '.repeat(boxWidth) + chalk.green('║'));
985
1039
 
986
- // What's new section
1040
+ // Version and next steps
987
1041
  console.log(chalk.green('║') + chalk.white.bold(` 🆕 Updated to v${newVersion}`.padEnd(boxWidth)) + chalk.green('║'));
988
- console.log(chalk.green('║') + chalk.gray(' Run /myai-configure --status to see your configuration'.padEnd(boxWidth)) + chalk.green('║'));
1042
+
1043
+ // Only show restart reminder if skills were actually changed
1044
+ const skillsChanged = results.added.some(f => f.includes('/')) || results.updated.some(f => f.includes('/'));
1045
+ if (skillsChanged) {
1046
+ console.log(chalk.green('║') + chalk.yellow(' ⚠️ Restart your AI assistant to load updated skills'.padEnd(boxWidth)) + chalk.green('║'));
1047
+ }
989
1048
 
990
1049
  console.log(chalk.green(botBorder));
991
1050
  console.log('');