@joshuafolkken/kit 1.1178.0 → 1.1240.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/.claude-plugin/plugin.json +1 -1
- package/.claude/settings.json +2 -2
- package/.claude/skills/dependency-update/SKILL.md +4 -8
- package/.claude/skills/epic-commands/SKILL.md +2 -2
- package/.claude/skills/epic-commands/epic-bundle.md +1 -1
- package/.claude/skills/workflow-commands/SKILL.md +2 -4
- package/.claude/skills/workflow-commands/backlogrun-child.md +6 -4
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +7 -3
- package/.claude/skills/workflow-commands/backlogrun-park.md +23 -2
- package/.claude/skills/workflow-commands/backlogrun-progress.md +9 -4
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +4 -3
- package/.claude/skills/workflow-commands/backlogrun-steps.md +21 -13
- package/.claude/skills/workflow-commands/chain-rule.md +1 -1
- package/.claude/skills/workflow-commands/delegation.md +2 -2
- package/.claude/skills/workflow-commands/followup.md +10 -0
- package/.claude/skills/workflow-commands/fullrun-steps.md +1 -1
- package/.claude/skills/workflow-commands/halfrun.md +1 -1
- package/.claude/skills/workflow-commands/issue-scout.md +1 -1
- package/.claude/skills/workflow-commands/kickoff.md +2 -1
- package/.claude/skills/workflow-commands/latest-gate.md +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +3 -3
- package/.claude/skills/workflow-commands/pre-gate-cut.md +6 -1
- package/.claude/skills/workflow-commands/prerequisite.md +2 -2
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +1 -1
- package/.codex/hooks.json +2 -2
- package/.cursorrules +6 -41
- package/.github/actions/setup-node/action.yml +1 -1
- package/.github/workflows/auto-tag.yml +3 -4
- package/.github/workflows/ci.yml +32 -31
- package/.github/workflows/dependabot-auto-merge.yml +13 -6
- package/.github/workflows/publish.yml +50 -4
- package/.github/workflows/sonar-qube.yml +3 -0
- package/.pnpmfile.mjs +4 -3
- package/.prettierignore +8 -2
- package/CLAUDE.md +18 -20
- package/README.md +44 -38
- package/SECURITY.md +15 -1
- package/dist/CLAUDE.md +18 -20
- package/dist/commands/document-section-cli.js +734 -0
- package/dist/hooks/audit-provision.js +346 -0
- package/dist/hooks/batch-guard.js +5 -4
- package/dist/hooks/{chunk-G6KRCKEC.js → chunk-4TZVB44A.js} +496 -378
- package/dist/hooks/chunk-5VNDSNG3.js +12 -0
- package/dist/hooks/chunk-CDY4NFQG.js +15 -0
- package/dist/hooks/chunk-ELCN5LCH.js +135 -0
- package/dist/hooks/{chunk-VQLLNFNT.js → chunk-F3ELQ2AF.js} +3 -3
- package/dist/hooks/{chunk-I4XSL4TT.js → chunk-GPTFMK5E.js} +1 -1
- package/dist/hooks/{chunk-3V37IID6.js → chunk-JBBMAPC4.js} +23 -14
- package/dist/hooks/{chunk-UAGLLIGZ.js → chunk-KHGB5S3Y.js} +7 -6
- package/dist/hooks/{chunk-GDS5N2KB.js → chunk-KHX4U3BG.js} +735 -683
- package/dist/hooks/{chunk-VESKRQOF.js → chunk-KRBERBBI.js} +3 -3
- package/dist/hooks/{chunk-DO6NWWHU.js → chunk-QVSWU24O.js} +4 -4
- package/dist/hooks/{chunk-S6X6WYKR.js → chunk-WK2XSHSI.js} +1643 -923
- package/dist/hooks/{chunk-ZAL3NRGL.js → chunk-XZYKEM6J.js} +25 -10
- package/dist/hooks/{chunk-32GQTL4F.js → chunk-ZQGD4GBY.js} +4 -2
- package/dist/hooks/codex-hook-adapter.js +14 -12
- package/dist/hooks/duplicate-read-guard.js +6 -5
- package/dist/hooks/format-edited.js +4 -3
- package/dist/hooks/inputs.json +203 -179
- package/dist/hooks/investigation-guard.js +6 -5
- package/dist/hooks/pretool-guard.js +12 -10
- package/dist/hooks/session-lang.js +2 -4
- package/dist/hooks/stop-guard.js +66 -72
- package/dist/josh.js +1088 -78
- package/dist/version/index.d.ts +7 -2
- package/dist/version/index.js +152 -75
- package/eslint/base.js +23 -1
- package/eslint/rules/code-quality.js +3 -0
- package/eslint/rules/early-return-one-liner.js +98 -0
- package/eslint/rules/unicorn.js +16 -1
- package/package.json +7 -6
- package/pnpm-workspace.yaml +9 -4
- package/prettier/basic.d.ts +3 -1
- package/prettier/index.d.ts +3 -1
- package/prettier/static.d.ts +3 -1
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +4 -4
- package/prompts/collaboration-workflow/glossary.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +1 -0
- package/prompts/collaboration-workflow/operating-rules.md +17 -9
- package/prompts/collaboration-workflow/overview.md +2 -2
- package/prompts/collaboration-workflow/principles.md +14 -12
- package/prompts/collaboration-workflow/report-format.md +1 -1
- package/prompts/collaboration-workflow/residency.md +1 -1
- package/prompts/collaboration-workflow/rule-delivery.md +6 -6
- package/prompts/collaboration-workflow/shell-body.md +6 -6
- package/prompts/collaboration-workflow/turn-batching.md +1 -1
- package/prompts/collaboration-workflow/upstream-interrupt.md +12 -2
- package/prompts/collaboration-workflow/wip-cap.md +10 -10
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +1 -1
- package/scripts/agent/agent-headless.ts +29 -0
- package/scripts/agent/agent-launch-environment.ts +6 -2
- package/scripts/agent/codex-agent-argv.ts +2 -1
- package/scripts/auto-ok/auto-ok-cli.ts +1 -1
- package/scripts/backlog/backlog-arrival.ts +3 -3
- package/scripts/backlog/backlog-budget.ts +1 -1
- package/scripts/backlog/backlog-drive-args.ts +135 -0
- package/scripts/backlog/backlog-drive-cli.ts +11 -137
- package/scripts/backlog/backlog-drive-launch.ts +39 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +3 -5
- package/scripts/backlog/backlog-drive-named.ts +3 -3
- package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
- package/scripts/backlog/backlog-drive-owner.ts +1 -1
- package/scripts/backlog/backlog-drive-restore.ts +1 -1
- package/scripts/backlog/backlog-drive-retrospective.ts +1 -1
- package/scripts/backlog/backlog-drive.ts +1 -1
- package/scripts/backlog/backlog-next.ts +16 -5
- package/scripts/backlog/backlog-offer-cli.ts +6 -6
- package/scripts/backlog/backlog-offer.ts +1 -1
- package/scripts/backlog/backlog-plan-cli.ts +1 -1
- package/scripts/backlog/backlog-pool.ts +57 -11
- package/scripts/backlog/backlog-ready.ts +1 -1
- package/scripts/backlog/backlog-scope.ts +1 -1
- package/scripts/backlog/backlog-stalled-detect.ts +2 -2
- package/scripts/backlog/backlog-stalled.ts +1 -1
- package/scripts/build/build-codex-hooks.ts +3 -1
- package/scripts/build/build-commands.ts +66 -0
- package/scripts/build/build-hooks.ts +2 -1
- package/scripts/build/build-library.ts +12 -3
- package/scripts/build/build.ts +70 -0
- package/scripts/build/local-bin.ts +3 -13
- package/scripts/delegation/investigation-reads.ts +3 -1
- package/scripts/discovery/repo-origin.ts +5 -5
- package/scripts/doctor/doctor-consumer.ts +2 -2
- package/scripts/doctor/doctor-io.ts +2 -3
- package/scripts/document/capped-print-part.ts +30 -0
- package/scripts/document/capped-print.ts +3 -4
- package/scripts/document/document-byte-budget.ts +11 -2
- package/scripts/document/document-scan.ts +117 -0
- package/scripts/document/document-section.ts +143 -16
- package/scripts/document/entry-read-budget.ts +5 -3
- package/scripts/document/entry-read-set.ts +10 -89
- package/scripts/document/read-set-cost.ts +98 -0
- package/scripts/epic/epic-add-body.ts +1 -0
- package/scripts/epic/epic-audit-checks.ts +1 -1
- package/scripts/epic/epic-audit-rationale.ts +4 -3
- package/scripts/epic/epic-bundle-cli.ts +14 -3
- package/scripts/epic/epic-bundle-poll.ts +41 -0
- package/scripts/epic/epic-busy.ts +1 -1
- package/scripts/epic/epic-candidate-confirm.ts +3 -2
- package/scripts/epic/epic-classify.ts +1 -1
- package/scripts/epic/epic-cli-argv.ts +78 -46
- package/scripts/epic/epic-cli-remove.ts +11 -19
- package/scripts/epic/epic-cli.ts +74 -73
- package/scripts/epic/epic-close-comment.ts +1 -1
- package/scripts/epic/epic-close.ts +1 -1
- package/scripts/epic/epic-cross-repo.ts +5 -5
- package/scripts/epic/epic-graph.ts +1 -1
- package/scripts/epic/epic-index.ts +1 -1
- package/scripts/epic/epic-issue.ts +2 -6
- package/scripts/epic/epic-lane-offer.ts +2 -2
- package/scripts/epic/epic-next.ts +29 -42
- package/scripts/epic/epic-solo-stale.ts +1 -1
- package/scripts/epic/epic-triage.ts +8 -4
- package/scripts/epic/epic-validate.ts +1 -1
- package/scripts/followup/git-followup-finish.ts +2 -2
- package/scripts/followup/git-followup-label.ts +2 -2
- package/scripts/followup/git-followup-merged.ts +2 -2
- package/scripts/followup/git-pr-followup-checks.ts +142 -0
- package/scripts/followup/git-pr-followup.ts +4 -129
- package/scripts/gate/core-admission.ts +162 -0
- package/scripts/gate/core-budget.ts +190 -68
- package/scripts/gate/gate-plan.ts +80 -7
- package/scripts/gate/gate-report.ts +28 -9
- package/scripts/gate/gate-skip.ts +38 -7
- package/scripts/gate/hook-gate-reuse.ts +12 -10
- package/scripts/gate/machine-capacity.ts +175 -0
- package/scripts/gate/pre-commit-type-check.ts +4 -1
- package/scripts/gate/project-checks.ts +6 -9
- package/scripts/gate/type-check-step.ts +2 -3
- package/scripts/gate/verification-gate.ts +34 -10
- package/scripts/gh/git-gh-api-path.ts +2 -2
- package/scripts/gh/git-gh-issue-rest.ts +3 -3
- package/scripts/gh/git-gh-issue-write.ts +53 -7
- package/scripts/gh/git-gh-pr-read.ts +64 -19
- package/scripts/gh/git-gh-pr-rest.ts +1 -1
- package/scripts/gh/git-gh-pr.ts +5 -1
- package/scripts/gh/git-pr-ai-review.ts +1 -1
- package/scripts/gh/git-pr-checks-eval.ts +1 -3
- package/scripts/gh/git-pr-checks-parse.ts +1 -1
- package/scripts/gh/git-pr-checks-watch.ts +6 -5
- package/scripts/gh/git-pr-checks.ts +7 -5
- package/scripts/gh/git-pr-coderabbit.ts +1 -1
- package/scripts/gh/git-pr-error.ts +1 -3
- package/scripts/gh/git-pr.ts +9 -13
- package/scripts/gh/github-issue-url.ts +2 -2
- package/scripts/git/constants.ts +2 -6
- package/scripts/git/git-command.ts +20 -218
- package/scripts/git/git-diff-reads.ts +225 -0
- package/scripts/git/git-error.ts +4 -12
- package/scripts/git/git-pre-push-hook.ts +139 -0
- package/scripts/git/git-prompt.ts +2 -6
- package/scripts/git/git-spawn-sync.ts +3 -1
- package/scripts/git/git-spawn.ts +1 -1
- package/scripts/git/git-staging.ts +4 -6
- package/scripts/git/git-status.ts +3 -9
- package/scripts/hooks/codex-hook-adapter.ts +1 -1
- package/scripts/hooks/edited-cspell.ts +2 -4
- package/scripts/hooks/format-edited-file.ts +3 -12
- package/scripts/hooks/pre-push-unit.ts +31 -9
- package/scripts/hooks/reserved-run.ts +2 -2
- package/scripts/hooks/run-hook.sh +5 -4
- package/scripts/hooks/stop-guard.ts +5 -3
- package/scripts/init/init-actions.ts +0 -5
- package/scripts/init/init-ai-copy.ts +13 -2
- package/scripts/init/init-logic-json-merge.ts +19 -0
- package/scripts/init/init-logic-secretlint.ts +7 -7
- package/scripts/init/init-logic-workspace.ts +41 -2
- package/scripts/init/init-logic.ts +16 -26
- package/scripts/init/init.ts +10 -16
- package/scripts/init/initial-commit.ts +4 -4
- package/scripts/init/kit-development-versions.ts +40 -0
- package/scripts/init/kit-setup-state.ts +2 -2
- package/scripts/init/package-manager-pin.ts +35 -0
- package/scripts/init/start-exec.ts +68 -19
- package/scripts/init/start-setup-pr.ts +9 -9
- package/scripts/init/start-steps.ts +6 -10
- package/scripts/issue/defect-rate-cli.ts +1 -1
- package/scripts/issue/git-next-issues.ts +1 -1
- package/scripts/issue/issue-auto-ok.ts +32 -7
- package/scripts/issue/issue-backlinks-cli.ts +2 -2
- package/scripts/issue/issue-backlinks.ts +9 -9
- package/scripts/issue/issue-comment-cli.ts +19 -13
- package/scripts/issue/issue-file-cli.ts +72 -22
- package/scripts/issue/issue-file.ts +29 -1
- package/scripts/issue/issue-labels.ts +13 -0
- package/scripts/issue/issue-release-cli.ts +155 -0
- package/scripts/issue/issue-release.ts +58 -0
- package/scripts/issue/issue-scout-closed.ts +1 -1
- package/scripts/issue/issue-state-cli.ts +30 -74
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-command-types.ts +14 -0
- package/scripts/josh/josh-commands-ai.ts +4 -4
- package/scripts/josh/josh-commands-backlog.ts +4 -1
- package/scripts/josh/josh-commands-development.ts +18 -0
- package/scripts/josh/josh-commands-document.ts +1 -0
- package/scripts/josh/josh-commands-issue.ts +8 -1
- package/scripts/josh/josh-commands-lane.ts +24 -1
- package/scripts/josh/josh-commands-maintenance.ts +6 -6
- package/scripts/josh/josh-commands-run.ts +12 -7
- package/scripts/josh/josh-in-process.ts +28 -9
- package/scripts/josh/josh-logic.ts +34 -15
- package/scripts/josh/process-identity.ts +1 -3
- package/scripts/josh/session-language-cli.ts +3 -4
- package/scripts/lane/lane-await.ts +5 -1
- package/scripts/lane/lane-child-invocation.ts +2 -2
- package/scripts/lane/lane-cli.ts +12 -4
- package/scripts/lane/lane-dispatch.ts +14 -10
- package/scripts/lane/lane-environment.ts +5 -1
- package/scripts/lane/lane-handoff.ts +1 -1
- package/scripts/lane/lane-install.ts +2 -13
- package/scripts/lane/lane-launch-cli.ts +15 -1
- package/scripts/lane/lane-ledger.ts +145 -0
- package/scripts/lane/lane-leftover.ts +44 -30
- package/scripts/lane/lane-load.ts +108 -0
- package/scripts/lane/lane-measure-cli.ts +149 -0
- package/scripts/lane/lane-occupancy.ts +3 -0
- package/scripts/lane/lane-open.ts +5 -5
- package/scripts/lane/lane-paths.ts +13 -0
- package/scripts/lane/lane-reap.ts +1 -3
- package/scripts/lane/lane-registry.ts +11 -0
- package/scripts/lane/lane-relaunch.ts +1 -1
- package/scripts/lane/lane-stats.ts +224 -0
- package/scripts/lane/lane-stray.ts +140 -0
- package/scripts/lane/lane-vacant.ts +36 -0
- package/scripts/lane/openai-lane-ship.ts +2 -2
- package/scripts/lane/openai-lane-supervisor-owner.ts +180 -0
- package/scripts/lane/openai-lane-supervisor.ts +7 -165
- package/scripts/lane/openai-review-broker.ts +2 -4
- package/scripts/lib/ancestor-directories.ts +35 -0
- package/scripts/lib/animation-helpers.ts +2 -2
- package/scripts/lib/buffered-process.ts +3 -7
- package/scripts/lib/cli-flags.ts +71 -1
- package/scripts/lib/spawn-exit.ts +2 -2
- package/scripts/lib/timeouts.ts +35 -2
- package/scripts/lines/line-budget.ts +4 -6
- package/scripts/notify/telegram-test.ts +6 -0
- package/scripts/observations/observation-ledger-line.ts +6 -6
- package/scripts/observations/observation-ledger-migrate.ts +55 -4
- package/scripts/observations/observation-ledger.ts +26 -7
- package/scripts/overrides/lockfile-overrides.ts +1 -1
- package/scripts/overrides/overrides-logic.ts +1 -1
- package/scripts/propagate/propagate-git.ts +1 -1
- package/scripts/propagate/propagate-publish.ts +2 -2
- package/scripts/propagate/propagate-steps.ts +20 -15
- package/scripts/propagate/propagate.ts +36 -27
- package/scripts/refactor/import-graph.ts +18 -1
- package/scripts/refactor/refactor-lint.ts +4 -4
- package/scripts/release/github-release-environment.ts +1 -0
- package/scripts/release/github-release-runs.ts +115 -0
- package/scripts/release/github-release.ts +13 -67
- package/scripts/repo/repository-labels.ts +2 -2
- package/scripts/repo/required-checks-logic.ts +1 -3
- package/scripts/review/live-evidence.ts +2 -4
- package/scripts/review/review-brief-cli.ts +1 -1
- package/scripts/review/review-finding-ledger.ts +1 -1
- package/scripts/review/review-findings-cli.ts +1 -3
- package/scripts/rules/decision-oracle-batch.ts +128 -0
- package/scripts/rules/decision-oracle-tokens.ts +21 -0
- package/scripts/rules/decision-oracle.ts +8 -120
- package/scripts/rules/delivered-rules.ts +26 -182
- package/scripts/rules/direct-filing.ts +1 -1
- package/scripts/rules/early-heartbeat.ts +3 -3
- package/scripts/rules/git-argv.ts +1 -1
- package/scripts/rules/git-force.ts +1 -1
- package/scripts/rules/implementation-cut.ts +2 -2
- package/scripts/rules/index-guard.ts +1 -1
- package/scripts/rules/issue-comments.ts +118 -0
- package/scripts/rules/{issue-fold.ts → issue-fold-rule.ts} +2 -2
- package/scripts/rules/lane-background.ts +2 -2
- package/scripts/rules/lane-park.ts +18 -0
- package/scripts/rules/lane-split-park.ts +128 -0
- package/scripts/rules/oracle-firing.ts +1 -1
- package/scripts/rules/poll-loop.ts +1 -1
- package/scripts/rules/pre-gate-cut.ts +1 -1
- package/scripts/rules/protected-files.ts +59 -4
- package/scripts/rules/{run-tail.ts → run-tail-rule.ts} +2 -2
- package/scripts/rules/shell-body-trigger.ts +1 -1
- package/scripts/rules/stop-rules.ts +18 -7
- package/scripts/rules/test-declared-commit.ts +4 -4
- package/scripts/rules/wip-cap.ts +63 -0
- package/scripts/run/{run-carry-args.ts → carry/run-carry-args.ts} +37 -13
- package/scripts/run/{run-carry-change.ts → carry/run-carry-change.ts} +29 -7
- package/scripts/run/{run-carry-cli.ts → carry/run-carry-cli.ts} +4 -6
- package/scripts/run/{run-carry.ts → carry/run-carry.ts} +1 -1
- package/scripts/run/{run-cut-args.ts → cut/run-cut-args.ts} +1 -1
- package/scripts/run/{run-cut-cli.ts → cut/run-cut-cli.ts} +18 -5
- package/scripts/run/{run-cut.ts → cut/run-cut.ts} +1 -1
- package/scripts/run/{run-entry-cli.ts → entry/run-entry-cli.ts} +11 -11
- package/scripts/run/{run-entry.ts → entry/run-entry.ts} +2 -2
- package/scripts/run/{run-event-render.ts → event/run-event-render.ts} +1 -0
- package/scripts/run/{run-event-scope.ts → event/run-event-scope.ts} +1 -1
- package/scripts/run/{run-event-stream-emit.ts → event/run-event-stream-emit.ts} +1 -1
- package/scripts/run/{run-event-stream.ts → event/run-event-stream.ts} +20 -2
- package/scripts/run/{run-hold-cli.ts → hold/run-hold-cli.ts} +5 -5
- package/scripts/run/{run-merge-cli.ts → merge/run-merge-cli.ts} +10 -5
- package/scripts/run/{run-merge-steps.ts → merge/run-merge-steps.ts} +53 -5
- package/scripts/run/{run-merge.ts → merge/run-merge.ts} +1 -1
- package/scripts/run/{run-progress-cli.ts → progress/run-progress-cli.ts} +1 -1
- package/scripts/run/{run-progress-config.ts → progress/run-progress-config.ts} +2 -17
- package/scripts/run/{run-progress-read.ts → progress/run-progress-read.ts} +5 -5
- package/scripts/run/{run-progress.ts → progress/run-progress.ts} +1 -1
- package/scripts/run/{run-review-steps.ts → review/run-review-steps.ts} +2 -3
- package/scripts/run/run-ending.ts +2 -2
- package/scripts/run/run-halfrun-resume.ts +6 -1
- package/scripts/run/run-headless.ts +1 -1
- package/scripts/run/run-invocation.ts +85 -84
- package/scripts/run/run-liveness.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +1 -1
- package/scripts/run/run-preflight.ts +6 -6
- package/scripts/run/run-prep-cli.ts +1 -1
- package/scripts/run/run-prrun-resume.ts +1 -1
- package/scripts/run/run-report-cli.ts +4 -4
- package/scripts/run/run-report.ts +2 -2
- package/scripts/run/run-status-cli.ts +1 -1
- package/scripts/run/run-step-cli.ts +3 -3
- package/scripts/run/run-step.ts +7 -4
- package/scripts/run/run-stop-notify.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +4 -4
- package/scripts/run/run-stranded.ts +2 -2
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +5 -3
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/run/{run-ship-cli.ts → ship/run-ship-cli.ts} +2 -2
- package/scripts/run/{run-ship-detach.ts → ship/run-ship-detach.ts} +3 -3
- package/scripts/run/ship/run-ship-lock.ts +50 -0
- package/scripts/run/{run-ship-preflight.ts → ship/run-ship-preflight.ts} +6 -2
- package/scripts/run/{run-ship-probe.ts → ship/run-ship-probe.ts} +2 -2
- package/scripts/run/{run-ship-return.ts → ship/run-ship-return.ts} +4 -3
- package/scripts/run/{run-ship-review-steps.ts → ship/run-ship-review-steps.ts} +3 -3
- package/scripts/run/{run-ship-scoped.ts → ship/run-ship-scoped.ts} +10 -1
- package/scripts/run/{run-ship-steps.ts → ship/run-ship-steps.ts} +11 -12
- package/scripts/run/ship/run-ship-stop-text.ts +13 -0
- package/scripts/run/{run-ship-sync.ts → ship/run-ship-sync.ts} +25 -11
- package/scripts/run/{run-tidy-lanes.ts → tidy/run-tidy-lanes.ts} +1 -1
- package/scripts/run/{run-wake-cli.ts → wake/run-wake-cli.ts} +25 -11
- package/scripts/run/{run-wake-describe.ts → wake/run-wake-describe.ts} +58 -7
- package/scripts/run/{run-wake-driver.ts → wake/run-wake-driver.ts} +59 -8
- package/scripts/run/{run-wake-handoff.ts → wake/run-wake-handoff.ts} +1 -1
- package/scripts/run/{run-wake-loop.ts → wake/run-wake-loop.ts} +13 -15
- package/scripts/run/wake/run-wake-restart.ts +58 -0
- package/scripts/run/{run-wake-session.ts → wake/run-wake-session.ts} +3 -3
- package/scripts/run/{run-wake.ts → wake/run-wake.ts} +16 -65
- package/scripts/safe-chain/preinstall-command.ts +20 -21
- package/scripts/safe-chain/project-config.ts +19 -15
- package/scripts/sync/sync-ai-files.ts +1 -1
- package/scripts/sync/sync-configs.ts +2 -1
- package/scripts/sync/sync.ts +15 -2
- package/scripts/test/unit-worker-share.ts +1 -0
- package/scripts/time-runtime/time-background.ts +5 -1
- package/scripts/time-runtime/time-instant.ts +3 -1
- package/scripts/time-runtime/time-spans.ts +6 -139
- package/scripts/time-runtime/time-tool-call.ts +160 -0
- package/scripts/version/effective-upstream.ts +2 -20
- package/scripts/version/latest-corepack.ts +124 -93
- package/scripts/version/latest-regression.ts +1 -1
- package/scripts/version/latest-update.ts +4 -4
- package/scripts/version/npm-registry.ts +20 -5
- package/scripts/version/publishable-range-check.ts +2 -2
- package/scripts/version/publishable-range.ts +1 -1
- package/scripts/version/release-age.ts +48 -38
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +40 -0
- package/scripts/version/upgrade-shell-command.ts +48 -8
- package/scripts/version/version-check-logic.ts +23 -14
- package/scripts/version/version-commands.ts +23 -11
- package/scripts/version/version-remote.ts +28 -13
- package/templates/pnpm-workspace.basic.yaml +4 -0
- package/templates/workflows/dependabot-auto-merge.yml +5 -5
- package/templates/workflows/github-release.yml +6 -0
- package/scripts/build/build-config-merge.ts +0 -27
- package/scripts/build/build-managed-marker.ts +0 -27
- package/scripts/build/build-self-sync-guard.ts +0 -27
- package/scripts/build/build-version.ts +0 -26
- package/scripts/version/preinstall-version-update.ts +0 -86
- /package/scripts/git/{schemas.ts → git-schemas.ts} +0 -0
- /package/scripts/overrides/{schemas.ts → overrides-schemas.ts} +0 -0
- /package/scripts/run/{run-carry-conversation.ts → carry/run-carry-conversation.ts} +0 -0
- /package/scripts/run/{run-carry-reclaim.ts → carry/run-carry-reclaim.ts} +0 -0
- /package/scripts/run/{run-carry-stash.ts → carry/run-carry-stash.ts} +0 -0
- /package/scripts/run/{run-carry-streak.ts → carry/run-carry-streak.ts} +0 -0
- /package/scripts/run/{run-cut-handoff.ts → cut/run-cut-handoff.ts} +0 -0
- /package/scripts/run/{run-cut-report.ts → cut/run-cut-report.ts} +0 -0
- /package/scripts/run/{run-entry-stop.ts → entry/run-entry-stop.ts} +0 -0
- /package/scripts/run/{run-event-cli.ts → event/run-event-cli.ts} +0 -0
- /package/scripts/run/{run-event-follow.ts → event/run-event-follow.ts} +0 -0
- /package/scripts/run/{run-event-watch.ts → event/run-event-watch.ts} +0 -0
- /package/scripts/run/{run-hold.ts → hold/run-hold.ts} +0 -0
- /package/scripts/run/{run-progress-args.ts → progress/run-progress-args.ts} +0 -0
- /package/scripts/run/{run-progress-clock.ts → progress/run-progress-clock.ts} +0 -0
- /package/scripts/run/{run-review-cli.ts → review/run-review-cli.ts} +0 -0
- /package/scripts/run/{run-review.ts → review/run-review.ts} +0 -0
- /package/scripts/run/{run-ship-next.ts → ship/run-ship-next.ts} +0 -0
- /package/scripts/run/{run-ship-pre-detach.ts → ship/run-ship-pre-detach.ts} +0 -0
- /package/scripts/run/{run-ship-review.ts → ship/run-ship-review.ts} +0 -0
- /package/scripts/run/{run-ship-stage.ts → ship/run-ship-stage.ts} +0 -0
- /package/scripts/run/{run-ship.ts → ship/run-ship.ts} +0 -0
- /package/scripts/run/{run-tidy-cli.ts → tidy/run-tidy-cli.ts} +0 -0
- /package/scripts/run/{run-tidy-stashes.ts → tidy/run-tidy-stashes.ts} +0 -0
- /package/scripts/run/{run-tidy.ts → tidy/run-tidy.ts} +0 -0
package/dist/josh.js
CHANGED
|
@@ -20,6 +20,10 @@ function read_spawn_stderr(result) {
|
|
|
20
20
|
return result.stderr ?? "";
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
// scripts/lib/timeouts.ts
|
|
24
|
+
var PROBE_TIMEOUT_MS = 2e3;
|
|
25
|
+
var GIT_TIMEOUT_MS = 1e4;
|
|
26
|
+
|
|
23
27
|
// scripts/git/git-spawn-sync.ts
|
|
24
28
|
import { execaSync } from "execa";
|
|
25
29
|
|
|
@@ -28,17 +32,13 @@ import { platform } from "node:os";
|
|
|
28
32
|
var GIT_COMMAND_UNIX = "/usr/bin/git";
|
|
29
33
|
var GIT_BINARY_KEY = "JOSH_GIT_BINARY";
|
|
30
34
|
function get_git_command() {
|
|
31
|
-
if (platform() === "win32")
|
|
32
|
-
return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
|
|
33
|
-
}
|
|
35
|
+
if (platform() === "win32") return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
|
|
34
36
|
return GIT_COMMAND_UNIX;
|
|
35
37
|
}
|
|
36
38
|
function get_git_command_for_spawn() {
|
|
37
39
|
const binary = process.env[GIT_BINARY_KEY];
|
|
38
40
|
if (binary !== void 0 && binary !== "") return binary;
|
|
39
|
-
if (platform() === "win32")
|
|
40
|
-
return String.raw`C:\Program Files\Git\cmd\git.exe`;
|
|
41
|
-
}
|
|
41
|
+
if (platform() === "win32") return String.raw`C:\Program Files\Git\cmd\git.exe`;
|
|
42
42
|
return GIT_COMMAND_UNIX;
|
|
43
43
|
}
|
|
44
44
|
var git_utilities = {
|
|
@@ -47,7 +47,6 @@ var git_utilities = {
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
// scripts/git/git-spawn-sync.ts
|
|
50
|
-
var GIT_TIMEOUT_MS = 1e4;
|
|
51
50
|
var SUCCESS_EXIT_CODE = 0;
|
|
52
51
|
var C_LOCALE = { LC_ALL: "C", LANGUAGE: "C" };
|
|
53
52
|
function run(args, options = {}) {
|
|
@@ -94,20 +93,20 @@ var ABSENT_CODE = "ENOENT";
|
|
|
94
93
|
function is_absent(error) {
|
|
95
94
|
return error instanceof Error && "code" in error && error.code === ABSENT_CODE;
|
|
96
95
|
}
|
|
97
|
-
function read_optional(
|
|
96
|
+
function read_optional(path12) {
|
|
98
97
|
try {
|
|
99
|
-
return readFileSync(
|
|
98
|
+
return readFileSync(path12, "utf8");
|
|
100
99
|
} catch (error) {
|
|
101
100
|
if (is_absent(error)) return void 0;
|
|
102
101
|
throw error;
|
|
103
102
|
}
|
|
104
103
|
}
|
|
105
|
-
function read_file_or_empty(
|
|
106
|
-
return read_optional(
|
|
104
|
+
function read_file_or_empty(path12) {
|
|
105
|
+
return read_optional(path12) ?? "";
|
|
107
106
|
}
|
|
108
|
-
function read_if_readable(
|
|
107
|
+
function read_if_readable(path12) {
|
|
109
108
|
try {
|
|
110
|
-
return readFileSync(
|
|
109
|
+
return readFileSync(path12, "utf8");
|
|
111
110
|
} catch {
|
|
112
111
|
return void 0;
|
|
113
112
|
}
|
|
@@ -125,7 +124,6 @@ var CLAUDE_MD = "CLAUDE.md";
|
|
|
125
124
|
var PLUGIN_ID = "kit@kit";
|
|
126
125
|
var CLAUDE_MD_POINTER = `@${NODE_MODULES}/${KIT_PACKAGE_NAME}/dist/${CLAUDE_MD}`;
|
|
127
126
|
var SECRETLINT_BIN = path.join(NODE_MODULES, ".bin", "secretlint");
|
|
128
|
-
var GIT_TIMEOUT_MS2 = 2e3;
|
|
129
127
|
var manifest_schema = z.object({
|
|
130
128
|
name: z.string().optional(),
|
|
131
129
|
dependencies: z.record(z.string(), z.string()).optional(),
|
|
@@ -160,7 +158,7 @@ function is_plugin_declared(root) {
|
|
|
160
158
|
}
|
|
161
159
|
function configured_hooks_path(root) {
|
|
162
160
|
const value = git_spawn_sync.read(["-C", root, "config", "--get", "core.hooksPath"], {
|
|
163
|
-
timeout:
|
|
161
|
+
timeout: PROBE_TIMEOUT_MS
|
|
164
162
|
});
|
|
165
163
|
return value === "" ? void 0 : value;
|
|
166
164
|
}
|
|
@@ -232,14 +230,31 @@ var doctor_consumer = {
|
|
|
232
230
|
};
|
|
233
231
|
|
|
234
232
|
// scripts/josh/josh-logic.ts
|
|
235
|
-
import { existsSync as existsSync4, readFileSync as
|
|
236
|
-
import
|
|
237
|
-
import { fileURLToPath } from "node:url";
|
|
233
|
+
import { existsSync as existsSync4, readFileSync as readFileSync5 } from "node:fs";
|
|
234
|
+
import path11 from "node:path";
|
|
235
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
238
236
|
|
|
239
237
|
// scripts/build/local-bin.ts
|
|
240
238
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
241
239
|
import { createRequire } from "node:module";
|
|
240
|
+
import path3 from "node:path";
|
|
241
|
+
|
|
242
|
+
// scripts/lib/ancestor-directories.ts
|
|
242
243
|
import path2 from "node:path";
|
|
244
|
+
var MAX_DEPTH = 64;
|
|
245
|
+
function list(start_directory) {
|
|
246
|
+
const directories = [];
|
|
247
|
+
let current = path2.resolve(start_directory);
|
|
248
|
+
while (directories.length < MAX_DEPTH && !directories.includes(current)) {
|
|
249
|
+
directories.push(current);
|
|
250
|
+
current = path2.dirname(current);
|
|
251
|
+
}
|
|
252
|
+
return directories;
|
|
253
|
+
}
|
|
254
|
+
function nearest(start_directory, is_match) {
|
|
255
|
+
return list(start_directory).find((directory) => is_match(directory));
|
|
256
|
+
}
|
|
257
|
+
var ancestor_directories = { list, nearest };
|
|
243
258
|
|
|
244
259
|
// scripts/lib/schemas.ts
|
|
245
260
|
import { z as z2 } from "zod";
|
|
@@ -281,26 +296,767 @@ var WINDOWS_SHIM_SUFFIX = ".cmd";
|
|
|
281
296
|
var PACKAGE_JSON = "package.json";
|
|
282
297
|
function resolve_local_bin(project_root, bin_name) {
|
|
283
298
|
const shim = process.platform === WINDOWS_PLATFORM ? `${bin_name}${WINDOWS_SHIM_SUFFIX}` : bin_name;
|
|
284
|
-
return
|
|
299
|
+
return path3.join(project_root, NODE_MODULES2, BIN_DIR, shim);
|
|
285
300
|
}
|
|
286
301
|
function read_bin_entry(manifest_path, package_name, bin_name) {
|
|
287
302
|
const { bin } = package_bin_schema.parse(JSON.parse(readFileSync2(manifest_path, "utf8")));
|
|
288
|
-
if (typeof bin === "string") return bin_name ===
|
|
303
|
+
if (typeof bin === "string") return bin_name === path3.basename(package_name) ? bin : void 0;
|
|
289
304
|
return bin?.[bin_name];
|
|
290
305
|
}
|
|
291
306
|
function resolve_package_bin(base_directory, package_name, bin_name) {
|
|
292
307
|
try {
|
|
293
|
-
const resolve_from = createRequire(
|
|
308
|
+
const resolve_from = createRequire(path3.join(base_directory, PACKAGE_JSON));
|
|
294
309
|
const manifest_path = resolve_from.resolve(`${package_name}/${PACKAGE_JSON}`);
|
|
295
310
|
const bin_entry = read_bin_entry(manifest_path, package_name, bin_name);
|
|
296
311
|
if (bin_entry === void 0) return void 0;
|
|
297
|
-
const cli_entry =
|
|
312
|
+
const cli_entry = path3.join(path3.dirname(manifest_path), bin_entry);
|
|
298
313
|
return existsSync2(cli_entry) ? cli_entry : void 0;
|
|
299
314
|
} catch {
|
|
300
315
|
return void 0;
|
|
301
316
|
}
|
|
302
317
|
}
|
|
303
318
|
|
|
319
|
+
// scripts/gate/core-budget.ts
|
|
320
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
321
|
+
import { readdirSync as readdirSync2 } from "node:fs";
|
|
322
|
+
import { availableParallelism as availableParallelism3 } from "node:os";
|
|
323
|
+
import path8 from "node:path";
|
|
324
|
+
|
|
325
|
+
// scripts/josh/platform-temporary.ts
|
|
326
|
+
import { accessSync, constants } from "node:fs";
|
|
327
|
+
import { tmpdir } from "node:os";
|
|
328
|
+
var POSIX_TEMP_ROOT = "/tmp";
|
|
329
|
+
var WINDOWS_PLATFORM2 = "win32";
|
|
330
|
+
function is_writable_directory(directory) {
|
|
331
|
+
try {
|
|
332
|
+
accessSync(directory, constants.W_OK);
|
|
333
|
+
return true;
|
|
334
|
+
} catch {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function resolve_temporary_root(platform2, can_write = is_writable_directory) {
|
|
339
|
+
if (platform2 === WINDOWS_PLATFORM2) return tmpdir();
|
|
340
|
+
return can_write(POSIX_TEMP_ROOT) ? POSIX_TEMP_ROOT : tmpdir();
|
|
341
|
+
}
|
|
342
|
+
var TEMP_ROOT_KEY = "JOSH_TEMP_ROOT";
|
|
343
|
+
function temporary_root(override, platform2) {
|
|
344
|
+
return override === void 0 || override === "" ? resolve_temporary_root(platform2) : override;
|
|
345
|
+
}
|
|
346
|
+
var PLATFORM_TEMP_ROOT = temporary_root(process.env[TEMP_ROOT_KEY], process.platform);
|
|
347
|
+
|
|
348
|
+
// scripts/josh/process-identity.ts
|
|
349
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
350
|
+
import { randomUUID } from "node:crypto";
|
|
351
|
+
import { readFileSync as readFileSync3, rmSync } from "node:fs";
|
|
352
|
+
import { createServer } from "node:net";
|
|
353
|
+
import path4 from "node:path";
|
|
354
|
+
var PS_COMMAND = "/bin/ps";
|
|
355
|
+
var FORMAT_FLAG = "-o";
|
|
356
|
+
var START_TIME_FORMAT = "lstart=";
|
|
357
|
+
var PID_FLAG = "-p";
|
|
358
|
+
var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
|
|
359
|
+
var LIVENESS_SIGNAL = 0;
|
|
360
|
+
var LOWEST_REAL_PID = 1;
|
|
361
|
+
var PROC_START_FIELD_INDEX = 19;
|
|
362
|
+
var BEACON_SCHEME = "socket:";
|
|
363
|
+
var BEACON_SUFFIX = ".sock";
|
|
364
|
+
var BEACON_PREFIX = `josh-process-identity-${String(process.getuid?.() ?? "")}-`;
|
|
365
|
+
var BEACON_ID_LENGTH = 36;
|
|
366
|
+
var BEACON_ID_PATTERN = /^[\da-f-]+$/u;
|
|
367
|
+
var WINDOWS_PLATFORM3 = "win32";
|
|
368
|
+
var SOCKET_PROBE_SOURCE = "const net=require('node:net');const socket=net.createConnection(process.argv[1]);socket.once('connect',()=>process.exit(0));socket.once('error',()=>process.exit(1));socket.setTimeout(1000,()=>process.exit(1));";
|
|
369
|
+
var beacons = /* @__PURE__ */ new Map();
|
|
370
|
+
var exit_cleanup = { is_registered: false };
|
|
371
|
+
function is_live_pid(pid) {
|
|
372
|
+
if (pid < LOWEST_REAL_PID) return false;
|
|
373
|
+
try {
|
|
374
|
+
process.kill(pid, LIVENESS_SIGNAL);
|
|
375
|
+
return true;
|
|
376
|
+
} catch {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
function read_proc_start(pid) {
|
|
381
|
+
try {
|
|
382
|
+
const stat = readFileSync3(`/proc/${String(pid)}/stat`, "utf8");
|
|
383
|
+
const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
|
|
384
|
+
const start = fields[PROC_START_FIELD_INDEX];
|
|
385
|
+
return start === void 0 ? void 0 : `proc:${start}`;
|
|
386
|
+
} catch {
|
|
387
|
+
return void 0;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function read_ps_start(pid) {
|
|
391
|
+
try {
|
|
392
|
+
const printed = execFileSync(
|
|
393
|
+
PS_COMMAND,
|
|
394
|
+
[FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
|
|
395
|
+
{
|
|
396
|
+
encoding: "utf8",
|
|
397
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
398
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
399
|
+
env: PROBE_ENVIRONMENT
|
|
400
|
+
}
|
|
401
|
+
).trim();
|
|
402
|
+
return printed.length > 0 ? printed : void 0;
|
|
403
|
+
} catch {
|
|
404
|
+
return void 0;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
var START_PROBES = { read_proc_start, read_ps_start };
|
|
408
|
+
function safe_probe(probe, pid) {
|
|
409
|
+
try {
|
|
410
|
+
return probe(pid);
|
|
411
|
+
} catch {
|
|
412
|
+
return void 0;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function read_start(pid, probes = START_PROBES) {
|
|
416
|
+
return safe_probe(probes.read_proc_start, pid) ?? safe_probe(probes.read_ps_start, pid);
|
|
417
|
+
}
|
|
418
|
+
function close_beacon(token) {
|
|
419
|
+
const server = beacons.get(token);
|
|
420
|
+
if (server === void 0) return;
|
|
421
|
+
beacons.delete(token);
|
|
422
|
+
server.close();
|
|
423
|
+
rmSync(token.slice(BEACON_SCHEME.length), { force: true });
|
|
424
|
+
}
|
|
425
|
+
function close_beacons() {
|
|
426
|
+
for (const token of beacons.keys()) close_beacon(token);
|
|
427
|
+
}
|
|
428
|
+
function ensure_exit_cleanup() {
|
|
429
|
+
if (exit_cleanup.is_registered) return;
|
|
430
|
+
exit_cleanup.is_registered = true;
|
|
431
|
+
process.once("exit", close_beacons);
|
|
432
|
+
}
|
|
433
|
+
function ignore_beacon_error() {
|
|
434
|
+
}
|
|
435
|
+
function bind_beacon(target) {
|
|
436
|
+
return createServer().on("error", ignore_beacon_error).listen(target);
|
|
437
|
+
}
|
|
438
|
+
function try_bind_beacon(bind, target) {
|
|
439
|
+
try {
|
|
440
|
+
const server = bind(target);
|
|
441
|
+
return server.listening ? server : void 0;
|
|
442
|
+
} catch {
|
|
443
|
+
return void 0;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
function open_beacon(bind = bind_beacon) {
|
|
447
|
+
const target = path4.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
|
|
448
|
+
const token = `${BEACON_SCHEME}${target}`;
|
|
449
|
+
const server = try_bind_beacon(bind, target);
|
|
450
|
+
if (server === void 0) return void 0;
|
|
451
|
+
server.unref();
|
|
452
|
+
beacons.set(token, server);
|
|
453
|
+
ensure_exit_cleanup();
|
|
454
|
+
return token;
|
|
455
|
+
}
|
|
456
|
+
function resolve_own_start(probes = START_PROBES, platform2 = process.platform) {
|
|
457
|
+
const start = read_start(process.pid, probes);
|
|
458
|
+
if (start !== void 0 || platform2 === WINDOWS_PLATFORM3) return start;
|
|
459
|
+
return open_beacon();
|
|
460
|
+
}
|
|
461
|
+
function is_valid_beacon_name(name) {
|
|
462
|
+
if (!name.startsWith(BEACON_PREFIX) || !name.endsWith(BEACON_SUFFIX)) return false;
|
|
463
|
+
const id = name.slice(BEACON_PREFIX.length, -BEACON_SUFFIX.length);
|
|
464
|
+
return id.length === BEACON_ID_LENGTH && BEACON_ID_PATTERN.test(id);
|
|
465
|
+
}
|
|
466
|
+
function beacon_target(token) {
|
|
467
|
+
if (!token.startsWith(BEACON_SCHEME)) return void 0;
|
|
468
|
+
const target = token.slice(BEACON_SCHEME.length);
|
|
469
|
+
if (path4.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
|
|
470
|
+
return is_valid_beacon_name(path4.basename(target)) ? target : void 0;
|
|
471
|
+
}
|
|
472
|
+
function is_live_beacon(target) {
|
|
473
|
+
return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
|
|
474
|
+
stdio: "ignore",
|
|
475
|
+
timeout: PROBE_TIMEOUT_MS
|
|
476
|
+
}).status === 0;
|
|
477
|
+
}
|
|
478
|
+
function has_matching_start(pid, recorded_start, read2) {
|
|
479
|
+
const observed = read2(pid);
|
|
480
|
+
return observed === void 0 ? void 0 : observed === recorded_start;
|
|
481
|
+
}
|
|
482
|
+
function matches_recorded_start(pid, recorded_start, read2) {
|
|
483
|
+
const target = beacon_target(recorded_start);
|
|
484
|
+
return target === void 0 ? has_matching_start(pid, recorded_start, read2) : is_live_beacon(target);
|
|
485
|
+
}
|
|
486
|
+
var own_probe = /* @__PURE__ */ new Map();
|
|
487
|
+
function own_start() {
|
|
488
|
+
if (!own_probe.has(process.pid)) own_probe.set(process.pid, resolve_own_start());
|
|
489
|
+
return own_probe.get(process.pid);
|
|
490
|
+
}
|
|
491
|
+
function own_fields() {
|
|
492
|
+
const start = own_start();
|
|
493
|
+
return { pid: process.pid, ...start !== void 0 && { process_start: start } };
|
|
494
|
+
}
|
|
495
|
+
function is_same_process(pid, recorded_start, read2 = read_start) {
|
|
496
|
+
if (pid === void 0 || !is_live_pid(pid)) return false;
|
|
497
|
+
if (recorded_start === void 0) return void 0;
|
|
498
|
+
return matches_recorded_start(pid, recorded_start, read2);
|
|
499
|
+
}
|
|
500
|
+
function is_own_process(pid, recorded_start) {
|
|
501
|
+
return pid === process.pid && recorded_start === own_start();
|
|
502
|
+
}
|
|
503
|
+
var process_identity = {
|
|
504
|
+
close_beacon,
|
|
505
|
+
is_live_pid,
|
|
506
|
+
is_own_process,
|
|
507
|
+
is_same_process,
|
|
508
|
+
open_beacon,
|
|
509
|
+
own_fields,
|
|
510
|
+
own_start,
|
|
511
|
+
read_start,
|
|
512
|
+
resolve_own_start
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
// scripts/josh/process-owner.ts
|
|
516
|
+
import { z as z3 } from "zod";
|
|
517
|
+
var process_owner_schema = z3.object({ pid: z3.number(), process_start: z3.string().optional() });
|
|
518
|
+
|
|
519
|
+
// scripts/josh/stamp-file.ts
|
|
520
|
+
import { createHash, randomUUID as randomUUID2 } from "node:crypto";
|
|
521
|
+
import { lstatSync, readFileSync as readFileSync4, renameSync, rmSync as rmSync2, writeFileSync } from "node:fs";
|
|
522
|
+
import path6 from "node:path";
|
|
523
|
+
|
|
524
|
+
// scripts/init/init-paths.ts
|
|
525
|
+
import path5 from "node:path";
|
|
526
|
+
import { fileURLToPath } from "node:url";
|
|
527
|
+
var PACKAGE_DIR = path5.join(path5.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
528
|
+
var PROJECT_ROOT = process.cwd();
|
|
529
|
+
|
|
530
|
+
// scripts/josh/stamp-file.ts
|
|
531
|
+
var HASH_ALGORITHM = "sha256";
|
|
532
|
+
var STAMP_SUFFIX = ".json";
|
|
533
|
+
var STAMP_KEY_LENGTH = 16;
|
|
534
|
+
var STAMP_FILE_MODE = 384;
|
|
535
|
+
var STAMP_WRITE_FLAG = "wx";
|
|
536
|
+
var STAMP_CREATE_FLAG = STAMP_WRITE_FLAG;
|
|
537
|
+
var EXISTS_ERROR_CODE = "EEXIST";
|
|
538
|
+
var ACCOUNT_KEY_SEPARATOR = ":";
|
|
539
|
+
function digest(content) {
|
|
540
|
+
return createHash(HASH_ALGORITHM).update(content).digest("hex");
|
|
541
|
+
}
|
|
542
|
+
function account_key() {
|
|
543
|
+
return String(process.getuid?.() ?? "");
|
|
544
|
+
}
|
|
545
|
+
function stamp_path(prefix, root = PACKAGE_DIR, suffix = STAMP_SUFFIX) {
|
|
546
|
+
const key = digest(`${account_key()}${ACCOUNT_KEY_SEPARATOR}${root}`).slice(0, STAMP_KEY_LENGTH);
|
|
547
|
+
return path6.join(PLATFORM_TEMP_ROOT, `${prefix}${key}${suffix}`);
|
|
548
|
+
}
|
|
549
|
+
function write_exclusively(target, content) {
|
|
550
|
+
rmSync2(target, { force: true });
|
|
551
|
+
writeFileSync(target, content, { flag: STAMP_WRITE_FLAG, mode: STAMP_FILE_MODE });
|
|
552
|
+
return target;
|
|
553
|
+
}
|
|
554
|
+
function write_stamp(target, payload) {
|
|
555
|
+
return write_exclusively(target, JSON.stringify(payload));
|
|
556
|
+
}
|
|
557
|
+
function replace_stamp(target, payload) {
|
|
558
|
+
const temporary = `${target}.${String(process.pid)}.${randomUUID2()}`;
|
|
559
|
+
try {
|
|
560
|
+
writeFileSync(temporary, JSON.stringify(payload), {
|
|
561
|
+
flag: STAMP_CREATE_FLAG,
|
|
562
|
+
mode: STAMP_FILE_MODE
|
|
563
|
+
});
|
|
564
|
+
renameSync(temporary, target);
|
|
565
|
+
return target;
|
|
566
|
+
} finally {
|
|
567
|
+
rmSync2(temporary, { force: true });
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
function write_text_stamp(target, text) {
|
|
571
|
+
return write_exclusively(target, text);
|
|
572
|
+
}
|
|
573
|
+
function create_stamp(target, payload) {
|
|
574
|
+
try {
|
|
575
|
+
writeFileSync(target, JSON.stringify(payload), {
|
|
576
|
+
flag: STAMP_CREATE_FLAG,
|
|
577
|
+
mode: STAMP_FILE_MODE
|
|
578
|
+
});
|
|
579
|
+
return true;
|
|
580
|
+
} catch (error) {
|
|
581
|
+
if (error.code === EXISTS_ERROR_CODE) return false;
|
|
582
|
+
throw error;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
function remove_stamp(target) {
|
|
586
|
+
rmSync2(target, { force: true });
|
|
587
|
+
}
|
|
588
|
+
function is_own_regular_file(source) {
|
|
589
|
+
const stats = lstatSync(source);
|
|
590
|
+
if (!stats.isFile()) return false;
|
|
591
|
+
const uid = process.getuid?.();
|
|
592
|
+
return uid === void 0 || stats.uid === uid;
|
|
593
|
+
}
|
|
594
|
+
function read_stamp_text(source) {
|
|
595
|
+
try {
|
|
596
|
+
if (!is_own_regular_file(source)) return void 0;
|
|
597
|
+
return readFileSync4(source, "utf8");
|
|
598
|
+
} catch {
|
|
599
|
+
return void 0;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
var stamp_file = {
|
|
603
|
+
create_stamp,
|
|
604
|
+
digest,
|
|
605
|
+
is_own_regular_file,
|
|
606
|
+
read_stamp_text,
|
|
607
|
+
replace_stamp,
|
|
608
|
+
remove_stamp,
|
|
609
|
+
stamp_path,
|
|
610
|
+
write_stamp,
|
|
611
|
+
write_text_stamp
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
// scripts/test/unit-worker-share.ts
|
|
615
|
+
import { readdirSync } from "node:fs";
|
|
616
|
+
import { availableParallelism } from "node:os";
|
|
617
|
+
import path7 from "node:path";
|
|
618
|
+
var RUN_PREFIX = "josh-unit-running-";
|
|
619
|
+
var WORKER_FLAG = "--maxWorkers";
|
|
620
|
+
var WORKER_FLAGS = [WORKER_FLAG, "--max-workers"];
|
|
621
|
+
var MIN_WORKERS = 1;
|
|
622
|
+
var SOLO_RUNS = 1;
|
|
623
|
+
function marker_path(pid = process.pid) {
|
|
624
|
+
return stamp_file.stamp_path(RUN_PREFIX, String(pid));
|
|
625
|
+
}
|
|
626
|
+
function is_running(marker) {
|
|
627
|
+
return process_identity.is_same_process(marker.pid, marker.process_start) !== false;
|
|
628
|
+
}
|
|
629
|
+
function read_marker(source) {
|
|
630
|
+
const raw = stamp_file.read_stamp_text(source);
|
|
631
|
+
if (raw === void 0) return void 0;
|
|
632
|
+
const parsed = process_owner_schema.safeParse(json_value.parse_or_undefined(raw));
|
|
633
|
+
return parsed.success ? parsed.data : void 0;
|
|
634
|
+
}
|
|
635
|
+
function marker_files(directory = PLATFORM_TEMP_ROOT) {
|
|
636
|
+
try {
|
|
637
|
+
return readdirSync(directory).filter((name) => name.startsWith(RUN_PREFIX));
|
|
638
|
+
} catch {
|
|
639
|
+
return [];
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
function sweep_marker(source) {
|
|
643
|
+
try {
|
|
644
|
+
stamp_file.remove_stamp(source);
|
|
645
|
+
} catch {
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
function is_marker_live(source) {
|
|
649
|
+
const marker = read_marker(source);
|
|
650
|
+
if (marker === void 0) return false;
|
|
651
|
+
if (is_running(marker)) return true;
|
|
652
|
+
sweep_marker(source);
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
function live_run_count(directory = PLATFORM_TEMP_ROOT) {
|
|
656
|
+
return marker_files(directory).filter((name) => is_marker_live(path7.join(directory, name))).length;
|
|
657
|
+
}
|
|
658
|
+
var NESTED_KEY = "JOSH_UNIT_RUN_MARKED";
|
|
659
|
+
var NESTED_VALUE = "1";
|
|
660
|
+
function is_nested_run() {
|
|
661
|
+
return process.env[NESTED_KEY] === NESTED_VALUE;
|
|
662
|
+
}
|
|
663
|
+
function resolve_unit_workers(available_cores, runs) {
|
|
664
|
+
if (runs <= SOLO_RUNS) return void 0;
|
|
665
|
+
return Math.max(MIN_WORKERS, Math.floor(available_cores / runs));
|
|
666
|
+
}
|
|
667
|
+
function current_share(available_cores = availableParallelism(), live_runs = live_run_count()) {
|
|
668
|
+
const own_run = is_nested_run() ? 0 : SOLO_RUNS;
|
|
669
|
+
return resolve_unit_workers(available_cores, live_runs + own_run);
|
|
670
|
+
}
|
|
671
|
+
function is_worker_flag(argument) {
|
|
672
|
+
return WORKER_FLAGS.some((flag) => argument === flag || argument.startsWith(`${flag}=`));
|
|
673
|
+
}
|
|
674
|
+
function worker_arguments(vitest_arguments, share) {
|
|
675
|
+
if (share === void 0) return [];
|
|
676
|
+
if (vitest_arguments.some((argument) => is_worker_flag(argument))) return [];
|
|
677
|
+
return [`${WORKER_FLAG}=${String(share)}`];
|
|
678
|
+
}
|
|
679
|
+
function mark_run_started(target) {
|
|
680
|
+
try {
|
|
681
|
+
stamp_file.write_stamp(target, process_identity.own_fields());
|
|
682
|
+
} catch {
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
async function with_run_marker(run2) {
|
|
686
|
+
if (is_nested_run()) return await run2();
|
|
687
|
+
const target = marker_path();
|
|
688
|
+
mark_run_started(target);
|
|
689
|
+
process.env[NESTED_KEY] = NESTED_VALUE;
|
|
690
|
+
try {
|
|
691
|
+
return await run2();
|
|
692
|
+
} finally {
|
|
693
|
+
process.env[NESTED_KEY] = "";
|
|
694
|
+
stamp_file.remove_stamp(target);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
var unit_worker_share = {
|
|
698
|
+
MIN_WORKERS,
|
|
699
|
+
NESTED_KEY,
|
|
700
|
+
NESTED_VALUE,
|
|
701
|
+
RUN_PREFIX,
|
|
702
|
+
SOLO_RUNS,
|
|
703
|
+
current_share,
|
|
704
|
+
is_nested_run,
|
|
705
|
+
live_run_count,
|
|
706
|
+
marker_path,
|
|
707
|
+
read_marker,
|
|
708
|
+
resolve_unit_workers,
|
|
709
|
+
with_run_marker,
|
|
710
|
+
worker_arguments
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
// scripts/gate/core-budget.ts
|
|
714
|
+
import { z as z4 } from "zod";
|
|
715
|
+
|
|
716
|
+
// scripts/gate/core-admission.ts
|
|
717
|
+
var MS_PER_SECOND = 1e3;
|
|
718
|
+
var RAMP_UP_MS = 3e4;
|
|
719
|
+
function compare_claim(left, right) {
|
|
720
|
+
const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
|
|
721
|
+
return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
|
|
722
|
+
}
|
|
723
|
+
function add_load(totals, reservation) {
|
|
724
|
+
totals.cores += reservation.weight;
|
|
725
|
+
totals.memory_mb += reservation.memory_mb ?? 0;
|
|
726
|
+
}
|
|
727
|
+
function exceeds(totals, budget) {
|
|
728
|
+
return totals.cores > budget.cores || totals.memory_mb > budget.memory_mb;
|
|
729
|
+
}
|
|
730
|
+
function admitted_keys(reservations, budget, memory_budget = Infinity) {
|
|
731
|
+
const limit = { cores: budget, memory_mb: memory_budget };
|
|
732
|
+
const totals = { cores: 0, memory_mb: 0 };
|
|
733
|
+
const admitted = /* @__PURE__ */ new Set();
|
|
734
|
+
for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
|
|
735
|
+
add_load(totals, entry.reservation);
|
|
736
|
+
if (index !== 0 && exceeds(totals, limit)) break;
|
|
737
|
+
admitted.add(entry.key);
|
|
738
|
+
}
|
|
739
|
+
return admitted;
|
|
740
|
+
}
|
|
741
|
+
function is_admitted(key, reservations, budget) {
|
|
742
|
+
return admitted_keys(reservations, budget.cores, budget.memory_mb).has(key);
|
|
743
|
+
}
|
|
744
|
+
function sum_load(reservations) {
|
|
745
|
+
const load = { cores: 0, memory_mb: 0 };
|
|
746
|
+
for (const entry of reservations) add_load(load, entry.reservation);
|
|
747
|
+
return load;
|
|
748
|
+
}
|
|
749
|
+
function is_ramped(reservation, now) {
|
|
750
|
+
const { admitted_at } = reservation;
|
|
751
|
+
return admitted_at !== void 0 && now - admitted_at >= RAMP_UP_MS;
|
|
752
|
+
}
|
|
753
|
+
function ledger_load(reservations, now) {
|
|
754
|
+
const admitted = reservations.filter((entry) => entry.reservation.admitted_at !== void 0);
|
|
755
|
+
const ramped = admitted.filter((entry) => is_ramped(entry.reservation, now));
|
|
756
|
+
return { cores: sum_load(admitted).cores, memory_mb: sum_load(ramped).memory_mb };
|
|
757
|
+
}
|
|
758
|
+
function total_weight(reservations) {
|
|
759
|
+
return sum_load(reservations).cores;
|
|
760
|
+
}
|
|
761
|
+
function admitted_load(reservations, budget) {
|
|
762
|
+
const admitted = admitted_keys(reservations, budget);
|
|
763
|
+
return total_weight(reservations.filter((entry) => admitted.has(entry.key)));
|
|
764
|
+
}
|
|
765
|
+
function describe_memory(ledger, budget) {
|
|
766
|
+
if (!Number.isFinite(budget.memory_mb)) return "";
|
|
767
|
+
return ` and ${String(Math.round(ledger.memory_mb))} MB of memory against ${String(Math.round(budget.memory_mb))} MB`;
|
|
768
|
+
}
|
|
769
|
+
function describe_overflow(admission) {
|
|
770
|
+
const { overflow } = admission;
|
|
771
|
+
if (overflow === void 0) return void 0;
|
|
772
|
+
const { ledger, budget } = overflow;
|
|
773
|
+
const waited = String(Math.round(overflow.waited_ms / MS_PER_SECOND));
|
|
774
|
+
const cores = `the ledger held ${String(ledger.cores)} cores against a budget of ${String(budget.cores)}`;
|
|
775
|
+
return `started past the core budget after ${waited}s \u2014 ${cores}${describe_memory(ledger, budget)}`;
|
|
776
|
+
}
|
|
777
|
+
var core_admission = {
|
|
778
|
+
RAMP_UP_MS,
|
|
779
|
+
admitted_keys,
|
|
780
|
+
admitted_load,
|
|
781
|
+
describe_overflow,
|
|
782
|
+
is_admitted,
|
|
783
|
+
ledger_load,
|
|
784
|
+
sum_load
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
// scripts/gate/machine-capacity.ts
|
|
788
|
+
import { readFile } from "node:fs/promises";
|
|
789
|
+
import { availableParallelism as availableParallelism2, cpus, totalmem } from "node:os";
|
|
790
|
+
import { execa } from "execa";
|
|
791
|
+
var SAMPLE_WINDOW_MS = 250;
|
|
792
|
+
var BASELINE_CORES = 2;
|
|
793
|
+
var BYTES_PER_MB = 1048576;
|
|
794
|
+
var KB_PER_MB = 1024;
|
|
795
|
+
var PERCENT = 100;
|
|
796
|
+
var MEMINFO_PATH = "/proc/meminfo";
|
|
797
|
+
var LINUX_AVAILABLE = /^MemAvailable:\s+(?<kb>\d+) kB/mu;
|
|
798
|
+
var PRESSURE_ARGUMENTS = ["-n", "kern.memorystatus_level"];
|
|
799
|
+
var PRESSURE_LEVEL = /^\s*(?<level>\d+)\s*$/u;
|
|
800
|
+
function cpu_times() {
|
|
801
|
+
let busy = 0;
|
|
802
|
+
let idle = 0;
|
|
803
|
+
for (const { times } of cpus()) {
|
|
804
|
+
busy += times.user + times.nice + times.sys + times.irq;
|
|
805
|
+
idle += times.idle;
|
|
806
|
+
}
|
|
807
|
+
return { busy, total: busy + idle };
|
|
808
|
+
}
|
|
809
|
+
function busy_cores_between(before, after, cores) {
|
|
810
|
+
const total = after.total - before.total;
|
|
811
|
+
if (total <= 0) return void 0;
|
|
812
|
+
return (after.busy - before.busy) / total * cores;
|
|
813
|
+
}
|
|
814
|
+
function parse_darwin_pressure(output, total_bytes) {
|
|
815
|
+
const level = PRESSURE_LEVEL.exec(output)?.groups?.["level"];
|
|
816
|
+
if (level === void 0) return void 0;
|
|
817
|
+
return Number(level) / PERCENT * (total_bytes / BYTES_PER_MB);
|
|
818
|
+
}
|
|
819
|
+
function parse_linux_available(meminfo) {
|
|
820
|
+
const kb = LINUX_AVAILABLE.exec(meminfo)?.groups?.["kb"];
|
|
821
|
+
return kb === void 0 ? void 0 : Number(kb) / KB_PER_MB;
|
|
822
|
+
}
|
|
823
|
+
async function read_available_mb(platform2 = process.platform) {
|
|
824
|
+
try {
|
|
825
|
+
if (platform2 === "darwin") {
|
|
826
|
+
const { stdout } = await execa("sysctl", PRESSURE_ARGUMENTS);
|
|
827
|
+
return parse_darwin_pressure(stdout, totalmem());
|
|
828
|
+
}
|
|
829
|
+
return platform2 === "linux" ? parse_linux_available(await readFile(MEMINFO_PATH, "utf8")) : void 0;
|
|
830
|
+
} catch {
|
|
831
|
+
return void 0;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
function is_unquoted() {
|
|
835
|
+
return cpus().length > 0 && cpus().length === availableParallelism2();
|
|
836
|
+
}
|
|
837
|
+
async function default_sleep(ms) {
|
|
838
|
+
await new Promise((resolve) => {
|
|
839
|
+
setTimeout(resolve, ms);
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
async function read_machine(sleep = default_sleep) {
|
|
843
|
+
const before = cpu_times();
|
|
844
|
+
const [available_mb] = await Promise.all([read_available_mb(), sleep(SAMPLE_WINDOW_MS)]);
|
|
845
|
+
const busy_cores = is_unquoted() ? busy_cores_between(before, cpu_times(), cpus().length) : void 0;
|
|
846
|
+
return { busy_cores, available_mb };
|
|
847
|
+
}
|
|
848
|
+
function external_cores(busy_cores, ledger_cores) {
|
|
849
|
+
if (busy_cores === void 0) return 0;
|
|
850
|
+
return Math.floor(Math.max(0, busy_cores - ledger_cores - BASELINE_CORES));
|
|
851
|
+
}
|
|
852
|
+
function machine_budget(cores, reading, ledger) {
|
|
853
|
+
return {
|
|
854
|
+
cores: cores - external_cores(reading.busy_cores, ledger.cores),
|
|
855
|
+
memory_mb: reading.available_mb === void 0 ? Infinity : reading.available_mb + ledger.memory_mb
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
var machine_capacity = {
|
|
859
|
+
BASELINE_CORES,
|
|
860
|
+
busy_cores_between,
|
|
861
|
+
machine_budget,
|
|
862
|
+
parse_darwin_pressure,
|
|
863
|
+
parse_linux_available,
|
|
864
|
+
read_machine
|
|
865
|
+
};
|
|
866
|
+
|
|
867
|
+
// scripts/gate/core-budget.ts
|
|
868
|
+
var RESERVED_PREFIX = "josh-core-reserved-";
|
|
869
|
+
var RESERVED_SUFFIX = ".json";
|
|
870
|
+
var POLL_INTERVAL_MS = 50;
|
|
871
|
+
var WAIT_CAP_MS = 12e4;
|
|
872
|
+
var MIN_BUDGET = 1;
|
|
873
|
+
var CORE_WEIGHTS = {
|
|
874
|
+
lint: 2,
|
|
875
|
+
type_check: 1,
|
|
876
|
+
spell_check: 1,
|
|
877
|
+
eslint_scan: 1
|
|
878
|
+
};
|
|
879
|
+
var MEMORY_MB = {
|
|
880
|
+
lint: 2400,
|
|
881
|
+
type_check: 1300,
|
|
882
|
+
spell_check: 350,
|
|
883
|
+
eslint_scan: 2400,
|
|
884
|
+
unit_worker: 350
|
|
885
|
+
};
|
|
886
|
+
var HELD_KEY = "JOSH_CORE_RESERVED";
|
|
887
|
+
var HELD_VALUE = "1";
|
|
888
|
+
var reservation_schema = process_owner_schema.extend({
|
|
889
|
+
weight: z4.number(),
|
|
890
|
+
claimed_at: z4.number(),
|
|
891
|
+
memory_mb: z4.number().optional(),
|
|
892
|
+
admitted_at: z4.number().optional()
|
|
893
|
+
});
|
|
894
|
+
function marker_name(key) {
|
|
895
|
+
return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`;
|
|
896
|
+
}
|
|
897
|
+
function is_running2(reservation) {
|
|
898
|
+
return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false;
|
|
899
|
+
}
|
|
900
|
+
function read_reservation(source) {
|
|
901
|
+
const raw = stamp_file.read_stamp_text(source);
|
|
902
|
+
if (raw === void 0) return void 0;
|
|
903
|
+
try {
|
|
904
|
+
const parsed = reservation_schema.safeParse(JSON.parse(raw));
|
|
905
|
+
return parsed.success ? parsed.data : void 0;
|
|
906
|
+
} catch {
|
|
907
|
+
return void 0;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
function sweep_marker2(source) {
|
|
911
|
+
try {
|
|
912
|
+
stamp_file.remove_stamp(source);
|
|
913
|
+
} catch {
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
function live_reservation(source) {
|
|
917
|
+
const reservation = read_reservation(source);
|
|
918
|
+
if (reservation === void 0) return void 0;
|
|
919
|
+
if (is_running2(reservation)) return reservation;
|
|
920
|
+
sweep_marker2(source);
|
|
921
|
+
return void 0;
|
|
922
|
+
}
|
|
923
|
+
function marker_files2(directory) {
|
|
924
|
+
try {
|
|
925
|
+
return readdirSync2(directory).filter(
|
|
926
|
+
(name) => name.startsWith(RESERVED_PREFIX) && name.endsWith(RESERVED_SUFFIX)
|
|
927
|
+
);
|
|
928
|
+
} catch {
|
|
929
|
+
return [];
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
function live_reservations(directory = PLATFORM_TEMP_ROOT) {
|
|
933
|
+
return marker_files2(directory).flatMap((name) => {
|
|
934
|
+
const reservation = live_reservation(path8.join(directory, name));
|
|
935
|
+
return reservation === void 0 ? [] : { key: name, reservation };
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
function normalize_budget(budget) {
|
|
939
|
+
return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET;
|
|
940
|
+
}
|
|
941
|
+
async function default_sleep2(ms) {
|
|
942
|
+
await new Promise((resolve) => {
|
|
943
|
+
setTimeout(resolve, ms);
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
function write_reservation(target, fields) {
|
|
947
|
+
stamp_file.replace_stamp(target, { ...process_identity.own_fields(), ...fields });
|
|
948
|
+
}
|
|
949
|
+
function resolve_timing(options) {
|
|
950
|
+
return {
|
|
951
|
+
now: options.now ?? Date.now,
|
|
952
|
+
sleep: options.sleep ?? default_sleep2,
|
|
953
|
+
poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
|
|
954
|
+
wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
async function current_budget(context, reservations) {
|
|
958
|
+
if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity };
|
|
959
|
+
const reading = await context.read_machine();
|
|
960
|
+
const ledger = core_admission.ledger_load(reservations, context.now());
|
|
961
|
+
const budget = machine_capacity.machine_budget(context.budget, reading, ledger);
|
|
962
|
+
return { ...budget, cores: normalize_budget(budget.cores) };
|
|
963
|
+
}
|
|
964
|
+
function admit(context, overflow) {
|
|
965
|
+
write_reservation(context.target, { ...context.fields, admitted_at: context.now() });
|
|
966
|
+
return { overflow };
|
|
967
|
+
}
|
|
968
|
+
function overflow_of(context, reservations, budget) {
|
|
969
|
+
return {
|
|
970
|
+
waited_ms: context.now() - context.fields.claimed_at,
|
|
971
|
+
ledger: core_admission.sum_load(reservations),
|
|
972
|
+
budget
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
async function poll_admission(context) {
|
|
976
|
+
const reservations = live_reservations(context.directory);
|
|
977
|
+
const budget = await current_budget(context, reservations);
|
|
978
|
+
if (core_admission.is_admitted(context.key, reservations, budget)) return admit(context);
|
|
979
|
+
if (context.now() >= context.deadline) {
|
|
980
|
+
return admit(context, overflow_of(context, reservations, budget));
|
|
981
|
+
}
|
|
982
|
+
return void 0;
|
|
983
|
+
}
|
|
984
|
+
async function await_admission(context) {
|
|
985
|
+
let admission = await poll_admission(context);
|
|
986
|
+
while (admission === void 0) {
|
|
987
|
+
await context.sleep(context.poll_interval_ms);
|
|
988
|
+
admission = await poll_admission(context);
|
|
989
|
+
}
|
|
990
|
+
return admission;
|
|
991
|
+
}
|
|
992
|
+
async function reserve(weight, options = {}) {
|
|
993
|
+
const timing = resolve_timing(options);
|
|
994
|
+
const directory = options.directory ?? PLATFORM_TEMP_ROOT;
|
|
995
|
+
const claimed_at = timing.now();
|
|
996
|
+
const name = marker_name(randomUUID3());
|
|
997
|
+
const target = path8.join(directory, name);
|
|
998
|
+
const fields = { weight, claimed_at, memory_mb: options.memory_mb };
|
|
999
|
+
write_reservation(target, fields);
|
|
1000
|
+
const admission = await await_admission({
|
|
1001
|
+
...timing,
|
|
1002
|
+
key: name,
|
|
1003
|
+
target,
|
|
1004
|
+
directory,
|
|
1005
|
+
budget: normalize_budget(options.budget ?? availableParallelism3()),
|
|
1006
|
+
deadline: claimed_at + timing.wait_cap_ms,
|
|
1007
|
+
fields,
|
|
1008
|
+
read_machine: options.read_machine ?? machine_capacity.read_machine
|
|
1009
|
+
});
|
|
1010
|
+
return { target, admission };
|
|
1011
|
+
}
|
|
1012
|
+
function release(handle) {
|
|
1013
|
+
sweep_marker2(handle.target);
|
|
1014
|
+
}
|
|
1015
|
+
async function with_core_reservation(weight, run2, options = {}) {
|
|
1016
|
+
const handle = await reserve(weight, options);
|
|
1017
|
+
try {
|
|
1018
|
+
return await run2(handle.admission);
|
|
1019
|
+
} finally {
|
|
1020
|
+
release(handle);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
function is_held() {
|
|
1024
|
+
return process.env[HELD_KEY] === HELD_VALUE;
|
|
1025
|
+
}
|
|
1026
|
+
function set_held_mark(value) {
|
|
1027
|
+
process.env[HELD_KEY] = value;
|
|
1028
|
+
}
|
|
1029
|
+
async function with_held_mark(run2) {
|
|
1030
|
+
const previous = process.env[HELD_KEY] ?? "";
|
|
1031
|
+
set_held_mark(HELD_VALUE);
|
|
1032
|
+
try {
|
|
1033
|
+
return await run2();
|
|
1034
|
+
} finally {
|
|
1035
|
+
set_held_mark(previous);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
async function with_command_reservation(weight, run2, options = {}) {
|
|
1039
|
+
if (is_held() || unit_worker_share.is_nested_run()) return await run2();
|
|
1040
|
+
return await with_core_reservation(weight, async () => await with_held_mark(run2), options);
|
|
1041
|
+
}
|
|
1042
|
+
var core_budget = {
|
|
1043
|
+
CORE_WEIGHTS,
|
|
1044
|
+
HELD_KEY,
|
|
1045
|
+
HELD_VALUE,
|
|
1046
|
+
MEMORY_MB,
|
|
1047
|
+
RESERVED_PREFIX,
|
|
1048
|
+
admitted_keys: core_admission.admitted_keys,
|
|
1049
|
+
admitted_load: core_admission.admitted_load,
|
|
1050
|
+
describe_overflow: core_admission.describe_overflow,
|
|
1051
|
+
is_held,
|
|
1052
|
+
live_reservations,
|
|
1053
|
+
release,
|
|
1054
|
+
reserve,
|
|
1055
|
+
with_command_reservation,
|
|
1056
|
+
with_core_reservation,
|
|
1057
|
+
with_held_mark
|
|
1058
|
+
};
|
|
1059
|
+
|
|
304
1060
|
// scripts/josh/josh-logic.ts
|
|
305
1061
|
import { execaSync as execaSync2 } from "execa";
|
|
306
1062
|
|
|
@@ -410,6 +1166,9 @@ var BACKLOG_COMMANDS = {
|
|
|
410
1166
|
},
|
|
411
1167
|
"backlog:stalled": {
|
|
412
1168
|
script: "scripts/backlog/backlog-stalled-cli.ts",
|
|
1169
|
+
// A stall sends one Telegram warning (joshuafolkken/kit#3357). The `Stop` hook calls the detector
|
|
1170
|
+
// directly, so this flag costs only the manual command its in-process dispatch.
|
|
1171
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
413
1172
|
description: "Report whether ready backlog work is sitting undispatched with a free lane and no recent dispatch",
|
|
414
1173
|
category: "AI tools",
|
|
415
1174
|
reference: ["", "automation", ["network"]]
|
|
@@ -428,7 +1187,8 @@ var DOCUMENT_COMMANDS = {
|
|
|
428
1187
|
script: "scripts/document/document-section-cli.ts",
|
|
429
1188
|
description: 'Print one section of a markdown document, for a `file.md` \u2192 "Heading" reference',
|
|
430
1189
|
category: "AI tools",
|
|
431
|
-
reference: ["<file> <heading>", "automation", ["none"]]
|
|
1190
|
+
reference: ["<file> <heading>", "automation", ["none"]],
|
|
1191
|
+
is_bundled: true
|
|
432
1192
|
},
|
|
433
1193
|
"read:set": {
|
|
434
1194
|
script: "scripts/document/read-set-cli.ts",
|
|
@@ -534,10 +1294,16 @@ var ISSUE_COMMANDS = {
|
|
|
534
1294
|
description: "File an Issue with every filing step: lint, Origin, WIP cap, duplicate scout, labels, then epic:bundle",
|
|
535
1295
|
category: "AI tools",
|
|
536
1296
|
reference: [
|
|
537
|
-
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok]",
|
|
1297
|
+
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok] [--release]",
|
|
538
1298
|
"automation",
|
|
539
1299
|
["network"]
|
|
540
1300
|
]
|
|
1301
|
+
},
|
|
1302
|
+
"issue:release": {
|
|
1303
|
+
script: "scripts/issue/issue-release-cli.ts",
|
|
1304
|
+
description: "Link an Issue to the repository's open release Issue as its blocker, filing one when none is open",
|
|
1305
|
+
category: "AI tools",
|
|
1306
|
+
reference: ["<issue>", "automation", ["network"]]
|
|
541
1307
|
}
|
|
542
1308
|
};
|
|
543
1309
|
|
|
@@ -545,6 +1311,10 @@ var ISSUE_COMMANDS = {
|
|
|
545
1311
|
var LANE_SCRIPT = "scripts/lane/lane-cli.ts";
|
|
546
1312
|
var LANE_ARGUMENTS = { script: LANE_SCRIPT, tsx_arguments: OPTIONAL_ENV_FILE_FLAGS };
|
|
547
1313
|
var ISSUE_WITH_OPTIONS = "<issue> [options]";
|
|
1314
|
+
var MEASURE_ARGUMENTS = {
|
|
1315
|
+
script: "scripts/lane/lane-measure-cli.ts",
|
|
1316
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
|
|
1317
|
+
};
|
|
548
1318
|
var LANE_COMMANDS = {
|
|
549
1319
|
"lane:open": {
|
|
550
1320
|
...LANE_ARGUMENTS,
|
|
@@ -569,7 +1339,7 @@ var LANE_COMMANDS = {
|
|
|
569
1339
|
},
|
|
570
1340
|
"lane:prune": {
|
|
571
1341
|
...LANE_ARGUMENTS,
|
|
572
|
-
description: "Close every lane an interruption left without its work tree",
|
|
1342
|
+
description: "Close every lane an interruption left without its work tree, then sweep unregistered leftovers under the lanes root",
|
|
573
1343
|
category: "AI tools",
|
|
574
1344
|
reference: ["", "automation", ["files", "git"]],
|
|
575
1345
|
default_script_arguments: ["prune"]
|
|
@@ -600,11 +1370,27 @@ var LANE_COMMANDS = {
|
|
|
600
1370
|
description: "Collapse a backlogrun lane-start event into one call: open the lane, pop and re-install on the first, dispatch the child",
|
|
601
1371
|
category: "AI tools",
|
|
602
1372
|
reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
|
|
1373
|
+
},
|
|
1374
|
+
// The lane-limit measurement (joshuafolkken/kit#3355): `.env` is read so `lane:stats` labels the row
|
|
1375
|
+
// with the `JOSH_LANE_LIMIT` a person set there.
|
|
1376
|
+
"lane:sample": {
|
|
1377
|
+
...MEASURE_ARGUMENTS,
|
|
1378
|
+
description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger",
|
|
1379
|
+
category: "AI tools",
|
|
1380
|
+
reference: ["[--every <seconds>]", "maintainer", ["files"]],
|
|
1381
|
+
default_script_arguments: ["sample"]
|
|
1382
|
+
},
|
|
1383
|
+
"lane:stats": {
|
|
1384
|
+
...MEASURE_ARGUMENTS,
|
|
1385
|
+
description: "Print one table row of lane throughput, gate duration and machine load over a period",
|
|
1386
|
+
category: "AI tools",
|
|
1387
|
+
reference: ["--period <days> [--limit <lane-limit>]", "maintainer", ["none"]],
|
|
1388
|
+
default_script_arguments: ["stats"]
|
|
603
1389
|
}
|
|
604
1390
|
};
|
|
605
1391
|
|
|
606
1392
|
// scripts/josh/josh-commands-run.ts
|
|
607
|
-
var RUN_HOLD_SCRIPT = "scripts/run/run-hold-cli.ts";
|
|
1393
|
+
var RUN_HOLD_SCRIPT = "scripts/run/hold/run-hold-cli.ts";
|
|
608
1394
|
var RUN_COMMANDS = {
|
|
609
1395
|
"run:hold": {
|
|
610
1396
|
script: RUN_HOLD_SCRIPT,
|
|
@@ -620,19 +1406,22 @@ var RUN_COMMANDS = {
|
|
|
620
1406
|
default_script_arguments: ["--release"]
|
|
621
1407
|
},
|
|
622
1408
|
"run:tidy": {
|
|
623
|
-
script: "scripts/run/run-tidy-cli.ts",
|
|
1409
|
+
script: "scripts/run/tidy/run-tidy-cli.ts",
|
|
624
1410
|
description: "Close merged lanes and drop stashes whose issues are all merged",
|
|
625
1411
|
category: "AI tools",
|
|
626
1412
|
reference: ["", "automation", ["git", "network", "files"]]
|
|
627
1413
|
},
|
|
628
1414
|
"run:carry": {
|
|
629
|
-
script: "scripts/run/run-carry-cli.ts",
|
|
1415
|
+
script: "scripts/run/carry/run-carry-cli.ts",
|
|
1416
|
+
// `--stopped` sends the stop confirmation, so the Telegram credentials come from `.env` as for
|
|
1417
|
+
// `run:wake` below (joshuafolkken/kit#3357).
|
|
1418
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
630
1419
|
description: "Carry one invocation\u2019s budget across its own session cuts",
|
|
631
1420
|
category: "AI tools",
|
|
632
1421
|
reference: ["<operation> [arguments...]", "automation", ["files"]]
|
|
633
1422
|
},
|
|
634
1423
|
"run:wake": {
|
|
635
|
-
script: "scripts/run/run-wake-cli.ts",
|
|
1424
|
+
script: "scripts/run/wake/run-wake-cli.ts",
|
|
636
1425
|
// `.env` rather than the ambient environment:
|
|
637
1426
|
// the failure warning needs the Telegram credentials, the same
|
|
638
1427
|
// reasons `notify` and `followup` carry these flags.
|
|
@@ -642,7 +1431,7 @@ var RUN_COMMANDS = {
|
|
|
642
1431
|
reference: ["[options]", "automation", ["processes", "notifications"]]
|
|
643
1432
|
},
|
|
644
1433
|
"run:cut": {
|
|
645
|
-
script: "scripts/run/run-cut-cli.ts",
|
|
1434
|
+
script: "scripts/run/cut/run-cut-cli.ts",
|
|
646
1435
|
description: "Cut a lane child before the gate and resume a fresh process",
|
|
647
1436
|
category: "AI tools",
|
|
648
1437
|
reference: ["[--resume] <issue> [--impl] [--handoff <path>]", "automation", ["files"]]
|
|
@@ -660,7 +1449,7 @@ var RUN_COMMANDS = {
|
|
|
660
1449
|
reference: ["<issue> --output <path> [--repo <owner/repo>]", "automation", ["network"]]
|
|
661
1450
|
},
|
|
662
1451
|
"run:progress": {
|
|
663
|
-
script: "scripts/run/run-progress-cli.ts",
|
|
1452
|
+
script: "scripts/run/progress/run-progress-cli.ts",
|
|
664
1453
|
description: "Report an unattended run\u2019s progress once it has gone quiet for an interval",
|
|
665
1454
|
category: "AI tools",
|
|
666
1455
|
reference: [
|
|
@@ -679,7 +1468,9 @@ var RUN_COMMANDS = {
|
|
|
679
1468
|
// read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
|
|
680
1469
|
// `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
|
|
681
1470
|
"run:entry": {
|
|
682
|
-
script: "scripts/run/run-entry-cli.ts",
|
|
1471
|
+
script: "scripts/run/entry/run-entry-cli.ts",
|
|
1472
|
+
// A `busy` hold or an `over` budget sends the stop confirmation (joshuafolkken/kit#3357).
|
|
1473
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
683
1474
|
description: "Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step",
|
|
684
1475
|
category: "AI tools",
|
|
685
1476
|
reference: ["<issue> [--to <command>]", "automation", ["git", "network", "files"]]
|
|
@@ -843,13 +1634,13 @@ var AI_COMMANDS = {
|
|
|
843
1634
|
reference: ["[<owner/repo>]", "automation", ["none"]]
|
|
844
1635
|
},
|
|
845
1636
|
"run:merge": {
|
|
846
|
-
script: "scripts/run/run-merge-cli.ts",
|
|
1637
|
+
script: "scripts/run/merge/run-merge-cli.ts",
|
|
847
1638
|
description: "Collapse a backlogrun merge event into one call: confirm the child, do the post-merge steps, offer the next child",
|
|
848
1639
|
category: "AI tools",
|
|
849
1640
|
reference: [ISSUE_WITH_OPTIONS2, "automation", ["git", "network"]]
|
|
850
1641
|
},
|
|
851
1642
|
"run:review": {
|
|
852
|
-
script: "scripts/run/run-review-cli.ts",
|
|
1643
|
+
script: "scripts/run/review/run-review-cli.ts",
|
|
853
1644
|
description: "Start the gate in the background and print the /code-review brief in one call so the two overlap (--join to join the gate and check its verdict)",
|
|
854
1645
|
category: "AI tools",
|
|
855
1646
|
reference: ["[--join]", "automation", ["processes", "files"]]
|
|
@@ -868,7 +1659,7 @@ var AI_COMMANDS = {
|
|
|
868
1659
|
// (`run:tail`) were four round trips re-billing the run's full context each. It stops at the first
|
|
869
1660
|
// failed step and names it, so the run reads only the step to fix.
|
|
870
1661
|
ship: {
|
|
871
|
-
script: "scripts/run/run-ship-cli.ts",
|
|
1662
|
+
script: "scripts/run/ship/run-ship-cli.ts",
|
|
872
1663
|
description: "Ship a change in one call: gate, commit/push/PR, the CI-wait merge and the report bookkeeping, stopping at the first failed step",
|
|
873
1664
|
category: "AI tools",
|
|
874
1665
|
reference: [
|
|
@@ -878,7 +1669,7 @@ var AI_COMMANDS = {
|
|
|
878
1669
|
]
|
|
879
1670
|
},
|
|
880
1671
|
"run:event": {
|
|
881
|
-
script: "scripts/run/run-event-cli.ts",
|
|
1672
|
+
script: "scripts/run/event/run-event-cli.ts",
|
|
882
1673
|
description: "Append to, read or watch the run\u2019s append-only event stream (--append <kind> <text> | --from|--follow <n> | --watch [<n>] | --last)",
|
|
883
1674
|
category: "AI tools",
|
|
884
1675
|
reference: [
|
|
@@ -938,6 +1729,192 @@ var CLONE_COMMANDS = {
|
|
|
938
1729
|
}
|
|
939
1730
|
};
|
|
940
1731
|
|
|
1732
|
+
// scripts/gate/gate-plan.ts
|
|
1733
|
+
import { availableParallelism as availableParallelism4 } from "node:os";
|
|
1734
|
+
|
|
1735
|
+
// scripts/lib/status-icons.ts
|
|
1736
|
+
var FAIL_ICON = "\u2717";
|
|
1737
|
+
var PASS_ICON = "\u2714";
|
|
1738
|
+
var status_icons = { FAIL_ICON, PASS_ICON };
|
|
1739
|
+
|
|
1740
|
+
// scripts/josh/josh-verdict.ts
|
|
1741
|
+
var { FAIL_ICON: FAIL_ICON2, PASS_ICON: PASS_ICON2 } = status_icons;
|
|
1742
|
+
var GATE_SUBJECT = "verification gate";
|
|
1743
|
+
var GATE_PASSED_PREFIX = `${PASS_ICON2} ${GATE_SUBJECT} passed`;
|
|
1744
|
+
var GATE_FAILED_PREFIX = `${FAIL_ICON2} ${GATE_SUBJECT} failed`;
|
|
1745
|
+
var PASSED_VERDICT = "passed";
|
|
1746
|
+
var FAILED_VERDICT = "failed";
|
|
1747
|
+
function format_gate_passed(step_count, total) {
|
|
1748
|
+
return `${GATE_PASSED_PREFIX} (${step_count} checks) in ${total}.`;
|
|
1749
|
+
}
|
|
1750
|
+
function format_gate_failed(failed_labels, total) {
|
|
1751
|
+
return `${GATE_FAILED_PREFIX}: ${failed_labels} (${total})`;
|
|
1752
|
+
}
|
|
1753
|
+
var GATE_OPENING_PREFIX = "plan: ";
|
|
1754
|
+
var GATE_OPENING_MARK = " checks at once";
|
|
1755
|
+
function is_gate_opening(line) {
|
|
1756
|
+
const trimmed = line.trimStart();
|
|
1757
|
+
return trimmed.startsWith(GATE_OPENING_PREFIX) && trimmed.includes(GATE_OPENING_MARK);
|
|
1758
|
+
}
|
|
1759
|
+
function read_verdict(line) {
|
|
1760
|
+
const trimmed = line.trimStart();
|
|
1761
|
+
if (trimmed.startsWith(GATE_FAILED_PREFIX)) return FAILED_VERDICT;
|
|
1762
|
+
if (trimmed.startsWith(GATE_PASSED_PREFIX)) return PASSED_VERDICT;
|
|
1763
|
+
return void 0;
|
|
1764
|
+
}
|
|
1765
|
+
var josh_verdict = {
|
|
1766
|
+
PASSED_VERDICT,
|
|
1767
|
+
FAILED_VERDICT,
|
|
1768
|
+
format_gate_passed,
|
|
1769
|
+
format_gate_failed,
|
|
1770
|
+
GATE_OPENING_MARK,
|
|
1771
|
+
GATE_OPENING_PREFIX,
|
|
1772
|
+
is_gate_opening,
|
|
1773
|
+
read_verdict
|
|
1774
|
+
};
|
|
1775
|
+
|
|
1776
|
+
// scripts/gate/gate-plan.ts
|
|
1777
|
+
var LINT_LABEL = "lint";
|
|
1778
|
+
var TYPE_CHECK_LABEL = "check";
|
|
1779
|
+
var UNIT_LABEL = "test:unit";
|
|
1780
|
+
var BEHAVIOR_LABEL = "behavior";
|
|
1781
|
+
var WARNING_CHECKER_LABELS = [LINT_LABEL, TYPE_CHECK_LABEL];
|
|
1782
|
+
var STATIC_CHECKS = [
|
|
1783
|
+
{
|
|
1784
|
+
label: LINT_LABEL,
|
|
1785
|
+
target: "lint",
|
|
1786
|
+
reserved_cores: core_budget.CORE_WEIGHTS.lint,
|
|
1787
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
1788
|
+
},
|
|
1789
|
+
{
|
|
1790
|
+
label: TYPE_CHECK_LABEL,
|
|
1791
|
+
target: "check",
|
|
1792
|
+
reserved_cores: core_budget.CORE_WEIGHTS.type_check,
|
|
1793
|
+
memory_mb: core_budget.MEMORY_MB.type_check
|
|
1794
|
+
},
|
|
1795
|
+
{
|
|
1796
|
+
label: "cspell",
|
|
1797
|
+
target: "cspell:dot",
|
|
1798
|
+
reserved_cores: core_budget.CORE_WEIGHTS.spell_check,
|
|
1799
|
+
memory_mb: core_budget.MEMORY_MB.spell_check
|
|
1800
|
+
},
|
|
1801
|
+
{ label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
|
|
1802
|
+
// **The unused-member check reserves no core** (joshuafolkken/kit#2987): it builds one TypeScript
|
|
1803
|
+
// program and walks it for about 5s, and it is over well before lint and the type check. A
|
|
1804
|
+
// reservation would only take a place from the four-core CI runner's fan-out and a worker from the
|
|
1805
|
+
// unit suite for the whole gate.
|
|
1806
|
+
{ label: "exports", target: "exports:unused", reserved_cores: 0 }
|
|
1807
|
+
];
|
|
1808
|
+
var GATE_CHECKS = [
|
|
1809
|
+
...STATIC_CHECKS,
|
|
1810
|
+
{ label: UNIT_LABEL, target: UNIT_LABEL, reserved_cores: 0 }
|
|
1811
|
+
];
|
|
1812
|
+
function select_gate_checks(is_unit_included) {
|
|
1813
|
+
return is_unit_included ? GATE_CHECKS : STATIC_CHECKS;
|
|
1814
|
+
}
|
|
1815
|
+
function has_unit_check(checks) {
|
|
1816
|
+
return checks.some((check) => check.label === UNIT_LABEL);
|
|
1817
|
+
}
|
|
1818
|
+
var RESERVED_CORES = STATIC_CHECKS.reduce(
|
|
1819
|
+
(total, check) => total + check.reserved_cores,
|
|
1820
|
+
0
|
|
1821
|
+
);
|
|
1822
|
+
var MEASURED_CORES = 11;
|
|
1823
|
+
var MIN_CONCURRENCY = 1;
|
|
1824
|
+
var MIN_SHARED_CORES = 1;
|
|
1825
|
+
function shared_cores(available_cores, concurrent_runs) {
|
|
1826
|
+
const runs = Number.isFinite(concurrent_runs) ? Math.max(unit_worker_share.SOLO_RUNS, concurrent_runs) : unit_worker_share.SOLO_RUNS;
|
|
1827
|
+
return Math.max(MIN_SHARED_CORES, Math.floor(available_cores / runs));
|
|
1828
|
+
}
|
|
1829
|
+
function resolve_concurrency(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS, checks = GATE_CHECKS) {
|
|
1830
|
+
const share = shared_cores(available_cores, concurrent_runs);
|
|
1831
|
+
let admitted = 0;
|
|
1832
|
+
let reserved = 0;
|
|
1833
|
+
for (const check of checks) {
|
|
1834
|
+
reserved += check.reserved_cores;
|
|
1835
|
+
if (reserved > share) break;
|
|
1836
|
+
admitted += 1;
|
|
1837
|
+
}
|
|
1838
|
+
return Math.max(MIN_CONCURRENCY, admitted);
|
|
1839
|
+
}
|
|
1840
|
+
function resolve_unit_worker_cap(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS) {
|
|
1841
|
+
const share = unit_worker_share.resolve_unit_workers(available_cores, concurrent_runs);
|
|
1842
|
+
if (share !== void 0) return share;
|
|
1843
|
+
if (available_cores < MEASURED_CORES) return void 0;
|
|
1844
|
+
return available_cores - RESERVED_CORES;
|
|
1845
|
+
}
|
|
1846
|
+
function solo_unit_weight(available_cores) {
|
|
1847
|
+
return Math.max(0, available_cores - RESERVED_CORES);
|
|
1848
|
+
}
|
|
1849
|
+
function check_weight(check, plan, available_cores) {
|
|
1850
|
+
if (check.label !== UNIT_LABEL) return check.reserved_cores;
|
|
1851
|
+
return plan.unit_worker_cap ?? solo_unit_weight(available_cores);
|
|
1852
|
+
}
|
|
1853
|
+
function unit_memory(workers) {
|
|
1854
|
+
return workers * core_budget.MEMORY_MB.unit_worker;
|
|
1855
|
+
}
|
|
1856
|
+
function check_memory(check, plan, available_cores) {
|
|
1857
|
+
if (check.label !== UNIT_LABEL) return check.memory_mb ?? 0;
|
|
1858
|
+
return unit_memory(check_weight(check, plan, available_cores));
|
|
1859
|
+
}
|
|
1860
|
+
function direct_unit_weight(available_cores = availableParallelism4(), live_runs = unit_worker_share.live_run_count()) {
|
|
1861
|
+
const weight = unit_worker_share.current_share(available_cores, live_runs) ?? solo_unit_weight(available_cores);
|
|
1862
|
+
return Math.max(unit_worker_share.MIN_WORKERS, weight);
|
|
1863
|
+
}
|
|
1864
|
+
function direct_unit_memory() {
|
|
1865
|
+
return unit_memory(direct_unit_weight());
|
|
1866
|
+
}
|
|
1867
|
+
function plan_of(concurrency, unit_worker_cap, checks = GATE_CHECKS) {
|
|
1868
|
+
return { checks, concurrency, unit_worker_cap };
|
|
1869
|
+
}
|
|
1870
|
+
function resolve_gate_plan(available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS, is_unit_included = true) {
|
|
1871
|
+
const checks = select_gate_checks(is_unit_included);
|
|
1872
|
+
return {
|
|
1873
|
+
checks,
|
|
1874
|
+
concurrency: resolve_concurrency(available_cores, concurrent_runs, checks),
|
|
1875
|
+
unit_worker_cap: is_unit_included ? resolve_unit_worker_cap(available_cores, concurrent_runs) : void 0
|
|
1876
|
+
};
|
|
1877
|
+
}
|
|
1878
|
+
function format_machine(available_cores, concurrent_runs) {
|
|
1879
|
+
const cores = `${String(available_cores)} cores`;
|
|
1880
|
+
if (concurrent_runs <= unit_worker_share.SOLO_RUNS) return cores;
|
|
1881
|
+
return `${cores}, ${String(concurrent_runs)} unit runs`;
|
|
1882
|
+
}
|
|
1883
|
+
function format_unit_cap(plan) {
|
|
1884
|
+
if (!has_unit_check(plan.checks)) return `${UNIT_LABEL} elsewhere`;
|
|
1885
|
+
if (plan.unit_worker_cap === void 0) return `${UNIT_LABEL} unrestricted`;
|
|
1886
|
+
return `${UNIT_LABEL} at ${String(plan.unit_worker_cap)} workers`;
|
|
1887
|
+
}
|
|
1888
|
+
function format_gate_plan(plan, available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS) {
|
|
1889
|
+
const cap = format_unit_cap(plan);
|
|
1890
|
+
const count = `${String(plan.concurrency)} of ${String(plan.checks.length)}`;
|
|
1891
|
+
const width = `${count}${josh_verdict.GATE_OPENING_MARK}`;
|
|
1892
|
+
const machine = format_machine(available_cores, concurrent_runs);
|
|
1893
|
+
return `${josh_verdict.GATE_OPENING_PREFIX}${width}, ${cap} (${machine})`;
|
|
1894
|
+
}
|
|
1895
|
+
var gate_plan = {
|
|
1896
|
+
GATE_CHECKS,
|
|
1897
|
+
LINT_LABEL,
|
|
1898
|
+
MEASURED_CORES,
|
|
1899
|
+
RESERVED_CORES,
|
|
1900
|
+
STATIC_CHECKS,
|
|
1901
|
+
TYPE_CHECK_LABEL,
|
|
1902
|
+
UNIT_LABEL,
|
|
1903
|
+
WARNING_CHECKER_LABELS,
|
|
1904
|
+
check_memory,
|
|
1905
|
+
check_weight,
|
|
1906
|
+
direct_unit_memory,
|
|
1907
|
+
direct_unit_weight,
|
|
1908
|
+
format_gate_plan,
|
|
1909
|
+
format_machine,
|
|
1910
|
+
has_unit_check,
|
|
1911
|
+
plan_of,
|
|
1912
|
+
resolve_concurrency,
|
|
1913
|
+
resolve_gate_plan,
|
|
1914
|
+
resolve_unit_worker_cap,
|
|
1915
|
+
select_gate_checks
|
|
1916
|
+
};
|
|
1917
|
+
|
|
941
1918
|
// scripts/josh/josh-commands-development.ts
|
|
942
1919
|
var FILE_ARGUMENTS = "[files...]";
|
|
943
1920
|
var REQUIRED_FILE_ARGUMENTS = "<files...>";
|
|
@@ -961,25 +1938,33 @@ var DEV_COMMANDS = {
|
|
|
961
1938
|
script: "scripts/lint/lint-parallel.ts",
|
|
962
1939
|
description: "Check code with prettier and eslint (skips a tool a basic project lacks)",
|
|
963
1940
|
category: "Development",
|
|
964
|
-
reference: ["", "developer", ["processes"]]
|
|
1941
|
+
reference: ["", "developer", ["processes"]],
|
|
1942
|
+
core_weight: core_budget.CORE_WEIGHTS.lint,
|
|
1943
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
965
1944
|
},
|
|
966
1945
|
"lint:related": {
|
|
967
1946
|
script: "scripts/lint/lint-related.ts",
|
|
968
1947
|
description: "Check only the changed files with prettier and eslint (whole tree on fallback)",
|
|
969
1948
|
category: "Development",
|
|
970
|
-
reference: [FILE_ARGUMENTS, "developer", ["processes"]]
|
|
1949
|
+
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
1950
|
+
core_weight: core_budget.CORE_WEIGHTS.lint,
|
|
1951
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
971
1952
|
},
|
|
972
1953
|
lines: {
|
|
973
1954
|
script: "scripts/lines/lines-command.ts",
|
|
974
1955
|
description: "Print a file's code lines against the max-lines limit and the headroom left",
|
|
975
1956
|
category: "Development",
|
|
976
|
-
reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]]
|
|
1957
|
+
reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]],
|
|
1958
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1959
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan
|
|
977
1960
|
},
|
|
978
1961
|
"refactor:scan": {
|
|
979
1962
|
script: "scripts/refactor/refactor-scan-cli.ts",
|
|
980
1963
|
description: "List refactoring candidates in the changed scope by category and answer clear/candidates",
|
|
981
1964
|
category: "Development",
|
|
982
|
-
reference: ["", "automation", ["processes"]]
|
|
1965
|
+
reference: ["", "automation", ["processes"]],
|
|
1966
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1967
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan
|
|
983
1968
|
},
|
|
984
1969
|
bytes: {
|
|
985
1970
|
script: "scripts/lines/bytes-command.ts",
|
|
@@ -1058,7 +2043,9 @@ var DEV_COMMANDS = {
|
|
|
1058
2043
|
script: "scripts/lint/cspell-cached.ts",
|
|
1059
2044
|
description: "Run spell check including dotfiles",
|
|
1060
2045
|
category: "Development",
|
|
1061
|
-
reference: ["", "developer", ["processes"]]
|
|
2046
|
+
reference: ["", "developer", ["processes"]],
|
|
2047
|
+
core_weight: core_budget.CORE_WEIGHTS.spell_check,
|
|
2048
|
+
memory_mb: core_budget.MEMORY_MB.spell_check
|
|
1062
2049
|
},
|
|
1063
2050
|
behavior: {
|
|
1064
2051
|
script: "scripts/behavior/behavior-cli.ts",
|
|
@@ -1076,13 +2063,17 @@ var DEV_COMMANDS = {
|
|
|
1076
2063
|
script: "scripts/test/test-unit-guard.ts",
|
|
1077
2064
|
description: "Run unit tests with Vitest (skips when Vitest is absent; fails when it has no tests)",
|
|
1078
2065
|
category: "Development",
|
|
1079
|
-
reference: [FILTER_ARGUMENTS, "developer", ["processes"]]
|
|
2066
|
+
reference: [FILTER_ARGUMENTS, "developer", ["processes"]],
|
|
2067
|
+
core_weight: gate_plan.direct_unit_weight,
|
|
2068
|
+
memory_mb: gate_plan.direct_unit_memory
|
|
1080
2069
|
},
|
|
1081
2070
|
"test:related": {
|
|
1082
2071
|
script: "scripts/test/test-related.ts",
|
|
1083
2072
|
description: "Run only the unit tests related to the changed files (full suite on fallback)",
|
|
1084
2073
|
category: "Development",
|
|
1085
|
-
reference: [FILE_ARGUMENTS, "developer", ["processes"]]
|
|
2074
|
+
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
2075
|
+
core_weight: gate_plan.direct_unit_weight,
|
|
2076
|
+
memory_mb: gate_plan.direct_unit_memory
|
|
1086
2077
|
},
|
|
1087
2078
|
"test:declared": {
|
|
1088
2079
|
script: "scripts/test/test-declared.ts",
|
|
@@ -1125,7 +2116,9 @@ var DEV_COMMANDS = {
|
|
|
1125
2116
|
script: "scripts/gate/type-check-command.ts",
|
|
1126
2117
|
description: "Type-check with tsc (skips a basic project with no TypeScript to check)",
|
|
1127
2118
|
category: "Development",
|
|
1128
|
-
reference: ["[arguments...]", "developer", ["processes"]]
|
|
2119
|
+
reference: ["[arguments...]", "developer", ["processes"]],
|
|
2120
|
+
core_weight: core_budget.CORE_WEIGHTS.type_check,
|
|
2121
|
+
memory_mb: core_budget.MEMORY_MB.type_check
|
|
1129
2122
|
},
|
|
1130
2123
|
port: {
|
|
1131
2124
|
script: "scripts/ports/port-command.ts",
|
|
@@ -1222,7 +2215,7 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1222
2215
|
script: "scripts/overrides/overrides-check.ts",
|
|
1223
2216
|
description: "Check pnpm overrides for drift",
|
|
1224
2217
|
category: "Maintenance",
|
|
1225
|
-
reference: ["[--save]", "
|
|
2218
|
+
reference: ["[--save]", "developer", ["files"]]
|
|
1226
2219
|
},
|
|
1227
2220
|
audit: {
|
|
1228
2221
|
script: "scripts/security/security-audit.ts",
|
|
@@ -1246,11 +2239,11 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1246
2239
|
shell: [
|
|
1247
2240
|
"sh",
|
|
1248
2241
|
"-c",
|
|
1249
|
-
"export NODE_AUTH_TOKEN=$(gh auth token) && pnpm josh latest:guard && pnpm josh latest:
|
|
2242
|
+
"export NODE_AUTH_TOKEN=$(gh auth token) && pnpm josh latest:guard && pnpm josh latest:update && pnpm josh ranges && pnpm josh audit && pnpm josh latest:corepack && pnpm josh latest:scope --record"
|
|
1250
2243
|
],
|
|
1251
|
-
description: "Update
|
|
2244
|
+
description: "Update dependencies, run security audit, then update pnpm",
|
|
1252
2245
|
category: "Maintenance",
|
|
1253
|
-
reference: ["", "
|
|
2246
|
+
reference: ["", "developer", ["files", "network", "processes"]],
|
|
1254
2247
|
argument_targets: ["latest:corepack", "latest:update", "audit"]
|
|
1255
2248
|
},
|
|
1256
2249
|
"latest:scope": {
|
|
@@ -1273,13 +2266,13 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1273
2266
|
script: "scripts/version/latest-corepack.ts",
|
|
1274
2267
|
description: "Update pnpm on the current major while preserving the integrity pin",
|
|
1275
2268
|
category: "Maintenance",
|
|
1276
|
-
reference: ["", "
|
|
2269
|
+
reference: ["", "developer", ["files", "network"]]
|
|
1277
2270
|
},
|
|
1278
2271
|
"latest:update": {
|
|
1279
2272
|
script: "scripts/version/latest-update.ts",
|
|
1280
2273
|
description: "Update all dependencies to latest",
|
|
1281
2274
|
category: "Maintenance",
|
|
1282
|
-
reference: ["", "
|
|
2275
|
+
reference: ["", "developer", ["files", "network"]]
|
|
1283
2276
|
}
|
|
1284
2277
|
};
|
|
1285
2278
|
|
|
@@ -1602,7 +2595,9 @@ var ALIASES = {
|
|
|
1602
2595
|
rtr: "retrospective",
|
|
1603
2596
|
rvf: "review:findings",
|
|
1604
2597
|
ruv: "rule:value",
|
|
1605
|
-
ev: "eval"
|
|
2598
|
+
ev: "eval",
|
|
2599
|
+
lsm: "lane:sample",
|
|
2600
|
+
lst: "lane:stats"
|
|
1606
2601
|
};
|
|
1607
2602
|
|
|
1608
2603
|
// scripts/josh/josh-composite-arguments.ts
|
|
@@ -1633,15 +2628,23 @@ var composite_arguments = { format_rejection, is_composite_shell, reject_extra_a
|
|
|
1633
2628
|
|
|
1634
2629
|
// scripts/josh/josh-in-process.ts
|
|
1635
2630
|
import { realpathSync } from "node:fs";
|
|
2631
|
+
import path9 from "node:path";
|
|
1636
2632
|
import { pathToFileURL } from "node:url";
|
|
1637
2633
|
var TYPESCRIPT_EXTENSION = ".ts";
|
|
2634
|
+
var JAVASCRIPT_EXTENSION = ".js";
|
|
2635
|
+
var BUNDLED_COMMAND_DIRECTORY = path9.join("dist", "commands");
|
|
1638
2636
|
var FAILURE_EXIT_CODE = 1;
|
|
1639
2637
|
function is_typescript_dispatcher(dispatcher_url) {
|
|
1640
2638
|
return dispatcher_url.endsWith(TYPESCRIPT_EXTENSION);
|
|
1641
2639
|
}
|
|
1642
|
-
function
|
|
1643
|
-
|
|
1644
|
-
return
|
|
2640
|
+
function bundled_script_path(package_directory, script) {
|
|
2641
|
+
const name = `${path9.basename(script, TYPESCRIPT_EXTENSION)}${JAVASCRIPT_EXTENSION}`;
|
|
2642
|
+
return path9.join(package_directory, BUNDLED_COMMAND_DIRECTORY, name);
|
|
2643
|
+
}
|
|
2644
|
+
function in_process_target(entry, package_directory, dispatcher_url) {
|
|
2645
|
+
if (entry.script === void 0 || entry.tsx_arguments !== void 0) return void 0;
|
|
2646
|
+
if (is_typescript_dispatcher(dispatcher_url)) return path9.join(package_directory, entry.script);
|
|
2647
|
+
return entry.is_bundled === true ? bundled_script_path(package_directory, entry.script) : void 0;
|
|
1645
2648
|
}
|
|
1646
2649
|
function read_exit_code() {
|
|
1647
2650
|
const code = process.exitCode;
|
|
@@ -1665,7 +2668,7 @@ async function run_in_process(script_path, script_arguments) {
|
|
|
1665
2668
|
}
|
|
1666
2669
|
return read_exit_code();
|
|
1667
2670
|
}
|
|
1668
|
-
var josh_in_process = {
|
|
2671
|
+
var josh_in_process = { bundled_script_path, in_process_target, run_in_process };
|
|
1669
2672
|
|
|
1670
2673
|
// scripts/josh/kit-only.ts
|
|
1671
2674
|
function kit_only_notice(cmd) {
|
|
@@ -1685,7 +2688,7 @@ var kit_only = {
|
|
|
1685
2688
|
|
|
1686
2689
|
// scripts/josh/run-github-prerequisite.ts
|
|
1687
2690
|
import { existsSync as existsSync3 } from "node:fs";
|
|
1688
|
-
import
|
|
2691
|
+
import path10 from "node:path";
|
|
1689
2692
|
|
|
1690
2693
|
// scripts/discovery/repo-origin.ts
|
|
1691
2694
|
var GITHUB_HOST = "github.com";
|
|
@@ -1750,15 +2753,15 @@ function origin_section_lines(lines) {
|
|
|
1750
2753
|
const end = rest.findIndex((line) => is_section_header(line));
|
|
1751
2754
|
return end === NOT_FOUND ? rest : rest.slice(0, end);
|
|
1752
2755
|
}
|
|
1753
|
-
function
|
|
2756
|
+
function url_value(line) {
|
|
1754
2757
|
const separator = line.indexOf("=");
|
|
1755
2758
|
if (separator === NOT_FOUND) return void 0;
|
|
1756
|
-
if (line.slice(0, separator).trim() !==
|
|
2759
|
+
if (line.slice(0, separator).trim() !== URL_KEY) return void 0;
|
|
1757
2760
|
return line.slice(separator + 1).trim();
|
|
1758
2761
|
}
|
|
1759
2762
|
function parse_origin_from_config(content) {
|
|
1760
2763
|
const lines = content.split("\n").map((line) => line.trim());
|
|
1761
|
-
return origin_section_lines(lines).map((line) =>
|
|
2764
|
+
return origin_section_lines(lines).map((line) => url_value(line)).find((url) => url !== void 0);
|
|
1762
2765
|
}
|
|
1763
2766
|
function section_groups(lines) {
|
|
1764
2767
|
const groups = [];
|
|
@@ -1770,7 +2773,7 @@ function section_groups(lines) {
|
|
|
1770
2773
|
}
|
|
1771
2774
|
function parse_remote_urls_from_config(content) {
|
|
1772
2775
|
const lines = content.split("\n").map((line) => line.trim());
|
|
1773
|
-
return section_groups(lines).filter((group) => REMOTE_SECTION.test(group[0] ?? "")).flatMap((group) => group.map((line) =>
|
|
2776
|
+
return section_groups(lines).filter((group) => REMOTE_SECTION.test(group[0] ?? "")).flatMap((group) => group.map((line) => url_value(line))).filter((url) => url !== void 0);
|
|
1774
2777
|
}
|
|
1775
2778
|
function format_identity(identity) {
|
|
1776
2779
|
return `${identity.owner}${PATH_SEPARATOR2}${identity.repo}`.toLowerCase();
|
|
@@ -1796,7 +2799,7 @@ var GITHUB_RUN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
1796
2799
|
]);
|
|
1797
2800
|
function explanation(root, command) {
|
|
1798
2801
|
if (!GITHUB_RUN_COMMANDS.has(command)) return void 0;
|
|
1799
|
-
if (!existsSync3(
|
|
2802
|
+
if (!existsSync3(path10.join(root, ".git"))) {
|
|
1800
2803
|
return `${command} requires Git and a GitHub origin. Run git init and add a GitHub origin first.`;
|
|
1801
2804
|
}
|
|
1802
2805
|
const url = git_spawn_sync.origin_url(root);
|
|
@@ -1813,24 +2816,21 @@ var TSX_PACKAGE = "tsx";
|
|
|
1813
2816
|
var PACKAGE_JSON2 = "package.json";
|
|
1814
2817
|
var UNKNOWN_COMMAND_EXIT_CODE = -1;
|
|
1815
2818
|
function find_package_directory(start_directory) {
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
current = parent;
|
|
1821
|
-
}
|
|
1822
|
-
return current;
|
|
2819
|
+
return ancestor_directories.nearest(
|
|
2820
|
+
start_directory,
|
|
2821
|
+
(directory) => existsSync4(path11.join(directory, PACKAGE_JSON2))
|
|
2822
|
+
) ?? start_directory;
|
|
1823
2823
|
}
|
|
1824
|
-
var
|
|
2824
|
+
var PACKAGE_DIR2 = find_package_directory(path11.dirname(fileURLToPath2(import.meta.url)));
|
|
1825
2825
|
function resolve_tsx_executable() {
|
|
1826
2826
|
const candidates = [
|
|
1827
|
-
resolve_local_bin(
|
|
2827
|
+
resolve_local_bin(PACKAGE_DIR2, TSX_BIN),
|
|
1828
2828
|
resolve_local_bin(process.cwd(), TSX_BIN)
|
|
1829
2829
|
];
|
|
1830
2830
|
return candidates.find(existsSync4) ?? TSX_BIN;
|
|
1831
2831
|
}
|
|
1832
2832
|
function resolve_tsx_cli_entry() {
|
|
1833
|
-
for (const base_directory of [
|
|
2833
|
+
for (const base_directory of [PACKAGE_DIR2, process.cwd()]) {
|
|
1834
2834
|
const cli_entry = resolve_package_bin(base_directory, TSX_PACKAGE, TSX_BIN);
|
|
1835
2835
|
if (cli_entry !== void 0) return cli_entry;
|
|
1836
2836
|
}
|
|
@@ -1844,7 +2844,7 @@ function resolve_tsx_runner() {
|
|
|
1844
2844
|
return { executable: resolve_tsx_executable(), leading_arguments: [] };
|
|
1845
2845
|
}
|
|
1846
2846
|
function read_package_version() {
|
|
1847
|
-
const raw =
|
|
2847
|
+
const raw = readFileSync5(path11.join(PACKAGE_DIR2, PACKAGE_JSON2), "utf8");
|
|
1848
2848
|
return package_version_schema.parse(JSON.parse(raw)).version;
|
|
1849
2849
|
}
|
|
1850
2850
|
var HEADER = `josh v${read_package_version()} \u2014 Joshua Folkken's dev toolkit`;
|
|
@@ -1928,12 +2928,10 @@ function spawn_script_entry(entry, script_path, script_arguments) {
|
|
|
1928
2928
|
]);
|
|
1929
2929
|
}
|
|
1930
2930
|
async function run_script_entry(entry, subcommand_arguments) {
|
|
1931
|
-
const script_path = path4.join(PACKAGE_DIR, entry.script ?? "");
|
|
1932
2931
|
const script_arguments = [...entry.default_script_arguments ?? [], ...subcommand_arguments];
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
return spawn_script_entry(entry, script_path, script_arguments);
|
|
2932
|
+
const target = josh_in_process.in_process_target(entry, PACKAGE_DIR2, import.meta.url);
|
|
2933
|
+
if (target !== void 0) return await josh_in_process.run_in_process(target, script_arguments);
|
|
2934
|
+
return spawn_script_entry(entry, path11.join(PACKAGE_DIR2, entry.script ?? ""), script_arguments);
|
|
1937
2935
|
}
|
|
1938
2936
|
function github_prerequisite_exit(resolved, is_consumer) {
|
|
1939
2937
|
if (!is_consumer) return void 0;
|
|
@@ -1958,10 +2956,22 @@ function pre_dispatch_exit(resolved, entry, subcommand_arguments, is_consumer) {
|
|
|
1958
2956
|
console.error(rejection);
|
|
1959
2957
|
return USAGE_ERROR_EXIT_CODE;
|
|
1960
2958
|
}
|
|
1961
|
-
async function
|
|
2959
|
+
async function run_entry(entry, subcommand_arguments) {
|
|
1962
2960
|
if (entry.shell) return run_shell_command(entry.shell, subcommand_arguments);
|
|
1963
2961
|
return await run_script_entry(entry, subcommand_arguments);
|
|
1964
2962
|
}
|
|
2963
|
+
function declared(value) {
|
|
2964
|
+
return typeof value === "function" ? value() : value;
|
|
2965
|
+
}
|
|
2966
|
+
async function dispatch_entry(entry, subcommand_arguments) {
|
|
2967
|
+
const weight = declared(entry.core_weight);
|
|
2968
|
+
if (weight === void 0) return await run_entry(entry, subcommand_arguments);
|
|
2969
|
+
return await core_budget.with_command_reservation(
|
|
2970
|
+
weight,
|
|
2971
|
+
async () => await run_entry(entry, subcommand_arguments),
|
|
2972
|
+
{ memory_mb: declared(entry.memory_mb) }
|
|
2973
|
+
);
|
|
2974
|
+
}
|
|
1965
2975
|
async function run_command(cmd, subcommand_arguments, is_consumer = false) {
|
|
1966
2976
|
const resolved = resolve_alias(cmd);
|
|
1967
2977
|
const entry = Object.hasOwn(COMMAND_MAP, resolved) ? COMMAND_MAP[resolved] : void 0;
|