@polymorphism-tech/morph-spec 4.9.0 → 4.10.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 (164) hide show
  1. package/README.md +2 -2
  2. package/bin/morph-spec.js +30 -0
  3. package/bin/task-manager.js +34 -22
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +1 -1
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/CLAUDE.md +35 -98
  8. package/framework/agents/backend/api-designer.md +3 -0
  9. package/framework/agents/backend/dotnet-senior.md +3 -0
  10. package/framework/agents/backend/ef-modeler.md +2 -0
  11. package/framework/agents/backend/hangfire-orchestrator.md +2 -0
  12. package/framework/agents/backend/ms-agent-expert.md +2 -0
  13. package/framework/agents/frontend/blazor-builder.md +2 -0
  14. package/framework/agents/frontend/nextjs-expert.md +2 -0
  15. package/framework/agents/infrastructure/azure-architect.md +2 -0
  16. package/framework/agents/infrastructure/azure-deploy-specialist.md +2 -0
  17. package/framework/agents/infrastructure/bicep-architect.md +2 -0
  18. package/framework/agents/infrastructure/container-specialist.md +2 -0
  19. package/framework/agents/infrastructure/devops-engineer.md +3 -0
  20. package/framework/agents/infrastructure/infra-architect.md +3 -0
  21. package/framework/agents/integrations/asaas-financial.md +2 -0
  22. package/framework/agents/integrations/azure-identity.md +2 -0
  23. package/framework/agents/integrations/clerk-auth.md +3 -0
  24. package/framework/agents/integrations/hangfire-integration.md +2 -0
  25. package/framework/agents/integrations/resend-email.md +2 -0
  26. package/framework/agents.json +37 -7
  27. package/framework/commands/commit.md +166 -0
  28. package/framework/commands/morph-apply.md +156 -155
  29. package/framework/commands/morph-archive.md +33 -27
  30. package/framework/commands/morph-infra.md +83 -77
  31. package/framework/commands/morph-preflight.md +97 -55
  32. package/framework/commands/morph-proposal.md +131 -58
  33. package/framework/commands/morph-status.md +36 -30
  34. package/framework/commands/morph-troubleshoot.md +68 -59
  35. package/framework/hooks/claude-code/notification/approval-reminder.js +3 -2
  36. package/framework/hooks/claude-code/post-tool-use/dispatch.js +154 -31
  37. package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +7 -84
  38. package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +8 -17
  39. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +16 -3
  40. package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +4 -3
  41. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +3 -2
  42. package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +60 -0
  43. package/framework/hooks/claude-code/session-start/inject-morph-context.js +55 -2
  44. package/framework/hooks/claude-code/session-start/post-compact-restore.js +41 -0
  45. package/framework/hooks/claude-code/stop/validate-completion.js +2 -15
  46. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +23 -5
  47. package/framework/hooks/shared/compact-restore.js +100 -0
  48. package/framework/hooks/shared/dispatch-helpers.js +116 -0
  49. package/framework/hooks/shared/phase-utils.js +9 -5
  50. package/framework/hooks/shared/state-reader.js +27 -3
  51. package/framework/phases.json +30 -7
  52. package/framework/rules/csharp-standards.md +3 -0
  53. package/framework/rules/frontend-standards.md +2 -0
  54. package/framework/rules/infrastructure-standards.md +3 -0
  55. package/framework/rules/morph-workflow.md +143 -86
  56. package/framework/rules/nextjs-standards.md +2 -0
  57. package/framework/rules/testing-standards.md +3 -0
  58. package/framework/skills/level-0-meta/mcp-registry.json +86 -51
  59. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +139 -0
  60. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +42 -19
  61. package/framework/skills/level-0-meta/{code-review → morph-code-review}/SKILL.md +8 -5
  62. package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/SKILL.md +8 -6
  63. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +362 -0
  64. package/framework/skills/level-0-meta/morph-init/SKILL.md +114 -20
  65. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +362 -0
  66. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +95 -87
  67. package/framework/skills/level-0-meta/{simulation-checklist → morph-simulation-checklist}/SKILL.md +24 -0
  68. package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/SKILL.md +43 -43
  69. package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/references/tools-per-phase.md +1 -2
  70. package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/SKILL.md +23 -12
  71. package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/scripts/check-phase-outputs.mjs +2 -2
  72. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +247 -0
  73. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +270 -0
  74. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +499 -0
  75. package/framework/skills/level-1-workflows/morph-phase-implement/.morph/logs/activity.json +38 -0
  76. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +472 -0
  77. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +50 -0
  78. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +45 -0
  79. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +47 -0
  80. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +246 -0
  81. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +238 -0
  82. package/framework/skills/level-1-workflows/morph-phase-tasks/.morph/logs/activity.json +14 -0
  83. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +312 -0
  84. package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/scripts/validate-tasks.mjs +3 -3
  85. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +324 -0
  86. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +146 -0
  87. package/framework/standards/integration/mcp/mcp-tools.md +25 -7
  88. package/framework/templates/docs/onboarding.md +2 -2
  89. package/package.json +3 -4
  90. package/src/commands/agents/dispatch-agents.js +50 -3
  91. package/src/commands/mcp/mcp-setup.js +39 -2
  92. package/src/commands/phase/phase-reset.js +74 -0
  93. package/src/commands/project/doctor.js +26 -7
  94. package/src/commands/project/update.js +4 -4
  95. package/src/commands/scope/escalate.js +215 -0
  96. package/src/commands/state/advance-phase.js +27 -53
  97. package/src/commands/state/state.js +1 -1
  98. package/src/commands/task/expand.js +100 -0
  99. package/src/core/paths/output-schema.js +4 -3
  100. package/src/core/state/phase-state-machine.js +7 -4
  101. package/src/core/state/state-manager.js +4 -3
  102. package/src/lib/detectors/claude-config-detector.js +93 -347
  103. package/src/lib/detectors/design-system-detector.js +189 -189
  104. package/src/lib/detectors/index.js +155 -57
  105. package/src/lib/generators/context-generator.js +2 -2
  106. package/src/lib/installers/mcp-installer.js +37 -5
  107. package/src/lib/phase-chain/phase-validator.js +22 -16
  108. package/src/lib/scope/impact-analyzer.js +106 -0
  109. package/src/lib/stack-filter.js +58 -0
  110. package/src/lib/tasks/task-parser.js +1 -1
  111. package/src/lib/validators/shared/emit-validator-dispatch.js +64 -0
  112. package/src/scripts/setup-infra.js +68 -18
  113. package/src/utils/agents-installer.js +51 -17
  114. package/src/utils/claude-md-injector.js +90 -0
  115. package/src/utils/file-copier.js +0 -1
  116. package/src/utils/hooks-installer.js +16 -5
  117. package/src/utils/skills-installer.js +67 -7
  118. package/CLAUDE.md +0 -98
  119. package/framework/memory/patterns-learned.md +0 -766
  120. package/framework/skills/level-0-meta/brainstorming/SKILL.md +0 -137
  121. package/framework/skills/level-0-meta/frontend-review/SKILL.md +0 -359
  122. package/framework/skills/level-0-meta/post-implementation/SKILL.md +0 -362
  123. package/framework/skills/level-0-meta/terminal-title/SKILL.md +0 -61
  124. package/framework/skills/level-0-meta/terminal-title/scripts/set_title.sh +0 -65
  125. package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +0 -216
  126. package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +0 -252
  127. package/framework/skills/level-1-workflows/phase-design/SKILL.md +0 -383
  128. package/framework/skills/level-1-workflows/phase-implement/SKILL.md +0 -492
  129. package/framework/skills/level-1-workflows/phase-setup/SKILL.md +0 -195
  130. package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +0 -271
  131. package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +0 -286
  132. package/src/commands/project/index.js +0 -8
  133. package/src/core/index.js +0 -10
  134. package/src/core/state/index.js +0 -8
  135. package/src/core/templates/index.js +0 -9
  136. package/src/core/templates/template-data-sources.js +0 -325
  137. package/src/core/workflows/index.js +0 -7
  138. package/src/lib/detectors/config-detector.js +0 -223
  139. package/src/lib/detectors/standards-generator.js +0 -335
  140. package/src/lib/detectors/structure-detector.js +0 -275
  141. package/src/lib/monitor/agent-resolver.js +0 -144
  142. package/src/lib/monitor/renderer.js +0 -230
  143. package/src/lib/orchestration/index.js +0 -7
  144. package/src/lib/orchestration/team-orchestrator.js +0 -404
  145. package/src/sanitizer/context-sanitizer.js +0 -221
  146. package/src/sanitizer/patterns.js +0 -163
  147. package/src/writer/file-writer.js +0 -86
  148. /package/framework/skills/level-0-meta/{brainstorming → morph-brainstorming}/references/proposal-example.md +0 -0
  149. /package/framework/skills/level-0-meta/{code-review → morph-code-review}/references/review-example.md +0 -0
  150. /package/framework/skills/level-0-meta/{code-review → morph-code-review}/references/review-guidelines.md +0 -0
  151. /package/framework/skills/level-0-meta/{code-review → morph-code-review}/scripts/scan-csharp.mjs +0 -0
  152. /package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/references/review-example-nextjs.md +0 -0
  153. /package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/scripts/scan-nextjs.mjs +0 -0
  154. /package/framework/skills/level-0-meta/{frontend-review → morph-frontend-review}/scripts/scan-accessibility.mjs +0 -0
  155. /package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/scripts/detect-dev-server.mjs +0 -0
  156. /package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/scripts/detect-stack.mjs +0 -0
  157. /package/framework/skills/level-1-workflows/{phase-clarify → morph-phase-clarify}/references/clarifications-example.md +0 -0
  158. /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/architecture-analysis-guide.md +0 -0
  159. /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/spec-authoring-guide.md +0 -0
  160. /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/spec-example.md +0 -0
  161. /package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/references/recap-example.md +0 -0
  162. /package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/references/vsa-implementation-guide.md +0 -0
  163. /package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/references/task-planning-patterns.md +0 -0
  164. /package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/references/tasks-example.md +0 -0
