@polymorphism-tech/morph-spec 4.11.1 → 4.13.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 (317) hide show
  1. package/README.md +21 -29
  2. package/bin/morph-spec.js +41 -24
  3. package/bin/task-manager.js +962 -1341
  4. package/bin/validate.js +1 -1
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +10 -11
  7. package/docs/QUICKSTART.md +15 -15
  8. package/framework/CLAUDE.md +5 -2
  9. package/framework/agents/README.md +3 -4
  10. package/framework/agents/ai-agents/ai-system-architect.md +6 -10
  11. package/framework/agents/architecture/seo-growth-hacker.md +166 -326
  12. package/framework/agents/architecture/standards-architect.md +21 -31
  13. package/framework/agents/backend/dotnet-senior.md +160 -86
  14. package/framework/agents/backend/ef-modeler.md +2 -6
  15. package/framework/agents/backend/hangfire-orchestrator.md +8 -9
  16. package/framework/agents/backend/ms-agent-expert.md +1 -1
  17. package/framework/agents/frontend/nextjs-expert.md +198 -133
  18. package/framework/agents/frontend/ui-ux-designer.md +226 -267
  19. package/framework/agents/infrastructure/infra-architect.md +191 -27
  20. package/framework/agents/integrations/clerk-auth.md +19 -26
  21. package/framework/agents/integrations/hangfire-integration.md +1 -4
  22. package/framework/agents.json +226 -1454
  23. package/framework/commands/morph-apply.md +4 -4
  24. package/framework/commands/morph-preflight.md +4 -26
  25. package/framework/commands/morph-proposal.md +19 -19
  26. package/framework/commands/morph-status.md +2 -2
  27. package/framework/commands/morph-troubleshoot.md +6 -13
  28. package/framework/hooks/README.md +1 -6
  29. package/framework/hooks/claude-code/post-tool-use/agent-complete.js +122 -0
  30. package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +4 -6
  31. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +12 -7
  32. package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +2 -2
  33. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +2 -2
  34. package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +5 -10
  35. package/framework/hooks/claude-code/session-start/inject-morph-context.js +63 -30
  36. package/framework/hooks/claude-code/session-start/resume-context.js +77 -0
  37. package/framework/hooks/claude-code/statusline.py +4 -5
  38. package/framework/hooks/claude-code/stop/validate-completion.js +4 -4
  39. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +8 -8
  40. package/framework/hooks/shared/compact-restore.js +28 -5
  41. package/framework/hooks/shared/dispatch-helpers.js +17 -0
  42. package/framework/hooks/shared/phase-utils.js +4 -8
  43. package/framework/hooks/shared/state-reader.js +34 -3
  44. package/framework/phases.json +7 -45
  45. package/framework/rules/ai-agents-standards.md +15 -0
  46. package/framework/rules/asaas-standards.md +13 -0
  47. package/framework/rules/clerk-standards.md +13 -0
  48. package/framework/rules/csharp-standards.md +8 -4
  49. package/framework/rules/data-standards.md +18 -0
  50. package/framework/rules/dotnet-templates.md +87 -0
  51. package/framework/rules/frontend-standards.md +13 -13
  52. package/framework/rules/hangfire-standards.md +13 -0
  53. package/framework/rules/infrastructure-standards.md +27 -16
  54. package/framework/rules/morph-workflow.md +73 -13
  55. package/framework/rules/nextjs-standards.md +1 -0
  56. package/framework/rules/nextjs-templates.md +40 -0
  57. package/framework/rules/resend-standards.md +12 -0
  58. package/framework/rules/supabase-standards.md +29 -0
  59. package/framework/skills/README.md +6 -8
  60. package/framework/skills/level-0-meta/mcp-registry.json +21 -99
  61. package/framework/{standards/ai-agents/team-orchestration.md → skills/level-0-meta/morph-agent-teams/SKILL.md} +472 -479
  62. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +28 -1
  63. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
  64. package/framework/skills/level-0-meta/morph-code-review/SKILL.md +1 -5
  65. package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +1 -1
  66. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +23 -41
  67. package/framework/skills/level-0-meta/morph-init/SKILL.md +18 -14
  68. package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +225 -0
  69. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +20 -0
  70. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +4 -8
  71. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +15 -59
  72. package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +7 -19
  73. package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +8 -8
  74. package/framework/skills/level-1-workflows/README.md +1 -1
  75. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +49 -50
  76. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +58 -124
  77. package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +5 -50
  78. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +1 -1
  79. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +127 -159
  80. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -3
  81. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +2 -2
  82. package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +1 -1
  83. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +17 -13
  84. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +22 -40
  85. package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +0 -2
  86. package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +5 -5
  87. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +275 -61
  88. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
  89. package/framework/squad-templates/backend-only.json +6 -6
  90. package/framework/squad-templates/frontend-only.json +17 -8
  91. package/framework/squad-templates/full-stack.json +29 -24
  92. package/framework/standards/STANDARDS.json +1021 -2338
  93. package/framework/standards/backend/dotnet/fluent-validation-vsa.md +200 -0
  94. package/framework/standards/backend/dotnet/result-pattern.md +213 -0
  95. package/framework/standards/backend/dotnet/scalar-ui.md +172 -0
  96. package/framework/standards/backend/dotnet/scrutor.md +158 -0
  97. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -0
  98. package/framework/standards/frontend/nextjs/motion-patterns.md +1 -1
  99. package/framework/standards/infrastructure/supabase/mcp-setup.md +83 -193
  100. package/framework/standards/integration/mcp/mcp-tools.md +91 -77
  101. package/framework/templates/IDE-SNIPPETS.md +2 -6
  102. package/framework/templates/README.md +709 -814
  103. package/framework/templates/REGISTRY.json +223 -762
  104. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -0
  105. package/framework/templates/code/dotnet/abstractions/error.cs +60 -0
  106. package/framework/templates/code/dotnet/abstractions/handler.cs +12 -0
  107. package/framework/templates/code/dotnet/abstractions/result.cs +74 -0
  108. package/framework/templates/code/dotnet/backend/repository.cs +148 -141
  109. package/framework/templates/code/dotnet/constants/api-tags.cs +6 -0
  110. package/framework/templates/code/dotnet/exceptions/exception-handler.cs +32 -0
  111. package/framework/templates/code/dotnet/extensions/database-extensions.cs +20 -0
  112. package/framework/templates/code/dotnet/extensions/handler-registration.cs +38 -0
  113. package/framework/templates/code/dotnet/extensions/health-checks.cs +24 -0
  114. package/framework/templates/code/dotnet/extensions/map-endpoints.cs +35 -0
  115. package/framework/templates/code/dotnet/extensions/result-extensions.cs +29 -0
  116. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -0
  117. package/framework/templates/code/dotnet/feature/entity.cs.hbs +8 -0
  118. package/framework/templates/code/dotnet/feature/errors.cs.hbs +8 -0
  119. package/framework/templates/code/dotnet/feature/handler.cs.hbs +24 -0
  120. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -0
  121. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -0
  122. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -0
  123. package/framework/templates/code/dotnet/jobs/job.cs +21 -17
  124. package/framework/templates/code/dotnet/pipelines/logging-decorator.cs +31 -0
  125. package/framework/templates/code/dotnet/pipelines/validation-decorator.cs +97 -0
  126. package/framework/templates/code/dotnet/test.cs +192 -106
  127. package/framework/templates/context/ARCHITECTURE.md +89 -0
  128. package/framework/templates/context/CONTEXT-FEATURE.md +2 -2
  129. package/framework/templates/context/CONTEXT.md +180 -181
  130. package/framework/templates/context/design-system.md +342 -211
  131. package/framework/templates/docs/onboarding.md +2 -3
  132. package/framework/templates/docs/proposal.md +171 -182
  133. package/framework/templates/docs/spec.md +1 -3
  134. package/framework/templates/docs/ui-components.md +0 -72
  135. package/framework/templates/examples/design-system-examples.md +4 -4
  136. package/framework/templates/feature/decisions.md +0 -66
  137. package/framework/templates/feature/recap.md +1 -2
  138. package/framework/templates/infrastructure/github/README.md +56 -593
  139. package/framework/templates/integrations/clerk-config.cs +0 -41
  140. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  141. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -2
  142. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +83 -126
  143. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +2 -2
  144. package/framework/templates/project/validate.js +2 -4
  145. package/framework/templates/ui/design-system.css +1 -1
  146. package/framework/workflows/README.md +8 -8
  147. package/framework/workflows/configs/fast-track.json +51 -0
  148. package/framework/workflows/configs/full.json +68 -0
  149. package/framework/workflows/configs/standard.json +7 -3
  150. package/framework/workflows/docs/STORY-DRIVEN-DEVELOPMENT.md +1 -1
  151. package/framework/workflows/docs/enforcement-pipeline.md +18 -19
  152. package/framework/workflows/docs/full-morph.md +69 -76
  153. package/framework/workflows/docs/standard.md +49 -44
  154. package/framework/workflows/docs/ui-refresh.md +1 -1
  155. package/package.json +3 -3
  156. package/src/commands/agents/dispatch-agents.js +55 -116
  157. package/src/commands/context/context-refresh.js +79 -0
  158. package/src/commands/mcp/mcp-setup.js +28 -6
  159. package/src/commands/phase/phase-reset.js +1 -1
  160. package/src/commands/project/doctor.js +10 -32
  161. package/src/commands/project/init.js +32 -1
  162. package/src/commands/project/status.js +6 -12
  163. package/src/commands/scaffold/scaffold.js +131 -0
  164. package/src/commands/scope/escalate.js +1 -1
  165. package/src/commands/state/advance-phase.js +15 -29
  166. package/src/commands/state/state.js +20 -5
  167. package/src/commands/tasks/task.js +0 -30
  168. package/src/commands/validation/validate-feature.js +3 -10
  169. package/src/core/paths/output-schema.js +12 -13
  170. package/src/core/state/phase-state-machine.js +211 -217
  171. package/src/core/state/state-manager.js +9 -9
  172. package/src/lib/agents/agents-manager.js +2 -2
  173. package/src/lib/agents/output-collector.js +1 -2
  174. package/src/lib/detectors/design-system-detector.js +4 -4
  175. package/src/lib/detectors/index.js +1 -11
  176. package/src/lib/generators/architecture-scanner.js +640 -0
  177. package/src/lib/generators/context-generator.js +3 -3
  178. package/src/lib/generators/design-system-generator.js +508 -298
  179. package/src/lib/generators/index.js +12 -10
  180. package/src/lib/generators/metadata-extractor.js +386 -387
  181. package/src/lib/generators/recap-generator.js +4 -4
  182. package/src/lib/generators/scaffold-generator.js +317 -0
  183. package/src/lib/generators/settings-generator.js +0 -1
  184. package/src/lib/phase-chain/phase-validator.js +64 -42
  185. package/src/lib/stack/stack-profile.js +2 -2
  186. package/src/lib/standards/digest-builder.js +72 -285
  187. package/src/lib/tasks/task-parser.js +11 -5
  188. package/src/lib/validators/architecture/architecture-validator.js +259 -387
  189. package/src/lib/validators/content/content-validator.js +287 -287
  190. package/src/lib/validators/css/css-validator.js +340 -352
  191. package/src/lib/validators/design-system/design-system-validator.js +11 -5
  192. package/src/lib/validators/packages/package-validator.js +347 -360
  193. package/src/lib/validators/shared/issue-counter.js +14 -18
  194. package/src/lib/validators/validation-runner.js +3 -19
  195. package/src/scripts/setup-infra.js +1 -1
  196. package/src/utils/agents-installer.js +24 -3
  197. package/src/utils/file-copier.js +1 -0
  198. package/src/utils/hooks-installer.js +21 -19
  199. package/src/utils/skills-installer.js +178 -178
  200. package/framework/agents/architecture/prompt-engineer.md +0 -195
  201. package/framework/agents/backend/api-designer.md +0 -106
  202. package/framework/agents/frontend/blazor-builder.md +0 -229
  203. package/framework/agents/frontend/nextjs-ui-specialist.md +0 -218
  204. package/framework/agents/infrastructure/azure-architect.md +0 -150
  205. package/framework/agents/infrastructure/azure-deploy-specialist.md +0 -707
  206. package/framework/agents/infrastructure/bicep-architect.md +0 -132
  207. package/framework/agents/infrastructure/container-specialist.md +0 -137
  208. package/framework/agents/infrastructure/devops-engineer.md +0 -126
  209. package/framework/agents/integrations/azure-identity.md +0 -148
  210. package/framework/agents/quality/code-analyzer.md +0 -239
  211. package/framework/agents/quality/testing-specialist.md +0 -130
  212. package/framework/hooks/claude-code/notification/approval-reminder.js +0 -57
  213. package/framework/hooks/claude-code/post-tool-use/context-refresh.js +0 -109
  214. package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +0 -78
  215. package/framework/index/troubleshooting-index.json +0 -184
  216. package/framework/rules/testing-standards.md +0 -14
  217. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +0 -230
  218. package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +0 -70
  219. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +0 -256
  220. package/framework/skills/level-1-workflows/morph-phase-clarify/references/clarifications-example.md +0 -117
  221. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +0 -269
  222. package/framework/standards/ai-agents/blazor-ui.md +0 -364
  223. package/framework/standards/architecture/ddd/aggregates.md +0 -120
  224. package/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
  225. package/framework/standards/architecture/ddd/complexity-levels.md +0 -108
  226. package/framework/standards/architecture/ddd/entities.md +0 -99
  227. package/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
  228. package/framework/standards/architecture/ddd/value-objects.md +0 -124
  229. package/framework/standards/backend/api/minimal-api.md +0 -494
  230. package/framework/standards/backend/api/rest.md +0 -492
  231. package/framework/standards/backend/authentication/passkeys.md +0 -428
  232. package/framework/standards/backend/database/ef-core.md +0 -199
  233. package/framework/standards/backend/database/migrations.md +0 -393
  234. package/framework/standards/backend/database/repository-patterns.md +0 -528
  235. package/framework/standards/backend/dotnet/async.md +0 -366
  236. package/framework/standards/backend/dotnet/core.md +0 -117
  237. package/framework/standards/backend/dotnet/di.md +0 -439
  238. package/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  239. package/framework/standards/context/analytics.md +0 -96
  240. package/framework/standards/context/bundles.md +0 -110
  241. package/framework/standards/context/priming.md +0 -78
  242. package/framework/standards/core/architecture.md +0 -185
  243. package/framework/standards/core/coding.md +0 -214
  244. package/framework/standards/core/git-branching-strategy.md +0 -403
  245. package/framework/standards/core/git.md +0 -185
  246. package/framework/standards/core/testing.md +0 -295
  247. package/framework/standards/data/nosql/blob-storage.md +0 -102
  248. package/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  249. package/framework/standards/frontend/blazor/design-checklist.md +0 -222
  250. package/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  251. package/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  252. package/framework/standards/frontend/blazor/html-conversion.md +0 -184
  253. package/framework/standards/frontend/blazor/lifecycle.md +0 -195
  254. package/framework/standards/frontend/blazor/pitfalls.md +0 -198
  255. package/framework/standards/frontend/blazor/state.md +0 -191
  256. package/framework/standards/frontend/design-system/aesthetic-direction.md +0 -213
  257. package/framework/standards/infrastructure/azure/azure.md +0 -624
  258. package/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  259. package/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  260. package/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  261. package/framework/standards/infrastructure/azure/services/functions.md +0 -486
  262. package/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  263. package/framework/standards/infrastructure/azure/services/storage.md +0 -407
  264. package/framework/standards/infrastructure/vercel/vercel-database.md +0 -106
  265. package/framework/standards/integration/api/graphql.md +0 -91
  266. package/framework/standards/integration/api/grpc.md +0 -114
  267. package/framework/standards/integration/api/rest-design.md +0 -95
  268. package/framework/standards/integration/event-driven/cqrs.md +0 -101
  269. package/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  270. package/framework/standards/integration/event-driven/service-bus.md +0 -95
  271. package/framework/standards/observability/logging.md +0 -131
  272. package/framework/standards/observability/metrics.md +0 -121
  273. package/framework/standards/observability/monitoring.md +0 -114
  274. package/framework/standards/observability/tracing.md +0 -132
  275. package/framework/standards/workflows/parallel-execution.md +0 -112
  276. package/framework/standards/workflows/thread-management.md +0 -113
  277. package/framework/templates/code/dotnet/backend/service.cs +0 -139
  278. package/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  279. package/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  280. package/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  281. package/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  282. package/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
  283. package/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
  284. package/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
  285. package/framework/templates/code/dotnet/frontend/component.razor +0 -239
  286. package/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  287. package/framework/templates/infrastructure/azure/README.md +0 -286
  288. package/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  289. package/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  290. package/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  291. package/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  292. package/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  293. package/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  294. package/framework/templates/infrastructure/azure/deploy.sh +0 -208
  295. package/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  296. package/framework/templates/infrastructure/azure/main.bicep +0 -189
  297. package/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  298. package/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  299. package/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  300. package/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  301. package/framework/templates/infrastructure/azure/storage.bicep +0 -106
  302. package/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  303. package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  304. package/framework/templates/integrations/azure-identity-config.cs +0 -288
  305. package/framework/templates/project-structure/dotnet-ddd.md +0 -70
  306. package/framework/templates/saas/subscription.cs +0 -347
  307. package/framework/templates/saas/tenant.cs +0 -338
  308. package/framework/templates/ui/FluentDesignTheme.cs +0 -149
  309. package/framework/templates/ui/MudTheme.cs +0 -281
  310. package/framework/workflows/configs/nodejs-cli.json +0 -40
  311. package/src/commands/standards/context-budget.js +0 -89
  312. package/src/lib/standards/index.js +0 -7
  313. package/src/lib/standards/standards-context-injector.js +0 -302
  314. package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +0 -316
  315. package/src/lib/validators/blazor/blazor-state-validator.js +0 -279
  316. package/src/lib/validators/blazor/blazor-validator.js +0 -369
  317. package/src/lib/validators/blazor/index.js +0 -9
