@joshuafolkken/kit 1.1514.0 → 1.1784.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -1
- package/.claude/settings.json +5 -5
- package/.claude/skills/epic-commands/SKILL.md +26 -65
- package/.claude/skills/epic-commands/epic-bundle.md +3 -1
- package/.claude/skills/workflow-commands/SKILL.md +5 -5
- package/.claude/skills/workflow-commands/background-commands.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
- package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +13 -7
- package/.claude/skills/workflow-commands/delegation.md +6 -5
- package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
- package/.claude/skills/workflow-commands/followup.md +9 -31
- package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
- package/.claude/skills/workflow-commands/fullrun.md +2 -2
- package/.claude/skills/workflow-commands/halfrun.md +17 -25
- package/.claude/skills/workflow-commands/issue-comments.md +16 -12
- package/.claude/skills/workflow-commands/issue-scout.md +2 -2
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +7 -12
- package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
- package/.claude/skills/workflow-commands/observation-filing.md +4 -36
- package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
- package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
- package/.claude/skills/workflow-commands/prerequisite.md +10 -16
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +3 -7
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +13 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-node/action.yml +9 -0
- package/.github/actions/setup-pnpm/action.yml +1 -1
- package/.github/dependabot.yml +16 -0
- package/.github/release.yml +0 -2
- package/.github/workflows/ci.yml +120 -10
- package/.github/workflows/publish.yml +8 -1
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +3 -7
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +3 -7
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
- package/dist/commands/read-set-cli.js +1867 -0
- package/dist/commands/run-prep-main.js +21653 -0
- package/dist/commands/run-step-cli.js +23880 -0
- package/dist/config-merge/index.js +5 -1
- package/dist/hooks/audit-provision.js +20 -35
- package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
- package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
- package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
- package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
- package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -22
- package/dist/hooks/format-edited.js +5 -6
- package/dist/hooks/inputs.json +443 -317
- package/dist/hooks/pretool-guard.js +7 -25
- package/dist/hooks/session-lang.js +44 -51
- package/dist/hooks/stop-guard.js +7716 -2187
- package/dist/josh.js +6002 -3583
- package/dist/self-sync-guard/index.js +74 -10
- package/dist/version/index.js +115 -406
- package/eslint/base.js +1 -1
- package/lefthook/base.yml +3 -1
- package/package.json +10 -48
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -7
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +33 -16
- package/prompts/collaboration-workflow/lane-instructions.md +1 -2
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +4 -6
- package/prompts/collaboration-workflow/output-bounds.md +2 -7
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +5 -0
- package/prompts/collaboration-workflow/report-format.md +31 -60
- package/prompts/collaboration-workflow/residency.md +2 -2
- package/prompts/collaboration-workflow/shell-body.md +6 -16
- package/prompts/collaboration-workflow/turn-batching.md +0 -2
- package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
- package/prompts/collaboration-workflow/wip-cap.md +1 -1
- package/prompts/collaboration-workflow.md +3 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +41 -21
- package/prompts/testing-guide.md +8 -43
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +14 -16
- package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
- package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
- package/scripts/auto-ok/auto-ok-judge.ts +13 -2
- package/scripts/auto-ok/auto-ok-main.ts +17 -0
- package/scripts/backlog/backlog-arrival.ts +14 -3
- package/scripts/backlog/backlog-budget-cli.ts +7 -33
- package/scripts/backlog/backlog-budget-main.ts +16 -0
- package/scripts/backlog/backlog-budget.ts +2 -3
- package/scripts/backlog/backlog-defect-priority.ts +4 -3
- package/scripts/backlog/backlog-drive-adopt.ts +67 -0
- package/scripts/backlog/backlog-drive-args.ts +4 -5
- package/scripts/backlog/backlog-drive-cli.ts +113 -28
- package/scripts/backlog/backlog-drive-hold.ts +162 -0
- package/scripts/backlog/backlog-drive-idle.ts +151 -0
- package/scripts/backlog/backlog-drive-judge.ts +25 -0
- package/scripts/backlog/backlog-drive-memory.ts +126 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
- package/scripts/backlog/backlog-drive-named.ts +53 -6
- package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
- package/scripts/backlog/backlog-drive-paused.ts +169 -0
- package/scripts/backlog/backlog-drive-restore.ts +30 -7
- package/scripts/backlog/backlog-drive-seats.ts +18 -8
- package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
- package/scripts/backlog/backlog-drive.ts +79 -75
- package/scripts/backlog/backlog-next-main.ts +16 -0
- package/scripts/backlog/backlog-next-shared.ts +73 -0
- package/scripts/backlog/backlog-next.ts +48 -16
- package/scripts/backlog/backlog-occupied.ts +52 -39
- package/scripts/backlog/backlog-offer-cli.ts +6 -21
- package/scripts/backlog/backlog-offer-exclude.ts +15 -0
- package/scripts/backlog/backlog-offer-main.ts +12 -0
- package/scripts/backlog/backlog-offer.ts +36 -3
- package/scripts/backlog/backlog-overlap.ts +22 -4
- package/scripts/backlog/backlog-plan-read.ts +6 -2
- package/scripts/backlog/backlog-plan.ts +18 -4
- package/scripts/backlog/backlog-pool.ts +10 -10
- package/scripts/backlog/backlog-rank.ts +10 -2
- package/scripts/backlog/backlog-ready.ts +112 -30
- package/scripts/backlog/backlog-stalled-detect.ts +109 -36
- package/scripts/backlog/backlog-stalled.ts +52 -16
- package/scripts/backlog/backlog-wait-cause.ts +86 -0
- package/scripts/backlog/backlog-waves.ts +39 -13
- package/scripts/backlog/backlogrun-args.ts +19 -7
- package/scripts/backlog/backlogrun-cli.ts +19 -5
- package/scripts/backlog/backlogrun-launch.ts +6 -0
- package/scripts/backlog/backlogrun-restart.ts +97 -0
- package/scripts/backlog/backlogrun-stop.ts +79 -7
- package/scripts/behavior/behavior-cli.ts +2 -2
- package/scripts/behavior/behavior-rules.ts +47 -24
- package/scripts/build/build-bin.ts +2 -16
- package/scripts/build/build-claude-md.ts +0 -7
- package/scripts/build/build-commands.ts +0 -13
- package/scripts/build/build-hooks.ts +49 -48
- package/scripts/build/hook-bundle-stamp.ts +29 -11
- package/scripts/build/local-bin.ts +1 -1
- package/scripts/cases/cases-cli.ts +25 -13
- package/scripts/cases/cases-interaction-scan.ts +134 -0
- package/scripts/cases/cases-interaction.ts +183 -0
- package/scripts/cases/cases-logic.ts +39 -6
- package/scripts/ci/pr-classification-main.ts +18 -0
- package/scripts/ci/pr-classification.ts +10 -17
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/cost-runtime/cost-blocks.ts +22 -37
- package/scripts/cost-runtime/cost-cli.ts +31 -14
- package/scripts/cost-runtime/cost-main.ts +12 -0
- package/scripts/cost-runtime/cost-transcript.ts +1 -0
- package/scripts/delegation/delegation-policy.ts +17 -4
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/investigation-guard.ts +0 -8
- package/scripts/delegation/investigation-reads.ts +3 -4
- package/scripts/dependabot/dependabot-cooldown.ts +194 -0
- package/scripts/discovery/repo-discovery.ts +24 -6
- package/scripts/doctor/doctor-consumer.ts +2 -5
- package/scripts/document/document-byte-budget.ts +8 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +0 -8
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-busy.ts +5 -12
- package/scripts/epic/epic-classify.ts +24 -15
- package/scripts/epic/epic-cli-argv.ts +31 -0
- package/scripts/epic/epic-cli-decide.ts +42 -0
- package/scripts/epic/epic-cli.ts +6 -38
- package/scripts/epic/epic-close.ts +112 -55
- package/scripts/epic/epic-cross-repo.ts +4 -7
- package/scripts/epic/epic-decide.ts +119 -0
- package/scripts/epic/epic-decision.ts +9 -0
- package/scripts/epic/epic-fetch.ts +4 -0
- package/scripts/epic/epic-graph.ts +2 -0
- package/scripts/epic/epic-issue.ts +5 -1
- package/scripts/epic/epic-label-age.ts +1 -1
- package/scripts/epic/epic-lane-offer.ts +39 -4
- package/scripts/epic/epic-next-main.ts +24 -0
- package/scripts/epic/epic-next.ts +6 -24
- package/scripts/epic/epic-outside-blocker.ts +6 -2
- package/scripts/epic/epic-parse.ts +9 -3
- package/scripts/epic/epic-read.ts +1 -0
- package/scripts/epic/epic-reconcile.ts +39 -0
- package/scripts/epic/epic-run.ts +10 -1
- package/scripts/epic/epic-solo.ts +50 -14
- package/scripts/epic/epic.ts +41 -7
- package/scripts/exports/unused-members-cli.ts +2 -2
- package/scripts/followup/followup-checks-event.ts +8 -3
- package/scripts/followup/followup-coderabbit-wait.ts +82 -0
- package/scripts/followup/followup-review-gates.ts +81 -0
- package/scripts/followup/git-followup-stages.ts +13 -3
- package/scripts/followup/git-followup-workflow.ts +19 -66
- package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
- package/scripts/followup/git-pr-followup.ts +36 -8
- package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
- package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
- package/scripts/gate/busy-average.ts +58 -0
- package/scripts/gate/check-cpu.ts +60 -0
- package/scripts/gate/check-inputs.ts +39 -95
- package/scripts/gate/check-reuse.ts +33 -54
- package/scripts/gate/command-memory.ts +192 -0
- package/scripts/gate/core-admission.ts +218 -28
- package/scripts/gate/core-budget-timing.ts +37 -0
- package/scripts/gate/core-budget.ts +80 -98
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +37 -5
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +27 -4
- package/scripts/gate/gate-ledger.ts +32 -4
- package/scripts/gate/gate-plan.ts +41 -34
- package/scripts/gate/gate-report.ts +14 -2
- package/scripts/gate/gate-run-steps.ts +53 -8
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +65 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/project-checks.ts +5 -12
- package/scripts/gate/scoped-green.ts +12 -8
- package/scripts/gate/since-green.ts +62 -0
- package/scripts/gate/toolchain-inputs.ts +115 -0
- package/scripts/gate/verification-gate.ts +27 -24
- package/scripts/gate/verification-inputs.ts +250 -0
- package/scripts/gh/gh-author-association.ts +96 -9
- package/scripts/gh/git-ai-review-scan.ts +4 -2
- package/scripts/gh/git-gh-api-path.ts +15 -0
- package/scripts/gh/git-gh-branch-rules.ts +73 -0
- package/scripts/gh/git-gh-conditional.ts +5 -2
- package/scripts/gh/git-gh-issue-read.ts +5 -1
- package/scripts/gh/git-gh-issue-write.ts +67 -29
- package/scripts/gh/git-gh-issue.ts +7 -3
- package/scripts/gh/git-gh-poll-read.ts +89 -0
- package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
- package/scripts/gh/git-gh-pr-rest.ts +1 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
- package/scripts/gh/git-gh-pr.ts +27 -15
- package/scripts/gh/git-pr-checks-eval.ts +39 -7
- package/scripts/gh/git-pr-checks-parse.ts +39 -9
- package/scripts/gh/git-pr-merge-checked.ts +80 -0
- package/scripts/git/base-tree.ts +19 -2
- package/scripts/git/changed-file-scope.ts +6 -4
- package/scripts/git/changed-paths.ts +18 -1
- package/scripts/git/git-diff-reads.ts +27 -2
- package/scripts/git/git-grep-hits.ts +85 -0
- package/scripts/git/git-location-environment.ts +1 -1
- package/scripts/git/git-merge-conflicts.ts +83 -0
- package/scripts/git/git-preflight.ts +37 -12
- package/scripts/git/git-push-transport.ts +1 -2
- package/scripts/git/git-schemas.ts +17 -7
- package/scripts/git/git-spawn.ts +1 -2
- package/scripts/git/git-status.ts +4 -4
- package/scripts/git/main-merge-main.ts +12 -0
- package/scripts/git/main-merge-regenerate.ts +2 -2
- package/scripts/git/main-merge.ts +25 -9
- package/scripts/git/main-sync-main.ts +12 -0
- package/scripts/git/main-sync.ts +0 -9
- package/scripts/git/stash/git-stash.ts +27 -4
- package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
- package/scripts/git/stash/stash-pop-cli.ts +6 -12
- package/scripts/git/stash/stash-pop-main.ts +12 -0
- package/scripts/git/stash/stash-push-cli.ts +76 -0
- package/scripts/git/stash/stash-push-main.ts +12 -0
- package/scripts/hooks/batch-guard.ts +0 -8
- package/scripts/hooks/check-commit-message-main.ts +8 -0
- package/scripts/hooks/check-commit-message.ts +4 -7
- package/scripts/hooks/format-edited-file.ts +8 -24
- package/scripts/hooks/pre-commit-lint.ts +30 -3
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +32 -19
- package/scripts/hooks/reserved-run.ts +67 -9
- package/scripts/hooks/run-hook.sh +13 -4
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +2 -21
- package/scripts/hooks/stop-guard.ts +13 -9
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -17
- package/scripts/init/init-actions.ts +0 -6
- package/scripts/init/init-ai-copy.ts +10 -36
- package/scripts/init/init-bootstrap.ts +9 -8
- package/scripts/init/init-dry-run-report.ts +1 -1
- package/scripts/init/init-dry-run.ts +1 -1
- package/scripts/init/init-file-action.ts +7 -9
- package/scripts/init/init-logic-json-merge.ts +2 -2
- package/scripts/init/init-logic-migrate.ts +9 -82
- package/scripts/init/init-logic.ts +3 -2
- package/scripts/init/init-main.ts +12 -0
- package/scripts/init/init.ts +5 -12
- package/scripts/init/kit-development-versions.ts +3 -7
- package/scripts/init/kit-written-paths.ts +2 -2
- package/scripts/init/project-profile.ts +5 -4
- package/scripts/init/tsconfig-preset-migration.ts +2 -1
- package/scripts/init/vscode-tasks.ts +1 -1
- package/scripts/issue/defect-origin-cli.ts +106 -0
- package/scripts/issue/defect-origin-line.ts +60 -0
- package/scripts/issue/defect-origin-main.ts +11 -0
- package/scripts/issue/defect-origin.ts +114 -0
- package/scripts/issue/defect-rate-cli.ts +34 -78
- package/scripts/issue/defect-rate.ts +0 -16
- package/scripts/issue/defect-report-cli.ts +128 -0
- package/scripts/issue/defect-report-format.ts +56 -0
- package/scripts/issue/defect-report-main.ts +11 -0
- package/scripts/issue/defect-report.ts +160 -0
- package/scripts/issue/expected-effect-lint.ts +1 -0
- package/scripts/issue/issue-already-done-cli.ts +62 -0
- package/scripts/issue/issue-body-or-comment.ts +40 -0
- package/scripts/issue/issue-cite-cli.ts +0 -9
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +12 -7
- package/scripts/issue/issue-comment-cli.ts +10 -24
- package/scripts/issue/issue-comment-main.ts +12 -0
- package/scripts/issue/issue-evidence-exit.ts +100 -0
- package/scripts/issue/issue-file-cli.ts +29 -7
- package/scripts/issue/issue-file.ts +19 -19
- package/scripts/issue/issue-fold-cli.ts +2 -11
- package/scripts/issue/issue-fold-main.ts +12 -0
- package/scripts/issue/issue-labels.ts +81 -90
- package/scripts/issue/issue-lint-cli.ts +2 -10
- package/scripts/issue/issue-lint-main.ts +12 -0
- package/scripts/issue/issue-measured-cli.ts +56 -0
- package/scripts/issue/issue-merged.ts +19 -2
- package/scripts/issue/issue-not-before-label.ts +135 -0
- package/scripts/issue/issue-not-before.ts +111 -0
- package/scripts/issue/issue-number-shape.ts +15 -1
- package/scripts/issue/issue-park.ts +28 -0
- package/scripts/issue/issue-plan-cli.ts +151 -0
- package/scripts/issue/issue-priority.ts +151 -0
- package/scripts/issue/issue-rank.ts +7 -1
- package/scripts/issue/issue-read-cli.ts +3 -10
- package/scripts/issue/issue-read-main.ts +12 -0
- package/scripts/issue/issue-read.ts +29 -5
- package/scripts/issue/issue-release-cli.ts +0 -10
- package/scripts/issue/issue-release-main.ts +13 -0
- package/scripts/issue/issue-release.ts +7 -12
- package/scripts/issue/issue-sample-gate.ts +192 -0
- package/scripts/issue/issue-sample-source.ts +76 -0
- package/scripts/issue/issue-scout-cli.ts +0 -11
- package/scripts/issue/issue-scout-main.ts +14 -0
- package/scripts/issue/issue-state-cli.ts +0 -10
- package/scripts/issue/issue-state-main.ts +12 -0
- package/scripts/issue/issue-watch-diff.ts +56 -15
- package/scripts/issue/issue-watch.ts +2 -1
- package/scripts/issue/issue-wip.ts +2 -7
- package/scripts/issue/measure-rerun-cli.ts +13 -8
- package/scripts/issue/plan-consumers-cli.ts +39 -0
- package/scripts/issue/plan-consumers-main.ts +11 -0
- package/scripts/issue/plan-consumers-section.ts +55 -0
- package/scripts/issue/plan-consumers.ts +127 -0
- package/scripts/josh/agent-session-environment.ts +1 -1
- package/scripts/josh/command-usage.ts +15 -43
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +12 -6
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +157 -158
- package/scripts/josh/josh-commands-backlog.ts +82 -16
- package/scripts/josh/josh-commands-clone.ts +1 -0
- package/scripts/josh/josh-commands-development.ts +111 -71
- package/scripts/josh/josh-commands-document.ts +43 -1
- package/scripts/josh/josh-commands-epic.ts +171 -0
- package/scripts/josh/josh-commands-hooks.ts +25 -2
- package/scripts/josh/josh-commands-issue-write.ts +181 -0
- package/scripts/josh/josh-commands-issue.ts +124 -24
- package/scripts/josh/josh-commands-lane.ts +103 -2
- package/scripts/josh/josh-commands-lint.ts +19 -8
- package/scripts/josh/josh-commands-maintenance.ts +112 -4
- package/scripts/josh/josh-commands-pause.ts +29 -0
- package/scripts/josh/josh-commands-progress.ts +87 -0
- package/scripts/josh/josh-commands-project.ts +138 -9
- package/scripts/josh/josh-commands-review.ts +124 -0
- package/scripts/josh/josh-commands-run.ts +211 -23
- package/scripts/josh/josh-commands-ship.ts +169 -0
- package/scripts/josh/josh-commands-split.ts +9 -0
- package/scripts/josh/josh-commands-versioning.ts +49 -2
- package/scripts/josh/josh-commands-workflow.ts +144 -6
- package/scripts/josh/josh-logic.ts +6 -13
- package/scripts/josh/package-directory.ts +2 -4
- package/scripts/josh/process-identity.ts +13 -4
- package/scripts/josh/session-language-cli.ts +4 -8
- package/scripts/josh/session-language-main.ts +13 -0
- package/scripts/josh/session-language.ts +6 -1
- package/scripts/josh/shared-cache.ts +90 -0
- package/scripts/josh/stamp-file.ts +9 -15
- package/scripts/lane/lane-await.ts +51 -12
- package/scripts/lane/lane-cache.ts +5 -30
- package/scripts/lane/lane-capacity.ts +14 -23
- package/scripts/lane/lane-check-stats.ts +62 -21
- package/scripts/lane/lane-child-invocation.ts +8 -0
- package/scripts/lane/lane-cli.ts +15 -5
- package/scripts/lane/lane-close.ts +86 -18
- package/scripts/lane/lane-core-wait-stats.ts +66 -0
- package/scripts/lane/lane-dispatch.ts +24 -3
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-handoff.ts +69 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +4 -11
- package/scripts/lane/lane-launch-cli.ts +0 -9
- package/scripts/lane/lane-launch-main.ts +12 -0
- package/scripts/lane/lane-ledger-schema.ts +266 -0
- package/scripts/lane/lane-ledger.ts +92 -123
- package/scripts/lane/lane-limit-cli.ts +12 -1
- package/scripts/lane/lane-measure-cli.ts +57 -11
- package/scripts/lane/lane-open.ts +9 -1
- package/scripts/lane/lane-parked.ts +3 -3
- package/scripts/lane/lane-pause-cli.ts +130 -0
- package/scripts/lane/lane-pause.ts +158 -0
- package/scripts/lane/lane-process-table.ts +166 -0
- package/scripts/lane/lane-reap-settle.ts +124 -0
- package/scripts/lane/lane-reap.ts +50 -15
- package/scripts/lane/lane-registry.ts +24 -3
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +22 -2
- package/scripts/lane/lane-round-two-stats.ts +49 -0
- package/scripts/lane/lane-sampler.ts +4 -0
- package/scripts/lane/lane-session-action.ts +19 -5
- package/scripts/lane/lane-session-broker.ts +102 -21
- package/scripts/lane/lane-snapshot-trace.ts +84 -0
- package/scripts/lane/lane-spans.ts +51 -0
- package/scripts/lane/lane-spent.ts +6 -3
- package/scripts/lane/lane-stage-stats.ts +7 -2
- package/scripts/lane/lane-state.ts +302 -0
- package/scripts/lane/lane-stats.ts +58 -4
- package/scripts/lane/lane-stop-stats.ts +113 -37
- package/scripts/lane/lane-test-related-stats.ts +127 -0
- package/scripts/lane/lane-transcript-calls.ts +145 -0
- package/scripts/lane/lane-transcript-stats.ts +168 -0
- package/scripts/lane/lane-vacant.ts +13 -3
- package/scripts/lane/lane-withdraw-cli.ts +5 -4
- package/scripts/lane/lane-withdraw.ts +50 -49
- package/scripts/lane/process-directories.ts +70 -0
- package/scripts/lane/process-lane-marks.ts +94 -0
- package/scripts/lib/atomic-write.ts +62 -0
- package/scripts/lib/buffered-process.ts +12 -5
- package/scripts/lib/cli-flags.ts +53 -0
- package/scripts/lib/figure-format.ts +63 -0
- package/scripts/lib/json-value.ts +9 -1
- package/scripts/lib/package-manifest.ts +35 -0
- package/scripts/lib/read-file.ts +3 -1
- package/scripts/lib/stamped-memo.ts +63 -0
- package/scripts/lib/stdout-on-stderr.ts +24 -0
- package/scripts/lib/timeouts.ts +9 -0
- package/scripts/lib/transcript-record.ts +91 -0
- package/scripts/lines/effective-limit.ts +1 -1
- package/scripts/lint/eslint-cache-dependencies.ts +145 -0
- package/scripts/lint/eslint-daemon.ts +265 -0
- package/scripts/lint/format.ts +11 -2
- package/scripts/lint/import-graph.ts +279 -0
- package/scripts/lint/lint-gate-scope.ts +102 -0
- package/scripts/lint/lint-parallel-main.ts +19 -0
- package/scripts/lint/lint-parallel.ts +62 -30
- package/scripts/lint/lint-related-scope.ts +30 -24
- package/scripts/lint/lint-related.ts +38 -6
- package/scripts/notify/confirmation-options.ts +1 -2
- package/scripts/notify/telegram-notify.ts +20 -20
- package/scripts/notify/telegram-test-logic.ts +0 -1
- package/scripts/notify/telegram-test-main.ts +8 -0
- package/scripts/notify/telegram-test.ts +2 -6
- package/scripts/observations/observation-ledger.ts +13 -0
- package/scripts/observations/observations-flush-landing.ts +5 -3
- package/scripts/observations/observations-flush.ts +6 -1
- package/scripts/overrides/overrides-check.ts +2 -5
- package/scripts/overrides/overrides-files.ts +2 -1
- package/scripts/overrides/overrides-logic.ts +3 -6
- package/scripts/package/verify-optional-eslint-install.ts +8 -6
- package/scripts/propagate/propagate-publish.ts +2 -7
- package/scripts/propagate/propagate-targets.ts +4 -12
- package/scripts/refactor/import-graph.ts +9 -7
- package/scripts/release/github-release-runs.ts +17 -6
- package/scripts/release/release-approval-prune.ts +18 -0
- package/scripts/release/release-history.ts +1 -3
- package/scripts/release/release-progress.ts +42 -22
- package/scripts/release/release-publish-run.ts +39 -0
- package/scripts/release/release-publish.ts +6 -6
- package/scripts/release/release-scope-cli.ts +0 -10
- package/scripts/release/release-scope-main.ts +12 -0
- package/scripts/repo/repo-setting.ts +3 -6
- package/scripts/repo/required-checks-logic.ts +6 -15
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-labels.ts +155 -0
- package/scripts/report/report-lint-cli.ts +3 -0
- package/scripts/report/report-lint.ts +85 -110
- package/scripts/report/report-template-cli.ts +59 -0
- package/scripts/report/report-template.ts +112 -0
- package/scripts/review/acceptance-map.ts +1 -0
- package/scripts/review/removed-tests-check.ts +86 -0
- package/scripts/review/removed-tests.ts +149 -0
- package/scripts/review/review-brief-cli.ts +81 -15
- package/scripts/review/review-brief-main.ts +12 -0
- package/scripts/review/review-brief.ts +31 -3
- package/scripts/review/review-code-tree.ts +10 -6
- package/scripts/review/review-comment-round.ts +26 -8
- package/scripts/review/review-finding-ledger.ts +30 -15
- package/scripts/review/review-interaction.ts +94 -0
- package/scripts/review/review-readers-scan.ts +163 -0
- package/scripts/review/review-record-cli.ts +69 -30
- package/scripts/review/review-record-main.ts +12 -0
- package/scripts/review/review-round-one-blobs.ts +221 -0
- package/scripts/review/review-round2-cli.ts +49 -12
- package/scripts/review/review-round2.ts +80 -12
- package/scripts/review/review-stamps.ts +19 -1
- package/scripts/review/review-stop-log.ts +96 -0
- package/scripts/review/review-stops-cli.ts +85 -0
- package/scripts/review/review-tree.ts +6 -17
- package/scripts/review/review-untouched-readers.ts +146 -0
- package/scripts/review/test-titles.ts +118 -0
- package/scripts/rules/agent-model.ts +8 -0
- package/scripts/rules/bash-triggers.ts +46 -3
- package/scripts/rules/decision-oracle-batch.ts +9 -1
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +80 -2
- package/scripts/rules/destructive-command.ts +8 -1
- package/scripts/rules/direct-filing.ts +10 -2
- package/scripts/rules/direct-issue-comment.ts +117 -0
- package/scripts/rules/direct-pr-create.ts +69 -3
- package/scripts/rules/early-heartbeat.ts +2 -1
- package/scripts/rules/file-body.ts +7 -0
- package/scripts/rules/filing-cap.ts +7 -0
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +4 -0
- package/scripts/rules/implementation-cut-verdict.ts +1 -1
- package/scripts/rules/implementation-cut.ts +11 -3
- package/scripts/rules/index-guard.ts +8 -1
- package/scripts/rules/issue-comments.ts +9 -1
- package/scripts/rules/josh-git-bare.ts +7 -0
- package/scripts/rules/lane-background.ts +67 -25
- package/scripts/rules/lane-carry-conflict.ts +6 -0
- package/scripts/rules/lane-direct-tool.ts +74 -0
- package/scripts/rules/lane-interactive-ask.ts +9 -2
- package/scripts/rules/lane-park.ts +45 -23
- package/scripts/rules/lane-split-park.ts +10 -2
- package/scripts/rules/lane-switch-main.ts +7 -0
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +1 -1
- package/scripts/rules/poll-loop.ts +7 -0
- package/scripts/rules/pr-merge.ts +123 -0
- package/scripts/rules/protected-files.ts +32 -5
- package/scripts/rules/raw-field-body.ts +6 -0
- package/scripts/rules/rule-body-guard.ts +8 -0
- package/scripts/rules/rule-list.ts +9 -28
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +1 -1
- package/scripts/rules/shell-segments.ts +35 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +3 -4
- package/scripts/rules/test-declared-commit.ts +11 -1
- package/scripts/rules/third-party-write.ts +7 -0
- package/scripts/rules/timed-rerun.ts +69 -0
- package/scripts/rules/worktree-guard.ts +13 -3
- package/scripts/run/board/run-board-app-name.ts +23 -0
- package/scripts/run/board/run-board-cli.ts +65 -32
- package/scripts/run/board/run-board-earlier.ts +94 -0
- package/scripts/run/board/run-board-ending-reason.ts +67 -0
- package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
- package/scripts/run/board/run-board-estimate.ts +98 -0
- package/scripts/run/board/run-board-fit.ts +153 -36
- package/scripts/run/board/run-board-fold.ts +123 -0
- package/scripts/run/board/run-board-fresh.ts +2 -2
- package/scripts/run/board/run-board-gather-live.ts +29 -0
- package/scripts/run/board/run-board-gather-thread.ts +189 -0
- package/scripts/run/board/run-board-gather-worker.ts +29 -0
- package/scripts/run/board/run-board-gather.ts +187 -0
- package/scripts/run/board/run-board-github.ts +118 -38
- package/scripts/run/board/run-board-header.ts +82 -20
- package/scripts/run/board/run-board-keys.ts +58 -0
- package/scripts/run/board/run-board-kind.ts +20 -6
- package/scripts/run/board/run-board-labels.ts +116 -71
- package/scripts/run/board/run-board-lane-state.ts +109 -0
- package/scripts/run/board/run-board-lane-time.ts +122 -0
- package/scripts/run/board/run-board-layout.ts +239 -60
- package/scripts/run/board/run-board-length.ts +52 -0
- package/scripts/run/board/run-board-machine.ts +8 -4
- package/scripts/run/board/run-board-main.ts +12 -0
- package/scripts/run/board/run-board-notes.ts +52 -31
- package/scripts/run/board/run-board-now.ts +1 -1
- package/scripts/run/board/run-board-operation.ts +15 -33
- package/scripts/run/board/run-board-phase.ts +1 -1
- package/scripts/run/board/run-board-plan-shared.ts +115 -0
- package/scripts/run/board/run-board-plan.ts +55 -3
- package/scripts/run/board/run-board-planning.ts +45 -0
- package/scripts/run/board/run-board-priority.ts +44 -0
- package/scripts/run/board/run-board-process-groups.ts +195 -0
- package/scripts/run/board/run-board-read.ts +151 -27
- package/scripts/run/board/run-board-reason.ts +235 -51
- package/scripts/run/board/run-board-released.ts +35 -0
- package/scripts/run/board/run-board-render-checks.ts +39 -5
- package/scripts/run/board/run-board-render-condition.ts +96 -0
- package/scripts/run/board/run-board-render-drawn.ts +67 -0
- package/scripts/run/board/run-board-render-foot.ts +59 -0
- package/scripts/run/board/run-board-render-icon.ts +35 -0
- package/scripts/run/board/run-board-render-lanes.ts +145 -0
- package/scripts/run/board/run-board-render-lead.ts +80 -0
- package/scripts/run/board/run-board-render-legend.ts +117 -48
- package/scripts/run/board/run-board-render-notes.ts +156 -29
- package/scripts/run/board/run-board-render-processes.ts +196 -0
- package/scripts/run/board/run-board-render-section.ts +119 -0
- package/scripts/run/board/run-board-render-slot.ts +3 -36
- package/scripts/run/board/run-board-render-tail.ts +115 -48
- package/scripts/run/board/run-board-render-time.ts +56 -0
- package/scripts/run/board/run-board-render-title.ts +117 -24
- package/scripts/run/board/run-board-render-waits.ts +104 -20
- package/scripts/run/board/run-board-render.ts +207 -265
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +9 -4
- package/scripts/run/board/run-board-setup.ts +1 -12
- package/scripts/run/board/run-board-snapshot.ts +111 -0
- package/scripts/run/board/run-board-spin.ts +2 -2
- package/scripts/run/board/run-board-state.ts +22 -33
- package/scripts/run/board/run-board-status.ts +147 -71
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +122 -107
- package/scripts/run/board/run-board-usage-board.ts +78 -0
- package/scripts/run/board/run-board-usage-lanes.ts +113 -0
- package/scripts/run/board/run-board-usage-listing.ts +93 -0
- package/scripts/run/board/run-board-usage-read.ts +120 -150
- package/scripts/run/board/run-board-usage-rusage.ts +19 -7
- package/scripts/run/board/run-board-usage-text.ts +139 -51
- package/scripts/run/board/run-board-usage-top.ts +102 -0
- package/scripts/run/board/run-board-usage.ts +89 -72
- package/scripts/run/board/run-board-usual.ts +20 -9
- package/scripts/run/carry/run-carry-args.ts +4 -7
- package/scripts/run/carry/run-carry-conversation.ts +1 -1
- package/scripts/run/carry/run-carry.ts +9 -4
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/event/run-event-cli.ts +1 -5
- package/scripts/run/event/run-event-filed.ts +12 -6
- package/scripts/run/event/run-event-follow.ts +2 -3
- package/scripts/run/event/run-event-render.ts +6 -10
- package/scripts/run/event/run-event-scope.ts +2 -2
- package/scripts/run/event/run-event-stream-emit.ts +82 -22
- package/scripts/run/event/run-event-stream.ts +34 -8
- package/scripts/run/hold/run-hold-adopt.ts +65 -0
- package/scripts/run/hold/run-hold-cli.ts +93 -22
- package/scripts/run/hold/run-hold-main.ts +12 -0
- package/scripts/run/hold/run-hold-member.ts +37 -0
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +62 -48
- package/scripts/run/merge/run-merge-close.ts +74 -0
- package/scripts/run/merge/run-merge-collect.ts +6 -13
- package/scripts/run/merge/run-merge-driver.ts +71 -0
- package/scripts/run/merge/run-merge-main.ts +12 -0
- package/scripts/run/merge/run-merge-outcome.ts +23 -0
- package/scripts/run/merge/run-merge-restart.ts +39 -0
- package/scripts/run/merge/run-merge-ship.ts +20 -4
- package/scripts/run/merge/run-merge-signals.ts +33 -9
- package/scripts/run/merge/run-merge-steps.ts +120 -85
- package/scripts/run/merge/run-merge.ts +38 -37
- package/scripts/run/park/run-park-cli.ts +91 -0
- package/scripts/run/park/run-park.ts +88 -0
- package/scripts/run/park/run-stalled.ts +68 -0
- package/scripts/run/pause/run-pause-cli.ts +73 -0
- package/scripts/run/pause/run-pause.ts +251 -0
- package/scripts/run/progress/run-progress-cli.ts +4 -12
- package/scripts/run/progress/run-progress-clock.ts +1 -1
- package/scripts/run/progress/run-progress-config.ts +6 -14
- package/scripts/run/progress/run-progress-main.ts +12 -0
- package/scripts/run/progress/run-progress.ts +1 -4
- package/scripts/run/review/run-review.ts +2 -1
- package/scripts/run/run-ending.ts +1 -0
- package/scripts/run/run-invocation.ts +5 -6
- package/scripts/run/run-liveness-cli.ts +6 -8
- package/scripts/run/run-liveness.ts +60 -29
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-preflight.ts +18 -3
- package/scripts/run/run-prep-cli.ts +1 -10
- package/scripts/run/run-prep-locate.ts +7 -50
- package/scripts/run/run-prep-main.ts +12 -0
- package/scripts/run/run-prep.ts +6 -0
- package/scripts/run/run-report-cli.ts +101 -13
- package/scripts/run/run-report-handoff.ts +114 -0
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +13 -0
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +1 -1
- package/scripts/run/ship/run-ship-args.ts +121 -0
- package/scripts/run/ship/run-ship-body-draft.ts +110 -0
- package/scripts/run/ship/run-ship-cli.ts +63 -140
- package/scripts/run/ship/run-ship-detach.ts +19 -8
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +18 -2
- package/scripts/run/ship/run-ship-overlap.ts +42 -5
- package/scripts/run/ship/run-ship-place.ts +96 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
- package/scripts/run/ship/run-ship-preflight.ts +137 -32
- package/scripts/run/ship/run-ship-probe.ts +11 -3
- package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
- package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
- package/scripts/run/ship/run-ship-return.ts +107 -23
- package/scripts/run/ship/run-ship-review-steps.ts +105 -151
- package/scripts/run/ship/run-ship-review.ts +73 -6
- package/scripts/run/ship/run-ship-reviewer.ts +207 -0
- package/scripts/run/ship/run-ship-stage.ts +55 -6
- package/scripts/run/ship/run-ship-steps.ts +46 -15
- package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +43 -6
- package/scripts/run/ship/run-ship.ts +30 -2
- package/scripts/run/tidy/run-tidy-cli.ts +0 -4
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
- package/scripts/run/tidy/run-tidy-main.ts +8 -0
- package/scripts/run/wake/run-wake-cli.ts +119 -100
- package/scripts/run/wake/run-wake-code.ts +83 -0
- package/scripts/run/wake/run-wake-driver.ts +19 -8
- package/scripts/run/wake/run-wake-loop.ts +34 -3
- package/scripts/run/wake/run-wake-main.ts +13 -0
- package/scripts/run/wake/run-wake-ports.ts +90 -0
- package/scripts/run/wake/run-wake-takeover.ts +66 -0
- package/scripts/run/wake/run-wake.ts +2 -1
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -1
- package/scripts/safe-chain/project-config.ts +3 -9
- package/scripts/security/security-audit-main.ts +8 -0
- package/scripts/security/security-audit-provision-logic.ts +0 -11
- package/scripts/security/security-audit-provision-main.ts +12 -0
- package/scripts/security/security-audit-provision.ts +11 -26
- package/scripts/security/security-audit.ts +6 -7
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
- package/scripts/split/split-assess-cli.ts +2 -2
- package/scripts/split/split-assess.ts +15 -0
- package/scripts/split/split-measure.ts +65 -0
- package/scripts/sync/claude-settings-merge.ts +8 -15
- package/scripts/sync/directory-copy-guard.ts +4 -9
- package/scripts/sync/file-content.ts +78 -8
- package/scripts/sync/sync-ai-files.ts +3 -5
- package/scripts/sync/sync-configs.ts +11 -23
- package/scripts/sync/sync-hook-safety.ts +4 -10
- package/scripts/sync/sync-main.ts +11 -0
- package/scripts/sync/sync.ts +25 -37
- package/scripts/test/test-declared-changed.ts +2 -2
- package/scripts/test/test-declared.ts +1 -1
- package/scripts/test/test-e2e-guard.ts +25 -1
- package/scripts/test/test-e2e-stamp.ts +38 -0
- package/scripts/test/test-pinned-logic.ts +145 -0
- package/scripts/test/test-pinned-main.ts +78 -0
- package/scripts/test/test-pinned.ts +100 -0
- package/scripts/test/test-read-map.ts +264 -0
- package/scripts/test/test-read-recording.ts +91 -0
- package/scripts/test/test-read-trace.ts +148 -0
- package/scripts/test/test-red-main.ts +12 -0
- package/scripts/test/test-red.ts +12 -30
- package/scripts/test/test-related-main.ts +18 -0
- package/scripts/test/test-related-record.ts +119 -0
- package/scripts/test/test-related-scope.ts +229 -43
- package/scripts/test/test-related.ts +300 -22
- package/scripts/test/test-unit-guard-main.ts +15 -0
- package/scripts/test/test-unit-guard.ts +42 -24
- package/scripts/test/unit-count-file.ts +37 -0
- package/scripts/test/unit-run-marker.ts +162 -0
- package/scripts/test/unit-setup-files.ts +51 -0
- package/scripts/test/unit-worker-share.ts +61 -149
- package/scripts/test/whole-suite-files.ts +63 -0
- package/scripts/time-runtime/time-background.ts +20 -2
- package/scripts/time-runtime/time-bundles.ts +4 -3
- package/scripts/time-runtime/time-density-hook.ts +8 -6
- package/scripts/time-runtime/time-followup-stage.ts +1 -3
- package/scripts/time-runtime/time-format.ts +5 -28
- package/scripts/time-runtime/time-markers.ts +10 -1
- package/scripts/time-runtime/time-shell.ts +97 -10
- package/scripts/time-runtime/time-transcript-line.ts +49 -62
- package/scripts/uninstall/uninstall.ts +1 -1
- package/scripts/version/bump-version-main.ts +12 -0
- package/scripts/version/bump-version.ts +25 -25
- package/scripts/version/effective-upstream.ts +6 -12
- package/scripts/version/latest-corepack.ts +17 -32
- package/scripts/version/latest-if-required-cli.ts +93 -0
- package/scripts/version/latest-lane-guard-main.ts +8 -0
- package/scripts/version/latest-lane-guard.ts +0 -4
- package/scripts/version/latest-scope-cli.ts +0 -9
- package/scripts/version/latest-scope-main.ts +12 -0
- package/scripts/version/latest-update.ts +5 -5
- package/scripts/version/npm-registry.ts +44 -6
- package/scripts/version/publishable-range-check.ts +5 -16
- package/scripts/version/release-age.ts +1 -1
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/release-window.ts +38 -0
- package/scripts/version/running-binary.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +3 -8
- package/scripts/version/version-targets.ts +6 -28
- package/templates/dependabot.yml +29 -0
- package/templates/gitignore +4 -1
- package/templates/pnpm-workspace.basic.yaml +1 -1
- package/templates/sonar-project.properties +3 -2
- package/templates/workflows/ci.yml +12 -4
- package/templates/workflows/github-release.yml +4 -0
- package/tsconfig.sonar.json +1 -1
- package/.ncurc.json +0 -3
- package/dist/hooks/batch-guard.js +0 -29
- package/dist/hooks/chunk-4KKD2UTK.js +0 -66
- package/dist/hooks/chunk-6TS2JD6D.js +0 -237
- package/dist/hooks/chunk-7DSBJVFH.js +0 -50
- package/dist/hooks/chunk-A65Y4YOR.js +0 -79
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EFXE6C37.js +0 -81
- package/dist/hooks/chunk-GP4IEC4O.js +0 -20
- package/dist/hooks/chunk-JP45SOCJ.js +0 -56
- package/dist/hooks/chunk-LAOV7NLM.js +0 -45
- package/dist/hooks/chunk-M4HGZV7U.js +0 -83
- package/dist/hooks/chunk-PF2NZL2A.js +0 -131
- package/dist/hooks/chunk-PTICX4OL.js +0 -358
- package/dist/hooks/chunk-RT27QRJW.js +0 -6247
- package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
- package/dist/hooks/chunk-UPUZF3AN.js +0 -279
- package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -29
- package/scripts/backlog/backlog-stalled-cli.ts +0 -30
- package/scripts/cost-runtime/cost-format.ts +0 -29
- package/scripts/init/basic-path-migration.ts +0 -24
- package/scripts/issue/issue-backlinks-cli.ts +0 -93
- package/scripts/josh/josh-commands-guard.ts +0 -38
- package/scripts/josh/josh-usage-automation.ts +0 -121
- package/scripts/josh/josh-usage-backlog.ts +0 -180
- package/scripts/josh/josh-usage-developer.ts +0 -230
- package/scripts/josh/josh-usage-hooks.ts +0 -38
- package/scripts/josh/josh-usage-issue.ts +0 -205
- package/scripts/josh/josh-usage-review.ts +0 -101
- package/scripts/josh/josh-usage-run.ts +0 -252
- package/scripts/josh/josh-usage-session.ts +0 -238
- package/scripts/josh/josh-usage-workflow.ts +0 -212
- package/scripts/lint/cross-file-recheck.ts +0 -155
- package/scripts/registry-migration/migrate-logic.ts +0 -237
- package/scripts/registry-migration/migrate.ts +0 -292
- package/scripts/registry-migration/user-npmrc.ts +0 -15
- package/scripts/rules/rule-guard.ts +0 -23
- package/scripts/rules/rule-registry-rows.ts +0 -292
- package/scripts/rules/rule-registry.ts +0 -112
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto'
|
|
2
|
+
import type { AgentProfile } from '#scripts/agent/agent-role-profile'
|
|
3
|
+
import { lane_close } from '#scripts/lane/lane-close'
|
|
4
|
+
import { poll } from '#scripts/lib/poll'
|
|
5
|
+
import { run_carry } from '#scripts/run/carry/run-carry'
|
|
6
|
+
import { run_event_setup } from '#scripts/run/event/run-event-setup'
|
|
7
|
+
import { run_headless } from '#scripts/run/run-headless'
|
|
8
|
+
import type { WakeContext } from './run-wake-describe'
|
|
9
|
+
import { run_wake_driver } from './run-wake-driver'
|
|
10
|
+
import { run_wake_handoff } from './run-wake-handoff'
|
|
11
|
+
import type { LoopPorts } from './run-wake-loop'
|
|
12
|
+
import { run_wake_session, type LaunchResult } from './run-wake-session'
|
|
13
|
+
|
|
14
|
+
// The production ports of the supervisor's loop (`run-wake-loop.ts` → `LoopPorts`), and the session
|
|
15
|
+
// launch they wake through.
|
|
16
|
+
|
|
17
|
+
// **The note covers both ways `wake_argv` answers `undefined`**, because it cannot tell them apart and
|
|
18
|
+
// a message that named only the first would accuse a legitimate invocation of carrying unsafe text.
|
|
19
|
+
// The second is the one a person actually meets: a `queue` whose references carry a `owner/repo#`
|
|
20
|
+
// prefix is a grammar this supervisor does not rebuild, and `queue.md` → "The session boundary" is why
|
|
21
|
+
// such a queue begins no record in the first place.
|
|
22
|
+
const UNSAFE_INVOCATION_NOTE =
|
|
23
|
+
'the carried invocation is not one this supervisor can continue — it is neither a backlogrun nor a queue it can rebuild, or it carries text that may not be passed to a command line'
|
|
24
|
+
|
|
25
|
+
function note_to_stderr(note: string): void {
|
|
26
|
+
console.error(`wake: ${note}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// **A session that started is said on the stream.** The driver's `waiting on judgment` is the moment it
|
|
30
|
+
// asked; from here a session is at work on the answer, until the supervisor's next hand-off.
|
|
31
|
+
function say_session_running(context: WakeContext): void {
|
|
32
|
+
run_event_setup.emit_to(context.event_target, run_event_setup.STAGE.SESSION, new Date())
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function wake_session(
|
|
36
|
+
context: WakeContext,
|
|
37
|
+
invocation: string,
|
|
38
|
+
profile: AgentProfile,
|
|
39
|
+
session: { id: string; material: string },
|
|
40
|
+
): LaunchResult {
|
|
41
|
+
const built = run_wake_session.wake_argv(invocation, profile, context.worktree, session)
|
|
42
|
+
|
|
43
|
+
if (built === undefined) return { kind: 'failed', note: UNSAFE_INVOCATION_NOTE }
|
|
44
|
+
if (built.kind === 'rejected') return { kind: 'failed', note: built.note }
|
|
45
|
+
|
|
46
|
+
// The headless mark is what lets the stop hook hold this session's turn open while its lanes run —
|
|
47
|
+
// under `claude -p` a turn-end is the process's end (`run-headless.ts`).
|
|
48
|
+
const environment = run_headless.environment()
|
|
49
|
+
const target = { cwd: context.worktree, env: environment, log_path: context.log_target }
|
|
50
|
+
const result = run_wake_session.launch({ argv: built.argv, ...target, profile }, note_to_stderr)
|
|
51
|
+
|
|
52
|
+
if (result.kind === 'launched') say_session_running(context)
|
|
53
|
+
|
|
54
|
+
return result
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// **A record this supervisor owns itself is not a session at work.** A failed driver leaves the record
|
|
58
|
+
// adopted for this process, so reading that owner as live would have every restarted pass wait on
|
|
59
|
+
// itself and never drive again.
|
|
60
|
+
//
|
|
61
|
+
// `is_code_stale` defaults to never: only the supervisor's own `--loop` watches its code
|
|
62
|
+
// (`run-wake-code.ts`).
|
|
63
|
+
function ports_for(
|
|
64
|
+
context: WakeContext,
|
|
65
|
+
profile: AgentProfile,
|
|
66
|
+
is_code_stale: () => Promise<boolean> = async () => false,
|
|
67
|
+
): LoopPorts {
|
|
68
|
+
return {
|
|
69
|
+
is_code_stale,
|
|
70
|
+
read_carry: () => run_carry.read_carry(context.carry_target),
|
|
71
|
+
is_owner_live: (read) => read.kind === 'carried' && run_carry.is_held_by_another(read.carry),
|
|
72
|
+
has_work: async () => true,
|
|
73
|
+
new_session_id: () => randomUUID(),
|
|
74
|
+
hand_off: () => {
|
|
75
|
+
run_wake_handoff.hand_off(context.carry_target)
|
|
76
|
+
},
|
|
77
|
+
drive: async () => await run_wake_driver.drive(context.carry_target),
|
|
78
|
+
wake: (invocation, session_id, material) =>
|
|
79
|
+
wake_session(context, invocation, profile, { id: session_id, material }),
|
|
80
|
+
sleep: poll.sleep,
|
|
81
|
+
now: () => new Date(),
|
|
82
|
+
retry_closes: async () => {
|
|
83
|
+
await lane_close.retry_closes()
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const run_wake_ports = { note_to_stderr, ports_for }
|
|
89
|
+
|
|
90
|
+
export { run_wake_ports }
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { process_identity } from '#scripts/josh/process-identity'
|
|
2
|
+
import { poll } from '#scripts/lib/poll'
|
|
3
|
+
import { MS_PER_SECOND } from '#scripts/lib/timeouts'
|
|
4
|
+
import { run_wake } from './run-wake'
|
|
5
|
+
import { run_wake_stop } from './run-wake-stop'
|
|
6
|
+
|
|
7
|
+
// Whether the successor a reload launched took the run over (joshuafolkken/kit#4509).
|
|
8
|
+
//
|
|
9
|
+
// **A spawn is not a take-over.** A successor that dies at load — a `main:sync` that pulled main but
|
|
10
|
+
// whose reinstall failed — was still `launched`, and reading that as the hand-over would leave the run
|
|
11
|
+
// with nobody watching it and nothing saying so. The successor claims the wake record before anything
|
|
12
|
+
// else (`run-wake-await.ts`), so its pid on that record is the proof; its death, or no claim within the
|
|
13
|
+
// bound, is a reload that failed.
|
|
14
|
+
|
|
15
|
+
const TAKEOVER_INTERVAL_MS = MS_PER_SECOND
|
|
16
|
+
// A cold `tsx` start claims within seconds; the bound is generous so a loaded machine is not a failure.
|
|
17
|
+
const TAKEOVER_ATTEMPTS = 120
|
|
18
|
+
|
|
19
|
+
type TakeoverResult = 'taken' | 'died' | 'unclaimed'
|
|
20
|
+
|
|
21
|
+
interface TakeoverPorts {
|
|
22
|
+
holder_pid: () => number | undefined
|
|
23
|
+
is_alive: (pid: number) => boolean
|
|
24
|
+
stop: (pid: number) => void
|
|
25
|
+
sleeper?: (duration_ms: number) => Promise<void>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function ports_of(wake_target: string): TakeoverPorts {
|
|
29
|
+
return {
|
|
30
|
+
holder_pid: () => run_wake.read_wake(wake_target)?.pid,
|
|
31
|
+
is_alive: process_identity.is_live_pid,
|
|
32
|
+
stop: run_wake_stop.signal,
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function result_of(pid: number, ports: TakeoverPorts): TakeoverResult {
|
|
37
|
+
if (ports.holder_pid() === pid) return 'taken'
|
|
38
|
+
|
|
39
|
+
return ports.is_alive(pid) ? 'unclaimed' : 'died'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// **A successor still unclaimed at the bound is stopped**, so the failed reload's warning says what is
|
|
43
|
+
// true: left running, it would claim the run later and supervise one the warning and the board call
|
|
44
|
+
// stranded.
|
|
45
|
+
async function await_takeover(
|
|
46
|
+
pid: number,
|
|
47
|
+
ports: TakeoverPorts,
|
|
48
|
+
attempts: number = TAKEOVER_ATTEMPTS,
|
|
49
|
+
): Promise<TakeoverResult> {
|
|
50
|
+
await poll.poll_until(async () => result_of(pid, ports) !== 'unclaimed', {
|
|
51
|
+
attempts,
|
|
52
|
+
interval_ms: TAKEOVER_INTERVAL_MS,
|
|
53
|
+
...(ports.sleeper && { sleeper: ports.sleeper }),
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const result = result_of(pid, ports)
|
|
57
|
+
|
|
58
|
+
if (result === 'unclaimed') ports.stop(pid)
|
|
59
|
+
|
|
60
|
+
return result
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const run_wake_takeover = { await_takeover, ports_of }
|
|
64
|
+
|
|
65
|
+
export type { TakeoverPorts, TakeoverResult }
|
|
66
|
+
export { run_wake_takeover }
|
|
@@ -53,7 +53,8 @@ interface RunWake {
|
|
|
53
53
|
idle_since?: string | undefined
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
// `reload`: the supervisor's code changed on disk, so it hands the run to a successor on that code.
|
|
57
|
+
type WakeStopReason = 'ended' | 'unreadable' | 'failed' | 'stopped' | 'reload'
|
|
57
58
|
|
|
58
59
|
// `superseded`: another supervisor holds the record and this process is the replaced one.
|
|
59
60
|
type WakeTidyResult = 'absent' | 'removed' | 'superseded'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, rmSync } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
|
+
import { package_manifest } from '#scripts/lib/package-manifest'
|
|
3
4
|
import { file_reader } from '#scripts/lib/read-file'
|
|
4
5
|
import { file_content } from '#scripts/sync/file-content'
|
|
5
6
|
import { z } from 'zod'
|
|
@@ -14,7 +15,6 @@ import { z } from 'zod'
|
|
|
14
15
|
// `pnpmfileChecksum`, which fails a frozen install until the lockfile is refreshed.
|
|
15
16
|
const PACK_HOOK_FILE = '.pnpmfile.mjs'
|
|
16
17
|
const MANAGED_LINE = '// josh-managed-pnpmfile: @joshuafolkken/kit'
|
|
17
|
-
const MANIFEST_FILE = 'package.json'
|
|
18
18
|
// pnpm loads `.pnpmfile.mjs` in preference to `.pnpmfile.cjs`, and neither once a `pnpmfile` setting
|
|
19
19
|
// names another file — so writing ours beside either would silently drop the project's hooks, or
|
|
20
20
|
// report a hook pnpm never runs.
|
|
@@ -77,7 +77,7 @@ const MESSAGES: Readonly<Record<PackHookResult, string | undefined>> = {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
function sync_pack_hook(project_root: string, package_directory: string): PackHookResult {
|
|
80
|
-
const manifest_text = file_reader.read_optional(
|
|
80
|
+
const manifest_text = file_reader.read_optional(package_manifest.manifest_path(project_root))
|
|
81
81
|
const is_private = manifest_text === undefined || !is_published(manifest_text)
|
|
82
82
|
const result = is_private ? 'private' : apply(project_root, package_directory)
|
|
83
83
|
const message = MESSAGES[result]
|
|
@@ -17,7 +17,8 @@ const INTEGRATION_HINT =
|
|
|
17
17
|
const LOCAL_INTEGRATION_CHECK_SOURCE = `if(!process.env.CI&&!process.env.GLOBAL_AGENT_HTTP_PROXY)console.warn('${INTEGRATION_HINT}')`
|
|
18
18
|
const SAFE_CHAIN_CMD = `node -e "${LOCAL_INTEGRATION_CHECK_SOURCE}"`
|
|
19
19
|
// Every `preinstall` an earlier kit wrote: `setup-ci` alone, pinned or not, or followed by the
|
|
20
|
-
// `node -e` check of any earlier wording.
|
|
20
|
+
// `node -e` check of any earlier wording. Removable from kit 2.0.0; consumers still carried `setup-ci`
|
|
21
|
+
// at joshuafolkken/kit#4187.
|
|
21
22
|
const LEGACY_PREINSTALL_RE =
|
|
22
23
|
/^pnpm dlx @aikidosec\/safe-chain(?:@\S+)? setup-ci(?: && node -e "[^"]*")?$/u
|
|
23
24
|
|
|
@@ -2,16 +2,14 @@ import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { file_reader } from '#scripts/lib/read-file'
|
|
4
4
|
import { yaml_document } from '#scripts/lib/yaml-document'
|
|
5
|
-
import {
|
|
5
|
+
import { release_window } from '#scripts/version/release-window'
|
|
6
6
|
import { dump } from 'js-yaml'
|
|
7
|
-
import { z } from 'zod'
|
|
8
7
|
|
|
9
8
|
const WORKSPACE_FILE = 'pnpm-workspace.yaml'
|
|
10
9
|
const PROJECT_CONFIG_FILE = '.aikido'
|
|
11
10
|
const EXCLUSIONS_FIELD = 'minimumPackageAgeExclusions'
|
|
12
11
|
const AGE_FIELD = 'minimumPackageAgeHours'
|
|
13
12
|
const MINUTES_PER_HOUR = 60
|
|
14
|
-
const workspace_schema = z.object({ minimumReleaseAgeExclude: z.array(z.string()).optional() })
|
|
15
13
|
|
|
16
14
|
function read_mapping(value: unknown, label: string): Record<string, unknown> {
|
|
17
15
|
if (value === undefined) return {}
|
|
@@ -82,7 +80,7 @@ function replace_safe_chain_block(existing: string, safe_chain: Record<string, u
|
|
|
82
80
|
// undeclared window writes nothing; an explicit `0` opt-out is written as 0 so an earlier
|
|
83
81
|
// synchronized age cannot outlive it.
|
|
84
82
|
function package_age_hours(workspace: string): number | undefined {
|
|
85
|
-
const minutes =
|
|
83
|
+
const { minutes } = release_window.parse_release_window(workspace)
|
|
86
84
|
if (minutes === undefined) return undefined
|
|
87
85
|
|
|
88
86
|
return Math.floor(minutes / MINUTES_PER_HOUR)
|
|
@@ -117,12 +115,8 @@ function has_nothing_to_write(
|
|
|
117
115
|
)
|
|
118
116
|
}
|
|
119
117
|
|
|
120
|
-
function read_exclusions(workspace: string): ReadonlyArray<string> {
|
|
121
|
-
return workspace_schema.parse(yaml_document.parse_yaml(workspace)).minimumReleaseAgeExclude ?? []
|
|
122
|
-
}
|
|
123
|
-
|
|
124
118
|
function merge_project_config(existing: string, workspace: string): string {
|
|
125
|
-
const exclusions =
|
|
119
|
+
const { exclusions } = release_window.parse_release_window(workspace)
|
|
126
120
|
const aikido = yaml_document.parse_yaml(existing)
|
|
127
121
|
const safe_chain = read_mapping(aikido['safe-chain'], 'safe-chain')
|
|
128
122
|
const merged = merge_age(merge_exclusions(safe_chain, exclusions), workspace)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { security_audit } from './security-audit'
|
|
4
|
+
|
|
5
|
+
// The `josh audit` entry, kept apart from `security-audit.ts` because `start-steps.ts` imports that
|
|
6
|
+
// one: a bundle is one file, so a main guard there would fire for every command that carries it
|
|
7
|
+
// (joshuafolkken/kit#4186). The audit takes no arguments.
|
|
8
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) process.exitCode = security_audit.run()
|
|
@@ -14,7 +14,6 @@ const RELEASE_BASE_URL = 'https://github.com/google/osv-scanner/releases/downloa
|
|
|
14
14
|
|
|
15
15
|
const WINDOWS_PLATFORM = 'win32'
|
|
16
16
|
const WINDOWS_ASSET_SUFFIX = '.exe'
|
|
17
|
-
const STAGING_SUFFIX = '.download'
|
|
18
17
|
|
|
19
18
|
// The asset is ~55 MB, and a link delivering it at 300 KB/s — measured, not hypothetical — takes
|
|
20
19
|
// over three minutes. A `SessionStart` hook is waited on, so a single bound generous enough to
|
|
@@ -91,15 +90,6 @@ function build_download_url(asset_name: string): string {
|
|
|
91
90
|
return `${RELEASE_BASE_URL}/v${SCANNER_VERSION}/${asset_name}`
|
|
92
91
|
}
|
|
93
92
|
|
|
94
|
-
// The staging file the download is written to before it is renamed onto the target. The process id
|
|
95
|
-
// is what keeps two sessions of one project apart — the `SessionStart` matcher is empty, so a
|
|
96
|
-
// `clear` during a startup's download is exactly that — and without it their writes interleave into
|
|
97
|
-
// one file that both then rename into place, which the checksum cannot catch because each verified
|
|
98
|
-
// its own buffer.
|
|
99
|
-
function build_staging_path(target_path: string, process_id: number): string {
|
|
100
|
-
return `${target_path}.${String(process_id)}${STAGING_SUFFIX}`
|
|
101
|
-
}
|
|
102
|
-
|
|
103
93
|
// The whole "where do we fetch from" decision in one pure call, so the table above is testable
|
|
104
94
|
// without a network round trip — which the unit suite forbids anyway (`test-network-guard.ts`).
|
|
105
95
|
function resolve_asset(platform: string, architecture: string): ScannerAsset | undefined {
|
|
@@ -198,7 +188,6 @@ const security_audit_provision_logic = {
|
|
|
198
188
|
build_asset_name,
|
|
199
189
|
build_download_timeout,
|
|
200
190
|
build_download_url,
|
|
201
|
-
build_staging_path,
|
|
202
191
|
format_already_present,
|
|
203
192
|
format_below_floor,
|
|
204
193
|
format_checksum_mismatch,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { security_audit_provision } from './security-audit-provision'
|
|
4
|
+
|
|
5
|
+
// The `josh audit:provision` entry and the session-start hook's bundle, kept apart from
|
|
6
|
+
// `security-audit-provision.ts` because `start-steps.ts` imports that one: a bundle is one file, so a
|
|
7
|
+
// main guard there would fire for every command that carries it (joshuafolkken/kit#4186).
|
|
8
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
9
|
+
const ARGV_OFFSET = 2
|
|
10
|
+
|
|
11
|
+
await security_audit_provision.run(process.argv.slice(ARGV_OFFSET))
|
|
12
|
+
}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
import { chmodSync, mkdirSync, renameSync, rmSync, writeFileSync } from 'node:fs'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import { fileURLToPath } from 'node:url'
|
|
5
1
|
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
6
2
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
3
|
+
import { atomic_write } from '#scripts/lib/atomic-write'
|
|
7
4
|
import { error_text } from '#scripts/lib/error-message'
|
|
8
5
|
import { timed_fetch } from '#scripts/lib/timed-fetch'
|
|
9
6
|
import { security_audit } from './security-audit'
|
|
@@ -43,24 +40,14 @@ async function download(url: string, timeout_ms: number): Promise<DownloadOutcom
|
|
|
43
40
|
}
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
// Staged beside the target and renamed onto it
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
43
|
+
// Staged beside the target and renamed onto it (`atomic-write.ts`). A download interrupted halfway
|
|
44
|
+
// would otherwise leave a truncated file at the path `josh audit` spawns; and a shared staging name
|
|
45
|
+
// would let two sessions of the same project — the `SessionStart` matcher is empty, so a `clear`
|
|
46
|
+
// during a startup's download is exactly that — interleave their writes into one file that both then
|
|
47
|
+
// rename into place, which the checksum cannot catch because it was verified against each process's
|
|
48
|
+
// own buffer.
|
|
52
49
|
function install(target_path: string, content: Buffer): void {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
mkdirSync(path.dirname(target_path), { recursive: true })
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
writeFileSync(staging_path, content)
|
|
59
|
-
chmodSync(staging_path, EXECUTABLE_MODE)
|
|
60
|
-
renameSync(staging_path, target_path)
|
|
61
|
-
} finally {
|
|
62
|
-
rmSync(staging_path, { force: true })
|
|
63
|
-
}
|
|
50
|
+
atomic_write.replace_file(target_path, content, { mode: EXECUTABLE_MODE })
|
|
64
51
|
}
|
|
65
52
|
|
|
66
53
|
function failure_stamp_path(target_path: string): string {
|
|
@@ -167,8 +154,8 @@ async function report(
|
|
|
167
154
|
// Every failure is a printed line and a zero exit, deliberately: this runs at session start, and a
|
|
168
155
|
// non-zero exit there would take an agent's whole session away over a tool it does not need yet.
|
|
169
156
|
// The audit's own gate is unchanged — a scanner that never arrived still fails the pre-push run.
|
|
170
|
-
async function
|
|
171
|
-
const is_forced =
|
|
157
|
+
async function run(argv: ReadonlyArray<string>): Promise<void> {
|
|
158
|
+
const is_forced = argv.includes(FORCE_FLAG)
|
|
172
159
|
|
|
173
160
|
try {
|
|
174
161
|
console.info(await report(PROJECT_ROOT, process.platform, process.arch, is_forced))
|
|
@@ -179,8 +166,6 @@ async function main(): Promise<void> {
|
|
|
179
166
|
}
|
|
180
167
|
}
|
|
181
168
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const security_audit_provision = { attempt, provision, report }
|
|
169
|
+
const security_audit_provision = { attempt, provision, report, run }
|
|
185
170
|
|
|
186
171
|
export { security_audit_provision }
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
1
|
import { accessSync, constants, statSync } from 'node:fs'
|
|
3
|
-
import { fileURLToPath } from 'node:url'
|
|
4
2
|
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
5
3
|
import { execaSync } from 'execa'
|
|
6
4
|
import { security_audit_logic } from './security-audit-logic'
|
|
@@ -115,27 +113,28 @@ function warn_below_floor(scanner_path: string): void {
|
|
|
115
113
|
console.warn(security_audit_provision_logic.format_below_floor(version))
|
|
116
114
|
}
|
|
117
115
|
|
|
118
|
-
|
|
116
|
+
// The `josh audit` run: the scanner's exit code, or a failure when there is no scanner at all.
|
|
117
|
+
function run(): number {
|
|
119
118
|
const { BINARY_NAME, format_missing_binary_error } = security_audit_logic
|
|
120
119
|
const choice = resolve_scanner(PROJECT_ROOT, process.platform)
|
|
121
120
|
|
|
122
121
|
if (choice === undefined) {
|
|
123
122
|
console.error(format_missing_binary_error(BINARY_NAME))
|
|
124
|
-
|
|
123
|
+
|
|
124
|
+
return FAILURE_EXIT_CODE
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
if (choice.is_below_floor) warn_below_floor(choice.path)
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
return run_scanner(choice.path)
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) main()
|
|
133
|
-
|
|
134
132
|
const security_audit = {
|
|
135
133
|
is_binary_available,
|
|
136
134
|
is_executable_file,
|
|
137
135
|
meets_floor,
|
|
138
136
|
resolve_scanner,
|
|
137
|
+
run,
|
|
139
138
|
run_scanner,
|
|
140
139
|
}
|
|
141
140
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs'
|
|
2
1
|
import path from 'node:path'
|
|
2
|
+
import { package_manifest } from '#scripts/lib/package-manifest'
|
|
3
|
+
import { z } from 'zod'
|
|
3
4
|
|
|
4
5
|
// `josh sync` / `josh-app sync` / `josh-game sync` all copy a distribution package's files into a
|
|
5
6
|
// consumer project. Run inside the package's OWN repository the direction reverses: the source of
|
|
@@ -12,20 +13,12 @@ import path from 'node:path'
|
|
|
12
13
|
// The check lives here rather than in each package's sync so the three distributors share one
|
|
13
14
|
// implementation: a second copy would drift, and a distributor that spelled the signal differently
|
|
14
15
|
// would keep exactly the hole this closes.
|
|
15
|
-
const
|
|
16
|
+
const named_manifest_schema = z.object({ name: z.string() })
|
|
16
17
|
|
|
18
|
+
// A missing, unreadable or malformed manifest says nothing about self-sync, and refusing to sync on
|
|
19
|
+
// it would break consumers whose manifest this package is about to create.
|
|
17
20
|
function read_package_name(directory: string): string | undefined {
|
|
18
|
-
|
|
19
|
-
const manifest: unknown = JSON.parse(readFileSync(path.join(directory, MANIFEST_NAME), 'utf8'))
|
|
20
|
-
if (typeof manifest !== 'object' || manifest === null) return undefined
|
|
21
|
-
const { name } = manifest as { name?: unknown }
|
|
22
|
-
|
|
23
|
-
return typeof name === 'string' ? name : undefined
|
|
24
|
-
} catch {
|
|
25
|
-
// A missing, unreadable or malformed manifest says nothing about self-sync, and refusing to
|
|
26
|
-
// sync on it would break consumers whose manifest this package is about to create.
|
|
27
|
-
return undefined
|
|
28
|
-
}
|
|
21
|
+
return package_manifest.read_manifest_if_valid(directory, named_manifest_schema)?.name
|
|
29
22
|
}
|
|
30
23
|
|
|
31
24
|
function is_same_directory(first: string, second: string): boolean {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import { git_command } from '#scripts/git/git-command'
|
|
4
3
|
import { path_decision } from '#scripts/josh/path-decision'
|
|
5
4
|
import { split_assess } from './split-assess'
|
|
5
|
+
import { split_measure } from './split-measure'
|
|
6
6
|
|
|
7
7
|
// `josh split:assess` — measure a branch's change size, tests excluded, and answer the size question
|
|
8
8
|
// of the split assessment.
|
|
@@ -33,7 +33,7 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
|
33
33
|
return FAILURE_EXIT_CODE
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const measurement =
|
|
36
|
+
const measurement = await split_measure.read_branch()
|
|
37
37
|
const reason = split_assess.reason(measurement)
|
|
38
38
|
|
|
39
39
|
path_decision.print_decision(JSON_KEY, measurement.verdict, reason, is_json)
|
|
@@ -107,12 +107,27 @@ function reason(measurement: SizeMeasurement): string {
|
|
|
107
107
|
return `${counted} (${guide}) — ${tail}`
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
// The `split-assessment.md` heading the notice points at; the document-rule test pins the document to it.
|
|
111
|
+
const NOTICE_SECTION = 'Over the guide before the gate'
|
|
112
|
+
const NOTICE_ACTION = `record why it stays one Issue, or carve the rest out into a new Issue — split-assessment.md → "${NOTICE_SECTION}"`
|
|
113
|
+
|
|
114
|
+
// The pre-gate notice `josh main:merge` prints for a diff over the guide. "Clearly" is the `split`
|
|
115
|
+
// verdict — both guides exceeded — so the one bar this file draws is the one the notice fires on,
|
|
116
|
+
// and a diff under it prints nothing.
|
|
117
|
+
function notice(measurement: SizeMeasurement): string | undefined {
|
|
118
|
+
if (measurement.verdict !== SPLIT_VERDICT) return undefined
|
|
119
|
+
|
|
120
|
+
return `split notice: ${reason(measurement)}. Before the run:cut, ${NOTICE_ACTION}`
|
|
121
|
+
}
|
|
122
|
+
|
|
110
123
|
const split_assess = {
|
|
111
124
|
FILE_GUIDE,
|
|
112
125
|
LINE_GUIDE,
|
|
126
|
+
NOTICE_SECTION,
|
|
113
127
|
SPLIT_VERDICT,
|
|
114
128
|
SINGLE_VERDICT,
|
|
115
129
|
assess,
|
|
130
|
+
notice,
|
|
116
131
|
parse_numstat,
|
|
117
132
|
reason,
|
|
118
133
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { changed_paths } from '#scripts/git/changed-paths'
|
|
4
|
+
import { git_command } from '#scripts/git/git-command'
|
|
5
|
+
import { git_spawn } from '#scripts/git/git-spawn'
|
|
6
|
+
import { split_assess } from './split-assess'
|
|
7
|
+
|
|
8
|
+
// The branch's size measurement — the one reading every `split_assess` caller takes.
|
|
9
|
+
//
|
|
10
|
+
// joshuafolkken/kit#4302: `git diff` never lists an untracked file, and a run has staged nothing
|
|
11
|
+
// when it measures, so the diff alone counted every new file a branch created as absent. Each
|
|
12
|
+
// untracked file is added as a numstat row of its line count, so a branch made of new modules
|
|
13
|
+
// measures as large as it is. A file holding a NUL byte is binary and counts zero lines, as
|
|
14
|
+
// `git diff --numstat` counts it. An entry with no readable content — a dangling symlink, a nested
|
|
15
|
+
// repository's directory — still counts as a file, of zero lines, so one such entry cannot reject
|
|
16
|
+
// the whole measurement.
|
|
17
|
+
|
|
18
|
+
const NUL_BYTE = 0
|
|
19
|
+
const NO_CONTENT = Buffer.alloc(0)
|
|
20
|
+
const NEWLINE = '\n'
|
|
21
|
+
|
|
22
|
+
function line_count(content: Buffer): number {
|
|
23
|
+
if (content.includes(NUL_BYTE)) return 0
|
|
24
|
+
|
|
25
|
+
const text = content.toString('utf8')
|
|
26
|
+
const newlines = text.split(NEWLINE).length - 1
|
|
27
|
+
|
|
28
|
+
return text === '' || text.endsWith(NEWLINE) ? newlines : newlines + 1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function read_content(file_path: string): Promise<Buffer> {
|
|
32
|
+
try {
|
|
33
|
+
return await readFile(file_path)
|
|
34
|
+
} catch {
|
|
35
|
+
return NO_CONTENT
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function untracked_row(root: string, file: string): Promise<string> {
|
|
40
|
+
const lines = line_count(await read_content(path.join(root, file)))
|
|
41
|
+
|
|
42
|
+
return `${String(lines)}\t0\t${file}`
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function untracked_numstat(): Promise<string> {
|
|
46
|
+
const files = changed_paths.to_paths(await git_command.untracked_names())
|
|
47
|
+
|
|
48
|
+
if (files.length === 0) return ''
|
|
49
|
+
|
|
50
|
+
const toplevel = await git_spawn.read(['rev-parse', '--show-toplevel'])
|
|
51
|
+
const root = toplevel.trim()
|
|
52
|
+
const rows = await Promise.all(files.map(async (file) => await untracked_row(root, file)))
|
|
53
|
+
|
|
54
|
+
return rows.join(NEWLINE)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function read_branch(): Promise<ReturnType<typeof split_assess.assess>> {
|
|
58
|
+
const tracked = await git_command.diff_main_numstat()
|
|
59
|
+
|
|
60
|
+
return split_assess.assess(`${tracked}${NEWLINE}${await untracked_numstat()}`)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const split_measure = { line_count, read_branch }
|
|
64
|
+
|
|
65
|
+
export { split_measure }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { json_format } from '#scripts/config-merge/json-format'
|
|
2
2
|
import { hook_command_rewrite } from '#scripts/init/hook-command-rewrite'
|
|
3
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
3
4
|
|
|
4
5
|
// `josh sync` used to replace a project's `.claude/settings.json` with the distributed file, which
|
|
5
6
|
// deleted every hook and permission the project had added — and `.claude/settings.local.json` is
|
|
@@ -29,10 +30,6 @@ const WITHDRAWN_KIT_PERMISSIONS: ReadonlySet<unknown> = new Set([
|
|
|
29
30
|
'Bash(git commit --all*)',
|
|
30
31
|
])
|
|
31
32
|
|
|
32
|
-
function is_json_object(value: unknown): value is JsonObject {
|
|
33
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
33
|
function as_array(value: unknown): Array<unknown> {
|
|
37
34
|
return Array.isArray(value) ? value : []
|
|
38
35
|
}
|
|
@@ -46,7 +43,7 @@ function merge_objects(kit: JsonObject, own: JsonObject, merge_entry: EntryMerge
|
|
|
46
43
|
}
|
|
47
44
|
|
|
48
45
|
function merge_kit_value(kit: unknown, own: unknown): unknown {
|
|
49
|
-
if (!
|
|
46
|
+
if (!json_value.is_record(kit) || !json_value.is_record(own)) return kit
|
|
50
47
|
|
|
51
48
|
return merge_objects(kit, own, (_key, kit_entry, own_entry) =>
|
|
52
49
|
merge_kit_value(kit_entry, own_entry),
|
|
@@ -68,7 +65,7 @@ function without_withdrawn(value: unknown): unknown {
|
|
|
68
65
|
// The withdrawn entries are taken out of every list first, so one goes even when kit no longer ships
|
|
69
66
|
// the list it sat in.
|
|
70
67
|
function merge_permissions(kit: unknown, own: unknown): unknown {
|
|
71
|
-
if (!
|
|
68
|
+
if (!json_value.is_record(kit) || !json_value.is_record(own)) return kit
|
|
72
69
|
const kept = Object.entries(own).map(([key, value]) => [key, without_withdrawn(value)] as const)
|
|
73
70
|
|
|
74
71
|
return merge_objects(kit, Object.fromEntries(kept), (_key, kit_entry, own_entry) =>
|
|
@@ -77,7 +74,7 @@ function merge_permissions(kit: unknown, own: unknown): unknown {
|
|
|
77
74
|
}
|
|
78
75
|
|
|
79
76
|
function is_kit_handler(handler: unknown): boolean {
|
|
80
|
-
if (!
|
|
77
|
+
if (!json_value.is_record(handler)) return false
|
|
81
78
|
const { command } = handler
|
|
82
79
|
|
|
83
80
|
return typeof command === 'string' && hook_command_rewrite.is_kit_hook_command(command)
|
|
@@ -85,7 +82,7 @@ function is_kit_handler(handler: unknown): boolean {
|
|
|
85
82
|
|
|
86
83
|
// A matcher group left with no handler of the project's own was kit's alone, and goes with them.
|
|
87
84
|
function without_kit_handlers(group: unknown): unknown {
|
|
88
|
-
if (!
|
|
85
|
+
if (!json_value.is_record(group)) return group
|
|
89
86
|
const handlers = as_array(group[HOOKS_KEY]).filter((handler) => !is_kit_handler(handler))
|
|
90
87
|
|
|
91
88
|
return handlers.length === 0 ? undefined : { ...group, [HOOKS_KEY]: handlers }
|
|
@@ -104,7 +101,7 @@ function own_hook_events(own: JsonObject): JsonObject {
|
|
|
104
101
|
}
|
|
105
102
|
|
|
106
103
|
function merge_hooks(kit: unknown, own: unknown): unknown {
|
|
107
|
-
if (!
|
|
104
|
+
if (!json_value.is_record(kit) || !json_value.is_record(own)) return kit
|
|
108
105
|
|
|
109
106
|
return merge_objects(kit, own_hook_events(own), (_event, kit_groups, groups) => [
|
|
110
107
|
...as_array(kit_groups),
|
|
@@ -120,13 +117,9 @@ function merge_top_level(key: string, kit: unknown, own: unknown): unknown {
|
|
|
120
117
|
}
|
|
121
118
|
|
|
122
119
|
function parse_object(content: string): JsonObject | undefined {
|
|
123
|
-
|
|
124
|
-
const parsed: unknown = JSON.parse(content)
|
|
120
|
+
const parsed = json_value.parse_or_undefined(content)
|
|
125
121
|
|
|
126
|
-
|
|
127
|
-
} catch {
|
|
128
|
-
return undefined
|
|
129
|
-
}
|
|
122
|
+
return json_value.is_record(parsed) ? parsed : undefined
|
|
130
123
|
}
|
|
131
124
|
|
|
132
125
|
// A file that does not parse as a JSON object has nothing the merge can keep, so it is replaced with
|