@joshuafolkken/kit 1.1784.0 → 1.2114.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/.claude/agents/reviewer-verification.md +19 -0
- package/.claude/agents/reviewer.md +19 -0
- package/.claude/settings.json +5 -6
- package/.claude/skills/dependency-update/SKILL.md +9 -10
- package/.claude/skills/workflow-commands/SKILL.md +6 -6
- package/.claude/skills/workflow-commands/background-commands.md +8 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +41 -32
- package/.claude/skills/workflow-commands/delegation.md +6 -6
- package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
- package/.claude/skills/workflow-commands/followup.md +7 -5
- package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
- package/.claude/skills/workflow-commands/fullrun.md +1 -1
- package/.claude/skills/workflow-commands/issue-comments.md +9 -4
- package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
- package/.claude/skills/workflow-commands/kickoff.md +2 -2
- package/.claude/skills/workflow-commands/observation-filing.md +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
- package/.claude/skills/workflow-commands/prerequisite.md +3 -2
- package/.claude/skills/workflow-commands/retrospective.md +2 -2
- package/.claude/skills/workflow-commands/split-assessment.md +7 -5
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-pnpm/action.yml +9 -16
- package/.github/dependabot.yml +16 -0
- package/.github/workflows/auto-tag.yml +45 -0
- package/.github/workflows/ci.yml +155 -15
- package/.github/workflows/dependabot-auto-merge.yml +63 -4
- package/.github/workflows/production.yml +8 -0
- package/.github/workflows/publish.yml +59 -45
- package/.vscode/settings.json +19 -0
- package/CLAUDE.md +5 -12
- package/SECURITY.md +2 -2
- package/dist/CLAUDE.md +5 -12
- package/dist/commands/document-read-cli.js +2 -1
- package/dist/commands/document-section-main.js +2 -1
- package/dist/commands/read-set-cli.js +194 -134
- package/dist/commands/run-prep-main.js +9694 -10173
- package/dist/commands/run-step-cli.js +22138 -18285
- package/dist/hooks/audit-provision.js +23 -5
- package/dist/hooks/chunk-3GKE653K.js +6204 -0
- package/dist/hooks/chunk-45CJJOO7.js +1243 -0
- package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
- package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
- package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
- package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
- package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
- package/dist/hooks/chunk-VVNYJWEI.js +30 -0
- package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
- package/dist/hooks/codex-hook-adapter.js +8 -8
- package/dist/hooks/format-edited.js +4 -5
- package/dist/hooks/inputs.json +415 -389
- package/dist/hooks/pretool-guard.js +7 -6
- package/dist/hooks/session-lang.js +101 -258
- package/dist/hooks/stop-guard.js +1744 -2576
- package/dist/josh.js +7133 -6368
- package/dist/version/index.js +161 -1
- package/eslint/rules/comment-why-only.js +108 -0
- package/package.json +15 -8
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +14 -11
- package/prompts/collaboration-workflow/issue-citation.md +0 -4
- package/prompts/collaboration-workflow/issue-template.md +40 -21
- package/prompts/collaboration-workflow/lane-instructions.md +3 -1
- package/prompts/collaboration-workflow/measurement.md +8 -1
- package/prompts/collaboration-workflow/operating-rules.md +11 -2
- package/prompts/collaboration-workflow/output-bounds.md +6 -2
- package/prompts/collaboration-workflow/plan-comment.md +1 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow/residency.md +3 -2
- package/prompts/collaboration-workflow/rule-delivery.md +13 -1
- package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
- package/prompts/collaboration-workflow/wip-cap.md +3 -1
- package/prompts/review-rubric.md +8 -0
- package/prompts/review.md +31 -22
- package/prompts/testing-guide.md +1 -0
- package/scripts/agent/agent-argv.ts +14 -16
- package/scripts/agent/agent-provider.ts +138 -0
- package/scripts/agent/agent-role-profile.ts +108 -156
- package/scripts/agent/agent-safe-text.ts +20 -5
- package/scripts/agent/api-usage-limit.ts +65 -0
- package/scripts/agent/claude-agent-argv.ts +19 -9
- package/scripts/agent/codex-agent-argv.ts +118 -22
- package/scripts/agent/usage-limit-reset.ts +179 -0
- package/scripts/auth/claude-token-output.ts +2 -2
- package/scripts/auto-ok/auto-ok-author.ts +53 -0
- package/scripts/auto-ok/auto-ok-cli.ts +20 -9
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-cli.ts +6 -1
- package/scripts/backlog/backlog-drive-hold.ts +3 -3
- package/scripts/backlog/backlog-drive-idle.ts +10 -0
- package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
- package/scripts/backlog/backlog-drive-launch.ts +8 -2
- package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
- package/scripts/backlog/backlog-drive-named.ts +28 -7
- package/scripts/backlog/backlog-drive-paused.ts +5 -4
- package/scripts/backlog/backlog-drive-restore.ts +11 -3
- package/scripts/backlog/backlog-drive.ts +21 -60
- package/scripts/backlog/backlog-gate-scope.ts +61 -0
- package/scripts/backlog/backlog-measure-close.ts +112 -0
- package/scripts/backlog/backlog-next.ts +39 -49
- package/scripts/backlog/backlog-occupied.ts +2 -2
- package/scripts/backlog/backlog-overlap.ts +42 -8
- package/scripts/backlog/backlog-plan-cli.ts +4 -1
- package/scripts/backlog/backlog-plan-comment.ts +81 -0
- package/scripts/backlog/backlog-plan-read.ts +19 -6
- package/scripts/backlog/backlog-pool.ts +50 -12
- package/scripts/backlog/backlog-rank.ts +60 -13
- package/scripts/backlog/backlog-stalled-detect.ts +2 -1
- package/scripts/backlog/backlog-waves.ts +17 -2
- package/scripts/backlog/backlogrun-launch.ts +7 -4
- package/scripts/cost-runtime/context-cut-payback.ts +27 -25
- package/scripts/cost-runtime/cost-cli.ts +37 -16
- package/scripts/cost-runtime/cost-pricing.ts +9 -0
- package/scripts/cost-runtime/cost-verdict.ts +4 -1
- package/scripts/delegation/delegation-policy.ts +2 -2
- package/scripts/delegation/duplicate-read-guard.ts +1 -0
- package/scripts/delegation/investigation-guard.ts +14 -2
- package/scripts/delegation/investigation-reads.ts +45 -23
- package/scripts/dependabot/dependabot-cooldown.ts +3 -2
- package/scripts/discovery/repo-party.ts +80 -20
- package/scripts/discovery/session-owner-pin.ts +51 -0
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/command-reference-line-budget.ts +42 -0
- package/scripts/document/document-byte-budget.ts +17 -7
- package/scripts/document/document-checks.ts +20 -0
- package/scripts/document/document-ratchet-check.ts +101 -0
- package/scripts/document/document-section.ts +1 -0
- package/scripts/document/entry-read-budget.ts +7 -3
- package/scripts/document/issue-citation-budget.ts +94 -0
- package/scripts/epic/epic-cli-argv.ts +2 -2
- package/scripts/epic/epic-fetch.ts +4 -2
- package/scripts/epic/epic-graph.ts +7 -2
- package/scripts/epic/epic-issue.ts +3 -1
- package/scripts/epic/epic-rank.ts +5 -0
- package/scripts/exports/unused-members-check.ts +62 -0
- package/scripts/exports/unused-members-cli.ts +6 -51
- package/scripts/followup/followup-ci-path.ts +67 -0
- package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
- package/scripts/followup/followup-coderabbit-wait.ts +13 -10
- package/scripts/followup/followup-failed-tests.ts +160 -0
- package/scripts/followup/followup-job-needs.ts +100 -0
- package/scripts/followup/followup-job-rerun.ts +303 -0
- package/scripts/followup/followup-main-move.ts +113 -0
- package/scripts/followup/git-followup-finish.ts +43 -11
- package/scripts/followup/git-followup-pending.ts +3 -3
- package/scripts/followup/git-followup-stages.ts +41 -11
- package/scripts/followup/git-pr-followup-checks.ts +55 -16
- package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
- package/scripts/followup/git-pr-followup.ts +62 -27
- package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
- package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
- package/scripts/gate/busy-average.ts +34 -2
- package/scripts/gate/check-related-pinned.ts +43 -0
- package/scripts/gate/check-related-reuse.ts +64 -0
- package/scripts/gate/check-related-section.ts +57 -0
- package/scripts/gate/check-related-unplanned.ts +34 -0
- package/scripts/gate/check-related.ts +265 -0
- package/scripts/gate/command-memory.ts +1 -1
- package/scripts/gate/core-admission.ts +24 -6
- package/scripts/gate/core-budget-timing.ts +20 -6
- package/scripts/gate/core-budget.ts +40 -11
- package/scripts/gate/core-wait-record.ts +3 -2
- package/scripts/gate/core-wait.ts +25 -2
- package/scripts/gate/core-weights.ts +15 -7
- package/scripts/gate/gate-labels.ts +46 -0
- package/scripts/gate/gate-ledger.ts +14 -6
- package/scripts/gate/gate-plan.ts +103 -58
- package/scripts/gate/gate-report.ts +9 -7
- package/scripts/gate/gate-run-steps.ts +26 -3
- package/scripts/gate/gate-skip.ts +45 -6
- package/scripts/gate/gate-static-group.ts +60 -0
- package/scripts/gate/gate-steps.ts +2 -1
- package/scripts/gate/gate-tree.ts +4 -2
- package/scripts/gate/hook-gate-reuse.ts +19 -2
- package/scripts/gate/metrics-totals.ts +59 -0
- package/scripts/gate/scoped-green.ts +68 -15
- package/scripts/gate/since-green.ts +14 -6
- package/scripts/gate/structural-checks.ts +96 -0
- package/scripts/gate/verification-gate.ts +51 -16
- package/scripts/gate/verification-inputs.ts +21 -6
- package/scripts/gate/verification-tail.ts +52 -0
- package/scripts/gh/gh-author-association.ts +23 -2
- package/scripts/gh/git-ai-review-scan.ts +1 -1
- package/scripts/gh/git-gh-api-path.ts +12 -3
- package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
- package/scripts/gh/git-gh-exec.ts +32 -2
- package/scripts/gh/git-gh-issue-read.ts +4 -2
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +8 -2
- package/scripts/gh/git-gh-issue.ts +12 -5
- package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
- package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
- package/scripts/gh/git-gh-pr-read.ts +74 -13
- package/scripts/gh/git-gh-pr-rest.ts +3 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
- package/scripts/gh/git-gh-pr-too-large.ts +20 -0
- package/scripts/gh/git-gh-pr.ts +21 -7
- package/scripts/gh/git-gh-retry.ts +141 -0
- package/scripts/gh/git-pr-ai-review.ts +15 -6
- package/scripts/gh/git-pr-checks-eval.ts +3 -0
- package/scripts/gh/git-pr-checks.ts +5 -5
- package/scripts/git/base-tree.ts +30 -0
- package/scripts/git/change-base.ts +4 -10
- package/scripts/git/changed-paths-sync.ts +63 -0
- package/scripts/git/changed-paths.ts +16 -1
- package/scripts/git/git-common-directory.ts +11 -1
- package/scripts/git/git-diff-reads.ts +66 -20
- package/scripts/git/git-error.ts +9 -2
- package/scripts/git/git-schemas.ts +13 -0
- package/scripts/git/git-worktree.ts +13 -0
- package/scripts/git/gone-branch.ts +4 -1
- package/scripts/git/main-merge-budget-conflict.ts +89 -0
- package/scripts/git/main-merge-guard.ts +55 -18
- package/scripts/git/main-merge-regenerate.ts +59 -25
- package/scripts/git/main-merge.ts +53 -5
- package/scripts/git/no-base-checkout.ts +127 -0
- package/scripts/git/stash/git-stash.ts +11 -2
- package/scripts/git/stash/stash-push-cli.ts +10 -0
- package/scripts/hooks/batch-guard.ts +40 -21
- package/scripts/hooks/edited-cspell.ts +37 -11
- package/scripts/hooks/format-edited-file.ts +22 -2
- package/scripts/hooks/lane-plan-guard.ts +50 -0
- package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
- package/scripts/hooks/pre-commit-lint.ts +14 -1
- package/scripts/hooks/pre-push-related-switch.ts +10 -0
- package/scripts/hooks/pre-push-unit.ts +76 -10
- package/scripts/hooks/pretool-guard.ts +2 -0
- package/scripts/hooks/reserved-run.ts +14 -1
- package/scripts/hooks/run-hook.sh +23 -8
- package/scripts/hooks/step-zero-notice.ts +6 -1
- package/scripts/hooks/stop-actions.ts +3 -15
- package/scripts/hooks/stop-guard.ts +7 -6
- package/scripts/init/distributed-paths.ts +1 -0
- package/scripts/init/hook-command-rewrite.ts +5 -1
- package/scripts/init/hook-launch.ts +4 -2
- package/scripts/issue/aggregation-split.ts +52 -0
- package/scripts/issue/defect-origin-line.ts +19 -1
- package/scripts/issue/defect-rate-cli.ts +5 -102
- package/scripts/issue/defect-report.ts +4 -4
- package/scripts/issue/effect-audit-cli.ts +178 -0
- package/scripts/issue/effect-audit.ts +185 -0
- package/scripts/issue/expected-effect-lint.ts +64 -9
- package/scripts/issue/git-next-issues.ts +5 -0
- package/scripts/issue/issue-body-or-comment.ts +38 -4
- package/scripts/issue/issue-cite-cli.ts +1 -3
- package/scripts/issue/issue-classification.ts +1 -0
- package/scripts/issue/issue-closing-pr.ts +8 -1
- package/scripts/issue/issue-evidence-exit.ts +4 -2
- package/scripts/issue/issue-file-cap.ts +58 -0
- package/scripts/issue/issue-file-cli.ts +111 -38
- package/scripts/issue/issue-file-deferral.ts +52 -0
- package/scripts/issue/issue-file-fold.ts +29 -10
- package/scripts/issue/issue-file-interrupt.ts +85 -0
- package/scripts/issue/issue-file-lane-hint.ts +30 -0
- package/scripts/issue/issue-file.ts +43 -6
- package/scripts/issue/issue-labels.ts +19 -2
- package/scripts/issue/issue-lint-cli.ts +27 -2
- package/scripts/issue/issue-measured-cli.ts +13 -35
- package/scripts/issue/issue-measured-close.ts +58 -0
- package/scripts/issue/issue-not-before-label.ts +2 -2
- package/scripts/issue/issue-not-before.ts +4 -1
- package/scripts/issue/issue-priority-cli.ts +60 -0
- package/scripts/issue/issue-priority-raise.ts +55 -0
- package/scripts/issue/issue-priority.ts +174 -43
- package/scripts/issue/issue-rank.ts +21 -4
- package/scripts/issue/issue-read-cli.ts +32 -6
- package/scripts/issue/issue-read.ts +37 -12
- package/scripts/issue/issue-sample-gate.ts +95 -74
- package/scripts/issue/issue-sample-prime.ts +127 -0
- package/scripts/issue/issue-sample-required.ts +57 -0
- package/scripts/issue/issue-sample-source.ts +12 -11
- package/scripts/issue/issue-search.ts +124 -0
- package/scripts/issue/issue-state.ts +13 -1
- package/scripts/issue/issue-template-section.ts +43 -0
- package/scripts/issue/issue-watch-diff.ts +31 -1
- package/scripts/issue/issue-watch-hook.ts +11 -2
- package/scripts/issue/issue-watch.ts +55 -12
- package/scripts/issue/markdown-section.ts +1 -0
- package/scripts/issue/measure-declaration.ts +121 -0
- package/scripts/issue/measure-rerun-cli.ts +7 -70
- package/scripts/issue/plan-consumers-section.ts +22 -1
- package/scripts/issue/reproduction-measure.ts +3 -1
- package/scripts/issue/size-estimate.ts +90 -0
- package/scripts/issue/trusted-measure.ts +84 -0
- package/scripts/josh/command-usage.ts +3 -2
- package/scripts/josh/durable-state-migrate.ts +105 -0
- package/scripts/josh/durable-state.ts +112 -0
- package/scripts/josh/josh-aliases.ts +95 -0
- package/scripts/josh/josh-command-map.ts +1 -82
- package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
- package/scripts/josh/josh-commands-ai.ts +5 -5
- package/scripts/josh/josh-commands-development.ts +59 -58
- package/scripts/josh/josh-commands-issue-write.ts +23 -4
- package/scripts/josh/josh-commands-issue.ts +32 -0
- package/scripts/josh/josh-commands-lane.ts +87 -4
- package/scripts/josh/josh-commands-lint.ts +16 -3
- package/scripts/josh/josh-commands-maintenance.ts +15 -0
- package/scripts/josh/josh-commands-review.ts +41 -6
- package/scripts/josh/josh-commands-ship.ts +56 -8
- package/scripts/josh/josh-commands-test-check.ts +80 -0
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/josh/josh-environment-file.ts +43 -3
- package/scripts/josh/josh-in-process.ts +2 -2
- package/scripts/josh/josh-logic.ts +5 -3
- package/scripts/josh/josh-run.ts +19 -1
- package/scripts/josh/run-record-path.ts +15 -0
- package/scripts/josh/stamp-file.ts +11 -2
- package/scripts/lane/lane-adopt-cli.ts +98 -0
- package/scripts/lane/lane-adopt.ts +208 -0
- package/scripts/lane/lane-await.ts +5 -8
- package/scripts/lane/lane-baseline.ts +123 -0
- package/scripts/lane/lane-breakdown-cli.ts +64 -0
- package/scripts/lane/lane-breakdown-implement.ts +170 -0
- package/scripts/lane/lane-breakdown-laps.ts +107 -0
- package/scripts/lane/lane-breakdown-pinned.ts +76 -0
- package/scripts/lane/lane-breakdown-text.ts +145 -0
- package/scripts/lane/lane-breakdown.ts +239 -0
- package/scripts/lane/lane-check-stats.ts +29 -8
- package/scripts/lane/lane-child-invocation.ts +9 -2
- package/scripts/lane/lane-child-mark-keys.ts +12 -0
- package/scripts/lane/lane-child-marker.ts +20 -1
- package/scripts/lane/lane-ci-path-stats.ts +73 -0
- package/scripts/lane/lane-claim-stats.ts +84 -0
- package/scripts/lane/lane-close.ts +8 -3
- package/scripts/lane/lane-dispatch-log.ts +3 -3
- package/scripts/lane/lane-dispatch.ts +2 -2
- package/scripts/lane/lane-gap-stats.ts +7 -6
- package/scripts/lane/lane-guard-policy.ts +7 -1
- package/scripts/lane/lane-implement-stats.ts +207 -0
- package/scripts/lane/lane-implement-subagents.ts +90 -0
- package/scripts/lane/lane-investigation-switch.ts +16 -0
- package/scripts/lane/lane-ledger-kind.ts +31 -0
- package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
- package/scripts/lane/lane-ledger-schema.ts +119 -36
- package/scripts/lane/lane-ledger-write.ts +257 -0
- package/scripts/lane/lane-ledger.ts +31 -177
- package/scripts/lane/lane-load.ts +1 -1
- package/scripts/lane/lane-measure-cli.ts +176 -59
- package/scripts/lane/lane-net-read.ts +44 -0
- package/scripts/lane/lane-net-time.ts +212 -0
- package/scripts/lane/lane-open.ts +16 -7
- package/scripts/lane/lane-output.ts +2 -4
- package/scripts/lane/lane-overrun-prompt.ts +147 -0
- package/scripts/lane/lane-overrun.ts +274 -0
- package/scripts/lane/lane-paths.ts +24 -1
- package/scripts/lane/lane-pause-cli.ts +4 -1
- package/scripts/lane/lane-paused-spans.ts +97 -0
- package/scripts/lane/lane-plan-check.ts +207 -0
- package/scripts/lane/lane-plan-cli.ts +41 -0
- package/scripts/lane/lane-plan.ts +144 -0
- package/scripts/lane/lane-registry.ts +14 -1
- package/scripts/lane/lane-relaunch.ts +1 -1
- package/scripts/lane/lane-round-one-stats.ts +51 -0
- package/scripts/lane/lane-sampler.ts +23 -4
- package/scripts/lane/lane-session-action.ts +93 -18
- package/scripts/lane/lane-session-broker.ts +49 -21
- package/scripts/lane/lane-session-reread-main.ts +14 -0
- package/scripts/lane/lane-session-reread.ts +51 -0
- package/scripts/lane/lane-ship-lap-stats.ts +74 -0
- package/scripts/lane/lane-sleep.ts +58 -0
- package/scripts/lane/lane-spent.ts +1 -1
- package/scripts/lane/lane-split-stats.ts +28 -0
- package/scripts/lane/lane-stage-stats.ts +13 -1
- package/scripts/lane/lane-state.ts +41 -9
- package/scripts/lane/lane-stats-tables.ts +58 -0
- package/scripts/lane/lane-stats.ts +21 -5
- package/scripts/lane/lane-stop-stats.ts +51 -19
- package/scripts/lane/lane-tail-stats.ts +32 -0
- package/scripts/lane/lane-transcript-calls.ts +67 -10
- package/scripts/lane/lane-transcript-stats.ts +44 -12
- package/scripts/lane/lane-value-cell.ts +72 -0
- package/scripts/lane/lane-value.ts +118 -0
- package/scripts/lane/lane-withdraw-closed.ts +124 -0
- package/scripts/lane/lane-withdraw.ts +108 -31
- package/scripts/lane/lane-yield.ts +85 -0
- package/scripts/lane/openai-lane-ship.ts +12 -11
- package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
- package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
- package/scripts/lane/openai-lane-supervisor.ts +5 -4
- package/scripts/lib/poll.ts +38 -9
- package/scripts/lib/settled-together.ts +10 -0
- package/scripts/lib/shell-quote.ts +21 -0
- package/scripts/lib/token-shape.ts +111 -0
- package/scripts/lint/eslint-daemon-sources.ts +79 -0
- package/scripts/lint/eslint-daemon.ts +45 -6
- package/scripts/lint/eslint-warm-cli.ts +7 -0
- package/scripts/lint/eslint-warm.ts +66 -0
- package/scripts/lint/import-graph.ts +141 -11
- package/scripts/lint/lint-gate-scope.ts +2 -2
- package/scripts/lint/lint-parallel.ts +54 -6
- package/scripts/lint/lint-related.ts +154 -33
- package/scripts/lint/rename-cli.ts +179 -0
- package/scripts/lint/rename-identifier.ts +192 -0
- package/scripts/lint/type-only-imports.ts +58 -0
- package/scripts/notify/telegram-notify.ts +12 -3
- package/scripts/observations/observation-record.ts +42 -16
- package/scripts/observations/observations-flush.ts +32 -9
- package/scripts/overrides/overrides-check.ts +9 -1
- package/scripts/release/release-approval-prune.ts +7 -1
- package/scripts/repo/required-checks-logic.ts +4 -1
- package/scripts/repo/ruleset-check.ts +4 -3
- package/scripts/report/markdown-shape.ts +28 -0
- package/scripts/report/report-format-reference.ts +15 -1
- package/scripts/report/report-labels.ts +12 -1
- package/scripts/report/report-lint-child-summary.ts +94 -0
- package/scripts/report/report-lint-cli.ts +26 -7
- package/scripts/report/report-lint.ts +2 -20
- package/scripts/review/prose-stale-cli.ts +88 -0
- package/scripts/review/prose-stale-scan.ts +152 -0
- package/scripts/review/review-attest.ts +73 -23
- package/scripts/review/review-brief-cli.ts +68 -19
- package/scripts/review/review-brief-paths.ts +22 -0
- package/scripts/review/review-brief.ts +14 -7
- package/scripts/review/review-comment-carry.ts +47 -0
- package/scripts/review/review-comment-round.ts +85 -22
- package/scripts/review/review-finding-ledger.ts +109 -7
- package/scripts/review/review-finding-text.ts +43 -0
- package/scripts/review/review-interaction.ts +11 -0
- package/scripts/review/review-lane-handover.ts +68 -0
- package/scripts/review/review-lint-cli.ts +57 -0
- package/scripts/review/review-lint-findings.ts +92 -0
- package/scripts/review/review-lint-sections.ts +80 -0
- package/scripts/review/review-lint.ts +221 -0
- package/scripts/review/review-prior-findings.ts +102 -0
- package/scripts/review/review-readers-scan.ts +4 -2
- package/scripts/review/review-record-cli.ts +177 -54
- package/scripts/review/review-record-code-round.ts +55 -0
- package/scripts/review/review-record-comment.ts +60 -0
- package/scripts/review/review-record-interaction.ts +35 -0
- package/scripts/review/review-record-pinned.ts +108 -0
- package/scripts/review/review-record.ts +25 -1
- package/scripts/review/review-reviewed-tree.ts +307 -0
- package/scripts/review/review-round-one-closure.ts +62 -0
- package/scripts/review/review-round-reuse.ts +106 -0
- package/scripts/review/review-round2-cli.ts +91 -29
- package/scripts/review/review-round2-skip-comment.ts +55 -0
- package/scripts/review/review-round2.ts +24 -8
- package/scripts/review/review-stamps.ts +7 -3
- package/scripts/review/review-stop-log.ts +20 -6
- package/scripts/review/review-stops-cli.ts +2 -1
- package/scripts/review/review-submit-cli.ts +101 -0
- package/scripts/rules/agent-model.ts +1 -1
- package/scripts/rules/bash-triggers.ts +3 -3
- package/scripts/rules/concise-reply.ts +88 -0
- package/scripts/rules/credential-body.ts +77 -0
- package/scripts/rules/decision-oracle.ts +1 -1
- package/scripts/rules/delivered-rules.ts +36 -17
- package/scripts/rules/destructive-command.ts +3 -11
- package/scripts/rules/direct-issue-comment.ts +34 -12
- package/scripts/rules/direct-issue-read.ts +191 -0
- package/scripts/rules/direct-pr-create.ts +4 -24
- package/scripts/rules/early-heartbeat.ts +2 -0
- package/scripts/rules/edit-tool.ts +27 -0
- package/scripts/rules/file-edit-rows.ts +17 -0
- package/scripts/rules/file-rewrite.ts +146 -0
- package/scripts/rules/firing-point.ts +3 -2
- package/scripts/rules/gh-api.ts +128 -7
- package/scripts/rules/gh-repo-selector.ts +84 -0
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/guard-remedy.ts +14 -5
- package/scripts/rules/implementation-cut.ts +61 -28
- package/scripts/rules/investigator-foreground.ts +231 -0
- package/scripts/rules/issue-citation.ts +15 -60
- package/scripts/rules/issue-comments.ts +9 -4
- package/scripts/rules/josh-git-bare.ts +1 -1
- package/scripts/rules/lane-background.ts +41 -13
- package/scripts/rules/lane-direct-tool.ts +107 -9
- package/scripts/rules/lane-interactive-ask.ts +4 -1
- package/scripts/rules/lane-park.ts +4 -2
- package/scripts/rules/lane-spilled-read.ts +90 -0
- package/scripts/rules/lane-split-park.ts +1 -1
- package/scripts/rules/lane-switch-main.ts +4 -4
- package/scripts/rules/last-prompt.ts +20 -47
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/permission-guards.ts +5 -1
- package/scripts/rules/piped-verification-shapes.ts +110 -0
- package/scripts/rules/piped-verification.ts +67 -17
- package/scripts/rules/poll-loop.ts +72 -9
- package/scripts/rules/pr-merge.ts +5 -5
- package/scripts/rules/pre-gate-cut.ts +3 -3
- package/scripts/rules/protected-files.ts +88 -24
- package/scripts/rules/reply-language.ts +3 -17
- package/scripts/rules/reply-prose.ts +34 -0
- package/scripts/rules/repo-admin.ts +132 -0
- package/scripts/rules/reviewer-foreground.ts +88 -0
- package/scripts/rules/round-one-check-related.ts +120 -0
- package/scripts/rules/rule-body-guard.ts +5 -15
- package/scripts/rules/rule-value-cache.ts +53 -5
- package/scripts/rules/rule-value-candidates.ts +84 -0
- package/scripts/rules/rule-value-cli.ts +59 -11
- package/scripts/rules/rule-value.ts +17 -4
- package/scripts/rules/run-tail-rule.ts +1 -1
- package/scripts/rules/sed-in-place.ts +196 -0
- package/scripts/rules/shell-segments.ts +10 -2
- package/scripts/rules/stop-rule-rows.ts +1 -13
- package/scripts/rules/stop-rules.ts +33 -58
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +110 -23
- package/scripts/rules/timed-rerun.ts +1 -1
- package/scripts/rules/turn-filings.ts +90 -0
- package/scripts/rules/worktree-guard.ts +22 -7
- package/scripts/run/board/run-board-ending-reason.ts +6 -2
- package/scripts/run/board/run-board-fit.ts +24 -1
- package/scripts/run/board/run-board-found.ts +134 -0
- package/scripts/run/board/run-board-header.ts +8 -0
- package/scripts/run/board/run-board-labels.ts +11 -1
- package/scripts/run/board/run-board-lane-time.ts +1 -0
- package/scripts/run/board/run-board-link.ts +15 -2
- package/scripts/run/board/run-board-notes.ts +7 -1
- package/scripts/run/board/run-board-operation.ts +4 -2
- package/scripts/run/board/run-board-phase.ts +2 -5
- package/scripts/run/board/run-board-plan.ts +1 -1
- package/scripts/run/board/run-board-read.ts +46 -1
- package/scripts/run/board/run-board-reason.ts +20 -8
- package/scripts/run/board/run-board-render-checks.ts +3 -2
- package/scripts/run/board/run-board-render-drawn.ts +11 -0
- package/scripts/run/board/run-board-render-found.ts +157 -0
- package/scripts/run/board/run-board-render-lead.ts +9 -0
- package/scripts/run/board/run-board-render-legend.ts +19 -0
- package/scripts/run/board/run-board-render-tail.ts +1 -1
- package/scripts/run/board/run-board-render.ts +82 -18
- package/scripts/run/board/run-board-spin.ts +1 -3
- package/scripts/run/board/run-board-status.ts +2 -0
- package/scripts/run/board/run-board-tick.ts +39 -10
- package/scripts/run/carry/run-carry-ended.ts +3 -2
- package/scripts/run/carry/run-carry.ts +3 -2
- package/scripts/run/cut/run-cut-cli.ts +33 -133
- package/scripts/run/cut/run-cut-digest.ts +152 -0
- package/scripts/run/cut/run-cut-handoff.ts +52 -8
- package/scripts/run/cut/run-cut-report.ts +24 -3
- package/scripts/run/cut/run-cut-resume.ts +129 -0
- package/scripts/run/cut/run-cut-review.ts +105 -0
- package/scripts/run/cut/run-cut.ts +18 -7
- package/scripts/run/detached-launch.ts +1 -1
- package/scripts/run/entry/run-entry-cli.ts +88 -19
- package/scripts/run/entry/run-entry-spill.ts +83 -0
- package/scripts/run/entry/run-entry-stop.ts +5 -1
- package/scripts/run/entry/run-entry-trust.ts +91 -0
- package/scripts/run/event/run-event-baseline.ts +56 -0
- package/scripts/run/event/run-event-filed.ts +9 -3
- package/scripts/run/event/run-event-overrun.ts +197 -0
- package/scripts/run/event/run-event-render.ts +4 -0
- package/scripts/run/event/run-event-stream.ts +25 -3
- package/scripts/run/hold/run-stop-notify.ts +3 -8
- package/scripts/run/merge/run-merge-cap.ts +57 -0
- package/scripts/run/merge/run-merge-cli.ts +66 -23
- package/scripts/run/merge/run-merge-outcome.ts +2 -0
- package/scripts/run/merge/run-merge-ship.ts +13 -3
- package/scripts/run/merge/run-merge-signals.ts +40 -23
- package/scripts/run/merge/run-merge-steps.ts +56 -36
- package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
- package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
- package/scripts/run/merge/run-merge.ts +41 -14
- package/scripts/run/review/run-review-cli.ts +306 -20
- package/scripts/run/review/run-review-early-push.ts +121 -0
- package/scripts/run/review/run-review-join-read.ts +94 -0
- package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
- package/scripts/run/review/run-review-pinned-join.ts +216 -0
- package/scripts/run/review/run-review-pinned-steps.ts +383 -0
- package/scripts/run/review/run-review-pinned-tree.ts +37 -0
- package/scripts/run/review/run-review-pinned.ts +53 -0
- package/scripts/run/review/run-review-steps.ts +70 -34
- package/scripts/run/review/run-review.ts +26 -6
- package/scripts/run/run-parent-cut-hook.ts +3 -4
- package/scripts/run/run-prep.ts +1 -0
- package/scripts/run/run-stage-read.ts +2 -6
- package/scripts/run/run-step-cli.ts +17 -5
- package/scripts/run/run-step-lane-plan.ts +27 -0
- package/scripts/run/run-step-section.ts +26 -7
- package/scripts/run/run-step.ts +5 -2
- package/scripts/run/ship/run-ship-args.ts +19 -0
- package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
- package/scripts/run/ship/run-ship-cli.ts +131 -39
- package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
- package/scripts/run/ship/run-ship-detach.ts +10 -4
- package/scripts/run/ship/run-ship-handover.ts +106 -0
- package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
- package/scripts/run/ship/run-ship-lap.ts +63 -0
- package/scripts/run/ship/run-ship-next.ts +27 -26
- package/scripts/run/ship/run-ship-overlap.ts +8 -3
- package/scripts/run/ship/run-ship-place.ts +9 -2
- package/scripts/run/ship/run-ship-planned.ts +92 -0
- package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
- package/scripts/run/ship/run-ship-preflight.ts +16 -4
- package/scripts/run/ship/run-ship-probe.ts +23 -9
- package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
- package/scripts/run/ship/run-ship-relaunch.ts +51 -0
- package/scripts/run/ship/run-ship-return.ts +103 -29
- package/scripts/run/ship/run-ship-review-reason.ts +24 -0
- package/scripts/run/ship/run-ship-review-steps.ts +230 -59
- package/scripts/run/ship/run-ship-review.ts +171 -51
- package/scripts/run/ship/run-ship-reviewer.ts +138 -42
- package/scripts/run/ship/run-ship-scoped.ts +39 -10
- package/scripts/run/ship/run-ship-stage.ts +49 -13
- package/scripts/run/ship/run-ship-steps.ts +24 -4
- package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
- package/scripts/run/ship/run-ship-stop-context.ts +50 -13
- package/scripts/run/ship/run-ship-sync.ts +171 -30
- package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
- package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
- package/scripts/run/ship/run-ship-waiter.ts +114 -0
- package/scripts/run/ship/run-ship.ts +16 -2
- package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
- package/scripts/run/wake/run-wake-cli.ts +6 -113
- package/scripts/run/wake/run-wake-code.ts +53 -11
- package/scripts/run/wake/run-wake-driver.ts +5 -3
- package/scripts/run/wake/run-wake-finish.ts +137 -0
- package/scripts/run/wake/run-wake-loop.ts +5 -3
- package/scripts/run/wake/run-wake-ports.ts +11 -3
- package/scripts/run/wake/run-wake-session.ts +2 -0
- package/scripts/run/wake/run-wake.ts +3 -2
- package/scripts/safe-chain/ci-installer-pin.ts +49 -8
- package/scripts/safe-chain/project-config.ts +3 -2
- package/scripts/security/secretlint-scan.ts +42 -9
- package/scripts/security/security-audit-provision-main.ts +9 -1
- package/scripts/security/security-audit-provision.ts +1 -1
- package/scripts/security/security-audit.ts +21 -1
- package/scripts/security/sonar-file.ts +10 -5
- package/scripts/split/split-assess.ts +12 -3
- package/scripts/split/split-early-notice.ts +116 -0
- package/scripts/split/split-measure.ts +20 -2
- package/scripts/split/split-resolution.ts +107 -0
- package/scripts/test/direct-importers.ts +185 -0
- package/scripts/test/pure-files-entries.ts +83 -0
- package/scripts/test/related-heavy-tests.ts +81 -0
- package/scripts/test/test-no-base.ts +88 -0
- package/scripts/test/test-pinned-cache-logic.ts +363 -0
- package/scripts/test/test-pinned-cache.ts +337 -0
- package/scripts/test/test-pinned-emit.ts +49 -0
- package/scripts/test/test-pinned-functions.ts +116 -0
- package/scripts/test/test-pinned-ledger.ts +80 -0
- package/scripts/test/test-pinned-logic.ts +208 -20
- package/scripts/test/test-pinned-main.ts +84 -18
- package/scripts/test/test-pinned-pool.ts +73 -0
- package/scripts/test/test-pinned-probe.ts +254 -0
- package/scripts/test/test-pinned-prune-logic.ts +118 -0
- package/scripts/test/test-pinned-reach.ts +194 -0
- package/scripts/test/test-pinned-record.ts +196 -0
- package/scripts/test/test-pinned-rewire.ts +148 -0
- package/scripts/test/test-pinned-spawn.ts +81 -0
- package/scripts/test/test-pinned-stage.ts +70 -0
- package/scripts/test/test-pinned.ts +258 -47
- package/scripts/test/test-reach-cli.ts +61 -0
- package/scripts/test/test-read-map.ts +35 -11
- package/scripts/test/test-read-recording.ts +17 -5
- package/scripts/test/test-read-trace.ts +26 -8
- package/scripts/test/test-red-logic.ts +46 -7
- package/scripts/test/test-red.ts +34 -14
- package/scripts/test/test-related-claim.ts +37 -0
- package/scripts/test/test-related-main.ts +4 -1
- package/scripts/test/test-related-moved.ts +91 -0
- package/scripts/test/test-related-record.ts +43 -23
- package/scripts/test/test-related-scope.ts +99 -34
- package/scripts/test/test-related-synced.ts +135 -0
- package/scripts/test/test-related-touched.ts +84 -0
- package/scripts/test/test-related.ts +167 -83
- package/scripts/test/test-unit-guard.ts +28 -5
- package/scripts/test/unit-durations.ts +41 -0
- package/scripts/test/unit-worker-share.ts +5 -4
- package/scripts/test/vitest-cache-directory.ts +19 -0
- package/scripts/test/vitest-cli-excludes.ts +14 -0
- package/scripts/test/vitest-failure-summary.ts +111 -0
- package/scripts/test/whole-suite-files.ts +12 -1
- package/scripts/time-runtime/time-batch-guard.ts +42 -4
- package/scripts/time-runtime/time-bundle-call.ts +1 -1
- package/scripts/time-runtime/time-bundles.ts +36 -5
- package/scripts/time-runtime/time-markers.ts +2 -2
- package/scripts/time-runtime/time-search-call.ts +38 -0
- package/scripts/time-runtime/time-shell.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +17 -5
- package/scripts/version/development-engines-verdict.ts +124 -0
- package/scripts/version/latest-corepack.ts +2 -0
- package/templates/gitignore +2 -0
- package/templates/workflows/ci.yml +41 -0
- package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
- package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
- package/dist/hooks/chunk-TUIFS5E7.js +0 -72
- package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
- package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
- package/scripts/rules/filing-cap.ts +0 -139
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { changed_paths } from './changed-paths'
|
|
2
|
+
import { git_diff_reads } from './git-diff-reads'
|
|
3
|
+
import { git_location_environment } from './git-location-environment'
|
|
4
|
+
import { git_spawn_sync, type GitSyncOptions } from './git-spawn-sync'
|
|
5
|
+
|
|
6
|
+
// The synchronous counterpart of `changed_paths.read_changed_paths(false)` — the branch diff since
|
|
7
|
+
// the merge base plus the untracked files — for a `PreToolUse` hook, which cannot await. It spawns the
|
|
8
|
+
// argument lists `git-diff-reads.ts` spawns, so the two readings agree on what "changed" is — through
|
|
9
|
+
// a merge of the default branch in progress too, measured from the base `change_base.resolved_through_merge`
|
|
10
|
+
// answers (joshuafolkken/kit#5309). Any failure is the empty list.
|
|
11
|
+
|
|
12
|
+
// With an explicit `cwd`, the git location variables are cleared so that directory is what git
|
|
13
|
+
// answers for, as in `git_spawn_sync.origin_url`.
|
|
14
|
+
function options_of(cwd: string | undefined): GitSyncOptions {
|
|
15
|
+
if (cwd === undefined) return {}
|
|
16
|
+
|
|
17
|
+
return { cwd, env: git_location_environment.location_free_environment() }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function default_branch_reference(options: GitSyncOptions): string {
|
|
21
|
+
const output = git_spawn_sync.read([...git_diff_reads.DEFAULT_BRANCH_ARGUMENTS], options)
|
|
22
|
+
const default_branch = git_diff_reads.default_branch_of(output)
|
|
23
|
+
const remote_reference = git_diff_reads.remote_reference_of(default_branch)
|
|
24
|
+
const check = git_diff_reads.reference_check_arguments(remote_reference)
|
|
25
|
+
|
|
26
|
+
return git_spawn_sync.read(check, options) === undefined ? default_branch : remote_reference
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// While a merge is in progress, the later of the base of `HEAD` and the base of `MERGE_HEAD`.
|
|
30
|
+
function through_merge(base: string, reference: string, options: GitSyncOptions): string {
|
|
31
|
+
const incoming = git_spawn_sync.read(git_diff_reads.incoming_base_arguments(reference), options)
|
|
32
|
+
|
|
33
|
+
if (incoming === undefined) return base
|
|
34
|
+
|
|
35
|
+
const kept = git_spawn_sync.read(git_diff_reads.later_base_arguments(base, incoming), options)
|
|
36
|
+
|
|
37
|
+
return git_diff_reads.later_base_of(kept, base)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function change_base(options: GitSyncOptions): string {
|
|
41
|
+
const reference = default_branch_reference(options)
|
|
42
|
+
const base = git_spawn_sync.read(git_diff_reads.merge_base_arguments(reference), options)
|
|
43
|
+
|
|
44
|
+
if (base === undefined) return reference
|
|
45
|
+
|
|
46
|
+
return through_merge(base, reference, options)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Repository-root-relative paths, as the asynchronous reading returns them.
|
|
50
|
+
function read_changed_paths(cwd?: string): ReadonlyArray<string> {
|
|
51
|
+
const options = options_of(cwd)
|
|
52
|
+
const tracked = git_spawn_sync.read(
|
|
53
|
+
git_diff_reads.names_since_arguments(change_base(options)),
|
|
54
|
+
options,
|
|
55
|
+
)
|
|
56
|
+
const untracked = git_spawn_sync.read(git_diff_reads.UNTRACKED_ARGUMENTS, options)
|
|
57
|
+
|
|
58
|
+
return [tracked, untracked].flatMap((raw = '') => changed_paths.to_paths(raw))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const changed_paths_sync = { read_changed_paths }
|
|
62
|
+
|
|
63
|
+
export { changed_paths_sync }
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { change_base } from './change-base'
|
|
1
2
|
import { git_command } from './git-command'
|
|
2
3
|
|
|
3
4
|
// The set of changed paths a mechanical, path-driven decision is made from.
|
|
@@ -12,13 +13,27 @@ function to_paths(raw: string): Array<string> {
|
|
|
12
13
|
.filter((line) => line !== '')
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
// joshuafolkken/kit#5307: **the tracked half is measured from the tree's base, through a merge in
|
|
17
|
+
// progress** (`change_base.resolved_through_merge`). A merge of the default branch stopped on a
|
|
18
|
+
// conflict holds the default branch's files in the tree while `HEAD` is still the commit before it,
|
|
19
|
+
// so the diff from `HEAD`'s merge-base read everything the merge brought in as this branch's own — and
|
|
20
|
+
// the ship's `unplanned` precondition refused the re-detach it had itself told the lane to make. A
|
|
21
|
+
// base that cannot be resolved reads as before.
|
|
22
|
+
async function tracked_names(): Promise<string> {
|
|
23
|
+
const base = await change_base.resolved_through_merge()
|
|
24
|
+
|
|
25
|
+
if (base === undefined) return await git_command.diff_main_names()
|
|
26
|
+
|
|
27
|
+
return await git_command.diff_names_since(base)
|
|
28
|
+
}
|
|
29
|
+
|
|
15
30
|
// The branch diff **plus** the untracked files. `git diff` lists neither, so a change that adds a
|
|
16
31
|
// new module and edits one inert file looked like an inert-only change and was handed `low`. The
|
|
17
32
|
// staged form needs no such addition: a file staged for addition is already in the cached diff.
|
|
18
33
|
async function read_changed_paths(is_staged: boolean): Promise<Array<string>> {
|
|
19
34
|
if (is_staged) return to_paths(await git_command.diff_cached_names())
|
|
20
35
|
|
|
21
|
-
const tracked = to_paths(await
|
|
36
|
+
const tracked = to_paths(await tracked_names())
|
|
22
37
|
const untracked = to_paths(await git_command.untracked_names())
|
|
23
38
|
|
|
24
39
|
return [...tracked, ...untracked]
|
|
@@ -8,6 +8,9 @@ import { git_location_environment, GIT_LOCATION_VARIABLES } from './git-location
|
|
|
8
8
|
// cannot name different directories. It had been run in three places with three timeouts and no
|
|
9
9
|
// memory of the answer, though a `PreToolUse` hook may ask it several times in one call.
|
|
10
10
|
|
|
11
|
+
// josh's own per-clone state inside the common git directory, in one entry of it so nothing josh writes
|
|
12
|
+
// sits at its root beside git's own files.
|
|
13
|
+
const STATE_DIRECTORY = 'josh'
|
|
11
14
|
const OWN_GIT_DIRECTORY = 0
|
|
12
15
|
const COMMON_GIT_DIRECTORY = 1
|
|
13
16
|
// The read runs inside `PreToolUse` hooks, which hold the tool call for as long as it takes;
|
|
@@ -97,6 +100,13 @@ function resolve(cwd: string): string | undefined {
|
|
|
97
100
|
return select_linked(directories(cwd))
|
|
98
101
|
}
|
|
99
102
|
|
|
100
|
-
const git_common_directory = {
|
|
103
|
+
const git_common_directory = {
|
|
104
|
+
STATE_DIRECTORY,
|
|
105
|
+
directories,
|
|
106
|
+
own,
|
|
107
|
+
repository,
|
|
108
|
+
resolve,
|
|
109
|
+
select_linked,
|
|
110
|
+
}
|
|
101
111
|
|
|
102
112
|
export { git_common_directory }
|
|
@@ -31,6 +31,16 @@ async function get_default_branch(): Promise<string> {
|
|
|
31
31
|
|
|
32
32
|
const MERGE_BASE_COMMAND = 'merge-base'
|
|
33
33
|
|
|
34
|
+
// The argument lists below are shared with `changed-paths-sync.ts`, so the hook-side synchronous
|
|
35
|
+
// reading cannot drift from this one.
|
|
36
|
+
function reference_check_arguments(reference: string): ReadonlyArray<string> {
|
|
37
|
+
return ['rev-parse', '--verify', '--quiet', reference]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function remote_reference_of(default_branch: string): string {
|
|
41
|
+
return `${REFS_REMOTES_ORIGIN_PREFIX}${default_branch}`
|
|
42
|
+
}
|
|
43
|
+
|
|
34
44
|
// **The ref the default branch is actually at**, which is not the same thing as its name.
|
|
35
45
|
// `get_default_branch` returns the bare name, and git resolves that to the
|
|
36
46
|
// *local* `refs/heads/<default>` — a ref nothing in this workflow advances, because merges happen on
|
|
@@ -45,7 +55,7 @@ const MERGE_BASE_COMMAND = 'merge-base'
|
|
|
45
55
|
// `prevent-main-commit.ts` exists to stop.
|
|
46
56
|
async function reference_exists(reference: string): Promise<boolean> {
|
|
47
57
|
try {
|
|
48
|
-
await git_spawn.read([
|
|
58
|
+
await git_spawn.read([...reference_check_arguments(reference)])
|
|
49
59
|
|
|
50
60
|
return true
|
|
51
61
|
} catch {
|
|
@@ -55,11 +65,33 @@ async function reference_exists(reference: string): Promise<boolean> {
|
|
|
55
65
|
|
|
56
66
|
async function default_branch_reference(): Promise<string> {
|
|
57
67
|
const default_branch = await get_default_branch()
|
|
58
|
-
const remote_reference =
|
|
68
|
+
const remote_reference = remote_reference_of(default_branch)
|
|
59
69
|
|
|
60
70
|
return (await reference_exists(remote_reference)) ? remote_reference : default_branch
|
|
61
71
|
}
|
|
62
72
|
|
|
73
|
+
function merge_base_arguments(reference: string): ReadonlyArray<string> {
|
|
74
|
+
return [MERGE_BASE_COMMAND, reference, 'HEAD']
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Where the side a merge in progress brings in left the default branch; git fails it where no merge
|
|
78
|
+
// is in progress. These three are `change_base.resolved_through_merge`'s, shared with the sync reading.
|
|
79
|
+
function incoming_base_arguments(reference: string): ReadonlyArray<string> {
|
|
80
|
+
return [MERGE_BASE_COMMAND, reference, 'MERGE_HEAD']
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// `--independent` drops every commit another one listed reaches, so of two commits on the default
|
|
84
|
+
// branch's history it keeps the later — read from its output by `later_base_of`.
|
|
85
|
+
function later_base_arguments(base: string, incoming: string): ReadonlyArray<string> {
|
|
86
|
+
return [MERGE_BASE_COMMAND, '--independent', base, incoming]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function later_base_of(output: string | undefined, base: string): string {
|
|
90
|
+
const [later = ''] = output?.split('\n', 1) ?? []
|
|
91
|
+
|
|
92
|
+
return later === '' ? base : later
|
|
93
|
+
}
|
|
94
|
+
|
|
63
95
|
// The commit this branch was cut from — and the base every "changed" reading below measures
|
|
64
96
|
// against, in place of the default branch itself.
|
|
65
97
|
//
|
|
@@ -89,7 +121,7 @@ async function change_base(): Promise<string> {
|
|
|
89
121
|
const default_branch = await default_branch_reference()
|
|
90
122
|
|
|
91
123
|
try {
|
|
92
|
-
return await git_spawn.read([
|
|
124
|
+
return await git_spawn.read([...merge_base_arguments(default_branch)])
|
|
93
125
|
} catch {
|
|
94
126
|
return default_branch
|
|
95
127
|
}
|
|
@@ -153,8 +185,8 @@ async function change_base_commit(): Promise<string> {
|
|
|
153
185
|
|
|
154
186
|
// The working tree against any commit, with the same flags as the branch diff. `josh test:related`
|
|
155
187
|
// reads the change since the commit its test-read map was recorded on, which is not the merge base.
|
|
156
|
-
|
|
157
|
-
return
|
|
188
|
+
function names_since_arguments(commit: string): ReadonlyArray<string> {
|
|
189
|
+
return [
|
|
158
190
|
...NO_PATH_QUOTING,
|
|
159
191
|
'diff',
|
|
160
192
|
NAME_ONLY_FLAG,
|
|
@@ -162,7 +194,11 @@ async function diff_names_since(commit: string): Promise<string> {
|
|
|
162
194
|
NO_RENAME_DETECTION,
|
|
163
195
|
commit,
|
|
164
196
|
'--',
|
|
165
|
-
]
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async function diff_names_since(commit: string): Promise<string> {
|
|
201
|
+
return await git_spawn.read([...names_since_arguments(commit)])
|
|
166
202
|
}
|
|
167
203
|
|
|
168
204
|
// Which of `paths` a commit's tree holds. `josh test:related` asks it of the tree its test-read map
|
|
@@ -197,17 +233,17 @@ async function diff_cached_names(): Promise<string> {
|
|
|
197
233
|
])
|
|
198
234
|
}
|
|
199
235
|
|
|
200
|
-
// The
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
async function
|
|
236
|
+
// The diff since `base` as `added\tdeleted\tpath` rows — the same flags as `diff_names_since`, so the
|
|
237
|
+
// size read and the name read agree on what "changed" is. A binary file prints `-` for both counts;
|
|
238
|
+
// the parser above `josh split:assess` reads it treats those as zero changed lines.
|
|
239
|
+
async function diff_numstat_since(base: string): Promise<string> {
|
|
204
240
|
return await git_spawn.read([
|
|
205
241
|
...NO_PATH_QUOTING,
|
|
206
242
|
'diff',
|
|
207
243
|
'--numstat',
|
|
208
244
|
NO_RELATIVE_PATHS,
|
|
209
245
|
NO_RENAME_DETECTION,
|
|
210
|
-
|
|
246
|
+
base,
|
|
211
247
|
'--',
|
|
212
248
|
])
|
|
213
249
|
}
|
|
@@ -226,19 +262,22 @@ async function diff_main_numstat(): Promise<string> {
|
|
|
226
262
|
// pathspec restores the whole tree; the flag restores the root-relative spelling.
|
|
227
263
|
const WHOLE_TREE_PATHSPEC = ':/'
|
|
228
264
|
|
|
265
|
+
const UNTRACKED_ARGUMENTS: ReadonlyArray<string> = [
|
|
266
|
+
...NO_PATH_QUOTING,
|
|
267
|
+
'ls-files',
|
|
268
|
+
'--others',
|
|
269
|
+
'--exclude-standard',
|
|
270
|
+
'--full-name',
|
|
271
|
+
WHOLE_TREE_PATHSPEC,
|
|
272
|
+
]
|
|
273
|
+
|
|
229
274
|
async function untracked_names(): Promise<string> {
|
|
230
|
-
return await git_spawn.read([
|
|
231
|
-
...NO_PATH_QUOTING,
|
|
232
|
-
'ls-files',
|
|
233
|
-
'--others',
|
|
234
|
-
'--exclude-standard',
|
|
235
|
-
'--full-name',
|
|
236
|
-
WHOLE_TREE_PATHSPEC,
|
|
237
|
-
])
|
|
275
|
+
return await git_spawn.read([...UNTRACKED_ARGUMENTS])
|
|
238
276
|
}
|
|
239
277
|
|
|
240
278
|
const git_diff_reads = {
|
|
241
279
|
DEFAULT_BRANCH_ARGUMENTS,
|
|
280
|
+
UNTRACKED_ARGUMENTS,
|
|
242
281
|
change_base,
|
|
243
282
|
change_base_commit,
|
|
244
283
|
default_branch_of,
|
|
@@ -246,9 +285,16 @@ const git_diff_reads = {
|
|
|
246
285
|
diff_cached_names,
|
|
247
286
|
diff_main,
|
|
248
287
|
diff_main_names,
|
|
249
|
-
|
|
288
|
+
diff_numstat_since,
|
|
250
289
|
diff_names_since,
|
|
251
290
|
get_default_branch,
|
|
291
|
+
incoming_base_arguments,
|
|
292
|
+
later_base_arguments,
|
|
293
|
+
later_base_of,
|
|
294
|
+
merge_base_arguments,
|
|
295
|
+
names_since_arguments,
|
|
296
|
+
reference_check_arguments,
|
|
297
|
+
remote_reference_of,
|
|
252
298
|
tree_names_at,
|
|
253
299
|
untracked_names,
|
|
254
300
|
}
|
package/scripts/git/git-error.ts
CHANGED
|
@@ -25,13 +25,18 @@ function get_cause_message(cause: unknown): string | undefined {
|
|
|
25
25
|
return undefined
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
// The heads of the lines a failed command names the error it ended on, and that error's cause, with —
|
|
29
|
+
// read back by a stopped `josh ship` stage (joshuafolkken/kit#5052).
|
|
30
|
+
const FAILURE_PREFIX = '❌ Error:'
|
|
31
|
+
const DETAILS_PREFIX = '💡 Details:'
|
|
32
|
+
|
|
28
33
|
function display_error_details(cause: unknown): void {
|
|
29
34
|
const cause_message = get_cause_message(cause)
|
|
30
35
|
|
|
31
36
|
if (cause_message === undefined || cause_message.length === 0) return
|
|
32
37
|
|
|
33
38
|
console.error('')
|
|
34
|
-
console.error(
|
|
39
|
+
console.error(DETAILS_PREFIX, cause_message)
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
const FAILURE_EXIT_CODE = 1
|
|
@@ -72,7 +77,7 @@ function display_failure(error: unknown): void {
|
|
|
72
77
|
const error_message = error_text.message_of(error)
|
|
73
78
|
|
|
74
79
|
console.error('')
|
|
75
|
-
console.error(
|
|
80
|
+
console.error(FAILURE_PREFIX, error_message)
|
|
76
81
|
|
|
77
82
|
if (error instanceof Error && error.cause !== undefined) {
|
|
78
83
|
display_error_details(error.cause)
|
|
@@ -118,6 +123,8 @@ function handle(error: unknown): void {
|
|
|
118
123
|
}
|
|
119
124
|
|
|
120
125
|
const git_error = {
|
|
126
|
+
DETAILS_PREFIX,
|
|
127
|
+
FAILURE_PREFIX,
|
|
121
128
|
handle,
|
|
122
129
|
}
|
|
123
130
|
|
|
@@ -36,6 +36,7 @@ const ai_review_pull_comment_schema = z.object({
|
|
|
36
36
|
body: z.string().optional(),
|
|
37
37
|
url: z.string().optional(),
|
|
38
38
|
author: z.object({ login: z.string().optional() }).optional(),
|
|
39
|
+
updatedAt: z.string().optional(),
|
|
39
40
|
})
|
|
40
41
|
|
|
41
42
|
const pr_info_schema = z.object({
|
|
@@ -108,6 +109,7 @@ const rest_comment_schema = z.looseObject({
|
|
|
108
109
|
body: z.string().nullish(),
|
|
109
110
|
html_url: z.string().optional(),
|
|
110
111
|
user: z.looseObject({ login: z.string().optional() }).nullish(),
|
|
112
|
+
updated_at: z.string().optional(),
|
|
111
113
|
})
|
|
112
114
|
|
|
113
115
|
// The `number,state,labels,body` read, for the epic check and the `--add` closed-epic refusal.
|
|
@@ -137,6 +139,12 @@ const epic_subject_schema = z.object({
|
|
|
137
139
|
// So `blockedBy` is optional for the reason it is absent in practice — the display and the busy
|
|
138
140
|
// check never ask for it, and a field that was not asked for is left out of the mapped row rather
|
|
139
141
|
// than filled in.
|
|
142
|
+
// Who wrote an issue, as REST names it — read through `gh_author_association.author_of`.
|
|
143
|
+
const author_fields_schema = {
|
|
144
|
+
author_association: z.string().nullish(),
|
|
145
|
+
user: z.looseObject({ login: z.string() }).nullish(),
|
|
146
|
+
}
|
|
147
|
+
|
|
140
148
|
const open_issue_schema = z.object({
|
|
141
149
|
number: z.number(),
|
|
142
150
|
title: z.string(),
|
|
@@ -145,6 +153,10 @@ const open_issue_schema = z.object({
|
|
|
145
153
|
blockedBy: blocked_by_schema,
|
|
146
154
|
// Present only on the pickup listing, which reads it for the paths each issue declares.
|
|
147
155
|
body: z.string().optional(),
|
|
156
|
+
...author_fields_schema,
|
|
157
|
+
// Assembled by the pickup from the author above, never read off the listing: whether the author
|
|
158
|
+
// has write access. Absent on every other listing.
|
|
159
|
+
author_trusted: z.boolean().optional(),
|
|
148
160
|
})
|
|
149
161
|
|
|
150
162
|
type RollupItemData = z.infer<typeof rollup_item_schema>
|
|
@@ -154,6 +166,7 @@ type OpenIssueData = z.infer<typeof open_issue_schema>
|
|
|
154
166
|
type RestCommentData = z.infer<typeof rest_comment_schema>
|
|
155
167
|
|
|
156
168
|
export {
|
|
169
|
+
author_fields_schema,
|
|
157
170
|
package_name_schema,
|
|
158
171
|
rollup_item_schema,
|
|
159
172
|
pr_raw_schema,
|
|
@@ -19,6 +19,7 @@ import { repository_lock } from './repository-lock'
|
|
|
19
19
|
// `lane-start-point.ts` and `release-publish.ts` both act on — so this module stops at "what git
|
|
20
20
|
// printed" and the meaning of it is decided there.
|
|
21
21
|
const WORKTREE = 'worktree'
|
|
22
|
+
const ORIGIN = 'origin'
|
|
22
23
|
|
|
23
24
|
// **Every call that writes `.git/worktrees/` runs under one repository-wide lock**.
|
|
24
25
|
// `git worktree add` is not safe against itself: while one add is still
|
|
@@ -87,6 +88,17 @@ async function worktree_add(
|
|
|
87
88
|
return await locked([WORKTREE, ...flags, directory, start_point ?? branch_name], SUITE_TIMEOUT_MS)
|
|
88
89
|
}
|
|
89
90
|
|
|
91
|
+
// **A lane's upstream is written when it is opened, not by its first push**
|
|
92
|
+
// (joshuafolkken/kit#4653). A Codex lane's sandbox cannot write the common directory's `config`, so the
|
|
93
|
+
// `--set-upstream` its push falls back to records nothing, and every later reader of `@{upstream}`
|
|
94
|
+
// would take the pushed lane for an unpushed one. Pointing it at the lane's own name on `origin` keeps
|
|
95
|
+
// a bare `git push` working before the remote branch exists. Under the work-tree lock, since two lanes
|
|
96
|
+
// opened at once would otherwise race on `config.lock`.
|
|
97
|
+
async function set_upstream(branch_name: string): Promise<void> {
|
|
98
|
+
await locked(['config', `branch.${branch_name}.remote`, ORIGIN])
|
|
99
|
+
await locked(['config', `branch.${branch_name}.merge`, `refs/heads/${branch_name}`])
|
|
100
|
+
}
|
|
101
|
+
|
|
90
102
|
// A throwaway tree at one commit, on no branch — `josh test:red` checks the merge-base out here, so
|
|
91
103
|
// the pre-fix tree is built without creating a branch or touching the caller's tree and index.
|
|
92
104
|
async function worktree_add_detached(directory: string, commit: string): Promise<string> {
|
|
@@ -139,6 +151,7 @@ async function branch_delete(branch_name: string): Promise<string> {
|
|
|
139
151
|
const git_worktree = {
|
|
140
152
|
branch_delete,
|
|
141
153
|
ls_remote_branch,
|
|
154
|
+
set_upstream,
|
|
142
155
|
worktree_add,
|
|
143
156
|
worktree_add_detached,
|
|
144
157
|
worktree_list,
|
|
@@ -7,7 +7,10 @@ import { git_spawn } from './git-spawn'
|
|
|
7
7
|
// **A branch is removed only when all three hold** — its upstream is gone, it is merged into the
|
|
8
8
|
// default branch, and no work tree has it checked out. Gone alone is not enough: a branch whose remote
|
|
9
9
|
// was deleted by hand before its work merged still holds the only copy of it. A branch with no
|
|
10
|
-
// upstream at all is never gone, so a local-only branch stays.
|
|
10
|
+
// upstream at all is never gone, so a local-only branch stays. A lane branch has its upstream from the
|
|
11
|
+
// moment it opens (`lane-open.ts`), so an unpushed lane reads `[gone]`: the merge test keeps one with
|
|
12
|
+
// commits of its own, and one with none — merged already — is kept by its work tree, then deleted with
|
|
13
|
+
// nothing lost once the tree is gone.
|
|
11
14
|
//
|
|
12
15
|
// **One `for-each-ref` read carries the work-tree answer too** — `%(worktreepath)` is git's own
|
|
13
16
|
// record of which tree holds the branch, so no `git worktree list` parse is repeated here.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// The resolution of a merge that stopped on `document-byte-budget.ts`'s ceiling rows
|
|
2
|
+
// (joshuafolkken/kit#4976). Two lanes that grow the same page each raise that page's ceiling and add a
|
|
3
|
+
// comment naming their Issue, so the later merge stops on the same row from both sides.
|
|
4
|
+
//
|
|
5
|
+
// **Only a hunk made of ceiling rows and their comments is resolved**: each side is comment lines
|
|
6
|
+
// followed by at most one ceiling row, both rows name the same page, and the result keeps every
|
|
7
|
+
// comment from both sides and the larger ceiling. A hunk holding only comments is resolved only when
|
|
8
|
+
// the row it annotates follows it. Any other hunk — the table's structure, another function — throws,
|
|
9
|
+
// so the merge stays the `conflict` it was. The merged page's size is still checked against the kept
|
|
10
|
+
// ceiling by `document-byte-budget.test.ts`.
|
|
11
|
+
|
|
12
|
+
const BUDGET_TABLE_PATH = 'scripts/document/document-byte-budget.ts'
|
|
13
|
+
const CEILING_ROW = /^\t\{ path: '(?<path>[^']+)', bytes: (?<bytes>[\d_]+) \},$/u
|
|
14
|
+
const COMMENT_PREFIX = '\t// '
|
|
15
|
+
const CONFLICT_MARKER = /^(?:<{7}|={7}|>{7}|\|{7})/mu
|
|
16
|
+
// A diff3 base section, dropped before the hunks are read: the resolution needs only the two sides.
|
|
17
|
+
const BASE_SECTION = /^\|{7} .*\n(?:.*\n)*?(?=={7}\n)/gmu
|
|
18
|
+
// One conflict hunk; the line after it is captured without being consumed.
|
|
19
|
+
const HUNK = /^<{7} .*\n(?<ours>(?:.*\n)*?)={7}\n(?<theirs>(?:.*\n)*?)>{7} .*\n(?=(?<after>.*))/gmu
|
|
20
|
+
|
|
21
|
+
interface Side {
|
|
22
|
+
comments: ReadonlyArray<string>
|
|
23
|
+
row: string | undefined
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function side_of(text: string): Side {
|
|
27
|
+
const lines = text.split('\n').slice(0, -1)
|
|
28
|
+
const last = lines.at(-1) ?? ''
|
|
29
|
+
const row = CEILING_ROW.test(last) ? last : undefined
|
|
30
|
+
const comments = row === undefined ? lines : lines.slice(0, -1)
|
|
31
|
+
|
|
32
|
+
if (comments.some((line) => !line.startsWith(COMMENT_PREFIX))) {
|
|
33
|
+
throw new Error(`${BUDGET_TABLE_PATH}: a conflict outside the ceiling rows`)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return { comments, row }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function ceiling_of(row: string): { path: string; bytes: number } {
|
|
40
|
+
const groups: Partial<Record<'path' | 'bytes', string>> = CEILING_ROW.exec(row)?.groups ?? {}
|
|
41
|
+
|
|
42
|
+
return { path: groups.path ?? '', bytes: Number(groups.bytes?.replaceAll('_', '')) }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function larger_row(ours: string, theirs: string): string {
|
|
46
|
+
const [mine, other] = [ceiling_of(ours), ceiling_of(theirs)]
|
|
47
|
+
|
|
48
|
+
if (mine.path !== other.path) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`${BUDGET_TABLE_PATH}: rows of two pages conflict (${mine.path}, ${other.path})`,
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return mine.bytes >= other.bytes ? ours : theirs
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function rows_of(ours: Side, theirs: Side, after: string): ReadonlyArray<string> {
|
|
58
|
+
if (ours.row !== undefined && theirs.row !== undefined) return [larger_row(ours.row, theirs.row)]
|
|
59
|
+
// Equal here only when both are undefined: a hunk of comments alone, kept only above a row.
|
|
60
|
+
if (ours.row === theirs.row && CEILING_ROW.test(after)) return []
|
|
61
|
+
|
|
62
|
+
throw new Error(`${BUDGET_TABLE_PATH}: a ceiling row changed on one side only`)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function merge_hunk(ours: string, theirs: string, after: string): string {
|
|
66
|
+
const [mine, other] = [side_of(ours), side_of(theirs)]
|
|
67
|
+
const comments = [...new Set([...mine.comments, ...other.comments])]
|
|
68
|
+
|
|
69
|
+
return [...comments, ...rows_of(mine, other, after)].map((line) => `${line}\n`).join('')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// The file with every hunk resolved; throws when any hunk is not a ceiling-row conflict.
|
|
73
|
+
function resolve(content: string): string {
|
|
74
|
+
const resolved = content
|
|
75
|
+
.replaceAll(BASE_SECTION, '')
|
|
76
|
+
.replaceAll(HUNK, (_hunk: string, ours: string, theirs: string, after: string) =>
|
|
77
|
+
merge_hunk(ours, theirs, after),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if (resolved === content || CONFLICT_MARKER.test(resolved)) {
|
|
81
|
+
throw new Error(`${BUDGET_TABLE_PATH}: a conflict left unresolved`)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return resolved
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const main_merge_budget_conflict = { BUDGET_TABLE_PATH, resolve }
|
|
88
|
+
|
|
89
|
+
export { main_merge_budget_conflict }
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
1
2
|
import { git_spawn } from './git-spawn'
|
|
2
3
|
|
|
3
4
|
// What `josh main:merge` refuses before it merges, and what it tells the run to do instead.
|
|
@@ -18,8 +19,12 @@ const UNMERGED_CODES = new Set(['DD', 'AU', 'UD', 'UA', 'DU', 'AA', 'UU'])
|
|
|
18
19
|
const UNSTAGED_INDEX_CODES = new Set([' ', '?', '!'])
|
|
19
20
|
const DIRECTORY_SUFFIX = '/'
|
|
20
21
|
const COMMIT_COMMAND = '`pnpm josh git -y`'
|
|
22
|
+
// A lane child's push is `josh ship`'s, so the lane-background row refuses a pushing `git -y` there;
|
|
23
|
+
// this is the commit-only form ship's own sync closes a merge with (`run-ship-sync.ts`).
|
|
24
|
+
const LANE_COMMIT_COMMAND = '`pnpm josh git -y --skip-push --skip-pr "<title> #<N>"`'
|
|
21
25
|
const PROCEDURE_POINTER =
|
|
22
26
|
'`.claude/skills/workflow-commands/chain-rule.md` → "origin/main is merged in before the gate"'
|
|
27
|
+
const MERGE_RERUN = '`pnpm josh main:merge`'
|
|
23
28
|
|
|
24
29
|
function status_lines(status: string): Array<string> {
|
|
25
30
|
return status.split('\n').filter((line) => line.length > STATUS_PREFIX_LENGTH)
|
|
@@ -57,55 +62,85 @@ function overlapping_paths(status: string, incoming: ReadonlyArray<string>): Arr
|
|
|
57
62
|
return uncommitted.filter((path) => incoming.some((changed) => covers(path, changed)))
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
function
|
|
65
|
+
function commit_command(is_lane_child = lane_child_marker.is_child_of(process.cwd())): string {
|
|
66
|
+
return is_lane_child ? LANE_COMMIT_COMMAND : COMMIT_COMMAND
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// `prefix` names the refusing command, `rerun` what to run once the merge is closed — `josh stash:push`
|
|
70
|
+
// refuses the same index, since `git stash` cannot set unresolved paths aside.
|
|
71
|
+
function unresolved_message(
|
|
72
|
+
prefix: string,
|
|
73
|
+
paths: ReadonlyArray<string>,
|
|
74
|
+
rerun: string,
|
|
75
|
+
commit = commit_command(),
|
|
76
|
+
): string {
|
|
61
77
|
return (
|
|
62
|
-
|
|
63
|
-
`markers, then finish through ${
|
|
64
|
-
`permission is needed, and inside a lane this is Tier A. Rerun
|
|
78
|
+
`${prefix}: the index still holds unresolved paths (${paths.join(', ')}). Remove the conflict ` +
|
|
79
|
+
`markers, then finish through ${commit} — it stages and commits them, so no \`git add\` ` +
|
|
80
|
+
`permission is needed, and inside a lane this is Tier A. Rerun ${rerun} after it ` +
|
|
65
81
|
`(${PROCEDURE_POINTER}).`
|
|
66
82
|
)
|
|
67
83
|
}
|
|
68
84
|
|
|
69
|
-
function staged_message(paths: ReadonlyArray<string
|
|
85
|
+
function staged_message(paths: ReadonlyArray<string>, commit: string): string {
|
|
70
86
|
return (
|
|
71
87
|
`main:merge: the index holds staged changes (${paths.join(', ')}), which git refuses to merge ` +
|
|
72
|
-
`over. Commit them first through ${
|
|
88
|
+
`over. Commit them first through ${commit}, then rerun \`pnpm josh main:merge\` ` +
|
|
73
89
|
`(${PROCEDURE_POINTER}).`
|
|
74
90
|
)
|
|
75
91
|
}
|
|
76
92
|
|
|
77
|
-
function overlap_message(
|
|
93
|
+
function overlap_message(
|
|
94
|
+
default_branch: string,
|
|
95
|
+
paths: ReadonlyArray<string>,
|
|
96
|
+
commit: string,
|
|
97
|
+
): string {
|
|
78
98
|
return (
|
|
79
99
|
`main:merge: uncommitted changes touch files origin/${default_branch} also changed ` +
|
|
80
|
-
`(${paths.join(', ')}). Commit the work first through ${
|
|
100
|
+
`(${paths.join(', ')}). Commit the work first through ${commit}, then rerun ` +
|
|
81
101
|
`\`pnpm josh main:merge\`. Never stash around the merge — a stash reapplied over it leaves the ` +
|
|
82
102
|
`conflict half-recorded in the index (${PROCEDURE_POINTER}).`
|
|
83
103
|
)
|
|
84
104
|
}
|
|
85
105
|
|
|
86
106
|
// Appended to git's own report when the merge itself stops on a conflict.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
107
|
+
function conflict_hint(commit = commit_command()): string {
|
|
108
|
+
return (
|
|
109
|
+
`main:merge: finish a conflicted merge by removing the conflict markers, then ${commit} ` +
|
|
110
|
+
`records the merge commit — no \`git add\` permission is needed (${PROCEDURE_POINTER}).`
|
|
111
|
+
)
|
|
112
|
+
}
|
|
90
113
|
|
|
91
|
-
function
|
|
114
|
+
function merge_refusal(
|
|
92
115
|
status: string,
|
|
93
116
|
incoming: ReadonlyArray<string>,
|
|
94
117
|
default_branch: string,
|
|
118
|
+
commit: string,
|
|
95
119
|
): string | undefined {
|
|
96
|
-
const unmerged = unmerged_paths(status)
|
|
97
|
-
|
|
98
|
-
if (unmerged.length > 0) return unmerged_message(unmerged)
|
|
99
120
|
// Nothing incoming means git answers "Already up to date" whatever the index holds.
|
|
100
121
|
if (incoming.length === 0) return undefined
|
|
101
122
|
|
|
102
123
|
const staged = staged_paths(status)
|
|
103
124
|
|
|
104
|
-
if (staged.length > 0) return staged_message(staged)
|
|
125
|
+
if (staged.length > 0) return staged_message(staged, commit)
|
|
105
126
|
|
|
106
127
|
const overlap = overlapping_paths(status, incoming)
|
|
107
128
|
|
|
108
|
-
return overlap.length > 0 ? overlap_message(default_branch, overlap) : undefined
|
|
129
|
+
return overlap.length > 0 ? overlap_message(default_branch, overlap, commit) : undefined
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// `commit` is the command the message names, resolved from the lane mark unless a caller passes it.
|
|
133
|
+
function refusal(
|
|
134
|
+
status: string,
|
|
135
|
+
incoming: ReadonlyArray<string>,
|
|
136
|
+
default_branch: string,
|
|
137
|
+
commit = commit_command(),
|
|
138
|
+
): string | undefined {
|
|
139
|
+
const unmerged = unmerged_paths(status)
|
|
140
|
+
|
|
141
|
+
if (unmerged.length > 0) return unresolved_message('main:merge', unmerged, MERGE_RERUN, commit)
|
|
142
|
+
|
|
143
|
+
return merge_refusal(status, incoming, default_branch, commit)
|
|
109
144
|
}
|
|
110
145
|
|
|
111
146
|
// The paths the default branch changed since this branch left it — what the merge would bring in.
|
|
@@ -122,12 +157,14 @@ async function incoming_paths(default_branch: string): Promise<Array<string>> {
|
|
|
122
157
|
}
|
|
123
158
|
|
|
124
159
|
const main_merge_guard = {
|
|
125
|
-
|
|
160
|
+
commit_command,
|
|
161
|
+
conflict_hint,
|
|
126
162
|
incoming_paths,
|
|
127
163
|
overlapping_paths,
|
|
128
164
|
refusal,
|
|
129
165
|
staged_paths,
|
|
130
166
|
unmerged_paths,
|
|
167
|
+
unresolved_message,
|
|
131
168
|
}
|
|
132
169
|
|
|
133
170
|
export { main_merge_guard }
|