@event4u/agent-config 16.2.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 (332) 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 +89 -237
  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 +4 -4
  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/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  23. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  24. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +6 -6
  25. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +32 -2
  26. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  27. package/dist/agent-src/contexts/execution/toolchain-resolver.md +101 -7
  28. package/dist/agent-src/rules/active-remediation.md +1 -1
  29. package/dist/agent-src/rules/autonomous-execution.md +1 -0
  30. package/dist/agent-src/rules/broken-access-control.md +1 -0
  31. package/dist/agent-src/rules/command-suggestion-policy.md +1 -0
  32. package/dist/agent-src/rules/context-hygiene.md +1 -1
  33. package/dist/agent-src/rules/decision-revisit-gate.md +16 -33
  34. package/dist/agent-src/rules/design-fidelity.md +13 -16
  35. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -0
  36. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -0
  37. package/dist/agent-src/rules/domain-safety-pii.md +1 -0
  38. package/dist/agent-src/rules/domain-safety-retention.md +1 -0
  39. package/dist/agent-src/rules/engineering-safety-floor.md +1 -0
  40. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  41. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
  42. package/dist/agent-src/rules/finance-safety-floor.md +1 -0
  43. package/dist/agent-src/rules/git-history-discipline.md +1 -0
  44. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
  45. package/dist/agent-src/rules/legal-safety-floor.md +3 -2
  46. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
  47. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
  48. package/dist/agent-src/rules/media-governance-routing.md +14 -17
  49. package/dist/agent-src/rules/persona-governance.md +2 -2
  50. package/dist/agent-src/rules/provider-lifecycle-discipline.md +1 -1
  51. package/dist/agent-src/rules/question-not-instruction.md +1 -0
  52. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  53. package/dist/agent-src/rules/runtime-safety.md +1 -0
  54. package/dist/agent-src/rules/secret-vcs-guard.md +1 -0
  55. package/dist/agent-src/rules/security-sensitive-stop.md +3 -2
  56. package/dist/agent-src/rules/session-canary.md +8 -62
  57. package/dist/agent-src/rules/settings-ask-protocol.md +1 -0
  58. package/dist/agent-src/rules/source-confidentiality.md +1 -0
  59. package/dist/agent-src/rules/strategy-safety-floor.md +1 -0
  60. package/dist/agent-src/rules/tool-safety.md +1 -0
  61. package/dist/agent-src/rules/untrusted-input-defense.md +1 -0
  62. package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
  63. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  64. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  65. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  66. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  67. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  68. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  69. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  70. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
  71. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  72. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  73. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  74. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  75. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  76. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  77. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  78. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  79. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
  80. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  81. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  82. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  83. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  84. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  85. package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
  86. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  87. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  88. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  89. package/dist/cli/registry.js +1 -1
  90. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  91. package/dist/cli-delegate/check_update_banner.js +12 -1
  92. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  93. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  94. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  95. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-CQWX336L.js} +1 -1
  96. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  97. package/dist/cli-delegate/chunk-EEHDXSYD.js +2040 -0
  98. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-GKE7ZVFA.js} +4 -4
  99. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  100. package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-JQVYKIZA.js} +10 -0
  101. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-JY2I2DXV.js} +12 -1
  102. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  103. package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
  104. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-LIYTLH6O.js} +1 -1
  105. package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-NQ7WT43P.js} +1186 -244
  106. package/dist/cli-delegate/chunk-NXEILF2K.js +2160 -0
  107. package/dist/cli-delegate/{chunk-5R7HOLAF.js → chunk-NYX3L2PZ.js} +1 -1
  108. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  109. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  110. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-QLDHIPWR.js} +1 -1
  111. package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-RQNNW7IF.js} +1314 -560
  112. package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-S4UMZNES.js} +1 -1
  113. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-S4YWNRKO.js} +24 -8
  114. package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-TRI6DQZ6.js} +2781 -340
  115. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  116. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  117. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  118. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  119. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  120. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  121. package/dist/cli-delegate/cmd_conformance.js +1167 -234
  122. package/dist/cli-delegate/cmd_doctor.js +13 -6
  123. package/dist/cli-delegate/cmd_doctor_neighbours.js +23 -0
  124. package/dist/cli-delegate/cmd_explain.js +5 -5
  125. package/dist/cli-delegate/cmd_export.js +11 -8
  126. package/dist/cli-delegate/cmd_fleet.js +3 -3
  127. package/dist/cli-delegate/cmd_handoff.js +10 -7
  128. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  129. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  130. package/dist/cli-delegate/cmd_migrate.js +2 -2
  131. package/dist/cli-delegate/cmd_packs_active.js +3 -3
  132. package/dist/cli-delegate/cmd_preflight.js +6 -6
  133. package/dist/cli-delegate/cmd_prune.js +11 -8
  134. package/dist/cli-delegate/cmd_refresh.js +2 -1
  135. package/dist/cli-delegate/cmd_route_audit.js +8 -6
  136. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  137. package/dist/cli-delegate/cmd_session_recycle.js +4 -3
  138. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  139. package/dist/cli-delegate/cmd_settings_migrate.js +11 -8
  140. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  141. package/dist/cli-delegate/cmd_sync.js +11 -8
  142. package/dist/cli-delegate/cmd_uninstall.js +11 -8
  143. package/dist/cli-delegate/cmd_update.js +1 -1
  144. package/dist/cli-delegate/cmd_upgrade.js +3 -2
  145. package/dist/cli-delegate/cmd_validate.js +11 -8
  146. package/dist/cli-delegate/cmd_versions.js +1 -1
  147. package/dist/cli-delegate/deferral_carry.js +16 -0
  148. package/dist/cli-delegate/gate_execute.js +2 -2
  149. package/dist/cli-delegate/roadmap_gates.js +5 -5
  150. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  151. package/dist/discovery/deprecation-report.md +1 -1
  152. package/dist/discovery/discovery-manifest.json +127 -75
  153. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  154. package/dist/discovery/discovery-manifest.summary.md +3 -3
  155. package/dist/discovery/dormancy-report.md +1 -1
  156. package/dist/discovery/orphan-report.md +1 -1
  157. package/dist/discovery/packs.json +7 -5
  158. package/dist/discovery/trust-report.md +2 -2
  159. package/dist/discovery/workspaces.json +6 -4
  160. package/dist/hooks/dispatch.js +5357 -6656
  161. package/dist/hooks/dispatch.sha256 +1 -1
  162. package/dist/install/claudePathsPlan.js +47 -6
  163. package/dist/install/claudeRuleRewrite.js +7 -0
  164. package/dist/install/emit_host_rules_cli.js +39 -36
  165. package/dist/install/globalRuleScope.js +87 -0
  166. package/dist/install/host_rule_ownership.js +160 -0
  167. package/dist/install/install.mjs +2080 -1024
  168. package/dist/install/installThinLayer.js +261 -0
  169. package/dist/install/installedRuleLinks.js +176 -0
  170. package/dist/install/wizard-plan.js +24 -0
  171. package/dist/mcp/registry-manifest.json +3 -3
  172. package/dist/mcp/server.json +2 -2
  173. package/dist/mcp/server.mjs +31965 -27154
  174. package/dist/scripts/_lib/agent_settings.js +11 -0
  175. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  176. package/dist/scripts/_lib/installed_layer.js +378 -0
  177. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  178. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  179. package/dist/scripts/_lib/rule_injection.js +67 -10
  180. package/dist/scripts/_lib/rule_law_section.js +122 -0
  181. package/dist/scripts/_lib/thin_rules.js +458 -0
  182. package/dist/scripts/_lib/windsurf_render.js +60 -0
  183. package/dist/scripts/condense.js +14 -26
  184. package/dist/scripts/project_thin_rules.js +14 -294
  185. package/dist/server/schemas/settings.js +6 -0
  186. package/dist/shared/skillRanking.js +74 -13
  187. package/docs/contracts/settings-classes.md +7 -5
  188. package/package.json +1 -1
  189. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  190. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  191. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  192. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  193. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  194. package/src/config/agent-settings.template.yml +62 -22
  195. package/src/config/continuity-surface.json +7 -0
  196. package/src/config/evaluator-budgets.json +4 -4
  197. package/src/config/gate-coverage.yml +96 -3
  198. package/src/config/gate-violation-baselines.json +17 -9
  199. package/src/config/hook-bundle-budget.json +25 -0
  200. package/src/config/hook-token-budget.json +6 -1
  201. package/src/config/host-instruction-limits.json +33 -0
  202. package/src/config/routing-coverage-seed.json +24 -3
  203. package/src/config/rule-activation-census.json +7 -3
  204. package/src/config/rule-consequence-class.json +161 -0
  205. package/src/config/rule-law-ceilings.json +99 -0
  206. package/src/install/claudePathsPlan.ts +46 -4
  207. package/src/install/claudeRuleRewrite.ts +10 -1
  208. package/src/install/emit_host_rules_cli.ts +43 -34
  209. package/src/install/globalRuleScope.ts +109 -0
  210. package/src/install/host_rule_ownership.ts +170 -0
  211. package/src/install/installThinLayer.ts +312 -0
  212. package/src/install/installedRuleLinks.ts +220 -0
  213. package/src/install/wizard-plan.ts +24 -0
  214. package/src/scripts/_cli/cmd_doctor.ts +23 -71
  215. package/src/scripts/_cli/cmd_doctor_neighbours.ts +293 -0
  216. package/src/scripts/_dispatch.bash +16 -2
  217. package/src/scripts/_lib/agent_settings.ts +11 -0
  218. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  219. package/src/scripts/_lib/estate_offsets.ts +241 -0
  220. package/src/scripts/_lib/exemption_shape.ts +143 -0
  221. package/src/scripts/_lib/fnv.ts +23 -0
  222. package/src/scripts/_lib/foreign_scan.ts +106 -0
  223. package/src/scripts/_lib/gitignore_block.ts +314 -0
  224. package/src/scripts/_lib/global_deploy_inventory.ts +32 -0
  225. package/src/scripts/_lib/graph_feeder_record.ts +214 -0
  226. package/src/scripts/_lib/hook_settings.ts +73 -0
  227. package/src/scripts/_lib/host_capability.ts +40 -19
  228. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  229. package/src/scripts/_lib/installed_layer.ts +538 -0
  230. package/src/scripts/_lib/json_merge.ts +82 -0
  231. package/src/scripts/_lib/json_pointers.ts +93 -11
  232. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  233. package/src/scripts/_lib/machine_wake.ts +16 -3
  234. package/src/scripts/_lib/neighbour_census.ts +760 -0
  235. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  236. package/src/scripts/_lib/neighbour_tool_use.ts +189 -0
  237. package/src/scripts/_lib/prompt_shape.ts +46 -0
  238. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  239. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  240. package/src/scripts/_lib/review_coverage.ts +134 -0
  241. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  242. package/src/scripts/_lib/rule_injection.ts +130 -10
  243. package/src/scripts/_lib/rule_law_section.ts +147 -0
  244. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  245. package/src/scripts/_lib/skill_origin.ts +254 -0
  246. package/src/scripts/_lib/structured_ask.ts +64 -21
  247. package/src/scripts/_lib/thin_rules.ts +540 -0
  248. package/src/scripts/_lib/touched_file_quality.ts +434 -0
  249. package/src/scripts/_lib/turn_end_refusals.ts +77 -2
  250. package/src/scripts/_lib/windsurf_render.ts +63 -0
  251. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  252. package/src/scripts/ai_council/clients.ts +26 -57
  253. package/src/scripts/ai_council/config.ts +1 -1
  254. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  255. package/src/scripts/audit_skill_overlap.ts +261 -0
  256. package/src/scripts/before_complete_hook.ts +243 -12
  257. package/src/scripts/bench_touched_file_quality.ts +238 -0
  258. package/src/scripts/check_enforcement_matrix.ts +377 -20
  259. package/src/scripts/check_estate_count.ts +130 -153
  260. package/src/scripts/check_finding_dispositions.ts +116 -4
  261. package/src/scripts/check_hook_bundle_composition.ts +370 -0
  262. package/src/scripts/check_kernel_edit_ratified.ts +49 -11
  263. package/src/scripts/check_memory.ts +7 -1
  264. package/src/scripts/check_release_highlights.ts +10 -0
  265. package/src/scripts/check_release_pr_shape.ts +38 -15
  266. package/src/scripts/check_standing_rule_delivery.ts +33 -13
  267. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  268. package/src/scripts/code_graph/detect.ts +127 -7
  269. package/src/scripts/code_graph/foreign.ts +194 -0
  270. package/src/scripts/code_graph/query.ts +217 -4
  271. package/src/scripts/code_graph/types.ts +26 -2
  272. package/src/scripts/code_graph/validate.ts +3 -1
  273. package/src/scripts/code_graph/verbs.ts +103 -0
  274. package/src/scripts/compile_hook_manifest.ts +33 -1
  275. package/src/scripts/condense.ts +14 -27
  276. package/src/scripts/estate_exemption_shape.ts +202 -0
  277. package/src/scripts/generate_host_cost_table.ts +1 -1
  278. package/src/scripts/hook_manifest.json +1 -1
  279. package/src/scripts/hook_manifest.yaml +150 -9
  280. package/src/scripts/hooks/block_config_weakening.ts +67 -2
  281. package/src/scripts/hooks/block_plumbing_writes.ts +29 -1
  282. package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
  283. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  284. package/src/scripts/hooks/dispatch_hook.ts +52 -52
  285. package/src/scripts/hooks/exit_codes.ts +2 -1
  286. package/src/scripts/hooks/host_lowering.json +1 -1
  287. package/src/scripts/hooks/host_lowering.ts +19 -1
  288. package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
  289. package/src/scripts/hooks/payload_stub.ts +10 -1
  290. package/src/scripts/hooks/rule_inject_hook.ts +757 -63
  291. package/src/scripts/hooks/table_fingerprint.ts +21 -0
  292. package/src/scripts/hooks/telemetry_usage_hook.ts +64 -8
  293. package/src/scripts/hooks/turn_end_gate_hook.ts +84 -0
  294. package/src/scripts/hooks_status.ts +112 -0
  295. package/src/scripts/injection_scan_hook.ts +7 -0
  296. package/src/scripts/install.ts +72 -185
  297. package/src/scripts/installed_layer_report.ts +103 -0
  298. package/src/scripts/language_mirror_hook.ts +15 -6
  299. package/src/scripts/learning_sidecar.ts +119 -8
  300. package/src/scripts/lint_hook_manifest.ts +53 -0
  301. package/src/scripts/lint_major_migration_sections.ts +156 -26
  302. package/src/scripts/lint_pack_boundaries.ts +63 -5
  303. package/src/scripts/lint_rule_law_section.ts +517 -0
  304. package/src/scripts/lint_workflow_security.ts +161 -5
  305. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  306. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  307. package/src/scripts/measure_routing_signal.ts +54 -16
  308. package/src/scripts/measure_skill_ranker_baseline.ts +216 -8
  309. package/src/scripts/memory_learn_hook.ts +91 -6
  310. package/src/scripts/model_rule_injection.ts +52 -5
  311. package/src/scripts/project_thin_rules.ts +34 -327
  312. package/src/scripts/report_evidence_temperature.ts +657 -0
  313. package/src/scripts/report_installed_rule_links.ts +157 -0
  314. package/src/scripts/report_label_agreement.ts +233 -0
  315. package/src/scripts/report_obligation_mechanism.ts +230 -0
  316. package/src/scripts/report_single_token_triggers.ts +277 -0
  317. package/src/scripts/report_skill_ranker_confusion.ts +442 -0
  318. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  319. package/src/scripts/report_verification_record_coverage.ts +306 -0
  320. package/src/scripts/rule_activation_census.ts +5 -2
  321. package/src/scripts/rule_trigger_eval.ts +9 -9
  322. package/src/scripts/schemas/review-findings.schema.json +3 -2
  323. package/src/scripts/schemas/rule.schema.json +5 -0
  324. package/src/scripts/self_review_gate.ts +62 -7
  325. package/src/scripts/skill_tools/score_skill_relevance.ts +290 -25
  326. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  327. package/src/scripts/sync_gitignore.ts +29 -235
  328. package/src/scripts/trigger_eval_grandfather.json +0 -5
  329. package/src/server/schemas/settings.ts +10 -0
  330. package/src/shared/skillRanking.ts +117 -11
  331. package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
  332. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
@@ -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-IGD6ERX6.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,16 +338,44 @@ 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 fs15 from "node:fs";
287
- import * as os3 from "node:os";
288
- import * as path13 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";
291
346
 
292
- // src/scripts/_lib/host_env_write.ts
293
- var YAML = __toESM(require_dist(), 1);
347
+ // src/scripts/_lib/reserved_name_sweep.ts
294
348
  import * as fs from "node:fs";
