@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
@@ -8,7 +8,7 @@ import { useMorphQuery } from '../hooks/useMorphQuery.js';
8
8
  import { apiBase, projectHref, featureHref } from '../lib/project.js';
9
9
 
10
10
  const KIND_LABEL = {
11
- page: 'Página', project: 'Projeto', feature: 'Feature', task: 'Task', skill: 'Skill', persona: 'Persona',
11
+ page: 'Página', project: 'Projeto', feature: 'Feature', slice: 'Fatia', skill: 'Skill', persona: 'Persona',
12
12
  standard: 'Standard', rule: 'Rule', hook: 'Hook', guide: 'Guia',
13
13
  };
14
14
 
@@ -17,7 +17,6 @@ const PAGES = [
17
17
  ['Personas', '/agents'], ['Standards', '/standards'], ['Rules', '/rules'], ['Hooks', '/hooks'],
18
18
  ];
19
19
 
20
- /** Everything the framework knows that has a page — built once. */
21
20
  function knowledgeIndex() {
22
21
  const out = PAGES.map(([title, to]) => ({ kind: 'page', title, to, hay: title }));
23
22
  for (const s of morphData.skills || []) out.push({ kind: 'skill', title: s.id, hint: s.description, to: entityHref('skill', s.id), hay: `${s.id} ${s.description}` });
@@ -42,30 +41,24 @@ function projectIndex(portfolio) {
42
41
  return (portfolio?.projects || []).map((p) => ({ kind: 'project', title: p.name, hint: p.dir, to: projectHref(p.id), hay: `${p.name} ${p.dir}` }));
43
42
  }
44
43
 
45
- /**
46
- * Features and their tasks. `projectName` is set for another project's
47
- * features, so a hit says where it lives.
48
- */
49
44
  function featureIndex(project, features, projectName = null) {
50
45
  const out = [];
51
46
  const where = (text) => (projectName ? (text ? `${projectName}: ${text}` : projectName) : text);
52
47
  for (const f of features || []) {
53
48
  out.push({ kind: 'feature', title: f.name, hint: where(f.description), to: featureHref(project, f.name), hay: `${f.name} ${f.description || ''} ${projectName || ''}` });
54
- for (const t of f.taskIndex || []) {
55
- out.push({ kind: 'task', title: `${t.id} ${t.title}`, hint: where(f.name), to: featureHref(project, f.name, '?tab=tasks'), hay: `${t.id} ${t.title} ${f.name} ${projectName || ''}` });
49
+ for (const sl of f.sliceIndex || []) {
50
+ out.push({ kind: 'slice', title: `${sl.id} ${sl.title}`, hint: where(f.name), to: featureHref(project, f.name, '?tab=slices'), hay: `${sl.id} ${sl.title} ${f.name} ${projectName || ''}` });
56
51
  }
57
52
  }
58
53
  return out;
59
54
  }
60
55
 
61
- /** The active features of the other projects, from the portfolio's summaries. */
62
56
  function otherProjectsIndex(portfolio, project) {
63
57
  return (portfolio?.projects || [])
64
58
  .filter((p) => p.id !== project && p.summary)
65
59
  .flatMap((p) => featureIndex(p.id, p.summary.activeFeatures, p.name));
66
60
  }
67
61
 
68
- /** Every query word must appear; a title that starts with the query ranks first. */
69
62
  export function searchIndex(index, query, limit = 40) {
70
63
  const words = query.toLowerCase().split(/\s+/).filter(Boolean);
71
64
  if (!words.length) return [];
@@ -119,7 +112,7 @@ export default function CommandPalette({ open, onClose, portfolio, project }) {
119
112
  value={query}
120
113
  onChange={(e) => setQuery(e.target.value)}
121
114
  onKeyDown={onKey}
122
- placeholder="Buscar features, tasks, skills, personas, standards, seções do guia…"
115
+ placeholder="Buscar features, fatias, skills, personas, standards, seções do guia…"
123
116
  className="w-full bg-transparent text-base text-[var(--color-fg)] outline-none focus-visible:outline-none placeholder:text-[var(--color-faint)]"
124
117
  aria-controls="palette-results"
125
118
  aria-activedescendant={results[active] ? `palette-${active}` : undefined}
@@ -1,11 +1,7 @@
1
1
  import { useEffect } from 'react';
2
2
  import { X } from '@phosphor-icons/react';
3
3
 
4
- /**
5
- * The reading drawer of the knowledge pages. Wide enough for rendered markdown,
6
- * closes on Escape, and sits over the graph without a backdrop so the graph
7
- * stays visible beside it.
8
- */
4
+ /** No backdrop: the graph stays visible beside the drawer. */
9
5
  export default function DetailPanel({ open, title, subtitle, onClose, children }) {
10
6
  useEffect(() => {
11
7
  if (!open) return undefined;
@@ -1,11 +1,6 @@
1
1
  import { Link, useSearchParams } from 'react-router-dom';
2
2
  import { useCallback } from 'react';
3
3
 
4
- /**
5
- * Where each kind of thing lives in the app. The ONE map of entity → URL, so a
6
- * persona, standard or skill reads as a link everywhere it is mentioned.
7
- * A feature belongs to a project: its links come from `featureHref` (lib/project.js).
8
- */
9
4
  export function entityHref(kind, id) {
10
5
  const q = (page) => `/${page}?sel=${encodeURIComponent(id)}`;
11
6
  switch (kind) {
@@ -20,7 +15,6 @@ export function entityHref(kind, id) {
20
15
  }
21
16
  }
22
17
 
23
- /** `standards/backend/dotnet/testing.md` (as tasks.json cites it) → the registry `path`. */
24
18
  export function standardKey(ref) {
25
19
  return String(ref).replace(/^\.?\/?(\.morph\/framework\/)?standards\//, '');
26
20
  }
@@ -34,12 +28,6 @@ export default function EntityLink({ kind, id, children, className = '', chip =
34
28
  return <Link to={entityHref(kind, id)} className={cls} title={title}>{children ?? id}</Link>;
35
29
  }
36
30
 
37
- /**
38
- * The selected item of a knowledge page, kept in `?sel=` so a panel can be
39
- * linked, bookmarked and reached from anywhere with EntityLink.
40
- *
41
- * @returns {[string|null, (id: string|null) => void]}
42
- */
43
31
  export function useSelection() {
44
32
  const [params, setParams] = useSearchParams();
45
33
  const sel = params.get('sel');
@@ -1,15 +1,8 @@
1
1
  import { Component } from 'react';
2
2
 
3
3
  /**
4
- * Catches a page that throws while rendering and shows the error in place of
5
- * the page, so the rest of the layout (the sidebar) keeps working.
6
- *
7
- * Without it one broken page unmounts the whole tree: 8.38.0 opened on
8
- * /agents, which threw a ReferenceError, and the dashboard was a black screen.
9
- *
10
4
  * Mount it with `key={location.pathname}`: a boundary that already caught an
11
- * error stays in fallback until it remounts, and the key remounts it when the
12
- * sidebar navigates to another page.
5
+ * error stays in fallback until it remounts.
13
6
  */
14
7
  export default class ErrorBoundary extends Component {
15
8
  constructor(props) {
@@ -2,9 +2,6 @@ import morphData from 'virtual:morph-data';
2
2
  import Markdown from './Markdown.jsx';
3
3
  import EntityLink, { standardKey } from './EntityLink.jsx';
4
4
 
5
- /**
6
- * Names of things that have a page. Built once from the knowledge module.
7
- */
8
5
  const skillIds = new Set((morphData.skills || []).map((s) => s.id));
9
6
  const personaIds = new Set((morphData.agents?.list || []).map((a) => a.id));
10
7
  const standardByKey = new Map();
@@ -13,13 +10,6 @@ for (const s of morphData.standards?.list || []) {
13
10
  standardByKey.set(s.path, s.id);
14
11
  }
15
12
 
16
- /**
17
- * What an inline code span names, if it names something with a page:
18
- * `morph-plan` or `/morph-plan` → skill, `morph-dotnet-senior` → persona,
19
- * a standard id or path → standard.
20
- *
21
- * @returns {{ kind: string, id: string } | null}
22
- */
23
13
  export function resolveMention(text) {
24
14
  const t = String(text).trim();
25
15
  const bare = t.replace(/^\//, '');
@@ -47,7 +37,6 @@ function InlineCode({ className, children, node, ...rest }) {
47
37
  return <code className={className} {...rest}>{children}</code>;
48
38
  }
49
39
 
50
- /** Markdown for framework and feature text: code spans that name a skill, persona or standard become links. */
51
40
  export default function KnowledgeMarkdown({ components, ...props }) {
52
41
  return <Markdown {...props} components={{ code: InlineCode, ...components }} />;
53
42
  }
@@ -6,7 +6,6 @@ import { splitFrontmatter } from '../lib/format.js';
6
6
  const REMARK = [remarkGfm];
7
7
  const REHYPE = [rehypeSlug];
8
8
 
9
- /** Frontmatter keys worth showing, in the order a reader wants them. */
10
9
  const META_ORDER = ['name', 'description', 'when_to_use', 'user-invocable', 'stacks', 'version', 'cliVersion'];
11
10
 
12
11
  function MetaBlock({ meta }) {
@@ -26,14 +25,6 @@ function MetaBlock({ meta }) {
26
25
  );
27
26
  }
28
27
 
29
- /**
30
- * Rendered markdown for every long text in the app: feature artifacts, skills,
31
- * standards, the charter. Frontmatter is lifted into a metadata block instead
32
- * of being printed as text.
33
- *
34
- * @param {{ text: string, components?: object, className?: string, size?: 'md'|'sm' }} props
35
- * `sm` is for side panels, where the reading column is narrower.
36
- */
37
28
  export default function Markdown({ text, components, className = '', size = 'md' }) {
38
29
  const { meta, body } = splitFrontmatter(text || '');
39
30
  return (
@@ -1,16 +1,5 @@
1
1
  import { PHASES, PHASE_INDEX, GATE_LABEL, phaseMeta } from '../lib/phases.js';
2
2
 
3
- /**
4
- * The phase rail: one segment per phase, a notch after each phase that ends in
5
- * an approval gate. The same motif is used in the feature list (sm) and in the
6
- * feature header (lg), so a feature's progress always reads the same way.
7
- *
8
- * Segment state is derived, never stored:
9
- * done — before the current phase, or the whole feature is completed
10
- * current — the derived phase of an active feature
11
- * skipped — an optional phase (uiux) the feature went past without its gate
12
- * todo — after the current phase
13
- */
14
3
  export function segmentStates(feature) {
15
4
  const idx = PHASE_INDEX[feature.phase] ?? 0;
16
5
  const finished = feature.status === 'completed';
@@ -1,10 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import { MagnifyingGlass } from '@phosphor-icons/react';
3
3
 
4
- /**
5
- * The toolbar of the knowledge pages: a search box and a few selects. The
6
- * `value` of each filter is controlled by the page; the search text is local.
7
- */
8
4
  export default function SearchFilter({ placeholder = 'Buscar', filters = [], onSearchChange, onFilterChange, children }) {
9
5
  const [search, setSearch] = useState('');
10
6
  function handleSearchChange(e) {
@@ -30,10 +30,6 @@ const linkClass = ({ isActive }) => [
30
30
  isActive ? 'bg-white/[0.08] text-[var(--color-fg)] shadow-[inset_0_1px_0_rgb(255_255_255_/_0.06)]' : 'text-[var(--color-dim)] hover:bg-white/[0.04] hover:text-[var(--color-fg)]',
31
31
  ].join(' ');
32
32
 
33
- /**
34
- * Switching project keeps the page: from a feature's detail it lands on the
35
- * other project's feature list, from Activity on the other project's Activity.
36
- */
37
33
  function ProjectSwitcher({ portfolio, current }) {
38
34
  const navigate = useNavigate();
39
35
  const { pathname } = useLocation();
@@ -122,7 +118,6 @@ export default function Sidebar({ portfolio, current, pulse, onSearch }) {
122
118
  );
123
119
  }
124
120
 
125
- /** The same destinations as a compact bar for narrow screens. */
126
121
  export function MobileNav({ current, onSearch }) {
127
122
  const items = [
128
123
  { to: '/', label: 'Portfólio' },
@@ -1,18 +1,8 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
2
 
3
3
  /**
4
- * Fetch a `/api/morph/*` resource and refetch it whenever the dev server
5
- * reports that the project's `.morph/` changed in the given scope.
6
- *
7
- * `scope` matches the server's invalidation: 'features' (feature.json,
8
- * tasks.json, artifacts) or 'activity' (events.jsonl). A refetch keeps the old
9
- * data on screen until the new one arrives — no flash of "loading" while an
10
- * agent is working.
11
- *
4
+ * A refetch keeps the old data on screen until the new one arrives.
12
5
  * @param {string|null} url - null skips the request
13
- * @param {{ scope?: string|string[], project?: string }} [opts] - `scope`: 'features',
14
- * 'activity' or 'projects'; `project`: only changes of this project refetch
15
- * @returns {{ data: any, error: string|null, loading: boolean, refreshedAt: number|null, refetch: () => void }}
16
6
  */
17
7
  export function useMorphQuery(url, { scope = 'features', project } = {}) {
18
8
  const [state, setState] = useState({ data: null, error: null, loading: Boolean(url), refreshedAt: null });
@@ -11,10 +11,7 @@ function read(key, fallback) {
11
11
  }
12
12
  }
13
13
 
14
- /**
15
- * A per-browser preference (view mode, filters). Storage can be unavailable or
16
- * throw (private mode, SSR); the value then simply does not persist.
17
- */
14
+ /** Storage can be unavailable or throw (private mode, SSR); the value then does not persist. */
18
15
  export function usePref(key, fallback) {
19
16
  const [value, setValue] = useState(() => (typeof window === 'undefined' ? fallback : read(key, fallback)));
20
17
  const set = useCallback((next) => {
@@ -27,7 +24,6 @@ export function usePref(key, fallback) {
27
24
  return [value, set];
28
25
  }
29
26
 
30
- /** Re-render every `ms` so relative times ("há 30 s") and "working now" stay true. */
31
27
  export function useNow(ms = 15_000) {
32
28
  const [now, setNow] = useState(() => Date.now());
33
29
  useEffect(() => {
@@ -8,7 +8,6 @@ const UNITS = [
8
8
  ['minute', 60],
9
9
  ];
10
10
 
11
- /** "há 12 minutos" — or an em dash when there is no date. */
12
11
  export function timeAgo(iso, now = Date.now()) {
13
12
  const t = Date.parse(iso || '');
14
13
  if (Number.isNaN(t)) return '—';
@@ -56,7 +55,6 @@ export function duration(seconds) {
56
55
  return `${Math.floor(m / 60)} h ${m % 60} min`;
57
56
  }
58
57
 
59
- /** Strip a leading YAML frontmatter block, returning both parts. */
60
58
  export function splitFrontmatter(text) {
61
59
  const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(text || '');
62
60
  if (!m) return { meta: null, body: text || '' };
@@ -1,14 +1,9 @@
1
- /**
2
- * Display vocabulary for the phase pipeline. The ORDER and the optional flag
3
- * come from framework/phases.json (morphData.phases); this file only adds the
4
- * words and the colour token each phase is shown with.
5
- */
1
+ /** The ORDER and the optional flag come from framework/phases.json; this file only adds words and colours. */
6
2
  import morphData from 'virtual:morph-data';
7
3
 
8
4
  const LABELS = {
9
- proposal: 'Proposta',
10
- uiux: 'UI/UX',
11
5
  plan: 'Plano',
6
+ uiux: 'UI/UX',
12
7
  implement: 'Implementação',
13
8
  review: 'Revisão',
14
9
  };
@@ -29,9 +24,8 @@ export function phaseMeta(id) {
29
24
  }
30
25
 
31
26
  export const GATE_LABEL = {
32
- proposal: 'Gate 1 (proposta)',
27
+ plan: 'Gate do plano',
33
28
  uiux: 'Gate UI/UX',
34
- plan: 'Gate 2 (plano)',
35
29
  review: 'Gate 3 (revisão)',
36
30
  };
37
31
 
@@ -3,10 +3,8 @@ import { useLocation } from 'react-router-dom';
3
3
  import { usePref } from '../hooks/usePref.js';
4
4
  import { useMorphQuery } from '../hooks/useMorphQuery.js';
5
5
 
6
- /** The live API of one project. */
7
6
  export const apiBase = (id) => `/api/morph/p/${encodeURIComponent(id)}`;
8
7
 
9
- /** A page of one project: `/p/{id}/features`, `/p/{id}/features/{name}`, `/p/{id}/activity`. */
10
8
  export const projectHref = (id, sub = 'features') => `/p/${encodeURIComponent(id)}/${sub}`;
11
9
 
12
10
  export const featureHref = (project, name, query = '') =>
@@ -14,10 +12,8 @@ export const featureHref = (project, name, query = '') =>
14
12
 
15
13
  const PROJECTS_CHANGED = 'morph:projects-changed';
16
14
 
17
- /** Tell every reader of the portfolio (page, sidebar, search) to read it again. */
18
15
  export const announceProjectsChanged = () => window.dispatchEvent(new Event(PROJECTS_CHANGED));
19
16
 
20
- /** The portfolio: registered projects, their summaries, and the ones found next to them. */
21
17
  export function useProjects() {
22
18
  const q = useMorphQuery('/api/morph/projects', { scope: 'projects' });
23
19
  const refetch = useRef(q.refetch);
@@ -30,14 +26,6 @@ export function useProjects() {
30
26
  return q;
31
27
  }
32
28
 
33
- /**
34
- * The project the person is looking at: the one in the URL, else the last one
35
- * they opened, else the one the dashboard was launched from. Knowledge pages
36
- * have no project in the URL but the sidebar still needs one to link to.
37
- *
38
- * @param {{ launch?: string|null, projects?: Array<{id: string}> }|null} portfolio
39
- * @returns {{ id: string|null, inUrl: boolean }}
40
- */
41
29
  export function useCurrentProject(portfolio) {
42
30
  const { pathname } = useLocation();
43
31
  const m = /^\/p\/([^/]+)/.exec(pathname);
@@ -13,7 +13,7 @@ export default function Activity() {
13
13
  <h1 className="mt-1 text-4xl font-semibold tracking-tight">Atividade</h1>
14
14
  <p className="mt-3 max-w-2xl text-sm leading-relaxed text-[var(--color-dim)]">
15
15
  O que o Claude fez no projeto, contado a partir da telemetria dos hooks: suas mensagens, as skills carregadas,
16
- os sub-agents despachados, as tasks, os verifies e os gates. Atualiza sozinho enquanto ele trabalha.
16
+ os sub-agents despachados, os verifies e os gates. Atualiza sozinho enquanto ele trabalha.
17
17
  </p>
18
18
  </header>
19
19
  <div className="rise-2 bezel">
@@ -10,11 +10,7 @@ import Markdown from '../components/Markdown.jsx';
10
10
  import EntityLink, { useSelection } from '../components/EntityLink.jsx';
11
11
  import { phaseMeta } from '../lib/phases.js';
12
12
 
13
- /**
14
- * `agents.json → color` is a color NAME (blue, cyan…), the one Claude Code
15
- * paints the sub-agent with. The map reads the same name, so a persona looks
16
- * the same here and in the terminal.
17
- */
13
+ /** Color NAMES, the ones Claude Code paints the sub-agent with. */
18
14
  const COLOR_HEX = {
19
15
  blue: '#60a5fa',
20
16
  cyan: '#22d3ee',
@@ -29,13 +25,11 @@ const COLOR_HEX = {
29
25
  };
30
26
  const FALLBACK_HEX = '#9ca3af';
31
27
 
32
- /** The ONE color lookup: nodes, edges, detail badge and legend all read it. */
33
28
  const personaColor = (agent) => COLOR_HEX[agent?.color] || FALLBACK_HEX;
34
29
 
35
30
  /** `'*'` in a persona's `stack` means "every stack" — it is not a stack of its own. */
36
31
  const UNIVERSAL_STACK = '*';
37
32
 
38
- /** The node of the human + main thread. Never a persona id. */
39
33
  const PRINCIPAL_ID = 'principal';
40
34
 
41
35
  const NODE_W = 220;
@@ -81,7 +75,6 @@ function buildLayout(nodes, edges) {
81
75
  });
82
76
  }
83
77
 
84
- /** Skills whose dispatch lines name this persona, or dispatch any implementer. */
85
78
  function dispatchingSkills(agent) {
86
79
  const implementer = (agent.activePhases || []).includes('implement');
87
80
  return (morphData.skills || []).filter((s) => (s.dispatches || []).some(