@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
@@ -2,20 +2,17 @@ import { createRequire as __acCreateRequire } from 'node:module'; const require
2
2
  import {
3
3
  ZodFirstPartyTypeKind,
4
4
  settingsSchema
5
- } from "./chunk-UNCRJBT3.js";
5
+ } from "./chunk-JQVYKIZA.js";
6
6
  import {
7
7
  main
8
- } from "./chunk-6KFEC3G7.js";
8
+ } from "./chunk-CQWX336L.js";
9
9
  import {
10
+ GLOBAL_DEPLOY_SOURCES,
10
11
  RULE_SOURCE_REL
11
12
  } from "./chunk-WOKWX5PL.js";
12
- import {
13
- classifyOwnership,
14
- recordedHashesForRoot
15
- } from "./chunk-YDPILCOL.js";
16
13
  import {
17
14
  appendTxLog
18
- } from "./chunk-5R7HOLAF.js";
15
+ } from "./chunk-NYX3L2PZ.js";
19
16
  import {
20
17
  SCOPE_DETECT_AI_DIRS,
21
18
  SCOPE_DETECT_MANIFESTS
@@ -31,8 +28,12 @@ import {
31
28
  reap_stale,
32
29
  reap_tagged_orphans,
33
30
  record_deploy,
31
+ recorded_rel_files,
34
32
  save_inventory
35
- } from "./chunk-6KM6ORRY.js";
33
+ } from "./chunk-S4YWNRKO.js";
34
+ import {
35
+ write_managed_block
36
+ } from "./chunk-ULQRUR23.js";
36
37
  import {
37
38
  check_version,
38
39
  classify_mismatch,
@@ -56,19 +57,31 @@ import {
56
57
  ruleScopeFromSettings
57
58
  } from "./chunk-DMSZHXZS.js";
58
59
  import {
60
+ HOOK_SIGNATURES,
61
+ deepMerge,
62
+ isManagedEntry,
63
+ isPlainObject,
64
+ jsonEqual,
65
+ mergeHostConfig
66
+ } from "./chunk-DEIV7XP7.js";
67
+ import {
68
+ NO_RECORDED_HASHES,
59
69
  ScopeMismatchError,
70
+ classifyOwnership,
60
71
  manifest_path,
72
+ readRecordedHashes,
61
73
  read_manifest,
74
+ recordedHashesForRoot,
62
75
  upsert_tool,
63
76
  write_manifest
64
- } from "./chunk-4E2W63DA.js";
77
+ } from "./chunk-OKJUIAPS.js";
65
78
  import {
66
79
  require_dist
67
80
  } from "./chunk-OY53J6II.js";
