@polymorphism-tech/morph-spec 4.7.2 → 4.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. package/LICENSE +1 -2
  2. package/README.md +379 -414
  3. package/bin/morph-spec.js +57 -394
  4. package/bin/validate.js +2 -26
  5. package/claude-plugin.json +2 -2
  6. package/docs/CHEATSHEET.md +203 -221
  7. package/docs/QUICKSTART.md +2 -8
  8. package/framework/CLAUDE.md +1 -1
  9. package/framework/commands/morph-proposal.md +3 -3
  10. package/framework/hooks/README.md +2 -5
  11. package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +4 -55
  12. package/framework/hooks/claude-code/session-start/inject-morph-context.js +20 -5
  13. package/framework/hooks/claude-code/statusline.py +6 -1
  14. package/framework/hooks/dev/check-sync-health.js +117 -0
  15. package/framework/hooks/dev/guard-version-numbers.js +57 -0
  16. package/framework/hooks/dev/sync-standards-registry.js +60 -0
  17. package/framework/hooks/dev/sync-template-registry.js +60 -0
  18. package/framework/hooks/dev/validate-skill-format.js +70 -0
  19. package/framework/hooks/dev/validate-standard-format.js +73 -0
  20. package/framework/hooks/shared/payload-utils.js +39 -0
  21. package/framework/hooks/shared/state-reader.js +25 -1
  22. package/framework/rules/morph-workflow.md +1 -1
  23. package/framework/skills/level-0-meta/morph-init/SKILL.md +216 -0
  24. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +4 -4
  25. package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +4 -4
  26. package/framework/skills/level-0-meta/verification-before-completion/SKILL.md +1 -1
  27. package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +192 -191
  28. package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +181 -180
  29. package/framework/skills/level-1-workflows/phase-design/SKILL.md +339 -338
  30. package/framework/skills/level-1-workflows/phase-implement/SKILL.md +254 -253
  31. package/framework/skills/level-1-workflows/phase-setup/SKILL.md +168 -170
  32. package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +284 -283
  33. package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +246 -245
  34. package/framework/templates/examples/design-system-examples.md +1 -1
  35. package/framework/templates/ui/FluentDesignTheme.cs +1 -1
  36. package/framework/templates/ui/MudTheme.cs +1 -1
  37. package/framework/templates/ui/design-system.css +1 -1
  38. package/package.json +7 -5
  39. package/src/commands/agents/index.js +1 -2
  40. package/src/commands/index.js +13 -16
  41. package/src/commands/project/doctor.js +100 -14
  42. package/src/commands/project/index.js +7 -10
  43. package/src/commands/project/init.js +398 -528
  44. package/src/commands/project/install-plugin-cmd.js +28 -0
  45. package/src/commands/project/setup-infra-cmd.js +12 -0
  46. package/src/commands/project/tutorial.js +115 -0
  47. package/src/commands/state/approve.js +213 -221
  48. package/src/commands/state/index.js +0 -1
  49. package/src/commands/state/state.js +337 -365
  50. package/src/commands/templates/index.js +0 -4
  51. package/src/commands/trust/trust.js +1 -93
  52. package/src/commands/utils/index.js +1 -5
  53. package/src/commands/validation/index.js +1 -5
  54. package/src/core/registry/command-registry.js +11 -285
  55. package/src/core/state/state-manager.js +5 -2
  56. package/src/lib/detectors/index.js +81 -87
  57. package/src/lib/detectors/structure-detector.js +275 -273
  58. package/src/lib/generators/recap-generator.js +232 -225
  59. package/src/scripts/global-install.js +34 -0
  60. package/src/scripts/install-plugin.js +126 -0
  61. package/src/scripts/setup-infra.js +203 -0
  62. package/src/utils/agents-installer.js +10 -1
  63. package/src/utils/hooks-installer.js +66 -3
  64. package/.morph/.morphversion +0 -5
  65. package/.morph/analytics/threads-log.jsonl +0 -5
  66. package/.morph/config/config.json +0 -8
  67. package/.morph/framework/agents.json +0 -1815
  68. package/.morph/framework/hooks/README.md +0 -205
  69. package/.morph/framework/hooks/claude-code/notification/approval-reminder.js +0 -54
  70. package/.morph/framework/hooks/claude-code/post-tool-use/dispatch.js +0 -83
  71. package/.morph/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +0 -42
  72. package/.morph/framework/hooks/claude-code/pre-compact/save-morph-context.js +0 -61
  73. package/.morph/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +0 -71
  74. package/.morph/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +0 -58
  75. package/.morph/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +0 -64
  76. package/.morph/framework/hooks/claude-code/session-start/inject-morph-context.js +0 -94
  77. package/.morph/framework/hooks/claude-code/statusline.py +0 -538
  78. package/.morph/framework/hooks/claude-code/statusline.sh +0 -7
  79. package/.morph/framework/hooks/claude-code/stop/validate-completion.js +0 -88
  80. package/.morph/framework/hooks/claude-code/user-prompt/enrich-prompt.js +0 -91
  81. package/.morph/framework/hooks/git/commit-msg/conventional-commits.sh +0 -33
  82. package/.morph/framework/hooks/git/pre-commit/agents.sh +0 -25
  83. package/.morph/framework/hooks/git/pre-commit/orchestrator.sh +0 -64
  84. package/.morph/framework/hooks/git/pre-commit/specs.sh +0 -50
  85. package/.morph/framework/hooks/git/pre-push/run-tests.sh +0 -44
  86. package/.morph/framework/hooks/shared/hook-response.js +0 -45
  87. package/.morph/framework/hooks/shared/phase-utils.js +0 -129
  88. package/.morph/framework/hooks/shared/state-reader.js +0 -138
  89. package/.morph/framework/hooks/shared/stdin-reader.js +0 -26
  90. package/.morph/framework/standards/STANDARDS.json +0 -933
  91. package/.morph/framework/standards/ai-agents/blazor-ui.md +0 -364
  92. package/.morph/framework/standards/ai-agents/production.md +0 -415
  93. package/.morph/framework/standards/ai-agents/setup.md +0 -418
  94. package/.morph/framework/standards/ai-agents/team-orchestration.md +0 -479
  95. package/.morph/framework/standards/ai-agents/workflows.md +0 -354
  96. package/.morph/framework/standards/architecture/ddd/aggregates.md +0 -120
  97. package/.morph/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
  98. package/.morph/framework/standards/architecture/ddd/complexity-levels.md +0 -108
  99. package/.morph/framework/standards/architecture/ddd/entities.md +0 -99
  100. package/.morph/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
  101. package/.morph/framework/standards/architecture/ddd/value-objects.md +0 -124
  102. package/.morph/framework/standards/backend/api/minimal-api.md +0 -494
  103. package/.morph/framework/standards/backend/api/rest.md +0 -492
  104. package/.morph/framework/standards/backend/api/validation.md +0 -88
  105. package/.morph/framework/standards/backend/authentication/passkeys.md +0 -428
  106. package/.morph/framework/standards/backend/database/ef-core.md +0 -199
  107. package/.morph/framework/standards/backend/database/migrations.md +0 -393
  108. package/.morph/framework/standards/backend/database/postgresql/database.md +0 -352
  109. package/.morph/framework/standards/backend/database/repository-patterns.md +0 -528
  110. package/.morph/framework/standards/backend/database/vector-search-rag.md +0 -541
  111. package/.morph/framework/standards/backend/dotnet/async.md +0 -366
  112. package/.morph/framework/standards/backend/dotnet/core.md +0 -117
  113. package/.morph/framework/standards/backend/dotnet/di.md +0 -439
  114. package/.morph/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  115. package/.morph/framework/standards/backend/integrations/asaas/asaas-api.md +0 -216
  116. package/.morph/framework/standards/backend/integrations/clerk/clerk-auth.md +0 -290
  117. package/.morph/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +0 -350
  118. package/.morph/framework/standards/backend/integrations/resend/resend-email.md +0 -385
  119. package/.morph/framework/standards/context/analytics.md +0 -96
  120. package/.morph/framework/standards/context/bundles.md +0 -110
  121. package/.morph/framework/standards/context/priming.md +0 -78
  122. package/.morph/framework/standards/core/architecture.md +0 -185
  123. package/.morph/framework/standards/core/coding.md +0 -214
  124. package/.morph/framework/standards/core/git-branching-strategy.md +0 -403
  125. package/.morph/framework/standards/core/git.md +0 -185
  126. package/.morph/framework/standards/core/testing.md +0 -295
  127. package/.morph/framework/standards/data/nosql/blob-storage.md +0 -102
  128. package/.morph/framework/standards/data/nosql/cache/redis.md +0 -97
  129. package/.morph/framework/standards/data/nosql/cosmos-db.md +0 -118
  130. package/.morph/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  131. package/.morph/framework/standards/data/vector-search/rag-chunking.md +0 -104
  132. package/.morph/framework/standards/frontend/blazor/design-checklist.md +0 -222
  133. package/.morph/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  134. package/.morph/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  135. package/.morph/framework/standards/frontend/blazor/html-conversion.md +0 -184
  136. package/.morph/framework/standards/frontend/blazor/lifecycle.md +0 -195
  137. package/.morph/framework/standards/frontend/blazor/pitfalls.md +0 -198
  138. package/.morph/framework/standards/frontend/blazor/state.md +0 -191
  139. package/.morph/framework/standards/frontend/design-system/animations.md +0 -151
  140. package/.morph/framework/standards/frontend/design-system/naming.md +0 -64
  141. package/.morph/framework/standards/frontend/nextjs/app-router.md +0 -123
  142. package/.morph/framework/standards/frontend/nextjs/components.md +0 -132
  143. package/.morph/framework/standards/frontend/nextjs/data-fetching.md +0 -126
  144. package/.morph/framework/standards/frontend/nextjs/forms.md +0 -128
  145. package/.morph/framework/standards/frontend/nextjs/naming-conventions.md +0 -67
  146. package/.morph/framework/standards/frontend/nextjs/nextjs-patterns.md +0 -215
  147. package/.morph/framework/standards/frontend/nextjs/project-structure.md +0 -102
  148. package/.morph/framework/standards/frontend/nextjs/state-management.md +0 -72
  149. package/.morph/framework/standards/frontend/nextjs/testing.md +0 -111
  150. package/.morph/framework/standards/infrastructure/azure/azure.md +0 -624
  151. package/.morph/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  152. package/.morph/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  153. package/.morph/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  154. package/.morph/framework/standards/infrastructure/azure/services/functions.md +0 -486
  155. package/.morph/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  156. package/.morph/framework/standards/infrastructure/azure/services/storage.md +0 -407
  157. package/.morph/framework/standards/infrastructure/docker/easypanel-deploy.md +0 -196
  158. package/.morph/framework/standards/infrastructure/supabase/mcp-setup.md +0 -252
  159. package/.morph/framework/standards/infrastructure/supabase/supabase-auth.md +0 -176
  160. package/.morph/framework/standards/infrastructure/supabase/supabase-pgvector.md +0 -169
  161. package/.morph/framework/standards/infrastructure/supabase/supabase-rls.md +0 -184
  162. package/.morph/framework/standards/infrastructure/supabase/supabase-storage.md +0 -153
  163. package/.morph/framework/standards/integration/api/graphql.md +0 -91
  164. package/.morph/framework/standards/integration/api/grpc.md +0 -114
  165. package/.morph/framework/standards/integration/api/rest-design.md +0 -95
  166. package/.morph/framework/standards/integration/event-driven/cqrs.md +0 -101
  167. package/.morph/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  168. package/.morph/framework/standards/integration/event-driven/service-bus.md +0 -95
  169. package/.morph/framework/standards/integration/mcp/mcp-tools.md +0 -384
  170. package/.morph/framework/standards/observability/logging.md +0 -131
  171. package/.morph/framework/standards/observability/metrics.md +0 -121
  172. package/.morph/framework/standards/observability/monitoring.md +0 -114
  173. package/.morph/framework/standards/observability/tracing.md +0 -132
  174. package/.morph/framework/standards/workflows/parallel-execution.md +0 -112
  175. package/.morph/framework/standards/workflows/thread-management.md +0 -113
  176. package/.morph/framework/templates/.idea/morph-templates.xml +0 -92
  177. package/.morph/framework/templates/.vscode/morph-templates.code-snippets +0 -186
  178. package/.morph/framework/templates/IDE-SNIPPETS.md +0 -266
  179. package/.morph/framework/templates/README.md +0 -814
  180. package/.morph/framework/templates/REGISTRY.json +0 -1888
  181. package/.morph/framework/templates/code/dotnet/backend/repository.cs +0 -141
  182. package/.morph/framework/templates/code/dotnet/backend/service.cs +0 -139
  183. package/.morph/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  184. package/.morph/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  185. package/.morph/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  186. package/.morph/framework/templates/code/dotnet/contracts/README.md +0 -74
  187. package/.morph/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  188. package/.morph/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
  189. package/.morph/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
  190. package/.morph/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
  191. package/.morph/framework/templates/code/dotnet/database/migration.cs +0 -83
  192. package/.morph/framework/templates/code/dotnet/frontend/component.razor +0 -239
  193. package/.morph/framework/templates/code/dotnet/jobs/agent.cs +0 -163
  194. package/.morph/framework/templates/code/dotnet/jobs/job.cs +0 -171
  195. package/.morph/framework/templates/code/dotnet/test.cs +0 -239
  196. package/.morph/framework/templates/code/sql/rls-policy.sql +0 -57
  197. package/.morph/framework/templates/code/sql/supabase-migration.sql +0 -100
  198. package/.morph/framework/templates/code/sql/supabase-migration.template.sql +0 -113
  199. package/.morph/framework/templates/code/typescript/contracts.ts +0 -168
  200. package/.morph/framework/templates/context/CONTEXT-FEATURE.md +0 -276
  201. package/.morph/framework/templates/context/CONTEXT.md +0 -181
  202. package/.morph/framework/templates/docs/clarifications.md +0 -253
  203. package/.morph/framework/templates/docs/onboarding.md +0 -123
  204. package/.morph/framework/templates/docs/proposal.md +0 -182
  205. package/.morph/framework/templates/docs/schema-analysis.md +0 -119
  206. package/.morph/framework/templates/docs/spec.md +0 -198
  207. package/.morph/framework/templates/docs/ui-components.md +0 -124
  208. package/.morph/framework/templates/docs/ui-design-system.md +0 -76
  209. package/.morph/framework/templates/docs/ui-flows.md +0 -167
  210. package/.morph/framework/templates/docs/ui-mockups.md +0 -98
  211. package/.morph/framework/templates/docs/user-stories.md +0 -34
  212. package/.morph/framework/templates/examples/design-system-examples.md +0 -357
  213. package/.morph/framework/templates/examples/spec-examples.md +0 -90
  214. package/.morph/framework/templates/feature/decisions.md +0 -187
  215. package/.morph/framework/templates/feature/recap.md +0 -146
  216. package/.morph/framework/templates/feature/tasks.md +0 -199
  217. package/.morph/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +0 -43
  218. package/.morph/framework/templates/frontend/nextjs/client-component.tsx.hbs +0 -26
  219. package/.morph/framework/templates/frontend/nextjs/env.mjs.hbs +0 -32
  220. package/.morph/framework/templates/frontend/nextjs/feature-form.tsx.hbs +0 -56
  221. package/.morph/framework/templates/frontend/nextjs/page.tsx.hbs +0 -22
  222. package/.morph/framework/templates/frontend/nextjs/tsconfig.json.hbs +0 -26
  223. package/.morph/framework/templates/frontend/nextjs/use-feature.ts.hbs +0 -54
  224. package/.morph/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  225. package/.morph/framework/templates/infrastructure/azure/README.md +0 -286
  226. package/.morph/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  227. package/.morph/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  228. package/.morph/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  229. package/.morph/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  230. package/.morph/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  231. package/.morph/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  232. package/.morph/framework/templates/infrastructure/azure/deploy.sh +0 -208
  233. package/.morph/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  234. package/.morph/framework/templates/infrastructure/azure/main.bicep +0 -189
  235. package/.morph/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  236. package/.morph/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  237. package/.morph/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  238. package/.morph/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  239. package/.morph/framework/templates/infrastructure/azure/storage.bicep +0 -106
  240. package/.morph/framework/templates/infrastructure/docker/Dockerfile.template +0 -58
  241. package/.morph/framework/templates/infrastructure/docker/docker-compose.template.yml +0 -67
  242. package/.morph/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +0 -38
  243. package/.morph/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +0 -48
  244. package/.morph/framework/templates/infrastructure/docker/easypanel.template.json +0 -54
  245. package/.morph/framework/templates/infrastructure/github/README.md +0 -593
  246. package/.morph/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  247. package/.morph/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -45
  248. package/.morph/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +0 -27
  249. package/.morph/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  250. package/.morph/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -31
  251. package/.morph/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -59
  252. package/.morph/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -39
  253. package/.morph/framework/templates/integrations/asaas-client.cs +0 -387
  254. package/.morph/framework/templates/integrations/asaas-webhook.cs +0 -351
  255. package/.morph/framework/templates/integrations/azure-identity-config.cs +0 -288
  256. package/.morph/framework/templates/integrations/clerk-config.cs +0 -258
  257. package/.morph/framework/templates/meta-prompts/fusion/fusion-agent.md +0 -76
  258. package/.morph/framework/templates/meta-prompts/fusion/fusion-aggregator.md +0 -100
  259. package/.morph/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
  260. package/.morph/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
  261. package/.morph/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
  262. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
  263. package/.morph/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
  264. package/.morph/framework/templates/meta-prompts/squad-leaders/backend-squad.md +0 -90
  265. package/.morph/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +0 -126
  266. package/.morph/framework/templates/meta-prompts/squad-leaders/squad-leader.md +0 -43
  267. package/.morph/framework/templates/meta-prompts/validators/checkpoint-validator.md +0 -107
  268. package/.morph/framework/templates/meta-prompts/validators/pre-commit-validator.md +0 -95
  269. package/.morph/framework/templates/project-structure/dotnet-ddd.md +0 -70
  270. package/.morph/framework/templates/saas/subscription.cs +0 -347
  271. package/.morph/framework/templates/saas/tenant.cs +0 -338
  272. package/.morph/framework/templates/state.template.json +0 -17
  273. package/.morph/framework/templates/ui/FluentDesignTheme.cs +0 -149
  274. package/.morph/framework/templates/ui/MudTheme.cs +0 -281
  275. package/.morph/framework/templates/ui/design-system.css +0 -226
  276. package/.morph/logs/tool-failures.log +0 -17
  277. package/.morph/memory/pre-compact-2026-02-24T17-43-30-049Z.json +0 -16
  278. package/.morph/plans/eager-watching-bunny.md +0 -105
  279. package/.morph/plans/temporal-seeking-nebula.md +0 -45
  280. package/.morph/state.json +0 -48
  281. package/CLAUDE.md +0 -77
  282. package/docs/ARCHITECTURE.md +0 -331
  283. package/docs/COMMAND-FLOWS.md +0 -368
  284. package/docs/claude-alignment-report.md +0 -137
  285. package/docs/examples/order-management/contracts.cs +0 -84
  286. package/docs/examples/order-management/proposal.md +0 -24
  287. package/docs/examples/order-management/spec.md +0 -162
  288. package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +0 -512
  289. package/docs/plans/2026-02-22-claude-settings.md +0 -515
  290. package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +0 -728
  291. package/docs/plans/2026-02-22-morph-spec-next.md +0 -478
  292. package/docs/plans/2026-02-22-native-alignment-design.md +0 -199
  293. package/docs/plans/2026-02-22-native-alignment-impl.md +0 -925
  294. package/docs/plans/2026-02-22-native-enrichment-design.md +0 -244
  295. package/docs/plans/2026-02-22-native-enrichment.md +0 -735
  296. package/docs/plans/2026-02-23-ddd-architecture-refactor.md +0 -1153
  297. package/docs/plans/2026-02-23-ddd-nextsteps.md +0 -682
  298. package/docs/plans/2026-02-23-infra-architect-refactor.md +0 -437
  299. package/docs/plans/2026-02-23-nextjs-code-review-design.md +0 -156
  300. package/docs/plans/2026-02-23-nextjs-code-review-impl.md +0 -1254
  301. package/docs/plans/2026-02-23-nextjs-standards-design.md +0 -149
  302. package/docs/plans/2026-02-23-nextjs-standards-impl.md +0 -1846
  303. package/scripts/generate-refs.js +0 -336
  304. package/scripts/generate-standards-registry.js +0 -44
  305. package/scripts/scan-nextjs.mjs +0 -169
  306. package/scripts/validate-real.mjs +0 -255
  307. package/src/commands/feature/create-story.js +0 -362
  308. package/src/commands/feature/index.js +0 -6
  309. package/src/commands/feature/shard-spec.js +0 -225
  310. package/src/commands/feature/sprint-status.js +0 -250
  311. package/src/commands/generation/generate-onboarding.js +0 -169
  312. package/src/commands/generation/generate.js +0 -276
  313. package/src/commands/generation/index.js +0 -5
  314. package/src/commands/learning/capture-pattern.js +0 -121
  315. package/src/commands/learning/index.js +0 -5
  316. package/src/commands/learning/search-patterns.js +0 -126
  317. package/src/commands/mcp/mcp.js +0 -102
  318. package/src/commands/project/changes.js +0 -66
  319. package/src/commands/project/cost.js +0 -179
  320. package/src/commands/project/diff.js +0 -278
  321. package/src/commands/project/revert.js +0 -173
  322. package/src/commands/project/standards.js +0 -80
  323. package/src/commands/project/sync.js +0 -167
  324. package/src/commands/project/update-agents.js +0 -23
  325. package/src/commands/state/rollback-phase.js +0 -185
  326. package/src/commands/templates/template-customize.js +0 -87
  327. package/src/commands/templates/template-list.js +0 -114
  328. package/src/commands/templates/template-show.js +0 -129
  329. package/src/commands/templates/template-validate.js +0 -91
  330. package/src/commands/utils/troubleshoot.js +0 -222
  331. package/src/commands/validation/analyze-blazor-concurrency.js +0 -193
  332. package/src/commands/validation/lint-fluent.js +0 -352
  333. package/src/commands/validation/validate-blazor-state.js +0 -210
  334. package/src/commands/validation/validate-blazor.js +0 -156
  335. package/src/commands/validation/validate-css.js +0 -84
  336. package/src/lib/detectors/conversation-analyzer.js +0 -163
  337. package/src/lib/learning/index.js +0 -7
  338. package/src/lib/learning/learning-system.js +0 -520
  339. package/src/lib/troubleshooting/index.js +0 -8
  340. package/src/lib/troubleshooting/troubleshoot-grep.js +0 -198
  341. package/src/lib/troubleshooting/troubleshoot-index.js +0 -144
  342. package/src/llm/environment-detector.js +0 -43
