@joshuafolkken/kit 1.1035.0 → 1.1094.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/verify-ui/SKILL.md +1 -1
- package/.claude/skills/workflow-commands/SKILL.md +21 -13
- package/.claude/skills/workflow-commands/background-commands.md +5 -4
- package/.claude/skills/workflow-commands/backlogrun-child.md +3 -3
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +9 -7
- package/.claude/skills/workflow-commands/backlogrun-park.md +6 -0
- package/.claude/skills/workflow-commands/backlogrun-progress.md +31 -37
- package/.claude/skills/workflow-commands/backlogrun-steps.md +25 -25
- package/.claude/skills/workflow-commands/backlogrun.md +2 -2
- package/.claude/skills/workflow-commands/chain-rule.md +6 -4
- package/.claude/skills/workflow-commands/delegation.md +3 -3
- package/.claude/skills/workflow-commands/followup-reference.md +3 -3
- 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 +3 -2
- package/.claude/skills/workflow-commands/halfrun.md +16 -19
- package/.claude/skills/workflow-commands/issue-comments.md +2 -2
- 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 +1 -1
- package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
- package/.claude/skills/workflow-commands/observation-filing.md +44 -89
- package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -36
- 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/working-tree-hold.md +24 -4
- package/.codex/hooks.json +16 -20
- package/.github/actions/setup-pnpm/action.yml +93 -0
- package/.github/dependabot.yml +5 -1
- package/.github/workflows/auto-tag.yml +21 -0
- package/.github/workflows/ci.yml +26 -128
- package/.github/workflows/pr-classification.yml +5 -41
- package/.github/workflows/publish.yml +42 -48
- package/.github/workflows/sonar-qube.yml +37 -4
- package/AGENTS.md +12 -2
- package/CLAUDE.md +15 -16
- package/GEMINI.md +14 -2
- package/README.md +59 -18
- package/SECURITY.md +36 -6
- package/cspell/index.yaml +2 -1
- package/dist/CLAUDE.md +15 -16
- package/dist/config-merge/index.js +15 -3
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-Y27M6A7X.js → chunk-3C4YCCEF.js} +5 -13
- package/dist/hooks/{chunk-D67KVGGY.js → chunk-7ZPFAVR7.js} +17 -88
- package/dist/hooks/{chunk-HOYJU5RM.js → chunk-E54KGFEQ.js} +11 -4
- package/dist/hooks/{chunk-KG6PZD72.js → chunk-IL27YTPH.js} +2 -2
- package/dist/hooks/{chunk-GJT4BNVE.js → chunk-KHWHKJOM.js} +3 -3
- package/dist/hooks/{chunk-HU66PWWL.js → chunk-M2XDCUKD.js} +1076 -509
- package/dist/hooks/{chunk-GLBDBJOK.js → chunk-NKOG3XAV.js} +199 -304
- package/dist/hooks/{chunk-ZXNE6NY3.js → chunk-O4LL4HTI.js} +2 -7
- package/dist/hooks/{chunk-XPLP27WA.js → chunk-OIZUHPJI.js} +5 -27
- package/dist/hooks/{chunk-EIFCAJRB.js → chunk-UD24EAIL.js} +2546 -1636
- package/dist/hooks/codex-hook-adapter.js +10 -11
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +15 -34
- package/dist/hooks/inputs.json +279 -0
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +23 -16
- package/dist/hooks/session-lang.js +0 -1
- package/dist/hooks/stop-guard.js +188 -509
- package/dist/josh.js +166 -225
- package/dist/managed-marker/index.js +2 -1
- package/dist/version/index.js +412 -64
- package/eslint/rules/promise.js +5 -0
- package/package.json +13 -8
- package/prompts/collaboration-workflow/file-edits.md +6 -53
- package/prompts/collaboration-workflow/issue-citation.md +5 -5
- package/prompts/collaboration-workflow/operating-rules.md +4 -4
- package/prompts/collaboration-workflow/overview.md +13 -1
- package/prompts/collaboration-workflow/report-format.md +1 -1
- package/prompts/collaboration-workflow/residency.md +4 -4
- package/prompts/collaboration-workflow/rule-delivery.md +5 -36
- package/prompts/collaboration-workflow/shell-body.md +7 -9
- package/prompts/collaboration-workflow/turn-batching.md +21 -37
- package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
- package/prompts/collaboration-workflow/wip-cap.md +36 -36
- package/prompts/collaboration-workflow.md +5 -8
- package/prompts/review-rubric.md +1 -1
- package/prompts/review.md +3 -3
- package/prompts/sonar-hotspot-handling.md +12 -4
- package/prompts/testing-guide.md +3 -3
- package/scripts/adopt/adopt-toolkits.ts +2 -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 +15 -25
- 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 +32 -22
- package/scripts/backlog/backlog-offer-cli.ts +0 -5
- package/scripts/backlog/backlog-plan-cli.ts +6 -8
- package/scripts/backlog/backlog-plan.ts +1 -1
- package/scripts/backlog/backlog-pool.ts +34 -17
- package/scripts/backlog/backlog-rank.ts +106 -0
- package/scripts/backlog/backlog-ready.ts +19 -3
- 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 +47 -31
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/build/build-codex-hooks.ts +26 -0
- package/scripts/build/build-hooks.ts +92 -11
- 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/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 +0 -3
- 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 +11 -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 +4 -6
- package/scripts/doctor/doctor-logic.ts +0 -4
- package/scripts/doctor/doctor.ts +14 -9
- package/scripts/document/document-byte-budget.ts +8 -9
- 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 +13 -4
- package/scripts/document/lane-child-read-set.ts +1 -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 +1 -0
- package/scripts/document/read-set-pricing.ts +0 -1
- package/scripts/document/read-set-trim.ts +1 -1
- 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 +5 -4
- 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 +20 -30
- 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 +37 -0
- 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 +32 -30
- 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 +2 -0
- 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-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 +1 -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-execa-error.ts +6 -1
- package/scripts/git/git-issue.ts +1 -1
- package/scripts/git/git-preflight.ts +24 -6
- package/scripts/git/git-prompt.ts +6 -31
- package/scripts/git/git-push-transport.ts +12 -69
- package/scripts/git/git-push.ts +1 -1
- package/scripts/git/git-spawn.ts +79 -3
- package/scripts/git/git-ssh-keepalive.ts +74 -0
- 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 +4 -2
- 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} +1 -1
- 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-cli.ts +15 -0
- package/scripts/hooks/format-edited-file.ts +4 -9
- package/scripts/hooks/pre-push-unit.ts +0 -4
- package/scripts/hooks/pretool-guard-cli.ts +21 -0
- package/scripts/hooks/pretool-guard.ts +36 -19
- 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-logic.ts +7 -0
- package/scripts/init/init.ts +0 -3
- package/scripts/init/project-profile.ts +6 -11
- package/scripts/init/start-exec.ts +8 -2
- package/scripts/init/start-plan.ts +18 -5
- package/scripts/init/start-setup-pr.ts +52 -25
- package/scripts/init/start-steps.ts +42 -9
- package/scripts/init/start.ts +40 -10
- package/scripts/issue/behavior-change-lint.ts +0 -1
- package/scripts/issue/defect-rate-cli.ts +3 -3
- package/scripts/issue/defect-rate.ts +1 -2
- package/scripts/{git → issue}/git-next-issues.ts +37 -8
- package/scripts/issue/issue-backlinks-cli.ts +1 -5
- package/scripts/issue/issue-cite-cli.ts +2 -6
- package/scripts/issue/issue-cite.ts +19 -3
- 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 +2 -2
- 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 +20 -0
- package/scripts/issue/issue-lint-cli.ts +1 -1
- package/scripts/issue/issue-merged.ts +2 -2
- package/scripts/issue/issue-rank.ts +89 -0
- 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 +1 -1
- package/scripts/issue/measure-rerun-cli.ts +1 -1
- 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 -102
- 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 +10 -3
- 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 +2 -2
- package/scripts/josh/path-decision.ts +0 -3
- package/scripts/josh/process-owner.ts +16 -0
- package/scripts/josh/session-language-cli.ts +0 -1
- package/scripts/lane/lane-await.ts +3 -6
- package/scripts/lane/lane-capacity.ts +6 -3
- package/scripts/lane/lane-child-invocation.ts +20 -7
- package/scripts/lane/lane-child-marker.ts +16 -2
- package/scripts/lane/lane-cli.ts +33 -18
- package/scripts/lane/lane-close.ts +1 -3
- 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 +21 -11
- 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/lane-report.ts +10 -4
- 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 +3 -0
- package/scripts/lib/bounded-pool.ts +1 -0
- 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/lines-command.ts +0 -1
- 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 +0 -2
- package/scripts/propagate/propagate-plan.ts +185 -0
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +5 -3
- package/scripts/propagate/propagate-steps.ts +19 -6
- package/scripts/propagate/propagate-targets.ts +13 -6
- package/scripts/propagate/propagate.ts +60 -46
- package/scripts/refactor/import-graph.ts +0 -1
- package/scripts/refactor/refactor-lint.ts +0 -2
- package/scripts/refactor/refactor-scan.ts +0 -1
- package/scripts/refactor/refactor-targets.ts +0 -1
- package/scripts/registry-migration/migrate-logic.ts +1 -2
- package/scripts/registry-migration/migrate.ts +19 -9
- package/scripts/release/github-release-cli.ts +8 -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 +2 -3
- package/scripts/release/release-scope-cli.ts +1 -2
- package/scripts/release/release-tag.ts +2 -4
- 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 +48 -16
- package/scripts/review/review-brief-cli.ts +72 -8
- package/scripts/review/review-brief.ts +67 -9
- 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 +1 -1
- package/scripts/review/review-record.ts +0 -1
- package/scripts/review/review-round2-cli.ts +1 -1
- package/scripts/review/review-stamps.ts +6 -2
- 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/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 +1 -2
- package/scripts/rules/index-guard.ts +71 -0
- package/scripts/rules/issue-citation.ts +50 -25
- package/scripts/rules/issue-fold.ts +1 -2
- package/scripts/rules/lane-background.ts +15 -7
- package/scripts/rules/lane-carry-conflict.ts +1 -2
- package/scripts/rules/lane-park.ts +14 -8
- 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/pre-gate-cut.ts +2 -2
- 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 +13 -5
- 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-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-cli.ts +0 -7
- package/scripts/run/run-cut.ts +8 -54
- package/scripts/run/run-ending-cli.ts +1 -1
- package/scripts/run/run-ending.ts +1 -4
- package/scripts/run/run-entry-cli.ts +101 -24
- 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.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 +24 -8
- package/scripts/run/run-hold-cli.ts +33 -10
- package/scripts/run/run-hold.ts +25 -5
- package/scripts/run/run-issue-number.ts +1 -1
- package/scripts/run/run-liveness-cli.ts +1 -1
- package/scripts/run/run-liveness.ts +2 -3
- package/scripts/run/run-merge-cli.ts +5 -13
- 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 +143 -0
- package/scripts/run/run-preflight.ts +2 -9
- package/scripts/run/run-prep-cli.ts +2 -2
- package/scripts/run/run-prep-locate.ts +1 -1
- package/scripts/run/run-progress-cli.ts +4 -7
- package/scripts/run/run-progress-clock.ts +6 -34
- package/scripts/run/run-progress-config.ts +0 -4
- package/scripts/run/run-progress-read.ts +3 -3
- package/scripts/run/run-progress.ts +22 -10
- 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 +27 -77
- 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 +87 -0
- package/scripts/run/run-ship-return.ts +8 -3
- package/scripts/run/run-ship-review-steps.ts +23 -30
- package/scripts/run/run-ship-review.ts +20 -0
- package/scripts/run/run-ship-scoped.ts +45 -0
- package/scripts/run/run-ship-stage.ts +5 -1
- package/scripts/run/run-ship-steps.ts +105 -0
- package/scripts/run/run-ship.ts +2 -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 +1 -1
- 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 +2 -1
- package/scripts/run/run-tidy-stashes.ts +12 -12
- package/scripts/run/run-wake-cli.ts +4 -5
- package/scripts/run/run-wake-describe.ts +19 -1
- 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 +9 -7
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/safe-chain/ci-installer-pin.ts +11 -5
- 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-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-logic.ts +0 -1
- package/scripts/test/test-declared.ts +0 -2
- 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 +2 -3
- 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 +97 -0
- 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 +5 -4
- package/scripts/version/version-remote.ts +28 -14
- package/scripts/version/version-targets.ts +4 -4
- package/templates/sonar-project.properties +28 -1
- package/templates/workflows/dependabot-auto-merge.yml +5 -3
- package/templates/workflows/github-release.yml +81 -0
- 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-write.ts +0 -0
- /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
- /package/scripts/{git → gh}/git-gh-pr-auto-merge.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
|
@@ -9,6 +9,9 @@ import { run_hold_cli } from './run-hold-cli'
|
|
|
9
9
|
import { run_next } from './run-next'
|
|
10
10
|
import { run_prep } from './run-prep'
|
|
11
11
|
import { run_prep_cli } from './run-prep-cli'
|
|
12
|
+
import { run_prrun_resume } from './run-prrun-resume'
|
|
13
|
+
import { run_stage, type StageCommand, type StageDecision } from './run-stage'
|
|
14
|
+
import { run_stage_read, type StageRead } from './run-stage-read'
|
|
12
15
|
import { run_step } from './run-step'
|
|
13
16
|
|
|
14
17
|
// `josh run:entry <N>` — one call for the fixed entry sequence a lane opens on (joshuafolkken/kit#2372).
|
|
@@ -27,7 +30,10 @@ const ARGV_OFFSET = 2
|
|
|
27
30
|
const SUCCESS_EXIT_CODE = 0
|
|
28
31
|
const FAILURE_EXIT_CODE = 1
|
|
29
32
|
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
30
|
-
const USAGE = 'Usage: josh run:entry <issue-number>'
|
|
33
|
+
const USAGE = 'Usage: josh run:entry <issue-number> [--to kickoff|halfrun|prrun|fullrun]'
|
|
34
|
+
const TO_FLAG = '--to'
|
|
35
|
+
// The flag and its command.
|
|
36
|
+
const TO_ARGUMENT_COUNT = 2
|
|
31
37
|
const should_forward_stderr = true
|
|
32
38
|
const NEWLINE = '\n'
|
|
33
39
|
|
|
@@ -48,16 +54,42 @@ function parse_number(argv: ReadonlyArray<string>): string | undefined {
|
|
|
48
54
|
return first
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
interface EntryRequest {
|
|
58
|
+
issue_number: string
|
|
59
|
+
command: StageCommand
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// `--to <command>` names how far the run goes (joshuafolkken/kit#3042); absent, it is `fullrun`.
|
|
63
|
+
// Anything else is refused.
|
|
64
|
+
function parse_command(rest: ReadonlyArray<string>): StageCommand | undefined {
|
|
65
|
+
if (rest.length === 0) return run_stage.DEFAULT_COMMAND
|
|
66
|
+
|
|
67
|
+
const [flag, value] = rest
|
|
68
|
+
|
|
69
|
+
if (flag !== TO_FLAG || rest.length !== TO_ARGUMENT_COUNT) return undefined
|
|
70
|
+
|
|
71
|
+
return run_stage.to_command(value)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function parse_request(argv: ReadonlyArray<string>): EntryRequest | undefined {
|
|
75
|
+
const issue_number = parse_number(argv.slice(0, 1))
|
|
76
|
+
const command = parse_command(argv.slice(1))
|
|
77
|
+
|
|
78
|
+
return issue_number === undefined || command === undefined ? undefined : { issue_number, command }
|
|
79
|
+
}
|
|
80
|
+
|
|
51
81
|
function first_line(out: string): string {
|
|
52
82
|
return out.split(NEWLINE)[0] ?? ''
|
|
53
83
|
}
|
|
54
84
|
|
|
55
85
|
// `run:hold <N>` prints one token — `hold`, `busy` or `unknown` — and forwards its explanation to
|
|
56
86
|
// stderr, so the composite branches on the token and the reader still sees why. `--fullrun` marks the
|
|
57
|
-
// hold as
|
|
58
|
-
|
|
87
|
+
// hold as a run whose implementation cut resumes as `fullrun #N` (joshuafolkken/kit#2760) — a
|
|
88
|
+
// `fullrun`'s, and a `prrun`'s, which runs `fullrun`'s steps; a `halfrun`'s hold is never marked.
|
|
89
|
+
async function claim_hold(issue_number: string, command: StageCommand): Promise<string> {
|
|
90
|
+
const mark = command === run_stage.HALFRUN ? [] : ['--fullrun']
|
|
59
91
|
const held = await josh_command.josh_run(
|
|
60
|
-
['run:hold', issue_number,
|
|
92
|
+
['run:hold', issue_number, ...mark],
|
|
61
93
|
should_forward_stderr,
|
|
62
94
|
)
|
|
63
95
|
|
|
@@ -131,31 +163,51 @@ function resume_report(issue_number: string, resume: Resume): number {
|
|
|
131
163
|
// **A `halfrun` stopped before its commit is resumed, not claimed** (joshuafolkken/kit#2796): its hold
|
|
132
164
|
// is kept over the verified diff, so the claim below would answer `busy` against it. The budget is asked
|
|
133
165
|
// first, as for any run; then the hold is adopted and the run goes to the gate, skipping everything up
|
|
134
|
-
// to and including implementation.
|
|
135
|
-
|
|
166
|
+
// to and including implementation. **A `prrun` stopped before its merge is resumed the same way**
|
|
167
|
+
// (joshuafolkken/kit#3023), under the token that says what is left of it.
|
|
168
|
+
async function resume_stopped(
|
|
169
|
+
issue_number: string,
|
|
170
|
+
token: string,
|
|
171
|
+
stopped_run: { adopt: (issue: string) => Promise<boolean> },
|
|
172
|
+
): Promise<number> {
|
|
136
173
|
const cost = await check_cost()
|
|
137
174
|
|
|
138
|
-
if (cost === run_entry.COST_OVER)
|
|
139
|
-
return stop_report(issue_number, HALFRUN_RESUME_TOKEN, cost, COST_STOP_NOTE)
|
|
140
|
-
}
|
|
175
|
+
if (cost === run_entry.COST_OVER) return stop_report(issue_number, token, cost, COST_STOP_NOTE)
|
|
141
176
|
|
|
142
|
-
if (!(await
|
|
177
|
+
if (!(await stopped_run.adopt(issue_number))) {
|
|
143
178
|
return stop_report(issue_number, run_hold_cli.BUSY_VERDICT, cost, HOLD_STOP_NOTE)
|
|
144
179
|
}
|
|
145
180
|
|
|
146
|
-
console.info(`entry #${issue_number} — resume: ${
|
|
181
|
+
console.info(`entry #${issue_number} — resume: ${token}`)
|
|
147
182
|
|
|
148
183
|
return SUCCESS_EXIT_CODE
|
|
149
184
|
}
|
|
150
185
|
|
|
151
|
-
|
|
152
|
-
|
|
186
|
+
// The stopped run a decision picks up: a `halfrun` stop resumes at the gate, a `prrun` stop at
|
|
187
|
+
// `followup` under its own token. `undefined` for any other start, so the ordinary claim decides.
|
|
188
|
+
async function resume_any(
|
|
189
|
+
issue_number: string,
|
|
190
|
+
decision: StageDecision,
|
|
191
|
+
stage: StageRead,
|
|
192
|
+
): Promise<number | undefined> {
|
|
193
|
+
if (decision.state === run_stage.HALFRUN_STOPPED) {
|
|
194
|
+
return await resume_stopped(issue_number, HALFRUN_RESUME_TOKEN, run_halfrun_resume)
|
|
195
|
+
}
|
|
153
196
|
|
|
154
|
-
|
|
197
|
+
return stage.prrun_token === undefined
|
|
198
|
+
? undefined
|
|
199
|
+
: await resume_stopped(issue_number, stage.prrun_token, run_prrun_resume)
|
|
200
|
+
}
|
|
155
201
|
|
|
156
|
-
|
|
202
|
+
// **A command whose stopping point the issue has already reached redoes nothing** (joshuafolkken/kit#3042)
|
|
203
|
+
// — the stage line is the whole report. A merged issue is the exception: the ordinary entry already
|
|
204
|
+
// answers it (`already-done`, or `keep-work` over a lane's uncommitted work), so it is left to that.
|
|
205
|
+
function is_settled(decision: StageDecision): boolean {
|
|
206
|
+
return decision.is_reached && decision.state !== run_stage.MERGED
|
|
207
|
+
}
|
|
157
208
|
|
|
158
|
-
|
|
209
|
+
async function claim_run({ issue_number, command }: EntryRequest): Promise<number> {
|
|
210
|
+
const hold = await claim_hold(issue_number, command)
|
|
159
211
|
|
|
160
212
|
if (hold !== run_hold_cli.HOLD_VERDICT) {
|
|
161
213
|
return stop_report(issue_number, hold, run_entry.COST_SKIPPED, HOLD_STOP_NOTE)
|
|
@@ -170,16 +222,45 @@ async function open_run(issue_number: string): Promise<number> {
|
|
|
170
222
|
return emit({ issue_number, hold, cost, verdict: reads.verdict, report: reads.report })
|
|
171
223
|
}
|
|
172
224
|
|
|
225
|
+
// A carried cut is asked first, before anything is read (`run:cut --resume`); `kickoff` claims and cuts
|
|
226
|
+
// nothing, so it never asks. `undefined` when no cut is waiting.
|
|
227
|
+
async function resume_cut(request: EntryRequest): Promise<number | undefined> {
|
|
228
|
+
if (request.command === run_stage.KICKOFF) return undefined
|
|
229
|
+
|
|
230
|
+
const resume = await ask_resume(request.issue_number)
|
|
231
|
+
|
|
232
|
+
return resume.token === run_cut_report.FRESH_VERDICT
|
|
233
|
+
? undefined
|
|
234
|
+
: resume_report(request.issue_number, resume)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// `kickoff` stops at the stage line whatever it says — it plans, and claims nothing.
|
|
238
|
+
async function open_run(request: EntryRequest): Promise<number> {
|
|
239
|
+
const { issue_number, command } = request
|
|
240
|
+
const cut = await resume_cut(request)
|
|
241
|
+
|
|
242
|
+
if (cut !== undefined) return cut
|
|
243
|
+
|
|
244
|
+
const stage = await run_stage_read.read_stage(issue_number)
|
|
245
|
+
const decision = run_stage.decide(stage.state, command)
|
|
246
|
+
|
|
247
|
+
console.info(run_stage.format_decision(issue_number, decision))
|
|
248
|
+
|
|
249
|
+
if (command === run_stage.KICKOFF || is_settled(decision)) return SUCCESS_EXIT_CODE
|
|
250
|
+
|
|
251
|
+
return (await resume_any(issue_number, decision, stage)) ?? (await claim_run(request))
|
|
252
|
+
}
|
|
253
|
+
|
|
173
254
|
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
174
|
-
const
|
|
255
|
+
const request = parse_request(argv)
|
|
175
256
|
|
|
176
|
-
if (
|
|
257
|
+
if (request === undefined) {
|
|
177
258
|
console.error(USAGE)
|
|
178
259
|
|
|
179
260
|
return FAILURE_EXIT_CODE
|
|
180
261
|
}
|
|
181
262
|
|
|
182
|
-
return await open_run(
|
|
263
|
+
return await open_run(request)
|
|
183
264
|
}
|
|
184
265
|
|
|
185
266
|
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
@@ -188,12 +269,8 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
188
269
|
|
|
189
270
|
const run_entry_cli = {
|
|
190
271
|
HALFRUN_RESUME_TOKEN,
|
|
191
|
-
SUCCESS_EXIT_CODE,
|
|
192
|
-
USAGE,
|
|
193
|
-
check_cost,
|
|
194
|
-
claim_hold,
|
|
195
|
-
main,
|
|
196
272
|
parse_number,
|
|
273
|
+
parse_request,
|
|
197
274
|
run,
|
|
198
275
|
}
|
|
199
276
|
|
package/scripts/run/run-entry.ts
CHANGED
|
@@ -52,6 +52,7 @@ async function follow(
|
|
|
52
52
|
let read = ports.read(position)
|
|
53
53
|
|
|
54
54
|
while (read.events.length === 0 && ports.now() < deadline) {
|
|
55
|
+
// eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
|
|
55
56
|
await ports.sleep(options.tick_ms)
|
|
56
57
|
read = ports.read(position)
|
|
57
58
|
}
|
|
@@ -69,7 +69,7 @@ function render(event: RunEvent, lang: string): string {
|
|
|
69
69
|
return [clock_of(event.at), label_of(event.kind, lang), event.text].join(FIELD_SEPARATOR)
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
const run_event_render = {
|
|
72
|
+
const run_event_render = { clock_of, label_of, render }
|
|
73
73
|
|
|
74
74
|
export type { KindLabel }
|
|
75
75
|
export { run_event_render }
|
|
@@ -91,6 +91,22 @@ const SHIP_POSITION_KINDS: ReadonlySet<string> = new Set([
|
|
|
91
91
|
run_event_stream.EVENT_KIND.SHIP_STOP,
|
|
92
92
|
])
|
|
93
93
|
|
|
94
|
+
const KIND = run_event_stream.EVENT_KIND
|
|
95
|
+
|
|
96
|
+
// The parent's record of the batch around a child — its dispatch, park and split, the retrospective
|
|
97
|
+
// whose summary may name an issue it filed, and the strand whose text carries the whole invocation
|
|
98
|
+
// (`backlogrun #<N1> #<N2> …`). Each can name the child, yet none is a position the child itself is at,
|
|
99
|
+
// so a lane child never reads one as its own.
|
|
100
|
+
const BATCH_RECORD_KINDS: ReadonlySet<string> = new Set([
|
|
101
|
+
KIND.CHILD_LAUNCH,
|
|
102
|
+
KIND.PARK,
|
|
103
|
+
KIND.SPLIT,
|
|
104
|
+
KIND.RETROSPECTIVE,
|
|
105
|
+
KIND.STRANDED,
|
|
106
|
+
])
|
|
107
|
+
|
|
108
|
+
const ISSUE_REFERENCE = /#(\d+)/u
|
|
109
|
+
|
|
94
110
|
function is_foreign_ship_event(event: RunEvent, issue: string): boolean {
|
|
95
111
|
return SHIP_POSITION_KINDS.has(event.kind) && !event.text.startsWith(`#${issue} `)
|
|
96
112
|
}
|
|
@@ -99,16 +115,49 @@ function is_own_ship_event(event: RunEvent, issue: string): boolean {
|
|
|
99
115
|
return SHIP_POSITION_KINDS.has(event.kind) && !is_foreign_ship_event(event, issue)
|
|
100
116
|
}
|
|
101
117
|
|
|
118
|
+
// **A lane child's position is read only from events that name its own issue** (joshuafolkken/kit#3039).
|
|
119
|
+
// The parent and every lane append to one stream under one carry scope, so anything else on it is another
|
|
120
|
+
// run's: another lane's merge told a planned child to stop, the parent's stall (which names no issue)
|
|
121
|
+
// pointed it at `backlog:next`, and another lane's cut at `run:cut --resume`. The child's own merge and
|
|
122
|
+
// outage stay, so the parent-only stop in `run-step.ts` still holds; the parent keeps reading everything.
|
|
123
|
+
function names_issue(event: RunEvent, issue: string): boolean {
|
|
124
|
+
return ISSUE_REFERENCE.exec(event.text)?.[1] === issue
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function is_lane_position(event: RunEvent, issue: string): boolean {
|
|
128
|
+
return !BATCH_RECORD_KINDS.has(event.kind) && names_issue(event, issue)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// A lane child's attempt begins at its own newest launch. A child re-dispatched after an outage — or
|
|
132
|
+
// relaunched after a cut, whose resume `run:cut --resume` answers at the entry — shares the scope with
|
|
133
|
+
// its previous attempt, and that attempt's outage would otherwise stop the new one at its entry `run:step`.
|
|
134
|
+
function since_own_launch(events: ReadonlyArray<RunEvent>, issue: string): ReadonlyArray<RunEvent> {
|
|
135
|
+
const launch = events.findLastIndex(
|
|
136
|
+
(event) => event.kind === KIND.CHILD_LAUNCH && names_issue(event, issue),
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
return events.slice(launch + 1)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function is_foreign_event(event: RunEvent, issue: string, is_lane_child: boolean): boolean {
|
|
143
|
+
if (is_lane_child) return !is_lane_position(event, issue)
|
|
144
|
+
|
|
145
|
+
return is_foreign_ship_event(event, issue)
|
|
146
|
+
}
|
|
147
|
+
|
|
102
148
|
// The newest position for one issue's run: the scoped last event with other issues' ship positions left
|
|
103
|
-
// out
|
|
104
|
-
//
|
|
105
|
-
//
|
|
149
|
+
// out — and, for a lane child, every event not naming its issue — and, where no scope applies, as in
|
|
150
|
+
// an interactive `fullrun` with no carry record, the issue's own newest ship position, which its issue
|
|
151
|
+
// number already scopes. A determined scope with nothing in it yet reads nothing: an earlier invocation's
|
|
152
|
+
// stop for the same issue is not this invocation's position.
|
|
106
153
|
function last_issue_event(
|
|
107
154
|
events: ReadonlyArray<RunEvent>,
|
|
108
155
|
scope: EventScope,
|
|
109
156
|
issue: string,
|
|
157
|
+
is_lane_child: boolean,
|
|
110
158
|
): RunEvent | undefined {
|
|
111
|
-
const
|
|
159
|
+
const attempt = is_lane_child ? since_own_launch(events, issue) : events
|
|
160
|
+
const own = attempt.filter((event) => !is_foreign_event(event, issue, is_lane_child))
|
|
112
161
|
|
|
113
162
|
if (scope.kind === SINCE_SCOPE) return last_scoped_event(own, scope)
|
|
114
163
|
|
|
@@ -238,13 +238,10 @@ const run_event_stream = {
|
|
|
238
238
|
EVENT_CAP,
|
|
239
239
|
EVENT_KIND,
|
|
240
240
|
EVENT_KINDS,
|
|
241
|
-
EVENT_PREFIX,
|
|
242
|
-
EVENT_SUFFIX,
|
|
243
241
|
TRACE_KINDS,
|
|
244
242
|
append,
|
|
245
243
|
format_event,
|
|
246
244
|
has_since,
|
|
247
|
-
is_event_kind,
|
|
248
245
|
read_events,
|
|
249
246
|
read_from,
|
|
250
247
|
read_last,
|
|
@@ -22,6 +22,7 @@ async function watch(ports: WatchPorts, position: number): Promise<number> {
|
|
|
22
22
|
let next = position
|
|
23
23
|
|
|
24
24
|
while (ports.should_continue()) {
|
|
25
|
+
// eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
|
|
25
26
|
const read = await ports.pass(next)
|
|
26
27
|
|
|
27
28
|
for (const event of read.events) ports.write(ports.render(event))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { run_hold, type HoldRead, type RunHold } from './run-hold'
|
|
1
|
+
import { run_hold, type HoldRead, type RunHold, type StopMarkFields } from './run-hold'
|
|
2
2
|
|
|
3
3
|
// joshuafolkken/kit#2796: a `halfrun` stops before its commit and **keeps** its hold, because the
|
|
4
4
|
// uncommitted, hand-verified work is exactly what a second run would trample. The person then types
|
|
@@ -38,7 +38,13 @@ function is_own_record(read: HoldRead, issue: string): boolean {
|
|
|
38
38
|
return hold === undefined || hold.issue === issue || hold.issue === run_hold.UNNUMBERED_ISSUE
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
// `mark` is the `halfrun` stop's by default; a `prrun` stop passes its own (joshuafolkken/kit#3023), so
|
|
42
|
+
// the own-record check is one check whichever run is stopping.
|
|
43
|
+
function mark_stop_at(
|
|
44
|
+
target: string,
|
|
45
|
+
issue: string,
|
|
46
|
+
mark: StopMarkFields = run_hold.HALFRUN_STOP_FIELDS,
|
|
47
|
+
): StopMark {
|
|
42
48
|
const read = run_hold.read_hold(target)
|
|
43
49
|
|
|
44
50
|
if (read.kind === 'unreadable') return UNREADABLE
|
|
@@ -47,7 +53,14 @@ function mark_stop_at(target: string, issue: string): StopMark {
|
|
|
47
53
|
|
|
48
54
|
run_hold.release_hold(target)
|
|
49
55
|
|
|
50
|
-
return run_hold.
|
|
56
|
+
return run_hold.create_stop_hold(target, issue, mark) ? MARKED : FOREIGN
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// The stopped run's record is replaced by this `fullrun`'s, shared with the `prrun` resume.
|
|
60
|
+
function take_over(target: string, issue: string): boolean {
|
|
61
|
+
run_hold.release_hold(target)
|
|
62
|
+
|
|
63
|
+
return run_hold.create_hold(target, issue, new Date(), true)
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
// `false` leaves the record untouched, so the ordinary claim that follows decides the tree exactly as
|
|
@@ -55,9 +68,7 @@ function mark_stop_at(target: string, issue: string): StopMark {
|
|
|
55
68
|
function adopt_at(target: string, issue: string, is_dirty: boolean): boolean {
|
|
56
69
|
if (!is_halfrun_stop(run_hold.read_hold(target), issue, is_dirty)) return false
|
|
57
70
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return run_hold.create_hold(target, issue, new Date(), true)
|
|
71
|
+
return take_over(target, issue)
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
// **An unreadable git directory is no resume**, never a crash: `run:entry` must still print its one
|
|
@@ -95,9 +106,11 @@ const run_halfrun_resume = {
|
|
|
95
106
|
UNREADABLE,
|
|
96
107
|
adopt,
|
|
97
108
|
adopt_at,
|
|
98
|
-
|
|
109
|
+
hold_of,
|
|
110
|
+
hold_target,
|
|
99
111
|
is_pending,
|
|
100
112
|
mark_stop_at,
|
|
113
|
+
take_over,
|
|
101
114
|
}
|
|
102
115
|
|
|
103
116
|
export type { StopMark }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
2
2
|
import { lane_reap } from '#scripts/lane/lane-reap'
|
|
3
|
+
import { lane_registry } from '#scripts/lane/lane-registry'
|
|
3
4
|
import { run_carry, type CarryRead, type RunCarry } from './run-carry'
|
|
4
|
-
import { run_watcher_guard } from './run-watcher-guard'
|
|
5
5
|
|
|
6
6
|
// The headless `backlogrun` parent (joshuafolkken/kit#2437). `run:wake` starts a cut's successor as
|
|
7
7
|
// `claude -p`, and there a turn that ends is the process that ends: its background `lane:await` and
|
|
@@ -51,7 +51,7 @@ async function read_carry_here(): Promise<CarryRead | undefined> {
|
|
|
51
51
|
async function must_keep_waiting(source: EnvironmentSource = process.env): Promise<boolean> {
|
|
52
52
|
const is_candidate = is_headless(source) && lane_child_marker.marked_issue(source) === undefined
|
|
53
53
|
|
|
54
|
-
if (!is_candidate || !(await
|
|
54
|
+
if (!is_candidate || !(await lane_registry.has_lanes_in_flight())) return false
|
|
55
55
|
|
|
56
56
|
return is_driving(await read_carry_here())
|
|
57
57
|
}
|
|
@@ -73,10 +73,27 @@ function is_owned_here(carry: RunCarry, ancestry: () => ReadonlySet<number>): bo
|
|
|
73
73
|
return carry.owner_pid !== undefined && ancestry().has(carry.owner_pid)
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function
|
|
77
|
-
|
|
76
|
+
function driven_here(
|
|
77
|
+
read: CarryRead | undefined,
|
|
78
|
+
ancestry: () => ReadonlySet<number>,
|
|
79
|
+
): RunCarry | undefined {
|
|
80
|
+
if (read?.kind !== 'carried' || !is_driving(read)) return undefined
|
|
78
81
|
|
|
79
|
-
return is_owned_here(read.carry, ancestry)
|
|
82
|
+
return is_owned_here(read.carry, ancestry) ? read.carry : undefined
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The live, un-handed-off carry record this session drives as the `backlogrun` parent, or `undefined`
|
|
87
|
+
* for a lane child or any session that does not own one. Returned rather than tested so a caller that
|
|
88
|
+
* also needs the record's counters (the parent cut's cap, joshuafolkken/kit#2947) reads it once.
|
|
89
|
+
*/
|
|
90
|
+
async function driving_carry(
|
|
91
|
+
source: EnvironmentSource = process.env,
|
|
92
|
+
ancestry: () => ReadonlySet<number> = lane_reap.own_ancestry,
|
|
93
|
+
): Promise<RunCarry | undefined> {
|
|
94
|
+
if (lane_child_marker.marked_issue(source) !== undefined) return undefined
|
|
95
|
+
|
|
96
|
+
return driven_here(await read_carry_here(), ancestry)
|
|
80
97
|
}
|
|
81
98
|
|
|
82
99
|
/**
|
|
@@ -88,14 +105,13 @@ async function is_backlog_parent(
|
|
|
88
105
|
source: EnvironmentSource = process.env,
|
|
89
106
|
ancestry: () => ReadonlySet<number> = lane_reap.own_ancestry,
|
|
90
107
|
): Promise<boolean> {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return is_driven_here(await read_carry_here(), ancestry)
|
|
108
|
+
return (await driving_carry(source, ancestry)) !== undefined
|
|
94
109
|
}
|
|
95
110
|
|
|
96
111
|
const run_headless = {
|
|
97
112
|
HEADLESS_ENV_KEY,
|
|
98
113
|
current_carry,
|
|
114
|
+
driving_carry,
|
|
99
115
|
environment,
|
|
100
116
|
is_backlog_parent,
|
|
101
117
|
is_headless,
|
|
@@ -3,6 +3,7 @@ import { fileURLToPath } from 'node:url'
|
|
|
3
3
|
import { run_halfrun_resume } from './run-halfrun-resume'
|
|
4
4
|
import { run_hold, type HoldRead, type RunHold } from './run-hold'
|
|
5
5
|
import { run_preflight, type PreflightDecision } from './run-preflight'
|
|
6
|
+
import { run_prrun_resume } from './run-prrun-resume'
|
|
6
7
|
import { run_tidy_cli } from './run-tidy-cli'
|
|
7
8
|
|
|
8
9
|
// `josh run:hold [<N>]` and `josh run:release [<N> | --force]` — the working-tree guard the typed
|
|
@@ -48,11 +49,13 @@ const FORCE_FLAG = '--force'
|
|
|
48
49
|
// implementation cut outside a lane resumes as `fullrun #N` (joshuafolkken/kit#2760).
|
|
49
50
|
const FULLRUN_FLAG = '--fullrun'
|
|
50
51
|
const HALFRUN_STOP_FLAG = '--halfrun-stop'
|
|
52
|
+
// A `prrun`'s stop before merge (joshuafolkken/kit#3023): its record keeps the commit it stopped on.
|
|
53
|
+
const PRRUN_STOP_FLAG = '--prrun-stop'
|
|
51
54
|
// The most a claim reads: the issue number and the one flag after it.
|
|
52
55
|
const MAX_CLAIM_ARGUMENTS = 2
|
|
53
56
|
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
54
57
|
const USAGE =
|
|
55
|
-
'Usage: josh run:hold [<issue-number> [--fullrun | --halfrun-stop]] | josh run:release [<issue-number> | --force]'
|
|
58
|
+
'Usage: josh run:hold [<issue-number> [--fullrun | --halfrun-stop | --prrun-stop]] | josh run:release [<issue-number> | --force]'
|
|
56
59
|
|
|
57
60
|
const HOLD_VERDICT = 'hold'
|
|
58
61
|
const BUSY_VERDICT = 'busy'
|
|
@@ -65,6 +68,7 @@ const HELD_VERDICT = 'held'
|
|
|
65
68
|
|
|
66
69
|
const FORCE_RELEASE_KIND = 'force-release'
|
|
67
70
|
const HALFRUN_STOP_KIND = 'halfrun-stop'
|
|
71
|
+
const PRRUN_STOP_KIND = 'prrun-stop'
|
|
68
72
|
|
|
69
73
|
interface ClaimRequest {
|
|
70
74
|
kind: 'claim'
|
|
@@ -72,11 +76,20 @@ interface ClaimRequest {
|
|
|
72
76
|
is_fullrun?: boolean
|
|
73
77
|
}
|
|
74
78
|
|
|
79
|
+
interface StopRequest {
|
|
80
|
+
kind: typeof HALFRUN_STOP_KIND | typeof PRRUN_STOP_KIND
|
|
81
|
+
issue: string
|
|
82
|
+
}
|
|
83
|
+
|
|
75
84
|
type HoldRequest =
|
|
76
85
|
| ClaimRequest
|
|
86
|
+
| StopRequest
|
|
77
87
|
| { kind: 'release'; claimant: string }
|
|
78
88
|
| { kind: typeof FORCE_RELEASE_KIND }
|
|
79
|
-
|
|
89
|
+
|
|
90
|
+
function is_stop_request(request: HoldRequest): request is StopRequest {
|
|
91
|
+
return request.kind === HALFRUN_STOP_KIND || request.kind === PRRUN_STOP_KIND
|
|
92
|
+
}
|
|
80
93
|
|
|
81
94
|
const FORCE_RELEASE_REQUEST: HoldRequest = { kind: FORCE_RELEASE_KIND }
|
|
82
95
|
|
|
@@ -84,12 +97,20 @@ function release_request(claimant: string): HoldRequest {
|
|
|
84
97
|
return { kind: 'release', claimant }
|
|
85
98
|
}
|
|
86
99
|
|
|
87
|
-
|
|
88
|
-
|
|
100
|
+
const STOP_KIND_BY_FLAG: ReadonlyMap<string, typeof HALFRUN_STOP_KIND | typeof PRRUN_STOP_KIND> =
|
|
101
|
+
new Map([
|
|
102
|
+
[HALFRUN_STOP_FLAG, HALFRUN_STOP_KIND],
|
|
103
|
+
[PRRUN_STOP_FLAG, PRRUN_STOP_KIND],
|
|
104
|
+
])
|
|
105
|
+
|
|
106
|
+
// The flag after a numbered claim: absent, `--fullrun`, `--halfrun-stop` or `--prrun-stop`. Anything
|
|
107
|
+
// else is a usage error.
|
|
89
108
|
function numbered_claim(issue: string, flag: string | undefined): HoldRequest | undefined {
|
|
90
109
|
if (flag === undefined) return { kind: 'claim', issue }
|
|
91
110
|
|
|
92
|
-
|
|
111
|
+
const stop_kind = STOP_KIND_BY_FLAG.get(flag)
|
|
112
|
+
|
|
113
|
+
if (stop_kind !== undefined) return { kind: stop_kind, issue }
|
|
93
114
|
|
|
94
115
|
return flag === FULLRUN_FLAG ? { kind: 'claim', issue, is_fullrun: true } : undefined
|
|
95
116
|
}
|
|
@@ -293,8 +314,12 @@ async function read_worktree(): Promise<string | undefined> {
|
|
|
293
314
|
|
|
294
315
|
// **A `halfrun` stop marks its own record** (joshuafolkken/kit#2796) — the positive "this run has ended
|
|
295
316
|
// over its verified diff" that `run:entry` adopts on `fullrun #N`. Another run's record is left alone.
|
|
296
|
-
|
|
297
|
-
|
|
317
|
+
// A `prrun` stop marks its record the same way, with the commit it stopped on (joshuafolkken/kit#3023).
|
|
318
|
+
async function mark_stop(target: string, request: StopRequest): Promise<number> {
|
|
319
|
+
const mark =
|
|
320
|
+
request.kind === PRRUN_STOP_KIND
|
|
321
|
+
? await run_prrun_resume.mark_stop_at(target, request.issue)
|
|
322
|
+
: run_halfrun_resume.mark_stop_at(target, request.issue)
|
|
298
323
|
|
|
299
324
|
if (mark === run_halfrun_resume.MARKED) return report_hold()
|
|
300
325
|
|
|
@@ -306,7 +331,7 @@ function mark_halfrun_stop(target: string, issue: string): number {
|
|
|
306
331
|
async function dispatch(request: HoldRequest, target: string, is_linked: boolean): Promise<number> {
|
|
307
332
|
if (request.kind === 'claim') return await claim(target, request, is_linked)
|
|
308
333
|
|
|
309
|
-
if (request
|
|
334
|
+
if (is_stop_request(request)) return await mark_stop(target, request)
|
|
310
335
|
|
|
311
336
|
if (request.kind === FORCE_RELEASE_KIND) return force_release(target)
|
|
312
337
|
|
|
@@ -351,8 +376,6 @@ const run_hold_cli = {
|
|
|
351
376
|
RELEASED_VERDICT,
|
|
352
377
|
UNKNOWN_VERDICT,
|
|
353
378
|
USAGE,
|
|
354
|
-
blocking_message,
|
|
355
|
-
main,
|
|
356
379
|
parse_request,
|
|
357
380
|
run,
|
|
358
381
|
}
|
package/scripts/run/run-hold.ts
CHANGED
|
@@ -52,6 +52,10 @@ interface RunHold {
|
|
|
52
52
|
// the positive record that the run has *ended* over its verified diff, which is what lets
|
|
53
53
|
// `fullrun #N` adopt the hold. A running `halfrun` or a `backlogrun` child never carries it.
|
|
54
54
|
is_halfrun_stop?: boolean | undefined
|
|
55
|
+
// Set only at a `prrun`'s stop before merge (`run:hold <N> --prrun-stop`, joshuafolkken/kit#3023): the
|
|
56
|
+
// commit the green pull request stood on, so `fullrun #N` can tell an untouched branch — merge it —
|
|
57
|
+
// from one that moved since and has to pass the gate and the review again.
|
|
58
|
+
prrun_stop_head?: string | undefined
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
type HoldRead =
|
|
@@ -92,6 +96,7 @@ const run_hold_schema = z.object({
|
|
|
92
96
|
pid: z.number(),
|
|
93
97
|
is_fullrun: z.boolean().optional(),
|
|
94
98
|
is_halfrun_stop: z.boolean().optional(),
|
|
99
|
+
prrun_stop_head: z.string().optional(),
|
|
95
100
|
})
|
|
96
101
|
|
|
97
102
|
// `undefined` for anything that is not a well-formed record, so the caller decides what a broken one
|
|
@@ -161,9 +166,24 @@ function create_hold(
|
|
|
161
166
|
return stamp_file.create_stamp(target, build_hold(issue, now, is_fullrun))
|
|
162
167
|
}
|
|
163
168
|
|
|
164
|
-
//
|
|
169
|
+
// What a stopped run's record carries on top of the claim: the `halfrun` stop's flag, or the commit a
|
|
170
|
+
// `prrun` stop stood on (joshuafolkken/kit#3023).
|
|
171
|
+
type StopMarkFields = Pick<RunHold, 'is_halfrun_stop' | 'prrun_stop_head'>
|
|
172
|
+
|
|
173
|
+
const HALFRUN_STOP_FIELDS: StopMarkFields = { is_halfrun_stop: true }
|
|
174
|
+
|
|
175
|
+
// The claim a stop leaves behind: the same exclusive create, carrying the stop mark.
|
|
176
|
+
function create_stop_hold(
|
|
177
|
+
target: string,
|
|
178
|
+
issue: string,
|
|
179
|
+
mark: StopMarkFields,
|
|
180
|
+
now: Date = new Date(),
|
|
181
|
+
): boolean {
|
|
182
|
+
return stamp_file.create_stamp(target, { ...build_hold(issue, now), ...mark })
|
|
183
|
+
}
|
|
184
|
+
|
|
165
185
|
function create_halfrun_stop_hold(target: string, issue: string, now: Date = new Date()): boolean {
|
|
166
|
-
return
|
|
186
|
+
return create_stop_hold(target, issue, HALFRUN_STOP_FIELDS, now)
|
|
167
187
|
}
|
|
168
188
|
|
|
169
189
|
// **A tree with uncommitted work in it is never handed over, however old its record is.** No age can
|
|
@@ -260,8 +280,9 @@ const run_hold = {
|
|
|
260
280
|
UNNUMBERED_ISSUE,
|
|
261
281
|
classify,
|
|
262
282
|
create_halfrun_stop_hold,
|
|
283
|
+
create_stop_hold,
|
|
284
|
+
HALFRUN_STOP_FIELDS,
|
|
263
285
|
create_hold,
|
|
264
|
-
describe_holder,
|
|
265
286
|
foreign_release_message,
|
|
266
287
|
forced_release_message,
|
|
267
288
|
held_message,
|
|
@@ -270,7 +291,6 @@ const run_hold = {
|
|
|
270
291
|
is_own_hold,
|
|
271
292
|
is_tree_dirty,
|
|
272
293
|
own_release_command,
|
|
273
|
-
parse_hold,
|
|
274
294
|
race_message,
|
|
275
295
|
read_hold,
|
|
276
296
|
release_hold,
|
|
@@ -282,5 +302,5 @@ const run_hold = {
|
|
|
282
302
|
write_hold,
|
|
283
303
|
}
|
|
284
304
|
|
|
285
|
-
export type { HoldRead, RunHold }
|
|
305
|
+
export type { HoldRead, RunHold, StopMarkFields }
|
|
286
306
|
export { run_hold }
|
|
@@ -14,6 +14,6 @@ function require_issue_number(issue: string): void {
|
|
|
14
14
|
if (!ISSUE_NUMBER_PATTERN.test(issue)) throw new Error(`${BAD_ISSUE_MESSAGE}${issue}`)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const run_issue_number = {
|
|
17
|
+
const run_issue_number = { ISSUE_NUMBER_PATTERN, require_issue_number }
|
|
18
18
|
|
|
19
19
|
export { run_issue_number }
|
|
@@ -159,7 +159,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
159
159
|
process.exitCode = await run(argv)
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
const run_liveness_cli = { USAGE,
|
|
162
|
+
const run_liveness_cli = { USAGE, parse_request, run }
|
|
163
163
|
|
|
164
164
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
165
165
|
|