@@ -1,335 +0,0 @@
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/framework/standards/coding.md\` for complete .NET standards.`;
129
- }
130
-
131
- if (config?.language === 'javascript') {
132
- const techLine = config.technologies?.length > 0
133
- ? `\n- **Framework**: ${config.technologies.join(', ')}`
134
- : '';
135
-
136
- return `### JavaScript / TypeScript Conventions
137
-
138
- Based on detected patterns in your codebase:
139
-
140
- - **Package Manager**: ${config.packageManager}${techLine}
141
-
142
- **Recommendation**: Refer to framework standards for JavaScript best practices.`;
143
- }
144
-
145
- return 'No specific coding standards inferred. Check framework standards for guidance.';
146
- }
147
-
148
- /**
149
- * Generate architecture section
150
- */
151
- function generateArchitectureSection(structure) {
152
- const { architecture } = structure;
153
-
154
- const descriptions = {
155
- 'cli-library': `### CLI / Library Architecture
156
-
157
- Your project follows a CLI/Library pattern:
158
-
159
- - ✅ **bin/** entry points detected
160
- - ✅ **src/** source directory detected
161
- - ✅ **package.json** present
162
-
163
- **Key principles**:
164
- - Commands exposed via bin/
165
- - Core logic in src/commands/ and src/lib/
166
- - Public API exported from src/index.js`,
167
-
168
- 'nextjs-app-router': `### Next.js App Router Architecture
169
-
170
- Your project uses the Next.js App Router pattern:
171
-
172
- - ✅ **app/** directory detected (React Server Components)
173
-
174
- **Key principles**:
175
- - Server Components by default
176
- - Client Components with 'use client' directive
177
- - Route handlers in app/api/`,
178
-
179
- 'express-mvc': `### Express MVC Architecture
180
-
181
- Your project uses Express with MVC pattern:
182
-
183
- - ✅ **routes/** detected
184
- - ✅ **controllers/** detected`,
185
-
186
- 'clean-architecture': `### Clean Architecture
187
-
188
- Your project follows Clean Architecture pattern:
189
-
190
- - ✅ **Domain** layer detected (core business logic)
191
- - ✅ **Application** layer detected (use cases)
192
- - ✅ **Infrastructure** layer detected (implementations)
193
-
194
- **Key principles**:
195
- - Domain has no dependencies
196
- - Application depends on Domain
197
- - Infrastructure implements Application interfaces`,
198
-
199
- 'cqrs': `### CQRS Pattern
200
-
201
- Your project uses Command Query Responsibility Segregation:
202
-
203
- - ✅ **Commands** detected (write operations)
204
- - ✅ **Queries** detected (read operations)
205
-
206
- **Key principles**:
207
- - Separate read and write models
208
- - Commands return void or Task
209
- - Queries return data`,
210
-
211
- 'mvc': `### MVC Pattern
212
-
213
- Your project uses Model-View-Controller pattern:
214
-
215
- - ✅ **Controllers** detected
216
- - ✅ **Models** detected
217
- - ✅ **Views** detected`
218
- };
219
-
220
- return descriptions[architecture] || `Architecture: ${architecture}`;
221
- }
222
-
223
- /**
224
- * Generate recommendations
225
- */
226
- function generateRecommendations(structure, config, conversation) {
227
- const recommendations = [];
228
-
229
- // Recommend based on stack
230
- if (structure?.stack === 'blazor') {
231
- if (!structure.uiLibrary) {
232
- recommendations.push('Consider adding Fluent UI Blazor or MudBlazor for consistent UI components');
233
- }
234
-
235
- if (!structure.patterns.includes('AI Agents') && config?.technologies?.includes('Microsoft Agent Framework')) {
236
- recommendations.push('Setup detected Agent Framework but no agents found - check .morph/framework/standards/agent-framework-setup.md');
237
- }
238
- }
239
-
240
- if (structure?.stack === 'nodejs' || config?.language === 'javascript') {
241
- if (!structure?.patterns?.includes('Unit Tests')) {
242
- recommendations.push('No unit tests detected - consider adding test coverage with Jest or Vitest');
243
- }
244
-
245
- if (structure?.architecture === 'unknown') {
246
- recommendations.push('No clear architecture detected - consider organizing code into src/commands/, src/lib/, src/core/');
247
- }
248
- } else {
249
- // Recommend tests (generic / .NET)
250
- if (!structure?.patterns?.includes('Unit Tests')) {
251
- recommendations.push('No unit tests detected - consider adding test project');
252
- }
253
-
254
- // Recommend DI (only meaningful for C# / .NET)
255
- if (config?.language === 'csharp' && !structure?.patterns?.includes('Dependency Injection')) {
256
- recommendations.push('Consider implementing Dependency Injection pattern');
257
- }
258
-
259
- // Architecture recommendations (.NET)
260
- if (structure?.architecture === 'unknown' && structure?.folders?.hasServices) {
261
- recommendations.push('Service layer detected but no clear architecture - consider Clean Architecture or CQRS');
262
- }
263
- }
264
-
265
- return recommendations;
266
- }
267
-
268
- /**
269
- * Identify gaps between framework and project
270
- */
271
- function identifyGaps(structure, config) {
272
- const gaps = [];
273
-
274
- // Check for missing patterns
275
- const expectedPatterns = {
276
- blazor: ['Service Layer', 'Repository Pattern', 'Dependency Injection'],
277
- nextjs: ['API Routes', 'Components'],
278
- };
279
-
280
- const expected = expectedPatterns[structure?.stack];
281
- if (expected) {
282
- expected.forEach(pattern => {
283
- if (!structure?.patterns?.includes(pattern)) {
284
- gaps.push(`Missing: ${pattern}`);
285
- }
286
- });
287
- }
288
-
289
- return gaps;
290
- }
291
-
292
- /**
293
- * Filter important dependencies
294
- */
295
- function filterImportantDependencies(deps) {
296
- const important = deps.filter(dep => {
297
- // .NET Framework packages
298
- if (dep.includes('Microsoft.') || dep.includes('System.')) return true;
299
- // Blazor UI libraries
300
- if (dep.includes('Blazor') || dep.includes('FluentUI') || dep.includes('Mud')) return true;
301
- // .NET common tools
302
- if (dep.includes('Hangfire') || dep.includes('Serilog') || dep.includes('AutoMapper')) return true;
303
- // AI/ML (.NET)
304
- if (dep.includes('Agents') || dep.includes('AI') || dep.includes('OpenAI')) return true;
305
- // JS: frontend frameworks
306
- if (['next', 'react', 'react-dom', 'vue', 'nuxt', 'svelte', 'astro'].includes(dep)) return true;
307
- // JS: backend frameworks
308
- if (['express', 'fastify', 'hono', 'koa', 'nestjs', '@nestjs/core'].includes(dep)) return true;
309
- // JS: databases / ORMs
310
- if (['prisma', '@prisma/client', 'supabase', '@supabase/supabase-js', 'drizzle-orm', 'mongoose', 'typeorm'].includes(dep)) return true;
311
- // JS: auth
312
- if (['next-auth', 'clerk', '@clerk/nextjs', 'lucia', 'better-auth'].includes(dep)) return true;
313
- // JS: validation / schema
314
- if (['zod', 'yup', 'joi', 'valibot'].includes(dep)) return true;
315
- // JS: testing
316
- if (['vitest', 'jest', '@jest/core', 'mocha', 'cypress', 'playwright'].includes(dep)) return true;
317
- // JS: UI / styling
318
- if (['tailwindcss', '@mui/material', 'shadcn-ui', 'radix-ui', 'chakra-ui'].includes(dep)) return true;
319
- // JS: AI
320
- if (dep.includes('openai') || dep.includes('anthropic') || dep.includes('langchain') || dep.includes('ai')) return true;
321
- return false;
322
- });
323
-
324
- return important.length > 0 ? important : deps;
325
- }
326
-
327
- /**
328
- * Format key for display
329
- */
330
- function formatKey(key) {
331
- return key
332
- .replace(/([A-Z])/g, ' $1')
333
- .replace(/^./, str => str.toUpperCase())
334
- .trim();
335
- }
@@ -1,275 +0,0 @@
1
- /**
2
- * Structure Detector - Analyzes folder structure to infer stack and architecture
3
- */
4
-
5
- import { glob } from 'glob';
6
- import { join } from 'path';
7
- import { existsSync } from 'fs';
8
-
9
- /**
10
- * Detect project structure
11
- * @param {string} projectPath - Project root path
12
- * @returns {Promise<Object>} Structure detection results
13
- */
14
- export async function detectStructure(projectPath) {
15
- const result = {
16
- stack: 'unknown',
17
- architecture: 'unknown',
18
- uiLibrary: null,
19
- patterns: [],
20
- folders: {
21
- hasPages: false,
22
- hasComponents: false,
23
- hasServices: false,
24
- hasRepositories: false,
25
- hasAgents: false
26
- }
27
- };
28
-
29
- // Detect stack
30
- result.stack = await detectStack(projectPath);
31
-
32
- // Detect architecture pattern
33
- result.architecture = await detectArchitecture(projectPath);
34
-
35
- // Detect UI library
36
- if (result.stack === 'blazor') {
37
- result.uiLibrary = await detectUILibrary(projectPath);
38
- }
39
-
40
- // Detect patterns
41
- result.patterns = await detectPatterns(projectPath);
42
-
43
- // Analyze folders
44
- result.folders = await analyzeFolders(projectPath);
45
-
46
- return result;
47
- }
48
-
49
- /**
50
- * Detect stack type
51
- */
52
- async function detectStack(projectPath) {
53
- // Order matters: more specific patterns first
54
- const patterns = {
55
- blazor: [
56
- '**/*.razor',
57
- '**/Pages/**/*.razor',
58
- '**/Components/**/*.razor'
59
- ],
60
- nextjs: [
61
- '**/next.config.js',
62
- '**/next.config.mjs',
63
- '**/next.config.ts',
64
- 'pages/**/*.tsx',
65
- 'app/**/*.tsx',
66
- '**/pages/**/*.tsx',
67
- '**/app/**/*.tsx'
68
- ],
69
- react: [
70
- 'src/App.jsx',
71
- 'src/App.tsx',
72
- 'vite.config.js',
73
- 'craco.config.js'
74
- ],
75
- vue: [
76
- 'vite.config.js', // Vue 3 + Vite
77
- 'vue.config.js', // Vue 2
78
- 'src/App.vue'
79
- ],
80
- dotnet: [
81
- '**/*.csproj',
82
- '**/Program.cs'
83
- ],
84
- typescript: [
85
- 'tsconfig.json',
86
- 'src/**/*.ts'
87
- ],
88
- nodejs: [
89
- 'package.json' // Fallback: generic Node.js
90
- ],
91
- python: [
92
- 'requirements.txt',
93
- 'pyproject.toml',
94
- 'setup.py'
95
- ],
96
- go: [
97
- 'go.mod',
98
- 'main.go'
99
- ]
100
- };
101
-
102
- const globIgnore = ['framework/**', 'test/**', 'node_modules/**', '.morph/**'];
103
-
104
- for (const [stack, globs] of Object.entries(patterns)) {
105
- for (const pattern of globs) {
106
- const files = await glob(pattern, { cwd: projectPath, nodir: true, ignore: globIgnore });
107
- if (files.length > 0) {
108
- return stack;
109
- }
110
- }
111
- }
112
-
113
- return 'unknown';
114
- }
115
-
116
- /**
117
- * Detect architecture pattern
118
- */
119
- async function detectArchitecture(projectPath) {
120
- const globIgnore = ['framework/**', 'test/**', 'node_modules/**', '.morph/**'];
121
-
122
- const checks = [
123
- // .NET: Clean Architecture
124
- {
125
- pattern: 'clean-architecture',
126
- indicators: [
127
- existsSync(join(projectPath, 'src', 'Application')),
128
- existsSync(join(projectPath, 'src', 'Domain')),
129
- existsSync(join(projectPath, 'src', 'Infrastructure'))
130
- ]
131
- },
132
- // .NET: CQRS
133
- {
134
- pattern: 'cqrs',
135
- indicators: [
136
- await glob('**/Commands/**/*.cs', { cwd: projectPath, ignore: globIgnore }).then(f => f.length > 0),
137
- await glob('**/Queries/**/*.cs', { cwd: projectPath, ignore: globIgnore }).then(f => f.length > 0)
138
- ]
139
- },
140
- // .NET: MVC
141
- {
142
- pattern: 'mvc',
143
- indicators: [
144
- existsSync(join(projectPath, 'Controllers')),
145
- existsSync(join(projectPath, 'Models')),
146
- existsSync(join(projectPath, 'Views'))
147
- ]
148
- },
149
- // JS: CLI / Library (bin + src + lib)
150
- {
151
- pattern: 'cli-library',
152
- indicators: [
153
- existsSync(join(projectPath, 'bin')),
154
- existsSync(join(projectPath, 'src')),
155
- existsSync(join(projectPath, 'package.json'))
156
- ]
157
- },
158
- // JS: Next.js App Router
159
- {
160
- pattern: 'nextjs-app-router',
161
- indicators: [
162
- existsSync(join(projectPath, 'app')),
163
- await glob('app/**/*.{js,ts,jsx,tsx}', { cwd: projectPath, ignore: globIgnore }).then(f => f.length > 0)
164
- ]
165
- },
166
- // JS: Express MVC
167
- {
168
- pattern: 'express-mvc',
169
- indicators: [
170
- existsSync(join(projectPath, 'src', 'routes')) || existsSync(join(projectPath, 'routes')),
171
- existsSync(join(projectPath, 'src', 'controllers')) || existsSync(join(projectPath, 'controllers'))
172
- ]
173
- }
174
- ];
175
-
176
- for (const { pattern, indicators } of checks) {
177
- if (indicators.every(Boolean)) {
178
- return pattern;
179
- }
180
- }
181
-
182
- return 'unknown';
183
- }
184
-
185
- /**
186
- * Detect UI library (Blazor projects)
187
- */
188
- async function detectUILibrary(projectPath) {
189
- const csprojFiles = await glob('**/*.csproj', { cwd: projectPath });
190
-
191
- for (const csprojFile of csprojFiles) {
192
- const content = await import('fs').then(fs =>
193
- fs.promises.readFile(join(projectPath, csprojFile), 'utf8')
194
- );
195
-
196
- if (content.includes('FluentUI.Blazor') || content.includes('Microsoft.FluentUI.AspNetCore.Components')) {
197
- return 'fluent-ui';
198
- }
199
-
200
- if (content.includes('MudBlazor')) {
201
- return 'mudblazor';
202
- }
203
- }
204
-
205
- return null;
206
- }
207
-
208
- /**
209
- * Detect common patterns
210
- */
211
- async function detectPatterns(projectPath) {
212
- const patterns = [];
213
- // Ignore template/vendor directories; keep test/ accessible for JS test detection
214
- const globIgnore = ['framework/**', 'test/fixtures/**', 'node_modules/**', '.morph/**'];
215
-
216
- // C# / .NET patterns
217
- const dotnetChecks = [
218
- { name: 'Repository Pattern', glob: '**/*Repository.cs' },
219
- { name: 'Service Layer', glob: '**/*Service.cs' },
220
- { name: 'DTOs', glob: '**/*Dto.cs' },
221
- { name: 'Entity Framework', glob: '**/Migrations/**/*.cs' },
222
- { name: 'Dependency Injection', glob: '**/DependencyInjection.cs' },
223
- { name: 'Hangfire Jobs', glob: '**/*Job.cs' },
224
- { name: 'AI Agents', glob: '**/*Agent.cs' },
225
- { name: 'Unit Tests', glob: '**/*.Tests/**/*.cs' }
226
- ];
227
-
228
- // JavaScript / TypeScript patterns
229
- const jsChecks = [
230
- { name: 'Service Layer', glob: 'src/**/*Service.js' },
231
- { name: 'Service Layer', glob: 'src/**/*Service.ts' },
232
- { name: 'Repository Pattern', glob: 'src/**/*Repository.js' },
233
- { name: 'Repository Pattern', glob: 'src/**/*Repository.ts' },
234
- { name: 'API Routes', glob: 'src/**/routes/**/*.{js,ts}' },
235
- { name: 'API Routes', glob: 'src/commands/**/*.{js,ts}' },
236
- { name: 'Unit Tests', glob: 'test/**/*.test.{js,ts}' },
237
- { name: 'Unit Tests', glob: 'src/**/*.test.{js,ts}' },
238
- { name: 'Unit Tests', glob: 'src/**/*.spec.{js,ts}' }
239
- ];
240
-
241
- const allChecks = [...dotnetChecks, ...jsChecks];
242
- const seen = new Set();
243
-
244
- for (const { name, glob: pattern } of allChecks) {
245
- if (seen.has(name)) continue;
246
- const files = await glob(pattern, { cwd: projectPath, nodir: true, ignore: globIgnore });
247
- if (files.length > 0) {
248
- patterns.push(name);
249
- seen.add(name);
250
- }
251
- }
252
-
253
- return patterns;
254
- }
255
-
256
- /**
257
- * Analyze folder structure
258
- */
259
- async function analyzeFolders(projectPath) {
260
- const folders = {
261
- hasPages: false,
262
- hasComponents: false,
263
- hasServices: false,
264
- hasRepositories: false,
265
- hasAgents: false
266
- };
267
-
268
- folders.hasPages = await glob('**/Pages/**/*', { cwd: projectPath }).then(f => f.length > 0);
269
- folders.hasComponents = await glob('**/Components/**/*', { cwd: projectPath }).then(f => f.length > 0);
270
- folders.hasServices = await glob('**/Services/**/*', { cwd: projectPath }).then(f => f.length > 0);
271
- folders.hasRepositories = await glob('**/Repositories/**/*', { cwd: projectPath }).then(f => f.length > 0);
272
- folders.hasAgents = await glob('**/Agents/**/*', { cwd: projectPath }).then(f => f.length > 0);
273
-
274
- return folders;
275
- }