68
81
  import {
69
82
  find_project_root_with_anchor,
70
83
  load_agent_settings
71
- } from "./chunk-FC75PGJE.js";
84
+ } from "./chunk-JY2I2DXV.js";
72
85
  import {
73
86
  event4u_root,
74
87
  legacy_xdg_root,
@@ -181,6 +194,7 @@ function _is_plain_object(value) {
181
194
  function collect_pointers(overlay, options = {}) {
182
195
  const prefix = options.prefix ?? "";
183
196
  const include_arrays = options.include_arrays ?? true;
197
+ const entry_signature = options.entry_signature ?? "";
184
198
  const entries = [];
185
199
  for (const [key, value] of Object.entries(overlay)) {
186
200
  const pointer = `${prefix}/${_escape_segment(String(key))}`;
@@ -189,14 +203,26 @@ function collect_pointers(overlay, options = {}) {
189
203
  entries.push({ json_pointer: pointer, value_hash: null });
190
204
  } else {
191
205
  entries.push(
192
- ...collect_pointers(value, { prefix: pointer, include_arrays })
206
+ ...collect_pointers(value, {
207
+ prefix: pointer,
208
+ include_arrays,
209
+ entry_signature
210
+ })
193
211
  );
194
212
  }
195
213
  } else if (Array.isArray(value)) {
196
- entries.push({
197
- json_pointer: pointer,
198
- value_hash: include_arrays ? value_hash(value) : null
199
- });
214
+ if (entry_signature !== "" && pointer.startsWith("/hooks/")) {
215
+ entries.push({
216
+ json_pointer: pointer,
217
+ value_hash: null,
218
+ entry_signature
219
+ });
220
+ } else {
221
+ entries.push({
222
+ json_pointer: pointer,
223
+ value_hash: include_arrays ? value_hash(value) : null
224
+ });
225
+ }
200
226
  } else {
201
227
  entries.push({ json_pointer: pointer, value_hash: null });
202
228
  }
@@ -207,11 +233,14 @@ function collect_pointers(overlay, options = {}) {
207
233
  return entries;
208
234
  }
209
235
  function build_merge_entries(file_label, overlay) {
210
- const pointers = collect_pointers(overlay);
236
+ const pointers = collect_pointers(overlay, {
237
+ entry_signature: HOOK_SIGNATURES[file_label] ?? ""
238
+ });
211
239
  return pointers.map((entry) => ({
212
240
  file: file_label,
213
241
  json_pointer: entry.json_pointer,
214
- value_hash: entry.value_hash
242
+ value_hash: entry.value_hash,
243
+ ...entry.entry_signature === void 0 ? {} : { entry_signature: entry.entry_signature }
215
244
  }));
216
245
  }
217
246
  function _split_segments(pointer) {
@@ -251,7 +280,33 @@ function subtract_pointers(doc, entries) {
251
280
  continue;
252
281
  }
253
282
  const [parent, leaf] = nav;
254
- if (expected !== null) {
283
+ const signature = entry.entry_signature ?? "";
284
+ if (signature !== "") {
285
+ const current = parent[leaf];
286
+ if (!Array.isArray(current)) {
287
+ warnings.push({
288
+ pointer,
289
+ reason: "missing",
290
+ expected_hash: null,
291
+ actual_hash: null
292
+ });
293
+ continue;
294
+ }
295
+ const kept = current.filter((item) => !isManagedEntry(item, signature));
296
+ if (kept.length === current.length) {
297
+ warnings.push({
298
+ pointer,
299
+ reason: "missing",
300
+ expected_hash: null,
301
+ actual_hash: null
302
+ });
303
+ continue;
304
+ }
305
+ if (kept.length > 0) {
306
+ parent[leaf] = kept;
307
+ continue;
308
+ }
309
+ } else if (expected !== null) {
255
310
  const actual = value_hash(parent[leaf]);
256
311
  if (actual !== expected) {
257
312
  warnings.push({
@@ -283,11 +338,89 @@ function subtract_pointers(doc, entries) {
283
338
  // src/scripts/install.ts
284
339
  import { spawn, spawnSync } from "node:child_process";
285
340
  import * as crypto5 from "node:crypto";
286
- import * as fs14 from "node:fs";
287
- import * as os3 from "node:os";
288
- import * as path12 from "node:path";
341
+ import * as fs20 from "node:fs";
342
+ import * as os6 from "node:os";
343
+ import * as path20 from "node:path";
289
344
  import process2 from "node:process";
290
- import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
345
+ import { fileURLToPath as fileURLToPath4, pathToFileURL } from "node:url";
346
+
347
+ // src/scripts/_lib/reserved_name_sweep.ts
348
+ import * as fs from "node:fs";
349
+ import * as path from "node:path";
350
+ function sweepReservedNames(commandsDir, currentFiles, isBuiltinName, recordedFiles) {
351
+ const reserved = [];
352
+ const foreign = [];
353
+ let entries = [];
354
+ try {
355
+ entries = fs.readdirSync(commandsDir).filter((f) => f.endsWith(".md"));
356
+ } catch {
357
+ return { reserved, foreign };
358
+ }
359
+ for (const fname of entries.sort()) {
360
+ const slug = fname.slice(0, -".md".length);
361
+ if (!isBuiltinName(slug)) continue;
362
+ const rel = `commands/${fname}`;
363
+ const ours = currentFiles.has(rel) || recordedFiles.has(rel);
364
+ if (!ours) {
365
+ foreign.push(slug);
366
+ continue;
367
+ }
368
+ fs.rmSync(path.join(commandsDir, fname), { force: true });
369
+ currentFiles.delete(rel);
370
+ reserved.push(slug);
371
+ }
372
+ return { reserved, foreign };
373
+ }
374
+
375
+ // src/scripts/_lib/host_env_write.ts
376
+ var YAML = __toESM(require_dist(), 1);
377
+ import * as fs2 from "node:fs";
378
+ import * as path2 from "node:path";
379
+ var WRITABLE_HOST_ENV = [
380
+ { variable: "BASH_MAX_OUTPUT_LENGTH", settingsKey: "bash_max_output_length" },
381
+ { variable: "MAX_MCP_OUTPUT_TOKENS", settingsKey: "max_mcp_output_tokens" }
382
+ ];
383
+ var SETTINGS_CANDIDATES = [
384
+ ["agents", "settings", ".agent-settings.yml"],
385
+ [".agent-settings.yml"]
386
+ ];
387
+ function readSettingsDoc(projectRoot) {
388
+ for (const parts of SETTINGS_CANDIDATES) {
389
+ const p = path2.join(projectRoot, ...parts);
390
+ let text;
391
+ try {
392
+ text = fs2.readFileSync(p, "utf-8");
393
+ } catch {
394
+ continue;
395
+ }
396
+ let doc;
397
+ try {
398
+ doc = YAML.parse(text, { version: "1.1" });
399
+ } catch {
400
+ return null;
401
+ }
402
+ return doc === null || doc === void 0 || typeof doc !== "object" ? null : doc;
403
+ }
404
+ return null;
405
+ }
406
+ function hostEnvBlock(settings) {
407
+ const root = settings;
408
+ const he = root?.["host_environment"];
409
+ const caps = he?.["request_size_caps"];
410
+ if (caps === void 0) return null;
411
+ const out = {};
412
+ for (const { variable, settingsKey } of WRITABLE_HOST_ENV) {
413
+ const v = caps[settingsKey];
414
+ if (typeof v === "number" && Number.isInteger(v) && v > 0) out[variable] = String(v);
415
+ }
416
+ return Object.keys(out).length === 0 ? null : out;
417
+ }
418
+ function withHostEnv(bridge, projectRoot, announce) {
419
+ const env = hostEnvBlock(readSettingsDoc(projectRoot));
420
+ if (env === null) return bridge;
421
+ announce(`.claude/settings.json: wrote ${Object.keys(env).join(", ")} (request-size caps)`);
422
+ return { ...bridge, env };
423
+ }
291
424
 
292
425
  // src/scripts/_lib/json_python_parity.ts
293
426
  function jsonStrNoAscii(s) {
@@ -497,8 +630,8 @@ function is_claude_builtin_name(slug) {
497
630
  }
498
631
 
499
632
  // src/scripts/_lib/mcp_bridge.ts
500
- import * as fs from "node:fs";
501
- import * as path from "node:path";
633
+ import * as fs3 from "node:fs";
634
+ import * as path3 from "node:path";
502
635
  var MCP_SERVER_KEY = "agent-config";
503
636
  var MCP_PACKAGE_NAME = "@event4u/agent-config";
504
637
  function mcpBridgeEntry(packageRoot) {
@@ -515,7 +648,7 @@ function mcpBridgeEntry(packageRoot) {
515
648
  }
516
649
  function readPackageVersion(packageRoot) {
517
650
  try {
518
- const raw = fs.readFileSync(path.join(packageRoot, "package.json"), "utf-8");
651
+ const raw = fs3.readFileSync(path3.join(packageRoot, "package.json"), "utf-8");
519
652
  const v = JSON.parse(raw).version;
520
653
  return typeof v === "string" && v.trim() !== "" ? v : null;
521
654
  } catch {
@@ -524,7 +657,7 @@ function readPackageVersion(packageRoot) {
524
657
  }
525
658
  function makeEnsureMcpBridge(mergeJsonFile) {
526
659
  return (projectRoot, force, packageRoot = projectRoot) => mergeJsonFile(
527
- path.join(projectRoot, ".mcp.json"),
660
+ path3.join(projectRoot, ".mcp.json"),
528
661
  mcpBridgeEntry(packageRoot),
529
662
  force,
530
663
  ".mcp.json"
@@ -550,7 +683,7 @@ function makeEnsureMcpRegistrations(mergeJsonFile) {
550
683
  const merged = {};
551
684
  for (const t of targets) {
552
685
  merged[t.toolId] = mergeJsonFile(
553
- path.join(projectRoot, ...t.relPath.split("/")),
686
+ path3.join(projectRoot, ...t.relPath.split("/")),
554
687
  mcpBridgeEntry(packageRoot),
555
688
  force,
556
689
  t.relPath
@@ -581,10 +714,10 @@ function projectionModeOf(raw) {
581
714
  return raw === "scoped" ? "scoped" : raw === "tiered" ? "tiered" : "legacy-all";
582
715
  }
583
716
  function resolveTierB(packageRoot) {
584
- const p = path.join(packageRoot, "agents", "runtime", "state", "skill-tiers.json");
585
- if (!fs.existsSync(p)) return null;
717
+ const p = path3.join(packageRoot, "agents", "runtime", "state", "skill-tiers.json");
718
+ if (!fs3.existsSync(p)) return null;
586
719
  try {
587
- const parsed = JSON.parse(fs.readFileSync(p, "utf-8"));
720
+ const parsed = JSON.parse(fs3.readFileSync(p, "utf-8"));
588
721
  if (!Array.isArray(parsed.tier_b)) return null;
589
722
  return new Set(parsed.tier_b.filter((n) => typeof n === "string"));
590
723
  } catch {
@@ -592,7 +725,7 @@ function resolveTierB(packageRoot) {
592
725
  }
593
726
  }
594
727
  function tierBPrunePredicate(tierB) {
595
- return (mdPath) => tierB.has(path.basename(path.dirname(mdPath)));
728
+ return (mdPath) => tierB.has(path3.basename(path3.dirname(mdPath)));
596
729
  }
597
730
  function tierBAdvisory(packageRoot) {
598
731
  const tierB = resolveTierB(packageRoot);
@@ -621,35 +754,35 @@ function applyTieredPrune(deployResults, packageRoot, pruneBy) {
621
754
 
622
755
  // src/install/conflictTracker.ts
623
756
  import * as crypto2 from "node:crypto";
624
- import * as fs3 from "node:fs";
625
- import * as path3 from "node:path";
757
+ import * as fs5 from "node:fs";
758
+ import * as path5 from "node:path";
626
759
 
627
760
  // src/install/fsPrimitives.ts
628
761
  import * as crypto from "node:crypto";
629
- import * as fs2 from "node:fs";
630
- import * as path2 from "node:path";
762
+ import * as fs4 from "node:fs";
763
+ import * as path4 from "node:path";
631
764
  function resolvePath(p) {
632
765
  try {
633
- return fs2.realpathSync(path2.resolve(p));
766
+ return fs4.realpathSync(path4.resolve(p));
634
767
  } catch {
635
- return path2.resolve(p);
768
+ return path4.resolve(p);
636
769
  }
637
770
  }
638
771
  function pathExists(p) {
639
772
  try {
640
- fs2.statSync(p);
773
+ fs4.statSync(p);
641
774
  return true;
642
775
  } catch {
643
776
  return false;
644
777
  }
645
778
  }
646
779
  function mkdirp(p) {
647
- fs2.mkdirSync(p, { recursive: true });
780
+ fs4.mkdirSync(p, { recursive: true });
648
781
  }
649
782
  function sha256OfFile(p) {
650
783
  let data;
651
784
  try {
652
- data = fs2.readFileSync(p);
785
+ data = fs4.readFileSync(p);
653
786
  } catch {
654
787
  return null;
655
788
  }
@@ -690,20 +823,20 @@ function createConflictTracker(host) {
690
823
  function recordedHashFor(target) {
691
824
  if (conflictState.root === null) return void 0;
692
825
  conflictState.recorded ??= recordedHashesForRoot(conflictState.root);
693
- const plain = path3.resolve(target);
826
+ const plain = path5.resolve(target);
694
827
  if (conflictState.recorded.has(plain)) return conflictState.recorded.get(plain);
695
828
  const real = resolvePath(target);
696
829
  return real === plain ? void 0 : conflictState.recorded.get(real);
697
830
  }
698
831
  function stageInto(target, sidecar, produce) {
699
- mkdirp(path3.dirname(sidecar));
700
- const tmp = path3.join(
701
- path3.dirname(sidecar),
702
- `.${path3.basename(sidecar)}.${process.pid}.${crypto2.randomBytes(6).toString("hex")}${path3.extname(target)}`
832
+ mkdirp(path5.dirname(sidecar));
833
+ const tmp = path5.join(
834
+ path5.dirname(sidecar),
835
+ `.${path5.basename(sidecar)}.${process.pid}.${crypto2.randomBytes(6).toString("hex")}${path5.extname(target)}`
703
836
  );
704
837
  const discard = () => {
705
838
  try {
706
- fs3.unlinkSync(tmp);
839
+ fs5.unlinkSync(tmp);
707
840
  } catch {
708
841
  }
709
842
  };
@@ -730,7 +863,7 @@ function createConflictTracker(host) {
730
863
  }
731
864
  }
732
865
  try {
733
- fs3.renameSync(tmp, sidecar);
866
+ fs5.renameSync(tmp, sidecar);
734
867
  } catch (exc) {
735
868
  discard();
736
869
  host.fail(
@@ -779,7 +912,7 @@ function createConflictTracker(host) {
779
912
  preserve(target, source, packageRoot) {
780
913
  const sidecar = sidecarPathFor(target);
781
914
  stageInto(target, sidecar, (tmp) => {
782
- fs3.copyFileSync(source, tmp);
915
+ fs5.copyFileSync(source, tmp);
783
916
  host.tagDeployed(tmp, source, packageRoot);
784
917
  });
785
918
  record(target, sidecar);
@@ -795,7 +928,7 @@ function createConflictTracker(host) {
795
928
  */
796
929
  preserveContent(target, content) {
797
930
  const sidecar = sidecarPathFor(target);
798
- stageInto(target, sidecar, (tmp) => fs3.writeFileSync(tmp, content, "utf-8"));
931
+ stageInto(target, sidecar, (tmp) => fs5.writeFileSync(tmp, content, "utf-8"));
799
932
  record(target, sidecar);
800
933
  },
801
934
  /**
@@ -814,10 +947,10 @@ function createConflictTracker(host) {
814
947
  }
815
948
 
816
949
  // src/install/manifestFiles.ts
817
- var YAML = __toESM(require_dist(), 1);
818
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
950
+ var YAML2 = __toESM(require_dist(), 1);
951
+ import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
819
952
  import { homedir } from "node:os";
820
- import { isAbsolute, join as join3, resolve as resolve3 } from "node:path";
953
+ import { isAbsolute, join as join5, resolve as resolve3 } from "node:path";
821
954
  function fileEntry(p, kind, hashContent) {
822
955
  return { path: p, kind, sha256: hashContent ? sha256OfFile(p) : null };
823
956
  }
@@ -840,7 +973,7 @@ function filesByToolFromBridges(tools, projectRoot, scope, bridgeMarker) {
840
973
  for (const toolId of [...tools].sort()) {
841
974
  const marker = bridgeMarker(toolId, scope);
842
975
  if (!marker) continue;
843
- const markerPath = isAbsolute(marker) ? marker : join3(projectRoot, marker);
976
+ const markerPath = isAbsolute(marker) ? marker : join5(projectRoot, marker);
844
977
  out[toolId] = [fileEntry(markerPath, "bridge", false)];
845
978
  }
846
979
  return out;
@@ -848,7 +981,7 @@ function filesByToolFromBridges(tools, projectRoot, scope, bridgeMarker) {
848
981
  function expanduser(p) {
849
982
  if (p === "~") return homedir();
850
983
  if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
851
- return join3(homedir(), p.slice(2));
984
+ return join5(homedir(), p.slice(2));
852
985
  }
853
986
  return p;
854
987
  }
@@ -861,7 +994,7 @@ function readRecordedByTool(manifestPath, projectRoot) {
861
994
  if (!existsSync2(manifestPath)) return out;
862
995
  let doc;
863
996
  try {
864
- doc = YAML.parse(readFileSync3(manifestPath, "utf8"));
997
+ doc = YAML2.parse(readFileSync4(manifestPath, "utf8"));
865
998
  } catch {
866
999
  return out;
867
1000
  }
@@ -940,8 +1073,9 @@ function preservedIndex(preservedTargets, staged) {
940
1073
  }
941
1074
 
942
1075
  // src/scripts/_lib/rule_layer_overlap.ts
943
- import * as fs4 from "node:fs";
944
- import * as path4 from "node:path";
1076
+ import * as fs6 from "node:fs";
1077
+ import * as os from "node:os";
1078
+ import * as path6 from "node:path";
945
1079
  var INSTALLER_PROVENANCE_KEYS = ["package", "source_path"];
946
1080
  function stripProvenance(text) {
947
1081
  const lines = text.split("\n");
@@ -992,17 +1126,23 @@ function compareLayers(global_layer, project_layer) {
992
1126
  redundant_chars
993
1127
  };
994
1128
  }
1129
+ function hostRuleLayerDirs(projectRoot) {
1130
+ return [
1131
+ path6.join(os.homedir(), ".claude", "rules"),
1132
+ path6.join(projectRoot, ".claude", "rules")
1133
+ ];
1134
+ }
995
1135
  function readRuleLayer(dir) {
996
1136
  let names;
997
1137
  try {
998
- names = fs4.readdirSync(dir);
1138
+ names = fs6.readdirSync(dir);
999
1139
  } catch {
1000
1140
  return null;
1001
1141
  }
1002
1142
  const files = /* @__PURE__ */ new Map();
1003
1143
  for (const name of names.filter((n) => n.endsWith(".md")).sort()) {
1004
1144
  try {
1005
- files.set(name, fs4.readFileSync(path4.join(dir, name), "utf-8"));
1145
+ files.set(name, fs6.readFileSync(path6.join(dir, name), "utf-8"));
1006
1146
  } catch {
1007
1147
  continue;
1008
1148
  }
@@ -1010,7 +1150,7 @@ function readRuleLayer(dir) {
1010
1150
  return { dir, files };
1011
1151
  }
1012
1152
  function claudeMdExcludesGlob(dir) {
1013
- return `${path4.resolve(dir).replace(/\/+$/, "")}/**`;
1153
+ return `${path6.resolve(dir).replace(/\/+$/, "")}/**`;
1014
1154
  }
1015
1155
  function mergeClaudeMdExcludes(existing, entry) {
1016
1156
  if (!Array.isArray(existing)) return [entry];
@@ -1041,25 +1181,25 @@ function decideLayerAction(report, choice, global_dir, project_dir) {
1041
1181
  // src/scripts/_lib/install_drift.ts
1042
1182
  var import_yaml = __toESM(require_dist(), 1);
1043
1183
  import * as crypto3 from "node:crypto";
1044
- import * as fs5 from "node:fs";
1045
- import * as os from "node:os";
1046
- import * as path5 from "node:path";
1184
+ import * as fs7 from "node:fs";
1185
+ import * as os2 from "node:os";
1186
+ import * as path7 from "node:path";
1047
1187
  function expanduser2(p) {
1048
1188
  if (p === "~") {
1049
- return os.homedir();
1189
+ return os2.homedir();
1050
1190
  }
1051
1191
  if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
1052
- return path5.join(os.homedir(), p.slice(2));
1192
+ return path7.join(os2.homedir(), p.slice(2));
1053
1193
  }
1054
1194
  return p;
1055
1195
  }
1056
1196
  function resolve_entry_path(project_root, raw) {
1057
1197
  const p = expanduser2(raw);
1058
- return path5.isAbsolute(p) ? p : path5.join(project_root, p);
1198
+ return path7.isAbsolute(p) ? p : path7.join(project_root, p);
1059
1199
  }
1060
1200
  function sha256_of_file(p) {
1061
1201
  try {
1062
- return crypto3.createHash("sha256").update(fs5.readFileSync(p)).digest("hex");
1202
+ return crypto3.createHash("sha256").update(fs7.readFileSync(p)).digest("hex");
1063
1203
  } catch {
1064
1204
  return null;
1065
1205
  }
@@ -1068,7 +1208,7 @@ function collect_drift(project_root, env) {
1068
1208
  const target = manifest_path(project_root, env);
1069
1209
  let text;
1070
1210
  try {
1071
- text = fs5.readFileSync(target, "utf-8");
1211
+ text = fs7.readFileSync(target, "utf-8");
1072
1212
  } catch {
1073
1213
  return null;
1074
1214
  }
@@ -1113,7 +1253,7 @@ function collect_drift(project_root, env) {
1113
1253
  continue;
1114
1254
  }
1115
1255
  const resolved = resolve_entry_path(project_root, raw_path);
1116
- if (!fs5.existsSync(resolved)) {
1256
+ if (!fs7.existsSync(resolved)) {
1117
1257
  out.push({
1118
1258
  tool_id,
1119
1259
  path: resolved,
@@ -1166,15 +1306,15 @@ function format_drift_report(entries) {
1166
1306
  }
1167
1307
 
1168
1308
  // src/scripts/_lib/skill_catalogue.ts
1169
- import * as fs6 from "node:fs";
1170
- import * as path6 from "node:path";
1309
+ import * as fs8 from "node:fs";
1310
+ import * as path8 from "node:path";
1171
1311
  var PROJECT_CATALOGUE_ROOTS = ["src/skills", ".claude/skills"];
1172
1312
  var HOST_CATALOGUE_ROOT = ".claude/skills";
1173
1313
  var DEFAULT_CATALOGUE_ROOTS = [
1174
1314
  ...PROJECT_CATALOGUE_ROOTS,
1175
1315
  `~/${HOST_CATALOGUE_ROOT}`
1176
1316
  ];
1177
- var OBSERVATION_LOG = path6.join(
1317
+ var OBSERVATION_LOG = path8.join(
1178
1318
  "agents",
1179
1319
  "evidence",
1180
1320
  "metrics",
@@ -1218,9 +1358,9 @@ function descriptionOf(frontmatter) {
1218
1358
  return "";
1219
1359
  }
1220
1360
  function readProjectedCatalogue(root) {
1221
- const names = fs6.readdirSync(root).filter((n) => fs6.existsSync(path6.join(root, n, "SKILL.md"))).sort();
1361
+ const names = fs8.readdirSync(root).filter((n) => fs8.existsSync(path8.join(root, n, "SKILL.md"))).sort();
1222
1362
  return names.map((name, index) => {
1223
- const content = fs6.readFileSync(path6.join(root, name, "SKILL.md"), "utf-8");
1363
+ const content = fs8.readFileSync(path8.join(root, name, "SKILL.md"), "utf-8");
1224
1364
  const frontmatter = frontmatterOf(content);
1225
1365
  const description = descriptionOf(frontmatter);
1226
1366
  return {
@@ -1237,12 +1377,12 @@ function truncationModeOf(record) {
1237
1377
  return record.truncation_mode ?? "per-entry";
1238
1378
  }
1239
1379
  function markdownFilesUnder(root) {
1240
- if (!fs6.existsSync(root)) return [];
1380
+ if (!fs8.existsSync(root)) return [];
1241
1381
  const out = [];
1242
1382
  const walk = (dir) => {
1243
- for (const entry of fs6.readdirSync(dir, { withFileTypes: true })) {
1244
- const full = path6.join(dir, entry.name);
1245
- if (fs6.statSync(full).isDirectory()) walk(full);
1383
+ for (const entry of fs8.readdirSync(dir, { withFileTypes: true })) {
1384
+ const full = path8.join(dir, entry.name);
1385
+ if (fs8.statSync(full).isDirectory()) walk(full);
1246
1386
  else if (entry.name.endsWith(".md")) out.push(full);
1247
1387
  }
1248
1388
  };
@@ -1250,9 +1390,9 @@ function markdownFilesUnder(root) {
1250
1390
  return out;
1251
1391
  }
1252
1392
  function measureCatalogueVolume(host, root) {
1253
- const skillsRoot = path6.join(root, "skills");
1254
- const skills = fs6.existsSync(skillsRoot) ? readProjectedCatalogue(skillsRoot) : [];
1255
- const commandEntries = markdownFilesUnder(path6.join(root, "commands")).length;
1393
+ const skillsRoot = path8.join(root, "skills");
1394
+ const skills = fs8.existsSync(skillsRoot) ? readProjectedCatalogue(skillsRoot) : [];
1395
+ const commandEntries = markdownFilesUnder(path8.join(root, "commands")).length;
1256
1396
  return {
1257
1397
  host,
1258
1398
  root,
@@ -1330,9 +1470,9 @@ function migrationPromptLines(host, eligibility, settingsPath) {
1330
1470
  ];
1331
1471
  }
1332
1472
  function readObservationLog(logPath) {
1333
- if (!fs6.existsSync(logPath)) return [];
1473
+ if (!fs8.existsSync(logPath)) return [];
1334
1474
  const out = [];
1335
- for (const line of fs6.readFileSync(logPath, "utf-8").split("\n")) {
1475
+ for (const line of fs8.readFileSync(logPath, "utf-8").split("\n")) {
1336
1476
  const trimmed = line.trim();
1337
1477
  if (trimmed.length === 0) continue;
1338
1478
  try {
@@ -1373,8 +1513,8 @@ function isInteractiveSession(probe) {
1373
1513
 
1374
1514
  // src/scripts/_lib/claude_desktop_bundler.ts
1375
1515
  import * as crypto4 from "node:crypto";
1376
- import * as fs7 from "node:fs";
1377
- import * as path7 from "node:path";
1516
+ import * as fs9 from "node:fs";
1517
+ import * as path9 from "node:path";
1378
1518
 
1379
1519
  // src/scripts/_lib/zip_min.ts
1380
1520
  import * as zlib from "node:zlib";
@@ -1481,7 +1621,7 @@ function _is_excluded(rel_parts) {
1481
1621
  }
1482
1622
  function _is_dir(p) {
1483
1623
  try {
1484
- return fs7.statSync(p).isDirectory();
1624
+ return fs9.statSync(p).isDirectory();
1485
1625
  } catch {
1486
1626
  return false;
1487
1627
  }
@@ -1493,12 +1633,12 @@ function _compare_rel_parts(a, b) {
1493
1633
  }
1494
1634
  function _walk_skill_files(skill_dir) {
1495
1635
  const out = [];
1496
- const resolved = fs7.realpathSync(skill_dir);
1636
+ const resolved = fs9.realpathSync(skill_dir);
1497
1637
  const walk = (root, relRoot) => {
1498
1638
  const dirNames = [];
1499
1639
  const fileNames = [];
1500
- for (const dirent of fs7.readdirSync(root, { withFileTypes: true })) {
1501
- const full = path7.join(root, dirent.name);
1640
+ for (const dirent of fs9.readdirSync(root, { withFileTypes: true })) {
1641
+ const full = path9.join(root, dirent.name);
1502
1642
  const isDir2 = dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full);
1503
1643
  if (isDir2) {
1504
1644
  dirNames.push(dirent.name);
@@ -1511,13 +1651,13 @@ function _walk_skill_files(skill_dir) {
1511
1651
  if (_is_excluded(rel_parts)) {
1512
1652
  continue;
1513
1653
  }
1514
- out.push([path7.join(root, fname), rel_parts]);
1654
+ out.push([path9.join(root, fname), rel_parts]);
1515
1655
  }
1516
1656
  for (const dname of dirNames) {
1517
1657
  if (_is_excluded([dname])) {
1518
1658
  continue;
1519
1659
  }
1520
- walk(path7.join(root, dname), [...relRoot, dname]);
1660
+ walk(path9.join(root, dname), [...relRoot, dname]);
1521
1661
  }
1522
1662
  };
1523
1663
  walk(resolved, []);
@@ -1530,53 +1670,53 @@ function _manifest_digest(files) {
1530
1670
  const rel = rel_parts.join("/");
1531
1671
  h.update(Buffer.from(rel, "utf-8"));
1532
1672
  h.update(Buffer.from([0]));
1533
- h.update(crypto4.createHash("sha256").update(fs7.readFileSync(abs_path)).digest());
1673
+ h.update(crypto4.createHash("sha256").update(fs9.readFileSync(abs_path)).digest());
1534
1674
  h.update(Buffer.from([0]));
1535
1675
  }
1536
1676
  return h.digest("hex");
1537
1677
  }
1538
1678
  function _atomic_write_zip(zip_path, files) {
1539
- fs7.mkdirSync(path7.dirname(zip_path), { recursive: true });
1540
- const stem = path7.basename(zip_path, path7.extname(zip_path));
1541
- const tmp_path = path7.join(
1542
- path7.dirname(zip_path),
1679
+ fs9.mkdirSync(path9.dirname(zip_path), { recursive: true });
1680
+ const stem = path9.basename(zip_path, path9.extname(zip_path));
1681
+ const tmp_path = path9.join(
1682
+ path9.dirname(zip_path),
1543
1683
  `.${stem}.${crypto4.randomBytes(6).toString("hex")}.zip.tmp`
1544
1684
  );
1545
1685
  try {
1546
1686
  const entries = files.map(([abs_path, rel_parts]) => ({
1547
1687
  name: rel_parts.join("/"),
1548
- data: fs7.readFileSync(abs_path)
1688
+ data: fs9.readFileSync(abs_path)
1549
1689
  }));
1550
- fs7.writeFileSync(tmp_path, zip_write_sync(entries));
1551
- fs7.renameSync(tmp_path, zip_path);
1690
+ fs9.writeFileSync(tmp_path, zip_write_sync(entries));
1691
+ fs9.renameSync(tmp_path, zip_path);
1552
1692
  } finally {
1553
- if (fs7.existsSync(tmp_path)) {
1554
- fs7.unlinkSync(tmp_path);
1693
+ if (fs9.existsSync(tmp_path)) {
1694
+ fs9.unlinkSync(tmp_path);
1555
1695
  }
1556
1696
  }
1557
1697
  }
1558
1698
  function _write_if_changed(dest_dir, slug, files, force, written) {
1559
1699
  const digest = _manifest_digest(files);
1560
- const zip_path = path7.join(dest_dir, `${slug}.zip`);
1561
- const digest_path = path7.join(dest_dir, `${slug}.sha256`);
1562
- const recorded = fs7.existsSync(digest_path) ? fs7.readFileSync(digest_path, "utf-8").trim() : "";
1563
- if (!force && recorded === digest && fs7.existsSync(zip_path)) {
1700
+ const zip_path = path9.join(dest_dir, `${slug}.zip`);
1701
+ const digest_path = path9.join(dest_dir, `${slug}.sha256`);
1702
+ const recorded = fs9.existsSync(digest_path) ? fs9.readFileSync(digest_path, "utf-8").trim() : "";
1703
+ if (!force && recorded === digest && fs9.existsSync(zip_path)) {
1564
1704
  return;
1565
1705
  }
1566
1706
  _atomic_write_zip(zip_path, files);
1567
- fs7.writeFileSync(digest_path, digest + "\n", "utf-8");
1707
+ fs9.writeFileSync(digest_path, digest + "\n", "utf-8");
1568
1708
  written.push(zip_path);
1569
1709
  }
1570
1710
  function build_skill_bundles(package_root, dest_dir, force = false, curation = null) {
1571
- const skills_root = path7.join(package_root, "dist/agent-src", "skills");
1711
+ const skills_root = path9.join(package_root, "dist/agent-src", "skills");
1572
1712
  if (!_is_dir(skills_root)) {
1573
1713
  return [];
1574
1714
  }
1575
- fs7.mkdirSync(dest_dir, { recursive: true });
1715
+ fs9.mkdirSync(dest_dir, { recursive: true });
1576
1716
  const written = [];
1577
- for (const name of fs7.readdirSync(skills_root).sort()) {
1578
- const entry = path7.join(skills_root, name);
1579
- const isSymlink2 = fs7.lstatSync(entry).isSymbolicLink();
1717
+ for (const name of fs9.readdirSync(skills_root).sort()) {
1718
+ const entry = path9.join(skills_root, name);
1719
+ const isSymlink2 = fs9.lstatSync(entry).isSymbolicLink();
1580
1720
  if (!(_is_dir(entry) || isSymlink2)) {
1581
1721
  continue;
1582
1722
  }
@@ -1584,8 +1724,8 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
1584
1724
  if (curation !== null && !curation.includes(skill_name)) {
1585
1725
  continue;
1586
1726
  }
1587
- const skill_md = path7.join(entry, "SKILL.md");
1588
- if (!fs7.existsSync(skill_md)) {
1727
+ const skill_md = path9.join(entry, "SKILL.md");
1728
+ if (!fs9.existsSync(skill_md)) {
1589
1729
  continue;
1590
1730
  }
1591
1731
  const files = _walk_skill_files(entry);
@@ -1597,15 +1737,15 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
1597
1737
  return written;
1598
1738
  }
1599
1739
  function _command_slug(source_file, commands_root) {
1600
- const rel = path7.relative(commands_root, source_file);
1601
- const noExt = rel.slice(0, rel.length - path7.extname(rel).length);
1602
- return noExt.split(path7.sep).join("-");
1740
+ const rel = path9.relative(commands_root, source_file);
1741
+ const noExt = rel.slice(0, rel.length - path9.extname(rel).length);
1742
+ return noExt.split(path9.sep).join("-");
1603
1743
  }
1604
1744
  function _iter_command_files(commands_root) {
1605
1745
  const found = [];
1606
1746
  const walk = (dir) => {
1607
- for (const dirent of fs7.readdirSync(dir, { withFileTypes: true })) {
1608
- const full = path7.join(dir, dirent.name);
1747
+ for (const dirent of fs9.readdirSync(dir, { withFileTypes: true })) {
1748
+ const full = path9.join(dir, dirent.name);
1609
1749
  if (dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full)) {
1610
1750
  walk(full);
1611
1751
  } else if (dirent.name.endsWith(".md")) {
@@ -1615,21 +1755,21 @@ function _iter_command_files(commands_root) {
1615
1755
  };
1616
1756
  walk(commands_root);
1617
1757
  found.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
1618
- return found.filter((source_file) => path7.basename(source_file) !== "AGENTS.md");
1758
+ return found.filter((source_file) => path9.basename(source_file) !== "AGENTS.md");
1619
1759
  }
1620
1760
  function build_command_bundles(package_root, dest_dir, force = false, curation = null) {
1621
- const commands_root = path7.join(package_root, "dist/agent-src", "commands");
1761
+ const commands_root = path9.join(package_root, "dist/agent-src", "commands");
1622
1762
  if (!_is_dir(commands_root)) {
1623
1763
  return [];
1624
1764
  }
1625
- const skills_root = path7.join(package_root, "dist/agent-src", "skills");
1765
+ const skills_root = path9.join(package_root, "dist/agent-src", "skills");
1626
1766
  let skill_names = /* @__PURE__ */ new Set();
1627
1767
  if (_is_dir(skills_root)) {
1628
1768
  skill_names = new Set(
1629
- fs7.readdirSync(skills_root).filter((name) => _is_dir(path7.join(skills_root, name)))
1769
+ fs9.readdirSync(skills_root).filter((name) => _is_dir(path9.join(skills_root, name)))
1630
1770
  );
1631
1771
  }
1632
- fs7.mkdirSync(dest_dir, { recursive: true });
1772
+ fs9.mkdirSync(dest_dir, { recursive: true });
1633
1773
  const written = [];
1634
1774
  for (const source_file of _iter_command_files(commands_root)) {
1635
1775
  const slug = _command_slug(source_file, commands_root);
@@ -1639,7 +1779,7 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
1639
1779
  if (curation !== null && !curation.includes(slug)) {
1640
1780
  continue;
1641
1781
  }
1642
- const files = [[fs7.realpathSync(source_file), ["SKILL.md"]]];
1782
+ const files = [[fs9.realpathSync(source_file), ["SKILL.md"]]];
1643
1783
  _write_if_changed(dest_dir, slug, files, force, written);
1644
1784
  }
1645
1785
  return written;
@@ -1647,15 +1787,25 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
1647
1787
 
1648
1788
  // src/scripts/hooks/host_lowering.ts
1649
1789
  var import_yaml2 = __toESM(require_dist(), 1);
1650
- import * as fs8 from "node:fs";
1651
- import * as path8 from "node:path";
1790
+ import * as fs10 from "node:fs";
1791
+ import * as path10 from "node:path";
1652
1792
  import { fileURLToPath } from "node:url";
1793
+
1794
+ // src/scripts/hooks/table_fingerprint.ts
1795
+ import { createHash as createHash5 } from "node:crypto";
1796
+ function tableFingerprint(text) {
1797
+ const digest = createHash5("sha256").update(text, "utf-8").digest("hex");
1798
+ return `${digest}:${String(text.length)}`;
1799
+ }
1800
+
1801
+ // src/scripts/hooks/host_lowering.ts
1653
1802
  var _IN_BUNDLE = true;
1654
- var _REPO_ROOT = path8.resolve(
1655
- path8.dirname(fileURLToPath(import.meta.url)),
1803
+ var _REPO_ROOT = path10.resolve(
1804
+ path10.dirname(fileURLToPath(import.meta.url)),
1656
1805
  ..._IN_BUNDLE ? ["..", ".."] : ["..", "..", ".."]
1657
1806
  );
1658
- var HOST_LOWERING_PATH = path8.join(_REPO_ROOT, "src", "scripts", "hooks", "host_lowering.yaml");
1807
+ var HOST_LOWERING_PATH = path10.join(_REPO_ROOT, "src", "scripts", "hooks", "host_lowering.yaml");
1808
+ var HOST_LOWERING_JSON_PATH = path10.join(_REPO_ROOT, "src", "scripts", "hooks", "host_lowering.json");
1659
1809
  var DEFAULT_SURFACE = "any";
1660
1810
  function _asString(v) {
1661
1811
  if (v === null || v === void 0) return null;
@@ -1663,7 +1813,9 @@ function _asString(v) {
1663
1813
  return String(v);
1664
1814
  }
1665
1815
  function _parse(text) {
1666
- const raw = (0, import_yaml2.parse)(text);
1816
+ return _structure((0, import_yaml2.parse)(text));
1817
+ }
1818
+ function _structure(raw) {
1667
1819
  const hostsRaw = raw?.["hosts"];
1668
1820
  if (typeof hostsRaw !== "object" || hostsRaw === null) {
1669
1821
  throw new Error("host_lowering.yaml: missing `hosts:` map");
@@ -1687,6 +1839,7 @@ function _parse(text) {
1687
1839
  verified = {
1688
1840
  docs_at: _asString(verifiedRaw["docs_at"]),
1689
1841
  docs_url: _asString(verifiedRaw["docs_url"]),
1842
+ docs_digest: _asString(verifiedRaw["docs_digest"]),
1690
1843
  probe_at: _asString(verifiedRaw["probe_at"]),
1691
1844
  host_version: _asString(verifiedRaw["host_version"]),
1692
1845
  expires
@@ -1700,7 +1853,9 @@ function _parse(text) {
1700
1853
  const be = rv["block_exit"];
1701
1854
  const row = {
1702
1855
  native,
1703
- block_exit: typeof be === "number" ? be : null
1856
+ block_exit: typeof be === "number" ? be : null,
1857
+ answered_at: _asString(rv["answered_at"]),
1858
+ docs_url: _asString(rv["docs_url"])
1704
1859
  };
1705
1860
  if (typeof rv["matcher"] === "string") row.matcher = rv["matcher"];
1706
1861
  slots.set(slot, row);
@@ -1721,9 +1876,47 @@ function _parse(text) {
1721
1876
  }
1722
1877
  var _cache = null;
1723
1878
  function loadHostLowering() {
1724
- if (_cache === null) _cache = _parse(fs8.readFileSync(HOST_LOWERING_PATH, "utf-8"));
1879
+ if (_cache !== null) return _cache;
1880
+ const text = fs10.readFileSync(HOST_LOWERING_PATH, "utf-8");
1881
+ let compiled;
1882
+ try {
1883
+ compiled = fs10.readFileSync(HOST_LOWERING_JSON_PATH, "utf-8");
1884
+ } catch {
1885
+ compiled = null;
1886
+ }
1887
+ _cache = resolveTable(text, compiled);
1725
1888
  return _cache;
1726
1889
  }
1890
+ function resolveTable(yamlText, compiledText) {
1891
+ if (compiledText !== null) {
1892
+ try {
1893
+ const raw = JSON.parse(compiledText);
1894
+ const table = raw["table"];
1895
+ if (raw["fingerprint"] === tableFingerprint(yamlText) && typeof table === "object" && table !== null && // road-to-blocking-severities 2.3 — the BODY, not only its
1896
+ // label. `fingerprint` above says the file was compiled from
1897
+ // the YAML as it stands; it says nothing about whether the
1898
+ // body underneath was edited afterwards, and an edited body
1899
+ // with an untouched label was served. `body_fingerprint` is
1900
+ // the fingerprint of the exact bytes the compiler emitted, so
1901
+ // re-stringifying what we just parsed recovers them.
1902
+ //
1903
+ // A compiled file WITHOUT the field — one written before 2.3 —
1904
+ // falls through here, which is slow and correct: accepting it
1905
+ // would make the check optional and therefore absent.
1906
+ //
1907
+ // What it covers is a partial edit, never an author: anyone
1908
+ // who edits the body can recompute this as easily as the
1909
+ // compiler. The deny in `block_plumbing_writes` and the
1910
+ // ratification record are the mechanisms aimed at an author;
1911
+ // this one is aimed at a mistake.
1912
+ raw["body_fingerprint"] === tableFingerprint(JSON.stringify(table))) {
1913
+ return _structure(table);
1914
+ }
1915
+ } catch {
1916
+ }
1917
+ }
1918
+ return _parse(yamlText);
1919
+ }
1727
1920
  function surfaceRow(host, surface = DEFAULT_SURFACE, table = loadHostLowering()) {
1728
1921
  return table.get(host)?.get(surface) ?? table.get(host)?.get(DEFAULT_SURFACE) ?? null;
1729
1922
  }
@@ -1740,26 +1933,26 @@ function hostBindings(host, table = loadHostLowering()) {
1740
1933
  }
1741
1934
 
1742
1935
  // src/install/partitionEligibility.ts
1743
- import * as fs10 from "node:fs";
1744
- import * as os2 from "node:os";
1936
+ import * as fs12 from "node:fs";
1937
+ import * as os3 from "node:os";
1745
1938
 
1746
1939
  // src/install/hostLayerFingerprint.ts
1747
- import { createHash as createHash5 } from "node:crypto";
1748
- import * as fs9 from "node:fs";
1749
- import * as path9 from "node:path";
1940
+ import { createHash as createHash6 } from "node:crypto";
1941
+ import * as fs11 from "node:fs";
1942
+ import * as path11 from "node:path";
1750
1943
  var FINGERPRINT_SCHEMA = 1;
1751
1944
  function collectFiles(dir) {
1752
1945
  const out = [];
1753
1946
  const walk = (d) => {
1754
1947
  let entries;
1755
1948
  try {
1756
- entries = fs9.readdirSync(d, { withFileTypes: true });
1949
+ entries = fs11.readdirSync(d, { withFileTypes: true });
1757
1950
  } catch {
1758
1951
  return;
1759
1952
  }
1760
1953
  const sorted = [...entries].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
1761
1954
  for (const e of sorted) {
1762
- const p = path9.join(d, e.name);
1955
+ const p = path11.join(d, e.name);
1763
1956
  if (e.isDirectory()) {
1764
1957
  walk(p);
1765
1958
  } else if (e.isFile()) {
@@ -1771,15 +1964,15 @@ function collectFiles(dir) {
1771
1964
  return out.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
1772
1965
  }
1773
1966
  function fingerprintLayers(layers) {
1774
- const h = createHash5("sha256");
1967
+ const h = createHash6("sha256");
1775
1968
  h.update(`v${FINGERPRINT_SCHEMA}\0`);
1776
1969
  for (const layer of layers) {
1777
1970
  h.update(`layer:${layer.label}\0`);
1778
1971
  for (const file of collectFiles(layer.root)) {
1779
- h.update(path9.relative(layer.root, file));
1972
+ h.update(path11.relative(layer.root, file));
1780
1973
  h.update("\0");
1781
1974
  try {
1782
- h.update(fs9.readFileSync(file));
1975
+ h.update(fs11.readFileSync(file));
1783
1976
  } catch {
1784
1977
  h.update("\0unreadable\0");
1785
1978
  }
@@ -1789,11 +1982,11 @@ function fingerprintLayers(layers) {
1789
1982
  return h.digest("hex");
1790
1983
  }
1791
1984
  function hostLayerInputs(userHome) {
1792
- const claude = path9.join(userHome, ".claude");
1985
+ const claude = path11.join(userHome, ".claude");
1793
1986
  return [
1794
- { label: "rules", root: path9.join(claude, "rules") },
1795
- { label: "skills", root: path9.join(claude, "skills") },
1796
- { label: "commands", root: path9.join(claude, "commands") }
1987
+ { label: "rules", root: path11.join(claude, "rules") },
1988
+ { label: "skills", root: path11.join(claude, "skills") },
1989
+ { label: "commands", root: path11.join(claude, "commands") }
1797
1990
  ];
1798
1991
  }
1799
1992
 
@@ -1802,7 +1995,7 @@ var MAINTAINER_WORKSPACE = "agent-config-maintainer";
1802
1995
  function isExclusivelyPackageOnly(source_path) {
1803
1996
  let meta;
1804
1997
  try {
1805
- [meta] = parseFrontmatter(fs10.readFileSync(source_path, "utf-8"));
1998
+ [meta] = parseFrontmatter(fs12.readFileSync(source_path, "utf-8"));
1806
1999
  } catch {
1807
2000
  return false;
1808
2001
  }
@@ -1817,7 +2010,7 @@ function stampHostLayerFingerprint(installedVersion, tools, lockfilePath, skip2,
1817
2010
  return null;
1818
2011
  }
1819
2012
  try {
1820
- const fingerprint = fingerprintLayers(hostLayerInputs(os2.homedir()));
2013
+ const fingerprint = fingerprintLayers(hostLayerInputs(os3.homedir()));
1821
2014
  write_lockfile(installedVersion, [...tools], {
1822
2015
  path: lockfilePath,
1823
2016
  host_layer_fingerprint: fingerprint
@@ -1833,8 +2026,8 @@ function stampHostLayerFingerprint(installedVersion, tools, lockfilePath, skip2,
1833
2026
  }
1834
2027
 
1835
2028
  // src/install/claudeRuleRewrite.ts
1836
- import * as fs11 from "node:fs";
1837
- import * as path10 from "node:path";
2029
+ import * as fs13 from "node:fs";
2030
+ import * as path12 from "node:path";
1838
2031
 
1839
2032
  // src/install/claudePathsPlan.ts
1840
2033
  function derive_trigger_globs(meta) {
@@ -1874,14 +2067,22 @@ function _expanded_pattern_count(pattern) {
1874
2067
  return n;
1875
2068
  }
1876
2069
  var CLAUDE_PATHS_PATTERN_BUDGET = 1e3;
2070
+ var PATH_SHAPED_TRIGGER_KEYS = /* @__PURE__ */ new Set(["file_pattern", "path_prefix"]);
2071
+ var NON_MATCHING_TRIGGER_KEYS = /* @__PURE__ */ new Set(["reason"]);
1877
2072
  function _has_non_path_trigger(meta) {
1878
2073
  const triggers = meta["triggers"];
1879
2074
  if (!Array.isArray(triggers)) return false;
1880
2075
  for (const t of triggers) {
1881
2076
  if (t === null || typeof t !== "object" || Array.isArray(t)) continue;
1882
2077
  const obj = t;
1883
- if (typeof obj["keyword"] === "string" && obj["keyword"]) return true;
1884
- if (typeof obj["phrase"] === "string" && obj["phrase"]) return true;
2078
+ for (const [key, value] of Object.entries(obj)) {
2079
+ if (PATH_SHAPED_TRIGGER_KEYS.has(key) || NON_MATCHING_TRIGGER_KEYS.has(key)) continue;
2080
+ if (typeof value === "string") {
2081
+ if (value.trim() !== "") return true;
2082
+ } else if (value !== void 0 && value !== null) {
2083
+ return true;
2084
+ }
2085
+ }
1885
2086
  }
1886
2087
  return false;
1887
2088
  }
@@ -1949,6 +2150,11 @@ function rewriteAndReport(rulesDir, quiet, info2, warn2, wrappers, preserved = /
1949
2150
  ` claude-code: ${wrappers.reserved.length} flat command(s) withheld \u2014 name is a Claude Code built-in (${wrappers.reserved.join(", ")}); nested /cluster:sub commands remain available`
1950
2151
  );
1951
2152
  }
2153
+ if (wrappers.foreign !== void 0 && wrappers.foreign.length > 0) {
2154
+ info2(
2155
+ ` claude-code: kept ${wrappers.foreign.length} neighbour command file(s) whose name is a Claude Code built-in (${wrappers.foreign.join(", ")}); not ours to remove`
2156
+ );
2157
+ }
1952
2158
  }
1953
2159
  if (result.rewritten > 0 && !quiet) {
1954
2160
  info2(
@@ -1990,23 +2196,23 @@ function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
1990
2196
  const result = { rewritten: 0, scoped: [], dropped: [], failed: [] };
1991
2197
  let entries;
1992
2198
  try {
1993
- entries = fs11.readdirSync(rulesDir);
2199
+ entries = fs13.readdirSync(rulesDir);
1994
2200
  } catch {
1995
2201
  return result;
1996
2202
  }
1997
2203
  for (const name of entries.filter((n) => n.endsWith(".md")).sort()) {
1998
- const full = path10.join(rulesDir, name);
1999
- if (preserved.has(path10.resolve(full))) continue;
2204
+ const full = path12.join(rulesDir, name);
2205
+ if (preserved.has(path12.resolve(full))) continue;
2000
2206
  let stat;
2001
2207
  try {
2002
- stat = fs11.lstatSync(full);
2208
+ stat = fs13.lstatSync(full);
2003
2209
  } catch {
2004
2210
  continue;
2005
2211
  }
2006
2212
  if (!stat.isFile() || stat.isSymbolicLink()) continue;
2007
2213
  let text;
2008
2214
  try {
2009
- text = fs11.readFileSync(full, "utf-8");
2215
+ text = fs13.readFileSync(full, "utf-8");
2010
2216
  } catch {
2011
2217
  continue;
2012
2218
  }
@@ -2016,7 +2222,7 @@ function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
2016
2222
  const withOwnership = _withPreservedKeys(rendered.text, text);
2017
2223
  if (withOwnership !== text) {
2018
2224
  try {
2019
- fs11.writeFileSync(full, withOwnership, "utf-8");
2225
+ fs13.writeFileSync(full, withOwnership, "utf-8");
2020
2226
  } catch (e) {
2021
2227
  result.failed.push({
2022
2228
  rule: name.slice(0, -3),
@@ -2035,6 +2241,744 @@ function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
2035
2241
  return result;
2036
2242
  }
2037
2243
 
2244
+ // src/install/installThinLayer.ts
2245
+ import * as fs17 from "node:fs";
2246
+ import * as path17 from "node:path";
2247
+ import * as os5 from "node:os";
2248
+
2249
+ // src/scripts/_lib/installed_layer.ts
2250
+ import * as fs14 from "node:fs";
2251
+ import * as path14 from "node:path";
2252
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
2253
+
2254
+ // src/install/globalRuleLayers.ts
2255
+ import * as os4 from "node:os";
2256
+ import * as path13 from "node:path";
2257
+ var GLOBAL_RULE_DIRS = {
2258
+ "claude-code": ".claude/rules",
2259
+ cursor: ".cursor/rules",
2260
+ augment: ".augment/rules",
2261
+ // Windsurf's scope root is `~/.codeium/windsurf/`, not `~/.windsurf/`.
2262
+ windsurf: ".codeium/windsurf/rules",
2263
+ // Cline's scope root IS the rules directory — no `rules/` suffix.
2264
+ cline: "Documents/Cline/Rules"
2265
+ };
2266
+ function globalRuleLayerPath(toolId, home = process.env["HOME"] ?? os4.homedir()) {
2267
+ const rel = GLOBAL_RULE_DIRS[toolId];
2268
+ return rel === void 0 ? null : path13.join(home, rel);
2269
+ }
2270
+
2271
+ // src/scripts/_lib/rule_law_section.ts
2272
+ var IRON_LAW_RE = /\biron\s+laws?\b/i;
2273
+ var HEADING_RE = /^(#{1,6})\s+(.+?)\s*$/;
2274
+ var FENCE_RE = /^\s*```/;
2275
+ function splitFrontmatter(text) {
2276
+ if (text.startsWith("---\n")) {
2277
+ const end = text.indexOf("\n---\n", 4);
2278
+ if (end !== -1) {
2279
+ return [text.slice(0, end + 5), text.slice(end + 5)];
2280
+ }
2281
+ }
2282
+ return ["", text];
2283
+ }
2284
+ function ruleBody(text) {
2285
+ const [, body] = splitFrontmatter(text);
2286
+ return body.replace(/<!--[\s\S]*?-->/g, "").trim();
2287
+ }
2288
+ function lawSections(body) {
2289
+ const lines = body.split("\n");
2290
+ let inFence = false;
2291
+ const headings = [];
2292
+ for (let i = 0; i < lines.length; i += 1) {
2293
+ const raw = lines[i];
2294
+ if (FENCE_RE.test(raw)) {
2295
+ inFence = !inFence;
2296
+ continue;
2297
+ }
2298
+ if (inFence) continue;
2299
+ const m = HEADING_RE.exec(raw);
2300
+ if (m) headings.push({ i, depth: m[1].length, title: m[2].trim() });
2301
+ }
2302
+ const out = [];
2303
+ for (let k = 0; k < headings.length; k += 1) {
2304
+ const h = headings[k];
2305
+ if (!IRON_LAW_RE.test(h.title)) continue;
2306
+ let end = lines.length;
2307
+ for (let j = k + 1; j < headings.length; j += 1) {
2308
+ const n = headings[j];
2309
+ if (n.depth <= h.depth) {
2310
+ end = n.i;
2311
+ break;
2312
+ }
2313
+ }
2314
+ out.push({
2315
+ title: h.title,
2316
+ depth: h.depth,
2317
+ line: h.i + 1,
2318
+ text: lines.slice(h.i, end).join("\n").trim()
2319
+ });
2320
+ }
2321
+ return out;
2322
+ }
2323
+ function lawText(body) {
2324
+ const sections = lawSections(body);
2325
+ if (sections.length === 0) return null;
2326
+ return sections.map((s) => s.text).join("\n\n");
2327
+ }
2328
+
2329
+ // src/scripts/_lib/installed_layer.ts
2330
+ var TOP_FILES = 20;
2331
+ var LIMIT_WARN_FRACTION = 0.8;
2332
+ function isUnconditional(text) {
2333
+ return !/^paths:/m.test(text);
2334
+ }
2335
+ function readLayer(host, scope, dir, recorded) {
2336
+ const empty = {
2337
+ files: 0,
2338
+ unconditional: 0,
2339
+ chars: 0,
2340
+ package_owned: 0,
2341
+ foreign: 0,
2342
+ package_owned_chars: 0,
2343
+ foreign_chars: 0,
2344
+ top: []
2345
+ };
2346
+ let names;
2347
+ try {
2348
+ names = fs14.readdirSync(dir);
2349
+ } catch {
2350
+ return { host, scope, dir, present: false, ...empty };
2351
+ }
2352
+ const readings = [];
2353
+ for (const name of names.sort()) {
2354
+ if (!name.endsWith(".md")) continue;
2355
+ const abs = path14.join(dir, name);
2356
+ let text;
2357
+ try {
2358
+ const st = fs14.statSync(abs);
2359
+ if (!st.isFile()) continue;
2360
+ text = fs14.readFileSync(abs, "utf-8");
2361
+ } catch {
2362
+ continue;
2363
+ }
2364
+ const owned = recorded.has(abs);
2365
+ readings.push({
2366
+ file: name,
2367
+ // THE STRIP IS THE PROJECTOR'S OWN. `ruleBody` is what
2368
+ // `project_thin_rules` and the delivery carrier both call, so "what
2369
+ // a host loads" and "what a delivery carries" cannot drift into two
2370
+ // spellings of the same measurement.
2371
+ chars: ruleBody(text).length,
2372
+ unconditional: isUnconditional(text),
2373
+ package_owned: owned
2374
+ });
2375
+ }
2376
+ const top = [...readings].sort((a, b) => b.chars - a.chars || a.file.localeCompare(b.file)).slice(0, TOP_FILES);
2377
+ return {
2378
+ host,
2379
+ scope,
2380
+ dir,
2381
+ present: true,
2382
+ files: readings.length,
2383
+ unconditional: readings.filter((r) => r.unconditional).length,
2384
+ chars: readings.reduce((n, r) => n + r.chars, 0),
2385
+ package_owned: readings.filter((r) => r.package_owned).length,
2386
+ foreign: readings.filter((r) => !r.package_owned).length,
2387
+ package_owned_chars: readings.reduce((n, r) => n + (r.package_owned ? r.chars : 0), 0),
2388
+ foreign_chars: readings.reduce((n, r) => n + (r.package_owned ? 0 : r.chars), 0),
2389
+ top
2390
+ };
2391
+ }
2392
+ function defaultHostLimitsPath() {
2393
+ return path14.join(
2394
+ path14.dirname(fileURLToPath2(import.meta.url)),
2395
+ "..",
2396
+ "..",
2397
+ "config",
2398
+ "host-instruction-limits.json"
2399
+ );
2400
+ }
2401
+ function loadHostInstructionLimits(file = defaultHostLimitsPath()) {
2402
+ const out = /* @__PURE__ */ new Map();
2403
+ let raw;
2404
+ try {
2405
+ raw = JSON.parse(fs14.readFileSync(file, "utf-8"));
2406
+ } catch {
2407
+ return out;
2408
+ }
2409
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return out;
2410
+ for (const [host, v] of Object.entries(raw)) {
2411
+ if (host.startsWith("_")) continue;
2412
+ if (typeof v !== "object" || v === null || Array.isArray(v)) continue;
2413
+ const e = v;
2414
+ const n = e.limit;
2415
+ const limit = typeof n === "number" && Number.isFinite(n) && n > 0 ? n : null;
2416
+ const k = e.kind;
2417
+ const kind = limit === null ? "unpublished" : k === "vendor-published" || k === "reported" ? k : "reported";
2418
+ out.set(host, { limit, kind });
2419
+ }
2420
+ return out;
2421
+ }
2422
+ function buildHostLimitRows(layers, limits) {
2423
+ const byHost = /* @__PURE__ */ new Map();
2424
+ for (const l of layers) {
2425
+ if (!l.present) continue;
2426
+ const acc = byHost.get(l.host) ?? { chars: 0, owned: 0, foreign: 0 };
2427
+ acc.chars += l.chars;
2428
+ acc.owned += l.package_owned_chars;
2429
+ acc.foreign += l.foreign_chars;
2430
+ byHost.set(l.host, acc);
2431
+ }
2432
+ for (const l of layers) if (!byHost.has(l.host)) byHost.set(l.host, { chars: 0, owned: 0, foreign: 0 });
2433
+ for (const [host, e] of limits) if (e.limit !== null && !byHost.has(host)) {
2434
+ byHost.set(host, { chars: 0, owned: 0, foreign: 0 });
2435
+ }
2436
+ const rows = [];
2437
+ for (const host of [...byHost.keys()].sort()) {
2438
+ const a = byHost.get(host);
2439
+ const e = limits.get(host) ?? { limit: null, kind: "unpublished" };
2440
+ const fraction = e.limit === null ? null : a.chars / e.limit;
2441
+ rows.push({
2442
+ host,
2443
+ limit: e.limit,
2444
+ kind: e.kind,
2445
+ chars: a.chars,
2446
+ package_owned_chars: a.owned,
2447
+ foreign_chars: a.foreign,
2448
+ fraction,
2449
+ warn: fraction !== null && fraction >= LIMIT_WARN_FRACTION
2450
+ });
2451
+ }
2452
+ return rows;
2453
+ }
2454
+ function renderHostLimitRows(rows) {
2455
+ const out = [
2456
+ "host instruction budgets \u2014 package-owned + foreign against the published limit"
2457
+ ];
2458
+ for (const r of rows) {
2459
+ const split = `${String(r.package_owned_chars)} package-owned + ${String(r.foreign_chars)} foreign = ${String(r.chars)} chars`;
2460
+ if (r.limit === null) {
2461
+ out.push(` ${r.host} \u2014 ${split}; no published limit recorded \u2014 not measured`);
2462
+ continue;
2463
+ }
2464
+ const pct = (r.fraction * 100).toFixed(1);
2465
+ out.push(
2466
+ ` ${r.host} \u2014 ${split}; ${pct}% of ${String(r.limit)} (${r.kind})` + (r.warn ? ` \u2014 WARNING: at or past ${String(Math.round(LIMIT_WARN_FRACTION * 100))}% of the published limit` : "")
2467
+ );
2468
+ }
2469
+ return out;
2470
+ }
2471
+
2472
+ // src/scripts/_lib/thin_rules.ts
2473
+ import { createHash as createHash7 } from "node:crypto";
2474
+ import * as fs16 from "node:fs";
2475
+ import * as path16 from "node:path";
2476
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
2477
+
2478
+ // src/scripts/_lib/rule_consequence_class.ts
2479
+ import * as fs15 from "node:fs";
2480
+ import * as path15 from "node:path";
2481
+ var CLASS_CONFIG_REL = "src/config/rule-consequence-class.json";
2482
+ function readConsequenceClass(repoRoot) {
2483
+ const raw = JSON.parse(fs15.readFileSync(path15.join(repoRoot, CLASS_CONFIG_REL), "utf-8"));
2484
+ return {
2485
+ criterion_ref: raw.criterion_ref ?? "",
2486
+ members: raw.members ?? {},
2487
+ no_stub: raw.no_stub ?? {},
2488
+ excluded: raw.excluded ?? {}
2489
+ };
2490
+ }
2491
+ function stubLawIds(cfg) {
2492
+ return new Set(Object.keys(cfg.members).filter((id) => cfg.no_stub[id] === void 0));
2493
+ }
2494
+
2495
+ // src/scripts/_lib/rule_injection.ts
2496
+ var PATH_TRIGGER_KINDS = ["path_prefix", "file_pattern"];
2497
+ function tierEntries(router, tier) {
2498
+ const raw = router[tier];
2499
+ if (!Array.isArray(raw)) return [];
2500
+ return raw.map((r) => ({
2501
+ id: String(r["id"] ?? ""),
2502
+ triggers: Array.isArray(r["triggers"]) ? r["triggers"] : []
2503
+ }));
2504
+ }
2505
+ function allTierRules(router) {
2506
+ const out = [];
2507
+ for (const tier of ["tier_1", "tier_2"]) {
2508
+ for (const e of tierEntries(router, tier)) out.push({ ...e, tier });
2509
+ }
2510
+ return out;
2511
+ }
2512
+ function pathOnlyRuleIds(router) {
2513
+ const ids = /* @__PURE__ */ new Set();
2514
+ for (const r of allTierRules(router)) {
2515
+ if (r.triggers.length === 0) continue;
2516
+ const allPath = r.triggers.every(
2517
+ (t) => PATH_TRIGGER_KINDS.some((k) => k in t)
2518
+ );
2519
+ if (allPath) ids.add(r.id);
2520
+ }
2521
+ return ids;
2522
+ }
2523
+ function triggerlessRuleIds(router) {
2524
+ return allTierRules(router).filter((r) => r.triggers.length === 0).map((r) => r.id);
2525
+ }
2526
+
2527
+ // src/scripts/_lib/thin_rules.ts
2528
+ var _HERE = fileURLToPath3(import.meta.url);
2529
+ var REPO_ROOT = path16.resolve(path16.dirname(_HERE), "..", "..", "..");
2530
+ var RULES_SOURCE = path16.join(REPO_ROOT, "dist/agent-src", "rules");
2531
+ var ROUTER = path16.join(REPO_ROOT, "dist", "router.json");
2532
+ function _globSortedMd(dir) {
2533
+ let names;
2534
+ try {
2535
+ names = fs16.readdirSync(dir);
2536
+ } catch {
2537
+ return [];
2538
+ }
2539
+ const out = names.filter((n) => n.endsWith(".md")).map((n) => path16.join(dir, n));
2540
+ out.sort();
2541
+ return out;
2542
+ }
2543
+ function kernel_ids(routerPath = ROUTER) {
2544
+ const data = JSON.parse(fs16.readFileSync(routerPath, "utf-8"));
2545
+ const kernel = data.kernel;
2546
+ if (Array.isArray(kernel)) {
2547
+ return new Set(kernel.map((x) => String(x)));
2548
+ }
2549
+ return /* @__PURE__ */ new Set();
2550
+ }
2551
+ function _router(routerPath = ROUTER) {
2552
+ return JSON.parse(fs16.readFileSync(routerPath, "utf-8"));
2553
+ }
2554
+ function path_only_ids(routerPath = ROUTER) {
2555
+ return pathOnlyRuleIds(_router(routerPath));
2556
+ }
2557
+ function no_trigger_ids(routerPath = ROUTER) {
2558
+ return new Set(triggerlessRuleIds(_router(routerPath)));
2559
+ }
2560
+ function rule_workspaces_map(routerPath = ROUTER) {
2561
+ const data = JSON.parse(fs16.readFileSync(routerPath, "utf-8"));
2562
+ const map = /* @__PURE__ */ new Map();
2563
+ for (const tier of ["tier_1", "tier_2"]) {
2564
+ const entries = data[tier];
2565
+ if (!Array.isArray(entries)) continue;
2566
+ for (const e of entries) {
2567
+ const obj = e;
2568
+ const ws = Array.isArray(obj.workspaces) ? obj.workspaces.map((w) => String(w)) : [];
2569
+ map.set(String(obj.id), ws);
2570
+ }
2571
+ }
2572
+ return map;
2573
+ }
2574
+ function id_in_scope(rule_id, scope, kernel, wsMap, fallback_ws = []) {
2575
+ if (scope === null || kernel.has(rule_id)) {
2576
+ return true;
2577
+ }
2578
+ const ws = wsMap.get(rule_id) ?? fallback_ws;
2579
+ if (ws.length === 0) {
2580
+ return true;
2581
+ }
2582
+ return ws.some((w) => scope.includes(w));
2583
+ }
2584
+ function fm_workspaces(text) {
2585
+ const [fm] = split_frontmatter(text);
2586
+ const flow = /^workspaces:[ \t]*\[([^\]]*)\]/m.exec(fm);
2587
+ if (flow) {
2588
+ return flow[1].split(",").map((s) => s.trim().replace(/^["']|["']$/g, "")).filter((s) => s.length > 0);
2589
+ }
2590
+ const m = /^workspaces:[ \t]*\n((?:[ \t]+-[ \t]+.*(?:\n|$))+)/m.exec(fm);
2591
+ if (!m) {
2592
+ return [];
2593
+ }
2594
+ return [...m[1].matchAll(/-[ \t]+(\S+)/g)].map((x) => x[1]);
2595
+ }
2596
+ function split_frontmatter(text) {
2597
+ if (text.startsWith("---\n")) {
2598
+ const end = text.indexOf("\n---\n", 4);
2599
+ if (end !== -1) {
2600
+ return [text.slice(0, end + 5), text.slice(end + 5)];
2601
+ }
2602
+ }
2603
+ return ["", text];
2604
+ }
2605
+ function _description(fm) {
2606
+ const m = /^description:\s*"?(.+?)"?\s*$/m.exec(fm);
2607
+ return m ? m[1].trim() : "";
2608
+ }
2609
+ var _TRIGGER_HINT_LIMIT = 6;
2610
+ function _trigger_hint(fm) {
2611
+ const hits = [];
2612
+ const re = /^\s*-\s*(?:keyword|phrase):\s*"?(.+?)"?\s*$/gm;
2613
+ let m;
2614
+ while ((m = re.exec(fm)) !== null) {
2615
+ hits.push(m[1].trim());
2616
+ if (hits.length >= _TRIGGER_HINT_LIMIT) {
2617
+ break;
2618
+ }
2619
+ }
2620
+ return hits.join(", ");
2621
+ }
2622
+ function _title(s) {
2623
+ return s.replace(/[A-Za-z]+/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase());
2624
+ }
2625
+ var THIN_ENTRY_MARKER = "> Routed rule \u2014 load the body on trigger-match.";
2626
+ var BODY_LINK_PREFIX = "../../dist/agent-src/rules/";
2627
+ function absoluteBodyLinkPrefix(packageRoot) {
2628
+ return `${path16.join(path16.resolve(packageRoot), "dist", "agent-src", "rules")}${path16.sep}`;
2629
+ }
2630
+ function thin_entry(rule_id, text, bodyLinkPrefix = BODY_LINK_PREFIX) {
2631
+ const [fm] = split_frontmatter(text);
2632
+ const desc = _description(fm);
2633
+ const hint = _trigger_hint(fm);
2634
+ const title = _title(rule_id.replace(/-/g, " "));
2635
+ const fires = hint ? ` Fires on: ${hint}.` : "";
2636
+ return `## ${title}
2637
+ ${THIN_ENTRY_MARKER}${fires} ${desc} Body: [\`${rule_id}\`](${bodyLinkPrefix}${rule_id}.md)
2638
+ `;
2639
+ }
2640
+ var STUB_LAW_OPEN = "<!-- law: byte-copied from the rule, sha256 ";
2641
+ var STUB_LAW_CLOSE = "<!-- /law -->";
2642
+ function lawDigest(law) {
2643
+ return createHash7("sha256").update(law, "utf-8").digest("hex").slice(0, 16);
2644
+ }
2645
+ var StubLawError = class extends Error {
2646
+ ruleId;
2647
+ constructor(ruleId, message) {
2648
+ super(message);
2649
+ this.name = "StubLawError";
2650
+ this.ruleId = ruleId;
2651
+ }
2652
+ };
2653
+ var STUB_LAW_MAX_CHARS = 2e3;
2654
+ function thin_entry_with_law(rule_id, text, bodyLinkPrefix = BODY_LINK_PREFIX) {
2655
+ const law = lawText(ruleBody(text));
2656
+ if (law === null) {
2657
+ throw new StubLawError(
2658
+ rule_id,
2659
+ `${rule_id} is a high-consequence class member with no law section \u2014 write one, or record it under \`no_stub\` in src/config/rule-consequence-class.json with the reason`
2660
+ );
2661
+ }
2662
+ if (law.length > STUB_LAW_MAX_CHARS) {
2663
+ throw new StubLawError(
2664
+ rule_id,
2665
+ `${rule_id} is a high-consequence class member whose law section is ${law.length} chars, over the ${STUB_LAW_MAX_CHARS} ceiling \u2014 a stub never ships a shortened copy, so either the law moves under the ceiling or the rule is recorded under \`no_stub\` in src/config/rule-consequence-class.json with the reason`
2666
+ );
2667
+ }
2668
+ return thin_entry(rule_id, text, bodyLinkPrefix) + `
2669
+ ${STUB_LAW_OPEN}${lawDigest(law)} -->
2670
+ ${law}
2671
+ ${STUB_LAW_CLOSE}
2672
+ `;
2673
+ }
2674
+ function build_thin(rules_dir = RULES_SOURCE, scope = null, announce = null, consequenceClass = null, roots = null) {
2675
+ const routerPath = roots?.routerPath ?? (roots?.packageRoot === void 0 ? ROUTER : path16.join(roots.packageRoot, "dist", "router.json"));
2676
+ const classRoot = roots?.packageRoot ?? REPO_ROOT;
2677
+ const bodyLinkPrefix = roots?.bodyLinkPrefix ?? BODY_LINK_PREFIX;
2678
+ const kernel = kernel_ids(routerPath);
2679
+ const noTrigger = no_trigger_ids(routerPath);
2680
+ const pathOnly = path_only_ids(routerPath);
2681
+ const cls = consequenceClass ?? readConsequenceClass(classRoot);
2682
+ const lawInStub = stubLawIds(cls);
2683
+ const wsMap = scope !== null ? rule_workspaces_map(routerPath) : /* @__PURE__ */ new Map();
2684
+ const out = /* @__PURE__ */ new Map();
2685
+ for (const p of _globSortedMd(rules_dir)) {
2686
+ const text = fs16.readFileSync(p, "utf-8");
2687
+ const stem = path16.basename(p).replace(/\.md$/, "");
2688
+ if (!id_in_scope(stem, scope, kernel, wsMap, fm_workspaces(text))) {
2689
+ continue;
2690
+ }
2691
+ const noStub = cls.no_stub[stem] !== void 0;
2692
+ const full = kernel.has(stem) || noTrigger.has(stem) || pathOnly.has(stem) || noStub;
2693
+ if (announce !== null && noTrigger.has(stem) && !kernel.has(stem)) {
2694
+ announce(`D3: trigger-less auto rule ${path16.basename(p)} \u2014 kept full-bodied, never thinned`);
2695
+ }
2696
+ if (announce !== null && pathOnly.has(stem) && !kernel.has(stem) && !noTrigger.has(stem)) {
2697
+ announce(
2698
+ `E2: path-only auto rule ${path16.basename(p)} \u2014 kept full-bodied; its only triggers are path-shaped and the delivery concern is not bound on pre_tool_use`
2699
+ );
2700
+ }
2701
+ if (full) {
2702
+ out.set(path16.basename(p), text);
2703
+ continue;
2704
+ }
2705
+ if (lawInStub.has(stem)) {
2706
+ if (announce !== null) {
2707
+ announce(
2708
+ `LAW: high-consequence rule ${path16.basename(p)} \u2014 stub carries its own law section, byte-copied`
2709
+ );
2710
+ }
2711
+ out.set(path16.basename(p), thin_entry_with_law(stem, text, bodyLinkPrefix));
2712
+ continue;
2713
+ }
2714
+ out.set(path16.basename(p), thin_entry(stem, text, bodyLinkPrefix));
2715
+ }
2716
+ return out;
2717
+ }
2718
+
2719
+ // src/install/installThinLayer.ts
2720
+ function thinInstalledRuleLayer(opts) {
2721
+ const packageRoot = path17.resolve(opts.packageRoot);
2722
+ const bodySourceDir = path17.join(packageRoot, "dist", "agent-src", "rules");
2723
+ const bodyLinkPrefix = absoluteBodyLinkPrefix(packageRoot);
2724
+ const preserved = opts.preserved ?? /* @__PURE__ */ new Set();
2725
+ const stubs = build_thin(bodySourceDir, null, null, null, { packageRoot, bodyLinkPrefix });
2726
+ let thinned = 0;
2727
+ let rewritten = 0;
2728
+ let kept = 0;
2729
+ let charsBefore = 0;
2730
+ let charsAfter = 0;
2731
+ const preservedHits = [];
2732
+ const absent = [];
2733
+ const failed = [];
2734
+ for (const [name, stubText] of stubs) {
2735
+ const target = path17.join(opts.rulesDir, name);
2736
+ let installed;
2737
+ try {
2738
+ installed = fs17.readFileSync(target, "utf-8");
2739
+ } catch (e) {
2740
+ if (e.code === "ENOENT") absent.push(name);
2741
+ else failed.push({ rule: name, reason: String(e) });
2742
+ continue;
2743
+ }
2744
+ let sourceText;
2745
+ try {
2746
+ sourceText = fs17.readFileSync(path17.join(bodySourceDir, name), "utf-8");
2747
+ } catch {
2748
+ sourceText = null;
2749
+ }
2750
+ if (stubText === sourceText) {
2751
+ kept += 1;
2752
+ charsBefore += installed.length;
2753
+ charsAfter += installed.length;
2754
+ continue;
2755
+ }
2756
+ if (preserved.has(path17.resolve(target))) {
2757
+ preservedHits.push(name);
2758
+ charsBefore += installed.length;
2759
+ charsAfter += installed.length;
2760
+ continue;
2761
+ }
2762
+ const [frontmatter] = split_frontmatter(installed);
2763
+ charsBefore += installed.length;
2764
+ if (frontmatter === "" && /^\uFEFF?[\s]*---/.test(installed)) {
2765
+ failed.push({
2766
+ rule: name,
2767
+ reason: "opens a frontmatter block that never closes \u2014 left untouched so its ownership keys survive"
2768
+ });
2769
+ charsAfter += installed.length;
2770
+ continue;
2771
+ }
2772
+ const next = `${frontmatter}${stubText}`;
2773
+ try {
2774
+ if (next !== installed) {
2775
+ fs17.writeFileSync(target, next, "utf-8");
2776
+ rewritten += 1;
2777
+ }
2778
+ thinned += 1;
2779
+ charsAfter += next.length;
2780
+ } catch (e) {
2781
+ failed.push({ rule: name, reason: String(e) });
2782
+ charsAfter += installed.length;
2783
+ }
2784
+ }
2785
+ if (stubs.size === 0) {
2786
+ failed.push({
2787
+ rule: bodySourceDir,
2788
+ reason: "no rule bodies found to build stubs from \u2014 the layer was left full-bodied"
2789
+ });
2790
+ }
2791
+ return {
2792
+ thinned,
2793
+ rewritten,
2794
+ kept,
2795
+ preserved: preservedHits,
2796
+ absent,
2797
+ failed,
2798
+ bodyLinkPrefix,
2799
+ charsBefore,
2800
+ charsAfter
2801
+ };
2802
+ }
2803
+ function describeThinInstalledLayer(res) {
2804
+ const out = [];
2805
+ out.push(
2806
+ res.rewritten === 0 && res.thinned > 0 ? ` claude-code: ${String(res.thinned)} rule(s) already thinned, ${String(res.kept)} kept full-bodied; ${String(res.charsAfter)} chars \u2014 nothing to rewrite` : ` claude-code: thinned ${String(res.rewritten)} rule(s) to stubs, ${String(res.kept)} kept full-bodied; ${String(res.charsBefore)} -> ${String(res.charsAfter)} chars`
2807
+ );
2808
+ if (res.preserved.length > 0) {
2809
+ out.push(
2810
+ ` claude-code: ${String(res.preserved.length)} rule(s) left full \u2014 you edited them and they are preserved, never overwritten (${res.preserved.join(", ")})`
2811
+ );
2812
+ }
2813
+ for (const f of res.failed) {
2814
+ out.push(` claude-code: ${f.rule}: could not write stub \u2014 ${f.reason}`);
2815
+ }
2816
+ return out;
2817
+ }
2818
+ function installReceiptBudgetLines(packageRoot, home = os5.homedir()) {
2819
+ try {
2820
+ const recorded = (() => {
2821
+ try {
2822
+ return readRecordedHashes(manifest_path(packageRoot), packageRoot);
2823
+ } catch {
2824
+ return NO_RECORDED_HASHES;
2825
+ }
2826
+ })();
2827
+ const layers = [];
2828
+ for (const host of Object.keys(GLOBAL_RULE_DIRS).sort()) {
2829
+ const dir = globalRuleLayerPath(host, home);
2830
+ if (dir === null) continue;
2831
+ layers.push(readLayer(host, "global", dir, recorded));
2832
+ }
2833
+ const rows = buildHostLimitRows(layers, loadHostInstructionLimits());
2834
+ return rows.length === 0 ? [] : renderHostLimitRows(rows).map((l) => ` ${l}`);
2835
+ } catch {
2836
+ return [];
2837
+ }
2838
+ }
2839
+
2840
+ // src/install/globalRuleScope.ts
2841
+ function isPlainObject2(v) {
2842
+ return typeof v === "object" && v !== null && !Array.isArray(v);
2843
+ }
2844
+ function resolveGlobalRuleScope(inputs) {
2845
+ const { packageRoot, warn: warn2 } = inputs;
2846
+ const settings_path = inputs.settingsPath;
2847
+ if (settings_path === null) {
2848
+ try {
2849
+ return ruleScopeFromSettings(inputs.loadDefaults(), packageRoot);
2850
+ } catch {
2851
+ return LEGACY_ALL;
2852
+ }
2853
+ }
2854
+ let text;
2855
+ try {
2856
+ text = inputs.readText(settings_path);
2857
+ } catch (e) {
2858
+ warn2(
2859
+ `could not read ${settings_path} (${String(e)}) \u2014 rule scoping falls back to legacy-all, so ALL rules including maintainer-only ones will be installed. Fix the file to restore scoping.`
2860
+ );
2861
+ return LEGACY_ALL;
2862
+ }
2863
+ const parsed = inputs.parseYaml(text);
2864
+ if (!isPlainObject2(parsed)) {
2865
+ warn2(
2866
+ `${settings_path} is not a YAML mapping \u2014 rule scoping falls back to legacy-all, so ALL rules including maintainer-only ones will be installed. Fix the file to restore scoping.`
2867
+ );
2868
+ return LEGACY_ALL;
2869
+ }
2870
+ try {
2871
+ return ruleScopeFromSettings(parsed, packageRoot);
2872
+ } catch (e) {
2873
+ warn2(
2874
+ `could not derive rule scope from ${settings_path} (${String(e)}) \u2014 falling back to legacy-all; ALL rules will be installed.`
2875
+ );
2876
+ return LEGACY_ALL;
2877
+ }
2878
+ }
2879
+
2880
+ // src/scripts/_lib/lean_projection_mode.ts
2881
+ import * as path18 from "node:path";
2882
+ var DEFAULT_LEAN_PROJECTION_MODE = "eager-all";
2883
+ function normalizeLeanProjectionMode(raw) {
2884
+ const v = typeof raw === "string" ? raw.trim().toLowerCase() : "";
2885
+ if (v === "thin") return "thin";
2886
+ if (v === "delivery") return "delivery";
2887
+ return DEFAULT_LEAN_PROJECTION_MODE;
2888
+ }
2889
+ function writesThinFiles(mode) {
2890
+ return mode === "thin" || mode === "delivery";
2891
+ }
2892
+ var THINNABLE_HOSTS = ["claude-code", "cursor", "cline"];
2893
+ var DEFAULT_LEAN_PROJECTION_HOSTS = ["claude-code"];
2894
+ function resolveLeanProjectionHosts(raw) {
2895
+ const known = new Set(THINNABLE_HOSTS);
2896
+ if (!Array.isArray(raw) || raw.length === 0) {
2897
+ return { hosts: [...DEFAULT_LEAN_PROJECTION_HOSTS], dropped: [], usedDefault: true };
2898
+ }
2899
+ const hosts = [];
2900
+ const dropped = [];
2901
+ for (const entry of raw) {
2902
+ const id = typeof entry === "string" ? entry.trim().toLowerCase() : "";
2903
+ if (id === "") {
2904
+ dropped.push({ id: String(entry), reason: "unknown" });
2905
+ continue;
2906
+ }
2907
+ if (!known.has(id)) {
2908
+ dropped.push({ id, reason: KNOWN_NON_THINNABLE_HOSTS.has(id) ? "not-thinnable" : "unknown" });
2909
+ continue;
2910
+ }
2911
+ if (!hosts.includes(id)) hosts.push(id);
2912
+ }
2913
+ hosts.sort();
2914
+ return { hosts, dropped, usedDefault: false };
2915
+ }
2916
+ var KNOWN_NON_THINNABLE_HOSTS = /* @__PURE__ */ new Set([
2917
+ "claude-desktop",
2918
+ "augment",
2919
+ "copilot",
2920
+ "windsurf",
2921
+ "gemini",
2922
+ "codex",
2923
+ "cowork"
2924
+ ]);
2925
+ function thinsHost(mode, hosts, hostId) {
2926
+ return writesThinFiles(mode) && hosts.includes(hostId);
2927
+ }
2928
+ function resolveLeanProjection(opts = {}) {
2929
+ const file = opts.settingsPath ?? path18.join(opts.projectRoot ?? process.cwd(), ".agent-settings.yml");
2930
+ const tpl = opts.packageRoot == null ? null : path18.join(opts.packageRoot, "src", "config", "agent-settings.template.yml");
2931
+ let lean;
2932
+ try {
2933
+ lean = load_agent_settings(
2934
+ tpl === null ? { project_path: file } : { project_path: file, template_path: tpl }
2935
+ )["lean_projection"];
2936
+ } catch {
2937
+ }
2938
+ const obj = typeof lean === "object" && lean !== null && !Array.isArray(lean) ? lean : {};
2939
+ const o = obj;
2940
+ return {
2941
+ mode: normalizeLeanProjectionMode(o["mode"] ?? ""),
2942
+ hosts: resolveLeanProjectionHosts(o["hosts"]),
2943
+ // LAZY, and the hot path is the reason. Provenance needs a SECOND,
2944
+ // template-isolated cascade, and only the installer reads it — the
2945
+ // delivery concern on `user_prompt_submit` destructures `{ mode, hosts }`
2946
+ // and discards this field, so computing it eagerly doubled the per-prompt
2947
+ // settings read for an answer nobody asked for. A getter keeps the
2948
+ // field's shape (`readonly modeExplicit: boolean`) and charges only the
2949
+ // caller that touches it.
2950
+ get modeExplicit() {
2951
+ return rawExplicitLeanProjectionMode(opts) !== "";
2952
+ }
2953
+ };
2954
+ }
2955
+ var NO_TEMPLATE_LAYER = path18.join(path18.sep, "dev", "null", "agent-config-absent-template.yml");
2956
+ function rawExplicitLeanProjectionMode(opts = {}) {
2957
+ const file = opts.settingsPath ?? path18.join(opts.projectRoot ?? process.cwd(), ".agent-settings.yml");
2958
+ let lean;
2959
+ try {
2960
+ lean = load_agent_settings({ project_path: file, template_path: NO_TEMPLATE_LAYER })["lean_projection"];
2961
+ } catch {
2962
+ return "";
2963
+ }
2964
+ if (typeof lean !== "object" || lean === null || Array.isArray(lean)) return "";
2965
+ const m = lean["mode"];
2966
+ return typeof m === "string" ? m.trim() : "";
2967
+ }
2968
+ function installerThinsHost(hostId, opts = {}) {
2969
+ const { mode, hosts, modeExplicit } = resolveLeanProjection({
2970
+ ...opts,
2971
+ settingsPath: opts.settingsPath ?? NO_PROJECT_LAYER
2972
+ });
2973
+ return modeExplicit && thinsHost(mode, hosts.hosts, hostId);
2974
+ }
2975
+ var NO_PROJECT_LAYER = path18.join(
2976
+ path18.sep,
2977
+ "dev",
2978
+ "null",
2979
+ "agent-config-absent-project-settings.yml"
2980
+ );
2981
+
2038
2982
  // src/shared/settingsSurface.ts
2039
2983
  function unwrapRef(root) {
2040
2984
  if (root.$ref !== void 0 && root.definitions !== void 0) {
@@ -3390,8 +4334,8 @@ var zodToJsonSchema = (schema, options) => {
3390
4334
  };
3391
4335
 
3392
4336
  // src/scripts/_lib/module_detection.ts
3393
- import * as fs12 from "node:fs";
3394
- import * as path11 from "node:path";
4337
+ import * as fs18 from "node:fs";
4338
+ import * as path19 from "node:path";
3395
4339
  var _SKIP_DIRS = /* @__PURE__ */ new Set([".module-template", ".example"]);
3396
4340
  var _RULES = [
3397
4341
  ["app/Modules", "laravel-hmvc", "App\\Modules\\{ModuleName}"],
@@ -3405,14 +4349,14 @@ var _RULES = [
3405
4349
  ];
3406
4350
  function _isDir(p) {
3407
4351
  try {
3408
- return fs12.statSync(p).isDirectory();
4352
+ return fs18.statSync(p).isDirectory();
3409
4353
  } catch {
3410
4354
  return false;
3411
4355
  }
3412
4356
  }
3413
4357
  function _isFile(p) {
3414
4358
  try {
3415
- return fs12.statSync(p).isFile();
4359
+ return fs18.statSync(p).isFile();
3416
4360
  } catch {
3417
4361
  return false;
3418
4362
  }
@@ -3426,13 +4370,13 @@ function _isUpperChar(ch) {
3426
4370
  function _list_module_subdirs(root) {
3427
4371
  let entries;
3428
4372
  try {
3429
- entries = fs12.readdirSync(root).sort();
4373
+ entries = fs18.readdirSync(root).sort();
3430
4374
  } catch {
3431
4375
  return [];
3432
4376
  }
3433
4377
  const out = [];
3434
4378
  for (const name of entries) {
3435
- if (!_isDir(path11.join(root, name))) {
4379
+ if (!_isDir(path19.join(root, name))) {
3436
4380
  continue;
3437
4381
  }
3438
4382
  if (name.startsWith(".")) {
@@ -3454,11 +4398,11 @@ function _score_confidence(stack, root, subdirs) {
3454
4398
  return capitalized.length > 0 ? "high" : "medium";
3455
4399
  }
3456
4400
  if (stack === "node-monorepo") {
3457
- const withPkgJson = subdirs.filter((name) => _isFile(path11.join(root, name, "package.json")));
4401
+ const withPkgJson = subdirs.filter((name) => _isFile(path19.join(root, name, "package.json")));
3458
4402
  return withPkgJson.length > 0 ? "high" : "medium";
3459
4403
  }
3460
4404
  if (stack === "python-src") {
3461
- const withInit = subdirs.filter((name) => _isFile(path11.join(root, name, "__init__.py")));
4405
+ const withInit = subdirs.filter((name) => _isFile(path19.join(root, name, "__init__.py")));
3462
4406
  return withInit.length > 0 ? "high" : "medium";
3463
4407
  }
3464
4408
  if (stack === "go-internal") {
@@ -3470,7 +4414,7 @@ function detect_module_roots(project_root) {
3470
4414
  const high = [];
3471
4415
  const medium = [];
3472
4416
  for (const [rel_path, stack, namespace_template] of _RULES) {
3473
- const abs_path = path11.join(project_root, rel_path);
4417
+ const abs_path = path19.join(project_root, rel_path);
3474
4418
  if (!_isDir(abs_path)) {
3475
4419
  continue;
3476
4420
  }
@@ -3492,7 +4436,7 @@ function detect_module_roots(project_root) {
3492
4436
  }
3493
4437
 
3494
4438
  // src/scripts/_lib/model_tier.ts
3495
- import fs13 from "node:fs";
4439
+ import fs19 from "node:fs";
3496
4440
  var TIER_TO_CLAUDE_MODEL = {
3497
4441
  frontier: "fable",
3498
4442
  high: "opus",
@@ -3501,8 +4445,8 @@ var TIER_TO_CLAUDE_MODEL = {
3501
4445
  };
3502
4446
  var MODEL_TIER_RE = /^model_tier:\s*"?([a-z]+)"?\s*$/m;
3503
4447
  function read_model_tier(skill_md) {
3504
- if (!fs13.existsSync(skill_md)) return null;
3505
- const text = fs13.readFileSync(skill_md).toString("utf-8");
4448
+ if (!fs19.existsSync(skill_md)) return null;
4449
+ const text = fs19.readFileSync(skill_md).toString("utf-8");
3506
4450
  if (!text.startsWith("---\n")) return null;
3507
4451
  const end = text.indexOf("\n---\n", 4);
3508
4452
  if (end === -1) return null;
@@ -3518,15 +4462,15 @@ function render_native_model_md(text, tier) {
3518
4462
  }
3519
4463
 
3520
4464
  // src/install/paths.ts
3521
- import { homedir as homedir4, tmpdir } from "node:os";
3522
- import { join as join12 } from "node:path";
4465
+ import { homedir as homedir7, tmpdir } from "node:os";
4466
+ import { join as join20 } from "node:path";
3523
4467
  var INSTALL_ROOT_SUBPATH = ".event4u/agent-config";
3524
4468
  var INSTALL_LOG_FILENAME = "install-log.jsonl";
3525
4469
  function resolveHome(home) {
3526
4470
  if (home && home.length > 0) {
3527
4471
  return home;
3528
4472
  }
3529
- const fromOs = homedir4();
4473
+ const fromOs = homedir7();
3530
4474
  if (!fromOs) {
3531
4475
  throw new Error(
3532
4476
  "Cannot resolve home directory \u2014 both $HOME (POSIX) and $USERPROFILE (Windows) are unset."
@@ -3535,14 +4479,14 @@ function resolveHome(home) {
3535
4479
  return fromOs;
3536
4480
  }
3537
4481
  function getInstallRoot(home) {
3538
- return join12(resolveHome(home), INSTALL_ROOT_SUBPATH);
4482
+ return join20(resolveHome(home), INSTALL_ROOT_SUBPATH);
3539
4483
  }
3540
4484
  function getLogPath(home) {
3541
- return join12(getInstallRoot(home), INSTALL_LOG_FILENAME);
4485
+ return join20(getInstallRoot(home), INSTALL_LOG_FILENAME);
3542
4486
  }
3543
4487
 
3544
4488
  // src/scripts/install.ts
3545
- var _HERE = fileURLToPath2(import.meta.url);
4489
+ var _HERE2 = fileURLToPath4(import.meta.url);
3546
4490
  var SystemExitError = class extends Error {
3547
4491
  constructor(code) {
3548
4492
  super(`system-exit-${code}`);
@@ -3558,43 +4502,43 @@ var ArgparseExit = class extends Error {
3558
4502
  code;
3559
4503
  };
3560
4504
  function expanduser3(p) {
3561
- if (p === "~") return os3.homedir();
4505
+ if (p === "~") return os6.homedir();
3562
4506
  if (p.startsWith("~/") || p.startsWith("~\\")) {
3563
- return path12.join(os3.homedir(), p.slice(2));
4507
+ return path20.join(os6.homedir(), p.slice(2));
3564
4508
  }
3565
4509
  return p;
3566
4510
  }
3567
4511
  function isFile(p) {
3568
4512
  try {
3569
- return fs14.statSync(p).isFile();
4513
+ return fs20.statSync(p).isFile();
3570
4514
  } catch {
3571
4515
  return false;
3572
4516
  }
3573
4517
  }
3574
4518
  function isDir(p) {
3575
4519
  try {
3576
- return fs14.statSync(p).isDirectory();
4520
+ return fs20.statSync(p).isDirectory();
3577
4521
  } catch {
3578
4522
  return false;
3579
4523
  }
3580
4524
  }
3581
4525
  function isSymlink(p) {
3582
4526
  try {
3583
- return fs14.lstatSync(p).isSymbolicLink();
4527
+ return fs20.lstatSync(p).isSymbolicLink();
3584
4528
  } catch {
3585
4529
  return false;
3586
4530
  }
3587
4531
  }
3588
4532
  function readText(p) {
3589
- return fs14.readFileSync(p, "utf-8");
4533
+ return fs20.readFileSync(p, "utf-8");
3590
4534
  }
3591
4535
  function writeText(p, content) {
3592
- fs14.writeFileSync(p, content, "utf-8");
4536
+ fs20.writeFileSync(p, content, "utf-8");
3593
4537
  }
3594
4538
  function sortedGlobStems(directory, suffix) {
3595
4539
  let entries;
3596
4540
  try {
3597
- entries = fs14.readdirSync(directory);
4541
+ entries = fs20.readdirSync(directory);
3598
4542
  } catch {
3599
4543
  return [];
3600
4544
  }
@@ -3614,34 +4558,34 @@ function sortedGlobStems(directory, suffix) {
3614
4558
  function countZips(directory) {
3615
4559
  if (!isDir(directory)) return 0;
3616
4560
  let n = 0;
3617
- for (const name of fs14.readdirSync(directory)) {
4561
+ for (const name of fs20.readdirSync(directory)) {
3618
4562
  if (name.endsWith(".zip")) n += 1;
3619
4563
  }
3620
4564
  return n;
3621
4565
  }
3622
4566
  function atomicWrite0644(target, body, prefix) {
3623
- const dir = path12.dirname(target);
3624
- const tmpName = path12.join(
4567
+ const dir = path20.dirname(target);
4568
+ const tmpName = path20.join(
3625
4569
  dir,
3626
4570
  `${prefix}${process2.pid}.${crypto5.randomBytes(6).toString("hex")}.yml.tmp`
3627
4571
  );
3628
4572
  let fd = null;
3629
4573
  try {
3630
- fd = fs14.openSync(tmpName, "wx", 420);
3631
- fs14.writeFileSync(fd, body, "utf-8");
3632
- fs14.closeSync(fd);
4574
+ fd = fs20.openSync(tmpName, "wx", 420);
4575
+ fs20.writeFileSync(fd, body, "utf-8");
4576
+ fs20.closeSync(fd);
3633
4577
  fd = null;
3634
- fs14.chmodSync(tmpName, 420);
3635
- fs14.renameSync(tmpName, target);
4578
+ fs20.chmodSync(tmpName, 420);
4579
+ fs20.renameSync(tmpName, target);
3636
4580
  } catch (err) {
3637
4581
  if (fd !== null) {
3638
4582
  try {
3639
- fs14.closeSync(fd);
4583
+ fs20.closeSync(fd);
3640
4584
  } catch {
3641
4585
  }
3642
4586
  }
3643
4587
  try {
3644
- fs14.unlinkSync(tmpName);
4588
+ fs20.unlinkSync(tmpName);
3645
4589
  } catch {
3646
4590
  }
3647
4591
  throw err;
@@ -3653,14 +4597,14 @@ function utcStamp(now) {
3653
4597
  return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())}T${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}Z`;
3654
4598
  }
3655
4599
  function yamlSafeLoad(text) {
3656
- let YAML2;
4600
+ let YAML3;
3657
4601
  try {
3658
- YAML2 = require_dist();
4602
+ YAML3 = require_dist();
3659
4603
  } catch {
3660
4604
  return null;
3661
4605
  }
3662
4606
  try {
3663
- const data = YAML2.parse(text, { version: "1.1" });
4607
+ const data = YAML3.parse(text, { version: "1.1" });
3664
4608
  return data;
3665
4609
  } catch {
3666
4610
  return void 0;
@@ -3676,12 +4620,12 @@ var LEGACY_SETTINGS_FILE = ".agent-settings";
3676
4620
  var LEGACY_BACKUP_FILE = ".agent-settings.backup.key-value";
3677
4621
  var SETTINGS_SUBDIR = ["agents", "settings"];
3678
4622
  function _canonical_settings_target(project_root) {
3679
- return path12.join(project_root, ...SETTINGS_SUBDIR, SETTINGS_FILE);
4623
+ return path20.join(project_root, ...SETTINGS_SUBDIR, SETTINGS_FILE);
3680
4624
  }
3681
4625
  function _resolve_settings_read(project_root) {
3682
4626
  const canonical = _canonical_settings_target(project_root);
3683
4627
  if (pathExists(canonical)) return canonical;
3684
- const legacy = path12.join(project_root, SETTINGS_FILE);
4628
+ const legacy = path20.join(project_root, SETTINGS_FILE);
3685
4629
  if (pathExists(legacy)) return legacy;
3686
4630
  return canonical;
3687
4631
  }
@@ -3747,9 +4691,9 @@ function fail(msg) {
3747
4691
  throw new SystemExitError(1);
3748
4692
  }
3749
4693
  function detect_package_root(project_root) {
3750
- const npm_path = path12.join(project_root, "node_modules", "@event4u", "agent-config");
4694
+ const npm_path = path20.join(project_root, "node_modules", "@event4u", "agent-config");
3751
4695
  if (isDir(npm_path)) return resolvePath(npm_path);
3752
- if (pathExists(path12.join(project_root, "src", "config", "profiles", "minimal.ini"))) {
4696
+ if (pathExists(path20.join(project_root, "src", "config", "profiles", "minimal.ini"))) {
3753
4697
  return project_root;
3754
4698
  }
3755
4699
  fail(
@@ -3757,12 +4701,12 @@ function detect_package_root(project_root) {
3757
4701
  );
3758
4702
  }
3759
4703
  function detect_package_type(package_root) {
3760
- if (package_root.split(path12.sep).includes("node_modules")) return "npm";
4704
+ if (package_root.split(path20.sep).includes("node_modules")) return "npm";
3761
4705
  return "local";
3762
4706
  }
3763
4707
  function detect_package_type_for_project(project_root, package_root) {
3764
4708
  const npm_path = resolvePath(
3765
- path12.join(project_root, "node_modules", "@event4u", "agent-config")
4709
+ path20.join(project_root, "node_modules", "@event4u", "agent-config")
3766
4710
  );
3767
4711
  const package_resolved = resolvePath(package_root);
3768
4712
  if (package_resolved === npm_path) return "npm";
@@ -3786,7 +4730,7 @@ function ensure_directory(p) {
3786
4730
  mkdirp(p);
3787
4731
  }
3788
4732
  function write_file(p, content) {
3789
- ensure_directory(path12.dirname(p));
4733
+ ensure_directory(path20.dirname(p));
3790
4734
  writeText(p, content);
3791
4735
  }
3792
4736
  function read_json_file(p) {
@@ -3807,50 +4751,6 @@ function write_json_file(p, data) {
3807
4751
  const content = jsonDumpsIndent(data, 4) + "\n";
3808
4752
  write_file(p, content);
3809
4753
  }
3810
- function _isPlainObject(v) {
3811
- return typeof v === "object" && v !== null && !Array.isArray(v);
3812
- }
3813
- function deepcopy(v) {
3814
- if (v === null || typeof v !== "object") return v;
3815
- if (Array.isArray(v)) return v.map((x) => deepcopy(x));
3816
- const out = {};
3817
- for (const k of Object.keys(v)) {
3818
- out[k] = deepcopy(v[k]);
3819
- }
3820
- return out;
3821
- }
3822
- function deep_merge(base, overlay) {
3823
- const result = deepcopy(base);
3824
- for (const key of Object.keys(overlay)) {
3825
- const value = overlay[key];
3826
- if (Object.prototype.hasOwnProperty.call(result, key) && _isPlainObject(result[key]) && _isPlainObject(value)) {
3827
- result[key] = deep_merge(
3828
- result[key],
3829
- value
3830
- );
3831
- } else {
3832
- result[key] = deepcopy(value);
3833
- }
3834
- }
3835
- return result;
3836
- }
3837
- function jsonEqual(a, b) {
3838
- if (a === b) return true;
3839
- if (typeof a !== typeof b) return false;
3840
- if (Array.isArray(a) || Array.isArray(b)) {
3841
- if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
3842
- return a.every((v, i) => jsonEqual(v, b[i]));
3843
- }
3844
- if (_isPlainObject(a) && _isPlainObject(b)) {
3845
- const ka = Object.keys(a);
3846
- const kb = Object.keys(b);
3847
- if (ka.length !== kb.length) return false;
3848
- return ka.every(
3849
- (k) => Object.prototype.hasOwnProperty.call(b, k) && jsonEqual(a[k], b[k])
3850
- );
3851
- }
3852
- return false;
3853
- }
3854
4754
  function merge_json_file(p, new_data, _force, label) {
3855
4755
  const new_entries = build_merge_entries(label, new_data);
3856
4756
  if (!pathExists(p)) {
@@ -3859,7 +4759,7 @@ function merge_json_file(p, new_data, _force, label) {
3859
4759
  return new_entries;
3860
4760
  }
3861
4761
  const existing = read_json_file(p);
3862
- const merged = deep_merge(existing, new_data);
4762
+ const merged = mergeHostConfig(existing, new_data, HOOK_SIGNATURES[label] ?? "", deepMerge);
3863
4763
  if (jsonEqual(merged, existing)) {
3864
4764
  skip(`${label} already configured`);
3865
4765
  return new_entries;
@@ -3957,7 +4857,7 @@ function _append_unknown_legacy(rendered, legacy_values, unknown_keys) {
3957
4857
  return rendered + "\n" + suffix;
3958
4858
  }
3959
4859
  function _migrate_legacy_if_present(project_root, template_body) {
3960
- const legacy_target = path12.join(project_root, LEGACY_SETTINGS_FILE);
4860
+ const legacy_target = path20.join(project_root, LEGACY_SETTINGS_FILE);
3961
4861
  if (!isFile(legacy_target)) return null;
3962
4862
  const legacy_text = readText(legacy_target);
3963
4863
  const [values, unknown] = _parse_legacy_settings(legacy_text);
@@ -3972,9 +4872,9 @@ function _migrate_legacy_if_present(project_root, template_body) {
3972
4872
  }
3973
4873
  }
3974
4874
  rendered = _append_unknown_legacy(rendered, values, unknown);
3975
- const backup_target = path12.join(project_root, LEGACY_BACKUP_FILE);
4875
+ const backup_target = path20.join(project_root, LEGACY_BACKUP_FILE);
3976
4876
  writeText(backup_target, legacy_text);
3977
- fs14.unlinkSync(legacy_target);
4877
+ fs20.unlinkSync(legacy_target);
3978
4878
  info(`Migrated legacy ${LEGACY_SETTINGS_FILE} \u2192 ${SETTINGS_FILE}`);
3979
4879
  info(`Backup saved to ${LEGACY_BACKUP_FILE}`);
3980
4880
  if (unknown.length > 0) {
@@ -4009,7 +4909,7 @@ function _render_template(template, profile_values) {
4009
4909
  return body;
4010
4910
  }
4011
4911
  function _load_valid_user_types(package_root) {
4012
- const directory = path12.join(package_root, USER_TYPES_DIR);
4912
+ const directory = path20.join(package_root, USER_TYPES_DIR);
4013
4913
  if (!isDir(directory)) return [];
4014
4914
  return sortedGlobStems(directory, ".yml");
4015
4915
  }
@@ -4066,8 +4966,8 @@ function splitlinesKeepends(text) {
4066
4966
  }
4067
4967
  function ensure_agent_settings(project_root, package_root, profile, force, user_type = "", packs = null) {
4068
4968
  const target = _canonical_settings_target(project_root);
4069
- const profile_source = path12.join(package_root, "src", "config", "profiles", `${profile}.ini`);
4070
- const template_source = path12.join(package_root, "src", "config", "agent-settings.template.yml");
4969
+ const profile_source = path20.join(package_root, "src", "config", "profiles", `${profile}.ini`);
4970
+ const template_source = path20.join(package_root, "src", "config", "agent-settings.template.yml");
4071
4971
  if (!pathExists(profile_source)) fail(`Missing profile preset: ${profile_source}`);
4072
4972
  if (!pathExists(template_source)) fail(`Missing settings template: ${template_source}`);
4073
4973
  const template = readText(template_source);
@@ -4081,21 +4981,21 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
4081
4981
  if (profile_values["rule_loading_tier"] !== profile) {
4082
4982
  const got = "rule_loading_tier" in profile_values ? `'${profile_values["rule_loading_tier"]}'` : "None";
4083
4983
  fail(
4084
- `Profile preset ${path12.basename(profile_source)} has rule_loading_tier=${got} but --profile=${profile}`
4984
+ `Profile preset ${path20.basename(profile_source)} has rule_loading_tier=${got} but --profile=${profile}`
4085
4985
  );
4086
4986
  }
4087
4987
  profile_values["user_type"] = _validate_user_type(package_root, user_type);
4088
4988
  let template_body = _render_template(template, profile_values);
4089
4989
  template_body = _inject_packs(template_body, packs ?? []);
4090
- const legacy_root = path12.join(project_root, SETTINGS_FILE);
4990
+ const legacy_root = path20.join(project_root, SETTINGS_FILE);
4091
4991
  if (isFile(legacy_root) && !pathExists(target)) {
4092
- mkdirp(path12.dirname(target));
4992
+ mkdirp(path20.dirname(target));
4093
4993
  writeText(target, readText(legacy_root));
4094
- fs14.unlinkSync(legacy_root);
4994
+ fs20.unlinkSync(legacy_root);
4095
4995
  success(`Migrated ${SETTINGS_FILE} \u2192 agents/settings/${SETTINGS_FILE} (ADR-038)`);
4096
4996
  return;
4097
4997
  }
4098
- const legacy_target = path12.join(project_root, LEGACY_SETTINGS_FILE);
4998
+ const legacy_target = path20.join(project_root, LEGACY_SETTINGS_FILE);
4099
4999
  if (isFile(legacy_target) && pathExists(target)) {
4100
5000
  warn(
4101
5001
  `Both ${SETTINGS_FILE} and legacy ${LEGACY_SETTINGS_FILE} exist. Skipping migration to avoid overwriting ${SETTINGS_FILE}. Delete one of them manually and re-run.`
@@ -4112,7 +5012,7 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
4112
5012
  skip(`${SETTINGS_FILE} already exists`);
4113
5013
  return;
4114
5014
  }
4115
- mkdirp(path12.dirname(target));
5015
+ mkdirp(path20.dirname(target));
4116
5016
  write_file(target, template_body);
4117
5017
  const user_type_value = profile_values["user_type"] ?? "";
4118
5018
  const suffix = user_type_value ? `, user_type=${user_type_value}` : "";
@@ -4125,7 +5025,7 @@ function ensure_vscode_bridge(project_root, package_type, force) {
4125
5025
  const plugin_path = plugin_paths[package_type] ?? "./plugin/agent-config";
4126
5026
  const bridge = { "chat.pluginLocations": { [plugin_path]: true } };
4127
5027
  return merge_json_file(
4128
- path12.join(project_root, ".vscode", "settings.json"),
5028
+ path20.join(project_root, ".vscode", "settings.json"),
4129
5029
  bridge,
4130
5030
  force,
4131
5031
  ".vscode/settings.json"
@@ -4134,14 +5034,14 @@ function ensure_vscode_bridge(project_root, package_type, force) {
4134
5034
  function ensure_augment_bridge(project_root, force) {
4135
5035
  const bridge = { enabledPlugins: { "agent-config@event4u": true } };
4136
5036
  return merge_json_file(
4137
- path12.join(project_root, ".augment", "settings.json"),
5037
+ path20.join(project_root, ".augment", "settings.json"),
4138
5038
  bridge,
4139
5039
  force,
4140
5040
  ".augment/settings.json"
4141
5041
  );
4142
5042
  }
4143
- var AUGMENT_USER_DIR = path12.join(os3.homedir(), ".augment");
4144
- var AUGMENT_USER_HOOKS_DIR = path12.join(AUGMENT_USER_DIR, "hooks");
5043
+ var AUGMENT_USER_DIR = path20.join(os6.homedir(), ".augment");
5044
+ var AUGMENT_USER_HOOKS_DIR = path20.join(AUGMENT_USER_DIR, "hooks");
4145
5045
  var AUGMENT_DISPATCHER_TRAMPOLINE = "augment-dispatcher.sh";
4146
5046
  var AUGMENT_LEGACY_TRAMPOLINES = [
4147
5047
  "augment-chat-history.sh",
@@ -4150,29 +5050,29 @@ var AUGMENT_LEGACY_TRAMPOLINES = [
4150
5050
  "augment-context-hygiene.sh"
4151
5051
  ];
4152
5052
  function _deploy_augment_trampoline(package_root, name, force) {
4153
- const src = path12.join(package_root, "scripts", "hooks", name);
5053
+ const src = path20.join(package_root, "scripts", "hooks", name);
4154
5054
  if (!pathExists(src)) {
4155
5055
  skip(`augment trampoline missing in package: ${src}`);
4156
5056
  return null;
4157
5057
  }
4158
5058
  mkdirp(AUGMENT_USER_HOOKS_DIR);
4159
- const dst = path12.join(AUGMENT_USER_HOOKS_DIR, name);
5059
+ const dst = path20.join(AUGMENT_USER_HOOKS_DIR, name);
4160
5060
  const src_text = readText(src);
4161
5061
  if (pathExists(dst) && readText(dst) === src_text && !force) {
4162
5062
  skip(`~/.augment/hooks/${name} already up to date`);
4163
5063
  } else {
4164
5064
  writeText(dst, src_text);
4165
- fs14.chmodSync(dst, 493);
5065
+ fs20.chmodSync(dst, 493);
4166
5066
  success(`~/.augment/hooks/${name} installed`);
4167
5067
  }
4168
5068
  return dst;
4169
5069
  }
4170
5070
  function _remove_legacy_augment_trampolines() {
4171
5071
  for (const name of AUGMENT_LEGACY_TRAMPOLINES) {
4172
- const legacy = path12.join(AUGMENT_USER_HOOKS_DIR, name);
5072
+ const legacy = path20.join(AUGMENT_USER_HOOKS_DIR, name);
4173
5073
  try {
4174
5074
  if (isFile(legacy)) {
4175
- fs14.unlinkSync(legacy);
5075
+ fs20.unlinkSync(legacy);
4176
5076
  skip(`removed legacy ~/.augment/hooks/${name}`);
4177
5077
  }
4178
5078
  } catch (err) {
@@ -4192,7 +5092,7 @@ function ensure_augment_user_hooks(package_root, force) {
4192
5092
  }
4193
5093
  const settings_patch = { hooks: per_event };
4194
5094
  return merge_json_file(
4195
- path12.join(AUGMENT_USER_DIR, "settings.json"),
5095
+ path20.join(AUGMENT_USER_DIR, "settings.json"),
4196
5096
  settings_patch,
4197
5097
  force,
4198
5098
  "~/.augment/settings.json"
@@ -4207,7 +5107,7 @@ function _heal_legacy_claude_plugin_ids(p) {
4207
5107
  if (!pathExists(p)) return [];
4208
5108
  const data = read_json_file(p);
4209
5109
  const enabled = data["enabledPlugins"];
4210
- if (!_isPlainObject(enabled)) return [];
5110
+ if (!isPlainObject(enabled)) return [];
4211
5111
  const removed = CLAUDE_LEGACY_PLUGIN_IDS.filter((pid) => pid in enabled);
4212
5112
  if (removed.length === 0) return [];
4213
5113
  for (const pid of removed) {
@@ -4217,12 +5117,10 @@ function _heal_legacy_claude_plugin_ids(p) {
4217
5117
  return removed;
4218
5118
  }
4219
5119
  function ensure_claude_bridge(project_root, force) {
4220
- const target = path12.join(project_root, ".claude", "settings.json");
5120
+ const target = path20.join(project_root, ".claude", "settings.json");
4221
5121
  const healed = _heal_legacy_claude_plugin_ids(target);
4222
- for (const pid of healed) {
4223
- success(`.claude/settings.json: removed stale plugin id \`${pid}\``);
4224
- }
4225
- const bridge = { enabledPlugins: { [CLAUDE_PLUGIN_ID]: true } };
5122
+ for (const pid of healed) success(`.claude/settings.json: removed stale plugin id \`${pid}\``);
5123
+ const bridge = withHostEnv({ enabledPlugins: { [CLAUDE_PLUGIN_ID]: true } }, project_root, success);
4226
5124
  return merge_json_file(target, bridge, force || healed.length > 0, ".claude/settings.json");
4227
5125
  }
4228
5126
  var ensure_mcp_bridge = makeEnsureMcpBridge(merge_json_file);
@@ -4237,29 +5135,29 @@ function ensure_cursor_bridge(project_root, force) {
4237
5135
  }
4238
5136
  const bridge = { version: 1, hooks };
4239
5137
  return merge_json_file(
4240
- path12.join(project_root, ".cursor", "hooks.json"),
5138
+ path20.join(project_root, ".cursor", "hooks.json"),
4241
5139
  bridge,
4242
5140
  force,
4243
5141
  ".cursor/hooks.json"
4244
5142
  );
4245
5143
  }
4246
- var CURSOR_USER_DIR = path12.join(os3.homedir(), ".cursor");
4247
- var CURSOR_USER_HOOKS_DIR = path12.join(CURSOR_USER_DIR, "hooks");
5144
+ var CURSOR_USER_DIR = path20.join(os6.homedir(), ".cursor");
5145
+ var CURSOR_USER_HOOKS_DIR = path20.join(CURSOR_USER_DIR, "hooks");
4248
5146
  var CURSOR_DISPATCHER_TRAMPOLINE = "cursor-dispatcher.sh";
4249
5147
  function ensure_cursor_user_hooks(package_root, force) {
4250
- const src = path12.join(package_root, "scripts", "hooks", CURSOR_DISPATCHER_TRAMPOLINE);
5148
+ const src = path20.join(package_root, "scripts", "hooks", CURSOR_DISPATCHER_TRAMPOLINE);
4251
5149
  if (!pathExists(src)) {
4252
5150
  skip(`cursor trampoline missing in package: ${src}`);
4253
5151
  return [];
4254
5152
  }
4255
5153
  mkdirp(CURSOR_USER_HOOKS_DIR);
4256
- const dst = path12.join(CURSOR_USER_HOOKS_DIR, CURSOR_DISPATCHER_TRAMPOLINE);
5154
+ const dst = path20.join(CURSOR_USER_HOOKS_DIR, CURSOR_DISPATCHER_TRAMPOLINE);
4257
5155
  const src_text = readText(src);
4258
5156
  if (pathExists(dst) && readText(dst) === src_text && !force) {
4259
5157
  skip(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} already up to date`);
4260
5158
  } else {
4261
5159
  writeText(dst, src_text);
4262
- fs14.chmodSync(dst, 493);
5160
+ fs20.chmodSync(dst, 493);
4263
5161
  success(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} installed`);
4264
5162
  }
4265
5163
  const hooks = {};
@@ -4268,7 +5166,7 @@ function ensure_cursor_user_hooks(package_root, force) {
4268
5166
  }
4269
5167
  const settings_patch = { version: 1, hooks };
4270
5168
  return merge_json_file(
4271
- path12.join(CURSOR_USER_DIR, "hooks.json"),
5169
+ path20.join(CURSOR_USER_DIR, "hooks.json"),
4272
5170
  settings_patch,
4273
5171
  force,
4274
5172
  "~/.cursor/hooks.json"
@@ -4303,12 +5201,12 @@ exit 0
4303
5201
  `;
4304
5202
  }
4305
5203
  function ensure_cline_bridge(project_root, force) {
4306
- const hooks_dir = path12.join(project_root, ".clinerules", "hooks");
5204
+ const hooks_dir = path20.join(project_root, ".clinerules", "hooks");
4307
5205
  mkdirp(hooks_dir);
4308
5206
  const workspace_quoted = shlexQuote(resolvePath(project_root));
4309
5207
  let written = 0;
4310
5208
  for (const { slot, native } of hostBindings("cline")) {
4311
- const target = path12.join(hooks_dir, native);
5209
+ const target = path20.join(hooks_dir, native);
4312
5210
  const body = clineProjectHookBody(native, slot, workspace_quoted);
4313
5211
  if (pathExists(target) && readText(target) === body && !force) {
4314
5212
  continue;
@@ -4318,7 +5216,7 @@ function ensure_cline_bridge(project_root, force) {
4318
5216
  continue;
4319
5217
  }
4320
5218
  writeText(target, body);
4321
- fs14.chmodSync(target, 493);
5219
+ fs20.chmodSync(target, 493);
4322
5220
  written += 1;
4323
5221
  }
4324
5222
  if (written) {
@@ -4327,27 +5225,27 @@ function ensure_cline_bridge(project_root, force) {
4327
5225
  skip(".clinerules/hooks/ already up to date");
4328
5226
  }
4329
5227
  }
4330
- var CLINE_USER_DIR = path12.join(os3.homedir(), "Documents", "Cline", "Hooks");
5228
+ var CLINE_USER_DIR = path20.join(os6.homedir(), "Documents", "Cline", "Hooks");
4331
5229
  var CLINE_DISPATCHER_TRAMPOLINE = "cline-dispatcher.sh";
4332
5230
  function ensure_cline_user_hooks(package_root, force) {
4333
- const src = path12.join(package_root, "scripts", "hooks", CLINE_DISPATCHER_TRAMPOLINE);
5231
+ const src = path20.join(package_root, "scripts", "hooks", CLINE_DISPATCHER_TRAMPOLINE);
4334
5232
  if (!pathExists(src)) {
4335
5233
  skip(`cline trampoline missing in package: ${src}`);
4336
5234
  return;
4337
5235
  }
4338
5236
  mkdirp(CLINE_USER_DIR);
4339
- const trampoline = path12.join(CLINE_USER_DIR, CLINE_DISPATCHER_TRAMPOLINE);
5237
+ const trampoline = path20.join(CLINE_USER_DIR, CLINE_DISPATCHER_TRAMPOLINE);
4340
5238
  const src_text = readText(src);
4341
5239
  if (pathExists(trampoline) && readText(trampoline) === src_text && !force) {
4342
5240
  skip(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} already up to date`);
4343
5241
  } else {
4344
5242
  writeText(trampoline, src_text);
4345
- fs14.chmodSync(trampoline, 493);
5243
+ fs20.chmodSync(trampoline, 493);
4346
5244
  success(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} installed`);
4347
5245
  }
4348
5246
  const trampoline_quoted = shlexQuote(trampoline);
4349
5247
  for (const { slot, native } of hostBindings("cline")) {
4350
- const wrapper = path12.join(CLINE_USER_DIR, native);
5248
+ const wrapper = path20.join(CLINE_USER_DIR, native);
4351
5249
  const body = `#!/usr/bin/env bash
4352
5250
  # Generated by event4u/agent-config \u2014 DO NOT EDIT.
4353
5251
  # User-scope Cline hook for ${native} \u2192 agent-config ${slot}.
@@ -4357,7 +5255,7 @@ exec ${trampoline_quoted} ${slot} ${native}
4357
5255
  continue;
4358
5256
  }
4359
5257
  writeText(wrapper, body);
4360
- fs14.chmodSync(wrapper, 493);
5258
+ fs20.chmodSync(wrapper, 493);
4361
5259
  }
4362
5260
  }
4363
5261
  function _windsurf_dispatch_command(ac_event, native) {
@@ -4373,29 +5271,29 @@ function ensure_windsurf_bridge(project_root, force) {
4373
5271
  }
4374
5272
  const bridge = { hooks };
4375
5273
  return merge_json_file(
4376
- path12.join(project_root, ".windsurf", "hooks.json"),
5274
+ path20.join(project_root, ".windsurf", "hooks.json"),
4377
5275
  bridge,
4378
5276
  force,
4379
5277
  ".windsurf/hooks.json"
4380
5278
  );
4381
5279
  }
4382
- var WINDSURF_USER_DIR = path12.join(os3.homedir(), ".codeium", "windsurf");
4383
- var WINDSURF_USER_HOOKS_DIR = path12.join(WINDSURF_USER_DIR, "hooks");
5280
+ var WINDSURF_USER_DIR = path20.join(os6.homedir(), ".codeium", "windsurf");
5281
+ var WINDSURF_USER_HOOKS_DIR = path20.join(WINDSURF_USER_DIR, "hooks");
4384
5282
  var WINDSURF_DISPATCHER_TRAMPOLINE = "windsurf-dispatcher.sh";
4385
5283
  function ensure_windsurf_user_hooks(package_root, force) {
4386
- const src = path12.join(package_root, "scripts", "hooks", WINDSURF_DISPATCHER_TRAMPOLINE);
5284
+ const src = path20.join(package_root, "scripts", "hooks", WINDSURF_DISPATCHER_TRAMPOLINE);
4387
5285
  if (!pathExists(src)) {
4388
5286
  skip(`windsurf trampoline missing in package: ${src}`);
4389
5287
  return [];
4390
5288
  }
4391
5289
  mkdirp(WINDSURF_USER_HOOKS_DIR);
4392
- const dst = path12.join(WINDSURF_USER_HOOKS_DIR, WINDSURF_DISPATCHER_TRAMPOLINE);
5290
+ const dst = path20.join(WINDSURF_USER_HOOKS_DIR, WINDSURF_DISPATCHER_TRAMPOLINE);
4393
5291
  const src_text = readText(src);
4394
5292
  if (pathExists(dst) && readText(dst) === src_text && !force) {
4395
5293
  skip(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} already up to date`);
4396
5294
  } else {
4397
5295
  writeText(dst, src_text);
4398
- fs14.chmodSync(dst, 493);
5296
+ fs20.chmodSync(dst, 493);
4399
5297
  success(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} installed`);
4400
5298
  }
4401
5299
  const hooks = {};
@@ -4407,7 +5305,7 @@ function ensure_windsurf_user_hooks(package_root, force) {
4407
5305
  }
4408
5306
  const settings_patch = { hooks };
4409
5307
  return merge_json_file(
4410
- path12.join(WINDSURF_USER_DIR, "hooks.json"),
5308
+ path20.join(WINDSURF_USER_DIR, "hooks.json"),
4411
5309
  settings_patch,
4412
5310
  force,
4413
5311
  "~/.codeium/windsurf/hooks.json"
@@ -4429,43 +5327,43 @@ function _gemini_hooks_dict(command_factory) {
4429
5327
  function ensure_gemini_bridge(project_root, force) {
4430
5328
  const bridge = { hooks: _gemini_hooks_dict(_gemini_dispatch_command) };
4431
5329
  return merge_json_file(
4432
- path12.join(project_root, ".gemini", "settings.json"),
5330
+ path20.join(project_root, ".gemini", "settings.json"),
4433
5331
  bridge,
4434
5332
  force,
4435
5333
  ".gemini/settings.json"
4436
5334
  );
4437
5335
  }
4438
- var GEMINI_USER_DIR = path12.join(os3.homedir(), ".gemini");
4439
- var GEMINI_USER_HOOKS_DIR = path12.join(GEMINI_USER_DIR, "hooks");
5336
+ var GEMINI_USER_DIR = path20.join(os6.homedir(), ".gemini");
5337
+ var GEMINI_USER_HOOKS_DIR = path20.join(GEMINI_USER_DIR, "hooks");
4440
5338
  var GEMINI_DISPATCHER_TRAMPOLINE = "gemini-dispatcher.sh";
4441
5339
  function ensure_gemini_user_hooks(package_root, force) {
4442
- const src = path12.join(package_root, "scripts", "hooks", GEMINI_DISPATCHER_TRAMPOLINE);
5340
+ const src = path20.join(package_root, "scripts", "hooks", GEMINI_DISPATCHER_TRAMPOLINE);
4443
5341
  if (!pathExists(src)) {
4444
5342
  skip(`gemini trampoline missing in package: ${src}`);
4445
5343
  return [];
4446
5344
  }
4447
5345
  mkdirp(GEMINI_USER_HOOKS_DIR);
4448
- const dst = path12.join(GEMINI_USER_HOOKS_DIR, GEMINI_DISPATCHER_TRAMPOLINE);
5346
+ const dst = path20.join(GEMINI_USER_HOOKS_DIR, GEMINI_DISPATCHER_TRAMPOLINE);
4449
5347
  const src_text = readText(src);
4450
5348
  if (pathExists(dst) && readText(dst) === src_text && !force) {
4451
5349
  skip(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} already up to date`);
4452
5350
  } else {
4453
5351
  writeText(dst, src_text);
4454
- fs14.chmodSync(dst, 493);
5352
+ fs20.chmodSync(dst, 493);
4455
5353
  success(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} installed`);
4456
5354
  }
4457
5355
  const settings_patch = {
4458
5356
  hooks: _gemini_hooks_dict((ac_event, native) => `${dst} ${ac_event} ${native}`)
4459
5357
  };
4460
5358
  return merge_json_file(
4461
- path12.join(GEMINI_USER_DIR, "settings.json"),
5359
+ path20.join(GEMINI_USER_DIR, "settings.json"),
4462
5360
  settings_patch,
4463
5361
  force,
4464
5362
  "~/.gemini/settings.json"
4465
5363
  );
4466
5364
  }
4467
5365
  function ensure_copilot_bridge(project_root, force) {
4468
- const target = path12.join(project_root, ".github", "plugin", "marketplace.json");
5366
+ const target = path20.join(project_root, ".github", "plugin", "marketplace.json");
4469
5367
  const bridge = {
4470
5368
  marketplace: {
4471
5369
  name: "event4u-agent-marketplace",
@@ -4508,7 +5406,7 @@ See \`docs/setup/per-ide/roocode.md\` for the full activation guide.
4508
5406
  Run \`./agent-config --help\` for available commands.
4509
5407
  `;
4510
5408
  function ensure_roocode_bridge(project_root, force) {
4511
- const target = path12.join(project_root, ".roo", "rules", "agent-config.md");
5409
+ const target = path20.join(project_root, ".roo", "rules", "agent-config.md");
4512
5410
  if (pathExists(target) && !force) {
4513
5411
  skip(".roo/rules/agent-config.md already exists");
4514
5412
  return;
@@ -4530,7 +5428,7 @@ To wire Claude Desktop to this project's rules, run:
4530
5428
  Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
4531
5429
  `;
4532
5430
  function ensure_claude_desktop_bridge(project_root, force) {
4533
- const target = path12.join(project_root, ".claude-desktop", "agent-config.md");
5431
+ const target = path20.join(project_root, ".claude-desktop", "agent-config.md");
4534
5432
  if (pathExists(target) && !force) {
4535
5433
  skip(".claude-desktop/agent-config.md already exists");
4536
5434
  return;
@@ -4555,7 +5453,7 @@ Or pass \`--read .aider/agent-config.md\` on the command line.
4555
5453
  Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
4556
5454
  `;
4557
5455
  function ensure_aider_bridge(project_root, force) {
4558
- const target = path12.join(project_root, ".aider", "agent-config.md");
5456
+ const target = path20.join(project_root, ".aider", "agent-config.md");
4559
5457
  if (pathExists(target) && !force) {
4560
5458
  skip(".aider/agent-config.md already exists");
4561
5459
  return;
@@ -4574,7 +5472,7 @@ developers where the rules and skills live.
4574
5472
  Canonical rule and skill source: \`.augment/\` (see project \`AGENTS.md\`).
4575
5473
  `;
4576
5474
  function ensure_codex_bridge(project_root, force) {
4577
- const target = path12.join(project_root, ".codex", "agent-config.md");
5475
+ const target = path20.join(project_root, ".codex", "agent-config.md");
4578
5476
  if (pathExists(target) && !force) {
4579
5477
  skip(".codex/agent-config.md already exists");
4580
5478
  return;
@@ -4592,7 +5490,7 @@ rules per session. The canonical rule and skill source lives under
4592
5490
  orientation).
4593
5491
  `;
4594
5492
  function ensure_continue_bridge(project_root, force) {
4595
- const target = path12.join(project_root, ".continue", "rules", "agent-config.md");
5493
+ const target = path20.join(project_root, ".continue", "rules", "agent-config.md");
4596
5494
  if (pathExists(target) && !force) {
4597
5495
  skip(".continue/rules/agent-config.md already exists");
4598
5496
  return;
@@ -4623,7 +5521,7 @@ orientation).
4623
5521
  See \`docs/setup/per-ide/kilocode.md\` for the full activation guide.
4624
5522
  `;
4625
5523
  function ensure_kilocode_bridge(project_root, force) {
4626
- const target = path12.join(project_root, ".kilocode", "rules", "agent-config.md");
5524
+ const target = path20.join(project_root, ".kilocode", "rules", "agent-config.md");
4627
5525
  if (pathExists(target) && !force) {
4628
5526
  skip(".kilocode/rules/agent-config.md already exists");
4629
5527
  return;
@@ -4650,7 +5548,7 @@ canonical source (or symlink it):
4650
5548
  Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
4651
5549
  `;
4652
5550
  function ensure_zed_bridge(project_root, force) {
4653
- const target = path12.join(project_root, ".zed", "agent-config.md");
5551
+ const target = path20.join(project_root, ".zed", "agent-config.md");
4654
5552
  if (pathExists(target) && !force) {
4655
5553
  skip(".zed/agent-config.md already exists");
4656
5554
  return;
@@ -4671,7 +5569,7 @@ rules into your JetBrains profile.
4671
5569
  Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
4672
5570
  `;
4673
5571
  function ensure_jetbrains_bridge(project_root, force) {
4674
- const target = path12.join(project_root, ".jetbrains", "agent-config.md");
5572
+ const target = path20.join(project_root, ".jetbrains", "agent-config.md");
4675
5573
  if (pathExists(target) && !force) {
4676
5574
  skip(".jetbrains/agent-config.md already exists");
4677
5575
  return;
@@ -4702,7 +5600,7 @@ session. The canonical rule and skill source lives under \`.augment/\`
4702
5600
  See \`docs/setup/per-ide/kiro.md\` for the full activation guide.
4703
5601
  `;
4704
5602
  function ensure_kiro_bridge(project_root, force) {
4705
- const target = path12.join(project_root, ".kiro", "steering", "agent-config.md");
5603
+ const target = path20.join(project_root, ".kiro", "steering", "agent-config.md");
4706
5604
  if (pathExists(target) && !force) {
4707
5605
  skip(".kiro/steering/agent-config.md already exists");
4708
5606
  return;
@@ -4739,35 +5637,35 @@ var SMOKE_BRIDGE_PATHS = {
4739
5637
  };
4740
5638
  function dirHasEntries(p) {
4741
5639
  try {
4742
- return fs14.readdirSync(p).length > 0;
5640
+ return fs20.readdirSync(p).length > 0;
4743
5641
  } catch {
4744
5642
  return false;
4745
5643
  }
4746
5644
  }
4747
5645
  function _resolve_tsx_invocation(scriptPath, scriptArgs) {
4748
5646
  const binName = process2.platform === "win32" ? "tsx.cmd" : "tsx";
4749
- let dir = path12.dirname(scriptPath);
5647
+ let dir = path20.dirname(scriptPath);
4750
5648
  for (; ; ) {
4751
- const candidate = path12.join(dir, "node_modules", ".bin", binName);
5649
+ const candidate = path20.join(dir, "node_modules", ".bin", binName);
4752
5650
  if (isFile(candidate)) {
4753
5651
  return { command: candidate, args: [scriptPath, ...scriptArgs] };
4754
5652
  }
4755
- const parent = path12.dirname(dir);
5653
+ const parent = path20.dirname(dir);
4756
5654
  if (parent === dir) break;
4757
5655
  dir = parent;
4758
5656
  }
4759
5657
  return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
4760
5658
  }
4761
5659
  function _smoke_test_hooks(project_root, package_root) {
4762
- const dispatcher = path12.join(package_root, "scripts", "hooks", "dispatch_hook.ts");
4763
- const manifest = path12.join(package_root, "scripts", "hook_manifest.yaml");
5660
+ const dispatcher = path20.join(package_root, "scripts", "hooks", "dispatch_hook.ts");
5661
+ const manifest = path20.join(package_root, "scripts", "hook_manifest.yaml");
4764
5662
  if (!isFile(dispatcher) || !isFile(manifest)) return 0;
4765
5663
  const failed = [];
4766
5664
  const skipped = [];
4767
5665
  const passed = [];
4768
5666
  for (const [platform, native] of smokeProbeEvents()) {
4769
5667
  const rel_bridge = SMOKE_BRIDGE_PATHS[platform] ?? "";
4770
- const bridge_path = rel_bridge ? path12.join(project_root, rel_bridge) : null;
5668
+ const bridge_path = rel_bridge ? path20.join(project_root, rel_bridge) : null;
4771
5669
  const bridge_present = Boolean(
4772
5670
  bridge_path && (isFile(bridge_path) || isDir(bridge_path) && dirHasEntries(bridge_path))
4773
5671
  );
@@ -4816,7 +5714,7 @@ function _smoke_test_hooks(project_root, package_root) {
4816
5714
  failed.push(`${platform}: dispatcher did not emit JSON plan`);
4817
5715
  continue;
4818
5716
  }
4819
- const concerns = _isPlainObject(plan) ? plan["concerns"] : void 0;
5717
+ const concerns = isPlainObject(plan) ? plan["concerns"] : void 0;
4820
5718
  if (!Array.isArray(concerns)) {
4821
5719
  failed.push(`${platform}: plan.concerns missing or not a list`);
4822
5720
  continue;
@@ -4898,47 +5796,6 @@ var PROJECT_BRIDGE_MARKERS = {
4898
5796
  jetbrains: ".jetbrains/agent-config.md",
4899
5797
  kiro: ".kiro/steering/agent-config.md"
4900
5798
  };
4901
- var _CLAUDE_SKILL_BUNDLE = [
4902
- ["dist/agent-src/rules", "rules"],
4903
- ["dist/agent-src/skills", "skills"],
4904
- ["dist/agent-src/commands", "commands"],
4905
- ["dist/agent-src/personas", "personas"]
4906
- ];
4907
- var GLOBAL_DEPLOY_SOURCES = {
4908
- "claude-code": _CLAUDE_SKILL_BUNDLE,
4909
- augment: [
4910
- ["dist/agent-src/rules", "rules"],
4911
- ["dist/agent-src/skills", "skills"],
4912
- ["dist/agent-src/commands", "commands"],
4913
- ["dist/agent-src/contexts", "contexts"],
4914
- ["dist/agent-src/personas", "personas"],
4915
- ["dist/agent-src/templates", "templates"]
4916
- ],
4917
- cursor: [
4918
- ["dist/agent-src/rules", "rules"],
4919
- ["dist/agent-src/commands", "commands"],
4920
- ["dist/agent-src/personas", "personas"]
4921
- ],
4922
- windsurf: [["dist/agent-src/rules", "rules"]],
4923
- cline: [["dist/agent-src/rules", ""]],
4924
- "gemini-cli": _CLAUDE_SKILL_BUNDLE,
4925
- codex: _CLAUDE_SKILL_BUNDLE,
4926
- continue: _CLAUDE_SKILL_BUNDLE,
4927
- roocode: _CLAUDE_SKILL_BUNDLE,
4928
- kilocode: _CLAUDE_SKILL_BUNDLE,
4929
- qoder: _CLAUDE_SKILL_BUNDLE,
4930
- opencode: _CLAUDE_SKILL_BUNDLE,
4931
- trae: _CLAUDE_SKILL_BUNDLE,
4932
- antigravity: _CLAUDE_SKILL_BUNDLE,
4933
- codebuddy: _CLAUDE_SKILL_BUNDLE,
4934
- droid: _CLAUDE_SKILL_BUNDLE,
4935
- warp: _CLAUDE_SKILL_BUNDLE,
4936
- kiro: [
4937
- ["dist/agent-src/rules", "rules"],
4938
- ["dist/agent-src/skills", "steering"],
4939
- ["dist/agent-src/personas", "personas"]
4940
- ]
4941
- };
4942
5799
  function claudeDesktopMarkerBody(lockfile, anchor, bundles_dir, bundle_count) {
4943
5800
  return `# agent-config \u2014 Claude Desktop marker
4944
5801
 
@@ -4967,9 +5824,9 @@ To remove this marker, delete this file.
4967
5824
  `;
4968
5825
  }
4969
5826
  var _CLAUDE_DESKTOP_BUNDLES_SUBPATH = "claude-desktop/bundles";
4970
- var GLOBAL_ROOT = path12.join(os3.homedir(), ".event4u", "agent-config");
4971
- var GLOBAL_USER_SETTINGS_PATH = path12.join(GLOBAL_ROOT, ".agent-user.yml");
4972
- var GLOBAL_AGENT_SETTINGS_PATH = path12.join(GLOBAL_ROOT, ".agent-settings.yml");
5827
+ var GLOBAL_ROOT = path20.join(os6.homedir(), ".event4u", "agent-config");
5828
+ var GLOBAL_USER_SETTINGS_PATH = path20.join(GLOBAL_ROOT, ".agent-user.yml");
5829
+ var GLOBAL_AGENT_SETTINGS_PATH = path20.join(GLOBAL_ROOT, ".agent-settings.yml");
4973
5830
  function _bridge_marker(tool_id, scope) {
4974
5831
  if (scope === "global") return USER_SCOPE_PATHS[tool_id] ?? "";
4975
5832
  return PROJECT_BRIDGE_MARKERS[tool_id] ?? "";
@@ -5015,10 +5872,10 @@ function _load_yaml_doc(p) {
5015
5872
  return {};
5016
5873
  }
5017
5874
  const data = yamlSafeLoad(text);
5018
- return _isPlainObject(data) ? data : {};
5875
+ return isPlainObject(data) ? data : {};
5019
5876
  }
5020
5877
  function _load_default_settings(package_root) {
5021
- const template_source = path12.join(package_root, "src", "config", "agent-settings.template.yml");
5878
+ const template_source = path20.join(package_root, "src", "config", "agent-settings.template.yml");
5022
5879
  if (!pathExists(template_source)) return {};
5023
5880
  let text;
5024
5881
  try {
@@ -5028,15 +5885,15 @@ function _load_default_settings(package_root) {
5028
5885
  }
5029
5886
  const rendered = text.split(RULE_LOADING_TIER_PLACEHOLDER).join(DEFAULT_PROFILE).split(USER_TYPE_PLACEHOLDER).join("");
5030
5887
  const data = yamlSafeLoad(rendered);
5031
- return _isPlainObject(data) ? data : {};
5888
+ return isPlainObject(data) ? data : {};
5032
5889
  }
5033
5890
  var RULE_LAYER_CHOICES = ["global", "project", "both-acknowledged"];
5034
5891
  function _suppress_rule_layer(project_root, suppress_dir) {
5035
- const target = path12.join(project_root, ".claude", "settings.local.json");
5892
+ const target = path20.join(project_root, ".claude", "settings.local.json");
5036
5893
  const existing = pathExists(target) ? read_json_file(target) : {};
5037
5894
  let real_dir = suppress_dir;
5038
5895
  try {
5039
- real_dir = fs14.realpathSync(suppress_dir);
5896
+ real_dir = fs20.realpathSync(suppress_dir);
5040
5897
  } catch {
5041
5898
  real_dir = suppress_dir;
5042
5899
  }
@@ -5047,8 +5904,7 @@ function _suppress_rule_layer(project_root, suppress_dir) {
5047
5904
  success(`.claude/settings.local.json: claudeMdExcludes += ${entry}`);
5048
5905
  }
5049
5906
  function _gate_rule_layer_overlap(project_root, layer, dry_run) {
5050
- const global_dir = path12.join(os3.homedir(), ".claude", "rules");
5051
- const project_dir = path12.join(project_root, ".claude", "rules");
5907
+ const [global_dir, project_dir] = hostRuleLayerDirs(project_root);
5052
5908
  const g = readRuleLayer(global_dir);
5053
5909
  const p = readRuleLayer(project_dir);
5054
5910
  if (g === null || p === null) return true;
@@ -5136,9 +5992,9 @@ function detect_scope(cwd) {
5136
5992
  if (pathExists(_resolve_settings_read(cwd))) {
5137
5993
  return ["project", `existing ${SETTINGS_FILE}`];
5138
5994
  }
5139
- const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(path12.join(cwd, m))) ?? null;
5140
- const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(path12.join(cwd, d))) ?? null;
5141
- const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(path12.join(cwd, f))) ?? null;
5995
+ const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(path20.join(cwd, m))) ?? null;
5996
+ const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(path20.join(cwd, d))) ?? null;
5997
+ const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(path20.join(cwd, f))) ?? null;
5142
5998
  if (has_manifest && (has_ai_dir || has_ai_file)) {
5143
5999
  const marker = has_ai_dir || has_ai_file;
5144
6000
  return ["prompt", `manifest (${has_manifest}) + AI-tool config (${marker})`];
@@ -5159,7 +6015,7 @@ function readLineSyncRaw(promptText) {
5159
6015
  for (; ; ) {
5160
6016
  let n;
5161
6017
  try {
5162
- n = fs14.readSync(0, buf, 0, 1, null);
6018
+ n = fs20.readSync(0, buf, 0, 1, null);
5163
6019
  } catch (err) {
5164
6020
  const code = err.code;
5165
6021
  if (code === "EAGAIN") {
@@ -5242,26 +6098,26 @@ function _update_installed_tools_manifest(project_root, tools, scope, force, fil
5242
6098
  }
5243
6099
  write_manifest(target, version, entries);
5244
6100
  if (!state.QUIET) {
5245
- const rel = isRelativeTo(target, project_root) ? path12.relative(project_root, target) : target;
6101
+ const rel = isRelativeTo(target, project_root) ? path20.relative(project_root, target) : target;
5246
6102
  info(`Manifest updated: ${rel}`);
5247
6103
  }
5248
6104
  return 0;
5249
6105
  }
5250
6106
  function isRelativeTo(child, parent) {
5251
- const rel = path12.relative(parent, child);
5252
- return rel === "" || !rel.startsWith("..") && !path12.isAbsolute(rel);
6107
+ const rel = path20.relative(parent, child);
6108
+ return rel === "" || !rel.startsWith("..") && !path20.isAbsolute(rel);
5253
6109
  }
5254
6110
  function _resolve_package_root_for_global() {
5255
- const here = resolvePath(_HERE);
5256
- const candidate = path12.dirname(path12.dirname(path12.dirname(here)));
5257
- if (!pathExists(path12.join(candidate, "src", "config", "profiles", "minimal.ini"))) {
6111
+ const here = resolvePath(_HERE2);
6112
+ const candidate = path20.dirname(path20.dirname(path20.dirname(here)));
6113
+ if (!pathExists(path20.join(candidate, "src", "config", "profiles", "minimal.ini"))) {
5258
6114
  fail(
5259
6115
  `Could not locate agent-config package root from ${here}. Expected src/config/profiles/minimal.ini at the parent directory.`
5260
6116
  );
5261
6117
  }
5262
6118
  return candidate;
5263
6119
  }
5264
- var CONSUMER_BRIDGE_MARKER_RELPATH = path12.join("agents", ".event4u-bridge.yml");
6120
+ var CONSUMER_BRIDGE_MARKER_RELPATH = path20.join("agents", ".event4u-bridge.yml");
5265
6121
  var MIGRATE_LEGACY_YAML_FILES = [".agent-settings.yml", ".agent-user.yml"];
5266
6122
  var MIGRATE_LEGACY_TOOL_DIRS = [".augment", ".claude", ".cursor"];
5267
6123
  var AGENT_CONFIG_PACKAGE_NAME = "@event4u/agent-config";
@@ -5269,7 +6125,7 @@ function _is_agent_config_source_repo(project_root) {
5269
6125
  if (process2.env["AGENT_CONFIG_CONSUMER_MODE"] === "1") {
5270
6126
  return [false, "consumer-mode-override"];
5271
6127
  }
5272
- const pkg_json = path12.join(project_root, "package.json");
6128
+ const pkg_json = path20.join(project_root, "package.json");
5273
6129
  if (isFile(pkg_json)) {
5274
6130
  let data = {};
5275
6131
  try {
@@ -5277,17 +6133,17 @@ function _is_agent_config_source_repo(project_root) {
5277
6133
  } catch {
5278
6134
  data = {};
5279
6135
  }
5280
- if (_isPlainObject(data) && data["name"] === AGENT_CONFIG_PACKAGE_NAME) {
6136
+ if (isPlainObject(data) && data["name"] === AGENT_CONFIG_PACKAGE_NAME) {
5281
6137
  return [true, "package.json:name"];
5282
6138
  }
5283
6139
  }
5284
- if (isDir(path12.join(project_root, ".agent-src.uncondensed"))) {
6140
+ if (isDir(path20.join(project_root, ".agent-src.uncondensed"))) {
5285
6141
  return [true, ".agent-src.uncondensed/"];
5286
6142
  }
5287
- const packages_dir = path12.join(project_root, "packages");
6143
+ const packages_dir = path20.join(project_root, "packages");
5288
6144
  if (isDir(packages_dir)) {
5289
- for (const child of fs14.readdirSync(packages_dir)) {
5290
- if (isDir(path12.join(packages_dir, child, ".agent-src.uncondensed"))) {
6145
+ for (const child of fs20.readdirSync(packages_dir)) {
6146
+ if (isDir(path20.join(packages_dir, child, ".agent-src.uncondensed"))) {
5291
6147
  return [true, `packages/${child}/.agent-src.uncondensed/`];
5292
6148
  }
5293
6149
  }
@@ -5305,17 +6161,17 @@ function _detect_legacy_for_migration(project_root) {
5305
6161
  }
5306
6162
  return [];
5307
6163
  }
5308
- if (isFile(path12.join(project_root, INSTALL_MODE_MARKER_REL))) return [];
6164
+ if (isFile(path20.join(project_root, INSTALL_MODE_MARKER_REL))) return [];
5309
6165
  const found = [];
5310
6166
  for (const name of MIGRATE_LEGACY_YAML_FILES) {
5311
- if (isFile(path12.join(project_root, name))) {
6167
+ if (isFile(path20.join(project_root, name))) {
5312
6168
  found.push(name);
5313
- } else if (isFile(path12.join(project_root, "settings", name))) {
6169
+ } else if (isFile(path20.join(project_root, "settings", name))) {
5314
6170
  found.push(`settings/${name}`);
5315
6171
  }
5316
6172
  }
5317
6173
  for (const name of MIGRATE_LEGACY_TOOL_DIRS) {
5318
- const p = path12.join(project_root, name);
6174
+ const p = path20.join(project_root, name);
5319
6175
  if (isDir(p) && !isSymlink(p)) {
5320
6176
  found.push(`${name}/`);
5321
6177
  }
@@ -5327,7 +6183,7 @@ function _prompt_migrate_to_global(project_root, artefacts) {
5327
6183
  process2.stdout.write("\n");
5328
6184
  warn("Legacy project-local artefacts detected \u2014 pre-ADR-020 layout:");
5329
6185
  for (const rel of artefacts) {
5330
- info(` ${path12.join(project_root, rel)}`);
6186
+ info(` ${path20.join(project_root, rel)}`);
5331
6187
  }
5332
6188
  info("The unified `agent-config migrate` sweeps these in one pass.");
5333
6189
  info("The wizard recreates fresh config afterwards.");
@@ -5356,22 +6212,22 @@ function _run_migrate_to_global(project_root) {
5356
6212
  }
5357
6213
  }
5358
6214
  function _format_global_root_for_marker(global_root) {
5359
- const home = resolvePath(os3.homedir());
6215
+ const home = resolvePath(os6.homedir());
5360
6216
  const resolved = resolvePath(global_root);
5361
- const rel = path12.relative(home, resolved);
5362
- if (rel === "" || rel.startsWith("..") || path12.isAbsolute(rel)) {
6217
+ const rel = path20.relative(home, resolved);
6218
+ if (rel === "" || rel.startsWith("..") || path20.isAbsolute(rel)) {
5363
6219
  return global_root;
5364
6220
  }
5365
- return `~/${rel.split(path12.sep).join("/")}`;
6221
+ return `~/${rel.split(path20.sep).join("/")}`;
5366
6222
  }
5367
6223
  function _remove_legacy_consumer_bridge_marker(project_root, env = null) {
5368
6224
  const env_map = env ?? process2.env;
5369
6225
  if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return null;
5370
- if (isDir(path12.join(project_root, ".agent-src.uncondensed"))) return null;
5371
- const target = path12.join(project_root, CONSUMER_BRIDGE_MARKER_RELPATH);
6226
+ if (isDir(path20.join(project_root, ".agent-src.uncondensed"))) return null;
6227
+ const target = path20.join(project_root, CONSUMER_BRIDGE_MARKER_RELPATH);
5372
6228
  if (!isFile(target)) return null;
5373
6229
  try {
5374
- fs14.rmSync(target);
6230
+ fs20.rmSync(target);
5375
6231
  } catch {
5376
6232
  return null;
5377
6233
  }
@@ -5385,7 +6241,7 @@ var PROJECT_ANCHOR_TOOLS = {
5385
6241
  function _write_per_tool_project_anchors(project_root, tools, env = null, now = null) {
5386
6242
  const env_map = env ?? process2.env;
5387
6243
  if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return [];
5388
- if (isDir(path12.join(project_root, ".agent-src.uncondensed"))) return [];
6244
+ if (isDir(path20.join(project_root, ".agent-src.uncondensed"))) return [];
5389
6245
  const global_root_str = _format_global_root_for_marker(
5390
6246
  event4u_root(env_map)
5391
6247
  );
@@ -5394,8 +6250,8 @@ function _write_per_tool_project_anchors(project_root, tools, env = null, now =
5394
6250
  for (const tool_id of Object.keys(PROJECT_ANCHOR_TOOLS).sort()) {
5395
6251
  const rel_path = PROJECT_ANCHOR_TOOLS[tool_id];
5396
6252
  if (!tools.has(tool_id)) continue;
5397
- const target = path12.join(project_root, rel_path);
5398
- mkdirp(path12.dirname(target));
6253
+ const target = path20.join(project_root, rel_path);
6254
+ mkdirp(path20.dirname(target));
5399
6255
  const body = `# event4u/agent-config \u2014 per-tool project anchor (auto-written).
5400
6256
  # Spec: docs/contracts/consumer-bridge.md \xA7 Per-tool anchor strategy.
5401
6257
  # Tool: ${tool_id}. Resolves the global install directly \u2014 no
@@ -5413,7 +6269,7 @@ installed_at: ${stamp}
5413
6269
  }
5414
6270
  var PACKAGE_TAG_ID = "event4u/agent-config";
5415
6271
  function _inject_package_tag(target, source, package_root) {
5416
- if (path12.extname(target) !== ".md") return;
6272
+ if (path20.extname(target) !== ".md") return;
5417
6273
  let text;
5418
6274
  try {
5419
6275
  text = readText(target);
@@ -5441,8 +6297,8 @@ function _inject_package_tag(target, source, package_root) {
5441
6297
  resolved_src = source;
5442
6298
  }
5443
6299
  if (package_root !== null) {
5444
- const rel = path12.relative(resolvePath(package_root), resolved_src);
5445
- if (rel !== "" && !rel.startsWith("..") && !path12.isAbsolute(rel)) {
6300
+ const rel = path20.relative(resolvePath(package_root), resolved_src);
6301
+ if (rel !== "" && !rel.startsWith("..") && !path20.isAbsolute(rel)) {
5446
6302
  source_value = rel;
5447
6303
  } else {
5448
6304
  source_value = resolved_src;
@@ -5477,7 +6333,7 @@ function _escapes_package_root(resolved, package_root) {
5477
6333
  if (package_root === null) return false;
5478
6334
  let root;
5479
6335
  try {
5480
- root = fs14.realpathSync(package_root);
6336
+ root = fs20.realpathSync(package_root);
5481
6337
  } catch {
5482
6338
  return false;
5483
6339
  }
@@ -5503,7 +6359,7 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5503
6359
  if (file_filter !== null && !file_filter(src)) return [0, 0, written_paths];
5504
6360
  let resolved_src = src;
5505
6361
  try {
5506
- resolved_src = fs14.realpathSync(src);
6362
+ resolved_src = fs20.realpathSync(src);
5507
6363
  } catch {
5508
6364
  resolved_src = src;
5509
6365
  }
@@ -5511,14 +6367,14 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5511
6367
  warn(`refused: ${src} dereferences outside the package root \u2014 not copied`);
5512
6368
  return [0, 0, written_paths];
5513
6369
  }
5514
- mkdirp(path12.dirname(dest));
6370
+ mkdirp(path20.dirname(dest));
5515
6371
  const decision = tracker.resolve(dest, force);
5516
6372
  if (decision === "preserve") {
5517
6373
  tracker.preserve(dest, resolved_src, package_root);
5518
6374
  _log_tx_entry("skip", dest);
5519
6375
  return [0, 1, written_paths];
5520
6376
  }
5521
- fs14.copyFileSync(src, dest);
6377
+ fs20.copyFileSync(src, dest);
5522
6378
  _inject_package_tag(dest, src, package_root);
5523
6379
  _log_tx_entry("write", dest);
5524
6380
  written_paths.push(dest);
@@ -5527,11 +6383,11 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5527
6383
  mkdirp(dest);
5528
6384
  const walk = (node) => {
5529
6385
  const acc = [];
5530
- const names = fs14.readdirSync(node).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
6386
+ const names = fs20.readdirSync(node).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
5531
6387
  for (const name of names) {
5532
- const entry = path12.join(node, name);
6388
+ const entry = path20.join(node, name);
5533
6389
  acc.push(entry);
5534
- const lst = fs14.lstatSync(entry);
6390
+ const lst = fs20.lstatSync(entry);
5535
6391
  if (lst.isDirectory() && !lst.isSymbolicLink()) {
5536
6392
  acc.push(...walk(entry));
5537
6393
  }
@@ -5539,9 +6395,9 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5539
6395
  return acc;
5540
6396
  };
5541
6397
  for (const entry of walk(src)) {
5542
- const rel = path12.relative(src, entry);
5543
- const target = path12.join(dest, rel);
5544
- const lst = fs14.lstatSync(entry);
6398
+ const rel = path20.relative(src, entry);
6399
+ const target = path20.join(dest, rel);
6400
+ const lst = fs20.lstatSync(entry);
5545
6401
  if (lst.isDirectory() && !lst.isSymbolicLink()) {
5546
6402
  mkdirp(target);
5547
6403
  continue;
@@ -5549,8 +6405,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5549
6405
  let resolvedIsDir = false;
5550
6406
  let resolved = entry;
5551
6407
  try {
5552
- resolved = fs14.realpathSync(entry);
5553
- resolvedIsDir = fs14.statSync(entry).isDirectory();
6408
+ resolved = fs20.realpathSync(entry);
6409
+ resolvedIsDir = fs20.statSync(entry).isDirectory();
5554
6410
  } catch {
5555
6411
  resolvedIsDir = false;
5556
6412
  }
@@ -5582,8 +6438,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5582
6438
  _log_tx_entry("skip", target);
5583
6439
  continue;
5584
6440
  }
5585
- mkdirp(path12.dirname(target));
5586
- fs14.copyFileSync(resolved, target);
6441
+ mkdirp(path20.dirname(target));
6442
+ fs20.copyFileSync(resolved, target);
5587
6443
  _inject_package_tag(target, resolved, package_root);
5588
6444
  _log_tx_entry("write", target);
5589
6445
  written += 1;
@@ -5596,7 +6452,7 @@ function _claude_desktop_bundles_dir() {
5596
6452
  }
5597
6453
  function _write_claude_desktop_marker(force, lockfile_path2, bundles_dir, bundle_count) {
5598
6454
  const anchor = expanduser3(USER_SCOPE_PATHS["claude-desktop"]);
5599
- const target = path12.join(anchor, "agent-config.md");
6455
+ const target = path20.join(anchor, "agent-config.md");
5600
6456
  mkdirp(anchor);
5601
6457
  const body = claudeDesktopMarkerBody(lockfile_path2, anchor, bundles_dir, bundle_count);
5602
6458
  if (tracker.resolve(target, force) === "preserve") {
@@ -5621,27 +6477,15 @@ function _deploy_claude_desktop(force, package_root, lockfile_path2) {
5621
6477
  return [bundle_count, 0, "deployed", [bundles_dir, ...marker_paths]];
5622
6478
  }
5623
6479
  var _CLAUDE_FLAT_WRAPPER_EXTRA = /* @__PURE__ */ new Set(["commit"]);
5624
- function _apply_claude_flat_command_wrappers(anchor, package_root, current_files) {
6480
+ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files, recorded_files = /* @__PURE__ */ new Set()) {
5625
6481
  const wrapped = [];
5626
6482
  const collisions = [];
5627
- const reserved = [];
5628
- const commands_dir = path12.join(anchor, "commands");
5629
- let flat_entries = [];
5630
- try {
5631
- flat_entries = fs14.readdirSync(commands_dir).filter((f) => f.endsWith(".md"));
5632
- } catch {
5633
- }
5634
- for (const fname of flat_entries.sort()) {
5635
- const slug = fname.slice(0, -".md".length);
5636
- if (!is_claude_builtin_name(slug)) continue;
5637
- fs14.rmSync(path12.join(commands_dir, fname), { force: true });
5638
- current_files.delete(`commands/${fname}`);
5639
- reserved.push(slug);
5640
- }
6483
+ const commands_dir = path20.join(anchor, "commands");
6484
+ const { reserved, foreign } = sweepReservedNames(commands_dir, current_files, is_claude_builtin_name, recorded_files);
5641
6485
  const eligible = new Set(_CLAUDE_FLAT_WRAPPER_EXTRA);
5642
6486
  try {
5643
6487
  const manifest = JSON.parse(
5644
- fs14.readFileSync(path12.join(package_root, "dist", "discovery", "discovery-manifest.json"), "utf8")
6488
+ fs20.readFileSync(path20.join(package_root, "dist", "discovery", "discovery-manifest.json"), "utf8")
5645
6489
  );
5646
6490
  for (const a of manifest.artefacts ?? []) {
5647
6491
  if (a.category !== "command" || typeof a.slug !== "string") continue;
@@ -5652,27 +6496,27 @@ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files
5652
6496
  }
5653
6497
  for (const slug of [...eligible].sort()) {
5654
6498
  const flat_rel = `commands/${slug}.md`;
5655
- const flat_abs = path12.join(anchor, "commands", `${slug}.md`);
5656
- if (!fs14.existsSync(flat_abs)) continue;
5657
- const skill_dir = path12.join(anchor, "skills", slug);
5658
- if (fs14.existsSync(skill_dir)) {
6499
+ const flat_abs = path20.join(anchor, "commands", `${slug}.md`);
6500
+ if (!fs20.existsSync(flat_abs)) continue;
6501
+ const skill_dir = path20.join(anchor, "skills", slug);
6502
+ if (fs20.existsSync(skill_dir)) {
5659
6503
  collisions.push(slug);
5660
6504
  continue;
5661
6505
  }
5662
- let body = fs14.readFileSync(flat_abs, "utf8");
6506
+ let body = fs20.readFileSync(flat_abs, "utf8");
5663
6507
  if (body.startsWith("---\n") && !/^name:/m.test(body.split("\n---")[0] ?? "")) {
5664
6508
  body = body.replace("---\n", `---
5665
6509
  name: ${slug}
5666
6510
  `);
5667
6511
  }
5668
- fs14.mkdirSync(skill_dir, { recursive: true });
5669
- fs14.writeFileSync(path12.join(skill_dir, "SKILL.md"), body, "utf8");
5670
- fs14.rmSync(flat_abs, { force: true });
6512
+ fs20.mkdirSync(skill_dir, { recursive: true });
6513
+ fs20.writeFileSync(path20.join(skill_dir, "SKILL.md"), body, "utf8");
6514
+ fs20.rmSync(flat_abs, { force: true });
5671
6515
  current_files.delete(flat_rel);
5672
6516
  current_files.add(`skills/${slug}/SKILL.md`);
5673
6517
  wrapped.push(slug);
5674
6518
  }
5675
- return { wrapped, collisions, reserved };
6519
+ return { wrapped, collisions, reserved, foreign };
5676
6520
  }
5677
6521
  function _deploy_global_content(tools, force, package_root, lockfile_path2) {
5678
6522
  const results = {};
@@ -5699,8 +6543,8 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
5699
6543
  const written_paths = [];
5700
6544
  let current_files = /* @__PURE__ */ new Set();
5701
6545
  for (const [src_rel, dest_sub] of plan) {
5702
- const src = path12.join(package_root, src_rel);
5703
- const dest = dest_sub ? path12.join(anchor, dest_sub) : anchor;
6546
+ const src = path20.join(package_root, src_rel);
6547
+ const dest = dest_sub ? path20.join(anchor, dest_sub) : anchor;
5704
6548
  const rule_filter = _rule_filter_for_source(src_rel, rule_scope);
5705
6549
  const [w, s, paths] = _copy_dir_dereferencing_symlinks(
5706
6550
  src,
@@ -5722,15 +6566,31 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
5722
6566
  );
5723
6567
  }
5724
6568
  if (tool_id === "claude-code") {
5725
- const res = _apply_claude_flat_command_wrappers(anchor, package_root, current_files);
6569
+ const res = _apply_claude_flat_command_wrappers(anchor, package_root, current_files, recorded_rel_files(tool_id, anchor));
6570
+ const preserved_now = new Set(
6571
+ tracker.conflictState.preserved.map((p) => path20.resolve(p))
6572
+ );
5726
6573
  rewriteAndReport(
5727
- path12.join(anchor, "rules"),
6574
+ path20.join(anchor, "rules"),
5728
6575
  state.QUIET,
5729
6576
  info,
5730
6577
  warn,
5731
6578
  res,
5732
- new Set(tracker.conflictState.preserved.map((p) => path12.resolve(p)))
6579
+ preserved_now
5733
6580
  );
6581
+ if (installerThinsHost(tool_id, { packageRoot: package_root })) {
6582
+ try {
6583
+ const thin = thinInstalledRuleLayer({
6584
+ rulesDir: path20.join(anchor, "rules"),
6585
+ packageRoot: package_root,
6586
+ preserved: preserved_now
6587
+ });
6588
+ if (!state.QUIET) for (const l of describeThinInstalledLayer(thin)) info(l);
6589
+ } catch (e) {
6590
+ warn(`claude-code: thinned rule layer not written \u2014 ${String(e)}`);
6591
+ }
6592
+ }
6593
+ if (!state.QUIET) for (const l of installReceiptBudgetLines(package_root)) info(l);
5734
6594
  }
5735
6595
  const missing_targets = _verify_deploy_targets(anchor, plan);
5736
6596
  if (missing_targets.length > 0) {
@@ -5772,10 +6632,10 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
5772
6632
  results[tool_id] = [written_total, skipped_total, "deployed", written_paths];
5773
6633
  if (tool_id === "claude-code") {
5774
6634
  try {
5775
- const manifest = path12.join(package_root, "src", "scripts", "hook_manifest.yaml");
6635
+ const manifest = path20.join(package_root, "src", "scripts", "hook_manifest.yaml");
5776
6636
  const matrix = build_claude_hook_matrix(manifest);
5777
6637
  const res = ensure_managed_hooks(
5778
- path12.join(anchor, "settings.json"),
6638
+ path20.join(anchor, "settings.json"),
5779
6639
  matrix
5780
6640
  );
5781
6641
  if (!state.QUIET) {
@@ -5812,7 +6672,7 @@ function _preview_global_reap(tools, package_root) {
5812
6672
  const anchor = expanduser3(anchor_raw);
5813
6673
  let current_files = /* @__PURE__ */ new Set();
5814
6674
  for (const [src_rel, dest_sub] of plan) {
5815
- const src = path12.join(package_root, src_rel);
6675
+ const src = path20.join(package_root, src_rel);
5816
6676
  current_files = setUnion(
5817
6677
  current_files,
5818
6678
  expected_deploy_files(
@@ -5846,14 +6706,14 @@ function _preview_global_reap(tools, package_root) {
5846
6706
  function _verify_deploy_targets(anchor, plan) {
5847
6707
  const missing = [];
5848
6708
  for (const [, dest_sub] of plan) {
5849
- const target = dest_sub ? path12.join(anchor, dest_sub) : anchor;
6709
+ const target = dest_sub ? path20.join(anchor, dest_sub) : anchor;
5850
6710
  const label = dest_sub || ".";
5851
6711
  if (!isDir(target)) {
5852
6712
  missing.push(label);
5853
6713
  continue;
5854
6714
  }
5855
6715
  try {
5856
- const entries = fs14.readdirSync(target);
6716
+ const entries = fs20.readdirSync(target);
5857
6717
  if (entries.length === 0) missing.push(label);
5858
6718
  } catch {
5859
6719
  missing.push(label);
@@ -5871,54 +6731,30 @@ function _resolve_global_settings_doc() {
5871
6731
  }
5872
6732
  function _resolve_global_settings_path() {
5873
6733
  const root = event4u_root();
5874
- const canonical = path12.join(root, "settings", SETTINGS_FILE);
6734
+ const canonical = path20.join(root, "settings", SETTINGS_FILE);
5875
6735
  if (pathExists(canonical)) return canonical;
5876
- const legacy = path12.join(root, SETTINGS_FILE);
6736
+ const legacy = path20.join(root, SETTINGS_FILE);
5877
6737
  if (pathExists(legacy)) return legacy;
5878
6738
  return null;
5879
6739
  }
5880
6740
  function _resolve_scoped_projection(package_root) {
5881
6741
  const doc = _resolve_global_settings_doc() ?? _load_default_settings(package_root);
5882
- const projection = _isPlainObject(doc["projection"]) ? doc["projection"] : {};
6742
+ const projection = isPlainObject(doc["projection"]) ? doc["projection"] : {};
5883
6743
  const mode = projectionModeOf(projection["mode"]);
5884
- const runtime = _isPlainObject(doc["runtime"]) ? doc["runtime"] : {};
6744
+ const runtime = isPlainObject(doc["runtime"]) ? doc["runtime"] : {};
5885
6745
  const active_packs_raw = runtime["active_packs"];
5886
6746
  const active_packs = Array.isArray(active_packs_raw) ? active_packs_raw.filter((v) => typeof v === "string") : [];
5887
6747
  return { mode, active_packs };
5888
6748
  }
5889
6749
  function _resolve_global_rule_scope(package_root) {
5890
- const settings_path = _resolve_global_settings_path();
5891
- if (settings_path === null) {
5892
- try {
5893
- return ruleScopeFromSettings(_load_default_settings(package_root), package_root);
5894
- } catch {
5895
- return LEGACY_ALL;
5896
- }
5897
- }
5898
- let text;
5899
- try {
5900
- text = readText(settings_path);
5901
- } catch (e) {
5902
- warn(
5903
- `could not read ${settings_path} (${String(e)}) \u2014 rule scoping falls back to legacy-all, so ALL rules including maintainer-only ones will be installed. Fix the file to restore scoping.`
5904
- );
5905
- return LEGACY_ALL;
5906
- }
5907
- const parsed = yamlSafeLoad(text);
5908
- if (!_isPlainObject(parsed)) {
5909
- warn(
5910
- `${settings_path} is not a YAML mapping \u2014 rule scoping falls back to legacy-all, so ALL rules including maintainer-only ones will be installed. Fix the file to restore scoping.`
5911
- );
5912
- return LEGACY_ALL;
5913
- }
5914
- try {
5915
- return ruleScopeFromSettings(parsed, package_root);
5916
- } catch (e) {
5917
- warn(
5918
- `could not derive rule scope from ${settings_path} (${String(e)}) \u2014 falling back to legacy-all; ALL rules will be installed.`
5919
- );
5920
- return LEGACY_ALL;
5921
- }
6750
+ return resolveGlobalRuleScope({
6751
+ settingsPath: _resolve_global_settings_path(),
6752
+ packageRoot: package_root,
6753
+ readText,
6754
+ parseYaml: yamlSafeLoad,
6755
+ loadDefaults: () => _load_default_settings(package_root),
6756
+ warn
6757
+ });
5922
6758
  }
5923
6759
  function _rule_filter_for_source(src_rel, scope) {
5924
6760
  if (src_rel !== RULE_SOURCE_REL) return null;
@@ -5984,7 +6820,7 @@ function install_global(tools, force, project_root = null, core_only = false) {
5984
6820
  info(` schema_version=1, agent_config_version=${installed_version}`);
5985
6821
  info(` tools=${merged_tools.join(",")}`);
5986
6822
  }
5987
- if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path12.join(project_root, ".agent-src.uncondensed"))) {
6823
+ if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path20.join(project_root, ".agent-src.uncondensed"))) {
5988
6824
  const drift = collect_drift(project_root);
5989
6825
  if (!state.QUIET) {
5990
6826
  process2.stdout.write("\n");
@@ -6098,19 +6934,19 @@ function install_global(tools, force, project_root = null, core_only = false) {
6098
6934
  }
6099
6935
  }
6100
6936
  }
6101
- if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path12.join(project_root, ".agent-src.uncondensed"))) {
6937
+ if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path20.join(project_root, ".agent-src.uncondensed"))) {
6102
6938
  const files_by_tool = filesByToolFromDeploy(deploy_results);
6103
6939
  const rc = _update_installed_tools_manifest(project_root, tools, "global", force, files_by_tool);
6104
6940
  if (rc !== 0) return rc;
6105
6941
  const removed_marker = _remove_legacy_consumer_bridge_marker(project_root);
6106
6942
  if (removed_marker !== null && !state.QUIET) {
6107
- const rel = isRelativeTo(removed_marker, project_root) ? path12.relative(project_root, removed_marker) : removed_marker;
6943
+ const rel = isRelativeTo(removed_marker, project_root) ? path20.relative(project_root, removed_marker) : removed_marker;
6108
6944
  info(`Removed legacy bridge marker: ${rel}`);
6109
6945
  }
6110
6946
  const anchor_paths = _write_per_tool_project_anchors(project_root, tools);
6111
6947
  if (anchor_paths.length > 0 && !state.QUIET) {
6112
6948
  for (const p of anchor_paths) {
6113
- const rel = isRelativeTo(p, project_root) ? path12.relative(project_root, p) : p;
6949
+ const rel = isRelativeTo(p, project_root) ? path20.relative(project_root, p) : p;
6114
6950
  info(`Project anchor written: ${rel}`);
6115
6951
  }
6116
6952
  }
@@ -6146,8 +6982,8 @@ function install_global(tools, force, project_root = null, core_only = false) {
6146
6982
  }
6147
6983
  function _catalogue_truncation_warnings(deploy_results, project_root) {
6148
6984
  const log_candidates = [
6149
- path12.join(event4u_root(), "state", "skill-catalogue.jsonl"),
6150
- ...project_root ? [path12.join(project_root, OBSERVATION_LOG)] : []
6985
+ path20.join(event4u_root(), "state", "skill-catalogue.jsonl"),
6986
+ ...project_root ? [path20.join(project_root, OBSERVATION_LOG)] : []
6151
6987
  ];
6152
6988
  const records = log_candidates.flatMap((p) => readObservationLog(p));
6153
6989
  if (records.length === 0) return [];
@@ -6170,13 +7006,13 @@ function _catalogue_truncation_warnings(deploy_results, project_root) {
6170
7006
  function _scoped_migration_notice(deploy_results, project_root, package_root, probe) {
6171
7007
  if (!isInteractiveSession(probe)) return [];
6172
7008
  const log_candidates = [
6173
- path12.join(event4u_root(), "state", "skill-catalogue.jsonl"),
6174
- ...project_root ? [path12.join(project_root, OBSERVATION_LOG)] : []
7009
+ path20.join(event4u_root(), "state", "skill-catalogue.jsonl"),
7010
+ ...project_root ? [path20.join(project_root, OBSERVATION_LOG)] : []
6175
7011
  ];
6176
7012
  const limits = knownHostLimits(log_candidates.flatMap((p) => readObservationLog(p)));
6177
7013
  if (limits.size === 0) return [];
6178
7014
  const resolved = _resolve_scoped_projection(package_root);
6179
- const settings_path = _resolve_global_settings_path() ?? path12.join(event4u_root(), "settings", SETTINGS_FILE);
7015
+ const settings_path = _resolve_global_settings_path() ?? path20.join(event4u_root(), "settings", SETTINGS_FILE);
6180
7016
  for (const tool_id of Object.keys(deploy_results).sort()) {
6181
7017
  const [, , status] = deploy_results[tool_id];
6182
7018
  if (status !== "deployed") continue;
@@ -6195,8 +7031,8 @@ function _scoped_migration_notice(deploy_results, project_root, package_root, pr
6195
7031
  }
6196
7032
  return [];
6197
7033
  }
6198
- var SETTINGS_SURFACE_REL = path12.join("state", "settings-surface.json");
6199
- var SETTINGS_DELTA_REL = path12.join("state", "settings-delta.json");
7034
+ var SETTINGS_SURFACE_REL = path20.join("state", "settings-surface.json");
7035
+ var SETTINGS_DELTA_REL = path20.join("state", "settings-delta.json");
6200
7036
  function _current_settings_surface(version) {
6201
7037
  const jsonSchema = zodToJsonSchema(settingsSchema, {
6202
7038
  name: "AgentSettings",
@@ -6207,20 +7043,20 @@ function _current_settings_surface(version) {
6207
7043
  }
6208
7044
  function _write_settings_surface_snapshot(installed_version) {
6209
7045
  const root = event4u_root();
6210
- const surface_path = path12.join(root, SETTINGS_SURFACE_REL);
6211
- const delta_path = path12.join(root, SETTINGS_DELTA_REL);
7046
+ const surface_path = path20.join(root, SETTINGS_SURFACE_REL);
7047
+ const delta_path = path20.join(root, SETTINGS_DELTA_REL);
6212
7048
  const next = _current_settings_surface(installed_version);
6213
7049
  let previous = null;
6214
7050
  try {
6215
- const parsed = JSON.parse(fs14.readFileSync(surface_path, "utf8"));
7051
+ const parsed = JSON.parse(fs20.readFileSync(surface_path, "utf8"));
6216
7052
  if (parsed !== null && typeof parsed === "object" && parsed.entries !== void 0) previous = parsed;
6217
7053
  } catch {
6218
7054
  }
6219
7055
  if (previous !== null && previous.version !== next.version) {
6220
7056
  const delta = computeSurfaceDelta(previous, next);
6221
7057
  if (delta.changes.length > 0) {
6222
- fs14.mkdirSync(path12.dirname(delta_path), { recursive: true, mode: 448 });
6223
- fs14.writeFileSync(delta_path, `${JSON.stringify(delta, null, 2)}
7058
+ fs20.mkdirSync(path20.dirname(delta_path), { recursive: true, mode: 448 });
7059
+ fs20.writeFileSync(delta_path, `${JSON.stringify(delta, null, 2)}
6224
7060
  `, { mode: 384 });
6225
7061
  if (!state.QUIET) {
6226
7062
  const counts = {};
@@ -6232,8 +7068,8 @@ function _write_settings_surface_snapshot(installed_version) {
6232
7068
  }
6233
7069
  }
6234
7070
  }
6235
- fs14.mkdirSync(path12.dirname(surface_path), { recursive: true, mode: 448 });
6236
- fs14.writeFileSync(surface_path, `${JSON.stringify(next, null, 2)}
7071
+ fs20.mkdirSync(path20.dirname(surface_path), { recursive: true, mode: 448 });
7072
+ fs20.writeFileSync(surface_path, `${JSON.stringify(next, null, 2)}
6237
7073
  `, { mode: 384 });
6238
7074
  }
6239
7075
  function arrayStrEqual(a, b) {
@@ -6449,17 +7285,17 @@ function _is_tool_enabled(tools, tool_id) {
6449
7285
  return tools.has(tool_id);
6450
7286
  }
6451
7287
  function _minimal_templates_root() {
6452
- const start = resolvePath(_HERE);
7288
+ const start = resolvePath(_HERE2);
6453
7289
  const chain = [start];
6454
7290
  let cur = start;
6455
7291
  for (; ; ) {
6456
- const parent = path12.dirname(cur);
7292
+ const parent = path20.dirname(cur);
6457
7293
  if (parent === cur) break;
6458
7294
  chain.push(parent);
6459
7295
  cur = parent;
6460
7296
  }
6461
7297
  for (const ancestor of chain) {
6462
- const candidate = path12.join(ancestor, "src", "templates", "minimal");
7298
+ const candidate = path20.join(ancestor, "src", "templates", "minimal");
6463
7299
  if (isDir(candidate)) return candidate;
6464
7300
  }
6465
7301
  fail("Could not locate src/templates/minimal/ \u2014 package install is corrupt.");
@@ -6467,9 +7303,9 @@ function _minimal_templates_root() {
6467
7303
  var INSTALL_MODE_MARKER_REL = "agents/.agent-state/install-mode.txt";
6468
7304
  function _write_install_mode_marker(project_root, mode) {
6469
7305
  if (mode !== "minimal" && mode !== "full") return;
6470
- const marker = path12.join(project_root, INSTALL_MODE_MARKER_REL);
7306
+ const marker = path20.join(project_root, INSTALL_MODE_MARKER_REL);
6471
7307
  try {
6472
- mkdirp(path12.dirname(marker));
7308
+ mkdirp(path20.dirname(marker));
6473
7309
  writeText(marker, `${mode}
6474
7310
  `);
6475
7311
  } catch {
@@ -6478,7 +7314,7 @@ function _write_install_mode_marker(project_root, mode) {
6478
7314
  function install_minimal(target_root_in, force, user_type = "") {
6479
7315
  let target_root = resolvePath(target_root_in);
6480
7316
  mkdirp(target_root);
6481
- const parent = path12.dirname(target_root);
7317
+ const parent = path20.dirname(target_root);
6482
7318
  if (parent !== target_root) {
6483
7319
  const existing = find_project_root_with_anchor(parent);
6484
7320
  if (existing !== null && existing[0] !== target_root) {
@@ -6489,21 +7325,21 @@ function install_minimal(target_root_in, force, user_type = "") {
6489
7325
  }
6490
7326
  }
6491
7327
  const templates = _minimal_templates_root();
6492
- const settings_src = path12.join(templates, SETTINGS_FILE);
6493
- const overrides_gitkeep_src = path12.join(templates, "overrides-gitkeep");
6494
- const overrides_readme_src = path12.join(templates, "agents-overrides-readme.md");
7328
+ const settings_src = path20.join(templates, SETTINGS_FILE);
7329
+ const overrides_gitkeep_src = path20.join(templates, "overrides-gitkeep");
7330
+ const overrides_readme_src = path20.join(templates, "agents-overrides-readme.md");
6495
7331
  if (!isFile(settings_src)) fail(`Bundled minimal settings template missing under ${templates}`);
6496
7332
  if (!isFile(overrides_gitkeep_src) || !isFile(overrides_readme_src)) {
6497
7333
  fail(`Bundled overrides scaffold templates missing under ${templates}`);
6498
7334
  }
6499
7335
  info(`Minimal init \u2192 ${target_root}`);
6500
- const overrides_root = path12.join(target_root, "agents", "overrides");
7336
+ const overrides_root = path20.join(target_root, "agents", "overrides");
6501
7337
  mkdirp(overrides_root);
6502
7338
  const gitkeep_body = readText(overrides_gitkeep_src);
6503
7339
  for (const sub of ["rules", "skills", "commands"]) {
6504
- const sub_dir = path12.join(overrides_root, sub);
7340
+ const sub_dir = path20.join(overrides_root, sub);
6505
7341
  mkdirp(sub_dir);
6506
- const gitkeep_dst = path12.join(sub_dir, ".gitkeep");
7342
+ const gitkeep_dst = path20.join(sub_dir, ".gitkeep");
6507
7343
  if (pathExists(gitkeep_dst) && !force) {
6508
7344
  skip(`agents/overrides/${sub}/.gitkeep already exists (use --force to overwrite)`);
6509
7345
  } else {
@@ -6511,7 +7347,7 @@ function install_minimal(target_root_in, force, user_type = "") {
6511
7347
  success(`Wrote agents/overrides/${sub}/.gitkeep`);
6512
7348
  }
6513
7349
  }
6514
- const readme_dst = path12.join(overrides_root, "README.md");
7350
+ const readme_dst = path20.join(overrides_root, "README.md");
6515
7351
  if (pathExists(readme_dst) && !force) {
6516
7352
  skip("agents/overrides/README.md already exists (use --force to overwrite)");
6517
7353
  } else {
@@ -6529,14 +7365,14 @@ function install_minimal(target_root_in, force, user_type = "") {
6529
7365
  personal:
6530
7366
  user_type: ${user_type}
6531
7367
  `;
6532
- mkdirp(path12.dirname(settings_dst));
7368
+ mkdirp(path20.dirname(settings_dst));
6533
7369
  writeText(settings_dst, body);
6534
7370
  success(`Wrote ${SETTINGS_FILE} (user_type=${user_type})`);
6535
7371
  }
6536
7372
  }
6537
7373
  const removed_marker = _remove_legacy_consumer_bridge_marker(target_root);
6538
7374
  if (removed_marker !== null) {
6539
- const rel = isRelativeTo(removed_marker, target_root) ? path12.relative(target_root, removed_marker) : removed_marker;
7375
+ const rel = isRelativeTo(removed_marker, target_root) ? path20.relative(target_root, removed_marker) : removed_marker;
6540
7376
  success(`Removed legacy bridge marker: ${rel}`);
6541
7377
  }
6542
7378
  _write_install_mode_marker(target_root, "minimal");
@@ -6610,7 +7446,7 @@ function run_interactive_init(project_root, force) {
6610
7446
  );
6611
7447
  return 0;
6612
7448
  }
6613
- const target = path12.join(project_root, _LOCAL_CONFIG_FILE);
7449
+ const target = path20.join(project_root, _LOCAL_CONFIG_FILE);
6614
7450
  if (pathExists(target) && !force) {
6615
7451
  warn(
6616
7452
  `${_LOCAL_CONFIG_FILE} already exists; re-run with --force to overwrite. Skipping interactive init.`
@@ -6637,7 +7473,7 @@ function run_interactive_init(project_root, force) {
6637
7473
  warn(`Could not write ${target}: ${String(exc)}`);
6638
7474
  return 1;
6639
7475
  }
6640
- success(`Wrote ${path12.relative(project_root, target)} (${user_type} / ${stack} / ${verbosity})`);
7476
+ success(`Wrote ${path20.relative(project_root, target)} (${user_type} / ${stack} / ${verbosity})`);
6641
7477
  return 0;
6642
7478
  }
6643
7479
  var _WIZARD_READY_RE = /^WIZARD_READY (http:\/\/(?:127\.0\.0\.1|localhost):\d+\/\S*)\r?$/;
@@ -6655,12 +7491,12 @@ function _wizard_should_launch(opts) {
6655
7491
  return [true, ""];
6656
7492
  }
6657
7493
  function _wizard_cli_dist(_project_root) {
6658
- const package_root = path12.dirname(path12.dirname(path12.dirname(resolvePath(_HERE))));
6659
- const cli = path12.join(package_root, "dist", "cli", "agent-config.js");
7494
+ const package_root = path20.dirname(path20.dirname(path20.dirname(resolvePath(_HERE2))));
7495
+ const cli = path20.join(package_root, "dist", "cli", "agent-config.js");
6660
7496
  return pathExists(cli) ? cli : null;
6661
7497
  }
6662
7498
  function _server_info_path() {
6663
- return path12.join(os3.homedir(), ".event4u", "agent-config", "local-server.json");
7499
+ return path20.join(os6.homedir(), ".event4u", "agent-config", "local-server.json");
6664
7500
  }
6665
7501
  function _pid_is_agent_config(pid) {
6666
7502
  let res;
@@ -6677,7 +7513,7 @@ function _pid_is_agent_config(pid) {
6677
7513
  }
6678
7514
  function unlinkMissingOk(p) {
6679
7515
  try {
6680
- fs14.unlinkSync(p);
7516
+ fs20.unlinkSync(p);
6681
7517
  } catch {
6682
7518
  }
6683
7519
  }
@@ -6755,14 +7591,14 @@ function _wizard_spawn(project_root, pass_project_root = true) {
6755
7591
  }
6756
7592
  function _wizard_run_sync(cmd, env, cli) {
6757
7593
  const total = _WIZARD_TIMEOUTS.reduce((a, b) => a + b, 0);
6758
- const log_path = path12.join(
6759
- os3.tmpdir(),
7594
+ const log_path = path20.join(
7595
+ os6.tmpdir(),
6760
7596
  `agent-config-wizard-${process2.pid}-${Date.now()}.log`
6761
7597
  );
6762
7598
  let child;
6763
7599
  let log_fd = null;
6764
7600
  try {
6765
- log_fd = fs14.openSync(log_path, "w");
7601
+ log_fd = fs20.openSync(log_path, "w");
6766
7602
  child = spawn(cmd[0], cmd.slice(1), {
6767
7603
  env,
6768
7604
  detached: true,
@@ -6780,7 +7616,7 @@ function _wizard_run_sync(cmd, env, cli) {
6780
7616
  } finally {
6781
7617
  if (log_fd !== null) {
6782
7618
  try {
6783
- fs14.closeSync(log_fd);
7619
+ fs20.closeSync(log_fd);
6784
7620
  } catch {
6785
7621
  }
6786
7622
  }
@@ -6957,7 +7793,7 @@ function main2(argv) {
6957
7793
  } catch (exc) {
6958
7794
  fail(`--apply-payload JSON parse error: ${String(exc)}`);
6959
7795
  }
6960
- if (!_isPlainObject(payload)) fail("--apply-payload root must be a JSON object");
7796
+ if (!isPlainObject(payload)) fail("--apply-payload root must be a JSON object");
6961
7797
  const pl = payload;
6962
7798
  const schema_version = pl["schema_version"];
6963
7799
  if (schema_version !== "wizard-v2" && schema_version !== "installer-v1") {
@@ -6976,13 +7812,13 @@ function main2(argv) {
6976
7812
  opts.scope = "global";
6977
7813
  }
6978
7814
  const settings = pl["settings"];
6979
- if (_isPlainObject(settings)) {
7815
+ if (isPlainObject(settings)) {
6980
7816
  const rule_loading_tier = settings["rule_loading_tier"] || settings["cost_profile"];
6981
7817
  if (typeof rule_loading_tier === "string" && rule_loading_tier) {
6982
7818
  opts.profile = rule_loading_tier;
6983
7819
  }
6984
7820
  const personal = settings["personal"];
6985
- if (_isPlainObject(personal)) {
7821
+ if (isPlainObject(personal)) {
6986
7822
  const user_type = personal["user_type"];
6987
7823
  if (typeof user_type === "string" && user_type) {
6988
7824
  opts.user_type = user_type;
@@ -7030,8 +7866,8 @@ function main2(argv) {
7030
7866
  const target_root = resolvePath(
7031
7867
  opts.custom_path || opts.project || process2.env["PROJECT_ROOT"] || process2.cwd()
7032
7868
  );
7033
- const minimal_package_root = path12.dirname(
7034
- path12.dirname(path12.dirname(_minimal_templates_root()))
7869
+ const minimal_package_root = path20.dirname(
7870
+ path20.dirname(path20.dirname(_minimal_templates_root()))
7035
7871
  );
7036
7872
  const validated_user_type = _validate_user_type(minimal_package_root, opts.user_type);
7037
7873
  return install_minimal(target_root, opts.force, validated_user_type);
@@ -7067,7 +7903,7 @@ function main2(argv) {
7067
7903
  return rc2;
7068
7904
  }
7069
7905
  const project_root = custom_path || resolvePath(opts.project || process2.env["PROJECT_ROOT"] || process2.cwd());
7070
- const is_first_run = !pathExists(path12.join(project_root, SETTINGS_FILE));
7906
+ const is_first_run = !pathExists(path20.join(project_root, SETTINGS_FILE));
7071
7907
  tracker.begin(project_root);
7072
7908
  let rc = _main_project_install(opts, project_root, parsed_tools, is_first_run);
7073
7909
  if (rc === 0 && opts.interactive) {
@@ -7112,8 +7948,8 @@ function _read_consumer_auto_switch(project_root) {
7112
7948
  } catch {
7113
7949
  return "suggest";
7114
7950
  }
7115
- const model = _isPlainObject(data) ? data["model"] : null;
7116
- const value = _isPlainObject(model) ? model["auto_switch"] : null;
7951
+ const model = isPlainObject(data) ? data["model"] : null;
7952
+ const value = isPlainObject(model) ? model["auto_switch"] : null;
7117
7953
  if (typeof value === "string" && ["auto", "suggest", "off"].includes(value.trim().toLowerCase())) {
7118
7954
  return value.trim().toLowerCase();
7119
7955
  }
@@ -7126,23 +7962,23 @@ function _team_setup_hint_line(project_root) {
7126
7962
  } catch {
7127
7963
  data = {};
7128
7964
  }
7129
- const ai_team = _isPlainObject(data) ? data["ai_team"] : null;
7130
- const flag = _isPlainObject(ai_team) ? ai_team["suppress_setup_hint"] : null;
7965
+ const ai_team = isPlainObject(data) ? data["ai_team"] : null;
7966
+ const flag = isPlainObject(ai_team) ? ai_team["suppress_setup_hint"] : null;
7131
7967
  const suppressed = flag === true || typeof flag === "string" && ["true", "yes", "on", "1"].includes(flag.trim().toLowerCase());
7132
7968
  if (suppressed) return null;
7133
7969
  return " \u2022 Claude Code team mode (optional cross-model review via the official codex plugin): run `agent-config doctor --check team` for setup status.";
7134
7970
  }
7135
7971
  function finalize_claude_model_tiers(project_root) {
7136
- const claude_skills = path12.join(project_root, ".claude", "skills");
7137
- const augment_skills = path12.join(project_root, ".augment", "skills");
7972
+ const claude_skills = path20.join(project_root, ".claude", "skills");
7973
+ const augment_skills = path20.join(project_root, ".augment", "skills");
7138
7974
  if (!isDir(claude_skills) || !isDir(augment_skills)) return 0;
7139
7975
  if (_read_consumer_auto_switch(project_root) !== "auto") return 0;
7140
7976
  let rendered = 0;
7141
- const entries = fs14.readdirSync(claude_skills).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
7977
+ const entries = fs20.readdirSync(claude_skills).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
7142
7978
  for (const name of entries) {
7143
- const entry = path12.join(claude_skills, name);
7144
- const src_dir = path12.join(augment_skills, name);
7145
- const src_md = path12.join(src_dir, "SKILL.md");
7979
+ const entry = path20.join(claude_skills, name);
7980
+ const src_dir = path20.join(augment_skills, name);
7981
+ const src_md = path20.join(src_dir, "SKILL.md");
7146
7982
  let tier;
7147
7983
  try {
7148
7984
  tier = read_model_tier(src_md);
@@ -7151,22 +7987,22 @@ function finalize_claude_model_tiers(project_root) {
7151
7987
  }
7152
7988
  if (tier === null || !(tier in TIER_TO_CLAUDE_MODEL) || !isDir(src_dir)) continue;
7153
7989
  if (isSymlink(entry) || isFile(entry)) {
7154
- fs14.unlinkSync(entry);
7990
+ fs20.unlinkSync(entry);
7155
7991
  } else if (isDir(entry)) {
7156
- fs14.rmSync(entry, { recursive: true, force: true });
7992
+ fs20.rmSync(entry, { recursive: true, force: true });
7157
7993
  }
7158
7994
  mkdirp(entry);
7159
- const srcFiles = fs14.readdirSync(src_dir).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
7995
+ const srcFiles = fs20.readdirSync(src_dir).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
7160
7996
  for (const fname of srcFiles) {
7161
7997
  if (fname === "SKILL.md") {
7162
7998
  writeText(
7163
- path12.join(entry, "SKILL.md"),
7999
+ path20.join(entry, "SKILL.md"),
7164
8000
  render_native_model_md(readText(src_md), tier)
7165
8001
  );
7166
8002
  } else {
7167
- fs14.symlinkSync(
7168
- path12.join("../../../.augment/skills", name, fname),
7169
- path12.join(entry, fname)
8003
+ fs20.symlinkSync(
8004
+ path20.join("../../../.augment/skills", name, fname),
8005
+ path20.join(entry, fname)
7170
8006
  );
7171
8007
  }
7172
8008
  }
@@ -7184,7 +8020,7 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
7184
8020
  let package_type;
7185
8021
  if (opts.package) {
7186
8022
  package_root = resolvePath(opts.package);
7187
- if (!pathExists(path12.join(package_root, "src", "config", "profiles", "minimal.ini"))) {
8023
+ if (!pathExists(path20.join(package_root, "src", "config", "profiles", "minimal.ini"))) {
7188
8024
  fail(`Invalid --package path (missing src/config/profiles/minimal.ini): ${package_root}`);
7189
8025
  }
7190
8026
  package_type = detect_package_type_for_project(project_root, package_root);
@@ -7322,19 +8158,21 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
7322
8158
  if (will_launch) {
7323
8159
  return _wizard_spawn(project_root);
7324
8160
  }
8161
+ const ign = write_managed_block(project_root, opts.dry_run);
8162
+ if (ign > 0) success(`.gitignore: ${opts.dry_run ? "would add " : "+"}${ign} managed entries`);
7325
8163
  return 0;
7326
8164
  }
7327
8165
  function _resolvedArgv1() {
7328
8166
  if (process2.argv[1] === void 0) return void 0;
7329
8167
  try {
7330
- return fs14.realpathSync(path12.resolve(process2.argv[1]));
8168
+ return fs20.realpathSync(path20.resolve(process2.argv[1]));
7331
8169
  } catch {
7332
- return path12.resolve(process2.argv[1]);
8170
+ return path20.resolve(process2.argv[1]);
7333
8171
  }
7334
8172
  }
7335
8173
  var _argv1 = _resolvedArgv1();
7336
8174
  var _isCliEntry = _argv1 !== void 0 && import.meta.url === pathToFileURL(_argv1).href;
7337
- if (_isCliEntry || _argv1 === _HERE) {
8175
+ if (_isCliEntry || _argv1 === _HERE2) {
7338
8176
  try {
7339
8177
  process2.exitCode = main2(process2.argv.slice(2));
7340
8178
  } catch (e) {