@polymorphism-tech/morph-spec 4.3.0 → 4.3.2

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 (209) hide show
  1. package/CLAUDE.md +155 -0
  2. package/bin/morph-spec.js +3 -3
  3. package/bin/task-manager.cjs +102 -14
  4. package/package.json +2 -1
  5. package/src/commands/agents/agents-fuse.js +2 -1
  6. package/src/commands/project/detect-agents.js +31 -1
  7. package/src/commands/project/detect.js +11 -1
  8. package/src/commands/project/doctor.js +76 -70
  9. package/src/commands/project/init.js +9 -2
  10. package/src/commands/project/update.js +12 -2
  11. package/src/commands/state/advance-phase.js +19 -4
  12. package/src/commands/state/state.js +38 -14
  13. package/src/commands/tasks/task.js +1 -1
  14. package/src/commands/threads/thread-template.js +1 -1
  15. package/src/core/state/state-manager.js +19 -15
  16. package/src/core/templates/template-registry.js +1 -1
  17. package/src/core/workflows/workflow-detector.js +16 -3
  18. package/src/lib/checkpoints/checkpoint-hooks.js +8 -3
  19. package/src/lib/detectors/index.js +1 -1
  20. package/src/lib/detectors/standards-generator.js +77 -17
  21. package/src/lib/detectors/structure-detector.js +67 -39
  22. package/src/lib/generators/recap-generator.js +30 -10
  23. package/src/lib/validators/validation-runner.js +8 -24
  24. package/src/utils/hooks-installer.js +69 -0
  25. package/stacks/blazor-azure/.claude/commands/morph-apply.md +221 -0
  26. package/stacks/blazor-azure/.claude/commands/morph-archive.md +79 -0
  27. package/stacks/blazor-azure/.claude/commands/morph-deploy.md +529 -0
  28. package/stacks/blazor-azure/.claude/commands/morph-infra.md +209 -0
  29. package/stacks/blazor-azure/.claude/commands/morph-preflight.md +227 -0
  30. package/stacks/blazor-azure/.claude/commands/morph-proposal.md +122 -0
  31. package/stacks/blazor-azure/.claude/commands/morph-status.md +86 -0
  32. package/stacks/blazor-azure/.claude/commands/morph-troubleshoot.md +122 -0
  33. package/stacks/blazor-azure/.morph/.morphversion +5 -5
  34. package/stacks/blazor-azure/.morph/archive/.gitkeep +25 -0
  35. package/stacks/blazor-azure/.morph/config/config.json +9 -0
  36. package/stacks/blazor-azure/.morph/features/.gitkeep +25 -0
  37. package/stacks/blazor-azure/.morph/project/context/README.md +17 -0
  38. package/stacks/blazor-azure/.morph/schemas/agent.schema.json +296 -0
  39. package/stacks/blazor-azure/.morph/schemas/tasks.schema.json +220 -0
  40. package/stacks/blazor-azure/.morph/specs/.gitkeep +20 -0
  41. package/stacks/blazor-azure/.morph/standards/ai-agents/blazor-ui.md +364 -0
  42. package/stacks/blazor-azure/.morph/standards/ai-agents/production.md +415 -0
  43. package/stacks/blazor-azure/.morph/standards/ai-agents/setup.md +418 -0
  44. package/stacks/blazor-azure/.morph/standards/ai-agents/team-orchestration.md +479 -0
  45. package/stacks/blazor-azure/.morph/standards/ai-agents/workflows.md +354 -0
  46. package/stacks/blazor-azure/.morph/standards/architecture/ddd/aggregates.md +120 -0
  47. package/stacks/blazor-azure/.morph/standards/architecture/ddd/entities.md +99 -0
  48. package/stacks/blazor-azure/.morph/standards/architecture/ddd/value-objects.md +124 -0
  49. package/stacks/blazor-azure/.morph/standards/backend/api/minimal-api.md +494 -0
  50. package/stacks/blazor-azure/.morph/standards/backend/api/rest.md +492 -0
  51. package/stacks/blazor-azure/.morph/standards/backend/api/validation.md +88 -0
  52. package/stacks/blazor-azure/.morph/standards/backend/authentication/passkeys.md +428 -0
  53. package/stacks/blazor-azure/.morph/standards/backend/database/ef-core.md +199 -0
  54. package/stacks/blazor-azure/.morph/standards/backend/database/migrations.md +393 -0
  55. package/stacks/blazor-azure/.morph/standards/backend/database/postgresql/database.md +352 -0
  56. package/stacks/blazor-azure/.morph/standards/backend/database/repository-patterns.md +528 -0
  57. package/stacks/blazor-azure/.morph/standards/backend/database/vector-search-rag.md +541 -0
  58. package/stacks/blazor-azure/.morph/standards/backend/dotnet/async.md +366 -0
  59. package/stacks/blazor-azure/.morph/standards/backend/dotnet/core.md +117 -0
  60. package/stacks/blazor-azure/.morph/standards/backend/dotnet/di.md +439 -0
  61. package/stacks/blazor-azure/.morph/standards/backend/dotnet/program-cs-checklist.md +92 -0
  62. package/stacks/blazor-azure/.morph/standards/backend/integrations/asaas/asaas-api.md +216 -0
  63. package/stacks/blazor-azure/.morph/standards/backend/integrations/clerk/clerk-auth.md +290 -0
  64. package/stacks/blazor-azure/.morph/standards/backend/integrations/hangfire/hangfire-jobs.md +350 -0
  65. package/stacks/blazor-azure/.morph/standards/backend/integrations/resend/resend-email.md +385 -0
  66. package/stacks/blazor-azure/.morph/standards/context/analytics.md +96 -0
  67. package/stacks/blazor-azure/.morph/standards/context/bundles.md +110 -0
  68. package/stacks/blazor-azure/.morph/standards/context/priming.md +78 -0
  69. package/stacks/blazor-azure/.morph/standards/core/architecture.md +185 -0
  70. package/stacks/blazor-azure/.morph/standards/core/coding.md +214 -0
  71. package/stacks/blazor-azure/.morph/standards/core/git-branching-strategy.md +403 -0
  72. package/stacks/blazor-azure/.morph/standards/core/git.md +185 -0
  73. package/stacks/blazor-azure/.morph/standards/core/testing.md +295 -0
  74. package/stacks/blazor-azure/.morph/standards/data/nosql/blob-storage.md +102 -0
  75. package/stacks/blazor-azure/.morph/standards/data/nosql/cache/redis.md +97 -0
  76. package/stacks/blazor-azure/.morph/standards/data/nosql/cosmos-db.md +118 -0
  77. package/stacks/blazor-azure/.morph/standards/data/vector-search/azure-ai-search.md +121 -0
  78. package/stacks/blazor-azure/.morph/standards/data/vector-search/rag-chunking.md +104 -0
  79. package/stacks/blazor-azure/.morph/standards/frontend/blazor/design-checklist.md +222 -0
  80. package/stacks/blazor-azure/.morph/standards/frontend/blazor/fluent-ui-setup.md +595 -0
  81. package/stacks/blazor-azure/.morph/standards/frontend/blazor/fluent-ui.md +137 -0
  82. package/stacks/blazor-azure/.morph/standards/frontend/blazor/html-conversion.md +184 -0
  83. package/stacks/blazor-azure/.morph/standards/frontend/blazor/lifecycle.md +195 -0
  84. package/stacks/blazor-azure/.morph/standards/frontend/blazor/pitfalls.md +198 -0
  85. package/stacks/blazor-azure/.morph/standards/frontend/blazor/state.md +191 -0
  86. package/stacks/blazor-azure/.morph/standards/frontend/design-system/animations.md +151 -0
  87. package/stacks/blazor-azure/.morph/standards/frontend/design-system/naming.md +64 -0
  88. package/stacks/blazor-azure/.morph/standards/frontend/nextjs/nextjs-patterns.md +198 -0
  89. package/stacks/blazor-azure/.morph/standards/infrastructure/azure/azure.md +624 -0
  90. package/stacks/blazor-azure/.morph/standards/infrastructure/azure/bicep/bicep-patterns.md +422 -0
  91. package/stacks/blazor-azure/.morph/standards/infrastructure/azure/devops/azure-devops-setup.md +516 -0
  92. package/stacks/blazor-azure/.morph/standards/infrastructure/azure/devops/local-development.md +520 -0
  93. package/stacks/blazor-azure/.morph/standards/infrastructure/azure/services/functions.md +486 -0
  94. package/stacks/blazor-azure/.morph/standards/infrastructure/azure/services/service-bus.md +459 -0
  95. package/stacks/blazor-azure/.morph/standards/infrastructure/azure/services/storage.md +407 -0
  96. package/stacks/blazor-azure/.morph/standards/infrastructure/docker/easypanel-deploy.md +196 -0
  97. package/stacks/blazor-azure/.morph/standards/infrastructure/supabase/mcp-setup.md +252 -0
  98. package/stacks/blazor-azure/.morph/standards/infrastructure/supabase/supabase-auth.md +176 -0
  99. package/stacks/blazor-azure/.morph/standards/infrastructure/supabase/supabase-pgvector.md +169 -0
  100. package/stacks/blazor-azure/.morph/standards/infrastructure/supabase/supabase-rls.md +184 -0
  101. package/stacks/blazor-azure/.morph/standards/infrastructure/supabase/supabase-storage.md +153 -0
  102. package/stacks/blazor-azure/.morph/standards/integration/api/graphql.md +91 -0
  103. package/stacks/blazor-azure/.morph/standards/integration/api/grpc.md +114 -0
  104. package/stacks/blazor-azure/.morph/standards/integration/api/rest-design.md +95 -0
  105. package/stacks/blazor-azure/.morph/standards/integration/event-driven/cqrs.md +101 -0
  106. package/stacks/blazor-azure/.morph/standards/integration/event-driven/event-sourcing.md +124 -0
  107. package/stacks/blazor-azure/.morph/standards/integration/event-driven/service-bus.md +95 -0
  108. package/stacks/blazor-azure/.morph/standards/observability/logging.md +131 -0
  109. package/stacks/blazor-azure/.morph/standards/observability/metrics.md +121 -0
  110. package/stacks/blazor-azure/.morph/standards/observability/monitoring.md +114 -0
  111. package/stacks/blazor-azure/.morph/standards/observability/tracing.md +132 -0
  112. package/stacks/blazor-azure/.morph/standards/workflows/parallel-execution.md +112 -0
  113. package/stacks/blazor-azure/.morph/standards/workflows/thread-management.md +113 -0
  114. package/stacks/blazor-azure/.morph/test-infra/example.bicep +59 -0
  115. package/stacks/blazor-azure/CLAUDE.md +106 -101
  116. package/stacks/nextjs-supabase/.claude/commands/morph-apply.md +221 -0
  117. package/stacks/nextjs-supabase/.claude/commands/morph-archive.md +79 -0
  118. package/stacks/nextjs-supabase/.claude/commands/morph-deploy.md +529 -0
  119. package/stacks/nextjs-supabase/.claude/commands/morph-infra.md +209 -0
  120. package/stacks/nextjs-supabase/.claude/commands/morph-preflight.md +227 -0
  121. package/stacks/nextjs-supabase/.claude/commands/morph-proposal.md +122 -0
  122. package/stacks/nextjs-supabase/.claude/commands/morph-status.md +86 -0
  123. package/stacks/nextjs-supabase/.claude/commands/morph-troubleshoot.md +122 -0
  124. package/stacks/nextjs-supabase/.morph/.morphversion +5 -0
  125. package/stacks/nextjs-supabase/.morph/config/agents.json +730 -127
  126. package/stacks/nextjs-supabase/.morph/config/config.json +9 -0
  127. package/stacks/nextjs-supabase/.morph/project/context/README.md +17 -0
  128. package/stacks/nextjs-supabase/.morph/standards/ai-agents/blazor-ui.md +364 -0
  129. package/stacks/nextjs-supabase/.morph/standards/ai-agents/production.md +415 -0
  130. package/stacks/nextjs-supabase/.morph/standards/ai-agents/setup.md +418 -0
  131. package/stacks/nextjs-supabase/.morph/standards/ai-agents/team-orchestration.md +479 -0
  132. package/stacks/nextjs-supabase/.morph/standards/ai-agents/workflows.md +354 -0
  133. package/stacks/nextjs-supabase/.morph/standards/architecture/ddd/aggregates.md +120 -0
  134. package/stacks/nextjs-supabase/.morph/standards/architecture/ddd/entities.md +99 -0
  135. package/stacks/nextjs-supabase/.morph/standards/architecture/ddd/value-objects.md +124 -0
  136. package/stacks/nextjs-supabase/.morph/standards/backend/api/minimal-api.md +494 -0
  137. package/stacks/nextjs-supabase/.morph/standards/backend/api/rest.md +492 -0
  138. package/stacks/nextjs-supabase/.morph/standards/backend/api/validation.md +88 -0
  139. package/stacks/nextjs-supabase/.morph/standards/backend/authentication/passkeys.md +428 -0
  140. package/stacks/nextjs-supabase/.morph/standards/backend/database/ef-core.md +199 -0
  141. package/stacks/nextjs-supabase/.morph/standards/backend/database/migrations.md +393 -0
  142. package/stacks/nextjs-supabase/.morph/standards/backend/database/postgresql/database.md +352 -0
  143. package/stacks/nextjs-supabase/.morph/standards/backend/database/repository-patterns.md +528 -0
  144. package/stacks/nextjs-supabase/.morph/standards/backend/database/vector-search-rag.md +541 -0
  145. package/stacks/nextjs-supabase/.morph/standards/backend/dotnet/async.md +366 -0
  146. package/stacks/nextjs-supabase/.morph/standards/backend/dotnet/core.md +117 -0
  147. package/stacks/nextjs-supabase/.morph/standards/backend/dotnet/di.md +439 -0
  148. package/stacks/nextjs-supabase/.morph/standards/backend/dotnet/program-cs-checklist.md +92 -0
  149. package/stacks/nextjs-supabase/.morph/standards/backend/integrations/asaas/asaas-api.md +216 -0
  150. package/stacks/nextjs-supabase/.morph/standards/backend/integrations/clerk/clerk-auth.md +290 -0
  151. package/stacks/nextjs-supabase/.morph/standards/backend/integrations/hangfire/hangfire-jobs.md +350 -0
  152. package/stacks/nextjs-supabase/.morph/standards/backend/integrations/resend/resend-email.md +385 -0
  153. package/stacks/nextjs-supabase/.morph/standards/context/analytics.md +96 -0
  154. package/stacks/nextjs-supabase/.morph/standards/context/bundles.md +110 -0
  155. package/stacks/nextjs-supabase/.morph/standards/context/priming.md +78 -0
  156. package/stacks/nextjs-supabase/.morph/standards/core/architecture.md +185 -0
  157. package/stacks/nextjs-supabase/.morph/standards/core/coding.md +214 -0
  158. package/stacks/nextjs-supabase/.morph/standards/core/git-branching-strategy.md +403 -0
  159. package/stacks/nextjs-supabase/.morph/standards/core/git.md +185 -0
  160. package/stacks/nextjs-supabase/.morph/standards/core/testing.md +295 -0
  161. package/stacks/nextjs-supabase/.morph/standards/data/nosql/blob-storage.md +102 -0
  162. package/stacks/nextjs-supabase/.morph/standards/data/nosql/cache/redis.md +97 -0
  163. package/stacks/nextjs-supabase/.morph/standards/data/nosql/cosmos-db.md +118 -0
  164. package/stacks/nextjs-supabase/.morph/standards/data/vector-search/azure-ai-search.md +121 -0
  165. package/stacks/nextjs-supabase/.morph/standards/data/vector-search/rag-chunking.md +104 -0
  166. package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/design-checklist.md +222 -0
  167. package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/fluent-ui-setup.md +595 -0
  168. package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/fluent-ui.md +137 -0
  169. package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/html-conversion.md +184 -0
  170. package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/lifecycle.md +195 -0
  171. package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/pitfalls.md +198 -0
  172. package/stacks/nextjs-supabase/.morph/standards/frontend/blazor/state.md +191 -0
  173. package/stacks/nextjs-supabase/.morph/standards/frontend/design-system/animations.md +151 -0
  174. package/stacks/nextjs-supabase/.morph/standards/frontend/design-system/naming.md +64 -0
  175. package/stacks/nextjs-supabase/.morph/standards/frontend/nextjs/nextjs-patterns.md +198 -0
  176. package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/azure.md +624 -0
  177. package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/bicep/bicep-patterns.md +422 -0
  178. package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/devops/azure-devops-setup.md +516 -0
  179. package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/devops/local-development.md +520 -0
  180. package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/services/functions.md +486 -0
  181. package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/services/service-bus.md +459 -0
  182. package/stacks/nextjs-supabase/.morph/standards/infrastructure/azure/services/storage.md +407 -0
  183. package/stacks/nextjs-supabase/.morph/standards/infrastructure/docker/easypanel-deploy.md +196 -0
  184. package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/mcp-setup.md +252 -0
  185. package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/supabase-auth.md +176 -0
  186. package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/supabase-pgvector.md +169 -0
  187. package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/supabase-rls.md +184 -0
  188. package/stacks/nextjs-supabase/.morph/standards/infrastructure/supabase/supabase-storage.md +153 -0
  189. package/stacks/nextjs-supabase/.morph/standards/integration/api/graphql.md +91 -0
  190. package/stacks/nextjs-supabase/.morph/standards/integration/api/grpc.md +114 -0
  191. package/stacks/nextjs-supabase/.morph/standards/integration/api/rest-design.md +95 -0
  192. package/stacks/nextjs-supabase/.morph/standards/integration/event-driven/cqrs.md +101 -0
  193. package/stacks/nextjs-supabase/.morph/standards/integration/event-driven/event-sourcing.md +124 -0
  194. package/stacks/nextjs-supabase/.morph/standards/integration/event-driven/service-bus.md +95 -0
  195. package/stacks/nextjs-supabase/.morph/standards/observability/logging.md +131 -0
  196. package/stacks/nextjs-supabase/.morph/standards/observability/metrics.md +121 -0
  197. package/stacks/nextjs-supabase/.morph/standards/observability/monitoring.md +114 -0
  198. package/stacks/nextjs-supabase/.morph/standards/observability/tracing.md +132 -0
  199. package/stacks/nextjs-supabase/.morph/standards/workflows/parallel-execution.md +112 -0
  200. package/stacks/nextjs-supabase/.morph/standards/workflows/thread-management.md +113 -0
  201. package/stacks/nextjs-supabase/CLAUDE.md +69 -63
  202. package/stacks/blazor-azure/.morph/templates/.gitkeep +0 -0
  203. package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/cd-prod.yml.hbs +0 -41
  204. package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/cd-staging.yml.hbs +0 -24
  205. package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/ci-build.yml.hbs +0 -23
  206. package/stacks/nextjs-supabase/.morph/templates/.gitkeep +0 -0
  207. package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/cd-prod.yml.hbs +0 -22
  208. package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/cd-staging.yml.hbs +0 -22
  209. package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/ci-build.yml.hbs +0 -35
