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