@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,20 +1,4 @@
1
- /**
2
- * Code Budget Validator — o que a feature adicionou além do código.
3
- *
4
- * Mede, só nas linhas que esta árvore adicionou contra a branch default:
5
- * (a) linhas de comentário que citam processo (task, UC, ADR, Gate...), que o
6
- * standard `architecture-code-comments` manda para o commit;
7
- * (b) linhas de teste ÷ linhas de produção, contra o orçamento por task do
8
- * `morph-plan` (um teste por pós-condição + um de regressão por bug);
9
- * (c) linhas de comentário ÷ linhas de código, porque o padrão do standard é
10
- * nenhum comentário. Doc-comment (`///`, JSDoc) conta como qualquer outro.
11
- *
12
- * Sempre `warning`: é medida de volume, e o excesso pode estar justificado na
13
- * task. Um aviso por medida, não por linha, porque cada aviso custa 1 ponto no
14
- * score do validador. Qualquer falha de medição vira skip com razão.
15
- *
16
- * @module code-budget-validator
17
- */
1
+ // Sempre `warning`: é medida de volume, e o excesso pode estar justificado no plano.
18
2
 
19
3
  import { readFileSync } from 'fs';
20
4
  import { join } from 'path';
@@ -25,31 +9,21 @@ import { isTestFile } from '../reuse/symbol-scanner.js';
25
9
  import { isGenerated, isProjectSource } from '../../../../framework/hooks/shared/source-files.js';
26
10
  import { citesProcess, commentLines } from '../../../../framework/hooks/shared/comment-scanner.js';
27
11
 
28
- /** Razão teste ÷ produção acima da qual se avisa. */
29
12
  export const MAX_TEST_RATIO = 1.5;
30
13
 
31
14
  /** Abaixo disto a razão não é julgada: a regressão de um bug de 2 linhas cabe aqui. */
32
15
  export const MIN_TEST_LINES = 40;
33
16
 
34
- /** Mais de uma linha de comentário a cada dez de código: os nomes não estão fazendo o trabalho. */
35
17
  export const MAX_COMMENT_RATIO = 0.1;
36
18
 
37
19
  /** Abaixo disto a densidade não é julgada: um comentário legítimo num arquivo pequeno já passaria da razão. */
38
20
  export const MIN_CODE_LINES = 40;
39
21
 
40
- /** Quantos locais citar no aviso de comentário antes de resumir com "(+N)". */
41
22
  const MAX_CITED = 4;
42
23
 
43
24
  const decimal = (n) => n.toFixed(1).replace('.', ',');
44
25
 
45
- /**
46
- * Puro, sem I/O.
47
- *
48
- * @param {Array<{path: string, content: string, added: number[]|null}>} files -
49
- * `added` são as linhas adicionadas; `null` é o arquivo inteiro (novo)
50
- * @returns {{commentLines: number, processLines: Array<{file: string, line: number, text: string}>,
51
- * testLines: number, productionLines: number, commentsByFile: Record<string, number>}}
52
- */
26
+ /** `added` são as linhas adicionadas de cada arquivo; `null` é o arquivo inteiro (novo). */
53
27
  export function measureCodeBudget(files) {
54
28
  const measured = { commentLines: 0, processLines: [], testLines: 0, productionLines: 0, commentsByFile: {} };
55
29
 
@@ -74,10 +48,6 @@ export function measureCodeBudget(files) {
74
48
  return measured;
75
49
  }
76
50
 
77
- /**
78
- * @param {ReturnType<typeof measureCodeBudget>} measured
79
- * @returns {Array<object>} avisos no formato do validation-runner
80
- */
81
51
  export function budgetIssues(measured) {
82
52
  const issues = [];
83
53
  const { commentLines: comments, processLines, testLines, productionLines, commentsByFile = {} } = measured;
@@ -89,11 +59,11 @@ export function budgetIssues(measured) {
89
59
  level: 'warning',
90
60
  message:
91
61
  `${processLines.length} de ${comments} linhas de comentário adicionadas citam processo ` +
92
- `(UC, ADR, T{n}, FR, Gate, spec.md, mockup): ${shown.join(', ')}${more > 0 ? ` (+${more})` : ''}`,
62
+ `(UC, ADR, FR, C{n}, F{n}, Gate, plan.md, checks.json, mockup): ${shown.join(', ')}${more > 0 ? ` (+${more})` : ''}`,
93
63
  file: processLines[0].file,
94
64
  line: processLines[0].line,
95
65
  solution:
96
- 'A história vai na mensagem de commit e no decisions.md; no código fica só o porquê que ' +
66
+ 'A história vai na mensagem de commit e no plan.md; no código fica só o porquê que ' +
97
67
  'ele não mostra (standard architecture-code-comments).',
98
68
  });
99
69
  }
