@polymorphism-tech/morph-spec 3.0.1 ā 3.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 +561 -63
- package/LICENSE +72 -72
- package/README.md +275 -79
- package/bin/detect-agents.js +3 -1
- package/bin/morph-spec.js +60 -1
- package/bin/render-template.js +61 -14
- package/bin/semantic-detect-agents.js +2 -1
- package/bin/{task-manager.js ā task-manager.cjs} +113 -8
- package/bin/validate-agents-skills.js +10 -4
- package/bin/validate-agents.js +4 -3
- 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/cli-auto-detection.md +219 -0
- package/docs/examples.md +328 -328
- package/docs/getting-started.md +3 -3
- package/docs/llm-interaction-config.md +735 -0
- package/docs/templates.md +418 -418
- package/docs/troubleshooting.md +269 -0
- package/package.json +7 -3
- package/scripts/postinstall.js +132 -132
- package/scripts/reorganize-skills.cjs +1 -1
- package/scripts/validate-agents-structure.cjs +1 -1
- package/scripts/validate-skills.cjs +2 -2
- package/src/commands/advance-phase.js +93 -2
- package/src/commands/analyze-blazor-concurrency.js +193 -193
- package/src/commands/approve.js +221 -0
- package/src/commands/capture-pattern.js +121 -0
- package/src/commands/create-story.js +5 -2
- package/src/commands/deploy.js +780 -780
- package/src/commands/detect-agents.js +4 -2
- package/src/commands/generate.js +276 -149
- package/src/commands/init.js +37 -0
- package/src/commands/lint-fluent.js +352 -352
- package/src/commands/migrate-state.js +158 -0
- package/src/commands/rollback-phase.js +185 -185
- package/src/commands/search-patterns.js +126 -0
- package/src/commands/session-summary.js +291 -291
- package/src/commands/shard-spec.js +224 -224
- package/src/commands/spawn-team.js +172 -0
- package/src/commands/sprint-status.js +250 -250
- package/src/commands/task.js +3 -3
- package/src/commands/troubleshoot.js +222 -222
- package/src/commands/update.js +36 -0
- package/src/commands/upgrade.js +346 -0
- package/src/commands/validate-blazor-state.js +210 -210
- package/src/commands/validate-blazor.js +156 -156
- package/src/commands/validate-css.js +84 -84
- package/src/commands/validate-phase.js +221 -221
- package/src/generator/.gitkeep +0 -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/blazor-concurrency-analyzer.js +288 -288
- package/src/lib/blazor-state-validator.js +291 -291
- package/src/lib/blazor-validator.js +374 -374
- package/src/lib/checkpoint-hooks.js +258 -0
- package/src/lib/context-generator.js +7 -4
- package/src/lib/css-validator.js +352 -352
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/hook-executor.js +2 -1
- package/src/lib/learning-system.js +520 -520
- package/src/lib/metadata-extractor.js +380 -0
- package/src/lib/mockup-generator.js +366 -366
- package/src/lib/phase-state-machine.js +214 -0
- package/src/lib/stack-resolver.js +148 -0
- package/src/lib/standards-context-injector.js +4 -3
- package/src/lib/state-manager.js +120 -0
- package/src/lib/team-orchestrator.js +2 -1
- package/src/lib/template-data-sources.js +325 -0
- package/src/lib/troubleshoot-grep.js +204 -194
- package/src/lib/troubleshoot-index.js +144 -144
- package/src/lib/ui-detector.js +350 -350
- package/src/lib/validation-runner.js +2 -1
- package/src/lib/validators/architecture-validator.js +387 -387
- package/src/lib/validators/content-validator.js +351 -0
- package/src/lib/validators/package-validator.js +360 -360
- package/src/lib/validators/ui-contrast-validator.js +422 -422
- package/src/llm/.gitkeep +0 -0
- 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/llm/schema-validator.js +121 -0
- package/src/orchestrator.js +206 -0
- package/src/sanitizer/.gitkeep +0 -0
- package/src/sanitizer/context-sanitizer.js +221 -0
- package/src/sanitizer/patterns.js +163 -0
- package/src/scanner/.gitkeep +0 -0
- package/src/scanner/project-scanner.js +242 -0
- package/src/types/index.js +477 -0
- package/src/ui/.gitkeep +0 -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 +190 -0
- package/src/utils/file-copier.js +3 -1
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- package/src/writer/.gitkeep +0 -0
- package/src/writer/file-writer.js +86 -0
- package/{content ā stacks/blazor-azure}/.azure/README.md +2 -2
- package/{content ā stacks/blazor-azure}/.azure/pipelines/pipeline-variables.yml +1 -1
- package/{content ā stacks/blazor-azure}/.azure/pipelines/prod-pipeline.yml +1 -1
- package/{content ā stacks/blazor-azure}/.azure/pipelines/staging-pipeline.yml +1 -1
- package/{content ā stacks/blazor-azure}/.claude/commands/morph-preflight.md +227 -227
- package/{content ā stacks/blazor-azure}/.claude/commands/morph-troubleshoot.md +122 -122
- package/{content ā stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-setup.md +1 -1
- package/{content ā stacks/blazor-azure}/.morph/docs/workflows/enforcement-pipeline.md +3 -3
- package/{content ā stacks/blazor-azure}/.morph/hooks/README.md +12 -12
- package/{content ā stacks/blazor-azure}/.morph/standards/agent-teams-workflow.md +2 -2
- package/{content ā stacks/blazor-azure}/.morph/standards/migration-guide.md +2 -2
- package/{content ā stacks/blazor-azure}/.morph/templates/infra/deploy-checklist.md +426 -426
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +244 -0
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +335 -0
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +189 -0
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +170 -0
- package/stacks/nextjs-supabase/.morph/config/agents.json +345 -0
- package/stacks/nextjs-supabase/.morph/config/config.template.json +92 -0
- package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +169 -0
- package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +247 -0
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +697 -0
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +85 -0
- package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +86 -0
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +498 -0
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +121 -0
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +138 -0
- package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +162 -0
- package/stacks/nextjs-supabase/.morph/project.md +168 -0
- package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +191 -0
- package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +193 -0
- package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +171 -0
- package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +164 -0
- package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +179 -0
- package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +148 -0
- package/stacks/nextjs-supabase/.morph/templates/contracts.cs +173 -0
- package/stacks/nextjs-supabase/.morph/templates/contracts.ts +168 -0
- package/stacks/nextjs-supabase/.morph/templates/decisions.md +115 -0
- package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +38 -0
- package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +48 -0
- package/stacks/nextjs-supabase/.morph/templates/proposal.md +145 -0
- package/stacks/nextjs-supabase/.morph/templates/recap.md +134 -0
- package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +57 -0
- package/stacks/nextjs-supabase/.morph/templates/spec.md +231 -0
- package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +100 -0
- package/stacks/nextjs-supabase/.morph/templates/tasks.md +257 -0
- package/stacks/nextjs-supabase/CLAUDE.md +149 -0
- package/stacks/nextjs-supabase/README.md +112 -0
- /package/{content ā stacks/blazor-azure}/.azure/docs/azure-devops-setup.md +0 -0
- /package/{content ā stacks/blazor-azure}/.azure/docs/branch-strategy.md +0 -0
- /package/{content ā stacks/blazor-azure}/.azure/docs/local-development.md +0 -0
- /package/{content ā stacks/blazor-azure}/.azure/pipelines/templates/build-dotnet.yml +0 -0
- /package/{content ā stacks/blazor-azure}/.azure/pipelines/templates/deploy-app-service.yml +0 -0
- /package/{content ā stacks/blazor-azure}/.azure/pipelines/templates/deploy-container-app.yml +0 -0
- /package/{content ā stacks/blazor-azure}/.azure/pipelines/templates/infra-deploy.yml +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/commands/morph-apply.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/commands/morph-archive.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/commands/morph-deploy.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/commands/morph-infra.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/commands/morph-proposal.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/commands/morph-status.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/settings.local.json +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-0-meta/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-0-meta/code-review.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-0-meta/morph-checklist.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-0-meta/simulation-checklist.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-1-workflows/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-1-workflows/morph-replicate.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-clarify.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-design.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-tasks.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-uiux.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/prompt-engineer.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/seo-growth-hacker.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/resend-email.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-3-technologies/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.claude/skills/level-4-patterns/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/.morphversion +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/archive/.gitkeep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/config/agents.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/config/config.template.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/docs/workflows/design-impl.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/docs/workflows/fast-track.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/docs/workflows/full-morph.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/docs/workflows/standard.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/docs/workflows/ui-refresh.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/api-nextjs/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/api-nextjs/contracts.ts +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/api-nextjs/spec.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/api-nextjs/tasks.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/micro-saas/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/micro-saas/contracts.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/micro-saas/decisions.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/micro-saas/spec.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/micro-saas/tasks.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/multi-agent/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/multi-agent/contracts.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/multi-agent/spec.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/multi-agent/tasks.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/scheduled-reports/decisions.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/scheduled-reports/proposal.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/scheduled-reports/spec.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/examples/state-v3.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/features/.gitkeep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/hooks/pre-commit-agents.sh +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/hooks/pre-commit-all.sh +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/hooks/pre-commit-specs.sh +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/hooks/pre-commit-tests.sh +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/hooks/task-completed.js +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/hooks/teammate-idle.js +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/project.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/schemas/agent.schema.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/schemas/tasks.schema.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/specs/.gitkeep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/agent-framework-blazor-ui.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/agent-framework-production.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/agent-framework-setup.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/agent-framework-workflows.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/architecture.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/azure.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/coding.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/dotnet10-migration.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/fluent-ui-setup.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/passkeys-auth.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/standards/vector-search-rag.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/state.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/CONTEXT-FEATURE.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/CONTEXT.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/FluentDesignTheme.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/MudTheme.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/agent.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/clarify-questions.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/component.razor +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/contracts/Commands.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/contracts/Entities.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/contracts/Queries.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/contracts/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/contracts.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/decisions.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/design-system.css +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/.dockerignore.example +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/Dockerfile.example +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/README.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/app-insights.bicep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/app-service.bicep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/azure-pipelines-deploy.yml +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/container-app-env.bicep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/container-app.bicep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/deploy.ps1 +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/deploy.sh +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/key-vault.bicep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/main.bicep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/parameters.dev.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/parameters.prod.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/parameters.staging.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/sql-database.bicep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/infra/storage.bicep +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/integrations/asaas-client.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/integrations/asaas-webhook.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/integrations/azure-identity-config.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/integrations/clerk-config.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/job.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/migration.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/proposal.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/recap.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/repository.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/saas/subscription.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/saas/tenant.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/service.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/simulation.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/spec.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/sprint-status.yaml +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/state.template.json +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/story.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/tasks.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/test.cs +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/ui-components.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/ui-design-system.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/ui-flows.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/templates/ui-mockups.md +0 -0
- /package/{content ā stacks/blazor-azure}/.morph/test-infra/example.bicep +0 -0
- /package/{content ā stacks/blazor-azure}/CLAUDE.md +0 -0
- /package/{content ā stacks/blazor-azure}/README.md +0 -0
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Type definitions and contracts for CLI Auto Context Detection
|
|
3
|
+
* @module morph-spec/cli-auto-context-detection
|
|
4
|
+
*
|
|
5
|
+
* This file defines the interfaces and types used throughout the CLI Auto Context Detection feature.
|
|
6
|
+
* Since MORPH-SPEC uses JavaScript (ESM), we use JSDoc for type annotations instead of TypeScript.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// PROJECT CONTEXT (Scanner Output)
|
|
11
|
+
// ============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parsed package.json content
|
|
15
|
+
* @typedef {Object} PackageJson
|
|
16
|
+
* @property {string} name - Package name
|
|
17
|
+
* @property {string} [version] - Package version
|
|
18
|
+
* @property {string} [description] - Package description
|
|
19
|
+
* @property {Object.<string, string>} [dependencies] - Production dependencies
|
|
20
|
+
* @property {Object.<string, string>} [devDependencies] - Development dependencies
|
|
21
|
+
* @property {Object.<string, string>} [scripts] - NPM scripts
|
|
22
|
+
* @property {string} [type] - Module type (commonjs | module)
|
|
23
|
+
* @property {Object} [engines] - Node.js engine requirements
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Directory structure analysis
|
|
28
|
+
* @typedef {Object} DirectoryStructure
|
|
29
|
+
* @property {boolean} hasSrc - Has src/ directory
|
|
30
|
+
* @property {boolean} hasBackend - Has backend/ or server/ directory
|
|
31
|
+
* @property {boolean} hasFrontend - Has frontend/ or client/ directory
|
|
32
|
+
* @property {boolean} hasTests - Has test/ or tests/ directory
|
|
33
|
+
* @property {string[]} topLevelDirs - List of top-level directories
|
|
34
|
+
* @property {string} pattern - Detected pattern (monorepo | single-project | multi-stack)
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Infrastructure files detected
|
|
39
|
+
* @typedef {Object} InfraFiles
|
|
40
|
+
* @property {string[]} dockerfiles - Paths to Dockerfiles
|
|
41
|
+
* @property {string[]} dockerComposeFiles - Paths to docker-compose.yml files
|
|
42
|
+
* @property {string[]} bicepFiles - Paths to *.bicep files
|
|
43
|
+
* @property {string[]} pipelines - Paths to CI/CD pipeline configs
|
|
44
|
+
* @property {boolean} hasAzure - Has Azure-related files
|
|
45
|
+
* @property {boolean} hasDocker - Has Docker-related files
|
|
46
|
+
* @property {boolean} hasDevOps - Has CI/CD configs
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Complete project context collected by scanner
|
|
51
|
+
* @typedef {Object} ProjectContext
|
|
52
|
+
* @property {string} cwd - Current working directory (absolute path)
|
|
53
|
+
* @property {PackageJson|null} packageJson - Parsed package.json (if exists)
|
|
54
|
+
* @property {string[]} csprojFiles - Paths to *.csproj files
|
|
55
|
+
* @property {string|null} solutionFile - Path to *.sln file (if exists)
|
|
56
|
+
* @property {string|null} readme - Content of README.md (if exists)
|
|
57
|
+
* @property {string|null} claudeMd - Content of CLAUDE.md (if exists)
|
|
58
|
+
* @property {DirectoryStructure} structure - Detected directory structure
|
|
59
|
+
* @property {InfraFiles} infraFiles - Detected infrastructure files
|
|
60
|
+
* @property {string|null} gitRemote - Git remote URL (if in git repo)
|
|
61
|
+
* @property {Date} scannedAt - Timestamp when scan was performed
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// PROJECT CONFIG (LLM Output)
|
|
66
|
+
// ============================================================================
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Technology specification
|
|
70
|
+
* @typedef {Object} TechSpec
|
|
71
|
+
* @property {string} tech - Technology name (e.g., "Next.js", ".NET", "PostgreSQL")
|
|
72
|
+
* @property {string} version - Version (e.g., "15", "10", "16")
|
|
73
|
+
* @property {string} [details] - Additional details (e.g., "Server Components", "Minimal API")
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Technology stack information
|
|
78
|
+
* @typedef {Object} StackInfo
|
|
79
|
+
* @property {TechSpec|null} frontend - Frontend technology (null if backend-only)
|
|
80
|
+
* @property {TechSpec} backend - Backend technology
|
|
81
|
+
* @property {TechSpec|null} database - Database technology (null if no persistence)
|
|
82
|
+
* @property {string|null} hosting - Hosting platform (e.g., "Azure", "Vercel", "Docker")
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Complete project configuration detected by LLM
|
|
87
|
+
* @typedef {Object} ProjectConfig
|
|
88
|
+
* @property {string} name - Project name (from package.json or repo)
|
|
89
|
+
* @property {string} description - Project description (1-2 sentences)
|
|
90
|
+
* @property {string} type - Project type (monorepo | blazor-server | nextjs | cli-tool | dotnet-api | other)
|
|
91
|
+
* @property {StackInfo} stack - Technology stack
|
|
92
|
+
* @property {string} architecture - Architecture pattern (clean-architecture | monolith | microservices | layered | other)
|
|
93
|
+
* @property {string} projectStructure - Description of folder structure
|
|
94
|
+
* @property {string} conventions - Detected code conventions (e.g., "ESM modules", "PascalCase for classes")
|
|
95
|
+
* @property {string|null} repository - Git repository URL
|
|
96
|
+
* @property {boolean} hasAzure - Uses Azure infrastructure
|
|
97
|
+
* @property {boolean} hasDocker - Uses Docker containerization
|
|
98
|
+
* @property {boolean} hasDevOps - Uses CI/CD pipelines
|
|
99
|
+
* @property {number} confidence - LLM confidence score (0-100)
|
|
100
|
+
* @property {string[]} warnings - Warnings or uncertainties detected
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
// ============================================================================
|
|
104
|
+
// SANITIZED CONTEXT (Input to LLM)
|
|
105
|
+
// ============================================================================
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Sanitized project context (safe to send to LLM)
|
|
109
|
+
* @typedef {Object} SanitizedContext
|
|
110
|
+
* @property {Object} packageJson - Sanitized package.json (secrets removed)
|
|
111
|
+
* @property {string[]} csprojFilenames - Filenames only (not full content)
|
|
112
|
+
* @property {boolean} hasSolution - Whether *.sln exists (no content)
|
|
113
|
+
* @property {string|null} readmeSummary - First 500 chars of README.md
|
|
114
|
+
* @property {string|null} claudeMdSummary - First 500 chars of CLAUDE.md
|
|
115
|
+
* @property {DirectoryStructure} structure - Directory structure (safe)
|
|
116
|
+
* @property {Object} infraSummary - Infrastructure summary (no secrets)
|
|
117
|
+
* @property {string|null} gitRemoteDomain - Git remote domain only (e.g., "github.com")
|
|
118
|
+
* @property {number} totalFiles - Total file count (for context)
|
|
119
|
+
*/
|
|
120
|
+
|
|
121
|
+
// ============================================================================
|
|
122
|
+
// GENERATED CONFIGS
|
|
123
|
+
// ============================================================================
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Generated configuration files
|
|
127
|
+
* @typedef {Object} GeneratedConfigs
|
|
128
|
+
* @property {string} projectMd - Rendered project.md content
|
|
129
|
+
* @property {string} configJson - Rendered config.json content (as string)
|
|
130
|
+
* @property {Object} configObject - Parsed config.json (as object)
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
// ============================================================================
|
|
134
|
+
// USER REVIEW
|
|
135
|
+
// ============================================================================
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* User approval response
|
|
139
|
+
* @typedef {Object} ApprovalResponse
|
|
140
|
+
* @property {'approve'|'edit'|'cancel'} action - User action
|
|
141
|
+
* @property {GeneratedConfigs} [editedConfigs] - Edited configs (if action === 'edit')
|
|
142
|
+
* @property {string} [cancelReason] - Reason for cancellation (if action === 'cancel')
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
// ============================================================================
|
|
146
|
+
// ERRORS
|
|
147
|
+
// ============================================================================
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* LLM Analysis Error
|
|
151
|
+
* @typedef {Error} LLMAnalysisError
|
|
152
|
+
* @property {string} name - "LLMAnalysisError"
|
|
153
|
+
* @property {string} message - Error message
|
|
154
|
+
* @property {number} statusCode - HTTP status code (if API error)
|
|
155
|
+
* @property {number} attempts - Number of retry attempts made
|
|
156
|
+
* @property {Error} [originalError] - Original error from API
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Validation Error
|
|
161
|
+
* @typedef {Error} ValidationError
|
|
162
|
+
* @property {string} name - "ValidationError"
|
|
163
|
+
* @property {string} message - Error message
|
|
164
|
+
* @property {string} field - Field that failed validation
|
|
165
|
+
* @property {any} value - Invalid value
|
|
166
|
+
* @property {Object} [schema] - JSON schema that was violated
|
|
167
|
+
*/
|
|
168
|
+
|
|
169
|
+
// ============================================================================
|
|
170
|
+
// SERVICE INTERFACES
|
|
171
|
+
// ============================================================================
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Project Scanner Interface
|
|
175
|
+
* @interface IProjectScanner
|
|
176
|
+
*/
|
|
177
|
+
export class IProjectScanner {
|
|
178
|
+
/**
|
|
179
|
+
* Scan the project directory and collect context
|
|
180
|
+
* @param {string} cwd - Current working directory
|
|
181
|
+
* @returns {Promise<ProjectContext>}
|
|
182
|
+
*/
|
|
183
|
+
async scan(cwd) {
|
|
184
|
+
throw new Error('Not implemented');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Read and parse package.json
|
|
189
|
+
* @param {string} cwd - Current working directory
|
|
190
|
+
* @returns {Promise<PackageJson|null>}
|
|
191
|
+
*/
|
|
192
|
+
async readPackageJson(cwd) {
|
|
193
|
+
throw new Error('Not implemented');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Find all .csproj files recursively
|
|
198
|
+
* @param {string} cwd - Current working directory
|
|
199
|
+
* @returns {Promise<string[]>}
|
|
200
|
+
*/
|
|
201
|
+
async findCsprojFiles(cwd) {
|
|
202
|
+
throw new Error('Not implemented');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Detect directory structure
|
|
207
|
+
* @param {string} cwd - Current working directory
|
|
208
|
+
* @returns {Promise<DirectoryStructure>}
|
|
209
|
+
*/
|
|
210
|
+
async detectDirectoryStructure(cwd) {
|
|
211
|
+
throw new Error('Not implemented');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Find infrastructure files (Docker, Bicep, pipelines)
|
|
216
|
+
* @param {string} cwd - Current working directory
|
|
217
|
+
* @returns {Promise<InfraFiles>}
|
|
218
|
+
*/
|
|
219
|
+
async findInfraFiles(cwd) {
|
|
220
|
+
throw new Error('Not implemented');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get git remote URL
|
|
225
|
+
* @param {string} cwd - Current working directory
|
|
226
|
+
* @returns {Promise<string|null>}
|
|
227
|
+
*/
|
|
228
|
+
async getGitRemote(cwd) {
|
|
229
|
+
throw new Error('Not implemented');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Context Sanitizer Interface
|
|
235
|
+
* @interface IContextSanitizer
|
|
236
|
+
*/
|
|
237
|
+
export class IContextSanitizer {
|
|
238
|
+
/**
|
|
239
|
+
* Sanitize project context (remove secrets, truncate files)
|
|
240
|
+
* @param {ProjectContext} context - Raw project context
|
|
241
|
+
* @returns {SanitizedContext}
|
|
242
|
+
*/
|
|
243
|
+
sanitize(context) {
|
|
244
|
+
throw new Error('Not implemented');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Detect and redact secrets from text
|
|
249
|
+
* @param {string} text - Text to sanitize
|
|
250
|
+
* @returns {string} Sanitized text
|
|
251
|
+
*/
|
|
252
|
+
redactSecrets(text) {
|
|
253
|
+
throw new Error('Not implemented');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Check if file should be excluded from LLM analysis
|
|
258
|
+
* @param {string} filepath - File path
|
|
259
|
+
* @returns {boolean} True if file should be excluded
|
|
260
|
+
*/
|
|
261
|
+
shouldExcludeFile(filepath) {
|
|
262
|
+
throw new Error('Not implemented');
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* LLM Analyzer Interface
|
|
268
|
+
* @interface ILLMAnalyzer
|
|
269
|
+
*/
|
|
270
|
+
export class ILLMAnalyzer {
|
|
271
|
+
/**
|
|
272
|
+
* Analyze project context using Claude Code's LLM
|
|
273
|
+
* @param {SanitizedContext} context - Sanitized project context
|
|
274
|
+
* @param {Object} [options] - Analysis options
|
|
275
|
+
* @param {number} [options.timeout] - Timeout in ms (default: 30000)
|
|
276
|
+
* @returns {Promise<ProjectConfig>}
|
|
277
|
+
* @throws {LLMAnalysisError} If analysis fails
|
|
278
|
+
*/
|
|
279
|
+
async analyze(context, options) {
|
|
280
|
+
throw new Error('Not implemented');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Build structured prompt for LLM
|
|
285
|
+
* @param {SanitizedContext} context - Sanitized context
|
|
286
|
+
* @returns {string} Prompt text
|
|
287
|
+
*/
|
|
288
|
+
buildPrompt(context) {
|
|
289
|
+
throw new Error('Not implemented');
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Invoke Claude Code's LLM (via Task tool or internal API)
|
|
294
|
+
* @param {string} prompt - Prompt text
|
|
295
|
+
* @param {Object} options - Invocation options
|
|
296
|
+
* @returns {Promise<string>} JSON response from LLM
|
|
297
|
+
* @throws {LLMAnalysisError}
|
|
298
|
+
*/
|
|
299
|
+
async invokeLLM(prompt, options) {
|
|
300
|
+
throw new Error('Not implemented');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Parse and validate LLM JSON response
|
|
305
|
+
* @param {string} response - Raw LLM response
|
|
306
|
+
* @returns {ProjectConfig}
|
|
307
|
+
* @throws {ValidationError} If response doesn't match schema
|
|
308
|
+
*/
|
|
309
|
+
parseJsonResponse(response) {
|
|
310
|
+
throw new Error('Not implemented');
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Config Generator Interface
|
|
316
|
+
* @interface IConfigGenerator
|
|
317
|
+
*/
|
|
318
|
+
export class IConfigGenerator {
|
|
319
|
+
/**
|
|
320
|
+
* Generate configuration files from project config
|
|
321
|
+
* @param {ProjectConfig} projectConfig - Detected project config
|
|
322
|
+
* @returns {Promise<GeneratedConfigs>}
|
|
323
|
+
*/
|
|
324
|
+
async generate(projectConfig) {
|
|
325
|
+
throw new Error('Not implemented');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Render project.md template
|
|
330
|
+
* @param {ProjectConfig} config - Project config
|
|
331
|
+
* @returns {string} Rendered markdown
|
|
332
|
+
*/
|
|
333
|
+
renderProjectMd(config) {
|
|
334
|
+
throw new Error('Not implemented');
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Render config.json template
|
|
339
|
+
* @param {ProjectConfig} config - Project config
|
|
340
|
+
* @returns {string} Rendered JSON string
|
|
341
|
+
*/
|
|
342
|
+
renderConfigJson(config) {
|
|
343
|
+
throw new Error('Not implemented');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Validate config.json against schema
|
|
348
|
+
* @param {string} configJson - JSON string
|
|
349
|
+
* @returns {boolean} True if valid
|
|
350
|
+
* @throws {ValidationError} If validation fails
|
|
351
|
+
*/
|
|
352
|
+
validateConfigJson(configJson) {
|
|
353
|
+
throw new Error('Not implemented');
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Backup existing configuration files
|
|
358
|
+
* @param {string} cwd - Current working directory
|
|
359
|
+
* @returns {Promise<void>}
|
|
360
|
+
*/
|
|
361
|
+
async backupExisting(cwd) {
|
|
362
|
+
throw new Error('Not implemented');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* User Review Interface
|
|
368
|
+
* @interface IUserReview
|
|
369
|
+
*/
|
|
370
|
+
export class IUserReview {
|
|
371
|
+
/**
|
|
372
|
+
* Prompt user for approval of generated configs
|
|
373
|
+
* @param {GeneratedConfigs} configs - Generated configs
|
|
374
|
+
* @param {ProjectConfig} projectConfig - Detected project config
|
|
375
|
+
* @returns {Promise<ApprovalResponse>}
|
|
376
|
+
*/
|
|
377
|
+
async promptForApproval(configs, projectConfig) {
|
|
378
|
+
throw new Error('Not implemented');
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Display diff between current and generated configs
|
|
383
|
+
* @param {string} current - Current config content
|
|
384
|
+
* @param {string} generated - Generated config content
|
|
385
|
+
* @returns {void}
|
|
386
|
+
*/
|
|
387
|
+
displayDiff(current, generated) {
|
|
388
|
+
throw new Error('Not implemented');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Open configs in editor for manual editing
|
|
393
|
+
* @param {GeneratedConfigs} configs - Configs to edit
|
|
394
|
+
* @returns {Promise<GeneratedConfigs>} Edited configs
|
|
395
|
+
*/
|
|
396
|
+
async openInEditor(configs) {
|
|
397
|
+
throw new Error('Not implemented');
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* File Writer Interface
|
|
403
|
+
* @interface IFileWriter
|
|
404
|
+
*/
|
|
405
|
+
export class IFileWriter {
|
|
406
|
+
/**
|
|
407
|
+
* Save generated configs to filesystem
|
|
408
|
+
* @param {string} cwd - Current working directory
|
|
409
|
+
* @param {GeneratedConfigs} configs - Configs to save
|
|
410
|
+
* @returns {Promise<void>}
|
|
411
|
+
*/
|
|
412
|
+
async save(cwd, configs) {
|
|
413
|
+
throw new Error('Not implemented');
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Write project.md file
|
|
418
|
+
* @param {string} filepath - File path
|
|
419
|
+
* @param {string} content - File content
|
|
420
|
+
* @returns {Promise<void>}
|
|
421
|
+
*/
|
|
422
|
+
async writeProjectMd(filepath, content) {
|
|
423
|
+
throw new Error('Not implemented');
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Write config.json file
|
|
428
|
+
* @param {string} filepath - File path
|
|
429
|
+
* @param {string} content - File content (JSON string)
|
|
430
|
+
* @returns {Promise<void>}
|
|
431
|
+
*/
|
|
432
|
+
async writeConfigJson(filepath, content) {
|
|
433
|
+
throw new Error('Not implemented');
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ============================================================================
|
|
438
|
+
// ORCHESTRATOR (Main Flow)
|
|
439
|
+
// ============================================================================
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* CLI Auto Context Detection Orchestrator
|
|
443
|
+
* @interface IAutoContextOrchestrator
|
|
444
|
+
*/
|
|
445
|
+
export class IAutoContextOrchestrator {
|
|
446
|
+
/**
|
|
447
|
+
* Execute the complete auto-detection flow
|
|
448
|
+
* @param {string} cwd - Current working directory
|
|
449
|
+
* @param {Object} [options] - Orchestration options
|
|
450
|
+
* @param {boolean} [options.skipReview] - Skip user review (auto-approve)
|
|
451
|
+
* @param {boolean} [options.fallbackOnError] - Fallback to wizard on LLM error
|
|
452
|
+
* @returns {Promise<{success: boolean, configs: GeneratedConfigs|null}>}
|
|
453
|
+
*/
|
|
454
|
+
async execute(cwd, options) {
|
|
455
|
+
throw new Error('Not implemented');
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// ============================================================================
|
|
460
|
+
// EXPORTS
|
|
461
|
+
// ============================================================================
|
|
462
|
+
|
|
463
|
+
export {
|
|
464
|
+
// Types
|
|
465
|
+
PackageJson,
|
|
466
|
+
DirectoryStructure,
|
|
467
|
+
InfraFiles,
|
|
468
|
+
ProjectContext,
|
|
469
|
+
TechSpec,
|
|
470
|
+
StackInfo,
|
|
471
|
+
ProjectConfig,
|
|
472
|
+
SanitizedContext,
|
|
473
|
+
GeneratedConfigs,
|
|
474
|
+
ApprovalResponse,
|
|
475
|
+
LLMAnalysisError,
|
|
476
|
+
ValidationError,
|
|
477
|
+
};
|
package/src/ui/.gitkeep
ADDED
|
File without changes
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Diff Display - Shows diff between current and generated configs
|
|
3
|
+
* @module morph-spec/ui/diff-display
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { diffLines } from 'diff';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Display diff between two text strings
|
|
11
|
+
* @param {string} oldContent - Original content
|
|
12
|
+
* @param {string} newContent - New content
|
|
13
|
+
* @param {string} filename - Filename for display
|
|
14
|
+
*/
|
|
15
|
+
export function displayDiff(oldContent, newContent, filename) {
|
|
16
|
+
console.log(chalk.bold(`\nš Changes in ${filename}:\n`));
|
|
17
|
+
|
|
18
|
+
const diff = diffLines(oldContent, newContent);
|
|
19
|
+
|
|
20
|
+
diff.forEach(part => {
|
|
21
|
+
const color = part.added ? chalk.green : part.removed ? chalk.red : chalk.gray;
|
|
22
|
+
const prefix = part.added ? '+ ' : part.removed ? '- ' : ' ';
|
|
23
|
+
|
|
24
|
+
part.value.split('\n').forEach((line, index) => {
|
|
25
|
+
if (line || index < part.value.split('\n').length - 1) {
|
|
26
|
+
console.log(color(prefix + line));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
console.log(); // Empty line after diff
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Display side-by-side summary of changes
|
|
36
|
+
* @param {Object} oldConfig - Old config object
|
|
37
|
+
* @param {Object} newConfig - New config object
|
|
38
|
+
*/
|
|
39
|
+
export function displayConfigSummary(oldConfig, newConfig) {
|
|
40
|
+
console.log(chalk.bold('\nš Configuration Summary:\n'));
|
|
41
|
+
|
|
42
|
+
const fields = [
|
|
43
|
+
{ key: 'name', label: 'Project Name' },
|
|
44
|
+
{ key: 'type', label: 'Project Type' },
|
|
45
|
+
{ key: 'description', label: 'Description' },
|
|
46
|
+
{ key: 'stack.backend.tech', label: 'Backend' },
|
|
47
|
+
{ key: 'stack.frontend.tech', label: 'Frontend' },
|
|
48
|
+
{ key: 'stack.database.tech', label: 'Database' },
|
|
49
|
+
{ key: 'architecture', label: 'Architecture' }
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
fields.forEach(({ key, label }) => {
|
|
53
|
+
const oldValue = getNestedValue(oldConfig, key) || chalk.gray('(not set)');
|
|
54
|
+
const newValue = getNestedValue(newConfig, key) || chalk.gray('(not set)');
|
|
55
|
+
|
|
56
|
+
const changed = oldValue !== newValue;
|
|
57
|
+
const color = changed ? chalk.yellow : chalk.white;
|
|
58
|
+
|
|
59
|
+
console.log(
|
|
60
|
+
color(` ${label.padEnd(20)}: `) +
|
|
61
|
+
chalk.dim(String(oldValue).padEnd(30)) +
|
|
62
|
+
chalk.bold(' ā ') +
|
|
63
|
+
color(newValue)
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
console.log();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get nested value from object by dot notation key
|
|
72
|
+
* @param {Object} obj - Object to query
|
|
73
|
+
* @param {string} key - Dot notation key (e.g., 'stack.backend.tech')
|
|
74
|
+
* @returns {any} Value or null
|
|
75
|
+
*/
|
|
76
|
+
function getNestedValue(obj, key) {
|
|
77
|
+
if (!obj) return null;
|
|
78
|
+
|
|
79
|
+
const keys = key.split('.');
|
|
80
|
+
let current = obj;
|
|
81
|
+
|
|
82
|
+
for (const k of keys) {
|
|
83
|
+
if (current && typeof current === 'object' && k in current) {
|
|
84
|
+
current = current[k];
|
|
85
|
+
} else {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return current;
|
|
91
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Interactive Wizard - Manual configuration when LLM fails
|
|
3
|
+
* @module morph-spec/ui/interactive-wizard
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import { getWizardQuestions, mapAnswersToConfig } from './wizard-questions.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {import('../types/index.js').ProjectConfig} ProjectConfig
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* InteractiveWizard - Guides user through manual project configuration
|
|
16
|
+
* @class
|
|
17
|
+
*/
|
|
18
|
+
export class InteractiveWizard {
|
|
19
|
+
/**
|
|
20
|
+
* Run interactive wizard to collect project configuration
|
|
21
|
+
* @returns {Promise<ProjectConfig>}
|
|
22
|
+
*/
|
|
23
|
+
async run() {
|
|
24
|
+
console.log(chalk.bold.cyan('\nš§ Interactive Project Configuration Wizard\n'));
|
|
25
|
+
console.log(chalk.dim(' Answer 7 questions to configure your project\n'));
|
|
26
|
+
|
|
27
|
+
const questions = getWizardQuestions();
|
|
28
|
+
const answers = await inquirer.prompt(questions);
|
|
29
|
+
|
|
30
|
+
// Map answers to ProjectConfig
|
|
31
|
+
const config = mapAnswersToConfig(answers);
|
|
32
|
+
|
|
33
|
+
// Show summary
|
|
34
|
+
this.displaySummary(config);
|
|
35
|
+
|
|
36
|
+
// Confirm before proceeding
|
|
37
|
+
const { confirmed } = await inquirer.prompt([
|
|
38
|
+
{
|
|
39
|
+
type: 'confirm',
|
|
40
|
+
name: 'confirmed',
|
|
41
|
+
message: 'Is this configuration correct?',
|
|
42
|
+
default: true
|
|
43
|
+
}
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
if (!confirmed) {
|
|
47
|
+
console.log(chalk.yellow('\nā Configuration canceled. Please run the wizard again.\n'));
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return config;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Display summary of collected configuration
|
|
56
|
+
* @param {ProjectConfig} config - Project configuration
|
|
57
|
+
*/
|
|
58
|
+
displaySummary(config) {
|
|
59
|
+
console.log(chalk.bold.green('\nā
Configuration Summary:\n'));
|
|
60
|
+
|
|
61
|
+
console.log(chalk.bold(' Name: ') + chalk.cyan(config.name));
|
|
62
|
+
console.log(chalk.bold(' Type: ') + chalk.yellow(config.type));
|
|
63
|
+
console.log(chalk.bold(' Description: ') + chalk.white(config.description));
|
|
64
|
+
console.log();
|
|
65
|
+
|
|
66
|
+
console.log(chalk.bold(' Stack:'));
|
|
67
|
+
if (config.stack.frontend) {
|
|
68
|
+
console.log(chalk.gray(' Frontend: ') + chalk.white(`${config.stack.frontend.tech} ${config.stack.frontend.version}`));
|
|
69
|
+
} else {
|
|
70
|
+
console.log(chalk.gray(' Frontend: ') + chalk.dim('None (backend-only)'));
|
|
71
|
+
}
|
|
72
|
+
console.log(chalk.gray(' Backend: ') + chalk.white(`${config.stack.backend.tech} ${config.stack.backend.version}`));
|
|
73
|
+
if (config.stack.database) {
|
|
74
|
+
console.log(chalk.gray(' Database: ') + chalk.white(`${config.stack.database.tech} ${config.stack.database.version}`));
|
|
75
|
+
} else {
|
|
76
|
+
console.log(chalk.gray(' Database: ') + chalk.dim('None'));
|
|
77
|
+
}
|
|
78
|
+
if (config.stack.hosting) {
|
|
79
|
+
console.log(chalk.gray(' Hosting: ') + chalk.white(config.stack.hosting));
|
|
80
|
+
}
|
|
81
|
+
console.log();
|
|
82
|
+
|
|
83
|
+
console.log(chalk.bold(' Architecture: ') + chalk.magenta(config.architecture));
|
|
84
|
+
console.log();
|
|
85
|
+
|
|
86
|
+
// Infrastructure flags
|
|
87
|
+
const flags = [];
|
|
88
|
+
if (config.hasAzure) flags.push(chalk.blue('Azure'));
|
|
89
|
+
if (config.hasDocker) flags.push(chalk.cyan('Docker'));
|
|
90
|
+
|
|
91
|
+
if (flags.length > 0) {
|
|
92
|
+
console.log(chalk.bold(' Infrastructure: ') + flags.join(' ⢠'));
|
|
93
|
+
console.log();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|