@polymorphism-tech/morph-spec 4.3.6 → 4.5.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 +44 -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/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/{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 +51 -0
- package/.morph/memory/pre-compact-2026-02-22T17-01-01-658Z.json +16 -0
- package/.morph/state.json +1 -1
- package/CLAUDE.md +20 -119
- 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/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 +239 -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/level-0-meta/brainstorming.md +133 -0
- package/framework/skills/level-0-meta/code-review.md +12 -4
- package/framework/skills/level-0-meta/mcp-registry.json +207 -0
- package/framework/skills/level-0-meta/morph-checklist.md +9 -1
- package/framework/skills/level-0-meta/simulation-checklist.md +9 -1
- package/framework/skills/level-0-meta/tool-usage-guide.md +335 -0
- package/framework/skills/level-0-meta/verification-before-completion.md +145 -0
- package/framework/skills/level-1-workflows/morph-replicate.md +9 -1
- package/framework/skills/level-1-workflows/phase-clarify.md +65 -4
- package/framework/skills/level-1-workflows/phase-codebase-analysis.md +182 -0
- package/framework/skills/level-1-workflows/phase-design.md +342 -80
- package/framework/skills/level-1-workflows/phase-implement.md +254 -0
- package/framework/skills/level-1-workflows/phase-setup.md +76 -10
- package/framework/skills/level-1-workflows/phase-tasks.md +88 -7
- package/framework/skills/level-1-workflows/phase-uiux.md +95 -17
- package/framework/skills/level-2-domains/ai-agents/ai-system-architect.md +8 -1
- package/framework/skills/level-2-domains/architecture/po-pm-advisor.md +8 -1
- package/framework/skills/level-2-domains/architecture/prompt-engineer.md +8 -1
- package/framework/skills/level-2-domains/architecture/seo-growth-hacker.md +8 -1
- package/framework/skills/level-2-domains/architecture/standards-architect.md +11 -4
- package/framework/skills/level-2-domains/backend/api-designer.md +8 -1
- package/framework/skills/level-2-domains/backend/dotnet-senior.md +8 -1
- package/framework/skills/level-2-domains/backend/ef-modeler.md +8 -1
- package/framework/skills/level-2-domains/backend/hangfire-orchestrator.md +9 -2
- package/framework/skills/level-2-domains/backend/ms-agent-expert.md +8 -1
- package/framework/skills/level-2-domains/frontend/blazor-builder.md +8 -1
- package/framework/skills/level-2-domains/frontend/nextjs-expert.md +8 -1
- package/framework/skills/level-2-domains/frontend/ui-ux-designer.md +9 -2
- package/framework/skills/level-2-domains/infrastructure/azure-architect.md +8 -1
- package/framework/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +8 -1
- package/framework/skills/level-2-domains/infrastructure/bicep-architect.md +8 -1
- package/framework/skills/level-2-domains/infrastructure/container-specialist.md +8 -1
- package/framework/skills/level-2-domains/infrastructure/devops-engineer.md +8 -1
- package/framework/skills/level-2-domains/integrations/asaas-financial.md +8 -1
- package/framework/skills/level-2-domains/integrations/azure-identity.md +8 -1
- package/framework/skills/level-2-domains/integrations/clerk-auth.md +8 -1
- package/framework/skills/level-2-domains/integrations/{hangfire-orchestrator.md → hangfire-integration.md} +8 -1
- package/framework/skills/level-2-domains/integrations/resend-email.md +8 -1
- package/framework/skills/level-2-domains/quality/code-analyzer.md +10 -3
- package/framework/skills/level-2-domains/quality/testing-specialist.md +8 -1
- 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 -2
- 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 -76
- 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 +63 -30
- 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 +392 -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 +74 -0
- 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/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/{project/context → context}/README.md +0 -0
- /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}/frontend/nextjs/nextjs-patterns.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/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
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
# morph-spec-next Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Close the remaining gaps left after Claude Code Native Alignment Rounds 1 & 2 — specifically: make `morph-spec update` sync all Claude-native artifacts introduced in recent rounds, add `.claude/rules/` and `.claude/agents/` health checks to `doctor`, and bump the version to 4.4.0 to signal the alignment work to users.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Four focused changes to existing files. No new files created. All changes are additive within the existing command/utility patterns. Tests follow the established pattern of testing utility functions directly (not interactive CLI commands).
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Node.js ESM, `fs-extra`, existing `installSkills` / `installAgents` utilities, `node:test`
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Background: What update.js is missing
|
|
14
|
+
|
|
15
|
+
`morph-spec update` currently:
|
|
16
|
+
- Cleans the entire `.claude/` directory (`cleanFrameworkDirs` line 62)
|
|
17
|
+
- Rebuilds: commands, skills (manual junction-linking), hooks, CLAUDE.md (via `copyDirectory` — bug)
|
|
18
|
+
- **Missing:** flat skills (`installSkills`), agents (`installAgents`), rules copy, `CLAUDE_runtime.md` copy
|
|
19
|
+
|
|
20
|
+
Also: line 311 calls `copyDirectory(claudeMdSrc, claudeMdDest)` on a single FILE — should be `copyFile`.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Task 1: Fix update.js — imports + copyFile bug
|
|
25
|
+
|
|
26
|
+
**Files:**
|
|
27
|
+
- Modify: `src/commands/project/update.js`
|
|
28
|
+
|
|
29
|
+
**Step 1: Add missing imports**
|
|
30
|
+
|
|
31
|
+
At the top of `update.js`, after the existing `import { installClaudeHooks }` line (line 29), add:
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
import { installSkills } from '../../utils/skills-installer.js';
|
|
35
|
+
import { installAgents } from '../../utils/agents-installer.js';
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Step 2: Fix the copyDirectory → copyFile bug on CLAUDE.md**
|
|
39
|
+
|
|
40
|
+
Find this block (around line 307–311):
|
|
41
|
+
```javascript
|
|
42
|
+
// Update CLAUDE.md
|
|
43
|
+
updateSpinner.text = 'Updating CLAUDE.md...';
|
|
44
|
+
const claudeMdSrc = join(contentDir, 'CLAUDE.md');
|
|
45
|
+
const claudeMdDest = join(targetPath, 'CLAUDE.md');
|
|
46
|
+
await copyDirectory(claudeMdSrc, claudeMdDest);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Replace `copyDirectory` with `copyFile`:
|
|
50
|
+
```javascript
|
|
51
|
+
// Update CLAUDE.md
|
|
52
|
+
updateSpinner.text = 'Updating CLAUDE.md...';
|
|
53
|
+
const claudeMdSrc = join(contentDir, 'framework', 'CLAUDE.md');
|
|
54
|
+
const claudeMdDest = join(targetPath, 'CLAUDE.md');
|
|
55
|
+
await copyFile(claudeMdSrc, claudeMdDest);
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Note: `contentDir` is the framework root (returned by `getContentDir()`), so `CLAUDE.md` is at `join(contentDir, 'framework', 'CLAUDE.md')`.
|
|
59
|
+
|
|
60
|
+
**Step 3: Run the existing update-related tests to confirm nothing broke**
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm test -- test/commands/init.test.js
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Expected: 16 pass, 0 fail.
|
|
67
|
+
|
|
68
|
+
**Step 4: Commit**
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
git add src/commands/project/update.js
|
|
72
|
+
git commit -m "fix(update): import installSkills/installAgents and fix copyFile bug on CLAUDE.md"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Task 2: Add new artifact sync steps to update.js
|
|
78
|
+
|
|
79
|
+
**Files:**
|
|
80
|
+
- Modify: `src/commands/project/update.js`
|
|
81
|
+
|
|
82
|
+
After the existing skills symlinking block (the closing `}` of the `{ const skillsSrc = ...}` block, around line 301) and BEFORE the hooks update line (`// Update Claude Code hooks`), insert these four steps:
|
|
83
|
+
|
|
84
|
+
**Step 1: Add flat skills sync (installSkills)**
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
// Sync morph skills to .claude/skills/ for native Claude Code discovery
|
|
88
|
+
updateSpinner.text = 'Syncing morph skills to .claude/skills/...';
|
|
89
|
+
await installSkills(targetPath);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Step 2: Add agents sync (installAgents)**
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
// Sync native subagents to .claude/agents/
|
|
96
|
+
updateSpinner.text = 'Syncing agents to .claude/agents/...';
|
|
97
|
+
await installAgents(targetPath, frameworkDir);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Step 3: Add rules sync**
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
// Sync path-scoped rules to .claude/rules/
|
|
104
|
+
updateSpinner.text = 'Syncing rules to .claude/rules/...';
|
|
105
|
+
const rulesSrc = join(frameworkDir, 'rules');
|
|
106
|
+
const rulesDest = join(claudeDest, 'rules');
|
|
107
|
+
if (await pathExists(rulesSrc)) {
|
|
108
|
+
await copyDirectory(rulesSrc, rulesDest);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Step 4: Add CLAUDE_runtime.md sync**
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
// Sync runtime CLAUDE.md to .claude/CLAUDE.md
|
|
116
|
+
updateSpinner.text = 'Syncing .claude/CLAUDE.md...';
|
|
117
|
+
const runtimeSrc = join(frameworkDir, 'CLAUDE_runtime.md');
|
|
118
|
+
const runtimeDest = join(claudeDest, 'CLAUDE.md');
|
|
119
|
+
if (await pathExists(runtimeSrc)) {
|
|
120
|
+
await copyFile(runtimeSrc, runtimeDest);
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Step 5: Update the success output block**
|
|
125
|
+
|
|
126
|
+
Find the "Updated files:" logger section (around line 336–350) and add these lines after the existing hooks line:
|
|
127
|
+
|
|
128
|
+
```javascript
|
|
129
|
+
logger.dim(' ✓ .claude/skills/ (flat .md for /skill-name discovery)');
|
|
130
|
+
logger.dim(' ✓ .claude/agents/ (native subagents refreshed)');
|
|
131
|
+
logger.dim(' ✓ .claude/rules/ (path-scoped rules synced)');
|
|
132
|
+
logger.dim(' ✓ .claude/CLAUDE.md (runtime quick reference)');
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Step 6: Run syntax check**
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
node --check src/commands/project/update.js && echo "Syntax OK"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Expected: `Syntax OK`
|
|
142
|
+
|
|
143
|
+
**Step 7: Commit**
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
git add src/commands/project/update.js
|
|
147
|
+
git commit -m "feat(update): sync rules, agents, flat skills, and .claude/CLAUDE.md on update"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Task 3: Write tests for update artifact sync
|
|
153
|
+
|
|
154
|
+
**Files:**
|
|
155
|
+
- Create: `test/commands/update.test.js`
|
|
156
|
+
|
|
157
|
+
The update command is interactive, so test the underlying utility functions directly — the same pattern used in `test/commands/init.test.js`.
|
|
158
|
+
|
|
159
|
+
**Step 1: Write the test file**
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
/**
|
|
163
|
+
* Tests for update command artifact sync.
|
|
164
|
+
* Tests utility functions directly to avoid interactive prompts.
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
import { test, describe, beforeEach, afterEach } from 'node:test';
|
|
168
|
+
import assert from 'node:assert/strict';
|
|
169
|
+
import { existsSync, readdirSync } from 'fs';
|
|
170
|
+
import { join } from 'path';
|
|
171
|
+
import { fileURLToPath } from 'url';
|
|
172
|
+
import { dirname } from 'path';
|
|
173
|
+
import { createTempDir, cleanupTempDir } from '../helpers/test-utils.js';
|
|
174
|
+
import { installSkills } from '../../src/utils/skills-installer.js';
|
|
175
|
+
import { installAgents } from '../../src/utils/agents-installer.js';
|
|
176
|
+
import { copyDirectory, copyFile, pathExists } from '../../src/utils/file-copier.js';
|
|
177
|
+
|
|
178
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
179
|
+
const FRAMEWORK_DIR = join(__dirname, '..', '..', 'framework');
|
|
180
|
+
|
|
181
|
+
describe('update — artifact sync', () => {
|
|
182
|
+
let tempDir;
|
|
183
|
+
|
|
184
|
+
beforeEach(() => {
|
|
185
|
+
tempDir = createTempDir();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
afterEach(() => {
|
|
189
|
+
cleanupTempDir(tempDir);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test('installSkills produces flat .claude/skills/ .md files', async () => {
|
|
193
|
+
await installSkills(tempDir);
|
|
194
|
+
const skillsDir = join(tempDir, '.claude', 'skills');
|
|
195
|
+
assert.ok(existsSync(skillsDir), '.claude/skills/ must exist');
|
|
196
|
+
const files = readdirSync(skillsDir).filter(f => f.endsWith('.md'));
|
|
197
|
+
assert.ok(files.length >= 4, `must have at least 4 flat skill files, got ${files.length}`);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
test('installAgents produces .claude/agents/ with morph- prefixed files', async () => {
|
|
201
|
+
await installAgents(tempDir, FRAMEWORK_DIR);
|
|
202
|
+
const agentsDir = join(tempDir, '.claude', 'agents');
|
|
203
|
+
assert.ok(existsSync(agentsDir), '.claude/agents/ must exist');
|
|
204
|
+
const files = readdirSync(agentsDir);
|
|
205
|
+
assert.ok(files.every(f => f.startsWith('morph-')), 'all agent files must have morph- prefix');
|
|
206
|
+
assert.ok(files.length >= 6, `must have at least 6 agents, got ${files.length}`);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test('rules copy produces .claude/rules/ with 5 files', async () => {
|
|
210
|
+
const rulesSrc = join(FRAMEWORK_DIR, 'rules');
|
|
211
|
+
const rulesDest = join(tempDir, '.claude', 'rules');
|
|
212
|
+
const exists = await pathExists(rulesSrc);
|
|
213
|
+
assert.ok(exists, 'framework/rules/ source must exist');
|
|
214
|
+
await copyDirectory(rulesSrc, rulesDest);
|
|
215
|
+
const files = readdirSync(rulesDest).filter(f => f.endsWith('.md'));
|
|
216
|
+
assert.equal(files.length, 5, `must install 5 rule files, got ${files.length}`);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
test('CLAUDE_runtime.md copy produces .claude/CLAUDE.md', async () => {
|
|
220
|
+
const src = join(FRAMEWORK_DIR, 'CLAUDE_runtime.md');
|
|
221
|
+
const dest = join(tempDir, '.claude', 'CLAUDE.md');
|
|
222
|
+
const claudeDir = join(tempDir, '.claude');
|
|
223
|
+
// ensure parent exists
|
|
224
|
+
await (await import('node:fs/promises')).mkdir(claudeDir, { recursive: true });
|
|
225
|
+
await copyFile(src, dest);
|
|
226
|
+
assert.ok(existsSync(dest), '.claude/CLAUDE.md must exist after copy');
|
|
227
|
+
const content = (await import('node:fs/promises')).readFile(dest, 'utf-8');
|
|
228
|
+
assert.ok(content instanceof Promise, 'content must be readable');
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test('clean-recreate is idempotent — second run replaces without error', async () => {
|
|
232
|
+
// First run
|
|
233
|
+
await installSkills(tempDir);
|
|
234
|
+
await installAgents(tempDir, FRAMEWORK_DIR);
|
|
235
|
+
const rulesSrc = join(FRAMEWORK_DIR, 'rules');
|
|
236
|
+
const rulesDest = join(tempDir, '.claude', 'rules');
|
|
237
|
+
await copyDirectory(rulesSrc, rulesDest);
|
|
238
|
+
|
|
239
|
+
// Second run (simulates update running again)
|
|
240
|
+
await installSkills(tempDir);
|
|
241
|
+
await installAgents(tempDir, FRAMEWORK_DIR);
|
|
242
|
+
await copyDirectory(rulesSrc, rulesDest);
|
|
243
|
+
|
|
244
|
+
const ruleFiles = readdirSync(rulesDest).filter(f => f.endsWith('.md'));
|
|
245
|
+
assert.equal(ruleFiles.length, 5, 'idempotent: must still have 5 rule files after second run');
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Step 2: Run the new tests**
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
npm test -- test/commands/update.test.js
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Expected: 5 pass, 0 fail.
|
|
257
|
+
|
|
258
|
+
**Step 3: Commit**
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
git add test/commands/update.test.js
|
|
262
|
+
git commit -m "test(update): add artifact sync tests for update command"
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Task 4: Version bump to 4.4.0
|
|
268
|
+
|
|
269
|
+
**Files:**
|
|
270
|
+
- Modify: `package.json`
|
|
271
|
+
|
|
272
|
+
**Step 1: Update version**
|
|
273
|
+
|
|
274
|
+
Find: `"version": "4.3.7"`
|
|
275
|
+
Replace with: `"version": "4.4.0"`
|
|
276
|
+
|
|
277
|
+
**Step 2: Update version reference in framework/CLAUDE.md and framework/CLAUDE_runtime.md**
|
|
278
|
+
|
|
279
|
+
In `framework/CLAUDE.md`, find: `*MORPH-SPEC v4.3.7 by Polymorphism Tech*`
|
|
280
|
+
Replace with: `*MORPH-SPEC v4.4.0 by Polymorphism Tech*`
|
|
281
|
+
|
|
282
|
+
In `framework/CLAUDE_runtime.md`, find: `*MORPH-SPEC v4.3.7 by Polymorphism Tech*`
|
|
283
|
+
Replace with: `*MORPH-SPEC v4.4.0 by Polymorphism Tech*`
|
|
284
|
+
|
|
285
|
+
**Step 3: Verify version is consistent**
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
node -e "import('./package.json', {assert:{type:'json'}}).then(m=>console.log(m.default.version))" 2>/dev/null || grep '"version"' package.json
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Expected: `4.4.0`
|
|
292
|
+
|
|
293
|
+
**Step 4: Commit**
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
git add package.json framework/CLAUDE.md framework/CLAUDE_runtime.md
|
|
297
|
+
git commit -m "chore: bump version to 4.4.0 — Claude Code native alignment rounds 1 & 2"
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Task 5: Doctor — add .claude/rules/ and .claude/agents/ checks
|
|
303
|
+
|
|
304
|
+
**Files:**
|
|
305
|
+
- Modify: `src/commands/project/doctor.js`
|
|
306
|
+
|
|
307
|
+
The `.claude/` check block (line ~454–494) checks commands and skills. Add rules and agents checks inside the `if (hasCommands && hasSkills)` block, after the skills link status check ends (after the closing `}` of the `if (skillDirs.length > 0)` block).
|
|
308
|
+
|
|
309
|
+
**Step 1: Add the rules check**
|
|
310
|
+
|
|
311
|
+
After the skills link block ends (around line 487), and still inside `if (hasCommands && hasSkills) {`, add:
|
|
312
|
+
|
|
313
|
+
```javascript
|
|
314
|
+
// Check .claude/rules/
|
|
315
|
+
const rulesPath = join(claudePath, 'rules');
|
|
316
|
+
if (await pathExists(rulesPath)) {
|
|
317
|
+
const ruleFiles = await fs.readdir(rulesPath);
|
|
318
|
+
const mdRules = ruleFiles.filter(f => f.endsWith('.md'));
|
|
319
|
+
checks.push({ name: '.claude/rules/', status: 'ok', msg: `${mdRules.length} rules` });
|
|
320
|
+
} else {
|
|
321
|
+
checks.push({ name: '.claude/rules/', status: 'warn', msg: 'missing — run morph-spec update' });
|
|
322
|
+
hasWarnings = true;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Check .claude/agents/
|
|
326
|
+
const agentsPath = join(claudePath, 'agents');
|
|
327
|
+
if (await pathExists(agentsPath)) {
|
|
328
|
+
const agentFiles = await fs.readdir(agentsPath);
|
|
329
|
+
const morphAgents = agentFiles.filter(f => f.startsWith('morph-') && f.endsWith('.md'));
|
|
330
|
+
checks.push({ name: '.claude/agents/', status: 'ok', msg: `${morphAgents.length} agents` });
|
|
331
|
+
} else {
|
|
332
|
+
checks.push({ name: '.claude/agents/', status: 'warn', msg: 'missing — run morph-spec update' });
|
|
333
|
+
hasWarnings = true;
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Step 2: Verify syntax**
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
node --check src/commands/project/doctor.js && echo "Syntax OK"
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Expected: `Syntax OK`
|
|
344
|
+
|
|
345
|
+
**Step 3: Commit**
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
git add src/commands/project/doctor.js
|
|
349
|
+
git commit -m "feat(doctor): add .claude/rules/ and .claude/agents/ health checks"
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Task 6: Write tests for doctor enhancements
|
|
355
|
+
|
|
356
|
+
**Files:**
|
|
357
|
+
- Create: `test/commands/doctor.test.js`
|
|
358
|
+
|
|
359
|
+
**Step 1: Write tests that directly exercise the check logic**
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
/**
|
|
363
|
+
* Tests for doctor command health check additions.
|
|
364
|
+
* Tests the check logic by setting up temp dirs with/without the expected artifacts.
|
|
365
|
+
*/
|
|
366
|
+
|
|
367
|
+
import { test, describe, beforeEach, afterEach } from 'node:test';
|
|
368
|
+
import assert from 'node:assert/strict';
|
|
369
|
+
import { mkdirSync, writeFileSync } from 'fs';
|
|
370
|
+
import { join } from 'path';
|
|
371
|
+
import { createTempDir, cleanupTempDir } from '../helpers/test-utils.js';
|
|
372
|
+
import { pathExists } from '../../src/utils/file-copier.js';
|
|
373
|
+
import { installSkills } from '../../src/utils/skills-installer.js';
|
|
374
|
+
import { installAgents } from '../../src/utils/agents-installer.js';
|
|
375
|
+
import { copyDirectory } from '../../src/utils/file-copier.js';
|
|
376
|
+
import { fileURLToPath } from 'url';
|
|
377
|
+
import { dirname } from 'path';
|
|
378
|
+
|
|
379
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
380
|
+
const FRAMEWORK_DIR = join(__dirname, '..', '..', 'framework');
|
|
381
|
+
|
|
382
|
+
describe('doctor — .claude artifact checks', () => {
|
|
383
|
+
let tempDir;
|
|
384
|
+
|
|
385
|
+
beforeEach(() => {
|
|
386
|
+
tempDir = createTempDir();
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
afterEach(() => {
|
|
390
|
+
cleanupTempDir(tempDir);
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
test('.claude/rules/ missing → would produce warn', async () => {
|
|
394
|
+
const rulesPath = join(tempDir, '.claude', 'rules');
|
|
395
|
+
const exists = await pathExists(rulesPath);
|
|
396
|
+
assert.equal(exists, false, '.claude/rules/ should not exist in fresh temp dir');
|
|
397
|
+
// Confirms doctor would add a warning
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
test('.claude/rules/ present with 5 files → would produce ok', async () => {
|
|
401
|
+
const rulesSrc = join(FRAMEWORK_DIR, 'rules');
|
|
402
|
+
const rulesDest = join(tempDir, '.claude', 'rules');
|
|
403
|
+
await copyDirectory(rulesSrc, rulesDest);
|
|
404
|
+
const exists = await pathExists(rulesDest);
|
|
405
|
+
assert.ok(exists, '.claude/rules/ must exist after copy');
|
|
406
|
+
const { readdirSync } = await import('fs');
|
|
407
|
+
const files = readdirSync(rulesDest).filter(f => f.endsWith('.md'));
|
|
408
|
+
assert.equal(files.length, 5, 'must have 5 rule files for an ok check');
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
test('.claude/agents/ missing → would produce warn', async () => {
|
|
412
|
+
const agentsPath = join(tempDir, '.claude', 'agents');
|
|
413
|
+
const exists = await pathExists(agentsPath);
|
|
414
|
+
assert.equal(exists, false, '.claude/agents/ should not exist in fresh temp dir');
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
test('.claude/agents/ present with morph- agents → would produce ok', async () => {
|
|
418
|
+
await installAgents(tempDir, FRAMEWORK_DIR);
|
|
419
|
+
const agentsPath = join(tempDir, '.claude', 'agents');
|
|
420
|
+
const exists = await pathExists(agentsPath);
|
|
421
|
+
assert.ok(exists, '.claude/agents/ must exist after installAgents');
|
|
422
|
+
const { readdirSync } = await import('fs');
|
|
423
|
+
const files = readdirSync(agentsPath).filter(f => f.startsWith('morph-'));
|
|
424
|
+
assert.ok(files.length >= 6, `must have at least 6 morph- agents, got ${files.length}`);
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**Step 2: Run the tests**
|
|
430
|
+
|
|
431
|
+
```bash
|
|
432
|
+
npm test -- test/commands/doctor.test.js
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Expected: 4 pass, 0 fail.
|
|
436
|
+
|
|
437
|
+
**Step 3: Commit**
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
git add test/commands/doctor.test.js
|
|
441
|
+
git commit -m "test(doctor): add tests for .claude/rules/ and .claude/agents/ check logic"
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## Task 7: Full test suite + final commit
|
|
447
|
+
|
|
448
|
+
**Step 1: Run full test suite**
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
npm test 2>&1 | tail -10
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
Expected: `pass` count ≥ 596, `fail` 0, `skipped` 1. (Previous baseline: 587 pass.)
|
|
455
|
+
|
|
456
|
+
**Step 2: If any failures, fix them before proceeding**
|
|
457
|
+
|
|
458
|
+
Failing tests mean the plan has a bug. Stop, diagnose, fix — do NOT skip tests.
|
|
459
|
+
|
|
460
|
+
**Step 3: Update memory**
|
|
461
|
+
|
|
462
|
+
Update `MEMORY.md` to reflect the new test count and version.
|
|
463
|
+
|
|
464
|
+
**Step 4: Final commit if anything was missed**
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
git status
|
|
468
|
+
# If clean: nothing to do
|
|
469
|
+
# If not: git add <files> && git commit -m "chore: final cleanup for morph-spec-next"
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## What this plan does NOT include (intentionally)
|
|
475
|
+
|
|
476
|
+
- `.wiki/prompts/` — only one prompt file, still useful for future alignment rounds; no cleanup needed
|
|
477
|
+
- Level 3–4 skill audit — both directories contain only `README.md`; nothing to audit
|
|
478
|
+
- `morph-workflow.md` live injection — rules are static files; the `enrich-prompt.js` hook already handles dynamic state injection and is already focused (no trim needed)
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Design: MORPH-SPEC Native Alignment + State.json Simplification
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-02-22
|
|
4
|
+
**Version target:** 4.5.0
|
|
5
|
+
**Branch:** single branch, all changes together
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
Six focused changes that align MORPH-SPEC closer to Claude Code's native platform patterns and reduce architectural complexity without breaking existing functionality.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Section 1 — Skills File Format Fix
|
|
16
|
+
|
|
17
|
+
**Problem:** `skills-installer.js` installs skills as flat files (`.claude/skills/brainstorming.md`). Native Claude Code format is subdirectory + `SKILL.md` (`.claude/skills/brainstorming/SKILL.md`). Flat format prevents frontmatter features from working (allowed-tools, argument-hint, context:fork).
|
|
18
|
+
|
|
19
|
+
**Design:**
|
|
20
|
+
- `installSkillsFromDir()` creates `<destDir>/<skillName>/SKILL.md` instead of `<destDir>/<skillName>.md`
|
|
21
|
+
- Skill name derived from filename without extension (same as today)
|
|
22
|
+
- All level-0-meta, level-1-workflows, level-2-domains affected
|
|
23
|
+
|
|
24
|
+
**Files:**
|
|
25
|
+
- `src/utils/skills-installer.js` — change flat copy to mkdir + write SKILL.md
|
|
26
|
+
- `test/utils/skills-installer.test.js` — update assertions to check subdirectory format
|
|
27
|
+
- `src/commands/project/update.js` — no change needed (calls installSkills which is updated)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Section 2 — Rules as Dynamic @-imports
|
|
32
|
+
|
|
33
|
+
**Problem:** `framework/rules/*.md` contain static copies of standards content. When standards change, rules become stale until next `morph-spec update`.
|
|
34
|
+
|
|
35
|
+
**Design:** Replace static body content with `@-import` directives pointing to `.morph/framework/standards/` paths in the user project. The `morph-workflow.md` rule keeps its own content (not a standards file).
|
|
36
|
+
|
|
37
|
+
**Files changed:**
|
|
38
|
+
- `framework/rules/csharp-standards.md` — body → @-imports to core/coding.md + backend/dotnet.md
|
|
39
|
+
- `framework/rules/frontend-standards.md` — body → @-imports to frontend/ standards
|
|
40
|
+
- `framework/rules/testing-standards.md` — body → @-imports to core/testing.md
|
|
41
|
+
- `framework/rules/infrastructure-standards.md` — body → @-imports to infrastructure/ standards
|
|
42
|
+
- `framework/rules/morph-workflow.md` — gets new "Test File Policy" section (see Section 4), no @-imports
|
|
43
|
+
|
|
44
|
+
**@-import paths** use `.morph/framework/standards/` because rules are installed into user projects where that path is valid.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Section 3 — CLAUDE.md Consolidation
|
|
49
|
+
|
|
50
|
+
**Problem:** Two separate user-facing CLAUDE.md files (`framework/CLAUDE.md` and `framework/CLAUDE_runtime.md`) with duplicated content and no @-imports for dynamic context.
|
|
51
|
+
|
|
52
|
+
**Design:** Single `framework/CLAUDE.md` that merges both files. Installed to `.claude/CLAUDE.md` in user projects. Uses `@.morph/context/README.md` import for dynamic project context. `framework/CLAUDE_runtime.md` deleted.
|
|
53
|
+
|
|
54
|
+
**New `framework/CLAUDE.md` structure:**
|
|
55
|
+
1. Header + project context @-import
|
|
56
|
+
2. Critical Rules (from current CLAUDE.md)
|
|
57
|
+
3. Quick Reference commands table (from CLAUDE_runtime.md)
|
|
58
|
+
4. State & Outputs table (from CLAUDE_runtime.md)
|
|
59
|
+
5. Phase Sequence (from CLAUDE_runtime.md)
|
|
60
|
+
6. Agents section (from CLAUDE_runtime.md)
|
|
61
|
+
7. MCP CLI deferred mode note (new)
|
|
62
|
+
8. Footer
|
|
63
|
+
|
|
64
|
+
**Files:**
|
|
65
|
+
- `framework/CLAUDE.md` — merged content
|
|
66
|
+
- `framework/CLAUDE_runtime.md` — **deleted**
|
|
67
|
+
- `src/commands/project/init.js` — change source from `CLAUDE_runtime.md` to `CLAUDE.md` for `.claude/CLAUDE.md` install
|
|
68
|
+
- `src/commands/project/update.js` — same change
|
|
69
|
+
- `test/commands/init.test.js` — update source file reference
|
|
70
|
+
- `test/commands/update.test.js` — update source file reference
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Section 4 — Test File Policy in morph-workflow Rule
|
|
75
|
+
|
|
76
|
+
**Problem:** Claude modifies test files to make failing tests pass instead of fixing the implementation. A blocking hook is not appropriate because Claude also needs to legitimately fix incorrect test specs.
|
|
77
|
+
|
|
78
|
+
**Design:** Behavioral rule in `framework/rules/morph-workflow.md` (always-active, no paths filter):
|
|
79
|
+
|
|
80
|
+
```markdown
|
|
81
|
+
## Test File Policy
|
|
82
|
+
|
|
83
|
+
When a test fails, always follow this order:
|
|
84
|
+
1. Analyze whether the IMPLEMENTATION is wrong or the TEST SPEC is wrong
|
|
85
|
+
2. Fix the implementation first
|
|
86
|
+
3. Only modify a test file if the test expectation itself is incorrect
|
|
87
|
+
4. Before modifying a test file, explain WHY the test spec is wrong
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
No new hook. Declarative behavioral guidance over imperative blocking.
|
|
91
|
+
|
|
92
|
+
**Files:**
|
|
93
|
+
- `framework/rules/morph-workflow.md` — add Test File Policy section
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Section 5 — Standards and Templates Additions
|
|
98
|
+
|
|
99
|
+
**5a. TypeScript Strict Mode**
|
|
100
|
+
|
|
101
|
+
Add explicit strict mode section to `framework/rules/frontend-standards.md`:
|
|
102
|
+
- `"strict": true` in tsconfig.json is required
|
|
103
|
+
- Explains why: agents rely on compiler errors to self-correct at compile time
|
|
104
|
+
|
|
105
|
+
**5b. MCP CLI Deferred Mode**
|
|
106
|
+
|
|
107
|
+
Add note to merged `framework/CLAUDE.md`:
|
|
108
|
+
- With 3+ MCPs, add `"experimental": { "mcpCliMode": true }` to settings.json
|
|
109
|
+
- Keeps context window clean; MCP tools load on-demand
|
|
110
|
+
|
|
111
|
+
**5c. User Stories Template**
|
|
112
|
+
|
|
113
|
+
New file `framework/templates/docs/user-stories.md` with format:
|
|
114
|
+
- Story header (feature, priority)
|
|
115
|
+
- Optimal path steps
|
|
116
|
+
- Edge cases
|
|
117
|
+
- Acceptance criteria checklist
|
|
118
|
+
|
|
119
|
+
**Files:**
|
|
120
|
+
- `framework/rules/frontend-standards.md` — add TypeScript strict section (also in @-import content)
|
|
121
|
+
- `framework/CLAUDE.md` — add MCP deferred mode note
|
|
122
|
+
- `framework/templates/docs/user-stories.md` — new template file
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Section 6 — State.json Simplification
|
|
127
|
+
|
|
128
|
+
**Problem:** `state.json` tracks `outputs.{type}.created` and `phase` — both derivable from the filesystem. The `track-output-creation.js` hook exists solely to maintain these two fields and has been the source of synchronization bugs.
|
|
129
|
+
|
|
130
|
+
**Design:**
|
|
131
|
+
|
|
132
|
+
Remove from state.json schema (per feature):
|
|
133
|
+
- `outputs` object (all 12 output types with `created` booleans and `path` strings)
|
|
134
|
+
- `phase` string field
|
|
135
|
+
|
|
136
|
+
Keep in state.json (unchanged):
|
|
137
|
+
- `workflow` — which workflow was auto-selected
|
|
138
|
+
- `approvalGates` — approval status per gate
|
|
139
|
+
- `tasks` — total/completed counts
|
|
140
|
+
- `createdAt` — timestamp
|
|
141
|
+
- `activeAgents` — for display/analytics
|
|
142
|
+
|
|
143
|
+
Derive at runtime:
|
|
144
|
+
```javascript
|
|
145
|
+
// Phase: highest-numbered folder present
|
|
146
|
+
function derivePhase(featurePath) {
|
|
147
|
+
const folders = ['4-implement', '3-tasks', '2-ui', '1-design', '0-proposal'];
|
|
148
|
+
return folders.find(f => fs.existsSync(path.join(featurePath, f))) ?? 'setup';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Output existence: file exists check
|
|
152
|
+
function deriveOutputs(feature, outputDefs) {
|
|
153
|
+
return Object.fromEntries(
|
|
154
|
+
Object.entries(outputDefs).map(([type, relPath]) => [
|
|
155
|
+
type, { created: fs.existsSync(path.join(featureBase, relPath)), path: relPath }
|
|
156
|
+
])
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Migration:** `state-manager.js` migration from v4.x → v5.0 removes `outputs` and `phase` fields on first load if present. Backwards compatible read.
|
|
162
|
+
|
|
163
|
+
**Files:**
|
|
164
|
+
- `src/core/state/state-manager.js` — remove `outputs` + `phase` from `ensureFeature()`, add migration, add `derivePhase()` + `deriveOutputs()` helpers
|
|
165
|
+
- `framework/hooks/claude-code/post-tool-use/track-output-creation.js` — **deleted**
|
|
166
|
+
- `src/utils/hooks-installer.js` — remove `track-output-creation.js` from PostToolUse hook list
|
|
167
|
+
- `src/commands/project/status.js` — update to call `derivePhase()` + `deriveOutputs()`
|
|
168
|
+
- `test/core/state/state-manager.test.js` — remove `outputs`/`phase` tests, add derive helper tests
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## What Does NOT Change
|
|
173
|
+
|
|
174
|
+
- `approvalGates` in state.json — kept, protected by permissions.deny
|
|
175
|
+
- `protect-spec-files.js` hook — kept, still reads approvalGates from state.json
|
|
176
|
+
- All 37 agents in agents.json — unchanged
|
|
177
|
+
- All validators — unchanged
|
|
178
|
+
- All workflow configs — unchanged
|
|
179
|
+
- All Handlebars templates (except new user-stories.md addition)
|
|
180
|
+
- Git hooks — unchanged
|
|
181
|
+
- Agent Teams hooks — unchanged
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Test Strategy
|
|
186
|
+
|
|
187
|
+
All 614 existing tests must pass after changes. New tests added for:
|
|
188
|
+
- `skills-installer.test.js` — verify subdirectory format
|
|
189
|
+
- `state-manager.test.js` — verify `derivePhase()`, `deriveOutputs()`, migration from v4
|
|
190
|
+
- `hooks-installer.test.js` — verify track-output-creation no longer registered
|
|
191
|
+
|
|
192
|
+
No integration tests needed — all changes are unit-testable.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Version Bump
|
|
197
|
+
|
|
198
|
+
`package.json`: `4.4.0` → `4.5.0`
|
|
199
|
+
`framework/CLAUDE.md`: update version in footer
|