@polymorphism-tech/morph-spec 3.0.1 → 3.2.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 (316) hide show
  1. package/CLAUDE.md +561 -63
  2. package/LICENSE +72 -72
  3. package/README.md +275 -79
  4. package/bin/detect-agents.js +3 -1
  5. package/bin/morph-spec.js +60 -1
  6. package/bin/render-template.js +61 -14
  7. package/bin/semantic-detect-agents.js +2 -1
  8. package/bin/{task-manager.js → task-manager.cjs} +113 -8
  9. package/bin/validate-agents-skills.js +10 -4
  10. package/bin/validate-agents.js +4 -3
  11. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
  12. package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
  13. package/docs/api/scripts/collapse.js +38 -38
  14. package/docs/api/scripts/commonNav.js +28 -28
  15. package/docs/api/scripts/linenumber.js +25 -25
  16. package/docs/api/scripts/nav.js +12 -12
  17. package/docs/api/scripts/polyfill.js +3 -3
  18. package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
  19. package/docs/api/scripts/prettify/lang-css.js +2 -2
  20. package/docs/api/scripts/prettify/prettify.js +28 -28
  21. package/docs/api/scripts/search.js +98 -98
  22. package/docs/api/styles/jsdoc.css +776 -776
  23. package/docs/api/styles/prettify.css +80 -80
  24. package/docs/cli-auto-detection.md +219 -0
  25. package/docs/examples.md +328 -328
  26. package/docs/getting-started.md +3 -3
  27. package/docs/llm-interaction-config.md +735 -0
  28. package/docs/templates.md +418 -418
  29. package/docs/troubleshooting.md +269 -0
  30. package/package.json +7 -3
  31. package/scripts/postinstall.js +132 -132
  32. package/scripts/reorganize-skills.cjs +1 -1
  33. package/scripts/validate-agents-structure.cjs +1 -1
  34. package/scripts/validate-skills.cjs +2 -2
  35. package/src/commands/advance-phase.js +93 -2
  36. package/src/commands/analyze-blazor-concurrency.js +193 -193
  37. package/src/commands/approve.js +221 -0
  38. package/src/commands/capture-pattern.js +121 -0
  39. package/src/commands/create-story.js +5 -2
  40. package/src/commands/deploy.js +780 -780
  41. package/src/commands/detect-agents.js +4 -2
  42. package/src/commands/generate.js +276 -149
  43. package/src/commands/init.js +37 -0
  44. package/src/commands/lint-fluent.js +352 -352
  45. package/src/commands/migrate-state.js +158 -0
  46. package/src/commands/rollback-phase.js +185 -185
  47. package/src/commands/search-patterns.js +126 -0
  48. package/src/commands/session-summary.js +291 -291
  49. package/src/commands/shard-spec.js +224 -224
  50. package/src/commands/spawn-team.js +172 -0
  51. package/src/commands/sprint-status.js +250 -250
  52. package/src/commands/task.js +3 -3
  53. package/src/commands/troubleshoot.js +222 -222
  54. package/src/commands/update.js +36 -0
  55. package/src/commands/upgrade.js +346 -0
  56. package/src/commands/validate-blazor-state.js +210 -210
  57. package/src/commands/validate-blazor.js +156 -156
  58. package/src/commands/validate-css.js +84 -84
  59. package/src/commands/validate-phase.js +221 -221
  60. package/src/generator/.gitkeep +0 -0
  61. package/src/generator/config-generator.js +206 -0
  62. package/src/generator/templates/config.json.template +40 -0
  63. package/src/generator/templates/project.md.template +67 -0
  64. package/src/lib/blazor-concurrency-analyzer.js +288 -288
  65. package/src/lib/blazor-state-validator.js +291 -291
  66. package/src/lib/blazor-validator.js +374 -374
  67. package/src/lib/checkpoint-hooks.js +258 -0
  68. package/src/lib/context-generator.js +7 -4
  69. package/src/lib/css-validator.js +352 -352
  70. package/src/lib/design-system-generator.js +298 -298
  71. package/src/lib/hook-executor.js +2 -1
  72. package/src/lib/learning-system.js +520 -520
  73. package/src/lib/metadata-extractor.js +380 -0
  74. package/src/lib/mockup-generator.js +366 -366
  75. package/src/lib/phase-state-machine.js +214 -0
  76. package/src/lib/stack-resolver.js +148 -0
  77. package/src/lib/standards-context-injector.js +4 -3
  78. package/src/lib/state-manager.js +120 -0
  79. package/src/lib/team-orchestrator.js +2 -1
  80. package/src/lib/template-data-sources.js +325 -0
  81. package/src/lib/troubleshoot-grep.js +204 -194
  82. package/src/lib/troubleshoot-index.js +144 -144
  83. package/src/lib/ui-detector.js +350 -350
  84. package/src/lib/validation-runner.js +2 -1
  85. package/src/lib/validators/architecture-validator.js +387 -387
  86. package/src/lib/validators/content-validator.js +351 -0
  87. package/src/lib/validators/package-validator.js +360 -360
  88. package/src/lib/validators/ui-contrast-validator.js +422 -422
  89. package/src/llm/.gitkeep +0 -0
  90. package/src/llm/analyzer.js +215 -0
  91. package/src/llm/environment-detector.js +43 -0
  92. package/src/llm/few-shot-examples.js +216 -0
  93. package/src/llm/project-config-schema.json +188 -0
  94. package/src/llm/prompt-builder.js +96 -0
  95. package/src/llm/schema-validator.js +121 -0
  96. package/src/orchestrator.js +206 -0
  97. package/src/sanitizer/.gitkeep +0 -0
  98. package/src/sanitizer/context-sanitizer.js +221 -0
  99. package/src/sanitizer/patterns.js +163 -0
  100. package/src/scanner/.gitkeep +0 -0
  101. package/src/scanner/project-scanner.js +242 -0
  102. package/src/types/index.js +477 -0
  103. package/src/ui/.gitkeep +0 -0
  104. package/src/ui/diff-display.js +91 -0
  105. package/src/ui/interactive-wizard.js +96 -0
  106. package/src/ui/user-review.js +211 -0
  107. package/src/ui/wizard-questions.js +190 -0
  108. package/src/utils/file-copier.js +3 -1
  109. package/src/utils/logger.js +32 -32
  110. package/src/utils/version-checker.js +175 -175
  111. package/src/writer/.gitkeep +0 -0
  112. package/src/writer/file-writer.js +86 -0
  113. package/{content → stacks/blazor-azure}/.azure/README.md +2 -2
  114. package/{content → stacks/blazor-azure}/.azure/pipelines/pipeline-variables.yml +1 -1
  115. package/{content → stacks/blazor-azure}/.azure/pipelines/prod-pipeline.yml +1 -1
  116. package/{content → stacks/blazor-azure}/.azure/pipelines/staging-pipeline.yml +1 -1
  117. package/{content → stacks/blazor-azure}/.claude/commands/morph-preflight.md +227 -227
  118. package/{content → stacks/blazor-azure}/.claude/commands/morph-troubleshoot.md +122 -122
  119. package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-setup.md +1 -1
  120. package/{content → stacks/blazor-azure}/.morph/docs/workflows/enforcement-pipeline.md +3 -3
  121. package/{content → stacks/blazor-azure}/.morph/hooks/README.md +12 -12
  122. package/{content → stacks/blazor-azure}/.morph/standards/agent-teams-workflow.md +2 -2
  123. package/{content → stacks/blazor-azure}/.morph/standards/migration-guide.md +2 -2
  124. package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy-checklist.md +426 -426
  125. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +244 -0
  126. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +335 -0
  127. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +189 -0
  128. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +170 -0
  129. package/stacks/nextjs-supabase/.morph/config/agents.json +345 -0
  130. package/stacks/nextjs-supabase/.morph/config/config.template.json +92 -0
  131. package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +169 -0
  132. package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +247 -0
  133. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +697 -0
  134. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +85 -0
  135. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +86 -0
  136. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +498 -0
  137. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +121 -0
  138. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +138 -0
  139. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +162 -0
  140. package/stacks/nextjs-supabase/.morph/project.md +168 -0
  141. package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +191 -0
  142. package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +193 -0
  143. package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +171 -0
  144. package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +164 -0
  145. package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +179 -0
  146. package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +148 -0
  147. package/stacks/nextjs-supabase/.morph/templates/contracts.cs +173 -0
  148. package/stacks/nextjs-supabase/.morph/templates/contracts.ts +168 -0
  149. package/stacks/nextjs-supabase/.morph/templates/decisions.md +115 -0
  150. package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +38 -0
  151. package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +48 -0
  152. package/stacks/nextjs-supabase/.morph/templates/proposal.md +145 -0
  153. package/stacks/nextjs-supabase/.morph/templates/recap.md +134 -0
  154. package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +57 -0
  155. package/stacks/nextjs-supabase/.morph/templates/spec.md +231 -0
  156. package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +100 -0
  157. package/stacks/nextjs-supabase/.morph/templates/tasks.md +257 -0
  158. package/stacks/nextjs-supabase/CLAUDE.md +149 -0
  159. package/stacks/nextjs-supabase/README.md +112 -0
  160. /package/{content → stacks/blazor-azure}/.azure/docs/azure-devops-setup.md +0 -0
  161. /package/{content → stacks/blazor-azure}/.azure/docs/branch-strategy.md +0 -0
  162. /package/{content → stacks/blazor-azure}/.azure/docs/local-development.md +0 -0
  163. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/build-dotnet.yml +0 -0
  164. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-app-service.yml +0 -0
  165. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/deploy-container-app.yml +0 -0
  166. /package/{content → stacks/blazor-azure}/.azure/pipelines/templates/infra-deploy.yml +0 -0
  167. /package/{content → stacks/blazor-azure}/.claude/commands/morph-apply.md +0 -0
  168. /package/{content → stacks/blazor-azure}/.claude/commands/morph-archive.md +0 -0
  169. /package/{content → stacks/blazor-azure}/.claude/commands/morph-deploy.md +0 -0
  170. /package/{content → stacks/blazor-azure}/.claude/commands/morph-infra.md +0 -0
  171. /package/{content → stacks/blazor-azure}/.claude/commands/morph-proposal.md +0 -0
  172. /package/{content → stacks/blazor-azure}/.claude/commands/morph-status.md +0 -0
  173. /package/{content → stacks/blazor-azure}/.claude/settings.local.json +0 -0
  174. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/README.md +0 -0
  175. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/code-review.md +0 -0
  176. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/morph-checklist.md +0 -0
  177. /package/{content → stacks/blazor-azure}/.claude/skills/level-0-meta/simulation-checklist.md +0 -0
  178. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/README.md +0 -0
  179. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/morph-replicate.md +0 -0
  180. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-clarify.md +0 -0
  181. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-design.md +0 -0
  182. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-tasks.md +0 -0
  183. /package/{content → stacks/blazor-azure}/.claude/skills/level-1-workflows/phase-uiux.md +0 -0
  184. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/README.md +0 -0
  185. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -0
  186. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -0
  187. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/prompt-engineer.md +0 -0
  188. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/seo-growth-hacker.md +0 -0
  189. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -0
  190. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -0
  191. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -0
  192. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -0
  193. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -0
  194. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -0
  195. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -0
  196. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -0
  197. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -0
  198. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +0 -0
  199. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -0
  200. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -0
  201. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -0
  202. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -0
  203. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -0
  204. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -0
  205. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/integrations/resend-email.md +0 -0
  206. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -0
  207. /package/{content → stacks/blazor-azure}/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -0
  208. /package/{content → stacks/blazor-azure}/.claude/skills/level-3-technologies/README.md +0 -0
  209. /package/{content → stacks/blazor-azure}/.claude/skills/level-4-patterns/README.md +0 -0
  210. /package/{content → stacks/blazor-azure}/.morph/.morphversion +0 -0
  211. /package/{content → stacks/blazor-azure}/.morph/archive/.gitkeep +0 -0
  212. /package/{content → stacks/blazor-azure}/.morph/config/agents.json +0 -0
  213. /package/{content → stacks/blazor-azure}/.morph/config/config.template.json +0 -0
  214. /package/{content → stacks/blazor-azure}/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +0 -0
  215. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/design-impl.md +0 -0
  216. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/fast-track.md +0 -0
  217. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/full-morph.md +0 -0
  218. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/standard.md +0 -0
  219. /package/{content → stacks/blazor-azure}/.morph/docs/workflows/ui-refresh.md +0 -0
  220. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/README.md +0 -0
  221. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/contracts.ts +0 -0
  222. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/spec.md +0 -0
  223. /package/{content → stacks/blazor-azure}/.morph/examples/api-nextjs/tasks.md +0 -0
  224. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/README.md +0 -0
  225. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/contracts.cs +0 -0
  226. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/decisions.md +0 -0
  227. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/spec.md +0 -0
  228. /package/{content → stacks/blazor-azure}/.morph/examples/micro-saas/tasks.md +0 -0
  229. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/README.md +0 -0
  230. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/contracts.cs +0 -0
  231. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/spec.md +0 -0
  232. /package/{content → stacks/blazor-azure}/.morph/examples/multi-agent/tasks.md +0 -0
  233. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/decisions.md +0 -0
  234. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/proposal.md +0 -0
  235. /package/{content → stacks/blazor-azure}/.morph/examples/scheduled-reports/spec.md +0 -0
  236. /package/{content → stacks/blazor-azure}/.morph/examples/state-v3.json +0 -0
  237. /package/{content → stacks/blazor-azure}/.morph/features/.gitkeep +0 -0
  238. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-agents.sh +0 -0
  239. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-all.sh +0 -0
  240. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-specs.sh +0 -0
  241. /package/{content → stacks/blazor-azure}/.morph/hooks/pre-commit-tests.sh +0 -0
  242. /package/{content → stacks/blazor-azure}/.morph/hooks/task-completed.js +0 -0
  243. /package/{content → stacks/blazor-azure}/.morph/hooks/teammate-idle.js +0 -0
  244. /package/{content → stacks/blazor-azure}/.morph/project.md +0 -0
  245. /package/{content → stacks/blazor-azure}/.morph/schemas/agent.schema.json +0 -0
  246. /package/{content → stacks/blazor-azure}/.morph/schemas/tasks.schema.json +0 -0
  247. /package/{content → stacks/blazor-azure}/.morph/specs/.gitkeep +0 -0
  248. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-blazor-ui.md +0 -0
  249. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-production.md +0 -0
  250. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-setup.md +0 -0
  251. /package/{content → stacks/blazor-azure}/.morph/standards/agent-framework-workflows.md +0 -0
  252. /package/{content → stacks/blazor-azure}/.morph/standards/architecture.md +0 -0
  253. /package/{content → stacks/blazor-azure}/.morph/standards/azure.md +0 -0
  254. /package/{content → stacks/blazor-azure}/.morph/standards/coding.md +0 -0
  255. /package/{content → stacks/blazor-azure}/.morph/standards/dotnet10-migration.md +0 -0
  256. /package/{content → stacks/blazor-azure}/.morph/standards/fluent-ui-setup.md +0 -0
  257. /package/{content → stacks/blazor-azure}/.morph/standards/passkeys-auth.md +0 -0
  258. /package/{content → stacks/blazor-azure}/.morph/standards/vector-search-rag.md +0 -0
  259. /package/{content → stacks/blazor-azure}/.morph/state.json +0 -0
  260. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT-FEATURE.md +0 -0
  261. /package/{content → stacks/blazor-azure}/.morph/templates/CONTEXT.md +0 -0
  262. /package/{content → stacks/blazor-azure}/.morph/templates/FluentDesignTheme.cs +0 -0
  263. /package/{content → stacks/blazor-azure}/.morph/templates/MudTheme.cs +0 -0
  264. /package/{content → stacks/blazor-azure}/.morph/templates/agent.cs +0 -0
  265. /package/{content → stacks/blazor-azure}/.morph/templates/clarify-questions.md +0 -0
  266. /package/{content → stacks/blazor-azure}/.morph/templates/component.razor +0 -0
  267. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Commands.cs +0 -0
  268. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Entities.cs +0 -0
  269. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/Queries.cs +0 -0
  270. /package/{content → stacks/blazor-azure}/.morph/templates/contracts/README.md +0 -0
  271. /package/{content → stacks/blazor-azure}/.morph/templates/contracts.cs +0 -0
  272. /package/{content → stacks/blazor-azure}/.morph/templates/decisions.md +0 -0
  273. /package/{content → stacks/blazor-azure}/.morph/templates/design-system.css +0 -0
  274. /package/{content → stacks/blazor-azure}/.morph/templates/infra/.dockerignore.example +0 -0
  275. /package/{content → stacks/blazor-azure}/.morph/templates/infra/Dockerfile.example +0 -0
  276. /package/{content → stacks/blazor-azure}/.morph/templates/infra/README.md +0 -0
  277. /package/{content → stacks/blazor-azure}/.morph/templates/infra/app-insights.bicep +0 -0
  278. /package/{content → stacks/blazor-azure}/.morph/templates/infra/app-service.bicep +0 -0
  279. /package/{content → stacks/blazor-azure}/.morph/templates/infra/azure-pipelines-deploy.yml +0 -0
  280. /package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app-env.bicep +0 -0
  281. /package/{content → stacks/blazor-azure}/.morph/templates/infra/container-app.bicep +0 -0
  282. /package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.ps1 +0 -0
  283. /package/{content → stacks/blazor-azure}/.morph/templates/infra/deploy.sh +0 -0
  284. /package/{content → stacks/blazor-azure}/.morph/templates/infra/key-vault.bicep +0 -0
  285. /package/{content → stacks/blazor-azure}/.morph/templates/infra/main.bicep +0 -0
  286. /package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.dev.json +0 -0
  287. /package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.prod.json +0 -0
  288. /package/{content → stacks/blazor-azure}/.morph/templates/infra/parameters.staging.json +0 -0
  289. /package/{content → stacks/blazor-azure}/.morph/templates/infra/sql-database.bicep +0 -0
  290. /package/{content → stacks/blazor-azure}/.morph/templates/infra/storage.bicep +0 -0
  291. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-client.cs +0 -0
  292. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/asaas-webhook.cs +0 -0
  293. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/azure-identity-config.cs +0 -0
  294. /package/{content → stacks/blazor-azure}/.morph/templates/integrations/clerk-config.cs +0 -0
  295. /package/{content → stacks/blazor-azure}/.morph/templates/job.cs +0 -0
  296. /package/{content → stacks/blazor-azure}/.morph/templates/migration.cs +0 -0
  297. /package/{content → stacks/blazor-azure}/.morph/templates/proposal.md +0 -0
  298. /package/{content → stacks/blazor-azure}/.morph/templates/recap.md +0 -0
  299. /package/{content → stacks/blazor-azure}/.morph/templates/repository.cs +0 -0
  300. /package/{content → stacks/blazor-azure}/.morph/templates/saas/subscription.cs +0 -0
  301. /package/{content → stacks/blazor-azure}/.morph/templates/saas/tenant.cs +0 -0
  302. /package/{content → stacks/blazor-azure}/.morph/templates/service.cs +0 -0
  303. /package/{content → stacks/blazor-azure}/.morph/templates/simulation.md +0 -0
  304. /package/{content → stacks/blazor-azure}/.morph/templates/spec.md +0 -0
  305. /package/{content → stacks/blazor-azure}/.morph/templates/sprint-status.yaml +0 -0
  306. /package/{content → stacks/blazor-azure}/.morph/templates/state.template.json +0 -0
  307. /package/{content → stacks/blazor-azure}/.morph/templates/story.md +0 -0
  308. /package/{content → stacks/blazor-azure}/.morph/templates/tasks.md +0 -0
  309. /package/{content → stacks/blazor-azure}/.morph/templates/test.cs +0 -0
  310. /package/{content → stacks/blazor-azure}/.morph/templates/ui-components.md +0 -0
  311. /package/{content → stacks/blazor-azure}/.morph/templates/ui-design-system.md +0 -0
  312. /package/{content → stacks/blazor-azure}/.morph/templates/ui-flows.md +0 -0
  313. /package/{content → stacks/blazor-azure}/.morph/templates/ui-mockups.md +0 -0
  314. /package/{content → stacks/blazor-azure}/.morph/test-infra/example.bicep +0 -0
  315. /package/{content → stacks/blazor-azure}/CLAUDE.md +0 -0
  316. /package/{content → stacks/blazor-azure}/README.md +0 -0
