@polymorphism-tech/morph-spec 2.3.0 → 3.0.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.
Files changed (166) hide show
  1. package/CLAUDE.md +446 -1730
  2. package/README.md +515 -516
  3. package/bin/morph-spec.js +366 -294
  4. package/bin/task-manager.js +429 -368
  5. package/bin/validate.js +369 -268
  6. package/content/.claude/commands/morph-apply.md +221 -158
  7. package/content/.claude/commands/morph-deploy.md +529 -0
  8. package/content/.claude/commands/morph-preflight.md +227 -0
  9. package/content/.claude/commands/morph-proposal.md +122 -101
  10. package/content/.claude/commands/morph-status.md +86 -86
  11. package/content/.claude/commands/morph-troubleshoot.md +122 -0
  12. package/content/.claude/skills/infra/azure-deploy-specialist.md +699 -0
  13. package/content/.claude/skills/level-0-meta/README.md +7 -0
  14. package/content/.claude/skills/level-0-meta/code-review.md +226 -0
  15. package/content/.claude/skills/level-0-meta/morph-checklist.md +117 -0
  16. package/content/.claude/skills/level-0-meta/simulation-checklist.md +77 -0
  17. package/content/.claude/skills/level-1-workflows/README.md +7 -0
  18. package/content/.claude/skills/level-1-workflows/morph-replicate.md +213 -0
  19. package/content/.claude/{commands/morph-clarify.md → skills/level-1-workflows/phase-clarify.md} +131 -184
  20. package/content/.claude/{commands/morph-design.md → skills/level-1-workflows/phase-design.md} +213 -275
  21. package/content/.claude/skills/level-1-workflows/phase-setup.md +106 -0
  22. package/content/.claude/skills/level-1-workflows/phase-tasks.md +164 -0
  23. package/content/.claude/{commands/morph-uiux.md → skills/level-1-workflows/phase-uiux.md} +169 -211
  24. package/content/.claude/skills/level-2-domains/README.md +14 -0
  25. package/content/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +192 -0
  26. package/content/.claude/skills/{specialists → level-2-domains/architecture}/po-pm-advisor.md +197 -197
  27. package/content/.claude/skills/level-2-domains/architecture/standards-architect.md +156 -0
  28. package/content/.claude/skills/level-2-domains/backend/dotnet-senior.md +287 -0
  29. package/content/.claude/skills/level-2-domains/backend/ef-modeler.md +113 -0
  30. package/content/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +126 -0
  31. package/content/.claude/skills/level-2-domains/backend/ms-agent-expert.md +109 -0
  32. package/content/.claude/skills/level-2-domains/frontend/blazor-builder.md +210 -0
  33. package/content/.claude/skills/level-2-domains/frontend/nextjs-expert.md +154 -0
  34. package/content/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +191 -0
  35. package/content/.claude/skills/{specialists → level-2-domains/infrastructure}/azure-architect.md +142 -142
  36. package/content/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +126 -0
  37. package/content/.claude/skills/level-2-domains/infrastructure/container-specialist.md +131 -0
  38. package/content/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +119 -0
  39. package/content/.claude/skills/level-2-domains/integrations/asaas-financial.md +130 -0
  40. package/content/.claude/skills/level-2-domains/integrations/azure-identity.md +142 -0
  41. package/content/.claude/skills/level-2-domains/integrations/clerk-auth.md +108 -0
  42. package/content/.claude/skills/level-2-domains/integrations/resend-email.md +119 -0
  43. package/content/.claude/skills/level-2-domains/quality/code-analyzer.md +235 -0
  44. package/content/.claude/skills/level-2-domains/quality/testing-specialist.md +126 -0
  45. package/content/.claude/skills/level-3-technologies/README.md +7 -0
  46. package/content/.claude/skills/level-4-patterns/README.md +7 -0
  47. package/content/.claude/skills/specialists/prompt-engineer.md +189 -0
  48. package/content/.claude/skills/specialists/seo-growth-hacker.md +320 -0
  49. package/content/.morph/config/agents.json +762 -242
  50. package/content/.morph/config/config.template.json +122 -108
  51. package/content/.morph/docs/workflows/design-impl.md +37 -0
  52. package/content/.morph/docs/workflows/enforcement-pipeline.md +668 -0
  53. package/content/.morph/docs/workflows/fast-track.md +29 -0
  54. package/content/.morph/docs/workflows/full-morph.md +76 -0
  55. package/content/.morph/docs/workflows/standard.md +44 -0
  56. package/content/.morph/docs/workflows/ui-refresh.md +39 -0
  57. package/content/.morph/examples/scheduled-reports/decisions.md +158 -0
  58. package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
  59. package/content/.morph/examples/scheduled-reports/spec.md +267 -0
  60. package/content/.morph/hooks/README.md +348 -239
  61. package/content/.morph/hooks/pre-commit-agents.sh +24 -24
  62. package/content/.morph/hooks/task-completed.js +73 -0
  63. package/content/.morph/hooks/teammate-idle.js +68 -0
  64. package/content/.morph/schemas/tasks.schema.json +220 -0
  65. package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
  66. package/content/.morph/standards/agent-framework-production.md +410 -0
  67. package/content/.morph/standards/agent-framework-setup.md +413 -453
  68. package/content/.morph/standards/agent-framework-workflows.md +349 -0
  69. package/content/.morph/standards/agent-teams-workflow.md +474 -0
  70. package/content/.morph/standards/architecture.md +325 -325
  71. package/content/.morph/standards/azure.md +605 -379
  72. package/content/.morph/standards/dotnet10-migration.md +520 -494
  73. package/content/.morph/templates/CONTEXT-FEATURE.md +276 -0
  74. package/content/.morph/templates/CONTEXT.md +170 -0
  75. package/content/.morph/templates/agent.cs +163 -172
  76. package/content/.morph/templates/clarify-questions.md +159 -0
  77. package/content/.morph/templates/contracts/Commands.cs +74 -0
  78. package/content/.morph/templates/contracts/Entities.cs +25 -0
  79. package/content/.morph/templates/contracts/Queries.cs +74 -0
  80. package/content/.morph/templates/contracts/README.md +74 -0
  81. package/content/.morph/templates/decisions.md +123 -106
  82. package/content/.morph/templates/infra/azure-pipelines-deploy.yml +480 -0
  83. package/content/.morph/templates/infra/deploy-checklist.md +426 -0
  84. package/content/.morph/templates/proposal.md +141 -155
  85. package/content/.morph/templates/recap.md +94 -105
  86. package/content/.morph/templates/simulation.md +353 -0
  87. package/content/.morph/templates/spec.md +149 -148
  88. package/content/.morph/templates/state.template.json +222 -222
  89. package/content/.morph/templates/tasks.md +257 -235
  90. package/content/.morph/templates/ui-components.md +362 -276
  91. package/content/CLAUDE.md +150 -442
  92. package/detectors/structure-detector.js +245 -250
  93. package/docs/README.md +144 -149
  94. package/docs/getting-started.md +301 -302
  95. package/docs/installation.md +361 -361
  96. package/docs/validation-checklist.md +265 -266
  97. package/package.json +80 -80
  98. package/src/commands/advance-phase.js +266 -0
  99. package/src/commands/analyze-blazor-concurrency.js +193 -0
  100. package/src/commands/deploy.js +780 -0
  101. package/src/commands/detect-agents.js +167 -0
  102. package/src/commands/doctor.js +356 -280
  103. package/src/commands/generate-context.js +40 -0
  104. package/src/commands/init.js +258 -245
  105. package/src/commands/lint-fluent.js +352 -0
  106. package/src/commands/rollback-phase.js +185 -0
  107. package/src/commands/session-summary.js +291 -0
  108. package/src/commands/task.js +78 -75
  109. package/src/commands/troubleshoot.js +222 -0
  110. package/src/commands/update.js +192 -159
  111. package/src/commands/validate-blazor-state.js +210 -0
  112. package/src/commands/validate-blazor.js +156 -0
  113. package/src/commands/validate-css.js +84 -0
  114. package/src/commands/validate-phase.js +221 -0
  115. package/src/lib/blazor-concurrency-analyzer.js +288 -0
  116. package/src/lib/blazor-state-validator.js +291 -0
  117. package/src/lib/blazor-validator.js +374 -0
  118. package/src/lib/complexity-analyzer.js +441 -292
  119. package/src/lib/context-generator.js +513 -0
  120. package/src/lib/continuous-validator.js +421 -440
  121. package/src/lib/css-validator.js +352 -0
  122. package/src/lib/decision-constraint-loader.js +109 -0
  123. package/src/lib/design-system-detector.js +187 -0
  124. package/src/lib/design-system-scaffolder.js +299 -0
  125. package/src/lib/hook-executor.js +256 -0
  126. package/src/lib/recap-generator.js +205 -0
  127. package/src/lib/spec-validator.js +258 -0
  128. package/src/lib/standards-context-injector.js +287 -0
  129. package/src/lib/state-manager.js +397 -340
  130. package/src/lib/team-orchestrator.js +322 -0
  131. package/src/lib/troubleshoot-grep.js +194 -0
  132. package/src/lib/troubleshoot-index.js +144 -0
  133. package/src/lib/validation-runner.js +283 -0
  134. package/src/lib/validators/contract-compliance-validator.js +273 -0
  135. package/src/lib/validators/design-system-validator.js +231 -0
  136. package/src/utils/file-copier.js +187 -139
  137. package/content/.claude/commands/morph-costs.md +0 -206
  138. package/content/.claude/commands/morph-setup.md +0 -100
  139. package/content/.claude/commands/morph-tasks.md +0 -319
  140. package/content/.claude/skills/infra/bicep-architect.md +0 -419
  141. package/content/.claude/skills/infra/container-specialist.md +0 -437
  142. package/content/.claude/skills/infra/devops-engineer.md +0 -405
  143. package/content/.claude/skills/integrations/asaas-financial.md +0 -333
  144. package/content/.claude/skills/integrations/azure-identity.md +0 -309
  145. package/content/.claude/skills/integrations/clerk-auth.md +0 -290
  146. package/content/.claude/skills/specialists/ai-system-architect.md +0 -604
  147. package/content/.claude/skills/specialists/cost-guardian.md +0 -110
  148. package/content/.claude/skills/specialists/ef-modeler.md +0 -211
  149. package/content/.claude/skills/specialists/hangfire-orchestrator.md +0 -255
  150. package/content/.claude/skills/specialists/ms-agent-expert.md +0 -263
  151. package/content/.claude/skills/specialists/standards-architect.md +0 -78
  152. package/content/.claude/skills/specialists/ui-ux-designer.md +0 -1100
  153. package/content/.claude/skills/stacks/dotnet-blazor.md +0 -606
  154. package/content/.claude/skills/stacks/dotnet-nextjs.md +0 -402
  155. package/content/.claude/skills/stacks/shopify.md +0 -445
  156. package/content/.morph/config/azure-pricing.json +0 -70
  157. package/content/.morph/config/azure-pricing.schema.json +0 -50
  158. package/content/.morph/hooks/pre-commit-costs.sh +0 -91
  159. package/docs/api/cost-calculator.js.html +0 -513
  160. package/docs/api/design-system-generator.js.html +0 -382
  161. package/docs/api/global.html +0 -5263
  162. package/docs/api/index.html +0 -96
  163. package/docs/api/state-manager.js.html +0 -423
  164. package/src/commands/cost.js +0 -181
  165. package/src/commands/update-pricing.js +0 -206
  166. package/src/lib/cost-calculator.js +0 -429
