@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
|
+
import { ancestor_directories } from '#scripts/lib/ancestor-directories'
|
|
3
4
|
import { z } from 'zod'
|
|
4
5
|
import { run_progress } from './run-progress'
|
|
5
6
|
|
|
@@ -28,10 +29,6 @@ import { run_progress } from './run-progress'
|
|
|
28
29
|
|
|
29
30
|
const PACKAGE_FILE = 'package.json'
|
|
30
31
|
|
|
31
|
-
// Deep enough to cross a workspace package and its root, and bounded so a path that never reaches a
|
|
32
|
-
// root — a broken mount, a mocked `dirname` — cannot spin.
|
|
33
|
-
const MAX_DEPTH = 10
|
|
34
|
-
|
|
35
32
|
// Unknown keys are stripped rather than rejected: this reads a whole `package.json`, and every other
|
|
36
33
|
// field in it is none of this module's business. A present-but-unusable interval fails the parse and
|
|
37
34
|
// falls through, which is the same answer an unusable environment variable already gets.
|
|
@@ -39,18 +36,6 @@ const package_schema = z.object({
|
|
|
39
36
|
josh: z.object({ progress_interval_minutes: z.number().positive() }).optional(),
|
|
40
37
|
})
|
|
41
38
|
|
|
42
|
-
function ancestors_of(start: string): ReadonlyArray<string> {
|
|
43
|
-
const directories: Array<string> = []
|
|
44
|
-
let current = path.resolve(start)
|
|
45
|
-
|
|
46
|
-
while (directories.length < MAX_DEPTH && !directories.includes(current)) {
|
|
47
|
-
directories.push(current)
|
|
48
|
-
current = path.dirname(current)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return directories
|
|
52
|
-
}
|
|
53
|
-
|
|
54
39
|
function read_declared_minutes(directory: string): number | undefined {
|
|
55
40
|
try {
|
|
56
41
|
const raw = readFileSync(path.join(directory, PACKAGE_FILE), 'utf8')
|
|
@@ -63,7 +48,7 @@ function read_declared_minutes(directory: string): number | undefined {
|
|
|
63
48
|
}
|
|
64
49
|
|
|
65
50
|
function read_package_minutes(start: string): number | undefined {
|
|
66
|
-
for (const directory of
|
|
51
|
+
for (const directory of ancestor_directories.list(start)) {
|
|
67
52
|
const minutes = read_declared_minutes(directory)
|
|
68
53
|
|
|
69
54
|
if (minutes !== undefined) return minutes
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { loadavg } from 'node:os'
|
|
2
2
|
import { epic_busy } from '#scripts/epic/epic-busy'
|
|
3
3
|
import { git_command } from '#scripts/git/git-command'
|
|
4
|
-
import type { OpenIssueData } from '#scripts/git/schemas'
|
|
4
|
+
import type { OpenIssueData } from '#scripts/git/git-schemas'
|
|
5
5
|
import { lane_registry } from '#scripts/lane/lane-registry'
|
|
6
6
|
import { lane_report } from '#scripts/lane/lane-report'
|
|
7
|
-
import { run_carry, type CarryRead } from '
|
|
8
|
-
import { run_hold, type HoldRead } from '
|
|
9
|
-
import { run_liveness } from '
|
|
10
|
-
import { run_preflight } from '
|
|
7
|
+
import { run_carry, type CarryRead } from '#scripts/run/carry/run-carry'
|
|
8
|
+
import { run_hold, type HoldRead } from '#scripts/run/hold/run-hold'
|
|
9
|
+
import { run_liveness } from '#scripts/run/run-liveness'
|
|
10
|
+
import { run_preflight } from '#scripts/run/run-preflight'
|
|
11
11
|
import type { ChildObservation, LaneObservation, Observations } from './run-progress'
|
|
12
12
|
import { run_progress_clock } from './run-progress-clock'
|
|
13
13
|
|
|
@@ -257,7 +257,7 @@ interface LineTiming {
|
|
|
257
257
|
* this is that same move for one value.
|
|
258
258
|
*
|
|
259
259
|
* **It is a schedule rather than an observation, and the two conditions on it are said in prose**
|
|
260
|
-
* (`docs/josh-commands-
|
|
260
|
+
* (`docs/josh-commands-run.md` → `josh run:progress`): it holds only while the silence continues, and a
|
|
261
261
|
* real report arriving first restarts the clock through `--mark` and supersedes it. The line printing
|
|
262
262
|
* it is itself a report, so the clock starts at this observation.
|
|
263
263
|
*/
|
|
@@ -8,7 +8,7 @@ import { GATE_COMMAND } from '#scripts/josh/josh-command-types'
|
|
|
8
8
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
9
9
|
import { review_stamps } from '#scripts/review/review-stamps'
|
|
10
10
|
import { review_tree } from '#scripts/review/review-tree'
|
|
11
|
-
import { detached_launch, type LaunchArgv, type LaunchResult } from '
|
|
11
|
+
import { detached_launch, type LaunchArgv, type LaunchResult } from '#scripts/run/detached-launch'
|
|
12
12
|
import { run_review, type GateState, type ReviewTiming, type TimingStart } from './run-review'
|
|
13
13
|
|
|
14
14
|
// The side effects `josh run:review` performs, kept out of `run-review.ts` the way `run-merge-steps.ts`
|
|
@@ -114,8 +114,7 @@ function write_timing_start(start: TimingStart, target: string = PROJECT_ROOT):
|
|
|
114
114
|
function to_timing(value: unknown): TimingStart | undefined {
|
|
115
115
|
if (typeof value !== 'object' || value === null) return undefined
|
|
116
116
|
|
|
117
|
-
const
|
|
118
|
-
const { gate_started_at, review_started_at } = record
|
|
117
|
+
const { gate_started_at, review_started_at } = value as Record<string, unknown>
|
|
119
118
|
|
|
120
119
|
if (typeof gate_started_at !== 'string' || typeof review_started_at !== 'string') return undefined
|
|
121
120
|
|
|
@@ -4,8 +4,8 @@ import { api_outage } from '#scripts/agent/api-outage'
|
|
|
4
4
|
import type { ClaudeResultEvent } from '#scripts/agent/claude-result-event'
|
|
5
5
|
import { git_gh_issue_read } from '#scripts/gh/git-gh-issue-read'
|
|
6
6
|
import { issue_state } from '#scripts/issue/issue-state'
|
|
7
|
-
import { run_cut } from '
|
|
8
|
-
import { run_hold } from '
|
|
7
|
+
import { run_cut } from '#scripts/run/cut/run-cut'
|
|
8
|
+
import { run_hold } from '#scripts/run/hold/run-hold'
|
|
9
9
|
import { run_issue_number } from './run-issue-number'
|
|
10
10
|
import { run_liveness } from './run-liveness'
|
|
11
11
|
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
run_hold,
|
|
3
|
+
type HoldRead,
|
|
4
|
+
type RunHold,
|
|
5
|
+
type StopMarkFields,
|
|
6
|
+
} from '#scripts/run/hold/run-hold'
|
|
2
7
|
|
|
3
8
|
// joshuafolkken/kit#2796: a `halfrun` stops before its commit and **keeps** its hold, because the
|
|
4
9
|
// uncommitted, hand-verified work is exactly what a second run would trample. The person then types
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
2
2
|
import { lane_reap } from '#scripts/lane/lane-reap'
|
|
3
3
|
import { lane_registry } from '#scripts/lane/lane-registry'
|
|
4
|
-
import { run_carry, type CarryRead, type RunCarry } from '
|
|
4
|
+
import { run_carry, type CarryRead, type RunCarry } from '#scripts/run/carry/run-carry'
|
|
5
5
|
|
|
6
6
|
// The headless `backlogrun` parent (joshuafolkken/kit#2437). `run:wake` starts a cut's successor as
|
|
7
7
|
// `claude -p`, and there a turn that ends is the process that ends: its background `lane:await` and
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { backlog_budget_cli } from '#scripts/backlog/backlog-budget-cli'
|
|
2
|
+
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
2
3
|
import { run_issue_number } from './run-issue-number'
|
|
3
4
|
|
|
4
5
|
// The grammar of an invocation that can be carried across a session cut, and the only place it is
|
|
@@ -39,17 +40,34 @@ const KNOWN_FLAGS: ReadonlyArray<string> = ['--max', '--idle']
|
|
|
39
40
|
// pool" (joshuafolkken/kit#1984). It is carried across a cut like any other part of the invocation, so
|
|
40
41
|
// a resumed session that reads it back does not silently start draining the backlog the person excluded.
|
|
41
42
|
const ONLY_FLAG = '--only'
|
|
43
|
+
// The read itself is `cli_flags`'s (joshuafolkken/kit#3261): strict, so an unknown flag, a flag with
|
|
44
|
+
// no value, `--only=<x>` and a value that is itself a flag are all refused before this file looks.
|
|
45
|
+
const OPTIONS = {
|
|
46
|
+
max: { type: 'string' },
|
|
47
|
+
idle: { type: 'string' },
|
|
48
|
+
only: { type: 'boolean' },
|
|
49
|
+
} as const
|
|
42
50
|
const ISSUE_PREFIX = '#'
|
|
51
|
+
const FLAG_PREFIX = '-'
|
|
43
52
|
const TOKEN_SEPARATOR = ' '
|
|
44
53
|
const FIRST_TOKEN = 0
|
|
45
54
|
const FIRST_ARGUMENT_INDEX = 1
|
|
46
|
-
const VALUE_OFFSET = 1
|
|
47
|
-
const FLAG_PAIR_LENGTH = 2
|
|
48
|
-
// `--only` advances the scan by one token, having no value where a `--max` / `--idle` pair advances two.
|
|
49
|
-
const ONLY_STEP = 1
|
|
50
55
|
const EMPTY_LENGTH = 0
|
|
51
56
|
const NOT_FOUND = -1
|
|
52
57
|
|
|
58
|
+
// One token of `parseArgs`'s `tokens` answer, as far as this file reads it: a positional's text, or an
|
|
59
|
+
// option's name and the value it was given (`--max 5` and `--max=5` alike).
|
|
60
|
+
interface ArgumentToken {
|
|
61
|
+
kind: string
|
|
62
|
+
name?: string
|
|
63
|
+
value?: string | undefined
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface Invocation {
|
|
67
|
+
issues: ReadonlyArray<number>
|
|
68
|
+
flags: ReadonlyArray<string>
|
|
69
|
+
}
|
|
70
|
+
|
|
53
71
|
// A space is the only separator that can survive `detached-launch.ts`'s `is_safe_value`, which has
|
|
54
72
|
// already refused every control character — so the split needs no pattern, and this file is left with
|
|
55
73
|
// no regular expression of its own for a backtracking analysis to find. The one pattern it does use
|
|
@@ -60,57 +78,33 @@ function tokens_of(invocation: string): ReadonlyArray<string> {
|
|
|
60
78
|
|
|
61
79
|
// **The integer check is `backlog:budget`'s own, imported rather than restated.** It is the command
|
|
62
80
|
// this invocation is going to be handed to, so a second copy of the rule here would be free to drift
|
|
63
|
-
// from the one that actually reads the number.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
81
|
+
// from the one that actually reads the number. `--only` carries no value and renders to its own
|
|
82
|
+
// constant for the same taint reason every other token does — the constant severs the record's string
|
|
83
|
+
// from the rebuilt one.
|
|
84
|
+
function render_option(token: ArgumentToken): string | undefined {
|
|
85
|
+
if (token.name === cli_flags.option_name(ONLY_FLAG)) return ONLY_FLAG
|
|
86
|
+
const flag = KNOWN_FLAGS.find((known) => cli_flags.option_name(known) === token.name)
|
|
87
|
+
const value = backlog_budget_cli.to_count(token.value)
|
|
67
88
|
|
|
68
89
|
if (flag === undefined || value === undefined) return undefined
|
|
69
90
|
|
|
70
91
|
return `${flag} ${String(value)}`
|
|
71
92
|
}
|
|
72
93
|
|
|
73
|
-
// One rendered flag and how far it advanced the scan: two tokens for a valued flag, one for `--only`.
|
|
74
|
-
// The advance is returned rather than assumed, so `flag_tokens` handles a valueless flag mixed in with
|
|
75
|
-
// the pairs without knowing which kind it read.
|
|
76
|
-
interface FlagRead {
|
|
77
|
-
part: string
|
|
78
|
-
advance: number
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// **`--only` is read before the valued flags**, because it is the one token that carries no value: read
|
|
82
|
-
// as a valued flag it would swallow whatever follows it as its argument. It renders to its own constant
|
|
83
|
-
// for the same taint reason every other token does — the constant severs the record's string from the
|
|
84
|
-
// rebuilt one.
|
|
85
|
-
function read_flag(tokens: ReadonlyArray<string>, index: number): FlagRead | undefined {
|
|
86
|
-
const token = tokens[index] ?? ''
|
|
87
|
-
|
|
88
|
-
if (token === ONLY_FLAG) return { part: ONLY_FLAG, advance: ONLY_STEP }
|
|
89
|
-
|
|
90
|
-
const part = flag_token(token, tokens[index + VALUE_OFFSET])
|
|
91
|
-
|
|
92
|
-
return part === undefined ? undefined : { part, advance: FLAG_PAIR_LENGTH }
|
|
93
|
-
}
|
|
94
|
-
|
|
95
94
|
// **An unknown flag is refused, never dropped.** Dropping one would wake a session running to a budget
|
|
96
95
|
// the person did not declare the first time `backlogrun` grows a flag this list has not caught up with
|
|
97
96
|
// — which is the failure that is hardest to notice, because the session runs and looks fine. A stray
|
|
98
|
-
// `#N` after the flags lands here too, as a token that
|
|
99
|
-
//
|
|
100
|
-
function
|
|
101
|
-
tokens: ReadonlyArray<string>,
|
|
102
|
-
start: number,
|
|
103
|
-
): ReadonlyArray<string> | undefined {
|
|
97
|
+
// `#N` after the flags lands here too, as a token that is no option, and is refused: the named list is
|
|
98
|
+
// the invocation's leading block, never interleaved with the budget. So is a `--` terminator.
|
|
99
|
+
function rendered_options(tokens: ReadonlyArray<ArgumentToken>): ReadonlyArray<string> | undefined {
|
|
104
100
|
const rendered: Array<string> = []
|
|
105
|
-
let index = start
|
|
106
101
|
|
|
107
|
-
|
|
108
|
-
const
|
|
102
|
+
for (const token of tokens) {
|
|
103
|
+
const part = render_option(token)
|
|
109
104
|
|
|
110
|
-
if (
|
|
105
|
+
if (part === undefined) return undefined
|
|
111
106
|
|
|
112
|
-
rendered.push(
|
|
113
|
-
index += read.advance
|
|
107
|
+
rendered.push(part)
|
|
114
108
|
}
|
|
115
109
|
|
|
116
110
|
return rendered
|
|
@@ -135,25 +129,15 @@ function issue_of(token: string): number | undefined {
|
|
|
135
129
|
return Number.isSafeInteger(issue) ? issue : undefined
|
|
136
130
|
}
|
|
137
131
|
|
|
138
|
-
// The named issues are the leading block of
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
// The contiguous leading block of `#`-prefixed tokens — everything up to the first token that is not
|
|
144
|
-
// an issue reference, which is where the budget flags begin.
|
|
145
|
-
function take_leading_prefixed(args: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
146
|
-
const stop = args.findIndex((token) => !token.startsWith(ISSUE_PREFIX))
|
|
147
|
-
|
|
148
|
-
return args.slice(FIRST_TOKEN, stop === NOT_FOUND ? args.length : stop)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function leading_issues(tokens: ReadonlyArray<string>): ReadonlyArray<number> | undefined {
|
|
132
|
+
// The named issues are the leading block of positionals, in the order they were typed, and each must be
|
|
133
|
+
// a `#N` that validates — anything else refuses the whole invocation rather than being dropped. An
|
|
134
|
+
// empty block is a valid answer here (a bare `backlogrun` or a budget-only one); `issue_numbers` is
|
|
135
|
+
// where "no named issues" becomes `undefined`.
|
|
136
|
+
function issues_of(tokens: ReadonlyArray<ArgumentToken>): ReadonlyArray<number> | undefined {
|
|
152
137
|
const issues: Array<number> = []
|
|
153
|
-
const prefixed = take_leading_prefixed(tokens.slice(FIRST_ARGUMENT_INDEX))
|
|
154
138
|
|
|
155
|
-
for (const token of
|
|
156
|
-
const issue = issue_of(token)
|
|
139
|
+
for (const token of tokens) {
|
|
140
|
+
const issue = issue_of(token.value ?? '')
|
|
157
141
|
|
|
158
142
|
if (issue === undefined) return undefined
|
|
159
143
|
|
|
@@ -163,6 +147,35 @@ function leading_issues(tokens: ReadonlyArray<string>): ReadonlyArray<number> |
|
|
|
163
147
|
return issues
|
|
164
148
|
}
|
|
165
149
|
|
|
150
|
+
// The arguments after the command word, as `parseArgs` tokens, or `undefined` for another command or
|
|
151
|
+
// an argument list the strict read refuses.
|
|
152
|
+
function argument_tokens(invocation: string): ReadonlyArray<ArgumentToken> | undefined {
|
|
153
|
+
const tokens = tokens_of(invocation)
|
|
154
|
+
|
|
155
|
+
if (tokens[FIRST_TOKEN] !== BACKLOG_COMMAND) return undefined
|
|
156
|
+
|
|
157
|
+
return cli_flags.parse_or_undefined({
|
|
158
|
+
args: tokens.slice(FIRST_ARGUMENT_INDEX),
|
|
159
|
+
options: OPTIONS,
|
|
160
|
+
allowPositionals: true,
|
|
161
|
+
tokens: true,
|
|
162
|
+
})?.tokens
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// The named list is everything before the first option, and the budget flags everything from it on.
|
|
166
|
+
function parse(invocation: string): Invocation | undefined {
|
|
167
|
+
const tokens = argument_tokens(invocation)
|
|
168
|
+
if (tokens === undefined) return undefined
|
|
169
|
+
const stop = tokens.findIndex((token) => token.kind !== 'positional')
|
|
170
|
+
const split_at = stop === NOT_FOUND ? tokens.length : stop
|
|
171
|
+
const issues = issues_of(tokens.slice(FIRST_TOKEN, split_at))
|
|
172
|
+
const flags = rendered_options(tokens.slice(split_at))
|
|
173
|
+
|
|
174
|
+
if (issues === undefined || flags === undefined) return undefined
|
|
175
|
+
|
|
176
|
+
return { issues, flags }
|
|
177
|
+
}
|
|
178
|
+
|
|
166
179
|
function issue_token(issue: number): string {
|
|
167
180
|
return `${ISSUE_PREFIX}${String(issue)}`
|
|
168
181
|
}
|
|
@@ -174,26 +187,17 @@ function joined(command: string, rendered: ReadonlyArray<string>): string {
|
|
|
174
187
|
// The named list rebuilds first and the budget flags after it, so the canonical text is
|
|
175
188
|
// `backlogrun #1 #2 --max 5` whatever spacing the record held. Both halves are composed from this
|
|
176
189
|
// file's own constants and validated integers, so no token of the record survives into the result.
|
|
177
|
-
function rebuilt_backlog(tokens: ReadonlyArray<string>): string | undefined {
|
|
178
|
-
const issues = leading_issues(tokens)
|
|
179
|
-
|
|
180
|
-
if (issues === undefined) return undefined
|
|
181
|
-
|
|
182
|
-
const flags = flag_tokens(tokens, FIRST_ARGUMENT_INDEX + issues.length)
|
|
183
|
-
|
|
184
|
-
if (flags === undefined) return undefined
|
|
185
|
-
|
|
186
|
-
return joined(BACKLOG_COMMAND, [...issues.map((issue) => issue_token(issue)), ...flags])
|
|
187
|
-
}
|
|
188
|
-
|
|
189
190
|
// The command word is compared against this file's own constant and the **constant** is what the
|
|
190
191
|
// rebuilt text is composed from, so no token of the record survives into the result.
|
|
191
192
|
function rebuild(invocation: string): string | undefined {
|
|
192
|
-
const
|
|
193
|
+
const parsed = parse(invocation)
|
|
193
194
|
|
|
194
|
-
if (
|
|
195
|
+
if (parsed === undefined) return undefined
|
|
195
196
|
|
|
196
|
-
return
|
|
197
|
+
return joined(BACKLOG_COMMAND, [
|
|
198
|
+
...parsed.issues.map((issue) => issue_token(issue)),
|
|
199
|
+
...parsed.flags,
|
|
200
|
+
])
|
|
197
201
|
}
|
|
198
202
|
|
|
199
203
|
// The issues a `backlogrun` invocation named, in the order it named them. An invocation with no named
|
|
@@ -201,12 +205,13 @@ function rebuild(invocation: string): string | undefined {
|
|
|
201
205
|
// "this invocation named no issues" and "this run has no issues left" are different facts, and a
|
|
202
206
|
// caller that could not tell them apart would report a finished sequential run as one that never had a
|
|
203
207
|
// list. A malformed leading `#N` answers `undefined` too, because there is then no list to trust.
|
|
208
|
+
// Only the leading block is read, so a flag this grammar does not carry — `backlog:plan`'s `--exclude`
|
|
209
|
+
// — after it does not hide the named issues.
|
|
204
210
|
function issue_numbers(invocation: string): ReadonlyArray<number> | undefined {
|
|
205
211
|
const tokens = tokens_of(invocation)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const issues = leading_issues(tokens)
|
|
212
|
+
const stop = tokens.findIndex((token) => token.startsWith(FLAG_PREFIX))
|
|
213
|
+
const leading = stop === NOT_FOUND ? tokens : tokens.slice(FIRST_TOKEN, stop)
|
|
214
|
+
const issues = parse(leading.join(TOKEN_SEPARATOR))?.issues
|
|
210
215
|
|
|
211
216
|
if (issues === undefined || issues.length === EMPTY_LENGTH) return undefined
|
|
212
217
|
|
|
@@ -214,15 +219,11 @@ function issue_numbers(invocation: string): ReadonlyArray<number> | undefined {
|
|
|
214
219
|
}
|
|
215
220
|
|
|
216
221
|
// Whether the invocation carries `--only`, so a resumed session runs the named list and stops rather
|
|
217
|
-
// than draining the pool. It reads the
|
|
222
|
+
// than draining the pool. It reads the flag from the same parse `rebuild` composes from, so the two
|
|
218
223
|
// cannot disagree on what `--only` looks like. A non-`backlogrun` invocation carries none, which is
|
|
219
224
|
// `false`.
|
|
220
225
|
function has_only(invocation: string): boolean {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (tokens[FIRST_TOKEN] !== BACKLOG_COMMAND) return false
|
|
224
|
-
|
|
225
|
-
return tokens.slice(FIRST_ARGUMENT_INDEX).includes(ONLY_FLAG)
|
|
226
|
+
return parse(invocation)?.flags.includes(ONLY_FLAG) === true
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
// **Three entries, because three things call in.** The command word, the flag list and the token
|
|
@@ -7,7 +7,7 @@ import { git_gh_issue_read } from '#scripts/gh/git-gh-issue-read'
|
|
|
7
7
|
import { ALREADY_DONE_LABEL, NEEDS_DECISION_LABEL } from '#scripts/issue/issue-labels'
|
|
8
8
|
import { issue_state } from '#scripts/issue/issue-state'
|
|
9
9
|
import { PLATFORM_TEMP_ROOT } from '#scripts/josh/platform-temporary'
|
|
10
|
-
import { run_hold } from '
|
|
10
|
+
import { run_hold } from '#scripts/run/hold/run-hold'
|
|
11
11
|
import { run_issue_number } from './run-issue-number'
|
|
12
12
|
|
|
13
13
|
// `josh run:liveness <N>` — whether the delegated unit running child `<N>` is still working, or
|
|
@@ -5,7 +5,7 @@ import { cost_verdict } from '#scripts/cost-runtime/cost-verdict'
|
|
|
5
5
|
import { hook_decision } from '#scripts/josh/hook-decision'
|
|
6
6
|
import { error_text } from '#scripts/lib/error-message'
|
|
7
7
|
import { implementation_cut_verdict } from '#scripts/rules/implementation-cut-verdict'
|
|
8
|
-
import { run_carry, type RunCarry } from '
|
|
8
|
+
import { run_carry, type RunCarry } from '#scripts/run/carry/run-carry'
|
|
9
9
|
import { run_headless } from './run-headless'
|
|
10
10
|
import { run_watcher_hook } from './run-watcher-hook'
|
|
11
11
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { git_gh_pr_read } from '#scripts/gh/git-gh-pr-read'
|
|
2
2
|
import { git_command } from '#scripts/git/git-command'
|
|
3
3
|
import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
|
|
4
|
+
import { run_hold } from '#scripts/run/hold/run-hold'
|
|
4
5
|
import { z } from 'zod'
|
|
5
|
-
import { run_hold } from './run-hold'
|
|
6
6
|
import { run_issue_number } from './run-issue-number'
|
|
7
7
|
|
|
8
8
|
// The preflight check — what an interrupted run left in this working tree, and what the rule says to
|
|
@@ -230,11 +230,11 @@ async function read_tree_state(): Promise<TreeState> {
|
|
|
230
230
|
// could not complete (joshuafolkken/kit#1048). That throw reaches the CLI as `unknown`; without it a
|
|
231
231
|
// rate-limited or logged-out `gh` turns a **merged** pull request into `resume`, and the run commits
|
|
232
232
|
// on top of work somebody already landed — the exact hazard `park` exists for.
|
|
233
|
-
// **The second half of the same guard.** `
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
//
|
|
237
|
-
//
|
|
233
|
+
// **The second half of the same guard.** `pr_view` throws on a read it could not complete
|
|
234
|
+
// (joshuafolkken/kit#3263), but the two are separate round trips, so a lookup that answers empty
|
|
235
|
+
// between them would still put a **merged** pull request back through `NO_PR` and out as `resume`.
|
|
236
|
+
// An empty answer for a branch `pr_exists` has just confirmed is therefore a failed read by
|
|
237
|
+
// construction, and it throws rather than answering.
|
|
238
238
|
async function read_pr_state(branch_name: string): Promise<PrState> {
|
|
239
239
|
if (!(await git_gh_pr_read.pr_exists(branch_name))) return NO_PR
|
|
240
240
|
|
|
@@ -5,10 +5,10 @@ import { issue_read_cli, type BlockRead } from '#scripts/issue/issue-read-cli'
|
|
|
5
5
|
import { issue_state_cli, type StateRead } from '#scripts/issue/issue-state-cli'
|
|
6
6
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
7
7
|
import { error_text } from '#scripts/lib/error-message'
|
|
8
|
+
import { run_ship_preflight } from '#scripts/run/ship/run-ship-preflight'
|
|
8
9
|
import { latest_scope_cli } from '#scripts/version/latest-scope-cli'
|
|
9
10
|
import { run_prep, type PrepParts } from './run-prep'
|
|
10
11
|
import { run_prep_locate } from './run-prep-locate'
|
|
11
|
-
import { run_ship_preflight } from './run-ship-preflight'
|
|
12
12
|
|
|
13
13
|
// `josh run:prep <N>` — one call for the reads a `fullrun` makes before its first edit
|
|
14
14
|
// (joshuafolkken/kit#1978): the issue body and comments (`issue:read`), the state, labels and
|
|
@@ -2,8 +2,8 @@ import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
|
2
2
|
import type { PullMergeState } from '#scripts/gh/git-gh-pr-read'
|
|
3
3
|
import { git_branch } from '#scripts/git/git-branch'
|
|
4
4
|
import { git_command } from '#scripts/git/git-command'
|
|
5
|
+
import { run_hold, type HoldRead } from '#scripts/run/hold/run-hold'
|
|
5
6
|
import { run_halfrun_resume, type StopMark } from './run-halfrun-resume'
|
|
6
|
-
import { run_hold, type HoldRead } from './run-hold'
|
|
7
7
|
|
|
8
8
|
// joshuafolkken/kit#3023: a `prrun` stops at a green, mergeable pull request and **keeps** its hold, so
|
|
9
9
|
// a person can look before anything merges. What comes next is one of three, and `run:entry` answers
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
3
|
import { git_followup_pending } from '#scripts/followup/git-followup-pending'
|
|
4
4
|
import { release_scope_cli } from '#scripts/release/release-scope-cli'
|
|
5
|
-
import { run_carry } from '
|
|
6
|
-
import { run_event_scope, type EventScope } from '
|
|
7
|
-
import { run_event_stream, type RunEvent } from '
|
|
8
|
-
import { run_event_stream_emit } from '
|
|
5
|
+
import { run_carry } from '#scripts/run/carry/run-carry'
|
|
6
|
+
import { run_event_scope, type EventScope } from '#scripts/run/event/run-event-scope'
|
|
7
|
+
import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
|
|
8
|
+
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
9
9
|
import { run_report } from './run-report'
|
|
10
10
|
|
|
11
11
|
// `josh run:report` — the session-facing report, generated from the run's event stream rather than
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { release_scope_cli, type Decision } from '#scripts/release/release-scope-cli'
|
|
2
|
-
import { run_event_scope, type EventScope } from '
|
|
3
|
-
import { run_event_stream, type RunEvent } from '
|
|
2
|
+
import { run_event_scope, type EventScope } from '#scripts/run/event/run-event-scope'
|
|
3
|
+
import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
|
|
4
4
|
|
|
5
5
|
// The session-facing report generated *from* the run's event stream, rather than composed by hand each
|
|
6
6
|
// time (joshuafolkken/kit#2249). #2205 gave the run a typed, ordered stream of what happened — a plan, a
|
|
@@ -3,7 +3,7 @@ import { fileURLToPath } from 'node:url'
|
|
|
3
3
|
import { cost_cli, type CostVerdict } from '#scripts/cost-runtime/cost-cli'
|
|
4
4
|
import { issue_state_cli, type StateRead } from '#scripts/issue/issue-state-cli'
|
|
5
5
|
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
6
|
-
import { run_carry, type CarryRead } from '
|
|
6
|
+
import { run_carry, type CarryRead } from '#scripts/run/carry/run-carry'
|
|
7
7
|
import { run_status, type StatusParts } from './run-status'
|
|
8
8
|
|
|
9
9
|
// `josh run:status <N>` — one call for the read-only status a run glances at (joshuafolkken/kit#2165):
|
|
@@ -6,9 +6,9 @@ import { hook_decision } from '#scripts/josh/hook-decision'
|
|
|
6
6
|
import { find_package_directory } from '#scripts/josh/josh-logic'
|
|
7
7
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
8
8
|
import { lane_reap } from '#scripts/lane/lane-reap'
|
|
9
|
-
import { run_carry, type CarryRead } from '
|
|
10
|
-
import { run_event_scope } from '
|
|
11
|
-
import { run_event_stream } from '
|
|
9
|
+
import { run_carry, type CarryRead } from '#scripts/run/carry/run-carry'
|
|
10
|
+
import { run_event_scope } from '#scripts/run/event/run-event-scope'
|
|
11
|
+
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
12
12
|
import { run_headless } from './run-headless'
|
|
13
13
|
import { run_prep, type PrepParts } from './run-prep'
|
|
14
14
|
import { run_prep_cli } from './run-prep-cli'
|
package/scripts/run/run-step.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { git_stash } from '#scripts/git/stash/git-stash'
|
|
2
|
+
import type { CarryRead } from '#scripts/run/carry/run-carry'
|
|
3
|
+
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
2
4
|
import { latest_scope_cli } from '#scripts/version/latest-scope-cli'
|
|
3
|
-
import type { CarryRead } from './run-carry'
|
|
4
|
-
import { run_event_stream } from './run-event-stream'
|
|
5
5
|
import { run_retrospective } from './run-retrospective'
|
|
6
6
|
|
|
7
7
|
// `josh run:step <N>` — the run's next single action, computed from three mechanical inputs and nothing
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { telegram_notify } from '#scripts/notify/telegram-notify'
|
|
2
|
-
import type { CarryRead } from '
|
|
2
|
+
import type { CarryRead } from '#scripts/run/carry/run-carry'
|
|
3
3
|
|
|
4
4
|
// **A `backlogrun` that halts because a person is needed used to reach nobody once the session was
|
|
5
5
|
// cut** (joshuafolkken/kit#2136). Every remaining child blocked behind a parked one, the backlog
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { telegram_notify } from '#scripts/notify/telegram-notify'
|
|
2
|
-
import { run_carry, type CarryRead, type RunCarry } from '
|
|
3
|
-
import { run_event_stream } from '
|
|
4
|
-
import { run_event_stream_emit } from '
|
|
2
|
+
import { run_carry, type CarryRead, type RunCarry } from '#scripts/run/carry/run-carry'
|
|
3
|
+
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
4
|
+
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
5
|
+
import { run_wake, type RunWake } from '#scripts/run/wake/run-wake'
|
|
5
6
|
import {
|
|
6
7
|
run_stranded,
|
|
7
8
|
type StrandedInput,
|
|
8
9
|
type StrandedVerdict,
|
|
9
10
|
type SupervisorLiveness,
|
|
10
11
|
} from './run-stranded'
|
|
11
|
-
import { run_wake, type RunWake } from './run-wake'
|
|
12
12
|
|
|
13
13
|
// The I/O half of the strand detector (joshuafolkken/kit#2375): it gathers the three facts the pure
|
|
14
14
|
// judge in `run-stranded.ts` weighs, then — on a strand — leaves the marker and sends the one
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { process_identity } from '#scripts/josh/process-identity'
|
|
2
|
-
import { run_carry, type CarryRead, type RunCarry } from '
|
|
3
|
-
import type { RunWake } from '
|
|
2
|
+
import { run_carry, type CarryRead, type RunCarry } from '#scripts/run/carry/run-carry'
|
|
3
|
+
import type { RunWake } from '#scripts/run/wake/run-wake'
|
|
4
4
|
|
|
5
5
|
// The mechanical judge of a *stranded* run (joshuafolkken/kit#2375). On 2026-09-22 a `backlogrun`'s
|
|
6
6
|
// cost hand-off left the record carried and handed off, the session that cut it died, no successor ever
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import { run_progress_read } from '
|
|
3
|
+
import { run_progress_read } from '#scripts/run/progress/run-progress-read'
|
|
4
4
|
import { run_watcher_guard } from './run-watcher-guard'
|
|
5
5
|
|
|
6
6
|
// `josh run:watcher:guard` — refuses when lane children are in-flight but the progress watcher has not
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { lane_registry } from '#scripts/lane/lane-registry'
|
|
2
|
+
import { run_progress_clock } from '#scripts/run/progress/run-progress-clock'
|
|
2
3
|
import { run_headless } from './run-headless'
|
|
3
|
-
import { run_progress_clock } from './run-progress-clock'
|
|
4
4
|
|
|
5
5
|
// A watcher that stopped while children are still in-flight leaves the run's event stream without a
|
|
6
6
|
// heartbeat and the parent without the wake an arrival would deliver. This guard detects that state so
|
|
@@ -37,9 +37,11 @@ const OK_RESULT: GuardResult = { kind: 'ok' }
|
|
|
37
37
|
// **Only the run that opened the lanes owes them a watcher** (joshuafolkken/kit#2965). The lane listing
|
|
38
38
|
// is machine-wide, so a session with no run of its own — an investigation, a `fullrun` beside a batch —
|
|
39
39
|
// used to be refused for another run's lanes. The session that drives the live `backlogrun` carry
|
|
40
|
-
// record is the one that dispatched them; every other session passes.
|
|
40
|
+
// record is the one that dispatched them; every other session passes. A session `run:wake` woke owes
|
|
41
|
+
// none either (joshuafolkken/kit#3245): the supervisor's driver watches the lanes, and the woken session
|
|
42
|
+
// only acts on the branch it was handed and cuts.
|
|
41
43
|
async function owes_watcher(): Promise<boolean> {
|
|
42
|
-
if (!(await run_headless.is_backlog_parent())) return false
|
|
44
|
+
if (run_headless.is_headless() || !(await run_headless.is_backlog_parent())) return false
|
|
43
45
|
|
|
44
46
|
return await lane_registry.has_lanes_in_flight()
|
|
45
47
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { hook_decision } from '#scripts/josh/hook-decision'
|
|
2
2
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
3
|
+
import { run_progress_read } from '#scripts/run/progress/run-progress-read'
|
|
3
4
|
import { z } from 'zod'
|
|
4
|
-
import { run_progress_read } from './run-progress-read'
|
|
5
5
|
import { run_watcher_guard } from './run-watcher-guard'
|
|
6
6
|
|
|
7
7
|
// The `PreToolUse` adapter that turns `run_watcher_guard`'s verdict into a deny reason, so the guard
|