@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
|
@@ -26,8 +26,36 @@
|
|
|
26
26
|
* conflict-count reduction and must not be banked as drawdown (AI council
|
|
27
27
|
* 2026-08-21, both seats; roadmap road-to-merge-hotspot-drawdown).
|
|
28
28
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
29
|
+
* The base is the explicit `--base`, else the default branch. Nothing here asks
|
|
30
|
+
* a forge which pull request the branch belongs to: a caller acting on a pull
|
|
31
|
+
* request passes its base, and without `--base` the run is about the default
|
|
32
|
+
* branch, which is right only for a branch that targets it.
|
|
33
|
+
*
|
|
34
|
+
* Exit codes: 0 = already current, or merged cleanly, or `unverified` (the
|
|
35
|
+
* target resolved but its commit could not be fetched, or a base ref's own
|
|
36
|
+
* fetch failed; nothing was touched) ·
|
|
37
|
+
* 1 = conflict, git refusing the merge before it starts (a dirty tree, an
|
|
38
|
+
* untracked file in the way — git's own line is printed), a merge that stopped
|
|
39
|
+
* part-way (MERGE_HEAD set, or the merge half-applied in the index — the line
|
|
40
|
+
* names `git merge --abort` or `git reset --merge`), or the base could
|
|
41
|
+
* not be resolved (no `--base` and no default
|
|
42
|
+
* branch, a `--base` the server does not know, no origin, or origin unreachable
|
|
43
|
+
* at the ref lookup) · 2 = internal error · 3 = behind, and
|
|
44
|
+
* `git.update_strategy` is not `merge`, so the merge was refused (reason code
|
|
45
|
+
* `TARGET_POLICY_STALE` when the branch is current with its non-default target
|
|
46
|
+
* and that target is itself behind the default branch the policy adds — the
|
|
47
|
+
* target's update, not this branch's; a branch also behind the target gets the
|
|
48
|
+
* ordinary behind line first, naming the target's lag as a note) · 4 =
|
|
49
|
+
* `git.update_strategy` cannot be read (a settings file or a committed
|
|
50
|
+
* `.git-convention.yml` that does not parse, a value outside the schema, or a
|
|
51
|
+
* value only a user-global file carries), so nothing was checked or merged; the line carries a stable reason
|
|
52
|
+
* code (`git-convention-malformed` / `-invalid` / `-discarded` /
|
|
53
|
+
* `-unresolvable`) and the file.
|
|
54
|
+
* `scanned:` on every path.
|
|
55
|
+
*
|
|
56
|
+
* The merge has its own timeout, 300 s, since it runs hooks and writes the work
|
|
57
|
+
* tree; `AGENT_CONFIG_SYNC_MERGE_TIMEOUT_MS` overrides it. Every other git call
|
|
58
|
+
* stays on the 8 s network bound.
|
|
31
59
|
*/
|
|
32
60
|
|
|
33
61
|
import * as path from 'node:path';
|
|
@@ -40,9 +68,25 @@ import {
|
|
|
40
68
|
loadPolicyAtSha,
|
|
41
69
|
type ShaFileReader,
|
|
42
70
|
} from './_lib/branch_convergence.js';
|
|
71
|
+
import { checkoutSource, describeRefusal, isRefusal, readGitConventionKey, type GitConventionReading } from './_lib/git_convention.js';
|
|
72
|
+
import {
|
|
73
|
+
conventionRoot,
|
|
74
|
+
ignoredCarrierWarning,
|
|
75
|
+
makeTargetDeps,
|
|
76
|
+
memoTargetDeps,
|
|
77
|
+
parseSymrefDefault,
|
|
78
|
+
readCommittedConvention,
|
|
79
|
+
resolveTarget,
|
|
80
|
+
type ConventionTarget,
|
|
81
|
+
type TargetDeps,
|
|
82
|
+
} from './_lib/git_convention_carrier.js';
|
|
83
|
+
import { baseValueError, splitResolvedRef } from './_lib/git_base_ref.js';
|
|
43
84
|
import { reportScanned } from './_lib/scan_scope.js';
|
|
44
85
|
|
|
86
|
+
export { parseSymrefDefault };
|
|
87
|
+
|
|
45
88
|
const NETWORK_TIMEOUT_MS = 8_000;
|
|
89
|
+
const MERGE_TIMEOUT_MS = 300_000;
|
|
46
90
|
|
|
47
91
|
/** Paths that are GENERATED — a conflict here is regenerated, never hand-merged. */
|
|
48
92
|
const GENERATED = [
|
|
@@ -165,14 +209,28 @@ const GENERATED_PATTERNS: readonly { readonly re: RegExp; readonly why: string }
|
|
|
165
209
|
*/
|
|
166
210
|
const REMEASURED = ['src/config/gate-violation-baselines.json'];
|
|
167
211
|
|
|
168
|
-
function sh(
|
|
212
|
+
function sh(
|
|
213
|
+
cmd: string,
|
|
214
|
+
args: readonly string[],
|
|
215
|
+
cwd: string,
|
|
216
|
+
timeout: number = NETWORK_TIMEOUT_MS,
|
|
217
|
+
): { ok: boolean; out: string; err: string; killed: boolean } {
|
|
169
218
|
const r = spawnSync(cmd, [...args], {
|
|
170
219
|
cwd,
|
|
171
220
|
encoding: 'utf-8',
|
|
172
|
-
timeout
|
|
221
|
+
timeout,
|
|
173
222
|
maxBuffer: 32 * 1024 * 1024,
|
|
174
223
|
});
|
|
175
|
-
return { ok: r.status === 0, out: r.stdout ?? '', err: (r.stderr ?? '').trim() };
|
|
224
|
+
return { ok: r.status === 0, out: r.stdout ?? '', err: (r.stderr ?? '').trim(), killed: r.signal !== null };
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* A merge runs hooks and writes the work tree, so the network timeout is the
|
|
229
|
+
* wrong bound for it: killed mid-flight it leaves MERGE_HEAD behind.
|
|
230
|
+
*/
|
|
231
|
+
function mergeTimeoutMs(): number {
|
|
232
|
+
const n = Number(process.env['AGENT_CONFIG_SYNC_MERGE_TIMEOUT_MS']);
|
|
233
|
+
return Number.isInteger(n) && n > 0 ? n : MERGE_TIMEOUT_MS;
|
|
176
234
|
}
|
|
177
235
|
|
|
178
236
|
/** True when `rel` is a generated artefact rather than an authored one. */
|
|
@@ -232,6 +290,28 @@ export interface Plan {
|
|
|
232
290
|
remeasured: string[];
|
|
233
291
|
authored: string[];
|
|
234
292
|
scanned: number;
|
|
293
|
+
/** Base refs the branch is behind — set by a dry run, so a caller can decide without parsing `message`. */
|
|
294
|
+
behind?: number;
|
|
295
|
+
/**
|
|
296
|
+
* Set when the policy added the default branch and the TARGET itself is
|
|
297
|
+
* behind it: updating the branch onto the target cannot make it current.
|
|
298
|
+
* `branchBehind` is how far the branch is behind the target itself; only at
|
|
299
|
+
* 0 is the target's update the one a reader needs, not this branch's.
|
|
300
|
+
*/
|
|
301
|
+
targetStale?: { target: string; defaultRef: string; behind: number; branchBehind: number };
|
|
302
|
+
/** The base-set summary and the per-ref behind list a dry run found, so a caller can word its own line. */
|
|
303
|
+
summary?: string;
|
|
304
|
+
behindDetail?: string;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** The refusal for a branch that is behind under a strategy other than `merge`. */
|
|
308
|
+
export function behindRefusalMessage(plan: Plan, strategy: string): string {
|
|
309
|
+
const t = plan.targetStale;
|
|
310
|
+
return (
|
|
311
|
+
`⚠️ sync_pr_branch: refused — the branch is behind and git.update_strategy is \`${strategy}\`; this script only merges. ` +
|
|
312
|
+
`Rebase on request instead (git-workflow references/branch-update.md). ${plan.summary ?? ''}. Behind: ${plan.behindDetail ?? '?'}.` +
|
|
313
|
+
(t === undefined ? '' : ` The target ${t.target} is itself ${String(t.behind)} commit(s) behind ${t.defaultRef}; once this branch is current with it, the target needs updating too.`)
|
|
314
|
+
);
|
|
235
315
|
}
|
|
236
316
|
|
|
237
317
|
/**
|
|
@@ -297,15 +377,14 @@ export function renderConflictReport(plan: Plan): string {
|
|
|
297
377
|
/**
|
|
298
378
|
* Why the base is a SET now, and what each entry means.
|
|
299
379
|
*
|
|
300
|
-
* The old resolution was an EXCLUSIVE chain — `--base`, then
|
|
301
|
-
*
|
|
380
|
+
* The old resolution was an EXCLUSIVE chain — `--base`, then `origin/HEAD` —
|
|
381
|
+
* so a PR targeting a release line or a stacked
|
|
302
382
|
* parent was kept current with its target and arbitrarily stale against the
|
|
303
383
|
* default branch. Whether the default belongs in the set is a policy question
|
|
304
384
|
* decided per target and read from the TARGET's own commit; see
|
|
305
385
|
* `_lib/branch_convergence.ts` for the decision and the trust boundary.
|
|
306
386
|
*/
|
|
307
387
|
export type BaseReason =
|
|
308
|
-
| 'pull-request-target'
|
|
309
388
|
| 'explicit-base-override'
|
|
310
389
|
| 'repository-default-branch'
|
|
311
390
|
| 'branch-convergence-policy:include-default';
|
|
@@ -327,7 +406,7 @@ export interface ResolveBaseResult {
|
|
|
327
406
|
readonly policyStatus: 'applied' | 'not-required' | 'disabled';
|
|
328
407
|
}
|
|
329
408
|
|
|
330
|
-
/** Neither
|
|
409
|
+
/** Neither `--base` nor a default branch answered. Distinct from a missing policy. */
|
|
331
410
|
export class UnresolvableBase extends Error {
|
|
332
411
|
constructor(detail: string) {
|
|
333
412
|
super(`unresolvable — ${detail}`);
|
|
@@ -339,66 +418,17 @@ export class UnresolvableBase extends Error {
|
|
|
339
418
|
* The git questions base resolution asks, as data.
|
|
340
419
|
*
|
|
341
420
|
* Injected rather than called inline so the twelve council fixtures can be
|
|
342
|
-
* exercised without a network
|
|
421
|
+
* exercised without a network or a real release line — this
|
|
343
422
|
* repository has none, so a live fixture could only ever cover the
|
|
344
423
|
* default-target path.
|
|
345
424
|
*/
|
|
346
|
-
export interface BaseDeps {
|
|
347
|
-
readonly currentBranch: () => string;
|
|
348
|
-
/** The open PR's `baseRefName`, bare (`release/1.x`), or null. */
|
|
349
|
-
readonly prBase: (branch: string) => string | null;
|
|
350
|
-
/** The default branch as a remote-tracking ref (`origin/main`), or null. */
|
|
351
|
-
readonly defaultBranch: () => string | null;
|
|
352
|
-
/** The SHA the server reports for a ref right now, or null. */
|
|
353
|
-
readonly remoteSha: (ref: string) => string | null;
|
|
425
|
+
export interface BaseDeps extends TargetDeps {
|
|
354
426
|
readonly readAtSha: ShaFileReader;
|
|
355
427
|
}
|
|
356
428
|
|
|
357
429
|
export function makeGitDeps(repo: string): BaseDeps {
|
|
358
430
|
return {
|
|
359
|
-
|
|
360
|
-
prBase: (branch: string): string | null => {
|
|
361
|
-
if (branch === '' || branch === 'HEAD') return null;
|
|
362
|
-
// The forge knows the REAL base, which matters for a stacked or
|
|
363
|
-
// release-line PR: measuring against the repo default would compare
|
|
364
|
-
// against a branch this PR never merges into.
|
|
365
|
-
const pr = sh('gh', ['pr', 'list', '--head', branch, '--state', 'open', '--json', 'baseRefName', '--limit', '1'], repo);
|
|
366
|
-
if (!pr.ok) return null;
|
|
367
|
-
try {
|
|
368
|
-
const rows = JSON.parse(pr.out || '[]') as Array<{ baseRefName?: string }>;
|
|
369
|
-
const b = rows[0]?.baseRefName;
|
|
370
|
-
return typeof b === 'string' && b !== '' ? b : null;
|
|
371
|
-
} catch {
|
|
372
|
-
return null;
|
|
373
|
-
}
|
|
374
|
-
},
|
|
375
|
-
// ASK THE SERVER first, and only then fall back to the local ref.
|
|
376
|
-
//
|
|
377
|
-
// The local-only form was this module's whole answer until the default
|
|
378
|
-
// branch became load-bearing here: the policy's `include` needs a ref to
|
|
379
|
-
// add, and the target-is-default identity check needs one to compare
|
|
380
|
-
// against. Measured in this worktree on 2026-09-03 — `refs/remotes/
|
|
381
|
-
// origin/HEAD` is not set, so the local form returned null and
|
|
382
|
-
// `sync_pr_branch` reported "no open PR and no origin/HEAD" while
|
|
383
|
-
// `check_branch_freshness`, standing three lines away in the same
|
|
384
|
-
// sequence, resolved `origin/main` from the server symref and passed.
|
|
385
|
-
// Two resolvers disagreeing about the base is the defect this roadmap
|
|
386
|
-
// exists to close, one layer down. Mirrors
|
|
387
|
-
// `check_branch_freshness.ts:223` `serverDefaultBase`.
|
|
388
|
-
defaultBranch: (): string | null => {
|
|
389
|
-
const remote = sh('git', ['ls-remote', '--symref', 'origin', 'HEAD'], repo);
|
|
390
|
-
const fromServer = remote.ok ? parseSymrefDefault(remote.out) : null;
|
|
391
|
-
if (fromServer !== null) return fromServer;
|
|
392
|
-
const head = sh('git', ['symbolic-ref', '--short', 'refs/remotes/origin/HEAD'], repo);
|
|
393
|
-
return head.ok && head.out.trim() !== '' ? head.out.trim() : null;
|
|
394
|
-
},
|
|
395
|
-
remoteSha: (ref: string): string | null => {
|
|
396
|
-
const bare = ref.replace(/^origin\//, '');
|
|
397
|
-
const out = sh('git', ['ls-remote', '--heads', 'origin', bare], repo);
|
|
398
|
-
if (!out.ok) return null;
|
|
399
|
-
const sha = out.out.trim().split(/\s+/)[0];
|
|
400
|
-
return sha !== undefined && /^[0-9a-f]{40}$/.test(sha) ? sha : null;
|
|
401
|
-
},
|
|
431
|
+
...makeTargetDeps(repo),
|
|
402
432
|
// `git show <sha>:<path>` and nothing else. There is no filesystem read
|
|
403
433
|
// here by construction: a policy the PR head carries must not be able to
|
|
404
434
|
// change the criteria the PR is judged against.
|
|
@@ -409,36 +439,15 @@ export function makeGitDeps(repo: string): BaseDeps {
|
|
|
409
439
|
};
|
|
410
440
|
}
|
|
411
441
|
|
|
412
|
-
/**
|
|
413
|
-
* The default branch the SERVER reports, from `git ls-remote --symref origin HEAD`.
|
|
414
|
-
*
|
|
415
|
-
* Pure and exported so the parse is testable without a network round trip, and
|
|
416
|
-
* because it closes a measured defect rather than a hypothetical one. Until
|
|
417
|
-
* 2026-09-03 this module read the default branch from `refs/remotes/origin/HEAD`
|
|
418
|
-
* alone — a clone-time ref that is simply absent in some checkouts. Measured in
|
|
419
|
-
* a worktree of this repository the same day: the local form returned null, so
|
|
420
|
-
* `sync_pr_branch` refused with "no open PR and no origin/HEAD" while
|
|
421
|
-
* `check_branch_freshness`, three lines later in the same documented sequence,
|
|
422
|
-
* resolved `origin/main` from the server symref and passed. Two resolvers
|
|
423
|
-
* disagreeing about the base is this roadmap's own subject one layer down, and
|
|
424
|
-
* the default branch stopped being cosmetic here the moment the policy's
|
|
425
|
-
* `include` needed a ref to add. Mirrors `check_branch_freshness.ts:223`.
|
|
426
|
-
*/
|
|
427
|
-
export function parseSymrefDefault(lsRemoteOut: string): string | null {
|
|
428
|
-
for (const line of lsRemoteOut.split('\n')) {
|
|
429
|
-
const t = line.trim();
|
|
430
|
-
if (!t.startsWith('ref:')) continue;
|
|
431
|
-
const name = t.slice('ref:'.length).trim().split(/\s+/)[0] ?? '';
|
|
432
|
-
if (!name.startsWith('refs/heads/')) continue;
|
|
433
|
-
const short = name.slice('refs/heads/'.length).trim();
|
|
434
|
-
if (short !== '') return `origin/${short}`;
|
|
435
|
-
}
|
|
436
|
-
return null;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
442
|
/** Strip the remote prefix so a policy key is the branch name a human writes. */
|
|
440
443
|
function bareName(ref: string): string {
|
|
441
|
-
return ref.
|
|
444
|
+
return splitResolvedRef(ref).branch;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function sameRemoteBranch(a: string, b: string): boolean {
|
|
448
|
+
const x = splitResolvedRef(a);
|
|
449
|
+
const y = splitResolvedRef(b);
|
|
450
|
+
return x.remote === y.remote && x.branch === y.branch;
|
|
442
451
|
}
|
|
443
452
|
|
|
444
453
|
/**
|
|
@@ -453,27 +462,24 @@ function bareName(ref: string): string {
|
|
|
453
462
|
export function resolveBase(repo: string, override: string | null, deps: BaseDeps = makeGitDeps(repo)): ResolveBaseResult {
|
|
454
463
|
const defaultRef = deps.defaultBranch();
|
|
455
464
|
|
|
456
|
-
|
|
457
|
-
if (
|
|
458
|
-
|
|
459
|
-
} else {
|
|
460
|
-
const pr = deps.prBase(deps.currentBranch());
|
|
461
|
-
if (pr !== null) {
|
|
462
|
-
target = { ref: `origin/${pr}`, reason: 'pull-request-target' };
|
|
463
|
-
} else if (defaultRef !== null) {
|
|
464
|
-
target = { ref: defaultRef, reason: 'repository-default-branch' };
|
|
465
|
-
} else {
|
|
466
|
-
throw new UnresolvableBase('no open PR and no origin/HEAD');
|
|
467
|
-
}
|
|
465
|
+
const target = resolveTarget(deps, override, defaultRef);
|
|
466
|
+
if (target === null) {
|
|
467
|
+
throw new UnresolvableBase('no --base and no origin/HEAD');
|
|
468
468
|
}
|
|
469
469
|
|
|
470
|
-
// A PR targeting the default branch needs no entry — identity by
|
|
471
|
-
// or by the SHA both names resolve to.
|
|
472
|
-
|
|
470
|
+
// A PR targeting the default branch needs no entry — identity by remote and
|
|
471
|
+
// branch name, or by the SHA both names resolve to. The branch name alone is
|
|
472
|
+
// not identity: `upstream/main` can sit on a different commit than `origin/main`.
|
|
473
|
+
const sameName = defaultRef !== null && sameRemoteBranch(target.ref, defaultRef);
|
|
473
474
|
const targetSha = deps.remoteSha(target.ref);
|
|
474
475
|
const defaultSha = defaultRef === null ? null : deps.remoteSha(defaultRef);
|
|
475
476
|
const sameSha = targetSha !== null && defaultSha !== null && targetSha === defaultSha;
|
|
476
|
-
|
|
477
|
+
// A fork layout: the pull request targets the default branch of the
|
|
478
|
+
// remote it names (`upstream/main`), not a release line of origin.
|
|
479
|
+
const targetRemote = splitResolvedRef(target.ref).remote;
|
|
480
|
+
const ownDefault = sameName || sameSha || (defaultRef !== null && splitResolvedRef(defaultRef).remote === targetRemote) ? null : (deps.defaultBranchOf?.(targetRemote) ?? null);
|
|
481
|
+
const ownName = ownDefault !== null && sameRemoteBranch(target.ref, ownDefault);
|
|
482
|
+
if (sameName || sameSha || ownName) {
|
|
477
483
|
return { entries: [target], policyStatus: 'not-required' };
|
|
478
484
|
}
|
|
479
485
|
|
|
@@ -527,8 +533,6 @@ export function describeReason(reason: BaseReason): string {
|
|
|
527
533
|
switch (reason) {
|
|
528
534
|
case 'explicit-base-override':
|
|
529
535
|
return 'given by --base';
|
|
530
|
-
case 'pull-request-target':
|
|
531
|
-
return 'the open PR base';
|
|
532
536
|
case 'repository-default-branch':
|
|
533
537
|
return 'the repo default branch';
|
|
534
538
|
case 'branch-convergence-policy:include-default':
|
|
@@ -569,6 +573,8 @@ export interface IntegrationAttempt {
|
|
|
569
573
|
|
|
570
574
|
export interface IntegrationOutcome {
|
|
571
575
|
readonly ok: boolean;
|
|
576
|
+
/** Set when `checkPin` refused the pinned set: nothing was merged. */
|
|
577
|
+
readonly stopped?: boolean;
|
|
572
578
|
readonly attempts: readonly IntegrationAttempt[];
|
|
573
579
|
readonly conflicted: readonly string[];
|
|
574
580
|
readonly message: string;
|
|
@@ -577,7 +583,10 @@ export interface IntegrationOutcome {
|
|
|
577
583
|
/** The git operations the retry loop needs, injected so a moving base is testable. */
|
|
578
584
|
export interface IntegrateOps {
|
|
579
585
|
readonly remoteSha: (ref: string) => string | null;
|
|
580
|
-
|
|
586
|
+
/** Merges `sha`, the pinned commit of `ref`; `error` is a refusal that is not a conflict. */
|
|
587
|
+
readonly merge: (ref: string, sha: string | null) => { ok: boolean; conflicted: string[]; error?: string };
|
|
588
|
+
/** Asked once, before the first merge, with the pinned OIDs; a message stops the run. */
|
|
589
|
+
readonly checkPin?: (pinned: readonly { ref: string; before: string | null }[]) => string | null;
|
|
581
590
|
}
|
|
582
591
|
|
|
583
592
|
function renderAttempts(attempts: readonly IntegrationAttempt[]): string {
|
|
@@ -600,10 +609,15 @@ export function integrateWithPinnedBase(refs: readonly string[], ops: IntegrateO
|
|
|
600
609
|
const attempts: IntegrationAttempt[] = [];
|
|
601
610
|
for (let n = 1; n <= MAX_BASE_ATTEMPTS; n++) {
|
|
602
611
|
const pinned = refs.map((ref) => ({ ref, before: ops.remoteSha(ref) }));
|
|
612
|
+
// Only before the first merge: once one has landed, a "nothing was
|
|
613
|
+
// merged" stop would misreport the tree, so a later move is a base move.
|
|
614
|
+
const stop = n === 1 ? (ops.checkPin?.(pinned) ?? null) : null;
|
|
615
|
+
if (stop !== null) return { ok: false, stopped: true, attempts, conflicted: [], message: stop };
|
|
603
616
|
let conflicted: string[] = [];
|
|
604
617
|
let clean = true;
|
|
605
618
|
for (const q of pinned) {
|
|
606
|
-
const m = ops.merge(q.ref);
|
|
619
|
+
const m = ops.merge(q.ref, q.before);
|
|
620
|
+
if (!m.ok && m.error !== undefined) return { ok: false, attempts, conflicted: [], message: m.error };
|
|
607
621
|
if (!m.ok) {
|
|
608
622
|
clean = false;
|
|
609
623
|
conflicted = m.conflicted;
|
|
@@ -639,6 +653,69 @@ export function integrateWithPinnedBase(refs: readonly string[], ops: IntegrateO
|
|
|
639
653
|
};
|
|
640
654
|
}
|
|
641
655
|
|
|
656
|
+
/**
|
|
657
|
+
* Merge exactly the commit the pin and the policy check were about.
|
|
658
|
+
*
|
|
659
|
+
* The run fetched once, before the pin, so the local tracking ref may name an
|
|
660
|
+
* older commit, or a newer one when the policy re-read fetched. It is fetched
|
|
661
|
+
* again when it differs from the pin, and the pinned SHA itself is merged when
|
|
662
|
+
* the ref still names another commit. A merge that leaves HEAD without the
|
|
663
|
+
* pinned commit is a refusal, never a success.
|
|
664
|
+
*/
|
|
665
|
+
function mergePinned(repo: string, ref: string, sha: string | null): { ok: boolean; conflicted: string[]; error?: string } {
|
|
666
|
+
const tracking = (): string => sh('git', ['rev-parse', '--verify', '-q', `${ref}^{commit}`], repo).out.trim();
|
|
667
|
+
let target = ref;
|
|
668
|
+
if (sha !== null && tracking() !== sha) {
|
|
669
|
+
const { remote, branch } = splitResolvedRef(ref);
|
|
670
|
+
sh('git', ['fetch', '--', remote, `+refs/heads/${branch}:refs/remotes/${remote}/${branch}`], repo);
|
|
671
|
+
if (tracking() !== sha) {
|
|
672
|
+
if (!sh('git', ['cat-file', '-e', `${sha}^{commit}`], repo).ok) {
|
|
673
|
+
return { ok: false, conflicted: [], error: `the pinned commit ${sha.slice(0, 12)} of ${ref} could not be fetched — nothing was merged for it.` };
|
|
674
|
+
}
|
|
675
|
+
target = sha;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
const indexWasClean = sh('git', ['diff', '--cached', '--quiet'], repo).ok;
|
|
679
|
+
const m = sh('git', ['merge', '--no-edit', target], repo, mergeTimeoutMs());
|
|
680
|
+
if (!m.ok) {
|
|
681
|
+
// A merge git refuses before it starts (local changes it would
|
|
682
|
+
// overwrite, an untracked file in the way) leaves no unmerged path.
|
|
683
|
+
const conflicted = sh('git', ['diff', '--name-only', '--diff-filter=U'], repo).out.split('\n').filter((p) => p.trim() !== '');
|
|
684
|
+
if (conflicted.length > 0) return { ok: false, conflicted };
|
|
685
|
+
// A staged difference that was not there before came from this merge —
|
|
686
|
+
// a killed git leaves one with no MERGE_HEAD to abort. Staged work the
|
|
687
|
+
// user had is not a half-applied merge, and resetting it would lose it.
|
|
688
|
+
const how = m.killed ? `was stopped after ${String(mergeTimeoutMs() / 1000)} s` : 'did not complete';
|
|
689
|
+
if (sh('git', ['rev-parse', '-q', '--verify', 'MERGE_HEAD'], repo).ok) {
|
|
690
|
+
return {
|
|
691
|
+
ok: false,
|
|
692
|
+
conflicted: [],
|
|
693
|
+
error:
|
|
694
|
+
`the merge of ${ref} ${how} and left a merge in progress (MERGE_HEAD is set) — ` +
|
|
695
|
+
'finish it with `git commit` or discard it with `git merge --abort`.',
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
if (indexWasClean && !sh('git', ['diff', '--cached', '--quiet'], repo).ok) {
|
|
699
|
+
return {
|
|
700
|
+
ok: false,
|
|
701
|
+
conflicted: [],
|
|
702
|
+
error:
|
|
703
|
+
`the merge of ${ref} ${how} and left it half-applied in the index (no MERGE_HEAD) — ` +
|
|
704
|
+
'discard it with `git reset --merge`.',
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
if (m.killed) {
|
|
708
|
+
return { ok: false, conflicted: [], error: `the merge of ${ref} was stopped after ${String(mergeTimeoutMs() / 1000)} s before it changed anything — nothing was merged for it.` };
|
|
709
|
+
}
|
|
710
|
+
const why = (m.err || m.out).trim().split('\n').join(' ');
|
|
711
|
+
return { ok: false, conflicted: [], error: `git refused to merge ${ref}: ${why || 'no reason given'} — nothing was merged for it.` };
|
|
712
|
+
}
|
|
713
|
+
if (sha !== null && !sh('git', ['merge-base', '--is-ancestor', sha, 'HEAD'], repo).ok) {
|
|
714
|
+
return { ok: false, conflicted: [], error: `the merge of ${ref} left HEAD without its pinned commit ${sha.slice(0, 12)}.` };
|
|
715
|
+
}
|
|
716
|
+
return { ok: true, conflicted: [] };
|
|
717
|
+
}
|
|
718
|
+
|
|
642
719
|
/** The regeneration operations Phase 3 needs, injected so no real conflict is required. */
|
|
643
720
|
export interface RegenOps {
|
|
644
721
|
readonly regenerate: () => { ok: boolean; err: string };
|
|
@@ -731,10 +808,19 @@ function gitRegenOps(repo: string): RegenOps {
|
|
|
731
808
|
};
|
|
732
809
|
}
|
|
733
810
|
|
|
734
|
-
|
|
811
|
+
/**
|
|
812
|
+
* What the merge path needs beyond the base set. `live` answers the last-moment
|
|
813
|
+
* pin and is never memoised — a memoised pin could not see the target move.
|
|
814
|
+
*/
|
|
815
|
+
export interface SyncOptions {
|
|
816
|
+
readonly live?: TargetDeps;
|
|
817
|
+
readonly checkPin?: IntegrateOps['checkPin'];
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
export function sync(repo: string, baseOverride: string | null, dryRun: boolean, autoResolve = false, deps?: BaseDeps, opts: SyncOptions = {}): Plan {
|
|
735
821
|
let resolved: ResolveBaseResult;
|
|
736
822
|
try {
|
|
737
|
-
resolved = resolveBase(repo, baseOverride);
|
|
823
|
+
resolved = resolveBase(repo, baseOverride, deps ?? makeGitDeps(repo));
|
|
738
824
|
} catch (exc) {
|
|
739
825
|
// A missing policy, an unresolvable target SHA and an unresolvable base
|
|
740
826
|
// are all REFUSALS carrying their own typed message. None of them
|
|
@@ -751,13 +837,14 @@ export function sync(repo: string, baseOverride: string | null, dryRun: boolean,
|
|
|
751
837
|
const summary = renderBaseSummary(resolved);
|
|
752
838
|
const order = integrationOrder(resolved);
|
|
753
839
|
|
|
754
|
-
const
|
|
755
|
-
|
|
840
|
+
const remotes = [...new Set(['origin', ...order.map((ref) => splitResolvedRef(ref).remote)])];
|
|
841
|
+
const failed = remotes.map((remote) => ({ remote, ...sh('git', ['fetch', '--prune', '--', remote], repo) })).find((f) => !f.ok);
|
|
842
|
+
if (failed !== undefined) {
|
|
756
843
|
// Unreachable remote is not "already current" — saying so is the whole
|
|
757
844
|
// point, since a silent pass here reproduces the staleness this closes.
|
|
758
845
|
return {
|
|
759
846
|
exit: 0,
|
|
760
|
-
message: `unverified — could not fetch
|
|
847
|
+
message: `unverified — could not fetch ${failed.remote} (${failed.err.split('\n')[0] ?? '?'}). Base freshness NOT checked.`,
|
|
761
848
|
generated: [],
|
|
762
849
|
remeasured: [],
|
|
763
850
|
authored: [],
|
|
@@ -765,10 +852,49 @@ export function sync(repo: string, baseOverride: string | null, dryRun: boolean,
|
|
|
765
852
|
};
|
|
766
853
|
}
|
|
767
854
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
855
|
+
// A single-branch clone's refspec never moves a base tracking ref fetched
|
|
856
|
+
// once by hand, so the remote-wide fetch above can leave it stale and the
|
|
857
|
+
// count below would read "already current". Each ref is fetched by name.
|
|
858
|
+
// A failed one is unverified like the remote-wide fetch: the ref still names
|
|
859
|
+
// whatever it named before, and counting it would read a stale "current".
|
|
860
|
+
for (const ref of order) {
|
|
861
|
+
const { remote, branch } = splitResolvedRef(ref);
|
|
862
|
+
const f = sh('git', ['fetch', '-q', '--', remote, `+refs/heads/${branch}:refs/remotes/${remote}/${branch}`], repo);
|
|
863
|
+
if (!f.ok) {
|
|
864
|
+
return {
|
|
865
|
+
exit: 0,
|
|
866
|
+
message: `unverified — could not fetch ${ref} (${f.err.split('\n')[0] ?? '?'}). Base freshness NOT checked.`,
|
|
867
|
+
generated: [],
|
|
868
|
+
remeasured: [],
|
|
869
|
+
authored: [],
|
|
870
|
+
scanned: 0,
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// A count git could not take is not a count of 0: a ref this checkout never
|
|
876
|
+
// fetched (a single-branch clone) would otherwise read as "already current".
|
|
877
|
+
const countBehind = (from: string, ref: string): number | null => {
|
|
878
|
+
const r = sh('git', ['rev-list', '--count', `${from}..${ref}`], repo);
|
|
879
|
+
const n = Number(r.out.trim());
|
|
880
|
+
return r.ok && r.out.trim() !== '' && Number.isInteger(n) ? n : null;
|
|
881
|
+
};
|
|
882
|
+
const uncountable = (ref: string): Plan => ({
|
|
883
|
+
exit: 1,
|
|
884
|
+
message:
|
|
885
|
+
`cannot count commits behind ${ref} — it is not in this checkout (a single-branch clone fetches only its own branch). ` +
|
|
886
|
+
`Fetch it: git fetch -- ${splitResolvedRef(ref).remote} +refs/heads/${bareName(ref)}:refs/remotes/${splitResolvedRef(ref).remote}/${bareName(ref)}`,
|
|
887
|
+
generated: [],
|
|
888
|
+
remeasured: [],
|
|
889
|
+
authored: [],
|
|
890
|
+
scanned: 0,
|
|
891
|
+
});
|
|
892
|
+
const behindEach: { ref: string; behind: number }[] = [];
|
|
893
|
+
for (const ref of order) {
|
|
894
|
+
const behind = countBehind('HEAD', ref);
|
|
895
|
+
if (behind === null) return uncountable(ref);
|
|
896
|
+
behindEach.push({ ref, behind });
|
|
897
|
+
}
|
|
772
898
|
// De-duplicated by ancestry: a ref already contained in HEAD is 0 behind and
|
|
773
899
|
// is not merged again, which is what keeps a target that already contains
|
|
774
900
|
// the default from being merged twice.
|
|
@@ -778,28 +904,33 @@ export function sync(repo: string, baseOverride: string | null, dryRun: boolean,
|
|
|
778
904
|
}
|
|
779
905
|
if (dryRun) {
|
|
780
906
|
const detail = stale.map((b) => `${b.ref} (${String(b.behind)} behind)`).join(', ');
|
|
907
|
+
const added = resolved.entries.find((e) => e.reason === 'branch-convergence-policy:include-default');
|
|
908
|
+
const target = resolved.entries[0]?.ref ?? '';
|
|
909
|
+
const targetBehind = added === undefined ? 0 : countBehind(target, added.ref);
|
|
910
|
+
if (targetBehind === null) return uncountable(added?.ref ?? target);
|
|
781
911
|
return {
|
|
912
|
+
...(targetBehind > 0 && added !== undefined
|
|
913
|
+
? { targetStale: { target, defaultRef: added.ref, behind: targetBehind, branchBehind: behindEach.find((b) => b.ref === target)?.behind ?? 0 } }
|
|
914
|
+
: {}),
|
|
782
915
|
exit: 0,
|
|
783
916
|
message: `${summary}. Behind: ${detail} — would merge in that order. Dry run, nothing changed.`,
|
|
917
|
+
summary,
|
|
918
|
+
behindDetail: detail,
|
|
784
919
|
generated: [],
|
|
785
920
|
remeasured: [],
|
|
786
921
|
authored: [],
|
|
787
922
|
scanned: order.length,
|
|
923
|
+
behind: stale.length,
|
|
788
924
|
};
|
|
789
925
|
}
|
|
790
926
|
|
|
927
|
+
const live = opts.live ?? makeGitDeps(repo);
|
|
791
928
|
const outcome = integrateWithPinnedBase(
|
|
792
929
|
stale.map((b) => b.ref),
|
|
793
930
|
{
|
|
794
|
-
remoteSha: (ref: string): string | null =>
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
if (m.ok) return { ok: true, conflicted: [] };
|
|
798
|
-
return {
|
|
799
|
-
ok: false,
|
|
800
|
-
conflicted: sh('git', ['diff', '--name-only', '--diff-filter=U'], repo).out.split('\n'),
|
|
801
|
-
};
|
|
802
|
-
},
|
|
931
|
+
remoteSha: (ref: string): string | null => live.remoteSha(ref),
|
|
932
|
+
...(opts.checkPin === undefined ? {} : { checkPin: opts.checkPin }),
|
|
933
|
+
merge: (ref: string, sha: string | null) => mergePinned(repo, ref, sha),
|
|
803
934
|
},
|
|
804
935
|
);
|
|
805
936
|
|
|
@@ -816,8 +947,8 @@ export function sync(repo: string, baseOverride: string | null, dryRun: boolean,
|
|
|
816
947
|
};
|
|
817
948
|
}
|
|
818
949
|
if (outcome.conflicted.length === 0) {
|
|
819
|
-
// The base kept moving
|
|
820
|
-
//
|
|
950
|
+
// The base kept moving, or moved onto a commit carrying another
|
|
951
|
+
// strategy. No conflict to classify; the message carries the OIDs.
|
|
821
952
|
return { exit: 1, message: `${summary}. ${outcome.message}`, generated: [], remeasured: [], authored: [], scanned: order.length };
|
|
822
953
|
}
|
|
823
954
|
|
|
@@ -845,7 +976,82 @@ export function sync(repo: string, baseOverride: string | null, dryRun: boolean,
|
|
|
845
976
|
};
|
|
846
977
|
}
|
|
847
978
|
|
|
848
|
-
|
|
979
|
+
/**
|
|
980
|
+
* `git.update_strategy` in force for the repository: the committed
|
|
981
|
+
* `.git-convention.yml` at the target commit, over the developer layers
|
|
982
|
+
* (ADR-283). Absent everywhere reads as `merge`, the behaviour before the key
|
|
983
|
+
* existed; a file that does not parse, a typo, a user-global-only value and a
|
|
984
|
+
* target commit that cannot be resolved are refusals here.
|
|
985
|
+
*/
|
|
986
|
+
export function updateStrategy(repo: string, base: string | null = null, deps?: TargetDeps): GitConventionReading {
|
|
987
|
+
return readStrategy(repo, base, deps).reading;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
function readStrategy(repo: string, base: string | null, deps?: TargetDeps): { reading: GitConventionReading; baseResolved: boolean; target: ConventionTarget | null } {
|
|
991
|
+
const read = readCommittedConvention(repo, { override: base, keys: ['update_strategy'], ...(deps ? { deps } : {}) });
|
|
992
|
+
return { reading: read.readings.update_strategy as GitConventionReading, baseResolved: read.target !== null && read.target.sha !== null, target: read.target };
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
export interface StrategyGate {
|
|
996
|
+
/** `null` — the strategy is readable, go on; otherwise the exit to return. */
|
|
997
|
+
exit: 0 | 1 | 4 | null;
|
|
998
|
+
line: string;
|
|
999
|
+
reading: GitConventionReading;
|
|
1000
|
+
/** The ref and commit the strategy was read at, when `strategyGate` resolved one. */
|
|
1001
|
+
target?: ConventionTarget | null;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* The one place that maps an unreadable `git.update_strategy` to an exit.
|
|
1006
|
+
*
|
|
1007
|
+
* A developer file that is itself a refusal, and a carrier at the target that
|
|
1008
|
+
* does not parse or is not accepted, are exit 4. A target that resolves to no
|
|
1009
|
+
* commit — no `--base` and no default branch, a ref the server does not know,
|
|
1010
|
+
* no origin, origin unreachable at the ref lookup — is the base failure, exit
|
|
1011
|
+
* 1. A target the server named whose commit could not be fetched is
|
|
1012
|
+
* `unverified`: exit 0 with a warning, and nothing is touched.
|
|
1013
|
+
*/
|
|
1014
|
+
export function strategyExit(reading: GitConventionReading, baseResolved: boolean, developer: GitConventionReading): StrategyGate {
|
|
1015
|
+
if (!isRefusal(reading.state)) return { exit: null, line: '', reading };
|
|
1016
|
+
const refused: StrategyGate = { exit: 4, line: `❌ sync_pr_branch: refused — ${describeRefusal(reading)}. Nothing was checked or merged.`, reading };
|
|
1017
|
+
if (reading.state !== 'unresolvable' || isRefusal(developer.state)) return refused;
|
|
1018
|
+
const why = reading.detail ?? 'the target commit is unknown';
|
|
1019
|
+
if (!baseResolved) return { exit: 1, line: `❌ sync_pr_branch: base could not be resolved — ${why}. Nothing was checked or merged.`, reading };
|
|
1020
|
+
return { exit: 0, line: `⚠️ sync_pr_branch: unverified — ${why}. Base freshness NOT checked, nothing was merged.`, reading };
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
export function strategyGate(repo: string, base: string | null, targetDeps: BaseDeps): StrategyGate {
|
|
1024
|
+
const { reading, baseResolved, target } = readStrategy(repo, base, targetDeps);
|
|
1025
|
+
return { ...strategyExit(reading, baseResolved, readGitConventionKey('update_strategy', checkoutSource(conventionRoot(repo).root))), target };
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/** The strategy a reading puts in force, or its refusing state: what a plan is made with. */
|
|
1029
|
+
function strategyInForce(r: GitConventionReading): string {
|
|
1030
|
+
return isRefusal(r.state) ? `unreadable (${r.state})` : (r.value ?? 'merge');
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* The stop for a target that moved between the strategy read and the pin.
|
|
1035
|
+
*
|
|
1036
|
+
* The commit being integrated is governed by the policy it carries, so the
|
|
1037
|
+
* carrier is read again at the pinned commit through the same reader. The same
|
|
1038
|
+
* strategy in force there goes on against the new commit; a different one, or
|
|
1039
|
+
* one that cannot be read, stops before anything is merged — the plan was made
|
|
1040
|
+
* under a policy the integrated commit no longer carries.
|
|
1041
|
+
*/
|
|
1042
|
+
export function policyMovedStop(from: string, to: string, planned: GitConventionReading, pinned: GitConventionReading): string | null {
|
|
1043
|
+
const was = strategyInForce(planned);
|
|
1044
|
+
const now = strategyInForce(pinned);
|
|
1045
|
+
if (was === now) return null;
|
|
1046
|
+
const why = isRefusal(pinned.state) ? ` (${describeRefusal(pinned)})` : '';
|
|
1047
|
+
return (
|
|
1048
|
+
`the target moved from ${from.slice(0, 12)} to ${to.slice(0, 12)} and its git.update_strategy changed from ${was} to ${now}${why} — ` +
|
|
1049
|
+
'nothing was merged; run again so the plan is made under the strategy the new commit carries.'
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/** `deps` answers the target questions; tests inject it, a run asks git. */
|
|
1054
|
+
export function main(argv?: readonly string[], deps?: BaseDeps): number {
|
|
849
1055
|
const args = argv ?? process.argv.slice(2);
|
|
850
1056
|
let repo = process.cwd();
|
|
851
1057
|
let base: string | null = null;
|
|
@@ -873,6 +1079,12 @@ export function main(argv?: readonly string[]): number {
|
|
|
873
1079
|
reportScanned({ gate: 'sync_pr_branch', scanned: 0, units: 'base ref(s)', roots: ['origin'], allowEmpty: 'argument error' });
|
|
874
1080
|
return 1;
|
|
875
1081
|
}
|
|
1082
|
+
const blank = baseValueError(v);
|
|
1083
|
+
if (blank !== null) {
|
|
1084
|
+
process.stderr.write(`❌ sync_pr_branch: ${blank}\n`);
|
|
1085
|
+
reportScanned({ gate: 'sync_pr_branch', scanned: 0, units: 'base ref(s)', roots: ['origin'], allowEmpty: 'argument error' });
|
|
1086
|
+
return 2;
|
|
1087
|
+
}
|
|
876
1088
|
base = v;
|
|
877
1089
|
} else if (a === '--dry-run') {
|
|
878
1090
|
dryRun = true;
|
|
@@ -884,7 +1096,18 @@ export function main(argv?: readonly string[]): number {
|
|
|
884
1096
|
process.stdout.write(
|
|
885
1097
|
'usage: sync_pr_branch [--repo PATH] [--base REF] [--dry-run] [--auto-resolve-generated] [--quiet]\n' +
|
|
886
1098
|
' Merges the PR base into the current branch so the PR does not go stale.\n' +
|
|
887
|
-
'
|
|
1099
|
+
' Under a git.update_strategy other than merge it only checks: a current\n' +
|
|
1100
|
+
' branch exits 0, a behind one exits 3 and is never merged (--dry-run and\n' +
|
|
1101
|
+
' --auto-resolve-generated have nothing to change there). A strategy that\n' +
|
|
1102
|
+
' cannot be read (unparsable file, typo, user-global-only) exits 4.\n' +
|
|
1103
|
+
' The base is --base; without it the default branch, so a PR into any other\n' +
|
|
1104
|
+
' base must pass --base <its base>; a branch name and refs/heads/<name> mean\n' +
|
|
1105
|
+
' origin/<name>, and <remote>/<name> is used as given. A blank --base\n' +
|
|
1106
|
+
' is a usage error, exit 2.\n' +
|
|
1107
|
+
' A base that cannot be resolved or counted exits 1; one whose commit\n' +
|
|
1108
|
+
' cannot be fetched is unverified, exit 0. A target that moves before the\n' +
|
|
1109
|
+
' merge is read again at the new commit; another strategy there exits 1,\n' +
|
|
1110
|
+
' nothing merged. A conflict is\n' +
|
|
888
1111
|
' reported and never auto-resolved; generated and authored conflicts are\n' +
|
|
889
1112
|
' listed separately because only the first has one correct resolution;\n' +
|
|
890
1113
|
' measured ratchet baselines are a third class, re-measured not merged.\n' +
|
|
@@ -903,9 +1126,52 @@ export function main(argv?: readonly string[]): number {
|
|
|
903
1126
|
}
|
|
904
1127
|
}
|
|
905
1128
|
|
|
1129
|
+
// This script only merges. Under any other strategy a merge of the base is
|
|
1130
|
+
// the commit the setting excludes, and a rebase needs the user's request per
|
|
1131
|
+
// git-history-discipline — so the branch is only CHECKED (dry run), and a
|
|
1132
|
+
// branch that is behind is refused rather than merged. A current branch
|
|
1133
|
+
// passes, so an automated pre-push sync stays green when nothing is to do.
|
|
1134
|
+
const ignored = ignoredCarrierWarning(conventionRoot(repo).root);
|
|
1135
|
+
if (ignored !== null) process.stdout.write(`⚠️ sync_pr_branch: ${ignored}\n`);
|
|
1136
|
+
const live = deps ?? makeGitDeps(repo);
|
|
1137
|
+
const targetDeps = memoTargetDeps(live);
|
|
906
1138
|
let plan: Plan;
|
|
907
1139
|
try {
|
|
908
|
-
|
|
1140
|
+
const gate = strategyGate(repo, base, targetDeps);
|
|
1141
|
+
if (gate.exit !== null) {
|
|
1142
|
+
process.stdout.write(`${gate.line}\n`);
|
|
1143
|
+
const why = gate.exit === 0 ? 'target commit not fetched — stated above' : gate.exit === 1 ? 'base unresolvable — stated above' : 'git.update_strategy unreadable';
|
|
1144
|
+
reportScanned({ gate: 'sync_pr_branch', scanned: 0, units: 'base ref(s)', roots: ['origin'], allowEmpty: why });
|
|
1145
|
+
return gate.exit;
|
|
1146
|
+
}
|
|
1147
|
+
const strategy = gate.reading.value ?? 'merge';
|
|
1148
|
+
if (strategy !== 'merge') {
|
|
1149
|
+
plan = sync(repo, base, true, false, targetDeps);
|
|
1150
|
+
const t = plan.targetStale;
|
|
1151
|
+
if (plan.exit === 0 && t !== undefined && t.branchBehind === 0) {
|
|
1152
|
+
process.stdout.write(
|
|
1153
|
+
`⚠️ sync_pr_branch: refused — TARGET_POLICY_STALE: the target ${t.target} is itself ${String(t.behind)} commit(s) behind ${t.defaultRef}, ` +
|
|
1154
|
+
`which the branch-convergence policy requires; updating this branch onto the target cannot make it current. ` +
|
|
1155
|
+
`The target needs updating first; this branch has nothing to do until then.\n`,
|
|
1156
|
+
);
|
|
1157
|
+
reportScanned({ gate: 'sync_pr_branch', scanned: plan.scanned, units: 'base ref(s)', roots: ['origin'] });
|
|
1158
|
+
return 3;
|
|
1159
|
+
}
|
|
1160
|
+
if (plan.exit === 0 && (plan.behind ?? 0) > 0) {
|
|
1161
|
+
process.stdout.write(`${behindRefusalMessage(plan, strategy)}\n`);
|
|
1162
|
+
reportScanned({ gate: 'sync_pr_branch', scanned: plan.scanned, units: 'base ref(s)', roots: ['origin'] });
|
|
1163
|
+
return 3;
|
|
1164
|
+
}
|
|
1165
|
+
} else {
|
|
1166
|
+
const read = gate.target ?? null;
|
|
1167
|
+
const checkPin = (pinned: readonly { ref: string; before: string | null }[]): string | null => {
|
|
1168
|
+
const now = read === null ? null : (pinned.find((p) => p.ref === read.ref)?.before ?? null);
|
|
1169
|
+
if (read === null || read.sha === null || now === null || now === read.sha) return null;
|
|
1170
|
+
const again = strategyGate(repo, base, { ...targetDeps, remoteSha: () => now });
|
|
1171
|
+
return policyMovedStop(read.sha, now, gate.reading, again.reading);
|
|
1172
|
+
};
|
|
1173
|
+
plan = sync(repo, base, dryRun, autoResolve, targetDeps, { live, checkPin });
|
|
1174
|
+
}
|
|
909
1175
|
} catch (exc) {
|
|
910
1176
|
reportScanned({ gate: 'sync_pr_branch', scanned: 0, units: 'base ref(s)', roots: ['origin'], allowEmpty: 'internal error' });
|
|
911
1177
|
process.stderr.write(`❌ sync_pr_branch: internal error: ${exc instanceof Error ? exc.message : String(exc)}\n`);
|
|
@@ -936,9 +1202,14 @@ export function main(argv?: readonly string[]): number {
|
|
|
936
1202
|
return plan.exit;
|
|
937
1203
|
}
|
|
938
1204
|
|
|
1205
|
+
// Inlined into the `git:convention` delegate bundle this module shares that
|
|
1206
|
+
// bundle's `import.meta.url`, so the URL comparison below would run `main` at
|
|
1207
|
+
// import time with the verb's argv. Defined by the esbuild builds only.
|
|
1208
|
+
declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
|
|
939
1209
|
const _HERE = fileURLToPath(import.meta.url);
|
|
940
1210
|
function _isCliEntry(): boolean {
|
|
941
1211
|
if (process.argv[1] === undefined) return false;
|
|
1212
|
+
if (typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__) return path.basename(process.argv[1], '.js') === 'sync_pr_branch';
|
|
942
1213
|
return import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href || process.argv[1] === _HERE;
|
|
943
1214
|
}
|
|
944
1215
|
if (_isCliEntry()) {
|