@polymorphism-tech/morph-spec 4.12.0 → 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 (314) 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 +215 -1453
  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/validator-feedback.js +4 -6
  30. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +12 -7
  31. package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +2 -2
  32. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +2 -2
  33. package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +5 -10
  34. package/framework/hooks/claude-code/session-start/inject-morph-context.js +63 -30
  35. package/framework/hooks/claude-code/session-start/resume-context.js +77 -0
  36. package/framework/hooks/claude-code/statusline.py +4 -5
  37. package/framework/hooks/claude-code/stop/validate-completion.js +4 -4
  38. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +8 -8
  39. package/framework/hooks/shared/compact-restore.js +28 -5
  40. package/framework/hooks/shared/phase-utils.js +4 -8
  41. package/framework/hooks/shared/state-reader.js +34 -3
  42. package/framework/phases.json +7 -45
  43. package/framework/rules/ai-agents-standards.md +15 -0
  44. package/framework/rules/asaas-standards.md +13 -0
  45. package/framework/rules/clerk-standards.md +13 -0
  46. package/framework/rules/csharp-standards.md +8 -4
  47. package/framework/rules/data-standards.md +18 -0
  48. package/framework/rules/dotnet-templates.md +87 -0
  49. package/framework/rules/frontend-standards.md +13 -13
  50. package/framework/rules/hangfire-standards.md +13 -0
  51. package/framework/rules/infrastructure-standards.md +27 -16
  52. package/framework/rules/morph-workflow.md +73 -13
  53. package/framework/rules/nextjs-standards.md +1 -0
  54. package/framework/rules/nextjs-templates.md +40 -0
  55. package/framework/rules/resend-standards.md +12 -0
  56. package/framework/rules/supabase-standards.md +29 -0
  57. package/framework/skills/README.md +6 -8
  58. package/framework/skills/level-0-meta/mcp-registry.json +21 -99
  59. package/framework/{standards/ai-agents/team-orchestration.md → skills/level-0-meta/morph-agent-teams/SKILL.md} +472 -479
  60. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +28 -1
  61. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
  62. package/framework/skills/level-0-meta/morph-code-review/SKILL.md +1 -5
  63. package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +1 -1
  64. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +23 -41
  65. package/framework/skills/level-0-meta/morph-init/SKILL.md +18 -14
  66. package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +225 -0
  67. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +20 -0
  68. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +4 -8
  69. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +15 -59
  70. package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +7 -19
  71. package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +8 -8
  72. package/framework/skills/level-1-workflows/README.md +1 -1
  73. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +49 -50
  74. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +58 -124
  75. package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +5 -50
  76. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +1 -1
  77. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +127 -159
  78. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +4 -3
  79. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +2 -2
  80. package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +1 -1
  81. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +17 -13
  82. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +22 -40
  83. package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +0 -2
  84. package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +5 -5
  85. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +57 -77
  86. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
  87. package/framework/squad-templates/backend-only.json +6 -6
  88. package/framework/squad-templates/frontend-only.json +17 -8
  89. package/framework/squad-templates/full-stack.json +29 -24
  90. package/framework/standards/STANDARDS.json +1021 -2369
  91. package/framework/standards/backend/dotnet/fluent-validation-vsa.md +200 -0
  92. package/framework/standards/backend/dotnet/result-pattern.md +213 -0
  93. package/framework/standards/backend/dotnet/scalar-ui.md +172 -0
  94. package/framework/standards/backend/dotnet/scrutor.md +158 -0
  95. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +274 -0
  96. package/framework/standards/frontend/nextjs/motion-patterns.md +1 -1
  97. package/framework/standards/infrastructure/supabase/mcp-setup.md +83 -193
  98. package/framework/standards/integration/mcp/mcp-tools.md +91 -77
  99. package/framework/templates/IDE-SNIPPETS.md +2 -6
  100. package/framework/templates/README.md +709 -814
  101. package/framework/templates/REGISTRY.json +223 -762
  102. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -0
  103. package/framework/templates/code/dotnet/abstractions/error.cs +60 -0
  104. package/framework/templates/code/dotnet/abstractions/handler.cs +12 -0
  105. package/framework/templates/code/dotnet/abstractions/result.cs +74 -0
  106. package/framework/templates/code/dotnet/backend/repository.cs +148 -141
  107. package/framework/templates/code/dotnet/constants/api-tags.cs +6 -0
  108. package/framework/templates/code/dotnet/exceptions/exception-handler.cs +32 -0
  109. package/framework/templates/code/dotnet/extensions/database-extensions.cs +20 -0
  110. package/framework/templates/code/dotnet/extensions/handler-registration.cs +38 -0
  111. package/framework/templates/code/dotnet/extensions/health-checks.cs +24 -0
  112. package/framework/templates/code/dotnet/extensions/map-endpoints.cs +35 -0
  113. package/framework/templates/code/dotnet/extensions/result-extensions.cs +29 -0
  114. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -0
  115. package/framework/templates/code/dotnet/feature/entity.cs.hbs +8 -0
  116. package/framework/templates/code/dotnet/feature/errors.cs.hbs +8 -0
  117. package/framework/templates/code/dotnet/feature/handler.cs.hbs +24 -0
  118. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -0
  119. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -0
  120. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -0
  121. package/framework/templates/code/dotnet/jobs/job.cs +21 -17
  122. package/framework/templates/code/dotnet/pipelines/logging-decorator.cs +31 -0
  123. package/framework/templates/code/dotnet/pipelines/validation-decorator.cs +97 -0
  124. package/framework/templates/code/dotnet/test.cs +192 -106
  125. package/framework/templates/context/ARCHITECTURE.md +89 -0
  126. package/framework/templates/context/CONTEXT-FEATURE.md +2 -2
  127. package/framework/templates/context/CONTEXT.md +180 -181
  128. package/framework/templates/context/design-system.md +1 -5
  129. package/framework/templates/docs/onboarding.md +2 -3
  130. package/framework/templates/docs/proposal.md +171 -182
  131. package/framework/templates/docs/spec.md +1 -3
  132. package/framework/templates/docs/ui-components.md +0 -72
  133. package/framework/templates/examples/design-system-examples.md +4 -4
  134. package/framework/templates/feature/decisions.md +0 -66
  135. package/framework/templates/feature/recap.md +1 -2
  136. package/framework/templates/infrastructure/github/README.md +56 -593
  137. package/framework/templates/integrations/clerk-config.cs +0 -41
  138. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  139. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -2
  140. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +83 -126
  141. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +2 -2
  142. package/framework/templates/project/validate.js +2 -4
  143. package/framework/templates/ui/design-system.css +1 -1
  144. package/framework/workflows/README.md +8 -8
  145. package/framework/workflows/configs/fast-track.json +51 -0
  146. package/framework/workflows/configs/full.json +68 -0
  147. package/framework/workflows/configs/standard.json +7 -3
  148. package/framework/workflows/docs/STORY-DRIVEN-DEVELOPMENT.md +1 -1
  149. package/framework/workflows/docs/enforcement-pipeline.md +18 -19
  150. package/framework/workflows/docs/full-morph.md +69 -76
  151. package/framework/workflows/docs/standard.md +49 -44
  152. package/framework/workflows/docs/ui-refresh.md +1 -1
  153. package/package.json +3 -3
  154. package/src/commands/agents/dispatch-agents.js +55 -116
  155. package/src/commands/context/context-refresh.js +79 -0
  156. package/src/commands/phase/phase-reset.js +1 -1
  157. package/src/commands/project/doctor.js +10 -32
  158. package/src/commands/project/init.js +12 -0
  159. package/src/commands/project/status.js +6 -12
  160. package/src/commands/scaffold/scaffold.js +131 -0
  161. package/src/commands/scope/escalate.js +1 -1
  162. package/src/commands/state/advance-phase.js +15 -29
  163. package/src/commands/state/state.js +20 -5
  164. package/src/commands/tasks/task.js +0 -30
  165. package/src/commands/validation/validate-feature.js +3 -10
  166. package/src/core/paths/output-schema.js +12 -13
  167. package/src/core/state/phase-state-machine.js +211 -217
  168. package/src/core/state/state-manager.js +9 -9
  169. package/src/lib/agents/agents-manager.js +2 -2
  170. package/src/lib/agents/output-collector.js +1 -2
  171. package/src/lib/detectors/design-system-detector.js +4 -4
  172. package/src/lib/detectors/index.js +1 -11
  173. package/src/lib/generators/architecture-scanner.js +640 -0
  174. package/src/lib/generators/context-generator.js +3 -3
  175. package/src/lib/generators/design-system-generator.js +508 -587
  176. package/src/lib/generators/index.js +12 -10
  177. package/src/lib/generators/metadata-extractor.js +386 -387
  178. package/src/lib/generators/recap-generator.js +4 -4
  179. package/src/lib/generators/scaffold-generator.js +317 -0
  180. package/src/lib/generators/settings-generator.js +0 -1
  181. package/src/lib/phase-chain/phase-validator.js +64 -42
  182. package/src/lib/stack/stack-profile.js +2 -2
  183. package/src/lib/standards/digest-builder.js +72 -285
  184. package/src/lib/tasks/task-parser.js +11 -5
  185. package/src/lib/validators/architecture/architecture-validator.js +259 -387
  186. package/src/lib/validators/content/content-validator.js +287 -287
  187. package/src/lib/validators/css/css-validator.js +340 -352
  188. package/src/lib/validators/packages/package-validator.js +347 -360
  189. package/src/lib/validators/shared/issue-counter.js +14 -18
  190. package/src/lib/validators/validation-runner.js +3 -19
  191. package/src/scripts/setup-infra.js +1 -1
  192. package/src/utils/agents-installer.js +24 -3
  193. package/src/utils/file-copier.js +1 -0
  194. package/src/utils/hooks-installer.js +11 -19
  195. package/src/utils/skills-installer.js +178 -178
  196. package/framework/agents/architecture/prompt-engineer.md +0 -195
  197. package/framework/agents/backend/api-designer.md +0 -106
  198. package/framework/agents/frontend/blazor-builder.md +0 -229
  199. package/framework/agents/frontend/nextjs-ui-specialist.md +0 -218
  200. package/framework/agents/infrastructure/azure-architect.md +0 -150
  201. package/framework/agents/infrastructure/azure-deploy-specialist.md +0 -707
  202. package/framework/agents/infrastructure/bicep-architect.md +0 -132
  203. package/framework/agents/infrastructure/container-specialist.md +0 -137
  204. package/framework/agents/infrastructure/devops-engineer.md +0 -126
  205. package/framework/agents/integrations/azure-identity.md +0 -148
  206. package/framework/agents/quality/code-analyzer.md +0 -239
  207. package/framework/agents/quality/testing-specialist.md +0 -130
  208. package/framework/hooks/claude-code/notification/approval-reminder.js +0 -57
  209. package/framework/hooks/claude-code/post-tool-use/context-refresh.js +0 -109
  210. package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +0 -78
  211. package/framework/index/troubleshooting-index.json +0 -184
  212. package/framework/rules/testing-standards.md +0 -14
  213. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +0 -230
  214. package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +0 -70
  215. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +0 -256
  216. package/framework/skills/level-1-workflows/morph-phase-clarify/references/clarifications-example.md +0 -117
  217. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +0 -269
  218. package/framework/standards/ai-agents/blazor-ui.md +0 -364
  219. package/framework/standards/architecture/ddd/aggregates.md +0 -120
  220. package/framework/standards/architecture/ddd/bounded-contexts.md +0 -105
  221. package/framework/standards/architecture/ddd/complexity-levels.md +0 -108
  222. package/framework/standards/architecture/ddd/entities.md +0 -99
  223. package/framework/standards/architecture/ddd/ubiquitous-language.md +0 -58
  224. package/framework/standards/architecture/ddd/value-objects.md +0 -124
  225. package/framework/standards/backend/api/minimal-api.md +0 -494
  226. package/framework/standards/backend/api/rest.md +0 -492
  227. package/framework/standards/backend/authentication/passkeys.md +0 -428
  228. package/framework/standards/backend/database/ef-core.md +0 -199
  229. package/framework/standards/backend/database/migrations.md +0 -393
  230. package/framework/standards/backend/database/repository-patterns.md +0 -528
  231. package/framework/standards/backend/dotnet/async.md +0 -366
  232. package/framework/standards/backend/dotnet/core.md +0 -117
  233. package/framework/standards/backend/dotnet/di.md +0 -439
  234. package/framework/standards/backend/dotnet/program-cs-checklist.md +0 -92
  235. package/framework/standards/context/analytics.md +0 -96
  236. package/framework/standards/context/bundles.md +0 -110
  237. package/framework/standards/context/priming.md +0 -78
  238. package/framework/standards/core/architecture.md +0 -185
  239. package/framework/standards/core/coding.md +0 -214
  240. package/framework/standards/core/git-branching-strategy.md +0 -403
  241. package/framework/standards/core/git.md +0 -185
  242. package/framework/standards/core/testing.md +0 -295
  243. package/framework/standards/data/nosql/blob-storage.md +0 -102
  244. package/framework/standards/data/vector-search/azure-ai-search.md +0 -121
  245. package/framework/standards/frontend/blazor/design-checklist.md +0 -222
  246. package/framework/standards/frontend/blazor/fluent-ui-setup.md +0 -595
  247. package/framework/standards/frontend/blazor/fluent-ui.md +0 -137
  248. package/framework/standards/frontend/blazor/html-conversion.md +0 -184
  249. package/framework/standards/frontend/blazor/lifecycle.md +0 -195
  250. package/framework/standards/frontend/blazor/pitfalls.md +0 -198
  251. package/framework/standards/frontend/blazor/state.md +0 -191
  252. package/framework/standards/frontend/design-system/aesthetic-direction.md +0 -266
  253. package/framework/standards/frontend/design-system/design-trends.md +0 -171
  254. package/framework/standards/infrastructure/azure/azure.md +0 -624
  255. package/framework/standards/infrastructure/azure/bicep/bicep-patterns.md +0 -422
  256. package/framework/standards/infrastructure/azure/devops/azure-devops-setup.md +0 -516
  257. package/framework/standards/infrastructure/azure/devops/local-development.md +0 -520
  258. package/framework/standards/infrastructure/azure/services/functions.md +0 -486
  259. package/framework/standards/infrastructure/azure/services/service-bus.md +0 -459
  260. package/framework/standards/infrastructure/azure/services/storage.md +0 -407
  261. package/framework/standards/infrastructure/vercel/vercel-database.md +0 -106
  262. package/framework/standards/integration/api/graphql.md +0 -91
  263. package/framework/standards/integration/api/grpc.md +0 -114
  264. package/framework/standards/integration/api/rest-design.md +0 -95
  265. package/framework/standards/integration/event-driven/cqrs.md +0 -101
  266. package/framework/standards/integration/event-driven/event-sourcing.md +0 -124
  267. package/framework/standards/integration/event-driven/service-bus.md +0 -95
  268. package/framework/standards/observability/logging.md +0 -131
  269. package/framework/standards/observability/metrics.md +0 -121
  270. package/framework/standards/observability/monitoring.md +0 -114
  271. package/framework/standards/observability/tracing.md +0 -132
  272. package/framework/standards/workflows/parallel-execution.md +0 -112
  273. package/framework/standards/workflows/thread-management.md +0 -113
  274. package/framework/templates/code/dotnet/backend/service.cs +0 -139
  275. package/framework/templates/code/dotnet/contracts/Commands.cs +0 -74
  276. package/framework/templates/code/dotnet/contracts/Entities.cs +0 -25
  277. package/framework/templates/code/dotnet/contracts/Queries.cs +0 -74
  278. package/framework/templates/code/dotnet/contracts/api-contracts.cs +0 -173
  279. package/framework/templates/code/dotnet/contracts/contracts-level1.cs +0 -69
  280. package/framework/templates/code/dotnet/contracts/contracts-level2.cs +0 -86
  281. package/framework/templates/code/dotnet/contracts/contracts-level3.cs +0 -41
  282. package/framework/templates/code/dotnet/frontend/component.razor +0 -239
  283. package/framework/templates/infrastructure/azure/Dockerfile.example +0 -82
  284. package/framework/templates/infrastructure/azure/README.md +0 -286
  285. package/framework/templates/infrastructure/azure/app-insights.bicep +0 -63
  286. package/framework/templates/infrastructure/azure/app-service.bicep +0 -164
  287. package/framework/templates/infrastructure/azure/container-app-env.bicep +0 -49
  288. package/framework/templates/infrastructure/azure/container-app.bicep +0 -156
  289. package/framework/templates/infrastructure/azure/deploy-checklist.md +0 -426
  290. package/framework/templates/infrastructure/azure/deploy.ps1 +0 -229
  291. package/framework/templates/infrastructure/azure/deploy.sh +0 -208
  292. package/framework/templates/infrastructure/azure/key-vault.bicep +0 -91
  293. package/framework/templates/infrastructure/azure/main.bicep +0 -189
  294. package/framework/templates/infrastructure/azure/parameters.dev.json +0 -29
  295. package/framework/templates/infrastructure/azure/parameters.prod.json +0 -29
  296. package/framework/templates/infrastructure/azure/parameters.staging.json +0 -29
  297. package/framework/templates/infrastructure/azure/sql-database.bicep +0 -103
  298. package/framework/templates/infrastructure/azure/storage.bicep +0 -106
  299. package/framework/templates/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -22
  300. package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +0 -61
  301. package/framework/templates/integrations/azure-identity-config.cs +0 -288
  302. package/framework/templates/project-structure/dotnet-ddd.md +0 -70
  303. package/framework/templates/saas/subscription.cs +0 -347
  304. package/framework/templates/saas/tenant.cs +0 -338
  305. package/framework/templates/ui/FluentDesignTheme.cs +0 -149
  306. package/framework/templates/ui/MudTheme.cs +0 -281
  307. package/framework/workflows/configs/nodejs-cli.json +0 -40
  308. package/src/commands/standards/context-budget.js +0 -89
  309. package/src/lib/standards/index.js +0 -7
  310. package/src/lib/standards/standards-context-injector.js +0 -302
  311. package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +0 -316
  312. package/src/lib/validators/blazor/blazor-state-validator.js +0 -279
  313. package/src/lib/validators/blazor/blazor-validator.js +0 -369
  314. 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
  }