@event4u/agent-config 16.1.0 → 16.3.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 (467) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +98 -257
  5. package/README.md +14 -12
  6. package/dist/agent-src/commands/analyze/inbox.md +1 -1
  7. package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
  8. package/dist/agent-src/commands/bug/fix.md +17 -2
  9. package/dist/agent-src/commands/feature/plan.md +1 -1
  10. package/dist/agent-src/commands/feature/roadmap.md +1 -1
  11. package/dist/agent-src/commands/fix/ci.md +1 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/jira-ticket.md +1 -1
  14. package/dist/agent-src/commands/roadmap/create.md +1 -1
  15. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  16. package/dist/agent-src/commands/roadmap/process-full.md +5 -5
  17. package/dist/agent-src/commands/roadmap/resolve-blockers.md +361 -0
  18. package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
  19. package/dist/agent-src/commands/roadmap.md +18 -4
  20. package/dist/agent-src/commands/tests/create.md +17 -3
  21. package/dist/agent-src/commands/tests/execute.md +22 -5
  22. package/dist/agent-src/commands/work.md +4 -0
  23. package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  24. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  25. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +6 -6
  26. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +4 -8
  27. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +32 -2
  28. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  29. package/dist/agent-src/contexts/execution/toolchain-resolver.md +101 -7
  30. package/dist/agent-src/rules/active-remediation.md +1 -1
  31. package/dist/agent-src/rules/autonomous-execution.md +1 -0
  32. package/dist/agent-src/rules/broken-access-control.md +1 -0
  33. package/dist/agent-src/rules/command-suggestion-policy.md +1 -0
  34. package/dist/agent-src/rules/context-hygiene.md +1 -1
  35. package/dist/agent-src/rules/decision-revisit-gate.md +16 -33
  36. package/dist/agent-src/rules/design-fidelity.md +13 -16
  37. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -0
  38. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -0
  39. package/dist/agent-src/rules/domain-safety-pii.md +1 -0
  40. package/dist/agent-src/rules/domain-safety-retention.md +1 -0
  41. package/dist/agent-src/rules/engineering-safety-floor.md +1 -0
  42. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  43. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
  44. package/dist/agent-src/rules/finance-safety-floor.md +1 -0
  45. package/dist/agent-src/rules/git-history-discipline.md +1 -0
  46. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
  47. package/dist/agent-src/rules/legal-safety-floor.md +3 -2
  48. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
  49. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
  50. package/dist/agent-src/rules/media-governance-routing.md +14 -17
  51. package/dist/agent-src/rules/persona-governance.md +2 -2
  52. package/dist/agent-src/rules/provider-lifecycle-discipline.md +1 -1
  53. package/dist/agent-src/rules/question-not-instruction.md +1 -0
  54. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  55. package/dist/agent-src/rules/runtime-safety.md +1 -0
  56. package/dist/agent-src/rules/secret-vcs-guard.md +1 -0
  57. package/dist/agent-src/rules/security-sensitive-stop.md +3 -2
  58. package/dist/agent-src/rules/session-canary.md +8 -62
  59. package/dist/agent-src/rules/settings-ask-protocol.md +1 -0
  60. package/dist/agent-src/rules/source-confidentiality.md +1 -0
  61. package/dist/agent-src/rules/strategy-safety-floor.md +1 -0
  62. package/dist/agent-src/rules/tool-safety.md +1 -0
  63. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  64. package/dist/agent-src/rules/untrusted-input-defense.md +1 -0
  65. package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
  66. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  67. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  68. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  69. package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +1 -1
  70. package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +2 -2
  71. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  72. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  73. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  74. package/dist/agent-src/skills/design-review/SKILL.md +30 -4
  75. package/dist/agent-src/skills/design-review/references/verification-automation.md +32 -0
  76. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  77. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +18 -3
  78. package/dist/agent-src/skills/existing-ui-audit/references/component-taxonomy-detection.md +56 -0
  79. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  80. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  81. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  82. package/dist/agent-src/skills/markitdown/SKILL.md +4 -0
  83. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  84. package/dist/agent-src/skills/playwright-testing/SKILL.md +30 -6
  85. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  86. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  87. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  88. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  89. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
  90. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  91. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  92. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  93. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  94. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  95. package/dist/agent-src/skills/ui-component-architect/SKILL.md +25 -2
  96. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  97. package/dist/agent-src/templates/roadmaps.md +30 -0
  98. package/dist/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
  99. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +302 -21
  100. package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
  101. package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
  102. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  103. package/dist/agent-src/templates/scripts/work_engine/state.ts +57 -7
  104. package/dist/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
  105. package/dist/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
  106. package/dist/cli/python/knowledge_ingest.js +1 -1
  107. package/dist/cli/python/workspace_drive.js +1 -1
  108. package/dist/cli/registry.js +1 -1
  109. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  110. package/dist/cli-delegate/check_update_banner.js +12 -1
  111. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  112. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  113. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  114. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-CQWX336L.js} +1 -1
  115. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  116. package/dist/cli-delegate/chunk-EEHDXSYD.js +2040 -0
  117. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-GKE7ZVFA.js} +4 -4
  118. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  119. package/dist/cli-delegate/{chunk-UNCRJBT3.js → chunk-JQVYKIZA.js} +41 -0
  120. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-JY2I2DXV.js} +12 -1
  121. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  122. package/dist/cli-delegate/{chunk-YUM5KURG.js → chunk-KR6EM23A.js} +235 -1455
  123. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-LIYTLH6O.js} +1 -1
  124. package/dist/cli-delegate/chunk-NQ7WT43P.js +2729 -0
  125. package/dist/cli-delegate/chunk-NXEILF2K.js +2160 -0
  126. package/dist/cli-delegate/{chunk-5R7HOLAF.js → chunk-NYX3L2PZ.js} +1 -1
  127. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  128. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  129. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-QLDHIPWR.js} +1 -1
  130. package/dist/cli-delegate/{chunk-HDVVGPQW.js → chunk-RQNNW7IF.js} +1405 -567
  131. package/dist/cli-delegate/{chunk-S3VFXMTM.js → chunk-S4UMZNES.js} +1 -1
  132. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-S4YWNRKO.js} +24 -8
  133. package/dist/cli-delegate/{chunk-GJCBB2UG.js → chunk-TRI6DQZ6.js} +3054 -325
  134. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  135. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  136. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  137. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  138. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  139. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  140. package/dist/cli-delegate/cmd_conformance.js +1862 -809
  141. package/dist/cli-delegate/cmd_doctor.js +13 -6
  142. package/dist/cli-delegate/cmd_doctor_neighbours.js +23 -0
  143. package/dist/cli-delegate/cmd_explain.js +5 -5
  144. package/dist/cli-delegate/cmd_export.js +11 -8
  145. package/dist/cli-delegate/cmd_fleet.js +3 -3
  146. package/dist/cli-delegate/cmd_handoff.js +10 -7
  147. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  148. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  149. package/dist/cli-delegate/cmd_migrate.js +2 -2
  150. package/dist/cli-delegate/cmd_packs_active.js +3 -3
  151. package/dist/cli-delegate/cmd_preflight.js +6 -6
  152. package/dist/cli-delegate/cmd_prune.js +11 -8
  153. package/dist/cli-delegate/cmd_refresh.js +2 -1
  154. package/dist/cli-delegate/cmd_route_audit.js +8 -6
  155. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  156. package/dist/cli-delegate/cmd_session_recycle.js +4 -3
  157. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  158. package/dist/cli-delegate/cmd_settings_migrate.js +11 -8
  159. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  160. package/dist/cli-delegate/cmd_sync.js +11 -8
  161. package/dist/cli-delegate/cmd_uninstall.js +11 -8
  162. package/dist/cli-delegate/cmd_update.js +1 -1
  163. package/dist/cli-delegate/cmd_upgrade.js +3 -2
  164. package/dist/cli-delegate/cmd_validate.js +11 -8
  165. package/dist/cli-delegate/cmd_versions.js +1 -1
  166. package/dist/cli-delegate/deferral_carry.js +16 -0
  167. package/dist/cli-delegate/gate_execute.js +2 -2
  168. package/dist/cli-delegate/roadmap_gates.js +5 -5
  169. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  170. package/dist/discovery/deprecation-report.md +1 -1
  171. package/dist/discovery/discovery-manifest.json +132 -80
  172. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  173. package/dist/discovery/discovery-manifest.summary.md +3 -3
  174. package/dist/discovery/dormancy-report.md +1 -1
  175. package/dist/discovery/orphan-report.md +1 -1
  176. package/dist/discovery/packs.json +7 -5
  177. package/dist/discovery/trust-report.md +2 -2
  178. package/dist/discovery/workspaces.json +6 -4
  179. package/dist/hooks/dispatch.js +7972 -5186
  180. package/dist/hooks/dispatch.sha256 +1 -0
  181. package/dist/install/claudePathsPlan.js +47 -6
  182. package/dist/install/claudeRuleRewrite.js +7 -0
  183. package/dist/install/emit_host_rules_cli.js +39 -36
  184. package/dist/install/globalRuleScope.js +87 -0
  185. package/dist/install/host_rule_ownership.js +160 -0
  186. package/dist/install/install.mjs +2226 -1055
  187. package/dist/install/installThinLayer.js +261 -0
  188. package/dist/install/installedRuleLinks.js +176 -0
  189. package/dist/install/wizard-plan.js +24 -0
  190. package/dist/mcp/registry-manifest.json +3 -3
  191. package/dist/mcp/server.json +2 -2
  192. package/dist/mcp/server.mjs +40913 -34865
  193. package/dist/scripts/_lib/agent_settings.js +11 -0
  194. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  195. package/dist/scripts/_lib/installed_layer.js +378 -0
  196. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  197. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  198. package/dist/scripts/_lib/rule_injection.js +67 -10
  199. package/dist/scripts/_lib/rule_law_section.js +122 -0
  200. package/dist/scripts/_lib/thin_rules.js +458 -0
  201. package/dist/scripts/_lib/windsurf_render.js +60 -0
  202. package/dist/scripts/condense.js +14 -26
  203. package/dist/scripts/project_thin_rules.js +14 -294
  204. package/dist/server/schemas/settings.js +29 -0
  205. package/dist/shared/skillRanking.js +74 -13
  206. package/dist/ui/assets/index-Cwq4d0hX.js +23 -0
  207. package/dist/ui/assets/index-Cyjy8bWO.css +1 -0
  208. package/dist/ui/index.html +2 -2
  209. package/docs/contracts/settings-classes.md +10 -6
  210. package/package.json +4 -4
  211. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  212. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  213. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  214. package/src/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
  215. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +302 -21
  216. package/src/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
  217. package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
  218. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  219. package/src/agent-src/templates/scripts/work_engine/state.ts +57 -7
  220. package/src/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
  221. package/src/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
  222. package/src/config/agent-settings.template.yml +91 -22
  223. package/src/config/ci-local-parity.yml +18 -0
  224. package/src/config/continuity-surface.json +9 -2
  225. package/src/config/evaluator-budgets.json +4 -4
  226. package/src/config/gate-coverage.yml +327 -3
  227. package/src/config/gate-violation-baselines.json +21 -9
  228. package/src/config/hook-bundle-budget.json +25 -0
  229. package/src/config/hook-latency-budget.json +21 -0
  230. package/src/config/hook-token-budget.json +8 -3
  231. package/src/config/host-instruction-limits.json +33 -0
  232. package/src/config/metric-registry.yml +114 -0
  233. package/src/config/placeholder-drift-budget.json +10 -0
  234. package/src/config/routing-coverage-seed.json +38 -3
  235. package/src/config/rule-activation-census.json +7 -3
  236. package/src/config/rule-consequence-class.json +161 -0
  237. package/src/config/rule-law-ceilings.json +99 -0
  238. package/src/install/claudePathsPlan.ts +46 -4
  239. package/src/install/claudeRuleRewrite.ts +10 -1
  240. package/src/install/emit_host_rules_cli.ts +43 -34
  241. package/src/install/globalRuleScope.ts +109 -0
  242. package/src/install/host_rule_ownership.ts +170 -0
  243. package/src/install/installThinLayer.ts +312 -0
  244. package/src/install/installedRuleLinks.ts +220 -0
  245. package/src/install/wizard-plan.ts +24 -0
  246. package/src/scripts/_cli/cmd_doctor.ts +28 -90
  247. package/src/scripts/_cli/cmd_doctor_neighbours.ts +293 -0
  248. package/src/scripts/_cli/doctor_execution.ts +100 -17
  249. package/src/scripts/_cli/doctor_network_posture.ts +226 -0
  250. package/src/scripts/_dispatch.bash +16 -2
  251. package/src/scripts/_lib/agent_settings.ts +11 -0
  252. package/src/scripts/_lib/body_portable.ts +102 -0
  253. package/src/scripts/_lib/cc_transcript.ts +132 -1
  254. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  255. package/src/scripts/_lib/concern_sla_window.ts +200 -0
  256. package/src/scripts/_lib/estate_offsets.ts +241 -0
  257. package/src/scripts/_lib/exemption_shape.ts +143 -0
  258. package/src/scripts/_lib/fnv.ts +23 -0
  259. package/src/scripts/_lib/foreign_scan.ts +106 -0
  260. package/src/scripts/_lib/forge_protection.ts +114 -0
  261. package/src/scripts/_lib/forge_reader.ts +558 -0
  262. package/src/scripts/_lib/gitignore_block.ts +314 -0
  263. package/src/scripts/_lib/global_deploy_inventory.ts +32 -0
  264. package/src/scripts/_lib/graph_feeder_record.ts +214 -0
  265. package/src/scripts/_lib/hook_settings.ts +73 -0
  266. package/src/scripts/_lib/host_capability.ts +40 -19
  267. package/src/scripts/_lib/host_env_write.ts +111 -0
  268. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  269. package/src/scripts/_lib/installed_layer.ts +538 -0
  270. package/src/scripts/_lib/json_merge.ts +82 -0
  271. package/src/scripts/_lib/json_pointers.ts +93 -11
  272. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  273. package/src/scripts/_lib/llm_proposer_transport.ts +14 -4
  274. package/src/scripts/_lib/machine_wake.ts +16 -3
  275. package/src/scripts/_lib/neighbour_census.ts +760 -0
  276. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  277. package/src/scripts/_lib/neighbour_tool_use.ts +189 -0
  278. package/src/scripts/_lib/obligations.ts +119 -8
  279. package/src/scripts/_lib/probe_inputs.ts +271 -0
  280. package/src/scripts/_lib/prompt_shape.ts +46 -0
  281. package/src/scripts/_lib/read_surface_scan.ts +322 -0
  282. package/src/scripts/_lib/release_highlights.ts +2 -1
  283. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  284. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  285. package/src/scripts/_lib/retrieval_sanitize.ts +77 -16
  286. package/src/scripts/_lib/review_coverage.ts +134 -0
  287. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  288. package/src/scripts/_lib/rule_injection.ts +130 -10
  289. package/src/scripts/_lib/rule_law_section.ts +147 -0
  290. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  291. package/src/scripts/_lib/shell_write_shapes.ts +108 -0
  292. package/src/scripts/_lib/skill_origin.ts +254 -0
  293. package/src/scripts/_lib/structural_hiding.ts +622 -0
  294. package/src/scripts/_lib/structured_ask.ts +64 -21
  295. package/src/scripts/_lib/thin_rules.ts +540 -0
  296. package/src/scripts/_lib/touched_file_quality.ts +434 -0
  297. package/src/scripts/_lib/turn_end_refusals.ts +600 -4
  298. package/src/scripts/_lib/turn_end_transcript.ts +216 -0
  299. package/src/scripts/_lib/verification_command.ts +324 -0
  300. package/src/scripts/_lib/verification_evidence.ts +647 -0
  301. package/src/scripts/_lib/verify_clause.ts +280 -0
  302. package/src/scripts/_lib/windsurf_render.ts +63 -0
  303. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  304. package/src/scripts/ai_council/clients.ts +26 -57
  305. package/src/scripts/ai_council/config.ts +1 -1
  306. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  307. package/src/scripts/ai_team/team_dispatch.ts +4 -0
  308. package/src/scripts/audit_skill_overlap.ts +261 -0
  309. package/src/scripts/before_complete_hook.ts +573 -25
  310. package/src/scripts/bench_hook_latency.ts +412 -5
  311. package/src/scripts/bench_touched_file_quality.ts +238 -0
  312. package/src/scripts/cache_realization_report.ts +61 -1
  313. package/src/scripts/check_argument_hint.ts +287 -0
  314. package/src/scripts/check_claims.ts +125 -1
  315. package/src/scripts/check_enforcement_coverage.ts +38 -9
  316. package/src/scripts/check_enforcement_matrix.ts +621 -22
  317. package/src/scripts/check_estate_count.ts +130 -153
  318. package/src/scripts/check_finding_dispositions.ts +138 -7
  319. package/src/scripts/check_generator_sync.ts +71 -0
  320. package/src/scripts/check_hook_bundle_composition.ts +370 -0
  321. package/src/scripts/check_host_docs_digest.ts +786 -0
  322. package/src/scripts/check_host_format_column.ts +559 -0
  323. package/src/scripts/check_input_references.ts +228 -0
  324. package/src/scripts/check_inputs_parity.ts +235 -0
  325. package/src/scripts/check_kernel_edit_ratified.ts +89 -9
  326. package/src/scripts/check_kill_switch_table.ts +294 -0
  327. package/src/scripts/check_memory.ts +7 -1
  328. package/src/scripts/check_placeholder_drift.ts +221 -0
  329. package/src/scripts/check_read_surface_coverage.ts +515 -0
  330. package/src/scripts/check_release_highlights.ts +10 -0
  331. package/src/scripts/check_release_holds.ts +2 -1
  332. package/src/scripts/check_release_pr_shape.ts +38 -15
  333. package/src/scripts/check_routing_coverage.ts +378 -11
  334. package/src/scripts/check_standing_rule_delivery.ts +33 -13
  335. package/src/scripts/check_static_parity.ts +17 -0
  336. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  337. package/src/scripts/ci_settle.ts +145 -19
  338. package/src/scripts/closure_scan.ts +115 -1
  339. package/src/scripts/code_graph/detect.ts +127 -7
  340. package/src/scripts/code_graph/foreign.ts +194 -0
  341. package/src/scripts/code_graph/query.ts +217 -4
  342. package/src/scripts/code_graph/types.ts +26 -2
  343. package/src/scripts/code_graph/validate.ts +3 -1
  344. package/src/scripts/code_graph/verbs.ts +103 -0
  345. package/src/scripts/compile_hook_manifest.ts +90 -14
  346. package/src/scripts/condense.ts +14 -27
  347. package/src/scripts/estate_exemption_shape.ts +202 -0
  348. package/src/scripts/external_sources_denylist.json +29 -4
  349. package/src/scripts/generate_host_cost_table.ts +1 -1
  350. package/src/scripts/hook_manifest.json +1 -1
  351. package/src/scripts/hook_manifest.yaml +192 -14
  352. package/src/scripts/hooks/block_config_weakening.ts +294 -4
  353. package/src/scripts/hooks/block_kernel_rule_writes.ts +9 -78
  354. package/src/scripts/hooks/block_plumbing_writes.ts +342 -0
  355. package/src/scripts/hooks/bundle_integrity.ts +291 -0
  356. package/src/scripts/hooks/chain_nudge_hook.ts +1 -2
  357. package/src/scripts/hooks/code_graph_context_hook.ts +253 -25
  358. package/src/scripts/hooks/comment_discipline_hook.ts +1 -3
  359. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  360. package/src/scripts/hooks/concern_registry.ts +2 -0
  361. package/src/scripts/hooks/concern_timings.ts +94 -0
  362. package/src/scripts/hooks/delegation_nudge_hook.ts +1 -2
  363. package/src/scripts/hooks/design_pass_hook.ts +100 -9
  364. package/src/scripts/hooks/design_slop_hook.ts +1 -2
  365. package/src/scripts/hooks/dispatch_hook.ts +77 -71
  366. package/src/scripts/hooks/edit_shape_hook.ts +1 -2
  367. package/src/scripts/hooks/end_review_nudge_hook.ts +1 -1
  368. package/src/scripts/hooks/evidence_independence.ts +1 -2
  369. package/src/scripts/hooks/exit_codes.ts +129 -0
  370. package/src/scripts/hooks/host_lowering.json +1 -0
  371. package/src/scripts/hooks/host_lowering.ts +146 -3
  372. package/src/scripts/hooks/host_lowering.yaml +262 -46
  373. package/src/scripts/hooks/host_semantics.ts +30 -2
  374. package/src/scripts/hooks/injection_budget.ts +9 -2
  375. package/src/scripts/hooks/interruption_ledger_hook.ts +1 -2
  376. package/src/scripts/hooks/journal_record_hook.ts +1 -2
  377. package/src/scripts/hooks/memory_recall_hook.ts +1 -2
  378. package/src/scripts/hooks/obligation_settle_hook.ts +151 -5
  379. package/src/scripts/hooks/one_question_per_ask_hook.ts +43 -6
  380. package/src/scripts/hooks/orchestration_record_hook.ts +1 -2
  381. package/src/scripts/hooks/payload_stub.ts +10 -1
  382. package/src/scripts/hooks/permission_gate.ts +1 -2
  383. package/src/scripts/hooks/push_settle_hook.ts +1 -3
  384. package/src/scripts/hooks/replay_hook.ts +2 -1
  385. package/src/scripts/hooks/reread_guard_hook.ts +1 -2
  386. package/src/scripts/hooks/review_baseline_hook.ts +1 -2
  387. package/src/scripts/hooks/rtk_wrap_hook.ts +1 -2
  388. package/src/scripts/hooks/rule_inject_hook.ts +765 -68
  389. package/src/scripts/hooks/run_continuation_hook.ts +13 -15
  390. package/src/scripts/hooks/skill_route_hook.ts +1 -2
  391. package/src/scripts/hooks/source_first_gate_hook.ts +1 -2
  392. package/src/scripts/hooks/spawn_guard_shadow_hook.ts +1 -2
  393. package/src/scripts/hooks/subagent_ledger_hook.ts +1 -2
  394. package/src/scripts/hooks/suggestion_capture_hook.ts +1 -1
  395. package/src/scripts/hooks/table_fingerprint.ts +70 -0
  396. package/src/scripts/hooks/telemetry_flush_hook.ts +1 -2
  397. package/src/scripts/hooks/telemetry_usage_hook.ts +65 -10
  398. package/src/scripts/hooks/tool_result_bytes_hook.ts +93 -9
  399. package/src/scripts/hooks/turn_end_gate_hook.ts +421 -324
  400. package/src/scripts/hooks/ui_route_nudge_hook.ts +1 -2
  401. package/src/scripts/hooks_status.ts +112 -0
  402. package/src/scripts/injection_scan_hook.ts +7 -0
  403. package/src/scripts/install.ts +75 -189
  404. package/src/scripts/installed_layer_report.ts +103 -0
  405. package/src/scripts/language_mirror_hook.ts +15 -6
  406. package/src/scripts/learning_sidecar.ts +119 -8
  407. package/src/scripts/lint_deny_text.ts +419 -0
  408. package/src/scripts/lint_exit_codes.ts +262 -0
  409. package/src/scripts/lint_hook_manifest.ts +108 -0
  410. package/src/scripts/lint_major_migration_sections.ts +156 -26
  411. package/src/scripts/lint_pack_boundaries.ts +63 -5
  412. package/src/scripts/lint_roadmap_blockers.ts +78 -12
  413. package/src/scripts/lint_rule_law_section.ts +517 -0
  414. package/src/scripts/lint_skill_descriptions.ts +1 -1
  415. package/src/scripts/lint_skill_scripts_readonly.ts +1 -1
  416. package/src/scripts/lint_workflow_security.ts +161 -5
  417. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  418. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  419. package/src/scripts/mcp_server/prompts.ts +142 -1
  420. package/src/scripts/measure_routing_signal.ts +54 -16
  421. package/src/scripts/measure_skill_ranker_baseline.ts +515 -53
  422. package/src/scripts/measure_turn_end_gate.ts +193 -0
  423. package/src/scripts/memory_learn_hook.ts +91 -6
  424. package/src/scripts/memory_lookup.ts +1 -1
  425. package/src/scripts/model_rule_injection.ts +52 -5
  426. package/src/scripts/prepack-check.mjs +53 -0
  427. package/src/scripts/project_thin_rules.ts +34 -327
  428. package/src/scripts/release_publication.ts +13 -1
  429. package/src/scripts/report_evidence_temperature.ts +657 -0
  430. package/src/scripts/report_installed_rule_links.ts +157 -0
  431. package/src/scripts/report_invocation_surface.ts +383 -0
  432. package/src/scripts/report_label_agreement.ts +233 -0
  433. package/src/scripts/report_obligation_carriers.ts +699 -0
  434. package/src/scripts/report_obligation_mechanism.ts +230 -0
  435. package/src/scripts/report_obligation_writer_split.ts +236 -0
  436. package/src/scripts/report_single_token_triggers.ts +277 -0
  437. package/src/scripts/report_skill_menu_census.ts +208 -0
  438. package/src/scripts/report_skill_ranker_confusion.ts +442 -0
  439. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  440. package/src/scripts/report_verification_record_coverage.ts +306 -0
  441. package/src/scripts/roadmap_verify_share.ts +213 -0
  442. package/src/scripts/rule_activation_census.ts +5 -2
  443. package/src/scripts/rule_trigger_eval.ts +9 -9
  444. package/src/scripts/schemas/command.schema.json +44 -0
  445. package/src/scripts/schemas/review-findings.schema.json +7 -2
  446. package/src/scripts/schemas/rule.schema.json +5 -0
  447. package/src/scripts/schemas/skill.schema.json +44 -0
  448. package/src/scripts/self_review_gate.ts +421 -17
  449. package/src/scripts/semantic_parity_census.ts +314 -0
  450. package/src/scripts/session_eol_report.ts +54 -1
  451. package/src/scripts/skill_tools/score_skill_relevance.ts +290 -25
  452. package/src/scripts/sweep_dead_scan_roots.ts +1 -1
  453. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  454. package/src/scripts/sync_gitignore.ts +29 -235
  455. package/src/scripts/trigger_eval_grandfather.json +0 -7
  456. package/src/scripts/trigger_eval_rotation.ts +122 -27
  457. package/src/scripts/ui_conformance_probe.ts +156 -4
  458. package/src/scripts/update_prices.ts +85 -3
  459. package/src/scripts/write_bundle_digest.mjs +74 -0
  460. package/src/server/schemas/settings.ts +41 -0
  461. package/src/shared/skillRanking.ts +117 -11
  462. package/src/templates/consumer-settings/ONBOARDING.md +1 -0
  463. package/dist/cli-delegate/chunk-FXYUYU4N.js +0 -4416
  464. package/dist/cli-delegate/chunk-QJWAUMJW.js +0 -1072
  465. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
  466. package/dist/ui/assets/index-DH1xc62v.js +0 -29
  467. package/dist/ui/assets/index-jSfMW8_t.css +0 -1
