@polymorphism-tech/morph-spec 3.1.0 → 4.2.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 +882 -3
- package/README.md +79 -18
- package/bin/detect-agents.js +1 -1
- package/bin/morph-spec.js +163 -26
- package/bin/task-manager.cjs +101 -7
- package/bin/validate.js +1 -1
- package/docs/cli-auto-detection.md +219 -0
- package/docs/getting-started.md +0 -5
- package/docs/llm-interaction-config.md +735 -0
- package/docs/troubleshooting.md +269 -0
- package/docs/v3.0/AGENTS.md +521 -0
- package/docs/v3.0/ANALYSIS.md +555 -0
- package/docs/v3.0/ARCHITECTURE.md +436 -0
- package/docs/v3.0/EXECUTION-FLOW.md +1304 -0
- package/docs/v3.0/FEATURES.md +688 -0
- package/docs/v3.0/README.md +231 -0
- package/docs/v3.0/ROADMAP.md +801 -0
- package/docs/validation-checklist.md +0 -1
- package/package.json +5 -1
- package/src/commands/agents/index.js +4 -0
- package/src/commands/agents/spawn-team.js +172 -0
- package/src/commands/{create-story.js → feature/create-story.js} +357 -354
- package/src/commands/feature/index.js +6 -0
- package/src/commands/{shard-spec.js → feature/shard-spec.js} +2 -2
- package/src/commands/{sprint-status.js → feature/sprint-status.js} +1 -1
- package/src/commands/{generate-context.js → generation/generate-context.js} +40 -40
- package/src/commands/{generate.js → generation/generate.js} +130 -3
- package/src/commands/generation/index.js +5 -0
- package/src/commands/index.js +16 -0
- package/src/commands/learning/capture-pattern.js +121 -0
- package/src/commands/learning/index.js +5 -0
- package/src/commands/learning/search-patterns.js +126 -0
- package/src/commands/{detect-agents.js → project/detect-agents.js} +178 -178
- package/src/commands/project/detect-workflow.js +174 -0
- package/src/commands/{detect.js → project/detect.js} +104 -104
- package/src/commands/{doctor.js → project/doctor.js} +356 -356
- package/src/commands/project/index.js +10 -0
- package/src/commands/{init.js → project/init.js} +305 -258
- package/src/commands/{sync.js → project/sync.js} +167 -167
- package/src/commands/{update.js → project/update.js} +240 -204
- package/src/commands/{advance-phase.js → state/advance-phase.js} +416 -266
- package/src/commands/state/approve.js +221 -0
- package/src/commands/state/index.js +8 -0
- package/src/commands/{rollback-phase.js → state/rollback-phase.js} +185 -185
- package/src/commands/{state.js → state/state.js} +334 -334
- package/src/commands/{validate-phase.js → state/validate-phase.js} +221 -221
- package/src/commands/tasks/index.js +4 -0
- package/src/commands/{task.js → tasks/task.js} +78 -78
- package/src/commands/templates/index.js +8 -0
- package/src/commands/templates/template-customize.js +101 -0
- package/src/commands/templates/template-list.js +128 -0
- package/src/commands/templates/template-render.js +95 -0
- package/src/commands/templates/template-show.js +131 -0
- package/src/commands/templates/template-validate.js +91 -0
- package/src/commands/utils/index.js +7 -0
- package/src/commands/utils/migrate-state.js +158 -0
- package/src/commands/{session-summary.js → utils/session-summary.js} +291 -291
- package/src/commands/{troubleshoot.js → utils/troubleshoot.js} +222 -222
- package/src/commands/utils/upgrade.js +346 -0
- package/src/commands/{analyze-blazor-concurrency.js → validation/analyze-blazor-concurrency.js} +193 -193
- package/src/commands/validation/index.js +8 -0
- package/src/commands/{lint-fluent.js → validation/lint-fluent.js} +352 -352
- package/src/commands/{validate-blazor-state.js → validation/validate-blazor-state.js} +210 -210
- package/src/commands/{validate-blazor.js → validation/validate-blazor.js} +156 -156
- package/src/commands/{validate-css.js → validation/validate-css.js} +84 -84
- package/src/core/index.js +10 -0
- package/src/core/registry/command-registry.js +302 -0
- package/src/core/registry/index.js +8 -0
- package/src/core/registry/validator-registry.js +204 -0
- package/src/core/state/index.js +8 -0
- package/src/core/state/phase-state-machine.js +214 -0
- package/src/{lib → core/state}/state-manager.js +572 -414
- package/src/core/templates/index.js +9 -0
- package/src/core/templates/template-data-sources.js +325 -0
- package/src/core/templates/template-registry.js +335 -0
- package/src/core/templates/template-renderer.js +477 -0
- package/src/core/templates/template-validator.js +296 -0
- package/src/core/workflows/index.js +7 -0
- package/src/core/workflows/workflow-detector.js +354 -0
- package/src/generator/config-generator.js +206 -0
- package/src/generator/templates/config.json.template +40 -0
- package/src/generator/templates/project.md.template +67 -0
- package/src/lib/{complexity-analyzer.js → analysis/complexity-analyzer.js} +441 -441
- package/src/lib/analysis/index.js +7 -0
- package/src/lib/checkpoints/checkpoint-hooks.js +258 -0
- package/src/lib/checkpoints/index.js +7 -0
- package/src/lib/detectors/config-detector.js +223 -223
- package/src/lib/detectors/conversation-analyzer.js +163 -163
- package/src/lib/{design-system-detector.js → detectors/design-system-detector.js} +187 -187
- package/src/lib/detectors/index.js +87 -84
- package/src/lib/detectors/standards-generator.js +275 -275
- package/src/lib/detectors/structure-detector.js +245 -245
- package/src/lib/{context-generator.js → generators/context-generator.js} +526 -516
- package/src/lib/generators/index.js +10 -0
- package/src/lib/generators/metadata-extractor.js +387 -0
- package/src/lib/{recap-generator.js → generators/recap-generator.js} +205 -205
- package/src/lib/learning/index.js +7 -0
- package/src/lib/orchestration/index.js +7 -0
- package/src/lib/{team-orchestrator.js → orchestration/team-orchestrator.js} +323 -323
- package/src/lib/stacks/index.js +7 -0
- package/src/lib/{stack-resolver.js → stacks/stack-resolver.js} +180 -148
- package/src/lib/standards/index.js +7 -0
- package/src/lib/{standards-context-injector.js → standards/standards-context-injector.js} +298 -288
- package/src/lib/troubleshooting/index.js +8 -0
- package/src/lib/{troubleshoot-grep.js → troubleshooting/troubleshoot-grep.js} +204 -204
- package/src/lib/{troubleshoot-index.js → troubleshooting/troubleshoot-index.js} +144 -144
- package/src/lib/validators/architecture/architecture-validator.js +387 -0
- package/src/lib/validators/architecture/index.js +7 -0
- package/src/lib/validators/architecture-validator.js +40 -367
- package/src/lib/{blazor-concurrency-analyzer.js → validators/blazor/blazor-concurrency-analyzer.js} +277 -288
- package/src/lib/{blazor-state-validator.js → validators/blazor/blazor-state-validator.js} +279 -291
- package/src/lib/{blazor-validator.js → validators/blazor/blazor-validator.js} +369 -374
- package/src/lib/validators/blazor/index.js +9 -0
- package/src/lib/validators/content/content-validator.js +351 -0
- package/src/lib/validators/content/index.js +7 -0
- package/src/lib/validators/content-validator.js +164 -0
- package/src/lib/validators/{contract-compliance-validator.js → contracts/contract-compliance-validator.js} +273 -273
- package/src/lib/validators/contracts/index.js +7 -0
- package/src/lib/{css-validator.js → validators/css/css-validator.js} +352 -352
- package/src/lib/validators/css/index.js +7 -0
- package/src/lib/validators/{design-system-validator.js → design-system/design-system-validator.js} +231 -231
- package/src/lib/validators/design-system/index.js +7 -0
- package/src/lib/validators/package-validator.js +41 -340
- package/src/lib/validators/packages/index.js +7 -0
- package/src/lib/validators/packages/package-validator.js +360 -0
- package/src/lib/validators/shared/index.js +12 -0
- package/src/lib/validators/shared/issue-counter.js +18 -0
- package/src/lib/validators/shared/result-formatter.js +124 -0
- package/src/lib/{spec-validator.js → validators/spec-validator.js} +258 -258
- package/src/lib/validators/ui/index.js +7 -0
- package/src/lib/validators/ui/ui-contrast-validator.js +422 -0
- package/src/lib/validators/ui-contrast-validator.js +31 -409
- package/src/lib/{validation-runner.js → validators/validation-runner.js} +286 -284
- package/src/llm/analyzer.js +215 -0
- package/src/llm/environment-detector.js +43 -0
- package/src/llm/few-shot-examples.js +216 -0
- package/src/llm/project-config-schema.json +188 -0
- package/src/llm/prompt-builder.js +96 -0
- package/src/orchestrator.js +206 -0
- package/src/sanitizer/context-sanitizer.js +221 -0
- package/src/sanitizer/patterns.js +163 -0
- package/src/scanner/project-scanner.js +242 -0
- package/src/ui/diff-display.js +91 -0
- package/src/ui/interactive-wizard.js +96 -0
- package/src/ui/user-review.js +211 -0
- package/src/ui/wizard-questions.js +188 -0
- package/src/utils/color-utils.js +70 -0
- package/src/utils/file-copier.js +188 -189
- package/src/utils/process-handler.js +97 -0
- package/src/writer/file-writer.js +86 -0
- package/stacks/blazor-azure/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +3 -3
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/api-designer.md +59 -0
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/dotnet-senior.md +45 -255
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ef-modeler.md +33 -88
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ms-agent-expert.md +25 -89
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/hangfire-orchestrator.md +64 -0
- package/stacks/blazor-azure/.morph/config/agents.json +879 -764
- package/stacks/blazor-azure/.morph/hooks/{pre-commit-tests.sh → pre-commit/tests-csharp.sh} +3 -2
- package/stacks/blazor-azure/.morph/templates/.gitkeep +0 -0
- package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/cd-prod.yml.hbs +41 -0
- package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/cd-staging.yml.hbs +24 -0
- package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/ci-build.yml.hbs +23 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-apply.md +221 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-archive.md +79 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-deploy.md +529 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-infra.md +209 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-preflight.md +227 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-proposal.md +122 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-status.md +86 -0
- package/stacks/nextjs-supabase/.claude/commands/morph-troubleshoot.md +122 -0
- package/stacks/nextjs-supabase/.claude/settings.local.json +6 -0
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +30 -150
- package/stacks/nextjs-supabase/.morph/config/agents.json +345 -345
- package/stacks/nextjs-supabase/.morph/hooks/pre-commit/tests-typescript.sh +61 -0
- package/stacks/nextjs-supabase/.morph/templates/.gitkeep +0 -0
- package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/cd-prod.yml.hbs +22 -0
- package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/cd-staging.yml.hbs +22 -0
- package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/ci-build.yml.hbs +35 -0
- package/stacks/nextjs-supabase/README.md +6 -15
- package/bin/render-template.js +0 -303
- package/bin/semantic-detect-agents.js +0 -247
- package/bin/validate-agents-skills.js +0 -257
- package/bin/validate-agents.js +0 -70
- package/bin/validate-phase.js +0 -263
- package/docs/examples.md +0 -328
- package/scripts/reorganize-skills.cjs +0 -175
- package/scripts/validate-agents-structure.cjs +0 -52
- package/scripts/validate-skills.cjs +0 -180
- package/src/commands/deploy.js +0 -780
- package/src/lib/continuous-validator.js +0 -421
- package/src/lib/decision-constraint-loader.js +0 -109
- package/src/lib/design-system-scaffolder.js +0 -299
- package/src/lib/hook-executor.js +0 -257
- package/src/lib/mockup-generator.js +0 -366
- package/src/lib/ui-detector.js +0 -350
- package/stacks/blazor-azure/.azure/README.md +0 -293
- package/stacks/blazor-azure/.azure/docs/azure-devops-setup.md +0 -454
- package/stacks/blazor-azure/.azure/docs/branch-strategy.md +0 -398
- package/stacks/blazor-azure/.azure/docs/local-development.md +0 -515
- package/stacks/blazor-azure/.azure/pipelines/pipeline-variables.yml +0 -34
- package/stacks/blazor-azure/.azure/pipelines/prod-pipeline.yml +0 -319
- package/stacks/blazor-azure/.azure/pipelines/staging-pipeline.yml +0 -234
- package/stacks/blazor-azure/.azure/pipelines/templates/build-dotnet.yml +0 -75
- package/stacks/blazor-azure/.azure/pipelines/templates/deploy-app-service.yml +0 -94
- package/stacks/blazor-azure/.azure/pipelines/templates/deploy-container-app.yml +0 -120
- package/stacks/blazor-azure/.azure/pipelines/templates/infra-deploy.yml +0 -90
- package/stacks/blazor-azure/.claude/settings.local.json +0 -15
- package/stacks/blazor-azure/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +0 -392
- package/stacks/blazor-azure/.morph/docs/workflows/design-impl.md +0 -37
- package/stacks/blazor-azure/.morph/docs/workflows/enforcement-pipeline.md +0 -668
- package/stacks/blazor-azure/.morph/docs/workflows/fast-track.md +0 -29
- package/stacks/blazor-azure/.morph/docs/workflows/full-morph.md +0 -76
- package/stacks/blazor-azure/.morph/docs/workflows/standard.md +0 -44
- package/stacks/blazor-azure/.morph/docs/workflows/ui-refresh.md +0 -39
- package/stacks/blazor-azure/.morph/examples/api-nextjs/README.md +0 -241
- package/stacks/blazor-azure/.morph/examples/api-nextjs/contracts.ts +0 -307
- package/stacks/blazor-azure/.morph/examples/api-nextjs/spec.md +0 -399
- package/stacks/blazor-azure/.morph/examples/api-nextjs/tasks.md +0 -168
- package/stacks/blazor-azure/.morph/examples/micro-saas/README.md +0 -125
- package/stacks/blazor-azure/.morph/examples/micro-saas/contracts.cs +0 -358
- package/stacks/blazor-azure/.morph/examples/micro-saas/decisions.md +0 -246
- package/stacks/blazor-azure/.morph/examples/micro-saas/spec.md +0 -236
- package/stacks/blazor-azure/.morph/examples/micro-saas/tasks.md +0 -150
- package/stacks/blazor-azure/.morph/examples/multi-agent/README.md +0 -309
- package/stacks/blazor-azure/.morph/examples/multi-agent/contracts.cs +0 -433
- package/stacks/blazor-azure/.morph/examples/multi-agent/spec.md +0 -479
- package/stacks/blazor-azure/.morph/examples/multi-agent/tasks.md +0 -185
- package/stacks/blazor-azure/.morph/examples/scheduled-reports/decisions.md +0 -158
- package/stacks/blazor-azure/.morph/examples/scheduled-reports/proposal.md +0 -95
- package/stacks/blazor-azure/.morph/examples/scheduled-reports/spec.md +0 -267
- package/stacks/blazor-azure/.morph/examples/state-v3.json +0 -188
- package/stacks/blazor-azure/.morph/hooks/README.md +0 -348
- package/stacks/blazor-azure/.morph/hooks/pre-commit-agents.sh +0 -24
- package/stacks/blazor-azure/.morph/hooks/pre-commit-all.sh +0 -48
- package/stacks/blazor-azure/.morph/hooks/pre-commit-specs.sh +0 -49
- package/stacks/blazor-azure/.morph/hooks/task-completed.js +0 -73
- package/stacks/blazor-azure/.morph/hooks/teammate-idle.js +0 -68
- package/stacks/blazor-azure/.morph/standards/agent-framework-blazor-ui.md +0 -359
- package/stacks/blazor-azure/.morph/standards/agent-framework-production.md +0 -410
- package/stacks/blazor-azure/.morph/standards/agent-framework-setup.md +0 -413
- package/stacks/blazor-azure/.morph/standards/agent-framework-workflows.md +0 -349
- package/stacks/blazor-azure/.morph/standards/agent-teams-workflow.md +0 -474
- package/stacks/blazor-azure/.morph/standards/architecture.md +0 -325
- package/stacks/blazor-azure/.morph/standards/azure.md +0 -605
- package/stacks/blazor-azure/.morph/standards/coding.md +0 -377
- package/stacks/blazor-azure/.morph/standards/dotnet10-migration.md +0 -520
- package/stacks/blazor-azure/.morph/standards/fluent-ui-setup.md +0 -590
- package/stacks/blazor-azure/.morph/standards/migration-guide.md +0 -514
- package/stacks/blazor-azure/.morph/standards/passkeys-auth.md +0 -423
- package/stacks/blazor-azure/.morph/standards/vector-search-rag.md +0 -536
- package/stacks/blazor-azure/.morph/templates/CONTEXT-FEATURE.md +0 -276
- package/stacks/blazor-azure/.morph/templates/CONTEXT.md +0 -170
- package/stacks/blazor-azure/.morph/templates/FluentDesignTheme.cs +0 -149
- package/stacks/blazor-azure/.morph/templates/MudTheme.cs +0 -281
- package/stacks/blazor-azure/.morph/templates/agent.cs +0 -163
- package/stacks/blazor-azure/.morph/templates/clarify-questions.md +0 -159
- package/stacks/blazor-azure/.morph/templates/component.razor +0 -239
- package/stacks/blazor-azure/.morph/templates/contracts/Commands.cs +0 -74
- package/stacks/blazor-azure/.morph/templates/contracts/Entities.cs +0 -25
- package/stacks/blazor-azure/.morph/templates/contracts/Queries.cs +0 -74
- package/stacks/blazor-azure/.morph/templates/contracts/README.md +0 -74
- package/stacks/blazor-azure/.morph/templates/contracts.cs +0 -217
- package/stacks/blazor-azure/.morph/templates/decisions.md +0 -123
- package/stacks/blazor-azure/.morph/templates/design-system.css +0 -226
- package/stacks/blazor-azure/.morph/templates/infra/.dockerignore.example +0 -89
- package/stacks/blazor-azure/.morph/templates/infra/Dockerfile.example +0 -82
- package/stacks/blazor-azure/.morph/templates/infra/README.md +0 -286
- package/stacks/blazor-azure/.morph/templates/infra/app-insights.bicep +0 -63
- package/stacks/blazor-azure/.morph/templates/infra/app-service.bicep +0 -164
- package/stacks/blazor-azure/.morph/templates/infra/azure-pipelines-deploy.yml +0 -480
- package/stacks/blazor-azure/.morph/templates/infra/container-app-env.bicep +0 -49
- package/stacks/blazor-azure/.morph/templates/infra/container-app.bicep +0 -156
- package/stacks/blazor-azure/.morph/templates/infra/deploy-checklist.md +0 -426
- package/stacks/blazor-azure/.morph/templates/infra/deploy.ps1 +0 -229
- package/stacks/blazor-azure/.morph/templates/infra/deploy.sh +0 -208
- package/stacks/blazor-azure/.morph/templates/infra/key-vault.bicep +0 -91
- package/stacks/blazor-azure/.morph/templates/infra/main.bicep +0 -189
- package/stacks/blazor-azure/.morph/templates/infra/parameters.dev.json +0 -29
- package/stacks/blazor-azure/.morph/templates/infra/parameters.prod.json +0 -29
- package/stacks/blazor-azure/.morph/templates/infra/parameters.staging.json +0 -29
- package/stacks/blazor-azure/.morph/templates/infra/sql-database.bicep +0 -103
- package/stacks/blazor-azure/.morph/templates/infra/storage.bicep +0 -106
- package/stacks/blazor-azure/.morph/templates/integrations/asaas-client.cs +0 -387
- package/stacks/blazor-azure/.morph/templates/integrations/asaas-webhook.cs +0 -351
- package/stacks/blazor-azure/.morph/templates/integrations/azure-identity-config.cs +0 -288
- package/stacks/blazor-azure/.morph/templates/integrations/clerk-config.cs +0 -258
- package/stacks/blazor-azure/.morph/templates/job.cs +0 -171
- package/stacks/blazor-azure/.morph/templates/migration.cs +0 -83
- package/stacks/blazor-azure/.morph/templates/proposal.md +0 -141
- package/stacks/blazor-azure/.morph/templates/recap.md +0 -94
- package/stacks/blazor-azure/.morph/templates/repository.cs +0 -141
- package/stacks/blazor-azure/.morph/templates/saas/subscription.cs +0 -347
- package/stacks/blazor-azure/.morph/templates/saas/tenant.cs +0 -338
- package/stacks/blazor-azure/.morph/templates/service.cs +0 -139
- package/stacks/blazor-azure/.morph/templates/simulation.md +0 -353
- package/stacks/blazor-azure/.morph/templates/spec.md +0 -149
- package/stacks/blazor-azure/.morph/templates/sprint-status.yaml +0 -68
- package/stacks/blazor-azure/.morph/templates/state.template.json +0 -222
- package/stacks/blazor-azure/.morph/templates/story.md +0 -143
- package/stacks/blazor-azure/.morph/templates/tasks.md +0 -257
- package/stacks/blazor-azure/.morph/templates/test.cs +0 -239
- package/stacks/blazor-azure/.morph/templates/ui-components.md +0 -362
- package/stacks/blazor-azure/.morph/templates/ui-design-system.md +0 -286
- package/stacks/blazor-azure/.morph/templates/ui-flows.md +0 -336
- package/stacks/blazor-azure/.morph/templates/ui-mockups.md +0 -133
- package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +0 -169
- package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +0 -247
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +0 -697
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +0 -85
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +0 -86
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +0 -498
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +0 -121
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +0 -138
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +0 -162
- package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +0 -191
- package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +0 -193
- package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +0 -171
- package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +0 -164
- package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +0 -179
- package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +0 -148
- package/stacks/nextjs-supabase/.morph/templates/contracts.cs +0 -173
- package/stacks/nextjs-supabase/.morph/templates/contracts.ts +0 -168
- package/stacks/nextjs-supabase/.morph/templates/decisions.md +0 -115
- package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +0 -38
- package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +0 -48
- package/stacks/nextjs-supabase/.morph/templates/proposal.md +0 -145
- package/stacks/nextjs-supabase/.morph/templates/recap.md +0 -134
- package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +0 -57
- package/stacks/nextjs-supabase/.morph/templates/spec.md +0 -231
- package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +0 -100
- package/stacks/nextjs-supabase/.morph/templates/tasks.md +0 -257
- /package/src/lib/{design-system-generator.js → generators/design-system-generator.js} +0 -0
- /package/src/lib/{learning-system.js → learning/learning-system.js} +0 -0
|
@@ -1,266 +1,416 @@
|
|
|
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 '
|
|
14
|
-
import { PHASES, validatePhase } from './validate-phase.js';
|
|
15
|
-
import { detectDesignSystem, hasUIAgentsActive } from '
|
|
16
|
-
import { validateSpec } from '
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
//
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
console.log('');
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
`
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
'
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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, getApprovalGate } from '../../core/state/state-manager.js';
|
|
14
|
+
import { PHASES, validatePhase } from './validate-phase.js';
|
|
15
|
+
import { detectDesignSystem, hasUIAgentsActive } from '../../lib/detectors/design-system-detector.js';
|
|
16
|
+
import { validateSpec } from '../../lib/validators/spec-validator.js';
|
|
17
|
+
import { validateTransition, getPhaseDisplayName } from '../../core/state/phase-state-machine.js';
|
|
18
|
+
import { validateSpecContent, validateTasksContent, validateFeatureOutputs } from '../../lib/validators/content-validator.js';
|
|
19
|
+
import { getWorkflowConfig } from '../../core/workflows/workflow-detector.js';
|
|
20
|
+
import { readFileSync, existsSync } from 'fs';
|
|
21
|
+
import { join, dirname } from 'path';
|
|
22
|
+
import { fileURLToPath } from 'url';
|
|
23
|
+
|
|
24
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
25
|
+
|
|
26
|
+
// Phase order for advancing (skips optional phases unless active)
|
|
27
|
+
const PHASE_ORDER = ['proposal', 'setup', 'uiux', 'design', 'clarify', 'tasks', 'implement', 'sync'];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get the next phase after the current one
|
|
31
|
+
*/
|
|
32
|
+
function getNextPhase(currentPhase, feature, skipOptional) {
|
|
33
|
+
// Load workflow config if workflow is set
|
|
34
|
+
let workflowConfig = null;
|
|
35
|
+
if (feature.workflow && feature.workflow !== 'auto') {
|
|
36
|
+
workflowConfig = getWorkflowConfig(feature.workflow);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const currentIndex = PHASE_ORDER.indexOf(currentPhase);
|
|
40
|
+
if (currentIndex === -1 || currentIndex >= PHASE_ORDER.length - 1) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (let i = currentIndex + 1; i < PHASE_ORDER.length; i++) {
|
|
45
|
+
const candidate = PHASE_ORDER[i];
|
|
46
|
+
const phaseDef = PHASES[candidate];
|
|
47
|
+
|
|
48
|
+
// === Workflow-Based Phase Skipping ===
|
|
49
|
+
if (workflowConfig && workflowConfig.phases) {
|
|
50
|
+
// Check if workflow explicitly skips this phase
|
|
51
|
+
if (workflowConfig.phases.skip && workflowConfig.phases.skip.includes(candidate)) {
|
|
52
|
+
console.log(chalk.gray(` ⏩ Skipping ${candidate}: workflow ${feature.workflow} skips this phase`));
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Check if this phase is part of a combined phase
|
|
57
|
+
if (workflowConfig.phases.combined) {
|
|
58
|
+
for (const [combinedName, phases] of Object.entries(workflowConfig.phases.combined)) {
|
|
59
|
+
if (phases.includes(candidate) && candidate !== combinedName) {
|
|
60
|
+
console.log(chalk.gray(` ⏩ Skipping ${candidate}: combined into ${combinedName} phase`));
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Check if workflow only runs specific phases
|
|
67
|
+
if (workflowConfig.phases.run && !workflowConfig.phases.run.includes(candidate)) {
|
|
68
|
+
// Also check if it's not a combined phase
|
|
69
|
+
const isCombinedPhase = workflowConfig.phases.combined &&
|
|
70
|
+
Object.keys(workflowConfig.phases.combined).includes(candidate);
|
|
71
|
+
if (!isCombinedPhase) {
|
|
72
|
+
console.log(chalk.gray(` ⏩ Skipping ${candidate}: not in workflow run list`));
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Check conditional skips
|
|
78
|
+
if (workflowConfig.phases.skipIfCondition) {
|
|
79
|
+
const condition = workflowConfig.phases.skipIfCondition[candidate];
|
|
80
|
+
if (condition) {
|
|
81
|
+
// Evaluate condition (simple conditions for now)
|
|
82
|
+
if (condition === '!hasUIAgents' && !hasUIAgentsActive(feature)) {
|
|
83
|
+
console.log(chalk.gray(` ⏩ Skipping ${candidate}: no UI agents active`));
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// === Legacy Phase Skipping (fallback when no workflow config) ===
|
|
91
|
+
if (!workflowConfig) {
|
|
92
|
+
// Skip optional phases if flag set or no relevant agents/outputs
|
|
93
|
+
if (phaseDef?.optional && skipOptional) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Skip uiux if no UI agents are active
|
|
98
|
+
if (candidate === 'uiux') {
|
|
99
|
+
const uiAgents = ['blazor-builder', 'uiux-designer', 'nextjs-expert', 'ui-ux-designer'];
|
|
100
|
+
const hasUiAgent = feature.activeAgents?.some(a => uiAgents.includes(a));
|
|
101
|
+
if (!hasUiAgent && skipOptional !== false) {
|
|
102
|
+
console.log(chalk.gray(` ⏩ Skipping ${candidate}: no UI agents active`));
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Skip sync for simple workflows
|
|
108
|
+
if (candidate === 'sync') {
|
|
109
|
+
const isSimple = feature.workflow === 'fast-track';
|
|
110
|
+
if (isSimple && skipOptional !== false) {
|
|
111
|
+
console.log(chalk.gray(` ⏩ Skipping ${candidate}: fast-track workflow`));
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return candidate;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Main command handler
|
|
125
|
+
*/
|
|
126
|
+
export async function advancePhaseCommand(feature, options = {}) {
|
|
127
|
+
console.log(chalk.cyan('\n╔════════════════════════════════════════════════╗'));
|
|
128
|
+
console.log(chalk.cyan('║ MORPH-SPEC PHASE ADVANCE ║'));
|
|
129
|
+
console.log(chalk.cyan('╚════════════════════════════════════════════════╝\n'));
|
|
130
|
+
|
|
131
|
+
// Get current feature state
|
|
132
|
+
const featureData = getFeature(feature);
|
|
133
|
+
if (!featureData) {
|
|
134
|
+
console.log(chalk.red(`✗ Feature not found: ${feature}`));
|
|
135
|
+
console.log(chalk.yellow(` Run: morph-spec state set ${feature} phase proposal`));
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const currentPhase = featureData.phase;
|
|
140
|
+
const currentPhaseDef = PHASES[currentPhase];
|
|
141
|
+
|
|
142
|
+
console.log(chalk.gray('Feature:'), feature);
|
|
143
|
+
console.log(chalk.gray('Current Phase:'), currentPhaseDef?.name || currentPhase);
|
|
144
|
+
console.log(chalk.gray('Workflow:'), featureData.workflow || 'auto');
|
|
145
|
+
|
|
146
|
+
// Determine next phase
|
|
147
|
+
const nextPhase = getNextPhase(currentPhase, featureData, options.skipOptional);
|
|
148
|
+
|
|
149
|
+
if (!nextPhase) {
|
|
150
|
+
console.log(chalk.green('\n✓ Feature is at the final phase!'));
|
|
151
|
+
if (currentPhase === 'implement' || currentPhase === 'sync') {
|
|
152
|
+
console.log(chalk.green(' Consider running: morph-spec generate recap ' + feature));
|
|
153
|
+
}
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const nextPhaseDef = PHASES[nextPhase];
|
|
158
|
+
console.log(chalk.gray('Next Phase:'), nextPhaseDef.name);
|
|
159
|
+
|
|
160
|
+
// === GATE 1: State Machine Validation ===
|
|
161
|
+
// Ensure phase transition is valid (no skipping required phases)
|
|
162
|
+
if (!options.force) {
|
|
163
|
+
try {
|
|
164
|
+
validateTransition(currentPhase, nextPhase);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.log(chalk.red('\n✗ Invalid phase transition'));
|
|
167
|
+
console.log(chalk.yellow(error.message));
|
|
168
|
+
console.log(chalk.gray('\nUse --force to override (not recommended)\n'));
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// === GATE 2: Approval Gate Check ===
|
|
174
|
+
// Check if current phase requires approval before advancing
|
|
175
|
+
const approvalGateMap = {
|
|
176
|
+
'design': 'design',
|
|
177
|
+
'tasks': 'tasks',
|
|
178
|
+
'uiux': 'uiux'
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const requiredGate = approvalGateMap[currentPhase];
|
|
182
|
+
if (requiredGate && !options.skipApproval) {
|
|
183
|
+
const gateStatus = getApprovalGate(feature, requiredGate);
|
|
184
|
+
|
|
185
|
+
if (!gateStatus || !gateStatus.approved) {
|
|
186
|
+
console.log(chalk.red(`\n✗ Phase "${currentPhase}" requires approval before advancing`));
|
|
187
|
+
console.log(chalk.yellow(`\nRun: morph-spec approve ${feature} ${requiredGate}`));
|
|
188
|
+
console.log(chalk.gray('Or use --skip-approval to bypass (not recommended)\n'));
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
console.log(chalk.green(`✓ Approval gate "${requiredGate}" passed`));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// === GATE 3: Output Requirements ===
|
|
196
|
+
// Validate that current phase requirements are met before advancing
|
|
197
|
+
const validation = validatePhase(feature, nextPhase);
|
|
198
|
+
|
|
199
|
+
if (!validation.valid) {
|
|
200
|
+
console.log(chalk.red('\n✗ Cannot advance — missing requirements:'));
|
|
201
|
+
validation.missingOutputs.forEach(output => {
|
|
202
|
+
console.log(chalk.red(` - ${output}`));
|
|
203
|
+
});
|
|
204
|
+
console.log(chalk.yellow(`\n Complete these before advancing to ${nextPhaseDef.name}`));
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (validation.stateWarning) {
|
|
209
|
+
console.log(chalk.yellow(`\n⚠️ ${validation.stateWarning}`));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// === GATE 4: Content Validation ===
|
|
213
|
+
// Validate spec.md and contracts.cs when advancing from design phase
|
|
214
|
+
if (currentPhase === 'design' && (nextPhase === 'clarify' || nextPhase === 'tasks')) {
|
|
215
|
+
// Check spec.md structure and content
|
|
216
|
+
if (featureData.outputs?.spec?.created) {
|
|
217
|
+
const specContentValidation = validateSpecContent(featureData.outputs.spec.path);
|
|
218
|
+
|
|
219
|
+
if (!specContentValidation.valid) {
|
|
220
|
+
console.log(chalk.red('\n✗ Spec content validation failed:'));
|
|
221
|
+
specContentValidation.missing.forEach(section => {
|
|
222
|
+
console.log(chalk.red(` - Missing section: ${section}`));
|
|
223
|
+
});
|
|
224
|
+
specContentValidation.errors.forEach(error => {
|
|
225
|
+
console.log(chalk.red(` - ${error}`));
|
|
226
|
+
});
|
|
227
|
+
console.log('');
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (specContentValidation.warnings?.length > 0 && !options.skipWarnings) {
|
|
232
|
+
console.log(chalk.yellow('\n⚠️ Spec content warnings:'));
|
|
233
|
+
specContentValidation.warnings.forEach(warning => {
|
|
234
|
+
console.log(chalk.yellow(` - ${warning}`));
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Run existing spec validator (anti-patterns, IaC checks)
|
|
240
|
+
const specValidation = await validateSpec('.', feature);
|
|
241
|
+
|
|
242
|
+
if (specValidation.errors > 0) {
|
|
243
|
+
console.log(chalk.red('\n✗ Spec validation failed — fix errors before advancing:'));
|
|
244
|
+
specValidation.issues.filter(i => i.level === 'error').forEach(issue => {
|
|
245
|
+
console.log(chalk.red(` - ${issue.message}`));
|
|
246
|
+
console.log(chalk.yellow(` → ${issue.solution}`));
|
|
247
|
+
});
|
|
248
|
+
console.log('');
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (specValidation.warnings > 0 && !options.skipWarnings) {
|
|
253
|
+
console.log(chalk.yellow('\n⚠️ Spec validation warnings:'));
|
|
254
|
+
specValidation.issues.filter(i => i.level === 'warning').forEach(issue => {
|
|
255
|
+
console.log(chalk.yellow(` - ${issue.message}`));
|
|
256
|
+
});
|
|
257
|
+
console.log(chalk.gray('\n (Use --skip-warnings to ignore warnings)\n'));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// === GATE 5: Tasks Content Validation ===
|
|
262
|
+
// Validate tasks.json structure when advancing to implement
|
|
263
|
+
if (currentPhase === 'tasks' && nextPhase === 'implement') {
|
|
264
|
+
if (featureData.outputs?.tasks?.created) {
|
|
265
|
+
const tasksContentValidation = validateTasksContent(featureData.outputs.tasks.path);
|
|
266
|
+
|
|
267
|
+
if (!tasksContentValidation.valid) {
|
|
268
|
+
console.log(chalk.red('\n✗ Tasks content validation failed:'));
|
|
269
|
+
tasksContentValidation.errors.forEach(error => {
|
|
270
|
+
console.log(chalk.red(` - ${error}`));
|
|
271
|
+
});
|
|
272
|
+
console.log('');
|
|
273
|
+
process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (tasksContentValidation.warnings?.length > 0 && !options.skipWarnings) {
|
|
277
|
+
console.log(chalk.yellow('\n⚠️ Tasks content warnings:'));
|
|
278
|
+
tasksContentValidation.warnings.forEach(warning => {
|
|
279
|
+
console.log(chalk.yellow(` - ${warning}`));
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Show tasks stats
|
|
284
|
+
console.log(chalk.green(`\n✓ Tasks validated: ${tasksContentValidation.stats.totalTasks} total (${tasksContentValidation.stats.regularTasks} tasks + ${tasksContentValidation.stats.checkpoints} checkpoints)`));
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Gate: Check design system when advancing to implement with UI agents
|
|
289
|
+
if (nextPhase === 'implement') {
|
|
290
|
+
const gateResult = designSystemGate(feature);
|
|
291
|
+
|
|
292
|
+
if (gateResult.blocked) {
|
|
293
|
+
console.log(chalk.red(`\n✗ ${gateResult.message}`));
|
|
294
|
+
console.log('');
|
|
295
|
+
gateResult.solution.forEach(line => {
|
|
296
|
+
if (line === '') {
|
|
297
|
+
console.log('');
|
|
298
|
+
} else {
|
|
299
|
+
console.log(chalk.yellow(` ${line}`));
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
console.log('');
|
|
303
|
+
process.exit(1);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Advance the phase
|
|
308
|
+
const state = loadState();
|
|
309
|
+
state.features[feature].phase = nextPhase;
|
|
310
|
+
state.features[feature].updatedAt = new Date().toISOString();
|
|
311
|
+
saveState(state);
|
|
312
|
+
|
|
313
|
+
console.log(chalk.green(`\n✓ Advanced to ${nextPhaseDef.name}`));
|
|
314
|
+
|
|
315
|
+
// Show what's needed in the new phase
|
|
316
|
+
console.log(chalk.cyan('\n📋 Phase requirements:'));
|
|
317
|
+
console.log(chalk.gray(` ${nextPhaseDef.description}`));
|
|
318
|
+
|
|
319
|
+
if (nextPhaseDef.requiredOutputs?.length > 0) {
|
|
320
|
+
console.log(chalk.cyan('\n Required outputs:'));
|
|
321
|
+
nextPhaseDef.requiredOutputs.forEach(output => {
|
|
322
|
+
const exists = validation.phase ? true : false; // Already validated
|
|
323
|
+
console.log(chalk.gray(` ✓ ${output} (exists)`));
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Show phase-specific guidance
|
|
328
|
+
const guidance = getPhaseGuidance(nextPhase, feature);
|
|
329
|
+
if (guidance) {
|
|
330
|
+
console.log(chalk.cyan('\n Next steps:'));
|
|
331
|
+
guidance.forEach(step => console.log(chalk.white(` → ${step}`)));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
console.log('');
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Get guidance for what to do in a phase
|
|
339
|
+
*/
|
|
340
|
+
function getPhaseGuidance(phase, feature) {
|
|
341
|
+
const guides = {
|
|
342
|
+
'setup': [
|
|
343
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
344
|
+
'Auto-continues from setup phase'
|
|
345
|
+
],
|
|
346
|
+
'uiux': [
|
|
347
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
348
|
+
'Provide layout references and preferences',
|
|
349
|
+
'Review wireframes before proceeding'
|
|
350
|
+
],
|
|
351
|
+
'design': [
|
|
352
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
353
|
+
'Review DECISION POINTS carefully',
|
|
354
|
+
'Approve spec.md and contracts.cs'
|
|
355
|
+
],
|
|
356
|
+
'clarify': [
|
|
357
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
358
|
+
'Resolve edge cases and unknowns'
|
|
359
|
+
],
|
|
360
|
+
'tasks': [
|
|
361
|
+
`Resume spec pipeline: /morph-proposal ${feature}`,
|
|
362
|
+
'Review task order and dependencies',
|
|
363
|
+
'Approve task list before implementing'
|
|
364
|
+
],
|
|
365
|
+
'implement': [
|
|
366
|
+
`Start implementing: /morph-apply ${feature}`,
|
|
367
|
+
'Complete tasks one by one with: morph-spec task done',
|
|
368
|
+
'Validators run automatically on task completion'
|
|
369
|
+
],
|
|
370
|
+
'sync': [
|
|
371
|
+
'Review decisions.md for standards to promote',
|
|
372
|
+
`Sync: morph-spec sync --path .morph/project/outputs/${feature}/decisions.md`
|
|
373
|
+
]
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
return guides[phase] || null;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Gate: Check design system exists when advancing to implement with UI agents
|
|
381
|
+
* @param {string} feature - Feature name
|
|
382
|
+
* @param {string} projectPath - Project root path
|
|
383
|
+
* @returns {Object} { blocked: boolean, message?: string, solution?: string[] }
|
|
384
|
+
*/
|
|
385
|
+
function designSystemGate(feature, projectPath = '.') {
|
|
386
|
+
// Check if UI agents are active
|
|
387
|
+
const hasUIAgents = hasUIAgentsActive(projectPath, feature);
|
|
388
|
+
|
|
389
|
+
if (!hasUIAgents) {
|
|
390
|
+
return { blocked: false }; // No UI agents, gate doesn't apply
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Check if design system exists
|
|
394
|
+
const dsDetection = detectDesignSystem(projectPath, feature);
|
|
395
|
+
|
|
396
|
+
if (dsDetection.hasDesignSystem) {
|
|
397
|
+
return { blocked: false }; // Design system exists, gate passed
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Block advancement - no design system found with UI agents active
|
|
401
|
+
return {
|
|
402
|
+
blocked: true,
|
|
403
|
+
message: 'Cannot advance to implementation — UI agents are active but no design system found',
|
|
404
|
+
solution: [
|
|
405
|
+
'Design system is required when UI agents (blazor-builder, ui-designer, css-specialist) are active',
|
|
406
|
+
'',
|
|
407
|
+
'Create a design system with one of these options:',
|
|
408
|
+
' 1. Project-level: .morph/project/design-system.md (shared across features)',
|
|
409
|
+
` 2. Feature-level: .morph/project/outputs/${feature}/ui-design-system.md (feature-specific)`,
|
|
410
|
+
' 3. Auto-generate: morph-spec generate design-system (scans existing CSS)',
|
|
411
|
+
'',
|
|
412
|
+
'Or remove UI agents if they are not needed:',
|
|
413
|
+
` morph-spec state remove-agent ${feature} blazor-builder`
|
|
414
|
+
]
|
|
415
|
+
};
|
|
416
|
+
}
|