@joshuafolkken/kit 1.1166.0 → 1.1229.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 +9 -5
- package/.claude/skills/workflow-commands/backlogrun-park.md +29 -9
- package/.claude/skills/workflow-commands/backlogrun-progress.md +7 -2
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +4 -3
- package/.claude/skills/workflow-commands/backlogrun-steps.md +24 -15
- 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 +5 -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 +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +3 -3
- package/.claude/skills/workflow-commands/pre-gate-cut.md +10 -5
- 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 +47 -33
- package/.github/workflows/dependabot-auto-merge.yml +13 -6
- package/.github/workflows/publish.yml +48 -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 +26 -19
- 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-DYAVAM6S.js → chunk-55HHG5PX.js} +1405 -631
- package/dist/hooks/{chunk-A6P7PN7P.js → chunk-5VMKCCC4.js} +25 -10
- package/dist/hooks/chunk-5VNDSNG3.js +12 -0
- package/dist/hooks/{chunk-5KTCMCOT.js → chunk-6HJJXRBX.js} +4 -2
- package/dist/hooks/chunk-CDY4NFQG.js +15 -0
- package/dist/hooks/chunk-ELCN5LCH.js +135 -0
- package/dist/hooks/{chunk-ENA7P5FB.js → chunk-F56MFS4B.js} +3 -3
- package/dist/hooks/{chunk-ANJ2WGFD.js → chunk-FIVDHQGT.js} +7 -6
- package/dist/hooks/{chunk-3V37IID6.js → chunk-JBBMAPC4.js} +23 -14
- package/dist/hooks/{chunk-GU5MATVE.js → chunk-JUDKDCDP.js} +499 -389
- package/dist/hooks/{chunk-ZDZ555YH.js → chunk-NV2JRZZO.js} +743 -909
- package/dist/hooks/{chunk-V2BTOZHT.js → chunk-RNWHN5BP.js} +3 -3
- package/dist/hooks/{chunk-URJA6XY4.js → chunk-TQNPDZNH.js} +4 -4
- package/dist/hooks/{chunk-GYNGP7HI.js → chunk-VC3PZPZO.js} +1 -1
- 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 +232 -210
- 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 +81 -59
- package/dist/josh.js +872 -75
- 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/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 +31 -9
- package/scripts/backlog/backlog-offer-cli.ts +6 -6
- package/scripts/backlog/backlog-offer.ts +1 -1
- package/scripts/backlog/backlog-plan-cli.ts +7 -6
- package/scripts/backlog/backlog-pool.ts +57 -11
- package/scripts/backlog/backlog-rank.ts +18 -9
- package/scripts/backlog/backlog-ready.ts +1 -1
- package/scripts/backlog/backlog-restructure.ts +152 -0
- 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/backlog/backlog-waves.ts +15 -17
- 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/cost-runtime/context-cut-threshold.ts +1 -9
- package/scripts/cost-runtime/cost-verdict.ts +15 -28
- 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-followup-stages.ts +9 -0
- package/scripts/followup/git-pr-followup-checks.ts +142 -0
- package/scripts/followup/git-pr-followup.ts +5 -130
- package/scripts/gate/core-budget.ts +69 -1
- package/scripts/gate/gate-plan.ts +47 -7
- package/scripts/gate/gate-skip.ts +38 -7
- package/scripts/gate/hook-gate-reuse.ts +12 -10
- 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 +27 -8
- 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-issue.ts +5 -3
- package/scripts/gh/git-gh-pr-read.ts +68 -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 +9 -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 +18 -6
- 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 +12 -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/{schemas.ts → git-schemas.ts} +2 -0
- 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/git/main-merge.ts +57 -21
- 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 +5 -15
- 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/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 +1 -1
- 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 +45 -18
- package/scripts/issue/issue-file.ts +24 -1
- 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 +11 -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 +11 -1
- package/scripts/josh/josh-commands-document.ts +1 -0
- package/scripts/josh/josh-commands-lane.ts +22 -0
- package/scripts/josh/josh-commands-maintenance.ts +4 -4
- package/scripts/josh/josh-commands-run.ts +12 -7
- package/scripts/josh/josh-in-process.ts +28 -9
- package/scripts/josh/josh-logic.ts +33 -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 +3 -3
- 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 +35 -3
- package/scripts/lane/lane-ledger.ts +145 -0
- package/scripts/lane/lane-leftover.ts +1 -1
- 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-reap.ts +1 -3
- package/scripts/lane/lane-relaunch.ts +1 -1
- package/scripts/lane/lane-stats.ts +224 -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-notify.ts +26 -1
- 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/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 +3 -3
- 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} +12 -6
- 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} +3 -3
- package/scripts/run/{run-cut-report.ts → cut/run-cut-report.ts} +2 -2
- 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-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} +16 -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 +2 -2
- 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} +29 -8
- 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-next.ts → ship/run-ship-next.ts} +13 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +66 -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} +10 -6
- 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-stage.ts → ship/run-ship-stage.ts} +13 -0
- package/scripts/run/{run-ship-steps.ts → ship/run-ship-steps.ts} +15 -8
- package/scripts/run/ship/run-ship-stop-text.ts +13 -0
- package/scripts/run/ship/run-ship-sync.ts +128 -0
- package/scripts/run/{run-ship.ts → ship/run-ship.ts} +6 -0
- 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} +31 -9
- package/scripts/run/{run-wake-describe.ts → wake/run-wake-describe.ts} +3 -3
- package/scripts/run/{run-wake-driver.ts → wake/run-wake-driver.ts} +99 -17
- 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} +8 -2
- 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} +1 -1
- 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/test-red-logic.ts +17 -2
- package/scripts/test/test-red.ts +8 -7
- 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/time-runtime/time-transcript-line.ts +27 -1
- package/scripts/version/effective-upstream.ts +2 -20
- package/scripts/version/latest-corepack.ts +17 -17
- 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 +2 -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/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-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-render.ts → event/run-event-render.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-review.ts → ship/run-ship-review.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,22 +20,25 @@ 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
|
|
|
26
30
|
// scripts/git/constants.ts
|
|
27
31
|
import { platform } from "node:os";
|
|
28
32
|
var GIT_COMMAND_UNIX = "/usr/bin/git";
|
|
33
|
+
var GIT_BINARY_KEY = "JOSH_GIT_BINARY";
|
|
29
34
|
function get_git_command() {
|
|
30
|
-
if (platform() === "win32")
|
|
31
|
-
return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
|
|
32
|
-
}
|
|
35
|
+
if (platform() === "win32") return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
|
|
33
36
|
return GIT_COMMAND_UNIX;
|
|
34
37
|
}
|
|
35
38
|
function get_git_command_for_spawn() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
const binary = process.env[GIT_BINARY_KEY];
|
|
40
|
+
if (binary !== void 0 && binary !== "") return binary;
|
|
41
|
+
if (platform() === "win32") return String.raw`C:\Program Files\Git\cmd\git.exe`;
|
|
39
42
|
return GIT_COMMAND_UNIX;
|
|
40
43
|
}
|
|
41
44
|
var git_utilities = {
|
|
@@ -44,7 +47,6 @@ var git_utilities = {
|
|
|
44
47
|
};
|
|
45
48
|
|
|
46
49
|
// scripts/git/git-spawn-sync.ts
|
|
47
|
-
var GIT_TIMEOUT_MS = 1e4;
|
|
48
50
|
var SUCCESS_EXIT_CODE = 0;
|
|
49
51
|
var C_LOCALE = { LC_ALL: "C", LANGUAGE: "C" };
|
|
50
52
|
function run(args, options = {}) {
|
|
@@ -91,20 +93,20 @@ var ABSENT_CODE = "ENOENT";
|
|
|
91
93
|
function is_absent(error) {
|
|
92
94
|
return error instanceof Error && "code" in error && error.code === ABSENT_CODE;
|
|
93
95
|
}
|
|
94
|
-
function read_optional(
|
|
96
|
+
function read_optional(path12) {
|
|
95
97
|
try {
|
|
96
|
-
return readFileSync(
|
|
98
|
+
return readFileSync(path12, "utf8");
|
|
97
99
|
} catch (error) {
|
|
98
100
|
if (is_absent(error)) return void 0;
|
|
99
101
|
throw error;
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
|
-
function read_file_or_empty(
|
|
103
|
-
return read_optional(
|
|
104
|
+
function read_file_or_empty(path12) {
|
|
105
|
+
return read_optional(path12) ?? "";
|
|
104
106
|
}
|
|
105
|
-
function read_if_readable(
|
|
107
|
+
function read_if_readable(path12) {
|
|
106
108
|
try {
|
|
107
|
-
return readFileSync(
|
|
109
|
+
return readFileSync(path12, "utf8");
|
|
108
110
|
} catch {
|
|
109
111
|
return void 0;
|
|
110
112
|
}
|
|
@@ -122,7 +124,6 @@ var CLAUDE_MD = "CLAUDE.md";
|
|
|
122
124
|
var PLUGIN_ID = "kit@kit";
|
|
123
125
|
var CLAUDE_MD_POINTER = `@${NODE_MODULES}/${KIT_PACKAGE_NAME}/dist/${CLAUDE_MD}`;
|
|
124
126
|
var SECRETLINT_BIN = path.join(NODE_MODULES, ".bin", "secretlint");
|
|
125
|
-
var GIT_TIMEOUT_MS2 = 2e3;
|
|
126
127
|
var manifest_schema = z.object({
|
|
127
128
|
name: z.string().optional(),
|
|
128
129
|
dependencies: z.record(z.string(), z.string()).optional(),
|
|
@@ -157,7 +158,7 @@ function is_plugin_declared(root) {
|
|
|
157
158
|
}
|
|
158
159
|
function configured_hooks_path(root) {
|
|
159
160
|
const value = git_spawn_sync.read(["-C", root, "config", "--get", "core.hooksPath"], {
|
|
160
|
-
timeout:
|
|
161
|
+
timeout: PROBE_TIMEOUT_MS
|
|
161
162
|
});
|
|
162
163
|
return value === "" ? void 0 : value;
|
|
163
164
|
}
|
|
@@ -229,14 +230,31 @@ var doctor_consumer = {
|
|
|
229
230
|
};
|
|
230
231
|
|
|
231
232
|
// scripts/josh/josh-logic.ts
|
|
232
|
-
import { existsSync as existsSync4, readFileSync as
|
|
233
|
-
import
|
|
234
|
-
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";
|
|
235
236
|
|
|
236
237
|
// scripts/build/local-bin.ts
|
|
237
238
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
238
239
|
import { createRequire } from "node:module";
|
|
240
|
+
import path3 from "node:path";
|
|
241
|
+
|
|
242
|
+
// scripts/lib/ancestor-directories.ts
|
|
239
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 };
|
|
240
258
|
|
|
241
259
|
// scripts/lib/schemas.ts
|
|
242
260
|
import { z as z2 } from "zod";
|
|
@@ -278,26 +296,589 @@ var WINDOWS_SHIM_SUFFIX = ".cmd";
|
|
|
278
296
|
var PACKAGE_JSON = "package.json";
|
|
279
297
|
function resolve_local_bin(project_root, bin_name) {
|
|
280
298
|
const shim = process.platform === WINDOWS_PLATFORM ? `${bin_name}${WINDOWS_SHIM_SUFFIX}` : bin_name;
|
|
281
|
-
return
|
|
299
|
+
return path3.join(project_root, NODE_MODULES2, BIN_DIR, shim);
|
|
282
300
|
}
|
|
283
301
|
function read_bin_entry(manifest_path, package_name, bin_name) {
|
|
284
302
|
const { bin } = package_bin_schema.parse(JSON.parse(readFileSync2(manifest_path, "utf8")));
|
|
285
|
-
if (typeof bin === "string") return bin_name ===
|
|
303
|
+
if (typeof bin === "string") return bin_name === path3.basename(package_name) ? bin : void 0;
|
|
286
304
|
return bin?.[bin_name];
|
|
287
305
|
}
|
|
288
306
|
function resolve_package_bin(base_directory, package_name, bin_name) {
|
|
289
307
|
try {
|
|
290
|
-
const resolve_from = createRequire(
|
|
308
|
+
const resolve_from = createRequire(path3.join(base_directory, PACKAGE_JSON));
|
|
291
309
|
const manifest_path = resolve_from.resolve(`${package_name}/${PACKAGE_JSON}`);
|
|
292
310
|
const bin_entry = read_bin_entry(manifest_path, package_name, bin_name);
|
|
293
311
|
if (bin_entry === void 0) return void 0;
|
|
294
|
-
const cli_entry =
|
|
312
|
+
const cli_entry = path3.join(path3.dirname(manifest_path), bin_entry);
|
|
295
313
|
return existsSync2(cli_entry) ? cli_entry : void 0;
|
|
296
314
|
} catch {
|
|
297
315
|
return void 0;
|
|
298
316
|
}
|
|
299
317
|
}
|
|
300
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 availableParallelism2 } 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
|
+
var RESERVED_PREFIX = "josh-core-reserved-";
|
|
716
|
+
var RESERVED_SUFFIX = ".json";
|
|
717
|
+
var POLL_INTERVAL_MS = 50;
|
|
718
|
+
var WAIT_CAP_MS = 12e4;
|
|
719
|
+
var MIN_BUDGET = 1;
|
|
720
|
+
var CORE_WEIGHTS = {
|
|
721
|
+
lint: 2,
|
|
722
|
+
type_check: 1,
|
|
723
|
+
spell_check: 1,
|
|
724
|
+
eslint_scan: 1
|
|
725
|
+
};
|
|
726
|
+
var HELD_KEY = "JOSH_CORE_RESERVED";
|
|
727
|
+
var HELD_VALUE = "1";
|
|
728
|
+
var reservation_schema = process_owner_schema.extend({
|
|
729
|
+
weight: z4.number(),
|
|
730
|
+
claimed_at: z4.number()
|
|
731
|
+
});
|
|
732
|
+
function marker_name(key) {
|
|
733
|
+
return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`;
|
|
734
|
+
}
|
|
735
|
+
function is_running2(reservation) {
|
|
736
|
+
return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false;
|
|
737
|
+
}
|
|
738
|
+
function read_reservation(source) {
|
|
739
|
+
const raw = stamp_file.read_stamp_text(source);
|
|
740
|
+
if (raw === void 0) return void 0;
|
|
741
|
+
try {
|
|
742
|
+
const parsed = reservation_schema.safeParse(JSON.parse(raw));
|
|
743
|
+
return parsed.success ? parsed.data : void 0;
|
|
744
|
+
} catch {
|
|
745
|
+
return void 0;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
function sweep_marker2(source) {
|
|
749
|
+
try {
|
|
750
|
+
stamp_file.remove_stamp(source);
|
|
751
|
+
} catch {
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
function live_reservation(source) {
|
|
755
|
+
const reservation = read_reservation(source);
|
|
756
|
+
if (reservation === void 0) return void 0;
|
|
757
|
+
if (is_running2(reservation)) return reservation;
|
|
758
|
+
sweep_marker2(source);
|
|
759
|
+
return void 0;
|
|
760
|
+
}
|
|
761
|
+
function marker_files2(directory) {
|
|
762
|
+
try {
|
|
763
|
+
return readdirSync2(directory).filter((name) => name.startsWith(RESERVED_PREFIX));
|
|
764
|
+
} catch {
|
|
765
|
+
return [];
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
function live_reservations(directory = PLATFORM_TEMP_ROOT) {
|
|
769
|
+
return marker_files2(directory).flatMap((name) => {
|
|
770
|
+
const reservation = live_reservation(path8.join(directory, name));
|
|
771
|
+
return reservation === void 0 ? [] : { key: name, reservation };
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
function compare_claim(left, right) {
|
|
775
|
+
const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
|
|
776
|
+
return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
|
|
777
|
+
}
|
|
778
|
+
function admitted_keys(reservations, budget) {
|
|
779
|
+
const admitted = /* @__PURE__ */ new Set();
|
|
780
|
+
let cumulative = 0;
|
|
781
|
+
for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
|
|
782
|
+
cumulative += entry.reservation.weight;
|
|
783
|
+
if (index !== 0 && cumulative > budget) break;
|
|
784
|
+
admitted.add(entry.key);
|
|
785
|
+
}
|
|
786
|
+
return admitted;
|
|
787
|
+
}
|
|
788
|
+
function is_admitted(key, reservations, budget) {
|
|
789
|
+
return admitted_keys(reservations, budget).has(key);
|
|
790
|
+
}
|
|
791
|
+
function admitted_load(reservations, budget) {
|
|
792
|
+
const admitted = admitted_keys(reservations, budget);
|
|
793
|
+
return reservations.filter((entry) => admitted.has(entry.key)).reduce((total, entry) => total + entry.reservation.weight, 0);
|
|
794
|
+
}
|
|
795
|
+
function normalize_budget(budget) {
|
|
796
|
+
return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET;
|
|
797
|
+
}
|
|
798
|
+
async function default_sleep(ms) {
|
|
799
|
+
await new Promise((resolve) => {
|
|
800
|
+
setTimeout(resolve, ms);
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
function write_reservation(target, weight, claimed_at) {
|
|
804
|
+
stamp_file.write_stamp(target, { ...process_identity.own_fields(), weight, claimed_at });
|
|
805
|
+
}
|
|
806
|
+
function resolve_timing(options) {
|
|
807
|
+
return {
|
|
808
|
+
now: options.now ?? Date.now,
|
|
809
|
+
sleep: options.sleep ?? default_sleep,
|
|
810
|
+
poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
async function await_admission(context) {
|
|
814
|
+
while (!is_admitted(context.key, live_reservations(context.directory), context.budget)) {
|
|
815
|
+
if (context.now() >= context.deadline) return;
|
|
816
|
+
await context.sleep(context.poll_interval_ms);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
async function reserve(weight, options = {}) {
|
|
820
|
+
const timing = resolve_timing(options);
|
|
821
|
+
const directory = options.directory ?? PLATFORM_TEMP_ROOT;
|
|
822
|
+
const budget = normalize_budget(options.budget ?? availableParallelism2());
|
|
823
|
+
const claimed_at = timing.now();
|
|
824
|
+
const name = marker_name(randomUUID3());
|
|
825
|
+
const target = path8.join(directory, name);
|
|
826
|
+
write_reservation(target, weight, claimed_at);
|
|
827
|
+
await await_admission({
|
|
828
|
+
...timing,
|
|
829
|
+
key: name,
|
|
830
|
+
directory,
|
|
831
|
+
budget,
|
|
832
|
+
deadline: claimed_at + (options.wait_cap_ms ?? WAIT_CAP_MS)
|
|
833
|
+
});
|
|
834
|
+
return { target };
|
|
835
|
+
}
|
|
836
|
+
function release(handle) {
|
|
837
|
+
sweep_marker2(handle.target);
|
|
838
|
+
}
|
|
839
|
+
async function with_core_reservation(weight, run2, options = {}) {
|
|
840
|
+
const handle = await reserve(weight, options);
|
|
841
|
+
try {
|
|
842
|
+
return await run2();
|
|
843
|
+
} finally {
|
|
844
|
+
release(handle);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
function is_held() {
|
|
848
|
+
return process.env[HELD_KEY] === HELD_VALUE;
|
|
849
|
+
}
|
|
850
|
+
function set_held_mark(value) {
|
|
851
|
+
process.env[HELD_KEY] = value;
|
|
852
|
+
}
|
|
853
|
+
async function with_held_mark(run2) {
|
|
854
|
+
const previous = process.env[HELD_KEY] ?? "";
|
|
855
|
+
set_held_mark(HELD_VALUE);
|
|
856
|
+
try {
|
|
857
|
+
return await run2();
|
|
858
|
+
} finally {
|
|
859
|
+
set_held_mark(previous);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
async function with_command_reservation(weight, run2, options = {}) {
|
|
863
|
+
if (is_held() || unit_worker_share.is_nested_run()) return await run2();
|
|
864
|
+
return await with_core_reservation(weight, async () => await with_held_mark(run2), options);
|
|
865
|
+
}
|
|
866
|
+
var core_budget = {
|
|
867
|
+
CORE_WEIGHTS,
|
|
868
|
+
HELD_KEY,
|
|
869
|
+
HELD_VALUE,
|
|
870
|
+
RESERVED_PREFIX,
|
|
871
|
+
admitted_keys,
|
|
872
|
+
admitted_load,
|
|
873
|
+
is_held,
|
|
874
|
+
live_reservations,
|
|
875
|
+
release,
|
|
876
|
+
reserve,
|
|
877
|
+
with_command_reservation,
|
|
878
|
+
with_core_reservation,
|
|
879
|
+
with_held_mark
|
|
880
|
+
};
|
|
881
|
+
|
|
301
882
|
// scripts/josh/josh-logic.ts
|
|
302
883
|
import { execaSync as execaSync2 } from "execa";
|
|
303
884
|
|
|
@@ -407,6 +988,9 @@ var BACKLOG_COMMANDS = {
|
|
|
407
988
|
},
|
|
408
989
|
"backlog:stalled": {
|
|
409
990
|
script: "scripts/backlog/backlog-stalled-cli.ts",
|
|
991
|
+
// A stall sends one Telegram warning (joshuafolkken/kit#3357). The `Stop` hook calls the detector
|
|
992
|
+
// directly, so this flag costs only the manual command its in-process dispatch.
|
|
993
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
410
994
|
description: "Report whether ready backlog work is sitting undispatched with a free lane and no recent dispatch",
|
|
411
995
|
category: "AI tools",
|
|
412
996
|
reference: ["", "automation", ["network"]]
|
|
@@ -425,7 +1009,8 @@ var DOCUMENT_COMMANDS = {
|
|
|
425
1009
|
script: "scripts/document/document-section-cli.ts",
|
|
426
1010
|
description: 'Print one section of a markdown document, for a `file.md` \u2192 "Heading" reference',
|
|
427
1011
|
category: "AI tools",
|
|
428
|
-
reference: ["<file> <heading>", "automation", ["none"]]
|
|
1012
|
+
reference: ["<file> <heading>", "automation", ["none"]],
|
|
1013
|
+
is_bundled: true
|
|
429
1014
|
},
|
|
430
1015
|
"read:set": {
|
|
431
1016
|
script: "scripts/document/read-set-cli.ts",
|
|
@@ -542,6 +1127,10 @@ var ISSUE_COMMANDS = {
|
|
|
542
1127
|
var LANE_SCRIPT = "scripts/lane/lane-cli.ts";
|
|
543
1128
|
var LANE_ARGUMENTS = { script: LANE_SCRIPT, tsx_arguments: OPTIONAL_ENV_FILE_FLAGS };
|
|
544
1129
|
var ISSUE_WITH_OPTIONS = "<issue> [options]";
|
|
1130
|
+
var MEASURE_ARGUMENTS = {
|
|
1131
|
+
script: "scripts/lane/lane-measure-cli.ts",
|
|
1132
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
|
|
1133
|
+
};
|
|
545
1134
|
var LANE_COMMANDS = {
|
|
546
1135
|
"lane:open": {
|
|
547
1136
|
...LANE_ARGUMENTS,
|
|
@@ -597,11 +1186,27 @@ var LANE_COMMANDS = {
|
|
|
597
1186
|
description: "Collapse a backlogrun lane-start event into one call: open the lane, pop and re-install on the first, dispatch the child",
|
|
598
1187
|
category: "AI tools",
|
|
599
1188
|
reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
|
|
1189
|
+
},
|
|
1190
|
+
// The lane-limit measurement (joshuafolkken/kit#3355): `.env` is read so `lane:stats` labels the row
|
|
1191
|
+
// with the `JOSH_LANE_LIMIT` a person set there.
|
|
1192
|
+
"lane:sample": {
|
|
1193
|
+
...MEASURE_ARGUMENTS,
|
|
1194
|
+
description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger",
|
|
1195
|
+
category: "AI tools",
|
|
1196
|
+
reference: ["[--every <seconds>]", "maintainer", ["files"]],
|
|
1197
|
+
default_script_arguments: ["sample"]
|
|
1198
|
+
},
|
|
1199
|
+
"lane:stats": {
|
|
1200
|
+
...MEASURE_ARGUMENTS,
|
|
1201
|
+
description: "Print one table row of lane throughput, gate duration and machine load over a period",
|
|
1202
|
+
category: "AI tools",
|
|
1203
|
+
reference: ["--period <days> [--limit <lane-limit>]", "maintainer", ["none"]],
|
|
1204
|
+
default_script_arguments: ["stats"]
|
|
600
1205
|
}
|
|
601
1206
|
};
|
|
602
1207
|
|
|
603
1208
|
// scripts/josh/josh-commands-run.ts
|
|
604
|
-
var RUN_HOLD_SCRIPT = "scripts/run/run-hold-cli.ts";
|
|
1209
|
+
var RUN_HOLD_SCRIPT = "scripts/run/hold/run-hold-cli.ts";
|
|
605
1210
|
var RUN_COMMANDS = {
|
|
606
1211
|
"run:hold": {
|
|
607
1212
|
script: RUN_HOLD_SCRIPT,
|
|
@@ -617,19 +1222,22 @@ var RUN_COMMANDS = {
|
|
|
617
1222
|
default_script_arguments: ["--release"]
|
|
618
1223
|
},
|
|
619
1224
|
"run:tidy": {
|
|
620
|
-
script: "scripts/run/run-tidy-cli.ts",
|
|
1225
|
+
script: "scripts/run/tidy/run-tidy-cli.ts",
|
|
621
1226
|
description: "Close merged lanes and drop stashes whose issues are all merged",
|
|
622
1227
|
category: "AI tools",
|
|
623
1228
|
reference: ["", "automation", ["git", "network", "files"]]
|
|
624
1229
|
},
|
|
625
1230
|
"run:carry": {
|
|
626
|
-
script: "scripts/run/run-carry-cli.ts",
|
|
1231
|
+
script: "scripts/run/carry/run-carry-cli.ts",
|
|
1232
|
+
// `--stopped` sends the stop confirmation, so the Telegram credentials come from `.env` as for
|
|
1233
|
+
// `run:wake` below (joshuafolkken/kit#3357).
|
|
1234
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
627
1235
|
description: "Carry one invocation\u2019s budget across its own session cuts",
|
|
628
1236
|
category: "AI tools",
|
|
629
1237
|
reference: ["<operation> [arguments...]", "automation", ["files"]]
|
|
630
1238
|
},
|
|
631
1239
|
"run:wake": {
|
|
632
|
-
script: "scripts/run/run-wake-cli.ts",
|
|
1240
|
+
script: "scripts/run/wake/run-wake-cli.ts",
|
|
633
1241
|
// `.env` rather than the ambient environment:
|
|
634
1242
|
// the failure warning needs the Telegram credentials, the same
|
|
635
1243
|
// reasons `notify` and `followup` carry these flags.
|
|
@@ -639,7 +1247,7 @@ var RUN_COMMANDS = {
|
|
|
639
1247
|
reference: ["[options]", "automation", ["processes", "notifications"]]
|
|
640
1248
|
},
|
|
641
1249
|
"run:cut": {
|
|
642
|
-
script: "scripts/run/run-cut-cli.ts",
|
|
1250
|
+
script: "scripts/run/cut/run-cut-cli.ts",
|
|
643
1251
|
description: "Cut a lane child before the gate and resume a fresh process",
|
|
644
1252
|
category: "AI tools",
|
|
645
1253
|
reference: ["[--resume] <issue> [--impl] [--handoff <path>]", "automation", ["files"]]
|
|
@@ -657,7 +1265,7 @@ var RUN_COMMANDS = {
|
|
|
657
1265
|
reference: ["<issue> --output <path> [--repo <owner/repo>]", "automation", ["network"]]
|
|
658
1266
|
},
|
|
659
1267
|
"run:progress": {
|
|
660
|
-
script: "scripts/run/run-progress-cli.ts",
|
|
1268
|
+
script: "scripts/run/progress/run-progress-cli.ts",
|
|
661
1269
|
description: "Report an unattended run\u2019s progress once it has gone quiet for an interval",
|
|
662
1270
|
category: "AI tools",
|
|
663
1271
|
reference: [
|
|
@@ -676,7 +1284,9 @@ var RUN_COMMANDS = {
|
|
|
676
1284
|
// read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
|
|
677
1285
|
// `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
|
|
678
1286
|
"run:entry": {
|
|
679
|
-
script: "scripts/run/run-entry-cli.ts",
|
|
1287
|
+
script: "scripts/run/entry/run-entry-cli.ts",
|
|
1288
|
+
// A `busy` hold or an `over` budget sends the stop confirmation (joshuafolkken/kit#3357).
|
|
1289
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
680
1290
|
description: "Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step",
|
|
681
1291
|
category: "AI tools",
|
|
682
1292
|
reference: ["<issue> [--to <command>]", "automation", ["git", "network", "files"]]
|
|
@@ -840,13 +1450,13 @@ var AI_COMMANDS = {
|
|
|
840
1450
|
reference: ["[<owner/repo>]", "automation", ["none"]]
|
|
841
1451
|
},
|
|
842
1452
|
"run:merge": {
|
|
843
|
-
script: "scripts/run/run-merge-cli.ts",
|
|
1453
|
+
script: "scripts/run/merge/run-merge-cli.ts",
|
|
844
1454
|
description: "Collapse a backlogrun merge event into one call: confirm the child, do the post-merge steps, offer the next child",
|
|
845
1455
|
category: "AI tools",
|
|
846
1456
|
reference: [ISSUE_WITH_OPTIONS2, "automation", ["git", "network"]]
|
|
847
1457
|
},
|
|
848
1458
|
"run:review": {
|
|
849
|
-
script: "scripts/run/run-review-cli.ts",
|
|
1459
|
+
script: "scripts/run/review/run-review-cli.ts",
|
|
850
1460
|
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)",
|
|
851
1461
|
category: "AI tools",
|
|
852
1462
|
reference: ["[--join]", "automation", ["processes", "files"]]
|
|
@@ -865,7 +1475,7 @@ var AI_COMMANDS = {
|
|
|
865
1475
|
// (`run:tail`) were four round trips re-billing the run's full context each. It stops at the first
|
|
866
1476
|
// failed step and names it, so the run reads only the step to fix.
|
|
867
1477
|
ship: {
|
|
868
|
-
script: "scripts/run/run-ship-cli.ts",
|
|
1478
|
+
script: "scripts/run/ship/run-ship-cli.ts",
|
|
869
1479
|
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",
|
|
870
1480
|
category: "AI tools",
|
|
871
1481
|
reference: [
|
|
@@ -875,7 +1485,7 @@ var AI_COMMANDS = {
|
|
|
875
1485
|
]
|
|
876
1486
|
},
|
|
877
1487
|
"run:event": {
|
|
878
|
-
script: "scripts/run/run-event-cli.ts",
|
|
1488
|
+
script: "scripts/run/event/run-event-cli.ts",
|
|
879
1489
|
description: "Append to, read or watch the run\u2019s append-only event stream (--append <kind> <text> | --from|--follow <n> | --watch [<n>] | --last)",
|
|
880
1490
|
category: "AI tools",
|
|
881
1491
|
reference: [
|
|
@@ -935,6 +1545,169 @@ var CLONE_COMMANDS = {
|
|
|
935
1545
|
}
|
|
936
1546
|
};
|
|
937
1547
|
|
|
1548
|
+
// scripts/gate/gate-plan.ts
|
|
1549
|
+
import { availableParallelism as availableParallelism3 } from "node:os";
|
|
1550
|
+
|
|
1551
|
+
// scripts/lib/status-icons.ts
|
|
1552
|
+
var FAIL_ICON = "\u2717";
|
|
1553
|
+
var PASS_ICON = "\u2714";
|
|
1554
|
+
var status_icons = { FAIL_ICON, PASS_ICON };
|
|
1555
|
+
|
|
1556
|
+
// scripts/josh/josh-verdict.ts
|
|
1557
|
+
var { FAIL_ICON: FAIL_ICON2, PASS_ICON: PASS_ICON2 } = status_icons;
|
|
1558
|
+
var GATE_SUBJECT = "verification gate";
|
|
1559
|
+
var GATE_PASSED_PREFIX = `${PASS_ICON2} ${GATE_SUBJECT} passed`;
|
|
1560
|
+
var GATE_FAILED_PREFIX = `${FAIL_ICON2} ${GATE_SUBJECT} failed`;
|
|
1561
|
+
var PASSED_VERDICT = "passed";
|
|
1562
|
+
var FAILED_VERDICT = "failed";
|
|
1563
|
+
function format_gate_passed(step_count, total) {
|
|
1564
|
+
return `${GATE_PASSED_PREFIX} (${step_count} checks) in ${total}.`;
|
|
1565
|
+
}
|
|
1566
|
+
function format_gate_failed(failed_labels, total) {
|
|
1567
|
+
return `${GATE_FAILED_PREFIX}: ${failed_labels} (${total})`;
|
|
1568
|
+
}
|
|
1569
|
+
var GATE_OPENING_PREFIX = "plan: ";
|
|
1570
|
+
var GATE_OPENING_MARK = " checks at once";
|
|
1571
|
+
function is_gate_opening(line) {
|
|
1572
|
+
const trimmed = line.trimStart();
|
|
1573
|
+
return trimmed.startsWith(GATE_OPENING_PREFIX) && trimmed.includes(GATE_OPENING_MARK);
|
|
1574
|
+
}
|
|
1575
|
+
function read_verdict(line) {
|
|
1576
|
+
const trimmed = line.trimStart();
|
|
1577
|
+
if (trimmed.startsWith(GATE_FAILED_PREFIX)) return FAILED_VERDICT;
|
|
1578
|
+
if (trimmed.startsWith(GATE_PASSED_PREFIX)) return PASSED_VERDICT;
|
|
1579
|
+
return void 0;
|
|
1580
|
+
}
|
|
1581
|
+
var josh_verdict = {
|
|
1582
|
+
PASSED_VERDICT,
|
|
1583
|
+
FAILED_VERDICT,
|
|
1584
|
+
format_gate_passed,
|
|
1585
|
+
format_gate_failed,
|
|
1586
|
+
GATE_OPENING_MARK,
|
|
1587
|
+
GATE_OPENING_PREFIX,
|
|
1588
|
+
is_gate_opening,
|
|
1589
|
+
read_verdict
|
|
1590
|
+
};
|
|
1591
|
+
|
|
1592
|
+
// scripts/gate/gate-plan.ts
|
|
1593
|
+
var LINT_LABEL = "lint";
|
|
1594
|
+
var TYPE_CHECK_LABEL = "check";
|
|
1595
|
+
var UNIT_LABEL = "test:unit";
|
|
1596
|
+
var BEHAVIOR_LABEL = "behavior";
|
|
1597
|
+
var WARNING_CHECKER_LABELS = [LINT_LABEL, TYPE_CHECK_LABEL];
|
|
1598
|
+
var STATIC_CHECKS = [
|
|
1599
|
+
{ label: LINT_LABEL, target: "lint", reserved_cores: core_budget.CORE_WEIGHTS.lint },
|
|
1600
|
+
{
|
|
1601
|
+
label: TYPE_CHECK_LABEL,
|
|
1602
|
+
target: "check",
|
|
1603
|
+
reserved_cores: core_budget.CORE_WEIGHTS.type_check
|
|
1604
|
+
},
|
|
1605
|
+
{ label: "cspell", target: "cspell:dot", reserved_cores: core_budget.CORE_WEIGHTS.spell_check },
|
|
1606
|
+
{ label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
|
|
1607
|
+
// **The unused-member check reserves no core** (joshuafolkken/kit#2987): it builds one TypeScript
|
|
1608
|
+
// program and walks it for about 5s, and it is over well before lint and the type check. A
|
|
1609
|
+
// reservation would only take a place from the four-core CI runner's fan-out and a worker from the
|
|
1610
|
+
// unit suite for the whole gate.
|
|
1611
|
+
{ label: "exports", target: "exports:unused", reserved_cores: 0 }
|
|
1612
|
+
];
|
|
1613
|
+
var GATE_CHECKS = [
|
|
1614
|
+
...STATIC_CHECKS,
|
|
1615
|
+
{ label: UNIT_LABEL, target: UNIT_LABEL, reserved_cores: 0 }
|
|
1616
|
+
];
|
|
1617
|
+
function select_gate_checks(is_unit_included) {
|
|
1618
|
+
return is_unit_included ? GATE_CHECKS : STATIC_CHECKS;
|
|
1619
|
+
}
|
|
1620
|
+
function has_unit_check(checks) {
|
|
1621
|
+
return checks.some((check) => check.label === UNIT_LABEL);
|
|
1622
|
+
}
|
|
1623
|
+
var RESERVED_CORES = STATIC_CHECKS.reduce(
|
|
1624
|
+
(total, check) => total + check.reserved_cores,
|
|
1625
|
+
0
|
|
1626
|
+
);
|
|
1627
|
+
var MEASURED_CORES = 11;
|
|
1628
|
+
var MIN_CONCURRENCY = 1;
|
|
1629
|
+
var MIN_SHARED_CORES = 1;
|
|
1630
|
+
function shared_cores(available_cores, concurrent_runs) {
|
|
1631
|
+
const runs = Number.isFinite(concurrent_runs) ? Math.max(unit_worker_share.SOLO_RUNS, concurrent_runs) : unit_worker_share.SOLO_RUNS;
|
|
1632
|
+
return Math.max(MIN_SHARED_CORES, Math.floor(available_cores / runs));
|
|
1633
|
+
}
|
|
1634
|
+
function resolve_concurrency(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS, checks = GATE_CHECKS) {
|
|
1635
|
+
const share = shared_cores(available_cores, concurrent_runs);
|
|
1636
|
+
let admitted = 0;
|
|
1637
|
+
let reserved = 0;
|
|
1638
|
+
for (const check of checks) {
|
|
1639
|
+
reserved += check.reserved_cores;
|
|
1640
|
+
if (reserved > share) break;
|
|
1641
|
+
admitted += 1;
|
|
1642
|
+
}
|
|
1643
|
+
return Math.max(MIN_CONCURRENCY, admitted);
|
|
1644
|
+
}
|
|
1645
|
+
function resolve_unit_worker_cap(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS) {
|
|
1646
|
+
const share = unit_worker_share.resolve_unit_workers(available_cores, concurrent_runs);
|
|
1647
|
+
if (share !== void 0) return share;
|
|
1648
|
+
if (available_cores < MEASURED_CORES) return void 0;
|
|
1649
|
+
return available_cores - RESERVED_CORES;
|
|
1650
|
+
}
|
|
1651
|
+
function solo_unit_weight(available_cores) {
|
|
1652
|
+
return Math.max(0, available_cores - RESERVED_CORES);
|
|
1653
|
+
}
|
|
1654
|
+
function check_weight(check, plan, available_cores) {
|
|
1655
|
+
if (check.label !== UNIT_LABEL) return check.reserved_cores;
|
|
1656
|
+
return plan.unit_worker_cap ?? solo_unit_weight(available_cores);
|
|
1657
|
+
}
|
|
1658
|
+
function direct_unit_weight(available_cores = availableParallelism3(), live_runs = unit_worker_share.live_run_count()) {
|
|
1659
|
+
const weight = unit_worker_share.current_share(available_cores, live_runs) ?? solo_unit_weight(available_cores);
|
|
1660
|
+
return Math.max(unit_worker_share.MIN_WORKERS, weight);
|
|
1661
|
+
}
|
|
1662
|
+
function plan_of(concurrency, unit_worker_cap, checks = GATE_CHECKS) {
|
|
1663
|
+
return { checks, concurrency, unit_worker_cap };
|
|
1664
|
+
}
|
|
1665
|
+
function resolve_gate_plan(available_cores = availableParallelism3(), concurrent_runs = unit_worker_share.SOLO_RUNS, is_unit_included = true) {
|
|
1666
|
+
const checks = select_gate_checks(is_unit_included);
|
|
1667
|
+
return {
|
|
1668
|
+
checks,
|
|
1669
|
+
concurrency: resolve_concurrency(available_cores, concurrent_runs, checks),
|
|
1670
|
+
unit_worker_cap: is_unit_included ? resolve_unit_worker_cap(available_cores, concurrent_runs) : void 0
|
|
1671
|
+
};
|
|
1672
|
+
}
|
|
1673
|
+
function format_machine(available_cores, concurrent_runs) {
|
|
1674
|
+
const cores = `${String(available_cores)} cores`;
|
|
1675
|
+
if (concurrent_runs <= unit_worker_share.SOLO_RUNS) return cores;
|
|
1676
|
+
return `${cores}, ${String(concurrent_runs)} unit runs`;
|
|
1677
|
+
}
|
|
1678
|
+
function format_unit_cap(plan) {
|
|
1679
|
+
if (!has_unit_check(plan.checks)) return `${UNIT_LABEL} elsewhere`;
|
|
1680
|
+
if (plan.unit_worker_cap === void 0) return `${UNIT_LABEL} unrestricted`;
|
|
1681
|
+
return `${UNIT_LABEL} at ${String(plan.unit_worker_cap)} workers`;
|
|
1682
|
+
}
|
|
1683
|
+
function format_gate_plan(plan, available_cores = availableParallelism3(), concurrent_runs = unit_worker_share.SOLO_RUNS) {
|
|
1684
|
+
const cap = format_unit_cap(plan);
|
|
1685
|
+
const count = `${String(plan.concurrency)} of ${String(plan.checks.length)}`;
|
|
1686
|
+
const width = `${count}${josh_verdict.GATE_OPENING_MARK}`;
|
|
1687
|
+
const machine = format_machine(available_cores, concurrent_runs);
|
|
1688
|
+
return `${josh_verdict.GATE_OPENING_PREFIX}${width}, ${cap} (${machine})`;
|
|
1689
|
+
}
|
|
1690
|
+
var gate_plan = {
|
|
1691
|
+
GATE_CHECKS,
|
|
1692
|
+
LINT_LABEL,
|
|
1693
|
+
MEASURED_CORES,
|
|
1694
|
+
RESERVED_CORES,
|
|
1695
|
+
STATIC_CHECKS,
|
|
1696
|
+
TYPE_CHECK_LABEL,
|
|
1697
|
+
UNIT_LABEL,
|
|
1698
|
+
WARNING_CHECKER_LABELS,
|
|
1699
|
+
check_weight,
|
|
1700
|
+
direct_unit_weight,
|
|
1701
|
+
format_gate_plan,
|
|
1702
|
+
format_machine,
|
|
1703
|
+
has_unit_check,
|
|
1704
|
+
plan_of,
|
|
1705
|
+
resolve_concurrency,
|
|
1706
|
+
resolve_gate_plan,
|
|
1707
|
+
resolve_unit_worker_cap,
|
|
1708
|
+
select_gate_checks
|
|
1709
|
+
};
|
|
1710
|
+
|
|
938
1711
|
// scripts/josh/josh-commands-development.ts
|
|
939
1712
|
var FILE_ARGUMENTS = "[files...]";
|
|
940
1713
|
var REQUIRED_FILE_ARGUMENTS = "<files...>";
|
|
@@ -958,25 +1731,29 @@ var DEV_COMMANDS = {
|
|
|
958
1731
|
script: "scripts/lint/lint-parallel.ts",
|
|
959
1732
|
description: "Check code with prettier and eslint (skips a tool a basic project lacks)",
|
|
960
1733
|
category: "Development",
|
|
961
|
-
reference: ["", "developer", ["processes"]]
|
|
1734
|
+
reference: ["", "developer", ["processes"]],
|
|
1735
|
+
core_weight: core_budget.CORE_WEIGHTS.lint
|
|
962
1736
|
},
|
|
963
1737
|
"lint:related": {
|
|
964
1738
|
script: "scripts/lint/lint-related.ts",
|
|
965
1739
|
description: "Check only the changed files with prettier and eslint (whole tree on fallback)",
|
|
966
1740
|
category: "Development",
|
|
967
|
-
reference: [FILE_ARGUMENTS, "developer", ["processes"]]
|
|
1741
|
+
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
1742
|
+
core_weight: core_budget.CORE_WEIGHTS.lint
|
|
968
1743
|
},
|
|
969
1744
|
lines: {
|
|
970
1745
|
script: "scripts/lines/lines-command.ts",
|
|
971
1746
|
description: "Print a file's code lines against the max-lines limit and the headroom left",
|
|
972
1747
|
category: "Development",
|
|
973
|
-
reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]]
|
|
1748
|
+
reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]],
|
|
1749
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan
|
|
974
1750
|
},
|
|
975
1751
|
"refactor:scan": {
|
|
976
1752
|
script: "scripts/refactor/refactor-scan-cli.ts",
|
|
977
1753
|
description: "List refactoring candidates in the changed scope by category and answer clear/candidates",
|
|
978
1754
|
category: "Development",
|
|
979
|
-
reference: ["", "automation", ["processes"]]
|
|
1755
|
+
reference: ["", "automation", ["processes"]],
|
|
1756
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan
|
|
980
1757
|
},
|
|
981
1758
|
bytes: {
|
|
982
1759
|
script: "scripts/lines/bytes-command.ts",
|
|
@@ -1055,7 +1832,8 @@ var DEV_COMMANDS = {
|
|
|
1055
1832
|
script: "scripts/lint/cspell-cached.ts",
|
|
1056
1833
|
description: "Run spell check including dotfiles",
|
|
1057
1834
|
category: "Development",
|
|
1058
|
-
reference: ["", "developer", ["processes"]]
|
|
1835
|
+
reference: ["", "developer", ["processes"]],
|
|
1836
|
+
core_weight: core_budget.CORE_WEIGHTS.spell_check
|
|
1059
1837
|
},
|
|
1060
1838
|
behavior: {
|
|
1061
1839
|
script: "scripts/behavior/behavior-cli.ts",
|
|
@@ -1073,13 +1851,15 @@ var DEV_COMMANDS = {
|
|
|
1073
1851
|
script: "scripts/test/test-unit-guard.ts",
|
|
1074
1852
|
description: "Run unit tests with Vitest (skips when Vitest is absent; fails when it has no tests)",
|
|
1075
1853
|
category: "Development",
|
|
1076
|
-
reference: [FILTER_ARGUMENTS, "developer", ["processes"]]
|
|
1854
|
+
reference: [FILTER_ARGUMENTS, "developer", ["processes"]],
|
|
1855
|
+
core_weight: gate_plan.direct_unit_weight
|
|
1077
1856
|
},
|
|
1078
1857
|
"test:related": {
|
|
1079
1858
|
script: "scripts/test/test-related.ts",
|
|
1080
1859
|
description: "Run only the unit tests related to the changed files (full suite on fallback)",
|
|
1081
1860
|
category: "Development",
|
|
1082
|
-
reference: [FILE_ARGUMENTS, "developer", ["processes"]]
|
|
1861
|
+
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
1862
|
+
core_weight: gate_plan.direct_unit_weight
|
|
1083
1863
|
},
|
|
1084
1864
|
"test:declared": {
|
|
1085
1865
|
script: "scripts/test/test-declared.ts",
|
|
@@ -1089,7 +1869,7 @@ var DEV_COMMANDS = {
|
|
|
1089
1869
|
},
|
|
1090
1870
|
"test:red": {
|
|
1091
1871
|
script: "scripts/test/test-red.ts",
|
|
1092
|
-
description: "Run the changed unit tests against the pre-fix tree (merge-base worktree) and report red/green/no-test",
|
|
1872
|
+
description: "Run the changed unit tests against the pre-fix tree (merge-base worktree) and report red/green/no-test/test-only",
|
|
1093
1873
|
category: "Development",
|
|
1094
1874
|
reference: ["", "developer", ["git", "processes"]]
|
|
1095
1875
|
},
|
|
@@ -1122,7 +1902,8 @@ var DEV_COMMANDS = {
|
|
|
1122
1902
|
script: "scripts/gate/type-check-command.ts",
|
|
1123
1903
|
description: "Type-check with tsc (skips a basic project with no TypeScript to check)",
|
|
1124
1904
|
category: "Development",
|
|
1125
|
-
reference: ["[arguments...]", "developer", ["processes"]]
|
|
1905
|
+
reference: ["[arguments...]", "developer", ["processes"]],
|
|
1906
|
+
core_weight: core_budget.CORE_WEIGHTS.type_check
|
|
1126
1907
|
},
|
|
1127
1908
|
port: {
|
|
1128
1909
|
script: "scripts/ports/port-command.ts",
|
|
@@ -1219,7 +2000,7 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1219
2000
|
script: "scripts/overrides/overrides-check.ts",
|
|
1220
2001
|
description: "Check pnpm overrides for drift",
|
|
1221
2002
|
category: "Maintenance",
|
|
1222
|
-
reference: ["[--save]", "
|
|
2003
|
+
reference: ["[--save]", "developer", ["files"]]
|
|
1223
2004
|
},
|
|
1224
2005
|
audit: {
|
|
1225
2006
|
script: "scripts/security/security-audit.ts",
|
|
@@ -1247,7 +2028,7 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1247
2028
|
],
|
|
1248
2029
|
description: "Update pnpm, dependencies, and run security audit",
|
|
1249
2030
|
category: "Maintenance",
|
|
1250
|
-
reference: ["", "
|
|
2031
|
+
reference: ["", "developer", ["files", "network", "processes"]],
|
|
1251
2032
|
argument_targets: ["latest:corepack", "latest:update", "audit"]
|
|
1252
2033
|
},
|
|
1253
2034
|
"latest:scope": {
|
|
@@ -1270,13 +2051,13 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1270
2051
|
script: "scripts/version/latest-corepack.ts",
|
|
1271
2052
|
description: "Update pnpm on the current major while preserving the integrity pin",
|
|
1272
2053
|
category: "Maintenance",
|
|
1273
|
-
reference: ["", "
|
|
2054
|
+
reference: ["", "developer", ["files", "network"]]
|
|
1274
2055
|
},
|
|
1275
2056
|
"latest:update": {
|
|
1276
2057
|
script: "scripts/version/latest-update.ts",
|
|
1277
2058
|
description: "Update all dependencies to latest",
|
|
1278
2059
|
category: "Maintenance",
|
|
1279
|
-
reference: ["", "
|
|
2060
|
+
reference: ["", "developer", ["files", "network"]]
|
|
1280
2061
|
}
|
|
1281
2062
|
};
|
|
1282
2063
|
|
|
@@ -1599,7 +2380,9 @@ var ALIASES = {
|
|
|
1599
2380
|
rtr: "retrospective",
|
|
1600
2381
|
rvf: "review:findings",
|
|
1601
2382
|
ruv: "rule:value",
|
|
1602
|
-
ev: "eval"
|
|
2383
|
+
ev: "eval",
|
|
2384
|
+
lsm: "lane:sample",
|
|
2385
|
+
lst: "lane:stats"
|
|
1603
2386
|
};
|
|
1604
2387
|
|
|
1605
2388
|
// scripts/josh/josh-composite-arguments.ts
|
|
@@ -1630,15 +2413,23 @@ var composite_arguments = { format_rejection, is_composite_shell, reject_extra_a
|
|
|
1630
2413
|
|
|
1631
2414
|
// scripts/josh/josh-in-process.ts
|
|
1632
2415
|
import { realpathSync } from "node:fs";
|
|
2416
|
+
import path9 from "node:path";
|
|
1633
2417
|
import { pathToFileURL } from "node:url";
|
|
1634
2418
|
var TYPESCRIPT_EXTENSION = ".ts";
|
|
2419
|
+
var JAVASCRIPT_EXTENSION = ".js";
|
|
2420
|
+
var BUNDLED_COMMAND_DIRECTORY = path9.join("dist", "commands");
|
|
1635
2421
|
var FAILURE_EXIT_CODE = 1;
|
|
1636
2422
|
function is_typescript_dispatcher(dispatcher_url) {
|
|
1637
2423
|
return dispatcher_url.endsWith(TYPESCRIPT_EXTENSION);
|
|
1638
2424
|
}
|
|
1639
|
-
function
|
|
1640
|
-
|
|
1641
|
-
return
|
|
2425
|
+
function bundled_script_path(package_directory, script) {
|
|
2426
|
+
const name = `${path9.basename(script, TYPESCRIPT_EXTENSION)}${JAVASCRIPT_EXTENSION}`;
|
|
2427
|
+
return path9.join(package_directory, BUNDLED_COMMAND_DIRECTORY, name);
|
|
2428
|
+
}
|
|
2429
|
+
function in_process_target(entry, package_directory, dispatcher_url) {
|
|
2430
|
+
if (entry.script === void 0 || entry.tsx_arguments !== void 0) return void 0;
|
|
2431
|
+
if (is_typescript_dispatcher(dispatcher_url)) return path9.join(package_directory, entry.script);
|
|
2432
|
+
return entry.is_bundled === true ? bundled_script_path(package_directory, entry.script) : void 0;
|
|
1642
2433
|
}
|
|
1643
2434
|
function read_exit_code() {
|
|
1644
2435
|
const code = process.exitCode;
|
|
@@ -1662,7 +2453,7 @@ async function run_in_process(script_path, script_arguments) {
|
|
|
1662
2453
|
}
|
|
1663
2454
|
return read_exit_code();
|
|
1664
2455
|
}
|
|
1665
|
-
var josh_in_process = {
|
|
2456
|
+
var josh_in_process = { bundled_script_path, in_process_target, run_in_process };
|
|
1666
2457
|
|
|
1667
2458
|
// scripts/josh/kit-only.ts
|
|
1668
2459
|
function kit_only_notice(cmd) {
|
|
@@ -1682,7 +2473,7 @@ var kit_only = {
|
|
|
1682
2473
|
|
|
1683
2474
|
// scripts/josh/run-github-prerequisite.ts
|
|
1684
2475
|
import { existsSync as existsSync3 } from "node:fs";
|
|
1685
|
-
import
|
|
2476
|
+
import path10 from "node:path";
|
|
1686
2477
|
|
|
1687
2478
|
// scripts/discovery/repo-origin.ts
|
|
1688
2479
|
var GITHUB_HOST = "github.com";
|
|
@@ -1747,15 +2538,15 @@ function origin_section_lines(lines) {
|
|
|
1747
2538
|
const end = rest.findIndex((line) => is_section_header(line));
|
|
1748
2539
|
return end === NOT_FOUND ? rest : rest.slice(0, end);
|
|
1749
2540
|
}
|
|
1750
|
-
function
|
|
2541
|
+
function url_value(line) {
|
|
1751
2542
|
const separator = line.indexOf("=");
|
|
1752
2543
|
if (separator === NOT_FOUND) return void 0;
|
|
1753
|
-
if (line.slice(0, separator).trim() !==
|
|
2544
|
+
if (line.slice(0, separator).trim() !== URL_KEY) return void 0;
|
|
1754
2545
|
return line.slice(separator + 1).trim();
|
|
1755
2546
|
}
|
|
1756
2547
|
function parse_origin_from_config(content) {
|
|
1757
2548
|
const lines = content.split("\n").map((line) => line.trim());
|
|
1758
|
-
return origin_section_lines(lines).map((line) =>
|
|
2549
|
+
return origin_section_lines(lines).map((line) => url_value(line)).find((url) => url !== void 0);
|
|
1759
2550
|
}
|
|
1760
2551
|
function section_groups(lines) {
|
|
1761
2552
|
const groups = [];
|
|
@@ -1767,7 +2558,7 @@ function section_groups(lines) {
|
|
|
1767
2558
|
}
|
|
1768
2559
|
function parse_remote_urls_from_config(content) {
|
|
1769
2560
|
const lines = content.split("\n").map((line) => line.trim());
|
|
1770
|
-
return section_groups(lines).filter((group) => REMOTE_SECTION.test(group[0] ?? "")).flatMap((group) => group.map((line) =>
|
|
2561
|
+
return section_groups(lines).filter((group) => REMOTE_SECTION.test(group[0] ?? "")).flatMap((group) => group.map((line) => url_value(line))).filter((url) => url !== void 0);
|
|
1771
2562
|
}
|
|
1772
2563
|
function format_identity(identity) {
|
|
1773
2564
|
return `${identity.owner}${PATH_SEPARATOR2}${identity.repo}`.toLowerCase();
|
|
@@ -1793,7 +2584,7 @@ var GITHUB_RUN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
1793
2584
|
]);
|
|
1794
2585
|
function explanation(root, command) {
|
|
1795
2586
|
if (!GITHUB_RUN_COMMANDS.has(command)) return void 0;
|
|
1796
|
-
if (!existsSync3(
|
|
2587
|
+
if (!existsSync3(path10.join(root, ".git"))) {
|
|
1797
2588
|
return `${command} requires Git and a GitHub origin. Run git init and add a GitHub origin first.`;
|
|
1798
2589
|
}
|
|
1799
2590
|
const url = git_spawn_sync.origin_url(root);
|
|
@@ -1810,24 +2601,21 @@ var TSX_PACKAGE = "tsx";
|
|
|
1810
2601
|
var PACKAGE_JSON2 = "package.json";
|
|
1811
2602
|
var UNKNOWN_COMMAND_EXIT_CODE = -1;
|
|
1812
2603
|
function find_package_directory(start_directory) {
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
current = parent;
|
|
1818
|
-
}
|
|
1819
|
-
return current;
|
|
2604
|
+
return ancestor_directories.nearest(
|
|
2605
|
+
start_directory,
|
|
2606
|
+
(directory) => existsSync4(path11.join(directory, PACKAGE_JSON2))
|
|
2607
|
+
) ?? start_directory;
|
|
1820
2608
|
}
|
|
1821
|
-
var
|
|
2609
|
+
var PACKAGE_DIR2 = find_package_directory(path11.dirname(fileURLToPath2(import.meta.url)));
|
|
1822
2610
|
function resolve_tsx_executable() {
|
|
1823
2611
|
const candidates = [
|
|
1824
|
-
resolve_local_bin(
|
|
2612
|
+
resolve_local_bin(PACKAGE_DIR2, TSX_BIN),
|
|
1825
2613
|
resolve_local_bin(process.cwd(), TSX_BIN)
|
|
1826
2614
|
];
|
|
1827
2615
|
return candidates.find(existsSync4) ?? TSX_BIN;
|
|
1828
2616
|
}
|
|
1829
2617
|
function resolve_tsx_cli_entry() {
|
|
1830
|
-
for (const base_directory of [
|
|
2618
|
+
for (const base_directory of [PACKAGE_DIR2, process.cwd()]) {
|
|
1831
2619
|
const cli_entry = resolve_package_bin(base_directory, TSX_PACKAGE, TSX_BIN);
|
|
1832
2620
|
if (cli_entry !== void 0) return cli_entry;
|
|
1833
2621
|
}
|
|
@@ -1841,7 +2629,7 @@ function resolve_tsx_runner() {
|
|
|
1841
2629
|
return { executable: resolve_tsx_executable(), leading_arguments: [] };
|
|
1842
2630
|
}
|
|
1843
2631
|
function read_package_version() {
|
|
1844
|
-
const raw =
|
|
2632
|
+
const raw = readFileSync5(path11.join(PACKAGE_DIR2, PACKAGE_JSON2), "utf8");
|
|
1845
2633
|
return package_version_schema.parse(JSON.parse(raw)).version;
|
|
1846
2634
|
}
|
|
1847
2635
|
var HEADER = `josh v${read_package_version()} \u2014 Joshua Folkken's dev toolkit`;
|
|
@@ -1925,12 +2713,10 @@ function spawn_script_entry(entry, script_path, script_arguments) {
|
|
|
1925
2713
|
]);
|
|
1926
2714
|
}
|
|
1927
2715
|
async function run_script_entry(entry, subcommand_arguments) {
|
|
1928
|
-
const script_path = path4.join(PACKAGE_DIR, entry.script ?? "");
|
|
1929
2716
|
const script_arguments = [...entry.default_script_arguments ?? [], ...subcommand_arguments];
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
return spawn_script_entry(entry, script_path, script_arguments);
|
|
2717
|
+
const target = josh_in_process.in_process_target(entry, PACKAGE_DIR2, import.meta.url);
|
|
2718
|
+
if (target !== void 0) return await josh_in_process.run_in_process(target, script_arguments);
|
|
2719
|
+
return spawn_script_entry(entry, path11.join(PACKAGE_DIR2, entry.script ?? ""), script_arguments);
|
|
1934
2720
|
}
|
|
1935
2721
|
function github_prerequisite_exit(resolved, is_consumer) {
|
|
1936
2722
|
if (!is_consumer) return void 0;
|
|
@@ -1955,10 +2741,21 @@ function pre_dispatch_exit(resolved, entry, subcommand_arguments, is_consumer) {
|
|
|
1955
2741
|
console.error(rejection);
|
|
1956
2742
|
return USAGE_ERROR_EXIT_CODE;
|
|
1957
2743
|
}
|
|
1958
|
-
async function
|
|
2744
|
+
async function run_entry(entry, subcommand_arguments) {
|
|
1959
2745
|
if (entry.shell) return run_shell_command(entry.shell, subcommand_arguments);
|
|
1960
2746
|
return await run_script_entry(entry, subcommand_arguments);
|
|
1961
2747
|
}
|
|
2748
|
+
function command_weight(entry) {
|
|
2749
|
+
return typeof entry.core_weight === "function" ? entry.core_weight() : entry.core_weight;
|
|
2750
|
+
}
|
|
2751
|
+
async function dispatch_entry(entry, subcommand_arguments) {
|
|
2752
|
+
const weight = command_weight(entry);
|
|
2753
|
+
if (weight === void 0) return await run_entry(entry, subcommand_arguments);
|
|
2754
|
+
return await core_budget.with_command_reservation(
|
|
2755
|
+
weight,
|
|
2756
|
+
async () => await run_entry(entry, subcommand_arguments)
|
|
2757
|
+
);
|
|
2758
|
+
}
|
|
1962
2759
|
async function run_command(cmd, subcommand_arguments, is_consumer = false) {
|
|
1963
2760
|
const resolved = resolve_alias(cmd);
|
|
1964
2761
|
const entry = Object.hasOwn(COMMAND_MAP, resolved) ? COMMAND_MAP[resolved] : void 0;
|