@@ -15,9 +15,11 @@
15
15
  import { readFileSync } from 'fs';
16
16
  import { join, dirname } from 'path';
17
17
  import { fileURLToPath } from 'url';
18
+ import { resolveAgentsConfigPath } from '../src/lib/stack-resolver.js';
18
19
 
19
20
  const __dirname = dirname(fileURLToPath(import.meta.url));
20
- const AGENTS_CONFIG_PATH = join(__dirname, '../content/.morph/config/agents.json');
21
+ const frameworkRoot = join(__dirname, '..');
22
+ const AGENTS_CONFIG_PATH = resolveAgentsConfigPath(frameworkRoot);
21
23
 
22
24
  // Cores para output no terminal
23
25
  const colors = {
package/bin/morph-spec.js CHANGED
@@ -1,10 +1,11 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { program } from 'commander';
4
4
  import chalk from 'chalk';
5
5
  import { fileURLToPath } from 'url';
6
6
  import { dirname, join } from 'path';
7
7
  import { readFileSync } from 'fs';
8
+ import { setGlobalStack } from '../src/lib/stack-resolver.js';
8
9
 
9
10
  import { initCommand } from '../src/commands/init.js';
10
11
  import { updateCommand } from '../src/commands/update.js';
@@ -31,6 +32,13 @@ import { validatePhaseCommand } from '../src/commands/validate-phase.js';
31
32
  import { sessionSummaryCommand } from '../src/commands/session-summary.js';
32
33
  import { rollbackPhaseCommand } from '../src/commands/rollback-phase.js';
33
34
  import { advancePhaseCommand } from '../src/commands/advance-phase.js';
35
+ import { approveCommand, rejectCommand, approvalStatusCommand } from '../src/commands/approve.js';
36
+ import { spawnTeamCommand } from '../src/commands/spawn-team.js';
37
+ import capturePatternProgram from '../src/commands/capture-pattern.js';
38
+ import searchPatternsProgram from '../src/commands/search-patterns.js';
39
+ import { generateMetadataCommand } from '../src/commands/generate.js';
40
+ import migrateStateProgram from '../src/commands/migrate-state.js';
41
+ import upgradeProgram from '../src/commands/upgrade.js';
34
42
 
35
43
  const __dirname = dirname(fileURLToPath(import.meta.url));
36
44
  const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
@@ -51,6 +59,7 @@ program
51
59
  .name('morph-spec')
52
60
  .description('MORPH-SPEC Framework CLI')
53
61
  .version(pkg.version)
62
+ .option('--stack <stack>', 'Override stack detection (blazor-azure | nextjs-supabase)')
54
63
  .addHelpText('beforeAll', banner);
55
64
 
56
65
  program
@@ -187,6 +196,13 @@ generateCommand
187
196
  await generateContextCommand('.', feature);
188
197
  });
