@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
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { machine_capacity, type MachineSample } from '#scripts/gate/machine-capacity'
|
|
2
|
+
import {
|
|
3
|
+
run_board_machine,
|
|
4
|
+
type MachineGauges,
|
|
5
|
+
type MachineMark,
|
|
6
|
+
} from '#scripts/run/board/run-board-machine'
|
|
7
|
+
import type { DrivePorts, DriveState, PassResult } from './backlog-drive'
|
|
8
|
+
|
|
9
|
+
// Whether the machine has room for one more lane (joshuafolkken/kit#4084). The lane limit counts lanes,
|
|
10
|
+
// not memory, so a lane opened while the machine swapped slowed every gate already running.
|
|
11
|
+
//
|
|
12
|
+
// **The reading is `run:board`'s own** (`run-board-machine.ts`): 🧠 and 💾 are the figures a person
|
|
13
|
+
// sees beside the waiting row, and the thresholds are the gauges' red and yellow.
|
|
14
|
+
//
|
|
15
|
+
// **Stopping is looser than resuming, so a machine near one threshold does not open and stop in turn.**
|
|
16
|
+
// A lane stops being opened when the kernel calls the memory critical, 🧠 turns red or 💾 swaps at a
|
|
17
|
+
// red rate. It resumes only once the kernel reads under critical and 🧠 and 💾 are both back under
|
|
18
|
+
// yellow. The kernel's warning is no hold (joshuafolkken/kit#4199): macOS keeps it long after the
|
|
19
|
+
// pressure passed, so a run held on it never resumed.
|
|
20
|
+
//
|
|
21
|
+
// **The 🧠 resume bar stays at yellow (70%) on measurement** (joshuafolkken/kit#4529). Across the
|
|
22
|
+
// 2026-10-22 run on an 18 GB machine (106 one-minute samples, 24 after the whole-suite and vitest-worker
|
|
23
|
+
// cuts merged) 🧠 never reached 70%, peaking at 67%; every memory hold, 1.3 minutes in all, came with a
|
|
24
|
+
// swap burst. 💾 is what holds a lane, so a lower 🧠 bar would admit nothing sooner and only risk swap.
|
|
25
|
+
//
|
|
26
|
+
// **A figure that could not be read is no limit**, as in the gate's core budget: a machine without
|
|
27
|
+
// `sysctl` dispatches as it did before memory was read.
|
|
28
|
+
|
|
29
|
+
const { MEMORY_RED, MEMORY_YELLOW, SWAP_RED_MB_PER_S, SWAP_YELLOW_MB_PER_S } = run_board_machine
|
|
30
|
+
const { PRESSURE_HOLD } = machine_capacity
|
|
31
|
+
// Two readings closer than this give no swap rate: a page swapped in a few milliseconds is no rate.
|
|
32
|
+
const MIN_RATE_MS = 1000
|
|
33
|
+
// The `hold` reason a pass held by memory records, read back by `run:board` and `lane:stats`.
|
|
34
|
+
const HOLD_REASON = 'memory'
|
|
35
|
+
|
|
36
|
+
type MemoryGauges = Pick<MachineGauges, 'memory_percent' | 'swap_mb_per_s' | 'memory_pressure'>
|
|
37
|
+
|
|
38
|
+
function is_kernel_pressured(gauges: MemoryGauges): boolean {
|
|
39
|
+
return (gauges.memory_pressure ?? 0) >= PRESSURE_HOLD
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function is_stop(gauges: MemoryGauges): boolean {
|
|
43
|
+
return (
|
|
44
|
+
is_kernel_pressured(gauges) ||
|
|
45
|
+
(gauges.memory_percent ?? 0) >= MEMORY_RED ||
|
|
46
|
+
(gauges.swap_mb_per_s ?? 0) >= SWAP_RED_MB_PER_S
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function is_resume(gauges: MemoryGauges): boolean {
|
|
51
|
+
return (
|
|
52
|
+
!is_kernel_pressured(gauges) &&
|
|
53
|
+
(gauges.memory_percent ?? 0) < MEMORY_YELLOW &&
|
|
54
|
+
(gauges.swap_mb_per_s ?? 0) < SWAP_YELLOW_MB_PER_S
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface GaugePorts {
|
|
59
|
+
read: () => Promise<MachineSample>
|
|
60
|
+
now: () => number
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const PRODUCTION: GaugePorts = { read: machine_capacity.read_sample, now: Date.now }
|
|
64
|
+
|
|
65
|
+
// What one gauge carries between calls.
|
|
66
|
+
interface GaugeMemo {
|
|
67
|
+
last: MachineMark | undefined
|
|
68
|
+
// The last swap rate measured, kept for a reading too close to the last to measure its own.
|
|
69
|
+
swap_mb_per_s: number | undefined
|
|
70
|
+
is_held: boolean
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// The reading's gauges, the rate measured from the last reading at least `MIN_RATE_MS` old; the last
|
|
74
|
+
// moves on only then, so two close calls keep measuring from the same one. A reading too close to
|
|
75
|
+
// measure keeps the last rate measured, so a held machine still swapping does not read 0 and resume.
|
|
76
|
+
function is_rate_of(last: MachineMark | undefined, mark: MachineMark): last is MachineMark {
|
|
77
|
+
return last !== undefined && mark.at_ms - last.at_ms >= MIN_RATE_MS
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function rated(memo: GaugeMemo, mark: MachineMark): MemoryGauges {
|
|
81
|
+
const { last } = memo
|
|
82
|
+
const is_rated = is_rate_of(last, mark)
|
|
83
|
+
|
|
84
|
+
if (last === undefined || is_rated) memo.last = mark
|
|
85
|
+
|
|
86
|
+
const gauges = run_board_machine.gauges_of(is_rated ? last : undefined, mark)
|
|
87
|
+
|
|
88
|
+
if (is_rated) memo.swap_mb_per_s = gauges.swap_mb_per_s
|
|
89
|
+
|
|
90
|
+
return { ...gauges, swap_mb_per_s: memo.swap_mb_per_s }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// The production `memory_held` port: each call reads the machine once, and the hold is carried
|
|
94
|
+
// between calls — a held machine waits for the resume, a free one for the stop.
|
|
95
|
+
function gauge(ports: GaugePorts = PRODUCTION): () => Promise<boolean> {
|
|
96
|
+
const memo: GaugeMemo = { last: undefined, swap_mb_per_s: undefined, is_held: false }
|
|
97
|
+
|
|
98
|
+
return async function memory_held(): Promise<boolean> {
|
|
99
|
+
const gauges = rated(memo, { sample: await ports.read(), at_ms: ports.now() })
|
|
100
|
+
|
|
101
|
+
memo.is_held = memo.is_held ? !is_resume(gauges) : is_stop(gauges)
|
|
102
|
+
|
|
103
|
+
return memo.is_held
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// An offer that answered `run` on a machine with no room: nothing launches, the pass records why, and
|
|
108
|
+
// the loop polls the memory until it clears.
|
|
109
|
+
async function held(state: DriveState, ports: Pick<DrivePorts, 'hold'>): Promise<PassResult> {
|
|
110
|
+
await ports.hold(HOLD_REASON)
|
|
111
|
+
|
|
112
|
+
return { kind: 'continue', state: { ...state, is_memory_held: true } }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Whether a held run's memory cleared since: the pass asks the offer again, not waiting out its interval.
|
|
116
|
+
async function is_cleared(
|
|
117
|
+
state: DriveState,
|
|
118
|
+
ports: Pick<DrivePorts, 'memory_held'>,
|
|
119
|
+
): Promise<boolean> {
|
|
120
|
+
return state.is_memory_held === true && !(await ports.memory_held())
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const backlog_drive_memory = { HOLD_REASON, gauge, held, is_cleared }
|
|
124
|
+
|
|
125
|
+
export { backlog_drive_memory }
|
|
126
|
+
export type { MemoryGauges }
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
2
|
-
import { EPIC_LABEL, has_label_name,
|
|
2
|
+
import { EPIC_LABEL, has_label_name, has_parked_label } from '#scripts/issue/issue-labels'
|
|
3
3
|
import type { IssueState } from '#scripts/issue/issue-state'
|
|
4
4
|
import { issue_state_cli } from '#scripts/issue/issue-state-cli'
|
|
5
5
|
import type { RunCarry } from '#scripts/run/carry/run-carry'
|
|
6
|
-
import { run_carry_added } from '#scripts/run/carry/run-carry-added'
|
|
7
6
|
import type { MergeResult } from '#scripts/run/merge/run-merge-cli'
|
|
8
|
-
import { run_invocation } from '#scripts/run/run-invocation'
|
|
9
7
|
import { backlog_budget } from './backlog-budget'
|
|
10
8
|
import type { DriveState, OfferRead } from './backlog-drive'
|
|
11
9
|
import { backlog_drive_epic } from './backlog-drive-epic'
|
|
@@ -52,12 +50,12 @@ function budget_offer(
|
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
// The outcome a named issue has already reached without this run dispatching it: closed is merged, and
|
|
55
|
-
// a `
|
|
56
|
-
// Either is booked done rather than offered.
|
|
53
|
+
// a park (`PARKED_LABELS`) waits on a person, so re-dispatching it only repeats the stop it parked on.
|
|
54
|
+
// Either is booked done rather than offered — the same reading `run:merge` gives a parked child.
|
|
57
55
|
function settled_outcome(state: IssueState): MergeResult['outcome'] | undefined {
|
|
58
56
|
if (state.state.toUpperCase() === 'CLOSED') return 'merged'
|
|
59
57
|
|
|
60
|
-
return
|
|
58
|
+
return has_parked_label(state.labels) ? 'parked' : undefined
|
|
61
59
|
}
|
|
62
60
|
|
|
63
61
|
async function classify(
|
|
@@ -102,10 +100,7 @@ async function is_unmerged(issue: number, merged: ReadonlyArray<number>): Promis
|
|
|
102
100
|
// The issues `run:add` put in count too: one that parked is no more a merge
|
|
103
101
|
// than a declared one.
|
|
104
102
|
async function unmerged_of(carry: RunCarry): Promise<Array<number>> {
|
|
105
|
-
const declared =
|
|
106
|
-
run_invocation.issue_numbers(carry.invocation) ?? [],
|
|
107
|
-
carry.added,
|
|
108
|
-
)
|
|
103
|
+
const declared = backlog_drive_named.named_issues(carry)
|
|
109
104
|
const merged = carry.merged_issues ?? []
|
|
110
105
|
const flags = await Promise.all(declared.map(async (issue) => await is_unmerged(issue, merged)))
|
|
111
106
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { lane_parked } from '#scripts/lane/lane-parked'
|
|
2
2
|
import { run_carry, type RunCarry } from '#scripts/run/carry/run-carry'
|
|
3
|
+
import { run_carry_added } from '#scripts/run/carry/run-carry-added'
|
|
3
4
|
import type { RunEvent } from '#scripts/run/event/run-event-stream'
|
|
4
5
|
import type { MergeResult } from '#scripts/run/merge/run-merge-cli'
|
|
5
6
|
import { run_merge_token } from '#scripts/run/merge/run-merge-token'
|
|
@@ -23,18 +24,37 @@ function is_declared(carry: RunCarry, issue: string): boolean {
|
|
|
23
24
|
// An issue `run:add` put in that is already in flight holds nothing up: it was
|
|
24
25
|
// asked for on its own, so the declared item behind it — an epic whose children fill the free lanes —
|
|
25
26
|
// is offered beside it. A declared issue in flight still holds the ones declared after it.
|
|
26
|
-
function is_held(carry: RunCarry,
|
|
27
|
-
return !
|
|
27
|
+
function is_held(carry: RunCarry, in_flight: ReadonlyArray<string>, issue: number): boolean {
|
|
28
|
+
return !in_flight.includes(String(issue)) || is_declared(carry, String(issue))
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
function next_of(carry: RunCarry,
|
|
31
|
+
function next_of(carry: RunCarry, in_flight: ReadonlyArray<string>): number | undefined {
|
|
31
32
|
const remaining = run_carry.remaining_of(carry) ?? []
|
|
32
33
|
|
|
33
|
-
return remaining.find((issue) => is_held(carry,
|
|
34
|
+
return remaining.find((issue) => is_held(carry, in_flight, issue)) ?? remaining[FIRST]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// The declared issue `issue` starts after while the declared order holds it: the one declared just
|
|
38
|
+
// before it, once it is behind `next_of` — what `offer` runs or waits on — whether that has started yet
|
|
39
|
+
// or not (joshuafolkken/kit#4279). `run:board` names it on the queued row; an issue `run:add` put in, or
|
|
40
|
+
// one already in flight, is held by nothing.
|
|
41
|
+
function held_after(
|
|
42
|
+
carry: RunCarry,
|
|
43
|
+
in_flight: ReadonlyArray<string>,
|
|
44
|
+
issue: number,
|
|
45
|
+
): number | undefined {
|
|
46
|
+
const next = next_of(carry, in_flight)
|
|
47
|
+
if (next === undefined || in_flight.includes(String(issue))) return undefined
|
|
48
|
+
const declared = (run_carry.remaining_of(carry) ?? []).filter((number) =>
|
|
49
|
+
is_declared(carry, String(number)),
|
|
50
|
+
)
|
|
51
|
+
const index = declared.indexOf(issue)
|
|
52
|
+
|
|
53
|
+
return index > declared.indexOf(next) ? declared[index - 1] : undefined
|
|
34
54
|
}
|
|
35
55
|
|
|
36
56
|
function offer(carry: RunCarry, state: DriveState, is_only: boolean): OfferRead | undefined {
|
|
37
|
-
const next = next_of(carry, state)
|
|
57
|
+
const next = next_of(carry, state.in_flight)
|
|
38
58
|
|
|
39
59
|
if (next !== undefined) {
|
|
40
60
|
const issue = String(next)
|
|
@@ -129,4 +149,31 @@ async function reconcile(
|
|
|
129
149
|
}
|
|
130
150
|
}
|
|
131
151
|
|
|
132
|
-
|
|
152
|
+
// The issues the run names: the declared list in its order, with the ones `run:add` put in.
|
|
153
|
+
function named_issues(carry: RunCarry): ReadonlyArray<number> {
|
|
154
|
+
return run_carry_added.ordered(run_invocation.issue_numbers(carry.invocation) ?? [], carry.added)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// **A `--only` run adopts only the carried lanes it names** (joshuafolkken/kit#4282): it drains
|
|
158
|
+
// nothing, and its stop waits for every lane in flight, so a lane an earlier invocation dispatched for
|
|
159
|
+
// another issue would hold the run's end until that issue settled. The next draining run collects it.
|
|
160
|
+
function own_carried(
|
|
161
|
+
carry: RunCarry,
|
|
162
|
+
dispatched: ReadonlyArray<string>,
|
|
163
|
+
is_only: boolean,
|
|
164
|
+
): ReadonlyArray<string> {
|
|
165
|
+
if (!is_only) return dispatched
|
|
166
|
+
const named = named_issues(carry)
|
|
167
|
+
|
|
168
|
+
return dispatched.filter((issue) => named.includes(Number(issue)))
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export const backlog_drive_named = {
|
|
172
|
+
next_of,
|
|
173
|
+
offer,
|
|
174
|
+
held_after,
|
|
175
|
+
mark_done,
|
|
176
|
+
named_issues,
|
|
177
|
+
own_carried,
|
|
178
|
+
reconcile,
|
|
179
|
+
}
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
import type { RunCarry } from '#scripts/run/carry/run-carry'
|
|
2
2
|
import type { DriveState } from './backlog-drive'
|
|
3
|
-
|
|
4
|
-
const LIST_SEPARATOR = ','
|
|
3
|
+
import { backlog_offer_exclude } from './backlog-offer-exclude'
|
|
5
4
|
|
|
6
5
|
// **A child in flight is never offered**. A lane child merges its own PR and
|
|
7
6
|
// drops `in-progress` before GitHub closes the issue and before the loop collects it, so `backlog:next`
|
|
8
7
|
// can offer it again; launching it then is refused by its still-open lane and handed to an AI session.
|
|
9
|
-
function excluded(state: DriveState): ReadonlyArray<string> {
|
|
10
|
-
return [...new Set([...state.exclude, ...state.in_flight])]
|
|
11
|
-
}
|
|
12
|
-
|
|
13
8
|
function offer_argv(
|
|
14
9
|
state: DriveState,
|
|
15
10
|
carry: RunCarry,
|
|
16
11
|
forwarded: ReadonlyArray<string>,
|
|
17
12
|
): ReadonlyArray<string> {
|
|
18
|
-
const exclude =
|
|
13
|
+
const exclude = backlog_offer_exclude.exclude_of(state.exclude, state.in_flight)
|
|
19
14
|
|
|
20
15
|
return [
|
|
21
16
|
'backlog:offer',
|
|
@@ -30,7 +25,7 @@ function offer_argv(
|
|
|
30
25
|
String(state.in_flight.length),
|
|
31
26
|
'--retries',
|
|
32
27
|
String(state.retries),
|
|
33
|
-
...(exclude
|
|
28
|
+
...backlog_offer_exclude.exclude_argv(exclude),
|
|
34
29
|
...forwarded,
|
|
35
30
|
]
|
|
36
31
|
}
|
|
@@ -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,4 +1,6 @@
|
|
|
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([
|
|
@@ -46,14 +48,33 @@ function settled_issues(events: ReadonlyArray<RunEvent>): ReadonlySet<number> {
|
|
|
46
48
|
)
|
|
47
49
|
}
|
|
48
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
|
+
|
|
49
76
|
function parked_issues(events: ReadonlyArray<RunEvent>): ReadonlySet<number> {
|
|
50
|
-
return new Set(
|
|
51
|
-
events
|
|
52
|
-
.filter((event) => event.kind === run_event_stream.EVENT_KIND.PARK)
|
|
53
|
-
.map((event) => issue_of(event))
|
|
54
|
-
.filter((issue) => issue !== undefined)
|
|
55
|
-
.map(Number),
|
|
56
|
-
)
|
|
77
|
+
return new Set(issues_of_kind(events, run_event_stream.EVENT_KIND.PARK).map(Number))
|
|
57
78
|
}
|
|
58
79
|
|
|
59
80
|
// The issues this invocation launched or settled — any other dispatched lane was carried in from an
|
|
@@ -87,7 +108,9 @@ function restore(
|
|
|
87
108
|
export const backlog_drive_restore = {
|
|
88
109
|
active_issues,
|
|
89
110
|
mentioned_issues,
|
|
111
|
+
offer_exclude,
|
|
90
112
|
restore,
|
|
113
|
+
withdrawn_issues,
|
|
91
114
|
settled_issues,
|
|
92
115
|
parked_issues,
|
|
93
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 }
|