@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
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { read_spawn_stderr, read_spawn_stdout } from '#scripts/lib/spawn-exit'
|
|
2
|
+
import { execaSync } from 'execa'
|
|
3
|
+
import { git_utilities } from './constants'
|
|
4
|
+
|
|
5
|
+
// The one place a synchronous git command is spawned from (joshuafolkken/kit#3065) — the sync
|
|
6
|
+
// counterpart of `git-spawn.ts`. Every caller here wants an answer rather than an exception, so a
|
|
7
|
+
// non-zero exit is returned as a result, and every call is bounded: a git that never answers is an
|
|
8
|
+
// unknown the caller already handles, never a hang.
|
|
9
|
+
|
|
10
|
+
const GIT_TIMEOUT_MS = 10_000
|
|
11
|
+
const SUCCESS_EXIT_CODE = 0
|
|
12
|
+
// git translates its messages, so a caller matching stderr would fail under any non-English locale.
|
|
13
|
+
const C_LOCALE: Record<string, string> = { LC_ALL: 'C', LANGUAGE: 'C' }
|
|
14
|
+
|
|
15
|
+
interface GitSyncOptions {
|
|
16
|
+
cwd?: string
|
|
17
|
+
timeout?: number
|
|
18
|
+
env?: Record<string, string | undefined>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface GitSyncResult {
|
|
22
|
+
exit_code: number | undefined
|
|
23
|
+
stdout: string
|
|
24
|
+
stderr: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function run(args: ReadonlyArray<string>, options: GitSyncOptions = {}): GitSyncResult {
|
|
28
|
+
// execa runs the binary directly with an argument array and no `shell` option; the git command and
|
|
29
|
+
// args are internally controlled, never untrusted input. tssecurity:S8705 is a false positive here.
|
|
30
|
+
const result = execaSync(git_utilities.get_git_command_for_spawn(), args, {
|
|
31
|
+
...options,
|
|
32
|
+
extendEnv: true,
|
|
33
|
+
reject: false,
|
|
34
|
+
timeout: options.timeout ?? GIT_TIMEOUT_MS,
|
|
35
|
+
}) // NOSONAR
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
exit_code: result.exitCode,
|
|
39
|
+
stdout: read_spawn_stdout(result),
|
|
40
|
+
stderr: read_spawn_stderr(result),
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The trimmed output of a command that succeeded, or undefined for any failure.
|
|
45
|
+
function read(args: ReadonlyArray<string>, options: GitSyncOptions = {}): string | undefined {
|
|
46
|
+
const result = run(args, options)
|
|
47
|
+
|
|
48
|
+
return result.exit_code === SUCCESS_EXIT_CODE ? result.stdout.trim() : undefined
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// The configured `origin` URL, or undefined when the repository has none.
|
|
52
|
+
function origin_url(cwd: string): string | undefined {
|
|
53
|
+
return read(['config', '--get', 'remote.origin.url'], { cwd })
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// The absolute repository (or worktree) root, asked under the C locale so a caller can tell "not a
|
|
57
|
+
// repository" apart from every other failure by its stderr.
|
|
58
|
+
function toplevel(timeout: number = GIT_TIMEOUT_MS): GitSyncResult {
|
|
59
|
+
return run(['rev-parse', '--show-toplevel'], { env: C_LOCALE, timeout })
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const git_spawn_sync = { GIT_TIMEOUT_MS, C_LOCALE, run, read, origin_url, toplevel }
|
|
63
|
+
|
|
64
|
+
export { git_spawn_sync }
|
|
65
|
+
export type { GitSyncResult }
|
package/scripts/git/git-spawn.ts
CHANGED
|
@@ -18,10 +18,11 @@ import { git_ssh_keepalive } from './git-ssh-keepalive'
|
|
|
18
18
|
// **`git-push-transport.ts` is the one deliberate exception among the command modules** and is not a
|
|
19
19
|
// second helper of this kind: a push needs a transport-fault retry that no other command has, so it
|
|
20
20
|
// spawns git itself. The timeout it carries is shared here by `read_remote` / `with_output_remote`. Those two files are the spawn sites of the ordinary command
|
|
21
|
-
// modules — the claim stops there.
|
|
22
|
-
// (
|
|
23
|
-
//
|
|
24
|
-
// binary is resolved has to read
|
|
21
|
+
// modules — the claim stops there. A synchronous caller goes through `git-spawn-sync.ts`, the same
|
|
22
|
+
// binary resolution with a result instead of an exception (joshuafolkken/kit#3065). Other parts of
|
|
23
|
+
// this package spawn git for their own purposes (`scripts/run/run-progress-clock.ts`,
|
|
24
|
+
// `scripts/git/git-fixture-workspace.ts`), and an audit of how the git binary is resolved has to read
|
|
25
|
+
// those too.
|
|
25
26
|
|
|
26
27
|
async function read(arguments_: Array<string>): Promise<string> {
|
|
27
28
|
const git_cmd = git_utilities.get_git_command_for_spawn()
|
|
@@ -62,6 +62,7 @@ async function stage_untracked_files(files: ReadonlyArray<string>): Promise<void
|
|
|
62
62
|
if (files.length === 0) return
|
|
63
63
|
|
|
64
64
|
for (const file of files) {
|
|
65
|
+
// eslint-disable-next-line no-await-in-loop -- git add holds the index lock, so two at once fail
|
|
65
66
|
await git_command.add_path(file)
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { animation_helpers, type AnimationOptions } from '
|
|
1
|
+
import { animation_helpers, type AnimationOptions } from '#scripts/lib/animation-helpers'
|
|
2
2
|
import { REQUIRED_STATUS_LENGTH, STAGED_STATUS_INDEX, UNTRACKED_FILE_PREFIX } from './constants'
|
|
3
3
|
import { git_command } from './git-command'
|
|
4
4
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { parseArgs } from 'node:util'
|
|
3
|
+
import { git_pr } from '#scripts/gh/git-pr'
|
|
3
4
|
import { cli_body } from '#scripts/josh/cli-body'
|
|
4
5
|
import { test_red_commit } from '#scripts/test/test-red-commit'
|
|
5
6
|
import { git_branch } from './git-branch'
|
|
6
7
|
import { git_commit } from './git-commit'
|
|
7
8
|
import { git_error } from './git-error'
|
|
8
9
|
import { git_issue, type IssueInfo } from './git-issue'
|
|
9
|
-
import { git_pr } from './git-pr'
|
|
10
10
|
import { git_preflight } from './git-preflight'
|
|
11
11
|
import { git_prompt, type WorkflowConfirmations } from './git-prompt'
|
|
12
12
|
import { git_push } from './git-push'
|
|
@@ -89,6 +89,7 @@ async function delete_each(names: ReadonlyArray<string>): Promise<PruneResult> {
|
|
|
89
89
|
|
|
90
90
|
for (const name of names) {
|
|
91
91
|
try {
|
|
92
|
+
// eslint-disable-next-line no-await-in-loop -- branch deletions write the same refs, one at a time
|
|
92
93
|
await git_spawn.read(['branch', '-d', name])
|
|
93
94
|
result.deleted.push(name)
|
|
94
95
|
} catch {
|
|
@@ -114,7 +114,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
114
114
|
process.exitCode = await run(argv)
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
const main_merge = {
|
|
117
|
+
const main_merge = { run }
|
|
118
118
|
|
|
119
119
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
120
120
|
|
package/scripts/git/main-sync.ts
CHANGED
|
@@ -70,9 +70,27 @@ async function prune_quietly(default_branch: string): Promise<void> {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// **The local default branch is fast-forwarded before it is checked out** (joshuafolkken/kit#2979).
|
|
74
|
+
// A run's ledger file is committed on its feature branch and merged; a line appended afterwards leaves
|
|
75
|
+
// it dirty, and git refuses to check out a stale default branch that lacks the file — so `run:tail`'s
|
|
76
|
+
// sync failed exactly when the flush after it had work. Once fast-forwarded, the default branch holds
|
|
77
|
+
// the committed file and the checkout carries the dirty lines over (the same step the flush takes,
|
|
78
|
+
// joshuafolkken/kit#2462). Skipped on the default branch, where `fetch` refuses to update the checked-out
|
|
79
|
+
// ref; a refusal elsewhere — a local default ahead of origin — is left to the checkout and pull to judge.
|
|
80
|
+
async function fast_forward_quietly(default_branch: string): Promise<void> {
|
|
81
|
+
if ((await git_command.branch()) === default_branch) return
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
await git_command.fast_forward_local(default_branch)
|
|
85
|
+
} catch {
|
|
86
|
+
// The checkout and `pull --ff-only` below decide, exactly as before this step existed.
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
73
90
|
async function synchronize(): Promise<number> {
|
|
74
91
|
const default_branch = await git_command.get_default_branch()
|
|
75
92
|
|
|
93
|
+
await fast_forward_quietly(default_branch)
|
|
76
94
|
await git_command.checkout(default_branch)
|
|
77
95
|
await git_command.pull_fast_forward()
|
|
78
96
|
await prune_quietly(default_branch)
|
|
@@ -115,7 +133,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
115
133
|
process.exitCode = await run(argv)
|
|
116
134
|
}
|
|
117
135
|
|
|
118
|
-
const main_sync = {
|
|
136
|
+
const main_sync = { run }
|
|
119
137
|
|
|
120
138
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
121
139
|
|
|
@@ -2,7 +2,9 @@ import { randomUUID } from 'node:crypto'
|
|
|
2
2
|
import { linkSync, renameSync, rmSync } from 'node:fs'
|
|
3
3
|
import { setTimeout as sleep } from 'node:timers/promises'
|
|
4
4
|
import { process_identity } from '#scripts/josh/process-identity'
|
|
5
|
+
import { process_owner_schema, type ProcessOwner } from '#scripts/josh/process-owner'
|
|
5
6
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
7
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
6
8
|
import { git_common_directory } from './git-common-directory'
|
|
7
9
|
|
|
8
10
|
// One holder at a time per repository, for work that every work tree of that repository shares
|
|
@@ -14,32 +16,29 @@ import { git_common_directory } from './git-common-directory'
|
|
|
14
16
|
|
|
15
17
|
const POLL_INTERVAL_MS = 200
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
pid: number
|
|
19
|
-
process_start?: string
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
type IsGone = (owner: LockOwner) => boolean
|
|
19
|
+
type IsGone = (owner: ProcessOwner) => boolean
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
// Without a `cwd` the read keeps the inherited git location variables, as every other git call of the
|
|
22
|
+
// running process does; an explicit `cwd` clears them so that directory is the one answered for.
|
|
23
|
+
function lock_path(prefix: string, cwd?: string): string {
|
|
24
|
+
return stamp_file.stamp_path(prefix, git_common_directory.repository(cwd) ?? cwd ?? process.cwd())
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
// A record that is not JSON, or is JSON of any other shape — `null`, an array, an object with no
|
|
28
|
+
// numeric `pid` — is unreadable rather than an owner, so it is never judged and never cleared.
|
|
29
|
+
function parse_owner(raw: string | undefined): ProcessOwner | undefined {
|
|
29
30
|
if (raw === undefined) return undefined
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return undefined
|
|
35
|
-
}
|
|
32
|
+
const parsed = process_owner_schema.safeParse(json_value.parse_or_undefined(raw))
|
|
33
|
+
|
|
34
|
+
return parsed.success ? parsed.data : undefined
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
function read_owner(target: string):
|
|
37
|
+
function read_owner(target: string): ProcessOwner | undefined {
|
|
39
38
|
return parse_owner(stamp_file.read_stamp_text(target))
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
function is_owner_gone(owner:
|
|
41
|
+
function is_owner_gone(owner: ProcessOwner): boolean {
|
|
43
42
|
return process_identity.is_same_process(owner.pid, owner.process_start) === false
|
|
44
43
|
}
|
|
45
44
|
|
|
@@ -111,6 +110,7 @@ async function acquire(target: string, max_wait_ms: number): Promise<boolean> {
|
|
|
111
110
|
|
|
112
111
|
while (!claim(target)) {
|
|
113
112
|
if (Date.now() >= deadline) return false
|
|
113
|
+
// eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
|
|
114
114
|
await sleep(POLL_INTERVAL_MS)
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { git_spawn } from '
|
|
1
|
+
import { git_spawn } from '#scripts/git/git-spawn'
|
|
2
2
|
|
|
3
3
|
// The one place a sanctioned `git stash pop` is targeted by its message rather than its stack
|
|
4
4
|
// position (joshuafolkken/kit#2050). The stash is a single repository-wide stack shared by every
|
|
@@ -21,12 +21,7 @@ interface Request {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function read_arguments(argv: ReadonlyArray<string>): ParsedValues | undefined {
|
|
24
|
-
return cli_flags.
|
|
25
|
-
args: [...argv],
|
|
26
|
-
options: OPTIONS,
|
|
27
|
-
strict: true,
|
|
28
|
-
allowPositionals: true,
|
|
29
|
-
})
|
|
24
|
+
return cli_flags.arguments_of(argv, OPTIONS)
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
// The message is the sole positional and must be a non-empty string: an empty message matches every
|
|
@@ -47,7 +42,7 @@ function to_request(parsed: ParsedValues): Request | undefined {
|
|
|
47
42
|
return { message, dir: parsed.values.dir }
|
|
48
43
|
}
|
|
49
44
|
|
|
50
|
-
const stash_pop_args = { USAGE,
|
|
45
|
+
const stash_pop_args = { USAGE, read_arguments, to_request }
|
|
51
46
|
|
|
52
47
|
export type { Request }
|
|
53
48
|
export { stash_pop_args }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { repository_lock } from '
|
|
1
|
+
import { repository_lock } from '#scripts/git/repository-lock'
|
|
2
2
|
|
|
3
3
|
// One stash sweep at a time per repository (joshuafolkken/kit#2701). The stash is a single stack every
|
|
4
4
|
// work tree shares, and a `backlogrun` runs one sweep per lane seat at once: two sweeps that each
|
|
@@ -11,7 +11,7 @@ const LOCK_PREFIX = 'josh-stash-sweep-lock-'
|
|
|
11
11
|
// wait; the cap only bounds a holder that hung, and a sweep that gives up keeps its entries.
|
|
12
12
|
const MAX_WAIT_MS = 30_000
|
|
13
13
|
|
|
14
|
-
function lock_path(cwd
|
|
14
|
+
function lock_path(cwd?: string): string {
|
|
15
15
|
return repository_lock.lock_path(LOCK_PREFIX, cwd)
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -25,6 +25,6 @@ async function with_lock<T>(
|
|
|
25
25
|
return await repository_lock.with_lock(work, target, max_wait_ms)
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const stash_sweep_lock = { clear_stale: repository_lock.clear_stale,
|
|
28
|
+
const stash_sweep_lock = { clear_stale: repository_lock.clear_stale, with_lock }
|
|
29
29
|
|
|
30
30
|
export { stash_sweep_lock }
|
|
@@ -122,7 +122,7 @@ async function spelling_diagnostics(
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
const edited_cspell = { format_unknown_words,
|
|
125
|
+
const edited_cspell = { format_unknown_words, spelling_diagnostics }
|
|
126
126
|
|
|
127
127
|
export type { CspellRunner }
|
|
128
128
|
export { edited_cspell, MAX_DIAGNOSTIC_CHARS }
|
|
@@ -327,6 +327,7 @@ async function run_command(command: FormatCommand, project_root: string): Promis
|
|
|
327
327
|
let outcome: CommandOutcome = { exit_code: 0, stdout: '' }
|
|
328
328
|
|
|
329
329
|
for (const invocation of resolve_invocations(command, project_root)) {
|
|
330
|
+
// eslint-disable-next-line no-await-in-loop -- a fallback route runs only when the previous one failed to start
|
|
330
331
|
outcome = await spawn_invocation(invocation, project_root)
|
|
331
332
|
if (!is_start_failure(outcome)) return outcome
|
|
332
333
|
}
|
|
@@ -374,6 +375,7 @@ async function collect_unfixed(
|
|
|
374
375
|
|
|
375
376
|
for (const command of plan) {
|
|
376
377
|
try {
|
|
378
|
+
// eslint-disable-next-line no-await-in-loop -- formatters rewrite the same file, in plan order
|
|
377
379
|
unfixed = eslint_unfixed(command, await runner(command, project_root)) ?? unfixed
|
|
378
380
|
} catch {
|
|
379
381
|
// One formatter failing to start is not a reason to skip the next: prettier runs last, and
|
|
@@ -5,6 +5,7 @@ import { delivered_rules } from '#scripts/rules/delivered-rules'
|
|
|
5
5
|
import { run_parent_cut_hook } from '#scripts/run/run-parent-cut-hook'
|
|
6
6
|
import { run_watcher_hook } from '#scripts/run/run-watcher-hook'
|
|
7
7
|
import { batch_outcome } from './batch-guard'
|
|
8
|
+
import { step_zero_notice } from './step-zero-notice'
|
|
8
9
|
|
|
9
10
|
// One PreToolUse process for the three guards that used to be three (joshuafolkken/kit#1930). A Bash
|
|
10
11
|
// call used to spawn `batch:guard`, `investigation:guard` and `rule:guard` separately — three pnpm
|
|
@@ -49,10 +50,20 @@ function with_duplicate_notice(combined: GuardOutcome, notice: string | undefine
|
|
|
49
50
|
return { reason: undefined, notice, fault: undefined }
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
// The Step 0 reminder is the last word (joshuafolkken/kit#2994): asked only where every guard stayed
|
|
54
|
+
// clear, so a refusal or another notice never spends its once-per-session stamp unseen.
|
|
55
|
+
function with_step_zero_notice(outcome: GuardOutcome, raw_payload: string): GuardOutcome {
|
|
56
|
+
if (!is_clear(outcome)) return outcome
|
|
57
|
+
|
|
58
|
+
const notice = step_zero_notice.notice(raw_payload)
|
|
59
|
+
|
|
60
|
+
return notice === undefined ? outcome : { reason: undefined, notice, fault: undefined }
|
|
61
|
+
}
|
|
62
|
+
|
|
52
63
|
// All guards run unconditionally, exactly as the separate PreToolUse entries did: each records its own
|
|
53
64
|
// once-per-run stamp, so short-circuiting on the first refusal would change which guard is allowed to
|
|
54
65
|
// fire on a later call.
|
|
55
|
-
function
|
|
66
|
+
function guard_outcome(raw_payload: string): GuardOutcome {
|
|
56
67
|
const batch = batch_outcome(raw_payload)
|
|
57
68
|
const investigation = investigation_refusal(raw_payload)
|
|
58
69
|
const duplicate = duplicate_read_outcome(raw_payload)
|
|
@@ -63,6 +74,11 @@ function pretool_outcome(raw_payload: string): GuardOutcome {
|
|
|
63
74
|
return with_duplicate_notice(combined, duplicate.notice)
|
|
64
75
|
}
|
|
65
76
|
|
|
77
|
+
// The synchronous verdict the Codex adapter asks for, with the Step 0 reminder as its last layer.
|
|
78
|
+
function pretool_outcome(raw_payload: string): GuardOutcome {
|
|
79
|
+
return with_step_zero_notice(guard_outcome(raw_payload), raw_payload)
|
|
80
|
+
}
|
|
81
|
+
|
|
66
82
|
// The watcher guard is the one composed rule that cannot answer synchronously — it reads the lane
|
|
67
83
|
// registry and the watcher's life record off disk (joshuafolkken/kit#2353). So it is asked after the
|
|
68
84
|
// synchronous guards and only where they stayed clear: a refusal from any of them wins first, exactly
|
|
@@ -81,15 +97,17 @@ async function async_reason(raw_payload: string): Promise<string | undefined> {
|
|
|
81
97
|
}
|
|
82
98
|
|
|
83
99
|
async function pretool_outcome_async(raw_payload: string): Promise<GuardOutcome> {
|
|
84
|
-
const base =
|
|
100
|
+
const base = guard_outcome(raw_payload)
|
|
85
101
|
|
|
86
102
|
if (!is_clear(base)) return base
|
|
87
103
|
|
|
88
104
|
const reason = await async_reason(raw_payload)
|
|
89
105
|
|
|
90
|
-
|
|
106
|
+
if (reason !== undefined) return { reason, notice: undefined, fault: undefined }
|
|
107
|
+
|
|
108
|
+
return with_step_zero_notice(base, raw_payload)
|
|
91
109
|
}
|
|
92
110
|
|
|
93
|
-
const pretool_guard = { combine_outcomes, pretool_outcome
|
|
111
|
+
const pretool_guard = { combine_outcomes, pretool_outcome }
|
|
94
112
|
|
|
95
113
|
export { pretool_guard, pretool_outcome, pretool_outcome_async }
|
|
@@ -85,6 +85,6 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
|
85
85
|
process.exitCode = await run_reserved(process.argv.slice(FIRST_ARGUMENT_INDEX))
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const reserved_run = { parse_arguments,
|
|
88
|
+
const reserved_run = { parse_arguments, run_reserved }
|
|
89
89
|
|
|
90
90
|
export { reserved_run }
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { hook_decision } from '#scripts/josh/hook-decision'
|
|
3
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
4
|
+
import { test_declared_logic } from '#scripts/test/test-declared-logic'
|
|
5
|
+
|
|
6
|
+
// The Code Change Rules Step 0 reminder, delivered at the moment implementation code is about to be
|
|
7
|
+
// written rather than on every prompt (joshuafolkken/kit#2994). As a `UserPromptSubmit` echo it was
|
|
8
|
+
// injected into every turn — a question that writes nothing included — and re-read as accumulated
|
|
9
|
+
// context on each turn after it. The trigger the rule names is "before writing any implementation
|
|
10
|
+
// code", so the hook that delivers it is the one that sees that write: the first `Edit` / `Write` of a
|
|
11
|
+
// runtime file in the session.
|
|
12
|
+
//
|
|
13
|
+
// **A runtime file only.** What counts is `test_declared_logic.is_exempt`, the same classification
|
|
14
|
+
// `pnpm josh test:declared` answers at the commit, so a doc or prompt edit neither shows the notice nor
|
|
15
|
+
// spends it. A path outside the working tree (a memory file, a scratchpad) is not this project's code.
|
|
16
|
+
//
|
|
17
|
+
// **Once per session**, on a stamp keyed by the transcript like every other guard record here. A stamp
|
|
18
|
+
// that cannot be written stays silent rather than repeating the notice on every edit.
|
|
19
|
+
const STAMP_PREFIX = 'josh-step-zero-notice-'
|
|
20
|
+
const EDIT_TOOLS: ReadonlySet<string> = new Set(['Edit', 'Write'])
|
|
21
|
+
const PARENT_PREFIX = '..'
|
|
22
|
+
|
|
23
|
+
const NOTICE =
|
|
24
|
+
'Before writing any implementation code: present the two-layer work summary (Now / Change / Check, then every change with its test) once per Issue. Full rule: Code Change Rules Step 0 in CLAUDE.md.'
|
|
25
|
+
|
|
26
|
+
const STAMP = hook_decision.create_refusal_stamp(STAMP_PREFIX)
|
|
27
|
+
|
|
28
|
+
// A Codex `apply_patch` arrives translated with its first file as `file_path` and every file in
|
|
29
|
+
// `file_paths`, so a patch that leads with a doc and also writes code is still a runtime write.
|
|
30
|
+
function edited_paths(tool_input: unknown): Array<string> {
|
|
31
|
+
if (!json_value.is_record(tool_input)) return []
|
|
32
|
+
|
|
33
|
+
const { file_path, file_paths } = tool_input
|
|
34
|
+
const listed: ReadonlyArray<unknown> = Array.isArray(file_paths) ? file_paths : []
|
|
35
|
+
|
|
36
|
+
return [file_path, ...listed].filter(
|
|
37
|
+
(entry): entry is string => typeof entry === 'string' && entry.length > 0,
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function is_runtime_file(file_path: string, root: string): boolean {
|
|
42
|
+
const relative = path.relative(root, path.resolve(root, file_path))
|
|
43
|
+
|
|
44
|
+
if (relative.startsWith(PARENT_PREFIX) || path.isAbsolute(relative)) return false
|
|
45
|
+
|
|
46
|
+
return !test_declared_logic.is_exempt(relative.split(path.sep).join('/'))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function is_candidate(raw_payload: string, root: string): string | undefined {
|
|
50
|
+
const payload = hook_decision.parse_hook_payload(raw_payload)
|
|
51
|
+
|
|
52
|
+
if (payload === undefined || !EDIT_TOOLS.has(payload.tool_name)) return undefined
|
|
53
|
+
|
|
54
|
+
const has_runtime_file = edited_paths(payload.tool_input).some((file_path) =>
|
|
55
|
+
is_runtime_file(file_path, root),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
return has_runtime_file ? payload.transcript_path : undefined
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function notice(raw_payload: string, root: string = process.cwd()): string | undefined {
|
|
62
|
+
const transcript = is_candidate(raw_payload, root)
|
|
63
|
+
|
|
64
|
+
if (transcript === undefined) return undefined
|
|
65
|
+
|
|
66
|
+
const target = STAMP.path(transcript)
|
|
67
|
+
|
|
68
|
+
if (STAMP.last_ms(target) !== hook_decision.NEVER_MS) return undefined
|
|
69
|
+
if (!STAMP.record(target, Date.now())) return undefined
|
|
70
|
+
|
|
71
|
+
return NOTICE
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const step_zero_notice = { NOTICE, notice, stamp_path: STAMP.path }
|
|
75
|
+
|
|
76
|
+
export { step_zero_notice }
|
|
@@ -7,12 +7,15 @@ import { repo_party } from '#scripts/discovery/repo-party'
|
|
|
7
7
|
import { hook_decision } from '#scripts/josh/hook-decision'
|
|
8
8
|
import { session_language } from '#scripts/josh/session-language'
|
|
9
9
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
10
|
+
import { lane_handoff } from '#scripts/lane/lane-handoff'
|
|
10
11
|
import { filing_cap } from '#scripts/rules/filing-cap'
|
|
11
12
|
import { lane_background } from '#scripts/rules/lane-background'
|
|
12
13
|
import { lane_park } from '#scripts/rules/lane-park'
|
|
13
14
|
import { last_prompt } from '#scripts/rules/last-prompt'
|
|
14
15
|
import { stop_rules, type StopContext, type StopOutcome } from '#scripts/rules/stop-rules'
|
|
16
|
+
import { run_carry } from '#scripts/run/run-carry'
|
|
15
17
|
import { run_cut } from '#scripts/run/run-cut'
|
|
18
|
+
import { run_halfrun_resume } from '#scripts/run/run-halfrun-resume'
|
|
16
19
|
import { run_headless } from '#scripts/run/run-headless'
|
|
17
20
|
import { run_hold } from '#scripts/run/run-hold'
|
|
18
21
|
import { run_stranded_detect } from '#scripts/run/run-stranded-detect'
|
|
@@ -29,16 +32,17 @@ import { time_hook_transcript } from '#scripts/time-runtime/time-hook-transcript
|
|
|
29
32
|
// resolving (send the notify, release the hold) and `stop_hook_active` is the backstop, so failing
|
|
30
33
|
// open here costs at most a missed nudge, never a stuck run.
|
|
31
34
|
|
|
32
|
-
// The hold record for this working tree is still in place
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
+
// The hold record for this working tree is still in place, and whether it is a `prrun` stop's
|
|
36
|
+
// (joshuafolkken/kit#3023). `unreadable` reads as absent: the safe direction for a stop guard is not to
|
|
37
|
+
// block, and an unreadable record is not proof a run is holding.
|
|
38
|
+
async function hold_facts(): Promise<Pick<StopContext, 'hold_present' | 'prrun_stopped'>> {
|
|
35
39
|
const directory = await run_hold.worktree_directory()
|
|
40
|
+
const hold =
|
|
41
|
+
directory === undefined
|
|
42
|
+
? undefined
|
|
43
|
+
: run_halfrun_resume.hold_of(run_hold.read_hold(run_hold.hold_path(directory)))
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const read = run_hold.read_hold(run_hold.hold_path(directory))
|
|
40
|
-
|
|
41
|
-
return read.kind === 'held' || read.kind === 'stale'
|
|
45
|
+
return { hold_present: hold !== undefined, prrun_stopped: hold?.prrun_stop_head !== undefined }
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
// A `confirmation` notify sits on this run's transcript tail. The tail is derived exactly as the
|
|
@@ -67,7 +71,7 @@ async function build_context(
|
|
|
67
71
|
const tail = transcript_tail(transcript_path)
|
|
68
72
|
|
|
69
73
|
return {
|
|
70
|
-
|
|
74
|
+
...(await hold_facts()),
|
|
71
75
|
tree_clean: !(await run_hold.is_tree_dirty()),
|
|
72
76
|
notified: lane_park.mentions_confirmation_notify(tail),
|
|
73
77
|
message: payload_tail.message,
|
|
@@ -81,6 +85,7 @@ async function build_context(
|
|
|
81
85
|
lane_child: lane_child_marker.is_child_of(process.cwd()),
|
|
82
86
|
background_pending: lane_background.pending_background_ids(tail).length > 0,
|
|
83
87
|
agent_pending: lane_background.pending_agent_ids(tail).length > 0,
|
|
88
|
+
handed_off: lane_handoff.is_handed_off(process.cwd()),
|
|
84
89
|
session_lang: session_lang(),
|
|
85
90
|
}
|
|
86
91
|
}
|
|
@@ -106,22 +111,43 @@ async function outcome_of(raw_payload: string): Promise<StopOutcome> {
|
|
|
106
111
|
}
|
|
107
112
|
}
|
|
108
113
|
|
|
114
|
+
// A live carry record is in place — `carried` alone reads as a run. Both report checks below are about
|
|
115
|
+
// a carried run: the strand judge reads this very record and returns on anything but `carried`, and a
|
|
116
|
+
// stall needs a backlog driver, which begins one before its plan. A spent (`expired`) or `unreadable`
|
|
117
|
+
// record a crashed run left behind is no run either, so it does not re-arm the stall's backlog probe
|
|
118
|
+
// on every stop (joshuafolkken/kit#2995).
|
|
119
|
+
// A failed git read — outside a repository, `git rev-parse` exits non-zero — reads as no run, since this
|
|
120
|
+
// gate sits ahead of the checks' own swallowing and must not throw into the stop decision either.
|
|
121
|
+
async function has_run_record(): Promise<boolean> {
|
|
122
|
+
try {
|
|
123
|
+
const directory = await run_carry.repository_directory()
|
|
124
|
+
|
|
125
|
+
if (directory === undefined) return false
|
|
126
|
+
|
|
127
|
+
return run_carry.read_carry(run_carry.carry_path(directory)).kind === 'carried'
|
|
128
|
+
} catch {
|
|
129
|
+
return false
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The stall check rides the Stop hook because the stop *is* the loop boundary: a run alive but not
|
|
134
|
+
// advancing ends turns without dispatching (joshuafolkken/kit#2359). The strand check rides the same
|
|
135
|
+
// boundary and is the step before the stall (joshuafolkken/kit#2375): it fires when the driver is gone
|
|
136
|
+
// — the budget handed off, the owner dead, no supervisor watching. Both only report and swallow their
|
|
137
|
+
// own failures, so neither can change the stop decision. An ordinary stop with no run record skips
|
|
138
|
+
// both, so it pays one directory read rather than their reads and a stale stream's backlog probe.
|
|
139
|
+
async function run_report_checks(): Promise<void> {
|
|
140
|
+
if (!(await has_run_record())) return
|
|
141
|
+
|
|
142
|
+
await backlog_stalled_detect.run_stall_check(backlog_ready.DEFAULT_PORTS)
|
|
143
|
+
await run_stranded_detect.run_stranded_check()
|
|
144
|
+
}
|
|
145
|
+
|
|
109
146
|
// Nothing reaches stdout on an ordinary stop, so what the harness parses stays empty unless the stop
|
|
110
147
|
// is being held — all three rules block, so a bare `#N` is reported the same way (joshuafolkken/kit#2247).
|
|
111
148
|
async function write_stop_decision(raw_payload: string): Promise<void> {
|
|
112
149
|
hook_decision.load_environment_file()
|
|
113
|
-
|
|
114
|
-
// The stall check rides the Stop hook because the stop *is* the loop boundary: a run alive but not
|
|
115
|
-
// advancing ends turns without dispatching (joshuafolkken/kit#2359). It only reports — leaves a
|
|
116
|
-
// marker, sends a notification — and swallows its own failures, so it can never change the decision
|
|
117
|
-
// below or hold the stop.
|
|
118
|
-
await backlog_stalled_detect.run_stall_check(backlog_ready.DEFAULT_PORTS)
|
|
119
|
-
|
|
120
|
-
// The strand check rides the same boundary for the same reason, and is the step before the stall
|
|
121
|
-
// (joshuafolkken/kit#2375): the stall detector needs a live driver that could dispatch, and this one
|
|
122
|
-
// fires when that driver is gone — the budget handed off, the owner dead, no supervisor watching. It
|
|
123
|
-
// too only reports and swallows its own failures, so it never touches the stop decision below.
|
|
124
|
-
await run_stranded_detect.run_stranded_check()
|
|
150
|
+
await run_report_checks()
|
|
125
151
|
|
|
126
152
|
const { reason } = await outcome_of(raw_payload)
|
|
127
153
|
|