@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
|
@@ -188,6 +188,21 @@ export interface ClaudePathsPlan {
|
|
|
188
188
|
dropped: { pattern: string; reason: 'unresolved-placeholder' | 'over-budget' | 'mixed-triggers' }[];
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* The two trigger keys `derive_trigger_globs` turns into a host glob. Kept
|
|
193
|
+
* beside it deliberately: the day a third path-shaped key is added there, this
|
|
194
|
+
* set is the other half of the same edit, and a reader looking at either one
|
|
195
|
+
* sees the pair.
|
|
196
|
+
*/
|
|
197
|
+
const PATH_SHAPED_TRIGGER_KEYS: ReadonlySet<string> = new Set(['file_pattern', 'path_prefix']);
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Keys on a trigger object that match nothing. `reason:` documents why the
|
|
201
|
+
* trigger exists; counting it would make every annotated path trigger look
|
|
202
|
+
* mixed and scope nothing at all.
|
|
203
|
+
*/
|
|
204
|
+
const NON_MATCHING_TRIGGER_KEYS: ReadonlySet<string> = new Set(['reason']);
|
|
205
|
+
|
|
191
206
|
/**
|
|
192
207
|
* Does this rule declare any trigger that is NOT path-shaped?
|
|
193
208
|
*
|
|
@@ -199,6 +214,18 @@ export interface ClaudePathsPlan {
|
|
|
199
214
|
* rule loads unconditionally. The emitter fed both semantics from one list, so
|
|
200
215
|
* a rule that declared keywords *and* one path glob silently became
|
|
201
216
|
* path-gated-only on Claude.
|
|
217
|
+
*
|
|
218
|
+
* **The test is a negation, not a list of non-path kinds**, and the difference
|
|
219
|
+
* is not stylistic. The predicate used to enumerate `keyword` and `phrase`,
|
|
220
|
+
* which left `command` — a prompt route like any other — uncounted:
|
|
221
|
+
* `roadmap-progress-sync` declares one `path_prefix` and three `command`
|
|
222
|
+
* triggers, so it was emitted with an exclusive `paths:` and its three command
|
|
223
|
+
* routes never fired on this host. A list can only ever be as current as its
|
|
224
|
+
* last edit; the schema's `additionalProperties: false` means a new match key
|
|
225
|
+
* arrives as a deliberate schema change, and until someone teaches
|
|
226
|
+
* `derive_trigger_globs` to make a glob from it, treating it as promptable is
|
|
227
|
+
* the fail-safe reading — the rule stays unconditional rather than silently
|
|
228
|
+
* narrowing to a path it does not have.
|
|
202
229
|
*/
|
|
203
230
|
export function _has_non_path_trigger(meta: Record<string, unknown>): boolean {
|
|
204
231
|
const triggers = meta['triggers'];
|
|
@@ -206,8 +233,21 @@ export function _has_non_path_trigger(meta: Record<string, unknown>): boolean {
|
|
|
206
233
|
for (const t of triggers) {
|
|
207
234
|
if (t === null || typeof t !== 'object' || Array.isArray(t)) continue;
|
|
208
235
|
const obj = t as Record<string, unknown>;
|
|
209
|
-
|
|
210
|
-
|
|
236
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
237
|
+
if (PATH_SHAPED_TRIGGER_KEYS.has(key) || NON_MATCHING_TRIGGER_KEYS.has(key)) continue;
|
|
238
|
+
// A string that is not blank, or ANY non-string value. The schema
|
|
239
|
+
// types all five match keys as strings today, so the second half is
|
|
240
|
+
// for the key that arrives later: a `keyword: ["a","b"]` read as
|
|
241
|
+
// "not a string, so not a trigger" would silently narrow the rule
|
|
242
|
+
// to a path it does not have, which is the exact failure the
|
|
243
|
+
// negation above exists to prevent. Undefined and null are the one
|
|
244
|
+
// shape that means "absent".
|
|
245
|
+
if (typeof value === 'string') {
|
|
246
|
+
if (value.trim() !== '') return true;
|
|
247
|
+
} else if (value !== undefined && value !== null) {
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
211
251
|
}
|
|
212
252
|
return false;
|
|
213
253
|
}
|
|
@@ -230,8 +270,10 @@ export function _claude_paths_plan(meta: Record<string, unknown>): ClaudePathsPl
|
|
|
230
270
|
const globs: string[] = [];
|
|
231
271
|
const dropped: ClaudePathsPlan['dropped'] = [];
|
|
232
272
|
|
|
233
|
-
// A rule that ALSO declares
|
|
234
|
-
//
|
|
273
|
+
// A rule that ALSO declares a non-path trigger — keyword, phrase, command,
|
|
274
|
+
// or a match key added to the schema later — gets no `paths:` at all, and
|
|
275
|
+
// therefore keeps loading unconditionally on Claude Code. The predicate is
|
|
276
|
+
// a negation of the two path-shaped keys, deliberately: see its docblock.
|
|
235
277
|
//
|
|
236
278
|
// Emitting `paths:` here would narrow the rule to a path match and discard
|
|
237
279
|
// every keyword the author wrote, because this host reads the list as the
|
|
@@ -132,7 +132,7 @@ export function rewriteAndReport(
|
|
|
132
132
|
quiet: boolean,
|
|
133
133
|
info: (m: string) => void,
|
|
134
134
|
warn: (m: string) => void,
|
|
135
|
-
wrappers?: { wrapped: readonly string[]; reserved: readonly string[] },
|
|
135
|
+
wrappers?: { wrapped: readonly string[]; reserved: readonly string[]; foreign?: readonly string[] },
|
|
136
136
|
preserved: ReadonlySet<string> = new Set(),
|
|
137
137
|
): ClaudeRuleRewriteResult {
|
|
138
138
|
const result = rewriteClaudeRules(rulesDir, preserved);
|
|
@@ -157,6 +157,15 @@ export function rewriteAndReport(
|
|
|
157
157
|
'commands remain available',
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
|
+
if (wrappers.foreign !== undefined && wrappers.foreign.length > 0) {
|
|
161
|
+
// Reported, never removed. The name shadows a host built-in, but
|
|
162
|
+
// this package did not write the file, so deleting it would be
|
|
163
|
+
// taking a neighbour's command away without saying so.
|
|
164
|
+
info(
|
|
165
|
+
` claude-code: kept ${wrappers.foreign.length} neighbour command file(s) whose ` +
|
|
166
|
+
`name is a Claude Code built-in (${wrappers.foreign.join(', ')}); not ours to remove`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
160
169
|
}
|
|
161
170
|
if (result.rewritten > 0 && !quiet) {
|
|
162
171
|
info(
|
|
@@ -44,6 +44,14 @@ import {
|
|
|
44
44
|
_emit_windsurf_rule,
|
|
45
45
|
strip_frontmatter,
|
|
46
46
|
} from '../scripts/condense.js';
|
|
47
|
+
import {
|
|
48
|
+
WINDSURFRULES_HEADER,
|
|
49
|
+
cleanOwnedOnly,
|
|
50
|
+
keptLine,
|
|
51
|
+
mayWriteRuleFile,
|
|
52
|
+
mayWriteWindsurfRules,
|
|
53
|
+
ownedPaths,
|
|
54
|
+
} from './host_rule_ownership.js';
|
|
47
55
|
|
|
48
56
|
function _ruleFiles(rulesDir: string): string[] {
|
|
49
57
|
return fs
|
|
@@ -60,63 +68,64 @@ function _ruleFiles(rulesDir: string): string[] {
|
|
|
60
68
|
});
|
|
61
69
|
}
|
|
62
70
|
|
|
63
|
-
/** Remove entries not in `valid` (mirror of condense's `_clean_modern_dir`). */
|
|
64
|
-
function _cleanDir(dir: string, valid: ReadonlySet<string>): void {
|
|
65
|
-
let entries: string[];
|
|
66
|
-
try {
|
|
67
|
-
entries = fs.readdirSync(dir);
|
|
68
|
-
} catch {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
for (const name of entries) {
|
|
72
|
-
if (name === 'README.md' || valid.has(name)) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
const full = path.join(dir, name);
|
|
76
|
-
try {
|
|
77
|
-
if (fs.lstatSync(full).isDirectory()) {
|
|
78
|
-
fs.rmSync(full, { recursive: true, force: true });
|
|
79
|
-
} else {
|
|
80
|
-
fs.unlinkSync(full);
|
|
81
|
-
}
|
|
82
|
-
} catch {
|
|
83
|
-
/* best-effort clean */
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
71
|
export function emitCursor(rulesDir: string, projectRoot: string): number {
|
|
89
72
|
const targetDir = path.join(projectRoot, '.cursor', 'rules');
|
|
90
73
|
const files = _ruleFiles(rulesDir);
|
|
74
|
+
const owned = ownedPaths(projectRoot);
|
|
91
75
|
const valid = new Set<string>();
|
|
76
|
+
let blocked = 0;
|
|
92
77
|
for (const src of files) {
|
|
93
78
|
const name = `${path.basename(src, '.md')}.mdc`;
|
|
94
|
-
|
|
79
|
+
const target = path.join(targetDir, name);
|
|
80
|
+
// Ownership BEFORE the write: a neighbour's file under one of our
|
|
81
|
+
// names would otherwise be destroyed and then skipped by the cleanup
|
|
82
|
+
// pass, which only looks at names this run did not emit.
|
|
83
|
+
if (!mayWriteRuleFile(target, owned)) {
|
|
84
|
+
blocked += 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
_emit_cursor_mdc(src, target);
|
|
95
88
|
valid.add(name);
|
|
96
89
|
}
|
|
97
|
-
|
|
90
|
+
const { kept } = cleanOwnedOnly(targetDir, valid, owned);
|
|
91
|
+
const line = keptLine(kept + blocked);
|
|
92
|
+
if (line !== null) process.stdout.write(`cursor: ${line}\n`);
|
|
98
93
|
return files.length;
|
|
99
94
|
}
|
|
100
95
|
|
|
101
96
|
export function emitWindsurf(rulesDir: string, projectRoot: string): number {
|
|
102
97
|
const perRuleDir = path.join(projectRoot, '.windsurf', 'rules');
|
|
103
98
|
const files = _ruleFiles(rulesDir);
|
|
99
|
+
const owned = ownedPaths(projectRoot);
|
|
104
100
|
const valid = new Set<string>();
|
|
101
|
+
let blocked = 0;
|
|
105
102
|
for (const src of files) {
|
|
106
103
|
const name = path.basename(src);
|
|
107
|
-
|
|
104
|
+
const target = path.join(perRuleDir, name);
|
|
105
|
+
if (!mayWriteRuleFile(target, owned)) {
|
|
106
|
+
blocked += 1;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
_emit_windsurf_rule(src, target);
|
|
108
110
|
valid.add(name);
|
|
109
111
|
}
|
|
110
|
-
|
|
112
|
+
const { kept } = cleanOwnedOnly(perRuleDir, valid, owned);
|
|
113
|
+
const line = keptLine(kept + blocked);
|
|
114
|
+
if (line !== null) process.stdout.write(`windsurf: ${line}\n`);
|
|
111
115
|
|
|
112
116
|
// Concatenated legacy surface — same format as the projection-path
|
|
113
117
|
// generator (condense.generate_windsurfrules), consumer-sourced header.
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
+
const target = path.join(projectRoot, '.windsurfrules');
|
|
119
|
+
if (mayWriteWindsurfRules(target, owned)) {
|
|
120
|
+
const parts = [`${WINDSURFRULES_HEADER}\n`];
|
|
121
|
+
for (const src of files) {
|
|
122
|
+
const content = strip_frontmatter(fs.readFileSync(src, 'utf-8'));
|
|
123
|
+
parts.push(`---\n\n${content.trim()}\n`);
|
|
124
|
+
}
|
|
125
|
+
fs.writeFileSync(target, parts.join('\n') + '\n', 'utf-8');
|
|
126
|
+
} else {
|
|
127
|
+
process.stdout.write('windsurf: kept: 1 neighbour file(s) (.windsurfrules)\n');
|
|
118
128
|
}
|
|
119
|
-
fs.writeFileSync(path.join(projectRoot, '.windsurfrules'), parts.join('\n') + '\n', 'utf-8');
|
|
120
129
|
return files.length;
|
|
121
130
|
}
|
|
122
131
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The rule scope governing a GLOBAL deploy.
|
|
3
|
+
*
|
|
4
|
+
* Moved out of `src/scripts/install.ts` by
|
|
5
|
+
* `road-to-an-installed-layer-that-is-thinned` step 1.1, which adds the thinning
|
|
6
|
+
* call to the same deploy loop. `check_source_size_budget` is a one-way ratchet
|
|
7
|
+
* with no per-change headroom, and this repository's stated convention is that
|
|
8
|
+
* the total falls through EXTRACTION and never rises through a baseline edit —
|
|
9
|
+
* the same reason `claudeRuleRewrite` holds the claude-code post-copy reporting
|
|
10
|
+
* rather than the installer. This function is the nearest self-contained block
|
|
11
|
+
* to the change: it is the predicate the deploy loop resolves once per run, it
|
|
12
|
+
* reaches nothing else in the installer, and its four environment touches are
|
|
13
|
+
* already parameters in all but name.
|
|
14
|
+
*
|
|
15
|
+
* BEHAVIOUR IS UNCHANGED, DELIBERATELY. The body is the installer's, verbatim
|
|
16
|
+
* apart from the four injected seams below; `install.ts` keeps a wrapper of the
|
|
17
|
+
* same name and signature, so its re-export and every caller and test see what
|
|
18
|
+
* they saw before. A behaviour change smuggled into an extraction is the one
|
|
19
|
+
* thing that would make the line saving not worth having.
|
|
20
|
+
*
|
|
21
|
+
* The seams are injected rather than imported because each one is an
|
|
22
|
+
* install-time decision the installer owns: where the global settings doc lives,
|
|
23
|
+
* how this build reads and parses YAML, what the packaged template says, and
|
|
24
|
+
* where a warning goes.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { LEGACY_ALL, ruleScopeFromSettings, type RuleScope } from './rule_scope.js';
|
|
28
|
+
|
|
29
|
+
export interface GlobalRuleScopeInputs {
|
|
30
|
+
/** The global settings file, or `null` when no artefact exists at all. */
|
|
31
|
+
readonly settingsPath: string | null;
|
|
32
|
+
/** The package being installed from. */
|
|
33
|
+
readonly packageRoot: string;
|
|
34
|
+
/** Read a file as text; throws like `fs.readFileSync` when it cannot. */
|
|
35
|
+
readonly readText: (p: string) => string;
|
|
36
|
+
/** Parse YAML permissively — anything unparseable comes back non-object. */
|
|
37
|
+
readonly parseYaml: (text: string) => unknown;
|
|
38
|
+
/** The packaged template settings, read only on a genuinely fresh machine. */
|
|
39
|
+
readonly loadDefaults: () => Record<string, unknown>;
|
|
40
|
+
/** Where a loud fallback goes. */
|
|
41
|
+
readonly warn: (message: string) => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function isPlainObject(v: unknown): boolean {
|
|
45
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the rule scope governing THIS global deploy — the same way the wizard
|
|
50
|
+
* does (`src/server/routes/install.ts::_resolveRuleScope`), so the two global
|
|
51
|
+
* paths cannot ship different rule sets for the same settings.
|
|
52
|
+
*
|
|
53
|
+
* Settings resolution mirrors `_resolve_scoped_projection` above: an existing
|
|
54
|
+
* global settings doc is authoritative, and only a genuinely fresh machine falls
|
|
55
|
+
* through to the packaged template. Any read or parse failure resolves to
|
|
56
|
+
* `LEGACY_ALL` — over-shipping is the safe direction, and the compat exclusion
|
|
57
|
+
* (`source-of-truth.md`) still applies even then.
|
|
58
|
+
*/
|
|
59
|
+
export function resolveGlobalRuleScope(inputs: GlobalRuleScopeInputs): RuleScope {
|
|
60
|
+
const { packageRoot, warn } = inputs;
|
|
61
|
+
const settings_path = inputs.settingsPath;
|
|
62
|
+
|
|
63
|
+
// No global settings artefact at all — a genuinely fresh machine. Fall
|
|
64
|
+
// through to the packaged template silently: there is no user decision to
|
|
65
|
+
// contradict, and this is the documented upgrade-compat path.
|
|
66
|
+
if (settings_path === null) {
|
|
67
|
+
try {
|
|
68
|
+
return ruleScopeFromSettings(inputs.loadDefaults(), packageRoot);
|
|
69
|
+
} catch {
|
|
70
|
+
return LEGACY_ALL;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// A doc EXISTS, so the user has expressed a configuration. Failing to read
|
|
75
|
+
// it is not the same as not having one: falling back to legacy-all here
|
|
76
|
+
// ships the maintainer-only rules the user may have deliberately scoped out,
|
|
77
|
+
// and `_load_yaml_doc` would report that as an indistinguishable `{}`. So
|
|
78
|
+
// parse it explicitly and be LOUD when it does not parse — over-shipping
|
|
79
|
+
// stays the safe direction, but it must not be a silent one.
|
|
80
|
+
let text: string;
|
|
81
|
+
try {
|
|
82
|
+
text = inputs.readText(settings_path);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
warn(
|
|
85
|
+
`could not read ${settings_path} (${String(e)}) — rule scoping falls back ` +
|
|
86
|
+
'to legacy-all, so ALL rules including maintainer-only ones will be ' +
|
|
87
|
+
'installed. Fix the file to restore scoping.',
|
|
88
|
+
);
|
|
89
|
+
return LEGACY_ALL;
|
|
90
|
+
}
|
|
91
|
+
const parsed = inputs.parseYaml(text);
|
|
92
|
+
if (!isPlainObject(parsed)) {
|
|
93
|
+
warn(
|
|
94
|
+
`${settings_path} is not a YAML mapping — rule scoping falls back to ` +
|
|
95
|
+
'legacy-all, so ALL rules including maintainer-only ones will be ' +
|
|
96
|
+
'installed. Fix the file to restore scoping.',
|
|
97
|
+
);
|
|
98
|
+
return LEGACY_ALL;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
return ruleScopeFromSettings(parsed as Record<string, unknown>, packageRoot);
|
|
102
|
+
} catch (e) {
|
|
103
|
+
warn(
|
|
104
|
+
`could not derive rule scope from ${settings_path} (${String(e)}) — ` +
|
|
105
|
+
'falling back to legacy-all; ALL rules will be installed.',
|
|
106
|
+
);
|
|
107
|
+
return LEGACY_ALL;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which host-rule files this package may delete or overwrite.
|
|
3
|
+
*
|
|
4
|
+
* The defect this closes: `_cleanDir` removed every entry under
|
|
5
|
+
* `.cursor/rules` and `.windsurf/rules` whose NAME was not one this run had
|
|
6
|
+
* just emitted, and `.windsurfrules` was overwritten unconditionally. A rule
|
|
7
|
+
* file another agent package wrote — or one the consumer wrote by hand — was
|
|
8
|
+
* destroyed on every install, which is the opposite of what the uninstall
|
|
9
|
+
* claim promises.
|
|
10
|
+
*
|
|
11
|
+
* Ownership is read from the installed-tools manifest's `files[]` inventory,
|
|
12
|
+
* never from a marker inside the file. The `.mdc` emitter writes no package
|
|
13
|
+
* tag (`condense.ts` `_emit_cursor_mdc`), so a tag-based gate would classify
|
|
14
|
+
* every file this package ever wrote as foreign and therefore never remove a
|
|
15
|
+
* stale one — it would read as conservative and in fact be inert. The manifest
|
|
16
|
+
* is the record of what this installer actually put on disk, so it is the
|
|
17
|
+
* thing that can answer the question.
|
|
18
|
+
*
|
|
19
|
+
* This module only READS that manifest. It never rewrites it: the available
|
|
20
|
+
* reader (`installed_tools.read_manifest`) drops nested `files[]` by design,
|
|
21
|
+
* so a read-modify-write through it would erase every other tool's inventory —
|
|
22
|
+
* the failure `manifestFiles.ts` documents at length.
|
|
23
|
+
*
|
|
24
|
+
* The consequence, stated rather than implied: a consumer whose manifest does
|
|
25
|
+
* not claim a path gets that path KEPT. Unproven means kept, never deleted.
|
|
26
|
+
* That is the safe direction for this lane and it is also a real limit — a
|
|
27
|
+
* stale file of ours sitting under an unclaimed path stays until something
|
|
28
|
+
* claims it.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import * as fs from 'node:fs';
|
|
32
|
+
import * as path from 'node:path';
|
|
33
|
+
|
|
34
|
+
import { sha256OfFile } from './fsPrimitives.js';
|
|
35
|
+
import { classifyOwnership, recordedHashesForRoot, type RecordedHashes } from './recordedOwnership.js';
|
|
36
|
+
|
|
37
|
+
/** The first line every `.windsurfrules` this package generates carries. */
|
|
38
|
+
export const WINDSURFRULES_HEADER = '# Auto-generated from .augment/rules/ — do not edit directly';
|
|
39
|
+
|
|
40
|
+
export interface CleanResult {
|
|
41
|
+
/** Entry names removed from the directory. */
|
|
42
|
+
removed: string[];
|
|
43
|
+
/** Entries kept because nothing proves this package wrote them. */
|
|
44
|
+
kept: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Every file path beneath `full`, or `[full]` when it is a file. */
|
|
48
|
+
function filesUnder(full: string): string[] {
|
|
49
|
+
let stat: fs.Stats;
|
|
50
|
+
try {
|
|
51
|
+
stat = fs.lstatSync(full);
|
|
52
|
+
} catch {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
if (!stat.isDirectory()) return [full];
|
|
56
|
+
const out: string[] = [];
|
|
57
|
+
for (const name of fs.readdirSync(full)) {
|
|
58
|
+
out.push(...filesUnder(path.join(full, name)));
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Is this exact file ours AND still carrying the bytes we wrote?
|
|
65
|
+
*
|
|
66
|
+
* The recorded digest is the point, not the path. A path-membership test
|
|
67
|
+
* answers "did we ever write here", which merges two materially different
|
|
68
|
+
* trees: a generated file still as we left it, and one the consumer has since
|
|
69
|
+
* edited. Deleting the second loses their work, and `recordedOwnership` exists
|
|
70
|
+
* to tell them apart — importing its map and then ignoring its hashes was the
|
|
71
|
+
* defect an independent review named here.
|
|
72
|
+
*/
|
|
73
|
+
function isUnchangedOurs(file: string, owned: RecordedHashes): boolean {
|
|
74
|
+
const target = path.resolve(file);
|
|
75
|
+
if (!owned.has(target)) return false;
|
|
76
|
+
return classifyOwnership(owned.get(target), sha256OfFile(target)) === 'recorded-unchanged';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Remove the stale entries of ours from `dir`, keeping everything else.
|
|
81
|
+
*
|
|
82
|
+
* An entry is removable only when every file it contains is ours AND
|
|
83
|
+
* unmodified: one unclaimed or edited file inside a directory keeps the whole
|
|
84
|
+
* directory, because removing it would take that file with it.
|
|
85
|
+
*/
|
|
86
|
+
export function cleanOwnedOnly(
|
|
87
|
+
dir: string,
|
|
88
|
+
valid: ReadonlySet<string>,
|
|
89
|
+
owned: RecordedHashes,
|
|
90
|
+
): CleanResult {
|
|
91
|
+
let entries: string[];
|
|
92
|
+
try {
|
|
93
|
+
entries = fs.readdirSync(dir);
|
|
94
|
+
} catch {
|
|
95
|
+
return { removed: [], kept: 0 };
|
|
96
|
+
}
|
|
97
|
+
const removed: string[] = [];
|
|
98
|
+
let kept = 0;
|
|
99
|
+
for (const name of entries) {
|
|
100
|
+
if (name === 'README.md' || valid.has(name)) continue;
|
|
101
|
+
const full = path.join(dir, name);
|
|
102
|
+
const contained = filesUnder(full);
|
|
103
|
+
const ours = contained.length > 0 && contained.every((f) => isUnchangedOurs(f, owned));
|
|
104
|
+
if (!ours) {
|
|
105
|
+
kept += 1;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
fs.rmSync(full, { recursive: true, force: true });
|
|
110
|
+
removed.push(name);
|
|
111
|
+
} catch {
|
|
112
|
+
kept += 1;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return { removed, kept };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* May this package write `.windsurfrules` at `target`?
|
|
120
|
+
*
|
|
121
|
+
* Yes when the file is absent, or when it still carries the header this
|
|
122
|
+
* package generates. Nothing else.
|
|
123
|
+
*
|
|
124
|
+
* A manifest claim is deliberately NOT a second route in. The file is
|
|
125
|
+
* generated and overwritten on every install, so the header IS the ownership
|
|
126
|
+
* signal and it is content-derived: if the header is gone, something replaced
|
|
127
|
+
* the file, and "the manifest says we wrote here once" is exactly the stale
|
|
128
|
+
* fact that would let us overwrite a neighbour's replacement. An independent
|
|
129
|
+
* review caught that route open, with a fixture asserting it.
|
|
130
|
+
*/
|
|
131
|
+
export function mayWriteWindsurfRules(target: string, owned: RecordedHashes): boolean {
|
|
132
|
+
void owned;
|
|
133
|
+
if (!fs.existsSync(target)) return true;
|
|
134
|
+
let head: string;
|
|
135
|
+
try {
|
|
136
|
+
head = fs.readFileSync(target, 'utf-8').split('\n', 1)[0] ?? '';
|
|
137
|
+
} catch {
|
|
138
|
+
// Unreadable is unproven, and unproven means do not touch it.
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
return head.trim() === WINDSURFRULES_HEADER;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* May this package write a rule file at `target`?
|
|
146
|
+
*
|
|
147
|
+
* The cleanup pass is not enough on its own, and an independent review found
|
|
148
|
+
* the hole: `_cleanDir` skips every name this run just emitted, so a
|
|
149
|
+
* neighbour's `foo.mdc` that happens to share a basename with one of our
|
|
150
|
+
* rules was already OVERWRITTEN by the time ownership was consulted. The
|
|
151
|
+
* check has to run BEFORE the write, which is what this is for.
|
|
152
|
+
*
|
|
153
|
+
* Absent, or ours and unmodified → write. Anything else is someone's file or
|
|
154
|
+
* someone's edit, and is left exactly as it is.
|
|
155
|
+
*/
|
|
156
|
+
export function mayWriteRuleFile(target: string, owned: RecordedHashes): boolean {
|
|
157
|
+
if (!fs.existsSync(target)) return true;
|
|
158
|
+
return isUnchangedOurs(target, owned);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** The manifest's claimed paths for a consumer root; empty when none resolves. */
|
|
162
|
+
export function ownedPaths(projectRoot: string): RecordedHashes {
|
|
163
|
+
return recordedHashesForRoot(projectRoot);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** The one line the emitter prints when it kept a neighbour's files. */
|
|
167
|
+
export function keptLine(kept: number): string | null {
|
|
168
|
+
if (kept <= 0) return null;
|
|
169
|
+
return `kept: ${kept} neighbour file(s)`;
|
|
170
|
+
}
|