@@ -133,16 +103,6 @@ export function budgetIssues(measured) {
133
103
  return issues;
134
104
  }
135
105
 
136
- /**
137
- * Validador plugado no `validation-runner` (e por ele no nó `validators` do
138
- * `morph-spec verify`).
139
- *
140
- * @param {string} projectPath
141
- * @param {string|null} [featureName] - não usado: a medida é da árvore inteira contra a default
142
- * @param {object} [options]
143
- * @param {Map<string, number[]|null>} [options.addedLines] - override da coleta (testes)
144
- * @returns {Promise<{errors: number, warnings: number, issues: object[], _skipReason?: string}>}
145
- */
146
106
  export async function validateCodeBudget(projectPath, featureName = null, options = {}) {
147
107
  const result = { errors: 0, warnings: 0, issues: [] };
148
108
 
@@ -1,9 +1,2 @@
1
- /**
2
- * Code Budget Validators
3
- *
4
- * Volume que a feature adicionou além do código: comentário que conta a
5
- * história do processo e teste acima do orçamento (ver code-budget-validator.js).
6
- */
7
-
8
1
  export * from './code-budget-validator.js';
9
2
  export * from '../../../../framework/hooks/shared/comment-scanner.js';
@@ -9,16 +9,15 @@ export async function validateContracts(projectPath, featureName, options = {})
9
9
 
10
10
  const skipped = (message) => ({ status: 'ok', errors: 0, warnings: 0, issues: [], coverage: null, message });
11
11
 
12
- if (!existsSync(contractsPath)) return skipped('No spec.md found — skipping');
12
+ if (!existsSync(contractsPath)) return skipped('No plan.md found — skipping');
13
13
 
14
14
  const contractsContent = readFileSync(contractsPath, 'utf-8');
15
15
  const contracts = parseContracts(contractsContent);
16
16
 
17
17
  if (contracts.interfaces.length === 0 && contracts.records.length === 0 && contracts.enums.length === 0) {
18
- return skipped('spec.md declares no interfaces/records/enums — skipping');
18
+ return skipped('plan.md declares no interfaces/records/enums — skipping');
19
19
  }
20
20
 
21
- // Find all .cs files in the project (excluding .morph outputs, bin, obj)
22
21
  const csFiles = await glob('**/*.cs', {
23
22
  cwd: projectPath,
24
23
  ignore: ['.morph/**', '**/bin/**', '**/obj/**', '**/node_modules/**']
@@ -30,7 +29,6 @@ export async function validateContracts(projectPath, featureName, options = {})
30
29
  try {
31
30
  projectCode[file] = readFileSync(fullPath, 'utf-8');
32
31
  } catch {
33
- // Skip unreadable files
34
32
  }
35
33
  }
36
34
 
@@ -39,7 +37,6 @@ export async function validateContracts(projectPath, featureName, options = {})
39
37
  let total = 0;
40
38
  const interfaceResults = [];
41
39
 
42
- // Validate interfaces
43
40
  for (const iface of contracts.interfaces) {
44
41
  total++;
45
42
  const result = validateInterface(iface, projectCode, options);
@@ -58,7 +55,6 @@ export async function validateContracts(projectPath, featureName, options = {})
58
55
  });
59
56
  }
60
57
 
