@polymorphism-tech/morph-spec 8.47.0 → 9.1.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 (377) hide show
  1. package/CLAUDE.md +51 -43
  2. package/README.md +39 -38
  3. package/bin/morph-spec.js +41 -113
  4. package/bin/validate.js +1 -147
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +1 -1
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/CLAUDE.md +41 -101
  9. package/framework/MORPH.md +95 -252
  10. package/framework/agents.json +86 -21
  11. package/framework/commands/morph-apply.md +5 -28
  12. package/framework/commands/morph-archive.md +1 -1
  13. package/framework/commands/morph-hotfix.md +8 -8
  14. package/framework/commands/morph-infra.md +1 -1
  15. package/framework/commands/morph-preflight.md +2 -3
  16. package/framework/commands/morph-status.md +4 -4
  17. package/framework/docs/CLI.md +574 -286
  18. package/framework/evals/review-checklist.md +82 -41
  19. package/framework/hooks/README.md +10 -11
  20. package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +6 -49
  21. package/framework/hooks/claude-code/core/block-raw-worktree-add.js +2 -35
  22. package/framework/hooks/claude-code/core/chain.js +4 -65
  23. package/framework/hooks/claude-code/core/comment-guard.js +3 -17
  24. package/framework/hooks/claude-code/core/denylist.json +33 -3
  25. package/framework/hooks/claude-code/core/enforce-phase-writes.js +15 -63
  26. package/framework/hooks/claude-code/core/gate-guard.js +9 -78
  27. package/framework/hooks/claude-code/core/graph-refresh-kick.js +3 -24
  28. package/framework/hooks/claude-code/core/heavy-gate.js +3 -21
  29. package/framework/hooks/claude-code/core/heavy-release.js +2 -13
  30. package/framework/hooks/claude-code/core/loop-detect.js +2 -31
  31. package/framework/hooks/claude-code/core/pre-bash-denylist.js +36 -2
  32. package/framework/hooks/claude-code/core/protect-spec-files.js +25 -297
  33. package/framework/hooks/claude-code/core/state-sync.js +15 -85
  34. package/framework/hooks/claude-code/core/telemetry-log.js +15 -96
  35. package/framework/hooks/claude-code/core/validate-completion.js +37 -147
  36. package/framework/hooks/claude-code/core/warn-bash-source-write.js +23 -0
  37. package/framework/hooks/claude-code/core/worktree-context.js +15 -114
  38. package/framework/hooks/claude-code/core/worktree-create.js +6 -70
  39. package/framework/hooks/claude-code/core/worktree-env-inject.js +5 -56
  40. package/framework/hooks/claude-code/core/worktree-remove.js +5 -31
  41. package/framework/hooks/claude-code/statusline.py +55 -41
  42. package/framework/hooks/package.json +3 -0
  43. package/framework/hooks/shared/activity-logger.js +9 -89
  44. package/framework/hooks/shared/agent-reap.js +2 -17
  45. package/framework/hooks/shared/build-check.js +11 -76
  46. package/framework/hooks/shared/claim-registry.js +9 -119
  47. package/framework/hooks/shared/command-tokens.js +168 -44
  48. package/framework/hooks/shared/comment-rules.js +5 -20
  49. package/framework/hooks/shared/comment-scanner.js +11 -43
  50. package/framework/hooks/shared/comment-stripper.js +11 -85
  51. package/framework/hooks/shared/e2e-check.js +0 -0
  52. package/framework/hooks/shared/errata.js +59 -0
  53. package/framework/hooks/shared/feature-locator.js +11 -95
  54. package/framework/hooks/shared/frontend-locations.js +4 -0
  55. package/framework/hooks/shared/gate-question.js +12 -0
  56. package/framework/hooks/shared/git-exclude.js +3 -20
  57. package/framework/hooks/shared/git-paths.js +8 -104
  58. package/framework/hooks/shared/graph-freshness.js +22 -166
  59. package/framework/hooks/shared/graph-refresh.js +21 -149
  60. package/framework/hooks/shared/heavy-command.js +4 -12
  61. package/framework/hooks/shared/hook-response.js +8 -83
  62. package/framework/hooks/shared/morph-cli.js +8 -52
  63. package/framework/hooks/shared/payload-utils.js +10 -132
  64. package/framework/hooks/shared/phase-utils.js +14 -72
  65. package/framework/hooks/shared/redact-secrets.js +4 -15
  66. package/framework/hooks/shared/reparse-scan.js +6 -66
  67. package/framework/hooks/shared/slice-progress.js +99 -0
  68. package/framework/hooks/shared/source-files.js +4 -17
  69. package/framework/hooks/shared/spawn-command.js +23 -0
  70. package/framework/hooks/shared/state-reader.js +51 -247
  71. package/framework/hooks/shared/state-writer.js +9 -54
  72. package/framework/hooks/shared/stdin-reader.js +1 -11
  73. package/framework/hooks/shared/telemetry-logger.js +7 -67
  74. package/framework/hooks/shared/transcript-usage.js +7 -29
  75. package/framework/hooks/shared/worktree-root.js +7 -29
  76. package/framework/mcp/registry.json +3 -4
  77. package/framework/phases.json +23 -39
  78. package/framework/rules/csharp-standards.md +1 -1
  79. package/framework/rules/frontend-standards.md +1 -0
  80. package/framework/rules/hangfire-standards.md +1 -1
  81. package/framework/rules/neon-standards.md +1 -1
  82. package/framework/schemas/config.schema.json +14 -9
  83. package/framework/schemas/feature.schema.json +15 -50
  84. package/framework/skills/README.md +3 -4
  85. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  86. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  87. package/framework/skills/core/morph-apply/SKILL.md +149 -222
  88. package/framework/skills/core/morph-hotfix/SKILL.md +33 -42
  89. package/framework/skills/core/morph-machine/SKILL.md +2 -2
  90. package/framework/skills/core/morph-media/SKILL.md +1 -1
  91. package/framework/skills/core/morph-plan/SKILL.md +137 -299
  92. package/framework/skills/core/morph-review/SKILL.md +111 -136
  93. package/framework/skills/core/morph-standards/SKILL.md +27 -39
  94. package/framework/skills/core/morph-uiux/SKILL.md +94 -152
  95. package/framework/standards/STANDARDS.json +109 -1219
  96. package/framework/standards/STANDARDS.meta.json +1319 -0
  97. package/framework/standards/ai-agents/agent-archetypes.md +2 -2
  98. package/framework/standards/ai-agents/agent-session.md +1 -1
  99. package/framework/standards/ai-agents/conversational-agent-with-phases.md +4 -4
  100. package/framework/standards/ai-agents/durable-workflows-hitl.md +3 -3
  101. package/framework/standards/ai-agents/evals-with-cache.md +1 -2
  102. package/framework/standards/ai-agents/guardrails.md +1 -1
  103. package/framework/standards/ai-agents/multi-agent-patterns.md +2 -2
  104. package/framework/standards/ai-agents/observability-patterns.md +1 -1
  105. package/framework/standards/ai-agents/production.md +1 -1
  106. package/framework/standards/ai-agents/prompt-sources.md +2 -2
  107. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  108. package/framework/standards/ai-agents/rag-custom-pgvector.md +2 -2
  109. package/framework/standards/ai-agents/setup.md +3 -3
  110. package/framework/standards/ai-agents/sweet-spot.md +2 -2
  111. package/framework/standards/ai-agents/tool-adapters.md +0 -2
  112. package/framework/standards/ai-agents/vector-data-extensions.md +4 -4
  113. package/framework/standards/ai-agents/workflows.md +1 -1
  114. package/framework/standards/architecture/code-comments.md +7 -7
  115. package/framework/standards/architecture/vertical-slice/vertical-slice.md +1 -1
  116. package/framework/standards/backend/api/validation.md +1 -1
  117. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +5 -5
  118. package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +1 -1
  119. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +2 -2
  120. package/framework/standards/data/nosql/cache/redis.md +1 -1
  121. package/framework/standards/data/nosql/cosmos-db.md +3 -3
  122. package/framework/standards/frontend/admin-app/forms.md +1 -1
  123. package/framework/standards/frontend/design-system/art-direction.md +88 -0
  124. package/framework/standards/frontend/design-system/premium-finish.md +77 -2
  125. package/framework/standards/infrastructure/neon/neon-pgvector.md +5 -5
  126. package/framework/standards/integration/mcp/mcp-tools.md +7 -7
  127. package/framework/templates/CLAUDE.md.core.template +3 -3
  128. package/framework/templates/README.md +2 -3
  129. package/framework/templates/REGISTRY.json +15 -179
  130. package/framework/templates/docs/plan.md +72 -0
  131. package/framework/templates/docs/ui-mockups.md +4 -0
  132. package/framework/templates/dotnet/ai-kit/README.md +1 -9
  133. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
  134. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
  135. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
  136. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
  137. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
  138. package/package.json +1 -1
  139. package/src/commands/context/context-refresh.js +0 -16
  140. package/src/commands/dashboard/dashboard.js +2 -8
  141. package/src/commands/e2e/e2e.js +18 -105
  142. package/src/commands/graph/affected.js +0 -14
  143. package/src/commands/graph/build.js +11 -50
  144. package/src/commands/graph/explain.js +0 -16
  145. package/src/commands/graph/status.js +1 -12
  146. package/src/commands/mcp/mcp-setup.js +4 -62
  147. package/src/commands/observability/cost.js +17 -111
  148. package/src/commands/observability/telemetry.js +1 -14
  149. package/src/commands/project/branch.js +4 -45
  150. package/src/commands/project/claim.js +4 -48
  151. package/src/commands/project/doctor-procs.js +1 -1
  152. package/src/commands/project/doctor.js +53 -307
  153. package/src/commands/project/env.js +1 -27
  154. package/src/commands/project/fleet.js +6 -35
  155. package/src/commands/project/heavy.js +3 -3
  156. package/src/commands/project/init.js +8 -68
  157. package/src/commands/project/install-plugin-cmd.js +0 -1
  158. package/src/commands/project/setup-infra-cmd.js +2 -1
  159. package/src/commands/project/stack-scan.js +58 -0
  160. package/src/commands/project/standards.js +65 -72
  161. package/src/commands/project/status.js +28 -121
  162. package/src/commands/project/update.js +31 -223
  163. package/src/commands/project/worktree.js +109 -883
  164. package/src/commands/scaffold/scaffold.js +0 -25
  165. package/src/commands/state/advance.js +65 -120
  166. package/src/commands/state/approve.js +87 -229
  167. package/src/commands/state/archive.js +23 -139
  168. package/src/commands/state/auto-approval.js +65 -0
  169. package/src/commands/state/create.js +49 -109
  170. package/src/commands/state/delete.js +11 -63
  171. package/src/commands/state/finish.js +105 -494
  172. package/src/commands/state/gate-check.js +74 -183
  173. package/src/commands/state/gate-decision.js +8 -42
  174. package/src/commands/state/handoff.js +4 -31
  175. package/src/commands/state/list.js +21 -91
  176. package/src/commands/state/report-check.js +134 -338
  177. package/src/commands/state/retype.js +12 -28
  178. package/src/commands/validation/index.js +0 -3
  179. package/src/commands/validation/mutate.js +79 -19
  180. package/src/commands/validation/plan-check.js +81 -0
  181. package/src/commands/validation/validate-feature.js +52 -216
  182. package/src/commands/validation/verify.js +45 -160
  183. package/src/core/paths/output-schema.js +9 -155
  184. package/src/core/state/feature-identity.js +1 -25
  185. package/src/core/state/gate-order.js +2 -30
  186. package/src/core/state/lifecycle-audit.js +8 -100
  187. package/src/core/state/state-manager.js +32 -395
  188. package/src/core/templates/template-registry.js +2 -97
  189. package/src/core/templates/template-renderer.js +13 -93
  190. package/src/core/templates/template-seed.js +21 -0
  191. package/src/core/work-types.js +10 -45
  192. package/src/dashboard/app/App.jsx +1 -8
  193. package/src/dashboard/app/components/ActivityFeed.jsx +2 -8
  194. package/src/dashboard/app/components/CommandPalette.jsx +4 -11
  195. package/src/dashboard/app/components/DetailPanel.jsx +1 -5
  196. package/src/dashboard/app/components/EntityLink.jsx +0 -12
  197. package/src/dashboard/app/components/ErrorBoundary.jsx +1 -8
  198. package/src/dashboard/app/components/KnowledgeMarkdown.jsx +0 -11
  199. package/src/dashboard/app/components/Markdown.jsx +0 -9
  200. package/src/dashboard/app/components/PhaseRail.jsx +0 -11
  201. package/src/dashboard/app/components/SearchFilter.jsx +0 -4
  202. package/src/dashboard/app/components/Sidebar.jsx +0 -5
  203. package/src/dashboard/app/hooks/useMorphQuery.js +1 -11
  204. package/src/dashboard/app/hooks/usePref.js +1 -5
  205. package/src/dashboard/app/lib/format.js +0 -2
  206. package/src/dashboard/app/lib/phases.js +3 -9
  207. package/src/dashboard/app/lib/project.js +0 -12
  208. package/src/dashboard/app/pages/Activity.jsx +1 -1
  209. package/src/dashboard/app/pages/AgentMap.jsx +1 -8
  210. package/src/dashboard/app/pages/FeatureDetail.jsx +139 -133
  211. package/src/dashboard/app/pages/Features.jsx +9 -16
  212. package/src/dashboard/app/pages/Guide.jsx +2 -3
  213. package/src/dashboard/app/pages/HookInspector.jsx +2 -23
  214. package/src/dashboard/app/pages/PhasePipeline.jsx +3 -7
  215. package/src/dashboard/app/pages/Portfolio.jsx +0 -1
  216. package/src/dashboard/app/pages/RulesMap.jsx +1 -16
  217. package/src/dashboard/app/pages/SkillsLibrary.jsx +1 -16
  218. package/src/dashboard/app/pages/Standards.jsx +2 -17
  219. package/src/dashboard/scanner/activity-scanner.js +14 -83
  220. package/src/dashboard/scanner/agents-scanner.js +1 -23
  221. package/src/dashboard/scanner/docs-scanner.js +1 -7
  222. package/src/dashboard/scanner/feature-status.js +2 -5
  223. package/src/dashboard/scanner/features-scanner.js +92 -113
  224. package/src/dashboard/scanner/hooks-scanner.js +5 -28
  225. package/src/dashboard/scanner/index.js +0 -4
  226. package/src/dashboard/scanner/portfolio.js +5 -29
  227. package/src/dashboard/scanner/project-api.js +8 -54
  228. package/src/dashboard/scanner/rules-scanner.js +1 -2
  229. package/src/dashboard/scanner/skills-scanner.js +2 -12
  230. package/src/dashboard/scanner/standards-scanner.js +4 -7
  231. package/src/dashboard/vite-plugin-morph-data.js +5 -19
  232. package/src/lib/ai/ai-checks.js +7 -52
  233. package/src/lib/ai/ai-project-scan.js +14 -108
  234. package/src/lib/ai/code-audit.js +7 -63
  235. package/src/lib/ai/pin-drift.js +8 -51
  236. package/src/lib/ai/registry-audit.js +11 -90
  237. package/src/lib/ci/ci-verify.js +14 -13
  238. package/src/lib/ci/github-ci.js +9 -37
  239. package/src/lib/ci/workflow-scaffold.js +2 -10
  240. package/src/lib/detectors/claude-config-detector.js +13 -74
  241. package/src/lib/detectors/index.js +8 -59
  242. package/src/lib/e2e/compose-env.js +5 -66
  243. package/src/lib/e2e/stack-teardown.js +6 -40
  244. package/src/lib/generators/architecture-scanner.js +18 -156
  245. package/src/lib/generators/handoff-generator.js +37 -112
  246. package/src/lib/generators/scaffold-generator.js +5 -101
  247. package/src/lib/generators/settings-generator.js +11 -122
  248. package/src/lib/git/branch-classifier.js +11 -84
  249. package/src/lib/git/default-branch.js +14 -169
  250. package/src/lib/git/evidence-staleness.js +2 -1
  251. package/src/lib/git/gh.js +2 -17
  252. package/src/lib/git/pending-prs.js +6 -37
  253. package/src/lib/git/pr-files.js +3 -28
  254. package/src/lib/git/pr-index.js +3 -34
  255. package/src/lib/git/tree-fingerprint.js +17 -17
  256. package/src/lib/git/tree-state.js +6 -33
  257. package/src/lib/graph/god-nodes.js +2 -22
  258. package/src/lib/graph/graph-health.js +3 -24
  259. package/src/lib/graph/graph-loader.js +5 -56
  260. package/src/lib/graph/graphify-runtime.js +7 -37
  261. package/src/lib/graph/graphifyignore.js +8 -74
  262. package/src/lib/graph/sanitize.js +16 -136
  263. package/src/lib/heavy/cleanup.js +2 -6
  264. package/src/lib/installers/effects.js +8 -93
  265. package/src/lib/installers/mcp-installer.js +9 -169
  266. package/src/lib/installers/memory-installer.js +8 -33
  267. package/src/lib/installers/templates-reconcile.js +5 -60
  268. package/src/lib/mutation/commands.js +3 -2
  269. package/src/lib/mutation/dotnet-introspection.js +281 -0
  270. package/src/lib/mutation/plan.js +14 -6
  271. package/src/lib/mutation/runner.js +1 -1
  272. package/src/lib/mutation/subset.js +47 -13
  273. package/src/lib/plan/artifact-vocabulary.js +40 -0
  274. package/src/lib/plan/checks.js +208 -0
  275. package/src/lib/plan/plan-parser.js +204 -0
  276. package/src/lib/plan/plan-template.js +18 -0
  277. package/src/lib/projects/registry.js +7 -44
  278. package/src/lib/review-reports.js +204 -0
  279. package/src/lib/risk-detector.js +131 -274
  280. package/src/lib/specs/adr-index.js +38 -85
  281. package/src/lib/specs/design-seed.js +18 -0
  282. package/src/lib/specs/frontmatter.js +31 -0
  283. package/src/lib/specs/gfm-table.js +11 -0
  284. package/src/lib/specs/revocations.js +31 -102
  285. package/src/lib/specs/screen-checklist.js +56 -132
  286. package/src/lib/stack/dotnet-build-ignores.js +43 -0
  287. package/src/lib/stack/stack-profile.js +1 -28
  288. package/src/lib/stack/stack-scan.js +260 -0
  289. package/src/lib/stack-filter.js +4 -27
  290. package/src/lib/standards/registry.js +37 -0
  291. package/src/lib/standards/sections.js +47 -0
  292. package/src/lib/standards/verified-against.js +19 -191
  293. package/src/lib/tasks/eval-node.js +23 -179
  294. package/src/lib/tasks/linux-runner.js +18 -142
  295. package/src/lib/tasks/test-nodes.js +43 -313
  296. package/src/lib/tasks/test-runner.js +107 -447
  297. package/src/lib/telemetry/metrics.js +13 -103
  298. package/src/lib/telemetry/telemetry-reader.js +13 -238
  299. package/src/lib/telemetry/verify-event.js +4 -34
  300. package/src/lib/validators/code-budget/code-budget-validator.js +4 -44
  301. package/src/lib/validators/code-budget/index.js +0 -7
  302. package/src/lib/validators/contracts/contract-compliance-validator.js +4 -26
  303. package/src/lib/validators/contracts/index.js +0 -6
  304. package/src/lib/validators/nextjs/index.js +0 -5
  305. package/src/lib/validators/nextjs/next-component-validator.js +4 -81
  306. package/src/lib/validators/packages/index.js +0 -6
  307. package/src/lib/validators/packages/package-validator.js +6 -56
  308. package/src/lib/validators/reuse/index.js +0 -8
  309. package/src/lib/validators/reuse/reuse-validator.js +24 -137
  310. package/src/lib/validators/reuse/symbol-scanner.js +6 -62
  311. package/src/lib/validators/traceability-check.js +54 -156
  312. package/src/lib/validators/validation-runner.js +20 -125
  313. package/src/lib/validators/verify-runner.js +152 -575
  314. package/src/lib/work-type-detector.js +5 -67
  315. package/src/lib/worktree/docker-audit.js +17 -137
  316. package/src/lib/worktree/env-allocator.js +10 -98
  317. package/src/lib/worktree/feature-truth.js +12 -115
  318. package/src/lib/worktree/finish-backup.js +32 -242
  319. package/src/lib/worktree/fleet-scanner.js +31 -126
  320. package/src/lib/worktree/ignored-triage.js +15 -91
  321. package/src/lib/worktree/vscode-settings.js +2 -3
  322. package/src/lib/worktree/worktree-audit.js +21 -213
  323. package/src/lib/worktree/worktree-include.js +3 -5
  324. package/src/scripts/global-install.js +3 -9
  325. package/src/scripts/install-plugin.js +1 -13
  326. package/src/scripts/setup-infra.js +17 -138
  327. package/src/utils/agents-installer.js +92 -272
  328. package/src/utils/banner.js +4 -25
  329. package/src/utils/claude-md-injector.js +1 -37
  330. package/src/utils/claude-settings-manager.js +1 -87
  331. package/src/utils/file-copier.js +32 -90
  332. package/src/utils/hooks-installer.js +26 -296
  333. package/src/utils/skills-installer.js +4 -102
  334. package/src/utils/version-checker.js +4 -83
  335. package/framework/commands/morph-proposal.md +0 -57
  336. package/framework/evals/trace-schema.md +0 -67
  337. package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
  338. package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
  339. package/framework/hooks/git/pre-commit/specs.sh +0 -50
  340. package/framework/hooks/shared/tasks-validator.js +0 -111
  341. package/framework/rules/morph-task-tracking.md +0 -54
  342. package/framework/rules/morph-workflow.md +0 -244
  343. package/framework/schemas/tasks.schema.json +0 -79
  344. package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
  345. package/framework/skills/core/morph-implement/SKILL.md +0 -194
  346. package/framework/skills/core/morph-proposal/SKILL.md +0 -152
  347. package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
  348. package/framework/templates/docs/proposal.md +0 -192
  349. package/framework/templates/docs/spec.md +0 -57
  350. package/framework/templates/docs/ui-components.md +0 -52
  351. package/framework/templates/docs/ui-design-system.md +0 -76
  352. package/framework/templates/docs/ui-flows.md +0 -167
  353. package/framework/templates/examples/spec-examples.md +0 -91
  354. package/framework/templates/feature/decisions.md +0 -124
  355. package/framework/templates/feature/recap.md +0 -145
  356. package/framework/templates/tasks.template.json +0 -17
  357. package/src/commands/state/usecase.js +0 -143
  358. package/src/commands/tasks/dag.js +0 -181
  359. package/src/commands/utils/index.js +0 -3
  360. package/src/lib/agents/output-collector.js +0 -76
  361. package/src/lib/detectors/design-system-detector.js +0 -188
  362. package/src/lib/evaluator-report.js +0 -104
  363. package/src/lib/generators/design-system-generator.js +0 -508
  364. package/src/lib/specs/acervo-format.js +0 -70
  365. package/src/lib/specs/acervo-lifecycle.js +0 -264
  366. package/src/lib/specs/done-criteria-check.js +0 -200
  367. package/src/lib/specs/usecase-check.js +0 -301
  368. package/src/lib/specs/usecase-promoter.js +0 -301
  369. package/src/lib/specs/usecase-registry.js +0 -237
  370. package/src/lib/tasks/dispatch-planner.js +0 -319
  371. package/src/lib/tasks/dotnet-test-introspection.js +0 -632
  372. package/src/lib/tasks/mermaid-renderer.js +0 -132
  373. package/src/lib/tasks/task-classifier.js +0 -30
  374. package/src/lib/tasks/task-parser.js +0 -209
  375. package/src/lib/tasks/tasks-json-parser.js +0 -296
  376. package/src/lib/tasks/test-scope.js +0 -597
  377. package/src/utils/agent-id-mapper.js +0 -11
