@polymorphism-tech/morph-spec 3.0.0 → 3.0.1

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 (160) hide show
  1. package/CLAUDE.md +75 -371
  2. package/LICENSE +72 -72
  3. package/bin/detect-agents.js +225 -225
  4. package/bin/render-template.js +302 -302
  5. package/bin/semantic-detect-agents.js +246 -246
  6. package/bin/validate-agents-skills.js +251 -251
  7. package/bin/validate-agents.js +69 -69
  8. package/bin/validate-phase.js +263 -263
  9. package/content/.azure/README.md +293 -293
  10. package/content/.azure/docs/azure-devops-setup.md +454 -454
  11. package/content/.azure/docs/branch-strategy.md +398 -398
  12. package/content/.azure/docs/local-development.md +515 -515
  13. package/content/.azure/pipelines/pipeline-variables.yml +34 -34
  14. package/content/.azure/pipelines/prod-pipeline.yml +319 -319
  15. package/content/.azure/pipelines/staging-pipeline.yml +234 -234
  16. package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
  17. package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
  18. package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
  19. package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
  20. package/content/.claude/commands/morph-archive.md +79 -79
  21. package/content/.claude/commands/morph-deploy.md +529 -529
  22. package/content/.claude/commands/morph-infra.md +209 -209
  23. package/content/.claude/commands/morph-preflight.md +227 -227
  24. package/content/.claude/commands/morph-troubleshoot.md +122 -122
  25. package/content/.claude/settings.local.json +15 -15
  26. package/content/.claude/skills/{specialists → level-2-domains/architecture}/prompt-engineer.md +189 -189
  27. package/content/.claude/skills/{specialists → level-2-domains/architecture}/seo-growth-hacker.md +320 -320
  28. package/content/.claude/skills/{infra → level-2-domains/infrastructure}/azure-deploy-specialist.md +699 -699
  29. package/content/.morph/.morphversion +5 -5
  30. package/content/.morph/archive/.gitkeep +25 -25
  31. package/content/.morph/config/agents.json +7 -5
  32. package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
  33. package/content/.morph/examples/api-nextjs/README.md +241 -241
  34. package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
  35. package/content/.morph/examples/api-nextjs/spec.md +399 -399
  36. package/content/.morph/examples/api-nextjs/tasks.md +168 -168
  37. package/content/.morph/examples/micro-saas/README.md +125 -125
  38. package/content/.morph/examples/micro-saas/contracts.cs +358 -358
  39. package/content/.morph/examples/micro-saas/decisions.md +246 -246
  40. package/content/.morph/examples/micro-saas/spec.md +236 -236
  41. package/content/.morph/examples/micro-saas/tasks.md +150 -150
  42. package/content/.morph/examples/multi-agent/README.md +309 -309
  43. package/content/.morph/examples/multi-agent/contracts.cs +433 -433
  44. package/content/.morph/examples/multi-agent/spec.md +479 -479
  45. package/content/.morph/examples/multi-agent/tasks.md +185 -185
  46. package/content/.morph/examples/state-v3.json +188 -188
  47. package/content/.morph/features/.gitkeep +25 -25
  48. package/content/.morph/hooks/pre-commit-all.sh +48 -48
  49. package/content/.morph/hooks/pre-commit-specs.sh +49 -49
  50. package/content/.morph/hooks/pre-commit-tests.sh +60 -60
  51. package/content/.morph/project.md +160 -160
  52. package/content/.morph/schemas/agent.schema.json +296 -296
  53. package/content/.morph/specs/.gitkeep +20 -20
  54. package/content/.morph/standards/coding.md +377 -377
  55. package/content/.morph/standards/fluent-ui-setup.md +590 -590
  56. package/content/.morph/standards/migration-guide.md +514 -514
  57. package/content/.morph/standards/passkeys-auth.md +423 -423
  58. package/content/.morph/standards/vector-search-rag.md +536 -536
  59. package/content/.morph/state.json +17 -17
  60. package/content/.morph/templates/FluentDesignTheme.cs +149 -149
  61. package/content/.morph/templates/MudTheme.cs +281 -281
  62. package/content/.morph/templates/component.razor +239 -239
  63. package/content/.morph/templates/contracts.cs +217 -217
  64. package/content/.morph/templates/design-system.css +226 -226
  65. package/content/.morph/templates/infra/.dockerignore.example +89 -89
  66. package/content/.morph/templates/infra/Dockerfile.example +82 -82
  67. package/content/.morph/templates/infra/README.md +286 -286
  68. package/content/.morph/templates/infra/app-insights.bicep +63 -63
  69. package/content/.morph/templates/infra/app-service.bicep +164 -164
  70. package/content/.morph/templates/infra/azure-pipelines-deploy.yml +480 -480
  71. package/content/.morph/templates/infra/container-app-env.bicep +49 -49
  72. package/content/.morph/templates/infra/container-app.bicep +156 -156
  73. package/content/.morph/templates/infra/deploy-checklist.md +426 -426
  74. package/content/.morph/templates/infra/deploy.ps1 +229 -229
  75. package/content/.morph/templates/infra/deploy.sh +208 -208
  76. package/content/.morph/templates/infra/key-vault.bicep +91 -91
  77. package/content/.morph/templates/infra/main.bicep +189 -189
  78. package/content/.morph/templates/infra/parameters.dev.json +29 -29
  79. package/content/.morph/templates/infra/parameters.prod.json +29 -29
  80. package/content/.morph/templates/infra/parameters.staging.json +29 -29
  81. package/content/.morph/templates/infra/sql-database.bicep +103 -103
  82. package/content/.morph/templates/infra/storage.bicep +106 -106
  83. package/content/.morph/templates/integrations/asaas-client.cs +387 -387
  84. package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
  85. package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
  86. package/content/.morph/templates/integrations/clerk-config.cs +258 -258
  87. package/content/.morph/templates/job.cs +171 -171
  88. package/content/.morph/templates/migration.cs +83 -83
  89. package/content/.morph/templates/repository.cs +141 -141
  90. package/content/.morph/templates/saas/subscription.cs +347 -347
  91. package/content/.morph/templates/saas/tenant.cs +338 -338
  92. package/content/.morph/templates/service.cs +139 -139
  93. package/content/.morph/templates/sprint-status.yaml +68 -68
  94. package/content/.morph/templates/story.md +143 -143
  95. package/content/.morph/templates/test.cs +239 -239
  96. package/content/.morph/templates/ui-design-system.md +286 -286
  97. package/content/.morph/templates/ui-flows.md +336 -336
  98. package/content/.morph/templates/ui-mockups.md +133 -133
  99. package/content/.morph/test-infra/example.bicep +59 -59
  100. package/content/README.md +79 -79
  101. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
  102. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
  103. package/docs/api/scripts/collapse.js +38 -38
  104. package/docs/api/scripts/commonNav.js +28 -28
  105. package/docs/api/scripts/linenumber.js +25 -25
  106. package/docs/api/scripts/nav.js +12 -12
  107. package/docs/api/scripts/polyfill.js +3 -3
  108. package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
  109. package/docs/api/scripts/prettify/lang-css.js +2 -2
  110. package/docs/api/scripts/prettify/prettify.js +28 -28
  111. package/docs/api/scripts/search.js +98 -98
  112. package/docs/api/styles/jsdoc.css +776 -776
  113. package/docs/api/styles/prettify.css +80 -80
  114. package/docs/examples.md +328 -328
  115. package/docs/templates.md +418 -418
  116. package/package.json +1 -2
  117. package/scripts/postinstall.js +132 -132
  118. package/scripts/reorganize-skills.cjs +175 -0
  119. package/scripts/validate-agents-structure.cjs +52 -0
  120. package/scripts/validate-skills.cjs +180 -0
  121. package/src/commands/analyze-blazor-concurrency.js +193 -193
  122. package/src/commands/create-story.js +351 -351
  123. package/src/commands/deploy.js +780 -780
  124. package/src/commands/detect-agents.js +9 -0
  125. package/src/commands/detect.js +104 -104
  126. package/src/commands/generate.js +149 -149
  127. package/src/commands/lint-fluent.js +352 -352
  128. package/src/commands/rollback-phase.js +185 -185
  129. package/src/commands/session-summary.js +291 -291
  130. package/src/commands/shard-spec.js +224 -224
  131. package/src/commands/sprint-status.js +250 -250
  132. package/src/commands/state.js +334 -333
  133. package/src/commands/sync.js +167 -167
  134. package/src/commands/troubleshoot.js +222 -222
  135. package/src/commands/update.js +13 -1
  136. package/src/commands/validate-blazor-state.js +210 -210
  137. package/src/commands/validate-blazor.js +156 -156
  138. package/src/commands/validate-css.js +84 -84
  139. package/src/commands/validate-phase.js +221 -221
  140. package/src/lib/blazor-concurrency-analyzer.js +288 -288
  141. package/src/lib/blazor-state-validator.js +291 -291
  142. package/src/lib/blazor-validator.js +374 -374
  143. package/src/lib/css-validator.js +352 -352
  144. package/src/lib/design-system-generator.js +298 -298
  145. package/{detectors → src/lib/detectors}/config-detector.js +223 -223
  146. package/{detectors → src/lib/detectors}/conversation-analyzer.js +163 -163
  147. package/{detectors → src/lib/detectors}/index.js +84 -84
  148. package/{detectors → src/lib/detectors}/standards-generator.js +275 -275
  149. package/src/lib/learning-system.js +520 -520
  150. package/src/lib/mockup-generator.js +366 -366
  151. package/src/lib/state-manager.js +21 -4
  152. package/src/lib/troubleshoot-grep.js +194 -194
  153. package/src/lib/troubleshoot-index.js +144 -144
  154. package/src/lib/ui-detector.js +350 -350
  155. package/src/lib/validators/architecture-validator.js +387 -387
  156. package/src/lib/validators/package-validator.js +360 -360
  157. package/src/lib/validators/ui-contrast-validator.js +422 -422
  158. package/src/utils/logger.js +32 -32
  159. package/src/utils/version-checker.js +175 -175
  160. /package/{detectors → src/lib/detectors}/structure-detector.js +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polymorphism-tech/morph-spec",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "MORPH-SPEC v2.0: AI-First development framework with .NET 10, Microsoft Agent Framework, and Fluent UI Blazor",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -27,7 +27,6 @@
