@joshuafolkken/kit 1.1050.0 → 1.1128.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/settings.json +9 -8
- package/.claude/skills/epic-commands/SKILL.md +5 -7
- package/.claude/skills/workflow-commands/SKILL.md +20 -12
- package/.claude/skills/workflow-commands/background-commands.md +36 -84
- package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
- package/.claude/skills/workflow-commands/backlogrun-progress.md +30 -33
- package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -12
- package/.claude/skills/workflow-commands/backlogrun.md +2 -2
- package/.claude/skills/workflow-commands/chain-rule.md +4 -2
- package/.claude/skills/workflow-commands/delegation.md +3 -3
- package/.claude/skills/workflow-commands/followup-reference.md +1 -1
- package/.claude/skills/workflow-commands/followup.md +7 -3
- package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/fullrun.md +8 -6
- package/.claude/skills/workflow-commands/halfrun.md +19 -21
- package/.claude/skills/workflow-commands/issue-comments.md +1 -1
- package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
- package/.claude/skills/workflow-commands/issue-scout.md +1 -1
- package/.claude/skills/workflow-commands/kickoff.md +9 -4
- package/.claude/skills/workflow-commands/latest-gate.md +8 -16
- package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
- package/.claude/skills/workflow-commands/observation-filing.md +3 -3
- package/.claude/skills/workflow-commands/pre-gate-cut.md +4 -8
- package/.claude/skills/workflow-commands/prerequisite.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +36 -0
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +4 -18
- package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
- package/.codex/hooks.json +16 -20
- package/.github/actions/setup-node/action.yml +33 -0
- package/.github/actions/setup-pnpm/action.yml +93 -0
- package/.github/dependabot.yml +5 -1
- package/.github/workflows/auto-tag.yml +2 -3
- package/.github/workflows/ci.yml +31 -134
- package/.github/workflows/dependabot-auto-merge.yml +1 -0
- package/.github/workflows/pr-classification.yml +6 -44
- package/.github/workflows/production.yml +1 -0
- package/.github/workflows/publish.yml +43 -47
- package/.github/workflows/sonar-qube.yml +41 -4
- package/.pnpmfile.mjs +29 -0
- package/AGENTS.md +5 -2
- package/CLAUDE.md +33 -27
- package/GEMINI.md +5 -2
- package/README.md +66 -20
- package/SECURITY.md +37 -6
- package/cspell/index.yaml +6 -1
- package/dist/CLAUDE.basic.md +6 -6
- package/dist/CLAUDE.md +33 -27
- package/dist/CLAUDE.static.md +6 -6
- package/dist/config-merge/index.js +48 -12
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-7VPDUBRN.js → chunk-4JZDP5X5.js} +152 -155
- package/dist/hooks/{chunk-HJIISEAC.js → chunk-5SD2YM7Z.js} +5 -13
- package/dist/hooks/{chunk-NAS4C7GP.js → chunk-77J7IEQM.js} +2 -2
- package/dist/hooks/{chunk-DMQN45FN.js → chunk-7HVB7SZG.js} +3 -3
- package/dist/hooks/{chunk-RLDX5SOC.js → chunk-AIOIOMPX.js} +4413 -1970
- package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M7QKEKWO.js} +873 -2049
- package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-MKVGBQPA.js} +2 -2
- package/dist/hooks/{chunk-EJDX2TOB.js → chunk-NXYMNPUQ.js} +7 -88
- package/dist/hooks/{chunk-NJQOBE6L.js → chunk-QVLT52OV.js} +2 -7
- package/dist/hooks/{chunk-GQ7KP45M.js → chunk-XYUIQOW3.js} +2 -2
- package/dist/hooks/codex-hook-adapter.js +12 -48
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +280 -0
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/session-lang.js +0 -1
- package/dist/hooks/stop-guard.js +192 -333
- package/dist/josh.js +240 -148
- package/dist/managed-marker/index.js +2 -1
- package/dist/version/index.js +70 -78
- package/eslint/rules/promise.js +5 -0
- package/eslint/rules/unicorn.js +3 -2
- package/package.json +26 -5
- package/pnpm-workspace.yaml +5 -7
- package/prompts/collaboration-workflow/glossary.md +17 -0
- package/prompts/collaboration-workflow/issue-citation.md +5 -5
- package/prompts/collaboration-workflow/issue-template.md +1 -1
- package/prompts/collaboration-workflow/operating-rules.md +5 -5
- package/prompts/collaboration-workflow/overview.md +13 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow/report-format.md +1 -1
- package/prompts/collaboration-workflow/residency.md +3 -3
- package/prompts/collaboration-workflow/rule-delivery.md +1 -1
- package/prompts/collaboration-workflow/turn-batching.md +3 -3
- package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
- package/prompts/collaboration-workflow/wip-cap.md +25 -22
- package/prompts/collaboration-workflow.md +6 -8
- package/prompts/review-rubric.md +1 -1
- package/prompts/review.md +3 -3
- package/prompts/sonar-hotspot-handling.md +11 -3
- package/prompts/testing-guide.md +3 -3
- package/scripts/adopt/adopt-toolkits.ts +0 -2
- package/scripts/adopt/adopt.ts +0 -2
- package/scripts/agent/agent-argv.ts +0 -2
- package/scripts/agent/agent-diagnostics.ts +1 -1
- package/scripts/agent/agent-role-profile.ts +0 -7
- package/scripts/agent/claude-agent-argv.ts +0 -2
- package/scripts/agent/codex-agent-argv.ts +1 -1
- package/scripts/agent/codex-hooks.ts +92 -0
- package/scripts/agent/interactive-ask.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +6 -16
- package/scripts/backlog/backlog-arrival.ts +30 -10
- package/scripts/backlog/backlog-budget-cli.ts +15 -16
- package/scripts/backlog/backlog-budget.ts +0 -2
- package/scripts/backlog/backlog-defect-priority.ts +2 -2
- package/scripts/backlog/backlog-drive-cli.ts +10 -8
- package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
- package/scripts/backlog/backlog-drive-named.ts +2 -1
- package/scripts/backlog/backlog-drive.ts +76 -16
- package/scripts/backlog/backlog-named.ts +0 -3
- package/scripts/backlog/backlog-next.ts +9 -15
- package/scripts/backlog/backlog-offer-cli.ts +6 -19
- package/scripts/backlog/backlog-plan-cli.ts +1 -7
- package/scripts/backlog/backlog-plan.ts +30 -19
- package/scripts/backlog/backlog-pool.ts +3 -6
- package/scripts/backlog/backlog-rank.ts +2 -2
- package/scripts/backlog/backlog-ready.ts +39 -10
- package/scripts/backlog/backlog-scope.ts +1 -3
- package/scripts/backlog/backlog-stalled-detect.ts +2 -2
- package/scripts/backlog/backlog-stalled.ts +0 -1
- package/scripts/backlog/backlog-waves.ts +5 -2
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/build/build-codex-hooks.ts +26 -0
- package/scripts/build/build-hooks.ts +85 -9
- package/scripts/build/hook-bundle-stamp.ts +111 -0
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +1 -1
- package/scripts/ci/composite-actions.ts +30 -0
- package/scripts/ci/pr-classification.ts +3 -3
- package/scripts/claude/workflow-destination.ts +10 -1
- package/scripts/clone/clone-fingerprint.ts +0 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/json-format.ts +0 -1
- package/scripts/config-merge/parse-jsonc.ts +33 -3
- package/scripts/config-merge/patch-json-key.ts +13 -6
- package/scripts/config-merge/patch-yaml-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +2 -9
- package/scripts/cost-runtime/cost-attribute.ts +0 -1
- package/scripts/cost-runtime/cost-cli.ts +3 -10
- package/scripts/cost-runtime/cost-corpus.ts +0 -2
- package/scripts/cost-runtime/cost-format.ts +0 -3
- package/scripts/cost-runtime/cost-pricing.ts +0 -1
- package/scripts/cost-runtime/cost-tokens.ts +0 -1
- package/scripts/delegation/delegation-cli.ts +1 -1
- package/scripts/delegation/delegation-policy.ts +0 -1
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +0 -2
- package/scripts/delegation/investigation-reads.ts +1 -164
- package/scripts/discovery/repo-map-logic.ts +0 -1
- package/scripts/discovery/repo-party-cli.ts +1 -1
- package/scripts/doctor/doctor-consumer.ts +6 -10
- package/scripts/doctor/doctor-io.ts +9 -13
- package/scripts/doctor/doctor-logic.ts +0 -4
- package/scripts/doctor/doctor.ts +14 -9
- package/scripts/document/backlogrun-parent-read-set.ts +12 -1
- package/scripts/document/document-byte-budget.ts +5 -5
- package/scripts/document/document-byte-check.ts +0 -1
- package/scripts/document/document-read-cli.ts +0 -2
- package/scripts/document/document-section-cli.ts +1 -1
- package/scripts/document/document-section.ts +0 -3
- package/scripts/document/edit-files-cli.ts +0 -1
- package/scripts/document/entry-read-budget.ts +21 -7
- package/scripts/document/entry-read-set.ts +32 -8
- package/scripts/document/lane-child-read-set.ts +8 -6
- package/scripts/document/read-files-cli.ts +0 -4
- package/scripts/document/read-set-cli.ts +0 -2
- package/scripts/document/read-set-point-of-use.ts +9 -3
- package/scripts/document/read-set-pricing.ts +0 -1
- package/scripts/document/read-set-trim.ts +4 -2
- package/scripts/epic/epic-add.ts +1 -1
- package/scripts/epic/epic-audit-cli.ts +1 -4
- package/scripts/epic/epic-audit-orphans.ts +1 -3
- package/scripts/epic/epic-audit-rationale.ts +0 -1
- package/scripts/epic/epic-audit-report.ts +0 -2
- package/scripts/epic/epic-audit.ts +8 -22
- package/scripts/epic/epic-bundle-cli.ts +1 -1
- package/scripts/epic/epic-bundle-evidence.ts +0 -1
- package/scripts/epic/epic-bundle-referenced.ts +1 -5
- package/scripts/epic/epic-bundle.ts +0 -4
- package/scripts/epic/epic-busy.ts +4 -5
- package/scripts/epic/epic-candidate-confirm.ts +0 -5
- package/scripts/epic/epic-classify.ts +2 -2
- package/scripts/epic/epic-cli-argv.ts +0 -1
- package/scripts/epic/epic-close-comment.ts +1 -1
- package/scripts/epic/epic-close.ts +5 -2
- package/scripts/epic/epic-cross-repo.ts +2 -4
- package/scripts/epic/epic-decision.ts +0 -1
- package/scripts/epic/epic-fetch.ts +2 -2
- package/scripts/epic/epic-index.ts +2 -3
- package/scripts/epic/epic-issue.ts +1 -15
- package/scripts/epic/epic-lane-offer.ts +9 -8
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +1 -3
- package/scripts/epic/epic-next-views.ts +0 -1
- package/scripts/epic/epic-next.ts +1 -10
- package/scripts/epic/epic-parse.ts +0 -1
- package/scripts/epic/epic-promote.ts +0 -9
- package/scripts/epic/epic-rank.ts +2 -2
- package/scripts/epic/epic-read.ts +1 -2
- package/scripts/epic/epic-reconcile.ts +1 -1
- package/scripts/epic/epic-reference.ts +1 -13
- package/scripts/epic/epic-relation-recheck.ts +1 -1
- package/scripts/epic/epic-relations.ts +1 -1
- package/scripts/epic/epic-remove.ts +1 -1
- package/scripts/epic/epic-report.ts +0 -1
- package/scripts/epic/epic-run.ts +2 -3
- package/scripts/epic/epic-shape.ts +1 -1
- package/scripts/epic/epic-solo-stale.ts +107 -0
- package/scripts/epic/epic-solo.ts +3 -2
- package/scripts/epic/epic-triage.ts +1 -1
- package/scripts/epic/epic-validate.ts +1 -1
- package/scripts/epic/epic.ts +1 -1
- package/scripts/exports/unused-members-cli.ts +53 -0
- package/scripts/{git → followup}/followup-issue-number.ts +1 -6
- package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
- package/scripts/{git → followup}/git-followup-finish.ts +1 -3
- package/scripts/{git → followup}/git-followup-flush.ts +2 -2
- package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
- package/scripts/{git → followup}/git-followup-label.ts +4 -4
- package/scripts/followup/git-followup-merged.ts +112 -0
- package/scripts/{git → followup}/git-followup-pending.ts +1 -1
- package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
- package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
- package/scripts/{git → followup}/git-pr-followup.ts +53 -16
- package/scripts/gate/core-budget.ts +3 -9
- package/scripts/gate/gate-plan.ts +7 -4
- package/scripts/gate/gate-report.ts +0 -6
- package/scripts/gate/gate-tree.ts +1 -1
- package/scripts/gate/pre-commit-type-check.ts +0 -6
- package/scripts/gate/project-checks.ts +7 -8
- package/scripts/gate/scoped-green.ts +0 -1
- package/scripts/gate/type-check-step.ts +1 -1
- package/scripts/gate/verification-gate.ts +0 -2
- package/scripts/gh/fix-gh-packages.ts +15 -12
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
- package/scripts/{git → gh}/git-gh-check.ts +2 -1
- package/scripts/{git → gh}/git-gh-exec.ts +1 -1
- package/scripts/{git → gh}/git-gh-failure.ts +1 -1
- package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
- package/scripts/{git → gh}/git-gh-issue-list.ts +13 -10
- package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
- package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
- package/scripts/{git → gh}/git-gh-issue-write.ts +4 -1
- package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +4 -1
- package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
- package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
- package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
- package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
- package/scripts/{git → gh}/git-gh-pr.ts +3 -1
- package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
- package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
- package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
- package/scripts/{git → gh}/git-pr-checks.ts +2 -1
- package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
- package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
- package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
- package/scripts/{git → gh}/git-pr.ts +3 -3
- package/scripts/git/changed-file-scope.ts +0 -1
- package/scripts/git/git-branch.ts +3 -6
- package/scripts/git/git-command.ts +6 -1
- package/scripts/git/git-commit.ts +1 -1
- package/scripts/git/git-common-directory.ts +80 -24
- package/scripts/git/git-error.ts +66 -9
- package/scripts/git/git-issue.ts +1 -1
- package/scripts/git/git-preflight.ts +2 -2
- package/scripts/git/git-prompt.ts +6 -31
- package/scripts/git/git-push.ts +1 -1
- package/scripts/git/git-spawn-sync.ts +65 -0
- package/scripts/git/git-spawn.ts +5 -4
- package/scripts/git/git-staging.ts +1 -0
- package/scripts/git/git-status.ts +1 -1
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/gone-branch.ts +1 -0
- package/scripts/git/listing-cutoff.ts +1 -1
- package/scripts/git/main-merge.ts +1 -1
- package/scripts/git/main-sync.ts +19 -1
- package/scripts/git/parse-json-array.ts +0 -3
- package/scripts/git/repository-lock.ts +16 -16
- package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
- package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +2 -7
- package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
- package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
- package/scripts/hooks/codex-hook-adapter.ts +0 -1
- package/scripts/hooks/edited-cspell.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +2 -0
- package/scripts/hooks/pre-push-unit.ts +0 -4
- package/scripts/hooks/pretool-guard.ts +22 -4
- package/scripts/hooks/reserved-run.ts +1 -1
- package/scripts/hooks/step-zero-notice.ts +76 -0
- package/scripts/hooks/stop-guard.ts +47 -21
- package/scripts/init/claude-plugin-config.ts +4 -5
- package/scripts/init/hook-command-rewrite.ts +16 -8
- package/scripts/init/hook-launch.ts +41 -15
- package/scripts/init/init-basic.ts +2 -5
- package/scripts/init/init-file-action.ts +54 -0
- package/scripts/init/init-logic-migrate.ts +35 -17
- package/scripts/init/init-logic-secretlint.ts +1 -1
- package/scripts/init/init-logic.ts +10 -19
- package/scripts/init/init.ts +11 -71
- package/scripts/init/kit-written-paths.ts +2 -0
- package/scripts/init/project-profile.ts +9 -17
- package/scripts/init/start-exec.ts +1 -1
- package/scripts/init/start-setup-pr.ts +6 -6
- package/scripts/init/start-steps.ts +3 -1
- package/scripts/issue/behavior-change-lint.ts +0 -1
- package/scripts/issue/defect-rate-cli.ts +64 -23
- package/scripts/issue/defect-rate.ts +1 -2
- package/scripts/{git → issue}/git-next-issues.ts +3 -3
- package/scripts/issue/issue-backlinks-cli.ts +1 -5
- package/scripts/issue/issue-backlinks.ts +7 -14
- package/scripts/issue/issue-cite-cli.ts +2 -6
- package/scripts/issue/issue-cite.ts +12 -8
- package/scripts/issue/issue-classification.ts +1 -9
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +2 -2
- package/scripts/issue/issue-file-cli.ts +5 -5
- package/scripts/issue/issue-file.ts +7 -14
- package/scripts/issue/issue-fold-cli.ts +1 -1
- package/scripts/issue/issue-fold-existing-cli.ts +1 -1
- package/scripts/{git → issue}/issue-labels.ts +8 -0
- package/scripts/issue/issue-lint-cli.ts +1 -1
- package/scripts/issue/issue-merged.ts +2 -2
- package/scripts/{git → issue}/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +8 -47
- package/scripts/issue/issue-read.ts +0 -2
- package/scripts/issue/issue-report-failures.ts +80 -0
- package/scripts/issue/issue-scout-cli.ts +1 -7
- package/scripts/issue/issue-scout-closed.ts +2 -2
- package/scripts/issue/issue-scout.ts +0 -2
- package/scripts/issue/issue-state-cli.ts +5 -46
- package/scripts/issue/issue-state.ts +1 -5
- package/scripts/issue/markdown-section.ts +21 -6
- package/scripts/issue/measure-rerun-cli.ts +74 -15
- package/scripts/issue/reproduction-measure.ts +1 -1
- package/scripts/josh/cli-body.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +0 -3
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-commands-ai.ts +9 -102
- package/scripts/josh/josh-commands-backlog.ts +5 -1
- package/scripts/josh/josh-commands-development.ts +8 -1
- package/scripts/josh/josh-commands-issue.ts +2 -2
- package/scripts/josh/josh-commands-maintenance.ts +7 -0
- package/scripts/josh/josh-commands-project.ts +7 -1
- package/scripts/josh/josh-commands-run.ts +114 -0
- package/scripts/josh/josh-commands-versioning.ts +8 -0
- package/scripts/josh/josh-commands-workflow.ts +3 -3
- package/scripts/josh/path-decision.ts +0 -3
- package/scripts/josh/process-owner.ts +16 -0
- package/scripts/josh/run-github-prerequisite.ts +3 -6
- package/scripts/josh/session-language-cli.ts +0 -1
- package/scripts/lane/lane-await.ts +46 -19
- package/scripts/lane/lane-capacity.ts +6 -3
- package/scripts/lane/lane-child-invocation.ts +20 -7
- package/scripts/lane/lane-cli.ts +1 -4
- package/scripts/lane/lane-close.ts +5 -4
- package/scripts/lane/lane-dispatch.ts +3 -4
- package/scripts/lane/lane-environment.ts +0 -9
- package/scripts/lane/lane-handoff.ts +38 -0
- package/scripts/lane/lane-launch-cli.ts +31 -27
- package/scripts/lane/lane-open.ts +0 -3
- package/scripts/lane/lane-output.ts +0 -1
- package/scripts/lane/lane-registry.ts +9 -0
- package/scripts/lane/openai-lane-ship.ts +2 -0
- package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
- package/scripts/lane/openai-lane-supervisor.ts +6 -4
- package/scripts/lane/openai-review-broker.ts +7 -1
- package/scripts/lib/bounded-pool.ts +1 -0
- package/scripts/lib/cli-flags.ts +31 -2
- package/scripts/lib/error-message.ts +12 -1
- package/scripts/lib/json-value.ts +5 -4
- package/scripts/lib/poll.ts +3 -1
- package/scripts/lib/timed-fetch.ts +15 -0
- package/scripts/lib/timeouts.ts +13 -0
- package/scripts/{yaml → lib}/yaml-document.ts +3 -1
- package/scripts/{bytes → lines}/bytes-command.ts +0 -2
- package/scripts/lines/line-targets.ts +0 -11
- package/scripts/lines/lines-command.ts +5 -4
- package/scripts/lint/lint-related-scope.ts +0 -1
- package/scripts/lint/lint-related.ts +1 -1
- package/scripts/{git → notify}/telegram-notify.ts +2 -2
- package/scripts/{git → notify}/telegram-test.ts +4 -4
- package/scripts/observations/observation-ledger-home.ts +0 -1
- package/scripts/observations/observation-ledger-line.ts +0 -1
- package/scripts/observations/observation-ledger-migrate.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +3 -3
- package/scripts/observations/observations-flush.ts +2 -2
- package/scripts/overrides/lockfile-overrides.ts +1 -1
- package/scripts/overrides/overrides-logic.ts +1 -1
- package/scripts/package/package-scout-cli.ts +2 -7
- package/scripts/package/package-scout.ts +0 -2
- package/scripts/propagate/propagate-git-failure.ts +0 -1
- package/scripts/propagate/propagate-git.ts +3 -10
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +0 -2
- package/scripts/propagate/propagate-steps.ts +3 -5
- package/scripts/propagate/propagate-targets.ts +0 -4
- package/scripts/propagate/propagate.ts +0 -4
- package/scripts/refactor/import-graph.ts +0 -1
- package/scripts/refactor/refactor-lint.ts +0 -2
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +0 -1
- package/scripts/registry-migration/migrate-logic.ts +28 -21
- package/scripts/registry-migration/migrate.ts +25 -14
- package/scripts/release/github-release-cli.ts +19 -6
- package/scripts/release/github-release-environment.ts +46 -0
- package/scripts/release/github-release.ts +151 -94
- package/scripts/release/release-history.ts +0 -1
- package/scripts/release/release-plan.ts +0 -1
- package/scripts/release/release-publish.ts +38 -5
- package/scripts/release/release-scope-cli.ts +1 -2
- package/scripts/release/release-tag.ts +2 -4
- package/scripts/release/release-worktree.ts +97 -2
- package/scripts/repo/auto-merge-setting-logic.ts +1 -4
- package/scripts/repo/repo-setting.ts +1 -1
- package/scripts/repo/repository-labels.ts +3 -3
- package/scripts/repo/required-checks-logic.ts +206 -0
- package/scripts/repo/required-checks-report.ts +71 -0
- package/scripts/repo/ruleset-check-cli.ts +53 -0
- package/scripts/repo/ruleset-check.ts +147 -0
- package/scripts/report/report-lint-cli.ts +0 -4
- package/scripts/review/disposition-cli.ts +1 -1
- package/scripts/review/live-evidence.ts +1 -1
- package/scripts/review/review-attest-cli.ts +0 -6
- package/scripts/review/review-attest.ts +4 -16
- package/scripts/review/review-brief-cli.ts +23 -6
- package/scripts/review/review-brief.ts +21 -8
- package/scripts/review/review-checkout.ts +3 -2
- package/scripts/review/review-diff-parts.ts +89 -0
- package/scripts/review/review-diff-write.ts +97 -0
- package/scripts/review/review-finding-ledger.ts +0 -1
- package/scripts/review/review-record-cli.ts +10 -17
- package/scripts/review/review-record.ts +0 -1
- package/scripts/review/review-round2-cli.ts +1 -1
- package/scripts/review/review-stamps.ts +0 -3
- package/scripts/review/review-tree.ts +14 -2
- package/scripts/rules/decision-oracle-stage.ts +18 -0
- package/scripts/rules/decision-oracle.ts +10 -7
- package/scripts/rules/delivered-rules.ts +9 -1
- package/scripts/rules/destructive-command.ts +119 -0
- package/scripts/rules/direct-filing.ts +1 -1
- package/scripts/rules/early-heartbeat.ts +4 -3
- package/scripts/rules/file-body.ts +0 -3
- package/scripts/rules/filing-cap.ts +0 -2
- package/scripts/rules/gh-api.ts +7 -2
- package/scripts/rules/git-argv.ts +18 -7
- package/scripts/rules/git-force.ts +0 -2
- package/scripts/rules/implementation-cut.ts +0 -1
- package/scripts/rules/index-guard.ts +71 -0
- package/scripts/rules/issue-citation.ts +50 -25
- package/scripts/rules/lane-background.ts +15 -7
- package/scripts/rules/lane-park.ts +22 -6
- package/scripts/rules/last-prompt.ts +1 -0
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/oracle-list-cli.ts +0 -3
- package/scripts/rules/permission-guards.ts +14 -0
- package/scripts/rules/protected-files.ts +74 -0
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +0 -3
- package/scripts/rules/rule-value-cli.ts +0 -1
- package/scripts/rules/shell-body-trigger.ts +0 -1
- package/scripts/rules/shell-segments.ts +0 -1
- package/scripts/rules/stop-rules.ts +20 -9
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +0 -1
- package/scripts/rules/worktree-guard.ts +26 -9
- package/scripts/run/run-carry-args.ts +8 -12
- package/scripts/run/run-carry-cli.ts +0 -2
- package/scripts/run/run-carry-stash.ts +2 -2
- package/scripts/run/run-carry-streak.ts +1 -1
- package/scripts/run/run-cut-args.ts +1 -6
- package/scripts/run/run-cut-cli.ts +0 -7
- package/scripts/run/run-cut.ts +8 -54
- package/scripts/run/run-ending-cli.ts +2 -6
- package/scripts/run/run-ending.ts +1 -4
- package/scripts/run/run-entry-cli.ts +133 -25
- package/scripts/run/run-entry-stop.ts +104 -0
- package/scripts/run/run-entry.ts +0 -1
- package/scripts/run/run-event-cli.ts +0 -2
- package/scripts/run/run-event-follow.ts +1 -0
- package/scripts/run/run-event-render.ts +1 -1
- package/scripts/run/run-event-scope.ts +53 -4
- package/scripts/run/run-event-stream-emit.ts +7 -2
- package/scripts/run/run-event-stream.ts +0 -3
- package/scripts/run/run-event-watch.ts +1 -0
- package/scripts/run/run-halfrun-resume.ts +20 -7
- package/scripts/run/run-headless.ts +2 -2
- package/scripts/run/run-hold-cli.ts +33 -10
- package/scripts/run/run-hold.ts +29 -6
- package/scripts/run/run-issue-number.ts +1 -1
- package/scripts/run/run-liveness-cli.ts +2 -6
- package/scripts/run/run-liveness.ts +2 -3
- package/scripts/run/run-merge-cli.ts +7 -23
- package/scripts/run/run-merge-steps.ts +5 -5
- package/scripts/run/run-merge.ts +1 -1
- package/scripts/run/run-next-cli.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +4 -2
- package/scripts/run/run-preflight.ts +2 -9
- package/scripts/run/run-prep-cli.ts +6 -3
- package/scripts/run/run-prep-locate.ts +1 -1
- package/scripts/run/run-progress-args.ts +20 -4
- package/scripts/run/run-progress-cli.ts +35 -36
- package/scripts/run/run-progress-clock.ts +10 -35
- package/scripts/run/run-progress-config.ts +0 -4
- package/scripts/run/run-progress-read.ts +1 -2
- package/scripts/run/run-progress.ts +1 -2
- package/scripts/run/run-prrun-resume.ts +117 -0
- package/scripts/run/run-report-cli.ts +1 -2
- package/scripts/run/run-report.ts +0 -1
- package/scripts/run/run-retrospective.ts +1 -1
- package/scripts/run/run-review-cli.ts +0 -3
- package/scripts/run/run-review-steps.ts +2 -0
- package/scripts/run/run-review.ts +0 -2
- package/scripts/run/run-ship-cli.ts +29 -19
- package/scripts/run/run-ship-detach.ts +1 -0
- package/scripts/run/run-ship-next.ts +106 -0
- package/scripts/run/run-ship-preflight.ts +1 -1
- package/scripts/run/run-ship-probe.ts +4 -1
- package/scripts/run/run-ship-return.ts +8 -3
- package/scripts/run/run-ship-review-steps.ts +18 -4
- package/scripts/run/run-ship-review.ts +11 -0
- package/scripts/run/run-ship-scoped.ts +1 -0
- package/scripts/run/run-ship-steps.ts +1 -1
- package/scripts/run/run-ship.ts +0 -1
- package/scripts/run/run-stage-read.ts +62 -0
- package/scripts/run/run-stage.ts +160 -0
- package/scripts/run/run-status-cli.ts +3 -16
- package/scripts/run/run-step-cli.ts +21 -14
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stop-notify.ts +1 -3
- package/scripts/run/run-stranded-cli.ts +0 -4
- package/scripts/run/run-stranded-detect.ts +2 -2
- package/scripts/run/run-tail-cli.ts +17 -11
- package/scripts/run/run-tail.ts +2 -0
- package/scripts/run/run-tidy-lanes.ts +6 -2
- package/scripts/run/run-tidy-stashes.ts +12 -12
- package/scripts/run/run-wake-cli.ts +4 -13
- package/scripts/run/run-wake-loop.ts +2 -2
- package/scripts/run/run-wake.ts +2 -4
- package/scripts/run/run-watcher-guard-cli.ts +0 -4
- package/scripts/run/run-watcher-guard.ts +18 -12
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/safe-chain/ci-installer-pin.ts +11 -5
- package/scripts/safe-chain/pack-hook.ts +92 -0
- package/scripts/safe-chain/project-config.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +0 -1
- package/scripts/security/security-audit-provision.ts +3 -2
- package/scripts/security/security-audit.ts +0 -1
- package/scripts/security/security-updates-logic.ts +0 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
- package/scripts/sonar/sonar-hotspots.ts +0 -1
- package/scripts/sonar/sonar-new-code-cli.ts +150 -0
- package/scripts/sonar/sonar-new-code.ts +79 -0
- package/scripts/sonar/sonar-project.ts +97 -0
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +2 -5
- package/scripts/sync/managed-config-scope-cli.ts +1 -1
- package/scripts/sync/skill-migration.ts +0 -1
- package/scripts/sync/sync-ai-files.ts +4 -0
- package/scripts/sync/sync-hook-safety.ts +2 -3
- package/scripts/sync/sync.ts +1 -8
- package/scripts/sync/template-source-logic.ts +0 -1
- package/scripts/sync/workflow-pin-logic.ts +16 -28
- package/scripts/test/test-declared-changed.ts +13 -16
- package/scripts/test/test-declared-logic.ts +0 -1
- package/scripts/test/test-declared.ts +3 -9
- package/scripts/test/test-red-commit.ts +2 -2
- package/scripts/test/test-red.ts +14 -7
- package/scripts/test/test-type-logic.ts +1 -1
- package/scripts/test/unit-worker-share.ts +7 -16
- package/scripts/time-runtime/time-batch-guard.ts +1 -2
- package/scripts/time-runtime/time-bundle-call.ts +0 -1
- package/scripts/time-runtime/time-bundles.ts +0 -4
- package/scripts/time-runtime/time-density-hook.ts +0 -2
- package/scripts/time-runtime/time-followup-stage.ts +1 -1
- package/scripts/time-runtime/time-format.ts +0 -73
- package/scripts/time-runtime/time-round-trips.ts +0 -4
- package/scripts/time-runtime/time-single-check.ts +1 -1
- package/scripts/time-runtime/time-spans.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +1 -2
- package/scripts/ui/ui-routes-cli.ts +0 -5
- package/scripts/ui/ui-routes.ts +0 -5
- package/scripts/version/effective-upstream.ts +2 -2
- package/scripts/version/latest-corepack.ts +7 -9
- package/scripts/version/latest-scope-cli.ts +0 -2
- package/scripts/version/latest-update.ts +0 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/publishable-range-check.ts +1 -1
- package/scripts/version/release-hold.ts +0 -4
- package/scripts/version/running-binary.ts +2 -2
- package/scripts/version/version-check-logic.ts +0 -2
- package/scripts/version/version-commands.ts +11 -1
- package/scripts/version/version-remote.ts +3 -3
- package/scripts/version/version-targets.ts +4 -4
- package/templates/CLAUDE.basic.md +6 -6
- package/templates/sonar-project.properties +28 -1
- package/templates/workflows/ci.yml +16 -82
- package/templates/workflows/dependabot-auto-merge.yml +6 -3
- package/templates/workflows/github-release.yml +79 -0
- package/tsconfig.sonar.json +4 -22
- package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
- package/prompts/collaboration-workflow/epic-audit.md +0 -5
- package/prompts/collaboration-workflow/epic-bundle.md +0 -5
- package/scripts/init/plugin-install-hint.ts +0 -47
- package/scripts/version/parse-json.ts +0 -13
- /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
- /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
- /package/scripts/{git → gh}/git-gh-command.ts +0 -0
- /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
- /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
- /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
- /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
- /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
- /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
- /package/scripts/{git → gh}/git-pr-error.ts +0 -0
- /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
- /package/scripts/{git → gh}/github-issue-url.ts +0 -0
- /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
- /package/scripts/{git → issue}/issue-reference.ts +0 -0
- /package/scripts/{git → lib}/animation-helpers.ts +0 -0
- /package/scripts/{git → lib}/git-animation.ts +0 -0
- /package/scripts/{git → notify}/git-notify.ts +0 -0
- /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
|
@@ -1,18 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
2
|
+
import { git_gh_helpers } from '#scripts/gh/git-gh-helpers'
|
|
3
|
+
import { git_pr_ai_review, type TelegramContext } from '#scripts/gh/git-pr-ai-review'
|
|
4
|
+
import {
|
|
5
|
+
DEFAULT_STABLE_READS,
|
|
6
|
+
git_pr_checks,
|
|
7
|
+
WATCH_CONFIRMED_STABLE_READS,
|
|
8
|
+
} from '#scripts/gh/git-pr-checks'
|
|
9
|
+
import { is_coderabbit_check } from '#scripts/gh/git-pr-checks-eval'
|
|
10
|
+
import { CHECK_STATUS_PASS, type PrStateSnapshot } from '#scripts/gh/git-pr-checks-parse'
|
|
11
|
+
import { git_pr_coderabbit } from '#scripts/gh/git-pr-coderabbit'
|
|
12
|
+
import { git_pr_managed_config } from '#scripts/gh/git-pr-managed-config'
|
|
13
|
+
import { github_issue_url } from '#scripts/gh/github-issue-url'
|
|
14
|
+
import { git_closes_keyword } from '#scripts/git/git-closes-keyword'
|
|
15
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
16
|
+
import type { GitNotifyConfig } from '#scripts/notify/git-notify'
|
|
17
|
+
import {
|
|
18
|
+
telegram_notify,
|
|
19
|
+
type TelegramSendInput,
|
|
20
|
+
type TelegramTaskType,
|
|
21
|
+
} from '#scripts/notify/telegram-notify'
|
|
22
|
+
import { git_followup_merged } from './git-followup-merged'
|
|
2
23
|
import { git_followup_pending } from './git-followup-pending'
|
|
3
24
|
import { git_followup_stages, type StageLog } from './git-followup-stages'
|
|
4
|
-
import { git_gh_command } from './git-gh-command'
|
|
5
|
-
import { git_gh_helpers } from './git-gh-helpers'
|
|
6
|
-
import type { GitNotifyConfig } from './git-notify'
|
|
7
|
-
import { git_pr_ai_review, type TelegramContext } from './git-pr-ai-review'
|
|
8
|
-
import { DEFAULT_STABLE_READS, git_pr_checks, WATCH_CONFIRMED_STABLE_READS } from './git-pr-checks'
|
|
9
|
-
import { is_coderabbit_check } from './git-pr-checks-eval'
|
|
10
|
-
import { CHECK_STATUS_PASS, git_pr_checks_parse, type PrStateSnapshot } from './git-pr-checks-parse'
|
|
11
|
-
import { git_pr_coderabbit } from './git-pr-coderabbit'
|
|
12
25
|
import { git_pr_followup_wrapup } from './git-pr-followup-wrapup'
|
|
13
|
-
import { git_pr_managed_config } from './git-pr-managed-config'
|
|
14
|
-
import { github_issue_url } from './github-issue-url'
|
|
15
|
-
import { telegram_notify, type TelegramSendInput, type TelegramTaskType } from './telegram-notify'
|
|
16
26
|
|
|
17
27
|
const { STAGE, lap } = git_followup_stages
|
|
18
28
|
|
|
@@ -64,6 +74,10 @@ interface FollowupInput {
|
|
|
64
74
|
ai_review_ignore_reason: string | undefined
|
|
65
75
|
is_skip_watch: boolean
|
|
66
76
|
should_merge: boolean
|
|
77
|
+
// The pull request merged before this run (joshuafolkken/kit#3023): only the tail is left to run.
|
|
78
|
+
is_merged?: boolean | undefined
|
|
79
|
+
// When it merged — a completion report posted before it is the `prrun` stop's, not this tail's.
|
|
80
|
+
merged_at?: string | undefined
|
|
67
81
|
}
|
|
68
82
|
|
|
69
83
|
const { parse_closes_issue_number } = git_closes_keyword
|
|
@@ -116,7 +130,7 @@ async function warn_if_missing_closes(branch_name: string): Promise<string | und
|
|
|
116
130
|
// on the path this whole change exists to remove. So the question asked here is the narrow one —
|
|
117
131
|
// *is this definitely an empty rollup* — and every other outcome falls through.
|
|
118
132
|
function reads_as_empty_rollup(raw_json: string): boolean {
|
|
119
|
-
const parsed =
|
|
133
|
+
const parsed = json_value.parse_or_undefined(raw_json)
|
|
120
134
|
|
|
121
135
|
if (typeof parsed !== 'object' || parsed === null || !('statusCheckRollup' in parsed)) {
|
|
122
136
|
return false
|
|
@@ -342,6 +356,8 @@ async function run_review_checks(
|
|
|
342
356
|
context: TelegramContext,
|
|
343
357
|
log: StageLog,
|
|
344
358
|
): Promise<{ notes: Array<string>; managed: Array<string> }> {
|
|
359
|
+
if (input.is_merged === true) return { notes: [], managed: [] }
|
|
360
|
+
|
|
345
361
|
const managed = await git_pr_managed_config.handle_managed_config_changes({
|
|
346
362
|
should_merge: input.should_merge,
|
|
347
363
|
})
|
|
@@ -359,6 +375,26 @@ async function run_review_checks(
|
|
|
359
375
|
return { notes: [...managed, ...check_notes, ...scan_notes], managed }
|
|
360
376
|
}
|
|
361
377
|
|
|
378
|
+
// **A tail re-run after a merge does not report twice** (joshuafolkken/kit#3023): where the issue
|
|
379
|
+
// already carries this pull request's completion report, the Telegram is skipped here and the comment
|
|
380
|
+
// in the wrapup. Answers whether it was recorded, so the wrapup skips on the same read.
|
|
381
|
+
async function notify_unless_recorded(
|
|
382
|
+
input: FollowupInput,
|
|
383
|
+
issue_number: string | undefined,
|
|
384
|
+
context: TelegramContext,
|
|
385
|
+
checks: { notes: Array<string> },
|
|
386
|
+
): Promise<boolean> {
|
|
387
|
+
const is_recorded = await git_followup_merged.is_completion_recorded({
|
|
388
|
+
merged_at: input.is_merged === true ? input.merged_at : undefined,
|
|
389
|
+
issue_number,
|
|
390
|
+
pr_url: context.pr_url,
|
|
391
|
+
})
|
|
392
|
+
|
|
393
|
+
if (!is_recorded) await notify_completion(context, checks.notes, input.should_merge)
|
|
394
|
+
|
|
395
|
+
return is_recorded
|
|
396
|
+
}
|
|
397
|
+
|
|
362
398
|
// **Answers with the issue number the run actually used** (joshuafolkken/kit#1539), which is the one
|
|
363
399
|
// the invocation named or, failing that, the one the pull request body closes. Everything downstream
|
|
364
400
|
// takes it from here rather than from the input, so the Telegram context, the completion comment and
|
|
@@ -369,8 +405,7 @@ async function run_stages(input: FollowupInput, log: StageLog): Promise<string |
|
|
|
369
405
|
|
|
370
406
|
lap(log, STAGE.closes_and_context)
|
|
371
407
|
const checks = await run_review_checks(input, context, log)
|
|
372
|
-
|
|
373
|
-
await notify_completion(context, checks.notes, input.should_merge)
|
|
408
|
+
const is_completion_recorded = await notify_unless_recorded(input, issue_number, context, checks)
|
|
374
409
|
|
|
375
410
|
lap(log, STAGE.telegram)
|
|
376
411
|
await git_pr_followup_wrapup.run_wrapup(
|
|
@@ -382,6 +417,8 @@ async function run_stages(input: FollowupInput, log: StageLog): Promise<string |
|
|
|
382
417
|
pr_url: context.pr_url,
|
|
383
418
|
should_merge: input.should_merge,
|
|
384
419
|
managed_notes: checks.managed,
|
|
420
|
+
is_merged: input.is_merged,
|
|
421
|
+
is_completion_recorded,
|
|
385
422
|
},
|
|
386
423
|
log,
|
|
387
424
|
)
|
|
@@ -426,4 +463,4 @@ export {
|
|
|
426
463
|
log_skip_notes,
|
|
427
464
|
}
|
|
428
465
|
export type { FollowupInput }
|
|
429
|
-
export type { TelegramContext } from '
|
|
466
|
+
export type { TelegramContext } from '#scripts/gh/git-pr-ai-review'
|
|
@@ -4,6 +4,7 @@ import { availableParallelism } from 'node:os'
|
|
|
4
4
|
import path from 'node:path'
|
|
5
5
|
import { PLATFORM_TEMP_ROOT } from '#scripts/josh/platform-temporary'
|
|
6
6
|
import { process_identity } from '#scripts/josh/process-identity'
|
|
7
|
+
import { process_owner_schema } from '#scripts/josh/process-owner'
|
|
7
8
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
8
9
|
import { z } from 'zod'
|
|
9
10
|
|
|
@@ -45,9 +46,7 @@ const WAIT_CAP_MS = 120_000
|
|
|
45
46
|
// The head of the ledger is always admitted, so the smallest budget worth planning against is one core.
|
|
46
47
|
const MIN_BUDGET = 1
|
|
47
48
|
|
|
48
|
-
const reservation_schema =
|
|
49
|
-
pid: z.number(),
|
|
50
|
-
process_start: z.string().optional(),
|
|
49
|
+
const reservation_schema = process_owner_schema.extend({
|
|
51
50
|
weight: z.number(),
|
|
52
51
|
claimed_at: z.number(),
|
|
53
52
|
})
|
|
@@ -228,6 +227,7 @@ async function await_admission(context: WaitContext): Promise<void> {
|
|
|
228
227
|
while (!is_admitted(context.key, live_reservations(context.directory), context.budget)) {
|
|
229
228
|
if (context.now() >= context.deadline) return
|
|
230
229
|
|
|
230
|
+
// eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
|
|
231
231
|
await context.sleep(context.poll_interval_ms)
|
|
232
232
|
}
|
|
233
233
|
}
|
|
@@ -273,16 +273,10 @@ async function with_core_reservation<T>(
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
const core_budget = {
|
|
276
|
-
MIN_BUDGET,
|
|
277
|
-
POLL_INTERVAL_MS,
|
|
278
276
|
RESERVED_PREFIX,
|
|
279
|
-
WAIT_CAP_MS,
|
|
280
277
|
admitted_keys,
|
|
281
278
|
admitted_load,
|
|
282
|
-
is_admitted,
|
|
283
|
-
is_running,
|
|
284
279
|
live_reservations,
|
|
285
|
-
read_reservation,
|
|
286
280
|
release,
|
|
287
281
|
reserve,
|
|
288
282
|
with_core_reservation,
|
|
@@ -66,6 +66,11 @@ const STATIC_CHECKS: ReadonlyArray<GateCheck> = [
|
|
|
66
66
|
{ label: TYPE_CHECK_LABEL, target: 'check', reserved_cores: 1 },
|
|
67
67
|
{ label: 'cspell', target: 'cspell:dot', reserved_cores: 1 },
|
|
68
68
|
{ label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
|
|
69
|
+
// **The unused-member check reserves no core** (joshuafolkken/kit#2987): it builds one TypeScript
|
|
70
|
+
// program and walks it single-threaded for about 5s — over well before lint and the type check, so
|
|
71
|
+
// a reservation would only take a place from the four-core CI runner's fan-out and a worker from
|
|
72
|
+
// the unit suite for the whole gate.
|
|
73
|
+
{ label: 'exports', target: 'exports:unused', reserved_cores: 0 },
|
|
69
74
|
]
|
|
70
75
|
|
|
71
76
|
// The checks, in the order their output is printed — the static set, then the unit suite last (the
|
|
@@ -91,8 +96,8 @@ function has_unit_check(checks: ReadonlyArray<GateCheck>): boolean {
|
|
|
91
96
|
return checks.some((check) => check.label === UNIT_LABEL)
|
|
92
97
|
}
|
|
93
98
|
|
|
94
|
-
// What the
|
|
95
|
-
// rather than over
|
|
99
|
+
// What the non-elastic checks hold between them: 2 + 1 + 1. Reduced over `STATIC_CHECKS`
|
|
100
|
+
// rather than over every check, because that is the set the sentence above names: `resolve_unit_worker_cap`
|
|
96
101
|
// spends this as the cores the unit suite must leave to its siblings, so summing the unit check into
|
|
97
102
|
// it would have the suite subtract its own reservation from its own budget the day that reservation
|
|
98
103
|
// stops being zero. The two sets give the same number today, which is exactly why the narrower one
|
|
@@ -331,7 +336,6 @@ function format_gate_plan(
|
|
|
331
336
|
}
|
|
332
337
|
|
|
333
338
|
const gate_plan = {
|
|
334
|
-
BEHAVIOR_LABEL,
|
|
335
339
|
GATE_CHECKS,
|
|
336
340
|
LINT_LABEL,
|
|
337
341
|
MEASURED_CORES,
|
|
@@ -343,7 +347,6 @@ const gate_plan = {
|
|
|
343
347
|
check_weight,
|
|
344
348
|
format_gate_plan,
|
|
345
349
|
format_machine,
|
|
346
|
-
format_unit_cap,
|
|
347
350
|
has_unit_check,
|
|
348
351
|
plan_of,
|
|
349
352
|
resolve_concurrency,
|
|
@@ -193,16 +193,10 @@ function report_gate_steps(
|
|
|
193
193
|
|
|
194
194
|
const gate_report = {
|
|
195
195
|
format_failure_actions,
|
|
196
|
-
format_seconds,
|
|
197
|
-
gate_step_header,
|
|
198
196
|
has_checker_warning,
|
|
199
|
-
has_warnings,
|
|
200
197
|
is_gate_step_failed,
|
|
201
198
|
is_skip_notice,
|
|
202
|
-
print_gate_step,
|
|
203
|
-
print_gate_summary,
|
|
204
199
|
report_gate_steps,
|
|
205
|
-
should_print_body,
|
|
206
200
|
}
|
|
207
201
|
|
|
208
202
|
export type { GateReport, GateStep, GateStepResult }
|
|
@@ -174,13 +174,7 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
|
174
174
|
const pre_commit_type_check = {
|
|
175
175
|
FORCE_ENV,
|
|
176
176
|
TYPE_CHECK_ARGUMENTS,
|
|
177
|
-
format_refusal,
|
|
178
|
-
format_skip,
|
|
179
|
-
is_recorded_check_this_check,
|
|
180
|
-
read_commit_tree,
|
|
181
|
-
reusable_green_commit,
|
|
182
177
|
run_pre_commit_type_check,
|
|
183
|
-
unexpected_arguments,
|
|
184
178
|
}
|
|
185
179
|
|
|
186
180
|
export type { CommitTree }
|
|
@@ -2,6 +2,7 @@ import { existsSync, globSync, readFileSync } from 'node:fs'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { find_local_bin_upwards } from '#scripts/build/local-bin'
|
|
4
4
|
import { project_profile } from '#scripts/init/project-profile'
|
|
5
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
5
6
|
import { SKIP_MARKER } from '#scripts/test/skip-marker'
|
|
6
7
|
import { z } from 'zod'
|
|
7
8
|
|
|
@@ -70,23 +71,23 @@ function has_bin(directory: string, bin_name: string): boolean {
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
function josh_settings(manifest: unknown): unknown {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return manifest.josh
|
|
74
|
+
return json_value.is_record(manifest) ? manifest['josh'] : undefined
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
function is_basic_manifest(manifest: unknown): boolean {
|
|
79
78
|
const josh = josh_settings(manifest)
|
|
80
|
-
if (
|
|
79
|
+
if (!json_value.is_record(josh)) return false
|
|
81
80
|
|
|
82
|
-
return project_profile.parse_profile(josh
|
|
81
|
+
return project_profile.parse_profile(josh['profile']) === 'basic'
|
|
83
82
|
}
|
|
84
83
|
|
|
84
|
+
// The try covers the read alone — a missing or unreadable manifest — since the parse already answers
|
|
85
|
+
// `undefined` for text that is not JSON.
|
|
85
86
|
function read_manifest(directory: string): unknown {
|
|
86
87
|
try {
|
|
87
88
|
const manifest_path = path.join(project_root(directory), PACKAGE_JSON)
|
|
88
89
|
|
|
89
|
-
return
|
|
90
|
+
return json_value.parse_or_undefined(readFileSync(manifest_path, 'utf8'))
|
|
90
91
|
} catch {
|
|
91
92
|
return undefined
|
|
92
93
|
}
|
|
@@ -158,8 +159,6 @@ function eslint_skip_reason(directory: string): string | undefined {
|
|
|
158
159
|
const project_checks = {
|
|
159
160
|
CSPELL_CONFIGS,
|
|
160
161
|
ESLINT_CONFIGS,
|
|
161
|
-
SCRIPT_FILES,
|
|
162
|
-
TYPE_CONFIGS,
|
|
163
162
|
TYPE_FILES,
|
|
164
163
|
WEB_FILES,
|
|
165
164
|
eslint_skip_reason,
|
|
@@ -74,6 +74,7 @@ async function resolve_toolkit_step(
|
|
|
74
74
|
// The command the gate spawns through `pnpm`, so a toolkit step resolves the same shim `pnpm` would.
|
|
75
75
|
async function resolve_type_check_args(start_directory: string): Promise<ReadonlyArray<string>> {
|
|
76
76
|
for (const bin_name of TOOLKIT_BINS) {
|
|
77
|
+
// eslint-disable-next-line no-await-in-loop -- the first toolkit bin that resolves wins
|
|
77
78
|
const step = await resolve_toolkit_step(start_directory, bin_name)
|
|
78
79
|
if (step !== undefined) return step
|
|
79
80
|
}
|
|
@@ -83,7 +84,6 @@ async function resolve_type_check_args(start_directory: string): Promise<Readonl
|
|
|
83
84
|
|
|
84
85
|
const type_check_step = {
|
|
85
86
|
parse_usage_commands,
|
|
86
|
-
resolve_toolkit_step,
|
|
87
87
|
resolve_type_check_args,
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -488,10 +488,8 @@ const verification_gate = {
|
|
|
488
488
|
mark_gate_running,
|
|
489
489
|
record_green_gate,
|
|
490
490
|
run_gate_steps,
|
|
491
|
-
run_marked_gate,
|
|
492
491
|
scoped_precheck_refusal,
|
|
493
492
|
with_gate_marker,
|
|
494
|
-
run_checked_gate,
|
|
495
493
|
run_gate_command,
|
|
496
494
|
run_gate_step,
|
|
497
495
|
run_verification_gate,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { existsSync, readFileSync, realpathSync, writeFileSync } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
4
5
|
import { file_reader } from '#scripts/lib/read-file'
|
|
6
|
+
import { timed_fetch } from '#scripts/lib/timed-fetch'
|
|
5
7
|
import { z } from 'zod'
|
|
6
8
|
import { fix_gh_packages_logic, type LockfilePackage } from './fix-gh-packages-logic'
|
|
7
9
|
import { gh_cli_token } from './gh-cli-token'
|
|
@@ -9,7 +11,8 @@ import { gh_cli_token } from './gh-cli-token'
|
|
|
9
11
|
const LOCKFILE = 'pnpm-lock.yaml'
|
|
10
12
|
const NPMRC = '.npmrc'
|
|
11
13
|
const GH_PACKAGES_HOST = 'npm.pkg.github.com'
|
|
12
|
-
|
|
14
|
+
// The packument reads are independent; the width keeps a large lockfile from bursting the registry.
|
|
15
|
+
const FETCH_CONCURRENCY = 8
|
|
13
16
|
|
|
14
17
|
const npm_distribution_schema = z.looseObject({ tarball: z.string().optional() })
|
|
15
18
|
const npm_version_schema = z.looseObject({ dist: npm_distribution_schema.optional() })
|
|
@@ -42,10 +45,7 @@ async function fetch_tarball_url(
|
|
|
42
45
|
token: string,
|
|
43
46
|
): Promise<string | undefined> {
|
|
44
47
|
const url = `https://${GH_PACKAGES_HOST}/${package_path}`
|
|
45
|
-
const response = await
|
|
46
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
47
|
-
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
48
|
-
})
|
|
48
|
+
const response = await timed_fetch(url, { headers: { Authorization: `Bearer ${token}` } })
|
|
49
49
|
|
|
50
50
|
if (!response.ok) {
|
|
51
51
|
console.warn(`fix-gh-packages: fetch failed for ${package_path} (${String(response.status)})`)
|
|
@@ -79,14 +79,13 @@ async function collect_fixes(
|
|
|
79
79
|
scopes: Set<string>,
|
|
80
80
|
token: string,
|
|
81
81
|
): Promise<Map<string, string>> {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
82
|
+
const pairs = await bounded_pool.bounded_map(
|
|
83
|
+
Object.entries(packages),
|
|
84
|
+
FETCH_CONCURRENCY,
|
|
85
|
+
async ([key, entry]) => await process_package_entry(key, entry, scopes, token),
|
|
86
|
+
)
|
|
88
87
|
|
|
89
|
-
return
|
|
88
|
+
return new Map(pairs.filter((pair) => pair !== undefined))
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
async function apply_fixes(cwd: string, scopes: Set<string>, token: string): Promise<void> {
|
|
@@ -128,3 +127,7 @@ async function main(): Promise<void> {
|
|
|
128
127
|
|
|
129
128
|
const [, argv1] = process.argv
|
|
130
129
|
if (argv1 !== undefined && realpathSync(argv1) === fileURLToPath(import.meta.url)) await main()
|
|
130
|
+
|
|
131
|
+
const fix_gh_packages = { collect_fixes }
|
|
132
|
+
|
|
133
|
+
export { fix_gh_packages }
|
package/scripts/gh/gh-spawn.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { git_gh_api_path } from '#scripts/git/git-gh-api-path'
|
|
2
|
-
import { git_gh_exec } from '#scripts/git/git-gh-exec'
|
|
3
1
|
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
2
|
+
import { git_gh_api_path } from './git-gh-api-path'
|
|
3
|
+
import { git_gh_exec } from './git-gh-exec'
|
|
4
4
|
|
|
5
5
|
// The synchronous twin of `git_gh_repo.repo_get_name_with_owner`: same fact, read the same way, but
|
|
6
6
|
// synchronously because `josh init` / `josh sync` / `josh doctor` decide before they can await.
|
|
@@ -146,9 +146,5 @@ function classify_ai_review_comments(comments: ReadonlyArray<ReviewComment>): Cl
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
|
|
150
|
-
classify_ai_review_comments,
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export { git_ai_review_scan, classify_ai_review_comments }
|
|
149
|
+
export { classify_ai_review_comments }
|
|
154
150
|
export type { ReviewComment, ClassifiedFinding, ClassifiedFindings, FindingKind }
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { COMMAND_TIMEOUT_MS } from '#scripts/lib/timeouts'
|
|
1
2
|
import { execa } from 'execa'
|
|
2
3
|
|
|
3
4
|
const GH_NOT_INSTALLED_MSG = 'gh CLI is not installed. Install it from https://cli.github.com/'
|
|
@@ -6,7 +7,7 @@ const gh_check: { promise?: Promise<void> } = {}
|
|
|
6
7
|
|
|
7
8
|
async function run_gh_check(): Promise<void> {
|
|
8
9
|
try {
|
|
9
|
-
await execa('gh', ['--version'])
|
|
10
|
+
await execa('gh', ['--version'], { timeout: COMMAND_TIMEOUT_MS })
|
|
10
11
|
} catch {
|
|
11
12
|
delete gh_check.promise
|
|
12
13
|
throw new Error(GH_NOT_INSTALLED_MSG)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { has_timed_out } from '#scripts/git/git-execa-error'
|
|
1
2
|
import { agent_session_environment } from '#scripts/josh/agent-session-environment'
|
|
2
3
|
import { error_text } from '#scripts/lib/error-message'
|
|
3
4
|
import { execa, execaSync } from 'execa'
|
|
4
|
-
import { has_timed_out } from './git-execa-error'
|
|
5
5
|
import { check_gh_installed } from './git-gh-check'
|
|
6
6
|
import { gh_failure } from './git-gh-failure'
|
|
7
7
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
1
2
|
import { git_gh_api_path } from './git-gh-api-path'
|
|
2
3
|
import { git_gh_exec } from './git-gh-exec'
|
|
3
4
|
import { read_blocked_by } from './git-gh-issue-read'
|
|
@@ -178,6 +179,7 @@ async function fetch_selected(request: IssueListRequest): Promise<SelectedRows>
|
|
|
178
179
|
let has_more = true
|
|
179
180
|
|
|
180
181
|
while (page <= MAX_PAGES && wants_more(has_more, selected.length, request.limit)) {
|
|
182
|
+
// eslint-disable-next-line no-await-in-loop -- paging stops as soon as enough rows are selected
|
|
181
183
|
const result = await fetch_page(request, page)
|
|
182
184
|
|
|
183
185
|
selected.push(...result.selected)
|
|
@@ -197,20 +199,21 @@ async function fetch_selected(request: IssueListRequest): Promise<SelectedRows>
|
|
|
197
199
|
// issue GitHub itself reports as unblocked costs no request. A backlog with no declared blockers
|
|
198
200
|
// therefore costs exactly what `gh` cost — one listing — rather than one request per row.
|
|
199
201
|
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
//
|
|
202
|
+
// Bounded rather than sequential (joshuafolkken/kit#3103): the pass was paced one request at a time,
|
|
203
|
+
// which made every `backlog:plan` wait about 0.7 s per opted-in issue declaring a blocker. The width
|
|
204
|
+
// is the one `epic:bundle` already reads the same endpoint at, so the burst stays bounded while a
|
|
205
|
+
// rate-limited read still fails the whole listing rather than a row (`bounded-pool.ts`).
|
|
206
|
+
const RELATION_CONCURRENCY = 8
|
|
207
|
+
|
|
203
208
|
async function read_relations(
|
|
204
209
|
rows: ReadonlyArray<RestIssue>,
|
|
205
210
|
repo?: string,
|
|
206
211
|
): Promise<Array<BlockedBy>> {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return relations
|
|
212
|
+
return await bounded_pool.bounded_map(
|
|
213
|
+
rows,
|
|
214
|
+
RELATION_CONCURRENCY,
|
|
215
|
+
async (row) => await read_blocked_by(String(row.number), row, repo),
|
|
216
|
+
)
|
|
214
217
|
}
|
|
215
218
|
|
|
216
219
|
// The listing, plus what it could not cover. `json` is `undefined` — never `'[]'` — when the listing
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IssueReference } from '#scripts/issue/issue-reference'
|
|
1
2
|
import { git_gh_api_path } from './git-gh-api-path'
|
|
2
3
|
import { git_gh_exec } from './git-gh-exec'
|
|
3
4
|
import { gh_failure, type GhFailure } from './git-gh-failure'
|
|
@@ -9,7 +10,6 @@ import {
|
|
|
9
10
|
type RestIssue,
|
|
10
11
|
} from './git-gh-issue-rest'
|
|
11
12
|
import { gh_reachability } from './git-gh-reachability'
|
|
12
|
-
import type { IssueReference } from './issue-reference'
|
|
13
13
|
|
|
14
14
|
// Reading one issue. Split out of `git-gh-issue.ts`, which had grown past the file-length limit
|
|
15
15
|
// while holding both the reads and the writes; the reads are what every epic command goes through,
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parse_json_array_or_undefined,
|
|
3
|
+
parse_json_object_safe,
|
|
4
|
+
} from '#scripts/git/parse-json-array'
|
|
5
|
+
import { blocking_issue_schema } from '#scripts/git/schemas'
|
|
6
|
+
import type { IssueReference } from '#scripts/issue/issue-reference'
|
|
1
7
|
import { z } from 'zod'
|
|
2
8
|
import { MERGED_STATE, to_gh_state } from './git-gh-rest-state'
|
|
3
|
-
import type { IssueReference } from './issue-reference'
|
|
4
|
-
import { parse_json_array_or_undefined, parse_json_object_safe } from './parse-json-array'
|
|
5
|
-
import { blocking_issue_schema } from './schemas'
|
|
6
9
|
|
|
7
10
|
// The translation between one REST issue (`repos/{owner}/{repo}/issues/{N}`) and the JSON shape
|
|
8
11
|
// `gh issue view --json <fields>` used to answer with.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { error_text } from '#scripts/lib/error-message'
|
|
1
2
|
import { git_gh_api_path } from './git-gh-api-path'
|
|
2
3
|
import { git_gh_exec, type GhApiRequest } from './git-gh-exec'
|
|
3
4
|
|
|
@@ -43,7 +44,9 @@ async function did_write_succeed(write: () => Promise<unknown>): Promise<boolean
|
|
|
43
44
|
await write()
|
|
44
45
|
|
|
45
46
|
return true
|
|
46
|
-
} catch {
|
|
47
|
+
} catch (error) {
|
|
48
|
+
error_text.trace_swallowed('git_gh_issue_write.did_write_succeed', error)
|
|
49
|
+
|
|
47
50
|
return false
|
|
48
51
|
}
|
|
49
52
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { error_text } from '#scripts/lib/error-message'
|
|
1
2
|
import { git_gh_api_path } from './git-gh-api-path'
|
|
2
3
|
import { git_gh_exec } from './git-gh-exec'
|
|
3
4
|
import { read_pull, require_pr_number } from './git-gh-pr-read'
|
|
@@ -40,7 +41,9 @@ async function pr_enable_auto_merge(branch_name: string): Promise<void> {
|
|
|
40
41
|
async function pr_is_merged(branch_name: string): Promise<boolean> {
|
|
41
42
|
try {
|
|
42
43
|
return git_gh_pr_rest.is_merged(await read_pull(await require_pr_number(branch_name)))
|
|
43
|
-
} catch {
|
|
44
|
+
} catch (error) {
|
|
45
|
+
error_text.trace_swallowed('git_gh_pr_auto_merge.pr_is_merged', error)
|
|
46
|
+
|
|
44
47
|
return false
|
|
45
48
|
}
|
|
46
49
|
}
|
|
@@ -77,6 +77,12 @@ async function fetch_pr_number(branch_name: string): Promise<number | undefined>
|
|
|
77
77
|
// distinction is the point. The *classification* is cheaper here and needs no status probe: a branch
|
|
78
78
|
// with no pull request is a 200 with an empty listing rather than a 404, so the lookup's own outcome
|
|
79
79
|
// already separates them (joshuafolkken/kit#1048).
|
|
80
|
+
interface PullMergeState {
|
|
81
|
+
is_merged: boolean
|
|
82
|
+
merged_at: string | undefined
|
|
83
|
+
head_sha: string | undefined
|
|
84
|
+
}
|
|
85
|
+
|
|
80
86
|
type PullNumberRead =
|
|
81
87
|
{ kind: 'read'; pr_number: number } | { kind: 'missing' } | { kind: 'unreadable'; cause: unknown }
|
|
82
88
|
|
|
@@ -215,6 +221,22 @@ async function pr_get_url(branch_name: string): Promise<string | undefined> {
|
|
|
215
221
|
return git_gh_helpers.parse_pr_state_string(pull.html_url)
|
|
216
222
|
}
|
|
217
223
|
|
|
224
|
+
// **Where the branch's pull request stands** — a merge a person made by hand included
|
|
225
|
+
// (joshuafolkken/kit#3023): whether it merged and when, and the commit its head is on, which a push
|
|
226
|
+
// made on GitHub moves without touching the local branch. `undefined` covers both "no pull request"
|
|
227
|
+
// and "nothing could be read": `followup` then takes its ordinary path, whose merge step settles a
|
|
228
|
+
// pull request that did merge after all (`pr_merge`), so an unread answer costs a wait, not a wrong tail.
|
|
229
|
+
async function pr_get_merge_state(branch_name: string): Promise<PullMergeState | undefined> {
|
|
230
|
+
const pull = await read_pull_of_branch(branch_name)
|
|
231
|
+
if (pull === undefined) return undefined
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
is_merged: git_gh_pr_rest.is_merged(pull),
|
|
235
|
+
merged_at: pull.merged_at ?? undefined,
|
|
236
|
+
head_sha: pull.head?.sha,
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
218
240
|
// REST answers JSON null for a pull request with no body where `gh --json body` answered an empty
|
|
219
241
|
// string, and both used to arrive here as the empty answer this folds to `undefined`.
|
|
220
242
|
async function pr_get_body(branch_name: string): Promise<string | undefined> {
|
|
@@ -281,6 +303,7 @@ const git_gh_pr_read = {
|
|
|
281
303
|
pr_get_number,
|
|
282
304
|
pr_get_url,
|
|
283
305
|
pr_get_body,
|
|
306
|
+
pr_get_merge_state,
|
|
284
307
|
pr_view,
|
|
285
308
|
pr_get_comments,
|
|
286
309
|
pr_get_review_comments,
|
|
@@ -290,6 +313,7 @@ const git_gh_pr_read = {
|
|
|
290
313
|
// needs them separately: the reviews endpoint is keyed by number while the rollup is keyed by the
|
|
291
314
|
// head commit the detail carries. Exported rather than re-derived so the memo above stays one memo
|
|
292
315
|
// (joshuafolkken/kit#1028).
|
|
316
|
+
export type { PullMergeState }
|
|
293
317
|
export {
|
|
294
318
|
git_gh_pr_read,
|
|
295
319
|
forget_pr_numbers,
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parse_json_array_or_undefined,
|
|
3
|
+
parse_json_object_safe,
|
|
4
|
+
} from '#scripts/git/parse-json-array'
|
|
5
|
+
import { rest_comment_schema } from '#scripts/git/schemas'
|
|
1
6
|
import { z } from 'zod'
|
|
2
7
|
import { MERGED_STATE, to_gh_state } from './git-gh-rest-state'
|
|
3
|
-
import { parse_json_array_or_undefined, parse_json_object_safe } from './parse-json-array'
|
|
4
|
-
import { rest_comment_schema } from './schemas'
|
|
5
8
|
|
|
6
9
|
// The translation between one REST pull request (`repos/{owner}/{repo}/pulls/{N}`) and the JSON
|
|
7
10
|
// shape `gh pr view --json <fields>` used to answer with.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
|
|
1
2
|
import { z } from 'zod'
|
|
2
|
-
import { parse_json_array_or_undefined } from './parse-json-array'
|
|
3
3
|
|
|
4
4
|
// GraphQL's `reviewDecision`, rebuilt from the review history REST serves.
|
|
5
5
|
//
|
|
@@ -90,7 +90,7 @@ function to_review_decision(reviews_json: string): string {
|
|
|
90
90
|
return latest.has(REVIEW_APPROVED) ? REVIEW_APPROVED : REVIEW_NONE
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
const git_gh_pr_review = { to_review_decision
|
|
93
|
+
const git_gh_pr_review = { to_review_decision }
|
|
94
94
|
|
|
95
95
|
export {
|
|
96
96
|
git_gh_pr_review,
|