@@ -1,15 +1,3 @@
1
- /**
2
- * setup-infra.js
3
- *
4
- * Headless infrastructure setup for MORPH-SPEC.
5
- * Extracted from init.js (steps 1-10) so it can run as
6
- * `morph-spec setup-infra` without interactive prompts or stack detection.
7
- *
8
- * Usage:
9
- * import { setupInfra } from './setup-infra.js';
10
- * await setupInfra('/path/to/project');
11
- */
12
-
13
1
  import { join, dirname, resolve } from 'path';
14
2
  import { fileURLToPath } from 'url';
15
3
  import { execSync } from 'child_process';
@@ -53,14 +41,7 @@ async function installRequiredPlugins(log, exec) {
53
41
  }
54
42
  }
55
43
 
56
- /**
57
- * Install only stack-matching rules from rulesSrc to rulesDest.
58
- * Also removes orphan rules in rulesDest that are no longer in the install set.
59
- *
60
- * @param {string} rulesSrc - Source rules directory (framework/rules/)
61
- * @param {string} rulesDest - Destination rules directory (.claude/rules/)
62
- * @param {string[]} projectTags - Stack tags from config (e.g., ['dotnet', 'blazor'])
63
- */
44
+ /** Also removes orphan rules in rulesDest that are no longer in the install set. */
64
45
  export function installRulesForStack(rulesSrc, rulesDest, projectTags, fx = realEffects()) {
65
46
  const sourceFiles = readdirSync(rulesSrc).filter(f => f.endsWith('.md'));
66
47
  const installed = new Set();
@@ -74,9 +55,7 @@ export function installRulesForStack(rulesSrc, rulesDest, projectTags, fx = real
74
55
  }
75
56
  }
