@polymorphism-tech/morph-spec 4.8.19 → 4.10.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 +21 -0
- package/README.md +2 -2
- package/bin/morph-spec.js +44 -55
- package/bin/task-manager.js +133 -20
- package/bin/validate.js +67 -33
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +201 -203
- package/docs/QUICKSTART.md +2 -2
- package/framework/CLAUDE.md +99 -77
- package/framework/agents.json +734 -182
- package/framework/commands/commit.md +166 -0
- package/framework/commands/morph-apply.md +13 -2
- package/framework/commands/morph-archive.md +8 -2
- package/framework/commands/morph-infra.md +6 -0
- package/framework/commands/morph-preflight.md +6 -0
- package/framework/commands/morph-proposal.md +56 -7
- package/framework/commands/morph-status.md +6 -0
- package/framework/commands/morph-troubleshoot.md +6 -0
- package/framework/hooks/claude-code/notification/approval-reminder.js +3 -2
- package/framework/hooks/claude-code/post-tool-use/context-refresh.js +1 -1
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +155 -32
- package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +78 -0
- package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +8 -17
- package/framework/hooks/claude-code/pre-compact/save-morph-context.js +16 -3
- package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +4 -3
- package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +4 -3
- package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +60 -0
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +124 -2
- package/framework/hooks/claude-code/session-start/post-compact-restore.js +41 -0
- package/framework/hooks/claude-code/statusline.py +76 -30
- package/framework/hooks/claude-code/stop/validate-completion.js +2 -15
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +23 -5
- package/framework/hooks/claude-code/user-prompt/set-terminal-title.js +14 -6
- package/framework/hooks/shared/activity-logger.js +0 -24
- package/framework/hooks/shared/compact-restore.js +100 -0
- package/framework/hooks/shared/dispatch-helpers.js +116 -0
- package/framework/hooks/shared/phase-utils.js +12 -5
- package/framework/hooks/shared/skill-reminder-helpers.js +79 -0
- package/framework/hooks/shared/stale-task-reset.js +57 -0
- package/framework/hooks/shared/state-reader.js +29 -5
- package/framework/hooks/shared/worktree-helpers.js +53 -0
- package/framework/phases.json +69 -14
- package/framework/rules/morph-workflow.md +88 -86
- package/framework/skills/level-0-meta/mcp-registry.json +86 -51
- package/framework/skills/level-0-meta/{brainstorming → morph-brainstorming}/SKILL.md +14 -17
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{code-review → morph-code-review}/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/SKILL.md +163 -163
- package/framework/skills/level-0-meta/{frontend-review → morph-frontend-review}/SKILL.md +9 -9
- package/framework/skills/level-0-meta/morph-init/SKILL.md +77 -12
- package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/SKILL.md +62 -15
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +1 -1
- package/framework/skills/level-0-meta/{simulation-checklist → morph-simulation-checklist}/SKILL.md +1 -1
- package/framework/skills/level-0-meta/{terminal-title → morph-terminal-title}/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/SKILL.md +3 -4
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/references/tools-per-phase.md +7 -7
- package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/scripts/check-phase-outputs.mjs +2 -2
- package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +238 -0
- package/framework/skills/level-1-workflows/{phase-codebase-analysis → morph-phase-codebase-analysis}/SKILL.md +3 -3
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +507 -0
- package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/SKILL.md +168 -27
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +50 -0
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +45 -0
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +47 -0
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +254 -0
- package/framework/skills/level-1-workflows/{phase-setup → morph-phase-setup}/SKILL.md +50 -3
- package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/SKILL.md +48 -11
- package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/scripts/validate-tasks.mjs +3 -3
- package/framework/skills/level-1-workflows/{phase-uiux → morph-phase-uiux}/SKILL.md +46 -11
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +97 -0
- package/framework/standards/STANDARDS.json +640 -88
- package/framework/standards/infrastructure/vercel/vercel-database.md +106 -0
- package/framework/standards/integration/mcp/mcp-tools.md +25 -7
- package/framework/templates/REGISTRY.json +1825 -1909
- package/framework/templates/context/CONTEXT-FEATURE.md +276 -276
- package/framework/templates/docs/onboarding.md +3 -7
- package/package.json +2 -7
- package/src/commands/agents/dispatch-agents.js +104 -6
- package/src/commands/mcp/mcp-setup.js +39 -2
- package/src/commands/phase/phase-reset.js +74 -0
- package/src/commands/project/doctor.js +34 -51
- package/src/commands/project/init.js +1 -1
- package/src/commands/project/status.js +2 -2
- package/src/commands/project/update.js +381 -365
- package/src/commands/project/worktree.js +154 -0
- package/src/commands/scope/escalate.js +215 -0
- package/src/commands/state/advance-phase.js +132 -68
- package/src/commands/state/approve.js +2 -2
- package/src/commands/state/index.js +7 -8
- package/src/commands/state/phase-runner.js +1 -1
- package/src/commands/state/state.js +61 -6
- package/src/commands/task/expand.js +100 -0
- package/src/commands/tasks/task.js +78 -99
- package/src/commands/templates/template-render.js +93 -173
- package/src/commands/trust/trust.js +26 -21
- package/src/core/paths/output-schema.js +19 -3
- package/src/core/state/phase-state-machine.js +7 -4
- package/src/core/state/state-manager.js +32 -57
- package/src/core/workflows/workflow-detector.js +9 -87
- package/src/lib/detectors/claude-config-detector.js +93 -347
- package/src/lib/detectors/design-system-detector.js +189 -189
- package/src/lib/detectors/index.js +155 -57
- package/src/lib/generators/context-generator.js +2 -2
- package/src/lib/installers/mcp-installer.js +37 -5
- package/src/lib/phase-chain/phase-validator.js +336 -0
- package/src/lib/scope/impact-analyzer.js +106 -0
- package/src/lib/stack/stack-profile.js +88 -0
- package/src/lib/tasks/task-classifier.js +16 -0
- package/src/lib/tasks/task-parser.js +1 -1
- package/src/lib/tasks/test-runner.js +77 -0
- package/src/lib/trust/trust-manager.js +32 -144
- package/src/lib/validators/shared/emit-validator-dispatch.js +64 -0
- package/src/lib/validators/spec-validator.js +58 -4
- package/src/lib/validators/validation-runner.js +23 -11
- package/src/scripts/setup-infra.js +255 -224
- package/src/utils/agents-installer.js +34 -14
- package/src/utils/banner.js +1 -1
- package/src/utils/claude-settings-manager.js +1 -1
- package/src/utils/file-copier.js +1 -1
- package/src/utils/hooks-installer.js +272 -8
- package/framework/hooks/dev/check-sync-health.js +0 -117
- package/framework/hooks/dev/guard-version-numbers.js +0 -57
- package/framework/hooks/dev/sync-standards-registry.js +0 -60
- package/framework/hooks/dev/sync-template-registry.js +0 -60
- package/framework/hooks/dev/validate-skill-format.js +0 -70
- package/framework/hooks/dev/validate-standard-format.js +0 -73
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +0 -190
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +0 -366
- package/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
- package/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
- package/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
- package/framework/workflows/configs/design-impl.json +0 -49
- package/framework/workflows/configs/express.json +0 -45
- package/framework/workflows/configs/fast-track.json +0 -42
- package/framework/workflows/configs/full-morph.json +0 -79
- package/framework/workflows/configs/fusion.json +0 -39
- package/framework/workflows/configs/long-running.json +0 -33
- package/framework/workflows/configs/spec-only.json +0 -43
- package/framework/workflows/configs/ui-refresh.json +0 -49
- package/framework/workflows/configs/zero-touch.json +0 -82
- package/src/commands/project/index.js +0 -8
- package/src/commands/project/monitor.js +0 -295
- package/src/commands/project/tutorial.js +0 -115
- package/src/commands/state/validate-phase.js +0 -238
- package/src/commands/templates/generate-contracts.js +0 -445
- package/src/core/index.js +0 -10
- package/src/core/orchestrator.js +0 -171
- package/src/core/registry/command-registry.js +0 -28
- package/src/core/registry/index.js +0 -8
- package/src/core/registry/validator-registry.js +0 -204
- package/src/core/state/index.js +0 -8
- package/src/core/templates/index.js +0 -9
- package/src/core/templates/template-data-sources.js +0 -325
- package/src/core/templates/template-validator.js +0 -296
- package/src/core/workflows/index.js +0 -7
- package/src/generator/config-generator.js +0 -206
- package/src/generator/templates/config.json.template +0 -40
- package/src/generator/templates/project.md.template +0 -67
- package/src/lib/agents/micro-agent-factory.js +0 -161
- package/src/lib/analysis/complexity-analyzer.js +0 -441
- package/src/lib/analysis/index.js +0 -7
- package/src/lib/analytics/analytics-engine.js +0 -345
- package/src/lib/checkpoints/checkpoint-hooks.js +0 -298
- package/src/lib/checkpoints/index.js +0 -7
- package/src/lib/context/context-bundler.js +0 -241
- package/src/lib/context/context-optimizer.js +0 -212
- package/src/lib/context/context-tracker.js +0 -273
- package/src/lib/context/core-four-tracker.js +0 -201
- package/src/lib/context/mcp-optimizer.js +0 -200
- package/src/lib/detectors/config-detector.js +0 -223
- package/src/lib/detectors/standards-generator.js +0 -335
- package/src/lib/detectors/structure-detector.js +0 -275
- package/src/lib/execution/fusion-executor.js +0 -304
- package/src/lib/execution/parallel-executor.js +0 -270
- package/src/lib/hooks/stop-hook-executor.js +0 -286
- package/src/lib/hops/hop-composer.js +0 -221
- package/src/lib/monitor/agent-resolver.js +0 -144
- package/src/lib/monitor/renderer.js +0 -230
- package/src/lib/orchestration/index.js +0 -7
- package/src/lib/orchestration/team-orchestrator.js +0 -404
- package/src/lib/phase-chain/eligibility-checker.js +0 -243
- package/src/lib/threads/thread-coordinator.js +0 -238
- package/src/lib/threads/thread-manager.js +0 -317
- package/src/lib/tracking/artifact-trail.js +0 -202
- package/src/sanitizer/context-sanitizer.js +0 -221
- package/src/sanitizer/patterns.js +0 -163
- package/src/scanner/project-scanner.js +0 -242
- package/src/ui/diff-display.js +0 -91
- package/src/ui/interactive-wizard.js +0 -96
- package/src/ui/user-review.js +0 -211
- package/src/ui/wizard-questions.js +0 -188
- package/src/utils/color-utils.js +0 -70
- package/src/utils/process-handler.js +0 -97
- package/src/writer/file-writer.js +0 -86
- /package/framework/skills/level-0-meta/{brainstorming → morph-brainstorming}/references/proposal-example.md +0 -0
- /package/framework/skills/level-0-meta/{code-review → morph-code-review}/references/review-example.md +0 -0
- /package/framework/skills/level-0-meta/{code-review → morph-code-review}/references/review-guidelines.md +0 -0
- /package/framework/skills/level-0-meta/{code-review → morph-code-review}/scripts/scan-csharp.mjs +0 -0
- /package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/references/review-example-nextjs.md +0 -0
- /package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/scripts/scan-nextjs.mjs +0 -0
- /package/framework/skills/level-0-meta/{frontend-review → morph-frontend-review}/scripts/scan-accessibility.mjs +0 -0
- /package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/scripts/detect-dev-server.mjs +0 -0
- /package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/scripts/detect-stack.mjs +0 -0
- /package/framework/skills/level-0-meta/{terminal-title → morph-terminal-title}/scripts/set_title.sh +0 -0
- /package/framework/skills/level-1-workflows/{phase-clarify → morph-phase-clarify}/references/clarifications-example.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/architecture-analysis-guide.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/spec-authoring-guide.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/spec-example.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/references/recap-example.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/references/vsa-implementation-guide.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/references/task-planning-patterns.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/references/tasks-example.md +0 -0
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Config Detector - Reads configuration files to extract technologies, versions, and dependencies
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { readFileSync, existsSync } from 'fs';
|
|
6
|
-
import { join } from 'path';
|
|
7
|
-
import { glob } from 'glob';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Detect project configuration
|
|
11
|
-
* @param {string} projectPath - Project root path
|
|
12
|
-
* @returns {Promise<Object>} Configuration detection results
|
|
13
|
-
*/
|
|
14
|
-
export async function detectConfig(projectPath) {
|
|
15
|
-
const result = {
|
|
16
|
-
language: 'unknown',
|
|
17
|
-
version: null,
|
|
18
|
-
packageManager: 'unknown',
|
|
19
|
-
dependencies: [],
|
|
20
|
-
technologies: [],
|
|
21
|
-
auth: null,
|
|
22
|
-
database: null,
|
|
23
|
-
hosting: null
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// Detect .NET projects
|
|
27
|
-
const dotnetConfig = await detectDotNet(projectPath);
|
|
28
|
-
if (dotnetConfig) {
|
|
29
|
-
Object.assign(result, dotnetConfig);
|
|
30
|
-
return result;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Detect Node.js projects
|
|
34
|
-
const nodeConfig = await detectNode(projectPath);
|
|
35
|
-
if (nodeConfig) {
|
|
36
|
-
Object.assign(result, nodeConfig);
|
|
37
|
-
return result;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return result;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Detect .NET configuration
|
|
45
|
-
*/
|
|
46
|
-
async function detectDotNet(projectPath) {
|
|
47
|
-
const programCs = join(projectPath, 'Program.cs');
|
|
48
|
-
const csprojFiles = await glob('**/*.csproj', { cwd: projectPath });
|
|
49
|
-
|
|
50
|
-
if (!existsSync(programCs) && csprojFiles.length === 0) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const config = {
|
|
55
|
-
language: 'csharp',
|
|
56
|
-
version: null,
|
|
57
|
-
packageManager: 'dotnet',
|
|
58
|
-
dependencies: [],
|
|
59
|
-
technologies: [],
|
|
60
|
-
auth: null,
|
|
61
|
-
database: null,
|
|
62
|
-
hosting: null
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
// Read Program.cs
|
|
66
|
-
if (existsSync(programCs)) {
|
|
67
|
-
const content = readFileSync(programCs, 'utf8');
|
|
68
|
-
|
|
69
|
-
// Detect .NET version
|
|
70
|
-
if (content.includes('WebApplication.CreateBuilder') || content.includes('.NET')) {
|
|
71
|
-
config.version = detectDotNetVersion(content);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Detect technologies from Program.cs
|
|
75
|
-
config.technologies = detectTechnologiesFromProgramCs(content);
|
|
76
|
-
config.auth = detectAuthMethod(content);
|
|
77
|
-
config.database = detectDatabase(content);
|
|
78
|
-
config.hosting = detectHosting(content);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Read .csproj files
|
|
82
|
-
for (const csprojFile of csprojFiles.slice(0, 3)) { // Read first 3 csproj files
|
|
83
|
-
const csprojPath = join(projectPath, csprojFile);
|
|
84
|
-
const content = readFileSync(csprojPath, 'utf8');
|
|
85
|
-
|
|
86
|
-
config.dependencies.push(...extractNuGetPackages(content));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Remove duplicates
|
|
90
|
-
config.dependencies = [...new Set(config.dependencies)];
|
|
91
|
-
config.technologies = [...new Set(config.technologies)];
|
|
92
|
-
|
|
93
|
-
return config;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Detect Node.js configuration
|
|
98
|
-
*/
|
|
99
|
-
async function detectNode(projectPath) {
|
|
100
|
-
const packageJsonPath = join(projectPath, 'package.json');
|
|
101
|
-
|
|
102
|
-
if (!existsSync(packageJsonPath)) {
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
107
|
-
|
|
108
|
-
const config = {
|
|
109
|
-
language: 'javascript',
|
|
110
|
-
version: packageJson.engines?.node || null,
|
|
111
|
-
packageManager: existsSync(join(projectPath, 'yarn.lock')) ? 'yarn' :
|
|
112
|
-
existsSync(join(projectPath, 'pnpm-lock.yaml')) ? 'pnpm' : 'npm',
|
|
113
|
-
dependencies: [],
|
|
114
|
-
technologies: [],
|
|
115
|
-
auth: null,
|
|
116
|
-
database: null,
|
|
117
|
-
hosting: null
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
// Extract dependencies
|
|
121
|
-
const allDeps = {
|
|
122
|
-
...packageJson.dependencies,
|
|
123
|
-
...packageJson.devDependencies
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
config.dependencies = Object.keys(allDeps);
|
|
127
|
-
|
|
128
|
-
// Detect technologies
|
|
129
|
-
if (allDeps['next']) config.technologies.push('Next.js');
|
|
130
|
-
if (allDeps['react']) config.technologies.push('React');
|
|
131
|
-
if (allDeps['@clerk/nextjs']) config.auth = 'Clerk';
|
|
132
|
-
if (allDeps['prisma']) config.database = 'Prisma';
|
|
133
|
-
|
|
134
|
-
return config;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Detect .NET version from Program.cs
|
|
139
|
-
*/
|
|
140
|
-
function detectDotNetVersion(content) {
|
|
141
|
-
if (content.includes('.NET 10') || content.includes('net10.0')) return '.NET 10';
|
|
142
|
-
if (content.includes('.NET 9') || content.includes('net9.0')) return '.NET 9';
|
|
143
|
-
if (content.includes('.NET 8') || content.includes('net8.0')) return '.NET 8';
|
|
144
|
-
return 'unknown';
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Detect technologies from Program.cs
|
|
149
|
-
*/
|
|
150
|
-
function detectTechnologiesFromProgramCs(content) {
|
|
151
|
-
const techs = [];
|
|
152
|
-
|
|
153
|
-
if (content.includes('AddBlazor') || content.includes('MapBlazorHub')) {
|
|
154
|
-
techs.push('Blazor Server');
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (content.includes('AddHangfire')) {
|
|
158
|
-
techs.push('Hangfire');
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (content.includes('IChatClient') || content.includes('Microsoft.Agents')) {
|
|
162
|
-
techs.push('Microsoft Agent Framework');
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (content.includes('AddDbContext') || content.includes('UseSqlServer')) {
|
|
166
|
-
techs.push('Entity Framework Core');
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (content.includes('AddFluentUIComponents') || content.includes('FluentUI')) {
|
|
170
|
-
techs.push('Fluent UI Blazor');
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (content.includes('AddMudServices') || content.includes('MudBlazor')) {
|
|
174
|
-
techs.push('MudBlazor');
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return techs;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Detect authentication method
|
|
182
|
-
*/
|
|
183
|
-
function detectAuthMethod(content) {
|
|
184
|
-
if (content.includes('AddClerk') || content.includes('Clerk')) return 'Clerk';
|
|
185
|
-
if (content.includes('AddMicrosoftIdentity') || content.includes('Entra')) return 'Microsoft Entra';
|
|
186
|
-
if (content.includes('AddAuthentication')) return 'ASP.NET Identity';
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Detect database
|
|
192
|
-
*/
|
|
193
|
-
function detectDatabase(content) {
|
|
194
|
-
if (content.includes('UseSqlServer')) return 'SQL Server';
|
|
195
|
-
if (content.includes('UsePostgres')) return 'PostgreSQL';
|
|
196
|
-
if (content.includes('UseSqlite')) return 'SQLite';
|
|
197
|
-
if (content.includes('UseCosmos')) return 'Cosmos DB';
|
|
198
|
-
return null;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Detect hosting platform
|
|
203
|
-
*/
|
|
204
|
-
function detectHosting(content) {
|
|
205
|
-
if (content.includes('Azure') || content.includes('AddAzure')) return 'Azure';
|
|
206
|
-
if (content.includes('AWS')) return 'AWS';
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Extract NuGet packages from .csproj
|
|
212
|
-
*/
|
|
213
|
-
function extractNuGetPackages(csprojContent) {
|
|
214
|
-
const packages = [];
|
|
215
|
-
const regex = /<PackageReference\s+Include="([^"]+)"/g;
|
|
216
|
-
let match;
|
|
217
|
-
|
|
218
|
-
while ((match = regex.exec(csprojContent)) !== null) {
|
|
219
|
-
packages.push(match[1]);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
return packages;
|
|
223
|
-
}
|
|
@@ -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
|
-
}
|