package/CLAUDE.md ADDED
@@ -0,0 +1,155 @@
1
+ # MORPH-SPEC - Claude Code Instructions
2
+
3
+ > by Polymorphism Tech
4
+
5
+ Spec-driven development system. Specialized agent hub for multi-stack projects with Infrastructure as Code.
6
+
7
+ ---
8
+
9
+ ## CRITICAL RULES
10
+
11
+ ### NEVER:
12
+ - Skip to code without a specification
13
+ - Implement without design approval
14
+ - Ignore standards in `.morph/standards/`
15
+ - Create infrastructure manually
16
+ - Generate code without defined contracts
17
+
18
+ ### ALWAYS:
19
+ - Follow the 5 mandatory phases
20
+ - Generate outputs in `.morph/project/outputs/{feature}/`
21
+ - Document decisions in `decisions.md`
22
+ - Checkpoint every 3 implemented tasks
23
+ - Use Infrastructure as Code
24
+
25
+ ---
26
+
27
+ ## WORKFLOW (5 Phases)
28
+
29
+ | Phase | Trigger | Actions | Output | Pause? |
30
+ |-------|---------|---------|--------|--------|
31
+ | **1. SETUP** | Feature request | Read project context, identify stack, activate agents, create folder | proposal.md | No |
32
+ | **2. DESIGN** | Setup done | Spec + contracts + decisions + costs | spec.md, contracts, decisions.md | **Yes** |
33
+ | **3. CLARIFY** | Design approved | Ambiguities, questions, edge cases | Updated spec | No |
34
+ | **4. TASKS** | Clarifications resolved | Break into tasks, ordering, checkpoints, dependencies | tasks.md | **Yes** |
35
+ | **5. IMPLEMENT** | Tasks approved | Task by task, checkpoint every 3, recap | Code + recap.md | No |
36
+
37
+ ---
38
+
39
+ ## PROJECT STRUCTURE
40
+
41
+ ```
42
+ project/
43
+ ├── CLAUDE.md
44
+ ├── .morph/
45
+ │ ├── config/ # config.json, agents.json
46
+ │ ├── standards/ # coding, architecture, stack-specific
47
+ │ ├── templates/ # Output templates
48
+ │ ├── project/
49
+ │ │ ├── context/ # detection-log.md, project.md
50
+ │ │ ├── standards/ # inferred.md, overrides.md
51
+ │ │ └── outputs/{feature}/ # Features in development
52
+ │ │ ├── proposal.md, spec.md, tasks.md
53
+ │ │ ├── contracts, decisions.md, recap.md
54
+ └── .claude/commands/ # Slash commands
55
+ ```
56
+
57
+ ---
58
+
59
+ ## AGENTS
60
+
61
+ ### Tier 1 — Orchestrators (Always Active)
62
+
63
+ | Agent | Responsibilities |
64
+ |-------|-----------------|
65
+ | **Standards Architect** | Standards, naming, review, cross-cutting concerns |
66
+ | **AI System Architect** | Agent systems, AI integrations, LLM orchestration |
67
+ | **Thread Orchestrator** | Parallel execution, thread management, context optimization |
68
+
69
+ ### Tier 2 — Domain Leaders
70
+
71
+ | Agent | Responsibilities |
72
+ |-------|-----------------|
73
+ | **Tech Lead** | Architecture decisions, code quality, task breakdown |
74
+ | **DevOps Engineer** | CI/CD, deployment pipelines, infrastructure |
75
+ | **QA Lead** | Test strategies, validation, quality gates |
76
+
77
+ ### Tier 3 — Specialists (Activated by keywords)
78
+
79
+ | Agent | Keywords |
80
+ |-------|---------|
81
+ | **Next.js Expert** | nextjs, react, frontend, app router, pages |
82
+ | **Blazor Builder** | blazor, razor, mudblazor, fluent ui |
83
+ | **API Designer** | api, endpoint, rest, openapi, swagger |
84
+ | **.NET Senior** | dotnet, csharp, minimal api, ef core |
85
+ | **EF Modeler** | entity framework, migrations, dbcontext |
86
+ | **Azure Architect** | azure, container apps, bicep, app service |
87
+ | **Bicep Architect** | bicep, iac, arm template, azure resources |
88
+ | **Azure Deploy Specialist** | deploy, ci/cd, github actions, azure devops |
89
+ | **Container Specialist** | docker, dockerfile, compose, kubernetes |
90
+ | **Supabase Expert** | supabase, postgresql, rls, realtime, pgvector |
91
+ | **Azure Identity** | auth, authentication, entra id, jwt, oauth |
92
+ | **Clerk Auth** | clerk, auth0, authentication, social login |
93
+ | **Asaas Financial** | payment, billing, subscription, asaas |
94
+ | **Resend Email** | email, resend, smtp, notifications |
95
+ | **Hangfire Orchestrator** | background jobs, queue, scheduling, hangfire |
96
+ | **MS Agent Expert** | semantic kernel, microsoft agents, ai pipeline |
97
+ | **UI/UX Designer** | design, ux, wireframe, mockup, figma |
98
+ | **SEO Growth Hacker** | seo, performance, analytics, lighthouse |
99
+ | **PO/PM Advisor** | product, roadmap, requirements, user stories |
100
+ | **Prompt Engineer** | prompts, system prompts, llm, few-shot |
101
+ | **Context Optimizer** | context window, token optimization, chunking |
102
+ | **Vector Search Expert** | vector db, embeddings, semantic search, rag |
103
+ | **Observability Expert** | logging, tracing, metrics, opentelemetry |
104
+ | **Code Analyzer** | refactor, analysis, code review, complexity |
105
+ | **Testing Specialist** | tests, coverage, tdd, bdd, vitest, jest, xunit |
106
+
107
+ ### Tier 4 — Validators
108
+
109
+ | Agent | Responsibilities |
110
+ |-------|-----------------|
111
+ | **Contract Compliance Validator** | Ensures implementation matches spec contracts |
112
+
113
+ ---
114
+
115
+ ## TEMPLATES
116
+
117
+ > ALWAYS use `morph-spec template render` to render. NEVER fill placeholders manually.
118
+
119
+ ### Placeholders: `{{PLACEHOLDER}}`
120
+
121
+ | Placeholder | Example |
122
+ |-------------|---------|
123
+ | `{{FEATURE_NAME}}` | `scheduled-reports` |
124
+ | `{{FEATURE_NAME_PASCAL}}` | `ScheduledReports` |
125
+ | `{{FEATURE_NAME_CAMEL}}` | `scheduledReports` |
126
+ | `{{STACK}}` | `blazor-azure` or `nextjs-supabase` |
127
+ | `{{DATE}}`, `{{AUTHOR}}`, `{{NAMESPACE}}` | Auto from config.json |
128
+
129
+ ---
130
+
131
+ ## COMMANDS
132
+
133
+ | Command | Action |
134
+ |---------|--------|
135
+ | `/morph-proposal {feature}` | Full spec pipeline (phases 1-4, auto-continuation with pauses) |
136
+ | `/morph-apply {feature}` | Implement feature (phase 5) |
137
+ | `/morph-status` | Dashboard |
138
+ | `/morph-archive {feature}` | Archive completed feature |
139
+ | `/morph-infra {action}` | Manage infrastructure |
140
+ | `/morph-preflight` | Pre-deploy validation |
141
+ | `/morph-troubleshoot {error}` | Error troubleshooting |
142
+
143
+ ---
144
+
145
+ ## REFERENCES
146
+
147
+ - `.morph/config/config.json` — Project configuration
148
+ - `.morph/config/agents.json` — Full agent definitions
149
+ - `.morph/standards/` — Coding, architecture, stack-specific standards
150
+ - `.morph/project/context/` — Detection log, project context
151
+ - `.morph/project/standards/inferred.md` — Auto-detected project standards
152
+
153
+ ---
154
+
155
+ *MORPH-SPEC v4.3.0 by Polymorphism Tech*
package/bin/morph-spec.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { program } from 'commander';
4
4
  import chalk from 'chalk';