@@ -184,7 +184,7 @@ export function normalizeHostManifest(input: unknown): HostCapabilityManifest {
184
184
  *
185
185
  * `contexts/execution/host-capability-manifest.md` § Observation protocol states
186
186
  * the per-field criterion and the four-part citation (host · host version ·
187
- * transcript or artefact reference · date). A row without all four is not
187
+ * transcript or artifact reference · date). A row without all four is not
188
188
  * admissible, and no row may be filled from a host's documentation.
189
189
  *
190
190
  * ## REACHABILITY, 2026-08-22 — one of eight, and the other seven are recorded
@@ -221,7 +221,7 @@ export function normalizeHostManifest(input: unknown): HostCapabilityManifest {
221
221
  * `duration_ms` — i.e. 420 child legs whose start and stop pair, which is the
222
222
  * criterion (a measurable child duration, not an inferred one).
223
223
  *
224
- * `parallel_spawn: true` — OBSERVED. Same host, session and artefact.
224
+ * `parallel_spawn: true` — OBSERVED. Same host, session and artifact.
225
225
  * **6,168** of 6,388 stop records carry `concurrent_open >= 2`, with a
226
226
  * maximum of **30** concurrently open children. Overlapping intervals at one
227
227
  * instant, which is the criterion — not two children in sequence.
@@ -235,25 +235,46 @@ export function normalizeHostManifest(input: unknown): HostCapabilityManifest {
235
235
  * `agent_teams` — out of scope for a row by construction; see its own field
236
236
  * doc comment and the protocol section.
237
237
  *
238
- * `structured_ask: false` — OBSERVED ABSENT, not never-looked, and the
239
- * difference is why it is written rather than omitted. claude (Claude Code
240
- * 2.1.263, Opus 5 1M session, 2026-09-07). The host delivers the session's
241
- * tool surface at session start; that surface carried no structured-ask tool
242
- * under any name `_lib/structured_ask.ts` matches, and no per-host shape is
243
- * recorded for it in `STRUCTURED_ASK_SHAPES`. Artefact:
244
- * `agents/evidence/analysis/structured-ask-host-observation-2026-09.md`. code-comment-allow provenance-comment -- the observation protocol declares a row inadmissible without its artefact citation, so this pointer is part of the contract the row satisfies, not evidence duplicated from a roadmap
245
- * The observation is about the delivered surface of one session on one
246
- * version; it is not a claim that the vendor ships no such tool anywhere,
247
- * and a later session observing one writes the `true` row over it.
248
- *
249
- * NO ROW ANYWHERE SETS THE STRUCTURED-ASK FIELD TRUE, and the observation
250
- * protocol above is the only path to the first one that does. A vendor's
251
- * documentation is not that path — and the phrasing here avoids the literal
252
- * key-value pair on purpose, because the roadmap step that ships this field
253
- * verifies the absence with a grep for exactly that string.
238
+ * `structured_ask` — OBSERVED PRESENT, and this row was `false` until
239
+ * 2026-10-05. claude (Claude Code, observed range 2.1.252 to 2.1.284,
240
+ * 2026-09-01 to 2026-10-02): 48 `AskUserQuestion` `tool_use` blocks, 47 of
241
+ * them answered by a non-error `tool_result`, and the per-host shape is now
242
+ * recorded in `STRUCTURED_ASK_SHAPES`. Artifact:
243
+ * `agents/evidence/analysis/structured-ask-host-observation-2026-10.md`. code-comment-allow provenance-comment -- the observation protocol declares a row inadmissible without its artifact citation, so this pointer is part of the contract the row satisfies, not evidence duplicated from a roadmap
244
+ *
245
+ * The earlier `false` (2.1.263, 2026-09-07,
246
+ * `structured-ask-host-observation-2026-09.md`) is not withdrawn as a
247
+ * reading. It was taken from a SUBAGENT leg, whose delivered surface carries
248
+ * no picker because a subagent has no user to ask; that artifact lists the
249
+ * surface it saw and it is the subagent toolset. What it could not support
250
+ * was the step from there to a claim about the host. The earliest call
251
+ * recorded here is on 2.1.252, before the `false` reading on 2.1.263 — the
252
+ * picker was being delivered and called while the row denying it was written.
253
+ *
254
+ * WHICH LEG THE SURFACE WAS READ FROM IS PART OF THE OBSERVATION. A row that
255
+ * does not say so invites exactly this substitution, so every row here says.
256
+ *
257
+ * The prose this block replaced avoided writing the literal field-plus-`true`
258
+ * pair on purpose, because a planning step verified that string's absence by
259
+ * grep. That grep is named rather than paraphrased —
260
+ * `grep -c 'structured_ask: true' src/scripts/_lib/host_capability.ts` — and
261
+ * re-run against this file it returns 1 where it returned 0. So the
262
+ * constraint is BROKEN, not intact, and recording that is the point: a reader
263
+ * who is told only that it is dead cannot tell which. The step that owned it
264
+ * is archived and its address is left in the roadmap rather than copied here.
265
+ *
266
+ * ARCHIVAL IS NOT WHY IT IS DEAD, and the distinction is load-bearing because
267
+ * the archival reading implies an ACTIVE copy of the same clause would bite.
268
+ * It would not. NOTHING IN THIS TREE EXECUTES A `verify:` CLAUSE'S COMMAND,
269
+ * archived or active: `_lib/verify_clause.ts` is a parser, and its four
270
+ * importers — `roadmap_verify_share`, `closure_scan`, `run_continuation_hook`
271
+ * and `check_verify_expectation_delta` — shell out to nothing but `git`. The
272
+ * step also scoped itself to its own merge ("returns 0 at merge"), which it
273
+ * did. Its stated successor was to record the first observed row with its
274
+ * provenance — which is what this block now is.
254
275
  */
255
276
  const HOST_CAPABILITY_REGISTRY: Readonly<Record<string, Partial<HostCapabilityManifest>>> = {
256
- claude: { subagent_spawn: true, parallel_spawn: true, structured_ask: false },
277
+ claude: { subagent_spawn: true, parallel_spawn: true, structured_ask: true },
257
278
  };
258
279
 
259
280
  /**
@@ -0,0 +1,111 @@
1
+ /**
2
+ * The only host environment variables this package will ever write.
3
+ *
4
+ * WHY ITS OWN MODULE. One place owns the question "which host variable may this
5
+ * package write", and the answer is a two-row allow table rather than a rule
6
+ * applied at a call site. `install.ts` imports it; nothing else writes host env.
7
+ * The move out of `install.ts` also keeps that file, already far over its size
8
+ * cap, from paying for this feature — the same reason the doctor's
9
+ * network-posture block moved into its own module.
10
+ *
11
+ * THE GUARANTEE IS THE SHAPE, not a check. Both traffic variables —
12
+ * `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` and `DISABLE_AUTOUPDATER` — reach
13
+ * the host's update-disabled resolver, the blanket one as its THIRD RUNG
14
+ * (measured on Claude Code 2.1.284, `docs/setup/host-traffic-environment.md`).
15
+ * A writer able to express either could disable a consumer's security updates.
16
+ * Owner-decided 2026-09-30 that it never may, and an allow table of two holds
17
+ * that where a deny list of two would have to stay complete as the host grows
18
+ * more variables.
19
+ *
20
+ * Both writable entries are request SIZE caps. Neither suppresses a call, an
21
+ * update check or a download — they bound how big a request is, never how many.
22
+ */
23
+
24
+ import * as fs from 'node:fs';
25
+ import * as path from 'node:path';
26
+
27
+ import * as YAML from 'yaml';
28
+
29
+ /** The allow table. Two rows, and adding a third is a governance change. */
30
+ export const WRITABLE_HOST_ENV: readonly { readonly variable: string; readonly settingsKey: string }[] = [
31
+ { variable: 'BASH_MAX_OUTPUT_LENGTH', settingsKey: 'bash_max_output_length' },
32
+ { variable: 'MAX_MCP_OUTPUT_TOKENS', settingsKey: 'max_mcp_output_tokens' },
33
+ ];
34
+
35
+ /** Where a project's settings document lives, canonical first. */
36
+ const SETTINGS_CANDIDATES: readonly string[][] = [
37
+ ['agents', 'settings', '.agent-settings.yml'],
38
+ ['.agent-settings.yml'],
39
+ ];
40
+
41
+ /**
42
+ * The project settings document, or `null` when there is none to read.
43
+ *
44
+ * `null` on an absent or unparseable file rather than `{}`: the caller reads a
45
+ * key whose ABSENCE means "write nothing", and collapsing an unreadable file to
46
+ * an empty object would give the same answer as a readable file with the key
47
+ * unset. Both write nothing, but only one of them is a fact.
48
+ */
49
+ export function readSettingsDoc(projectRoot: string): unknown | null {
50
+ for (const parts of SETTINGS_CANDIDATES) {
51
+ const p = path.join(projectRoot, ...parts);
52
+ let text: string;
53
+ try {
54
+ text = fs.readFileSync(p, 'utf-8');
55
+ } catch {
56
+ continue;
57
+ }
58
+ let doc: unknown;
59
+ try {
60
+ doc = YAML.parse(text, { version: '1.1' });
61
+ } catch {
62
+ return null;
63
+ }
64
+ return doc === null || doc === undefined || typeof doc !== 'object' ? null : doc;
65
+ }
66
+ return null;
67
+ }
68
+
69
+ /**
70
+ * The `env` block for the host settings file, or `null` when nothing is set.
71
+ *
72
+ * `null` rather than `{}`: an empty object would still be merged into the
73
+ * consumer's file, leaving an `env: {}` nobody asked for and making "this
74
+ * package wrote nothing" indistinguishable from "this package wrote a blank".
75
+ *
76
+ * A non-integer or non-positive value is IGNORED rather than written. The schema
77
+ * already refuses it; this branch is for a hand-edited settings file, where
78
+ * writing a value the host would silently reinterpret is worse than writing none.
79
+ */
80
+ export function hostEnvBlock(settings: unknown): Record<string, string> | null {
81
+ const root = settings as Record<string, unknown> | null | undefined;
82
+ const he = root?.['host_environment'] as Record<string, unknown> | undefined;
83
+ const caps = he?.['request_size_caps'] as Record<string, unknown> | undefined;
84
+ if (caps === undefined) return null;
85
+ const out: Record<string, string> = {};
86
+ for (const { variable, settingsKey } of WRITABLE_HOST_ENV) {
87
+ const v = caps[settingsKey];
88
+ if (typeof v === 'number' && Number.isInteger(v) && v > 0) out[variable] = String(v);
89
+ }
90
+ return Object.keys(out).length === 0 ? null : out;
91
+ }
92
+
93
+ /**
94
+ * The host bridge object with the `env` block merged in, if there is one.
95
+ *
96
+ * Takes the bridge and returns it rather than being called for its side effect,
97
+ * so the caller is one expression and `install.ts` — already far over its size
98
+ * cap — pays one line for this feature instead of six. `announce` is injected
99
+ * rather than imported: this module has no opinion about how a caller reports,
100
+ * and importing the installer's logger would make a leaf depend on its consumer.
101
+ */
102
+ export function withHostEnv(
103
+ bridge: Record<string, unknown>,
104
+ projectRoot: string,
105
+ announce: (msg: string) => void,
106
+ ): Record<string, unknown> {
107
+ const env = hostEnvBlock(readSettingsDoc(projectRoot));
108
+ if (env === null) return bridge;
109
+ announce(`.claude/settings.json: wrote ${Object.keys(env).join(', ')} (request-size caps)`);
110
+ return { ...bridge, env };
111
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Per-event hook merging that keeps a neighbour package's entries.
3
+ *
4
+ * The defect this closes:
5
+ * `install.ts` wrote every host hook file through `deep_merge`, which REPLACES
6
+ * an array wholesale. Seven call sites write a `hooks.<event>` array — augment
7
+ * user, cursor project + user, windsurf project + user, gemini project + user —
8
+ * so any hook another agent package had registered on those events was silently
9
+ * destroyed at install time. Only the Claude path was safe, because
10
+ * `_lib/claude_settings_hooks.ts` already merges per event by signature; that
11
+ * module's contract is the one generalised here.
12
+ *
13
+ * The rule, for each event present in the patch:
14
+ *
15
+ * 1. keep, in order and byte-identical, every existing entry that does NOT
16
+ * carry this package's signature;
17
+ * 2. drop every existing entry that DOES carry it (ours, possibly from an older
18
+ * version with a different command string);
19
+ * 3. append the patch's entries for that event.
20
+ *
21
+ * Events the patch does not mention are left exactly as they are — a host file
22
+ * may legitimately carry foreign events this package never binds.
23
+ *
24
+ * Step 2 is what keeps an upgrade idempotent: a migration that changes our own
25
+ * command string replaces the old entry rather than leaving a stale duplicate
26
+ * beside it. That is risk 1 of this lane's register, and the lifecycle fixture
27
+ * asserts exactly one managed entry per event after install → upgrade.
28
+ *
29
+ * Identity is content-derived, never an added field.
30
+ * An entry is ours when its command string contains the caller's `signature`.
31
+ * No marker key is written into the host's file: a host that dedupes identical
32
+ * command strings (Claude Code does) must keep seeing a byte-identical command,
33
+ * and a marker field would also be a key the host did not ask for. The
34
+ * signature a call site passes is the stable fragment of the command it writes —
35
+ * `dispatch:hook --platform <host>` for the project-level bridges, the
36
+ * dispatcher trampoline's filename for the user-level ones, which is the part
37
+ * that survives a change of home directory or binary path.
38
+ *
39
+ * Shape awareness:
40
+ * hosts disagree about what an entry looks like, so the command extractor
41
+ * covers all three shapes this package writes and reads:
42
+ *
43
+ * - `{ command: "…" }` — cursor, windsurf
44
+ * - `{ hooks: [{ type, command }] }` — augment
45
+ * - `{ matcher, hooks: [{ type, command }] }` — gemini, claude
46
+ *
47
+ * An entry of none of those shapes is foreign by construction: it carries no
48
+ * command we can read, so it cannot be ours, so it is kept. Unreadable means
49
+ * kept, never deleted — the asymmetry is deliberate.
50
+ */
51
+
52
+ import { deepcopy, isPlainObject } from './json_merge.js';
53
+
54
+ /**
55
+ * The stable command fragment that identifies this package's entry, per writer.
56
+ *
57
+ * Keyed by the label `merge_json_file` already prints, so a call site names its
58
+ * signature with the string it is holding anyway. Two families, for one reason:
59
+ * a project-level bridge invokes the repo-local binary, so the verb and platform
60
+ * flag are the stable part; a user-level writer invokes an absolute trampoline
61
+ * path, where the only fragment that survives a different `$HOME`, a renamed
62
+ * checkout or a reinstall is the script's filename.
63
+ *
64
+ * A signature MUST NOT change between releases. If it does, entries written by
65
+ * the previous version stop being recognised as ours and accumulate beside the
66
+ * new one instead of being replaced — the stale-duplicate failure this module's
67
+ * step 2 exists to prevent. A new command shape is therefore a new entry under
68
+ * an unchanged signature, never a new signature.
69
+ */
70
+ export const HOOK_SIGNATURES: Readonly<Record<string, string>> = {
71
+ '~/.augment/settings.json': 'augment-dispatcher.sh',
72
+ '.cursor/hooks.json': 'dispatch:hook --platform cursor',
73
+ '~/.cursor/hooks.json': 'cursor-dispatcher.sh',
74
+ '.windsurf/hooks.json': 'dispatch:hook --platform windsurf',
75
+ '~/.codeium/windsurf/hooks.json': 'windsurf-dispatcher.sh',
76
+ '.gemini/settings.json': 'dispatch:hook --platform gemini',
77
+ '~/.gemini/settings.json': 'gemini-dispatcher.sh',
78
+ };
79
+
80
+ /** Every command string reachable inside one hook entry, in document order. */
81
+ export function entryCommands(entry: unknown): string[] {
82
+ if (!isPlainObject(entry)) return [];
83
+ const out: string[] = [];
84
+ if (typeof entry['command'] === 'string') out.push(entry['command']);
85
+ const nested = entry['hooks'];
86
+ if (Array.isArray(nested)) {
87
+ for (const inner of nested) {
88
+ if (isPlainObject(inner) && typeof inner['command'] === 'string') {
89
+ out.push(inner['command']);
90
+ }
91
+ }
92
+ }
93
+ return out;
94
+ }
95
+
96
+ /** True when `entry` was written by this package, per the content signature. */
97
+ export function isManagedEntry(entry: unknown, signature: string): boolean {
98
+ if (signature === '') return false;
99
+ return entryCommands(entry).some((cmd) => cmd.includes(signature));
100
+ }
101
+
102
+ /**
103
+ * Merge one event's entry list: foreign entries kept in order, ours replaced.
104
+ *
105
+ * Exported for the fixture, which asserts the foreign entry is byte-identical
106
+ * and that exactly one managed entry survives a repeated install.
107
+ */
108
+ export function mergeEventEntries(
109
+ existing: readonly unknown[],
110
+ incoming: readonly unknown[],
111
+ signature: string,
112
+ ): unknown[] {
113
+ const kept = existing.filter((entry) => !isManagedEntry(entry, signature));
114
+ return [...kept.map((e) => deepcopy(e)), ...incoming.map((e) => deepcopy(e))];
115
+ }
116
+
117
+ /**
118
+ * Merge the `hooks` object of a host config.
119
+ *
120
+ * `existingHooks` may be absent or a non-object (a corrupt or foreign-shaped
121
+ * file) — then the patch is returned on its own, which is what `deep_merge`
122
+ * did and is the only answer available: there is no array to preserve.
123
+ */
124
+ export function mergeHookEvents(
125
+ existingHooks: unknown,
126
+ patchHooks: Record<string, unknown>,
127
+ signature: string,
128
+ ): Record<string, unknown> {
129
+ if (!isPlainObject(existingHooks)) return deepcopy(patchHooks);
130
+ const out: Record<string, unknown> = deepcopy(existingHooks);
131
+ for (const event of Object.keys(patchHooks)) {
132
+ const incoming = patchHooks[event];
133
+ const current = out[event];
134
+ if (!Array.isArray(incoming)) {
135
+ // Not an entry list — nothing array-shaped to preserve, overlay wins.
136
+ out[event] = deepcopy(incoming);
137
+ continue;
138
+ }
139
+ out[event] = mergeEventEntries(Array.isArray(current) ? current : [], incoming, signature);
140
+ }
141
+ return out;
142
+ }
143
+
144
+ /**
145
+ * Apply a host-config patch, routing the `hooks` key through per-event merging.
146
+ *
147
+ * Every other key keeps `deepMerge` semantics — only the shared hook lists need
148
+ * coexistence, and widening array-append to all keys would corrupt, for example,
149
+ * an `enabledPlugins` list or a settings array the host expects to own.
150
+ *
151
+ * `deepMergeFn` is injected rather than imported so the installer keeps passing
152
+ * its own function and this module stays independent of that file's internals.
153
+ */
154
+ export function mergeHostConfig(
155
+ existing: Record<string, unknown>,
156
+ patch: Record<string, unknown>,
157
+ signature: string,
158
+ deepMergeFn: (a: Record<string, unknown>, b: Record<string, unknown>) => Record<string, unknown>,
159
+ ): Record<string, unknown> {
160
+ const merged = deepMergeFn(existing, patch);
161
+ const patchHooks = patch['hooks'];
162
+ if (signature === '' || !isPlainObject(patchHooks)) return merged;
163
+ merged['hooks'] = mergeHookEvents(existing['hooks'], patchHooks, signature);
164
+ return merged;
165
+ }