@event4u/agent-config 16.2.0 → 16.4.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 +337 -234
- package/README.md +15 -13
- package/agents/templates/.ai-council.yml.example +26 -8
- package/dist/agent-src/commands/analyze/inbox.md +11 -8
- package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
- package/dist/agent-src/commands/bug/fix.md +17 -2
- package/dist/agent-src/commands/bug/investigate.md +1 -1
- package/dist/agent-src/commands/commit/in-chunks.md +40 -31
- package/dist/agent-src/commands/commit.md +72 -33
- package/dist/agent-src/commands/condense.md +2 -8
- package/dist/agent-src/commands/council/debate.md +11 -7
- package/dist/agent-src/commands/council/default.md +10 -9
- package/dist/agent-src/commands/council.md +1 -1
- package/dist/agent-src/commands/estimate-ticket.md +1 -1
- package/dist/agent-src/commands/feature/explore.md +3 -3
- package/dist/agent-src/commands/feature/plan.md +2 -2
- package/dist/agent-src/commands/feature/roadmap.md +1 -1
- package/dist/agent-src/commands/fix/ci.md +18 -4
- package/dist/agent-src/commands/fix/commit-messages.md +48 -23
- package/dist/agent-src/commands/fix/pr-comments.md +3 -6
- package/dist/agent-src/commands/implement-ticket.md +4 -4
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/memory/add.md +4 -16
- package/dist/agent-src/commands/memory/load.md +5 -6
- package/dist/agent-src/commands/memory/promote.md +3 -16
- package/dist/agent-src/commands/mission/upgrade.md +3 -2
- package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
- package/dist/agent-src/commands/optimize/deep.md +4 -2
- package/dist/agent-src/commands/optimize/rtk.md +4 -26
- package/dist/agent-src/commands/pr/create/description-only.md +18 -15
- package/dist/agent-src/commands/pr/create.md +42 -34
- package/dist/agent-src/commands/pr/merge.md +136 -9
- package/dist/agent-src/commands/prepare-for-review.md +13 -11
- package/dist/agent-src/commands/project/analyze.md +7 -35
- package/dist/agent-src/commands/refine-ticket.md +1 -1
- package/dist/agent-src/commands/review/changes.md +14 -19
- package/dist/agent-src/commands/roadmap/create.md +1 -1
- package/dist/agent-src/commands/roadmap/materialize.md +1 -1
- package/dist/agent-src/commands/roadmap/next.md +10 -1
- package/dist/agent-src/commands/roadmap/process-full.md +56 -42
- package/dist/agent-src/commands/roadmap/resolve-blockers.md +411 -0
- package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
- package/dist/agent-src/commands/roadmap.md +18 -4
- package/dist/agent-src/commands/tests/create.md +17 -3
- package/dist/agent-src/commands/tests/execute.md +22 -5
- package/dist/agent-src/commands/worktree/create.md +7 -3
- package/dist/agent-src/commands/worktree/verify.md +2 -1
- package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
- package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
- package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
- package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +7 -7
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
- package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
- package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
- package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +99 -54
- package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
- package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
- package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
- package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +95 -7
- package/dist/agent-src/contexts/subagent-configuration.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
- package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
- package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
- package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
- package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
- package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
- package/dist/agent-src/guidelines/php/git.md +15 -2
- package/dist/agent-src/rules/active-remediation.md +1 -2
- package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
- package/dist/agent-src/rules/architecture.md +0 -1
- package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
- package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
- package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/brand-consistency.md +0 -1
- package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
- package/dist/agent-src/rules/broken-access-control.md +1 -1
- package/dist/agent-src/rules/cli-output-handling.md +0 -1
- package/dist/agent-src/rules/code-comment-discipline.md +0 -1
- package/dist/agent-src/rules/code-provenance.md +0 -1
- package/dist/agent-src/rules/command-suggestion-policy.md +1 -1
- package/dist/agent-src/rules/commit-conventions.md +1 -2
- package/dist/agent-src/rules/communication-through-line.md +1 -2
- package/dist/agent-src/rules/content-quoting-floor.md +1 -2
- package/dist/agent-src/rules/context-hygiene.md +6 -6
- package/dist/agent-src/rules/copilot-routing.md +1 -2
- package/dist/agent-src/rules/council-availability.md +4 -4
- package/dist/agent-src/rules/cross-source-consistency.md +4 -6
- package/dist/agent-src/rules/decision-revisit-gate.md +17 -35
- package/dist/agent-src/rules/delegation-policy.md +2 -3
- package/dist/agent-src/rules/design-fidelity.md +12 -16
- package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
- package/dist/agent-src/rules/devcontainer-routing.md +1 -2
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
- package/dist/agent-src/rules/docker-commands.md +0 -1
- package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
- package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +1 -1
- package/dist/agent-src/rules/domain-safety-retention.md +1 -1
- package/dist/agent-src/rules/downstream-changes.md +0 -1
- package/dist/agent-src/rules/engineering-safety-floor.md +1 -1
- package/dist/agent-src/rules/evaluator-independence.md +3 -2
- package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
- package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
- package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -2
- package/dist/agent-src/rules/finance-safety-floor.md +1 -1
- package/dist/agent-src/rules/fix-what-you-see.md +6 -32
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
- package/dist/agent-src/rules/git-history-discipline.md +2 -2
- package/dist/agent-src/rules/guidelines.md +0 -1
- package/dist/agent-src/rules/history-discipline.md +0 -1
- package/dist/agent-src/rules/icon-consistency.md +0 -1
- package/dist/agent-src/rules/image-likeness-and-rights.md +1 -1
- package/dist/agent-src/rules/improve-before-implement.md +0 -1
- package/dist/agent-src/rules/invite-challenge.md +0 -1
- package/dist/agent-src/rules/laravel-routing.md +1 -2
- package/dist/agent-src/rules/laravel-translations.md +0 -1
- package/dist/agent-src/rules/legal-safety-floor.md +3 -3
- package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -1
- package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -1
- package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
- package/dist/agent-src/rules/media-governance-routing.md +13 -17
- package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
- package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
- package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
- package/dist/agent-src/rules/missing-tool-handling.md +0 -1
- package/dist/agent-src/rules/model-recommendation.md +0 -1
- package/dist/agent-src/rules/neighbour-precedence.md +64 -0
- package/dist/agent-src/rules/no-attribution-footers.md +0 -1
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
- package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
- package/dist/agent-src/rules/no-roadmap-references.md +0 -1
- package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
- package/dist/agent-src/rules/onboarding-gate.md +0 -1
- package/dist/agent-src/rules/output-discipline.md +0 -1
- package/dist/agent-src/rules/package-ci-checks.md +0 -1
- package/dist/agent-src/rules/persona-governance.md +4 -5
- package/dist/agent-src/rules/php-coding.md +0 -1
- package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
- package/dist/agent-src/rules/preservation-guard.md +0 -1
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -4
- package/dist/agent-src/rules/question-not-instruction.md +1 -1
- package/dist/agent-src/rules/reviewer-awareness.md +0 -1
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +4 -7
- package/dist/agent-src/rules/role-mode-adherence.md +0 -1
- package/dist/agent-src/rules/rule-type-governance.md +0 -1
- package/dist/agent-src/rules/runtime-safety.md +1 -1
- package/dist/agent-src/rules/scale-discipline.md +0 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
- package/dist/agent-src/rules/security-sensitive-stop.md +3 -3
- package/dist/agent-src/rules/self-repair-loop.md +0 -1
- package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
- package/dist/agent-src/rules/session-canary.md +7 -62
- package/dist/agent-src/rules/settings-ask-protocol.md +6 -6
- package/dist/agent-src/rules/size-enforcement.md +0 -1
- package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
- package/dist/agent-src/rules/skill-quality.md +0 -1
- package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
- package/dist/agent-src/rules/source-confidentiality.md +1 -1
- package/dist/agent-src/rules/source-discovery-gate.md +0 -1
- package/dist/agent-src/rules/source-of-truth.md +0 -1
- package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
- package/dist/agent-src/rules/symfony-routing.md +1 -2
- package/dist/agent-src/rules/think-before-action.md +0 -1
- package/dist/agent-src/rules/token-budget-discipline.md +12 -46
- package/dist/agent-src/rules/token-efficiency.md +0 -1
- package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
- package/dist/agent-src/rules/tool-safety.md +1 -1
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +1 -1
- package/dist/agent-src/rules/upstream-proposal.md +0 -1
- package/dist/agent-src/rules/user-interaction.md +0 -1
- package/dist/agent-src/rules/user-interrupt-priority.md +1 -1
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/dist/agent-src/scripts/deferral_carry.ts +339 -0
- package/dist/agent-src/scripts/gate_budget.ts +47 -23
- package/dist/agent-src/scripts/gate_execute.ts +12 -4
- package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
- package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
- package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
- package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
- package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
- package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
- package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
- package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
- package/dist/agent-src/skills/database/data/manifest.json +2 -2
- package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
- package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
- package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
- package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
- package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
- package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
- package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
- package/dist/agent-src/skills/iconography/SKILL.md +1 -1
- package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
- package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
- package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
- package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
- package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
- package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +5 -3
- package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -2
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
- package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
- package/dist/agent-src/templates/AGENTS.md +1 -1
- package/dist/agent-src/templates/agent-settings.md +46 -129
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
- package/dist/agent-src/templates/command.md +2 -2
- package/dist/agent-src/templates/roadmaps.md +6 -1
- package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
- package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
- package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
- package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/dist/agent-src/templates/skill.md +1 -1
- package/dist/cli/registry.js +2 -1
- package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
- package/dist/cli-delegate/check_update_banner.js +207 -120
- package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
- package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-5GPULQBE.js} +2797 -338
- package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-6SRJTYJS.js} +42 -176
- package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
- package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
- package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
- package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
- package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
- package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-AED2VQGM.js} +1245 -249
- package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
- package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
- package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
- package/dist/cli-delegate/chunk-F3QDG2GT.js +2569 -0
- package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-G5VVIZRC.js} +3 -3
- package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-H76PHZBI.js} +149 -61
- package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
- package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
- package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
- package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
- package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-KXXWJTDO.js} +6 -11
- package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
- package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-MDPPKQCQ.js} +58 -9
- package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-MSUL5NYP.js} +5 -5
- package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
- package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
- package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
- package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-PWX7CKMD.js} +4 -4
- package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
- package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-T7XSJSUQ.js} +1144 -589
- package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
- package/dist/cli-delegate/chunk-WQWXGIWB.js +1779 -0
- package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-XQTPXKFA.js} +1 -1
- package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
- package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
- package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
- package/dist/cli-delegate/cmd_analyze_session.js +223 -43
- package/dist/cli-delegate/cmd_brand_status.js +3 -2
- package/dist/cli-delegate/cmd_conformance.js +1252 -249
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +19 -9
- package/dist/cli-delegate/cmd_doctor_neighbours.js +30 -0
- package/dist/cli-delegate/cmd_explain.js +45 -21
- package/dist/cli-delegate/cmd_export.js +13 -10
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_git_convention.js +1851 -0
- package/dist/cli-delegate/cmd_handoff.js +44 -22
- package/dist/cli-delegate/cmd_mcp_available.js +3 -2
- package/dist/cli-delegate/cmd_memory_get.js +3 -1
- package/dist/cli-delegate/cmd_migrate.js +3 -3
- package/dist/cli-delegate/cmd_packs_active.js +5 -4
- package/dist/cli-delegate/cmd_preflight.js +6 -6
- package/dist/cli-delegate/cmd_prune.js +14 -11
- package/dist/cli-delegate/cmd_refresh.js +2 -1
- package/dist/cli-delegate/cmd_route_audit.js +10 -8
- package/dist/cli-delegate/cmd_route_explain.js +4 -4
- package/dist/cli-delegate/cmd_session_recycle.js +10 -7
- package/dist/cli-delegate/cmd_settings_check.js +54 -7
- package/dist/cli-delegate/cmd_settings_get.js +18 -8
- package/dist/cli-delegate/cmd_settings_migrate.js +13 -10
- package/dist/cli-delegate/cmd_settings_set.js +4 -4
- package/dist/cli-delegate/cmd_sync.js +14 -11
- package/dist/cli-delegate/cmd_uninstall.js +15 -12
- package/dist/cli-delegate/cmd_update.js +7 -7
- package/dist/cli-delegate/cmd_upgrade.js +9 -8
- package/dist/cli-delegate/cmd_validate.js +15 -12
- package/dist/cli-delegate/cmd_versions.js +5 -5
- package/dist/cli-delegate/deferral_carry.js +16 -0
- package/dist/cli-delegate/gate_budget.js +1 -1
- package/dist/cli-delegate/gate_execute.js +3 -3
- package/dist/cli-delegate/roadmap_gates.js +6 -6
- package/dist/cli-delegate/update_roadmap_progress.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +232 -141
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +26 -9
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +7 -4
- package/dist/hooks/dispatch.js +5655 -6623
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/install/claudePathsPlan.js +47 -6
- package/dist/install/claudeRuleRewrite.js +7 -0
- package/dist/install/emit_host_rules_cli.js +39 -36
- package/dist/install/globalRuleScope.js +87 -0
- package/dist/install/host_rule_ownership.js +160 -0
- package/dist/install/install.mjs +2336 -1249
- package/dist/install/installThinLayer.js +289 -0
- package/dist/install/installedRuleLinks.js +262 -0
- package/dist/install/wizard-plan.js +24 -0
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
- package/dist/mcp/registry-manifest.json +5 -5
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +36504 -30986
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +26 -120
- package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
- package/dist/scripts/_lib/compile_time_toggles.js +12 -21
- package/dist/scripts/_lib/git_convention.js +232 -0
- package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
- package/dist/scripts/_lib/installed_layer.js +704 -0
- package/dist/scripts/_lib/lean_projection_mode.js +218 -15
- package/dist/scripts/_lib/package_root.js +68 -0
- package/dist/scripts/_lib/rule_consequence_class.js +45 -0
- package/dist/scripts/_lib/rule_injection.js +67 -10
- package/dist/scripts/_lib/rule_law_section.js +122 -0
- package/dist/scripts/_lib/settings_removed_keys.js +168 -0
- package/dist/scripts/_lib/thin_rules.js +535 -0
- package/dist/scripts/_lib/windsurf_render.js +60 -0
- package/dist/scripts/condense.js +14 -26
- package/dist/scripts/project_thin_rules.js +14 -294
- package/dist/server/app.js +2 -1
- package/dist/server/gitKeysGate.js +105 -0
- package/dist/server/routes/settings.js +67 -8
- package/dist/server/routes/wizard.js +4 -0
- package/dist/server/schemas/settings.js +29 -81
- package/dist/shared/skillRanking.js +103 -16
- package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +72 -1
- package/docs/contracts/settings-classes.md +39 -67
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
- package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
- package/docs/guidelines/agent-infra/layered-settings.md +13 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
- package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
- package/docs/guidelines/php/git.md +15 -2
- package/package.json +1 -1
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/src/agent-src/scripts/deferral_carry.ts +339 -0
- package/src/agent-src/scripts/gate_budget.ts +47 -23
- package/src/agent-src/scripts/gate_execute.ts +12 -4
- package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/src/agent-src/templates/AGENTS.md +1 -1
- package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
- package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
- package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
- package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/src/config/agent-settings.template.yml +141 -334
- package/src/config/agents-paths.yml +16 -0
- package/src/config/assurance-capability-registry.json +7 -3
- package/src/config/ci-local-parity.yml +3 -0
- package/src/config/continuity-surface.json +10 -3
- package/src/config/discovery/packs.yml +17 -1
- package/src/config/evaluator-budgets.json +23 -10
- package/src/config/gate-coverage.yml +138 -3
- package/src/config/gate-violation-baselines.json +64 -16
- package/src/config/gitignore-block.txt +19 -0
- package/src/config/hook-bundle-budget.json +25 -0
- package/src/config/hook-token-budget.json +6 -1
- package/src/config/host-instruction-limits.json +33 -0
- package/src/config/release-gate-locality.yml +2 -1
- package/src/config/routing-coverage-seed.json +67 -4
- package/src/config/rule-activation-census.json +7 -3
- package/src/config/rule-consequence-class.json +161 -0
- package/src/config/rule-law-ceilings.json +105 -0
- package/src/config/rule-obligations.json +833 -0
- package/src/install/claudePathsPlan.ts +46 -4
- package/src/install/claudeRuleRewrite.ts +10 -1
- package/src/install/emit_host_rules_cli.ts +43 -34
- package/src/install/globalRuleScope.ts +109 -0
- package/src/install/host_rule_ownership.ts +170 -0
- package/src/install/installThinLayer.ts +378 -0
- package/src/install/installedRuleLinks.ts +308 -0
- package/src/install/wizard-plan.ts +24 -0
- package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
- package/src/scripts/_cli/cmd_conformance.ts +13 -2
- package/src/scripts/_cli/cmd_doctor.ts +33 -81
- package/src/scripts/_cli/cmd_doctor_neighbours.ts +426 -0
- package/src/scripts/_cli/cmd_explain.ts +72 -14
- package/src/scripts/_cli/cmd_git_convention.ts +637 -0
- package/src/scripts/_cli/cmd_settings_check.ts +66 -8
- package/src/scripts/_cli/cmd_settings_get.ts +18 -3
- package/src/scripts/_cli/doctor_execution.ts +72 -1
- package/src/scripts/_dispatch.bash +53 -4
- package/src/scripts/_lib/agent_settings.ts +26 -124
- package/src/scripts/_lib/blocked_by_marker.ts +1 -1
- package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
- package/src/scripts/_lib/compile_time_toggles.ts +12 -21
- package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
- package/src/scripts/_lib/estate_offsets.ts +241 -0
- package/src/scripts/_lib/exemption_shape.ts +143 -0
- package/src/scripts/_lib/fnv.ts +23 -0
- package/src/scripts/_lib/foreign_scan.ts +106 -0
- package/src/scripts/_lib/git_base_ref.ts +92 -0
- package/src/scripts/_lib/git_convention.ts +291 -0
- package/src/scripts/_lib/git_convention_carrier.ts +389 -0
- package/src/scripts/_lib/git_convention_grammar.ts +246 -0
- package/src/scripts/_lib/git_convention_measure.ts +344 -0
- package/src/scripts/_lib/gitignore_block.ts +314 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +106 -0
- package/src/scripts/_lib/graph_feeder_record.ts +437 -0
- package/src/scripts/_lib/hook_settings.ts +73 -0
- package/src/scripts/_lib/host_capability.ts +40 -19
- package/src/scripts/_lib/host_hook_merge.ts +165 -0
- package/src/scripts/_lib/installed_layer.ts +963 -0
- package/src/scripts/_lib/json_merge.ts +82 -0
- package/src/scripts/_lib/json_pointers.ts +93 -11
- package/src/scripts/_lib/knowledge_global.ts +14 -1
- package/src/scripts/_lib/lean_projection_mode.ts +275 -15
- package/src/scripts/_lib/machine_wake.ts +16 -3
- package/src/scripts/_lib/module_reach.ts +456 -0
- package/src/scripts/_lib/neighbour_census.ts +760 -0
- package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
- package/src/scripts/_lib/neighbour_scan.ts +122 -0
- package/src/scripts/_lib/neighbour_tool_use.ts +187 -0
- package/src/scripts/_lib/prompt_shape.ts +46 -0
- package/src/scripts/_lib/ratification_artifact.ts +220 -1
- package/src/scripts/_lib/ratification_subject.ts +92 -0
- package/src/scripts/_lib/release_findings_ingest.ts +15 -7
- package/src/scripts/_lib/release_highlights.ts +5 -0
- package/src/scripts/_lib/release_migration_gate.ts +19 -3
- package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
- package/src/scripts/_lib/review_coverage.ts +134 -0
- package/src/scripts/_lib/rule_consequence_class.ts +71 -0
- package/src/scripts/_lib/rule_injection.ts +130 -10
- package/src/scripts/_lib/rule_law_section.ts +147 -0
- package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
- package/src/scripts/_lib/rule_obligations.ts +205 -0
- package/src/scripts/_lib/self_repair.ts +1 -1
- package/src/scripts/_lib/settings_removed_keys.ts +173 -0
- package/src/scripts/_lib/skill_origin.ts +254 -0
- package/src/scripts/_lib/structured_ask.ts +64 -21
- package/src/scripts/_lib/test_red_state.ts +5 -0
- package/src/scripts/_lib/thin_rules.ts +620 -0
- package/src/scripts/_lib/touched_file_quality.ts +570 -0
- package/src/scripts/_lib/turn_end_refusals.ts +77 -2
- package/src/scripts/_lib/windsurf_render.ts +63 -0
- package/src/scripts/_lib/worker_budget.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +16 -1
- package/src/scripts/ai_council/cli_call_budget.ts +13 -5
- package/src/scripts/ai_council/clients.ts +26 -57
- package/src/scripts/ai_council/config.ts +8 -8
- package/src/scripts/ai_council/modification_review.ts +100 -0
- package/src/scripts/ai_council/modification_review_questions.ts +90 -0
- package/src/scripts/ai_council/orchestrator.ts +5 -5
- package/src/scripts/ai_council/spend_gate.ts +18 -7
- package/src/scripts/ai_council/vendor_defaults.ts +45 -0
- package/src/scripts/ai_team/config.ts +11 -16
- package/src/scripts/audit_skill_overlap.ts +261 -0
- package/src/scripts/audit_user_type_axis.ts +20 -8
- package/src/scripts/before_complete_hook.ts +243 -12
- package/src/scripts/bench_ab_clone.ts +1 -2
- package/src/scripts/bench_concern_spawn_path.ts +129 -0
- package/src/scripts/bench_graph_feeder_latency.ts +584 -0
- package/src/scripts/bench_touched_file_quality.ts +238 -0
- package/src/scripts/check_agent_artifact_location.ts +36 -0
- package/src/scripts/check_branch_freshness.ts +147 -24
- package/src/scripts/check_enforcement_coverage.ts +130 -0
- package/src/scripts/check_enforcement_matrix.ts +377 -20
- package/src/scripts/check_estate_count.ts +130 -153
- package/src/scripts/check_evaluator_budgets.ts +4 -0
- package/src/scripts/check_finding_dispositions.ts +196 -21
- package/src/scripts/check_gate_coverage.ts +4 -3
- package/src/scripts/check_gate_reachability.ts +48 -1
- package/src/scripts/check_generator_sync.ts +48 -0
- package/src/scripts/check_hook_bundle_composition.ts +477 -0
- package/src/scripts/check_kernel_edit_ratified.ts +132 -14
- package/src/scripts/check_memory.ts +7 -1
- package/src/scripts/check_pack_size.ts +1 -1
- package/src/scripts/check_release_highlights.ts +10 -0
- package/src/scripts/check_release_manifest_content.ts +189 -0
- package/src/scripts/check_release_pr_shape.ts +38 -15
- package/src/scripts/check_standing_rule_delivery.ts +129 -13
- package/src/scripts/check_suppression_hygiene.ts +2 -5
- package/src/scripts/check_verify_expectation_delta.ts +521 -0
- package/src/scripts/ci_settle.ts +42 -5
- package/src/scripts/classify_merge_risk.ts +320 -0
- package/src/scripts/closure_scan.ts +91 -1
- package/src/scripts/code_graph/detect.ts +127 -7
- package/src/scripts/code_graph/foreign.ts +194 -0
- package/src/scripts/code_graph/query.ts +217 -4
- package/src/scripts/code_graph/types.ts +26 -2
- package/src/scripts/code_graph/validate.ts +3 -1
- package/src/scripts/code_graph/verbs.ts +103 -0
- package/src/scripts/command_suggester/settings.ts +8 -108
- package/src/scripts/command_suggester/types.ts +4 -5
- package/src/scripts/compile_hook_manifest.ts +33 -1
- package/src/scripts/condense.ts +14 -27
- package/src/scripts/consumer_matrix.ts +102 -0
- package/src/scripts/context_hygiene_hook.ts +13 -23
- package/src/scripts/cost/preflight.mjs +12 -1
- package/src/scripts/council_cli.ts +7 -7
- package/src/scripts/dispatch_r2_reviewer.ts +24 -11
- package/src/scripts/estate_exemption_shape.ts +202 -0
- package/src/scripts/explain_run.ts +8 -13
- package/src/scripts/generate_git_convention_grammar.ts +127 -0
- package/src/scripts/generate_host_cost_table.ts +21 -4
- package/src/scripts/handoff_context_hook.ts +86 -37
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +175 -15
- package/src/scripts/hooks/block_config_weakening.ts +115 -7
- package/src/scripts/hooks/block_plumbing_writes.ts +37 -5
- package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
- package/src/scripts/hooks/concern_failure_policy.ts +280 -0
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
- package/src/scripts/hooks/dispatch_hook.ts +52 -52
- package/src/scripts/hooks/evidence_independence.ts +12 -4
- package/src/scripts/hooks/exit_codes.ts +2 -1
- package/src/scripts/hooks/host_lowering.json +1 -1
- package/src/scripts/hooks/host_lowering.ts +19 -1
- package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
- package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
- package/src/scripts/hooks/payload_stub.ts +10 -1
- package/src/scripts/hooks/push_settle_hook.ts +4 -3
- package/src/scripts/hooks/rule_inject_hook.ts +795 -60
- package/src/scripts/hooks/state_io.ts +8 -4
- package/src/scripts/hooks/table_fingerprint.ts +21 -0
- package/src/scripts/hooks/telemetry_usage_hook.ts +24 -7
- package/src/scripts/hooks/turn_end_gate_hook.ts +85 -0
- package/src/scripts/hooks_status.ts +112 -0
- package/src/scripts/injection_scan_hook.ts +7 -0
- package/src/scripts/install-hooks.sh +42 -14
- package/src/scripts/install.ts +78 -215
- package/src/scripts/installed_layer_report.ts +103 -0
- package/src/scripts/language_mirror_hook.ts +15 -6
- package/src/scripts/learning_sidecar.ts +119 -8
- package/src/scripts/lint_blocker_citations.ts +198 -0
- package/src/scripts/lint_evidence_artifacts.ts +9 -0
- package/src/scripts/lint_hook_concern_budget.ts +10 -21
- package/src/scripts/lint_hook_manifest.ts +53 -0
- package/src/scripts/lint_major_migration_sections.ts +156 -26
- package/src/scripts/lint_pack_boundaries.ts +465 -29
- package/src/scripts/lint_roadmap_blockers.ts +282 -29
- package/src/scripts/lint_roadmap_complexity.ts +4 -2
- package/src/scripts/lint_rule_law_section.ts +647 -0
- package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
- package/src/scripts/lint_settings_classes.ts +1 -1
- package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
- package/src/scripts/lint_workflow_security.ts +173 -6
- package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
- package/src/scripts/mcp_server/graph_tools.ts +72 -3
- package/src/scripts/measure_routing_signal.ts +54 -16
- package/src/scripts/measure_skill_ranker_baseline.ts +221 -8
- package/src/scripts/memory_learn_hook.ts +91 -6
- package/src/scripts/model_rule_injection.ts +55 -8
- package/src/scripts/onboarding_gate_hook.ts +7 -6
- package/src/scripts/print_required_checks.ts +15 -3
- package/src/scripts/probe_host_compliance.ts +33 -5
- package/src/scripts/probe_turnaround.ts +183 -3
- package/src/scripts/project_thin_rules.ts +34 -327
- package/src/scripts/ratification_header.ts +77 -0
- package/src/scripts/refusal_envelope.ts +138 -0
- package/src/scripts/release_publication.ts +29 -3
- package/src/scripts/report_dispatch_import_closure.ts +76 -0
- package/src/scripts/report_evidence_temperature.ts +657 -0
- package/src/scripts/report_installed_rule_links.ts +274 -0
- package/src/scripts/report_label_agreement.ts +233 -0
- package/src/scripts/report_module_reach.ts +212 -0
- package/src/scripts/report_obligation_mechanism.ts +228 -0
- package/src/scripts/report_parked_blockers.ts +222 -0
- package/src/scripts/report_required_checks_drift.ts +196 -0
- package/src/scripts/report_single_token_triggers.ts +277 -0
- package/src/scripts/report_skill_ranker_confusion.ts +543 -0
- package/src/scripts/report_standing_payload_by_host.ts +188 -15
- package/src/scripts/report_verification_record_coverage.ts +306 -0
- package/src/scripts/routing_doctor.ts +2 -2
- package/src/scripts/rule_activation_census.ts +5 -2
- package/src/scripts/rule_trigger_eval.ts +9 -9
- package/src/scripts/schemas/agent-settings.schema.json +17 -31
- package/src/scripts/schemas/command.schema.json +1 -1
- package/src/scripts/schemas/review-findings.schema.json +3 -2
- package/src/scripts/schemas/rule.schema.json +5 -0
- package/src/scripts/schemas/skill.schema.json +1 -1
- package/src/scripts/self_review_gate.ts +101 -9
- package/src/scripts/skill_tools/score_skill_relevance.ts +314 -40
- package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
- package/src/scripts/sync_gitignore.ts +29 -235
- package/src/scripts/sync_pr_branch.ts +403 -132
- package/src/scripts/trigger_eval_grandfather.json +0 -21
- package/src/server/schemas/settings.ts +42 -176
- package/src/shared/skillRanking.ts +169 -14
- package/dist/cli-delegate/chunk-5R7HOLAF.js +0 -99
- package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
- package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
- package/src/scripts/_lib/config_chain.ts +0 -477
- package/src/scripts/_lib/conformance_report.ts +0 -403
- package/src/scripts/_lib/eval_discrimination.ts +0 -95
- package/src/scripts/_lib/evaluator_promotion.ts +0 -225
- package/src/scripts/_lib/file_slicer.ts +0 -117
- package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
- package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
- package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
- package/src/scripts/_lib/role_split.ts +0 -338
|
@@ -2,28 +2,32 @@ import { createRequire as __acCreateRequire } from 'node:module'; const require
|
|
|
2
2
|
import {
|
|
3
3
|
ZodFirstPartyTypeKind,
|
|
4
4
|
settingsSchema
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import {
|
|
7
|
-
main
|
|
8
|
-
} from "./chunk-6KFEC3G7.js";
|
|
5
|
+
} from "./chunk-6SRJTYJS.js";
|
|
9
6
|
import {
|
|
7
|
+
GLOBAL_DEPLOY_SOURCES,
|
|
10
8
|
RULE_SOURCE_REL
|
|
11
9
|
} from "./chunk-WOKWX5PL.js";
|
|
12
10
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "./chunk-YDPILCOL.js";
|
|
11
|
+
main
|
|
12
|
+
} from "./chunk-G5VVIZRC.js";
|
|
16
13
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
absoluteBodyLinkPrefix,
|
|
15
|
+
appendTxLog,
|
|
16
|
+
build_thin,
|
|
17
|
+
ruleBody,
|
|
18
|
+
splitFrontmatter,
|
|
19
|
+
split_frontmatter
|
|
20
|
+
} from "./chunk-6YQC2HLF.js";
|
|
19
21
|
import {
|
|
20
22
|
SCOPE_DETECT_AI_DIRS,
|
|
21
23
|
SCOPE_DETECT_MANIFESTS
|
|
22
24
|
} from "./chunk-A4QJ6ENT.js";
|
|
23
25
|
import {
|
|
26
|
+
INVENTORY_BASENAME,
|
|
24
27
|
build_claude_hook_matrix,
|
|
25
28
|
ensure_managed_hooks,
|
|
26
29
|
expected_deploy_files,
|
|
30
|
+
inventory_path,
|
|
27
31
|
is_ancestor,
|
|
28
32
|
load_inventory,
|
|
29
33
|
printResiduals,
|
|
@@ -31,18 +35,10 @@ import {
|
|
|
31
35
|
reap_stale,
|
|
32
36
|
reap_tagged_orphans,
|
|
33
37
|
record_deploy,
|
|
38
|
+
recorded_absolute_files,
|
|
39
|
+
recorded_rel_files,
|
|
34
40
|
save_inventory
|
|
35
|
-
} from "./chunk-
|
|
36
|
-
import {
|
|
37
|
-
check_version,
|
|
38
|
-
classify_mismatch,
|
|
39
|
-
current_package_version,
|
|
40
|
-
lockfile_path,
|
|
41
|
-
lockfile_write_path,
|
|
42
|
-
migrate_layout,
|
|
43
|
-
read_lockfile,
|
|
44
|
-
write_lockfile
|
|
45
|
-
} from "./chunk-T7L2QK3K.js";
|
|
41
|
+
} from "./chunk-MDPPKQCQ.js";
|
|
46
42
|
import {
|
|
47
43
|
LEGACY_ALL,
|
|
48
44
|
compute_active_pack_ids,
|
|
@@ -56,25 +52,51 @@ import {
|
|
|
56
52
|
ruleScopeFromSettings
|
|
57
53
|
} from "./chunk-DMSZHXZS.js";
|
|
58
54
|
import {
|
|
55
|
+
write_managed_block
|
|
56
|
+
} from "./chunk-ULQRUR23.js";
|
|
57
|
+
import {
|
|
58
|
+
check_version,
|
|
59
|
+
classify_mismatch,
|
|
60
|
+
current_package_version,
|
|
61
|
+
lockfile_path,
|
|
62
|
+
lockfile_write_path,
|
|
63
|
+
migrate_layout,
|
|
64
|
+
read_lockfile,
|
|
65
|
+
write_lockfile
|
|
66
|
+
} from "./chunk-LQOCRFWT.js";
|
|
67
|
+
import {
|
|
68
|
+
HOOK_SIGNATURES,
|
|
69
|
+
deepMerge,
|
|
70
|
+
isManagedEntry,
|
|
71
|
+
isPlainObject,
|
|
72
|
+
jsonEqual,
|
|
73
|
+
mergeHostConfig
|
|
74
|
+
} from "./chunk-DEIV7XP7.js";
|
|
75
|
+
import {
|
|
76
|
+
NO_RECORDED_HASHES,
|
|
59
77
|
ScopeMismatchError,
|
|
78
|
+
classifyOwnership,
|
|
60
79
|
manifest_path,
|
|
80
|
+
readRecordedHashes,
|
|
61
81
|
read_manifest,
|
|
82
|
+
recordedHashesForRoot,
|
|
62
83
|
upsert_tool,
|
|
63
84
|
write_manifest
|
|
64
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-OKJUIAPS.js";
|
|
65
86
|
import {
|
|
66
87
|
require_dist
|
|
67
88
|
} from "./chunk-OY53J6II.js";
|
|
68
89
|
import {
|
|
69
90
|
find_project_root_with_anchor,
|
|
70
91
|
load_agent_settings
|
|
71
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-H76PHZBI.js";
|
|
72
93
|
import {
|
|
94
|
+
DEFAULT_EVENT4U_ROOT_RELATIVE,
|
|
73
95
|
event4u_root,
|
|
74
96
|
legacy_xdg_root,
|
|
75
97
|
migrate_legacy_namespace,
|
|
76
98
|
write_target
|
|
77
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-T6BP34WI.js";
|
|
78
100
|
import {
|
|
79
101
|
__toESM
|
|
80
102
|
} from "./chunk-J55WI3RR.js";
|
|
@@ -181,6 +203,7 @@ function _is_plain_object(value) {
|
|
|
181
203
|
function collect_pointers(overlay, options = {}) {
|
|
182
204
|
const prefix = options.prefix ?? "";
|
|
183
205
|
const include_arrays = options.include_arrays ?? true;
|
|
206
|
+
const entry_signature = options.entry_signature ?? "";
|
|
184
207
|
const entries = [];
|
|
185
208
|
for (const [key, value] of Object.entries(overlay)) {
|
|
186
209
|
const pointer = `${prefix}/${_escape_segment(String(key))}`;
|
|
@@ -189,14 +212,26 @@ function collect_pointers(overlay, options = {}) {
|
|
|
189
212
|
entries.push({ json_pointer: pointer, value_hash: null });
|
|
190
213
|
} else {
|
|
191
214
|
entries.push(
|
|
192
|
-
...collect_pointers(value, {
|
|
215
|
+
...collect_pointers(value, {
|
|
216
|
+
prefix: pointer,
|
|
217
|
+
include_arrays,
|
|
218
|
+
entry_signature
|
|
219
|
+
})
|
|
193
220
|
);
|
|
194
221
|
}
|
|
195
222
|
} else if (Array.isArray(value)) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
223
|
+
if (entry_signature !== "" && pointer.startsWith("/hooks/")) {
|
|
224
|
+
entries.push({
|
|
225
|
+
json_pointer: pointer,
|
|
226
|
+
value_hash: null,
|
|
227
|
+
entry_signature
|
|
228
|
+
});
|
|
229
|
+
} else {
|
|
230
|
+
entries.push({
|
|
231
|
+
json_pointer: pointer,
|
|
232
|
+
value_hash: include_arrays ? value_hash(value) : null
|
|
233
|
+
});
|
|
234
|
+
}
|
|
200
235
|
} else {
|
|
201
236
|
entries.push({ json_pointer: pointer, value_hash: null });
|
|
202
237
|
}
|
|
@@ -207,11 +242,14 @@ function collect_pointers(overlay, options = {}) {
|
|
|
207
242
|
return entries;
|
|
208
243
|
}
|
|
209
244
|
function build_merge_entries(file_label, overlay) {
|
|
210
|
-
const pointers = collect_pointers(overlay
|
|
245
|
+
const pointers = collect_pointers(overlay, {
|
|
246
|
+
entry_signature: HOOK_SIGNATURES[file_label] ?? ""
|
|
247
|
+
});
|
|
211
248
|
return pointers.map((entry) => ({
|
|
212
249
|
file: file_label,
|
|
213
250
|
json_pointer: entry.json_pointer,
|
|
214
|
-
value_hash: entry.value_hash
|
|
251
|
+
value_hash: entry.value_hash,
|
|
252
|
+
...entry.entry_signature === void 0 ? {} : { entry_signature: entry.entry_signature }
|
|
215
253
|
}));
|
|
216
254
|
}
|
|
217
255
|
function _split_segments(pointer) {
|
|
@@ -251,7 +289,33 @@ function subtract_pointers(doc, entries) {
|
|
|
251
289
|
continue;
|
|
252
290
|
}
|
|
253
291
|
const [parent, leaf] = nav;
|
|
254
|
-
|
|
292
|
+
const signature = entry.entry_signature ?? "";
|
|
293
|
+
if (signature !== "") {
|
|
294
|
+
const current = parent[leaf];
|
|
295
|
+
if (!Array.isArray(current)) {
|
|
296
|
+
warnings.push({
|
|
297
|
+
pointer,
|
|
298
|
+
reason: "missing",
|
|
299
|
+
expected_hash: null,
|
|
300
|
+
actual_hash: null
|
|
301
|
+
});
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
const kept = current.filter((item) => !isManagedEntry(item, signature));
|
|
305
|
+
if (kept.length === current.length) {
|
|
306
|
+
warnings.push({
|
|
307
|
+
pointer,
|
|
308
|
+
reason: "missing",
|
|
309
|
+
expected_hash: null,
|
|
310
|
+
actual_hash: null
|
|
311
|
+
});
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (kept.length > 0) {
|
|
315
|
+
parent[leaf] = kept;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
} else if (expected !== null) {
|
|
255
319
|
const actual = value_hash(parent[leaf]);
|
|
256
320
|
if (actual !== expected) {
|
|
257
321
|
warnings.push({
|
|
@@ -283,16 +347,44 @@ function subtract_pointers(doc, entries) {
|
|
|
283
347
|
// src/scripts/install.ts
|
|
284
348
|
import { spawn, spawnSync } from "node:child_process";
|
|
285
349
|
import * as crypto5 from "node:crypto";
|
|
286
|
-
import * as
|
|
287
|
-
import * as
|
|
288
|
-
import * as
|
|
350
|
+
import * as fs18 from "node:fs";
|
|
351
|
+
import * as os7 from "node:os";
|
|
352
|
+
import * as path18 from "node:path";
|
|
289
353
|
import process2 from "node:process";
|
|
290
|
-
import { fileURLToPath as
|
|
354
|
+
import { fileURLToPath as fileURLToPath3, pathToFileURL } from "node:url";
|
|
291
355
|
|
|
292
|
-
// src/scripts/_lib/
|
|
293
|
-
var YAML = __toESM(require_dist(), 1);
|
|
356
|
+
// src/scripts/_lib/reserved_name_sweep.ts
|
|
294
357
|
import * as fs from "node:fs";
|
|
295
358
|
import * as path from "node:path";
|
|
359
|
+
function sweepReservedNames(commandsDir, currentFiles, isBuiltinName, recordedFiles) {
|
|
360
|
+
const reserved = [];
|
|
361
|
+
const foreign = [];
|
|
362
|
+
let entries = [];
|
|
363
|
+
try {
|
|
364
|
+
entries = fs.readdirSync(commandsDir).filter((f) => f.endsWith(".md"));
|
|
365
|
+
} catch {
|
|
366
|
+
return { reserved, foreign };
|
|
367
|
+
}
|
|
368
|
+
for (const fname of entries.sort()) {
|
|
369
|
+
const slug = fname.slice(0, -".md".length);
|
|
370
|
+
if (!isBuiltinName(slug)) continue;
|
|
371
|
+
const rel = `commands/${fname}`;
|
|
372
|
+
const ours = currentFiles.has(rel) || recordedFiles.has(rel);
|
|
373
|
+
if (!ours) {
|
|
374
|
+
foreign.push(slug);
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
fs.rmSync(path.join(commandsDir, fname), { force: true });
|
|
378
|
+
currentFiles.delete(rel);
|
|
379
|
+
reserved.push(slug);
|
|
380
|
+
}
|
|
381
|
+
return { reserved, foreign };
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// src/scripts/_lib/host_env_write.ts
|
|
385
|
+
var YAML = __toESM(require_dist(), 1);
|
|
386
|
+
import * as fs2 from "node:fs";
|
|
387
|
+
import * as path2 from "node:path";
|
|
296
388
|
var WRITABLE_HOST_ENV = [
|
|
297
389
|
{ variable: "BASH_MAX_OUTPUT_LENGTH", settingsKey: "bash_max_output_length" },
|
|
298
390
|
{ variable: "MAX_MCP_OUTPUT_TOKENS", settingsKey: "max_mcp_output_tokens" }
|
|
@@ -303,10 +395,10 @@ var SETTINGS_CANDIDATES = [
|
|
|
303
395
|
];
|
|
304
396
|
function readSettingsDoc(projectRoot) {
|
|
305
397
|
for (const parts of SETTINGS_CANDIDATES) {
|
|
306
|
-
const p =
|
|
398
|
+
const p = path2.join(projectRoot, ...parts);
|
|
307
399
|
let text;
|
|
308
400
|
try {
|
|
309
|
-
text =
|
|
401
|
+
text = fs2.readFileSync(p, "utf-8");
|
|
310
402
|
} catch {
|
|
311
403
|
continue;
|
|
312
404
|
}
|
|
@@ -547,8 +639,8 @@ function is_claude_builtin_name(slug) {
|
|
|
547
639
|
}
|
|
548
640
|
|
|
549
641
|
// src/scripts/_lib/mcp_bridge.ts
|
|
550
|
-
import * as
|
|
551
|
-
import * as
|
|
642
|
+
import * as fs3 from "node:fs";
|
|
643
|
+
import * as path3 from "node:path";
|
|
552
644
|
var MCP_SERVER_KEY = "agent-config";
|
|
553
645
|
var MCP_PACKAGE_NAME = "@event4u/agent-config";
|
|
554
646
|
function mcpBridgeEntry(packageRoot) {
|
|
@@ -565,7 +657,7 @@ function mcpBridgeEntry(packageRoot) {
|
|
|
565
657
|
}
|
|
566
658
|
function readPackageVersion(packageRoot) {
|
|
567
659
|
try {
|
|
568
|
-
const raw =
|
|
660
|
+
const raw = fs3.readFileSync(path3.join(packageRoot, "package.json"), "utf-8");
|
|
569
661
|
const v = JSON.parse(raw).version;
|
|
570
662
|
return typeof v === "string" && v.trim() !== "" ? v : null;
|
|
571
663
|
} catch {
|
|
@@ -574,7 +666,7 @@ function readPackageVersion(packageRoot) {
|
|
|
574
666
|
}
|
|
575
667
|
function makeEnsureMcpBridge(mergeJsonFile) {
|
|
576
668
|
return (projectRoot, force, packageRoot = projectRoot) => mergeJsonFile(
|
|
577
|
-
|
|
669
|
+
path3.join(projectRoot, ".mcp.json"),
|
|
578
670
|
mcpBridgeEntry(packageRoot),
|
|
579
671
|
force,
|
|
580
672
|
".mcp.json"
|
|
@@ -600,7 +692,7 @@ function makeEnsureMcpRegistrations(mergeJsonFile) {
|
|
|
600
692
|
const merged = {};
|
|
601
693
|
for (const t of targets) {
|
|
602
694
|
merged[t.toolId] = mergeJsonFile(
|
|
603
|
-
|
|
695
|
+
path3.join(projectRoot, ...t.relPath.split("/")),
|
|
604
696
|
mcpBridgeEntry(packageRoot),
|
|
605
697
|
force,
|
|
606
698
|
t.relPath
|
|
@@ -631,10 +723,10 @@ function projectionModeOf(raw) {
|
|
|
631
723
|
return raw === "scoped" ? "scoped" : raw === "tiered" ? "tiered" : "legacy-all";
|
|
632
724
|
}
|
|
633
725
|
function resolveTierB(packageRoot) {
|
|
634
|
-
const p =
|
|
635
|
-
if (!
|
|
726
|
+
const p = path3.join(packageRoot, "agents", "runtime", "state", "skill-tiers.json");
|
|
727
|
+
if (!fs3.existsSync(p)) return null;
|
|
636
728
|
try {
|
|
637
|
-
const parsed = JSON.parse(
|
|
729
|
+
const parsed = JSON.parse(fs3.readFileSync(p, "utf-8"));
|
|
638
730
|
if (!Array.isArray(parsed.tier_b)) return null;
|
|
639
731
|
return new Set(parsed.tier_b.filter((n) => typeof n === "string"));
|
|
640
732
|
} catch {
|
|
@@ -642,7 +734,7 @@ function resolveTierB(packageRoot) {
|
|
|
642
734
|
}
|
|
643
735
|
}
|
|
644
736
|
function tierBPrunePredicate(tierB) {
|
|
645
|
-
return (mdPath) => tierB.has(
|
|
737
|
+
return (mdPath) => tierB.has(path3.basename(path3.dirname(mdPath)));
|
|
646
738
|
}
|
|
647
739
|
function tierBAdvisory(packageRoot) {
|
|
648
740
|
const tierB = resolveTierB(packageRoot);
|
|
@@ -671,35 +763,35 @@ function applyTieredPrune(deployResults, packageRoot, pruneBy) {
|
|
|
671
763
|
|
|
672
764
|
// src/install/conflictTracker.ts
|
|
673
765
|
import * as crypto2 from "node:crypto";
|
|
674
|
-
import * as
|
|
675
|
-
import * as
|
|
766
|
+
import * as fs5 from "node:fs";
|
|
767
|
+
import * as path5 from "node:path";
|
|
676
768
|
|
|
677
769
|
// src/install/fsPrimitives.ts
|
|
678
770
|
import * as crypto from "node:crypto";
|
|
679
|
-
import * as
|
|
680
|
-
import * as
|
|
771
|
+
import * as fs4 from "node:fs";
|
|
772
|
+
import * as path4 from "node:path";
|
|
681
773
|
function resolvePath(p) {
|
|
682
774
|
try {
|
|
683
|
-
return
|
|
775
|
+
return fs4.realpathSync(path4.resolve(p));
|
|
684
776
|
} catch {
|
|
685
|
-
return
|
|
777
|
+
return path4.resolve(p);
|
|
686
778
|
}
|
|
687
779
|
}
|
|
688
780
|
function pathExists(p) {
|
|
689
781
|
try {
|
|
690
|
-
|
|
782
|
+
fs4.statSync(p);
|
|
691
783
|
return true;
|
|
692
784
|
} catch {
|
|
693
785
|
return false;
|
|
694
786
|
}
|
|
695
787
|
}
|
|
696
788
|
function mkdirp(p) {
|
|
697
|
-
|
|
789
|
+
fs4.mkdirSync(p, { recursive: true });
|
|
698
790
|
}
|
|
699
791
|
function sha256OfFile(p) {
|
|
700
792
|
let data;
|
|
701
793
|
try {
|
|
702
|
-
data =
|
|
794
|
+
data = fs4.readFileSync(p);
|
|
703
795
|
} catch {
|
|
704
796
|
return null;
|
|
705
797
|
}
|
|
@@ -740,20 +832,20 @@ function createConflictTracker(host) {
|
|
|
740
832
|
function recordedHashFor(target) {
|
|
741
833
|
if (conflictState.root === null) return void 0;
|
|
742
834
|
conflictState.recorded ??= recordedHashesForRoot(conflictState.root);
|
|
743
|
-
const plain =
|
|
835
|
+
const plain = path5.resolve(target);
|
|
744
836
|
if (conflictState.recorded.has(plain)) return conflictState.recorded.get(plain);
|
|
745
837
|
const real = resolvePath(target);
|
|
746
838
|
return real === plain ? void 0 : conflictState.recorded.get(real);
|
|
747
839
|
}
|
|
748
840
|
function stageInto(target, sidecar, produce) {
|
|
749
|
-
mkdirp(
|
|
750
|
-
const tmp =
|
|
751
|
-
|
|
752
|
-
`.${
|
|
841
|
+
mkdirp(path5.dirname(sidecar));
|
|
842
|
+
const tmp = path5.join(
|
|
843
|
+
path5.dirname(sidecar),
|
|
844
|
+
`.${path5.basename(sidecar)}.${process.pid}.${crypto2.randomBytes(6).toString("hex")}${path5.extname(target)}`
|
|
753
845
|
);
|
|
754
846
|
const discard = () => {
|
|
755
847
|
try {
|
|
756
|
-
|
|
848
|
+
fs5.unlinkSync(tmp);
|
|
757
849
|
} catch {
|
|
758
850
|
}
|
|
759
851
|
};
|
|
@@ -780,7 +872,7 @@ function createConflictTracker(host) {
|
|
|
780
872
|
}
|
|
781
873
|
}
|
|
782
874
|
try {
|
|
783
|
-
|
|
875
|
+
fs5.renameSync(tmp, sidecar);
|
|
784
876
|
} catch (exc) {
|
|
785
877
|
discard();
|
|
786
878
|
host.fail(
|
|
@@ -829,7 +921,7 @@ function createConflictTracker(host) {
|
|
|
829
921
|
preserve(target, source, packageRoot) {
|
|
830
922
|
const sidecar = sidecarPathFor(target);
|
|
831
923
|
stageInto(target, sidecar, (tmp) => {
|
|
832
|
-
|
|
924
|
+
fs5.copyFileSync(source, tmp);
|
|
833
925
|
host.tagDeployed(tmp, source, packageRoot);
|
|
834
926
|
});
|
|
835
927
|
record(target, sidecar);
|
|
@@ -845,7 +937,7 @@ function createConflictTracker(host) {
|
|
|
845
937
|
*/
|
|
846
938
|
preserveContent(target, content) {
|
|
847
939
|
const sidecar = sidecarPathFor(target);
|
|
848
|
-
stageInto(target, sidecar, (tmp) =>
|
|
940
|
+
stageInto(target, sidecar, (tmp) => fs5.writeFileSync(tmp, content, "utf-8"));
|
|
849
941
|
record(target, sidecar);
|
|
850
942
|
},
|
|
851
943
|
/**
|
|
@@ -867,7 +959,7 @@ function createConflictTracker(host) {
|
|
|
867
959
|
var YAML2 = __toESM(require_dist(), 1);
|
|
868
960
|
import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
|
|
869
961
|
import { homedir } from "node:os";
|
|
870
|
-
import { isAbsolute, join as
|
|
962
|
+
import { isAbsolute, join as join5, resolve as resolve3 } from "node:path";
|
|
871
963
|
function fileEntry(p, kind, hashContent) {
|
|
872
964
|
return { path: p, kind, sha256: hashContent ? sha256OfFile(p) : null };
|
|
873
965
|
}
|
|
@@ -890,7 +982,7 @@ function filesByToolFromBridges(tools, projectRoot, scope, bridgeMarker) {
|
|
|
890
982
|
for (const toolId of [...tools].sort()) {
|
|
891
983
|
const marker = bridgeMarker(toolId, scope);
|
|
892
984
|
if (!marker) continue;
|
|
893
|
-
const markerPath = isAbsolute(marker) ? marker :
|
|
985
|
+
const markerPath = isAbsolute(marker) ? marker : join5(projectRoot, marker);
|
|
894
986
|
out[toolId] = [fileEntry(markerPath, "bridge", false)];
|
|
895
987
|
}
|
|
896
988
|
return out;
|
|
@@ -898,7 +990,7 @@ function filesByToolFromBridges(tools, projectRoot, scope, bridgeMarker) {
|
|
|
898
990
|
function expanduser(p) {
|
|
899
991
|
if (p === "~") return homedir();
|
|
900
992
|
if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
|
|
901
|
-
return
|
|
993
|
+
return join5(homedir(), p.slice(2));
|
|
902
994
|
}
|
|
903
995
|
return p;
|
|
904
996
|
}
|
|
@@ -990,8 +1082,9 @@ function preservedIndex(preservedTargets, staged) {
|
|
|
990
1082
|
}
|
|
991
1083
|
|
|
992
1084
|
// src/scripts/_lib/rule_layer_overlap.ts
|
|
993
|
-
import * as
|
|
994
|
-
import * as
|
|
1085
|
+
import * as fs6 from "node:fs";
|
|
1086
|
+
import * as os from "node:os";
|
|
1087
|
+
import * as path6 from "node:path";
|
|
995
1088
|
var INSTALLER_PROVENANCE_KEYS = ["package", "source_path"];
|
|
996
1089
|
function stripProvenance(text) {
|
|
997
1090
|
const lines = text.split("\n");
|
|
@@ -1042,17 +1135,23 @@ function compareLayers(global_layer, project_layer) {
|
|
|
1042
1135
|
redundant_chars
|
|
1043
1136
|
};
|
|
1044
1137
|
}
|
|
1138
|
+
function hostRuleLayerDirs(projectRoot) {
|
|
1139
|
+
return [
|
|
1140
|
+
path6.join(os.homedir(), ".claude", "rules"),
|
|
1141
|
+
path6.join(projectRoot, ".claude", "rules")
|
|
1142
|
+
];
|
|
1143
|
+
}
|
|
1045
1144
|
function readRuleLayer(dir) {
|
|
1046
1145
|
let names;
|
|
1047
1146
|
try {
|
|
1048
|
-
names =
|
|
1147
|
+
names = fs6.readdirSync(dir);
|
|
1049
1148
|
} catch {
|
|
1050
1149
|
return null;
|
|
1051
1150
|
}
|
|
1052
1151
|
const files = /* @__PURE__ */ new Map();
|
|
1053
1152
|
for (const name of names.filter((n) => n.endsWith(".md")).sort()) {
|
|
1054
1153
|
try {
|
|
1055
|
-
files.set(name,
|
|
1154
|
+
files.set(name, fs6.readFileSync(path6.join(dir, name), "utf-8"));
|
|
1056
1155
|
} catch {
|
|
1057
1156
|
continue;
|
|
1058
1157
|
}
|
|
@@ -1060,7 +1159,7 @@ function readRuleLayer(dir) {
|
|
|
1060
1159
|
return { dir, files };
|
|
1061
1160
|
}
|
|
1062
1161
|
function claudeMdExcludesGlob(dir) {
|
|
1063
|
-
return `${
|
|
1162
|
+
return `${path6.resolve(dir).replace(/\/+$/, "")}/**`;
|
|
1064
1163
|
}
|
|
1065
1164
|
function mergeClaudeMdExcludes(existing, entry) {
|
|
1066
1165
|
if (!Array.isArray(existing)) return [entry];
|
|
@@ -1091,25 +1190,25 @@ function decideLayerAction(report, choice, global_dir, project_dir) {
|
|
|
1091
1190
|
// src/scripts/_lib/install_drift.ts
|
|
1092
1191
|
var import_yaml = __toESM(require_dist(), 1);
|
|
1093
1192
|
import * as crypto3 from "node:crypto";
|
|
1094
|
-
import * as
|
|
1095
|
-
import * as
|
|
1096
|
-
import * as
|
|
1193
|
+
import * as fs7 from "node:fs";
|
|
1194
|
+
import * as os2 from "node:os";
|
|
1195
|
+
import * as path7 from "node:path";
|
|
1097
1196
|
function expanduser2(p) {
|
|
1098
1197
|
if (p === "~") {
|
|
1099
|
-
return
|
|
1198
|
+
return os2.homedir();
|
|
1100
1199
|
}
|
|
1101
1200
|
if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
|
|
1102
|
-
return
|
|
1201
|
+
return path7.join(os2.homedir(), p.slice(2));
|
|
1103
1202
|
}
|
|
1104
1203
|
return p;
|
|
1105
1204
|
}
|
|
1106
1205
|
function resolve_entry_path(project_root, raw) {
|
|
1107
1206
|
const p = expanduser2(raw);
|
|
1108
|
-
return
|
|
1207
|
+
return path7.isAbsolute(p) ? p : path7.join(project_root, p);
|
|
1109
1208
|
}
|
|
1110
1209
|
function sha256_of_file(p) {
|
|
1111
1210
|
try {
|
|
1112
|
-
return crypto3.createHash("sha256").update(
|
|
1211
|
+
return crypto3.createHash("sha256").update(fs7.readFileSync(p)).digest("hex");
|
|
1113
1212
|
} catch {
|
|
1114
1213
|
return null;
|
|
1115
1214
|
}
|
|
@@ -1118,7 +1217,7 @@ function collect_drift(project_root, env) {
|
|
|
1118
1217
|
const target = manifest_path(project_root, env);
|
|
1119
1218
|
let text;
|
|
1120
1219
|
try {
|
|
1121
|
-
text =
|
|
1220
|
+
text = fs7.readFileSync(target, "utf-8");
|
|
1122
1221
|
} catch {
|
|
1123
1222
|
return null;
|
|
1124
1223
|
}
|
|
@@ -1163,7 +1262,7 @@ function collect_drift(project_root, env) {
|
|
|
1163
1262
|
continue;
|
|
1164
1263
|
}
|
|
1165
1264
|
const resolved = resolve_entry_path(project_root, raw_path);
|
|
1166
|
-
if (!
|
|
1265
|
+
if (!fs7.existsSync(resolved)) {
|
|
1167
1266
|
out.push({
|
|
1168
1267
|
tool_id,
|
|
1169
1268
|
path: resolved,
|
|
@@ -1216,15 +1315,15 @@ function format_drift_report(entries) {
|
|
|
1216
1315
|
}
|
|
1217
1316
|
|
|
1218
1317
|
// src/scripts/_lib/skill_catalogue.ts
|
|
1219
|
-
import * as
|
|
1220
|
-
import * as
|
|
1318
|
+
import * as fs8 from "node:fs";
|
|
1319
|
+
import * as path8 from "node:path";
|
|
1221
1320
|
var PROJECT_CATALOGUE_ROOTS = ["src/skills", ".claude/skills"];
|
|
1222
1321
|
var HOST_CATALOGUE_ROOT = ".claude/skills";
|
|
1223
1322
|
var DEFAULT_CATALOGUE_ROOTS = [
|
|
1224
1323
|
...PROJECT_CATALOGUE_ROOTS,
|
|
1225
1324
|
`~/${HOST_CATALOGUE_ROOT}`
|
|
1226
1325
|
];
|
|
1227
|
-
var OBSERVATION_LOG =
|
|
1326
|
+
var OBSERVATION_LOG = path8.join(
|
|
1228
1327
|
"agents",
|
|
1229
1328
|
"evidence",
|
|
1230
1329
|
"metrics",
|
|
@@ -1268,9 +1367,9 @@ function descriptionOf(frontmatter) {
|
|
|
1268
1367
|
return "";
|
|
1269
1368
|
}
|
|
1270
1369
|
function readProjectedCatalogue(root) {
|
|
1271
|
-
const names =
|
|
1370
|
+
const names = fs8.readdirSync(root).filter((n) => fs8.existsSync(path8.join(root, n, "SKILL.md"))).sort();
|
|
1272
1371
|
return names.map((name, index) => {
|
|
1273
|
-
const content =
|
|
1372
|
+
const content = fs8.readFileSync(path8.join(root, name, "SKILL.md"), "utf-8");
|
|
1274
1373
|
const frontmatter = frontmatterOf(content);
|
|
1275
1374
|
const description = descriptionOf(frontmatter);
|
|
1276
1375
|
return {
|
|
@@ -1287,12 +1386,12 @@ function truncationModeOf(record) {
|
|
|
1287
1386
|
return record.truncation_mode ?? "per-entry";
|
|
1288
1387
|
}
|
|
1289
1388
|
function markdownFilesUnder(root) {
|
|
1290
|
-
if (!
|
|
1389
|
+
if (!fs8.existsSync(root)) return [];
|
|
1291
1390
|
const out = [];
|
|
1292
1391
|
const walk = (dir) => {
|
|
1293
|
-
for (const entry of
|
|
1294
|
-
const full =
|
|
1295
|
-
if (
|
|
1392
|
+
for (const entry of fs8.readdirSync(dir, { withFileTypes: true })) {
|
|
1393
|
+
const full = path8.join(dir, entry.name);
|
|
1394
|
+
if (fs8.statSync(full).isDirectory()) walk(full);
|
|
1296
1395
|
else if (entry.name.endsWith(".md")) out.push(full);
|
|
1297
1396
|
}
|
|
1298
1397
|
};
|
|
@@ -1300,9 +1399,9 @@ function markdownFilesUnder(root) {
|
|
|
1300
1399
|
return out;
|
|
1301
1400
|
}
|
|
1302
1401
|
function measureCatalogueVolume(host, root) {
|
|
1303
|
-
const skillsRoot =
|
|
1304
|
-
const skills =
|
|
1305
|
-
const commandEntries = markdownFilesUnder(
|
|
1402
|
+
const skillsRoot = path8.join(root, "skills");
|
|
1403
|
+
const skills = fs8.existsSync(skillsRoot) ? readProjectedCatalogue(skillsRoot) : [];
|
|
1404
|
+
const commandEntries = markdownFilesUnder(path8.join(root, "commands")).length;
|
|
1306
1405
|
return {
|
|
1307
1406
|
host,
|
|
1308
1407
|
root,
|
|
@@ -1380,9 +1479,9 @@ function migrationPromptLines(host, eligibility, settingsPath) {
|
|
|
1380
1479
|
];
|
|
1381
1480
|
}
|
|
1382
1481
|
function readObservationLog(logPath) {
|
|
1383
|
-
if (!
|
|
1482
|
+
if (!fs8.existsSync(logPath)) return [];
|
|
1384
1483
|
const out = [];
|
|
1385
|
-
for (const line of
|
|
1484
|
+
for (const line of fs8.readFileSync(logPath, "utf-8").split("\n")) {
|
|
1386
1485
|
const trimmed = line.trim();
|
|
1387
1486
|
if (trimmed.length === 0) continue;
|
|
1388
1487
|
try {
|
|
@@ -1423,8 +1522,8 @@ function isInteractiveSession(probe) {
|
|
|
1423
1522
|
|
|
1424
1523
|
// src/scripts/_lib/claude_desktop_bundler.ts
|
|
1425
1524
|
import * as crypto4 from "node:crypto";
|
|
1426
|
-
import * as
|
|
1427
|
-
import * as
|
|
1525
|
+
import * as fs9 from "node:fs";
|
|
1526
|
+
import * as path9 from "node:path";
|
|
1428
1527
|
|
|
1429
1528
|
// src/scripts/_lib/zip_min.ts
|
|
1430
1529
|
import * as zlib from "node:zlib";
|
|
@@ -1531,7 +1630,7 @@ function _is_excluded(rel_parts) {
|
|
|
1531
1630
|
}
|
|
1532
1631
|
function _is_dir(p) {
|
|
1533
1632
|
try {
|
|
1534
|
-
return
|
|
1633
|
+
return fs9.statSync(p).isDirectory();
|
|
1535
1634
|
} catch {
|
|
1536
1635
|
return false;
|
|
1537
1636
|
}
|
|
@@ -1543,12 +1642,12 @@ function _compare_rel_parts(a, b) {
|
|
|
1543
1642
|
}
|
|
1544
1643
|
function _walk_skill_files(skill_dir) {
|
|
1545
1644
|
const out = [];
|
|
1546
|
-
const resolved =
|
|
1645
|
+
const resolved = fs9.realpathSync(skill_dir);
|
|
1547
1646
|
const walk = (root, relRoot) => {
|
|
1548
1647
|
const dirNames = [];
|
|
1549
1648
|
const fileNames = [];
|
|
1550
|
-
for (const dirent of
|
|
1551
|
-
const full =
|
|
1649
|
+
for (const dirent of fs9.readdirSync(root, { withFileTypes: true })) {
|
|
1650
|
+
const full = path9.join(root, dirent.name);
|
|
1552
1651
|
const isDir2 = dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full);
|
|
1553
1652
|
if (isDir2) {
|
|
1554
1653
|
dirNames.push(dirent.name);
|
|
@@ -1561,13 +1660,13 @@ function _walk_skill_files(skill_dir) {
|
|
|
1561
1660
|
if (_is_excluded(rel_parts)) {
|
|
1562
1661
|
continue;
|
|
1563
1662
|
}
|
|
1564
|
-
out.push([
|
|
1663
|
+
out.push([path9.join(root, fname), rel_parts]);
|
|
1565
1664
|
}
|
|
1566
1665
|
for (const dname of dirNames) {
|
|
1567
1666
|
if (_is_excluded([dname])) {
|
|
1568
1667
|
continue;
|
|
1569
1668
|
}
|
|
1570
|
-
walk(
|
|
1669
|
+
walk(path9.join(root, dname), [...relRoot, dname]);
|
|
1571
1670
|
}
|
|
1572
1671
|
};
|
|
1573
1672
|
walk(resolved, []);
|
|
@@ -1580,53 +1679,53 @@ function _manifest_digest(files) {
|
|
|
1580
1679
|
const rel = rel_parts.join("/");
|
|
1581
1680
|
h.update(Buffer.from(rel, "utf-8"));
|
|
1582
1681
|
h.update(Buffer.from([0]));
|
|
1583
|
-
h.update(crypto4.createHash("sha256").update(
|
|
1682
|
+
h.update(crypto4.createHash("sha256").update(fs9.readFileSync(abs_path)).digest());
|
|
1584
1683
|
h.update(Buffer.from([0]));
|
|
1585
1684
|
}
|
|
1586
1685
|
return h.digest("hex");
|
|
1587
1686
|
}
|
|
1588
1687
|
function _atomic_write_zip(zip_path, files) {
|
|
1589
|
-
|
|
1590
|
-
const stem =
|
|
1591
|
-
const tmp_path =
|
|
1592
|
-
|
|
1688
|
+
fs9.mkdirSync(path9.dirname(zip_path), { recursive: true });
|
|
1689
|
+
const stem = path9.basename(zip_path, path9.extname(zip_path));
|
|
1690
|
+
const tmp_path = path9.join(
|
|
1691
|
+
path9.dirname(zip_path),
|
|
1593
1692
|
`.${stem}.${crypto4.randomBytes(6).toString("hex")}.zip.tmp`
|
|
1594
1693
|
);
|
|
1595
1694
|
try {
|
|
1596
1695
|
const entries = files.map(([abs_path, rel_parts]) => ({
|
|
1597
1696
|
name: rel_parts.join("/"),
|
|
1598
|
-
data:
|
|
1697
|
+
data: fs9.readFileSync(abs_path)
|
|
1599
1698
|
}));
|
|
1600
|
-
|
|
1601
|
-
|
|
1699
|
+
fs9.writeFileSync(tmp_path, zip_write_sync(entries));
|
|
1700
|
+
fs9.renameSync(tmp_path, zip_path);
|
|
1602
1701
|
} finally {
|
|
1603
|
-
if (
|
|
1604
|
-
|
|
1702
|
+
if (fs9.existsSync(tmp_path)) {
|
|
1703
|
+
fs9.unlinkSync(tmp_path);
|
|
1605
1704
|
}
|
|
1606
1705
|
}
|
|
1607
1706
|
}
|
|
1608
1707
|
function _write_if_changed(dest_dir, slug, files, force, written) {
|
|
1609
1708
|
const digest = _manifest_digest(files);
|
|
1610
|
-
const zip_path =
|
|
1611
|
-
const digest_path =
|
|
1612
|
-
const recorded =
|
|
1613
|
-
if (!force && recorded === digest &&
|
|
1709
|
+
const zip_path = path9.join(dest_dir, `${slug}.zip`);
|
|
1710
|
+
const digest_path = path9.join(dest_dir, `${slug}.sha256`);
|
|
1711
|
+
const recorded = fs9.existsSync(digest_path) ? fs9.readFileSync(digest_path, "utf-8").trim() : "";
|
|
1712
|
+
if (!force && recorded === digest && fs9.existsSync(zip_path)) {
|
|
1614
1713
|
return;
|
|
1615
1714
|
}
|
|
1616
1715
|
_atomic_write_zip(zip_path, files);
|
|
1617
|
-
|
|
1716
|
+
fs9.writeFileSync(digest_path, digest + "\n", "utf-8");
|
|
1618
1717
|
written.push(zip_path);
|
|
1619
1718
|
}
|
|
1620
1719
|
function build_skill_bundles(package_root, dest_dir, force = false, curation = null) {
|
|
1621
|
-
const skills_root =
|
|
1720
|
+
const skills_root = path9.join(package_root, "dist/agent-src", "skills");
|
|
1622
1721
|
if (!_is_dir(skills_root)) {
|
|
1623
1722
|
return [];
|
|
1624
1723
|
}
|
|
1625
|
-
|
|
1724
|
+
fs9.mkdirSync(dest_dir, { recursive: true });
|
|
1626
1725
|
const written = [];
|
|
1627
|
-
for (const name of
|
|
1628
|
-
const entry =
|
|
1629
|
-
const isSymlink2 =
|
|
1726
|
+
for (const name of fs9.readdirSync(skills_root).sort()) {
|
|
1727
|
+
const entry = path9.join(skills_root, name);
|
|
1728
|
+
const isSymlink2 = fs9.lstatSync(entry).isSymbolicLink();
|
|
1630
1729
|
if (!(_is_dir(entry) || isSymlink2)) {
|
|
1631
1730
|
continue;
|
|
1632
1731
|
}
|
|
@@ -1634,8 +1733,8 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
|
|
|
1634
1733
|
if (curation !== null && !curation.includes(skill_name)) {
|
|
1635
1734
|
continue;
|
|
1636
1735
|
}
|
|
1637
|
-
const skill_md =
|
|
1638
|
-
if (!
|
|
1736
|
+
const skill_md = path9.join(entry, "SKILL.md");
|
|
1737
|
+
if (!fs9.existsSync(skill_md)) {
|
|
1639
1738
|
continue;
|
|
1640
1739
|
}
|
|
1641
1740
|
const files = _walk_skill_files(entry);
|
|
@@ -1647,15 +1746,15 @@ function build_skill_bundles(package_root, dest_dir, force = false, curation = n
|
|
|
1647
1746
|
return written;
|
|
1648
1747
|
}
|
|
1649
1748
|
function _command_slug(source_file, commands_root) {
|
|
1650
|
-
const rel =
|
|
1651
|
-
const noExt = rel.slice(0, rel.length -
|
|
1652
|
-
return noExt.split(
|
|
1749
|
+
const rel = path9.relative(commands_root, source_file);
|
|
1750
|
+
const noExt = rel.slice(0, rel.length - path9.extname(rel).length);
|
|
1751
|
+
return noExt.split(path9.sep).join("-");
|
|
1653
1752
|
}
|
|
1654
1753
|
function _iter_command_files(commands_root) {
|
|
1655
1754
|
const found = [];
|
|
1656
1755
|
const walk = (dir) => {
|
|
1657
|
-
for (const dirent of
|
|
1658
|
-
const full =
|
|
1756
|
+
for (const dirent of fs9.readdirSync(dir, { withFileTypes: true })) {
|
|
1757
|
+
const full = path9.join(dir, dirent.name);
|
|
1659
1758
|
if (dirent.isDirectory() || dirent.isSymbolicLink() && _is_dir(full)) {
|
|
1660
1759
|
walk(full);
|
|
1661
1760
|
} else if (dirent.name.endsWith(".md")) {
|
|
@@ -1665,21 +1764,21 @@ function _iter_command_files(commands_root) {
|
|
|
1665
1764
|
};
|
|
1666
1765
|
walk(commands_root);
|
|
1667
1766
|
found.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
1668
|
-
return found.filter((source_file) =>
|
|
1767
|
+
return found.filter((source_file) => path9.basename(source_file) !== "AGENTS.md");
|
|
1669
1768
|
}
|
|
1670
1769
|
function build_command_bundles(package_root, dest_dir, force = false, curation = null) {
|
|
1671
|
-
const commands_root =
|
|
1770
|
+
const commands_root = path9.join(package_root, "dist/agent-src", "commands");
|
|
1672
1771
|
if (!_is_dir(commands_root)) {
|
|
1673
1772
|
return [];
|
|
1674
1773
|
}
|
|
1675
|
-
const skills_root =
|
|
1774
|
+
const skills_root = path9.join(package_root, "dist/agent-src", "skills");
|
|
1676
1775
|
let skill_names = /* @__PURE__ */ new Set();
|
|
1677
1776
|
if (_is_dir(skills_root)) {
|
|
1678
1777
|
skill_names = new Set(
|
|
1679
|
-
|
|
1778
|
+
fs9.readdirSync(skills_root).filter((name) => _is_dir(path9.join(skills_root, name)))
|
|
1680
1779
|
);
|
|
1681
1780
|
}
|
|
1682
|
-
|
|
1781
|
+
fs9.mkdirSync(dest_dir, { recursive: true });
|
|
1683
1782
|
const written = [];
|
|
1684
1783
|
for (const source_file of _iter_command_files(commands_root)) {
|
|
1685
1784
|
const slug = _command_slug(source_file, commands_root);
|
|
@@ -1689,7 +1788,7 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
|
|
|
1689
1788
|
if (curation !== null && !curation.includes(slug)) {
|
|
1690
1789
|
continue;
|
|
1691
1790
|
}
|
|
1692
|
-
const files = [[
|
|
1791
|
+
const files = [[fs9.realpathSync(source_file), ["SKILL.md"]]];
|
|
1693
1792
|
_write_if_changed(dest_dir, slug, files, force, written);
|
|
1694
1793
|
}
|
|
1695
1794
|
return written;
|
|
@@ -1697,8 +1796,8 @@ function build_command_bundles(package_root, dest_dir, force = false, curation =
|
|
|
1697
1796
|
|
|
1698
1797
|
// src/scripts/hooks/host_lowering.ts
|
|
1699
1798
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
1700
|
-
import * as
|
|
1701
|
-
import * as
|
|
1799
|
+
import * as fs10 from "node:fs";
|
|
1800
|
+
import * as path10 from "node:path";
|
|
1702
1801
|
import { fileURLToPath } from "node:url";
|
|
1703
1802
|
|
|
1704
1803
|
// src/scripts/hooks/table_fingerprint.ts
|
|
@@ -1710,12 +1809,12 @@ function tableFingerprint(text) {
|
|
|
1710
1809
|
|
|
1711
1810
|
// src/scripts/hooks/host_lowering.ts
|
|
1712
1811
|
var _IN_BUNDLE = true;
|
|
1713
|
-
var _REPO_ROOT =
|
|
1714
|
-
|
|
1812
|
+
var _REPO_ROOT = path10.resolve(
|
|
1813
|
+
path10.dirname(fileURLToPath(import.meta.url)),
|
|
1715
1814
|
..._IN_BUNDLE ? ["..", ".."] : ["..", "..", ".."]
|
|
1716
1815
|
);
|
|
1717
|
-
var HOST_LOWERING_PATH =
|
|
1718
|
-
var HOST_LOWERING_JSON_PATH =
|
|
1816
|
+
var HOST_LOWERING_PATH = path10.join(_REPO_ROOT, "src", "scripts", "hooks", "host_lowering.yaml");
|
|
1817
|
+
var HOST_LOWERING_JSON_PATH = path10.join(_REPO_ROOT, "src", "scripts", "hooks", "host_lowering.json");
|
|
1719
1818
|
var DEFAULT_SURFACE = "any";
|
|
1720
1819
|
function _asString(v) {
|
|
1721
1820
|
if (v === null || v === void 0) return null;
|
|
@@ -1787,10 +1886,10 @@ function _structure(raw) {
|
|
|
1787
1886
|
var _cache = null;
|
|
1788
1887
|
function loadHostLowering() {
|
|
1789
1888
|
if (_cache !== null) return _cache;
|
|
1790
|
-
const text =
|
|
1889
|
+
const text = fs10.readFileSync(HOST_LOWERING_PATH, "utf-8");
|
|
1791
1890
|
let compiled;
|
|
1792
1891
|
try {
|
|
1793
|
-
compiled =
|
|
1892
|
+
compiled = fs10.readFileSync(HOST_LOWERING_JSON_PATH, "utf-8");
|
|
1794
1893
|
} catch {
|
|
1795
1894
|
compiled = null;
|
|
1796
1895
|
}
|
|
@@ -1802,7 +1901,24 @@ function resolveTable(yamlText, compiledText) {
|
|
|
1802
1901
|
try {
|
|
1803
1902
|
const raw = JSON.parse(compiledText);
|
|
1804
1903
|
const table = raw["table"];
|
|
1805
|
-
if (raw["fingerprint"] === tableFingerprint(yamlText) && typeof table === "object" && table !== null
|
|
1904
|
+
if (raw["fingerprint"] === tableFingerprint(yamlText) && typeof table === "object" && table !== null && // road-to-blocking-severities 2.3 — the BODY, not only its
|
|
1905
|
+
// label. `fingerprint` above says the file was compiled from
|
|
1906
|
+
// the YAML as it stands; it says nothing about whether the
|
|
1907
|
+
// body underneath was edited afterwards, and an edited body
|
|
1908
|
+
// with an untouched label was served. `body_fingerprint` is
|
|
1909
|
+
// the fingerprint of the exact bytes the compiler emitted, so
|
|
1910
|
+
// re-stringifying what we just parsed recovers them.
|
|
1911
|
+
//
|
|
1912
|
+
// A compiled file WITHOUT the field — one written before 2.3 —
|
|
1913
|
+
// falls through here, which is slow and correct: accepting it
|
|
1914
|
+
// would make the check optional and therefore absent.
|
|
1915
|
+
//
|
|
1916
|
+
// What it covers is a partial edit, never an author: anyone
|
|
1917
|
+
// who edits the body can recompute this as easily as the
|
|
1918
|
+
// compiler. The deny in `block_plumbing_writes` and the
|
|
1919
|
+
// ratification record are the mechanisms aimed at an author;
|
|
1920
|
+
// this one is aimed at a mistake.
|
|
1921
|
+
raw["body_fingerprint"] === tableFingerprint(JSON.stringify(table))) {
|
|
1806
1922
|
return _structure(table);
|
|
1807
1923
|
}
|
|
1808
1924
|
} catch {
|
|
@@ -1826,26 +1942,26 @@ function hostBindings(host, table = loadHostLowering()) {
|
|
|
1826
1942
|
}
|
|
1827
1943
|
|
|
1828
1944
|
// src/install/partitionEligibility.ts
|
|
1829
|
-
import * as
|
|
1830
|
-
import * as
|
|
1945
|
+
import * as fs12 from "node:fs";
|
|
1946
|
+
import * as os3 from "node:os";
|
|
1831
1947
|
|
|
1832
1948
|
// src/install/hostLayerFingerprint.ts
|
|
1833
1949
|
import { createHash as createHash6 } from "node:crypto";
|
|
1834
|
-
import * as
|
|
1835
|
-
import * as
|
|
1950
|
+
import * as fs11 from "node:fs";
|
|
1951
|
+
import * as path11 from "node:path";
|
|
1836
1952
|
var FINGERPRINT_SCHEMA = 1;
|
|
1837
1953
|
function collectFiles(dir) {
|
|
1838
1954
|
const out = [];
|
|
1839
1955
|
const walk = (d) => {
|
|
1840
1956
|
let entries;
|
|
1841
1957
|
try {
|
|
1842
|
-
entries =
|
|
1958
|
+
entries = fs11.readdirSync(d, { withFileTypes: true });
|
|
1843
1959
|
} catch {
|
|
1844
1960
|
return;
|
|
1845
1961
|
}
|
|
1846
1962
|
const sorted = [...entries].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
1847
1963
|
for (const e of sorted) {
|
|
1848
|
-
const p =
|
|
1964
|
+
const p = path11.join(d, e.name);
|
|
1849
1965
|
if (e.isDirectory()) {
|
|
1850
1966
|
walk(p);
|
|
1851
1967
|
} else if (e.isFile()) {
|
|
@@ -1862,10 +1978,10 @@ function fingerprintLayers(layers) {
|
|
|
1862
1978
|
for (const layer of layers) {
|
|
1863
1979
|
h.update(`layer:${layer.label}\0`);
|
|
1864
1980
|
for (const file of collectFiles(layer.root)) {
|
|
1865
|
-
h.update(
|
|
1981
|
+
h.update(path11.relative(layer.root, file));
|
|
1866
1982
|
h.update("\0");
|
|
1867
1983
|
try {
|
|
1868
|
-
h.update(
|
|
1984
|
+
h.update(fs11.readFileSync(file));
|
|
1869
1985
|
} catch {
|
|
1870
1986
|
h.update("\0unreadable\0");
|
|
1871
1987
|
}
|
|
@@ -1875,11 +1991,11 @@ function fingerprintLayers(layers) {
|
|
|
1875
1991
|
return h.digest("hex");
|
|
1876
1992
|
}
|
|
1877
1993
|
function hostLayerInputs(userHome) {
|
|
1878
|
-
const claude =
|
|
1994
|
+
const claude = path11.join(userHome, ".claude");
|
|
1879
1995
|
return [
|
|
1880
|
-
{ label: "rules", root:
|
|
1881
|
-
{ label: "skills", root:
|
|
1882
|
-
{ label: "commands", root:
|
|
1996
|
+
{ label: "rules", root: path11.join(claude, "rules") },
|
|
1997
|
+
{ label: "skills", root: path11.join(claude, "skills") },
|
|
1998
|
+
{ label: "commands", root: path11.join(claude, "commands") }
|
|
1883
1999
|
];
|
|
1884
2000
|
}
|
|
1885
2001
|
|
|
@@ -1888,7 +2004,7 @@ var MAINTAINER_WORKSPACE = "agent-config-maintainer";
|
|
|
1888
2004
|
function isExclusivelyPackageOnly(source_path) {
|
|
1889
2005
|
let meta;
|
|
1890
2006
|
try {
|
|
1891
|
-
[meta] = parseFrontmatter(
|
|
2007
|
+
[meta] = parseFrontmatter(fs12.readFileSync(source_path, "utf-8"));
|
|
1892
2008
|
} catch {
|
|
1893
2009
|
return false;
|
|
1894
2010
|
}
|
|
@@ -1903,7 +2019,7 @@ function stampHostLayerFingerprint(installedVersion, tools, lockfilePath, skip2,
|
|
|
1903
2019
|
return null;
|
|
1904
2020
|
}
|
|
1905
2021
|
try {
|
|
1906
|
-
const fingerprint = fingerprintLayers(hostLayerInputs(
|
|
2022
|
+
const fingerprint = fingerprintLayers(hostLayerInputs(os3.homedir()));
|
|
1907
2023
|
write_lockfile(installedVersion, [...tools], {
|
|
1908
2024
|
path: lockfilePath,
|
|
1909
2025
|
host_layer_fingerprint: fingerprint
|
|
@@ -1919,8 +2035,8 @@ function stampHostLayerFingerprint(installedVersion, tools, lockfilePath, skip2,
|
|
|
1919
2035
|
}
|
|
1920
2036
|
|
|
1921
2037
|
// src/install/claudeRuleRewrite.ts
|
|
1922
|
-
import * as
|
|
1923
|
-
import * as
|
|
2038
|
+
import * as fs13 from "node:fs";
|
|
2039
|
+
import * as path12 from "node:path";
|
|
1924
2040
|
|
|
1925
2041
|
// src/install/claudePathsPlan.ts
|
|
1926
2042
|
function derive_trigger_globs(meta) {
|
|
@@ -1960,14 +2076,22 @@ function _expanded_pattern_count(pattern) {
|
|
|
1960
2076
|
return n;
|
|
1961
2077
|
}
|
|
1962
2078
|
var CLAUDE_PATHS_PATTERN_BUDGET = 1e3;
|
|
2079
|
+
var PATH_SHAPED_TRIGGER_KEYS = /* @__PURE__ */ new Set(["file_pattern", "path_prefix"]);
|
|
2080
|
+
var NON_MATCHING_TRIGGER_KEYS = /* @__PURE__ */ new Set(["reason"]);
|
|
1963
2081
|
function _has_non_path_trigger(meta) {
|
|
1964
2082
|
const triggers = meta["triggers"];
|
|
1965
2083
|
if (!Array.isArray(triggers)) return false;
|
|
1966
2084
|
for (const t of triggers) {
|
|
1967
2085
|
if (t === null || typeof t !== "object" || Array.isArray(t)) continue;
|
|
1968
2086
|
const obj = t;
|
|
1969
|
-
|
|
1970
|
-
|
|
2087
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
2088
|
+
if (PATH_SHAPED_TRIGGER_KEYS.has(key) || NON_MATCHING_TRIGGER_KEYS.has(key)) continue;
|
|
2089
|
+
if (typeof value === "string") {
|
|
2090
|
+
if (value.trim() !== "") return true;
|
|
2091
|
+
} else if (value !== void 0 && value !== null) {
|
|
2092
|
+
return true;
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
1971
2095
|
}
|
|
1972
2096
|
return false;
|
|
1973
2097
|
}
|
|
@@ -2035,6 +2159,11 @@ function rewriteAndReport(rulesDir, quiet, info2, warn2, wrappers, preserved = /
|
|
|
2035
2159
|
` claude-code: ${wrappers.reserved.length} flat command(s) withheld \u2014 name is a Claude Code built-in (${wrappers.reserved.join(", ")}); nested /cluster:sub commands remain available`
|
|
2036
2160
|
);
|
|
2037
2161
|
}
|
|
2162
|
+
if (wrappers.foreign !== void 0 && wrappers.foreign.length > 0) {
|
|
2163
|
+
info2(
|
|
2164
|
+
` claude-code: kept ${wrappers.foreign.length} neighbour command file(s) whose name is a Claude Code built-in (${wrappers.foreign.join(", ")}); not ours to remove`
|
|
2165
|
+
);
|
|
2166
|
+
}
|
|
2038
2167
|
}
|
|
2039
2168
|
if (result.rewritten > 0 && !quiet) {
|
|
2040
2169
|
info2(
|
|
@@ -2076,23 +2205,23 @@ function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
|
|
|
2076
2205
|
const result = { rewritten: 0, scoped: [], dropped: [], failed: [] };
|
|
2077
2206
|
let entries;
|
|
2078
2207
|
try {
|
|
2079
|
-
entries =
|
|
2208
|
+
entries = fs13.readdirSync(rulesDir);
|
|
2080
2209
|
} catch {
|
|
2081
2210
|
return result;
|
|
2082
2211
|
}
|
|
2083
2212
|
for (const name of entries.filter((n) => n.endsWith(".md")).sort()) {
|
|
2084
|
-
const full =
|
|
2085
|
-
if (preserved.has(
|
|
2213
|
+
const full = path12.join(rulesDir, name);
|
|
2214
|
+
if (preserved.has(path12.resolve(full))) continue;
|
|
2086
2215
|
let stat;
|
|
2087
2216
|
try {
|
|
2088
|
-
stat =
|
|
2217
|
+
stat = fs13.lstatSync(full);
|
|
2089
2218
|
} catch {
|
|
2090
2219
|
continue;
|
|
2091
2220
|
}
|
|
2092
2221
|
if (!stat.isFile() || stat.isSymbolicLink()) continue;
|
|
2093
2222
|
let text;
|
|
2094
2223
|
try {
|
|
2095
|
-
text =
|
|
2224
|
+
text = fs13.readFileSync(full, "utf-8");
|
|
2096
2225
|
} catch {
|
|
2097
2226
|
continue;
|
|
2098
2227
|
}
|
|
@@ -2102,7 +2231,7 @@ function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
|
|
|
2102
2231
|
const withOwnership = _withPreservedKeys(rendered.text, text);
|
|
2103
2232
|
if (withOwnership !== text) {
|
|
2104
2233
|
try {
|
|
2105
|
-
|
|
2234
|
+
fs13.writeFileSync(full, withOwnership, "utf-8");
|
|
2106
2235
|
} catch (e) {
|
|
2107
2236
|
result.failed.push({
|
|
2108
2237
|
rule: name.slice(0, -3),
|
|
@@ -2121,6 +2250,554 @@ function rewriteClaudeRules(rulesDir, preserved = /* @__PURE__ */ new Set()) {
|
|
|
2121
2250
|
return result;
|
|
2122
2251
|
}
|
|
2123
2252
|
|
|
2253
|
+
// src/install/installThinLayer.ts
|
|
2254
|
+
import * as fs15 from "node:fs";
|
|
2255
|
+
import * as path15 from "node:path";
|
|
2256
|
+
import * as os6 from "node:os";
|
|
2257
|
+
|
|
2258
|
+
// src/scripts/_lib/installed_layer.ts
|
|
2259
|
+
import * as fs14 from "node:fs";
|
|
2260
|
+
import * as os5 from "node:os";
|
|
2261
|
+
import * as path14 from "node:path";
|
|
2262
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2263
|
+
|
|
2264
|
+
// src/install/globalRuleLayers.ts
|
|
2265
|
+
import * as os4 from "node:os";
|
|
2266
|
+
import * as path13 from "node:path";
|
|
2267
|
+
var GLOBAL_RULE_DIRS = {
|
|
2268
|
+
"claude-code": ".claude/rules",
|
|
2269
|
+
cursor: ".cursor/rules",
|
|
2270
|
+
augment: ".augment/rules",
|
|
2271
|
+
// Windsurf's scope root is `~/.codeium/windsurf/`, not `~/.windsurf/`.
|
|
2272
|
+
windsurf: ".codeium/windsurf/rules",
|
|
2273
|
+
// Cline's scope root IS the rules directory — no `rules/` suffix.
|
|
2274
|
+
cline: "Documents/Cline/Rules"
|
|
2275
|
+
};
|
|
2276
|
+
function globalRuleLayerPath(toolId, home = process.env["HOME"] ?? os4.homedir()) {
|
|
2277
|
+
const rel = GLOBAL_RULE_DIRS[toolId];
|
|
2278
|
+
return rel === void 0 ? null : path13.join(home, rel);
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
// src/scripts/_lib/installed_layer.ts
|
|
2282
|
+
var TOP_FILES = 20;
|
|
2283
|
+
var LIMIT_WARN_FRACTION = 0.8;
|
|
2284
|
+
function isUnconditional(text) {
|
|
2285
|
+
const [frontmatter] = splitFrontmatter(text);
|
|
2286
|
+
const emptyBlock = /^---\n---(\n|$)/.test(text);
|
|
2287
|
+
if (frontmatter === "" && !emptyBlock && /^\uFEFF?[\s]*---/.test(text)) {
|
|
2288
|
+
return !/^paths:/m.test(text);
|
|
2289
|
+
}
|
|
2290
|
+
return !/^paths:/m.test(frontmatter);
|
|
2291
|
+
}
|
|
2292
|
+
function readLayer(host, scope, dir, recorded) {
|
|
2293
|
+
const empty = {
|
|
2294
|
+
files: 0,
|
|
2295
|
+
unconditional: 0,
|
|
2296
|
+
chars: 0,
|
|
2297
|
+
package_owned: 0,
|
|
2298
|
+
foreign: 0,
|
|
2299
|
+
package_owned_chars: 0,
|
|
2300
|
+
foreign_chars: 0,
|
|
2301
|
+
unconditional_chars: 0,
|
|
2302
|
+
scoped_chars: 0,
|
|
2303
|
+
top: []
|
|
2304
|
+
};
|
|
2305
|
+
let names;
|
|
2306
|
+
try {
|
|
2307
|
+
names = fs14.readdirSync(dir);
|
|
2308
|
+
} catch {
|
|
2309
|
+
return { host, scope, dir, present: false, ...empty };
|
|
2310
|
+
}
|
|
2311
|
+
const readings = [];
|
|
2312
|
+
for (const name of names.sort()) {
|
|
2313
|
+
if (!name.endsWith(".md")) continue;
|
|
2314
|
+
const abs = path14.join(dir, name);
|
|
2315
|
+
let text;
|
|
2316
|
+
try {
|
|
2317
|
+
const st = fs14.statSync(abs);
|
|
2318
|
+
if (!st.isFile()) continue;
|
|
2319
|
+
text = fs14.readFileSync(abs, "utf-8");
|
|
2320
|
+
} catch {
|
|
2321
|
+
continue;
|
|
2322
|
+
}
|
|
2323
|
+
const owned = recorded.has(abs);
|
|
2324
|
+
readings.push({
|
|
2325
|
+
file: name,
|
|
2326
|
+
// THE STRIP IS THE PROJECTOR'S OWN. `ruleBody` is what
|
|
2327
|
+
// `project_thin_rules` and the delivery carrier both call, so "what
|
|
2328
|
+
// a host loads" and "what a delivery carries" cannot drift into two
|
|
2329
|
+
// spellings of the same measurement.
|
|
2330
|
+
chars: ruleBody(text).length,
|
|
2331
|
+
unconditional: isUnconditional(text),
|
|
2332
|
+
package_owned: owned
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
const top = [...readings].sort((a, b) => b.chars - a.chars || a.file.localeCompare(b.file)).slice(0, TOP_FILES);
|
|
2336
|
+
return {
|
|
2337
|
+
host,
|
|
2338
|
+
scope,
|
|
2339
|
+
dir,
|
|
2340
|
+
present: true,
|
|
2341
|
+
files: readings.length,
|
|
2342
|
+
unconditional: readings.filter((r) => r.unconditional).length,
|
|
2343
|
+
chars: readings.reduce((n, r) => n + r.chars, 0),
|
|
2344
|
+
package_owned: readings.filter((r) => r.package_owned).length,
|
|
2345
|
+
foreign: readings.filter((r) => !r.package_owned).length,
|
|
2346
|
+
package_owned_chars: readings.reduce((n, r) => n + (r.package_owned ? r.chars : 0), 0),
|
|
2347
|
+
foreign_chars: readings.reduce((n, r) => n + (r.package_owned ? 0 : r.chars), 0),
|
|
2348
|
+
unconditional_chars: readings.reduce((n, r) => n + (r.unconditional ? r.chars : 0), 0),
|
|
2349
|
+
scoped_chars: readings.reduce((n, r) => n + (r.unconditional ? 0 : r.chars), 0),
|
|
2350
|
+
top
|
|
2351
|
+
};
|
|
2352
|
+
}
|
|
2353
|
+
function defaultHostLimitsPath() {
|
|
2354
|
+
return path14.join(
|
|
2355
|
+
path14.dirname(fileURLToPath2(import.meta.url)),
|
|
2356
|
+
"..",
|
|
2357
|
+
"..",
|
|
2358
|
+
"config",
|
|
2359
|
+
"host-instruction-limits.json"
|
|
2360
|
+
);
|
|
2361
|
+
}
|
|
2362
|
+
function loadHostInstructionLimits(file = defaultHostLimitsPath()) {
|
|
2363
|
+
const out = /* @__PURE__ */ new Map();
|
|
2364
|
+
let raw;
|
|
2365
|
+
try {
|
|
2366
|
+
raw = JSON.parse(fs14.readFileSync(file, "utf-8"));
|
|
2367
|
+
} catch {
|
|
2368
|
+
return out;
|
|
2369
|
+
}
|
|
2370
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return out;
|
|
2371
|
+
for (const [host, v] of Object.entries(raw)) {
|
|
2372
|
+
if (host.startsWith("_")) continue;
|
|
2373
|
+
if (typeof v !== "object" || v === null || Array.isArray(v)) continue;
|
|
2374
|
+
const e = v;
|
|
2375
|
+
const n = e.limit;
|
|
2376
|
+
const limit = typeof n === "number" && Number.isFinite(n) && n > 0 ? n : null;
|
|
2377
|
+
const k = e.kind;
|
|
2378
|
+
const kind = limit === null ? "unpublished" : k === "vendor-published" || k === "reported" ? k : "reported";
|
|
2379
|
+
out.set(host, { limit, kind });
|
|
2380
|
+
}
|
|
2381
|
+
return out;
|
|
2382
|
+
}
|
|
2383
|
+
function buildHostLimitRows(layers, limits) {
|
|
2384
|
+
const byHost = /* @__PURE__ */ new Map();
|
|
2385
|
+
for (const l of layers) {
|
|
2386
|
+
if (!l.present) continue;
|
|
2387
|
+
const acc = byHost.get(l.host) ?? { chars: 0, owned: 0, foreign: 0 };
|
|
2388
|
+
acc.chars += l.chars;
|
|
2389
|
+
acc.owned += l.package_owned_chars;
|
|
2390
|
+
acc.foreign += l.foreign_chars;
|
|
2391
|
+
byHost.set(l.host, acc);
|
|
2392
|
+
}
|
|
2393
|
+
for (const l of layers) if (!byHost.has(l.host)) byHost.set(l.host, { chars: 0, owned: 0, foreign: 0 });
|
|
2394
|
+
for (const [host, e] of limits) if (e.limit !== null && !byHost.has(host)) {
|
|
2395
|
+
byHost.set(host, { chars: 0, owned: 0, foreign: 0 });
|
|
2396
|
+
}
|
|
2397
|
+
const rows = [];
|
|
2398
|
+
for (const host of [...byHost.keys()].sort()) {
|
|
2399
|
+
const a = byHost.get(host);
|
|
2400
|
+
const e = limits.get(host) ?? { limit: null, kind: "unpublished" };
|
|
2401
|
+
const fraction = e.limit === null ? null : a.chars / e.limit;
|
|
2402
|
+
rows.push({
|
|
2403
|
+
host,
|
|
2404
|
+
limit: e.limit,
|
|
2405
|
+
kind: e.kind,
|
|
2406
|
+
chars: a.chars,
|
|
2407
|
+
package_owned_chars: a.owned,
|
|
2408
|
+
foreign_chars: a.foreign,
|
|
2409
|
+
fraction,
|
|
2410
|
+
warn: fraction !== null && fraction >= LIMIT_WARN_FRACTION
|
|
2411
|
+
});
|
|
2412
|
+
}
|
|
2413
|
+
return rows;
|
|
2414
|
+
}
|
|
2415
|
+
function defaultInventoryPath(home) {
|
|
2416
|
+
if (home === void 0 || home === null || home === "") return inventory_path();
|
|
2417
|
+
try {
|
|
2418
|
+
const real = (q) => {
|
|
2419
|
+
try {
|
|
2420
|
+
return fs14.realpathSync(q);
|
|
2421
|
+
} catch {
|
|
2422
|
+
return path14.resolve(q);
|
|
2423
|
+
}
|
|
2424
|
+
};
|
|
2425
|
+
const mine = os5.homedir();
|
|
2426
|
+
if (path14.resolve(home) === path14.resolve(mine) || real(home) === real(mine)) {
|
|
2427
|
+
return inventory_path();
|
|
2428
|
+
}
|
|
2429
|
+
} catch {
|
|
2430
|
+
}
|
|
2431
|
+
return path14.join(home, DEFAULT_EVENT4U_ROOT_RELATIVE, INVENTORY_BASENAME);
|
|
2432
|
+
}
|
|
2433
|
+
function resolveLayerOwnership(opts) {
|
|
2434
|
+
const recorded = /* @__PURE__ */ new Map();
|
|
2435
|
+
const sources = [];
|
|
2436
|
+
if (opts.inventoryPath !== null) {
|
|
2437
|
+
let n = 0;
|
|
2438
|
+
try {
|
|
2439
|
+
const inv = load_inventory(opts.inventoryPath ?? defaultInventoryPath(opts.home));
|
|
2440
|
+
for (const abs of recorded_absolute_files(inv, opts.home ?? null)) {
|
|
2441
|
+
if (!recorded.has(abs)) n += 1;
|
|
2442
|
+
recorded.set(abs, null);
|
|
2443
|
+
}
|
|
2444
|
+
} catch {
|
|
2445
|
+
}
|
|
2446
|
+
if (n > 0) sources.push("global-inventory");
|
|
2447
|
+
}
|
|
2448
|
+
let fromDeploy = 0;
|
|
2449
|
+
for (const [anchor, rels] of opts.thisDeploy ?? /* @__PURE__ */ new Map()) {
|
|
2450
|
+
for (const rel of rels) {
|
|
2451
|
+
const abs = path14.resolve(anchor, rel);
|
|
2452
|
+
if (!recorded.has(abs)) fromDeploy += 1;
|
|
2453
|
+
recorded.set(abs, null);
|
|
2454
|
+
try {
|
|
2455
|
+
recorded.set(fs14.realpathSync(abs), null);
|
|
2456
|
+
} catch {
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
if (fromDeploy > 0) sources.push("this-deploy");
|
|
2461
|
+
const manifestPath = opts.manifestPath ?? null;
|
|
2462
|
+
if (manifestPath !== null && fs14.existsSync(manifestPath)) {
|
|
2463
|
+
let n = 0;
|
|
2464
|
+
let recordedHashes;
|
|
2465
|
+
try {
|
|
2466
|
+
recordedHashes = readRecordedHashes(manifestPath, opts.projectRoot);
|
|
2467
|
+
} catch {
|
|
2468
|
+
recordedHashes = NO_RECORDED_HASHES;
|
|
2469
|
+
}
|
|
2470
|
+
for (const [abs, hash] of recordedHashes) {
|
|
2471
|
+
n += 1;
|
|
2472
|
+
recorded.set(abs, hash);
|
|
2473
|
+
}
|
|
2474
|
+
if (n > 0) sources.push("manifest");
|
|
2475
|
+
}
|
|
2476
|
+
if (recorded.size === 0) {
|
|
2477
|
+
return { recorded: NO_RECORDED_HASHES, sources: [], source: "none" };
|
|
2478
|
+
}
|
|
2479
|
+
const primary = sources.includes("manifest") ? "manifest" : sources.includes("global-inventory") ? "global-inventory" : "this-deploy";
|
|
2480
|
+
return { recorded, sources, source: primary };
|
|
2481
|
+
}
|
|
2482
|
+
function ownershipLine(sources) {
|
|
2483
|
+
const list = (Array.isArray(sources) ? sources : [sources]).filter(
|
|
2484
|
+
(s) => s !== "none"
|
|
2485
|
+
);
|
|
2486
|
+
if (list.length === 0) {
|
|
2487
|
+
return "ownership: NO manifest and NO deploy inventory resolved \u2014 every file reads foreign, which is no evidence rather than a finding";
|
|
2488
|
+
}
|
|
2489
|
+
const phrases = {
|
|
2490
|
+
manifest: "the installed-tools manifest",
|
|
2491
|
+
"global-inventory": "the global deploy inventory (deployed-files.json)",
|
|
2492
|
+
"this-deploy": "the file set this install just wrote"
|
|
2493
|
+
};
|
|
2494
|
+
const named = list.map((s) => phrases[s]);
|
|
2495
|
+
const joined = named.length === 1 ? named[0] : `${named.slice(0, -1).join(", ")} and ${named[named.length - 1]}`;
|
|
2496
|
+
return `ownership: read from ${joined}`;
|
|
2497
|
+
}
|
|
2498
|
+
function renderHostLimitRows(rows) {
|
|
2499
|
+
const out = [
|
|
2500
|
+
"host instruction budgets \u2014 package-owned + foreign against the published limit"
|
|
2501
|
+
];
|
|
2502
|
+
for (const r of rows) {
|
|
2503
|
+
const split = `${String(r.package_owned_chars)} package-owned + ${String(r.foreign_chars)} foreign = ${String(r.chars)} chars`;
|
|
2504
|
+
if (r.limit === null) {
|
|
2505
|
+
out.push(` ${r.host} \u2014 ${split}; no published limit recorded \u2014 not measured`);
|
|
2506
|
+
continue;
|
|
2507
|
+
}
|
|
2508
|
+
const pct = (r.fraction * 100).toFixed(1);
|
|
2509
|
+
out.push(
|
|
2510
|
+
` ${r.host} \u2014 ${split}; ${pct}% of ${String(r.limit)} (${r.kind})` + (r.warn ? ` \u2014 WARNING: at or past ${String(Math.round(LIMIT_WARN_FRACTION * 100))}% of the published limit` : "")
|
|
2511
|
+
);
|
|
2512
|
+
}
|
|
2513
|
+
return out;
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
// src/install/installThinLayer.ts
|
|
2517
|
+
function thinInstalledRuleLayer(opts) {
|
|
2518
|
+
const packageRoot = path15.resolve(opts.packageRoot);
|
|
2519
|
+
const bodySourceDir = path15.join(packageRoot, "dist", "agent-src", "rules");
|
|
2520
|
+
const bodyLinkPrefix = absoluteBodyLinkPrefix(packageRoot);
|
|
2521
|
+
const preserved = opts.preserved ?? /* @__PURE__ */ new Set();
|
|
2522
|
+
const stubs = build_thin(bodySourceDir, null, null, null, { packageRoot, bodyLinkPrefix });
|
|
2523
|
+
let thinned = 0;
|
|
2524
|
+
let rewritten = 0;
|
|
2525
|
+
let kept = 0;
|
|
2526
|
+
let charsBefore = 0;
|
|
2527
|
+
let charsAfter = 0;
|
|
2528
|
+
const preservedHits = [];
|
|
2529
|
+
const absent = [];
|
|
2530
|
+
const failed = [];
|
|
2531
|
+
for (const [name, stubText] of stubs) {
|
|
2532
|
+
const target = path15.join(opts.rulesDir, name);
|
|
2533
|
+
let installed;
|
|
2534
|
+
try {
|
|
2535
|
+
installed = fs15.readFileSync(target, "utf-8");
|
|
2536
|
+
} catch (e) {
|
|
2537
|
+
if (e.code === "ENOENT") absent.push(name);
|
|
2538
|
+
else failed.push({ rule: name, reason: String(e) });
|
|
2539
|
+
continue;
|
|
2540
|
+
}
|
|
2541
|
+
let sourceText;
|
|
2542
|
+
try {
|
|
2543
|
+
sourceText = fs15.readFileSync(path15.join(bodySourceDir, name), "utf-8");
|
|
2544
|
+
} catch {
|
|
2545
|
+
sourceText = null;
|
|
2546
|
+
}
|
|
2547
|
+
if (stubText === sourceText) {
|
|
2548
|
+
kept += 1;
|
|
2549
|
+
charsBefore += installed.length;
|
|
2550
|
+
charsAfter += installed.length;
|
|
2551
|
+
continue;
|
|
2552
|
+
}
|
|
2553
|
+
if (preserved.has(path15.resolve(target))) {
|
|
2554
|
+
preservedHits.push(name);
|
|
2555
|
+
charsBefore += installed.length;
|
|
2556
|
+
charsAfter += installed.length;
|
|
2557
|
+
continue;
|
|
2558
|
+
}
|
|
2559
|
+
const [frontmatter] = split_frontmatter(installed);
|
|
2560
|
+
charsBefore += installed.length;
|
|
2561
|
+
if (frontmatter === "" && /^\uFEFF?[\s]*---/.test(installed)) {
|
|
2562
|
+
failed.push({
|
|
2563
|
+
rule: name,
|
|
2564
|
+
reason: "opens a frontmatter block that never closes \u2014 left untouched so its ownership keys survive"
|
|
2565
|
+
});
|
|
2566
|
+
charsAfter += installed.length;
|
|
2567
|
+
continue;
|
|
2568
|
+
}
|
|
2569
|
+
const next = `${frontmatter}${stubText}`;
|
|
2570
|
+
try {
|
|
2571
|
+
if (next !== installed) {
|
|
2572
|
+
fs15.writeFileSync(target, next, "utf-8");
|
|
2573
|
+
rewritten += 1;
|
|
2574
|
+
}
|
|
2575
|
+
thinned += 1;
|
|
2576
|
+
charsAfter += next.length;
|
|
2577
|
+
} catch (e) {
|
|
2578
|
+
failed.push({ rule: name, reason: String(e) });
|
|
2579
|
+
charsAfter += installed.length;
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
if (stubs.size === 0) {
|
|
2583
|
+
failed.push({
|
|
2584
|
+
rule: bodySourceDir,
|
|
2585
|
+
reason: "no rule bodies found to build stubs from \u2014 the layer was left full-bodied"
|
|
2586
|
+
});
|
|
2587
|
+
}
|
|
2588
|
+
return {
|
|
2589
|
+
thinned,
|
|
2590
|
+
rewritten,
|
|
2591
|
+
kept,
|
|
2592
|
+
preserved: preservedHits,
|
|
2593
|
+
absent,
|
|
2594
|
+
failed,
|
|
2595
|
+
bodyLinkPrefix,
|
|
2596
|
+
charsBefore,
|
|
2597
|
+
charsAfter
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
function describeThinInstalledLayer(res) {
|
|
2601
|
+
const out = [];
|
|
2602
|
+
out.push(
|
|
2603
|
+
res.rewritten === 0 && res.thinned > 0 ? ` claude-code: ${String(res.thinned)} rule(s) already thinned, ${String(res.kept)} kept full-bodied; ${String(res.charsAfter)} chars \u2014 nothing to rewrite` : ` claude-code: thinned ${String(res.rewritten)} rule(s) to stubs, ${String(res.kept)} kept full-bodied; ${String(res.charsBefore)} -> ${String(res.charsAfter)} chars`
|
|
2604
|
+
);
|
|
2605
|
+
if (res.preserved.length > 0) {
|
|
2606
|
+
out.push(
|
|
2607
|
+
` claude-code: ${String(res.preserved.length)} rule(s) left full \u2014 you edited them and they are preserved, never overwritten (${res.preserved.join(", ")})`
|
|
2608
|
+
);
|
|
2609
|
+
}
|
|
2610
|
+
for (const f of res.failed) {
|
|
2611
|
+
out.push(` claude-code: ${f.rule}: could not write stub \u2014 ${f.reason}`);
|
|
2612
|
+
}
|
|
2613
|
+
return out;
|
|
2614
|
+
}
|
|
2615
|
+
function installReceiptBudgetLines(packageRoot, home = os6.homedir(), opts = {}) {
|
|
2616
|
+
try {
|
|
2617
|
+
const { recorded, sources } = resolveLayerOwnership({
|
|
2618
|
+
manifestPath: opts.manifestPath === void 0 ? manifest_path(packageRoot) : opts.manifestPath,
|
|
2619
|
+
projectRoot: packageRoot,
|
|
2620
|
+
// The same home the layers below are read from — the inventory's
|
|
2621
|
+
// anchor is tilde-relative, so the two must agree or the receipt
|
|
2622
|
+
// measures one install and claims ownership of another.
|
|
2623
|
+
home,
|
|
2624
|
+
// THE RECEIPT IS THE "ASKING PROCESS" CASE, so it names no home
|
|
2625
|
+
// here. It runs inside the install that WROTE the inventory, and
|
|
2626
|
+
// that writer resolves the path through `inventory_path()` —
|
|
2627
|
+
// honouring `AGENT_CONFIG_DEPLOY_INVENTORY`, which names a FILE
|
|
2628
|
+
// rather than a home, and `EVENT4U_CONFIG_HOME`. Passing `home`
|
|
2629
|
+
// would take `defaultInventoryPath`'s stated-home branch and read
|
|
2630
|
+
// `<home>/.event4u/...`, a file nothing wrote under either
|
|
2631
|
+
// override, and the inventory evidence would be silently lost.
|
|
2632
|
+
// UNDEFINED IS LEFT UNDEFINED so `resolveLayerOwnership` applies
|
|
2633
|
+
// `defaultInventoryPath(home)` — the SAME resolution the report
|
|
2634
|
+
// uses. Hardcoding `inventory_path()` here made the two readers
|
|
2635
|
+
// step 1.2 exists to reconcile disagree for any home that is not
|
|
2636
|
+
// the asking process's: the receipt read one install's inventory
|
|
2637
|
+
// and then expanded its tilde-relative anchors against the OTHER
|
|
2638
|
+
// home, which is the cross-home misattribution two docstrings in
|
|
2639
|
+
// the resolver forbid. `defaultInventoryPath` already returns
|
|
2640
|
+
// `inventory_path()` when the stated home IS this process's, which
|
|
2641
|
+
// is the case that motivated the hardcode.
|
|
2642
|
+
inventoryPath: opts.inventoryPath,
|
|
2643
|
+
thisDeploy: opts.thisDeploy
|
|
2644
|
+
});
|
|
2645
|
+
const layers = [];
|
|
2646
|
+
for (const host of Object.keys(GLOBAL_RULE_DIRS).sort()) {
|
|
2647
|
+
const dir = globalRuleLayerPath(host, home);
|
|
2648
|
+
if (dir === null) continue;
|
|
2649
|
+
layers.push(readLayer(host, "global", dir, recorded));
|
|
2650
|
+
}
|
|
2651
|
+
const rows = buildHostLimitRows(layers, loadHostInstructionLimits());
|
|
2652
|
+
if (rows.length === 0) return [];
|
|
2653
|
+
return [` ${ownershipLine(sources)}`, ...renderHostLimitRows(rows).map((l) => ` ${l}`)];
|
|
2654
|
+
} catch {
|
|
2655
|
+
return [];
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
|
|
2659
|
+
// src/install/globalRuleScope.ts
|
|
2660
|
+
function isPlainObject2(v) {
|
|
2661
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2662
|
+
}
|
|
2663
|
+
function resolveGlobalRuleScope(inputs) {
|
|
2664
|
+
const { packageRoot, warn: warn2 } = inputs;
|
|
2665
|
+
const settings_path = inputs.settingsPath;
|
|
2666
|
+
if (settings_path === null) {
|
|
2667
|
+
try {
|
|
2668
|
+
return ruleScopeFromSettings(inputs.loadDefaults(), packageRoot);
|
|
2669
|
+
} catch {
|
|
2670
|
+
return LEGACY_ALL;
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
let text;
|
|
2674
|
+
try {
|
|
2675
|
+
text = inputs.readText(settings_path);
|
|
2676
|
+
} catch (e) {
|
|
2677
|
+
warn2(
|
|
2678
|
+
`could not read ${settings_path} (${String(e)}) \u2014 rule scoping falls back to legacy-all, so ALL rules including maintainer-only ones will be installed. Fix the file to restore scoping.`
|
|
2679
|
+
);
|
|
2680
|
+
return LEGACY_ALL;
|
|
2681
|
+
}
|
|
2682
|
+
const parsed = inputs.parseYaml(text);
|
|
2683
|
+
if (!isPlainObject2(parsed)) {
|
|
2684
|
+
warn2(
|
|
2685
|
+
`${settings_path} is not a YAML mapping \u2014 rule scoping falls back to legacy-all, so ALL rules including maintainer-only ones will be installed. Fix the file to restore scoping.`
|
|
2686
|
+
);
|
|
2687
|
+
return LEGACY_ALL;
|
|
2688
|
+
}
|
|
2689
|
+
try {
|
|
2690
|
+
return ruleScopeFromSettings(parsed, packageRoot);
|
|
2691
|
+
} catch (e) {
|
|
2692
|
+
warn2(
|
|
2693
|
+
`could not derive rule scope from ${settings_path} (${String(e)}) \u2014 falling back to legacy-all; ALL rules will be installed.`
|
|
2694
|
+
);
|
|
2695
|
+
return LEGACY_ALL;
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2699
|
+
// src/scripts/_lib/lean_projection_mode.ts
|
|
2700
|
+
import * as path16 from "node:path";
|
|
2701
|
+
var DEFAULT_LEAN_PROJECTION_MODE = "eager-all";
|
|
2702
|
+
function normalizeLeanProjectionMode(raw) {
|
|
2703
|
+
const v = typeof raw === "string" ? raw.trim().toLowerCase() : "";
|
|
2704
|
+
if (v === "thin") return "thin";
|
|
2705
|
+
if (v === "delivery") return "delivery";
|
|
2706
|
+
return DEFAULT_LEAN_PROJECTION_MODE;
|
|
2707
|
+
}
|
|
2708
|
+
function writesThinFiles(mode) {
|
|
2709
|
+
return mode === "thin" || mode === "delivery";
|
|
2710
|
+
}
|
|
2711
|
+
var THINNABLE_HOSTS = ["claude-code", "cursor", "cline"];
|
|
2712
|
+
var DEFAULT_LEAN_PROJECTION_HOSTS = ["claude-code"];
|
|
2713
|
+
function resolveLeanProjectionHosts(raw) {
|
|
2714
|
+
const known = new Set(THINNABLE_HOSTS);
|
|
2715
|
+
if (!Array.isArray(raw) || raw.length === 0) {
|
|
2716
|
+
return { hosts: [...DEFAULT_LEAN_PROJECTION_HOSTS], dropped: [], usedDefault: true };
|
|
2717
|
+
}
|
|
2718
|
+
const hosts = [];
|
|
2719
|
+
const dropped = [];
|
|
2720
|
+
for (const entry of raw) {
|
|
2721
|
+
const id = typeof entry === "string" ? entry.trim().toLowerCase() : "";
|
|
2722
|
+
if (id === "") {
|
|
2723
|
+
dropped.push({ id: String(entry), reason: "unknown" });
|
|
2724
|
+
continue;
|
|
2725
|
+
}
|
|
2726
|
+
if (!known.has(id)) {
|
|
2727
|
+
dropped.push({ id, reason: KNOWN_NON_THINNABLE_HOSTS.has(id) ? "not-thinnable" : "unknown" });
|
|
2728
|
+
continue;
|
|
2729
|
+
}
|
|
2730
|
+
if (!hosts.includes(id)) hosts.push(id);
|
|
2731
|
+
}
|
|
2732
|
+
hosts.sort();
|
|
2733
|
+
return { hosts, dropped, usedDefault: false };
|
|
2734
|
+
}
|
|
2735
|
+
var KNOWN_NON_THINNABLE_HOSTS = /* @__PURE__ */ new Set([
|
|
2736
|
+
"claude-desktop",
|
|
2737
|
+
"augment",
|
|
2738
|
+
"copilot",
|
|
2739
|
+
"windsurf",
|
|
2740
|
+
"gemini",
|
|
2741
|
+
"codex",
|
|
2742
|
+
"cowork"
|
|
2743
|
+
]);
|
|
2744
|
+
function thinsHost(mode, hosts, hostId) {
|
|
2745
|
+
return writesThinFiles(mode) && hosts.includes(hostId);
|
|
2746
|
+
}
|
|
2747
|
+
function resolveLeanProjection(opts = {}) {
|
|
2748
|
+
const file = opts.settingsPath ?? path16.join(opts.projectRoot ?? process.cwd(), ".agent-settings.yml");
|
|
2749
|
+
const tpl = opts.packageRoot == null ? null : path16.join(opts.packageRoot, "src", "config", "agent-settings.template.yml");
|
|
2750
|
+
let lean;
|
|
2751
|
+
try {
|
|
2752
|
+
lean = load_agent_settings(
|
|
2753
|
+
tpl === null ? { project_path: file } : { project_path: file, template_path: tpl }
|
|
2754
|
+
)["lean_projection"];
|
|
2755
|
+
} catch {
|
|
2756
|
+
}
|
|
2757
|
+
const obj = typeof lean === "object" && lean !== null && !Array.isArray(lean) ? lean : {};
|
|
2758
|
+
const o = obj;
|
|
2759
|
+
return {
|
|
2760
|
+
mode: normalizeLeanProjectionMode(o["mode"] ?? ""),
|
|
2761
|
+
hosts: resolveLeanProjectionHosts(o["hosts"]),
|
|
2762
|
+
// LAZY, and the hot path is the reason. Provenance needs a SECOND,
|
|
2763
|
+
// template-isolated cascade, and only the installer reads it — the
|
|
2764
|
+
// delivery concern on `user_prompt_submit` destructures `{ mode, hosts }`
|
|
2765
|
+
// and discards this field, so computing it eagerly doubled the per-prompt
|
|
2766
|
+
// settings read for an answer nobody asked for. A getter keeps the
|
|
2767
|
+
// field's shape (`readonly modeExplicit: boolean`) and charges only the
|
|
2768
|
+
// caller that touches it.
|
|
2769
|
+
get modeExplicit() {
|
|
2770
|
+
return rawExplicitLeanProjectionMode(opts) !== "";
|
|
2771
|
+
}
|
|
2772
|
+
};
|
|
2773
|
+
}
|
|
2774
|
+
var NO_TEMPLATE_LAYER = path16.join(path16.sep, "dev", "null", "agent-config-absent-template.yml");
|
|
2775
|
+
function rawExplicitLeanProjectionMode(opts = {}) {
|
|
2776
|
+
const file = opts.settingsPath ?? path16.join(opts.projectRoot ?? process.cwd(), ".agent-settings.yml");
|
|
2777
|
+
let lean;
|
|
2778
|
+
try {
|
|
2779
|
+
lean = load_agent_settings({ project_path: file, template_path: NO_TEMPLATE_LAYER })["lean_projection"];
|
|
2780
|
+
} catch {
|
|
2781
|
+
return "";
|
|
2782
|
+
}
|
|
2783
|
+
if (typeof lean !== "object" || lean === null || Array.isArray(lean)) return "";
|
|
2784
|
+
const m = lean["mode"];
|
|
2785
|
+
return typeof m === "string" ? m.trim() : "";
|
|
2786
|
+
}
|
|
2787
|
+
function installerThinsHost(hostId, opts = {}) {
|
|
2788
|
+
const { mode, hosts, modeExplicit } = resolveLeanProjection({
|
|
2789
|
+
...opts,
|
|
2790
|
+
settingsPath: opts.settingsPath ?? NO_PROJECT_LAYER
|
|
2791
|
+
});
|
|
2792
|
+
return modeExplicit && thinsHost(mode, hosts.hosts, hostId);
|
|
2793
|
+
}
|
|
2794
|
+
var NO_PROJECT_LAYER = path16.join(
|
|
2795
|
+
path16.sep,
|
|
2796
|
+
"dev",
|
|
2797
|
+
"null",
|
|
2798
|
+
"agent-config-absent-project-settings.yml"
|
|
2799
|
+
);
|
|
2800
|
+
|
|
2124
2801
|
// src/shared/settingsSurface.ts
|
|
2125
2802
|
function unwrapRef(root) {
|
|
2126
2803
|
if (root.$ref !== void 0 && root.definitions !== void 0) {
|
|
@@ -3476,8 +4153,8 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
3476
4153
|
};
|
|
3477
4154
|
|
|
3478
4155
|
// src/scripts/_lib/module_detection.ts
|
|
3479
|
-
import * as
|
|
3480
|
-
import * as
|
|
4156
|
+
import * as fs16 from "node:fs";
|
|
4157
|
+
import * as path17 from "node:path";
|
|
3481
4158
|
var _SKIP_DIRS = /* @__PURE__ */ new Set([".module-template", ".example"]);
|
|
3482
4159
|
var _RULES = [
|
|
3483
4160
|
["app/Modules", "laravel-hmvc", "App\\Modules\\{ModuleName}"],
|
|
@@ -3491,14 +4168,14 @@ var _RULES = [
|
|
|
3491
4168
|
];
|
|
3492
4169
|
function _isDir(p) {
|
|
3493
4170
|
try {
|
|
3494
|
-
return
|
|
4171
|
+
return fs16.statSync(p).isDirectory();
|
|
3495
4172
|
} catch {
|
|
3496
4173
|
return false;
|
|
3497
4174
|
}
|
|
3498
4175
|
}
|
|
3499
4176
|
function _isFile(p) {
|
|
3500
4177
|
try {
|
|
3501
|
-
return
|
|
4178
|
+
return fs16.statSync(p).isFile();
|
|
3502
4179
|
} catch {
|
|
3503
4180
|
return false;
|
|
3504
4181
|
}
|
|
@@ -3512,13 +4189,13 @@ function _isUpperChar(ch) {
|
|
|
3512
4189
|
function _list_module_subdirs(root) {
|
|
3513
4190
|
let entries;
|
|
3514
4191
|
try {
|
|
3515
|
-
entries =
|
|
4192
|
+
entries = fs16.readdirSync(root).sort();
|
|
3516
4193
|
} catch {
|
|
3517
4194
|
return [];
|
|
3518
4195
|
}
|
|
3519
4196
|
const out = [];
|
|
3520
4197
|
for (const name of entries) {
|
|
3521
|
-
if (!_isDir(
|
|
4198
|
+
if (!_isDir(path17.join(root, name))) {
|
|
3522
4199
|
continue;
|
|
3523
4200
|
}
|
|
3524
4201
|
if (name.startsWith(".")) {
|
|
@@ -3540,11 +4217,11 @@ function _score_confidence(stack, root, subdirs) {
|
|
|
3540
4217
|
return capitalized.length > 0 ? "high" : "medium";
|
|
3541
4218
|
}
|
|
3542
4219
|
if (stack === "node-monorepo") {
|
|
3543
|
-
const withPkgJson = subdirs.filter((name) => _isFile(
|
|
4220
|
+
const withPkgJson = subdirs.filter((name) => _isFile(path17.join(root, name, "package.json")));
|
|
3544
4221
|
return withPkgJson.length > 0 ? "high" : "medium";
|
|
3545
4222
|
}
|
|
3546
4223
|
if (stack === "python-src") {
|
|
3547
|
-
const withInit = subdirs.filter((name) => _isFile(
|
|
4224
|
+
const withInit = subdirs.filter((name) => _isFile(path17.join(root, name, "__init__.py")));
|
|
3548
4225
|
return withInit.length > 0 ? "high" : "medium";
|
|
3549
4226
|
}
|
|
3550
4227
|
if (stack === "go-internal") {
|
|
@@ -3556,7 +4233,7 @@ function detect_module_roots(project_root) {
|
|
|
3556
4233
|
const high = [];
|
|
3557
4234
|
const medium = [];
|
|
3558
4235
|
for (const [rel_path, stack, namespace_template] of _RULES) {
|
|
3559
|
-
const abs_path =
|
|
4236
|
+
const abs_path = path17.join(project_root, rel_path);
|
|
3560
4237
|
if (!_isDir(abs_path)) {
|
|
3561
4238
|
continue;
|
|
3562
4239
|
}
|
|
@@ -3578,7 +4255,7 @@ function detect_module_roots(project_root) {
|
|
|
3578
4255
|
}
|
|
3579
4256
|
|
|
3580
4257
|
// src/scripts/_lib/model_tier.ts
|
|
3581
|
-
import
|
|
4258
|
+
import fs17 from "node:fs";
|
|
3582
4259
|
var TIER_TO_CLAUDE_MODEL = {
|
|
3583
4260
|
frontier: "fable",
|
|
3584
4261
|
high: "opus",
|
|
@@ -3587,8 +4264,8 @@ var TIER_TO_CLAUDE_MODEL = {
|
|
|
3587
4264
|
};
|
|
3588
4265
|
var MODEL_TIER_RE = /^model_tier:\s*"?([a-z]+)"?\s*$/m;
|
|
3589
4266
|
function read_model_tier(skill_md) {
|
|
3590
|
-
if (!
|
|
3591
|
-
const text =
|
|
4267
|
+
if (!fs17.existsSync(skill_md)) return null;
|
|
4268
|
+
const text = fs17.readFileSync(skill_md).toString("utf-8");
|
|
3592
4269
|
if (!text.startsWith("---\n")) return null;
|
|
3593
4270
|
const end = text.indexOf("\n---\n", 4);
|
|
3594
4271
|
if (end === -1) return null;
|
|
@@ -3604,15 +4281,15 @@ function render_native_model_md(text, tier) {
|
|
|
3604
4281
|
}
|
|
3605
4282
|
|
|
3606
4283
|
// src/install/paths.ts
|
|
3607
|
-
import { homedir as
|
|
3608
|
-
import { join as
|
|
4284
|
+
import { homedir as homedir8, tmpdir } from "node:os";
|
|
4285
|
+
import { join as join18 } from "node:path";
|
|
3609
4286
|
var INSTALL_ROOT_SUBPATH = ".event4u/agent-config";
|
|
3610
4287
|
var INSTALL_LOG_FILENAME = "install-log.jsonl";
|
|
3611
4288
|
function resolveHome(home) {
|
|
3612
4289
|
if (home && home.length > 0) {
|
|
3613
4290
|
return home;
|
|
3614
4291
|
}
|
|
3615
|
-
const fromOs =
|
|
4292
|
+
const fromOs = homedir8();
|
|
3616
4293
|
if (!fromOs) {
|
|
3617
4294
|
throw new Error(
|
|
3618
4295
|
"Cannot resolve home directory \u2014 both $HOME (POSIX) and $USERPROFILE (Windows) are unset."
|
|
@@ -3621,14 +4298,14 @@ function resolveHome(home) {
|
|
|
3621
4298
|
return fromOs;
|
|
3622
4299
|
}
|
|
3623
4300
|
function getInstallRoot(home) {
|
|
3624
|
-
return
|
|
4301
|
+
return join18(resolveHome(home), INSTALL_ROOT_SUBPATH);
|
|
3625
4302
|
}
|
|
3626
4303
|
function getLogPath(home) {
|
|
3627
|
-
return
|
|
4304
|
+
return join18(getInstallRoot(home), INSTALL_LOG_FILENAME);
|
|
3628
4305
|
}
|
|
3629
4306
|
|
|
3630
4307
|
// src/scripts/install.ts
|
|
3631
|
-
var _HERE =
|
|
4308
|
+
var _HERE = fileURLToPath3(import.meta.url);
|
|
3632
4309
|
var SystemExitError = class extends Error {
|
|
3633
4310
|
constructor(code) {
|
|
3634
4311
|
super(`system-exit-${code}`);
|
|
@@ -3644,43 +4321,43 @@ var ArgparseExit = class extends Error {
|
|
|
3644
4321
|
code;
|
|
3645
4322
|
};
|
|
3646
4323
|
function expanduser3(p) {
|
|
3647
|
-
if (p === "~") return
|
|
4324
|
+
if (p === "~") return os7.homedir();
|
|
3648
4325
|
if (p.startsWith("~/") || p.startsWith("~\\")) {
|
|
3649
|
-
return
|
|
4326
|
+
return path18.join(os7.homedir(), p.slice(2));
|
|
3650
4327
|
}
|
|
3651
4328
|
return p;
|
|
3652
4329
|
}
|
|
3653
4330
|
function isFile(p) {
|
|
3654
4331
|
try {
|
|
3655
|
-
return
|
|
4332
|
+
return fs18.statSync(p).isFile();
|
|
3656
4333
|
} catch {
|
|
3657
4334
|
return false;
|
|
3658
4335
|
}
|
|
3659
4336
|
}
|
|
3660
4337
|
function isDir(p) {
|
|
3661
4338
|
try {
|
|
3662
|
-
return
|
|
4339
|
+
return fs18.statSync(p).isDirectory();
|
|
3663
4340
|
} catch {
|
|
3664
4341
|
return false;
|
|
3665
4342
|
}
|
|
3666
4343
|
}
|
|
3667
4344
|
function isSymlink(p) {
|
|
3668
4345
|
try {
|
|
3669
|
-
return
|
|
4346
|
+
return fs18.lstatSync(p).isSymbolicLink();
|
|
3670
4347
|
} catch {
|
|
3671
4348
|
return false;
|
|
3672
4349
|
}
|
|
3673
4350
|
}
|
|
3674
4351
|
function readText(p) {
|
|
3675
|
-
return
|
|
4352
|
+
return fs18.readFileSync(p, "utf-8");
|
|
3676
4353
|
}
|
|
3677
4354
|
function writeText(p, content) {
|
|
3678
|
-
|
|
4355
|
+
fs18.writeFileSync(p, content, "utf-8");
|
|
3679
4356
|
}
|
|
3680
4357
|
function sortedGlobStems(directory, suffix) {
|
|
3681
4358
|
let entries;
|
|
3682
4359
|
try {
|
|
3683
|
-
entries =
|
|
4360
|
+
entries = fs18.readdirSync(directory);
|
|
3684
4361
|
} catch {
|
|
3685
4362
|
return [];
|
|
3686
4363
|
}
|
|
@@ -3700,34 +4377,34 @@ function sortedGlobStems(directory, suffix) {
|
|
|
3700
4377
|
function countZips(directory) {
|
|
3701
4378
|
if (!isDir(directory)) return 0;
|
|
3702
4379
|
let n = 0;
|
|
3703
|
-
for (const name of
|
|
4380
|
+
for (const name of fs18.readdirSync(directory)) {
|
|
3704
4381
|
if (name.endsWith(".zip")) n += 1;
|
|
3705
4382
|
}
|
|
3706
4383
|
return n;
|
|
3707
4384
|
}
|
|
3708
4385
|
function atomicWrite0644(target, body, prefix) {
|
|
3709
|
-
const dir =
|
|
3710
|
-
const tmpName =
|
|
4386
|
+
const dir = path18.dirname(target);
|
|
4387
|
+
const tmpName = path18.join(
|
|
3711
4388
|
dir,
|
|
3712
4389
|
`${prefix}${process2.pid}.${crypto5.randomBytes(6).toString("hex")}.yml.tmp`
|
|
3713
4390
|
);
|
|
3714
4391
|
let fd = null;
|
|
3715
4392
|
try {
|
|
3716
|
-
fd =
|
|
3717
|
-
|
|
3718
|
-
|
|
4393
|
+
fd = fs18.openSync(tmpName, "wx", 420);
|
|
4394
|
+
fs18.writeFileSync(fd, body, "utf-8");
|
|
4395
|
+
fs18.closeSync(fd);
|
|
3719
4396
|
fd = null;
|
|
3720
|
-
|
|
3721
|
-
|
|
4397
|
+
fs18.chmodSync(tmpName, 420);
|
|
4398
|
+
fs18.renameSync(tmpName, target);
|
|
3722
4399
|
} catch (err) {
|
|
3723
4400
|
if (fd !== null) {
|
|
3724
4401
|
try {
|
|
3725
|
-
|
|
4402
|
+
fs18.closeSync(fd);
|
|
3726
4403
|
} catch {
|
|
3727
4404
|
}
|
|
3728
4405
|
}
|
|
3729
4406
|
try {
|
|
3730
|
-
|
|
4407
|
+
fs18.unlinkSync(tmpName);
|
|
3731
4408
|
} catch {
|
|
3732
4409
|
}
|
|
3733
4410
|
throw err;
|
|
@@ -3762,12 +4439,12 @@ var LEGACY_SETTINGS_FILE = ".agent-settings";
|
|
|
3762
4439
|
var LEGACY_BACKUP_FILE = ".agent-settings.backup.key-value";
|
|
3763
4440
|
var SETTINGS_SUBDIR = ["agents", "settings"];
|
|
3764
4441
|
function _canonical_settings_target(project_root) {
|
|
3765
|
-
return
|
|
4442
|
+
return path18.join(project_root, ...SETTINGS_SUBDIR, SETTINGS_FILE);
|
|
3766
4443
|
}
|
|
3767
4444
|
function _resolve_settings_read(project_root) {
|
|
3768
4445
|
const canonical = _canonical_settings_target(project_root);
|
|
3769
4446
|
if (pathExists(canonical)) return canonical;
|
|
3770
|
-
const legacy =
|
|
4447
|
+
const legacy = path18.join(project_root, SETTINGS_FILE);
|
|
3771
4448
|
if (pathExists(legacy)) return legacy;
|
|
3772
4449
|
return canonical;
|
|
3773
4450
|
}
|
|
@@ -3777,15 +4454,10 @@ var LEGACY_RENAME_MAP = {
|
|
|
3777
4454
|
open_edited_files: "personal.open_edited_files",
|
|
3778
4455
|
user_name: "personal.user_name",
|
|
3779
4456
|
rtk_installed: "personal.rtk_installed",
|
|
3780
|
-
minimal_output: "personal.minimal_output",
|
|
3781
|
-
play_by_play: "personal.play_by_play",
|
|
3782
|
-
pr_comment_bot_icon: "project.pr_comment_bot_icon",
|
|
3783
|
-
pr_template: "project.pr_template",
|
|
3784
4457
|
upstream_repo: "project.upstream_repo",
|
|
3785
4458
|
improvement_pr_branch_prefix: "project.improvement_pr_branch_prefix",
|
|
3786
4459
|
github_pr_reply_method: "github.pr_reply_method",
|
|
3787
4460
|
eloquent_access_style: "eloquent.access_style",
|
|
3788
|
-
skill_improvement_pipeline: "pipelines.skill_improvement",
|
|
3789
4461
|
subagent_implementer_model: "subagents.implementer_model",
|
|
3790
4462
|
subagent_judge_model: "subagents.judge_model",
|
|
3791
4463
|
subagent_max_parallel: "subagents.max_parallel"
|
|
@@ -3833,9 +4505,9 @@ function fail(msg) {
|
|
|
3833
4505
|
throw new SystemExitError(1);
|
|
3834
4506
|
}
|
|
3835
4507
|
function detect_package_root(project_root) {
|
|
3836
|
-
const npm_path =
|
|
4508
|
+
const npm_path = path18.join(project_root, "node_modules", "@event4u", "agent-config");
|
|
3837
4509
|
if (isDir(npm_path)) return resolvePath(npm_path);
|
|
3838
|
-
if (pathExists(
|
|
4510
|
+
if (pathExists(path18.join(project_root, "src", "config", "profiles", "minimal.ini"))) {
|
|
3839
4511
|
return project_root;
|
|
3840
4512
|
}
|
|
3841
4513
|
fail(
|
|
@@ -3843,12 +4515,12 @@ function detect_package_root(project_root) {
|
|
|
3843
4515
|
);
|
|
3844
4516
|
}
|
|
3845
4517
|
function detect_package_type(package_root) {
|
|
3846
|
-
if (package_root.split(
|
|
4518
|
+
if (package_root.split(path18.sep).includes("node_modules")) return "npm";
|
|
3847
4519
|
return "local";
|
|
3848
4520
|
}
|
|
3849
4521
|
function detect_package_type_for_project(project_root, package_root) {
|
|
3850
4522
|
const npm_path = resolvePath(
|
|
3851
|
-
|
|
4523
|
+
path18.join(project_root, "node_modules", "@event4u", "agent-config")
|
|
3852
4524
|
);
|
|
3853
4525
|
const package_resolved = resolvePath(package_root);
|
|
3854
4526
|
if (package_resolved === npm_path) return "npm";
|
|
@@ -3872,7 +4544,7 @@ function ensure_directory(p) {
|
|
|
3872
4544
|
mkdirp(p);
|
|
3873
4545
|
}
|
|
3874
4546
|
function write_file(p, content) {
|
|
3875
|
-
ensure_directory(
|
|
4547
|
+
ensure_directory(path18.dirname(p));
|
|
3876
4548
|
writeText(p, content);
|
|
3877
4549
|
}
|
|
3878
4550
|
function read_json_file(p) {
|
|
@@ -3893,50 +4565,6 @@ function write_json_file(p, data) {
|
|
|
3893
4565
|
const content = jsonDumpsIndent(data, 4) + "\n";
|
|
3894
4566
|
write_file(p, content);
|
|
3895
4567
|
}
|
|
3896
|
-
function _isPlainObject(v) {
|
|
3897
|
-
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
3898
|
-
}
|
|
3899
|
-
function deepcopy(v) {
|
|
3900
|
-
if (v === null || typeof v !== "object") return v;
|
|
3901
|
-
if (Array.isArray(v)) return v.map((x) => deepcopy(x));
|
|
3902
|
-
const out = {};
|
|
3903
|
-
for (const k of Object.keys(v)) {
|
|
3904
|
-
out[k] = deepcopy(v[k]);
|
|
3905
|
-
}
|
|
3906
|
-
return out;
|
|
3907
|
-
}
|
|
3908
|
-
function deep_merge(base, overlay) {
|
|
3909
|
-
const result = deepcopy(base);
|
|
3910
|
-
for (const key of Object.keys(overlay)) {
|
|
3911
|
-
const value = overlay[key];
|
|
3912
|
-
if (Object.prototype.hasOwnProperty.call(result, key) && _isPlainObject(result[key]) && _isPlainObject(value)) {
|
|
3913
|
-
result[key] = deep_merge(
|
|
3914
|
-
result[key],
|
|
3915
|
-
value
|
|
3916
|
-
);
|
|
3917
|
-
} else {
|
|
3918
|
-
result[key] = deepcopy(value);
|
|
3919
|
-
}
|
|
3920
|
-
}
|
|
3921
|
-
return result;
|
|
3922
|
-
}
|
|
3923
|
-
function jsonEqual(a, b) {
|
|
3924
|
-
if (a === b) return true;
|
|
3925
|
-
if (typeof a !== typeof b) return false;
|
|
3926
|
-
if (Array.isArray(a) || Array.isArray(b)) {
|
|
3927
|
-
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
3928
|
-
return a.every((v, i) => jsonEqual(v, b[i]));
|
|
3929
|
-
}
|
|
3930
|
-
if (_isPlainObject(a) && _isPlainObject(b)) {
|
|
3931
|
-
const ka = Object.keys(a);
|
|
3932
|
-
const kb = Object.keys(b);
|
|
3933
|
-
if (ka.length !== kb.length) return false;
|
|
3934
|
-
return ka.every(
|
|
3935
|
-
(k) => Object.prototype.hasOwnProperty.call(b, k) && jsonEqual(a[k], b[k])
|
|
3936
|
-
);
|
|
3937
|
-
}
|
|
3938
|
-
return false;
|
|
3939
|
-
}
|
|
3940
4568
|
function merge_json_file(p, new_data, _force, label) {
|
|
3941
4569
|
const new_entries = build_merge_entries(label, new_data);
|
|
3942
4570
|
if (!pathExists(p)) {
|
|
@@ -3945,7 +4573,7 @@ function merge_json_file(p, new_data, _force, label) {
|
|
|
3945
4573
|
return new_entries;
|
|
3946
4574
|
}
|
|
3947
4575
|
const existing = read_json_file(p);
|
|
3948
|
-
const merged =
|
|
4576
|
+
const merged = mergeHostConfig(existing, new_data, HOOK_SIGNATURES[label] ?? "", deepMerge);
|
|
3949
4577
|
if (jsonEqual(merged, existing)) {
|
|
3950
4578
|
skip(`${label} already configured`);
|
|
3951
4579
|
return new_entries;
|
|
@@ -4043,7 +4671,7 @@ function _append_unknown_legacy(rendered, legacy_values, unknown_keys) {
|
|
|
4043
4671
|
return rendered + "\n" + suffix;
|
|
4044
4672
|
}
|
|
4045
4673
|
function _migrate_legacy_if_present(project_root, template_body) {
|
|
4046
|
-
const legacy_target =
|
|
4674
|
+
const legacy_target = path18.join(project_root, LEGACY_SETTINGS_FILE);
|
|
4047
4675
|
if (!isFile(legacy_target)) return null;
|
|
4048
4676
|
const legacy_text = readText(legacy_target);
|
|
4049
4677
|
const [values, unknown] = _parse_legacy_settings(legacy_text);
|
|
@@ -4058,9 +4686,9 @@ function _migrate_legacy_if_present(project_root, template_body) {
|
|
|
4058
4686
|
}
|
|
4059
4687
|
}
|
|
4060
4688
|
rendered = _append_unknown_legacy(rendered, values, unknown);
|
|
4061
|
-
const backup_target =
|
|
4689
|
+
const backup_target = path18.join(project_root, LEGACY_BACKUP_FILE);
|
|
4062
4690
|
writeText(backup_target, legacy_text);
|
|
4063
|
-
|
|
4691
|
+
fs18.unlinkSync(legacy_target);
|
|
4064
4692
|
info(`Migrated legacy ${LEGACY_SETTINGS_FILE} \u2192 ${SETTINGS_FILE}`);
|
|
4065
4693
|
info(`Backup saved to ${LEGACY_BACKUP_FILE}`);
|
|
4066
4694
|
if (unknown.length > 0) {
|
|
@@ -4095,7 +4723,7 @@ function _render_template(template, profile_values) {
|
|
|
4095
4723
|
return body;
|
|
4096
4724
|
}
|
|
4097
4725
|
function _load_valid_user_types(package_root) {
|
|
4098
|
-
const directory =
|
|
4726
|
+
const directory = path18.join(package_root, USER_TYPES_DIR);
|
|
4099
4727
|
if (!isDir(directory)) return [];
|
|
4100
4728
|
return sortedGlobStems(directory, ".yml");
|
|
4101
4729
|
}
|
|
@@ -4152,8 +4780,8 @@ function splitlinesKeepends(text) {
|
|
|
4152
4780
|
}
|
|
4153
4781
|
function ensure_agent_settings(project_root, package_root, profile, force, user_type = "", packs = null) {
|
|
4154
4782
|
const target = _canonical_settings_target(project_root);
|
|
4155
|
-
const profile_source =
|
|
4156
|
-
const template_source =
|
|
4783
|
+
const profile_source = path18.join(package_root, "src", "config", "profiles", `${profile}.ini`);
|
|
4784
|
+
const template_source = path18.join(package_root, "src", "config", "agent-settings.template.yml");
|
|
4157
4785
|
if (!pathExists(profile_source)) fail(`Missing profile preset: ${profile_source}`);
|
|
4158
4786
|
if (!pathExists(template_source)) fail(`Missing settings template: ${template_source}`);
|
|
4159
4787
|
const template = readText(template_source);
|
|
@@ -4167,21 +4795,21 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
|
|
|
4167
4795
|
if (profile_values["rule_loading_tier"] !== profile) {
|
|
4168
4796
|
const got = "rule_loading_tier" in profile_values ? `'${profile_values["rule_loading_tier"]}'` : "None";
|
|
4169
4797
|
fail(
|
|
4170
|
-
`Profile preset ${
|
|
4798
|
+
`Profile preset ${path18.basename(profile_source)} has rule_loading_tier=${got} but --profile=${profile}`
|
|
4171
4799
|
);
|
|
4172
4800
|
}
|
|
4173
4801
|
profile_values["user_type"] = _validate_user_type(package_root, user_type);
|
|
4174
4802
|
let template_body = _render_template(template, profile_values);
|
|
4175
4803
|
template_body = _inject_packs(template_body, packs ?? []);
|
|
4176
|
-
const legacy_root =
|
|
4804
|
+
const legacy_root = path18.join(project_root, SETTINGS_FILE);
|
|
4177
4805
|
if (isFile(legacy_root) && !pathExists(target)) {
|
|
4178
|
-
mkdirp(
|
|
4806
|
+
mkdirp(path18.dirname(target));
|
|
4179
4807
|
writeText(target, readText(legacy_root));
|
|
4180
|
-
|
|
4808
|
+
fs18.unlinkSync(legacy_root);
|
|
4181
4809
|
success(`Migrated ${SETTINGS_FILE} \u2192 agents/settings/${SETTINGS_FILE} (ADR-038)`);
|
|
4182
4810
|
return;
|
|
4183
4811
|
}
|
|
4184
|
-
const legacy_target =
|
|
4812
|
+
const legacy_target = path18.join(project_root, LEGACY_SETTINGS_FILE);
|
|
4185
4813
|
if (isFile(legacy_target) && pathExists(target)) {
|
|
4186
4814
|
warn(
|
|
4187
4815
|
`Both ${SETTINGS_FILE} and legacy ${LEGACY_SETTINGS_FILE} exist. Skipping migration to avoid overwriting ${SETTINGS_FILE}. Delete one of them manually and re-run.`
|
|
@@ -4198,7 +4826,7 @@ function ensure_agent_settings(project_root, package_root, profile, force, user_
|
|
|
4198
4826
|
skip(`${SETTINGS_FILE} already exists`);
|
|
4199
4827
|
return;
|
|
4200
4828
|
}
|
|
4201
|
-
mkdirp(
|
|
4829
|
+
mkdirp(path18.dirname(target));
|
|
4202
4830
|
write_file(target, template_body);
|
|
4203
4831
|
const user_type_value = profile_values["user_type"] ?? "";
|
|
4204
4832
|
const suffix = user_type_value ? `, user_type=${user_type_value}` : "";
|
|
@@ -4211,7 +4839,7 @@ function ensure_vscode_bridge(project_root, package_type, force) {
|
|
|
4211
4839
|
const plugin_path = plugin_paths[package_type] ?? "./plugin/agent-config";
|
|
4212
4840
|
const bridge = { "chat.pluginLocations": { [plugin_path]: true } };
|
|
4213
4841
|
return merge_json_file(
|
|
4214
|
-
|
|
4842
|
+
path18.join(project_root, ".vscode", "settings.json"),
|
|
4215
4843
|
bridge,
|
|
4216
4844
|
force,
|
|
4217
4845
|
".vscode/settings.json"
|
|
@@ -4220,14 +4848,14 @@ function ensure_vscode_bridge(project_root, package_type, force) {
|
|
|
4220
4848
|
function ensure_augment_bridge(project_root, force) {
|
|
4221
4849
|
const bridge = { enabledPlugins: { "agent-config@event4u": true } };
|
|
4222
4850
|
return merge_json_file(
|
|
4223
|
-
|
|
4851
|
+
path18.join(project_root, ".augment", "settings.json"),
|
|
4224
4852
|
bridge,
|
|
4225
4853
|
force,
|
|
4226
4854
|
".augment/settings.json"
|
|
4227
4855
|
);
|
|
4228
4856
|
}
|
|
4229
|
-
var AUGMENT_USER_DIR =
|
|
4230
|
-
var AUGMENT_USER_HOOKS_DIR =
|
|
4857
|
+
var AUGMENT_USER_DIR = path18.join(os7.homedir(), ".augment");
|
|
4858
|
+
var AUGMENT_USER_HOOKS_DIR = path18.join(AUGMENT_USER_DIR, "hooks");
|
|
4231
4859
|
var AUGMENT_DISPATCHER_TRAMPOLINE = "augment-dispatcher.sh";
|
|
4232
4860
|
var AUGMENT_LEGACY_TRAMPOLINES = [
|
|
4233
4861
|
"augment-chat-history.sh",
|
|
@@ -4236,29 +4864,29 @@ var AUGMENT_LEGACY_TRAMPOLINES = [
|
|
|
4236
4864
|
"augment-context-hygiene.sh"
|
|
4237
4865
|
];
|
|
4238
4866
|
function _deploy_augment_trampoline(package_root, name, force) {
|
|
4239
|
-
const src =
|
|
4867
|
+
const src = path18.join(package_root, "scripts", "hooks", name);
|
|
4240
4868
|
if (!pathExists(src)) {
|
|
4241
4869
|
skip(`augment trampoline missing in package: ${src}`);
|
|
4242
4870
|
return null;
|
|
4243
4871
|
}
|
|
4244
4872
|
mkdirp(AUGMENT_USER_HOOKS_DIR);
|
|
4245
|
-
const dst =
|
|
4873
|
+
const dst = path18.join(AUGMENT_USER_HOOKS_DIR, name);
|
|
4246
4874
|
const src_text = readText(src);
|
|
4247
4875
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
4248
4876
|
skip(`~/.augment/hooks/${name} already up to date`);
|
|
4249
4877
|
} else {
|
|
4250
4878
|
writeText(dst, src_text);
|
|
4251
|
-
|
|
4879
|
+
fs18.chmodSync(dst, 493);
|
|
4252
4880
|
success(`~/.augment/hooks/${name} installed`);
|
|
4253
4881
|
}
|
|
4254
4882
|
return dst;
|
|
4255
4883
|
}
|
|
4256
4884
|
function _remove_legacy_augment_trampolines() {
|
|
4257
4885
|
for (const name of AUGMENT_LEGACY_TRAMPOLINES) {
|
|
4258
|
-
const legacy =
|
|
4886
|
+
const legacy = path18.join(AUGMENT_USER_HOOKS_DIR, name);
|
|
4259
4887
|
try {
|
|
4260
4888
|
if (isFile(legacy)) {
|
|
4261
|
-
|
|
4889
|
+
fs18.unlinkSync(legacy);
|
|
4262
4890
|
skip(`removed legacy ~/.augment/hooks/${name}`);
|
|
4263
4891
|
}
|
|
4264
4892
|
} catch (err) {
|
|
@@ -4278,7 +4906,7 @@ function ensure_augment_user_hooks(package_root, force) {
|
|
|
4278
4906
|
}
|
|
4279
4907
|
const settings_patch = { hooks: per_event };
|
|
4280
4908
|
return merge_json_file(
|
|
4281
|
-
|
|
4909
|
+
path18.join(AUGMENT_USER_DIR, "settings.json"),
|
|
4282
4910
|
settings_patch,
|
|
4283
4911
|
force,
|
|
4284
4912
|
"~/.augment/settings.json"
|
|
@@ -4293,7 +4921,7 @@ function _heal_legacy_claude_plugin_ids(p) {
|
|
|
4293
4921
|
if (!pathExists(p)) return [];
|
|
4294
4922
|
const data = read_json_file(p);
|
|
4295
4923
|
const enabled = data["enabledPlugins"];
|
|
4296
|
-
if (!
|
|
4924
|
+
if (!isPlainObject(enabled)) return [];
|
|
4297
4925
|
const removed = CLAUDE_LEGACY_PLUGIN_IDS.filter((pid) => pid in enabled);
|
|
4298
4926
|
if (removed.length === 0) return [];
|
|
4299
4927
|
for (const pid of removed) {
|
|
@@ -4303,7 +4931,7 @@ function _heal_legacy_claude_plugin_ids(p) {
|
|
|
4303
4931
|
return removed;
|
|
4304
4932
|
}
|
|
4305
4933
|
function ensure_claude_bridge(project_root, force) {
|
|
4306
|
-
const target =
|
|
4934
|
+
const target = path18.join(project_root, ".claude", "settings.json");
|
|
4307
4935
|
const healed = _heal_legacy_claude_plugin_ids(target);
|
|
4308
4936
|
for (const pid of healed) success(`.claude/settings.json: removed stale plugin id \`${pid}\``);
|
|
4309
4937
|
const bridge = withHostEnv({ enabledPlugins: { [CLAUDE_PLUGIN_ID]: true } }, project_root, success);
|
|
@@ -4321,29 +4949,29 @@ function ensure_cursor_bridge(project_root, force) {
|
|
|
4321
4949
|
}
|
|
4322
4950
|
const bridge = { version: 1, hooks };
|
|
4323
4951
|
return merge_json_file(
|
|
4324
|
-
|
|
4952
|
+
path18.join(project_root, ".cursor", "hooks.json"),
|
|
4325
4953
|
bridge,
|
|
4326
4954
|
force,
|
|
4327
4955
|
".cursor/hooks.json"
|
|
4328
4956
|
);
|
|
4329
4957
|
}
|
|
4330
|
-
var CURSOR_USER_DIR =
|
|
4331
|
-
var CURSOR_USER_HOOKS_DIR =
|
|
4958
|
+
var CURSOR_USER_DIR = path18.join(os7.homedir(), ".cursor");
|
|
4959
|
+
var CURSOR_USER_HOOKS_DIR = path18.join(CURSOR_USER_DIR, "hooks");
|
|
4332
4960
|
var CURSOR_DISPATCHER_TRAMPOLINE = "cursor-dispatcher.sh";
|
|
4333
4961
|
function ensure_cursor_user_hooks(package_root, force) {
|
|
4334
|
-
const src =
|
|
4962
|
+
const src = path18.join(package_root, "scripts", "hooks", CURSOR_DISPATCHER_TRAMPOLINE);
|
|
4335
4963
|
if (!pathExists(src)) {
|
|
4336
4964
|
skip(`cursor trampoline missing in package: ${src}`);
|
|
4337
4965
|
return [];
|
|
4338
4966
|
}
|
|
4339
4967
|
mkdirp(CURSOR_USER_HOOKS_DIR);
|
|
4340
|
-
const dst =
|
|
4968
|
+
const dst = path18.join(CURSOR_USER_HOOKS_DIR, CURSOR_DISPATCHER_TRAMPOLINE);
|
|
4341
4969
|
const src_text = readText(src);
|
|
4342
4970
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
4343
4971
|
skip(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
4344
4972
|
} else {
|
|
4345
4973
|
writeText(dst, src_text);
|
|
4346
|
-
|
|
4974
|
+
fs18.chmodSync(dst, 493);
|
|
4347
4975
|
success(`~/.cursor/hooks/${CURSOR_DISPATCHER_TRAMPOLINE} installed`);
|
|
4348
4976
|
}
|
|
4349
4977
|
const hooks = {};
|
|
@@ -4352,7 +4980,7 @@ function ensure_cursor_user_hooks(package_root, force) {
|
|
|
4352
4980
|
}
|
|
4353
4981
|
const settings_patch = { version: 1, hooks };
|
|
4354
4982
|
return merge_json_file(
|
|
4355
|
-
|
|
4983
|
+
path18.join(CURSOR_USER_DIR, "hooks.json"),
|
|
4356
4984
|
settings_patch,
|
|
4357
4985
|
force,
|
|
4358
4986
|
"~/.cursor/hooks.json"
|
|
@@ -4387,12 +5015,12 @@ exit 0
|
|
|
4387
5015
|
`;
|
|
4388
5016
|
}
|
|
4389
5017
|
function ensure_cline_bridge(project_root, force) {
|
|
4390
|
-
const hooks_dir =
|
|
5018
|
+
const hooks_dir = path18.join(project_root, ".clinerules", "hooks");
|
|
4391
5019
|
mkdirp(hooks_dir);
|
|
4392
5020
|
const workspace_quoted = shlexQuote(resolvePath(project_root));
|
|
4393
5021
|
let written = 0;
|
|
4394
5022
|
for (const { slot, native } of hostBindings("cline")) {
|
|
4395
|
-
const target =
|
|
5023
|
+
const target = path18.join(hooks_dir, native);
|
|
4396
5024
|
const body = clineProjectHookBody(native, slot, workspace_quoted);
|
|
4397
5025
|
if (pathExists(target) && readText(target) === body && !force) {
|
|
4398
5026
|
continue;
|
|
@@ -4402,7 +5030,7 @@ function ensure_cline_bridge(project_root, force) {
|
|
|
4402
5030
|
continue;
|
|
4403
5031
|
}
|
|
4404
5032
|
writeText(target, body);
|
|
4405
|
-
|
|
5033
|
+
fs18.chmodSync(target, 493);
|
|
4406
5034
|
written += 1;
|
|
4407
5035
|
}
|
|
4408
5036
|
if (written) {
|
|
@@ -4411,27 +5039,27 @@ function ensure_cline_bridge(project_root, force) {
|
|
|
4411
5039
|
skip(".clinerules/hooks/ already up to date");
|
|
4412
5040
|
}
|
|
4413
5041
|
}
|
|
4414
|
-
var CLINE_USER_DIR =
|
|
5042
|
+
var CLINE_USER_DIR = path18.join(os7.homedir(), "Documents", "Cline", "Hooks");
|
|
4415
5043
|
var CLINE_DISPATCHER_TRAMPOLINE = "cline-dispatcher.sh";
|
|
4416
5044
|
function ensure_cline_user_hooks(package_root, force) {
|
|
4417
|
-
const src =
|
|
5045
|
+
const src = path18.join(package_root, "scripts", "hooks", CLINE_DISPATCHER_TRAMPOLINE);
|
|
4418
5046
|
if (!pathExists(src)) {
|
|
4419
5047
|
skip(`cline trampoline missing in package: ${src}`);
|
|
4420
5048
|
return;
|
|
4421
5049
|
}
|
|
4422
5050
|
mkdirp(CLINE_USER_DIR);
|
|
4423
|
-
const trampoline =
|
|
5051
|
+
const trampoline = path18.join(CLINE_USER_DIR, CLINE_DISPATCHER_TRAMPOLINE);
|
|
4424
5052
|
const src_text = readText(src);
|
|
4425
5053
|
if (pathExists(trampoline) && readText(trampoline) === src_text && !force) {
|
|
4426
5054
|
skip(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
4427
5055
|
} else {
|
|
4428
5056
|
writeText(trampoline, src_text);
|
|
4429
|
-
|
|
5057
|
+
fs18.chmodSync(trampoline, 493);
|
|
4430
5058
|
success(`~/Documents/Cline/Hooks/${CLINE_DISPATCHER_TRAMPOLINE} installed`);
|
|
4431
5059
|
}
|
|
4432
5060
|
const trampoline_quoted = shlexQuote(trampoline);
|
|
4433
5061
|
for (const { slot, native } of hostBindings("cline")) {
|
|
4434
|
-
const wrapper =
|
|
5062
|
+
const wrapper = path18.join(CLINE_USER_DIR, native);
|
|
4435
5063
|
const body = `#!/usr/bin/env bash
|
|
4436
5064
|
# Generated by event4u/agent-config \u2014 DO NOT EDIT.
|
|
4437
5065
|
# User-scope Cline hook for ${native} \u2192 agent-config ${slot}.
|
|
@@ -4441,7 +5069,7 @@ exec ${trampoline_quoted} ${slot} ${native}
|
|
|
4441
5069
|
continue;
|
|
4442
5070
|
}
|
|
4443
5071
|
writeText(wrapper, body);
|
|
4444
|
-
|
|
5072
|
+
fs18.chmodSync(wrapper, 493);
|
|
4445
5073
|
}
|
|
4446
5074
|
}
|
|
4447
5075
|
function _windsurf_dispatch_command(ac_event, native) {
|
|
@@ -4457,29 +5085,29 @@ function ensure_windsurf_bridge(project_root, force) {
|
|
|
4457
5085
|
}
|
|
4458
5086
|
const bridge = { hooks };
|
|
4459
5087
|
return merge_json_file(
|
|
4460
|
-
|
|
5088
|
+
path18.join(project_root, ".windsurf", "hooks.json"),
|
|
4461
5089
|
bridge,
|
|
4462
5090
|
force,
|
|
4463
5091
|
".windsurf/hooks.json"
|
|
4464
5092
|
);
|
|
4465
5093
|
}
|
|
4466
|
-
var WINDSURF_USER_DIR =
|
|
4467
|
-
var WINDSURF_USER_HOOKS_DIR =
|
|
5094
|
+
var WINDSURF_USER_DIR = path18.join(os7.homedir(), ".codeium", "windsurf");
|
|
5095
|
+
var WINDSURF_USER_HOOKS_DIR = path18.join(WINDSURF_USER_DIR, "hooks");
|
|
4468
5096
|
var WINDSURF_DISPATCHER_TRAMPOLINE = "windsurf-dispatcher.sh";
|
|
4469
5097
|
function ensure_windsurf_user_hooks(package_root, force) {
|
|
4470
|
-
const src =
|
|
5098
|
+
const src = path18.join(package_root, "scripts", "hooks", WINDSURF_DISPATCHER_TRAMPOLINE);
|
|
4471
5099
|
if (!pathExists(src)) {
|
|
4472
5100
|
skip(`windsurf trampoline missing in package: ${src}`);
|
|
4473
5101
|
return [];
|
|
4474
5102
|
}
|
|
4475
5103
|
mkdirp(WINDSURF_USER_HOOKS_DIR);
|
|
4476
|
-
const dst =
|
|
5104
|
+
const dst = path18.join(WINDSURF_USER_HOOKS_DIR, WINDSURF_DISPATCHER_TRAMPOLINE);
|
|
4477
5105
|
const src_text = readText(src);
|
|
4478
5106
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
4479
5107
|
skip(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
4480
5108
|
} else {
|
|
4481
5109
|
writeText(dst, src_text);
|
|
4482
|
-
|
|
5110
|
+
fs18.chmodSync(dst, 493);
|
|
4483
5111
|
success(`~/.codeium/windsurf/hooks/${WINDSURF_DISPATCHER_TRAMPOLINE} installed`);
|
|
4484
5112
|
}
|
|
4485
5113
|
const hooks = {};
|
|
@@ -4491,7 +5119,7 @@ function ensure_windsurf_user_hooks(package_root, force) {
|
|
|
4491
5119
|
}
|
|
4492
5120
|
const settings_patch = { hooks };
|
|
4493
5121
|
return merge_json_file(
|
|
4494
|
-
|
|
5122
|
+
path18.join(WINDSURF_USER_DIR, "hooks.json"),
|
|
4495
5123
|
settings_patch,
|
|
4496
5124
|
force,
|
|
4497
5125
|
"~/.codeium/windsurf/hooks.json"
|
|
@@ -4513,43 +5141,43 @@ function _gemini_hooks_dict(command_factory) {
|
|
|
4513
5141
|
function ensure_gemini_bridge(project_root, force) {
|
|
4514
5142
|
const bridge = { hooks: _gemini_hooks_dict(_gemini_dispatch_command) };
|
|
4515
5143
|
return merge_json_file(
|
|
4516
|
-
|
|
5144
|
+
path18.join(project_root, ".gemini", "settings.json"),
|
|
4517
5145
|
bridge,
|
|
4518
5146
|
force,
|
|
4519
5147
|
".gemini/settings.json"
|
|
4520
5148
|
);
|
|
4521
5149
|
}
|
|
4522
|
-
var GEMINI_USER_DIR =
|
|
4523
|
-
var GEMINI_USER_HOOKS_DIR =
|
|
5150
|
+
var GEMINI_USER_DIR = path18.join(os7.homedir(), ".gemini");
|
|
5151
|
+
var GEMINI_USER_HOOKS_DIR = path18.join(GEMINI_USER_DIR, "hooks");
|
|
4524
5152
|
var GEMINI_DISPATCHER_TRAMPOLINE = "gemini-dispatcher.sh";
|
|
4525
5153
|
function ensure_gemini_user_hooks(package_root, force) {
|
|
4526
|
-
const src =
|
|
5154
|
+
const src = path18.join(package_root, "scripts", "hooks", GEMINI_DISPATCHER_TRAMPOLINE);
|
|
4527
5155
|
if (!pathExists(src)) {
|
|
4528
5156
|
skip(`gemini trampoline missing in package: ${src}`);
|
|
4529
5157
|
return [];
|
|
4530
5158
|
}
|
|
4531
5159
|
mkdirp(GEMINI_USER_HOOKS_DIR);
|
|
4532
|
-
const dst =
|
|
5160
|
+
const dst = path18.join(GEMINI_USER_HOOKS_DIR, GEMINI_DISPATCHER_TRAMPOLINE);
|
|
4533
5161
|
const src_text = readText(src);
|
|
4534
5162
|
if (pathExists(dst) && readText(dst) === src_text && !force) {
|
|
4535
5163
|
skip(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} already up to date`);
|
|
4536
5164
|
} else {
|
|
4537
5165
|
writeText(dst, src_text);
|
|
4538
|
-
|
|
5166
|
+
fs18.chmodSync(dst, 493);
|
|
4539
5167
|
success(`~/.gemini/hooks/${GEMINI_DISPATCHER_TRAMPOLINE} installed`);
|
|
4540
5168
|
}
|
|
4541
5169
|
const settings_patch = {
|
|
4542
5170
|
hooks: _gemini_hooks_dict((ac_event, native) => `${dst} ${ac_event} ${native}`)
|
|
4543
5171
|
};
|
|
4544
5172
|
return merge_json_file(
|
|
4545
|
-
|
|
5173
|
+
path18.join(GEMINI_USER_DIR, "settings.json"),
|
|
4546
5174
|
settings_patch,
|
|
4547
5175
|
force,
|
|
4548
5176
|
"~/.gemini/settings.json"
|
|
4549
5177
|
);
|
|
4550
5178
|
}
|
|
4551
5179
|
function ensure_copilot_bridge(project_root, force) {
|
|
4552
|
-
const target =
|
|
5180
|
+
const target = path18.join(project_root, ".github", "plugin", "marketplace.json");
|
|
4553
5181
|
const bridge = {
|
|
4554
5182
|
marketplace: {
|
|
4555
5183
|
name: "event4u-agent-marketplace",
|
|
@@ -4592,7 +5220,7 @@ See \`docs/setup/per-ide/roocode.md\` for the full activation guide.
|
|
|
4592
5220
|
Run \`./agent-config --help\` for available commands.
|
|
4593
5221
|
`;
|
|
4594
5222
|
function ensure_roocode_bridge(project_root, force) {
|
|
4595
|
-
const target =
|
|
5223
|
+
const target = path18.join(project_root, ".roo", "rules", "agent-config.md");
|
|
4596
5224
|
if (pathExists(target) && !force) {
|
|
4597
5225
|
skip(".roo/rules/agent-config.md already exists");
|
|
4598
5226
|
return;
|
|
@@ -4614,7 +5242,7 @@ To wire Claude Desktop to this project's rules, run:
|
|
|
4614
5242
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
4615
5243
|
`;
|
|
4616
5244
|
function ensure_claude_desktop_bridge(project_root, force) {
|
|
4617
|
-
const target =
|
|
5245
|
+
const target = path18.join(project_root, ".claude-desktop", "agent-config.md");
|
|
4618
5246
|
if (pathExists(target) && !force) {
|
|
4619
5247
|
skip(".claude-desktop/agent-config.md already exists");
|
|
4620
5248
|
return;
|
|
@@ -4639,7 +5267,7 @@ Or pass \`--read .aider/agent-config.md\` on the command line.
|
|
|
4639
5267
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
4640
5268
|
`;
|
|
4641
5269
|
function ensure_aider_bridge(project_root, force) {
|
|
4642
|
-
const target =
|
|
5270
|
+
const target = path18.join(project_root, ".aider", "agent-config.md");
|
|
4643
5271
|
if (pathExists(target) && !force) {
|
|
4644
5272
|
skip(".aider/agent-config.md already exists");
|
|
4645
5273
|
return;
|
|
@@ -4658,7 +5286,7 @@ developers where the rules and skills live.
|
|
|
4658
5286
|
Canonical rule and skill source: \`.augment/\` (see project \`AGENTS.md\`).
|
|
4659
5287
|
`;
|
|
4660
5288
|
function ensure_codex_bridge(project_root, force) {
|
|
4661
|
-
const target =
|
|
5289
|
+
const target = path18.join(project_root, ".codex", "agent-config.md");
|
|
4662
5290
|
if (pathExists(target) && !force) {
|
|
4663
5291
|
skip(".codex/agent-config.md already exists");
|
|
4664
5292
|
return;
|
|
@@ -4676,7 +5304,7 @@ rules per session. The canonical rule and skill source lives under
|
|
|
4676
5304
|
orientation).
|
|
4677
5305
|
`;
|
|
4678
5306
|
function ensure_continue_bridge(project_root, force) {
|
|
4679
|
-
const target =
|
|
5307
|
+
const target = path18.join(project_root, ".continue", "rules", "agent-config.md");
|
|
4680
5308
|
if (pathExists(target) && !force) {
|
|
4681
5309
|
skip(".continue/rules/agent-config.md already exists");
|
|
4682
5310
|
return;
|
|
@@ -4707,7 +5335,7 @@ orientation).
|
|
|
4707
5335
|
See \`docs/setup/per-ide/kilocode.md\` for the full activation guide.
|
|
4708
5336
|
`;
|
|
4709
5337
|
function ensure_kilocode_bridge(project_root, force) {
|
|
4710
|
-
const target =
|
|
5338
|
+
const target = path18.join(project_root, ".kilocode", "rules", "agent-config.md");
|
|
4711
5339
|
if (pathExists(target) && !force) {
|
|
4712
5340
|
skip(".kilocode/rules/agent-config.md already exists");
|
|
4713
5341
|
return;
|
|
@@ -4734,7 +5362,7 @@ canonical source (or symlink it):
|
|
|
4734
5362
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
4735
5363
|
`;
|
|
4736
5364
|
function ensure_zed_bridge(project_root, force) {
|
|
4737
|
-
const target =
|
|
5365
|
+
const target = path18.join(project_root, ".zed", "agent-config.md");
|
|
4738
5366
|
if (pathExists(target) && !force) {
|
|
4739
5367
|
skip(".zed/agent-config.md already exists");
|
|
4740
5368
|
return;
|
|
@@ -4755,7 +5383,7 @@ rules into your JetBrains profile.
|
|
|
4755
5383
|
Canonical rule and skill source: \`.augment/\` (see \`AGENTS.md\`).
|
|
4756
5384
|
`;
|
|
4757
5385
|
function ensure_jetbrains_bridge(project_root, force) {
|
|
4758
|
-
const target =
|
|
5386
|
+
const target = path18.join(project_root, ".jetbrains", "agent-config.md");
|
|
4759
5387
|
if (pathExists(target) && !force) {
|
|
4760
5388
|
skip(".jetbrains/agent-config.md already exists");
|
|
4761
5389
|
return;
|
|
@@ -4786,7 +5414,7 @@ session. The canonical rule and skill source lives under \`.augment/\`
|
|
|
4786
5414
|
See \`docs/setup/per-ide/kiro.md\` for the full activation guide.
|
|
4787
5415
|
`;
|
|
4788
5416
|
function ensure_kiro_bridge(project_root, force) {
|
|
4789
|
-
const target =
|
|
5417
|
+
const target = path18.join(project_root, ".kiro", "steering", "agent-config.md");
|
|
4790
5418
|
if (pathExists(target) && !force) {
|
|
4791
5419
|
skip(".kiro/steering/agent-config.md already exists");
|
|
4792
5420
|
return;
|
|
@@ -4823,35 +5451,35 @@ var SMOKE_BRIDGE_PATHS = {
|
|
|
4823
5451
|
};
|
|
4824
5452
|
function dirHasEntries(p) {
|
|
4825
5453
|
try {
|
|
4826
|
-
return
|
|
5454
|
+
return fs18.readdirSync(p).length > 0;
|
|
4827
5455
|
} catch {
|
|
4828
5456
|
return false;
|
|
4829
5457
|
}
|
|
4830
5458
|
}
|
|
4831
5459
|
function _resolve_tsx_invocation(scriptPath, scriptArgs) {
|
|
4832
5460
|
const binName = process2.platform === "win32" ? "tsx.cmd" : "tsx";
|
|
4833
|
-
let dir =
|
|
5461
|
+
let dir = path18.dirname(scriptPath);
|
|
4834
5462
|
for (; ; ) {
|
|
4835
|
-
const candidate =
|
|
5463
|
+
const candidate = path18.join(dir, "node_modules", ".bin", binName);
|
|
4836
5464
|
if (isFile(candidate)) {
|
|
4837
5465
|
return { command: candidate, args: [scriptPath, ...scriptArgs] };
|
|
4838
5466
|
}
|
|
4839
|
-
const parent =
|
|
5467
|
+
const parent = path18.dirname(dir);
|
|
4840
5468
|
if (parent === dir) break;
|
|
4841
5469
|
dir = parent;
|
|
4842
5470
|
}
|
|
4843
5471
|
return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
|
|
4844
5472
|
}
|
|
4845
5473
|
function _smoke_test_hooks(project_root, package_root) {
|
|
4846
|
-
const dispatcher =
|
|
4847
|
-
const manifest =
|
|
5474
|
+
const dispatcher = path18.join(package_root, "scripts", "hooks", "dispatch_hook.ts");
|
|
5475
|
+
const manifest = path18.join(package_root, "scripts", "hook_manifest.yaml");
|
|
4848
5476
|
if (!isFile(dispatcher) || !isFile(manifest)) return 0;
|
|
4849
5477
|
const failed = [];
|
|
4850
5478
|
const skipped = [];
|
|
4851
5479
|
const passed = [];
|
|
4852
5480
|
for (const [platform, native] of smokeProbeEvents()) {
|
|
4853
5481
|
const rel_bridge = SMOKE_BRIDGE_PATHS[platform] ?? "";
|
|
4854
|
-
const bridge_path = rel_bridge ?
|
|
5482
|
+
const bridge_path = rel_bridge ? path18.join(project_root, rel_bridge) : null;
|
|
4855
5483
|
const bridge_present = Boolean(
|
|
4856
5484
|
bridge_path && (isFile(bridge_path) || isDir(bridge_path) && dirHasEntries(bridge_path))
|
|
4857
5485
|
);
|
|
@@ -4900,7 +5528,7 @@ function _smoke_test_hooks(project_root, package_root) {
|
|
|
4900
5528
|
failed.push(`${platform}: dispatcher did not emit JSON plan`);
|
|
4901
5529
|
continue;
|
|
4902
5530
|
}
|
|
4903
|
-
const concerns =
|
|
5531
|
+
const concerns = isPlainObject(plan) ? plan["concerns"] : void 0;
|
|
4904
5532
|
if (!Array.isArray(concerns)) {
|
|
4905
5533
|
failed.push(`${platform}: plan.concerns missing or not a list`);
|
|
4906
5534
|
continue;
|
|
@@ -4982,47 +5610,6 @@ var PROJECT_BRIDGE_MARKERS = {
|
|
|
4982
5610
|
jetbrains: ".jetbrains/agent-config.md",
|
|
4983
5611
|
kiro: ".kiro/steering/agent-config.md"
|
|
4984
5612
|
};
|
|
4985
|
-
var _CLAUDE_SKILL_BUNDLE = [
|
|
4986
|
-
["dist/agent-src/rules", "rules"],
|
|
4987
|
-
["dist/agent-src/skills", "skills"],
|
|
4988
|
-
["dist/agent-src/commands", "commands"],
|
|
4989
|
-
["dist/agent-src/personas", "personas"]
|
|
4990
|
-
];
|
|
4991
|
-
var GLOBAL_DEPLOY_SOURCES = {
|
|
4992
|
-
"claude-code": _CLAUDE_SKILL_BUNDLE,
|
|
4993
|
-
augment: [
|
|
4994
|
-
["dist/agent-src/rules", "rules"],
|
|
4995
|
-
["dist/agent-src/skills", "skills"],
|
|
4996
|
-
["dist/agent-src/commands", "commands"],
|
|
4997
|
-
["dist/agent-src/contexts", "contexts"],
|
|
4998
|
-
["dist/agent-src/personas", "personas"],
|
|
4999
|
-
["dist/agent-src/templates", "templates"]
|
|
5000
|
-
],
|
|
5001
|
-
cursor: [
|
|
5002
|
-
["dist/agent-src/rules", "rules"],
|
|
5003
|
-
["dist/agent-src/commands", "commands"],
|
|
5004
|
-
["dist/agent-src/personas", "personas"]
|
|
5005
|
-
],
|
|
5006
|
-
windsurf: [["dist/agent-src/rules", "rules"]],
|
|
5007
|
-
cline: [["dist/agent-src/rules", ""]],
|
|
5008
|
-
"gemini-cli": _CLAUDE_SKILL_BUNDLE,
|
|
5009
|
-
codex: _CLAUDE_SKILL_BUNDLE,
|
|
5010
|
-
continue: _CLAUDE_SKILL_BUNDLE,
|
|
5011
|
-
roocode: _CLAUDE_SKILL_BUNDLE,
|
|
5012
|
-
kilocode: _CLAUDE_SKILL_BUNDLE,
|
|
5013
|
-
qoder: _CLAUDE_SKILL_BUNDLE,
|
|
5014
|
-
opencode: _CLAUDE_SKILL_BUNDLE,
|
|
5015
|
-
trae: _CLAUDE_SKILL_BUNDLE,
|
|
5016
|
-
antigravity: _CLAUDE_SKILL_BUNDLE,
|
|
5017
|
-
codebuddy: _CLAUDE_SKILL_BUNDLE,
|
|
5018
|
-
droid: _CLAUDE_SKILL_BUNDLE,
|
|
5019
|
-
warp: _CLAUDE_SKILL_BUNDLE,
|
|
5020
|
-
kiro: [
|
|
5021
|
-
["dist/agent-src/rules", "rules"],
|
|
5022
|
-
["dist/agent-src/skills", "steering"],
|
|
5023
|
-
["dist/agent-src/personas", "personas"]
|
|
5024
|
-
]
|
|
5025
|
-
};
|
|
5026
5613
|
function claudeDesktopMarkerBody(lockfile, anchor, bundles_dir, bundle_count) {
|
|
5027
5614
|
return `# agent-config \u2014 Claude Desktop marker
|
|
5028
5615
|
|
|
@@ -5051,9 +5638,9 @@ To remove this marker, delete this file.
|
|
|
5051
5638
|
`;
|
|
5052
5639
|
}
|
|
5053
5640
|
var _CLAUDE_DESKTOP_BUNDLES_SUBPATH = "claude-desktop/bundles";
|
|
5054
|
-
var GLOBAL_ROOT =
|
|
5055
|
-
var GLOBAL_USER_SETTINGS_PATH =
|
|
5056
|
-
var GLOBAL_AGENT_SETTINGS_PATH =
|
|
5641
|
+
var GLOBAL_ROOT = path18.join(os7.homedir(), ".event4u", "agent-config");
|
|
5642
|
+
var GLOBAL_USER_SETTINGS_PATH = path18.join(GLOBAL_ROOT, ".agent-user.yml");
|
|
5643
|
+
var GLOBAL_AGENT_SETTINGS_PATH = path18.join(GLOBAL_ROOT, ".agent-settings.yml");
|
|
5057
5644
|
function _bridge_marker(tool_id, scope) {
|
|
5058
5645
|
if (scope === "global") return USER_SCOPE_PATHS[tool_id] ?? "";
|
|
5059
5646
|
return PROJECT_BRIDGE_MARKERS[tool_id] ?? "";
|
|
@@ -5099,10 +5686,10 @@ function _load_yaml_doc(p) {
|
|
|
5099
5686
|
return {};
|
|
5100
5687
|
}
|
|
5101
5688
|
const data = yamlSafeLoad(text);
|
|
5102
|
-
return
|
|
5689
|
+
return isPlainObject(data) ? data : {};
|
|
5103
5690
|
}
|
|
5104
5691
|
function _load_default_settings(package_root) {
|
|
5105
|
-
const template_source =
|
|
5692
|
+
const template_source = path18.join(package_root, "src", "config", "agent-settings.template.yml");
|
|
5106
5693
|
if (!pathExists(template_source)) return {};
|
|
5107
5694
|
let text;
|
|
5108
5695
|
try {
|
|
@@ -5112,15 +5699,15 @@ function _load_default_settings(package_root) {
|
|
|
5112
5699
|
}
|
|
5113
5700
|
const rendered = text.split(RULE_LOADING_TIER_PLACEHOLDER).join(DEFAULT_PROFILE).split(USER_TYPE_PLACEHOLDER).join("");
|
|
5114
5701
|
const data = yamlSafeLoad(rendered);
|
|
5115
|
-
return
|
|
5702
|
+
return isPlainObject(data) ? data : {};
|
|
5116
5703
|
}
|
|
5117
5704
|
var RULE_LAYER_CHOICES = ["global", "project", "both-acknowledged"];
|
|
5118
5705
|
function _suppress_rule_layer(project_root, suppress_dir) {
|
|
5119
|
-
const target =
|
|
5706
|
+
const target = path18.join(project_root, ".claude", "settings.local.json");
|
|
5120
5707
|
const existing = pathExists(target) ? read_json_file(target) : {};
|
|
5121
5708
|
let real_dir = suppress_dir;
|
|
5122
5709
|
try {
|
|
5123
|
-
real_dir =
|
|
5710
|
+
real_dir = fs18.realpathSync(suppress_dir);
|
|
5124
5711
|
} catch {
|
|
5125
5712
|
real_dir = suppress_dir;
|
|
5126
5713
|
}
|
|
@@ -5131,8 +5718,7 @@ function _suppress_rule_layer(project_root, suppress_dir) {
|
|
|
5131
5718
|
success(`.claude/settings.local.json: claudeMdExcludes += ${entry}`);
|
|
5132
5719
|
}
|
|
5133
5720
|
function _gate_rule_layer_overlap(project_root, layer, dry_run) {
|
|
5134
|
-
const global_dir =
|
|
5135
|
-
const project_dir = path13.join(project_root, ".claude", "rules");
|
|
5721
|
+
const [global_dir, project_dir] = hostRuleLayerDirs(project_root);
|
|
5136
5722
|
const g = readRuleLayer(global_dir);
|
|
5137
5723
|
const p = readRuleLayer(project_dir);
|
|
5138
5724
|
if (g === null || p === null) return true;
|
|
@@ -5220,9 +5806,9 @@ function detect_scope(cwd) {
|
|
|
5220
5806
|
if (pathExists(_resolve_settings_read(cwd))) {
|
|
5221
5807
|
return ["project", `existing ${SETTINGS_FILE}`];
|
|
5222
5808
|
}
|
|
5223
|
-
const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(
|
|
5224
|
-
const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(
|
|
5225
|
-
const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(
|
|
5809
|
+
const has_manifest = SCOPE_DETECT_MANIFESTS.find((m) => pathExists(path18.join(cwd, m))) ?? null;
|
|
5810
|
+
const has_ai_dir = SCOPE_DETECT_AI_DIRS.find((d) => isDir(path18.join(cwd, d))) ?? null;
|
|
5811
|
+
const has_ai_file = SCOPE_DETECT_AI_FILES.find((f) => pathExists(path18.join(cwd, f))) ?? null;
|
|
5226
5812
|
if (has_manifest && (has_ai_dir || has_ai_file)) {
|
|
5227
5813
|
const marker = has_ai_dir || has_ai_file;
|
|
5228
5814
|
return ["prompt", `manifest (${has_manifest}) + AI-tool config (${marker})`];
|
|
@@ -5243,7 +5829,7 @@ function readLineSyncRaw(promptText) {
|
|
|
5243
5829
|
for (; ; ) {
|
|
5244
5830
|
let n;
|
|
5245
5831
|
try {
|
|
5246
|
-
n =
|
|
5832
|
+
n = fs18.readSync(0, buf, 0, 1, null);
|
|
5247
5833
|
} catch (err) {
|
|
5248
5834
|
const code = err.code;
|
|
5249
5835
|
if (code === "EAGAIN") {
|
|
@@ -5326,26 +5912,26 @@ function _update_installed_tools_manifest(project_root, tools, scope, force, fil
|
|
|
5326
5912
|
}
|
|
5327
5913
|
write_manifest(target, version, entries);
|
|
5328
5914
|
if (!state.QUIET) {
|
|
5329
|
-
const rel = isRelativeTo(target, project_root) ?
|
|
5915
|
+
const rel = isRelativeTo(target, project_root) ? path18.relative(project_root, target) : target;
|
|
5330
5916
|
info(`Manifest updated: ${rel}`);
|
|
5331
5917
|
}
|
|
5332
5918
|
return 0;
|
|
5333
5919
|
}
|
|
5334
5920
|
function isRelativeTo(child, parent) {
|
|
5335
|
-
const rel =
|
|
5336
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
5921
|
+
const rel = path18.relative(parent, child);
|
|
5922
|
+
return rel === "" || !rel.startsWith("..") && !path18.isAbsolute(rel);
|
|
5337
5923
|
}
|
|
5338
5924
|
function _resolve_package_root_for_global() {
|
|
5339
5925
|
const here = resolvePath(_HERE);
|
|
5340
|
-
const candidate =
|
|
5341
|
-
if (!pathExists(
|
|
5926
|
+
const candidate = path18.dirname(path18.dirname(path18.dirname(here)));
|
|
5927
|
+
if (!pathExists(path18.join(candidate, "src", "config", "profiles", "minimal.ini"))) {
|
|
5342
5928
|
fail(
|
|
5343
5929
|
`Could not locate agent-config package root from ${here}. Expected src/config/profiles/minimal.ini at the parent directory.`
|
|
5344
5930
|
);
|
|
5345
5931
|
}
|
|
5346
5932
|
return candidate;
|
|
5347
5933
|
}
|
|
5348
|
-
var CONSUMER_BRIDGE_MARKER_RELPATH =
|
|
5934
|
+
var CONSUMER_BRIDGE_MARKER_RELPATH = path18.join("agents", ".event4u-bridge.yml");
|
|
5349
5935
|
var MIGRATE_LEGACY_YAML_FILES = [".agent-settings.yml", ".agent-user.yml"];
|
|
5350
5936
|
var MIGRATE_LEGACY_TOOL_DIRS = [".augment", ".claude", ".cursor"];
|
|
5351
5937
|
var AGENT_CONFIG_PACKAGE_NAME = "@event4u/agent-config";
|
|
@@ -5353,7 +5939,7 @@ function _is_agent_config_source_repo(project_root) {
|
|
|
5353
5939
|
if (process2.env["AGENT_CONFIG_CONSUMER_MODE"] === "1") {
|
|
5354
5940
|
return [false, "consumer-mode-override"];
|
|
5355
5941
|
}
|
|
5356
|
-
const pkg_json =
|
|
5942
|
+
const pkg_json = path18.join(project_root, "package.json");
|
|
5357
5943
|
if (isFile(pkg_json)) {
|
|
5358
5944
|
let data = {};
|
|
5359
5945
|
try {
|
|
@@ -5361,17 +5947,17 @@ function _is_agent_config_source_repo(project_root) {
|
|
|
5361
5947
|
} catch {
|
|
5362
5948
|
data = {};
|
|
5363
5949
|
}
|
|
5364
|
-
if (
|
|
5950
|
+
if (isPlainObject(data) && data["name"] === AGENT_CONFIG_PACKAGE_NAME) {
|
|
5365
5951
|
return [true, "package.json:name"];
|
|
5366
5952
|
}
|
|
5367
5953
|
}
|
|
5368
|
-
if (isDir(
|
|
5954
|
+
if (isDir(path18.join(project_root, ".agent-src.uncondensed"))) {
|
|
5369
5955
|
return [true, ".agent-src.uncondensed/"];
|
|
5370
5956
|
}
|
|
5371
|
-
const packages_dir =
|
|
5957
|
+
const packages_dir = path18.join(project_root, "packages");
|
|
5372
5958
|
if (isDir(packages_dir)) {
|
|
5373
|
-
for (const child of
|
|
5374
|
-
if (isDir(
|
|
5959
|
+
for (const child of fs18.readdirSync(packages_dir)) {
|
|
5960
|
+
if (isDir(path18.join(packages_dir, child, ".agent-src.uncondensed"))) {
|
|
5375
5961
|
return [true, `packages/${child}/.agent-src.uncondensed/`];
|
|
5376
5962
|
}
|
|
5377
5963
|
}
|
|
@@ -5389,17 +5975,17 @@ function _detect_legacy_for_migration(project_root) {
|
|
|
5389
5975
|
}
|
|
5390
5976
|
return [];
|
|
5391
5977
|
}
|
|
5392
|
-
if (isFile(
|
|
5978
|
+
if (isFile(path18.join(project_root, INSTALL_MODE_MARKER_REL))) return [];
|
|
5393
5979
|
const found = [];
|
|
5394
5980
|
for (const name of MIGRATE_LEGACY_YAML_FILES) {
|
|
5395
|
-
if (isFile(
|
|
5981
|
+
if (isFile(path18.join(project_root, name))) {
|
|
5396
5982
|
found.push(name);
|
|
5397
|
-
} else if (isFile(
|
|
5983
|
+
} else if (isFile(path18.join(project_root, "settings", name))) {
|
|
5398
5984
|
found.push(`settings/${name}`);
|
|
5399
5985
|
}
|
|
5400
5986
|
}
|
|
5401
5987
|
for (const name of MIGRATE_LEGACY_TOOL_DIRS) {
|
|
5402
|
-
const p =
|
|
5988
|
+
const p = path18.join(project_root, name);
|
|
5403
5989
|
if (isDir(p) && !isSymlink(p)) {
|
|
5404
5990
|
found.push(`${name}/`);
|
|
5405
5991
|
}
|
|
@@ -5411,7 +5997,7 @@ function _prompt_migrate_to_global(project_root, artefacts) {
|
|
|
5411
5997
|
process2.stdout.write("\n");
|
|
5412
5998
|
warn("Legacy project-local artefacts detected \u2014 pre-ADR-020 layout:");
|
|
5413
5999
|
for (const rel of artefacts) {
|
|
5414
|
-
info(` ${
|
|
6000
|
+
info(` ${path18.join(project_root, rel)}`);
|
|
5415
6001
|
}
|
|
5416
6002
|
info("The unified `agent-config migrate` sweeps these in one pass.");
|
|
5417
6003
|
info("The wizard recreates fresh config afterwards.");
|
|
@@ -5440,22 +6026,22 @@ function _run_migrate_to_global(project_root) {
|
|
|
5440
6026
|
}
|
|
5441
6027
|
}
|
|
5442
6028
|
function _format_global_root_for_marker(global_root) {
|
|
5443
|
-
const home = resolvePath(
|
|
6029
|
+
const home = resolvePath(os7.homedir());
|
|
5444
6030
|
const resolved = resolvePath(global_root);
|
|
5445
|
-
const rel =
|
|
5446
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
6031
|
+
const rel = path18.relative(home, resolved);
|
|
6032
|
+
if (rel === "" || rel.startsWith("..") || path18.isAbsolute(rel)) {
|
|
5447
6033
|
return global_root;
|
|
5448
6034
|
}
|
|
5449
|
-
return `~/${rel.split(
|
|
6035
|
+
return `~/${rel.split(path18.sep).join("/")}`;
|
|
5450
6036
|
}
|
|
5451
6037
|
function _remove_legacy_consumer_bridge_marker(project_root, env = null) {
|
|
5452
6038
|
const env_map = env ?? process2.env;
|
|
5453
6039
|
if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return null;
|
|
5454
|
-
if (isDir(
|
|
5455
|
-
const target =
|
|
6040
|
+
if (isDir(path18.join(project_root, ".agent-src.uncondensed"))) return null;
|
|
6041
|
+
const target = path18.join(project_root, CONSUMER_BRIDGE_MARKER_RELPATH);
|
|
5456
6042
|
if (!isFile(target)) return null;
|
|
5457
6043
|
try {
|
|
5458
|
-
|
|
6044
|
+
fs18.rmSync(target);
|
|
5459
6045
|
} catch {
|
|
5460
6046
|
return null;
|
|
5461
6047
|
}
|
|
@@ -5469,7 +6055,7 @@ var PROJECT_ANCHOR_TOOLS = {
|
|
|
5469
6055
|
function _write_per_tool_project_anchors(project_root, tools, env = null, now = null) {
|
|
5470
6056
|
const env_map = env ?? process2.env;
|
|
5471
6057
|
if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return [];
|
|
5472
|
-
if (isDir(
|
|
6058
|
+
if (isDir(path18.join(project_root, ".agent-src.uncondensed"))) return [];
|
|
5473
6059
|
const global_root_str = _format_global_root_for_marker(
|
|
5474
6060
|
event4u_root(env_map)
|
|
5475
6061
|
);
|
|
@@ -5478,8 +6064,8 @@ function _write_per_tool_project_anchors(project_root, tools, env = null, now =
|
|
|
5478
6064
|
for (const tool_id of Object.keys(PROJECT_ANCHOR_TOOLS).sort()) {
|
|
5479
6065
|
const rel_path = PROJECT_ANCHOR_TOOLS[tool_id];
|
|
5480
6066
|
if (!tools.has(tool_id)) continue;
|
|
5481
|
-
const target =
|
|
5482
|
-
mkdirp(
|
|
6067
|
+
const target = path18.join(project_root, rel_path);
|
|
6068
|
+
mkdirp(path18.dirname(target));
|
|
5483
6069
|
const body = `# event4u/agent-config \u2014 per-tool project anchor (auto-written).
|
|
5484
6070
|
# Spec: docs/contracts/consumer-bridge.md \xA7 Per-tool anchor strategy.
|
|
5485
6071
|
# Tool: ${tool_id}. Resolves the global install directly \u2014 no
|
|
@@ -5497,7 +6083,7 @@ installed_at: ${stamp}
|
|
|
5497
6083
|
}
|
|
5498
6084
|
var PACKAGE_TAG_ID = "event4u/agent-config";
|
|
5499
6085
|
function _inject_package_tag(target, source, package_root) {
|
|
5500
|
-
if (
|
|
6086
|
+
if (path18.extname(target) !== ".md") return;
|
|
5501
6087
|
let text;
|
|
5502
6088
|
try {
|
|
5503
6089
|
text = readText(target);
|
|
@@ -5525,8 +6111,8 @@ function _inject_package_tag(target, source, package_root) {
|
|
|
5525
6111
|
resolved_src = source;
|
|
5526
6112
|
}
|
|
5527
6113
|
if (package_root !== null) {
|
|
5528
|
-
const rel =
|
|
5529
|
-
if (rel !== "" && !rel.startsWith("..") && !
|
|
6114
|
+
const rel = path18.relative(resolvePath(package_root), resolved_src);
|
|
6115
|
+
if (rel !== "" && !rel.startsWith("..") && !path18.isAbsolute(rel)) {
|
|
5530
6116
|
source_value = rel;
|
|
5531
6117
|
} else {
|
|
5532
6118
|
source_value = resolved_src;
|
|
@@ -5561,7 +6147,7 @@ function _escapes_package_root(resolved, package_root) {
|
|
|
5561
6147
|
if (package_root === null) return false;
|
|
5562
6148
|
let root;
|
|
5563
6149
|
try {
|
|
5564
|
-
root =
|
|
6150
|
+
root = fs18.realpathSync(package_root);
|
|
5565
6151
|
} catch {
|
|
5566
6152
|
return false;
|
|
5567
6153
|
}
|
|
@@ -5587,7 +6173,7 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5587
6173
|
if (file_filter !== null && !file_filter(src)) return [0, 0, written_paths];
|
|
5588
6174
|
let resolved_src = src;
|
|
5589
6175
|
try {
|
|
5590
|
-
resolved_src =
|
|
6176
|
+
resolved_src = fs18.realpathSync(src);
|
|
5591
6177
|
} catch {
|
|
5592
6178
|
resolved_src = src;
|
|
5593
6179
|
}
|
|
@@ -5595,14 +6181,14 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5595
6181
|
warn(`refused: ${src} dereferences outside the package root \u2014 not copied`);
|
|
5596
6182
|
return [0, 0, written_paths];
|
|
5597
6183
|
}
|
|
5598
|
-
mkdirp(
|
|
6184
|
+
mkdirp(path18.dirname(dest));
|
|
5599
6185
|
const decision = tracker.resolve(dest, force);
|
|
5600
6186
|
if (decision === "preserve") {
|
|
5601
6187
|
tracker.preserve(dest, resolved_src, package_root);
|
|
5602
6188
|
_log_tx_entry("skip", dest);
|
|
5603
6189
|
return [0, 1, written_paths];
|
|
5604
6190
|
}
|
|
5605
|
-
|
|
6191
|
+
fs18.copyFileSync(src, dest);
|
|
5606
6192
|
_inject_package_tag(dest, src, package_root);
|
|
5607
6193
|
_log_tx_entry("write", dest);
|
|
5608
6194
|
written_paths.push(dest);
|
|
@@ -5611,11 +6197,11 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5611
6197
|
mkdirp(dest);
|
|
5612
6198
|
const walk = (node) => {
|
|
5613
6199
|
const acc = [];
|
|
5614
|
-
const names =
|
|
6200
|
+
const names = fs18.readdirSync(node).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
5615
6201
|
for (const name of names) {
|
|
5616
|
-
const entry =
|
|
6202
|
+
const entry = path18.join(node, name);
|
|
5617
6203
|
acc.push(entry);
|
|
5618
|
-
const lst =
|
|
6204
|
+
const lst = fs18.lstatSync(entry);
|
|
5619
6205
|
if (lst.isDirectory() && !lst.isSymbolicLink()) {
|
|
5620
6206
|
acc.push(...walk(entry));
|
|
5621
6207
|
}
|
|
@@ -5623,9 +6209,9 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5623
6209
|
return acc;
|
|
5624
6210
|
};
|
|
5625
6211
|
for (const entry of walk(src)) {
|
|
5626
|
-
const rel =
|
|
5627
|
-
const target =
|
|
5628
|
-
const lst =
|
|
6212
|
+
const rel = path18.relative(src, entry);
|
|
6213
|
+
const target = path18.join(dest, rel);
|
|
6214
|
+
const lst = fs18.lstatSync(entry);
|
|
5629
6215
|
if (lst.isDirectory() && !lst.isSymbolicLink()) {
|
|
5630
6216
|
mkdirp(target);
|
|
5631
6217
|
continue;
|
|
@@ -5633,8 +6219,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5633
6219
|
let resolvedIsDir = false;
|
|
5634
6220
|
let resolved = entry;
|
|
5635
6221
|
try {
|
|
5636
|
-
resolved =
|
|
5637
|
-
resolvedIsDir =
|
|
6222
|
+
resolved = fs18.realpathSync(entry);
|
|
6223
|
+
resolvedIsDir = fs18.statSync(entry).isDirectory();
|
|
5638
6224
|
} catch {
|
|
5639
6225
|
resolvedIsDir = false;
|
|
5640
6226
|
}
|
|
@@ -5666,8 +6252,8 @@ function _copy_dir_dereferencing_symlinks(src, dest, force, package_root = null,
|
|
|
5666
6252
|
_log_tx_entry("skip", target);
|
|
5667
6253
|
continue;
|
|
5668
6254
|
}
|
|
5669
|
-
mkdirp(
|
|
5670
|
-
|
|
6255
|
+
mkdirp(path18.dirname(target));
|
|
6256
|
+
fs18.copyFileSync(resolved, target);
|
|
5671
6257
|
_inject_package_tag(target, resolved, package_root);
|
|
5672
6258
|
_log_tx_entry("write", target);
|
|
5673
6259
|
written += 1;
|
|
@@ -5680,7 +6266,7 @@ function _claude_desktop_bundles_dir() {
|
|
|
5680
6266
|
}
|
|
5681
6267
|
function _write_claude_desktop_marker(force, lockfile_path2, bundles_dir, bundle_count) {
|
|
5682
6268
|
const anchor = expanduser3(USER_SCOPE_PATHS["claude-desktop"]);
|
|
5683
|
-
const target =
|
|
6269
|
+
const target = path18.join(anchor, "agent-config.md");
|
|
5684
6270
|
mkdirp(anchor);
|
|
5685
6271
|
const body = claudeDesktopMarkerBody(lockfile_path2, anchor, bundles_dir, bundle_count);
|
|
5686
6272
|
if (tracker.resolve(target, force) === "preserve") {
|
|
@@ -5705,27 +6291,15 @@ function _deploy_claude_desktop(force, package_root, lockfile_path2) {
|
|
|
5705
6291
|
return [bundle_count, 0, "deployed", [bundles_dir, ...marker_paths]];
|
|
5706
6292
|
}
|
|
5707
6293
|
var _CLAUDE_FLAT_WRAPPER_EXTRA = /* @__PURE__ */ new Set(["commit"]);
|
|
5708
|
-
function _apply_claude_flat_command_wrappers(anchor, package_root, current_files) {
|
|
6294
|
+
function _apply_claude_flat_command_wrappers(anchor, package_root, current_files, recorded_files = /* @__PURE__ */ new Set()) {
|
|
5709
6295
|
const wrapped = [];
|
|
5710
6296
|
const collisions = [];
|
|
5711
|
-
const
|
|
5712
|
-
const
|
|
5713
|
-
let flat_entries = [];
|
|
5714
|
-
try {
|
|
5715
|
-
flat_entries = fs15.readdirSync(commands_dir).filter((f) => f.endsWith(".md"));
|
|
5716
|
-
} catch {
|
|
5717
|
-
}
|
|
5718
|
-
for (const fname of flat_entries.sort()) {
|
|
5719
|
-
const slug = fname.slice(0, -".md".length);
|
|
5720
|
-
if (!is_claude_builtin_name(slug)) continue;
|
|
5721
|
-
fs15.rmSync(path13.join(commands_dir, fname), { force: true });
|
|
5722
|
-
current_files.delete(`commands/${fname}`);
|
|
5723
|
-
reserved.push(slug);
|
|
5724
|
-
}
|
|
6297
|
+
const commands_dir = path18.join(anchor, "commands");
|
|
6298
|
+
const { reserved, foreign } = sweepReservedNames(commands_dir, current_files, is_claude_builtin_name, recorded_files);
|
|
5725
6299
|
const eligible = new Set(_CLAUDE_FLAT_WRAPPER_EXTRA);
|
|
5726
6300
|
try {
|
|
5727
6301
|
const manifest = JSON.parse(
|
|
5728
|
-
|
|
6302
|
+
fs18.readFileSync(path18.join(package_root, "dist", "discovery", "discovery-manifest.json"), "utf8")
|
|
5729
6303
|
);
|
|
5730
6304
|
for (const a of manifest.artefacts ?? []) {
|
|
5731
6305
|
if (a.category !== "command" || typeof a.slug !== "string") continue;
|
|
@@ -5736,27 +6310,27 @@ function _apply_claude_flat_command_wrappers(anchor, package_root, current_files
|
|
|
5736
6310
|
}
|
|
5737
6311
|
for (const slug of [...eligible].sort()) {
|
|
5738
6312
|
const flat_rel = `commands/${slug}.md`;
|
|
5739
|
-
const flat_abs =
|
|
5740
|
-
if (!
|
|
5741
|
-
const skill_dir =
|
|
5742
|
-
if (
|
|
6313
|
+
const flat_abs = path18.join(anchor, "commands", `${slug}.md`);
|
|
6314
|
+
if (!fs18.existsSync(flat_abs)) continue;
|
|
6315
|
+
const skill_dir = path18.join(anchor, "skills", slug);
|
|
6316
|
+
if (fs18.existsSync(skill_dir)) {
|
|
5743
6317
|
collisions.push(slug);
|
|
5744
6318
|
continue;
|
|
5745
6319
|
}
|
|
5746
|
-
let body =
|
|
6320
|
+
let body = fs18.readFileSync(flat_abs, "utf8");
|
|
5747
6321
|
if (body.startsWith("---\n") && !/^name:/m.test(body.split("\n---")[0] ?? "")) {
|
|
5748
6322
|
body = body.replace("---\n", `---
|
|
5749
6323
|
name: ${slug}
|
|
5750
6324
|
`);
|
|
5751
6325
|
}
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
6326
|
+
fs18.mkdirSync(skill_dir, { recursive: true });
|
|
6327
|
+
fs18.writeFileSync(path18.join(skill_dir, "SKILL.md"), body, "utf8");
|
|
6328
|
+
fs18.rmSync(flat_abs, { force: true });
|
|
5755
6329
|
current_files.delete(flat_rel);
|
|
5756
6330
|
current_files.add(`skills/${slug}/SKILL.md`);
|
|
5757
6331
|
wrapped.push(slug);
|
|
5758
6332
|
}
|
|
5759
|
-
return { wrapped, collisions, reserved };
|
|
6333
|
+
return { wrapped, collisions, reserved, foreign };
|
|
5760
6334
|
}
|
|
5761
6335
|
function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
5762
6336
|
const results = {};
|
|
@@ -5783,8 +6357,8 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
5783
6357
|
const written_paths = [];
|
|
5784
6358
|
let current_files = /* @__PURE__ */ new Set();
|
|
5785
6359
|
for (const [src_rel, dest_sub] of plan) {
|
|
5786
|
-
const src =
|
|
5787
|
-
const dest = dest_sub ?
|
|
6360
|
+
const src = path18.join(package_root, src_rel);
|
|
6361
|
+
const dest = dest_sub ? path18.join(anchor, dest_sub) : anchor;
|
|
5788
6362
|
const rule_filter = _rule_filter_for_source(src_rel, rule_scope);
|
|
5789
6363
|
const [w, s, paths] = _copy_dir_dereferencing_symlinks(
|
|
5790
6364
|
src,
|
|
@@ -5806,15 +6380,31 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
5806
6380
|
);
|
|
5807
6381
|
}
|
|
5808
6382
|
if (tool_id === "claude-code") {
|
|
5809
|
-
const res = _apply_claude_flat_command_wrappers(anchor, package_root, current_files);
|
|
6383
|
+
const res = _apply_claude_flat_command_wrappers(anchor, package_root, current_files, recorded_rel_files(tool_id, anchor));
|
|
6384
|
+
const preserved_now = new Set(
|
|
6385
|
+
tracker.conflictState.preserved.map((p) => path18.resolve(p))
|
|
6386
|
+
);
|
|
5810
6387
|
rewriteAndReport(
|
|
5811
|
-
|
|
6388
|
+
path18.join(anchor, "rules"),
|
|
5812
6389
|
state.QUIET,
|
|
5813
6390
|
info,
|
|
5814
6391
|
warn,
|
|
5815
6392
|
res,
|
|
5816
|
-
|
|
6393
|
+
preserved_now
|
|
5817
6394
|
);
|
|
6395
|
+
if (installerThinsHost(tool_id, { packageRoot: package_root })) {
|
|
6396
|
+
try {
|
|
6397
|
+
const thin = thinInstalledRuleLayer({
|
|
6398
|
+
rulesDir: path18.join(anchor, "rules"),
|
|
6399
|
+
packageRoot: package_root,
|
|
6400
|
+
preserved: preserved_now
|
|
6401
|
+
});
|
|
6402
|
+
if (!state.QUIET) for (const l of describeThinInstalledLayer(thin)) info(l);
|
|
6403
|
+
} catch (e) {
|
|
6404
|
+
warn(`claude-code: thinned rule layer not written \u2014 ${String(e)}`);
|
|
6405
|
+
}
|
|
6406
|
+
}
|
|
6407
|
+
if (!state.QUIET) for (const l of installReceiptBudgetLines(package_root, void 0, { thisDeploy: /* @__PURE__ */ new Map([[anchor, current_files]]) })) info(l);
|
|
5818
6408
|
}
|
|
5819
6409
|
const missing_targets = _verify_deploy_targets(anchor, plan);
|
|
5820
6410
|
if (missing_targets.length > 0) {
|
|
@@ -5856,10 +6446,10 @@ function _deploy_global_content(tools, force, package_root, lockfile_path2) {
|
|
|
5856
6446
|
results[tool_id] = [written_total, skipped_total, "deployed", written_paths];
|
|
5857
6447
|
if (tool_id === "claude-code") {
|
|
5858
6448
|
try {
|
|
5859
|
-
const manifest =
|
|
6449
|
+
const manifest = path18.join(package_root, "src", "scripts", "hook_manifest.yaml");
|
|
5860
6450
|
const matrix = build_claude_hook_matrix(manifest);
|
|
5861
6451
|
const res = ensure_managed_hooks(
|
|
5862
|
-
|
|
6452
|
+
path18.join(anchor, "settings.json"),
|
|
5863
6453
|
matrix
|
|
5864
6454
|
);
|
|
5865
6455
|
if (!state.QUIET) {
|
|
@@ -5896,7 +6486,7 @@ function _preview_global_reap(tools, package_root) {
|
|
|
5896
6486
|
const anchor = expanduser3(anchor_raw);
|
|
5897
6487
|
let current_files = /* @__PURE__ */ new Set();
|
|
5898
6488
|
for (const [src_rel, dest_sub] of plan) {
|
|
5899
|
-
const src =
|
|
6489
|
+
const src = path18.join(package_root, src_rel);
|
|
5900
6490
|
current_files = setUnion(
|
|
5901
6491
|
current_files,
|
|
5902
6492
|
expected_deploy_files(
|
|
@@ -5930,14 +6520,14 @@ function _preview_global_reap(tools, package_root) {
|
|
|
5930
6520
|
function _verify_deploy_targets(anchor, plan) {
|
|
5931
6521
|
const missing = [];
|
|
5932
6522
|
for (const [, dest_sub] of plan) {
|
|
5933
|
-
const target = dest_sub ?
|
|
6523
|
+
const target = dest_sub ? path18.join(anchor, dest_sub) : anchor;
|
|
5934
6524
|
const label = dest_sub || ".";
|
|
5935
6525
|
if (!isDir(target)) {
|
|
5936
6526
|
missing.push(label);
|
|
5937
6527
|
continue;
|
|
5938
6528
|
}
|
|
5939
6529
|
try {
|
|
5940
|
-
const entries =
|
|
6530
|
+
const entries = fs18.readdirSync(target);
|
|
5941
6531
|
if (entries.length === 0) missing.push(label);
|
|
5942
6532
|
} catch {
|
|
5943
6533
|
missing.push(label);
|
|
@@ -5955,54 +6545,30 @@ function _resolve_global_settings_doc() {
|
|
|
5955
6545
|
}
|
|
5956
6546
|
function _resolve_global_settings_path() {
|
|
5957
6547
|
const root = event4u_root();
|
|
5958
|
-
const canonical =
|
|
6548
|
+
const canonical = path18.join(root, "settings", SETTINGS_FILE);
|
|
5959
6549
|
if (pathExists(canonical)) return canonical;
|
|
5960
|
-
const legacy =
|
|
6550
|
+
const legacy = path18.join(root, SETTINGS_FILE);
|
|
5961
6551
|
if (pathExists(legacy)) return legacy;
|
|
5962
6552
|
return null;
|
|
5963
6553
|
}
|
|
5964
6554
|
function _resolve_scoped_projection(package_root) {
|
|
5965
6555
|
const doc = _resolve_global_settings_doc() ?? _load_default_settings(package_root);
|
|
5966
|
-
const projection =
|
|
6556
|
+
const projection = isPlainObject(doc["projection"]) ? doc["projection"] : {};
|
|
5967
6557
|
const mode = projectionModeOf(projection["mode"]);
|
|
5968
|
-
const runtime =
|
|
6558
|
+
const runtime = isPlainObject(doc["runtime"]) ? doc["runtime"] : {};
|
|
5969
6559
|
const active_packs_raw = runtime["active_packs"];
|
|
5970
6560
|
const active_packs = Array.isArray(active_packs_raw) ? active_packs_raw.filter((v) => typeof v === "string") : [];
|
|
5971
6561
|
return { mode, active_packs };
|
|
5972
6562
|
}
|
|
5973
6563
|
function _resolve_global_rule_scope(package_root) {
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
}
|
|
5982
|
-
let text;
|
|
5983
|
-
try {
|
|
5984
|
-
text = readText(settings_path);
|
|
5985
|
-
} catch (e) {
|
|
5986
|
-
warn(
|
|
5987
|
-
`could not read ${settings_path} (${String(e)}) \u2014 rule scoping falls back to legacy-all, so ALL rules including maintainer-only ones will be installed. Fix the file to restore scoping.`
|
|
5988
|
-
);
|
|
5989
|
-
return LEGACY_ALL;
|
|
5990
|
-
}
|
|
5991
|
-
const parsed = yamlSafeLoad(text);
|
|
5992
|
-
if (!_isPlainObject(parsed)) {
|
|
5993
|
-
warn(
|
|
5994
|
-
`${settings_path} is not a YAML mapping \u2014 rule scoping falls back to legacy-all, so ALL rules including maintainer-only ones will be installed. Fix the file to restore scoping.`
|
|
5995
|
-
);
|
|
5996
|
-
return LEGACY_ALL;
|
|
5997
|
-
}
|
|
5998
|
-
try {
|
|
5999
|
-
return ruleScopeFromSettings(parsed, package_root);
|
|
6000
|
-
} catch (e) {
|
|
6001
|
-
warn(
|
|
6002
|
-
`could not derive rule scope from ${settings_path} (${String(e)}) \u2014 falling back to legacy-all; ALL rules will be installed.`
|
|
6003
|
-
);
|
|
6004
|
-
return LEGACY_ALL;
|
|
6005
|
-
}
|
|
6564
|
+
return resolveGlobalRuleScope({
|
|
6565
|
+
settingsPath: _resolve_global_settings_path(),
|
|
6566
|
+
packageRoot: package_root,
|
|
6567
|
+
readText,
|
|
6568
|
+
parseYaml: yamlSafeLoad,
|
|
6569
|
+
loadDefaults: () => _load_default_settings(package_root),
|
|
6570
|
+
warn
|
|
6571
|
+
});
|
|
6006
6572
|
}
|
|
6007
6573
|
function _rule_filter_for_source(src_rel, scope) {
|
|
6008
6574
|
if (src_rel !== RULE_SOURCE_REL) return null;
|
|
@@ -6068,7 +6634,7 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
6068
6634
|
info(` schema_version=1, agent_config_version=${installed_version}`);
|
|
6069
6635
|
info(` tools=${merged_tools.join(",")}`);
|
|
6070
6636
|
}
|
|
6071
|
-
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(
|
|
6637
|
+
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path18.join(project_root, ".agent-src.uncondensed"))) {
|
|
6072
6638
|
const drift = collect_drift(project_root);
|
|
6073
6639
|
if (!state.QUIET) {
|
|
6074
6640
|
process2.stdout.write("\n");
|
|
@@ -6182,19 +6748,19 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
6182
6748
|
}
|
|
6183
6749
|
}
|
|
6184
6750
|
}
|
|
6185
|
-
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(
|
|
6751
|
+
if (project_root !== null && pathExists(_resolve_settings_read(project_root)) && !isDir(path18.join(project_root, ".agent-src.uncondensed"))) {
|
|
6186
6752
|
const files_by_tool = filesByToolFromDeploy(deploy_results);
|
|
6187
6753
|
const rc = _update_installed_tools_manifest(project_root, tools, "global", force, files_by_tool);
|
|
6188
6754
|
if (rc !== 0) return rc;
|
|
6189
6755
|
const removed_marker = _remove_legacy_consumer_bridge_marker(project_root);
|
|
6190
6756
|
if (removed_marker !== null && !state.QUIET) {
|
|
6191
|
-
const rel = isRelativeTo(removed_marker, project_root) ?
|
|
6757
|
+
const rel = isRelativeTo(removed_marker, project_root) ? path18.relative(project_root, removed_marker) : removed_marker;
|
|
6192
6758
|
info(`Removed legacy bridge marker: ${rel}`);
|
|
6193
6759
|
}
|
|
6194
6760
|
const anchor_paths = _write_per_tool_project_anchors(project_root, tools);
|
|
6195
6761
|
if (anchor_paths.length > 0 && !state.QUIET) {
|
|
6196
6762
|
for (const p of anchor_paths) {
|
|
6197
|
-
const rel = isRelativeTo(p, project_root) ?
|
|
6763
|
+
const rel = isRelativeTo(p, project_root) ? path18.relative(project_root, p) : p;
|
|
6198
6764
|
info(`Project anchor written: ${rel}`);
|
|
6199
6765
|
}
|
|
6200
6766
|
}
|
|
@@ -6230,8 +6796,8 @@ function install_global(tools, force, project_root = null, core_only = false) {
|
|
|
6230
6796
|
}
|
|
6231
6797
|
function _catalogue_truncation_warnings(deploy_results, project_root) {
|
|
6232
6798
|
const log_candidates = [
|
|
6233
|
-
|
|
6234
|
-
...project_root ? [
|
|
6799
|
+
path18.join(event4u_root(), "state", "skill-catalogue.jsonl"),
|
|
6800
|
+
...project_root ? [path18.join(project_root, OBSERVATION_LOG)] : []
|
|
6235
6801
|
];
|
|
6236
6802
|
const records = log_candidates.flatMap((p) => readObservationLog(p));
|
|
6237
6803
|
if (records.length === 0) return [];
|
|
@@ -6254,13 +6820,13 @@ function _catalogue_truncation_warnings(deploy_results, project_root) {
|
|
|
6254
6820
|
function _scoped_migration_notice(deploy_results, project_root, package_root, probe) {
|
|
6255
6821
|
if (!isInteractiveSession(probe)) return [];
|
|
6256
6822
|
const log_candidates = [
|
|
6257
|
-
|
|
6258
|
-
...project_root ? [
|
|
6823
|
+
path18.join(event4u_root(), "state", "skill-catalogue.jsonl"),
|
|
6824
|
+
...project_root ? [path18.join(project_root, OBSERVATION_LOG)] : []
|
|
6259
6825
|
];
|
|
6260
6826
|
const limits = knownHostLimits(log_candidates.flatMap((p) => readObservationLog(p)));
|
|
6261
6827
|
if (limits.size === 0) return [];
|
|
6262
6828
|
const resolved = _resolve_scoped_projection(package_root);
|
|
6263
|
-
const settings_path = _resolve_global_settings_path() ??
|
|
6829
|
+
const settings_path = _resolve_global_settings_path() ?? path18.join(event4u_root(), "settings", SETTINGS_FILE);
|
|
6264
6830
|
for (const tool_id of Object.keys(deploy_results).sort()) {
|
|
6265
6831
|
const [, , status] = deploy_results[tool_id];
|
|
6266
6832
|
if (status !== "deployed") continue;
|
|
@@ -6279,8 +6845,8 @@ function _scoped_migration_notice(deploy_results, project_root, package_root, pr
|
|
|
6279
6845
|
}
|
|
6280
6846
|
return [];
|
|
6281
6847
|
}
|
|
6282
|
-
var SETTINGS_SURFACE_REL =
|
|
6283
|
-
var SETTINGS_DELTA_REL =
|
|
6848
|
+
var SETTINGS_SURFACE_REL = path18.join("state", "settings-surface.json");
|
|
6849
|
+
var SETTINGS_DELTA_REL = path18.join("state", "settings-delta.json");
|
|
6284
6850
|
function _current_settings_surface(version) {
|
|
6285
6851
|
const jsonSchema = zodToJsonSchema(settingsSchema, {
|
|
6286
6852
|
name: "AgentSettings",
|
|
@@ -6291,20 +6857,20 @@ function _current_settings_surface(version) {
|
|
|
6291
6857
|
}
|
|
6292
6858
|
function _write_settings_surface_snapshot(installed_version) {
|
|
6293
6859
|
const root = event4u_root();
|
|
6294
|
-
const surface_path =
|
|
6295
|
-
const delta_path =
|
|
6860
|
+
const surface_path = path18.join(root, SETTINGS_SURFACE_REL);
|
|
6861
|
+
const delta_path = path18.join(root, SETTINGS_DELTA_REL);
|
|
6296
6862
|
const next = _current_settings_surface(installed_version);
|
|
6297
6863
|
let previous = null;
|
|
6298
6864
|
try {
|
|
6299
|
-
const parsed = JSON.parse(
|
|
6865
|
+
const parsed = JSON.parse(fs18.readFileSync(surface_path, "utf8"));
|
|
6300
6866
|
if (parsed !== null && typeof parsed === "object" && parsed.entries !== void 0) previous = parsed;
|
|
6301
6867
|
} catch {
|
|
6302
6868
|
}
|
|
6303
6869
|
if (previous !== null && previous.version !== next.version) {
|
|
6304
6870
|
const delta = computeSurfaceDelta(previous, next);
|
|
6305
6871
|
if (delta.changes.length > 0) {
|
|
6306
|
-
|
|
6307
|
-
|
|
6872
|
+
fs18.mkdirSync(path18.dirname(delta_path), { recursive: true, mode: 448 });
|
|
6873
|
+
fs18.writeFileSync(delta_path, `${JSON.stringify(delta, null, 2)}
|
|
6308
6874
|
`, { mode: 384 });
|
|
6309
6875
|
if (!state.QUIET) {
|
|
6310
6876
|
const counts = {};
|
|
@@ -6316,8 +6882,8 @@ function _write_settings_surface_snapshot(installed_version) {
|
|
|
6316
6882
|
}
|
|
6317
6883
|
}
|
|
6318
6884
|
}
|
|
6319
|
-
|
|
6320
|
-
|
|
6885
|
+
fs18.mkdirSync(path18.dirname(surface_path), { recursive: true, mode: 448 });
|
|
6886
|
+
fs18.writeFileSync(surface_path, `${JSON.stringify(next, null, 2)}
|
|
6321
6887
|
`, { mode: 384 });
|
|
6322
6888
|
}
|
|
6323
6889
|
function arrayStrEqual(a, b) {
|
|
@@ -6537,13 +7103,13 @@ function _minimal_templates_root() {
|
|
|
6537
7103
|
const chain = [start];
|
|
6538
7104
|
let cur = start;
|
|
6539
7105
|
for (; ; ) {
|
|
6540
|
-
const parent =
|
|
7106
|
+
const parent = path18.dirname(cur);
|
|
6541
7107
|
if (parent === cur) break;
|
|
6542
7108
|
chain.push(parent);
|
|
6543
7109
|
cur = parent;
|
|
6544
7110
|
}
|
|
6545
7111
|
for (const ancestor of chain) {
|
|
6546
|
-
const candidate =
|
|
7112
|
+
const candidate = path18.join(ancestor, "src", "templates", "minimal");
|
|
6547
7113
|
if (isDir(candidate)) return candidate;
|
|
6548
7114
|
}
|
|
6549
7115
|
fail("Could not locate src/templates/minimal/ \u2014 package install is corrupt.");
|
|
@@ -6551,9 +7117,9 @@ function _minimal_templates_root() {
|
|
|
6551
7117
|
var INSTALL_MODE_MARKER_REL = "agents/.agent-state/install-mode.txt";
|
|
6552
7118
|
function _write_install_mode_marker(project_root, mode) {
|
|
6553
7119
|
if (mode !== "minimal" && mode !== "full") return;
|
|
6554
|
-
const marker =
|
|
7120
|
+
const marker = path18.join(project_root, INSTALL_MODE_MARKER_REL);
|
|
6555
7121
|
try {
|
|
6556
|
-
mkdirp(
|
|
7122
|
+
mkdirp(path18.dirname(marker));
|
|
6557
7123
|
writeText(marker, `${mode}
|
|
6558
7124
|
`);
|
|
6559
7125
|
} catch {
|
|
@@ -6562,7 +7128,7 @@ function _write_install_mode_marker(project_root, mode) {
|
|
|
6562
7128
|
function install_minimal(target_root_in, force, user_type = "") {
|
|
6563
7129
|
let target_root = resolvePath(target_root_in);
|
|
6564
7130
|
mkdirp(target_root);
|
|
6565
|
-
const parent =
|
|
7131
|
+
const parent = path18.dirname(target_root);
|
|
6566
7132
|
if (parent !== target_root) {
|
|
6567
7133
|
const existing = find_project_root_with_anchor(parent);
|
|
6568
7134
|
if (existing !== null && existing[0] !== target_root) {
|
|
@@ -6573,21 +7139,21 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
6573
7139
|
}
|
|
6574
7140
|
}
|
|
6575
7141
|
const templates = _minimal_templates_root();
|
|
6576
|
-
const settings_src =
|
|
6577
|
-
const overrides_gitkeep_src =
|
|
6578
|
-
const overrides_readme_src =
|
|
7142
|
+
const settings_src = path18.join(templates, SETTINGS_FILE);
|
|
7143
|
+
const overrides_gitkeep_src = path18.join(templates, "overrides-gitkeep");
|
|
7144
|
+
const overrides_readme_src = path18.join(templates, "agents-overrides-readme.md");
|
|
6579
7145
|
if (!isFile(settings_src)) fail(`Bundled minimal settings template missing under ${templates}`);
|
|
6580
7146
|
if (!isFile(overrides_gitkeep_src) || !isFile(overrides_readme_src)) {
|
|
6581
7147
|
fail(`Bundled overrides scaffold templates missing under ${templates}`);
|
|
6582
7148
|
}
|
|
6583
7149
|
info(`Minimal init \u2192 ${target_root}`);
|
|
6584
|
-
const overrides_root =
|
|
7150
|
+
const overrides_root = path18.join(target_root, "agents", "overrides");
|
|
6585
7151
|
mkdirp(overrides_root);
|
|
6586
7152
|
const gitkeep_body = readText(overrides_gitkeep_src);
|
|
6587
7153
|
for (const sub of ["rules", "skills", "commands"]) {
|
|
6588
|
-
const sub_dir =
|
|
7154
|
+
const sub_dir = path18.join(overrides_root, sub);
|
|
6589
7155
|
mkdirp(sub_dir);
|
|
6590
|
-
const gitkeep_dst =
|
|
7156
|
+
const gitkeep_dst = path18.join(sub_dir, ".gitkeep");
|
|
6591
7157
|
if (pathExists(gitkeep_dst) && !force) {
|
|
6592
7158
|
skip(`agents/overrides/${sub}/.gitkeep already exists (use --force to overwrite)`);
|
|
6593
7159
|
} else {
|
|
@@ -6595,7 +7161,7 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
6595
7161
|
success(`Wrote agents/overrides/${sub}/.gitkeep`);
|
|
6596
7162
|
}
|
|
6597
7163
|
}
|
|
6598
|
-
const readme_dst =
|
|
7164
|
+
const readme_dst = path18.join(overrides_root, "README.md");
|
|
6599
7165
|
if (pathExists(readme_dst) && !force) {
|
|
6600
7166
|
skip("agents/overrides/README.md already exists (use --force to overwrite)");
|
|
6601
7167
|
} else {
|
|
@@ -6613,14 +7179,14 @@ function install_minimal(target_root_in, force, user_type = "") {
|
|
|
6613
7179
|
personal:
|
|
6614
7180
|
user_type: ${user_type}
|
|
6615
7181
|
`;
|
|
6616
|
-
mkdirp(
|
|
7182
|
+
mkdirp(path18.dirname(settings_dst));
|
|
6617
7183
|
writeText(settings_dst, body);
|
|
6618
7184
|
success(`Wrote ${SETTINGS_FILE} (user_type=${user_type})`);
|
|
6619
7185
|
}
|
|
6620
7186
|
}
|
|
6621
7187
|
const removed_marker = _remove_legacy_consumer_bridge_marker(target_root);
|
|
6622
7188
|
if (removed_marker !== null) {
|
|
6623
|
-
const rel = isRelativeTo(removed_marker, target_root) ?
|
|
7189
|
+
const rel = isRelativeTo(removed_marker, target_root) ? path18.relative(target_root, removed_marker) : removed_marker;
|
|
6624
7190
|
success(`Removed legacy bridge marker: ${rel}`);
|
|
6625
7191
|
}
|
|
6626
7192
|
_write_install_mode_marker(target_root, "minimal");
|
|
@@ -6694,7 +7260,7 @@ function run_interactive_init(project_root, force) {
|
|
|
6694
7260
|
);
|
|
6695
7261
|
return 0;
|
|
6696
7262
|
}
|
|
6697
|
-
const target =
|
|
7263
|
+
const target = path18.join(project_root, _LOCAL_CONFIG_FILE);
|
|
6698
7264
|
if (pathExists(target) && !force) {
|
|
6699
7265
|
warn(
|
|
6700
7266
|
`${_LOCAL_CONFIG_FILE} already exists; re-run with --force to overwrite. Skipping interactive init.`
|
|
@@ -6721,7 +7287,7 @@ function run_interactive_init(project_root, force) {
|
|
|
6721
7287
|
warn(`Could not write ${target}: ${String(exc)}`);
|
|
6722
7288
|
return 1;
|
|
6723
7289
|
}
|
|
6724
|
-
success(`Wrote ${
|
|
7290
|
+
success(`Wrote ${path18.relative(project_root, target)} (${user_type} / ${stack} / ${verbosity})`);
|
|
6725
7291
|
return 0;
|
|
6726
7292
|
}
|
|
6727
7293
|
var _WIZARD_READY_RE = /^WIZARD_READY (http:\/\/(?:127\.0\.0\.1|localhost):\d+\/\S*)\r?$/;
|
|
@@ -6739,12 +7305,12 @@ function _wizard_should_launch(opts) {
|
|
|
6739
7305
|
return [true, ""];
|
|
6740
7306
|
}
|
|
6741
7307
|
function _wizard_cli_dist(_project_root) {
|
|
6742
|
-
const package_root =
|
|
6743
|
-
const cli =
|
|
7308
|
+
const package_root = path18.dirname(path18.dirname(path18.dirname(resolvePath(_HERE))));
|
|
7309
|
+
const cli = path18.join(package_root, "dist", "cli", "agent-config.js");
|
|
6744
7310
|
return pathExists(cli) ? cli : null;
|
|
6745
7311
|
}
|
|
6746
7312
|
function _server_info_path() {
|
|
6747
|
-
return
|
|
7313
|
+
return path18.join(os7.homedir(), ".event4u", "agent-config", "local-server.json");
|
|
6748
7314
|
}
|
|
6749
7315
|
function _pid_is_agent_config(pid) {
|
|
6750
7316
|
let res;
|
|
@@ -6761,7 +7327,7 @@ function _pid_is_agent_config(pid) {
|
|
|
6761
7327
|
}
|
|
6762
7328
|
function unlinkMissingOk(p) {
|
|
6763
7329
|
try {
|
|
6764
|
-
|
|
7330
|
+
fs18.unlinkSync(p);
|
|
6765
7331
|
} catch {
|
|
6766
7332
|
}
|
|
6767
7333
|
}
|
|
@@ -6839,14 +7405,14 @@ function _wizard_spawn(project_root, pass_project_root = true) {
|
|
|
6839
7405
|
}
|
|
6840
7406
|
function _wizard_run_sync(cmd, env, cli) {
|
|
6841
7407
|
const total = _WIZARD_TIMEOUTS.reduce((a, b) => a + b, 0);
|
|
6842
|
-
const log_path =
|
|
6843
|
-
|
|
7408
|
+
const log_path = path18.join(
|
|
7409
|
+
os7.tmpdir(),
|
|
6844
7410
|
`agent-config-wizard-${process2.pid}-${Date.now()}.log`
|
|
6845
7411
|
);
|
|
6846
7412
|
let child;
|
|
6847
7413
|
let log_fd = null;
|
|
6848
7414
|
try {
|
|
6849
|
-
log_fd =
|
|
7415
|
+
log_fd = fs18.openSync(log_path, "w");
|
|
6850
7416
|
child = spawn(cmd[0], cmd.slice(1), {
|
|
6851
7417
|
env,
|
|
6852
7418
|
detached: true,
|
|
@@ -6864,7 +7430,7 @@ function _wizard_run_sync(cmd, env, cli) {
|
|
|
6864
7430
|
} finally {
|
|
6865
7431
|
if (log_fd !== null) {
|
|
6866
7432
|
try {
|
|
6867
|
-
|
|
7433
|
+
fs18.closeSync(log_fd);
|
|
6868
7434
|
} catch {
|
|
6869
7435
|
}
|
|
6870
7436
|
}
|
|
@@ -7041,7 +7607,7 @@ function main2(argv) {
|
|
|
7041
7607
|
} catch (exc) {
|
|
7042
7608
|
fail(`--apply-payload JSON parse error: ${String(exc)}`);
|
|
7043
7609
|
}
|
|
7044
|
-
if (!
|
|
7610
|
+
if (!isPlainObject(payload)) fail("--apply-payload root must be a JSON object");
|
|
7045
7611
|
const pl = payload;
|
|
7046
7612
|
const schema_version = pl["schema_version"];
|
|
7047
7613
|
if (schema_version !== "wizard-v2" && schema_version !== "installer-v1") {
|
|
@@ -7060,13 +7626,13 @@ function main2(argv) {
|
|
|
7060
7626
|
opts.scope = "global";
|
|
7061
7627
|
}
|
|
7062
7628
|
const settings = pl["settings"];
|
|
7063
|
-
if (
|
|
7629
|
+
if (isPlainObject(settings)) {
|
|
7064
7630
|
const rule_loading_tier = settings["rule_loading_tier"] || settings["cost_profile"];
|
|
7065
7631
|
if (typeof rule_loading_tier === "string" && rule_loading_tier) {
|
|
7066
7632
|
opts.profile = rule_loading_tier;
|
|
7067
7633
|
}
|
|
7068
7634
|
const personal = settings["personal"];
|
|
7069
|
-
if (
|
|
7635
|
+
if (isPlainObject(personal)) {
|
|
7070
7636
|
const user_type = personal["user_type"];
|
|
7071
7637
|
if (typeof user_type === "string" && user_type) {
|
|
7072
7638
|
opts.user_type = user_type;
|
|
@@ -7114,8 +7680,8 @@ function main2(argv) {
|
|
|
7114
7680
|
const target_root = resolvePath(
|
|
7115
7681
|
opts.custom_path || opts.project || process2.env["PROJECT_ROOT"] || process2.cwd()
|
|
7116
7682
|
);
|
|
7117
|
-
const minimal_package_root =
|
|
7118
|
-
|
|
7683
|
+
const minimal_package_root = path18.dirname(
|
|
7684
|
+
path18.dirname(path18.dirname(_minimal_templates_root()))
|
|
7119
7685
|
);
|
|
7120
7686
|
const validated_user_type = _validate_user_type(minimal_package_root, opts.user_type);
|
|
7121
7687
|
return install_minimal(target_root, opts.force, validated_user_type);
|
|
@@ -7151,7 +7717,7 @@ function main2(argv) {
|
|
|
7151
7717
|
return rc2;
|
|
7152
7718
|
}
|
|
7153
7719
|
const project_root = custom_path || resolvePath(opts.project || process2.env["PROJECT_ROOT"] || process2.cwd());
|
|
7154
|
-
const is_first_run = !pathExists(
|
|
7720
|
+
const is_first_run = !pathExists(path18.join(project_root, SETTINGS_FILE));
|
|
7155
7721
|
tracker.begin(project_root);
|
|
7156
7722
|
let rc = _main_project_install(opts, project_root, parsed_tools, is_first_run);
|
|
7157
7723
|
if (rc === 0 && opts.interactive) {
|
|
@@ -7196,37 +7762,27 @@ function _read_consumer_auto_switch(project_root) {
|
|
|
7196
7762
|
} catch {
|
|
7197
7763
|
return "suggest";
|
|
7198
7764
|
}
|
|
7199
|
-
const model =
|
|
7200
|
-
const value =
|
|
7765
|
+
const model = isPlainObject(data) ? data["model"] : null;
|
|
7766
|
+
const value = isPlainObject(model) ? model["auto_switch"] : null;
|
|
7201
7767
|
if (typeof value === "string" && ["auto", "suggest", "off"].includes(value.trim().toLowerCase())) {
|
|
7202
7768
|
return value.trim().toLowerCase();
|
|
7203
7769
|
}
|
|
7204
7770
|
return "suggest";
|
|
7205
7771
|
}
|
|
7206
|
-
function _team_setup_hint_line(
|
|
7207
|
-
let data;
|
|
7208
|
-
try {
|
|
7209
|
-
data = load_agent_settings({ project_path: _resolve_settings_read(project_root) });
|
|
7210
|
-
} catch {
|
|
7211
|
-
data = {};
|
|
7212
|
-
}
|
|
7213
|
-
const ai_team = _isPlainObject(data) ? data["ai_team"] : null;
|
|
7214
|
-
const flag = _isPlainObject(ai_team) ? ai_team["suppress_setup_hint"] : null;
|
|
7215
|
-
const suppressed = flag === true || typeof flag === "string" && ["true", "yes", "on", "1"].includes(flag.trim().toLowerCase());
|
|
7216
|
-
if (suppressed) return null;
|
|
7772
|
+
function _team_setup_hint_line() {
|
|
7217
7773
|
return " \u2022 Claude Code team mode (optional cross-model review via the official codex plugin): run `agent-config doctor --check team` for setup status.";
|
|
7218
7774
|
}
|
|
7219
7775
|
function finalize_claude_model_tiers(project_root) {
|
|
7220
|
-
const claude_skills =
|
|
7221
|
-
const augment_skills =
|
|
7776
|
+
const claude_skills = path18.join(project_root, ".claude", "skills");
|
|
7777
|
+
const augment_skills = path18.join(project_root, ".augment", "skills");
|
|
7222
7778
|
if (!isDir(claude_skills) || !isDir(augment_skills)) return 0;
|
|
7223
7779
|
if (_read_consumer_auto_switch(project_root) !== "auto") return 0;
|
|
7224
7780
|
let rendered = 0;
|
|
7225
|
-
const entries =
|
|
7781
|
+
const entries = fs18.readdirSync(claude_skills).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
7226
7782
|
for (const name of entries) {
|
|
7227
|
-
const entry =
|
|
7228
|
-
const src_dir =
|
|
7229
|
-
const src_md =
|
|
7783
|
+
const entry = path18.join(claude_skills, name);
|
|
7784
|
+
const src_dir = path18.join(augment_skills, name);
|
|
7785
|
+
const src_md = path18.join(src_dir, "SKILL.md");
|
|
7230
7786
|
let tier;
|
|
7231
7787
|
try {
|
|
7232
7788
|
tier = read_model_tier(src_md);
|
|
@@ -7235,22 +7791,22 @@ function finalize_claude_model_tiers(project_root) {
|
|
|
7235
7791
|
}
|
|
7236
7792
|
if (tier === null || !(tier in TIER_TO_CLAUDE_MODEL) || !isDir(src_dir)) continue;
|
|
7237
7793
|
if (isSymlink(entry) || isFile(entry)) {
|
|
7238
|
-
|
|
7794
|
+
fs18.unlinkSync(entry);
|
|
7239
7795
|
} else if (isDir(entry)) {
|
|
7240
|
-
|
|
7796
|
+
fs18.rmSync(entry, { recursive: true, force: true });
|
|
7241
7797
|
}
|
|
7242
7798
|
mkdirp(entry);
|
|
7243
|
-
const srcFiles =
|
|
7799
|
+
const srcFiles = fs18.readdirSync(src_dir).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
7244
7800
|
for (const fname of srcFiles) {
|
|
7245
7801
|
if (fname === "SKILL.md") {
|
|
7246
7802
|
writeText(
|
|
7247
|
-
|
|
7803
|
+
path18.join(entry, "SKILL.md"),
|
|
7248
7804
|
render_native_model_md(readText(src_md), tier)
|
|
7249
7805
|
);
|
|
7250
7806
|
} else {
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7807
|
+
fs18.symlinkSync(
|
|
7808
|
+
path18.join("../../../.augment/skills", name, fname),
|
|
7809
|
+
path18.join(entry, fname)
|
|
7254
7810
|
);
|
|
7255
7811
|
}
|
|
7256
7812
|
}
|
|
@@ -7268,7 +7824,7 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
7268
7824
|
let package_type;
|
|
7269
7825
|
if (opts.package) {
|
|
7270
7826
|
package_root = resolvePath(opts.package);
|
|
7271
|
-
if (!pathExists(
|
|
7827
|
+
if (!pathExists(path18.join(package_root, "src", "config", "profiles", "minimal.ini"))) {
|
|
7272
7828
|
fail(`Invalid --package path (missing src/config/profiles/minimal.ini): ${package_root}`);
|
|
7273
7829
|
}
|
|
7274
7830
|
package_type = detect_package_type_for_project(project_root, package_root);
|
|
@@ -7394,11 +7950,8 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
7394
7950
|
}
|
|
7395
7951
|
printResiduals(tools, state.QUIET);
|
|
7396
7952
|
if (_is_tool_enabled(tools, "claude-code")) {
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
process2.stdout.write(team_hint + "\n");
|
|
7400
|
-
process2.stdout.write("\n");
|
|
7401
|
-
}
|
|
7953
|
+
process2.stdout.write(_team_setup_hint_line() + "\n");
|
|
7954
|
+
process2.stdout.write("\n");
|
|
7402
7955
|
}
|
|
7403
7956
|
}
|
|
7404
7957
|
_propose_modules_config(project_root, is_first_run);
|
|
@@ -7406,14 +7959,16 @@ function _main_project_install(opts, project_root, parsed_tools, is_first_run) {
|
|
|
7406
7959
|
if (will_launch) {
|
|
7407
7960
|
return _wizard_spawn(project_root);
|
|
7408
7961
|
}
|
|
7962
|
+
const ign = write_managed_block(project_root, opts.dry_run);
|
|
7963
|
+
if (ign > 0) success(`.gitignore: ${opts.dry_run ? "would add " : "+"}${ign} managed entries`);
|
|
7409
7964
|
return 0;
|
|
7410
7965
|
}
|
|
7411
7966
|
function _resolvedArgv1() {
|
|
7412
7967
|
if (process2.argv[1] === void 0) return void 0;
|
|
7413
7968
|
try {
|
|
7414
|
-
return
|
|
7969
|
+
return fs18.realpathSync(path18.resolve(process2.argv[1]));
|
|
7415
7970
|
} catch {
|
|
7416
|
-
return
|
|
7971
|
+
return path18.resolve(process2.argv[1]);
|
|
7417
7972
|
}
|
|
7418
7973
|
}
|
|
7419
7974
|
var _argv1 = _resolvedArgv1();
|