@@ -141,7 +141,7 @@ program
141
141
  program
142
142
  .command('doctor')
143
143
  .description('Check MORPH installation health')
144
- .option('--v3', 'Run v3.0 specific checks (lib files, HOPs, standards, agents, migration status)')
144
+ .option('--full', 'Run full health check (lib files, commands, HOPs, standards, agents, state)')
145
145
  .action(doctorCommand);
146
146
 
147
147
  program
@@ -256,7 +256,7 @@ generateCommand
256
256
  .description('Auto-generate recap.md from project data (state, validation, contracts)')
257
257
  .option('--quiet', 'Suppress output')
258
258
  .action(async (feature, options) => {
259
- const { generateRecap } = await import('../src/lib/recap-generator.js');
259
+ const { generateRecap } = await import('../src/lib/generators/recap-generator.js');
260
260
  await generateRecap('.', feature, options);
261
261
  });
262
262
 
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  const fs = require('fs').promises;
11
+ const fsSync = require('fs');
11
12
  const path = require('path');
12
13
 
13
14
  // Simple ANSI color helpers (chalk v5 is ESM-only, can't require in CJS)
@@ -22,6 +23,68 @@ const chalk = {
22
23
  bold: (s) => `\x1b[1m${s}\x1b[0m`,
23
24
  };
