@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.
Files changed (375) hide show
  1. package/.morph/.morphversion +3 -3
  2. package/.morph/analytics/threads-log.jsonl +44 -9
  3. package/.morph/config/config.json +2 -3
  4. package/.morph/framework/standards/STANDARDS.json +812 -0
  5. package/.morph/{standards → framework/standards}/ai-agents/team-orchestration.md +3 -3
  6. package/.morph/framework/standards/integration/mcp/mcp-tools.md +384 -0
  7. package/.morph/{templates → framework/templates}/README.md +17 -17
  8. package/.morph/{templates → framework/templates}/REGISTRY.json +48 -233
  9. package/.morph/framework/templates/code/dotnet/contracts/contracts.cs.hbs +172 -0
  10. package/.morph/{templates → framework/templates}/context/CONTEXT-FEATURE.md +1 -1
  11. package/.morph/{templates → framework/templates}/context/CONTEXT.md +3 -3
  12. package/.morph/framework/templates/docs/clarifications.md +253 -0
  13. package/.morph/framework/templates/docs/onboarding.md +123 -0
  14. package/.morph/framework/templates/docs/schema-analysis.md +119 -0
  15. package/.morph/{templates → framework/templates}/docs/spec.md +149 -149
  16. package/.morph/framework/templates/docs/ui-components.md +124 -0
  17. package/.morph/framework/templates/docs/ui-design-system.md +76 -0
  18. package/.morph/framework/templates/docs/ui-flows.md +167 -0
  19. package/.morph/framework/templates/docs/ui-mockups.md +98 -0
  20. package/.morph/{templates → framework/templates}/examples/spec-examples.md +1 -1
  21. package/.morph/{templates → framework/templates}/infrastructure/github/README.md +11 -11
  22. package/.morph/{templates → framework/templates}/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +2 -2
  23. package/.morph/{templates → framework/templates}/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  24. package/.morph/{templates → framework/templates}/meta-prompts/validators/pre-commit-validator.md +1 -1
  25. package/.morph/logs/tool-failures.log +51 -0
  26. package/.morph/memory/pre-compact-2026-02-22T17-01-01-658Z.json +16 -0
  27. package/.morph/state.json +1 -1
  28. package/CLAUDE.md +20 -119
  29. package/README.md +20 -18
  30. package/bin/detect-agents.js +1 -1
  31. package/bin/morph-spec.js +116 -266
  32. package/bin/task-manager.cjs +2 -2
  33. package/bin/validate.js +1 -1
  34. package/claude-plugin.json +14 -0
  35. package/docs/claude-alignment-report.md +137 -0
  36. package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +512 -0
  37. package/docs/plans/2026-02-22-claude-settings.md +515 -0
  38. package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +728 -0
  39. package/docs/plans/2026-02-22-morph-spec-next.md +478 -0
  40. package/docs/plans/2026-02-22-native-alignment-design.md +199 -0
  41. package/docs/plans/2026-02-22-native-alignment-impl.md +925 -0
  42. package/docs/plans/2026-02-22-native-enrichment-design.md +244 -0
  43. package/docs/plans/2026-02-22-native-enrichment.md +735 -0
  44. package/framework/CLAUDE.md +77 -0
  45. package/framework/commands/morph-apply.md +9 -9
  46. package/framework/commands/morph-archive.md +8 -8
  47. package/framework/commands/morph-infra.md +1 -1
  48. package/framework/commands/morph-proposal.md +9 -9
  49. package/framework/commands/morph-status.md +3 -3
  50. package/framework/commands/morph-troubleshoot.md +1 -1
  51. package/framework/hooks/README.md +201 -282
  52. package/framework/hooks/claude-code/notification/approval-reminder.js +52 -0
  53. package/framework/hooks/claude-code/post-tool-use/dispatch.js +83 -0
  54. package/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +42 -0
  55. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +61 -0
  56. package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +71 -0
  57. package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +58 -0
  58. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +64 -0
  59. package/framework/hooks/claude-code/session-start/inject-morph-context.js +94 -0
  60. package/framework/hooks/claude-code/statusline.py +239 -0
  61. package/framework/hooks/claude-code/statusline.sh +7 -0
  62. package/framework/hooks/claude-code/stop/validate-completion.js +88 -0
  63. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +91 -0
  64. package/framework/hooks/shared/hook-response.js +45 -0
  65. package/framework/hooks/shared/phase-utils.js +129 -0
  66. package/framework/hooks/shared/state-reader.js +138 -0
  67. package/framework/hooks/shared/stdin-reader.js +26 -0
  68. package/framework/phases.json +145 -0
  69. package/framework/rules/csharp-standards.md +10 -0
  70. package/framework/rules/frontend-standards.md +14 -0
  71. package/framework/rules/infrastructure-standards.md +13 -0
  72. package/framework/rules/morph-workflow.md +86 -0
  73. package/framework/rules/testing-standards.md +11 -0
  74. package/framework/skills/level-0-meta/brainstorming.md +133 -0
  75. package/framework/skills/level-0-meta/code-review.md +12 -4
  76. package/framework/skills/level-0-meta/mcp-registry.json +207 -0
  77. package/framework/skills/level-0-meta/morph-checklist.md +9 -1
  78. package/framework/skills/level-0-meta/simulation-checklist.md +9 -1
  79. package/framework/skills/level-0-meta/tool-usage-guide.md +335 -0
  80. package/framework/skills/level-0-meta/verification-before-completion.md +145 -0
  81. package/framework/skills/level-1-workflows/morph-replicate.md +9 -1
  82. package/framework/skills/level-1-workflows/phase-clarify.md +65 -4
  83. package/framework/skills/level-1-workflows/phase-codebase-analysis.md +182 -0
  84. package/framework/skills/level-1-workflows/phase-design.md +342 -80
  85. package/framework/skills/level-1-workflows/phase-implement.md +254 -0
  86. package/framework/skills/level-1-workflows/phase-setup.md +76 -10
  87. package/framework/skills/level-1-workflows/phase-tasks.md +88 -7
  88. package/framework/skills/level-1-workflows/phase-uiux.md +95 -17
  89. package/framework/skills/level-2-domains/ai-agents/ai-system-architect.md +8 -1
  90. package/framework/skills/level-2-domains/architecture/po-pm-advisor.md +8 -1
  91. package/framework/skills/level-2-domains/architecture/prompt-engineer.md +8 -1
  92. package/framework/skills/level-2-domains/architecture/seo-growth-hacker.md +8 -1
  93. package/framework/skills/level-2-domains/architecture/standards-architect.md +11 -4
  94. package/framework/skills/level-2-domains/backend/api-designer.md +8 -1
  95. package/framework/skills/level-2-domains/backend/dotnet-senior.md +8 -1
  96. package/framework/skills/level-2-domains/backend/ef-modeler.md +8 -1
  97. package/framework/skills/level-2-domains/backend/hangfire-orchestrator.md +9 -2
  98. package/framework/skills/level-2-domains/backend/ms-agent-expert.md +8 -1
  99. package/framework/skills/level-2-domains/frontend/blazor-builder.md +8 -1
  100. package/framework/skills/level-2-domains/frontend/nextjs-expert.md +8 -1
  101. package/framework/skills/level-2-domains/frontend/ui-ux-designer.md +9 -2
  102. package/framework/skills/level-2-domains/infrastructure/azure-architect.md +8 -1
  103. package/framework/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +8 -1
  104. package/framework/skills/level-2-domains/infrastructure/bicep-architect.md +8 -1
  105. package/framework/skills/level-2-domains/infrastructure/container-specialist.md +8 -1
  106. package/framework/skills/level-2-domains/infrastructure/devops-engineer.md +8 -1
  107. package/framework/skills/level-2-domains/integrations/asaas-financial.md +8 -1
  108. package/framework/skills/level-2-domains/integrations/azure-identity.md +8 -1
  109. package/framework/skills/level-2-domains/integrations/clerk-auth.md +8 -1
  110. package/framework/skills/level-2-domains/integrations/{hangfire-orchestrator.md → hangfire-integration.md} +8 -1
  111. package/framework/skills/level-2-domains/integrations/resend-email.md +8 -1
  112. package/framework/skills/level-2-domains/quality/code-analyzer.md +10 -3
  113. package/framework/skills/level-2-domains/quality/testing-specialist.md +8 -1
  114. package/framework/standards/STANDARDS.json +812 -0
  115. package/framework/standards/ai-agents/team-orchestration.md +3 -3
  116. package/framework/standards/frontend/nextjs/nextjs-patterns.md +17 -0
  117. package/framework/standards/integration/mcp/mcp-tools.md +384 -0
  118. package/framework/templates/README.md +17 -17
  119. package/framework/templates/REGISTRY.json +48 -233
  120. package/framework/templates/code/dotnet/contracts/contracts.cs.hbs +172 -0
  121. package/framework/templates/context/CONTEXT-FEATURE.md +1 -1
  122. package/framework/templates/context/CONTEXT.md +3 -3
  123. package/framework/templates/docs/clarifications.md +253 -0
  124. package/framework/templates/docs/onboarding.md +123 -0
  125. package/framework/templates/docs/schema-analysis.md +119 -0
  126. package/framework/templates/docs/spec.md +149 -149
  127. package/framework/templates/docs/ui-components.md +124 -0
  128. package/framework/templates/docs/ui-design-system.md +76 -0
  129. package/framework/templates/docs/ui-flows.md +167 -0
  130. package/framework/templates/docs/ui-mockups.md +98 -0
  131. package/framework/templates/docs/user-stories.md +34 -0
  132. package/framework/templates/examples/spec-examples.md +1 -1
  133. package/framework/templates/infrastructure/github/README.md +11 -11
  134. package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +2 -2
  135. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  136. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +1 -1
  137. package/framework/workflows/configs/express.json +45 -0
  138. package/framework/workflows/configs/spec-only.json +43 -0
  139. package/framework/workflows/docs/enforcement-pipeline.md +8 -8
  140. package/framework/workflows/docs/full-morph.md +3 -3
  141. package/package.json +3 -2
  142. package/scripts/generate-refs.js +336 -0
  143. package/scripts/generate-standards-registry.js +44 -0
  144. package/scripts/validate-real.mjs +255 -0
  145. package/src/commands/feature/create-story.js +362 -361
  146. package/src/commands/feature/shard-spec.js +225 -224
  147. package/src/commands/feature/sprint-status.js +1 -1
  148. package/src/commands/generation/generate-onboarding.js +169 -0
  149. package/src/commands/generation/generate.js +2 -2
  150. package/src/commands/mcp/mcp-setup.js +315 -0
  151. package/src/commands/project/changes.js +66 -0
  152. package/src/commands/project/checkpoint.js +209 -0
  153. package/src/commands/project/cost.js +179 -0
  154. package/src/commands/project/diff.js +278 -0
  155. package/src/commands/project/doctor.js +55 -7
  156. package/src/commands/project/init.js +318 -76
  157. package/src/commands/project/revert.js +173 -0
  158. package/src/commands/project/standards.js +80 -0
  159. package/src/commands/project/status.js +376 -0
  160. package/src/commands/project/update-agents.js +23 -0
  161. package/src/commands/project/update.js +63 -30
  162. package/src/commands/state/advance-phase.js +4 -3
  163. package/src/commands/state/state.js +10 -3
  164. package/src/commands/state/validate-phase.js +19 -2
  165. package/src/commands/templates/template-customize.js +4 -4
  166. package/src/commands/templates/template-render.js +1 -1
  167. package/src/commands/templates/template-show.js +1 -1
  168. package/src/commands/validation/validate-feature.js +359 -0
  169. package/src/core/orchestrator.js +3 -38
  170. package/src/core/paths/output-schema.js +135 -0
  171. package/src/core/state/state-manager.js +831 -592
  172. package/src/core/templates/template-registry.js +2 -2
  173. package/src/core/workflows/workflow-detector.js +17 -1
  174. package/src/lib/agents/micro-agent-factory.js +1 -1
  175. package/src/lib/context/context-bundler.js +2 -1
  176. package/src/lib/detectors/claude-config-detector.js +392 -0
  177. package/src/lib/detectors/conversation-analyzer.js +4 -4
  178. package/src/lib/detectors/design-system-detector.js +6 -5
  179. package/src/lib/detectors/standards-generator.js +2 -2
  180. package/src/lib/generators/context-generator.js +539 -538
  181. package/src/lib/generators/recap-generator.js +1 -1
  182. package/src/lib/generators/settings-generator.js +210 -0
  183. package/src/lib/hooks/hook-executor.js +1 -1
  184. package/src/lib/installers/mcp-installer.js +299 -0
  185. package/src/lib/learning/learning-system.js +3 -3
  186. package/src/lib/orchestration/team-orchestrator.js +1 -1
  187. package/src/lib/standards/standards-context-injector.js +7 -7
  188. package/src/lib/threads/thread-coordinator.js +1 -1
  189. package/src/lib/troubleshooting/troubleshoot-grep.js +1 -1
  190. package/src/lib/validators/contracts/contract-compliance-validator.js +274 -273
  191. package/src/lib/validators/design-system/design-system-validator.js +1 -1
  192. package/src/lib/validators/spec-validator.js +258 -258
  193. package/src/lib/validators/validation-runner.js +270 -269
  194. package/src/utils/agents-installer.js +206 -0
  195. package/src/utils/claude-settings-manager.js +258 -0
  196. package/src/utils/file-copier.js +1 -1
  197. package/src/utils/hooks-installer.js +354 -28
  198. package/src/utils/skills-installer.js +74 -0
  199. package/.morph/project/context/detection-log.md +0 -16
  200. package/.morph/project/standards/inferred.md +0 -59
  201. package/framework/hooks/agent-stop/validate-and-continue.js +0 -96
  202. package/framework/hooks/agent-stop/validate-checkpoints.js +0 -101
  203. package/framework/hooks/agent-stop/validate-tests.js +0 -109
  204. package/framework/hooks/agent-teams/dispatch.js +0 -67
  205. package/framework/hooks/agent-teams/phase-advanced.js +0 -80
  206. package/framework/hooks/agent-teams/task-completed.js +0 -76
  207. package/framework/hooks/agent-teams/teammate-idle.js +0 -70
  208. package/src/commands/agents/agents-fuse.js +0 -97
  209. package/src/commands/agents/micro-agent.js +0 -112
  210. package/src/commands/agents/spawn-team.js +0 -237
  211. package/src/commands/agents/squad-template.js +0 -146
  212. package/src/commands/analytics/analytics.js +0 -176
  213. package/src/commands/context/context-prime.js +0 -63
  214. package/src/commands/context/core-four.js +0 -54
  215. package/src/commands/generation/generate-context.js +0 -40
  216. package/src/commands/project/detect-agents.js +0 -207
  217. package/src/commands/project/detect-workflow.js +0 -174
  218. package/src/commands/threads/thread-template.js +0 -103
  219. package/src/commands/threads/threads.js +0 -261
  220. package/src/commands/utils/session-summary.js +0 -291
  221. package/src/llm/analyzer.js +0 -215
  222. package/src/llm/few-shot-examples.js +0 -216
  223. package/src/llm/project-config-schema.json +0 -188
  224. package/src/llm/prompt-builder.js +0 -96
  225. /package/.morph/{project/context → context}/README.md +0 -0
  226. /package/.morph/{config → framework}/agents.json +0 -0
  227. /package/.morph/{standards → framework/standards}/ai-agents/blazor-ui.md +0 -0
  228. /package/.morph/{standards → framework/standards}/ai-agents/production.md +0 -0
  229. /package/.morph/{standards → framework/standards}/ai-agents/setup.md +0 -0
  230. /package/.morph/{standards → framework/standards}/ai-agents/workflows.md +0 -0
  231. /package/.morph/{standards → framework/standards}/architecture/ddd/aggregates.md +0 -0
  232. /package/.morph/{standards → framework/standards}/architecture/ddd/entities.md +0 -0
  233. /package/.morph/{standards → framework/standards}/architecture/ddd/value-objects.md +0 -0
  234. /package/.morph/{standards → framework/standards}/backend/api/minimal-api.md +0 -0
  235. /package/.morph/{standards → framework/standards}/backend/api/rest.md +0 -0
  236. /package/.morph/{standards → framework/standards}/backend/api/validation.md +0 -0
  237. /package/.morph/{standards → framework/standards}/backend/authentication/passkeys.md +0 -0
  238. /package/.morph/{standards → framework/standards}/backend/database/ef-core.md +0 -0
  239. /package/.morph/{standards → framework/standards}/backend/database/migrations.md +0 -0
  240. /package/.morph/{standards → framework/standards}/backend/database/postgresql/database.md +0 -0
  241. /package/.morph/{standards → framework/standards}/backend/database/repository-patterns.md +0 -0
  242. /package/.morph/{standards → framework/standards}/backend/database/vector-search-rag.md +0 -0
  243. /package/.morph/{standards → framework/standards}/backend/dotnet/async.md +0 -0
  244. /package/.morph/{standards → framework/standards}/backend/dotnet/core.md +0 -0
  245. /package/.morph/{standards → framework/standards}/backend/dotnet/di.md +0 -0
  246. /package/.morph/{standards → framework/standards}/backend/dotnet/program-cs-checklist.md +0 -0
  247. /package/.morph/{standards → framework/standards}/backend/integrations/asaas/asaas-api.md +0 -0
  248. /package/.morph/{standards → framework/standards}/backend/integrations/clerk/clerk-auth.md +0 -0
  249. /package/.morph/{standards → framework/standards}/backend/integrations/hangfire/hangfire-jobs.md +0 -0
  250. /package/.morph/{standards → framework/standards}/backend/integrations/resend/resend-email.md +0 -0
  251. /package/.morph/{standards → framework/standards}/context/analytics.md +0 -0
  252. /package/.morph/{standards → framework/standards}/context/bundles.md +0 -0
  253. /package/.morph/{standards → framework/standards}/context/priming.md +0 -0
  254. /package/.morph/{standards → framework/standards}/core/architecture.md +0 -0
  255. /package/.morph/{standards → framework/standards}/core/coding.md +0 -0
  256. /package/.morph/{standards → framework/standards}/core/git-branching-strategy.md +0 -0
  257. /package/.morph/{standards → framework/standards}/core/git.md +0 -0
  258. /package/.morph/{standards → framework/standards}/core/testing.md +0 -0
  259. /package/.morph/{standards → framework/standards}/data/nosql/blob-storage.md +0 -0
  260. /package/.morph/{standards → framework/standards}/data/nosql/cache/redis.md +0 -0
  261. /package/.morph/{standards → framework/standards}/data/nosql/cosmos-db.md +0 -0
  262. /package/.morph/{standards → framework/standards}/data/vector-search/azure-ai-search.md +0 -0
  263. /package/.morph/{standards → framework/standards}/data/vector-search/rag-chunking.md +0 -0
  264. /package/.morph/{standards → framework/standards}/frontend/blazor/design-checklist.md +0 -0
  265. /package/.morph/{standards → framework/standards}/frontend/blazor/fluent-ui-setup.md +0 -0
  266. /package/.morph/{standards → framework/standards}/frontend/blazor/fluent-ui.md +0 -0
  267. /package/.morph/{standards → framework/standards}/frontend/blazor/html-conversion.md +0 -0
  268. /package/.morph/{standards → framework/standards}/frontend/blazor/lifecycle.md +0 -0
  269. /package/.morph/{standards → framework/standards}/frontend/blazor/pitfalls.md +0 -0
  270. /package/.morph/{standards → framework/standards}/frontend/blazor/state.md +0 -0
  271. /package/.morph/{standards → framework/standards}/frontend/design-system/animations.md +0 -0
  272. /package/.morph/{standards → framework/standards}/frontend/design-system/naming.md +0 -0
  273. /package/.morph/{standards → framework/standards}/frontend/nextjs/nextjs-patterns.md +0 -0
  274. /package/.morph/{standards → framework/standards}/infrastructure/azure/azure.md +0 -0
  275. /package/.morph/{standards → framework/standards}/infrastructure/azure/bicep/bicep-patterns.md +0 -0
  276. /package/.morph/{standards → framework/standards}/infrastructure/azure/devops/azure-devops-setup.md +0 -0
  277. /package/.morph/{standards → framework/standards}/infrastructure/azure/devops/local-development.md +0 -0
  278. /package/.morph/{standards → framework/standards}/infrastructure/azure/services/functions.md +0 -0
  279. /package/.morph/{standards → framework/standards}/infrastructure/azure/services/service-bus.md +0 -0
  280. /package/.morph/{standards → framework/standards}/infrastructure/azure/services/storage.md +0 -0
  281. /package/.morph/{standards → framework/standards}/infrastructure/docker/easypanel-deploy.md +0 -0
  282. /package/.morph/{standards → framework/standards}/infrastructure/supabase/mcp-setup.md +0 -0
  283. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-auth.md +0 -0
  284. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-pgvector.md +0 -0
  285. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-rls.md +0 -0
  286. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-storage.md +0 -0
  287. /package/.morph/{standards → framework/standards}/integration/api/graphql.md +0 -0
  288. /package/.morph/{standards → framework/standards}/integration/api/grpc.md +0 -0
  289. /package/.morph/{standards → framework/standards}/integration/api/rest-design.md +0 -0
  290. /package/.morph/{standards → framework/standards}/integration/event-driven/cqrs.md +0 -0
  291. /package/.morph/{standards → framework/standards}/integration/event-driven/event-sourcing.md +0 -0
  292. /package/.morph/{standards → framework/standards}/integration/event-driven/service-bus.md +0 -0
  293. /package/.morph/{standards → framework/standards}/observability/logging.md +0 -0
  294. /package/.morph/{standards → framework/standards}/observability/metrics.md +0 -0
  295. /package/.morph/{standards → framework/standards}/observability/monitoring.md +0 -0
  296. /package/.morph/{standards → framework/standards}/observability/tracing.md +0 -0
  297. /package/.morph/{standards → framework/standards}/workflows/parallel-execution.md +0 -0
  298. /package/.morph/{standards → framework/standards}/workflows/thread-management.md +0 -0
  299. /package/.morph/{templates → framework/templates}/.idea/morph-templates.xml +0 -0
  300. /package/.morph/{templates → framework/templates}/.vscode/morph-templates.code-snippets +0 -0
  301. /package/.morph/{templates → framework/templates}/IDE-SNIPPETS.md +0 -0
  302. /package/.morph/{templates → framework/templates}/code/dotnet/backend/repository.cs +0 -0
  303. /package/.morph/{templates → framework/templates}/code/dotnet/backend/service.cs +0 -0
  304. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Commands.cs +0 -0
  305. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Entities.cs +0 -0
  306. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Queries.cs +0 -0
  307. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/README.md +0 -0
  308. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/api-contracts.cs +0 -0
  309. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/contracts.cs +0 -0
  310. /package/.morph/{templates → framework/templates}/code/dotnet/database/migration.cs +0 -0
  311. /package/.morph/{templates → framework/templates}/code/dotnet/frontend/component.razor +0 -0
  312. /package/.morph/{templates → framework/templates}/code/dotnet/jobs/agent.cs +0 -0
  313. /package/.morph/{templates → framework/templates}/code/dotnet/jobs/job.cs +0 -0
  314. /package/.morph/{templates → framework/templates}/code/dotnet/test.cs +0 -0
  315. /package/.morph/{templates → framework/templates}/code/sql/rls-policy.sql +0 -0
  316. /package/.morph/{templates → framework/templates}/code/sql/supabase-migration.sql +0 -0
  317. /package/.morph/{templates → framework/templates}/code/sql/supabase-migration.template.sql +0 -0
  318. /package/.morph/{templates → framework/templates}/code/typescript/contracts.ts +0 -0
  319. /package/.morph/{templates → framework/templates}/docs/proposal.md +0 -0
  320. /package/.morph/{templates → framework/templates}/examples/design-system-examples.md +0 -0
  321. /package/.morph/{templates → framework/templates}/feature/decisions.md +0 -0
  322. /package/.morph/{templates → framework/templates}/feature/recap.md +0 -0
  323. /package/.morph/{templates → framework/templates}/feature/tasks.md +0 -0
  324. /package/.morph/{templates → framework/templates}/infrastructure/azure/Dockerfile.example +0 -0
  325. /package/.morph/{templates → framework/templates}/infrastructure/azure/README.md +0 -0
  326. /package/.morph/{templates → framework/templates}/infrastructure/azure/app-insights.bicep +0 -0
  327. /package/.morph/{templates → framework/templates}/infrastructure/azure/app-service.bicep +0 -0
  328. /package/.morph/{templates → framework/templates}/infrastructure/azure/container-app-env.bicep +0 -0
  329. /package/.morph/{templates → framework/templates}/infrastructure/azure/container-app.bicep +0 -0
  330. /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy-checklist.md +0 -0
  331. /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy.ps1 +0 -0
  332. /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy.sh +0 -0
  333. /package/.morph/{templates → framework/templates}/infrastructure/azure/key-vault.bicep +0 -0
  334. /package/.morph/{templates → framework/templates}/infrastructure/azure/main.bicep +0 -0
  335. /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.dev.json +0 -0
  336. /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.prod.json +0 -0
  337. /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.staging.json +0 -0
  338. /package/.morph/{templates → framework/templates}/infrastructure/azure/sql-database.bicep +0 -0
  339. /package/.morph/{templates → framework/templates}/infrastructure/azure/storage.bicep +0 -0
  340. /package/.morph/{templates → framework/templates}/infrastructure/docker/Dockerfile.template +0 -0
  341. /package/.morph/{templates → framework/templates}/infrastructure/docker/docker-compose.template.yml +0 -0
  342. /package/.morph/{templates → framework/templates}/infrastructure/docker/dockerfile-api.dockerfile +0 -0
  343. /package/.morph/{templates → framework/templates}/infrastructure/docker/dockerfile-web.dockerfile +0 -0
  344. /package/.morph/{templates → framework/templates}/infrastructure/docker/easypanel.template.json +0 -0
  345. /package/.morph/{templates → framework/templates}/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -0
  346. /package/.morph/{templates → framework/templates}/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -0
  347. /package/.morph/{templates → framework/templates}/infrastructure/github/actions/health-check/action.yml.hbs +0 -0
  348. /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -0
  349. /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -0
  350. /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -0
  351. /package/.morph/{templates → framework/templates}/integrations/asaas-client.cs +0 -0
  352. /package/.morph/{templates → framework/templates}/integrations/asaas-webhook.cs +0 -0
  353. /package/.morph/{templates → framework/templates}/integrations/azure-identity-config.cs +0 -0
  354. /package/.morph/{templates → framework/templates}/integrations/clerk-config.cs +0 -0
  355. /package/.morph/{templates → framework/templates}/meta-prompts/fusion/fusion-agent.md +0 -0
  356. /package/.morph/{templates → framework/templates}/meta-prompts/fusion/fusion-aggregator.md +0 -0
  357. /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-retry.md +0 -0
  358. /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-validation.md +0 -0
  359. /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-wrapper.md +0 -0
  360. /package/.morph/{templates → framework/templates}/meta-prompts/parallel-workers/parallel-coordinator.md +0 -0
  361. /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/backend-squad.md +0 -0
  362. /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/frontend-squad.md +0 -0
  363. /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/squad-leader.md +0 -0
  364. /package/.morph/{templates → framework/templates}/meta-prompts/validators/checkpoint-validator.md +0 -0
  365. /package/.morph/{templates → framework/templates}/saas/subscription.cs +0 -0
  366. /package/.morph/{templates → framework/templates}/saas/tenant.cs +0 -0
  367. /package/.morph/{templates → framework/templates}/state.template.json +0 -0
  368. /package/.morph/{templates → framework/templates}/ui/FluentDesignTheme.cs +0 -0
  369. /package/.morph/{templates → framework/templates}/ui/MudTheme.cs +0 -0
  370. /package/.morph/{templates → framework/templates}/ui/design-system.css +0 -0
  371. /package/framework/hooks/{commit-msg → git/commit-msg}/conventional-commits.sh +0 -0
  372. /package/framework/hooks/{pre-commit → git/pre-commit}/agents.sh +0 -0
  373. /package/framework/hooks/{pre-commit → git/pre-commit}/orchestrator.sh +0 -0
  374. /package/framework/hooks/{pre-commit → git/pre-commit}/specs.sh +0 -0
  375. /package/framework/hooks/{pre-push → git/pre-push}/run-tests.sh +0 -0
