@polymorphism-tech/morph-spec 4.12.0 → 4.14.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 (316) hide show
  1. package/CLAUDE.md +7 -7
  2. package/README.md +28 -34
  3. package/bin/morph-spec.js +41 -24
  4. package/bin/task-manager.js +962 -1341
  5. package/bin/validate.js +1 -1
  6. package/claude-plugin.json +1 -1
  7. package/docs/CHEATSHEET.md +14 -16
  8. package/docs/QUICKSTART.md +15 -15
  9. package/framework/CLAUDE.md +5 -2
  10. package/framework/agents/README.md +3 -4
  11. package/framework/agents/ai-agents/ai-system-architect.md +6 -10
  12. package/framework/agents/architecture/seo-growth-hacker.md +166 -326
  13. package/framework/agents/architecture/standards-architect.md +21 -31
  14. package/framework/agents/backend/dotnet-senior.md +160 -86
  15. package/framework/agents/backend/ef-modeler.md +2 -6
  16. package/framework/agents/backend/hangfire-orchestrator.md +8 -9
  17. package/framework/agents/backend/ms-agent-expert.md +1 -1
  18. package/framework/agents/frontend/nextjs-expert.md +198 -133
  19. package/framework/agents/frontend/ui-ux-designer.md +226 -267
  20. package/framework/agents/infrastructure/infra-architect.md +191 -27
  21. package/framework/agents/integrations/clerk-auth.md +19 -26
  22. package/framework/agents/integrations/hangfire-integration.md +1 -4
  23. package/framework/agents.json +1084 -2278
  24. package/framework/commands/morph-apply.md +4 -6
  25. package/framework/commands/morph-preflight.md +192 -269
  26. package/framework/commands/morph-proposal.md +210 -238
  27. package/framework/commands/morph-status.md +72 -92
  28. package/framework/commands/morph-troubleshoot.md +6 -13
  29. package/framework/hooks/README.md +1 -6
  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/phase-utils.js +4 -8
  42. package/framework/hooks/shared/state-reader.js +34 -3
  43. package/framework/phases.json +162 -200
  44. package/framework/rules/ai-agents-standards.md +15 -0
  45. package/framework/rules/asaas-standards.md +13 -0
  46. package/framework/rules/clerk-standards.md +13 -0
  47. package/framework/rules/csharp-standards.md +8 -4
  48. package/framework/rules/data-standards.md +18 -0
  49. package/framework/rules/dotnet-templates.md +87 -0
  50. package/framework/rules/frontend-standards.md +13 -13
  51. package/framework/rules/hangfire-standards.md +13 -0
  52. package/framework/rules/infrastructure-standards.md +27 -16
  53. package/framework/rules/morph-workflow.md +73 -13
  54. package/framework/rules/nextjs-standards.md +1 -0
  55. package/framework/rules/nextjs-templates.md +40 -0
  56. package/framework/rules/resend-standards.md +12 -0
  57. package/framework/rules/supabase-standards.md +29 -0
  58. package/framework/skills/README.md +6 -8
  59. package/framework/skills/level-0-meta/mcp-registry.json +21 -99
  60. package/framework/{standards/ai-agents/team-orchestration.md → skills/level-0-meta/morph-agent-teams/SKILL.md} +472 -479
  61. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +28 -1
  62. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
  63. package/framework/skills/level-0-meta/morph-code-review/SKILL.md +1 -5
  64. package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +1 -1
  65. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +23 -41
  66. package/framework/skills/level-0-meta/morph-init/SKILL.md +18 -14
  67. package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +225 -0
  68. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +20 -0
  69. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +4 -8
  70. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +15 -59
  71. package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +7 -19
  72. package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +8 -8
  73. package/framework/skills/level-1-workflows/README.md +1 -1
  74. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +49 -50
  75. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +57 -123
  76. package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +5 -50
  77. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +1 -1
  78. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +127 -159
  79. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +1 -1
  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 +143 -172
  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 +57 -77
  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 -2369
  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 +1 -5
  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/phase/phase-reset.js +1 -1
  159. package/src/commands/project/doctor.js +10 -32
  160. package/src/commands/project/init.js +12 -0
  161. package/src/commands/project/status.js +6 -12
  162. package/src/commands/scaffold/scaffold.js +131 -0
  163. package/src/commands/scope/escalate.js +1 -1
  164. package/src/commands/state/advance-phase.js +15 -29
  165. package/src/commands/state/state.js +20 -5
  166. package/src/commands/tasks/task.js +0 -30
  167. package/src/commands/validation/validate-feature.js +3 -10
  168. package/src/core/paths/output-schema.js +12 -13
  169. package/src/core/state/phase-state-machine.js +211 -217
  170. package/src/core/state/state-manager.js +9 -9
  171. package/src/lib/agents/agents-manager.js +2 -2
  172. package/src/lib/agents/output-collector.js +1 -2
  173. package/src/lib/detectors/design-system-detector.js +4 -4
  174. package/src/lib/detectors/index.js +1 -11
  175. package/src/lib/generators/architecture-scanner.js +640 -0
  176. package/src/lib/generators/context-generator.js +3 -3
  177. package/src/lib/generators/design-system-generator.js +508 -587
  178. package/src/lib/generators/index.js +12 -10
  179. package/src/lib/generators/metadata-extractor.js +386 -387
  180. package/src/lib/generators/recap-generator.js +4 -4
  181. package/src/lib/generators/scaffold-generator.js +317 -0
  182. package/src/lib/generators/settings-generator.js +0 -1
  183. package/src/lib/phase-chain/phase-validator.js +64 -42
  184. package/src/lib/stack/stack-profile.js +2 -2
  185. package/src/lib/standards/digest-builder.js +72 -285
  186. package/src/lib/tasks/task-parser.js +11 -5
  187. package/src/lib/validators/architecture/architecture-validator.js +259 -387
  188. package/src/lib/validators/content/content-validator.js +287 -287
  189. package/src/lib/validators/css/css-validator.js +340 -352
  190. package/src/lib/validators/packages/package-validator.js +347 -360
  191. package/src/lib/validators/shared/issue-counter.js +14 -18
  192. package/src/lib/validators/validation-runner.js +3 -19
  193. package/src/scripts/setup-infra.js +1 -1
  194. package/src/utils/agents-installer.js +61 -10
  195. package/src/utils/file-copier.js +1 -0
  196. package/src/utils/hooks-installer.js +11 -19
  197. package/src/utils/skills-installer.js +178 -178
  198. package/framework/agents/architecture/prompt-engineer.md +0 -195
  199. package/framework/agents/backend/api-designer.md +0 -106
  200. package/framework/agents/frontend/blazor-builder.md +0 -229
  201. package/framework/agents/frontend/nextjs-ui-specialist.md +0 -218
  202. package/framework/agents/infrastructure/azure-architect.md +0 -150
  203. package/framework/agents/infrastructure/azure-deploy-specialist.md +0 -707
  204. package/framework/agents/infrastructure/bicep-architect.md +0 -132
  205. package/framework/agents/infrastructure/container-specialist.md +0 -137
  206. package/framework/agents/infrastructure/devops-engineer.md +0 -126
  207. package/framework/agents/integrations/azure-identity.md +0 -148
  208. package/framework/agents/quality/code-analyzer.md +0 -239
  209. package/framework/agents/quality/testing-specialist.md +0 -130
  210. package/framework/hooks/claude-code/notification/approval-reminder.js +0 -57
  211. package/framework/hooks/claude-code/post-tool-use/context-refresh.js +0 -109
  212. package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +0 -78
  213. package/framework/index/troubleshooting-index.json +0 -184
  214. package/framework/rules/testing-standards.md +0 -14
  215. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +0 -230
  216. package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +0 -70
  217. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +0 -256
  218. package/framework/skills/level-1-workflows/morph-phase-clarify/references/clarifications-example.md +0 -117
  219. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +0 -269
  220. package/framework/standards/ai-agents/blazor-ui.md +0 -364
  221. package/framework/standards/architecture/ddd/aggregates.md +0 -120
  222. package/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
  223. package/framework/standards/architecture/ddd/complexity-levels.md +0 -108
  224. package/framework/standards/architecture/ddd/entities.md +0 -99
  225. package/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
  226. package/framework/standards/architecture/ddd/value-objects.md +0 -124
  227. package/framework/standards/backend/api/minimal-api.md +0 -494
  228. package/framework/standards/backend/api/rest.md +0 -492
  229. package/framework/standards/backend/authentication/passkeys.md +0 -428
  230. package/framework/standards/backend/database/ef-core.md +0 -199
  231. package/framework/standards/backend/database/migrations.md +0 -393
  232. package/framework/standards/backend/database/repository-patterns.md +0 -528
  233. package/framework/standards/backend/dotnet/async.md +0 -366
  234. package/framework/standards/backend/dotnet/core.md +0 -117
  235. package/framework/standards/backend/dotnet/di.md +0 -439
  236. package/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  237. package/framework/standards/context/analytics.md +0 -96
  238. package/framework/standards/context/bundles.md +0 -110
  239. package/framework/standards/context/priming.md +0 -78
  240. package/framework/standards/core/architecture.md +0 -185
  241. package/framework/standards/core/coding.md +0 -214
  242. package/framework/standards/core/git-branching-strategy.md +0 -403
  243. package/framework/standards/core/git.md +0 -185
  244. package/framework/standards/core/testing.md +0 -295
  245. package/framework/standards/data/nosql/blob-storage.md +0 -102
  246. package/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  247. package/framework/standards/frontend/blazor/design-checklist.md +0 -222
  248. package/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  249. package/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  250. package/framework/standards/frontend/blazor/html-conversion.md +0 -184
  251. package/framework/standards/frontend/blazor/lifecycle.md +0 -195
  252. package/framework/standards/frontend/blazor/pitfalls.md +0 -198
  253. package/framework/standards/frontend/blazor/state.md +0 -191
  254. package/framework/standards/frontend/design-system/aesthetic-direction.md +0 -266
  255. package/framework/standards/frontend/design-system/design-trends.md +0 -171
  256. package/framework/standards/infrastructure/azure/azure.md +0 -624
  257. package/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  258. package/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  259. package/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  260. package/framework/standards/infrastructure/azure/services/functions.md +0 -486
  261. package/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  262. package/framework/standards/infrastructure/azure/services/storage.md +0 -407
  263. package/framework/standards/infrastructure/vercel/vercel-database.md +0 -106
  264. package/framework/standards/integration/api/graphql.md +0 -91
  265. package/framework/standards/integration/api/grpc.md +0 -114
  266. package/framework/standards/integration/api/rest-design.md +0 -95
  267. package/framework/standards/integration/event-driven/cqrs.md +0 -101
  268. package/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  269. package/framework/standards/integration/event-driven/service-bus.md +0 -95
  270. package/framework/standards/observability/logging.md +0 -131
  271. package/framework/standards/observability/metrics.md +0 -121
  272. package/framework/standards/observability/monitoring.md +0 -114
  273. package/framework/standards/observability/tracing.md +0 -132
  274. package/framework/standards/workflows/parallel-execution.md +0 -112
  275. package/framework/standards/workflows/thread-management.md +0 -113
  276. package/framework/templates/code/dotnet/backend/service.cs +0 -139
  277. package/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  278. package/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  279. package/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  280. package/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  281. package/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
  282. package/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
  283. package/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
  284. package/framework/templates/code/dotnet/frontend/component.razor +0 -239
  285. package/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  286. package/framework/templates/infrastructure/azure/README.md +0 -286
  287. package/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  288. package/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  289. package/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  290. package/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  291. package/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  292. package/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  293. package/framework/templates/infrastructure/azure/deploy.sh +0 -208
  294. package/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  295. package/framework/templates/infrastructure/azure/main.bicep +0 -189
  296. package/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  297. package/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  298. package/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  299. package/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  300. package/framework/templates/infrastructure/azure/storage.bicep +0 -106
  301. package/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  302. package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  303. package/framework/templates/integrations/azure-identity-config.cs +0 -288
  304. package/framework/templates/project-structure/dotnet-ddd.md +0 -70
  305. package/framework/templates/saas/subscription.cs +0 -347
  306. package/framework/templates/saas/tenant.cs +0 -338
  307. package/framework/templates/ui/FluentDesignTheme.cs +0 -149
  308. package/framework/templates/ui/MudTheme.cs +0 -281
  309. package/framework/workflows/configs/nodejs-cli.json +0 -40
  310. package/src/commands/standards/context-budget.js +0 -89
  311. package/src/lib/standards/index.js +0 -7
  312. package/src/lib/standards/standards-context-injector.js +0 -302
  313. package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +0 -316
  314. package/src/lib/validators/blazor/blazor-state-validator.js +0 -279
  315. package/src/lib/validators/blazor/blazor-validator.js +0 -369
  316. 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
  }