@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,41 @@
|
|
|
1
|
+
import { agent_exit_record } from './agent-exit-record'
|
|
2
|
+
import type { ClaudeResultEvent } from './claude-result-event'
|
|
3
|
+
|
|
4
|
+
// Whether a Claude session's exit record is an authentication failure — measured on 2026-10-19, when
|
|
5
|
+
// an expired OAuth session ended three lane children with `Failed to authenticate: OAuth session
|
|
6
|
+
// expired and could not be refreshed` and the parent parked each as a child that stopped on its own
|
|
7
|
+
// (joshuafolkken/kit#4216).
|
|
8
|
+
//
|
|
9
|
+
// **Kept apart from `api-outage.ts`**: an outage clears on its own, so its child is re-dispatched; an
|
|
10
|
+
// authentication failure lasts until a person runs `/login`, so every dispatch fails the same way and
|
|
11
|
+
// the run has to stop instead. The read is the same mechanical one — the error flag AND a fixed
|
|
12
|
+
// marker in the harness's own `reason`, never the marker alone.
|
|
13
|
+
|
|
14
|
+
// Matched against `reason`, which carries the record's `result` text — the observed record's
|
|
15
|
+
// `error: 'authentication_failed'` code is not decoded, so it is no marker here.
|
|
16
|
+
const AUTH_MARKERS: ReadonlyArray<string> = ['failed to authenticate']
|
|
17
|
+
|
|
18
|
+
// The fixed sentence a stop caused by an authentication failure carries, so the tooling that reads a
|
|
19
|
+
// stop back (`run-ship-stop-cause.ts`) tells it from a review finding by this text, not by guessing.
|
|
20
|
+
const AUTH_FAILURE_NOTE = 'the session could not authenticate — a person has to run /login'
|
|
21
|
+
|
|
22
|
+
function is_auth_failure(record: ClaudeResultEvent | undefined): boolean {
|
|
23
|
+
if (record === undefined || !record.is_error || record.reason === undefined) return false
|
|
24
|
+
|
|
25
|
+
const lower = record.reason.toLowerCase()
|
|
26
|
+
|
|
27
|
+
return AUTH_MARKERS.some((marker) => lower.includes(marker))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// The same read over a whole stream-json transcript, such as a reviewer's log: its last exit record.
|
|
31
|
+
// The log is appended across launches, so it is read only when it ends on an exit record: a later
|
|
32
|
+
// session that died before writing its own leaves an earlier session's record behind it — not read.
|
|
33
|
+
function is_auth_failed_transcript(transcript: string | undefined): boolean {
|
|
34
|
+
if (transcript === undefined || !agent_exit_record.ends_on_exit_record(transcript)) return false
|
|
35
|
+
|
|
36
|
+
return is_auth_failure(agent_exit_record.read_exit_record(transcript))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const api_auth = { AUTH_FAILURE_NOTE, is_auth_failed_transcript, is_auth_failure }
|
|
40
|
+
|
|
41
|
+
export { api_auth }
|
|
@@ -4,7 +4,7 @@ import type { ClaudeResultEvent } from './claude-result-event'
|
|
|
4
4
|
// stopped mid-implementation on its own. Measured twice: on 2026-09-15 four
|
|
5
5
|
// children ended `The socket connection was closed unexpectedly`, and on 2026-09-21 a child spent all
|
|
6
6
|
// ten connection retries on `Unable to connect to API (ConnectionRefused)`. The parent read both as
|
|
7
|
-
// ordinary failures — `in-progress` stripped,
|
|
7
|
+
// ordinary failures — `in-progress` stripped, a park label applied, counted against the
|
|
8
8
|
// consecutive-failure guard — when the child never reached the API at all.
|
|
9
9
|
//
|
|
10
10
|
// **The read is mechanical, never a similarity judgement.** A terminal `result` event that ends in
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
import { fileURLToPath } from 'node:url'
|
|
3
1
|
import { epic_bundle_gaps } from '#scripts/epic/epic-bundle-gaps'
|
|
4
2
|
import { epic_index, type FetchedEpics } from '#scripts/epic/epic-index'
|
|
5
3
|
import { epic_issue } from '#scripts/epic/epic-issue'
|
|
@@ -10,6 +8,8 @@ import { cutoff_cause, cutoff_of, type ScanCutoff } from '#scripts/git/listing-c
|
|
|
10
8
|
import { read_json_listing } from '#scripts/git/parse-json-array'
|
|
11
9
|
import { git_next_issues } from '#scripts/issue/git-next-issues'
|
|
12
10
|
import { AUTO_OK_LABEL } from '#scripts/issue/issue-labels'
|
|
11
|
+
import { issue_not_before } from '#scripts/issue/issue-not-before'
|
|
12
|
+
import { issue_sample_gate } from '#scripts/issue/issue-sample-gate'
|
|
13
13
|
import { session_cite } from '#scripts/issue/session-cite'
|
|
14
14
|
|
|
15
15
|
// `josh auto-ok:next` — which issue outside the epic an unattended run picks up next.
|
|
@@ -20,7 +20,6 @@ import { session_cite } from '#scripts/issue/session-cite'
|
|
|
20
20
|
// nothing checks it. The contract is `epic:next`'s: one token on standard output, every explanation
|
|
21
21
|
// on standard error, so `answer=$(pnpm josh auto-ok:next)` reads it.
|
|
22
22
|
|
|
23
|
-
const ARGV_OFFSET = 2
|
|
24
23
|
const SUCCESS_EXIT_CODE = 0
|
|
25
24
|
const FAILURE_EXIT_CODE = 1
|
|
26
25
|
const EXCLUDE_FLAG = '--exclude'
|
|
@@ -210,7 +209,11 @@ async function fetch_opted_in(): Promise<OptedInRead> {
|
|
|
210
209
|
LISTING_LIMIT,
|
|
211
210
|
)
|
|
212
211
|
|
|
213
|
-
|
|
212
|
+
const read = json === undefined ? await classify_failed_read() : parse_listing(json, is_capped)
|
|
213
|
+
|
|
214
|
+
if (read.kind === 'read') await issue_sample_gate.prime(read.issues.map((issue) => issue.body))
|
|
215
|
+
|
|
216
|
+
return read
|
|
214
217
|
}
|
|
215
218
|
|
|
216
219
|
// Whether every issue this one declares as a blocker has closed. `blockedBy` is the same native
|
|
@@ -331,10 +334,15 @@ function is_runnable(
|
|
|
331
334
|
issue: OpenIssueData,
|
|
332
335
|
tracked: ReadonlyMap<number, number>,
|
|
333
336
|
exclude: ReadonlyArray<number>,
|
|
337
|
+
now: number = Date.now(),
|
|
334
338
|
): boolean {
|
|
335
339
|
if (tracked.has(issue.number)) return false
|
|
336
340
|
|
|
337
|
-
return
|
|
341
|
+
return (
|
|
342
|
+
is_unblocked(issue) &&
|
|
343
|
+
!exclude.includes(issue.number) &&
|
|
344
|
+
issue_not_before.is_due(issue.body, now)
|
|
345
|
+
)
|
|
338
346
|
}
|
|
339
347
|
|
|
340
348
|
function pick_next(
|
|
@@ -351,7 +359,7 @@ function pick_next(
|
|
|
351
359
|
function none_reason(count: number): string {
|
|
352
360
|
if (count === 0) return NONE_OPTED_IN_MESSAGE
|
|
353
361
|
|
|
354
|
-
return `All ${String(count)} open \`${AUTO_OK_LABEL}\` issue(s) are excluded — tracked by an opted-in epic, an epic itself, already in progress, parked, blocked by an open issue, or the one just merged.`
|
|
362
|
+
return `All ${String(count)} open \`${AUTO_OK_LABEL}\` issue(s) are excluded — tracked by an opted-in epic, an epic itself, already in progress, parked, blocked by an open issue, not due until its start time, or the one just merged.`
|
|
355
363
|
}
|
|
356
364
|
|
|
357
365
|
// Said only when the cap actually bit, and worded from the answer rather than before it: the one run
|
|
@@ -457,14 +465,6 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
|
457
465
|
return await answer(read, options.exclude)
|
|
458
466
|
}
|
|
459
467
|
|
|
460
|
-
// `process.exitCode` rather than `process.exit()`: the answer is written with `console.info`, and on
|
|
461
|
-
// macOS a write to a pipe is asynchronous — `process.exit()` can tear the process down before it has
|
|
462
|
-
// drained, and this command's whole contract is `answer=$(pnpm josh auto-ok:next)`. The same shape
|
|
463
|
-
// is already in `scripts/cost-runtime/cost-cli.ts`, which met the truncation first.
|
|
464
|
-
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
465
|
-
process.exitCode = await run(argv)
|
|
466
|
-
}
|
|
467
|
-
|
|
468
468
|
const auto_ok_cli = {
|
|
469
469
|
USAGE,
|
|
470
470
|
NONE_TOKEN,
|
|
@@ -486,7 +486,5 @@ const auto_ok_cli = {
|
|
|
486
486
|
run,
|
|
487
487
|
}
|
|
488
488
|
|
|
489
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
490
|
-
|
|
491
489
|
export { auto_ok_cli }
|
|
492
490
|
export type { NextOptions, OptedInRead, PickupContext, TrackingRead }
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { gh_author_association } from '#scripts/gh/gh-author-association'
|
|
1
2
|
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
2
3
|
import { issue_label_schema } from '#scripts/git/git-schemas'
|
|
3
4
|
import { read_json_listing } from '#scripts/git/parse-json-array'
|
|
@@ -25,6 +26,8 @@ const row_schema = z.looseObject({
|
|
|
25
26
|
body: z.string().nullish(),
|
|
26
27
|
labels: z.array(issue_label_schema),
|
|
27
28
|
updatedAt: z.string(),
|
|
29
|
+
author_association: z.string().nullish(),
|
|
30
|
+
user: z.looseObject({ login: z.string() }).nullish(),
|
|
28
31
|
})
|
|
29
32
|
|
|
30
33
|
interface JudgeRow extends JudgeIssue {
|
|
@@ -35,13 +38,17 @@ interface JudgeRow extends JudgeIssue {
|
|
|
35
38
|
// An issue's number to the `updatedAt` it was last seen judged at.
|
|
36
39
|
type JudgedCache = Map<number, string>
|
|
37
40
|
|
|
38
|
-
function to_row(raw: z.infer<typeof row_schema>): JudgeRow {
|
|
41
|
+
async function to_row(raw: z.infer<typeof row_schema>): Promise<JudgeRow> {
|
|
39
42
|
return {
|
|
40
43
|
number: raw.number,
|
|
41
44
|
title: raw.title,
|
|
42
45
|
body: raw.body ?? '',
|
|
43
46
|
labels: raw.labels.map((label) => label.name),
|
|
44
47
|
updated_at: raw.updatedAt,
|
|
48
|
+
is_trusted: await gh_author_association.is_trusted({
|
|
49
|
+
login: raw.user?.login,
|
|
50
|
+
association: raw.author_association,
|
|
51
|
+
}),
|
|
45
52
|
}
|
|
46
53
|
}
|
|
47
54
|
|
|
@@ -55,7 +62,9 @@ async function read_candidates(): Promise<ReadonlyArray<JudgeRow> | undefined> {
|
|
|
55
62
|
|
|
56
63
|
if (listing.kind !== 'read') return undefined
|
|
57
64
|
|
|
58
|
-
|
|
65
|
+
const rows = await Promise.all(listing.rows.map(async (raw) => await to_row(raw)))
|
|
66
|
+
|
|
67
|
+
return rows.filter((row) => auto_ok_judge.is_candidate(row))
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
// `true` only for an issue known to owe a judgement: a failed comment read learns nothing, so it is
|
|
@@ -63,7 +72,7 @@ async function read_candidates(): Promise<ReadonlyArray<JudgeRow> | undefined> {
|
|
|
63
72
|
async function owes_judgement(row: JudgeRow, cache: JudgedCache): Promise<boolean> {
|
|
64
73
|
if (cache.get(row.number) === row.updated_at) return false
|
|
65
74
|
|
|
66
|
-
const comments = issue_watch_diff.parse_comments(
|
|
75
|
+
const comments = await issue_watch_diff.parse_comments(
|
|
67
76
|
await git_gh_command.issue_list_comments(String(row.number)),
|
|
68
77
|
)
|
|
69
78
|
|
|
@@ -2,11 +2,8 @@ import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
|
2
2
|
import { issue_label_schema } from '#scripts/git/git-schemas'
|
|
3
3
|
import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
|
|
4
4
|
import { issue_auto_ok, type AutoOkDecision } from '#scripts/issue/issue-auto-ok'
|
|
5
|
-
import {
|
|
6
|
-
import { AUTO_OK_LABEL } from '#scripts/issue/issue-labels'
|
|
5
|
+
import { AUTO_OK_LABEL, has_label_name } from '#scripts/issue/issue-labels'
|
|
7
6
|
import { session_cite } from '#scripts/issue/session-cite'
|
|
8
|
-
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
9
|
-
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
10
7
|
import { z } from 'zod'
|
|
11
8
|
import { auto_ok_judge } from './auto-ok-judge'
|
|
12
9
|
|
|
@@ -14,17 +11,30 @@ import { auto_ok_judge } from './auto-ok-judge'
|
|
|
14
11
|
//
|
|
15
12
|
// **An applied judgement still passes the mechanical exclusions** — `issue_auto_ok.exclusion_of` is
|
|
16
13
|
// re-read against the labels as they stand, so a label added since the listing refuses the write
|
|
17
|
-
// rather than racing it. **The
|
|
18
|
-
//
|
|
19
|
-
//
|
|
14
|
+
// rather than racing it. **The judgement comment lands before the labels**: a re-run skips an issue
|
|
15
|
+
// that already carries `auto-ok`, so a comment failing after the labels would never be retried, while
|
|
16
|
+
// a label failing after the comment leaves `auto-ok` off and the issue open to an explicit
|
|
17
|
+
// `--apply <N>` — the refusal names it, since the listing reads the comment as judged. **The
|
|
18
|
+
// run label lands before `auto-ok`**, so the pool never holds an opted-in issue that `backlog:next`
|
|
19
|
+
// would withhold as untriaged. Both answers leave the judgement comment the next listing reads as the
|
|
20
|
+
// record; an applied one writes nothing to the run board, which shows the issue once it is dispatched
|
|
21
|
+
// (joshuafolkken/kit#4133).
|
|
20
22
|
|
|
21
23
|
const SUCCESS_EXIT_CODE = 0
|
|
22
24
|
const FAILURE_EXIT_CODE = 1
|
|
23
25
|
const UNREADABLE = 'the issue could not be read'
|
|
26
|
+
const CLOSED_STATE = 'CLOSED'
|
|
27
|
+
// The judgement comment is already posted, so the listing will not offer the issue again.
|
|
28
|
+
const RETRY_HINT = 're-run `pnpm josh auto-ok:judge --apply <N>` to finish it'
|
|
24
29
|
|
|
25
|
-
const issue_schema = z.object({
|
|
30
|
+
const issue_schema = z.object({
|
|
31
|
+
state: z.string().nullish(),
|
|
32
|
+
labels: z.array(issue_label_schema),
|
|
33
|
+
body: z.string().nullish(),
|
|
34
|
+
})
|
|
26
35
|
|
|
27
36
|
interface IssueRead {
|
|
37
|
+
is_closed: boolean
|
|
28
38
|
labels: ReadonlyArray<string>
|
|
29
39
|
body: string
|
|
30
40
|
}
|
|
@@ -35,7 +45,21 @@ async function read_issue(issue: string): Promise<IssueRead | undefined> {
|
|
|
35
45
|
|
|
36
46
|
if (parsed === undefined) return undefined
|
|
37
47
|
|
|
38
|
-
return {
|
|
48
|
+
return {
|
|
49
|
+
is_closed: parsed.state === CLOSED_STATE,
|
|
50
|
+
labels: parsed.labels.map((label) => label.name),
|
|
51
|
+
body: parsed.body ?? '',
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Why an apply has nothing to write: a closed issue is past the pool, and one already opted in was
|
|
56
|
+
// judged once — writing again would repeat the comment (joshuafolkken/kit#4097).
|
|
57
|
+
function settled_of(read: IssueRead): string | undefined {
|
|
58
|
+
if (read.is_closed) return 'the issue is closed'
|
|
59
|
+
|
|
60
|
+
return has_label_name(read.labels, AUTO_OK_LABEL)
|
|
61
|
+
? `\`${AUTO_OK_LABEL}\` is already applied`
|
|
62
|
+
: undefined
|
|
39
63
|
}
|
|
40
64
|
|
|
41
65
|
async function apply_labels(issue: string, run_label: string): Promise<string | undefined> {
|
|
@@ -74,18 +98,15 @@ async function apply_to(issue: string, run_label: string, read: IssueRead): Prom
|
|
|
74
98
|
|
|
75
99
|
if (exclusion !== undefined) return refused(issue, issue_auto_ok.line_of(exclusion))
|
|
76
100
|
|
|
77
|
-
const problem = await apply_labels(issue, run_label)
|
|
78
|
-
|
|
79
|
-
if (problem !== undefined) return refused(issue, problem)
|
|
80
|
-
|
|
81
101
|
const reason = `judged by backlogrun: no exclusion holds and no person's judgement is needed (${run_label})`
|
|
82
102
|
|
|
83
|
-
await
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
103
|
+
if ((await record(issue, { is_applied: true, reason }, read.body)) !== SUCCESS_EXIT_CODE) {
|
|
104
|
+
return FAILURE_EXIT_CODE
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const problem = await apply_labels(issue, run_label)
|
|
87
108
|
|
|
88
|
-
return
|
|
109
|
+
return problem === undefined ? SUCCESS_EXIT_CODE : refused(issue, `${problem}; ${RETRY_HINT}`)
|
|
89
110
|
}
|
|
90
111
|
|
|
91
112
|
async function apply(issue: string, run_label: string): Promise<number> {
|
|
@@ -93,7 +114,13 @@ async function apply(issue: string, run_label: string): Promise<number> {
|
|
|
93
114
|
|
|
94
115
|
if (read === undefined) return refused(issue, UNREADABLE)
|
|
95
116
|
|
|
96
|
-
|
|
117
|
+
const settled = settled_of(read)
|
|
118
|
+
|
|
119
|
+
if (settled === undefined) return await apply_to(issue, run_label, read)
|
|
120
|
+
|
|
121
|
+
console.info(`${session_cite.issue(issue)}: nothing to apply — ${settled}`)
|
|
122
|
+
|
|
123
|
+
return SUCCESS_EXIT_CODE
|
|
97
124
|
}
|
|
98
125
|
|
|
99
126
|
async function decline(issue: string, reason: string): Promise<number> {
|
|
@@ -14,11 +14,16 @@ import type { WatchComment } from '#scripts/issue/issue-watch-diff'
|
|
|
14
14
|
// **The record is the judgement comment itself.** It carries a digest of the body it judged, so an
|
|
15
15
|
// issue is judged again only when its body changed or a person commented after it — the same line
|
|
16
16
|
// `issue_watch_diff` draws between a person's update and an automated one.
|
|
17
|
+
//
|
|
18
|
+
// **Only an author with write access is read** (`gh_author_association`, joshuafolkken/kit#4021): an
|
|
19
|
+
// issue anyone else filed is never a candidate, and a judgement comment or a later comment from anyone
|
|
20
|
+
// else is not counted, so a third party can neither opt an issue in nor mark one judged.
|
|
17
21
|
|
|
18
22
|
interface JudgeIssue {
|
|
19
23
|
number: number
|
|
20
24
|
labels: ReadonlyArray<string>
|
|
21
25
|
body: string
|
|
26
|
+
is_trusted: boolean
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
const MARKER_PREFIX = '<!-- josh:auto-ok-judged body='
|
|
@@ -29,7 +34,7 @@ const CRLF = '\r\n'
|
|
|
29
34
|
const LF = '\n'
|
|
30
35
|
|
|
31
36
|
function is_candidate(issue: JudgeIssue): boolean {
|
|
32
|
-
if (has_label_name(issue.labels, AUTO_OK_LABEL)) return false
|
|
37
|
+
if (!issue.is_trusted || has_label_name(issue.labels, AUTO_OK_LABEL)) return false
|
|
33
38
|
|
|
34
39
|
return issue_auto_ok.exclusion_of(issue.labels) === undefined
|
|
35
40
|
}
|
|
@@ -42,9 +47,15 @@ function body_digest(body: string): string {
|
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
function digest_of(comment: WatchComment): string | undefined {
|
|
50
|
+
if (!comment.is_trusted) return undefined
|
|
51
|
+
|
|
45
52
|
return MARKER_PATTERN.exec(comment.body)?.groups?.['digest']
|
|
46
53
|
}
|
|
47
54
|
|
|
55
|
+
function is_person_comment(comment: WatchComment): boolean {
|
|
56
|
+
return comment.is_trusted === true && !comment.is_automated
|
|
57
|
+
}
|
|
58
|
+
|
|
48
59
|
// Judged when the newest judgement comment covers the body as it stands and no person has commented
|
|
49
60
|
// since. A failed comment read never reaches here — the caller treats it as nothing learned.
|
|
50
61
|
function is_judged(body: string, comments: ReadonlyArray<WatchComment>): boolean {
|
|
@@ -52,7 +63,7 @@ function is_judged(body: string, comments: ReadonlyArray<WatchComment>): boolean
|
|
|
52
63
|
|
|
53
64
|
if (judgement === undefined || digest_of(judgement) !== body_digest(body)) return false
|
|
54
65
|
|
|
55
|
-
return comments.every((comment) => comment.id <= judgement.id || comment
|
|
66
|
+
return comments.every((comment) => comment.id <= judgement.id || !is_person_comment(comment))
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
function comment_of(decision: AutoOkDecision, body: string): string {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { auto_ok_cli } from './auto-ok-cli'
|
|
4
|
+
|
|
5
|
+
// The `josh auto-ok:next` entry, kept apart from `auto-ok-cli.ts` because other modules import that
|
|
6
|
+
// one: a bundle is one file, so a main guard there would fire for every command that carries it
|
|
7
|
+
// (joshuafolkken/kit#4186).
|
|
8
|
+
//
|
|
9
|
+
// `process.exitCode` rather than `process.exit()`: the answer is written with `console.info`, and on
|
|
10
|
+
// macOS a write to a pipe is asynchronous — `process.exit()` can tear the process down before it has
|
|
11
|
+
// drained, and this command's whole contract is `answer=$(pnpm josh auto-ok:next)`. The same shape
|
|
12
|
+
// is already in `scripts/cost-runtime/cost-main.ts`, which met the truncation first.
|
|
13
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
14
|
+
const ARGV_OFFSET = 2
|
|
15
|
+
|
|
16
|
+
process.exitCode = await auto_ok_cli.run(process.argv.slice(ARGV_OFFSET))
|
|
17
|
+
}
|
|
@@ -7,11 +7,12 @@ import { backlog_arrival_added } from './backlog-arrival-added'
|
|
|
7
7
|
import { backlog_next } from './backlog-next'
|
|
8
8
|
import { backlog_ready, type ReadyPorts, type ReadyReading } from './backlog-ready'
|
|
9
9
|
import { backlog_stalled } from './backlog-stalled'
|
|
10
|
+
import { backlog_stalled_detect } from './backlog-stalled-detect'
|
|
10
11
|
|
|
11
12
|
// The arrival probe a `backlogrun` parent's `--wait` watcher runs while children are in flight.
|
|
12
13
|
// Without it, an issue opted in with `auto-ok` mid-run is picked up only when the parent
|
|
13
14
|
// next wakes — a child's merge, or the progress interval — so in practice the ten-minute stall detector
|
|
14
|
-
// becomes the pick-up,
|
|
15
|
+
// becomes the pick-up, ten minutes late.
|
|
15
16
|
//
|
|
16
17
|
// **The watcher's exit is the only thing that wakes a live parent**, so the probe rides it: once a
|
|
17
18
|
// minute it reads the backlog the pick-up line reads (`backlog_ready.read_ready`, cheap first — a full
|
|
@@ -66,15 +67,18 @@ async function bounded_ready_issues(): Promise<ReadonlyArray<string>> {
|
|
|
66
67
|
return answered_issues(await backlog_ready.read_backlog_next(COMMAND_TIMEOUT_MS))
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
// The backlog reads,
|
|
70
|
+
// The backlog reads, whether `run:add` handed the run an issue since a given instant, and the stall
|
|
71
|
+
// detector's record of whether work and a free lane coexist (joshuafolkken/kit#4349).
|
|
70
72
|
interface ArrivalPorts extends ReadyPorts {
|
|
71
73
|
is_added_since: (since_ms: number) => Promise<boolean>
|
|
74
|
+
observe_offerable: (is_offerable: boolean) => Promise<void>
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
const ARRIVAL_PORTS: ArrivalPorts = {
|
|
75
78
|
free_lane_count: backlog_ready.free_lane_count,
|
|
76
79
|
ready_issues: bounded_ready_issues,
|
|
77
80
|
is_added_since: backlog_arrival_added.is_added_since,
|
|
81
|
+
observe_offerable: backlog_stalled_detect.observe_offerable,
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
interface ArrivalProbe {
|
|
@@ -94,6 +98,11 @@ function arrivals(
|
|
|
94
98
|
return is_raised ? reading.issues : reading.issues.filter((issue) => !baseline.has(issue))
|
|
95
99
|
}
|
|
96
100
|
|
|
101
|
+
// The stall detector's condition, off the reading the probe already made.
|
|
102
|
+
function is_offerable(reading: ReadyReading): boolean {
|
|
103
|
+
return reading.issues.length > NONE && reading.free_lanes > NO_FREE
|
|
104
|
+
}
|
|
105
|
+
|
|
97
106
|
// The baseline is the whole runnable pool, free lane or not: an issue that was waiting for a lane is not
|
|
98
107
|
// new when one frees, and the child's merge that freed it already wakes the parent.
|
|
99
108
|
//
|
|
@@ -149,7 +158,7 @@ async function retry_baseline(
|
|
|
149
158
|
function pool_probe_of(
|
|
150
159
|
initial: ReadonlySet<string> | undefined,
|
|
151
160
|
first_ms: number,
|
|
152
|
-
ports:
|
|
161
|
+
ports: ArrivalPorts,
|
|
153
162
|
is_raised: () => boolean,
|
|
154
163
|
): ArrivalProbe {
|
|
155
164
|
let next_ms = first_ms
|
|
@@ -168,6 +177,8 @@ function pool_probe_of(
|
|
|
168
177
|
|
|
169
178
|
const reading = await read_reading(ports)
|
|
170
179
|
|
|
180
|
+
if (reading !== undefined) await ports.observe_offerable(is_offerable(reading))
|
|
181
|
+
|
|
171
182
|
return reading !== undefined && arrivals(baseline, reading, is_raised()).length > NONE
|
|
172
183
|
}
|
|
173
184
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
import { fileURLToPath } from 'node:url'
|
|
3
1
|
import { path_decision } from '#scripts/josh/path-decision'
|
|
4
2
|
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
3
|
+
import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
|
|
5
4
|
import {
|
|
6
5
|
backlog_budget,
|
|
7
6
|
type BacklogAnswer,
|
|
@@ -13,7 +12,6 @@ import {
|
|
|
13
12
|
// command line, hand it to the pure decision, print the verdict on stdout and the reason on stderr
|
|
14
13
|
// through the printer every mechanically-decided command in this repository already shares.
|
|
15
14
|
|
|
16
|
-
const ARGV_OFFSET = 2
|
|
17
15
|
const SUCCESS_EXIT_CODE = 0
|
|
18
16
|
const FAILURE_EXIT_CODE = 1
|
|
19
17
|
const JSON_KEY = 'budget'
|
|
@@ -54,19 +52,6 @@ function to_time_ms(raw: string | undefined): number | undefined {
|
|
|
54
52
|
return Number.isNaN(parsed) ? undefined : parsed
|
|
55
53
|
}
|
|
56
54
|
|
|
57
|
-
// Digits and nothing else. `Number('')`, `Number(' ')` and `Number('0x10')` are all safe integers, so
|
|
58
|
-
// a check that only asked `Number.isSafeInteger` would read an unset shell variable — `--max
|
|
59
|
-
// "$max_issues"` — as a maximum of zero and finish the run having done nothing.
|
|
60
|
-
const COUNT_PATTERN = /^\d+$/u
|
|
61
|
-
|
|
62
|
-
function to_count(raw: string | undefined): number | undefined {
|
|
63
|
-
if (raw === undefined || !COUNT_PATTERN.test(raw)) return undefined
|
|
64
|
-
|
|
65
|
-
const parsed = Number(raw)
|
|
66
|
-
|
|
67
|
-
return Number.isSafeInteger(parsed) ? parsed : undefined
|
|
68
|
-
}
|
|
69
|
-
|
|
70
55
|
// A flag that was given but could not be read makes the whole invocation unreadable. Falling back to
|
|
71
56
|
// the default instead would answer a question nobody asked — a mistyped `--idle 0` would read as the
|
|
72
57
|
// default watch and hold a run open that was asked to finish at its first empty backlog.
|
|
@@ -80,10 +65,10 @@ type Counts = Record<(typeof COUNT_NAMES)[number], number | undefined>
|
|
|
80
65
|
|
|
81
66
|
function counts_of(values: ParsedValues): Counts {
|
|
82
67
|
return {
|
|
83
|
-
idle: to_count(cli_flags.string_of(values.idle)),
|
|
84
|
-
max: to_count(cli_flags.string_of(values.max)),
|
|
85
|
-
merged: to_count(cli_flags.string_of(values.merged)),
|
|
86
|
-
running: to_count(cli_flags.string_of(values.running)),
|
|
68
|
+
idle: cli_flags.to_count(cli_flags.string_of(values.idle)),
|
|
69
|
+
max: cli_flags.to_count(cli_flags.string_of(values.max)),
|
|
70
|
+
merged: cli_flags.to_count(cli_flags.string_of(values.merged)),
|
|
71
|
+
running: cli_flags.to_count(cli_flags.string_of(values.running)),
|
|
87
72
|
}
|
|
88
73
|
}
|
|
89
74
|
|
|
@@ -102,7 +87,7 @@ function to_idle_ms(idle_minutes: number | undefined): number | undefined {
|
|
|
102
87
|
if (idle_minutes === undefined) return backlog_budget.DEFAULT_IDLE_MS
|
|
103
88
|
if (idle_minutes === NO_IDLE_MINUTES) return undefined
|
|
104
89
|
|
|
105
|
-
return idle_minutes *
|
|
90
|
+
return idle_minutes * MS_PER_MINUTE
|
|
106
91
|
}
|
|
107
92
|
|
|
108
93
|
// An idle watch measured from the run's start is not the watch that was asked for. A run already
|
|
@@ -117,7 +102,7 @@ function to_idle_ms(idle_minutes: number | undefined): number | undefined {
|
|
|
117
102
|
// lands on the very first ask, before the run has started anything, and the fix is one flag the loop
|
|
118
103
|
// already holds: it always knows when it last had work.
|
|
119
104
|
function is_watch_readable(values: ParsedValues): boolean {
|
|
120
|
-
if (to_idle_ms(to_count(cli_flags.string_of(values.idle))) === undefined) return true
|
|
105
|
+
if (to_idle_ms(cli_flags.to_count(cli_flags.string_of(values.idle))) === undefined) return true
|
|
121
106
|
|
|
122
107
|
return cli_flags.string_of(values.active) !== undefined
|
|
123
108
|
}
|
|
@@ -197,28 +182,17 @@ function run(argv: ReadonlyArray<string>, now_ms: number = Date.now()): number {
|
|
|
197
182
|
return SUCCESS_EXIT_CODE
|
|
198
183
|
}
|
|
199
184
|
|
|
200
|
-
// `process.exitCode` rather than `process.exit()`, for the reason `backlog:next` records: the whole
|
|
201
|
-
// contract is `answer=$(pnpm josh backlog:budget …)`, and exiting outright can cut the pipe before it
|
|
202
|
-
// has drained.
|
|
203
|
-
function main(argv: ReadonlyArray<string>): void {
|
|
204
|
-
process.exitCode = run(argv)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
185
|
const backlog_budget_cli = {
|
|
208
186
|
JSON_KEY,
|
|
209
187
|
OPTIONS,
|
|
210
188
|
SUCCESS_EXIT_CODE,
|
|
211
189
|
USAGE,
|
|
212
190
|
build_input,
|
|
213
|
-
main,
|
|
214
191
|
read_arguments,
|
|
215
192
|
run,
|
|
216
193
|
to_answer,
|
|
217
|
-
to_count,
|
|
218
194
|
to_time_ms,
|
|
219
195
|
}
|
|
220
196
|
|
|
221
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
|
|
222
|
-
|
|
223
197
|
export { backlog_budget_cli }
|
|
224
198
|
export type { ParsedValues }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { backlog_budget_cli } from './backlog-budget-cli'
|
|
4
|
+
|
|
5
|
+
// The `josh backlog:budget` entry, kept apart from `backlog-budget-cli.ts` because other modules
|
|
6
|
+
// import that one: a bundle is one file, so a main guard there would fire for every command that
|
|
7
|
+
// carries it (joshuafolkken/kit#4186).
|
|
8
|
+
//
|
|
9
|
+
// `process.exitCode` rather than `process.exit()`, for the reason `backlog:next` records: the whole
|
|
10
|
+
// contract is `answer=$(pnpm josh backlog:budget …)`, and exiting outright can cut the pipe before it
|
|
11
|
+
// has drained.
|
|
12
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
13
|
+
const ARGV_OFFSET = 2
|
|
14
|
+
|
|
15
|
+
process.exitCode = backlog_budget_cli.run(process.argv.slice(ARGV_OFFSET))
|
|
16
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { MS_PER_MINUTE, MS_PER_SECOND } from '#scripts/lib/timeouts'
|
|
2
|
+
|
|
1
3
|
// `josh backlog:budget` — whether a `backlogrun` may start more work, keep watching, or finish.
|
|
2
4
|
//
|
|
3
5
|
// `backlog:next` says what may start; it says nothing about when the run itself should end. Without
|
|
@@ -17,7 +19,6 @@
|
|
|
17
19
|
// and `josh review:level` are commands: a count and an elapsed time kept in an agent's head are a
|
|
18
20
|
// one-shot judgement — a threshold asked once and then never again while the run walks past it.
|
|
19
21
|
|
|
20
|
-
const MS_PER_MINUTE = 60_000
|
|
21
22
|
const MINUTES_PER_HOUR = 60
|
|
22
23
|
|
|
23
24
|
// **How long a run with nothing to do waits, and the only time bound a run has.** It is counted from
|
|
@@ -34,7 +35,6 @@ const DEFAULT_IDLE_MS = DEFAULT_IDLE_MINUTES * MS_PER_MINUTE
|
|
|
34
35
|
// once, without waiting it out. `backlogrun-progress.md` → "Waiting, and never waiting forever" holds
|
|
35
36
|
// the row; the figure is here because `idle_watch_reason` below has to say it.
|
|
36
37
|
const OFFER_INTERVAL_SECONDS = 60
|
|
37
|
-
const MS_PER_SECOND = 1000
|
|
38
38
|
const OFFER_INTERVAL_MS = OFFER_INTERVAL_SECONDS * MS_PER_SECOND
|
|
39
39
|
|
|
40
40
|
const RUN_VERDICT = 'run'
|
|
@@ -231,7 +231,6 @@ const backlog_budget = {
|
|
|
231
231
|
DEFAULT_IDLE_MINUTES,
|
|
232
232
|
DEFAULT_IDLE_MS,
|
|
233
233
|
IDLE_WAIT_HOURS,
|
|
234
|
-
MS_PER_MINUTE,
|
|
235
234
|
OFFER_INTERVAL_MS,
|
|
236
235
|
RUN_VERDICT,
|
|
237
236
|
STOP_VERDICT,
|
|
@@ -18,10 +18,11 @@ function above_message(measured: DefectRate): string {
|
|
|
18
18
|
return `The defect rate ${defect_rate.rate_text(measured)} is above its baseline ${String(defect_rate.BASELINE_RATE)}, so defects are offered first and new mechanisms last.`
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
//
|
|
22
|
-
//
|
|
21
|
+
// The body the listing already carried, else one read for it (joshuafolkken/kit#4550). An unreadable
|
|
22
|
+
// body reads as empty: the labels still classify `route:interrupt`, and anything else keeps its usual
|
|
23
|
+
// place rather than being deferred on a read that failed.
|
|
23
24
|
async function kind_of_child(child: EpicChild): Promise<IssueKind> {
|
|
24
|
-
const body = await git_gh_command.issue_get_body(String(child.number), child.repo)
|
|
25
|
+
const body = child.body ?? (await git_gh_command.issue_get_body(String(child.number), child.repo))
|
|
25
26
|
|
|
26
27
|
return defect_rate.kind_of({ body: body ?? '', labels: child.labels })
|
|
27
28
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
2
|
+
import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
|
|
3
|
+
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
4
|
+
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
5
|
+
import type { DrivePorts, DriveState } from './backlog-drive'
|
|
6
|
+
import { backlog_drive_restore } from './backlog-drive-restore'
|
|
7
|
+
|
|
8
|
+
// **A lane the drive did not launch is still the run's to collect** (joshuafolkken/kit#4373). The loop
|
|
9
|
+
// held only the lanes it was seeded with and the ones it launched, so a child the parent dispatched
|
|
10
|
+
// itself with `lane:launch` — an interrupt in a named run — finished, merged and was never handed to
|
|
11
|
+
// `run:merge`: no `merge` event and no collected lane until `run:carry --end`, 91 minutes later. The
|
|
12
|
+
// stop was `run_pass` collecting only `state.in_flight` (`backlog-drive.ts`), seeded once at start
|
|
13
|
+
// (`backlog-drive-cli.ts` `seeded_lanes`). Adopted, a child that ends with its pull request unmerged
|
|
14
|
+
// is classified `failed` by `run:merge` (`run-merge.ts` `unfinished_outcome`), which puts it on the
|
|
15
|
+
// stream as a park with its cause (`run-merge-cli.ts` `on_parked_failure`) — the reason a lane left
|
|
16
|
+
// unmerged is recorded.
|
|
17
|
+
|
|
18
|
+
// The open lanes on a child this run launched and never settled — what the drive adopts while it runs
|
|
19
|
+
// and `run:carry --end` collects once it has stopped.
|
|
20
|
+
async function active_lanes(): Promise<ReadonlyArray<LaneInfo>> {
|
|
21
|
+
const active = backlog_drive_restore.active_issues(await run_event_stream_emit.current_events())
|
|
22
|
+
const lanes = await lane_registry.list_lanes()
|
|
23
|
+
|
|
24
|
+
return lanes.filter((lane) => !lane.is_stranded && active.has(lane.issue))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function adopted_note(issue: string): string {
|
|
28
|
+
return `${issue_cite.plain(issue)} adopted by backlog:drive: its lane was launched outside the loop`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function note_adopted(issue: string): Promise<void> {
|
|
32
|
+
await run_event_stream_emit.emit(run_event_stream.EVENT_KIND.NOTE, adopted_note(issue))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// The active lanes the loop does not hold, each put on the stream with why it is adopted.
|
|
36
|
+
async function adoptable(in_flight: ReadonlyArray<string>): Promise<ReadonlyArray<string>> {
|
|
37
|
+
const lanes = await active_lanes()
|
|
38
|
+
const issues = lanes.map((lane) => lane.issue).filter((issue) => !in_flight.includes(issue))
|
|
39
|
+
|
|
40
|
+
await Promise.all(
|
|
41
|
+
issues.map(async (issue) => {
|
|
42
|
+
await note_adopted(issue)
|
|
43
|
+
}),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
return issues
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The state with every adoptable lane in flight, so its child is collected as soon as it ends. Asked on
|
|
50
|
+
// an offered pass only, not every poll: the read walks the run's whole event stream. A stopping run
|
|
51
|
+
// adopts nothing: the child whose unparked failure stopped it left the stream unsettled, so adopting
|
|
52
|
+
// would collect — and count — it again.
|
|
53
|
+
async function held(
|
|
54
|
+
state: DriveState,
|
|
55
|
+
should_offer: boolean,
|
|
56
|
+
ports: Pick<DrivePorts, 'adoptable'>,
|
|
57
|
+
): Promise<DriveState> {
|
|
58
|
+
if (!should_offer || state.is_stopping) return state
|
|
59
|
+
|
|
60
|
+
const adopting = await ports.adoptable(state.in_flight)
|
|
61
|
+
|
|
62
|
+
return adopting.length === 0 ? state : { ...state, in_flight: [...state.in_flight, ...adopting] }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const backlog_drive_adopt = { active_lanes, adoptable, held }
|
|
66
|
+
|
|
67
|
+
export { backlog_drive_adopt }
|