189
198
 
199
+ generateCommand
200
+ .command('metadata <feature>')
201
+ .description('Generate metadata.json summary from markdown outputs')
202
+ .option('--output <path>', 'Custom output path')
203
+ .option('--verbose', 'Show detailed extraction info')
204
+ .action((feature, options) => generateMetadataCommand(feature, options));
205
+
190
206
  // Validation commands (Sprint 4: Continuous Validation)
191
207
  program
192
208
  .command('validate [validator]')
@@ -363,4 +379,47 @@ program
363
379
  .option('-v, --verbose', 'Show detailed output')
364
380
  .action(rollbackPhaseCommand);
365
381
 
382
+ // Approval workflow commands (MORPH-SPEC 3.0)
383
+ program
384
+ .command('approve <feature> <gate>')
385
+ .description('Approve a phase gate (design, tasks, uiux, proposal)')
386
+ .option('--approver <name>', 'Name of approver (default: current user)')
387
+ .option('--notes <notes>', 'Approval notes')
388
+ .action((feature, gate, options) => approveCommand(feature, gate, options));
389
+
390
+ program
391
+ .command('reject <feature> <gate> [reason]')
392
+ .description('Reject a phase gate with optional reason')
393
+ .action((feature, gate, reason, options) => rejectCommand(feature, gate, reason, options));
394
+
395
+ program
396
+ .command('approval-status <feature>')
397
+ .description('Show approval status for all gates')
398
+ .option('--json', 'Output as JSON')
399
+ .action((feature, options) => approvalStatusCommand(feature, options));
400
+
401
+ // Agent team spawning (MORPH-SPEC 3.0)
402
+ program
403
+ .command('spawn-team <feature>')
404
+ .description('Generate agent team configuration for Task tool')
405
+ .option('--json', 'Output as JSON')
406
+ .option('--verbose', 'Show detailed team configuration')
407
+ .action((feature, options) => spawnTeamCommand(feature, options));
408
+
409
+ // Pattern learning system (MORPH-SPEC 3.0) - Add as subcommands
410
+ program.addCommand(capturePatternProgram);
411
+ program.addCommand(searchPatternsProgram);
412
+
413
+ // Migration and upgrade commands (MORPH-SPEC 3.0) - Add as subcommands
414
+ program.addCommand(migrateStateProgram);
415
+ program.addCommand(upgradeProgram);
416
+
417
+ // Wire global --stack flag to stack-resolver before any command executes
418
+ program.hook('preAction', () => {
419
+ const opts = program.opts();
420
+ if (opts.stack) {
421
+ setGlobalStack(opts.stack);
422
+ }
423
+ });
424
+
366
425
  program.parse();
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * Example:
12
12
  * node bin/render-template.js \
