@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
|
@@ -1,23 +1,166 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Claude Code Hooks Installer
|
|
2
|
+
* Claude Code Hooks Installer (v2)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Registry-based installer for all MORPH-SPEC Claude Code hooks.
|
|
5
|
+
* Declarative MORPH_HOOKS array defines all hooks.
|
|
6
|
+
* Idempotent merge into .claude/settings.local.json.
|
|
6
7
|
*
|
|
7
8
|
* Called by `morph-spec init` and `morph-spec update`.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
import { join } from 'path';
|
|
11
|
-
import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
12
|
-
import { existsSync } from 'fs';
|
|
12
|
+
import { readFile, writeFile, mkdir, copyFile } from 'fs/promises';
|
|
13
|
+
import { existsSync, chmodSync } from 'fs';
|
|
14
|
+
import { homedir } from 'os';
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
/** Current hooks schema version — bump when hook definitions change */
|
|
17
|
+
const HOOKS_VERSION = '2.4.0';
|
|
18
|
+
|
|
19
|
+
/** Marker for old dispatch.js (v1) */
|
|
20
|
+
const OLD_DISPATCH_COMMAND = 'node framework/hooks/agent-teams/dispatch.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Native permissions.deny entries managed by MORPH-SPEC.
|
|
24
|
+
* These replace the protect-readonly-files.js PreToolUse hook,
|
|
25
|
+
* using Claude Code's built-in permissions system instead.
|
|
26
|
+
*/
|
|
27
|
+
const MORPH_PERMISSIONS = [
|
|
28
|
+
'Write(.morph/state.json)',
|
|
29
|
+
'Edit(.morph/state.json)',
|
|
30
|
+
'Write(.morph/framework/**)',
|
|
31
|
+
'Edit(.morph/framework/**)',
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* All MORPH-SPEC hook definitions.
|
|
36
|
+
* Each entry maps to a Claude Code hook event.
|
|
37
|
+
*/
|
|
38
|
+
const MORPH_HOOKS = [
|
|
39
|
+
// === SessionStart ===
|
|
40
|
+
{
|
|
41
|
+
event: 'SessionStart',
|
|
42
|
+
matcher: 'startup|resume|compact',
|
|
43
|
+
hooks: [{
|
|
44
|
+
type: 'command',
|
|
45
|
+
command: 'node framework/hooks/claude-code/session-start/inject-morph-context.js'
|
|
46
|
+
}]
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// === UserPromptSubmit ===
|
|
50
|
+
{
|
|
51
|
+
event: 'UserPromptSubmit',
|
|
52
|
+
matcher: null,
|
|
53
|
+
hooks: [{
|
|
54
|
+
type: 'command',
|
|
55
|
+
command: 'node framework/hooks/claude-code/user-prompt/enrich-prompt.js'
|
|
56
|
+
}]
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
// === PreToolUse: Write|Edit ===
|
|
60
|
+
{
|
|
61
|
+
event: 'PreToolUse',
|
|
62
|
+
matcher: 'Write|Edit',
|
|
63
|
+
hooks: [
|
|
64
|
+
// Note: protect-readonly-files.js replaced by native permissions.deny (see MORPH_PERMISSIONS)
|
|
65
|
+
// Order matters: cheapest check first
|
|
66
|
+
{
|
|
67
|
+
type: 'command',
|
|
68
|
+
command: 'node framework/hooks/claude-code/pre-tool-use/protect-spec-files.js'
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'command',
|
|
72
|
+
command: 'node framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js'
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
// === PreToolUse: Bash ===
|
|
78
|
+
{
|
|
79
|
+
event: 'PreToolUse',
|
|
80
|
+
matcher: 'Bash',
|
|
81
|
+
hooks: [{
|
|
82
|
+
type: 'prompt',
|
|
83
|
+
prompt: `You are a guard for a morph-spec project. Read the bash command from the hook input and check:
|
|
84
|
+
1. Does the command delete .morph/ (e.g. contains "rm" with "-r" or "-rf" and ".morph")? If yes, BLOCK.
|
|
85
|
+
2. Does the command edit state.json directly via sed, jq, awk, echo, cat, or printf with a shell redirect (>)? If yes, BLOCK.
|
|
86
|
+
3. Does the command write to .morph/framework/ via a shell redirect (>)? If yes, BLOCK.
|
|
87
|
+
If any condition is true, respond: {"ok": false, "reason": "MORPH-SPEC: <brief explanation and suggested alternative using morph-spec CLI>"}
|
|
88
|
+
Otherwise respond: {"ok": true}`
|
|
89
|
+
}]
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
// === PostToolUse: Bash ===
|
|
93
|
+
{
|
|
94
|
+
event: 'PostToolUse',
|
|
95
|
+
matcher: 'Bash',
|
|
96
|
+
hooks: [{
|
|
97
|
+
type: 'command',
|
|
98
|
+
command: 'node framework/hooks/claude-code/post-tool-use/dispatch.js'
|
|
99
|
+
}]
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
// === Stop ===
|
|
103
|
+
{
|
|
104
|
+
event: 'Stop',
|
|
105
|
+
matcher: null,
|
|
106
|
+
hooks: [{
|
|
107
|
+
type: 'agent',
|
|
108
|
+
prompt: `Check if the active morph-spec feature phase outputs are complete.
|
|
109
|
+
1. Read the file .morph/state.json to find features with status "in_progress".
|
|
110
|
+
2. For each in_progress feature, check if required output files for the current phase exist and are non-empty.
|
|
111
|
+
- proposal phase: .morph/features/{feature}/0-proposal/proposal.md
|
|
112
|
+
- design phase: .morph/features/{feature}/1-design/spec.md
|
|
113
|
+
- tasks phase: .morph/features/{feature}/3-tasks/tasks.md
|
|
114
|
+
- implement phase: check tasks.completed vs tasks.total from state.json
|
|
115
|
+
3. If all required outputs exist and tasks are complete, return {"ok": true}.
|
|
116
|
+
4. If any required output is missing or empty, return {"ok": false, "reason": "Missing output: <path>"}.
|
|
117
|
+
5. If state.json does not exist or no feature is in_progress, return {"ok": true}.
|
|
118
|
+
Do NOT modify any files. Read only.`,
|
|
119
|
+
timeout: 60
|
|
120
|
+
}]
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
// === PreCompact ===
|
|
124
|
+
{
|
|
125
|
+
event: 'PreCompact',
|
|
126
|
+
matcher: null,
|
|
127
|
+
hooks: [{
|
|
128
|
+
type: 'command',
|
|
129
|
+
command: 'node framework/hooks/claude-code/pre-compact/save-morph-context.js'
|
|
130
|
+
}]
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
// === PostToolUseFailure ===
|
|
134
|
+
{
|
|
135
|
+
event: 'PostToolUseFailure',
|
|
136
|
+
matcher: null,
|
|
137
|
+
hooks: [{
|
|
138
|
+
type: 'command',
|
|
139
|
+
command: 'node framework/hooks/claude-code/post-tool-use/handle-tool-failure.js',
|
|
140
|
+
timeout: 10000,
|
|
141
|
+
}]
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
// === Notification ===
|
|
145
|
+
{
|
|
146
|
+
event: 'Notification',
|
|
147
|
+
matcher: 'idle_prompt',
|
|
148
|
+
hooks: [{
|
|
149
|
+
type: 'command',
|
|
150
|
+
command: 'node framework/hooks/claude-code/notification/approval-reminder.js'
|
|
151
|
+
}]
|
|
152
|
+
}
|
|
153
|
+
];
|
|
15
154
|
|
|
16
155
|
/**
|
|
17
|
-
* Install or update
|
|
156
|
+
* Install or update all MORPH-SPEC hooks in .claude/settings.local.json.
|
|
157
|
+
*
|
|
158
|
+
* - Idempotent: safe to call multiple times
|
|
159
|
+
* - Removes old v1 dispatch.js entry if present
|
|
160
|
+
* - Tracks installed version via _morph_managed.hooks_version
|
|
18
161
|
*
|
|
19
162
|
* @param {string} targetPath - Project root directory
|
|
20
|
-
* @returns {
|
|
163
|
+
* @returns {Promise<{ installed: number, updated: boolean }>}
|
|
21
164
|
*/
|
|
22
165
|
export async function installClaudeHooks(targetPath) {
|
|
23
166
|
const claudeDir = join(targetPath, '.claude');
|
|
@@ -29,35 +172,89 @@ export async function installClaudeHooks(targetPath) {
|
|
|
29
172
|
try {
|
|
30
173
|
settings = JSON.parse(await readFile(settingsPath, 'utf-8'));
|
|
31
174
|
} catch {
|
|
32
|
-
// Malformed JSON — start fresh to avoid corrupting the file
|
|
33
175
|
settings = {};
|
|
34
176
|
}
|
|
35
177
|
}
|
|
36
178
|
|
|
37
|
-
// Ensure hooks.PostToolUse array exists
|
|
38
179
|
settings.hooks = settings.hooks || {};
|
|
39
|
-
settings.hooks.PostToolUse = settings.hooks.PostToolUse || [];
|
|
40
180
|
|
|
41
|
-
// Check if
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
181
|
+
// Check if already at current version
|
|
182
|
+
const managed = settings._morph_managed || {};
|
|
183
|
+
const alreadyCurrent = managed.hooks_version === HOOKS_VERSION;
|
|
184
|
+
|
|
185
|
+
// Remove old v1 dispatch.js entry
|
|
186
|
+
removeOldDispatch(settings);
|
|
187
|
+
|
|
188
|
+
// Remove all morph-managed hooks (clean slate for idempotent update)
|
|
189
|
+
removeMorphHooks(settings);
|
|
190
|
+
|
|
191
|
+
// Install all hooks from the registry
|
|
192
|
+
let installed = 0;
|
|
193
|
+
for (const hookDef of MORPH_HOOKS) {
|
|
194
|
+
const { event, matcher, hooks } = hookDef;
|
|
195
|
+
|
|
196
|
+
if (!settings.hooks[event]) {
|
|
197
|
+
settings.hooks[event] = [];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const entry = { _morph: true };
|
|
201
|
+
if (matcher) {
|
|
202
|
+
entry.matcher = matcher;
|
|
203
|
+
}
|
|
204
|
+
entry.hooks = hooks.map(h => {
|
|
205
|
+
// Agent and prompt hooks: pass through as-is (no command path transform)
|
|
206
|
+
if (h.type === 'agent' || h.type === 'prompt') {
|
|
207
|
+
const agentHook = { type: h.type, prompt: h.prompt };
|
|
208
|
+
if (h.timeout !== undefined) agentHook.timeout = h.timeout;
|
|
209
|
+
return agentHook;
|
|
210
|
+
}
|
|
211
|
+
// Command hooks: transform path to use $CLAUDE_PROJECT_DIR
|
|
212
|
+
return {
|
|
213
|
+
type: h.type,
|
|
214
|
+
command: `node "$CLAUDE_PROJECT_DIR/framework/hooks/claude-code/${getHookSubpath(h.command)}"`,
|
|
215
|
+
...(h.timeout !== undefined ? { timeout: h.timeout } : {})
|
|
216
|
+
};
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
settings.hooks[event].push(entry);
|
|
220
|
+
installed++;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Install native permissions.deny entries (idempotent)
|
|
224
|
+
settings.permissions = settings.permissions || {};
|
|
225
|
+
settings.permissions.deny = settings.permissions.deny || [];
|
|
226
|
+
// Remove previously managed permissions to avoid duplicates on re-install
|
|
227
|
+
settings.permissions.deny = settings.permissions.deny.filter(
|
|
228
|
+
p => !MORPH_PERMISSIONS.includes(p)
|
|
45
229
|
);
|
|
230
|
+
for (const perm of MORPH_PERMISSIONS) {
|
|
231
|
+
settings.permissions.deny.push(perm);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// JSON Schema for IDE auto-complete and validation
|
|
235
|
+
settings['$schema'] = 'https://json.schemastore.org/claude-code-settings.json';
|
|
46
236
|
|
|
47
|
-
|
|
48
|
-
|
|
237
|
+
// Environment variables — always set MORPH_SPEC_ACTIVE, preserve user additions
|
|
238
|
+
settings.env = { ...settings.env, MORPH_SPEC_ACTIVE: 'true' };
|
|
239
|
+
|
|
240
|
+
// Attribution — only set if not already customized by user
|
|
241
|
+
if (!settings.attribution) {
|
|
242
|
+
settings.attribution = {
|
|
243
|
+
commit: '🤖 Co-authored by MORPH-SPEC',
|
|
244
|
+
pr: '',
|
|
245
|
+
};
|
|
49
246
|
}
|
|
50
247
|
|
|
51
|
-
//
|
|
52
|
-
settings.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
248
|
+
// Plans directory for Claude Code plan mode
|
|
249
|
+
if (!settings.plansDirectory) {
|
|
250
|
+
settings.plansDirectory = '.morph/plans';
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Track installed hooks version
|
|
254
|
+
settings._morph_managed = settings._morph_managed || {};
|
|
255
|
+
settings._morph_managed.hooks_version = HOOKS_VERSION;
|
|
256
|
+
settings._morph_managed.hooks_installed = [...new Set(MORPH_HOOKS.map(h => h.event))];
|
|
257
|
+
settings._morph_managed.generated_at = new Date().toISOString();
|
|
61
258
|
|
|
62
259
|
// Ensure .claude directory exists
|
|
63
260
|
if (!existsSync(claudeDir)) {
|
|
@@ -65,5 +262,134 @@ export async function installClaudeHooks(targetPath) {
|
|
|
65
262
|
}
|
|
66
263
|
|
|
67
264
|
await writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
68
|
-
return
|
|
265
|
+
return { installed, updated: !alreadyCurrent };
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Install the morph-spec statusline globally into ~/.claude/.
|
|
270
|
+
*
|
|
271
|
+
* Copies statusline.sh and statusline.py to ~/.claude/ and registers
|
|
272
|
+
* the statusLine config in ~/.claude/settings.json so it applies to
|
|
273
|
+
* every Claude Code session, not just morph-spec projects.
|
|
274
|
+
*
|
|
275
|
+
* Python 3 must be available as `python3` on PATH (global prerequisite).
|
|
276
|
+
*
|
|
277
|
+
* @param {string} hooksSourceDir - Path to framework/hooks/claude-code/
|
|
278
|
+
* @param {string} [globalClaudeDirOverride] - Override ~/.claude/ (for testing)
|
|
279
|
+
* @returns {Promise<{ installed: boolean, globalDir: string }>}
|
|
280
|
+
*/
|
|
281
|
+
export async function installGlobalStatusline(hooksSourceDir, globalClaudeDirOverride = null) {
|
|
282
|
+
const globalDir = globalClaudeDirOverride || join(homedir(), '.claude');
|
|
283
|
+
await mkdir(globalDir, { recursive: true });
|
|
284
|
+
|
|
285
|
+
// Copy statusline scripts to ~/.claude/
|
|
286
|
+
const scripts = ['statusline.sh', 'statusline.py'];
|
|
287
|
+
for (const fname of scripts) {
|
|
288
|
+
const src = join(hooksSourceDir, fname);
|
|
289
|
+
if (existsSync(src)) {
|
|
290
|
+
await copyFile(src, join(globalDir, fname));
|
|
291
|
+
if (process.platform !== 'win32') {
|
|
292
|
+
try { chmodSync(join(globalDir, fname), 0o755); } catch { /* non-critical */ }
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Register statusLine in ~/.claude/settings.json (global user settings)
|
|
298
|
+
const settingsPath = join(globalDir, 'settings.json');
|
|
299
|
+
let settings = {};
|
|
300
|
+
if (existsSync(settingsPath)) {
|
|
301
|
+
try {
|
|
302
|
+
settings = JSON.parse(await readFile(settingsPath, 'utf-8'));
|
|
303
|
+
} catch {
|
|
304
|
+
settings = {};
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
settings.statusLine = {
|
|
309
|
+
type: 'command',
|
|
310
|
+
command: join(globalDir, 'statusline.sh').replace(/\\/g, '/'),
|
|
311
|
+
padding: 2
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
await writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
315
|
+
return { installed: true, globalDir };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Remove old v1 agent-teams/dispatch.js hook entries.
|
|
320
|
+
* @param {Object} settings
|
|
321
|
+
*/
|
|
322
|
+
function removeOldDispatch(settings) {
|
|
323
|
+
if (!settings.hooks?.PostToolUse) return;
|
|
324
|
+
|
|
325
|
+
settings.hooks.PostToolUse = settings.hooks.PostToolUse.filter(entry => {
|
|
326
|
+
if (!Array.isArray(entry.hooks)) return true;
|
|
327
|
+
return !entry.hooks.some(h =>
|
|
328
|
+
h.command === OLD_DISPATCH_COMMAND ||
|
|
329
|
+
(typeof h.command === 'string' && h.command.includes('agent-teams/dispatch.js'))
|
|
330
|
+
);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
if (settings.hooks.PostToolUse.length === 0) {
|
|
334
|
+
delete settings.hooks.PostToolUse;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Remove all morph-managed hook entries.
|
|
340
|
+
* Uses _morph:true marker (v2.2+) with legacy path-pattern fallback.
|
|
341
|
+
* Preserves any user-added hooks.
|
|
342
|
+
* @param {Object} settings
|
|
343
|
+
*/
|
|
344
|
+
function removeMorphHooks(settings) {
|
|
345
|
+
const morphPathPattern = /framework\/hooks\/claude-code\//;
|
|
346
|
+
|
|
347
|
+
for (const [event, entries] of Object.entries(settings.hooks)) {
|
|
348
|
+
if (!Array.isArray(entries)) continue;
|
|
349
|
+
|
|
350
|
+
settings.hooks[event] = entries.filter(entry => {
|
|
351
|
+
// Remove if explicitly marked as morph-managed
|
|
352
|
+
if (entry._morph === true) return false;
|
|
353
|
+
|
|
354
|
+
if (!Array.isArray(entry.hooks)) return true;
|
|
355
|
+
// Legacy path-pattern detection: remove if all hooks are morph command hooks
|
|
356
|
+
// Note: legacy path only covers command-type hooks (those with a path-matching command).
|
|
357
|
+
// Agent/prompt hooks without _morph marker are NOT removed by this fallback.
|
|
358
|
+
// This is acceptable since all morph hooks since v2.2.0 carry the _morph marker.
|
|
359
|
+
const nonMorphHooks = entry.hooks.filter(h =>
|
|
360
|
+
typeof h.command !== 'string' || !morphPathPattern.test(h.command)
|
|
361
|
+
);
|
|
362
|
+
return nonMorphHooks.length > 0;
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
if (settings.hooks[event].length === 0) {
|
|
366
|
+
delete settings.hooks[event];
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Extract hook subpath from a full command string.
|
|
373
|
+
* @param {string} command - e.g., 'node framework/hooks/claude-code/stop/validate-completion.js'
|
|
374
|
+
* @returns {string} e.g., 'stop/validate-completion.js'
|
|
375
|
+
*/
|
|
376
|
+
function getHookSubpath(command) {
|
|
377
|
+
const match = command.match(/claude-code\/(.+)$/);
|
|
378
|
+
return match ? match[1] : command;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Get the current hooks version.
|
|
383
|
+
* @returns {string}
|
|
384
|
+
*/
|
|
385
|
+
export function getHooksVersion() {
|
|
386
|
+
return HOOKS_VERSION;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Get the list of hook definitions (for testing/inspection).
|
|
391
|
+
* @returns {Array}
|
|
392
|
+
*/
|
|
393
|
+
export function getHookDefinitions() {
|
|
394
|
+
return MORPH_HOOKS;
|
|
69
395
|
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills Installer
|
|
3
|
+
*
|
|
4
|
+
* Copies framework skills to .claude/skills/ during morph-spec init.
|
|
5
|
+
* Installs level-0-meta and level-1-workflows skills using the native Claude Code
|
|
6
|
+
* subdirectory format: .claude/skills/{skill-name}/SKILL.md (plus optional
|
|
7
|
+
* scripts/, references/, and assets/ subdirectories).
|
|
8
|
+
* Level-2 domain specialists are installed as native subagents via installDomainAgents().
|
|
9
|
+
* Level-3 and level-4 only contain README.md placeholder files and are skipped.
|
|
10
|
+
*
|
|
11
|
+
* Source skills can be either:
|
|
12
|
+
* - Directory-based: framework/skills/{level}/{skill-name}/SKILL.md (preferred)
|
|
13
|
+
* - Flat file: framework/skills/{level}/{skill-name}.md (legacy, still supported)
|
|
14
|
+
*
|
|
15
|
+
* Directory-based skills have their entire directory copied (scripts/, references/,
|
|
16
|
+
* assets/) so Claude Code can execute scripts and load references on demand.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { mkdirSync, copyFileSync, existsSync, readdirSync, statSync } from 'fs';
|
|
20
|
+
import { join } from 'path';
|
|
21
|
+
import { fileURLToPath } from 'url';
|
|
22
|
+
|
|
23
|
+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
24
|
+
const FRAMEWORK_SKILLS_DIR = join(__dirname, '..', '..', 'framework', 'skills');
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Skill levels to install in .claude/skills/.
|
|
28
|
+
* Level-0 meta skills (planning, reviewing) and level-1 workflow skills
|
|
29
|
+
* (phase-design, phase-implement, etc.) are installed. Level-2 domain
|
|
30
|
+
* specialists are installed as native subagents via installDomainAgents()
|
|
31
|
+
* instead. Level-3 and level-4 are skipped (no content yet).
|
|
32
|
+
*/
|
|
33
|
+
const SKILL_LEVELS_TO_INSTALL = ['level-0-meta', 'level-1-workflows'];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Recursively copy a directory tree from src to dest.
|
|
37
|
+
* Creates dest if it doesn't exist. Skips README.md files.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} src - Source directory path
|
|
40
|
+
* @param {string} dest - Destination directory path
|
|
41
|
+
*/
|
|
42
|
+
function copyDirectory(src, dest) {
|
|
43
|
+
mkdirSync(dest, { recursive: true });
|
|
44
|
+
for (const entry of readdirSync(src)) {
|
|
45
|
+
if (entry === 'README.md') continue;
|
|
46
|
+
const srcPath = join(src, entry);
|
|
47
|
+
const destPath = join(dest, entry);
|
|
48
|
+
if (statSync(srcPath).isDirectory()) {
|
|
49
|
+
copyDirectory(srcPath, destPath);
|
|
50
|
+
} else {
|
|
51
|
+
copyFileSync(srcPath, destPath);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Walk srcDir and install skills into destDir.
|
|
58
|
+
*
|
|
59
|
+
* Handles two source formats:
|
|
60
|
+
* 1. Directory-based skill: srcDir/{skill-name}/SKILL.md
|
|
61
|
+
* → copies entire directory (SKILL.md + scripts/ + references/ + assets/)
|
|
62
|
+
* → destDir/{skill-name}/
|
|
63
|
+
*
|
|
64
|
+
* 2. Flat .md skill (legacy): srcDir/{skill-name}.md
|
|
65
|
+
* → destDir/{skill-name}/SKILL.md
|
|
66
|
+
*
|
|
67
|
+
* Level directories (level-0-meta, level-1-workflows, sub-categories) are
|
|
68
|
+
* traversed recursively. A directory is recognized as a skill directory when
|
|
69
|
+
* it contains a SKILL.md file.
|
|
70
|
+
*
|
|
71
|
+
* @param {string} srcDir - Source directory to walk
|
|
72
|
+
* @param {string} destDir - Destination base directory (.claude/skills/)
|
|
73
|
+
*/
|
|
74
|
+
function installSkillsFromDir(srcDir, destDir) {
|
|
75
|
+
const entries = readdirSync(srcDir);
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
const srcPath = join(srcDir, entry);
|
|
78
|
+
const stat = statSync(srcPath);
|
|
79
|
+
|
|
80
|
+
if (stat.isDirectory()) {
|
|
81
|
+
const skillMdPath = join(srcPath, 'SKILL.md');
|
|
82
|
+
if (existsSync(skillMdPath)) {
|
|
83
|
+
// Directory-based skill — copy entire directory including scripts/, references/, assets/
|
|
84
|
+
const skillDestDir = join(destDir, entry);
|
|
85
|
+
copyDirectory(srcPath, skillDestDir);
|
|
86
|
+
} else {
|
|
87
|
+
// Level/category directory — recurse
|
|
88
|
+
installSkillsFromDir(srcPath, destDir);
|
|
89
|
+
}
|
|
90
|
+
} else if (entry.endsWith('.md') && entry !== 'README.md') {
|
|
91
|
+
// Legacy flat .md skill — wrap in subdirectory as SKILL.md
|
|
92
|
+
const skillName = entry.slice(0, -3);
|
|
93
|
+
const skillDir = join(destDir, skillName);
|
|
94
|
+
mkdirSync(skillDir, { recursive: true });
|
|
95
|
+
copyFileSync(srcPath, join(skillDir, 'SKILL.md'));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Install morph framework skills to .claude/skills/ in the target project.
|
|
102
|
+
* Skills are copied into subdirectories as SKILL.md files so Claude Code can
|
|
103
|
+
* discover them natively via /<skill-name> syntax (e.g., /phase-design,
|
|
104
|
+
* /blazor-builder). Directory-based skills also get their scripts/,
|
|
105
|
+
* references/, and assets/ subdirectories copied for on-demand loading.
|
|
106
|
+
*
|
|
107
|
+
* @param {string} projectDir - Target project root directory
|
|
108
|
+
*/
|
|
109
|
+
export async function installSkills(projectDir) {
|
|
110
|
+
const claudeSkillsDir = join(projectDir, '.claude', 'skills');
|
|
111
|
+
mkdirSync(claudeSkillsDir, { recursive: true });
|
|
112
|
+
|
|
113
|
+
for (const level of SKILL_LEVELS_TO_INSTALL) {
|
|
114
|
+
const levelDir = join(FRAMEWORK_SKILLS_DIR, level);
|
|
115
|
+
if (!existsSync(levelDir)) continue;
|
|
116
|
+
installSkillsFromDir(levelDir, claudeSkillsDir);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# morph-spec-framework - Project Context
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
This file will be auto-updated by MORPH-SPEC detection system.
|
|
6
|
-
|
|
7
|
-
## Stack
|
|
8
|
-
|
|
9
|
-
Run `morph-spec detect` to analyze your project.
|
|
10
|
-
|
|
11
|
-
## Technologies
|
|
12
|
-
|
|
13
|
-
(To be detected)
|
|
14
|
-
|
|
15
|
-
## Architecture
|
|
16
|
-
|
|
17
|
-
(To be detected)
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
## Detection Summary
|
|
2
|
-
|
|
3
|
-
### Stack
|
|
4
|
-
- **Type**: nodejs
|
|
5
|
-
- **Architecture**: cli-library
|
|
6
|
-
|
|
7
|
-
### Technologies
|
|
8
|
-
- **Language**: javascript
|
|
9
|
-
- **Version**: >=18.0.0
|
|
10
|
-
- **Package Manager**: npm
|
|
11
|
-
|
|
12
|
-
### Patterns Detected
|
|
13
|
-
- API Routes
|
|
14
|
-
- Unit Tests
|
|
15
|
-
|
|
16
|
-
### Recommendations
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# Inferred Standards (Auto-generated)
|
|
2
|
-
|
|
3
|
-
> ⚠️ This file is auto-generated by MORPH-SPEC detection system.
|
|
4
|
-
> Manual edits will be overwritten. Create custom standards in `overrides.md`.
|
|
5
|
-
|
|
6
|
-
**Generated:** 2026-02-19T22:12:05.727Z
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## 🎯 Project Stack
|
|
11
|
-
|
|
12
|
-
- **Type**: nodejs
|
|
13
|
-
- **Language**: javascript
|
|
14
|
-
- **Version**: >=18.0.0
|
|
15
|
-
- **Architecture**: cli-library
|
|
16
|
-
|
|
17
|
-
## 📐 Patterns in Use
|
|
18
|
-
|
|
19
|
-
- API Routes
|
|
20
|
-
- Unit Tests
|
|
21
|
-
|
|
22
|
-
## 💻 Inferred Coding Standards
|
|
23
|
-
|
|
24
|
-
### JavaScript / TypeScript Conventions
|
|
25
|
-
|
|
26
|
-
Based on detected patterns in your codebase:
|
|
27
|
-
|
|
28
|
-
- **Package Manager**: npm
|
|
29
|
-
|
|
30
|
-
**Recommendation**: Refer to framework standards for JavaScript best practices.
|
|
31
|
-
|
|
32
|
-
## 🏗️ Architecture Pattern
|
|
33
|
-
|
|
34
|
-
### CLI / Library Architecture
|
|
35
|
-
|
|
36
|
-
Your project follows a CLI/Library pattern:
|
|
37
|
-
|
|
38
|
-
- ✅ **bin/** entry points detected
|
|
39
|
-
- ✅ **src/** source directory detected
|
|
40
|
-
- ✅ **package.json** present
|
|
41
|
-
|
|
42
|
-
**Key principles**:
|
|
43
|
-
- Commands exposed via bin/
|
|
44
|
-
- Core logic in src/commands/ and src/lib/
|
|
45
|
-
- Public API exported from src/index.js
|
|
46
|
-
|
|
47
|
-
## 📦 Key Dependencies
|
|
48
|
-
|
|
49
|
-
- @polymorphism-tech/morph-spec
|
|
50
|
-
- ajv
|
|
51
|
-
- ajv-formats
|
|
52
|
-
- chalk
|
|
53
|
-
- commander
|
|
54
|
-
- diff
|
|
55
|
-
- fs-extra
|
|
56
|
-
- glob
|
|
57
|
-
- handlebars
|
|
58
|
-
- inquirer
|
|
59
|
-
- ... and 6 more
|