@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
|
@@ -28,7 +28,7 @@ export async function generateRecap(projectPath, featureName, options = {}) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
const feature = state.features[featureName];
|
|
31
|
-
const outputsPath = join(projectPath, '.morph/
|
|
31
|
+
const outputsPath = join(projectPath, '.morph/features', featureName);
|
|
32
32
|
|
|
33
33
|
// Gather data
|
|
34
34
|
const tasksSummary = getTasksSummary(feature);
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates .claude/settings.local.json for projects based on detected
|
|
5
|
+
* stack, MCPs, and morph-spec configuration. Uses _morph_managed marker
|
|
6
|
+
* to track managed entries for safe reset.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { existsSync } from 'fs';
|
|
11
|
+
import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
12
|
+
|
|
13
|
+
const MORPH_MANAGED_KEY = '_morph_managed';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Generate and merge settings for a project
|
|
17
|
+
* @param {string} targetPath - Project root directory
|
|
18
|
+
* @param {Object} detectedConfig - Output from detectClaudeConfig()
|
|
19
|
+
* @param {Object} morphConfig - morph-spec config (from .morph/config/config.json)
|
|
20
|
+
* @returns {Promise<Object>} Generated settings summary
|
|
21
|
+
*/
|
|
22
|
+
export async function generateSettings(targetPath, detectedConfig, morphConfig = {}) {
|
|
23
|
+
const claudeDir = join(targetPath, '.claude');
|
|
24
|
+
const settingsPath = join(claudeDir, 'settings.local.json');
|
|
25
|
+
|
|
26
|
+
// Read existing settings
|
|
27
|
+
const existing = await readSettingsSafe(settingsPath);
|
|
28
|
+
|
|
29
|
+
// Build stack-based permissions
|
|
30
|
+
const stack = morphConfig?.project?.architecture || 'unknown';
|
|
31
|
+
const permissions = buildPermissions(stack, detectedConfig);
|
|
32
|
+
|
|
33
|
+
// Build generated settings
|
|
34
|
+
const generated = {};
|
|
35
|
+
|
|
36
|
+
if (permissions.length > 0) {
|
|
37
|
+
generated.permissions = permissions;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Track what we manage
|
|
41
|
+
const managed = {
|
|
42
|
+
permissions_added: permissions,
|
|
43
|
+
mcps_detected: detectedConfig.mcpServers.map(s => s.name),
|
|
44
|
+
plugins_detected: detectedConfig.plugins.map(p => p.name),
|
|
45
|
+
generated_at: new Date().toISOString()
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Merge without overwriting user config
|
|
49
|
+
const merged = mergeSettings(existing, generated);
|
|
50
|
+
merged[MORPH_MANAGED_KEY] = managed;
|
|
51
|
+
|
|
52
|
+
// Ensure directory exists
|
|
53
|
+
if (!existsSync(claudeDir)) {
|
|
54
|
+
await mkdir(claudeDir, { recursive: true });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
await writeFile(settingsPath, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
settingsPath,
|
|
61
|
+
permissionsAdded: permissions.length,
|
|
62
|
+
managed
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Build permission rules based on detected stack
|
|
68
|
+
* @param {string} stack - Detected project stack
|
|
69
|
+
* @param {Object} detectedConfig - Detected Claude config
|
|
70
|
+
* @returns {Array<string>} Permission patterns
|
|
71
|
+
*/
|
|
72
|
+
export function buildPermissions(stack, detectedConfig = {}) {
|
|
73
|
+
const permissions = [];
|
|
74
|
+
|
|
75
|
+
// Stack-based permissions
|
|
76
|
+
const stackPermissions = {
|
|
77
|
+
nodejs: ['Bash(node:*)', 'Bash(npm:*)', 'Bash(npx:*)'],
|
|
78
|
+
typescript: ['Bash(node:*)', 'Bash(npm:*)', 'Bash(npx:*)', 'Bash(tsc:*)'],
|
|
79
|
+
nextjs: ['Bash(node:*)', 'Bash(npm:*)', 'Bash(npx:*)'],
|
|
80
|
+
react: ['Bash(node:*)', 'Bash(npm:*)', 'Bash(npx:*)'],
|
|
81
|
+
vue: ['Bash(node:*)', 'Bash(npm:*)', 'Bash(npx:*)'],
|
|
82
|
+
dotnet: ['Bash(dotnet:*)', 'Bash(nuget:*)'],
|
|
83
|
+
blazor: ['Bash(dotnet:*)', 'Bash(nuget:*)'],
|
|
84
|
+
python: ['Bash(python:*)', 'Bash(pip:*)', 'Bash(pytest:*)'],
|
|
85
|
+
go: ['Bash(go:*)']
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
if (stackPermissions[stack]) {
|
|
89
|
+
permissions.push(...stackPermissions[stack]);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// morph-spec CLI always needs node/npx
|
|
93
|
+
if (!permissions.includes('Bash(npx:*)')) {
|
|
94
|
+
permissions.push('Bash(npx:*)');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return permissions;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Deep merge settings without overwriting user entries
|
|
102
|
+
* @param {Object} existing - Current settings.local.json
|
|
103
|
+
* @param {Object} generated - Generated settings to merge
|
|
104
|
+
* @returns {Object} Merged settings
|
|
105
|
+
*/
|
|
106
|
+
export function mergeSettings(existing, generated) {
|
|
107
|
+
const result = { ...existing };
|
|
108
|
+
|
|
109
|
+
for (const [key, value] of Object.entries(generated)) {
|
|
110
|
+
if (key === MORPH_MANAGED_KEY) continue;
|
|
111
|
+
|
|
112
|
+
if (Array.isArray(value) && Array.isArray(result[key])) {
|
|
113
|
+
// Merge arrays without duplicates
|
|
114
|
+
const set = new Set(result[key]);
|
|
115
|
+
for (const item of value) {
|
|
116
|
+
set.add(item);
|
|
117
|
+
}
|
|
118
|
+
result[key] = [...set];
|
|
119
|
+
} else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
120
|
+
// Recursively merge objects
|
|
121
|
+
result[key] = mergeSettings(result[key] || {}, value);
|
|
122
|
+
} else if (!(key in result)) {
|
|
123
|
+
// Only add new keys, never overwrite existing
|
|
124
|
+
result[key] = value;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Remove only morph-spec managed entries from settings
|
|
133
|
+
* @param {string} settingsPath - Path to settings.local.json
|
|
134
|
+
* @returns {Promise<Object>} Summary of what was removed
|
|
135
|
+
*/
|
|
136
|
+
export async function resetMorphSettings(settingsPath) {
|
|
137
|
+
if (!existsSync(settingsPath)) {
|
|
138
|
+
return { removed: false, reason: 'file not found' };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const settings = await readSettingsSafe(settingsPath);
|
|
142
|
+
const managed = settings[MORPH_MANAGED_KEY];
|
|
143
|
+
|
|
144
|
+
if (!managed) {
|
|
145
|
+
return { removed: false, reason: 'no _morph_managed section found' };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Remove managed permissions
|
|
149
|
+
if (managed.permissions_added && Array.isArray(settings.permissions)) {
|
|
150
|
+
settings.permissions = settings.permissions.filter(
|
|
151
|
+
p => !managed.permissions_added.includes(p)
|
|
152
|
+
);
|
|
153
|
+
if (settings.permissions.length === 0) {
|
|
154
|
+
delete settings.permissions;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Remove the managed marker itself
|
|
159
|
+
delete settings[MORPH_MANAGED_KEY];
|
|
160
|
+
|
|
161
|
+
// Write back
|
|
162
|
+
await writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
removed: true,
|
|
166
|
+
permissionsRemoved: managed.permissions_added || [],
|
|
167
|
+
previouslyGenerated: managed.generated_at
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Save integrations.json with detected config
|
|
173
|
+
* @param {string} targetPath - Project root directory
|
|
174
|
+
* @param {Object} detectedConfig - Output from detectClaudeConfig()
|
|
175
|
+
*/
|
|
176
|
+
export async function saveIntegrations(targetPath, detectedConfig) {
|
|
177
|
+
const integrationsPath = join(targetPath, '.morph', 'config', 'integrations.json');
|
|
178
|
+
const integrationsDir = join(targetPath, '.morph', 'config');
|
|
179
|
+
|
|
180
|
+
if (!existsSync(integrationsDir)) {
|
|
181
|
+
await mkdir(integrationsDir, { recursive: true });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const integrations = {
|
|
185
|
+
version: '1.0.0',
|
|
186
|
+
detectedAt: new Date().toISOString(),
|
|
187
|
+
plugins: detectedConfig.plugins,
|
|
188
|
+
mcpServers: detectedConfig.mcpServers,
|
|
189
|
+
superpowers: detectedConfig.superpowers,
|
|
190
|
+
customSkills: detectedConfig.customSkills.length,
|
|
191
|
+
customCommands: detectedConfig.customCommands.length,
|
|
192
|
+
hooks: detectedConfig.hooks.length
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
await writeFile(integrationsPath, JSON.stringify(integrations, null, 2) + '\n', 'utf-8');
|
|
196
|
+
return integrationsPath;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ============================================================================
|
|
200
|
+
// Helpers
|
|
201
|
+
// ============================================================================
|
|
202
|
+
|
|
203
|
+
async function readSettingsSafe(settingsPath) {
|
|
204
|
+
try {
|
|
205
|
+
if (!existsSync(settingsPath)) return {};
|
|
206
|
+
return JSON.parse(await readFile(settingsPath, 'utf-8'));
|
|
207
|
+
} catch {
|
|
208
|
+
return {};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Installer
|
|
3
|
+
*
|
|
4
|
+
* Core logic for installing and configuring MCP servers during morph-spec init
|
|
5
|
+
* and via `morph-spec mcp setup`. Handles auto-installable (credential-free)
|
|
6
|
+
* MCPs, prerequisite checking, credential collection, and setup guidance.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { readFileSync, existsSync } from 'fs';
|
|
11
|
+
import { execSync } from 'child_process';
|
|
12
|
+
import { installMcpServers } from '../../utils/claude-settings-manager.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Load the enhanced MCP registry (v2.0.0)
|
|
16
|
+
* @returns {Object} Registry with install blocks
|
|
17
|
+
*/
|
|
18
|
+
export function loadMcpRegistry() {
|
|
19
|
+
const registryPath = join(
|
|
20
|
+
import.meta.dirname, '..', '..', '..', 'framework', 'skills', 'level-0-meta', 'mcp-registry.json'
|
|
21
|
+
);
|
|
22
|
+
const raw = readFileSync(registryPath, 'utf-8');
|
|
23
|
+
return JSON.parse(raw);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Filter MCPs by stack relevance
|
|
28
|
+
* @param {Object} registry - Full MCP registry
|
|
29
|
+
* @param {string} stack - Detected project stack (e.g., 'nextjs-supabase', 'blazor')
|
|
30
|
+
* @returns {Object} Filtered map of mcpName → mcpEntry
|
|
31
|
+
*/
|
|
32
|
+
export function filterByStack(registry, stack) {
|
|
33
|
+
const result = {};
|
|
34
|
+
const normalizedStack = (stack || '').toLowerCase();
|
|
35
|
+
|
|
36
|
+
for (const [name, entry] of Object.entries(registry.mcps)) {
|
|
37
|
+
if (!entry.install) continue;
|
|
38
|
+
const relevance = entry.install.stackRelevance || [];
|
|
39
|
+
|
|
40
|
+
if (relevance.includes('*')) {
|
|
41
|
+
result[name] = entry;
|
|
42
|
+
} else if (normalizedStack && relevance.some(s => normalizedStack.includes(s))) {
|
|
43
|
+
result[name] = entry;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Match detected MCP servers against the registry
|
|
52
|
+
* @param {Array} existingServers - From detectClaudeConfig().mcpServers
|
|
53
|
+
* @param {Object} registry - MCP registry
|
|
54
|
+
* @returns {Object} Map of mcpName → { installed: true, source }
|
|
55
|
+
*/
|
|
56
|
+
export function getInstalledMcps(existingServers, registry) {
|
|
57
|
+
const installed = {};
|
|
58
|
+
const registryNames = Object.keys(registry.mcps);
|
|
59
|
+
|
|
60
|
+
for (const server of existingServers) {
|
|
61
|
+
const serverName = server.name.toLowerCase();
|
|
62
|
+
for (const regName of registryNames) {
|
|
63
|
+
if (serverName.includes(regName)) {
|
|
64
|
+
installed[regName] = { installed: true, source: server.source };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return installed;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Check if prerequisites are met for an MCP entry
|
|
74
|
+
* @param {Object} mcpEntry - MCP entry from registry
|
|
75
|
+
* @returns {Array} Array of { name, met, installUrl } for each prerequisite
|
|
76
|
+
*/
|
|
77
|
+
export function checkPrerequisites(mcpEntry) {
|
|
78
|
+
const prereqs = mcpEntry.install?.prerequisites || [];
|
|
79
|
+
const results = [];
|
|
80
|
+
|
|
81
|
+
for (const prereq of prereqs) {
|
|
82
|
+
let met = false;
|
|
83
|
+
try {
|
|
84
|
+
execSync(prereq.checkCommand, { stdio: 'ignore', timeout: 5000 });
|
|
85
|
+
met = true;
|
|
86
|
+
} catch {
|
|
87
|
+
// Command failed or not found
|
|
88
|
+
}
|
|
89
|
+
results.push({
|
|
90
|
+
name: prereq.name,
|
|
91
|
+
met,
|
|
92
|
+
installUrl: prereq.installUrl
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Install auto-installable MCPs (no credentials, no prerequisites)
|
|
101
|
+
* @param {string} targetPath - Project root directory
|
|
102
|
+
* @param {Object} mcpsToInstall - Map of mcpName → mcpEntry
|
|
103
|
+
* @returns {Promise<Object>} Result from installMcpServers
|
|
104
|
+
*/
|
|
105
|
+
export async function installAutoMcps(targetPath, mcpsToInstall) {
|
|
106
|
+
const servers = {};
|
|
107
|
+
|
|
108
|
+
for (const [name, entry] of Object.entries(mcpsToInstall)) {
|
|
109
|
+
const config = { ...entry.install.config };
|
|
110
|
+
// Only include env if it has actual values
|
|
111
|
+
if (config.env && Object.values(config.env).every(v => !v)) {
|
|
112
|
+
delete config.env;
|
|
113
|
+
}
|
|
114
|
+
servers[name] = config;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return installMcpServers(targetPath, servers);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Install a single MCP with provided credentials
|
|
122
|
+
* @param {string} targetPath - Project root directory
|
|
123
|
+
* @param {string} name - MCP name
|
|
124
|
+
* @param {Object} mcpEntry - MCP entry from registry
|
|
125
|
+
* @param {Object} credentialValues - Map of envVar → value
|
|
126
|
+
* @returns {Promise<Object>} Result from installMcpServers
|
|
127
|
+
*/
|
|
128
|
+
export async function installMcpWithCredentials(targetPath, name, mcpEntry, credentialValues) {
|
|
129
|
+
const config = { ...mcpEntry.install.config };
|
|
130
|
+
config.env = { ...config.env, ...credentialValues };
|
|
131
|
+
return installMcpServers(targetPath, { [name]: config });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Generate setup instructions for a credential-requiring MCP
|
|
136
|
+
* @param {string} name - MCP name
|
|
137
|
+
* @param {Object} mcpEntry - MCP entry from registry
|
|
138
|
+
* @returns {Object} { configSnippet, credentialUrls, cliCommand }
|
|
139
|
+
*/
|
|
140
|
+
export function generateSetupInstructions(name, mcpEntry) {
|
|
141
|
+
const config = mcpEntry.install.config;
|
|
142
|
+
const credentials = mcpEntry.install.credentials || [];
|
|
143
|
+
|
|
144
|
+
// Build the config snippet with placeholder values
|
|
145
|
+
const snippetConfig = { ...config };
|
|
146
|
+
if (credentials.length > 0) {
|
|
147
|
+
snippetConfig.env = {};
|
|
148
|
+
for (const cred of credentials) {
|
|
149
|
+
snippetConfig.env[cred.envVar] = cred.secret ? 'YOUR_KEY' : 'YOUR_VALUE';
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const configSnippet = JSON.stringify({ [name]: snippetConfig }, null, 2);
|
|
154
|
+
|
|
155
|
+
const credentialUrls = credentials.map(c => ({
|
|
156
|
+
name: c.name,
|
|
157
|
+
envVar: c.envVar,
|
|
158
|
+
helpUrl: c.helpUrl
|
|
159
|
+
}));
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
configSnippet,
|
|
163
|
+
credentialUrls,
|
|
164
|
+
cliCommand: `morph-spec mcp setup ${name}`
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Full orchestrator for MCP setup during init or `mcp setup`
|
|
170
|
+
* @param {string} targetPath - Project root directory
|
|
171
|
+
* @param {string} stack - Detected project stack
|
|
172
|
+
* @param {Array} existingMcps - From detectClaudeConfig().mcpServers
|
|
173
|
+
* @param {Object} options
|
|
174
|
+
* @param {boolean} options.autoOnly - Only handle auto-installable MCPs
|
|
175
|
+
* @returns {Object} { autoInstallable, alreadyInstalled, needsManualSetup, notRelevant, prerequisitesMissing }
|
|
176
|
+
*/
|
|
177
|
+
export function orchestrateMcpSetup(targetPath, stack, existingMcps, options = {}) {
|
|
178
|
+
const registry = loadMcpRegistry();
|
|
179
|
+
const relevant = filterByStack(registry, stack);
|
|
180
|
+
const installed = getInstalledMcps(existingMcps || [], registry);
|
|
181
|
+
|
|
182
|
+
const autoInstallable = {};
|
|
183
|
+
const alreadyInstalled = {};
|
|
184
|
+
const needsManualSetup = {};
|
|
185
|
+
const notRelevant = {};
|
|
186
|
+
const prerequisitesMissing = {};
|
|
187
|
+
|
|
188
|
+
// Categorize all MCPs
|
|
189
|
+
for (const [name, entry] of Object.entries(registry.mcps)) {
|
|
190
|
+
if (!entry.install) continue;
|
|
191
|
+
|
|
192
|
+
// Check if already installed
|
|
193
|
+
if (installed[name]) {
|
|
194
|
+
alreadyInstalled[name] = { entry, source: installed[name].source };
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Check if relevant to stack
|
|
199
|
+
if (!relevant[name]) {
|
|
200
|
+
notRelevant[name] = entry;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Check prerequisites
|
|
205
|
+
const prereqResults = checkPrerequisites(entry);
|
|
206
|
+
const unmetPrereqs = prereqResults.filter(p => !p.met);
|
|
207
|
+
if (unmetPrereqs.length > 0) {
|
|
208
|
+
prerequisitesMissing[name] = { entry, unmet: unmetPrereqs };
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Categorize by install type
|
|
213
|
+
if (entry.install.autoInstall) {
|
|
214
|
+
autoInstallable[name] = entry;
|
|
215
|
+
} else if (!options.autoOnly) {
|
|
216
|
+
needsManualSetup[name] = entry;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
registry,
|
|
222
|
+
autoInstallable,
|
|
223
|
+
alreadyInstalled,
|
|
224
|
+
needsManualSetup,
|
|
225
|
+
notRelevant,
|
|
226
|
+
prerequisitesMissing
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Format MCP status table for display
|
|
232
|
+
* @param {Object} orchestration - Result from orchestrateMcpSetup
|
|
233
|
+
* @param {Object} justInstalled - Map of names just installed during this run
|
|
234
|
+
* @returns {Array<Object>} Array of { name, status, detail }
|
|
235
|
+
*/
|
|
236
|
+
export function formatMcpStatusTable(orchestration, justInstalled = {}) {
|
|
237
|
+
const rows = [];
|
|
238
|
+
|
|
239
|
+
const { autoInstallable, alreadyInstalled, needsManualSetup, notRelevant, prerequisitesMissing, registry } = orchestration;
|
|
240
|
+
|
|
241
|
+
// Installed during this run
|
|
242
|
+
for (const [name, entry] of Object.entries(justInstalled)) {
|
|
243
|
+
const mcpEntry = registry.mcps[name];
|
|
244
|
+
rows.push({
|
|
245
|
+
name,
|
|
246
|
+
status: 'installed',
|
|
247
|
+
detail: mcpEntry ? mcpEntry.usage : ''
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Auto-installable but not yet installed (and not just-installed)
|
|
252
|
+
for (const [name, entry] of Object.entries(autoInstallable)) {
|
|
253
|
+
if (justInstalled[name]) continue;
|
|
254
|
+
rows.push({
|
|
255
|
+
name,
|
|
256
|
+
status: 'available',
|
|
257
|
+
detail: `Run: morph-spec mcp setup --auto`
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Already installed
|
|
262
|
+
for (const [name, { source }] of Object.entries(alreadyInstalled)) {
|
|
263
|
+
rows.push({
|
|
264
|
+
name,
|
|
265
|
+
status: 'already_configured',
|
|
266
|
+
detail: `(${source})`
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Needs manual setup
|
|
271
|
+
for (const [name, entry] of Object.entries(needsManualSetup)) {
|
|
272
|
+
rows.push({
|
|
273
|
+
name,
|
|
274
|
+
status: 'needs_setup',
|
|
275
|
+
detail: `Run: morph-spec mcp setup ${name}`
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Prerequisites missing
|
|
280
|
+
for (const [name, { unmet }] of Object.entries(prerequisitesMissing)) {
|
|
281
|
+
const missing = unmet.map(p => p.name).join(', ');
|
|
282
|
+
rows.push({
|
|
283
|
+
name,
|
|
284
|
+
status: 'prereq_missing',
|
|
285
|
+
detail: `Missing: ${missing}`
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Not relevant
|
|
290
|
+
for (const [name] of Object.entries(notRelevant)) {
|
|
291
|
+
rows.push({
|
|
292
|
+
name,
|
|
293
|
+
status: 'not_relevant',
|
|
294
|
+
detail: 'not relevant to stack'
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return rows;
|
|
299
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Learns from:
|
|
8
8
|
* - decisions.md files (ADRs from each feature)
|
|
9
|
-
* - .morph/
|
|
9
|
+
* - .morph/context/*.md (project standards)
|
|
10
10
|
* - state.json (feature outcomes and complexity)
|
|
11
11
|
*
|
|
12
12
|
* MORPH-SPEC 3.0 - Sprint 4
|
|
@@ -118,7 +118,7 @@ export class LearningSystem {
|
|
|
118
118
|
console.log(chalk.cyan('🧠 Learning from project history...\n'));
|
|
119
119
|
|
|
120
120
|
// Find all decisions.md files
|
|
121
|
-
const decisionFiles = await glob('.morph/
|
|
121
|
+
const decisionFiles = await glob('.morph/features/*/decisions.md', {
|
|
122
122
|
cwd: this.projectPath
|
|
123
123
|
});
|
|
124
124
|
|
|
@@ -130,7 +130,7 @@ export class LearningSystem {
|
|
|
130
130
|
let newDecisions = 0;
|
|
131
131
|
|
|
132
132
|
for (const file of decisionFiles) {
|
|
133
|
-
const featureName = file.split('/')[
|
|
133
|
+
const featureName = file.split('/')[2]; // Extract feature name from path
|
|
134
134
|
const learned = await this.learnFromDecisionFile(file, featureName);
|
|
135
135
|
newDecisions += learned;
|
|
136
136
|
}
|
|
@@ -23,7 +23,7 @@ const __dirname = path.dirname(__filename);
|
|
|
23
23
|
* @returns {Promise<Object>} Parsed agents configuration
|
|
24
24
|
*/
|
|
25
25
|
async function loadAgentsConfig(projectPath) {
|
|
26
|
-
const agentsPath = path.join(projectPath, '.morph/
|
|
26
|
+
const agentsPath = path.join(projectPath, '.morph/framework/agents.json');
|
|
27
27
|
const content = await fs.readFile(agentsPath, 'utf8');
|
|
28
28
|
return JSON.parse(content);
|
|
29
29
|
}
|
|
@@ -19,7 +19,7 @@ const AGENT_STANDARDS_MAP = {
|
|
|
19
19
|
'standards-architect': [
|
|
20
20
|
'core/architecture',
|
|
21
21
|
'core/coding',
|
|
22
|
-
'infrastructure/azure/azure', // Stack-specific (kept in .morph/standards/)
|
|
22
|
+
'infrastructure/azure/azure', // Stack-specific (kept in .morph/framework/standards/)
|
|
23
23
|
'backend/dotnet/core',
|
|
24
24
|
'backend/dotnet/program-cs-checklist'
|
|
25
25
|
],
|
|
@@ -200,9 +200,9 @@ const AGENT_STANDARDS_MAP = {
|
|
|
200
200
|
function loadStandard(standardName, projectPath) {
|
|
201
201
|
const locations = [
|
|
202
202
|
// 1. Project override
|
|
203
|
-
join(projectPath, '.morph/
|
|
204
|
-
// 2. Project-level standards (.morph/standards/)
|
|
205
|
-
join(projectPath, '.morph/standards', `${standardName}.md`),
|
|
203
|
+
join(projectPath, '.morph/context', `${standardName}.md`),
|
|
204
|
+
// 2. Project-level standards (.morph/framework/standards/)
|
|
205
|
+
join(projectPath, '.morph/framework/standards', `${standardName}.md`),
|
|
206
206
|
// 3. Framework standards (hierarchical structure: core/, backend/, frontend/, infrastructure/)
|
|
207
207
|
join(projectPath, 'framework/standards', `${standardName}.md`)
|
|
208
208
|
];
|
|
@@ -232,7 +232,7 @@ export function loadStandardsForAgent(agentId, projectPath = '.') {
|
|
|
232
232
|
const contentParts = [];
|
|
233
233
|
|
|
234
234
|
// Load inferred standards if exists (project-specific learnings)
|
|
235
|
-
const inferredPath = join(projectPath, '.morph/
|
|
235
|
+
const inferredPath = join(projectPath, '.morph/context/inferred.md');
|
|
236
236
|
if (existsSync(inferredPath)) {
|
|
237
237
|
try {
|
|
238
238
|
const inferredContent = readFileSync(inferredPath, 'utf8');
|
|
@@ -282,8 +282,8 @@ export function getStandardsListForAgent(agentId) {
|
|
|
282
282
|
*/
|
|
283
283
|
export function checkStandardExists(standardName, projectPath = '.') {
|
|
284
284
|
const locations = [
|
|
285
|
-
{ type: 'project', path: join(projectPath, '.morph/
|
|
286
|
-
{ type: 'morph', path: join(projectPath, '.morph/standards', `${standardName}.md`) },
|
|
285
|
+
{ type: 'project', path: join(projectPath, '.morph/context', `${standardName}.md`) },
|
|
286
|
+
{ type: 'morph', path: join(projectPath, '.morph/framework/standards', `${standardName}.md`) },
|
|
287
287
|
{ type: 'framework', path: join(projectPath, 'framework/standards', `${standardName}.md`) }
|
|
288
288
|
];
|
|
289
289
|
|
|
@@ -44,7 +44,7 @@ export function buildGraph(tasks) {
|
|
|
44
44
|
* @returns {Object} { nodes: Map<id, task>, edges: Map<id, Set<depId>> }
|
|
45
45
|
*/
|
|
46
46
|
export function analyzeDependencies(feature) {
|
|
47
|
-
const tasksPath = join(process.cwd(), `.morph/
|
|
47
|
+
const tasksPath = join(process.cwd(), `.morph/features/${feature}/tasks.json`);
|
|
48
48
|
|
|
49
49
|
if (!existsSync(tasksPath)) {
|
|
50
50
|
throw new Error(`tasks.json not found for feature: ${feature}`);
|