13
- * content/.morph/templates/spec.md \
13
+ * stacks/blazor-azure/.morph/templates/spec.md \
14
14
  * .morph/project/outputs/my-feature/spec.md \
15
15
  * '{"FEATURE_NAME":"my-feature","STACK":"Blazor","DATE":"2024-01-15"}'
16
16
  */
@@ -18,6 +18,8 @@
18
18
  import fs from 'fs';
19
19
  import path from 'path';
20
20
  import { fileURLToPath } from 'url';
21
+ import { resolveConfigDir } from '../src/lib/stack-resolver.js';
22
+ import { getAllTemplatePlaceholders } from '../src/lib/template-data-sources.js';
21
23
 
22
24
  const __filename = fileURLToPath(import.meta.url);
23
25
  const __dirname = path.dirname(__filename);
@@ -37,8 +39,8 @@ const colors = {
37
39
  function loadConfig() {
38
40
  const configPaths = [
39
41
  path.join(process.cwd(), '.morph/config/config.json'),
40
- path.join(process.cwd(), 'content/.morph/config/config.json'),
41
- path.join(__dirname, '../content/.morph/config/config.template.json')
42
+ path.join(resolveConfigDir(process.cwd()), 'config.json'),
43
+ path.join(resolveConfigDir(path.join(__dirname, '..')), 'config.template.json')
42
44
  ];
43
45
 
44
46
  for (const configPath of configPaths) {
@@ -110,7 +112,7 @@ function transformCase(str) {
110
112
  /**
111
113
  * Render template by replacing placeholders
112
114
  */
113
- function renderTemplate(templatePath, variables) {
115
+ function renderTemplate(templatePath, variables, mcpData = null) {
114
116
  if (!fs.existsSync(templatePath)) {
115
117
  throw new Error(`Template file not found: ${templatePath}`);
116
118
  }
@@ -120,8 +122,8 @@ function renderTemplate(templatePath, variables) {
120
122
  // Get default variables
121
123
  const defaults = getDefaultVariables();
122
124
 
123
- // Merge with provided variables (provided takes precedence)
124
- const allVariables = { ...defaults, ...variables };
125
+ // Merge: defaults → MCP data → provided variables (rightmost takes precedence)
126
+ const allVariables = { ...defaults, ...(mcpData || {}), ...variables };
125
127
 
126
128
  // Auto-generate case transformations for FEATURE_NAME if provided
127
129
  if (allVariables.FEATURE_NAME) {
@@ -199,14 +201,34 @@ ${colors.green}Standard Placeholders:${colors.reset}
199
201
 
200
202
  ${colors.green}Example:${colors.reset}
201
203
  node bin/render-template.js \\
202
- content/.morph/templates/spec.md \\
204
+ stacks/blazor-azure/.morph/templates/spec.md \\
203
205
  .morph/project/outputs/scheduled-reports/spec.md \\
204
206
  '{"FEATURE_NAME":"scheduled-reports","STACK":"Blazor"}'
205
207
 
206
208
  ${colors.green}Flags:${colors.reset}
207
- --help, -h Show this help message
208
- --verbose, -v Show detailed replacement information
209
- --dry-run, -d Preview output without writing file
209
+ --help, -h Show this help message
210
+ --verbose, -v Show detailed replacement information
211
+ --dry-run, -d Preview output without writing file
212
+ --with-mcp-data Inject dynamic MCP data (project stats, compliance, activity)
213
+
214
+ ${colors.green}MCP Data Placeholders:${colors.reset} (Available with --with-mcp-data flag)
215
+ {{MCP_PROJECT_FILES}} - Total files in project
216
+ {{MCP_TEST_COVERAGE}} - Test coverage percentage (or N/A)
217
+ {{MCP_COMPLIANCE_SCORE}} - Overall compliance score (0-100)
218
+ {{MCP_LAST_FEATURE}} - Name of last feature worked on
219
+ {{MCP_LAST_COMMIT}} - Last git commit message
220
+ {{MCP_LAST_COMMIT_AUTHOR}} - Author of last commit
221
+ {{MCP_LAST_COMMIT_TIME}} - Relative time of last commit
222
+ {{MCP_CS_FILES}} - Number of .cs files
223
+ {{MCP_RAZOR_FILES}} - Number of .razor files
224
+ {{MCP_TS_FILES}} - Number of .ts files
225
+ {{MCP_JS_FILES}} - Number of .js files
226
+ {{MCP_NUGET_PACKAGES}} - Number of NuGet packages
227
+ {{MCP_NPM_PACKAGES}} - Number of npm packages
228
+ {{MCP_ARCHITECTURE_VIOLATIONS}} - Architecture validator errors
229
+ {{MCP_PACKAGE_CONFLICTS}} - Package conflict count
230
+ {{MCP_SECURITY_ISSUES}} - Security validator issues
231
+ {{MCP_RECENT_BRANCHES}} - Recent git branches (up to 3)
210
232
 
211
233
  ${colors.yellow}Note:${colors.reset} DATE, YEAR, AUTHOR, PROJECT_NAME, STACK, NAMESPACE are auto-populated from config.json
212
234
  `);
@@ -215,7 +237,7 @@ ${colors.yellow}Note:${colors.reset} DATE, YEAR, AUTHOR, PROJECT_NAME, STACK, NA
215
237
  /**
216
238
  * Main CLI logic
217
239
  */
218
- function main() {
240
+ async function main() {
219
241
  const args = process.argv.slice(2);
220
242
 
221
243
  // Check for help flag
@@ -227,9 +249,10 @@ function main() {
227
249
  // Parse flags
228
250
  const verbose = args.includes('--verbose') || args.includes('-v');
229
251
  const dryRun = args.includes('--dry-run') || args.includes('-d');
252
+ const withMcpData = args.includes('--with-mcp-data');
230
253
 
231
254
  // Filter out flags
232
- const flags = ['--verbose', '-v', '--dry-run', '-d', '--help', '-h'];
255
+ const flags = ['--verbose', '-v', '--dry-run', '-d', '--help', '-h', '--with-mcp-data'];
233
256
  const cleanArgs = args.filter(arg => !flags.includes(arg));
234
257
 
235
258
  // Validate arguments
@@ -252,10 +275,31 @@ function main() {
252
275
  }
253
276
 
254
277
  try {
278
+ // Get MCP data if requested
279
+ let mcpData = null;
280
+ if (withMcpData) {
281
+ try {
282
+ console.log(`${colors.cyan}šŸ” Gathering MCP data from project...${colors.reset}`);
283
+ mcpData = await getAllTemplatePlaceholders(process.cwd());
284
+
285
+ if (verbose) {
286
+ console.log(`${colors.green}āœ… MCP data loaded:${colors.reset}`);
287
+ console.log(` Files: ${mcpData.MCP_PROJECT_FILES}`);
288
+ console.log(` Coverage: ${mcpData.MCP_TEST_COVERAGE}`);
289
+ console.log(` Compliance: ${mcpData.MCP_COMPLIANCE_SCORE}%`);
290
+ console.log(` Last Feature: ${mcpData.MCP_LAST_FEATURE}\n`);
291
+ }
292
+ } catch (error) {
293
+ console.error(`${colors.yellow}āš ļø Warning: Failed to load MCP data - ${error.message}${colors.reset}`);
294
+ console.error(` Continuing with standard placeholders only...\n`);
295
+ }
296
+ }
297
+
255
298
  // Render template
256
299
  const { content, replacedPlaceholders, unreplacedPlaceholders } = renderTemplate(
257
300
  templatePath,
258
- variables
301
+ variables,
302
+ mcpData
259
303
  );
260
304
 
261
305
  // Dry run: just preview
@@ -299,4 +343,7 @@ function main() {
299
343
  }
300
344
 
301
345
  // Run CLI
302
- main();
346
+ main().catch(error => {
347
+ console.error(`${colors.red}āŒ Fatal error: ${error.message}${colors.reset}`);
348
+ process.exit(1);
349
+ });
@@ -17,6 +17,7 @@ import fs from 'fs';
17
17
  import path from 'path';
18
18
  import { fileURLToPath } from 'url';
19
19
  import { execSync } from 'child_process';
20
+ import { resolveAgentsConfigPath } from '../src/lib/stack-resolver.js';
20
21
 
21
22
  const __filename = fileURLToPath(import.meta.url);
22
23
  const __dirname = path.dirname(__filename);
@@ -121,7 +122,7 @@ function keywordBasedDetection(userRequest) {
121
122
  * Load agent descriptions for LLM context
122
123
  */
123
124
  function loadAgentDescriptions() {
124
- const agentsPath = path.join(process.cwd(), 'content/.morph/config/agents.json');
125
+ const agentsPath = resolveAgentsConfigPath(process.cwd());
125
126
 
126
127
  if (!fs.existsSync(agentsPath)) {
127
128
  throw new Error('agents.json not found');
@@ -9,7 +9,18 @@
9
9
 
10
10
  const fs = require('fs').promises;
11
11
  const path = require('path');
12
- const chalk = require('chalk');
12
+
13
+ // Simple ANSI color helpers (chalk v5 is ESM-only, can't require in CJS)
14
+ const chalk = {
15
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
16
+ green: (s) => `\x1b[32m${s}\x1b[0m`,
17
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
18
+ blue: (s) => `\x1b[34m${s}\x1b[0m`,
19
+ magenta: (s) => `\x1b[35m${s}\x1b[0m`,
20
+ cyan: (s) => `\x1b[36m${s}\x1b[0m`,
21
+ gray: (s) => `\x1b[90m${s}\x1b[0m`,
22
+ bold: (s) => `\x1b[1m${s}\x1b[0m`,
23
+ };
13
24
 
14
25
  class TaskManager {
15
26
  constructor(statePath = '.morph/state.json') {
@@ -127,6 +138,9 @@ class TaskManager {
127
138
  // Save state
128
139
  await this.saveState(state);
129
140
 
141
+ // Auto-generate metadata.json (for quick LLM access)
142
+ await this.generateMetadata(featureName, feature);
143
+
130
144
  // Display progress
131
145
  this.displayProgress(feature);
132
146
 
@@ -219,10 +233,40 @@ class TaskManager {
219
233
  * Auto-checkpoint every 3 tasks (includes validation summary)
220
234
  */
221
235
  async autoCheckpoint(feature, tasks, featureName) {
236
+ const tasksCompleted = feature.tasks?.completed || tasks.length;
237
+ const checkpointNum = Math.floor(tasksCompleted / 3);
238
+
239
+ console.log(chalk.magenta(`\nšŸ” CHECKPOINT ${checkpointNum} - Running automated validation...`));
240
+
241
+ let checkpointResult = null;
222
242
  let validationNote = '';
223
243
 
224
- // Run validation and include summary in checkpoint
225
- if (featureName) {
244
+ // Run checkpoint hooks (new enhanced validation system)
245
+ try {
246
+ const { runCheckpointHooks, shouldRunCheckpoint } = await import('../src/lib/checkpoint-hooks.js');
247
+
248
+ if (shouldRunCheckpoint(tasksCompleted, 3)) {
249
+ checkpointResult = await runCheckpointHooks(featureName, checkpointNum);
250
+
251
+ if (checkpointResult.passed) {
252
+ validationNote = ' | āœ“ All validations passed';
253
+ } else {
254
+ validationNote = ` | āœ— ${checkpointResult.summary.errors} errors, ${checkpointResult.summary.warnings} warnings`;
255
+
256
+ // Check if we should block progress
257
+ const config = await this.loadCheckpointConfig();
258
+ if (config.checkpoints?.onFailure?.blockProgress && checkpointResult.summary.errors > 0) {
259
+ console.log(chalk.red('\nāŒ Checkpoint FAILED - Fix violations before proceeding'));
260
+ throw new Error('Checkpoint validation failed');
261
+ }
262
+ }
263
+ }
264
+ } catch (error) {
265
+ if (error.message === 'Checkpoint validation failed') {
266
+ throw error; // Re-throw to block task completion
267
+ }
268
+ // Fallback to old validation if checkpoint-hooks not available
269
+ console.log(chalk.yellow('āš ļø Checkpoint hooks not available, using legacy validation'));
226
270
  try {
227
271
  const { runValidation } = await import('../src/lib/validation-runner.js');
228
272
  const result = await runValidation('.', featureName, { verbose: false });
@@ -230,23 +274,84 @@ class TaskManager {
230
274
  ? ' | Validation: PASSED'
231
275
  : ` | Validation: ${result.errors.length} errors, ${result.warnings.length} warnings`;
232
276
  } catch {
233
- // Validation not available, skip
277
+ // No validation available
234
278
  }
235
279
  }
236
280
 
281
+ // Create checkpoint record
237
282
  const checkpoint = {
238
283
  id: `CHECKPOINT_AUTO_${Date.now()}`,
239
284
  timestamp: new Date().toISOString(),
240
285
  tasksCompleted: tasks.map(t => t.id),
241
- note: `Auto-checkpoint: ${tasks.length} tasks completed${validationNote}`
286
+ note: `Auto-checkpoint: ${tasks.length} tasks completed${validationNote}`,
287
+ validationResults: checkpointResult?.results || null
242
288
  };
243
289
 
244
290
  feature.checkpoints = feature.checkpoints || [];
245
291
  feature.checkpoints.push(checkpoint);
246
292
 
247
- console.log(chalk.magenta(`\nšŸŽ‰ Auto-checkpoint reached! ${tasks.length} tasks completed`));
248
- if (validationNote) {
249
- console.log(chalk.gray(` ${validationNote.trim().replace(/^ \| /, '')}`));
293
+ if (checkpointResult?.passed) {
294
+ console.log(chalk.green(`\nāœ… Checkpoint ${checkpointNum} PASSED`));
295
+ } else if (checkpointResult) {
296
+ console.log(chalk.yellow(`\nāš ļø Checkpoint ${checkpointNum} completed with warnings`));
297
+ } else {
298
+ console.log(chalk.magenta(`\nšŸŽ‰ Auto-checkpoint ${checkpointNum} reached!`));
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Load checkpoint configuration from llm-interaction.json
304
+ */
305
+ async loadCheckpointConfig() {
306
+ try {
307
+ const configPath = path.join(process.cwd(), '.morph/config/llm-interaction.json');
308
+ const content = await fs.readFile(configPath, 'utf-8');
309
+ return JSON.parse(content);
310
+ } catch {
311
+ // Return defaults if config doesn't exist
312
+ return {
313
+ checkpoints: {
314
+ frequency: 3,
315
+ autoValidate: true,
316
+ onFailure: {
317
+ blockProgress: false
318
+ }
319
+ }
320
+ };
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Auto-generate metadata.json after task completion
326
+ */
327
+ async generateMetadata(featureName, feature) {
328
+ try {
329
+ const config = await this.loadCheckpointConfig();
330
+
331
+ // Check if auto-generation is enabled
332
+ if (!config.metadata?.autoGenerate) {
333
+ return;
334
+ }
335
+
336
+ const { extractFeatureMetadata } = await import('../src/lib/metadata-extractor.js');
337
+ const metadata = extractFeatureMetadata(feature);
338
+
339
+ const outputPath = path.join(
340
+ process.cwd(),
341
+ `.morph/project/outputs/${featureName}/metadata.json`
342
+ );
343
+
344
+ // Ensure directory exists
345
+ const outputDir = path.dirname(outputPath);
346
+ await fs.mkdir(outputDir, { recursive: true });
347
+
348
+ // Write metadata
349
+ await fs.writeFile(outputPath, JSON.stringify(metadata, null, 2), 'utf-8');
350
+
351
+ console.log(chalk.gray(` šŸ“Š Metadata updated: ${path.relative(process.cwd(), outputPath)}`));
352
+ } catch (error) {
353
+ // Don't block task completion if metadata generation fails
354
+ console.log(chalk.yellow(` āš ļø Metadata generation failed: ${error.message}`));
250
355
  }
251
356
  }
252
357
 
@@ -14,10 +14,12 @@
14
14
  import { readFileSync, existsSync, readdirSync, statSync } from 'fs';
15
15
  import { join, dirname } from 'path';
16
16
  import { fileURLToPath } from 'url';
17
+ import { resolveAgentsConfigPath, resolveStackPath } from '../src/lib/stack-resolver.js';
17
18
 
18
19
  const __dirname = dirname(fileURLToPath(import.meta.url));
19
- const AGENTS_CONFIG_PATH = join(__dirname, '../content/.morph/config/agents.json');
20
- const SKILLS_BASE_PATH = join(__dirname, '../content/.claude/skills');
20
+ const frameworkRoot = join(__dirname, '..');
21
+ const AGENTS_CONFIG_PATH = resolveAgentsConfigPath(frameworkRoot);
22
+ const SKILLS_BASE_PATH = join(resolveStackPath(frameworkRoot), '.claude/skills');
21
23
 
22
24
  // Cores para output
23
25
  const colors = {
@@ -60,8 +62,12 @@ function getAllSkillFiles(dir, fileList = []) {
60
62
  if (stat.isDirectory()) {
61
63
  getAllSkillFiles(filePath, fileList);
62
64
  } else if (file.endsWith('.md')) {
63
- // Converter para path relativo ao content/
64
- const relativePath = filePath.replace(/\\/g, '/').split('/content/')[1];
65
+ // Converter para path relativo ao stacks/blazor-azure/
66
+ const stackPath = resolveStackPath(frameworkRoot).replace(/\\/g, '/');
67
+ const normalizedFile = filePath.replace(/\\/g, '/');
68
+ const relativePath = normalizedFile.startsWith(stackPath)
69
+ ? normalizedFile.slice(stackPath.length + 1)
70
+ : normalizedFile;
65
71
  fileList.push(relativePath);
66
72
  }
67
73
  });
@@ -4,21 +4,22 @@ import path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import Ajv from 'ajv';
6
6
  import addFormats from 'ajv-formats';
7
+ import { resolveAgentsConfigPath, resolveStackPath } from '../src/lib/stack-resolver.js';
7
8
 
8
9
  const __filename = fileURLToPath(import.meta.url);
9
10
  const __dirname = path.dirname(__filename);
10
11
 
11
12
  function main() {
12
13
  const args = process.argv.slice(2);
13
-
14
+
14
15
  if (args.includes('--help') || args.includes('-h')) {
15
16
  console.log('Usage: node bin/validate-agents.js [agents-file-path]');
16
17
  process.exit(0);
17
18
  }
18
19
 
19
- const defaultPath = path.join(process.cwd(), 'content/.morph/config/agents.json');
20
+ const defaultPath = resolveAgentsConfigPath(process.cwd());
20
21
  const agentsPath = args[0] || defaultPath;
21
- const schemaPath = path.join(__dirname, '../content/.morph/schemas/agent.schema.json');
22
+ const schemaPath = path.join(resolveStackPath(path.join(__dirname, '..')), '.morph/schemas/agent.schema.json');
22
23
 
23
24
  if (!fs.existsSync(agentsPath)) {
24
25
  console.error('Error: agents.json not found at', agentsPath);