@joshuafolkken/kit 1.1514.0 → 1.1784.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -1
- package/.claude/settings.json +5 -5
- package/.claude/skills/epic-commands/SKILL.md +26 -65
- package/.claude/skills/epic-commands/epic-bundle.md +3 -1
- package/.claude/skills/workflow-commands/SKILL.md +5 -5
- package/.claude/skills/workflow-commands/background-commands.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
- package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +13 -7
- package/.claude/skills/workflow-commands/delegation.md +6 -5
- package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
- package/.claude/skills/workflow-commands/followup.md +9 -31
- package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
- package/.claude/skills/workflow-commands/fullrun.md +2 -2
- package/.claude/skills/workflow-commands/halfrun.md +17 -25
- package/.claude/skills/workflow-commands/issue-comments.md +16 -12
- package/.claude/skills/workflow-commands/issue-scout.md +2 -2
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +7 -12
- package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
- package/.claude/skills/workflow-commands/observation-filing.md +4 -36
- package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
- package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
- package/.claude/skills/workflow-commands/prerequisite.md +10 -16
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +3 -7
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +13 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-node/action.yml +9 -0
- package/.github/actions/setup-pnpm/action.yml +1 -1
- package/.github/dependabot.yml +16 -0
- package/.github/release.yml +0 -2
- package/.github/workflows/ci.yml +120 -10
- package/.github/workflows/publish.yml +8 -1
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +3 -7
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +3 -7
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
- package/dist/commands/read-set-cli.js +1867 -0
- package/dist/commands/run-prep-main.js +21653 -0
- package/dist/commands/run-step-cli.js +23880 -0
- package/dist/config-merge/index.js +5 -1
- package/dist/hooks/audit-provision.js +20 -35
- package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
- package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
- package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
- package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
- package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -22
- package/dist/hooks/format-edited.js +5 -6
- package/dist/hooks/inputs.json +443 -317
- package/dist/hooks/pretool-guard.js +7 -25
- package/dist/hooks/session-lang.js +44 -51
- package/dist/hooks/stop-guard.js +7716 -2187
- package/dist/josh.js +6002 -3583
- package/dist/self-sync-guard/index.js +74 -10
- package/dist/version/index.js +115 -406
- package/eslint/base.js +1 -1
- package/lefthook/base.yml +3 -1
- package/package.json +10 -48
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -7
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +33 -16
- package/prompts/collaboration-workflow/lane-instructions.md +1 -2
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +4 -6
- package/prompts/collaboration-workflow/output-bounds.md +2 -7
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +5 -0
- package/prompts/collaboration-workflow/report-format.md +31 -60
- package/prompts/collaboration-workflow/residency.md +2 -2
- package/prompts/collaboration-workflow/shell-body.md +6 -16
- package/prompts/collaboration-workflow/turn-batching.md +0 -2
- package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
- package/prompts/collaboration-workflow/wip-cap.md +1 -1
- package/prompts/collaboration-workflow.md +3 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +41 -21
- package/prompts/testing-guide.md +8 -43
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +14 -16
- package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
- package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
- package/scripts/auto-ok/auto-ok-judge.ts +13 -2
- package/scripts/auto-ok/auto-ok-main.ts +17 -0
- package/scripts/backlog/backlog-arrival.ts +14 -3
- package/scripts/backlog/backlog-budget-cli.ts +7 -33
- package/scripts/backlog/backlog-budget-main.ts +16 -0
- package/scripts/backlog/backlog-budget.ts +2 -3
- package/scripts/backlog/backlog-defect-priority.ts +4 -3
- package/scripts/backlog/backlog-drive-adopt.ts +67 -0
- package/scripts/backlog/backlog-drive-args.ts +4 -5
- package/scripts/backlog/backlog-drive-cli.ts +113 -28
- package/scripts/backlog/backlog-drive-hold.ts +162 -0
- package/scripts/backlog/backlog-drive-idle.ts +151 -0
- package/scripts/backlog/backlog-drive-judge.ts +25 -0
- package/scripts/backlog/backlog-drive-memory.ts +126 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
- package/scripts/backlog/backlog-drive-named.ts +53 -6
- package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
- package/scripts/backlog/backlog-drive-paused.ts +169 -0
- package/scripts/backlog/backlog-drive-restore.ts +30 -7
- package/scripts/backlog/backlog-drive-seats.ts +18 -8
- package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
- package/scripts/backlog/backlog-drive.ts +79 -75
- package/scripts/backlog/backlog-next-main.ts +16 -0
- package/scripts/backlog/backlog-next-shared.ts +73 -0
- package/scripts/backlog/backlog-next.ts +48 -16
- package/scripts/backlog/backlog-occupied.ts +52 -39
- package/scripts/backlog/backlog-offer-cli.ts +6 -21
- package/scripts/backlog/backlog-offer-exclude.ts +15 -0
- package/scripts/backlog/backlog-offer-main.ts +12 -0
- package/scripts/backlog/backlog-offer.ts +36 -3
- package/scripts/backlog/backlog-overlap.ts +22 -4
- package/scripts/backlog/backlog-plan-read.ts +6 -2
- package/scripts/backlog/backlog-plan.ts +18 -4
- package/scripts/backlog/backlog-pool.ts +10 -10
- package/scripts/backlog/backlog-rank.ts +10 -2
- package/scripts/backlog/backlog-ready.ts +112 -30
- package/scripts/backlog/backlog-stalled-detect.ts +109 -36
- package/scripts/backlog/backlog-stalled.ts +52 -16
- package/scripts/backlog/backlog-wait-cause.ts +86 -0
- package/scripts/backlog/backlog-waves.ts +39 -13
- package/scripts/backlog/backlogrun-args.ts +19 -7
- package/scripts/backlog/backlogrun-cli.ts +19 -5
- package/scripts/backlog/backlogrun-launch.ts +6 -0
- package/scripts/backlog/backlogrun-restart.ts +97 -0
- package/scripts/backlog/backlogrun-stop.ts +79 -7
- package/scripts/behavior/behavior-cli.ts +2 -2
- package/scripts/behavior/behavior-rules.ts +47 -24
- package/scripts/build/build-bin.ts +2 -16
- package/scripts/build/build-claude-md.ts +0 -7
- package/scripts/build/build-commands.ts +0 -13
- package/scripts/build/build-hooks.ts +49 -48
- package/scripts/build/hook-bundle-stamp.ts +29 -11
- package/scripts/build/local-bin.ts +1 -1
- package/scripts/cases/cases-cli.ts +25 -13
- package/scripts/cases/cases-interaction-scan.ts +134 -0
- package/scripts/cases/cases-interaction.ts +183 -0
- package/scripts/cases/cases-logic.ts +39 -6
- package/scripts/ci/pr-classification-main.ts +18 -0
- package/scripts/ci/pr-classification.ts +10 -17
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/cost-runtime/cost-blocks.ts +22 -37
- package/scripts/cost-runtime/cost-cli.ts +31 -14
- package/scripts/cost-runtime/cost-main.ts +12 -0
- package/scripts/cost-runtime/cost-transcript.ts +1 -0
- package/scripts/delegation/delegation-policy.ts +17 -4
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/investigation-guard.ts +0 -8
- package/scripts/delegation/investigation-reads.ts +3 -4
- package/scripts/dependabot/dependabot-cooldown.ts +194 -0
- package/scripts/discovery/repo-discovery.ts +24 -6
- package/scripts/doctor/doctor-consumer.ts +2 -5
- package/scripts/document/document-byte-budget.ts +8 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +0 -8
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-busy.ts +5 -12
- package/scripts/epic/epic-classify.ts +24 -15
- package/scripts/epic/epic-cli-argv.ts +31 -0
- package/scripts/epic/epic-cli-decide.ts +42 -0
- package/scripts/epic/epic-cli.ts +6 -38
- package/scripts/epic/epic-close.ts +112 -55
- package/scripts/epic/epic-cross-repo.ts +4 -7
- package/scripts/epic/epic-decide.ts +119 -0
- package/scripts/epic/epic-decision.ts +9 -0
- package/scripts/epic/epic-fetch.ts +4 -0
- package/scripts/epic/epic-graph.ts +2 -0
- package/scripts/epic/epic-issue.ts +5 -1
- package/scripts/epic/epic-label-age.ts +1 -1
- package/scripts/epic/epic-lane-offer.ts +39 -4
- package/scripts/epic/epic-next-main.ts +24 -0
- package/scripts/epic/epic-next.ts +6 -24
- package/scripts/epic/epic-outside-blocker.ts +6 -2
- package/scripts/epic/epic-parse.ts +9 -3
- package/scripts/epic/epic-read.ts +1 -0
- package/scripts/epic/epic-reconcile.ts +39 -0
- package/scripts/epic/epic-run.ts +10 -1
- package/scripts/epic/epic-solo.ts +50 -14
- package/scripts/epic/epic.ts +41 -7
- package/scripts/exports/unused-members-cli.ts +2 -2
- package/scripts/followup/followup-checks-event.ts +8 -3
- package/scripts/followup/followup-coderabbit-wait.ts +82 -0
- package/scripts/followup/followup-review-gates.ts +81 -0
- package/scripts/followup/git-followup-stages.ts +13 -3
- package/scripts/followup/git-followup-workflow.ts +19 -66
- package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
- package/scripts/followup/git-pr-followup.ts +36 -8
- package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
- package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
- package/scripts/gate/busy-average.ts +58 -0
- package/scripts/gate/check-cpu.ts +60 -0
- package/scripts/gate/check-inputs.ts +39 -95
- package/scripts/gate/check-reuse.ts +33 -54
- package/scripts/gate/command-memory.ts +192 -0
- package/scripts/gate/core-admission.ts +218 -28
- package/scripts/gate/core-budget-timing.ts +37 -0
- package/scripts/gate/core-budget.ts +80 -98
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +37 -5
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +27 -4
- package/scripts/gate/gate-ledger.ts +32 -4
- package/scripts/gate/gate-plan.ts +41 -34
- package/scripts/gate/gate-report.ts +14 -2
- package/scripts/gate/gate-run-steps.ts +53 -8
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +65 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/project-checks.ts +5 -12
- package/scripts/gate/scoped-green.ts +12 -8
- package/scripts/gate/since-green.ts +62 -0
- package/scripts/gate/toolchain-inputs.ts +115 -0
- package/scripts/gate/verification-gate.ts +27 -24
- package/scripts/gate/verification-inputs.ts +250 -0
- package/scripts/gh/gh-author-association.ts +96 -9
- package/scripts/gh/git-ai-review-scan.ts +4 -2
- package/scripts/gh/git-gh-api-path.ts +15 -0
- package/scripts/gh/git-gh-branch-rules.ts +73 -0
- package/scripts/gh/git-gh-conditional.ts +5 -2
- package/scripts/gh/git-gh-issue-read.ts +5 -1
- package/scripts/gh/git-gh-issue-write.ts +67 -29
- package/scripts/gh/git-gh-issue.ts +7 -3
- package/scripts/gh/git-gh-poll-read.ts +89 -0
- package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
- package/scripts/gh/git-gh-pr-rest.ts +1 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
- package/scripts/gh/git-gh-pr.ts +27 -15
- package/scripts/gh/git-pr-checks-eval.ts +39 -7
- package/scripts/gh/git-pr-checks-parse.ts +39 -9
- package/scripts/gh/git-pr-merge-checked.ts +80 -0
- package/scripts/git/base-tree.ts +19 -2
- package/scripts/git/changed-file-scope.ts +6 -4
- package/scripts/git/changed-paths.ts +18 -1
- package/scripts/git/git-diff-reads.ts +27 -2
- package/scripts/git/git-grep-hits.ts +85 -0
- package/scripts/git/git-location-environment.ts +1 -1
- package/scripts/git/git-merge-conflicts.ts +83 -0
- package/scripts/git/git-preflight.ts +37 -12
- package/scripts/git/git-push-transport.ts +1 -2
- package/scripts/git/git-schemas.ts +17 -7
- package/scripts/git/git-spawn.ts +1 -2
- package/scripts/git/git-status.ts +4 -4
- package/scripts/git/main-merge-main.ts +12 -0
- package/scripts/git/main-merge-regenerate.ts +2 -2
- package/scripts/git/main-merge.ts +25 -9
- package/scripts/git/main-sync-main.ts +12 -0
- package/scripts/git/main-sync.ts +0 -9
- package/scripts/git/stash/git-stash.ts +27 -4
- package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
- package/scripts/git/stash/stash-pop-cli.ts +6 -12
- package/scripts/git/stash/stash-pop-main.ts +12 -0
- package/scripts/git/stash/stash-push-cli.ts +76 -0
- package/scripts/git/stash/stash-push-main.ts +12 -0
- package/scripts/hooks/batch-guard.ts +0 -8
- package/scripts/hooks/check-commit-message-main.ts +8 -0
- package/scripts/hooks/check-commit-message.ts +4 -7
- package/scripts/hooks/format-edited-file.ts +8 -24
- package/scripts/hooks/pre-commit-lint.ts +30 -3
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +32 -19
- package/scripts/hooks/reserved-run.ts +67 -9
- package/scripts/hooks/run-hook.sh +13 -4
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +2 -21
- package/scripts/hooks/stop-guard.ts +13 -9
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -17
- package/scripts/init/init-actions.ts +0 -6
- package/scripts/init/init-ai-copy.ts +10 -36
- package/scripts/init/init-bootstrap.ts +9 -8
- package/scripts/init/init-dry-run-report.ts +1 -1
- package/scripts/init/init-dry-run.ts +1 -1
- package/scripts/init/init-file-action.ts +7 -9
- package/scripts/init/init-logic-json-merge.ts +2 -2
- package/scripts/init/init-logic-migrate.ts +9 -82
- package/scripts/init/init-logic.ts +3 -2
- package/scripts/init/init-main.ts +12 -0
- package/scripts/init/init.ts +5 -12
- package/scripts/init/kit-development-versions.ts +3 -7
- package/scripts/init/kit-written-paths.ts +2 -2
- package/scripts/init/project-profile.ts +5 -4
- package/scripts/init/tsconfig-preset-migration.ts +2 -1
- package/scripts/init/vscode-tasks.ts +1 -1
- package/scripts/issue/defect-origin-cli.ts +106 -0
- package/scripts/issue/defect-origin-line.ts +60 -0
- package/scripts/issue/defect-origin-main.ts +11 -0
- package/scripts/issue/defect-origin.ts +114 -0
- package/scripts/issue/defect-rate-cli.ts +34 -78
- package/scripts/issue/defect-rate.ts +0 -16
- package/scripts/issue/defect-report-cli.ts +128 -0
- package/scripts/issue/defect-report-format.ts +56 -0
- package/scripts/issue/defect-report-main.ts +11 -0
- package/scripts/issue/defect-report.ts +160 -0
- package/scripts/issue/expected-effect-lint.ts +1 -0
- package/scripts/issue/issue-already-done-cli.ts +62 -0
- package/scripts/issue/issue-body-or-comment.ts +40 -0
- package/scripts/issue/issue-cite-cli.ts +0 -9
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +12 -7
- package/scripts/issue/issue-comment-cli.ts +10 -24
- package/scripts/issue/issue-comment-main.ts +12 -0
- package/scripts/issue/issue-evidence-exit.ts +100 -0
- package/scripts/issue/issue-file-cli.ts +29 -7
- package/scripts/issue/issue-file.ts +19 -19
- package/scripts/issue/issue-fold-cli.ts +2 -11
- package/scripts/issue/issue-fold-main.ts +12 -0
- package/scripts/issue/issue-labels.ts +81 -90
- package/scripts/issue/issue-lint-cli.ts +2 -10
- package/scripts/issue/issue-lint-main.ts +12 -0
- package/scripts/issue/issue-measured-cli.ts +56 -0
- package/scripts/issue/issue-merged.ts +19 -2
- package/scripts/issue/issue-not-before-label.ts +135 -0
- package/scripts/issue/issue-not-before.ts +111 -0
- package/scripts/issue/issue-number-shape.ts +15 -1
- package/scripts/issue/issue-park.ts +28 -0
- package/scripts/issue/issue-plan-cli.ts +151 -0
- package/scripts/issue/issue-priority.ts +151 -0
- package/scripts/issue/issue-rank.ts +7 -1
- package/scripts/issue/issue-read-cli.ts +3 -10
- package/scripts/issue/issue-read-main.ts +12 -0
- package/scripts/issue/issue-read.ts +29 -5
- package/scripts/issue/issue-release-cli.ts +0 -10
- package/scripts/issue/issue-release-main.ts +13 -0
- package/scripts/issue/issue-release.ts +7 -12
- package/scripts/issue/issue-sample-gate.ts +192 -0
- package/scripts/issue/issue-sample-source.ts +76 -0
- package/scripts/issue/issue-scout-cli.ts +0 -11
- package/scripts/issue/issue-scout-main.ts +14 -0
- package/scripts/issue/issue-state-cli.ts +0 -10
- package/scripts/issue/issue-state-main.ts +12 -0
- package/scripts/issue/issue-watch-diff.ts +56 -15
- package/scripts/issue/issue-watch.ts +2 -1
- package/scripts/issue/issue-wip.ts +2 -7
- package/scripts/issue/measure-rerun-cli.ts +13 -8
- package/scripts/issue/plan-consumers-cli.ts +39 -0
- package/scripts/issue/plan-consumers-main.ts +11 -0
- package/scripts/issue/plan-consumers-section.ts +55 -0
- package/scripts/issue/plan-consumers.ts +127 -0
- package/scripts/josh/agent-session-environment.ts +1 -1
- package/scripts/josh/command-usage.ts +15 -43
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +12 -6
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +157 -158
- package/scripts/josh/josh-commands-backlog.ts +82 -16
- package/scripts/josh/josh-commands-clone.ts +1 -0
- package/scripts/josh/josh-commands-development.ts +111 -71
- package/scripts/josh/josh-commands-document.ts +43 -1
- package/scripts/josh/josh-commands-epic.ts +171 -0
- package/scripts/josh/josh-commands-hooks.ts +25 -2
- package/scripts/josh/josh-commands-issue-write.ts +181 -0
- package/scripts/josh/josh-commands-issue.ts +124 -24
- package/scripts/josh/josh-commands-lane.ts +103 -2
- package/scripts/josh/josh-commands-lint.ts +19 -8
- package/scripts/josh/josh-commands-maintenance.ts +112 -4
- package/scripts/josh/josh-commands-pause.ts +29 -0
- package/scripts/josh/josh-commands-progress.ts +87 -0
- package/scripts/josh/josh-commands-project.ts +138 -9
- package/scripts/josh/josh-commands-review.ts +124 -0
- package/scripts/josh/josh-commands-run.ts +211 -23
- package/scripts/josh/josh-commands-ship.ts +169 -0
- package/scripts/josh/josh-commands-split.ts +9 -0
- package/scripts/josh/josh-commands-versioning.ts +49 -2
- package/scripts/josh/josh-commands-workflow.ts +144 -6
- package/scripts/josh/josh-logic.ts +6 -13
- package/scripts/josh/package-directory.ts +2 -4
- package/scripts/josh/process-identity.ts +13 -4
- package/scripts/josh/session-language-cli.ts +4 -8
- package/scripts/josh/session-language-main.ts +13 -0
- package/scripts/josh/session-language.ts +6 -1
- package/scripts/josh/shared-cache.ts +90 -0
- package/scripts/josh/stamp-file.ts +9 -15
- package/scripts/lane/lane-await.ts +51 -12
- package/scripts/lane/lane-cache.ts +5 -30
- package/scripts/lane/lane-capacity.ts +14 -23
- package/scripts/lane/lane-check-stats.ts +62 -21
- package/scripts/lane/lane-child-invocation.ts +8 -0
- package/scripts/lane/lane-cli.ts +15 -5
- package/scripts/lane/lane-close.ts +86 -18
- package/scripts/lane/lane-core-wait-stats.ts +66 -0
- package/scripts/lane/lane-dispatch.ts +24 -3
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-handoff.ts +69 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +4 -11
- package/scripts/lane/lane-launch-cli.ts +0 -9
- package/scripts/lane/lane-launch-main.ts +12 -0
- package/scripts/lane/lane-ledger-schema.ts +266 -0
- package/scripts/lane/lane-ledger.ts +92 -123
- package/scripts/lane/lane-limit-cli.ts +12 -1
- package/scripts/lane/lane-measure-cli.ts +57 -11
- package/scripts/lane/lane-open.ts +9 -1
- package/scripts/lane/lane-parked.ts +3 -3
- package/scripts/lane/lane-pause-cli.ts +130 -0
- package/scripts/lane/lane-pause.ts +158 -0
- package/scripts/lane/lane-process-table.ts +166 -0
- package/scripts/lane/lane-reap-settle.ts +124 -0
- package/scripts/lane/lane-reap.ts +50 -15
- package/scripts/lane/lane-registry.ts +24 -3
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +22 -2
- package/scripts/lane/lane-round-two-stats.ts +49 -0
- package/scripts/lane/lane-sampler.ts +4 -0
- package/scripts/lane/lane-session-action.ts +19 -5
- package/scripts/lane/lane-session-broker.ts +102 -21
- package/scripts/lane/lane-snapshot-trace.ts +84 -0
- package/scripts/lane/lane-spans.ts +51 -0
- package/scripts/lane/lane-spent.ts +6 -3
- package/scripts/lane/lane-stage-stats.ts +7 -2
- package/scripts/lane/lane-state.ts +302 -0
- package/scripts/lane/lane-stats.ts +58 -4
- package/scripts/lane/lane-stop-stats.ts +113 -37
- package/scripts/lane/lane-test-related-stats.ts +127 -0
- package/scripts/lane/lane-transcript-calls.ts +145 -0
- package/scripts/lane/lane-transcript-stats.ts +168 -0
- package/scripts/lane/lane-vacant.ts +13 -3
- package/scripts/lane/lane-withdraw-cli.ts +5 -4
- package/scripts/lane/lane-withdraw.ts +50 -49
- package/scripts/lane/process-directories.ts +70 -0
- package/scripts/lane/process-lane-marks.ts +94 -0
- package/scripts/lib/atomic-write.ts +62 -0
- package/scripts/lib/buffered-process.ts +12 -5
- package/scripts/lib/cli-flags.ts +53 -0
- package/scripts/lib/figure-format.ts +63 -0
- package/scripts/lib/json-value.ts +9 -1
- package/scripts/lib/package-manifest.ts +35 -0
- package/scripts/lib/read-file.ts +3 -1
- package/scripts/lib/stamped-memo.ts +63 -0
- package/scripts/lib/stdout-on-stderr.ts +24 -0
- package/scripts/lib/timeouts.ts +9 -0
- package/scripts/lib/transcript-record.ts +91 -0
- package/scripts/lines/effective-limit.ts +1 -1
- package/scripts/lint/eslint-cache-dependencies.ts +145 -0
- package/scripts/lint/eslint-daemon.ts +265 -0
- package/scripts/lint/format.ts +11 -2
- package/scripts/lint/import-graph.ts +279 -0
- package/scripts/lint/lint-gate-scope.ts +102 -0
- package/scripts/lint/lint-parallel-main.ts +19 -0
- package/scripts/lint/lint-parallel.ts +62 -30
- package/scripts/lint/lint-related-scope.ts +30 -24
- package/scripts/lint/lint-related.ts +38 -6
- package/scripts/notify/confirmation-options.ts +1 -2
- package/scripts/notify/telegram-notify.ts +20 -20
- package/scripts/notify/telegram-test-logic.ts +0 -1
- package/scripts/notify/telegram-test-main.ts +8 -0
- package/scripts/notify/telegram-test.ts +2 -6
- package/scripts/observations/observation-ledger.ts +13 -0
- package/scripts/observations/observations-flush-landing.ts +5 -3
- package/scripts/observations/observations-flush.ts +6 -1
- package/scripts/overrides/overrides-check.ts +2 -5
- package/scripts/overrides/overrides-files.ts +2 -1
- package/scripts/overrides/overrides-logic.ts +3 -6
- package/scripts/package/verify-optional-eslint-install.ts +8 -6
- package/scripts/propagate/propagate-publish.ts +2 -7
- package/scripts/propagate/propagate-targets.ts +4 -12
- package/scripts/refactor/import-graph.ts +9 -7
- package/scripts/release/github-release-runs.ts +17 -6
- package/scripts/release/release-approval-prune.ts +18 -0
- package/scripts/release/release-history.ts +1 -3
- package/scripts/release/release-progress.ts +42 -22
- package/scripts/release/release-publish-run.ts +39 -0
- package/scripts/release/release-publish.ts +6 -6
- package/scripts/release/release-scope-cli.ts +0 -10
- package/scripts/release/release-scope-main.ts +12 -0
- package/scripts/repo/repo-setting.ts +3 -6
- package/scripts/repo/required-checks-logic.ts +6 -15
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-labels.ts +155 -0
- package/scripts/report/report-lint-cli.ts +3 -0
- package/scripts/report/report-lint.ts +85 -110
- package/scripts/report/report-template-cli.ts +59 -0
- package/scripts/report/report-template.ts +112 -0
- package/scripts/review/acceptance-map.ts +1 -0
- package/scripts/review/removed-tests-check.ts +86 -0
- package/scripts/review/removed-tests.ts +149 -0
- package/scripts/review/review-brief-cli.ts +81 -15
- package/scripts/review/review-brief-main.ts +12 -0
- package/scripts/review/review-brief.ts +31 -3
- package/scripts/review/review-code-tree.ts +10 -6
- package/scripts/review/review-comment-round.ts +26 -8
- package/scripts/review/review-finding-ledger.ts +30 -15
- package/scripts/review/review-interaction.ts +94 -0
- package/scripts/review/review-readers-scan.ts +163 -0
- package/scripts/review/review-record-cli.ts +69 -30
- package/scripts/review/review-record-main.ts +12 -0
- package/scripts/review/review-round-one-blobs.ts +221 -0
- package/scripts/review/review-round2-cli.ts +49 -12
- package/scripts/review/review-round2.ts +80 -12
- package/scripts/review/review-stamps.ts +19 -1
- package/scripts/review/review-stop-log.ts +96 -0
- package/scripts/review/review-stops-cli.ts +85 -0
- package/scripts/review/review-tree.ts +6 -17
- package/scripts/review/review-untouched-readers.ts +146 -0
- package/scripts/review/test-titles.ts +118 -0
- package/scripts/rules/agent-model.ts +8 -0
- package/scripts/rules/bash-triggers.ts +46 -3
- package/scripts/rules/decision-oracle-batch.ts +9 -1
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +80 -2
- package/scripts/rules/destructive-command.ts +8 -1
- package/scripts/rules/direct-filing.ts +10 -2
- package/scripts/rules/direct-issue-comment.ts +117 -0
- package/scripts/rules/direct-pr-create.ts +69 -3
- package/scripts/rules/early-heartbeat.ts +2 -1
- package/scripts/rules/file-body.ts +7 -0
- package/scripts/rules/filing-cap.ts +7 -0
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +4 -0
- package/scripts/rules/implementation-cut-verdict.ts +1 -1
- package/scripts/rules/implementation-cut.ts +11 -3
- package/scripts/rules/index-guard.ts +8 -1
- package/scripts/rules/issue-comments.ts +9 -1
- package/scripts/rules/josh-git-bare.ts +7 -0
- package/scripts/rules/lane-background.ts +67 -25
- package/scripts/rules/lane-carry-conflict.ts +6 -0
- package/scripts/rules/lane-direct-tool.ts +74 -0
- package/scripts/rules/lane-interactive-ask.ts +9 -2
- package/scripts/rules/lane-park.ts +45 -23
- package/scripts/rules/lane-split-park.ts +10 -2
- package/scripts/rules/lane-switch-main.ts +7 -0
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +1 -1
- package/scripts/rules/poll-loop.ts +7 -0
- package/scripts/rules/pr-merge.ts +123 -0
- package/scripts/rules/protected-files.ts +32 -5
- package/scripts/rules/raw-field-body.ts +6 -0
- package/scripts/rules/rule-body-guard.ts +8 -0
- package/scripts/rules/rule-list.ts +9 -28
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +1 -1
- package/scripts/rules/shell-segments.ts +35 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +3 -4
- package/scripts/rules/test-declared-commit.ts +11 -1
- package/scripts/rules/third-party-write.ts +7 -0
- package/scripts/rules/timed-rerun.ts +69 -0
- package/scripts/rules/worktree-guard.ts +13 -3
- package/scripts/run/board/run-board-app-name.ts +23 -0
- package/scripts/run/board/run-board-cli.ts +65 -32
- package/scripts/run/board/run-board-earlier.ts +94 -0
- package/scripts/run/board/run-board-ending-reason.ts +67 -0
- package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
- package/scripts/run/board/run-board-estimate.ts +98 -0
- package/scripts/run/board/run-board-fit.ts +153 -36
- package/scripts/run/board/run-board-fold.ts +123 -0
- package/scripts/run/board/run-board-fresh.ts +2 -2
- package/scripts/run/board/run-board-gather-live.ts +29 -0
- package/scripts/run/board/run-board-gather-thread.ts +189 -0
- package/scripts/run/board/run-board-gather-worker.ts +29 -0
- package/scripts/run/board/run-board-gather.ts +187 -0
- package/scripts/run/board/run-board-github.ts +118 -38
- package/scripts/run/board/run-board-header.ts +82 -20
- package/scripts/run/board/run-board-keys.ts +58 -0
- package/scripts/run/board/run-board-kind.ts +20 -6
- package/scripts/run/board/run-board-labels.ts +116 -71
- package/scripts/run/board/run-board-lane-state.ts +109 -0
- package/scripts/run/board/run-board-lane-time.ts +122 -0
- package/scripts/run/board/run-board-layout.ts +239 -60
- package/scripts/run/board/run-board-length.ts +52 -0
- package/scripts/run/board/run-board-machine.ts +8 -4
- package/scripts/run/board/run-board-main.ts +12 -0
- package/scripts/run/board/run-board-notes.ts +52 -31
- package/scripts/run/board/run-board-now.ts +1 -1
- package/scripts/run/board/run-board-operation.ts +15 -33
- package/scripts/run/board/run-board-phase.ts +1 -1
- package/scripts/run/board/run-board-plan-shared.ts +115 -0
- package/scripts/run/board/run-board-plan.ts +55 -3
- package/scripts/run/board/run-board-planning.ts +45 -0
- package/scripts/run/board/run-board-priority.ts +44 -0
- package/scripts/run/board/run-board-process-groups.ts +195 -0
- package/scripts/run/board/run-board-read.ts +151 -27
- package/scripts/run/board/run-board-reason.ts +235 -51
- package/scripts/run/board/run-board-released.ts +35 -0
- package/scripts/run/board/run-board-render-checks.ts +39 -5
- package/scripts/run/board/run-board-render-condition.ts +96 -0
- package/scripts/run/board/run-board-render-drawn.ts +67 -0
- package/scripts/run/board/run-board-render-foot.ts +59 -0
- package/scripts/run/board/run-board-render-icon.ts +35 -0
- package/scripts/run/board/run-board-render-lanes.ts +145 -0
- package/scripts/run/board/run-board-render-lead.ts +80 -0
- package/scripts/run/board/run-board-render-legend.ts +117 -48
- package/scripts/run/board/run-board-render-notes.ts +156 -29
- package/scripts/run/board/run-board-render-processes.ts +196 -0
- package/scripts/run/board/run-board-render-section.ts +119 -0
- package/scripts/run/board/run-board-render-slot.ts +3 -36
- package/scripts/run/board/run-board-render-tail.ts +115 -48
- package/scripts/run/board/run-board-render-time.ts +56 -0
- package/scripts/run/board/run-board-render-title.ts +117 -24
- package/scripts/run/board/run-board-render-waits.ts +104 -20
- package/scripts/run/board/run-board-render.ts +207 -265
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +9 -4
- package/scripts/run/board/run-board-setup.ts +1 -12
- package/scripts/run/board/run-board-snapshot.ts +111 -0
- package/scripts/run/board/run-board-spin.ts +2 -2
- package/scripts/run/board/run-board-state.ts +22 -33
- package/scripts/run/board/run-board-status.ts +147 -71
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +122 -107
- package/scripts/run/board/run-board-usage-board.ts +78 -0
- package/scripts/run/board/run-board-usage-lanes.ts +113 -0
- package/scripts/run/board/run-board-usage-listing.ts +93 -0
- package/scripts/run/board/run-board-usage-read.ts +120 -150
- package/scripts/run/board/run-board-usage-rusage.ts +19 -7
- package/scripts/run/board/run-board-usage-text.ts +139 -51
- package/scripts/run/board/run-board-usage-top.ts +102 -0
- package/scripts/run/board/run-board-usage.ts +89 -72
- package/scripts/run/board/run-board-usual.ts +20 -9
- package/scripts/run/carry/run-carry-args.ts +4 -7
- package/scripts/run/carry/run-carry-conversation.ts +1 -1
- package/scripts/run/carry/run-carry.ts +9 -4
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/event/run-event-cli.ts +1 -5
- package/scripts/run/event/run-event-filed.ts +12 -6
- package/scripts/run/event/run-event-follow.ts +2 -3
- package/scripts/run/event/run-event-render.ts +6 -10
- package/scripts/run/event/run-event-scope.ts +2 -2
- package/scripts/run/event/run-event-stream-emit.ts +82 -22
- package/scripts/run/event/run-event-stream.ts +34 -8
- package/scripts/run/hold/run-hold-adopt.ts +65 -0
- package/scripts/run/hold/run-hold-cli.ts +93 -22
- package/scripts/run/hold/run-hold-main.ts +12 -0
- package/scripts/run/hold/run-hold-member.ts +37 -0
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +62 -48
- package/scripts/run/merge/run-merge-close.ts +74 -0
- package/scripts/run/merge/run-merge-collect.ts +6 -13
- package/scripts/run/merge/run-merge-driver.ts +71 -0
- package/scripts/run/merge/run-merge-main.ts +12 -0
- package/scripts/run/merge/run-merge-outcome.ts +23 -0
- package/scripts/run/merge/run-merge-restart.ts +39 -0
- package/scripts/run/merge/run-merge-ship.ts +20 -4
- package/scripts/run/merge/run-merge-signals.ts +33 -9
- package/scripts/run/merge/run-merge-steps.ts +120 -85
- package/scripts/run/merge/run-merge.ts +38 -37
- package/scripts/run/park/run-park-cli.ts +91 -0
- package/scripts/run/park/run-park.ts +88 -0
- package/scripts/run/park/run-stalled.ts +68 -0
- package/scripts/run/pause/run-pause-cli.ts +73 -0
- package/scripts/run/pause/run-pause.ts +251 -0
- package/scripts/run/progress/run-progress-cli.ts +4 -12
- package/scripts/run/progress/run-progress-clock.ts +1 -1
- package/scripts/run/progress/run-progress-config.ts +6 -14
- package/scripts/run/progress/run-progress-main.ts +12 -0
- package/scripts/run/progress/run-progress.ts +1 -4
- package/scripts/run/review/run-review.ts +2 -1
- package/scripts/run/run-ending.ts +1 -0
- package/scripts/run/run-invocation.ts +5 -6
- package/scripts/run/run-liveness-cli.ts +6 -8
- package/scripts/run/run-liveness.ts +60 -29
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-preflight.ts +18 -3
- package/scripts/run/run-prep-cli.ts +1 -10
- package/scripts/run/run-prep-locate.ts +7 -50
- package/scripts/run/run-prep-main.ts +12 -0
- package/scripts/run/run-prep.ts +6 -0
- package/scripts/run/run-report-cli.ts +101 -13
- package/scripts/run/run-report-handoff.ts +114 -0
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +13 -0
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +1 -1
- package/scripts/run/ship/run-ship-args.ts +121 -0
- package/scripts/run/ship/run-ship-body-draft.ts +110 -0
- package/scripts/run/ship/run-ship-cli.ts +63 -140
- package/scripts/run/ship/run-ship-detach.ts +19 -8
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +18 -2
- package/scripts/run/ship/run-ship-overlap.ts +42 -5
- package/scripts/run/ship/run-ship-place.ts +96 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
- package/scripts/run/ship/run-ship-preflight.ts +137 -32
- package/scripts/run/ship/run-ship-probe.ts +11 -3
- package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
- package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
- package/scripts/run/ship/run-ship-return.ts +107 -23
- package/scripts/run/ship/run-ship-review-steps.ts +105 -151
- package/scripts/run/ship/run-ship-review.ts +73 -6
- package/scripts/run/ship/run-ship-reviewer.ts +207 -0
- package/scripts/run/ship/run-ship-stage.ts +55 -6
- package/scripts/run/ship/run-ship-steps.ts +46 -15
- package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +43 -6
- package/scripts/run/ship/run-ship.ts +30 -2
- package/scripts/run/tidy/run-tidy-cli.ts +0 -4
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
- package/scripts/run/tidy/run-tidy-main.ts +8 -0
- package/scripts/run/wake/run-wake-cli.ts +119 -100
- package/scripts/run/wake/run-wake-code.ts +83 -0
- package/scripts/run/wake/run-wake-driver.ts +19 -8
- package/scripts/run/wake/run-wake-loop.ts +34 -3
- package/scripts/run/wake/run-wake-main.ts +13 -0
- package/scripts/run/wake/run-wake-ports.ts +90 -0
- package/scripts/run/wake/run-wake-takeover.ts +66 -0
- package/scripts/run/wake/run-wake.ts +2 -1
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -1
- package/scripts/safe-chain/project-config.ts +3 -9
- package/scripts/security/security-audit-main.ts +8 -0
- package/scripts/security/security-audit-provision-logic.ts +0 -11
- package/scripts/security/security-audit-provision-main.ts +12 -0
- package/scripts/security/security-audit-provision.ts +11 -26
- package/scripts/security/security-audit.ts +6 -7
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
- package/scripts/split/split-assess-cli.ts +2 -2
- package/scripts/split/split-assess.ts +15 -0
- package/scripts/split/split-measure.ts +65 -0
- package/scripts/sync/claude-settings-merge.ts +8 -15
- package/scripts/sync/directory-copy-guard.ts +4 -9
- package/scripts/sync/file-content.ts +78 -8
- package/scripts/sync/sync-ai-files.ts +3 -5
- package/scripts/sync/sync-configs.ts +11 -23
- package/scripts/sync/sync-hook-safety.ts +4 -10
- package/scripts/sync/sync-main.ts +11 -0
- package/scripts/sync/sync.ts +25 -37
- package/scripts/test/test-declared-changed.ts +2 -2
- package/scripts/test/test-declared.ts +1 -1
- package/scripts/test/test-e2e-guard.ts +25 -1
- package/scripts/test/test-e2e-stamp.ts +38 -0
- package/scripts/test/test-pinned-logic.ts +145 -0
- package/scripts/test/test-pinned-main.ts +78 -0
- package/scripts/test/test-pinned.ts +100 -0
- package/scripts/test/test-read-map.ts +264 -0
- package/scripts/test/test-read-recording.ts +91 -0
- package/scripts/test/test-read-trace.ts +148 -0
- package/scripts/test/test-red-main.ts +12 -0
- package/scripts/test/test-red.ts +12 -30
- package/scripts/test/test-related-main.ts +18 -0
- package/scripts/test/test-related-record.ts +119 -0
- package/scripts/test/test-related-scope.ts +229 -43
- package/scripts/test/test-related.ts +300 -22
- package/scripts/test/test-unit-guard-main.ts +15 -0
- package/scripts/test/test-unit-guard.ts +42 -24
- package/scripts/test/unit-count-file.ts +37 -0
- package/scripts/test/unit-run-marker.ts +162 -0
- package/scripts/test/unit-setup-files.ts +51 -0
- package/scripts/test/unit-worker-share.ts +61 -149
- package/scripts/test/whole-suite-files.ts +63 -0
- package/scripts/time-runtime/time-background.ts +20 -2
- package/scripts/time-runtime/time-bundles.ts +4 -3
- package/scripts/time-runtime/time-density-hook.ts +8 -6
- package/scripts/time-runtime/time-followup-stage.ts +1 -3
- package/scripts/time-runtime/time-format.ts +5 -28
- package/scripts/time-runtime/time-markers.ts +10 -1
- package/scripts/time-runtime/time-shell.ts +97 -10
- package/scripts/time-runtime/time-transcript-line.ts +49 -62
- package/scripts/uninstall/uninstall.ts +1 -1
- package/scripts/version/bump-version-main.ts +12 -0
- package/scripts/version/bump-version.ts +25 -25
- package/scripts/version/effective-upstream.ts +6 -12
- package/scripts/version/latest-corepack.ts +17 -32
- package/scripts/version/latest-if-required-cli.ts +93 -0
- package/scripts/version/latest-lane-guard-main.ts +8 -0
- package/scripts/version/latest-lane-guard.ts +0 -4
- package/scripts/version/latest-scope-cli.ts +0 -9
- package/scripts/version/latest-scope-main.ts +12 -0
- package/scripts/version/latest-update.ts +5 -5
- package/scripts/version/npm-registry.ts +44 -6
- package/scripts/version/publishable-range-check.ts +5 -16
- package/scripts/version/release-age.ts +1 -1
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/release-window.ts +38 -0
- package/scripts/version/running-binary.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +3 -8
- package/scripts/version/version-targets.ts +6 -28
- package/templates/dependabot.yml +29 -0
- package/templates/gitignore +4 -1
- package/templates/pnpm-workspace.basic.yaml +1 -1
- package/templates/sonar-project.properties +3 -2
- package/templates/workflows/ci.yml +12 -4
- package/templates/workflows/github-release.yml +4 -0
- package/tsconfig.sonar.json +1 -1
- package/.ncurc.json +0 -3
- package/dist/hooks/batch-guard.js +0 -29
- package/dist/hooks/chunk-4KKD2UTK.js +0 -66
- package/dist/hooks/chunk-6TS2JD6D.js +0 -237
- package/dist/hooks/chunk-7DSBJVFH.js +0 -50
- package/dist/hooks/chunk-A65Y4YOR.js +0 -79
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EFXE6C37.js +0 -81
- package/dist/hooks/chunk-GP4IEC4O.js +0 -20
- package/dist/hooks/chunk-JP45SOCJ.js +0 -56
- package/dist/hooks/chunk-LAOV7NLM.js +0 -45
- package/dist/hooks/chunk-M4HGZV7U.js +0 -83
- package/dist/hooks/chunk-PF2NZL2A.js +0 -131
- package/dist/hooks/chunk-PTICX4OL.js +0 -358
- package/dist/hooks/chunk-RT27QRJW.js +0 -6247
- package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
- package/dist/hooks/chunk-UPUZF3AN.js +0 -279
- package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -29
- package/scripts/backlog/backlog-stalled-cli.ts +0 -30
- package/scripts/cost-runtime/cost-format.ts +0 -29
- package/scripts/init/basic-path-migration.ts +0 -24
- package/scripts/issue/issue-backlinks-cli.ts +0 -93
- package/scripts/josh/josh-commands-guard.ts +0 -38
- package/scripts/josh/josh-usage-automation.ts +0 -121
- package/scripts/josh/josh-usage-backlog.ts +0 -180
- package/scripts/josh/josh-usage-developer.ts +0 -230
- package/scripts/josh/josh-usage-hooks.ts +0 -38
- package/scripts/josh/josh-usage-issue.ts +0 -205
- package/scripts/josh/josh-usage-review.ts +0 -101
- package/scripts/josh/josh-usage-run.ts +0 -252
- package/scripts/josh/josh-usage-session.ts +0 -238
- package/scripts/josh/josh-usage-workflow.ts +0 -212
- package/scripts/lint/cross-file-recheck.ts +0 -155
- package/scripts/registry-migration/migrate-logic.ts +0 -237
- package/scripts/registry-migration/migrate.ts +0 -292
- package/scripts/registry-migration/user-npmrc.ts +0 -15
- package/scripts/rules/rule-guard.ts +0 -23
- package/scripts/rules/rule-registry-rows.ts +0 -292
- package/scripts/rules/rule-registry.ts +0 -112
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises'
|
|
2
|
-
import { availableParallelism, cpus, totalmem } from 'node:os'
|
|
2
|
+
import { availableParallelism, cpus, loadavg, totalmem } from 'node:os'
|
|
3
3
|
import { PROBE_TIMEOUT_MS } from '#scripts/lib/timeouts'
|
|
4
4
|
import { execa } from 'execa'
|
|
5
5
|
|
|
@@ -32,12 +32,12 @@ import { execa } from 'execa'
|
|
|
32
32
|
// The window the busy cores are measured over: long enough that one scheduler tick does not dominate it,
|
|
33
33
|
// short enough that a solo admission is not visibly delayed.
|
|
34
34
|
const SAMPLE_WINDOW_MS = 250
|
|
35
|
-
// **
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
const
|
|
35
|
+
// **Run-queue load outside the ledger past this many times the cores holds the first waiter too**
|
|
36
|
+
// (joshuafolkken/kit#4361). The first waiter ignores outside load (joshuafolkken/kit#4313), and lanes took
|
|
37
|
+
// the 11-core machine to a load average of 25–34. Twice the cores is loose on purpose: the one-core
|
|
38
|
+
// editor load #4313 stopped holding a solo gate stays far below it, so neither its starvation nor the
|
|
39
|
+
// lanes' speed comes back, while a machine whose queue beyond the ledger passes two per core waits.
|
|
40
|
+
const OVERLOAD_FACTOR = 2
|
|
41
41
|
const BYTES_PER_MB = 1_048_576
|
|
42
42
|
const KB_PER_MB = 1024
|
|
43
43
|
const PERCENT = 100
|
|
@@ -62,7 +62,10 @@ const PAGE_SIZE_NAME = 'hw.pagesize'
|
|
|
62
62
|
// The kernel's memory-pressure verdict — 1 normal, 2 warning, 4 critical — the one Activity Monitor
|
|
63
63
|
// colors its "memory pressure" graph by.
|
|
64
64
|
const PRESSURE_NAME = 'kern.memorystatus_vm_pressure_level'
|
|
65
|
-
|
|
65
|
+
// **Only critical holds; warning is sticky** (joshuafolkken/kit#4199). On macOS the verdict can stay at
|
|
66
|
+
// warning for hours after the pressure passed, so a hold on warning never lifts. What is pressured right
|
|
67
|
+
// now shows in the free figure and the swap and compressor traffic; the verdict adds only critical.
|
|
68
|
+
const PRESSURE_HOLD = 4
|
|
66
69
|
// The swap traffic across one window that reads as pressure — 64 MB a second paged to disk. A machine
|
|
67
70
|
// that swapped once still pages a few megabytes back in as old pages are touched.
|
|
68
71
|
const SWAP_PRESSURE_MB = 16
|
|
@@ -81,10 +84,13 @@ const SYSCTL_ARGUMENTS = [
|
|
|
81
84
|
const SYSCTL_LINE = /^(?<name>[\w.]+): (?<value>\d+)$/gmu
|
|
82
85
|
|
|
83
86
|
// `memory_pressured` says why `available_mb` read none, so a claim that waits can name the pressure.
|
|
87
|
+
// `run_queue` is the one-minute load average: the busy cores stop at the core count, so only the queue
|
|
88
|
+
// tells a machine at twice its cores from one at once (`is_overloaded`).
|
|
84
89
|
interface MachineReading {
|
|
85
90
|
busy_cores: number | undefined
|
|
86
91
|
available_mb: number | undefined
|
|
87
92
|
memory_pressured?: boolean | undefined
|
|
93
|
+
run_queue?: number | undefined
|
|
88
94
|
}
|
|
89
95
|
|
|
90
96
|
// The memory half of a reading. `swapped_mb` is a counter — every page swapped in or out since boot —
|
|
@@ -103,10 +109,15 @@ interface LedgerLoad {
|
|
|
103
109
|
memory_mb: number
|
|
104
110
|
}
|
|
105
111
|
|
|
112
|
+
// `busy_excess` is the measured cores beyond what the ledger declares — what `cores` gave up to load the
|
|
113
|
+
// ledger does not hold, so a claim that waits on it can name the CPU as saturated. `is_overloaded` lifts
|
|
114
|
+
// the first waiter's exemption from that load (`core_admission.is_admitted`).
|
|
106
115
|
interface MachineBudget {
|
|
107
116
|
cores: number
|
|
108
117
|
memory_mb: number
|
|
109
118
|
memory_pressured?: boolean | undefined
|
|
119
|
+
busy_excess?: number | undefined
|
|
120
|
+
is_overloaded?: boolean | undefined
|
|
110
121
|
}
|
|
111
122
|
|
|
112
123
|
interface CpuTimes {
|
|
@@ -287,22 +298,23 @@ function moved_over(from: number | undefined, to: number | undefined, limit: num
|
|
|
287
298
|
|
|
288
299
|
function is_pressured(before: MemoryReading, after: MemoryReading): boolean {
|
|
289
300
|
return (
|
|
290
|
-
(after.pressure_level ?? 0) >=
|
|
301
|
+
(after.pressure_level ?? 0) >= PRESSURE_HOLD ||
|
|
291
302
|
moved_over(before.swapped_mb, after.swapped_mb, SWAP_PRESSURE_MB) ||
|
|
292
303
|
moved_over(before.compressed_mb, after.compressed_mb, COMPRESSION_PRESSURE_MB)
|
|
293
304
|
)
|
|
294
305
|
}
|
|
295
306
|
|
|
296
|
-
// **
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
//
|
|
302
|
-
|
|
307
|
+
// **Only a reading the kernel calls critical has nothing free to admit against.** Swap and compressor
|
|
308
|
+
// traffic across the window used to answer no free memory too (joshuafolkken/kit#3943), but this machine
|
|
309
|
+
// swaps out 0.4–1.3 TB a day as a matter of course, so that traffic held about a third of every wait
|
|
310
|
+
// with memory to spare (joshuafolkken/kit#4313). A claim now waits on memory only when the free figure
|
|
311
|
+
// falls short of what it declares; the traffic still names the wait as pressure (`memory_pressured`),
|
|
312
|
+
// and holds a claim past the shortfall that running alone or the wait cap would otherwise start
|
|
313
|
+
// (`core_admission.is_swap_held`, joshuafolkken/kit#4451).
|
|
314
|
+
function pressured_available(after: MemoryReading): number | undefined {
|
|
303
315
|
if (after.available_mb === undefined) return undefined
|
|
304
316
|
|
|
305
|
-
return
|
|
317
|
+
return (after.pressure_level ?? 0) >= PRESSURE_HOLD ? 0 : after.available_mb
|
|
306
318
|
}
|
|
307
319
|
|
|
308
320
|
// Memory is read at both ends of the window, so the swap counter's difference is the activity during it.
|
|
@@ -312,13 +324,13 @@ async function read_machine(
|
|
|
312
324
|
const before = cpu_times()
|
|
313
325
|
const [memory_before] = await Promise.all([read_memory(), sleep(SAMPLE_WINDOW_MS)])
|
|
314
326
|
const memory_after = await read_memory()
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
: undefined
|
|
327
|
+
const is_host = is_unquoted()
|
|
328
|
+
const busy_cores = is_host ? busy_cores_between(before, cpu_times(), cpus().length) : undefined
|
|
318
329
|
|
|
319
330
|
return {
|
|
320
331
|
busy_cores,
|
|
321
|
-
|
|
332
|
+
run_queue: is_host ? loadavg()[0] : undefined,
|
|
333
|
+
available_mb: pressured_available(memory_after),
|
|
322
334
|
memory_pressured: is_pressured(memory_before, memory_after),
|
|
323
335
|
}
|
|
324
336
|
}
|
|
@@ -327,31 +339,52 @@ async function read_sample(): Promise<MachineSample> {
|
|
|
327
339
|
return { cpu: cpu_times(), memory: await read_memory(), total_mb: totalmem() / BYTES_PER_MB }
|
|
328
340
|
}
|
|
329
341
|
|
|
330
|
-
// The busy cores the ledger does not account for,
|
|
331
|
-
//
|
|
342
|
+
// The busy cores the ledger does not account for, in whole cores — the budget is in whole cores, and a
|
|
343
|
+
// fraction of a core is not a core to give up.
|
|
344
|
+
//
|
|
345
|
+
// **Every busy core counts, the background included** (joshuafolkken/kit#4238). A baseline of two cores
|
|
346
|
+
// used to be exempt, so with 10 cores reserved and all 11 busy the reading saw no excess and admitted
|
|
347
|
+
// another claim onto a saturated CPU.
|
|
332
348
|
function external_cores(busy_cores: number | undefined, ledger_cores: number): number {
|
|
333
349
|
if (busy_cores === undefined) return 0
|
|
334
350
|
|
|
335
|
-
return Math.floor(Math.max(0, busy_cores - ledger_cores
|
|
351
|
+
return Math.floor(Math.max(0, busy_cores - ledger_cores))
|
|
336
352
|
}
|
|
337
353
|
|
|
338
|
-
//
|
|
339
|
-
//
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
-
|
|
354
|
+
// The run queue beyond what the ledger declares, past `OVERLOAD_FACTOR` times the cores. The ledger's own
|
|
355
|
+
// claims running past their weight count as outside load. The load average trails by a minute, so a
|
|
356
|
+
// first waiter held here waits out the decay — only at a load already this far past the machine. A queue
|
|
357
|
+
// that could not be read, and Windows' constant zero, never hold.
|
|
358
|
+
function is_overloaded(
|
|
359
|
+
run_queue: number | undefined,
|
|
360
|
+
ledger_cores: number,
|
|
361
|
+
cores: number,
|
|
362
|
+
): boolean {
|
|
363
|
+
if (run_queue === undefined) return false
|
|
364
|
+
|
|
365
|
+
return run_queue - ledger_cores > cores * OVERLOAD_FACTOR
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// **The budget the ledger admits against: `cores − max(ledger, busy)` free, plus what the ledger itself
|
|
369
|
+
// already holds.** The admission walk counts the ledger's declared weight again, so it is added back —
|
|
370
|
+
// what is subtracted is only the busy load beyond it. A claim admitted moments ago is not busy yet, and
|
|
371
|
+
// the ledger's declared cores cover it. The caller passes every admitted claim's cores but only the
|
|
372
|
+
// memory of claims past `core_admission.RAMP_UP_MS`, whose tools have had time to allocate.
|
|
343
373
|
// Memory that could not be read is no limit at all, the behavior before memory was read.
|
|
344
374
|
function machine_budget(cores: number, reading: MachineReading, ledger: LedgerLoad): MachineBudget {
|
|
375
|
+
const busy_excess = external_cores(reading.busy_cores, ledger.cores)
|
|
376
|
+
|
|
345
377
|
return {
|
|
346
|
-
cores: cores -
|
|
378
|
+
cores: Math.max(0, cores - busy_excess),
|
|
347
379
|
memory_mb:
|
|
348
380
|
reading.available_mb === undefined ? Infinity : reading.available_mb + ledger.memory_mb,
|
|
349
381
|
memory_pressured: reading.memory_pressured,
|
|
382
|
+
busy_excess,
|
|
383
|
+
is_overloaded: is_overloaded(reading.run_queue, ledger.cores, cores),
|
|
350
384
|
}
|
|
351
385
|
}
|
|
352
386
|
|
|
353
387
|
const machine_capacity = {
|
|
354
|
-
BASELINE_CORES,
|
|
355
388
|
busy_cores_between,
|
|
356
389
|
busy_share_between,
|
|
357
390
|
COMPRESSION_PRESSURE_MB,
|
|
@@ -360,6 +393,7 @@ const machine_capacity = {
|
|
|
360
393
|
parse_darwin_memory,
|
|
361
394
|
parse_linux_available,
|
|
362
395
|
parse_linux_swapped,
|
|
396
|
+
PRESSURE_HOLD,
|
|
363
397
|
pressured_available,
|
|
364
398
|
read_machine,
|
|
365
399
|
read_memory,
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { git_spawn } from '#scripts/git/git-spawn'
|
|
2
|
+
import { file_map_stamp, type FileMapStamp } from '#scripts/josh/file-map-stamp'
|
|
3
|
+
import type { GateTree } from './gate-tree'
|
|
4
|
+
|
|
5
|
+
// Every path whose content can differ from the tree a green record was taken on — the one reading the
|
|
6
|
+
// gate's per-check reuse (`check-reuse.ts`) and the scoped checks' since-green narrowing
|
|
7
|
+
// (`since-green.ts`) both act on, so the two can never disagree about what moved.
|
|
8
|
+
//
|
|
9
|
+
// **What moved is the union of two diffs**. The changed-file map is a diff against the merge base, so a
|
|
10
|
+
// path absent from both maps holds the merge base's content — and the base's own diff
|
|
11
|
+
// (`git diff <recorded> <current>`) names every path that content moved for, which is what a main sync
|
|
12
|
+
// brought in. A path in either map whose digest differs is the other half
|
|
13
|
+
// (`file_map_stamp.changed_since`).
|
|
14
|
+
|
|
15
|
+
const NAME_SEPARATOR = '\0'
|
|
16
|
+
const BASE_DIFF = ['diff', '--name-only', '--no-renames', '-z'] as const
|
|
17
|
+
|
|
18
|
+
async function base_diff(from: string, to: string): Promise<ReadonlyArray<string> | undefined> {
|
|
19
|
+
if (from === to) return []
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const names = await git_spawn.read([...BASE_DIFF, from, to])
|
|
23
|
+
|
|
24
|
+
return names.split(NAME_SEPARATOR).filter((name) => name !== '')
|
|
25
|
+
} catch {
|
|
26
|
+
return undefined
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// The two diffs apart: `synced` is what a main sync brought in, `changed` the paths whose digest moved.
|
|
31
|
+
// A path can be in both.
|
|
32
|
+
interface MovedParts {
|
|
33
|
+
changed: ReadonlyArray<string>
|
|
34
|
+
synced: ReadonlyArray<string>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// `undefined` when the record cannot be compared: no base on either side, or a tree map that came back
|
|
38
|
+
// empty — also what `gate-tree.ts` answers when git could not be read, so it describes no tree.
|
|
39
|
+
async function moved_parts(stamp: FileMapStamp, tree: GateTree): Promise<MovedParts | undefined> {
|
|
40
|
+
const is_unread = Object.keys(tree.files).length === 0
|
|
41
|
+
|
|
42
|
+
if (is_unread || stamp.base === undefined || tree.base === undefined) return undefined
|
|
43
|
+
|
|
44
|
+
const synced = await base_diff(stamp.base, tree.base)
|
|
45
|
+
|
|
46
|
+
if (synced === undefined) return undefined
|
|
47
|
+
|
|
48
|
+
return { changed: file_map_stamp.changed_since(stamp, tree.files), synced }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function union_of(parts: MovedParts): ReadonlyArray<string> {
|
|
52
|
+
return [...new Set([...parts.changed, ...parts.synced])]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function moved_since(
|
|
56
|
+
stamp: FileMapStamp,
|
|
57
|
+
tree: GateTree,
|
|
58
|
+
): Promise<ReadonlyArray<string> | undefined> {
|
|
59
|
+
const parts = await moved_parts(stamp, tree)
|
|
60
|
+
|
|
61
|
+
return parts === undefined ? undefined : union_of(parts)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const moved_paths = { moved_parts, moved_since, union_of }
|
|
65
|
+
|
|
66
|
+
export type { MovedParts }
|
|
67
|
+
export { moved_paths }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, globSync
|
|
1
|
+
import { existsSync, globSync } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { find_local_bin_upwards } from '#scripts/build/local-bin'
|
|
4
4
|
import { doctor_consumer } from '#scripts/doctor/doctor-consumer'
|
|
@@ -6,10 +6,10 @@ import { own_formatter } from '#scripts/init/own-formatter'
|
|
|
6
6
|
import { project_profile } from '#scripts/init/project-profile'
|
|
7
7
|
import { ancestor_directories } from '#scripts/lib/ancestor-directories'
|
|
8
8
|
import { json_value } from '#scripts/lib/json-value'
|
|
9
|
+
import { package_manifest } from '#scripts/lib/package-manifest'
|
|
9
10
|
import { NOT_USED_MARKER, SKIP_MARKER } from '#scripts/test/skip-marker'
|
|
10
11
|
import { z } from 'zod'
|
|
11
12
|
|
|
12
|
-
const PACKAGE_JSON = 'package.json'
|
|
13
13
|
const IGNORED_DIRS = new Set([
|
|
14
14
|
'node_modules',
|
|
15
15
|
'.git',
|
|
@@ -48,7 +48,7 @@ const object_schema = z.record(z.string(), z.unknown())
|
|
|
48
48
|
function project_root(directory: string): string {
|
|
49
49
|
return (
|
|
50
50
|
ancestor_directories.nearest(directory, (candidate) =>
|
|
51
|
-
existsSync(
|
|
51
|
+
existsSync(package_manifest.manifest_path(candidate)),
|
|
52
52
|
) ?? directory
|
|
53
53
|
)
|
|
54
54
|
}
|
|
@@ -86,16 +86,9 @@ function is_basic_manifest(manifest: unknown): boolean {
|
|
|
86
86
|
return project_profile.parse_profile(josh['profile']) === 'basic'
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
//
|
|
90
|
-
// `undefined` for text that is not JSON.
|
|
89
|
+
// A missing, unreadable or non-JSON manifest answers `undefined`; the shape is each caller's question.
|
|
91
90
|
function read_manifest(directory: string): unknown {
|
|
92
|
-
|
|
93
|
-
const manifest_path = path.join(project_root(directory), PACKAGE_JSON)
|
|
94
|
-
|
|
95
|
-
return json_value.parse_or_undefined(readFileSync(manifest_path, 'utf8'))
|
|
96
|
-
} catch {
|
|
97
|
-
return undefined
|
|
98
|
-
}
|
|
91
|
+
return package_manifest.read_manifest_if_valid(project_root(directory), z.unknown())
|
|
99
92
|
}
|
|
100
93
|
|
|
101
94
|
function is_basic(directory: string): boolean {
|
|
@@ -12,14 +12,14 @@ import { gate_tree, type GateTree } from './gate-tree'
|
|
|
12
12
|
// tree neither check has read return their findings one round trip at a time; one call running both
|
|
13
13
|
// checks first returns most of them at once.
|
|
14
14
|
//
|
|
15
|
-
// **It fixes when the checks run, never whether they run
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
// check's result in place of re-running it.
|
|
15
|
+
// **It fixes when the checks run, never whether they run.** Nothing here skips a check or
|
|
16
|
+
// reinterprets its output, and `josh gate` still runs its four checks exactly as before. The one other
|
|
17
|
+
// reader is the checks' own re-run, which narrows to what moved since this record (`since-green.ts`).
|
|
19
18
|
//
|
|
20
19
|
// **The judgement is the gate's own, not a second one.** "There is a record and nothing it covers has
|
|
21
20
|
// moved" is `review_brief.matching_stamp` plus the base equality `gate_skip.reusable_green_gate`
|
|
22
|
-
// already compares
|
|
21
|
+
// already compares and the inputs fingerprint each record carries (`verification-inputs.ts`), over the
|
|
22
|
+
// same `FileMapStamp` shape written to the same kind of file. A second
|
|
23
23
|
// definition of "this tree is unchanged" is the clone `CLAUDE.md` prohibits, and it is exactly where
|
|
24
24
|
// two commands would start disagreeing about one working tree.
|
|
25
25
|
//
|
|
@@ -95,7 +95,11 @@ function checks_of(sources: ScopedSources): ReadonlyArray<ScopedCheck> {
|
|
|
95
95
|
function describes_tree(check: ScopedCheck, tree: Record<string, string>, base: string): boolean {
|
|
96
96
|
const stamp = review_brief.matching_stamp(check.stamp.read(check.source), tree)
|
|
97
97
|
|
|
98
|
-
return
|
|
98
|
+
return (
|
|
99
|
+
stamp !== undefined &&
|
|
100
|
+
file_map_stamp.describes_base(stamp, base) &&
|
|
101
|
+
check.stamp.describes_inputs(stamp)
|
|
102
|
+
)
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
// **Whether there is a tree to speak about at all**, asked once and used from both ends: the reader
|
|
@@ -161,8 +165,8 @@ function refusal(missing: ReadonlyArray<string>): string {
|
|
|
161
165
|
'282 seconds, 31% of the run, picking up one lint rule and one failing test at a time after its ' +
|
|
162
166
|
'review had already started. Run them in one call — ' +
|
|
163
167
|
`\`${LINT_COMMAND} && ${TEST_COMMAND}\`, measured at 13.8 seconds — and reissue this command. ` +
|
|
164
|
-
'The record fixes when the checks run and never whether they run: nothing is skipped
|
|
165
|
-
'
|
|
168
|
+
'The record fixes when the checks run and never whether they run: nothing is skipped or reused ' +
|
|
169
|
+
'because of it. `prompts/review.md` → "The scoped checks answer on the last edit".'
|
|
166
170
|
)
|
|
167
171
|
}
|
|
168
172
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { FileMapStampAccess } from '#scripts/josh/file-map-stamp'
|
|
2
|
+
import { gate_tree } from './gate-tree'
|
|
3
|
+
import { moved_paths, type MovedParts } from './moved-paths'
|
|
4
|
+
import { verification_inputs } from './verification-inputs'
|
|
5
|
+
|
|
6
|
+
// **A scoped check re-run reads only what moved since its last green run on this checkout**
|
|
7
|
+
// (joshuafolkken/kit#4393). A lane's ship retry — after a review fix or a preflight stop — re-ran
|
|
8
|
+
// `josh lint:related` and `josh test:related` (the gate's unit step too) over the whole branch diff,
|
|
9
|
+
// though everything outside the fix had been green on the tree before it.
|
|
10
|
+
//
|
|
11
|
+
// **The check is no weaker.** The green record (`scoped-green.ts`) vouches that the check passed over
|
|
12
|
+
// the branch diff of the tree it names; what moved since is every path whose content can differ from
|
|
13
|
+
// that tree (`moved-paths.ts`), a main sync's own changes included. A record written by a narrowed run
|
|
14
|
+
// vouches for the same thing, by the same argument one run earlier.
|
|
15
|
+
//
|
|
16
|
+
// **Whatever cannot be narrowed answers `undefined`**, and the caller reads the whole branch change as
|
|
17
|
+
// before: no record, one that cannot be compared, one written under other tools or environment, or a
|
|
18
|
+
// moved file the check's declaration names a configuration — a file green under the old configuration
|
|
19
|
+
// says nothing under the new one. An empty list is
|
|
20
|
+
// the positive fact that nothing moved: the gate's unit step on the tree the preflight just passed.
|
|
21
|
+
|
|
22
|
+
// The narrowing line each command prints before it runs, so a since-green run is never read as one
|
|
23
|
+
// over the whole branch.
|
|
24
|
+
function describe(label: string, moved: ReadonlyArray<string>): string {
|
|
25
|
+
return `${label}: reading only the ${String(moved.length)} file(s) changed since its last green run on this checkout.`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function is_narrowable(label: string, parts: MovedParts | undefined): parts is MovedParts {
|
|
29
|
+
return parts !== undefined && !verification_inputs.configures(label, moved_paths.union_of(parts))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// What moved with a main sync's part kept apart, for a caller that records how much of its input the
|
|
33
|
+
// sync brought in (`josh test:related`, joshuafolkken/kit#4465). `label` names the gate check whose
|
|
34
|
+
// declaration (`verification-inputs.ts`) the record vouches for.
|
|
35
|
+
async function read_moved_parts(
|
|
36
|
+
stamp: FileMapStampAccess,
|
|
37
|
+
label: string,
|
|
38
|
+
source?: string,
|
|
39
|
+
): Promise<MovedParts | undefined> {
|
|
40
|
+
const record = stamp.read(source)
|
|
41
|
+
|
|
42
|
+
if (record === undefined || !stamp.describes_inputs(record)) return undefined
|
|
43
|
+
|
|
44
|
+
const parts = await moved_paths.moved_parts(record, await gate_tree.read_gate_tree())
|
|
45
|
+
|
|
46
|
+
return is_narrowable(label, parts) ? parts : undefined
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Repository-root-relative paths, or `undefined` when the caller has to read the whole branch change.
|
|
50
|
+
async function read_moved(
|
|
51
|
+
stamp: FileMapStampAccess,
|
|
52
|
+
label: string,
|
|
53
|
+
source?: string,
|
|
54
|
+
): Promise<ReadonlyArray<string> | undefined> {
|
|
55
|
+
const parts = await read_moved_parts(stamp, label, source)
|
|
56
|
+
|
|
57
|
+
return parts === undefined ? undefined : moved_paths.union_of(parts)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const since_green = { describe, read_moved, read_moved_parts }
|
|
61
|
+
|
|
62
|
+
export { since_green }
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto'
|
|
2
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
|
|
5
|
+
// **The toolchain's inputs, listed once** (joshuafolkken/kit#4496): the files whose content moves what
|
|
6
|
+
// a tool answers while every source stays byte-identical — the installed packages, the eslint config
|
|
7
|
+
// and the TypeScript program's options. Every result kept across runs is discarded when they move:
|
|
8
|
+
// the metrics base cache (`metrics-base-cache.ts`), the hook bundles (`hook-bundle-stamp.ts`), the
|
|
9
|
+
// warm ESLint daemon (`eslint-daemon.ts`) and the gate's verdicts (`verification-inputs.ts`). A file
|
|
10
|
+
// added here reaches all of them.
|
|
11
|
+
//
|
|
12
|
+
// Loaded by plain `node` on every hook launch (`tools/hooks/hook-bundle-ready.ts`), so this module
|
|
13
|
+
// imports `node:` built-ins alone.
|
|
14
|
+
|
|
15
|
+
// The package manager's manifest, lock and settings files, and the record pnpm rewrites on every
|
|
16
|
+
// install — a consumer's eslint config imports its rules from installed packages.
|
|
17
|
+
const PACKAGE_FILES: ReadonlyArray<string> = [
|
|
18
|
+
'package.json',
|
|
19
|
+
'pnpm-lock.yaml',
|
|
20
|
+
'pnpm-workspace.yaml',
|
|
21
|
+
'package-lock.json',
|
|
22
|
+
'yarn.lock',
|
|
23
|
+
'bun.lock',
|
|
24
|
+
'bun.lockb',
|
|
25
|
+
'.npmrc',
|
|
26
|
+
'node_modules/.modules.yaml',
|
|
27
|
+
]
|
|
28
|
+
// The root entries of the eslint flat config and of the TypeScript program, and the directories of
|
|
29
|
+
// the rule modules and the shared compiler options they import.
|
|
30
|
+
const CONFIG_ENTRIES: ReadonlyArray<RegExp> = [
|
|
31
|
+
/^eslint\.config\.[cm]?[jt]s$/u,
|
|
32
|
+
/^tsconfig(?:\.[\w-]+)?\.json$/u,
|
|
33
|
+
]
|
|
34
|
+
const CONFIG_DIRECTORIES: ReadonlySet<string> = new Set(['eslint', 'tsconfig'])
|
|
35
|
+
// A test beside the rule modules configures nothing.
|
|
36
|
+
const TEST_MARKER = '.test.'
|
|
37
|
+
const SEPARATOR = '/'
|
|
38
|
+
const DIGEST_ALGORITHM = 'sha256'
|
|
39
|
+
|
|
40
|
+
// Code-unit order, so the digest does not depend on the locale of the machine that computes it.
|
|
41
|
+
function by_code_unit(left: string, right: string): number {
|
|
42
|
+
if (left === right) return 0
|
|
43
|
+
|
|
44
|
+
return left < right ? -1 : 1
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function to_posix(relative: string): string {
|
|
48
|
+
return relative.split(path.sep).join(SEPARATOR)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function is_config_entry(name: string): boolean {
|
|
52
|
+
return CONFIG_ENTRIES.some((entry) => entry.test(name))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function is_config_module(relative: string): boolean {
|
|
56
|
+
const [top = ''] = relative.split(SEPARATOR, 1)
|
|
57
|
+
|
|
58
|
+
return CONFIG_DIRECTORIES.has(top) && !path.basename(relative).includes(TEST_MARKER)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Whether the root-relative `relative` is a toolchain input.
|
|
62
|
+
function is_input(relative: string): boolean {
|
|
63
|
+
const posix = to_posix(relative)
|
|
64
|
+
if (PACKAGE_FILES.includes(posix)) return true
|
|
65
|
+
|
|
66
|
+
return is_config_entry(posix) || is_config_module(posix)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Files only: a directory moves on every entry created in it, an editor's temp file too.
|
|
70
|
+
function modules_under(root: string, directory: string): ReadonlyArray<string> {
|
|
71
|
+
const absolute = path.join(root, directory)
|
|
72
|
+
if (!existsSync(absolute)) return []
|
|
73
|
+
|
|
74
|
+
return readdirSync(absolute, { recursive: true, withFileTypes: true })
|
|
75
|
+
.filter((entry) => entry.isFile())
|
|
76
|
+
.map((entry) => to_posix(path.relative(root, path.join(entry.parentPath, entry.name))))
|
|
77
|
+
.filter((relative) => is_config_module(relative))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// The root-relative toolchain inputs present under `root`, in code-unit order.
|
|
81
|
+
function paths(root: string): ReadonlyArray<string> {
|
|
82
|
+
const present = PACKAGE_FILES.filter((relative) => existsSync(path.join(root, relative)))
|
|
83
|
+
const entries = readdirSync(root).filter((name) => is_config_entry(name))
|
|
84
|
+
const modules = [...CONFIG_DIRECTORIES].flatMap((directory) => modules_under(root, directory))
|
|
85
|
+
|
|
86
|
+
return [...present, ...entries, ...modules].toSorted(by_code_unit)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function read_or_empty(file: string): Uint8Array {
|
|
90
|
+
try {
|
|
91
|
+
return readFileSync(file)
|
|
92
|
+
} catch {
|
|
93
|
+
return new Uint8Array()
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// **The fingerprint of the toolchain under `root`**: each input's path and content, in code-unit
|
|
98
|
+
// order, so an added, removed, renamed or edited input changes it. A file gone between the listing
|
|
99
|
+
// and its read hashes as empty.
|
|
100
|
+
function digest(root: string): string {
|
|
101
|
+
const hash = createHash(DIGEST_ALGORITHM)
|
|
102
|
+
|
|
103
|
+
for (const relative of paths(root)) {
|
|
104
|
+
hash
|
|
105
|
+
.update(`${relative}\0`)
|
|
106
|
+
.update(read_or_empty(path.join(root, relative)))
|
|
107
|
+
.update('\0')
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return hash.digest('hex')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const toolchain_inputs = { digest, is_input, PACKAGE_FILES, paths }
|
|
114
|
+
|
|
115
|
+
export { toolchain_inputs }
|
|
@@ -9,7 +9,6 @@ import { review_stamps } from '#scripts/review/review-stamps'
|
|
|
9
9
|
import { review_tree } from '#scripts/review/review-tree'
|
|
10
10
|
import { unit_worker_share } from '#scripts/test/unit-worker-share'
|
|
11
11
|
import { check_reuse, type CheckRecords } from './check-reuse'
|
|
12
|
-
import { free_cores } from './free-cores'
|
|
13
12
|
import { gate_ledger, type GateLedgerStart } from './gate-ledger'
|
|
14
13
|
import { gate_plan, type GatePlan } from './gate-plan'
|
|
15
14
|
import { gate_report, type GateStepResult } from './gate-report'
|
|
@@ -165,21 +164,19 @@ async function run_marked_gate<T>(
|
|
|
165
164
|
// The concurrent-run count is read here rather than inside `gate-plan.ts` for the reason the core
|
|
166
165
|
// count already is: that module stays a pure function of its inputs, and the machine is asked once and
|
|
167
166
|
// handed to both calls. Counted *before* the unit step writes its own marker, so `+ 1` is this gate.
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
): GatePlan {
|
|
167
|
+
//
|
|
168
|
+
// **The free cores do not cap the plan** (joshuafolkken/kit#4167). The unit claim's admission narrows it
|
|
169
|
+
// to the room the outside load leaves, read over its wait rather than once at the gate's start — a
|
|
170
|
+
// width fixed off one busy instant held for the whole suite (`core_admission.is_too_narrow`).
|
|
171
|
+
function announce_gate_plan(is_unit_included: boolean, available_cores: number): GatePlan {
|
|
174
172
|
const concurrent_runs = unit_worker_share.live_run_count() + unit_worker_share.SOLO_RUNS
|
|
175
173
|
const is_kit_repository = project_checks.is_kit_repository(process.cwd())
|
|
176
|
-
const
|
|
174
|
+
const plan = gate_plan.resolve_gate_plan(
|
|
177
175
|
available_cores,
|
|
178
176
|
concurrent_runs,
|
|
179
177
|
is_unit_included,
|
|
180
178
|
is_kit_repository,
|
|
181
179
|
)
|
|
182
|
-
const plan = gate_plan.bound_by_free(resolved, available_cores, free)
|
|
183
180
|
|
|
184
181
|
process.stdout.write(`${gate_plan.format_gate_plan(plan, available_cores, concurrent_runs)}\n`)
|
|
185
182
|
|
|
@@ -217,10 +214,6 @@ interface GateOptions {
|
|
|
217
214
|
// Where each check's own green record lives (`check-reuse.ts`). Only the CLI entry resolves it, for
|
|
218
215
|
// the ledger's reason: a suite whose checks never ran must not record them green on the live tree.
|
|
219
216
|
check_records?: CheckRecords | undefined
|
|
220
|
-
// The cores free of load from outside the core budget's ledger (`free-cores.ts`). Only the CLI entry
|
|
221
|
-
// resolves it, for the ledger's reason: a suite driving the gate never reads the machine, so its plan
|
|
222
|
-
// does not depend on what else happened to be running.
|
|
223
|
-
read_free_cores?: ((available_cores: number) => Promise<number | undefined>) | undefined
|
|
224
217
|
}
|
|
225
218
|
|
|
226
219
|
// **Per-check records belong to the full local gate alone**: CI's `--no-unit` gate is the safety net
|
|
@@ -325,9 +318,7 @@ async function run_checked_gate(
|
|
|
325
318
|
// Resolved at the gate's entry, before this gate sets `JOSH_UNIT_RUN_MARKED`, so a gate nested in the
|
|
326
319
|
// unit suite reads the flag as set and reserves nothing.
|
|
327
320
|
const budget = gate_run_steps.default_budget()
|
|
328
|
-
|
|
329
|
-
const free = await options.read_free_cores?.(budget.available_cores)
|
|
330
|
-
const plan = announce_gate_plan(is_unit_included, budget.available_cores, free)
|
|
321
|
+
const plan = announce_gate_plan(is_unit_included, budget.available_cores)
|
|
331
322
|
const reused = await checks_to_reuse(plan, tree, options)
|
|
332
323
|
|
|
333
324
|
// **The gate holds the unit-run marker for its whole run, not just its unit step.** The step that
|
|
@@ -353,17 +344,30 @@ function reusable_stamp(tree: GateTree, options: GateOptions): FileMapStamp | un
|
|
|
353
344
|
return gate_skip.reusable_green_gate(tree.files, tree.base, options.stamp_path)
|
|
354
345
|
}
|
|
355
346
|
|
|
347
|
+
// The reuse leaves its line in the ledger too, so `josh lane:stats` counts the gates it saved
|
|
348
|
+
// (joshuafolkken/kit#4397).
|
|
349
|
+
async function reuse_gate(
|
|
350
|
+
stamp: FileMapStamp,
|
|
351
|
+
options: GateOptions,
|
|
352
|
+
started_at: number,
|
|
353
|
+
): Promise<number> {
|
|
354
|
+
process.stdout.write(`${gate_skip.format_skip(stamp.taken_at)}\n`)
|
|
355
|
+
await gate_ledger.record_reused(options.ledger_path, performance.now() - started_at)
|
|
356
|
+
|
|
357
|
+
return 0
|
|
358
|
+
}
|
|
359
|
+
|
|
356
360
|
// The two ways a gate ends before it runs a check: a green record it can reuse (exit 0), and the
|
|
357
361
|
// scoped pre-check refusing a tree the pair has not been green on (exit 1). `undefined` means neither
|
|
358
362
|
// fired and the checks run. **Nothing else stands between the skip and the checks.**
|
|
359
|
-
function short_circuit_gate(
|
|
363
|
+
async function short_circuit_gate(
|
|
364
|
+
tree: GateTree,
|
|
365
|
+
options: GateOptions,
|
|
366
|
+
started_at: number,
|
|
367
|
+
): Promise<number | undefined> {
|
|
360
368
|
const reusable = reusable_stamp(tree, options)
|
|
361
369
|
|
|
362
|
-
if (reusable !== undefined)
|
|
363
|
-
process.stdout.write(`${gate_skip.format_skip(reusable.taken_at)}\n`)
|
|
364
|
-
|
|
365
|
-
return 0
|
|
366
|
-
}
|
|
370
|
+
if (reusable !== undefined) return await reuse_gate(reusable, options, started_at)
|
|
367
371
|
|
|
368
372
|
const scoped_refusal = scoped_precheck_refusal(tree, options)
|
|
369
373
|
|
|
@@ -379,7 +383,7 @@ async function run_verification_gate(options: GateOptions = {}): Promise<number>
|
|
|
379
383
|
// four checks alone took — the gate's own bookkeeping is part of the wait either way.
|
|
380
384
|
const started_at = performance.now()
|
|
381
385
|
const tree = await gate_tree.read_gate_tree()
|
|
382
|
-
const short_circuit = short_circuit_gate(tree, options)
|
|
386
|
+
const short_circuit = await short_circuit_gate(tree, options, started_at)
|
|
383
387
|
|
|
384
388
|
if (short_circuit !== undefined) return short_circuit
|
|
385
389
|
|
|
@@ -438,7 +442,6 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
|
438
442
|
process.exitCode = await run_gate_command(process.argv.slice(FIRST_ARGUMENT_INDEX), {
|
|
439
443
|
ledger_path: await lane_ledger.target(),
|
|
440
444
|
check_records: check_reuse.DEFAULT_RECORDS,
|
|
441
|
-
read_free_cores: async (available_cores) => await free_cores.read({ available_cores }),
|
|
442
445
|
})
|
|
443
446
|
}
|
|
444
447
|
|