24
25
 
26
+ // ============================================================================
27
+ // v3 Schema Helpers
28
+ // ============================================================================
29
+
30
+ /**
31
+ * Parse tasks.md to extract task stubs for v3 state format.
32
+ * Looks for headings like: ### T001 — Task title
33
+ */
34
+ async function parseTasksMd(featureName) {
35
+ const tasksPath = path.join(process.cwd(), `.morph/project/outputs/${featureName}/tasks.md`);
36
+ let content = '';
37
+ try {
38
+ content = await fs.readFile(tasksPath, 'utf-8');
39
+ } catch {
40
+ return [];
41
+ }
42
+
43
+ const tasks = [];
44
+ const headingRe = /^###\s+(T\d+)\s+[—–-]\s+(.+)$/gm;
45
+ let match;
46
+ while ((match = headingRe.exec(content)) !== null) {
47
+ tasks.push({
48
+ id: match[1],
49
+ title: match[2].trim(),
50
+ status: 'pending',
51
+ dependencies: [],
52
+ files: [],
53
+ checkpoint: null
54
+ });
55
+ }
56
+ return tasks;
57
+ }
58
+
59
+ /**
60
+ * Ensure feature.taskList exists (array of individual task objects).
61
+ * In v3 state, feature.tasks is a counter object {total, completed, ...}.
62
+ * Individual task objects live in feature.taskList.
63
+ */
64
+ async function ensureTaskList(feature, featureName) {
65
+ if (Array.isArray(feature.tasks)) {
66
+ // v2 format: tasks IS the array
67
+ return feature.tasks;
68
+ }
69
+ // v3 format: use taskList or build from tasks.md
70
+ if (!feature.taskList || feature.taskList.length === 0) {
71
+ feature.taskList = await parseTasksMd(featureName);
72
+ }
73
+ return feature.taskList;
74
+ }
75
+
76
+ /**
77
+ * After modifying taskList, sync counts back to feature.tasks counter.
78
+ */
79
+ function syncCounters(feature) {
80
+ if (Array.isArray(feature.tasks)) return; // v2, nothing to sync
81
+ const list = feature.taskList || [];
82
+ feature.tasks.completed = list.filter(t => t.status === 'completed').length;
83
+ feature.tasks.inProgress = list.filter(t => t.status === 'in_progress').length;
84
+ feature.tasks.pending = list.filter(t => t.status === 'pending').length;
85
+ // Don't touch feature.tasks.total — it is the authoritative count
86
+ }
87
+
25
88
  class TaskManager {
26
89
  constructor(statePath = '.morph/state.json') {
27
90
  this.statePath = statePath;
@@ -46,7 +109,12 @@ class TaskManager {
46
109
  * Save state.json
47
110
  */
48
111
  async saveState(state) {
49
- state.project.updatedAt = new Date().toISOString();
112
+ // v3 state uses metadata.lastUpdated, v2 used project.updatedAt
113
+ if (state.metadata) {
114
+ state.metadata.lastUpdated = new Date().toISOString();
115
+ } else if (state.project) {
116
+ state.project.updatedAt = new Date().toISOString();
117
+ }
50
118
  await fs.writeFile(this.statePath, JSON.stringify(state, null, 2), 'utf-8');
51
119
  }
52
120
 
@@ -65,11 +133,12 @@ class TaskManager {
65
133
  throw new Error(`Feature '${featureName}' not found in state.json`);
66
134
  }
67
135
 
136
+ const taskList = await ensureTaskList(feature, featureName);
68
137
  const results = [];
69
138
  const tasksToComplete = [];
70
139
 
71
140
  for (const taskId of taskIds) {
72
- const task = feature.tasks.find(t => t.id === taskId);
141
+ const task = taskList.find(t => t.id === taskId);
73
142
 
74
143
  if (!task) {
75
144
  console.error(chalk.red(`❌ Task ${taskId} not found`));
@@ -82,7 +151,7 @@ class TaskManager {
82
151
  }
83
152
 
84
153
  // Validate dependencies
85
- const missingDeps = this.checkDependencies(task, feature.tasks);
154
+ const missingDeps = this.checkDependencies(task, taskList);
86
155
  if (missingDeps.length > 0) {
87
156
  console.error(chalk.red(`❌ Cannot complete ${taskId}: missing dependencies: ${missingDeps.join(', ')}`));
88
157
  continue;
@@ -118,11 +187,12 @@ class TaskManager {
118
187
  }
119
188
  }
120
189
 
121
- // Update progress
122
- feature.progress = this.calculateProgress(feature.tasks);
190
+ // Sync v3 counters then compute progress
191
+ syncCounters(feature);
192
+ feature.progress = this.calculateProgress(taskList);
123
193
 
124
194
  // Auto-checkpoint every 3 tasks
125
- const recentCompleted = this.getRecentCompleted(feature.tasks, 3);
195
+ const recentCompleted = this.getRecentCompleted(taskList, 3);
126
196
  if (recentCompleted.length === 3) {
127
197
  const lastCheckpoint = feature.checkpoints[feature.checkpoints.length - 1];
128
198
  const shouldAutoCheckpoint = !lastCheckpoint ||
@@ -138,6 +208,21 @@ class TaskManager {
138
208
  // Save state
139
209
  await this.saveState(state);
140
210
 
211
+ // Run TaskCompleted agent-teams hook for each completed task (non-blocking)
212
+ for (const task of results) {
213
+ try {
214
+ const { executeHook, formatHookResults } = await import('../src/lib/hooks/hook-executor.js');
215
+ const hookResult = await executeHook(process.cwd(), featureName, 'TaskCompleted', {
216
+ taskId: task.id
217
+ });
218
+ if (!hookResult.passed && hookResult.errors.length > 0) {
219
+ console.log(formatHookResults(hookResult, 'TaskCompleted'));
220
+ }
221
+ } catch {
222
+ // Hook executor unavailable — non-blocking
223
+ }
224
+ }
225
+
141
226
  // Auto-generate metadata.json (for quick LLM access)
142
227
  await this.generateMetadata(featureName, feature);
143
228
 
@@ -145,7 +230,7 @@ class TaskManager {
145
230
  this.displayProgress(feature);
146
231
 
147
232
  // Suggest next task
148
- const nextTask = this.getNextTask(feature.tasks);
233
+ const nextTask = this.getNextTask(taskList);
149
234
  if (nextTask) {
150
235
  console.log(chalk.cyan(`\n⏭️ Next: ${nextTask.id} - ${nextTask.title}`));
151
236
  if (nextTask.dependencies && nextTask.dependencies.length > 0) {
@@ -167,7 +252,7 @@ class TaskManager {
167
252
  try {
168
253
  console.log(chalk.cyan('\n🔍 Running code validation...'));
169
254
 
170
- const { runValidation, formatValidationResults } = await import('../src/lib/validation-runner.js');
255
+ const { runValidation, formatValidationResults } = await import('../src/lib/validators/validation-runner.js');
171
256
  const result = await runValidation('.', featureName, { verbose: true });
172
257
 
173
258
  formatValidationResults(result);
@@ -243,7 +328,7 @@ class TaskManager {
243
328
 
244
329
  // Run checkpoint hooks (new enhanced validation system)
245
330
  try {
246
- const { runCheckpointHooks, shouldRunCheckpoint } = await import('../src/lib/checkpoint-hooks.js');
331
+ const { runCheckpointHooks, shouldRunCheckpoint } = await import('../src/lib/checkpoints/checkpoint-hooks.js');
247
332
 
248
333
  if (shouldRunCheckpoint(tasksCompleted, 3)) {
249
334
  checkpointResult = await runCheckpointHooks(featureName, checkpointNum);
@@ -268,7 +353,7 @@ class TaskManager {
268
353
  // Fallback to old validation if checkpoint-hooks not available
269
354
  console.log(chalk.yellow('⚠️ Checkpoint hooks not available, using legacy validation'));
270
355
  try {
271
- const { runValidation } = await import('../src/lib/validation-runner.js');
356
+ const { runValidation } = await import('../src/lib/validators/validation-runner.js');
272
357
  const result = await runValidation('.', featureName, { verbose: false });
273
358
  validationNote = result.passed
274
359
  ? ' | Validation: PASSED'
@@ -333,7 +418,7 @@ class TaskManager {
333
418
  return;
334
419
  }
335
420
 
336
- const { extractFeatureMetadata } = await import('../src/lib/metadata-extractor.js');
421
+ const { extractFeatureMetadata } = await import('../src/lib/generators/metadata-extractor.js');
337
422
  const metadata = extractFeatureMetadata(feature);
338
423
 
339
424
  const outputPath = path.join(
@@ -410,7 +495,8 @@ class TaskManager {
410
495
  throw new Error(`Feature '${featureName}' not found`);
411
496
  }
412
497
 
413
- const task = feature.tasks.find(t => t.id === taskId);
498
+ const taskList = await ensureTaskList(feature, featureName);
499
+ const task = taskList.find(t => t.id === taskId);
414
500
 
415
501
  if (!task) {
416
502
  throw new Error(`Task ${taskId} not found`);
@@ -422,13 +508,14 @@ class TaskManager {
422
508
  }
423
509
 
424
510
  // Validate dependencies
425
- const missingDeps = this.checkDependencies(task, feature.tasks);
511
+ const missingDeps = this.checkDependencies(task, taskList);
426
512
  if (missingDeps.length > 0) {
427
513
  throw new Error(`Cannot start ${taskId}: missing dependencies: ${missingDeps.join(', ')}`);
428
514
  }
429
515
 
430
516
  task.status = 'in_progress';
431
517
  task.startedAt = new Date().toISOString();
518
+ syncCounters(feature);
432
519
 
433
520
  await this.saveState(state);
434
521
 
@@ -446,7 +533,8 @@ class TaskManager {
446
533
  throw new Error(`Feature '${featureName}' not found`);
447
534
  }
448
535
 
449
- const nextTask = this.getNextTask(feature.tasks);
536
+ const taskList = await ensureTaskList(feature, featureName);
537
+ const nextTask = this.getNextTask(taskList);
450
538
 
451
539
  if (nextTask) {
452
540
  console.log(chalk.cyan(`\n⏭️ Next task: ${nextTask.id} - ${nextTask.title}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polymorphism-tech/morph-spec",
3
- "version": "4.3.0",
3
+ "version": "4.3.2",
4
4
  "description": "MORPH-SPEC: AI-First development framework with validation pipeline and multi-stack support",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -48,6 +48,7 @@
48
48
  "docs:serve": "npx http-server docs/api -p 8080 -o"
49
49
  },
50
50
  "dependencies": {
51
+ "@polymorphism-tech/morph-spec": "^4.3.1",
51
52
  "ajv": "^8.12.0",
52
53
  "ajv-formats": "^3.0.1",
53
54
  "chalk": "^5.3.0",
@@ -71,7 +71,8 @@ export async function agentsReviewAggregateCommand(feature, options) {
71
71
  const agentList = options.agents.split(',').map(a => a.trim());
72
72
  const strategy = options.strategy || 'best-of-n';
73
73
 
74
- console.log(chalk.cyan(`\n Aggregate Reviews ${feature}\n`));
74
+ console.log(chalk.yellow('\n [STUB] This command returns mock data. Real aggregation not yet implemented.\n'));
75
+ console.log(chalk.cyan(` Aggregate Reviews — ${feature}\n`));
75
76
  console.log(` Agents: ${agentList.join(', ')}`);
76
77
  console.log(` Strategy: ${strategy}`);
77
78
  console.log('');
@@ -123,6 +123,34 @@ export function detectAgentsCommand(input, options) {
123
123
  const config = loadAgentsConfig();
124
124
  const result = detectAgents(userInput, config);
125
125
 
126
+ // Stack-aware filtering: penalize stack-mismatched agents
127
+ try {
128
+ const projectConfigPath = join(process.cwd(), '.morph/config/config.json');
129
+ const projectConfig = JSON.parse(readFileSync(projectConfigPath, 'utf8'));
130
+ const stack = projectConfig?.project?.stack || projectConfig?.project?.language || '';
131
+ const isJsStack = stack === 'nodejs' || stack === 'javascript' || stack === 'nextjs';
132
+
133
+ if (isJsStack) {
134
+ const dotnetKeywords = ['dotnet', '.net', 'csharp', 'c#', 'blazor', 'razor', 'azure', 'bicep',
135
+ 'ef core', 'entity framework', 'hangfire', 'mudblazor', 'fluent ui', 'asp.net'];
136
+ const hasExplicitDotnetRequest = dotnetKeywords.some(k => userInput.toLowerCase().includes(k));
137
+
138
+ if (!hasExplicitDotnetRequest) {
139
+ const dotnetAgents = new Set([
140
+ 'dotnet-senior', 'azure-architect', 'ef-modeler', 'bicep-architect',
141
+ 'blazor-builder', 'blazor-concurrency-validator', 'hangfire-orchestrator',
142
+ 'azure-deploy-specialist'
143
+ ]);
144
+ result.core = result.core.filter(id => !dotnetAgents.has(id));
145
+ result.specialists = result.specialists.filter(id => !dotnetAgents.has(id));
146
+ result.all = result.all.filter(id => !dotnetAgents.has(id));
147
+ result.matches = result.matches.filter(m => !dotnetAgents.has(m.id));
148
+ }
149
+ }
150
+ } catch {
151
+ // Config not found or unreadable — skip stack filtering
152
+ }
153
+
126
154
  // Enrich with complexity analysis
127
155
  try {
128
156
  result.complexity = analyzeRequestComplexity(userInput);
@@ -141,7 +169,9 @@ export function detectAgentsCommand(input, options) {
141
169
  }
142
170
 
143
171
  // Enrich with skill paths for each detected agent
144
- const allAgents = [...(config.agents.core || []), ...(config.agents.specialists || [])];
172
+ const allAgents = Object.entries(config.agents || {})
173
+ .filter(([id]) => !id.startsWith('_'))
174
+ .map(([id, agent]) => ({ id, ...agent }));
145
175
  result.skillPaths = result.all
146
176
  .map(id => {
147
177
  const agent = allAgents.find(a => a.id === id);
@@ -3,7 +3,7 @@ import ora from 'ora';
3
3
  import chalk from 'chalk';
4
4
  import { logger } from '../../utils/logger.js';
5
5
  import { detectProject, getDetectionSummary } from '../../lib/detectors/index.js';
6
- import { ensureDir, writeFile } from '../../utils/file-copier.js';
6
+ import { ensureDir, writeFile, readJson, writeJson, pathExists } from '../../utils/file-copier.js';
7
7
 
8
8
  export async function detectCommand(options) {
9
9
  const targetPath = options.path || process.cwd();
@@ -84,6 +84,16 @@ export async function detectCommand(options) {
84
84
  const standardsPath = join(standardsDir, 'inferred.md');
85
85
  await writeFile(standardsPath, results.inferred.markdown);
86
86
 
87
+ // Update config.json with detected stack and architecture
88
+ const configPath = join(targetPath, '.morph', 'config', 'config.json');
89
+ if (await pathExists(configPath)) {
90
+ const projectConfig = await readJson(configPath);
91
+ projectConfig.project = projectConfig.project || {};
92
+ projectConfig.project.stack = results.structure.stack;
93
+ projectConfig.project.architecture = results.structure.architecture;
94
+ await writeJson(configPath, projectConfig);
95
+ }
96
+
87
97
  spinner.succeed('Results saved!');
88
98
  logger.dim(` - ${logPath}`);
89
99
  logger.dim(` - ${standardsPath}`);