@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,127 @@
|
|
|
1
|
+
import { MS_PER_SECOND } from '#scripts/lib/timeouts'
|
|
2
|
+
import { lane_ledger, type LedgerEntry, type TestRelatedEntry } from './lane-ledger'
|
|
3
|
+
import { lane_stage_stats } from './lane-stage-stats'
|
|
4
|
+
import { lane_stats, type StatsWindow } from './lane-stats'
|
|
5
|
+
|
|
6
|
+
// What widened a `josh test:related` run (joshuafolkken/kit#4465): one row per scope it settled on —
|
|
7
|
+
// `related`, `none` or the full-suite fallback kind — with the medians of its input (the change
|
|
8
|
+
// itself, what a main sync brought in, what the change since the test-read map's tree joined, the
|
|
9
|
+
// readers the map added), of the test files vitest
|
|
10
|
+
// ran and of its duration. A `related` row whose test files far outrun its input is vitest widening the
|
|
11
|
+
// run on its own.
|
|
12
|
+
|
|
13
|
+
const DECIMALS = 1
|
|
14
|
+
const RUNS_COLUMN = 'runs'
|
|
15
|
+
const SECONDS_COLUMN = 'median (s)'
|
|
16
|
+
const COLUMNS = [
|
|
17
|
+
'test:related scope',
|
|
18
|
+
RUNS_COLUMN,
|
|
19
|
+
'changed',
|
|
20
|
+
'synced',
|
|
21
|
+
'since map',
|
|
22
|
+
'readers',
|
|
23
|
+
'test files',
|
|
24
|
+
SECONDS_COLUMN,
|
|
25
|
+
] as const
|
|
26
|
+
const TRIGGER_COLUMNS = ['test:related whole-suite trigger', RUNS_COLUMN, SECONDS_COLUMN] as const
|
|
27
|
+
|
|
28
|
+
type CountField = 'changed' | 'synced' | 'since_map' | 'readers'
|
|
29
|
+
|
|
30
|
+
function is_test_related(entry: LedgerEntry): entry is TestRelatedEntry {
|
|
31
|
+
return entry.kind === lane_ledger.KIND.TEST_RELATED
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function count_cell(values: ReadonlyArray<number>): string {
|
|
35
|
+
const median = lane_stats.median(values)
|
|
36
|
+
|
|
37
|
+
return median === undefined ? lane_stage_stats.NOT_MEASURED : String(median)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function seconds_cell(values: ReadonlyArray<number>): string {
|
|
41
|
+
const median = lane_stats.median(values)
|
|
42
|
+
|
|
43
|
+
return median === undefined
|
|
44
|
+
? lane_stage_stats.NOT_MEASURED
|
|
45
|
+
: (median / MS_PER_SECOND).toFixed(DECIMALS)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function median_of(runs: ReadonlyArray<TestRelatedEntry>, field: CountField): string {
|
|
49
|
+
return count_cell(runs.map((run) => run[field]))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function scope_row(scope: string, entries: ReadonlyArray<TestRelatedEntry>): string {
|
|
53
|
+
const runs = entries.filter((entry) => entry.scope === scope)
|
|
54
|
+
const test_files = runs.map((run) => run.test_files).filter((files) => files !== undefined)
|
|
55
|
+
|
|
56
|
+
return lane_stats.to_row([
|
|
57
|
+
scope,
|
|
58
|
+
String(runs.length),
|
|
59
|
+
median_of(runs, 'changed'),
|
|
60
|
+
median_of(runs, 'synced'),
|
|
61
|
+
median_of(runs, 'since_map'),
|
|
62
|
+
median_of(runs, 'readers'),
|
|
63
|
+
count_cell(test_files),
|
|
64
|
+
seconds_cell(runs.map((run) => run.elapsed_ms)),
|
|
65
|
+
])
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function rows_under(columns: ReadonlyArray<string>, rows: ReadonlyArray<string>): string {
|
|
69
|
+
return [lane_stats.to_row(columns), lane_stats.to_row(columns.map(() => '---')), ...rows].join(
|
|
70
|
+
'\n',
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function runs_in(
|
|
75
|
+
entries: ReadonlyArray<LedgerEntry>,
|
|
76
|
+
window: StatsWindow,
|
|
77
|
+
): Array<TestRelatedEntry> {
|
|
78
|
+
return lane_stats.in_window(entries, window).filter(is_test_related)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// The period's table: `entries` is the whole ledger, filtered here to `window`.
|
|
82
|
+
function table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string {
|
|
83
|
+
const runs = runs_in(entries, window)
|
|
84
|
+
const scopes = [...new Set(runs.map((run) => run.scope))]
|
|
85
|
+
|
|
86
|
+
return rows_under(
|
|
87
|
+
COLUMNS,
|
|
88
|
+
scopes.map((scope) => scope_row(scope, runs)),
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
interface TriggerRuns {
|
|
93
|
+
file: string
|
|
94
|
+
runs: ReadonlyArray<TestRelatedEntry>
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function runs_sent_by(file: string, runs: ReadonlyArray<TestRelatedEntry>): TriggerRuns {
|
|
98
|
+
return { file, runs: runs.filter((run) => run.trigger_files?.includes(file) === true) }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function trigger_row({ file, runs }: TriggerRuns): string {
|
|
102
|
+
return lane_stats.to_row([
|
|
103
|
+
file,
|
|
104
|
+
String(runs.length),
|
|
105
|
+
seconds_cell(runs.map((run) => run.elapsed_ms)),
|
|
106
|
+
])
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Which changed file sent a run to the whole suite, most runs first (joshuafolkken/kit#4510): the
|
|
110
|
+
// table `WHOLE_SUITE_FILES` and the test-read map are trimmed from. A row written before the files
|
|
111
|
+
// were recorded names none, and so counts under no file.
|
|
112
|
+
function trigger_table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string {
|
|
113
|
+
const runs = runs_in(entries, window)
|
|
114
|
+
const files = [...new Set(runs.flatMap((run) => run.trigger_files ?? []))]
|
|
115
|
+
const triggers = files
|
|
116
|
+
.map((file) => runs_sent_by(file, runs))
|
|
117
|
+
.toSorted((left, right) => right.runs.length - left.runs.length)
|
|
118
|
+
|
|
119
|
+
return rows_under(
|
|
120
|
+
TRIGGER_COLUMNS,
|
|
121
|
+
triggers.map((trigger) => trigger_row(trigger)),
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const lane_test_related_stats = { table, trigger_table }
|
|
126
|
+
|
|
127
|
+
export { lane_test_related_stats }
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
|
|
4
|
+
// One lane session's transcript reduced to its tool calls: each `tool_use` an `assistant` line carries,
|
|
5
|
+
// joined by its id to the `tool_result` a later `user` line carries, so `josh lane:stats` can time a
|
|
6
|
+
// call as the gap between the two lines (joshuafolkken/kit#4418).
|
|
7
|
+
//
|
|
8
|
+
// **A backgrounded call is kept but not timed.** Its result line is the immediate "running in the
|
|
9
|
+
// background" notice, so the gap measures nothing the run waited on; `duration_ms` is `undefined` for
|
|
10
|
+
// it, as for a call whose result never arrived (an interrupted turn).
|
|
11
|
+
|
|
12
|
+
interface ToolCall {
|
|
13
|
+
session_id: string
|
|
14
|
+
started_ms: number
|
|
15
|
+
duration_ms: number | undefined
|
|
16
|
+
background: boolean
|
|
17
|
+
command: string | undefined
|
|
18
|
+
output: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ToolUse {
|
|
22
|
+
started_ms: number
|
|
23
|
+
background: boolean
|
|
24
|
+
command: string | undefined
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface ToolResult {
|
|
28
|
+
ended_ms: number
|
|
29
|
+
output: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface TextPart {
|
|
33
|
+
text?: string | null | undefined
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function join_parts(parts: ReadonlyArray<TextPart>): string {
|
|
37
|
+
return parts.map((part) => part.text ?? '').join('\n')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface RawInput {
|
|
41
|
+
command?: unknown
|
|
42
|
+
run_in_background?: unknown
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface CallInput {
|
|
46
|
+
background: boolean
|
|
47
|
+
command: string | undefined
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function to_input(input: RawInput | null | undefined): CallInput {
|
|
51
|
+
const command = input?.command
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
background: input?.run_in_background === true,
|
|
55
|
+
command: typeof command === 'string' ? command : undefined,
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const TEXT_PARTS_SCHEMA = z.array(z.object({ text: z.string().nullish() }))
|
|
60
|
+
// A result's text: a string, or the text parts of a block list; anything else reads as no output.
|
|
61
|
+
const RESULT_CONTENT_SCHEMA = z
|
|
62
|
+
.union([z.string(), TEXT_PARTS_SCHEMA.transform(join_parts)])
|
|
63
|
+
.catch('')
|
|
64
|
+
const INPUT_SCHEMA = z.object({ command: z.unknown(), run_in_background: z.unknown() }).partial()
|
|
65
|
+
|
|
66
|
+
const BLOCK_SCHEMA = z.object({
|
|
67
|
+
type: z.string(),
|
|
68
|
+
id: z.string().nullish(),
|
|
69
|
+
input: INPUT_SCHEMA.nullish().transform(to_input),
|
|
70
|
+
tool_use_id: z.string().nullish(),
|
|
71
|
+
content: RESULT_CONTENT_SCHEMA.optional(),
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
type Block = z.infer<typeof BLOCK_SCHEMA>
|
|
75
|
+
|
|
76
|
+
function blocks_of(message: { content: Array<Block> } | null | undefined): Array<Block> {
|
|
77
|
+
return message?.content ?? []
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// A line that is not JSON, not a message, or carries no readable timestamp fails the parse.
|
|
81
|
+
const LINE_SCHEMA = z.object({
|
|
82
|
+
timestamp: z.string().transform(Date.parse).pipe(z.number()),
|
|
83
|
+
message: z
|
|
84
|
+
.object({ content: z.array(BLOCK_SCHEMA).catch([]) })
|
|
85
|
+
.nullish()
|
|
86
|
+
.transform(blocks_of),
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
interface Pairs {
|
|
90
|
+
uses: Map<string, ToolUse>
|
|
91
|
+
results: Map<string, ToolResult>
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function record_use(pairs: Pairs, block: Block, started_ms: number): void {
|
|
95
|
+
if (block.type !== 'tool_use' || !block.id) return
|
|
96
|
+
|
|
97
|
+
pairs.uses.set(block.id, { started_ms, ...block.input })
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function record_result(pairs: Pairs, block: Block, ended_ms: number): void {
|
|
101
|
+
if (block.type !== 'tool_result' || !block.tool_use_id) return
|
|
102
|
+
|
|
103
|
+
pairs.results.set(block.tool_use_id, { ended_ms, output: block.content ?? '' })
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function record_line(pairs: Pairs, line: string): void {
|
|
107
|
+
const parsed = LINE_SCHEMA.safeParse(json_value.parse_or_undefined(line))
|
|
108
|
+
|
|
109
|
+
if (!parsed.success) return
|
|
110
|
+
|
|
111
|
+
const { timestamp, message } = parsed.data
|
|
112
|
+
|
|
113
|
+
for (const block of message) {
|
|
114
|
+
record_use(pairs, block, timestamp)
|
|
115
|
+
record_result(pairs, block, timestamp)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function to_call(session_id: string, use: ToolUse, result: ToolResult | undefined): ToolCall {
|
|
120
|
+
const is_timed = result !== undefined && !use.background
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
session_id,
|
|
124
|
+
started_ms: use.started_ms,
|
|
125
|
+
duration_ms: is_timed ? result.ended_ms - use.started_ms : undefined,
|
|
126
|
+
background: use.background,
|
|
127
|
+
command: use.command,
|
|
128
|
+
output: result?.output ?? '',
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Every tool call `raw` — one transcript's text — records, in the order the calls were made.
|
|
133
|
+
function parse(session_id: string, raw: string): Array<ToolCall> {
|
|
134
|
+
const pairs: Pairs = { uses: new Map(), results: new Map() }
|
|
135
|
+
const lines = raw.split('\n')
|
|
136
|
+
|
|
137
|
+
for (const line of lines) record_line(pairs, line)
|
|
138
|
+
|
|
139
|
+
return [...pairs.uses].map(([id, use]) => to_call(session_id, use, pairs.results.get(id)))
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const lane_transcript_calls = { parse }
|
|
143
|
+
|
|
144
|
+
export type { ToolCall }
|
|
145
|
+
export { lane_transcript_calls }
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { cost_transcript } from '#scripts/cost-runtime/cost-transcript'
|
|
2
|
+
import { MS_PER_SECOND } from '#scripts/lib/timeouts'
|
|
3
|
+
import { time_shell } from '#scripts/time-runtime/time-shell'
|
|
4
|
+
import { lane_stage_stats } from './lane-stage-stats'
|
|
5
|
+
import { lane_stats, type StatsWindow } from './lane-stats'
|
|
6
|
+
import { lane_transcript_calls, type ToolCall } from './lane-transcript-calls'
|
|
7
|
+
|
|
8
|
+
// The lane speed metrics only the lane sessions' transcripts hold, printed by `josh lane:stats` under the
|
|
9
|
+
// ledger's tables so a speed check needs no ad-hoc aggregation (joshuafolkken/kit#4418): tool time per
|
|
10
|
+
// session, the verification calls and the share that waited for the core budget, and the medians of
|
|
11
|
+
// `lint:related` / `test:related`.
|
|
12
|
+
//
|
|
13
|
+
// **A chained call is counted apart from a solo one.** One Bash call that runs two verification
|
|
14
|
+
// commands (`josh lint:related && josh test:related`) has one duration for both, so it would read as
|
|
15
|
+
// either command's time; the per-command medians take solo calls only. **Only a foreground call is
|
|
16
|
+
// timed** — `lane_transcript_calls` leaves a backgrounded one's duration out.
|
|
17
|
+
//
|
|
18
|
+
// **The period is cut at each call's own timestamp**, not a transcript's modification time, so a
|
|
19
|
+
// fractional `--period` (since a merge) counts the same calls whichever session they sit in.
|
|
20
|
+
|
|
21
|
+
const TIMED_COMMANDS: ReadonlyArray<string> = ['lint:related', 'test:related']
|
|
22
|
+
// **The verification calls split by what ran them** (joshuafolkken/kit#4442): the scoped checks of the
|
|
23
|
+
// implementation loop, a whole `gate` or `metrics` run by hand before the ship, and the `ship` call —
|
|
24
|
+
// whose own gate runs inside it and is the ledger's to count — so a hand-run gate is never hidden in the
|
|
25
|
+
// loop's volume. A call naming two classes counts in each.
|
|
26
|
+
const CALL_CLASSES: ReadonlyArray<readonly [string, ReadonlySet<string>]> = [
|
|
27
|
+
['verification calls, scoped checks', new Set([...TIMED_COMMANDS, 'cspell:dot'])],
|
|
28
|
+
['verification calls, gate / metrics by hand', new Set(['gate', 'metrics'])],
|
|
29
|
+
['verification calls, ship', new Set(['ship'])],
|
|
30
|
+
]
|
|
31
|
+
const VERIFICATION_COMMANDS: ReadonlySet<string> = new Set(
|
|
32
|
+
CALL_CLASSES.flatMap(([, names]) => [...names]),
|
|
33
|
+
)
|
|
34
|
+
// A command is `josh <name>` at the start of a shell command — after a separator and the shell
|
|
35
|
+
// keywords, then past what `time_shell` skips (env assignments, wrappers with their flags and operands,
|
|
36
|
+
// a `pnpm` / `npx` runner) — so `josh lint:related; josh test:related`, `out=$(pnpm josh gate)` and
|
|
37
|
+
// `CI=1 timeout 600 pnpm josh gate` name their commands. A heredoc body or a quoted string only
|
|
38
|
+
// mentions a command, so `time_shell.unquoted` cuts both, keeping a `"$(…)"` that runs
|
|
39
|
+
// (joshuafolkken/kit#4525).
|
|
40
|
+
const SEPARATOR_PATTERN = /[;&|()\n]/u
|
|
41
|
+
const WORD_PATTERN = /\s+/u
|
|
42
|
+
const KEYWORDS: ReadonlySet<string> = new Set([
|
|
43
|
+
'if',
|
|
44
|
+
'elif',
|
|
45
|
+
'else',
|
|
46
|
+
'then',
|
|
47
|
+
'while',
|
|
48
|
+
'until',
|
|
49
|
+
'do',
|
|
50
|
+
'!',
|
|
51
|
+
'{',
|
|
52
|
+
])
|
|
53
|
+
// `scripts/gate/core-wait.ts` writes this into every wait line it prints.
|
|
54
|
+
const CORE_WAIT_PHRASE = 'waits for the core budget'
|
|
55
|
+
const PERCENT = 100
|
|
56
|
+
const COLUMNS = ['transcript metric', 'value'] as const
|
|
57
|
+
const { NOT_MEASURED } = lane_stage_stats
|
|
58
|
+
|
|
59
|
+
// The josh command `segment` runs, or `''` when it runs none.
|
|
60
|
+
function segment_command(segment: string): string {
|
|
61
|
+
const words = segment.trim().split(WORD_PATTERN)
|
|
62
|
+
const start = words.findIndex((word) => !KEYWORDS.has(word))
|
|
63
|
+
const named = time_shell.josh_command_of_segment(words.slice(start).join(' '))
|
|
64
|
+
|
|
65
|
+
return named.slice(time_shell.JOSH_PREFIX.length)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function verification_commands(command = ''): Array<string> {
|
|
69
|
+
const spoken = time_shell.unquoted(command)
|
|
70
|
+
const named = spoken.split(SEPARATOR_PATTERN).map((segment) => segment_command(segment))
|
|
71
|
+
|
|
72
|
+
return named.filter((name) => VERIFICATION_COMMANDS.has(name))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function seconds_cell(ms: number | undefined): string {
|
|
76
|
+
return ms === undefined ? NOT_MEASURED : (ms / MS_PER_SECOND).toFixed(1)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function is_timed(ms: number | undefined): ms is number {
|
|
80
|
+
return ms !== undefined
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function durations(calls: ReadonlyArray<ToolCall>): Array<number> {
|
|
84
|
+
return calls.map((call) => call.duration_ms).filter((ms) => is_timed(ms))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Each session's summed foreground tool time, for the sessions that made a call in the period.
|
|
88
|
+
function session_times(calls: ReadonlyArray<ToolCall>): Array<number> {
|
|
89
|
+
const sessions = [...new Set(calls.map((call) => call.session_id))]
|
|
90
|
+
|
|
91
|
+
return sessions.map((session) =>
|
|
92
|
+
durations(calls.filter((call) => call.session_id === session)).reduce(
|
|
93
|
+
(sum, value) => sum + value,
|
|
94
|
+
0,
|
|
95
|
+
),
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function share_cell(part: number, whole: number): string {
|
|
100
|
+
if (whole === 0) return NOT_MEASURED
|
|
101
|
+
|
|
102
|
+
return `${String(part)} of ${String(whole)} (${((part / whole) * PERCENT).toFixed(1)}%)`
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function solo_median_row(verifying: ReadonlyArray<ToolCall>, name: string): Array<string> {
|
|
106
|
+
const solo = verifying.filter((call) => {
|
|
107
|
+
const named = verification_commands(call.command)
|
|
108
|
+
|
|
109
|
+
return named.length === 1 && named[0] === name
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
return [`${name} median, solo (s)`, seconds_cell(lane_stats.median(durations(solo)))]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function class_rows(verifying: ReadonlyArray<ToolCall>): Array<Array<string>> {
|
|
116
|
+
return CALL_CLASSES.map(([metric, names]) => {
|
|
117
|
+
const named = verifying.filter((call) =>
|
|
118
|
+
verification_commands(call.command).some((name) => names.has(name)),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
return [metric, String(named.length)]
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function rows_of(calls: ReadonlyArray<ToolCall>): Array<Array<string>> {
|
|
126
|
+
const times = session_times(calls)
|
|
127
|
+
const verifying = calls.filter((call) => verification_commands(call.command).length > 0)
|
|
128
|
+
const chained = verifying.filter((call) => verification_commands(call.command).length > 1)
|
|
129
|
+
const waited = verifying.filter((call) => call.output.includes(CORE_WAIT_PHRASE))
|
|
130
|
+
|
|
131
|
+
return [
|
|
132
|
+
['lane sessions', String(times.length)],
|
|
133
|
+
['tool time per session, median (min)', lane_stage_stats.cell(lane_stats.median(times))],
|
|
134
|
+
['tool time per session, mean (min)', lane_stage_stats.cell(lane_stats.mean(times))],
|
|
135
|
+
['verification calls, solo', String(verifying.length - chained.length)],
|
|
136
|
+
['verification calls, chained', String(chained.length)],
|
|
137
|
+
...class_rows(verifying),
|
|
138
|
+
['waited for the core budget', share_cell(waited.length, verifying.length)],
|
|
139
|
+
...TIMED_COMMANDS.map((name) => solo_median_row(verifying, name)),
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// The period's table: `calls` is every lane session's calls, filtered here to `window`.
|
|
144
|
+
function table(calls: ReadonlyArray<ToolCall>, window: StatsWindow): string {
|
|
145
|
+
const period = calls.filter(
|
|
146
|
+
(call) => call.started_ms >= window.since_ms && call.started_ms <= window.until_ms,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
return [
|
|
150
|
+
lane_stats.to_row(COLUMNS),
|
|
151
|
+
lane_stats.to_row(COLUMNS.map(() => '---')),
|
|
152
|
+
...rows_of(period).map((row) => lane_stats.to_row(row)),
|
|
153
|
+
].join('\n')
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// The tool calls of every lane session under `directories` that was still written to in `window` — a
|
|
157
|
+
// transcript last modified before the period holds no call in it, so it is never read. A delegated
|
|
158
|
+
// unit's transcript is not a lane session, and its time is already inside the parent's wait for it.
|
|
159
|
+
function read_calls(directories: ReadonlyArray<string>, window: StatsWindow): Array<ToolCall> {
|
|
160
|
+
return cost_transcript
|
|
161
|
+
.list_sessions_across(directories)
|
|
162
|
+
.filter((file) => !file.is_delegated && file.modified_ms >= window.since_ms)
|
|
163
|
+
.flatMap((file) => lane_transcript_calls.parse(file.session_id, cost_transcript.read_raw(file)))
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const lane_transcript_stats = { read_calls, table, verification_commands }
|
|
167
|
+
|
|
168
|
+
export { lane_transcript_stats }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { git_command } from '#scripts/git/git-command'
|
|
2
2
|
import { run_hold } from '#scripts/run/hold/run-hold'
|
|
3
|
+
import { PROCESS_NONE } from '#scripts/run/run-liveness'
|
|
3
4
|
import { lane_await } from './lane-await'
|
|
4
5
|
import type { LaneInfo } from './lane-registry'
|
|
5
6
|
|
|
@@ -9,7 +10,7 @@ import type { LaneInfo } from './lane-registry'
|
|
|
9
10
|
// refuses it as `already-open` — so the next launch of that issue failed on a lane with nothing in it.
|
|
10
11
|
//
|
|
11
12
|
// **Every unreadable answer is "not vacant"**: `is_tree_dirty` already reads an unreadable status as
|
|
12
|
-
// dirty, and a branch whose commits cannot be counted is kept rather than closed, because closing it
|
|
13
|
+
// dirty, a process probe that could not look reads as occupied, and a branch whose commits cannot be counted is kept rather than closed, because closing it
|
|
13
14
|
// deletes the branch and anything on it.
|
|
14
15
|
async function has_no_commits(lane: LaneInfo): Promise<boolean> {
|
|
15
16
|
try {
|
|
@@ -21,8 +22,10 @@ async function has_no_commits(lane: LaneInfo): Promise<boolean> {
|
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
// Only pgrep's own "no match" clears a lane: a probe that failed or timed out never looked, and a
|
|
26
|
+
// freshly launched child with no commit yet must not read vacant on it (joshuafolkken/kit#4028).
|
|
24
27
|
function is_occupied(lane: LaneInfo): boolean {
|
|
25
|
-
return lane.is_stranded || lane_await.
|
|
28
|
+
return lane.is_stranded || lane_await.process_trace_default(lane.issue) !== PROCESS_NONE
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
async function is_vacant(lane: LaneInfo): Promise<boolean> {
|
|
@@ -31,6 +34,13 @@ async function is_vacant(lane: LaneInfo): Promise<boolean> {
|
|
|
31
34
|
return await has_no_commits(lane)
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
// The issues of the lanes that hold nothing worth keeping, read in parallel.
|
|
38
|
+
async function vacant_issues(lanes: ReadonlyArray<LaneInfo>): Promise<Array<string>> {
|
|
39
|
+
const answers = await Promise.all(lanes.map(async (lane) => await is_vacant(lane)))
|
|
40
|
+
|
|
41
|
+
return lanes.filter((_lane, index) => answers[index] === true).map((lane) => lane.issue)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const lane_vacant = { is_vacant, vacant_issues }
|
|
35
45
|
|
|
36
46
|
export { lane_vacant }
|
|
@@ -4,8 +4,9 @@ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
|
4
4
|
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
5
5
|
import { lane_withdraw, type WithdrawOutcome } from './lane-withdraw'
|
|
6
6
|
|
|
7
|
-
// `josh lane:withdraw <issue> --reason <text>` — every explanation on standard error, and a
|
|
8
|
-
//
|
|
7
|
+
// `josh lane:withdraw <issue> --reason <text>` — every explanation on standard error, and anything but a
|
|
8
|
+
// finished withdrawal exits non-zero, so a caller never takes a half-done one as done. The Issue stays
|
|
9
|
+
// open on success.
|
|
9
10
|
|
|
10
11
|
const ARGV_OFFSET = 2
|
|
11
12
|
const SUCCESS_EXIT_CODE = 0
|
|
@@ -24,7 +25,7 @@ function issue_of(positionals: ReadonlyArray<string>): string | undefined {
|
|
|
24
25
|
return rest.length === 0 && issue_number_shape.is_issue_number(issue ?? '') ? issue : undefined
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
// A reason of only whitespace is no reason: the Issue would
|
|
28
|
+
// A reason of only whitespace is no reason: the Issue would carry an empty `Why:` line.
|
|
28
29
|
function reason_of(value: unknown): string | undefined {
|
|
29
30
|
const reason = cli_flags.string_of(value)?.trim()
|
|
30
31
|
|
|
@@ -41,7 +42,7 @@ function parse_request(argv: ReadonlyArray<string>): Request | undefined {
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
function exit_code_of(outcome: WithdrawOutcome): number {
|
|
44
|
-
return outcome.kind === 'withdrawn'
|
|
45
|
+
return outcome.kind === 'withdrawn' ? SUCCESS_EXIT_CODE : FAILURE_EXIT_CODE
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
@@ -10,22 +10,21 @@ import { lane_close, type CloseKind } from './lane-close'
|
|
|
10
10
|
import { lane_preserve, type KeptWork } from './lane-preserve'
|
|
11
11
|
import { lane_reap } from './lane-reap'
|
|
12
12
|
import { lane_registry, type LaneInfo } from './lane-registry'
|
|
13
|
+
import { lane_residents } from './lane-residents'
|
|
14
|
+
import { lane_state } from './lane-state'
|
|
13
15
|
|
|
14
|
-
// `josh lane:withdraw <N> --reason <text>` — a person takes a running lane child's issue out of the
|
|
15
|
-
//
|
|
16
|
+
// `josh lane:withdraw <N> --reason <text>` — a person takes a running lane child's issue out of the
|
|
17
|
+
// current run: the child is stopped, its work stashed and the lane closed. **The Issue stays open** —
|
|
18
|
+
// a withdrawal ends this run's attempt, not the work — so a later run offers it again; this run does
|
|
19
|
+
// not (`backlog-drive-restore.ts` → `offer_exclude`, and the drive's own exclusion).
|
|
16
20
|
//
|
|
17
21
|
// **The `withdraw` event is written first, before anything is stopped.** Killing the child alone would
|
|
18
22
|
// let `lane:await` book it stopped and `run:merge` classify it from GitHub — an open issue resumed as an
|
|
19
|
-
// `outage` or parked `
|
|
20
|
-
// newest launch-or-withdraw event is a withdraw is booked `withdrawn` whatever the Issue's state reads
|
|
21
|
-
// at that moment, and the race between the kill and the close cannot book it as anything else.
|
|
23
|
+
// `outage` or parked `run:stalled`. `run:merge` reads the event stream before GitHub, so a child whose
|
|
24
|
+
// newest launch-or-withdraw event is a withdraw is booked `withdrawn` whatever the Issue's state reads.
|
|
22
25
|
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// GitHub's close — `run:merge` books a merged close as merged whatever the event stream says.
|
|
26
|
-
//
|
|
27
|
-
// A tree that could not be stashed is left in place with the Issue open: closing the lane would delete
|
|
28
|
-
// the work, and the person decides what to keep.
|
|
26
|
+
// A tree that could not be stashed is left in place: closing the lane would delete the work, and the
|
|
27
|
+
// person decides what to keep.
|
|
29
28
|
|
|
30
29
|
const WITHDRAW_OCCASION = 'lane withdraw'
|
|
31
30
|
const WITHDRAW_CAUSE = 'a person withdrew it with `lane:withdraw`'
|
|
@@ -41,22 +40,21 @@ interface Withdrawn {
|
|
|
41
40
|
// How many of the child's processes the withdrawal stopped — 0 for a child that had already ended.
|
|
42
41
|
reaped: number
|
|
43
42
|
stash: string | undefined
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
had_closed: boolean
|
|
43
|
+
// Whether the comment saying the issue stays open reached it.
|
|
44
|
+
is_noted: boolean
|
|
47
45
|
lane: CloseKind
|
|
46
|
+
// What else the close ended from the checkout; `undefined` where it could not be read.
|
|
47
|
+
residents: ReadonlyArray<number> | undefined
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
type IssueSettled = Pick<Withdrawn, 'had_closed' | 'is_closed'>
|
|
51
|
-
|
|
52
50
|
type Refused =
|
|
53
51
|
{ kind: typeof CLOSED_KIND } | { kind: typeof NO_LANE_KIND } | { kind: typeof UNREADABLE_KIND }
|
|
54
52
|
type WithdrawOutcome = Withdrawn | Unsaved | Refused
|
|
55
53
|
|
|
56
|
-
function
|
|
54
|
+
function withdraw_comment(reason: string): string {
|
|
57
55
|
return [
|
|
58
|
-
'Withdrawn by a person with `pnpm josh lane:withdraw`.',
|
|
59
|
-
'Its lane child was stopped and the lane closed.',
|
|
56
|
+
'Withdrawn from the current run by a person with `pnpm josh lane:withdraw`.',
|
|
57
|
+
'Its lane child was stopped and the lane closed. The Issue stays open: this run does not resume it, and the next run offers it again.',
|
|
60
58
|
`- Why: ${reason}`,
|
|
61
59
|
].join('\n')
|
|
62
60
|
}
|
|
@@ -78,47 +76,45 @@ async function refusal_of(issue: string): Promise<Refused | undefined> {
|
|
|
78
76
|
return undefined
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
async function
|
|
82
|
-
const refusal = await refusal_of(issue)
|
|
83
|
-
|
|
84
|
-
// An unread issue may have merged during the reap, so it is left open for a person to close.
|
|
85
|
-
if (refusal !== undefined) {
|
|
86
|
-
const is_closed = refusal.kind === CLOSED_KIND
|
|
87
|
-
|
|
88
|
-
return { is_closed, had_closed: is_closed }
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const is_closed = await git_gh_issue_write.issue_close_not_planned(issue, close_comment(reason))
|
|
92
|
-
|
|
93
|
-
return { is_closed, had_closed: false }
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async function close_issue(
|
|
79
|
+
async function note_issue(
|
|
97
80
|
issue: string,
|
|
98
81
|
reason: string,
|
|
99
82
|
stash: string | undefined,
|
|
100
|
-
): Promise<
|
|
101
|
-
const
|
|
83
|
+
): Promise<boolean> {
|
|
84
|
+
const is_noted = await git_gh_issue_write.issue_try_comment(issue, withdraw_comment(reason))
|
|
102
85
|
|
|
103
86
|
if (stash !== undefined) await lane_preserve.announce(issue, stash, WITHDRAW_CAUSE)
|
|
104
87
|
await run_label.unmark(issue)
|
|
105
88
|
|
|
106
|
-
return
|
|
89
|
+
return is_noted
|
|
107
90
|
}
|
|
108
91
|
|
|
109
92
|
async function stop_and_close(lane: LaneInfo, reason: string): Promise<WithdrawOutcome> {
|
|
110
93
|
await record_withdraw(lane.issue, reason)
|
|
111
|
-
const reaped = lane_reap.reap_child(lane
|
|
94
|
+
const reaped = lane_reap.reap_child(lane).length
|
|
112
95
|
const saved = await lane_preserve.keep_work(lane.issue, lane.directory, WITHDRAW_OCCASION)
|
|
113
96
|
|
|
114
97
|
if (saved.kind === 'unsaved') return saved
|
|
115
|
-
const
|
|
98
|
+
const is_noted = await note_issue(lane.issue, reason, saved.stash)
|
|
116
99
|
const closed = await lane_close.close_lane(lane.issue)
|
|
117
100
|
|
|
118
|
-
|
|
101
|
+
// After the close, so the record names the withdrawal rather than the close it ran. An `incomplete`
|
|
102
|
+
// close is not `ended`: the supervisor closes the lane again until its last process is gone.
|
|
103
|
+
if (closed.kind !== 'incomplete') {
|
|
104
|
+
await lane_state.record_change({ issue: lane.issue, state: 'ended', command: 'lane:withdraw' })
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
kind: 'withdrawn',
|
|
109
|
+
reaped,
|
|
110
|
+
stash: saved.stash,
|
|
111
|
+
is_noted,
|
|
112
|
+
lane: closed.kind,
|
|
113
|
+
residents: closed.residents,
|
|
114
|
+
}
|
|
119
115
|
}
|
|
120
116
|
|
|
121
|
-
/** Stop `#<N>`'s lane child, stash its work
|
|
117
|
+
/** Stop `#<N>`'s lane child, stash its work and close the lane, leaving the Issue open. */
|
|
122
118
|
async function withdraw(issue: string, reason: string): Promise<WithdrawOutcome> {
|
|
123
119
|
issue_number_shape.require_issue_number(issue)
|
|
124
120
|
const refusal = await refusal_of(issue)
|
|
@@ -137,21 +133,26 @@ function stash_sentence(stash: string | undefined): string {
|
|
|
137
133
|
return `Its uncommitted work was stashed — recover with \`pnpm josh stash:pop "${stash}"\`.`
|
|
138
134
|
}
|
|
139
135
|
|
|
136
|
+
// What the lane's close left or ended, as a suffix.
|
|
137
|
+
function lane_suffix(outcome: Withdrawn, cited: string): string {
|
|
138
|
+
const removed = outcome.lane === 'incomplete' ? ' The lane could not be fully removed.' : ''
|
|
139
|
+
const residents = lane_residents.residents_sentence(outcome.residents, cited)
|
|
140
|
+
|
|
141
|
+
return residents === undefined ? removed : `${removed} ${residents}`
|
|
142
|
+
}
|
|
143
|
+
|
|
140
144
|
function withdrawn_text(outcome: Withdrawn, issue: string): string {
|
|
141
145
|
const cited = session_cite.issue(issue)
|
|
142
146
|
const stopped = outcome.reaped === 0 ? 'Its child had already ended.' : 'Stopped its child.'
|
|
143
147
|
const head = `Withdrew ${cited}. ${stopped} ${stash_sentence(outcome.stash)}`
|
|
144
|
-
const lane = outcome
|
|
145
|
-
|
|
146
|
-
if (outcome.had_closed) return `${head} The Issue had already closed and was left as is.${lane}`
|
|
147
|
-
|
|
148
|
-
if (outcome.is_closed) return `${head} The Issue is closed as not planned.${lane}`
|
|
148
|
+
const lane = lane_suffix(outcome, cited)
|
|
149
|
+
const noted = outcome.is_noted ? '' : ' The comment saying so could not be posted.'
|
|
149
150
|
|
|
150
|
-
return `${head} The Issue
|
|
151
|
+
return `${head} The Issue stays open: this run does not offer it again, the next run does.${noted}${lane}`
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
function unsaved_text(outcome: Unsaved, issue: string): string {
|
|
154
|
-
return `The child for ${session_cite.issue(issue)} was stopped, but its uncommitted work could not be stashed (${outcome.reason}), so the
|
|
155
|
+
return `The child for ${session_cite.issue(issue)} was stopped, but its uncommitted work could not be stashed (${outcome.reason}), so the lane is left at ${outcome.directory}; \`run:merge\` books it withdrawn.`
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
function refused_text(outcome: Refused, issue: string): string {
|