@joshuafolkken/kit 1.1050.0 → 1.1128.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/settings.json +9 -8
- package/.claude/skills/epic-commands/SKILL.md +5 -7
- package/.claude/skills/workflow-commands/SKILL.md +20 -12
- package/.claude/skills/workflow-commands/background-commands.md +36 -84
- package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
- package/.claude/skills/workflow-commands/backlogrun-progress.md +30 -33
- package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -12
- package/.claude/skills/workflow-commands/backlogrun.md +2 -2
- package/.claude/skills/workflow-commands/chain-rule.md +4 -2
- package/.claude/skills/workflow-commands/delegation.md +3 -3
- package/.claude/skills/workflow-commands/followup-reference.md +1 -1
- package/.claude/skills/workflow-commands/followup.md +7 -3
- package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/fullrun.md +8 -6
- package/.claude/skills/workflow-commands/halfrun.md +19 -21
- package/.claude/skills/workflow-commands/issue-comments.md +1 -1
- package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
- package/.claude/skills/workflow-commands/issue-scout.md +1 -1
- package/.claude/skills/workflow-commands/kickoff.md +9 -4
- package/.claude/skills/workflow-commands/latest-gate.md +8 -16
- package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
- package/.claude/skills/workflow-commands/observation-filing.md +3 -3
- package/.claude/skills/workflow-commands/pre-gate-cut.md +4 -8
- package/.claude/skills/workflow-commands/prerequisite.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +36 -0
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +4 -18
- package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
- package/.codex/hooks.json +16 -20
- package/.github/actions/setup-node/action.yml +33 -0
- package/.github/actions/setup-pnpm/action.yml +93 -0
- package/.github/dependabot.yml +5 -1
- package/.github/workflows/auto-tag.yml +2 -3
- package/.github/workflows/ci.yml +31 -134
- package/.github/workflows/dependabot-auto-merge.yml +1 -0
- package/.github/workflows/pr-classification.yml +6 -44
- package/.github/workflows/production.yml +1 -0
- package/.github/workflows/publish.yml +43 -47
- package/.github/workflows/sonar-qube.yml +41 -4
- package/.pnpmfile.mjs +29 -0
- package/AGENTS.md +5 -2
- package/CLAUDE.md +33 -27
- package/GEMINI.md +5 -2
- package/README.md +66 -20
- package/SECURITY.md +37 -6
- package/cspell/index.yaml +6 -1
- package/dist/CLAUDE.basic.md +6 -6
- package/dist/CLAUDE.md +33 -27
- package/dist/CLAUDE.static.md +6 -6
- package/dist/config-merge/index.js +48 -12
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-7VPDUBRN.js → chunk-4JZDP5X5.js} +152 -155
- package/dist/hooks/{chunk-HJIISEAC.js → chunk-5SD2YM7Z.js} +5 -13
- package/dist/hooks/{chunk-NAS4C7GP.js → chunk-77J7IEQM.js} +2 -2
- package/dist/hooks/{chunk-DMQN45FN.js → chunk-7HVB7SZG.js} +3 -3
- package/dist/hooks/{chunk-RLDX5SOC.js → chunk-AIOIOMPX.js} +4413 -1970
- package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M7QKEKWO.js} +873 -2049
- package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-MKVGBQPA.js} +2 -2
- package/dist/hooks/{chunk-EJDX2TOB.js → chunk-NXYMNPUQ.js} +7 -88
- package/dist/hooks/{chunk-NJQOBE6L.js → chunk-QVLT52OV.js} +2 -7
- package/dist/hooks/{chunk-GQ7KP45M.js → chunk-XYUIQOW3.js} +2 -2
- package/dist/hooks/codex-hook-adapter.js +12 -48
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +280 -0
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/session-lang.js +0 -1
- package/dist/hooks/stop-guard.js +192 -333
- package/dist/josh.js +240 -148
- package/dist/managed-marker/index.js +2 -1
- package/dist/version/index.js +70 -78
- package/eslint/rules/promise.js +5 -0
- package/eslint/rules/unicorn.js +3 -2
- package/package.json +26 -5
- package/pnpm-workspace.yaml +5 -7
- package/prompts/collaboration-workflow/glossary.md +17 -0
- package/prompts/collaboration-workflow/issue-citation.md +5 -5
- package/prompts/collaboration-workflow/issue-template.md +1 -1
- package/prompts/collaboration-workflow/operating-rules.md +5 -5
- package/prompts/collaboration-workflow/overview.md +13 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow/report-format.md +1 -1
- package/prompts/collaboration-workflow/residency.md +3 -3
- package/prompts/collaboration-workflow/rule-delivery.md +1 -1
- package/prompts/collaboration-workflow/turn-batching.md +3 -3
- package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
- package/prompts/collaboration-workflow/wip-cap.md +25 -22
- package/prompts/collaboration-workflow.md +6 -8
- package/prompts/review-rubric.md +1 -1
- package/prompts/review.md +3 -3
- package/prompts/sonar-hotspot-handling.md +11 -3
- package/prompts/testing-guide.md +3 -3
- package/scripts/adopt/adopt-toolkits.ts +0 -2
- package/scripts/adopt/adopt.ts +0 -2
- package/scripts/agent/agent-argv.ts +0 -2
- package/scripts/agent/agent-diagnostics.ts +1 -1
- package/scripts/agent/agent-role-profile.ts +0 -7
- package/scripts/agent/claude-agent-argv.ts +0 -2
- package/scripts/agent/codex-agent-argv.ts +1 -1
- package/scripts/agent/codex-hooks.ts +92 -0
- package/scripts/agent/interactive-ask.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +6 -16
- package/scripts/backlog/backlog-arrival.ts +30 -10
- package/scripts/backlog/backlog-budget-cli.ts +15 -16
- package/scripts/backlog/backlog-budget.ts +0 -2
- package/scripts/backlog/backlog-defect-priority.ts +2 -2
- package/scripts/backlog/backlog-drive-cli.ts +10 -8
- package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
- package/scripts/backlog/backlog-drive-named.ts +2 -1
- package/scripts/backlog/backlog-drive.ts +76 -16
- package/scripts/backlog/backlog-named.ts +0 -3
- package/scripts/backlog/backlog-next.ts +9 -15
- package/scripts/backlog/backlog-offer-cli.ts +6 -19
- package/scripts/backlog/backlog-plan-cli.ts +1 -7
- package/scripts/backlog/backlog-plan.ts +30 -19
- package/scripts/backlog/backlog-pool.ts +3 -6
- package/scripts/backlog/backlog-rank.ts +2 -2
- package/scripts/backlog/backlog-ready.ts +39 -10
- package/scripts/backlog/backlog-scope.ts +1 -3
- package/scripts/backlog/backlog-stalled-detect.ts +2 -2
- package/scripts/backlog/backlog-stalled.ts +0 -1
- package/scripts/backlog/backlog-waves.ts +5 -2
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/build/build-codex-hooks.ts +26 -0
- package/scripts/build/build-hooks.ts +85 -9
- package/scripts/build/hook-bundle-stamp.ts +111 -0
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +1 -1
- package/scripts/ci/composite-actions.ts +30 -0
- package/scripts/ci/pr-classification.ts +3 -3
- package/scripts/claude/workflow-destination.ts +10 -1
- package/scripts/clone/clone-fingerprint.ts +0 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/json-format.ts +0 -1
- package/scripts/config-merge/parse-jsonc.ts +33 -3
- package/scripts/config-merge/patch-json-key.ts +13 -6
- package/scripts/config-merge/patch-yaml-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +2 -9
- package/scripts/cost-runtime/cost-attribute.ts +0 -1
- package/scripts/cost-runtime/cost-cli.ts +3 -10
- package/scripts/cost-runtime/cost-corpus.ts +0 -2
- package/scripts/cost-runtime/cost-format.ts +0 -3
- package/scripts/cost-runtime/cost-pricing.ts +0 -1
- package/scripts/cost-runtime/cost-tokens.ts +0 -1
- package/scripts/delegation/delegation-cli.ts +1 -1
- package/scripts/delegation/delegation-policy.ts +0 -1
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +0 -2
- package/scripts/delegation/investigation-reads.ts +1 -164
- package/scripts/discovery/repo-map-logic.ts +0 -1
- package/scripts/discovery/repo-party-cli.ts +1 -1
- package/scripts/doctor/doctor-consumer.ts +6 -10
- package/scripts/doctor/doctor-io.ts +9 -13
- package/scripts/doctor/doctor-logic.ts +0 -4
- package/scripts/doctor/doctor.ts +14 -9
- package/scripts/document/backlogrun-parent-read-set.ts +12 -1
- package/scripts/document/document-byte-budget.ts +5 -5
- package/scripts/document/document-byte-check.ts +0 -1
- package/scripts/document/document-read-cli.ts +0 -2
- package/scripts/document/document-section-cli.ts +1 -1
- package/scripts/document/document-section.ts +0 -3
- package/scripts/document/edit-files-cli.ts +0 -1
- package/scripts/document/entry-read-budget.ts +21 -7
- package/scripts/document/entry-read-set.ts +32 -8
- package/scripts/document/lane-child-read-set.ts +8 -6
- package/scripts/document/read-files-cli.ts +0 -4
- package/scripts/document/read-set-cli.ts +0 -2
- package/scripts/document/read-set-point-of-use.ts +9 -3
- package/scripts/document/read-set-pricing.ts +0 -1
- package/scripts/document/read-set-trim.ts +4 -2
- package/scripts/epic/epic-add.ts +1 -1
- package/scripts/epic/epic-audit-cli.ts +1 -4
- package/scripts/epic/epic-audit-orphans.ts +1 -3
- package/scripts/epic/epic-audit-rationale.ts +0 -1
- package/scripts/epic/epic-audit-report.ts +0 -2
- package/scripts/epic/epic-audit.ts +8 -22
- package/scripts/epic/epic-bundle-cli.ts +1 -1
- package/scripts/epic/epic-bundle-evidence.ts +0 -1
- package/scripts/epic/epic-bundle-referenced.ts +1 -5
- package/scripts/epic/epic-bundle.ts +0 -4
- package/scripts/epic/epic-busy.ts +4 -5
- package/scripts/epic/epic-candidate-confirm.ts +0 -5
- package/scripts/epic/epic-classify.ts +2 -2
- package/scripts/epic/epic-cli-argv.ts +0 -1
- package/scripts/epic/epic-close-comment.ts +1 -1
- package/scripts/epic/epic-close.ts +5 -2
- package/scripts/epic/epic-cross-repo.ts +2 -4
- package/scripts/epic/epic-decision.ts +0 -1
- package/scripts/epic/epic-fetch.ts +2 -2
- package/scripts/epic/epic-index.ts +2 -3
- package/scripts/epic/epic-issue.ts +1 -15
- package/scripts/epic/epic-lane-offer.ts +9 -8
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +1 -3
- package/scripts/epic/epic-next-views.ts +0 -1
- package/scripts/epic/epic-next.ts +1 -10
- package/scripts/epic/epic-parse.ts +0 -1
- package/scripts/epic/epic-promote.ts +0 -9
- package/scripts/epic/epic-rank.ts +2 -2
- package/scripts/epic/epic-read.ts +1 -2
- package/scripts/epic/epic-reconcile.ts +1 -1
- package/scripts/epic/epic-reference.ts +1 -13
- package/scripts/epic/epic-relation-recheck.ts +1 -1
- package/scripts/epic/epic-relations.ts +1 -1
- package/scripts/epic/epic-remove.ts +1 -1
- package/scripts/epic/epic-report.ts +0 -1
- package/scripts/epic/epic-run.ts +2 -3
- package/scripts/epic/epic-shape.ts +1 -1
- package/scripts/epic/epic-solo-stale.ts +107 -0
- package/scripts/epic/epic-solo.ts +3 -2
- package/scripts/epic/epic-triage.ts +1 -1
- package/scripts/epic/epic-validate.ts +1 -1
- package/scripts/epic/epic.ts +1 -1
- package/scripts/exports/unused-members-cli.ts +53 -0
- package/scripts/{git → followup}/followup-issue-number.ts +1 -6
- package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
- package/scripts/{git → followup}/git-followup-finish.ts +1 -3
- package/scripts/{git → followup}/git-followup-flush.ts +2 -2
- package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
- package/scripts/{git → followup}/git-followup-label.ts +4 -4
- package/scripts/followup/git-followup-merged.ts +112 -0
- package/scripts/{git → followup}/git-followup-pending.ts +1 -1
- package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
- package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
- package/scripts/{git → followup}/git-pr-followup.ts +53 -16
- package/scripts/gate/core-budget.ts +3 -9
- package/scripts/gate/gate-plan.ts +7 -4
- package/scripts/gate/gate-report.ts +0 -6
- package/scripts/gate/gate-tree.ts +1 -1
- package/scripts/gate/pre-commit-type-check.ts +0 -6
- package/scripts/gate/project-checks.ts +7 -8
- package/scripts/gate/scoped-green.ts +0 -1
- package/scripts/gate/type-check-step.ts +1 -1
- package/scripts/gate/verification-gate.ts +0 -2
- package/scripts/gh/fix-gh-packages.ts +15 -12
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
- package/scripts/{git → gh}/git-gh-check.ts +2 -1
- package/scripts/{git → gh}/git-gh-exec.ts +1 -1
- package/scripts/{git → gh}/git-gh-failure.ts +1 -1
- package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
- package/scripts/{git → gh}/git-gh-issue-list.ts +13 -10
- package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
- package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
- package/scripts/{git → gh}/git-gh-issue-write.ts +4 -1
- package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +4 -1
- package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
- package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
- package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
- package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
- package/scripts/{git → gh}/git-gh-pr.ts +3 -1
- package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
- package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
- package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
- package/scripts/{git → gh}/git-pr-checks.ts +2 -1
- package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
- package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
- package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
- package/scripts/{git → gh}/git-pr.ts +3 -3
- package/scripts/git/changed-file-scope.ts +0 -1
- package/scripts/git/git-branch.ts +3 -6
- package/scripts/git/git-command.ts +6 -1
- package/scripts/git/git-commit.ts +1 -1
- package/scripts/git/git-common-directory.ts +80 -24
- package/scripts/git/git-error.ts +66 -9
- package/scripts/git/git-issue.ts +1 -1
- package/scripts/git/git-preflight.ts +2 -2
- package/scripts/git/git-prompt.ts +6 -31
- package/scripts/git/git-push.ts +1 -1
- package/scripts/git/git-spawn-sync.ts +65 -0
- package/scripts/git/git-spawn.ts +5 -4
- package/scripts/git/git-staging.ts +1 -0
- package/scripts/git/git-status.ts +1 -1
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/gone-branch.ts +1 -0
- package/scripts/git/listing-cutoff.ts +1 -1
- package/scripts/git/main-merge.ts +1 -1
- package/scripts/git/main-sync.ts +19 -1
- package/scripts/git/parse-json-array.ts +0 -3
- package/scripts/git/repository-lock.ts +16 -16
- package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
- package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +2 -7
- package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
- package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
- package/scripts/hooks/codex-hook-adapter.ts +0 -1
- package/scripts/hooks/edited-cspell.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +2 -0
- package/scripts/hooks/pre-push-unit.ts +0 -4
- package/scripts/hooks/pretool-guard.ts +22 -4
- package/scripts/hooks/reserved-run.ts +1 -1
- package/scripts/hooks/step-zero-notice.ts +76 -0
- package/scripts/hooks/stop-guard.ts +47 -21
- package/scripts/init/claude-plugin-config.ts +4 -5
- package/scripts/init/hook-command-rewrite.ts +16 -8
- package/scripts/init/hook-launch.ts +41 -15
- package/scripts/init/init-basic.ts +2 -5
- package/scripts/init/init-file-action.ts +54 -0
- package/scripts/init/init-logic-migrate.ts +35 -17
- package/scripts/init/init-logic-secretlint.ts +1 -1
- package/scripts/init/init-logic.ts +10 -19
- package/scripts/init/init.ts +11 -71
- package/scripts/init/kit-written-paths.ts +2 -0
- package/scripts/init/project-profile.ts +9 -17
- package/scripts/init/start-exec.ts +1 -1
- package/scripts/init/start-setup-pr.ts +6 -6
- package/scripts/init/start-steps.ts +3 -1
- package/scripts/issue/behavior-change-lint.ts +0 -1
- package/scripts/issue/defect-rate-cli.ts +64 -23
- package/scripts/issue/defect-rate.ts +1 -2
- package/scripts/{git → issue}/git-next-issues.ts +3 -3
- package/scripts/issue/issue-backlinks-cli.ts +1 -5
- package/scripts/issue/issue-backlinks.ts +7 -14
- package/scripts/issue/issue-cite-cli.ts +2 -6
- package/scripts/issue/issue-cite.ts +12 -8
- package/scripts/issue/issue-classification.ts +1 -9
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +2 -2
- package/scripts/issue/issue-file-cli.ts +5 -5
- package/scripts/issue/issue-file.ts +7 -14
- package/scripts/issue/issue-fold-cli.ts +1 -1
- package/scripts/issue/issue-fold-existing-cli.ts +1 -1
- package/scripts/{git → issue}/issue-labels.ts +8 -0
- package/scripts/issue/issue-lint-cli.ts +1 -1
- package/scripts/issue/issue-merged.ts +2 -2
- package/scripts/{git → issue}/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +8 -47
- package/scripts/issue/issue-read.ts +0 -2
- package/scripts/issue/issue-report-failures.ts +80 -0
- package/scripts/issue/issue-scout-cli.ts +1 -7
- package/scripts/issue/issue-scout-closed.ts +2 -2
- package/scripts/issue/issue-scout.ts +0 -2
- package/scripts/issue/issue-state-cli.ts +5 -46
- package/scripts/issue/issue-state.ts +1 -5
- package/scripts/issue/markdown-section.ts +21 -6
- package/scripts/issue/measure-rerun-cli.ts +74 -15
- package/scripts/issue/reproduction-measure.ts +1 -1
- package/scripts/josh/cli-body.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +0 -3
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-commands-ai.ts +9 -102
- package/scripts/josh/josh-commands-backlog.ts +5 -1
- package/scripts/josh/josh-commands-development.ts +8 -1
- package/scripts/josh/josh-commands-issue.ts +2 -2
- package/scripts/josh/josh-commands-maintenance.ts +7 -0
- package/scripts/josh/josh-commands-project.ts +7 -1
- package/scripts/josh/josh-commands-run.ts +114 -0
- package/scripts/josh/josh-commands-versioning.ts +8 -0
- package/scripts/josh/josh-commands-workflow.ts +3 -3
- package/scripts/josh/path-decision.ts +0 -3
- package/scripts/josh/process-owner.ts +16 -0
- package/scripts/josh/run-github-prerequisite.ts +3 -6
- package/scripts/josh/session-language-cli.ts +0 -1
- package/scripts/lane/lane-await.ts +46 -19
- package/scripts/lane/lane-capacity.ts +6 -3
- package/scripts/lane/lane-child-invocation.ts +20 -7
- package/scripts/lane/lane-cli.ts +1 -4
- package/scripts/lane/lane-close.ts +5 -4
- package/scripts/lane/lane-dispatch.ts +3 -4
- package/scripts/lane/lane-environment.ts +0 -9
- package/scripts/lane/lane-handoff.ts +38 -0
- package/scripts/lane/lane-launch-cli.ts +31 -27
- package/scripts/lane/lane-open.ts +0 -3
- package/scripts/lane/lane-output.ts +0 -1
- package/scripts/lane/lane-registry.ts +9 -0
- package/scripts/lane/openai-lane-ship.ts +2 -0
- package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
- package/scripts/lane/openai-lane-supervisor.ts +6 -4
- package/scripts/lane/openai-review-broker.ts +7 -1
- package/scripts/lib/bounded-pool.ts +1 -0
- package/scripts/lib/cli-flags.ts +31 -2
- package/scripts/lib/error-message.ts +12 -1
- package/scripts/lib/json-value.ts +5 -4
- package/scripts/lib/poll.ts +3 -1
- package/scripts/lib/timed-fetch.ts +15 -0
- package/scripts/lib/timeouts.ts +13 -0
- package/scripts/{yaml → lib}/yaml-document.ts +3 -1
- package/scripts/{bytes → lines}/bytes-command.ts +0 -2
- package/scripts/lines/line-targets.ts +0 -11
- package/scripts/lines/lines-command.ts +5 -4
- package/scripts/lint/lint-related-scope.ts +0 -1
- package/scripts/lint/lint-related.ts +1 -1
- package/scripts/{git → notify}/telegram-notify.ts +2 -2
- package/scripts/{git → notify}/telegram-test.ts +4 -4
- package/scripts/observations/observation-ledger-home.ts +0 -1
- package/scripts/observations/observation-ledger-line.ts +0 -1
- package/scripts/observations/observation-ledger-migrate.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +3 -3
- package/scripts/observations/observations-flush.ts +2 -2
- package/scripts/overrides/lockfile-overrides.ts +1 -1
- package/scripts/overrides/overrides-logic.ts +1 -1
- package/scripts/package/package-scout-cli.ts +2 -7
- package/scripts/package/package-scout.ts +0 -2
- package/scripts/propagate/propagate-git-failure.ts +0 -1
- package/scripts/propagate/propagate-git.ts +3 -10
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +0 -2
- package/scripts/propagate/propagate-steps.ts +3 -5
- package/scripts/propagate/propagate-targets.ts +0 -4
- package/scripts/propagate/propagate.ts +0 -4
- package/scripts/refactor/import-graph.ts +0 -1
- package/scripts/refactor/refactor-lint.ts +0 -2
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +0 -1
- package/scripts/registry-migration/migrate-logic.ts +28 -21
- package/scripts/registry-migration/migrate.ts +25 -14
- package/scripts/release/github-release-cli.ts +19 -6
- package/scripts/release/github-release-environment.ts +46 -0
- package/scripts/release/github-release.ts +151 -94
- package/scripts/release/release-history.ts +0 -1
- package/scripts/release/release-plan.ts +0 -1
- package/scripts/release/release-publish.ts +38 -5
- package/scripts/release/release-scope-cli.ts +1 -2
- package/scripts/release/release-tag.ts +2 -4
- package/scripts/release/release-worktree.ts +97 -2
- package/scripts/repo/auto-merge-setting-logic.ts +1 -4
- package/scripts/repo/repo-setting.ts +1 -1
- package/scripts/repo/repository-labels.ts +3 -3
- package/scripts/repo/required-checks-logic.ts +206 -0
- package/scripts/repo/required-checks-report.ts +71 -0
- package/scripts/repo/ruleset-check-cli.ts +53 -0
- package/scripts/repo/ruleset-check.ts +147 -0
- package/scripts/report/report-lint-cli.ts +0 -4
- package/scripts/review/disposition-cli.ts +1 -1
- package/scripts/review/live-evidence.ts +1 -1
- package/scripts/review/review-attest-cli.ts +0 -6
- package/scripts/review/review-attest.ts +4 -16
- package/scripts/review/review-brief-cli.ts +23 -6
- package/scripts/review/review-brief.ts +21 -8
- package/scripts/review/review-checkout.ts +3 -2
- package/scripts/review/review-diff-parts.ts +89 -0
- package/scripts/review/review-diff-write.ts +97 -0
- package/scripts/review/review-finding-ledger.ts +0 -1
- package/scripts/review/review-record-cli.ts +10 -17
- package/scripts/review/review-record.ts +0 -1
- package/scripts/review/review-round2-cli.ts +1 -1
- package/scripts/review/review-stamps.ts +0 -3
- package/scripts/review/review-tree.ts +14 -2
- package/scripts/rules/decision-oracle-stage.ts +18 -0
- package/scripts/rules/decision-oracle.ts +10 -7
- package/scripts/rules/delivered-rules.ts +9 -1
- package/scripts/rules/destructive-command.ts +119 -0
- package/scripts/rules/direct-filing.ts +1 -1
- package/scripts/rules/early-heartbeat.ts +4 -3
- package/scripts/rules/file-body.ts +0 -3
- package/scripts/rules/filing-cap.ts +0 -2
- package/scripts/rules/gh-api.ts +7 -2
- package/scripts/rules/git-argv.ts +18 -7
- package/scripts/rules/git-force.ts +0 -2
- package/scripts/rules/implementation-cut.ts +0 -1
- package/scripts/rules/index-guard.ts +71 -0
- package/scripts/rules/issue-citation.ts +50 -25
- package/scripts/rules/lane-background.ts +15 -7
- package/scripts/rules/lane-park.ts +22 -6
- package/scripts/rules/last-prompt.ts +1 -0
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/oracle-list-cli.ts +0 -3
- package/scripts/rules/permission-guards.ts +14 -0
- package/scripts/rules/protected-files.ts +74 -0
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +0 -3
- package/scripts/rules/rule-value-cli.ts +0 -1
- package/scripts/rules/shell-body-trigger.ts +0 -1
- package/scripts/rules/shell-segments.ts +0 -1
- package/scripts/rules/stop-rules.ts +20 -9
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +0 -1
- package/scripts/rules/worktree-guard.ts +26 -9
- package/scripts/run/run-carry-args.ts +8 -12
- package/scripts/run/run-carry-cli.ts +0 -2
- package/scripts/run/run-carry-stash.ts +2 -2
- package/scripts/run/run-carry-streak.ts +1 -1
- package/scripts/run/run-cut-args.ts +1 -6
- package/scripts/run/run-cut-cli.ts +0 -7
- package/scripts/run/run-cut.ts +8 -54
- package/scripts/run/run-ending-cli.ts +2 -6
- package/scripts/run/run-ending.ts +1 -4
- package/scripts/run/run-entry-cli.ts +133 -25
- package/scripts/run/run-entry-stop.ts +104 -0
- package/scripts/run/run-entry.ts +0 -1
- package/scripts/run/run-event-cli.ts +0 -2
- package/scripts/run/run-event-follow.ts +1 -0
- package/scripts/run/run-event-render.ts +1 -1
- package/scripts/run/run-event-scope.ts +53 -4
- package/scripts/run/run-event-stream-emit.ts +7 -2
- package/scripts/run/run-event-stream.ts +0 -3
- package/scripts/run/run-event-watch.ts +1 -0
- package/scripts/run/run-halfrun-resume.ts +20 -7
- package/scripts/run/run-headless.ts +2 -2
- package/scripts/run/run-hold-cli.ts +33 -10
- package/scripts/run/run-hold.ts +29 -6
- package/scripts/run/run-issue-number.ts +1 -1
- package/scripts/run/run-liveness-cli.ts +2 -6
- package/scripts/run/run-liveness.ts +2 -3
- package/scripts/run/run-merge-cli.ts +7 -23
- package/scripts/run/run-merge-steps.ts +5 -5
- package/scripts/run/run-merge.ts +1 -1
- package/scripts/run/run-next-cli.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +4 -2
- package/scripts/run/run-preflight.ts +2 -9
- package/scripts/run/run-prep-cli.ts +6 -3
- package/scripts/run/run-prep-locate.ts +1 -1
- package/scripts/run/run-progress-args.ts +20 -4
- package/scripts/run/run-progress-cli.ts +35 -36
- package/scripts/run/run-progress-clock.ts +10 -35
- package/scripts/run/run-progress-config.ts +0 -4
- package/scripts/run/run-progress-read.ts +1 -2
- package/scripts/run/run-progress.ts +1 -2
- package/scripts/run/run-prrun-resume.ts +117 -0
- package/scripts/run/run-report-cli.ts +1 -2
- package/scripts/run/run-report.ts +0 -1
- package/scripts/run/run-retrospective.ts +1 -1
- package/scripts/run/run-review-cli.ts +0 -3
- package/scripts/run/run-review-steps.ts +2 -0
- package/scripts/run/run-review.ts +0 -2
- package/scripts/run/run-ship-cli.ts +29 -19
- package/scripts/run/run-ship-detach.ts +1 -0
- package/scripts/run/run-ship-next.ts +106 -0
- package/scripts/run/run-ship-preflight.ts +1 -1
- package/scripts/run/run-ship-probe.ts +4 -1
- package/scripts/run/run-ship-return.ts +8 -3
- package/scripts/run/run-ship-review-steps.ts +18 -4
- package/scripts/run/run-ship-review.ts +11 -0
- package/scripts/run/run-ship-scoped.ts +1 -0
- package/scripts/run/run-ship-steps.ts +1 -1
- package/scripts/run/run-ship.ts +0 -1
- package/scripts/run/run-stage-read.ts +62 -0
- package/scripts/run/run-stage.ts +160 -0
- package/scripts/run/run-status-cli.ts +3 -16
- package/scripts/run/run-step-cli.ts +21 -14
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stop-notify.ts +1 -3
- package/scripts/run/run-stranded-cli.ts +0 -4
- package/scripts/run/run-stranded-detect.ts +2 -2
- package/scripts/run/run-tail-cli.ts +17 -11
- package/scripts/run/run-tail.ts +2 -0
- package/scripts/run/run-tidy-lanes.ts +6 -2
- package/scripts/run/run-tidy-stashes.ts +12 -12
- package/scripts/run/run-wake-cli.ts +4 -13
- package/scripts/run/run-wake-loop.ts +2 -2
- package/scripts/run/run-wake.ts +2 -4
- package/scripts/run/run-watcher-guard-cli.ts +0 -4
- package/scripts/run/run-watcher-guard.ts +18 -12
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/safe-chain/ci-installer-pin.ts +11 -5
- package/scripts/safe-chain/pack-hook.ts +92 -0
- package/scripts/safe-chain/project-config.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +0 -1
- package/scripts/security/security-audit-provision.ts +3 -2
- package/scripts/security/security-audit.ts +0 -1
- package/scripts/security/security-updates-logic.ts +0 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
- package/scripts/sonar/sonar-hotspots.ts +0 -1
- package/scripts/sonar/sonar-new-code-cli.ts +150 -0
- package/scripts/sonar/sonar-new-code.ts +79 -0
- package/scripts/sonar/sonar-project.ts +97 -0
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +2 -5
- package/scripts/sync/managed-config-scope-cli.ts +1 -1
- package/scripts/sync/skill-migration.ts +0 -1
- package/scripts/sync/sync-ai-files.ts +4 -0
- package/scripts/sync/sync-hook-safety.ts +2 -3
- package/scripts/sync/sync.ts +1 -8
- package/scripts/sync/template-source-logic.ts +0 -1
- package/scripts/sync/workflow-pin-logic.ts +16 -28
- package/scripts/test/test-declared-changed.ts +13 -16
- package/scripts/test/test-declared-logic.ts +0 -1
- package/scripts/test/test-declared.ts +3 -9
- package/scripts/test/test-red-commit.ts +2 -2
- package/scripts/test/test-red.ts +14 -7
- package/scripts/test/test-type-logic.ts +1 -1
- package/scripts/test/unit-worker-share.ts +7 -16
- package/scripts/time-runtime/time-batch-guard.ts +1 -2
- package/scripts/time-runtime/time-bundle-call.ts +0 -1
- package/scripts/time-runtime/time-bundles.ts +0 -4
- package/scripts/time-runtime/time-density-hook.ts +0 -2
- package/scripts/time-runtime/time-followup-stage.ts +1 -1
- package/scripts/time-runtime/time-format.ts +0 -73
- package/scripts/time-runtime/time-round-trips.ts +0 -4
- package/scripts/time-runtime/time-single-check.ts +1 -1
- package/scripts/time-runtime/time-spans.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +1 -2
- package/scripts/ui/ui-routes-cli.ts +0 -5
- package/scripts/ui/ui-routes.ts +0 -5
- package/scripts/version/effective-upstream.ts +2 -2
- package/scripts/version/latest-corepack.ts +7 -9
- package/scripts/version/latest-scope-cli.ts +0 -2
- package/scripts/version/latest-update.ts +0 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/publishable-range-check.ts +1 -1
- package/scripts/version/release-hold.ts +0 -4
- package/scripts/version/running-binary.ts +2 -2
- package/scripts/version/version-check-logic.ts +0 -2
- package/scripts/version/version-commands.ts +11 -1
- package/scripts/version/version-remote.ts +3 -3
- package/scripts/version/version-targets.ts +4 -4
- package/templates/CLAUDE.basic.md +6 -6
- package/templates/sonar-project.properties +28 -1
- package/templates/workflows/ci.yml +16 -82
- package/templates/workflows/dependabot-auto-merge.yml +6 -3
- package/templates/workflows/github-release.yml +79 -0
- package/tsconfig.sonar.json +4 -22
- package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
- package/prompts/collaboration-workflow/epic-audit.md +0 -5
- package/prompts/collaboration-workflow/epic-bundle.md +0 -5
- package/scripts/init/plugin-install-hint.ts +0 -47
- package/scripts/version/parse-json.ts +0 -13
- /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
- /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
- /package/scripts/{git → gh}/git-gh-command.ts +0 -0
- /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
- /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
- /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
- /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
- /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
- /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
- /package/scripts/{git → gh}/git-pr-error.ts +0 -0
- /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
- /package/scripts/{git → gh}/github-issue-url.ts +0 -0
- /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
- /package/scripts/{git → issue}/issue-reference.ts +0 -0
- /package/scripts/{git → lib}/animation-helpers.ts +0 -0
- /package/scripts/{git → lib}/git-animation.ts +0 -0
- /package/scripts/{git → notify}/git-notify.ts +0 -0
- /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
|
@@ -4,11 +4,15 @@ import { josh_command } from '#scripts/josh/josh-run'
|
|
|
4
4
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
5
5
|
import { run_cut_report } from './run-cut-report'
|
|
6
6
|
import { run_entry, type EntryParts } from './run-entry'
|
|
7
|
+
import { run_entry_stop } from './run-entry-stop'
|
|
7
8
|
import { run_halfrun_resume } from './run-halfrun-resume'
|
|
8
9
|
import { run_hold_cli } from './run-hold-cli'
|
|
9
10
|
import { run_next } from './run-next'
|
|
10
11
|
import { run_prep } from './run-prep'
|
|
11
12
|
import { run_prep_cli } from './run-prep-cli'
|
|
13
|
+
import { run_prrun_resume } from './run-prrun-resume'
|
|
14
|
+
import { run_stage, type StageCommand, type StageDecision } from './run-stage'
|
|
15
|
+
import { run_stage_read, type StageRead } from './run-stage-read'
|
|
12
16
|
import { run_step } from './run-step'
|
|
13
17
|
|
|
14
18
|
// `josh run:entry <N>` — one call for the fixed entry sequence a lane opens on (joshuafolkken/kit#2372).
|
|
@@ -27,13 +31,17 @@ const ARGV_OFFSET = 2
|
|
|
27
31
|
const SUCCESS_EXIT_CODE = 0
|
|
28
32
|
const FAILURE_EXIT_CODE = 1
|
|
29
33
|
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
30
|
-
const USAGE = 'Usage: josh run:entry <issue-number>'
|
|
34
|
+
const USAGE = 'Usage: josh run:entry <issue-number> [--to kickoff|halfrun|prrun|fullrun]'
|
|
35
|
+
const TO_FLAG = '--to'
|
|
36
|
+
// The flag and its command.
|
|
37
|
+
const TO_ARGUMENT_COUNT = 2
|
|
31
38
|
const should_forward_stderr = true
|
|
32
39
|
const NEWLINE = '\n'
|
|
33
40
|
|
|
34
41
|
const HOLD_STOP_NOTE =
|
|
35
42
|
'(tree not held — see the reason above; clean up and retry, or release with `pnpm josh run:release`)'
|
|
36
43
|
const COST_STOP_NOTE = '(session budget spent — see the figure above; resume in a fresh session)'
|
|
44
|
+
const { BUDGET_REASON, HOLD_REASON } = run_entry_stop
|
|
37
45
|
const HALFRUN_RESUME_TOKEN = 'halfrun'
|
|
38
46
|
|
|
39
47
|
// Exactly one issue number, or the call is refused — `run:entry` opens one run, and a second number
|
|
@@ -48,16 +56,42 @@ function parse_number(argv: ReadonlyArray<string>): string | undefined {
|
|
|
48
56
|
return first
|
|
49
57
|
}
|
|
50
58
|
|
|
59
|
+
interface EntryRequest {
|
|
60
|
+
issue_number: string
|
|
61
|
+
command: StageCommand
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// `--to <command>` names how far the run goes (joshuafolkken/kit#3042); absent, it is `fullrun`.
|
|
65
|
+
// Anything else is refused.
|
|
66
|
+
function parse_command(rest: ReadonlyArray<string>): StageCommand | undefined {
|
|
67
|
+
if (rest.length === 0) return run_stage.DEFAULT_COMMAND
|
|
68
|
+
|
|
69
|
+
const [flag, value] = rest
|
|
70
|
+
|
|
71
|
+
if (flag !== TO_FLAG || rest.length !== TO_ARGUMENT_COUNT) return undefined
|
|
72
|
+
|
|
73
|
+
return run_stage.to_command(value)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function parse_request(argv: ReadonlyArray<string>): EntryRequest | undefined {
|
|
77
|
+
const issue_number = parse_number(argv.slice(0, 1))
|
|
78
|
+
const command = parse_command(argv.slice(1))
|
|
79
|
+
|
|
80
|
+
return issue_number === undefined || command === undefined ? undefined : { issue_number, command }
|
|
81
|
+
}
|
|
82
|
+
|
|
51
83
|
function first_line(out: string): string {
|
|
52
84
|
return out.split(NEWLINE)[0] ?? ''
|
|
53
85
|
}
|
|
54
86
|
|
|
55
87
|
// `run:hold <N>` prints one token — `hold`, `busy` or `unknown` — and forwards its explanation to
|
|
56
88
|
// stderr, so the composite branches on the token and the reader still sees why. `--fullrun` marks the
|
|
57
|
-
// hold as
|
|
58
|
-
|
|
89
|
+
// hold as a run whose implementation cut resumes as `fullrun #N` (joshuafolkken/kit#2760) — a
|
|
90
|
+
// `fullrun`'s, and a `prrun`'s, which runs `fullrun`'s steps; a `halfrun`'s hold is never marked.
|
|
91
|
+
async function claim_hold(issue_number: string, command: StageCommand): Promise<string> {
|
|
92
|
+
const mark = command === run_stage.HALFRUN ? [] : ['--fullrun']
|
|
59
93
|
const held = await josh_command.josh_run(
|
|
60
|
-
['run:hold', issue_number,
|
|
94
|
+
['run:hold', issue_number, ...mark],
|
|
61
95
|
should_forward_stderr,
|
|
62
96
|
)
|
|
63
97
|
|
|
@@ -103,6 +137,23 @@ function stop_report(issue_number: string, hold: string, cost: string, report: s
|
|
|
103
137
|
return emit({ issue_number, hold, cost, verdict: run_entry.NO_VERDICT, report })
|
|
104
138
|
}
|
|
105
139
|
|
|
140
|
+
// A stop this command decided carries its own chores (joshuafolkken/kit#3099): the `confirmation`
|
|
141
|
+
// Telegram always, and the release where this call claimed the hold — `run_entry_stop` says why.
|
|
142
|
+
interface StopCall {
|
|
143
|
+
parts: Pick<EntryParts, 'issue_number' | 'hold' | 'cost' | 'report'>
|
|
144
|
+
command: StageCommand
|
|
145
|
+
reason: string
|
|
146
|
+
should_release: boolean
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async function stop_run({ parts, command, reason, should_release }: StopCall): Promise<number> {
|
|
150
|
+
const code = stop_report(parts.issue_number, parts.hold, parts.cost, parts.report)
|
|
151
|
+
|
|
152
|
+
await run_entry_stop.stop({ issue_number: parts.issue_number, command, reason, should_release })
|
|
153
|
+
|
|
154
|
+
return code
|
|
155
|
+
}
|
|
156
|
+
|
|
106
157
|
interface Resume {
|
|
107
158
|
token: string
|
|
108
159
|
code: number
|
|
@@ -131,55 +182,116 @@ function resume_report(issue_number: string, resume: Resume): number {
|
|
|
131
182
|
// **A `halfrun` stopped before its commit is resumed, not claimed** (joshuafolkken/kit#2796): its hold
|
|
132
183
|
// is kept over the verified diff, so the claim below would answer `busy` against it. The budget is asked
|
|
133
184
|
// first, as for any run; then the hold is adopted and the run goes to the gate, skipping everything up
|
|
134
|
-
// to and including implementation.
|
|
135
|
-
|
|
185
|
+
// to and including implementation. **A `prrun` stopped before its merge is resumed the same way**
|
|
186
|
+
// (joshuafolkken/kit#3023), under the token that says what is left of it.
|
|
187
|
+
async function resume_stopped(
|
|
188
|
+
{ issue_number, command }: EntryRequest,
|
|
189
|
+
token: string,
|
|
190
|
+
stopped_run: { adopt: (issue: string) => Promise<boolean> },
|
|
191
|
+
): Promise<number> {
|
|
136
192
|
const cost = await check_cost()
|
|
137
193
|
|
|
138
194
|
if (cost === run_entry.COST_OVER) {
|
|
139
|
-
|
|
195
|
+
const parts = { issue_number, hold: token, cost, report: COST_STOP_NOTE }
|
|
196
|
+
|
|
197
|
+
return await stop_run({ parts, command, reason: BUDGET_REASON, should_release: false })
|
|
140
198
|
}
|
|
141
199
|
|
|
142
|
-
if (!(await
|
|
143
|
-
|
|
200
|
+
if (!(await stopped_run.adopt(issue_number))) {
|
|
201
|
+
const parts = { issue_number, hold: run_hold_cli.BUSY_VERDICT, cost, report: HOLD_STOP_NOTE }
|
|
202
|
+
|
|
203
|
+
return await stop_run({ parts, command, reason: HOLD_REASON, should_release: false })
|
|
144
204
|
}
|
|
145
205
|
|
|
146
|
-
console.info(`entry #${issue_number} — resume: ${
|
|
206
|
+
console.info(`entry #${issue_number} — resume: ${token}`)
|
|
147
207
|
|
|
148
208
|
return SUCCESS_EXIT_CODE
|
|
149
209
|
}
|
|
150
210
|
|
|
151
|
-
|
|
152
|
-
|
|
211
|
+
// The stopped run a decision picks up: a `halfrun` stop resumes at the gate, a `prrun` stop at
|
|
212
|
+
// `followup` under its own token. `undefined` for any other start, so the ordinary claim decides.
|
|
213
|
+
async function resume_any(
|
|
214
|
+
request: EntryRequest,
|
|
215
|
+
decision: StageDecision,
|
|
216
|
+
stage: StageRead,
|
|
217
|
+
): Promise<number | undefined> {
|
|
218
|
+
if (decision.state === run_stage.HALFRUN_STOPPED) {
|
|
219
|
+
return await resume_stopped(request, HALFRUN_RESUME_TOKEN, run_halfrun_resume)
|
|
220
|
+
}
|
|
153
221
|
|
|
154
|
-
|
|
222
|
+
return stage.prrun_token === undefined
|
|
223
|
+
? undefined
|
|
224
|
+
: await resume_stopped(request, stage.prrun_token, run_prrun_resume)
|
|
225
|
+
}
|
|
155
226
|
|
|
156
|
-
|
|
227
|
+
// **A command whose stopping point the issue has already reached redoes nothing** (joshuafolkken/kit#3042)
|
|
228
|
+
// — the stage line is the whole report. A merged issue is the exception: the ordinary entry already
|
|
229
|
+
// answers it (`already-done`, or `keep-work` over a lane's uncommitted work), so it is left to that.
|
|
230
|
+
function is_settled(decision: StageDecision): boolean {
|
|
231
|
+
return decision.is_reached && decision.state !== run_stage.MERGED
|
|
232
|
+
}
|
|
157
233
|
|
|
158
|
-
|
|
234
|
+
async function claim_run({ issue_number, command }: EntryRequest): Promise<number> {
|
|
235
|
+
const hold = await claim_hold(issue_number, command)
|
|
159
236
|
|
|
160
237
|
if (hold !== run_hold_cli.HOLD_VERDICT) {
|
|
161
|
-
|
|
238
|
+
const parts = { issue_number, hold, cost: run_entry.COST_SKIPPED, report: HOLD_STOP_NOTE }
|
|
239
|
+
|
|
240
|
+
return await stop_run({ parts, command, reason: HOLD_REASON, should_release: false })
|
|
162
241
|
}
|
|
163
242
|
|
|
164
243
|
const cost = await check_cost()
|
|
165
244
|
|
|
166
|
-
if (cost === run_entry.COST_OVER)
|
|
245
|
+
if (cost === run_entry.COST_OVER) {
|
|
246
|
+
const parts = { issue_number, hold, cost, report: COST_STOP_NOTE }
|
|
247
|
+
|
|
248
|
+
return await stop_run({ parts, command, reason: BUDGET_REASON, should_release: true })
|
|
249
|
+
}
|
|
167
250
|
|
|
168
251
|
const reads = await gather_reads(issue_number)
|
|
169
252
|
|
|
170
253
|
return emit({ issue_number, hold, cost, verdict: reads.verdict, report: reads.report })
|
|
171
254
|
}
|
|
172
255
|
|
|
256
|
+
// A carried cut is asked first, before anything is read (`run:cut --resume`); `kickoff` claims and cuts
|
|
257
|
+
// nothing, so it never asks. `undefined` when no cut is waiting.
|
|
258
|
+
async function resume_cut(request: EntryRequest): Promise<number | undefined> {
|
|
259
|
+
if (request.command === run_stage.KICKOFF) return undefined
|
|
260
|
+
|
|
261
|
+
const resume = await ask_resume(request.issue_number)
|
|
262
|
+
|
|
263
|
+
return resume.token === run_cut_report.FRESH_VERDICT
|
|
264
|
+
? undefined
|
|
265
|
+
: resume_report(request.issue_number, resume)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// `kickoff` stops at the stage line whatever it says — it plans, and claims nothing.
|
|
269
|
+
async function open_run(request: EntryRequest): Promise<number> {
|
|
270
|
+
const { issue_number, command } = request
|
|
271
|
+
const cut = await resume_cut(request)
|
|
272
|
+
|
|
273
|
+
if (cut !== undefined) return cut
|
|
274
|
+
|
|
275
|
+
const stage = await run_stage_read.read_stage(issue_number)
|
|
276
|
+
const decision = run_stage.decide(stage.state, command)
|
|
277
|
+
|
|
278
|
+
console.info(run_stage.format_decision(issue_number, decision))
|
|
279
|
+
|
|
280
|
+
if (command === run_stage.KICKOFF || is_settled(decision)) return SUCCESS_EXIT_CODE
|
|
281
|
+
|
|
282
|
+
return (await resume_any(request, decision, stage)) ?? (await claim_run(request))
|
|
283
|
+
}
|
|
284
|
+
|
|
173
285
|
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
174
|
-
const
|
|
286
|
+
const request = parse_request(argv)
|
|
175
287
|
|
|
176
|
-
if (
|
|
288
|
+
if (request === undefined) {
|
|
177
289
|
console.error(USAGE)
|
|
178
290
|
|
|
179
291
|
return FAILURE_EXIT_CODE
|
|
180
292
|
}
|
|
181
293
|
|
|
182
|
-
return await open_run(
|
|
294
|
+
return await open_run(request)
|
|
183
295
|
}
|
|
184
296
|
|
|
185
297
|
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
@@ -188,12 +300,8 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
188
300
|
|
|
189
301
|
const run_entry_cli = {
|
|
190
302
|
HALFRUN_RESUME_TOKEN,
|
|
191
|
-
SUCCESS_EXIT_CODE,
|
|
192
|
-
USAGE,
|
|
193
|
-
check_cost,
|
|
194
|
-
claim_hold,
|
|
195
|
-
main,
|
|
196
303
|
parse_number,
|
|
304
|
+
parse_request,
|
|
197
305
|
run,
|
|
198
306
|
}
|
|
199
307
|
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { josh_command } from '#scripts/josh/josh-run'
|
|
2
|
+
import { telegram_notify } from '#scripts/notify/telegram-notify'
|
|
3
|
+
import { lane_park } from '#scripts/rules/lane-park'
|
|
4
|
+
|
|
5
|
+
// What `run:entry` does on the way out of a stop it decided itself (joshuafolkken/kit#3099).
|
|
6
|
+
//
|
|
7
|
+
// **The stop's chores used to be the agent's to remember, and the `Stop` hook was what reminded it.**
|
|
8
|
+
// `fullrun.md` step 3 asked the agent, on an `over` budget, to send the `confirmation` Telegram and then
|
|
9
|
+
// run `pnpm josh run:release` — two calls after a command had already decided the run was over. Across
|
|
10
|
+
// eleven measured sessions the hook sent a reply back five times for exactly those two calls, each one a
|
|
11
|
+
// further turn re-reading the whole context. The command that decides the stop knows everything the
|
|
12
|
+
// chores need, so it does them, and the hook stays a safety net that a normal run never trips.
|
|
13
|
+
//
|
|
14
|
+
// **The release is the claim's own undo, and only where this call made the claim.** A resume over a
|
|
15
|
+
// stopped `halfrun` / `prrun` stops on the budget before adopting anything, and the hold there is the
|
|
16
|
+
// stopped run's — kept on purpose over its verified diff — so that stop notifies and releases nothing.
|
|
17
|
+
// A `busy` / `unknown` hold is another run's, or none at all, so it is never released here either.
|
|
18
|
+
//
|
|
19
|
+
// **A dispatched lane child sends no Telegram from here.** Its stop must park the Issue before it
|
|
20
|
+
// notifies, and `lane_park`'s guard delivers that rule at the `josh notify` call — a Telegram sent from
|
|
21
|
+
// inside this command would pass that guard by and satisfy the `Stop` hook with no park behind it.
|
|
22
|
+
|
|
23
|
+
interface StopNotice {
|
|
24
|
+
issue_number: string
|
|
25
|
+
command: string
|
|
26
|
+
reason: string
|
|
27
|
+
should_release: boolean
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface StopPorts {
|
|
31
|
+
notify: (input: { issue_title: string; body: string; recovery: string }) => Promise<boolean>
|
|
32
|
+
release: (issue_number: string) => Promise<boolean>
|
|
33
|
+
is_parking_child: () => boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const RECOVERY = 'If this did not arrive, the run:entry output in the session names the stop.'
|
|
37
|
+
const NOTIFY_FAILED_NOTE =
|
|
38
|
+
'(the confirmation Telegram could not be sent — send it with `pnpm josh notify --task-type confirmation` before stopping)'
|
|
39
|
+
const RELEASED_NOTE = '(hold released by run:entry — the tree is free for the resume)'
|
|
40
|
+
const RELEASE_FAILED_NOTE =
|
|
41
|
+
'(the hold could not be released — run `pnpm josh run:release` before stopping)'
|
|
42
|
+
const should_forward_stderr = true
|
|
43
|
+
const SUCCESS_EXIT_CODE = 0
|
|
44
|
+
|
|
45
|
+
const BUDGET_REASON = 'the session budget is spent'
|
|
46
|
+
const HOLD_REASON = 'the working tree is not held for this run — see the run:entry output'
|
|
47
|
+
|
|
48
|
+
async function release(issue_number: string): Promise<boolean> {
|
|
49
|
+
const released = await josh_command.josh_run(['run:release', issue_number], should_forward_stderr)
|
|
50
|
+
|
|
51
|
+
return released.code === SUCCESS_EXIT_CODE
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function is_parking_child(): boolean {
|
|
55
|
+
return lane_park.is_parking_child()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const DEFAULT_PORTS: StopPorts = { notify: telegram_notify.confirm, release, is_parking_child }
|
|
59
|
+
|
|
60
|
+
function body_of(notice: StopNotice): string {
|
|
61
|
+
return `${notice.command} #${notice.issue_number} stopped at entry: ${notice.reason}.\nResume with \`${notice.command} #${notice.issue_number}\`.`
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// The release runs first, so the resume the Telegram names finds the tree free when a person acts on it.
|
|
65
|
+
// The marker line is printed only for a Telegram that went out: the `Stop` hook reads it as the notify,
|
|
66
|
+
// and a failed send has to leave the hook still asking for one. The released note, likewise, is printed
|
|
67
|
+
// only for a release that succeeded, so a failed one leaves the agent still asked to release.
|
|
68
|
+
async function release_claim(notice: StopNotice, ports: StopPorts): Promise<void> {
|
|
69
|
+
if (!notice.should_release) return
|
|
70
|
+
|
|
71
|
+
const is_released = await ports.release(notice.issue_number)
|
|
72
|
+
|
|
73
|
+
console.info(is_released ? RELEASED_NOTE : RELEASE_FAILED_NOTE)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function notify_stop(notice: StopNotice, ports: StopPorts): Promise<void> {
|
|
77
|
+
if (ports.is_parking_child()) return
|
|
78
|
+
|
|
79
|
+
const is_sent = await ports.notify({
|
|
80
|
+
issue_title: `${notice.command} #${notice.issue_number} stopped`,
|
|
81
|
+
body: body_of(notice),
|
|
82
|
+
recovery: RECOVERY,
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
console.info(is_sent ? lane_park.COMMAND_NOTIFY_MARKER : NOTIFY_FAILED_NOTE)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function stop(notice: StopNotice, ports: StopPorts = DEFAULT_PORTS): Promise<void> {
|
|
89
|
+
await release_claim(notice, ports)
|
|
90
|
+
await notify_stop(notice, ports)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const run_entry_stop = {
|
|
94
|
+
BUDGET_REASON,
|
|
95
|
+
HOLD_REASON,
|
|
96
|
+
NOTIFY_FAILED_NOTE,
|
|
97
|
+
RELEASED_NOTE,
|
|
98
|
+
RELEASE_FAILED_NOTE,
|
|
99
|
+
body_of,
|
|
100
|
+
stop,
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { run_entry_stop }
|
|
104
|
+
export type { StopNotice, StopPorts }
|
package/scripts/run/run-entry.ts
CHANGED
|
@@ -52,6 +52,7 @@ async function follow(
|
|
|
52
52
|
let read = ports.read(position)
|
|
53
53
|
|
|
54
54
|
while (read.events.length === 0 && ports.now() < deadline) {
|
|
55
|
+
// eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
|
|
55
56
|
await ports.sleep(options.tick_ms)
|
|
56
57
|
read = ports.read(position)
|
|
57
58
|
}
|
|
@@ -69,7 +69,7 @@ function render(event: RunEvent, lang: string): string {
|
|
|
69
69
|
return [clock_of(event.at), label_of(event.kind, lang), event.text].join(FIELD_SEPARATOR)
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
const run_event_render = {
|
|
72
|
+
const run_event_render = { clock_of, label_of, render }
|
|
73
73
|
|
|
74
74
|
export type { KindLabel }
|
|
75
75
|
export { run_event_render }
|
|
@@ -91,6 +91,22 @@ const SHIP_POSITION_KINDS: ReadonlySet<string> = new Set([
|
|
|
91
91
|
run_event_stream.EVENT_KIND.SHIP_STOP,
|
|
92
92
|
])
|
|
93
93
|
|
|
94
|
+
const KIND = run_event_stream.EVENT_KIND
|
|
95
|
+
|
|
96
|
+
// The parent's record of the batch around a child — its dispatch, park and split, the retrospective
|
|
97
|
+
// whose summary may name an issue it filed, and the strand whose text carries the whole invocation
|
|
98
|
+
// (`backlogrun #<N1> #<N2> …`). Each can name the child, yet none is a position the child itself is at,
|
|
99
|
+
// so a lane child never reads one as its own.
|
|
100
|
+
const BATCH_RECORD_KINDS: ReadonlySet<string> = new Set([
|
|
101
|
+
KIND.CHILD_LAUNCH,
|
|
102
|
+
KIND.PARK,
|
|
103
|
+
KIND.SPLIT,
|
|
104
|
+
KIND.RETROSPECTIVE,
|
|
105
|
+
KIND.STRANDED,
|
|
106
|
+
])
|
|
107
|
+
|
|
108
|
+
const ISSUE_REFERENCE = /#(\d+)/u
|
|
109
|
+
|
|
94
110
|
function is_foreign_ship_event(event: RunEvent, issue: string): boolean {
|
|
95
111
|
return SHIP_POSITION_KINDS.has(event.kind) && !event.text.startsWith(`#${issue} `)
|
|
96
112
|
}
|
|
@@ -99,16 +115,49 @@ function is_own_ship_event(event: RunEvent, issue: string): boolean {
|
|
|
99
115
|
return SHIP_POSITION_KINDS.has(event.kind) && !is_foreign_ship_event(event, issue)
|
|
100
116
|
}
|
|
101
117
|
|
|
118
|
+
// **A lane child's position is read only from events that name its own issue** (joshuafolkken/kit#3039).
|
|
119
|
+
// The parent and every lane append to one stream under one carry scope, so anything else on it is another
|
|
120
|
+
// run's: another lane's merge told a planned child to stop, the parent's stall (which names no issue)
|
|
121
|
+
// pointed it at `backlog:next`, and another lane's cut at `run:cut --resume`. The child's own merge and
|
|
122
|
+
// outage stay, so the parent-only stop in `run-step.ts` still holds; the parent keeps reading everything.
|
|
123
|
+
function names_issue(event: RunEvent, issue: string): boolean {
|
|
124
|
+
return ISSUE_REFERENCE.exec(event.text)?.[1] === issue
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function is_lane_position(event: RunEvent, issue: string): boolean {
|
|
128
|
+
return !BATCH_RECORD_KINDS.has(event.kind) && names_issue(event, issue)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// A lane child's attempt begins at its own newest launch. A child re-dispatched after an outage — or
|
|
132
|
+
// relaunched after a cut, whose resume `run:cut --resume` answers at the entry — shares the scope with
|
|
133
|
+
// its previous attempt, and that attempt's outage would otherwise stop the new one at its entry `run:step`.
|
|
134
|
+
function since_own_launch(events: ReadonlyArray<RunEvent>, issue: string): ReadonlyArray<RunEvent> {
|
|
135
|
+
const launch = events.findLastIndex(
|
|
136
|
+
(event) => event.kind === KIND.CHILD_LAUNCH && names_issue(event, issue),
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
return events.slice(launch + 1)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function is_foreign_event(event: RunEvent, issue: string, is_lane_child: boolean): boolean {
|
|
143
|
+
if (is_lane_child) return !is_lane_position(event, issue)
|
|
144
|
+
|
|
145
|
+
return is_foreign_ship_event(event, issue)
|
|
146
|
+
}
|
|
147
|
+
|
|
102
148
|
// The newest position for one issue's run: the scoped last event with other issues' ship positions left
|
|
103
|
-
// out
|
|
104
|
-
//
|
|
105
|
-
//
|
|
149
|
+
// out — and, for a lane child, every event not naming its issue — and, where no scope applies, as in
|
|
150
|
+
// an interactive `fullrun` with no carry record, the issue's own newest ship position, which its issue
|
|
151
|
+
// number already scopes. A determined scope with nothing in it yet reads nothing: an earlier invocation's
|
|
152
|
+
// stop for the same issue is not this invocation's position.
|
|
106
153
|
function last_issue_event(
|
|
107
154
|
events: ReadonlyArray<RunEvent>,
|
|
108
155
|
scope: EventScope,
|
|
109
156
|
issue: string,
|
|
157
|
+
is_lane_child: boolean,
|
|
110
158
|
): RunEvent | undefined {
|
|
111
|
-
const
|
|
159
|
+
const attempt = is_lane_child ? since_own_launch(events, issue) : events
|
|
160
|
+
const own = attempt.filter((event) => !is_foreign_event(event, issue, is_lane_child))
|
|
112
161
|
|
|
113
162
|
if (scope.kind === SINCE_SCOPE) return last_scoped_event(own, scope)
|
|
114
163
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { error_text } from '#scripts/lib/error-message'
|
|
1
2
|
import { run_carry } from './run-carry'
|
|
2
3
|
import { run_event_scope } from './run-event-scope'
|
|
3
4
|
import { run_event_stream, type RunEvent } from './run-event-stream'
|
|
@@ -62,8 +63,10 @@ async function emit_once(kind: string, text: string): Promise<boolean> {
|
|
|
62
63
|
if (target === undefined || run_event_stream.read_last(target)?.kind === kind) return false
|
|
63
64
|
|
|
64
65
|
return run_event_stream.append(target, kind, text, now_iso()).appended
|
|
65
|
-
} catch {
|
|
66
|
+
} catch (error) {
|
|
66
67
|
// Best-effort: a failed append is dropped rather than raised into the loop's work.
|
|
68
|
+
error_text.trace_swallowed('run_event_stream_emit.emit_once', error)
|
|
69
|
+
|
|
67
70
|
return false
|
|
68
71
|
}
|
|
69
72
|
}
|
|
@@ -98,8 +101,10 @@ async function emit_once_since(kind: string, text: string, reset_kind: string):
|
|
|
98
101
|
}
|
|
99
102
|
|
|
100
103
|
return run_event_stream.append(target, kind, text, now_iso()).appended
|
|
101
|
-
} catch {
|
|
104
|
+
} catch (error) {
|
|
102
105
|
// Best-effort: a failed append is dropped rather than raised into the caller's work.
|
|
106
|
+
error_text.trace_swallowed('run_event_stream_emit.emit_once_since', error)
|
|
107
|
+
|
|
103
108
|
return false
|
|
104
109
|
}
|
|
105
110
|
}
|
|
@@ -238,13 +238,10 @@ const run_event_stream = {
|
|
|
238
238
|
EVENT_CAP,
|
|
239
239
|
EVENT_KIND,
|
|
240
240
|
EVENT_KINDS,
|
|
241
|
-
EVENT_PREFIX,
|
|
242
|
-
EVENT_SUFFIX,
|
|
243
241
|
TRACE_KINDS,
|
|
244
242
|
append,
|
|
245
243
|
format_event,
|
|
246
244
|
has_since,
|
|
247
|
-
is_event_kind,
|
|
248
245
|
read_events,
|
|
249
246
|
read_from,
|
|
250
247
|
read_last,
|
|
@@ -22,6 +22,7 @@ async function watch(ports: WatchPorts, position: number): Promise<number> {
|
|
|
22
22
|
let next = position
|
|
23
23
|
|
|
24
24
|
while (ports.should_continue()) {
|
|
25
|
+
// eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
|
|
25
26
|
const read = await ports.pass(next)
|
|
26
27
|
|
|
27
28
|
for (const event of read.events) ports.write(ports.render(event))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { run_hold, type HoldRead, type RunHold } from './run-hold'
|
|
1
|
+
import { run_hold, type HoldRead, type RunHold, type StopMarkFields } from './run-hold'
|
|
2
2
|
|
|
3
3
|
// joshuafolkken/kit#2796: a `halfrun` stops before its commit and **keeps** its hold, because the
|
|
4
4
|
// uncommitted, hand-verified work is exactly what a second run would trample. The person then types
|
|
@@ -38,7 +38,13 @@ function is_own_record(read: HoldRead, issue: string): boolean {
|
|
|
38
38
|
return hold === undefined || hold.issue === issue || hold.issue === run_hold.UNNUMBERED_ISSUE
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
// `mark` is the `halfrun` stop's by default; a `prrun` stop passes its own (joshuafolkken/kit#3023), so
|
|
42
|
+
// the own-record check is one check whichever run is stopping.
|
|
43
|
+
function mark_stop_at(
|
|
44
|
+
target: string,
|
|
45
|
+
issue: string,
|
|
46
|
+
mark: StopMarkFields = run_hold.HALFRUN_STOP_FIELDS,
|
|
47
|
+
): StopMark {
|
|
42
48
|
const read = run_hold.read_hold(target)
|
|
43
49
|
|
|
44
50
|
if (read.kind === 'unreadable') return UNREADABLE
|
|
@@ -47,7 +53,14 @@ function mark_stop_at(target: string, issue: string): StopMark {
|
|
|
47
53
|
|
|
48
54
|
run_hold.release_hold(target)
|
|
49
55
|
|
|
50
|
-
return run_hold.
|
|
56
|
+
return run_hold.create_stop_hold(target, issue, mark) ? MARKED : FOREIGN
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// The stopped run's record is replaced by this `fullrun`'s, shared with the `prrun` resume.
|
|
60
|
+
function take_over(target: string, issue: string): boolean {
|
|
61
|
+
run_hold.release_hold(target)
|
|
62
|
+
|
|
63
|
+
return run_hold.create_hold(target, issue, new Date(), true)
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
// `false` leaves the record untouched, so the ordinary claim that follows decides the tree exactly as
|
|
@@ -55,9 +68,7 @@ function mark_stop_at(target: string, issue: string): StopMark {
|
|
|
55
68
|
function adopt_at(target: string, issue: string, is_dirty: boolean): boolean {
|
|
56
69
|
if (!is_halfrun_stop(run_hold.read_hold(target), issue, is_dirty)) return false
|
|
57
70
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return run_hold.create_hold(target, issue, new Date(), true)
|
|
71
|
+
return take_over(target, issue)
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
// **An unreadable git directory is no resume**, never a crash: `run:entry` must still print its one
|
|
@@ -95,9 +106,11 @@ const run_halfrun_resume = {
|
|
|
95
106
|
UNREADABLE,
|
|
96
107
|
adopt,
|
|
97
108
|
adopt_at,
|
|
98
|
-
|
|
109
|
+
hold_of,
|
|
110
|
+
hold_target,
|
|
99
111
|
is_pending,
|
|
100
112
|
mark_stop_at,
|
|
113
|
+
take_over,
|
|
101
114
|
}
|
|
102
115
|
|
|
103
116
|
export type { StopMark }
|
|
@@ -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
|
+
import { lane_registry } from '#scripts/lane/lane-registry'
|
|
3
4
|
import { run_carry, type CarryRead, type RunCarry } from './run-carry'
|
|
4
|
-
import { run_watcher_guard } from './run-watcher-guard'
|
|
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
|
|
@@ -51,7 +51,7 @@ async function read_carry_here(): Promise<CarryRead | undefined> {
|
|
|
51
51
|
async function must_keep_waiting(source: EnvironmentSource = process.env): Promise<boolean> {
|
|
52
52
|
const is_candidate = is_headless(source) && lane_child_marker.marked_issue(source) === undefined
|
|
53
53
|
|
|
54
|
-
if (!is_candidate || !(await
|
|
54
|
+
if (!is_candidate || !(await lane_registry.has_lanes_in_flight())) return false
|
|
55
55
|
|
|
56
56
|
return is_driving(await read_carry_here())
|
|
57
57
|
}
|