@joshuafolkken/kit 1.1514.0 → 1.1784.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -1
- package/.claude/settings.json +5 -5
- package/.claude/skills/epic-commands/SKILL.md +26 -65
- package/.claude/skills/epic-commands/epic-bundle.md +3 -1
- package/.claude/skills/workflow-commands/SKILL.md +5 -5
- package/.claude/skills/workflow-commands/background-commands.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
- package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +13 -7
- package/.claude/skills/workflow-commands/delegation.md +6 -5
- package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
- package/.claude/skills/workflow-commands/followup.md +9 -31
- package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
- package/.claude/skills/workflow-commands/fullrun.md +2 -2
- package/.claude/skills/workflow-commands/halfrun.md +17 -25
- package/.claude/skills/workflow-commands/issue-comments.md +16 -12
- package/.claude/skills/workflow-commands/issue-scout.md +2 -2
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +7 -12
- package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
- package/.claude/skills/workflow-commands/observation-filing.md +4 -36
- package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
- package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
- package/.claude/skills/workflow-commands/prerequisite.md +10 -16
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +3 -7
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +13 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-node/action.yml +9 -0
- package/.github/actions/setup-pnpm/action.yml +1 -1
- package/.github/dependabot.yml +16 -0
- package/.github/release.yml +0 -2
- package/.github/workflows/ci.yml +120 -10
- package/.github/workflows/publish.yml +8 -1
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +3 -7
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +3 -7
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
- package/dist/commands/read-set-cli.js +1867 -0
- package/dist/commands/run-prep-main.js +21653 -0
- package/dist/commands/run-step-cli.js +23880 -0
- package/dist/config-merge/index.js +5 -1
- package/dist/hooks/audit-provision.js +20 -35
- package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
- package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
- package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
- package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
- package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -22
- package/dist/hooks/format-edited.js +5 -6
- package/dist/hooks/inputs.json +443 -317
- package/dist/hooks/pretool-guard.js +7 -25
- package/dist/hooks/session-lang.js +44 -51
- package/dist/hooks/stop-guard.js +7716 -2187
- package/dist/josh.js +6002 -3583
- package/dist/self-sync-guard/index.js +74 -10
- package/dist/version/index.js +115 -406
- package/eslint/base.js +1 -1
- package/lefthook/base.yml +3 -1
- package/package.json +10 -48
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -7
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +33 -16
- package/prompts/collaboration-workflow/lane-instructions.md +1 -2
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +4 -6
- package/prompts/collaboration-workflow/output-bounds.md +2 -7
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +5 -0
- package/prompts/collaboration-workflow/report-format.md +31 -60
- package/prompts/collaboration-workflow/residency.md +2 -2
- package/prompts/collaboration-workflow/shell-body.md +6 -16
- package/prompts/collaboration-workflow/turn-batching.md +0 -2
- package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
- package/prompts/collaboration-workflow/wip-cap.md +1 -1
- package/prompts/collaboration-workflow.md +3 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +41 -21
- package/prompts/testing-guide.md +8 -43
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +14 -16
- package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
- package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
- package/scripts/auto-ok/auto-ok-judge.ts +13 -2
- package/scripts/auto-ok/auto-ok-main.ts +17 -0
- package/scripts/backlog/backlog-arrival.ts +14 -3
- package/scripts/backlog/backlog-budget-cli.ts +7 -33
- package/scripts/backlog/backlog-budget-main.ts +16 -0
- package/scripts/backlog/backlog-budget.ts +2 -3
- package/scripts/backlog/backlog-defect-priority.ts +4 -3
- package/scripts/backlog/backlog-drive-adopt.ts +67 -0
- package/scripts/backlog/backlog-drive-args.ts +4 -5
- package/scripts/backlog/backlog-drive-cli.ts +113 -28
- package/scripts/backlog/backlog-drive-hold.ts +162 -0
- package/scripts/backlog/backlog-drive-idle.ts +151 -0
- package/scripts/backlog/backlog-drive-judge.ts +25 -0
- package/scripts/backlog/backlog-drive-memory.ts +126 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
- package/scripts/backlog/backlog-drive-named.ts +53 -6
- package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
- package/scripts/backlog/backlog-drive-paused.ts +169 -0
- package/scripts/backlog/backlog-drive-restore.ts +30 -7
- package/scripts/backlog/backlog-drive-seats.ts +18 -8
- package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
- package/scripts/backlog/backlog-drive.ts +79 -75
- package/scripts/backlog/backlog-next-main.ts +16 -0
- package/scripts/backlog/backlog-next-shared.ts +73 -0
- package/scripts/backlog/backlog-next.ts +48 -16
- package/scripts/backlog/backlog-occupied.ts +52 -39
- package/scripts/backlog/backlog-offer-cli.ts +6 -21
- package/scripts/backlog/backlog-offer-exclude.ts +15 -0
- package/scripts/backlog/backlog-offer-main.ts +12 -0
- package/scripts/backlog/backlog-offer.ts +36 -3
- package/scripts/backlog/backlog-overlap.ts +22 -4
- package/scripts/backlog/backlog-plan-read.ts +6 -2
- package/scripts/backlog/backlog-plan.ts +18 -4
- package/scripts/backlog/backlog-pool.ts +10 -10
- package/scripts/backlog/backlog-rank.ts +10 -2
- package/scripts/backlog/backlog-ready.ts +112 -30
- package/scripts/backlog/backlog-stalled-detect.ts +109 -36
- package/scripts/backlog/backlog-stalled.ts +52 -16
- package/scripts/backlog/backlog-wait-cause.ts +86 -0
- package/scripts/backlog/backlog-waves.ts +39 -13
- package/scripts/backlog/backlogrun-args.ts +19 -7
- package/scripts/backlog/backlogrun-cli.ts +19 -5
- package/scripts/backlog/backlogrun-launch.ts +6 -0
- package/scripts/backlog/backlogrun-restart.ts +97 -0
- package/scripts/backlog/backlogrun-stop.ts +79 -7
- package/scripts/behavior/behavior-cli.ts +2 -2
- package/scripts/behavior/behavior-rules.ts +47 -24
- package/scripts/build/build-bin.ts +2 -16
- package/scripts/build/build-claude-md.ts +0 -7
- package/scripts/build/build-commands.ts +0 -13
- package/scripts/build/build-hooks.ts +49 -48
- package/scripts/build/hook-bundle-stamp.ts +29 -11
- package/scripts/build/local-bin.ts +1 -1
- package/scripts/cases/cases-cli.ts +25 -13
- package/scripts/cases/cases-interaction-scan.ts +134 -0
- package/scripts/cases/cases-interaction.ts +183 -0
- package/scripts/cases/cases-logic.ts +39 -6
- package/scripts/ci/pr-classification-main.ts +18 -0
- package/scripts/ci/pr-classification.ts +10 -17
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/cost-runtime/cost-blocks.ts +22 -37
- package/scripts/cost-runtime/cost-cli.ts +31 -14
- package/scripts/cost-runtime/cost-main.ts +12 -0
- package/scripts/cost-runtime/cost-transcript.ts +1 -0
- package/scripts/delegation/delegation-policy.ts +17 -4
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/investigation-guard.ts +0 -8
- package/scripts/delegation/investigation-reads.ts +3 -4
- package/scripts/dependabot/dependabot-cooldown.ts +194 -0
- package/scripts/discovery/repo-discovery.ts +24 -6
- package/scripts/doctor/doctor-consumer.ts +2 -5
- package/scripts/document/document-byte-budget.ts +8 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +0 -8
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-busy.ts +5 -12
- package/scripts/epic/epic-classify.ts +24 -15
- package/scripts/epic/epic-cli-argv.ts +31 -0
- package/scripts/epic/epic-cli-decide.ts +42 -0
- package/scripts/epic/epic-cli.ts +6 -38
- package/scripts/epic/epic-close.ts +112 -55
- package/scripts/epic/epic-cross-repo.ts +4 -7
- package/scripts/epic/epic-decide.ts +119 -0
- package/scripts/epic/epic-decision.ts +9 -0
- package/scripts/epic/epic-fetch.ts +4 -0
- package/scripts/epic/epic-graph.ts +2 -0
- package/scripts/epic/epic-issue.ts +5 -1
- package/scripts/epic/epic-label-age.ts +1 -1
- package/scripts/epic/epic-lane-offer.ts +39 -4
- package/scripts/epic/epic-next-main.ts +24 -0
- package/scripts/epic/epic-next.ts +6 -24
- package/scripts/epic/epic-outside-blocker.ts +6 -2
- package/scripts/epic/epic-parse.ts +9 -3
- package/scripts/epic/epic-read.ts +1 -0
- package/scripts/epic/epic-reconcile.ts +39 -0
- package/scripts/epic/epic-run.ts +10 -1
- package/scripts/epic/epic-solo.ts +50 -14
- package/scripts/epic/epic.ts +41 -7
- package/scripts/exports/unused-members-cli.ts +2 -2
- package/scripts/followup/followup-checks-event.ts +8 -3
- package/scripts/followup/followup-coderabbit-wait.ts +82 -0
- package/scripts/followup/followup-review-gates.ts +81 -0
- package/scripts/followup/git-followup-stages.ts +13 -3
- package/scripts/followup/git-followup-workflow.ts +19 -66
- package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
- package/scripts/followup/git-pr-followup.ts +36 -8
- package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
- package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
- package/scripts/gate/busy-average.ts +58 -0
- package/scripts/gate/check-cpu.ts +60 -0
- package/scripts/gate/check-inputs.ts +39 -95
- package/scripts/gate/check-reuse.ts +33 -54
- package/scripts/gate/command-memory.ts +192 -0
- package/scripts/gate/core-admission.ts +218 -28
- package/scripts/gate/core-budget-timing.ts +37 -0
- package/scripts/gate/core-budget.ts +80 -98
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +37 -5
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +27 -4
- package/scripts/gate/gate-ledger.ts +32 -4
- package/scripts/gate/gate-plan.ts +41 -34
- package/scripts/gate/gate-report.ts +14 -2
- package/scripts/gate/gate-run-steps.ts +53 -8
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +65 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/project-checks.ts +5 -12
- package/scripts/gate/scoped-green.ts +12 -8
- package/scripts/gate/since-green.ts +62 -0
- package/scripts/gate/toolchain-inputs.ts +115 -0
- package/scripts/gate/verification-gate.ts +27 -24
- package/scripts/gate/verification-inputs.ts +250 -0
- package/scripts/gh/gh-author-association.ts +96 -9
- package/scripts/gh/git-ai-review-scan.ts +4 -2
- package/scripts/gh/git-gh-api-path.ts +15 -0
- package/scripts/gh/git-gh-branch-rules.ts +73 -0
- package/scripts/gh/git-gh-conditional.ts +5 -2
- package/scripts/gh/git-gh-issue-read.ts +5 -1
- package/scripts/gh/git-gh-issue-write.ts +67 -29
- package/scripts/gh/git-gh-issue.ts +7 -3
- package/scripts/gh/git-gh-poll-read.ts +89 -0
- package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
- package/scripts/gh/git-gh-pr-rest.ts +1 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
- package/scripts/gh/git-gh-pr.ts +27 -15
- package/scripts/gh/git-pr-checks-eval.ts +39 -7
- package/scripts/gh/git-pr-checks-parse.ts +39 -9
- package/scripts/gh/git-pr-merge-checked.ts +80 -0
- package/scripts/git/base-tree.ts +19 -2
- package/scripts/git/changed-file-scope.ts +6 -4
- package/scripts/git/changed-paths.ts +18 -1
- package/scripts/git/git-diff-reads.ts +27 -2
- package/scripts/git/git-grep-hits.ts +85 -0
- package/scripts/git/git-location-environment.ts +1 -1
- package/scripts/git/git-merge-conflicts.ts +83 -0
- package/scripts/git/git-preflight.ts +37 -12
- package/scripts/git/git-push-transport.ts +1 -2
- package/scripts/git/git-schemas.ts +17 -7
- package/scripts/git/git-spawn.ts +1 -2
- package/scripts/git/git-status.ts +4 -4
- package/scripts/git/main-merge-main.ts +12 -0
- package/scripts/git/main-merge-regenerate.ts +2 -2
- package/scripts/git/main-merge.ts +25 -9
- package/scripts/git/main-sync-main.ts +12 -0
- package/scripts/git/main-sync.ts +0 -9
- package/scripts/git/stash/git-stash.ts +27 -4
- package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
- package/scripts/git/stash/stash-pop-cli.ts +6 -12
- package/scripts/git/stash/stash-pop-main.ts +12 -0
- package/scripts/git/stash/stash-push-cli.ts +76 -0
- package/scripts/git/stash/stash-push-main.ts +12 -0
- package/scripts/hooks/batch-guard.ts +0 -8
- package/scripts/hooks/check-commit-message-main.ts +8 -0
- package/scripts/hooks/check-commit-message.ts +4 -7
- package/scripts/hooks/format-edited-file.ts +8 -24
- package/scripts/hooks/pre-commit-lint.ts +30 -3
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +32 -19
- package/scripts/hooks/reserved-run.ts +67 -9
- package/scripts/hooks/run-hook.sh +13 -4
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +2 -21
- package/scripts/hooks/stop-guard.ts +13 -9
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -17
- package/scripts/init/init-actions.ts +0 -6
- package/scripts/init/init-ai-copy.ts +10 -36
- package/scripts/init/init-bootstrap.ts +9 -8
- package/scripts/init/init-dry-run-report.ts +1 -1
- package/scripts/init/init-dry-run.ts +1 -1
- package/scripts/init/init-file-action.ts +7 -9
- package/scripts/init/init-logic-json-merge.ts +2 -2
- package/scripts/init/init-logic-migrate.ts +9 -82
- package/scripts/init/init-logic.ts +3 -2
- package/scripts/init/init-main.ts +12 -0
- package/scripts/init/init.ts +5 -12
- package/scripts/init/kit-development-versions.ts +3 -7
- package/scripts/init/kit-written-paths.ts +2 -2
- package/scripts/init/project-profile.ts +5 -4
- package/scripts/init/tsconfig-preset-migration.ts +2 -1
- package/scripts/init/vscode-tasks.ts +1 -1
- package/scripts/issue/defect-origin-cli.ts +106 -0
- package/scripts/issue/defect-origin-line.ts +60 -0
- package/scripts/issue/defect-origin-main.ts +11 -0
- package/scripts/issue/defect-origin.ts +114 -0
- package/scripts/issue/defect-rate-cli.ts +34 -78
- package/scripts/issue/defect-rate.ts +0 -16
- package/scripts/issue/defect-report-cli.ts +128 -0
- package/scripts/issue/defect-report-format.ts +56 -0
- package/scripts/issue/defect-report-main.ts +11 -0
- package/scripts/issue/defect-report.ts +160 -0
- package/scripts/issue/expected-effect-lint.ts +1 -0
- package/scripts/issue/issue-already-done-cli.ts +62 -0
- package/scripts/issue/issue-body-or-comment.ts +40 -0
- package/scripts/issue/issue-cite-cli.ts +0 -9
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +12 -7
- package/scripts/issue/issue-comment-cli.ts +10 -24
- package/scripts/issue/issue-comment-main.ts +12 -0
- package/scripts/issue/issue-evidence-exit.ts +100 -0
- package/scripts/issue/issue-file-cli.ts +29 -7
- package/scripts/issue/issue-file.ts +19 -19
- package/scripts/issue/issue-fold-cli.ts +2 -11
- package/scripts/issue/issue-fold-main.ts +12 -0
- package/scripts/issue/issue-labels.ts +81 -90
- package/scripts/issue/issue-lint-cli.ts +2 -10
- package/scripts/issue/issue-lint-main.ts +12 -0
- package/scripts/issue/issue-measured-cli.ts +56 -0
- package/scripts/issue/issue-merged.ts +19 -2
- package/scripts/issue/issue-not-before-label.ts +135 -0
- package/scripts/issue/issue-not-before.ts +111 -0
- package/scripts/issue/issue-number-shape.ts +15 -1
- package/scripts/issue/issue-park.ts +28 -0
- package/scripts/issue/issue-plan-cli.ts +151 -0
- package/scripts/issue/issue-priority.ts +151 -0
- package/scripts/issue/issue-rank.ts +7 -1
- package/scripts/issue/issue-read-cli.ts +3 -10
- package/scripts/issue/issue-read-main.ts +12 -0
- package/scripts/issue/issue-read.ts +29 -5
- package/scripts/issue/issue-release-cli.ts +0 -10
- package/scripts/issue/issue-release-main.ts +13 -0
- package/scripts/issue/issue-release.ts +7 -12
- package/scripts/issue/issue-sample-gate.ts +192 -0
- package/scripts/issue/issue-sample-source.ts +76 -0
- package/scripts/issue/issue-scout-cli.ts +0 -11
- package/scripts/issue/issue-scout-main.ts +14 -0
- package/scripts/issue/issue-state-cli.ts +0 -10
- package/scripts/issue/issue-state-main.ts +12 -0
- package/scripts/issue/issue-watch-diff.ts +56 -15
- package/scripts/issue/issue-watch.ts +2 -1
- package/scripts/issue/issue-wip.ts +2 -7
- package/scripts/issue/measure-rerun-cli.ts +13 -8
- package/scripts/issue/plan-consumers-cli.ts +39 -0
- package/scripts/issue/plan-consumers-main.ts +11 -0
- package/scripts/issue/plan-consumers-section.ts +55 -0
- package/scripts/issue/plan-consumers.ts +127 -0
- package/scripts/josh/agent-session-environment.ts +1 -1
- package/scripts/josh/command-usage.ts +15 -43
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +12 -6
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +157 -158
- package/scripts/josh/josh-commands-backlog.ts +82 -16
- package/scripts/josh/josh-commands-clone.ts +1 -0
- package/scripts/josh/josh-commands-development.ts +111 -71
- package/scripts/josh/josh-commands-document.ts +43 -1
- package/scripts/josh/josh-commands-epic.ts +171 -0
- package/scripts/josh/josh-commands-hooks.ts +25 -2
- package/scripts/josh/josh-commands-issue-write.ts +181 -0
- package/scripts/josh/josh-commands-issue.ts +124 -24
- package/scripts/josh/josh-commands-lane.ts +103 -2
- package/scripts/josh/josh-commands-lint.ts +19 -8
- package/scripts/josh/josh-commands-maintenance.ts +112 -4
- package/scripts/josh/josh-commands-pause.ts +29 -0
- package/scripts/josh/josh-commands-progress.ts +87 -0
- package/scripts/josh/josh-commands-project.ts +138 -9
- package/scripts/josh/josh-commands-review.ts +124 -0
- package/scripts/josh/josh-commands-run.ts +211 -23
- package/scripts/josh/josh-commands-ship.ts +169 -0
- package/scripts/josh/josh-commands-split.ts +9 -0
- package/scripts/josh/josh-commands-versioning.ts +49 -2
- package/scripts/josh/josh-commands-workflow.ts +144 -6
- package/scripts/josh/josh-logic.ts +6 -13
- package/scripts/josh/package-directory.ts +2 -4
- package/scripts/josh/process-identity.ts +13 -4
- package/scripts/josh/session-language-cli.ts +4 -8
- package/scripts/josh/session-language-main.ts +13 -0
- package/scripts/josh/session-language.ts +6 -1
- package/scripts/josh/shared-cache.ts +90 -0
- package/scripts/josh/stamp-file.ts +9 -15
- package/scripts/lane/lane-await.ts +51 -12
- package/scripts/lane/lane-cache.ts +5 -30
- package/scripts/lane/lane-capacity.ts +14 -23
- package/scripts/lane/lane-check-stats.ts +62 -21
- package/scripts/lane/lane-child-invocation.ts +8 -0
- package/scripts/lane/lane-cli.ts +15 -5
- package/scripts/lane/lane-close.ts +86 -18
- package/scripts/lane/lane-core-wait-stats.ts +66 -0
- package/scripts/lane/lane-dispatch.ts +24 -3
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-handoff.ts +69 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +4 -11
- package/scripts/lane/lane-launch-cli.ts +0 -9
- package/scripts/lane/lane-launch-main.ts +12 -0
- package/scripts/lane/lane-ledger-schema.ts +266 -0
- package/scripts/lane/lane-ledger.ts +92 -123
- package/scripts/lane/lane-limit-cli.ts +12 -1
- package/scripts/lane/lane-measure-cli.ts +57 -11
- package/scripts/lane/lane-open.ts +9 -1
- package/scripts/lane/lane-parked.ts +3 -3
- package/scripts/lane/lane-pause-cli.ts +130 -0
- package/scripts/lane/lane-pause.ts +158 -0
- package/scripts/lane/lane-process-table.ts +166 -0
- package/scripts/lane/lane-reap-settle.ts +124 -0
- package/scripts/lane/lane-reap.ts +50 -15
- package/scripts/lane/lane-registry.ts +24 -3
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +22 -2
- package/scripts/lane/lane-round-two-stats.ts +49 -0
- package/scripts/lane/lane-sampler.ts +4 -0
- package/scripts/lane/lane-session-action.ts +19 -5
- package/scripts/lane/lane-session-broker.ts +102 -21
- package/scripts/lane/lane-snapshot-trace.ts +84 -0
- package/scripts/lane/lane-spans.ts +51 -0
- package/scripts/lane/lane-spent.ts +6 -3
- package/scripts/lane/lane-stage-stats.ts +7 -2
- package/scripts/lane/lane-state.ts +302 -0
- package/scripts/lane/lane-stats.ts +58 -4
- package/scripts/lane/lane-stop-stats.ts +113 -37
- package/scripts/lane/lane-test-related-stats.ts +127 -0
- package/scripts/lane/lane-transcript-calls.ts +145 -0
- package/scripts/lane/lane-transcript-stats.ts +168 -0
- package/scripts/lane/lane-vacant.ts +13 -3
- package/scripts/lane/lane-withdraw-cli.ts +5 -4
- package/scripts/lane/lane-withdraw.ts +50 -49
- package/scripts/lane/process-directories.ts +70 -0
- package/scripts/lane/process-lane-marks.ts +94 -0
- package/scripts/lib/atomic-write.ts +62 -0
- package/scripts/lib/buffered-process.ts +12 -5
- package/scripts/lib/cli-flags.ts +53 -0
- package/scripts/lib/figure-format.ts +63 -0
- package/scripts/lib/json-value.ts +9 -1
- package/scripts/lib/package-manifest.ts +35 -0
- package/scripts/lib/read-file.ts +3 -1
- package/scripts/lib/stamped-memo.ts +63 -0
- package/scripts/lib/stdout-on-stderr.ts +24 -0
- package/scripts/lib/timeouts.ts +9 -0
- package/scripts/lib/transcript-record.ts +91 -0
- package/scripts/lines/effective-limit.ts +1 -1
- package/scripts/lint/eslint-cache-dependencies.ts +145 -0
- package/scripts/lint/eslint-daemon.ts +265 -0
- package/scripts/lint/format.ts +11 -2
- package/scripts/lint/import-graph.ts +279 -0
- package/scripts/lint/lint-gate-scope.ts +102 -0
- package/scripts/lint/lint-parallel-main.ts +19 -0
- package/scripts/lint/lint-parallel.ts +62 -30
- package/scripts/lint/lint-related-scope.ts +30 -24
- package/scripts/lint/lint-related.ts +38 -6
- package/scripts/notify/confirmation-options.ts +1 -2
- package/scripts/notify/telegram-notify.ts +20 -20
- package/scripts/notify/telegram-test-logic.ts +0 -1
- package/scripts/notify/telegram-test-main.ts +8 -0
- package/scripts/notify/telegram-test.ts +2 -6
- package/scripts/observations/observation-ledger.ts +13 -0
- package/scripts/observations/observations-flush-landing.ts +5 -3
- package/scripts/observations/observations-flush.ts +6 -1
- package/scripts/overrides/overrides-check.ts +2 -5
- package/scripts/overrides/overrides-files.ts +2 -1
- package/scripts/overrides/overrides-logic.ts +3 -6
- package/scripts/package/verify-optional-eslint-install.ts +8 -6
- package/scripts/propagate/propagate-publish.ts +2 -7
- package/scripts/propagate/propagate-targets.ts +4 -12
- package/scripts/refactor/import-graph.ts +9 -7
- package/scripts/release/github-release-runs.ts +17 -6
- package/scripts/release/release-approval-prune.ts +18 -0
- package/scripts/release/release-history.ts +1 -3
- package/scripts/release/release-progress.ts +42 -22
- package/scripts/release/release-publish-run.ts +39 -0
- package/scripts/release/release-publish.ts +6 -6
- package/scripts/release/release-scope-cli.ts +0 -10
- package/scripts/release/release-scope-main.ts +12 -0
- package/scripts/repo/repo-setting.ts +3 -6
- package/scripts/repo/required-checks-logic.ts +6 -15
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-labels.ts +155 -0
- package/scripts/report/report-lint-cli.ts +3 -0
- package/scripts/report/report-lint.ts +85 -110
- package/scripts/report/report-template-cli.ts +59 -0
- package/scripts/report/report-template.ts +112 -0
- package/scripts/review/acceptance-map.ts +1 -0
- package/scripts/review/removed-tests-check.ts +86 -0
- package/scripts/review/removed-tests.ts +149 -0
- package/scripts/review/review-brief-cli.ts +81 -15
- package/scripts/review/review-brief-main.ts +12 -0
- package/scripts/review/review-brief.ts +31 -3
- package/scripts/review/review-code-tree.ts +10 -6
- package/scripts/review/review-comment-round.ts +26 -8
- package/scripts/review/review-finding-ledger.ts +30 -15
- package/scripts/review/review-interaction.ts +94 -0
- package/scripts/review/review-readers-scan.ts +163 -0
- package/scripts/review/review-record-cli.ts +69 -30
- package/scripts/review/review-record-main.ts +12 -0
- package/scripts/review/review-round-one-blobs.ts +221 -0
- package/scripts/review/review-round2-cli.ts +49 -12
- package/scripts/review/review-round2.ts +80 -12
- package/scripts/review/review-stamps.ts +19 -1
- package/scripts/review/review-stop-log.ts +96 -0
- package/scripts/review/review-stops-cli.ts +85 -0
- package/scripts/review/review-tree.ts +6 -17
- package/scripts/review/review-untouched-readers.ts +146 -0
- package/scripts/review/test-titles.ts +118 -0
- package/scripts/rules/agent-model.ts +8 -0
- package/scripts/rules/bash-triggers.ts +46 -3
- package/scripts/rules/decision-oracle-batch.ts +9 -1
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +80 -2
- package/scripts/rules/destructive-command.ts +8 -1
- package/scripts/rules/direct-filing.ts +10 -2
- package/scripts/rules/direct-issue-comment.ts +117 -0
- package/scripts/rules/direct-pr-create.ts +69 -3
- package/scripts/rules/early-heartbeat.ts +2 -1
- package/scripts/rules/file-body.ts +7 -0
- package/scripts/rules/filing-cap.ts +7 -0
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +4 -0
- package/scripts/rules/implementation-cut-verdict.ts +1 -1
- package/scripts/rules/implementation-cut.ts +11 -3
- package/scripts/rules/index-guard.ts +8 -1
- package/scripts/rules/issue-comments.ts +9 -1
- package/scripts/rules/josh-git-bare.ts +7 -0
- package/scripts/rules/lane-background.ts +67 -25
- package/scripts/rules/lane-carry-conflict.ts +6 -0
- package/scripts/rules/lane-direct-tool.ts +74 -0
- package/scripts/rules/lane-interactive-ask.ts +9 -2
- package/scripts/rules/lane-park.ts +45 -23
- package/scripts/rules/lane-split-park.ts +10 -2
- package/scripts/rules/lane-switch-main.ts +7 -0
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +1 -1
- package/scripts/rules/poll-loop.ts +7 -0
- package/scripts/rules/pr-merge.ts +123 -0
- package/scripts/rules/protected-files.ts +32 -5
- package/scripts/rules/raw-field-body.ts +6 -0
- package/scripts/rules/rule-body-guard.ts +8 -0
- package/scripts/rules/rule-list.ts +9 -28
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +1 -1
- package/scripts/rules/shell-segments.ts +35 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +3 -4
- package/scripts/rules/test-declared-commit.ts +11 -1
- package/scripts/rules/third-party-write.ts +7 -0
- package/scripts/rules/timed-rerun.ts +69 -0
- package/scripts/rules/worktree-guard.ts +13 -3
- package/scripts/run/board/run-board-app-name.ts +23 -0
- package/scripts/run/board/run-board-cli.ts +65 -32
- package/scripts/run/board/run-board-earlier.ts +94 -0
- package/scripts/run/board/run-board-ending-reason.ts +67 -0
- package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
- package/scripts/run/board/run-board-estimate.ts +98 -0
- package/scripts/run/board/run-board-fit.ts +153 -36
- package/scripts/run/board/run-board-fold.ts +123 -0
- package/scripts/run/board/run-board-fresh.ts +2 -2
- package/scripts/run/board/run-board-gather-live.ts +29 -0
- package/scripts/run/board/run-board-gather-thread.ts +189 -0
- package/scripts/run/board/run-board-gather-worker.ts +29 -0
- package/scripts/run/board/run-board-gather.ts +187 -0
- package/scripts/run/board/run-board-github.ts +118 -38
- package/scripts/run/board/run-board-header.ts +82 -20
- package/scripts/run/board/run-board-keys.ts +58 -0
- package/scripts/run/board/run-board-kind.ts +20 -6
- package/scripts/run/board/run-board-labels.ts +116 -71
- package/scripts/run/board/run-board-lane-state.ts +109 -0
- package/scripts/run/board/run-board-lane-time.ts +122 -0
- package/scripts/run/board/run-board-layout.ts +239 -60
- package/scripts/run/board/run-board-length.ts +52 -0
- package/scripts/run/board/run-board-machine.ts +8 -4
- package/scripts/run/board/run-board-main.ts +12 -0
- package/scripts/run/board/run-board-notes.ts +52 -31
- package/scripts/run/board/run-board-now.ts +1 -1
- package/scripts/run/board/run-board-operation.ts +15 -33
- package/scripts/run/board/run-board-phase.ts +1 -1
- package/scripts/run/board/run-board-plan-shared.ts +115 -0
- package/scripts/run/board/run-board-plan.ts +55 -3
- package/scripts/run/board/run-board-planning.ts +45 -0
- package/scripts/run/board/run-board-priority.ts +44 -0
- package/scripts/run/board/run-board-process-groups.ts +195 -0
- package/scripts/run/board/run-board-read.ts +151 -27
- package/scripts/run/board/run-board-reason.ts +235 -51
- package/scripts/run/board/run-board-released.ts +35 -0
- package/scripts/run/board/run-board-render-checks.ts +39 -5
- package/scripts/run/board/run-board-render-condition.ts +96 -0
- package/scripts/run/board/run-board-render-drawn.ts +67 -0
- package/scripts/run/board/run-board-render-foot.ts +59 -0
- package/scripts/run/board/run-board-render-icon.ts +35 -0
- package/scripts/run/board/run-board-render-lanes.ts +145 -0
- package/scripts/run/board/run-board-render-lead.ts +80 -0
- package/scripts/run/board/run-board-render-legend.ts +117 -48
- package/scripts/run/board/run-board-render-notes.ts +156 -29
- package/scripts/run/board/run-board-render-processes.ts +196 -0
- package/scripts/run/board/run-board-render-section.ts +119 -0
- package/scripts/run/board/run-board-render-slot.ts +3 -36
- package/scripts/run/board/run-board-render-tail.ts +115 -48
- package/scripts/run/board/run-board-render-time.ts +56 -0
- package/scripts/run/board/run-board-render-title.ts +117 -24
- package/scripts/run/board/run-board-render-waits.ts +104 -20
- package/scripts/run/board/run-board-render.ts +207 -265
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +9 -4
- package/scripts/run/board/run-board-setup.ts +1 -12
- package/scripts/run/board/run-board-snapshot.ts +111 -0
- package/scripts/run/board/run-board-spin.ts +2 -2
- package/scripts/run/board/run-board-state.ts +22 -33
- package/scripts/run/board/run-board-status.ts +147 -71
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +122 -107
- package/scripts/run/board/run-board-usage-board.ts +78 -0
- package/scripts/run/board/run-board-usage-lanes.ts +113 -0
- package/scripts/run/board/run-board-usage-listing.ts +93 -0
- package/scripts/run/board/run-board-usage-read.ts +120 -150
- package/scripts/run/board/run-board-usage-rusage.ts +19 -7
- package/scripts/run/board/run-board-usage-text.ts +139 -51
- package/scripts/run/board/run-board-usage-top.ts +102 -0
- package/scripts/run/board/run-board-usage.ts +89 -72
- package/scripts/run/board/run-board-usual.ts +20 -9
- package/scripts/run/carry/run-carry-args.ts +4 -7
- package/scripts/run/carry/run-carry-conversation.ts +1 -1
- package/scripts/run/carry/run-carry.ts +9 -4
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/event/run-event-cli.ts +1 -5
- package/scripts/run/event/run-event-filed.ts +12 -6
- package/scripts/run/event/run-event-follow.ts +2 -3
- package/scripts/run/event/run-event-render.ts +6 -10
- package/scripts/run/event/run-event-scope.ts +2 -2
- package/scripts/run/event/run-event-stream-emit.ts +82 -22
- package/scripts/run/event/run-event-stream.ts +34 -8
- package/scripts/run/hold/run-hold-adopt.ts +65 -0
- package/scripts/run/hold/run-hold-cli.ts +93 -22
- package/scripts/run/hold/run-hold-main.ts +12 -0
- package/scripts/run/hold/run-hold-member.ts +37 -0
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +62 -48
- package/scripts/run/merge/run-merge-close.ts +74 -0
- package/scripts/run/merge/run-merge-collect.ts +6 -13
- package/scripts/run/merge/run-merge-driver.ts +71 -0
- package/scripts/run/merge/run-merge-main.ts +12 -0
- package/scripts/run/merge/run-merge-outcome.ts +23 -0
- package/scripts/run/merge/run-merge-restart.ts +39 -0
- package/scripts/run/merge/run-merge-ship.ts +20 -4
- package/scripts/run/merge/run-merge-signals.ts +33 -9
- package/scripts/run/merge/run-merge-steps.ts +120 -85
- package/scripts/run/merge/run-merge.ts +38 -37
- package/scripts/run/park/run-park-cli.ts +91 -0
- package/scripts/run/park/run-park.ts +88 -0
- package/scripts/run/park/run-stalled.ts +68 -0
- package/scripts/run/pause/run-pause-cli.ts +73 -0
- package/scripts/run/pause/run-pause.ts +251 -0
- package/scripts/run/progress/run-progress-cli.ts +4 -12
- package/scripts/run/progress/run-progress-clock.ts +1 -1
- package/scripts/run/progress/run-progress-config.ts +6 -14
- package/scripts/run/progress/run-progress-main.ts +12 -0
- package/scripts/run/progress/run-progress.ts +1 -4
- package/scripts/run/review/run-review.ts +2 -1
- package/scripts/run/run-ending.ts +1 -0
- package/scripts/run/run-invocation.ts +5 -6
- package/scripts/run/run-liveness-cli.ts +6 -8
- package/scripts/run/run-liveness.ts +60 -29
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-preflight.ts +18 -3
- package/scripts/run/run-prep-cli.ts +1 -10
- package/scripts/run/run-prep-locate.ts +7 -50
- package/scripts/run/run-prep-main.ts +12 -0
- package/scripts/run/run-prep.ts +6 -0
- package/scripts/run/run-report-cli.ts +101 -13
- package/scripts/run/run-report-handoff.ts +114 -0
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +13 -0
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +1 -1
- package/scripts/run/ship/run-ship-args.ts +121 -0
- package/scripts/run/ship/run-ship-body-draft.ts +110 -0
- package/scripts/run/ship/run-ship-cli.ts +63 -140
- package/scripts/run/ship/run-ship-detach.ts +19 -8
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +18 -2
- package/scripts/run/ship/run-ship-overlap.ts +42 -5
- package/scripts/run/ship/run-ship-place.ts +96 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
- package/scripts/run/ship/run-ship-preflight.ts +137 -32
- package/scripts/run/ship/run-ship-probe.ts +11 -3
- package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
- package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
- package/scripts/run/ship/run-ship-return.ts +107 -23
- package/scripts/run/ship/run-ship-review-steps.ts +105 -151
- package/scripts/run/ship/run-ship-review.ts +73 -6
- package/scripts/run/ship/run-ship-reviewer.ts +207 -0
- package/scripts/run/ship/run-ship-stage.ts +55 -6
- package/scripts/run/ship/run-ship-steps.ts +46 -15
- package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +43 -6
- package/scripts/run/ship/run-ship.ts +30 -2
- package/scripts/run/tidy/run-tidy-cli.ts +0 -4
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
- package/scripts/run/tidy/run-tidy-main.ts +8 -0
- package/scripts/run/wake/run-wake-cli.ts +119 -100
- package/scripts/run/wake/run-wake-code.ts +83 -0
- package/scripts/run/wake/run-wake-driver.ts +19 -8
- package/scripts/run/wake/run-wake-loop.ts +34 -3
- package/scripts/run/wake/run-wake-main.ts +13 -0
- package/scripts/run/wake/run-wake-ports.ts +90 -0
- package/scripts/run/wake/run-wake-takeover.ts +66 -0
- package/scripts/run/wake/run-wake.ts +2 -1
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -1
- package/scripts/safe-chain/project-config.ts +3 -9
- package/scripts/security/security-audit-main.ts +8 -0
- package/scripts/security/security-audit-provision-logic.ts +0 -11
- package/scripts/security/security-audit-provision-main.ts +12 -0
- package/scripts/security/security-audit-provision.ts +11 -26
- package/scripts/security/security-audit.ts +6 -7
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
- package/scripts/split/split-assess-cli.ts +2 -2
- package/scripts/split/split-assess.ts +15 -0
- package/scripts/split/split-measure.ts +65 -0
- package/scripts/sync/claude-settings-merge.ts +8 -15
- package/scripts/sync/directory-copy-guard.ts +4 -9
- package/scripts/sync/file-content.ts +78 -8
- package/scripts/sync/sync-ai-files.ts +3 -5
- package/scripts/sync/sync-configs.ts +11 -23
- package/scripts/sync/sync-hook-safety.ts +4 -10
- package/scripts/sync/sync-main.ts +11 -0
- package/scripts/sync/sync.ts +25 -37
- package/scripts/test/test-declared-changed.ts +2 -2
- package/scripts/test/test-declared.ts +1 -1
- package/scripts/test/test-e2e-guard.ts +25 -1
- package/scripts/test/test-e2e-stamp.ts +38 -0
- package/scripts/test/test-pinned-logic.ts +145 -0
- package/scripts/test/test-pinned-main.ts +78 -0
- package/scripts/test/test-pinned.ts +100 -0
- package/scripts/test/test-read-map.ts +264 -0
- package/scripts/test/test-read-recording.ts +91 -0
- package/scripts/test/test-read-trace.ts +148 -0
- package/scripts/test/test-red-main.ts +12 -0
- package/scripts/test/test-red.ts +12 -30
- package/scripts/test/test-related-main.ts +18 -0
- package/scripts/test/test-related-record.ts +119 -0
- package/scripts/test/test-related-scope.ts +229 -43
- package/scripts/test/test-related.ts +300 -22
- package/scripts/test/test-unit-guard-main.ts +15 -0
- package/scripts/test/test-unit-guard.ts +42 -24
- package/scripts/test/unit-count-file.ts +37 -0
- package/scripts/test/unit-run-marker.ts +162 -0
- package/scripts/test/unit-setup-files.ts +51 -0
- package/scripts/test/unit-worker-share.ts +61 -149
- package/scripts/test/whole-suite-files.ts +63 -0
- package/scripts/time-runtime/time-background.ts +20 -2
- package/scripts/time-runtime/time-bundles.ts +4 -3
- package/scripts/time-runtime/time-density-hook.ts +8 -6
- package/scripts/time-runtime/time-followup-stage.ts +1 -3
- package/scripts/time-runtime/time-format.ts +5 -28
- package/scripts/time-runtime/time-markers.ts +10 -1
- package/scripts/time-runtime/time-shell.ts +97 -10
- package/scripts/time-runtime/time-transcript-line.ts +49 -62
- package/scripts/uninstall/uninstall.ts +1 -1
- package/scripts/version/bump-version-main.ts +12 -0
- package/scripts/version/bump-version.ts +25 -25
- package/scripts/version/effective-upstream.ts +6 -12
- package/scripts/version/latest-corepack.ts +17 -32
- package/scripts/version/latest-if-required-cli.ts +93 -0
- package/scripts/version/latest-lane-guard-main.ts +8 -0
- package/scripts/version/latest-lane-guard.ts +0 -4
- package/scripts/version/latest-scope-cli.ts +0 -9
- package/scripts/version/latest-scope-main.ts +12 -0
- package/scripts/version/latest-update.ts +5 -5
- package/scripts/version/npm-registry.ts +44 -6
- package/scripts/version/publishable-range-check.ts +5 -16
- package/scripts/version/release-age.ts +1 -1
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/release-window.ts +38 -0
- package/scripts/version/running-binary.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +3 -8
- package/scripts/version/version-targets.ts +6 -28
- package/templates/dependabot.yml +29 -0
- package/templates/gitignore +4 -1
- package/templates/pnpm-workspace.basic.yaml +1 -1
- package/templates/sonar-project.properties +3 -2
- package/templates/workflows/ci.yml +12 -4
- package/templates/workflows/github-release.yml +4 -0
- package/tsconfig.sonar.json +1 -1
- package/.ncurc.json +0 -3
- package/dist/hooks/batch-guard.js +0 -29
- package/dist/hooks/chunk-4KKD2UTK.js +0 -66
- package/dist/hooks/chunk-6TS2JD6D.js +0 -237
- package/dist/hooks/chunk-7DSBJVFH.js +0 -50
- package/dist/hooks/chunk-A65Y4YOR.js +0 -79
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EFXE6C37.js +0 -81
- package/dist/hooks/chunk-GP4IEC4O.js +0 -20
- package/dist/hooks/chunk-JP45SOCJ.js +0 -56
- package/dist/hooks/chunk-LAOV7NLM.js +0 -45
- package/dist/hooks/chunk-M4HGZV7U.js +0 -83
- package/dist/hooks/chunk-PF2NZL2A.js +0 -131
- package/dist/hooks/chunk-PTICX4OL.js +0 -358
- package/dist/hooks/chunk-RT27QRJW.js +0 -6247
- package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
- package/dist/hooks/chunk-UPUZF3AN.js +0 -279
- package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -29
- package/scripts/backlog/backlog-stalled-cli.ts +0 -30
- package/scripts/cost-runtime/cost-format.ts +0 -29
- package/scripts/init/basic-path-migration.ts +0 -24
- package/scripts/issue/issue-backlinks-cli.ts +0 -93
- package/scripts/josh/josh-commands-guard.ts +0 -38
- package/scripts/josh/josh-usage-automation.ts +0 -121
- package/scripts/josh/josh-usage-backlog.ts +0 -180
- package/scripts/josh/josh-usage-developer.ts +0 -230
- package/scripts/josh/josh-usage-hooks.ts +0 -38
- package/scripts/josh/josh-usage-issue.ts +0 -205
- package/scripts/josh/josh-usage-review.ts +0 -101
- package/scripts/josh/josh-usage-run.ts +0 -252
- package/scripts/josh/josh-usage-session.ts +0 -238
- package/scripts/josh/josh-usage-workflow.ts +0 -212
- package/scripts/lint/cross-file-recheck.ts +0 -155
- package/scripts/registry-migration/migrate-logic.ts +0 -237
- package/scripts/registry-migration/migrate.ts +0 -292
- package/scripts/registry-migration/user-npmrc.ts +0 -15
- package/scripts/rules/rule-guard.ts +0 -23
- package/scripts/rules/rule-registry-rows.ts +0 -292
- package/scripts/rules/rule-registry.ts +0 -112
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { json_value } from '#scripts/lib/json-value'
|
|
2
|
+
import { direct_pr_create } from '#scripts/rules/direct-pr-create'
|
|
2
3
|
import { time_shell } from '#scripts/time-runtime/time-shell'
|
|
3
4
|
import type { Block, TranscriptLine } from '#scripts/time-runtime/time-transcript-line'
|
|
4
5
|
import type { Assertion, Finding } from './behavior-assertion'
|
|
5
6
|
|
|
6
|
-
// The behavior assertions checked against recorded transcripts.
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// wall of red that says nothing about which behavior actually regressed.
|
|
7
|
+
// The behavior assertions checked against recorded transcripts. Rules join one at a time, each
|
|
8
|
+
// verified green across the recorded corpus first — starting with many would land a wall of red that
|
|
9
|
+
// says nothing about which behavior actually regressed.
|
|
10
10
|
|
|
11
11
|
const BASH_TOOL = 'Bash'
|
|
12
12
|
const TOOL_USE = 'tool_use'
|
|
@@ -98,46 +98,69 @@ function denied_call_ids(lines: ReadonlyArray<TranscriptLine>): ReadonlySet<stri
|
|
|
98
98
|
)
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
// The
|
|
102
|
-
// line is one assistant content block, so its position is a place a reader can open
|
|
103
|
-
function
|
|
101
|
+
// The Bash calls that ran on one transcript line and broke the rule, each as a finding at that line's
|
|
102
|
+
// position. A line is one assistant content block, so its position is a place a reader can open.
|
|
103
|
+
function line_findings(
|
|
104
104
|
line: TranscriptLine,
|
|
105
|
-
|
|
105
|
+
position: number,
|
|
106
106
|
denied_ids: ReadonlySet<string>,
|
|
107
|
+
rule: BashRule,
|
|
107
108
|
): ReadonlyArray<Finding> {
|
|
108
109
|
return line.blocks
|
|
109
110
|
.filter((block) => !denied_ids.has(block.id))
|
|
110
111
|
.map((block) => command_of(block))
|
|
111
|
-
.filter((command): command is string => command !== undefined &&
|
|
112
|
-
.map((command) => ({
|
|
113
|
-
assertion: INDEX_ASSERTION_NAME,
|
|
114
|
-
position: index + FIRST_POSITION_OFFSET,
|
|
115
|
-
detail: command,
|
|
116
|
-
}))
|
|
112
|
+
.filter((command): command is string => command !== undefined && rule.is_violation(command))
|
|
113
|
+
.map((command) => ({ assertion: rule.name, position, detail: command }))
|
|
117
114
|
}
|
|
118
115
|
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
interface BashRule {
|
|
117
|
+
name: string
|
|
118
|
+
describe: string
|
|
119
|
+
is_violation: (command: string) => boolean
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// One assertion over the Bash calls a run actually executed: a call the permission layer or a
|
|
123
|
+
// PreToolUse hook refused never ran, so it breaks nothing.
|
|
124
|
+
function bash_assertion(rule: BashRule): Assertion {
|
|
125
|
+
function scan(lines: ReadonlyArray<TranscriptLine>): ReadonlyArray<Finding> {
|
|
126
|
+
const denied_ids = denied_call_ids(lines)
|
|
127
|
+
|
|
128
|
+
return lines.flatMap((line, index) =>
|
|
129
|
+
line_findings(line, index + FIRST_POSITION_OFFSET, denied_ids, rule),
|
|
130
|
+
)
|
|
131
|
+
}
|
|
121
132
|
|
|
122
|
-
return
|
|
133
|
+
return { name: rule.name, describe: rule.describe, scan }
|
|
123
134
|
}
|
|
124
135
|
|
|
125
|
-
const index_mutation_assertion
|
|
136
|
+
const index_mutation_assertion = bash_assertion({
|
|
126
137
|
name: INDEX_ASSERTION_NAME,
|
|
127
138
|
describe: 'git staging or commit must go through `pnpm josh git`, never a direct git call',
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// The
|
|
132
|
-
//
|
|
133
|
-
|
|
139
|
+
is_violation: is_index_mutation,
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
// The matcher is the `direct-pr-create` guard's own, so the assertion and the refusal cannot drift. The
|
|
143
|
+
// guard refuses every match, so a finding means a direct PR call ran past it — every run since the
|
|
144
|
+
// guard landed is green; the only hits in the corpus predate it.
|
|
145
|
+
const PR_CREATE_ASSERTION_NAME = 'no-direct-pr-create'
|
|
146
|
+
const pr_create_assertion = bash_assertion({
|
|
147
|
+
name: PR_CREATE_ASSERTION_NAME,
|
|
148
|
+
describe: 'a pull request must be opened with `pnpm josh pr`, never `gh pr create` or `gh api`',
|
|
149
|
+
is_violation: direct_pr_create.is_direct_pr_create,
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
// Every rule green across the recorded corpus. A new rule is appended here only after it has been
|
|
153
|
+
// verified green against past real runs.
|
|
154
|
+
const ALL_ASSERTIONS: ReadonlyArray<Assertion> = [index_mutation_assertion, pr_create_assertion]
|
|
134
155
|
|
|
135
156
|
const behavior_rules = {
|
|
136
157
|
ALL_ASSERTIONS,
|
|
137
158
|
INDEX_ASSERTION_NAME,
|
|
159
|
+
PR_CREATE_ASSERTION_NAME,
|
|
138
160
|
command_of,
|
|
139
161
|
index_mutation_assertion,
|
|
140
162
|
is_index_mutation,
|
|
163
|
+
pr_create_assertion,
|
|
141
164
|
}
|
|
142
165
|
|
|
143
166
|
export { behavior_rules }
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
1
|
import path from 'node:path'
|
|
3
2
|
import { fileURLToPath } from 'node:url'
|
|
4
|
-
import { error_text } from '#scripts/lib/error-message'
|
|
5
3
|
import { build } from 'esbuild'
|
|
6
4
|
|
|
7
5
|
const PACKAGE_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..')
|
|
@@ -9,10 +7,10 @@ const ENTRY_POINT = path.join(PACKAGE_DIR, 'scripts', 'josh', 'josh.ts')
|
|
|
9
7
|
const OUTFILE = path.join(PACKAGE_DIR, 'dist', 'josh.js')
|
|
10
8
|
const NODE_BANNER = '#!/usr/bin/env node'
|
|
11
9
|
|
|
12
|
-
async function build_bin(): Promise<void> {
|
|
10
|
+
async function build_bin(outfile: string = OUTFILE): Promise<void> {
|
|
13
11
|
await build({
|
|
14
12
|
entryPoints: [ENTRY_POINT],
|
|
15
|
-
outfile
|
|
13
|
+
outfile,
|
|
16
14
|
bundle: true,
|
|
17
15
|
platform: 'node',
|
|
18
16
|
format: 'esm',
|
|
@@ -22,16 +20,4 @@ async function build_bin(): Promise<void> {
|
|
|
22
20
|
})
|
|
23
21
|
}
|
|
24
22
|
|
|
25
|
-
async function main(): Promise<void> {
|
|
26
|
-
try {
|
|
27
|
-
await build_bin()
|
|
28
|
-
console.info(` ✔ ${OUTFILE} built`)
|
|
29
|
-
} catch (error) {
|
|
30
|
-
console.error(error_text.message_of(error))
|
|
31
|
-
process.exit(1)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
|
|
36
|
-
|
|
37
23
|
export { build_bin, NODE_BANNER, OUTFILE }
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
1
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
3
2
|
import path from 'node:path'
|
|
4
3
|
import { fileURLToPath } from 'node:url'
|
|
@@ -40,12 +39,6 @@ function build_claude_md(): string {
|
|
|
40
39
|
return DIST_CLAUDE_MD
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
function main(): void {
|
|
44
|
-
console.info(` ✔ ${build_claude_md()} built`)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) main()
|
|
48
|
-
|
|
49
42
|
export {
|
|
50
43
|
build_claude_md,
|
|
51
44
|
DIST_BASIC_CLAUDE_MDS,
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
1
|
import { rmSync } from 'node:fs'
|
|
3
2
|
import path from 'node:path'
|
|
4
3
|
import { fileURLToPath } from 'node:url'
|
|
5
4
|
import { COMMAND_MAP } from '#scripts/josh/josh-command-map'
|
|
6
5
|
import { BUNDLED_COMMAND_DIRECTORY, josh_in_process } from '#scripts/josh/josh-in-process'
|
|
7
|
-
import { error_text } from '#scripts/lib/error-message'
|
|
8
6
|
import { build } from 'esbuild'
|
|
9
7
|
|
|
10
8
|
const PACKAGE_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..')
|
|
@@ -52,15 +50,4 @@ async function build_commands(out_directory: string = OUT_DIR): Promise<string>
|
|
|
52
50
|
return out_directory
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
async function main(): Promise<void> {
|
|
56
|
-
try {
|
|
57
|
-
console.info(` ✔ ${await build_commands()} built`)
|
|
58
|
-
} catch (error) {
|
|
59
|
-
console.error(error_text.message_of(error))
|
|
60
|
-
process.exit(1)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
|
|
65
|
-
|
|
66
53
|
export { build_commands, bundled_scripts, OUT_DIR }
|
|
@@ -1,20 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
mkdirSync,
|
|
4
|
-
mkdtempSync,
|
|
5
|
-
readdirSync,
|
|
6
|
-
readFileSync,
|
|
7
|
-
renameSync,
|
|
8
|
-
rmSync,
|
|
9
|
-
writeFileSync,
|
|
10
|
-
} from 'node:fs'
|
|
1
|
+
import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync } from 'node:fs'
|
|
11
2
|
import path from 'node:path'
|
|
12
3
|
import { fileURLToPath } from 'node:url'
|
|
13
4
|
import { hook_bundle_stamp } from '#scripts/build/hook-bundle-stamp'
|
|
14
|
-
import {
|
|
5
|
+
import { toolchain_inputs } from '#scripts/gate/toolchain-inputs'
|
|
6
|
+
import { atomic_write } from '#scripts/lib/atomic-write'
|
|
15
7
|
import { build, type OnLoadArgs, type OutputFile, type Plugin, type PluginBuild } from 'esbuild'
|
|
16
8
|
|
|
17
|
-
const
|
|
9
|
+
const BUILD_SCRIPT = fileURLToPath(import.meta.url)
|
|
10
|
+
const PACKAGE_DIR = path.join(path.dirname(BUILD_SCRIPT), '..', '..')
|
|
18
11
|
const OUT_DIR = path.join(PACKAGE_DIR, 'dist', 'hooks')
|
|
19
12
|
const { STAMP_NAME } = hook_bundle_stamp
|
|
20
13
|
const CHUNK_PREFIX = 'chunk-'
|
|
@@ -29,11 +22,11 @@ const ANY_PATH = /.*/
|
|
|
29
22
|
//
|
|
30
23
|
// **`splitting: true` is load-bearing, not an optimization.** Every hook module decides whether to
|
|
31
24
|
// run its main from `process.argv[1] === fileURLToPath(import.meta.url)`. A single-file bundle would
|
|
32
|
-
// collapse every imported module's `import.meta.url` to the one output path, so a call to
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
25
|
+
// collapse every imported module's `import.meta.url` to the one output path, so a call to one hook
|
|
26
|
+
// would fire the self-invoke of every other entry it carries — each reads stdin, and the second read
|
|
27
|
+
// gets an empty payload. Code splitting keeps every entry in its own file with its own
|
|
28
|
+
// `import.meta.url`, so only the file actually launched runs its main. The guards `pretool-guard`
|
|
29
|
+
// composes carry no self-invoke: theirs live in `*-main.ts` entries no module imports.
|
|
37
30
|
//
|
|
38
31
|
// **The flip side: an entry another entry imports loses its main**. Splitting
|
|
39
32
|
// moves a module two entries share into a chunk, so a launched hook whose own module is imported
|
|
@@ -49,20 +42,15 @@ interface HookBundle {
|
|
|
49
42
|
out: string
|
|
50
43
|
}
|
|
51
44
|
|
|
52
|
-
// The settings.json hooks (the session-start audit provisioner among them)
|
|
53
|
-
//
|
|
54
|
-
// must be their own entries to keep their `import.meta.url` out of `pretool-guard`'s file.
|
|
55
|
-
// `delivered-rules` (the fourth guard) has no self-invoke, so it stays inlined.
|
|
45
|
+
// The settings.json hooks (the session-start audit provisioner among them) and the Codex input
|
|
46
|
+
// adapter — every hook a hook config launches, and nothing else.
|
|
56
47
|
const HOOK_BUNDLES: ReadonlyArray<HookBundle> = [
|
|
57
48
|
{ source: 'scripts/hooks/codex-hook-adapter.ts', out: 'codex-hook-adapter' },
|
|
58
49
|
{ source: 'scripts/hooks/pretool-guard-cli.ts', out: 'pretool-guard' },
|
|
59
50
|
{ source: 'scripts/hooks/stop-guard.ts', out: 'stop-guard' },
|
|
60
51
|
{ source: 'scripts/hooks/format-edited-cli.ts', out: 'format-edited' },
|
|
61
|
-
{ source: 'scripts/josh/session-language-
|
|
62
|
-
{ source: 'scripts/security/security-audit-provision.ts', out: 'audit-provision' },
|
|
63
|
-
{ source: 'scripts/hooks/batch-guard.ts', out: 'batch-guard' },
|
|
64
|
-
{ source: 'scripts/delegation/investigation-guard.ts', out: 'investigation-guard' },
|
|
65
|
-
{ source: 'scripts/delegation/duplicate-read-guard.ts', out: 'duplicate-read-guard' },
|
|
52
|
+
{ source: 'scripts/josh/session-language-main.ts', out: 'session-lang' },
|
|
53
|
+
{ source: 'scripts/security/security-audit-provision-main.ts', out: 'audit-provision' },
|
|
66
54
|
]
|
|
67
55
|
|
|
68
56
|
function entry_point(bundle: HookBundle): { in: string; out: string } {
|
|
@@ -83,9 +71,22 @@ function prune_stale_outputs(out_directory: string, outputs: ReadonlyArray<strin
|
|
|
83
71
|
}
|
|
84
72
|
}
|
|
85
73
|
|
|
74
|
+
// **A module inlined into an entry keeps no self-invoke.** Its `import.meta.url` collapses to the
|
|
75
|
+
// entry's output path, so its guard would match `argv[1]` and its main would run beside the hook's:
|
|
76
|
+
// `stop-guard` ran `josh run:hold`'s, `josh notify`'s and `josh run:tidy`'s on every stop, and their
|
|
77
|
+
// stdout ahead of the envelope made the harness drop the refusal (joshuafolkken/kit#4123). Only the
|
|
78
|
+
// launched entry runs a main, so every other module's guard is built as `false`.
|
|
79
|
+
const SELF_INVOKE_GUARD = 'process.argv[1] === fileURLToPath(import.meta.url)'
|
|
80
|
+
|
|
81
|
+
function loaded_contents(contents: Uint8Array, is_entry: boolean): string {
|
|
82
|
+
const source = Buffer.from(contents).toString('utf8')
|
|
83
|
+
|
|
84
|
+
return is_entry ? source : source.replaceAll(SELF_INVOKE_GUARD, 'false')
|
|
85
|
+
}
|
|
86
|
+
|
|
86
87
|
// Every file the build loads is read here, so the stamp digests the exact bytes that were bundled —
|
|
87
88
|
// a source edited mid-build is recorded as what it was, and the next launch rebuilds it.
|
|
88
|
-
function source_recorder(sources: Map<string, Uint8Array>): Plugin {
|
|
89
|
+
function source_recorder(sources: Map<string, Uint8Array>, entries: ReadonlySet<string>): Plugin {
|
|
89
90
|
return {
|
|
90
91
|
name: 'hook-source-recorder',
|
|
91
92
|
setup(plugin_build: PluginBuild): void {
|
|
@@ -94,7 +95,7 @@ function source_recorder(sources: Map<string, Uint8Array>): Plugin {
|
|
|
94
95
|
|
|
95
96
|
sources.set(path.relative(PACKAGE_DIR, args.path), contents)
|
|
96
97
|
|
|
97
|
-
return { contents, loader: 'default' }
|
|
98
|
+
return { contents: loaded_contents(contents, entries.has(args.path)), loader: 'default' }
|
|
98
99
|
})
|
|
99
100
|
},
|
|
100
101
|
}
|
|
@@ -113,10 +114,7 @@ function is_chunk_first(left: OutputFile, right: OutputFile): number {
|
|
|
113
114
|
// Each file is written into a private staging directory and renamed into place, so a hook never
|
|
114
115
|
// reads a half-written bundle and two builds running side by side never write one file at once.
|
|
115
116
|
function place(staging: string, target: string, contents: Uint8Array | string): void {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
writeFileSync(temporary, contents)
|
|
119
|
-
renameSync(temporary, target)
|
|
117
|
+
atomic_write.replace_file(target, contents, { staging_directory: staging })
|
|
120
118
|
}
|
|
121
119
|
|
|
122
120
|
function place_build(out_directory: string, files: ReadonlyArray<OutputFile>, stamp: string): void {
|
|
@@ -142,11 +140,26 @@ function place_build(out_directory: string, files: ReadonlyArray<OutputFile>, st
|
|
|
142
140
|
// every tool call, and an emptied directory would make a hook launched mid-build fail to load and its
|
|
143
141
|
// guard fail open. The source digest is placed last (`hook-bundle-stamp.ts`), so a launch only reads
|
|
144
142
|
// the bundles as fresh once every one of them is in place.
|
|
143
|
+
//
|
|
144
|
+
// This script is an input too: it rewrites what it loads, so an edit to it changes the bundles while
|
|
145
|
+
// every bundled source stays byte-identical. So is the toolchain (`toolchain-inputs.ts`): the manifest
|
|
146
|
+
// maps the `#scripts/*` imports esbuild resolves, and the lockfile pins esbuild itself.
|
|
147
|
+
function build_inputs(): Map<string, Uint8Array> {
|
|
148
|
+
const toolchain = toolchain_inputs.paths(PACKAGE_DIR)
|
|
149
|
+
|
|
150
|
+
return new Map<string, Uint8Array>([
|
|
151
|
+
[path.relative(PACKAGE_DIR, BUILD_SCRIPT), readFileSync(BUILD_SCRIPT)],
|
|
152
|
+
...toolchain.map((input) => [input, readFileSync(path.join(PACKAGE_DIR, input))] as const),
|
|
153
|
+
])
|
|
154
|
+
}
|
|
155
|
+
|
|
145
156
|
async function build_hooks(out_directory: string = OUT_DIR): Promise<void> {
|
|
146
|
-
const sources =
|
|
157
|
+
const sources = build_inputs()
|
|
158
|
+
const entry_points = HOOK_BUNDLES.map((bundle) => entry_point(bundle))
|
|
159
|
+
const entries = new Set(entry_points.map((entry) => entry.in))
|
|
147
160
|
const { outputFiles: files } = await build({
|
|
148
161
|
absWorkingDir: PACKAGE_DIR,
|
|
149
|
-
entryPoints:
|
|
162
|
+
entryPoints: entry_points,
|
|
150
163
|
outdir: out_directory,
|
|
151
164
|
bundle: true,
|
|
152
165
|
splitting: true,
|
|
@@ -155,7 +168,7 @@ async function build_hooks(out_directory: string = OUT_DIR): Promise<void> {
|
|
|
155
168
|
target: 'node22',
|
|
156
169
|
packages: 'external',
|
|
157
170
|
write: false,
|
|
158
|
-
plugins: [source_recorder(sources)],
|
|
171
|
+
plugins: [source_recorder(sources, entries)],
|
|
159
172
|
})
|
|
160
173
|
const stamp = hook_bundle_stamp.stamp_text(
|
|
161
174
|
sources,
|
|
@@ -165,17 +178,5 @@ async function build_hooks(out_directory: string = OUT_DIR): Promise<void> {
|
|
|
165
178
|
place_build(out_directory, files, stamp)
|
|
166
179
|
}
|
|
167
180
|
|
|
168
|
-
async function main(): Promise<void> {
|
|
169
|
-
try {
|
|
170
|
-
await build_hooks()
|
|
171
|
-
for (const bundle of HOOK_BUNDLES) console.info(` ✔ ${outfile_for(bundle)} built`)
|
|
172
|
-
} catch (error) {
|
|
173
|
-
console.error(error_text.message_of(error))
|
|
174
|
-
process.exit(1)
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
|
|
179
|
-
|
|
180
181
|
export type { HookBundle }
|
|
181
|
-
export { build_hooks, HOOK_BUNDLES, OUT_DIR, outfile_for }
|
|
182
|
+
export { build_hooks, HOOK_BUNDLES, OUT_DIR, outfile_for, STAGING_PREFIX }
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto'
|
|
2
|
-
import { existsSync, readFileSync,
|
|
2
|
+
import { existsSync, readFileSync, statSync } from 'node:fs'
|
|
3
3
|
import path from 'node:path'
|
|
4
|
+
import { toolchain_inputs } from '#scripts/gate/toolchain-inputs'
|
|
5
|
+
import { atomic_write } from '#scripts/lib/atomic-write'
|
|
4
6
|
import { json_value } from '#scripts/lib/json-value'
|
|
5
7
|
|
|
6
8
|
// What a hook build was made from, so a later launch can tell whether `dist/hooks/` still matches the
|
|
@@ -31,7 +33,7 @@ import { json_value } from '#scripts/lib/json-value'
|
|
|
31
33
|
// again. Once an mtime is older than the window any later write moves it, so only settled inputs are
|
|
32
34
|
// remembered; a launch inside the window simply hashes.
|
|
33
35
|
//
|
|
34
|
-
// This module is loaded by plain `node` on every hook launch (`
|
|
36
|
+
// This module is loaded by plain `node` on every hook launch (`tools/hooks/hook-bundle-ready.ts`),
|
|
35
37
|
// so it imports `node:` built-ins and `#scripts/*` subpaths alone — nothing slow to load.
|
|
36
38
|
|
|
37
39
|
const STAMP_NAME = 'inputs.json'
|
|
@@ -171,13 +173,10 @@ function is_remembered(
|
|
|
171
173
|
// Written through a rename so a concurrent launch never reads half a record. Best-effort: a tree that
|
|
172
174
|
// cannot be written is simply hashed again next time.
|
|
173
175
|
function remember(out_directory: string, verified: VerifiedDigest): void {
|
|
174
|
-
const temporary_path = path.join(out_directory, `${VERIFIED_NAME}.${String(process.pid)}`)
|
|
175
|
-
|
|
176
176
|
try {
|
|
177
|
-
|
|
178
|
-
renameSync(temporary_path, path.join(out_directory, VERIFIED_NAME))
|
|
177
|
+
atomic_write.replace_file(path.join(out_directory, VERIFIED_NAME), JSON.stringify(verified))
|
|
179
178
|
} catch {
|
|
180
|
-
|
|
179
|
+
// A record that could not be written leaves the digest to be computed again.
|
|
181
180
|
}
|
|
182
181
|
}
|
|
183
182
|
|
|
@@ -194,12 +193,31 @@ function is_digest_current(
|
|
|
194
193
|
return true
|
|
195
194
|
}
|
|
196
195
|
|
|
197
|
-
//
|
|
198
|
-
//
|
|
199
|
-
|
|
196
|
+
// The build records the toolchain inputs among its sources (`build-hooks.ts`), so an edited one
|
|
197
|
+
// changes the digest; one created since — a new `tsconfig.*.json` or rule module — is in no record.
|
|
198
|
+
function lists_toolchain(stamp: HookBundleStamp, package_directory: string): boolean {
|
|
199
|
+
const recorded = new Set(stamp.inputs.map((input) => input.split(path.sep).join('/')))
|
|
200
|
+
|
|
201
|
+
return toolchain_inputs.paths(package_directory).every((input) => recorded.has(input))
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function is_complete(
|
|
205
|
+
stamp: HookBundleStamp,
|
|
206
|
+
out_directory: string,
|
|
207
|
+
package_directory: string,
|
|
208
|
+
): boolean {
|
|
209
|
+
if (stamp.outputs.some((output) => !existsSync(path.join(out_directory, output)))) return false
|
|
210
|
+
|
|
211
|
+
return lists_toolchain(stamp, package_directory)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Fresh only when the record exists, every output it lists is still there, it lists every toolchain
|
|
215
|
+
// input, and the listed inputs hash to the recorded digest — a missing or deleted input counts as
|
|
216
|
+
// stale. The hash is skipped when the inputs still carry the signatures of an earlier launch that
|
|
217
|
+
// verified this digest.
|
|
200
218
|
function is_fresh(out_directory: string, package_directory: string): boolean {
|
|
201
219
|
const stamp = read_stamp(out_directory)
|
|
202
|
-
if (
|
|
220
|
+
if (stamp === undefined || !is_complete(stamp, out_directory, package_directory)) return false
|
|
203
221
|
const snapshot = read_snapshot(package_directory, stamp.inputs)
|
|
204
222
|
if (snapshot === undefined) return false
|
|
205
223
|
if (is_remembered(out_directory, stamp.digest, snapshot.signatures)) return true
|
|
@@ -2,13 +2,13 @@ import { existsSync, readFileSync } from 'node:fs'
|
|
|
2
2
|
import { createRequire } from 'node:module'
|
|
3
3
|
import path from 'node:path'
|
|
4
4
|
import { ancestor_directories } from '#scripts/lib/ancestor-directories'
|
|
5
|
+
import { PACKAGE_JSON } from '#scripts/lib/package-manifest'
|
|
5
6
|
import { package_bin_schema } from '#scripts/lib/schemas'
|
|
6
7
|
|
|
7
8
|
const NODE_MODULES = 'node_modules'
|
|
8
9
|
const BIN_DIR = '.bin'
|
|
9
10
|
const WINDOWS_PLATFORM = 'win32'
|
|
10
11
|
const WINDOWS_SHIM_SUFFIX = '.cmd'
|
|
11
|
-
const PACKAGE_JSON = 'package.json'
|
|
12
12
|
|
|
13
13
|
// Every spawn site that reaches for a locally-installed CLI needs the same two details: pnpm
|
|
14
14
|
// writes the shims under `node_modules/.bin`, and on Windows the executable one carries a
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { cases_interaction_scan, type Findings } from './cases-interaction-scan'
|
|
3
4
|
import { cases, type Boundary } from './cases-logic'
|
|
4
5
|
|
|
5
|
-
// `josh cases <path...>` — print the I/O boundaries the changed paths cross and the
|
|
6
|
-
// each owes. The
|
|
7
|
-
// them; the required cases go on stderr so a person sees them without a
|
|
8
|
-
// The logic and the vocabulary live in `cases-logic.ts
|
|
6
|
+
// `josh cases <path...>` — print the I/O boundaries the changed paths cross, the shared state and the
|
|
7
|
+
// environment they depend on, and the abnormal cases each owes. The tokens go on stdout so
|
|
8
|
+
// `$(pnpm josh cases …)` reads them; the required cases go on stderr so a person sees them without a
|
|
9
|
+
// shell parsing around them. The logic and the vocabulary live in `cases-logic.ts` and
|
|
10
|
+
// `cases-interaction.ts`; everything here is the invocation.
|
|
9
11
|
|
|
10
12
|
const ARGV_OFFSET = 2
|
|
11
13
|
const USAGE = 'Usage: josh cases <path...>'
|
|
@@ -13,19 +15,27 @@ const FAILURE_EXIT_CODE = 1
|
|
|
13
15
|
|
|
14
16
|
function report_none(): number {
|
|
15
17
|
console.info(cases.NONE)
|
|
16
|
-
console.error(
|
|
18
|
+
console.error(
|
|
19
|
+
'no network, process, filesystem, time, shared-state or environment boundary crossed',
|
|
20
|
+
)
|
|
17
21
|
|
|
18
22
|
return 0
|
|
19
23
|
}
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
console.
|
|
25
|
+
// The interaction lines come first, as `report:template` places them at the head of "if it breaks".
|
|
26
|
+
function report_crossed(boundaries: ReadonlyArray<Boundary>, findings: Findings): number {
|
|
27
|
+
console.info([...boundaries, ...cases_interaction_scan.interactions_of(findings)].join(' '))
|
|
28
|
+
|
|
29
|
+
for (const line of cases_interaction_scan.lines_for(findings)) console.error(line)
|
|
30
|
+
|
|
31
|
+
if (boundaries.length > 0) {
|
|
32
|
+
console.error(`required abnormal cases: ${cases.cases_for(boundaries).join(' / ')}`)
|
|
33
|
+
}
|
|
24
34
|
|
|
25
35
|
return 0
|
|
26
36
|
}
|
|
27
37
|
|
|
28
|
-
function run(argv: ReadonlyArray<string>): number {
|
|
38
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
29
39
|
if (argv.length === 0) {
|
|
30
40
|
console.error(USAGE)
|
|
31
41
|
|
|
@@ -33,16 +43,18 @@ function run(argv: ReadonlyArray<string>): number {
|
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
const boundaries = cases.boundaries_in(argv)
|
|
46
|
+
const findings = await cases_interaction_scan.scan(argv)
|
|
47
|
+
const is_crossed = boundaries.length + cases_interaction_scan.interactions_of(findings).length > 0
|
|
36
48
|
|
|
37
|
-
return
|
|
49
|
+
return is_crossed ? report_crossed(boundaries, findings) : report_none()
|
|
38
50
|
}
|
|
39
51
|
|
|
40
|
-
function main(argv: ReadonlyArray<string>): void {
|
|
41
|
-
process.exitCode = run(argv)
|
|
52
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
53
|
+
process.exitCode = await run(argv)
|
|
42
54
|
}
|
|
43
55
|
|
|
44
56
|
const cases_cli = { run }
|
|
45
57
|
|
|
46
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
|
|
58
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
47
59
|
|
|
48
60
|
export { cases_cli }
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { git_grep_hits, type GrepResult } from '#scripts/git/git-grep-hits'
|
|
3
|
+
import { file_reader } from '#scripts/lib/read-file'
|
|
4
|
+
import {
|
|
5
|
+
cases_interaction,
|
|
6
|
+
type Interaction,
|
|
7
|
+
type StatePath,
|
|
8
|
+
type Wording,
|
|
9
|
+
} from './cases-interaction'
|
|
10
|
+
|
|
11
|
+
// The I/O half of `josh cases`' interaction boundaries (joshuafolkken/kit#4491): read the changed
|
|
12
|
+
// sources, then search the rest of the repository for each state path they name — by its literal and
|
|
13
|
+
// by every constant this source binds it to — so the summary lists the other readers and writers as
|
|
14
|
+
// `file:line`. Tests are left out of the search: a fixture path is not a second writer at run time.
|
|
15
|
+
|
|
16
|
+
const SOURCE_EXTENSIONS: ReadonlySet<string> = new Set(['.ts', '.js', '.mjs', '.cjs', '.svelte'])
|
|
17
|
+
const SOURCE_PATHSPECS: ReadonlyArray<string> = [
|
|
18
|
+
'*.ts',
|
|
19
|
+
'*.js',
|
|
20
|
+
'*.mjs',
|
|
21
|
+
'*.cjs',
|
|
22
|
+
'*.svelte',
|
|
23
|
+
':(exclude)*.test.ts',
|
|
24
|
+
]
|
|
25
|
+
const WHOLE_WORD = ['-w']
|
|
26
|
+
const MAX_OTHERS = 10
|
|
27
|
+
|
|
28
|
+
interface SharedState {
|
|
29
|
+
path: string
|
|
30
|
+
others: ReadonlyArray<string>
|
|
31
|
+
has_failed: boolean
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface Findings {
|
|
35
|
+
states: ReadonlyArray<SharedState>
|
|
36
|
+
variables: ReadonlyArray<string>
|
|
37
|
+
residents: ReadonlyArray<string>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function is_source(file: string): boolean {
|
|
41
|
+
return SOURCE_EXTENSIONS.has(path.extname(file))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function repo_relative(file: string): string {
|
|
45
|
+
return path.relative(process.cwd(), path.resolve(file))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// A module that declares its own constant of the same name holds its own state, not this one.
|
|
49
|
+
async function constant_hits(name: string): Promise<GrepResult> {
|
|
50
|
+
const result = await git_grep_hits.search(name, WHOLE_WORD, SOURCE_PATHSPECS)
|
|
51
|
+
const declaration = new RegExp(String.raw`\b(?:const|let|var)\s+${name}\b`, 'u')
|
|
52
|
+
const declaring = new Set(
|
|
53
|
+
result.hits.filter((hit) => declaration.test(hit.excerpt)).map((hit) => hit.path),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
return { ...result, hits: result.hits.filter((hit) => !declaring.has(hit.path)) }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function shared_state(state: StatePath, own: ReadonlySet<string>): Promise<SharedState> {
|
|
60
|
+
const results = await Promise.all([
|
|
61
|
+
git_grep_hits.search(state.path, [], SOURCE_PATHSPECS),
|
|
62
|
+
...state.constants.map(async (name) => await constant_hits(name)),
|
|
63
|
+
])
|
|
64
|
+
const sites = results
|
|
65
|
+
.flatMap((result) => result.hits)
|
|
66
|
+
.filter((hit) => !own.has(hit.path))
|
|
67
|
+
.map((hit) => `${hit.path}:${hit.line}`)
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
path: state.path,
|
|
71
|
+
others: [...new Set(sites)],
|
|
72
|
+
has_failed: results.some((result) => result.has_failed),
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function scan(paths: ReadonlyArray<string>): Promise<Findings> {
|
|
77
|
+
const content = paths
|
|
78
|
+
.filter((file) => is_source(file))
|
|
79
|
+
.map((file) => file_reader.read_if_readable(file) ?? '')
|
|
80
|
+
.join('\n')
|
|
81
|
+
const own = new Set(paths.map((file) => repo_relative(file)))
|
|
82
|
+
const states = await Promise.all(
|
|
83
|
+
cases_interaction.state_paths_in(content).map(async (state) => await shared_state(state, own)),
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
return { states, ...cases_interaction.environment_in(content) }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function interactions_of(findings: Findings): ReadonlyArray<Interaction> {
|
|
90
|
+
const has_environment = findings.variables.length + findings.residents.length > 0
|
|
91
|
+
const crossed = { state: findings.states.length > 0, env: has_environment }
|
|
92
|
+
|
|
93
|
+
return cases_interaction.INTERACTIONS.filter((interaction) => crossed[interaction])
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function others_text(state: SharedState, words: Wording): string {
|
|
97
|
+
if (state.has_failed) return words.search_failed
|
|
98
|
+
if (state.others.length === 0) return words.no_others
|
|
99
|
+
|
|
100
|
+
const shown = state.others.slice(0, MAX_OTHERS)
|
|
101
|
+
const rest = state.others.length - shown.length
|
|
102
|
+
|
|
103
|
+
return rest > 0 ? `${shown.join(', ')}, +${String(rest)}` : shown.join(', ')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function line(label: string, subject: string, owed: ReadonlyArray<string>): string {
|
|
107
|
+
return `${label} ${subject}: ${owed.join(' / ')}`
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// One line per state, variable and resident process, in that order — each carries its own subject,
|
|
111
|
+
// so the reader sees whose cases they are without a second table.
|
|
112
|
+
function lines_for(findings: Findings, lang?: string): ReadonlyArray<string> {
|
|
113
|
+
const words = cases_interaction.wording(lang)
|
|
114
|
+
const state_lines = findings.states.map((state) =>
|
|
115
|
+
line(
|
|
116
|
+
words.state,
|
|
117
|
+
`\`${state.path}\` (${words.others}: ${others_text(state, words)})`,
|
|
118
|
+
words.state_cases,
|
|
119
|
+
),
|
|
120
|
+
)
|
|
121
|
+
const variable_lines = findings.variables.map((name) =>
|
|
122
|
+
line(words.variable, `\`${name}\``, words.variable_cases),
|
|
123
|
+
)
|
|
124
|
+
const resident_lines = findings.residents.map((name) =>
|
|
125
|
+
line(words.resident, `\`${name}\``, words.resident_cases),
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
return [...state_lines, ...variable_lines, ...resident_lines]
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const cases_interaction_scan = { scan, interactions_of, lines_for }
|
|
132
|
+
|
|
133
|
+
export type { Findings, SharedState }
|
|
134
|
+
export { cases_interaction_scan }
|