@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
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The unclaimed-file scan under this package's own deploy roots.
|
|
3
|
+
*
|
|
4
|
+
* Moved verbatim out of `src/scripts/_cli/cmd_doctor.ts`
|
|
5
|
+
* (road-to-a-tree-that-keeps-its-neighbours Phase 2.6). The behaviour is
|
|
6
|
+
* unchanged — this is a module boundary, not a rewrite.
|
|
7
|
+
*
|
|
8
|
+
* Two reasons it earns its own file. `cmd_doctor.ts` is 2,100 lines above the
|
|
9
|
+
* `check_source_size_budget` ceiling, so the census line that now links this
|
|
10
|
+
* listing is paid for by a MOVE rather than by raising the tree-wide excess.
|
|
11
|
+
* And the neighbour census answers a strictly larger question than this scan
|
|
12
|
+
* does — this one lists FILES under paths this package deploys to, the census
|
|
13
|
+
* lists ARTEFACTS wherever a host keeps them — so the two belong beside each
|
|
14
|
+
* other rather than nested inside a doctor renderer.
|
|
15
|
+
*
|
|
16
|
+
* What this scan does NOT do, stated because the two listings look alike: it
|
|
17
|
+
* never leaves a deploy root, so a neighbour's skill in `~/.claude/skills` or
|
|
18
|
+
* hook entry in `.cursor/hooks.json` is invisible to it. That gap is the
|
|
19
|
+
* census's subject, and the census links back here rather than repeating the
|
|
20
|
+
* paths this one already prints.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import * as fs from 'node:fs';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `Path.rglob("*")` — every descendant path (dirs + files), recursively.
|
|
27
|
+
*
|
|
28
|
+
* Order is not relied upon by callers (they sort the matched set), but the
|
|
29
|
+
* walk is deterministic (sorted per directory) to keep behaviour stable.
|
|
30
|
+
*/
|
|
31
|
+
export function rglob(root: string, isDir: (p: string) => boolean, join: (a: string, b: string) => string): string[] {
|
|
32
|
+
const out: string[] = [];
|
|
33
|
+
const walk = (dir: string): void => {
|
|
34
|
+
let entries: fs.Dirent[];
|
|
35
|
+
try {
|
|
36
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
37
|
+
} catch {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
41
|
+
for (const ent of entries) {
|
|
42
|
+
const full = join(dir, ent.name);
|
|
43
|
+
out.push(full);
|
|
44
|
+
let dirLike = ent.isDirectory();
|
|
45
|
+
if (ent.isSymbolicLink()) {
|
|
46
|
+
// pathlib rglob follows into symlinked dirs.
|
|
47
|
+
dirLike = isDir(full);
|
|
48
|
+
}
|
|
49
|
+
if (dirLike) {
|
|
50
|
+
walk(full);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
walk(root);
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ForeignScanDeps {
|
|
59
|
+
pathExists: (p: string) => boolean;
|
|
60
|
+
isDir: (p: string) => boolean;
|
|
61
|
+
isFile: (p: string) => boolean;
|
|
62
|
+
resolvePath: (p: string) => string;
|
|
63
|
+
join: (a: string, b: string) => string;
|
|
64
|
+
/** Resolve one declared deploy root against the consumer root. */
|
|
65
|
+
resolveRoot: (projectRoot: string, rel: string) => string;
|
|
66
|
+
defaultRoots: readonly string[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Walk every declared deploy root and surface unclaimed files. Only regular
|
|
71
|
+
* files under `deploy_roots` count; bookkeeping is on the resolved final path.
|
|
72
|
+
*/
|
|
73
|
+
export function scanForeign(
|
|
74
|
+
projectRoot: string,
|
|
75
|
+
manifest: Record<string, unknown>,
|
|
76
|
+
known: Set<string>,
|
|
77
|
+
deps: ForeignScanDeps,
|
|
78
|
+
): string[] {
|
|
79
|
+
const roots = (manifest['deploy_roots'] as unknown[] | undefined) || Array.from(deps.defaultRoots);
|
|
80
|
+
const foreign: string[] = [];
|
|
81
|
+
const seen = new Set<string>();
|
|
82
|
+
for (const root_rel of roots) {
|
|
83
|
+
const root = deps.resolveRoot(projectRoot, String(root_rel));
|
|
84
|
+
if (!deps.pathExists(root) || !deps.isDir(root)) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
for (const child of rglob(root, deps.isDir, deps.join)) {
|
|
88
|
+
if (!deps.isFile(child)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
let resolved: string;
|
|
92
|
+
try {
|
|
93
|
+
resolved = deps.resolvePath(child);
|
|
94
|
+
} catch {
|
|
95
|
+
resolved = child;
|
|
96
|
+
}
|
|
97
|
+
if (known.has(resolved) || seen.has(resolved)) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
seen.add(resolved);
|
|
101
|
+
foreign.push(child);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
foreign.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
105
|
+
return foreign;
|
|
106
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one reading of a `--base` value, shared by `sync_pr_branch` and
|
|
3
|
+
* `check_branch_freshness`.
|
|
4
|
+
*
|
|
5
|
+
* The two resolvers used to accept different spellings: one prefixed every
|
|
6
|
+
* value with `origin/`, the other asked the server for `refs/heads/<value>`
|
|
7
|
+
* verbatim. A name copied from one tool's output into the other then named a
|
|
8
|
+
* ref nobody has (`origin/origin/main`, `refs/heads/origin/main`), and the
|
|
9
|
+
* freshness gate read that absent ref as an unreachable remote and passed.
|
|
10
|
+
*
|
|
11
|
+
* A value that already names where it lives is kept as given: a
|
|
12
|
+
* remote-tracking ref and `<remote>/x` for a configured remote. `refs/heads/x`
|
|
13
|
+
* names the branch on origin, so it maps to `refs/remotes/origin/x`: the local
|
|
14
|
+
* branch of that name is the same clone-time copy a bare name avoids, and a
|
|
15
|
+
* fetch never updates it. Anything else is a branch name on origin, slashes
|
|
16
|
+
* included, because `release/1.x` is a branch name and not a remote called
|
|
17
|
+
* `release`.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export interface BaseRef {
|
|
21
|
+
/** The remote the server-side SHA is asked of. */
|
|
22
|
+
readonly remote: string;
|
|
23
|
+
/** The branch name on that remote. */
|
|
24
|
+
readonly branch: string;
|
|
25
|
+
/** The ref git operations use locally: as given, or `origin/<branch>` for a bare name. */
|
|
26
|
+
readonly ref: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const REMOTE_TRACKING = 'refs/remotes/';
|
|
30
|
+
const LOCAL_HEADS = 'refs/heads/';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The usage error for a `--base` given a blank value, or null for one that
|
|
34
|
+
* names something. Every tool that accepts `--base` rejects a blank one: an
|
|
35
|
+
* unset variable expands to nothing, and reading that as "no override" judged
|
|
36
|
+
* the run against the default branch without a word.
|
|
37
|
+
*/
|
|
38
|
+
export function blankBaseError(value: string): string | null {
|
|
39
|
+
return value.trim() === '' ? '--base was given an empty value — name the base branch (an unset variable expands to nothing); nothing was read or merged' : null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The usage error for any `--base` value that must not reach git: a blank one,
|
|
44
|
+
* or one whose branch name starts with `-`, which git would read as an option.
|
|
45
|
+
* No branch can carry that name (`git check-ref-format --branch` refuses it).
|
|
46
|
+
*/
|
|
47
|
+
export function baseValueError(value: string, remotes: readonly string[] = []): string | null {
|
|
48
|
+
const blank = blankBaseError(value);
|
|
49
|
+
if (blank !== null) return blank;
|
|
50
|
+
const v = value.trim();
|
|
51
|
+
const branch = v.startsWith('-') ? v : (parseBaseRef(v, remotes)?.branch ?? v);
|
|
52
|
+
return branch.startsWith('-') ? `--base ${JSON.stringify(v)} names a branch that starts with "-", which git reads as an option — no branch has that name; nothing was read or merged` : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Read a `--base` value; null when it is empty. `remotes` are the configured remote names. */
|
|
56
|
+
export function parseBaseRef(value: string, remotes: readonly string[] = []): BaseRef | null {
|
|
57
|
+
const v = value.trim();
|
|
58
|
+
if (v === '') return null;
|
|
59
|
+
if (v.startsWith(LOCAL_HEADS) && v.length > LOCAL_HEADS.length) {
|
|
60
|
+
const branch = v.slice(LOCAL_HEADS.length);
|
|
61
|
+
return { remote: 'origin', branch, ref: `${REMOTE_TRACKING}origin/${branch}` };
|
|
62
|
+
}
|
|
63
|
+
if (v.startsWith('refs/')) return splitResolvedRef(v);
|
|
64
|
+
const slash = v.indexOf('/');
|
|
65
|
+
const known = new Set(['origin', ...remotes]);
|
|
66
|
+
if (slash > 0 && slash < v.length - 1 && known.has(v.slice(0, slash))) {
|
|
67
|
+
return { remote: v.slice(0, slash), branch: v.slice(slash + 1), ref: v };
|
|
68
|
+
}
|
|
69
|
+
return { remote: 'origin', branch: v, ref: `origin/${v}` };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Split a ref that was already resolved by `parseBaseRef` or reported by git
|
|
74
|
+
* (`origin/main`, `refs/heads/main`). A full ref outside the branch namespaces
|
|
75
|
+
* keeps its whole name as the branch, so the server answers it as unknown.
|
|
76
|
+
*/
|
|
77
|
+
export function splitResolvedRef(ref: string): BaseRef {
|
|
78
|
+
if (ref.startsWith(LOCAL_HEADS)) return { remote: 'origin', branch: ref.slice(LOCAL_HEADS.length), ref };
|
|
79
|
+
if (ref.startsWith(REMOTE_TRACKING)) {
|
|
80
|
+
const rest = ref.slice(REMOTE_TRACKING.length);
|
|
81
|
+
const slash = rest.indexOf('/');
|
|
82
|
+
if (slash > 0) return { remote: rest.slice(0, slash), branch: rest.slice(slash + 1), ref };
|
|
83
|
+
}
|
|
84
|
+
if (ref.startsWith('refs/')) return { remote: 'origin', branch: ref, ref };
|
|
85
|
+
const slash = ref.indexOf('/');
|
|
86
|
+
return slash > 0 ? { remote: ref.slice(0, slash), branch: ref.slice(slash + 1), ref } : { remote: 'origin', branch: ref, ref: `origin/${ref}` };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** `<remote>/<branch>`, the name a human reads and `task push-ready BASE=` accepts. */
|
|
90
|
+
export function displayBase(b: BaseRef): string {
|
|
91
|
+
return `${b.remote}/${b.branch}`;
|
|
92
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one reader of the `git.*` convention keys.
|
|
3
|
+
*
|
|
4
|
+
* `load_agent_settings` merges a layer that does not parse as if it were absent
|
|
5
|
+
* and drops user-global keys off its whitelist without a word, which is right
|
|
6
|
+
* for a setting whose default is harmless and wrong for these three: a team that
|
|
7
|
+
* declares `rebase` and gets a merge commit because an unrelated line elsewhere
|
|
8
|
+
* in the file has an unclosed bracket has had its convention overridden by a
|
|
9
|
+
* default nobody chose. So every key is reported with one of six states, and a
|
|
10
|
+
* caller that acts on the value refuses on anything but `valid` or `absent`:
|
|
11
|
+
*
|
|
12
|
+
* - `valid` — the deciding layer parsed and the value is allowed;
|
|
13
|
+
* - `absent` — no layer sets the key; the template default is reported;
|
|
14
|
+
* - `malformed` — a layer at or above the deciding one does not parse, so the
|
|
15
|
+
* value is unknowable;
|
|
16
|
+
* - `invalid` — the deciding layer sets a value the schema does not allow;
|
|
17
|
+
* - `discarded` — only a user-global file sets the key, and the loader drops
|
|
18
|
+
* user-global keys that are not whitelisted;
|
|
19
|
+
* - `unresolvable` — the commit a committed declaration must be read at cannot
|
|
20
|
+
* be resolved, so whether it declares anything is unknown.
|
|
21
|
+
*
|
|
22
|
+
* Where the layers come from is a {@link GitConventionSource}, so a reader of a
|
|
23
|
+
* committed declaration can replace the checkout cascade without touching the
|
|
24
|
+
* state logic.
|
|
25
|
+
*/
|
|
26
|
+
import { spawnSync } from 'node:child_process';
|
|
27
|
+
import { createRequire } from 'node:module';
|
|
28
|
+
import * as fs from 'node:fs';
|
|
29
|
+
|
|
30
|
+
import type * as YamlModule from 'yaml';
|
|
31
|
+
|
|
32
|
+
import { settings_layer_states, template_defaults, user_global_settings_paths } from './agent_settings.js';
|
|
33
|
+
|
|
34
|
+
const _require = createRequire(import.meta.url);
|
|
35
|
+
|
|
36
|
+
export const GIT_CONVENTION_KEYS = ['commit_format', 'branch_pattern', 'update_strategy'] as const;
|
|
37
|
+
export type GitConventionKey = (typeof GIT_CONVENTION_KEYS)[number];
|
|
38
|
+
|
|
39
|
+
export type GitConventionState = 'valid' | 'absent' | 'malformed' | 'invalid' | 'discarded' | 'unresolvable';
|
|
40
|
+
|
|
41
|
+
/** Mirrors the enums in `agent-settings.schema.json`; a test pins the parity. */
|
|
42
|
+
export const GIT_CONVENTION_ENUMS: Partial<Record<GitConventionKey, readonly string[]>> = {
|
|
43
|
+
commit_format: ['ticket-scope', 'ticket-conventional'],
|
|
44
|
+
update_strategy: ['merge', 'rebase'],
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type GitConventionReason =
|
|
48
|
+
| 'git-convention-malformed'
|
|
49
|
+
| 'git-convention-invalid'
|
|
50
|
+
| 'git-convention-discarded'
|
|
51
|
+
| 'git-convention-unresolvable';
|
|
52
|
+
|
|
53
|
+
export interface GitConventionReading {
|
|
54
|
+
key: GitConventionKey;
|
|
55
|
+
value: string | null;
|
|
56
|
+
source: string | null;
|
|
57
|
+
state: GitConventionState;
|
|
58
|
+
reason: GitConventionReason | null;
|
|
59
|
+
detail: string | null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface GitConventionLayer {
|
|
63
|
+
path: string;
|
|
64
|
+
parsed: 'absent' | 'valid' | 'malformed';
|
|
65
|
+
data: unknown;
|
|
66
|
+
/** False for a layer whose `git.*` values the loader discards. */
|
|
67
|
+
carries: boolean;
|
|
68
|
+
/** Why a `malformed` layer is unknown: it does not parse, or its document is not a map. */
|
|
69
|
+
why?: string;
|
|
70
|
+
/** Set when the document parses but is not the shape the file is read in; every key reads `invalid`. */
|
|
71
|
+
shapeError?: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface GitConventionSource {
|
|
75
|
+
/** Every layer, lowest precedence first. */
|
|
76
|
+
layers(): GitConventionLayer[];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type GitConventionDefaults = Partial<Record<GitConventionKey, string>>;
|
|
80
|
+
|
|
81
|
+
function _parse(p: string): Pick<GitConventionLayer, 'parsed' | 'data' | 'why'> {
|
|
82
|
+
let text: string;
|
|
83
|
+
try {
|
|
84
|
+
if (!fs.statSync(p).isFile()) return { parsed: 'absent', data: null };
|
|
85
|
+
text = fs.readFileSync(p, 'utf-8');
|
|
86
|
+
} catch (err) {
|
|
87
|
+
if ((err as NodeJS.ErrnoException).code === 'ENOENT') return { parsed: 'absent', data: null };
|
|
88
|
+
return { parsed: 'malformed', data: null, why: 'the file cannot be read' };
|
|
89
|
+
}
|
|
90
|
+
return parseLayerText(text);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Where the parse failed. An unquoted pattern (`{ticket}-{slug}`) is a flow
|
|
95
|
+
* mapping to YAML, and the error says nothing about quoting.
|
|
96
|
+
*/
|
|
97
|
+
function _parseFailure(text: string, err: unknown): string {
|
|
98
|
+
const line = (err as { linePos?: { line: number }[] }).linePos?.[0]?.line;
|
|
99
|
+
if (line === undefined) return 'the file does not parse';
|
|
100
|
+
const quote = (text.split('\n')[line - 1] ?? '').includes('{') ? `; a value containing \`{\` must be quoted, e.g. ${_quoteExample('branch_pattern')}` : '';
|
|
101
|
+
return `the file does not parse at line ${line}${quote}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function _quoteExample(key: GitConventionKey): string {
|
|
105
|
+
return `${key}: "${key === 'branch_pattern' ? '{ticket}-{slug}' : (GIT_CONVENTION_ENUMS[key]?.[0] ?? '…')}"`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** One layer's text, parsed the way the settings loader parses a file. */
|
|
109
|
+
export function parseLayerText(text: string): Pick<GitConventionLayer, 'parsed' | 'data' | 'why'> {
|
|
110
|
+
let data: unknown;
|
|
111
|
+
try {
|
|
112
|
+
const YAML = _require('yaml') as typeof YamlModule;
|
|
113
|
+
data = YAML.parse(text, { version: '1.1' });
|
|
114
|
+
} catch (err) {
|
|
115
|
+
return { parsed: 'malformed', data: null, why: _parseFailure(text, err) };
|
|
116
|
+
}
|
|
117
|
+
if (data === null || data === undefined) return { parsed: 'valid', data: {} };
|
|
118
|
+
// The loader ignores a document that is not a map, which is the same silent
|
|
119
|
+
// fallback as a parse error.
|
|
120
|
+
if (typeof data !== 'object' || Array.isArray(data)) return { parsed: 'malformed', data: null, why: 'the document is not a map' };
|
|
121
|
+
return { parsed: 'valid', data };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Explicit files: the user-global ones carry nothing, the developer ones carry. */
|
|
125
|
+
export function fileSource(files: { userGlobal?: readonly string[]; developer?: readonly string[] }): GitConventionSource {
|
|
126
|
+
return {
|
|
127
|
+
layers: () => [
|
|
128
|
+
...(files.userGlobal ?? []).map((p) => ({ path: p, carries: false, ..._parse(p) })),
|
|
129
|
+
...(files.developer ?? []).map((p) => ({ path: p, carries: true, ..._parse(p) })),
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** The layers `load_agent_settings({ cwd })` reads for the checkout at `cwd`. */
|
|
135
|
+
export function checkoutSource(cwd: string): GitConventionSource {
|
|
136
|
+
return {
|
|
137
|
+
layers: () => {
|
|
138
|
+
const userGlobalCount = user_global_settings_paths().length;
|
|
139
|
+
const all = settings_layer_states({ cwd }).map((l) => l.path);
|
|
140
|
+
return fileSource({ userGlobal: all.slice(0, userGlobalCount), developer: all.slice(userGlobalCount) }).layers();
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
type Lookup = { present: false } | { present: true; value: unknown } | { present: true; notAMap: true };
|
|
146
|
+
|
|
147
|
+
function _lookup(data: unknown, key: GitConventionKey): Lookup {
|
|
148
|
+
if (data === null || typeof data !== 'object') return { present: false };
|
|
149
|
+
const git = (data as Record<string, unknown>).git;
|
|
150
|
+
if (git === undefined || git === null) return { present: false };
|
|
151
|
+
if (typeof git !== 'object' || Array.isArray(git)) return { present: true, notAMap: true };
|
|
152
|
+
const value = (git as Record<string, unknown>)[key];
|
|
153
|
+
if (value === undefined || value === null) return { present: false };
|
|
154
|
+
return { present: true, value };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const BRANCH_PLACEHOLDERS = ['type', 'ticket', 'slug'] as const;
|
|
158
|
+
const BRANCH_SAMPLE: Record<(typeof BRANCH_PLACEHOLDERS)[number], string> = {
|
|
159
|
+
type: 'feat',
|
|
160
|
+
ticket: 'DEV-1234',
|
|
161
|
+
slug: 'sample-change',
|
|
162
|
+
};
|
|
163
|
+
/** A rendered name reaches shell commands, so the literal alphabet is closed. */
|
|
164
|
+
const BRANCH_LITERAL = /^[A-Za-z0-9._/-]*$/;
|
|
165
|
+
|
|
166
|
+
/** The pattern with every placeholder filled from a fixed sample. */
|
|
167
|
+
export function renderBranchSample(pattern: string): string {
|
|
168
|
+
return pattern.replace(/\{(type|ticket|slug)\}/g, (_m, name: keyof typeof BRANCH_SAMPLE) => BRANCH_SAMPLE[name]);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function _branchPatternReason(pattern: string): string | null {
|
|
172
|
+
if (pattern === '') return 'the pattern is empty';
|
|
173
|
+
const literal = pattern.replace(/\{([^{}]*)\}/g, (match, name: string) => {
|
|
174
|
+
return (BRANCH_PLACEHOLDERS as readonly string[]).includes(name) ? '' : `\u0000${match}`;
|
|
175
|
+
});
|
|
176
|
+
const unknown = /\u0000(\{[^{}]*\})/.exec(literal);
|
|
177
|
+
if (unknown !== null) {
|
|
178
|
+
return `unknown placeholder ${unknown[1]}; allowed: ${BRANCH_PLACEHOLDERS.map((p) => `{${p}}`).join(', ')}`;
|
|
179
|
+
}
|
|
180
|
+
if (/[{}]/.test(literal)) return 'an unbalanced brace';
|
|
181
|
+
if (!BRANCH_LITERAL.test(literal)) {
|
|
182
|
+
const bad = [...new Set(literal.replace(/[A-Za-z0-9._/-]/g, ''))].join('');
|
|
183
|
+
return `literal character(s) ${JSON.stringify(bad)} outside [A-Za-z0-9._/-]`;
|
|
184
|
+
}
|
|
185
|
+
if (!pattern.includes('{slug}')) return 'the pattern must contain {slug}';
|
|
186
|
+
const sample = renderBranchSample(pattern);
|
|
187
|
+
const check = spawnSync('git', ['check-ref-format', '--branch', sample], { encoding: 'utf8' });
|
|
188
|
+
// Without git the closed alphabet above is the whole check.
|
|
189
|
+
if (check.error === undefined && check.status !== 0) {
|
|
190
|
+
return `the sample \`${sample}\` fails git check-ref-format --branch`;
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Why `value` is not allowed for `key`, or null when it is. */
|
|
196
|
+
export function invalidReason(key: GitConventionKey, value: string): string | null {
|
|
197
|
+
// The schema neither trims nor folds case, so neither does this check.
|
|
198
|
+
if (value !== value.trim()) return `\`${value}\` has leading or trailing whitespace`;
|
|
199
|
+
const allowed = GIT_CONVENTION_ENUMS[key];
|
|
200
|
+
if (allowed !== undefined) {
|
|
201
|
+
if (allowed.includes(value)) return null;
|
|
202
|
+
const caseOnly = allowed.includes(value.toLowerCase()) ? ' (values are case-sensitive)' : '';
|
|
203
|
+
return `\`${value}\` is not one of ${allowed.map((v) => `\`${v}\``).join(', ')}${caseOnly}`;
|
|
204
|
+
}
|
|
205
|
+
return _branchPatternReason(value);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function _defaults(): GitConventionDefaults {
|
|
209
|
+
const git = (template_defaults() as { git?: Record<string, unknown> }).git ?? {};
|
|
210
|
+
const out: GitConventionDefaults = {};
|
|
211
|
+
for (const key of GIT_CONVENTION_KEYS) {
|
|
212
|
+
if (typeof git[key] === 'string') out[key] = git[key] as string;
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** The template default for a key, or null when the template sets none. */
|
|
218
|
+
export function conventionDefault(key: GitConventionKey): string | null {
|
|
219
|
+
return _defaults()[key] ?? null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function conventionReading(
|
|
223
|
+
key: GitConventionKey,
|
|
224
|
+
state: GitConventionState,
|
|
225
|
+
value: string | null,
|
|
226
|
+
source: string | null,
|
|
227
|
+
detail: string | null = null,
|
|
228
|
+
): GitConventionReading {
|
|
229
|
+
const reason: GitConventionReason | null = isRefusal(state) ? (`git-convention-${state}` as GitConventionReason) : null;
|
|
230
|
+
return { key, value, source, state, reason, detail };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export function readGitConventionKey(
|
|
234
|
+
key: GitConventionKey,
|
|
235
|
+
source: GitConventionSource,
|
|
236
|
+
defaults: GitConventionDefaults = _defaults(),
|
|
237
|
+
): GitConventionReading {
|
|
238
|
+
const layers = source.layers();
|
|
239
|
+
const fallback = defaults[key] ?? null;
|
|
240
|
+
for (const layer of [...layers].reverse().filter((l) => l.carries)) {
|
|
241
|
+
if (layer.parsed === 'malformed') {
|
|
242
|
+
return conventionReading(key, 'malformed', null, layer.path, `${layer.why ?? 'the file cannot be read'}, so the value it may set is unknown`);
|
|
243
|
+
}
|
|
244
|
+
if (layer.shapeError !== undefined) return conventionReading(key, 'invalid', null, layer.path, layer.shapeError);
|
|
245
|
+
const found = _lookup(layer.data, key);
|
|
246
|
+
if (!found.present) continue;
|
|
247
|
+
if ('notAMap' in found) return conventionReading(key, 'invalid', null, layer.path, '`git:` is not a map');
|
|
248
|
+
if (typeof found.value !== 'string') {
|
|
249
|
+
const shown = typeof found.value === 'object' && found.value !== null ? JSON.stringify(found.value) : String(found.value);
|
|
250
|
+
return conventionReading(key, 'invalid', shown, layer.path, `the value is not a string — quote the value, e.g. ${_quoteExample(key)}`);
|
|
251
|
+
}
|
|
252
|
+
const value = found.value;
|
|
253
|
+
const why = invalidReason(key, value);
|
|
254
|
+
return why === null ? conventionReading(key, 'valid', value, layer.path) : conventionReading(key, 'invalid', value, layer.path, why);
|
|
255
|
+
}
|
|
256
|
+
for (const layer of [...layers].reverse().filter((l) => !l.carries && l.parsed === 'valid')) {
|
|
257
|
+
const found = _lookup(layer.data, key);
|
|
258
|
+
if (!found.present || 'notAMap' in found) continue;
|
|
259
|
+
const value = typeof found.value === 'string' ? found.value : String(found.value);
|
|
260
|
+
if (fallback !== null && value === fallback) continue;
|
|
261
|
+
return conventionReading(
|
|
262
|
+
key,
|
|
263
|
+
'discarded',
|
|
264
|
+
value,
|
|
265
|
+
layer.path,
|
|
266
|
+
'user-global files do not carry git.* keys; set it in the project settings file',
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
return conventionReading(key, 'absent', fallback, null);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export function readGitConvention(
|
|
273
|
+
source: GitConventionSource,
|
|
274
|
+
defaults: GitConventionDefaults = _defaults(),
|
|
275
|
+
): Record<GitConventionKey, GitConventionReading> {
|
|
276
|
+
const out = {} as Record<GitConventionKey, GitConventionReading>;
|
|
277
|
+
for (const key of GIT_CONVENTION_KEYS) out[key] = readGitConventionKey(key, source, defaults);
|
|
278
|
+
return out;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** Every state a caller must not act on; `show`, `sync` and the `/pr:merge` prose share this one set. */
|
|
282
|
+
export const REFUSAL_STATES: readonly GitConventionState[] = ['malformed', 'invalid', 'discarded', 'unresolvable'];
|
|
283
|
+
|
|
284
|
+
export function isRefusal(state: GitConventionState): boolean {
|
|
285
|
+
return REFUSAL_STATES.includes(state);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/** One line naming the reason code, the key and the file. */
|
|
289
|
+
export function describeRefusal(reading: GitConventionReading): string {
|
|
290
|
+
return `${reading.reason ?? 'git-convention-ok'}: git.${reading.key} in ${reading.source ?? '(no file)'} — ${reading.detail ?? reading.state}`;
|
|
291
|
+
}
|