76
57
 
77
- // Cleanup orphans — calado em `dryRun` pelo mesmo motivo dos laços gêmeos em
78
- // skills-installer.js e agents-installer.js (D6): `cleanFrameworkDirs()` já
79
- // apagou `.claude/rules/` inteiro antes de este código rodar de verdade.
58
+ // Calado em `dryRun`: `cleanFrameworkDirs()` já apagou `.claude/rules/` inteiro antes da execução real.
80
59
  if (!fx.dryRun) {
81
60
  for (const file of readdirSync(rulesDest).filter(f => f.endsWith('.md'))) {
82
61
  if (!installed.has(file)) {
@@ -88,11 +67,7 @@ export function installRulesForStack(rulesSrc, rulesDest, projectTags, fx = real
88
67
  return { installed: installed.size };
89
68
  }
90
69
 
91
- /**
92
- * Slash commands filtered by `stacks:` frontmatter. Clean-slate like the
93
- * skills: removes only a framework command that the stack filtered out, never
94
- * a command the user wrote into `.claude/commands/`.
95
- */
70
+ /** Clean-slate: removes only a framework command the stack filtered out, never one the user wrote. */
96
71
  export function installCommandsForStack(commandsSrc, commandsDest, projectTags, fx = realEffects()) {
97
72
  const sourceFiles = readdirSync(commandsSrc).filter(f => f.endsWith('.md'));
98
73
  let installed = 0;
@@ -108,22 +83,13 @@ export function installCommandsForStack(commandsSrc, commandsDest, projectTags,
108
83
  return { installed };
109
84
  }
110
85
 
111
- /**
112
- * Re-install only stack-aware assets (commands, rules, skills, agents) using current config.json.
113
- * Skips infrastructure steps (dirs, framework copy, hooks).
114
- *
115
- * @param {string} targetPath - Absolute path to the target project directory
116
- * @param {Function} log - Logging function
117
- * @returns {{ agentCounts: object, domainCounts: object, projectTags: string[] }}
118
- */
119
86
  async function installStackAwareAssets(targetPath, log) {
120
87
  const configPath = join(targetPath, '.morph', 'config', 'config.json');
121
88
  let projectTags = [];
122
89
  if (await pathExists(configPath)) {
123
90
  try {
124
- // BOM-tolerant: a config.json hand-edited on Windows (PS 5.1 Out-File)
125
- // carries a UTF-8 BOM; without stripping it this parse fails silently
126
- // and only universal personas get installed.
91
+ // BOM-tolerant: a config.json written by PS 5.1 Out-File carries a BOM, and a failed parse
92
+ // here silently installs only the universal personas.
127
93
  const config = JSON.parse(readFileSync(configPath, 'utf-8').replace(/^/, ''));
128
94
  projectTags = getProjectTags(config);
129
95
  } catch { /* ignore malformed config */ }
@@ -159,20 +125,8 @@ async function installStackAwareAssets(targetPath, log) {
159
125
  }
160
126
 
161
127
  /**
162
- * Rewrite the managed personas block in .claude/CLAUDE.md with the agents
163
- * ACTUALLY installed (derived list — never a hand-written promise).
164
- * No markers / no file → no-op (fail-open).
165
- * Exported so `morph-spec update` derives the same block on upgrades.
166
- *
167
- * @param {string} claudeMdPath - Absolute path to the installed .claude/CLAUDE.md
168
- * @param {Array<{ name: string, title: string, domains: string[] }>} agents
169
- * @param {object} [options]
170
- * @param {ReturnType<import('../lib/installers/effects.js').createEffects>} [options.fx]
171
- * @param {string} [options.readFrom] - De onde LER o conteúdo-base.
172
- * Num `--dry-run` o arquivo de destino ainda não recebeu a cópia que o passo
173
- * anterior previu, então ler o destino diria "sem marcadores" e o efeito de
174
- * escrita sumiria da previsão — divergindo da execução real. Lendo a MESMA
175
- * origem que seria copiada, previsão e execução decidem igual.
128
+ * No markers or no file is a no-op. `readFrom`: on `--dry-run` the destination has not received
129
+ * the predicted copy yet, so read the copy's source and let preview and real run decide alike.
176
130
  */
177
131
  export async function updateClaudeMdAgentsBlock(claudeMdPath, agents = [], options = {}) {
178
132
  const { fx = realEffects(), readFrom = claudeMdPath } = options;
@@ -195,20 +149,8 @@ export async function updateClaudeMdAgentsBlock(claudeMdPath, agents = [], optio
195
149
  }
196
150
 
197
151
  /**
198
- * Installs MORPH-SPEC infrastructure into the target project directory.
199
- * Headless — no prompts, no spinner (suppressed when MORPH_QUIET=1), no stack detection.
200
- *
201
- * @param {string} targetPath - Absolute path to the target project directory
202
- * @param {object} options
203
- * @param {Function} options._exec - exec function (for testing)
204
- * @param {Function} [options._detectGraphifyVersion] - graphify probe (for testing: the
205
- * step-18b branches differ with graphify installed or not, and CI has no Python)
206
- * @param {Function} [options._log] - log sink (for testing: replaces stdout, which the test
207
- * runner itself reports through — stubbing it swallows test results)
208
- * @param {boolean} options.reinstall - If true, only re-install stack-aware assets (rules, skills, agents)
209
- * @param {boolean} options.force - Bypass the secondary-worktree guard (see below). Callers
210
- * (e.g. `initCommand`) that already performed their own equivalent check pass this so the
211
- * check isn't redundantly re-applied here.
152
+ * Headless install: no prompts, no stack detection. `force` skips the secondary-worktree guard
153
+ * for callers that already ran an equivalent check.
212
154
  */
213
155
  export async function setupInfra(targetPath, {
214
156
  _exec = execSync, _detectGraphifyVersion = null, _log = null, reinstall = false, force = false,
@@ -220,16 +162,9 @@ export async function setupInfra(targetPath, {
220
162
  else if (!quiet) process.stdout.write(msg + '\n');
221
163
  }
222
164
 
223
- // Guard: refuse a FULL install from inside a secondary (linked) worktree.
224
- // `.claude/` and `.morph/framework/` are junctions back to the primary root
225
- // there, but `.morph/config/`, `.morph/context/`, `.morph/checkpoints/`,
226
- // `.morph/memory/`, `.morph/archive/` and `.morph/state.json` are NOT — a
227
- // full install would scaffold a second, disconnected config/state tree
228
- // inside the worktree. `reinstall` mode is exempt: it only touches
229
- // .claude/* stack-aware assets, which are the junctioned (safe) subset.
230
- // `resolvePrimaryRoot` fails open to `targetPath` itself outside a git repo
231
- // (or on any git error), so non-git projects and the primary root are
232
- // never blocked.
165
+ // In a linked worktree only .claude/ and .morph/framework/ are junctions to the root: a full
166
+ // install would scaffold a second, disconnected config/state tree. `reinstall` touches only
167
+ // the junctioned subset.
233
168
  if (!reinstall && !force) {
234
169
  const target = resolve(targetPath).replace(/\\/g, '/');
235
170
  const root = resolvePrimaryRoot(targetPath);
@@ -241,12 +176,9 @@ export async function setupInfra(targetPath, {
241
176
  }
242
177
  }
243
178
 
244
- // --- Reinstall mode: only re-install stack-aware assets ---
245
179
  if (reinstall) {
246
180
  log('setup-infra (reinstall): re-installing stack-aware assets...');
247
181
  const { agentCounts, domainCounts } = await installStackAwareAssets(targetPath, log);
248
- // Keep the derived personas list in .claude/CLAUDE.md in sync with what
249
- // was actually (re)installed.
250
182
  await updateClaudeMdAgentsBlock(join(targetPath, '.claude', 'CLAUDE.md'), agentCounts?.agents ?? []);
251
183
  log('setup-infra (reinstall): complete.');
252
184
  return {
@@ -258,17 +190,14 @@ export async function setupInfra(targetPath, {
258
190
  };
259
191
  }
260
192
 
261
- // --- 0. Install required Claude Code plugins ---
262
193
  await installRequiredPlugins(log, _exec);
263
194
 
264
- // --- 1. Inject @import into root CLAUDE.md (preserves user content) ---
265
195
  log('Step 1: Setting up CLAUDE.md...');
266
196
  const claudeMdSrc = join(FRAMEWORK_DIR, 'CLAUDE.md');
267
197
  const claudeMdDest = join(targetPath, 'CLAUDE.md');
268
198
  const importResult = await injectMorphImport(claudeMdDest);
269
199
  log(` ✓ Root CLAUDE.md: ${importResult}`);
270
200
 
271
- // --- 2. Create .morph directory structure ---
272
201
  log('Step 2: Creating .morph structure...');
273
202
  const morphPath = join(targetPath, '.morph');
274
203
  const configDir = join(morphPath, 'config');
@@ -287,7 +216,6 @@ export async function setupInfra(targetPath, {
287
216
  await ensureDir(memoryDir);
288
217
  await ensureDir(archiveDir);
289
218
 
290
- // --- 3. Write minimal config.json (only if not exists) ---
291
219
  log('Step 3: Writing config.json...');
292
220
  const configPath = join(configDir, 'config.json');
293
221
  if (!(await pathExists(configPath))) {
@@ -303,7 +231,6 @@ export async function setupInfra(targetPath, {
303
231
  await writeJson(configPath, config);
304
232
  }
305
233
 
306
- // --- 4. Write placeholder context/README.md (only if not exists) ---
307
234
  log('Step 4: Writing context/README.md...');
308
235
  const contextReadmePath = join(contextDir, 'README.md');
309
236
  if (!(await pathExists(contextReadmePath))) {
@@ -312,27 +239,9 @@ export async function setupInfra(targetPath, {
312
239
  await writeFile(contextReadmePath, readmeContent);
313
240
  }
314
241
 
315
- // --- 5. framework/templates is intentionally NOT copied to
316
- // .morph/framework/templates anymore (R3 perf plan, Task 2). Template
317
- // resolution is layered (template-registry.js, architecture-scanner.js
318
- // resolveTemplatePath): a project-local .morph/framework/templates/{path}
319
- // is still checked FIRST as an explicit override, then falls back to the
320
- // npm package's own framework/templates/ — which is what every template
321
- // actually rendered from until now anyway, since the installed copy was
322
- // never read as anything but that override. Pre-populating it was a
323
- // byte-for-byte redundant 348KB copy on every install/update.
324
242
  log('Step 5: Skipping framework templates copy (resolved from package; local override still supported)...');
325
- // Cópia legada de instalação pré-R3: se existir, ela SOMBREIA os templates
326
- // do pacote (override-first). `update` sempre reconcilia porque
327
- // checkProjectOutdated() já leu a versão anterior do projeto antes de
328
- // chamar update. Aqui (init/setup-infra) fazemos o mesmo QUANDO a mesma
329
- // fonte está disponível: getProjectMorphVersion() lê .morph/.morphversion
330
- // — o MESMO arquivo/campo que checkProjectOutdated().current usa — e essa
331
- // leitura acontece ANTES do Passo 17 (saveProjectMorphVersion) sobrescrever
332
- // esse arquivo com a versão atual, então "versão anterior" aqui é real, não
333
- // a que este próprio run está prestes a gravar. Sem esse registro (projeto
334
- // nunca rastreado antes, ou greenfield), não há fonte segura — mantém o
335
- // aviso como fallback, igual ao comportamento anterior.
243
+ // A cópia legada SOMBREIA os templates do pacote (override-first). A versão anterior é lida
244
+ // aqui, antes de o passo 17 regravar .morph/.morphversion; sem ela, não há fonte segura e só avisa.
336
245
  const legacyTemplatesDir = join(frameworkDestDir, 'templates');
337
246
  if (await pathExists(legacyTemplatesDir)) {
338
247
  const priorVersionInfo = await getProjectMorphVersion(targetPath);
@@ -348,7 +257,6 @@ export async function setupInfra(targetPath, {
348
257
  }
349
258
  }
350
259
 
351
- // --- 6. Copy framework/standards → .morph/framework/standards ---
352
260
  log('Step 6: Copying framework standards...');
353
261
  const frameworkStandardsSrc = join(FRAMEWORK_DIR, 'standards');
354
262
  const frameworkStandardsDest = join(frameworkDestDir, 'standards');
@@ -356,7 +264,6 @@ export async function setupInfra(targetPath, {
356
264
  await copyDirectory(frameworkStandardsSrc, frameworkStandardsDest);
357
265
  }
358
266
 
359
- // --- 7. Copy framework/hooks → .morph/framework/hooks ---
360
267
  log('Step 7: Copying hooks...');
361
268
  const hooksSrc = join(FRAMEWORK_DIR, 'hooks');
362
269
  const hooksDest = join(frameworkDestDir, 'hooks');
@@ -364,7 +271,6 @@ export async function setupInfra(targetPath, {
364
271
  await copyDirectory(hooksSrc, hooksDest);
365
272
  }
366
273
 
367
- // --- 7c. Copy framework/evals → .morph/framework/evals ---
368
274
  log('Step 7c: Copying evals (review checklist + trace schema)...');
369
275
  const evalsSrc = join(FRAMEWORK_DIR, 'evals');
370
276
  const evalsDest = join(frameworkDestDir, 'evals');
@@ -372,7 +278,6 @@ export async function setupInfra(targetPath, {
372
278
  await copyDirectory(evalsSrc, evalsDest);
373
279
  }
374
280
 
375
- // --- 8. Copy framework/agents.json → .morph/framework/agents.json ---
376
281
  log('Step 8: Copying agents.json...');
377
282
  const agentsSrc = join(FRAMEWORK_DIR, 'agents.json');
378
283
  const agentsDest = join(frameworkDestDir, 'agents.json');
@@ -380,7 +285,6 @@ export async function setupInfra(targetPath, {
380
285
  await copyFile(agentsSrc, agentsDest);
381
286
  }
382
287
 
383
- // --- 8b. Copy framework/MORPH.md → .morph/framework/MORPH.md ---
384
288
  log('Step 8b: Copying MORPH.md (NLH charter)...');
385
289
  const morphMdSrc = join(FRAMEWORK_DIR, 'MORPH.md');
386
290
  const morphMdDest = join(frameworkDestDir, 'MORPH.md');
@@ -388,9 +292,6 @@ export async function setupInfra(targetPath, {
388
292
  await copyFile(morphMdSrc, morphMdDest);
389
293
  }
390
294
 
391
- // --- 8b2. Copy framework/docs/CLI.md → .morph/framework/CLI.md ---
392
- // Referência completa dos comandos (flags, semântica, exemplos) — o
393
- // CLAUDE.md residente carrega só a tabela compacta e aponta para cá.
394
295
  log('Step 8b2: Copying CLI.md (command reference)...');
395
296
  const cliMdSrc = join(FRAMEWORK_DIR, 'docs', 'CLI.md');
396
297
  const cliMdDest = join(frameworkDestDir, 'CLI.md');
@@ -398,7 +299,6 @@ export async function setupInfra(targetPath, {
398
299
  await copyFile(cliMdSrc, cliMdDest);
399
300
  }
400
301
 
401
- // --- 8c. Copy framework/phases.json → .morph/framework/phases.json ---
402
302
  log('Step 8c: Copying phases.json...');
403
303
  const phasesSrc = join(FRAMEWORK_DIR, 'phases.json');
404
304
  const phasesDest = join(frameworkDestDir, 'phases.json');
@@ -406,7 +306,6 @@ export async function setupInfra(targetPath, {
406
306
  await copyFile(phasesSrc, phasesDest);
407
307
  }
408
308
 
409
- // --- 8d. Copy framework/schemas → .morph/framework/schemas (JSON schemas) ---
410
309
  log('Step 8d: Copying schemas...');
411
310
  const schemasSrc = join(FRAMEWORK_DIR, 'schemas');
412
311
  const schemasDest = join(frameworkDestDir, 'schemas');
@@ -416,20 +315,16 @@ export async function setupInfra(targetPath, {
416
315
 
417
316
  const claudeDest = join(targetPath, '.claude');
418
317
 
419
- // --- 9-13. Install stack-aware assets (commands, rules, skills, agents) ---
420
318
  log('Steps 10-13: Installing stack-aware assets...');
421
319
  const { agentCounts, domainCounts, projectTags } = await installStackAwareAssets(targetPath, log);
422
320
 
423
- // --- 14. Copy framework/CLAUDE.md → .claude/CLAUDE.md (morph-owned, gitignored) ---
424
321
  log('Step 14: Installing .claude/CLAUDE.md...');
425
322
  const runtimeClaudeMdDest = join(claudeDest, 'CLAUDE.md');
426
323
  if (await pathExists(claudeMdSrc)) {
427
324
  await copyFile(claudeMdSrc, runtimeClaudeMdDest);
428
- // Derive the personas section from what step 10-13 actually installed.
429
325
  await updateClaudeMdAgentsBlock(runtimeClaudeMdDest, agentCounts?.agents ?? []);
430
326
  }
431
327
 
432
- // --- 15. installGlobalStatusline (non-critical) ---
433
328
  log('Step 15: Installing global statusline...');
434
329
  const HOOKS_SRC = join(FRAMEWORK_DIR, 'hooks', 'claude-code');
435
330
  try {
@@ -438,16 +333,13 @@ export async function setupInfra(targetPath, {
438
333
  // Non-critical — global ~/.claude may not be writable
439
334
  }
440
335
 
441
- // --- 16. installClaudeHooks ---
442
336
  log('Step 16: Installing Claude Code hooks...');
443
337
  await installClaudeHooks(targetPath);
444
338
 
445
- // --- 17. saveProjectMorphVersion ---
446
339
  log('Step 17: Saving version info...');
447
340
  const cliVersion = getInstalledCLIVersion();
448
341
  await saveProjectMorphVersion(targetPath, cliVersion);
449
342
 
450
- // --- 18. updateGitignore + .gitattributes ---
451
343
  log('Step 18: Updating .gitignore + .gitattributes...');
452
344
  await updateGitignore(targetPath);
453
345
  await ensureGitattributes(targetPath);
@@ -455,10 +347,7 @@ export async function setupInfra(targetPath, {
455
347
  log('Step 18a: Editor excludes for worktrees...');
456
348
  try { applyEditorSettings(targetPath); } catch { /* fail-open */ }
457
349
 
458
- // --- 18b. Codebase graph (graphify) ---
459
- // Fail-open por inteiro (ADR-002): sem Python, sem uv e sem pipx, o step
460
- // registra e segue. O wrapper de CLI mata o processo em qualquer throw
461
- // (setup-infra-cmd.js), então nada aqui pode escapar do try.
350
+ // Fail-open por inteiro: o wrapper de CLI mata o processo em qualquer throw.
462
351
  log('Step 18b: Codebase graph (graphify)...');
463
352
  try {
464
353
  const { writeGraphifyignore, describeOutdatedIgnore } = await import('../lib/graph/graphifyignore.js');
@@ -486,7 +375,6 @@ export async function setupInfra(targetPath, {
486
375
  } else {
487
376
  const { kind } = detectInstaller();
488
377
  if (!kind) {
489
- // Registra e segue: o framework funciona sem grafo, por grep.
490
378
  log(` ⚠ Sem uv/pipx/python — grafo indisponível. Depois: uv tool install ${GRAPHIFY_PACKAGE}==${GRAPHIFY_VERSION}`);
491
379
  } else {
492
380
  // Sem o extra [sql] os arquivos .sql são ignorados em silêncio.
@@ -501,16 +389,8 @@ export async function setupInfra(targetPath, {
501
389
  }
502
390
  }
503
391
 
504
- // Nenhum hook do graphify: o refresh mora nos hooks do Claude (step 16 —
505
- // graph-refresh-kick + SessionStart), que o `update` reinstala. O
506
- // `graphify hook install` ficou de fora por três defeitos medidos no 0.9.50:
507
- // sai sem fazer nada em worktree vinculada, não tem post-merge (merge e pull
508
- // nunca rebuildam) e, num commit depois de um fast-forward, carimba o HEAD
509
- // num grafo sem os arquivos do merge. E nunca `graphify claude install`:
510
- // escreveria no CLAUDE.md e um PreToolUse próprio.
511
- //
512
- // A linha só sai com o graphify presente, e diz o que dispara de fato: um
513
- // commit feito no terminal não dispara nada até o próximo desses.
392
+ // Sem hook git do graphify: o refresh mora nos hooks do Claude (step 16). O `graphify hook install`
393
+ // 0.9.50 não roda em worktree vinculada, não tem post-merge e carimba HEAD num grafo sem o merge.
514
394
  if (probe()) {
515
395
  log(' ✓ refresh automático do grafo da raiz: depois dos comandos git/gh/morph-spec do agente e no início de cada sessão');
516
396
  }
@@ -518,7 +398,6 @@ export async function setupInfra(targetPath, {
518
398
  log(` ⚠ Step do grafo pulado: ${err.message}`);
519
399
  }
520
400
 
521
- // --- 19. Initialize state.json (only if not exists) ---
522
401
  log('Step 19: Initializing state.json...');
523
402
  const statePath = join(morphPath, 'state.json');
524
403
  if (!(await pathExists(statePath))) {