@polymorphism-tech/morph-spec 4.7.2 → 4.8.4
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/LICENSE +1 -2
- package/README.md +379 -414
- package/bin/morph-spec.js +57 -394
- package/bin/validate.js +2 -26
- package/claude-plugin.json +2 -2
- package/docs/CHEATSHEET.md +203 -221
- package/docs/QUICKSTART.md +2 -8
- package/framework/CLAUDE.md +1 -1
- package/framework/commands/morph-proposal.md +3 -3
- package/framework/hooks/README.md +2 -5
- package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +4 -55
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +20 -5
- package/framework/hooks/claude-code/statusline.py +6 -1
- package/framework/hooks/dev/check-sync-health.js +117 -0
- package/framework/hooks/dev/guard-version-numbers.js +57 -0
- package/framework/hooks/dev/sync-standards-registry.js +60 -0
- package/framework/hooks/dev/sync-template-registry.js +60 -0
- package/framework/hooks/dev/validate-skill-format.js +70 -0
- package/framework/hooks/dev/validate-standard-format.js +73 -0
- package/framework/hooks/shared/payload-utils.js +39 -0
- package/framework/hooks/shared/state-reader.js +25 -1
- package/framework/rules/morph-workflow.md +1 -1
- package/framework/skills/level-0-meta/morph-init/SKILL.md +216 -0
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +4 -4
- package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +4 -4
- package/framework/skills/level-0-meta/verification-before-completion/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +192 -191
- package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +181 -180
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +339 -338
- package/framework/skills/level-1-workflows/phase-implement/SKILL.md +254 -253
- package/framework/skills/level-1-workflows/phase-setup/SKILL.md +168 -170
- package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +284 -283
- package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +246 -245
- package/framework/templates/examples/design-system-examples.md +1 -1
- package/framework/templates/ui/FluentDesignTheme.cs +1 -1
- package/framework/templates/ui/MudTheme.cs +1 -1
- package/framework/templates/ui/design-system.css +1 -1
- package/package.json +7 -5
- package/src/commands/agents/index.js +1 -2
- package/src/commands/index.js +13 -16
- package/src/commands/project/doctor.js +100 -14
- package/src/commands/project/index.js +7 -10
- package/src/commands/project/init.js +398 -528
- package/src/commands/project/install-plugin-cmd.js +28 -0
- package/src/commands/project/setup-infra-cmd.js +12 -0
- package/src/commands/project/tutorial.js +115 -0
- package/src/commands/state/approve.js +213 -221
- package/src/commands/state/index.js +0 -1
- package/src/commands/state/state.js +337 -365
- package/src/commands/templates/index.js +0 -4
- package/src/commands/trust/trust.js +1 -93
- package/src/commands/utils/index.js +1 -5
- package/src/commands/validation/index.js +1 -5
- package/src/core/registry/command-registry.js +11 -285
- package/src/core/state/state-manager.js +5 -2
- package/src/lib/detectors/index.js +81 -87
- package/src/lib/detectors/structure-detector.js +275 -273
- package/src/lib/generators/recap-generator.js +232 -225
- package/src/scripts/global-install.js +34 -0
- package/src/scripts/install-plugin.js +126 -0
- package/src/scripts/setup-infra.js +203 -0
- package/src/utils/agents-installer.js +10 -1
- package/src/utils/hooks-installer.js +66 -3
- package/.morph/.morphversion +0 -5
- package/.morph/analytics/threads-log.jsonl +0 -5
- package/.morph/config/config.json +0 -8
- package/.morph/framework/agents.json +0 -1815
- package/.morph/framework/hooks/README.md +0 -205
- package/.morph/framework/hooks/claude-code/notification/approval-reminder.js +0 -54
- package/.morph/framework/hooks/claude-code/post-tool-use/dispatch.js +0 -83
- package/.morph/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +0 -42
- package/.morph/framework/hooks/claude-code/pre-compact/save-morph-context.js +0 -61
- package/.morph/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +0 -71
- package/.morph/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +0 -58
- package/.morph/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +0 -64
- package/.morph/framework/hooks/claude-code/session-start/inject-morph-context.js +0 -94
- package/.morph/framework/hooks/claude-code/statusline.py +0 -538
- package/.morph/framework/hooks/claude-code/statusline.sh +0 -7
- package/.morph/framework/hooks/claude-code/stop/validate-completion.js +0 -88
- package/.morph/framework/hooks/claude-code/user-prompt/enrich-prompt.js +0 -91
- package/.morph/framework/hooks/git/commit-msg/conventional-commits.sh +0 -33
- package/.morph/framework/hooks/git/pre-commit/agents.sh +0 -25
- package/.morph/framework/hooks/git/pre-commit/orchestrator.sh +0 -64
- package/.morph/framework/hooks/git/pre-commit/specs.sh +0 -50
- package/.morph/framework/hooks/git/pre-push/run-tests.sh +0 -44
- package/.morph/framework/hooks/shared/hook-response.js +0 -45
- package/.morph/framework/hooks/shared/phase-utils.js +0 -129
- package/.morph/framework/hooks/shared/state-reader.js +0 -138
- package/.morph/framework/hooks/shared/stdin-reader.js +0 -26
- package/.morph/framework/standards/STANDARDS.json +0 -933
- package/.morph/framework/standards/ai-agents/blazor-ui.md +0 -364
- package/.morph/framework/standards/ai-agents/production.md +0 -415
- package/.morph/framework/standards/ai-agents/setup.md +0 -418
- package/.morph/framework/standards/ai-agents/team-orchestration.md +0 -479
- package/.morph/framework/standards/ai-agents/workflows.md +0 -354
- package/.morph/framework/standards/architecture/ddd/aggregates.md +0 -120
- package/.morph/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
- package/.morph/framework/standards/architecture/ddd/complexity-levels.md +0 -108
- package/.morph/framework/standards/architecture/ddd/entities.md +0 -99
- package/.morph/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
- package/.morph/framework/standards/architecture/ddd/value-objects.md +0 -124
- package/.morph/framework/standards/backend/api/minimal-api.md +0 -494
- package/.morph/framework/standards/backend/api/rest.md +0 -492
- package/.morph/framework/standards/backend/api/validation.md +0 -88
- package/.morph/framework/standards/backend/authentication/passkeys.md +0 -428
- package/.morph/framework/standards/backend/database/ef-core.md +0 -199
- package/.morph/framework/standards/backend/database/migrations.md +0 -393
- package/.morph/framework/standards/backend/database/postgresql/database.md +0 -352
- package/.morph/framework/standards/backend/database/repository-patterns.md +0 -528
- package/.morph/framework/standards/backend/database/vector-search-rag.md +0 -541
- package/.morph/framework/standards/backend/dotnet/async.md +0 -366
- package/.morph/framework/standards/backend/dotnet/core.md +0 -117
- package/.morph/framework/standards/backend/dotnet/di.md +0 -439
- package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
- package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +0 -216
- package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +0 -290
- package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +0 -350
- package/.morph/framework/standards/backend/integrations/resend/resend-email.md +0 -385
- package/.morph/framework/standards/context/analytics.md +0 -96
- package/.morph/framework/standards/context/bundles.md +0 -110
- package/.morph/framework/standards/context/priming.md +0 -78
- package/.morph/framework/standards/core/architecture.md +0 -185
- package/.morph/framework/standards/core/coding.md +0 -214
- package/.morph/framework/standards/core/git-branching-strategy.md +0 -403
- package/.morph/framework/standards/core/git.md +0 -185
- package/.morph/framework/standards/core/testing.md +0 -295
- package/.morph/framework/standards/data/nosql/blob-storage.md +0 -102
- package/.morph/framework/standards/data/nosql/cache/redis.md +0 -97
- package/.morph/framework/standards/data/nosql/cosmos-db.md +0 -118
- package/.morph/framework/standards/data/vector-search/azure-ai-search.md +0 -121
- package/.morph/framework/standards/data/vector-search/rag-chunking.md +0 -104
- package/.morph/framework/standards/frontend/blazor/design-checklist.md +0 -222
- package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
- package/.morph/framework/standards/frontend/blazor/fluent-ui.md +0 -137
- package/.morph/framework/standards/frontend/blazor/html-conversion.md +0 -184
- package/.morph/framework/standards/frontend/blazor/lifecycle.md +0 -195
- package/.morph/framework/standards/frontend/blazor/pitfalls.md +0 -198
- package/.morph/framework/standards/frontend/blazor/state.md +0 -191
- package/.morph/framework/standards/frontend/design-system/animations.md +0 -151
- package/.morph/framework/standards/frontend/design-system/naming.md +0 -64
- package/.morph/framework/standards/frontend/nextjs/app-router.md +0 -123
- package/.morph/framework/standards/frontend/nextjs/components.md +0 -132
- package/.morph/framework/standards/frontend/nextjs/data-fetching.md +0 -126
- package/.morph/framework/standards/frontend/nextjs/forms.md +0 -128
- package/.morph/framework/standards/frontend/nextjs/naming-conventions.md +0 -67
- package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +0 -215
- package/.morph/framework/standards/frontend/nextjs/project-structure.md +0 -102
- package/.morph/framework/standards/frontend/nextjs/state-management.md +0 -72
- package/.morph/framework/standards/frontend/nextjs/testing.md +0 -111
- package/.morph/framework/standards/infrastructure/azure/azure.md +0 -624
- package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
- package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
- package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
- package/.morph/framework/standards/infrastructure/azure/services/functions.md +0 -486
- package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
- package/.morph/framework/standards/infrastructure/azure/services/storage.md +0 -407
- package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +0 -196
- package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +0 -252
- package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
- package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
- package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
- package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
- package/.morph/framework/standards/integration/api/graphql.md +0 -91
- package/.morph/framework/standards/integration/api/grpc.md +0 -114
- package/.morph/framework/standards/integration/api/rest-design.md +0 -95
- package/.morph/framework/standards/integration/event-driven/cqrs.md +0 -101
- package/.morph/framework/standards/integration/event-driven/event-sourcing.md +0 -124
- package/.morph/framework/standards/integration/event-driven/service-bus.md +0 -95
- package/.morph/framework/standards/integration/mcp/mcp-tools.md +0 -384
- package/.morph/framework/standards/observability/logging.md +0 -131
- package/.morph/framework/standards/observability/metrics.md +0 -121
- package/.morph/framework/standards/observability/monitoring.md +0 -114
- package/.morph/framework/standards/observability/tracing.md +0 -132
- package/.morph/framework/standards/workflows/parallel-execution.md +0 -112
- package/.morph/framework/standards/workflows/thread-management.md +0 -113
- package/.morph/framework/templates/.idea/morph-templates.xml +0 -92
- package/.morph/framework/templates/.vscode/morph-templates.code-snippets +0 -186
- package/.morph/framework/templates/IDE-SNIPPETS.md +0 -266
- package/.morph/framework/templates/README.md +0 -814
- package/.morph/framework/templates/REGISTRY.json +0 -1888
- package/.morph/framework/templates/code/dotnet/backend/repository.cs +0 -141
- package/.morph/framework/templates/code/dotnet/backend/service.cs +0 -139
- package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
- package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
- package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
- package/.morph/framework/templates/code/dotnet/contracts/README.md +0 -74
- package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
- package/.morph/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
- package/.morph/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
- package/.morph/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
- package/.morph/framework/templates/code/dotnet/database/migration.cs +0 -83
- package/.morph/framework/templates/code/dotnet/frontend/component.razor +0 -239
- package/.morph/framework/templates/code/dotnet/jobs/agent.cs +0 -163
- package/.morph/framework/templates/code/dotnet/jobs/job.cs +0 -171
- package/.morph/framework/templates/code/dotnet/test.cs +0 -239
- package/.morph/framework/templates/code/sql/rls-policy.sql +0 -57
- package/.morph/framework/templates/code/sql/supabase-migration.sql +0 -100
- package/.morph/framework/templates/code/sql/supabase-migration.template.sql +0 -113
- package/.morph/framework/templates/code/typescript/contracts.ts +0 -168
- package/.morph/framework/templates/context/CONTEXT-FEATURE.md +0 -276
- package/.morph/framework/templates/context/CONTEXT.md +0 -181
- package/.morph/framework/templates/docs/clarifications.md +0 -253
- package/.morph/framework/templates/docs/onboarding.md +0 -123
- package/.morph/framework/templates/docs/proposal.md +0 -182
- package/.morph/framework/templates/docs/schema-analysis.md +0 -119
- package/.morph/framework/templates/docs/spec.md +0 -198
- package/.morph/framework/templates/docs/ui-components.md +0 -124
- package/.morph/framework/templates/docs/ui-design-system.md +0 -76
- package/.morph/framework/templates/docs/ui-flows.md +0 -167
- package/.morph/framework/templates/docs/ui-mockups.md +0 -98
- package/.morph/framework/templates/docs/user-stories.md +0 -34
- package/.morph/framework/templates/examples/design-system-examples.md +0 -357
- package/.morph/framework/templates/examples/spec-examples.md +0 -90
- package/.morph/framework/templates/feature/decisions.md +0 -187
- package/.morph/framework/templates/feature/recap.md +0 -146
- package/.morph/framework/templates/feature/tasks.md +0 -199
- package/.morph/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +0 -43
- package/.morph/framework/templates/frontend/nextjs/client-component.tsx.hbs +0 -26
- package/.morph/framework/templates/frontend/nextjs/env.mjs.hbs +0 -32
- package/.morph/framework/templates/frontend/nextjs/feature-form.tsx.hbs +0 -56
- package/.morph/framework/templates/frontend/nextjs/page.tsx.hbs +0 -22
- package/.morph/framework/templates/frontend/nextjs/tsconfig.json.hbs +0 -26
- package/.morph/framework/templates/frontend/nextjs/use-feature.ts.hbs +0 -54
- package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
- package/.morph/framework/templates/infrastructure/azure/README.md +0 -286
- package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
- package/.morph/framework/templates/infrastructure/azure/app-service.bicep +0 -164
- package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
- package/.morph/framework/templates/infrastructure/azure/container-app.bicep +0 -156
- package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
- package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
- package/.morph/framework/templates/infrastructure/azure/deploy.sh +0 -208
- package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
- package/.morph/framework/templates/infrastructure/azure/main.bicep +0 -189
- package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
- package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
- package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
- package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
- package/.morph/framework/templates/infrastructure/azure/storage.bicep +0 -106
- package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +0 -58
- package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +0 -67
- package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +0 -38
- package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +0 -48
- package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +0 -54
- package/.morph/framework/templates/infrastructure/github/README.md +0 -593
- package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
- package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -45
- package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +0 -27
- package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
- package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -31
- package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -59
- package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -39
- package/.morph/framework/templates/integrations/asaas-client.cs +0 -387
- package/.morph/framework/templates/integrations/asaas-webhook.cs +0 -351
- package/.morph/framework/templates/integrations/azure-identity-config.cs +0 -288
- package/.morph/framework/templates/integrations/clerk-config.cs +0 -258
- package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +0 -76
- package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +0 -100
- package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
- package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
- package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
- package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
- package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
- package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +0 -90
- package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +0 -126
- package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +0 -43
- package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +0 -107
- package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +0 -95
- package/.morph/framework/templates/project-structure/dotnet-ddd.md +0 -70
- package/.morph/framework/templates/saas/subscription.cs +0 -347
- package/.morph/framework/templates/saas/tenant.cs +0 -338
- package/.morph/framework/templates/state.template.json +0 -17
- package/.morph/framework/templates/ui/FluentDesignTheme.cs +0 -149
- package/.morph/framework/templates/ui/MudTheme.cs +0 -281
- package/.morph/framework/templates/ui/design-system.css +0 -226
- package/.morph/logs/tool-failures.log +0 -17
- package/.morph/memory/pre-compact-2026-02-24T17-43-30-049Z.json +0 -16
- package/.morph/plans/eager-watching-bunny.md +0 -105
- package/.morph/plans/temporal-seeking-nebula.md +0 -45
- package/.morph/state.json +0 -48
- package/CLAUDE.md +0 -77
- package/docs/ARCHITECTURE.md +0 -331
- package/docs/COMMAND-FLOWS.md +0 -368
- package/docs/claude-alignment-report.md +0 -137
- package/docs/examples/order-management/contracts.cs +0 -84
- package/docs/examples/order-management/proposal.md +0 -24
- package/docs/examples/order-management/spec.md +0 -162
- package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +0 -512
- package/docs/plans/2026-02-22-claude-settings.md +0 -515
- package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +0 -728
- package/docs/plans/2026-02-22-morph-spec-next.md +0 -478
- package/docs/plans/2026-02-22-native-alignment-design.md +0 -199
- package/docs/plans/2026-02-22-native-alignment-impl.md +0 -925
- package/docs/plans/2026-02-22-native-enrichment-design.md +0 -244
- package/docs/plans/2026-02-22-native-enrichment.md +0 -735
- package/docs/plans/2026-02-23-ddd-architecture-refactor.md +0 -1153
- package/docs/plans/2026-02-23-ddd-nextsteps.md +0 -682
- package/docs/plans/2026-02-23-infra-architect-refactor.md +0 -437
- package/docs/plans/2026-02-23-nextjs-code-review-design.md +0 -156
- package/docs/plans/2026-02-23-nextjs-code-review-impl.md +0 -1254
- package/docs/plans/2026-02-23-nextjs-standards-design.md +0 -149
- package/docs/plans/2026-02-23-nextjs-standards-impl.md +0 -1846
- package/scripts/generate-refs.js +0 -336
- package/scripts/generate-standards-registry.js +0 -44
- package/scripts/scan-nextjs.mjs +0 -169
- package/scripts/validate-real.mjs +0 -255
- package/src/commands/feature/create-story.js +0 -362
- package/src/commands/feature/index.js +0 -6
- package/src/commands/feature/shard-spec.js +0 -225
- package/src/commands/feature/sprint-status.js +0 -250
- package/src/commands/generation/generate-onboarding.js +0 -169
- package/src/commands/generation/generate.js +0 -276
- package/src/commands/generation/index.js +0 -5
- package/src/commands/learning/capture-pattern.js +0 -121
- package/src/commands/learning/index.js +0 -5
- package/src/commands/learning/search-patterns.js +0 -126
- package/src/commands/mcp/mcp.js +0 -102
- package/src/commands/project/changes.js +0 -66
- package/src/commands/project/cost.js +0 -179
- package/src/commands/project/diff.js +0 -278
- package/src/commands/project/revert.js +0 -173
- package/src/commands/project/standards.js +0 -80
- package/src/commands/project/sync.js +0 -167
- package/src/commands/project/update-agents.js +0 -23
- package/src/commands/state/rollback-phase.js +0 -185
- package/src/commands/templates/template-customize.js +0 -87
- package/src/commands/templates/template-list.js +0 -114
- package/src/commands/templates/template-show.js +0 -129
- package/src/commands/templates/template-validate.js +0 -91
- package/src/commands/utils/troubleshoot.js +0 -222
- package/src/commands/validation/analyze-blazor-concurrency.js +0 -193
- package/src/commands/validation/lint-fluent.js +0 -352
- package/src/commands/validation/validate-blazor-state.js +0 -210
- package/src/commands/validation/validate-blazor.js +0 -156
- package/src/commands/validation/validate-css.js +0 -84
- package/src/lib/detectors/conversation-analyzer.js +0 -163
- package/src/lib/learning/index.js +0 -7
- package/src/lib/learning/learning-system.js +0 -520
- package/src/lib/troubleshooting/index.js +0 -8
- package/src/lib/troubleshooting/troubleshoot-grep.js +0 -198
- package/src/lib/troubleshooting/troubleshoot-index.js +0 -144
- package/src/llm/environment-detector.js +0 -43
|
@@ -1,925 +0,0 @@
|
|
|
1
|
-
# Native Alignment Implementation Plan
|
|
2
|
-
|
|
3
|
-
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
-
|
|
5
|
-
**Goal:** Align MORPH-SPEC with Claude Code's native platform patterns across 6 areas: skills format, rules as @-imports, CLAUDE.md consolidation, test file policy, standards additions, and state.json simplification.
|
|
6
|
-
|
|
7
|
-
**Architecture:** Non-breaking changes first (Tasks 1-5), state.json simplification last (Tasks 6-8). All 614 existing tests must pass at each commit. Each task is independently testable.
|
|
8
|
-
|
|
9
|
-
**Tech Stack:** Node.js ESM, `node:test`, `node:fs`, `node:path`. Run tests with `npm test`. Single test file: `node --test test/path/to/file.test.js`.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Task 1: Fix Skills File Format (flat → subdirectory/SKILL.md)
|
|
14
|
-
|
|
15
|
-
**Files:**
|
|
16
|
-
- Modify: `src/utils/skills-installer.js`
|
|
17
|
-
- Modify: `test/utils/skills-installer.test.js`
|
|
18
|
-
|
|
19
|
-
**Context:** Claude Code's native skill format is `.claude/skills/<name>/SKILL.md`, not `.claude/skills/<name>.md`. Flat files prevent frontmatter features (allowed-tools, argument-hint) from working. Current code in `installSkillsFromDir()` does `copyFileSync(srcPath, join(destDir, entry))` — we change it to `mkdir(join(destDir, skillName))` + `copyFile(srcPath, join(destDir, skillName, 'SKILL.md'))`.
|
|
20
|
-
|
|
21
|
-
**Step 1: Update skills-installer.js**
|
|
22
|
-
|
|
23
|
-
Replace the body of `installSkillsFromDir` in `src/utils/skills-installer.js`:
|
|
24
|
-
|
|
25
|
-
```javascript
|
|
26
|
-
function installSkillsFromDir(srcDir, destDir) {
|
|
27
|
-
const entries = readdirSync(srcDir);
|
|
28
|
-
for (const entry of entries) {
|
|
29
|
-
const srcPath = join(srcDir, entry);
|
|
30
|
-
const stat = statSync(srcPath);
|
|
31
|
-
|
|
32
|
-
if (stat.isDirectory()) {
|
|
33
|
-
installSkillsFromDir(srcPath, destDir);
|
|
34
|
-
} else if (entry.endsWith('.md') && entry !== 'README.md') {
|
|
35
|
-
const skillName = entry.slice(0, -3); // strip .md
|
|
36
|
-
const skillDir = join(destDir, skillName);
|
|
37
|
-
mkdirSync(skillDir, { recursive: true });
|
|
38
|
-
copyFileSync(srcPath, join(skillDir, 'SKILL.md'));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Also add `mkdirSync` to the imports at line 11:
|
|
45
|
-
```javascript
|
|
46
|
-
import { mkdirSync, copyFileSync, existsSync, readdirSync, statSync } from 'fs';
|
|
47
|
-
```
|
|
48
|
-
(mkdirSync is already imported — verify it's there, add if missing)
|
|
49
|
-
|
|
50
|
-
**Step 2: Run single test file to verify it fails**
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
node --test test/utils/skills-installer.test.js
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Expected: FAIL — assertions check for `.md` filenames like `morph-checklist.md` which no longer exist.
|
|
57
|
-
|
|
58
|
-
**Step 3: Update skills-installer.test.js**
|
|
59
|
-
|
|
60
|
-
Replace the entire test file content:
|
|
61
|
-
|
|
62
|
-
```javascript
|
|
63
|
-
/**
|
|
64
|
-
* Tests for src/utils/skills-installer.js
|
|
65
|
-
*/
|
|
66
|
-
|
|
67
|
-
import { test, describe, before, after } from 'node:test';
|
|
68
|
-
import assert from 'node:assert/strict';
|
|
69
|
-
import { mkdtemp, rm, readdir, stat } from 'node:fs/promises';
|
|
70
|
-
import { join } from 'path';
|
|
71
|
-
import { tmpdir } from 'os';
|
|
72
|
-
import { installSkills } from '../../src/utils/skills-installer.js';
|
|
73
|
-
|
|
74
|
-
describe('installSkills', () => {
|
|
75
|
-
let tmpDir;
|
|
76
|
-
|
|
77
|
-
before(async () => {
|
|
78
|
-
tmpDir = await mkdtemp(join(tmpdir(), 'morph-skills-'));
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
after(async () => {
|
|
82
|
-
await rm(tmpDir, { recursive: true, force: true });
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
test('creates .claude/skills/ directory', async () => {
|
|
86
|
-
await installSkills(tmpDir);
|
|
87
|
-
const entries = await readdir(join(tmpDir, '.claude', 'skills'));
|
|
88
|
-
assert.ok(entries.length > 0, 'should have skill directories installed');
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test('installs skills as subdirectories (not flat .md files)', async () => {
|
|
92
|
-
await installSkills(tmpDir);
|
|
93
|
-
const entries = await readdir(join(tmpDir, '.claude', 'skills'));
|
|
94
|
-
// All entries should be directories, not .md files
|
|
95
|
-
for (const entry of entries) {
|
|
96
|
-
assert.ok(!entry.endsWith('.md'), `${entry} should be a directory, not a flat .md file`);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test('each skill directory contains SKILL.md', async () => {
|
|
101
|
-
await installSkills(tmpDir);
|
|
102
|
-
const entries = await readdir(join(tmpDir, '.claude', 'skills'));
|
|
103
|
-
for (const entry of entries) {
|
|
104
|
-
const skillMd = join(tmpDir, '.claude', 'skills', entry, 'SKILL.md');
|
|
105
|
-
const s = await stat(skillMd).catch(() => null);
|
|
106
|
-
assert.ok(s?.isFile(), `${entry}/SKILL.md should exist and be a file`);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test('installs level-0-meta skills (morph-checklist, code-review)', async () => {
|
|
111
|
-
await installSkills(tmpDir);
|
|
112
|
-
const entries = await readdir(join(tmpDir, '.claude', 'skills'));
|
|
113
|
-
assert.ok(entries.includes('morph-checklist'), 'morph-checklist/ directory should be installed');
|
|
114
|
-
assert.ok(entries.includes('code-review'), 'code-review/ directory should be installed');
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
test('installs level-1-workflows skills (phase-design, phase-implement)', async () => {
|
|
118
|
-
await installSkills(tmpDir);
|
|
119
|
-
const entries = await readdir(join(tmpDir, '.claude', 'skills'));
|
|
120
|
-
assert.ok(entries.includes('phase-design'), 'phase-design/ directory should be installed');
|
|
121
|
-
assert.ok(entries.includes('phase-implement'), 'phase-implement/ directory should be installed');
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
test('does not install README.md files as skills', async () => {
|
|
125
|
-
await installSkills(tmpDir);
|
|
126
|
-
const entries = await readdir(join(tmpDir, '.claude', 'skills'));
|
|
127
|
-
assert.ok(!entries.includes('README'), 'README should not be installed as a skill');
|
|
128
|
-
assert.ok(!entries.includes('README.md'), 'README.md should not appear in skills dir');
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test('installs at least 10 skills total', async () => {
|
|
132
|
-
await installSkills(tmpDir);
|
|
133
|
-
const entries = await readdir(join(tmpDir, '.claude', 'skills'));
|
|
134
|
-
assert.ok(entries.length >= 10, `should install at least 10 skills, got ${entries.length}`);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
test('is idempotent — running twice produces same directory count', async () => {
|
|
138
|
-
await installSkills(tmpDir);
|
|
139
|
-
const firstCount = (await readdir(join(tmpDir, '.claude', 'skills'))).length;
|
|
140
|
-
await installSkills(tmpDir);
|
|
141
|
-
const secondCount = (await readdir(join(tmpDir, '.claude', 'skills'))).length;
|
|
142
|
-
assert.strictEqual(firstCount, secondCount, 'directory count should not change on second run');
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
**Step 4: Run test to verify it passes**
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
node --test test/utils/skills-installer.test.js
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
Expected: all 8 tests PASS.
|
|
154
|
-
|
|
155
|
-
**Step 5: Run full suite**
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
|
-
npm test
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
Expected: 614+ tests pass, 0 fail.
|
|
162
|
-
|
|
163
|
-
**Step 6: Commit**
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
git add src/utils/skills-installer.js test/utils/skills-installer.test.js
|
|
167
|
-
git commit -m "feat(skills): install as subdirectory/SKILL.md — native Claude Code format"
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
## Task 2: Rules as Dynamic @-imports
|
|
173
|
-
|
|
174
|
-
**Files:**
|
|
175
|
-
- Modify: `framework/rules/csharp-standards.md`
|
|
176
|
-
- Modify: `framework/rules/frontend-standards.md`
|
|
177
|
-
- Modify: `framework/rules/testing-standards.md`
|
|
178
|
-
- Modify: `framework/rules/infrastructure-standards.md`
|
|
179
|
-
|
|
180
|
-
**Context:** Rules currently contain static copies of standards content. Replacing with @-imports makes them always current. The @-import paths use `.morph/framework/standards/` because rules are installed into user projects where that path is valid after `morph-spec init`. `morph-workflow.md` is NOT changed here — it has its own content (not a standards file).
|
|
181
|
-
|
|
182
|
-
No code changes — only markdown content changes. No tests needed (framework content files have no unit tests).
|
|
183
|
-
|
|
184
|
-
**Step 1: Replace csharp-standards.md body**
|
|
185
|
-
|
|
186
|
-
Replace everything after the frontmatter (after line 5 `---`) in `framework/rules/csharp-standards.md` with:
|
|
187
|
-
|
|
188
|
-
```markdown
|
|
189
|
-
---
|
|
190
|
-
paths:
|
|
191
|
-
- "**/*.cs"
|
|
192
|
-
- "**/*.csproj"
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
# C# and .NET Standards
|
|
196
|
-
|
|
197
|
-
@.morph/framework/standards/core/coding.md
|
|
198
|
-
@.morph/framework/standards/backend/dotnet.md
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
> **Note:** Verify the exact filenames exist in `framework/standards/core/` and `framework/standards/backend/`. Run `ls framework/standards/core/` and `ls framework/standards/backend/` first. Use the actual filenames found.
|
|
202
|
-
|
|
203
|
-
**Step 2: Replace frontend-standards.md body**
|
|
204
|
-
|
|
205
|
-
```markdown
|
|
206
|
-
---
|
|
207
|
-
paths:
|
|
208
|
-
- "**/*.razor"
|
|
209
|
-
- "**/*.tsx"
|
|
210
|
-
- "**/*.ts"
|
|
211
|
-
- "**/*.css"
|
|
212
|
-
- "**/*.scss"
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
# Frontend Standards
|
|
216
|
-
|
|
217
|
-
@.morph/framework/standards/frontend/blazor.md
|
|
218
|
-
@.morph/framework/standards/frontend/nextjs.md
|
|
219
|
-
@.morph/framework/standards/frontend/css.md
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
> Same note: verify filenames first with `ls framework/standards/frontend/`.
|
|
223
|
-
|
|
224
|
-
**Step 3: Replace testing-standards.md body**
|
|
225
|
-
|
|
226
|
-
```markdown
|
|
227
|
-
---
|
|
228
|
-
paths:
|
|
229
|
-
- "tests/**"
|
|
230
|
-
- "**/*.test.*"
|
|
231
|
-
- "**/*.spec.*"
|
|
232
|
-
- "**/*Tests.cs"
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
# Testing Standards
|
|
236
|
-
|
|
237
|
-
@.morph/framework/standards/core/testing.md
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
**Step 4: Replace infrastructure-standards.md body**
|
|
241
|
-
|
|
242
|
-
```markdown
|
|
243
|
-
---
|
|
244
|
-
paths:
|
|
245
|
-
- "**/*.bicep"
|
|
246
|
-
- "**/Dockerfile"
|
|
247
|
-
- "**/docker-compose*.yml"
|
|
248
|
-
- "**/pipelines/**"
|
|
249
|
-
- "**/.github/workflows/**"
|
|
250
|
-
---
|
|
251
|
-
|
|
252
|
-
# Infrastructure Standards
|
|
253
|
-
|
|
254
|
-
@.morph/framework/standards/infrastructure/azure.md
|
|
255
|
-
@.morph/framework/standards/infrastructure/docker.md
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**Step 5: Verify actual standard filenames before writing**
|
|
259
|
-
|
|
260
|
-
```bash
|
|
261
|
-
ls framework/standards/core/
|
|
262
|
-
ls framework/standards/backend/
|
|
263
|
-
ls framework/standards/frontend/
|
|
264
|
-
ls framework/standards/infrastructure/
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
Adjust @-import paths above to match actual filenames.
|
|
268
|
-
|
|
269
|
-
**Step 6: Run full suite (no tests for framework content, but verify nothing broke)**
|
|
270
|
-
|
|
271
|
-
```bash
|
|
272
|
-
npm test
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
Expected: same pass count as before.
|
|
276
|
-
|
|
277
|
-
**Step 7: Commit**
|
|
278
|
-
|
|
279
|
-
```bash
|
|
280
|
-
git add framework/rules/csharp-standards.md framework/rules/frontend-standards.md framework/rules/testing-standards.md framework/rules/infrastructure-standards.md
|
|
281
|
-
git commit -m "feat(rules): replace static content with @-imports from framework/standards"
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
---
|
|
285
|
-
|
|
286
|
-
## Task 3: CLAUDE.md Consolidation
|
|
287
|
-
|
|
288
|
-
**Files:**
|
|
289
|
-
- Modify: `framework/CLAUDE.md` — merge both files into one
|
|
290
|
-
- Delete: `framework/CLAUDE_runtime.md`
|
|
291
|
-
- Modify: `src/commands/project/init.js` — change CLAUDE_runtime.md → CLAUDE.md as source
|
|
292
|
-
- Modify: `src/commands/project/update.js` — same
|
|
293
|
-
- Modify: `test/commands/init.test.js` — update source file reference
|
|
294
|
-
- Modify: `test/commands/update.test.js` — update source file reference
|
|
295
|
-
|
|
296
|
-
**Context:** `init.js` copies `framework/CLAUDE_runtime.md` → `.claude/CLAUDE.md` in user projects. After this task, it copies `framework/CLAUDE.md` instead. The merged file has all content from both plus MCP deferred mode note.
|
|
297
|
-
|
|
298
|
-
**Step 1: Find the CLAUDE_runtime.md copy line in init.js**
|
|
299
|
-
|
|
300
|
-
```bash
|
|
301
|
-
grep -n "CLAUDE_runtime" src/commands/project/init.js
|
|
302
|
-
grep -n "CLAUDE_runtime" src/commands/project/update.js
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
Note the exact line numbers.
|
|
306
|
-
|
|
307
|
-
**Step 2: Write new merged framework/CLAUDE.md**
|
|
308
|
-
|
|
309
|
-
Replace the entire content of `framework/CLAUDE.md`:
|
|
310
|
-
|
|
311
|
-
```markdown
|
|
312
|
-
# MORPH-SPEC Runtime Instructions
|
|
313
|
-
|
|
314
|
-
> by Polymorphism Tech — Spec-driven development for .NET/Blazor/Next.js/Azure
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## Project Context
|
|
319
|
-
|
|
320
|
-
@.morph/context/README.md
|
|
321
|
-
|
|
322
|
-
---
|
|
323
|
-
|
|
324
|
-
## Critical Rules
|
|
325
|
-
|
|
326
|
-
**NEVER:**
|
|
327
|
-
- Skip to code without a specification
|
|
328
|
-
- Implement without design approval
|
|
329
|
-
- Ignore standards in `.morph/framework/standards/`
|
|
330
|
-
- Create infrastructure manually
|
|
331
|
-
- Generate code without defined contracts
|
|
332
|
-
|
|
333
|
-
**ALWAYS:**
|
|
334
|
-
- Follow the mandatory phases
|
|
335
|
-
- Generate outputs in `.morph/features/{feature}/`
|
|
336
|
-
- Document decisions in `decisions.md`
|
|
337
|
-
- Checkpoint every 3 implemented tasks
|
|
338
|
-
- Use Infrastructure as Code
|
|
339
|
-
|
|
340
|
-
---
|
|
341
|
-
|
|
342
|
-
## Quick Reference
|
|
343
|
-
|
|
344
|
-
| Command | Purpose |
|
|
345
|
-
|---------|---------|
|
|
346
|
-
| `/morph-proposal {feature}` | Full spec pipeline (phases 1–4, pauses for approval) |
|
|
347
|
-
| `/morph-apply {feature}` | Implement feature (phase 5) |
|
|
348
|
-
| `/morph-status` | Feature status dashboard |
|
|
349
|
-
| `/morph-preflight` | Pre-implementation validation |
|
|
350
|
-
|
|
351
|
-
---
|
|
352
|
-
|
|
353
|
-
## State & Outputs
|
|
354
|
-
|
|
355
|
-
| Path | Notes |
|
|
356
|
-
|------|-------|
|
|
357
|
-
| `.morph/state.json` | **READ-ONLY** — use `morph-spec` CLI to update |
|
|
358
|
-
| `.morph/features/{feature}/{phase}/` | Feature outputs organized by phase |
|
|
359
|
-
| `.morph/framework/` | **READ-ONLY** — framework files managed by morph-spec |
|
|
360
|
-
| `.morph/config/config.json` | Project configuration (editable) |
|
|
361
|
-
|
|
362
|
-
---
|
|
363
|
-
|
|
364
|
-
## Phase Sequence
|
|
365
|
-
|
|
366
|
-
```
|
|
367
|
-
proposal → setup → [uiux] → design → clarify → tasks → implement → [sync]
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
Use `morph-spec state show {feature}` to see current phase and pending approval gates.
|
|
371
|
-
|
|
372
|
-
---
|
|
373
|
-
|
|
374
|
-
## Agents
|
|
375
|
-
|
|
376
|
-
Tier-1 and tier-2 MORPH agents are available as native subagents in `.claude/agents/`.
|
|
377
|
-
They can be invoked directly by Claude Code during multi-agent workflows.
|
|
378
|
-
|
|
379
|
-
---
|
|
380
|
-
|
|
381
|
-
## Context Window Tip
|
|
382
|
-
|
|
383
|
-
When using 3+ MCPs, add `"experimental": { "mcpCliMode": true }` to `.claude/settings.json`.
|
|
384
|
-
MCP tools load on-demand instead of all at startup — keeps context clean for actual work.
|
|
385
|
-
|
|
386
|
-
---
|
|
387
|
-
|
|
388
|
-
*MORPH-SPEC v4.5.0 by Polymorphism Tech*
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
**Step 3: Update init.js source reference**
|
|
392
|
-
|
|
393
|
-
Find the line that copies CLAUDE_runtime.md and change it to CLAUDE.md. It will look something like:
|
|
394
|
-
|
|
395
|
-
```javascript
|
|
396
|
-
// BEFORE (find exact line with grep result from Step 1):
|
|
397
|
-
await copyFile(join(frameworkDir, 'CLAUDE_runtime.md'), join(projectDir, '.claude', 'CLAUDE.md'));
|
|
398
|
-
|
|
399
|
-
// AFTER:
|
|
400
|
-
await copyFile(join(frameworkDir, 'CLAUDE.md'), join(projectDir, '.claude', 'CLAUDE.md'));
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
**Step 4: Update update.js source reference**
|
|
404
|
-
|
|
405
|
-
Same change in `src/commands/project/update.js`.
|
|
406
|
-
|
|
407
|
-
**Step 5: Run test files to find failing assertions**
|
|
408
|
-
|
|
409
|
-
```bash
|
|
410
|
-
node --test test/commands/init.test.js
|
|
411
|
-
node --test test/commands/update.test.js
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
Find any assertions referencing `CLAUDE_runtime.md` and change them to `CLAUDE.md`.
|
|
415
|
-
|
|
416
|
-
**Step 6: Delete framework/CLAUDE_runtime.md**
|
|
417
|
-
|
|
418
|
-
```bash
|
|
419
|
-
git rm framework/CLAUDE_runtime.md
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
**Step 7: Run full suite**
|
|
423
|
-
|
|
424
|
-
```bash
|
|
425
|
-
npm test
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
Expected: same pass count, 0 fail.
|
|
429
|
-
|
|
430
|
-
**Step 8: Commit**
|
|
431
|
-
|
|
432
|
-
```bash
|
|
433
|
-
git add framework/CLAUDE.md src/commands/project/init.js src/commands/project/update.js test/commands/init.test.js test/commands/update.test.js
|
|
434
|
-
git commit -m "feat(claude-md): merge CLAUDE.md + CLAUDE_runtime.md into single unified file"
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
---
|
|
438
|
-
|
|
439
|
-
## Task 4: Test File Policy in morph-workflow.md
|
|
440
|
-
|
|
441
|
-
**Files:**
|
|
442
|
-
- Modify: `framework/rules/morph-workflow.md`
|
|
443
|
-
|
|
444
|
-
**Context:** No hook — behavioral guidance only. Add "Test File Policy" section at the end of the file (before the final `*MORPH-SPEC by Polymorphism Tech*` footer). No tests needed.
|
|
445
|
-
|
|
446
|
-
**Step 1: Add section to framework/rules/morph-workflow.md**
|
|
447
|
-
|
|
448
|
-
Append before the final footer line:
|
|
449
|
-
|
|
450
|
-
```markdown
|
|
451
|
-
---
|
|
452
|
-
|
|
453
|
-
## Test File Policy
|
|
454
|
-
|
|
455
|
-
When a test fails, always follow this order:
|
|
456
|
-
|
|
457
|
-
1. **Analyze first** — determine if the IMPLEMENTATION is wrong or the TEST SPEC is wrong
|
|
458
|
-
2. **Fix implementation first** — the test is the spec; trust it by default
|
|
459
|
-
3. **Only modify a test file if the test expectation itself is incorrect** — wrong expected value, wrong behavior modeled
|
|
460
|
-
4. **Before modifying any test file, explain WHY the test spec is wrong** — what the correct behavior is and why the test doesn't model it
|
|
461
|
-
|
|
462
|
-
Do not modify test files to make a failing test pass when the implementation is the actual problem.
|
|
463
|
-
|
|
464
|
-
---
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
**Step 2: Run full suite**
|
|
468
|
-
|
|
469
|
-
```bash
|
|
470
|
-
npm test
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
Expected: same pass count.
|
|
474
|
-
|
|
475
|
-
**Step 3: Commit**
|
|
476
|
-
|
|
477
|
-
```bash
|
|
478
|
-
git add framework/rules/morph-workflow.md
|
|
479
|
-
git commit -m "feat(rules): add Test File Policy to morph-workflow rule"
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
---
|
|
483
|
-
|
|
484
|
-
## Task 5: Standards and Templates Additions
|
|
485
|
-
|
|
486
|
-
**Files:**
|
|
487
|
-
- Modify: `framework/rules/frontend-standards.md` — note: already updated in Task 2 with @-imports, so also update the source standard file
|
|
488
|
-
- Create: `framework/templates/docs/user-stories.md`
|
|
489
|
-
|
|
490
|
-
**Context:** TypeScript strict mode guidance goes into the actual standards file (which the rule now @-imports). User stories template is a new Handlebars template.
|
|
491
|
-
|
|
492
|
-
**Step 1: Check if TypeScript strict is already in frontend standards**
|
|
493
|
-
|
|
494
|
-
```bash
|
|
495
|
-
grep -r "strict" framework/standards/frontend/
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
If not present, add to the appropriate standards file (e.g., `framework/standards/frontend/typescript.md` or whatever file exists):
|
|
499
|
-
|
|
500
|
-
```markdown
|
|
501
|
-
## TypeScript Strict Mode (Required)
|
|
502
|
-
|
|
503
|
-
Always enable `"strict": true` in `tsconfig.json`. This is non-negotiable for
|
|
504
|
-
agent-assisted development because agents rely on compiler errors to self-correct.
|
|
505
|
-
Without strict mode, type/null errors only surface at runtime where agents cannot observe them.
|
|
506
|
-
|
|
507
|
-
```json
|
|
508
|
-
{
|
|
509
|
-
"compilerOptions": {
|
|
510
|
-
"strict": true,
|
|
511
|
-
"noUncheckedIndexedAccess": true
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
Strict mode enables: `strictNullChecks`, `noImplicitAny`, `strictFunctionTypes`, `strictPropertyInitialization`.
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
**Step 2: Create framework/templates/docs/user-stories.md**
|
|
520
|
-
|
|
521
|
-
```markdown
|
|
522
|
-
# User Stories: {{featureName}}
|
|
523
|
-
|
|
524
|
-
> Generated: {{date}} | Feature: {{featureName}} | Status: Draft
|
|
525
|
-
|
|
526
|
-
---
|
|
527
|
-
|
|
528
|
-
## Story 1: [Actor] [Action]
|
|
529
|
-
|
|
530
|
-
**Feature:** {{featureName}}
|
|
531
|
-
**Priority:** High / Medium / Low
|
|
532
|
-
|
|
533
|
-
### Optimal Path
|
|
534
|
-
1. [Step 1]
|
|
535
|
-
2. [Step 2]
|
|
536
|
-
3. [Step 3 — success state]
|
|
537
|
-
|
|
538
|
-
### Edge Cases
|
|
539
|
-
- [Edge case] → [Expected behavior]
|
|
540
|
-
- [Error condition] → [Expected error handling]
|
|
541
|
-
|
|
542
|
-
### Acceptance Criteria
|
|
543
|
-
- [ ] [Measurable criterion 1]
|
|
544
|
-
- [ ] [Measurable criterion 2]
|
|
545
|
-
- [ ] Edge: [edge case criterion]
|
|
546
|
-
|
|
547
|
-
---
|
|
548
|
-
|
|
549
|
-
## Story 2: [Actor] [Action]
|
|
550
|
-
|
|
551
|
-
[Repeat structure above]
|
|
552
|
-
|
|
553
|
-
---
|
|
554
|
-
|
|
555
|
-
*Generated by MORPH-SPEC — complete before implementation begins*
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
**Step 3: Run full suite**
|
|
559
|
-
|
|
560
|
-
```bash
|
|
561
|
-
npm test
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
Expected: same pass count.
|
|
565
|
-
|
|
566
|
-
**Step 4: Commit**
|
|
567
|
-
|
|
568
|
-
```bash
|
|
569
|
-
git add framework/standards/ framework/templates/docs/user-stories.md
|
|
570
|
-
git commit -m "feat(standards): add TypeScript strict mode requirement; add user-stories template"
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
---
|
|
574
|
-
|
|
575
|
-
## Task 6: Remove `outputs` and `phase` from state-manager.js
|
|
576
|
-
|
|
577
|
-
**Files:**
|
|
578
|
-
- Modify: `src/core/state/state-manager.js`
|
|
579
|
-
- Modify: `test/lib/state-manager.test.js`
|
|
580
|
-
|
|
581
|
-
**Context:** `ensureFeature()` at line 191 sets `outputs: getAllOutputPaths(featureName)` and `phase: "proposal"`. Remove both fields. Add two new exported helper functions: `derivePhase(featurePath)` and `deriveOutputs(featureName)`. Add v4→v5 migration in `loadState()`.
|
|
582
|
-
|
|
583
|
-
**Step 1: Add helper functions to state-manager.js**
|
|
584
|
-
|
|
585
|
-
Add these two new exported functions after the existing `getStatePath()` function (around line 25):
|
|
586
|
-
|
|
587
|
-
```javascript
|
|
588
|
-
/**
|
|
589
|
-
* Derive current phase from filesystem — checks for phase folders in descending order.
|
|
590
|
-
* Returns the phase corresponding to the highest-numbered folder present.
|
|
591
|
-
*
|
|
592
|
-
* @param {string} featurePath - Absolute path to .morph/features/{feature}/
|
|
593
|
-
* @returns {string} Phase name: 'implement' | 'tasks' | 'uiux' | 'design' | 'proposal' | 'setup'
|
|
594
|
-
*/
|
|
595
|
-
export function derivePhase(featurePath) {
|
|
596
|
-
const phaseMap = [
|
|
597
|
-
['4-implement', 'implement'],
|
|
598
|
-
['3-tasks', 'tasks'],
|
|
599
|
-
['2-ui', 'uiux'],
|
|
600
|
-
['1-design', 'design'],
|
|
601
|
-
['0-proposal', 'proposal'],
|
|
602
|
-
];
|
|
603
|
-
for (const [folder, phase] of phaseMap) {
|
|
604
|
-
if (existsSync(join(featurePath, folder))) return phase;
|
|
605
|
-
}
|
|
606
|
-
return 'setup';
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
/**
|
|
610
|
-
* Derive output existence from filesystem — checks if each output file exists at its expected path.
|
|
611
|
-
* Returns an object matching the old outputs shape for backwards-compatible display.
|
|
612
|
-
*
|
|
613
|
-
* @param {string} featureName - Feature name
|
|
614
|
-
* @param {string} [baseDir] - Project base dir (defaults to cwd)
|
|
615
|
-
* @returns {Object} Map of outputType → { created: boolean, path: string }
|
|
616
|
-
*/
|
|
617
|
-
export function deriveOutputs(featureName, baseDir = process.cwd()) {
|
|
618
|
-
const outputPaths = getAllOutputPaths(featureName);
|
|
619
|
-
const result = {};
|
|
620
|
-
for (const [type, { path: relPath }] of Object.entries(outputPaths)) {
|
|
621
|
-
const absPath = join(baseDir, relPath);
|
|
622
|
-
result[type] = { created: existsSync(absPath), path: relPath };
|
|
623
|
-
}
|
|
624
|
-
return result;
|
|
625
|
-
}
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
**Step 2: Remove `outputs` and `phase` from ensureFeature()**
|
|
629
|
-
|
|
630
|
-
In `ensureFeature()` (around line 191), change:
|
|
631
|
-
|
|
632
|
-
```javascript
|
|
633
|
-
// REMOVE these two lines:
|
|
634
|
-
phase: "proposal",
|
|
635
|
-
outputs: getAllOutputPaths(featureName),
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
The feature object after the change should NOT have `phase` or `outputs` keys.
|
|
639
|
-
|
|
640
|
-
**Step 3: Add v4→v5 migration in loadState()**
|
|
641
|
-
|
|
642
|
-
In `loadState()`, after the existing v3→v4 migration block (around line 65), add:
|
|
643
|
-
|
|
644
|
-
```javascript
|
|
645
|
-
// Migrate v4.x → v5.0.0: remove outputs and phase (now derived from filesystem)
|
|
646
|
-
if (state.version && state.version.startsWith('4.')) {
|
|
647
|
-
state.version = '5.0.0';
|
|
648
|
-
for (const feature of Object.values(state.features || {})) {
|
|
649
|
-
delete feature.outputs;
|
|
650
|
-
delete feature.phase;
|
|
651
|
-
}
|
|
652
|
-
writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf8');
|
|
653
|
-
}
|
|
654
|
-
```
|
|
655
|
-
|
|
656
|
-
**Step 4: Update initState() version string**
|
|
657
|
-
|
|
658
|
-
Change `version: "4.0.0"` to `version: "5.0.0"` in `initState()`.
|
|
659
|
-
|
|
660
|
-
**Step 5: Run state-manager tests to find failures**
|
|
661
|
-
|
|
662
|
-
```bash
|
|
663
|
-
node --test test/lib/state-manager.test.js
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
Find tests that assert on `feature.phase` or `feature.outputs` and update them:
|
|
667
|
-
- Tests asserting `feature.phase === 'design'` → remove or replace with `derivePhase()` call
|
|
668
|
-
- Tests asserting `feature.outputs.spec.created` → remove or replace with `deriveOutputs()` call
|
|
669
|
-
- Tests asserting `state.version === '4.0.0'` → change to `'5.0.0'`
|
|
670
|
-
|
|
671
|
-
**Step 6: Add new tests for derivePhase and deriveOutputs**
|
|
672
|
-
|
|
673
|
-
In `test/lib/state-manager.test.js`, add:
|
|
674
|
-
|
|
675
|
-
```javascript
|
|
676
|
-
import { derivePhase, deriveOutputs } from '../../src/core/state/state-manager.js';
|
|
677
|
-
import { mkdirSync } from 'fs';
|
|
678
|
-
|
|
679
|
-
describe('derivePhase', () => {
|
|
680
|
-
test('returns setup when no phase folders exist', () => {
|
|
681
|
-
const dir = createTempDir();
|
|
682
|
-
assert.strictEqual(derivePhase(join(dir, '.morph', 'features', 'f')), 'setup');
|
|
683
|
-
cleanupTempDir(dir);
|
|
684
|
-
});
|
|
685
|
-
|
|
686
|
-
test('returns proposal when 0-proposal/ exists', () => {
|
|
687
|
-
const dir = createTempDir();
|
|
688
|
-
const featurePath = join(dir, '.morph', 'features', 'f');
|
|
689
|
-
mkdirSync(join(featurePath, '0-proposal'), { recursive: true });
|
|
690
|
-
assert.strictEqual(derivePhase(featurePath), 'proposal');
|
|
691
|
-
cleanupTempDir(dir);
|
|
692
|
-
});
|
|
693
|
-
|
|
694
|
-
test('returns tasks when 3-tasks/ is highest folder', () => {
|
|
695
|
-
const dir = createTempDir();
|
|
696
|
-
const featurePath = join(dir, '.morph', 'features', 'f');
|
|
697
|
-
mkdirSync(join(featurePath, '0-proposal'), { recursive: true });
|
|
698
|
-
mkdirSync(join(featurePath, '1-design'), { recursive: true });
|
|
699
|
-
mkdirSync(join(featurePath, '3-tasks'), { recursive: true });
|
|
700
|
-
assert.strictEqual(derivePhase(featurePath), 'tasks');
|
|
701
|
-
cleanupTempDir(dir);
|
|
702
|
-
});
|
|
703
|
-
|
|
704
|
-
test('returns implement when 4-implement/ exists', () => {
|
|
705
|
-
const dir = createTempDir();
|
|
706
|
-
const featurePath = join(dir, '.morph', 'features', 'f');
|
|
707
|
-
mkdirSync(join(featurePath, '4-implement'), { recursive: true });
|
|
708
|
-
assert.strictEqual(derivePhase(featurePath), 'implement');
|
|
709
|
-
cleanupTempDir(dir);
|
|
710
|
-
});
|
|
711
|
-
});
|
|
712
|
-
|
|
713
|
-
describe('state migration v4 → v5', () => {
|
|
714
|
-
test('removes outputs and phase from v4 state on load', () => {
|
|
715
|
-
const dir = createTempDir();
|
|
716
|
-
process.chdir(dir);
|
|
717
|
-
// Write a v4.0.0 state with outputs and phase
|
|
718
|
-
const v4State = {
|
|
719
|
-
version: '4.0.0',
|
|
720
|
-
project: { name: 'Test' },
|
|
721
|
-
features: {
|
|
722
|
-
'my-feature': {
|
|
723
|
-
phase: 'design',
|
|
724
|
-
outputs: { spec: { created: true, path: 'some/path' } },
|
|
725
|
-
workflow: 'standard'
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
};
|
|
729
|
-
mkdirSync(join(dir, '.morph'), { recursive: true });
|
|
730
|
-
writeFileSync(join(dir, '.morph', 'state.json'), JSON.stringify(v4State), 'utf8');
|
|
731
|
-
|
|
732
|
-
const state = loadState();
|
|
733
|
-
assert.strictEqual(state.version, '5.0.0');
|
|
734
|
-
assert.strictEqual(state.features['my-feature'].phase, undefined);
|
|
735
|
-
assert.strictEqual(state.features['my-feature'].outputs, undefined);
|
|
736
|
-
assert.strictEqual(state.features['my-feature'].workflow, 'standard'); // kept
|
|
737
|
-
|
|
738
|
-
process.chdir(originalCwd);
|
|
739
|
-
cleanupTempDir(dir);
|
|
740
|
-
});
|
|
741
|
-
});
|
|
742
|
-
```
|
|
743
|
-
|
|
744
|
-
**Step 7: Run full suite**
|
|
745
|
-
|
|
746
|
-
```bash
|
|
747
|
-
npm test
|
|
748
|
-
```
|
|
749
|
-
|
|
750
|
-
Expected: 614+ tests pass, 0 fail.
|
|
751
|
-
|
|
752
|
-
**Step 8: Commit**
|
|
753
|
-
|
|
754
|
-
```bash
|
|
755
|
-
git add src/core/state/state-manager.js test/lib/state-manager.test.js
|
|
756
|
-
git commit -m "feat(state): remove outputs+phase fields; derive from filesystem at runtime"
|
|
757
|
-
```
|
|
758
|
-
|
|
759
|
-
---
|
|
760
|
-
|
|
761
|
-
## Task 7: Delete track-output-creation hook + unregister it
|
|
762
|
-
|
|
763
|
-
**Files:**
|
|
764
|
-
- Delete: `framework/hooks/claude-code/post-tool-use/track-output-creation.js`
|
|
765
|
-
- Modify: `src/utils/hooks-installer.js` — remove PostToolUse/Write entry for track-output-creation
|
|
766
|
-
- Delete: `test/hooks/track-output-creation.test.js`
|
|
767
|
-
- Modify: `test/hooks/hooks-installer.test.js` — verify hook no longer registered
|
|
768
|
-
|
|
769
|
-
**Context:** `track-output-creation.js` existed solely to mark `outputs.{type}.created = true` in state.json. With `outputs` removed from state.json (Task 6), this hook has no purpose.
|
|
770
|
-
|
|
771
|
-
**Step 1: Remove the PostToolUse/Write hook entry from hooks-installer.js**
|
|
772
|
-
|
|
773
|
-
In `src/utils/hooks-installer.js`, find and delete the entire block (around lines 92-100):
|
|
774
|
-
|
|
775
|
-
```javascript
|
|
776
|
-
// DELETE this entire block:
|
|
777
|
-
// === PostToolUse: Write ===
|
|
778
|
-
{
|
|
779
|
-
event: 'PostToolUse',
|
|
780
|
-
matcher: 'Write',
|
|
781
|
-
hooks: [{
|
|
782
|
-
type: 'command',
|
|
783
|
-
command: 'node framework/hooks/claude-code/post-tool-use/track-output-creation.js'
|
|
784
|
-
}]
|
|
785
|
-
},
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
**Step 2: Delete the hook file**
|
|
789
|
-
|
|
790
|
-
```bash
|
|
791
|
-
git rm framework/hooks/claude-code/post-tool-use/track-output-creation.js
|
|
792
|
-
git rm test/hooks/track-output-creation.test.js
|
|
793
|
-
```
|
|
794
|
-
|
|
795
|
-
**Step 3: Update hooks-installer.test.js**
|
|
796
|
-
|
|
797
|
-
Find any test that asserts `PostToolUse` is installed with `track-output-creation` and either remove it or change it to assert the hook is NOT registered. Add:
|
|
798
|
-
|
|
799
|
-
```javascript
|
|
800
|
-
test('does NOT register track-output-creation hook (removed in v5)', async () => {
|
|
801
|
-
await installClaudeHooks(tempDir);
|
|
802
|
-
const settings = readSettings();
|
|
803
|
-
const postToolUseHooks = settings.hooks?.PostToolUse ?? [];
|
|
804
|
-
const commands = postToolUseHooks.flatMap(h => h.hooks ?? []).map(h => h.command ?? '');
|
|
805
|
-
assert.ok(
|
|
806
|
-
!commands.some(c => c.includes('track-output-creation')),
|
|
807
|
-
'track-output-creation should not be registered'
|
|
808
|
-
);
|
|
809
|
-
});
|
|
810
|
-
```
|
|
811
|
-
|
|
812
|
-
**Step 4: Run hooks tests**
|
|
813
|
-
|
|
814
|
-
```bash
|
|
815
|
-
node --test test/hooks/hooks-installer.test.js
|
|
816
|
-
```
|
|
817
|
-
|
|
818
|
-
Expected: all pass.
|
|
819
|
-
|
|
820
|
-
**Step 5: Run full suite**
|
|
821
|
-
|
|
822
|
-
```bash
|
|
823
|
-
npm test
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
Expected: test count slightly lower (track-output-creation.test.js removed), 0 fail.
|
|
827
|
-
|
|
828
|
-
**Step 6: Commit**
|
|
829
|
-
|
|
830
|
-
```bash
|
|
831
|
-
git add src/utils/hooks-installer.js test/hooks/hooks-installer.test.js
|
|
832
|
-
git commit -m "feat(hooks): remove track-output-creation — outputs now derived from filesystem"
|
|
833
|
-
```
|
|
834
|
-
|
|
835
|
-
---
|
|
836
|
-
|
|
837
|
-
## Task 8: Update status command + version bump
|
|
838
|
-
|
|
839
|
-
**Files:**
|
|
840
|
-
- Modify: `src/commands/project/status.js` — use derivePhase/deriveOutputs
|
|
841
|
-
- Modify: `test/commands/status.test.js` — update assertions
|
|
842
|
-
- Modify: `package.json` — version 4.4.0 → 4.5.0
|
|
843
|
-
|
|
844
|
-
**Context:** `morph-spec status <feature>` currently reads `feature.phase` and `feature.outputs` from state.json. After Task 6 these fields don't exist. Update status to call `derivePhase()` and `deriveOutputs()` instead.
|
|
845
|
-
|
|
846
|
-
**Step 1: Find where status.js reads phase and outputs**
|
|
847
|
-
|
|
848
|
-
```bash
|
|
849
|
-
grep -n "\.phase\|\.outputs" src/commands/project/status.js
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
**Step 2: Update status.js to use derive helpers**
|
|
853
|
-
|
|
854
|
-
Import and use the new helpers:
|
|
855
|
-
|
|
856
|
-
```javascript
|
|
857
|
-
import { loadState, derivePhase, deriveOutputs } from '../../core/state/state-manager.js';
|
|
858
|
-
import { join } from 'path';
|
|
859
|
-
|
|
860
|
-
// Where phase was read:
|
|
861
|
-
// BEFORE: const phase = feature.phase;
|
|
862
|
-
// AFTER:
|
|
863
|
-
const featurePath = join(process.cwd(), '.morph', 'features', featureName);
|
|
864
|
-
const phase = derivePhase(featurePath);
|
|
865
|
-
|
|
866
|
-
// Where outputs were read:
|
|
867
|
-
// BEFORE: const outputs = feature.outputs;
|
|
868
|
-
// AFTER:
|
|
869
|
-
const outputs = deriveOutputs(featureName);
|
|
870
|
-
```
|
|
871
|
-
|
|
872
|
-
**Step 3: Run status tests**
|
|
873
|
-
|
|
874
|
-
```bash
|
|
875
|
-
node --test test/commands/status.test.js
|
|
876
|
-
```
|
|
877
|
-
|
|
878
|
-
Fix any failing assertions — they'll be about phase values or outputs shape. The shape of `deriveOutputs()` return value matches the old `feature.outputs` shape (`{ type: { created: boolean, path: string } }`), so display logic should need minimal changes.
|
|
879
|
-
|
|
880
|
-
**Step 4: Bump version in package.json**
|
|
881
|
-
|
|
882
|
-
Change `"version": "4.4.0"` to `"version": "4.5.0"`.
|
|
883
|
-
|
|
884
|
-
**Step 5: Update version reference in framework/CLAUDE.md footer**
|
|
885
|
-
|
|
886
|
-
Change `*MORPH-SPEC v4.4.0 by Polymorphism Tech*` to `*MORPH-SPEC v4.5.0 by Polymorphism Tech*`.
|
|
887
|
-
(This file was already rewritten in Task 3 with v4.5.0, so just verify it's correct.)
|
|
888
|
-
|
|
889
|
-
**Step 6: Run full suite — final verification**
|
|
890
|
-
|
|
891
|
-
```bash
|
|
892
|
-
npm test
|
|
893
|
-
```
|
|
894
|
-
|
|
895
|
-
Expected: all tests pass, 0 fail. Count may differ from original (some tests removed, some added).
|
|
896
|
-
|
|
897
|
-
**Step 7: Final commit**
|
|
898
|
-
|
|
899
|
-
```bash
|
|
900
|
-
git add src/commands/project/status.js test/commands/status.test.js package.json framework/CLAUDE.md
|
|
901
|
-
git commit -m "feat(status): derive phase+outputs from filesystem; bump version to 4.5.0"
|
|
902
|
-
```
|
|
903
|
-
|
|
904
|
-
---
|
|
905
|
-
|
|
906
|
-
## Final Verification
|
|
907
|
-
|
|
908
|
-
After all 8 tasks:
|
|
909
|
-
|
|
910
|
-
```bash
|
|
911
|
-
npm test
|
|
912
|
-
git log --oneline -8
|
|
913
|
-
```
|
|
914
|
-
|
|
915
|
-
Expected log:
|
|
916
|
-
```
|
|
917
|
-
feat(status): derive phase+outputs from filesystem; bump version to 4.5.0
|
|
918
|
-
feat(hooks): remove track-output-creation — outputs now derived from filesystem
|
|
919
|
-
feat(state): remove outputs+phase fields; derive from filesystem at runtime
|
|
920
|
-
feat(standards): add TypeScript strict mode requirement; add user-stories template
|
|
921
|
-
feat(rules): add Test File Policy to morph-workflow rule
|
|
922
|
-
feat(claude-md): merge CLAUDE.md + CLAUDE_runtime.md into single unified file
|
|
923
|
-
feat(rules): replace static content with @-imports from framework/standards
|
|
924
|
-
feat(skills): install as subdirectory/SKILL.md — native Claude Code format
|
|
925
|
-
```
|