@@ -0,0 +1,728 @@
1
+ # Claude Code 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:** Implement all actionable improvements from the CC native alignment analysis: fix a broken SubagentStart hook, convert bash validation to a prompt-type hook, inject active feature spec into session context, add `$ARGUMENTS` support to phase skills, add `disable-model-invocation` + `context: fork` where appropriate, and convert level-2-domain specialists from skills to native Claude Code subagents.
6
+
7
+ **Architecture:** The changes touch hooks-installer.js (MORPH_HOOKS array + HOOKS_VERSION), the SessionStart hook script, all six phase workflow skill files, skills-installer.js, and agents-installer.js (new `installDomainAgents` function). Tests must pass after each task. No shared-module rewrites (too risky); no trust→defaultMode mapping (deeply integrated, separate concern).
8
+
9
+ **Tech Stack:** Node.js ESM, node:test, YAML frontmatter in .md files, Commander.js CLI
10
+
11
+ ---
12
+
13
+ ## Phase 1: Hooks cleanup and improvements
14
+
15
+ ### Task 1: Remove broken SubagentStart hook entry
16
+
17
+ `MORPH_HOOKS` references `subagent/log-agent-start.js` which does not exist. This causes a `hooks` entry pointing at a missing file — fail-open semantics mean it silently passes, but the entry is dead weight.
18
+
19
+ **Files:**
20
+ - Modify: `src/utils/hooks-installer.js`
21
+
22
+ **Step 1: Remove the SubagentStart entry from MORPH_HOOKS**
23
+
24
+ In `src/utils/hooks-installer.js`, delete the entire SubagentStart block (lines 159–168):
25
+
26
+ ```js
27
+ // === SubagentStart ===
28
+ {
29
+ event: 'SubagentStart',
30
+ matcher: 'morph-.*',
31
+ hooks: [{
32
+ type: 'command',
33
+ command: 'node framework/hooks/claude-code/subagent/log-agent-start.js'
34
+ }]
35
+ },
36
+ ```
37
+
38
+ **Step 2: Bump HOOKS_VERSION to 2.3.0**
39
+
40
+ ```js
41
+ const HOOKS_VERSION = '2.3.0';
42
+ ```
43
+
44
+ **Step 3: Verify no SubagentStart key appears in hooks tests**
45
+
46
+ Run: `npm test -- test/hooks/hooks-installer.test.js`
47
+ Expected: All pass (the test that checks installed events doesn't assert SubagentStart)
48
+
49
+ **Step 4: Commit**
50
+
51
+ ```bash
52
+ git add src/utils/hooks-installer.js
53
+ git commit -m "fix(hooks): remove SubagentStart hook pointing at missing log-agent-start.js"
54
+ ```
55
+
56
+ ---
57
+
58
+ ### Task 2: Convert validate-bash-commands.js to a prompt-type hook
59
+
60
+ The Node.js `validate-bash-commands.js` performs 3 regex checks. These can be replaced by a CC-native `type: "prompt"` hook that uses Haiku to evaluate the command — simpler, no file required.
61
+
62
+ **Files:**
63
+ - Modify: `src/utils/hooks-installer.js`
64
+ - No file to delete yet (keep validate-bash-commands.js for reference, remove in Task 2b)
65
+
66
+ **Step 1: Write failing test that expects the Bash PreToolUse hook to be type "prompt"**
67
+
68
+ In `test/hooks/hooks-installer.test.js`, add inside `describe('installClaudeHooks', ...)`:
69
+
70
+ ```js
71
+ test('Bash PreToolUse hook is type prompt (not command)', async () => {
72
+ await installClaudeHooks(tempDir);
73
+ const settings = readSettings();
74
+ const bashEntry = settings.hooks.PreToolUse.find(e => e.matcher === 'Bash');
75
+ assert.ok(bashEntry, 'Bash PreToolUse entry exists');
76
+ assert.strictEqual(bashEntry.hooks[0].type, 'prompt');
77
+ assert.ok(bashEntry.hooks[0].prompt, 'prompt field is set');
78
+ });
79
+ ```
80
+
81
+ **Step 2: Run test to confirm it fails**
82
+
83
+ Run: `npm test -- test/hooks/hooks-installer.test.js 2>&1 | grep -A3 "Bash PreToolUse hook is type prompt"`
84
+ Expected: FAIL — hook type is currently "command"
85
+
86
+ **Step 3: Replace the Bash PreToolUse hook in MORPH_HOOKS**
87
+
88
+ In `src/utils/hooks-installer.js`, replace the `// === PreToolUse: Bash ===` block:
89
+
90
+ ```js
91
+ // === PreToolUse: Bash ===
92
+ {
93
+ event: 'PreToolUse',
94
+ matcher: 'Bash',
95
+ hooks: [{
96
+ type: 'prompt',
97
+ prompt: `You are a guard for a morph-spec project. Read the bash command from the hook input and check:
98
+ 1. Does the command delete .morph/ (e.g. "rm -rf .morph" or "rm -rf .morph/")? → BLOCK
99
+ 2. Does the command edit state.json directly via sed, jq, awk, echo, cat, or printf with a shell redirect (>)? → BLOCK
100
+ 3. Does the command write to .morph/framework/ via shell redirect (>)? → BLOCK
101
+ If any condition is true, respond: {"ok": false, "reason": "MORPH-SPEC: <brief explanation and suggested alternative>"}
102
+ Otherwise respond: {"ok": true}`
103
+ }]
104
+ },
105
+ ```
106
+
107
+ **Step 4: Run the new test — expect PASS**
108
+
109
+ Run: `npm test -- test/hooks/hooks-installer.test.js 2>&1 | grep -A3 "Bash PreToolUse hook is type prompt"`
110
+ Expected: PASS
111
+
112
+ **Step 5: Run full hooks installer tests**
113
+
114
+ Run: `npm test -- test/hooks/hooks-installer.test.js`
115
+ Expected: All pass (existing "installs all hook events" test doesn't assert Bash hook type)
116
+
117
+ **Step 6: Commit**
118
+
119
+ ```bash
120
+ git add src/utils/hooks-installer.js test/hooks/hooks-installer.test.js
121
+ git commit -m "feat(hooks): convert Bash guard to native prompt-type hook, remove Node.js dependency"
122
+ ```
123
+
124
+ ---
125
+
126
+ ### Task 3: Inject active feature spec into SessionStart context
127
+
128
+ The framework claims to be spec-driven but the active feature's spec.md is never auto-loaded into Claude's context. Fix `inject-morph-context.js` to include the spec content (truncated to 3000 chars) when an active feature exists and has a spec.
129
+
130
+ **Files:**
131
+ - Modify: `framework/hooks/claude-code/session-start/inject-morph-context.js`
132
+
133
+ **Step 1: Write failing test for spec injection behavior**
134
+
135
+ In `test/hooks/shared-utils.test.js` (or create `test/hooks/inject-context.test.js`):
136
+
137
+ ```js
138
+ import { test, describe } from 'node:test';
139
+ import assert from 'node:assert';
140
+ import { readFileSync, existsSync } from 'fs';
141
+
142
+ describe('inject-morph-context spec injection', () => {
143
+ test('inject-morph-context.js reads spec file content', () => {
144
+ const src = readFileSync(
145
+ 'framework/hooks/claude-code/session-start/inject-morph-context.js',
146
+ 'utf-8'
147
+ );
148
+ // Must read the spec file for the active feature
149
+ assert.ok(src.includes('1-design/spec.md'), 'Should reference spec.md path');
150
+ assert.ok(src.includes('Active feature spec'), 'Should label the spec section');
151
+ });
152
+ });
153
+ ```
154
+
155
+ **Step 2: Run to confirm it fails**
156
+
157
+ Run: `npm test -- test/hooks/inject-context.test.js`
158
+ Expected: FAIL — "Should reference spec.md path"
159
+
160
+ **Step 3: Modify inject-morph-context.js to add spec injection**
161
+
162
+ After the `if (active) { ... }` block (after the "Key commands" line), add the spec reading logic. The full modified file:
163
+
164
+ ```js
165
+ #!/usr/bin/env node
166
+
167
+ /**
168
+ * SessionStart Hook: Inject MORPH-SPEC Context
169
+ *
170
+ * Event: SessionStart | Matcher: startup|resume|compact
171
+ *
172
+ * Reads state.json and injects a summary + active feature spec as
173
+ * additionalContext so Claude knows the current morph-spec state and
174
+ * spec at session start.
175
+ *
176
+ * Fail-open: exits 0 on any error.
177
+ */
178
+
179
+ import { readFileSync, existsSync } from 'fs';
180
+ import { join } from 'path';
181
+ import { loadState, getActiveFeature, getPendingGates, getMissingOutputs } from '../../shared/state-reader.js';
182
+ import { stateExists } from '../../shared/state-reader.js';
183
+ import { injectContext, pass } from '../../shared/hook-response.js';
184
+
185
+ const SPEC_MAX_CHARS = 3000;
186
+
187
+ try {
188
+ if (!stateExists()) pass();
189
+
190
+ const state = loadState();
191
+ if (!state?.features || Object.keys(state.features).length === 0) pass();
192
+
193
+ const active = getActiveFeature();
194
+ const lines = ['MORPH-SPEC Status:'];
195
+
196
+ if (active) {
197
+ const { name, feature } = active;
198
+ lines.push(`- Active feature: ${name} (phase: ${feature.phase}, workflow: ${feature.workflow || 'auto'})`);
199
+ lines.push(`- Status: ${feature.status}`);
200
+
201
+ // Task progress
202
+ if (feature.tasks) {
203
+ lines.push(`- Tasks: ${feature.tasks.completed || 0}/${feature.tasks.total || 0} completed`);
204
+ }
205
+
206
+ // Pending approvals
207
+ const pending = getPendingGates(name);
208
+ if (pending.length > 0) {
209
+ lines.push(`- Pending approvals: ${pending.join(', ')}`);
210
+ }
211
+
212
+ // Next required output
213
+ const missing = getMissingOutputs(name);
214
+ if (missing.length > 0) {
215
+ const next = missing[0];
216
+ lines.push(`- Next required output: ${next.type} → ${next.path}`);
217
+ }
218
+
219
+ // Checkpoints
220
+ if (feature.checkpoints?.length > 0) {
221
+ const lastCp = feature.checkpoints[feature.checkpoints.length - 1];
222
+ lines.push(`- Last checkpoint: #${lastCp.checkpointNum} (${lastCp.passed ? 'passed' : 'failed'})`);
223
+ }
224
+
225
+ // Active feature spec (truncated)
226
+ const specPath = join(process.cwd(), `.morph/features/${name}/1-design/spec.md`);
227
+ if (existsSync(specPath)) {
228
+ try {
229
+ const specContent = readFileSync(specPath, 'utf-8');
230
+ const truncated = specContent.length > SPEC_MAX_CHARS
231
+ ? specContent.slice(0, SPEC_MAX_CHARS) + '\n\n[... spec truncated — read full file at ' + specPath + ']'
232
+ : specContent;
233
+ lines.push('');
234
+ lines.push(`--- Active feature spec (${name}/1-design/spec.md) ---`);
235
+ lines.push(truncated);
236
+ lines.push('--- End spec ---');
237
+ } catch {
238
+ // Non-blocking: skip spec injection on read error
239
+ }
240
+ }
241
+ } else {
242
+ // Show summary of all features
243
+ const featureNames = Object.keys(state.features);
244
+ lines.push(`- Features: ${featureNames.length} (${featureNames.join(', ')})`);
245
+
246
+ for (const [name, feature] of Object.entries(state.features)) {
247
+ lines.push(` - ${name}: phase=${feature.phase}, status=${feature.status}`);
248
+ }
249
+ }
250
+
251
+ // Remind about key commands
252
+ lines.push('');
253
+ lines.push('Key commands: morph-spec status <feature> | morph-spec phase advance <feature> | morph-spec approve <feature> <gate>');
254
+
255
+ injectContext(lines.join('\n'));
256
+ } catch {
257
+ // Fail-open
258
+ process.exit(0);
259
+ }
260
+ ```
261
+
262
+ **Step 4: Run test**
263
+
264
+ Run: `npm test -- test/hooks/inject-context.test.js`
265
+ Expected: PASS
266
+
267
+ **Step 5: Commit**
268
+
269
+ ```bash
270
+ git add framework/hooks/claude-code/session-start/inject-morph-context.js test/hooks/inject-context.test.js
271
+ git commit -m "feat(hooks): inject active feature spec.md into SessionStart context"
272
+ ```
273
+
274
+ ---
275
+
276
+ ## Phase 2: Skills improvements
277
+
278
+ ### Task 4: Add $ARGUMENTS to all phase workflow skills
279
+
280
+ Phase skills currently have no way to accept a feature name argument. `/phase-design` and `/phase-design my-feature` both work but the latter doesn't bind to the feature. Add `$ARGUMENTS` to enable bound invocations like `/phase-design my-feature`.
281
+
282
+ **Files to modify:**
283
+ - `framework/skills/level-1-workflows/phase-setup.md`
284
+ - `framework/skills/level-1-workflows/phase-design.md`
285
+ - `framework/skills/level-1-workflows/phase-clarify.md`
286
+ - `framework/skills/level-1-workflows/phase-uiux.md`
287
+ - `framework/skills/level-1-workflows/phase-tasks.md`
288
+ - `framework/skills/level-1-workflows/phase-implement.md`
289
+
290
+ **Step 1: Read each file to see current argument references**
291
+
292
+ For each file, check if `{feature-name}`, `{feature}`, or `$ARGUMENTS` is already used.
293
+
294
+ Run: `grep -n "feature-name\|ARGUMENTS" framework/skills/level-1-workflows/*.md`
295
+
296
+ **Step 2: Add argument-hint frontmatter and $ARGUMENTS to phase-design.md**
297
+
298
+ In `framework/skills/level-1-workflows/phase-design.md`, add to frontmatter:
299
+ ```yaml
300
+ argument-hint: "[feature-name]"
301
+ ```
302
+ Then replace all instances of `{feature-name}` with `$ARGUMENTS` in the skill body (wherever the user is expected to fill in a feature name). If no placeholder exists, add at top of body:
303
+ ```markdown
304
+ Feature: **$ARGUMENTS**
305
+ ```
306
+
307
+ Repeat this same pattern for all 6 phase skill files.
308
+
309
+ **Step 3: Write test that verifies $ARGUMENTS appears in installed skills**
310
+
311
+ Add to `test/utils/skills-installer.test.js` (or create it):
312
+ ```js
313
+ test('installed phase-design skill contains $ARGUMENTS', async () => {
314
+ await installSkills(tempDir);
315
+ const skillPath = join(tempDir, '.claude', 'skills', 'phase-design.md');
316
+ assert.ok(existsSync(skillPath), 'phase-design.md installed');
317
+ const content = readFileSync(skillPath, 'utf-8');
318
+ assert.ok(content.includes('$ARGUMENTS') || content.includes('argument-hint'),
319
+ 'skill supports arguments');
320
+ });
321
+ ```
322
+
323
+ **Step 4: Run test, fix any issues, run all tests**
324
+
325
+ Run: `npm test -- test/utils/skills-installer.test.js`
326
+ Run: `npm test`
327
+ Expected: All pass
328
+
329
+ **Step 5: Commit**
330
+
331
+ ```bash
332
+ git add framework/skills/level-1-workflows/
333
+ git commit -m "feat(skills): add \$ARGUMENTS support to all phase workflow skills"
334
+ ```
335
+
336
+ ---
337
+
338
+ ### Task 5: Add disable-model-invocation and context:fork to appropriate skills
339
+
340
+ **phase-implement** and **phase-tasks** should not be auto-triggered by Claude (they have side effects). Add `disable-model-invocation: true`. **phase-implement** should also run in an isolated context via `context: fork`.
341
+
342
+ **Files:**
343
+ - Modify: `framework/skills/level-1-workflows/phase-implement.md`
344
+ - Modify: `framework/skills/level-1-workflows/phase-tasks.md`
345
+
346
+ **Step 1: Add to phase-implement.md frontmatter**
347
+
348
+ ```yaml
349
+ disable-model-invocation: true
350
+ context: fork
351
+ agent: general-purpose
352
+ ```
353
+
354
+ Note: `phase-implement` already has `user-invocable: false`. Keep that. Add the two new fields.
355
+
356
+ **Step 2: Add to phase-tasks.md frontmatter**
357
+
358
+ ```yaml
359
+ disable-model-invocation: true
360
+ ```
361
+
362
+ **Step 3: Verify the frontmatter parses correctly**
363
+
364
+ Read both files after editing and verify YAML is valid (no duplicate keys, correct indentation).
365
+
366
+ **Step 4: Commit**
367
+
368
+ ```bash
369
+ git add framework/skills/level-1-workflows/phase-implement.md \
370
+ framework/skills/level-1-workflows/phase-tasks.md
371
+ git commit -m "feat(skills): disable auto-invocation and add context:fork to implementation phases"
372
+ ```
373
+
374
+ ---
375
+
376
+ ## Phase 3: Domain specialists as native subagents
377
+
378
+ ### Task 6: Add installDomainAgents() to agents-installer.js
379
+
380
+ Domain specialist skills in `framework/skills/level-2-domains/` should be installed as Claude Code subagents (`.claude/agents/`) with `memory: project`, not as flat skill files. Create a function that converts each skill .md file into a proper agent .md file.
381
+
382
+ **Files:**
383
+ - Modify: `src/utils/agents-installer.js`
384
+
385
+ **Step 1: Write failing test**
386
+
387
+ Add to `test/utils/agents-installer.test.js`:
388
+ ```js
389
+ import { installDomainAgents } from '../../src/utils/agents-installer.js';
390
+
391
+ describe('installDomainAgents', () => {
392
+ test('creates agent files from level-2-domains skills', async () => {
393
+ await installDomainAgents(tempDir, 'framework');
394
+ const agentsDir = join(tempDir, '.claude', 'agents');
395
+ assert.ok(existsSync(agentsDir));
396
+
397
+ // blazor-builder skill → agent file
398
+ const blazorAgent = join(agentsDir, 'morph-domain-blazor-builder.md');
399
+ assert.ok(existsSync(blazorAgent), 'blazor-builder domain agent created');
400
+
401
+ const content = readFileSync(blazorAgent, 'utf-8');
402
+ assert.ok(content.includes('memory: project'), 'agent has project memory');
403
+ assert.ok(content.includes('model: sonnet'), 'agent uses sonnet model');
404
+ });
405
+
406
+ test('domain agent files have required frontmatter fields', async () => {
407
+ await installDomainAgents(tempDir, 'framework');
408
+ const blazorAgent = join(tempDir, '.claude', 'agents', 'morph-domain-blazor-builder.md');
409
+ const content = readFileSync(blazorAgent, 'utf-8');
410
+ assert.ok(content.startsWith('---'), 'has frontmatter');
411
+ assert.ok(content.includes('name:'), 'has name');
412
+ assert.ok(content.includes('description:'), 'has description');
413
+ assert.ok(content.includes('tools:'), 'has tools');
414
+ assert.ok(content.includes('memory: project'), 'has memory');
415
+ });
416
+ });
417
+ ```
418
+
419
+ **Step 2: Run test to confirm it fails**
420
+
421
+ Run: `npm test -- test/utils/agents-installer.test.js 2>&1 | grep "installDomainAgents"`
422
+ Expected: FAIL — function not exported
423
+
424
+ **Step 3: Implement installDomainAgents() in agents-installer.js**
425
+
426
+ Add after the existing `installAgents` function:
427
+
428
+ ```js
429
+ import { readdirSync, readFileSync as readFileSyncFS, statSync } from 'node:fs';
430
+
431
+ /**
432
+ * Install level-2-domains specialist skills as native Claude Code subagents.
433
+ * Each skill .md file becomes a .claude/agents/morph-domain-{name}.md file
434
+ * with memory: project and specialist tool access.
435
+ *
436
+ * @param {string} projectDir - Target project directory
437
+ * @param {string} frameworkDir - Path to morph-spec framework/ directory
438
+ */
439
+ export async function installDomainAgents(projectDir, frameworkDir = 'framework') {
440
+ const domainSkillsDir = join(frameworkDir, 'skills', 'level-2-domains');
441
+ if (!existsSync(domainSkillsDir)) return;
442
+
443
+ const targetDir = join(projectDir, '.claude', 'agents');
444
+ mkdirSync(targetDir, { recursive: true });
445
+
446
+ const skillFiles = collectSkillFiles(domainSkillsDir);
447
+
448
+ for (const filePath of skillFiles) {
449
+ const raw = readFileSyncFS(filePath, 'utf-8');
450
+ const { frontmatter, body } = parseSkillFile(raw);
451
+
452
+ const name = frontmatter.name;
453
+ if (!name) continue;
454
+
455
+ const description = frontmatter.description?.trim().replace(/^>\s*/, '') || `${name} domain specialist`;
456
+ const tools = frontmatter['allowed-tools'] || 'Read, Edit, Write, Bash, Grep, Glob';
457
+
458
+ const agentFrontmatter = [
459
+ `name: ${name}`,
460
+ `description: ${description}`,
461
+ `model: sonnet`,
462
+ `tools: ${tools}`,
463
+ `maxTurns: 20`,
464
+ `memory: project`,
465
+ ].join('\n');
466
+
467
+ const content = `---\n${agentFrontmatter}\n---\n\n${body}\n`;
468
+ const filename = `morph-domain-${name}.md`;
469
+ writeFileSync(join(targetDir, filename), content, 'utf-8');
470
+ }
471
+ }
472
+
473
+ /**
474
+ * Recursively collect all .md files (excluding README.md) from a directory.
475
+ * @param {string} dir
476
+ * @returns {string[]}
477
+ */
478
+ function collectSkillFiles(dir) {
479
+ const result = [];
480
+ for (const entry of readdirSync(dir)) {
481
+ const fullPath = join(dir, entry);
482
+ if (statSync(fullPath).isDirectory()) {
483
+ result.push(...collectSkillFiles(fullPath));
484
+ } else if (entry.endsWith('.md') && entry !== 'README.md') {
485
+ result.push(fullPath);
486
+ }
487
+ }
488
+ return result;
489
+ }
490
+
491
+ /**
492
+ * Parse a skill .md file with YAML frontmatter.
493
+ * Returns { frontmatter: Object, body: string }.
494
+ * @param {string} content
495
+ * @returns {{ frontmatter: Record<string, string>, body: string }}
496
+ */
497
+ function parseSkillFile(content) {
498
+ const frontmatter = {};
499
+ let body = content;
500
+
501
+ if (content.startsWith('---')) {
502
+ const end = content.indexOf('\n---', 3);
503
+ if (end !== -1) {
504
+ const fmText = content.slice(3, end).trim();
505
+ body = content.slice(end + 4).trim();
506
+
507
+ for (const line of fmText.split('\n')) {
508
+ const colonIdx = line.indexOf(':');
509
+ if (colonIdx === -1) continue;
510
+ const key = line.slice(0, colonIdx).trim();
511
+ const val = line.slice(colonIdx + 1).trim();
512
+ if (key && !key.startsWith('-')) {
513
+ frontmatter[key] = val.replace(/^['"]|['"]$/g, '');
514
+ }
515
+ }
516
+ }
517
+ }
518
+
519
+ return { frontmatter, body };
520
+ }
521
+ ```
522
+
523
+ **Step 4: Add `existsSync` to existing imports at top of agents-installer.js**
524
+
525
+ The file currently imports from `node:fs`:
526
+ ```js
527
+ import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
528
+ ```
529
+ Change to:
530
+ ```js
531
+ import { readFileSync, writeFileSync, mkdirSync, readdirSync, statSync, existsSync } from 'node:fs';
532
+ ```
533
+
534
+ **Step 5: Run the new tests**
535
+
536
+ Run: `npm test -- test/utils/agents-installer.test.js`
537
+ Expected: Both new tests PASS
538
+
539
+ **Step 6: Run full test suite**
540
+
541
+ Run: `npm test`
542
+ Expected: All pass
543
+
544
+ **Step 7: Commit**
545
+
546
+ ```bash
547
+ git add src/utils/agents-installer.js test/utils/agents-installer.test.js
548
+ git commit -m "feat(agents): add installDomainAgents() — converts level-2-domain skills to native subagents with memory:project"
549
+ ```
550
+
551
+ ---
552
+
553
+ ### Task 7: Stop installing level-2-domains as flat skills
554
+
555
+ Now that domain specialists are installed as subagents, remove them from the skills installer to avoid duplication.
556
+
557
+ **Files:**
558
+ - Modify: `src/utils/skills-installer.js`
559
+
560
+ **Step 1: Write test that verifies level-2-domains are NOT installed as flat skills**
561
+
562
+ In `test/utils/skills-installer.test.js`, add:
563
+ ```js
564
+ test('level-2-domains skills are NOT installed as flat skill files', async () => {
565
+ await installSkills(tempDir);
566
+ const skillsDir = join(tempDir, '.claude', 'skills');
567
+ // blazor-builder should not appear as a skill (it's now a domain agent)
568
+ const blazorSkill = join(skillsDir, 'blazor-builder.md');
569
+ assert.ok(!existsSync(blazorSkill), 'blazor-builder.md should NOT be in skills (it is a domain agent now)');
570
+ });
571
+ ```
572
+
573
+ **Step 2: Run test to confirm it fails (blazor-builder.md currently IS installed)**
574
+
575
+ Run: `npm test -- test/utils/skills-installer.test.js 2>&1 | grep "level-2-domains skills"`
576
+ Expected: FAIL
577
+
578
+ **Step 3: Remove level-2-domains from SKILL_LEVELS_TO_INSTALL**
579
+
580
+ In `src/utils/skills-installer.js`, change:
581
+ ```js
582
+ const SKILL_LEVELS_TO_INSTALL = ['level-0-meta', 'level-1-workflows', 'level-2-domains'];
583
+ ```
584
+ to:
585
+ ```js
586
+ // level-2-domains are installed as native subagents via installDomainAgents() — not as skills
587
+ const SKILL_LEVELS_TO_INSTALL = ['level-0-meta', 'level-1-workflows'];
588
+ ```
589
+
590
+ **Step 4: Run tests**
591
+
592
+ Run: `npm test -- test/utils/skills-installer.test.js`
593
+ Expected: All pass including new test
594
+
595
+ **Step 5: Commit**
596
+
597
+ ```bash
598
+ git add src/utils/skills-installer.js test/utils/skills-installer.test.js
599
+ git commit -m "feat(skills): remove level-2-domains from skill installer (now installed as domain subagents)"
600
+ ```
601
+
602
+ ---
603
+
604
+ ### Task 8: Wire installDomainAgents() into init.js and update.js
605
+
606
+ `init.js` already calls `installAgents()`. Add `installDomainAgents()` call after it. Same for `update.js`.
607
+
608
+ **Files:**
609
+ - Modify: `src/commands/project/init.js`
610
+ - Modify: `src/commands/project/update.js`
611
+
612
+ **Step 1: Read the relevant section of init.js to find where installAgents is called**
613
+
614
+ Look for the `installAgents(` call in init.js.
615
+
616
+ **Step 2: Add installDomainAgents import and call in init.js**
617
+
618
+ Add to imports at top of init.js (after existing agents-installer import):
619
+ ```js
620
+ import { installAgents, installDomainAgents } from '../../utils/agents-installer.js';
621
+ ```
622
+
623
+ After the `await installAgents(targetDir, frameworkDir)` call, add:
624
+ ```js
625
+ await installDomainAgents(targetDir, frameworkDir);
626
+ ```
627
+
628
+ **Step 3: Add installDomainAgents import and call in update.js**
629
+
630
+ Same pattern — add import and call after the existing `installAgents()` call.
631
+
632
+ **Step 4: Run integration tests**
633
+
634
+ Run: `npm test -- test/commands/init.test.js`
635
+ Run: `npm test -- test/commands/update.test.js`
636
+ Expected: All pass (new call is additive, doesn't break existing behavior)
637
+
638
+ **Step 5: Commit**
639
+
640
+ ```bash
641
+ git add src/commands/project/init.js src/commands/project/update.js
642
+ git commit -m "feat(init,update): install domain specialist subagents alongside tier-1/2 agents"
643
+ ```
644
+
645
+ ---
646
+
647
+ ## Phase 4: Cleanup and version bump
648
+
649
+ ### Task 9: Remove validate-bash-commands.js dead file and update HOOKS_VERSION
650
+
651
+ The Bash guard is now a prompt-type hook. The Node.js file is no longer called. Remove it to reduce confusion.
652
+
653
+ **Files:**
654
+ - Delete: `framework/hooks/claude-code/pre-tool-use/validate-bash-commands.js`
655
+ - Bump HOOKS_VERSION in `src/utils/hooks-installer.js` to `2.4.0`
656
+
657
+ **Step 1: Verify the file is no longer referenced in MORPH_HOOKS**
658
+
659
+ Run: `grep -r "validate-bash-commands" src/ framework/hooks/`
660
+ Expected: Zero matches in production code (tests may reference it)
661
+
662
+ **Step 2: Delete the file**
663
+
664
+ ```bash
665
+ rm "framework/hooks/claude-code/pre-tool-use/validate-bash-commands.js"
666
+ ```
667
+
668
+ **Step 3: Bump HOOKS_VERSION**
669
+
670
+ In `src/utils/hooks-installer.js`:
671
+ ```js
672
+ const HOOKS_VERSION = '2.4.0';
673
+ ```
674
+
675
+ **Step 4: Run all tests**
676
+
677
+ Run: `npm test`
678
+ Expected: All pass
679
+
680
+ **Step 5: Commit**
681
+
682
+ ```bash
683
+ git add src/utils/hooks-installer.js
684
+ git rm framework/hooks/claude-code/pre-tool-use/validate-bash-commands.js
685
+ git commit -m "chore(hooks): remove validate-bash-commands.js (replaced by prompt-type hook), bump HOOKS_VERSION to 2.4.0"
686
+ ```
687
+
688
+ ---
689
+
690
+ ### Task 10: Update package.json version and run full test suite
691
+
692
+ **Files:**
693
+ - Modify: `package.json`
694
+ - Modify: `framework/CLAUDE.md` (version string)
695
+ - Modify: `framework/CLAUDE_runtime.md` (version string)
696
+
697
+ **Step 1: Bump version to 4.5.0**
698
+
699
+ In `package.json`, change `"version": "4.4.0"` to `"version": "4.5.0"`.
700
+
701
+ **Step 2: Update version strings in framework files**
702
+
703
+ In `framework/CLAUDE.md` and `framework/CLAUDE_runtime.md`, update `v4.4.0` to `v4.5.0`.
704
+
705
+ **Step 3: Run full test suite**
706
+
707
+ Run: `npm test`
708
+ Expected: All tests pass, zero failures
709
+
710
+ **Step 4: Final commit**
711
+
712
+ ```bash
713
+ git add package.json framework/CLAUDE.md framework/CLAUDE_runtime.md
714
+ git commit -m "chore: bump version to 4.5.0 — CC native alignment round 3"
715
+ ```
716
+
717
+ ---
718
+
719
+ ## Deferred (out of scope for this plan)
720
+
721
+ The following items from the analysis require deeper investigation or have higher risk:
722
+
723
+ - **Rewrite hooks shared modules to bash/jq** — high refactor risk; hooks work correctly today
724
+ - **Map trust scoring to `permissions.defaultMode`** — trust is deeply integrated into state + approval gating; separate PR
725
+ - **Migrate standards CLI to skills** — large UX change; needs design discussion
726
+ - **Reduce workflow configs from 10 to ≤4** — needs usage data
727
+ - **Verify `.claude/rules/` native CC support** — needs official CC team confirmation
728
+ - **Replace workflow-detector LLM call with AskUserQuestion** — behavior change requiring testing