@joshuafolkken/kit 1.1471.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 +6 -6
- package/.claude/skills/epic-commands/SKILL.md +26 -77
- package/.claude/skills/epic-commands/epic-bundle.md +12 -6
- package/.claude/skills/epic-commands/execution-waves.md +1 -2
- package/.claude/skills/verify-ui/SKILL.md +1 -2
- package/.claude/skills/workflow-commands/SKILL.md +12 -14
- package/.claude/skills/workflow-commands/background-commands.md +8 -12
- package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
- package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
- package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
- package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
- package/.claude/skills/workflow-commands/backlogrun.md +32 -51
- package/.claude/skills/workflow-commands/chain-rule.md +18 -11
- package/.claude/skills/workflow-commands/delegation.md +13 -8
- package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
- package/.claude/skills/workflow-commands/followup.md +10 -35
- package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
- package/.claude/skills/workflow-commands/fullrun.md +6 -8
- package/.claude/skills/workflow-commands/halfrun.md +20 -32
- package/.claude/skills/workflow-commands/into-target.md +1 -2
- package/.claude/skills/workflow-commands/issue-comments.md +19 -15
- package/.claude/skills/workflow-commands/issue-scout.md +5 -4
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +9 -18
- package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
- package/.claude/skills/workflow-commands/observation-filing.md +4 -50
- package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
- package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
- package/.claude/skills/workflow-commands/prerequisite.md +11 -18
- package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
- package/.claude/skills/workflow-commands/prrun.md +6 -12
- package/.claude/skills/workflow-commands/retrospective.md +5 -5
- package/.claude/skills/workflow-commands/split-assessment.md +14 -4
- package/.claude/skills/workflow-commands/target-repository.md +1 -2
- package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
- package/.codex/hooks.json +6 -6
- package/.github/actions/setup-node/action.yml +10 -1
- 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 +121 -11
- package/.github/workflows/publish.yml +10 -3
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +4 -8
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/cspell/index.yaml +7 -0
- package/dist/CLAUDE.md +4 -8
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
- 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-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
- package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -19
- package/dist/hooks/format-edited.js +5 -5
- package/dist/hooks/inputs.json +436 -257
- package/dist/hooks/pretool-guard.js +7 -22
- package/dist/hooks/session-lang.js +380 -42
- package/dist/hooks/stop-guard.js +8711 -782
- package/dist/josh.js +5263 -997
- 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 +8 -4
- package/package.json +17 -53
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -9
- package/prompts/collaboration-workflow/gh-rest.md +1 -2
- package/prompts/collaboration-workflow/issue-citation.md +2 -4
- package/prompts/collaboration-workflow/issue-template.md +42 -17
- package/prompts/collaboration-workflow/lane-instructions.md +34 -0
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +6 -12
- package/prompts/collaboration-workflow/output-bounds.md +4 -9
- package/prompts/collaboration-workflow/overview.md +1 -1
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +19 -8
- package/prompts/collaboration-workflow/report-format.md +37 -57
- package/prompts/collaboration-workflow/residency.md +12 -8
- package/prompts/collaboration-workflow/rule-delivery.md +3 -11
- package/prompts/collaboration-workflow/shell-body.md +8 -18
- package/prompts/collaboration-workflow/turn-batching.md +4 -6
- package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
- package/prompts/collaboration-workflow/wip-cap.md +7 -7
- package/prompts/collaboration-workflow.md +4 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +45 -26
- package/prompts/testing-guide.md +10 -45
- package/scripts/agent/agent-argv.ts +20 -4
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/agent-role-profile.ts +101 -45
- package/scripts/agent/agent-safe-text.ts +60 -0
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/claude-agent-argv.ts +14 -0
- package/scripts/agent/codex-agent-argv.ts +2 -0
- package/scripts/agent/lane-instructions.ts +144 -0
- 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 +6 -7
- 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 +54 -7
- 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 +39 -8
- 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 +69 -0
- 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 +137 -18
- 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 +2 -10
- package/scripts/delegation/investigation-guard.ts +15 -73
- package/scripts/delegation/investigation-reads.ts +3 -5
- 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 +9 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +17 -13
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/document/entry-read-budget.ts +2 -2
- package/scripts/document/read-set-cli.ts +4 -1
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-audit-orphans.ts +5 -8
- package/scripts/epic/epic-audit.ts +52 -1
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-evidence.ts +49 -26
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-bundle-referenced.ts +14 -3
- package/scripts/epic/epic-bundle.ts +17 -9
- 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 +31 -60
- 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 +73 -0
- package/scripts/gate/check-reuse.ts +141 -0
- 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 +150 -119
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +162 -0
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +72 -0
- package/scripts/gate/gate-ledger.ts +49 -7
- package/scripts/gate/gate-plan.ts +44 -15
- package/scripts/gate/gate-report.ts +29 -4
- package/scripts/gate/gate-run-steps.ts +195 -0
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/held-mark.ts +55 -0
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +124 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/pre-commit-type-check.ts +14 -1
- 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 +65 -129
- 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-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +77 -17
- 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/gh/git-pr.ts +13 -1
- 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 +78 -0
- package/scripts/git/main-merge.ts +39 -14
- 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 +5 -16
- 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 +118 -0
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +57 -69
- package/scripts/hooks/reserved-run.ts +67 -8
- package/scripts/hooks/run-hook.sh +18 -11
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +185 -0
- package/scripts/hooks/stop-guard.ts +72 -27
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -12
- 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 +60 -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 +33 -22
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +13 -8
- 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 +7 -13
- 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 +19 -25
- 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/markdown-section.ts +19 -5
- 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 +82 -0
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +6 -1
- package/scripts/josh/josh-command-types.ts +65 -13
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +169 -157
- 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 +31 -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 +112 -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 +149 -6
- package/scripts/josh/josh-logic.ts +11 -27
- package/scripts/josh/josh.ts +14 -5
- package/scripts/josh/package-directory.ts +18 -0
- 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 +19 -22
- package/scripts/lane/lane-check-stats.ts +97 -0
- package/scripts/lane/lane-child-invocation.ts +43 -4
- 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 +27 -6
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-guard-policy.ts +2 -2
- package/scripts/lane/lane-handoff.ts +76 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +16 -15
- 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 +108 -97
- package/scripts/lane/lane-limit-cli.ts +19 -9
- package/scripts/lane/lane-measure-cli.ts +58 -10
- 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-preserve.ts +29 -1
- 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 +33 -10
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +26 -27
- 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 +160 -0
- package/scripts/lane/lane-session-broker.ts +134 -134
- 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 +72 -0
- package/scripts/lane/lane-withdraw.ts +183 -0
- 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 +14 -5
- 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 +72 -33
- package/scripts/lint/lint-related-scope.ts +33 -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 +12 -11
- 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 +4 -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-check.ts +61 -0
- package/scripts/review/acceptance-map.ts +206 -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 +82 -16
- 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 +67 -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 +90 -3
- 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 +8 -0
- package/scripts/rules/firing-point.ts +6 -5
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +121 -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 +76 -7
- 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/last-prompt.ts +50 -5
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/oracle-list-cli.ts +7 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +4 -2
- 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 +12 -28
- package/scripts/rules/rule-rewrite.ts +114 -0
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +8 -2
- package/scripts/rules/shell-segments.ts +50 -0
- package/scripts/rules/stop-decision.ts +77 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +150 -51
- package/scripts/rules/tail-commands.ts +15 -1
- 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 -30
- package/scripts/run/board/run-board-closed.ts +8 -2
- 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 +119 -31
- package/scripts/run/board/run-board-header.ts +86 -21
- 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 +118 -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 +240 -61
- 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 +153 -13
- package/scripts/run/board/run-board-reason.ts +238 -45
- 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 -47
- 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 +125 -0
- package/scripts/run/board/run-board-render.ts +206 -259
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +10 -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 +23 -29
- package/scripts/run/board/run-board-status.ts +206 -79
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +123 -104
- 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-cli.ts +3 -2
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/cut/run-cut-report.ts +16 -0
- package/scripts/run/detached-launch.ts +23 -4
- package/scripts/run/entry/run-entry-cli.ts +8 -1
- 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 +7 -10
- package/scripts/run/event/run-event-scope.ts +20 -2
- package/scripts/run/event/run-event-stream-emit.ts +78 -11
- package/scripts/run/event/run-event-stream.ts +37 -7
- 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-hold-session.ts +46 -0
- package/scripts/run/hold/run-hold.ts +7 -1
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/launch-priority.ts +32 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +72 -107
- 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 +123 -0
- package/scripts/run/merge/run-merge-steps.ts +128 -83
- package/scripts/run/merge/run-merge.ts +53 -40
- 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 +61 -30
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-poll-hook.ts +157 -0
- 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-cli.ts +22 -15
- package/scripts/run/run-step-section.ts +85 -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 +67 -151
- package/scripts/run/ship/run-ship-detach.ts +27 -7
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +27 -3
- package/scripts/run/ship/run-ship-overlap.ts +232 -0
- 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 +102 -27
- package/scripts/run/ship/run-ship-preflight.ts +161 -30
- 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 +123 -15
- package/scripts/run/ship/run-ship-review-steps.ts +105 -149
- 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-context.ts +206 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +57 -12
- 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 +55 -6
- 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 +54 -21
- 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 +71 -137
- 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 +126 -14
- package/scripts/time-runtime/time-spans.ts +1 -0
- package/scripts/time-runtime/time-tool-call.ts +7 -0
- 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 +10 -3
- 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-43ZHT22P.js +0 -3495
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EUMACUK2.js +0 -2038
- package/dist/hooks/chunk-H5HVWYXK.js +0 -359
- package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
- package/dist/hooks/chunk-IX6TTTI6.js +0 -95
- package/dist/hooks/chunk-J47HU5H5.js +0 -237
- package/dist/hooks/chunk-K4EOONYM.js +0 -45
- package/dist/hooks/chunk-K4LMBQC2.js +0 -68
- package/dist/hooks/chunk-SHGPANFB.js +0 -56
- package/dist/hooks/chunk-YHBZAJSV.js +0 -79
- package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -32
- 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/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 -282
- package/scripts/rules/rule-registry.ts +0 -109
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto'
|
|
2
|
+
import { epic_audit_logic } from '#scripts/epic/epic-audit'
|
|
3
|
+
import { markdown_section } from '#scripts/issue/markdown-section'
|
|
4
|
+
import { session_cite } from '#scripts/issue/session-cite'
|
|
5
|
+
import { report_format_reference } from '#scripts/report/report-format-reference'
|
|
6
|
+
|
|
7
|
+
// A green gate and a clean review say the diff is sound, never that it delivers what the Issue asked
|
|
8
|
+
// for. **This is the seam where each acceptance criterion is checked one by one**: the pull request
|
|
9
|
+
// body carries one row per criterion — met, with its evidence, or deferred to a split-off issue — and
|
|
10
|
+
// `josh followup` re-reads the Issue just before the merge and refuses a criterion with no row.
|
|
11
|
+
//
|
|
12
|
+
// **A criterion is matched by an identifier built from its own text**, so a criterion added or
|
|
13
|
+
// reworded after the body was written has an identifier no row carries, and is refused as unmapped
|
|
14
|
+
// rather than passing on a stale row. The checkbox is stripped first: ticking it changes nothing.
|
|
15
|
+
//
|
|
16
|
+
// The criteria are read through `epic_audit_logic.acceptance_section`, the one place the acceptance
|
|
17
|
+
// headings are defined.
|
|
18
|
+
|
|
19
|
+
const MAP_HEADING = '## 受け入れ条件の対応'
|
|
20
|
+
const MET = '満たした'
|
|
21
|
+
const DEFERRED = '見送り'
|
|
22
|
+
const PENDING = '未記入'
|
|
23
|
+
const PENDING_SUFFIX = `— ${PENDING}`
|
|
24
|
+
const ID_PREFIX = 'ac-'
|
|
25
|
+
const ID_HEX_LENGTH = 8
|
|
26
|
+
const BACKTICK = '`'
|
|
27
|
+
// A top-level list item only: a nested item is detail under a criterion, not one of its own.
|
|
28
|
+
const CRITERION_PATTERN = /^(?:[-*+]|\d+\.)\s+(?:\[[ xX]\]\s+)?(?<text>\S.*)$/u
|
|
29
|
+
// A list item, heading, table row or HTML comment opens a block of its own, never a wrapped line.
|
|
30
|
+
const BLOCK_START_PATTERN = /^\s*(?:(?:[-*+]|\d+\.)\s|#|\||<!--)/u
|
|
31
|
+
// The criterion's text may sit between the identifier and the status for the reader, so the status is
|
|
32
|
+
// the last status word on the line — a criterion quoting the row format stays text.
|
|
33
|
+
const ROW_PATTERN = new RegExp(
|
|
34
|
+
String.raw`^[-*]\s+${BACKTICK}(?<id>${ID_PREFIX}[0-9a-f]{${String(ID_HEX_LENGTH)}})${BACKTICK}(?:\s.*)?\s(?<kind>${MET}|${DEFERRED}):\s*(?<rest>\S.*)$`,
|
|
35
|
+
'u',
|
|
36
|
+
)
|
|
37
|
+
// A deferral names the split-off issue first, then why it was deferred.
|
|
38
|
+
const DEFERRAL_PATTERN = /^(?<issue>(?:[\w.-]+\/[\w.-]+)?#\d+)\s+\S/u
|
|
39
|
+
const ROW_FORMAT = `under ${MAP_HEADING}, one line per acceptance criterion: \`- \`<id>\` <criterion> — ${MET}: <test name, file:line or command output>\` or \`- \`<id>\` <criterion> — ${DEFERRED}: #<split-off issue> <reason>\``
|
|
40
|
+
|
|
41
|
+
interface Criterion {
|
|
42
|
+
id: string
|
|
43
|
+
text: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface Deferral {
|
|
47
|
+
id: string
|
|
48
|
+
issue: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface Row {
|
|
52
|
+
id: string
|
|
53
|
+
kind: string
|
|
54
|
+
rest: string
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface MapRows {
|
|
58
|
+
met: ReadonlySet<string>
|
|
59
|
+
deferrals: ReadonlyArray<Deferral>
|
|
60
|
+
ids: ReadonlySet<string>
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface MapComparison {
|
|
64
|
+
missing: ReadonlyArray<Criterion>
|
|
65
|
+
deferrals: ReadonlyArray<Deferral>
|
|
66
|
+
stale: ReadonlyArray<string>
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function criterion_id(text: string): string {
|
|
70
|
+
const normalized = text.replaceAll(/\s+/gu, ' ').trim()
|
|
71
|
+
const digest = createHash('sha256').update(normalized).digest('hex')
|
|
72
|
+
|
|
73
|
+
return `${ID_PREFIX}${digest.slice(0, ID_HEX_LENGTH)}`
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function joins(last: string | undefined, line: string): boolean {
|
|
77
|
+
const is_continuation = line.trim() !== '' && !BLOCK_START_PATTERN.test(line)
|
|
78
|
+
|
|
79
|
+
return is_continuation && last !== undefined && CRITERION_PATTERN.test(last)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// A criterion wrapped onto continuation lines is one criterion, hashed whole — rewording any of its
|
|
83
|
+
// lines changes its identifier. A blank line or a nested item ends it.
|
|
84
|
+
function unwrapped(lines: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
85
|
+
const items: Array<string> = []
|
|
86
|
+
|
|
87
|
+
for (const line of lines) {
|
|
88
|
+
items.push(joins(items.at(-1), line) ? `${items.pop() ?? ''} ${line.trim()}` : line)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return items
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function criteria_of(issue_body: string | undefined): ReadonlyArray<Criterion> {
|
|
95
|
+
// A list item inside a code fence is an example the Issue quotes, not a criterion. An indented line
|
|
96
|
+
// outside one is a wrapped criterion's continuation, so it is kept.
|
|
97
|
+
const lines = markdown_section.fence_free_lines(epic_audit_logic.acceptance_section(issue_body))
|
|
98
|
+
const texts = unwrapped(lines).map((line) => CRITERION_PATTERN.exec(line)?.groups?.['text'])
|
|
99
|
+
|
|
100
|
+
return texts
|
|
101
|
+
.filter((text): text is string => text !== undefined)
|
|
102
|
+
.map((text) => ({ id: criterion_id(text), text: text.trim() }))
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// A deferral row with no issue or no reason is no row at all, so its criterion reads as unmapped.
|
|
106
|
+
function deferral_of(id: string, rest: string): Deferral | undefined {
|
|
107
|
+
const issue = DEFERRAL_PATTERN.exec(rest)?.groups?.['issue']
|
|
108
|
+
|
|
109
|
+
return issue === undefined ? undefined : { id, issue }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Every group in `ROW_PATTERN` is mandatory, so a match always carries the name.
|
|
113
|
+
function group(groups: Readonly<Record<string, string>>, name: string): string {
|
|
114
|
+
return groups[name] ?? ''
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// A pending row is no row even when the criterion it quotes carries a status word — otherwise the
|
|
118
|
+
// skeleton's own unfilled row would read as met.
|
|
119
|
+
function row_of(line: string): Row | undefined {
|
|
120
|
+
const trimmed = line.trim()
|
|
121
|
+
|
|
122
|
+
if (trimmed.endsWith(PENDING_SUFFIX)) return undefined
|
|
123
|
+
const groups = ROW_PATTERN.exec(trimmed)?.groups
|
|
124
|
+
|
|
125
|
+
if (groups === undefined) return undefined
|
|
126
|
+
|
|
127
|
+
return { id: group(groups, 'id'), kind: group(groups, 'kind'), rest: group(groups, 'rest') }
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function rows_of(pr_body = ''): MapRows {
|
|
131
|
+
const rows = markdown_section
|
|
132
|
+
.section_lines(pr_body, MAP_HEADING)
|
|
133
|
+
.map((line) => row_of(line))
|
|
134
|
+
.filter((row): row is Row => row !== undefined)
|
|
135
|
+
const met = rows.filter((row) => row.kind === MET).map((row) => row.id)
|
|
136
|
+
const deferrals = rows
|
|
137
|
+
.filter((row) => row.kind === DEFERRED)
|
|
138
|
+
.map((row) => deferral_of(row.id, row.rest))
|
|
139
|
+
.filter((deferral): deferral is Deferral => deferral !== undefined)
|
|
140
|
+
|
|
141
|
+
return { met: new Set(met), deferrals, ids: new Set([...met, ...deferrals.map((row) => row.id)]) }
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function compare(criteria: ReadonlyArray<Criterion>, rows: MapRows): MapComparison {
|
|
145
|
+
const current = new Set(criteria.map((criterion) => criterion.id))
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
missing: criteria.filter((criterion) => !rows.ids.has(criterion.id)),
|
|
149
|
+
deferrals: rows.deferrals.filter((deferral) => current.has(deferral.id)),
|
|
150
|
+
stale: [...rows.ids].filter((id) => !current.has(id)),
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// What `josh pr` writes when the caller's body carries no table: every criterion as a pending row,
|
|
155
|
+
// which the merge refuses until it is filled in.
|
|
156
|
+
function skeleton(issue_body: string | undefined): string | undefined {
|
|
157
|
+
const criteria = criteria_of(issue_body)
|
|
158
|
+
|
|
159
|
+
if (criteria.length === 0) return undefined
|
|
160
|
+
const rows = criteria.map(
|
|
161
|
+
(criterion) => `- \`${criterion.id}\` ${criterion.text} ${PENDING_SUFFIX}`,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
return [MAP_HEADING, '', ...rows].join('\n')
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function has_map(pr_body = ''): boolean {
|
|
168
|
+
return markdown_section.has_unfenced_line(pr_body, MAP_HEADING)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function listed(title: string, lines: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
172
|
+
return lines.length === 0 ? [] : [title, ...lines.map((line) => ` ${line}`)]
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function refusal_message(
|
|
176
|
+
issue: string,
|
|
177
|
+
comparison: MapComparison,
|
|
178
|
+
absent: ReadonlyArray<string>,
|
|
179
|
+
): string {
|
|
180
|
+
return [
|
|
181
|
+
`The pull request body does not map every acceptance criterion of ${session_cite.issue(issue)} as it reads now, so the merge is refused.`,
|
|
182
|
+
...listed(
|
|
183
|
+
'Criteria with no row (added or reworded since the body was written, or never mapped):',
|
|
184
|
+
comparison.missing.map((criterion) => `- \`${criterion.id}\` ${criterion.text}`),
|
|
185
|
+
),
|
|
186
|
+
...listed('Deferral rows naming an issue that could not be found:', absent),
|
|
187
|
+
...listed('Rows naming no current criterion:', comparison.stale),
|
|
188
|
+
`Write ${ROW_FORMAT} — format: ${report_format_reference.pointer(report_format_reference.ACCEPTANCE_MAP_HEADING)}`,
|
|
189
|
+
'Write it into the `--body-file` before `josh ship`, or update an open PR with `gh api -X PATCH repos/{owner}/{repo}/pulls/<N> -F body=@<path>`, then re-run.',
|
|
190
|
+
].join('\n')
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const acceptance_map = {
|
|
194
|
+
MAP_HEADING,
|
|
195
|
+
compare,
|
|
196
|
+
criteria_of,
|
|
197
|
+
criterion_id,
|
|
198
|
+
has_map,
|
|
199
|
+
refusal_message,
|
|
200
|
+
ROW_FORMAT,
|
|
201
|
+
rows_of,
|
|
202
|
+
skeleton,
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export type { Criterion, Deferral, MapComparison }
|
|
206
|
+
export { acceptance_map }
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
4
|
+
import { change_base } from '#scripts/git/change-base'
|
|
5
|
+
import { changed_paths } from '#scripts/git/changed-paths'
|
|
6
|
+
import { git_command } from '#scripts/git/git-command'
|
|
7
|
+
import { test_declared_logic } from '#scripts/test/test-declared-logic'
|
|
8
|
+
import type { TypeScriptApi } from './comment-ranges'
|
|
9
|
+
import { removed_tests } from './removed-tests'
|
|
10
|
+
import { review_code_tree } from './review-code-tree'
|
|
11
|
+
import { test_titles } from './test-titles'
|
|
12
|
+
|
|
13
|
+
// The reads behind `removed_tests`: the change base, the test files changed since it, each one's text
|
|
14
|
+
// at the base and in the working tree, and the pull request body. Kept apart so the comparison stays
|
|
15
|
+
// pure.
|
|
16
|
+
//
|
|
17
|
+
// **The base is the tree's, through a merge in progress** (`change_base.resolved_through_merge`): the
|
|
18
|
+
// head side is the work tree, so a stopped merge of the default branch has already removed whatever
|
|
19
|
+
// tests the default branch removed, and measuring from `HEAD`'s older merge-base would list them as
|
|
20
|
+
// this change's own.
|
|
21
|
+
//
|
|
22
|
+
// **A base that cannot be resolved is a refusal, not a pass** — the tests it would have held are
|
|
23
|
+
// exactly what this gate exists to see. A file is read at the base only where the base holds it, so a
|
|
24
|
+
// failed `git show` throws rather than reading as a file that had no tests. TypeScript is an optional
|
|
25
|
+
// peer of this package (`review_code_tree.load_typescript`): a project without it has no titles to
|
|
26
|
+
// compare and merges as before.
|
|
27
|
+
|
|
28
|
+
const UNREADABLE_MESSAGE =
|
|
29
|
+
'Merge refused: the change base could not be resolved, so the tests this change removes could not be listed; re-run once `git merge-base` answers.'
|
|
30
|
+
|
|
31
|
+
function titles_in(api: TypeScriptApi, texts: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
32
|
+
return texts.flatMap((text) => test_titles.titles_of(api, text))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function base_texts(
|
|
36
|
+
base: string,
|
|
37
|
+
paths: ReadonlyArray<string>,
|
|
38
|
+
): Promise<ReadonlyArray<string>> {
|
|
39
|
+
const held = await changed_paths.read_held_at(base, paths)
|
|
40
|
+
|
|
41
|
+
return await Promise.all(
|
|
42
|
+
held.map(async (relative) => await git_command.show_file(`${base}:${relative}`)),
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// A test file the change deleted is absent from the tree, and every title it held reads as gone.
|
|
47
|
+
function tree_texts(root: string, paths: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
48
|
+
return paths
|
|
49
|
+
.map((relative) => path.join(root, relative))
|
|
50
|
+
.filter((absolute) => existsSync(absolute))
|
|
51
|
+
.map((absolute) => readFileSync(absolute, 'utf8'))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function read(): Promise<ReadonlyArray<string> | undefined> {
|
|
55
|
+
const base = await change_base.resolved_through_merge()
|
|
56
|
+
|
|
57
|
+
if (base === undefined) return undefined
|
|
58
|
+
const root = await git_command.repository_root()
|
|
59
|
+
const api = review_code_tree.load_typescript(root)
|
|
60
|
+
|
|
61
|
+
if (api === undefined) return []
|
|
62
|
+
const changed = await changed_paths.read_changed_since(base)
|
|
63
|
+
const paths = changed.filter((relative) => test_declared_logic.is_test_file(relative))
|
|
64
|
+
const before = titles_in(api, await base_texts(base, paths))
|
|
65
|
+
|
|
66
|
+
return removed_tests.removed(before, titles_in(api, tree_texts(root, paths)))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// `josh ship`'s preflight asks the body it is about to deliver, so a missing disposition stops it
|
|
70
|
+
// before the review rather than at the merge.
|
|
71
|
+
async function body_refusal(pr_body: string | undefined): Promise<string | undefined> {
|
|
72
|
+
const removed = await read()
|
|
73
|
+
|
|
74
|
+
if (removed === undefined) return UNREADABLE_MESSAGE
|
|
75
|
+
const left = removed_tests.undisposed(removed, pr_body)
|
|
76
|
+
|
|
77
|
+
return left.length === 0 ? undefined : removed_tests.refusal_message(left)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function refusal(branch_name: string): Promise<string | undefined> {
|
|
81
|
+
return await body_refusal(await git_gh_command.pr_get_body(branch_name))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const removed_tests_check = { body_refusal, read, refusal, UNREADABLE_MESSAGE }
|
|
85
|
+
|
|
86
|
+
export { removed_tests_check }
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { markdown_section } from '#scripts/issue/markdown-section'
|
|
2
|
+
import { report_format_reference } from '#scripts/report/report-format-reference'
|
|
3
|
+
import { test_titles } from './test-titles'
|
|
4
|
+
|
|
5
|
+
// A test is the record of a behavior, and a change that deletes one with no word of what replaced it
|
|
6
|
+
// loses that behavior silently: the gate stays green and the review reads only what is there
|
|
7
|
+
// (joshuafolkken/kit#4287, after #4171 dropped `lane_thresholds()` with the tests that guarded it).
|
|
8
|
+
// **This is the seam where a deleted test has to be accounted for**: every test the base had and the
|
|
9
|
+
// change no longer has is listed in the review brief, and the merge is refused until the pull request
|
|
10
|
+
// body names, for each, the test that replaced it or the Issue that retired its behavior.
|
|
11
|
+
//
|
|
12
|
+
// **A test that moved is not deleted.** Tests are compared by full name across every changed test
|
|
13
|
+
// file, so one moved to another file keeps its name. One moved under another `describe` keeps its own
|
|
14
|
+
// title, so a gone name is matched against an arrived name with the same title, one for one — a common
|
|
15
|
+
// title such as "returns undefined" deleted under one block is still listed when another block keeps
|
|
16
|
+
// its own copy.
|
|
17
|
+
|
|
18
|
+
const DISPOSITION_HEADING = '## 消えたテストの処置'
|
|
19
|
+
// The heading as a line of its own, never the mention of it inside a format hint.
|
|
20
|
+
const HEADING_LINE = new RegExp(String.raw`^${DISPOSITION_HEADING}[ \t]*$`, 'mu')
|
|
21
|
+
const REPLACED = '置き換え'
|
|
22
|
+
const RETIRED = '廃止'
|
|
23
|
+
const PENDING_SUFFIX = '— 未記入'
|
|
24
|
+
const BRIEF_HEADING = 'Removed tests'
|
|
25
|
+
// The title runs to the first backtick that a disposition follows, so a title holding backticks of its
|
|
26
|
+
// own — `it('reads the \`.each\` table')` — can still be disposed.
|
|
27
|
+
const ROW_PATTERN = new RegExp(
|
|
28
|
+
String.raw`^[-*]\s+\x60(?<title>.+?)\x60\s+—\s+(?<kind>${REPLACED}|${RETIRED}):\s*(?<rest>\S.*)$`,
|
|
29
|
+
'u',
|
|
30
|
+
)
|
|
31
|
+
// A retirement names the Issue that decided it first — an Issue or a plan comment on one — then why.
|
|
32
|
+
const RETIREMENT_PATTERN = /^(?:[\w.-]+\/[\w.-]+)?#\d+\s+\S/u
|
|
33
|
+
const ROW_FORMAT = `under ${DISPOSITION_HEADING}, one line per removed test: \`- \`<test>\` — ${REPLACED}: <the test that guards the behavior now>\` or \`- \`<test>\` — ${RETIRED}: #<Issue that retired the behavior> <reason>\``
|
|
34
|
+
|
|
35
|
+
function unique(titles: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
36
|
+
return [...new Set(titles)]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function leaf_counts(titles: ReadonlyArray<string>): Map<string, number> {
|
|
40
|
+
const counts = new Map<string, number>()
|
|
41
|
+
|
|
42
|
+
for (const title of titles) {
|
|
43
|
+
const leaf = test_titles.leaf_of(title)
|
|
44
|
+
|
|
45
|
+
counts.set(leaf, (counts.get(leaf) ?? 0) + 1)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return counts
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Spends one arrived name with the same title, so each arrival accounts for one departure only.
|
|
52
|
+
function is_moved(arrived: Map<string, number>, title: string): boolean {
|
|
53
|
+
const leaf = test_titles.leaf_of(title)
|
|
54
|
+
const left = arrived.get(leaf) ?? 0
|
|
55
|
+
|
|
56
|
+
if (left === 0) return false
|
|
57
|
+
arrived.set(leaf, left - 1)
|
|
58
|
+
|
|
59
|
+
return true
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function removed(base: ReadonlyArray<string>, head: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
63
|
+
const base_names = new Set(base)
|
|
64
|
+
const head_names = new Set(head)
|
|
65
|
+
const arrived = leaf_counts(unique(head).filter((title) => !base_names.has(title)))
|
|
66
|
+
|
|
67
|
+
return unique(base)
|
|
68
|
+
.filter((title) => !head_names.has(title))
|
|
69
|
+
.filter((title) => !is_moved(arrived, title))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// A retirement with no Issue is no row at all, so its test reads as undisposed.
|
|
73
|
+
function is_cited(groups: Readonly<Record<string, string>>): boolean {
|
|
74
|
+
return groups['kind'] === REPLACED || RETIREMENT_PATTERN.test(groups['rest'] ?? '')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function disposed_title(line: string): string | undefined {
|
|
78
|
+
const groups = ROW_PATTERN.exec(line.trim())?.groups
|
|
79
|
+
|
|
80
|
+
if (groups === undefined || !is_cited(groups)) return undefined
|
|
81
|
+
|
|
82
|
+
return groups['title']
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function undisposed(removed_titles: ReadonlyArray<string>, pr_body = ''): ReadonlyArray<string> {
|
|
86
|
+
const disposed = new Set(
|
|
87
|
+
markdown_section
|
|
88
|
+
.section_lines(pr_body, DISPOSITION_HEADING)
|
|
89
|
+
.map((line) => disposed_title(line)),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
return removed_titles.filter((title) => !disposed.has(title))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function pending_rows(titles: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
96
|
+
return titles.map((title) => `- \`${title}\` ${PENDING_SUFFIX}`)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function has_row(lines: ReadonlyArray<string>, title: string): boolean {
|
|
100
|
+
return lines.some((line) => line.trim().startsWith(`- \`${title}\` `))
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// The pending rows a body still lacks, put under its disposition heading — added at the end when the
|
|
104
|
+
// body has none — so a run fills them in before `josh ship` rather than meeting them at its preflight
|
|
105
|
+
// (joshuafolkken/kit#4563). A title with any row already, pending or filled, is left as it is.
|
|
106
|
+
function with_pending_rows(body: string, titles: ReadonlyArray<string>): string {
|
|
107
|
+
const lines = markdown_section.section_lines(body, DISPOSITION_HEADING)
|
|
108
|
+
const rows = pending_rows(titles.filter((title) => !has_row(lines, title))).join('\n')
|
|
109
|
+
|
|
110
|
+
if (rows === '') return body
|
|
111
|
+
if (!HEADING_LINE.test(body)) return `${body.trimEnd()}\n\n${DISPOSITION_HEADING}\n\n${rows}\n`
|
|
112
|
+
|
|
113
|
+
return body.replace(HEADING_LINE, () => `${DISPOSITION_HEADING}\n\n${rows}`)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Nothing when the change removed no test, so an ordinary brief is not one line longer.
|
|
117
|
+
function brief_block(removed_titles: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
118
|
+
if (removed_titles.length === 0) return []
|
|
119
|
+
|
|
120
|
+
return [
|
|
121
|
+
'',
|
|
122
|
+
`${BRIEF_HEADING} — these tests existed at the base and are gone from the change. For each, find the test that guards its behavior now, or the Issue that retired the behavior; a removed test with neither is a finding (missing test). The pull request body must dispose of each ${ROW_FORMAT}, or \`josh followup\` refuses the merge:`,
|
|
123
|
+
...pending_rows(removed_titles),
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function refusal_message(titles: ReadonlyArray<string>): string {
|
|
128
|
+
return [
|
|
129
|
+
`Merge refused: this change removes ${String(titles.length)} test(s) the pull request body does not account for.`,
|
|
130
|
+
`Put these rows into the body's ${DISPOSITION_HEADING} section, replacing each ending with the test that replaced it or the Issue that retired its behavior:`,
|
|
131
|
+
DISPOSITION_HEADING,
|
|
132
|
+
'',
|
|
133
|
+
...pending_rows(titles),
|
|
134
|
+
`Write ${ROW_FORMAT} — format: ${report_format_reference.pointer(report_format_reference.REMOVED_TESTS_HEADING)}`,
|
|
135
|
+
'Write it into the `--body-file` before `josh ship`, or update an open PR with `gh api -X PATCH repos/{owner}/{repo}/pulls/<N> -F body=@<path>`, then re-run.',
|
|
136
|
+
].join('\n')
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const removed_tests = {
|
|
140
|
+
brief_block,
|
|
141
|
+
DISPOSITION_HEADING,
|
|
142
|
+
refusal_message,
|
|
143
|
+
removed,
|
|
144
|
+
ROW_FORMAT,
|
|
145
|
+
undisposed,
|
|
146
|
+
with_pending_rows,
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export { removed_tests }
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
1
|
import path from 'node:path'
|
|
3
2
|
import { fileURLToPath } from 'node:url'
|
|
4
3
|
import { agent_role_profile, type AgentProfile } from '#scripts/agent/agent-role-profile'
|
|
@@ -8,21 +7,26 @@ import { change_base } from '#scripts/git/change-base'
|
|
|
8
7
|
import { changed_paths } from '#scripts/git/changed-paths'
|
|
9
8
|
import { git_command } from '#scripts/git/git-command'
|
|
10
9
|
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
10
|
+
import { issue_watch_gate } from '#scripts/issue/issue-watch-gate'
|
|
11
11
|
import type { FileMapStamp } from '#scripts/josh/file-map-stamp'
|
|
12
12
|
import { find_package_directory } from '#scripts/josh/josh-logic'
|
|
13
13
|
import { path_decision } from '#scripts/josh/path-decision'
|
|
14
14
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
15
15
|
import { lane_session_broker } from '#scripts/lane/lane-session-broker'
|
|
16
16
|
import { run_ship_review } from '#scripts/run/ship/run-ship-review'
|
|
17
|
+
import { removed_tests_check } from './removed-tests-check'
|
|
17
18
|
import { review_attest } from './review-attest'
|
|
18
19
|
import { review_brief } from './review-brief'
|
|
19
20
|
import { review_checkout, type ReviewCheckout } from './review-checkout'
|
|
20
21
|
import { review_code_tree } from './review-code-tree'
|
|
21
22
|
import type { DiffParts } from './review-diff-parts'
|
|
22
23
|
import { review_diff_write } from './review-diff-write'
|
|
24
|
+
import { review_interaction } from './review-interaction'
|
|
23
25
|
import { review_level, type ReviewLevel } from './review-level'
|
|
26
|
+
import { review_round_one_blobs } from './review-round-one-blobs'
|
|
24
27
|
import { review_stamps } from './review-stamps'
|
|
25
28
|
import { review_tree } from './review-tree'
|
|
29
|
+
import { review_untouched_readers, type ReadersRead } from './review-untouched-readers'
|
|
26
30
|
|
|
27
31
|
// `josh review:brief` — print the whole `/code-review` invocation, not just the level.
|
|
28
32
|
//
|
|
@@ -33,8 +37,8 @@ import { review_tree } from './review-tree'
|
|
|
33
37
|
// so "still running" is the usual answer at this point), how this project runs its unit tests, and —
|
|
34
38
|
// on round 2 — which files the first round's fixes touched.
|
|
35
39
|
|
|
36
|
-
const
|
|
37
|
-
|
|
40
|
+
const USAGE =
|
|
41
|
+
'Usage: josh review:brief [--round <1|2>] | --interaction | --level-only [--staged] [--json]'
|
|
38
42
|
|
|
39
43
|
// The rubric's absolute path, resolved against the kit package rather than the review checkout root.
|
|
40
44
|
// The rubric ships inside the package, so a consumer that keeps no
|
|
@@ -54,6 +58,7 @@ const ROUND_FLAG = '--round'
|
|
|
54
58
|
// paths and nothing else. `--staged` and `--json` are passed straight through, exactly as the old
|
|
55
59
|
// command took them.
|
|
56
60
|
const LEVEL_ONLY_FLAG = '--level-only'
|
|
61
|
+
const INTERACTION_FLAG = '--interaction'
|
|
57
62
|
const LEVEL_KEY = 'level'
|
|
58
63
|
const FIRST_ROUND = 1
|
|
59
64
|
const FAILURE_EXIT_CODE = 1
|
|
@@ -132,7 +137,12 @@ function record_round_one(
|
|
|
132
137
|
return false
|
|
133
138
|
}
|
|
134
139
|
|
|
135
|
-
review_stamps.round_one_stamp.write(
|
|
140
|
+
review_stamps.round_one_stamp.write(
|
|
141
|
+
tree,
|
|
142
|
+
target,
|
|
143
|
+
base,
|
|
144
|
+
review_round_one_blobs.capture(Object.keys(tree)),
|
|
145
|
+
)
|
|
136
146
|
|
|
137
147
|
return true
|
|
138
148
|
} catch {
|
|
@@ -202,6 +212,7 @@ interface ComposeRequest {
|
|
|
202
212
|
tree: Record<string, string>
|
|
203
213
|
base: string
|
|
204
214
|
profile: AgentProfile
|
|
215
|
+
interaction?: ReadonlyArray<string> | undefined
|
|
205
216
|
}
|
|
206
217
|
|
|
207
218
|
// **Swallowed, and the brief keeps its target line**: parts that could not be
|
|
@@ -221,9 +232,35 @@ async function read_diff(
|
|
|
221
232
|
}
|
|
222
233
|
}
|
|
223
234
|
|
|
235
|
+
// **Swallowed, and the brief omits the list**: `josh ship` and `followup` read the same list again
|
|
236
|
+
// and refuse on a failure, so the merge never rests on this reading.
|
|
237
|
+
async function read_removed_tests(): Promise<ReadonlyArray<string>> {
|
|
238
|
+
try {
|
|
239
|
+
return (await removed_tests_check.read()) ?? []
|
|
240
|
+
} catch {
|
|
241
|
+
return []
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// **A failure is marked, and the brief says the list could not be read** — never an empty list,
|
|
246
|
+
// which would read as a change with no reader outside it.
|
|
247
|
+
async function read_readers(
|
|
248
|
+
root: string,
|
|
249
|
+
base: string,
|
|
250
|
+
paths: ReadonlyArray<string>,
|
|
251
|
+
): Promise<ReadersRead> {
|
|
252
|
+
try {
|
|
253
|
+
return await review_untouched_readers.read({ root, base, paths })
|
|
254
|
+
} catch {
|
|
255
|
+
return review_untouched_readers.FAILED_READ
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
224
259
|
async function compose_brief(request: ComposeRequest): Promise<string> {
|
|
225
|
-
const { round, paths, tree, base, profile } = request
|
|
226
|
-
const
|
|
260
|
+
const { round, paths, tree, base, profile, interaction } = request
|
|
261
|
+
const opened = await open_contract()
|
|
262
|
+
// The interaction review reads the whole change, never a resume's narrowing (joshuafolkken/kit#4276).
|
|
263
|
+
const contract = interaction === undefined ? opened : { ...opened, resumed_from: undefined }
|
|
227
264
|
const stamps = {
|
|
228
265
|
gate: review_stamps.gate_stamp.read(),
|
|
229
266
|
in_flight: review_stamps.in_flight_stamp.read(),
|
|
@@ -245,6 +282,9 @@ async function compose_brief(request: ComposeRequest): Promise<string> {
|
|
|
245
282
|
rubric_path: RUBRIC_PATH,
|
|
246
283
|
...contract,
|
|
247
284
|
diff: await read_diff(contract.checkout.root, base, paths),
|
|
285
|
+
readers: await read_readers(contract.checkout.root, base, paths),
|
|
286
|
+
removed_tests: await read_removed_tests(),
|
|
287
|
+
interaction,
|
|
248
288
|
})
|
|
249
289
|
}
|
|
250
290
|
|
|
@@ -325,23 +365,55 @@ async function record_review(
|
|
|
325
365
|
record_briefed(round, tree, commit)
|
|
326
366
|
}
|
|
327
367
|
|
|
328
|
-
|
|
368
|
+
// An interaction brief records nothing: the round-one and briefed stamps describe `/code-review`'s
|
|
369
|
+
// round, which already ran, and retaking them would move the delta round 2 is measured from.
|
|
370
|
+
async function run_review(
|
|
371
|
+
round: number,
|
|
372
|
+
reading: ChangeReading,
|
|
373
|
+
interaction?: ReadonlyArray<string>,
|
|
374
|
+
): Promise<number> {
|
|
329
375
|
const { base, commit, paths, tree } = reading
|
|
330
376
|
const refusal = scoped_green.refusal_for(tree, commit)
|
|
331
377
|
|
|
332
378
|
if (refusal !== undefined) return report_error(refusal)
|
|
333
|
-
const resolved = agent_role_profile.
|
|
379
|
+
const resolved = agent_role_profile.resolve_review(round)
|
|
334
380
|
|
|
335
381
|
if (resolved.kind === 'rejected') return report_error(resolved.note)
|
|
336
382
|
agent_role_profile.warn_of_default()
|
|
337
|
-
|
|
338
|
-
|
|
383
|
+
const { profile } = resolved
|
|
384
|
+
|
|
385
|
+
console.info(await compose_brief({ round, paths, tree, base, profile, interaction }))
|
|
386
|
+
if (interaction === undefined) await record_review(round, tree, commit)
|
|
339
387
|
|
|
340
388
|
return 0
|
|
341
389
|
}
|
|
342
390
|
|
|
391
|
+
// The interaction review's brief (joshuafolkken/kit#4276): `/code-review`'s round-1 brief over the
|
|
392
|
+
// whole change, with the role and the run-tooling paths appended. Not due, it says so and exits 0.
|
|
393
|
+
//
|
|
394
|
+
// **An issue update taken in after round 1's brief refuses it**: minting this brief moves the pointer
|
|
395
|
+
// `josh followup` measures that update against (`issue-watch-gate.ts`), so a round 1 that read the
|
|
396
|
+
// earlier specification would merge without that refusal.
|
|
397
|
+
async function run_interaction(): Promise<number> {
|
|
398
|
+
const reading = await read_change()
|
|
399
|
+
const targets = review_interaction.due_paths(reading.paths)
|
|
400
|
+
|
|
401
|
+
if (targets.length === 0) {
|
|
402
|
+
console.info(review_interaction.NOT_DUE_LINE)
|
|
403
|
+
|
|
404
|
+
return 0
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const stale = await issue_watch_gate.review_refusal_here()
|
|
408
|
+
|
|
409
|
+
if (stale !== undefined) return report_error(stale)
|
|
410
|
+
|
|
411
|
+
return await run_review(FIRST_ROUND, reading, targets)
|
|
412
|
+
}
|
|
413
|
+
|
|
343
414
|
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
344
415
|
if (argv[0] === LEVEL_ONLY_FLAG) return await run_level(argv.slice(1))
|
|
416
|
+
if (argv.length === 1 && argv[0] === INTERACTION_FLAG) return await run_interaction()
|
|
345
417
|
|
|
346
418
|
const round = parse_round(argv)
|
|
347
419
|
|
|
@@ -350,10 +422,6 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
|
350
422
|
return await run_review(round, await read_change())
|
|
351
423
|
}
|
|
352
424
|
|
|
353
|
-
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
354
|
-
process.exitCode = await run(argv)
|
|
355
|
-
}
|
|
356
|
-
|
|
357
425
|
const review_brief_cli = {
|
|
358
426
|
FIRST_ROUND,
|
|
359
427
|
format_reason,
|
|
@@ -365,6 +433,4 @@ const review_brief_cli = {
|
|
|
365
433
|
run,
|
|
366
434
|
}
|
|
367
435
|
|
|
368
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
369
|
-
|
|
370
436
|
export { review_brief_cli }
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { review_brief_cli } from './review-brief-cli'
|
|
4
|
+
|
|
5
|
+
// The `josh review:brief` entry, kept apart from `review-brief-cli.ts` because `run-review-cli.ts`
|
|
6
|
+
// imports 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
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
9
|
+
const ARGV_OFFSET = 2
|
|
10
|
+
|
|
11
|
+
process.exitCode = await review_brief_cli.run(process.argv.slice(ARGV_OFFSET))
|
|
12
|
+
}
|