@polymorphism-tech/morph-spec 7.9.0 → 7.9.2
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/README.md +4 -4
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +6 -2
- package/docs/QUICKSTART.md +4 -4
- package/framework/CLAUDE.md +1 -1
- package/framework/MORPH.md +2 -2
- package/framework/commands/commit.md +166 -166
- package/framework/commands/morph-infra.md +215 -215
- package/framework/commands/morph-preflight.md +205 -205
- package/framework/commands/morph-troubleshoot.md +124 -124
- package/framework/hooks/claude-code/statusline.py +679 -679
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
- package/framework/hooks/git/pre-commit/agents.sh +25 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
- package/framework/hooks/git/pre-commit/specs.sh +50 -50
- package/framework/hooks/git/pre-push/run-tests.sh +44 -44
- package/framework/hooks/shared/activity-logger.js +160 -160
- package/framework/hooks/shared/hook-response.js +45 -45
- package/framework/hooks/shared/payload-utils.js +78 -78
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/rubrics/backend.json +41 -41
- package/framework/rules/ai-agents-standards.md +45 -45
- package/framework/rules/dotnet-templates.md +86 -86
- package/framework/rules/frontend-standards.md +13 -13
- package/framework/rules/infrastructure-standards.md +27 -27
- package/framework/rules/neon-standards.md +25 -25
- package/framework/rules/nextjs-standards.md +20 -20
- package/framework/rules/nextjs-templates.md +40 -40
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +13 -8
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-implement/SKILL.md +13 -8
- package/framework/skills/core/morph-plan/SKILL.md +1 -1
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +10 -7
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/standards/ai-agents/agent-session.md +160 -160
- package/framework/standards/ai-agents/batching.md +193 -193
- package/framework/standards/ai-agents/context-providers.md +188 -188
- package/framework/standards/ai-agents/mcp-server.md +250 -250
- package/framework/standards/ai-agents/mcp-tools.md +197 -197
- package/framework/standards/ai-agents/middleware-patterns.md +207 -207
- package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
- package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
- package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
- package/framework/standards/ai-agents/modalities-vision.md +201 -201
- package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
- package/framework/standards/ai-agents/production.md +275 -275
- package/framework/standards/ai-agents/prompts-in-db.md +214 -214
- package/framework/standards/ai-agents/providers/model-registry.md +158 -158
- package/framework/standards/ai-agents/service-tier-flex.md +135 -135
- package/framework/standards/ai-agents/structured-output.md +249 -249
- package/framework/standards/ai-agents/sweet-spot.md +109 -109
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
- package/framework/templates/code/dotnet/database/migration.cs +83 -83
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/code/typescript/contracts.ts +167 -167
- package/framework/templates/docs/clarifications.md +253 -253
- package/framework/templates/docs/schema-analysis.md +119 -119
- package/framework/templates/docs/ui-components.md +52 -52
- package/framework/templates/docs/ui-design-system.md +76 -76
- package/framework/templates/docs/ui-flows.md +167 -167
- package/framework/templates/docs/ui-mockups.md +98 -98
- package/framework/templates/feature/decisions.md +122 -122
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -50
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/integrations/asaas-client.cs +387 -387
- package/framework/templates/integrations/asaas-webhook.cs +351 -351
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +113 -113
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
- package/framework/templates/project/validate.js +120 -120
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +2 -1
- package/src/commands/dashboard/dashboard.js +53 -53
- package/src/commands/index.js +13 -13
- package/src/commands/mcp/mcp-setup.js +519 -519
- package/src/commands/project/checkpoint.js +209 -209
- package/src/commands/project/doctor.js +1 -1
- package/src/commands/project/update.js +4 -1
- package/src/core/state/phase-state-machine.js +197 -197
- package/src/core/templates/template-renderer.js +477 -477
- package/src/dashboard/app/components/DetailPanel.jsx +11 -11
- package/src/dashboard/app/components/FlowGraph.jsx +17 -17
- package/src/dashboard/app/components/SearchFilter.jsx +22 -22
- package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/AgentMap.jsx +370 -370
- package/src/dashboard/app/pages/HookInspector.jsx +418 -418
- package/src/dashboard/app/pages/LiveState.jsx +239 -239
- package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
- package/src/dashboard/app/pages/RulesMap.jsx +273 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
- package/src/dashboard/app/pages/Standards.jsx +332 -332
- package/src/dashboard/app/styles/index.css +47 -47
- package/src/dashboard/index.html +12 -12
- package/src/dashboard/package.json +24 -24
- package/src/dashboard/scanner/hooks-scanner.js +41 -41
- package/src/dashboard/scanner/phases-scanner.js +15 -15
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/scanner/rules-scanner.js +37 -37
- package/src/dashboard/scanner/skills-scanner.js +43 -43
- package/src/dashboard/scanner/squads-scanner.js +13 -13
- package/src/dashboard/scanner/standards-scanner.js +26 -26
- package/src/dashboard/vite-plugin-morph-data.js +17 -17
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/agents/metrics-aggregator.js +56 -56
- package/src/lib/agents/metrics-calculator.js +125 -125
- package/src/lib/agents/output-collector.js +73 -73
- package/src/lib/detectors/claude-config-detector.js +152 -152
- package/src/lib/detectors/design-system-detector.js +231 -231
- package/src/lib/detectors/index.js +217 -217
- package/src/lib/generators/architecture-scanner.js +639 -639
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/index.js +13 -13
- package/src/lib/generators/settings-generator.js +209 -209
- package/src/lib/hooks/hook-executor.js +167 -167
- package/src/lib/installers/mcp-installer.js +719 -719
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/tasks/test-runner.js +81 -81
- package/src/lib/validators/architecture/architecture-validator.js +259 -259
- package/src/lib/validators/checkpoint-persistence.js +39 -39
- package/src/lib/validators/contracts/contract-compliance-validator.js +274 -274
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/packages/package-validator.js +347 -347
- package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
- package/src/lib/validators/shared/issue-counter.js +14 -14
- package/src/lib/validators/validation-runner.js +349 -349
- package/src/scripts/setup-infra.js +385 -385
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/skills-installer.js +174 -174
- package/src/utils/version-checker.js +2 -2
- package/framework/templates/.idea/morph-templates.xml +0 -92
- package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
# Pre-Commit Validator
|
|
2
|
-
|
|
3
|
-
You are running as part of the **pre-commit hook** to validate changes before they are committed.
|
|
4
|
-
|
|
5
|
-
## Trigger Context
|
|
6
|
-
- Hook: pre-commit
|
|
7
|
-
- Feature: {{FEATURE_NAME}}
|
|
8
|
-
- Branch: {{BRANCH_NAME}}
|
|
9
|
-
- Staged Files: {{STAGED_FILE_COUNT}} files
|
|
10
|
-
|
|
11
|
-
## Staged Files Under Review
|
|
12
|
-
|
|
13
|
-
{{STAGED_FILES}}
|
|
14
|
-
|
|
15
|
-
## Validation Sequence
|
|
16
|
-
|
|
17
|
-
### 1. Conventional Commit Format Check
|
|
18
|
-
Verify the commit message (if provided) follows Conventional Commits:
|
|
19
|
-
```
|
|
20
|
-
<type>(<scope>): <description>
|
|
21
|
-
|
|
22
|
-
Types: feat, fix, docs, style, refactor, test, chore, perf, ci, build
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Valid examples:
|
|
26
|
-
- `feat(auth): add JWT refresh token rotation`
|
|
27
|
-
- `fix(api): resolve handler lifecycle in reports endpoint`
|
|
28
|
-
- `chore(deps): update TanStack Query to 5.x`
|
|
29
|
-
|
|
30
|
-
### 2. Secret Scan
|
|
31
|
-
Check staged files for accidental secrets:
|
|
32
|
-
- Connection strings with passwords
|
|
33
|
-
- API keys or tokens
|
|
34
|
-
- Private keys (-----BEGIN RSA PRIVATE KEY-----)
|
|
35
|
-
- `.env` files accidentally staged
|
|
36
|
-
|
|
37
|
-
**Blockers** (commit must be rejected):
|
|
38
|
-
- Any `password=` or `pwd=` outside development appsettings
|
|
39
|
-
- API keys matching common patterns (sk-*, xoxb-*, ghp_*)
|
|
40
|
-
- Private key headers
|
|
41
|
-
|
|
42
|
-
### 3. Agent Spec Validation (if agents.json staged)
|
|
43
|
-
If `.morph/framework/agents.json` is in staged files:
|
|
44
|
-
- Valid JSON structure
|
|
45
|
-
- All required agent fields present (agentId, role, tier, domain)
|
|
46
|
-
- No duplicate agentIds
|
|
47
|
-
- Valid tier values (1-4)
|
|
48
|
-
|
|
49
|
-
### 4. Spec Format Validation (if spec.md staged)
|
|
50
|
-
If any `spec.md` is staged:
|
|
51
|
-
- Has required sections: Overview, Requirements, Technical Design, Data Model, API Contracts
|
|
52
|
-
- No placeholder text (`{{TODO}}`, `TBD`, `[PLACEHOLDER]`)
|
|
53
|
-
- Word count > 200 (meaningful spec)
|
|
54
|
-
|
|
55
|
-
### 5. Stack-Specific Validation
|
|
56
|
-
{{#if IS_CSHARP}}
|
|
57
|
-
For C# files:
|
|
58
|
-
- No `TODO` comments in staged code
|
|
59
|
-
- No `Console.WriteLine` in production code (use ILogger)
|
|
60
|
-
- No `Thread.Sleep` (use async alternatives)
|
|
61
|
-
{{/if}}
|
|
62
|
-
|
|
63
|
-
{{#if IS_TYPESCRIPT}}
|
|
64
|
-
For TypeScript files:
|
|
65
|
-
- No `any` type (use proper types)
|
|
66
|
-
- No `console.log` in production components
|
|
67
|
-
- No commented-out code blocks > 3 lines
|
|
68
|
-
{{/if}}
|
|
69
|
-
|
|
70
|
-
## Decision
|
|
71
|
-
|
|
72
|
-
**All checks pass:**
|
|
73
|
-
```
|
|
74
|
-
✅ Pre-commit validation passed
|
|
75
|
-
Proceeding with commit.
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
**Blocking issue found:**
|
|
79
|
-
```
|
|
80
|
-
❌ Pre-commit BLOCKED
|
|
81
|
-
|
|
82
|
-
Issue: [description]
|
|
83
|
-
File: [file:line]
|
|
84
|
-
Fix: [specific instruction]
|
|
85
|
-
|
|
86
|
-
Commit rejected. Fix the issue and retry.
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
**Warning only (commit proceeds):**
|
|
90
|
-
```
|
|
91
|
-
⚠️ Pre-commit warnings (commit allowed)
|
|
92
|
-
|
|
93
|
-
Warning: [description]
|
|
94
|
-
Recommendation: [suggestion]
|
|
95
|
-
```
|
|
1
|
+
# Pre-Commit Validator
|
|
2
|
+
|
|
3
|
+
You are running as part of the **pre-commit hook** to validate changes before they are committed.
|
|
4
|
+
|
|
5
|
+
## Trigger Context
|
|
6
|
+
- Hook: pre-commit
|
|
7
|
+
- Feature: {{FEATURE_NAME}}
|
|
8
|
+
- Branch: {{BRANCH_NAME}}
|
|
9
|
+
- Staged Files: {{STAGED_FILE_COUNT}} files
|
|
10
|
+
|
|
11
|
+
## Staged Files Under Review
|
|
12
|
+
|
|
13
|
+
{{STAGED_FILES}}
|
|
14
|
+
|
|
15
|
+
## Validation Sequence
|
|
16
|
+
|
|
17
|
+
### 1. Conventional Commit Format Check
|
|
18
|
+
Verify the commit message (if provided) follows Conventional Commits:
|
|
19
|
+
```
|
|
20
|
+
<type>(<scope>): <description>
|
|
21
|
+
|
|
22
|
+
Types: feat, fix, docs, style, refactor, test, chore, perf, ci, build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Valid examples:
|
|
26
|
+
- `feat(auth): add JWT refresh token rotation`
|
|
27
|
+
- `fix(api): resolve handler lifecycle in reports endpoint`
|
|
28
|
+
- `chore(deps): update TanStack Query to 5.x`
|
|
29
|
+
|
|
30
|
+
### 2. Secret Scan
|
|
31
|
+
Check staged files for accidental secrets:
|
|
32
|
+
- Connection strings with passwords
|
|
33
|
+
- API keys or tokens
|
|
34
|
+
- Private keys (-----BEGIN RSA PRIVATE KEY-----)
|
|
35
|
+
- `.env` files accidentally staged
|
|
36
|
+
|
|
37
|
+
**Blockers** (commit must be rejected):
|
|
38
|
+
- Any `password=` or `pwd=` outside development appsettings
|
|
39
|
+
- API keys matching common patterns (sk-*, xoxb-*, ghp_*)
|
|
40
|
+
- Private key headers
|
|
41
|
+
|
|
42
|
+
### 3. Agent Spec Validation (if agents.json staged)
|
|
43
|
+
If `.morph/framework/agents.json` is in staged files:
|
|
44
|
+
- Valid JSON structure
|
|
45
|
+
- All required agent fields present (agentId, role, tier, domain)
|
|
46
|
+
- No duplicate agentIds
|
|
47
|
+
- Valid tier values (1-4)
|
|
48
|
+
|
|
49
|
+
### 4. Spec Format Validation (if spec.md staged)
|
|
50
|
+
If any `spec.md` is staged:
|
|
51
|
+
- Has required sections: Overview, Requirements, Technical Design, Data Model, API Contracts
|
|
52
|
+
- No placeholder text (`{{TODO}}`, `TBD`, `[PLACEHOLDER]`)
|
|
53
|
+
- Word count > 200 (meaningful spec)
|
|
54
|
+
|
|
55
|
+
### 5. Stack-Specific Validation
|
|
56
|
+
{{#if IS_CSHARP}}
|
|
57
|
+
For C# files:
|
|
58
|
+
- No `TODO` comments in staged code
|
|
59
|
+
- No `Console.WriteLine` in production code (use ILogger)
|
|
60
|
+
- No `Thread.Sleep` (use async alternatives)
|
|
61
|
+
{{/if}}
|
|
62
|
+
|
|
63
|
+
{{#if IS_TYPESCRIPT}}
|
|
64
|
+
For TypeScript files:
|
|
65
|
+
- No `any` type (use proper types)
|
|
66
|
+
- No `console.log` in production components
|
|
67
|
+
- No commented-out code blocks > 3 lines
|
|
68
|
+
{{/if}}
|
|
69
|
+
|
|
70
|
+
## Decision
|
|
71
|
+
|
|
72
|
+
**All checks pass:**
|
|
73
|
+
```
|
|
74
|
+
✅ Pre-commit validation passed
|
|
75
|
+
Proceeding with commit.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Blocking issue found:**
|
|
79
|
+
```
|
|
80
|
+
❌ Pre-commit BLOCKED
|
|
81
|
+
|
|
82
|
+
Issue: [description]
|
|
83
|
+
File: [file:line]
|
|
84
|
+
Fix: [specific instruction]
|
|
85
|
+
|
|
86
|
+
Commit rejected. Fix the issue and retry.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Warning only (commit proceeds):**
|
|
90
|
+
```
|
|
91
|
+
⚠️ Pre-commit warnings (commit allowed)
|
|
92
|
+
|
|
93
|
+
Warning: [description]
|
|
94
|
+
Recommendation: [suggestion]
|
|
95
|
+
```
|
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* bin/validate.js — generated by morph-spec setup-infra
|
|
4
|
-
*
|
|
5
|
-
* Thin validator entry-point called by morph-spec validate-completion hook:
|
|
6
|
-
* node bin/validate.js <validator> [--json]
|
|
7
|
-
*
|
|
8
|
-
* Supported validators: architecture, nextjs-component,
|
|
9
|
-
* packages, design-system, ui-contrast, css
|
|
10
|
-
*
|
|
11
|
-
* Exits 0 on pass, 1 on validation errors.
|
|
12
|
-
* --json flag prints structured JSON to stdout.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const validator = process.argv[2];
|
|
16
|
-
const isJson = process.argv.includes('--json');
|
|
17
|
-
|
|
18
|
-
if (!validator) {
|
|
19
|
-
console.error('Usage: node bin/validate.js <validator> [--json]');
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const { execSync } = await import('child_process');
|
|
24
|
-
const { existsSync } = await import('fs');
|
|
25
|
-
const { join } = await import('path');
|
|
26
|
-
|
|
27
|
-
const cwd = process.cwd();
|
|
28
|
-
|
|
29
|
-
const results = {
|
|
30
|
-
validator,
|
|
31
|
-
errors: 0,
|
|
32
|
-
warnings: 0,
|
|
33
|
-
passed: true,
|
|
34
|
-
issues: [],
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Run a shell command and capture output.
|
|
39
|
-
* Returns { success, stdout, stderr }.
|
|
40
|
-
*/
|
|
41
|
-
function runCommand(cmd, options = {}) {
|
|
42
|
-
try {
|
|
43
|
-
const stdout = execSync(cmd, { cwd, stdio: ['pipe', 'pipe', 'pipe'], ...options }).toString();
|
|
44
|
-
return { success: true, stdout, stderr: '' };
|
|
45
|
-
} catch (err) {
|
|
46
|
-
return {
|
|
47
|
-
success: false,
|
|
48
|
-
stdout: err.stdout?.toString() || '',
|
|
49
|
-
stderr: err.stderr?.toString() || err.message,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// ── Stack detection ───────────────────────────────────────────────────────────
|
|
55
|
-
|
|
56
|
-
const hasFrontend = existsSync(join(cwd, 'src/frontend')) || existsSync(join(cwd, 'frontend'));
|
|
57
|
-
const hasBackend = existsSync(join(cwd, 'src/backend')) || existsSync(join(cwd, 'backend'));
|
|
58
|
-
const hasSln = existsSync(join(cwd, 'src/backend/backend.sln')) ||
|
|
59
|
-
existsSync(join(cwd, 'src/backend/Backend.sln'));
|
|
60
|
-
|
|
61
|
-
const frontendDir = existsSync(join(cwd, 'src/frontend')) ? 'src/frontend' : 'frontend';
|
|
62
|
-
const backendDir = existsSync(join(cwd, 'src/backend')) ? 'src/backend' : 'backend';
|
|
63
|
-
|
|
64
|
-
// ── Validator dispatch ────────────────────────────────────────────────────────
|
|
65
|
-
|
|
66
|
-
switch (validator) {
|
|
67
|
-
case 'architecture': {
|
|
68
|
-
if (hasBackend && hasSln) {
|
|
69
|
-
const slnFile = hasSln ? (
|
|
70
|
-
existsSync(join(cwd, 'src/backend/backend.sln')) ? 'backend.sln' : 'Backend.sln'
|
|
71
|
-
) : '.';
|
|
72
|
-
const result = runCommand(`dotnet build ${slnFile} --no-restore -warnaserror`, { cwd: join(cwd, backendDir) });
|
|
73
|
-
if (!result.success) {
|
|
74
|
-
results.errors++;
|
|
75
|
-
results.passed = false;
|
|
76
|
-
results.issues.push({ level: 'error', message: `dotnet build failed: ${result.stderr.split('\n')[0]}` });
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
case 'nextjs-component':
|
|
83
|
-
case 'packages':
|
|
84
|
-
case 'design-system': {
|
|
85
|
-
if (hasFrontend) {
|
|
86
|
-
const result = runCommand('npx tsc --noEmit', { cwd: join(cwd, frontendDir) });
|
|
87
|
-
if (!result.success) {
|
|
88
|
-
results.errors++;
|
|
89
|
-
results.passed = false;
|
|
90
|
-
results.issues.push({ level: 'error', message: `TypeScript errors found. Run: npx tsc --noEmit` });
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
case 'ui-contrast':
|
|
97
|
-
case 'css': {
|
|
98
|
-
// CSS/contrast validators are visual — report as informational
|
|
99
|
-
results.issues.push({ level: 'info', message: `${validator} requires manual review` });
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
default:
|
|
104
|
-
results.issues.push({ level: 'warning', message: `Unknown validator: ${validator}` });
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// ── Output ────────────────────────────────────────────────────────────────────
|
|
109
|
-
|
|
110
|
-
if (isJson) {
|
|
111
|
-
console.log(JSON.stringify(results, null, 2));
|
|
112
|
-
} else {
|
|
113
|
-
const icon = results.passed ? '✅' : '❌';
|
|
114
|
-
console.log(`${icon} Validator: ${validator} — ${results.passed ? 'PASSED' : `FAILED (${results.errors} errors)`}`);
|
|
115
|
-
for (const issue of results.issues) {
|
|
116
|
-
console.log(` [${issue.level}] ${issue.message}`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
process.exit(results.passed ? 0 : 1);
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* bin/validate.js — generated by morph-spec setup-infra
|
|
4
|
+
*
|
|
5
|
+
* Thin validator entry-point called by morph-spec validate-completion hook:
|
|
6
|
+
* node bin/validate.js <validator> [--json]
|
|
7
|
+
*
|
|
8
|
+
* Supported validators: architecture, nextjs-component,
|
|
9
|
+
* packages, design-system, ui-contrast, css
|
|
10
|
+
*
|
|
11
|
+
* Exits 0 on pass, 1 on validation errors.
|
|
12
|
+
* --json flag prints structured JSON to stdout.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const validator = process.argv[2];
|
|
16
|
+
const isJson = process.argv.includes('--json');
|
|
17
|
+
|
|
18
|
+
if (!validator) {
|
|
19
|
+
console.error('Usage: node bin/validate.js <validator> [--json]');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const { execSync } = await import('child_process');
|
|
24
|
+
const { existsSync } = await import('fs');
|
|
25
|
+
const { join } = await import('path');
|
|
26
|
+
|
|
27
|
+
const cwd = process.cwd();
|
|
28
|
+
|
|
29
|
+
const results = {
|
|
30
|
+
validator,
|
|
31
|
+
errors: 0,
|
|
32
|
+
warnings: 0,
|
|
33
|
+
passed: true,
|
|
34
|
+
issues: [],
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Run a shell command and capture output.
|
|
39
|
+
* Returns { success, stdout, stderr }.
|
|
40
|
+
*/
|
|
41
|
+
function runCommand(cmd, options = {}) {
|
|
42
|
+
try {
|
|
43
|
+
const stdout = execSync(cmd, { cwd, stdio: ['pipe', 'pipe', 'pipe'], ...options }).toString();
|
|
44
|
+
return { success: true, stdout, stderr: '' };
|
|
45
|
+
} catch (err) {
|
|
46
|
+
return {
|
|
47
|
+
success: false,
|
|
48
|
+
stdout: err.stdout?.toString() || '',
|
|
49
|
+
stderr: err.stderr?.toString() || err.message,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ── Stack detection ───────────────────────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
const hasFrontend = existsSync(join(cwd, 'src/frontend')) || existsSync(join(cwd, 'frontend'));
|
|
57
|
+
const hasBackend = existsSync(join(cwd, 'src/backend')) || existsSync(join(cwd, 'backend'));
|
|
58
|
+
const hasSln = existsSync(join(cwd, 'src/backend/backend.sln')) ||
|
|
59
|
+
existsSync(join(cwd, 'src/backend/Backend.sln'));
|
|
60
|
+
|
|
61
|
+
const frontendDir = existsSync(join(cwd, 'src/frontend')) ? 'src/frontend' : 'frontend';
|
|
62
|
+
const backendDir = existsSync(join(cwd, 'src/backend')) ? 'src/backend' : 'backend';
|
|
63
|
+
|
|
64
|
+
// ── Validator dispatch ────────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
switch (validator) {
|
|
67
|
+
case 'architecture': {
|
|
68
|
+
if (hasBackend && hasSln) {
|
|
69
|
+
const slnFile = hasSln ? (
|
|
70
|
+
existsSync(join(cwd, 'src/backend/backend.sln')) ? 'backend.sln' : 'Backend.sln'
|
|
71
|
+
) : '.';
|
|
72
|
+
const result = runCommand(`dotnet build ${slnFile} --no-restore -warnaserror`, { cwd: join(cwd, backendDir) });
|
|
73
|
+
if (!result.success) {
|
|
74
|
+
results.errors++;
|
|
75
|
+
results.passed = false;
|
|
76
|
+
results.issues.push({ level: 'error', message: `dotnet build failed: ${result.stderr.split('\n')[0]}` });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
case 'nextjs-component':
|
|
83
|
+
case 'packages':
|
|
84
|
+
case 'design-system': {
|
|
85
|
+
if (hasFrontend) {
|
|
86
|
+
const result = runCommand('npx tsc --noEmit', { cwd: join(cwd, frontendDir) });
|
|
87
|
+
if (!result.success) {
|
|
88
|
+
results.errors++;
|
|
89
|
+
results.passed = false;
|
|
90
|
+
results.issues.push({ level: 'error', message: `TypeScript errors found. Run: npx tsc --noEmit` });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
case 'ui-contrast':
|
|
97
|
+
case 'css': {
|
|
98
|
+
// CSS/contrast validators are visual — report as informational
|
|
99
|
+
results.issues.push({ level: 'info', message: `${validator} requires manual review` });
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
default:
|
|
104
|
+
results.issues.push({ level: 'warning', message: `Unknown validator: ${validator}` });
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ── Output ────────────────────────────────────────────────────────────────────
|
|
109
|
+
|
|
110
|
+
if (isJson) {
|
|
111
|
+
console.log(JSON.stringify(results, null, 2));
|
|
112
|
+
} else {
|
|
113
|
+
const icon = results.passed ? '✅' : '❌';
|
|
114
|
+
console.log(`${icon} Validator: ${validator} — ${results.passed ? 'PASSED' : `FAILED (${results.errors} errors)`}`);
|
|
115
|
+
for (const issue of results.issues) {
|
|
116
|
+
console.log(` [${issue.level}] ${issue.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
process.exit(results.passed ? 0 : 1);
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "3.0.0",
|
|
3
|
-
"project": {
|
|
4
|
-
"name": "{{PROJECT_NAME}}",
|
|
5
|
-
"type": "{{PROJECT_TYPE}}",
|
|
6
|
-
"createdAt": "{{TIMESTAMP}}",
|
|
7
|
-
"updatedAt": "{{TIMESTAMP}}"
|
|
8
|
-
},
|
|
9
|
-
"features": {},
|
|
10
|
-
"threads": {},
|
|
11
|
-
"metadata": {
|
|
12
|
-
"totalFeatures": 0,
|
|
13
|
-
"completedFeatures": 0,
|
|
14
|
-
"totalTimeSpent": 0,
|
|
15
|
-
"lastUpdated": "{{TIMESTAMP}}"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"version": "3.0.0",
|
|
3
|
+
"project": {
|
|
4
|
+
"name": "{{PROJECT_NAME}}",
|
|
5
|
+
"type": "{{PROJECT_TYPE}}",
|
|
6
|
+
"createdAt": "{{TIMESTAMP}}",
|
|
7
|
+
"updatedAt": "{{TIMESTAMP}}"
|
|
8
|
+
},
|
|
9
|
+
"features": {},
|
|
10
|
+
"threads": {},
|
|
11
|
+
"metadata": {
|
|
12
|
+
"totalFeatures": 0,
|
|
13
|
+
"completedFeatures": 0,
|
|
14
|
+
"totalTimeSpent": 0,
|
|
15
|
+
"lastUpdated": "{{TIMESTAMP}}"
|
|
16
|
+
}
|
|
17
|
+
}
|