@joshuafolkken/kit 1.1514.0 → 1.1784.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -1
- package/.claude/settings.json +5 -5
- package/.claude/skills/epic-commands/SKILL.md +26 -65
- package/.claude/skills/epic-commands/epic-bundle.md +3 -1
- package/.claude/skills/workflow-commands/SKILL.md +5 -5
- package/.claude/skills/workflow-commands/background-commands.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
- package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +13 -7
- package/.claude/skills/workflow-commands/delegation.md +6 -5
- package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
- package/.claude/skills/workflow-commands/followup.md +9 -31
- package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
- package/.claude/skills/workflow-commands/fullrun.md +2 -2
- package/.claude/skills/workflow-commands/halfrun.md +17 -25
- package/.claude/skills/workflow-commands/issue-comments.md +16 -12
- package/.claude/skills/workflow-commands/issue-scout.md +2 -2
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +7 -12
- package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
- package/.claude/skills/workflow-commands/observation-filing.md +4 -36
- package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
- package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
- package/.claude/skills/workflow-commands/prerequisite.md +10 -16
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +3 -7
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +13 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-node/action.yml +9 -0
- package/.github/actions/setup-pnpm/action.yml +1 -1
- package/.github/dependabot.yml +16 -0
- package/.github/release.yml +0 -2
- package/.github/workflows/ci.yml +120 -10
- package/.github/workflows/publish.yml +8 -1
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +3 -7
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +3 -7
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
- package/dist/commands/read-set-cli.js +1867 -0
- package/dist/commands/run-prep-main.js +21653 -0
- package/dist/commands/run-step-cli.js +23880 -0
- package/dist/config-merge/index.js +5 -1
- package/dist/hooks/audit-provision.js +20 -35
- package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
- package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
- package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
- package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
- package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -22
- package/dist/hooks/format-edited.js +5 -6
- package/dist/hooks/inputs.json +443 -317
- package/dist/hooks/pretool-guard.js +7 -25
- package/dist/hooks/session-lang.js +44 -51
- package/dist/hooks/stop-guard.js +7716 -2187
- package/dist/josh.js +6002 -3583
- package/dist/self-sync-guard/index.js +74 -10
- package/dist/version/index.js +115 -406
- package/eslint/base.js +1 -1
- package/lefthook/base.yml +3 -1
- package/package.json +10 -48
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -7
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +33 -16
- package/prompts/collaboration-workflow/lane-instructions.md +1 -2
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +4 -6
- package/prompts/collaboration-workflow/output-bounds.md +2 -7
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +5 -0
- package/prompts/collaboration-workflow/report-format.md +31 -60
- package/prompts/collaboration-workflow/residency.md +2 -2
- package/prompts/collaboration-workflow/shell-body.md +6 -16
- package/prompts/collaboration-workflow/turn-batching.md +0 -2
- package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
- package/prompts/collaboration-workflow/wip-cap.md +1 -1
- package/prompts/collaboration-workflow.md +3 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +41 -21
- package/prompts/testing-guide.md +8 -43
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +14 -16
- package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
- package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
- package/scripts/auto-ok/auto-ok-judge.ts +13 -2
- package/scripts/auto-ok/auto-ok-main.ts +17 -0
- package/scripts/backlog/backlog-arrival.ts +14 -3
- package/scripts/backlog/backlog-budget-cli.ts +7 -33
- package/scripts/backlog/backlog-budget-main.ts +16 -0
- package/scripts/backlog/backlog-budget.ts +2 -3
- package/scripts/backlog/backlog-defect-priority.ts +4 -3
- package/scripts/backlog/backlog-drive-adopt.ts +67 -0
- package/scripts/backlog/backlog-drive-args.ts +4 -5
- package/scripts/backlog/backlog-drive-cli.ts +113 -28
- package/scripts/backlog/backlog-drive-hold.ts +162 -0
- package/scripts/backlog/backlog-drive-idle.ts +151 -0
- package/scripts/backlog/backlog-drive-judge.ts +25 -0
- package/scripts/backlog/backlog-drive-memory.ts +126 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
- package/scripts/backlog/backlog-drive-named.ts +53 -6
- package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
- package/scripts/backlog/backlog-drive-paused.ts +169 -0
- package/scripts/backlog/backlog-drive-restore.ts +30 -7
- package/scripts/backlog/backlog-drive-seats.ts +18 -8
- package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
- package/scripts/backlog/backlog-drive.ts +79 -75
- package/scripts/backlog/backlog-next-main.ts +16 -0
- package/scripts/backlog/backlog-next-shared.ts +73 -0
- package/scripts/backlog/backlog-next.ts +48 -16
- package/scripts/backlog/backlog-occupied.ts +52 -39
- package/scripts/backlog/backlog-offer-cli.ts +6 -21
- package/scripts/backlog/backlog-offer-exclude.ts +15 -0
- package/scripts/backlog/backlog-offer-main.ts +12 -0
- package/scripts/backlog/backlog-offer.ts +36 -3
- package/scripts/backlog/backlog-overlap.ts +22 -4
- package/scripts/backlog/backlog-plan-read.ts +6 -2
- package/scripts/backlog/backlog-plan.ts +18 -4
- package/scripts/backlog/backlog-pool.ts +10 -10
- package/scripts/backlog/backlog-rank.ts +10 -2
- package/scripts/backlog/backlog-ready.ts +112 -30
- package/scripts/backlog/backlog-stalled-detect.ts +109 -36
- package/scripts/backlog/backlog-stalled.ts +52 -16
- package/scripts/backlog/backlog-wait-cause.ts +86 -0
- package/scripts/backlog/backlog-waves.ts +39 -13
- package/scripts/backlog/backlogrun-args.ts +19 -7
- package/scripts/backlog/backlogrun-cli.ts +19 -5
- package/scripts/backlog/backlogrun-launch.ts +6 -0
- package/scripts/backlog/backlogrun-restart.ts +97 -0
- package/scripts/backlog/backlogrun-stop.ts +79 -7
- package/scripts/behavior/behavior-cli.ts +2 -2
- package/scripts/behavior/behavior-rules.ts +47 -24
- package/scripts/build/build-bin.ts +2 -16
- package/scripts/build/build-claude-md.ts +0 -7
- package/scripts/build/build-commands.ts +0 -13
- package/scripts/build/build-hooks.ts +49 -48
- package/scripts/build/hook-bundle-stamp.ts +29 -11
- package/scripts/build/local-bin.ts +1 -1
- package/scripts/cases/cases-cli.ts +25 -13
- package/scripts/cases/cases-interaction-scan.ts +134 -0
- package/scripts/cases/cases-interaction.ts +183 -0
- package/scripts/cases/cases-logic.ts +39 -6
- package/scripts/ci/pr-classification-main.ts +18 -0
- package/scripts/ci/pr-classification.ts +10 -17
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/cost-runtime/cost-blocks.ts +22 -37
- package/scripts/cost-runtime/cost-cli.ts +31 -14
- package/scripts/cost-runtime/cost-main.ts +12 -0
- package/scripts/cost-runtime/cost-transcript.ts +1 -0
- package/scripts/delegation/delegation-policy.ts +17 -4
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/investigation-guard.ts +0 -8
- package/scripts/delegation/investigation-reads.ts +3 -4
- package/scripts/dependabot/dependabot-cooldown.ts +194 -0
- package/scripts/discovery/repo-discovery.ts +24 -6
- package/scripts/doctor/doctor-consumer.ts +2 -5
- package/scripts/document/document-byte-budget.ts +8 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +0 -8
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-busy.ts +5 -12
- package/scripts/epic/epic-classify.ts +24 -15
- package/scripts/epic/epic-cli-argv.ts +31 -0
- package/scripts/epic/epic-cli-decide.ts +42 -0
- package/scripts/epic/epic-cli.ts +6 -38
- package/scripts/epic/epic-close.ts +112 -55
- package/scripts/epic/epic-cross-repo.ts +4 -7
- package/scripts/epic/epic-decide.ts +119 -0
- package/scripts/epic/epic-decision.ts +9 -0
- package/scripts/epic/epic-fetch.ts +4 -0
- package/scripts/epic/epic-graph.ts +2 -0
- package/scripts/epic/epic-issue.ts +5 -1
- package/scripts/epic/epic-label-age.ts +1 -1
- package/scripts/epic/epic-lane-offer.ts +39 -4
- package/scripts/epic/epic-next-main.ts +24 -0
- package/scripts/epic/epic-next.ts +6 -24
- package/scripts/epic/epic-outside-blocker.ts +6 -2
- package/scripts/epic/epic-parse.ts +9 -3
- package/scripts/epic/epic-read.ts +1 -0
- package/scripts/epic/epic-reconcile.ts +39 -0
- package/scripts/epic/epic-run.ts +10 -1
- package/scripts/epic/epic-solo.ts +50 -14
- package/scripts/epic/epic.ts +41 -7
- package/scripts/exports/unused-members-cli.ts +2 -2
- package/scripts/followup/followup-checks-event.ts +8 -3
- package/scripts/followup/followup-coderabbit-wait.ts +82 -0
- package/scripts/followup/followup-review-gates.ts +81 -0
- package/scripts/followup/git-followup-stages.ts +13 -3
- package/scripts/followup/git-followup-workflow.ts +19 -66
- package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
- package/scripts/followup/git-pr-followup.ts +36 -8
- package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
- package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
- package/scripts/gate/busy-average.ts +58 -0
- package/scripts/gate/check-cpu.ts +60 -0
- package/scripts/gate/check-inputs.ts +39 -95
- package/scripts/gate/check-reuse.ts +33 -54
- package/scripts/gate/command-memory.ts +192 -0
- package/scripts/gate/core-admission.ts +218 -28
- package/scripts/gate/core-budget-timing.ts +37 -0
- package/scripts/gate/core-budget.ts +80 -98
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +37 -5
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +27 -4
- package/scripts/gate/gate-ledger.ts +32 -4
- package/scripts/gate/gate-plan.ts +41 -34
- package/scripts/gate/gate-report.ts +14 -2
- package/scripts/gate/gate-run-steps.ts +53 -8
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +65 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/project-checks.ts +5 -12
- package/scripts/gate/scoped-green.ts +12 -8
- package/scripts/gate/since-green.ts +62 -0
- package/scripts/gate/toolchain-inputs.ts +115 -0
- package/scripts/gate/verification-gate.ts +27 -24
- package/scripts/gate/verification-inputs.ts +250 -0
- package/scripts/gh/gh-author-association.ts +96 -9
- package/scripts/gh/git-ai-review-scan.ts +4 -2
- package/scripts/gh/git-gh-api-path.ts +15 -0
- package/scripts/gh/git-gh-branch-rules.ts +73 -0
- package/scripts/gh/git-gh-conditional.ts +5 -2
- package/scripts/gh/git-gh-issue-read.ts +5 -1
- package/scripts/gh/git-gh-issue-write.ts +67 -29
- package/scripts/gh/git-gh-issue.ts +7 -3
- package/scripts/gh/git-gh-poll-read.ts +89 -0
- package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
- package/scripts/gh/git-gh-pr-rest.ts +1 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
- package/scripts/gh/git-gh-pr.ts +27 -15
- package/scripts/gh/git-pr-checks-eval.ts +39 -7
- package/scripts/gh/git-pr-checks-parse.ts +39 -9
- package/scripts/gh/git-pr-merge-checked.ts +80 -0
- package/scripts/git/base-tree.ts +19 -2
- package/scripts/git/changed-file-scope.ts +6 -4
- package/scripts/git/changed-paths.ts +18 -1
- package/scripts/git/git-diff-reads.ts +27 -2
- package/scripts/git/git-grep-hits.ts +85 -0
- package/scripts/git/git-location-environment.ts +1 -1
- package/scripts/git/git-merge-conflicts.ts +83 -0
- package/scripts/git/git-preflight.ts +37 -12
- package/scripts/git/git-push-transport.ts +1 -2
- package/scripts/git/git-schemas.ts +17 -7
- package/scripts/git/git-spawn.ts +1 -2
- package/scripts/git/git-status.ts +4 -4
- package/scripts/git/main-merge-main.ts +12 -0
- package/scripts/git/main-merge-regenerate.ts +2 -2
- package/scripts/git/main-merge.ts +25 -9
- package/scripts/git/main-sync-main.ts +12 -0
- package/scripts/git/main-sync.ts +0 -9
- package/scripts/git/stash/git-stash.ts +27 -4
- package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
- package/scripts/git/stash/stash-pop-cli.ts +6 -12
- package/scripts/git/stash/stash-pop-main.ts +12 -0
- package/scripts/git/stash/stash-push-cli.ts +76 -0
- package/scripts/git/stash/stash-push-main.ts +12 -0
- package/scripts/hooks/batch-guard.ts +0 -8
- package/scripts/hooks/check-commit-message-main.ts +8 -0
- package/scripts/hooks/check-commit-message.ts +4 -7
- package/scripts/hooks/format-edited-file.ts +8 -24
- package/scripts/hooks/pre-commit-lint.ts +30 -3
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +32 -19
- package/scripts/hooks/reserved-run.ts +67 -9
- package/scripts/hooks/run-hook.sh +13 -4
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +2 -21
- package/scripts/hooks/stop-guard.ts +13 -9
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -17
- package/scripts/init/init-actions.ts +0 -6
- package/scripts/init/init-ai-copy.ts +10 -36
- package/scripts/init/init-bootstrap.ts +9 -8
- package/scripts/init/init-dry-run-report.ts +1 -1
- package/scripts/init/init-dry-run.ts +1 -1
- package/scripts/init/init-file-action.ts +7 -9
- package/scripts/init/init-logic-json-merge.ts +2 -2
- package/scripts/init/init-logic-migrate.ts +9 -82
- package/scripts/init/init-logic.ts +3 -2
- package/scripts/init/init-main.ts +12 -0
- package/scripts/init/init.ts +5 -12
- package/scripts/init/kit-development-versions.ts +3 -7
- package/scripts/init/kit-written-paths.ts +2 -2
- package/scripts/init/project-profile.ts +5 -4
- package/scripts/init/tsconfig-preset-migration.ts +2 -1
- package/scripts/init/vscode-tasks.ts +1 -1
- package/scripts/issue/defect-origin-cli.ts +106 -0
- package/scripts/issue/defect-origin-line.ts +60 -0
- package/scripts/issue/defect-origin-main.ts +11 -0
- package/scripts/issue/defect-origin.ts +114 -0
- package/scripts/issue/defect-rate-cli.ts +34 -78
- package/scripts/issue/defect-rate.ts +0 -16
- package/scripts/issue/defect-report-cli.ts +128 -0
- package/scripts/issue/defect-report-format.ts +56 -0
- package/scripts/issue/defect-report-main.ts +11 -0
- package/scripts/issue/defect-report.ts +160 -0
- package/scripts/issue/expected-effect-lint.ts +1 -0
- package/scripts/issue/issue-already-done-cli.ts +62 -0
- package/scripts/issue/issue-body-or-comment.ts +40 -0
- package/scripts/issue/issue-cite-cli.ts +0 -9
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +12 -7
- package/scripts/issue/issue-comment-cli.ts +10 -24
- package/scripts/issue/issue-comment-main.ts +12 -0
- package/scripts/issue/issue-evidence-exit.ts +100 -0
- package/scripts/issue/issue-file-cli.ts +29 -7
- package/scripts/issue/issue-file.ts +19 -19
- package/scripts/issue/issue-fold-cli.ts +2 -11
- package/scripts/issue/issue-fold-main.ts +12 -0
- package/scripts/issue/issue-labels.ts +81 -90
- package/scripts/issue/issue-lint-cli.ts +2 -10
- package/scripts/issue/issue-lint-main.ts +12 -0
- package/scripts/issue/issue-measured-cli.ts +56 -0
- package/scripts/issue/issue-merged.ts +19 -2
- package/scripts/issue/issue-not-before-label.ts +135 -0
- package/scripts/issue/issue-not-before.ts +111 -0
- package/scripts/issue/issue-number-shape.ts +15 -1
- package/scripts/issue/issue-park.ts +28 -0
- package/scripts/issue/issue-plan-cli.ts +151 -0
- package/scripts/issue/issue-priority.ts +151 -0
- package/scripts/issue/issue-rank.ts +7 -1
- package/scripts/issue/issue-read-cli.ts +3 -10
- package/scripts/issue/issue-read-main.ts +12 -0
- package/scripts/issue/issue-read.ts +29 -5
- package/scripts/issue/issue-release-cli.ts +0 -10
- package/scripts/issue/issue-release-main.ts +13 -0
- package/scripts/issue/issue-release.ts +7 -12
- package/scripts/issue/issue-sample-gate.ts +192 -0
- package/scripts/issue/issue-sample-source.ts +76 -0
- package/scripts/issue/issue-scout-cli.ts +0 -11
- package/scripts/issue/issue-scout-main.ts +14 -0
- package/scripts/issue/issue-state-cli.ts +0 -10
- package/scripts/issue/issue-state-main.ts +12 -0
- package/scripts/issue/issue-watch-diff.ts +56 -15
- package/scripts/issue/issue-watch.ts +2 -1
- package/scripts/issue/issue-wip.ts +2 -7
- package/scripts/issue/measure-rerun-cli.ts +13 -8
- package/scripts/issue/plan-consumers-cli.ts +39 -0
- package/scripts/issue/plan-consumers-main.ts +11 -0
- package/scripts/issue/plan-consumers-section.ts +55 -0
- package/scripts/issue/plan-consumers.ts +127 -0
- package/scripts/josh/agent-session-environment.ts +1 -1
- package/scripts/josh/command-usage.ts +15 -43
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +12 -6
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +157 -158
- package/scripts/josh/josh-commands-backlog.ts +82 -16
- package/scripts/josh/josh-commands-clone.ts +1 -0
- package/scripts/josh/josh-commands-development.ts +111 -71
- package/scripts/josh/josh-commands-document.ts +43 -1
- package/scripts/josh/josh-commands-epic.ts +171 -0
- package/scripts/josh/josh-commands-hooks.ts +25 -2
- package/scripts/josh/josh-commands-issue-write.ts +181 -0
- package/scripts/josh/josh-commands-issue.ts +124 -24
- package/scripts/josh/josh-commands-lane.ts +103 -2
- package/scripts/josh/josh-commands-lint.ts +19 -8
- package/scripts/josh/josh-commands-maintenance.ts +112 -4
- package/scripts/josh/josh-commands-pause.ts +29 -0
- package/scripts/josh/josh-commands-progress.ts +87 -0
- package/scripts/josh/josh-commands-project.ts +138 -9
- package/scripts/josh/josh-commands-review.ts +124 -0
- package/scripts/josh/josh-commands-run.ts +211 -23
- package/scripts/josh/josh-commands-ship.ts +169 -0
- package/scripts/josh/josh-commands-split.ts +9 -0
- package/scripts/josh/josh-commands-versioning.ts +49 -2
- package/scripts/josh/josh-commands-workflow.ts +144 -6
- package/scripts/josh/josh-logic.ts +6 -13
- package/scripts/josh/package-directory.ts +2 -4
- package/scripts/josh/process-identity.ts +13 -4
- package/scripts/josh/session-language-cli.ts +4 -8
- package/scripts/josh/session-language-main.ts +13 -0
- package/scripts/josh/session-language.ts +6 -1
- package/scripts/josh/shared-cache.ts +90 -0
- package/scripts/josh/stamp-file.ts +9 -15
- package/scripts/lane/lane-await.ts +51 -12
- package/scripts/lane/lane-cache.ts +5 -30
- package/scripts/lane/lane-capacity.ts +14 -23
- package/scripts/lane/lane-check-stats.ts +62 -21
- package/scripts/lane/lane-child-invocation.ts +8 -0
- package/scripts/lane/lane-cli.ts +15 -5
- package/scripts/lane/lane-close.ts +86 -18
- package/scripts/lane/lane-core-wait-stats.ts +66 -0
- package/scripts/lane/lane-dispatch.ts +24 -3
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-handoff.ts +69 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +4 -11
- package/scripts/lane/lane-launch-cli.ts +0 -9
- package/scripts/lane/lane-launch-main.ts +12 -0
- package/scripts/lane/lane-ledger-schema.ts +266 -0
- package/scripts/lane/lane-ledger.ts +92 -123
- package/scripts/lane/lane-limit-cli.ts +12 -1
- package/scripts/lane/lane-measure-cli.ts +57 -11
- package/scripts/lane/lane-open.ts +9 -1
- package/scripts/lane/lane-parked.ts +3 -3
- package/scripts/lane/lane-pause-cli.ts +130 -0
- package/scripts/lane/lane-pause.ts +158 -0
- package/scripts/lane/lane-process-table.ts +166 -0
- package/scripts/lane/lane-reap-settle.ts +124 -0
- package/scripts/lane/lane-reap.ts +50 -15
- package/scripts/lane/lane-registry.ts +24 -3
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +22 -2
- package/scripts/lane/lane-round-two-stats.ts +49 -0
- package/scripts/lane/lane-sampler.ts +4 -0
- package/scripts/lane/lane-session-action.ts +19 -5
- package/scripts/lane/lane-session-broker.ts +102 -21
- package/scripts/lane/lane-snapshot-trace.ts +84 -0
- package/scripts/lane/lane-spans.ts +51 -0
- package/scripts/lane/lane-spent.ts +6 -3
- package/scripts/lane/lane-stage-stats.ts +7 -2
- package/scripts/lane/lane-state.ts +302 -0
- package/scripts/lane/lane-stats.ts +58 -4
- package/scripts/lane/lane-stop-stats.ts +113 -37
- package/scripts/lane/lane-test-related-stats.ts +127 -0
- package/scripts/lane/lane-transcript-calls.ts +145 -0
- package/scripts/lane/lane-transcript-stats.ts +168 -0
- package/scripts/lane/lane-vacant.ts +13 -3
- package/scripts/lane/lane-withdraw-cli.ts +5 -4
- package/scripts/lane/lane-withdraw.ts +50 -49
- package/scripts/lane/process-directories.ts +70 -0
- package/scripts/lane/process-lane-marks.ts +94 -0
- package/scripts/lib/atomic-write.ts +62 -0
- package/scripts/lib/buffered-process.ts +12 -5
- package/scripts/lib/cli-flags.ts +53 -0
- package/scripts/lib/figure-format.ts +63 -0
- package/scripts/lib/json-value.ts +9 -1
- package/scripts/lib/package-manifest.ts +35 -0
- package/scripts/lib/read-file.ts +3 -1
- package/scripts/lib/stamped-memo.ts +63 -0
- package/scripts/lib/stdout-on-stderr.ts +24 -0
- package/scripts/lib/timeouts.ts +9 -0
- package/scripts/lib/transcript-record.ts +91 -0
- package/scripts/lines/effective-limit.ts +1 -1
- package/scripts/lint/eslint-cache-dependencies.ts +145 -0
- package/scripts/lint/eslint-daemon.ts +265 -0
- package/scripts/lint/format.ts +11 -2
- package/scripts/lint/import-graph.ts +279 -0
- package/scripts/lint/lint-gate-scope.ts +102 -0
- package/scripts/lint/lint-parallel-main.ts +19 -0
- package/scripts/lint/lint-parallel.ts +62 -30
- package/scripts/lint/lint-related-scope.ts +30 -24
- package/scripts/lint/lint-related.ts +38 -6
- package/scripts/notify/confirmation-options.ts +1 -2
- package/scripts/notify/telegram-notify.ts +20 -20
- package/scripts/notify/telegram-test-logic.ts +0 -1
- package/scripts/notify/telegram-test-main.ts +8 -0
- package/scripts/notify/telegram-test.ts +2 -6
- package/scripts/observations/observation-ledger.ts +13 -0
- package/scripts/observations/observations-flush-landing.ts +5 -3
- package/scripts/observations/observations-flush.ts +6 -1
- package/scripts/overrides/overrides-check.ts +2 -5
- package/scripts/overrides/overrides-files.ts +2 -1
- package/scripts/overrides/overrides-logic.ts +3 -6
- package/scripts/package/verify-optional-eslint-install.ts +8 -6
- package/scripts/propagate/propagate-publish.ts +2 -7
- package/scripts/propagate/propagate-targets.ts +4 -12
- package/scripts/refactor/import-graph.ts +9 -7
- package/scripts/release/github-release-runs.ts +17 -6
- package/scripts/release/release-approval-prune.ts +18 -0
- package/scripts/release/release-history.ts +1 -3
- package/scripts/release/release-progress.ts +42 -22
- package/scripts/release/release-publish-run.ts +39 -0
- package/scripts/release/release-publish.ts +6 -6
- package/scripts/release/release-scope-cli.ts +0 -10
- package/scripts/release/release-scope-main.ts +12 -0
- package/scripts/repo/repo-setting.ts +3 -6
- package/scripts/repo/required-checks-logic.ts +6 -15
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-labels.ts +155 -0
- package/scripts/report/report-lint-cli.ts +3 -0
- package/scripts/report/report-lint.ts +85 -110
- package/scripts/report/report-template-cli.ts +59 -0
- package/scripts/report/report-template.ts +112 -0
- package/scripts/review/acceptance-map.ts +1 -0
- package/scripts/review/removed-tests-check.ts +86 -0
- package/scripts/review/removed-tests.ts +149 -0
- package/scripts/review/review-brief-cli.ts +81 -15
- package/scripts/review/review-brief-main.ts +12 -0
- package/scripts/review/review-brief.ts +31 -3
- package/scripts/review/review-code-tree.ts +10 -6
- package/scripts/review/review-comment-round.ts +26 -8
- package/scripts/review/review-finding-ledger.ts +30 -15
- package/scripts/review/review-interaction.ts +94 -0
- package/scripts/review/review-readers-scan.ts +163 -0
- package/scripts/review/review-record-cli.ts +69 -30
- package/scripts/review/review-record-main.ts +12 -0
- package/scripts/review/review-round-one-blobs.ts +221 -0
- package/scripts/review/review-round2-cli.ts +49 -12
- package/scripts/review/review-round2.ts +80 -12
- package/scripts/review/review-stamps.ts +19 -1
- package/scripts/review/review-stop-log.ts +96 -0
- package/scripts/review/review-stops-cli.ts +85 -0
- package/scripts/review/review-tree.ts +6 -17
- package/scripts/review/review-untouched-readers.ts +146 -0
- package/scripts/review/test-titles.ts +118 -0
- package/scripts/rules/agent-model.ts +8 -0
- package/scripts/rules/bash-triggers.ts +46 -3
- package/scripts/rules/decision-oracle-batch.ts +9 -1
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +80 -2
- package/scripts/rules/destructive-command.ts +8 -1
- package/scripts/rules/direct-filing.ts +10 -2
- package/scripts/rules/direct-issue-comment.ts +117 -0
- package/scripts/rules/direct-pr-create.ts +69 -3
- package/scripts/rules/early-heartbeat.ts +2 -1
- package/scripts/rules/file-body.ts +7 -0
- package/scripts/rules/filing-cap.ts +7 -0
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +4 -0
- package/scripts/rules/implementation-cut-verdict.ts +1 -1
- package/scripts/rules/implementation-cut.ts +11 -3
- package/scripts/rules/index-guard.ts +8 -1
- package/scripts/rules/issue-comments.ts +9 -1
- package/scripts/rules/josh-git-bare.ts +7 -0
- package/scripts/rules/lane-background.ts +67 -25
- package/scripts/rules/lane-carry-conflict.ts +6 -0
- package/scripts/rules/lane-direct-tool.ts +74 -0
- package/scripts/rules/lane-interactive-ask.ts +9 -2
- package/scripts/rules/lane-park.ts +45 -23
- package/scripts/rules/lane-split-park.ts +10 -2
- package/scripts/rules/lane-switch-main.ts +7 -0
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +1 -1
- package/scripts/rules/poll-loop.ts +7 -0
- package/scripts/rules/pr-merge.ts +123 -0
- package/scripts/rules/protected-files.ts +32 -5
- package/scripts/rules/raw-field-body.ts +6 -0
- package/scripts/rules/rule-body-guard.ts +8 -0
- package/scripts/rules/rule-list.ts +9 -28
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +1 -1
- package/scripts/rules/shell-segments.ts +35 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +3 -4
- package/scripts/rules/test-declared-commit.ts +11 -1
- package/scripts/rules/third-party-write.ts +7 -0
- package/scripts/rules/timed-rerun.ts +69 -0
- package/scripts/rules/worktree-guard.ts +13 -3
- package/scripts/run/board/run-board-app-name.ts +23 -0
- package/scripts/run/board/run-board-cli.ts +65 -32
- package/scripts/run/board/run-board-earlier.ts +94 -0
- package/scripts/run/board/run-board-ending-reason.ts +67 -0
- package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
- package/scripts/run/board/run-board-estimate.ts +98 -0
- package/scripts/run/board/run-board-fit.ts +153 -36
- package/scripts/run/board/run-board-fold.ts +123 -0
- package/scripts/run/board/run-board-fresh.ts +2 -2
- package/scripts/run/board/run-board-gather-live.ts +29 -0
- package/scripts/run/board/run-board-gather-thread.ts +189 -0
- package/scripts/run/board/run-board-gather-worker.ts +29 -0
- package/scripts/run/board/run-board-gather.ts +187 -0
- package/scripts/run/board/run-board-github.ts +118 -38
- package/scripts/run/board/run-board-header.ts +82 -20
- package/scripts/run/board/run-board-keys.ts +58 -0
- package/scripts/run/board/run-board-kind.ts +20 -6
- package/scripts/run/board/run-board-labels.ts +116 -71
- package/scripts/run/board/run-board-lane-state.ts +109 -0
- package/scripts/run/board/run-board-lane-time.ts +122 -0
- package/scripts/run/board/run-board-layout.ts +239 -60
- package/scripts/run/board/run-board-length.ts +52 -0
- package/scripts/run/board/run-board-machine.ts +8 -4
- package/scripts/run/board/run-board-main.ts +12 -0
- package/scripts/run/board/run-board-notes.ts +52 -31
- package/scripts/run/board/run-board-now.ts +1 -1
- package/scripts/run/board/run-board-operation.ts +15 -33
- package/scripts/run/board/run-board-phase.ts +1 -1
- package/scripts/run/board/run-board-plan-shared.ts +115 -0
- package/scripts/run/board/run-board-plan.ts +55 -3
- package/scripts/run/board/run-board-planning.ts +45 -0
- package/scripts/run/board/run-board-priority.ts +44 -0
- package/scripts/run/board/run-board-process-groups.ts +195 -0
- package/scripts/run/board/run-board-read.ts +151 -27
- package/scripts/run/board/run-board-reason.ts +235 -51
- package/scripts/run/board/run-board-released.ts +35 -0
- package/scripts/run/board/run-board-render-checks.ts +39 -5
- package/scripts/run/board/run-board-render-condition.ts +96 -0
- package/scripts/run/board/run-board-render-drawn.ts +67 -0
- package/scripts/run/board/run-board-render-foot.ts +59 -0
- package/scripts/run/board/run-board-render-icon.ts +35 -0
- package/scripts/run/board/run-board-render-lanes.ts +145 -0
- package/scripts/run/board/run-board-render-lead.ts +80 -0
- package/scripts/run/board/run-board-render-legend.ts +117 -48
- package/scripts/run/board/run-board-render-notes.ts +156 -29
- package/scripts/run/board/run-board-render-processes.ts +196 -0
- package/scripts/run/board/run-board-render-section.ts +119 -0
- package/scripts/run/board/run-board-render-slot.ts +3 -36
- package/scripts/run/board/run-board-render-tail.ts +115 -48
- package/scripts/run/board/run-board-render-time.ts +56 -0
- package/scripts/run/board/run-board-render-title.ts +117 -24
- package/scripts/run/board/run-board-render-waits.ts +104 -20
- package/scripts/run/board/run-board-render.ts +207 -265
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +9 -4
- package/scripts/run/board/run-board-setup.ts +1 -12
- package/scripts/run/board/run-board-snapshot.ts +111 -0
- package/scripts/run/board/run-board-spin.ts +2 -2
- package/scripts/run/board/run-board-state.ts +22 -33
- package/scripts/run/board/run-board-status.ts +147 -71
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +122 -107
- package/scripts/run/board/run-board-usage-board.ts +78 -0
- package/scripts/run/board/run-board-usage-lanes.ts +113 -0
- package/scripts/run/board/run-board-usage-listing.ts +93 -0
- package/scripts/run/board/run-board-usage-read.ts +120 -150
- package/scripts/run/board/run-board-usage-rusage.ts +19 -7
- package/scripts/run/board/run-board-usage-text.ts +139 -51
- package/scripts/run/board/run-board-usage-top.ts +102 -0
- package/scripts/run/board/run-board-usage.ts +89 -72
- package/scripts/run/board/run-board-usual.ts +20 -9
- package/scripts/run/carry/run-carry-args.ts +4 -7
- package/scripts/run/carry/run-carry-conversation.ts +1 -1
- package/scripts/run/carry/run-carry.ts +9 -4
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/event/run-event-cli.ts +1 -5
- package/scripts/run/event/run-event-filed.ts +12 -6
- package/scripts/run/event/run-event-follow.ts +2 -3
- package/scripts/run/event/run-event-render.ts +6 -10
- package/scripts/run/event/run-event-scope.ts +2 -2
- package/scripts/run/event/run-event-stream-emit.ts +82 -22
- package/scripts/run/event/run-event-stream.ts +34 -8
- package/scripts/run/hold/run-hold-adopt.ts +65 -0
- package/scripts/run/hold/run-hold-cli.ts +93 -22
- package/scripts/run/hold/run-hold-main.ts +12 -0
- package/scripts/run/hold/run-hold-member.ts +37 -0
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +62 -48
- package/scripts/run/merge/run-merge-close.ts +74 -0
- package/scripts/run/merge/run-merge-collect.ts +6 -13
- package/scripts/run/merge/run-merge-driver.ts +71 -0
- package/scripts/run/merge/run-merge-main.ts +12 -0
- package/scripts/run/merge/run-merge-outcome.ts +23 -0
- package/scripts/run/merge/run-merge-restart.ts +39 -0
- package/scripts/run/merge/run-merge-ship.ts +20 -4
- package/scripts/run/merge/run-merge-signals.ts +33 -9
- package/scripts/run/merge/run-merge-steps.ts +120 -85
- package/scripts/run/merge/run-merge.ts +38 -37
- package/scripts/run/park/run-park-cli.ts +91 -0
- package/scripts/run/park/run-park.ts +88 -0
- package/scripts/run/park/run-stalled.ts +68 -0
- package/scripts/run/pause/run-pause-cli.ts +73 -0
- package/scripts/run/pause/run-pause.ts +251 -0
- package/scripts/run/progress/run-progress-cli.ts +4 -12
- package/scripts/run/progress/run-progress-clock.ts +1 -1
- package/scripts/run/progress/run-progress-config.ts +6 -14
- package/scripts/run/progress/run-progress-main.ts +12 -0
- package/scripts/run/progress/run-progress.ts +1 -4
- package/scripts/run/review/run-review.ts +2 -1
- package/scripts/run/run-ending.ts +1 -0
- package/scripts/run/run-invocation.ts +5 -6
- package/scripts/run/run-liveness-cli.ts +6 -8
- package/scripts/run/run-liveness.ts +60 -29
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-preflight.ts +18 -3
- package/scripts/run/run-prep-cli.ts +1 -10
- package/scripts/run/run-prep-locate.ts +7 -50
- package/scripts/run/run-prep-main.ts +12 -0
- package/scripts/run/run-prep.ts +6 -0
- package/scripts/run/run-report-cli.ts +101 -13
- package/scripts/run/run-report-handoff.ts +114 -0
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +13 -0
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +1 -1
- package/scripts/run/ship/run-ship-args.ts +121 -0
- package/scripts/run/ship/run-ship-body-draft.ts +110 -0
- package/scripts/run/ship/run-ship-cli.ts +63 -140
- package/scripts/run/ship/run-ship-detach.ts +19 -8
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +18 -2
- package/scripts/run/ship/run-ship-overlap.ts +42 -5
- package/scripts/run/ship/run-ship-place.ts +96 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
- package/scripts/run/ship/run-ship-preflight.ts +137 -32
- package/scripts/run/ship/run-ship-probe.ts +11 -3
- package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
- package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
- package/scripts/run/ship/run-ship-return.ts +107 -23
- package/scripts/run/ship/run-ship-review-steps.ts +105 -151
- package/scripts/run/ship/run-ship-review.ts +73 -6
- package/scripts/run/ship/run-ship-reviewer.ts +207 -0
- package/scripts/run/ship/run-ship-stage.ts +55 -6
- package/scripts/run/ship/run-ship-steps.ts +46 -15
- package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +43 -6
- package/scripts/run/ship/run-ship.ts +30 -2
- package/scripts/run/tidy/run-tidy-cli.ts +0 -4
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
- package/scripts/run/tidy/run-tidy-main.ts +8 -0
- package/scripts/run/wake/run-wake-cli.ts +119 -100
- package/scripts/run/wake/run-wake-code.ts +83 -0
- package/scripts/run/wake/run-wake-driver.ts +19 -8
- package/scripts/run/wake/run-wake-loop.ts +34 -3
- package/scripts/run/wake/run-wake-main.ts +13 -0
- package/scripts/run/wake/run-wake-ports.ts +90 -0
- package/scripts/run/wake/run-wake-takeover.ts +66 -0
- package/scripts/run/wake/run-wake.ts +2 -1
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -1
- package/scripts/safe-chain/project-config.ts +3 -9
- package/scripts/security/security-audit-main.ts +8 -0
- package/scripts/security/security-audit-provision-logic.ts +0 -11
- package/scripts/security/security-audit-provision-main.ts +12 -0
- package/scripts/security/security-audit-provision.ts +11 -26
- package/scripts/security/security-audit.ts +6 -7
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
- package/scripts/split/split-assess-cli.ts +2 -2
- package/scripts/split/split-assess.ts +15 -0
- package/scripts/split/split-measure.ts +65 -0
- package/scripts/sync/claude-settings-merge.ts +8 -15
- package/scripts/sync/directory-copy-guard.ts +4 -9
- package/scripts/sync/file-content.ts +78 -8
- package/scripts/sync/sync-ai-files.ts +3 -5
- package/scripts/sync/sync-configs.ts +11 -23
- package/scripts/sync/sync-hook-safety.ts +4 -10
- package/scripts/sync/sync-main.ts +11 -0
- package/scripts/sync/sync.ts +25 -37
- package/scripts/test/test-declared-changed.ts +2 -2
- package/scripts/test/test-declared.ts +1 -1
- package/scripts/test/test-e2e-guard.ts +25 -1
- package/scripts/test/test-e2e-stamp.ts +38 -0
- package/scripts/test/test-pinned-logic.ts +145 -0
- package/scripts/test/test-pinned-main.ts +78 -0
- package/scripts/test/test-pinned.ts +100 -0
- package/scripts/test/test-read-map.ts +264 -0
- package/scripts/test/test-read-recording.ts +91 -0
- package/scripts/test/test-read-trace.ts +148 -0
- package/scripts/test/test-red-main.ts +12 -0
- package/scripts/test/test-red.ts +12 -30
- package/scripts/test/test-related-main.ts +18 -0
- package/scripts/test/test-related-record.ts +119 -0
- package/scripts/test/test-related-scope.ts +229 -43
- package/scripts/test/test-related.ts +300 -22
- package/scripts/test/test-unit-guard-main.ts +15 -0
- package/scripts/test/test-unit-guard.ts +42 -24
- package/scripts/test/unit-count-file.ts +37 -0
- package/scripts/test/unit-run-marker.ts +162 -0
- package/scripts/test/unit-setup-files.ts +51 -0
- package/scripts/test/unit-worker-share.ts +61 -149
- package/scripts/test/whole-suite-files.ts +63 -0
- package/scripts/time-runtime/time-background.ts +20 -2
- package/scripts/time-runtime/time-bundles.ts +4 -3
- package/scripts/time-runtime/time-density-hook.ts +8 -6
- package/scripts/time-runtime/time-followup-stage.ts +1 -3
- package/scripts/time-runtime/time-format.ts +5 -28
- package/scripts/time-runtime/time-markers.ts +10 -1
- package/scripts/time-runtime/time-shell.ts +97 -10
- package/scripts/time-runtime/time-transcript-line.ts +49 -62
- package/scripts/uninstall/uninstall.ts +1 -1
- package/scripts/version/bump-version-main.ts +12 -0
- package/scripts/version/bump-version.ts +25 -25
- package/scripts/version/effective-upstream.ts +6 -12
- package/scripts/version/latest-corepack.ts +17 -32
- package/scripts/version/latest-if-required-cli.ts +93 -0
- package/scripts/version/latest-lane-guard-main.ts +8 -0
- package/scripts/version/latest-lane-guard.ts +0 -4
- package/scripts/version/latest-scope-cli.ts +0 -9
- package/scripts/version/latest-scope-main.ts +12 -0
- package/scripts/version/latest-update.ts +5 -5
- package/scripts/version/npm-registry.ts +44 -6
- package/scripts/version/publishable-range-check.ts +5 -16
- package/scripts/version/release-age.ts +1 -1
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/release-window.ts +38 -0
- package/scripts/version/running-binary.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +3 -8
- package/scripts/version/version-targets.ts +6 -28
- package/templates/dependabot.yml +29 -0
- package/templates/gitignore +4 -1
- package/templates/pnpm-workspace.basic.yaml +1 -1
- package/templates/sonar-project.properties +3 -2
- package/templates/workflows/ci.yml +12 -4
- package/templates/workflows/github-release.yml +4 -0
- package/tsconfig.sonar.json +1 -1
- package/.ncurc.json +0 -3
- package/dist/hooks/batch-guard.js +0 -29
- package/dist/hooks/chunk-4KKD2UTK.js +0 -66
- package/dist/hooks/chunk-6TS2JD6D.js +0 -237
- package/dist/hooks/chunk-7DSBJVFH.js +0 -50
- package/dist/hooks/chunk-A65Y4YOR.js +0 -79
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EFXE6C37.js +0 -81
- package/dist/hooks/chunk-GP4IEC4O.js +0 -20
- package/dist/hooks/chunk-JP45SOCJ.js +0 -56
- package/dist/hooks/chunk-LAOV7NLM.js +0 -45
- package/dist/hooks/chunk-M4HGZV7U.js +0 -83
- package/dist/hooks/chunk-PF2NZL2A.js +0 -131
- package/dist/hooks/chunk-PTICX4OL.js +0 -358
- package/dist/hooks/chunk-RT27QRJW.js +0 -6247
- package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
- package/dist/hooks/chunk-UPUZF3AN.js +0 -279
- package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -29
- package/scripts/backlog/backlog-stalled-cli.ts +0 -30
- package/scripts/cost-runtime/cost-format.ts +0 -29
- package/scripts/init/basic-path-migration.ts +0 -24
- package/scripts/issue/issue-backlinks-cli.ts +0 -93
- package/scripts/josh/josh-commands-guard.ts +0 -38
- package/scripts/josh/josh-usage-automation.ts +0 -121
- package/scripts/josh/josh-usage-backlog.ts +0 -180
- package/scripts/josh/josh-usage-developer.ts +0 -230
- package/scripts/josh/josh-usage-hooks.ts +0 -38
- package/scripts/josh/josh-usage-issue.ts +0 -205
- package/scripts/josh/josh-usage-review.ts +0 -101
- package/scripts/josh/josh-usage-run.ts +0 -252
- package/scripts/josh/josh-usage-session.ts +0 -238
- package/scripts/josh/josh-usage-workflow.ts +0 -212
- package/scripts/lint/cross-file-recheck.ts +0 -155
- package/scripts/registry-migration/migrate-logic.ts +0 -237
- package/scripts/registry-migration/migrate.ts +0 -292
- package/scripts/registry-migration/user-npmrc.ts +0 -15
- package/scripts/rules/rule-guard.ts +0 -23
- package/scripts/rules/rule-registry-rows.ts +0 -292
- package/scripts/rules/rule-registry.ts +0 -112
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -1,34 +1,37 @@
|
|
|
1
1
|
import { git_command } from '#scripts/git/git-command'
|
|
2
|
-
import { git_spawn } from '#scripts/git/git-spawn'
|
|
3
2
|
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
4
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
file_map_stamp,
|
|
5
|
+
type FileMapStamp,
|
|
6
|
+
type FileMapStampAccess,
|
|
7
|
+
} from '#scripts/josh/file-map-stamp'
|
|
5
8
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
6
9
|
import { review_tree } from '#scripts/review/review-tree'
|
|
7
|
-
import { check_inputs
|
|
10
|
+
import { check_inputs } from './check-inputs'
|
|
8
11
|
import { gate_report, type GateStepResult } from './gate-report'
|
|
9
12
|
import type { GateTree } from './gate-tree'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
// path absent from both maps holds the merge base's content — and the base's own diff
|
|
19
|
-
// (`git diff <recorded> <current>`) names every path that content moved for. A path in either map whose
|
|
20
|
-
// digest differs is the other half (`file_map_stamp.changed_since`).
|
|
13
|
+
import { moved_paths } from './moved-paths'
|
|
14
|
+
import { verification_inputs, type PrettierIgnored } from './verification-inputs'
|
|
15
|
+
|
|
16
|
+
// One green record per declared check, so a gate re-run starts only the checks whose inputs moved
|
|
17
|
+
// (`verification-inputs.ts` declares what each reads). The whole-gate record (`gate-skip.ts`) is refused
|
|
18
|
+
// the moment the merge base moves; a main sync that brought in only `.claude/**/*.md` then re-ran lint
|
|
19
|
+
// and the type check over sources neither had a reason to read again. What moved since a record is
|
|
20
|
+
// `moved-paths.ts`.
|
|
21
21
|
//
|
|
22
22
|
// **A record is reuse of a result, not a check dropped**: no base, an empty changed-file map, an
|
|
23
|
-
// unreadable base diff
|
|
23
|
+
// unreadable base diff, no root or a fingerprint of the check's tools and environment that moved
|
|
24
|
+
// answers "not reusable", and an undeclared check is never reusable. The records are written and read
|
|
24
25
|
// only where the CLI entry resolved their destination (`CheckRecords`), so a suite driving the gate
|
|
25
26
|
// never plants a green record over the live tree.
|
|
26
27
|
|
|
27
28
|
const CHECK_PREFIX = 'josh-gate-check-'
|
|
28
|
-
const NAME_SEPARATOR = '\0'
|
|
29
|
-
const BASE_DIFF = ['diff', '--name-only', '--no-renames', '-z'] as const
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
function check_stamp(label: string): FileMapStampAccess {
|
|
31
|
+
return file_map_stamp.create(CHECK_PREFIX, PROJECT_ROOT, () =>
|
|
32
|
+
verification_inputs.fingerprint([label]),
|
|
33
|
+
)
|
|
34
|
+
}
|
|
32
35
|
|
|
33
36
|
// Where each check's record lives — a parameter so a test plants records in a directory of its own.
|
|
34
37
|
type CheckRecords = (label: string) => string
|
|
@@ -37,39 +40,11 @@ function default_records(label: string): string {
|
|
|
37
40
|
return stamp_file.stamp_path(`${CHECK_PREFIX}${label}-`, PROJECT_ROOT)
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
async function base_diff(from: string, to: string): Promise<ReadonlyArray<string> | undefined> {
|
|
41
|
-
if (from === to) return []
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const names = await git_spawn.read([...BASE_DIFF, from, to])
|
|
45
|
-
|
|
46
|
-
return names.split(NAME_SEPARATOR).filter((name) => name !== '')
|
|
47
|
-
} catch {
|
|
48
|
-
return undefined
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async function moved_since(
|
|
53
|
-
stamp: FileMapStamp,
|
|
54
|
-
tree: GateTree,
|
|
55
|
-
): Promise<ReadonlyArray<string> | undefined> {
|
|
56
|
-
// An empty map is also what `gate-tree.ts` answers when git could not be read, so it describes no
|
|
57
|
-
// tree to diff against — the reading `gate_skip.gate_reuse` refuses too.
|
|
58
|
-
const is_unread = Object.keys(tree.files).length === 0
|
|
59
|
-
|
|
60
|
-
if (is_unread || stamp.base === undefined || tree.base === undefined) return undefined
|
|
61
|
-
|
|
62
|
-
const moved_base = await base_diff(stamp.base, tree.base)
|
|
63
|
-
|
|
64
|
-
if (moved_base === undefined) return undefined
|
|
65
|
-
|
|
66
|
-
return [...file_map_stamp.changed_since(stamp, tree.files), ...moved_base]
|
|
67
|
-
}
|
|
68
|
-
|
|
69
43
|
interface ReuseContext {
|
|
70
44
|
tree: GateTree
|
|
71
45
|
records: CheckRecords
|
|
72
46
|
is_ignored: PrettierIgnored
|
|
47
|
+
root: string
|
|
73
48
|
}
|
|
74
49
|
|
|
75
50
|
async function is_stamp_reusable(
|
|
@@ -77,16 +52,18 @@ async function is_stamp_reusable(
|
|
|
77
52
|
stamp: FileMapStamp,
|
|
78
53
|
context: ReuseContext,
|
|
79
54
|
): Promise<boolean> {
|
|
80
|
-
const moved = await moved_since(stamp, context.tree)
|
|
55
|
+
const moved = await moved_paths.moved_since(stamp, context.tree)
|
|
81
56
|
|
|
82
|
-
if (moved === undefined) return false
|
|
57
|
+
if (moved === undefined || !check_stamp(label).describes_inputs(stamp)) return false
|
|
83
58
|
|
|
84
|
-
return !(await check_inputs.touches_inputs(label, moved, context.is_ignored))
|
|
59
|
+
return !(await check_inputs.touches_inputs(label, moved, context.is_ignored, context.root))
|
|
85
60
|
}
|
|
86
61
|
|
|
87
62
|
// The time the check's record was taken, or `undefined` when the check has to run.
|
|
88
63
|
async function reused_at(label: string, context: ReuseContext): Promise<string | undefined> {
|
|
89
|
-
const stamp =
|
|
64
|
+
const stamp = verification_inputs.is_declared(label)
|
|
65
|
+
? check_stamp(label).read(context.records(label))
|
|
66
|
+
: undefined
|
|
90
67
|
|
|
91
68
|
if (stamp === undefined) return undefined
|
|
92
69
|
|
|
@@ -111,7 +88,7 @@ async function reusable_checks(
|
|
|
111
88
|
|
|
112
89
|
if (root === undefined) return new Map()
|
|
113
90
|
|
|
114
|
-
const context = { tree, records, is_ignored: check_inputs.prettier_ignored(root) }
|
|
91
|
+
const context = { tree, records, root, is_ignored: check_inputs.prettier_ignored(root) }
|
|
115
92
|
const answers = await Promise.all(
|
|
116
93
|
labels.map(async (label) => [label, await reused_at(label, context)] as const),
|
|
117
94
|
)
|
|
@@ -121,7 +98,7 @@ async function reusable_checks(
|
|
|
121
98
|
|
|
122
99
|
function is_recordable(result: GateStepResult): boolean {
|
|
123
100
|
return (
|
|
124
|
-
|
|
101
|
+
verification_inputs.is_declared(result.label) &&
|
|
125
102
|
!gate_report.is_gate_step_failed(result) &&
|
|
126
103
|
gate_report.has_nothing_to_say(result)
|
|
127
104
|
)
|
|
@@ -134,7 +111,9 @@ function write_records(
|
|
|
134
111
|
): void {
|
|
135
112
|
const recordable = results.filter((result) => is_recordable(result))
|
|
136
113
|
|
|
137
|
-
for (const
|
|
114
|
+
for (const { label } of recordable) {
|
|
115
|
+
check_stamp(label).write(tree.files, records(label), tree.base)
|
|
116
|
+
}
|
|
138
117
|
}
|
|
139
118
|
|
|
140
119
|
// Every scoped check that passed silently, recorded against the tree it read — a red gate's green
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import os from 'node:os'
|
|
2
|
+
import { bash_triggers } from '#scripts/rules/bash-triggers'
|
|
3
|
+
import { git_argv, type ProgramCall } from '#scripts/rules/git-argv'
|
|
4
|
+
import { shell_segments } from '#scripts/rules/shell-segments'
|
|
5
|
+
import { time_shell } from '#scripts/time-runtime/time-shell'
|
|
6
|
+
import { core_weights } from './core-weights'
|
|
7
|
+
|
|
8
|
+
// The heavy tools a shell line launches, and the memory they hold (joshuafolkken/kit#4582).
|
|
9
|
+
//
|
|
10
|
+
// **`reserved-run` counted a wrapped command's cores and no memory**: a lane ran
|
|
11
|
+
// `reserved-run 4 -- sh -c '… eslint . --concurrency 4 …'`, typed eslint held a TypeScript program per
|
|
12
|
+
// worker, and the 12 GB process was admitted beside four other lanes until the machine swapped. The
|
|
13
|
+
// estimate here is what the wrapper now reserves, and the same reading is what `lane-direct-tool`
|
|
14
|
+
// refuses a multi-worker eslint on.
|
|
15
|
+
//
|
|
16
|
+
// **Every spelling is read down to the program.** `git_argv.program_of` skips the wrapper words, a
|
|
17
|
+
// quoted script handed to a shell is read as its own line (`bash_triggers.shell_script_of`), and the
|
|
18
|
+
// command after `pnpm josh reserved-run <weight> --` is read as the call it wraps, marked reserved. A
|
|
19
|
+
// heredoc body is text, so it is dropped before the line is cut — unless a shell reads it
|
|
20
|
+
// (`bash <<'EOF'`), when it is read as a line of its own, the `sh -c` escape spelled another way.
|
|
21
|
+
//
|
|
22
|
+
// **The estimate is the largest tool's, not the sum**: the commands of one line run one after another,
|
|
23
|
+
// so only one of them is resident at a time. A line with no known tool is `undefined`, the 0 MB it
|
|
24
|
+
// counted before — `reserved-run 1 -- pnpm josh audit` reserves its own, and is not counted twice.
|
|
25
|
+
|
|
26
|
+
interface ToolCall extends ProgramCall {
|
|
27
|
+
// Inside a `pnpm josh reserved-run … --`, the budgeted path.
|
|
28
|
+
is_reserved: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// A line still to be cut into its programs.
|
|
32
|
+
interface PendingLine {
|
|
33
|
+
line: string
|
|
34
|
+
is_reserved: boolean
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const JOSH_PROGRAM = 'josh'
|
|
38
|
+
const RESERVED_RUN = 'reserved-run'
|
|
39
|
+
const COMMAND_SEPARATOR = '--'
|
|
40
|
+
const ESLINT = 'eslint'
|
|
41
|
+
const VITEST = 'vitest'
|
|
42
|
+
const AUTO_WORKERS = 'auto'
|
|
43
|
+
const LINE_BREAK = '\n'
|
|
44
|
+
// A heredoc fed to a shell — `bash <<'EOF'`, `sh -s <<EOF` — whose body the shell runs.
|
|
45
|
+
const SHELL_HEREDOC = /\b(?:ba|z|da|k)?sh(?:\s+-\w+)*\s*<<-?\s*(['"]?)(\w+)\1/u
|
|
46
|
+
const HEREDOC_DELIMITER_GROUP = 2
|
|
47
|
+
// ESLint 10's `auto` caps its workers at half the available cores (`eslint/lib/eslint/eslint.js`).
|
|
48
|
+
const AUTO_CORE_SHARE = 2
|
|
49
|
+
const SINGLE_WORKER = 1
|
|
50
|
+
// The flag each multi-worker tool takes its worker count from.
|
|
51
|
+
const WORKER_FLAGS: Readonly<Partial<Record<string, string>>> = {
|
|
52
|
+
[ESLINT]: '--concurrency',
|
|
53
|
+
[VITEST]: '--maxWorkers',
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// The command `pnpm josh reserved-run <weight> [--memory <MB>] -- <command>` wraps, or `undefined`.
|
|
57
|
+
function wrapped_command_of(call: ProgramCall): string | undefined {
|
|
58
|
+
if (call.name !== JOSH_PROGRAM || call.args[0] !== RESERVED_RUN) return undefined
|
|
59
|
+
|
|
60
|
+
const separator = call.args.indexOf(COMMAND_SEPARATOR)
|
|
61
|
+
|
|
62
|
+
return separator === -1 ? undefined : call.args.slice(separator + 1).join(' ')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// One command of a line: the program it launches, or the line it hands on — a `reserved-run`'s
|
|
66
|
+
// wrapped command, or a shell's quoted script.
|
|
67
|
+
function reading_of(segment: string, is_reserved: boolean): ToolCall | PendingLine | undefined {
|
|
68
|
+
const call = git_argv.program_of(segment)
|
|
69
|
+
const wrapped = call === undefined ? undefined : wrapped_command_of(call)
|
|
70
|
+
|
|
71
|
+
if (wrapped !== undefined) return { line: wrapped, is_reserved: true }
|
|
72
|
+
|
|
73
|
+
const script = bash_triggers.shell_script_of(segment)
|
|
74
|
+
|
|
75
|
+
if (script !== undefined) return { line: script, is_reserved }
|
|
76
|
+
|
|
77
|
+
return call === undefined ? undefined : { ...call, is_reserved }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// The lines up to the delimiter alone on its line, or to the end when it never closes.
|
|
81
|
+
function body_until(lines: ReadonlyArray<string>, delimiter: string): string {
|
|
82
|
+
const end = lines.findIndex((body_line) => body_line.trim() === delimiter)
|
|
83
|
+
|
|
84
|
+
return (end === -1 ? lines : lines.slice(0, end)).join(LINE_BREAK)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// The body of every heredoc the line feeds to a shell, each as a line of its own: `bash <<'EOF'` runs
|
|
88
|
+
// its body, where `cat <<EOF` only prints it.
|
|
89
|
+
function shell_heredoc_bodies(line: string): Array<string> {
|
|
90
|
+
const lines = line.split(LINE_BREAK)
|
|
91
|
+
|
|
92
|
+
return lines.flatMap((opening, index) => {
|
|
93
|
+
const delimiter = SHELL_HEREDOC.exec(opening)?.[HEREDOC_DELIMITER_GROUP]
|
|
94
|
+
|
|
95
|
+
return delimiter === undefined ? [] : body_until(lines.slice(index + 1), delimiter)
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function is_tool_call(reading: ToolCall | PendingLine): reading is ToolCall {
|
|
100
|
+
return 'name' in reading
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function is_pending_line(reading: ToolCall | PendingLine): reading is PendingLine {
|
|
104
|
+
return !is_tool_call(reading)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Every program the line launches, a shell's quoted script and a `reserved-run`'s command included.
|
|
108
|
+
// A queue rather than recursion: each handed-on line is shorter than the one it came from.
|
|
109
|
+
function tool_calls_of(line: string): Array<ToolCall> {
|
|
110
|
+
const pending: Array<PendingLine> = [{ line, is_reserved: false }]
|
|
111
|
+
const calls: Array<ToolCall> = []
|
|
112
|
+
|
|
113
|
+
for (let next = pending.shift(); next !== undefined; next = pending.shift()) {
|
|
114
|
+
const { is_reserved } = next
|
|
115
|
+
const readings = shell_segments
|
|
116
|
+
.quote_aware_commands_of(time_shell.without_heredoc_bodies(next.line))
|
|
117
|
+
.flatMap((segment) => reading_of(segment, is_reserved) ?? [])
|
|
118
|
+
|
|
119
|
+
const bodies = shell_heredoc_bodies(next.line).map((body) => ({ line: body, is_reserved }))
|
|
120
|
+
|
|
121
|
+
calls.push(...readings.filter((reading) => is_tool_call(reading)))
|
|
122
|
+
pending.push(...readings.filter((reading) => is_pending_line(reading)), ...bodies)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return calls
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// `--flag <value>` or `--flag=<value>`.
|
|
129
|
+
function flag_value(args: ReadonlyArray<string>, flag: string): string | undefined {
|
|
130
|
+
const prefix = `${flag}=`
|
|
131
|
+
const index = args.findIndex((argument) => argument === flag || argument.startsWith(prefix))
|
|
132
|
+
const argument = args[index]
|
|
133
|
+
|
|
134
|
+
if (argument === undefined) return undefined
|
|
135
|
+
|
|
136
|
+
return argument === flag ? args[index + 1] : argument.slice(prefix.length)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// The workers a tool opens when its flag is missing. **vitest's default is the machine less one**
|
|
140
|
+
// (`maxWorkers`, run mode): `vitest.config.ts` shares the machine only between marked runs, so a lone
|
|
141
|
+
// direct run opens them all. ESLint's `--concurrency` defaults to `off`, one worker.
|
|
142
|
+
function default_workers(name: string, cores: number): number {
|
|
143
|
+
return name === VITEST ? Math.max(SINGLE_WORKER, cores - 1) : SINGLE_WORKER
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// A worker flag's count: half the cores for `auto`, else the number — one for `off` and an unreadable
|
|
147
|
+
// value alike.
|
|
148
|
+
function count_of(value: string, cores: number): number {
|
|
149
|
+
if (value === AUTO_WORKERS) return Math.max(SINGLE_WORKER, Math.floor(cores / AUTO_CORE_SHARE))
|
|
150
|
+
|
|
151
|
+
const count = Number(value)
|
|
152
|
+
|
|
153
|
+
return Number.isSafeInteger(count) && count > SINGLE_WORKER ? count : SINGLE_WORKER
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function workers_of(call: ToolCall, cores: number = os.availableParallelism()): number {
|
|
157
|
+
const flag = WORKER_FLAGS[call.name]
|
|
158
|
+
const value = flag === undefined ? undefined : flag_value(call.args, flag)
|
|
159
|
+
|
|
160
|
+
return value === undefined ? default_workers(call.name, cores) : count_of(value, cores)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function memory_of(call: ToolCall, cores: number): number | undefined {
|
|
164
|
+
const row = core_weights.TOOL_MEMORY[call.name]
|
|
165
|
+
|
|
166
|
+
return row === undefined ? undefined : core_weights.MEMORY_MB[row] * workers_of(call, cores)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// The MB the line's largest tool holds, or `undefined` when it launches none the table knows.
|
|
170
|
+
function estimated_memory_mb(
|
|
171
|
+
line: string,
|
|
172
|
+
cores: number = os.availableParallelism(),
|
|
173
|
+
): number | undefined {
|
|
174
|
+
const amounts = tool_calls_of(line).flatMap((call) => memory_of(call, cores) ?? [])
|
|
175
|
+
|
|
176
|
+
return amounts.length === 0 ? undefined : Math.max(...amounts)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// True when the line runs eslint with more than one worker, wrapped or not.
|
|
180
|
+
function runs_multi_worker_eslint(
|
|
181
|
+
line: string,
|
|
182
|
+
cores: number = os.availableParallelism(),
|
|
183
|
+
): boolean {
|
|
184
|
+
return tool_calls_of(line).some(
|
|
185
|
+
(call) => call.name === ESLINT && workers_of(call, cores) > SINGLE_WORKER,
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const command_memory = { estimated_memory_mb, runs_multi_worker_eslint, tool_calls_of }
|
|
190
|
+
|
|
191
|
+
export { command_memory }
|
|
192
|
+
export type { ToolCall }
|
|
@@ -1,25 +1,37 @@
|
|
|
1
|
+
import { MS_PER_SECOND } from '#scripts/lib/timeouts'
|
|
1
2
|
import type { LedgerLoad, MachineBudget } from './machine-capacity'
|
|
2
3
|
|
|
3
4
|
// The ledger's admission arithmetic, kept apart from the markers `core-budget.ts` reads and writes so
|
|
4
5
|
// that file stays under its line ceiling as the budget grew a memory side.
|
|
5
6
|
// Everything here is a pure function of the ledger it is handed.
|
|
6
7
|
|
|
7
|
-
const MS_PER_SECOND = 1000
|
|
8
8
|
// **How long an admitted claim's tool takes to reach its declared peak.** The machine reading holds only
|
|
9
9
|
// what a tool has already allocated, so a claim admitted moments ago is not in it yet: adding its
|
|
10
10
|
// declared memory back would admit the next claim into memory about to be taken — the concurrent start
|
|
11
|
-
// this ledger exists to stop. Until the window passes, the claim's memory counts only in
|
|
11
|
+
// this ledger exists to stop. Until the window passes, the claim's memory counts only in `is_admitted`; a
|
|
12
12
|
// tool partway up is then counted twice, which costs a slower admission, never a swap. Its cores are in
|
|
13
13
|
// the reading from the start, so the window does not apply to them.
|
|
14
14
|
const RAMP_UP_MS = 30_000
|
|
15
|
+
// How long after a waiting claim's own claim a lighter claim may still pass it (`may_pass`): long
|
|
16
|
+
// enough for the related checks an edit triggers together, short enough that a heavy claim waits only
|
|
17
|
+
// for the claims already in flight.
|
|
18
|
+
const BYPASS_WINDOW_MS = 30_000
|
|
19
|
+
// A narrowed unit claim still runs one worker: zero would run no test and report the suite green.
|
|
20
|
+
const MIN_GRANT = 1
|
|
21
|
+
// A unit claim narrowed to less than its asked weight over this waits rather than starts (`is_too_narrow`).
|
|
22
|
+
const NARROW_DIVISOR = 2
|
|
15
23
|
|
|
16
24
|
// What admission reads from a marker. `memory_mb` and `admitted_at` are optional because a marker an
|
|
17
25
|
// older `josh` wrote has neither: it declares no memory, and it counts as load from outside the ledger.
|
|
26
|
+
// `granted` is the narrower weight a unit claim was admitted at past the wait cap; once set, it is the
|
|
27
|
+
// load the claim holds.
|
|
18
28
|
interface LedgerReservation {
|
|
19
29
|
weight: number
|
|
20
30
|
claimed_at: number
|
|
21
31
|
memory_mb?: number | undefined
|
|
22
32
|
admitted_at?: number | undefined
|
|
33
|
+
granted?: number | undefined
|
|
34
|
+
is_unit?: boolean | undefined
|
|
23
35
|
}
|
|
24
36
|
|
|
25
37
|
interface LedgerEntry {
|
|
@@ -37,8 +49,13 @@ interface Overflow {
|
|
|
37
49
|
budget: MachineBudget
|
|
38
50
|
}
|
|
39
51
|
|
|
52
|
+
// `granted` is set only when a unit claim was narrowed to the room left at the wait cap. `waited_ms` is
|
|
53
|
+
// how long the claim waited, about one machine read's window for one admitted on its first read
|
|
54
|
+
// (joshuafolkken/kit#4451).
|
|
40
55
|
interface Admission {
|
|
41
56
|
overflow: Overflow | undefined
|
|
57
|
+
granted?: number | undefined
|
|
58
|
+
waited_ms?: number | undefined
|
|
42
59
|
}
|
|
43
60
|
|
|
44
61
|
// Claim order, with the filename as the tiebreak so every reader agrees on the same ledger order
|
|
@@ -50,54 +67,169 @@ function compare_claim(left: LedgerEntry, right: LedgerEntry): number {
|
|
|
50
67
|
}
|
|
51
68
|
|
|
52
69
|
function add_load(totals: LedgerLoad, reservation: LedgerReservation): void {
|
|
53
|
-
totals.cores += reservation.weight
|
|
70
|
+
totals.cores += reservation.granted ?? reservation.weight
|
|
54
71
|
totals.memory_mb += reservation.memory_mb ?? 0
|
|
55
72
|
}
|
|
56
73
|
|
|
57
|
-
function exceeds(totals: LedgerLoad, budget:
|
|
74
|
+
function exceeds(totals: LedgerLoad, budget: LedgerLoad): boolean {
|
|
58
75
|
return totals.cores > budget.cores || totals.memory_mb > budget.memory_mb
|
|
59
76
|
}
|
|
60
77
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
function sum_load(reservations: ReadonlyArray<LedgerEntry>): LedgerLoad {
|
|
79
|
+
const load = { cores: 0, memory_mb: 0 }
|
|
80
|
+
|
|
81
|
+
for (const entry of reservations) add_load(load, entry.reservation)
|
|
82
|
+
|
|
83
|
+
return load
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function is_waiting(entry: LedgerEntry): boolean {
|
|
87
|
+
return entry.reservation.admitted_at === undefined
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function fits(entries: ReadonlyArray<LedgerEntry>, limit: LedgerLoad): boolean {
|
|
91
|
+
return !exceeds(sum_load(entries), limit)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Where a claim stands in the ledger: the claims already running, whatever their place, and the
|
|
95
|
+
// claims still waiting ahead of it in claim order.
|
|
96
|
+
interface Placement {
|
|
97
|
+
own: LedgerEntry
|
|
98
|
+
is_oldest: boolean
|
|
99
|
+
ahead: Array<LedgerEntry>
|
|
100
|
+
running: Array<LedgerEntry>
|
|
101
|
+
}
|
|
75
102
|
|
|
76
|
-
|
|
77
|
-
|
|
103
|
+
function place(key: string, reservations: ReadonlyArray<LedgerEntry>): Placement | undefined {
|
|
104
|
+
const ordered = reservations.toSorted(compare_claim)
|
|
105
|
+
const index = ordered.findIndex((entry) => entry.key === key)
|
|
106
|
+
const own = ordered[index]
|
|
78
107
|
|
|
79
|
-
|
|
108
|
+
if (own === undefined) return undefined
|
|
80
109
|
|
|
81
|
-
|
|
110
|
+
return {
|
|
111
|
+
own,
|
|
112
|
+
is_oldest: index === 0,
|
|
113
|
+
ahead: ordered.slice(0, index).filter((entry) => is_waiting(entry)),
|
|
114
|
+
running: ordered.filter((entry) => entry.key !== key && !is_waiting(entry)),
|
|
82
115
|
}
|
|
116
|
+
}
|
|
83
117
|
|
|
84
|
-
|
|
118
|
+
// **The first waiting claim is held by the ledger, never by load from outside it**
|
|
119
|
+
// (joshuafolkken/kit#4313). Holding it on `busy_excess` (joshuafolkken/kit#4238) made a solo gate's unit
|
|
120
|
+
// claim wait out the cap behind one core of Claude sessions or editor load — work deferred, not removed.
|
|
121
|
+
// It is admitted against the cores the ledger leaves, and a unit claim narrows to the room the outside
|
|
122
|
+
// load leaves (`narrowed_weight`), so that load bounds its workers instead of its start. **On an
|
|
123
|
+
// overloaded machine it waits like any claim** (`is_overloaded`, joshuafolkken/kit#4361): every poll reads
|
|
124
|
+
// the load afresh, so it runs once the load falls back under the cap.
|
|
125
|
+
function first_waiter_limit(budget: MachineBudget): LedgerLoad {
|
|
126
|
+
if (budget.is_overloaded === true) return budget
|
|
127
|
+
|
|
128
|
+
return { cores: budget.cores + (budget.busy_excess ?? 0), memory_mb: budget.memory_mb }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// **A light claim passes a waiting one only within a window of that one's claim** (#4313). A claim that
|
|
132
|
+
// fits the room the running claims leave runs instead of queueing behind a heavier claim that does not
|
|
133
|
+
// fit it; a claim made more than the window after a waiter queues behind it, so a waiter is passed by a
|
|
134
|
+
// bounded set of claims and is never starved.
|
|
135
|
+
function may_pass({ own, ahead, running }: Placement, budget: MachineBudget): boolean {
|
|
136
|
+
const latest = own.reservation.claimed_at - BYPASS_WINDOW_MS
|
|
137
|
+
const is_recent = ahead.every((entry) => entry.reservation.claimed_at > latest)
|
|
138
|
+
|
|
139
|
+
return is_recent && fits([...running, own], budget)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function fits_in_order({ own, ahead, running }: Placement, budget: MachineBudget): boolean {
|
|
143
|
+
const limit = ahead.length === 0 ? first_waiter_limit(budget) : budget
|
|
144
|
+
|
|
145
|
+
return fits([...running, ...ahead, own], limit)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// **A host-wide swap stall holds the oldest claim too** (joshuafolkken/kit#4451). Running alone skipped
|
|
149
|
+
// the memory test, so a lone gate started a 2.4 GB lint into a stall with 1.7 GB free and swapped it
|
|
150
|
+
// for 830 s. Only both together hold: traffic alone is this machine's daily norm (#4313), and a claim
|
|
151
|
+
// heavier than free memory on a calm machine would wait for room that never comes.
|
|
152
|
+
function is_swap_stalled({ own, running }: Placement, budget: MachineBudget): boolean {
|
|
153
|
+
const needed_mb = sum_load([...running, own]).memory_mb
|
|
154
|
+
|
|
155
|
+
return budget.memory_pressured === true && needed_mb > budget.memory_mb
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// **The wait cap does not release a swap-stall hold, for any claim** (joshuafolkken/kit#4451): the cap
|
|
159
|
+
// exists so a wedged sibling cannot stall the machine for good, but a stall ends when its traffic stops
|
|
160
|
+
// or its memory is free, so the hold cannot outlive it. Released at the cap, a 2.4 GB lint started into
|
|
161
|
+
// the stall it waited on and swapped for the same 830 s — and holding only a lone claim let a gate's
|
|
162
|
+
// later claims start into the stall at their own caps, after which the lint was no longer alone.
|
|
163
|
+
function is_swap_held(
|
|
164
|
+
key: string,
|
|
165
|
+
reservations: ReadonlyArray<LedgerEntry>,
|
|
166
|
+
budget: MachineBudget,
|
|
167
|
+
): boolean {
|
|
168
|
+
const placement = place(key, reservations)
|
|
169
|
+
|
|
170
|
+
return placement !== undefined && is_swap_stalled(placement, budget)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// The oldest claim runs alone once nothing else does — unless the machine is overloaded, where it waits
|
|
174
|
+
// like the first waiter (`first_waiter_limit`) until a poll reads the load back under the cap, or stalled
|
|
175
|
+
// on swap (`is_swap_stalled`), where it waits until the traffic stops or its memory is free.
|
|
176
|
+
function runs_alone(placement: Placement, budget: MachineBudget): boolean {
|
|
177
|
+
if (!placement.is_oldest || placement.running.length > 0) return false
|
|
178
|
+
|
|
179
|
+
return budget.is_overloaded !== true && !is_swap_stalled(placement, budget)
|
|
85
180
|
}
|
|
86
181
|
|
|
182
|
+
// **Admission: the oldest claim runs once nothing else does, then claim order, then a bounded pass.**
|
|
183
|
+
// The oldest runs because a single check heavier than the whole machine must not wait for room that will
|
|
184
|
+
// never come — except into a swap stall (`is_swap_stalled`), which passes. Claims that passed it are
|
|
185
|
+
// still running beside it, and their room does come back, so it waits for them rather than starting on
|
|
186
|
+
// top of their cores and memory. A later claim runs when every running claim, every claim waiting
|
|
187
|
+
// ahead of it and its own load fit the budget — the first waiter against the ledger alone
|
|
188
|
+
// (`first_waiter_limit`) — or when it may pass the waiters ahead (`may_pass`).
|
|
87
189
|
function is_admitted(
|
|
88
190
|
key: string,
|
|
89
191
|
reservations: ReadonlyArray<LedgerEntry>,
|
|
90
192
|
budget: MachineBudget,
|
|
91
193
|
): boolean {
|
|
92
|
-
|
|
194
|
+
const placement = place(key, reservations)
|
|
195
|
+
|
|
196
|
+
if (placement === undefined) return false
|
|
197
|
+
if (runs_alone(placement, budget)) return true
|
|
198
|
+
|
|
199
|
+
return fits_in_order(placement, budget) || may_pass(placement, budget)
|
|
93
200
|
}
|
|
94
201
|
|
|
95
|
-
function
|
|
96
|
-
const
|
|
202
|
+
function mark_admitted(entries: Array<LedgerEntry>, key: string): void {
|
|
203
|
+
const index = entries.findIndex((entry) => entry.key === key)
|
|
204
|
+
const entry = entries[index]
|
|
97
205
|
|
|
98
|
-
|
|
206
|
+
if (entry === undefined) return
|
|
99
207
|
|
|
100
|
-
|
|
208
|
+
entries[index] = {
|
|
209
|
+
...entry,
|
|
210
|
+
reservation: { ...entry.reservation, admitted_at: entry.reservation.claimed_at },
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// **The keys one round of polls admits**, each claim polling in claim order and reading the ledger the
|
|
215
|
+
// claims before it left — an admitted claim is running for every claim after it, as its marker is.
|
|
216
|
+
function admitted_keys(
|
|
217
|
+
reservations: ReadonlyArray<LedgerEntry>,
|
|
218
|
+
budget: number,
|
|
219
|
+
memory_budget = Infinity,
|
|
220
|
+
): Set<string> {
|
|
221
|
+
const limit = { cores: budget, memory_mb: memory_budget }
|
|
222
|
+
const ledger = [...reservations]
|
|
223
|
+
const admitted = new Set<string>()
|
|
224
|
+
|
|
225
|
+
for (const { key } of reservations.toSorted(compare_claim)) {
|
|
226
|
+
if (!is_admitted(key, ledger, limit)) continue
|
|
227
|
+
|
|
228
|
+
admitted.add(key)
|
|
229
|
+
mark_admitted(ledger, key)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return admitted
|
|
101
233
|
}
|
|
102
234
|
|
|
103
235
|
function is_ramped(reservation: LedgerReservation, now: number): boolean {
|
|
@@ -120,6 +252,59 @@ function total_weight(reservations: ReadonlyArray<LedgerEntry>): number {
|
|
|
120
252
|
return sum_load(reservations).cores
|
|
121
253
|
}
|
|
122
254
|
|
|
255
|
+
// **The weight a unit claim admitted past the wait cap may take: the cores the admitted claims leave
|
|
256
|
+
// free, never below one worker and never above what it asked for.** Admitting it at full width put the
|
|
257
|
+
// ledger past the machine (joshuafolkken/kit#4235); a unit suite is the one tool whose width follows a
|
|
258
|
+
// number, so it narrows instead. `undefined` for any other claim, and for one that fits as asked.
|
|
259
|
+
function narrowed_weight(
|
|
260
|
+
key: string,
|
|
261
|
+
reservations: ReadonlyArray<LedgerEntry>,
|
|
262
|
+
budget: number,
|
|
263
|
+
): number | undefined {
|
|
264
|
+
const own = reservations.find((entry) => entry.key === key)?.reservation
|
|
265
|
+
|
|
266
|
+
if (own?.is_unit !== true) return undefined
|
|
267
|
+
|
|
268
|
+
const others = reservations.filter(
|
|
269
|
+
(entry) => entry.key !== key && entry.reservation.admitted_at !== undefined,
|
|
270
|
+
)
|
|
271
|
+
const room = Math.max(MIN_GRANT, Math.floor(budget - total_weight(others)))
|
|
272
|
+
|
|
273
|
+
return room >= own.weight ? undefined : room
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// **A unit claim narrowed below half its asked width waits for room instead, until the wait cap**
|
|
277
|
+
// (joshuafolkken/kit#4167). vitest fixes its pool at start, so a width read off one busy instant holds for
|
|
278
|
+
// the whole suite after the cores come back: over seven days a run at three workers or fewer took a
|
|
279
|
+
// median 197 s against 76–90 s at seven, and 14 of the 18 slowest unit runs started that narrow. The
|
|
280
|
+
// wait costs at most the cap, past which the claim narrows as before; a narrowing to half or more — a
|
|
281
|
+
// core of editor load beside a solo gate — still starts at once (joshuafolkken/kit#4313).
|
|
282
|
+
function is_too_narrow(
|
|
283
|
+
key: string,
|
|
284
|
+
reservations: ReadonlyArray<LedgerEntry>,
|
|
285
|
+
granted: number | undefined,
|
|
286
|
+
): boolean {
|
|
287
|
+
if (granted === undefined) return false
|
|
288
|
+
|
|
289
|
+
const own = reservations.find((entry) => entry.key === key)?.reservation
|
|
290
|
+
|
|
291
|
+
return own !== undefined && granted * NARROW_DIVISOR < own.weight
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// The ledger as it stands once `key` is admitted at `granted`, so the overflow it reports counts the
|
|
295
|
+
// narrowed weight rather than the one the claim asked for.
|
|
296
|
+
function with_grant<T extends LedgerEntry>(
|
|
297
|
+
key: string,
|
|
298
|
+
reservations: ReadonlyArray<T>,
|
|
299
|
+
granted: number | undefined,
|
|
300
|
+
): Array<T> {
|
|
301
|
+
if (granted === undefined) return [...reservations]
|
|
302
|
+
|
|
303
|
+
return reservations.map((entry) =>
|
|
304
|
+
entry.key === key ? { ...entry, reservation: { ...entry.reservation, granted } } : entry,
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
|
|
123
308
|
// The weight actually running at once — what the reproduction test asserts stays within the budget.
|
|
124
309
|
function admitted_load(reservations: ReadonlyArray<LedgerEntry>, budget: number): number {
|
|
125
310
|
const admitted = admitted_keys(reservations, budget)
|
|
@@ -149,13 +334,18 @@ function describe_overflow(admission: Admission): string | undefined {
|
|
|
149
334
|
}
|
|
150
335
|
|
|
151
336
|
const core_admission = {
|
|
337
|
+
BYPASS_WINDOW_MS,
|
|
152
338
|
RAMP_UP_MS,
|
|
153
339
|
admitted_keys,
|
|
154
340
|
admitted_load,
|
|
155
341
|
describe_overflow,
|
|
156
342
|
is_admitted,
|
|
343
|
+
is_swap_held,
|
|
344
|
+
is_too_narrow,
|
|
157
345
|
ledger_load,
|
|
346
|
+
narrowed_weight,
|
|
158
347
|
sum_load,
|
|
348
|
+
with_grant,
|
|
159
349
|
}
|
|
160
350
|
|
|
161
351
|
export type { Admission, LedgerEntry, Overflow }
|