@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.
- package/CLAUDE.md +75 -371
- package/LICENSE +72 -72
- package/bin/detect-agents.js +225 -225
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- package/content/.azure/README.md +293 -293
- package/content/.azure/docs/azure-devops-setup.md +454 -454
- package/content/.azure/docs/branch-strategy.md +398 -398
- package/content/.azure/docs/local-development.md +515 -515
- package/content/.azure/pipelines/pipeline-variables.yml +34 -34
- package/content/.azure/pipelines/prod-pipeline.yml +319 -319
- package/content/.azure/pipelines/staging-pipeline.yml +234 -234
- package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
- package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
- package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
- package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
- package/content/.claude/commands/morph-archive.md +79 -79
- package/content/.claude/commands/morph-deploy.md +529 -529
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -227
- package/content/.claude/commands/morph-troubleshoot.md +122 -122
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/{specialists → level-2-domains/architecture}/prompt-engineer.md +189 -189
- package/content/.claude/skills/{specialists → level-2-domains/architecture}/seo-growth-hacker.md +320 -320
- package/content/.claude/skills/{infra → level-2-domains/infrastructure}/azure-deploy-specialist.md +699 -699
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +7 -5
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/examples/api-nextjs/README.md +241 -241
- package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
- package/content/.morph/examples/api-nextjs/spec.md +399 -399
- package/content/.morph/examples/api-nextjs/tasks.md +168 -168
- package/content/.morph/examples/micro-saas/README.md +125 -125
- package/content/.morph/examples/micro-saas/contracts.cs +358 -358
- package/content/.morph/examples/micro-saas/decisions.md +246 -246
- package/content/.morph/examples/micro-saas/spec.md +236 -236
- package/content/.morph/examples/micro-saas/tasks.md +150 -150
- package/content/.morph/examples/multi-agent/README.md +309 -309
- package/content/.morph/examples/multi-agent/contracts.cs +433 -433
- package/content/.morph/examples/multi-agent/spec.md +479 -479
- package/content/.morph/examples/multi-agent/tasks.md +185 -185
- package/content/.morph/examples/state-v3.json +188 -188
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/pre-commit-all.sh +48 -48
- package/content/.morph/hooks/pre-commit-specs.sh +49 -49
- package/content/.morph/hooks/pre-commit-tests.sh +60 -60
- package/content/.morph/project.md +160 -160
- package/content/.morph/schemas/agent.schema.json +296 -296
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/coding.md +377 -377
- package/content/.morph/standards/fluent-ui-setup.md +590 -590
- package/content/.morph/standards/migration-guide.md +514 -514
- package/content/.morph/standards/passkeys-auth.md +423 -423
- package/content/.morph/standards/vector-search-rag.md +536 -536
- package/content/.morph/state.json +17 -17
- package/content/.morph/templates/FluentDesignTheme.cs +149 -149
- package/content/.morph/templates/MudTheme.cs +281 -281
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts.cs +217 -217
- package/content/.morph/templates/design-system.css +226 -226
- package/content/.morph/templates/infra/.dockerignore.example +89 -89
- package/content/.morph/templates/infra/Dockerfile.example +82 -82
- package/content/.morph/templates/infra/README.md +286 -286
- package/content/.morph/templates/infra/app-insights.bicep +63 -63
- package/content/.morph/templates/infra/app-service.bicep +164 -164
- package/content/.morph/templates/infra/azure-pipelines-deploy.yml +480 -480
- package/content/.morph/templates/infra/container-app-env.bicep +49 -49
- package/content/.morph/templates/infra/container-app.bicep +156 -156
- package/content/.morph/templates/infra/deploy-checklist.md +426 -426
- package/content/.morph/templates/infra/deploy.ps1 +229 -229
- package/content/.morph/templates/infra/deploy.sh +208 -208
- package/content/.morph/templates/infra/key-vault.bicep +91 -91
- package/content/.morph/templates/infra/main.bicep +189 -189
- package/content/.morph/templates/infra/parameters.dev.json +29 -29
- package/content/.morph/templates/infra/parameters.prod.json +29 -29
- package/content/.morph/templates/infra/parameters.staging.json +29 -29
- package/content/.morph/templates/infra/sql-database.bicep +103 -103
- package/content/.morph/templates/infra/storage.bicep +106 -106
- package/content/.morph/templates/integrations/asaas-client.cs +387 -387
- package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
- package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
- package/content/.morph/templates/integrations/clerk-config.cs +258 -258
- package/content/.morph/templates/job.cs +171 -171
- package/content/.morph/templates/migration.cs +83 -83
- package/content/.morph/templates/repository.cs +141 -141
- package/content/.morph/templates/saas/subscription.cs +347 -347
- package/content/.morph/templates/saas/tenant.cs +338 -338
- package/content/.morph/templates/service.cs +139 -139
- package/content/.morph/templates/sprint-status.yaml +68 -68
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/test.cs +239 -239
- package/content/.morph/templates/ui-design-system.md +286 -286
- package/content/.morph/templates/ui-flows.md +336 -336
- package/content/.morph/templates/ui-mockups.md +133 -133
- package/content/.morph/test-infra/example.bicep +59 -59
- package/content/README.md +79 -79
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
- package/docs/api/scripts/collapse.js +38 -38
- package/docs/api/scripts/commonNav.js +28 -28
- package/docs/api/scripts/linenumber.js +25 -25
- package/docs/api/scripts/nav.js +12 -12
- package/docs/api/scripts/polyfill.js +3 -3
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
- package/docs/api/scripts/prettify/lang-css.js +2 -2
- package/docs/api/scripts/prettify/prettify.js +28 -28
- package/docs/api/scripts/search.js +98 -98
- package/docs/api/styles/jsdoc.css +776 -776
- package/docs/api/styles/prettify.css +80 -80
- package/docs/examples.md +328 -328
- package/docs/templates.md +418 -418
- package/package.json +1 -2
- package/scripts/postinstall.js +132 -132
- package/scripts/reorganize-skills.cjs +175 -0
- package/scripts/validate-agents-structure.cjs +52 -0
- package/scripts/validate-skills.cjs +180 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -193
- package/src/commands/create-story.js +351 -351
- package/src/commands/deploy.js +780 -780
- package/src/commands/detect-agents.js +9 -0
- package/src/commands/detect.js +104 -104
- package/src/commands/generate.js +149 -149
- package/src/commands/lint-fluent.js +352 -352
- package/src/commands/rollback-phase.js +185 -185
- package/src/commands/session-summary.js +291 -291
- package/src/commands/shard-spec.js +224 -224
- package/src/commands/sprint-status.js +250 -250
- package/src/commands/state.js +334 -333
- package/src/commands/sync.js +167 -167
- package/src/commands/troubleshoot.js +222 -222
- package/src/commands/update.js +13 -1
- package/src/commands/validate-blazor-state.js +210 -210
- package/src/commands/validate-blazor.js +156 -156
- package/src/commands/validate-css.js +84 -84
- package/src/commands/validate-phase.js +221 -221
- package/src/lib/blazor-concurrency-analyzer.js +288 -288
- package/src/lib/blazor-state-validator.js +291 -291
- package/src/lib/blazor-validator.js +374 -374
- package/src/lib/css-validator.js +352 -352
- package/src/lib/design-system-generator.js +298 -298
- package/{detectors → src/lib/detectors}/config-detector.js +223 -223
- package/{detectors → src/lib/detectors}/conversation-analyzer.js +163 -163
- package/{detectors → src/lib/detectors}/index.js +84 -84
- package/{detectors → src/lib/detectors}/standards-generator.js +275 -275
- package/src/lib/learning-system.js +520 -520
- package/src/lib/mockup-generator.js +366 -366
- package/src/lib/state-manager.js +21 -4
- package/src/lib/troubleshoot-grep.js +194 -194
- package/src/lib/troubleshoot-index.js +144 -144
- package/src/lib/ui-detector.js +350 -350
- package/src/lib/validators/architecture-validator.js +387 -387
- package/src/lib/validators/package-validator.js +360 -360
- package/src/lib/validators/ui-contrast-validator.js +422 -422
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- /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.
|
|
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",
|
package/scripts/postinstall.js
CHANGED
|
@@ -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
|
+
}
|