@@ -1,225 +0,0 @@
1
- /**
2
- * MORPH-SPEC Document Sharding
3
- * Splits large spec.md files into manageable shards (BMAD-inspired)
4
- * Achieves 90% token savings by loading only relevant sections
5
- */
6
-
7
- import fs from 'fs';
8
- import path from 'path';
9
- import ora from 'ora';
10
- import chalk from 'chalk';
11
- import { getAbsoluteOutputPath } from '../../core/paths/output-schema.js';
12
- import { logger } from '../../utils/logger.js';
13
- import { ensureDir, writeFile } from '../../utils/file-copier.js';
14
-
15
- // ============================================================================
16
- // Helper Functions
17
- // ============================================================================
18
-
19
- function parseSpec(specContent) {
20
- const sections = [];
21
- const lines = specContent.split('\n');
22
-
23
- let currentSection = null;
24
- let currentContent = [];
25
-
26
- for (const line of lines) {
27
- // Detect level 2 heading (## Heading)
28
- if (line.match(/^## /)) {
29
- // Save previous section
30
- if (currentSection) {
31
- sections.push({
32
- title: currentSection,
33
- slug: toSlug(currentSection),
34
- content: currentContent.join('\n').trim(),
35
- });
36
- }
37
-
38
- // Start new section
39
- currentSection = line.replace(/^## /, '').trim();
40
- currentContent = [line]; // Include heading in content
41
- } else {
42
- currentContent.push(line);
43
- }
44
- }
45
-
46
- // Save last section
47
- if (currentSection) {
48
- sections.push({
49
- title: currentSection,
50
- slug: toSlug(currentSection),
51
- content: currentContent.join('\n').trim(),
52
- });
53
- }
54
-
55
- return sections;
56
- }
57
-
58
- function toSlug(title) {
59
- return title
60
- .toLowerCase()
61
- .replace(/[^a-z0-9]+/g, '-')
62
- .replace(/^-|-$/g, '');
63
- }
64
-
65
- function generateIndex(sections, featureName) {
66
- let index = `# ${toTitleCase(featureName)} - Technical Specification\n\n`;
67
- index += `> **Sharded Spec:** This spec has been split into sections for optimal token usage\n`;
68
- index += `> **BMAD Pattern:** Load only the section you need during implementation\n\n`;
69
- index += `---\n\n`;
70
- index += `## 📋 Table of Contents\n\n`;
71
-
72
- sections.forEach((section, i) => {
73
- index += `${i + 1}. **[${section.title}](${section.slug}.md)**\n`;
74
-
75
- // Add first 100 chars as description
76
- const firstLine = section.content.split('\n').find(l => l.trim() && !l.startsWith('#'));
77
- const description = firstLine ? firstLine.substring(0, 100) + '...' : 'See section for details';
78
- index += ` > ${description}\n\n`;
79
- });
80
-
81
- index += `---\n\n`;
82
- index += `## 💡 How to Use Sharded Specs\n\n`;
83
- index += `### In Planning Phases (1-3)\n`;
84
- index += `Load **all sections** to get complete context:\n`;
85
- index += `\`\`\`bash\n`;
86
- index += `# Read index.md + all section files\n`;
87
- index += `\`\`\`\n\n`;
88
-
89
- index += `### In Implementation Phase (4)\n`;
90
- index += `Load **only the relevant section** for your current story:\n`;
91
- index += `\`\`\`bash\n`;
92
- index += `# Example: Working on entity design story\n`;
93
- index += `# Read: spec/index.md + spec/entity-design.md (not the other 10 sections!)\n`;
94
- index += `\`\`\`\n\n`;
95
-
96
- index += `**Token Savings:** For a 10-section spec (30k tokens), selective loading = **90% savings**\n\n`;
97
- index += `---\n\n`;
98
- index += `*Generated by MORPH-SPEC Framework - Document Sharding*\n`;
99
- index += `*Inspired by BMAD Method: 90% token reduction for large specs*\n`;
100
-
101
- return index;
102
- }
103
-
104
- function toTitleCase(str) {
105
- return str
106
- .split('-')
107
- .map(word => word.charAt(0).toUpperCase() + word.slice(1))
108
- .join(' ');
109
- }
110
-
111
- function estimateTokens(text) {
112
- // Rough estimate: 1 token ≈ 4 characters
113
- return Math.ceil(text.length / 4);
114
- }
115
-
116
- // ============================================================================
117
- // Command Function
118
- // ============================================================================
119
-
120
- export async function shardSpecCommand(feature, options) {
121
- logger.header('MORPH-SPEC Document Sharding');
122
- logger.dim(`Feature: ${feature}`);
123
- logger.blank();
124
-
125
- const spinner = ora('Analyzing spec.md...').start();
126
-
127
- try {
128
- // Find spec.md
129
- const specPath = getAbsoluteOutputPath(process.cwd(), feature, 'spec');
130
- if (!fs.existsSync(specPath)) {
131
- throw new Error(`Spec not found: ${specPath}`);
132
- }
133
-
134
- // Read spec content
135
- const specContent = fs.readFileSync(specPath, 'utf-8');
136
- const totalTokens = estimateTokens(specContent);
137
-
138
- spinner.info(`Original spec.md: ~${totalTokens.toLocaleString()} tokens`);
139
- logger.blank();
140
-
141
- // Parse into sections
142
- const sections = parseSpec(specContent);
143
-
144
- if (sections.length < 3) {
145
- spinner.warn(`Spec has only ${sections.length} sections - sharding not recommended`);
146
- logger.dim(' Sharding is most beneficial for specs with 5+ sections');
147
- return;
148
- }
149
-
150
- spinner.succeed(`Detected ${sections.length} sections`);
151
- logger.blank();
152
-
153
- // Generate index
154
- const indexContent = generateIndex(sections, feature);
155
-
156
- // Calculate savings
157
- const avgShardTokens = sections.reduce((sum, s) => sum + estimateTokens(s.content), 0) / sections.length;
158
- const savingsPercent = Math.round(((totalTokens - avgShardTokens) / totalTokens) * 100);
159
-
160
- logger.header('Token Savings (selective load):');
161
- logger.info(` ${chalk.green(`~${savingsPercent}%`)} reduction`);
162
- logger.dim(` - Full load: ~${totalTokens.toLocaleString()} tokens`);
163
- logger.dim(` - Selective load: ~${Math.round(avgShardTokens).toLocaleString()} tokens (index + 1 shard)`);
164
- logger.blank();
165
-
166
- if (options.verbose) {
167
- logger.header('Shard Details:');
168
- logger.blank();
169
- sections.forEach((section, i) => {
170
- const tokens = estimateTokens(section.content);
171
- logger.dim(` ${i + 1}. ${section.title}`);
172
- logger.dim(` File: ${section.slug}.md`);
173
- logger.dim(` Tokens: ~${tokens.toLocaleString()}`);
174
- logger.blank();
175
- });
176
- }
177
-
178
- // Output
179
- const outputDir = path.join(process.cwd(), `.morph/features/${feature}/1-design/spec`);
180
-
181
- if (options.dryRun) {
182
- logger.header('DRY RUN - Would create:');
183
- logger.dim(` ${outputDir}/index.md`);
184
- sections.forEach(s => logger.dim(` ${outputDir}/${s.slug}.md`));
185
- logger.blank();
186
- logger.success('Run without --dry-run to create files');
187
- } else {
188
- const createSpinner = ora('Creating sharded spec files...').start();
189
-
190
- // Create directory
191
- await ensureDir(outputDir);
192
-
193
- // Write index
194
- await writeFile(path.join(outputDir, 'index.md'), indexContent);
195
- createSpinner.text = 'Created index.md';
196
-
197
- // Write shards
198
- for (const section of sections) {
199
- const shardPath = path.join(outputDir, `${section.slug}.md`);
200
- await writeFile(shardPath, section.content);
201
- createSpinner.text = `Created ${section.slug}.md`;
202
- }
203
-
204
- createSpinner.succeed('Sharded spec created!');
205
- logger.blank();
206
-
207
- // Archive original spec.md
208
- const archivePath = specPath.replace('.md', '.original.md');
209
- fs.renameSync(specPath, archivePath);
210
- logger.dim(' Archived original: spec.original.md');
211
- logger.blank();
212
-
213
- logger.header('Next steps:');
214
- logger.dim(` 1. Review sharded spec in .morph/features/${feature}/1-design/spec/`);
215
- logger.dim(` 2. Create stories: morph-spec story create ${feature} SR-001`);
216
- logger.dim(' 3. Stories will auto-load only relevant shards (90% token savings)');
217
- logger.blank();
218
- }
219
-
220
- } catch (error) {
221
- spinner.fail('Sharding failed');
222
- logger.error(error.message);
223
- process.exit(1);
224
- }
225
- }
@@ -1,250 +0,0 @@
1
- /**
2
- * MORPH-SPEC Sprint Status Manager
3
- * Updates sprint-status.yaml and shows next story
4
- */
5
-
6
- import fs from 'fs';
7
- import path from 'path';
8
- import yaml from 'yaml';
9
- import ora from 'ora';
10
- import chalk from 'chalk';
11
- import { logger } from '../../utils/logger.js';
12
-
13
- // ============================================================================
14
- // Helper Functions
15
- // ============================================================================
16
-
17
- function loadSprintStatus(featureName) {
18
- const statusPath = path.join(process.cwd(), `.morph/features/${featureName}/sprint-status.yaml`);
19
-
20
- if (!fs.existsSync(statusPath)) {
21
- throw new Error(`Sprint status not found: ${statusPath}\n\n💡 Create a sprint status file first:\n morph-spec story create ${featureName} STORY-001`);
22
- }
23
-
24
- const content = fs.readFileSync(statusPath, 'utf-8');
25
- return { path: statusPath, data: yaml.parse(content) };
26
- }
27
-
28
- function saveSprintStatus(statusPath, data) {
29
- const content = yaml.stringify(data);
30
- fs.writeFileSync(statusPath, content);
31
- }
32
-
33
- function updateMetrics(sprint) {
34
- const stories = sprint.stories || [];
35
- const metrics = {
36
- total_stories: stories.length,
37
- ready: stories.filter(s => s.status === 'ready').length,
38
- in_progress: stories.filter(s => s.status === 'in_progress').length,
39
- ready_for_qa: stories.filter(s => s.status === 'ready_for_qa').length,
40
- done: stories.filter(s => s.status === 'done').length,
41
- };
42
-
43
- metrics.completion_percent = stories.length > 0
44
- ? Math.round((metrics.done / stories.length) * 100)
45
- : 0;
46
-
47
- sprint.metrics = metrics;
48
- sprint.updated = new Date().toISOString().split('T')[0];
49
- }
50
-
51
- function findStory(sprint, storyId) {
52
- return sprint.stories.find(s => s.id === storyId);
53
- }
54
-
55
- function getNextStory(sprint) {
56
- // Find first story that is "ready" (not in_progress or done)
57
- return sprint.stories.find(s => s.status === 'ready' || s.status === 'pending');
58
- }
59
-
60
- function displayStatus(sprint) {
61
- logger.header(`Sprint Status: ${sprint.feature}`);
62
- logger.blank();
63
- logger.info(`Epic: ${chalk.cyan(sprint.epic)}`);
64
- logger.info(`Progress: ${chalk.green(`${sprint.metrics.completion_percent}%`)} (${sprint.metrics.done}/${sprint.metrics.total_stories} stories done)`);
65
- logger.blank();
66
-
67
- logger.header('Stories:');
68
- sprint.stories.forEach(story => {
69
- const statusEmoji = {
70
- pending: '⏸️ ',
71
- ready: '✅',
72
- in_progress: '🔄',
73
- ready_for_qa: '👀',
74
- done: '✔️ ',
75
- }[story.status] || '❓';
76
-
77
- const statusColor = {
78
- pending: chalk.dim,
79
- ready: chalk.cyan,
80
- in_progress: chalk.yellow,
81
- ready_for_qa: chalk.magenta,
82
- done: chalk.green,
83
- }[story.status] || chalk.white;
84
-
85
- logger.dim(` ${statusEmoji} ${story.id}: ${story.title} ${statusColor(`(${story.status})`)}`);
86
- });
87
- logger.blank();
88
-
89
- if (sprint.current && sprint.current.story_id) {
90
- logger.info(`🎯 Current Focus: ${chalk.cyan(sprint.current.story_id)} (${sprint.current.agent} agent)`);
91
- }
92
-
93
- if (sprint.next && sprint.next.story_id) {
94
- logger.info(`📋 Next Story: ${chalk.cyan(sprint.next.story_id)}`);
95
- logger.dim(` ${sprint.next.recommendation || 'Ready for development'}`);
96
- }
97
-
98
- logger.blank();
99
- }
100
-
101
- // ============================================================================
102
- // Command Function
103
- // ============================================================================
104
-
105
- export async function sprintStatusCommand(feature, action, storyId, options) {
106
- // Default action is 'show'
107
- const cmd = action || 'show';
108
-
109
- if (cmd === 'help' || options.help) {
110
- logger.header('MORPH-SPEC Sprint Status Manager');
111
- logger.blank();
112
- logger.info('Usage:');
113
- logger.dim(' morph-spec story status <feature> [command] [story-id]');
114
- logger.blank();
115
- logger.info('Commands:');
116
- logger.dim(' show Display current sprint status (default)');
117
- logger.dim(' start <story-id> Mark story as in_progress');
118
- logger.dim(' qa <story-id> Mark story as ready_for_qa');
119
- logger.dim(' done <story-id> Mark story as done');
120
- logger.dim(' next Show next story to work on');
121
- logger.blank();
122
- logger.info('Examples:');
123
- logger.dim(' morph-spec story status scheduled-reports show');
124
- logger.dim(' morph-spec story status scheduled-reports start SR-001');
125
- logger.dim(' morph-spec story status scheduled-reports qa SR-001');
126
- logger.dim(' morph-spec story status scheduled-reports done SR-001');
127
- logger.dim(' morph-spec story status scheduled-reports next');
128
- logger.blank();
129
- return;
130
- }
131
-
132
- try {
133
- // Load sprint status
134
- const { path: statusPath, data: sprint } = loadSprintStatus(feature);
135
-
136
- // Execute command
137
- switch (cmd) {
138
- case 'show':
139
- displayStatus(sprint);
140
- break;
141
-
142
- case 'start':
143
- if (!storyId) {
144
- throw new Error('Story ID required for "start" command');
145
- }
146
- const storyToStart = findStory(sprint, storyId);
147
- if (!storyToStart) {
148
- throw new Error(`Story not found: ${storyId}`);
149
- }
150
-
151
- const spinner = ora('Updating story status...').start();
152
- storyToStart.status = 'in_progress';
153
- storyToStart.started = new Date().toISOString().split('T')[0];
154
- storyToStart.assigned = 'dev';
155
- sprint.current = { story_id: storyId, agent: 'dev', phase: 'implementation' };
156
- updateMetrics(sprint);
157
- saveSprintStatus(statusPath, sprint);
158
- spinner.succeed(`Story ${chalk.cyan(storyId)} marked as IN PROGRESS`);
159
- logger.blank();
160
- logger.info('💡 Recommendation: Run this story in a FRESH Claude session');
161
- logger.dim(' /dev → Implement story → Add Dev Notes');
162
- logger.blank();
163
- break;
164
-
165
- case 'qa':
166
- if (!storyId) {
167
- throw new Error('Story ID required for "qa" command');
168
- }
169
- const storyForQA = findStory(sprint, storyId);
170
- if (!storyForQA) {
171
- throw new Error(`Story not found: ${storyId}`);
172
- }
173
-
174
- const qaSpinner = ora('Updating story status...').start();
175
- storyForQA.status = 'ready_for_qa';
176
- storyForQA.assigned = 'qa';
177
- sprint.current = { story_id: storyId, agent: 'qa', phase: 'review' };
178
- updateMetrics(sprint);
179
- saveSprintStatus(statusPath, sprint);
180
- qaSpinner.succeed(`Story ${chalk.cyan(storyId)} marked as READY FOR QA`);
181
- logger.blank();
182
- logger.info('💡 Recommendation: QA in a FRESH Claude session');
183
- logger.dim(' /qa → Review code → Add QA Notes');
184
- logger.blank();
185
- break;
186
-
187
- case 'done':
188
- if (!storyId) {
189
- throw new Error('Story ID required for "done" command');
190
- }
191
- const storyDone = findStory(sprint, storyId);
192
- if (!storyDone) {
193
- throw new Error(`Story not found: ${storyId}`);
194
- }
195
-
196
- const doneSpinner = ora('Updating story status...').start();
197
- storyDone.status = 'done';
198
- storyDone.completed = new Date().toISOString().split('T')[0];
199
- updateMetrics(sprint);
200
-
201
- // Update next story
202
- const nextStory = getNextStory(sprint);
203
- if (nextStory) {
204
- sprint.next = {
205
- story_id: nextStory.id,
206
- recommendation: `Story ${nextStory.id} is ready for development`,
207
- };
208
- } else {
209
- sprint.next = null;
210
- }
211
-
212
- saveSprintStatus(statusPath, sprint);
213
- doneSpinner.succeed(`Story ${chalk.cyan(storyId)} marked as DONE`);
214
- logger.blank();
215
-
216
- if (nextStory) {
217
- logger.info(`📋 Next Story: ${chalk.cyan(nextStory.id)}`);
218
- logger.dim(` ${nextStory.title}`);
219
- logger.blank();
220
- } else {
221
- logger.success('🎉 All stories completed! Feature ready for final review.');
222
- logger.blank();
223
- }
224
- break;
225
-
226
- case 'next':
227
- const next = getNextStory(sprint);
228
- if (next) {
229
- logger.header('Next Story:');
230
- logger.blank();
231
- logger.info(`📋 Story ID: ${chalk.cyan(next.id)}`);
232
- logger.info(` Title: ${next.title}`);
233
- logger.info(` File: ${chalk.dim(next.file)}`);
234
- logger.info(` Status: ${next.status}`);
235
- logger.blank();
236
- } else {
237
- logger.success('🎉 No pending stories! Sprint complete.');
238
- logger.blank();
239
- }
240
- break;
241
-
242
- default:
243
- throw new Error(`Unknown command: ${cmd}\n Use --help to see available commands`);
244
- }
245
-
246
- } catch (error) {
247
- logger.error(error.message);
248
- process.exit(1);
249
- }
250
- }
@@ -1,169 +0,0 @@
1
- /**
2
- * Generate Onboarding Command
3
- *
4
- * Reads project context and renders the onboarding template
5
- * with detected MCPs, agents, standards, and workflow info.
6
- */
7
-
8
- import { join } from 'path';
9
- import { existsSync, readFileSync, readdirSync } from 'fs';
10
- import chalk from 'chalk';
11
- import { logger } from '../../utils/logger.js';
12
- import { pathExists, readJson, writeFile, ensureDir } from '../../utils/file-copier.js';
13
- import { getInstalledCLIVersion } from '../../utils/version-checker.js';
14
-
15
- export async function generateOnboardingCommand(options = {}) {
16
- const targetPath = process.cwd();
17
- const configPath = join(targetPath, '.morph', 'config', 'config.json');
18
- const integrationsPath = join(targetPath, '.morph', 'config', 'integrations.json');
19
- const agentsPath = join(targetPath, '.morph', 'config', 'agents.json');
20
-
21
- logger.header('Generating Onboarding Guide');
22
-
23
- // Load config
24
- if (!(await pathExists(configPath))) {
25
- logger.error('Project not initialized. Run "morph-spec init" first.');
26
- process.exit(1);
27
- }
28
-
29
- const config = await readJson(configPath);
30
- const integrations = await pathExists(integrationsPath) ? await readJson(integrationsPath) : null;
31
-
32
- // Build template variables
33
- const projectName = config?.project?.name || 'Unknown Project';
34
- const stack = config?.project?.stack || config?.project?.architecture || 'not detected';
35
- const architecture = config?.project?.architecture || 'not detected';
36
- const version = getInstalledCLIVersion();
37
- const date = new Date().toISOString().split('T')[0];
38
-
39
- // Build agents list
40
- let agentsList = 'No agents configuration found. Run `morph-spec init` to set up.';
41
- if (await pathExists(agentsPath)) {
42
- try {
43
- const agentsConfig = await readJson(agentsPath);
44
- const agents = agentsConfig.agents || {};
45
- const lines = [];
46
- for (const [id, agent] of Object.entries(agents)) {
47
- const emoji = agent.emoji || '';
48
- const tier = agent.tier ? `Tier ${agent.tier}` : '';
49
- lines.push(`- ${emoji} **${agent.name || id}** (${tier}) — ${agent.role || agent.responsibilities?.[0] || ''}`);
50
- }
51
- if (lines.length > 0) {
52
- agentsList = lines.join('\n');
53
- }
54
- } catch {
55
- // Use default
56
- }
57
- }
58
-
59
- // Build MCPs summary
60
- let availableMcps = 'No MCPs detected. Install MCP servers and run `morph-spec init --force` to detect.';
61
- if (integrations) {
62
- const lines = [];
63
-
64
- if (integrations.plugins?.length > 0) {
65
- lines.push('**Plugins:**');
66
- for (const p of integrations.plugins) {
67
- const ver = p.version ? ` v${p.version}` : '';
68
- lines.push(`- ${p.name}${ver}`);
69
- }
70
- }
71
-
72
- if (integrations.mcpServers?.length > 0) {
73
- lines.push('');
74
- lines.push('**MCP Servers:**');
75
-
76
- const phaseMap = {
77
- context7: 'proposal, design, tasks, implement',
78
- supabase: 'design, implement',
79
- playwright: 'UI/UX, implement',
80
- github: 'setup, tasks, implement',
81
- figma: 'UI/UX'
82
- };
83
-
84
- for (const s of integrations.mcpServers) {
85
- const name = s.name.toLowerCase();
86
- const phases = Object.entries(phaseMap).find(([k]) => name.includes(k));
87
- const phaseStr = phases ? ` (phases: ${phases[1]})` : '';
88
- lines.push(`- **${s.name}** (${s.source})${phaseStr}`);
89
- }
90
- }
91
-
92
- if (integrations.superpowers?.installed) {
93
- lines.push('');
94
- lines.push(`**Superpowers:** installed (${integrations.superpowers.skills?.length || 0} skills)`);
95
- }
96
-
97
- if (lines.length > 0) {
98
- availableMcps = lines.join('\n');
99
- }
100
- }
101
-
102
- // Build standards summary
103
- let standardsSummary = 'Using morph-spec defaults.';
104
- const standardsDir = join(targetPath, '.morph', 'standards');
105
- if (existsSync(standardsDir)) {
106
- try {
107
- const standards = collectStandards(standardsDir);
108
- if (standards.length > 0) {
109
- standardsSummary = standards.map(s => `- ${s}`).join('\n');
110
- }
111
- } catch {
112
- // Use default
113
- }
114
- }
115
-
116
- // Build workflow summary
117
- const workflowSummary = 'Workflow is **auto-detected** from your feature request. The framework analyzes keywords and complexity to choose the best workflow.';
118
-
119
- // Read template
120
- const templatePath = join(import.meta.dirname, '..', '..', '..', 'framework', 'templates', 'docs', 'onboarding.md');
121
- let template;
122
- if (existsSync(templatePath)) {
123
- template = readFileSync(templatePath, 'utf-8');
124
- } else {
125
- logger.error('Onboarding template not found.');
126
- process.exit(1);
127
- }
128
-
129
- // Replace placeholders
130
- let content = template
131
- .replace(/\{\{PROJECT_NAME\}\}/g, projectName)
132
- .replace(/\{\{STACK\}\}/g, stack)
133
- .replace(/\{\{ARCHITECTURE\}\}/g, architecture)
134
- .replace(/\{\{DATE\}\}/g, date)
135
- .replace(/\{\{VERSION\}\}/g, version)
136
- .replace(/\{\{AGENTS_LIST\}\}/g, agentsList)
137
- .replace(/\{\{AVAILABLE_MCPS\}\}/g, availableMcps)
138
- .replace(/\{\{STANDARDS_SUMMARY\}\}/g, standardsSummary)
139
- .replace(/\{\{WORKFLOW_SUMMARY\}\}/g, workflowSummary);
140
-
141
- // Write output
142
- const outputDir = join(targetPath, '.morph', 'project', 'outputs');
143
- await ensureDir(outputDir);
144
- const outputPath = join(outputDir, 'onboarding.md');
145
- await writeFile(outputPath, content);
146
-
147
- logger.success(`Onboarding guide generated: ${outputPath}`);
148
- logger.dim('Share this file with new team members.');
149
- }
150
-
151
- /**
152
- * Collect standard file names from directory tree
153
- */
154
- function collectStandards(dir, prefix = '') {
155
- const results = [];
156
- try {
157
- const entries = readdirSync(dir, { withFileTypes: true });
158
- for (const entry of entries) {
159
- if (entry.isDirectory()) {
160
- results.push(...collectStandards(join(dir, entry.name), `${prefix}${entry.name}/`));
161
- } else if (entry.name.endsWith('.md') && entry.name !== 'README.md') {
162
- results.push(`${prefix}${entry.name.replace('.md', '')}`);
163
- }
164
- }
165
- } catch {
166
- // Permission errors
167
- }
168
- return results;
169
- }