@@ -1,285 +1,72 @@
1
- /**
2
- * Standard Digest Builder
3
- *
4
- * Composes agent briefings from STANDARDS.json digests.
5
- * Reduces context per agent from ~2000-8000 tokens (file reads)
6
- * to ~400-600 tokens (digest inline).
7
- *
8
- * Usage:
9
- * buildAgentBriefing(agentId, phase) → string
10
- * Injected into dispatch taskPrompt as "\n\nConstraints:\n" + briefing
11
- *
12
- * Standards refs in agents.json support two formats:
13
- * Legacy: "core/coding.md" (treated as scope:'all', priority:'required')
14
- * Scoped: { id, scope, priority, anchor }
15
- */
16
-
17
- import { readFileSync, existsSync } from 'fs';
18
- import { join, dirname } from 'path';
19
- import { fileURLToPath } from 'url';
20
- import { shouldInstall, getProjectTags } from '../../lib/stack-filter.js';
21
-
22
- const __dirname = dirname(fileURLToPath(import.meta.url));
23
-
24
- const AGENTS_JSON_PATH = join(__dirname, '../../../framework/agents.json');
25
- const STANDARDS_JSON_PATH = join(__dirname, '../../../framework/standards/STANDARDS.json');
26
-
27
- /** Token budget threshold — warn if briefing exceeds this */
28
- const TOKEN_BUDGET_THRESHOLD = 8000;
29
-
30
- let _agentsCache = null;
31
- let _standardsCache = null;
32
-
33
- // ─────────────────────────────────────────────────────────────────────────────
34
- // Loaders
35
- // ─────────────────────────────────────────────────────────────────────────────
36
-
37
- /** Load and cache agents.json */
38
- function loadAgents() {
39
- if (_agentsCache) return _agentsCache;
40
- if (!existsSync(AGENTS_JSON_PATH)) return { agents: {} };
41
- try {
42
- _agentsCache = JSON.parse(readFileSync(AGENTS_JSON_PATH, 'utf8'));
43
- return _agentsCache;
44
- } catch {
45
- return { agents: {} };
46
- }
47
- }
48
-
49
- /** Load STANDARDS.json and build path/id lookup maps (module-level cache) */
50
- function loadStandards() {
51
- if (_standardsCache) return _standardsCache;
52
- if (!existsSync(STANDARDS_JSON_PATH)) {
53
- _standardsCache = { byPath: new Map(), byId: new Map() };
54
- return _standardsCache;
55
- }
56
- try {
57
- const raw = JSON.parse(readFileSync(STANDARDS_JSON_PATH, 'utf8'));
58
- const byPath = new Map();
59
- const byId = new Map();
60
- for (const entry of raw.standards || []) {
61
- byPath.set(entry.path, entry);
62
- byId.set(entry.id, entry);
63
- }
64
- _standardsCache = { byPath, byId };
65
- return _standardsCache;
66
- } catch {
67
- _standardsCache = { byPath: new Map(), byId: new Map() };
68
- return _standardsCache;
69
- }
70
- }
71
-
72
- /**
73
- * Load project config.json from .morph/config.json.
74
- *
75
- * @param {string} [projectPath] - Override project path (defaults to cwd)
76
- * @returns {Object|null}
77
- */
78
- function loadProjectConfig(projectPath) {
79
- const configPath = join(projectPath || process.cwd(), '.morph', 'config.json');
80
- try {
81
- if (!existsSync(configPath)) return null;
82
- return JSON.parse(readFileSync(configPath, 'utf8'));
83
- } catch {
84
- return null;
85
- }
86
- }
87
-
88
- /**
89
- * Estimate token count for a text string.
90
- * Uses ~4 chars/token heuristic (conservative for English + code).
91
- *
92
- * @param {string} text
93
- * @returns {number}
94
- */
95
- export function estimateTokens(text) {
96
- if (!text) return 0;
97
- return Math.ceil(text.length / 4);
98
- }
99
-
100
- // ─────────────────────────────────────────────────────────────────────────────
101
- // Helpers
102
- // ─────────────────────────────────────────────────────────────────────────────
103
-
104
- /**
105
- * Normalize a standards reference to canonical shape.
106
- * Supports legacy string format and new scoped object format.
107
- *
108
- * @param {string|Object} ref
109
- * @returns {{ id?: string, path?: string, scope: string, priority: string, anchor?: string }}
110
- */
111
- function normalizeRef(ref) {
112
- if (typeof ref === 'string') {
113
- return { path: ref, scope: 'all', priority: 'required' };
114
- }
115
- return {
116
- id: ref.id,
117
- path: ref.path,
118
- scope: ref.scope || 'all',
119
- priority: ref.priority || 'required',
120
- anchor: ref.anchor,
121
- };
122
- }
123
-
124
- /**
125
- * Resolve a normalized ref to a STANDARDS.json entry.
126
- * Tries id lookup first, then exact path, then suffix match for short paths.
127
- *
128
- * @param {{ id?: string, path?: string }} ref
129
- * @param {{ byPath: Map, byId: Map }} standards
130
- * @returns {Object|null}
131
- */
132
- function resolveEntry(ref, standards) {
133
- if (ref.id) {
134
- const entry = standards.byId.get(ref.id);
135
- if (entry) return entry;
136
- }
137
- if (ref.path) {
138
- const entry = standards.byPath.get(ref.path);
139
- if (entry) return entry;
140
-
141
- // Some agents use short paths like "azure.md" — try suffix match
142
- for (const [, e] of standards.byPath) {
143
- if (e.path.endsWith('/' + ref.path)) return e;
144
- }
145
- }
146
- return null;
147
- }
148
-
149
- /**
150
- * Format a single standards entry as a briefing line.
151
- *
152
- * priority='required' with digest → inline digest text
153
- * priority='reference' → path + optional anchor only
154
- * no digest → path reference fallback
155
- *
156
- * @param {Object} entry - STANDARDS.json entry
157
- * @param {string} priority - 'required' | 'reference'
158
- * @param {string} [anchor] - specific anchor key from entry.anchors
159
- * @returns {string}
160
- */
161
- function formatBriefingLine(entry, priority, anchor) {
162
- const anchorFrag = anchor && entry.anchors?.[anchor] ? entry.anchors[anchor] : '';
163
-
164
- if (priority === 'required' && entry.digest) {
165
- const ref = anchorFrag ? ` (ref: ${entry.path}${anchorFrag})` : '';
166
- return `[${entry.name.toUpperCase()}] ${entry.digest}${ref}`;
167
- }
168
-
169
- if (priority === 'reference') {
170
- return `[REF: ${entry.path}${anchorFrag}]`;
171
- }
172
-
173
- // No digest — inject path reference as fallback
174
- return `[REF: ${entry.path}${anchorFrag}]`;
175
- }
176
-
177
- // ─────────────────────────────────────────────────────────────────────────────
178
- // Public API
179
- // ─────────────────────────────────────────────────────────────────────────────
180
-
181
- /**
182
- * Build an agent briefing string for injection into taskPrompt.
183
- * Returns empty string when agent not found, has no standards, or all refs
184
- * are filtered by scope or stack.
185
- *
186
- * @param {string} agentId - Agent ID from agents.json
187
- * @param {string} phase - Current phase (design|tasks|implement)
188
- * @param {Object} [opts] - Options
189
- * @param {string} [opts.projectPath] - Override project path (defaults to cwd)
190
- * @returns {string} Formatted briefing or ''
191
- */
192
- export function buildAgentBriefing(agentId, phase, opts = {}) {
193
- const agents = loadAgents();
194
- const agentData = agents.agents?.[agentId];
195
- if (!agentData) return '';
196
-
197
- const standardsRefs = agentData.standards || [];
198
- if (standardsRefs.length === 0) return '';
199
-
200
- const standards = loadStandards();
201
-
202
- // Load project tags for stack filtering
203
- const config = loadProjectConfig(opts.projectPath);
204
- const projectTags = config ? getProjectTags(config) : [];
205
-
206
- const lines = [];
207
-
208
- for (const rawRef of standardsRefs) {
209
- const ref = normalizeRef(rawRef);
210
-
211
- // Scope filtering: skip refs scoped to a different phase
212
- if (ref.scope !== 'all' && ref.scope !== phase) continue;
213
-
214
- const entry = resolveEntry(ref, standards);
215
- if (!entry) {
216
- // No entry found in registry — emit a path reference as fallback
217
- const path = ref.path || ref.id;
218
- if (path) lines.push(`[REF: ${path}]`);
219
- continue;
220
- }
221
-
222
- // Stack filtering: skip standards not relevant to this project's stack
223
- if (projectTags.length > 0 && !shouldInstall(entry.stacks || ['*'], projectTags)) continue;
224
-
225
- const line = formatBriefingLine(entry, ref.priority, ref.anchor);
226
- if (line) lines.push(line);
227
- }
228
-
229
- const briefing = lines.length > 0 ? lines.join('\n') : '';
230
-
231
- // Token budget warning
232
- if (briefing) {
233
- const tokens = estimateTokens(briefing);
234
- if (tokens > TOKEN_BUDGET_THRESHOLD) {
235
- process.stderr.write(
236
- `[digest-builder] Warning: briefing for agent '${agentId}' is ~${tokens} tokens (threshold: ${TOKEN_BUDGET_THRESHOLD})\n`
237
- );
238
- }
239
- }
240
-
241
- return briefing;
242
- }
243
-
244
- /**
245
- * Build a read-only validation task prompt for Tier-4 validator agents.
246
- * Uses hook_behavior.validates[] from agents.json.
247
- *
248
- * @param {string} agentId - Agent ID (must be tier 4 with hook_behavior)
249
- * @param {string} [taskId] - Optional task ID being validated
250
- * @returns {string} Validator task prompt or ''
251
- */
252
- export function buildValidatorPrompt(agentId, taskId) {
253
- const agents = loadAgents();
254
- const agentData = agents.agents?.[agentId];
255
- if (!agentData?.hook_behavior) return '';
256
-
257
- const validates = agentData.hook_behavior.validates || [];
258
- const severity = agentData.hook_behavior.severity || 'error';
259
- const blocksOnFail = agentData.hook_behavior.blocks_on_fail ?? true;
260
- const taskSuffix = taskId ? ` for task ${taskId}` : '';
261
-
262
- const lines = [
263
- `You are ${agentData.title || agentId} (Tier 4 Validator). Mode: READ-ONLY validation${taskSuffix}.`,
264
- `DO NOT edit any files. Review the current implementation for the following violations:`,
265
- ``,
266
- `Checks (severity: ${severity}):`,
267
- ...validates.map(v => ` - ${v}`),
268
- ``,
269
- `Output a single JSON line: { "passed": boolean, "issues": [{ "file": "path/to/file", "line": 0, "message": "description", "rule": "rule-name" }] }`,
270
- blocksOnFail
271
- ? `BLOCKING: if any issues found, implementation must be fixed before task can complete.`
272
- : `NON-BLOCKING: issues are warnings only — task completion is not blocked.`,
273
- ];
274
-
275
- return lines.join('\n');
276
- }
277
-
278
- /**
279
- * Invalidate module-level caches.
280
- * Used in tests to ensure a fresh load of agents.json / STANDARDS.json.
281
- */
282
- export function clearCache() {
283
- _agentsCache = null;
284
- _standardsCache = null;
285
- }
1
+ /**
2
+ * Validator Prompt Builder
3
+ *
4
+ * Generates read-only validation task prompts for Tier-4 validator agents
5
+ * from agents.json hook_behavior configuration.
6
+ *
7
+ * Used by dispatch-agents.js in --mode validate.
8
+ */
9
+
10
+ import { readFileSync, existsSync } from 'fs';
11
+ import { join, dirname } from 'path';
12
+ import { fileURLToPath } from 'url';
13
+
14
+ const __dirname = dirname(fileURLToPath(import.meta.url));
15
+
16
+ const AGENTS_JSON_PATH = join(__dirname, '../../../framework/agents.json');
17
+
18
+ let _agentsCache = null;
19
+
20
+ /** Load and cache agents.json */
21
+ function loadAgents() {
22
+ if (_agentsCache) return _agentsCache;
23
+ if (!existsSync(AGENTS_JSON_PATH)) return { agents: {} };
24
+ try {
25
+ _agentsCache = JSON.parse(readFileSync(AGENTS_JSON_PATH, 'utf8'));
26
+ return _agentsCache;
27
+ } catch {
28
+ return { agents: {} };
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Build a read-only validation task prompt for Tier-4 validator agents.
34
+ * Uses hook_behavior.validates[] from agents.json.
35
+ *
36
+ * @param {string} agentId - Agent ID (must be tier 4 with hook_behavior)
37
+ * @param {string} [taskId] - Optional task ID being validated
38
+ * @returns {string} Validator task prompt or ''
39
+ */
40
+ export function buildValidatorPrompt(agentId, taskId) {
41
+ const agents = loadAgents();
42
+ const agentData = agents.agents?.[agentId];
43
+ if (!agentData?.hook_behavior) return '';
44
+
45
+ const validates = agentData.hook_behavior.validates || [];
46
+ const severity = agentData.hook_behavior.severity || 'error';
47
+ const blocksOnFail = agentData.hook_behavior.blocks_on_fail ?? true;
48
+ const taskSuffix = taskId ? ` for task ${taskId}` : '';
49
+
50
+ const lines = [
51
+ `You are ${agentData.title || agentId} (Tier 4 Validator). Mode: READ-ONLY validation${taskSuffix}.`,
52
+ `DO NOT edit any files. Review the current implementation for the following violations:`,
53
+ ``,
54
+ `Checks (severity: ${severity}):`,
55
+ ...validates.map(v => ` - ${v}`),
56
+ ``,
57
+ `Output a single JSON line: { "passed": boolean, "issues": [{ "file": "path/to/file", "line": 0, "message": "description", "rule": "rule-name" }] }`,
58
+ blocksOnFail
59
+ ? `BLOCKING: if any issues found, implementation must be fixed before task can complete.`
60
+ : `NON-BLOCKING: issues are warnings only — task completion is not blocked.`,
61
+ ];
62
+
63
+ return lines.join('\n');
64
+ }
65
+
66
+ /**
67
+ * Invalidate module-level caches.
68
+ * Used in tests to ensure a fresh load of agents.json.
69
+ */
70
+ export function clearCache() {
71
+ _agentsCache = null;
72
+ }
@@ -82,7 +82,7 @@ export function parseTaskList(content) {
82
82
  // ============================================================================
83
83
 
84
84
  /**
85
- * Parse tasks.md and return a map of { parallelGroup -> taskId[] }.
85
+ * Parse tasks.md and return a map of { group -> taskId[] }.
86
86
  * Gracefully returns {} if the file doesn't exist or is unparseable.
87
87
  *
88
88
  * @param {string} tasksPath - Absolute path to tasks.md
@@ -187,6 +187,10 @@ export async function ensureTaskList(feature, featureName, cwd = process.cwd())
187
187
  * After modifying taskList, sync the counter fields back to feature.tasks.
188
188
  * tasks.total is derived from the actual taskList length (not trusted from state).
189
189
  *
190
+ * @deprecated Prefer reading directly from feature.taskList. Counter fields
191
+ * (feature.tasks) duplicate native Claude Code task tracking. This function
192
+ * is kept for backward compatibility but will be removed in a future version.
193
+ *
190
194
  * @param {Object} feature - Feature state object (mutated in place)
191
195
  */
192
196
  export function syncCounters(feature) {
@@ -196,8 +200,10 @@ export function syncCounters(feature) {
196
200
  feature.tasks = { total: 0, completed: 0, inProgress: 0, pending: 0 };
197
201
  }
198
202
  const list = feature.taskList || [];
199
- feature.tasks.total = list.length;
200
- feature.tasks.completed = list.filter(t => t.status === 'completed').length;
201
- feature.tasks.inProgress = list.filter(t => t.status === 'in_progress').length;
202
- feature.tasks.pending = list.filter(t => t.status === 'pending').length;
203
+ // Exclude expanded tasks — they are replaced by their sub-tasks
204
+ const active = list.filter(t => t.status !== 'expanded');
205
+ feature.tasks.total = active.length;
206
+ feature.tasks.completed = active.filter(t => t.status === 'completed').length;
207
+ feature.tasks.inProgress = active.filter(t => t.status === 'in_progress').length;
208
+ feature.tasks.pending = active.filter(t => t.status === 'pending').length;
203
209
  }