@polymorphism-tech/morph-spec 4.3.7 → 4.6.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/.morph/.morphversion +3 -3
- package/.morph/analytics/threads-log.jsonl +6 -9
- package/.morph/config/config.json +2 -3
- package/.morph/framework/standards/STANDARDS.json +812 -0
- package/.morph/{standards → framework/standards}/ai-agents/team-orchestration.md +3 -3
- package/.morph/{standards → framework/standards}/frontend/nextjs/nextjs-patterns.md +17 -0
- package/.morph/framework/standards/integration/mcp/mcp-tools.md +384 -0
- package/.morph/{templates → framework/templates}/README.md +17 -17
- package/.morph/{templates → framework/templates}/REGISTRY.json +48 -233
- package/.morph/framework/templates/code/dotnet/contracts/contracts.cs.hbs +172 -0
- package/.morph/{templates → framework/templates}/context/CONTEXT-FEATURE.md +1 -1
- package/.morph/{templates → framework/templates}/context/CONTEXT.md +3 -3
- package/.morph/framework/templates/docs/clarifications.md +253 -0
- package/.morph/framework/templates/docs/onboarding.md +123 -0
- package/.morph/framework/templates/docs/schema-analysis.md +119 -0
- package/.morph/{templates → framework/templates}/docs/spec.md +149 -149
- package/.morph/framework/templates/docs/ui-components.md +124 -0
- package/.morph/framework/templates/docs/ui-design-system.md +76 -0
- package/.morph/framework/templates/docs/ui-flows.md +167 -0
- package/.morph/framework/templates/docs/ui-mockups.md +98 -0
- package/.morph/framework/templates/docs/user-stories.md +34 -0
- package/.morph/{templates → framework/templates}/examples/spec-examples.md +1 -1
- package/.morph/{templates → framework/templates}/infrastructure/github/README.md +11 -11
- package/.morph/{templates → framework/templates}/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +2 -2
- package/.morph/{templates → framework/templates}/meta-prompts/parallel-workers/parallel-worker.md +2 -2
- package/.morph/{templates → framework/templates}/meta-prompts/validators/pre-commit-validator.md +1 -1
- package/.morph/logs/tool-failures.log +7 -0
- package/.morph/memory/pre-compact-2026-02-23T15-43-03-521Z.json +16 -0
- package/.morph/state.json +1 -1
- package/CLAUDE.md +77 -155
- package/README.md +20 -18
- package/bin/detect-agents.js +1 -1
- package/bin/morph-spec.js +116 -266
- package/bin/task-manager.cjs +2 -2
- package/bin/validate.js +1 -1
- package/claude-plugin.json +14 -0
- package/docs/claude-alignment-report.md +137 -0
- package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +512 -0
- package/docs/plans/2026-02-22-claude-settings.md +515 -0
- package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +728 -0
- package/docs/plans/2026-02-22-morph-spec-next.md +478 -0
- package/docs/plans/2026-02-22-native-alignment-design.md +199 -0
- package/docs/plans/2026-02-22-native-alignment-impl.md +925 -0
- package/docs/plans/2026-02-22-native-enrichment-design.md +244 -0
- package/docs/plans/2026-02-22-native-enrichment.md +735 -0
- package/framework/CLAUDE.md +77 -0
- package/framework/{skills/level-2-domains → agents}/ai-agents/ai-system-architect.md +7 -3
- package/framework/{skills/level-2-domains → agents}/architecture/po-pm-advisor.md +7 -1
- package/framework/{skills/level-2-domains → agents}/architecture/prompt-engineer.md +7 -1
- package/framework/{skills/level-2-domains → agents}/architecture/seo-growth-hacker.md +7 -1
- package/framework/{skills/level-2-domains → agents}/architecture/standards-architect.md +10 -6
- package/framework/agents/backend/api-designer.md +103 -0
- package/framework/{skills/level-2-domains → agents}/backend/dotnet-senior.md +7 -1
- package/framework/agents/backend/ef-modeler.md +119 -0
- package/framework/{skills/level-2-domains → agents}/backend/hangfire-orchestrator.md +8 -4
- package/framework/{skills/level-2-domains → agents}/backend/ms-agent-expert.md +7 -3
- package/framework/{skills/level-2-domains → agents}/frontend/blazor-builder.md +7 -3
- package/framework/{skills/level-2-domains → agents}/frontend/nextjs-expert.md +7 -3
- package/framework/{skills/level-2-domains → agents}/frontend/ui-ux-designer.md +8 -2
- package/framework/{skills/level-2-domains → agents}/infrastructure/azure-architect.md +7 -1
- package/framework/{skills/level-2-domains → agents}/infrastructure/azure-deploy-specialist.md +7 -1
- package/framework/{skills/level-2-domains → agents}/infrastructure/bicep-architect.md +7 -3
- package/framework/{skills/level-2-domains → agents}/infrastructure/container-specialist.md +7 -3
- package/framework/{skills/level-2-domains → agents}/infrastructure/devops-engineer.md +7 -3
- package/framework/{skills/level-2-domains → agents}/integrations/asaas-financial.md +7 -3
- package/framework/{skills/level-2-domains → agents}/integrations/azure-identity.md +7 -3
- package/framework/{skills/level-2-domains → agents}/integrations/clerk-auth.md +7 -3
- package/framework/{skills/level-2-domains/integrations/hangfire-orchestrator.md → agents/integrations/hangfire-integration.md} +7 -1
- package/framework/{skills/level-2-domains → agents}/integrations/resend-email.md +7 -3
- package/framework/{skills/level-2-domains → agents}/quality/code-analyzer.md +9 -5
- package/framework/{skills/level-2-domains → agents}/quality/testing-specialist.md +7 -3
- package/framework/commands/morph-apply.md +9 -9
- package/framework/commands/morph-archive.md +8 -8
- package/framework/commands/morph-infra.md +1 -1
- package/framework/commands/morph-proposal.md +9 -9
- package/framework/commands/morph-status.md +3 -3
- package/framework/commands/morph-troubleshoot.md +1 -1
- package/framework/hooks/README.md +201 -282
- package/framework/hooks/claude-code/notification/approval-reminder.js +52 -0
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +83 -0
- package/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +42 -0
- package/framework/hooks/claude-code/pre-compact/save-morph-context.js +61 -0
- package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +71 -0
- package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +58 -0
- package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +64 -0
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +94 -0
- package/framework/hooks/claude-code/statusline.py +538 -0
- package/framework/hooks/claude-code/statusline.sh +7 -0
- package/framework/hooks/claude-code/stop/validate-completion.js +88 -0
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +91 -0
- package/framework/hooks/shared/hook-response.js +45 -0
- package/framework/hooks/shared/phase-utils.js +129 -0
- package/framework/hooks/shared/state-reader.js +138 -0
- package/framework/hooks/shared/stdin-reader.js +26 -0
- package/framework/phases.json +145 -0
- package/framework/rules/csharp-standards.md +10 -0
- package/framework/rules/frontend-standards.md +14 -0
- package/framework/rules/infrastructure-standards.md +13 -0
- package/framework/rules/morph-workflow.md +86 -0
- package/framework/rules/testing-standards.md +11 -0
- package/framework/skills/README.md +66 -0
- package/framework/skills/level-0-meta/brainstorming/SKILL.md +135 -0
- package/framework/skills/level-0-meta/brainstorming/references/proposal-example.md +138 -0
- package/framework/skills/level-0-meta/{code-review.md → code-review/SKILL.md} +13 -4
- package/framework/skills/level-0-meta/code-review/references/review-example.md +164 -0
- package/framework/skills/level-0-meta/code-review/scripts/scan-csharp.mjs +121 -0
- package/framework/skills/level-0-meta/mcp-registry.json +207 -0
- package/framework/skills/level-0-meta/{morph-checklist.md → morph-checklist/SKILL.md} +8 -3
- package/framework/skills/{level-1-workflows/morph-replicate.md → level-0-meta/morph-replicate/SKILL.md} +13 -6
- package/framework/skills/level-0-meta/{simulation-checklist.md → simulation-checklist/SKILL.md} +9 -4
- package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +334 -0
- package/framework/skills/level-0-meta/verification-before-completion/SKILL.md +147 -0
- package/framework/skills/level-0-meta/verification-before-completion/scripts/check-phase-outputs.mjs +110 -0
- package/framework/skills/level-1-workflows/{phase-clarify.md → phase-clarify/SKILL.md} +65 -4
- package/framework/skills/level-1-workflows/phase-clarify/references/clarifications-example.md +117 -0
- package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +181 -0
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +303 -0
- package/framework/skills/level-1-workflows/phase-design/references/spec-example.md +253 -0
- package/framework/skills/level-1-workflows/phase-implement/SKILL.md +254 -0
- package/framework/skills/level-1-workflows/phase-implement/references/recap-example.md +132 -0
- package/framework/skills/level-1-workflows/phase-setup/SKILL.md +171 -0
- package/framework/skills/level-1-workflows/{phase-tasks.md → phase-tasks/SKILL.md} +89 -7
- package/framework/skills/level-1-workflows/phase-tasks/references/tasks-example.md +231 -0
- package/framework/skills/level-1-workflows/phase-tasks/scripts/validate-tasks.mjs +112 -0
- package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +246 -0
- package/framework/standards/STANDARDS.json +812 -0
- package/framework/standards/ai-agents/team-orchestration.md +3 -3
- package/framework/standards/frontend/nextjs/nextjs-patterns.md +17 -0
- package/framework/standards/integration/mcp/mcp-tools.md +384 -0
- package/framework/templates/README.md +17 -17
- package/framework/templates/REGISTRY.json +48 -233
- package/framework/templates/code/dotnet/contracts/contracts.cs.hbs +172 -0
- package/framework/templates/context/CONTEXT-FEATURE.md +1 -1
- package/framework/templates/context/CONTEXT.md +3 -3
- package/framework/templates/docs/clarifications.md +253 -0
- package/framework/templates/docs/onboarding.md +123 -0
- package/framework/templates/docs/schema-analysis.md +119 -0
- package/framework/templates/docs/spec.md +149 -149
- package/framework/templates/docs/ui-components.md +124 -0
- package/framework/templates/docs/ui-design-system.md +76 -0
- package/framework/templates/docs/ui-flows.md +167 -0
- package/framework/templates/docs/ui-mockups.md +98 -0
- package/framework/templates/docs/user-stories.md +34 -0
- package/framework/templates/examples/spec-examples.md +1 -1
- package/framework/templates/infrastructure/github/README.md +11 -11
- package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +2 -2
- package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +1 -1
- package/framework/workflows/configs/express.json +45 -0
- package/framework/workflows/configs/spec-only.json +43 -0
- package/framework/workflows/docs/enforcement-pipeline.md +8 -8
- package/framework/workflows/docs/full-morph.md +3 -3
- package/package.json +3 -1
- package/scripts/generate-refs.js +336 -0
- package/scripts/generate-standards-registry.js +44 -0
- package/scripts/validate-real.mjs +255 -0
- package/src/commands/feature/create-story.js +362 -361
- package/src/commands/feature/shard-spec.js +225 -224
- package/src/commands/feature/sprint-status.js +1 -1
- package/src/commands/generation/generate-onboarding.js +169 -0
- package/src/commands/generation/generate.js +2 -2
- package/src/commands/mcp/mcp-setup.js +315 -0
- package/src/commands/project/changes.js +66 -0
- package/src/commands/project/checkpoint.js +209 -0
- package/src/commands/project/cost.js +179 -0
- package/src/commands/project/diff.js +278 -0
- package/src/commands/project/doctor.js +55 -7
- package/src/commands/project/init.js +318 -136
- package/src/commands/project/revert.js +173 -0
- package/src/commands/project/standards.js +80 -0
- package/src/commands/project/status.js +376 -0
- package/src/commands/project/update-agents.js +23 -0
- package/src/commands/project/update.js +60 -88
- package/src/commands/state/advance-phase.js +4 -3
- package/src/commands/state/state.js +10 -3
- package/src/commands/state/validate-phase.js +19 -2
- package/src/commands/templates/template-customize.js +4 -4
- package/src/commands/templates/template-render.js +1 -1
- package/src/commands/templates/template-show.js +1 -1
- package/src/commands/validation/validate-feature.js +359 -0
- package/src/core/orchestrator.js +3 -38
- package/src/core/paths/output-schema.js +135 -0
- package/src/core/state/state-manager.js +831 -592
- package/src/core/templates/template-registry.js +2 -2
- package/src/core/workflows/workflow-detector.js +17 -1
- package/src/lib/agents/micro-agent-factory.js +1 -1
- package/src/lib/context/context-bundler.js +2 -1
- package/src/lib/detectors/claude-config-detector.js +390 -0
- package/src/lib/detectors/conversation-analyzer.js +4 -4
- package/src/lib/detectors/design-system-detector.js +6 -5
- package/src/lib/detectors/standards-generator.js +2 -2
- package/src/lib/generators/context-generator.js +539 -538
- package/src/lib/generators/recap-generator.js +1 -1
- package/src/lib/generators/settings-generator.js +210 -0
- package/src/lib/hooks/hook-executor.js +1 -1
- package/src/lib/installers/mcp-installer.js +299 -0
- package/src/lib/learning/learning-system.js +3 -3
- package/src/lib/orchestration/team-orchestrator.js +1 -1
- package/src/lib/standards/standards-context-injector.js +7 -7
- package/src/lib/threads/thread-coordinator.js +1 -1
- package/src/lib/troubleshooting/troubleshoot-grep.js +1 -1
- package/src/lib/validators/contracts/contract-compliance-validator.js +274 -273
- package/src/lib/validators/design-system/design-system-validator.js +1 -1
- package/src/lib/validators/spec-validator.js +258 -258
- package/src/lib/validators/validation-runner.js +270 -269
- package/src/utils/agents-installer.js +206 -0
- package/src/utils/claude-settings-manager.js +258 -0
- package/src/utils/file-copier.js +1 -1
- package/src/utils/hooks-installer.js +354 -28
- package/src/utils/skills-installer.js +118 -0
- package/.morph/project/context/README.md +0 -17
- package/.morph/project/context/detection-log.md +0 -16
- package/.morph/project/standards/inferred.md +0 -59
- package/framework/hooks/agent-stop/validate-and-continue.js +0 -96
- package/framework/hooks/agent-stop/validate-checkpoints.js +0 -101
- package/framework/hooks/agent-stop/validate-tests.js +0 -109
- package/framework/hooks/agent-teams/dispatch.js +0 -67
- package/framework/hooks/agent-teams/phase-advanced.js +0 -80
- package/framework/hooks/agent-teams/task-completed.js +0 -76
- package/framework/hooks/agent-teams/teammate-idle.js +0 -70
- package/framework/skills/level-1-workflows/phase-design.md +0 -213
- package/framework/skills/level-1-workflows/phase-setup.md +0 -106
- package/framework/skills/level-1-workflows/phase-uiux.md +0 -169
- package/framework/skills/level-2-domains/backend/api-designer.md +0 -59
- package/framework/skills/level-2-domains/backend/ef-modeler.md +0 -58
- package/framework/skills/level-3-technologies/README.md +0 -7
- package/framework/skills/level-4-patterns/README.md +0 -7
- package/src/commands/agents/agents-fuse.js +0 -97
- package/src/commands/agents/micro-agent.js +0 -112
- package/src/commands/agents/spawn-team.js +0 -237
- package/src/commands/agents/squad-template.js +0 -146
- package/src/commands/analytics/analytics.js +0 -176
- package/src/commands/context/context-prime.js +0 -63
- package/src/commands/context/core-four.js +0 -54
- package/src/commands/generation/generate-context.js +0 -40
- package/src/commands/project/detect-agents.js +0 -207
- package/src/commands/project/detect-workflow.js +0 -174
- package/src/commands/threads/thread-template.js +0 -103
- package/src/commands/threads/threads.js +0 -261
- package/src/commands/utils/session-summary.js +0 -291
- package/src/llm/analyzer.js +0 -215
- package/src/llm/few-shot-examples.js +0 -216
- package/src/llm/project-config-schema.json +0 -188
- package/src/llm/prompt-builder.js +0 -96
- /package/.morph/{config → framework}/agents.json +0 -0
- /package/.morph/{standards → framework/standards}/ai-agents/blazor-ui.md +0 -0
- /package/.morph/{standards → framework/standards}/ai-agents/production.md +0 -0
- /package/.morph/{standards → framework/standards}/ai-agents/setup.md +0 -0
- /package/.morph/{standards → framework/standards}/ai-agents/workflows.md +0 -0
- /package/.morph/{standards → framework/standards}/architecture/ddd/aggregates.md +0 -0
- /package/.morph/{standards → framework/standards}/architecture/ddd/entities.md +0 -0
- /package/.morph/{standards → framework/standards}/architecture/ddd/value-objects.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/api/minimal-api.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/api/rest.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/api/validation.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/authentication/passkeys.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/database/ef-core.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/database/migrations.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/database/postgresql/database.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/database/repository-patterns.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/database/vector-search-rag.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/dotnet/async.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/dotnet/core.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/dotnet/di.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/dotnet/program-cs-checklist.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/integrations/asaas/asaas-api.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/integrations/clerk/clerk-auth.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/integrations/hangfire/hangfire-jobs.md +0 -0
- /package/.morph/{standards → framework/standards}/backend/integrations/resend/resend-email.md +0 -0
- /package/.morph/{standards → framework/standards}/context/analytics.md +0 -0
- /package/.morph/{standards → framework/standards}/context/bundles.md +0 -0
- /package/.morph/{standards → framework/standards}/context/priming.md +0 -0
- /package/.morph/{standards → framework/standards}/core/architecture.md +0 -0
- /package/.morph/{standards → framework/standards}/core/coding.md +0 -0
- /package/.morph/{standards → framework/standards}/core/git-branching-strategy.md +0 -0
- /package/.morph/{standards → framework/standards}/core/git.md +0 -0
- /package/.morph/{standards → framework/standards}/core/testing.md +0 -0
- /package/.morph/{standards → framework/standards}/data/nosql/blob-storage.md +0 -0
- /package/.morph/{standards → framework/standards}/data/nosql/cache/redis.md +0 -0
- /package/.morph/{standards → framework/standards}/data/nosql/cosmos-db.md +0 -0
- /package/.morph/{standards → framework/standards}/data/vector-search/azure-ai-search.md +0 -0
- /package/.morph/{standards → framework/standards}/data/vector-search/rag-chunking.md +0 -0
- /package/.morph/{standards → framework/standards}/frontend/blazor/design-checklist.md +0 -0
- /package/.morph/{standards → framework/standards}/frontend/blazor/fluent-ui-setup.md +0 -0
- /package/.morph/{standards → framework/standards}/frontend/blazor/fluent-ui.md +0 -0
- /package/.morph/{standards → framework/standards}/frontend/blazor/html-conversion.md +0 -0
- /package/.morph/{standards → framework/standards}/frontend/blazor/lifecycle.md +0 -0
- /package/.morph/{standards → framework/standards}/frontend/blazor/pitfalls.md +0 -0
- /package/.morph/{standards → framework/standards}/frontend/blazor/state.md +0 -0
- /package/.morph/{standards → framework/standards}/frontend/design-system/animations.md +0 -0
- /package/.morph/{standards → framework/standards}/frontend/design-system/naming.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/azure/azure.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/azure/bicep/bicep-patterns.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/azure/devops/azure-devops-setup.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/azure/devops/local-development.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/azure/services/functions.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/azure/services/service-bus.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/azure/services/storage.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/docker/easypanel-deploy.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/supabase/mcp-setup.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-auth.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-pgvector.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-rls.md +0 -0
- /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-storage.md +0 -0
- /package/.morph/{standards → framework/standards}/integration/api/graphql.md +0 -0
- /package/.morph/{standards → framework/standards}/integration/api/grpc.md +0 -0
- /package/.morph/{standards → framework/standards}/integration/api/rest-design.md +0 -0
- /package/.morph/{standards → framework/standards}/integration/event-driven/cqrs.md +0 -0
- /package/.morph/{standards → framework/standards}/integration/event-driven/event-sourcing.md +0 -0
- /package/.morph/{standards → framework/standards}/integration/event-driven/service-bus.md +0 -0
- /package/.morph/{standards → framework/standards}/observability/logging.md +0 -0
- /package/.morph/{standards → framework/standards}/observability/metrics.md +0 -0
- /package/.morph/{standards → framework/standards}/observability/monitoring.md +0 -0
- /package/.morph/{standards → framework/standards}/observability/tracing.md +0 -0
- /package/.morph/{standards → framework/standards}/workflows/parallel-execution.md +0 -0
- /package/.morph/{standards → framework/standards}/workflows/thread-management.md +0 -0
- /package/.morph/{templates → framework/templates}/.idea/morph-templates.xml +0 -0
- /package/.morph/{templates → framework/templates}/.vscode/morph-templates.code-snippets +0 -0
- /package/.morph/{templates → framework/templates}/IDE-SNIPPETS.md +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/backend/repository.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/backend/service.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Commands.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Entities.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Queries.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/contracts/README.md +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/contracts/api-contracts.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/contracts/contracts.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/database/migration.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/frontend/component.razor +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/jobs/agent.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/jobs/job.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/dotnet/test.cs +0 -0
- /package/.morph/{templates → framework/templates}/code/sql/rls-policy.sql +0 -0
- /package/.morph/{templates → framework/templates}/code/sql/supabase-migration.sql +0 -0
- /package/.morph/{templates → framework/templates}/code/sql/supabase-migration.template.sql +0 -0
- /package/.morph/{templates → framework/templates}/code/typescript/contracts.ts +0 -0
- /package/.morph/{templates → framework/templates}/docs/proposal.md +0 -0
- /package/.morph/{templates → framework/templates}/examples/design-system-examples.md +0 -0
- /package/.morph/{templates → framework/templates}/feature/decisions.md +0 -0
- /package/.morph/{templates → framework/templates}/feature/recap.md +0 -0
- /package/.morph/{templates → framework/templates}/feature/tasks.md +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/Dockerfile.example +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/README.md +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/app-insights.bicep +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/app-service.bicep +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/container-app-env.bicep +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/container-app.bicep +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy-checklist.md +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy.ps1 +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy.sh +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/key-vault.bicep +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/main.bicep +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.dev.json +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.prod.json +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.staging.json +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/sql-database.bicep +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/azure/storage.bicep +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/docker/Dockerfile.template +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/docker/docker-compose.template.yml +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/docker/dockerfile-api.dockerfile +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/docker/dockerfile-web.dockerfile +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/docker/easypanel.template.json +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/github/actions/health-check/action.yml.hbs +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -0
- /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -0
- /package/.morph/{templates → framework/templates}/integrations/asaas-client.cs +0 -0
- /package/.morph/{templates → framework/templates}/integrations/asaas-webhook.cs +0 -0
- /package/.morph/{templates → framework/templates}/integrations/azure-identity-config.cs +0 -0
- /package/.morph/{templates → framework/templates}/integrations/clerk-config.cs +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/fusion/fusion-agent.md +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/fusion/fusion-aggregator.md +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-retry.md +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-validation.md +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-wrapper.md +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/parallel-workers/parallel-coordinator.md +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/backend-squad.md +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/frontend-squad.md +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/squad-leader.md +0 -0
- /package/.morph/{templates → framework/templates}/meta-prompts/validators/checkpoint-validator.md +0 -0
- /package/.morph/{templates → framework/templates}/saas/subscription.cs +0 -0
- /package/.morph/{templates → framework/templates}/saas/tenant.cs +0 -0
- /package/.morph/{templates → framework/templates}/state.template.json +0 -0
- /package/.morph/{templates → framework/templates}/ui/FluentDesignTheme.cs +0 -0
- /package/.morph/{templates → framework/templates}/ui/MudTheme.cs +0 -0
- /package/.morph/{templates → framework/templates}/ui/design-system.css +0 -0
- /package/framework/{skills/level-2-domains → agents}/README.md +0 -0
- /package/framework/hooks/{commit-msg → git/commit-msg}/conventional-commits.sh +0 -0
- /package/framework/hooks/{pre-commit → git/pre-commit}/agents.sh +0 -0
- /package/framework/hooks/{pre-commit → git/pre-commit}/orchestrator.sh +0 -0
- /package/framework/hooks/{pre-commit → git/pre-commit}/specs.sh +0 -0
- /package/framework/hooks/{pre-push → git/pre-push}/run-tests.sh +0 -0
|
@@ -4,7 +4,6 @@ import ora from 'ora';
|
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { logger } from '../../utils/logger.js';
|
|
6
6
|
import {
|
|
7
|
-
getContentDir,
|
|
8
7
|
copyDirectory,
|
|
9
8
|
copyFile,
|
|
10
9
|
pathExists,
|
|
@@ -13,20 +12,29 @@ import {
|
|
|
13
12
|
ensureDir,
|
|
14
13
|
writeFile,
|
|
15
14
|
readFile,
|
|
16
|
-
updateGitignore
|
|
17
|
-
createSymlink,
|
|
18
|
-
createDirectoryLink
|
|
15
|
+
updateGitignore
|
|
19
16
|
} from '../../utils/file-copier.js';
|
|
20
17
|
import { saveProjectMorphVersion, getInstalledCLIVersion } from '../../utils/version-checker.js';
|
|
21
|
-
import { installClaudeHooks } from '../../utils/
|
|
18
|
+
import { installClaudeHooks, installGlobalStatusline } from '../../utils/claude-settings-manager.js';
|
|
19
|
+
import { installSkills } from '../../utils/skills-installer.js';
|
|
20
|
+
import { installAgents, installDomainAgents } from '../../utils/agents-installer.js';
|
|
22
21
|
import { AutoContextOrchestrator } from '../../core/orchestrator.js';
|
|
23
22
|
import { detectClaudeCode } from '../../llm/environment-detector.js';
|
|
24
23
|
import inquirer from 'inquirer';
|
|
25
24
|
import { detectProject } from '../../lib/detectors/index.js';
|
|
25
|
+
import { detectClaudeConfig, mapMcpsToPhases, formatConfigSummary } from '../../lib/detectors/claude-config-detector.js';
|
|
26
|
+
import { generateSettings, saveIntegrations } from '../../lib/generators/settings-generator.js';
|
|
27
|
+
import {
|
|
28
|
+
orchestrateMcpSetup,
|
|
29
|
+
installAutoMcps,
|
|
30
|
+
installMcpWithCredentials,
|
|
31
|
+
generateSetupInstructions,
|
|
32
|
+
formatMcpStatusTable
|
|
33
|
+
} from '../../lib/installers/mcp-installer.js';
|
|
26
34
|
|
|
27
35
|
export async function initCommand(options) {
|
|
28
36
|
const targetPath = options.path || process.cwd();
|
|
29
|
-
const claudeMdPath = join(import.meta.dirname, '..', '..', '..', 'CLAUDE.md');
|
|
37
|
+
const claudeMdPath = join(import.meta.dirname, '..', '..', '..', 'framework', 'CLAUDE.md');
|
|
30
38
|
|
|
31
39
|
logger.header('MORPH-SPEC Framework Installation');
|
|
32
40
|
logger.dim(`Target: ${targetPath}`);
|
|
@@ -62,12 +70,14 @@ export async function initCommand(options) {
|
|
|
62
70
|
|
|
63
71
|
// 2. Create .morph directory structure
|
|
64
72
|
spinner.text = 'Creating .morph structure...';
|
|
65
|
-
const projectPath = join(morphPath, 'project');
|
|
66
73
|
const configDir = join(morphPath, 'config');
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
const frameworkDestDir = join(morphPath, 'framework');
|
|
75
|
+
const contextDir = join(morphPath, 'context');
|
|
76
|
+
const featuresDir = join(morphPath, 'features');
|
|
77
|
+
await ensureDir(contextDir);
|
|
78
|
+
await ensureDir(featuresDir);
|
|
70
79
|
await ensureDir(configDir);
|
|
80
|
+
await ensureDir(frameworkDestDir);
|
|
71
81
|
|
|
72
82
|
// 3. Create config.json
|
|
73
83
|
spinner.text = 'Generating config.json...';
|
|
@@ -87,7 +97,7 @@ export async function initCommand(options) {
|
|
|
87
97
|
|
|
88
98
|
// 4. Create context/README.md
|
|
89
99
|
spinner.text = 'Creating context README...';
|
|
90
|
-
const contextReadme = join(
|
|
100
|
+
const contextReadme = join(contextDir, 'README.md');
|
|
91
101
|
const readmeContent = `# ${dirName} - Project Context
|
|
92
102
|
|
|
93
103
|
## Overview
|
|
@@ -109,9 +119,8 @@ Run \`morph-spec detect\` to analyze your project.
|
|
|
109
119
|
await writeFile(contextReadme, readmeContent);
|
|
110
120
|
|
|
111
121
|
// 5. Copy framework templates (project-local overrides start from framework defaults)
|
|
112
|
-
const contentDir = getContentDir();
|
|
113
122
|
const frameworkTemplatesSrc = join(import.meta.dirname, '..', '..', '..', 'framework', 'templates');
|
|
114
|
-
const templatesDest = join(
|
|
123
|
+
const templatesDest = join(frameworkDestDir, 'templates');
|
|
115
124
|
let templatesCopied = false;
|
|
116
125
|
if (await pathExists(frameworkTemplatesSrc)) {
|
|
117
126
|
await copyDirectory(frameworkTemplatesSrc, templatesDest);
|
|
@@ -123,7 +132,7 @@ Run \`morph-spec detect\` to analyze your project.
|
|
|
123
132
|
// 6b. Copy framework standards hierarchy (universal standards)
|
|
124
133
|
spinner.text = 'Copying framework standards hierarchy...';
|
|
125
134
|
const frameworkStandardsSrc = join(import.meta.dirname, '..', '..', '..', 'framework', 'standards');
|
|
126
|
-
const frameworkStandardsDest = join(
|
|
135
|
+
const frameworkStandardsDest = join(frameworkDestDir, 'standards');
|
|
127
136
|
if (await pathExists(frameworkStandardsSrc)) {
|
|
128
137
|
// Copy entire hierarchy (core/, backend/, frontend/, infrastructure/)
|
|
129
138
|
await copyDirectory(frameworkStandardsSrc, frameworkStandardsDest);
|
|
@@ -133,32 +142,17 @@ Run \`morph-spec detect\` to analyze your project.
|
|
|
133
142
|
// 7. Copy agents.json (sourced from framework/ — canonical single source of truth)
|
|
134
143
|
spinner.text = 'Copying agents configuration...';
|
|
135
144
|
const agentsSrc = join(import.meta.dirname, '..', '..', '..', 'framework', 'agents.json');
|
|
136
|
-
const agentsDest = join(
|
|
145
|
+
const agentsDest = join(frameworkDestDir, 'agents.json');
|
|
137
146
|
if (await pathExists(agentsSrc)) {
|
|
138
147
|
await copyFile(agentsSrc, agentsDest);
|
|
139
148
|
}
|
|
140
149
|
|
|
141
|
-
// 8. Copy
|
|
142
|
-
spinner.text = 'Copying Azure pricing data...';
|
|
143
|
-
const pricingSrc = join(contentDir, '.morph', 'config', 'azure-pricing.json');
|
|
144
|
-
const pricingDest = join(configDir, 'azure-pricing.json');
|
|
145
|
-
if (await pathExists(pricingSrc)) {
|
|
146
|
-
await copyFile(pricingSrc, pricingDest);
|
|
147
|
-
}
|
|
148
|
-
const pricingSchemaSrc = join(contentDir, '.morph', 'config', 'azure-pricing.schema.json');
|
|
149
|
-
const pricingSchemaDest = join(configDir, 'azure-pricing.schema.json');
|
|
150
|
-
if (await pathExists(pricingSchemaSrc)) {
|
|
151
|
-
await copyFile(pricingSchemaSrc, pricingSchemaDest);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// 9. Copy .claude commands and create symlinks for skills
|
|
150
|
+
// 8. Copy .claude commands and install skills
|
|
155
151
|
// Source: framework/ (canonical for all stacks)
|
|
156
152
|
spinner.text = 'Setting up Claude Code integration...';
|
|
157
153
|
const frameworkDir = join(import.meta.dirname, '..', '..', '..', 'framework');
|
|
158
154
|
const claudeDest = join(targetPath, '.claude');
|
|
159
155
|
|
|
160
|
-
let symlinkCount = 0;
|
|
161
|
-
let copyCount = 0;
|
|
162
156
|
let commandsCopied = false;
|
|
163
157
|
|
|
164
158
|
// Copy commands directory (slash commands): framework/commands/ → .claude/commands/
|
|
@@ -171,58 +165,48 @@ Run \`morph-spec detect\` to analyze your project.
|
|
|
171
165
|
logger.warn(' ⚠ framework/commands/ source missing — commands not installed');
|
|
172
166
|
}
|
|
173
167
|
|
|
174
|
-
//
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const entries = await fs.readdir(skillsSrc, { withFileTypes: true });
|
|
184
|
-
|
|
185
|
-
let linkedCategories = 0;
|
|
186
|
-
let copiedCategories = 0;
|
|
187
|
-
let totalSkillFiles = 0;
|
|
188
|
-
|
|
189
|
-
// Link category directories (specialists/, infra/, checklists/, etc.)
|
|
190
|
-
for (const entry of entries) {
|
|
191
|
-
if (entry.isDirectory()) {
|
|
192
|
-
const categorySrc = join(skillsSrc, entry.name);
|
|
193
|
-
const categoryDest = join(skillsDest, entry.name);
|
|
194
|
-
|
|
195
|
-
// Count .md files for reporting
|
|
196
|
-
const categoryEntries = await fs.readdir(categorySrc, { withFileTypes: true });
|
|
197
|
-
const mdFiles = categoryEntries.filter(e => e.isFile() && e.name.endsWith('.md'));
|
|
198
|
-
totalSkillFiles += mdFiles.length;
|
|
199
|
-
|
|
200
|
-
const result = await createDirectoryLink(categorySrc, categoryDest);
|
|
201
|
-
if (result === 'copy') {
|
|
202
|
-
copiedCategories++;
|
|
203
|
-
} else {
|
|
204
|
-
linkedCategories++;
|
|
205
|
-
}
|
|
206
|
-
} else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
207
|
-
// Handle .md files in skills root
|
|
208
|
-
totalSkillFiles++;
|
|
209
|
-
const result = await createSymlink(join(skillsSrc, entry.name), join(skillsDest, entry.name), 'file');
|
|
210
|
-
if (result === 'symlink') {
|
|
211
|
-
linkedCategories++;
|
|
212
|
-
} else {
|
|
213
|
-
copiedCategories++;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
168
|
+
// 9a. Install path-scoped rules to .claude/rules/ (native Claude Code pattern)
|
|
169
|
+
spinner.text = 'Installing path-scoped rules to .claude/rules/...';
|
|
170
|
+
const rulesSrc = join(frameworkDir, 'rules');
|
|
171
|
+
const rulesDest = join(claudeDest, 'rules');
|
|
172
|
+
let rulesCopied = false;
|
|
173
|
+
if (await pathExists(rulesSrc)) {
|
|
174
|
+
await copyDirectory(rulesSrc, rulesDest);
|
|
175
|
+
rulesCopied = true;
|
|
176
|
+
}
|
|
217
177
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
178
|
+
// 9b. Install morph skills to .claude/skills/ for native Claude Code discovery
|
|
179
|
+
spinner.text = 'Installing morph skills to .claude/skills/...';
|
|
180
|
+
await installSkills(targetPath);
|
|
181
|
+
|
|
182
|
+
// 9b2. Install tier-1/2 agents as native Claude Code subagents in .claude/agents/
|
|
183
|
+
spinner.text = 'Installing native subagents to .claude/agents/...';
|
|
184
|
+
await installAgents(targetPath, frameworkDir);
|
|
185
|
+
|
|
186
|
+
// 9b2b. Install level-2 domain agents as native Claude Code subagents in .claude/agents/
|
|
187
|
+
await installDomainAgents(targetPath, frameworkDir);
|
|
188
|
+
|
|
189
|
+
// 9b3. Install runtime CLAUDE.md to .claude/CLAUDE.md (Claude Code runtime instructions)
|
|
190
|
+
spinner.text = 'Installing .claude/CLAUDE.md...';
|
|
191
|
+
const runtimeClaudeMdSrc = join(frameworkDir, 'CLAUDE.md');
|
|
192
|
+
const runtimeClaudeMdDest = join(claudeDest, 'CLAUDE.md');
|
|
193
|
+
if (await pathExists(runtimeClaudeMdSrc)) {
|
|
194
|
+
await copyFile(runtimeClaudeMdSrc, runtimeClaudeMdDest);
|
|
221
195
|
}
|
|
222
196
|
|
|
223
|
-
//
|
|
197
|
+
// 9c. Install statusline globally to ~/.claude/ (applies to all Claude Code sessions)
|
|
198
|
+
spinner.text = 'Installing statusline globally to ~/.claude/...';
|
|
199
|
+
const HOOKS_SRC = join(import.meta.dirname, '..', '..', '..', 'framework', 'hooks', 'claude-code');
|
|
200
|
+
try {
|
|
201
|
+
await installGlobalStatusline(HOOKS_SRC);
|
|
202
|
+
} catch {
|
|
203
|
+
// Non-critical: global dir may not be writable in all environments
|
|
204
|
+
logger.dim(' ⚠ Could not install statusline globally (non-critical)');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// 9d. Install/update Claude Code hooks in .claude/settings.local.json
|
|
224
208
|
spinner.text = 'Installing Claude Code hooks...';
|
|
225
|
-
const
|
|
209
|
+
const hooksResult = await installClaudeHooks(targetPath);
|
|
226
210
|
|
|
227
211
|
// 10. Save version info
|
|
228
212
|
spinner.text = 'Saving version info...';
|
|
@@ -233,89 +217,281 @@ Run \`morph-spec detect\` to analyze your project.
|
|
|
233
217
|
spinner.text = 'Updating .gitignore...';
|
|
234
218
|
await updateGitignore(targetPath);
|
|
235
219
|
|
|
236
|
-
|
|
220
|
+
// 11b. Detect Claude Code environment (plugins, MCPs, skills)
|
|
221
|
+
spinner.text = 'Detecting Claude Code environment...';
|
|
222
|
+
let claudeConfigDetected = null;
|
|
223
|
+
let integrationsCreated = false;
|
|
224
|
+
try {
|
|
225
|
+
claudeConfigDetected = await detectClaudeConfig(targetPath);
|
|
226
|
+
const hasIntegrations = claudeConfigDetected.plugins.length > 0
|
|
227
|
+
|| claudeConfigDetected.mcpServers.length > 0
|
|
228
|
+
|| claudeConfigDetected.superpowers.installed;
|
|
229
|
+
|
|
230
|
+
if (hasIntegrations) {
|
|
231
|
+
spinner.stop();
|
|
232
|
+
logger.blank();
|
|
233
|
+
logger.header('Claude Code Environment Detected');
|
|
234
|
+
|
|
235
|
+
const summary = formatConfigSummary(claudeConfigDetected);
|
|
236
|
+
if (summary) {
|
|
237
|
+
logger.info(summary);
|
|
238
|
+
}
|
|
237
239
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
240
|
+
// Show MCP-to-phase mapping
|
|
241
|
+
if (claudeConfigDetected.mcpServers.length > 0) {
|
|
242
|
+
const phaseMap = mapMcpsToPhases(claudeConfigDetected.mcpServers);
|
|
243
|
+
logger.blank();
|
|
244
|
+
logger.dim('MCP usage by phase:');
|
|
245
|
+
for (const [phase, mcps] of Object.entries(phaseMap)) {
|
|
246
|
+
if (mcps.length > 0) {
|
|
247
|
+
logger.dim(` ${phase}: ${mcps.map(m => m.name).join(', ')}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
243
251
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
]);
|
|
252
|
-
logger.blank();
|
|
252
|
+
logger.blank();
|
|
253
|
+
const { saveIntegrationsChoice } = await inquirer.prompt([{
|
|
254
|
+
type: 'confirm',
|
|
255
|
+
name: 'saveIntegrationsChoice',
|
|
256
|
+
message: 'Save detected integrations and generate optimized settings?',
|
|
257
|
+
default: true
|
|
258
|
+
}]);
|
|
253
259
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if (symlinkCount > 0) {
|
|
268
|
-
const linkType = process.platform === 'win32' ? 'junction-linked' : 'symlinked';
|
|
269
|
-
logger.dim(` ✓ .claude/skills/ (${symlinkCount} ${linkType})`);
|
|
270
|
-
} else if (copyCount > 0) {
|
|
271
|
-
logger.dim(` ✓ .claude/skills/ (${copyCount} copied)`);
|
|
272
|
-
logger.warn(` ⚠ Directory links not supported (copied instead). Skills won't auto-update.`);
|
|
260
|
+
if (saveIntegrationsChoice) {
|
|
261
|
+
spinner.start('Saving integrations...');
|
|
262
|
+
await saveIntegrations(targetPath, claudeConfigDetected);
|
|
263
|
+
await generateSettings(targetPath, claudeConfigDetected, config);
|
|
264
|
+
integrationsCreated = true;
|
|
265
|
+
spinner.succeed('Integrations saved to .morph/config/integrations.json');
|
|
266
|
+
} else {
|
|
267
|
+
spinner.start('Continuing...');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
} catch (error) {
|
|
271
|
+
// Non-fatal: continue without integrations
|
|
272
|
+
logger.dim(` Claude config detection skipped: ${error.message}`);
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
275
|
+
// 11c. Stack detection (moved before MCP setup so we know the stack)
|
|
276
|
+
spinner.text = 'Detecting project stack...';
|
|
277
|
+
let detectedStack = 'unknown';
|
|
278
278
|
const hasProjectFiles = await pathExists(join(targetPath, 'package.json'))
|
|
279
279
|
|| await pathExists(join(targetPath, 'src'))
|
|
280
280
|
|| (await fs.readdir(targetPath)).some(f => f.endsWith('.csproj'));
|
|
281
281
|
|
|
282
282
|
if (hasProjectFiles) {
|
|
283
|
-
logger.blank();
|
|
284
|
-
logger.header('Existing Project Detected');
|
|
285
|
-
|
|
286
283
|
try {
|
|
287
284
|
const quickResults = await detectProject(targetPath, { conversation: false, generateStandards: false });
|
|
288
285
|
const structure = quickResults.structure;
|
|
289
286
|
|
|
290
287
|
if (structure?.stack && structure.stack !== 'unknown') {
|
|
288
|
+
detectedStack = structure.stack;
|
|
289
|
+
spinner.stop();
|
|
290
|
+
logger.blank();
|
|
291
|
+
logger.header('Existing Project Detected');
|
|
291
292
|
logger.info(`Stack detected: ${structure.stack}`);
|
|
292
293
|
if (structure?.architecture) logger.dim(`Architecture: ${structure.architecture}`);
|
|
293
294
|
if (structure?.uiLibrary) logger.dim(`UI Library: ${structure.uiLibrary}`);
|
|
295
|
+
|
|
296
|
+
const { standardsChoice } = await inquirer.prompt([{
|
|
297
|
+
type: 'list',
|
|
298
|
+
name: 'standardsChoice',
|
|
299
|
+
message: 'How should morph-spec handle your project standards?',
|
|
300
|
+
choices: [
|
|
301
|
+
{ name: 'Keep morph-spec defaults (recommended)', value: 'morph-spec' },
|
|
302
|
+
{ name: 'Detect project-specific standards', value: 'detect' }
|
|
303
|
+
]
|
|
304
|
+
}]);
|
|
305
|
+
|
|
306
|
+
if (standardsChoice === 'detect') {
|
|
307
|
+
spinner.start('Generating project-specific standards...');
|
|
308
|
+
const fullResults = await detectProject(targetPath, { conversation: false });
|
|
309
|
+
const inferredPath = join(contextDir, 'standards.md');
|
|
310
|
+
await writeFile(inferredPath, fullResults.inferred.markdown);
|
|
311
|
+
spinner.succeed('Generated .morph/context/standards.md');
|
|
312
|
+
logger.dim('Review and edit .morph/context/standards.md as needed.');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
spinner.start('Continuing...');
|
|
294
316
|
}
|
|
317
|
+
} catch (error) {
|
|
318
|
+
logger.dim(` Stack detection skipped: ${error.message}`);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
295
321
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
322
|
+
// 11d. MCP Auto-Setup
|
|
323
|
+
let mcpSetupResult = null;
|
|
324
|
+
if (!options.skipMcp) {
|
|
325
|
+
try {
|
|
326
|
+
spinner.stop();
|
|
327
|
+
const existingMcps = claudeConfigDetected?.mcpServers || [];
|
|
328
|
+
const orchestration = orchestrateMcpSetup(targetPath, detectedStack, existingMcps);
|
|
329
|
+
|
|
330
|
+
const autoNames = Object.keys(orchestration.autoInstallable);
|
|
331
|
+
const manualNames = Object.keys(orchestration.needsManualSetup);
|
|
332
|
+
const hasAutoMcps = autoNames.length > 0;
|
|
333
|
+
const hasManualMcps = manualNames.length > 0;
|
|
334
|
+
|
|
335
|
+
if (hasAutoMcps || hasManualMcps) {
|
|
336
|
+
logger.blank();
|
|
337
|
+
logger.header('MCP Server Setup');
|
|
338
|
+
|
|
339
|
+
// Auto-install prompt
|
|
340
|
+
let autoInstalled = {};
|
|
341
|
+
if (hasAutoMcps) {
|
|
342
|
+
const { installAuto } = await inquirer.prompt([{
|
|
343
|
+
type: 'confirm',
|
|
344
|
+
name: 'installAuto',
|
|
345
|
+
message: `Install recommended MCP servers? (${autoNames.join(', ')})`,
|
|
346
|
+
default: true
|
|
347
|
+
}]);
|
|
348
|
+
|
|
349
|
+
if (installAuto) {
|
|
350
|
+
spinner.start('Installing MCP servers...');
|
|
351
|
+
const result = await installAutoMcps(targetPath, orchestration.autoInstallable);
|
|
352
|
+
spinner.succeed(`Installed ${result.added.length} MCP server(s)`);
|
|
353
|
+
for (const name of result.added) {
|
|
354
|
+
autoInstalled[name] = orchestration.autoInstallable[name];
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Credential MCPs — inline setup or instructions
|
|
360
|
+
const manualInstalled = {};
|
|
361
|
+
if (hasManualMcps) {
|
|
362
|
+
for (const [name, entry] of Object.entries(orchestration.needsManualSetup)) {
|
|
363
|
+
logger.blank();
|
|
364
|
+
|
|
365
|
+
// Show warnings
|
|
366
|
+
for (const warning of entry.install.warnings || []) {
|
|
367
|
+
logger.warn(` ${warning}`);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
371
|
+
const { setupNow } = await inquirer.prompt([{
|
|
372
|
+
type: 'confirm',
|
|
373
|
+
name: 'setupNow',
|
|
374
|
+
message: `Set up ${capitalizedName} MCP now? (${entry.usage})`,
|
|
375
|
+
default: false
|
|
376
|
+
}]);
|
|
377
|
+
|
|
378
|
+
if (setupNow) {
|
|
379
|
+
// Collect credentials
|
|
380
|
+
const credentialValues = {};
|
|
381
|
+
for (const cred of entry.install.credentials) {
|
|
382
|
+
const { value } = await inquirer.prompt([{
|
|
383
|
+
type: cred.secret ? 'password' : 'input',
|
|
384
|
+
name: 'value',
|
|
385
|
+
message: `${cred.name}:`,
|
|
386
|
+
mask: cred.secret ? '*' : undefined
|
|
387
|
+
}]);
|
|
388
|
+
credentialValues[cred.envVar] = value;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
spinner.start(`Configuring ${name}...`);
|
|
392
|
+
await installMcpWithCredentials(targetPath, name, entry, credentialValues);
|
|
393
|
+
spinner.succeed(`${capitalizedName} MCP configured`);
|
|
394
|
+
manualInstalled[name] = entry;
|
|
395
|
+
} else {
|
|
396
|
+
// Show setup instructions
|
|
397
|
+
const instructions = generateSetupInstructions(name, entry);
|
|
398
|
+
logger.blank();
|
|
399
|
+
logger.dim(' Add to .claude/settings.local.json → mcpServers:');
|
|
400
|
+
logger.dim(' ' + '─'.repeat(55));
|
|
401
|
+
for (const line of instructions.configSnippet.split('\n')) {
|
|
402
|
+
logger.dim(` ${line}`);
|
|
403
|
+
}
|
|
404
|
+
logger.dim(' ' + '─'.repeat(55));
|
|
405
|
+
|
|
406
|
+
for (const cred of instructions.credentialUrls) {
|
|
407
|
+
logger.dim(` Get ${cred.name}: ${cred.helpUrl}`);
|
|
408
|
+
}
|
|
409
|
+
logger.dim(` Or run later: ${instructions.cliCommand}`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Summary table
|
|
415
|
+
const justInstalled = { ...autoInstalled, ...manualInstalled };
|
|
416
|
+
const statusRows = formatMcpStatusTable(orchestration, justInstalled);
|
|
417
|
+
|
|
418
|
+
if (statusRows.length > 0) {
|
|
419
|
+
logger.blank();
|
|
420
|
+
logger.info('MCP Servers');
|
|
421
|
+
logger.dim('─'.repeat(60));
|
|
422
|
+
|
|
423
|
+
const STATUS_ICONS = {
|
|
424
|
+
installed: '✓',
|
|
425
|
+
available: '○',
|
|
426
|
+
already_configured: '✓',
|
|
427
|
+
needs_setup: '⚠',
|
|
428
|
+
prereq_missing: '✗',
|
|
429
|
+
not_relevant: '─'
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
for (const row of statusRows) {
|
|
433
|
+
const icon = STATUS_ICONS[row.status] || '?';
|
|
434
|
+
const statusLabel = row.status.replace(/_/g, ' ');
|
|
435
|
+
logger.dim(` ${icon} ${row.name.padEnd(15)} ${statusLabel.padEnd(20)} ${row.detail}`);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
305
438
|
|
|
306
|
-
|
|
307
|
-
spinner.start('Generating project-specific standards...');
|
|
308
|
-
const fullResults = await detectProject(targetPath, { conversation: false });
|
|
309
|
-
const inferredPath = join(morphPath, 'project', 'standards', 'inferred.md');
|
|
310
|
-
await writeFile(inferredPath, fullResults.inferred.markdown);
|
|
311
|
-
spinner.succeed('Generated .morph/project/standards/inferred.md');
|
|
312
|
-
logger.dim('Review and edit .morph/project/standards/inferred.md as needed.');
|
|
439
|
+
mcpSetupResult = { autoInstalled, manualInstalled, orchestration };
|
|
313
440
|
}
|
|
314
441
|
} catch (error) {
|
|
315
|
-
logger.
|
|
442
|
+
logger.dim(` MCP setup skipped: ${error.message}`);
|
|
443
|
+
}
|
|
444
|
+
} else {
|
|
445
|
+
logger.dim('\nSkipped MCP setup (--skip-mcp flag)');
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
spinner.succeed('MORPH-SPEC installed successfully!');
|
|
449
|
+
|
|
450
|
+
// Show next steps
|
|
451
|
+
logger.blank();
|
|
452
|
+
logger.success(`MORPH-SPEC v${cliVersion} installed successfully!`);
|
|
453
|
+
logger.blank();
|
|
454
|
+
logger.header('Next Steps');
|
|
455
|
+
|
|
456
|
+
logger.step(1, 'Run detection: morph-spec detect');
|
|
457
|
+
logger.step(2, 'Review .morph/config/config.json and .morph/context/standards.md');
|
|
458
|
+
logger.step(3, 'Open project in VS Code with Claude Code');
|
|
459
|
+
logger.step(4, 'Start your first feature:');
|
|
460
|
+
logger.blank();
|
|
461
|
+
logger.box([
|
|
462
|
+
'Ask Claude Code to implement a feature'
|
|
463
|
+
]);
|
|
464
|
+
logger.blank();
|
|
465
|
+
|
|
466
|
+
logger.info('Files installed:');
|
|
467
|
+
logger.dim(` ✓ CLAUDE.md`);
|
|
468
|
+
logger.dim(` ✓ .morph/config/ (config.json)`);
|
|
469
|
+
logger.dim(` ✓ .morph/framework/ (agents.json, standards/, templates/)`);
|
|
470
|
+
logger.dim(` ✓ .morph/context/ (project context)`);
|
|
471
|
+
logger.dim(` ✓ .morph/features/ (feature outputs)`);
|
|
472
|
+
if (commandsCopied) {
|
|
473
|
+
logger.dim(` ✓ .claude/commands/ (slash commands)`);
|
|
474
|
+
}
|
|
475
|
+
if (rulesCopied) {
|
|
476
|
+
logger.dim(` ✓ .claude/rules/ (5 path-scoped rules)`);
|
|
477
|
+
}
|
|
478
|
+
logger.dim(` ✓ .claude/settings.local.json (${hooksResult.installed} hooks installed)`);
|
|
479
|
+
if (integrationsCreated) {
|
|
480
|
+
logger.dim(` ✓ .morph/config/integrations.json (detected plugins & MCPs)`);
|
|
481
|
+
}
|
|
482
|
+
if (mcpSetupResult) {
|
|
483
|
+
const autoCount = Object.keys(mcpSetupResult.autoInstalled).length;
|
|
484
|
+
const manualCount = Object.keys(mcpSetupResult.manualInstalled).length;
|
|
485
|
+
if (autoCount + manualCount > 0) {
|
|
486
|
+
logger.dim(` ✓ MCP servers (${autoCount + manualCount} configured)`);
|
|
316
487
|
}
|
|
317
488
|
}
|
|
318
489
|
|
|
490
|
+
logger.dim(' ✓ .claude/skills/ (installed as skill directories)');
|
|
491
|
+
logger.dim(' ✓ .claude/agents/ (native subagents installed)');
|
|
492
|
+
|
|
493
|
+
logger.blank();
|
|
494
|
+
|
|
319
495
|
// 13. LLM-based auto-detect project context (if Claude Code is available and not --skip-detection)
|
|
320
496
|
if (!options.skipDetection && detectClaudeCode()) {
|
|
321
497
|
logger.blank();
|
|
@@ -349,6 +525,12 @@ Run \`morph-spec detect\` to analyze your project.
|
|
|
349
525
|
logger.dim('Run "morph-spec update --wizard" to configure manually.');
|
|
350
526
|
}
|
|
351
527
|
|
|
528
|
+
// Suggest tutorial for first-time users
|
|
529
|
+
if (integrationsCreated) {
|
|
530
|
+
logger.blank();
|
|
531
|
+
logger.info('First time using morph-spec? Run `morph-spec tutorial` to get started.');
|
|
532
|
+
}
|
|
533
|
+
|
|
352
534
|
logger.blank();
|
|
353
535
|
|
|
354
536
|
} catch (error) {
|