@joshuafolkken/kit 1.1514.0 → 1.1784.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -1
- package/.claude/settings.json +5 -5
- package/.claude/skills/epic-commands/SKILL.md +26 -65
- package/.claude/skills/epic-commands/epic-bundle.md +3 -1
- package/.claude/skills/workflow-commands/SKILL.md +5 -5
- package/.claude/skills/workflow-commands/background-commands.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
- package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +13 -7
- package/.claude/skills/workflow-commands/delegation.md +6 -5
- package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
- package/.claude/skills/workflow-commands/followup.md +9 -31
- package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
- package/.claude/skills/workflow-commands/fullrun.md +2 -2
- package/.claude/skills/workflow-commands/halfrun.md +17 -25
- package/.claude/skills/workflow-commands/issue-comments.md +16 -12
- package/.claude/skills/workflow-commands/issue-scout.md +2 -2
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +7 -12
- package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
- package/.claude/skills/workflow-commands/observation-filing.md +4 -36
- package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
- package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
- package/.claude/skills/workflow-commands/prerequisite.md +10 -16
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +3 -7
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +13 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-node/action.yml +9 -0
- package/.github/actions/setup-pnpm/action.yml +1 -1
- package/.github/dependabot.yml +16 -0
- package/.github/release.yml +0 -2
- package/.github/workflows/ci.yml +120 -10
- package/.github/workflows/publish.yml +8 -1
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +3 -7
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +3 -7
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
- package/dist/commands/read-set-cli.js +1867 -0
- package/dist/commands/run-prep-main.js +21653 -0
- package/dist/commands/run-step-cli.js +23880 -0
- package/dist/config-merge/index.js +5 -1
- package/dist/hooks/audit-provision.js +20 -35
- package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
- package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
- package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
- package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
- package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -22
- package/dist/hooks/format-edited.js +5 -6
- package/dist/hooks/inputs.json +443 -317
- package/dist/hooks/pretool-guard.js +7 -25
- package/dist/hooks/session-lang.js +44 -51
- package/dist/hooks/stop-guard.js +7716 -2187
- package/dist/josh.js +6002 -3583
- package/dist/self-sync-guard/index.js +74 -10
- package/dist/version/index.js +115 -406
- package/eslint/base.js +1 -1
- package/lefthook/base.yml +3 -1
- package/package.json +10 -48
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -7
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +33 -16
- package/prompts/collaboration-workflow/lane-instructions.md +1 -2
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +4 -6
- package/prompts/collaboration-workflow/output-bounds.md +2 -7
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +5 -0
- package/prompts/collaboration-workflow/report-format.md +31 -60
- package/prompts/collaboration-workflow/residency.md +2 -2
- package/prompts/collaboration-workflow/shell-body.md +6 -16
- package/prompts/collaboration-workflow/turn-batching.md +0 -2
- package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
- package/prompts/collaboration-workflow/wip-cap.md +1 -1
- package/prompts/collaboration-workflow.md +3 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +41 -21
- package/prompts/testing-guide.md +8 -43
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +14 -16
- package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
- package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
- package/scripts/auto-ok/auto-ok-judge.ts +13 -2
- package/scripts/auto-ok/auto-ok-main.ts +17 -0
- package/scripts/backlog/backlog-arrival.ts +14 -3
- package/scripts/backlog/backlog-budget-cli.ts +7 -33
- package/scripts/backlog/backlog-budget-main.ts +16 -0
- package/scripts/backlog/backlog-budget.ts +2 -3
- package/scripts/backlog/backlog-defect-priority.ts +4 -3
- package/scripts/backlog/backlog-drive-adopt.ts +67 -0
- package/scripts/backlog/backlog-drive-args.ts +4 -5
- package/scripts/backlog/backlog-drive-cli.ts +113 -28
- package/scripts/backlog/backlog-drive-hold.ts +162 -0
- package/scripts/backlog/backlog-drive-idle.ts +151 -0
- package/scripts/backlog/backlog-drive-judge.ts +25 -0
- package/scripts/backlog/backlog-drive-memory.ts +126 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
- package/scripts/backlog/backlog-drive-named.ts +53 -6
- package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
- package/scripts/backlog/backlog-drive-paused.ts +169 -0
- package/scripts/backlog/backlog-drive-restore.ts +30 -7
- package/scripts/backlog/backlog-drive-seats.ts +18 -8
- package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
- package/scripts/backlog/backlog-drive.ts +79 -75
- package/scripts/backlog/backlog-next-main.ts +16 -0
- package/scripts/backlog/backlog-next-shared.ts +73 -0
- package/scripts/backlog/backlog-next.ts +48 -16
- package/scripts/backlog/backlog-occupied.ts +52 -39
- package/scripts/backlog/backlog-offer-cli.ts +6 -21
- package/scripts/backlog/backlog-offer-exclude.ts +15 -0
- package/scripts/backlog/backlog-offer-main.ts +12 -0
- package/scripts/backlog/backlog-offer.ts +36 -3
- package/scripts/backlog/backlog-overlap.ts +22 -4
- package/scripts/backlog/backlog-plan-read.ts +6 -2
- package/scripts/backlog/backlog-plan.ts +18 -4
- package/scripts/backlog/backlog-pool.ts +10 -10
- package/scripts/backlog/backlog-rank.ts +10 -2
- package/scripts/backlog/backlog-ready.ts +112 -30
- package/scripts/backlog/backlog-stalled-detect.ts +109 -36
- package/scripts/backlog/backlog-stalled.ts +52 -16
- package/scripts/backlog/backlog-wait-cause.ts +86 -0
- package/scripts/backlog/backlog-waves.ts +39 -13
- package/scripts/backlog/backlogrun-args.ts +19 -7
- package/scripts/backlog/backlogrun-cli.ts +19 -5
- package/scripts/backlog/backlogrun-launch.ts +6 -0
- package/scripts/backlog/backlogrun-restart.ts +97 -0
- package/scripts/backlog/backlogrun-stop.ts +79 -7
- package/scripts/behavior/behavior-cli.ts +2 -2
- package/scripts/behavior/behavior-rules.ts +47 -24
- package/scripts/build/build-bin.ts +2 -16
- package/scripts/build/build-claude-md.ts +0 -7
- package/scripts/build/build-commands.ts +0 -13
- package/scripts/build/build-hooks.ts +49 -48
- package/scripts/build/hook-bundle-stamp.ts +29 -11
- package/scripts/build/local-bin.ts +1 -1
- package/scripts/cases/cases-cli.ts +25 -13
- package/scripts/cases/cases-interaction-scan.ts +134 -0
- package/scripts/cases/cases-interaction.ts +183 -0
- package/scripts/cases/cases-logic.ts +39 -6
- package/scripts/ci/pr-classification-main.ts +18 -0
- package/scripts/ci/pr-classification.ts +10 -17
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/cost-runtime/cost-blocks.ts +22 -37
- package/scripts/cost-runtime/cost-cli.ts +31 -14
- package/scripts/cost-runtime/cost-main.ts +12 -0
- package/scripts/cost-runtime/cost-transcript.ts +1 -0
- package/scripts/delegation/delegation-policy.ts +17 -4
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/investigation-guard.ts +0 -8
- package/scripts/delegation/investigation-reads.ts +3 -4
- package/scripts/dependabot/dependabot-cooldown.ts +194 -0
- package/scripts/discovery/repo-discovery.ts +24 -6
- package/scripts/doctor/doctor-consumer.ts +2 -5
- package/scripts/document/document-byte-budget.ts +8 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +0 -8
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-busy.ts +5 -12
- package/scripts/epic/epic-classify.ts +24 -15
- package/scripts/epic/epic-cli-argv.ts +31 -0
- package/scripts/epic/epic-cli-decide.ts +42 -0
- package/scripts/epic/epic-cli.ts +6 -38
- package/scripts/epic/epic-close.ts +112 -55
- package/scripts/epic/epic-cross-repo.ts +4 -7
- package/scripts/epic/epic-decide.ts +119 -0
- package/scripts/epic/epic-decision.ts +9 -0
- package/scripts/epic/epic-fetch.ts +4 -0
- package/scripts/epic/epic-graph.ts +2 -0
- package/scripts/epic/epic-issue.ts +5 -1
- package/scripts/epic/epic-label-age.ts +1 -1
- package/scripts/epic/epic-lane-offer.ts +39 -4
- package/scripts/epic/epic-next-main.ts +24 -0
- package/scripts/epic/epic-next.ts +6 -24
- package/scripts/epic/epic-outside-blocker.ts +6 -2
- package/scripts/epic/epic-parse.ts +9 -3
- package/scripts/epic/epic-read.ts +1 -0
- package/scripts/epic/epic-reconcile.ts +39 -0
- package/scripts/epic/epic-run.ts +10 -1
- package/scripts/epic/epic-solo.ts +50 -14
- package/scripts/epic/epic.ts +41 -7
- package/scripts/exports/unused-members-cli.ts +2 -2
- package/scripts/followup/followup-checks-event.ts +8 -3
- package/scripts/followup/followup-coderabbit-wait.ts +82 -0
- package/scripts/followup/followup-review-gates.ts +81 -0
- package/scripts/followup/git-followup-stages.ts +13 -3
- package/scripts/followup/git-followup-workflow.ts +19 -66
- package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
- package/scripts/followup/git-pr-followup.ts +36 -8
- package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
- package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
- package/scripts/gate/busy-average.ts +58 -0
- package/scripts/gate/check-cpu.ts +60 -0
- package/scripts/gate/check-inputs.ts +39 -95
- package/scripts/gate/check-reuse.ts +33 -54
- package/scripts/gate/command-memory.ts +192 -0
- package/scripts/gate/core-admission.ts +218 -28
- package/scripts/gate/core-budget-timing.ts +37 -0
- package/scripts/gate/core-budget.ts +80 -98
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +37 -5
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +27 -4
- package/scripts/gate/gate-ledger.ts +32 -4
- package/scripts/gate/gate-plan.ts +41 -34
- package/scripts/gate/gate-report.ts +14 -2
- package/scripts/gate/gate-run-steps.ts +53 -8
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +65 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/project-checks.ts +5 -12
- package/scripts/gate/scoped-green.ts +12 -8
- package/scripts/gate/since-green.ts +62 -0
- package/scripts/gate/toolchain-inputs.ts +115 -0
- package/scripts/gate/verification-gate.ts +27 -24
- package/scripts/gate/verification-inputs.ts +250 -0
- package/scripts/gh/gh-author-association.ts +96 -9
- package/scripts/gh/git-ai-review-scan.ts +4 -2
- package/scripts/gh/git-gh-api-path.ts +15 -0
- package/scripts/gh/git-gh-branch-rules.ts +73 -0
- package/scripts/gh/git-gh-conditional.ts +5 -2
- package/scripts/gh/git-gh-issue-read.ts +5 -1
- package/scripts/gh/git-gh-issue-write.ts +67 -29
- package/scripts/gh/git-gh-issue.ts +7 -3
- package/scripts/gh/git-gh-poll-read.ts +89 -0
- package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
- package/scripts/gh/git-gh-pr-rest.ts +1 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
- package/scripts/gh/git-gh-pr.ts +27 -15
- package/scripts/gh/git-pr-checks-eval.ts +39 -7
- package/scripts/gh/git-pr-checks-parse.ts +39 -9
- package/scripts/gh/git-pr-merge-checked.ts +80 -0
- package/scripts/git/base-tree.ts +19 -2
- package/scripts/git/changed-file-scope.ts +6 -4
- package/scripts/git/changed-paths.ts +18 -1
- package/scripts/git/git-diff-reads.ts +27 -2
- package/scripts/git/git-grep-hits.ts +85 -0
- package/scripts/git/git-location-environment.ts +1 -1
- package/scripts/git/git-merge-conflicts.ts +83 -0
- package/scripts/git/git-preflight.ts +37 -12
- package/scripts/git/git-push-transport.ts +1 -2
- package/scripts/git/git-schemas.ts +17 -7
- package/scripts/git/git-spawn.ts +1 -2
- package/scripts/git/git-status.ts +4 -4
- package/scripts/git/main-merge-main.ts +12 -0
- package/scripts/git/main-merge-regenerate.ts +2 -2
- package/scripts/git/main-merge.ts +25 -9
- package/scripts/git/main-sync-main.ts +12 -0
- package/scripts/git/main-sync.ts +0 -9
- package/scripts/git/stash/git-stash.ts +27 -4
- package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
- package/scripts/git/stash/stash-pop-cli.ts +6 -12
- package/scripts/git/stash/stash-pop-main.ts +12 -0
- package/scripts/git/stash/stash-push-cli.ts +76 -0
- package/scripts/git/stash/stash-push-main.ts +12 -0
- package/scripts/hooks/batch-guard.ts +0 -8
- package/scripts/hooks/check-commit-message-main.ts +8 -0
- package/scripts/hooks/check-commit-message.ts +4 -7
- package/scripts/hooks/format-edited-file.ts +8 -24
- package/scripts/hooks/pre-commit-lint.ts +30 -3
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +32 -19
- package/scripts/hooks/reserved-run.ts +67 -9
- package/scripts/hooks/run-hook.sh +13 -4
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +2 -21
- package/scripts/hooks/stop-guard.ts +13 -9
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -17
- package/scripts/init/init-actions.ts +0 -6
- package/scripts/init/init-ai-copy.ts +10 -36
- package/scripts/init/init-bootstrap.ts +9 -8
- package/scripts/init/init-dry-run-report.ts +1 -1
- package/scripts/init/init-dry-run.ts +1 -1
- package/scripts/init/init-file-action.ts +7 -9
- package/scripts/init/init-logic-json-merge.ts +2 -2
- package/scripts/init/init-logic-migrate.ts +9 -82
- package/scripts/init/init-logic.ts +3 -2
- package/scripts/init/init-main.ts +12 -0
- package/scripts/init/init.ts +5 -12
- package/scripts/init/kit-development-versions.ts +3 -7
- package/scripts/init/kit-written-paths.ts +2 -2
- package/scripts/init/project-profile.ts +5 -4
- package/scripts/init/tsconfig-preset-migration.ts +2 -1
- package/scripts/init/vscode-tasks.ts +1 -1
- package/scripts/issue/defect-origin-cli.ts +106 -0
- package/scripts/issue/defect-origin-line.ts +60 -0
- package/scripts/issue/defect-origin-main.ts +11 -0
- package/scripts/issue/defect-origin.ts +114 -0
- package/scripts/issue/defect-rate-cli.ts +34 -78
- package/scripts/issue/defect-rate.ts +0 -16
- package/scripts/issue/defect-report-cli.ts +128 -0
- package/scripts/issue/defect-report-format.ts +56 -0
- package/scripts/issue/defect-report-main.ts +11 -0
- package/scripts/issue/defect-report.ts +160 -0
- package/scripts/issue/expected-effect-lint.ts +1 -0
- package/scripts/issue/issue-already-done-cli.ts +62 -0
- package/scripts/issue/issue-body-or-comment.ts +40 -0
- package/scripts/issue/issue-cite-cli.ts +0 -9
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +12 -7
- package/scripts/issue/issue-comment-cli.ts +10 -24
- package/scripts/issue/issue-comment-main.ts +12 -0
- package/scripts/issue/issue-evidence-exit.ts +100 -0
- package/scripts/issue/issue-file-cli.ts +29 -7
- package/scripts/issue/issue-file.ts +19 -19
- package/scripts/issue/issue-fold-cli.ts +2 -11
- package/scripts/issue/issue-fold-main.ts +12 -0
- package/scripts/issue/issue-labels.ts +81 -90
- package/scripts/issue/issue-lint-cli.ts +2 -10
- package/scripts/issue/issue-lint-main.ts +12 -0
- package/scripts/issue/issue-measured-cli.ts +56 -0
- package/scripts/issue/issue-merged.ts +19 -2
- package/scripts/issue/issue-not-before-label.ts +135 -0
- package/scripts/issue/issue-not-before.ts +111 -0
- package/scripts/issue/issue-number-shape.ts +15 -1
- package/scripts/issue/issue-park.ts +28 -0
- package/scripts/issue/issue-plan-cli.ts +151 -0
- package/scripts/issue/issue-priority.ts +151 -0
- package/scripts/issue/issue-rank.ts +7 -1
- package/scripts/issue/issue-read-cli.ts +3 -10
- package/scripts/issue/issue-read-main.ts +12 -0
- package/scripts/issue/issue-read.ts +29 -5
- package/scripts/issue/issue-release-cli.ts +0 -10
- package/scripts/issue/issue-release-main.ts +13 -0
- package/scripts/issue/issue-release.ts +7 -12
- package/scripts/issue/issue-sample-gate.ts +192 -0
- package/scripts/issue/issue-sample-source.ts +76 -0
- package/scripts/issue/issue-scout-cli.ts +0 -11
- package/scripts/issue/issue-scout-main.ts +14 -0
- package/scripts/issue/issue-state-cli.ts +0 -10
- package/scripts/issue/issue-state-main.ts +12 -0
- package/scripts/issue/issue-watch-diff.ts +56 -15
- package/scripts/issue/issue-watch.ts +2 -1
- package/scripts/issue/issue-wip.ts +2 -7
- package/scripts/issue/measure-rerun-cli.ts +13 -8
- package/scripts/issue/plan-consumers-cli.ts +39 -0
- package/scripts/issue/plan-consumers-main.ts +11 -0
- package/scripts/issue/plan-consumers-section.ts +55 -0
- package/scripts/issue/plan-consumers.ts +127 -0
- package/scripts/josh/agent-session-environment.ts +1 -1
- package/scripts/josh/command-usage.ts +15 -43
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +12 -6
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +157 -158
- package/scripts/josh/josh-commands-backlog.ts +82 -16
- package/scripts/josh/josh-commands-clone.ts +1 -0
- package/scripts/josh/josh-commands-development.ts +111 -71
- package/scripts/josh/josh-commands-document.ts +43 -1
- package/scripts/josh/josh-commands-epic.ts +171 -0
- package/scripts/josh/josh-commands-hooks.ts +25 -2
- package/scripts/josh/josh-commands-issue-write.ts +181 -0
- package/scripts/josh/josh-commands-issue.ts +124 -24
- package/scripts/josh/josh-commands-lane.ts +103 -2
- package/scripts/josh/josh-commands-lint.ts +19 -8
- package/scripts/josh/josh-commands-maintenance.ts +112 -4
- package/scripts/josh/josh-commands-pause.ts +29 -0
- package/scripts/josh/josh-commands-progress.ts +87 -0
- package/scripts/josh/josh-commands-project.ts +138 -9
- package/scripts/josh/josh-commands-review.ts +124 -0
- package/scripts/josh/josh-commands-run.ts +211 -23
- package/scripts/josh/josh-commands-ship.ts +169 -0
- package/scripts/josh/josh-commands-split.ts +9 -0
- package/scripts/josh/josh-commands-versioning.ts +49 -2
- package/scripts/josh/josh-commands-workflow.ts +144 -6
- package/scripts/josh/josh-logic.ts +6 -13
- package/scripts/josh/package-directory.ts +2 -4
- package/scripts/josh/process-identity.ts +13 -4
- package/scripts/josh/session-language-cli.ts +4 -8
- package/scripts/josh/session-language-main.ts +13 -0
- package/scripts/josh/session-language.ts +6 -1
- package/scripts/josh/shared-cache.ts +90 -0
- package/scripts/josh/stamp-file.ts +9 -15
- package/scripts/lane/lane-await.ts +51 -12
- package/scripts/lane/lane-cache.ts +5 -30
- package/scripts/lane/lane-capacity.ts +14 -23
- package/scripts/lane/lane-check-stats.ts +62 -21
- package/scripts/lane/lane-child-invocation.ts +8 -0
- package/scripts/lane/lane-cli.ts +15 -5
- package/scripts/lane/lane-close.ts +86 -18
- package/scripts/lane/lane-core-wait-stats.ts +66 -0
- package/scripts/lane/lane-dispatch.ts +24 -3
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-handoff.ts +69 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +4 -11
- package/scripts/lane/lane-launch-cli.ts +0 -9
- package/scripts/lane/lane-launch-main.ts +12 -0
- package/scripts/lane/lane-ledger-schema.ts +266 -0
- package/scripts/lane/lane-ledger.ts +92 -123
- package/scripts/lane/lane-limit-cli.ts +12 -1
- package/scripts/lane/lane-measure-cli.ts +57 -11
- package/scripts/lane/lane-open.ts +9 -1
- package/scripts/lane/lane-parked.ts +3 -3
- package/scripts/lane/lane-pause-cli.ts +130 -0
- package/scripts/lane/lane-pause.ts +158 -0
- package/scripts/lane/lane-process-table.ts +166 -0
- package/scripts/lane/lane-reap-settle.ts +124 -0
- package/scripts/lane/lane-reap.ts +50 -15
- package/scripts/lane/lane-registry.ts +24 -3
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +22 -2
- package/scripts/lane/lane-round-two-stats.ts +49 -0
- package/scripts/lane/lane-sampler.ts +4 -0
- package/scripts/lane/lane-session-action.ts +19 -5
- package/scripts/lane/lane-session-broker.ts +102 -21
- package/scripts/lane/lane-snapshot-trace.ts +84 -0
- package/scripts/lane/lane-spans.ts +51 -0
- package/scripts/lane/lane-spent.ts +6 -3
- package/scripts/lane/lane-stage-stats.ts +7 -2
- package/scripts/lane/lane-state.ts +302 -0
- package/scripts/lane/lane-stats.ts +58 -4
- package/scripts/lane/lane-stop-stats.ts +113 -37
- package/scripts/lane/lane-test-related-stats.ts +127 -0
- package/scripts/lane/lane-transcript-calls.ts +145 -0
- package/scripts/lane/lane-transcript-stats.ts +168 -0
- package/scripts/lane/lane-vacant.ts +13 -3
- package/scripts/lane/lane-withdraw-cli.ts +5 -4
- package/scripts/lane/lane-withdraw.ts +50 -49
- package/scripts/lane/process-directories.ts +70 -0
- package/scripts/lane/process-lane-marks.ts +94 -0
- package/scripts/lib/atomic-write.ts +62 -0
- package/scripts/lib/buffered-process.ts +12 -5
- package/scripts/lib/cli-flags.ts +53 -0
- package/scripts/lib/figure-format.ts +63 -0
- package/scripts/lib/json-value.ts +9 -1
- package/scripts/lib/package-manifest.ts +35 -0
- package/scripts/lib/read-file.ts +3 -1
- package/scripts/lib/stamped-memo.ts +63 -0
- package/scripts/lib/stdout-on-stderr.ts +24 -0
- package/scripts/lib/timeouts.ts +9 -0
- package/scripts/lib/transcript-record.ts +91 -0
- package/scripts/lines/effective-limit.ts +1 -1
- package/scripts/lint/eslint-cache-dependencies.ts +145 -0
- package/scripts/lint/eslint-daemon.ts +265 -0
- package/scripts/lint/format.ts +11 -2
- package/scripts/lint/import-graph.ts +279 -0
- package/scripts/lint/lint-gate-scope.ts +102 -0
- package/scripts/lint/lint-parallel-main.ts +19 -0
- package/scripts/lint/lint-parallel.ts +62 -30
- package/scripts/lint/lint-related-scope.ts +30 -24
- package/scripts/lint/lint-related.ts +38 -6
- package/scripts/notify/confirmation-options.ts +1 -2
- package/scripts/notify/telegram-notify.ts +20 -20
- package/scripts/notify/telegram-test-logic.ts +0 -1
- package/scripts/notify/telegram-test-main.ts +8 -0
- package/scripts/notify/telegram-test.ts +2 -6
- package/scripts/observations/observation-ledger.ts +13 -0
- package/scripts/observations/observations-flush-landing.ts +5 -3
- package/scripts/observations/observations-flush.ts +6 -1
- package/scripts/overrides/overrides-check.ts +2 -5
- package/scripts/overrides/overrides-files.ts +2 -1
- package/scripts/overrides/overrides-logic.ts +3 -6
- package/scripts/package/verify-optional-eslint-install.ts +8 -6
- package/scripts/propagate/propagate-publish.ts +2 -7
- package/scripts/propagate/propagate-targets.ts +4 -12
- package/scripts/refactor/import-graph.ts +9 -7
- package/scripts/release/github-release-runs.ts +17 -6
- package/scripts/release/release-approval-prune.ts +18 -0
- package/scripts/release/release-history.ts +1 -3
- package/scripts/release/release-progress.ts +42 -22
- package/scripts/release/release-publish-run.ts +39 -0
- package/scripts/release/release-publish.ts +6 -6
- package/scripts/release/release-scope-cli.ts +0 -10
- package/scripts/release/release-scope-main.ts +12 -0
- package/scripts/repo/repo-setting.ts +3 -6
- package/scripts/repo/required-checks-logic.ts +6 -15
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-labels.ts +155 -0
- package/scripts/report/report-lint-cli.ts +3 -0
- package/scripts/report/report-lint.ts +85 -110
- package/scripts/report/report-template-cli.ts +59 -0
- package/scripts/report/report-template.ts +112 -0
- package/scripts/review/acceptance-map.ts +1 -0
- package/scripts/review/removed-tests-check.ts +86 -0
- package/scripts/review/removed-tests.ts +149 -0
- package/scripts/review/review-brief-cli.ts +81 -15
- package/scripts/review/review-brief-main.ts +12 -0
- package/scripts/review/review-brief.ts +31 -3
- package/scripts/review/review-code-tree.ts +10 -6
- package/scripts/review/review-comment-round.ts +26 -8
- package/scripts/review/review-finding-ledger.ts +30 -15
- package/scripts/review/review-interaction.ts +94 -0
- package/scripts/review/review-readers-scan.ts +163 -0
- package/scripts/review/review-record-cli.ts +69 -30
- package/scripts/review/review-record-main.ts +12 -0
- package/scripts/review/review-round-one-blobs.ts +221 -0
- package/scripts/review/review-round2-cli.ts +49 -12
- package/scripts/review/review-round2.ts +80 -12
- package/scripts/review/review-stamps.ts +19 -1
- package/scripts/review/review-stop-log.ts +96 -0
- package/scripts/review/review-stops-cli.ts +85 -0
- package/scripts/review/review-tree.ts +6 -17
- package/scripts/review/review-untouched-readers.ts +146 -0
- package/scripts/review/test-titles.ts +118 -0
- package/scripts/rules/agent-model.ts +8 -0
- package/scripts/rules/bash-triggers.ts +46 -3
- package/scripts/rules/decision-oracle-batch.ts +9 -1
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +80 -2
- package/scripts/rules/destructive-command.ts +8 -1
- package/scripts/rules/direct-filing.ts +10 -2
- package/scripts/rules/direct-issue-comment.ts +117 -0
- package/scripts/rules/direct-pr-create.ts +69 -3
- package/scripts/rules/early-heartbeat.ts +2 -1
- package/scripts/rules/file-body.ts +7 -0
- package/scripts/rules/filing-cap.ts +7 -0
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +4 -0
- package/scripts/rules/implementation-cut-verdict.ts +1 -1
- package/scripts/rules/implementation-cut.ts +11 -3
- package/scripts/rules/index-guard.ts +8 -1
- package/scripts/rules/issue-comments.ts +9 -1
- package/scripts/rules/josh-git-bare.ts +7 -0
- package/scripts/rules/lane-background.ts +67 -25
- package/scripts/rules/lane-carry-conflict.ts +6 -0
- package/scripts/rules/lane-direct-tool.ts +74 -0
- package/scripts/rules/lane-interactive-ask.ts +9 -2
- package/scripts/rules/lane-park.ts +45 -23
- package/scripts/rules/lane-split-park.ts +10 -2
- package/scripts/rules/lane-switch-main.ts +7 -0
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +1 -1
- package/scripts/rules/poll-loop.ts +7 -0
- package/scripts/rules/pr-merge.ts +123 -0
- package/scripts/rules/protected-files.ts +32 -5
- package/scripts/rules/raw-field-body.ts +6 -0
- package/scripts/rules/rule-body-guard.ts +8 -0
- package/scripts/rules/rule-list.ts +9 -28
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +1 -1
- package/scripts/rules/shell-segments.ts +35 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +3 -4
- package/scripts/rules/test-declared-commit.ts +11 -1
- package/scripts/rules/third-party-write.ts +7 -0
- package/scripts/rules/timed-rerun.ts +69 -0
- package/scripts/rules/worktree-guard.ts +13 -3
- package/scripts/run/board/run-board-app-name.ts +23 -0
- package/scripts/run/board/run-board-cli.ts +65 -32
- package/scripts/run/board/run-board-earlier.ts +94 -0
- package/scripts/run/board/run-board-ending-reason.ts +67 -0
- package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
- package/scripts/run/board/run-board-estimate.ts +98 -0
- package/scripts/run/board/run-board-fit.ts +153 -36
- package/scripts/run/board/run-board-fold.ts +123 -0
- package/scripts/run/board/run-board-fresh.ts +2 -2
- package/scripts/run/board/run-board-gather-live.ts +29 -0
- package/scripts/run/board/run-board-gather-thread.ts +189 -0
- package/scripts/run/board/run-board-gather-worker.ts +29 -0
- package/scripts/run/board/run-board-gather.ts +187 -0
- package/scripts/run/board/run-board-github.ts +118 -38
- package/scripts/run/board/run-board-header.ts +82 -20
- package/scripts/run/board/run-board-keys.ts +58 -0
- package/scripts/run/board/run-board-kind.ts +20 -6
- package/scripts/run/board/run-board-labels.ts +116 -71
- package/scripts/run/board/run-board-lane-state.ts +109 -0
- package/scripts/run/board/run-board-lane-time.ts +122 -0
- package/scripts/run/board/run-board-layout.ts +239 -60
- package/scripts/run/board/run-board-length.ts +52 -0
- package/scripts/run/board/run-board-machine.ts +8 -4
- package/scripts/run/board/run-board-main.ts +12 -0
- package/scripts/run/board/run-board-notes.ts +52 -31
- package/scripts/run/board/run-board-now.ts +1 -1
- package/scripts/run/board/run-board-operation.ts +15 -33
- package/scripts/run/board/run-board-phase.ts +1 -1
- package/scripts/run/board/run-board-plan-shared.ts +115 -0
- package/scripts/run/board/run-board-plan.ts +55 -3
- package/scripts/run/board/run-board-planning.ts +45 -0
- package/scripts/run/board/run-board-priority.ts +44 -0
- package/scripts/run/board/run-board-process-groups.ts +195 -0
- package/scripts/run/board/run-board-read.ts +151 -27
- package/scripts/run/board/run-board-reason.ts +235 -51
- package/scripts/run/board/run-board-released.ts +35 -0
- package/scripts/run/board/run-board-render-checks.ts +39 -5
- package/scripts/run/board/run-board-render-condition.ts +96 -0
- package/scripts/run/board/run-board-render-drawn.ts +67 -0
- package/scripts/run/board/run-board-render-foot.ts +59 -0
- package/scripts/run/board/run-board-render-icon.ts +35 -0
- package/scripts/run/board/run-board-render-lanes.ts +145 -0
- package/scripts/run/board/run-board-render-lead.ts +80 -0
- package/scripts/run/board/run-board-render-legend.ts +117 -48
- package/scripts/run/board/run-board-render-notes.ts +156 -29
- package/scripts/run/board/run-board-render-processes.ts +196 -0
- package/scripts/run/board/run-board-render-section.ts +119 -0
- package/scripts/run/board/run-board-render-slot.ts +3 -36
- package/scripts/run/board/run-board-render-tail.ts +115 -48
- package/scripts/run/board/run-board-render-time.ts +56 -0
- package/scripts/run/board/run-board-render-title.ts +117 -24
- package/scripts/run/board/run-board-render-waits.ts +104 -20
- package/scripts/run/board/run-board-render.ts +207 -265
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +9 -4
- package/scripts/run/board/run-board-setup.ts +1 -12
- package/scripts/run/board/run-board-snapshot.ts +111 -0
- package/scripts/run/board/run-board-spin.ts +2 -2
- package/scripts/run/board/run-board-state.ts +22 -33
- package/scripts/run/board/run-board-status.ts +147 -71
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +122 -107
- package/scripts/run/board/run-board-usage-board.ts +78 -0
- package/scripts/run/board/run-board-usage-lanes.ts +113 -0
- package/scripts/run/board/run-board-usage-listing.ts +93 -0
- package/scripts/run/board/run-board-usage-read.ts +120 -150
- package/scripts/run/board/run-board-usage-rusage.ts +19 -7
- package/scripts/run/board/run-board-usage-text.ts +139 -51
- package/scripts/run/board/run-board-usage-top.ts +102 -0
- package/scripts/run/board/run-board-usage.ts +89 -72
- package/scripts/run/board/run-board-usual.ts +20 -9
- package/scripts/run/carry/run-carry-args.ts +4 -7
- package/scripts/run/carry/run-carry-conversation.ts +1 -1
- package/scripts/run/carry/run-carry.ts +9 -4
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/event/run-event-cli.ts +1 -5
- package/scripts/run/event/run-event-filed.ts +12 -6
- package/scripts/run/event/run-event-follow.ts +2 -3
- package/scripts/run/event/run-event-render.ts +6 -10
- package/scripts/run/event/run-event-scope.ts +2 -2
- package/scripts/run/event/run-event-stream-emit.ts +82 -22
- package/scripts/run/event/run-event-stream.ts +34 -8
- package/scripts/run/hold/run-hold-adopt.ts +65 -0
- package/scripts/run/hold/run-hold-cli.ts +93 -22
- package/scripts/run/hold/run-hold-main.ts +12 -0
- package/scripts/run/hold/run-hold-member.ts +37 -0
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +62 -48
- package/scripts/run/merge/run-merge-close.ts +74 -0
- package/scripts/run/merge/run-merge-collect.ts +6 -13
- package/scripts/run/merge/run-merge-driver.ts +71 -0
- package/scripts/run/merge/run-merge-main.ts +12 -0
- package/scripts/run/merge/run-merge-outcome.ts +23 -0
- package/scripts/run/merge/run-merge-restart.ts +39 -0
- package/scripts/run/merge/run-merge-ship.ts +20 -4
- package/scripts/run/merge/run-merge-signals.ts +33 -9
- package/scripts/run/merge/run-merge-steps.ts +120 -85
- package/scripts/run/merge/run-merge.ts +38 -37
- package/scripts/run/park/run-park-cli.ts +91 -0
- package/scripts/run/park/run-park.ts +88 -0
- package/scripts/run/park/run-stalled.ts +68 -0
- package/scripts/run/pause/run-pause-cli.ts +73 -0
- package/scripts/run/pause/run-pause.ts +251 -0
- package/scripts/run/progress/run-progress-cli.ts +4 -12
- package/scripts/run/progress/run-progress-clock.ts +1 -1
- package/scripts/run/progress/run-progress-config.ts +6 -14
- package/scripts/run/progress/run-progress-main.ts +12 -0
- package/scripts/run/progress/run-progress.ts +1 -4
- package/scripts/run/review/run-review.ts +2 -1
- package/scripts/run/run-ending.ts +1 -0
- package/scripts/run/run-invocation.ts +5 -6
- package/scripts/run/run-liveness-cli.ts +6 -8
- package/scripts/run/run-liveness.ts +60 -29
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-preflight.ts +18 -3
- package/scripts/run/run-prep-cli.ts +1 -10
- package/scripts/run/run-prep-locate.ts +7 -50
- package/scripts/run/run-prep-main.ts +12 -0
- package/scripts/run/run-prep.ts +6 -0
- package/scripts/run/run-report-cli.ts +101 -13
- package/scripts/run/run-report-handoff.ts +114 -0
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +13 -0
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +1 -1
- package/scripts/run/ship/run-ship-args.ts +121 -0
- package/scripts/run/ship/run-ship-body-draft.ts +110 -0
- package/scripts/run/ship/run-ship-cli.ts +63 -140
- package/scripts/run/ship/run-ship-detach.ts +19 -8
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +18 -2
- package/scripts/run/ship/run-ship-overlap.ts +42 -5
- package/scripts/run/ship/run-ship-place.ts +96 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
- package/scripts/run/ship/run-ship-preflight.ts +137 -32
- package/scripts/run/ship/run-ship-probe.ts +11 -3
- package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
- package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
- package/scripts/run/ship/run-ship-return.ts +107 -23
- package/scripts/run/ship/run-ship-review-steps.ts +105 -151
- package/scripts/run/ship/run-ship-review.ts +73 -6
- package/scripts/run/ship/run-ship-reviewer.ts +207 -0
- package/scripts/run/ship/run-ship-stage.ts +55 -6
- package/scripts/run/ship/run-ship-steps.ts +46 -15
- package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +43 -6
- package/scripts/run/ship/run-ship.ts +30 -2
- package/scripts/run/tidy/run-tidy-cli.ts +0 -4
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
- package/scripts/run/tidy/run-tidy-main.ts +8 -0
- package/scripts/run/wake/run-wake-cli.ts +119 -100
- package/scripts/run/wake/run-wake-code.ts +83 -0
- package/scripts/run/wake/run-wake-driver.ts +19 -8
- package/scripts/run/wake/run-wake-loop.ts +34 -3
- package/scripts/run/wake/run-wake-main.ts +13 -0
- package/scripts/run/wake/run-wake-ports.ts +90 -0
- package/scripts/run/wake/run-wake-takeover.ts +66 -0
- package/scripts/run/wake/run-wake.ts +2 -1
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -1
- package/scripts/safe-chain/project-config.ts +3 -9
- package/scripts/security/security-audit-main.ts +8 -0
- package/scripts/security/security-audit-provision-logic.ts +0 -11
- package/scripts/security/security-audit-provision-main.ts +12 -0
- package/scripts/security/security-audit-provision.ts +11 -26
- package/scripts/security/security-audit.ts +6 -7
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
- package/scripts/split/split-assess-cli.ts +2 -2
- package/scripts/split/split-assess.ts +15 -0
- package/scripts/split/split-measure.ts +65 -0
- package/scripts/sync/claude-settings-merge.ts +8 -15
- package/scripts/sync/directory-copy-guard.ts +4 -9
- package/scripts/sync/file-content.ts +78 -8
- package/scripts/sync/sync-ai-files.ts +3 -5
- package/scripts/sync/sync-configs.ts +11 -23
- package/scripts/sync/sync-hook-safety.ts +4 -10
- package/scripts/sync/sync-main.ts +11 -0
- package/scripts/sync/sync.ts +25 -37
- package/scripts/test/test-declared-changed.ts +2 -2
- package/scripts/test/test-declared.ts +1 -1
- package/scripts/test/test-e2e-guard.ts +25 -1
- package/scripts/test/test-e2e-stamp.ts +38 -0
- package/scripts/test/test-pinned-logic.ts +145 -0
- package/scripts/test/test-pinned-main.ts +78 -0
- package/scripts/test/test-pinned.ts +100 -0
- package/scripts/test/test-read-map.ts +264 -0
- package/scripts/test/test-read-recording.ts +91 -0
- package/scripts/test/test-read-trace.ts +148 -0
- package/scripts/test/test-red-main.ts +12 -0
- package/scripts/test/test-red.ts +12 -30
- package/scripts/test/test-related-main.ts +18 -0
- package/scripts/test/test-related-record.ts +119 -0
- package/scripts/test/test-related-scope.ts +229 -43
- package/scripts/test/test-related.ts +300 -22
- package/scripts/test/test-unit-guard-main.ts +15 -0
- package/scripts/test/test-unit-guard.ts +42 -24
- package/scripts/test/unit-count-file.ts +37 -0
- package/scripts/test/unit-run-marker.ts +162 -0
- package/scripts/test/unit-setup-files.ts +51 -0
- package/scripts/test/unit-worker-share.ts +61 -149
- package/scripts/test/whole-suite-files.ts +63 -0
- package/scripts/time-runtime/time-background.ts +20 -2
- package/scripts/time-runtime/time-bundles.ts +4 -3
- package/scripts/time-runtime/time-density-hook.ts +8 -6
- package/scripts/time-runtime/time-followup-stage.ts +1 -3
- package/scripts/time-runtime/time-format.ts +5 -28
- package/scripts/time-runtime/time-markers.ts +10 -1
- package/scripts/time-runtime/time-shell.ts +97 -10
- package/scripts/time-runtime/time-transcript-line.ts +49 -62
- package/scripts/uninstall/uninstall.ts +1 -1
- package/scripts/version/bump-version-main.ts +12 -0
- package/scripts/version/bump-version.ts +25 -25
- package/scripts/version/effective-upstream.ts +6 -12
- package/scripts/version/latest-corepack.ts +17 -32
- package/scripts/version/latest-if-required-cli.ts +93 -0
- package/scripts/version/latest-lane-guard-main.ts +8 -0
- package/scripts/version/latest-lane-guard.ts +0 -4
- package/scripts/version/latest-scope-cli.ts +0 -9
- package/scripts/version/latest-scope-main.ts +12 -0
- package/scripts/version/latest-update.ts +5 -5
- package/scripts/version/npm-registry.ts +44 -6
- package/scripts/version/publishable-range-check.ts +5 -16
- package/scripts/version/release-age.ts +1 -1
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/release-window.ts +38 -0
- package/scripts/version/running-binary.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +3 -8
- package/scripts/version/version-targets.ts +6 -28
- package/templates/dependabot.yml +29 -0
- package/templates/gitignore +4 -1
- package/templates/pnpm-workspace.basic.yaml +1 -1
- package/templates/sonar-project.properties +3 -2
- package/templates/workflows/ci.yml +12 -4
- package/templates/workflows/github-release.yml +4 -0
- package/tsconfig.sonar.json +1 -1
- package/.ncurc.json +0 -3
- package/dist/hooks/batch-guard.js +0 -29
- package/dist/hooks/chunk-4KKD2UTK.js +0 -66
- package/dist/hooks/chunk-6TS2JD6D.js +0 -237
- package/dist/hooks/chunk-7DSBJVFH.js +0 -50
- package/dist/hooks/chunk-A65Y4YOR.js +0 -79
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EFXE6C37.js +0 -81
- package/dist/hooks/chunk-GP4IEC4O.js +0 -20
- package/dist/hooks/chunk-JP45SOCJ.js +0 -56
- package/dist/hooks/chunk-LAOV7NLM.js +0 -45
- package/dist/hooks/chunk-M4HGZV7U.js +0 -83
- package/dist/hooks/chunk-PF2NZL2A.js +0 -131
- package/dist/hooks/chunk-PTICX4OL.js +0 -358
- package/dist/hooks/chunk-RT27QRJW.js +0 -6247
- package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
- package/dist/hooks/chunk-UPUZF3AN.js +0 -279
- package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -29
- package/scripts/backlog/backlog-stalled-cli.ts +0 -30
- package/scripts/cost-runtime/cost-format.ts +0 -29
- package/scripts/init/basic-path-migration.ts +0 -24
- package/scripts/issue/issue-backlinks-cli.ts +0 -93
- package/scripts/josh/josh-commands-guard.ts +0 -38
- package/scripts/josh/josh-usage-automation.ts +0 -121
- package/scripts/josh/josh-usage-backlog.ts +0 -180
- package/scripts/josh/josh-usage-developer.ts +0 -230
- package/scripts/josh/josh-usage-hooks.ts +0 -38
- package/scripts/josh/josh-usage-issue.ts +0 -205
- package/scripts/josh/josh-usage-review.ts +0 -101
- package/scripts/josh/josh-usage-run.ts +0 -252
- package/scripts/josh/josh-usage-session.ts +0 -238
- package/scripts/josh/josh-usage-workflow.ts +0 -212
- package/scripts/lint/cross-file-recheck.ts +0 -155
- package/scripts/registry-migration/migrate-logic.ts +0 -237
- package/scripts/registry-migration/migrate.ts +0 -292
- package/scripts/registry-migration/user-npmrc.ts +0 -15
- package/scripts/rules/rule-guard.ts +0 -23
- package/scripts/rules/rule-registry-rows.ts +0 -292
- package/scripts/rules/rule-registry.ts +0 -112
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
2
2
|
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
3
|
+
import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
|
|
3
4
|
import type { DriveState } from './backlog-drive'
|
|
4
5
|
|
|
5
6
|
// The `josh backlog:drive` flags — read into a `DriveContext`, and written back as the `resume:` line —
|
|
@@ -7,9 +8,7 @@ import type { DriveState } from './backlog-drive'
|
|
|
7
8
|
// `backlog_drive_cli` re-exports `parse` and `resume_line` under the names they always had, so the move
|
|
8
9
|
// changed no call site and no suite that reads them through `backlog_drive_cli`.
|
|
9
10
|
|
|
10
|
-
const MS_PER_MINUTE = 60_000
|
|
11
11
|
const LIST_SEPARATOR = ','
|
|
12
|
-
const COUNT_PATTERN = /^\d+$/u
|
|
13
12
|
const USAGE =
|
|
14
13
|
'Usage: josh backlog:drive --owner <pid> [--active <ISO-8601>] [--max <n>] [--idle <minutes>] [--only] [--exclude <n>[,<n>...]] [--await <n>[,<n>...]] [--window <minutes>] [--stopped <n>]'
|
|
15
14
|
|
|
@@ -57,7 +56,7 @@ function to_issues(raw: string | undefined): ReadonlyArray<string> | undefined {
|
|
|
57
56
|
function forwarded_of(values: Values): ReadonlyArray<string> | undefined {
|
|
58
57
|
const pairs = (['max', 'idle'] as const).filter((name) => values[name] !== undefined)
|
|
59
58
|
|
|
60
|
-
if (pairs.some((name) =>
|
|
59
|
+
if (pairs.some((name) => cli_flags.to_count(values[name]) === undefined)) return undefined
|
|
61
60
|
|
|
62
61
|
return pairs.flatMap((name) => [`--${name}`, values[name] ?? ''])
|
|
63
62
|
}
|
|
@@ -68,7 +67,7 @@ function window_of(raw: string | undefined): number | undefined {
|
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
function is_valid_window(raw: string | undefined): boolean {
|
|
71
|
-
return raw === undefined ||
|
|
70
|
+
return raw === undefined || cli_flags.to_count(raw) !== undefined
|
|
72
71
|
}
|
|
73
72
|
|
|
74
73
|
function is_valid_single(values: Values): boolean {
|
|
@@ -81,7 +80,7 @@ function is_valid_single(values: Values): boolean {
|
|
|
81
80
|
function owner_of(values: Values | undefined): string | undefined {
|
|
82
81
|
const owner = values?.owner
|
|
83
82
|
|
|
84
|
-
return owner
|
|
83
|
+
return cli_flags.to_count(owner) === undefined ? undefined : owner
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
function to_context(values: Values, owner: string): DriveContext | undefined {
|
|
@@ -12,7 +12,8 @@ import { error_text } from '#scripts/lib/error-message'
|
|
|
12
12
|
import { json_value } from '#scripts/lib/json-value'
|
|
13
13
|
import { run_carry, type RunCarry } from '#scripts/run/carry/run-carry'
|
|
14
14
|
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
15
|
-
import {
|
|
15
|
+
import type { MergeResult } from '#scripts/run/merge/run-merge-cli'
|
|
16
|
+
import { run_merge_driver } from '#scripts/run/merge/run-merge-driver'
|
|
16
17
|
import { z } from 'zod'
|
|
17
18
|
import { backlog_budget } from './backlog-budget'
|
|
18
19
|
import {
|
|
@@ -23,14 +24,19 @@ import {
|
|
|
23
24
|
type LoopPorts,
|
|
24
25
|
type OfferRead,
|
|
25
26
|
} from './backlog-drive'
|
|
27
|
+
import { backlog_drive_adopt } from './backlog-drive-adopt'
|
|
26
28
|
import { backlog_drive_args, type DriveContext } from './backlog-drive-args'
|
|
27
29
|
import { backlog_drive_carried } from './backlog-drive-carried'
|
|
28
30
|
import { backlog_drive_finish } from './backlog-drive-finish'
|
|
31
|
+
import { backlog_drive_hold, type HoldRecorder } from './backlog-drive-hold'
|
|
32
|
+
import { backlog_drive_idle } from './backlog-drive-idle'
|
|
29
33
|
import { backlog_drive_launch } from './backlog-drive-launch'
|
|
34
|
+
import { backlog_drive_memory } from './backlog-drive-memory'
|
|
30
35
|
import { backlog_drive_named } from './backlog-drive-named'
|
|
31
36
|
import { backlog_drive_named_offer } from './backlog-drive-named-offer'
|
|
32
37
|
import { backlog_drive_offer_argv } from './backlog-drive-offer-argv'
|
|
33
38
|
import { backlog_drive_owner } from './backlog-drive-owner'
|
|
39
|
+
import { backlog_drive_paused } from './backlog-drive-paused'
|
|
34
40
|
import { backlog_drive_restore } from './backlog-drive-restore'
|
|
35
41
|
import { backlog_drive_retrospective } from './backlog-drive-retrospective'
|
|
36
42
|
import { backlog_drive_seats } from './backlog-drive-seats'
|
|
@@ -59,6 +65,8 @@ const offer_read_schema = z.object({
|
|
|
59
65
|
issues: z.array(z.string()),
|
|
60
66
|
retries: z.number(),
|
|
61
67
|
answer: z.string().optional(),
|
|
68
|
+
cause: z.string().optional(),
|
|
69
|
+
waiting: z.array(z.number()).optional(),
|
|
62
70
|
reason: z.string().optional(),
|
|
63
71
|
is_finish: z.boolean().optional(),
|
|
64
72
|
})
|
|
@@ -106,20 +114,21 @@ function merge_token(out: string, code: number): string {
|
|
|
106
114
|
return ''
|
|
107
115
|
}
|
|
108
116
|
|
|
117
|
+
// A `run:merge` that printed no result — a crash before its verdict — answers no token, which the loop
|
|
118
|
+
// never reads as a collection.
|
|
119
|
+
function unprinted(code: number): MergeResult {
|
|
120
|
+
return { token: '', code, is_offer: true, outcome: 'unresolved' }
|
|
121
|
+
}
|
|
122
|
+
|
|
109
123
|
// The child's transcript, where its lane recorded one, so `run:merge` can tell an API outage from a
|
|
110
|
-
// failure exactly as it does for the parent that passes `--output` by hand.
|
|
111
|
-
//
|
|
124
|
+
// failure exactly as it does for the parent that passes `--output` by hand. Run as its own process
|
|
125
|
+
// (`run-merge-driver.ts`), so a fix merged since this loop started is the code that decides the child.
|
|
112
126
|
async function merge(issue: string, owner: string): Promise<MergeResult> {
|
|
113
127
|
await backlog_drive_owner.assert_current(owner)
|
|
114
128
|
const lane = await lane_registry.find_open_lane(issue)
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
repo: undefined,
|
|
119
|
-
over: undefined,
|
|
120
|
-
owner: run_carry.owner_of(Number(owner)),
|
|
121
|
-
output: lane?.output,
|
|
122
|
-
})
|
|
129
|
+
const argv = run_merge_driver.argv_of({ child: issue, owner, output: lane?.output })
|
|
130
|
+
const ran = await josh_command.josh_run(argv, should_forward_stderr)
|
|
131
|
+
const result = run_merge_driver.read(ran.out) ?? unprinted(ran.code)
|
|
123
132
|
|
|
124
133
|
await backlog_drive_named.mark_done(issue, result, owner)
|
|
125
134
|
|
|
@@ -130,17 +139,18 @@ async function merge(issue: string, owner: string): Promise<MergeResult> {
|
|
|
130
139
|
// a restart after it ended — is read as having appeared, so it is collected after the re-confirm window
|
|
131
140
|
// rather than waited on until the never-appeared timeout. One that never appeared is collected too:
|
|
132
141
|
// `run:merge` reads its state rather than this loop guessing.
|
|
133
|
-
function finished_checker(seeded:
|
|
142
|
+
function finished_checker(seeded: ReadonlySet<string>): (issue: string) => boolean {
|
|
134
143
|
const states = new Map<string, AwaitState>()
|
|
135
144
|
const config = {
|
|
136
145
|
is_running: lane_await.is_process_running_default,
|
|
146
|
+
is_shipped: lane_await.is_shipped_default,
|
|
137
147
|
reconfirm_ms: lane_await.RECONFIRM_MS,
|
|
138
148
|
never_appeared_timeout_ms: lane_await.NEVER_APPEARED_TIMEOUT_MS,
|
|
139
149
|
}
|
|
140
150
|
|
|
141
151
|
return (issue: string): boolean => {
|
|
142
152
|
const state = states.get(issue) ?? {
|
|
143
|
-
appeared: seeded.
|
|
153
|
+
appeared: seeded.has(issue),
|
|
144
154
|
disappeared_at: undefined,
|
|
145
155
|
first_polled_at: undefined,
|
|
146
156
|
}
|
|
@@ -181,19 +191,61 @@ function judgement_reader(): () => Promise<number> {
|
|
|
181
191
|
}
|
|
182
192
|
}
|
|
183
193
|
|
|
194
|
+
// The reports an offered pass leaves: why it started nothing, the idle notice and the paused notice.
|
|
195
|
+
function reporters(holds: HoldRecorder): Pick<LoopPorts, 'hold' | 'idle' | 'paused'> {
|
|
196
|
+
return {
|
|
197
|
+
hold: holds.hold,
|
|
198
|
+
idle: backlog_drive_idle.notify,
|
|
199
|
+
paused: async () => {
|
|
200
|
+
await backlog_drive_paused.notify()
|
|
201
|
+
},
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// What a launch is weighed against: the free lanes, a kept lane, and the memory for one more.
|
|
206
|
+
function room_ports(): Pick<LoopPorts, 'free_lanes' | 'has_lane' | 'limit_room' | 'memory_held'> {
|
|
207
|
+
return {
|
|
208
|
+
free_lanes: backlog_ready.drive_free_lane_count,
|
|
209
|
+
limit_room: backlog_ready.drive_limit_room,
|
|
210
|
+
has_lane: backlog_drive_seats.has_kept_lane,
|
|
211
|
+
memory_held: backlog_drive_memory.gauge(),
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// The children's ports. An adopted lane was dispatched like a seeded one, so a child already gone is
|
|
216
|
+
// collected rather than waited on until the never-appeared timeout.
|
|
217
|
+
function child_ports(
|
|
218
|
+
seeded: ReadonlyArray<string>,
|
|
219
|
+
owner: string,
|
|
220
|
+
): Pick<LoopPorts, 'adoptable' | 'is_finished' | 'merge'> {
|
|
221
|
+
const known = new Set(seeded)
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
is_finished: finished_checker(known),
|
|
225
|
+
merge: async (issue) => await merge(issue, owner),
|
|
226
|
+
adoptable: async (in_flight) => {
|
|
227
|
+
const adopting = await backlog_drive_adopt.adoptable(in_flight)
|
|
228
|
+
|
|
229
|
+
for (const issue of adopting) known.add(issue)
|
|
230
|
+
|
|
231
|
+
return adopting
|
|
232
|
+
},
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
184
236
|
function ports_of(
|
|
185
237
|
context: DriveContext,
|
|
186
238
|
seeded: ReadonlyArray<string>,
|
|
187
239
|
last: { state: DriveState },
|
|
240
|
+
holds: HoldRecorder,
|
|
188
241
|
): LoopPorts {
|
|
189
242
|
return {
|
|
190
|
-
|
|
191
|
-
merge: async (issue) => await merge(issue, context.owner),
|
|
243
|
+
...child_ports(seeded, context.owner),
|
|
192
244
|
offer: async (state) => await read_offer(state, context),
|
|
193
245
|
launch: async (issue) => await backlog_drive_launch.launch(issue, context.owner),
|
|
194
|
-
|
|
195
|
-
has_lane: backlog_drive_seats.has_kept_lane,
|
|
246
|
+
...room_ports(),
|
|
196
247
|
judgement_owed: judgement_reader(),
|
|
248
|
+
...reporters(holds),
|
|
197
249
|
now: () => new Date(),
|
|
198
250
|
sleep: async (milliseconds) => {
|
|
199
251
|
await sleep(milliseconds)
|
|
@@ -205,7 +257,15 @@ function ports_of(
|
|
|
205
257
|
}
|
|
206
258
|
}
|
|
207
259
|
|
|
208
|
-
|
|
260
|
+
// The lanes still in flight, and the children this run withdrew: a withdrawal while the drive was
|
|
261
|
+
// handed back is never collected by this invocation, so its exclusion is read from the stream
|
|
262
|
+
// (joshuafolkken/kit#4365).
|
|
263
|
+
interface Seeded {
|
|
264
|
+
lanes: ReadonlyArray<string>
|
|
265
|
+
withdrawn: ReadonlyArray<string>
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async function seeded_lanes(context: DriveContext): Promise<Seeded | undefined> {
|
|
209
269
|
const carry = await read_record()
|
|
210
270
|
|
|
211
271
|
if (carry === undefined) return undefined
|
|
@@ -216,9 +276,13 @@ async function seeded_lanes(context: DriveContext): Promise<ReadonlyArray<string
|
|
|
216
276
|
|
|
217
277
|
const open = await open_lanes()
|
|
218
278
|
const lanes = [...new Set([...open.map((lane) => lane.issue), ...context.awaited])]
|
|
219
|
-
const
|
|
279
|
+
const carried = await backlog_drive_carried.carried(open)
|
|
280
|
+
const dispatched = backlog_drive_named.own_carried(carry, carried, context.is_only)
|
|
220
281
|
|
|
221
|
-
return
|
|
282
|
+
return {
|
|
283
|
+
lanes: backlog_drive_restore.restore(lanes, events, carry.merged_issues ?? [], dispatched),
|
|
284
|
+
withdrawn: backlog_drive_restore.withdrawn_issues(events),
|
|
285
|
+
}
|
|
222
286
|
}
|
|
223
287
|
|
|
224
288
|
// The interval between two asks is `backlog:budget`'s own, so the driver keeps the one its reason prints.
|
|
@@ -226,19 +290,39 @@ function loop_config(window_ms: number | undefined): LoopConfig {
|
|
|
226
290
|
return { poll_ms: POLL_MS, offer_ms: backlog_budget.OFFER_INTERVAL_MS, window_ms }
|
|
227
291
|
}
|
|
228
292
|
|
|
293
|
+
// The hand-back, the ledger's hold included — the lanes now wait on a session — and the resume line.
|
|
294
|
+
async function report_end(
|
|
295
|
+
end: DriveEnd,
|
|
296
|
+
state: DriveState,
|
|
297
|
+
context: DriveContext,
|
|
298
|
+
holds: HoldRecorder,
|
|
299
|
+
): Promise<void> {
|
|
300
|
+
await holds.end(end)
|
|
301
|
+
console.info(end_line(end))
|
|
302
|
+
console.info(backlog_drive_args.resume_line(state, context))
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function seeded_state(seeded: Seeded, context: DriveContext): DriveState {
|
|
306
|
+
const fresh = backlog_drive.initial_state(
|
|
307
|
+
seeded.lanes,
|
|
308
|
+
context.active ?? new Date().toISOString(),
|
|
309
|
+
)
|
|
310
|
+
const initial =
|
|
311
|
+
context.stopped === undefined ? fresh : backlog_drive.merge_stopped(context.stopped, fresh)
|
|
312
|
+
|
|
313
|
+
return { ...initial, exclude: [...new Set([...context.exclude, ...seeded.withdrawn])] }
|
|
314
|
+
}
|
|
315
|
+
|
|
229
316
|
async function drive(context: DriveContext): Promise<number> {
|
|
230
317
|
const seeded = await seeded_lanes(context)
|
|
231
318
|
|
|
232
319
|
if (seeded === undefined) return FAILURE_EXIT_CODE
|
|
233
|
-
const
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
const
|
|
237
|
-
const config = loop_config(context.window_ms)
|
|
238
|
-
const end = await backlog_drive.run_loop(last.state, config, ports_of(context, seeded, last))
|
|
320
|
+
const last = { state: seeded_state(seeded, context) }
|
|
321
|
+
const holds = backlog_drive_hold.recorder()
|
|
322
|
+
const ports = ports_of(context, seeded.lanes, last, holds)
|
|
323
|
+
const end = await backlog_drive.run_loop(last.state, loop_config(context.window_ms), ports)
|
|
239
324
|
|
|
240
|
-
|
|
241
|
-
console.info(backlog_drive_args.resume_line(last.state, context))
|
|
325
|
+
await report_end(end, last.state, context, holds)
|
|
242
326
|
|
|
243
327
|
return SUCCESS_EXIT_CODE
|
|
244
328
|
}
|
|
@@ -288,6 +372,7 @@ const backlog_drive_cli = {
|
|
|
288
372
|
read_offer,
|
|
289
373
|
resume_line: backlog_drive_args.resume_line,
|
|
290
374
|
run,
|
|
375
|
+
seeded_state,
|
|
291
376
|
to_offer,
|
|
292
377
|
}
|
|
293
378
|
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { lane_ledger } from '#scripts/lane/lane-ledger'
|
|
2
|
+
import type { DriveEnd, DrivePorts, DriveState, OfferRead, PassResult } from './backlog-drive'
|
|
3
|
+
import { backlog_ready } from './backlog-ready'
|
|
4
|
+
|
|
5
|
+
// Why a free lane stayed empty, written where `josh lane:stats` reads it (joshuafolkken/kit#3995).
|
|
6
|
+
//
|
|
7
|
+
// **The driver already dispatches the moment a lane frees**: a pass that collected a child asks the
|
|
8
|
+
// offer at once (`backlog-drive.ts` → `is_offering`). What a backlog stall episode could not say is
|
|
9
|
+
// why a free lane then stayed empty — an offer that started nothing, or the driver handed back to a
|
|
10
|
+
// session that had not restarted it yet. Each such pass records its reason; the time is derived in
|
|
11
|
+
// `lane-held-stats.ts`, so a hold is told apart from a dispatch that was simply slow.
|
|
12
|
+
//
|
|
13
|
+
// **Only a free lane is a hold.** Every lane taken is the limit doing its job, not idle capacity, and a
|
|
14
|
+
// finished run — a `stop`, the drain's `watch` or `retrospective` — owes no lane a child. Either writes
|
|
15
|
+
// a `released` entry instead, which ends the hold before it: a lane opened outside this driver can
|
|
16
|
+
// fill the pool, and no dispatch of this driver's would end that hold. A full pool's release is written
|
|
17
|
+
// once per hold, so it does not add a line on every pass; the finished run's is written every time.
|
|
18
|
+
|
|
19
|
+
const NO_FREE_LANES = 0
|
|
20
|
+
const OFFER_PREFIX = 'offer'
|
|
21
|
+
const HAND_BACK_PREFIX = 'hand-back'
|
|
22
|
+
const REASON_SEPARATOR = ':'
|
|
23
|
+
// The verdict that starts nothing more: the run is finishing, so the lanes it frees are no hold.
|
|
24
|
+
const STOP_VERDICT = 'stop'
|
|
25
|
+
// The ends that finished the run: nothing is owed a lane after them.
|
|
26
|
+
const FINISHED_REASONS: ReadonlySet<string> = new Set([STOP_VERDICT, 'watch', 'retrospective'])
|
|
27
|
+
|
|
28
|
+
interface HoldRecorder {
|
|
29
|
+
hold: DrivePorts['hold']
|
|
30
|
+
end: (end: DriveEnd) => Promise<void>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// The issues an offer that started nothing waited on, when it named them (joshuafolkken/kit#4513).
|
|
34
|
+
interface HeldWaiting {
|
|
35
|
+
waiting?: ReadonlyArray<number> | undefined
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// A hold's reason, `undefined` for the finished run, and the issues its offer waited on.
|
|
39
|
+
interface HeldDraft extends HeldWaiting {
|
|
40
|
+
reason: string | undefined
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Whether a hold may still be open — at a driver's start, one an earlier driver's hand-back left.
|
|
44
|
+
interface HoldLedger {
|
|
45
|
+
is_open: boolean
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// The reason an offer that started nothing holds a free lane, or `undefined` for the run's stop. The
|
|
49
|
+
// offer's cause stands in for its answer, so a `run:solo` wait is `offer:watch:solo` rather than one
|
|
50
|
+
// more `offer:watch:blocked` (joshuafolkken/kit#4396), and a dependency-chain or start-condition wait is
|
|
51
|
+
// `offer:watch:chain`, `offer:watch:gate` or `offer:watch:chain+gate` (joshuafolkken/kit#4513).
|
|
52
|
+
function offer_reason(read: OfferRead): string | undefined {
|
|
53
|
+
if (read.verdict === STOP_VERDICT) return undefined
|
|
54
|
+
|
|
55
|
+
const detail = read.cause ?? read.answer
|
|
56
|
+
const parts = [OFFER_PREFIX, read.verdict, ...(detail === undefined ? [] : [detail])]
|
|
57
|
+
|
|
58
|
+
return parts.join(REASON_SEPARATOR)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// A continuing pass after an offer that started nothing is a hold; an ended one is the hand-back's.
|
|
62
|
+
async function held(
|
|
63
|
+
result: PassResult,
|
|
64
|
+
read: OfferRead,
|
|
65
|
+
ports: Pick<DrivePorts, 'hold'>,
|
|
66
|
+
): Promise<PassResult> {
|
|
67
|
+
if (result.kind === 'continue') await ports.hold(offer_reason(read), read.waiting)
|
|
68
|
+
|
|
69
|
+
return result
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// A collection whose `run:merge` answered `stop` — the consecutive-failure guard — finishes the run as
|
|
73
|
+
// an offer's `stop` does, but no offer follows it to release the hold, so it is released here. Left
|
|
74
|
+
// open, the lanes it freed read as held until the next driver's first offer (joshuafolkken/kit#4571).
|
|
75
|
+
async function stopped(
|
|
76
|
+
before: DriveState,
|
|
77
|
+
after: DriveState,
|
|
78
|
+
ports: Pick<DrivePorts, 'hold'>,
|
|
79
|
+
): Promise<void> {
|
|
80
|
+
if (after.is_stopping && !before.is_stopping) await ports.hold(undefined)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// The reason a driver's end leaves the lanes waiting on a session, or `undefined` for the finished run.
|
|
84
|
+
function hand_back_reason(end: DriveEnd): string | undefined {
|
|
85
|
+
if (FINISHED_REASONS.has(end.reason)) return undefined
|
|
86
|
+
|
|
87
|
+
return [HAND_BACK_PREFIX, end.reason].join(REASON_SEPARATOR)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// The free count, or `undefined` where the lane limit is unreadable: no hold is known then. The
|
|
91
|
+
// finished run (`reason` absent) reads as a full pool — it holds no lane either way.
|
|
92
|
+
async function free_count(
|
|
93
|
+
free_lanes: () => Promise<number>,
|
|
94
|
+
reason: string | undefined,
|
|
95
|
+
): Promise<number | undefined> {
|
|
96
|
+
if (reason === undefined) return NO_FREE_LANES
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
return await free_lanes()
|
|
100
|
+
} catch {
|
|
101
|
+
return undefined
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function release(ledger: HoldLedger): Promise<void> {
|
|
106
|
+
ledger.is_open = false
|
|
107
|
+
await lane_ledger.record_released()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function release_open(ledger: HoldLedger): Promise<void> {
|
|
111
|
+
if (ledger.is_open) await release(ledger)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// A ledger line only while a lane is free. The finished run always writes its release: children parked
|
|
115
|
+
// since a full pool's release still wait for an offer answer, and only this line ends their wait
|
|
116
|
+
// (joshuafolkken/kit#4571). A full pool releases the open hold once, not on every pass.
|
|
117
|
+
async function record(
|
|
118
|
+
ledger: HoldLedger,
|
|
119
|
+
draft: HeldDraft,
|
|
120
|
+
count: number | undefined,
|
|
121
|
+
): Promise<void> {
|
|
122
|
+
if (count === undefined) return
|
|
123
|
+
|
|
124
|
+
if (draft.reason === undefined) {
|
|
125
|
+
await release(ledger)
|
|
126
|
+
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (count === NO_FREE_LANES) {
|
|
131
|
+
await release_open(ledger)
|
|
132
|
+
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
ledger.is_open = true
|
|
137
|
+
await lane_ledger.record_held({ reason: draft.reason, waiting: draft.waiting })
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// The production `hold` port and the driver's end, sharing whether a hold is open. Best-effort like
|
|
141
|
+
// every ledger write — an unreadable lane limit records nothing rather than failing the driver.
|
|
142
|
+
function recorder(
|
|
143
|
+
free_lanes: () => Promise<number> = backlog_ready.drive_free_lane_count,
|
|
144
|
+
): HoldRecorder {
|
|
145
|
+
const ledger: HoldLedger = { is_open: true }
|
|
146
|
+
|
|
147
|
+
async function write(reason: string | undefined, waiting?: ReadonlyArray<number>): Promise<void> {
|
|
148
|
+
await record(ledger, { reason, waiting }, await free_count(free_lanes, reason))
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
hold: write,
|
|
153
|
+
end: async (end) => {
|
|
154
|
+
await write(hand_back_reason(end))
|
|
155
|
+
},
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const backlog_drive_hold = { hand_back_reason, held, recorder, stopped }
|
|
160
|
+
|
|
161
|
+
export { backlog_drive_hold }
|
|
162
|
+
export type { HeldWaiting, HoldRecorder }
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { auto_ok_cli } from '#scripts/auto-ok/auto-ok-cli'
|
|
2
|
+
import type { OpenIssueData } from '#scripts/git/git-schemas'
|
|
3
|
+
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
4
|
+
import { has_any_label, NEEDS_DECISION_LABEL, RUN_STALLED_LABEL } from '#scripts/issue/issue-labels'
|
|
5
|
+
import { issue_not_before } from '#scripts/issue/issue-not-before'
|
|
6
|
+
import { telegram_notify } from '#scripts/notify/telegram-notify'
|
|
7
|
+
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
8
|
+
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
9
|
+
import type { DrivePorts, DriveState, OfferRead, PassResult } from './backlog-drive'
|
|
10
|
+
|
|
11
|
+
// The one notification an idle backlogrun sends (joshuafolkken/kit#4015): a watch with no child running
|
|
12
|
+
// is where a person's hand is wanted — a parked issue to decide, a dated one to wait out, or the next run
|
|
13
|
+
// to start. A stall was notified instead and reached nobody with anything to do, since the next dispatch
|
|
14
|
+
// resolved it; this fires only once nothing is left for the loop itself to do.
|
|
15
|
+
//
|
|
16
|
+
// **Once per idle episode**: the loop asks once a minute while it watches, so the marker on the stream
|
|
17
|
+
// (`emit_once_since_with`, reset by a `child-launch`) holds every repeat back, and the pool is read only
|
|
18
|
+
// for an episode that is new.
|
|
19
|
+
|
|
20
|
+
const WATCH_VERDICT = 'watch'
|
|
21
|
+
const BLOCKED_ANSWER = 'blocked'
|
|
22
|
+
const DECISION_HEADING = `Waiting on a decision (${NEEDS_DECISION_LABEL}):`
|
|
23
|
+
const STALLED_HEADING = `Stalled mechanically (${RUN_STALLED_LABEL}):`
|
|
24
|
+
const IDLE_HEAD = 'No child running and nothing left to dispatch.'
|
|
25
|
+
const IDLE_RECOVERY =
|
|
26
|
+
'Decide the parked issues, fix and release the stalled ones, or start the next run with `backlogrun`.'
|
|
27
|
+
|
|
28
|
+
interface IdlePorts {
|
|
29
|
+
read_issues: () => Promise<ReadonlyArray<OpenIssueData> | undefined>
|
|
30
|
+
emit: (compose: () => Promise<string>) => Promise<string | undefined>
|
|
31
|
+
send: (body: string) => Promise<boolean>
|
|
32
|
+
now_ms: () => number
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface IdleReading {
|
|
36
|
+
merged: number
|
|
37
|
+
// The `auto-ok` pool, or `undefined` when it could not be read.
|
|
38
|
+
issues: ReadonlyArray<OpenIssueData> | undefined
|
|
39
|
+
now_ms: number
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Idle is any watch with nothing in flight, not only the drain: a watch over parked or dated issues
|
|
43
|
+
// alone waits on a person just the same. A `blocked` watch is not: with nothing in flight it is only a
|
|
44
|
+
// transient `retry`, which says nothing about whether work is left to dispatch.
|
|
45
|
+
function is_idle(result: PassResult, read: OfferRead): boolean {
|
|
46
|
+
if (read.answer === BLOCKED_ANSWER) return false
|
|
47
|
+
|
|
48
|
+
return read.verdict === WATCH_VERDICT && result.state.in_flight.length === 0
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function noticed(
|
|
52
|
+
result: PassResult,
|
|
53
|
+
read: OfferRead,
|
|
54
|
+
ports: Pick<DrivePorts, 'idle'>,
|
|
55
|
+
): Promise<PassResult> {
|
|
56
|
+
if (is_idle(result, read)) await ports.idle(result.state)
|
|
57
|
+
|
|
58
|
+
return result
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function cited(issue: OpenIssueData, suffix = ''): string {
|
|
62
|
+
return `- ${issue_cite.plain(issue.number)} ${issue.title}${suffix}`
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// The cited issues carrying one park label. `needs-decision` and `run:stalled` are listed apart: one asks
|
|
66
|
+
// a person for a judgement, the other for a mechanical fix (`issue-labels.ts`).
|
|
67
|
+
function labelled_lines(issues: ReadonlyArray<OpenIssueData>, label: string): Array<string> {
|
|
68
|
+
return issues
|
|
69
|
+
.filter((issue) => has_any_label(issue.labels, new Set([label])))
|
|
70
|
+
.map((issue) => cited(issue))
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function dated_lines(issues: ReadonlyArray<OpenIssueData>, now_ms: number): Array<string> {
|
|
74
|
+
const lines: Array<string> = []
|
|
75
|
+
|
|
76
|
+
for (const issue of issues) {
|
|
77
|
+
const reason = issue_not_before.waiting_reason(issue.body, now_ms)
|
|
78
|
+
|
|
79
|
+
if (reason !== undefined) lines.push(cited(issue, ` — ${reason}`))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return lines
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function section(heading: string, lines: ReadonlyArray<string>): Array<string> {
|
|
86
|
+
return lines.length === 0 ? [] : [heading, ...lines]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function remaining_lines(reading: IdleReading): Array<string> {
|
|
90
|
+
if (reading.issues === undefined) return ['Remaining issues: unreadable']
|
|
91
|
+
|
|
92
|
+
const lines = [
|
|
93
|
+
...section(DECISION_HEADING, labelled_lines(reading.issues, NEEDS_DECISION_LABEL)),
|
|
94
|
+
...section(STALLED_HEADING, labelled_lines(reading.issues, RUN_STALLED_LABEL)),
|
|
95
|
+
...section('Waiting on a date:', dated_lines(reading.issues, reading.now_ms)),
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
return lines.length === 0 ? ['Nothing parked or dated is left.'] : lines
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function describe(reading: IdleReading): string {
|
|
102
|
+
const merged = `Merged this run: ${String(reading.merged)}`
|
|
103
|
+
|
|
104
|
+
return [IDLE_HEAD, merged, ...remaining_lines(reading)].join('\n')
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function read_pool(): Promise<ReadonlyArray<OpenIssueData> | undefined> {
|
|
108
|
+
const read = await auto_ok_cli.fetch_opted_in()
|
|
109
|
+
|
|
110
|
+
return read.kind === 'read' ? read.issues : undefined
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function emit_idle(compose: () => Promise<string>): Promise<string | undefined> {
|
|
114
|
+
const { IDLE_NOTICE, CHILD_LAUNCH } = run_event_stream.EVENT_KIND
|
|
115
|
+
|
|
116
|
+
return await run_event_stream_emit.emit_once_since_with(IDLE_NOTICE, CHILD_LAUNCH, compose)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function send_idle(body: string): Promise<boolean> {
|
|
120
|
+
return await telegram_notify.idle({ body, recovery: IDLE_RECOVERY })
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const DEFAULT_PORTS: IdlePorts = {
|
|
124
|
+
read_issues: read_pool,
|
|
125
|
+
emit: emit_idle,
|
|
126
|
+
send: send_idle,
|
|
127
|
+
now_ms: () => Date.now(),
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// The production `idle` port. Best-effort: the loop is only reporting, so a failed read or send is
|
|
131
|
+
// dropped rather than raised into the watch.
|
|
132
|
+
async function notify(state: DriveState, ports: IdlePorts = DEFAULT_PORTS): Promise<void> {
|
|
133
|
+
try {
|
|
134
|
+
const body = await ports.emit(async () =>
|
|
135
|
+
describe({
|
|
136
|
+
merged: state.exclude.length,
|
|
137
|
+
issues: await ports.read_issues(),
|
|
138
|
+
now_ms: ports.now_ms(),
|
|
139
|
+
}),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
if (body !== undefined) await ports.send(body)
|
|
143
|
+
} catch {
|
|
144
|
+
// Reporting is best-effort: an idle notice we could not read or send is dropped.
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const backlog_drive_idle = { describe, noticed, notify, read_pool }
|
|
149
|
+
|
|
150
|
+
export { backlog_drive_idle }
|
|
151
|
+
export type { IdlePorts }
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DrivePorts, OfferRead } from './backlog-drive'
|
|
2
|
+
|
|
3
|
+
// **A free lane with nothing opted in is the open backlog's turn to be judged**
|
|
4
|
+
// (joshuafolkken/kit#3854): a watch over an exhausted pool hands back `judge` while an open issue
|
|
5
|
+
// lacking `auto-ok` still owes a judgement, ahead of the drain it would otherwise be. Once every one
|
|
6
|
+
// carries its judgement comment the count is zero and the watch is the driver's again.
|
|
7
|
+
|
|
8
|
+
const WATCH_VERDICT = 'watch'
|
|
9
|
+
const EXHAUSTED_ANSWER = 'exhausted'
|
|
10
|
+
const NO_FREE_LANES = 0
|
|
11
|
+
|
|
12
|
+
async function is_owed(
|
|
13
|
+
read: OfferRead,
|
|
14
|
+
ports: Pick<DrivePorts, 'free_lanes' | 'judgement_owed'>,
|
|
15
|
+
): Promise<boolean> {
|
|
16
|
+
const is_exhausted = read.verdict === WATCH_VERDICT && read.answer === EXHAUSTED_ANSWER
|
|
17
|
+
|
|
18
|
+
if (!is_exhausted || (await ports.free_lanes()) <= NO_FREE_LANES) return false
|
|
19
|
+
|
|
20
|
+
return (await ports.judgement_owed()) > 0
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const backlog_drive_judge = { is_owed }
|
|
24
|
+
|
|
25
|
+
export { backlog_drive_judge }
|