@polymorphism-tech/morph-spec 2.2.0 → 2.4.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 +314 -1673
- package/LICENSE +72 -72
- package/README.md +515 -516
- package/bin/detect-agents.js +225 -225
- package/bin/morph-spec.js +358 -173
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/task-manager.js +429 -0
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- package/bin/validate.js +369 -0
- package/content/.azure/README.md +293 -293
- package/content/.azure/docs/azure-devops-setup.md +454 -454
- package/content/.azure/docs/branch-strategy.md +398 -398
- package/content/.azure/docs/local-development.md +515 -515
- package/content/.azure/pipelines/pipeline-variables.yml +34 -34
- package/content/.azure/pipelines/prod-pipeline.yml +319 -319
- package/content/.azure/pipelines/staging-pipeline.yml +234 -234
- package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
- package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
- package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
- package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
- package/content/.claude/commands/morph-apply.md +221 -158
- package/content/.claude/commands/morph-archive.md +79 -79
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -0
- package/content/.claude/commands/morph-proposal.md +122 -101
- package/content/.claude/commands/morph-status.md +86 -86
- package/content/.claude/commands/morph-troubleshoot.md +122 -0
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/checklists/code-review.md +226 -0
- package/content/.claude/skills/checklists/morph-checklist.md +117 -0
- package/content/.claude/skills/checklists/simulation-checklist.md +77 -0
- package/content/.claude/skills/infra/bicep-architect.md +126 -419
- package/content/.claude/skills/infra/container-specialist.md +131 -437
- package/content/.claude/skills/infra/devops-engineer.md +119 -405
- package/content/.claude/skills/integrations/asaas-financial.md +130 -333
- package/content/.claude/skills/integrations/azure-identity.md +142 -309
- package/content/.claude/skills/integrations/clerk-auth.md +108 -290
- package/content/.claude/skills/integrations/resend-email.md +119 -0
- package/content/.claude/skills/specialists/ai-system-architect.md +192 -604
- package/content/.claude/skills/specialists/azure-architect.md +142 -142
- package/content/.claude/skills/specialists/code-analyzer.md +235 -0
- package/content/.claude/skills/specialists/dotnet-senior.md +287 -0
- package/content/.claude/skills/specialists/ef-modeler.md +113 -200
- package/content/.claude/skills/specialists/hangfire-orchestrator.md +126 -245
- package/content/.claude/skills/specialists/ms-agent-expert.md +109 -263
- package/content/.claude/skills/specialists/po-pm-advisor.md +197 -197
- package/content/.claude/skills/specialists/standards-architect.md +156 -78
- package/content/.claude/skills/specialists/testing-specialist.md +126 -0
- package/content/.claude/skills/specialists/ui-ux-designer.md +191 -1060
- package/content/.claude/skills/stacks/dotnet-blazor.md +210 -588
- package/content/.claude/skills/stacks/dotnet-nextjs.md +154 -402
- package/content/.claude/skills/workflows/morph-replicate.md +213 -0
- package/content/.claude/{commands/morph-clarify.md → skills/workflows/phase-clarify.md} +5 -58
- package/content/.claude/{commands/morph-design.md → skills/workflows/phase-design.md} +16 -86
- package/content/.claude/{commands/morph-setup.md → skills/workflows/phase-setup.md} +9 -17
- package/content/.claude/skills/workflows/phase-tasks.md +164 -0
- package/content/.claude/{commands/morph-uiux.md → skills/workflows/phase-uiux.md} +15 -88
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +378 -242
- package/content/.morph/config/config.template.json +89 -108
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/docs/workflows/design-impl.md +37 -0
- package/content/.morph/docs/workflows/fast-track.md +29 -0
- package/content/.morph/docs/workflows/full-morph.md +76 -0
- package/content/.morph/docs/workflows/standard.md +44 -0
- package/content/.morph/docs/workflows/ui-refresh.md +39 -0
- package/content/.morph/examples/api-nextjs/README.md +241 -241
- package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
- package/content/.morph/examples/api-nextjs/spec.md +399 -399
- package/content/.morph/examples/api-nextjs/tasks.md +168 -168
- package/content/.morph/examples/micro-saas/README.md +125 -125
- package/content/.morph/examples/micro-saas/contracts.cs +358 -358
- package/content/.morph/examples/micro-saas/decisions.md +246 -246
- package/content/.morph/examples/micro-saas/spec.md +236 -236
- package/content/.morph/examples/micro-saas/tasks.md +150 -150
- package/content/.morph/examples/multi-agent/README.md +309 -309
- package/content/.morph/examples/multi-agent/contracts.cs +433 -433
- package/content/.morph/examples/multi-agent/spec.md +479 -479
- package/content/.morph/examples/multi-agent/tasks.md +185 -185
- package/content/.morph/examples/scheduled-reports/decisions.md +158 -0
- package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
- package/content/.morph/examples/scheduled-reports/spec.md +267 -0
- package/content/.morph/examples/state-v3.json +188 -0
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/README.md +190 -239
- package/content/.morph/hooks/pre-commit-agents.sh +24 -24
- package/content/.morph/hooks/pre-commit-all.sh +48 -48
- package/content/.morph/hooks/pre-commit-specs.sh +49 -49
- package/content/.morph/hooks/pre-commit-tests.sh +60 -60
- package/content/.morph/project.md +160 -160
- package/content/.morph/schemas/agent.schema.json +296 -296
- package/content/.morph/schemas/tasks.schema.json +220 -0
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
- package/content/.morph/standards/agent-framework-production.md +410 -0
- package/content/.morph/standards/agent-framework-setup.md +413 -453
- package/content/.morph/standards/agent-framework-workflows.md +349 -0
- package/content/.morph/standards/architecture.md +325 -325
- package/content/.morph/standards/azure.md +605 -379
- package/content/.morph/standards/coding.md +377 -377
- package/content/.morph/standards/dotnet10-migration.md +520 -494
- package/content/.morph/standards/fluent-ui-setup.md +590 -590
- package/content/.morph/standards/migration-guide.md +514 -514
- package/content/.morph/standards/passkeys-auth.md +423 -423
- package/content/.morph/standards/vector-search-rag.md +536 -536
- package/content/.morph/state.json +17 -17
- package/content/.morph/templates/FluentDesignTheme.cs +149 -149
- package/content/.morph/templates/MudTheme.cs +281 -281
- package/content/.morph/templates/agent.cs +163 -172
- package/content/.morph/templates/clarify-questions.md +159 -0
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts/Commands.cs +74 -0
- package/content/.morph/templates/contracts/Entities.cs +25 -0
- package/content/.morph/templates/contracts/Queries.cs +74 -0
- package/content/.morph/templates/contracts/README.md +74 -0
- package/content/.morph/templates/contracts.cs +217 -217
- package/content/.morph/templates/decisions.md +123 -106
- package/content/.morph/templates/design-system.css +226 -226
- package/content/.morph/templates/infra/.dockerignore.example +89 -89
- package/content/.morph/templates/infra/Dockerfile.example +82 -82
- package/content/.morph/templates/infra/README.md +286 -286
- package/content/.morph/templates/infra/app-insights.bicep +63 -63
- package/content/.morph/templates/infra/app-service.bicep +164 -164
- package/content/.morph/templates/infra/container-app-env.bicep +49 -49
- package/content/.morph/templates/infra/container-app.bicep +156 -156
- package/content/.morph/templates/infra/deploy-checklist.md +426 -0
- package/content/.morph/templates/infra/deploy.ps1 +229 -229
- package/content/.morph/templates/infra/deploy.sh +208 -208
- package/content/.morph/templates/infra/key-vault.bicep +91 -91
- package/content/.morph/templates/infra/main.bicep +189 -189
- package/content/.morph/templates/infra/parameters.dev.json +29 -29
- package/content/.morph/templates/infra/parameters.prod.json +29 -29
- package/content/.morph/templates/infra/parameters.staging.json +29 -29
- package/content/.morph/templates/infra/sql-database.bicep +103 -103
- package/content/.morph/templates/infra/storage.bicep +106 -106
- package/content/.morph/templates/integrations/asaas-client.cs +387 -387
- package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
- package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
- package/content/.morph/templates/integrations/clerk-config.cs +258 -258
- package/content/.morph/templates/job.cs +171 -171
- package/content/.morph/templates/migration.cs +83 -83
- package/content/.morph/templates/proposal.md +141 -155
- package/content/.morph/templates/recap.md +94 -105
- package/content/.morph/templates/repository.cs +141 -141
- package/content/.morph/templates/saas/subscription.cs +347 -347
- package/content/.morph/templates/saas/tenant.cs +338 -338
- package/content/.morph/templates/service.cs +139 -139
- package/content/.morph/templates/simulation.md +353 -0
- package/content/.morph/templates/spec.md +149 -148
- package/content/.morph/templates/sprint-status.yaml +68 -68
- package/content/.morph/templates/state.template.json +222 -222
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/tasks.md +257 -235
- package/content/.morph/templates/test.cs +239 -239
- package/content/.morph/templates/ui-components.md +362 -276
- package/content/.morph/templates/ui-design-system.md +286 -286
- package/content/.morph/templates/ui-flows.md +336 -336
- package/content/.morph/templates/ui-mockups.md +133 -133
- package/content/.morph/test-infra/example.bicep +59 -59
- package/content/CLAUDE.md +150 -442
- package/content/README.md +79 -79
- package/detectors/config-detector.js +223 -223
- package/detectors/conversation-analyzer.js +163 -163
- package/detectors/index.js +84 -84
- package/detectors/standards-generator.js +275 -275
- package/detectors/structure-detector.js +245 -250
- package/docs/README.md +144 -149
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
- package/docs/api/scripts/collapse.js +38 -38
- package/docs/api/scripts/commonNav.js +28 -28
- package/docs/api/scripts/linenumber.js +25 -25
- package/docs/api/scripts/nav.js +12 -12
- package/docs/api/scripts/polyfill.js +3 -3
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
- package/docs/api/scripts/prettify/lang-css.js +2 -2
- package/docs/api/scripts/prettify/prettify.js +28 -28
- package/docs/api/scripts/search.js +98 -98
- package/docs/api/styles/jsdoc.css +776 -776
- package/docs/api/styles/prettify.css +80 -80
- package/docs/examples.md +328 -328
- package/docs/getting-started.md +301 -302
- package/docs/installation.md +361 -361
- package/docs/templates.md +418 -418
- package/docs/validation-checklist.md +265 -266
- package/package.json +80 -80
- package/scripts/postinstall.js +132 -132
- package/src/commands/advance-phase.js +183 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -0
- package/src/commands/create-story.js +351 -351
- package/src/commands/detect-agents.js +139 -0
- package/src/commands/detect.js +104 -104
- package/src/commands/doctor.js +356 -280
- package/src/commands/generate.js +149 -149
- package/src/commands/init.js +258 -245
- package/src/commands/lint-fluent.js +352 -0
- package/src/commands/rollback-phase.js +185 -0
- package/src/commands/session-summary.js +291 -0
- package/src/commands/shard-spec.js +224 -224
- package/src/commands/sprint-status.js +250 -250
- package/src/commands/state.js +333 -333
- package/src/commands/sync.js +167 -167
- package/src/commands/task.js +78 -0
- package/src/commands/troubleshoot.js +222 -0
- package/src/commands/update.js +192 -159
- package/src/commands/validate-blazor-state.js +210 -0
- package/src/commands/validate-blazor.js +156 -0
- package/src/commands/validate-css.js +84 -0
- package/src/commands/validate-phase.js +221 -0
- package/src/lib/blazor-concurrency-analyzer.js +288 -0
- package/src/lib/blazor-state-validator.js +291 -0
- package/src/lib/blazor-validator.js +374 -0
- package/src/lib/complexity-analyzer.js +441 -292
- package/src/lib/continuous-validator.js +421 -0
- package/src/lib/css-validator.js +352 -0
- package/src/lib/decision-constraint-loader.js +109 -0
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/learning-system.js +520 -0
- package/src/lib/mockup-generator.js +366 -0
- package/src/lib/recap-generator.js +205 -0
- package/src/lib/state-manager.js +397 -340
- package/src/lib/troubleshoot-grep.js +194 -0
- package/src/lib/troubleshoot-index.js +144 -0
- package/src/lib/ui-detector.js +350 -0
- package/src/lib/validation-runner.js +231 -0
- package/src/lib/validators/architecture-validator.js +387 -0
- package/src/lib/validators/contract-compliance-validator.js +273 -0
- package/src/lib/validators/package-validator.js +360 -0
- package/src/lib/validators/ui-contrast-validator.js +422 -0
- package/src/utils/file-copier.js +179 -139
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- package/content/.claude/commands/morph-costs.md +0 -206
- package/content/.claude/commands/morph-tasks.md +0 -319
- package/content/.claude/skills/specialists/cost-guardian.md +0 -110
- package/content/.claude/skills/stacks/shopify.md +0 -445
- package/content/.morph/config/azure-pricing.json +0 -70
- package/content/.morph/config/azure-pricing.schema.json +0 -50
- package/content/.morph/hooks/pre-commit-costs.sh +0 -91
- package/docs/api/cost-calculator.js.html +0 -513
- package/docs/api/design-system-generator.js.html +0 -382
- package/docs/api/global.html +0 -5263
- package/docs/api/index.html +0 -96
- package/docs/api/state-manager.js.html +0 -423
- package/src/commands/cost.js +0 -181
- package/src/commands/update-pricing.js +0 -206
- package/src/lib/cost-calculator.js +0 -429
package/package.json
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@polymorphism-tech/morph-spec",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "MORPH-SPEC v2.0: AI-First development framework with .NET 10, Microsoft Agent Framework, and Fluent UI Blazor",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"claude-code",
|
|
7
|
-
"claude",
|
|
8
|
-
"ai-coding",
|
|
9
|
-
"ai-first",
|
|
10
|
-
"spec-driven",
|
|
11
|
-
"dotnet",
|
|
12
|
-
"dotnet10",
|
|
13
|
-
"blazor",
|
|
14
|
-
"agent-framework",
|
|
15
|
-
"fluent-ui",
|
|
16
|
-
"framework",
|
|
17
|
-
"developer-tools",
|
|
18
|
-
"morph",
|
|
19
|
-
"polymorphism",
|
|
20
|
-
"micro-saas"
|
|
21
|
-
],
|
|
22
|
-
"main": "src/index.js",
|
|
23
|
-
"bin": {
|
|
24
|
-
"morph-spec": "bin/morph-spec.js"
|
|
25
|
-
},
|
|
26
|
-
"files": [
|
|
27
|
-
"bin/",
|
|
28
|
-
"src/",
|
|
29
|
-
"scripts/",
|
|
30
|
-
"detectors/",
|
|
31
|
-
"content/",
|
|
32
|
-
"docs/",
|
|
33
|
-
"README.md",
|
|
34
|
-
"LICENSE",
|
|
35
|
-
"CLAUDE.md"
|
|
36
|
-
],
|
|
37
|
-
"type": "module",
|
|
38
|
-
"engines": {
|
|
39
|
-
"node": ">=18.0.0"
|
|
40
|
-
},
|
|
41
|
-
"scripts": {
|
|
42
|
-
"postinstall": "node scripts/postinstall.js",
|
|
43
|
-
"start": "node bin/morph-spec.js",
|
|
44
|
-
"test": "node --test",
|
|
45
|
-
"test:coverage": "c8 --reporter=text --reporter=html --reporter=lcov node --test",
|
|
46
|
-
"test:coverage:summary": "c8 --reporter=text-summary node --test",
|
|
47
|
-
"docs": "jsdoc -c jsdoc.json",
|
|
48
|
-
"docs:watch": "jsdoc -c jsdoc.json --watch",
|
|
49
|
-
"docs:serve": "npx http-server docs/api -p 8080 -o"
|
|
50
|
-
},
|
|
51
|
-
"dependencies": {
|
|
52
|
-
"ajv": "^8.12.0",
|
|
53
|
-
"ajv-formats": "^3.0.1",
|
|
54
|
-
"chalk": "^5.3.0",
|
|
55
|
-
"commander": "^12.0.0",
|
|
56
|
-
"fs-extra": "^11.2.0",
|
|
57
|
-
"glob": "^10.3.0",
|
|
58
|
-
"ora": "^8.0.0",
|
|
59
|
-
"yaml": "^2.3.4"
|
|
60
|
-
},
|
|
61
|
-
"repository": {
|
|
62
|
-
"type": "git",
|
|
63
|
-
"url": "git+https://github.com/lucasPolymorphism/morph-spec-framework.git"
|
|
64
|
-
},
|
|
65
|
-
"author": "Polymorphism Tech <contact@polymorphism.com.br>",
|
|
66
|
-
"license": "SEE LICENSE IN LICENSE",
|
|
67
|
-
"homepage": "https://polymorphism.com.br/morph-spec",
|
|
68
|
-
"bugs": {
|
|
69
|
-
"email": "support@polymorphism.com.br"
|
|
70
|
-
},
|
|
71
|
-
"private": false,
|
|
72
|
-
"publishConfig": {
|
|
73
|
-
"access": "public"
|
|
74
|
-
},
|
|
75
|
-
"devDependencies": {
|
|
76
|
-
"c8": "^10.1.3",
|
|
77
|
-
"docdash": "^2.0.2",
|
|
78
|
-
"jsdoc": "^4.0.5"
|
|
79
|
-
}
|
|
80
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@polymorphism-tech/morph-spec",
|
|
3
|
+
"version": "2.4.0",
|
|
4
|
+
"description": "MORPH-SPEC v2.0: AI-First development framework with .NET 10, Microsoft Agent Framework, and Fluent UI Blazor",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"claude-code",
|
|
7
|
+
"claude",
|
|
8
|
+
"ai-coding",
|
|
9
|
+
"ai-first",
|
|
10
|
+
"spec-driven",
|
|
11
|
+
"dotnet",
|
|
12
|
+
"dotnet10",
|
|
13
|
+
"blazor",
|
|
14
|
+
"agent-framework",
|
|
15
|
+
"fluent-ui",
|
|
16
|
+
"framework",
|
|
17
|
+
"developer-tools",
|
|
18
|
+
"morph",
|
|
19
|
+
"polymorphism",
|
|
20
|
+
"micro-saas"
|
|
21
|
+
],
|
|
22
|
+
"main": "src/index.js",
|
|
23
|
+
"bin": {
|
|
24
|
+
"morph-spec": "bin/morph-spec.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"bin/",
|
|
28
|
+
"src/",
|
|
29
|
+
"scripts/",
|
|
30
|
+
"detectors/",
|
|
31
|
+
"content/",
|
|
32
|
+
"docs/",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE",
|
|
35
|
+
"CLAUDE.md"
|
|
36
|
+
],
|
|
37
|
+
"type": "module",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"postinstall": "node scripts/postinstall.js",
|
|
43
|
+
"start": "node bin/morph-spec.js",
|
|
44
|
+
"test": "node --test",
|
|
45
|
+
"test:coverage": "c8 --reporter=text --reporter=html --reporter=lcov node --test",
|
|
46
|
+
"test:coverage:summary": "c8 --reporter=text-summary node --test",
|
|
47
|
+
"docs": "jsdoc -c jsdoc.json",
|
|
48
|
+
"docs:watch": "jsdoc -c jsdoc.json --watch",
|
|
49
|
+
"docs:serve": "npx http-server docs/api -p 8080 -o"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"ajv": "^8.12.0",
|
|
53
|
+
"ajv-formats": "^3.0.1",
|
|
54
|
+
"chalk": "^5.3.0",
|
|
55
|
+
"commander": "^12.0.0",
|
|
56
|
+
"fs-extra": "^11.2.0",
|
|
57
|
+
"glob": "^10.3.0",
|
|
58
|
+
"ora": "^8.0.0",
|
|
59
|
+
"yaml": "^2.3.4"
|
|
60
|
+
},
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "git+https://github.com/lucasPolymorphism/morph-spec-framework.git"
|
|
64
|
+
},
|
|
65
|
+
"author": "Polymorphism Tech <contact@polymorphism.com.br>",
|
|
66
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
67
|
+
"homepage": "https://polymorphism.com.br/morph-spec",
|
|
68
|
+
"bugs": {
|
|
69
|
+
"email": "support@polymorphism.com.br"
|
|
70
|
+
},
|
|
71
|
+
"private": false,
|
|
72
|
+
"publishConfig": {
|
|
73
|
+
"access": "public"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"c8": "^10.1.3",
|
|
77
|
+
"docdash": "^2.0.2",
|
|
78
|
+
"jsdoc": "^4.0.5"
|
|
79
|
+
}
|
|
80
|
+
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Postinstall script for @polymorphism-tech/morph-spec
|
|
5
|
-
*
|
|
6
|
-
* Checks if morph-spec is accessible in PATH and warns users
|
|
7
|
-
* if it's not (common issue with nvm-windows).
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { execSync } from 'child_process';
|
|
11
|
-
import { platform } from 'os';
|
|
12
|
-
import chalk from 'chalk';
|
|
13
|
-
|
|
14
|
-
const isWindows = platform() === 'win32';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Check if morph-spec command is in PATH
|
|
18
|
-
*/
|
|
19
|
-
function isMorphSpecInPath() {
|
|
20
|
-
try {
|
|
21
|
-
const command = isWindows ? 'where morph-spec' : 'which morph-spec';
|
|
22
|
-
execSync(command, { stdio: 'ignore' });
|
|
23
|
-
return true;
|
|
24
|
-
} catch {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Detect if nvm-windows is installed
|
|
31
|
-
*/
|
|
32
|
-
function isUsingNvmWindows() {
|
|
33
|
-
if (!isWindows) return false;
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
const path = process.env.PATH || '';
|
|
37
|
-
return path.includes('nvm4w') || path.includes('\\nvm\\');
|
|
38
|
-
} catch {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Get npm global prefix
|
|
45
|
-
*/
|
|
46
|
-
function getNpmGlobalPrefix() {
|
|
47
|
-
try {
|
|
48
|
-
const prefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
|
|
49
|
-
return prefix;
|
|
50
|
-
} catch {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Show installation success message
|
|
57
|
-
*/
|
|
58
|
-
function showSuccessMessage() {
|
|
59
|
-
console.log('');
|
|
60
|
-
console.log(chalk.green('✓ @polymorphism-tech/morph-spec installed successfully!'));
|
|
61
|
-
console.log('');
|
|
62
|
-
console.log(chalk.cyan('Quick start:'));
|
|
63
|
-
console.log(chalk.white(' morph-spec init'));
|
|
64
|
-
console.log(chalk.white(' morph-spec --help'));
|
|
65
|
-
console.log('');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Show PATH warning for nvm-windows users
|
|
70
|
-
*/
|
|
71
|
-
function showPathWarning() {
|
|
72
|
-
console.log('');
|
|
73
|
-
console.log(chalk.yellow('⚠ Warning: morph-spec command not found in PATH'));
|
|
74
|
-
console.log('');
|
|
75
|
-
|
|
76
|
-
if (isUsingNvmWindows()) {
|
|
77
|
-
console.log(chalk.white('You are using nvm-windows, which does not automatically add'));
|
|
78
|
-
console.log(chalk.white('npm global packages to your PATH.'));
|
|
79
|
-
console.log('');
|
|
80
|
-
console.log(chalk.cyan('Solution 1: Add npm global directory to PATH'));
|
|
81
|
-
|
|
82
|
-
const prefix = getNpmGlobalPrefix();
|
|
83
|
-
if (prefix) {
|
|
84
|
-
console.log(chalk.white(` Add this to your PATH: ${chalk.yellow(prefix)}`));
|
|
85
|
-
console.log('');
|
|
86
|
-
console.log(chalk.gray(' PowerShell (as Administrator):'));
|
|
87
|
-
console.log(chalk.white(` [Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";${prefix}", "User")`));
|
|
88
|
-
console.log('');
|
|
89
|
-
console.log(chalk.gray(' Or manually via System Properties > Environment Variables'));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
console.log('');
|
|
93
|
-
console.log(chalk.cyan('Solution 2: Use npx (recommended)'));
|
|
94
|
-
console.log(chalk.white(' npx @polymorphism-tech/morph-spec init'));
|
|
95
|
-
console.log(chalk.white(' npx @polymorphism-tech/morph-spec --help'));
|
|
96
|
-
} else {
|
|
97
|
-
console.log(chalk.white('The morph-spec command was not found in your PATH.'));
|
|
98
|
-
console.log('');
|
|
99
|
-
console.log(chalk.cyan('Solution: Use npx instead'));
|
|
100
|
-
console.log(chalk.white(' npx @polymorphism-tech/morph-spec init'));
|
|
101
|
-
console.log(chalk.white(' npx @polymorphism-tech/morph-spec --help'));
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
console.log('');
|
|
105
|
-
console.log(chalk.gray('For more help, see: https://github.com/lucasPolymorphism/morph-spec-framework#troubleshooting'));
|
|
106
|
-
console.log('');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Main postinstall check
|
|
111
|
-
*/
|
|
112
|
-
function main() {
|
|
113
|
-
// Only show messages for global installs
|
|
114
|
-
// Skip for local installs (when used as dependency)
|
|
115
|
-
const isGlobalInstall = process.env.npm_config_global === 'true';
|
|
116
|
-
|
|
117
|
-
if (!isGlobalInstall) {
|
|
118
|
-
// Silent exit for local installs
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Give npm a moment to set up the symlinks
|
|
123
|
-
setTimeout(() => {
|
|
124
|
-
if (isMorphSpecInPath()) {
|
|
125
|
-
showSuccessMessage();
|
|
126
|
-
} else {
|
|
127
|
-
showPathWarning();
|
|
128
|
-
}
|
|
129
|
-
}, 100);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
main();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Postinstall script for @polymorphism-tech/morph-spec
|
|
5
|
+
*
|
|
6
|
+
* Checks if morph-spec is accessible in PATH and warns users
|
|
7
|
+
* if it's not (common issue with nvm-windows).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execSync } from 'child_process';
|
|
11
|
+
import { platform } from 'os';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
|
|
14
|
+
const isWindows = platform() === 'win32';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Check if morph-spec command is in PATH
|
|
18
|
+
*/
|
|
19
|
+
function isMorphSpecInPath() {
|
|
20
|
+
try {
|
|
21
|
+
const command = isWindows ? 'where morph-spec' : 'which morph-spec';
|
|
22
|
+
execSync(command, { stdio: 'ignore' });
|
|
23
|
+
return true;
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Detect if nvm-windows is installed
|
|
31
|
+
*/
|
|
32
|
+
function isUsingNvmWindows() {
|
|
33
|
+
if (!isWindows) return false;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const path = process.env.PATH || '';
|
|
37
|
+
return path.includes('nvm4w') || path.includes('\\nvm\\');
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get npm global prefix
|
|
45
|
+
*/
|
|
46
|
+
function getNpmGlobalPrefix() {
|
|
47
|
+
try {
|
|
48
|
+
const prefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
|
|
49
|
+
return prefix;
|
|
50
|
+
} catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Show installation success message
|
|
57
|
+
*/
|
|
58
|
+
function showSuccessMessage() {
|
|
59
|
+
console.log('');
|
|
60
|
+
console.log(chalk.green('✓ @polymorphism-tech/morph-spec installed successfully!'));
|
|
61
|
+
console.log('');
|
|
62
|
+
console.log(chalk.cyan('Quick start:'));
|
|
63
|
+
console.log(chalk.white(' morph-spec init'));
|
|
64
|
+
console.log(chalk.white(' morph-spec --help'));
|
|
65
|
+
console.log('');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Show PATH warning for nvm-windows users
|
|
70
|
+
*/
|
|
71
|
+
function showPathWarning() {
|
|
72
|
+
console.log('');
|
|
73
|
+
console.log(chalk.yellow('⚠ Warning: morph-spec command not found in PATH'));
|
|
74
|
+
console.log('');
|
|
75
|
+
|
|
76
|
+
if (isUsingNvmWindows()) {
|
|
77
|
+
console.log(chalk.white('You are using nvm-windows, which does not automatically add'));
|
|
78
|
+
console.log(chalk.white('npm global packages to your PATH.'));
|
|
79
|
+
console.log('');
|
|
80
|
+
console.log(chalk.cyan('Solution 1: Add npm global directory to PATH'));
|
|
81
|
+
|
|
82
|
+
const prefix = getNpmGlobalPrefix();
|
|
83
|
+
if (prefix) {
|
|
84
|
+
console.log(chalk.white(` Add this to your PATH: ${chalk.yellow(prefix)}`));
|
|
85
|
+
console.log('');
|
|
86
|
+
console.log(chalk.gray(' PowerShell (as Administrator):'));
|
|
87
|
+
console.log(chalk.white(` [Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";${prefix}", "User")`));
|
|
88
|
+
console.log('');
|
|
89
|
+
console.log(chalk.gray(' Or manually via System Properties > Environment Variables'));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log('');
|
|
93
|
+
console.log(chalk.cyan('Solution 2: Use npx (recommended)'));
|
|
94
|
+
console.log(chalk.white(' npx @polymorphism-tech/morph-spec init'));
|
|
95
|
+
console.log(chalk.white(' npx @polymorphism-tech/morph-spec --help'));
|
|
96
|
+
} else {
|
|
97
|
+
console.log(chalk.white('The morph-spec command was not found in your PATH.'));
|
|
98
|
+
console.log('');
|
|
99
|
+
console.log(chalk.cyan('Solution: Use npx instead'));
|
|
100
|
+
console.log(chalk.white(' npx @polymorphism-tech/morph-spec init'));
|
|
101
|
+
console.log(chalk.white(' npx @polymorphism-tech/morph-spec --help'));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
console.log('');
|
|
105
|
+
console.log(chalk.gray('For more help, see: https://github.com/lucasPolymorphism/morph-spec-framework#troubleshooting'));
|
|
106
|
+
console.log('');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Main postinstall check
|
|
111
|
+
*/
|
|
112
|
+
function main() {
|
|
113
|
+
// Only show messages for global installs
|
|
114
|
+
// Skip for local installs (when used as dependency)
|
|
115
|
+
const isGlobalInstall = process.env.npm_config_global === 'true';
|
|
116
|
+
|
|
117
|
+
if (!isGlobalInstall) {
|
|
118
|
+
// Silent exit for local installs
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Give npm a moment to set up the symlinks
|
|
123
|
+
setTimeout(() => {
|
|
124
|
+
if (isMorphSpecInPath()) {
|
|
125
|
+
showSuccessMessage();
|
|
126
|
+
} else {
|
|
127
|
+
showPathWarning();
|
|
128
|
+
}
|
|
129
|
+
}, 100);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
main();
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MORPH-SPEC Phase Advance Command
|
|
3
|
+
*
|
|
4
|
+
* Validates current phase → advances to next → shows requirements.
|
|
5
|
+
* Replaces the two-step `state set` + `validate-phase` dance.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* morph-spec phase advance <feature>
|
|
9
|
+
* morph-spec phase advance <feature> --skip-optional
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import { loadState, saveState, getFeature } from '../lib/state-manager.js';
|
|
14
|
+
import { PHASES, validatePhase } from './validate-phase.js';
|
|
15
|
+
|
|
16
|
+
// Phase order for advancing (skips optional phases unless active)
|
|
17
|
+
const PHASE_ORDER = ['proposal', 'setup', 'uiux', 'design', 'clarify', 'tasks', 'implement', 'sync'];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get the next phase after the current one
|
|
21
|
+
*/
|
|
22
|
+
function getNextPhase(currentPhase, feature, skipOptional) {
|
|
23
|
+
const currentIndex = PHASE_ORDER.indexOf(currentPhase);
|
|
24
|
+
if (currentIndex === -1 || currentIndex >= PHASE_ORDER.length - 1) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
for (let i = currentIndex + 1; i < PHASE_ORDER.length; i++) {
|
|
29
|
+
const candidate = PHASE_ORDER[i];
|
|
30
|
+
const phaseDef = PHASES[candidate];
|
|
31
|
+
|
|
32
|
+
// Skip optional phases if flag set or no relevant agents/outputs
|
|
33
|
+
if (phaseDef?.optional && skipOptional) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Skip uiux if no UI agents are active
|
|
38
|
+
if (candidate === 'uiux') {
|
|
39
|
+
const uiAgents = ['blazor-builder', 'uiux-designer'];
|
|
40
|
+
const hasUiAgent = feature.activeAgents?.some(a => uiAgents.includes(a));
|
|
41
|
+
if (!hasUiAgent && skipOptional !== false) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Skip sync for simple workflows
|
|
47
|
+
if (candidate === 'sync') {
|
|
48
|
+
const isSimple = feature.workflow === 'fast-track';
|
|
49
|
+
if (isSimple && skipOptional !== false) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return candidate;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Main command handler
|
|
62
|
+
*/
|
|
63
|
+
export async function advancePhaseCommand(feature, options = {}) {
|
|
64
|
+
console.log(chalk.cyan('\n╔════════════════════════════════════════════════╗'));
|
|
65
|
+
console.log(chalk.cyan('║ MORPH-SPEC PHASE ADVANCE ║'));
|
|
66
|
+
console.log(chalk.cyan('╚════════════════════════════════════════════════╝\n'));
|
|
67
|
+
|
|
68
|
+
// Get current feature state
|
|
69
|
+
const featureData = getFeature(feature);
|
|
70
|
+
if (!featureData) {
|
|
71
|
+
console.log(chalk.red(`✗ Feature not found: ${feature}`));
|
|
72
|
+
console.log(chalk.yellow(` Run: morph-spec state set ${feature} phase proposal`));
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const currentPhase = featureData.phase;
|
|
77
|
+
const currentPhaseDef = PHASES[currentPhase];
|
|
78
|
+
|
|
79
|
+
console.log(chalk.gray('Feature:'), feature);
|
|
80
|
+
console.log(chalk.gray('Current Phase:'), currentPhaseDef?.name || currentPhase);
|
|
81
|
+
console.log(chalk.gray('Workflow:'), featureData.workflow || 'auto');
|
|
82
|
+
|
|
83
|
+
// Determine next phase
|
|
84
|
+
const nextPhase = getNextPhase(currentPhase, featureData, options.skipOptional);
|
|
85
|
+
|
|
86
|
+
if (!nextPhase) {
|
|
87
|
+
console.log(chalk.green('\n✓ Feature is at the final phase!'));
|
|
88
|
+
if (currentPhase === 'implement' || currentPhase === 'sync') {
|
|
89
|
+
console.log(chalk.green(' Consider running: morph-spec generate recap ' + feature));
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const nextPhaseDef = PHASES[nextPhase];
|
|
95
|
+
console.log(chalk.gray('Next Phase:'), nextPhaseDef.name);
|
|
96
|
+
|
|
97
|
+
// Validate that current phase requirements are met before advancing
|
|
98
|
+
const validation = validatePhase(feature, nextPhase);
|
|
99
|
+
|
|
100
|
+
if (!validation.valid) {
|
|
101
|
+
console.log(chalk.red('\n✗ Cannot advance — missing requirements:'));
|
|
102
|
+
validation.missingOutputs.forEach(output => {
|
|
103
|
+
console.log(chalk.red(` - ${output}`));
|
|
104
|
+
});
|
|
105
|
+
console.log(chalk.yellow(`\n Complete these before advancing to ${nextPhaseDef.name}`));
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (validation.stateWarning) {
|
|
110
|
+
console.log(chalk.yellow(`\n⚠️ ${validation.stateWarning}`));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Advance the phase
|
|
114
|
+
const state = loadState();
|
|
115
|
+
state.features[feature].phase = nextPhase;
|
|
116
|
+
state.features[feature].updatedAt = new Date().toISOString();
|
|
117
|
+
saveState(state);
|
|
118
|
+
|
|
119
|
+
console.log(chalk.green(`\n✓ Advanced to ${nextPhaseDef.name}`));
|
|
120
|
+
|
|
121
|
+
// Show what's needed in the new phase
|
|
122
|
+
console.log(chalk.cyan('\n📋 Phase requirements:'));
|
|
123
|
+
console.log(chalk.gray(` ${nextPhaseDef.description}`));
|
|
124
|
+
|
|
125
|
+
if (nextPhaseDef.requiredOutputs?.length > 0) {
|
|
126
|
+
console.log(chalk.cyan('\n Required outputs:'));
|
|
127
|
+
nextPhaseDef.requiredOutputs.forEach(output => {
|
|
128
|
+
const exists = validation.phase ? true : false; // Already validated
|
|
129
|
+
console.log(chalk.gray(` ✓ ${output} (exists)`));
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Show phase-specific guidance
|
|
134
|
+
const guidance = getPhaseGuidance(nextPhase, feature);
|
|
135
|
+
if (guidance) {
|
|
136
|
+
console.log(chalk.cyan('\n Next steps:'));
|
|
137
|
+
guidance.forEach(step => console.log(chalk.white(` → ${step}`)));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.log('');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get guidance for what to do in a phase
|
|
145
|
+
*/
|
|
146
|
+
function getPhaseGuidance(phase, feature) {
|
|
147
|
+
const guides = {
|
|
148
|
+
'setup': [
|
|
149
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
150
|
+
'Auto-continues from setup phase'
|
|
151
|
+
],
|
|
152
|
+
'uiux': [
|
|
153
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
154
|
+
'Provide layout references and preferences',
|
|
155
|
+
'Review wireframes before proceeding'
|
|
156
|
+
],
|
|
157
|
+
'design': [
|
|
158
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
159
|
+
'Review DECISION POINTS carefully',
|
|
160
|
+
'Approve spec.md and contracts.cs'
|
|
161
|
+
],
|
|
162
|
+
'clarify': [
|
|
163
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
164
|
+
'Resolve edge cases and unknowns'
|
|
165
|
+
],
|
|
166
|
+
'tasks': [
|
|
167
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
168
|
+
'Review task order and dependencies',
|
|
169
|
+
'Approve task list before implementing'
|
|
170
|
+
],
|
|
171
|
+
'implement': [
|
|
172
|
+
`Start implementing: /morph-apply ${feature}`,
|
|
173
|
+
'Complete tasks one by one with: morph-spec task done',
|
|
174
|
+
'Validators run automatically on task completion'
|
|
175
|
+
],
|
|
176
|
+
'sync': [
|
|
177
|
+
'Review decisions.md for standards to promote',
|
|
178
|
+
`Sync: morph-spec sync --path .morph/project/outputs/${feature}/decisions.md`
|
|
179
|
+
]
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
return guides[phase] || null;
|
|
183
|
+
}
|