61
- // Check for missing methods
62
58
  for (const method of result.missingMethods || []) {
63
59
  issues.push({
64
60
  level: 'error',
@@ -69,7 +65,6 @@ export async function validateContracts(projectPath, featureName, options = {})
69
65
  }
70
66
  }
71
67
 
72
- // Validate records/DTOs
73
68
  for (const record of contracts.records) {
74
69
  total++;
75
70
  const found = Object.entries(projectCode).some(([, content]) =>
@@ -90,7 +85,6 @@ export async function validateContracts(projectPath, featureName, options = {})
90
85
  }
91
86
  }
92
87
 
93
- // Validate enums
94
88
  for (const enumDef of contracts.enums) {
95
89
  total++;
96
90
  const found = Object.entries(projectCode).some(([, content]) =>
@@ -138,7 +132,6 @@ function parseContracts(content) {
138
132
  const records = [];
139
133
  const enums = [];
140
134
 
141
- // Extract interfaces with their methods
142
135
  const interfaceRegex = /public\s+interface\s+(I\w+)(?:\s*:\s*[\w<>,\s]+)?\s*\{([^}]*)\}/gs;
143
136
  let match;
144
137
 
@@ -150,18 +143,15 @@ function parseContracts(content) {
150
143
  interfaces.push({ name, methods });
151
144
  }
152
145
 
153
- // Extract records/classes (DTOs)
154
146
  const recordRegex = /public\s+(record|class|struct)\s+(\w+)/g;
155
147
  while ((match = recordRegex.exec(content)) !== null) {
156
148
  const type = match[1];
157
149
  const name = match[2];
158
- // Skip interface names that were already captured
159
150
  if (!name.startsWith('I') || !interfaces.some(i => i.name === name)) {
160
151
  records.push({ type, name });
161
152
  }
162
153
  }
163
154
 
164
- // Extract enums
165
155
  const enumRegex = /public\s+enum\s+(\w+)/g;
166
156
  while ((match = enumRegex.exec(content)) !== null) {
167
157
  enums.push({ name: match[1] });
@@ -170,9 +160,6 @@ function parseContracts(content) {
170
160
  return { interfaces, records, enums };
171
161
  }
172
162
 
173
- /**
174
- * Extract method signatures from an interface body
175
- */
176
163
  function extractMethods(body) {
177
164
  const methods = [];
178
165
 
@@ -182,7 +169,6 @@ function extractMethods(body) {
182
169
 
183
170
  while ((match = methodRegex.exec(body)) !== null) {
184
171
  const methodName = match[1];
185
- // Skip property getters/setters
186
172
  if (!['get', 'set', 'init'].includes(methodName)) {
187
173
  methods.push(methodName);
188
174
  }
@@ -191,9 +177,6 @@ function extractMethods(body) {
191
177
  return methods;
192
178
  }
193
179
 
194
- /**
195
- * Validate that an interface is implemented in project code
196
- */
197
180
  function validateInterface(iface, projectCode, options) {
198
181
  const result = {
199
182
  name: iface.name,
@@ -205,7 +188,6 @@ function validateInterface(iface, projectCode, options) {
205
188
  missingMethods: []
206
189
  };
207
190
 
208
- // Search for classes implementing this interface
209
191
  const implRegex = new RegExp(`class\\s+(\\w+)\\s*(?:<[^>]*>)?\\s*:\\s*[^{]*${escapeRegex(iface.name)}`, 'g');
210
192
 
211
193
  for (const [file, content] of Object.entries(projectCode)) {
@@ -215,7 +197,6 @@ function validateInterface(iface, projectCode, options) {
215
197
  result.implementingClass = match[1];
216
198
  result.implementingFile = file;
217
199
 
218
- // Check which methods are implemented
219
200
  for (const method of iface.methods) {
220
201
  const methodExists = new RegExp(`(public|protected|private|internal)?\\s*(async\\s+)?\\S+\\s+${escapeRegex(method)}\\s*\\(`, 'g').test(content);
221
202
  if (methodExists) {
@@ -225,17 +206,14 @@ function validateInterface(iface, projectCode, options) {
225
206
  }
226
207
  }
227
208
 
228
- break; // Found the implementation
209
+ break;
229
210
  }
230
- implRegex.lastIndex = 0; // Reset for next file
211
+ implRegex.lastIndex = 0;
231
212
  }
232
213
 
233
214
  return result;
234
215
  }
235
216
 
236
- /**
237
- * Escape special regex characters in a string
238
- */
239
217
  function escapeRegex(str) {
240
218
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
241
219
  }
@@ -1,7 +1 @@
1
- /**
2
- * Contract Validators
3
- *
4
- * API contract compliance validation.
5
- */
6
-
7
1
  export * from './contract-compliance-validator.js';
@@ -1,6 +1 @@
1
- /**
2
- * Next.js Validators
3
- *
4
- * Validators specific to Next.js App Router patterns.
5
- */
6
1
  export { validateNextComponent, validateNextComponentFiles } from './next-component-validator.js';
@@ -2,25 +2,8 @@ import { glob } from 'glob';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
 
5
- /**
6
- * Next.js Component Validator
7
- *
8
- * Validates .tsx files for:
9
- * 1. Unnecessary 'use client' directives (no interactivity)
10
- * 2. Missing 'use client' when React hooks are used
11
- * 3. File naming convention (kebab-case)
12
- *
13
- * @module next-component-validator
14
- */
15
-
16
- // ============================================
17
- // CONSTANTS
18
- // ============================================
19
-
20
- /** Hooks/patterns that require 'use client' */
21
5
  const CLIENT_HOOKS = ['useState', 'useEffect', 'useRef', 'useReducer', 'useCallback', 'useMemo', 'useContext'];
22
6
 
23
- /** Event handler patterns that indicate interactivity (hooks are checked via CLIENT_HOOKS) */
24
7
  const EVENT_HANDLER_PATTERNS = [
25
8
  /\bonClick\b/,
26
9
  /\bonChange\b/,
@@ -28,66 +11,29 @@ const EVENT_HANDLER_PATTERNS = [
28
11
  /\bonFocus\b/,
29
12
  /\bonBlur\b/,
30
13
  /\bonKeyDown\b/,
31
- // Qualquer outro handler de evento em JSX (onMouseEnter, onKeyUp, onScroll, onDrop…).
32
- // Sem isto, a lista fechada acima transforma interatividade legítima em falso-positivo.
33
14
  /\bon[A-Z]\w*\s*=\s*\{/,
34
15
  ];
35
16
 
36
- /**
37
- * Chamada de QUALQUER hook, não só os sete nativos: `useRouter()`, `useQuery()`, `useForm<T>()`.
38
- * O `[<(]` é o que faz `useState<Record<string, string>>(` contar — um hook com argumento de
39
- * tipo não casa com `useState\s*\(` e passava despercebido.
40
- */
17
+ // `[<(]` faz hook com argumento de tipo (`useState<Record<string, string>>(`) contar.
41
18
  const HOOK_CALL_PATTERN = /\buse[A-Z]\w*\s*[<(]/;
42
19
 
43
- /**
44
- * APIs de React que só existem no cliente. `forwardRef` e `createContext` lançam em Server
45
- * Component, então um módulo que os usa PRECISA da diretiva, mesmo sem hook nem handler.
46
- */
20
+ // Lançam em Server Component: o módulo precisa da diretiva mesmo sem hook nem handler.
47
21
  const CLIENT_ONLY_APIS = [/\bforwardRef\b/, /\bcreateContext\b/];
48
22
 
49
- /** Globais de browser: quem os toca não roda no servidor. */
50
23
  const BROWSER_GLOBALS = /\b(window|document|localStorage|sessionStorage|navigator)\s*[.[]/;
51
24
 
52
- /**
53
- * Pacotes cujos componentes são client-only. O caso que mais gerava ruído é o wrapper de
54
- * shadcn/Radix: ele só reexporta primitivas, então não tem hook nem handler no próprio
55
- * arquivo — e era acusado para sempre, apesar de estar correto.
56
- */
25
+ // Wrapper shadcn/Radix só reexporta primitivas client-only, sem hook nem handler no arquivo.
57
26
  const CLIENT_ONLY_IMPORTS = /from\s+['"](@radix-ui\/|sonner|@react-pdf\/|file-saver|framer-motion|motion\/|recharts|next\/navigation|react-hook-form|@tanstack\/react-query|embla-carousel|cmdk|vaul|react-day-picker|input-otp|@dnd-kit\/)/;
58
27
 
59
- /** Next.js special files exempt from naming checks */
60
28
  const NEXTJS_SPECIAL_FILES = ['page.tsx', 'layout.tsx', 'loading.tsx', 'error.tsx', 'not-found.tsx', 'route.ts', 'middleware.ts'];
61
29
 
62
- // ============================================
63
- // MAIN VALIDATION FUNCTION
64
- // ============================================
65
-
66
- /**
67
- * @typedef {Object} ValidationIssue
68
- * @property {'error' | 'warning' | 'info'} type
69
- * @property {string} message
70
- * @property {string} [suggestion]
71
- * @property {string} file
72
- * @property {number} [line]
73
- */
74
-
75
- /**
76
- * Validates a Next.js component file.
77
- *
78
- * @param {string} content - File content
79
- * @param {string} filePath - Relative file path
80
- * @returns {ValidationIssue[]}
81
- */
82
30
  export function validateNextComponent(content, filePath) {
83
31
  const issues = [];
84
32
 
85
- // Only validate .tsx and .ts files
86
33
  if (!filePath.endsWith('.tsx') && !filePath.endsWith('.ts')) {
87
34
  return issues;
88
35
  }
89
36
 
90
- // Skip non-component utility files (no JSX, no hooks)
91
37
  const hasJsx = /(?<![a-zA-Z0-9])<[A-Z][a-zA-Z]*[\s/>]|(?<![a-zA-Z0-9])<[a-z][a-z]+[\s>/]/.test(content);
92
38
  const hasHooks = CLIENT_HOOKS.some(hook => content.includes(hook));
93
39
 
@@ -97,13 +43,10 @@ export function validateNextComponent(content, filePath) {
97
43
 
98
44
  const hasUseClient = /^'use client';?|^"use client";?/.test(content.trimStart());
99
45
 
100
- // Check 1: use client present but no interactivity
101
46
  if (hasUseClient) {
102
47
  const hasEventHandlers = EVENT_HANDLER_PATTERNS.some(pattern => pattern.test(content));
103
48
  const hasClientHooks = CLIENT_HOOKS.some(hook => new RegExp(`\\b${hook}\\b`).test(content));
104
- // Só acusa quando NENHUM sinal de necessidade de cliente aparece. Um falso-positivo aqui
105
- // pede a remoção de uma diretiva que o build precisa, então a checagem erra para o lado
106
- // de ficar calada.
49
+ // Falso-positivo pediria remover uma diretiva que o build precisa: erra para o lado calado.
107
50
  const needsClient =
108
51
  hasEventHandlers ||
109
52
  hasClientHooks ||
@@ -121,7 +64,6 @@ export function validateNextComponent(content, filePath) {
121
64
  }
122
65
  }
123
66
 
124
- // Check 2: hooks used without use client
125
67
  // .ts files (custom hooks, utilities) never render JSX — skip this check
126
68
  if (!hasUseClient) {
127
69
  if (!filePath.endsWith('.tsx')) return issues;
@@ -137,7 +79,6 @@ export function validateNextComponent(content, filePath) {
137
79
  }
138
80
  }
139
81
 
140
- // Check 3: file naming convention (kebab-case)
141
82
  const fileName = filePath.split('/').pop() ?? '';
142
83
  const isSpecialFile = NEXTJS_SPECIAL_FILES.includes(fileName);
143
84
 
@@ -157,10 +98,6 @@ export function validateNextComponent(content, filePath) {
157
98
  return issues;
158
99
  }
159
100
 
160
- // ============================================
161
- // HELPERS
162
- // ============================================
163
-
164
101
  function toKebabCase(str) {
165
102
  return str
166
103
  .replace(/([A-Z])/g, '-$1')
@@ -168,22 +105,9 @@ function toKebabCase(str) {
168
105
  .replace(/^-/, '');
169
106
  }
170
107
 
171
- // ============================================
172
- // PROJECT-LEVEL SCANNER
173
- // ============================================
174
-
175
- /**
176
- * Validates all Next.js component files in a project directory.
177
- * Wraps validateNextComponent for use in validation-runner.js.
178
- *
179
- * @param {string} projectPath - Root path of the project
180
- * @param {Object} _options - Validator options (unused, for interface compatibility)
181
- * @returns {Promise<{ errors: number, warnings: number, issues: Array }>}
182
- */
183
108
  export async function validateNextComponentFiles(projectPath, _options = {}) {
184
109
  const result = { errors: 0, warnings: 0, issues: [] };
185
110
 
186
- // Find all .tsx and .ts files under src/
187
111
  const srcDir = join(projectPath, 'src');
188
112
  const normalizedSrc = srcDir.replace(/\\/g, '/');
189
113
  const pattern = normalizedSrc + '/**/*.{tsx,ts}';
@@ -197,7 +121,6 @@ export async function validateNextComponentFiles(projectPath, _options = {}) {
197
121
  continue;
198
122
  }
199
123
 
200
- // Make path relative for cleaner output
201
124
  const normFilePath = filePath.replace(/\\/g, '/');
202
125
  const relPath = normFilePath.replace(projectPath.replace(/\\/g, '/') + '/', '');
203
126
  const fileIssues = validateNextComponent(content, relPath);
@@ -1,7 +1 @@
1
- /**
2
- * Package Validators
3
- *
4
- * Package and dependency validation.
5
- */
6
-
7
1
  export * from './package-validator.js';
@@ -1,21 +1,9 @@
1
- /**
2
- * Package Compatibility Validator
3
- *
4
- * Validates NuGet package versions against .NET compatibility matrix.
5
- * Critical for .NET 10 migration - prevents runtime errors.
6
- *
7
- * MORPH-SPEC 3.0 - Sprint 4
8
- */
9
-
10
1
  import { readFileSync } from 'fs';
11
2
  import { join } from 'path';
12
3
  import { glob } from 'glob';
13
4
  import chalk from 'chalk';
14
5
 
15
- /**
16
- * Compatibility matrix for .NET versions
17
- * Source: framework/standards/dotnet10-compatibility.md
18
- */
6
+ // Source: framework/standards/dotnet10-compatibility.md
19
7
  const COMPATIBILITY_MATRIX = {
20
8
  'Hangfire.AspNetCore': {
21
9
  9: '1.8.0',
@@ -50,7 +38,7 @@ const COMPATIBILITY_MATRIX = {
50
38
  breaking: false
51
39
  },
52
40
  'Microsoft.SemanticKernel': {
53
- 9: null, // Not compatible with .NET 10
41
+ 9: null,
54
42
  10: null,
55
43
  deprecated: true,
56
44
  replacement: 'Microsoft.Extensions.AI.Abstractions',
@@ -58,17 +46,11 @@ const COMPATIBILITY_MATRIX = {
58
46
  }
59
47
  };
60
48
 
61
- /**
62
- * Package Validator Class
63
- */
64
49
  export class PackageValidator {
65
50
  constructor(projectPath = '.') {
66
51
  this.projectPath = projectPath;
67
52
  }
68
53
 
69
- /**
70
- * Validate all .csproj files in project
71
- */
72
54
  async validateAll() {
73
55
  const csprojFiles = await glob('**/*.csproj', {
74
56
  cwd: this.projectPath,
@@ -86,10 +68,7 @@ export class PackageValidator {
86
68
  const allIssues = [];
87
69
 
88
70
  for (const file of csprojFiles) {
89
- // glob returns paths relative to `cwd: this.projectPath`, so they only
90
- // resolve against projectPath — reading them relative to process.cwd()
91
- // raised ENOENT whenever the two differed (worktree, fleet, a verify
92
- // launched from the primary root), and the throw read as a clean pass.
71
+ // glob paths are relative to `cwd: this.projectPath`, never to process.cwd().
93
72
  const result = await this.validateFile(join(this.projectPath, file));
94
73
  if (result.issues.length > 0) {
95
74
  results.push({ file, ...result });
@@ -101,9 +80,7 @@ export class PackageValidator {
101
80
  status: results.length === 0 ? 'ok' : 'error',
102
81
  totalFiles: csprojFiles.length,
103
82
  filesWithIssues: results.length,
104
- // The runner's contract. Without these three the findings below were
105
- // read as `errors: 0` and the run reported "✅ All validations passed"
106
- // while holding a list of NuGet packages that do not build on .NET 10.
83
+ // The runner's contract: without these counts the findings read as `errors: 0`.
107
84
  errors: allIssues.filter(i => i.level === 'error').length,
108
85
  warnings: allIssues.filter(i => i.level === 'warning').length,
109
86
  issues: allIssues,
@@ -111,13 +88,9 @@ export class PackageValidator {
111
88
  };
112
89
  }
113
90
 
114
- /**
115
- * Validate single .csproj file
116
- */
117
91
  async validateFile(filePath) {
118
92
  const content = readFileSync(filePath, 'utf-8');
119
93
 
120
- // Extract .NET version
121
94
  const tfmMatch = content.match(/<TargetFramework>(.*?)<\/TargetFramework>/);
122
95
  if (!tfmMatch) {
123
96
  return {
@@ -142,10 +115,8 @@ export class PackageValidator {
142
115
  };
143
116
  }
144
117
 
145
- // Extract package references
146
118
  const packages = this.extractPackages(content);
147
119
 
148
- // Validate each package
149
120
  const issues = [];
150
121
 
151
122
  for (const pkg of packages) {
@@ -162,9 +133,6 @@ export class PackageValidator {
162
133
  };
163
134
  }
164
135
 
165
- /**
166
- * Extract package references from .csproj content
167
- */
168
136
  extractPackages(csprojContent) {
169
137
  const packages = [];
170
138
  const packageRegex = /<PackageReference\s+Include="([^"]+)"\s+Version="([^"]+)"/g;
@@ -180,18 +148,13 @@ export class PackageValidator {
180
148
  return packages;
181
149
  }
182
150
 
183
- /**
184
- * Validate single package against compatibility matrix
185
- */
186
151
  validatePackage(pkg, dotnetVersion) {
187
152
  const rule = COMPATIBILITY_MATRIX[pkg.name];
188
153
 
189
154
  if (!rule) {
190
- // Package not in matrix - no validation
191
155
  return null;
192
156
  }
193
157
 
194
- // Check if deprecated
195
158
  if (rule.deprecated) {
196
159
  return {
197
160
  level: 'error',
@@ -204,7 +167,6 @@ export class PackageValidator {
204
167
  };
205
168
  }
206
169
 
207
- // Check if version is sufficient
208
170
  const requiredVersion = rule[dotnetVersion];
209
171
 
210
172
  if (!requiredVersion) {
@@ -235,13 +197,10 @@ export class PackageValidator {
235
197
  };
236
198
  }
237
199
 
238
- return null; // Package is compatible
200
+ return null;
239
201
  }
240
202
 
241
- /**
242
- * Compare semantic versions
243
- * Returns: -1 (v1 < v2), 0 (equal), 1 (v1 > v2)
244
- */
203
+ // -1 (v1 < v2), 0 (equal), 1 (v1 > v2)
245
204
  compareVersions(v1, v2) {
246
205
  const parts1 = v1.split('.').map(p => parseInt(p.replace(/[^0-9]/g, '')) || 0);
247
206
  const parts2 = v2.split('.').map(p => parseInt(p.replace(/[^0-9]/g, '')) || 0);
@@ -259,9 +218,6 @@ export class PackageValidator {
259
218
  return 0;
260
219
  }
261
220
 
262
- /**
263
- * Format validation results for console output
264
- */
265
221
  formatResults(results) {
266
222
  if (results.status === 'ok') {
267
223
  console.log(chalk.green('✅ All packages are compatible'));
@@ -314,9 +270,6 @@ export class PackageValidator {
314
270
  }
315
271
  }
316
272
 
317
- /**
318
- * Auto-fix compatible issues
319
- */
320
273
  async autoFix(results) {
321
274
  const { execSync } = await import('child_process');
322
275
  let fixedCount = 0;
@@ -340,9 +293,6 @@ export class PackageValidator {
340
293
  }
341
294
  }
342
295
 
343
- /**
344
- * Quick validation function (for imports)
345
- */
346
296
  export async function validatePackages(projectPath = '.', options = {}) {
347
297
  const validator = new PackageValidator(projectPath);
348
298
  const results = await validator.validateAll();
@@ -1,10 +1,2 @@
1
- /**
2
- * Reuse Validators
3
- *
4
- * Cobrança determinística de reuso de código: símbolo novo cujo nome já existe
5
- * no grafo do codebase, na mesma linguagem. É a terceira camada do ciclo
6
- * PROSA → ARTEFATO → VERIFICAÇÃO (ver reuse-validator.js).
7
- */
8
-
9
1
  export * from './reuse-validator.js';
10
2
  export * from './symbol-scanner.js';