@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,204 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validator Registry - Technology-Based Auto-Discovery
|
|
3
|
-
*
|
|
4
|
-
* Maps validator types to their modules for dynamic loading.
|
|
5
|
-
* Organized by technology (blazor, css, architecture, etc.)
|
|
6
|
-
*
|
|
7
|
-
* @module validator-registry
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Validator Metadata Registry
|
|
12
|
-
*
|
|
13
|
-
* Technology-scoped validator discovery.
|
|
14
|
-
*/
|
|
15
|
-
export const validatorMetadata = {
|
|
16
|
-
// Blazor Validators
|
|
17
|
-
'blazor': {
|
|
18
|
-
technology: 'blazor',
|
|
19
|
-
validators: [
|
|
20
|
-
{
|
|
21
|
-
id: 'blazor-validator',
|
|
22
|
-
name: 'Blazor Patterns Validator',
|
|
23
|
-
description: 'Validates Fluent UI Blazor patterns and components',
|
|
24
|
-
module: () => import('../../lib/validators/blazor/blazor-validator.js'),
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: 'blazor-state',
|
|
28
|
-
name: 'Blazor State Validator',
|
|
29
|
-
description: 'Validates Blazor state management patterns',
|
|
30
|
-
module: () => import('../../lib/validators/blazor/blazor-state-validator.js'),
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
id: 'blazor-concurrency',
|
|
34
|
-
name: 'Blazor Concurrency Analyzer',
|
|
35
|
-
description: 'Analyzes Blazor concurrency and DbContext issues',
|
|
36
|
-
module: () => import('../../lib/validators/blazor/blazor-concurrency-analyzer.js'),
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
// CSS Validators
|
|
42
|
-
'css': {
|
|
43
|
-
technology: 'css',
|
|
44
|
-
validators: [
|
|
45
|
-
{
|
|
46
|
-
id: 'css-validator',
|
|
47
|
-
name: 'CSS Validator',
|
|
48
|
-
description: 'Validates CSS classes and design system compliance',
|
|
49
|
-
module: () => import('../../lib/validators/css/css-validator.js'),
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
// Architecture Validators
|
|
55
|
-
'architecture': {
|
|
56
|
-
technology: 'architecture',
|
|
57
|
-
validators: [
|
|
58
|
-
{
|
|
59
|
-
id: 'architecture-validator',
|
|
60
|
-
name: 'Architecture Validator',
|
|
61
|
-
description: 'Validates architectural patterns (DI, CQRS, etc.)',
|
|
62
|
-
module: () => import('../../lib/validators/architecture/architecture-validator.js'),
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
},
|
|
66
|
-
|
|
67
|
-
// Design System Validators
|
|
68
|
-
'design-system': {
|
|
69
|
-
technology: 'design-system',
|
|
70
|
-
validators: [
|
|
71
|
-
{
|
|
72
|
-
id: 'design-system-validator',
|
|
73
|
-
name: 'Design System Validator',
|
|
74
|
-
description: 'Validates design system compliance',
|
|
75
|
-
module: () => import('../../lib/validators/design-system/design-system-validator.js'),
|
|
76
|
-
},
|
|
77
|
-
],
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
// Content Validators
|
|
81
|
-
'content': {
|
|
82
|
-
technology: 'content',
|
|
83
|
-
validators: [
|
|
84
|
-
{
|
|
85
|
-
id: 'content-validator',
|
|
86
|
-
name: 'Content Validator',
|
|
87
|
-
description: 'Validates content and specification format',
|
|
88
|
-
module: () => import('../../lib/validators/content/content-validator.js'),
|
|
89
|
-
},
|
|
90
|
-
],
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
// Contract Validators
|
|
94
|
-
'contracts': {
|
|
95
|
-
technology: 'contracts',
|
|
96
|
-
validators: [
|
|
97
|
-
{
|
|
98
|
-
id: 'contract-compliance-validator',
|
|
99
|
-
name: 'Contract Compliance Validator',
|
|
100
|
-
description: 'Validates API contract compliance',
|
|
101
|
-
module: () => import('../../lib/validators/contracts/contract-compliance-validator.js'),
|
|
102
|
-
},
|
|
103
|
-
],
|
|
104
|
-
},
|
|
105
|
-
|
|
106
|
-
// Package Validators
|
|
107
|
-
'packages': {
|
|
108
|
-
technology: 'packages',
|
|
109
|
-
validators: [
|
|
110
|
-
{
|
|
111
|
-
id: 'package-validator',
|
|
112
|
-
name: 'Package Validator',
|
|
113
|
-
description: 'Validates package dependencies and versions',
|
|
114
|
-
module: () => import('../../lib/validators/packages/package-validator.js'),
|
|
115
|
-
},
|
|
116
|
-
],
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
// UI Validators
|
|
120
|
-
'ui': {
|
|
121
|
-
technology: 'ui',
|
|
122
|
-
validators: [
|
|
123
|
-
{
|
|
124
|
-
id: 'ui-contrast-validator',
|
|
125
|
-
name: 'UI Contrast Validator',
|
|
126
|
-
description: 'Validates UI contrast and accessibility',
|
|
127
|
-
module: () => import('../../lib/validators/ui/ui-contrast-validator.js'),
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Load validator by ID
|
|
135
|
-
*
|
|
136
|
-
* @param {string} validatorId - Validator ID (e.g., 'blazor-validator')
|
|
137
|
-
* @returns {Promise<Object>} Validator module
|
|
138
|
-
*/
|
|
139
|
-
export async function loadValidator(validatorId) {
|
|
140
|
-
for (const techMeta of Object.values(validatorMetadata)) {
|
|
141
|
-
const validator = techMeta.validators.find(v => v.id === validatorId);
|
|
142
|
-
if (validator) {
|
|
143
|
-
return await validator.module();
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
throw new Error(`Validator not found: ${validatorId}`);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Load all validators for a technology
|
|
152
|
-
*
|
|
153
|
-
* @param {string} technology - Technology name (e.g., 'blazor', 'css')
|
|
154
|
-
* @returns {Promise<Object[]>} Array of validator modules
|
|
155
|
-
*/
|
|
156
|
-
export async function loadValidatorsForTechnology(technology) {
|
|
157
|
-
const techMeta = validatorMetadata[technology];
|
|
158
|
-
|
|
159
|
-
if (!techMeta) {
|
|
160
|
-
throw new Error(`No validators found for technology: ${technology}`);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return await Promise.all(
|
|
164
|
-
techMeta.validators.map(v => v.module())
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Get all validator IDs
|
|
170
|
-
*
|
|
171
|
-
* @returns {string[]} Array of validator IDs
|
|
172
|
-
*/
|
|
173
|
-
export function getAllValidatorIds() {
|
|
174
|
-
const ids = [];
|
|
175
|
-
for (const techMeta of Object.values(validatorMetadata)) {
|
|
176
|
-
ids.push(...techMeta.validators.map(v => v.id));
|
|
177
|
-
}
|
|
178
|
-
return ids;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Get all technologies
|
|
183
|
-
*
|
|
184
|
-
* @returns {string[]} Array of technology names
|
|
185
|
-
*/
|
|
186
|
-
export function getAllTechnologies() {
|
|
187
|
-
return Object.keys(validatorMetadata);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Get validator metadata by ID
|
|
192
|
-
*
|
|
193
|
-
* @param {string} validatorId - Validator ID
|
|
194
|
-
* @returns {Object|null} Validator metadata or null
|
|
195
|
-
*/
|
|
196
|
-
export function getValidatorMetadata(validatorId) {
|
|
197
|
-
for (const techMeta of Object.values(validatorMetadata)) {
|
|
198
|
-
const validator = techMeta.validators.find(v => v.id === validatorId);
|
|
199
|
-
if (validator) {
|
|
200
|
-
return { ...validator, technology: techMeta.technology };
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
return null;
|
|
204
|
-
}
|
package/src/core/state/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core Template System
|
|
3
|
-
*
|
|
4
|
-
* Template registry, rendering, and data sources for code generation.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export { TemplateRegistry } from './template-registry.js';
|
|
8
|
-
export { TemplateRenderer } from './template-renderer.js';
|
|
9
|
-
export { TemplateDataSources } from './template-data-sources.js';
|
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import { glob } from 'glob';
|
|
2
|
-
import { readFileSync, existsSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
import { execSync } from 'child_process';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Template Data Sources - Inject dynamic MCP data into templates
|
|
8
|
-
*
|
|
9
|
-
* Provides project context, compliance status, and recent activity
|
|
10
|
-
* for enriching template placeholders.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Get project structure statistics
|
|
15
|
-
* @param {string} projectPath - Project root path
|
|
16
|
-
* @returns {Promise<Object>} Project structure data
|
|
17
|
-
*/
|
|
18
|
-
export async function getProjectStructure(projectPath = process.cwd()) {
|
|
19
|
-
try {
|
|
20
|
-
// Find all files (excluding common ignore patterns)
|
|
21
|
-
const files = await glob('**/*', {
|
|
22
|
-
cwd: projectPath,
|
|
23
|
-
ignore: [
|
|
24
|
-
'node_modules/**',
|
|
25
|
-
'bin/**',
|
|
26
|
-
'obj/**',
|
|
27
|
-
'.git/**',
|
|
28
|
-
'.morph/**',
|
|
29
|
-
'dist/**',
|
|
30
|
-
'build/**',
|
|
31
|
-
'*.log'
|
|
32
|
-
],
|
|
33
|
-
nodir: true
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
// Calculate language stats
|
|
37
|
-
const languageStats = {};
|
|
38
|
-
files.forEach(file => {
|
|
39
|
-
const ext = file.split('.').pop();
|
|
40
|
-
languageStats[ext] = (languageStats[ext] || 0) + 1;
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// Get test coverage if available
|
|
44
|
-
let testCoverage = null;
|
|
45
|
-
const coveragePath = join(projectPath, 'coverage/coverage-summary.json');
|
|
46
|
-
if (existsSync(coveragePath)) {
|
|
47
|
-
const coverageData = JSON.parse(readFileSync(coveragePath, 'utf8'));
|
|
48
|
-
testCoverage = coverageData.total?.lines?.pct || null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Get last commit info
|
|
52
|
-
let lastCommit = null;
|
|
53
|
-
try {
|
|
54
|
-
const gitLog = execSync('git log -1 --format="%H|%an|%ar|%s"', {
|
|
55
|
-
cwd: projectPath,
|
|
56
|
-
encoding: 'utf8',
|
|
57
|
-
stdio: 'pipe'
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const [hash, author, time, message] = gitLog.trim().split('|');
|
|
61
|
-
lastCommit = { hash: hash.substring(0, 7), author, time, message };
|
|
62
|
-
} catch {
|
|
63
|
-
// Git not available or not a repo
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
totalFiles: files.length,
|
|
68
|
-
languageStats,
|
|
69
|
-
testCoverage: testCoverage ? Math.round(testCoverage) : null,
|
|
70
|
-
lastCommit,
|
|
71
|
-
filesByExtension: {
|
|
72
|
-
cs: languageStats.cs || 0,
|
|
73
|
-
js: languageStats.js || 0,
|
|
74
|
-
ts: languageStats.ts || 0,
|
|
75
|
-
tsx: languageStats.tsx || 0,
|
|
76
|
-
razor: languageStats.razor || 0,
|
|
77
|
-
css: languageStats.css || 0,
|
|
78
|
-
md: languageStats.md || 0
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
} catch (error) {
|
|
82
|
-
return {
|
|
83
|
-
error: error.message,
|
|
84
|
-
totalFiles: 0,
|
|
85
|
-
testCoverage: null
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Get dependency information
|
|
92
|
-
* @param {string} projectPath - Project root path
|
|
93
|
-
* @returns {Promise<Object>} Dependency data
|
|
94
|
-
*/
|
|
95
|
-
export async function getDependencyInfo(projectPath = process.cwd()) {
|
|
96
|
-
const dependencies = {
|
|
97
|
-
nuget: [],
|
|
98
|
-
npm: [],
|
|
99
|
-
outdated: []
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
try {
|
|
103
|
-
// Check for NuGet packages (C# projects)
|
|
104
|
-
const csprojFiles = await glob('**/*.csproj', {
|
|
105
|
-
cwd: projectPath,
|
|
106
|
-
ignore: ['**/bin/**', '**/obj/**']
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
if (csprojFiles.length > 0) {
|
|
110
|
-
const csprojPath = join(projectPath, csprojFiles[0]);
|
|
111
|
-
const csprojContent = readFileSync(csprojPath, 'utf8');
|
|
112
|
-
|
|
113
|
-
// Extract PackageReference elements
|
|
114
|
-
const packageRegex = /<PackageReference\s+Include="([^"]+)"\s+Version="([^"]+)"/g;
|
|
115
|
-
let match;
|
|
116
|
-
|
|
117
|
-
while ((match = packageRegex.exec(csprojContent)) !== null) {
|
|
118
|
-
dependencies.nuget.push({
|
|
119
|
-
name: match[1],
|
|
120
|
-
version: match[2]
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Check for npm packages
|
|
126
|
-
const packageJsonPath = join(projectPath, 'package.json');
|
|
127
|
-
if (existsSync(packageJsonPath)) {
|
|
128
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
129
|
-
|
|
130
|
-
const allDeps = {
|
|
131
|
-
...packageJson.dependencies,
|
|
132
|
-
...packageJson.devDependencies
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
Object.entries(allDeps).forEach(([name, version]) => {
|
|
136
|
-
dependencies.npm.push({ name, version });
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
} catch (error) {
|
|
141
|
-
dependencies.error = error.message;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return dependencies;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Get compliance status from validators
|
|
149
|
-
* @param {string} projectPath - Project root path
|
|
150
|
-
* @returns {Promise<Object>} Compliance data
|
|
151
|
-
*/
|
|
152
|
-
export async function getComplianceStatus(projectPath = process.cwd()) {
|
|
153
|
-
const compliance = {
|
|
154
|
-
architectureViolations: 0,
|
|
155
|
-
packageConflicts: 0,
|
|
156
|
-
designSystemCompliance: 100,
|
|
157
|
-
securityIssues: 0,
|
|
158
|
-
overall: 100
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
try {
|
|
162
|
-
// Run validators if available
|
|
163
|
-
const validators = ['architecture', 'packages', 'design-system', 'security'];
|
|
164
|
-
|
|
165
|
-
for (const validator of validators) {
|
|
166
|
-
try {
|
|
167
|
-
const result = execSync(
|
|
168
|
-
`node bin/validate.js ${validator} --json`,
|
|
169
|
-
{
|
|
170
|
-
cwd: projectPath,
|
|
171
|
-
encoding: 'utf8',
|
|
172
|
-
stdio: 'pipe'
|
|
173
|
-
}
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
const parsed = JSON.parse(result);
|
|
177
|
-
|
|
178
|
-
if (validator === 'architecture') {
|
|
179
|
-
compliance.architectureViolations = parsed.errors || 0;
|
|
180
|
-
} else if (validator === 'packages') {
|
|
181
|
-
compliance.packageConflicts = parsed.errors || 0;
|
|
182
|
-
} else if (validator === 'design-system') {
|
|
183
|
-
const total = parsed.total || 100;
|
|
184
|
-
const errors = parsed.errors || 0;
|
|
185
|
-
compliance.designSystemCompliance = Math.round(((total - errors) / total) * 100);
|
|
186
|
-
} else if (validator === 'security') {
|
|
187
|
-
compliance.securityIssues = parsed.errors || 0;
|
|
188
|
-
}
|
|
189
|
-
} catch {
|
|
190
|
-
// Validator not available or failed - skip
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Calculate overall compliance score
|
|
195
|
-
const violations = compliance.architectureViolations +
|
|
196
|
-
compliance.packageConflicts +
|
|
197
|
-
compliance.securityIssues;
|
|
198
|
-
|
|
199
|
-
compliance.overall = Math.max(0, 100 - (violations * 5));
|
|
200
|
-
|
|
201
|
-
} catch (error) {
|
|
202
|
-
compliance.error = error.message;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return compliance;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Get recent activity and history
|
|
210
|
-
* @param {string} projectPath - Project root path
|
|
211
|
-
* @returns {Promise<Object>} Activity data
|
|
212
|
-
*/
|
|
213
|
-
export async function getRecentActivity(projectPath = process.cwd()) {
|
|
214
|
-
const activity = {
|
|
215
|
-
lastFeature: null,
|
|
216
|
-
recentCommits: [],
|
|
217
|
-
activeBranches: [],
|
|
218
|
-
lastDeployment: null
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
try {
|
|
222
|
-
// Check state.json for last feature
|
|
223
|
-
const statePath = join(projectPath, '.morph/state.json');
|
|
224
|
-
if (existsSync(statePath)) {
|
|
225
|
-
const state = JSON.parse(readFileSync(statePath, 'utf8'));
|
|
226
|
-
|
|
227
|
-
// Find most recently updated feature
|
|
228
|
-
let lastFeature = null;
|
|
229
|
-
let lastTimestamp = null;
|
|
230
|
-
|
|
231
|
-
Object.entries(state.features || {}).forEach(([name, feature]) => {
|
|
232
|
-
const updatedAt = feature.updatedAt || feature.createdAt;
|
|
233
|
-
if (updatedAt && (!lastTimestamp || updatedAt > lastTimestamp)) {
|
|
234
|
-
lastTimestamp = updatedAt;
|
|
235
|
-
lastFeature = name;
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
activity.lastFeature = lastFeature;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Get recent commits
|
|
243
|
-
try {
|
|
244
|
-
const gitLog = execSync('git log -5 --format="%h|%an|%ar|%s"', {
|
|
245
|
-
cwd: projectPath,
|
|
246
|
-
encoding: 'utf8',
|
|
247
|
-
stdio: 'pipe'
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
activity.recentCommits = gitLog.trim().split('\n').map(line => {
|
|
251
|
-
const [hash, author, time, message] = line.split('|');
|
|
252
|
-
return { hash, author, time, message };
|
|
253
|
-
});
|
|
254
|
-
} catch {
|
|
255
|
-
// Git not available
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Get active branches
|
|
259
|
-
try {
|
|
260
|
-
const branches = execSync('git branch -a', {
|
|
261
|
-
cwd: projectPath,
|
|
262
|
-
encoding: 'utf8',
|
|
263
|
-
stdio: 'pipe'
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
activity.activeBranches = branches
|
|
267
|
-
.split('\n')
|
|
268
|
-
.map(b => b.trim().replace(/^\*\s+/, ''))
|
|
269
|
-
.filter(b => b && !b.includes('->'));
|
|
270
|
-
} catch {
|
|
271
|
-
// Git not available
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
} catch (error) {
|
|
275
|
-
activity.error = error.message;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return activity;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Get all template data sources combined
|
|
283
|
-
* @param {string} projectPath - Project root path
|
|
284
|
-
* @returns {Promise<Object>} All data sources
|
|
285
|
-
*/
|
|
286
|
-
export async function getAllTemplatePlaceholders(projectPath = process.cwd()) {
|
|
287
|
-
const [structure, dependencies, compliance, activity] = await Promise.all([
|
|
288
|
-
getProjectStructure(projectPath),
|
|
289
|
-
getDependencyInfo(projectPath),
|
|
290
|
-
getComplianceStatus(projectPath),
|
|
291
|
-
getRecentActivity(projectPath)
|
|
292
|
-
]);
|
|
293
|
-
|
|
294
|
-
return {
|
|
295
|
-
MCP_PROJECT_FILES: structure.totalFiles,
|
|
296
|
-
MCP_TEST_COVERAGE: structure.testCoverage || 'N/A',
|
|
297
|
-
MCP_COMPLIANCE_SCORE: compliance.overall,
|
|
298
|
-
MCP_LAST_FEATURE: activity.lastFeature || 'None',
|
|
299
|
-
MCP_LAST_COMMIT: structure.lastCommit?.message || 'Unknown',
|
|
300
|
-
MCP_LAST_COMMIT_AUTHOR: structure.lastCommit?.author || 'Unknown',
|
|
301
|
-
MCP_LAST_COMMIT_TIME: structure.lastCommit?.time || 'Unknown',
|
|
302
|
-
|
|
303
|
-
MCP_CS_FILES: structure.filesByExtension?.cs || 0,
|
|
304
|
-
MCP_RAZOR_FILES: structure.filesByExtension?.razor || 0,
|
|
305
|
-
MCP_TS_FILES: structure.filesByExtension?.ts || 0,
|
|
306
|
-
MCP_JS_FILES: structure.filesByExtension?.js || 0,
|
|
307
|
-
|
|
308
|
-
MCP_NUGET_PACKAGES: dependencies.nuget.length,
|
|
309
|
-
MCP_NPM_PACKAGES: dependencies.npm.length,
|
|
310
|
-
|
|
311
|
-
MCP_ARCHITECTURE_VIOLATIONS: compliance.architectureViolations,
|
|
312
|
-
MCP_PACKAGE_CONFLICTS: compliance.packageConflicts,
|
|
313
|
-
MCP_SECURITY_ISSUES: compliance.securityIssues,
|
|
314
|
-
|
|
315
|
-
MCP_RECENT_BRANCHES: activity.activeBranches.slice(0, 3).join(', '),
|
|
316
|
-
|
|
317
|
-
// Full objects for advanced usage
|
|
318
|
-
_raw: {
|
|
319
|
-
structure,
|
|
320
|
-
dependencies,
|
|
321
|
-
compliance,
|
|
322
|
-
activity
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
}
|