@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,15 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { setInterval as every } from 'node:timers/promises'
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { cost_transcript } from '#scripts/cost-runtime/cost-transcript'
|
|
4
5
|
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
6
|
+
import { MS_PER_SECOND } from '#scripts/lib/timeouts'
|
|
7
|
+
import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
|
|
8
|
+
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
5
9
|
import { lane_capacity } from './lane-capacity'
|
|
6
10
|
import { lane_check_stats } from './lane-check-stats'
|
|
11
|
+
import { lane_core_wait_stats } from './lane-core-wait-stats'
|
|
12
|
+
import { lane_gap_stats } from './lane-gap-stats'
|
|
13
|
+
import { lane_held_stats } from './lane-held-stats'
|
|
7
14
|
import { lane_ledger } from './lane-ledger'
|
|
8
15
|
import { lane_process_stats } from './lane-process-stats'
|
|
16
|
+
import { lane_round_two_stats } from './lane-round-two-stats'
|
|
9
17
|
import { lane_sampler, type MeasureContext } from './lane-sampler'
|
|
10
18
|
import { lane_stage_stats } from './lane-stage-stats'
|
|
11
|
-
import { lane_stats } from './lane-stats'
|
|
19
|
+
import { lane_stats, type StatsWindow } from './lane-stats'
|
|
12
20
|
import { lane_stop_stats } from './lane-stop-stats'
|
|
21
|
+
import { lane_test_related_stats } from './lane-test-related-stats'
|
|
22
|
+
import type { ToolCall } from './lane-transcript-calls'
|
|
23
|
+
import { lane_transcript_stats } from './lane-transcript-stats'
|
|
13
24
|
|
|
14
25
|
// `josh lane:sample` / `josh lane:stats` — the lane-limit measurement.
|
|
15
26
|
//
|
|
@@ -23,7 +34,6 @@ import { lane_stop_stats } from './lane-stop-stats'
|
|
|
23
34
|
|
|
24
35
|
const ARGV_OFFSET = 2
|
|
25
36
|
const FAILURE_EXIT_CODE = 1
|
|
26
|
-
const MS_PER_SECOND = 1000
|
|
27
37
|
const SAMPLE_VERB = 'sample'
|
|
28
38
|
const STATS_VERB = 'stats'
|
|
29
39
|
const USAGE = [
|
|
@@ -102,6 +112,45 @@ async function read_ledger(
|
|
|
102
112
|
return path === undefined ? [] : lane_ledger.read_entries(path)
|
|
103
113
|
}
|
|
104
114
|
|
|
115
|
+
// The run's event stream, read for the parks that end a stop's wait.
|
|
116
|
+
async function read_events(context: MeasureContext): Promise<ReadonlyArray<RunEvent>> {
|
|
117
|
+
if (context.events_path !== undefined) return run_event_stream.read_events(context.events_path)
|
|
118
|
+
|
|
119
|
+
return await run_event_stream_emit.all_events()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Every lane's transcript directory under this checkout's lane root, read from a lane or the main checkout.
|
|
123
|
+
function transcript_directories(context: MeasureContext): ReadonlyArray<string> {
|
|
124
|
+
if (context.transcript_directories !== undefined) return context.transcript_directories
|
|
125
|
+
|
|
126
|
+
const main_cwd = cost_transcript.session_cwd(process.cwd())
|
|
127
|
+
|
|
128
|
+
return cost_transcript.lane_transcript_directories(main_cwd, cost_transcript.home_directory())
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface PeriodRecords {
|
|
132
|
+
entries: ReturnType<typeof lane_ledger.read_entries>
|
|
133
|
+
events: ReadonlyArray<RunEvent>
|
|
134
|
+
calls: ReadonlyArray<ToolCall>
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// The tables under the period's row, in the order `lane:stats` prints them.
|
|
138
|
+
function tables_of({ entries, events, calls }: PeriodRecords, window: StatsWindow): Array<string> {
|
|
139
|
+
return [
|
|
140
|
+
lane_stage_stats.table(entries, window),
|
|
141
|
+
lane_stop_stats.table(entries, window, events),
|
|
142
|
+
lane_gap_stats.table(entries, window, events),
|
|
143
|
+
lane_round_two_stats.table(entries, window),
|
|
144
|
+
lane_held_stats.table(entries, window),
|
|
145
|
+
lane_core_wait_stats.table(entries, window),
|
|
146
|
+
lane_process_stats.table(entries, window),
|
|
147
|
+
lane_check_stats.table(entries, window),
|
|
148
|
+
lane_test_related_stats.table(entries, window),
|
|
149
|
+
lane_test_related_stats.trigger_table(entries, window),
|
|
150
|
+
lane_transcript_stats.table(calls, window),
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
|
|
105
154
|
async function stats_command(
|
|
106
155
|
rest: ReadonlyArray<string>,
|
|
107
156
|
context: MeasureContext,
|
|
@@ -115,16 +164,13 @@ async function stats_command(
|
|
|
115
164
|
const label = { limit: await limit_label(values.limit), period_days }
|
|
116
165
|
const entries = await read_ledger(context)
|
|
117
166
|
const row = lane_stats.row(entries, window, label)
|
|
167
|
+
const records = {
|
|
168
|
+
entries,
|
|
169
|
+
events: await read_events(context),
|
|
170
|
+
calls: lane_transcript_stats.read_calls(transcript_directories(context), window),
|
|
171
|
+
}
|
|
118
172
|
|
|
119
|
-
console.info(
|
|
120
|
-
[
|
|
121
|
-
`${lane_stats.header()}\n${row}`,
|
|
122
|
-
lane_stage_stats.table(entries, window),
|
|
123
|
-
lane_stop_stats.table(entries, window),
|
|
124
|
-
lane_process_stats.table(entries, window),
|
|
125
|
-
lane_check_stats.table(entries, window),
|
|
126
|
-
].join('\n\n'),
|
|
127
|
-
)
|
|
173
|
+
console.info([`${lane_stats.header()}\n${row}`, ...tables_of(records, window)].join('\n\n'))
|
|
128
174
|
|
|
129
175
|
return 0
|
|
130
176
|
}
|
|
@@ -13,6 +13,7 @@ import { lane_paths } from './lane-paths'
|
|
|
13
13
|
import { lane_registry, type LaneInfo } from './lane-registry'
|
|
14
14
|
import { lane_seed_policy } from './lane-seed'
|
|
15
15
|
import { lane_start_point } from './lane-start-point'
|
|
16
|
+
import { lane_state } from './lane-state'
|
|
16
17
|
|
|
17
18
|
// Opening a lane: one linked work tree, one branch, one port seed, and the dependencies to run in it.
|
|
18
19
|
//
|
|
@@ -256,6 +257,13 @@ async function clear_the_way(
|
|
|
256
257
|
await lane_leftover.reclaim(lane_paths.lane_directory(root, issue))
|
|
257
258
|
}
|
|
258
259
|
|
|
260
|
+
// The lane's state record starts here, so no lane opened from now on is without one.
|
|
261
|
+
async function opened(lane: LaneInfo): Promise<OpenOutcome> {
|
|
262
|
+
await lane_state.record_change({ issue: lane.issue, state: 'open', command: 'lane:open' })
|
|
263
|
+
|
|
264
|
+
return { kind: 'opened', lane }
|
|
265
|
+
}
|
|
266
|
+
|
|
259
267
|
/**
|
|
260
268
|
* Open the lane for `issue`, or say why it was not opened.
|
|
261
269
|
*
|
|
@@ -283,7 +291,7 @@ async function open_lane(issue: string): Promise<OpenOutcome> {
|
|
|
283
291
|
|
|
284
292
|
await materialize(plan, repository_root)
|
|
285
293
|
|
|
286
|
-
return
|
|
294
|
+
return await opened(plan.lane)
|
|
287
295
|
}
|
|
288
296
|
|
|
289
297
|
const lane_open = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { has_parked_label } from '#scripts/issue/issue-labels'
|
|
2
2
|
import { issue_state_cli } from '#scripts/issue/issue-state-cli'
|
|
3
3
|
|
|
4
|
-
// Whether an issue is parked for a person —
|
|
4
|
+
// Whether an issue is parked for a person — any park label (`PARKED_LABELS`) — read live, so a session a
|
|
5
5
|
// lane's broker would start for it is refused once the run has parked it (joshuafolkken/kit#3878).
|
|
6
6
|
//
|
|
7
7
|
// **An issue whose state cannot be read is not parked**: the read gates every brokered review, so
|
|
@@ -10,7 +10,7 @@ import { issue_state_cli } from '#scripts/issue/issue-state-cli'
|
|
|
10
10
|
async function is_parked(issue: string): Promise<boolean> {
|
|
11
11
|
const read = await issue_state_cli.read_issue(issue)
|
|
12
12
|
|
|
13
|
-
return read.kind === 'state' &&
|
|
13
|
+
return read.kind === 'state' && has_parked_label(read.state.labels)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const lane_parked = { is_parked }
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
4
|
+
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
5
|
+
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
6
|
+
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
7
|
+
import { lane_pause, type LaneSignalled } from './lane-pause'
|
|
8
|
+
import type { LaneProcesses } from './lane-reap'
|
|
9
|
+
import { lane_registry } from './lane-registry'
|
|
10
|
+
import { lane_state } from './lane-state'
|
|
11
|
+
|
|
12
|
+
// `josh lane:pause <issue> | --all` and `josh lane:resume <issue> | --all` — one script told apart by
|
|
13
|
+
// the verb the registry passes first. A named lane with no child process to signal exits non-zero, so a
|
|
14
|
+
// caller never takes a pause that stopped nothing as done — a detached resident signalled alone counts
|
|
15
|
+
// as nothing. A lane whose detached processes could not be read exits non-zero too, since a resume
|
|
16
|
+
// may have left one of them stopped. A lane whose child was signalled has the change written to its state record and to the
|
|
17
|
+
// run's event stream, so who halted it is on record.
|
|
18
|
+
|
|
19
|
+
const ARGV_OFFSET = 2
|
|
20
|
+
const SUCCESS_EXIT_CODE = 0
|
|
21
|
+
const FAILURE_EXIT_CODE = 1
|
|
22
|
+
const ALL_FLAG = '--all'
|
|
23
|
+
const USAGE = [
|
|
24
|
+
'Usage: josh lane:pause <issue-number> | josh lane:pause --all',
|
|
25
|
+
' josh lane:resume <issue-number> | josh lane:resume --all',
|
|
26
|
+
].join('\n')
|
|
27
|
+
|
|
28
|
+
const VERBS = {
|
|
29
|
+
pause: { act: 'pause_lane', done: 'paused', state: 'paused' },
|
|
30
|
+
resume: { act: 'resume_lane', done: 'resumed', state: 'running' },
|
|
31
|
+
} as const
|
|
32
|
+
|
|
33
|
+
type Verb = keyof typeof VERBS
|
|
34
|
+
|
|
35
|
+
function is_verb(value: string | undefined): value is Verb {
|
|
36
|
+
return value === 'pause' || value === 'resume'
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function lanes_of(target: ReadonlyArray<string>): Promise<Array<LaneProcesses> | undefined> {
|
|
40
|
+
const [issue, ...rest] = target
|
|
41
|
+
|
|
42
|
+
if (issue === undefined || rest.length > 0) return undefined
|
|
43
|
+
if (issue === ALL_FLAG) return await lane_pause.open_lanes()
|
|
44
|
+
if (!issue_number_shape.is_issue_number(issue)) return undefined
|
|
45
|
+
|
|
46
|
+
return [await lane_registry.lane_location(issue)]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function outcome_of(verb: Verb, result: LaneSignalled): string {
|
|
50
|
+
const { done } = VERBS[verb]
|
|
51
|
+
const count = String(result.signalled.length)
|
|
52
|
+
|
|
53
|
+
if (result.signalled.length === 0) return `no child process running — nothing ${done}`
|
|
54
|
+
|
|
55
|
+
if (result.child.length === 0) {
|
|
56
|
+
return `no child process running — ${done} ${count} detached process(es), state unchanged`
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return `${done} ${count} process(es)`
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const UNREAD_NOTE =
|
|
63
|
+
' — could not read the detached processes (lsof or ps failed); any of them was missed'
|
|
64
|
+
|
|
65
|
+
// One line per lane: how many of its processes were signalled, and whether its residents went unread.
|
|
66
|
+
function report(verb: Verb, issue: string, result: LaneSignalled): void {
|
|
67
|
+
const note = result.is_unread ? UNREAD_NOTE : ''
|
|
68
|
+
|
|
69
|
+
console.info(`lane:${verb} ${issue_cite.plain(issue)}: ${outcome_of(verb, result)}${note}`)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function record(verb: Verb, issue: string): Promise<void> {
|
|
73
|
+
const command = `lane:${verb}`
|
|
74
|
+
|
|
75
|
+
await lane_state.record_change({ issue, state: VERBS[verb].state, command })
|
|
76
|
+
await run_event_stream_emit.emit(
|
|
77
|
+
run_event_stream.EVENT_KIND.LANE_STATE,
|
|
78
|
+
`${issue_cite.plain(issue)} ${VERBS[verb].done} by ${command}`,
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function settle(verb: Verb, lane: LaneProcesses): Promise<LaneSignalled> {
|
|
83
|
+
const result = lane_pause[VERBS[verb].act](lane)
|
|
84
|
+
|
|
85
|
+
report(verb, lane.issue, result)
|
|
86
|
+
if (result.child.length > 0) await record(verb, lane.issue)
|
|
87
|
+
|
|
88
|
+
return result
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// A named lane with no child signalled fails; any lane whose residents went unread fails.
|
|
92
|
+
function is_failed(result: LaneSignalled, is_named: boolean): boolean {
|
|
93
|
+
return result.is_unread || (is_named && result.child.length === 0)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function apply(
|
|
97
|
+
verb: Verb,
|
|
98
|
+
lanes: ReadonlyArray<LaneProcesses>,
|
|
99
|
+
is_named: boolean,
|
|
100
|
+
): Promise<number> {
|
|
101
|
+
const results = await Promise.all(lanes.map(async (lane) => await settle(verb, lane)))
|
|
102
|
+
|
|
103
|
+
return results.some((result) => is_failed(result, is_named))
|
|
104
|
+
? FAILURE_EXIT_CODE
|
|
105
|
+
: SUCCESS_EXIT_CODE
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function report_usage(): number {
|
|
109
|
+
console.error(USAGE)
|
|
110
|
+
|
|
111
|
+
return FAILURE_EXIT_CODE
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
115
|
+
const [verb, ...target] = argv
|
|
116
|
+
if (!is_verb(verb)) return report_usage()
|
|
117
|
+
const lanes = await lanes_of(target)
|
|
118
|
+
|
|
119
|
+
return lanes === undefined ? report_usage() : await apply(verb, lanes, target[0] !== ALL_FLAG)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
123
|
+
process.exitCode = await run(argv)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const lane_pause_cli = { run }
|
|
127
|
+
|
|
128
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
129
|
+
|
|
130
|
+
export { lane_pause_cli }
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { lane_reap, type LaneProcesses, type ReapProbes } from './lane-reap'
|
|
2
|
+
import { lane_registry } from './lane-registry'
|
|
3
|
+
import { lane_residents } from './lane-residents'
|
|
4
|
+
|
|
5
|
+
// Suspending a lane child in place, and letting it carry on from the same point.
|
|
6
|
+
//
|
|
7
|
+
// **Nothing but the processes is touched here.** The work tree, the branch and the issue stay as they
|
|
8
|
+
// are, so a paused lane is resumed rather than rebuilt — the one way to halt a lane that `lane:close`
|
|
9
|
+
// (which deletes it) and `lane:withdraw` (which takes its issue out of the run) are not. The command
|
|
10
|
+
// (`lane-pause-cli.ts`) records the change in the lane's state and on the run's event stream.
|
|
11
|
+
//
|
|
12
|
+
// **The tree is `lane_reap`'s** — the same match, the same descendants, the caller's own ancestry
|
|
13
|
+
// spared — so a pause and a reap never disagree on which processes are the lane's.
|
|
14
|
+
//
|
|
15
|
+
// **A pause reads the tree again until no new process turns up.** A parent signalled after it had
|
|
16
|
+
// already forked leaves a child that was not in the first read running; each round stops what the
|
|
17
|
+
// last one did not see, up to `PAUSE_ROUNDS`.
|
|
18
|
+
//
|
|
19
|
+
// **A process detached from the tree is stopped and continued with it** (joshuafolkken/kit#4300): the
|
|
20
|
+
// edit hook's `eslint_d`, a detached `ship`, found by its working directory or mark as `lane:close`
|
|
21
|
+
// finds it (`lane-residents.ts`), so a resume reaches every process the pause stopped. A pause with no
|
|
22
|
+
// child in the tree stops none of them: it pauses no lane and records nothing, so nothing would resume
|
|
23
|
+
// them. A read of them that failed is `is_unread`, never "none", so a caller can say they were missed.
|
|
24
|
+
|
|
25
|
+
const STOP_SIGNAL = 'SIGSTOP'
|
|
26
|
+
const CONTINUE_SIGNAL = 'SIGCONT'
|
|
27
|
+
const PAUSE_ROUNDS = 5
|
|
28
|
+
|
|
29
|
+
type LaneSignal = typeof STOP_SIGNAL | typeof CONTINUE_SIGNAL
|
|
30
|
+
|
|
31
|
+
interface PauseProbes extends ReapProbes {
|
|
32
|
+
signal: (pid: number, name: LaneSignal) => boolean
|
|
33
|
+
// What runs from the lane outside the tree (`lane-residents.ts`); `undefined` when unreadable.
|
|
34
|
+
residents: (lane: LaneProcesses) => ReadonlyArray<number> | undefined
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// What a pause or a resume reached: the lane's processes signalled, and those of them in the child's
|
|
38
|
+
// tree. Only `child` says the lane is running — a resident outlives the child it served (`eslint_d`
|
|
39
|
+
// idles on), so signalling it alone pauses no lane. `is_unread`: the residents could not be read, so
|
|
40
|
+
// any of them may have been missed.
|
|
41
|
+
interface LaneSignalled {
|
|
42
|
+
signalled: Array<number>
|
|
43
|
+
child: Array<number>
|
|
44
|
+
is_unread: boolean
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// One read of the lane: the child's tree, and the tree with what runs from the lane outside it.
|
|
48
|
+
interface LaneRead {
|
|
49
|
+
tree: Array<number>
|
|
50
|
+
all: Array<number>
|
|
51
|
+
is_unread: boolean
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function signal(pid: number, name: LaneSignal): boolean {
|
|
55
|
+
try {
|
|
56
|
+
process.kill(pid, name)
|
|
57
|
+
|
|
58
|
+
return true
|
|
59
|
+
} catch {
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const SYSTEM_PROBES: PauseProbes = {
|
|
65
|
+
...lane_reap.SYSTEM_PROBES,
|
|
66
|
+
signal,
|
|
67
|
+
residents: (lane) => lane_residents.residents(lane),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// The lane child's tree and what runs from the lane outside it, each once. The residents are read only
|
|
71
|
+
// beside a child, unless `is_resident_read_forced`.
|
|
72
|
+
function lane_processes(
|
|
73
|
+
lane: LaneProcesses,
|
|
74
|
+
probes: PauseProbes,
|
|
75
|
+
is_resident_read_forced: boolean,
|
|
76
|
+
): LaneRead {
|
|
77
|
+
const tree = lane_reap.lane_tree(lane.issue, probes)
|
|
78
|
+
if (!is_resident_read_forced && tree.length === 0) return { tree, all: tree, is_unread: false }
|
|
79
|
+
const residents = probes.residents(lane)
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
tree,
|
|
83
|
+
all: [...new Set([...tree, ...(residents ?? [])])],
|
|
84
|
+
is_unread: residents === undefined,
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function signalled_of(
|
|
89
|
+
signalled: Array<number>,
|
|
90
|
+
tree: ReadonlySet<number>,
|
|
91
|
+
is_unread: boolean,
|
|
92
|
+
): LaneSignalled {
|
|
93
|
+
return { signalled, child: signalled.filter((pid) => tree.has(pid)), is_unread }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Every pid read is `seen`, so a process the signal could not reach is not retried each round; only the
|
|
97
|
+
// ones the signal reached are `stopped`. Every tree pid read is `tree`.
|
|
98
|
+
interface PauseProgress {
|
|
99
|
+
seen: Set<number>
|
|
100
|
+
tree: Set<number>
|
|
101
|
+
stopped: Array<number>
|
|
102
|
+
is_unread: boolean
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function stop_unseen(lane: LaneProcesses, progress: PauseProgress, probes: PauseProbes): number {
|
|
106
|
+
const read = lane_processes(lane, probes, progress.tree.size > 0)
|
|
107
|
+
const unseen = read.all.filter((pid) => !progress.seen.has(pid))
|
|
108
|
+
|
|
109
|
+
for (const pid of read.tree) progress.tree.add(pid)
|
|
110
|
+
progress.is_unread ||= read.is_unread
|
|
111
|
+
|
|
112
|
+
for (const pid of unseen) {
|
|
113
|
+
progress.seen.add(pid)
|
|
114
|
+
if (probes.signal(pid, STOP_SIGNAL)) progress.stopped.push(pid)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return unseen.length
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** SIGSTOP every process of the lane; returns the pids stopped. */
|
|
121
|
+
function pause_lane(lane: LaneProcesses, probes: PauseProbes = SYSTEM_PROBES): LaneSignalled {
|
|
122
|
+
const progress: PauseProgress = {
|
|
123
|
+
seen: new Set(),
|
|
124
|
+
tree: new Set(),
|
|
125
|
+
stopped: [],
|
|
126
|
+
is_unread: false,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
for (let round = 0; round < PAUSE_ROUNDS; round += 1) {
|
|
130
|
+
if (stop_unseen(lane, progress, probes) === 0) break
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return signalled_of(progress.stopped, progress.tree, progress.is_unread)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** SIGCONT every process of the lane; returns the pids continued. */
|
|
137
|
+
function resume_lane(lane: LaneProcesses, probes: PauseProbes = SYSTEM_PROBES): LaneSignalled {
|
|
138
|
+
const read = lane_processes(lane, probes, true)
|
|
139
|
+
const continued = read.all.filter((pid) => probes.signal(pid, CONTINUE_SIGNAL))
|
|
140
|
+
|
|
141
|
+
return signalled_of(continued, new Set(read.tree), read.is_unread)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Only what a pause reads: a lane is matched by its issue and its directory, nothing else.
|
|
145
|
+
function processes_of(lane: LaneProcesses): LaneProcesses {
|
|
146
|
+
return { issue: lane.issue, directory: lane.directory }
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async function open_lanes(): Promise<Array<LaneProcesses>> {
|
|
150
|
+
const lanes = await lane_registry.list_lanes()
|
|
151
|
+
|
|
152
|
+
return lanes.map((lane) => processes_of(lane))
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const lane_pause = { PAUSE_ROUNDS, open_lanes, pause_lane, resume_lane }
|
|
156
|
+
|
|
157
|
+
export { lane_pause }
|
|
158
|
+
export type { LaneSignal, LaneSignalled, PauseProbes }
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { process_identity } from '#scripts/josh/process-identity'
|
|
2
|
+
import { PROBE_TIMEOUT_MS } from '#scripts/lib/timeouts'
|
|
3
|
+
import { execa } from 'execa'
|
|
4
|
+
import { lane_reap, type TreeProbes } from './lane-reap'
|
|
5
|
+
import { process_tools } from './process-tools'
|
|
6
|
+
|
|
7
|
+
// Every process on the machine at one instant, read by one asynchronous `ps`, answering the probes a
|
|
8
|
+
// lane's tree is read through (joshuafolkken/kit#4241), and the listing `run:board`'s
|
|
9
|
+
// usage columns are read from (joshuafolkken/kit#4246).
|
|
10
|
+
//
|
|
11
|
+
// **Why one snapshot.** `lane_reap`'s probes start one synchronous `ps` / `pgrep` per ancestor and per
|
|
12
|
+
// descendant, so a reader that asks about every lane each few seconds — `run:board`, the backlogrun
|
|
13
|
+
// drive — blocked its event loop for over a second with seven lanes under load. The snapshot costs one
|
|
14
|
+
// spawn whatever the lane and process counts, and never blocks. `run:board` takes one per refresh and
|
|
15
|
+
// hands it to both the lane count and the usage columns (`shared`), so the two read the same instant.
|
|
16
|
+
//
|
|
17
|
+
// **The walk is not re-implemented.** `lane_reap` still walks the tree; the
|
|
18
|
+
// snapshot only answers the questions it asks. `matching` reads the full command line the way
|
|
19
|
+
// `pgrep -f` does, and `-ww` keeps `ps` from cutting it at a terminal width. The command is the full
|
|
20
|
+
// line rather than `comm`: `ps` cuts any column but the last, so the two cannot share one listing.
|
|
21
|
+
//
|
|
22
|
+
// **The start time is `process_identity`'s own reading.** A detached ship's record names its process by
|
|
23
|
+
// start time (`run-ship-detach.ts`), and the `lstart` column under `process_identity`'s environment
|
|
24
|
+
// prints it exactly as that module's own `ps` does, so a ship is told alive from these rows without
|
|
25
|
+
// starting another `ps` (joshuafolkken/kit#4245).
|
|
26
|
+
|
|
27
|
+
const COLUMNS = ['pid=', 'ppid=', 'time=', 'rss=', 'stat=', process_identity.START_TIME_FORMAT]
|
|
28
|
+
const PS_ARGUMENTS = ['-A', '-ww', '-o', [...COLUMNS, 'command='].join(',')]
|
|
29
|
+
// `ps` labels nothing locale-dependent here, and the C locale keeps its columns stable; the time zone
|
|
30
|
+
// fixes how the start time prints.
|
|
31
|
+
const PS_ENVIRONMENT = process_identity.PROBE_ENVIRONMENT
|
|
32
|
+
const FIELD_SEPARATOR = /\s+/u
|
|
33
|
+
// `lstart` prints `Tue Sep 8 08:39:04 2026`: five fields, the day of the month padded to two places.
|
|
34
|
+
const START_FIELDS = 5
|
|
35
|
+
const DAY_FIELD = 2
|
|
36
|
+
const DAY_WIDTH = 2
|
|
37
|
+
|
|
38
|
+
interface ProcessRow {
|
|
39
|
+
pid: number
|
|
40
|
+
parent: number
|
|
41
|
+
// `ps`'s cumulative CPU time as printed, `[DD-][HH:]MM:SS[.ss]`.
|
|
42
|
+
time: string
|
|
43
|
+
rss_kb: number
|
|
44
|
+
stat: string
|
|
45
|
+
// The start time as `process_identity`'s `ps` prints it.
|
|
46
|
+
start: string
|
|
47
|
+
command: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// One snapshot's rows.
|
|
51
|
+
type ProcessTable = ReadonlyArray<ProcessRow>
|
|
52
|
+
// A snapshot read on demand, `undefined` where `ps` did not answer.
|
|
53
|
+
type TableRead = () => Promise<ProcessTable | undefined>
|
|
54
|
+
|
|
55
|
+
function is_row(row: ProcessRow): boolean {
|
|
56
|
+
const { pid, parent, rss_kb, command } = row
|
|
57
|
+
|
|
58
|
+
return Number.isSafeInteger(pid + parent) && Number.isFinite(rss_kb) && command !== ''
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// The split fields put back with the day's padding the split dropped.
|
|
62
|
+
function start_of(fields: ReadonlyArray<string>): string {
|
|
63
|
+
return fields
|
|
64
|
+
.map((field, index) => (index === DAY_FIELD ? field.padStart(DAY_WIDTH) : field))
|
|
65
|
+
.join(' ')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// The command's own runs of white space read as one space, which no lane pattern tells apart.
|
|
69
|
+
function row_of(line: string): ProcessRow | undefined {
|
|
70
|
+
const [pid, parent, time = '', rss, stat = '', ...rest] = line.trim().split(FIELD_SEPARATOR)
|
|
71
|
+
const numbers = { pid: Number(pid), parent: Number(parent), rss_kb: Number(rss) }
|
|
72
|
+
const start = start_of(rest.slice(0, START_FIELDS))
|
|
73
|
+
const row = { ...numbers, time, stat, start, command: rest.slice(START_FIELDS).join(' ') }
|
|
74
|
+
|
|
75
|
+
return is_row(row) ? row : undefined
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Each `ps` line as a row; a line that does not read as one is left out. */
|
|
79
|
+
function parse(printed: string): Array<ProcessRow> {
|
|
80
|
+
return printed
|
|
81
|
+
.split('\n')
|
|
82
|
+
.map((line) => row_of(line))
|
|
83
|
+
.filter((row) => row !== undefined)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function matching_in(rows: ProcessTable, pattern: string): Array<number> {
|
|
87
|
+
const expression = new RegExp(pattern, 'u')
|
|
88
|
+
|
|
89
|
+
return rows.filter((row) => expression.test(row.command)).map((row) => row.pid)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Each parent's children, indexed once so a walk does not rescan every row per process.
|
|
93
|
+
function children_index(rows: ProcessTable): Map<number, Array<number>> {
|
|
94
|
+
const children = new Map<number, Array<number>>()
|
|
95
|
+
|
|
96
|
+
for (const { pid, parent } of rows) {
|
|
97
|
+
const siblings = children.get(parent) ?? []
|
|
98
|
+
|
|
99
|
+
siblings.push(pid)
|
|
100
|
+
children.set(parent, siblings)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return children
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** The probes a lane's tree is read through, answered from `rows` alone. */
|
|
107
|
+
function probes_of(rows: ProcessTable): TreeProbes {
|
|
108
|
+
const by_pid = new Map(rows.map((row) => [row.pid, row]))
|
|
109
|
+
const children = children_index(rows)
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
matching: (pattern) => matching_in(rows, pattern),
|
|
113
|
+
children_of: (pid) => children.get(pid) ?? [],
|
|
114
|
+
parent_of: (pid) => by_pid.get(pid)?.parent,
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** `process_identity.read_start` with its `ps` answered from `rows`: `/proc` first, as there. */
|
|
119
|
+
function start_reader(rows: ProcessTable): (pid: number) => string | undefined {
|
|
120
|
+
const starts = new Map(rows.map((row) => [row.pid, row.start]))
|
|
121
|
+
const probes = {
|
|
122
|
+
...process_identity.START_PROBES,
|
|
123
|
+
read_ps_start: (pid: number) => starts.get(pid),
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return (pid) => process_identity.read_start(pid, probes)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** The snapshot, `undefined` where `ps` did not answer; a missing `ps` is refused by name. */
|
|
130
|
+
async function read_table(): Promise<ProcessTable | undefined> {
|
|
131
|
+
try {
|
|
132
|
+
const { stdout } = await execa(lane_reap.PS_COMMAND, PS_ARGUMENTS, {
|
|
133
|
+
env: PS_ENVIRONMENT,
|
|
134
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
return parse(stdout)
|
|
138
|
+
} catch (error) {
|
|
139
|
+
process_tools.throw_if_missing(lane_reap.PS_COMMAND, error)
|
|
140
|
+
|
|
141
|
+
return undefined
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** `read`, run on the first call alone; every later call answers that same snapshot. */
|
|
146
|
+
function shared(read: TableRead): TableRead {
|
|
147
|
+
const taken: { table?: ReturnType<TableRead> } = {}
|
|
148
|
+
|
|
149
|
+
return async function table() {
|
|
150
|
+
taken.table ??= read()
|
|
151
|
+
|
|
152
|
+
return await taken.table
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const lane_process_table = {
|
|
157
|
+
PS_ARGUMENTS,
|
|
158
|
+
parse,
|
|
159
|
+
probes_of,
|
|
160
|
+
read_table,
|
|
161
|
+
shared,
|
|
162
|
+
start_reader,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export { lane_process_table }
|
|
166
|
+
export type { ProcessRow, ProcessTable, TableRead }
|