@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
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { agent_argv, type AgentArgv } from '#scripts/agent/agent-argv'
|
|
2
2
|
import { agent_role_profile, type AgentProfile } from '#scripts/agent/agent-role-profile'
|
|
3
|
-
import { gate_tree } from '#scripts/gate/gate-tree'
|
|
4
|
-
import { scoped_green } from '#scripts/gate/scoped-green'
|
|
5
3
|
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
6
4
|
import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
|
|
7
5
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
8
6
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
9
7
|
import { openai_review_broker } from '#scripts/lane/openai-review-broker'
|
|
8
|
+
import { review_record } from '#scripts/review/review-record'
|
|
10
9
|
import { detached_launch } from './detached-launch'
|
|
11
10
|
import { run_ship_review, type RoundOutcome, type ScoredVerdict } from './run-ship-review'
|
|
11
|
+
import { run_ship_scoped, type Phase } from './run-ship-scoped'
|
|
12
12
|
|
|
13
13
|
// The side effects of `josh ship --review` (joshuafolkken/kit#2427): the round-1 review the chain used
|
|
14
14
|
// to open, launch, join, attest and record across five agent turns, run by the supervisor beside the
|
|
@@ -44,10 +44,15 @@ const ROUND_TWO_DECISION = ['review:round2', '--round-1-closed']
|
|
|
44
44
|
const ROUND_TWO_BRIEF = ['review:brief', '--round', '2']
|
|
45
45
|
const ROUND_TWO_REQUIRED = 'required'
|
|
46
46
|
const FIXED_JOIN_NOTE =
|
|
47
|
-
'the round-1 gate read the tree before the review fixes — drained, not judged; the gate
|
|
47
|
+
'the round-1 gate read the tree before the review fixes — drained, not judged; the gate re-runs once the tree is fixed.'
|
|
48
48
|
const ROUND_TWO_SKIPPED_NOTE = 'round 2 not due — nothing left to verify; shipping on.'
|
|
49
|
+
const ROUND_ONE_RECORDED_NOTE =
|
|
50
|
+
'round 1 already recorded for this issue — not reviewed again; the gate reads the fixed tree and round 2 decides after the commit.'
|
|
51
|
+
|
|
52
|
+
// The scoped pair's precondition, met by the supervisor itself rather than stopped on
|
|
53
|
+
// (joshuafolkken/kit#2500), single-sourced with the preflight and gate stages (joshuafolkken/kit#2946).
|
|
54
|
+
const { run_phases, scoped_pair } = run_ship_scoped
|
|
49
55
|
|
|
50
|
-
type Phase = () => Promise<JoshResult>
|
|
51
56
|
type PromptOf = (brief_path: string, findings_path: string) => string
|
|
52
57
|
|
|
53
58
|
function failure(out: string): JoshResult {
|
|
@@ -123,12 +128,14 @@ function current_verdict(): ReturnType<typeof run_ship_review.read_verdict> {
|
|
|
123
128
|
|
|
124
129
|
// A red join blocks unless the reviewer fixed findings in place: the background gate then read the
|
|
125
130
|
// tree before the fixes, so its verdict describes a tree that no longer exists. The join still ran to
|
|
126
|
-
// its end, so the gate stage that follows never races it.
|
|
131
|
+
// its end, so the gate stage that follows never races it. Any fix drains it, not only a round whose
|
|
132
|
+
// every finding was fixed — a partial fix moved the tree just the same, and the round then stops on its
|
|
133
|
+
// unfixed finding at the record rather than on a `Gate RED` the gate never earned (joshuafolkken/kit#2961).
|
|
127
134
|
async function join_gate(): Promise<JoshResult> {
|
|
128
135
|
const joined = await josh([RUN_REVIEW, '--join'])
|
|
129
136
|
|
|
130
137
|
if (joined.code === SUCCESS_EXIT_CODE) return joined
|
|
131
|
-
if (
|
|
138
|
+
if (!run_ship_review.has_fixes(stamp_file.read_stamp_text(paths().findings))) return joined
|
|
132
139
|
|
|
133
140
|
note(FIXED_JOIN_NOTE)
|
|
134
141
|
|
|
@@ -153,17 +160,6 @@ async function record_and_route(
|
|
|
153
160
|
return outcome.is_passing ? { code: SUCCESS_EXIT_CODE, out } : failure(out)
|
|
154
161
|
}
|
|
155
162
|
|
|
156
|
-
async function run_phases(phases: ReadonlyArray<Phase>): Promise<JoshResult> {
|
|
157
|
-
let last: JoshResult = { code: SUCCESS_EXIT_CODE, out: '' }
|
|
158
|
-
|
|
159
|
-
for (const phase of phases) {
|
|
160
|
-
last = await phase()
|
|
161
|
-
if (last.code !== SUCCESS_EXIT_CODE) return last
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return last
|
|
165
|
-
}
|
|
166
|
-
|
|
167
163
|
// A brief-minting command, then a reviewer handed what it printed.
|
|
168
164
|
function reviewed(
|
|
169
165
|
open: ReadonlyArray<string>,
|
|
@@ -185,18 +181,6 @@ function reviewed(
|
|
|
185
181
|
]
|
|
186
182
|
}
|
|
187
183
|
|
|
188
|
-
// The scoped pair's precondition, met by the supervisor itself rather than stopped on
|
|
189
|
-
// (joshuafolkken/kit#2500): only the checks with no green record for this tree run — the same
|
|
190
|
-
// question `review:brief` and the local gate refuse on — so a fresh record costs nothing and a stale
|
|
191
|
-
// or absent one costs a scoped run instead of a stop and a relaunched session. A check that genuinely
|
|
192
|
-
// fails still stops the ship, its output forwarded to the ship log.
|
|
193
|
-
async function scoped_pair(): Promise<JoshResult> {
|
|
194
|
-
const tree = await gate_tree.read_gate_tree()
|
|
195
|
-
const scripts = scoped_green.missing_scripts(tree.files, tree.base)
|
|
196
|
-
|
|
197
|
-
return await run_phases(scripts.map((script) => async () => await josh([script])))
|
|
198
|
-
}
|
|
199
|
-
|
|
200
184
|
// Fixes made in place are counted only once the scoped pair is green on the fixed tree. The reviewer is
|
|
201
185
|
// asked to leave it green; this is the check that it did, and a fix it could not get green is routed as
|
|
202
186
|
// the finding it still is — recorded, then stopped before the gate and the commit take it in.
|
|
@@ -212,7 +196,16 @@ async function round_one_record(issue: string): Promise<JoshResult> {
|
|
|
212
196
|
|
|
213
197
|
// The round-1 review, beside the gate: scoped pair → open → review → join → attest → record, stopping
|
|
214
198
|
// at the first that did not pass.
|
|
199
|
+
//
|
|
200
|
+
// **A recorded round 1 is not run again** (joshuafolkken/kit#2964). A ship relaunched with `--review`
|
|
201
|
+
// after a round-1 stop would otherwise review the whole change a second time as round 1 — a new Medium
|
|
202
|
+
// there stops it again, and round 2 after the commit makes a third. The fix delta is round 2's to
|
|
203
|
+
// verify, and `round_two_stage` asks whether it is due after the commit.
|
|
215
204
|
async function review_stage(issue: string): Promise<JoshResult> {
|
|
205
|
+
const recorded = await review_record.check(Number(issue))
|
|
206
|
+
|
|
207
|
+
if (recorded.status === 'ok') return { code: SUCCESS_EXIT_CODE, out: ROUND_ONE_RECORDED_NOTE }
|
|
208
|
+
|
|
216
209
|
return await run_phases([
|
|
217
210
|
scoped_pair,
|
|
218
211
|
...reviewed([RUN_REVIEW], run_ship_review.reviewer_prompt, issue, '1'),
|
|
@@ -242,6 +235,6 @@ async function round_two_stage(issue: string): Promise<JoshResult> {
|
|
|
242
235
|
])
|
|
243
236
|
}
|
|
244
237
|
|
|
245
|
-
const run_ship_review_steps = {
|
|
238
|
+
const run_ship_review_steps = { review_stage, round_two_stage }
|
|
246
239
|
|
|
247
240
|
export { run_ship_review_steps }
|
|
@@ -154,6 +154,24 @@ function round_one_outcome(verdict: ScoredVerdict): RoundOutcome {
|
|
|
154
154
|
return { is_passing: true, note: verdict.kind === VERDICT.FIXED ? FIXED_NOTE : CLEAN_NOTE }
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
// Whether a findings file records a clean round 1 (joshuafolkken/kit#2945). A resumed round 1 narrows to
|
|
158
|
+
// the delta only past a review that found nothing to fix. A blocking one has a finding in a file the
|
|
159
|
+
// delta may not touch. A fixed one approved its own edits, not the briefed tree the delta is measured
|
|
160
|
+
// from, so a file reverted to that tree would drop out of the delta with its finding back in it.
|
|
161
|
+
function is_clean_round_one(text: string | undefined): boolean {
|
|
162
|
+
return read_verdict(text).kind === VERDICT.CLEAN
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Whether the reviewer edited the tree — any finding marked fixed, whether or not another one still
|
|
166
|
+
// blocks (joshuafolkken/kit#2961). A partial fix moves the tree the background gate read as surely as a
|
|
167
|
+
// full one, so the join reads it red either way; keyed off the verdict kind instead, a round that fixed
|
|
168
|
+
// one Medium and left another stopped at a misleading `Gate RED` before its own blocking note.
|
|
169
|
+
function has_fixes(text: string | undefined): boolean {
|
|
170
|
+
if (text === undefined) return false
|
|
171
|
+
|
|
172
|
+
return spec_findings(text).some((finding) => finding.is_fixed)
|
|
173
|
+
}
|
|
174
|
+
|
|
157
175
|
// Round 2 is final and reads only, so it passes clean or Low-only alone — a fix it made would itself be
|
|
158
176
|
// unreviewed.
|
|
159
177
|
function round_two_outcome(verdict: ScoredVerdict): RoundOutcome {
|
|
@@ -166,6 +184,8 @@ const run_ship_review = {
|
|
|
166
184
|
FIXED_PREFIX,
|
|
167
185
|
UNVERIFIED_OUTCOME,
|
|
168
186
|
VERDICT,
|
|
187
|
+
has_fixes,
|
|
188
|
+
is_clean_round_one,
|
|
169
189
|
read_verdict,
|
|
170
190
|
reviewer_prompt,
|
|
171
191
|
round_one_outcome,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { gate_tree } from '#scripts/gate/gate-tree'
|
|
2
|
+
import { scoped_green } from '#scripts/gate/scoped-green'
|
|
3
|
+
import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
|
|
4
|
+
|
|
5
|
+
// The scoped pair `josh ship` meets itself rather than stops on (joshuafolkken/kit#2500), shared by
|
|
6
|
+
// every stage that needs a green record for this tree (joshuafolkken/kit#2946): the preflight stage at
|
|
7
|
+
// the start, the review rounds, and the gate stage — a reviewer may have edited the tree after round
|
|
8
|
+
// 1's pair ran, and `josh gate` refuses a tree with no green record.
|
|
9
|
+
|
|
10
|
+
const SUCCESS_EXIT_CODE = 0
|
|
11
|
+
const should_forward_stderr = true
|
|
12
|
+
|
|
13
|
+
type Phase = () => Promise<JoshResult>
|
|
14
|
+
|
|
15
|
+
async function run_phases(phases: ReadonlyArray<Phase>): Promise<JoshResult> {
|
|
16
|
+
let last: JoshResult = { code: SUCCESS_EXIT_CODE, out: '' }
|
|
17
|
+
|
|
18
|
+
for (const phase of phases) {
|
|
19
|
+
// eslint-disable-next-line no-await-in-loop -- phases run in order and the first failure stops the rest
|
|
20
|
+
last = await phase()
|
|
21
|
+
if (last.code !== SUCCESS_EXIT_CODE) return last
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return last
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Only the checks with no green record for this tree run — the same question `review:brief` and the
|
|
28
|
+
// local gate refuse on — so a fresh record costs nothing and a stale or absent one costs a scoped run
|
|
29
|
+
// instead of a stop and a relaunched session. A check that genuinely fails still stops the ship, its
|
|
30
|
+
// output forwarded to the ship log.
|
|
31
|
+
async function scoped_pair(): Promise<JoshResult> {
|
|
32
|
+
const tree = await gate_tree.read_gate_tree()
|
|
33
|
+
const scripts = scoped_green.missing_scripts(tree.files, tree.base)
|
|
34
|
+
|
|
35
|
+
return await run_phases(
|
|
36
|
+
scripts.map(
|
|
37
|
+
(script) => async () => await josh_command.josh_run([script], should_forward_stderr),
|
|
38
|
+
),
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const run_ship_scoped = { run_phases, scoped_pair }
|
|
43
|
+
|
|
44
|
+
export type { Phase }
|
|
45
|
+
export { run_ship_scoped }
|
|
@@ -17,6 +17,7 @@ import { z } from 'zod'
|
|
|
17
17
|
// re-run on an unchanged tree a reuse rather than a second execution. No quality gate is folded away.
|
|
18
18
|
|
|
19
19
|
const STAGE = {
|
|
20
|
+
PREFLIGHT: 'preflight',
|
|
20
21
|
REVIEW: 'review',
|
|
21
22
|
GATE: 'gate',
|
|
22
23
|
COMMIT: 'commit',
|
|
@@ -78,7 +79,7 @@ function mark_done(target: string, stage: Stage): void {
|
|
|
78
79
|
stamp_file.replace_stamp(target, { done: [...done] })
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
// Removed once the report stage completes, so a later ship of the same issue starts from the
|
|
82
|
+
// Removed once the report stage completes, so a later ship of the same issue starts from the preflight.
|
|
82
83
|
function clear(target: string): void {
|
|
83
84
|
stamp_file.remove_stamp(target)
|
|
84
85
|
}
|
|
@@ -90,6 +91,9 @@ function is_shipped(state: ShipState): boolean {
|
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
const DONE_BY: Record<Stage, (done: ReadonlySet<string>, state: ShipState) => boolean> = {
|
|
94
|
+
// The preflight (joshuafolkken/kit#2946) asks what the commit stage would refuse on, so a commit is
|
|
95
|
+
// its output as it is the gate's; a resumed commit stage still asks `git -y`'s own preflight.
|
|
96
|
+
[STAGE.PREFLIGHT]: (_done, state) => state.is_merged || state.is_committed,
|
|
93
97
|
// The `--review` round (joshuafolkken/kit#2427) precedes the commit, so a commit is its output as it
|
|
94
98
|
// is the gate's. A record alone is not honored: before a commit the tree may have been edited since
|
|
95
99
|
// the recorded round, and only a commit pins the tree that round read.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
|
|
2
|
+
import { run_ship } from './run-ship'
|
|
3
|
+
import { run_ship_preflight } from './run-ship-preflight'
|
|
4
|
+
import { run_ship_review_steps } from './run-ship-review-steps'
|
|
5
|
+
import { run_ship_scoped } from './run-ship-scoped'
|
|
6
|
+
import { run_ship_stage, type ShipState, type Stage } from './run-ship-stage'
|
|
7
|
+
|
|
8
|
+
// The stages `josh ship` runs, in the order a change ships (joshuafolkken/kit#2398), kept apart from the
|
|
9
|
+
// chaining CLI so the order is read in one place.
|
|
10
|
+
|
|
11
|
+
const should_forward_stderr = true
|
|
12
|
+
|
|
13
|
+
interface ShipArguments {
|
|
14
|
+
title: string
|
|
15
|
+
number: string
|
|
16
|
+
notify: ReadonlyArray<string>
|
|
17
|
+
body: ReadonlyArray<string>
|
|
18
|
+
body_path: string | undefined
|
|
19
|
+
cites: ReadonlyArray<string>
|
|
20
|
+
is_review: boolean
|
|
21
|
+
is_detach: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface Step {
|
|
25
|
+
stage: Stage
|
|
26
|
+
header: string
|
|
27
|
+
run: (args: ShipArguments, state: ShipState) => Promise<JoshResult>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const { STAGE } = run_ship_stage
|
|
31
|
+
|
|
32
|
+
async function josh(argv: ReadonlyArray<string>): Promise<JoshResult> {
|
|
33
|
+
return await josh_command.josh_run(argv, should_forward_stderr)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// joshuafolkken/kit#2946: the pull request's preconditions and the scoped pair are asked first, so a
|
|
37
|
+
// stop they would cause lands before the review and the gate rather than after them.
|
|
38
|
+
const PREFLIGHT_STEP: Step = {
|
|
39
|
+
stage: STAGE.PREFLIGHT,
|
|
40
|
+
header: run_ship.PREFLIGHT_HEADER,
|
|
41
|
+
run: async (args) =>
|
|
42
|
+
await run_ship_preflight.stage({ title: args.title, body_path: args.body_path }),
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// The gate before the commit, the commit/push/PR before the merge. The gate meets the scoped pair
|
|
46
|
+
// first: a round-1 reviewer may have edited the tree since the preflight, and `josh gate` refuses a tree
|
|
47
|
+
// with no green record (joshuafolkken/kit#2946). The commit step carries the `--skip-*` flags a resumed
|
|
48
|
+
// ship needs, so an existing commit or push is never made twice.
|
|
49
|
+
const COMMIT_STEPS: ReadonlyArray<Step> = [
|
|
50
|
+
{
|
|
51
|
+
stage: STAGE.GATE,
|
|
52
|
+
header: run_ship.GATE_HEADER,
|
|
53
|
+
run: async () =>
|
|
54
|
+
await run_ship_scoped.run_phases([
|
|
55
|
+
run_ship_scoped.scoped_pair,
|
|
56
|
+
async () => await josh(['gate']),
|
|
57
|
+
]),
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
stage: STAGE.COMMIT,
|
|
61
|
+
header: run_ship.COMMIT_HEADER,
|
|
62
|
+
run: async (args, state) =>
|
|
63
|
+
await josh(['git', '-y', ...run_ship_stage.commit_flags(state), ...args.body, args.title]),
|
|
64
|
+
},
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
// The merge before the report bookkeeping.
|
|
68
|
+
const MERGE_STEPS: ReadonlyArray<Step> = [
|
|
69
|
+
{
|
|
70
|
+
stage: STAGE.FOLLOWUP,
|
|
71
|
+
header: run_ship.FOLLOWUP_HEADER,
|
|
72
|
+
run: async (args) => await josh(['followup', args.title, ...args.notify]),
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
stage: STAGE.REPORT,
|
|
76
|
+
header: run_ship.REPORT_HEADER,
|
|
77
|
+
run: async (args) => await josh(['run:tail', args.number, ...args.cites]),
|
|
78
|
+
},
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
// `--review` (joshuafolkken/kit#2427) puts the supervised round-1 review in front of the gate: it
|
|
82
|
+
// launches the gate itself, so the gate stage that follows reuses that tree's green record. It also
|
|
83
|
+
// puts the round-2 pass between the commit and the followup (joshuafolkken/kit#2489), so the PR opens
|
|
84
|
+
// between the rounds and round 2 runs beside CI — a no-op when round 1 left no fix delta.
|
|
85
|
+
const REVIEW_STEP: Step = {
|
|
86
|
+
stage: STAGE.REVIEW,
|
|
87
|
+
header: run_ship.REVIEW_HEADER,
|
|
88
|
+
run: async (args) => await run_ship_review_steps.review_stage(args.number),
|
|
89
|
+
}
|
|
90
|
+
const ROUND_TWO_STEP: Step = {
|
|
91
|
+
stage: STAGE.ROUND_TWO,
|
|
92
|
+
header: run_ship.ROUND_TWO_HEADER,
|
|
93
|
+
run: async (args) => await run_ship_review_steps.round_two_stage(args.number),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function steps(args: ShipArguments): ReadonlyArray<Step> {
|
|
97
|
+
if (!args.is_review) return [PREFLIGHT_STEP, ...COMMIT_STEPS, ...MERGE_STEPS]
|
|
98
|
+
|
|
99
|
+
return [PREFLIGHT_STEP, REVIEW_STEP, ...COMMIT_STEPS, ROUND_TWO_STEP, ...MERGE_STEPS]
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const run_ship_steps = { PREFLIGHT_STEP, steps }
|
|
103
|
+
|
|
104
|
+
export type { ShipArguments, Step }
|
|
105
|
+
export { run_ship_steps }
|
package/scripts/run/run-ship.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// `run:tail`, ship stops at the first failed step: a red gate must never reach the commit, so the
|
|
10
10
|
// composite ends at the failure, and the report names the step that failed so the run reads only it.
|
|
11
11
|
|
|
12
|
+
const PREFLIGHT_HEADER = '=== preflight ==='
|
|
12
13
|
const REVIEW_HEADER = '=== review ==='
|
|
13
14
|
const GATE_HEADER = '=== gate ==='
|
|
14
15
|
const COMMIT_HEADER = '=== commit/push/PR ==='
|
|
@@ -63,12 +64,12 @@ const run_ship = {
|
|
|
63
64
|
COMMIT_HEADER,
|
|
64
65
|
FOLLOWUP_HEADER,
|
|
65
66
|
GATE_HEADER,
|
|
67
|
+
PREFLIGHT_HEADER,
|
|
66
68
|
REPORT_HEADER,
|
|
67
69
|
REVIEW_HEADER,
|
|
68
70
|
ROUND_TWO_HEADER,
|
|
69
71
|
SKIPPED_BODY,
|
|
70
72
|
STOPPED_PREFIX,
|
|
71
|
-
SUCCESS_EXIT_CODE,
|
|
72
73
|
exit_code,
|
|
73
74
|
failed_section,
|
|
74
75
|
format_report,
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { has_label_name, PLANNED_LABEL } from '#scripts/issue/issue-labels'
|
|
2
|
+
import { issue_state_cli, type StateRead } from '#scripts/issue/issue-state-cli'
|
|
3
|
+
import { run_halfrun_resume } from './run-halfrun-resume'
|
|
4
|
+
import { run_prrun_resume, type PrrunToken } from './run-prrun-resume'
|
|
5
|
+
import { run_stage, type StageState } from './run-stage'
|
|
6
|
+
|
|
7
|
+
// The reading half of the stage ladder (joshuafolkken/kit#3042): the facts `run_stage.state_of` folds
|
|
8
|
+
// into one state, each read from where the stage that produced it left it — never from the
|
|
9
|
+
// conversation. A closed issue and the `run:planned` label come from GitHub; a `halfrun` stop and a `prrun`
|
|
10
|
+
// stop come from the stop's own mark on the tree's hold (`run-halfrun-resume.ts`,
|
|
11
|
+
// `run-prrun-resume.ts`).
|
|
12
|
+
|
|
13
|
+
const CLOSED = 'CLOSED'
|
|
14
|
+
|
|
15
|
+
interface StageRead {
|
|
16
|
+
state: StageState
|
|
17
|
+
// The `prrun` stop's resume token, kept so the entry acts on it without reading the pull request
|
|
18
|
+
// again; `undefined` when no `prrun` stop is recorded for the issue.
|
|
19
|
+
prrun_token: PrrunToken | undefined
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function is_closed(read: StateRead): boolean {
|
|
23
|
+
return read.kind === 'state' && read.state.state === CLOSED
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function is_planned(read: StateRead): boolean {
|
|
27
|
+
return read.kind === 'state' && has_label_name(read.state.labels, PLANNED_LABEL)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// The two stops are one hold record, so at most one is present; the `prrun` one is asked only when the
|
|
31
|
+
// `halfrun` one is not, which spares its pull-request read.
|
|
32
|
+
async function read_stop(
|
|
33
|
+
issue: string,
|
|
34
|
+
): Promise<{ is_halfrun_stopped: boolean; prrun_token: PrrunToken | undefined }> {
|
|
35
|
+
if (await run_halfrun_resume.is_pending(issue)) {
|
|
36
|
+
return { is_halfrun_stopped: true, prrun_token: undefined }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return { is_halfrun_stopped: false, prrun_token: await run_prrun_resume.resume_token(issue) }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// An unreadable issue reads as neither closed nor planned: the ordinary entry that follows reads it
|
|
43
|
+
// again and answers `unknown` for it, exactly as before the ladder existed.
|
|
44
|
+
async function read_stage(issue: string): Promise<StageRead> {
|
|
45
|
+
const [issue_read, stop] = await Promise.all([
|
|
46
|
+
issue_state_cli.read_issue(issue),
|
|
47
|
+
read_stop(issue),
|
|
48
|
+
])
|
|
49
|
+
const state = run_stage.state_of({
|
|
50
|
+
is_closed: is_closed(issue_read),
|
|
51
|
+
is_prrun_stopped: stop.prrun_token !== undefined,
|
|
52
|
+
is_halfrun_stopped: stop.is_halfrun_stopped,
|
|
53
|
+
is_planned: is_planned(issue_read),
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
return { state, prrun_token: stop.prrun_token }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const run_stage_read = { read_stage }
|
|
60
|
+
|
|
61
|
+
export type { StageRead }
|
|
62
|
+
export { run_stage_read }
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// joshuafolkken/kit#3042: the workflow commands form a ladder — `kickoff` → `halfrun` → `prrun` →
|
|
2
|
+
// `fullrun` — and **the command typed decides only how far a run goes; where it starts is read off the
|
|
3
|
+
// issue**. A run that finds work already done resumes after it rather than redoing it, and a command
|
|
4
|
+
// whose stopping point the issue has already reached reports that and stops.
|
|
5
|
+
//
|
|
6
|
+
// This module is the pure half of that rule: the five states an issue can be found in, the four
|
|
7
|
+
// commands, and the one table that maps a (state, command) pair to a start and an end. `run:entry` reads
|
|
8
|
+
// the state (`run-stage-read.ts`) and branches on the answer; the stage table in
|
|
9
|
+
// `docs/how-to/run-issues.md` and each stop's `Next:` line are pinned to this module by
|
|
10
|
+
// `run-stage-document.test.ts`, so the prose cannot drift from what the entry does.
|
|
11
|
+
|
|
12
|
+
const KICKOFF = 'kickoff'
|
|
13
|
+
const HALFRUN = 'halfrun'
|
|
14
|
+
const PRRUN = 'prrun'
|
|
15
|
+
const FULLRUN = 'fullrun'
|
|
16
|
+
|
|
17
|
+
// In ladder order: a command's index plus one is the state rank it brings an issue to.
|
|
18
|
+
const COMMANDS = [KICKOFF, HALFRUN, PRRUN, FULLRUN] as const
|
|
19
|
+
|
|
20
|
+
type StageCommand = (typeof COMMANDS)[number]
|
|
21
|
+
|
|
22
|
+
// What `run:entry` serves when no command is named — the one it served alone before the ladder existed.
|
|
23
|
+
const DEFAULT_COMMAND: StageCommand = FULLRUN
|
|
24
|
+
|
|
25
|
+
const FRESH = 'fresh'
|
|
26
|
+
const PLANNED = 'planned'
|
|
27
|
+
const HALFRUN_STOPPED = 'halfrun-stopped'
|
|
28
|
+
const PRRUN_STOPPED = 'prrun-stopped'
|
|
29
|
+
const MERGED = 'merged'
|
|
30
|
+
|
|
31
|
+
// In ladder order: a state's index is how many rungs the issue has already climbed.
|
|
32
|
+
const STATES = [FRESH, PLANNED, HALFRUN_STOPPED, PRRUN_STOPPED, MERGED] as const
|
|
33
|
+
|
|
34
|
+
type StageState = (typeof STATES)[number]
|
|
35
|
+
|
|
36
|
+
const REACHED = 'reached'
|
|
37
|
+
|
|
38
|
+
// Where a run picks the issue up from each state — the first piece of work not yet done. A merged issue
|
|
39
|
+
// has none: every command has reached it.
|
|
40
|
+
const STARTS: Readonly<Record<StageState, string>> = {
|
|
41
|
+
[FRESH]: 'plan',
|
|
42
|
+
[PLANNED]: 'implement',
|
|
43
|
+
[HALFRUN_STOPPED]: 'gate',
|
|
44
|
+
[PRRUN_STOPPED]: 'followup',
|
|
45
|
+
[MERGED]: REACHED,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Every start a decision can print, in ladder order — the `run:entry` oracle's vocabulary.
|
|
49
|
+
const START_TOKENS: ReadonlyArray<string> = [...new Set(Object.values(STARTS))]
|
|
50
|
+
|
|
51
|
+
// Where each command stops.
|
|
52
|
+
const ENDS: Readonly<Record<StageCommand, string>> = {
|
|
53
|
+
[KICKOFF]: 'plan posted',
|
|
54
|
+
[HALFRUN]: 'gated, before the commit',
|
|
55
|
+
[PRRUN]: 'green, mergeable PR',
|
|
56
|
+
[FULLRUN]: 'merged',
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const NEXT_PREFIX = 'Next: '
|
|
60
|
+
const NEXT_SEPARATOR = ' | '
|
|
61
|
+
const STATE_HEADER = 'Issue state'
|
|
62
|
+
const CELL_ARROW = ' → '
|
|
63
|
+
const REACHED_CELL = 'reached — report and stop'
|
|
64
|
+
|
|
65
|
+
interface StageFacts {
|
|
66
|
+
is_closed: boolean
|
|
67
|
+
is_prrun_stopped: boolean
|
|
68
|
+
is_halfrun_stopped: boolean
|
|
69
|
+
is_planned: boolean
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface StageDecision {
|
|
73
|
+
state: StageState
|
|
74
|
+
command: StageCommand
|
|
75
|
+
// The first piece of work the run does, or `reached` when there is none left for this command.
|
|
76
|
+
start: string
|
|
77
|
+
end: string
|
|
78
|
+
is_reached: boolean
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function to_command(value: string | undefined): StageCommand | undefined {
|
|
82
|
+
return COMMANDS.find((command) => command === value)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// The furthest rung the facts show, so a closed issue is merged whatever its hold still says.
|
|
86
|
+
function state_of(facts: StageFacts): StageState {
|
|
87
|
+
if (facts.is_closed) return MERGED
|
|
88
|
+
if (facts.is_prrun_stopped) return PRRUN_STOPPED
|
|
89
|
+
if (facts.is_halfrun_stopped) return HALFRUN_STOPPED
|
|
90
|
+
|
|
91
|
+
return facts.is_planned ? PLANNED : FRESH
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function decide(state: StageState, command: StageCommand): StageDecision {
|
|
95
|
+
const is_reached = STATES.indexOf(state) > COMMANDS.indexOf(command)
|
|
96
|
+
const start = is_reached ? REACHED : STARTS[state]
|
|
97
|
+
|
|
98
|
+
return { state, command, start, end: ENDS[command], is_reached }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// The commands that go further than `command`, nearest first — what a stop offers next.
|
|
102
|
+
function next_commands(command: StageCommand): ReadonlyArray<StageCommand> {
|
|
103
|
+
return COMMANDS.slice(COMMANDS.indexOf(command) + 1)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// The `Next:` line a stop's Telegram and report carry, e.g. `Next: prrun #<N> | fullrun #<N>`.
|
|
107
|
+
function next_line(command: StageCommand, issue: string): string {
|
|
108
|
+
const commands = next_commands(command).map((next) => `${next} #${issue}`)
|
|
109
|
+
|
|
110
|
+
return `${NEXT_PREFIX}${commands.join(NEXT_SEPARATOR)}`
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function format_decision(issue: string, decision: StageDecision): string {
|
|
114
|
+
const fields = [`at: ${decision.state}`, `to: ${decision.command}`, `start: ${decision.start}`]
|
|
115
|
+
|
|
116
|
+
return `stage #${issue} — ${fields.join(' · ')}`
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function cell(state: StageState, command: StageCommand): string {
|
|
120
|
+
const decision = decide(state, command)
|
|
121
|
+
|
|
122
|
+
return decision.is_reached ? REACHED_CELL : `${decision.start}${CELL_ARROW}${decision.end}`
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// The stage table as rows of cells, header first — the shape both documents carry.
|
|
126
|
+
function table_rows(): ReadonlyArray<ReadonlyArray<string>> {
|
|
127
|
+
const header = [STATE_HEADER, ...COMMANDS.map((command) => `\`${command}\``)]
|
|
128
|
+
const rows = STATES.map((state) => [
|
|
129
|
+
`\`${state}\``,
|
|
130
|
+
...COMMANDS.map((command) => cell(state, command)),
|
|
131
|
+
])
|
|
132
|
+
|
|
133
|
+
return [header, ...rows]
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const run_stage = {
|
|
137
|
+
COMMANDS,
|
|
138
|
+
DEFAULT_COMMAND,
|
|
139
|
+
FRESH,
|
|
140
|
+
HALFRUN,
|
|
141
|
+
HALFRUN_STOPPED,
|
|
142
|
+
KICKOFF,
|
|
143
|
+
MERGED,
|
|
144
|
+
PLANNED,
|
|
145
|
+
PRRUN,
|
|
146
|
+
PRRUN_STOPPED,
|
|
147
|
+
REACHED,
|
|
148
|
+
START_TOKENS,
|
|
149
|
+
STATES,
|
|
150
|
+
decide,
|
|
151
|
+
format_decision,
|
|
152
|
+
next_commands,
|
|
153
|
+
next_line,
|
|
154
|
+
state_of,
|
|
155
|
+
table_rows,
|
|
156
|
+
to_command,
|
|
157
|
+
} as const
|
|
158
|
+
|
|
159
|
+
export type { StageCommand, StageDecision, StageFacts, StageState }
|
|
160
|
+
export { run_stage }
|
|
@@ -168,7 +168,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
168
168
|
process.exitCode = await run(argv)
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
const run_status_cli = {
|
|
171
|
+
const run_status_cli = { parse, run }
|
|
172
172
|
|
|
173
173
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
174
174
|
|
|
@@ -44,18 +44,22 @@ function is_handed_off_here(carry: CarryRead): boolean {
|
|
|
44
44
|
return run_headless.is_owned_here(carry.carry, lane_reap.own_ancestry)
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
const UNREADABLE_RUN: RunReads = {
|
|
48
|
+
carry_kind: 'unreadable',
|
|
49
|
+
is_retrospective_done: false,
|
|
50
|
+
is_at_cut_cap: false,
|
|
51
|
+
is_handed_off: false,
|
|
52
|
+
last_event: undefined,
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
// The run-level reads, keyed on the common git directory both the carry and the event stream share. A
|
|
48
56
|
// directory that cannot be read leaves the position unknowable, which `next_action` answers `unknown`.
|
|
49
|
-
function read_run(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
is_handed_off: false,
|
|
56
|
-
last_event: undefined,
|
|
57
|
-
}
|
|
58
|
-
}
|
|
57
|
+
function read_run(
|
|
58
|
+
directory: string | undefined,
|
|
59
|
+
issue_number: string,
|
|
60
|
+
is_lane_child: boolean,
|
|
61
|
+
): RunReads {
|
|
62
|
+
if (directory === undefined) return UNREADABLE_RUN
|
|
59
63
|
|
|
60
64
|
const carry = run_carry.read_carry(run_carry.carry_path(directory))
|
|
61
65
|
const events = run_event_stream.read_events(run_event_stream.target_of(directory))
|
|
@@ -63,11 +67,13 @@ function read_run(directory: string | undefined, issue_number: string): RunReads
|
|
|
63
67
|
// invocation left on the stream must not be read as this run's position (joshuafolkken/kit#2395). The
|
|
64
68
|
// observed defect was a `run:step` that printed `wait` on a fresh run because an old `child-launch` was
|
|
65
69
|
// still the stream's tail. Another issue's detached ship supervisor is left out the same way
|
|
66
|
-
// (joshuafolkken/kit#2428)
|
|
70
|
+
// (joshuafolkken/kit#2428), and so — for a lane child — is every event that does not name its own issue
|
|
71
|
+
// (joshuafolkken/kit#3039).
|
|
67
72
|
const last = run_event_scope.last_issue_event(
|
|
68
73
|
events,
|
|
69
74
|
run_event_scope.scope_of(carry),
|
|
70
75
|
issue_number,
|
|
76
|
+
is_lane_child,
|
|
71
77
|
)
|
|
72
78
|
|
|
73
79
|
return {
|
|
@@ -82,7 +88,8 @@ function read_run(directory: string | undefined, issue_number: string): RunReads
|
|
|
82
88
|
async function gather(issue_number: string): Promise<StepInput> {
|
|
83
89
|
const reads = await run_prep_cli.gather(issue_number)
|
|
84
90
|
const parts = run_prep_cli.to_parts(issue_number, reads)
|
|
85
|
-
const
|
|
91
|
+
const is_lane_child = lane_child_marker.is_child_of(process.cwd())
|
|
92
|
+
const run_reads = read_run(await run_carry.repository_directory(), issue_number, is_lane_child)
|
|
86
93
|
|
|
87
94
|
return {
|
|
88
95
|
issue_number,
|
|
@@ -94,7 +101,7 @@ async function gather(issue_number: string): Promise<StepInput> {
|
|
|
94
101
|
is_retrospective_done: run_reads.is_retrospective_done,
|
|
95
102
|
is_at_cut_cap: run_reads.is_at_cut_cap,
|
|
96
103
|
is_handed_off: run_reads.is_handed_off,
|
|
97
|
-
is_lane_child
|
|
104
|
+
is_lane_child,
|
|
98
105
|
is_consumer: doctor_consumer.is_kit_consumer(find_package_directory(process.cwd())),
|
|
99
106
|
// Read here rather than in `run-step.ts` so the position logic stays a pure function of its input.
|
|
100
107
|
is_retrospective_enabled: run_retrospective.is_enabled(),
|
|
@@ -128,7 +135,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
128
135
|
process.exitCode = await run(argv)
|
|
129
136
|
}
|
|
130
137
|
|
|
131
|
-
const run_step_cli = {
|
|
138
|
+
const run_step_cli = { run }
|
|
132
139
|
|
|
133
140
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
134
141
|
|
package/scripts/run/run-step.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { git_stash } from '#scripts/git/git-stash'
|
|
1
|
+
import { git_stash } from '#scripts/git/stash/git-stash'
|
|
2
2
|
import { latest_scope_cli } from '#scripts/version/latest-scope-cli'
|
|
3
3
|
import type { CarryRead } from './run-carry'
|
|
4
4
|
import { run_event_stream } from './run-event-stream'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { telegram_notify } from '#scripts/
|
|
1
|
+
import { telegram_notify } from '#scripts/notify/telegram-notify'
|
|
2
2
|
import type { CarryRead } from './run-carry'
|
|
3
3
|
|
|
4
4
|
// **A `backlogrun` that halts because a person is needed used to reach nobody once the session was
|
|
@@ -43,8 +43,6 @@ async function announce(notice: StopNotice): Promise<boolean> {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const run_stop_notify = {
|
|
46
|
-
STOP_RECOVERY,
|
|
47
|
-
STOP_TITLE,
|
|
48
46
|
announce,
|
|
49
47
|
plan,
|
|
50
48
|
}
|