@polymorphism-tech/morph-spec 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +314 -1673
- package/LICENSE +72 -72
- package/README.md +515 -516
- package/bin/detect-agents.js +225 -225
- package/bin/morph-spec.js +358 -173
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/task-manager.js +429 -0
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- package/bin/validate.js +369 -0
- 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-apply.md +221 -158
- package/content/.claude/commands/morph-archive.md +79 -79
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -0
- package/content/.claude/commands/morph-proposal.md +122 -101
- package/content/.claude/commands/morph-status.md +86 -86
- package/content/.claude/commands/morph-troubleshoot.md +122 -0
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/checklists/code-review.md +226 -0
- package/content/.claude/skills/checklists/morph-checklist.md +117 -0
- package/content/.claude/skills/checklists/simulation-checklist.md +77 -0
- package/content/.claude/skills/infra/bicep-architect.md +126 -419
- package/content/.claude/skills/infra/container-specialist.md +131 -437
- package/content/.claude/skills/infra/devops-engineer.md +119 -405
- package/content/.claude/skills/integrations/asaas-financial.md +130 -333
- package/content/.claude/skills/integrations/azure-identity.md +142 -309
- package/content/.claude/skills/integrations/clerk-auth.md +108 -290
- package/content/.claude/skills/integrations/resend-email.md +119 -0
- package/content/.claude/skills/specialists/ai-system-architect.md +192 -604
- package/content/.claude/skills/specialists/azure-architect.md +142 -142
- package/content/.claude/skills/specialists/code-analyzer.md +235 -0
- package/content/.claude/skills/specialists/dotnet-senior.md +287 -0
- package/content/.claude/skills/specialists/ef-modeler.md +113 -200
- package/content/.claude/skills/specialists/hangfire-orchestrator.md +126 -245
- package/content/.claude/skills/specialists/ms-agent-expert.md +109 -263
- package/content/.claude/skills/specialists/po-pm-advisor.md +197 -197
- package/content/.claude/skills/specialists/standards-architect.md +156 -78
- package/content/.claude/skills/specialists/testing-specialist.md +126 -0
- package/content/.claude/skills/specialists/ui-ux-designer.md +191 -1060
- package/content/.claude/skills/stacks/dotnet-blazor.md +210 -588
- package/content/.claude/skills/stacks/dotnet-nextjs.md +154 -402
- package/content/.claude/skills/workflows/morph-replicate.md +213 -0
- package/content/.claude/{commands/morph-clarify.md → skills/workflows/phase-clarify.md} +5 -58
- package/content/.claude/{commands/morph-design.md → skills/workflows/phase-design.md} +16 -86
- package/content/.claude/{commands/morph-setup.md → skills/workflows/phase-setup.md} +9 -17
- package/content/.claude/skills/workflows/phase-tasks.md +164 -0
- package/content/.claude/{commands/morph-uiux.md → skills/workflows/phase-uiux.md} +15 -88
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +378 -242
- package/content/.morph/config/config.template.json +89 -108
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/docs/workflows/design-impl.md +37 -0
- package/content/.morph/docs/workflows/fast-track.md +29 -0
- package/content/.morph/docs/workflows/full-morph.md +76 -0
- package/content/.morph/docs/workflows/standard.md +44 -0
- package/content/.morph/docs/workflows/ui-refresh.md +39 -0
- 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/scheduled-reports/decisions.md +158 -0
- package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
- package/content/.morph/examples/scheduled-reports/spec.md +267 -0
- package/content/.morph/examples/state-v3.json +188 -0
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/README.md +190 -239
- package/content/.morph/hooks/pre-commit-agents.sh +24 -24
- 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/schemas/tasks.schema.json +220 -0
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
- package/content/.morph/standards/agent-framework-production.md +410 -0
- package/content/.morph/standards/agent-framework-setup.md +413 -453
- package/content/.morph/standards/agent-framework-workflows.md +349 -0
- package/content/.morph/standards/architecture.md +325 -325
- package/content/.morph/standards/azure.md +605 -379
- package/content/.morph/standards/coding.md +377 -377
- package/content/.morph/standards/dotnet10-migration.md +520 -494
- 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/agent.cs +163 -172
- package/content/.morph/templates/clarify-questions.md +159 -0
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts/Commands.cs +74 -0
- package/content/.morph/templates/contracts/Entities.cs +25 -0
- package/content/.morph/templates/contracts/Queries.cs +74 -0
- package/content/.morph/templates/contracts/README.md +74 -0
- package/content/.morph/templates/contracts.cs +217 -217
- package/content/.morph/templates/decisions.md +123 -106
- 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/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 -0
- 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/proposal.md +141 -155
- package/content/.morph/templates/recap.md +94 -105
- 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/simulation.md +353 -0
- package/content/.morph/templates/spec.md +149 -148
- package/content/.morph/templates/sprint-status.yaml +68 -68
- package/content/.morph/templates/state.template.json +222 -222
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/tasks.md +257 -235
- package/content/.morph/templates/test.cs +239 -239
- package/content/.morph/templates/ui-components.md +362 -276
- 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/CLAUDE.md +150 -442
- package/content/README.md +79 -79
- package/detectors/config-detector.js +223 -223
- package/detectors/conversation-analyzer.js +163 -163
- package/detectors/index.js +84 -84
- package/detectors/standards-generator.js +275 -275
- package/detectors/structure-detector.js +245 -250
- package/docs/README.md +144 -149
- 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/getting-started.md +301 -302
- package/docs/installation.md +361 -361
- package/docs/templates.md +418 -418
- package/docs/validation-checklist.md +265 -266
- package/package.json +80 -80
- package/scripts/postinstall.js +132 -132
- package/src/commands/advance-phase.js +183 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -0
- package/src/commands/create-story.js +351 -351
- package/src/commands/detect-agents.js +139 -0
- package/src/commands/detect.js +104 -104
- package/src/commands/doctor.js +356 -280
- package/src/commands/generate.js +149 -149
- package/src/commands/init.js +258 -245
- package/src/commands/lint-fluent.js +352 -0
- package/src/commands/rollback-phase.js +185 -0
- package/src/commands/session-summary.js +291 -0
- package/src/commands/shard-spec.js +224 -224
- package/src/commands/sprint-status.js +250 -250
- package/src/commands/state.js +333 -333
- package/src/commands/sync.js +167 -167
- package/src/commands/task.js +78 -0
- package/src/commands/troubleshoot.js +222 -0
- package/src/commands/update.js +192 -159
- package/src/commands/validate-blazor-state.js +210 -0
- package/src/commands/validate-blazor.js +156 -0
- package/src/commands/validate-css.js +84 -0
- package/src/commands/validate-phase.js +221 -0
- package/src/lib/blazor-concurrency-analyzer.js +288 -0
- package/src/lib/blazor-state-validator.js +291 -0
- package/src/lib/blazor-validator.js +374 -0
- package/src/lib/complexity-analyzer.js +441 -292
- package/src/lib/continuous-validator.js +421 -0
- package/src/lib/css-validator.js +352 -0
- package/src/lib/decision-constraint-loader.js +109 -0
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/learning-system.js +520 -0
- package/src/lib/mockup-generator.js +366 -0
- package/src/lib/recap-generator.js +205 -0
- package/src/lib/state-manager.js +397 -340
- package/src/lib/troubleshoot-grep.js +194 -0
- package/src/lib/troubleshoot-index.js +144 -0
- package/src/lib/ui-detector.js +350 -0
- package/src/lib/validation-runner.js +231 -0
- package/src/lib/validators/architecture-validator.js +387 -0
- package/src/lib/validators/contract-compliance-validator.js +273 -0
- package/src/lib/validators/package-validator.js +360 -0
- package/src/lib/validators/ui-contrast-validator.js +422 -0
- package/src/utils/file-copier.js +179 -139
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- package/content/.claude/commands/morph-costs.md +0 -206
- package/content/.claude/commands/morph-tasks.md +0 -319
- package/content/.claude/skills/specialists/cost-guardian.md +0 -110
- package/content/.claude/skills/stacks/shopify.md +0 -445
- package/content/.morph/config/azure-pricing.json +0 -70
- package/content/.morph/config/azure-pricing.schema.json +0 -50
- package/content/.morph/hooks/pre-commit-costs.sh +0 -91
- package/docs/api/cost-calculator.js.html +0 -513
- package/docs/api/design-system-generator.js.html +0 -382
- package/docs/api/global.html +0 -5263
- package/docs/api/index.html +0 -96
- package/docs/api/state-manager.js.html +0 -423
- package/src/commands/cost.js +0 -181
- package/src/commands/update-pricing.js +0 -206
- package/src/lib/cost-calculator.js +0 -429
|
@@ -1,275 +1,275 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standards Generator - Generates inferred-standards.md from detection results
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Generate inferred standards
|
|
7
|
-
* @param {Object} detectionResults - Results from all detectors
|
|
8
|
-
* @returns {Promise<Object>} Generated standards
|
|
9
|
-
*/
|
|
10
|
-
export async function generateStandards(detectionResults) {
|
|
11
|
-
const { structure, config, conversation } = detectionResults;
|
|
12
|
-
|
|
13
|
-
const standards = {
|
|
14
|
-
markdown: generateMarkdown(structure, config, conversation),
|
|
15
|
-
recommendations: generateRecommendations(structure, config, conversation),
|
|
16
|
-
gaps: identifyGaps(structure, config)
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
return standards;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Generate markdown content for inferred-standards.md
|
|
24
|
-
*/
|
|
25
|
-
function generateMarkdown(structure, config, conversation) {
|
|
26
|
-
const sections = [];
|
|
27
|
-
|
|
28
|
-
// Header
|
|
29
|
-
sections.push(`# Inferred Standards (Auto-generated)`);
|
|
30
|
-
sections.push(``);
|
|
31
|
-
sections.push(`> ⚠️ This file is auto-generated by MORPH-SPEC detection system.`);
|
|
32
|
-
sections.push(`> Manual edits will be overwritten. Create custom standards in \`overrides.md\`.`);
|
|
33
|
-
sections.push(``);
|
|
34
|
-
sections.push(`**Generated:** ${new Date().toISOString()}`);
|
|
35
|
-
sections.push(``);
|
|
36
|
-
sections.push(`---`);
|
|
37
|
-
sections.push(``);
|
|
38
|
-
|
|
39
|
-
// Stack Summary
|
|
40
|
-
sections.push(`## 🎯 Project Stack`);
|
|
41
|
-
sections.push(``);
|
|
42
|
-
sections.push(`- **Type**: ${structure?.stack || 'unknown'}`);
|
|
43
|
-
sections.push(`- **Language**: ${config?.language || 'unknown'}`);
|
|
44
|
-
sections.push(`- **Version**: ${config?.version || 'unknown'}`);
|
|
45
|
-
sections.push(`- **Architecture**: ${structure?.architecture || 'unknown'}`);
|
|
46
|
-
if (structure?.uiLibrary) {
|
|
47
|
-
sections.push(`- **UI Library**: ${structure.uiLibrary}`);
|
|
48
|
-
}
|
|
49
|
-
sections.push(``);
|
|
50
|
-
|
|
51
|
-
// Technologies
|
|
52
|
-
if (config?.technologies?.length > 0) {
|
|
53
|
-
sections.push(`## 🛠️ Technologies Detected`);
|
|
54
|
-
sections.push(``);
|
|
55
|
-
config.technologies.forEach(tech => {
|
|
56
|
-
sections.push(`- ${tech}`);
|
|
57
|
-
});
|
|
58
|
-
sections.push(``);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Patterns
|
|
62
|
-
if (structure?.patterns?.length > 0) {
|
|
63
|
-
sections.push(`## 📐 Patterns in Use`);
|
|
64
|
-
sections.push(``);
|
|
65
|
-
structure.patterns.forEach(pattern => {
|
|
66
|
-
sections.push(`- ${pattern}`);
|
|
67
|
-
});
|
|
68
|
-
sections.push(``);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Coding Standards (inferred)
|
|
72
|
-
sections.push(`## 💻 Inferred Coding Standards`);
|
|
73
|
-
sections.push(``);
|
|
74
|
-
sections.push(generateCodingStandards(structure, config));
|
|
75
|
-
sections.push(``);
|
|
76
|
-
|
|
77
|
-
// Architecture Patterns
|
|
78
|
-
if (structure?.architecture !== 'unknown') {
|
|
79
|
-
sections.push(`## 🏗️ Architecture Pattern`);
|
|
80
|
-
sections.push(``);
|
|
81
|
-
sections.push(generateArchitectureSection(structure));
|
|
82
|
-
sections.push(``);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Dependencies
|
|
86
|
-
if (config?.dependencies?.length > 0) {
|
|
87
|
-
sections.push(`## 📦 Key Dependencies`);
|
|
88
|
-
sections.push(``);
|
|
89
|
-
const importantDeps = filterImportantDependencies(config.dependencies);
|
|
90
|
-
importantDeps.slice(0, 10).forEach(dep => {
|
|
91
|
-
sections.push(`- ${dep}`);
|
|
92
|
-
});
|
|
93
|
-
if (config.dependencies.length > 10) {
|
|
94
|
-
sections.push(`- ... and ${config.dependencies.length - 10} more`);
|
|
95
|
-
}
|
|
96
|
-
sections.push(``);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// User Preferences (from conversation)
|
|
100
|
-
if (conversation?.preferences && Object.keys(conversation.preferences).some(k => conversation.preferences[k])) {
|
|
101
|
-
sections.push(`## 🎨 User Preferences (from past decisions)`);
|
|
102
|
-
sections.push(``);
|
|
103
|
-
Object.entries(conversation.preferences).forEach(([key, value]) => {
|
|
104
|
-
if (value) {
|
|
105
|
-
sections.push(`- **${formatKey(key)}**: ${value}`);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
sections.push(``);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return sections.join('\n');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Generate coding standards section
|
|
116
|
-
*/
|
|
117
|
-
function generateCodingStandards(structure, config) {
|
|
118
|
-
if (config?.language === 'csharp') {
|
|
119
|
-
return `### C# / .NET Conventions
|
|
120
|
-
|
|
121
|
-
Based on detected patterns in your codebase:
|
|
122
|
-
|
|
123
|
-
- **Naming**: PascalCase for classes, camelCase for variables
|
|
124
|
-
- **Async**: Methods with \`Async\` suffix
|
|
125
|
-
- **DI**: Constructor injection (${structure.patterns.includes('Dependency Injection') ? '✅ detected' : '⚠️ not detected'})
|
|
126
|
-
- **Tests**: ${structure.patterns.includes('Unit Tests') ? '✅ Present' : '⚠️ Not detected'}
|
|
127
|
-
|
|
128
|
-
**Recommendation**: Refer to \`.morph/standards/coding.md\` for complete .NET standards.`;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (config?.language === 'javascript') {
|
|
132
|
-
return `### JavaScript / TypeScript Conventions
|
|
133
|
-
|
|
134
|
-
Based on detected patterns in your codebase:
|
|
135
|
-
|
|
136
|
-
- **Package Manager**: ${config.packageManager}
|
|
137
|
-
- **Framework**: ${config.technologies.join(', ')}
|
|
138
|
-
|
|
139
|
-
**Recommendation**: Refer to framework standards for JavaScript best practices.`;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return 'No specific coding standards inferred. Check framework standards for guidance.';
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Generate architecture section
|
|
147
|
-
*/
|
|
148
|
-
function generateArchitectureSection(structure) {
|
|
149
|
-
const { architecture } = structure;
|
|
150
|
-
|
|
151
|
-
const descriptions = {
|
|
152
|
-
'clean-architecture': `### Clean Architecture
|
|
153
|
-
|
|
154
|
-
Your project follows Clean Architecture pattern:
|
|
155
|
-
|
|
156
|
-
- ✅ **Domain** layer detected (core business logic)
|
|
157
|
-
- ✅ **Application** layer detected (use cases)
|
|
158
|
-
- ✅ **Infrastructure** layer detected (implementations)
|
|
159
|
-
|
|
160
|
-
**Key principles**:
|
|
161
|
-
- Domain has no dependencies
|
|
162
|
-
- Application depends on Domain
|
|
163
|
-
- Infrastructure implements Application interfaces`,
|
|
164
|
-
|
|
165
|
-
'cqrs': `### CQRS Pattern
|
|
166
|
-
|
|
167
|
-
Your project uses Command Query Responsibility Segregation:
|
|
168
|
-
|
|
169
|
-
- ✅ **Commands** detected (write operations)
|
|
170
|
-
- ✅ **Queries** detected (read operations)
|
|
171
|
-
|
|
172
|
-
**Key principles**:
|
|
173
|
-
- Separate read and write models
|
|
174
|
-
- Commands return void or Task
|
|
175
|
-
- Queries return data`,
|
|
176
|
-
|
|
177
|
-
'mvc': `### MVC Pattern
|
|
178
|
-
|
|
179
|
-
Your project uses Model-View-Controller pattern:
|
|
180
|
-
|
|
181
|
-
- ✅ **Controllers** detected
|
|
182
|
-
- ✅ **Models** detected
|
|
183
|
-
- ✅ **Views** detected`
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
return descriptions[architecture] || `Architecture: ${architecture}`;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Generate recommendations
|
|
191
|
-
*/
|
|
192
|
-
function generateRecommendations(structure, config, conversation) {
|
|
193
|
-
const recommendations = [];
|
|
194
|
-
|
|
195
|
-
// Recommend based on stack
|
|
196
|
-
if (structure?.stack === 'blazor') {
|
|
197
|
-
if (!structure.uiLibrary) {
|
|
198
|
-
recommendations.push('Consider adding Fluent UI Blazor or MudBlazor for consistent UI components');
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (!structure.patterns.includes('AI Agents') && config?.technologies?.includes('Microsoft Agent Framework')) {
|
|
202
|
-
recommendations.push('Setup detected Agent Framework but no agents found - check .morph/standards/agent-framework-setup.md');
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Recommend tests
|
|
207
|
-
if (!structure?.patterns?.includes('Unit Tests')) {
|
|
208
|
-
recommendations.push('No unit tests detected - consider adding test project');
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Recommend DI
|
|
212
|
-
if (!structure?.patterns?.includes('Dependency Injection')) {
|
|
213
|
-
recommendations.push('Consider implementing Dependency Injection pattern');
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Architecture recommendations
|
|
217
|
-
if (structure?.architecture === 'unknown' && structure?.folders?.hasServices) {
|
|
218
|
-
recommendations.push('Service layer detected but no clear architecture - consider Clean Architecture or CQRS');
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return recommendations;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Identify gaps between framework and project
|
|
226
|
-
*/
|
|
227
|
-
function identifyGaps(structure, config) {
|
|
228
|
-
const gaps = [];
|
|
229
|
-
|
|
230
|
-
// Check for missing patterns
|
|
231
|
-
const expectedPatterns = {
|
|
232
|
-
blazor: ['Service Layer', 'Repository Pattern', 'Dependency Injection'],
|
|
233
|
-
nextjs: ['API Routes', 'Components'],
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
const expected = expectedPatterns[structure?.stack];
|
|
237
|
-
if (expected) {
|
|
238
|
-
expected.forEach(pattern => {
|
|
239
|
-
if (!structure?.patterns?.includes(pattern)) {
|
|
240
|
-
gaps.push(`Missing: ${pattern}`);
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return gaps;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Filter important dependencies
|
|
250
|
-
*/
|
|
251
|
-
function filterImportantDependencies(deps) {
|
|
252
|
-
const important = deps.filter(dep => {
|
|
253
|
-
// Framework packages
|
|
254
|
-
if (dep.includes('Microsoft.') || dep.includes('System.')) return true;
|
|
255
|
-
// UI libraries
|
|
256
|
-
if (dep.includes('Blazor') || dep.includes('FluentUI') || dep.includes('Mud')) return true;
|
|
257
|
-
// Common tools
|
|
258
|
-
if (dep.includes('Hangfire') || dep.includes('Serilog') || dep.includes('AutoMapper')) return true;
|
|
259
|
-
// AI/ML
|
|
260
|
-
if (dep.includes('Agents') || dep.includes('AI') || dep.includes('OpenAI')) return true;
|
|
261
|
-
return false;
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
return important.length > 0 ? important : deps;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Format key for display
|
|
269
|
-
*/
|
|
270
|
-
function formatKey(key) {
|
|
271
|
-
return key
|
|
272
|
-
.replace(/([A-Z])/g, ' $1')
|
|
273
|
-
.replace(/^./, str => str.toUpperCase())
|
|
274
|
-
.trim();
|
|
275
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Standards Generator - Generates inferred-standards.md from detection results
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate inferred standards
|
|
7
|
+
* @param {Object} detectionResults - Results from all detectors
|
|
8
|
+
* @returns {Promise<Object>} Generated standards
|
|
9
|
+
*/
|
|
10
|
+
export async function generateStandards(detectionResults) {
|
|
11
|
+
const { structure, config, conversation } = detectionResults;
|
|
12
|
+
|
|
13
|
+
const standards = {
|
|
14
|
+
markdown: generateMarkdown(structure, config, conversation),
|
|
15
|
+
recommendations: generateRecommendations(structure, config, conversation),
|
|
16
|
+
gaps: identifyGaps(structure, config)
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
return standards;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generate markdown content for inferred-standards.md
|
|
24
|
+
*/
|
|
25
|
+
function generateMarkdown(structure, config, conversation) {
|
|
26
|
+
const sections = [];
|
|
27
|
+
|
|
28
|
+
// Header
|
|
29
|
+
sections.push(`# Inferred Standards (Auto-generated)`);
|
|
30
|
+
sections.push(``);
|
|
31
|
+
sections.push(`> ⚠️ This file is auto-generated by MORPH-SPEC detection system.`);
|
|
32
|
+
sections.push(`> Manual edits will be overwritten. Create custom standards in \`overrides.md\`.`);
|
|
33
|
+
sections.push(``);
|
|
34
|
+
sections.push(`**Generated:** ${new Date().toISOString()}`);
|
|
35
|
+
sections.push(``);
|
|
36
|
+
sections.push(`---`);
|
|
37
|
+
sections.push(``);
|
|
38
|
+
|
|
39
|
+
// Stack Summary
|
|
40
|
+
sections.push(`## 🎯 Project Stack`);
|
|
41
|
+
sections.push(``);
|
|
42
|
+
sections.push(`- **Type**: ${structure?.stack || 'unknown'}`);
|
|
43
|
+
sections.push(`- **Language**: ${config?.language || 'unknown'}`);
|
|
44
|
+
sections.push(`- **Version**: ${config?.version || 'unknown'}`);
|
|
45
|
+
sections.push(`- **Architecture**: ${structure?.architecture || 'unknown'}`);
|
|
46
|
+
if (structure?.uiLibrary) {
|
|
47
|
+
sections.push(`- **UI Library**: ${structure.uiLibrary}`);
|
|
48
|
+
}
|
|
49
|
+
sections.push(``);
|
|
50
|
+
|
|
51
|
+
// Technologies
|
|
52
|
+
if (config?.technologies?.length > 0) {
|
|
53
|
+
sections.push(`## 🛠️ Technologies Detected`);
|
|
54
|
+
sections.push(``);
|
|
55
|
+
config.technologies.forEach(tech => {
|
|
56
|
+
sections.push(`- ${tech}`);
|
|
57
|
+
});
|
|
58
|
+
sections.push(``);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Patterns
|
|
62
|
+
if (structure?.patterns?.length > 0) {
|
|
63
|
+
sections.push(`## 📐 Patterns in Use`);
|
|
64
|
+
sections.push(``);
|
|
65
|
+
structure.patterns.forEach(pattern => {
|
|
66
|
+
sections.push(`- ${pattern}`);
|
|
67
|
+
});
|
|
68
|
+
sections.push(``);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Coding Standards (inferred)
|
|
72
|
+
sections.push(`## 💻 Inferred Coding Standards`);
|
|
73
|
+
sections.push(``);
|
|
74
|
+
sections.push(generateCodingStandards(structure, config));
|
|
75
|
+
sections.push(``);
|
|
76
|
+
|
|
77
|
+
// Architecture Patterns
|
|
78
|
+
if (structure?.architecture !== 'unknown') {
|
|
79
|
+
sections.push(`## 🏗️ Architecture Pattern`);
|
|
80
|
+
sections.push(``);
|
|
81
|
+
sections.push(generateArchitectureSection(structure));
|
|
82
|
+
sections.push(``);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Dependencies
|
|
86
|
+
if (config?.dependencies?.length > 0) {
|
|
87
|
+
sections.push(`## 📦 Key Dependencies`);
|
|
88
|
+
sections.push(``);
|
|
89
|
+
const importantDeps = filterImportantDependencies(config.dependencies);
|
|
90
|
+
importantDeps.slice(0, 10).forEach(dep => {
|
|
91
|
+
sections.push(`- ${dep}`);
|
|
92
|
+
});
|
|
93
|
+
if (config.dependencies.length > 10) {
|
|
94
|
+
sections.push(`- ... and ${config.dependencies.length - 10} more`);
|
|
95
|
+
}
|
|
96
|
+
sections.push(``);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// User Preferences (from conversation)
|
|
100
|
+
if (conversation?.preferences && Object.keys(conversation.preferences).some(k => conversation.preferences[k])) {
|
|
101
|
+
sections.push(`## 🎨 User Preferences (from past decisions)`);
|
|
102
|
+
sections.push(``);
|
|
103
|
+
Object.entries(conversation.preferences).forEach(([key, value]) => {
|
|
104
|
+
if (value) {
|
|
105
|
+
sections.push(`- **${formatKey(key)}**: ${value}`);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
sections.push(``);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return sections.join('\n');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Generate coding standards section
|
|
116
|
+
*/
|
|
117
|
+
function generateCodingStandards(structure, config) {
|
|
118
|
+
if (config?.language === 'csharp') {
|
|
119
|
+
return `### C# / .NET Conventions
|
|
120
|
+
|
|
121
|
+
Based on detected patterns in your codebase:
|
|
122
|
+
|
|
123
|
+
- **Naming**: PascalCase for classes, camelCase for variables
|
|
124
|
+
- **Async**: Methods with \`Async\` suffix
|
|
125
|
+
- **DI**: Constructor injection (${structure.patterns.includes('Dependency Injection') ? '✅ detected' : '⚠️ not detected'})
|
|
126
|
+
- **Tests**: ${structure.patterns.includes('Unit Tests') ? '✅ Present' : '⚠️ Not detected'}
|
|
127
|
+
|
|
128
|
+
**Recommendation**: Refer to \`.morph/standards/coding.md\` for complete .NET standards.`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (config?.language === 'javascript') {
|
|
132
|
+
return `### JavaScript / TypeScript Conventions
|
|
133
|
+
|
|
134
|
+
Based on detected patterns in your codebase:
|
|
135
|
+
|
|
136
|
+
- **Package Manager**: ${config.packageManager}
|
|
137
|
+
- **Framework**: ${config.technologies.join(', ')}
|
|
138
|
+
|
|
139
|
+
**Recommendation**: Refer to framework standards for JavaScript best practices.`;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return 'No specific coding standards inferred. Check framework standards for guidance.';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Generate architecture section
|
|
147
|
+
*/
|
|
148
|
+
function generateArchitectureSection(structure) {
|
|
149
|
+
const { architecture } = structure;
|
|
150
|
+
|
|
151
|
+
const descriptions = {
|
|
152
|
+
'clean-architecture': `### Clean Architecture
|
|
153
|
+
|
|
154
|
+
Your project follows Clean Architecture pattern:
|
|
155
|
+
|
|
156
|
+
- ✅ **Domain** layer detected (core business logic)
|
|
157
|
+
- ✅ **Application** layer detected (use cases)
|
|
158
|
+
- ✅ **Infrastructure** layer detected (implementations)
|
|
159
|
+
|
|
160
|
+
**Key principles**:
|
|
161
|
+
- Domain has no dependencies
|
|
162
|
+
- Application depends on Domain
|
|
163
|
+
- Infrastructure implements Application interfaces`,
|
|
164
|
+
|
|
165
|
+
'cqrs': `### CQRS Pattern
|
|
166
|
+
|
|
167
|
+
Your project uses Command Query Responsibility Segregation:
|
|
168
|
+
|
|
169
|
+
- ✅ **Commands** detected (write operations)
|
|
170
|
+
- ✅ **Queries** detected (read operations)
|
|
171
|
+
|
|
172
|
+
**Key principles**:
|
|
173
|
+
- Separate read and write models
|
|
174
|
+
- Commands return void or Task
|
|
175
|
+
- Queries return data`,
|
|
176
|
+
|
|
177
|
+
'mvc': `### MVC Pattern
|
|
178
|
+
|
|
179
|
+
Your project uses Model-View-Controller pattern:
|
|
180
|
+
|
|
181
|
+
- ✅ **Controllers** detected
|
|
182
|
+
- ✅ **Models** detected
|
|
183
|
+
- ✅ **Views** detected`
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
return descriptions[architecture] || `Architecture: ${architecture}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Generate recommendations
|
|
191
|
+
*/
|
|
192
|
+
function generateRecommendations(structure, config, conversation) {
|
|
193
|
+
const recommendations = [];
|
|
194
|
+
|
|
195
|
+
// Recommend based on stack
|
|
196
|
+
if (structure?.stack === 'blazor') {
|
|
197
|
+
if (!structure.uiLibrary) {
|
|
198
|
+
recommendations.push('Consider adding Fluent UI Blazor or MudBlazor for consistent UI components');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!structure.patterns.includes('AI Agents') && config?.technologies?.includes('Microsoft Agent Framework')) {
|
|
202
|
+
recommendations.push('Setup detected Agent Framework but no agents found - check .morph/standards/agent-framework-setup.md');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Recommend tests
|
|
207
|
+
if (!structure?.patterns?.includes('Unit Tests')) {
|
|
208
|
+
recommendations.push('No unit tests detected - consider adding test project');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Recommend DI
|
|
212
|
+
if (!structure?.patterns?.includes('Dependency Injection')) {
|
|
213
|
+
recommendations.push('Consider implementing Dependency Injection pattern');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Architecture recommendations
|
|
217
|
+
if (structure?.architecture === 'unknown' && structure?.folders?.hasServices) {
|
|
218
|
+
recommendations.push('Service layer detected but no clear architecture - consider Clean Architecture or CQRS');
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return recommendations;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Identify gaps between framework and project
|
|
226
|
+
*/
|
|
227
|
+
function identifyGaps(structure, config) {
|
|
228
|
+
const gaps = [];
|
|
229
|
+
|
|
230
|
+
// Check for missing patterns
|
|
231
|
+
const expectedPatterns = {
|
|
232
|
+
blazor: ['Service Layer', 'Repository Pattern', 'Dependency Injection'],
|
|
233
|
+
nextjs: ['API Routes', 'Components'],
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const expected = expectedPatterns[structure?.stack];
|
|
237
|
+
if (expected) {
|
|
238
|
+
expected.forEach(pattern => {
|
|
239
|
+
if (!structure?.patterns?.includes(pattern)) {
|
|
240
|
+
gaps.push(`Missing: ${pattern}`);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return gaps;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Filter important dependencies
|
|
250
|
+
*/
|
|
251
|
+
function filterImportantDependencies(deps) {
|
|
252
|
+
const important = deps.filter(dep => {
|
|
253
|
+
// Framework packages
|
|
254
|
+
if (dep.includes('Microsoft.') || dep.includes('System.')) return true;
|
|
255
|
+
// UI libraries
|
|
256
|
+
if (dep.includes('Blazor') || dep.includes('FluentUI') || dep.includes('Mud')) return true;
|
|
257
|
+
// Common tools
|
|
258
|
+
if (dep.includes('Hangfire') || dep.includes('Serilog') || dep.includes('AutoMapper')) return true;
|
|
259
|
+
// AI/ML
|
|
260
|
+
if (dep.includes('Agents') || dep.includes('AI') || dep.includes('OpenAI')) return true;
|
|
261
|
+
return false;
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
return important.length > 0 ? important : deps;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Format key for display
|
|
269
|
+
*/
|
|
270
|
+
function formatKey(key) {
|
|
271
|
+
return key
|
|
272
|
+
.replace(/([A-Z])/g, ' $1')
|
|
273
|
+
.replace(/^./, str => str.toUpperCase())
|
|
274
|
+
.trim();
|
|
275
|
+
}
|