27
27
  "bin/",
28
28
  "src/",
29
29
  "scripts/",
30
- "detectors/",
31
30
  "content/",
32
31
  "docs/",
33
32
  "README.md",
@@ -1,132 +1,132 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Postinstall script for @polymorphism-tech/morph-spec
5
- *
6
- * Checks if morph-spec is accessible in PATH and warns users
7
- * if it's not (common issue with nvm-windows).
8
- */
9
-
10
- import { execSync } from 'child_process';
11
- import { platform } from 'os';
12
- import chalk from 'chalk';
13
-
14
- const isWindows = platform() === 'win32';
15
-
16
- /**
17
- * Check if morph-spec command is in PATH
18
- */
19
- function isMorphSpecInPath() {
20
- try {
21
- const command = isWindows ? 'where morph-spec' : 'which morph-spec';
22
- execSync(command, { stdio: 'ignore' });
23
- return true;
24
- } catch {
25
- return false;
26
- }
27
- }
28
-
29
- /**
30
- * Detect if nvm-windows is installed
31
- */
32
- function isUsingNvmWindows() {
33
- if (!isWindows) return false;
34
-
35
- try {
36
- const path = process.env.PATH || '';
37
- return path.includes('nvm4w') || path.includes('\\nvm\\');
38
- } catch {
39
- return false;
40
- }
41
- }
42
-
43
- /**
44
- * Get npm global prefix
45
- */
46
- function getNpmGlobalPrefix() {
47
- try {
48
- const prefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
49
- return prefix;
50
- } catch {
51
- return null;
52
- }
53
- }
54
-
55
- /**
56
- * Show installation success message
57
- */
58
- function showSuccessMessage() {
59
- console.log('');
60
- console.log(chalk.green('✓ @polymorphism-tech/morph-spec installed successfully!'));
61
- console.log('');
62
- console.log(chalk.cyan('Quick start:'));
63
- console.log(chalk.white(' morph-spec init'));
64
- console.log(chalk.white(' morph-spec --help'));
65
- console.log('');
66
- }
67
-
68
- /**
69
- * Show PATH warning for nvm-windows users
70
- */
71
- function showPathWarning() {
72
- console.log('');
73
- console.log(chalk.yellow('⚠ Warning: morph-spec command not found in PATH'));
74
- console.log('');
75
-
76
- if (isUsingNvmWindows()) {
77
- console.log(chalk.white('You are using nvm-windows, which does not automatically add'));
78
- console.log(chalk.white('npm global packages to your PATH.'));
79
- console.log('');
80
- console.log(chalk.cyan('Solution 1: Add npm global directory to PATH'));
81
-
82
- const prefix = getNpmGlobalPrefix();
83
- if (prefix) {
84
- console.log(chalk.white(` Add this to your PATH: ${chalk.yellow(prefix)}`));
85
- console.log('');
86
- console.log(chalk.gray(' PowerShell (as Administrator):'));
87
- console.log(chalk.white(` [Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";${prefix}", "User")`));
88
- console.log('');
89
- console.log(chalk.gray(' Or manually via System Properties > Environment Variables'));
90
- }
91
-
92
- console.log('');
93
- console.log(chalk.cyan('Solution 2: Use npx (recommended)'));
94
- console.log(chalk.white(' npx @polymorphism-tech/morph-spec init'));
95
- console.log(chalk.white(' npx @polymorphism-tech/morph-spec --help'));
96
- } else {
97
- console.log(chalk.white('The morph-spec command was not found in your PATH.'));
98
- console.log('');
99
- console.log(chalk.cyan('Solution: Use npx instead'));
100
- console.log(chalk.white(' npx @polymorphism-tech/morph-spec init'));
101
- console.log(chalk.white(' npx @polymorphism-tech/morph-spec --help'));
102
- }
103
-
104
- console.log('');
105
- console.log(chalk.gray('For more help, see: https://github.com/lucasPolymorphism/morph-spec-framework#troubleshooting'));
106
- console.log('');
107
- }
108
-
109
- /**
110
- * Main postinstall check
111
- */
112
- function main() {
113
- // Only show messages for global installs
114
- // Skip for local installs (when used as dependency)
115
- const isGlobalInstall = process.env.npm_config_global === 'true';
116
-
117
- if (!isGlobalInstall) {
118
- // Silent exit for local installs
119
- return;
120
- }
121
-
122
- // Give npm a moment to set up the symlinks
123
- setTimeout(() => {
124
- if (isMorphSpecInPath()) {
125
- showSuccessMessage();
126
- } else {
127
- showPathWarning();
128
- }
129
- }, 100);
130
- }
131
-
132
- main();
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Postinstall script for @polymorphism-tech/morph-spec
5
+ *
6
+ * Checks if morph-spec is accessible in PATH and warns users
7
+ * if it's not (common issue with nvm-windows).
8
+ */
9
+
10
+ import { execSync } from 'child_process';
11
+ import { platform } from 'os';
12
+ import chalk from 'chalk';
13
+
14
+ const isWindows = platform() === 'win32';
15
+
16
+ /**
17
+ * Check if morph-spec command is in PATH
18
+ */
19
+ function isMorphSpecInPath() {
20
+ try {
21
+ const command = isWindows ? 'where morph-spec' : 'which morph-spec';
22
+ execSync(command, { stdio: 'ignore' });
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Detect if nvm-windows is installed
31
+ */
32
+ function isUsingNvmWindows() {
33
+ if (!isWindows) return false;
34
+
35
+ try {
36
+ const path = process.env.PATH || '';
37
+ return path.includes('nvm4w') || path.includes('\\nvm\\');
38
+ } catch {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Get npm global prefix
45
+ */
46
+ function getNpmGlobalPrefix() {
47
+ try {
48
+ const prefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
49
+ return prefix;
50
+ } catch {
51
+ return null;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Show installation success message
57
+ */
58
+ function showSuccessMessage() {
59
+ console.log('');
60
+ console.log(chalk.green('✓ @polymorphism-tech/morph-spec installed successfully!'));
61
+ console.log('');
62
+ console.log(chalk.cyan('Quick start:'));
63
+ console.log(chalk.white(' morph-spec init'));
64
+ console.log(chalk.white(' morph-spec --help'));
65
+ console.log('');
66
+ }
67
+
68
+ /**
69
+ * Show PATH warning for nvm-windows users
70
+ */
71
+ function showPathWarning() {
72
+ console.log('');
73
+ console.log(chalk.yellow('⚠ Warning: morph-spec command not found in PATH'));
74
+ console.log('');
75
+
76
+ if (isUsingNvmWindows()) {
77
+ console.log(chalk.white('You are using nvm-windows, which does not automatically add'));
78
+ console.log(chalk.white('npm global packages to your PATH.'));
79
+ console.log('');
80
+ console.log(chalk.cyan('Solution 1: Add npm global directory to PATH'));
81
+
82
+ const prefix = getNpmGlobalPrefix();
83
+ if (prefix) {
84
+ console.log(chalk.white(` Add this to your PATH: ${chalk.yellow(prefix)}`));
85
+ console.log('');
86
+ console.log(chalk.gray(' PowerShell (as Administrator):'));
87
+ console.log(chalk.white(` [Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";${prefix}", "User")`));
88
+ console.log('');
89
+ console.log(chalk.gray(' Or manually via System Properties > Environment Variables'));
90
+ }
91
+
92
+ console.log('');
93
+ console.log(chalk.cyan('Solution 2: Use npx (recommended)'));
94
+ console.log(chalk.white(' npx @polymorphism-tech/morph-spec init'));
95
+ console.log(chalk.white(' npx @polymorphism-tech/morph-spec --help'));
96
+ } else {
97
+ console.log(chalk.white('The morph-spec command was not found in your PATH.'));
98
+ console.log('');
99
+ console.log(chalk.cyan('Solution: Use npx instead'));
100
+ console.log(chalk.white(' npx @polymorphism-tech/morph-spec init'));
101
+ console.log(chalk.white(' npx @polymorphism-tech/morph-spec --help'));
102
+ }
103
+
104
+ console.log('');
105
+ console.log(chalk.gray('For more help, see: https://github.com/lucasPolymorphism/morph-spec-framework#troubleshooting'));
106
+ console.log('');
107
+ }
108
+
109
+ /**
110
+ * Main postinstall check
111
+ */
112
+ function main() {
113
+ // Only show messages for global installs
114
+ // Skip for local installs (when used as dependency)
115
+ const isGlobalInstall = process.env.npm_config_global === 'true';
116
+
117
+ if (!isGlobalInstall) {
118
+ // Silent exit for local installs
119
+ return;
120
+ }
121
+
122
+ // Give npm a moment to set up the symlinks
123
+ setTimeout(() => {
124
+ if (isMorphSpecInPath()) {
125
+ showSuccessMessage();
126
+ } else {
127
+ showPathWarning();
128
+ }
129
+ }, 100);
130
+ }
131
+
132
+ main();
@@ -0,0 +1,175 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ // Define new 5-level structure with mapping
5
+ const skillMapping = {
6
+ // Level 0: Meta-Skills (user-facing, high-level orchestration)
7
+ 'level-0-meta': [
8
+ 'checklists/morph-checklist.md',
9
+ 'checklists/simulation-checklist.md',
10
+ 'checklists/code-review.md'
11
+ ],
12
+
13
+ // Level 1: Workflows (phase orchestration)
14
+ 'level-1-workflows': [
15
+ 'workflows/phase-setup.md',
16
+ 'workflows/phase-uiux.md',
17
+ 'workflows/phase-design.md',
18
+ 'workflows/phase-clarify.md',
19
+ 'workflows/phase-tasks.md',
20
+ 'workflows/morph-replicate.md'
21
+ ],
22
+
23
+ // Level 2: Domains (domain expertise - maps to squads)
24
+ 'level-2-domains/backend': [
25
+ 'specialists/dotnet-senior.md',
26
+ 'specialists/ef-modeler.md',
27
+ 'specialists/hangfire-orchestrator.md',
28
+ 'specialists/ms-agent-expert.md'
29
+ ],
30
+ 'level-2-domains/frontend': [
31
+ 'specialists/ui-ux-designer.md',
32
+ 'stacks/dotnet-blazor.md',
33
+ 'stacks/dotnet-nextjs.md'
34
+ ],
35
+ 'level-2-domains/infrastructure': [
36
+ 'specialists/azure-architect.md',
37
+ 'infra/bicep-architect.md',
38
+ 'infra/devops-engineer.md',
39
+ 'infra/container-specialist.md'
40
+ ],
41
+ 'level-2-domains/quality': [
42
+ 'specialists/testing-specialist.md',
43
+ 'specialists/code-analyzer.md'
44
+ ],
45
+ 'level-2-domains/ai-agents': [
46
+ 'specialists/ai-system-architect.md'
47
+ ],
48
+ 'level-2-domains/integrations': [
49
+ 'integrations/asaas-financial.md',
50
+ 'integrations/clerk-auth.md',
51
+ 'integrations/azure-identity.md',
52
+ 'integrations/resend-email.md'
53
+ ],
54
+ 'level-2-domains/architecture': [
55
+ 'specialists/standards-architect.md',
56
+ 'specialists/po-pm-advisor.md'
57
+ ],
58
+
59
+ // Level 3: Technologies (empty for now, will populate in Phase 8/9)
60
+ 'level-3-technologies': [],
61
+
62
+ // Level 4: Patterns (empty for now, will populate later)
63
+ 'level-4-patterns': []
64
+ };
65
+
66
+ const baseDir = 'content/.claude/skills';
67
+
68
+ // Create new directory structure
69
+ console.log('📁 Creating new 5-level directory structure...\n');
70
+ Object.keys(skillMapping).forEach(dir => {
71
+ const fullPath = path.join(baseDir, dir);
72
+ if (!fs.existsSync(fullPath)) {
73
+ fs.mkdirSync(fullPath, { recursive: true });
74
+ console.log(` ✅ Created: ${dir}`);
75
+ }
76
+ });
77
+
78
+ console.log('\n📦 Moving skill files...\n');
79
+
80
+ // Move files to new structure
81
+ let movedCount = 0;
82
+ Object.entries(skillMapping).forEach(([targetDir, files]) => {
83
+ files.forEach(relPath => {
84
+ const oldPath = path.join(baseDir, relPath);
85
+ const fileName = path.basename(relPath);
86
+ const newPath = path.join(baseDir, targetDir, fileName);
87
+
88
+ if (fs.existsSync(oldPath)) {
89
+ fs.copyFileSync(oldPath, newPath);
90
+ movedCount++;
91
+ console.log(` ✅ Moved: ${relPath} → ${targetDir}/${fileName}`);
92
+ } else {
93
+ console.log(` ⚠️ Not found: ${relPath}`);
94
+ }
95
+ });
96
+ });
97
+
98
+ console.log(`\n✅ Moved ${movedCount} skill files to new structure`);
99
+
100
+ // Create README files for each level
101
+ const readmes = {
102
+ 'level-0-meta/README.md': `# Level 0: Meta-Skills
103
+
104
+ High-level orchestration skills and user-facing commands.
105
+
106
+ **Purpose:** Skills that orchestrate multiple workflows or provide top-level guidance.
107
+
108
+ **Examples:** morph-checklist, simulation-checklist, code-review
109
+ `,
110
+
111
+ 'level-1-workflows/README.md': `# Level 1: Workflows
112
+
113
+ Phase orchestration and workflow management.
114
+
115
+ **Purpose:** Skills that implement MORPH workflow phases (FASE 0-6).
116
+
117
+ **Examples:** phase-setup, phase-design, phase-uiux
118
+ `,
119
+
120
+ 'level-2-domains/README.md': `# Level 2: Domains
121
+
122
+ Domain expertise skills organized by squad.
123
+
124
+ **Purpose:** Skills that provide deep domain knowledge (backend, frontend, infra, quality, ai-agents, integrations).
125
+
126
+ **Squads:**
127
+ - backend/ - Backend Squad (led by dotnet-senior)
128
+ - frontend/ - Frontend Squad (led by ui-designer)
129
+ - infrastructure/ - Infrastructure Squad (led by azure-architect)
130
+ - quality/ - Quality Squad (coordinated by standards-architect)
131
+ - ai-agents/ - AI/Agent specialists
132
+ - integrations/ - External integration specialists
133
+ - architecture/ - Architecture and planning
134
+ `,
135
+
136
+ 'level-3-technologies/README.md': `# Level 3: Technologies
137
+
138
+ Technology-specific implementation patterns.
139
+
140
+ **Purpose:** Skills for specific technologies (EF Core, Blazor, Hangfire, SignalR, etc.).
141
+
142
+ **To be populated in Phase 8/9.**
143
+ `,
144
+
145
+ 'level-4-patterns/README.md': `# Level 4: Patterns
146
+
147
+ Architectural and design patterns.
148
+
149
+ **Purpose:** Skills for specific patterns (CQRS, Event Sourcing, DDD, Repository, etc.).
150
+
151
+ **To be populated later.**
152
+ `
153
+ };
154
+
155
+ console.log('\n📝 Creating README files...\n');
156
+ Object.entries(readmes).forEach(([file, content]) => {
157
+ const fullPath = path.join(baseDir, file);
158
+ fs.writeFileSync(fullPath, content, 'utf8');
159
+ console.log(` ✅ Created: ${file}`);
160
+ });
161
+
162
+ console.log('\n✅ Phase 0, Day 2: Skill reorganization COMPLETE');
163
+ console.log('\nNew structure:');
164
+ console.log(' level-0-meta/ (3 files)');
165
+ console.log(' level-1-workflows/ (6 files)');
166
+ console.log(' level-2-domains/ (7 subdirs, 20 files)');
167
+ console.log(' ├── backend/ (4 files)');
168
+ console.log(' ├── frontend/ (3 files)');
169
+ console.log(' ├── infrastructure/ (4 files)');
170
+ console.log(' ├── quality/ (2 files)');
171
+ console.log(' ├── ai-agents/ (1 file)');
172
+ console.log(' ├── integrations/ (4 files)');
173
+ console.log(' └── architecture/ (2 files)');
174
+ console.log(' level-3-technologies/ (empty - Phase 8/9)');
175
+ console.log(' level-4-patterns/ (empty - later)');
@@ -0,0 +1,52 @@
1
+ const fs = require('fs');
2
+
3
+ const agents = JSON.parse(fs.readFileSync('content/.morph/config/agents.json', 'utf8'));
4
+
5
+ console.log('✅ Version:', agents.version);
6
+ console.log('✅ Total agents:', Object.keys(agents.agents || {}).length);
7
+ console.log('✅ Tiers breakdown:', JSON.stringify(agents.tiers, null, 2));
8
+
9
+ // Validate each agent has required fields
10
+ const requiredFields = ['tier', 'role', 'title', 'domains', 'keywords', 'always_active', 'validators', 'relationships', 'standards'];
11
+ const missing = [];
12
+
13
+ Object.entries(agents.agents || {}).forEach(([id, agent]) => {
14
+ if (id.startsWith('_comment')) return; // Skip comment entries
15
+
16
+ const agentMissing = requiredFields.filter(field => !(field in agent));
17
+ if (agentMissing.length > 0) {
18
+ missing.push({ id, missing: agentMissing });
19
+ }
20
+
21
+ // Validate relationships object
22
+ if (agent.relationships) {
23
+ const reqRelFields = ['reports_to', 'team_role'];
24
+ const relMissing = reqRelFields.filter(field => !(field in agent.relationships));
25
+ if (relMissing.length > 0) {
26
+ missing.push({ id, missing: relMissing.map(f => `relationships.${f}`) });
27
+ }
28
+ }
29
+ });
30
+
31
+ if (missing.length === 0) {
32
+ console.log('✅ All agents have required fields');
33
+ } else {
34
+ console.log('❌ Agents with missing fields:', missing.length);
35
+ missing.forEach(m => console.log(` - ${m.id}: missing ${m.missing.join(', ')}`));
36
+ }
37
+
38
+ // Count agents by tier
39
+ const tierCounts = { 1: 0, 2: 0, 3: 0, 4: 0 };
40
+ Object.entries(agents.agents || {}).forEach(([id, agent]) => {
41
+ if (!id.startsWith('_comment') && agent.tier) {
42
+ tierCounts[agent.tier]++;
43
+ }
44
+ });
45
+
46
+ console.log('\n✅ Agents per tier:');
47
+ console.log(' Tier 1 (Orchestrators):', tierCounts[1]);
48
+ console.log(' Tier 2 (Domain Leaders):', tierCounts[2]);
49
+ console.log(' Tier 3 (Specialists):', tierCounts[3]);
50
+ console.log(' Tier 4 (Validators):', tierCounts[4]);
51
+
52
+ console.log('\n✅ Phase 0, Day 1: COMPLETE - agents.json validated');
@@ -0,0 +1,180 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const skillsBase = 'content/.claude/skills';
5
+ const agentsPath = 'content/.morph/config/agents.json';
6
+
7
+ console.log('🧪 Validating MORPH 3.0 Skills Structure\n');
8
+
9
+ // Load agents.json
10
+ const agentsConfig = JSON.parse(fs.readFileSync(agentsPath, 'utf8'));
11
+
12
+ // Step 1: Verify 5-level directory structure
13
+ console.log('📁 Step 1: Verify 5-level directory structure');
14
+ const requiredDirs = [
15
+ 'level-0-meta',
16
+ 'level-1-workflows',
17
+ 'level-2-domains',
18
+ 'level-3-technologies',
19
+ 'level-4-patterns'
20
+ ];
21
+
22
+ const missingDirs = [];
23
+ requiredDirs.forEach(dir => {
24
+ const fullPath = path.join(skillsBase, dir);
25
+ if (!fs.existsSync(fullPath)) {
26
+ missingDirs.push(dir);
27
+ } else {
28
+ console.log(` ✅ ${dir}/`);
29
+ }
30
+ });
31
+
32
+ if (missingDirs.length > 0) {
33
+ console.log(` ❌ Missing directories: ${missingDirs.join(', ')}`);
34
+ }
35
+ console.log('');
36
+
37
+ // Step 2: Check level-2-domains subdirectories
38
+ console.log('📂 Step 2: Verify level-2-domains squads');
39
+ const requiredSquads = [
40
+ 'backend', 'frontend', 'infrastructure', 'quality',
41
+ 'ai-agents', 'integrations', 'architecture'
42
+ ];
43
+
44
+ const level2Path = path.join(skillsBase, 'level-2-domains');
45
+ const existingSquads = fs.readdirSync(level2Path)
46
+ .filter(item => {
47
+ const itemPath = path.join(level2Path, item);
48
+ return fs.statSync(itemPath).isDirectory();
49
+ });
50
+
51
+ requiredSquads.forEach(squad => {
52
+ if (existingSquads.includes(squad)) {
53
+ const squadPath = path.join(level2Path, squad);
54
+ const skillCount = fs.readdirSync(squadPath).filter(f => f.endsWith('.md')).length;
55
+ console.log(` ✅ ${squad}/ (${skillCount} skills)`);
56
+ } else {
57
+ console.log(` ❌ Missing: ${squad}/`);
58
+ }
59
+ });
60
+ console.log('');
61
+
62
+ // Step 3: Count all skill files
63
+ console.log('📄 Step 3: Count skill files');
64
+ function countSkills(dir) {
65
+ let count = 0;
66
+ const items = fs.readdirSync(dir);
67
+ items.forEach(item => {
68
+ const fullPath = path.join(dir, item);
69
+ const stat = fs.statSync(fullPath);
70
+ if (stat.isDirectory()) {
71
+ count += countSkills(fullPath);
72
+ } else if (item.endsWith('.md') && item !== 'README.md') {
73
+ count++;
74
+ }
75
+ });
76
+ return count;
77
+ }
78
+
79
+ const totalSkills = countSkills(skillsBase);
80
+ console.log(` ✅ Total skill files: ${totalSkills}`);
81
+ console.log('');
82
+
83
+ // Step 4: Verify no old directories remain
84
+ console.log('🗑️ Step 4: Verify old directories removed');
85
+ const oldDirs = ['specialists', 'stacks', 'integrations', 'infra', 'workflows', 'checklists'];
86
+ const remainingOldDirs = oldDirs.filter(dir => {
87
+ return fs.existsSync(path.join(skillsBase, dir));
88
+ });
89
+
90
+ if (remainingOldDirs.length > 0) {
91
+ console.log(` ❌ Old directories still exist: ${remainingOldDirs.join(', ')}`);
92
+ } else {
93
+ console.log(' ✅ All old directories removed');
94
+ }
95
+ console.log('');
96
+
97
+ // Step 5: Verify agents → skills mapping (sample of key agents)
98
+ console.log('🎯 Step 5: Verify key agents have skills');
99
+ const agentSkillMap = {
100
+ 'dotnet-senior': 'level-2-domains/backend/dotnet-senior.md',
101
+ 'ef-modeler': 'level-2-domains/backend/ef-modeler.md',
102
+ 'hangfire-orchestrator': 'level-2-domains/backend/hangfire-orchestrator.md',
103
+ 'ms-agent-expert': 'level-2-domains/backend/ms-agent-expert.md',
104
+ 'blazor-builder': 'level-2-domains/frontend/blazor-builder.md',
105
+ 'nextjs-expert': 'level-2-domains/frontend/nextjs-expert.md',
106
+ 'ui-ux-designer': 'level-2-domains/frontend/ui-ux-designer.md',
107
+ 'azure-architect': 'level-2-domains/infrastructure/azure-architect.md',
108
+ 'bicep-architect': 'level-2-domains/infrastructure/bicep-architect.md',
109
+ 'devops-engineer': 'level-2-domains/infrastructure/devops-engineer.md',
110
+ 'container-specialist': 'level-2-domains/infrastructure/container-specialist.md',
111
+ 'testing-specialist': 'level-2-domains/quality/testing-specialist.md',
112
+ 'code-analyzer': 'level-2-domains/quality/code-analyzer.md',
113
+ 'standards-architect': 'level-2-domains/architecture/standards-architect.md',
114
+ 'po-pm-advisor': 'level-2-domains/architecture/po-pm-advisor.md',
115
+ 'ai-system-architect': 'level-2-domains/ai-agents/ai-system-architect.md',
116
+ 'asaas-financial': 'level-2-domains/integrations/asaas-financial.md',
117
+ 'clerk-auth': 'level-2-domains/integrations/clerk-auth.md',
118
+ 'azure-identity': 'level-2-domains/integrations/azure-identity.md',
119
+ 'resend-email': 'level-2-domains/integrations/resend-email.md'
120
+ };
121
+
122
+ let missingSkills = 0;
123
+ Object.entries(agentSkillMap).forEach(([agentId, skillPath]) => {
124
+ const fullPath = path.join(skillsBase, skillPath);
125
+ if (fs.existsSync(fullPath)) {
126
+ console.log(` ✅ ${agentId} → ${skillPath}`);
127
+ } else {
128
+ console.log(` ❌ ${agentId} → ${skillPath} (NOT FOUND)`);
129
+ missingSkills++;
130
+ }
131
+ });
132
+ console.log('');
133
+
134
+ // Step 6: Check skill file quality (headers, structure)
135
+ console.log('📋 Step 6: Check skill file structure');
136
+ let malformedSkills = 0;
137
+ Object.entries(agentSkillMap).forEach(([agentId, skillPath]) => {
138
+ const fullPath = path.join(skillsBase, skillPath);
139
+ if (fs.existsSync(fullPath)) {
140
+ const content = fs.readFileSync(fullPath, 'utf8');
141
+ const lines = content.split('\n');
142
+
143
+ // Check has markdown header (# Title)
144
+ if (!lines[0].startsWith('#')) {
145
+ console.log(` ⚠️ ${agentId}: Missing markdown header`);
146
+ malformedSkills++;
147
+ }
148
+ }
149
+ });
150
+
151
+ if (malformedSkills === 0) {
152
+ console.log(' ✅ All skills have proper structure');
153
+ } else {
154
+ console.log(` ⚠️ ${malformedSkills} skills have structure issues`);
155
+ }
156
+ console.log('');
157
+
158
+ // Final summary
159
+ console.log('='.repeat(60));
160
+ console.log('📊 VALIDATION SUMMARY');
161
+ console.log('='.repeat(60));
162
+ console.log(`✅ 5-level structure: ${missingDirs.length === 0 ? 'PASS' : 'FAIL'}`);
163
+ console.log(`✅ Squad directories: ${requiredSquads.every(s => existingSquads.includes(s)) ? 'PASS' : 'FAIL'}`);
164
+ console.log(`✅ Total skills: ${totalSkills} files`);
165
+ console.log(`✅ Old dirs removed: ${remainingOldDirs.length === 0 ? 'PASS' : 'FAIL'}`);
166
+ console.log(`✅ Agent→skill map: ${missingSkills === 0 ? 'PASS' : 'FAIL'}`);
167
+ console.log(`✅ Skill structure: ${malformedSkills === 0 ? 'PASS' : 'WARN'}`);
168
+
169
+ const allPassed = missingDirs.length === 0 &&
170
+ requiredSquads.every(s => existingSquads.includes(s)) &&
171
+ remainingOldDirs.length === 0 &&
172
+ missingSkills === 0;
173
+
174
+ if (allPassed) {
175
+ console.log('\n🎉 ALL CHECKS PASSED - Skills structure is valid!');
176
+ process.exit(0);
177
+ } else {
178
+ console.log('\n⚠️ SOME CHECKS FAILED - Review issues above');
179
+ process.exit(1);
180
+ }