@joshuafolkken/kit 1.1471.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 +6 -6
- package/.claude/skills/epic-commands/SKILL.md +26 -77
- package/.claude/skills/epic-commands/epic-bundle.md +12 -6
- package/.claude/skills/epic-commands/execution-waves.md +1 -2
- package/.claude/skills/verify-ui/SKILL.md +1 -2
- package/.claude/skills/workflow-commands/SKILL.md +12 -14
- package/.claude/skills/workflow-commands/background-commands.md +8 -12
- package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
- package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
- package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
- package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
- package/.claude/skills/workflow-commands/backlogrun.md +32 -51
- package/.claude/skills/workflow-commands/chain-rule.md +18 -11
- package/.claude/skills/workflow-commands/delegation.md +13 -8
- package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
- package/.claude/skills/workflow-commands/followup.md +10 -35
- package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
- package/.claude/skills/workflow-commands/fullrun.md +6 -8
- package/.claude/skills/workflow-commands/halfrun.md +20 -32
- package/.claude/skills/workflow-commands/into-target.md +1 -2
- package/.claude/skills/workflow-commands/issue-comments.md +19 -15
- package/.claude/skills/workflow-commands/issue-scout.md +5 -4
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +9 -18
- package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
- package/.claude/skills/workflow-commands/observation-filing.md +4 -50
- package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
- package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
- package/.claude/skills/workflow-commands/prerequisite.md +11 -18
- package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
- package/.claude/skills/workflow-commands/prrun.md +6 -12
- package/.claude/skills/workflow-commands/retrospective.md +5 -5
- package/.claude/skills/workflow-commands/split-assessment.md +14 -4
- package/.claude/skills/workflow-commands/target-repository.md +1 -2
- package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
- package/.codex/hooks.json +6 -6
- package/.github/actions/setup-node/action.yml +10 -1
- 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 +121 -11
- package/.github/workflows/publish.yml +10 -3
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +4 -8
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/cspell/index.yaml +7 -0
- package/dist/CLAUDE.md +4 -8
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
- 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-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
- package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -19
- package/dist/hooks/format-edited.js +5 -5
- package/dist/hooks/inputs.json +436 -257
- package/dist/hooks/pretool-guard.js +7 -22
- package/dist/hooks/session-lang.js +380 -42
- package/dist/hooks/stop-guard.js +8711 -782
- package/dist/josh.js +5263 -997
- 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 +8 -4
- package/package.json +17 -53
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -9
- package/prompts/collaboration-workflow/gh-rest.md +1 -2
- package/prompts/collaboration-workflow/issue-citation.md +2 -4
- package/prompts/collaboration-workflow/issue-template.md +42 -17
- package/prompts/collaboration-workflow/lane-instructions.md +34 -0
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +6 -12
- package/prompts/collaboration-workflow/output-bounds.md +4 -9
- package/prompts/collaboration-workflow/overview.md +1 -1
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +19 -8
- package/prompts/collaboration-workflow/report-format.md +37 -57
- package/prompts/collaboration-workflow/residency.md +12 -8
- package/prompts/collaboration-workflow/rule-delivery.md +3 -11
- package/prompts/collaboration-workflow/shell-body.md +8 -18
- package/prompts/collaboration-workflow/turn-batching.md +4 -6
- package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
- package/prompts/collaboration-workflow/wip-cap.md +7 -7
- package/prompts/collaboration-workflow.md +4 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +45 -26
- package/prompts/testing-guide.md +10 -45
- package/scripts/agent/agent-argv.ts +20 -4
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/agent-role-profile.ts +101 -45
- package/scripts/agent/agent-safe-text.ts +60 -0
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/claude-agent-argv.ts +14 -0
- package/scripts/agent/codex-agent-argv.ts +2 -0
- package/scripts/agent/lane-instructions.ts +144 -0
- 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 +6 -7
- 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 +54 -7
- 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 +39 -8
- 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 +69 -0
- 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 +137 -18
- 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 +2 -10
- package/scripts/delegation/investigation-guard.ts +15 -73
- package/scripts/delegation/investigation-reads.ts +3 -5
- 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 +9 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +17 -13
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/document/entry-read-budget.ts +2 -2
- package/scripts/document/read-set-cli.ts +4 -1
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-audit-orphans.ts +5 -8
- package/scripts/epic/epic-audit.ts +52 -1
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-evidence.ts +49 -26
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-bundle-referenced.ts +14 -3
- package/scripts/epic/epic-bundle.ts +17 -9
- 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 +31 -60
- 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 +73 -0
- package/scripts/gate/check-reuse.ts +141 -0
- 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 +150 -119
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +162 -0
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +72 -0
- package/scripts/gate/gate-ledger.ts +49 -7
- package/scripts/gate/gate-plan.ts +44 -15
- package/scripts/gate/gate-report.ts +29 -4
- package/scripts/gate/gate-run-steps.ts +195 -0
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/held-mark.ts +55 -0
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +124 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/pre-commit-type-check.ts +14 -1
- 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 +65 -129
- 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-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +77 -17
- 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/gh/git-pr.ts +13 -1
- 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 +78 -0
- package/scripts/git/main-merge.ts +39 -14
- 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 +5 -16
- 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 +118 -0
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +57 -69
- package/scripts/hooks/reserved-run.ts +67 -8
- package/scripts/hooks/run-hook.sh +18 -11
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +185 -0
- package/scripts/hooks/stop-guard.ts +72 -27
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -12
- 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 +60 -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 +33 -22
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +13 -8
- 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 +7 -13
- 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 +19 -25
- 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/markdown-section.ts +19 -5
- 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 +82 -0
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +6 -1
- package/scripts/josh/josh-command-types.ts +65 -13
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +169 -157
- 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 +31 -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 +112 -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 +149 -6
- package/scripts/josh/josh-logic.ts +11 -27
- package/scripts/josh/josh.ts +14 -5
- package/scripts/josh/package-directory.ts +18 -0
- 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 +19 -22
- package/scripts/lane/lane-check-stats.ts +97 -0
- package/scripts/lane/lane-child-invocation.ts +43 -4
- 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 +27 -6
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-guard-policy.ts +2 -2
- package/scripts/lane/lane-handoff.ts +76 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +16 -15
- 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 +108 -97
- package/scripts/lane/lane-limit-cli.ts +19 -9
- package/scripts/lane/lane-measure-cli.ts +58 -10
- 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-preserve.ts +29 -1
- 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 +33 -10
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +26 -27
- 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 +160 -0
- package/scripts/lane/lane-session-broker.ts +134 -134
- 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 +72 -0
- package/scripts/lane/lane-withdraw.ts +183 -0
- 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 +14 -5
- 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 +72 -33
- package/scripts/lint/lint-related-scope.ts +33 -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 +12 -11
- 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 +4 -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-check.ts +61 -0
- package/scripts/review/acceptance-map.ts +206 -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 +82 -16
- 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 +67 -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 +90 -3
- 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 +8 -0
- package/scripts/rules/firing-point.ts +6 -5
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +121 -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 +76 -7
- 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/last-prompt.ts +50 -5
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/oracle-list-cli.ts +7 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +4 -2
- 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 +12 -28
- package/scripts/rules/rule-rewrite.ts +114 -0
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +8 -2
- package/scripts/rules/shell-segments.ts +50 -0
- package/scripts/rules/stop-decision.ts +77 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +150 -51
- package/scripts/rules/tail-commands.ts +15 -1
- 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 -30
- package/scripts/run/board/run-board-closed.ts +8 -2
- 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 +119 -31
- package/scripts/run/board/run-board-header.ts +86 -21
- 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 +118 -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 +240 -61
- 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 +153 -13
- package/scripts/run/board/run-board-reason.ts +238 -45
- 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 -47
- 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 +125 -0
- package/scripts/run/board/run-board-render.ts +206 -259
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +10 -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 +23 -29
- package/scripts/run/board/run-board-status.ts +206 -79
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +123 -104
- 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-cli.ts +3 -2
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/cut/run-cut-report.ts +16 -0
- package/scripts/run/detached-launch.ts +23 -4
- package/scripts/run/entry/run-entry-cli.ts +8 -1
- 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 +7 -10
- package/scripts/run/event/run-event-scope.ts +20 -2
- package/scripts/run/event/run-event-stream-emit.ts +78 -11
- package/scripts/run/event/run-event-stream.ts +37 -7
- 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-hold-session.ts +46 -0
- package/scripts/run/hold/run-hold.ts +7 -1
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/launch-priority.ts +32 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +72 -107
- 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 +123 -0
- package/scripts/run/merge/run-merge-steps.ts +128 -83
- package/scripts/run/merge/run-merge.ts +53 -40
- 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 +61 -30
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-poll-hook.ts +157 -0
- 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-cli.ts +22 -15
- package/scripts/run/run-step-section.ts +85 -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 +67 -151
- package/scripts/run/ship/run-ship-detach.ts +27 -7
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +27 -3
- package/scripts/run/ship/run-ship-overlap.ts +232 -0
- 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 +102 -27
- package/scripts/run/ship/run-ship-preflight.ts +161 -30
- 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 +123 -15
- package/scripts/run/ship/run-ship-review-steps.ts +105 -149
- 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-context.ts +206 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +57 -12
- 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 +55 -6
- 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 +54 -21
- 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 +71 -137
- 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 +126 -14
- package/scripts/time-runtime/time-spans.ts +1 -0
- package/scripts/time-runtime/time-tool-call.ts +7 -0
- 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 +10 -3
- 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-43ZHT22P.js +0 -3495
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EUMACUK2.js +0 -2038
- package/dist/hooks/chunk-H5HVWYXK.js +0 -359
- package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
- package/dist/hooks/chunk-IX6TTTI6.js +0 -95
- package/dist/hooks/chunk-J47HU5H5.js +0 -237
- package/dist/hooks/chunk-K4EOONYM.js +0 -45
- package/dist/hooks/chunk-K4LMBQC2.js +0 -68
- package/dist/hooks/chunk-SHGPANFB.js +0 -56
- package/dist/hooks/chunk-YHBZAJSV.js +0 -79
- package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -32
- 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/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 -282
- package/scripts/rules/rule-registry.ts +0 -109
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { OpenIssueData } from '#scripts/git/git-schemas'
|
|
2
|
+
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
3
|
+
import { has_any_label, NEEDS_DECISION_LABEL, RUN_STALLED_LABEL } from '#scripts/issue/issue-labels'
|
|
4
|
+
import { lane_registry } from '#scripts/lane/lane-registry'
|
|
5
|
+
import { lane_state, type LaneStateRecord } from '#scripts/lane/lane-state'
|
|
6
|
+
import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
|
|
7
|
+
import { telegram_notify } from '#scripts/notify/telegram-notify'
|
|
8
|
+
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
9
|
+
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
10
|
+
import { DEFAULT_SILENT_MINUTES } from '#scripts/run/run-liveness'
|
|
11
|
+
import type { DrivePorts, OfferRead, PassResult } from './backlog-drive'
|
|
12
|
+
import { backlog_drive_idle } from './backlog-drive-idle'
|
|
13
|
+
import { backlog_overlap } from './backlog-overlap'
|
|
14
|
+
|
|
15
|
+
// A run held only by paused lanes (joshuafolkken/kit#4270): nothing of this run in flight, nothing
|
|
16
|
+
// dispatched, and a lane a person paused past the silent window `run:liveness` waits out declares a
|
|
17
|
+
// path an open candidate overlaps. A paused lane holds no lane place (`backlog-occupied.ts`), so that
|
|
18
|
+
// overlap is the one way it holds the run; the loop would otherwise watch for ever — a paused lane
|
|
19
|
+
// frees nothing until someone resumes it — so it asks the person once. A drained or parked backlog
|
|
20
|
+
// with a lane paused somewhere is not held by it, and stays quiet.
|
|
21
|
+
//
|
|
22
|
+
// **Once per pause episode**: the marker on the stream (`emit_once_since_with`, reset by the
|
|
23
|
+
// `lane-state` line every `lane:pause` / `lane:resume` writes) holds every repeat back.
|
|
24
|
+
|
|
25
|
+
const HOLDING_VERDICTS: ReadonlySet<string> = new Set(['watch', 'wait'])
|
|
26
|
+
const BLOCKED_ANSWER = 'blocked'
|
|
27
|
+
const PAUSED_TITLE = 'backlogrun held by paused lanes'
|
|
28
|
+
const PAUSED_HEAD =
|
|
29
|
+
'No child of this run is running, and these paused lanes hold back work overlapping their paths:'
|
|
30
|
+
const PAUSED_RECOVERY =
|
|
31
|
+
'Resume a lane with `pnpm josh lane:resume <N>`, or close it with `pnpm josh lane:close <N>`.'
|
|
32
|
+
const SILENT_WINDOW_MS = DEFAULT_SILENT_MINUTES * MS_PER_MINUTE
|
|
33
|
+
// A candidate a person set aside waits on that person, not on the paused lane it overlaps.
|
|
34
|
+
const SET_ASIDE_LABELS: ReadonlySet<string> = new Set([NEEDS_DECISION_LABEL, RUN_STALLED_LABEL])
|
|
35
|
+
|
|
36
|
+
interface PausedPorts {
|
|
37
|
+
read_records: () => Promise<ReadonlyArray<LaneStateRecord>>
|
|
38
|
+
// The `auto-ok` pool, or `undefined` when it could not be read.
|
|
39
|
+
read_issues: () => Promise<ReadonlyArray<OpenIssueData> | undefined>
|
|
40
|
+
emit: (compose: () => Promise<string>) => Promise<string | undefined>
|
|
41
|
+
send: (body: string) => Promise<boolean>
|
|
42
|
+
now_ms: () => number
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// The port is asked on every holding offer with nothing in flight; `notify` decides whether a paused
|
|
46
|
+
// lane is what holds it.
|
|
47
|
+
function is_held(result: PassResult, read: OfferRead): boolean {
|
|
48
|
+
if (read.answer === BLOCKED_ANSWER) return false
|
|
49
|
+
|
|
50
|
+
return HOLDING_VERDICTS.has(read.verdict) && result.state.in_flight.length === 0
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function noticed(
|
|
54
|
+
result: PassResult,
|
|
55
|
+
read: OfferRead,
|
|
56
|
+
ports: Pick<DrivePorts, 'paused'>,
|
|
57
|
+
): Promise<PassResult> {
|
|
58
|
+
if (is_held(result, read)) await ports.paused()
|
|
59
|
+
|
|
60
|
+
return result
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The records paused for at least the silent window at `now_ms`. */
|
|
64
|
+
function long_paused(
|
|
65
|
+
records: ReadonlyArray<LaneStateRecord>,
|
|
66
|
+
now_ms: number,
|
|
67
|
+
): Array<LaneStateRecord> {
|
|
68
|
+
return records.filter(
|
|
69
|
+
(record) =>
|
|
70
|
+
record.state === 'paused' && now_ms - Date.parse(record.changed_at) >= SILENT_WINDOW_MS,
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// The open candidates no lane works on and no person set aside — the ones a paused lane can hold.
|
|
75
|
+
function waiting_of(
|
|
76
|
+
issues: ReadonlyArray<OpenIssueData>,
|
|
77
|
+
records: ReadonlyArray<LaneStateRecord>,
|
|
78
|
+
): Array<number> {
|
|
79
|
+
const lanes = new Set(records.map((record) => record.issue))
|
|
80
|
+
|
|
81
|
+
return issues
|
|
82
|
+
.filter((issue) => !lanes.has(String(issue.number)))
|
|
83
|
+
.filter((issue) => !has_any_label(issue.labels, SET_ASIDE_LABELS))
|
|
84
|
+
.map((issue) => issue.number)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** The `paused` records whose declared paths a waiting candidate overlaps. */
|
|
88
|
+
function holding(
|
|
89
|
+
paused: ReadonlyArray<LaneStateRecord>,
|
|
90
|
+
issues: ReadonlyArray<OpenIssueData>,
|
|
91
|
+
records: ReadonlyArray<LaneStateRecord>,
|
|
92
|
+
): Array<LaneStateRecord> {
|
|
93
|
+
const declared = backlog_overlap.declared_of(issues)
|
|
94
|
+
const waiting = waiting_of(issues, records)
|
|
95
|
+
|
|
96
|
+
return paused.filter((record) =>
|
|
97
|
+
waiting.some((number) => backlog_overlap.holds(declared, Number(record.issue), number)),
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function held_by(ports: PausedPorts): Promise<Array<LaneStateRecord>> {
|
|
102
|
+
const records = await ports.read_records()
|
|
103
|
+
const paused = long_paused(records, ports.now_ms())
|
|
104
|
+
|
|
105
|
+
if (paused.length === 0) return []
|
|
106
|
+
|
|
107
|
+
const issues = await ports.read_issues()
|
|
108
|
+
|
|
109
|
+
return issues === undefined ? [] : holding(paused, issues, records)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function describe(records: ReadonlyArray<LaneStateRecord>): string {
|
|
113
|
+
const lines = records.map(
|
|
114
|
+
(record) => `- ${issue_cite.plain(record.issue)} — ${lane_state.paused_note(record) ?? ''}`,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
return [PAUSED_HEAD, ...lines].join('\n')
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function read_lane_records(): Promise<ReadonlyArray<LaneStateRecord>> {
|
|
121
|
+
const lanes = await lane_registry.list_lanes()
|
|
122
|
+
const records = await lane_state.read_states(lanes.map((lane) => lane.issue))
|
|
123
|
+
|
|
124
|
+
return [...records.values()]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function emit_paused(compose: () => Promise<string>): Promise<string | undefined> {
|
|
128
|
+
const { PAUSED_NOTICE, LANE_STATE } = run_event_stream.EVENT_KIND
|
|
129
|
+
|
|
130
|
+
return await run_event_stream_emit.emit_once_since_with(PAUSED_NOTICE, LANE_STATE, compose)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function send_paused(body: string): Promise<boolean> {
|
|
134
|
+
return await telegram_notify.confirm({
|
|
135
|
+
issue_title: PAUSED_TITLE,
|
|
136
|
+
body,
|
|
137
|
+
recovery: PAUSED_RECOVERY,
|
|
138
|
+
recommended: 'Resume the paused lanes with `pnpm josh lane:resume <N>`',
|
|
139
|
+
alternatives: ['Close the paused lanes with `pnpm josh lane:close <N>`'],
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const DEFAULT_PORTS: PausedPorts = {
|
|
144
|
+
read_records: read_lane_records,
|
|
145
|
+
read_issues: backlog_drive_idle.read_pool,
|
|
146
|
+
emit: emit_paused,
|
|
147
|
+
send: send_paused,
|
|
148
|
+
now_ms: () => Date.now(),
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// The production `paused` port. Best-effort, as the idle port is: a failed read or send is dropped.
|
|
152
|
+
async function notify(ports: PausedPorts = DEFAULT_PORTS): Promise<void> {
|
|
153
|
+
try {
|
|
154
|
+
const paused = await held_by(ports)
|
|
155
|
+
|
|
156
|
+
if (paused.length === 0) return
|
|
157
|
+
|
|
158
|
+
const body = await ports.emit(async () => describe(paused))
|
|
159
|
+
|
|
160
|
+
if (body !== undefined) await ports.send(body)
|
|
161
|
+
} catch {
|
|
162
|
+
// Reporting is best-effort: a paused notice we could not read or send is dropped.
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const backlog_drive_paused = { noticed, notify }
|
|
167
|
+
|
|
168
|
+
export { backlog_drive_paused }
|
|
169
|
+
export type { PausedPorts }
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
+
import { run_event_scope } from '#scripts/run/event/run-event-scope'
|
|
1
2
|
import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
|
|
3
|
+
import { backlog_offer_exclude } from './backlog-offer-exclude'
|
|
2
4
|
|
|
3
5
|
const ISSUE_IN_EVENT = /#([1-9]\d*)\b/u
|
|
4
6
|
const SETTLED_KINDS: ReadonlySet<string> = new Set([
|
|
5
7
|
run_event_stream.EVENT_KIND.MERGE,
|
|
6
8
|
run_event_stream.EVENT_KIND.PARK,
|
|
7
9
|
run_event_stream.EVENT_KIND.SPLIT,
|
|
10
|
+
run_event_stream.EVENT_KIND.WITHDRAW,
|
|
8
11
|
run_event_stream.EVENT_KIND.OUTAGE,
|
|
9
12
|
])
|
|
10
13
|
const DONE_KINDS: ReadonlySet<string> = new Set([
|
|
11
14
|
run_event_stream.EVENT_KIND.MERGE,
|
|
12
15
|
run_event_stream.EVENT_KIND.PARK,
|
|
13
16
|
run_event_stream.EVENT_KIND.SPLIT,
|
|
17
|
+
run_event_stream.EVENT_KIND.WITHDRAW,
|
|
14
18
|
])
|
|
15
19
|
|
|
16
20
|
function issue_of(event: RunEvent): string | undefined {
|
|
@@ -44,14 +48,33 @@ function settled_issues(events: ReadonlyArray<RunEvent>): ReadonlySet<number> {
|
|
|
44
48
|
)
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
function issues_of_kind(events: ReadonlyArray<RunEvent>, kind: string): ReadonlyArray<string> {
|
|
52
|
+
return events
|
|
53
|
+
.filter((event) => event.kind === kind)
|
|
54
|
+
.map((event) => issue_of(event))
|
|
55
|
+
.filter((issue) => issue !== undefined)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The issues a person withdrew from this run and nobody launched again: the withdrawal leaves the issue
|
|
59
|
+
// open for the next run, so this one keeps it out of the offer (joshuafolkken/kit#4365).
|
|
60
|
+
function withdrawn_issues(events: ReadonlyArray<RunEvent>): ReadonlyArray<string> {
|
|
61
|
+
const named = issues_of_kind(events, run_event_stream.EVENT_KIND.WITHDRAW)
|
|
62
|
+
|
|
63
|
+
return named.filter((issue) => run_event_scope.is_withdrawn(events, issue))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// The offer's exclusion as the stream records it: the merged and withdrawn children and the ones still
|
|
67
|
+
// in flight — the list the drive keeps in memory, read by a reader that has only the stream
|
|
68
|
+
// (joshuafolkken/kit#4349).
|
|
69
|
+
function offer_exclude(events: ReadonlyArray<RunEvent>): ReadonlyArray<string> {
|
|
70
|
+
const merged = issues_of_kind(events, run_event_stream.EVENT_KIND.MERGE)
|
|
71
|
+
const settled = [...merged, ...withdrawn_issues(events)]
|
|
72
|
+
|
|
73
|
+
return backlog_offer_exclude.exclude_of(settled, active_issues(events))
|
|
74
|
+
}
|
|
75
|
+
|
|
47
76
|
function parked_issues(events: ReadonlyArray<RunEvent>): ReadonlySet<number> {
|
|
48
|
-
return new Set(
|
|
49
|
-
events
|
|
50
|
-
.filter((event) => event.kind === run_event_stream.EVENT_KIND.PARK)
|
|
51
|
-
.map((event) => issue_of(event))
|
|
52
|
-
.filter((issue) => issue !== undefined)
|
|
53
|
-
.map(Number),
|
|
54
|
-
)
|
|
77
|
+
return new Set(issues_of_kind(events, run_event_stream.EVENT_KIND.PARK).map(Number))
|
|
55
78
|
}
|
|
56
79
|
|
|
57
80
|
// The issues this invocation launched or settled — any other dispatched lane was carried in from an
|
|
@@ -82,4 +105,12 @@ function restore(
|
|
|
82
105
|
)
|
|
83
106
|
}
|
|
84
107
|
|
|
85
|
-
export const backlog_drive_restore = {
|
|
108
|
+
export const backlog_drive_restore = {
|
|
109
|
+
active_issues,
|
|
110
|
+
mentioned_issues,
|
|
111
|
+
offer_exclude,
|
|
112
|
+
restore,
|
|
113
|
+
withdrawn_issues,
|
|
114
|
+
settled_issues,
|
|
115
|
+
parked_issues,
|
|
116
|
+
}
|
|
@@ -1,25 +1,35 @@
|
|
|
1
1
|
import { lane_registry } from '#scripts/lane/lane-registry'
|
|
2
|
+
import { lane_vacant } from '#scripts/lane/lane-vacant'
|
|
2
3
|
import type { DrivePorts } from './backlog-drive'
|
|
3
4
|
|
|
4
|
-
type SeatPorts = Pick<DrivePorts, 'free_lanes' | 'has_lane'>
|
|
5
|
+
type SeatPorts = Pick<DrivePorts, 'free_lanes' | 'has_lane' | 'limit_room'>
|
|
5
6
|
|
|
6
|
-
// The issues a pass launches:
|
|
7
|
-
//
|
|
7
|
+
// The issues a pass launches: those that already hold a kept lane first, then the rest. A lane with no
|
|
8
|
+
// child in it holds no place under the limit (`backlog-occupied.ts`), so resuming its issue takes one
|
|
9
|
+
// (joshuafolkken/kit#4107) — but it keeps its port seat, so the resumes are cut by the limit room alone:
|
|
10
|
+
// idle kept lanes filling every seat must not shut out their own resumes. Fresh launches take what is
|
|
11
|
+
// left of both.
|
|
8
12
|
async function seated(issues: ReadonlyArray<string>, ports: SeatPorts): Promise<Array<string>> {
|
|
9
13
|
const kept = await Promise.all(issues.map(async (issue) => await ports.has_lane(issue)))
|
|
10
|
-
const
|
|
14
|
+
const room = await ports.limit_room()
|
|
15
|
+
const resumed = issues.filter((_issue, index) => kept[index] === true).slice(0, room)
|
|
16
|
+
const fresh_room = Math.min(await ports.free_lanes(), room - resumed.length)
|
|
11
17
|
|
|
12
18
|
return [
|
|
13
|
-
...
|
|
14
|
-
...
|
|
19
|
+
...resumed,
|
|
20
|
+
...issues.filter((_issue, index) => kept[index] !== true).slice(0, fresh_room),
|
|
15
21
|
]
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
// A kept lane is one a child was dispatched into — `lane:launch` reuses it rather
|
|
24
|
+
// A kept lane is one a child was dispatched into that holds work — `lane:launch` reuses it rather
|
|
25
|
+
// than opening one. A vacant one holds nothing to resume, so its issue waits in line like any fresh
|
|
26
|
+
// launch (joshuafolkken/kit#4028).
|
|
19
27
|
async function has_kept_lane(issue: string): Promise<boolean> {
|
|
20
28
|
const lane = await lane_registry.find_open_lane(issue)
|
|
21
29
|
|
|
22
|
-
|
|
30
|
+
if (lane?.output === undefined) return false
|
|
31
|
+
|
|
32
|
+
return !(await lane_vacant.is_vacant(lane))
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
const backlog_drive_seats = { has_kept_lane, seated }
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { run_merge_token, type MergeToken } from '#scripts/run/merge/run-merge-token'
|
|
2
|
+
|
|
3
|
+
const { MERGE_TOKEN } = run_merge_token
|
|
4
|
+
|
|
5
|
+
// How the loop reads each `run:merge` token — keyed by the producer's own type, so a token added there
|
|
6
|
+
// is a type error here until it is classified. `hand-back` ends the loop at once: a hand-off, a person's
|
|
7
|
+
// stop, the environment down, a foreign owner, an unreadable state. `stop` — the failure guard, or a
|
|
8
|
+
// failed child left unparked — collects the child, starts nothing more, and collects the children still
|
|
9
|
+
// in flight before the loop ends. `await` is a cut resumed in place: the same lane is awaited again.
|
|
10
|
+
//
|
|
11
|
+
// **The offer `run:merge` passes through is never read here** (joshuafolkken/kit#3781): its `stop` —
|
|
12
|
+
// only person-waiting issues left — is spelled like the control one, and acting on it ended the run
|
|
13
|
+
// without the idle watch. The loop asks `backlog:offer` on the next pass instead, so whether a parked
|
|
14
|
+
// backlog waits or ends is `backlog:budget`'s alone, after a merge as after any other pass.
|
|
15
|
+
type TokenHandling = 'hand-back' | 'stop' | 'await'
|
|
16
|
+
const TOKEN_HANDLING: Readonly<Record<MergeToken, TokenHandling>> = {
|
|
17
|
+
[MERGE_TOKEN.OVER]: 'hand-back',
|
|
18
|
+
[MERGE_TOKEN.HUMAN_REVIEW]: 'hand-back',
|
|
19
|
+
[MERGE_TOKEN.ENVIRONMENT]: 'hand-back',
|
|
20
|
+
[MERGE_TOKEN.BUSY]: 'hand-back',
|
|
21
|
+
[MERGE_TOKEN.RETRY]: 'hand-back',
|
|
22
|
+
[MERGE_TOKEN.STOP]: 'stop',
|
|
23
|
+
[MERGE_TOKEN.RESUMED]: 'await',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function tokens_handled(...handlings: ReadonlyArray<TokenHandling>): ReadonlySet<string> {
|
|
27
|
+
const entries = Object.entries(TOKEN_HANDLING)
|
|
28
|
+
|
|
29
|
+
return new Set(entries.filter(([, handling]) => handlings.includes(handling)).map(([key]) => key))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const IMMEDIATE_TOKENS = tokens_handled('hand-back')
|
|
33
|
+
// Every token `run:merge` prints first even on a non-zero exit.
|
|
34
|
+
const HANDOFF_TOKENS = tokens_handled('hand-back', 'stop')
|
|
35
|
+
|
|
36
|
+
const backlog_drive_token_handling = { HANDOFF_TOKENS, IMMEDIATE_TOKENS, TOKEN_HANDLING }
|
|
37
|
+
|
|
38
|
+
export { backlog_drive_token_handling }
|
|
@@ -19,43 +19,22 @@
|
|
|
19
19
|
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
20
20
|
import type { LaunchOutcome } from '#scripts/lane/lane-launch-cli'
|
|
21
21
|
import type { MergeResult } from '#scripts/run/merge/run-merge-cli'
|
|
22
|
-
import { run_merge_token
|
|
22
|
+
import { run_merge_token } from '#scripts/run/merge/run-merge-token'
|
|
23
|
+
import { backlog_drive_adopt } from './backlog-drive-adopt'
|
|
24
|
+
import { backlog_drive_hold, type HeldWaiting } from './backlog-drive-hold'
|
|
25
|
+
import { backlog_drive_idle } from './backlog-drive-idle'
|
|
26
|
+
import { backlog_drive_judge } from './backlog-drive-judge'
|
|
27
|
+
import { backlog_drive_memory } from './backlog-drive-memory'
|
|
28
|
+
import { backlog_drive_paused } from './backlog-drive-paused'
|
|
23
29
|
import { backlog_drive_seats } from './backlog-drive-seats'
|
|
30
|
+
import { backlog_drive_token_handling } from './backlog-drive-token-handling'
|
|
24
31
|
|
|
25
32
|
const { MERGE_TOKEN } = run_merge_token
|
|
33
|
+
const { HANDOFF_TOKENS, IMMEDIATE_TOKENS, TOKEN_HANDLING } = backlog_drive_token_handling
|
|
26
34
|
const RUN_VERDICT = 'run'
|
|
27
35
|
const STOP_VERDICT = 'stop'
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
// stop, the environment down, a foreign owner, an unreadable state. `stop` — the failure guard, or a
|
|
31
|
-
// failed child left unparked — collects the child, starts nothing more, and collects the children still
|
|
32
|
-
// in flight before the loop ends. `await` is a cut resumed in place: the same lane is awaited again.
|
|
33
|
-
//
|
|
34
|
-
// **The offer `run:merge` passes through is never read here** (joshuafolkken/kit#3781): its `stop` —
|
|
35
|
-
// only person-waiting issues left — is spelled like the control one, and acting on it ended the run
|
|
36
|
-
// without the idle watch. The loop asks `backlog:offer` on the next pass instead, so whether a parked
|
|
37
|
-
// backlog waits or ends is `backlog:budget`'s alone, after a merge as after any other pass.
|
|
38
|
-
type TokenHandling = 'hand-back' | 'stop' | 'await'
|
|
39
|
-
const TOKEN_HANDLING: Readonly<Record<MergeToken, TokenHandling>> = {
|
|
40
|
-
[MERGE_TOKEN.OVER]: 'hand-back',
|
|
41
|
-
[MERGE_TOKEN.HUMAN_REVIEW]: 'hand-back',
|
|
42
|
-
[MERGE_TOKEN.ENVIRONMENT]: 'hand-back',
|
|
43
|
-
[MERGE_TOKEN.BUSY]: 'hand-back',
|
|
44
|
-
[MERGE_TOKEN.RETRY]: 'hand-back',
|
|
45
|
-
[MERGE_TOKEN.STOP]: 'stop',
|
|
46
|
-
[MERGE_TOKEN.RESUMED]: 'await',
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function tokens_handled(...handlings: ReadonlyArray<TokenHandling>): ReadonlySet<string> {
|
|
50
|
-
const entries = Object.entries(TOKEN_HANDLING)
|
|
51
|
-
|
|
52
|
-
return new Set(entries.filter(([, handling]) => handlings.includes(handling)).map(([key]) => key))
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const IMMEDIATE_TOKENS = tokens_handled('hand-back')
|
|
56
|
-
// Every token `run:merge` prints first even on a non-zero exit.
|
|
57
|
-
const HANDOFF_TOKENS = tokens_handled('hand-back', 'stop')
|
|
58
|
-
const MERGED_OUTCOME = 'merged'
|
|
36
|
+
// The outcomes that keep a child out of the rest of this run's offers.
|
|
37
|
+
const EXCLUDED_OUTCOMES: ReadonlySet<string> = new Set(['merged', 'withdrawn'])
|
|
59
38
|
const WATCH_VERDICT = 'watch'
|
|
60
39
|
// The verdicts the loop acts on without the parent. Any other is handed back as it was printed.
|
|
61
40
|
const KNOWN_VERDICTS: ReadonlySet<string> = new Set([
|
|
@@ -71,11 +50,13 @@ const JUDGE_REASON = 'judge'
|
|
|
71
50
|
const LAUNCHED = 'launched'
|
|
72
51
|
const UNOPENED = 'unopened'
|
|
73
52
|
|
|
74
|
-
interface OfferRead {
|
|
53
|
+
interface OfferRead extends HeldWaiting {
|
|
75
54
|
verdict: string
|
|
76
55
|
issues: ReadonlyArray<string>
|
|
77
56
|
retries: number
|
|
78
57
|
answer?: string | undefined
|
|
58
|
+
// Why a `blocked` answer started nothing — `solo`, or `backlog-wait-cause.ts`'s with its `waiting`.
|
|
59
|
+
cause?: string | undefined
|
|
79
60
|
reason?: string | undefined
|
|
80
61
|
// Whether a drain here owes the retrospective: the opt-in switch is on and it has not run yet. Absent
|
|
81
62
|
// reads as not owed, so a drain with the switch off keeps the idle watch.
|
|
@@ -98,6 +79,8 @@ interface DriveState {
|
|
|
98
79
|
stop_is_finish?: boolean | undefined
|
|
99
80
|
// The child whose merge answered `stop`, carried on the resume line: no offer re-derives that stop.
|
|
100
81
|
stopped_by?: string | undefined
|
|
82
|
+
// The last offer answered `run` on a machine with no memory to spare (`backlog-drive-memory.ts`).
|
|
83
|
+
is_memory_held?: boolean | undefined
|
|
101
84
|
}
|
|
102
85
|
|
|
103
86
|
interface DriveEnd {
|
|
@@ -118,6 +101,9 @@ interface DrivePorts {
|
|
|
118
101
|
is_finished: (issue: string) => boolean
|
|
119
102
|
// `run:merge <N>`'s first stdout token and the outcome it handled the child as.
|
|
120
103
|
merge: (issue: string) => Promise<Collected>
|
|
104
|
+
// The lanes on a child this run launched and never settled that the loop does not hold — one the
|
|
105
|
+
// parent dispatched itself with `lane:launch` (`backlog_drive_adopt.adoptable` in production).
|
|
106
|
+
adoptable: (in_flight: ReadonlyArray<string>) => Promise<ReadonlyArray<string>>
|
|
121
107
|
// `backlog:offer`'s answer for the state, or `undefined` when it exited non-zero.
|
|
122
108
|
offer: (state: DriveState) => Promise<OfferRead | undefined>
|
|
123
109
|
// Where `lane:launch`'s chain ended — `launched`, `unopened` (no lane taken) or `failed` (one taken).
|
|
@@ -125,12 +111,26 @@ interface DrivePorts {
|
|
|
125
111
|
// The lanes free right now — `backlog_ready.drive_free_lane_count` in production, the limit less the
|
|
126
112
|
// open lanes.
|
|
127
113
|
free_lanes: () => Promise<number>
|
|
128
|
-
//
|
|
129
|
-
|
|
114
|
+
// The places left under the limit, port seats aside — `backlog_ready.drive_limit_room` in production.
|
|
115
|
+
limit_room: () => Promise<number>
|
|
116
|
+
// Whether the issue already holds a kept lane (one a child was dispatched into) — it is reused, and
|
|
117
|
+
// seated ahead of a fresh launch inside the limit room (`backlog-drive-seats.ts`).
|
|
130
118
|
has_lane: (issue: string) => Promise<boolean>
|
|
131
119
|
// How many open issues lacking `auto-ok` still owe a judgement — `auto_ok_judge_read.owed` in
|
|
132
120
|
// production, `0` when the read failed.
|
|
133
121
|
judgement_owed: () => Promise<number>
|
|
122
|
+
// Whether the machine has no memory for one more lane — `backlog_drive_memory.gauge()` in production,
|
|
123
|
+
// which carries its hysteresis between calls.
|
|
124
|
+
memory_held: () => Promise<boolean>
|
|
125
|
+
// Why an offered pass started nothing (`backlog-drive-hold.ts`). Production records it in the lane
|
|
126
|
+
// ledger only while a lane is free. `undefined` is the run's stop, which owes no lane a child.
|
|
127
|
+
hold: (reason: string | undefined, waiting?: ReadonlyArray<number>) => Promise<void>
|
|
128
|
+
// A watch with nothing in flight — the one idle notification (`backlog-drive-idle.ts`), deduplicated
|
|
129
|
+
// per episode by the port itself.
|
|
130
|
+
idle: (state: DriveState) => Promise<void>
|
|
131
|
+
// A holding offer with nothing in flight — the paused-lane notice (`backlog-drive-paused.ts`), which
|
|
132
|
+
// reads the lane records itself and is deduplicated per pause episode by the port.
|
|
133
|
+
paused: () => Promise<void>
|
|
134
134
|
now: () => Date
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -154,20 +154,12 @@ function ended(reason: string, state: DriveState, token?: string, issue?: string
|
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
|
|
157
|
+
// A drain owing the retrospective, read under a `watch` or a `stop` verdict. Only an empty backlog
|
|
158
|
+
// drains: `backlog:offer` marks the drain on `exhausted` alone, so a watch over a parked or unreadable
|
|
159
|
+
// backlog has no retrospective for `run:step` to fire and stays the driver's.
|
|
160
|
+
function is_drain_owed(read: OfferRead, state: DriveState, verdict: string): boolean {
|
|
160
161
|
return (
|
|
161
|
-
read.verdict ===
|
|
162
|
-
read.answer === EXHAUSTED_ANSWER &&
|
|
163
|
-
state.in_flight.length === 0 &&
|
|
164
|
-
read.is_retrospective_owed === true
|
|
165
|
-
)
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function needs_retrospective(read: OfferRead, state: DriveState): boolean {
|
|
169
|
-
return (
|
|
170
|
-
read.verdict === STOP_VERDICT &&
|
|
162
|
+
read.verdict === verdict &&
|
|
171
163
|
read.answer === EXHAUSTED_ANSWER &&
|
|
172
164
|
state.in_flight.length === 0 &&
|
|
173
165
|
read.is_retrospective_owed === true
|
|
@@ -196,10 +188,12 @@ function merge_stopped(issue: string, state: DriveState): DriveState {
|
|
|
196
188
|
}
|
|
197
189
|
}
|
|
198
190
|
|
|
199
|
-
//
|
|
200
|
-
//
|
|
191
|
+
// A merged child is excluded because `backlog:next` may still read it OPEN, and a withdrawn one because
|
|
192
|
+
// `lane:withdraw` leaves it OPEN for the next run, not this one (joshuafolkken/kit#4365). Any other is
|
|
193
|
+
// classified by its labels, so excluding it would hide a child a person released for the rest of the
|
|
194
|
+
// process.
|
|
201
195
|
function excluded(issue: string, outcome: Collected['outcome'], state: DriveState): Array<string> {
|
|
202
|
-
if (outcome
|
|
196
|
+
if (!EXCLUDED_OUTCOMES.has(outcome) || state.exclude.includes(issue)) return state.exclude
|
|
203
197
|
|
|
204
198
|
return [...state.exclude, issue]
|
|
205
199
|
}
|
|
@@ -251,6 +245,8 @@ async function collect_finished(state: DriveState, ports: DrivePorts): Promise<P
|
|
|
251
245
|
current = result.state
|
|
252
246
|
}
|
|
253
247
|
|
|
248
|
+
await backlog_drive_hold.stopped(state, current, ports)
|
|
249
|
+
|
|
254
250
|
return { kind: 'continue', state: current }
|
|
255
251
|
}
|
|
256
252
|
|
|
@@ -271,8 +267,8 @@ async function refused(
|
|
|
271
267
|
|
|
272
268
|
// **No more new lanes than free lanes**. `backlog:offer` lists every ready issue without reading the
|
|
273
269
|
// lanes, so launching all of them overran `JOSH_LANE_LIMIT` until `lane:open` ran out of seats. An issue
|
|
274
|
-
// that already holds a kept lane reuses
|
|
275
|
-
// up to the free count, read
|
|
270
|
+
// that already holds a kept lane reuses its port seat but takes a place under the limit, ahead of a
|
|
271
|
+
// fresh launch; the rest launch up to the free count (`backlog-drive-seats.ts`), read before the first.
|
|
276
272
|
//
|
|
277
273
|
// **Only a launch is activity**: a pass that started nothing — every lane taken
|
|
278
274
|
// — keeps `active` where it was, or the once-a-minute offer would restart the idle budget for good.
|
|
@@ -310,7 +306,10 @@ async function launch_all(
|
|
|
310
306
|
// parent's. With children still running the watch is only waiting on them.
|
|
311
307
|
function on_verdict(read: OfferRead, state: DriveState): PassResult {
|
|
312
308
|
if (!KNOWN_VERDICTS.has(read.verdict)) return ended(read.verdict, state, read.verdict)
|
|
313
|
-
|
|
309
|
+
|
|
310
|
+
if (is_drain_owed(read, state, STOP_VERDICT)) {
|
|
311
|
+
return ended('retrospective', state, 'retrospective')
|
|
312
|
+
}
|
|
314
313
|
|
|
315
314
|
if (read.verdict === STOP_VERDICT) {
|
|
316
315
|
return {
|
|
@@ -324,43 +323,44 @@ function on_verdict(read: OfferRead, state: DriveState): PassResult {
|
|
|
324
323
|
}
|
|
325
324
|
}
|
|
326
325
|
|
|
327
|
-
if (
|
|
326
|
+
if (is_drain_owed(read, state, WATCH_VERDICT)) return ended(WATCH_VERDICT, state, WATCH_VERDICT)
|
|
328
327
|
|
|
329
328
|
return { kind: 'continue', state }
|
|
330
329
|
}
|
|
331
330
|
|
|
332
|
-
//
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
if (!is_exhausted || (await ports.free_lanes()) <= NO_FREE_LANES) return false
|
|
331
|
+
// An offer answered `run`: launched while the machine has memory to spare, held until it does otherwise.
|
|
332
|
+
async function run_offered(
|
|
333
|
+
issues: ReadonlyArray<string>,
|
|
334
|
+
state: DriveState,
|
|
335
|
+
ports: DrivePorts,
|
|
336
|
+
): Promise<PassResult> {
|
|
337
|
+
if (await ports.memory_held()) return await backlog_drive_memory.held(state, ports)
|
|
340
338
|
|
|
341
|
-
return
|
|
339
|
+
return await launch_all(issues, state, ports)
|
|
342
340
|
}
|
|
343
341
|
|
|
342
|
+
// Every offer answers the memory hold afresh: one that is not `run` leaves nothing held for memory.
|
|
344
343
|
async function ask_offer(state: DriveState, ports: DrivePorts): Promise<PassResult> {
|
|
345
344
|
const read = await ports.offer(state)
|
|
346
345
|
|
|
347
346
|
if (read === undefined) return ended('offer', state)
|
|
348
347
|
|
|
349
|
-
const next = { ...state, retries: read.retries }
|
|
348
|
+
const next = { ...state, retries: read.retries, is_memory_held: false }
|
|
350
349
|
|
|
351
|
-
if (read.verdict === RUN_VERDICT) return await
|
|
352
|
-
if (await
|
|
350
|
+
if (read.verdict === RUN_VERDICT) return await run_offered(read.issues, next, ports)
|
|
351
|
+
if (await backlog_drive_judge.is_owed(read, ports)) return ended(JUDGE_REASON, next, JUDGE_REASON)
|
|
353
352
|
|
|
354
|
-
|
|
353
|
+
const idle = await backlog_drive_idle.noticed(on_verdict(read, next), read, ports)
|
|
354
|
+
const result = await backlog_drive_paused.noticed(idle, read, ports)
|
|
355
|
+
|
|
356
|
+
return await backlog_drive_hold.held(result, read, ports)
|
|
355
357
|
}
|
|
356
358
|
|
|
357
359
|
// One pass: collect every child that ended, then — unless a `stop` has been read — ask what to start.
|
|
358
360
|
// `should_offer` is the caller's throttle on the one network read; a collection always asks, because a
|
|
359
361
|
// lane just freed.
|
|
360
362
|
function is_offering(before: DriveState, after: DriveState, should_offer: boolean): boolean {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
return should_offer || after.in_flight.length !== before.in_flight.length
|
|
363
|
+
return !after.is_stopping && (should_offer || after.in_flight.length !== before.in_flight.length)
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
// A stopping run with nothing left in flight has ended.
|
|
@@ -377,10 +377,11 @@ async function run_pass(
|
|
|
377
377
|
should_offer: boolean,
|
|
378
378
|
ports: DrivePorts,
|
|
379
379
|
): Promise<PassResult> {
|
|
380
|
-
const
|
|
380
|
+
const held = await backlog_drive_adopt.held(state, should_offer, ports)
|
|
381
|
+
const collected = await collect_finished(held, ports)
|
|
381
382
|
|
|
382
383
|
if (collected.kind === 'end') return collected
|
|
383
|
-
if (!is_offering(
|
|
384
|
+
if (!is_offering(held, collected.state, should_offer)) return settle(collected)
|
|
384
385
|
|
|
385
386
|
return settle(await ask_offer(collected.state, ports))
|
|
386
387
|
}
|
|
@@ -419,10 +420,13 @@ function is_window_spent(run: LoopRun, config: LoopConfig, now_ms: number): bool
|
|
|
419
420
|
type LoopStep = { kind: 'end'; end: DriveEnd } | { kind: 'next'; run: LoopRun }
|
|
420
421
|
|
|
421
422
|
// One pass of the loop: the offer is due on the first pass and then no oftener than `offer_ms`, bar the
|
|
422
|
-
// passes that collected a child. A `next` carries the run
|
|
423
|
+
// passes that collected a child and the one that finds a memory hold cleared. A `next` carries the run
|
|
424
|
+
// to sleep on and pass again.
|
|
423
425
|
async function loop_step(run: LoopRun, config: LoopConfig, ports: LoopPorts): Promise<LoopStep> {
|
|
424
426
|
const now_ms = ports.now().getTime()
|
|
425
|
-
const is_due =
|
|
427
|
+
const is_due =
|
|
428
|
+
now_ms - run.offered_ms >= config.offer_ms ||
|
|
429
|
+
(await backlog_drive_memory.is_cleared(run.state, ports))
|
|
426
430
|
const result = await run_pass(run.state, is_due, ports)
|
|
427
431
|
|
|
428
432
|
ports.on_state(result.state)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { backlog_next } from './backlog-next'
|
|
4
|
+
|
|
5
|
+
// The `josh backlog:next` entry, kept apart from `backlog-next.ts` because other modules import that
|
|
6
|
+
// one: a bundle is one file, so a main guard there would fire for every command that carries it
|
|
7
|
+
// (joshuafolkken/kit#4186).
|
|
8
|
+
//
|
|
9
|
+
// `process.exitCode` rather than `process.exit()`, for the reason `auto-ok:next` records: the whole
|
|
10
|
+
// contract is `answers=$(pnpm josh backlog:next)`, and exiting outright can cut the pipe before it
|
|
11
|
+
// has drained.
|
|
12
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
13
|
+
const ARGV_OFFSET = 2
|
|
14
|
+
|
|
15
|
+
process.exitCode = await backlog_next.run(process.argv.slice(ARGV_OFFSET))
|
|
16
|
+
}
|