@@ -1,250 +1,245 @@
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
- ],
67
- shopify: [
68
- '**/*.liquid',
69
- 'sections/**/*.liquid',
70
- 'templates/**/*.liquid'
71
- ],
72
- react: [
73
- 'src/App.jsx',
74
- 'src/App.tsx',
75
- 'vite.config.js',
76
- 'craco.config.js'
77
- ],
78
- vue: [
79
- 'vite.config.js', // Vue 3 + Vite
80
- 'vue.config.js', // Vue 2
81
- 'src/App.vue'
82
- ],
83
- dotnet: [
84
- '**/*.csproj',
85
- '**/Program.cs'
86
- ],
87
- typescript: [
88
- 'tsconfig.json',
89
- 'src/**/*.ts'
90
- ],
91
- nodejs: [
92
- 'package.json' // Fallback: generic Node.js
93
- ],
94
- python: [
95
- 'requirements.txt',
96
- 'pyproject.toml',
97
- 'setup.py'
98
- ],
99
- go: [
100
- 'go.mod',
101
- 'main.go'
102
- ]
103
- };
104
-
105
- for (const [stack, globs] of Object.entries(patterns)) {
106
- for (const pattern of globs) {
107
- const files = await glob(pattern, { cwd: projectPath, nodir: true });
108
- if (files.length > 0) {
109
- return stack;
110
- }
111
- }
112
- }
113
-
114
- return 'unknown';
115
- }
116
-
117
- /**
118
- * Detect architecture pattern
119
- */
120
- async function detectArchitecture(projectPath) {
121
- const checks = [
122
- {
123
- pattern: 'clean-architecture',
124
- indicators: [
125
- existsSync(join(projectPath, 'src', 'Application')),
126
- existsSync(join(projectPath, 'src', 'Domain')),
127
- existsSync(join(projectPath, 'src', 'Infrastructure'))
128
- ]
129
- },
130
- {
131
- pattern: 'cqrs',
132
- indicators: [
133
- await glob('**/Commands/**/*.cs', { cwd: projectPath }).then(f => f.length > 0),
134
- await glob('**/Queries/**/*.cs', { cwd: projectPath }).then(f => f.length > 0)
135
- ]
136
- },
137
- {
138
- pattern: 'mvc',
139
- indicators: [
140
- existsSync(join(projectPath, 'Controllers')),
141
- existsSync(join(projectPath, 'Models')),
142
- existsSync(join(projectPath, 'Views'))
143
- ]
144
- }
145
- ];
146
-
147
- for (const { pattern, indicators } of checks) {
148
- if (indicators.every(Boolean)) {
149
- return pattern;
150
- }
151
- }
152
-
153
- return 'unknown';
154
- }
155
-
156
- /**
157
- * Detect UI library (Blazor projects)
158
- */
159
- async function detectUILibrary(projectPath) {
160
- const csprojFiles = await glob('**/*.csproj', { cwd: projectPath });
161
-
162
- for (const csprojFile of csprojFiles) {
163
- const content = await import('fs').then(fs =>
164
- fs.promises.readFile(join(projectPath, csprojFile), 'utf8')
165
- );
166
-
167
- if (content.includes('FluentUI.Blazor') || content.includes('Microsoft.FluentUI.AspNetCore.Components')) {
168
- return 'fluent-ui';
169
- }
170
-
171
- if (content.includes('MudBlazor')) {
172
- return 'mudblazor';
173
- }
174
- }
175
-
176
- return null;
177
- }
178
-
179
- /**
180
- * Detect common patterns
181
- */
182
- async function detectPatterns(projectPath) {
183
- const patterns = [];
184
-
185
- // Check for specific patterns
186
- const checks = [
187
- {
188
- name: 'Repository Pattern',
189
- glob: '**/*Repository.cs'
190
- },
191
- {
192
- name: 'Service Layer',
193
- glob: '**/*Service.cs'
194
- },
195
- {
196
- name: 'DTOs',
197
- glob: '**/*Dto.cs'
198
- },
199
- {
200
- name: 'Entity Framework',
201
- glob: '**/Migrations/**/*.cs'
202
- },
203
- {
204
- name: 'Dependency Injection',
205
- glob: '**/DependencyInjection.cs'
206
- },
207
- {
208
- name: 'Hangfire Jobs',
209
- glob: '**/*Job.cs'
210
- },
211
- {
212
- name: 'AI Agents',
213
- glob: '**/*Agent.cs'
214
- },
215
- {
216
- name: 'Unit Tests',
217
- glob: '**/*.Tests/**/*.cs'
218
- }
219
- ];
220
-
221
- for (const { name, glob: pattern } of checks) {
222
- const files = await glob(pattern, { cwd: projectPath, nodir: true });
223
- if (files.length > 0) {
224
- patterns.push(name);
225
- }
226
- }
227
-
228
- return patterns;
229
- }
230
-
231
- /**
232
- * Analyze folder structure
233
- */
234
- async function analyzeFolders(projectPath) {
235
- const folders = {
236
- hasPages: false,
237
- hasComponents: false,
238
- hasServices: false,
239
- hasRepositories: false,
240
- hasAgents: false
241
- };
242
-
243
- folders.hasPages = await glob('**/Pages/**/*', { cwd: projectPath }).then(f => f.length > 0);
244
- folders.hasComponents = await glob('**/Components/**/*', { cwd: projectPath }).then(f => f.length > 0);
245
- folders.hasServices = await glob('**/Services/**/*', { cwd: projectPath }).then(f => f.length > 0);
246
- folders.hasRepositories = await glob('**/Repositories/**/*', { cwd: projectPath }).then(f => f.length > 0);
247
- folders.hasAgents = await glob('**/Agents/**/*', { cwd: projectPath }).then(f => f.length > 0);
248
-
249
- return folders;
250
- }
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
+ ],
67
+ react: [
68
+ 'src/App.jsx',
69
+ 'src/App.tsx',
70
+ 'vite.config.js',
71
+ 'craco.config.js'
72
+ ],
73
+ vue: [
74
+ 'vite.config.js', // Vue 3 + Vite
75
+ 'vue.config.js', // Vue 2
76
+ 'src/App.vue'
77
+ ],
78
+ dotnet: [
79
+ '**/*.csproj',
80
+ '**/Program.cs'
81
+ ],
82
+ typescript: [
83
+ 'tsconfig.json',
84
+ 'src/**/*.ts'
85
+ ],
86
+ nodejs: [
87
+ 'package.json' // Fallback: generic Node.js
88
+ ],
89
+ python: [
90
+ 'requirements.txt',
91
+ 'pyproject.toml',
92
+ 'setup.py'
93
+ ],
94
+ go: [
95
+ 'go.mod',
96
+ 'main.go'
97
+ ]
98
+ };
99
+
100
+ for (const [stack, globs] of Object.entries(patterns)) {
101
+ for (const pattern of globs) {
102
+ const files = await glob(pattern, { cwd: projectPath, nodir: true });
103
+ if (files.length > 0) {
104
+ return stack;
105
+ }
106
+ }
107
+ }
108
+
109
+ return 'unknown';
110
+ }
111
+
112
+ /**
113
+ * Detect architecture pattern
114
+ */
115
+ async function detectArchitecture(projectPath) {
116
+ const checks = [
117
+ {
118
+ pattern: 'clean-architecture',
119
+ indicators: [
120
+ existsSync(join(projectPath, 'src', 'Application')),
121
+ existsSync(join(projectPath, 'src', 'Domain')),
122
+ existsSync(join(projectPath, 'src', 'Infrastructure'))
123
+ ]
124
+ },
125
+ {
126
+ pattern: 'cqrs',
127
+ indicators: [
128
+ await glob('**/Commands/**/*.cs', { cwd: projectPath }).then(f => f.length > 0),
129
+ await glob('**/Queries/**/*.cs', { cwd: projectPath }).then(f => f.length > 0)
130
+ ]
131
+ },
132
+ {
133
+ pattern: 'mvc',
134
+ indicators: [
135
+ existsSync(join(projectPath, 'Controllers')),
136
+ existsSync(join(projectPath, 'Models')),
137
+ existsSync(join(projectPath, 'Views'))
138
+ ]
139
+ }
140
+ ];
141
+
142
+ for (const { pattern, indicators } of checks) {
143
+ if (indicators.every(Boolean)) {
144
+ return pattern;
145
+ }
146
+ }
147
+
148
+ return 'unknown';
149
+ }
150
+
151
+ /**
152
+ * Detect UI library (Blazor projects)
153
+ */
154
+ async function detectUILibrary(projectPath) {
155
+ const csprojFiles = await glob('**/*.csproj', { cwd: projectPath });
156
+
157
+ for (const csprojFile of csprojFiles) {
158
+ const content = await import('fs').then(fs =>
159
+ fs.promises.readFile(join(projectPath, csprojFile), 'utf8')
160
+ );
161
+
162
+ if (content.includes('FluentUI.Blazor') || content.includes('Microsoft.FluentUI.AspNetCore.Components')) {
163
+ return 'fluent-ui';
164
+ }
165
+
166
+ if (content.includes('MudBlazor')) {
167
+ return 'mudblazor';
168
+ }
169
+ }
170
+
171
+ return null;
172
+ }
173
+
174
+ /**
175
+ * Detect common patterns
176
+ */
177
+ async function detectPatterns(projectPath) {
178
+ const patterns = [];
179
+
180
+ // Check for specific patterns
181
+ const checks = [
182
+ {
183
+ name: 'Repository Pattern',
184
+ glob: '**/*Repository.cs'
185
+ },
186
+ {
187
+ name: 'Service Layer',
188
+ glob: '**/*Service.cs'
189
+ },
190
+ {
191
+ name: 'DTOs',
192
+ glob: '**/*Dto.cs'
193
+ },
194
+ {
195
+ name: 'Entity Framework',
196
+ glob: '**/Migrations/**/*.cs'
197
+ },
198
+ {
199
+ name: 'Dependency Injection',
200
+ glob: '**/DependencyInjection.cs'
201
+ },
202
+ {
203
+ name: 'Hangfire Jobs',
204
+ glob: '**/*Job.cs'
205
+ },
206
+ {
207
+ name: 'AI Agents',
208
+ glob: '**/*Agent.cs'
209
+ },
210
+ {
211
+ name: 'Unit Tests',
212
+ glob: '**/*.Tests/**/*.cs'
213
+ }
214
+ ];
215
+
216
+ for (const { name, glob: pattern } of checks) {
217
+ const files = await glob(pattern, { cwd: projectPath, nodir: true });
218
+ if (files.length > 0) {
219
+ patterns.push(name);
220
+ }
221
+ }
222
+
223
+ return patterns;
224
+ }
225
+
226
+ /**
227
+ * Analyze folder structure
228
+ */
229
+ async function analyzeFolders(projectPath) {
230
+ const folders = {
231
+ hasPages: false,
232
+ hasComponents: false,
233
+ hasServices: false,
234
+ hasRepositories: false,
235
+ hasAgents: false
236
+ };
237
+
238
+ folders.hasPages = await glob('**/Pages/**/*', { cwd: projectPath }).then(f => f.length > 0);
239
+ folders.hasComponents = await glob('**/Components/**/*', { cwd: projectPath }).then(f => f.length > 0);
240
+ folders.hasServices = await glob('**/Services/**/*', { cwd: projectPath }).then(f => f.length > 0);
241
+ folders.hasRepositories = await glob('**/Repositories/**/*', { cwd: projectPath }).then(f => f.length > 0);
242
+ folders.hasAgents = await glob('**/Agents/**/*', { cwd: projectPath }).then(f => f.length > 0);
243
+
244
+ return folders;
245
+ }