295
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";
296
379
  var WRITABLE_HOST_ENV = [
297
380
  { variable: "BASH_MAX_OUTPUT_LENGTH", settingsKey: "bash_max_output_length" },
298
381
  { variable: "MAX_MCP_OUTPUT_TOKENS", settingsKey: "max_mcp_output_tokens" }
@@ -303,10 +386,10 @@ var SETTINGS_CANDIDATES = [
303
386
  ];
304
387
  function readSettingsDoc(projectRoot) {
305
388
  for (const parts of SETTINGS_CANDIDATES) {
306
- const p = path.join(projectRoot, ...parts);
389
+ const p = path2.join(projectRoot, ...parts);
307
390
  let text;
308
391
  try {
309
- text = fs.readFileSync(p, "utf-8");
392
+ text = fs2.readFileSync(p, "utf-8");
310
393
  } catch {
311
394
  continue;
312
395
  }
@@ -547,8 +630,8 @@ function is_claude_builtin_name(slug) {
547
630
  }
548
631
 
549
632
  // src/scripts/_lib/mcp_bridge.ts
550
- import * as fs2 from "node:fs";
551
- import * as path2 from "node:path";
633
+ import * as fs3 from "node:fs";
634
+ import * as path3 from "node:path";
552
635
  var MCP_SERVER_KEY = "agent-config";
553
636
  var MCP_PACKAGE_NAME = "@event4u/agent-config";
554
637
  function mcpBridgeEntry(packageRoot) {
@@ -565,7 +648,7 @@ function mcpBridgeEntry(packageRoot) {
565
648
  }
566
649
  function readPackageVersion(packageRoot) {
567
650
  try {
568
- const raw = fs2.readFileSync(path2.join(packageRoot, "package.json"), "utf-8");
651
+ const raw = fs3.readFileSync(path3.join(packageRoot, "package.json"), "utf-8");
569
652
  const v = JSON.parse(raw).version;
570
653
  return typeof v === "string" && v.trim() !== "" ? v : null;
571
654
  } catch {
@@ -574,7 +657,7 @@ function readPackageVersion(packageRoot) {
574
657
  }
575
658
  function makeEnsureMcpBridge(mergeJsonFile) {
576
659
  return (projectRoot, force, packageRoot = projectRoot) => mergeJsonFile(
577
- path2.join(projectRoot, ".mcp.json"),
660
+ path3.join(projectRoot, ".mcp.json"),
578
661
  mcpBridgeEntry(packageRoot),
579
662
  force,
580
663
  ".mcp.json"
@@ -600,7 +683,7 @@ function makeEnsureMcpRegistrations(mergeJsonFile) {
600
683
  const merged = {};
601
684
  for (const t of targets) {
602
685
  merged[t.toolId] = mergeJsonFile(
603
- path2.join(projectRoot, ...t.relPath.split("/")),
686
+ path3.join(projectRoot, ...t.relPath.split("/")),
604
687
  mcpBridgeEntry(packageRoot),
605
688
  force,
606
689
  t.relPath
@@ -631,10 +714,10 @@ function projectionModeOf(raw) {
631
714
  return raw === "scoped" ? "scoped" : raw === "tiered" ? "tiered" : "legacy-all";
632
715
  }
633
716
  function resolveTierB(packageRoot) {
634
- const p = path2.join(packageRoot, "agents", "runtime", "state", "skill-tiers.json");
635
- if (!fs2.existsSync(p)) return null;
717
+ const p = path3.join(packageRoot, "agents", "runtime", "state", "skill-tiers.json");
718
+ if (!fs3.existsSync(p)) return null;
636
719
  try {
637
- const parsed = JSON.parse(fs2.readFileSync(p, "utf-8"));
720
+ const parsed = JSON.parse(fs3.readFileSync(p, "utf-8"));
638
721
  if (!Array.isArray(parsed.tier_b)) return null;
639
722
  return new Set(parsed.tier_b.filter((n) => typeof n === "string"));
640
723
  } catch {
@@ -642,7 +725,7 @@ function resolveTierB(packageRoot) {
642
725
  }
643
726
  }
644
727
  function tierBPrunePredicate(tierB) {
645
- return (mdPath) => tierB.has(path2.basename(path2.dirname(mdPath)));
728
+ return (mdPath) => tierB.has(path3.basename(path3.dirname(mdPath)));
646
729
  }
647
730
  function tierBAdvisory(packageRoot) {
648
731
  const tierB = resolveTierB(packageRoot);
@@ -671,35 +754,35 @@ function applyTieredPrune(deployResults, packageRoot, pruneBy) {
671
754
 
672
755
  // src/install/conflictTracker.ts
673
756
  import * as crypto2 from "node:crypto";
674
- import * as fs4 from "node:fs";
675
- import * as path4 from "node:path";
757
+ import * as fs5 from "node:fs";
758
+ import * as path5 from "node:path";
676
759
 
677
760
  // src/install/fsPrimitives.ts
678
761
  import * as crypto from "node:crypto";
679
- import * as fs3 from "node:fs";
680
- import * as path3 from "node:path";
762
+ import * as fs4 from "node:fs";
763
+ import * as path4 from "node:path";
681
764
  function resolvePath(p) {
682
765
  try {
683
- return fs3.realpathSync(path3.resolve(p));
766
+ return fs4.realpathSync(path4.resolve(p));
684
767
  } catch {
685
- return path3.resolve(p);
768
+ return path4.resolve(p);
686
769
  }
687
770
  }
688
771
  function pathExists(p) {
689
772
  try {
690
- fs3.statSync(p);
773
+ fs4.statSync(p);
691
774
  return true;
692
775
  } catch {
693
776
  return false;
694
777
  }
695
778
  }
696
779
  function mkdirp(p) {
697
- fs3.mkdirSync(p, { recursive: true });
780
+ fs4.mkdirSync(p, { recursive: true });
698
781
  }
699
782
  function sha256OfFile(p) {
700
783
  let data;
701
784
  try {
702
- data = fs3.readFileSync(p);
785
+ data = fs4.readFileSync(p);
703
786
  } catch {
704
787
  return null;
705
788
  }
@@ -740,20 +823,20 @@ function createConflictTracker(host) {
740
823
  function recordedHashFor(target) {
741
824
  if (conflictState.root === null) return void 0;
742
825
  conflictState.recorded ??= recordedHashesForRoot(conflictState.root);
743
- const plain = path4.resolve(target);
826
+ const plain = path5.resolve(target);
744
827
  if (conflictState.recorded.has(plain)) return conflictState.recorded.get(plain);
745
828
  const real = resolvePath(target);
746
829
  return real === plain ? void 0 : conflictState.recorded.get(real);
747
830
  }
748
831
  function stageInto(target, sidecar, produce) {
749
- mkdirp(path4.dirname(sidecar));
750
- const tmp = path4.join(
751
- path4.dirname(sidecar),
752
- `.${path4.basename(sidecar)}.${process.pid}.${crypto2.randomBytes(6).toString("hex")}${path4.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)}`
753
836
  );
754
837
  const discard = () => {
755
838
  try {
756
- fs4.unlinkSync(tmp);
839
+ fs5.unlinkSync(tmp);
757
840
  } catch {
758
841
  }
759
842
  };
@@ -780,7 +863,7 @@ function createConflictTracker(host) {
780
863
  }
781
864
  }
782
865
  try {
783
- fs4.renameSync(tmp, sidecar);
866
+ fs5.renameSync(tmp, sidecar);
784
867
  } catch (exc) {
785
868
  discard();
786
869
  host.fail(
@@ -829,7 +912,7 @@ function createConflictTracker(host) {
829
912
  preserve(target, source, packageRoot) {
830
913
  const sidecar = sidecarPathFor(target);
831
914
  stageInto(target, sidecar, (tmp) => {
832
- fs4.copyFileSync(source, tmp);
915
+ fs5.copyFileSync(source, tmp);
833
916
  host.tagDeployed(tmp, source, packageRoot);
834
917
  });
835
918
  record(target, sidecar);
@@ -845,7 +928,7 @@ function createConflictTracker(host) {
845
928
  */
846
929
  preserveContent(target, content) {
847
930
  const sidecar = sidecarPathFor(target);
848
- stageInto(target, sidecar, (tmp) => fs4.writeFileSync(tmp, content, "utf-8"));
931
+ stageInto(target, sidecar, (tmp) => fs5.writeFileSync(tmp, content, "utf-8"));
849
932
  record(target, sidecar);
850
933
  },
851
934
  /**
@@ -867,7 +950,7 @@ function createConflictTracker(host) {
867
950
  var YAML2 = __toESM(require_dist(), 1);
868
951
  import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
869
952
  import { homedir } from "node:os";
870
- import { isAbsolute, join as join4, resolve as resolve3 } from "node:path";
953
+ import { isAbsolute, join as join5, resolve as resolve3 } from "node:path";
871
954
  function fileEntry(p, kind, hashContent) {
872
955
  return { path: p, kind, sha256: hashContent ? sha256OfFile(p) : null };
873
956
  }
@@ -890,7 +973,7 @@ function filesByToolFromBridges(tools, projectRoot, scope, bridgeMarker) {
890
973
  for (const toolId of [...tools].sort()) {
891
974
  const marker = bridgeMarker(toolId, scope);
892
975
  if (!marker) continue;
893
- const markerPath = isAbsolute(marker) ? marker : join4(projectRoot, marker);
976
+ const markerPath = isAbsolute(marker) ? marker : join5(projectRoot, marker);
894
977
  out[toolId] = [fileEntry(markerPath, "bridge", false)];
895
978
  }
896
979
  return out;
@@ -898,7 +981,7 @@ function filesByToolFromBridges(tools, projectRoot, scope, bridgeMarker) {
898
981
  function expanduser(p) {
899
982
  if (p === "~") return homedir();
900
983
  if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
901
- return join4(homedir(), p.slice(2));
984
+ return join5(homedir(), p.slice(2));
902
985
  }
903
986
  return p;
904
987
  }
@@ -990,8 +1073,9 @@ function preservedIndex(preservedTargets, staged) {
990
1073
  }
991
1074
 
992
1075
  // src/scripts/_lib/rule_layer_overlap.ts
993
- import * as fs5 from "node:fs";
994
- import * as path5 from "node:path";
1076
+ import * as fs6 from "node:fs";
1077
+ import * as os from "node:os";
1078
+ import * as path6 from "node:path";
995
1079
  var INSTALLER_PROVENANCE_KEYS = ["package", "source_path"];
996
1080
  function stripProvenance(text) {
997
1081
  const lines = text.split("\n");
@@ -1042,17 +1126,23 @@ function compareLayers(global_layer, project_layer) {
1042
1126
  redundant_chars
1043
1127
  };
1044
1128
  }
1129
+ function hostRuleLayerDirs(projectRoot) {
1130
+ return [
1131
+ path6.join(os.homedir(), ".claude", "rules"),
1132
+ path6.join(projectRoot, ".claude", "rules")
1133
+ ];
1134
+ }
1045
1135
  function readRuleLayer(dir) {
1046
1136
  let names;
1047
1137
  try {
1048
- names = fs5.readdirSync(dir);
1138
+ names = fs6.readdirSync(dir);
1049
1139
  } catch {
1050
1140
  return null;
1051
1141
  }
1052
1142
  const files = /* @__PURE__ */ new Map();
1053
1143
  for (const name of names.filter((n) => n.endsWith(".md")).sort()) {
1054
1144
  try {
1055
- files.set(name, fs5.readFileSync(path5.join(dir, name), "utf-8"));
1145
+ files.set(name, fs6.readFileSync(path6.join(dir, name), "utf-8"));
1056
1146
  } catch {
1057
1147
  continue;
1058
1148
  }
@@ -1060,7 +1150,7 @@ function readRuleLayer(dir) {
1060
1150
  return { dir, files };
1061
1151
  }
1062
1152
  function claudeMdExcludesGlob(dir) {
1063
- return `${path5.resolve(dir).replace(/\/+$/, "")}/**`;
1153
+ return `${path6.resolve(dir).replace(/\/+$/, "")}/**`;
1064
1154
  }
1065
1155
  function mergeClaudeMdExcludes(existing, entry) {
1066
1156
  if (!Array.isArray(existing)) return [entry];
@@ -1091,25 +1181,25 @@ function decideLayerAction(report, choice, global_dir, project_dir) {
1091
1181
  // src/scripts/_lib/install_drift.ts
1092
1182
  var import_yaml = __toESM(require_dist(), 1);
1093
1183
  import * as crypto3 from "node:crypto";
1094
- import * as fs6 from "node:fs";
1095
- import * as os from "node:os";
1096
- import * as path6 from "node:path";
1184
+ import * as fs7 from "node:fs";
1185
+ import * as os2 from "node:os";
1186
+ import * as path7 from "node:path";
1097
1187
  function expanduser2(p) {
1098
1188
  if (p === "~") {
1099
- return os.homedir();
1189
+ return os2.homedir();
1100
1190
  }
1101
1191
  if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
1102
- return path6.join(os.homedir(), p.slice(2));
1192
+ return path7.join(os2.homedir(), p.slice(2));
1103
1193
  }
1104
1194
  return p;
1105
1195
  }
1106
1196
  function resolve_entry_path(project_root, raw) {
1107
1197
  const p = expanduser2(raw);
1108
- return path6.isAbsolute(p) ? p : path6.join(project_root, p);
1198
+ return path7.isAbsolute(p) ? p : path7.join(project_root, p);
1109
1199
  }
1110
1200
  function sha256_of_file(p) {
1111
1201
  try {
1112
- return crypto3.createHash("sha256").update(fs6.readFileSync(p)).digest("hex");
1202
+ return crypto3.createHash("sha256").update(fs7.readFileSync(p)).digest("hex");
1113
1203
  } catch {
1114
1204
  return null;
1115
1205
  }
@@ -1118,7 +1208,7 @@ function collect_drift(project_root, env) {
1118
1208
  const target = manifest_path(project_root, env);
1119
1209
  let text;
1120
1210
  try {
1121
- text = fs6.readFileSync(target, "utf-8");
1211
+ text = fs7.readFileSync(target, "utf-8");
1122
1212
  } catch {
1123
1213
  return null;
1124
1214
  }
@@ -1163,7 +1253,7 @@ function collect_drift(project_root, env) {
1163
1253
  continue;
1164
1254
  }
1165
1255
  const resolved = resolve_entry_path(project_root, raw_path);
1166
- if (!fs6.existsSync(resolved)) {
1256
+ if (!fs7.existsSync(resolved)) {
1167
1257
  out.push({
1168
1258
  tool_id,
1169
1259
  path: resolved,
@@ -1216,15 +1306,15 @@ function format_drift_report(entries) {
1216
1306
  }
1217
1307
 
1218
1308
  // src/scripts/_lib/skill_catalogue.ts
1219
- import * as fs7 from "node:fs";
1220
- import * as path7 from "node:path";
1309
+ import * as fs8 from "node:fs";
1310
+ import * as path8 from "node:path";
1221
1311
  var PROJECT_CATALOGUE_ROOTS = ["src/skills", ".claude/skills"];
1222
1312
  var HOST_CATALOGUE_ROOT = ".claude/skills";
1223
1313
  var DEFAULT_CATALOGUE_ROOTS = [
1224
1314
  ...PROJECT_CATALOGUE_ROOTS,
1225
1315
  `~/${HOST_CATALOGUE_ROOT}`
1226
1316
  ];
1227
- var OBSERVATION_LOG = path7.join(
1317
+ var OBSERVATION_LOG = path8.join(
1228
1318
  "agents",
1229
1319
  "evidence",
1230
1320
  "metrics",
@@ -1268,9 +1358,9 @@ function descriptionOf(frontmatter) {
1268
1358
  return "";
1269
1359
  }
1270
1360
  function readProjectedCatalogue(root) {
1271
- const names = fs7.readdirSync(root).filter((n) => fs7.existsSync(path7.join(root, n, "SKILL.md"))).sort();
1361
+ const names = fs8.readdirSync(root).filter((n) => fs8.existsSync(path8.join(root, n, "SKILL.md"))).sort();
1272
1362
  return names.map((name, index) => {
1273
- const content = fs7.readFileSync(path7.join(root, name, "SKILL.md"), "utf-8");
1363
+ const content = fs8.readFileSync(path8.join(root, name, "SKILL.md"), "utf-8");
1274
1364
  const frontmatter = frontmatterOf(content);
1275
1365
  const description = descriptionOf(frontmatter);
1276
1366
  return {
@@ -1287,12 +1377,12 @@ function truncationModeOf(record) {
1287
1377
  return record.truncation_mode ?? "per-entry";
1288
1378
  }
1289
1379
  function markdownFilesUnder(root) {
1290
- if (!fs7.existsSync(root)) return [];
1380
+ if (!fs8.existsSync(root)) return [];
1291
1381
  const out = [];
1292
1382
  const walk = (dir) => {
1293
- for (const entry of fs7.readdirSync(dir, { withFileTypes: true })) {
1294
- const full = path7.join(dir, entry.name);
1295
- if (fs7.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);
1296
1386
  else if (entry.name.endsWith(".md")) out.push(full);
1297
1387
  }
1298
1388
  };
@@ -1300,9 +1390,9 @@ function markdownFilesUnder(root) {
1300
1390
  return out;
1301
1391
  }
1302
1392
  function measureCatalogueVolume(host, root) {
1303
- const skillsRoot = path7.join(root, "skills");
1304
- const skills = fs7.existsSync(skillsRoot) ? readProjectedCatalogue(skillsRoot) : [];
1305
- const commandEntries = markdownFilesUnder(path7.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;
1306
1396
  return {
1307
1397
  host,
1308
1398
  root,
@@ -1380,9 +1470,9 @@ function migrationPromptLines(host, eligibility, settingsPath) {
1380
1470
  ];
1381
1471
  }
1382
1472
  function readObservationLog(logPath) {
1383
- if (!fs7.existsSync(logPath)) return [];
1473
+ if (!fs8.existsSync(logPath)) return [];
1384
1474
  const out = [];
1385
- for (const line of fs7.readFileSync(logPath, "utf-8").split("\n")) {
1475
+ for (const line of fs8.readFileSync(logPath, "utf-8").split("\n")) {
1386
1476
  const trimmed = line.trim();
1387
1477
  if (trimmed.length === 0) continue;
1388
1478
  try {
@@ -1423,8 +1513,8 @@ function isInteractiveSession(probe) {
1423
1513
 
1424
1514
  // src/scripts/_lib/claude_desktop_bundler.ts
1425
1515
  import * as crypto4 from "node:crypto";
1426
- import * as fs8 from "node:fs";
1427
- import * as path8 from "node:path";
1516
+ import * as fs9 from "node:fs";
1517
+ import * as path9 from "node:path";
1428
1518
 
1429
1519
  // src/scripts/_lib/zip_min.ts
1430
1520
  import * as zlib from "node:zlib";
@@ -1531,7 +1621,7 @@ function _is_excluded(rel_parts) {
1531
1621
  }
1532
1622
  function _is_dir(p) {
1533
1623
  try {
1534
- return fs8.statSync(p).isDirectory();
1624
+ return fs9.statSync(p).isDirectory();
1535
1625
  } catch {
1536
1626
  return false;
1537
1627
  }
@@ -1543,12 +1633,12 @@ function _compare_rel_parts(a, b) {
1543
1633
  }
1544
1634
  function _walk_skill_files(skill_dir) {
1545
1635
  const out = [];
1546
- const resolved = fs8.realpathSync(skill_dir);
1636
+ const resolved = fs9.realpathSync(skill_dir);
1547
1637
  const walk = (root, relRoot) => {
1548
1638
  const dirNames = [];
1549
1639
  const fileNames = [];
1550
- for (const dirent of fs8.readdirSync(root, { withFileTypes: true })) {
1551
- const full = path8.join(root, dirent.name);
1640
+ for (const dirent of fs9.readdirSync(root, { withFileTypes: true })) {
1641
+ const full = path9.join(root, dirent.name);
1552
1642
  const isDir2 = dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full);
1553
1643
  if (isDir2) {
1554
1644
  dirNames.push(dirent.name);
@@ -1561,13 +1651,13 @@ function _walk_skill_files(skill_dir) {
1561
1651
  if (_is_excluded(rel_parts)) {
1562
1652
  continue;
1563
1653
  }
1564
- out.push([path8.join(root, fname), rel_parts]);
1654
+ out.push([path9.join(root, fname), rel_parts]);
1565
1655
  }
1566
1656
  for (const dname of dirNames) {
1567
1657
  if (_is_excluded([dname])) {
1568
1658
  continue;
1569
1659
  }
1570
- walk(path8.join(root, dname), [...relRoot, dname]);
1660
+ walk(path9.join(root, dname), [...relRoot, dname]);
1571
1661
  }
1572
1662
  };
1573
1663
  walk(resolved, []);
@@ -1580,53 +1670,53 @@ function _manifest_digest(files) {
1580
1670
  const rel = rel_parts.join("/");
1581
1671
  h.update(Buffer.from(rel, "utf-8"));
1582
1672
  h.update(Buffer.from([0]));
1583
- h.update(crypto4.createHash("sha256").update(fs8.readFileSync(abs_path)).digest());
1673
+ h.update(crypto4.createHash("sha256").update(fs9.readFileSync(abs_path)).digest());
1584
1674
  h.update(Buffer.from([0]));
1585
1675
  }
1586
1676
  return h.digest("hex");
1587
1677
  }
1588
1678
  function _atomic_write_zip(zip_path, files) {
1589
- fs8.mkdirSync(path8.dirname(zip_path), { recursive: true });
1590
- const stem = path8.basename(zip_path, path8.extname(zip_path));
1591
- const tmp_path = path8.join(
1592
- path8.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),
1593
1683
  `.${stem}.${crypto4.randomBytes(6).toString("hex")}.zip.tmp`
1594
1684
  );
1595
1685
  try {
1596
1686
  const entries = files.map(([abs_path, rel_parts]) => ({
1597
1687
  name: rel_parts.join("/"),
1598
- data: fs8.readFileSync(abs_path)
1688
+ data: fs9.readFileSync(abs_path)
1599
1689
  }));
1600
- fs8.writeFileSync(tmp_path, zip_write_sync(entries));
1601
- fs8.renameSync(tmp_path, zip_path);
1690
+ fs9.writeFileSync(tmp_path, zip_write_sync(entries));
1691
+ fs9.renameSync(tmp_path, zip_path);
1602
1692
  } finally {
1603
- if (fs8.existsSync(tmp_path)) {
1604
- fs8.unlinkSync(tmp_path);
1693
+ if (fs9.existsSync(tmp_path)) {
1694
+ fs9.unlinkSync(tmp_path);
1605
1695
  }
1606
1696
  }
1607
1697
  }
1608
1698
  function _write_if_changed(dest_dir, slug, files, force, written) {
1609
1699
  const digest = _manifest_digest(files);
1610
- const zip_path = path8.join(dest_dir, `${slug}.zip`);
1611
- const digest_path = path8.join(dest_dir, `${slug}.sha256`);
1612
- const recorded = fs8.existsSync(digest_path) ? fs8.readFileSync(digest_path, "utf-8").trim() : "";
1613
- if (!force && recorded === digest && fs8.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)) {
1614
1704
  return;
1615
1705
  }
1616
1706
  _atomic_write_zip(zip_path, files);
1617
- fs8.writeFileSync(digest_path, digest + "\n", "utf-8");
1707
+ fs9.writeFileSync(digest_path, digest + "\n", "utf-8");
1618
1708
  written.push(zip_path);
1619
1709
  }
1620
1710
  function build_skill_bundles(package_root, dest_dir, force = false, curation = null) {
1621
- const skills_root = path8.join(package_root, "dist/agent-src", "skills");
1711
+ const skills_root = path9.join(package_root, "dist/agent-src", "skills");
1622
1712
  if (!_is_dir(skills_root)) {
1623
1713
  return [];
1624
1714
  }
1625
- fs8.mkdirSync(dest_dir, { recursive: true });
1715
+ fs9.mkdirSync(dest_dir, { recursive: true });
1626
1716
  const written = [];
1627
- for (const name of fs8.readdirSync(skills_root).sort()) {
1628
- const entry = path8.join(skills_root, name);
1629
- const isSymlink2 = fs8.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();
1630
1720
  if (!(_is_dir(entry) || isSymlink2)) {
1631
1721
  continue;
1632
1722
  }
@@ -1634,8 +1724,8 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
1634
1724
  if (curation !== null && !curation.includes(skill_name)) {
1635
1725
  continue;
1636
1726
  }
1637
- const skill_md = path8.join(entry, "SKILL.md");
1638
- if (!fs8.existsSync(skill_md)) {
1727
+ const skill_md = path9.join(entry, "SKILL.md");
1728
+ if (!fs9.existsSync(skill_md)) {
1639
1729
  continue;
1640
1730
  }
1641
1731
  const files = _walk_skill_files(entry);
@@ -1647,15 +1737,15 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
1647
1737
  return written;
1648
1738
  }
1649
1739
  function _command_slug(source_file, commands_root) {
1650
- const rel = path8.relative(commands_root, source_file);
1651
- const noExt = rel.slice(0, rel.length - path8.extname(rel).length);
1652
- return noExt.split(path8.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("-");
1653
1743
  }
1654
1744
  function _iter_command_files(commands_root) {
1655
1745
  const found = [];
1656
1746
  const walk = (dir) => {
1657
- for (const dirent of fs8.readdirSync(dir, { withFileTypes: true })) {
1658
- const full = path8.join(dir, dirent.name);
1747
+ for (const dirent of fs9.readdirSync(dir, { withFileTypes: true })) {
1748
+ const full = path9.join(dir, dirent.name);
1659
1749
  if (dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full)) {
1660
1750
  walk(full);
1661
1751
  } else if (dirent.name.endsWith(".md")) {
@@ -1665,21 +1755,21 @@ function _iter_command_files(commands_root) {
1665
1755
  };
1666
1756
  walk(commands_root);
1667
1757
  found.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
1668
- return found.filter((source_file) => path8.basename(source_file) !== "AGENTS.md");
1758
+ return found.filter((source_file) => path9.basename(source_file) !== "AGENTS.md");
1669
1759
  }
1670
1760
  function build_command_bundles(package_root, dest_dir, force = false, curation = null) {
1671
- const commands_root = path8.join(package_root, "dist/agent-src", "commands");
1761
+ const commands_root = path9.join(package_root, "dist/agent-src", "commands");
1672
1762
  if (!_is_dir(commands_root)) {
1673
1763
  return [];
1674
1764
  }
1675
- const skills_root = path8.join(package_root, "dist/agent-src", "skills");
1765
+ const skills_root = path9.join(package_root, "dist/agent-src", "skills");
1676
1766
  let skill_names = /* @__PURE__ */ new Set();
1677
1767
  if (_is_dir(skills_root)) {
1678
1768
  skill_names = new Set(
1679
- fs8.readdirSync(skills_root).filter((name) => _is_dir(path8.join(skills_root, name)))
1769
+ fs9.readdirSync(skills_root).filter((name) => _is_dir(path9.join(skills_root, name)))
1680
1770
  );
1681
1771
  }
1682
- fs8.mkdirSync(dest_dir, { recursive: true });
1772
+ fs9.mkdirSync(dest_dir, { recursive: true });
1683
1773
  const written = [];
1684
1774
  for (const source_file of _iter_command_files(commands_root)) {
1685
1775
  const slug = _command_slug(source_file, commands_root);
@@ -1689,7 +1779,7 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
1689
1779
  if (curation !== null && !curation.includes(slug)) {
1690
1780
  continue;
1691
1781
  }
1692
- const files = [[fs8.realpathSync(source_file), ["SKILL.md"]]];
1782
+ const files = [[fs9.realpathSync(source_file), ["SKILL.md"]]];
1693
1783
  _write_if_changed(dest_dir, slug, files, force, written);
1694
1784
  }
1695
1785
  return written;
@@ -1697,8 +1787,8 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
1697
1787
 
1698
1788
  // src/scripts/hooks/host_lowering.ts
1699
1789
  var import_yaml2 = __toESM(require_dist(), 1);
1700
- import * as fs9 from "node:fs";
1701
- import * as path9 from "node:path";
1790
+ import * as fs10 from "node:fs";
1791
+ import * as path10 from "node:path";
1702
1792
  import { fileURLToPath } from "node:url";
1703
1793
 
1704
1794
  // src/scripts/hooks/table_fingerprint.ts
@@ -1710,12 +1800,12 @@ function tableFingerprint(text) {
1710
1800
 
1711
1801
  // src/scripts/hooks/host_lowering.ts
1712
1802
  var _IN_BUNDLE = true;
1713
- var _REPO_ROOT = path9.resolve(
1714
- path9.dirname(fileURLToPath(import.meta.url)),
1803
+ var _REPO_ROOT = path10.resolve(
1804
+ path10.dirname(fileURLToPath(import.meta.url)),
1715
1805
  ..._IN_BUNDLE ? ["..", ".."] : ["..", "..", ".."]
1716
1806
  );
1717
- var HOST_LOWERING_PATH = path9.join(_REPO_ROOT, "src", "scripts", "hooks", "host_lowering.yaml");
1718
- var HOST_LOWERING_JSON_PATH = path9.join(_REPO_ROOT, "src", "scripts", "hooks", "host_lowering.json");
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");
1719
1809
  var DEFAULT_SURFACE = "any";
1720
1810
  function _asString(v) {
1721
1811
  if (v === null || v === void 0) return null;
@@ -1787,10 +1877,10 @@ function _structure(raw) {
1787
1877
  var _cache = null;
1788
1878
  function loadHostLowering() {
1789
1879
  if (_cache !== null) return _cache;
1790
- const text = fs9.readFileSync(HOST_LOWERING_PATH, "utf-8");
1880
+ const text = fs10.readFileSync(HOST_LOWERING_PATH, "utf-8");
1791
1881
  let compiled;
1792
1882
  try {
1793
- compiled = fs9.readFileSync(HOST_LOWERING_JSON_PATH, "utf-8");
1883
+ compiled = fs10.readFileSync(HOST_LOWERING_JSON_PATH, "utf-8");
1794
1884
  } catch {
1795
1885
  compiled = null;
1796
1886
  }
@@ -1802,7 +1892,24 @@ function resolveTable(yamlText, compiledText) {
1802
1892
  try {
1803
1893
  const raw = JSON.parse(compiledText);
1804
1894
  const table = raw["table"];
1805
- if (raw["fingerprint"] === tableFingerprint(yamlText) && typeof table === "object" && table !== null) {
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))) {
1806
1913
  return _structure(table);
1807
1914
  }
1808
1915
  } catch {
@@ -1826,26 +1933,26 @@ function hostBindings(host, table = loadHostLowering()) {
1826
1933
  }
1827
1934
 
1828
1935
  // src/install/partitionEligibility.ts
1829
- import * as fs11 from "node:fs";
1830
- import * as os2 from "node:os";
1936
+ import * as fs12 from "node:fs";
1937
+ import * as os3 from "node:os";
1831
1938
 
1832
1939
  // src/install/hostLayerFingerprint.ts
1833
1940
  import { createHash as createHash6 } from "node:crypto";
1834
- import * as fs10 from "node:fs";
1835
- import * as path10 from "node:path";
1941
+ import * as fs11 from "node:fs";
1942
+ import * as path11 from "node:path";
1836
1943
  var FINGERPRINT_SCHEMA = 1;
1837
1944
  function collectFiles(dir) {
1838
1945
  const out = [];
1839
1946
  const walk = (d) => {
1840
1947
  let entries;
1841
1948
  try {
1842
- entries = fs10.readdirSync(d, { withFileTypes: true });
1949
+ entries = fs11.readdirSync(d, { withFileTypes: true });
1843
1950
  } catch {
1844
1951
  return;
1845
1952
  }
1846
1953
  const sorted = [...entries].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
1847
1954
  for (const e of sorted) {
1848
- const p = path10.join(d, e.name);
1955
+ const p = path11.join(d, e.name);
1849
1956
  if (e.isDirectory()) {
1850
1957
  walk(p);
1851
1958
  } else if (e.isFile()) {
@@ -1862,10 +1969,10 @@ function fingerprintLayers(layers) {
1862
1969
  for (const layer of layers) {
1863
1970
  h.update(`layer:${layer.label}\0`);
1864
1971
  for (const file of collectFiles(layer.root)) {
1865
- h.update(path10.relative(layer.root, file));
1972
+ h.update(path11.relative(layer.root, file));
1866
1973
  h.update("\0");
1867
1974
  try {
1868
- h.update(fs10.readFileSync(file));
1975
+ h.update(fs11.readFileSync(file));
1869
1976
  } catch {
1870
1977
  h.update("\0unreadable\0");
1871
1978
  }
@@ -1875,11 +1982,11 @@ function fingerprintLayers(layers) {
1875
1982
  return h.digest("hex");
1876
1983
  }
1877
1984
  function hostLayerInputs(userHome) {
1878
- const claude = path10.join(userHome, ".claude");
1985
+ const claude = path11.join(userHome, ".claude");
1879
1986
  return [
1880
- { label: "rules", root: path10.join(claude, "rules") },
1881
- { label: "skills", root: path10.join(claude, "skills") },
1882
- { label: "commands", root: path10.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") }
1883
1990
  ];
1884
1991
  }
1885
1992
 
@@ -1888,7 +1995,7 @@ var MAINTAINER_WORKSPACE = "agent-config-maintainer";
1888
1995
  function isExclusivelyPackageOnly(source_path) {
1889
1996
  let meta;
1890
1997
  try {
1891
- [meta] = parseFrontmatter(fs11.readFileSync(source_path, "utf-8"));
1998
+ [meta] = parseFrontmatter(fs12.readFileSync(source_path, "utf-8"));
1892
1999
  } catch {
1893
2000
  return false;
1894
2001
  }
@@ -1903,7 +2010,7 @@ function stampHostLayerFingerprint(installedVersion, tools, lockfilePath, skip2,
1903
2010
  return null;
1904
2011
  }
1905
2012
  try {
1906
- const fingerprint = fingerprintLayers(hostLayerInputs(os2.homedir()));
2013
+ const fingerprint = fingerprintLayers(hostLayerInputs(os3.homedir()));
1907
2014
  write_lockfile(installedVersion, [...tools], {
1908
2015
  path: lockfilePath,
1909
2016
  host_layer_fingerprint: fingerprint
@@ -1919,8 +2026,8 @@ function stampHostLayerFingerprint(installedVersion, tools, lockfilePath, skip2,
1919
2026
  }
1920
2027
 
1921
2028
  // src/install/claudeRuleRewrite.ts
1922
- import * as fs12 from "node:fs";
1923
- import * as path11 from "node:path";
2029
+ import * as fs13 from "node:fs";
2030
+ import * as path12 from "node:path";
1924
2031
 
1925
2032
  // src/install/claudePathsPlan.ts
1926
2033
  function derive_trigger_globs(meta) {
@@ -1960,14 +2067,22 @@ function _expanded_pattern_count(pattern) {
1960
2067
  return n;
1961
2068
  }
1962
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"]);
1963
2072
  function _has_non_path_trigger(meta) {
1964
2073
  const triggers = meta["triggers"];
1965
2074
  if (!Array.isArray(triggers)) return false;
1966
2075
  for (const t of triggers) {
1967
2076
  if (t === null || typeof t !== "object" || Array.isArray(t)) continue;
1968
2077
  const obj = t;
1969
- if (typeof obj["keyword"] === "string" && obj["keyword"]) return true;
1970
- 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
+ }
1971
2086
  }
1972
2087
  return false;
1973
2088
  }
@@ -2035,6 +2150,11 @@ function rewriteAndReport(rulesDir, quiet, info2, warn2, wrappers, preserved = /
2035
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`
2036
2151
  );
2037
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
+ }
2038
2158
  }
2039
2159
  if (result.rewritten > 0 && !quiet) {
2040
2160
  info2(
@@ -2076,23 +2196,23 @@ function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
2076
2196
  const result = { rewritten: 0, scoped: [], dropped: [], failed: [] };
2077
2197
  let entries;
2078
2198
  try {
2079
- entries = fs12.readdirSync(rulesDir);
2199
+ entries = fs13.readdirSync(rulesDir);
2080
2200
  } catch {
2081
2201
  return result;
2082
2202
  }
2083
2203
  for (const name of entries.filter((n) => n.endsWith(".md")).sort()) {
2084
- const full = path11.join(rulesDir, name);
2085
- if (preserved.has(path11.resolve(full))) continue;
2204
+ const full = path12.join(rulesDir, name);
2205
+ if (preserved.has(path12.resolve(full))) continue;
2086
2206
  let stat;
2087
2207
  try {
2088
- stat = fs12.lstatSync(full);
2208
+ stat = fs13.lstatSync(full);
2089
2209
  } catch {
2090
2210
  continue;
2091
2211
  }
2092
2212
  if (!stat.isFile() || stat.isSymbolicLink()) continue;
2093
2213
  let text;
2094
2214
  try {
2095
- text = fs12.readFileSync(full, "utf-8");
2215
+ text = fs13.readFileSync(full, "utf-8");
2096
2216
  } catch {
2097
2217
  continue;
2098
2218
  }
@@ -2102,7 +2222,7 @@ function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
2102
2222
  const withOwnership = _withPreservedKeys(rendered.text, text);
2103
2223
  if (withOwnership !== text) {
2104
2224
  try {
2105
- fs12.writeFileSync(full, withOwnership, "utf-8");
2225
+ fs13.writeFileSync(full, withOwnership, "utf-8");
2106
2226
  } catch (e) {
2107
2227
  result.failed.push({
2108
2228
  rule: name.slice(0, -3),
@@ -2121,6 +2241,744 @@ function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
2121
2241
  return result;
2122
2242
  }
2123
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
+
2124
2982
  // src/shared/settingsSurface.ts
2125
2983
  function unwrapRef(root) {
2126
2984
  if (root.$ref !== void 0 && root.definitions !== void 0) {
@@ -3476,8 +4334,8 @@ var zodToJsonSchema = (schema, options) => {
3476
4334
  };
3477
4335
 
3478
4336
  // src/scripts/_lib/module_detection.ts
3479
- import * as fs13 from "node:fs";
3480
- import * as path12 from "node:path";
4337
+ import * as fs18 from "node:fs";
4338
+ import * as path19 from "node:path";
3481
4339
  var _SKIP_DIRS = /* @__PURE__ */ new Set([".module-template", ".example"]);
3482
4340
  var _RULES = [
3483
4341
  ["app/Modules", "laravel-hmvc", "App\\Modules\\{ModuleName}"],
@@ -3491,14 +4349,14 @@ var _RULES = [
3491
4349
  ];
3492
4350
  function _isDir(p) {
3493
4351
  try {
3494
- return fs13.statSync(p).isDirectory();
4352
+ return fs18.statSync(p).isDirectory();
3495
4353
  } catch {
3496
4354
  return false;
3497
4355
  }
3498
4356
  }
3499
4357
  function _isFile(p) {
3500
4358
  try {
3501
- return fs13.statSync(p).isFile();
4359
+ return fs18.statSync(p).isFile();
3502
4360
  } catch {
3503
4361
  return false;
3504
4362
  }
@@ -3512,13 +4370,13 @@ function _isUpperChar(ch) {
3512
4370
  function _list_module_subdirs(root) {
3513
4371
  let entries;
3514
4372
  try {
3515
- entries = fs13.readdirSync(root).sort();
4373
+ entries = fs18.readdirSync(root).sort();
3516
4374
  } catch {
3517
4375
  return [];
3518
4376
  }
3519
4377
  const out = [];
3520
4378
  for (const name of entries) {
3521
- if (!_isDir(path12.join(root, name))) {
4379
+ if (!_isDir(path19.join(root, name))) {
3522
4380
  continue;
3523
4381
  }
3524
4382
  if (name.startsWith(".")) {
@@ -3540,11 +4398,11 @@ function _score_confidence(stack, root, subdirs) {
3540
4398
  return capitalized.length > 0 ? "high" : "medium";
3541
4399
  }
3542
4400
  if (stack === "node-monorepo") {
3543
- const withPkgJson = subdirs.filter((name) => _isFile(path12.join(root, name, "package.json")));
4401
+ const withPkgJson = subdirs.filter((name) => _isFile(path19.join(root, name, "package.json")));
3544
4402
  return withPkgJson.length > 0 ? "high" : "medium";
3545
4403
  }
3546
4404
  if (stack === "python-src") {
3547
- const withInit = subdirs.filter((name) => _isFile(path12.join(root, name, "__init__.py")));
4405
+ const withInit = subdirs.filter((name) => _isFile(path19.join(root, name, "__init__.py")));
3548
4406
  return withInit.length > 0 ? "high" : "medium";
3549
4407
  }
3550
4408
  if (stack === "go-internal") {
@@ -3556,7 +4414,7 @@ function detect_module_roots(project_root) {
3556
4414
  const high = [];
3557
4415
  const medium = [];
3558
4416
  for (const [rel_path, stack, namespace_template] of _RULES) {
3559
- const abs_path = path12.join(project_root, rel_path);
4417
+ const abs_path = path19.join(project_root, rel_path);
3560
4418
  if (!_isDir(abs_path)) {
3561
4419
  continue;
3562
4420
  }
@@ -3578,7 +4436,7 @@ function detect_module_roots(project_root) {
3578
4436
  }
3579
4437
 
3580
4438
  // src/scripts/_lib/model_tier.ts
3581
- import fs14 from "node:fs";
4439
+ import fs19 from "node:fs";
3582
4440
  var TIER_TO_CLAUDE_MODEL = {
3583
4441
  frontier: "fable",
3584
4442
  high: "opus",
@@ -3587,8 +4445,8 @@ var TIER_TO_CLAUDE_MODEL = {
3587
4445
  };
3588
4446
  var MODEL_TIER_RE = /^model_tier:\s*"?([a-z]+)"?\s*$/m;
3589
4447
  function read_model_tier(skill_md) {
3590
- if (!fs14.existsSync(skill_md)) return null;
3591
- const text = fs14.readFileSync(skill_md).toString("utf-8");
4448
+ if (!fs19.existsSync(skill_md)) return null;
4449
+ const text = fs19.readFileSync(skill_md).toString("utf-8");
3592
4450
  if (!text.startsWith("---\n")) return null;
3593
4451
  const end = text.indexOf("\n---\n", 4);
3594
4452
  if (end === -1) return null;
@@ -3604,15 +4462,15 @@ function render_native_model_md(text, tier) {
3604
4462
  }
3605
4463
 
3606
4464
  // src/install/paths.ts
3607
- import { homedir as homedir4, tmpdir } from "node:os";
3608
- import { join as join13 } from "node:path";
4465
+ import { homedir as homedir7, tmpdir } from "node:os";
4466
+ import { join as join20 } from "node:path";
3609
4467
  var INSTALL_ROOT_SUBPATH = ".event4u/agent-config";
3610
4468
  var INSTALL_LOG_FILENAME = "install-log.jsonl";
3611
4469
  function resolveHome(home) {
3612
4470
  if (home && home.length > 0) {
3613
4471
  return home;
3614
4472
  }
3615
- const fromOs = homedir4();
4473
+ const fromOs = homedir7();
3616
4474
  if (!fromOs) {
3617
4475
  throw new Error(
3618
4476
  "Cannot resolve home directory \u2014 both $HOME (POSIX) and $USERPROFILE (Windows) are unset."
@@ -3621,14 +4479,14 @@ function resolveHome(home) {
3621
4479
  return fromOs;
3622
4480
  }
3623
4481
  function getInstallRoot(home) {
3624
- return join13(resolveHome(home), INSTALL_ROOT_SUBPATH);
4482
+ return join20(resolveHome(home), INSTALL_ROOT_SUBPATH);
3625
4483
  }
3626
4484
  function getLogPath(home) {
3627
- return join13(getInstallRoot(home), INSTALL_LOG_FILENAME);
4485
+ return join20(getInstallRoot(home), INSTALL_LOG_FILENAME);
3628
4486
  }
3629
4487
 
3630
4488
  // src/scripts/install.ts
3631
- var _HERE = fileURLToPath2(import.meta.url);
4489
+ var _HERE2 = fileURLToPath4(import.meta.url);
3632
4490
  var SystemExitError = class extends Error {
3633
4491
  constructor(code) {
3634
4492
  super(`system-exit-${code}`);
@@ -3644,43 +4502,43 @@ var ArgparseExit = class extends Error {
3644
4502
  code;
3645
4503
  };
3646
4504
  function expanduser3(p) {
3647
- if (p === "~") return os3.homedir();
4505
+ if (p === "~") return os6.homedir();
3648
4506
  if (p.startsWith("~/") || p.startsWith("~\\")) {
3649
- return path13.join(os3.homedir(), p.slice(2));
4507
+ return path20.join(os6.homedir(), p.slice(2));
3650
4508
  }
3651
4509
  return p;
3652
4510
  }
3653
4511
  function isFile(p) {
3654
4512
  try {
3655
- return fs15.statSync(p).isFile();
4513
+ return fs20.statSync(p).isFile();
3656
4514
  } catch {
3657
4515
  return false;
3658
4516
  }
3659
4517
  }
3660
4518
  function isDir(p) {
3661
4519
  try {
3662
- return fs15.statSync(p).isDirectory();
4520
+ return fs20.statSync(p).isDirectory();
3663
4521
  } catch {
3664
4522
  return false;
3665
4523
  }
3666
4524
  }
3667
4525
  function isSymlink(p) {
3668
4526
  try {
3669
- return fs15.lstatSync(p).isSymbolicLink();
4527
+ return fs20.lstatSync(p).isSymbolicLink();
3670
4528
  } catch {
3671
4529
  return false;
3672
4530
  }
3673
4531
  }
3674
4532
  function readText(p) {
3675
- return fs15.readFileSync(p, "utf-8");
4533
+ return fs20.readFileSync(p, "utf-8");
3676
4534
  }
3677
4535
  function writeText(p, content) {
3678
- fs15.writeFileSync(p, content, "utf-8");
4536
+ fs20.writeFileSync(p, content, "utf-8");
3679
4537
  }
3680
4538
  function sortedGlobStems(directory, suffix) {
3681
4539
  let entries;
3682
4540
  try {
3683
- entries = fs15.readdirSync(directory);
4541
+ entries = fs20.readdirSync(directory);
3684
4542
  } catch {
3685
4543
  return [];
3686
4544
  }
@@ -3700,34 +4558,34 @@ function sortedGlobStems(directory, suffix) {
3700
4558
  function countZips(directory) {
3701
4559
  if (!isDir(directory)) return 0;
3702
4560
  let n = 0;
3703
- for (const name of fs15.readdirSync(directory)) {
4561
+ for (const name of fs20.readdirSync(directory)) {
3704
4562
  if (name.endsWith(".zip")) n += 1;
3705
4563
  }
3706
4564
  return n;
3707
4565
  }
3708
4566
  function atomicWrite0644(target, body, prefix) {
3709
- const dir = path13.dirname(target);
3710
- const tmpName = path13.join(
4567
+ const dir = path20.dirname(target);
4568
+ const tmpName = path20.join(
3711
4569
  dir,
3712
4570
  `${prefix}${process2.pid}.${crypto5.randomBytes(6).toString("hex")}.yml.tmp`
3713
4571
  );
3714
4572
  let fd = null;
3715
4573
  try {
3716
- fd = fs15.openSync(tmpName, "wx", 420);
3717
- fs15.writeFileSync(fd, body, "utf-8");
3718
- fs15.closeSync(fd);
4574
+ fd = fs20.openSync(tmpName, "wx", 420);
4575
+ fs20.writeFileSync(fd, body, "utf-8");
4576
+ fs20.closeSync(fd);
3719
4577
  fd = null;
3720
- fs15.chmodSync(tmpName, 420);
3721
- fs15.renameSync(tmpName, target);
4578
+ fs20.chmodSync(tmpName, 420);
4579
+ fs20.renameSync(tmpName, target);
3722
4580
  } catch (err) {
3723
4581
  if (fd !== null) {
3724
4582
  try {
3725
- fs15.closeSync(fd);
4583
+ fs20.closeSync(fd);
3726
4584
  } catch {
3727
4585
  }
3728
4586
  }
3729
4587
  try {
3730
- fs15.unlinkSync(tmpName);
4588
+ fs20.unlinkSync(tmpName);
3731
4589
  } catch {
3732
4590
  }
3733
4591
  throw err;
@@ -3762,12 +4620,12 @@ var LEGACY_SETTINGS_FILE = ".agent-settings";
3762
4620
  var LEGACY_BACKUP_FILE = ".agent-settings.backup.key-value";
3763
4621
  var SETTINGS_SUBDIR = ["agents", "settings"];
3764
4622
  function _canonical_settings_target(project_root) {
3765
- return path13.join(project_root, ...SETTINGS_SUBDIR, SETTINGS_FILE);
4623
+ return path20.join(project_root, ...SETTINGS_SUBDIR, SETTINGS_FILE);
3766
4624
  }
3767
4625
  function _resolve_settings_read(project_root) {
3768
4626
  const canonical = _canonical_settings_target(project_root);
3769
4627
  if (pathExists(canonical)) return canonical;
3770
- const legacy = path13.join(project_root, SETTINGS_FILE);
4628
+ const legacy = path20.join(project_root, SETTINGS_FILE);
3771
4629
  if (pathExists(legacy)) return legacy;
3772
4630
  return canonical;
3773
4631
  }
@@ -3833,9 +4691,9 @@ function fail(msg) {
3833
4691
  throw new SystemExitError(1);
3834
4692
  }
3835
4693
  function detect_package_root(project_root) {
3836
- const npm_path = path13.join(project_root, "node_modules", "@event4u", "agent-config");
4694
+ const npm_path = path20.join(project_root, "node_modules", "@event4u", "agent-config");
3837
4695
  if (isDir(npm_path)) return resolvePath(npm_path);
3838
- if (pathExists(path13.join(project_root, "src", "config", "profiles", "minimal.ini"))) {
4696
+ if (pathExists(path20.join(project_root, "src", "config", "profiles", "minimal.ini"))) {
3839
4697
  return project_root;
3840
4698
  }
3841
4699
  fail(
@@ -3843,12 +4701,12 @@ function detect_package_root(project_root) {
3843
4701
  );
3844
4702
  }
3845
4703
  function detect_package_type(package_root) {
3846
- if (package_root.split(path13.sep).includes("node_modules")) return "npm";
4704
+ if (package_root.split(path20.sep).includes("node_modules")) return "npm";
3847
4705
  return "local";
3848
4706
  }
3849
4707
  function detect_package_type_for_project(project_root, package_root) {
3850
4708
  const npm_path = resolvePath(
3851
- path13.join(project_root, "node_modules", "@event4u", "agent-config")
4709
+ path20.join(project_root, "node_modules", "@event4u", "agent-config")
3852
4710
  );
3853
4711
  const package_resolved = resolvePath(package_root);
3854
4712
  if (package_resolved === npm_path) return "npm";
@@ -3872,7 +4730,7 @@ function ensure_directory(p) {
3872
4730
  mkdirp(p);
3873
4731
  }
3874
4732
  function write_file(p, content) {
3875
- ensure_directory(path13.dirname(p));
4733
+ ensure_directory(path20.dirname(p));
3876
4734
  writeText(p, content);
3877
4735
  }
3878
4736
  function read_json_file(p) {
@@ -3893,50 +4751,6 @@ function write_json_file(p, data) {
3893
4751
  const content = jsonDumpsIndent(data, 4) + "\n";
3894
4752
  write_file(p, content);
3895
4753
  }
3896
- function _isPlainObject(v) {
3897
- return typeof v === "object" && v !== null && !Array.isArray(v);
3898
- }
3899
- function deepcopy(v) {
3900
- if (v === null || typeof v !== "object") return v;
3901
- if (Array.isArray(v)) return v.map((x) => deepcopy(x));
3902
- const out = {};
3903
- for (const k of Object.keys(v)) {
3904
- out[k] = deepcopy(v[k]);
3905
- }
3906
- return out;
3907
- }
3908
- function deep_merge(base, overlay) {
3909
- const result = deepcopy(base);
3910
- for (const key of Object.keys(overlay)) {
3911
- const value = overlay[key];
3912
- if (Object.prototype.hasOwnProperty.call(result, key) && _isPlainObject(result[key]) && _isPlainObject(value)) {
3913
- result[key] = deep_merge(
3914
- result[key],
3915
- value
3916
- );
3917
- } else {
3918
- result[key] = deepcopy(value);
3919
- }
3920
- }
3921
- return result;
3922
- }
3923
- function jsonEqual(a, b) {
3924
- if (a === b) return true;
3925
- if (typeof a !== typeof b) return false;
3926
- if (Array.isArray(a) || Array.isArray(b)) {
3927
- if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
3928
- return a.every((v, i) => jsonEqual(v, b[i]));
3929
- }
3930
- if (_isPlainObject(a) && _isPlainObject(b)) {
3931
- const ka = Object.keys(a);
3932
- const kb = Object.keys(b);
3933
- if (ka.length !== kb.length) return false;
3934
- return ka.every(
3935
- (k) => Object.prototype.hasOwnProperty.call(b, k) && jsonEqual(a[k], b[k])
3936
- );
3937
- }
3938
- return false;
3939
- }
3940
4754
  function merge_json_file(p, new_data, _force, label) {
3941
4755
  const new_entries = build_merge_entries(label, new_data);
3942
4756
  if (!pathExists(p)) {
@@ -3945,7 +4759,7 @@ function merge_json_file(p, new_data, _force, label) {
3945
4759
  return new_entries;
3946
4760
  }
3947
4761
  const existing = read_json_file(p);
3948
- const merged = deep_merge(existing, new_data);
4762
+ const merged = mergeHostConfig(existing, new_data, HOOK_SIGNATURES[label] ?? "", deepMerge);
3949
4763
  if (jsonEqual(merged, existing)) {
3950
4764
  skip(`${label} already configured`);
3951
4765
  return new_entries;
@@ -4043,7 +4857,7 @@ function _append_unknown_legacy(rendered, legacy_values, unknown_keys) {
4043
4857
  return rendered + "\n" + suffix;
4044
4858
  }
4045
4859
  function _migrate_legacy_if_present(project_root, template_body) {
4046
- const legacy_target = path13.join(project_root, LEGACY_SETTINGS_FILE);
4860
+ const legacy_target = path20.join(project_root, LEGACY_SETTINGS_FILE);
4047
4861
  if (!isFile(legacy_target)) return null;
4048
4862
  const legacy_text = readText(legacy_target);
4049
4863
  const [values, unknown] = _parse_legacy_settings(legacy_text);
@@ -4058,9 +4872,9 @@ function _migrate_legacy_if_present(project_root, template_body) {
4058
4872
  }
4059
4873
  }
4060
4874
  rendered = _append_unknown_legacy(rendered, values, unknown);
4061
- const backup_target = path13.join(project_root, LEGACY_BACKUP_FILE);
4875
+ const backup_target = path20.join(project_root, LEGACY_BACKUP_FILE);
4062
4876
  writeText(backup_target, legacy_text);
4063
- fs15.unlinkSync(legacy_target);
4877
+ fs20.unlinkSync(legacy_target);
4064
4878
  info(`Migrated legacy ${LEGACY_SETTINGS_FILE} \u2192 ${SETTINGS_FILE}`);
4065
4879
  info(`Backup saved to ${LEGACY_BACKUP_FILE}`);
4066
4880
  if (unknown.length > 0) {
@@ -4095,7 +4909,7 @@ function _render_template(template, profile_values) {
4095
4909
  return body;
4096
4910
  }
4097
4911
  function _load_valid_user_types(package_root) {
4098
- const directory = path13.join(package_root, USER_TYPES_DIR);
4912
+ const directory = path20.join(package_root, USER_TYPES_DIR);
4099
4913
  if (!isDir(directory)) return [];
4100
4914
  return sortedGlobStems(directory, ".yml");
4101
4915
  }
@@ -4152,8 +4966,8 @@ function splitlinesKeepends(text) {
4152
4966
  }
4153
4967
  function ensure_agent_settings(project_root, package_root, profile, force, user_type = "", packs = null) {
4154
4968
  const target = _canonical_settings_target(project_root);
4155
- const profile_source = path13.join(package_root, "src", "config", "profiles", `${profile}.ini`);
4156
- const template_source = path13.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");
4157
4971
  if (!pathExists(profile_source)) fail(`Missing profile preset: ${profile_source}`);
4158
4972
  if (!pathExists(template_source)) fail(`Missing settings template: ${template_source}`);
4159
4973
  const template = readText(template_source);
@@ -4167,21 +4981,21 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
4167
4981
  if (profile_values["rule_loading_tier"] !== profile) {
4168
4982
  const got = "rule_loading_tier" in profile_values ? `'${profile_values["rule_loading_tier"]}'` : "None";
4169
4983
  fail(
4170
- `Profile preset ${path13.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}`
4171
4985
  );
4172
4986
  }
4173
4987
  profile_values["user_type"] = _validate_user_type(package_root, user_type);
4174
4988
  let template_body = _render_template(template, profile_values);
4175
4989
  template_body = _inject_packs(template_body, packs ?? []);
4176
- const legacy_root = path13.join(project_root, SETTINGS_FILE);
4990
+ const legacy_root = path20.join(project_root, SETTINGS_FILE);
4177
4991
  if (isFile(legacy_root) && !pathExists(target)) {
4178
- mkdirp(path13.dirname(target));
4992
+ mkdirp(path20.dirname(target));
4179
4993
  writeText(target, readText(legacy_root));
4180
- fs15.unlinkSync(legacy_root);
4994
+ fs20.unlinkSync(legacy_root);
4181
4995
  success(`Migrated ${SETTINGS_FILE} \u2192 agents/settings/${SETTINGS_FILE} (ADR-038)`);
4182
4996
  return;
4183
4997
  }
4184
- const legacy_target = path13.join(project_root, LEGACY_SETTINGS_FILE);
4998
+ const legacy_target = path20.join(project_root, LEGACY_SETTINGS_FILE);
4185
4999
  if (isFile(legacy_target) && pathExists(target)) {
4186
5000
  warn(
4187
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.`
@@ -4198,7 +5012,7 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
4198
5012
  skip(`${SETTINGS_FILE} already exists`);
4199
5013
  return;
4200
5014
  }
4201
- mkdirp(path13.dirname(target));
5015
+ mkdirp(path20.dirname(target));
4202
5016
  write_file(target, template_body);
4203
5017
  const user_type_value = profile_values["user_type"] ?? "";
4204
5018
  const suffix = user_type_value ? `, user_type=${user_type_value}` : "";
@@ -4211,7 +5025,7 @@ function ensure_vscode_bridge(project_root, package_type, force) {
4211
5025
  const plugin_path = plugin_paths[package_type] ?? "./plugin/agent-config";
4212
5026
  const bridge = { "chat.pluginLocations": { [plugin_path]: true } };
4213
5027
  return merge_json_file(
4214
- path13.join(project_root, ".vscode", "settings.json"),
5028
+ path20.join(project_root, ".vscode", "settings.json"),
4215
5029
  bridge,
4216
5030
  force,
4217
5031
  ".vscode/settings.json"
@@ -4220,14 +5034,14 @@ function ensure_vscode_bridge(project_root, package_type, force) {
4220
5034
  function ensure_augment_bridge(project_root, force) {
4221
5035
  const bridge = { enabledPlugins: { "agent-config@event4u": true } };
4222
5036
  return merge_json_file(
4223
- path13.join(project_root, ".augment", "settings.json"),
5037
+ path20.join(project_root, ".augment", "settings.json"),
4224
5038
  bridge,
4225
5039
  force,
4226
5040
  ".augment/settings.json"
4227
5041
  );
4228
5042
  }
4229
- var AUGMENT_USER_DIR = path13.join(os3.homedir(), ".augment");
4230
- var AUGMENT_USER_HOOKS_DIR = path13.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");
4231
5045
  var AUGMENT_DISPATCHER_TRAMPOLINE = "augment-dispatcher.sh";
4232
5046
  var AUGMENT_LEGACY_TRAMPOLINES = [
4233
5047
  "augment-chat-history.sh",
@@ -4236,29 +5050,29 @@ var AUGMENT_LEGACY_TRAMPOLINES = [
4236
5050
  "augment-context-hygiene.sh"
4237
5051
  ];
4238
5052
  function _deploy_augment_trampoline(package_root, name, force) {
4239
- const src = path13.join(package_root, "scripts", "hooks", name);
5053
+ const src = path20.join(package_root, "scripts", "hooks", name);
4240
5054
  if (!pathExists(src)) {
4241
5055
  skip(`augment trampoline missing in package: ${src}`);
4242
5056
  return null;
4243
5057
  }
4244
5058
  mkdirp(AUGMENT_USER_HOOKS_DIR);
4245
- const dst = path13.join(AUGMENT_USER_HOOKS_DIR, name);
5059
+ const dst = path20.join(AUGMENT_USER_HOOKS_DIR, name);
4246
5060
  const src_text = readText(src);
4247
5061
  if (pathExists(dst) && readText(dst) === src_text && !force) {
4248
5062
  skip(`~/.augment/hooks/${name} already up to date`);
4249
5063
  } else {
4250
5064
  writeText(dst, src_text);
4251
- fs15.chmodSync(dst, 493);
5065
+ fs20.chmodSync(dst, 493);
4252
5066
  success(`~/.augment/hooks/${name} installed`);
4253
5067
  }
4254
5068
  return dst;
4255
5069
  }
4256
5070
  function _remove_legacy_augment_trampolines() {
4257
5071
  for (const name of AUGMENT_LEGACY_TRAMPOLINES) {
4258
- const legacy = path13.join(AUGMENT_USER_HOOKS_DIR, name);
5072
+ const legacy = path20.join(AUGMENT_USER_HOOKS_DIR, name);
4259
5073
  try {
4260
5074
  if (isFile(legacy)) {
4261
- fs15.unlinkSync(legacy);
5075
+ fs20.unlinkSync(legacy);
4262
5076
  skip(`removed legacy ~/.augment/hooks/${name}`);
4263
5077
  }
4264
5078
  } catch (err) {
@@ -4278,7 +5092,7 @@ function ensure_augment_user_hooks(package_root, force) {
4278
5092
  }
4279
5093
  const settings_patch = { hooks: per_event };
4280
5094
  return merge_json_file(
4281
- path13.join(AUGMENT_USER_DIR, "settings.json"),
5095
+ path20.join(AUGMENT_USER_DIR, "settings.json"),
4282
5096
  settings_patch,
4283
5097
  force,
4284
5098
  "~/.augment/settings.json"
@@ -4293,7 +5107,7 @@ function _heal_legacy_claude_plugin_ids(p) {
4293
5107
  if (!pathExists(p)) return [];
4294
5108
  const data = read_json_file(p);
4295
5109
  const enabled = data["enabledPlugins"];
4296
- if (!_isPlainObject(enabled)) return [];
5110
+ if (!isPlainObject(enabled)) return [];
4297
5111
  const removed = CLAUDE_LEGACY_PLUGIN_IDS.filter((pid) => pid in enabled);
4298
5112
  if (removed.length === 0) return [];
4299
5113
  for (const pid of removed) {
@@ -4303,7 +5117,7 @@ function _heal_legacy_claude_plugin_ids(p) {
4303
5117
  return removed;
4304
5118
  }
4305
5119
  function ensure_claude_bridge(project_root, force) {
4306
- const target = path13.join(project_root, ".claude", "settings.json");
5120
+ const target = path20.join(project_root, ".claude", "settings.json");
4307
5121
  const healed = _heal_legacy_claude_plugin_ids(target);
4308
5122
  for (const pid of healed) success(`.claude/settings.json: removed stale plugin id \`${pid}\``);
4309
5123
  const bridge = withHostEnv({ enabledPlugins: { [CLAUDE_PLUGIN_ID]: true } }, project_root, success);
@@ -4321,29 +5135,29 @@ function ensure_cursor_bridge(project_root, force) {
4321
5135
  }
4322
5136
  const bridge = { version: 1, hooks };
4323
5137
  return merge_json_file(
4324
- path13.join(project_root, ".cursor", "hooks.json"),
5138
+ path20.join(project_root, ".cursor", "hooks.json"),
4325
5139
  bridge,
4326
5140
  force,
4327
5141
  ".cursor/hooks.json"
4328
5142
  );
4329
5143
  }
4330
- var CURSOR_USER_DIR = path13.join(os3.homedir(), ".cursor");
4331
- var CURSOR_USER_HOOKS_DIR = path13.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");
4332
5146
  var CURSOR_DISPATCHER_TRAMPOLINE = "cursor-dispatcher.sh";
4333
5147
  function ensure_cursor_user_hooks(package_root, force) {
4334
- const src = path13.join(package_root, "scripts", "hooks", CURSOR_DISPATCHER_TRAMPOLINE);
5148
+ const src = path20.join(package_root, "scripts", "hooks", CURSOR_DISPATCHER_TRAMPOLINE);
4335
5149
  if (!pathExists(src)) {
4336
5150
  skip(`cursor trampoline missing in package: ${src}`);
4337
5151
  return [];
4338
5152
  }
4339
5153
  mkdirp(CURSOR_USER_HOOKS_DIR);
4340
- const dst = path13.join(CURSOR_USER_HOOKS_DIR, CURSOR_DISPATCHER_TRAMPOLINE);
5154
+ const dst = path20.join(CURSOR_USER_HOOKS_DIR, CURSOR_DISPATCHER_TRAMPOLINE);
4341
5155
  const src_text = readText(src);
4342
5156
  if (pathExists(dst) && readText(dst) === src_text && !force) {
4343
5157
  skip(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} already up to date`);
4344
5158
  } else {
4345
5159
  writeText(dst, src_text);
4346
- fs15.chmodSync(dst, 493);
5160
+ fs20.chmodSync(dst, 493);
4347
5161
  success(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} installed`);
4348
5162
  }
4349
5163
  const hooks = {};
@@ -4352,7 +5166,7 @@ function ensure_cursor_user_hooks(package_root, force) {
4352
5166
  }
4353
5167
  const settings_patch = { version: 1, hooks };
4354
5168
  return merge_json_file(
4355
- path13.join(CURSOR_USER_DIR, "hooks.json"),
5169
+ path20.join(CURSOR_USER_DIR, "hooks.json"),
4356
5170
  settings_patch,
4357
5171
  force,
4358
5172
  "~/.cursor/hooks.json"
@@ -4387,12 +5201,12 @@ exit 0
4387
5201
  `;
4388
5202
  }
4389
5203
  function ensure_cline_bridge(project_root, force) {
4390
- const hooks_dir = path13.join(project_root, ".clinerules", "hooks");
5204
+ const hooks_dir = path20.join(project_root, ".clinerules", "hooks");
4391
5205
  mkdirp(hooks_dir);
4392
5206
  const workspace_quoted = shlexQuote(resolvePath(project_root));
4393
5207
  let written = 0;
4394
5208
  for (const { slot, native } of hostBindings("cline")) {
4395
- const target = path13.join(hooks_dir, native);
5209
+ const target = path20.join(hooks_dir, native);
4396
5210
  const body = clineProjectHookBody(native, slot, workspace_quoted);
4397
5211
  if (pathExists(target) && readText(target) === body && !force) {
4398
5212
  continue;
@@ -4402,7 +5216,7 @@ function ensure_cline_bridge(project_root, force) {
4402
5216
  continue;
4403
5217
  }
4404
5218
  writeText(target, body);
4405
- fs15.chmodSync(target, 493);
5219
+ fs20.chmodSync(target, 493);
4406
5220
  written += 1;
4407
5221
  }
4408
5222
  if (written) {
@@ -4411,27 +5225,27 @@ function ensure_cline_bridge(project_root, force) {
4411
5225
  skip(".clinerules/hooks/ already up to date");
4412
5226
  }
4413
5227
  }
4414
- var CLINE_USER_DIR = path13.join(os3.homedir(), "Documents", "Cline", "Hooks");
5228
+ var CLINE_USER_DIR = path20.join(os6.homedir(), "Documents", "Cline", "Hooks");
4415
5229
  var CLINE_DISPATCHER_TRAMPOLINE = "cline-dispatcher.sh";
4416
5230
  function ensure_cline_user_hooks(package_root, force) {
4417
- const src = path13.join(package_root, "scripts", "hooks", CLINE_DISPATCHER_TRAMPOLINE);
5231
+ const src = path20.join(package_root, "scripts", "hooks", CLINE_DISPATCHER_TRAMPOLINE);
4418
5232
  if (!pathExists(src)) {
4419
5233
  skip(`cline trampoline missing in package: ${src}`);
4420
5234
  return;
4421
5235
  }
4422
5236
  mkdirp(CLINE_USER_DIR);
4423
- const trampoline = path13.join(CLINE_USER_DIR, CLINE_DISPATCHER_TRAMPOLINE);
5237
+ const trampoline = path20.join(CLINE_USER_DIR, CLINE_DISPATCHER_TRAMPOLINE);
4424
5238
  const src_text = readText(src);
4425
5239
  if (pathExists(trampoline) && readText(trampoline) === src_text && !force) {
4426
5240
  skip(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} already up to date`);
4427
5241
  } else {
4428
5242
  writeText(trampoline, src_text);
4429
- fs15.chmodSync(trampoline, 493);
5243
+ fs20.chmodSync(trampoline, 493);
4430
5244
  success(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} installed`);
4431
5245
  }
4432
5246
  const trampoline_quoted = shlexQuote(trampoline);
4433
5247
  for (const { slot, native } of hostBindings("cline")) {
4434
- const wrapper = path13.join(CLINE_USER_DIR, native);
5248
+ const wrapper = path20.join(CLINE_USER_DIR, native);
4435
5249
  const body = `#!/usr/bin/env bash
4436
5250
  # Generated by event4u/agent-config \u2014 DO NOT EDIT.
4437
5251
  # User-scope Cline hook for ${native} \u2192 agent-config ${slot}.
@@ -4441,7 +5255,7 @@ exec ${trampoline_quoted} ${slot} ${native}
4441
5255
  continue;
4442
5256
  }
4443
5257
  writeText(wrapper, body);
4444
- fs15.chmodSync(wrapper, 493);
5258
+ fs20.chmodSync(wrapper, 493);
4445
5259
  }
4446
5260
  }
4447
5261
  function _windsurf_dispatch_command(ac_event, native) {
@@ -4457,29 +5271,29 @@ function ensure_windsurf_bridge(project_root, force) {
4457
5271
  }
4458
5272
  const bridge = { hooks };
4459
5273
  return merge_json_file(
4460
- path13.join(project_root, ".windsurf", "hooks.json"),
5274
+ path20.join(project_root, ".windsurf", "hooks.json"),
4461
5275
  bridge,
4462
5276
  force,
4463
5277
  ".windsurf/hooks.json"
4464
5278
  );
4465
5279
  }
4466
- var WINDSURF_USER_DIR = path13.join(os3.homedir(), ".codeium", "windsurf");
4467
- var WINDSURF_USER_HOOKS_DIR = path13.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");
4468
5282
  var WINDSURF_DISPATCHER_TRAMPOLINE = "windsurf-dispatcher.sh";
4469
5283
  function ensure_windsurf_user_hooks(package_root, force) {
4470
- const src = path13.join(package_root, "scripts", "hooks", WINDSURF_DISPATCHER_TRAMPOLINE);
5284
+ const src = path20.join(package_root, "scripts", "hooks", WINDSURF_DISPATCHER_TRAMPOLINE);
4471
5285
  if (!pathExists(src)) {
4472
5286
  skip(`windsurf trampoline missing in package: ${src}`);
4473
5287
  return [];
4474
5288
  }
4475
5289
  mkdirp(WINDSURF_USER_HOOKS_DIR);
4476
- const dst = path13.join(WINDSURF_USER_HOOKS_DIR, WINDSURF_DISPATCHER_TRAMPOLINE);
5290
+ const dst = path20.join(WINDSURF_USER_HOOKS_DIR, WINDSURF_DISPATCHER_TRAMPOLINE);
4477
5291
  const src_text = readText(src);
4478
5292
  if (pathExists(dst) && readText(dst) === src_text && !force) {
4479
5293
  skip(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} already up to date`);
4480
5294
  } else {
4481
5295
  writeText(dst, src_text);
4482
- fs15.chmodSync(dst, 493);
5296
+ fs20.chmodSync(dst, 493);
4483
5297
  success(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} installed`);
4484
5298
  }
4485
5299
  const hooks = {};
@@ -4491,7 +5305,7 @@ function ensure_windsurf_user_hooks(package_root, force) {
4491
5305
  }
4492
5306
  const settings_patch = { hooks };
4493
5307
  return merge_json_file(
4494
- path13.join(WINDSURF_USER_DIR, "hooks.json"),
5308
+ path20.join(WINDSURF_USER_DIR, "hooks.json"),
4495
5309
  settings_patch,
4496
5310
  force,
4497
5311
  "~/.codeium/windsurf/hooks.json"
@@ -4513,43 +5327,43 @@ function _gemini_hooks_dict(command_factory) {
4513
5327
  function ensure_gemini_bridge(project_root, force) {
4514
5328
  const bridge = { hooks: _gemini_hooks_dict(_gemini_dispatch_command) };
4515
5329
  return merge_json_file(
4516
- path13.join(project_root, ".gemini", "settings.json"),
5330
+ path20.join(project_root, ".gemini", "settings.json"),
4517
5331
  bridge,
4518
5332
  force,
4519
5333
  ".gemini/settings.json"
4520
5334
  );
4521
5335
  }
4522
- var GEMINI_USER_DIR = path13.join(os3.homedir(), ".gemini");
4523
- var GEMINI_USER_HOOKS_DIR = path13.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");
4524
5338
  var GEMINI_DISPATCHER_TRAMPOLINE = "gemini-dispatcher.sh";
4525
5339
  function ensure_gemini_user_hooks(package_root, force) {
4526
- const src = path13.join(package_root, "scripts", "hooks", GEMINI_DISPATCHER_TRAMPOLINE);
5340
+ const src = path20.join(package_root, "scripts", "hooks", GEMINI_DISPATCHER_TRAMPOLINE);
4527
5341
  if (!pathExists(src)) {
4528
5342
  skip(`gemini trampoline missing in package: ${src}`);
4529
5343
  return [];
4530
5344
  }
4531
5345
  mkdirp(GEMINI_USER_HOOKS_DIR);
4532
- const dst = path13.join(GEMINI_USER_HOOKS_DIR, GEMINI_DISPATCHER_TRAMPOLINE);
5346
+ const dst = path20.join(GEMINI_USER_HOOKS_DIR, GEMINI_DISPATCHER_TRAMPOLINE);
4533
5347
  const src_text = readText(src);
4534
5348
  if (pathExists(dst) && readText(dst) === src_text && !force) {
4535
5349
  skip(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} already up to date`);
4536
5350
  } else {
4537
5351
  writeText(dst, src_text);
4538
- fs15.chmodSync(dst, 493);
5352
+ fs20.chmodSync(dst, 493);
4539
5353
  success(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} installed`);
4540
5354
  }
4541
5355
  const settings_patch = {
4542
5356
  hooks: _gemini_hooks_dict((ac_event, native) => `${dst} ${ac_event} ${native}`)
4543
5357
  };
4544
5358
  return merge_json_file(
4545
- path13.join(GEMINI_USER_DIR, "settings.json"),
5359
+ path20.join(GEMINI_USER_DIR, "settings.json"),
4546
5360
  settings_patch,
4547
5361
  force,
4548
5362
  "~/.gemini/settings.json"
4549
5363
  );
4550
5364
  }
4551
5365
  function ensure_copilot_bridge(project_root, force) {
4552
- const target = path13.join(project_root, ".github", "plugin", "marketplace.json");
5366
+ const target = path20.join(project_root, ".github", "plugin", "marketplace.json");
4553
5367
  const bridge = {
4554
5368
  marketplace: {
4555
5369
  name: "event4u-agent-marketplace",
@@ -4592,7 +5406,7 @@ See \`docs/setup/per-ide/roocode.md\` for the full activation guide.
4592
5406
  Run \`./agent-config --help\` for available commands.
4593
5407
  `;
4594
5408
  function ensure_roocode_bridge(project_root, force) {
4595
- const target = path13.join(project_root, ".roo", "rules", "agent-config.md");
5409
+ const target = path20.join(project_root, ".roo", "rules", "agent-config.md");
4596
5410
  if (pathExists(target) && !force) {
4597
5411
  skip(".roo/rules/agent-config.md already exists");
4598
5412
  return;
@@ -4614,7 +5428,7 @@ To wire Claude Desktop to this project's rules, run:
4614
5428
  Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
4615
5429
  `;
4616
5430
  function ensure_claude_desktop_bridge(project_root, force) {
4617
- const target = path13.join(project_root, ".claude-desktop", "agent-config.md");
5431
+ const target = path20.join(project_root, ".claude-desktop", "agent-config.md");
4618
5432
  if (pathExists(target) && !force) {
4619
5433
  skip(".claude-desktop/agent-config.md already exists");
4620
5434
  return;
@@ -4639,7 +5453,7 @@ Or pass \`--read .aider/agent-config.md\` on the command line.
4639
5453
  Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
4640
5454
  `;
4641
5455
  function ensure_aider_bridge(project_root, force) {
4642
- const target = path13.join(project_root, ".aider", "agent-config.md");
5456
+ const target = path20.join(project_root, ".aider", "agent-config.md");
4643
5457
  if (pathExists(target) && !force) {
4644
5458
  skip(".aider/agent-config.md already exists");
4645
5459
  return;
@@ -4658,7 +5472,7 @@ developers where the rules and skills live.
4658
5472
  Canonical rule and skill source: \`.augment/\` (see project \`AGENTS.md\`).
4659
5473
  `;
4660
5474
  function ensure_codex_bridge(project_root, force) {
4661
- const target = path13.join(project_root, ".codex", "agent-config.md");
5475
+ const target = path20.join(project_root, ".codex", "agent-config.md");
4662
5476
  if (pathExists(target) && !force) {
4663
5477
  skip(".codex/agent-config.md already exists");
4664
5478
  return;
@@ -4676,7 +5490,7 @@ rules per session. The canonical rule and skill source lives under
4676
5490
  orientation).
4677
5491
  `;
4678
5492
  function ensure_continue_bridge(project_root, force) {
4679
- const target = path13.join(project_root, ".continue", "rules", "agent-config.md");
5493
+ const target = path20.join(project_root, ".continue", "rules", "agent-config.md");
4680
5494
  if (pathExists(target) && !force) {
4681
5495
  skip(".continue/rules/agent-config.md already exists");
4682
5496
  return;
@@ -4707,7 +5521,7 @@ orientation).
4707
5521
  See \`docs/setup/per-ide/kilocode.md\` for the full activation guide.
4708
5522
  `;
4709
5523
  function ensure_kilocode_bridge(project_root, force) {
4710
- const target = path13.join(project_root, ".kilocode", "rules", "agent-config.md");
5524
+ const target = path20.join(project_root, ".kilocode", "rules", "agent-config.md");
4711
5525
  if (pathExists(target) && !force) {
4712
5526
  skip(".kilocode/rules/agent-config.md already exists");
4713
5527
  return;
@@ -4734,7 +5548,7 @@ canonical source (or symlink it):
4734
5548
  Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
4735
5549
  `;
4736
5550
  function ensure_zed_bridge(project_root, force) {
4737
- const target = path13.join(project_root, ".zed", "agent-config.md");
5551
+ const target = path20.join(project_root, ".zed", "agent-config.md");
4738
5552
  if (pathExists(target) && !force) {
4739
5553
  skip(".zed/agent-config.md already exists");
4740
5554
  return;
@@ -4755,7 +5569,7 @@ rules into your JetBrains profile.
4755
5569
  Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
4756
5570
  `;
4757
5571
  function ensure_jetbrains_bridge(project_root, force) {
4758
- const target = path13.join(project_root, ".jetbrains", "agent-config.md");
5572
+ const target = path20.join(project_root, ".jetbrains", "agent-config.md");
4759
5573
  if (pathExists(target) && !force) {
4760
5574
  skip(".jetbrains/agent-config.md already exists");
4761
5575
  return;
@@ -4786,7 +5600,7 @@ session. The canonical rule and skill source lives under \`.augment/\`
4786
5600
  See \`docs/setup/per-ide/kiro.md\` for the full activation guide.
4787
5601
  `;
4788
5602
  function ensure_kiro_bridge(project_root, force) {
4789
- const target = path13.join(project_root, ".kiro", "steering", "agent-config.md");
5603
+ const target = path20.join(project_root, ".kiro", "steering", "agent-config.md");
4790
5604
  if (pathExists(target) && !force) {
4791
5605
  skip(".kiro/steering/agent-config.md already exists");
4792
5606
  return;
@@ -4823,35 +5637,35 @@ var SMOKE_BRIDGE_PATHS = {
4823
5637
  };
4824
5638
  function dirHasEntries(p) {
4825
5639
  try {
4826
- return fs15.readdirSync(p).length > 0;
5640
+ return fs20.readdirSync(p).length > 0;
4827
5641
  } catch {
4828
5642
  return false;
4829
5643
  }
4830
5644
  }
4831
5645
  function _resolve_tsx_invocation(scriptPath, scriptArgs) {
4832
5646
  const binName = process2.platform === "win32" ? "tsx.cmd" : "tsx";
4833
- let dir = path13.dirname(scriptPath);
5647
+ let dir = path20.dirname(scriptPath);
4834
5648
  for (; ; ) {
4835
- const candidate = path13.join(dir, "node_modules", ".bin", binName);
5649
+ const candidate = path20.join(dir, "node_modules", ".bin", binName);
4836
5650
  if (isFile(candidate)) {
4837
5651
  return { command: candidate, args: [scriptPath, ...scriptArgs] };
4838
5652
  }
4839
- const parent = path13.dirname(dir);
5653
+ const parent = path20.dirname(dir);
4840
5654
  if (parent === dir) break;
4841
5655
  dir = parent;
4842
5656
  }
4843
5657
  return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
4844
5658
  }
4845
5659
  function _smoke_test_hooks(project_root, package_root) {
4846
- const dispatcher = path13.join(package_root, "scripts", "hooks", "dispatch_hook.ts");
4847
- const manifest = path13.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");
4848
5662
  if (!isFile(dispatcher) || !isFile(manifest)) return 0;
4849
5663
  const failed = [];
4850
5664
  const skipped = [];
4851
5665
  const passed = [];
4852
5666
  for (const [platform, native] of smokeProbeEvents()) {
4853
5667
  const rel_bridge = SMOKE_BRIDGE_PATHS[platform] ?? "";
4854
- const bridge_path = rel_bridge ? path13.join(project_root, rel_bridge) : null;
5668
+ const bridge_path = rel_bridge ? path20.join(project_root, rel_bridge) : null;
4855
5669
  const bridge_present = Boolean(
4856
5670
  bridge_path && (isFile(bridge_path) || isDir(bridge_path) && dirHasEntries(bridge_path))
4857
5671
  );
@@ -4900,7 +5714,7 @@ function _smoke_test_hooks(project_root, package_root) {
4900
5714
  failed.push(`${platform}: dispatcher did not emit JSON plan`);
4901
5715
  continue;
4902
5716
  }
4903
- const concerns = _isPlainObject(plan) ? plan["concerns"] : void 0;
5717
+ const concerns = isPlainObject(plan) ? plan["concerns"] : void 0;
4904
5718
  if (!Array.isArray(concerns)) {
4905
5719
  failed.push(`${platform}: plan.concerns missing or not a list`);
4906
5720
  continue;
@@ -4982,47 +5796,6 @@ var PROJECT_BRIDGE_MARKERS = {
4982
5796
  jetbrains: ".jetbrains/agent-config.md",
4983
5797
  kiro: ".kiro/steering/agent-config.md"
4984
5798
  };
4985
- var _CLAUDE_SKILL_BUNDLE = [
4986
- ["dist/agent-src/rules", "rules"],
4987
- ["dist/agent-src/skills", "skills"],
4988
- ["dist/agent-src/commands", "commands"],
4989
- ["dist/agent-src/personas", "personas"]
4990
- ];
4991
- var GLOBAL_DEPLOY_SOURCES = {
4992
- "claude-code": _CLAUDE_SKILL_BUNDLE,
4993
- augment: [
4994
- ["dist/agent-src/rules", "rules"],
4995
- ["dist/agent-src/skills", "skills"],
4996
- ["dist/agent-src/commands", "commands"],
4997
- ["dist/agent-src/contexts", "contexts"],
4998
- ["dist/agent-src/personas", "personas"],
4999
- ["dist/agent-src/templates", "templates"]
5000
- ],
5001
- cursor: [
5002
- ["dist/agent-src/rules", "rules"],
5003
- ["dist/agent-src/commands", "commands"],
5004
- ["dist/agent-src/personas", "personas"]
5005
- ],
5006
- windsurf: [["dist/agent-src/rules", "rules"]],
5007
- cline: [["dist/agent-src/rules", ""]],
5008
- "gemini-cli": _CLAUDE_SKILL_BUNDLE,
5009
- codex: _CLAUDE_SKILL_BUNDLE,
5010
- continue: _CLAUDE_SKILL_BUNDLE,
5011
- roocode: _CLAUDE_SKILL_BUNDLE,
5012
- kilocode: _CLAUDE_SKILL_BUNDLE,
5013
- qoder: _CLAUDE_SKILL_BUNDLE,
5014
- opencode: _CLAUDE_SKILL_BUNDLE,
5015
- trae: _CLAUDE_SKILL_BUNDLE,
5016
- antigravity: _CLAUDE_SKILL_BUNDLE,
5017
- codebuddy: _CLAUDE_SKILL_BUNDLE,
5018
- droid: _CLAUDE_SKILL_BUNDLE,
5019
- warp: _CLAUDE_SKILL_BUNDLE,
5020
- kiro: [
5021
- ["dist/agent-src/rules", "rules"],
5022
- ["dist/agent-src/skills", "steering"],
5023
- ["dist/agent-src/personas", "personas"]
5024
- ]
5025
- };
5026
5799
  function claudeDesktopMarkerBody(lockfile, anchor, bundles_dir, bundle_count) {
5027
5800
  return `# agent-config \u2014 Claude Desktop marker
5028
5801
 
@@ -5051,9 +5824,9 @@ To remove this marker, delete this file.
5051
5824
  `;
5052
5825
  }
5053
5826
  var _CLAUDE_DESKTOP_BUNDLES_SUBPATH = "claude-desktop/bundles";
5054
- var GLOBAL_ROOT = path13.join(os3.homedir(), ".event4u", "agent-config");
5055
- var GLOBAL_USER_SETTINGS_PATH = path13.join(GLOBAL_ROOT, ".agent-user.yml");
5056
- var GLOBAL_AGENT_SETTINGS_PATH = path13.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");
5057
5830
  function _bridge_marker(tool_id, scope) {
5058
5831
  if (scope === "global") return USER_SCOPE_PATHS[tool_id] ?? "";
5059
5832
  return PROJECT_BRIDGE_MARKERS[tool_id] ?? "";
@@ -5099,10 +5872,10 @@ function _load_yaml_doc(p) {
5099
5872
  return {};
5100
5873
  }
5101
5874
  const data = yamlSafeLoad(text);
5102
- return _isPlainObject(data) ? data : {};
5875
+ return isPlainObject(data) ? data : {};
5103
5876
  }
5104
5877
  function _load_default_settings(package_root) {
5105
- const template_source = path13.join(package_root, "src", "config", "agent-settings.template.yml");
5878
+ const template_source = path20.join(package_root, "src", "config", "agent-settings.template.yml");
5106
5879
  if (!pathExists(template_source)) return {};
5107
5880
  let text;
5108
5881
  try {
@@ -5112,15 +5885,15 @@ function _load_default_settings(package_root) {
5112
5885
  }
5113
5886
  const rendered = text.split(RULE_LOADING_TIER_PLACEHOLDER).join(DEFAULT_PROFILE).split(USER_TYPE_PLACEHOLDER).join("");
5114
5887
  const data = yamlSafeLoad(rendered);
5115
- return _isPlainObject(data) ? data : {};
5888
+ return isPlainObject(data) ? data : {};
5116
5889
  }
5117
5890
  var RULE_LAYER_CHOICES = ["global", "project", "both-acknowledged"];
5118
5891
  function _suppress_rule_layer(project_root, suppress_dir) {
5119
- const target = path13.join(project_root, ".claude", "settings.local.json");
5892
+ const target = path20.join(project_root, ".claude", "settings.local.json");
5120
5893
  const existing = pathExists(target) ? read_json_file(target) : {};
5121
5894
  let real_dir = suppress_dir;
5122
5895
  try {
5123
- real_dir = fs15.realpathSync(suppress_dir);
5896
+ real_dir = fs20.realpathSync(suppress_dir);
5124
5897
  } catch {
5125
5898
  real_dir = suppress_dir;
5126
5899
  }
@@ -5131,8 +5904,7 @@ function _suppress_rule_layer(project_root, suppress_dir) {
5131
5904
  success(`.claude/settings.local.json: claudeMdExcludes += ${entry}`);
5132
5905
  }
5133
5906
  function _gate_rule_layer_overlap(project_root, layer, dry_run) {
5134
- const global_dir = path13.join(os3.homedir(), ".claude", "rules");
5135
- const project_dir = path13.join(project_root, ".claude", "rules");
5907
+ const [global_dir, project_dir] = hostRuleLayerDirs(project_root);
5136
5908
  const g = readRuleLayer(global_dir);
5137
5909
  const p = readRuleLayer(project_dir);
5138
5910
  if (g === null || p === null) return true;
@@ -5220,9 +5992,9 @@ function detect_scope(cwd) {
5220
5992
  if (pathExists(_resolve_settings_read(cwd))) {
5221
5993
  return ["project", `existing ${SETTINGS_FILE}`];
5222
5994
  }
5223
- const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(path13.join(cwd, m))) ?? null;
5224
- const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(path13.join(cwd, d))) ?? null;
5225
- const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(path13.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;
5226
5998
  if (has_manifest && (has_ai_dir || has_ai_file)) {
5227
5999
  const marker = has_ai_dir || has_ai_file;
5228
6000
  return ["prompt", `manifest (${has_manifest}) + AI-tool config (${marker})`];
@@ -5243,7 +6015,7 @@ function readLineSyncRaw(promptText) {
5243
6015
  for (; ; ) {
5244
6016
  let n;
5245
6017
  try {
5246
- n = fs15.readSync(0, buf, 0, 1, null);
6018
+ n = fs20.readSync(0, buf, 0, 1, null);
5247
6019
  } catch (err) {
5248
6020
  const code = err.code;
5249
6021
  if (code === "EAGAIN") {
@@ -5326,26 +6098,26 @@ function _update_installed_tools_manifest(project_root, tools, scope, force, fil
5326
6098
  }
5327
6099
  write_manifest(target, version, entries);
5328
6100
  if (!state.QUIET) {
5329
- const rel = isRelativeTo(target, project_root) ? path13.relative(project_root, target) : target;
6101
+ const rel = isRelativeTo(target, project_root) ? path20.relative(project_root, target) : target;
5330
6102
  info(`Manifest updated: ${rel}`);
5331
6103
  }
5332
6104
  return 0;
5333
6105
  }
5334
6106
  function isRelativeTo(child, parent) {
5335
- const rel = path13.relative(parent, child);
5336
- return rel === "" || !rel.startsWith("..") && !path13.isAbsolute(rel);
6107
+ const rel = path20.relative(parent, child);
6108
+ return rel === "" || !rel.startsWith("..") && !path20.isAbsolute(rel);
5337
6109
  }
5338
6110
  function _resolve_package_root_for_global() {
5339
- const here = resolvePath(_HERE);
5340
- const candidate = path13.dirname(path13.dirname(path13.dirname(here)));
5341
- if (!pathExists(path13.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"))) {
5342
6114
  fail(
5343
6115
  `Could not locate agent-config package root from ${here}. Expected src/config/profiles/minimal.ini at the parent directory.`
5344
6116
  );
5345
6117
  }
5346
6118
  return candidate;
5347
6119
  }
5348
- var CONSUMER_BRIDGE_MARKER_RELPATH = path13.join("agents", ".event4u-bridge.yml");
6120
+ var CONSUMER_BRIDGE_MARKER_RELPATH = path20.join("agents", ".event4u-bridge.yml");
5349
6121
  var MIGRATE_LEGACY_YAML_FILES = [".agent-settings.yml", ".agent-user.yml"];
5350
6122
  var MIGRATE_LEGACY_TOOL_DIRS = [".augment", ".claude", ".cursor"];
5351
6123
  var AGENT_CONFIG_PACKAGE_NAME = "@event4u/agent-config";
@@ -5353,7 +6125,7 @@ function _is_agent_config_source_repo(project_root) {
5353
6125
  if (process2.env["AGENT_CONFIG_CONSUMER_MODE"] === "1") {
5354
6126
  return [false, "consumer-mode-override"];
5355
6127
  }
5356
- const pkg_json = path13.join(project_root, "package.json");
6128
+ const pkg_json = path20.join(project_root, "package.json");
5357
6129
  if (isFile(pkg_json)) {
5358
6130
  let data = {};
5359
6131
  try {
@@ -5361,17 +6133,17 @@ function _is_agent_config_source_repo(project_root) {
5361
6133
  } catch {
5362
6134
  data = {};
5363
6135
  }
5364
- if (_isPlainObject(data) && data["name"] === AGENT_CONFIG_PACKAGE_NAME) {
6136
+ if (isPlainObject(data) && data["name"] === AGENT_CONFIG_PACKAGE_NAME) {
5365
6137
  return [true, "package.json:name"];
5366
6138
  }
5367
6139
  }
5368
- if (isDir(path13.join(project_root, ".agent-src.uncondensed"))) {
6140
+ if (isDir(path20.join(project_root, ".agent-src.uncondensed"))) {
5369
6141
  return [true, ".agent-src.uncondensed/"];
5370
6142
  }
5371
- const packages_dir = path13.join(project_root, "packages");
6143
+ const packages_dir = path20.join(project_root, "packages");
5372
6144
  if (isDir(packages_dir)) {
5373
- for (const child of fs15.readdirSync(packages_dir)) {
5374
- if (isDir(path13.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"))) {
5375
6147
  return [true, `packages/${child}/.agent-src.uncondensed/`];
5376
6148
  }
5377
6149
  }
@@ -5389,17 +6161,17 @@ function _detect_legacy_for_migration(project_root) {
5389
6161
  }
5390
6162
  return [];
5391
6163
  }
5392
- if (isFile(path13.join(project_root, INSTALL_MODE_MARKER_REL))) return [];
6164
+ if (isFile(path20.join(project_root, INSTALL_MODE_MARKER_REL))) return [];
5393
6165
  const found = [];
5394
6166
  for (const name of MIGRATE_LEGACY_YAML_FILES) {
5395
- if (isFile(path13.join(project_root, name))) {
6167
+ if (isFile(path20.join(project_root, name))) {
5396
6168
  found.push(name);
5397
- } else if (isFile(path13.join(project_root, "settings", name))) {
6169
+ } else if (isFile(path20.join(project_root, "settings", name))) {
5398
6170
  found.push(`settings/${name}`);
5399
6171
  }
5400
6172
  }
5401
6173
  for (const name of MIGRATE_LEGACY_TOOL_DIRS) {
5402
- const p = path13.join(project_root, name);
6174
+ const p = path20.join(project_root, name);
5403
6175
  if (isDir(p) && !isSymlink(p)) {
5404
6176
  found.push(`${name}/`);
5405
6177
  }
@@ -5411,7 +6183,7 @@ function _prompt_migrate_to_global(project_root, artefacts) {
5411
6183
  process2.stdout.write("\n");
5412
6184
  warn("Legacy project-local artefacts detected \u2014 pre-ADR-020 layout:");
5413
6185
  for (const rel of artefacts) {
5414
- info(` ${path13.join(project_root, rel)}`);
6186
+ info(` ${path20.join(project_root, rel)}`);
5415
6187
  }
5416
6188
  info("The unified `agent-config migrate` sweeps these in one pass.");
5417
6189
  info("The wizard recreates fresh config afterwards.");
@@ -5440,22 +6212,22 @@ function _run_migrate_to_global(project_root) {
5440
6212
  }
5441
6213
  }
5442
6214
  function _format_global_root_for_marker(global_root) {
5443
- const home = resolvePath(os3.homedir());
6215
+ const home = resolvePath(os6.homedir());
5444
6216
  const resolved = resolvePath(global_root);
5445
- const rel = path13.relative(home, resolved);
5446
- if (rel === "" || rel.startsWith("..") || path13.isAbsolute(rel)) {
6217
+ const rel = path20.relative(home, resolved);
6218
+ if (rel === "" || rel.startsWith("..") || path20.isAbsolute(rel)) {
5447
6219
  return global_root;
5448
6220
  }
5449
- return `~/${rel.split(path13.sep).join("/")}`;
6221
+ return `~/${rel.split(path20.sep).join("/")}`;
5450
6222
  }
5451
6223
  function _remove_legacy_consumer_bridge_marker(project_root, env = null) {
5452
6224
  const env_map = env ?? process2.env;
5453
6225
  if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return null;
5454
- if (isDir(path13.join(project_root, ".agent-src.uncondensed"))) return null;
5455
- const target = path13.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);
5456
6228
  if (!isFile(target)) return null;
5457
6229
  try {
5458
- fs15.rmSync(target);
6230
+ fs20.rmSync(target);
5459
6231
  } catch {
5460
6232
  return null;
5461
6233
  }
@@ -5469,7 +6241,7 @@ var PROJECT_ANCHOR_TOOLS = {
5469
6241
  function _write_per_tool_project_anchors(project_root, tools, env = null, now = null) {
5470
6242
  const env_map = env ?? process2.env;
5471
6243
  if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return [];
5472
- if (isDir(path13.join(project_root, ".agent-src.uncondensed"))) return [];
6244
+ if (isDir(path20.join(project_root, ".agent-src.uncondensed"))) return [];
5473
6245
  const global_root_str = _format_global_root_for_marker(
5474
6246
  event4u_root(env_map)
5475
6247
  );
@@ -5478,8 +6250,8 @@ function _write_per_tool_project_anchors(project_root, tools, env = null, now =
5478
6250
  for (const tool_id of Object.keys(PROJECT_ANCHOR_TOOLS).sort()) {
5479
6251
  const rel_path = PROJECT_ANCHOR_TOOLS[tool_id];
5480
6252
  if (!tools.has(tool_id)) continue;
5481
- const target = path13.join(project_root, rel_path);
5482
- mkdirp(path13.dirname(target));
6253
+ const target = path20.join(project_root, rel_path);
6254
+ mkdirp(path20.dirname(target));
5483
6255
  const body = `# event4u/agent-config \u2014 per-tool project anchor (auto-written).
5484
6256
  # Spec: docs/contracts/consumer-bridge.md \xA7 Per-tool anchor strategy.
5485
6257
  # Tool: ${tool_id}. Resolves the global install directly \u2014 no
@@ -5497,7 +6269,7 @@ installed_at: ${stamp}
5497
6269
  }
5498
6270
  var PACKAGE_TAG_ID = "event4u/agent-config";
5499
6271
  function _inject_package_tag(target, source, package_root) {
5500
- if (path13.extname(target) !== ".md") return;
6272
+ if (path20.extname(target) !== ".md") return;
5501
6273
  let text;
5502
6274
  try {
5503
6275
  text = readText(target);
@@ -5525,8 +6297,8 @@ function _inject_package_tag(target, source, package_root) {
5525
6297
  resolved_src = source;
5526
6298
  }
5527
6299
  if (package_root !== null) {
5528
- const rel = path13.relative(resolvePath(package_root), resolved_src);
5529
- if (rel !== "" && !rel.startsWith("..") && !path13.isAbsolute(rel)) {
6300
+ const rel = path20.relative(resolvePath(package_root), resolved_src);
6301
+ if (rel !== "" && !rel.startsWith("..") && !path20.isAbsolute(rel)) {
5530
6302
  source_value = rel;
5531
6303
  } else {
5532
6304
  source_value = resolved_src;
@@ -5561,7 +6333,7 @@ function _escapes_package_root(resolved, package_root) {
5561
6333
  if (package_root === null) return false;
5562
6334
  let root;
5563
6335
  try {
5564
- root = fs15.realpathSync(package_root);
6336
+ root = fs20.realpathSync(package_root);
5565
6337
  } catch {
5566
6338
  return false;
5567
6339
  }
@@ -5587,7 +6359,7 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5587
6359
  if (file_filter !== null && !file_filter(src)) return [0, 0, written_paths];
5588
6360
  let resolved_src = src;
5589
6361
  try {
5590
- resolved_src = fs15.realpathSync(src);
6362
+ resolved_src = fs20.realpathSync(src);
5591
6363
  } catch {
5592
6364
  resolved_src = src;
5593
6365
  }
@@ -5595,14 +6367,14 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5595
6367
  warn(`refused: ${src} dereferences outside the package root \u2014 not copied`);
5596
6368
  return [0, 0, written_paths];
5597
6369
  }
5598
- mkdirp(path13.dirname(dest));
6370
+ mkdirp(path20.dirname(dest));
5599
6371
  const decision = tracker.resolve(dest, force);
5600
6372
  if (decision === "preserve") {
5601
6373
  tracker.preserve(dest, resolved_src, package_root);
5602
6374
  _log_tx_entry("skip", dest);
5603
6375
  return [0, 1, written_paths];
5604
6376
  }
5605
- fs15.copyFileSync(src, dest);
6377
+ fs20.copyFileSync(src, dest);
5606
6378
  _inject_package_tag(dest, src, package_root);
5607
6379
  _log_tx_entry("write", dest);
5608
6380
  written_paths.push(dest);
@@ -5611,11 +6383,11 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5611
6383
  mkdirp(dest);
5612
6384
  const walk = (node) => {
5613
6385
  const acc = [];
5614
- const names = fs15.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);
5615
6387
  for (const name of names) {
5616
- const entry = path13.join(node, name);
6388
+ const entry = path20.join(node, name);
5617
6389
  acc.push(entry);
5618
- const lst = fs15.lstatSync(entry);
6390
+ const lst = fs20.lstatSync(entry);
5619
6391
  if (lst.isDirectory() && !lst.isSymbolicLink()) {
5620
6392
  acc.push(...walk(entry));
5621
6393
  }
@@ -5623,9 +6395,9 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5623
6395
  return acc;
5624
6396
  };
5625
6397
  for (const entry of walk(src)) {
5626
- const rel = path13.relative(src, entry);
5627
- const target = path13.join(dest, rel);
5628
- const lst = fs15.lstatSync(entry);
6398
+ const rel = path20.relative(src, entry);
6399
+ const target = path20.join(dest, rel);
6400
+ const lst = fs20.lstatSync(entry);
5629
6401
  if (lst.isDirectory() && !lst.isSymbolicLink()) {
5630
6402
  mkdirp(target);
5631
6403
  continue;
@@ -5633,8 +6405,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5633
6405
  let resolvedIsDir = false;
5634
6406
  let resolved = entry;
5635
6407
  try {
5636
- resolved = fs15.realpathSync(entry);
5637
- resolvedIsDir = fs15.statSync(entry).isDirectory();
6408
+ resolved = fs20.realpathSync(entry);
6409
+ resolvedIsDir = fs20.statSync(entry).isDirectory();
5638
6410
  } catch {
5639
6411
  resolvedIsDir = false;
5640
6412
  }
@@ -5666,8 +6438,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
5666
6438
  _log_tx_entry("skip", target);
5667
6439
  continue;
5668
6440
  }
5669
- mkdirp(path13.dirname(target));
5670
- fs15.copyFileSync(resolved, target);
6441
+ mkdirp(path20.dirname(target));
6442
+ fs20.copyFileSync(resolved, target);
5671
6443
  _inject_package_tag(target, resolved, package_root);
5672
6444
  _log_tx_entry("write", target);
5673
6445
  written += 1;
@@ -5680,7 +6452,7 @@ function _claude_desktop_bundles_dir() {
5680
6452
  }
5681
6453
  function _write_claude_desktop_marker(force, lockfile_path2, bundles_dir, bundle_count) {
5682
6454
  const anchor = expanduser3(USER_SCOPE_PATHS["claude-desktop"]);
5683
- const target = path13.join(anchor, "agent-config.md");
6455
+ const target = path20.join(anchor, "agent-config.md");
5684
6456
  mkdirp(anchor);
5685
6457
  const body = claudeDesktopMarkerBody(lockfile_path2, anchor, bundles_dir, bundle_count);
5686
6458
  if (tracker.resolve(target, force) === "preserve") {
@@ -5705,27 +6477,15 @@ function _deploy_claude_desktop(force, package_root, lockfile_path2) {
5705
6477
  return [bundle_count, 0, "deployed", [bundles_dir, ...marker_paths]];
5706
6478
  }
5707
6479
  var _CLAUDE_FLAT_WRAPPER_EXTRA = /* @__PURE__ */ new Set(["commit"]);
5708
- 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()) {
5709
6481
  const wrapped = [];
5710
6482
  const collisions = [];
5711
- const reserved = [];
5712
- const commands_dir = path13.join(anchor, "commands");
5713
- let flat_entries = [];
5714
- try {
5715
- flat_entries = fs15.readdirSync(commands_dir).filter((f) => f.endsWith(".md"));
5716
- } catch {
5717
- }
5718
- for (const fname of flat_entries.sort()) {
5719
- const slug = fname.slice(0, -".md".length);
5720
- if (!is_claude_builtin_name(slug)) continue;
5721
- fs15.rmSync(path13.join(commands_dir, fname), { force: true });
5722
- current_files.delete(`commands/${fname}`);
5723
- reserved.push(slug);
5724
- }
6483
+ const commands_dir = path20.join(anchor, "commands");
6484
+ const { reserved, foreign } = sweepReservedNames(commands_dir, current_files, is_claude_builtin_name, recorded_files);
5725
6485
  const eligible = new Set(_CLAUDE_FLAT_WRAPPER_EXTRA);
5726
6486
  try {
5727
6487
  const manifest = JSON.parse(
5728
- fs15.readFileSync(path13.join(package_root, "dist", "discovery", "discovery-manifest.json"), "utf8")
6488
+ fs20.readFileSync(path20.join(package_root, "dist", "discovery", "discovery-manifest.json"), "utf8")
5729
6489
  );
5730
6490
  for (const a of manifest.artefacts ?? []) {
5731
6491
  if (a.category !== "command" || typeof a.slug !== "string") continue;
@@ -5736,27 +6496,27 @@ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files
5736
6496
  }
5737
6497
  for (const slug of [...eligible].sort()) {
5738
6498
  const flat_rel = `commands/${slug}.md`;
5739
- const flat_abs = path13.join(anchor, "commands", `${slug}.md`);
5740
- if (!fs15.existsSync(flat_abs)) continue;
5741
- const skill_dir = path13.join(anchor, "skills", slug);
5742
- if (fs15.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)) {
5743
6503
  collisions.push(slug);
5744
6504
  continue;
5745
6505
  }
5746
- let body = fs15.readFileSync(flat_abs, "utf8");
6506
+ let body = fs20.readFileSync(flat_abs, "utf8");
5747
6507
  if (body.startsWith("---\n") && !/^name:/m.test(body.split("\n---")[0] ?? "")) {
5748
6508
  body = body.replace("---\n", `---
5749
6509
  name: ${slug}
5750
6510
  `);
5751
6511
  }
5752
- fs15.mkdirSync(skill_dir, { recursive: true });
5753
- fs15.writeFileSync(path13.join(skill_dir, "SKILL.md"), body, "utf8");
5754
- fs15.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 });
5755
6515
  current_files.delete(flat_rel);
5756
6516
  current_files.add(`skills/${slug}/SKILL.md`);
5757
6517
  wrapped.push(slug);
5758
6518
  }
5759
- return { wrapped, collisions, reserved };
6519
+ return { wrapped, collisions, reserved, foreign };
5760
6520
  }
5761
6521
  function _deploy_global_content(tools, force, package_root, lockfile_path2) {
5762
6522
  const results = {};
@@ -5783,8 +6543,8 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
5783
6543
  const written_paths = [];
5784
6544
  let current_files = /* @__PURE__ */ new Set();
5785
6545
  for (const [src_rel, dest_sub] of plan) {
5786
- const src = path13.join(package_root, src_rel);
5787
- const dest = dest_sub ? path13.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;
5788
6548
  const rule_filter = _rule_filter_for_source(src_rel, rule_scope);
5789
6549
  const [w, s, paths] = _copy_dir_dereferencing_symlinks(
5790
6550
  src,
@@ -5806,15 +6566,31 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
5806
6566
  );
5807
6567
  }
5808
6568
  if (tool_id === "claude-code") {
5809
- 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
+ );
5810
6573
  rewriteAndReport(
5811
- path13.join(anchor, "rules"),
6574
+ path20.join(anchor, "rules"),
5812
6575
  state.QUIET,
5813
6576
  info,
5814
6577
  warn,
5815
6578
  res,
5816
- new Set(tracker.conflictState.preserved.map((p) => path13.resolve(p)))
6579
+ preserved_now
5817
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);
5818
6594
  }
5819
6595
  const missing_targets = _verify_deploy_targets(anchor, plan);
5820
6596
  if (missing_targets.length > 0) {
@@ -5856,10 +6632,10 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
5856
6632
  results[tool_id] = [written_total, skipped_total, "deployed", written_paths];
5857
6633
  if (tool_id === "claude-code") {
5858
6634
  try {
5859
- const manifest = path13.join(package_root, "src", "scripts", "hook_manifest.yaml");
6635
+ const manifest = path20.join(package_root, "src", "scripts", "hook_manifest.yaml");
5860
6636
  const matrix = build_claude_hook_matrix(manifest);
5861
6637
  const res = ensure_managed_hooks(
5862
- path13.join(anchor, "settings.json"),
6638
+ path20.join(anchor, "settings.json"),
5863
6639
  matrix
5864
6640
  );
5865
6641
  if (!state.QUIET) {
@@ -5896,7 +6672,7 @@ function _preview_global_reap(tools, package_root) {
5896
6672
  const anchor = expanduser3(anchor_raw);
5897
6673
  let current_files = /* @__PURE__ */ new Set();
5898
6674
  for (const [src_rel, dest_sub] of plan) {
5899
- const src = path13.join(package_root, src_rel);
6675
+ const src = path20.join(package_root, src_rel);
5900
6676
  current_files = setUnion(
5901
6677
  current_files,
5902
6678
  expected_deploy_files(
@@ -5930,14 +6706,14 @@ function _preview_global_reap(tools, package_root) {
5930
6706
  function _verify_deploy_targets(anchor, plan) {
5931
6707
  const missing = [];
5932
6708
  for (const [, dest_sub] of plan) {
5933
- const target = dest_sub ? path13.join(anchor, dest_sub) : anchor;
6709
+ const target = dest_sub ? path20.join(anchor, dest_sub) : anchor;
5934
6710
  const label = dest_sub || ".";
5935
6711
  if (!isDir(target)) {
5936
6712
  missing.push(label);
5937
6713
  continue;
5938
6714
  }
5939
6715
  try {
5940
- const entries = fs15.readdirSync(target);
6716
+ const entries = fs20.readdirSync(target);
5941
6717
  if (entries.length === 0) missing.push(label);
5942
6718
  } catch {
5943
6719
  missing.push(label);
@@ -5955,54 +6731,30 @@ function _resolve_global_settings_doc() {
5955
6731
  }
5956
6732
  function _resolve_global_settings_path() {
5957
6733
  const root = event4u_root();
5958
- const canonical = path13.join(root, "settings", SETTINGS_FILE);
6734
+ const canonical = path20.join(root, "settings", SETTINGS_FILE);
5959
6735
  if (pathExists(canonical)) return canonical;
5960
- const legacy = path13.join(root, SETTINGS_FILE);
6736
+ const legacy = path20.join(root, SETTINGS_FILE);
5961
6737
  if (pathExists(legacy)) return legacy;
5962
6738
  return null;
5963
6739
  }
5964
6740
  function _resolve_scoped_projection(package_root) {
5965
6741
  const doc = _resolve_global_settings_doc() ?? _load_default_settings(package_root);
5966
- const projection = _isPlainObject(doc["projection"]) ? doc["projection"] : {};
6742
+ const projection = isPlainObject(doc["projection"]) ? doc["projection"] : {};
5967
6743
  const mode = projectionModeOf(projection["mode"]);
5968
- const runtime = _isPlainObject(doc["runtime"]) ? doc["runtime"] : {};
6744
+ const runtime = isPlainObject(doc["runtime"]) ? doc["runtime"] : {};
5969
6745
  const active_packs_raw = runtime["active_packs"];
5970
6746
  const active_packs = Array.isArray(active_packs_raw) ? active_packs_raw.filter((v) => typeof v === "string") : [];
5971
6747
  return { mode, active_packs };
5972
6748
  }
5973
6749
  function _resolve_global_rule_scope(package_root) {
5974
- const settings_path = _resolve_global_settings_path();
5975
- if (settings_path === null) {
5976
- try {
5977
- return ruleScopeFromSettings(_load_default_settings(package_root), package_root);
5978
- } catch {
5979
- return LEGACY_ALL;
5980
- }
5981
- }
5982
- let text;
5983
- try {
5984
- text = readText(settings_path);
5985
- } catch (e) {
5986
- warn(
5987
- `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.`
5988
- );
5989
- return LEGACY_ALL;
5990
- }
5991
- const parsed = yamlSafeLoad(text);
5992
- if (!_isPlainObject(parsed)) {
5993
- warn(
5994
- `${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.`
5995
- );
5996
- return LEGACY_ALL;
5997
- }
5998
- try {
5999
- return ruleScopeFromSettings(parsed, package_root);
6000
- } catch (e) {
6001
- warn(
6002
- `could not derive rule scope from ${settings_path} (${String(e)}) \u2014 falling back to legacy-all; ALL rules will be installed.`
6003
- );
6004
- return LEGACY_ALL;
6005
- }
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
+ });
6006
6758
  }
6007
6759
  function _rule_filter_for_source(src_rel, scope) {
6008
6760
  if (src_rel !== RULE_SOURCE_REL) return null;
@@ -6068,7 +6820,7 @@ function install_global(tools, force, project_root = null, core_only = false) {
6068
6820
  info(` schema_version=1, agent_config_version=${installed_version}`);
6069
6821
  info(` tools=${merged_tools.join(",")}`);
6070
6822
  }
6071
- if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path13.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"))) {
6072
6824
  const drift = collect_drift(project_root);
6073
6825
  if (!state.QUIET) {
6074
6826
  process2.stdout.write("\n");
@@ -6182,19 +6934,19 @@ function install_global(tools, force, project_root = null, core_only = false) {
6182
6934
  }
6183
6935
  }
6184
6936
  }
6185
- if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path13.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"))) {
6186
6938
  const files_by_tool = filesByToolFromDeploy(deploy_results);
6187
6939
  const rc = _update_installed_tools_manifest(project_root, tools, "global", force, files_by_tool);
6188
6940
  if (rc !== 0) return rc;
6189
6941
  const removed_marker = _remove_legacy_consumer_bridge_marker(project_root);
6190
6942
  if (removed_marker !== null && !state.QUIET) {
6191
- const rel = isRelativeTo(removed_marker, project_root) ? path13.relative(project_root, removed_marker) : removed_marker;
6943
+ const rel = isRelativeTo(removed_marker, project_root) ? path20.relative(project_root, removed_marker) : removed_marker;
6192
6944
  info(`Removed legacy bridge marker: ${rel}`);
6193
6945
  }
6194
6946
  const anchor_paths = _write_per_tool_project_anchors(project_root, tools);
6195
6947
  if (anchor_paths.length > 0 && !state.QUIET) {
6196
6948
  for (const p of anchor_paths) {
6197
- const rel = isRelativeTo(p, project_root) ? path13.relative(project_root, p) : p;
6949
+ const rel = isRelativeTo(p, project_root) ? path20.relative(project_root, p) : p;
6198
6950
  info(`Project anchor written: ${rel}`);
6199
6951
  }
6200
6952
  }
@@ -6230,8 +6982,8 @@ function install_global(tools, force, project_root = null, core_only = false) {
6230
6982
  }
6231
6983
  function _catalogue_truncation_warnings(deploy_results, project_root) {
6232
6984
  const log_candidates = [
6233
- path13.join(event4u_root(), "state", "skill-catalogue.jsonl"),
6234
- ...project_root ? [path13.join(project_root, OBSERVATION_LOG)] : []
6985
+ path20.join(event4u_root(), "state", "skill-catalogue.jsonl"),
6986
+ ...project_root ? [path20.join(project_root, OBSERVATION_LOG)] : []
6235
6987
  ];
6236
6988
  const records = log_candidates.flatMap((p) => readObservationLog(p));
6237
6989
  if (records.length === 0) return [];
@@ -6254,13 +7006,13 @@ function _catalogue_truncation_warnings(deploy_results, project_root) {
6254
7006
  function _scoped_migration_notice(deploy_results, project_root, package_root, probe) {
6255
7007
  if (!isInteractiveSession(probe)) return [];
6256
7008
  const log_candidates = [
6257
- path13.join(event4u_root(), "state", "skill-catalogue.jsonl"),
6258
- ...project_root ? [path13.join(project_root, OBSERVATION_LOG)] : []
7009
+ path20.join(event4u_root(), "state", "skill-catalogue.jsonl"),
7010
+ ...project_root ? [path20.join(project_root, OBSERVATION_LOG)] : []
6259
7011
  ];
6260
7012
  const limits = knownHostLimits(log_candidates.flatMap((p) => readObservationLog(p)));
6261
7013
  if (limits.size === 0) return [];
6262
7014
  const resolved = _resolve_scoped_projection(package_root);
6263
- const settings_path = _resolve_global_settings_path() ?? path13.join(event4u_root(), "settings", SETTINGS_FILE);
7015
+ const settings_path = _resolve_global_settings_path() ?? path20.join(event4u_root(), "settings", SETTINGS_FILE);
6264
7016
  for (const tool_id of Object.keys(deploy_results).sort()) {
6265
7017
  const [, , status] = deploy_results[tool_id];
6266
7018
  if (status !== "deployed") continue;
@@ -6279,8 +7031,8 @@ function _scoped_migration_notice(deploy_results, project_root, package_root, pr
6279
7031
  }
6280
7032
  return [];
6281
7033
  }
6282
- var SETTINGS_SURFACE_REL = path13.join("state", "settings-surface.json");
6283
- var SETTINGS_DELTA_REL = path13.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");
6284
7036
  function _current_settings_surface(version) {
6285
7037
  const jsonSchema = zodToJsonSchema(settingsSchema, {
6286
7038
  name: "AgentSettings",
@@ -6291,20 +7043,20 @@ function _current_settings_surface(version) {
6291
7043
  }
6292
7044
  function _write_settings_surface_snapshot(installed_version) {
6293
7045
  const root = event4u_root();
6294
- const surface_path = path13.join(root, SETTINGS_SURFACE_REL);
6295
- const delta_path = path13.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);
6296
7048
  const next = _current_settings_surface(installed_version);
6297
7049
  let previous = null;
6298
7050
  try {
6299
- const parsed = JSON.parse(fs15.readFileSync(surface_path, "utf8"));
7051
+ const parsed = JSON.parse(fs20.readFileSync(surface_path, "utf8"));
6300
7052
  if (parsed !== null && typeof parsed === "object" && parsed.entries !== void 0) previous = parsed;
6301
7053
  } catch {
6302
7054
  }
6303
7055
  if (previous !== null && previous.version !== next.version) {
6304
7056
  const delta = computeSurfaceDelta(previous, next);
6305
7057
  if (delta.changes.length > 0) {
6306
- fs15.mkdirSync(path13.dirname(delta_path), { recursive: true, mode: 448 });
6307
- fs15.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)}
6308
7060
  `, { mode: 384 });
6309
7061
  if (!state.QUIET) {
6310
7062
  const counts = {};
@@ -6316,8 +7068,8 @@ function _write_settings_surface_snapshot(installed_version) {
6316
7068
  }
6317
7069
  }
6318
7070
  }
6319
- fs15.mkdirSync(path13.dirname(surface_path), { recursive: true, mode: 448 });
6320
- fs15.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)}
6321
7073
  `, { mode: 384 });
6322
7074
  }
6323
7075
  function arrayStrEqual(a, b) {
@@ -6533,17 +7285,17 @@ function _is_tool_enabled(tools, tool_id) {
6533
7285
  return tools.has(tool_id);
6534
7286
  }
6535
7287
  function _minimal_templates_root() {
6536
- const start = resolvePath(_HERE);
7288
+ const start = resolvePath(_HERE2);
6537
7289
  const chain = [start];
6538
7290
  let cur = start;
6539
7291
  for (; ; ) {
6540
- const parent = path13.dirname(cur);
7292
+ const parent = path20.dirname(cur);
6541
7293
  if (parent === cur) break;
6542
7294
  chain.push(parent);
6543
7295
  cur = parent;
6544
7296
  }
6545
7297
  for (const ancestor of chain) {
6546
- const candidate = path13.join(ancestor, "src", "templates", "minimal");
7298
+ const candidate = path20.join(ancestor, "src", "templates", "minimal");
6547
7299
  if (isDir(candidate)) return candidate;
6548
7300
  }
6549
7301
  fail("Could not locate src/templates/minimal/ \u2014 package install is corrupt.");
@@ -6551,9 +7303,9 @@ function _minimal_templates_root() {
6551
7303
  var INSTALL_MODE_MARKER_REL = "agents/.agent-state/install-mode.txt";
6552
7304
  function _write_install_mode_marker(project_root, mode) {
6553
7305
  if (mode !== "minimal" && mode !== "full") return;
6554
- const marker = path13.join(project_root, INSTALL_MODE_MARKER_REL);
7306
+ const marker = path20.join(project_root, INSTALL_MODE_MARKER_REL);
6555
7307
  try {
6556
- mkdirp(path13.dirname(marker));
7308
+ mkdirp(path20.dirname(marker));
6557
7309
  writeText(marker, `${mode}
6558
7310
  `);
6559
7311
  } catch {
@@ -6562,7 +7314,7 @@ function _write_install_mode_marker(project_root, mode) {
6562
7314
  function install_minimal(target_root_in, force, user_type = "") {
6563
7315
  let target_root = resolvePath(target_root_in);
6564
7316
  mkdirp(target_root);
6565
- const parent = path13.dirname(target_root);
7317
+ const parent = path20.dirname(target_root);
6566
7318
  if (parent !== target_root) {
6567
7319
  const existing = find_project_root_with_anchor(parent);
6568
7320
  if (existing !== null && existing[0] !== target_root) {
@@ -6573,21 +7325,21 @@ function install_minimal(target_root_in, force, user_type = "") {
6573
7325
  }
6574
7326
  }
6575
7327
  const templates = _minimal_templates_root();
6576
- const settings_src = path13.join(templates, SETTINGS_FILE);
6577
- const overrides_gitkeep_src = path13.join(templates, "overrides-gitkeep");
6578
- const overrides_readme_src = path13.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");
6579
7331
  if (!isFile(settings_src)) fail(`Bundled minimal settings template missing under ${templates}`);
6580
7332
  if (!isFile(overrides_gitkeep_src) || !isFile(overrides_readme_src)) {
6581
7333
  fail(`Bundled overrides scaffold templates missing under ${templates}`);
6582
7334
  }
6583
7335
  info(`Minimal init \u2192 ${target_root}`);
6584
- const overrides_root = path13.join(target_root, "agents", "overrides");
7336
+ const overrides_root = path20.join(target_root, "agents", "overrides");
6585
7337
  mkdirp(overrides_root);
6586
7338
  const gitkeep_body = readText(overrides_gitkeep_src);
6587
7339
  for (const sub of ["rules", "skills", "commands"]) {
6588
- const sub_dir = path13.join(overrides_root, sub);
7340
+ const sub_dir = path20.join(overrides_root, sub);
6589
7341
  mkdirp(sub_dir);
6590
- const gitkeep_dst = path13.join(sub_dir, ".gitkeep");
7342
+ const gitkeep_dst = path20.join(sub_dir, ".gitkeep");
6591
7343
  if (pathExists(gitkeep_dst) && !force) {
6592
7344
  skip(`agents/overrides/${sub}/.gitkeep already exists (use --force to overwrite)`);
6593
7345
  } else {
@@ -6595,7 +7347,7 @@ function install_minimal(target_root_in, force, user_type = "") {
6595
7347
  success(`Wrote agents/overrides/${sub}/.gitkeep`);
6596
7348
  }
6597
7349
  }
6598
- const readme_dst = path13.join(overrides_root, "README.md");
7350
+ const readme_dst = path20.join(overrides_root, "README.md");
6599
7351
  if (pathExists(readme_dst) && !force) {
6600
7352
  skip("agents/overrides/README.md already exists (use --force to overwrite)");
6601
7353
  } else {
@@ -6613,14 +7365,14 @@ function install_minimal(target_root_in, force, user_type = "") {
6613
7365
  personal:
6614
7366
  user_type: ${user_type}
6615
7367
  `;
6616
- mkdirp(path13.dirname(settings_dst));
7368
+ mkdirp(path20.dirname(settings_dst));
6617
7369
  writeText(settings_dst, body);
6618
7370
  success(`Wrote ${SETTINGS_FILE} (user_type=${user_type})`);
6619
7371
  }
6620
7372
  }
6621
7373
  const removed_marker = _remove_legacy_consumer_bridge_marker(target_root);
6622
7374
  if (removed_marker !== null) {
6623
- const rel = isRelativeTo(removed_marker, target_root) ? path13.relative(target_root, removed_marker) : removed_marker;
7375
+ const rel = isRelativeTo(removed_marker, target_root) ? path20.relative(target_root, removed_marker) : removed_marker;
6624
7376
  success(`Removed legacy bridge marker: ${rel}`);
6625
7377
  }
6626
7378
  _write_install_mode_marker(target_root, "minimal");
@@ -6694,7 +7446,7 @@ function run_interactive_init(project_root, force) {
6694
7446
  );
6695
7447
  return 0;
6696
7448
  }
6697
- const target = path13.join(project_root, _LOCAL_CONFIG_FILE);
7449
+ const target = path20.join(project_root, _LOCAL_CONFIG_FILE);
6698
7450
  if (pathExists(target) && !force) {
6699
7451
  warn(
6700
7452
  `${_LOCAL_CONFIG_FILE} already exists; re-run with --force to overwrite. Skipping interactive init.`
@@ -6721,7 +7473,7 @@ function run_interactive_init(project_root, force) {
6721
7473
  warn(`Could not write ${target}: ${String(exc)}`);
6722
7474
  return 1;
6723
7475
  }
6724
- success(`Wrote ${path13.relative(project_root, target)} (${user_type} / ${stack} / ${verbosity})`);
7476
+ success(`Wrote ${path20.relative(project_root, target)} (${user_type} / ${stack} / ${verbosity})`);
6725
7477
  return 0;
6726
7478
  }
6727
7479
  var _WIZARD_READY_RE = /^WIZARD_READY (http:\/\/(?:127\.0\.0\.1|localhost):\d+\/\S*)\r?$/;
@@ -6739,12 +7491,12 @@ function _wizard_should_launch(opts) {
6739
7491
  return [true, ""];
6740
7492
  }
6741
7493
  function _wizard_cli_dist(_project_root) {
6742
- const package_root = path13.dirname(path13.dirname(path13.dirname(resolvePath(_HERE))));
6743
- const cli = path13.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");
6744
7496
  return pathExists(cli) ? cli : null;
6745
7497
  }
6746
7498
  function _server_info_path() {
6747
- return path13.join(os3.homedir(), ".event4u", "agent-config", "local-server.json");
7499
+ return path20.join(os6.homedir(), ".event4u", "agent-config", "local-server.json");
6748
7500
  }
6749
7501
  function _pid_is_agent_config(pid) {
6750
7502
  let res;
@@ -6761,7 +7513,7 @@ function _pid_is_agent_config(pid) {
6761
7513
  }
6762
7514
  function unlinkMissingOk(p) {
6763
7515
  try {
6764
- fs15.unlinkSync(p);
7516
+ fs20.unlinkSync(p);
6765
7517
  } catch {
6766
7518
  }
6767
7519
  }
@@ -6839,14 +7591,14 @@ function _wizard_spawn(project_root, pass_project_root = true) {
6839
7591
  }
6840
7592
  function _wizard_run_sync(cmd, env, cli) {
6841
7593
  const total = _WIZARD_TIMEOUTS.reduce((a, b) => a + b, 0);
6842
- const log_path = path13.join(
6843
- os3.tmpdir(),
7594
+ const log_path = path20.join(
7595
+ os6.tmpdir(),
6844
7596
  `agent-config-wizard-${process2.pid}-${Date.now()}.log`
6845
7597
  );
6846
7598
  let child;
6847
7599
  let log_fd = null;
6848
7600
  try {
6849
- log_fd = fs15.openSync(log_path, "w");
7601
+ log_fd = fs20.openSync(log_path, "w");
6850
7602
  child = spawn(cmd[0], cmd.slice(1), {
6851
7603
  env,
6852
7604
  detached: true,
@@ -6864,7 +7616,7 @@ function _wizard_run_sync(cmd, env, cli) {
6864
7616
  } finally {
6865
7617
  if (log_fd !== null) {
6866
7618
  try {
6867
- fs15.closeSync(log_fd);
7619
+ fs20.closeSync(log_fd);
6868
7620
  } catch {
6869
7621
  }
6870
7622
  }
@@ -7041,7 +7793,7 @@ function main2(argv) {
7041
7793
  } catch (exc) {
7042
7794
  fail(`--apply-payload JSON parse error: ${String(exc)}`);
7043
7795
  }
7044
- 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");
7045
7797
  const pl = payload;
7046
7798
  const schema_version = pl["schema_version"];
7047
7799
  if (schema_version !== "wizard-v2" && schema_version !== "installer-v1") {
@@ -7060,13 +7812,13 @@ function main2(argv) {
7060
7812
  opts.scope = "global";
7061
7813
  }
7062
7814
  const settings = pl["settings"];
7063
- if (_isPlainObject(settings)) {
7815
+ if (isPlainObject(settings)) {
7064
7816
  const rule_loading_tier = settings["rule_loading_tier"] || settings["cost_profile"];
7065
7817
  if (typeof rule_loading_tier === "string" && rule_loading_tier) {
7066
7818
  opts.profile = rule_loading_tier;
7067
7819
  }
7068
7820
  const personal = settings["personal"];
7069
- if (_isPlainObject(personal)) {
7821
+ if (isPlainObject(personal)) {
7070
7822
  const user_type = personal["user_type"];
7071
7823
  if (typeof user_type === "string" && user_type) {
7072
7824
  opts.user_type = user_type;
@@ -7114,8 +7866,8 @@ function main2(argv) {
7114
7866
  const target_root = resolvePath(
7115
7867
  opts.custom_path || opts.project || process2.env["PROJECT_ROOT"] || process2.cwd()
7116
7868
  );
7117
- const minimal_package_root = path13.dirname(
7118
- path13.dirname(path13.dirname(_minimal_templates_root()))
7869
+ const minimal_package_root = path20.dirname(
7870
+ path20.dirname(path20.dirname(_minimal_templates_root()))
7119
7871
  );
7120
7872
  const validated_user_type = _validate_user_type(minimal_package_root, opts.user_type);
7121
7873
  return install_minimal(target_root, opts.force, validated_user_type);
@@ -7151,7 +7903,7 @@ function main2(argv) {
7151
7903
  return rc2;
7152
7904
  }
7153
7905
  const project_root = custom_path || resolvePath(opts.project || process2.env["PROJECT_ROOT"] || process2.cwd());
7154
- const is_first_run = !pathExists(path13.join(project_root, SETTINGS_FILE));
7906
+ const is_first_run = !pathExists(path20.join(project_root, SETTINGS_FILE));
7155
7907
  tracker.begin(project_root);
7156
7908
  let rc = _main_project_install(opts, project_root, parsed_tools, is_first_run);
7157
7909
  if (rc === 0 && opts.interactive) {
@@ -7196,8 +7948,8 @@ function _read_consumer_auto_switch(project_root) {
7196
7948
  } catch {
7197
7949
  return "suggest";
7198
7950
  }
7199
- const model = _isPlainObject(data) ? data["model"] : null;
7200
- 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;
7201
7953
  if (typeof value === "string" && ["auto", "suggest", "off"].includes(value.trim().toLowerCase())) {
7202
7954
  return value.trim().toLowerCase();
7203
7955
  }
@@ -7210,23 +7962,23 @@ function _team_setup_hint_line(project_root) {
7210
7962
  } catch {
7211
7963
  data = {};
7212
7964
  }
7213
- const ai_team = _isPlainObject(data) ? data["ai_team"] : null;
7214
- 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;
7215
7967
  const suppressed = flag === true || typeof flag === "string" && ["true", "yes", "on", "1"].includes(flag.trim().toLowerCase());
7216
7968
  if (suppressed) return null;
7217
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.";
7218
7970
  }
7219
7971
  function finalize_claude_model_tiers(project_root) {
7220
- const claude_skills = path13.join(project_root, ".claude", "skills");
7221
- const augment_skills = path13.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");
7222
7974
  if (!isDir(claude_skills) || !isDir(augment_skills)) return 0;
7223
7975
  if (_read_consumer_auto_switch(project_root) !== "auto") return 0;
7224
7976
  let rendered = 0;
7225
- const entries = fs15.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);
7226
7978
  for (const name of entries) {
7227
- const entry = path13.join(claude_skills, name);
7228
- const src_dir = path13.join(augment_skills, name);
7229
- const src_md = path13.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");
7230
7982
  let tier;
7231
7983
  try {
7232
7984
  tier = read_model_tier(src_md);
@@ -7235,22 +7987,22 @@ function finalize_claude_model_tiers(project_root) {
7235
7987
  }
7236
7988
  if (tier === null || !(tier in TIER_TO_CLAUDE_MODEL) || !isDir(src_dir)) continue;
7237
7989
  if (isSymlink(entry) || isFile(entry)) {
7238
- fs15.unlinkSync(entry);
7990
+ fs20.unlinkSync(entry);
7239
7991
  } else if (isDir(entry)) {
7240
- fs15.rmSync(entry, { recursive: true, force: true });
7992
+ fs20.rmSync(entry, { recursive: true, force: true });
7241
7993
  }
7242
7994
  mkdirp(entry);
7243
- const srcFiles = fs15.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);
7244
7996
  for (const fname of srcFiles) {
7245
7997
  if (fname === "SKILL.md") {
7246
7998
  writeText(
7247
- path13.join(entry, "SKILL.md"),
7999
+ path20.join(entry, "SKILL.md"),
7248
8000
  render_native_model_md(readText(src_md), tier)
7249
8001
  );
7250
8002
  } else {
7251
- fs15.symlinkSync(
7252
- path13.join("../../../.augment/skills", name, fname),
7253
- path13.join(entry, fname)
8003
+ fs20.symlinkSync(
8004
+ path20.join("../../../.augment/skills", name, fname),
8005
+ path20.join(entry, fname)
7254
8006
  );
7255
8007
  }
7256
8008
  }
@@ -7268,7 +8020,7 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
7268
8020
  let package_type;
7269
8021
  if (opts.package) {
7270
8022
  package_root = resolvePath(opts.package);
7271
- if (!pathExists(path13.join(package_root, "src", "config", "profiles", "minimal.ini"))) {
8023
+ if (!pathExists(path20.join(package_root, "src", "config", "profiles", "minimal.ini"))) {
7272
8024
  fail(`Invalid --package path (missing src/config/profiles/minimal.ini): ${package_root}`);
7273
8025
  }
7274
8026
  package_type = detect_package_type_for_project(project_root, package_root);
@@ -7406,19 +8158,21 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
7406
8158
  if (will_launch) {
7407
8159
  return _wizard_spawn(project_root);
7408
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`);
7409
8163
  return 0;
7410
8164
  }
7411
8165
  function _resolvedArgv1() {
7412
8166
  if (process2.argv[1] === void 0) return void 0;
7413
8167
  try {
7414
- return fs15.realpathSync(path13.resolve(process2.argv[1]));
8168
+ return fs20.realpathSync(path20.resolve(process2.argv[1]));
7415
8169
  } catch {
7416
- return path13.resolve(process2.argv[1]);
8170
+ return path20.resolve(process2.argv[1]);
7417
8171
  }
7418
8172
  }
7419
8173
  var _argv1 = _resolvedArgv1();
7420
8174
  var _isCliEntry = _argv1 !== void 0 && import.meta.url === pathToFileURL(_argv1).href;
7421
- if (_isCliEntry || _argv1 === _HERE) {
8175
+ if (_isCliEntry || _argv1 === _HERE2) {
7422
8176
  try {
7423
8177
  process2.exitCode = main2(process2.argv.slice(2));
7424
8178
  } catch (e) {