@joshuafolkken/kit 1.1514.0 → 1.1784.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -1
- package/.claude/settings.json +5 -5
- package/.claude/skills/epic-commands/SKILL.md +26 -65
- package/.claude/skills/epic-commands/epic-bundle.md +3 -1
- package/.claude/skills/workflow-commands/SKILL.md +5 -5
- package/.claude/skills/workflow-commands/background-commands.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
- package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +13 -7
- package/.claude/skills/workflow-commands/delegation.md +6 -5
- package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
- package/.claude/skills/workflow-commands/followup.md +9 -31
- package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
- package/.claude/skills/workflow-commands/fullrun.md +2 -2
- package/.claude/skills/workflow-commands/halfrun.md +17 -25
- package/.claude/skills/workflow-commands/issue-comments.md +16 -12
- package/.claude/skills/workflow-commands/issue-scout.md +2 -2
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +7 -12
- package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
- package/.claude/skills/workflow-commands/observation-filing.md +4 -36
- package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
- package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
- package/.claude/skills/workflow-commands/prerequisite.md +10 -16
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +3 -7
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +13 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-node/action.yml +9 -0
- package/.github/actions/setup-pnpm/action.yml +1 -1
- package/.github/dependabot.yml +16 -0
- package/.github/release.yml +0 -2
- package/.github/workflows/ci.yml +120 -10
- package/.github/workflows/publish.yml +8 -1
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +3 -7
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +3 -7
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
- package/dist/commands/read-set-cli.js +1867 -0
- package/dist/commands/run-prep-main.js +21653 -0
- package/dist/commands/run-step-cli.js +23880 -0
- package/dist/config-merge/index.js +5 -1
- package/dist/hooks/audit-provision.js +20 -35
- package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
- package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
- package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
- package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
- package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -22
- package/dist/hooks/format-edited.js +5 -6
- package/dist/hooks/inputs.json +443 -317
- package/dist/hooks/pretool-guard.js +7 -25
- package/dist/hooks/session-lang.js +44 -51
- package/dist/hooks/stop-guard.js +7716 -2187
- package/dist/josh.js +6002 -3583
- package/dist/self-sync-guard/index.js +74 -10
- package/dist/version/index.js +115 -406
- package/eslint/base.js +1 -1
- package/lefthook/base.yml +3 -1
- package/package.json +10 -48
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -7
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +33 -16
- package/prompts/collaboration-workflow/lane-instructions.md +1 -2
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +4 -6
- package/prompts/collaboration-workflow/output-bounds.md +2 -7
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +5 -0
- package/prompts/collaboration-workflow/report-format.md +31 -60
- package/prompts/collaboration-workflow/residency.md +2 -2
- package/prompts/collaboration-workflow/shell-body.md +6 -16
- package/prompts/collaboration-workflow/turn-batching.md +0 -2
- package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
- package/prompts/collaboration-workflow/wip-cap.md +1 -1
- package/prompts/collaboration-workflow.md +3 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +41 -21
- package/prompts/testing-guide.md +8 -43
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +14 -16
- package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
- package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
- package/scripts/auto-ok/auto-ok-judge.ts +13 -2
- package/scripts/auto-ok/auto-ok-main.ts +17 -0
- package/scripts/backlog/backlog-arrival.ts +14 -3
- package/scripts/backlog/backlog-budget-cli.ts +7 -33
- package/scripts/backlog/backlog-budget-main.ts +16 -0
- package/scripts/backlog/backlog-budget.ts +2 -3
- package/scripts/backlog/backlog-defect-priority.ts +4 -3
- package/scripts/backlog/backlog-drive-adopt.ts +67 -0
- package/scripts/backlog/backlog-drive-args.ts +4 -5
- package/scripts/backlog/backlog-drive-cli.ts +113 -28
- package/scripts/backlog/backlog-drive-hold.ts +162 -0
- package/scripts/backlog/backlog-drive-idle.ts +151 -0
- package/scripts/backlog/backlog-drive-judge.ts +25 -0
- package/scripts/backlog/backlog-drive-memory.ts +126 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
- package/scripts/backlog/backlog-drive-named.ts +53 -6
- package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
- package/scripts/backlog/backlog-drive-paused.ts +169 -0
- package/scripts/backlog/backlog-drive-restore.ts +30 -7
- package/scripts/backlog/backlog-drive-seats.ts +18 -8
- package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
- package/scripts/backlog/backlog-drive.ts +79 -75
- package/scripts/backlog/backlog-next-main.ts +16 -0
- package/scripts/backlog/backlog-next-shared.ts +73 -0
- package/scripts/backlog/backlog-next.ts +48 -16
- package/scripts/backlog/backlog-occupied.ts +52 -39
- package/scripts/backlog/backlog-offer-cli.ts +6 -21
- package/scripts/backlog/backlog-offer-exclude.ts +15 -0
- package/scripts/backlog/backlog-offer-main.ts +12 -0
- package/scripts/backlog/backlog-offer.ts +36 -3
- package/scripts/backlog/backlog-overlap.ts +22 -4
- package/scripts/backlog/backlog-plan-read.ts +6 -2
- package/scripts/backlog/backlog-plan.ts +18 -4
- package/scripts/backlog/backlog-pool.ts +10 -10
- package/scripts/backlog/backlog-rank.ts +10 -2
- package/scripts/backlog/backlog-ready.ts +112 -30
- package/scripts/backlog/backlog-stalled-detect.ts +109 -36
- package/scripts/backlog/backlog-stalled.ts +52 -16
- package/scripts/backlog/backlog-wait-cause.ts +86 -0
- package/scripts/backlog/backlog-waves.ts +39 -13
- package/scripts/backlog/backlogrun-args.ts +19 -7
- package/scripts/backlog/backlogrun-cli.ts +19 -5
- package/scripts/backlog/backlogrun-launch.ts +6 -0
- package/scripts/backlog/backlogrun-restart.ts +97 -0
- package/scripts/backlog/backlogrun-stop.ts +79 -7
- package/scripts/behavior/behavior-cli.ts +2 -2
- package/scripts/behavior/behavior-rules.ts +47 -24
- package/scripts/build/build-bin.ts +2 -16
- package/scripts/build/build-claude-md.ts +0 -7
- package/scripts/build/build-commands.ts +0 -13
- package/scripts/build/build-hooks.ts +49 -48
- package/scripts/build/hook-bundle-stamp.ts +29 -11
- package/scripts/build/local-bin.ts +1 -1
- package/scripts/cases/cases-cli.ts +25 -13
- package/scripts/cases/cases-interaction-scan.ts +134 -0
- package/scripts/cases/cases-interaction.ts +183 -0
- package/scripts/cases/cases-logic.ts +39 -6
- package/scripts/ci/pr-classification-main.ts +18 -0
- package/scripts/ci/pr-classification.ts +10 -17
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/cost-runtime/cost-blocks.ts +22 -37
- package/scripts/cost-runtime/cost-cli.ts +31 -14
- package/scripts/cost-runtime/cost-main.ts +12 -0
- package/scripts/cost-runtime/cost-transcript.ts +1 -0
- package/scripts/delegation/delegation-policy.ts +17 -4
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/investigation-guard.ts +0 -8
- package/scripts/delegation/investigation-reads.ts +3 -4
- package/scripts/dependabot/dependabot-cooldown.ts +194 -0
- package/scripts/discovery/repo-discovery.ts +24 -6
- package/scripts/doctor/doctor-consumer.ts +2 -5
- package/scripts/document/document-byte-budget.ts +8 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +0 -8
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-busy.ts +5 -12
- package/scripts/epic/epic-classify.ts +24 -15
- package/scripts/epic/epic-cli-argv.ts +31 -0
- package/scripts/epic/epic-cli-decide.ts +42 -0
- package/scripts/epic/epic-cli.ts +6 -38
- package/scripts/epic/epic-close.ts +112 -55
- package/scripts/epic/epic-cross-repo.ts +4 -7
- package/scripts/epic/epic-decide.ts +119 -0
- package/scripts/epic/epic-decision.ts +9 -0
- package/scripts/epic/epic-fetch.ts +4 -0
- package/scripts/epic/epic-graph.ts +2 -0
- package/scripts/epic/epic-issue.ts +5 -1
- package/scripts/epic/epic-label-age.ts +1 -1
- package/scripts/epic/epic-lane-offer.ts +39 -4
- package/scripts/epic/epic-next-main.ts +24 -0
- package/scripts/epic/epic-next.ts +6 -24
- package/scripts/epic/epic-outside-blocker.ts +6 -2
- package/scripts/epic/epic-parse.ts +9 -3
- package/scripts/epic/epic-read.ts +1 -0
- package/scripts/epic/epic-reconcile.ts +39 -0
- package/scripts/epic/epic-run.ts +10 -1
- package/scripts/epic/epic-solo.ts +50 -14
- package/scripts/epic/epic.ts +41 -7
- package/scripts/exports/unused-members-cli.ts +2 -2
- package/scripts/followup/followup-checks-event.ts +8 -3
- package/scripts/followup/followup-coderabbit-wait.ts +82 -0
- package/scripts/followup/followup-review-gates.ts +81 -0
- package/scripts/followup/git-followup-stages.ts +13 -3
- package/scripts/followup/git-followup-workflow.ts +19 -66
- package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
- package/scripts/followup/git-pr-followup.ts +36 -8
- package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
- package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
- package/scripts/gate/busy-average.ts +58 -0
- package/scripts/gate/check-cpu.ts +60 -0
- package/scripts/gate/check-inputs.ts +39 -95
- package/scripts/gate/check-reuse.ts +33 -54
- package/scripts/gate/command-memory.ts +192 -0
- package/scripts/gate/core-admission.ts +218 -28
- package/scripts/gate/core-budget-timing.ts +37 -0
- package/scripts/gate/core-budget.ts +80 -98
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +37 -5
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +27 -4
- package/scripts/gate/gate-ledger.ts +32 -4
- package/scripts/gate/gate-plan.ts +41 -34
- package/scripts/gate/gate-report.ts +14 -2
- package/scripts/gate/gate-run-steps.ts +53 -8
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +65 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/project-checks.ts +5 -12
- package/scripts/gate/scoped-green.ts +12 -8
- package/scripts/gate/since-green.ts +62 -0
- package/scripts/gate/toolchain-inputs.ts +115 -0
- package/scripts/gate/verification-gate.ts +27 -24
- package/scripts/gate/verification-inputs.ts +250 -0
- package/scripts/gh/gh-author-association.ts +96 -9
- package/scripts/gh/git-ai-review-scan.ts +4 -2
- package/scripts/gh/git-gh-api-path.ts +15 -0
- package/scripts/gh/git-gh-branch-rules.ts +73 -0
- package/scripts/gh/git-gh-conditional.ts +5 -2
- package/scripts/gh/git-gh-issue-read.ts +5 -1
- package/scripts/gh/git-gh-issue-write.ts +67 -29
- package/scripts/gh/git-gh-issue.ts +7 -3
- package/scripts/gh/git-gh-poll-read.ts +89 -0
- package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
- package/scripts/gh/git-gh-pr-rest.ts +1 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
- package/scripts/gh/git-gh-pr.ts +27 -15
- package/scripts/gh/git-pr-checks-eval.ts +39 -7
- package/scripts/gh/git-pr-checks-parse.ts +39 -9
- package/scripts/gh/git-pr-merge-checked.ts +80 -0
- package/scripts/git/base-tree.ts +19 -2
- package/scripts/git/changed-file-scope.ts +6 -4
- package/scripts/git/changed-paths.ts +18 -1
- package/scripts/git/git-diff-reads.ts +27 -2
- package/scripts/git/git-grep-hits.ts +85 -0
- package/scripts/git/git-location-environment.ts +1 -1
- package/scripts/git/git-merge-conflicts.ts +83 -0
- package/scripts/git/git-preflight.ts +37 -12
- package/scripts/git/git-push-transport.ts +1 -2
- package/scripts/git/git-schemas.ts +17 -7
- package/scripts/git/git-spawn.ts +1 -2
- package/scripts/git/git-status.ts +4 -4
- package/scripts/git/main-merge-main.ts +12 -0
- package/scripts/git/main-merge-regenerate.ts +2 -2
- package/scripts/git/main-merge.ts +25 -9
- package/scripts/git/main-sync-main.ts +12 -0
- package/scripts/git/main-sync.ts +0 -9
- package/scripts/git/stash/git-stash.ts +27 -4
- package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
- package/scripts/git/stash/stash-pop-cli.ts +6 -12
- package/scripts/git/stash/stash-pop-main.ts +12 -0
- package/scripts/git/stash/stash-push-cli.ts +76 -0
- package/scripts/git/stash/stash-push-main.ts +12 -0
- package/scripts/hooks/batch-guard.ts +0 -8
- package/scripts/hooks/check-commit-message-main.ts +8 -0
- package/scripts/hooks/check-commit-message.ts +4 -7
- package/scripts/hooks/format-edited-file.ts +8 -24
- package/scripts/hooks/pre-commit-lint.ts +30 -3
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +32 -19
- package/scripts/hooks/reserved-run.ts +67 -9
- package/scripts/hooks/run-hook.sh +13 -4
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +2 -21
- package/scripts/hooks/stop-guard.ts +13 -9
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -17
- package/scripts/init/init-actions.ts +0 -6
- package/scripts/init/init-ai-copy.ts +10 -36
- package/scripts/init/init-bootstrap.ts +9 -8
- package/scripts/init/init-dry-run-report.ts +1 -1
- package/scripts/init/init-dry-run.ts +1 -1
- package/scripts/init/init-file-action.ts +7 -9
- package/scripts/init/init-logic-json-merge.ts +2 -2
- package/scripts/init/init-logic-migrate.ts +9 -82
- package/scripts/init/init-logic.ts +3 -2
- package/scripts/init/init-main.ts +12 -0
- package/scripts/init/init.ts +5 -12
- package/scripts/init/kit-development-versions.ts +3 -7
- package/scripts/init/kit-written-paths.ts +2 -2
- package/scripts/init/project-profile.ts +5 -4
- package/scripts/init/tsconfig-preset-migration.ts +2 -1
- package/scripts/init/vscode-tasks.ts +1 -1
- package/scripts/issue/defect-origin-cli.ts +106 -0
- package/scripts/issue/defect-origin-line.ts +60 -0
- package/scripts/issue/defect-origin-main.ts +11 -0
- package/scripts/issue/defect-origin.ts +114 -0
- package/scripts/issue/defect-rate-cli.ts +34 -78
- package/scripts/issue/defect-rate.ts +0 -16
- package/scripts/issue/defect-report-cli.ts +128 -0
- package/scripts/issue/defect-report-format.ts +56 -0
- package/scripts/issue/defect-report-main.ts +11 -0
- package/scripts/issue/defect-report.ts +160 -0
- package/scripts/issue/expected-effect-lint.ts +1 -0
- package/scripts/issue/issue-already-done-cli.ts +62 -0
- package/scripts/issue/issue-body-or-comment.ts +40 -0
- package/scripts/issue/issue-cite-cli.ts +0 -9
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +12 -7
- package/scripts/issue/issue-comment-cli.ts +10 -24
- package/scripts/issue/issue-comment-main.ts +12 -0
- package/scripts/issue/issue-evidence-exit.ts +100 -0
- package/scripts/issue/issue-file-cli.ts +29 -7
- package/scripts/issue/issue-file.ts +19 -19
- package/scripts/issue/issue-fold-cli.ts +2 -11
- package/scripts/issue/issue-fold-main.ts +12 -0
- package/scripts/issue/issue-labels.ts +81 -90
- package/scripts/issue/issue-lint-cli.ts +2 -10
- package/scripts/issue/issue-lint-main.ts +12 -0
- package/scripts/issue/issue-measured-cli.ts +56 -0
- package/scripts/issue/issue-merged.ts +19 -2
- package/scripts/issue/issue-not-before-label.ts +135 -0
- package/scripts/issue/issue-not-before.ts +111 -0
- package/scripts/issue/issue-number-shape.ts +15 -1
- package/scripts/issue/issue-park.ts +28 -0
- package/scripts/issue/issue-plan-cli.ts +151 -0
- package/scripts/issue/issue-priority.ts +151 -0
- package/scripts/issue/issue-rank.ts +7 -1
- package/scripts/issue/issue-read-cli.ts +3 -10
- package/scripts/issue/issue-read-main.ts +12 -0
- package/scripts/issue/issue-read.ts +29 -5
- package/scripts/issue/issue-release-cli.ts +0 -10
- package/scripts/issue/issue-release-main.ts +13 -0
- package/scripts/issue/issue-release.ts +7 -12
- package/scripts/issue/issue-sample-gate.ts +192 -0
- package/scripts/issue/issue-sample-source.ts +76 -0
- package/scripts/issue/issue-scout-cli.ts +0 -11
- package/scripts/issue/issue-scout-main.ts +14 -0
- package/scripts/issue/issue-state-cli.ts +0 -10
- package/scripts/issue/issue-state-main.ts +12 -0
- package/scripts/issue/issue-watch-diff.ts +56 -15
- package/scripts/issue/issue-watch.ts +2 -1
- package/scripts/issue/issue-wip.ts +2 -7
- package/scripts/issue/measure-rerun-cli.ts +13 -8
- package/scripts/issue/plan-consumers-cli.ts +39 -0
- package/scripts/issue/plan-consumers-main.ts +11 -0
- package/scripts/issue/plan-consumers-section.ts +55 -0
- package/scripts/issue/plan-consumers.ts +127 -0
- package/scripts/josh/agent-session-environment.ts +1 -1
- package/scripts/josh/command-usage.ts +15 -43
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +12 -6
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +157 -158
- package/scripts/josh/josh-commands-backlog.ts +82 -16
- package/scripts/josh/josh-commands-clone.ts +1 -0
- package/scripts/josh/josh-commands-development.ts +111 -71
- package/scripts/josh/josh-commands-document.ts +43 -1
- package/scripts/josh/josh-commands-epic.ts +171 -0
- package/scripts/josh/josh-commands-hooks.ts +25 -2
- package/scripts/josh/josh-commands-issue-write.ts +181 -0
- package/scripts/josh/josh-commands-issue.ts +124 -24
- package/scripts/josh/josh-commands-lane.ts +103 -2
- package/scripts/josh/josh-commands-lint.ts +19 -8
- package/scripts/josh/josh-commands-maintenance.ts +112 -4
- package/scripts/josh/josh-commands-pause.ts +29 -0
- package/scripts/josh/josh-commands-progress.ts +87 -0
- package/scripts/josh/josh-commands-project.ts +138 -9
- package/scripts/josh/josh-commands-review.ts +124 -0
- package/scripts/josh/josh-commands-run.ts +211 -23
- package/scripts/josh/josh-commands-ship.ts +169 -0
- package/scripts/josh/josh-commands-split.ts +9 -0
- package/scripts/josh/josh-commands-versioning.ts +49 -2
- package/scripts/josh/josh-commands-workflow.ts +144 -6
- package/scripts/josh/josh-logic.ts +6 -13
- package/scripts/josh/package-directory.ts +2 -4
- package/scripts/josh/process-identity.ts +13 -4
- package/scripts/josh/session-language-cli.ts +4 -8
- package/scripts/josh/session-language-main.ts +13 -0
- package/scripts/josh/session-language.ts +6 -1
- package/scripts/josh/shared-cache.ts +90 -0
- package/scripts/josh/stamp-file.ts +9 -15
- package/scripts/lane/lane-await.ts +51 -12
- package/scripts/lane/lane-cache.ts +5 -30
- package/scripts/lane/lane-capacity.ts +14 -23
- package/scripts/lane/lane-check-stats.ts +62 -21
- package/scripts/lane/lane-child-invocation.ts +8 -0
- package/scripts/lane/lane-cli.ts +15 -5
- package/scripts/lane/lane-close.ts +86 -18
- package/scripts/lane/lane-core-wait-stats.ts +66 -0
- package/scripts/lane/lane-dispatch.ts +24 -3
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-handoff.ts +69 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +4 -11
- package/scripts/lane/lane-launch-cli.ts +0 -9
- package/scripts/lane/lane-launch-main.ts +12 -0
- package/scripts/lane/lane-ledger-schema.ts +266 -0
- package/scripts/lane/lane-ledger.ts +92 -123
- package/scripts/lane/lane-limit-cli.ts +12 -1
- package/scripts/lane/lane-measure-cli.ts +57 -11
- package/scripts/lane/lane-open.ts +9 -1
- package/scripts/lane/lane-parked.ts +3 -3
- package/scripts/lane/lane-pause-cli.ts +130 -0
- package/scripts/lane/lane-pause.ts +158 -0
- package/scripts/lane/lane-process-table.ts +166 -0
- package/scripts/lane/lane-reap-settle.ts +124 -0
- package/scripts/lane/lane-reap.ts +50 -15
- package/scripts/lane/lane-registry.ts +24 -3
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +22 -2
- package/scripts/lane/lane-round-two-stats.ts +49 -0
- package/scripts/lane/lane-sampler.ts +4 -0
- package/scripts/lane/lane-session-action.ts +19 -5
- package/scripts/lane/lane-session-broker.ts +102 -21
- package/scripts/lane/lane-snapshot-trace.ts +84 -0
- package/scripts/lane/lane-spans.ts +51 -0
- package/scripts/lane/lane-spent.ts +6 -3
- package/scripts/lane/lane-stage-stats.ts +7 -2
- package/scripts/lane/lane-state.ts +302 -0
- package/scripts/lane/lane-stats.ts +58 -4
- package/scripts/lane/lane-stop-stats.ts +113 -37
- package/scripts/lane/lane-test-related-stats.ts +127 -0
- package/scripts/lane/lane-transcript-calls.ts +145 -0
- package/scripts/lane/lane-transcript-stats.ts +168 -0
- package/scripts/lane/lane-vacant.ts +13 -3
- package/scripts/lane/lane-withdraw-cli.ts +5 -4
- package/scripts/lane/lane-withdraw.ts +50 -49
- package/scripts/lane/process-directories.ts +70 -0
- package/scripts/lane/process-lane-marks.ts +94 -0
- package/scripts/lib/atomic-write.ts +62 -0
- package/scripts/lib/buffered-process.ts +12 -5
- package/scripts/lib/cli-flags.ts +53 -0
- package/scripts/lib/figure-format.ts +63 -0
- package/scripts/lib/json-value.ts +9 -1
- package/scripts/lib/package-manifest.ts +35 -0
- package/scripts/lib/read-file.ts +3 -1
- package/scripts/lib/stamped-memo.ts +63 -0
- package/scripts/lib/stdout-on-stderr.ts +24 -0
- package/scripts/lib/timeouts.ts +9 -0
- package/scripts/lib/transcript-record.ts +91 -0
- package/scripts/lines/effective-limit.ts +1 -1
- package/scripts/lint/eslint-cache-dependencies.ts +145 -0
- package/scripts/lint/eslint-daemon.ts +265 -0
- package/scripts/lint/format.ts +11 -2
- package/scripts/lint/import-graph.ts +279 -0
- package/scripts/lint/lint-gate-scope.ts +102 -0
- package/scripts/lint/lint-parallel-main.ts +19 -0
- package/scripts/lint/lint-parallel.ts +62 -30
- package/scripts/lint/lint-related-scope.ts +30 -24
- package/scripts/lint/lint-related.ts +38 -6
- package/scripts/notify/confirmation-options.ts +1 -2
- package/scripts/notify/telegram-notify.ts +20 -20
- package/scripts/notify/telegram-test-logic.ts +0 -1
- package/scripts/notify/telegram-test-main.ts +8 -0
- package/scripts/notify/telegram-test.ts +2 -6
- package/scripts/observations/observation-ledger.ts +13 -0
- package/scripts/observations/observations-flush-landing.ts +5 -3
- package/scripts/observations/observations-flush.ts +6 -1
- package/scripts/overrides/overrides-check.ts +2 -5
- package/scripts/overrides/overrides-files.ts +2 -1
- package/scripts/overrides/overrides-logic.ts +3 -6
- package/scripts/package/verify-optional-eslint-install.ts +8 -6
- package/scripts/propagate/propagate-publish.ts +2 -7
- package/scripts/propagate/propagate-targets.ts +4 -12
- package/scripts/refactor/import-graph.ts +9 -7
- package/scripts/release/github-release-runs.ts +17 -6
- package/scripts/release/release-approval-prune.ts +18 -0
- package/scripts/release/release-history.ts +1 -3
- package/scripts/release/release-progress.ts +42 -22
- package/scripts/release/release-publish-run.ts +39 -0
- package/scripts/release/release-publish.ts +6 -6
- package/scripts/release/release-scope-cli.ts +0 -10
- package/scripts/release/release-scope-main.ts +12 -0
- package/scripts/repo/repo-setting.ts +3 -6
- package/scripts/repo/required-checks-logic.ts +6 -15
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-labels.ts +155 -0
- package/scripts/report/report-lint-cli.ts +3 -0
- package/scripts/report/report-lint.ts +85 -110
- package/scripts/report/report-template-cli.ts +59 -0
- package/scripts/report/report-template.ts +112 -0
- package/scripts/review/acceptance-map.ts +1 -0
- package/scripts/review/removed-tests-check.ts +86 -0
- package/scripts/review/removed-tests.ts +149 -0
- package/scripts/review/review-brief-cli.ts +81 -15
- package/scripts/review/review-brief-main.ts +12 -0
- package/scripts/review/review-brief.ts +31 -3
- package/scripts/review/review-code-tree.ts +10 -6
- package/scripts/review/review-comment-round.ts +26 -8
- package/scripts/review/review-finding-ledger.ts +30 -15
- package/scripts/review/review-interaction.ts +94 -0
- package/scripts/review/review-readers-scan.ts +163 -0
- package/scripts/review/review-record-cli.ts +69 -30
- package/scripts/review/review-record-main.ts +12 -0
- package/scripts/review/review-round-one-blobs.ts +221 -0
- package/scripts/review/review-round2-cli.ts +49 -12
- package/scripts/review/review-round2.ts +80 -12
- package/scripts/review/review-stamps.ts +19 -1
- package/scripts/review/review-stop-log.ts +96 -0
- package/scripts/review/review-stops-cli.ts +85 -0
- package/scripts/review/review-tree.ts +6 -17
- package/scripts/review/review-untouched-readers.ts +146 -0
- package/scripts/review/test-titles.ts +118 -0
- package/scripts/rules/agent-model.ts +8 -0
- package/scripts/rules/bash-triggers.ts +46 -3
- package/scripts/rules/decision-oracle-batch.ts +9 -1
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +80 -2
- package/scripts/rules/destructive-command.ts +8 -1
- package/scripts/rules/direct-filing.ts +10 -2
- package/scripts/rules/direct-issue-comment.ts +117 -0
- package/scripts/rules/direct-pr-create.ts +69 -3
- package/scripts/rules/early-heartbeat.ts +2 -1
- package/scripts/rules/file-body.ts +7 -0
- package/scripts/rules/filing-cap.ts +7 -0
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +4 -0
- package/scripts/rules/implementation-cut-verdict.ts +1 -1
- package/scripts/rules/implementation-cut.ts +11 -3
- package/scripts/rules/index-guard.ts +8 -1
- package/scripts/rules/issue-comments.ts +9 -1
- package/scripts/rules/josh-git-bare.ts +7 -0
- package/scripts/rules/lane-background.ts +67 -25
- package/scripts/rules/lane-carry-conflict.ts +6 -0
- package/scripts/rules/lane-direct-tool.ts +74 -0
- package/scripts/rules/lane-interactive-ask.ts +9 -2
- package/scripts/rules/lane-park.ts +45 -23
- package/scripts/rules/lane-split-park.ts +10 -2
- package/scripts/rules/lane-switch-main.ts +7 -0
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +1 -1
- package/scripts/rules/poll-loop.ts +7 -0
- package/scripts/rules/pr-merge.ts +123 -0
- package/scripts/rules/protected-files.ts +32 -5
- package/scripts/rules/raw-field-body.ts +6 -0
- package/scripts/rules/rule-body-guard.ts +8 -0
- package/scripts/rules/rule-list.ts +9 -28
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +1 -1
- package/scripts/rules/shell-segments.ts +35 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +3 -4
- package/scripts/rules/test-declared-commit.ts +11 -1
- package/scripts/rules/third-party-write.ts +7 -0
- package/scripts/rules/timed-rerun.ts +69 -0
- package/scripts/rules/worktree-guard.ts +13 -3
- package/scripts/run/board/run-board-app-name.ts +23 -0
- package/scripts/run/board/run-board-cli.ts +65 -32
- package/scripts/run/board/run-board-earlier.ts +94 -0
- package/scripts/run/board/run-board-ending-reason.ts +67 -0
- package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
- package/scripts/run/board/run-board-estimate.ts +98 -0
- package/scripts/run/board/run-board-fit.ts +153 -36
- package/scripts/run/board/run-board-fold.ts +123 -0
- package/scripts/run/board/run-board-fresh.ts +2 -2
- package/scripts/run/board/run-board-gather-live.ts +29 -0
- package/scripts/run/board/run-board-gather-thread.ts +189 -0
- package/scripts/run/board/run-board-gather-worker.ts +29 -0
- package/scripts/run/board/run-board-gather.ts +187 -0
- package/scripts/run/board/run-board-github.ts +118 -38
- package/scripts/run/board/run-board-header.ts +82 -20
- package/scripts/run/board/run-board-keys.ts +58 -0
- package/scripts/run/board/run-board-kind.ts +20 -6
- package/scripts/run/board/run-board-labels.ts +116 -71
- package/scripts/run/board/run-board-lane-state.ts +109 -0
- package/scripts/run/board/run-board-lane-time.ts +122 -0
- package/scripts/run/board/run-board-layout.ts +239 -60
- package/scripts/run/board/run-board-length.ts +52 -0
- package/scripts/run/board/run-board-machine.ts +8 -4
- package/scripts/run/board/run-board-main.ts +12 -0
- package/scripts/run/board/run-board-notes.ts +52 -31
- package/scripts/run/board/run-board-now.ts +1 -1
- package/scripts/run/board/run-board-operation.ts +15 -33
- package/scripts/run/board/run-board-phase.ts +1 -1
- package/scripts/run/board/run-board-plan-shared.ts +115 -0
- package/scripts/run/board/run-board-plan.ts +55 -3
- package/scripts/run/board/run-board-planning.ts +45 -0
- package/scripts/run/board/run-board-priority.ts +44 -0
- package/scripts/run/board/run-board-process-groups.ts +195 -0
- package/scripts/run/board/run-board-read.ts +151 -27
- package/scripts/run/board/run-board-reason.ts +235 -51
- package/scripts/run/board/run-board-released.ts +35 -0
- package/scripts/run/board/run-board-render-checks.ts +39 -5
- package/scripts/run/board/run-board-render-condition.ts +96 -0
- package/scripts/run/board/run-board-render-drawn.ts +67 -0
- package/scripts/run/board/run-board-render-foot.ts +59 -0
- package/scripts/run/board/run-board-render-icon.ts +35 -0
- package/scripts/run/board/run-board-render-lanes.ts +145 -0
- package/scripts/run/board/run-board-render-lead.ts +80 -0
- package/scripts/run/board/run-board-render-legend.ts +117 -48
- package/scripts/run/board/run-board-render-notes.ts +156 -29
- package/scripts/run/board/run-board-render-processes.ts +196 -0
- package/scripts/run/board/run-board-render-section.ts +119 -0
- package/scripts/run/board/run-board-render-slot.ts +3 -36
- package/scripts/run/board/run-board-render-tail.ts +115 -48
- package/scripts/run/board/run-board-render-time.ts +56 -0
- package/scripts/run/board/run-board-render-title.ts +117 -24
- package/scripts/run/board/run-board-render-waits.ts +104 -20
- package/scripts/run/board/run-board-render.ts +207 -265
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +9 -4
- package/scripts/run/board/run-board-setup.ts +1 -12
- package/scripts/run/board/run-board-snapshot.ts +111 -0
- package/scripts/run/board/run-board-spin.ts +2 -2
- package/scripts/run/board/run-board-state.ts +22 -33
- package/scripts/run/board/run-board-status.ts +147 -71
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +122 -107
- package/scripts/run/board/run-board-usage-board.ts +78 -0
- package/scripts/run/board/run-board-usage-lanes.ts +113 -0
- package/scripts/run/board/run-board-usage-listing.ts +93 -0
- package/scripts/run/board/run-board-usage-read.ts +120 -150
- package/scripts/run/board/run-board-usage-rusage.ts +19 -7
- package/scripts/run/board/run-board-usage-text.ts +139 -51
- package/scripts/run/board/run-board-usage-top.ts +102 -0
- package/scripts/run/board/run-board-usage.ts +89 -72
- package/scripts/run/board/run-board-usual.ts +20 -9
- package/scripts/run/carry/run-carry-args.ts +4 -7
- package/scripts/run/carry/run-carry-conversation.ts +1 -1
- package/scripts/run/carry/run-carry.ts +9 -4
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/event/run-event-cli.ts +1 -5
- package/scripts/run/event/run-event-filed.ts +12 -6
- package/scripts/run/event/run-event-follow.ts +2 -3
- package/scripts/run/event/run-event-render.ts +6 -10
- package/scripts/run/event/run-event-scope.ts +2 -2
- package/scripts/run/event/run-event-stream-emit.ts +82 -22
- package/scripts/run/event/run-event-stream.ts +34 -8
- package/scripts/run/hold/run-hold-adopt.ts +65 -0
- package/scripts/run/hold/run-hold-cli.ts +93 -22
- package/scripts/run/hold/run-hold-main.ts +12 -0
- package/scripts/run/hold/run-hold-member.ts +37 -0
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +62 -48
- package/scripts/run/merge/run-merge-close.ts +74 -0
- package/scripts/run/merge/run-merge-collect.ts +6 -13
- package/scripts/run/merge/run-merge-driver.ts +71 -0
- package/scripts/run/merge/run-merge-main.ts +12 -0
- package/scripts/run/merge/run-merge-outcome.ts +23 -0
- package/scripts/run/merge/run-merge-restart.ts +39 -0
- package/scripts/run/merge/run-merge-ship.ts +20 -4
- package/scripts/run/merge/run-merge-signals.ts +33 -9
- package/scripts/run/merge/run-merge-steps.ts +120 -85
- package/scripts/run/merge/run-merge.ts +38 -37
- package/scripts/run/park/run-park-cli.ts +91 -0
- package/scripts/run/park/run-park.ts +88 -0
- package/scripts/run/park/run-stalled.ts +68 -0
- package/scripts/run/pause/run-pause-cli.ts +73 -0
- package/scripts/run/pause/run-pause.ts +251 -0
- package/scripts/run/progress/run-progress-cli.ts +4 -12
- package/scripts/run/progress/run-progress-clock.ts +1 -1
- package/scripts/run/progress/run-progress-config.ts +6 -14
- package/scripts/run/progress/run-progress-main.ts +12 -0
- package/scripts/run/progress/run-progress.ts +1 -4
- package/scripts/run/review/run-review.ts +2 -1
- package/scripts/run/run-ending.ts +1 -0
- package/scripts/run/run-invocation.ts +5 -6
- package/scripts/run/run-liveness-cli.ts +6 -8
- package/scripts/run/run-liveness.ts +60 -29
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-preflight.ts +18 -3
- package/scripts/run/run-prep-cli.ts +1 -10
- package/scripts/run/run-prep-locate.ts +7 -50
- package/scripts/run/run-prep-main.ts +12 -0
- package/scripts/run/run-prep.ts +6 -0
- package/scripts/run/run-report-cli.ts +101 -13
- package/scripts/run/run-report-handoff.ts +114 -0
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +13 -0
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +1 -1
- package/scripts/run/ship/run-ship-args.ts +121 -0
- package/scripts/run/ship/run-ship-body-draft.ts +110 -0
- package/scripts/run/ship/run-ship-cli.ts +63 -140
- package/scripts/run/ship/run-ship-detach.ts +19 -8
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +18 -2
- package/scripts/run/ship/run-ship-overlap.ts +42 -5
- package/scripts/run/ship/run-ship-place.ts +96 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
- package/scripts/run/ship/run-ship-preflight.ts +137 -32
- package/scripts/run/ship/run-ship-probe.ts +11 -3
- package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
- package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
- package/scripts/run/ship/run-ship-return.ts +107 -23
- package/scripts/run/ship/run-ship-review-steps.ts +105 -151
- package/scripts/run/ship/run-ship-review.ts +73 -6
- package/scripts/run/ship/run-ship-reviewer.ts +207 -0
- package/scripts/run/ship/run-ship-stage.ts +55 -6
- package/scripts/run/ship/run-ship-steps.ts +46 -15
- package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +43 -6
- package/scripts/run/ship/run-ship.ts +30 -2
- package/scripts/run/tidy/run-tidy-cli.ts +0 -4
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
- package/scripts/run/tidy/run-tidy-main.ts +8 -0
- package/scripts/run/wake/run-wake-cli.ts +119 -100
- package/scripts/run/wake/run-wake-code.ts +83 -0
- package/scripts/run/wake/run-wake-driver.ts +19 -8
- package/scripts/run/wake/run-wake-loop.ts +34 -3
- package/scripts/run/wake/run-wake-main.ts +13 -0
- package/scripts/run/wake/run-wake-ports.ts +90 -0
- package/scripts/run/wake/run-wake-takeover.ts +66 -0
- package/scripts/run/wake/run-wake.ts +2 -1
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -1
- package/scripts/safe-chain/project-config.ts +3 -9
- package/scripts/security/security-audit-main.ts +8 -0
- package/scripts/security/security-audit-provision-logic.ts +0 -11
- package/scripts/security/security-audit-provision-main.ts +12 -0
- package/scripts/security/security-audit-provision.ts +11 -26
- package/scripts/security/security-audit.ts +6 -7
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
- package/scripts/split/split-assess-cli.ts +2 -2
- package/scripts/split/split-assess.ts +15 -0
- package/scripts/split/split-measure.ts +65 -0
- package/scripts/sync/claude-settings-merge.ts +8 -15
- package/scripts/sync/directory-copy-guard.ts +4 -9
- package/scripts/sync/file-content.ts +78 -8
- package/scripts/sync/sync-ai-files.ts +3 -5
- package/scripts/sync/sync-configs.ts +11 -23
- package/scripts/sync/sync-hook-safety.ts +4 -10
- package/scripts/sync/sync-main.ts +11 -0
- package/scripts/sync/sync.ts +25 -37
- package/scripts/test/test-declared-changed.ts +2 -2
- package/scripts/test/test-declared.ts +1 -1
- package/scripts/test/test-e2e-guard.ts +25 -1
- package/scripts/test/test-e2e-stamp.ts +38 -0
- package/scripts/test/test-pinned-logic.ts +145 -0
- package/scripts/test/test-pinned-main.ts +78 -0
- package/scripts/test/test-pinned.ts +100 -0
- package/scripts/test/test-read-map.ts +264 -0
- package/scripts/test/test-read-recording.ts +91 -0
- package/scripts/test/test-read-trace.ts +148 -0
- package/scripts/test/test-red-main.ts +12 -0
- package/scripts/test/test-red.ts +12 -30
- package/scripts/test/test-related-main.ts +18 -0
- package/scripts/test/test-related-record.ts +119 -0
- package/scripts/test/test-related-scope.ts +229 -43
- package/scripts/test/test-related.ts +300 -22
- package/scripts/test/test-unit-guard-main.ts +15 -0
- package/scripts/test/test-unit-guard.ts +42 -24
- package/scripts/test/unit-count-file.ts +37 -0
- package/scripts/test/unit-run-marker.ts +162 -0
- package/scripts/test/unit-setup-files.ts +51 -0
- package/scripts/test/unit-worker-share.ts +61 -149
- package/scripts/test/whole-suite-files.ts +63 -0
- package/scripts/time-runtime/time-background.ts +20 -2
- package/scripts/time-runtime/time-bundles.ts +4 -3
- package/scripts/time-runtime/time-density-hook.ts +8 -6
- package/scripts/time-runtime/time-followup-stage.ts +1 -3
- package/scripts/time-runtime/time-format.ts +5 -28
- package/scripts/time-runtime/time-markers.ts +10 -1
- package/scripts/time-runtime/time-shell.ts +97 -10
- package/scripts/time-runtime/time-transcript-line.ts +49 -62
- package/scripts/uninstall/uninstall.ts +1 -1
- package/scripts/version/bump-version-main.ts +12 -0
- package/scripts/version/bump-version.ts +25 -25
- package/scripts/version/effective-upstream.ts +6 -12
- package/scripts/version/latest-corepack.ts +17 -32
- package/scripts/version/latest-if-required-cli.ts +93 -0
- package/scripts/version/latest-lane-guard-main.ts +8 -0
- package/scripts/version/latest-lane-guard.ts +0 -4
- package/scripts/version/latest-scope-cli.ts +0 -9
- package/scripts/version/latest-scope-main.ts +12 -0
- package/scripts/version/latest-update.ts +5 -5
- package/scripts/version/npm-registry.ts +44 -6
- package/scripts/version/publishable-range-check.ts +5 -16
- package/scripts/version/release-age.ts +1 -1
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/release-window.ts +38 -0
- package/scripts/version/running-binary.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +3 -8
- package/scripts/version/version-targets.ts +6 -28
- package/templates/dependabot.yml +29 -0
- package/templates/gitignore +4 -1
- package/templates/pnpm-workspace.basic.yaml +1 -1
- package/templates/sonar-project.properties +3 -2
- package/templates/workflows/ci.yml +12 -4
- package/templates/workflows/github-release.yml +4 -0
- package/tsconfig.sonar.json +1 -1
- package/.ncurc.json +0 -3
- package/dist/hooks/batch-guard.js +0 -29
- package/dist/hooks/chunk-4KKD2UTK.js +0 -66
- package/dist/hooks/chunk-6TS2JD6D.js +0 -237
- package/dist/hooks/chunk-7DSBJVFH.js +0 -50
- package/dist/hooks/chunk-A65Y4YOR.js +0 -79
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EFXE6C37.js +0 -81
- package/dist/hooks/chunk-GP4IEC4O.js +0 -20
- package/dist/hooks/chunk-JP45SOCJ.js +0 -56
- package/dist/hooks/chunk-LAOV7NLM.js +0 -45
- package/dist/hooks/chunk-M4HGZV7U.js +0 -83
- package/dist/hooks/chunk-PF2NZL2A.js +0 -131
- package/dist/hooks/chunk-PTICX4OL.js +0 -358
- package/dist/hooks/chunk-RT27QRJW.js +0 -6247
- package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
- package/dist/hooks/chunk-UPUZF3AN.js +0 -279
- package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -29
- package/scripts/backlog/backlog-stalled-cli.ts +0 -30
- package/scripts/cost-runtime/cost-format.ts +0 -29
- package/scripts/init/basic-path-migration.ts +0 -24
- package/scripts/issue/issue-backlinks-cli.ts +0 -93
- package/scripts/josh/josh-commands-guard.ts +0 -38
- package/scripts/josh/josh-usage-automation.ts +0 -121
- package/scripts/josh/josh-usage-backlog.ts +0 -180
- package/scripts/josh/josh-usage-developer.ts +0 -230
- package/scripts/josh/josh-usage-hooks.ts +0 -38
- package/scripts/josh/josh-usage-issue.ts +0 -205
- package/scripts/josh/josh-usage-review.ts +0 -101
- package/scripts/josh/josh-usage-run.ts +0 -252
- package/scripts/josh/josh-usage-session.ts +0 -238
- package/scripts/josh/josh-usage-workflow.ts +0 -212
- package/scripts/lint/cross-file-recheck.ts +0 -155
- package/scripts/registry-migration/migrate-logic.ts +0 -237
- package/scripts/registry-migration/migrate.ts +0 -292
- package/scripts/registry-migration/user-npmrc.ts +0 -15
- package/scripts/rules/rule-guard.ts +0 -23
- package/scripts/rules/rule-registry-rows.ts +0 -292
- package/scripts/rules/rule-registry.ts +0 -112
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { readdirSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { repository_lock } from '#scripts/git/repository-lock'
|
|
4
|
+
import { session_cite } from '#scripts/issue/session-cite'
|
|
5
|
+
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
6
|
+
import { figure_format } from '#scripts/lib/figure-format'
|
|
7
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
8
|
+
import { run_carry } from '#scripts/run/carry/run-carry'
|
|
9
|
+
import { z } from 'zod'
|
|
10
|
+
|
|
11
|
+
// One record per lane of where it is in its life — opened, running, paused, ended — written only by
|
|
12
|
+
// the lane commands (joshuafolkken/kit#4268), so a reader asks the record rather than guessing from
|
|
13
|
+
// the `.env` mtime, the event stream or the `ps` state.
|
|
14
|
+
//
|
|
15
|
+
// **It is a `stamp_path` keyed on the common git directory**, beside the carry record and the event
|
|
16
|
+
// stream and outside every work tree, so it is the same file from the main checkout and from inside
|
|
17
|
+
// the lane, it outlives `lane:close`'s removal of the lane, and `JOSH_TEMP_ROOT` moves it with every
|
|
18
|
+
// other record the run keeps.
|
|
19
|
+
//
|
|
20
|
+
// **The write is `stamp_file.replace_stamp`'s** — a temporary file beside the target, renamed over it —
|
|
21
|
+
// so two commands writing the same lane at once leave one whole record, never a torn one. **The read,
|
|
22
|
+
// the transition check and that write are one step under a per-record lock**, as the event stream's
|
|
23
|
+
// append is: unlocked, a pause that read `running` could rename its `paused` over a merge's `ended`.
|
|
24
|
+
//
|
|
25
|
+
// **A transition the lifecycle does not have is not written** (an `ended` lane is not paused); it is
|
|
26
|
+
// warned about and the command carries on, as it does when the record cannot be written at all — the
|
|
27
|
+
// record never fails the command that keeps it.
|
|
28
|
+
|
|
29
|
+
const STATE_PREFIX = 'josh-lane-state-'
|
|
30
|
+
const STATE_SUFFIX = '.json'
|
|
31
|
+
const LOCK_SUFFIX = '.lock'
|
|
32
|
+
// A change holds the lock for one read and one rename; a wait this long means a holder is stuck.
|
|
33
|
+
const LOCK_WAIT_MS = 5000
|
|
34
|
+
const LANE_STATES = ['open', 'running', 'paused', 'ended'] as const
|
|
35
|
+
// What a lane with no record is answered with: its state is unknown, so it keeps its place.
|
|
36
|
+
const NO_STATE_HINT = 'no lane state — counted in use'
|
|
37
|
+
|
|
38
|
+
type LaneState = (typeof LANE_STATES)[number]
|
|
39
|
+
|
|
40
|
+
const lane_run_schema = z.object({ started_at: z.string(), owner_pid: z.number().optional() })
|
|
41
|
+
|
|
42
|
+
// A process the last `lane:close` could not end even with a SIGKILL, and why (`lane-reap-settle.ts`).
|
|
43
|
+
const stuck_schema = z.object({ pid: z.number(), reason: z.string() })
|
|
44
|
+
|
|
45
|
+
const lane_state_schema = z.object({
|
|
46
|
+
issue: z.string(),
|
|
47
|
+
run: lane_run_schema.optional(),
|
|
48
|
+
state: z.enum(LANE_STATES),
|
|
49
|
+
launched_at: z.string().optional(),
|
|
50
|
+
changed_at: z.string(),
|
|
51
|
+
changed_by: z.string(),
|
|
52
|
+
stuck: z.array(stuck_schema).optional(),
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
type LaneRun = z.infer<typeof lane_run_schema>
|
|
56
|
+
type LaneStateRecord = z.infer<typeof lane_state_schema>
|
|
57
|
+
type StuckProcess = z.infer<typeof stuck_schema>
|
|
58
|
+
// Each lane's record, by issue; a lane with none is left out (`read_states`).
|
|
59
|
+
type LaneRecords = ReadonlyMap<string, LaneStateRecord>
|
|
60
|
+
|
|
61
|
+
// The states each one moves to. A lane with no record yet (opened before the record existed) moves to
|
|
62
|
+
// any of them.
|
|
63
|
+
const TRANSITIONS: Record<LaneState, ReadonlyArray<LaneState>> = {
|
|
64
|
+
open: ['open', 'running', 'ended'],
|
|
65
|
+
running: ['running', 'paused', 'ended'],
|
|
66
|
+
paused: ['paused', 'running', 'ended'],
|
|
67
|
+
ended: ['ended', 'open'],
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// One command's change: the state it leaves the lane in, and whether it launched a child — a launch
|
|
71
|
+
// stamps the launch time and the run that launched it, which every other change keeps.
|
|
72
|
+
interface LaneChange {
|
|
73
|
+
issue: string
|
|
74
|
+
state: LaneState
|
|
75
|
+
command: string
|
|
76
|
+
is_launch?: boolean
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface StateOptions {
|
|
80
|
+
directory?: string | undefined
|
|
81
|
+
now?: Date
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
type RecordOutcome =
|
|
85
|
+
{ kind: 'written'; record: LaneStateRecord } | { kind: 'skipped'; reason: string }
|
|
86
|
+
|
|
87
|
+
function state_path(directory: string, issue: string): string {
|
|
88
|
+
return stamp_file.stamp_path(STATE_PREFIX, directory, `-${issue}${STATE_SUFFIX}`)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function is_allowed(from: LaneState | undefined, to: LaneState): boolean {
|
|
92
|
+
return from === undefined || TRANSITIONS[from].includes(to)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function read_record(directory: string, issue: string): LaneStateRecord | undefined {
|
|
96
|
+
const raw = stamp_file.read_stamp_text(state_path(directory, issue))
|
|
97
|
+
|
|
98
|
+
return raw === undefined ? undefined : json_value.parse_with(raw, lane_state_schema)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function write_record(directory: string, record: LaneStateRecord): void {
|
|
102
|
+
stamp_file.replace_stamp(state_path(directory, record.issue), record)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// The run a launch belongs to: the carry's start and owner, read from the same common git directory.
|
|
106
|
+
function current_run(directory: string): LaneRun | undefined {
|
|
107
|
+
const carried = run_carry.read_carry(run_carry.carry_path(directory))
|
|
108
|
+
|
|
109
|
+
if (carried.kind !== 'carried') return undefined
|
|
110
|
+
|
|
111
|
+
return { started_at: carried.carry.started_at, owner_pid: carried.carry.owner_pid }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function launch_fields(change: LaneChange, directory: string, now: Date): Partial<LaneStateRecord> {
|
|
115
|
+
if (change.is_launch !== true) return {}
|
|
116
|
+
|
|
117
|
+
return { run: current_run(directory), launched_at: now.toISOString() }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function next_record(
|
|
121
|
+
change: LaneChange,
|
|
122
|
+
previous: LaneStateRecord | undefined,
|
|
123
|
+
directory: string,
|
|
124
|
+
now: Date,
|
|
125
|
+
): LaneStateRecord {
|
|
126
|
+
return {
|
|
127
|
+
// An open starts a fresh life: a reopened lane keeps nothing of the run that launched it before.
|
|
128
|
+
...(change.state !== 'open' && previous),
|
|
129
|
+
issue: change.issue,
|
|
130
|
+
state: change.state,
|
|
131
|
+
changed_at: now.toISOString(),
|
|
132
|
+
changed_by: change.command,
|
|
133
|
+
...launch_fields(change, directory, now),
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function apply_held(change: LaneChange, directory: string, now: Date): RecordOutcome {
|
|
138
|
+
const previous = read_record(directory, change.issue)
|
|
139
|
+
|
|
140
|
+
if (!is_allowed(previous?.state, change.state)) {
|
|
141
|
+
return { kind: 'skipped', reason: `no ${previous?.state ?? ''} → ${change.state} transition` }
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const record = next_record(change, previous, directory, now)
|
|
145
|
+
|
|
146
|
+
write_record(directory, record)
|
|
147
|
+
|
|
148
|
+
return { kind: 'written', record }
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const NO_DIRECTORY: RecordOutcome = { kind: 'skipped', reason: 'no git directory' }
|
|
152
|
+
|
|
153
|
+
// The read, the check and the write of one record, under its lock.
|
|
154
|
+
function locked(directory: string, issue: string, held: () => RecordOutcome): RecordOutcome {
|
|
155
|
+
const lock = `${state_path(directory, issue)}${LOCK_SUFFIX}`
|
|
156
|
+
const outcome = repository_lock.with_lock_sync(held, lock, LOCK_WAIT_MS)
|
|
157
|
+
|
|
158
|
+
return outcome ?? { kind: 'skipped', reason: `gave up waiting for the lock at ${lock}` }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function apply(change: LaneChange, directory: string, now: Date): RecordOutcome {
|
|
162
|
+
return locked(directory, change.issue, () => apply_held(change, directory, now))
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function warn(change: LaneChange, reason: string): void {
|
|
166
|
+
console.warn(
|
|
167
|
+
`${change.command} ${session_cite.issue(change.issue)}: lane state not recorded — ${reason}`,
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function resolve_directory(directory: string | undefined): Promise<string | undefined> {
|
|
172
|
+
return directory ?? (await run_carry.repository_directory())
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function outcome_of(change: LaneChange, options: StateOptions): Promise<RecordOutcome> {
|
|
176
|
+
const directory = await resolve_directory(options.directory)
|
|
177
|
+
|
|
178
|
+
if (directory === undefined) return NO_DIRECTORY
|
|
179
|
+
|
|
180
|
+
return apply(change, directory, options.now ?? new Date())
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function settled_outcome(change: LaneChange, options: StateOptions): Promise<RecordOutcome> {
|
|
184
|
+
try {
|
|
185
|
+
return await outcome_of(change, options)
|
|
186
|
+
} catch (error: unknown) {
|
|
187
|
+
return { kind: 'skipped', reason: error instanceof Error ? error.message : String(error) }
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function record_change(
|
|
192
|
+
change: LaneChange,
|
|
193
|
+
options: StateOptions = {},
|
|
194
|
+
): Promise<RecordOutcome> {
|
|
195
|
+
const outcome = await settled_outcome(change, options)
|
|
196
|
+
|
|
197
|
+
if (outcome.kind === 'skipped') warn(change, outcome.reason)
|
|
198
|
+
|
|
199
|
+
return outcome
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async function read_state(issue: string, directory?: string): Promise<LaneStateRecord | undefined> {
|
|
203
|
+
const root = await resolve_directory(directory)
|
|
204
|
+
|
|
205
|
+
return root === undefined ? undefined : read_record(root, issue)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// The issue each record of `directory` is for, read off the file names `state_path` writes.
|
|
209
|
+
function recorded_issues(directory: string): Array<string> {
|
|
210
|
+
const empty = state_path(directory, '')
|
|
211
|
+
const head = path.basename(empty).slice(0, -STATE_SUFFIX.length)
|
|
212
|
+
|
|
213
|
+
return readdirSync(path.dirname(empty))
|
|
214
|
+
.filter((name) => name.startsWith(head) && name.endsWith(STATE_SUFFIX))
|
|
215
|
+
.map((name) => name.slice(head.length, -STATE_SUFFIX.length))
|
|
216
|
+
.filter((issue) => issue.length > 0)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Every lane's record, a closed lane's included — the record outlives the work tree. */
|
|
220
|
+
async function read_records(directory?: string): Promise<Array<LaneStateRecord>> {
|
|
221
|
+
const root = await resolve_directory(directory)
|
|
222
|
+
|
|
223
|
+
if (root === undefined) return []
|
|
224
|
+
|
|
225
|
+
const records = recorded_issues(root).map((issue) => read_record(root, issue))
|
|
226
|
+
|
|
227
|
+
return records.filter((record) => record !== undefined)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function stuck_held(issue: string, stuck: Array<StuckProcess>, directory: string): RecordOutcome {
|
|
231
|
+
const previous = read_record(directory, issue)
|
|
232
|
+
|
|
233
|
+
if (previous === undefined) return { kind: 'skipped', reason: 'no record' }
|
|
234
|
+
|
|
235
|
+
const record = { ...previous, stuck }
|
|
236
|
+
|
|
237
|
+
write_record(directory, record)
|
|
238
|
+
|
|
239
|
+
return { kind: 'written', record }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Note on the lane's record the processes its close could not end, leaving its state as it is: a lane
|
|
244
|
+
* a close has not finished is not `ended`. A lane with no record is not given one.
|
|
245
|
+
*/
|
|
246
|
+
async function record_stuck(
|
|
247
|
+
issue: string,
|
|
248
|
+
stuck: Array<StuckProcess>,
|
|
249
|
+
directory?: string,
|
|
250
|
+
): Promise<RecordOutcome> {
|
|
251
|
+
const root = await resolve_directory(directory)
|
|
252
|
+
|
|
253
|
+
if (root === undefined) return NO_DIRECTORY
|
|
254
|
+
|
|
255
|
+
return locked(root, issue, () => stuck_held(issue, stuck, root))
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** Each of `issues`' records, by issue; an issue with none is left out. */
|
|
259
|
+
async function read_states(
|
|
260
|
+
issues: ReadonlyArray<string>,
|
|
261
|
+
directory?: string,
|
|
262
|
+
): Promise<LaneRecords> {
|
|
263
|
+
const root = await resolve_directory(directory)
|
|
264
|
+
|
|
265
|
+
if (root === undefined) return new Map()
|
|
266
|
+
|
|
267
|
+
const read = issues.map((issue): [string, LaneStateRecord | undefined] => [
|
|
268
|
+
issue,
|
|
269
|
+
read_record(root, issue),
|
|
270
|
+
])
|
|
271
|
+
|
|
272
|
+
return new Map(read.filter((entry): entry is [string, LaneStateRecord] => entry[1] !== undefined))
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** `paused since 01:28 by lane:pause` — the one wording every reader names a paused lane in. */
|
|
276
|
+
function paused_text(since_ms: number, changed_by: string): string {
|
|
277
|
+
return `paused since ${figure_format.minute_of(since_ms)} by ${changed_by}`
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** `paused_text` for a paused record, `undefined` for any other. */
|
|
281
|
+
function paused_note(record: LaneStateRecord | undefined): string | undefined {
|
|
282
|
+
if (record?.state !== 'paused') return undefined
|
|
283
|
+
|
|
284
|
+
return paused_text(Date.parse(record.changed_at), record.changed_by)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const lane_state = {
|
|
288
|
+
LANE_STATES,
|
|
289
|
+
NO_STATE_HINT,
|
|
290
|
+
is_allowed,
|
|
291
|
+
paused_note,
|
|
292
|
+
paused_text,
|
|
293
|
+
read_records,
|
|
294
|
+
read_state,
|
|
295
|
+
read_states,
|
|
296
|
+
record_change,
|
|
297
|
+
record_stuck,
|
|
298
|
+
state_path,
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export { lane_state }
|
|
302
|
+
export type { LaneChange, LaneRecords, LaneState, LaneStateRecord, RecordOutcome, StuckProcess }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { machine_capacity } from '#scripts/gate/machine-capacity'
|
|
2
|
-
import
|
|
2
|
+
import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
|
|
3
|
+
import type { DispatchEntry, GateEntry, LedgerEntry, LoadEntry, MergeEntry } from './lane-ledger'
|
|
3
4
|
import { lane_sampler } from './lane-sampler'
|
|
4
5
|
|
|
5
6
|
// The lane-limit measurement's one table row: the ledger entries of one period
|
|
@@ -21,7 +22,6 @@ import { lane_sampler } from './lane-sampler'
|
|
|
21
22
|
// **Swap is a rate, not a level.** A sample carries `machine_capacity`'s counter — every page swapped
|
|
22
23
|
// since boot — so the swap columns are what was swapped between consecutive samples, per hour.
|
|
23
24
|
|
|
24
|
-
const MS_PER_MINUTE = 60_000
|
|
25
25
|
const MS_PER_HOUR = 3_600_000
|
|
26
26
|
// A busy lane pool finishes a gate well within this; a longer silence is time nobody was running work.
|
|
27
27
|
const ACTIVE_GAP_MS = MS_PER_HOUR
|
|
@@ -40,6 +40,7 @@ const COLUMNS = [
|
|
|
40
40
|
'merges',
|
|
41
41
|
'merges / hour',
|
|
42
42
|
'effective lanes',
|
|
43
|
+
'lane median (min)',
|
|
43
44
|
'gate median (min)',
|
|
44
45
|
'gate max (min)',
|
|
45
46
|
'load peak',
|
|
@@ -65,7 +66,10 @@ function window_of(period_days: number, now_ms: number): StatsWindow {
|
|
|
65
66
|
return { since_ms: now_ms - period_days * MS_PER_DAY, until_ms: now_ms }
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
function in_window
|
|
69
|
+
function in_window<T extends { at: string }>(
|
|
70
|
+
entries: ReadonlyArray<T>,
|
|
71
|
+
window: StatsWindow,
|
|
72
|
+
): Array<T> {
|
|
69
73
|
return entries.filter((entry) => {
|
|
70
74
|
const at = Date.parse(entry.at)
|
|
71
75
|
|
|
@@ -77,6 +81,14 @@ function is_gate(entry: LedgerEntry): entry is GateEntry {
|
|
|
77
81
|
return entry.kind === 'gate'
|
|
78
82
|
}
|
|
79
83
|
|
|
84
|
+
function is_merge(entry: LedgerEntry): entry is MergeEntry {
|
|
85
|
+
return entry.kind === 'merge'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function is_dispatch(entry: LedgerEntry): entry is DispatchEntry {
|
|
89
|
+
return entry.kind === 'dispatch'
|
|
90
|
+
}
|
|
91
|
+
|
|
80
92
|
function is_load(entry: LedgerEntry): entry is LoadEntry {
|
|
81
93
|
return entry.kind === 'load'
|
|
82
94
|
}
|
|
@@ -200,8 +212,49 @@ function throughput_cells(entries: ReadonlyArray<LedgerEntry>): Array<string> {
|
|
|
200
212
|
return [String(merges), cell(per_hour), cell(mean(lanes))]
|
|
201
213
|
}
|
|
202
214
|
|
|
215
|
+
function dispatched_before(
|
|
216
|
+
dispatches: ReadonlyArray<DispatchEntry>,
|
|
217
|
+
merge: MergeEntry,
|
|
218
|
+
): number | undefined {
|
|
219
|
+
const merged_at = Date.parse(merge.at)
|
|
220
|
+
const starts = dispatches
|
|
221
|
+
.filter((dispatch) => dispatch.issue === merge.issue)
|
|
222
|
+
.map((dispatch) => Date.parse(dispatch.at))
|
|
223
|
+
.filter((at) => at <= merged_at)
|
|
224
|
+
|
|
225
|
+
return peak(starts)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function lane_minutes(
|
|
229
|
+
dispatches: ReadonlyArray<DispatchEntry>,
|
|
230
|
+
merge: MergeEntry,
|
|
231
|
+
): number | undefined {
|
|
232
|
+
const start = dispatched_before(dispatches, merge)
|
|
233
|
+
|
|
234
|
+
return start === undefined ? undefined : (Date.parse(merge.at) - start) / MS_PER_MINUTE
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// One merge's lane time runs from the latest dispatch of its issue — looked up in the whole ledger,
|
|
238
|
+
// since a lane may start before the window — to the merge. A merge no dispatch preceded is skipped.
|
|
239
|
+
function lane_cell(
|
|
240
|
+
entries: ReadonlyArray<LedgerEntry>,
|
|
241
|
+
period: ReadonlyArray<LedgerEntry>,
|
|
242
|
+
): string {
|
|
243
|
+
const dispatches = entries.filter(is_dispatch)
|
|
244
|
+
const minutes = period
|
|
245
|
+
.filter((entry) => is_merge(entry))
|
|
246
|
+
.map((merge) => lane_minutes(dispatches, merge))
|
|
247
|
+
.filter(is_number)
|
|
248
|
+
|
|
249
|
+
return cell(median(minutes))
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// A reused gate ran no check, so its few milliseconds would pull the median toward a gate that never ran.
|
|
203
253
|
function gate_cells(entries: ReadonlyArray<LedgerEntry>): Array<string> {
|
|
204
|
-
const minutes = entries
|
|
254
|
+
const minutes = entries
|
|
255
|
+
.filter(is_gate)
|
|
256
|
+
.filter((entry) => entry.is_reused !== true)
|
|
257
|
+
.map((entry) => entry.elapsed_ms / MS_PER_MINUTE)
|
|
205
258
|
|
|
206
259
|
return [cell(median(minutes)), cell(peak(minutes))]
|
|
207
260
|
}
|
|
@@ -248,6 +301,7 @@ function row(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow, label: Ro
|
|
|
248
301
|
label.limit,
|
|
249
302
|
String(label.period_days),
|
|
250
303
|
...throughput_cells(period),
|
|
304
|
+
lane_cell(entries, period),
|
|
251
305
|
...gate_cells(period),
|
|
252
306
|
...load_cells(period.filter(is_load)),
|
|
253
307
|
])
|
|
@@ -1,20 +1,29 @@
|
|
|
1
|
+
import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
|
|
1
2
|
import { run_ship_stage } from '#scripts/run/ship/run-ship-stage'
|
|
2
3
|
import { lane_ledger, type LedgerEntry, type StopEntry } from './lane-ledger'
|
|
4
|
+
import type { IssueAt } from './lane-spans'
|
|
3
5
|
import { lane_stage_stats } from './lane-stage-stats'
|
|
4
6
|
import { lane_stats, type StatsWindow } from './lane-stats'
|
|
5
7
|
|
|
6
8
|
// How long a lane stood stopped: the ledger's `stop` entries of one period reduced to one row per stop
|
|
7
|
-
// reason — median, maximum, how many
|
|
8
|
-
// `josh lane:stats` under the per-stage table, so the stop reason worth removing next is a number.
|
|
9
|
+
// reason — the wait's median, maximum and total, how many waits ended and how many never did — printed
|
|
10
|
+
// by `josh lane:stats` under the per-stage table, so the stop reason worth removing next is a number.
|
|
9
11
|
//
|
|
10
|
-
// **The wait is derived, not recorded**: from a stop to
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
// resumption of a stop that may be days old.
|
|
12
|
+
// **The wait is derived, not recorded**: from a stop to whichever comes first of the same issue's next
|
|
13
|
+
// ship stage (the lane resumed), its re-dispatch (a fresh lane took it over) and its park on the run's
|
|
14
|
+
// event stream (the run gave up on it) — the time the stop held the issue (joshuafolkken/kit#3997). A
|
|
15
|
+
// stop none of the three followed is counted under `not resumed` and kept out of the median, the
|
|
16
|
+
// maximum and the total, whose time has no end.
|
|
16
17
|
|
|
17
|
-
const COLUMNS = [
|
|
18
|
+
const COLUMNS = [
|
|
19
|
+
'stop',
|
|
20
|
+
'wait median (min)',
|
|
21
|
+
'wait max (min)',
|
|
22
|
+
'wait total (min)',
|
|
23
|
+
'runs',
|
|
24
|
+
'not resumed',
|
|
25
|
+
'causes',
|
|
26
|
+
] as const
|
|
18
27
|
const { STAGE } = run_ship_stage
|
|
19
28
|
const { is_dispatch, is_number, is_stage } = lane_stage_stats
|
|
20
29
|
const REASONS = [
|
|
@@ -28,9 +37,19 @@ const REASONS = [
|
|
|
28
37
|
STAGE.FOLLOWUP,
|
|
29
38
|
STAGE.REPORT,
|
|
30
39
|
] as const
|
|
40
|
+
// `#<N> parked`, `#<N> parked (<reason>)`, `#<N> waiting on #<M>`, `#<N> cut (<phase>)` and
|
|
41
|
+
// `#<N> resumed` name their issue first.
|
|
42
|
+
const EVENT_ISSUE = /#([1-9]\d*)\b/u
|
|
43
|
+
|
|
44
|
+
// A stop recorded before it carried a cause (joshuafolkken/kit#3998) is counted under this one.
|
|
45
|
+
const UNRECORDED_CAUSE = 'unrecorded'
|
|
46
|
+
const NO_CAUSES = '-'
|
|
31
47
|
|
|
48
|
+
// `causes` is a preflight stop's unmet preconditions or a review stop's blocking finding kinds, every
|
|
49
|
+
// one of them, else the stop's one cause.
|
|
32
50
|
interface StopWait {
|
|
33
51
|
reason: string
|
|
52
|
+
causes: ReadonlyArray<string>
|
|
34
53
|
wait_ms: number | undefined
|
|
35
54
|
}
|
|
36
55
|
|
|
@@ -38,51 +57,108 @@ function is_stop(entry: LedgerEntry): entry is StopEntry {
|
|
|
38
57
|
return entry.kind === lane_ledger.KIND.STOP
|
|
39
58
|
}
|
|
40
59
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
// Every run event of `kind`, with the issue its text names first.
|
|
61
|
+
function events_of(events: ReadonlyArray<RunEvent>, kind: string): Array<IssueAt> {
|
|
62
|
+
return events
|
|
63
|
+
.filter((event) => event.kind === kind)
|
|
64
|
+
.map((event) => ({
|
|
65
|
+
issue: Number(EVENT_ISSUE.exec(event.text)?.[1]),
|
|
66
|
+
at_ms: Date.parse(event.at),
|
|
67
|
+
}))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function parks_of(events: ReadonlyArray<RunEvent>): Array<IssueAt> {
|
|
71
|
+
return events_of(events, run_event_stream.EVENT_KIND.PARK)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function ends_of(
|
|
75
|
+
entries: ReadonlyArray<LedgerEntry>,
|
|
76
|
+
parks: ReadonlyArray<IssueAt>,
|
|
77
|
+
): Array<IssueAt> {
|
|
78
|
+
const resumes = entries
|
|
79
|
+
.filter((entry) => is_stage(entry))
|
|
80
|
+
.map((stage) => ({ issue: stage.issue, at_ms: lane_stage_stats.started_ms(stage) }))
|
|
81
|
+
const dispatches = entries
|
|
44
82
|
.filter((entry) => is_dispatch(entry))
|
|
45
|
-
.
|
|
46
|
-
.map((entry) => Date.parse(entry.at))
|
|
47
|
-
.filter((at) => at > from_ms)
|
|
83
|
+
.map((entry) => ({ issue: entry.issue, at_ms: Date.parse(entry.at) }))
|
|
48
84
|
|
|
49
|
-
return
|
|
85
|
+
return [...resumes, ...dispatches, ...parks]
|
|
50
86
|
}
|
|
51
87
|
|
|
52
|
-
|
|
88
|
+
// A stage's start counts from the stop's own instant, so a ship relaunched within the same
|
|
89
|
+
// millisecond still ends the wait; the stage that stopped started before it.
|
|
90
|
+
function wait_ms(stop: StopEntry, ends: ReadonlyArray<IssueAt>): number | undefined {
|
|
53
91
|
const from_ms = Date.parse(stop.at)
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
.
|
|
57
|
-
.filter((stage) => stage.issue === stop.issue)
|
|
58
|
-
.map((stage) => lane_stage_stats.started_ms(stage))
|
|
59
|
-
.filter((start) => start >= from_ms && start < until_ms)
|
|
92
|
+
const later = ends
|
|
93
|
+
.filter((end) => end.issue === stop.issue && end.at_ms >= from_ms)
|
|
94
|
+
.map((end) => end.at_ms - from_ms)
|
|
60
95
|
|
|
61
|
-
return
|
|
96
|
+
return later.length === 0 ? undefined : Math.min(...later)
|
|
62
97
|
}
|
|
63
98
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
99
|
+
// A stop recorded before it named its preconditions (joshuafolkken/kit#4166) or its finding kinds
|
|
100
|
+
// (joshuafolkken/kit#4426) counts under its cause.
|
|
101
|
+
function causes_of(stop: StopEntry): ReadonlyArray<string> {
|
|
102
|
+
const { preconditions = [], findings = [] } = stop
|
|
103
|
+
const kinds = [...preconditions, ...findings]
|
|
104
|
+
|
|
105
|
+
return kinds.length > 0 ? kinds : [stop.cause ?? UNRECORDED_CAUSE]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function waits_of(
|
|
109
|
+
entries: ReadonlyArray<LedgerEntry>,
|
|
110
|
+
ends: ReadonlyArray<IssueAt>,
|
|
111
|
+
): Array<StopWait> {
|
|
112
|
+
return entries.filter(is_stop).map((stop) => ({
|
|
113
|
+
reason: stop.reason,
|
|
114
|
+
causes: causes_of(stop),
|
|
115
|
+
wait_ms: wait_ms(stop, ends),
|
|
116
|
+
}))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function total(values: ReadonlyArray<number>): number | undefined {
|
|
120
|
+
return values.length === 0 ? undefined : values.reduce((sum, value) => sum + value, 0)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// `infra 2, check 1` — how many of one reason's stops each cause took, the most frequent first. A stop
|
|
124
|
+
// with two unmet preconditions counts once under each.
|
|
125
|
+
function causes_cell(waits: ReadonlyArray<StopWait>): string {
|
|
126
|
+
const all = waits.flatMap((wait) => wait.causes)
|
|
127
|
+
const counted = [...new Set(all)].map((cause) => ({
|
|
128
|
+
cause,
|
|
129
|
+
count: all.filter((each) => each === cause).length,
|
|
130
|
+
}))
|
|
131
|
+
const ranked = counted.toSorted((left, right) => right.count - left.count)
|
|
132
|
+
|
|
133
|
+
return ranked.length === 0
|
|
134
|
+
? NO_CAUSES
|
|
135
|
+
: ranked.map(({ cause, count }) => `${cause} ${String(count)}`).join(', ')
|
|
68
136
|
}
|
|
69
137
|
|
|
70
138
|
function reason_row(reason: string, waits: ReadonlyArray<StopWait>): string {
|
|
71
139
|
const of_reason = waits.filter((wait) => wait.reason === reason)
|
|
72
|
-
const
|
|
140
|
+
const ended = of_reason.map((wait) => wait.wait_ms).filter((value) => is_number(value))
|
|
73
141
|
|
|
74
142
|
return lane_stats.to_row([
|
|
75
143
|
reason,
|
|
76
|
-
lane_stage_stats.cell(lane_stats.median(
|
|
77
|
-
lane_stage_stats.cell(lane_stats.peak(
|
|
78
|
-
|
|
79
|
-
String(
|
|
144
|
+
lane_stage_stats.cell(lane_stats.median(ended)),
|
|
145
|
+
lane_stage_stats.cell(lane_stats.peak(ended)),
|
|
146
|
+
lane_stage_stats.cell(total(ended)),
|
|
147
|
+
String(ended.length),
|
|
148
|
+
String(of_reason.length - ended.length),
|
|
149
|
+
causes_cell(of_reason),
|
|
80
150
|
])
|
|
81
151
|
}
|
|
82
152
|
|
|
83
|
-
// The period's table: `entries` is the whole ledger, filtered here to `window
|
|
84
|
-
|
|
85
|
-
|
|
153
|
+
// The period's table: `entries` is the whole ledger, filtered here to `window` — only the stops are; a
|
|
154
|
+
// wait may end after the period's last stop. `events` is the run's event stream, read for its parks.
|
|
155
|
+
function table(
|
|
156
|
+
entries: ReadonlyArray<LedgerEntry>,
|
|
157
|
+
window: StatsWindow,
|
|
158
|
+
events: ReadonlyArray<RunEvent> = [],
|
|
159
|
+
): string {
|
|
160
|
+
const ends = ends_of(entries, parks_of(events))
|
|
161
|
+
const waits = waits_of(lane_stats.in_window(entries, window), ends)
|
|
86
162
|
|
|
87
163
|
return [
|
|
88
164
|
lane_stats.to_row(COLUMNS),
|
|
@@ -91,6 +167,6 @@ function table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string
|
|
|
91
167
|
].join('\n')
|
|
92
168
|
}
|
|
93
169
|
|
|
94
|
-
const lane_stop_stats = { REASONS, table }
|
|
170
|
+
const lane_stop_stats = { REASONS, events_of, table }
|
|
95
171
|
|
|
96
172
|
export { lane_stop_stats }
|