@event4u/agent-config 16.0.0 → 16.2.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 +289 -140
- package/CONTRIBUTING.md +9 -0
- package/README.md +2 -2
- package/dist/agent-src/commands/analyze/inbox.md +26 -0
- package/dist/agent-src/commands/analyze/roadmap-repos.md +27 -0
- package/dist/agent-src/commands/challenge-me/closure.md +178 -0
- package/dist/agent-src/commands/challenge-me.md +9 -2
- package/dist/agent-src/commands/council/default.md +25 -5
- package/dist/agent-src/commands/feature/plan.md +28 -1
- package/dist/agent-src/commands/feature/roadmap.md +28 -1
- package/dist/agent-src/commands/implement-ticket.md +27 -0
- package/dist/agent-src/commands/jira-ticket.md +27 -0
- package/dist/agent-src/commands/pr/create.md +29 -0
- package/dist/agent-src/commands/pr/merge.md +60 -9
- package/dist/agent-src/commands/roadmap/ai-council.md +7 -1
- package/dist/agent-src/commands/roadmap/create.md +74 -27
- package/dist/agent-src/commands/roadmap/materialize.md +27 -0
- package/dist/agent-src/commands/roadmap/process-full.md +123 -18
- package/dist/agent-src/commands/team.md +22 -0
- package/dist/agent-src/commands/work.md +4 -0
- package/dist/agent-src/contexts/authority/scope-growth-ownership.md +80 -0
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +47 -0
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +44 -3
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +19 -23
- package/dist/agent-src/contexts/execution/decision-closure-execution.md +93 -0
- package/dist/agent-src/contexts/execution/fix-loop-ladder.md +108 -0
- package/dist/agent-src/contexts/execution/plan-confidence-gate.md +4 -2
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +75 -6
- package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
- package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
- package/dist/agent-src/guidelines/design-fidelity-routing.md +29 -0
- package/dist/agent-src/rules/autonomous-execution.md +15 -8
- package/dist/agent-src/rules/delegation-policy.md +23 -45
- package/dist/agent-src/rules/design-fidelity.md +32 -37
- package/dist/agent-src/rules/evaluator-independence.md +43 -49
- package/dist/agent-src/rules/test-first.md +41 -0
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +1 -1
- package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
- package/dist/agent-src/skills/ai-council/SKILL.md +11 -3
- package/dist/agent-src/skills/api-design/data/manifest.json +3 -3
- package/dist/agent-src/skills/database/data/manifest.json +4 -4
- package/dist/agent-src/skills/database/data/query-tuning.csv +3 -3
- package/dist/agent-src/skills/design-review/SKILL.md +80 -4
- package/dist/agent-src/skills/design-review/references/verification-automation.md +32 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +30 -5
- package/dist/agent-src/skills/existing-ui-audit/references/component-taxonomy-detection.md +56 -0
- package/dist/agent-src/skills/experiment-loop/SKILL.md +31 -1
- package/dist/agent-src/skills/markitdown/SKILL.md +4 -0
- package/dist/agent-src/skills/playwright-testing/SKILL.md +30 -6
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +42 -3
- package/dist/agent-src/skills/threat-modeling/SKILL.md +9 -4
- package/dist/agent-src/skills/threat-modeling/data/manifest.json +4 -4
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +23 -0
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +37 -3
- package/dist/agent-src/templates/agent-settings.md +1 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +218 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -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 +260 -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/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-delegate/check_update_banner.js +40 -2
- package/dist/cli-delegate/chunk-4E2W63DA.js +335 -0
- package/dist/cli-delegate/{chunk-S3VFXMTM.js → chunk-4XFP2Y3E.js} +1 -1
- package/dist/cli-delegate/chunk-5R7HOLAF.js +99 -0
- package/dist/cli-delegate/{chunk-IVBPRCQO.js → chunk-6KFEC3G7.js} +1 -1
- package/dist/cli-delegate/{chunk-2TAQ2K4V.js → chunk-6KM6ORRY.js} +55 -386
- package/dist/cli-delegate/{chunk-AK6HODNQ.js → chunk-7XGBX6ZH.js} +973 -555
- package/dist/cli-delegate/{chunk-2XY7ILBT.js → chunk-FC75PGJE.js} +42 -2
- package/dist/cli-delegate/{chunk-55ACLDUE.js → chunk-FP36SWJD.js} +587 -141
- package/dist/cli-delegate/{chunk-3FKR64R5.js → chunk-IGD6ERX6.js} +62 -7
- package/dist/cli-delegate/{chunk-GYC3VRYN.js → chunk-JNMVLWLR.js} +99 -14
- package/dist/cli-delegate/{chunk-H32DGUJH.js → chunk-P6ZHP5W2.js} +1 -1
- package/dist/cli-delegate/{chunk-57PN4GYJ.js → chunk-RGNIWTEA.js} +1 -1
- package/dist/cli-delegate/chunk-ROYYTEZU.js +39 -0
- package/dist/cli-delegate/{chunk-2DK2VJWG.js → chunk-WGXTVKCQ.js} +20 -6
- package/dist/cli-delegate/chunk-YDPILCOL.js +152 -0
- package/dist/cli-delegate/{chunk-QJWAUMJW.js → chunk-YJ72UIAK.js} +730 -15
- 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 +985 -831
- package/dist/cli-delegate/cmd_doctor.js +7 -5
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +9 -7
- package/dist/cli-delegate/cmd_fleet.js +4 -2
- package/dist/cli-delegate/cmd_handoff.js +7 -7
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -2
- package/dist/cli-delegate/cmd_preflight.js +4 -2
- package/dist/cli-delegate/cmd_prune.js +10 -8
- package/dist/cli-delegate/cmd_route_audit.js +3 -3
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +4 -4
- package/dist/cli-delegate/cmd_settings_get.js +28 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +9 -7
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +10 -8
- package/dist/cli-delegate/cmd_uninstall.js +16 -13
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +12 -10
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +90 -43
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +10 -8
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +8 -6
- package/dist/hooks/dispatch.js +7682 -2772
- package/dist/hooks/dispatch.sha256 +1 -0
- package/dist/install/claudeRuleRewrite.js +14 -3
- package/dist/install/conflict.js +60 -10
- package/dist/install/conflictTracker.js +218 -0
- package/dist/install/fsPrimitives.js +54 -0
- package/dist/install/install.mjs +2200 -1559
- package/dist/install/manifestFiles.js +259 -0
- package/dist/install/preflight.js +14 -2
- package/dist/install/preserve.js +157 -0
- package/dist/install/recordedOwnership.js +132 -0
- package/dist/install/txlog.js +11 -2
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +3066 -1470
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +3 -2
- package/dist/scripts/_lib/fs_atomic.js +167 -0
- package/dist/scripts/_lib/installed_tools.js +460 -0
- package/dist/scripts/_lib/lean_projection_mode.js +3 -2
- package/dist/scripts/_lib/settings_renamed_keys.js +78 -0
- package/dist/server/routes/install.js +8 -0
- package/dist/server/routes/wizard.js +9 -3
- package/dist/server/schemas/settings.js +40 -5
- package/dist/shared/missionExecution.js +97 -0
- 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/MIGRATION.md +103 -0
- package/docs/contracts/settings-classes.md +28 -7
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
- package/docs/guidelines/design-fidelity-routing.md +29 -0
- package/package.json +4 -4
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
- 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 +260 -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/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 +168 -27
- package/src/config/auto-rule-budget.json +16 -0
- package/src/config/ci-local-parity.yml +36 -5
- package/src/config/continuity-surface.json +23 -2
- package/src/config/gate-coverage.yml +377 -13
- package/src/config/gate-violation-baselines.json +10 -6
- package/src/config/hook-latency-budget.json +21 -0
- package/src/config/hook-token-budget.json +4 -2
- package/src/config/loop-surfaces.yaml +215 -0
- package/src/config/metric-registry.yml +114 -0
- package/src/config/placeholder-drift-budget.json +10 -0
- package/src/config/platform-anchor.json +3 -2
- package/src/config/release-gate-locality.yml +11 -0
- package/src/config/routing-coverage-seed.json +33 -5
- package/src/config/rule-enforcement-baseline.json +0 -1
- package/src/install/claudeRuleRewrite.ts +16 -2
- package/src/install/conflict.ts +65 -9
- package/src/install/conflictTracker.ts +299 -0
- package/src/install/fsPrimitives.ts +54 -0
- package/src/install/manifestFiles.ts +312 -0
- package/src/install/preflight.ts +16 -2
- package/src/install/preserve.ts +205 -0
- package/src/install/recordedOwnership.ts +149 -0
- package/src/install/txlog.ts +11 -2
- package/src/install/types.ts +19 -4
- package/src/scripts/_cli/cmd_conformance.ts +88 -15
- package/src/scripts/_cli/cmd_doctor.ts +7 -20
- package/src/scripts/_cli/cmd_route_explain.ts +9 -2
- package/src/scripts/_cli/cmd_settings_get.ts +44 -0
- package/src/scripts/_cli/doctor_execution.ts +173 -0
- package/src/scripts/_cli/doctor_network_posture.ts +226 -0
- package/src/scripts/_lib/activation_payload.ts +247 -0
- package/src/scripts/_lib/agent_settings.ts +4 -2
- package/src/scripts/_lib/authority_path.ts +102 -0
- package/src/scripts/_lib/body_portable.ts +102 -0
- package/src/scripts/_lib/cascade_base.ts +94 -0
- package/src/scripts/_lib/cc_transcript.ts +132 -1
- package/src/scripts/_lib/changelog_eras.ts +7 -2
- package/src/scripts/_lib/concern_sla_window.ts +200 -0
- package/src/scripts/_lib/continuation_ladder.ts +149 -2
- package/src/scripts/_lib/council_transport.ts +129 -0
- package/src/scripts/_lib/delivery_ready.ts +112 -0
- package/src/scripts/_lib/forge_protection.ts +381 -0
- package/src/scripts/_lib/forge_reader.ts +558 -0
- package/src/scripts/_lib/hook_platform_keys.ts +27 -0
- package/src/scripts/_lib/host_env_write.ts +111 -0
- package/src/scripts/_lib/json_python_parity.ts +127 -0
- package/src/scripts/_lib/lean_projection_mode.ts +14 -3
- package/src/scripts/_lib/llm_proposer_transport.ts +14 -4
- package/src/scripts/_lib/loop_surfaces.ts +382 -0
- package/src/scripts/_lib/mission_record.ts +190 -0
- package/src/scripts/_lib/obligation_frequency.ts +217 -0
- package/src/scripts/_lib/obligations.ts +513 -0
- package/src/scripts/_lib/orchestration_record.ts +11 -20
- package/src/scripts/_lib/probe_inputs.ts +271 -0
- package/src/scripts/_lib/read_surface_scan.ts +322 -0
- package/src/scripts/_lib/release_highlights.ts +201 -11
- package/src/scripts/_lib/release_holds.ts +493 -0
- package/src/scripts/_lib/release_migration_gate.ts +184 -0
- package/src/scripts/_lib/retrieval_sanitize.ts +77 -16
- package/src/scripts/_lib/rides_along.ts +102 -0
- package/src/scripts/_lib/settings_renamed_keys.ts +82 -0
- package/src/scripts/_lib/shell_write_shapes.ts +108 -0
- package/src/scripts/_lib/structural_hiding.ts +622 -0
- package/src/scripts/_lib/test_delta.ts +166 -0
- package/src/scripts/_lib/test_provenance.ts +171 -0
- package/src/scripts/_lib/turn_end_refusals.ts +525 -4
- package/src/scripts/_lib/turn_end_transcript.ts +216 -0
- package/src/scripts/_lib/typed_op_grant.ts +246 -0
- package/src/scripts/_lib/typed_op_watch.ts +185 -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/ai_council/config.ts +8 -11
- package/src/scripts/ai_council/fallback_config.ts +5 -3
- package/src/scripts/ai_council/ownership_classes.ts +118 -0
- package/src/scripts/ai_team/team_dispatch.ts +4 -0
- package/src/scripts/ask_block_census.ts +285 -15
- package/src/scripts/before_complete_hook.ts +340 -23
- package/src/scripts/bench_hook_latency.ts +412 -5
- 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 +866 -0
- package/src/scripts/check_finding_dispositions.ts +22 -3
- package/src/scripts/check_gate_reachability.ts +173 -10
- package/src/scripts/check_generator_sync.ts +1025 -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 +47 -5
- package/src/scripts/check_kill_switch_table.ts +294 -0
- package/src/scripts/check_placeholder_drift.ts +221 -0
- package/src/scripts/check_preamble_payload_budget.ts +75 -2
- package/src/scripts/check_read_surface_coverage.ts +515 -0
- package/src/scripts/check_release_highlights.ts +33 -1
- package/src/scripts/check_release_holds.ts +568 -0
- package/src/scripts/check_routing_coverage.ts +378 -11
- package/src/scripts/check_rule_projection_integrity.ts +22 -12
- package/src/scripts/check_static_parity.ts +17 -0
- package/src/scripts/check_test_delta.ts +294 -0
- package/src/scripts/check_test_weakening.ts +299 -0
- package/src/scripts/ci_settle.ts +145 -19
- package/src/scripts/closure_scan.ts +447 -0
- package/src/scripts/compile_hook_manifest.ts +102 -18
- package/src/scripts/council_record_shape.ts +209 -0
- package/src/scripts/external_sources_denylist.json +29 -4
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +127 -11
- package/src/scripts/hooks/block_config_weakening.ts +229 -4
- package/src/scripts/hooks/block_kernel_rule_writes.ts +9 -78
- package/src/scripts/hooks/block_plumbing_writes.ts +314 -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 +1 -2
- package/src/scripts/hooks/comment_discipline_hook.ts +1 -3
- package/src/scripts/hooks/concern_registry.ts +6 -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 +221 -5
- package/src/scripts/hooks/design_slop_hook.ts +1 -2
- package/src/scripts/hooks/dispatch_hook.ts +25 -19
- 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 +97 -2
- package/src/scripts/hooks/exit_codes.ts +128 -0
- package/src/scripts/hooks/host_lowering.json +1 -0
- package/src/scripts/hooks/host_lowering.ts +128 -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 +539 -0
- package/src/scripts/hooks/obligation_settle_hook.ts +328 -0
- package/src/scripts/hooks/one_question_per_ask_hook.ts +25 -4
- package/src/scripts/hooks/orchestration_record_hook.ts +1 -2
- 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 +55 -4
- package/src/scripts/hooks/run_continuation_hook.ts +30 -35
- 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 +49 -0
- package/src/scripts/hooks/telemetry_flush_hook.ts +1 -2
- package/src/scripts/hooks/telemetry_usage_hook.ts +1 -2
- package/src/scripts/hooks/tool_result_bytes_hook.ts +93 -9
- package/src/scripts/hooks/turn_end_gate_hook.ts +337 -324
- package/src/scripts/hooks/ui_route_nudge_hook.ts +1 -2
- package/src/scripts/hooks_doctor.ts +85 -0
- package/src/scripts/hooks_status.ts +19 -0
- package/src/scripts/install.ts +109 -210
- package/src/scripts/janitor.ts +7 -0
- package/src/scripts/lint_decision_classes.ts +464 -0
- 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 +66 -0
- package/src/scripts/lint_major_migration_sections.ts +450 -0
- package/src/scripts/lint_plan_risk_register.ts +47 -3
- package/src/scripts/lint_roadmap_blockers.ts +139 -12
- package/src/scripts/lint_roadmap_producers.ts +202 -0
- package/src/scripts/lint_skill_descriptions.ts +1 -1
- package/src/scripts/lint_skill_scripts_readonly.ts +1 -1
- package/src/scripts/mcp_server/prompts.ts +142 -1
- package/src/scripts/measure_rule_budget.ts +101 -5
- package/src/scripts/measure_skill_ranker_baseline.ts +305 -51
- package/src/scripts/measure_turn_end_gate.ts +193 -0
- package/src/scripts/memory_lookup.ts +1 -1
- package/src/scripts/new_roadmap.ts +37 -0
- package/src/scripts/orchestration_record.ts +0 -5
- package/src/scripts/prepack-check.mjs +53 -0
- package/src/scripts/release.ts +14 -98
- package/src/scripts/release_drill.ts +267 -1
- package/src/scripts/release_publication.ts +64 -1
- package/src/scripts/report_enforcement_drift.ts +566 -0
- package/src/scripts/report_host_injection_effect.ts +3 -11
- package/src/scripts/report_invocation_surface.ts +383 -0
- package/src/scripts/report_obligation_carriers.ts +699 -0
- package/src/scripts/report_obligation_writer_split.ts +236 -0
- package/src/scripts/report_skill_menu_census.ts +208 -0
- package/src/scripts/report_standing_payload_by_host.ts +26 -152
- package/src/scripts/roadmap_verify_share.ts +213 -0
- package/src/scripts/schemas/agent-settings.schema.json +23 -0
- package/src/scripts/schemas/command.schema.json +48 -0
- package/src/scripts/schemas/review-findings.schema.json +4 -0
- package/src/scripts/schemas/skill.schema.json +44 -0
- package/src/scripts/scope_growth.ts +219 -0
- package/src/scripts/self_review_gate.ts +359 -10
- package/src/scripts/semantic_parity_census.ts +314 -0
- package/src/scripts/session_eol_report.ts +54 -1
- package/src/scripts/sweep_dead_scan_roots.ts +1 -1
- package/src/scripts/trigger_eval_grandfather.json +0 -3
- package/src/scripts/trigger_eval_rotation.ts +122 -27
- package/src/scripts/ui_conformance_probe.ts +774 -0
- package/src/scripts/update_prices.ts +85 -3
- package/src/scripts/write_bundle_digest.mjs +74 -0
- package/src/server/schemas/settings.ts +62 -7
- package/src/shared/missionExecution.ts +126 -0
- package/src/templates/consumer-settings/ONBOARDING.md +1 -0
- package/dist/cli-delegate/chunk-523HCFYO.js +0 -90
- package/dist/ui/assets/index-D0jaCRPM.js +0 -29
- package/dist/ui/assets/index-jSfMW8_t.css +0 -1
- /package/dist/cli-delegate/{chunk-YUM5KURG.js → chunk-7RQP4UDH.js} +0 -0
|
@@ -2,35 +2,37 @@ import { createRequire as __acCreateRequire } from 'node:module'; const require
|
|
|
2
2
|
import {
|
|
3
3
|
ZodFirstPartyTypeKind,
|
|
4
4
|
settingsSchema
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-IGD6ERX6.js";
|
|
6
6
|
import {
|
|
7
7
|
main
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6KFEC3G7.js";
|
|
9
9
|
import {
|
|
10
10
|
RULE_SOURCE_REL
|
|
11
11
|
} from "./chunk-WOKWX5PL.js";
|
|
12
|
+
import {
|
|
13
|
+
classifyOwnership,
|
|
14
|
+
recordedHashesForRoot
|
|
15
|
+
} from "./chunk-YDPILCOL.js";
|
|
16
|
+
import {
|
|
17
|
+
appendTxLog
|
|
18
|
+
} from "./chunk-5R7HOLAF.js";
|
|
12
19
|
import {
|
|
13
20
|
SCOPE_DETECT_AI_DIRS,
|
|
14
21
|
SCOPE_DETECT_MANIFESTS
|
|
15
22
|
} from "./chunk-A4QJ6ENT.js";
|
|
16
23
|
import {
|
|
17
|
-
ScopeMismatchError,
|
|
18
24
|
build_claude_hook_matrix,
|
|
19
25
|
ensure_managed_hooks,
|
|
20
26
|
expected_deploy_files,
|
|
21
27
|
is_ancestor,
|
|
22
28
|
load_inventory,
|
|
23
|
-
manifest_path,
|
|
24
29
|
printResiduals,
|
|
25
30
|
probeHostCapabilities,
|
|
26
|
-
read_manifest,
|
|
27
31
|
reap_stale,
|
|
28
32
|
reap_tagged_orphans,
|
|
29
33
|
record_deploy,
|
|
30
|
-
save_inventory
|
|
31
|
-
|
|
32
|
-
write_manifest
|
|
33
|
-
} from "./chunk-2TAQ2K4V.js";
|
|
34
|
+
save_inventory
|
|
35
|
+
} from "./chunk-6KM6ORRY.js";
|
|
34
36
|
import {
|
|
35
37
|
check_version,
|
|
36
38
|
classify_mismatch,
|
|
@@ -53,13 +55,20 @@ import {
|
|
|
53
55
|
ruleFileArrives,
|
|
54
56
|
ruleScopeFromSettings
|
|
55
57
|
} from "./chunk-DMSZHXZS.js";
|
|
58
|
+
import {
|
|
59
|
+
ScopeMismatchError,
|
|
60
|
+
manifest_path,
|
|
61
|
+
read_manifest,
|
|
62
|
+
upsert_tool,
|
|
63
|
+
write_manifest
|
|
64
|
+
} from "./chunk-4E2W63DA.js";
|
|
56
65
|
import {
|
|
57
66
|
require_dist
|
|
58
67
|
} from "./chunk-OY53J6II.js";
|
|
59
68
|
import {
|
|
60
69
|
find_project_root_with_anchor,
|
|
61
70
|
load_agent_settings
|
|
62
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-FC75PGJE.js";
|
|
63
72
|
import {
|
|
64
73
|
event4u_root,
|
|
65
74
|
legacy_xdg_root,
|
|
@@ -273,13 +282,154 @@ function subtract_pointers(doc, entries) {
|
|
|
273
282
|
|
|
274
283
|
// src/scripts/install.ts
|
|
275
284
|
import { spawn, spawnSync } from "node:child_process";
|
|
276
|
-
import * as
|
|
277
|
-
import * as
|
|
285
|
+
import * as crypto5 from "node:crypto";
|
|
286
|
+
import * as fs15 from "node:fs";
|
|
278
287
|
import * as os3 from "node:os";
|
|
279
|
-
import * as
|
|
288
|
+
import * as path13 from "node:path";
|
|
280
289
|
import process2 from "node:process";
|
|
281
290
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
282
291
|
|
|
292
|
+
// src/scripts/_lib/host_env_write.ts
|
|
293
|
+
var YAML = __toESM(require_dist(), 1);
|
|
294
|
+
import * as fs from "node:fs";
|
|
295
|
+
import * as path from "node:path";
|
|
296
|
+
var WRITABLE_HOST_ENV = [
|
|
297
|
+
{ variable: "BASH_MAX_OUTPUT_LENGTH", settingsKey: "bash_max_output_length" },
|
|
298
|
+
{ variable: "MAX_MCP_OUTPUT_TOKENS", settingsKey: "max_mcp_output_tokens" }
|
|
299
|
+
];
|
|
300
|
+
var SETTINGS_CANDIDATES = [
|
|
301
|
+
["agents", "settings", ".agent-settings.yml"],
|
|
302
|
+
[".agent-settings.yml"]
|
|
303
|
+
];
|
|
304
|
+
function readSettingsDoc(projectRoot) {
|
|
305
|
+
for (const parts of SETTINGS_CANDIDATES) {
|
|
306
|
+
const p = path.join(projectRoot, ...parts);
|
|
307
|
+
let text;
|
|
308
|
+
try {
|
|
309
|
+
text = fs.readFileSync(p, "utf-8");
|
|
310
|
+
} catch {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
let doc;
|
|
314
|
+
try {
|
|
315
|
+
doc = YAML.parse(text, { version: "1.1" });
|
|
316
|
+
} catch {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
return doc === null || doc === void 0 || typeof doc !== "object" ? null : doc;
|
|
320
|
+
}
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
function hostEnvBlock(settings) {
|
|
324
|
+
const root = settings;
|
|
325
|
+
const he = root?.["host_environment"];
|
|
326
|
+
const caps = he?.["request_size_caps"];
|
|
327
|
+
if (caps === void 0) return null;
|
|
328
|
+
const out = {};
|
|
329
|
+
for (const { variable, settingsKey } of WRITABLE_HOST_ENV) {
|
|
330
|
+
const v = caps[settingsKey];
|
|
331
|
+
if (typeof v === "number" && Number.isInteger(v) && v > 0) out[variable] = String(v);
|
|
332
|
+
}
|
|
333
|
+
return Object.keys(out).length === 0 ? null : out;
|
|
334
|
+
}
|
|
335
|
+
function withHostEnv(bridge, projectRoot, announce) {
|
|
336
|
+
const env = hostEnvBlock(readSettingsDoc(projectRoot));
|
|
337
|
+
if (env === null) return bridge;
|
|
338
|
+
announce(`.claude/settings.json: wrote ${Object.keys(env).join(", ")} (request-size caps)`);
|
|
339
|
+
return { ...bridge, env };
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// src/scripts/_lib/json_python_parity.ts
|
|
343
|
+
function jsonStrNoAscii(s) {
|
|
344
|
+
let out = '"';
|
|
345
|
+
for (const ch of s) {
|
|
346
|
+
const code = ch.codePointAt(0);
|
|
347
|
+
switch (ch) {
|
|
348
|
+
case '"':
|
|
349
|
+
out += '\\"';
|
|
350
|
+
break;
|
|
351
|
+
case "\\":
|
|
352
|
+
out += "\\\\";
|
|
353
|
+
break;
|
|
354
|
+
case "\n":
|
|
355
|
+
out += "\\n";
|
|
356
|
+
break;
|
|
357
|
+
case "\r":
|
|
358
|
+
out += "\\r";
|
|
359
|
+
break;
|
|
360
|
+
case " ":
|
|
361
|
+
out += "\\t";
|
|
362
|
+
break;
|
|
363
|
+
case "\b":
|
|
364
|
+
out += "\\b";
|
|
365
|
+
break;
|
|
366
|
+
case "\f":
|
|
367
|
+
out += "\\f";
|
|
368
|
+
break;
|
|
369
|
+
default:
|
|
370
|
+
if (code < 32) {
|
|
371
|
+
out += "\\u" + code.toString(16).padStart(4, "0");
|
|
372
|
+
} else {
|
|
373
|
+
out += ch;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return out + '"';
|
|
378
|
+
}
|
|
379
|
+
function _jsonScalar(value) {
|
|
380
|
+
if (value === null || value === void 0) return "null";
|
|
381
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
382
|
+
if (typeof value === "number") {
|
|
383
|
+
if (!Number.isFinite(value)) {
|
|
384
|
+
if (Number.isNaN(value)) return "NaN";
|
|
385
|
+
return value > 0 ? "Infinity" : "-Infinity";
|
|
386
|
+
}
|
|
387
|
+
return String(value);
|
|
388
|
+
}
|
|
389
|
+
if (typeof value === "string") return jsonStrNoAscii(value);
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
function _dumpIndent(value, indent, depth) {
|
|
393
|
+
const scalar = _jsonScalar(value);
|
|
394
|
+
if (scalar !== null) return scalar;
|
|
395
|
+
const pad = " ".repeat(indent * (depth + 1));
|
|
396
|
+
const closePad = " ".repeat(indent * depth);
|
|
397
|
+
if (Array.isArray(value)) {
|
|
398
|
+
if (value.length === 0) return "[]";
|
|
399
|
+
const items = value.map((v) => pad + _dumpIndent(v, indent, depth + 1));
|
|
400
|
+
return `[
|
|
401
|
+
${items.join(",\n")}
|
|
402
|
+
${closePad}]`;
|
|
403
|
+
}
|
|
404
|
+
if (typeof value === "object" && value !== null) {
|
|
405
|
+
const obj = value;
|
|
406
|
+
const keys = Object.keys(obj);
|
|
407
|
+
if (keys.length === 0) return "{}";
|
|
408
|
+
const items = keys.map(
|
|
409
|
+
(k) => `${pad}${jsonStrNoAscii(k)}: ${_dumpIndent(obj[k], indent, depth + 1)}`
|
|
410
|
+
);
|
|
411
|
+
return `{
|
|
412
|
+
${items.join(",\n")}
|
|
413
|
+
${closePad}}`;
|
|
414
|
+
}
|
|
415
|
+
return jsonStrNoAscii(String(value));
|
|
416
|
+
}
|
|
417
|
+
function jsonDumpsIndent(value, indent) {
|
|
418
|
+
return _dumpIndent(value, indent, 0);
|
|
419
|
+
}
|
|
420
|
+
function jsonDumpsCompact(value) {
|
|
421
|
+
const scalar = _jsonScalar(value);
|
|
422
|
+
if (scalar !== null) return scalar;
|
|
423
|
+
if (Array.isArray(value)) {
|
|
424
|
+
return "[" + value.map((v) => jsonDumpsCompact(v)).join(",") + "]";
|
|
425
|
+
}
|
|
426
|
+
if (typeof value === "object" && value !== null) {
|
|
427
|
+
const obj = value;
|
|
428
|
+
return "{" + Object.keys(obj).map((k) => `${jsonStrNoAscii(k)}:${jsonDumpsCompact(obj[k])}`).join(",") + "}";
|
|
429
|
+
}
|
|
430
|
+
return jsonStrNoAscii(String(value));
|
|
431
|
+
}
|
|
432
|
+
|
|
283
433
|
// src/scripts/_lib/claude_builtin_names.ts
|
|
284
434
|
var _CURRENT = [
|
|
285
435
|
"add-dir",
|
|
@@ -397,8 +547,8 @@ function is_claude_builtin_name(slug) {
|
|
|
397
547
|
}
|
|
398
548
|
|
|
399
549
|
// src/scripts/_lib/mcp_bridge.ts
|
|
400
|
-
import * as
|
|
401
|
-
import * as
|
|
550
|
+
import * as fs2 from "node:fs";
|
|
551
|
+
import * as path2 from "node:path";
|
|
402
552
|
var MCP_SERVER_KEY = "agent-config";
|
|
403
553
|
var MCP_PACKAGE_NAME = "@event4u/agent-config";
|
|
404
554
|
function mcpBridgeEntry(packageRoot) {
|
|
@@ -415,7 +565,7 @@ function mcpBridgeEntry(packageRoot) {
|
|
|
415
565
|
}
|
|
416
566
|
function readPackageVersion(packageRoot) {
|
|
417
567
|
try {
|
|
418
|
-
const raw =
|
|
568
|
+
const raw = fs2.readFileSync(path2.join(packageRoot, "package.json"), "utf-8");
|
|
419
569
|
const v = JSON.parse(raw).version;
|
|
420
570
|
return typeof v === "string" && v.trim() !== "" ? v : null;
|
|
421
571
|
} catch {
|
|
@@ -424,7 +574,7 @@ function readPackageVersion(packageRoot) {
|
|
|
424
574
|
}
|
|
425
575
|
function makeEnsureMcpBridge(mergeJsonFile) {
|
|
426
576
|
return (projectRoot, force, packageRoot = projectRoot) => mergeJsonFile(
|
|
427
|
-
|
|
577
|
+
path2.join(projectRoot, ".mcp.json"),
|
|
428
578
|
mcpBridgeEntry(packageRoot),
|
|
429
579
|
force,
|
|
430
580
|
".mcp.json"
|
|
@@ -450,7 +600,7 @@ function makeEnsureMcpRegistrations(mergeJsonFile) {
|
|
|
450
600
|
const merged = {};
|
|
451
601
|
for (const t of targets) {
|
|
452
602
|
merged[t.toolId] = mergeJsonFile(
|
|
453
|
-
|
|
603
|
+
path2.join(projectRoot, ...t.relPath.split("/")),
|
|
454
604
|
mcpBridgeEntry(packageRoot),
|
|
455
605
|
force,
|
|
456
606
|
t.relPath
|
|
@@ -481,10 +631,10 @@ function projectionModeOf(raw) {
|
|
|
481
631
|
return raw === "scoped" ? "scoped" : raw === "tiered" ? "tiered" : "legacy-all";
|
|
482
632
|
}
|
|
483
633
|
function resolveTierB(packageRoot) {
|
|
484
|
-
const p =
|
|
485
|
-
if (!
|
|
634
|
+
const p = path2.join(packageRoot, "agents", "runtime", "state", "skill-tiers.json");
|
|
635
|
+
if (!fs2.existsSync(p)) return null;
|
|
486
636
|
try {
|
|
487
|
-
const parsed = JSON.parse(
|
|
637
|
+
const parsed = JSON.parse(fs2.readFileSync(p, "utf-8"));
|
|
488
638
|
if (!Array.isArray(parsed.tier_b)) return null;
|
|
489
639
|
return new Set(parsed.tier_b.filter((n) => typeof n === "string"));
|
|
490
640
|
} catch {
|
|
@@ -492,7 +642,7 @@ function resolveTierB(packageRoot) {
|
|
|
492
642
|
}
|
|
493
643
|
}
|
|
494
644
|
function tierBPrunePredicate(tierB) {
|
|
495
|
-
return (mdPath) => tierB.has(
|
|
645
|
+
return (mdPath) => tierB.has(path2.basename(path2.dirname(mdPath)));
|
|
496
646
|
}
|
|
497
647
|
function tierBAdvisory(packageRoot) {
|
|
498
648
|
const tierB = resolveTierB(packageRoot);
|
|
@@ -519,9 +669,329 @@ function applyTieredPrune(deployResults, packageRoot, pruneBy) {
|
|
|
519
669
|
};
|
|
520
670
|
}
|
|
521
671
|
|
|
672
|
+
// src/install/conflictTracker.ts
|
|
673
|
+
import * as crypto2 from "node:crypto";
|
|
674
|
+
import * as fs4 from "node:fs";
|
|
675
|
+
import * as path4 from "node:path";
|
|
676
|
+
|
|
677
|
+
// src/install/fsPrimitives.ts
|
|
678
|
+
import * as crypto from "node:crypto";
|
|
679
|
+
import * as fs3 from "node:fs";
|
|
680
|
+
import * as path3 from "node:path";
|
|
681
|
+
function resolvePath(p) {
|
|
682
|
+
try {
|
|
683
|
+
return fs3.realpathSync(path3.resolve(p));
|
|
684
|
+
} catch {
|
|
685
|
+
return path3.resolve(p);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
function pathExists(p) {
|
|
689
|
+
try {
|
|
690
|
+
fs3.statSync(p);
|
|
691
|
+
return true;
|
|
692
|
+
} catch {
|
|
693
|
+
return false;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
function mkdirp(p) {
|
|
697
|
+
fs3.mkdirSync(p, { recursive: true });
|
|
698
|
+
}
|
|
699
|
+
function sha256OfFile(p) {
|
|
700
|
+
let data;
|
|
701
|
+
try {
|
|
702
|
+
data = fs3.readFileSync(p);
|
|
703
|
+
} catch {
|
|
704
|
+
return null;
|
|
705
|
+
}
|
|
706
|
+
return crypto.createHash("sha256").update(data).digest("hex");
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// src/install/preserve.ts
|
|
710
|
+
var SIDECAR_SUFFIX = ".agent-config.new";
|
|
711
|
+
var EXIT_COMPLETED_WITH_CONFLICTS = 3;
|
|
712
|
+
function decideDeployWrite(inputs) {
|
|
713
|
+
if (!inputs.exists) return "write";
|
|
714
|
+
if (inputs.force) return "write";
|
|
715
|
+
const ownership = classifyOwnership(inputs.recordedSha256, inputs.onDiskSha256);
|
|
716
|
+
return ownership === "recorded-modified" ? "preserve" : "write";
|
|
717
|
+
}
|
|
718
|
+
function sidecarPathFor(target) {
|
|
719
|
+
return `${target}${SIDECAR_SUFFIX}`;
|
|
720
|
+
}
|
|
721
|
+
function preservedFileMessage(target, sidecar) {
|
|
722
|
+
return `Preserved user-modified ${target}. Package content was written to ${sidecar}; the active installation is not current. Review and merge it, or rerun with --force to replace the managed file.`;
|
|
723
|
+
}
|
|
724
|
+
function conflictSummaryMessage(count) {
|
|
725
|
+
const noun = count === 1 ? "file" : "files";
|
|
726
|
+
return `Completed with conflicts: ${count} user-modified ${noun} preserved. Package content is staged alongside as *${SIDECAR_SUFFIX}; the active installation is not current until you merge it, or rerun with --force to replace the managed ${noun}.`;
|
|
727
|
+
}
|
|
728
|
+
function foreignSidecarMessage(target, sidecar) {
|
|
729
|
+
return `Refusing to replace ${sidecar}: it already exists with different content and this install cannot show it wrote it. Package content for ${target} was NOT staged. Move or delete that file and re-run, or rerun with --force to replace the managed file instead.`;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// src/install/conflictTracker.ts
|
|
733
|
+
function createConflictTracker(host) {
|
|
734
|
+
const conflictState = {
|
|
735
|
+
root: null,
|
|
736
|
+
recorded: null,
|
|
737
|
+
preserved: [],
|
|
738
|
+
staged: /* @__PURE__ */ new Map()
|
|
739
|
+
};
|
|
740
|
+
function recordedHashFor(target) {
|
|
741
|
+
if (conflictState.root === null) return void 0;
|
|
742
|
+
conflictState.recorded ??= recordedHashesForRoot(conflictState.root);
|
|
743
|
+
const plain = path4.resolve(target);
|
|
744
|
+
if (conflictState.recorded.has(plain)) return conflictState.recorded.get(plain);
|
|
745
|
+
const real = resolvePath(target);
|
|
746
|
+
return real === plain ? void 0 : conflictState.recorded.get(real);
|
|
747
|
+
}
|
|
748
|
+
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)}`
|
|
753
|
+
);
|
|
754
|
+
const discard = () => {
|
|
755
|
+
try {
|
|
756
|
+
fs4.unlinkSync(tmp);
|
|
757
|
+
} catch {
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
let candidate;
|
|
761
|
+
try {
|
|
762
|
+
produce(tmp);
|
|
763
|
+
candidate = sha256OfFile(tmp);
|
|
764
|
+
} catch (exc) {
|
|
765
|
+
discard();
|
|
766
|
+
host.fail(
|
|
767
|
+
`Could not stage package content for ${target} at ${sidecar}: ${String(exc)}. Nothing was written; the managed file is unchanged.`
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
if (pathExists(sidecar)) {
|
|
771
|
+
const onDisk = sha256OfFile(sidecar);
|
|
772
|
+
if (onDisk !== null && onDisk === candidate) {
|
|
773
|
+
discard();
|
|
774
|
+
conflictState.staged.set(sidecar, onDisk);
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
if (onDisk === null || onDisk !== recordedHashFor(sidecar)) {
|
|
778
|
+
discard();
|
|
779
|
+
host.fail(foreignSidecarMessage(target, sidecar));
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
try {
|
|
783
|
+
fs4.renameSync(tmp, sidecar);
|
|
784
|
+
} catch (exc) {
|
|
785
|
+
discard();
|
|
786
|
+
host.fail(
|
|
787
|
+
`Could not stage package content for ${target} at ${sidecar}: ${String(exc)}. Nothing was written; the managed file is unchanged.`
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
conflictState.staged.set(sidecar, candidate);
|
|
791
|
+
host.logWrite(sidecar);
|
|
792
|
+
}
|
|
793
|
+
function record(target, sidecar) {
|
|
794
|
+
if (conflictState.preserved.includes(target)) return;
|
|
795
|
+
conflictState.preserved.push(target);
|
|
796
|
+
host.warn(preservedFileMessage(target, sidecar));
|
|
797
|
+
}
|
|
798
|
+
return {
|
|
799
|
+
conflictState,
|
|
800
|
+
begin(root) {
|
|
801
|
+
conflictState.root = root;
|
|
802
|
+
conflictState.recorded = null;
|
|
803
|
+
conflictState.preserved = [];
|
|
804
|
+
conflictState.staged = /* @__PURE__ */ new Map();
|
|
805
|
+
},
|
|
806
|
+
/**
|
|
807
|
+
* The on-disk digest is computed HERE rather than carried from the
|
|
808
|
+
* plan: this runs immediately before the caller copies over `target`,
|
|
809
|
+
* so a file edited between planning and writing is still classified
|
|
810
|
+
* from the bytes that are actually about to be destroyed.
|
|
811
|
+
*/
|
|
812
|
+
resolve(target, force) {
|
|
813
|
+
const exists = pathExists(target);
|
|
814
|
+
return decideDeployWrite({
|
|
815
|
+
exists,
|
|
816
|
+
recordedSha256: exists ? recordedHashFor(target) : void 0,
|
|
817
|
+
onDiskSha256: exists ? sha256OfFile(target) : null,
|
|
818
|
+
force
|
|
819
|
+
});
|
|
820
|
+
},
|
|
821
|
+
/**
|
|
822
|
+
* Stage the package content beside a preserved target.
|
|
823
|
+
*
|
|
824
|
+
* The staged bytes are what the installer WOULD have written — the
|
|
825
|
+
* package file plus its install-time tag — so merging the sidecar by
|
|
826
|
+
* hand yields a file that matches the digest this run records and still
|
|
827
|
+
* carries the ownership evidence the reaper reads.
|
|
828
|
+
*/
|
|
829
|
+
preserve(target, source, packageRoot) {
|
|
830
|
+
const sidecar = sidecarPathFor(target);
|
|
831
|
+
stageInto(target, sidecar, (tmp) => {
|
|
832
|
+
fs4.copyFileSync(source, tmp);
|
|
833
|
+
host.tagDeployed(tmp, source, packageRoot);
|
|
834
|
+
});
|
|
835
|
+
record(target, sidecar);
|
|
836
|
+
},
|
|
837
|
+
/**
|
|
838
|
+
* The same, for a managed file the installer GENERATES rather than
|
|
839
|
+
* copies (the Claude Desktop marker).
|
|
840
|
+
*
|
|
841
|
+
* Those writers are recorded in the manifest with a digest, so they are
|
|
842
|
+
* in the class the ruling covers, and one of them wrote unconditionally
|
|
843
|
+
* — ignoring even `--force` — because the tracker was wired only into
|
|
844
|
+
* the copy loop.
|
|
845
|
+
*/
|
|
846
|
+
preserveContent(target, content) {
|
|
847
|
+
const sidecar = sidecarPathFor(target);
|
|
848
|
+
stageInto(target, sidecar, (tmp) => fs4.writeFileSync(tmp, content, "utf-8"));
|
|
849
|
+
record(target, sidecar);
|
|
850
|
+
},
|
|
851
|
+
/**
|
|
852
|
+
* Runs before the installer's terminal NDJSON frame so that frame can
|
|
853
|
+
* carry the count. A failing run keeps its own code — a conflict never
|
|
854
|
+
* masks a failure.
|
|
855
|
+
*/
|
|
856
|
+
finalizeRc(rc) {
|
|
857
|
+
const count = conflictState.preserved.length;
|
|
858
|
+
if (count === 0) return rc;
|
|
859
|
+
host.emitProgress({ type: "conflicts", count, paths: [...conflictState.preserved] });
|
|
860
|
+
host.warn(conflictSummaryMessage(count));
|
|
861
|
+
return rc === 0 ? EXIT_COMPLETED_WITH_CONFLICTS : rc;
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// src/install/manifestFiles.ts
|
|
867
|
+
var YAML2 = __toESM(require_dist(), 1);
|
|
868
|
+
import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
|
|
869
|
+
import { homedir } from "node:os";
|
|
870
|
+
import { isAbsolute, join as join4, resolve as resolve3 } from "node:path";
|
|
871
|
+
function fileEntry(p, kind, hashContent) {
|
|
872
|
+
return { path: p, kind, sha256: hashContent ? sha256OfFile(p) : null };
|
|
873
|
+
}
|
|
874
|
+
function filesByToolFromDeploy(deployResults) {
|
|
875
|
+
const out = {};
|
|
876
|
+
for (const toolId of Object.keys(deployResults)) {
|
|
877
|
+
const [, , status, paths] = deployResults[toolId];
|
|
878
|
+
if (status === "deployed") {
|
|
879
|
+
out[toolId] = paths.map((p) => fileEntry(p, "deployed", true));
|
|
880
|
+
} else if (status === "marker") {
|
|
881
|
+
out[toolId] = paths.map((p) => fileEntry(p, "marker", true));
|
|
882
|
+
} else {
|
|
883
|
+
out[toolId] = null;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
return out;
|
|
887
|
+
}
|
|
888
|
+
function filesByToolFromBridges(tools, projectRoot, scope, bridgeMarker) {
|
|
889
|
+
const out = {};
|
|
890
|
+
for (const toolId of [...tools].sort()) {
|
|
891
|
+
const marker = bridgeMarker(toolId, scope);
|
|
892
|
+
if (!marker) continue;
|
|
893
|
+
const markerPath = isAbsolute(marker) ? marker : join4(projectRoot, marker);
|
|
894
|
+
out[toolId] = [fileEntry(markerPath, "bridge", false)];
|
|
895
|
+
}
|
|
896
|
+
return out;
|
|
897
|
+
}
|
|
898
|
+
function expanduser(p) {
|
|
899
|
+
if (p === "~") return homedir();
|
|
900
|
+
if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
|
|
901
|
+
return join4(homedir(), p.slice(2));
|
|
902
|
+
}
|
|
903
|
+
return p;
|
|
904
|
+
}
|
|
905
|
+
function resolveRecorded(raw, projectRoot) {
|
|
906
|
+
const expanded = expanduser(raw);
|
|
907
|
+
return isAbsolute(expanded) ? resolve3(expanded) : resolve3(projectRoot, expanded);
|
|
908
|
+
}
|
|
909
|
+
function readRecordedByTool(manifestPath, projectRoot) {
|
|
910
|
+
const out = /* @__PURE__ */ new Map();
|
|
911
|
+
if (!existsSync2(manifestPath)) return out;
|
|
912
|
+
let doc;
|
|
913
|
+
try {
|
|
914
|
+
doc = YAML2.parse(readFileSync4(manifestPath, "utf8"));
|
|
915
|
+
} catch {
|
|
916
|
+
return out;
|
|
917
|
+
}
|
|
918
|
+
if (doc === null || typeof doc !== "object" || Array.isArray(doc)) return out;
|
|
919
|
+
const tools = doc["tools"];
|
|
920
|
+
if (!Array.isArray(tools)) return out;
|
|
921
|
+
for (const tool of tools) {
|
|
922
|
+
if (tool === null || typeof tool !== "object" || Array.isArray(tool)) continue;
|
|
923
|
+
const rec = tool;
|
|
924
|
+
const name = rec["name"];
|
|
925
|
+
if (typeof name !== "string" || name.length === 0) continue;
|
|
926
|
+
const files = [];
|
|
927
|
+
const rawFiles = rec["files"];
|
|
928
|
+
if (Array.isArray(rawFiles)) {
|
|
929
|
+
for (const entry of rawFiles) {
|
|
930
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
931
|
+
const raw = entry["path"];
|
|
932
|
+
if (typeof raw !== "string" || raw.length === 0) continue;
|
|
933
|
+
files.push({
|
|
934
|
+
entry,
|
|
935
|
+
resolved: resolveRecorded(raw, projectRoot)
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
const rawMerged = rec["merged_keys"];
|
|
940
|
+
const mergedKeys = Array.isArray(rawMerged) ? rawMerged : [];
|
|
941
|
+
out.set(name, { files, mergedKeys });
|
|
942
|
+
}
|
|
943
|
+
return out;
|
|
944
|
+
}
|
|
945
|
+
function hydrateRecordedInventories(entries, prior) {
|
|
946
|
+
for (const entry of entries) {
|
|
947
|
+
const name = entry["name"];
|
|
948
|
+
if (typeof name !== "string") continue;
|
|
949
|
+
const recorded = prior.get(name);
|
|
950
|
+
if (recorded === void 0) continue;
|
|
951
|
+
if (Array.isArray(entry["files"]) && entry["files"].length === 0) {
|
|
952
|
+
entry["files"] = recorded.files.map((f) => f.entry);
|
|
953
|
+
}
|
|
954
|
+
if (Array.isArray(entry["merged_keys"]) && entry["merged_keys"].length === 0) {
|
|
955
|
+
entry["merged_keys"] = [...recorded.mergedKeys];
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
return entries;
|
|
959
|
+
}
|
|
960
|
+
function reconcileToolFiles(fresh, prior, preserved) {
|
|
961
|
+
if (fresh === null || fresh === void 0) {
|
|
962
|
+
return prior === void 0 ? null : prior.files.map((f) => f.entry);
|
|
963
|
+
}
|
|
964
|
+
if (prior === void 0 || preserved.size === 0) return [...fresh];
|
|
965
|
+
const seen = /* @__PURE__ */ new Set();
|
|
966
|
+
for (const entry of fresh) {
|
|
967
|
+
const raw = entry["path"];
|
|
968
|
+
if (typeof raw === "string") seen.add(resolve3(expanduser(raw)));
|
|
969
|
+
}
|
|
970
|
+
const out = [...fresh];
|
|
971
|
+
for (const file of prior.files) {
|
|
972
|
+
const staged = preserved.get(file.resolved);
|
|
973
|
+
if (staged === void 0 || seen.has(file.resolved)) continue;
|
|
974
|
+
out.push(staged.sha256 === null ? file.entry : { ...file.entry, sha256: staged.sha256 });
|
|
975
|
+
if (staged.sidecar !== null) out.push(staged.sidecar);
|
|
976
|
+
}
|
|
977
|
+
return out;
|
|
978
|
+
}
|
|
979
|
+
function preservedIndex(preservedTargets, staged) {
|
|
980
|
+
const out = /* @__PURE__ */ new Map();
|
|
981
|
+
for (const target of preservedTargets) {
|
|
982
|
+
const sidecar = sidecarPathFor(target);
|
|
983
|
+
const sha = staged.get(sidecar) ?? null;
|
|
984
|
+
out.set(resolve3(target), {
|
|
985
|
+
sha256: sha,
|
|
986
|
+
sidecar: sha === null ? null : { path: sidecar, kind: "sidecar", sha256: sha }
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
return out;
|
|
990
|
+
}
|
|
991
|
+
|
|
522
992
|
// src/scripts/_lib/rule_layer_overlap.ts
|
|
523
|
-
import * as
|
|
524
|
-
import * as
|
|
993
|
+
import * as fs5 from "node:fs";
|
|
994
|
+
import * as path5 from "node:path";
|
|
525
995
|
var INSTALLER_PROVENANCE_KEYS = ["package", "source_path"];
|
|
526
996
|
function stripProvenance(text) {
|
|
527
997
|
const lines = text.split("\n");
|
|
@@ -575,14 +1045,14 @@ function compareLayers(global_layer, project_layer) {
|
|
|
575
1045
|
function readRuleLayer(dir) {
|
|
576
1046
|
let names;
|
|
577
1047
|
try {
|
|
578
|
-
names =
|
|
1048
|
+
names = fs5.readdirSync(dir);
|
|
579
1049
|
} catch {
|
|
580
1050
|
return null;
|
|
581
1051
|
}
|
|
582
1052
|
const files = /* @__PURE__ */ new Map();
|
|
583
1053
|
for (const name of names.filter((n) => n.endsWith(".md")).sort()) {
|
|
584
1054
|
try {
|
|
585
|
-
files.set(name,
|
|
1055
|
+
files.set(name, fs5.readFileSync(path5.join(dir, name), "utf-8"));
|
|
586
1056
|
} catch {
|
|
587
1057
|
continue;
|
|
588
1058
|
}
|
|
@@ -590,7 +1060,7 @@ function readRuleLayer(dir) {
|
|
|
590
1060
|
return { dir, files };
|
|
591
1061
|
}
|
|
592
1062
|
function claudeMdExcludesGlob(dir) {
|
|
593
|
-
return `${
|
|
1063
|
+
return `${path5.resolve(dir).replace(/\/+$/, "")}/**`;
|
|
594
1064
|
}
|
|
595
1065
|
function mergeClaudeMdExcludes(existing, entry) {
|
|
596
1066
|
if (!Array.isArray(existing)) return [entry];
|
|
@@ -620,26 +1090,26 @@ function decideLayerAction(report, choice, global_dir, project_dir) {
|
|
|
620
1090
|
|
|
621
1091
|
// src/scripts/_lib/install_drift.ts
|
|
622
1092
|
var import_yaml = __toESM(require_dist(), 1);
|
|
623
|
-
import * as
|
|
624
|
-
import * as
|
|
1093
|
+
import * as crypto3 from "node:crypto";
|
|
1094
|
+
import * as fs6 from "node:fs";
|
|
625
1095
|
import * as os from "node:os";
|
|
626
|
-
import * as
|
|
627
|
-
function
|
|
1096
|
+
import * as path6 from "node:path";
|
|
1097
|
+
function expanduser2(p) {
|
|
628
1098
|
if (p === "~") {
|
|
629
1099
|
return os.homedir();
|
|
630
1100
|
}
|
|
631
1101
|
if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
|
|
632
|
-
return
|
|
1102
|
+
return path6.join(os.homedir(), p.slice(2));
|
|
633
1103
|
}
|
|
634
1104
|
return p;
|
|
635
1105
|
}
|
|
636
1106
|
function resolve_entry_path(project_root, raw) {
|
|
637
|
-
const p =
|
|
638
|
-
return
|
|
1107
|
+
const p = expanduser2(raw);
|
|
1108
|
+
return path6.isAbsolute(p) ? p : path6.join(project_root, p);
|
|
639
1109
|
}
|
|
640
1110
|
function sha256_of_file(p) {
|
|
641
1111
|
try {
|
|
642
|
-
return
|
|
1112
|
+
return crypto3.createHash("sha256").update(fs6.readFileSync(p)).digest("hex");
|
|
643
1113
|
} catch {
|
|
644
1114
|
return null;
|
|
645
1115
|
}
|
|
@@ -648,7 +1118,7 @@ function collect_drift(project_root, env) {
|
|
|
648
1118
|
const target = manifest_path(project_root, env);
|
|
649
1119
|
let text;
|
|
650
1120
|
try {
|
|
651
|
-
text =
|
|
1121
|
+
text = fs6.readFileSync(target, "utf-8");
|
|
652
1122
|
} catch {
|
|
653
1123
|
return null;
|
|
654
1124
|
}
|
|
@@ -693,7 +1163,7 @@ function collect_drift(project_root, env) {
|
|
|
693
1163
|
continue;
|
|
694
1164
|
}
|
|
695
1165
|
const resolved = resolve_entry_path(project_root, raw_path);
|
|
696
|
-
if (!
|
|
1166
|
+
if (!fs6.existsSync(resolved)) {
|
|
697
1167
|
out.push({
|
|
698
1168
|
tool_id,
|
|
699
1169
|
path: resolved,
|
|
@@ -746,15 +1216,15 @@ function format_drift_report(entries) {
|
|
|
746
1216
|
}
|
|
747
1217
|
|
|
748
1218
|
// src/scripts/_lib/skill_catalogue.ts
|
|
749
|
-
import * as
|
|
750
|
-
import * as
|
|
1219
|
+
import * as fs7 from "node:fs";
|
|
1220
|
+
import * as path7 from "node:path";
|
|
751
1221
|
var PROJECT_CATALOGUE_ROOTS = ["src/skills", ".claude/skills"];
|
|
752
1222
|
var HOST_CATALOGUE_ROOT = ".claude/skills";
|
|
753
1223
|
var DEFAULT_CATALOGUE_ROOTS = [
|
|
754
1224
|
...PROJECT_CATALOGUE_ROOTS,
|
|
755
1225
|
`~/${HOST_CATALOGUE_ROOT}`
|
|
756
1226
|
];
|
|
757
|
-
var OBSERVATION_LOG =
|
|
1227
|
+
var OBSERVATION_LOG = path7.join(
|
|
758
1228
|
"agents",
|
|
759
1229
|
"evidence",
|
|
760
1230
|
"metrics",
|
|
@@ -798,9 +1268,9 @@ function descriptionOf(frontmatter) {
|
|
|
798
1268
|
return "";
|
|
799
1269
|
}
|
|
800
1270
|
function readProjectedCatalogue(root) {
|
|
801
|
-
const names =
|
|
1271
|
+
const names = fs7.readdirSync(root).filter((n) => fs7.existsSync(path7.join(root, n, "SKILL.md"))).sort();
|
|
802
1272
|
return names.map((name, index) => {
|
|
803
|
-
const content =
|
|
1273
|
+
const content = fs7.readFileSync(path7.join(root, name, "SKILL.md"), "utf-8");
|
|
804
1274
|
const frontmatter = frontmatterOf(content);
|
|
805
1275
|
const description = descriptionOf(frontmatter);
|
|
806
1276
|
return {
|
|
@@ -817,12 +1287,12 @@ function truncationModeOf(record) {
|
|
|
817
1287
|
return record.truncation_mode ?? "per-entry";
|
|
818
1288
|
}
|
|
819
1289
|
function markdownFilesUnder(root) {
|
|
820
|
-
if (!
|
|
1290
|
+
if (!fs7.existsSync(root)) return [];
|
|
821
1291
|
const out = [];
|
|
822
1292
|
const walk = (dir) => {
|
|
823
|
-
for (const entry of
|
|
824
|
-
const full =
|
|
825
|
-
if (
|
|
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);
|
|
826
1296
|
else if (entry.name.endsWith(".md")) out.push(full);
|
|
827
1297
|
}
|
|
828
1298
|
};
|
|
@@ -830,9 +1300,9 @@ function markdownFilesUnder(root) {
|
|
|
830
1300
|
return out;
|
|
831
1301
|
}
|
|
832
1302
|
function measureCatalogueVolume(host, root) {
|
|
833
|
-
const skillsRoot =
|
|
834
|
-
const skills =
|
|
835
|
-
const commandEntries = markdownFilesUnder(
|
|
1303
|
+
const skillsRoot = path7.join(root, "skills");
|
|
1304
|
+
const skills = fs7.existsSync(skillsRoot) ? readProjectedCatalogue(skillsRoot) : [];
|
|
1305
|
+
const commandEntries = markdownFilesUnder(path7.join(root, "commands")).length;
|
|
836
1306
|
return {
|
|
837
1307
|
host,
|
|
838
1308
|
root,
|
|
@@ -910,9 +1380,9 @@ function migrationPromptLines(host, eligibility, settingsPath) {
|
|
|
910
1380
|
];
|
|
911
1381
|
}
|
|
912
1382
|
function readObservationLog(logPath) {
|
|
913
|
-
if (!
|
|
1383
|
+
if (!fs7.existsSync(logPath)) return [];
|
|
914
1384
|
const out = [];
|
|
915
|
-
for (const line of
|
|
1385
|
+
for (const line of fs7.readFileSync(logPath, "utf-8").split("\n")) {
|
|
916
1386
|
const trimmed = line.trim();
|
|
917
1387
|
if (trimmed.length === 0) continue;
|
|
918
1388
|
try {
|
|
@@ -952,9 +1422,9 @@ function isInteractiveSession(probe) {
|
|
|
952
1422
|
}
|
|
953
1423
|
|
|
954
1424
|
// src/scripts/_lib/claude_desktop_bundler.ts
|
|
955
|
-
import * as
|
|
956
|
-
import * as
|
|
957
|
-
import * as
|
|
1425
|
+
import * as crypto4 from "node:crypto";
|
|
1426
|
+
import * as fs8 from "node:fs";
|
|
1427
|
+
import * as path8 from "node:path";
|
|
958
1428
|
|
|
959
1429
|
// src/scripts/_lib/zip_min.ts
|
|
960
1430
|
import * as zlib from "node:zlib";
|
|
@@ -1061,7 +1531,7 @@ function _is_excluded(rel_parts) {
|
|
|
1061
1531
|
}
|
|
1062
1532
|
function _is_dir(p) {
|
|
1063
1533
|
try {
|
|
1064
|
-
return
|
|
1534
|
+
return fs8.statSync(p).isDirectory();
|
|
1065
1535
|
} catch {
|
|
1066
1536
|
return false;
|
|
1067
1537
|
}
|
|
@@ -1073,12 +1543,12 @@ function _compare_rel_parts(a, b) {
|
|
|
1073
1543
|
}
|
|
1074
1544
|
function _walk_skill_files(skill_dir) {
|
|
1075
1545
|
const out = [];
|
|
1076
|
-
const resolved =
|
|
1546
|
+
const resolved = fs8.realpathSync(skill_dir);
|
|
1077
1547
|
const walk = (root, relRoot) => {
|
|
1078
1548
|
const dirNames = [];
|
|
1079
1549
|
const fileNames = [];
|
|
1080
|
-
for (const dirent of
|
|
1081
|
-
const full =
|
|
1550
|
+
for (const dirent of fs8.readdirSync(root, { withFileTypes: true })) {
|
|
1551
|
+
const full = path8.join(root, dirent.name);
|
|
1082
1552
|
const isDir2 = dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full);
|
|
1083
1553
|
if (isDir2) {
|
|
1084
1554
|
dirNames.push(dirent.name);
|
|
@@ -1091,13 +1561,13 @@ function _walk_skill_files(skill_dir) {
|
|
|
1091
1561
|
if (_is_excluded(rel_parts)) {
|
|
1092
1562
|
continue;
|
|
1093
1563
|
}
|
|
1094
|
-
out.push([
|
|
1564
|
+
out.push([path8.join(root, fname), rel_parts]);
|
|
1095
1565
|
}
|
|
1096
1566
|
for (const dname of dirNames) {
|
|
1097
1567
|
if (_is_excluded([dname])) {
|
|
1098
1568
|
continue;
|
|
1099
1569
|
}
|
|
1100
|
-
walk(
|
|
1570
|
+
walk(path8.join(root, dname), [...relRoot, dname]);
|
|
1101
1571
|
}
|
|
1102
1572
|
};
|
|
1103
1573
|
walk(resolved, []);
|
|
@@ -1105,58 +1575,58 @@ function _walk_skill_files(skill_dir) {
|
|
|
1105
1575
|
return out;
|
|
1106
1576
|
}
|
|
1107
1577
|
function _manifest_digest(files) {
|
|
1108
|
-
const h =
|
|
1578
|
+
const h = crypto4.createHash("sha256");
|
|
1109
1579
|
for (const [abs_path, rel_parts] of files) {
|
|
1110
1580
|
const rel = rel_parts.join("/");
|
|
1111
1581
|
h.update(Buffer.from(rel, "utf-8"));
|
|
1112
1582
|
h.update(Buffer.from([0]));
|
|
1113
|
-
h.update(
|
|
1583
|
+
h.update(crypto4.createHash("sha256").update(fs8.readFileSync(abs_path)).digest());
|
|
1114
1584
|
h.update(Buffer.from([0]));
|
|
1115
1585
|
}
|
|
1116
1586
|
return h.digest("hex");
|
|
1117
1587
|
}
|
|
1118
1588
|
function _atomic_write_zip(zip_path, files) {
|
|
1119
|
-
|
|
1120
|
-
const stem =
|
|
1121
|
-
const tmp_path =
|
|
1122
|
-
|
|
1123
|
-
`.${stem}.${
|
|
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),
|
|
1593
|
+
`.${stem}.${crypto4.randomBytes(6).toString("hex")}.zip.tmp`
|
|
1124
1594
|
);
|
|
1125
1595
|
try {
|
|
1126
1596
|
const entries = files.map(([abs_path, rel_parts]) => ({
|
|
1127
1597
|
name: rel_parts.join("/"),
|
|
1128
|
-
data:
|
|
1598
|
+
data: fs8.readFileSync(abs_path)
|
|
1129
1599
|
}));
|
|
1130
|
-
|
|
1131
|
-
|
|
1600
|
+
fs8.writeFileSync(tmp_path, zip_write_sync(entries));
|
|
1601
|
+
fs8.renameSync(tmp_path, zip_path);
|
|
1132
1602
|
} finally {
|
|
1133
|
-
if (
|
|
1134
|
-
|
|
1603
|
+
if (fs8.existsSync(tmp_path)) {
|
|
1604
|
+
fs8.unlinkSync(tmp_path);
|
|
1135
1605
|
}
|
|
1136
1606
|
}
|
|
1137
1607
|
}
|
|
1138
1608
|
function _write_if_changed(dest_dir, slug, files, force, written) {
|
|
1139
1609
|
const digest = _manifest_digest(files);
|
|
1140
|
-
const zip_path =
|
|
1141
|
-
const digest_path =
|
|
1142
|
-
const recorded =
|
|
1143
|
-
if (!force && recorded === digest &&
|
|
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)) {
|
|
1144
1614
|
return;
|
|
1145
1615
|
}
|
|
1146
1616
|
_atomic_write_zip(zip_path, files);
|
|
1147
|
-
|
|
1617
|
+
fs8.writeFileSync(digest_path, digest + "\n", "utf-8");
|
|
1148
1618
|
written.push(zip_path);
|
|
1149
1619
|
}
|
|
1150
1620
|
function build_skill_bundles(package_root, dest_dir, force = false, curation = null) {
|
|
1151
|
-
const skills_root =
|
|
1621
|
+
const skills_root = path8.join(package_root, "dist/agent-src", "skills");
|
|
1152
1622
|
if (!_is_dir(skills_root)) {
|
|
1153
1623
|
return [];
|
|
1154
1624
|
}
|
|
1155
|
-
|
|
1625
|
+
fs8.mkdirSync(dest_dir, { recursive: true });
|
|
1156
1626
|
const written = [];
|
|
1157
|
-
for (const name of
|
|
1158
|
-
const entry =
|
|
1159
|
-
const isSymlink2 =
|
|
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();
|
|
1160
1630
|
if (!(_is_dir(entry) || isSymlink2)) {
|
|
1161
1631
|
continue;
|
|
1162
1632
|
}
|
|
@@ -1164,8 +1634,8 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
|
|
|
1164
1634
|
if (curation !== null && !curation.includes(skill_name)) {
|
|
1165
1635
|
continue;
|
|
1166
1636
|
}
|
|
1167
|
-
const skill_md =
|
|
1168
|
-
if (!
|
|
1637
|
+
const skill_md = path8.join(entry, "SKILL.md");
|
|
1638
|
+
if (!fs8.existsSync(skill_md)) {
|
|
1169
1639
|
continue;
|
|
1170
1640
|
}
|
|
1171
1641
|
const files = _walk_skill_files(entry);
|
|
@@ -1177,15 +1647,15 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
|
|
|
1177
1647
|
return written;
|
|
1178
1648
|
}
|
|
1179
1649
|
function _command_slug(source_file, commands_root) {
|
|
1180
|
-
const rel =
|
|
1181
|
-
const noExt = rel.slice(0, rel.length -
|
|
1182
|
-
return noExt.split(
|
|
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("-");
|
|
1183
1653
|
}
|
|
1184
1654
|
function _iter_command_files(commands_root) {
|
|
1185
1655
|
const found = [];
|
|
1186
1656
|
const walk = (dir) => {
|
|
1187
|
-
for (const dirent of
|
|
1188
|
-
const full =
|
|
1657
|
+
for (const dirent of fs8.readdirSync(dir, { withFileTypes: true })) {
|
|
1658
|
+
const full = path8.join(dir, dirent.name);
|
|
1189
1659
|
if (dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full)) {
|
|
1190
1660
|
walk(full);
|
|
1191
1661
|
} else if (dirent.name.endsWith(".md")) {
|
|
@@ -1195,21 +1665,21 @@ function _iter_command_files(commands_root) {
|
|
|
1195
1665
|
};
|
|
1196
1666
|
walk(commands_root);
|
|
1197
1667
|
found.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
1198
|
-
return found.filter((source_file) =>
|
|
1668
|
+
return found.filter((source_file) => path8.basename(source_file) !== "AGENTS.md");
|
|
1199
1669
|
}
|
|
1200
1670
|
function build_command_bundles(package_root, dest_dir, force = false, curation = null) {
|
|
1201
|
-
const commands_root =
|
|
1671
|
+
const commands_root = path8.join(package_root, "dist/agent-src", "commands");
|
|
1202
1672
|
if (!_is_dir(commands_root)) {
|
|
1203
1673
|
return [];
|
|
1204
1674
|
}
|
|
1205
|
-
const skills_root =
|
|
1675
|
+
const skills_root = path8.join(package_root, "dist/agent-src", "skills");
|
|
1206
1676
|
let skill_names = /* @__PURE__ */ new Set();
|
|
1207
1677
|
if (_is_dir(skills_root)) {
|
|
1208
1678
|
skill_names = new Set(
|
|
1209
|
-
|
|
1679
|
+
fs8.readdirSync(skills_root).filter((name) => _is_dir(path8.join(skills_root, name)))
|
|
1210
1680
|
);
|
|
1211
1681
|
}
|
|
1212
|
-
|
|
1682
|
+
fs8.mkdirSync(dest_dir, { recursive: true });
|
|
1213
1683
|
const written = [];
|
|
1214
1684
|
for (const source_file of _iter_command_files(commands_root)) {
|
|
1215
1685
|
const slug = _command_slug(source_file, commands_root);
|
|
@@ -1219,7 +1689,7 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
|
|
|
1219
1689
|
if (curation !== null && !curation.includes(slug)) {
|
|
1220
1690
|
continue;
|
|
1221
1691
|
}
|
|
1222
|
-
const files = [[
|
|
1692
|
+
const files = [[fs8.realpathSync(source_file), ["SKILL.md"]]];
|
|
1223
1693
|
_write_if_changed(dest_dir, slug, files, force, written);
|
|
1224
1694
|
}
|
|
1225
1695
|
return written;
|
|
@@ -1227,15 +1697,25 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
|
|
|
1227
1697
|
|
|
1228
1698
|
// src/scripts/hooks/host_lowering.ts
|
|
1229
1699
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
1230
|
-
import * as
|
|
1231
|
-
import * as
|
|
1700
|
+
import * as fs9 from "node:fs";
|
|
1701
|
+
import * as path9 from "node:path";
|
|
1232
1702
|
import { fileURLToPath } from "node:url";
|
|
1703
|
+
|
|
1704
|
+
// src/scripts/hooks/table_fingerprint.ts
|
|
1705
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
1706
|
+
function tableFingerprint(text) {
|
|
1707
|
+
const digest = createHash5("sha256").update(text, "utf-8").digest("hex");
|
|
1708
|
+
return `${digest}:${String(text.length)}`;
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
// src/scripts/hooks/host_lowering.ts
|
|
1233
1712
|
var _IN_BUNDLE = true;
|
|
1234
|
-
var _REPO_ROOT =
|
|
1235
|
-
|
|
1713
|
+
var _REPO_ROOT = path9.resolve(
|
|
1714
|
+
path9.dirname(fileURLToPath(import.meta.url)),
|
|
1236
1715
|
..._IN_BUNDLE ? ["..", ".."] : ["..", "..", ".."]
|
|
1237
1716
|
);
|
|
1238
|
-
var HOST_LOWERING_PATH =
|
|
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");
|
|
1239
1719
|
var DEFAULT_SURFACE = "any";
|
|
1240
1720
|
function _asString(v) {
|
|
1241
1721
|
if (v === null || v === void 0) return null;
|
|
@@ -1243,7 +1723,9 @@ function _asString(v) {
|
|
|
1243
1723
|
return String(v);
|
|
1244
1724
|
}
|
|
1245
1725
|
function _parse(text) {
|
|
1246
|
-
|
|
1726
|
+
return _structure((0, import_yaml2.parse)(text));
|
|
1727
|
+
}
|
|
1728
|
+
function _structure(raw) {
|
|
1247
1729
|
const hostsRaw = raw?.["hosts"];
|
|
1248
1730
|
if (typeof hostsRaw !== "object" || hostsRaw === null) {
|
|
1249
1731
|
throw new Error("host_lowering.yaml: missing `hosts:` map");
|
|
@@ -1267,6 +1749,7 @@ function _parse(text) {
|
|
|
1267
1749
|
verified = {
|
|
1268
1750
|
docs_at: _asString(verifiedRaw["docs_at"]),
|
|
1269
1751
|
docs_url: _asString(verifiedRaw["docs_url"]),
|
|
1752
|
+
docs_digest: _asString(verifiedRaw["docs_digest"]),
|
|
1270
1753
|
probe_at: _asString(verifiedRaw["probe_at"]),
|
|
1271
1754
|
host_version: _asString(verifiedRaw["host_version"]),
|
|
1272
1755
|
expires
|
|
@@ -1280,7 +1763,9 @@ function _parse(text) {
|
|
|
1280
1763
|
const be = rv["block_exit"];
|
|
1281
1764
|
const row = {
|
|
1282
1765
|
native,
|
|
1283
|
-
block_exit: typeof be === "number" ? be : null
|
|
1766
|
+
block_exit: typeof be === "number" ? be : null,
|
|
1767
|
+
answered_at: _asString(rv["answered_at"]),
|
|
1768
|
+
docs_url: _asString(rv["docs_url"])
|
|
1284
1769
|
};
|
|
1285
1770
|
if (typeof rv["matcher"] === "string") row.matcher = rv["matcher"];
|
|
1286
1771
|
slots.set(slot, row);
|
|
@@ -1301,9 +1786,30 @@ function _parse(text) {
|
|
|
1301
1786
|
}
|
|
1302
1787
|
var _cache = null;
|
|
1303
1788
|
function loadHostLowering() {
|
|
1304
|
-
if (_cache
|
|
1789
|
+
if (_cache !== null) return _cache;
|
|
1790
|
+
const text = fs9.readFileSync(HOST_LOWERING_PATH, "utf-8");
|
|
1791
|
+
let compiled;
|
|
1792
|
+
try {
|
|
1793
|
+
compiled = fs9.readFileSync(HOST_LOWERING_JSON_PATH, "utf-8");
|
|
1794
|
+
} catch {
|
|
1795
|
+
compiled = null;
|
|
1796
|
+
}
|
|
1797
|
+
_cache = resolveTable(text, compiled);
|
|
1305
1798
|
return _cache;
|
|
1306
1799
|
}
|
|
1800
|
+
function resolveTable(yamlText, compiledText) {
|
|
1801
|
+
if (compiledText !== null) {
|
|
1802
|
+
try {
|
|
1803
|
+
const raw = JSON.parse(compiledText);
|
|
1804
|
+
const table = raw["table"];
|
|
1805
|
+
if (raw["fingerprint"] === tableFingerprint(yamlText) && typeof table === "object" && table !== null) {
|
|
1806
|
+
return _structure(table);
|
|
1807
|
+
}
|
|
1808
|
+
} catch {
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
return _parse(yamlText);
|
|
1812
|
+
}
|
|
1307
1813
|
function surfaceRow(host, surface = DEFAULT_SURFACE, table = loadHostLowering()) {
|
|
1308
1814
|
return table.get(host)?.get(surface) ?? table.get(host)?.get(DEFAULT_SURFACE) ?? null;
|
|
1309
1815
|
}
|
|
@@ -1320,26 +1826,26 @@ function hostBindings(host, table = loadHostLowering()) {
|
|
|
1320
1826
|
}
|
|
1321
1827
|
|
|
1322
1828
|
// src/install/partitionEligibility.ts
|
|
1323
|
-
import * as
|
|
1829
|
+
import * as fs11 from "node:fs";
|
|
1324
1830
|
import * as os2 from "node:os";
|
|
1325
1831
|
|
|
1326
1832
|
// src/install/hostLayerFingerprint.ts
|
|
1327
|
-
import { createHash as
|
|
1328
|
-
import * as
|
|
1329
|
-
import * as
|
|
1833
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
1834
|
+
import * as fs10 from "node:fs";
|
|
1835
|
+
import * as path10 from "node:path";
|
|
1330
1836
|
var FINGERPRINT_SCHEMA = 1;
|
|
1331
1837
|
function collectFiles(dir) {
|
|
1332
1838
|
const out = [];
|
|
1333
1839
|
const walk = (d) => {
|
|
1334
1840
|
let entries;
|
|
1335
1841
|
try {
|
|
1336
|
-
entries =
|
|
1842
|
+
entries = fs10.readdirSync(d, { withFileTypes: true });
|
|
1337
1843
|
} catch {
|
|
1338
1844
|
return;
|
|
1339
1845
|
}
|
|
1340
1846
|
const sorted = [...entries].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
1341
1847
|
for (const e of sorted) {
|
|
1342
|
-
const p =
|
|
1848
|
+
const p = path10.join(d, e.name);
|
|
1343
1849
|
if (e.isDirectory()) {
|
|
1344
1850
|
walk(p);
|
|
1345
1851
|
} else if (e.isFile()) {
|
|
@@ -1351,15 +1857,15 @@ function collectFiles(dir) {
|
|
|
1351
1857
|
return out.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
1352
1858
|
}
|
|
1353
1859
|
function fingerprintLayers(layers) {
|
|
1354
|
-
const h =
|
|
1860
|
+
const h = createHash6("sha256");
|
|
1355
1861
|
h.update(`v${FINGERPRINT_SCHEMA}\0`);
|
|
1356
1862
|
for (const layer of layers) {
|
|
1357
1863
|
h.update(`layer:${layer.label}\0`);
|
|
1358
1864
|
for (const file of collectFiles(layer.root)) {
|
|
1359
|
-
h.update(
|
|
1865
|
+
h.update(path10.relative(layer.root, file));
|
|
1360
1866
|
h.update("\0");
|
|
1361
1867
|
try {
|
|
1362
|
-
h.update(
|
|
1868
|
+
h.update(fs10.readFileSync(file));
|
|
1363
1869
|
} catch {
|
|
1364
1870
|
h.update("\0unreadable\0");
|
|
1365
1871
|
}
|
|
@@ -1369,11 +1875,11 @@ function fingerprintLayers(layers) {
|
|
|
1369
1875
|
return h.digest("hex");
|
|
1370
1876
|
}
|
|
1371
1877
|
function hostLayerInputs(userHome) {
|
|
1372
|
-
const claude =
|
|
1878
|
+
const claude = path10.join(userHome, ".claude");
|
|
1373
1879
|
return [
|
|
1374
|
-
{ label: "rules", root:
|
|
1375
|
-
{ label: "skills", root:
|
|
1376
|
-
{ label: "commands", root:
|
|
1880
|
+
{ label: "rules", root: path10.join(claude, "rules") },
|
|
1881
|
+
{ label: "skills", root: path10.join(claude, "skills") },
|
|
1882
|
+
{ label: "commands", root: path10.join(claude, "commands") }
|
|
1377
1883
|
];
|
|
1378
1884
|
}
|
|
1379
1885
|
|
|
@@ -1382,7 +1888,7 @@ var MAINTAINER_WORKSPACE = "agent-config-maintainer";
|
|
|
1382
1888
|
function isExclusivelyPackageOnly(source_path) {
|
|
1383
1889
|
let meta;
|
|
1384
1890
|
try {
|
|
1385
|
-
[meta] = parseFrontmatter(
|
|
1891
|
+
[meta] = parseFrontmatter(fs11.readFileSync(source_path, "utf-8"));
|
|
1386
1892
|
} catch {
|
|
1387
1893
|
return false;
|
|
1388
1894
|
}
|
|
@@ -1413,8 +1919,8 @@ function stampHostLayerFingerprint(installedVersion, tools, lockfilePath, skip2,
|
|
|
1413
1919
|
}
|
|
1414
1920
|
|
|
1415
1921
|
// src/install/claudeRuleRewrite.ts
|
|
1416
|
-
import * as
|
|
1417
|
-
import * as
|
|
1922
|
+
import * as fs12 from "node:fs";
|
|
1923
|
+
import * as path11 from "node:path";
|
|
1418
1924
|
|
|
1419
1925
|
// src/install/claudePathsPlan.ts
|
|
1420
1926
|
function derive_trigger_globs(meta) {
|
|
@@ -1516,8 +2022,8 @@ function _withPreservedKeys(rendered, original) {
|
|
|
1516
2022
|
}
|
|
1517
2023
|
return ["---", ...keep, "---", "", rendered].join("\n");
|
|
1518
2024
|
}
|
|
1519
|
-
function rewriteAndReport(rulesDir, quiet, info2, warn2, wrappers) {
|
|
1520
|
-
const result = rewriteClaudeRules(rulesDir);
|
|
2025
|
+
function rewriteAndReport(rulesDir, quiet, info2, warn2, wrappers, preserved = /* @__PURE__ */ new Set()) {
|
|
2026
|
+
const result = rewriteClaudeRules(rulesDir, preserved);
|
|
1521
2027
|
if (wrappers && !quiet) {
|
|
1522
2028
|
if (wrappers.wrapped.length > 0) {
|
|
1523
2029
|
info2(
|
|
@@ -1566,26 +2072,27 @@ function renderClaudeRule(sourceText) {
|
|
|
1566
2072
|
lines.push(pyRstrip(body) + "\n");
|
|
1567
2073
|
return { text: lines.join("\n"), globs: plan.globs, dropped: plan.dropped };
|
|
1568
2074
|
}
|
|
1569
|
-
function rewriteClaudeRules(rulesDir) {
|
|
2075
|
+
function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
|
|
1570
2076
|
const result = { rewritten: 0, scoped: [], dropped: [], failed: [] };
|
|
1571
2077
|
let entries;
|
|
1572
2078
|
try {
|
|
1573
|
-
entries =
|
|
2079
|
+
entries = fs12.readdirSync(rulesDir);
|
|
1574
2080
|
} catch {
|
|
1575
2081
|
return result;
|
|
1576
2082
|
}
|
|
1577
2083
|
for (const name of entries.filter((n) => n.endsWith(".md")).sort()) {
|
|
1578
|
-
const full =
|
|
2084
|
+
const full = path11.join(rulesDir, name);
|
|
2085
|
+
if (preserved.has(path11.resolve(full))) continue;
|
|
1579
2086
|
let stat;
|
|
1580
2087
|
try {
|
|
1581
|
-
stat =
|
|
2088
|
+
stat = fs12.lstatSync(full);
|
|
1582
2089
|
} catch {
|
|
1583
2090
|
continue;
|
|
1584
2091
|
}
|
|
1585
2092
|
if (!stat.isFile() || stat.isSymbolicLink()) continue;
|
|
1586
2093
|
let text;
|
|
1587
2094
|
try {
|
|
1588
|
-
text =
|
|
2095
|
+
text = fs12.readFileSync(full, "utf-8");
|
|
1589
2096
|
} catch {
|
|
1590
2097
|
continue;
|
|
1591
2098
|
}
|
|
@@ -1595,7 +2102,7 @@ function rewriteClaudeRules(rulesDir) {
|
|
|
1595
2102
|
const withOwnership = _withPreservedKeys(rendered.text, text);
|
|
1596
2103
|
if (withOwnership !== text) {
|
|
1597
2104
|
try {
|
|
1598
|
-
|
|
2105
|
+
fs12.writeFileSync(full, withOwnership, "utf-8");
|
|
1599
2106
|
} catch (e) {
|
|
1600
2107
|
result.failed.push({
|
|
1601
2108
|
rule: name.slice(0, -3),
|
|
@@ -2969,8 +3476,8 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
2969
3476
|
};
|
|
2970
3477
|
|
|
2971
3478
|
// src/scripts/_lib/module_detection.ts
|
|
2972
|
-
import * as
|
|
2973
|
-
import * as
|
|
3479
|
+
import * as fs13 from "node:fs";
|
|
3480
|
+
import * as path12 from "node:path";
|
|
2974
3481
|
var _SKIP_DIRS = /* @__PURE__ */ new Set([".module-template", ".example"]);
|
|
2975
3482
|
var _RULES = [
|
|
2976
3483
|
["app/Modules", "laravel-hmvc", "App\\Modules\\{ModuleName}"],
|
|
@@ -2984,14 +3491,14 @@ var _RULES = [
|
|
|
2984
3491
|
];
|
|
2985
3492
|
function _isDir(p) {
|
|
2986
3493
|
try {
|
|
2987
|
-
return
|
|
3494
|
+
return fs13.statSync(p).isDirectory();
|
|
2988
3495
|
} catch {
|
|
2989
3496
|
return false;
|
|
2990
3497
|
}
|
|
2991
3498
|
}
|
|
2992
3499
|
function _isFile(p) {
|
|
2993
3500
|
try {
|
|
2994
|
-
return
|
|
3501
|
+
return fs13.statSync(p).isFile();
|
|
2995
3502
|
} catch {
|
|
2996
3503
|
return false;
|
|
2997
3504
|
}
|
|
@@ -3005,13 +3512,13 @@ function _isUpperChar(ch) {
|
|
|
3005
3512
|
function _list_module_subdirs(root) {
|
|
3006
3513
|
let entries;
|
|
3007
3514
|
try {
|
|
3008
|
-
entries =
|
|
3515
|
+
entries = fs13.readdirSync(root).sort();
|
|
3009
3516
|
} catch {
|
|
3010
3517
|
return [];
|
|
3011
3518
|
}
|
|
3012
3519
|
const out = [];
|
|
3013
3520
|
for (const name of entries) {
|
|
3014
|
-
if (!_isDir(
|
|
3521
|
+
if (!_isDir(path12.join(root, name))) {
|
|
3015
3522
|
continue;
|
|
3016
3523
|
}
|
|
3017
3524
|
if (name.startsWith(".")) {
|
|
@@ -3033,11 +3540,11 @@ function _score_confidence(stack, root, subdirs) {
|
|
|
3033
3540
|
return capitalized.length > 0 ? "high" : "medium";
|
|
3034
3541
|
}
|
|
3035
3542
|
if (stack === "node-monorepo") {
|
|
3036
|
-
const withPkgJson = subdirs.filter((name) => _isFile(
|
|
3543
|
+
const withPkgJson = subdirs.filter((name) => _isFile(path12.join(root, name, "package.json")));
|
|
3037
3544
|
return withPkgJson.length > 0 ? "high" : "medium";
|
|
3038
3545
|
}
|
|
3039
3546
|
if (stack === "python-src") {
|
|
3040
|
-
const withInit = subdirs.filter((name) => _isFile(
|
|
3547
|
+
const withInit = subdirs.filter((name) => _isFile(path12.join(root, name, "__init__.py")));
|
|
3041
3548
|
return withInit.length > 0 ? "high" : "medium";
|
|
3042
3549
|
}
|
|
3043
3550
|
if (stack === "go-internal") {
|
|
@@ -3049,7 +3556,7 @@ function detect_module_roots(project_root) {
|
|
|
3049
3556
|
const high = [];
|
|
3050
3557
|
const medium = [];
|
|
3051
3558
|
for (const [rel_path, stack, namespace_template] of _RULES) {
|
|
3052
|
-
const abs_path =
|
|
3559
|
+
const abs_path = path12.join(project_root, rel_path);
|
|
3053
3560
|
if (!_isDir(abs_path)) {
|
|
3054
3561
|
continue;
|
|
3055
3562
|
}
|
|
@@ -3071,7 +3578,7 @@ function detect_module_roots(project_root) {
|
|
|
3071
3578
|
}
|
|
3072
3579
|
|
|
3073
3580
|
// src/scripts/_lib/model_tier.ts
|
|
3074
|
-
import
|
|
3581
|
+
import fs14 from "node:fs";
|
|
3075
3582
|
var TIER_TO_CLAUDE_MODEL = {
|
|
3076
3583
|
frontier: "fable",
|
|
3077
3584
|
high: "opus",
|
|
@@ -3080,8 +3587,8 @@ var TIER_TO_CLAUDE_MODEL = {
|
|
|
3080
3587
|
};
|
|
3081
3588
|
var MODEL_TIER_RE = /^model_tier:\s*"?([a-z]+)"?\s*$/m;
|
|
3082
3589
|
function read_model_tier(skill_md) {
|
|
3083
|
-
if (!
|
|
3084
|
-
const text =
|
|
3590
|
+
if (!fs14.existsSync(skill_md)) return null;
|
|
3591
|
+
const text = fs14.readFileSync(skill_md).toString("utf-8");
|
|
3085
3592
|
if (!text.startsWith("---\n")) return null;
|
|
3086
3593
|
const end = text.indexOf("\n---\n", 4);
|
|
3087
3594
|
if (end === -1) return null;
|
|
@@ -3096,6 +3603,30 @@ function render_native_model_md(text, tier) {
|
|
|
3096
3603
|
return text.replace(MODEL_TIER_RE, `model: ${model}`);
|
|
3097
3604
|
}
|
|
3098
3605
|
|
|
3606
|
+
// src/install/paths.ts
|
|
3607
|
+
import { homedir as homedir4, tmpdir } from "node:os";
|
|
3608
|
+
import { join as join13 } from "node:path";
|
|
3609
|
+
var INSTALL_ROOT_SUBPATH = ".event4u/agent-config";
|
|
3610
|
+
var INSTALL_LOG_FILENAME = "install-log.jsonl";
|
|
3611
|
+
function resolveHome(home) {
|
|
3612
|
+
if (home && home.length > 0) {
|
|
3613
|
+
return home;
|
|
3614
|
+
}
|
|
3615
|
+
const fromOs = homedir4();
|
|
3616
|
+
if (!fromOs) {
|
|
3617
|
+
throw new Error(
|
|
3618
|
+
"Cannot resolve home directory \u2014 both $HOME (POSIX) and $USERPROFILE (Windows) are unset."
|
|
3619
|
+
);
|
|
3620
|
+
}
|
|
3621
|
+
return fromOs;
|
|
3622
|
+
}
|
|
3623
|
+
function getInstallRoot(home) {
|
|
3624
|
+
return join13(resolveHome(home), INSTALL_ROOT_SUBPATH);
|
|
3625
|
+
}
|
|
3626
|
+
function getLogPath(home) {
|
|
3627
|
+
return join13(getInstallRoot(home), INSTALL_LOG_FILENAME);
|
|
3628
|
+
}
|
|
3629
|
+
|
|
3099
3630
|
// src/scripts/install.ts
|
|
3100
3631
|
var _HERE = fileURLToPath2(import.meta.url);
|
|
3101
3632
|
var SystemExitError = class extends Error {
|
|
@@ -3112,62 +3643,44 @@ var ArgparseExit = class extends Error {
|
|
|
3112
3643
|
}
|
|
3113
3644
|
code;
|
|
3114
3645
|
};
|
|
3115
|
-
function
|
|
3646
|
+
function expanduser3(p) {
|
|
3116
3647
|
if (p === "~") return os3.homedir();
|
|
3117
3648
|
if (p.startsWith("~/") || p.startsWith("~\\")) {
|
|
3118
|
-
return
|
|
3649
|
+
return path13.join(os3.homedir(), p.slice(2));
|
|
3119
3650
|
}
|
|
3120
3651
|
return p;
|
|
3121
3652
|
}
|
|
3122
|
-
function resolvePath(p) {
|
|
3123
|
-
try {
|
|
3124
|
-
return fs12.realpathSync(path10.resolve(p));
|
|
3125
|
-
} catch {
|
|
3126
|
-
return path10.resolve(p);
|
|
3127
|
-
}
|
|
3128
|
-
}
|
|
3129
3653
|
function isFile(p) {
|
|
3130
3654
|
try {
|
|
3131
|
-
return
|
|
3655
|
+
return fs15.statSync(p).isFile();
|
|
3132
3656
|
} catch {
|
|
3133
3657
|
return false;
|
|
3134
3658
|
}
|
|
3135
3659
|
}
|
|
3136
3660
|
function isDir(p) {
|
|
3137
3661
|
try {
|
|
3138
|
-
return
|
|
3139
|
-
} catch {
|
|
3140
|
-
return false;
|
|
3141
|
-
}
|
|
3142
|
-
}
|
|
3143
|
-
function pathExists(p) {
|
|
3144
|
-
try {
|
|
3145
|
-
fs12.statSync(p);
|
|
3146
|
-
return true;
|
|
3662
|
+
return fs15.statSync(p).isDirectory();
|
|
3147
3663
|
} catch {
|
|
3148
3664
|
return false;
|
|
3149
3665
|
}
|
|
3150
3666
|
}
|
|
3151
3667
|
function isSymlink(p) {
|
|
3152
3668
|
try {
|
|
3153
|
-
return
|
|
3669
|
+
return fs15.lstatSync(p).isSymbolicLink();
|
|
3154
3670
|
} catch {
|
|
3155
3671
|
return false;
|
|
3156
3672
|
}
|
|
3157
3673
|
}
|
|
3158
3674
|
function readText(p) {
|
|
3159
|
-
return
|
|
3675
|
+
return fs15.readFileSync(p, "utf-8");
|
|
3160
3676
|
}
|
|
3161
3677
|
function writeText(p, content) {
|
|
3162
|
-
|
|
3163
|
-
}
|
|
3164
|
-
function mkdirp(p) {
|
|
3165
|
-
fs12.mkdirSync(p, { recursive: true });
|
|
3678
|
+
fs15.writeFileSync(p, content, "utf-8");
|
|
3166
3679
|
}
|
|
3167
3680
|
function sortedGlobStems(directory, suffix) {
|
|
3168
3681
|
let entries;
|
|
3169
3682
|
try {
|
|
3170
|
-
entries =
|
|
3683
|
+
entries = fs15.readdirSync(directory);
|
|
3171
3684
|
} catch {
|
|
3172
3685
|
return [];
|
|
3173
3686
|
}
|
|
@@ -3187,43 +3700,34 @@ function sortedGlobStems(directory, suffix) {
|
|
|
3187
3700
|
function countZips(directory) {
|
|
3188
3701
|
if (!isDir(directory)) return 0;
|
|
3189
3702
|
let n = 0;
|
|
3190
|
-
for (const name of
|
|
3703
|
+
for (const name of fs15.readdirSync(directory)) {
|
|
3191
3704
|
if (name.endsWith(".zip")) n += 1;
|
|
3192
3705
|
}
|
|
3193
3706
|
return n;
|
|
3194
3707
|
}
|
|
3195
|
-
function sha256OfFile(p) {
|
|
3196
|
-
let data;
|
|
3197
|
-
try {
|
|
3198
|
-
data = fs12.readFileSync(p);
|
|
3199
|
-
} catch {
|
|
3200
|
-
return null;
|
|
3201
|
-
}
|
|
3202
|
-
return crypto3.createHash("sha256").update(data).digest("hex");
|
|
3203
|
-
}
|
|
3204
3708
|
function atomicWrite0644(target, body, prefix) {
|
|
3205
|
-
const dir =
|
|
3206
|
-
const tmpName =
|
|
3709
|
+
const dir = path13.dirname(target);
|
|
3710
|
+
const tmpName = path13.join(
|
|
3207
3711
|
dir,
|
|
3208
|
-
`${prefix}${process2.pid}.${
|
|
3712
|
+
`${prefix}${process2.pid}.${crypto5.randomBytes(6).toString("hex")}.yml.tmp`
|
|
3209
3713
|
);
|
|
3210
3714
|
let fd = null;
|
|
3211
3715
|
try {
|
|
3212
|
-
fd =
|
|
3213
|
-
|
|
3214
|
-
|
|
3716
|
+
fd = fs15.openSync(tmpName, "wx", 420);
|
|
3717
|
+
fs15.writeFileSync(fd, body, "utf-8");
|
|
3718
|
+
fs15.closeSync(fd);
|
|
3215
3719
|
fd = null;
|
|
3216
|
-
|
|
3217
|
-
|
|
3720
|
+
fs15.chmodSync(tmpName, 420);
|
|
3721
|
+
fs15.renameSync(tmpName, target);
|
|
3218
3722
|
} catch (err) {
|
|
3219
3723
|
if (fd !== null) {
|
|
3220
3724
|
try {
|
|
3221
|
-
|
|
3725
|
+
fs15.closeSync(fd);
|
|
3222
3726
|
} catch {
|
|
3223
3727
|
}
|
|
3224
3728
|
}
|
|
3225
3729
|
try {
|
|
3226
|
-
|
|
3730
|
+
fs15.unlinkSync(tmpName);
|
|
3227
3731
|
} catch {
|
|
3228
3732
|
}
|
|
3229
3733
|
throw err;
|
|
@@ -3234,104 +3738,15 @@ function utcStamp(now) {
|
|
|
3234
3738
|
const pad = (n, w = 2) => String(n).padStart(w, "0");
|
|
3235
3739
|
return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())}T${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}Z`;
|
|
3236
3740
|
}
|
|
3237
|
-
function _jsonStrNoAscii(s) {
|
|
3238
|
-
let out = '"';
|
|
3239
|
-
for (const ch of s) {
|
|
3240
|
-
const code = ch.codePointAt(0);
|
|
3241
|
-
switch (ch) {
|
|
3242
|
-
case '"':
|
|
3243
|
-
out += '\\"';
|
|
3244
|
-
break;
|
|
3245
|
-
case "\\":
|
|
3246
|
-
out += "\\\\";
|
|
3247
|
-
break;
|
|
3248
|
-
case "\n":
|
|
3249
|
-
out += "\\n";
|
|
3250
|
-
break;
|
|
3251
|
-
case "\r":
|
|
3252
|
-
out += "\\r";
|
|
3253
|
-
break;
|
|
3254
|
-
case " ":
|
|
3255
|
-
out += "\\t";
|
|
3256
|
-
break;
|
|
3257
|
-
case "\b":
|
|
3258
|
-
out += "\\b";
|
|
3259
|
-
break;
|
|
3260
|
-
case "\f":
|
|
3261
|
-
out += "\\f";
|
|
3262
|
-
break;
|
|
3263
|
-
default:
|
|
3264
|
-
if (code < 32) {
|
|
3265
|
-
out += "\\u" + code.toString(16).padStart(4, "0");
|
|
3266
|
-
} else {
|
|
3267
|
-
out += ch;
|
|
3268
|
-
}
|
|
3269
|
-
}
|
|
3270
|
-
}
|
|
3271
|
-
return out + '"';
|
|
3272
|
-
}
|
|
3273
|
-
function _jsonScalar(value) {
|
|
3274
|
-
if (value === null || value === void 0) return "null";
|
|
3275
|
-
if (typeof value === "boolean") return value ? "true" : "false";
|
|
3276
|
-
if (typeof value === "number") {
|
|
3277
|
-
if (!Number.isFinite(value)) {
|
|
3278
|
-
if (Number.isNaN(value)) return "NaN";
|
|
3279
|
-
return value > 0 ? "Infinity" : "-Infinity";
|
|
3280
|
-
}
|
|
3281
|
-
return String(value);
|
|
3282
|
-
}
|
|
3283
|
-
if (typeof value === "string") return _jsonStrNoAscii(value);
|
|
3284
|
-
return null;
|
|
3285
|
-
}
|
|
3286
|
-
function _dumpIndent(value, indent, depth) {
|
|
3287
|
-
const scalar = _jsonScalar(value);
|
|
3288
|
-
if (scalar !== null) return scalar;
|
|
3289
|
-
const pad = " ".repeat(indent * (depth + 1));
|
|
3290
|
-
const closePad = " ".repeat(indent * depth);
|
|
3291
|
-
if (Array.isArray(value)) {
|
|
3292
|
-
if (value.length === 0) return "[]";
|
|
3293
|
-
const items = value.map((v) => pad + _dumpIndent(v, indent, depth + 1));
|
|
3294
|
-
return `[
|
|
3295
|
-
${items.join(",\n")}
|
|
3296
|
-
${closePad}]`;
|
|
3297
|
-
}
|
|
3298
|
-
if (typeof value === "object" && value !== null) {
|
|
3299
|
-
const obj = value;
|
|
3300
|
-
const keys = Object.keys(obj);
|
|
3301
|
-
if (keys.length === 0) return "{}";
|
|
3302
|
-
const items = keys.map(
|
|
3303
|
-
(k) => `${pad}${_jsonStrNoAscii(k)}: ${_dumpIndent(obj[k], indent, depth + 1)}`
|
|
3304
|
-
);
|
|
3305
|
-
return `{
|
|
3306
|
-
${items.join(",\n")}
|
|
3307
|
-
${closePad}}`;
|
|
3308
|
-
}
|
|
3309
|
-
return _jsonStrNoAscii(String(value));
|
|
3310
|
-
}
|
|
3311
|
-
function jsonDumpsIndent(value, indent) {
|
|
3312
|
-
return _dumpIndent(value, indent, 0);
|
|
3313
|
-
}
|
|
3314
|
-
function jsonDumpsCompact(value) {
|
|
3315
|
-
const scalar = _jsonScalar(value);
|
|
3316
|
-
if (scalar !== null) return scalar;
|
|
3317
|
-
if (Array.isArray(value)) {
|
|
3318
|
-
return "[" + value.map((v) => jsonDumpsCompact(v)).join(",") + "]";
|
|
3319
|
-
}
|
|
3320
|
-
if (typeof value === "object" && value !== null) {
|
|
3321
|
-
const obj = value;
|
|
3322
|
-
return "{" + Object.keys(obj).map((k) => `${_jsonStrNoAscii(k)}:${jsonDumpsCompact(obj[k])}`).join(",") + "}";
|
|
3323
|
-
}
|
|
3324
|
-
return _jsonStrNoAscii(String(value));
|
|
3325
|
-
}
|
|
3326
3741
|
function yamlSafeLoad(text) {
|
|
3327
|
-
let
|
|
3742
|
+
let YAML3;
|
|
3328
3743
|
try {
|
|
3329
|
-
|
|
3744
|
+
YAML3 = require_dist();
|
|
3330
3745
|
} catch {
|
|
3331
3746
|
return null;
|
|
3332
3747
|
}
|
|
3333
3748
|
try {
|
|
3334
|
-
const data =
|
|
3749
|
+
const data = YAML3.parse(text, { version: "1.1" });
|
|
3335
3750
|
return data;
|
|
3336
3751
|
} catch {
|
|
3337
3752
|
return void 0;
|
|
@@ -3347,12 +3762,12 @@ var LEGACY_SETTINGS_FILE = ".agent-settings";
|
|
|
3347
3762
|
var LEGACY_BACKUP_FILE = ".agent-settings.backup.key-value";
|
|
3348
3763
|
var SETTINGS_SUBDIR = ["agents", "settings"];
|
|
3349
3764
|
function _canonical_settings_target(project_root) {
|
|
3350
|
-
return
|
|
3765
|
+
return path13.join(project_root, ...SETTINGS_SUBDIR, SETTINGS_FILE);
|
|
3351
3766
|
}
|
|
3352
3767
|
function _resolve_settings_read(project_root) {
|
|
3353
3768
|
const canonical = _canonical_settings_target(project_root);
|
|
3354
3769
|
if (pathExists(canonical)) return canonical;
|
|
3355
|
-
const legacy =
|
|
3770
|
+
const legacy = path13.join(project_root, SETTINGS_FILE);
|
|
3356
3771
|
if (pathExists(legacy)) return legacy;
|
|
3357
3772
|
return canonical;
|
|
3358
3773
|
}
|
|
@@ -3387,6 +3802,8 @@ function _emit_progress_terminal(rc) {
|
|
|
3387
3802
|
if (!state.PROGRESS_NDJSON) return;
|
|
3388
3803
|
if (rc === 0) {
|
|
3389
3804
|
_emit_progress({ type: "done" });
|
|
3805
|
+
} else if (rc === EXIT_COMPLETED_WITH_CONFLICTS) {
|
|
3806
|
+
_emit_progress({ type: "done", conflicts: tracker.conflictState.preserved.length });
|
|
3390
3807
|
} else {
|
|
3391
3808
|
_emit_progress({ type: "error", code: "E_INSTALL", exitCode: rc });
|
|
3392
3809
|
}
|
|
@@ -3416,9 +3833,9 @@ function fail(msg) {
|
|
|
3416
3833
|
throw new SystemExitError(1);
|
|
3417
3834
|
}
|
|
3418
3835
|
function detect_package_root(project_root) {
|
|
3419
|
-
const npm_path =
|
|
3836
|
+
const npm_path = path13.join(project_root, "node_modules", "@event4u", "agent-config");
|
|
3420
3837
|
if (isDir(npm_path)) return resolvePath(npm_path);
|
|
3421
|
-
if (pathExists(
|
|
3838
|
+
if (pathExists(path13.join(project_root, "src", "config", "profiles", "minimal.ini"))) {
|
|
3422
3839
|
return project_root;
|
|
3423
3840
|
}
|
|
3424
3841
|
fail(
|
|
@@ -3426,12 +3843,12 @@ function detect_package_root(project_root) {
|
|
|
3426
3843
|
);
|
|
3427
3844
|
}
|
|
3428
3845
|
function detect_package_type(package_root) {
|
|
3429
|
-
if (package_root.split(
|
|
3846
|
+
if (package_root.split(path13.sep).includes("node_modules")) return "npm";
|
|
3430
3847
|
return "local";
|
|
3431
3848
|
}
|
|
3432
3849
|
function detect_package_type_for_project(project_root, package_root) {
|
|
3433
3850
|
const npm_path = resolvePath(
|
|
3434
|
-
|
|
3851
|
+
path13.join(project_root, "node_modules", "@event4u", "agent-config")
|
|
3435
3852
|
);
|
|
3436
3853
|
const package_resolved = resolvePath(package_root);
|
|
3437
3854
|
if (package_resolved === npm_path) return "npm";
|
|
@@ -3444,14 +3861,18 @@ function _is_interactive() {
|
|
|
3444
3861
|
return false;
|
|
3445
3862
|
}
|
|
3446
3863
|
}
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3864
|
+
var tracker = createConflictTracker({
|
|
3865
|
+
warn,
|
|
3866
|
+
fail,
|
|
3867
|
+
logWrite: (target) => _log_tx_entry("write", target),
|
|
3868
|
+
emitProgress: (frame) => _emit_progress(frame),
|
|
3869
|
+
tagDeployed: (target, source, package_root) => _inject_package_tag(target, source, package_root)
|
|
3870
|
+
});
|
|
3450
3871
|
function ensure_directory(p) {
|
|
3451
3872
|
mkdirp(p);
|
|
3452
3873
|
}
|
|
3453
3874
|
function write_file(p, content) {
|
|
3454
|
-
ensure_directory(
|
|
3875
|
+
ensure_directory(path13.dirname(p));
|
|
3455
3876
|
writeText(p, content);
|
|
3456
3877
|
}
|
|
3457
3878
|
function read_json_file(p) {
|
|
@@ -3622,7 +4043,7 @@ function _append_unknown_legacy(rendered, legacy_values, unknown_keys) {
|
|
|
3622
4043
|
return rendered + "\n" + suffix;
|
|
3623
4044
|
}
|
|
3624
4045
|
function _migrate_legacy_if_present(project_root, template_body) {
|
|
3625
|
-
const legacy_target =
|
|
4046
|
+
const legacy_target = path13.join(project_root, LEGACY_SETTINGS_FILE);
|
|
3626
4047
|
if (!isFile(legacy_target)) return null;
|
|
3627
4048
|
const legacy_text = readText(legacy_target);
|
|
3628
4049
|
const [values, unknown] = _parse_legacy_settings(legacy_text);
|
|
@@ -3637,9 +4058,9 @@ function _migrate_legacy_if_present(project_root, template_body) {
|
|
|
3637
4058
|
}
|
|
3638
4059
|
}
|
|
3639
4060
|
rendered = _append_unknown_legacy(rendered, values, unknown);
|
|
3640
|
-
const backup_target =
|
|
4061
|
+
const backup_target = path13.join(project_root, LEGACY_BACKUP_FILE);
|
|
3641
4062
|
writeText(backup_target, legacy_text);
|
|
3642
|
-
|
|
4063
|
+
fs15.unlinkSync(legacy_target);
|
|
3643
4064
|
info(`Migrated legacy ${LEGACY_SETTINGS_FILE} \u2192 ${SETTINGS_FILE}`);
|
|
3644
4065
|
info(`Backup saved to ${LEGACY_BACKUP_FILE}`);
|
|
3645
4066
|
if (unknown.length > 0) {
|
|
@@ -3674,7 +4095,7 @@ function _render_template(template, profile_values) {
|
|
|
3674
4095
|
return body;
|
|
3675
4096
|
}
|
|
3676
4097
|
function _load_valid_user_types(package_root) {
|
|
3677
|
-
const directory =
|
|
4098
|
+
const directory = path13.join(package_root, USER_TYPES_DIR);
|
|
3678
4099
|
if (!isDir(directory)) return [];
|
|
3679
4100
|
return sortedGlobStems(directory, ".yml");
|
|
3680
4101
|
}
|
|
@@ -3731,8 +4152,8 @@ function splitlinesKeepends(text) {
|
|
|
3731
4152
|
}
|
|
3732
4153
|
function ensure_agent_settings(project_root, package_root, profile, force, user_type = "", packs = null) {
|
|
3733
4154
|
const target = _canonical_settings_target(project_root);
|
|
3734
|
-
const profile_source =
|
|
3735
|
-
const template_source =
|
|
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");
|
|
3736
4157
|
if (!pathExists(profile_source)) fail(`Missing profile preset: ${profile_source}`);
|
|
3737
4158
|
if (!pathExists(template_source)) fail(`Missing settings template: ${template_source}`);
|
|
3738
4159
|
const template = readText(template_source);
|
|
@@ -3746,21 +4167,21 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
|
|
|
3746
4167
|
if (profile_values["rule_loading_tier"] !== profile) {
|
|
3747
4168
|
const got = "rule_loading_tier" in profile_values ? `'${profile_values["rule_loading_tier"]}'` : "None";
|
|
3748
4169
|
fail(
|
|
3749
|
-
`Profile preset ${
|
|
4170
|
+
`Profile preset ${path13.basename(profile_source)} has rule_loading_tier=${got} but --profile=${profile}`
|
|
3750
4171
|
);
|
|
3751
4172
|
}
|
|
3752
4173
|
profile_values["user_type"] = _validate_user_type(package_root, user_type);
|
|
3753
4174
|
let template_body = _render_template(template, profile_values);
|
|
3754
4175
|
template_body = _inject_packs(template_body, packs ?? []);
|
|
3755
|
-
const legacy_root =
|
|
4176
|
+
const legacy_root = path13.join(project_root, SETTINGS_FILE);
|
|
3756
4177
|
if (isFile(legacy_root) && !pathExists(target)) {
|
|
3757
|
-
mkdirp(
|
|
4178
|
+
mkdirp(path13.dirname(target));
|
|
3758
4179
|
writeText(target, readText(legacy_root));
|
|
3759
|
-
|
|
4180
|
+
fs15.unlinkSync(legacy_root);
|
|
3760
4181
|
success(`Migrated ${SETTINGS_FILE} \u2192 agents/settings/${SETTINGS_FILE} (ADR-038)`);
|
|
3761
4182
|
return;
|
|
3762
4183
|
}
|
|
3763
|
-
const legacy_target =
|
|
4184
|
+
const legacy_target = path13.join(project_root, LEGACY_SETTINGS_FILE);
|
|
3764
4185
|
if (isFile(legacy_target) && pathExists(target)) {
|
|
3765
4186
|
warn(
|
|
3766
4187
|
`Both ${SETTINGS_FILE} and legacy ${LEGACY_SETTINGS_FILE} exist. Skipping migration to avoid overwriting ${SETTINGS_FILE}. Delete one of them manually and re-run.`
|
|
@@ -3777,7 +4198,7 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
|
|
|
3777
4198
|
skip(`${SETTINGS_FILE} already exists`);
|
|
3778
4199
|
return;
|
|
3779
4200
|
}
|
|
3780
|
-
mkdirp(
|
|
4201
|
+
mkdirp(path13.dirname(target));
|
|
3781
4202
|
write_file(target, template_body);
|
|
3782
4203
|
const user_type_value = profile_values["user_type"] ?? "";
|
|
3783
4204
|
const suffix = user_type_value ? `, user_type=${user_type_value}` : "";
|
|
@@ -3790,7 +4211,7 @@ function ensure_vscode_bridge(project_root, package_type, force) {
|
|
|
3790
4211
|
const plugin_path = plugin_paths[package_type] ?? "./plugin/agent-config";
|
|
3791
4212
|
const bridge = { "chat.pluginLocations": { [plugin_path]: true } };
|
|
3792
4213
|
return merge_json_file(
|
|
3793
|
-
|
|
4214
|
+
path13.join(project_root, ".vscode", "settings.json"),
|
|
3794
4215
|
bridge,
|
|
3795
4216
|
force,
|
|
3796
4217
|
".vscode/settings.json"
|
|
@@ -3799,14 +4220,14 @@ function ensure_vscode_bridge(project_root, package_type, force) {
|
|
|
3799
4220
|
function ensure_augment_bridge(project_root, force) {
|
|
3800
4221
|
const bridge = { enabledPlugins: { "agent-config@event4u": true } };
|
|
3801
4222
|
return merge_json_file(
|
|
3802
|
-
|
|
4223
|
+
path13.join(project_root, ".augment", "settings.json"),
|
|
3803
4224
|
bridge,
|
|
3804
4225
|
force,
|
|
3805
4226
|
".augment/settings.json"
|
|
3806
4227
|
);
|
|
3807
4228
|
}
|
|
3808
|
-
var AUGMENT_USER_DIR =
|
|
3809
|
-
var AUGMENT_USER_HOOKS_DIR =
|
|
4229
|
+
var AUGMENT_USER_DIR = path13.join(os3.homedir(), ".augment");
|
|
4230
|
+
var AUGMENT_USER_HOOKS_DIR = path13.join(AUGMENT_USER_DIR, "hooks");
|
|
3810
4231
|
var AUGMENT_DISPATCHER_TRAMPOLINE = "augment-dispatcher.sh";
|
|
3811
4232
|
var AUGMENT_LEGACY_TRAMPOLINES = [
|
|
3812
4233
|
"augment-chat-history.sh",
|
|
@@ -3815,29 +4236,29 @@ var AUGMENT_LEGACY_TRAMPOLINES = [
|
|
|
3815
4236
|
"augment-context-hygiene.sh"
|
|
3816
4237
|
];
|
|
3817
4238
|
function _deploy_augment_trampoline(package_root, name, force) {
|
|
3818
|
-
const src =
|
|
4239
|
+
const src = path13.join(package_root, "scripts", "hooks", name);
|
|
3819
4240
|
if (!pathExists(src)) {
|
|
3820
4241
|
skip(`augment trampoline missing in package: ${src}`);
|
|
3821
4242
|
return null;
|
|
3822
4243
|
}
|
|
3823
4244
|
mkdirp(AUGMENT_USER_HOOKS_DIR);
|
|
3824
|
-
const dst =
|
|
4245
|
+
const dst = path13.join(AUGMENT_USER_HOOKS_DIR, name);
|
|
3825
4246
|
const src_text = readText(src);
|
|
3826
4247
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3827
4248
|
skip(`~/.augment/hooks/${name} already up to date`);
|
|
3828
4249
|
} else {
|
|
3829
4250
|
writeText(dst, src_text);
|
|
3830
|
-
|
|
4251
|
+
fs15.chmodSync(dst, 493);
|
|
3831
4252
|
success(`~/.augment/hooks/${name} installed`);
|
|
3832
4253
|
}
|
|
3833
4254
|
return dst;
|
|
3834
4255
|
}
|
|
3835
4256
|
function _remove_legacy_augment_trampolines() {
|
|
3836
4257
|
for (const name of AUGMENT_LEGACY_TRAMPOLINES) {
|
|
3837
|
-
const legacy =
|
|
4258
|
+
const legacy = path13.join(AUGMENT_USER_HOOKS_DIR, name);
|
|
3838
4259
|
try {
|
|
3839
4260
|
if (isFile(legacy)) {
|
|
3840
|
-
|
|
4261
|
+
fs15.unlinkSync(legacy);
|
|
3841
4262
|
skip(`removed legacy ~/.augment/hooks/${name}`);
|
|
3842
4263
|
}
|
|
3843
4264
|
} catch (err) {
|
|
@@ -3857,7 +4278,7 @@ function ensure_augment_user_hooks(package_root, force) {
|
|
|
3857
4278
|
}
|
|
3858
4279
|
const settings_patch = { hooks: per_event };
|
|
3859
4280
|
return merge_json_file(
|
|
3860
|
-
|
|
4281
|
+
path13.join(AUGMENT_USER_DIR, "settings.json"),
|
|
3861
4282
|
settings_patch,
|
|
3862
4283
|
force,
|
|
3863
4284
|
"~/.augment/settings.json"
|
|
@@ -3882,12 +4303,10 @@ function _heal_legacy_claude_plugin_ids(p) {
|
|
|
3882
4303
|
return removed;
|
|
3883
4304
|
}
|
|
3884
4305
|
function ensure_claude_bridge(project_root, force) {
|
|
3885
|
-
const target =
|
|
4306
|
+
const target = path13.join(project_root, ".claude", "settings.json");
|
|
3886
4307
|
const healed = _heal_legacy_claude_plugin_ids(target);
|
|
3887
|
-
for (const pid of healed) {
|
|
3888
|
-
|
|
3889
|
-
}
|
|
3890
|
-
const bridge = { enabledPlugins: { [CLAUDE_PLUGIN_ID]: true } };
|
|
4308
|
+
for (const pid of healed) success(`.claude/settings.json: removed stale plugin id \`${pid}\``);
|
|
4309
|
+
const bridge = withHostEnv({ enabledPlugins: { [CLAUDE_PLUGIN_ID]: true } }, project_root, success);
|
|
3891
4310
|
return merge_json_file(target, bridge, force || healed.length > 0, ".claude/settings.json");
|
|
3892
4311
|
}
|
|
3893
4312
|
var ensure_mcp_bridge = makeEnsureMcpBridge(merge_json_file);
|
|
@@ -3902,29 +4321,29 @@ function ensure_cursor_bridge(project_root, force) {
|
|
|
3902
4321
|
}
|
|
3903
4322
|
const bridge = { version: 1, hooks };
|
|
3904
4323
|
return merge_json_file(
|
|
3905
|
-
|
|
4324
|
+
path13.join(project_root, ".cursor", "hooks.json"),
|
|
3906
4325
|
bridge,
|
|
3907
4326
|
force,
|
|
3908
4327
|
".cursor/hooks.json"
|
|
3909
4328
|
);
|
|
3910
4329
|
}
|
|
3911
|
-
var CURSOR_USER_DIR =
|
|
3912
|
-
var CURSOR_USER_HOOKS_DIR =
|
|
4330
|
+
var CURSOR_USER_DIR = path13.join(os3.homedir(), ".cursor");
|
|
4331
|
+
var CURSOR_USER_HOOKS_DIR = path13.join(CURSOR_USER_DIR, "hooks");
|
|
3913
4332
|
var CURSOR_DISPATCHER_TRAMPOLINE = "cursor-dispatcher.sh";
|
|
3914
4333
|
function ensure_cursor_user_hooks(package_root, force) {
|
|
3915
|
-
const src =
|
|
4334
|
+
const src = path13.join(package_root, "scripts", "hooks", CURSOR_DISPATCHER_TRAMPOLINE);
|
|
3916
4335
|
if (!pathExists(src)) {
|
|
3917
4336
|
skip(`cursor trampoline missing in package: ${src}`);
|
|
3918
4337
|
return [];
|
|
3919
4338
|
}
|
|
3920
4339
|
mkdirp(CURSOR_USER_HOOKS_DIR);
|
|
3921
|
-
const dst =
|
|
4340
|
+
const dst = path13.join(CURSOR_USER_HOOKS_DIR, CURSOR_DISPATCHER_TRAMPOLINE);
|
|
3922
4341
|
const src_text = readText(src);
|
|
3923
4342
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
3924
4343
|
skip(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
3925
4344
|
} else {
|
|
3926
4345
|
writeText(dst, src_text);
|
|
3927
|
-
|
|
4346
|
+
fs15.chmodSync(dst, 493);
|
|
3928
4347
|
success(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} installed`);
|
|
3929
4348
|
}
|
|
3930
4349
|
const hooks = {};
|
|
@@ -3933,7 +4352,7 @@ function ensure_cursor_user_hooks(package_root, force) {
|
|
|
3933
4352
|
}
|
|
3934
4353
|
const settings_patch = { version: 1, hooks };
|
|
3935
4354
|
return merge_json_file(
|
|
3936
|
-
|
|
4355
|
+
path13.join(CURSOR_USER_DIR, "hooks.json"),
|
|
3937
4356
|
settings_patch,
|
|
3938
4357
|
force,
|
|
3939
4358
|
"~/.cursor/hooks.json"
|
|
@@ -3968,12 +4387,12 @@ exit 0
|
|
|
3968
4387
|
`;
|
|
3969
4388
|
}
|
|
3970
4389
|
function ensure_cline_bridge(project_root, force) {
|
|
3971
|
-
const hooks_dir =
|
|
4390
|
+
const hooks_dir = path13.join(project_root, ".clinerules", "hooks");
|
|
3972
4391
|
mkdirp(hooks_dir);
|
|
3973
4392
|
const workspace_quoted = shlexQuote(resolvePath(project_root));
|
|
3974
4393
|
let written = 0;
|
|
3975
4394
|
for (const { slot, native } of hostBindings("cline")) {
|
|
3976
|
-
const target =
|
|
4395
|
+
const target = path13.join(hooks_dir, native);
|
|
3977
4396
|
const body = clineProjectHookBody(native, slot, workspace_quoted);
|
|
3978
4397
|
if (pathExists(target) && readText(target) === body && !force) {
|
|
3979
4398
|
continue;
|
|
@@ -3983,7 +4402,7 @@ function ensure_cline_bridge(project_root, force) {
|
|
|
3983
4402
|
continue;
|
|
3984
4403
|
}
|
|
3985
4404
|
writeText(target, body);
|
|
3986
|
-
|
|
4405
|
+
fs15.chmodSync(target, 493);
|
|
3987
4406
|
written += 1;
|
|
3988
4407
|
}
|
|
3989
4408
|
if (written) {
|
|
@@ -3992,27 +4411,27 @@ function ensure_cline_bridge(project_root, force) {
|
|
|
3992
4411
|
skip(".clinerules/hooks/ already up to date");
|
|
3993
4412
|
}
|
|
3994
4413
|
}
|
|
3995
|
-
var CLINE_USER_DIR =
|
|
4414
|
+
var CLINE_USER_DIR = path13.join(os3.homedir(), "Documents", "Cline", "Hooks");
|
|
3996
4415
|
var CLINE_DISPATCHER_TRAMPOLINE = "cline-dispatcher.sh";
|
|
3997
4416
|
function ensure_cline_user_hooks(package_root, force) {
|
|
3998
|
-
const src =
|
|
4417
|
+
const src = path13.join(package_root, "scripts", "hooks", CLINE_DISPATCHER_TRAMPOLINE);
|
|
3999
4418
|
if (!pathExists(src)) {
|
|
4000
4419
|
skip(`cline trampoline missing in package: ${src}`);
|
|
4001
4420
|
return;
|
|
4002
4421
|
}
|
|
4003
4422
|
mkdirp(CLINE_USER_DIR);
|
|
4004
|
-
const trampoline =
|
|
4423
|
+
const trampoline = path13.join(CLINE_USER_DIR, CLINE_DISPATCHER_TRAMPOLINE);
|
|
4005
4424
|
const src_text = readText(src);
|
|
4006
4425
|
if (pathExists(trampoline) && readText(trampoline) === src_text && !force) {
|
|
4007
4426
|
skip(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
4008
4427
|
} else {
|
|
4009
4428
|
writeText(trampoline, src_text);
|
|
4010
|
-
|
|
4429
|
+
fs15.chmodSync(trampoline, 493);
|
|
4011
4430
|
success(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} installed`);
|
|
4012
4431
|
}
|
|
4013
4432
|
const trampoline_quoted = shlexQuote(trampoline);
|
|
4014
4433
|
for (const { slot, native } of hostBindings("cline")) {
|
|
4015
|
-
const wrapper =
|
|
4434
|
+
const wrapper = path13.join(CLINE_USER_DIR, native);
|
|
4016
4435
|
const body = `#!/usr/bin/env bash
|
|
4017
4436
|
# Generated by event4u/agent-config \u2014 DO NOT EDIT.
|
|
4018
4437
|
# User-scope Cline hook for ${native} \u2192 agent-config ${slot}.
|
|
@@ -4022,7 +4441,7 @@ exec ${trampoline_quoted} ${slot} ${native}
|
|
|
4022
4441
|
continue;
|
|
4023
4442
|
}
|
|
4024
4443
|
writeText(wrapper, body);
|
|
4025
|
-
|
|
4444
|
+
fs15.chmodSync(wrapper, 493);
|
|
4026
4445
|
}
|
|
4027
4446
|
}
|
|
4028
4447
|
function _windsurf_dispatch_command(ac_event, native) {
|
|
@@ -4038,29 +4457,29 @@ function ensure_windsurf_bridge(project_root, force) {
|
|
|
4038
4457
|
}
|
|
4039
4458
|
const bridge = { hooks };
|
|
4040
4459
|
return merge_json_file(
|
|
4041
|
-
|
|
4460
|
+
path13.join(project_root, ".windsurf", "hooks.json"),
|
|
4042
4461
|
bridge,
|
|
4043
4462
|
force,
|
|
4044
4463
|
".windsurf/hooks.json"
|
|
4045
4464
|
);
|
|
4046
4465
|
}
|
|
4047
|
-
var WINDSURF_USER_DIR =
|
|
4048
|
-
var WINDSURF_USER_HOOKS_DIR =
|
|
4466
|
+
var WINDSURF_USER_DIR = path13.join(os3.homedir(), ".codeium", "windsurf");
|
|
4467
|
+
var WINDSURF_USER_HOOKS_DIR = path13.join(WINDSURF_USER_DIR, "hooks");
|
|
4049
4468
|
var WINDSURF_DISPATCHER_TRAMPOLINE = "windsurf-dispatcher.sh";
|
|
4050
4469
|
function ensure_windsurf_user_hooks(package_root, force) {
|
|
4051
|
-
const src =
|
|
4470
|
+
const src = path13.join(package_root, "scripts", "hooks", WINDSURF_DISPATCHER_TRAMPOLINE);
|
|
4052
4471
|
if (!pathExists(src)) {
|
|
4053
4472
|
skip(`windsurf trampoline missing in package: ${src}`);
|
|
4054
4473
|
return [];
|
|
4055
4474
|
}
|
|
4056
4475
|
mkdirp(WINDSURF_USER_HOOKS_DIR);
|
|
4057
|
-
const dst =
|
|
4476
|
+
const dst = path13.join(WINDSURF_USER_HOOKS_DIR, WINDSURF_DISPATCHER_TRAMPOLINE);
|
|
4058
4477
|
const src_text = readText(src);
|
|
4059
4478
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
4060
4479
|
skip(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
4061
4480
|
} else {
|
|
4062
4481
|
writeText(dst, src_text);
|
|
4063
|
-
|
|
4482
|
+
fs15.chmodSync(dst, 493);
|
|
4064
4483
|
success(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} installed`);
|
|
4065
4484
|
}
|
|
4066
4485
|
const hooks = {};
|
|
@@ -4072,7 +4491,7 @@ function ensure_windsurf_user_hooks(package_root, force) {
|
|
|
4072
4491
|
}
|
|
4073
4492
|
const settings_patch = { hooks };
|
|
4074
4493
|
return merge_json_file(
|
|
4075
|
-
|
|
4494
|
+
path13.join(WINDSURF_USER_DIR, "hooks.json"),
|
|
4076
4495
|
settings_patch,
|
|
4077
4496
|
force,
|
|
4078
4497
|
"~/.codeium/windsurf/hooks.json"
|
|
@@ -4094,43 +4513,43 @@ function _gemini_hooks_dict(command_factory) {
|
|
|
4094
4513
|
function ensure_gemini_bridge(project_root, force) {
|
|
4095
4514
|
const bridge = { hooks: _gemini_hooks_dict(_gemini_dispatch_command) };
|
|
4096
4515
|
return merge_json_file(
|
|
4097
|
-
|
|
4516
|
+
path13.join(project_root, ".gemini", "settings.json"),
|
|
4098
4517
|
bridge,
|
|
4099
4518
|
force,
|
|
4100
4519
|
".gemini/settings.json"
|
|
4101
4520
|
);
|
|
4102
4521
|
}
|
|
4103
|
-
var GEMINI_USER_DIR =
|
|
4104
|
-
var GEMINI_USER_HOOKS_DIR =
|
|
4522
|
+
var GEMINI_USER_DIR = path13.join(os3.homedir(), ".gemini");
|
|
4523
|
+
var GEMINI_USER_HOOKS_DIR = path13.join(GEMINI_USER_DIR, "hooks");
|
|
4105
4524
|
var GEMINI_DISPATCHER_TRAMPOLINE = "gemini-dispatcher.sh";
|
|
4106
4525
|
function ensure_gemini_user_hooks(package_root, force) {
|
|
4107
|
-
const src =
|
|
4526
|
+
const src = path13.join(package_root, "scripts", "hooks", GEMINI_DISPATCHER_TRAMPOLINE);
|
|
4108
4527
|
if (!pathExists(src)) {
|
|
4109
4528
|
skip(`gemini trampoline missing in package: ${src}`);
|
|
4110
4529
|
return [];
|
|
4111
4530
|
}
|
|
4112
4531
|
mkdirp(GEMINI_USER_HOOKS_DIR);
|
|
4113
|
-
const dst =
|
|
4532
|
+
const dst = path13.join(GEMINI_USER_HOOKS_DIR, GEMINI_DISPATCHER_TRAMPOLINE);
|
|
4114
4533
|
const src_text = readText(src);
|
|
4115
4534
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
4116
4535
|
skip(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
4117
4536
|
} else {
|
|
4118
4537
|
writeText(dst, src_text);
|
|
4119
|
-
|
|
4538
|
+
fs15.chmodSync(dst, 493);
|
|
4120
4539
|
success(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} installed`);
|
|
4121
4540
|
}
|
|
4122
4541
|
const settings_patch = {
|
|
4123
4542
|
hooks: _gemini_hooks_dict((ac_event, native) => `${dst} ${ac_event} ${native}`)
|
|
4124
4543
|
};
|
|
4125
4544
|
return merge_json_file(
|
|
4126
|
-
|
|
4545
|
+
path13.join(GEMINI_USER_DIR, "settings.json"),
|
|
4127
4546
|
settings_patch,
|
|
4128
4547
|
force,
|
|
4129
4548
|
"~/.gemini/settings.json"
|
|
4130
4549
|
);
|
|
4131
4550
|
}
|
|
4132
4551
|
function ensure_copilot_bridge(project_root, force) {
|
|
4133
|
-
const target =
|
|
4552
|
+
const target = path13.join(project_root, ".github", "plugin", "marketplace.json");
|
|
4134
4553
|
const bridge = {
|
|
4135
4554
|
marketplace: {
|
|
4136
4555
|
name: "event4u-agent-marketplace",
|
|
@@ -4173,7 +4592,7 @@ See \`docs/setup/per-ide/roocode.md\` for the full activation guide.
|
|
|
4173
4592
|
Run \`./agent-config --help\` for available commands.
|
|
4174
4593
|
`;
|
|
4175
4594
|
function ensure_roocode_bridge(project_root, force) {
|
|
4176
|
-
const target =
|
|
4595
|
+
const target = path13.join(project_root, ".roo", "rules", "agent-config.md");
|
|
4177
4596
|
if (pathExists(target) && !force) {
|
|
4178
4597
|
skip(".roo/rules/agent-config.md already exists");
|
|
4179
4598
|
return;
|
|
@@ -4195,7 +4614,7 @@ To wire Claude Desktop to this project's rules, run:
|
|
|
4195
4614
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
4196
4615
|
`;
|
|
4197
4616
|
function ensure_claude_desktop_bridge(project_root, force) {
|
|
4198
|
-
const target =
|
|
4617
|
+
const target = path13.join(project_root, ".claude-desktop", "agent-config.md");
|
|
4199
4618
|
if (pathExists(target) && !force) {
|
|
4200
4619
|
skip(".claude-desktop/agent-config.md already exists");
|
|
4201
4620
|
return;
|
|
@@ -4220,7 +4639,7 @@ Or pass \`--read .aider/agent-config.md\` on the command line.
|
|
|
4220
4639
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
4221
4640
|
`;
|
|
4222
4641
|
function ensure_aider_bridge(project_root, force) {
|
|
4223
|
-
const target =
|
|
4642
|
+
const target = path13.join(project_root, ".aider", "agent-config.md");
|
|
4224
4643
|
if (pathExists(target) && !force) {
|
|
4225
4644
|
skip(".aider/agent-config.md already exists");
|
|
4226
4645
|
return;
|
|
@@ -4239,7 +4658,7 @@ developers where the rules and skills live.
|
|
|
4239
4658
|
Canonical rule and skill source: \`.augment/\` (see project \`AGENTS.md\`).
|
|
4240
4659
|
`;
|
|
4241
4660
|
function ensure_codex_bridge(project_root, force) {
|
|
4242
|
-
const target =
|
|
4661
|
+
const target = path13.join(project_root, ".codex", "agent-config.md");
|
|
4243
4662
|
if (pathExists(target) && !force) {
|
|
4244
4663
|
skip(".codex/agent-config.md already exists");
|
|
4245
4664
|
return;
|
|
@@ -4257,7 +4676,7 @@ rules per session. The canonical rule and skill source lives under
|
|
|
4257
4676
|
orientation).
|
|
4258
4677
|
`;
|
|
4259
4678
|
function ensure_continue_bridge(project_root, force) {
|
|
4260
|
-
const target =
|
|
4679
|
+
const target = path13.join(project_root, ".continue", "rules", "agent-config.md");
|
|
4261
4680
|
if (pathExists(target) && !force) {
|
|
4262
4681
|
skip(".continue/rules/agent-config.md already exists");
|
|
4263
4682
|
return;
|
|
@@ -4288,7 +4707,7 @@ orientation).
|
|
|
4288
4707
|
See \`docs/setup/per-ide/kilocode.md\` for the full activation guide.
|
|
4289
4708
|
`;
|
|
4290
4709
|
function ensure_kilocode_bridge(project_root, force) {
|
|
4291
|
-
const target =
|
|
4710
|
+
const target = path13.join(project_root, ".kilocode", "rules", "agent-config.md");
|
|
4292
4711
|
if (pathExists(target) && !force) {
|
|
4293
4712
|
skip(".kilocode/rules/agent-config.md already exists");
|
|
4294
4713
|
return;
|
|
@@ -4315,7 +4734,7 @@ canonical source (or symlink it):
|
|
|
4315
4734
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
4316
4735
|
`;
|
|
4317
4736
|
function ensure_zed_bridge(project_root, force) {
|
|
4318
|
-
const target =
|
|
4737
|
+
const target = path13.join(project_root, ".zed", "agent-config.md");
|
|
4319
4738
|
if (pathExists(target) && !force) {
|
|
4320
4739
|
skip(".zed/agent-config.md already exists");
|
|
4321
4740
|
return;
|
|
@@ -4336,7 +4755,7 @@ rules into your JetBrains profile.
|
|
|
4336
4755
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
4337
4756
|
`;
|
|
4338
4757
|
function ensure_jetbrains_bridge(project_root, force) {
|
|
4339
|
-
const target =
|
|
4758
|
+
const target = path13.join(project_root, ".jetbrains", "agent-config.md");
|
|
4340
4759
|
if (pathExists(target) && !force) {
|
|
4341
4760
|
skip(".jetbrains/agent-config.md already exists");
|
|
4342
4761
|
return;
|
|
@@ -4367,7 +4786,7 @@ session. The canonical rule and skill source lives under \`.augment/\`
|
|
|
4367
4786
|
See \`docs/setup/per-ide/kiro.md\` for the full activation guide.
|
|
4368
4787
|
`;
|
|
4369
4788
|
function ensure_kiro_bridge(project_root, force) {
|
|
4370
|
-
const target =
|
|
4789
|
+
const target = path13.join(project_root, ".kiro", "steering", "agent-config.md");
|
|
4371
4790
|
if (pathExists(target) && !force) {
|
|
4372
4791
|
skip(".kiro/steering/agent-config.md already exists");
|
|
4373
4792
|
return;
|
|
@@ -4404,35 +4823,35 @@ var SMOKE_BRIDGE_PATHS = {
|
|
|
4404
4823
|
};
|
|
4405
4824
|
function dirHasEntries(p) {
|
|
4406
4825
|
try {
|
|
4407
|
-
return
|
|
4826
|
+
return fs15.readdirSync(p).length > 0;
|
|
4408
4827
|
} catch {
|
|
4409
4828
|
return false;
|
|
4410
4829
|
}
|
|
4411
4830
|
}
|
|
4412
4831
|
function _resolve_tsx_invocation(scriptPath, scriptArgs) {
|
|
4413
4832
|
const binName = process2.platform === "win32" ? "tsx.cmd" : "tsx";
|
|
4414
|
-
let dir =
|
|
4833
|
+
let dir = path13.dirname(scriptPath);
|
|
4415
4834
|
for (; ; ) {
|
|
4416
|
-
const candidate =
|
|
4835
|
+
const candidate = path13.join(dir, "node_modules", ".bin", binName);
|
|
4417
4836
|
if (isFile(candidate)) {
|
|
4418
4837
|
return { command: candidate, args: [scriptPath, ...scriptArgs] };
|
|
4419
4838
|
}
|
|
4420
|
-
const parent =
|
|
4839
|
+
const parent = path13.dirname(dir);
|
|
4421
4840
|
if (parent === dir) break;
|
|
4422
4841
|
dir = parent;
|
|
4423
4842
|
}
|
|
4424
4843
|
return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
|
|
4425
4844
|
}
|
|
4426
4845
|
function _smoke_test_hooks(project_root, package_root) {
|
|
4427
|
-
const dispatcher =
|
|
4428
|
-
const manifest =
|
|
4846
|
+
const dispatcher = path13.join(package_root, "scripts", "hooks", "dispatch_hook.ts");
|
|
4847
|
+
const manifest = path13.join(package_root, "scripts", "hook_manifest.yaml");
|
|
4429
4848
|
if (!isFile(dispatcher) || !isFile(manifest)) return 0;
|
|
4430
4849
|
const failed = [];
|
|
4431
4850
|
const skipped = [];
|
|
4432
4851
|
const passed = [];
|
|
4433
4852
|
for (const [platform, native] of smokeProbeEvents()) {
|
|
4434
4853
|
const rel_bridge = SMOKE_BRIDGE_PATHS[platform] ?? "";
|
|
4435
|
-
const bridge_path = rel_bridge ?
|
|
4854
|
+
const bridge_path = rel_bridge ? path13.join(project_root, rel_bridge) : null;
|
|
4436
4855
|
const bridge_present = Boolean(
|
|
4437
4856
|
bridge_path && (isFile(bridge_path) || isDir(bridge_path) && dirHasEntries(bridge_path))
|
|
4438
4857
|
);
|
|
@@ -4632,9 +5051,9 @@ To remove this marker, delete this file.
|
|
|
4632
5051
|
`;
|
|
4633
5052
|
}
|
|
4634
5053
|
var _CLAUDE_DESKTOP_BUNDLES_SUBPATH = "claude-desktop/bundles";
|
|
4635
|
-
var GLOBAL_ROOT =
|
|
4636
|
-
var GLOBAL_USER_SETTINGS_PATH =
|
|
4637
|
-
var GLOBAL_AGENT_SETTINGS_PATH =
|
|
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");
|
|
4638
5057
|
function _bridge_marker(tool_id, scope) {
|
|
4639
5058
|
if (scope === "global") return USER_SCOPE_PATHS[tool_id] ?? "";
|
|
4640
5059
|
return PROJECT_BRIDGE_MARKERS[tool_id] ?? "";
|
|
@@ -4683,7 +5102,7 @@ function _load_yaml_doc(p) {
|
|
|
4683
5102
|
return _isPlainObject(data) ? data : {};
|
|
4684
5103
|
}
|
|
4685
5104
|
function _load_default_settings(package_root) {
|
|
4686
|
-
const template_source =
|
|
5105
|
+
const template_source = path13.join(package_root, "src", "config", "agent-settings.template.yml");
|
|
4687
5106
|
if (!pathExists(template_source)) return {};
|
|
4688
5107
|
let text;
|
|
4689
5108
|
try {
|
|
@@ -4697,11 +5116,11 @@ function _load_default_settings(package_root) {
|
|
|
4697
5116
|
}
|
|
4698
5117
|
var RULE_LAYER_CHOICES = ["global", "project", "both-acknowledged"];
|
|
4699
5118
|
function _suppress_rule_layer(project_root, suppress_dir) {
|
|
4700
|
-
const target =
|
|
5119
|
+
const target = path13.join(project_root, ".claude", "settings.local.json");
|
|
4701
5120
|
const existing = pathExists(target) ? read_json_file(target) : {};
|
|
4702
5121
|
let real_dir = suppress_dir;
|
|
4703
5122
|
try {
|
|
4704
|
-
real_dir =
|
|
5123
|
+
real_dir = fs15.realpathSync(suppress_dir);
|
|
4705
5124
|
} catch {
|
|
4706
5125
|
real_dir = suppress_dir;
|
|
4707
5126
|
}
|
|
@@ -4712,8 +5131,8 @@ function _suppress_rule_layer(project_root, suppress_dir) {
|
|
|
4712
5131
|
success(`.claude/settings.local.json: claudeMdExcludes += ${entry}`);
|
|
4713
5132
|
}
|
|
4714
5133
|
function _gate_rule_layer_overlap(project_root, layer, dry_run) {
|
|
4715
|
-
const global_dir =
|
|
4716
|
-
const project_dir =
|
|
5134
|
+
const global_dir = path13.join(os3.homedir(), ".claude", "rules");
|
|
5135
|
+
const project_dir = path13.join(project_root, ".claude", "rules");
|
|
4717
5136
|
const g = readRuleLayer(global_dir);
|
|
4718
5137
|
const p = readRuleLayer(project_dir);
|
|
4719
5138
|
if (g === null || p === null) return true;
|
|
@@ -4784,7 +5203,7 @@ function _run_scope_prompt(opts, reason, custom_path) {
|
|
|
4784
5203
|
fail("Custom-path prompt aborted (EOF on stdin)");
|
|
4785
5204
|
}
|
|
4786
5205
|
if (!raw) fail("Custom-path prompt requires a non-empty path");
|
|
4787
|
-
cp = resolvePath(
|
|
5206
|
+
cp = resolvePath(expanduser3(raw));
|
|
4788
5207
|
opts.custom_path = cp;
|
|
4789
5208
|
}
|
|
4790
5209
|
if (!state.QUIET) info(`Custom destination: ${cp}`);
|
|
@@ -4801,9 +5220,9 @@ function detect_scope(cwd) {
|
|
|
4801
5220
|
if (pathExists(_resolve_settings_read(cwd))) {
|
|
4802
5221
|
return ["project", `existing ${SETTINGS_FILE}`];
|
|
4803
5222
|
}
|
|
4804
|
-
const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(
|
|
4805
|
-
const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(
|
|
4806
|
-
const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(
|
|
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;
|
|
4807
5226
|
if (has_manifest && (has_ai_dir || has_ai_file)) {
|
|
4808
5227
|
const marker = has_ai_dir || has_ai_file;
|
|
4809
5228
|
return ["prompt", `manifest (${has_manifest}) + AI-tool config (${marker})`];
|
|
@@ -4824,7 +5243,7 @@ function readLineSyncRaw(promptText) {
|
|
|
4824
5243
|
for (; ; ) {
|
|
4825
5244
|
let n;
|
|
4826
5245
|
try {
|
|
4827
|
-
n =
|
|
5246
|
+
n = fs15.readSync(0, buf, 0, 1, null);
|
|
4828
5247
|
} catch (err) {
|
|
4829
5248
|
const code = err.code;
|
|
4830
5249
|
if (code === "EAGAIN") {
|
|
@@ -4869,52 +5288,20 @@ function prompt_scope_choice(reason) {
|
|
|
4869
5288
|
}
|
|
4870
5289
|
fail("Scope prompt aborted (3 invalid replies); pass --scope=project|global to override");
|
|
4871
5290
|
}
|
|
4872
|
-
function _sha256_of_file(p) {
|
|
4873
|
-
return sha256OfFile(p);
|
|
4874
|
-
}
|
|
4875
|
-
function _file_entry(p, kind, hash_content) {
|
|
4876
|
-
return {
|
|
4877
|
-
path: p,
|
|
4878
|
-
kind,
|
|
4879
|
-
sha256: hash_content ? _sha256_of_file(p) : null
|
|
4880
|
-
};
|
|
4881
|
-
}
|
|
4882
|
-
function _files_by_tool_from_deploy(deploy_results) {
|
|
4883
|
-
const out = {};
|
|
4884
|
-
for (const tool_id of Object.keys(deploy_results)) {
|
|
4885
|
-
const [, , status, paths] = deploy_results[tool_id];
|
|
4886
|
-
if (status === "deployed") {
|
|
4887
|
-
out[tool_id] = paths.map((p) => _file_entry(p, "deployed", true));
|
|
4888
|
-
} else if (status === "marker") {
|
|
4889
|
-
out[tool_id] = paths.map((p) => _file_entry(p, "marker", true));
|
|
4890
|
-
} else {
|
|
4891
|
-
out[tool_id] = [];
|
|
4892
|
-
}
|
|
4893
|
-
}
|
|
4894
|
-
return out;
|
|
4895
|
-
}
|
|
4896
|
-
function _files_by_tool_from_bridges(tools, project_root, scope) {
|
|
4897
|
-
const out = {};
|
|
4898
|
-
for (const tool_id of [...tools].sort()) {
|
|
4899
|
-
const marker = _bridge_marker(tool_id, scope);
|
|
4900
|
-
if (!marker) continue;
|
|
4901
|
-
let marker_path = marker;
|
|
4902
|
-
if (!path10.isAbsolute(marker_path)) {
|
|
4903
|
-
marker_path = path10.join(project_root, marker_path);
|
|
4904
|
-
}
|
|
4905
|
-
out[tool_id] = [_file_entry(marker_path, "bridge", false)];
|
|
4906
|
-
}
|
|
4907
|
-
return out;
|
|
4908
|
-
}
|
|
4909
5291
|
function _update_installed_tools_manifest(project_root, tools, scope, force, files_by_tool = null, merged_keys_by_tool = null) {
|
|
4910
5292
|
const target = manifest_path(project_root);
|
|
4911
5293
|
const existing = read_manifest(target) ?? {};
|
|
4912
|
-
|
|
5294
|
+
const prior = readRecordedByTool(target, project_root);
|
|
5295
|
+
const preserved = preservedIndex(tracker.conflictState.preserved, tracker.conflictState.staged);
|
|
5296
|
+
let entries = hydrateRecordedInventories(
|
|
5297
|
+
Array.isArray(existing["tools"]) ? [...existing["tools"]] : [],
|
|
5298
|
+
prior
|
|
5299
|
+
);
|
|
4913
5300
|
const version = current_package_version();
|
|
4914
5301
|
for (const tool_id of [...tools].sort()) {
|
|
4915
5302
|
const marker = _bridge_marker(tool_id, scope);
|
|
4916
5303
|
if (!marker) continue;
|
|
4917
|
-
const files = files_by_tool
|
|
5304
|
+
const files = reconcileToolFiles(files_by_tool?.[tool_id], prior.get(tool_id), preserved);
|
|
4918
5305
|
const merged_keys = merged_keys_by_tool ? merged_keys_by_tool[tool_id] ?? null : null;
|
|
4919
5306
|
try {
|
|
4920
5307
|
entries = upsert_tool(entries, {
|
|
@@ -4939,26 +5326,26 @@ function _update_installed_tools_manifest(project_root, tools, scope, force, fil
|
|
|
4939
5326
|
}
|
|
4940
5327
|
write_manifest(target, version, entries);
|
|
4941
5328
|
if (!state.QUIET) {
|
|
4942
|
-
const rel = isRelativeTo(target, project_root) ?
|
|
5329
|
+
const rel = isRelativeTo(target, project_root) ? path13.relative(project_root, target) : target;
|
|
4943
5330
|
info(`Manifest updated: ${rel}`);
|
|
4944
5331
|
}
|
|
4945
5332
|
return 0;
|
|
4946
5333
|
}
|
|
4947
5334
|
function isRelativeTo(child, parent) {
|
|
4948
|
-
const rel =
|
|
4949
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
5335
|
+
const rel = path13.relative(parent, child);
|
|
5336
|
+
return rel === "" || !rel.startsWith("..") && !path13.isAbsolute(rel);
|
|
4950
5337
|
}
|
|
4951
5338
|
function _resolve_package_root_for_global() {
|
|
4952
5339
|
const here = resolvePath(_HERE);
|
|
4953
|
-
const candidate =
|
|
4954
|
-
if (!pathExists(
|
|
5340
|
+
const candidate = path13.dirname(path13.dirname(path13.dirname(here)));
|
|
5341
|
+
if (!pathExists(path13.join(candidate, "src", "config", "profiles", "minimal.ini"))) {
|
|
4955
5342
|
fail(
|
|
4956
5343
|
`Could not locate agent-config package root from ${here}. Expected src/config/profiles/minimal.ini at the parent directory.`
|
|
4957
5344
|
);
|
|
4958
5345
|
}
|
|
4959
5346
|
return candidate;
|
|
4960
5347
|
}
|
|
4961
|
-
var CONSUMER_BRIDGE_MARKER_RELPATH =
|
|
5348
|
+
var CONSUMER_BRIDGE_MARKER_RELPATH = path13.join("agents", ".event4u-bridge.yml");
|
|
4962
5349
|
var MIGRATE_LEGACY_YAML_FILES = [".agent-settings.yml", ".agent-user.yml"];
|
|
4963
5350
|
var MIGRATE_LEGACY_TOOL_DIRS = [".augment", ".claude", ".cursor"];
|
|
4964
5351
|
var AGENT_CONFIG_PACKAGE_NAME = "@event4u/agent-config";
|
|
@@ -4966,7 +5353,7 @@ function _is_agent_config_source_repo(project_root) {
|
|
|
4966
5353
|
if (process2.env["AGENT_CONFIG_CONSUMER_MODE"] === "1") {
|
|
4967
5354
|
return [false, "consumer-mode-override"];
|
|
4968
5355
|
}
|
|
4969
|
-
const pkg_json =
|
|
5356
|
+
const pkg_json = path13.join(project_root, "package.json");
|
|
4970
5357
|
if (isFile(pkg_json)) {
|
|
4971
5358
|
let data = {};
|
|
4972
5359
|
try {
|
|
@@ -4978,13 +5365,13 @@ function _is_agent_config_source_repo(project_root) {
|
|
|
4978
5365
|
return [true, "package.json:name"];
|
|
4979
5366
|
}
|
|
4980
5367
|
}
|
|
4981
|
-
if (isDir(
|
|
5368
|
+
if (isDir(path13.join(project_root, ".agent-src.uncondensed"))) {
|
|
4982
5369
|
return [true, ".agent-src.uncondensed/"];
|
|
4983
5370
|
}
|
|
4984
|
-
const packages_dir =
|
|
5371
|
+
const packages_dir = path13.join(project_root, "packages");
|
|
4985
5372
|
if (isDir(packages_dir)) {
|
|
4986
|
-
for (const child of
|
|
4987
|
-
if (isDir(
|
|
5373
|
+
for (const child of fs15.readdirSync(packages_dir)) {
|
|
5374
|
+
if (isDir(path13.join(packages_dir, child, ".agent-src.uncondensed"))) {
|
|
4988
5375
|
return [true, `packages/${child}/.agent-src.uncondensed/`];
|
|
4989
5376
|
}
|
|
4990
5377
|
}
|
|
@@ -5002,17 +5389,17 @@ function _detect_legacy_for_migration(project_root) {
|
|
|
5002
5389
|
}
|
|
5003
5390
|
return [];
|
|
5004
5391
|
}
|
|
5005
|
-
if (isFile(
|
|
5392
|
+
if (isFile(path13.join(project_root, INSTALL_MODE_MARKER_REL))) return [];
|
|
5006
5393
|
const found = [];
|
|
5007
5394
|
for (const name of MIGRATE_LEGACY_YAML_FILES) {
|
|
5008
|
-
if (isFile(
|
|
5395
|
+
if (isFile(path13.join(project_root, name))) {
|
|
5009
5396
|
found.push(name);
|
|
5010
|
-
} else if (isFile(
|
|
5397
|
+
} else if (isFile(path13.join(project_root, "settings", name))) {
|
|
5011
5398
|
found.push(`settings/${name}`);
|
|
5012
5399
|
}
|
|
5013
5400
|
}
|
|
5014
5401
|
for (const name of MIGRATE_LEGACY_TOOL_DIRS) {
|
|
5015
|
-
const p =
|
|
5402
|
+
const p = path13.join(project_root, name);
|
|
5016
5403
|
if (isDir(p) && !isSymlink(p)) {
|
|
5017
5404
|
found.push(`${name}/`);
|
|
5018
5405
|
}
|
|
@@ -5024,7 +5411,7 @@ function _prompt_migrate_to_global(project_root, artefacts) {
|
|
|
5024
5411
|
process2.stdout.write("\n");
|
|
5025
5412
|
warn("Legacy project-local artefacts detected \u2014 pre-ADR-020 layout:");
|
|
5026
5413
|
for (const rel of artefacts) {
|
|
5027
|
-
info(` ${
|
|
5414
|
+
info(` ${path13.join(project_root, rel)}`);
|
|
5028
5415
|
}
|
|
5029
5416
|
info("The unified `agent-config migrate` sweeps these in one pass.");
|
|
5030
5417
|
info("The wizard recreates fresh config afterwards.");
|
|
@@ -5055,20 +5442,20 @@ function _run_migrate_to_global(project_root) {
|
|
|
5055
5442
|
function _format_global_root_for_marker(global_root) {
|
|
5056
5443
|
const home = resolvePath(os3.homedir());
|
|
5057
5444
|
const resolved = resolvePath(global_root);
|
|
5058
|
-
const rel =
|
|
5059
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
5445
|
+
const rel = path13.relative(home, resolved);
|
|
5446
|
+
if (rel === "" || rel.startsWith("..") || path13.isAbsolute(rel)) {
|
|
5060
5447
|
return global_root;
|
|
5061
5448
|
}
|
|
5062
|
-
return `~/${rel.split(
|
|
5449
|
+
return `~/${rel.split(path13.sep).join("/")}`;
|
|
5063
5450
|
}
|
|
5064
5451
|
function _remove_legacy_consumer_bridge_marker(project_root, env = null) {
|
|
5065
5452
|
const env_map = env ?? process2.env;
|
|
5066
5453
|
if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return null;
|
|
5067
|
-
if (isDir(
|
|
5068
|
-
const target =
|
|
5454
|
+
if (isDir(path13.join(project_root, ".agent-src.uncondensed"))) return null;
|
|
5455
|
+
const target = path13.join(project_root, CONSUMER_BRIDGE_MARKER_RELPATH);
|
|
5069
5456
|
if (!isFile(target)) return null;
|
|
5070
5457
|
try {
|
|
5071
|
-
|
|
5458
|
+
fs15.rmSync(target);
|
|
5072
5459
|
} catch {
|
|
5073
5460
|
return null;
|
|
5074
5461
|
}
|
|
@@ -5082,7 +5469,7 @@ var PROJECT_ANCHOR_TOOLS = {
|
|
|
5082
5469
|
function _write_per_tool_project_anchors(project_root, tools, env = null, now = null) {
|
|
5083
5470
|
const env_map = env ?? process2.env;
|
|
5084
5471
|
if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return [];
|
|
5085
|
-
if (isDir(
|
|
5472
|
+
if (isDir(path13.join(project_root, ".agent-src.uncondensed"))) return [];
|
|
5086
5473
|
const global_root_str = _format_global_root_for_marker(
|
|
5087
5474
|
event4u_root(env_map)
|
|
5088
5475
|
);
|
|
@@ -5091,8 +5478,8 @@ function _write_per_tool_project_anchors(project_root, tools, env = null, now =
|
|
|
5091
5478
|
for (const tool_id of Object.keys(PROJECT_ANCHOR_TOOLS).sort()) {
|
|
5092
5479
|
const rel_path = PROJECT_ANCHOR_TOOLS[tool_id];
|
|
5093
5480
|
if (!tools.has(tool_id)) continue;
|
|
5094
|
-
const target =
|
|
5095
|
-
mkdirp(
|
|
5481
|
+
const target = path13.join(project_root, rel_path);
|
|
5482
|
+
mkdirp(path13.dirname(target));
|
|
5096
5483
|
const body = `# event4u/agent-config \u2014 per-tool project anchor (auto-written).
|
|
5097
5484
|
# Spec: docs/contracts/consumer-bridge.md \xA7 Per-tool anchor strategy.
|
|
5098
5485
|
# Tool: ${tool_id}. Resolves the global install directly \u2014 no
|
|
@@ -5110,7 +5497,7 @@ installed_at: ${stamp}
|
|
|
5110
5497
|
}
|
|
5111
5498
|
var PACKAGE_TAG_ID = "event4u/agent-config";
|
|
5112
5499
|
function _inject_package_tag(target, source, package_root) {
|
|
5113
|
-
if (
|
|
5500
|
+
if (path13.extname(target) !== ".md") return;
|
|
5114
5501
|
let text;
|
|
5115
5502
|
try {
|
|
5116
5503
|
text = readText(target);
|
|
@@ -5138,8 +5525,8 @@ function _inject_package_tag(target, source, package_root) {
|
|
|
5138
5525
|
resolved_src = source;
|
|
5139
5526
|
}
|
|
5140
5527
|
if (package_root !== null) {
|
|
5141
|
-
const rel =
|
|
5142
|
-
if (rel !== "" && !rel.startsWith("..") && !
|
|
5528
|
+
const rel = path13.relative(resolvePath(package_root), resolved_src);
|
|
5529
|
+
if (rel !== "" && !rel.startsWith("..") && !path13.isAbsolute(rel)) {
|
|
5143
5530
|
source_value = rel;
|
|
5144
5531
|
} else {
|
|
5145
5532
|
source_value = resolved_src;
|
|
@@ -5174,12 +5561,23 @@ function _escapes_package_root(resolved, package_root) {
|
|
|
5174
5561
|
if (package_root === null) return false;
|
|
5175
5562
|
let root;
|
|
5176
5563
|
try {
|
|
5177
|
-
root =
|
|
5564
|
+
root = fs15.realpathSync(package_root);
|
|
5178
5565
|
} catch {
|
|
5179
5566
|
return false;
|
|
5180
5567
|
}
|
|
5181
5568
|
return !is_ancestor(root, resolved);
|
|
5182
5569
|
}
|
|
5570
|
+
function _log_tx_entry(kind, target) {
|
|
5571
|
+
try {
|
|
5572
|
+
appendTxLog(getLogPath(), {
|
|
5573
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5574
|
+
kind,
|
|
5575
|
+
path: target,
|
|
5576
|
+
sha256: kind === "write" ? sha256OfFile(target) : null
|
|
5577
|
+
});
|
|
5578
|
+
} catch {
|
|
5579
|
+
}
|
|
5580
|
+
}
|
|
5183
5581
|
function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null, file_filter = null) {
|
|
5184
5582
|
let written = 0;
|
|
5185
5583
|
let skipped = 0;
|
|
@@ -5189,7 +5587,7 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5189
5587
|
if (file_filter !== null && !file_filter(src)) return [0, 0, written_paths];
|
|
5190
5588
|
let resolved_src = src;
|
|
5191
5589
|
try {
|
|
5192
|
-
resolved_src =
|
|
5590
|
+
resolved_src = fs15.realpathSync(src);
|
|
5193
5591
|
} catch {
|
|
5194
5592
|
resolved_src = src;
|
|
5195
5593
|
}
|
|
@@ -5197,22 +5595,27 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5197
5595
|
warn(`refused: ${src} dereferences outside the package root \u2014 not copied`);
|
|
5198
5596
|
return [0, 0, written_paths];
|
|
5199
5597
|
}
|
|
5200
|
-
mkdirp(
|
|
5201
|
-
const decision =
|
|
5202
|
-
if (decision === "
|
|
5203
|
-
|
|
5598
|
+
mkdirp(path13.dirname(dest));
|
|
5599
|
+
const decision = tracker.resolve(dest, force);
|
|
5600
|
+
if (decision === "preserve") {
|
|
5601
|
+
tracker.preserve(dest, resolved_src, package_root);
|
|
5602
|
+
_log_tx_entry("skip", dest);
|
|
5603
|
+
return [0, 1, written_paths];
|
|
5604
|
+
}
|
|
5605
|
+
fs15.copyFileSync(src, dest);
|
|
5204
5606
|
_inject_package_tag(dest, src, package_root);
|
|
5607
|
+
_log_tx_entry("write", dest);
|
|
5205
5608
|
written_paths.push(dest);
|
|
5206
5609
|
return [1, 0, written_paths];
|
|
5207
5610
|
}
|
|
5208
5611
|
mkdirp(dest);
|
|
5209
5612
|
const walk = (node) => {
|
|
5210
5613
|
const acc = [];
|
|
5211
|
-
const names =
|
|
5614
|
+
const names = fs15.readdirSync(node).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
5212
5615
|
for (const name of names) {
|
|
5213
|
-
const entry =
|
|
5616
|
+
const entry = path13.join(node, name);
|
|
5214
5617
|
acc.push(entry);
|
|
5215
|
-
const lst =
|
|
5618
|
+
const lst = fs15.lstatSync(entry);
|
|
5216
5619
|
if (lst.isDirectory() && !lst.isSymbolicLink()) {
|
|
5217
5620
|
acc.push(...walk(entry));
|
|
5218
5621
|
}
|
|
@@ -5220,9 +5623,9 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5220
5623
|
return acc;
|
|
5221
5624
|
};
|
|
5222
5625
|
for (const entry of walk(src)) {
|
|
5223
|
-
const rel =
|
|
5224
|
-
const target =
|
|
5225
|
-
const lst =
|
|
5626
|
+
const rel = path13.relative(src, entry);
|
|
5627
|
+
const target = path13.join(dest, rel);
|
|
5628
|
+
const lst = fs15.lstatSync(entry);
|
|
5226
5629
|
if (lst.isDirectory() && !lst.isSymbolicLink()) {
|
|
5227
5630
|
mkdirp(target);
|
|
5228
5631
|
continue;
|
|
@@ -5230,8 +5633,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5230
5633
|
let resolvedIsDir = false;
|
|
5231
5634
|
let resolved = entry;
|
|
5232
5635
|
try {
|
|
5233
|
-
resolved =
|
|
5234
|
-
resolvedIsDir =
|
|
5636
|
+
resolved = fs15.realpathSync(entry);
|
|
5637
|
+
resolvedIsDir = fs15.statSync(entry).isDirectory();
|
|
5235
5638
|
} catch {
|
|
5236
5639
|
resolvedIsDir = false;
|
|
5237
5640
|
}
|
|
@@ -5256,14 +5659,17 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5256
5659
|
if (file_filter !== null && !file_filter(entry)) {
|
|
5257
5660
|
continue;
|
|
5258
5661
|
}
|
|
5259
|
-
const decision =
|
|
5260
|
-
if (decision === "
|
|
5662
|
+
const decision = tracker.resolve(target, force);
|
|
5663
|
+
if (decision === "preserve") {
|
|
5664
|
+
tracker.preserve(target, resolved, package_root);
|
|
5261
5665
|
skipped += 1;
|
|
5666
|
+
_log_tx_entry("skip", target);
|
|
5262
5667
|
continue;
|
|
5263
5668
|
}
|
|
5264
|
-
mkdirp(
|
|
5265
|
-
|
|
5669
|
+
mkdirp(path13.dirname(target));
|
|
5670
|
+
fs15.copyFileSync(resolved, target);
|
|
5266
5671
|
_inject_package_tag(target, resolved, package_root);
|
|
5672
|
+
_log_tx_entry("write", target);
|
|
5267
5673
|
written += 1;
|
|
5268
5674
|
written_paths.push(target);
|
|
5269
5675
|
}
|
|
@@ -5272,12 +5678,17 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5272
5678
|
function _claude_desktop_bundles_dir() {
|
|
5273
5679
|
return write_target(_CLAUDE_DESKTOP_BUNDLES_SUBPATH);
|
|
5274
5680
|
}
|
|
5275
|
-
function _write_claude_desktop_marker(
|
|
5276
|
-
const anchor =
|
|
5277
|
-
const target =
|
|
5681
|
+
function _write_claude_desktop_marker(force, lockfile_path2, bundles_dir, bundle_count) {
|
|
5682
|
+
const anchor = expanduser3(USER_SCOPE_PATHS["claude-desktop"]);
|
|
5683
|
+
const target = path13.join(anchor, "agent-config.md");
|
|
5278
5684
|
mkdirp(anchor);
|
|
5279
5685
|
const body = claudeDesktopMarkerBody(lockfile_path2, anchor, bundles_dir, bundle_count);
|
|
5686
|
+
if (tracker.resolve(target, force) === "preserve") {
|
|
5687
|
+
tracker.preserveContent(target, body);
|
|
5688
|
+
return [0, 1, []];
|
|
5689
|
+
}
|
|
5280
5690
|
writeText(target, body);
|
|
5691
|
+
_log_tx_entry("write", target);
|
|
5281
5692
|
return [1, 0, [target]];
|
|
5282
5693
|
}
|
|
5283
5694
|
function _deploy_claude_desktop(force, package_root, lockfile_path2) {
|
|
@@ -5298,23 +5709,23 @@ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files
|
|
|
5298
5709
|
const wrapped = [];
|
|
5299
5710
|
const collisions = [];
|
|
5300
5711
|
const reserved = [];
|
|
5301
|
-
const commands_dir =
|
|
5712
|
+
const commands_dir = path13.join(anchor, "commands");
|
|
5302
5713
|
let flat_entries = [];
|
|
5303
5714
|
try {
|
|
5304
|
-
flat_entries =
|
|
5715
|
+
flat_entries = fs15.readdirSync(commands_dir).filter((f) => f.endsWith(".md"));
|
|
5305
5716
|
} catch {
|
|
5306
5717
|
}
|
|
5307
5718
|
for (const fname of flat_entries.sort()) {
|
|
5308
5719
|
const slug = fname.slice(0, -".md".length);
|
|
5309
5720
|
if (!is_claude_builtin_name(slug)) continue;
|
|
5310
|
-
|
|
5721
|
+
fs15.rmSync(path13.join(commands_dir, fname), { force: true });
|
|
5311
5722
|
current_files.delete(`commands/${fname}`);
|
|
5312
5723
|
reserved.push(slug);
|
|
5313
5724
|
}
|
|
5314
5725
|
const eligible = new Set(_CLAUDE_FLAT_WRAPPER_EXTRA);
|
|
5315
5726
|
try {
|
|
5316
5727
|
const manifest = JSON.parse(
|
|
5317
|
-
|
|
5728
|
+
fs15.readFileSync(path13.join(package_root, "dist", "discovery", "discovery-manifest.json"), "utf8")
|
|
5318
5729
|
);
|
|
5319
5730
|
for (const a of manifest.artefacts ?? []) {
|
|
5320
5731
|
if (a.category !== "command" || typeof a.slug !== "string") continue;
|
|
@@ -5325,22 +5736,22 @@ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files
|
|
|
5325
5736
|
}
|
|
5326
5737
|
for (const slug of [...eligible].sort()) {
|
|
5327
5738
|
const flat_rel = `commands/${slug}.md`;
|
|
5328
|
-
const flat_abs =
|
|
5329
|
-
if (!
|
|
5330
|
-
const skill_dir =
|
|
5331
|
-
if (
|
|
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)) {
|
|
5332
5743
|
collisions.push(slug);
|
|
5333
5744
|
continue;
|
|
5334
5745
|
}
|
|
5335
|
-
let body =
|
|
5746
|
+
let body = fs15.readFileSync(flat_abs, "utf8");
|
|
5336
5747
|
if (body.startsWith("---\n") && !/^name:/m.test(body.split("\n---")[0] ?? "")) {
|
|
5337
5748
|
body = body.replace("---\n", `---
|
|
5338
5749
|
name: ${slug}
|
|
5339
5750
|
`);
|
|
5340
5751
|
}
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
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 });
|
|
5344
5755
|
current_files.delete(flat_rel);
|
|
5345
5756
|
current_files.add(`skills/${slug}/SKILL.md`);
|
|
5346
5757
|
wrapped.push(slug);
|
|
@@ -5366,14 +5777,14 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
5366
5777
|
results[tool_id] = [0, 0, "unsupported", []];
|
|
5367
5778
|
continue;
|
|
5368
5779
|
}
|
|
5369
|
-
const anchor =
|
|
5780
|
+
const anchor = expanduser3(anchor_raw);
|
|
5370
5781
|
let written_total = 0;
|
|
5371
5782
|
let skipped_total = 0;
|
|
5372
5783
|
const written_paths = [];
|
|
5373
5784
|
let current_files = /* @__PURE__ */ new Set();
|
|
5374
5785
|
for (const [src_rel, dest_sub] of plan) {
|
|
5375
|
-
const src =
|
|
5376
|
-
const dest = dest_sub ?
|
|
5786
|
+
const src = path13.join(package_root, src_rel);
|
|
5787
|
+
const dest = dest_sub ? path13.join(anchor, dest_sub) : anchor;
|
|
5377
5788
|
const rule_filter = _rule_filter_for_source(src_rel, rule_scope);
|
|
5378
5789
|
const [w, s, paths] = _copy_dir_dereferencing_symlinks(
|
|
5379
5790
|
src,
|
|
@@ -5397,11 +5808,12 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
5397
5808
|
if (tool_id === "claude-code") {
|
|
5398
5809
|
const res = _apply_claude_flat_command_wrappers(anchor, package_root, current_files);
|
|
5399
5810
|
rewriteAndReport(
|
|
5400
|
-
|
|
5811
|
+
path13.join(anchor, "rules"),
|
|
5401
5812
|
state.QUIET,
|
|
5402
5813
|
info,
|
|
5403
5814
|
warn,
|
|
5404
|
-
res
|
|
5815
|
+
res,
|
|
5816
|
+
new Set(tracker.conflictState.preserved.map((p) => path13.resolve(p)))
|
|
5405
5817
|
);
|
|
5406
5818
|
}
|
|
5407
5819
|
const missing_targets = _verify_deploy_targets(anchor, plan);
|
|
@@ -5444,10 +5856,10 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
5444
5856
|
results[tool_id] = [written_total, skipped_total, "deployed", written_paths];
|
|
5445
5857
|
if (tool_id === "claude-code") {
|
|
5446
5858
|
try {
|
|
5447
|
-
const manifest =
|
|
5859
|
+
const manifest = path13.join(package_root, "src", "scripts", "hook_manifest.yaml");
|
|
5448
5860
|
const matrix = build_claude_hook_matrix(manifest);
|
|
5449
5861
|
const res = ensure_managed_hooks(
|
|
5450
|
-
|
|
5862
|
+
path13.join(anchor, "settings.json"),
|
|
5451
5863
|
matrix
|
|
5452
5864
|
);
|
|
5453
5865
|
if (!state.QUIET) {
|
|
@@ -5481,10 +5893,10 @@ function _preview_global_reap(tools, package_root) {
|
|
|
5481
5893
|
if (plan === void 0) continue;
|
|
5482
5894
|
const anchor_raw = USER_SCOPE_PATHS[tool_id];
|
|
5483
5895
|
if (!anchor_raw) continue;
|
|
5484
|
-
const anchor =
|
|
5896
|
+
const anchor = expanduser3(anchor_raw);
|
|
5485
5897
|
let current_files = /* @__PURE__ */ new Set();
|
|
5486
5898
|
for (const [src_rel, dest_sub] of plan) {
|
|
5487
|
-
const src =
|
|
5899
|
+
const src = path13.join(package_root, src_rel);
|
|
5488
5900
|
current_files = setUnion(
|
|
5489
5901
|
current_files,
|
|
5490
5902
|
expected_deploy_files(
|
|
@@ -5518,14 +5930,14 @@ function _preview_global_reap(tools, package_root) {
|
|
|
5518
5930
|
function _verify_deploy_targets(anchor, plan) {
|
|
5519
5931
|
const missing = [];
|
|
5520
5932
|
for (const [, dest_sub] of plan) {
|
|
5521
|
-
const target = dest_sub ?
|
|
5933
|
+
const target = dest_sub ? path13.join(anchor, dest_sub) : anchor;
|
|
5522
5934
|
const label = dest_sub || ".";
|
|
5523
5935
|
if (!isDir(target)) {
|
|
5524
5936
|
missing.push(label);
|
|
5525
5937
|
continue;
|
|
5526
5938
|
}
|
|
5527
5939
|
try {
|
|
5528
|
-
const entries =
|
|
5940
|
+
const entries = fs15.readdirSync(target);
|
|
5529
5941
|
if (entries.length === 0) missing.push(label);
|
|
5530
5942
|
} catch {
|
|
5531
5943
|
missing.push(label);
|
|
@@ -5543,9 +5955,9 @@ function _resolve_global_settings_doc() {
|
|
|
5543
5955
|
}
|
|
5544
5956
|
function _resolve_global_settings_path() {
|
|
5545
5957
|
const root = event4u_root();
|
|
5546
|
-
const canonical =
|
|
5958
|
+
const canonical = path13.join(root, "settings", SETTINGS_FILE);
|
|
5547
5959
|
if (pathExists(canonical)) return canonical;
|
|
5548
|
-
const legacy =
|
|
5960
|
+
const legacy = path13.join(root, SETTINGS_FILE);
|
|
5549
5961
|
if (pathExists(legacy)) return legacy;
|
|
5550
5962
|
return null;
|
|
5551
5963
|
}
|
|
@@ -5656,7 +6068,7 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
5656
6068
|
info(` schema_version=1, agent_config_version=${installed_version}`);
|
|
5657
6069
|
info(` tools=${merged_tools.join(",")}`);
|
|
5658
6070
|
}
|
|
5659
|
-
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(
|
|
6071
|
+
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path13.join(project_root, ".agent-src.uncondensed"))) {
|
|
5660
6072
|
const drift = collect_drift(project_root);
|
|
5661
6073
|
if (!state.QUIET) {
|
|
5662
6074
|
process2.stdout.write("\n");
|
|
@@ -5770,19 +6182,19 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
5770
6182
|
}
|
|
5771
6183
|
}
|
|
5772
6184
|
}
|
|
5773
|
-
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(
|
|
5774
|
-
const files_by_tool =
|
|
6185
|
+
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path13.join(project_root, ".agent-src.uncondensed"))) {
|
|
6186
|
+
const files_by_tool = filesByToolFromDeploy(deploy_results);
|
|
5775
6187
|
const rc = _update_installed_tools_manifest(project_root, tools, "global", force, files_by_tool);
|
|
5776
6188
|
if (rc !== 0) return rc;
|
|
5777
6189
|
const removed_marker = _remove_legacy_consumer_bridge_marker(project_root);
|
|
5778
6190
|
if (removed_marker !== null && !state.QUIET) {
|
|
5779
|
-
const rel = isRelativeTo(removed_marker, project_root) ?
|
|
6191
|
+
const rel = isRelativeTo(removed_marker, project_root) ? path13.relative(project_root, removed_marker) : removed_marker;
|
|
5780
6192
|
info(`Removed legacy bridge marker: ${rel}`);
|
|
5781
6193
|
}
|
|
5782
6194
|
const anchor_paths = _write_per_tool_project_anchors(project_root, tools);
|
|
5783
6195
|
if (anchor_paths.length > 0 && !state.QUIET) {
|
|
5784
6196
|
for (const p of anchor_paths) {
|
|
5785
|
-
const rel = isRelativeTo(p, project_root) ?
|
|
6197
|
+
const rel = isRelativeTo(p, project_root) ? path13.relative(project_root, p) : p;
|
|
5786
6198
|
info(`Project anchor written: ${rel}`);
|
|
5787
6199
|
}
|
|
5788
6200
|
}
|
|
@@ -5818,8 +6230,8 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
5818
6230
|
}
|
|
5819
6231
|
function _catalogue_truncation_warnings(deploy_results, project_root) {
|
|
5820
6232
|
const log_candidates = [
|
|
5821
|
-
|
|
5822
|
-
...project_root ? [
|
|
6233
|
+
path13.join(event4u_root(), "state", "skill-catalogue.jsonl"),
|
|
6234
|
+
...project_root ? [path13.join(project_root, OBSERVATION_LOG)] : []
|
|
5823
6235
|
];
|
|
5824
6236
|
const records = log_candidates.flatMap((p) => readObservationLog(p));
|
|
5825
6237
|
if (records.length === 0) return [];
|
|
@@ -5833,7 +6245,7 @@ function _catalogue_truncation_warnings(deploy_results, project_root) {
|
|
|
5833
6245
|
if (limit === void 0) continue;
|
|
5834
6246
|
const anchor_raw = USER_SCOPE_PATHS[tool_id];
|
|
5835
6247
|
if (!anchor_raw) continue;
|
|
5836
|
-
const volume = measureCatalogueVolume(tool_id,
|
|
6248
|
+
const volume = measureCatalogueVolume(tool_id, expanduser3(anchor_raw));
|
|
5837
6249
|
const warning = catalogueLimitWarning(volume, limit);
|
|
5838
6250
|
if (warning !== null) lines.push(warning);
|
|
5839
6251
|
}
|
|
@@ -5842,19 +6254,19 @@ function _catalogue_truncation_warnings(deploy_results, project_root) {
|
|
|
5842
6254
|
function _scoped_migration_notice(deploy_results, project_root, package_root, probe) {
|
|
5843
6255
|
if (!isInteractiveSession(probe)) return [];
|
|
5844
6256
|
const log_candidates = [
|
|
5845
|
-
|
|
5846
|
-
...project_root ? [
|
|
6257
|
+
path13.join(event4u_root(), "state", "skill-catalogue.jsonl"),
|
|
6258
|
+
...project_root ? [path13.join(project_root, OBSERVATION_LOG)] : []
|
|
5847
6259
|
];
|
|
5848
6260
|
const limits = knownHostLimits(log_candidates.flatMap((p) => readObservationLog(p)));
|
|
5849
6261
|
if (limits.size === 0) return [];
|
|
5850
6262
|
const resolved = _resolve_scoped_projection(package_root);
|
|
5851
|
-
const settings_path = _resolve_global_settings_path() ??
|
|
6263
|
+
const settings_path = _resolve_global_settings_path() ?? path13.join(event4u_root(), "settings", SETTINGS_FILE);
|
|
5852
6264
|
for (const tool_id of Object.keys(deploy_results).sort()) {
|
|
5853
6265
|
const [, , status] = deploy_results[tool_id];
|
|
5854
6266
|
if (status !== "deployed") continue;
|
|
5855
6267
|
const anchor_raw = USER_SCOPE_PATHS[tool_id];
|
|
5856
6268
|
if (!anchor_raw) continue;
|
|
5857
|
-
const volume = measureCatalogueVolume(tool_id,
|
|
6269
|
+
const volume = measureCatalogueVolume(tool_id, expanduser3(anchor_raw));
|
|
5858
6270
|
const eligibility = migrationEligibility(
|
|
5859
6271
|
tool_id,
|
|
5860
6272
|
resolved.mode,
|
|
@@ -5867,8 +6279,8 @@ function _scoped_migration_notice(deploy_results, project_root, package_root, pr
|
|
|
5867
6279
|
}
|
|
5868
6280
|
return [];
|
|
5869
6281
|
}
|
|
5870
|
-
var SETTINGS_SURFACE_REL =
|
|
5871
|
-
var SETTINGS_DELTA_REL =
|
|
6282
|
+
var SETTINGS_SURFACE_REL = path13.join("state", "settings-surface.json");
|
|
6283
|
+
var SETTINGS_DELTA_REL = path13.join("state", "settings-delta.json");
|
|
5872
6284
|
function _current_settings_surface(version) {
|
|
5873
6285
|
const jsonSchema = zodToJsonSchema(settingsSchema, {
|
|
5874
6286
|
name: "AgentSettings",
|
|
@@ -5879,20 +6291,20 @@ function _current_settings_surface(version) {
|
|
|
5879
6291
|
}
|
|
5880
6292
|
function _write_settings_surface_snapshot(installed_version) {
|
|
5881
6293
|
const root = event4u_root();
|
|
5882
|
-
const surface_path =
|
|
5883
|
-
const delta_path =
|
|
6294
|
+
const surface_path = path13.join(root, SETTINGS_SURFACE_REL);
|
|
6295
|
+
const delta_path = path13.join(root, SETTINGS_DELTA_REL);
|
|
5884
6296
|
const next = _current_settings_surface(installed_version);
|
|
5885
6297
|
let previous = null;
|
|
5886
6298
|
try {
|
|
5887
|
-
const parsed = JSON.parse(
|
|
6299
|
+
const parsed = JSON.parse(fs15.readFileSync(surface_path, "utf8"));
|
|
5888
6300
|
if (parsed !== null && typeof parsed === "object" && parsed.entries !== void 0) previous = parsed;
|
|
5889
6301
|
} catch {
|
|
5890
6302
|
}
|
|
5891
6303
|
if (previous !== null && previous.version !== next.version) {
|
|
5892
6304
|
const delta = computeSurfaceDelta(previous, next);
|
|
5893
6305
|
if (delta.changes.length > 0) {
|
|
5894
|
-
|
|
5895
|
-
|
|
6306
|
+
fs15.mkdirSync(path13.dirname(delta_path), { recursive: true, mode: 448 });
|
|
6307
|
+
fs15.writeFileSync(delta_path, `${JSON.stringify(delta, null, 2)}
|
|
5896
6308
|
`, { mode: 384 });
|
|
5897
6309
|
if (!state.QUIET) {
|
|
5898
6310
|
const counts = {};
|
|
@@ -5904,8 +6316,8 @@ function _write_settings_surface_snapshot(installed_version) {
|
|
|
5904
6316
|
}
|
|
5905
6317
|
}
|
|
5906
6318
|
}
|
|
5907
|
-
|
|
5908
|
-
|
|
6319
|
+
fs15.mkdirSync(path13.dirname(surface_path), { recursive: true, mode: 448 });
|
|
6320
|
+
fs15.writeFileSync(surface_path, `${JSON.stringify(next, null, 2)}
|
|
5909
6321
|
`, { mode: 384 });
|
|
5910
6322
|
}
|
|
5911
6323
|
function arrayStrEqual(a, b) {
|
|
@@ -6125,13 +6537,13 @@ function _minimal_templates_root() {
|
|
|
6125
6537
|
const chain = [start];
|
|
6126
6538
|
let cur = start;
|
|
6127
6539
|
for (; ; ) {
|
|
6128
|
-
const parent =
|
|
6540
|
+
const parent = path13.dirname(cur);
|
|
6129
6541
|
if (parent === cur) break;
|
|
6130
6542
|
chain.push(parent);
|
|
6131
6543
|
cur = parent;
|
|
6132
6544
|
}
|
|
6133
6545
|
for (const ancestor of chain) {
|
|
6134
|
-
const candidate =
|
|
6546
|
+
const candidate = path13.join(ancestor, "src", "templates", "minimal");
|
|
6135
6547
|
if (isDir(candidate)) return candidate;
|
|
6136
6548
|
}
|
|
6137
6549
|
fail("Could not locate src/templates/minimal/ \u2014 package install is corrupt.");
|
|
@@ -6139,9 +6551,9 @@ function _minimal_templates_root() {
|
|
|
6139
6551
|
var INSTALL_MODE_MARKER_REL = "agents/.agent-state/install-mode.txt";
|
|
6140
6552
|
function _write_install_mode_marker(project_root, mode) {
|
|
6141
6553
|
if (mode !== "minimal" && mode !== "full") return;
|
|
6142
|
-
const marker =
|
|
6554
|
+
const marker = path13.join(project_root, INSTALL_MODE_MARKER_REL);
|
|
6143
6555
|
try {
|
|
6144
|
-
mkdirp(
|
|
6556
|
+
mkdirp(path13.dirname(marker));
|
|
6145
6557
|
writeText(marker, `${mode}
|
|
6146
6558
|
`);
|
|
6147
6559
|
} catch {
|
|
@@ -6150,7 +6562,7 @@ function _write_install_mode_marker(project_root, mode) {
|
|
|
6150
6562
|
function install_minimal(target_root_in, force, user_type = "") {
|
|
6151
6563
|
let target_root = resolvePath(target_root_in);
|
|
6152
6564
|
mkdirp(target_root);
|
|
6153
|
-
const parent =
|
|
6565
|
+
const parent = path13.dirname(target_root);
|
|
6154
6566
|
if (parent !== target_root) {
|
|
6155
6567
|
const existing = find_project_root_with_anchor(parent);
|
|
6156
6568
|
if (existing !== null && existing[0] !== target_root) {
|
|
@@ -6161,21 +6573,21 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
6161
6573
|
}
|
|
6162
6574
|
}
|
|
6163
6575
|
const templates = _minimal_templates_root();
|
|
6164
|
-
const settings_src =
|
|
6165
|
-
const overrides_gitkeep_src =
|
|
6166
|
-
const overrides_readme_src =
|
|
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");
|
|
6167
6579
|
if (!isFile(settings_src)) fail(`Bundled minimal settings template missing under ${templates}`);
|
|
6168
6580
|
if (!isFile(overrides_gitkeep_src) || !isFile(overrides_readme_src)) {
|
|
6169
6581
|
fail(`Bundled overrides scaffold templates missing under ${templates}`);
|
|
6170
6582
|
}
|
|
6171
6583
|
info(`Minimal init \u2192 ${target_root}`);
|
|
6172
|
-
const overrides_root =
|
|
6584
|
+
const overrides_root = path13.join(target_root, "agents", "overrides");
|
|
6173
6585
|
mkdirp(overrides_root);
|
|
6174
6586
|
const gitkeep_body = readText(overrides_gitkeep_src);
|
|
6175
6587
|
for (const sub of ["rules", "skills", "commands"]) {
|
|
6176
|
-
const sub_dir =
|
|
6588
|
+
const sub_dir = path13.join(overrides_root, sub);
|
|
6177
6589
|
mkdirp(sub_dir);
|
|
6178
|
-
const gitkeep_dst =
|
|
6590
|
+
const gitkeep_dst = path13.join(sub_dir, ".gitkeep");
|
|
6179
6591
|
if (pathExists(gitkeep_dst) && !force) {
|
|
6180
6592
|
skip(`agents/overrides/${sub}/.gitkeep already exists (use --force to overwrite)`);
|
|
6181
6593
|
} else {
|
|
@@ -6183,7 +6595,7 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
6183
6595
|
success(`Wrote agents/overrides/${sub}/.gitkeep`);
|
|
6184
6596
|
}
|
|
6185
6597
|
}
|
|
6186
|
-
const readme_dst =
|
|
6598
|
+
const readme_dst = path13.join(overrides_root, "README.md");
|
|
6187
6599
|
if (pathExists(readme_dst) && !force) {
|
|
6188
6600
|
skip("agents/overrides/README.md already exists (use --force to overwrite)");
|
|
6189
6601
|
} else {
|
|
@@ -6201,14 +6613,14 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
6201
6613
|
personal:
|
|
6202
6614
|
user_type: ${user_type}
|
|
6203
6615
|
`;
|
|
6204
|
-
mkdirp(
|
|
6616
|
+
mkdirp(path13.dirname(settings_dst));
|
|
6205
6617
|
writeText(settings_dst, body);
|
|
6206
6618
|
success(`Wrote ${SETTINGS_FILE} (user_type=${user_type})`);
|
|
6207
6619
|
}
|
|
6208
6620
|
}
|
|
6209
6621
|
const removed_marker = _remove_legacy_consumer_bridge_marker(target_root);
|
|
6210
6622
|
if (removed_marker !== null) {
|
|
6211
|
-
const rel = isRelativeTo(removed_marker, target_root) ?
|
|
6623
|
+
const rel = isRelativeTo(removed_marker, target_root) ? path13.relative(target_root, removed_marker) : removed_marker;
|
|
6212
6624
|
success(`Removed legacy bridge marker: ${rel}`);
|
|
6213
6625
|
}
|
|
6214
6626
|
_write_install_mode_marker(target_root, "minimal");
|
|
@@ -6282,7 +6694,7 @@ function run_interactive_init(project_root, force) {
|
|
|
6282
6694
|
);
|
|
6283
6695
|
return 0;
|
|
6284
6696
|
}
|
|
6285
|
-
const target =
|
|
6697
|
+
const target = path13.join(project_root, _LOCAL_CONFIG_FILE);
|
|
6286
6698
|
if (pathExists(target) && !force) {
|
|
6287
6699
|
warn(
|
|
6288
6700
|
`${_LOCAL_CONFIG_FILE} already exists; re-run with --force to overwrite. Skipping interactive init.`
|
|
@@ -6309,7 +6721,7 @@ function run_interactive_init(project_root, force) {
|
|
|
6309
6721
|
warn(`Could not write ${target}: ${String(exc)}`);
|
|
6310
6722
|
return 1;
|
|
6311
6723
|
}
|
|
6312
|
-
success(`Wrote ${
|
|
6724
|
+
success(`Wrote ${path13.relative(project_root, target)} (${user_type} / ${stack} / ${verbosity})`);
|
|
6313
6725
|
return 0;
|
|
6314
6726
|
}
|
|
6315
6727
|
var _WIZARD_READY_RE = /^WIZARD_READY (http:\/\/(?:127\.0\.0\.1|localhost):\d+\/\S*)\r?$/;
|
|
@@ -6327,12 +6739,12 @@ function _wizard_should_launch(opts) {
|
|
|
6327
6739
|
return [true, ""];
|
|
6328
6740
|
}
|
|
6329
6741
|
function _wizard_cli_dist(_project_root) {
|
|
6330
|
-
const package_root =
|
|
6331
|
-
const cli =
|
|
6742
|
+
const package_root = path13.dirname(path13.dirname(path13.dirname(resolvePath(_HERE))));
|
|
6743
|
+
const cli = path13.join(package_root, "dist", "cli", "agent-config.js");
|
|
6332
6744
|
return pathExists(cli) ? cli : null;
|
|
6333
6745
|
}
|
|
6334
6746
|
function _server_info_path() {
|
|
6335
|
-
return
|
|
6747
|
+
return path13.join(os3.homedir(), ".event4u", "agent-config", "local-server.json");
|
|
6336
6748
|
}
|
|
6337
6749
|
function _pid_is_agent_config(pid) {
|
|
6338
6750
|
let res;
|
|
@@ -6349,7 +6761,7 @@ function _pid_is_agent_config(pid) {
|
|
|
6349
6761
|
}
|
|
6350
6762
|
function unlinkMissingOk(p) {
|
|
6351
6763
|
try {
|
|
6352
|
-
|
|
6764
|
+
fs15.unlinkSync(p);
|
|
6353
6765
|
} catch {
|
|
6354
6766
|
}
|
|
6355
6767
|
}
|
|
@@ -6427,14 +6839,14 @@ function _wizard_spawn(project_root, pass_project_root = true) {
|
|
|
6427
6839
|
}
|
|
6428
6840
|
function _wizard_run_sync(cmd, env, cli) {
|
|
6429
6841
|
const total = _WIZARD_TIMEOUTS.reduce((a, b) => a + b, 0);
|
|
6430
|
-
const log_path =
|
|
6842
|
+
const log_path = path13.join(
|
|
6431
6843
|
os3.tmpdir(),
|
|
6432
6844
|
`agent-config-wizard-${process2.pid}-${Date.now()}.log`
|
|
6433
6845
|
);
|
|
6434
6846
|
let child;
|
|
6435
6847
|
let log_fd = null;
|
|
6436
6848
|
try {
|
|
6437
|
-
log_fd =
|
|
6849
|
+
log_fd = fs15.openSync(log_path, "w");
|
|
6438
6850
|
child = spawn(cmd[0], cmd.slice(1), {
|
|
6439
6851
|
env,
|
|
6440
6852
|
detached: true,
|
|
@@ -6452,7 +6864,7 @@ function _wizard_run_sync(cmd, env, cli) {
|
|
|
6452
6864
|
} finally {
|
|
6453
6865
|
if (log_fd !== null) {
|
|
6454
6866
|
try {
|
|
6455
|
-
|
|
6867
|
+
fs15.closeSync(log_fd);
|
|
6456
6868
|
} catch {
|
|
6457
6869
|
}
|
|
6458
6870
|
}
|
|
@@ -6702,8 +7114,8 @@ function main2(argv) {
|
|
|
6702
7114
|
const target_root = resolvePath(
|
|
6703
7115
|
opts.custom_path || opts.project || process2.env["PROJECT_ROOT"] || process2.cwd()
|
|
6704
7116
|
);
|
|
6705
|
-
const minimal_package_root =
|
|
6706
|
-
|
|
7117
|
+
const minimal_package_root = path13.dirname(
|
|
7118
|
+
path13.dirname(path13.dirname(_minimal_templates_root()))
|
|
6707
7119
|
);
|
|
6708
7120
|
const validated_user_type = _validate_user_type(minimal_package_root, opts.user_type);
|
|
6709
7121
|
return install_minimal(target_root, opts.force, validated_user_type);
|
|
@@ -6727,19 +7139,25 @@ function main2(argv) {
|
|
|
6727
7139
|
const rc3 = _run_migrate_to_global(detect_root);
|
|
6728
7140
|
if (rc3 !== 0) return rc3;
|
|
6729
7141
|
}
|
|
6730
|
-
|
|
7142
|
+
tracker.begin(detect_root);
|
|
7143
|
+
const rc2 = tracker.finalizeRc(
|
|
7144
|
+
install_global(parsed_tools, opts.force, detect_root, opts.core_only)
|
|
7145
|
+
);
|
|
6731
7146
|
_emit_progress_terminal(rc2);
|
|
6732
|
-
if (rc2 === 0 && wizard_handoff) {
|
|
6733
|
-
|
|
7147
|
+
if ((rc2 === 0 || rc2 === EXIT_COMPLETED_WITH_CONFLICTS) && wizard_handoff) {
|
|
7148
|
+
const wizard_rc = _wizard_spawn(detect_root, false);
|
|
7149
|
+
return wizard_rc === 0 ? rc2 : wizard_rc;
|
|
6734
7150
|
}
|
|
6735
7151
|
return rc2;
|
|
6736
7152
|
}
|
|
6737
7153
|
const project_root = custom_path || resolvePath(opts.project || process2.env["PROJECT_ROOT"] || process2.cwd());
|
|
6738
|
-
const is_first_run = !pathExists(
|
|
6739
|
-
|
|
7154
|
+
const is_first_run = !pathExists(path13.join(project_root, SETTINGS_FILE));
|
|
7155
|
+
tracker.begin(project_root);
|
|
7156
|
+
let rc = _main_project_install(opts, project_root, parsed_tools, is_first_run);
|
|
6740
7157
|
if (rc === 0 && opts.interactive) {
|
|
6741
7158
|
run_interactive_init(project_root, opts.force);
|
|
6742
7159
|
}
|
|
7160
|
+
rc = tracker.finalizeRc(rc);
|
|
6743
7161
|
_emit_progress_terminal(rc);
|
|
6744
7162
|
return rc;
|
|
6745
7163
|
}
|
|
@@ -6799,16 +7217,16 @@ function _team_setup_hint_line(project_root) {
|
|
|
6799
7217
|
return " \u2022 Claude Code team mode (optional cross-model review via the official codex plugin): run `agent-config doctor --check team` for setup status.";
|
|
6800
7218
|
}
|
|
6801
7219
|
function finalize_claude_model_tiers(project_root) {
|
|
6802
|
-
const claude_skills =
|
|
6803
|
-
const augment_skills =
|
|
7220
|
+
const claude_skills = path13.join(project_root, ".claude", "skills");
|
|
7221
|
+
const augment_skills = path13.join(project_root, ".augment", "skills");
|
|
6804
7222
|
if (!isDir(claude_skills) || !isDir(augment_skills)) return 0;
|
|
6805
7223
|
if (_read_consumer_auto_switch(project_root) !== "auto") return 0;
|
|
6806
7224
|
let rendered = 0;
|
|
6807
|
-
const entries =
|
|
7225
|
+
const entries = fs15.readdirSync(claude_skills).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
6808
7226
|
for (const name of entries) {
|
|
6809
|
-
const entry =
|
|
6810
|
-
const src_dir =
|
|
6811
|
-
const src_md =
|
|
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");
|
|
6812
7230
|
let tier;
|
|
6813
7231
|
try {
|
|
6814
7232
|
tier = read_model_tier(src_md);
|
|
@@ -6817,22 +7235,22 @@ function finalize_claude_model_tiers(project_root) {
|
|
|
6817
7235
|
}
|
|
6818
7236
|
if (tier === null || !(tier in TIER_TO_CLAUDE_MODEL) || !isDir(src_dir)) continue;
|
|
6819
7237
|
if (isSymlink(entry) || isFile(entry)) {
|
|
6820
|
-
|
|
7238
|
+
fs15.unlinkSync(entry);
|
|
6821
7239
|
} else if (isDir(entry)) {
|
|
6822
|
-
|
|
7240
|
+
fs15.rmSync(entry, { recursive: true, force: true });
|
|
6823
7241
|
}
|
|
6824
7242
|
mkdirp(entry);
|
|
6825
|
-
const srcFiles =
|
|
7243
|
+
const srcFiles = fs15.readdirSync(src_dir).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
6826
7244
|
for (const fname of srcFiles) {
|
|
6827
7245
|
if (fname === "SKILL.md") {
|
|
6828
7246
|
writeText(
|
|
6829
|
-
|
|
7247
|
+
path13.join(entry, "SKILL.md"),
|
|
6830
7248
|
render_native_model_md(readText(src_md), tier)
|
|
6831
7249
|
);
|
|
6832
7250
|
} else {
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
7251
|
+
fs15.symlinkSync(
|
|
7252
|
+
path13.join("../../../.augment/skills", name, fname),
|
|
7253
|
+
path13.join(entry, fname)
|
|
6836
7254
|
);
|
|
6837
7255
|
}
|
|
6838
7256
|
}
|
|
@@ -6850,7 +7268,7 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
6850
7268
|
let package_type;
|
|
6851
7269
|
if (opts.package) {
|
|
6852
7270
|
package_root = resolvePath(opts.package);
|
|
6853
|
-
if (!pathExists(
|
|
7271
|
+
if (!pathExists(path13.join(package_root, "src", "config", "profiles", "minimal.ini"))) {
|
|
6854
7272
|
fail(`Invalid --package path (missing src/config/profiles/minimal.ini): ${package_root}`);
|
|
6855
7273
|
}
|
|
6856
7274
|
package_type = detect_package_type_for_project(project_root, package_root);
|
|
@@ -6936,7 +7354,7 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
6936
7354
|
_smoke_test_hooks(project_root, package_root);
|
|
6937
7355
|
}
|
|
6938
7356
|
if (!opts.skip_bridges) {
|
|
6939
|
-
const files_by_tool =
|
|
7357
|
+
const files_by_tool = filesByToolFromBridges(parsed_tools, project_root, "project", _bridge_marker);
|
|
6940
7358
|
const rc = _update_installed_tools_manifest(
|
|
6941
7359
|
project_root,
|
|
6942
7360
|
parsed_tools,
|
|
@@ -6993,9 +7411,9 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
6993
7411
|
function _resolvedArgv1() {
|
|
6994
7412
|
if (process2.argv[1] === void 0) return void 0;
|
|
6995
7413
|
try {
|
|
6996
|
-
return
|
|
7414
|
+
return fs15.realpathSync(path13.resolve(process2.argv[1]));
|
|
6997
7415
|
} catch {
|
|
6998
|
-
return
|
|
7416
|
+
return path13.resolve(process2.argv[1]);
|
|
6999
7417
|
}
|
|
7000
7418
|
}
|
|
7001
7419
|
var _argv1 = _resolvedArgv1();
|