@joshuafolkken/kit 1.1784.0 → 1.2114.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/agents/reviewer-verification.md +19 -0
- package/.claude/agents/reviewer.md +19 -0
- package/.claude/settings.json +5 -6
- package/.claude/skills/dependency-update/SKILL.md +9 -10
- package/.claude/skills/workflow-commands/SKILL.md +6 -6
- package/.claude/skills/workflow-commands/background-commands.md +8 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +41 -32
- package/.claude/skills/workflow-commands/delegation.md +6 -6
- package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
- package/.claude/skills/workflow-commands/followup.md +7 -5
- package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
- package/.claude/skills/workflow-commands/fullrun.md +1 -1
- package/.claude/skills/workflow-commands/issue-comments.md +9 -4
- package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
- package/.claude/skills/workflow-commands/kickoff.md +2 -2
- package/.claude/skills/workflow-commands/observation-filing.md +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
- package/.claude/skills/workflow-commands/prerequisite.md +3 -2
- package/.claude/skills/workflow-commands/retrospective.md +2 -2
- package/.claude/skills/workflow-commands/split-assessment.md +7 -5
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-pnpm/action.yml +9 -16
- package/.github/dependabot.yml +16 -0
- package/.github/workflows/auto-tag.yml +45 -0
- package/.github/workflows/ci.yml +155 -15
- package/.github/workflows/dependabot-auto-merge.yml +63 -4
- package/.github/workflows/production.yml +8 -0
- package/.github/workflows/publish.yml +59 -45
- package/.vscode/settings.json +19 -0
- package/CLAUDE.md +5 -12
- package/SECURITY.md +2 -2
- package/dist/CLAUDE.md +5 -12
- package/dist/commands/document-read-cli.js +2 -1
- package/dist/commands/document-section-main.js +2 -1
- package/dist/commands/read-set-cli.js +194 -134
- package/dist/commands/run-prep-main.js +9694 -10173
- package/dist/commands/run-step-cli.js +22138 -18285
- package/dist/hooks/audit-provision.js +23 -5
- package/dist/hooks/chunk-3GKE653K.js +6204 -0
- package/dist/hooks/chunk-45CJJOO7.js +1243 -0
- package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
- package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
- package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
- package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
- package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
- package/dist/hooks/chunk-VVNYJWEI.js +30 -0
- package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
- package/dist/hooks/codex-hook-adapter.js +8 -8
- package/dist/hooks/format-edited.js +4 -5
- package/dist/hooks/inputs.json +415 -389
- package/dist/hooks/pretool-guard.js +7 -6
- package/dist/hooks/session-lang.js +101 -258
- package/dist/hooks/stop-guard.js +1744 -2576
- package/dist/josh.js +7133 -6368
- package/dist/version/index.js +161 -1
- package/eslint/rules/comment-why-only.js +108 -0
- package/package.json +15 -8
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +14 -11
- package/prompts/collaboration-workflow/issue-citation.md +0 -4
- package/prompts/collaboration-workflow/issue-template.md +40 -21
- package/prompts/collaboration-workflow/lane-instructions.md +3 -1
- package/prompts/collaboration-workflow/measurement.md +8 -1
- package/prompts/collaboration-workflow/operating-rules.md +11 -2
- package/prompts/collaboration-workflow/output-bounds.md +6 -2
- package/prompts/collaboration-workflow/plan-comment.md +1 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow/residency.md +3 -2
- package/prompts/collaboration-workflow/rule-delivery.md +13 -1
- package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
- package/prompts/collaboration-workflow/wip-cap.md +3 -1
- package/prompts/review-rubric.md +8 -0
- package/prompts/review.md +31 -22
- package/prompts/testing-guide.md +1 -0
- package/scripts/agent/agent-argv.ts +14 -16
- package/scripts/agent/agent-provider.ts +138 -0
- package/scripts/agent/agent-role-profile.ts +108 -156
- package/scripts/agent/agent-safe-text.ts +20 -5
- package/scripts/agent/api-usage-limit.ts +65 -0
- package/scripts/agent/claude-agent-argv.ts +19 -9
- package/scripts/agent/codex-agent-argv.ts +118 -22
- package/scripts/agent/usage-limit-reset.ts +179 -0
- package/scripts/auth/claude-token-output.ts +2 -2
- package/scripts/auto-ok/auto-ok-author.ts +53 -0
- package/scripts/auto-ok/auto-ok-cli.ts +20 -9
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-cli.ts +6 -1
- package/scripts/backlog/backlog-drive-hold.ts +3 -3
- package/scripts/backlog/backlog-drive-idle.ts +10 -0
- package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
- package/scripts/backlog/backlog-drive-launch.ts +8 -2
- package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
- package/scripts/backlog/backlog-drive-named.ts +28 -7
- package/scripts/backlog/backlog-drive-paused.ts +5 -4
- package/scripts/backlog/backlog-drive-restore.ts +11 -3
- package/scripts/backlog/backlog-drive.ts +21 -60
- package/scripts/backlog/backlog-gate-scope.ts +61 -0
- package/scripts/backlog/backlog-measure-close.ts +112 -0
- package/scripts/backlog/backlog-next.ts +39 -49
- package/scripts/backlog/backlog-occupied.ts +2 -2
- package/scripts/backlog/backlog-overlap.ts +42 -8
- package/scripts/backlog/backlog-plan-cli.ts +4 -1
- package/scripts/backlog/backlog-plan-comment.ts +81 -0
- package/scripts/backlog/backlog-plan-read.ts +19 -6
- package/scripts/backlog/backlog-pool.ts +50 -12
- package/scripts/backlog/backlog-rank.ts +60 -13
- package/scripts/backlog/backlog-stalled-detect.ts +2 -1
- package/scripts/backlog/backlog-waves.ts +17 -2
- package/scripts/backlog/backlogrun-launch.ts +7 -4
- package/scripts/cost-runtime/context-cut-payback.ts +27 -25
- package/scripts/cost-runtime/cost-cli.ts +37 -16
- package/scripts/cost-runtime/cost-pricing.ts +9 -0
- package/scripts/cost-runtime/cost-verdict.ts +4 -1
- package/scripts/delegation/delegation-policy.ts +2 -2
- package/scripts/delegation/duplicate-read-guard.ts +1 -0
- package/scripts/delegation/investigation-guard.ts +14 -2
- package/scripts/delegation/investigation-reads.ts +45 -23
- package/scripts/dependabot/dependabot-cooldown.ts +3 -2
- package/scripts/discovery/repo-party.ts +80 -20
- package/scripts/discovery/session-owner-pin.ts +51 -0
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/command-reference-line-budget.ts +42 -0
- package/scripts/document/document-byte-budget.ts +17 -7
- package/scripts/document/document-checks.ts +20 -0
- package/scripts/document/document-ratchet-check.ts +101 -0
- package/scripts/document/document-section.ts +1 -0
- package/scripts/document/entry-read-budget.ts +7 -3
- package/scripts/document/issue-citation-budget.ts +94 -0
- package/scripts/epic/epic-cli-argv.ts +2 -2
- package/scripts/epic/epic-fetch.ts +4 -2
- package/scripts/epic/epic-graph.ts +7 -2
- package/scripts/epic/epic-issue.ts +3 -1
- package/scripts/epic/epic-rank.ts +5 -0
- package/scripts/exports/unused-members-check.ts +62 -0
- package/scripts/exports/unused-members-cli.ts +6 -51
- package/scripts/followup/followup-ci-path.ts +67 -0
- package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
- package/scripts/followup/followup-coderabbit-wait.ts +13 -10
- package/scripts/followup/followup-failed-tests.ts +160 -0
- package/scripts/followup/followup-job-needs.ts +100 -0
- package/scripts/followup/followup-job-rerun.ts +303 -0
- package/scripts/followup/followup-main-move.ts +113 -0
- package/scripts/followup/git-followup-finish.ts +43 -11
- package/scripts/followup/git-followup-pending.ts +3 -3
- package/scripts/followup/git-followup-stages.ts +41 -11
- package/scripts/followup/git-pr-followup-checks.ts +55 -16
- package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
- package/scripts/followup/git-pr-followup.ts +62 -27
- package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
- package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
- package/scripts/gate/busy-average.ts +34 -2
- package/scripts/gate/check-related-pinned.ts +43 -0
- package/scripts/gate/check-related-reuse.ts +64 -0
- package/scripts/gate/check-related-section.ts +57 -0
- package/scripts/gate/check-related-unplanned.ts +34 -0
- package/scripts/gate/check-related.ts +265 -0
- package/scripts/gate/command-memory.ts +1 -1
- package/scripts/gate/core-admission.ts +24 -6
- package/scripts/gate/core-budget-timing.ts +20 -6
- package/scripts/gate/core-budget.ts +40 -11
- package/scripts/gate/core-wait-record.ts +3 -2
- package/scripts/gate/core-wait.ts +25 -2
- package/scripts/gate/core-weights.ts +15 -7
- package/scripts/gate/gate-labels.ts +46 -0
- package/scripts/gate/gate-ledger.ts +14 -6
- package/scripts/gate/gate-plan.ts +103 -58
- package/scripts/gate/gate-report.ts +9 -7
- package/scripts/gate/gate-run-steps.ts +26 -3
- package/scripts/gate/gate-skip.ts +45 -6
- package/scripts/gate/gate-static-group.ts +60 -0
- package/scripts/gate/gate-steps.ts +2 -1
- package/scripts/gate/gate-tree.ts +4 -2
- package/scripts/gate/hook-gate-reuse.ts +19 -2
- package/scripts/gate/metrics-totals.ts +59 -0
- package/scripts/gate/scoped-green.ts +68 -15
- package/scripts/gate/since-green.ts +14 -6
- package/scripts/gate/structural-checks.ts +96 -0
- package/scripts/gate/verification-gate.ts +51 -16
- package/scripts/gate/verification-inputs.ts +21 -6
- package/scripts/gate/verification-tail.ts +52 -0
- package/scripts/gh/gh-author-association.ts +23 -2
- package/scripts/gh/git-ai-review-scan.ts +1 -1
- package/scripts/gh/git-gh-api-path.ts +12 -3
- package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
- package/scripts/gh/git-gh-exec.ts +32 -2
- package/scripts/gh/git-gh-issue-read.ts +4 -2
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +8 -2
- package/scripts/gh/git-gh-issue.ts +12 -5
- package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
- package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
- package/scripts/gh/git-gh-pr-read.ts +74 -13
- package/scripts/gh/git-gh-pr-rest.ts +3 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
- package/scripts/gh/git-gh-pr-too-large.ts +20 -0
- package/scripts/gh/git-gh-pr.ts +21 -7
- package/scripts/gh/git-gh-retry.ts +141 -0
- package/scripts/gh/git-pr-ai-review.ts +15 -6
- package/scripts/gh/git-pr-checks-eval.ts +3 -0
- package/scripts/gh/git-pr-checks.ts +5 -5
- package/scripts/git/base-tree.ts +30 -0
- package/scripts/git/change-base.ts +4 -10
- package/scripts/git/changed-paths-sync.ts +63 -0
- package/scripts/git/changed-paths.ts +16 -1
- package/scripts/git/git-common-directory.ts +11 -1
- package/scripts/git/git-diff-reads.ts +66 -20
- package/scripts/git/git-error.ts +9 -2
- package/scripts/git/git-schemas.ts +13 -0
- package/scripts/git/git-worktree.ts +13 -0
- package/scripts/git/gone-branch.ts +4 -1
- package/scripts/git/main-merge-budget-conflict.ts +89 -0
- package/scripts/git/main-merge-guard.ts +55 -18
- package/scripts/git/main-merge-regenerate.ts +59 -25
- package/scripts/git/main-merge.ts +53 -5
- package/scripts/git/no-base-checkout.ts +127 -0
- package/scripts/git/stash/git-stash.ts +11 -2
- package/scripts/git/stash/stash-push-cli.ts +10 -0
- package/scripts/hooks/batch-guard.ts +40 -21
- package/scripts/hooks/edited-cspell.ts +37 -11
- package/scripts/hooks/format-edited-file.ts +22 -2
- package/scripts/hooks/lane-plan-guard.ts +50 -0
- package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
- package/scripts/hooks/pre-commit-lint.ts +14 -1
- package/scripts/hooks/pre-push-related-switch.ts +10 -0
- package/scripts/hooks/pre-push-unit.ts +76 -10
- package/scripts/hooks/pretool-guard.ts +2 -0
- package/scripts/hooks/reserved-run.ts +14 -1
- package/scripts/hooks/run-hook.sh +23 -8
- package/scripts/hooks/step-zero-notice.ts +6 -1
- package/scripts/hooks/stop-actions.ts +3 -15
- package/scripts/hooks/stop-guard.ts +7 -6
- package/scripts/init/distributed-paths.ts +1 -0
- package/scripts/init/hook-command-rewrite.ts +5 -1
- package/scripts/init/hook-launch.ts +4 -2
- package/scripts/issue/aggregation-split.ts +52 -0
- package/scripts/issue/defect-origin-line.ts +19 -1
- package/scripts/issue/defect-rate-cli.ts +5 -102
- package/scripts/issue/defect-report.ts +4 -4
- package/scripts/issue/effect-audit-cli.ts +178 -0
- package/scripts/issue/effect-audit.ts +185 -0
- package/scripts/issue/expected-effect-lint.ts +64 -9
- package/scripts/issue/git-next-issues.ts +5 -0
- package/scripts/issue/issue-body-or-comment.ts +38 -4
- package/scripts/issue/issue-cite-cli.ts +1 -3
- package/scripts/issue/issue-classification.ts +1 -0
- package/scripts/issue/issue-closing-pr.ts +8 -1
- package/scripts/issue/issue-evidence-exit.ts +4 -2
- package/scripts/issue/issue-file-cap.ts +58 -0
- package/scripts/issue/issue-file-cli.ts +111 -38
- package/scripts/issue/issue-file-deferral.ts +52 -0
- package/scripts/issue/issue-file-fold.ts +29 -10
- package/scripts/issue/issue-file-interrupt.ts +85 -0
- package/scripts/issue/issue-file-lane-hint.ts +30 -0
- package/scripts/issue/issue-file.ts +43 -6
- package/scripts/issue/issue-labels.ts +19 -2
- package/scripts/issue/issue-lint-cli.ts +27 -2
- package/scripts/issue/issue-measured-cli.ts +13 -35
- package/scripts/issue/issue-measured-close.ts +58 -0
- package/scripts/issue/issue-not-before-label.ts +2 -2
- package/scripts/issue/issue-not-before.ts +4 -1
- package/scripts/issue/issue-priority-cli.ts +60 -0
- package/scripts/issue/issue-priority-raise.ts +55 -0
- package/scripts/issue/issue-priority.ts +174 -43
- package/scripts/issue/issue-rank.ts +21 -4
- package/scripts/issue/issue-read-cli.ts +32 -6
- package/scripts/issue/issue-read.ts +37 -12
- package/scripts/issue/issue-sample-gate.ts +95 -74
- package/scripts/issue/issue-sample-prime.ts +127 -0
- package/scripts/issue/issue-sample-required.ts +57 -0
- package/scripts/issue/issue-sample-source.ts +12 -11
- package/scripts/issue/issue-search.ts +124 -0
- package/scripts/issue/issue-state.ts +13 -1
- package/scripts/issue/issue-template-section.ts +43 -0
- package/scripts/issue/issue-watch-diff.ts +31 -1
- package/scripts/issue/issue-watch-hook.ts +11 -2
- package/scripts/issue/issue-watch.ts +55 -12
- package/scripts/issue/markdown-section.ts +1 -0
- package/scripts/issue/measure-declaration.ts +121 -0
- package/scripts/issue/measure-rerun-cli.ts +7 -70
- package/scripts/issue/plan-consumers-section.ts +22 -1
- package/scripts/issue/reproduction-measure.ts +3 -1
- package/scripts/issue/size-estimate.ts +90 -0
- package/scripts/issue/trusted-measure.ts +84 -0
- package/scripts/josh/command-usage.ts +3 -2
- package/scripts/josh/durable-state-migrate.ts +105 -0
- package/scripts/josh/durable-state.ts +112 -0
- package/scripts/josh/josh-aliases.ts +95 -0
- package/scripts/josh/josh-command-map.ts +1 -82
- package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
- package/scripts/josh/josh-commands-ai.ts +5 -5
- package/scripts/josh/josh-commands-development.ts +59 -58
- package/scripts/josh/josh-commands-issue-write.ts +23 -4
- package/scripts/josh/josh-commands-issue.ts +32 -0
- package/scripts/josh/josh-commands-lane.ts +87 -4
- package/scripts/josh/josh-commands-lint.ts +16 -3
- package/scripts/josh/josh-commands-maintenance.ts +15 -0
- package/scripts/josh/josh-commands-review.ts +41 -6
- package/scripts/josh/josh-commands-ship.ts +56 -8
- package/scripts/josh/josh-commands-test-check.ts +80 -0
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/josh/josh-environment-file.ts +43 -3
- package/scripts/josh/josh-in-process.ts +2 -2
- package/scripts/josh/josh-logic.ts +5 -3
- package/scripts/josh/josh-run.ts +19 -1
- package/scripts/josh/run-record-path.ts +15 -0
- package/scripts/josh/stamp-file.ts +11 -2
- package/scripts/lane/lane-adopt-cli.ts +98 -0
- package/scripts/lane/lane-adopt.ts +208 -0
- package/scripts/lane/lane-await.ts +5 -8
- package/scripts/lane/lane-baseline.ts +123 -0
- package/scripts/lane/lane-breakdown-cli.ts +64 -0
- package/scripts/lane/lane-breakdown-implement.ts +170 -0
- package/scripts/lane/lane-breakdown-laps.ts +107 -0
- package/scripts/lane/lane-breakdown-pinned.ts +76 -0
- package/scripts/lane/lane-breakdown-text.ts +145 -0
- package/scripts/lane/lane-breakdown.ts +239 -0
- package/scripts/lane/lane-check-stats.ts +29 -8
- package/scripts/lane/lane-child-invocation.ts +9 -2
- package/scripts/lane/lane-child-mark-keys.ts +12 -0
- package/scripts/lane/lane-child-marker.ts +20 -1
- package/scripts/lane/lane-ci-path-stats.ts +73 -0
- package/scripts/lane/lane-claim-stats.ts +84 -0
- package/scripts/lane/lane-close.ts +8 -3
- package/scripts/lane/lane-dispatch-log.ts +3 -3
- package/scripts/lane/lane-dispatch.ts +2 -2
- package/scripts/lane/lane-gap-stats.ts +7 -6
- package/scripts/lane/lane-guard-policy.ts +7 -1
- package/scripts/lane/lane-implement-stats.ts +207 -0
- package/scripts/lane/lane-implement-subagents.ts +90 -0
- package/scripts/lane/lane-investigation-switch.ts +16 -0
- package/scripts/lane/lane-ledger-kind.ts +31 -0
- package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
- package/scripts/lane/lane-ledger-schema.ts +119 -36
- package/scripts/lane/lane-ledger-write.ts +257 -0
- package/scripts/lane/lane-ledger.ts +31 -177
- package/scripts/lane/lane-load.ts +1 -1
- package/scripts/lane/lane-measure-cli.ts +176 -59
- package/scripts/lane/lane-net-read.ts +44 -0
- package/scripts/lane/lane-net-time.ts +212 -0
- package/scripts/lane/lane-open.ts +16 -7
- package/scripts/lane/lane-output.ts +2 -4
- package/scripts/lane/lane-overrun-prompt.ts +147 -0
- package/scripts/lane/lane-overrun.ts +274 -0
- package/scripts/lane/lane-paths.ts +24 -1
- package/scripts/lane/lane-pause-cli.ts +4 -1
- package/scripts/lane/lane-paused-spans.ts +97 -0
- package/scripts/lane/lane-plan-check.ts +207 -0
- package/scripts/lane/lane-plan-cli.ts +41 -0
- package/scripts/lane/lane-plan.ts +144 -0
- package/scripts/lane/lane-registry.ts +14 -1
- package/scripts/lane/lane-relaunch.ts +1 -1
- package/scripts/lane/lane-round-one-stats.ts +51 -0
- package/scripts/lane/lane-sampler.ts +23 -4
- package/scripts/lane/lane-session-action.ts +93 -18
- package/scripts/lane/lane-session-broker.ts +49 -21
- package/scripts/lane/lane-session-reread-main.ts +14 -0
- package/scripts/lane/lane-session-reread.ts +51 -0
- package/scripts/lane/lane-ship-lap-stats.ts +74 -0
- package/scripts/lane/lane-sleep.ts +58 -0
- package/scripts/lane/lane-spent.ts +1 -1
- package/scripts/lane/lane-split-stats.ts +28 -0
- package/scripts/lane/lane-stage-stats.ts +13 -1
- package/scripts/lane/lane-state.ts +41 -9
- package/scripts/lane/lane-stats-tables.ts +58 -0
- package/scripts/lane/lane-stats.ts +21 -5
- package/scripts/lane/lane-stop-stats.ts +51 -19
- package/scripts/lane/lane-tail-stats.ts +32 -0
- package/scripts/lane/lane-transcript-calls.ts +67 -10
- package/scripts/lane/lane-transcript-stats.ts +44 -12
- package/scripts/lane/lane-value-cell.ts +72 -0
- package/scripts/lane/lane-value.ts +118 -0
- package/scripts/lane/lane-withdraw-closed.ts +124 -0
- package/scripts/lane/lane-withdraw.ts +108 -31
- package/scripts/lane/lane-yield.ts +85 -0
- package/scripts/lane/openai-lane-ship.ts +12 -11
- package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
- package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
- package/scripts/lane/openai-lane-supervisor.ts +5 -4
- package/scripts/lib/poll.ts +38 -9
- package/scripts/lib/settled-together.ts +10 -0
- package/scripts/lib/shell-quote.ts +21 -0
- package/scripts/lib/token-shape.ts +111 -0
- package/scripts/lint/eslint-daemon-sources.ts +79 -0
- package/scripts/lint/eslint-daemon.ts +45 -6
- package/scripts/lint/eslint-warm-cli.ts +7 -0
- package/scripts/lint/eslint-warm.ts +66 -0
- package/scripts/lint/import-graph.ts +141 -11
- package/scripts/lint/lint-gate-scope.ts +2 -2
- package/scripts/lint/lint-parallel.ts +54 -6
- package/scripts/lint/lint-related.ts +154 -33
- package/scripts/lint/rename-cli.ts +179 -0
- package/scripts/lint/rename-identifier.ts +192 -0
- package/scripts/lint/type-only-imports.ts +58 -0
- package/scripts/notify/telegram-notify.ts +12 -3
- package/scripts/observations/observation-record.ts +42 -16
- package/scripts/observations/observations-flush.ts +32 -9
- package/scripts/overrides/overrides-check.ts +9 -1
- package/scripts/release/release-approval-prune.ts +7 -1
- package/scripts/repo/required-checks-logic.ts +4 -1
- package/scripts/repo/ruleset-check.ts +4 -3
- package/scripts/report/markdown-shape.ts +28 -0
- package/scripts/report/report-format-reference.ts +15 -1
- package/scripts/report/report-labels.ts +12 -1
- package/scripts/report/report-lint-child-summary.ts +94 -0
- package/scripts/report/report-lint-cli.ts +26 -7
- package/scripts/report/report-lint.ts +2 -20
- package/scripts/review/prose-stale-cli.ts +88 -0
- package/scripts/review/prose-stale-scan.ts +152 -0
- package/scripts/review/review-attest.ts +73 -23
- package/scripts/review/review-brief-cli.ts +68 -19
- package/scripts/review/review-brief-paths.ts +22 -0
- package/scripts/review/review-brief.ts +14 -7
- package/scripts/review/review-comment-carry.ts +47 -0
- package/scripts/review/review-comment-round.ts +85 -22
- package/scripts/review/review-finding-ledger.ts +109 -7
- package/scripts/review/review-finding-text.ts +43 -0
- package/scripts/review/review-interaction.ts +11 -0
- package/scripts/review/review-lane-handover.ts +68 -0
- package/scripts/review/review-lint-cli.ts +57 -0
- package/scripts/review/review-lint-findings.ts +92 -0
- package/scripts/review/review-lint-sections.ts +80 -0
- package/scripts/review/review-lint.ts +221 -0
- package/scripts/review/review-prior-findings.ts +102 -0
- package/scripts/review/review-readers-scan.ts +4 -2
- package/scripts/review/review-record-cli.ts +177 -54
- package/scripts/review/review-record-code-round.ts +55 -0
- package/scripts/review/review-record-comment.ts +60 -0
- package/scripts/review/review-record-interaction.ts +35 -0
- package/scripts/review/review-record-pinned.ts +108 -0
- package/scripts/review/review-record.ts +25 -1
- package/scripts/review/review-reviewed-tree.ts +307 -0
- package/scripts/review/review-round-one-closure.ts +62 -0
- package/scripts/review/review-round-reuse.ts +106 -0
- package/scripts/review/review-round2-cli.ts +91 -29
- package/scripts/review/review-round2-skip-comment.ts +55 -0
- package/scripts/review/review-round2.ts +24 -8
- package/scripts/review/review-stamps.ts +7 -3
- package/scripts/review/review-stop-log.ts +20 -6
- package/scripts/review/review-stops-cli.ts +2 -1
- package/scripts/review/review-submit-cli.ts +101 -0
- package/scripts/rules/agent-model.ts +1 -1
- package/scripts/rules/bash-triggers.ts +3 -3
- package/scripts/rules/concise-reply.ts +88 -0
- package/scripts/rules/credential-body.ts +77 -0
- package/scripts/rules/decision-oracle.ts +1 -1
- package/scripts/rules/delivered-rules.ts +36 -17
- package/scripts/rules/destructive-command.ts +3 -11
- package/scripts/rules/direct-issue-comment.ts +34 -12
- package/scripts/rules/direct-issue-read.ts +191 -0
- package/scripts/rules/direct-pr-create.ts +4 -24
- package/scripts/rules/early-heartbeat.ts +2 -0
- package/scripts/rules/edit-tool.ts +27 -0
- package/scripts/rules/file-edit-rows.ts +17 -0
- package/scripts/rules/file-rewrite.ts +146 -0
- package/scripts/rules/firing-point.ts +3 -2
- package/scripts/rules/gh-api.ts +128 -7
- package/scripts/rules/gh-repo-selector.ts +84 -0
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/guard-remedy.ts +14 -5
- package/scripts/rules/implementation-cut.ts +61 -28
- package/scripts/rules/investigator-foreground.ts +231 -0
- package/scripts/rules/issue-citation.ts +15 -60
- package/scripts/rules/issue-comments.ts +9 -4
- package/scripts/rules/josh-git-bare.ts +1 -1
- package/scripts/rules/lane-background.ts +41 -13
- package/scripts/rules/lane-direct-tool.ts +107 -9
- package/scripts/rules/lane-interactive-ask.ts +4 -1
- package/scripts/rules/lane-park.ts +4 -2
- package/scripts/rules/lane-spilled-read.ts +90 -0
- package/scripts/rules/lane-split-park.ts +1 -1
- package/scripts/rules/lane-switch-main.ts +4 -4
- package/scripts/rules/last-prompt.ts +20 -47
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/permission-guards.ts +5 -1
- package/scripts/rules/piped-verification-shapes.ts +110 -0
- package/scripts/rules/piped-verification.ts +67 -17
- package/scripts/rules/poll-loop.ts +72 -9
- package/scripts/rules/pr-merge.ts +5 -5
- package/scripts/rules/pre-gate-cut.ts +3 -3
- package/scripts/rules/protected-files.ts +88 -24
- package/scripts/rules/reply-language.ts +3 -17
- package/scripts/rules/reply-prose.ts +34 -0
- package/scripts/rules/repo-admin.ts +132 -0
- package/scripts/rules/reviewer-foreground.ts +88 -0
- package/scripts/rules/round-one-check-related.ts +120 -0
- package/scripts/rules/rule-body-guard.ts +5 -15
- package/scripts/rules/rule-value-cache.ts +53 -5
- package/scripts/rules/rule-value-candidates.ts +84 -0
- package/scripts/rules/rule-value-cli.ts +59 -11
- package/scripts/rules/rule-value.ts +17 -4
- package/scripts/rules/run-tail-rule.ts +1 -1
- package/scripts/rules/sed-in-place.ts +196 -0
- package/scripts/rules/shell-segments.ts +10 -2
- package/scripts/rules/stop-rule-rows.ts +1 -13
- package/scripts/rules/stop-rules.ts +33 -58
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +110 -23
- package/scripts/rules/timed-rerun.ts +1 -1
- package/scripts/rules/turn-filings.ts +90 -0
- package/scripts/rules/worktree-guard.ts +22 -7
- package/scripts/run/board/run-board-ending-reason.ts +6 -2
- package/scripts/run/board/run-board-fit.ts +24 -1
- package/scripts/run/board/run-board-found.ts +134 -0
- package/scripts/run/board/run-board-header.ts +8 -0
- package/scripts/run/board/run-board-labels.ts +11 -1
- package/scripts/run/board/run-board-lane-time.ts +1 -0
- package/scripts/run/board/run-board-link.ts +15 -2
- package/scripts/run/board/run-board-notes.ts +7 -1
- package/scripts/run/board/run-board-operation.ts +4 -2
- package/scripts/run/board/run-board-phase.ts +2 -5
- package/scripts/run/board/run-board-plan.ts +1 -1
- package/scripts/run/board/run-board-read.ts +46 -1
- package/scripts/run/board/run-board-reason.ts +20 -8
- package/scripts/run/board/run-board-render-checks.ts +3 -2
- package/scripts/run/board/run-board-render-drawn.ts +11 -0
- package/scripts/run/board/run-board-render-found.ts +157 -0
- package/scripts/run/board/run-board-render-lead.ts +9 -0
- package/scripts/run/board/run-board-render-legend.ts +19 -0
- package/scripts/run/board/run-board-render-tail.ts +1 -1
- package/scripts/run/board/run-board-render.ts +82 -18
- package/scripts/run/board/run-board-spin.ts +1 -3
- package/scripts/run/board/run-board-status.ts +2 -0
- package/scripts/run/board/run-board-tick.ts +39 -10
- package/scripts/run/carry/run-carry-ended.ts +3 -2
- package/scripts/run/carry/run-carry.ts +3 -2
- package/scripts/run/cut/run-cut-cli.ts +33 -133
- package/scripts/run/cut/run-cut-digest.ts +152 -0
- package/scripts/run/cut/run-cut-handoff.ts +52 -8
- package/scripts/run/cut/run-cut-report.ts +24 -3
- package/scripts/run/cut/run-cut-resume.ts +129 -0
- package/scripts/run/cut/run-cut-review.ts +105 -0
- package/scripts/run/cut/run-cut.ts +18 -7
- package/scripts/run/detached-launch.ts +1 -1
- package/scripts/run/entry/run-entry-cli.ts +88 -19
- package/scripts/run/entry/run-entry-spill.ts +83 -0
- package/scripts/run/entry/run-entry-stop.ts +5 -1
- package/scripts/run/entry/run-entry-trust.ts +91 -0
- package/scripts/run/event/run-event-baseline.ts +56 -0
- package/scripts/run/event/run-event-filed.ts +9 -3
- package/scripts/run/event/run-event-overrun.ts +197 -0
- package/scripts/run/event/run-event-render.ts +4 -0
- package/scripts/run/event/run-event-stream.ts +25 -3
- package/scripts/run/hold/run-stop-notify.ts +3 -8
- package/scripts/run/merge/run-merge-cap.ts +57 -0
- package/scripts/run/merge/run-merge-cli.ts +66 -23
- package/scripts/run/merge/run-merge-outcome.ts +2 -0
- package/scripts/run/merge/run-merge-ship.ts +13 -3
- package/scripts/run/merge/run-merge-signals.ts +40 -23
- package/scripts/run/merge/run-merge-steps.ts +56 -36
- package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
- package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
- package/scripts/run/merge/run-merge.ts +41 -14
- package/scripts/run/review/run-review-cli.ts +306 -20
- package/scripts/run/review/run-review-early-push.ts +121 -0
- package/scripts/run/review/run-review-join-read.ts +94 -0
- package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
- package/scripts/run/review/run-review-pinned-join.ts +216 -0
- package/scripts/run/review/run-review-pinned-steps.ts +383 -0
- package/scripts/run/review/run-review-pinned-tree.ts +37 -0
- package/scripts/run/review/run-review-pinned.ts +53 -0
- package/scripts/run/review/run-review-steps.ts +70 -34
- package/scripts/run/review/run-review.ts +26 -6
- package/scripts/run/run-parent-cut-hook.ts +3 -4
- package/scripts/run/run-prep.ts +1 -0
- package/scripts/run/run-stage-read.ts +2 -6
- package/scripts/run/run-step-cli.ts +17 -5
- package/scripts/run/run-step-lane-plan.ts +27 -0
- package/scripts/run/run-step-section.ts +26 -7
- package/scripts/run/run-step.ts +5 -2
- package/scripts/run/ship/run-ship-args.ts +19 -0
- package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
- package/scripts/run/ship/run-ship-cli.ts +131 -39
- package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
- package/scripts/run/ship/run-ship-detach.ts +10 -4
- package/scripts/run/ship/run-ship-handover.ts +106 -0
- package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
- package/scripts/run/ship/run-ship-lap.ts +63 -0
- package/scripts/run/ship/run-ship-next.ts +27 -26
- package/scripts/run/ship/run-ship-overlap.ts +8 -3
- package/scripts/run/ship/run-ship-place.ts +9 -2
- package/scripts/run/ship/run-ship-planned.ts +92 -0
- package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
- package/scripts/run/ship/run-ship-preflight.ts +16 -4
- package/scripts/run/ship/run-ship-probe.ts +23 -9
- package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
- package/scripts/run/ship/run-ship-relaunch.ts +51 -0
- package/scripts/run/ship/run-ship-return.ts +103 -29
- package/scripts/run/ship/run-ship-review-reason.ts +24 -0
- package/scripts/run/ship/run-ship-review-steps.ts +230 -59
- package/scripts/run/ship/run-ship-review.ts +171 -51
- package/scripts/run/ship/run-ship-reviewer.ts +138 -42
- package/scripts/run/ship/run-ship-scoped.ts +39 -10
- package/scripts/run/ship/run-ship-stage.ts +49 -13
- package/scripts/run/ship/run-ship-steps.ts +24 -4
- package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
- package/scripts/run/ship/run-ship-stop-context.ts +50 -13
- package/scripts/run/ship/run-ship-sync.ts +171 -30
- package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
- package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
- package/scripts/run/ship/run-ship-waiter.ts +114 -0
- package/scripts/run/ship/run-ship.ts +16 -2
- package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
- package/scripts/run/wake/run-wake-cli.ts +6 -113
- package/scripts/run/wake/run-wake-code.ts +53 -11
- package/scripts/run/wake/run-wake-driver.ts +5 -3
- package/scripts/run/wake/run-wake-finish.ts +137 -0
- package/scripts/run/wake/run-wake-loop.ts +5 -3
- package/scripts/run/wake/run-wake-ports.ts +11 -3
- package/scripts/run/wake/run-wake-session.ts +2 -0
- package/scripts/run/wake/run-wake.ts +3 -2
- package/scripts/safe-chain/ci-installer-pin.ts +49 -8
- package/scripts/safe-chain/project-config.ts +3 -2
- package/scripts/security/secretlint-scan.ts +42 -9
- package/scripts/security/security-audit-provision-main.ts +9 -1
- package/scripts/security/security-audit-provision.ts +1 -1
- package/scripts/security/security-audit.ts +21 -1
- package/scripts/security/sonar-file.ts +10 -5
- package/scripts/split/split-assess.ts +12 -3
- package/scripts/split/split-early-notice.ts +116 -0
- package/scripts/split/split-measure.ts +20 -2
- package/scripts/split/split-resolution.ts +107 -0
- package/scripts/test/direct-importers.ts +185 -0
- package/scripts/test/pure-files-entries.ts +83 -0
- package/scripts/test/related-heavy-tests.ts +81 -0
- package/scripts/test/test-no-base.ts +88 -0
- package/scripts/test/test-pinned-cache-logic.ts +363 -0
- package/scripts/test/test-pinned-cache.ts +337 -0
- package/scripts/test/test-pinned-emit.ts +49 -0
- package/scripts/test/test-pinned-functions.ts +116 -0
- package/scripts/test/test-pinned-ledger.ts +80 -0
- package/scripts/test/test-pinned-logic.ts +208 -20
- package/scripts/test/test-pinned-main.ts +84 -18
- package/scripts/test/test-pinned-pool.ts +73 -0
- package/scripts/test/test-pinned-probe.ts +254 -0
- package/scripts/test/test-pinned-prune-logic.ts +118 -0
- package/scripts/test/test-pinned-reach.ts +194 -0
- package/scripts/test/test-pinned-record.ts +196 -0
- package/scripts/test/test-pinned-rewire.ts +148 -0
- package/scripts/test/test-pinned-spawn.ts +81 -0
- package/scripts/test/test-pinned-stage.ts +70 -0
- package/scripts/test/test-pinned.ts +258 -47
- package/scripts/test/test-reach-cli.ts +61 -0
- package/scripts/test/test-read-map.ts +35 -11
- package/scripts/test/test-read-recording.ts +17 -5
- package/scripts/test/test-read-trace.ts +26 -8
- package/scripts/test/test-red-logic.ts +46 -7
- package/scripts/test/test-red.ts +34 -14
- package/scripts/test/test-related-claim.ts +37 -0
- package/scripts/test/test-related-main.ts +4 -1
- package/scripts/test/test-related-moved.ts +91 -0
- package/scripts/test/test-related-record.ts +43 -23
- package/scripts/test/test-related-scope.ts +99 -34
- package/scripts/test/test-related-synced.ts +135 -0
- package/scripts/test/test-related-touched.ts +84 -0
- package/scripts/test/test-related.ts +167 -83
- package/scripts/test/test-unit-guard.ts +28 -5
- package/scripts/test/unit-durations.ts +41 -0
- package/scripts/test/unit-worker-share.ts +5 -4
- package/scripts/test/vitest-cache-directory.ts +19 -0
- package/scripts/test/vitest-cli-excludes.ts +14 -0
- package/scripts/test/vitest-failure-summary.ts +111 -0
- package/scripts/test/whole-suite-files.ts +12 -1
- package/scripts/time-runtime/time-batch-guard.ts +42 -4
- package/scripts/time-runtime/time-bundle-call.ts +1 -1
- package/scripts/time-runtime/time-bundles.ts +36 -5
- package/scripts/time-runtime/time-markers.ts +2 -2
- package/scripts/time-runtime/time-search-call.ts +38 -0
- package/scripts/time-runtime/time-shell.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +17 -5
- package/scripts/version/development-engines-verdict.ts +124 -0
- package/scripts/version/latest-corepack.ts +2 -0
- package/templates/gitignore +2 -0
- package/templates/workflows/ci.yml +41 -0
- package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
- package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
- package/dist/hooks/chunk-TUIFS5E7.js +0 -72
- package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
- package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
- package/scripts/rules/filing-cap.ts +0 -139
|
@@ -360,6 +360,19 @@ async function collect_unfixed(
|
|
|
360
360
|
return unfixed
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
+
// The edited file as the daemon read it, or nothing when no eslint command linted it — a `.json`
|
|
364
|
+
// module prettier alone formats is still in the type program, and a refreshed record would hide its
|
|
365
|
+
// old copy there (joshuafolkken/kit#4867).
|
|
366
|
+
function linted_path(
|
|
367
|
+
plan: ReadonlyArray<FormatCommand>,
|
|
368
|
+
file_path: string,
|
|
369
|
+
project_root: string,
|
|
370
|
+
): string | undefined {
|
|
371
|
+
if (plan.every((command) => command.bin !== ESLINT_BIN)) return undefined
|
|
372
|
+
|
|
373
|
+
return relative_to_root(project_root, file_path)
|
|
374
|
+
}
|
|
375
|
+
|
|
363
376
|
async function format_edited_file(
|
|
364
377
|
raw_payload: string,
|
|
365
378
|
runner: CommandRunner,
|
|
@@ -376,7 +389,11 @@ async function format_edited_file(
|
|
|
376
389
|
const daemon_before = eslint_daemon.read_record(project_root)
|
|
377
390
|
const unfixed = await collect_unfixed(plan, runner, project_root)
|
|
378
391
|
|
|
379
|
-
eslint_daemon.
|
|
392
|
+
eslint_daemon.remember_after_edit(
|
|
393
|
+
project_root,
|
|
394
|
+
daemon_before,
|
|
395
|
+
linted_path(plan, file_path, project_root),
|
|
396
|
+
)
|
|
380
397
|
|
|
381
398
|
return format_diagnostics(unfixed === '' ? undefined : unfixed)
|
|
382
399
|
}
|
|
@@ -444,15 +461,18 @@ function report_no_payload(): void {
|
|
|
444
461
|
// its content before the formatters ran against its content after — so it too is known only once they
|
|
445
462
|
// have. The rewrite, lint and spell blocks are composed together first, then
|
|
446
463
|
// joined to the density line — one envelope, since a `PostToolUse` hook's stdout carries only one.
|
|
464
|
+
// The spell check runs beside the formatters rather than after them, on the text as the edit left it:
|
|
465
|
+
// it was the hook's largest step (joshuafolkken/kit#4596), and a formatter rewrites layout, not words.
|
|
447
466
|
// A hook killed at its 15s timeout is the one case this loses the density
|
|
448
467
|
// line to — a run already gone pathologically wrong, per HOOK_PROCESS_TIMEOUT_MS.
|
|
449
468
|
async function run_hook(payload: string): Promise<void> {
|
|
450
469
|
const notice = time_density_hook.density_notice(payload)
|
|
451
470
|
const file_path = parse_edited_path(payload)
|
|
452
471
|
const before = rewrite_notice.read_text(file_path)
|
|
472
|
+
const pending_spelling = edited_cspell.spelling_diagnostics(file_path, process.cwd(), before)
|
|
453
473
|
const lint = await format_edited_payload(payload, process.cwd())
|
|
454
474
|
const rewrite = rewrite_notice.build(before, rewrite_notice.read_text(file_path))
|
|
455
|
-
const spelling = await
|
|
475
|
+
const spelling = await pending_spelling
|
|
456
476
|
const parts = compose_context(rewrite, compose_context(lint, spelling))
|
|
457
477
|
const context = compose_context(notice, parts)
|
|
458
478
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { lane_child_marker, type MarkerSource } from '#scripts/lane/lane-child-marker'
|
|
2
|
+
import { lane_plan } from '#scripts/lane/lane-plan'
|
|
3
|
+
import { step_zero_notice } from './step-zero-notice'
|
|
4
|
+
|
|
5
|
+
// A dispatched lane child's first implementation edit is refused until `josh lane:plan` has recorded
|
|
6
|
+
// the files its work summary changes and cleared them (joshuafolkken/kit#4864). The record is what holds a later lane
|
|
7
|
+
// back from those files, so it has to exist before the code does; a document asking for it would be
|
|
8
|
+
// read after the edit it governs.
|
|
9
|
+
//
|
|
10
|
+
// **A dispatched lane child only**, the trust condition `lane-phase.ts` applies: a person's session, or
|
|
11
|
+
// one carrying a mark leaked from a parent, runs no lanes beside it to wait on.
|
|
12
|
+
|
|
13
|
+
const COMMAND_DOC = '`docs/josh-commands-run.md` → "`josh lane:plan`"'
|
|
14
|
+
const OUTCOMES =
|
|
15
|
+
'on `yield` end the session with no edit (its lane is given back); on `wait` run it again'
|
|
16
|
+
|
|
17
|
+
function reason_text(issue: string): string {
|
|
18
|
+
const command = `\`pnpm josh lane:plan ${issue} <path>...\``
|
|
19
|
+
|
|
20
|
+
return `⛔ lane plan: run ${command} naming every file the work summary changes before the first implementation edit — ${OUTCOMES} (${COMMAND_DOC}).`
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// The issue of the dispatched lane child making this runtime edit, or `undefined` for any other call.
|
|
24
|
+
function lane_child_edit(
|
|
25
|
+
raw_payload: string,
|
|
26
|
+
directory: string,
|
|
27
|
+
source: MarkerSource,
|
|
28
|
+
): string | undefined {
|
|
29
|
+
if (!lane_child_marker.is_child_of(directory, source)) return undefined
|
|
30
|
+
|
|
31
|
+
return step_zero_notice.is_runtime_edit(raw_payload, directory)
|
|
32
|
+
? lane_child_marker.marked_issue(source)
|
|
33
|
+
: undefined
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function reason(
|
|
37
|
+
raw_payload: string,
|
|
38
|
+
directory: string = process.cwd(),
|
|
39
|
+
source: MarkerSource = process.env,
|
|
40
|
+
): string | undefined {
|
|
41
|
+
const issue = lane_child_edit(raw_payload, directory, source)
|
|
42
|
+
|
|
43
|
+
if (issue === undefined) return undefined
|
|
44
|
+
|
|
45
|
+
return lane_plan.is_uncleared(Number(issue), directory) ? reason_text(issue) : undefined
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const lane_plan_guard = { reason }
|
|
49
|
+
|
|
50
|
+
export { lane_plan_guard }
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// **Switched off, a pre-commit lint hook neither reserves the core budget nor runs** — set by `josh
|
|
2
|
+
// ship`'s local commit (`run-ship-sync.ts`), whose tree the gate or the scoped pair checks before
|
|
3
|
+
// anything is pushed (joshuafolkken/kit#4985). On by default like every other distributed guard. Its
|
|
4
|
+
// own module because the hook is an entry with a main guard, which nothing may import.
|
|
5
|
+
const SWITCH_ENV_KEY = 'JOSH_PRE_COMMIT_LINT'
|
|
6
|
+
|
|
7
|
+
const pre_commit_lint_switch = { SWITCH_ENV_KEY }
|
|
8
|
+
|
|
9
|
+
export { pre_commit_lint_switch }
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
3
|
import { core_budget } from '#scripts/gate/core-budget'
|
|
4
|
+
import { pre_commit_lint_switch } from '#scripts/hooks/pre-commit-lint-switch'
|
|
5
|
+
import { hook_decision } from '#scripts/josh/hook-decision'
|
|
4
6
|
import {
|
|
5
7
|
CSPELL_COMMIT_CACHE_FLAGS,
|
|
6
8
|
ESLINT_COMMIT_CACHE_FILE,
|
|
@@ -51,8 +53,13 @@ const TOOL_BUDGETS: Readonly<Record<string, 'spell_check' | 'format' | 'eslint_s
|
|
|
51
53
|
eslint: 'eslint_scan',
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
const SUCCESS_EXIT_CODE = 0
|
|
57
|
+
|
|
54
58
|
const USAGE = `Usage: josh pre-commit-lint <${Object.keys(TOOL_ARGUMENTS).join('|')}> [files...]`
|
|
59
|
+
const END_OF_OPTIONS = '--'
|
|
55
60
|
|
|
61
|
+
// The staged files follow `--`, so a file named `--plugin=x.mjs` is read as a file, never as an
|
|
62
|
+
// option that loads code (joshuafolkken/kit#4634).
|
|
56
63
|
function build_arguments(
|
|
57
64
|
tool: string,
|
|
58
65
|
staged_files: ReadonlyArray<string>,
|
|
@@ -60,7 +67,7 @@ function build_arguments(
|
|
|
60
67
|
const tool_arguments = TOOL_ARGUMENTS[tool]
|
|
61
68
|
if (tool_arguments === undefined) return undefined
|
|
62
69
|
|
|
63
|
-
return [...tool_arguments, ...staged_files]
|
|
70
|
+
return [...tool_arguments, END_OF_OPTIONS, ...staged_files]
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
// eslint goes through the lane's warm daemon when one is reachable (joshuafolkken/kit#4358): the same
|
|
@@ -92,6 +99,10 @@ async function run_reserved(tool: string, staged_files: ReadonlyArray<string>):
|
|
|
92
99
|
return await run_tool(command_arguments)
|
|
93
100
|
}
|
|
94
101
|
|
|
102
|
+
function is_switched_on(): boolean {
|
|
103
|
+
return hook_decision.is_switch_enabled(pre_commit_lint_switch.SWITCH_ENV_KEY)
|
|
104
|
+
}
|
|
105
|
+
|
|
95
106
|
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
96
107
|
const [tool = '', ...staged_files] = argv
|
|
97
108
|
const budget = TOOL_BUDGETS[tool]
|
|
@@ -102,6 +113,8 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
|
102
113
|
return USAGE_ERROR_EXIT_CODE
|
|
103
114
|
}
|
|
104
115
|
|
|
116
|
+
if (!is_switched_on()) return SUCCESS_EXIT_CODE
|
|
117
|
+
|
|
105
118
|
return await core_budget.with_command_reservation(
|
|
106
119
|
core_budget.CORE_WEIGHTS[budget],
|
|
107
120
|
async () => await run_reserved(tool, staged_files),
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// **Switched on, a pre-push unit run the gate record does not cover runs the related tests rather than
|
|
2
|
+
// the whole suite** — set by `josh ship`'s push ahead of the gate (`run-ship-sync.ts`), whose gate over
|
|
3
|
+
// the same tree runs the whole suite next (joshuafolkken/kit#5067). Off by default. Its own module
|
|
4
|
+
// because the hook is an entry with a main guard, which nothing may import.
|
|
5
|
+
const SWITCH_ENV_KEY = 'JOSH_PRE_PUSH_RELATED'
|
|
6
|
+
const SWITCH_ON = '1'
|
|
7
|
+
|
|
8
|
+
const pre_push_related_switch = { SWITCH_ENV_KEY, SWITCH_ON }
|
|
9
|
+
|
|
10
|
+
export { pre_push_related_switch }
|
|
@@ -5,7 +5,10 @@ import { gate_plan } from '#scripts/gate/gate-plan'
|
|
|
5
5
|
import { gate_skip, type GateReuse } from '#scripts/gate/gate-skip'
|
|
6
6
|
import { gate_tree, type GateTree } from '#scripts/gate/gate-tree'
|
|
7
7
|
import { hook_gate_reuse } from '#scripts/gate/hook-gate-reuse'
|
|
8
|
+
import type { PushMissRecord } from '#scripts/lane/lane-ledger-schema'
|
|
9
|
+
import { lane_ledger_write } from '#scripts/lane/lane-ledger-write'
|
|
8
10
|
import { test_unit_guard } from '#scripts/test/test-unit-guard'
|
|
11
|
+
import { pre_push_related_switch } from './pre-push-related-switch'
|
|
9
12
|
|
|
10
13
|
// The pre-push hook's unit run, which does not re-run a suite a green gate already covers: the gate
|
|
11
14
|
// writes its record down, and re-running `vitest run` on a tree it just printed green is the bulk of
|
|
@@ -125,30 +128,93 @@ function format_miss(reason: string): string {
|
|
|
125
128
|
return `↻ running the whole unit suite — the green gate record does not cover this push: ${reason}.`
|
|
126
129
|
}
|
|
127
130
|
|
|
128
|
-
// **
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
+
// **A unit run claims its place in the core budget, the one `josh test:unit` claims.** Without it a
|
|
132
|
+
// push's run went beside other lanes' gates off the ledger, so their admission saw its workers only as
|
|
133
|
+
// foreign load (joshuafolkken/kit#3874). Only the miss reserves: a reused record runs nothing, and a
|
|
131
134
|
// claim there could make a push wait out a full ledger for a suite it then skips.
|
|
132
|
-
async function
|
|
135
|
+
async function run_reserved(command: string, run: () => Promise<number>): Promise<number> {
|
|
133
136
|
const claim = gate_plan.DIRECT_UNIT_CLAIM
|
|
134
137
|
|
|
135
|
-
return await core_budget.with_command_reservation(
|
|
136
|
-
claim.
|
|
138
|
+
return await core_budget.with_command_reservation(claim.core_weight(), run, {
|
|
139
|
+
memory_mb: claim.memory_mb(),
|
|
140
|
+
command,
|
|
141
|
+
is_unit: claim.is_unit_claim,
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function run_reserved_suite(vitest_arguments: ReadonlyArray<string>): Promise<number> {
|
|
146
|
+
return await run_reserved(
|
|
147
|
+
'pre-push test:unit',
|
|
137
148
|
async () => await test_unit_guard.run_guarded_unit(process.cwd(), vitest_arguments),
|
|
138
|
-
{ memory_mb: claim.memory_mb(), command: 'pre-push test:unit', is_unit: claim.is_unit_claim },
|
|
139
149
|
)
|
|
140
150
|
}
|
|
141
151
|
|
|
152
|
+
// **A push its caller makes ahead of the gate runs the related tests, not the whole suite**
|
|
153
|
+
// (joshuafolkken/kit#5067). `josh ship` pushes the tree its sync merged with the default branch onto an
|
|
154
|
+
// open pull request so CI starts beside the gate, and the gate that follows runs the whole suite over
|
|
155
|
+
// that same tree; the push itself only needs what this branch's change reaches. Only the caller sets
|
|
156
|
+
// it, `--force` and the escape hatch still win, and a narrowed run asked for its own arguments rather
|
|
157
|
+
// than this scope.
|
|
158
|
+
function is_related_requested(extra_arguments: ReadonlyArray<string>): boolean {
|
|
159
|
+
const { SWITCH_ENV_KEY, SWITCH_ON } = pre_push_related_switch
|
|
160
|
+
|
|
161
|
+
if (process.env[SWITCH_ENV_KEY] !== SWITCH_ON || extra_arguments.length > 0) return false
|
|
162
|
+
|
|
163
|
+
return !hook_gate_reuse.is_force_requested(FORCE_ENV)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function format_related(reason: string): string {
|
|
167
|
+
return `↻ running the related unit tests — the push runs ahead of its gate, and the green gate record does not cover it: ${reason}.`
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Imported only on this path, so every other push leaves the import graph `test-related.ts` loads alone.
|
|
171
|
+
async function run_related(): Promise<number> {
|
|
172
|
+
const { test_related } = await import('#scripts/test/test-related')
|
|
173
|
+
|
|
174
|
+
return await run_reserved(
|
|
175
|
+
'pre-push test:related',
|
|
176
|
+
async () => await test_related.run_related_tests([]),
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// joshuafolkken/kit#5234: the miss's kind goes to the lane ledger, so `lane:stats` counts the suites a
|
|
181
|
+
// push ran and why beside the gate's own fallbacks.
|
|
182
|
+
async function record_miss(scope: PushMissRecord['scope'], kind: string): Promise<void> {
|
|
183
|
+
await lane_ledger_write.record_push_miss({ scope, reason: kind })
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async function run_miss(
|
|
187
|
+
reason: string,
|
|
188
|
+
kind: string,
|
|
189
|
+
extra_arguments: ReadonlyArray<string>,
|
|
190
|
+
): Promise<number> {
|
|
191
|
+
if (is_related_requested(extra_arguments)) {
|
|
192
|
+
process.stdout.write(`${format_related(reason)}\n`)
|
|
193
|
+
await record_miss('related', kind)
|
|
194
|
+
|
|
195
|
+
return await run_related()
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
process.stdout.write(`${format_miss(reason)}\n`)
|
|
199
|
+
await record_miss('whole', kind)
|
|
200
|
+
|
|
201
|
+
return await run_reserved_suite(forwarded_arguments(extra_arguments))
|
|
202
|
+
}
|
|
203
|
+
|
|
142
204
|
async function run_pre_push_unit(
|
|
143
205
|
extra_arguments: ReadonlyArray<string> = [],
|
|
144
206
|
source?: string,
|
|
145
207
|
): Promise<number> {
|
|
146
|
-
const
|
|
208
|
+
const tree = await read_push_tree()
|
|
209
|
+
const reuse = push_reuse(tree, extra_arguments, source)
|
|
147
210
|
|
|
148
211
|
if ('miss' in reuse) {
|
|
149
|
-
|
|
212
|
+
const kind = hook_gate_reuse.miss_kind(reuse.miss, {
|
|
213
|
+
carry_miss: tree.carry_miss,
|
|
214
|
+
force_env: FORCE_ENV,
|
|
215
|
+
})
|
|
150
216
|
|
|
151
|
-
return await
|
|
217
|
+
return await run_miss(reuse.miss, kind, extra_arguments)
|
|
152
218
|
}
|
|
153
219
|
|
|
154
220
|
process.stdout.write(`${format_skip(reuse.stamp.taken_at)}\n`)
|
|
@@ -11,6 +11,7 @@ import { run_poll_hook } from '#scripts/run/run-poll-hook'
|
|
|
11
11
|
import { run_watcher_hook } from '#scripts/run/run-watcher-hook'
|
|
12
12
|
import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
|
|
13
13
|
import { batch_outcome } from './batch-guard'
|
|
14
|
+
import { lane_plan_guard } from './lane-plan-guard'
|
|
14
15
|
import { shell_rules_notice } from './shell-rules-notice'
|
|
15
16
|
import { step_zero_notice } from './step-zero-notice'
|
|
16
17
|
|
|
@@ -72,6 +73,7 @@ function guard_outcome(raw_payload: string): GuardOutcome {
|
|
|
72
73
|
batch_outcome(raw_payload),
|
|
73
74
|
investigation_outcome(raw_payload),
|
|
74
75
|
duplicate_read_outcome(raw_payload),
|
|
76
|
+
{ reason: lane_plan_guard.reason(raw_payload), notice: undefined, fault: undefined },
|
|
75
77
|
]
|
|
76
78
|
|
|
77
79
|
return combine_outcomes(outcomes, delivered_rules.delivery(raw_payload))
|
|
@@ -106,12 +106,25 @@ function reservation_options(parsed: ReservedCommand): {
|
|
|
106
106
|
return { command, memory_mb: parsed.memory_mb ?? command_memory.estimated_memory_mb(command) }
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
// The directory the caller typed the command in. **`pnpm josh` runs from the package root**, so without
|
|
110
|
+
// this a wrapped `eslint rules/a.ts` typed in `scripts/` would lint from the root and match nothing;
|
|
111
|
+
// pnpm records the caller's directory in `INIT_CWD` (joshuafolkken/kit#5147).
|
|
112
|
+
function command_directory(): string {
|
|
113
|
+
const initial = process.env['INIT_CWD']
|
|
114
|
+
|
|
115
|
+
return initial === undefined || initial === '' ? process.cwd() : initial
|
|
116
|
+
}
|
|
117
|
+
|
|
109
118
|
// `stdio: 'inherit'` so the command's own progress reaches the push, and `reject: false` so a failing
|
|
110
119
|
// command becomes an exit code the caller returns rather than a throw — the reservation is released by
|
|
111
120
|
// `with_core_reservation`'s `finally` on either path.
|
|
112
121
|
async function run_command(command: ReadonlyArray<string>): Promise<number> {
|
|
113
122
|
const [file = '', ...args] = command
|
|
114
|
-
const result = await execa(file, args, {
|
|
123
|
+
const result = await execa(file, args, {
|
|
124
|
+
cwd: command_directory(),
|
|
125
|
+
stdio: 'inherit',
|
|
126
|
+
reject: false,
|
|
127
|
+
})
|
|
115
128
|
|
|
116
129
|
return result.exitCode ?? FAIL_EXIT_CODE
|
|
117
130
|
}
|
|
@@ -22,23 +22,38 @@
|
|
|
22
22
|
# `dirname`, and `node` replaces this shell through `exec` rather than running beside it.
|
|
23
23
|
# - An `if`/`else`, never `&&`/`||`: a guard's refusal is a non-zero exit, and a chain would read it as
|
|
24
24
|
# a missing bundle and run the hook twice.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
fi
|
|
25
|
+
# - A hook launched inside one of Claude Code's own worktrees (`EnterWorktree`, an
|
|
26
|
+
# `isolation: "worktree"` subagent) runs in that worktree. Claude Code keeps `CLAUDE_PROJECT_DIR` on
|
|
27
|
+
# the main checkout there, so the prefix lands on it and hands over where the hook was launched in
|
|
28
|
+
# `JOSH_HOOK_CWD` (joshuafolkken/kit#4617). The code still comes from the project root — a fresh
|
|
29
|
+
# worktree has no install and no bundles — so only the working directory moves.
|
|
31
30
|
|
|
32
31
|
hook_name=$1
|
|
33
32
|
shift
|
|
34
33
|
case $0 in
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
/*) hooks_dir=${0%/*} ;;
|
|
35
|
+
*/*) hooks_dir=$PWD/${0%/*} ;;
|
|
36
|
+
*) hooks_dir=$PWD ;;
|
|
37
37
|
esac
|
|
38
38
|
package_dir="$hooks_dir/../.."
|
|
39
39
|
bundle="$package_dir/dist/hooks/$hook_name.js"
|
|
40
40
|
josh_command="${hook_name%%-*}:${hook_name#*-}"
|
|
41
41
|
|
|
42
|
+
worktrees_dir=$PWD/.claude/worktrees/
|
|
43
|
+
case $JOSH_HOOK_CWD in
|
|
44
|
+
"$worktrees_dir"?*)
|
|
45
|
+
worktree_path=${JOSH_HOOK_CWD#"$worktrees_dir"}
|
|
46
|
+
cd "$worktrees_dir${worktree_path%%/*}" || exit
|
|
47
|
+
;;
|
|
48
|
+
*) ;;
|
|
49
|
+
esac
|
|
50
|
+
|
|
51
|
+
location_variables='GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE'
|
|
52
|
+
if [ -n "$GIT_ALTERNATE_OBJECT_DIRECTORIES$GIT_COMMON_DIR$GIT_DIR$GIT_INDEX_FILE$GIT_NAMESPACE$GIT_OBJECT_DIRECTORY$GIT_WORK_TREE" ] &&
|
|
53
|
+
(unset $location_variables && git rev-parse --show-toplevel >/dev/null 2>&1); then
|
|
54
|
+
unset $location_variables
|
|
55
|
+
fi
|
|
56
|
+
|
|
42
57
|
case $0 in
|
|
43
58
|
*node_modules/*)
|
|
44
59
|
if [ -d "$package_dir/dist/hooks" ]; then exec node "$bundle" "$@"; else exec node "$package_dir/dist/josh.js" "$josh_command" "$@"; fi
|
|
@@ -58,6 +58,11 @@ function is_candidate(raw_payload: string, root: string): string | undefined {
|
|
|
58
58
|
return has_runtime_file ? payload.transcript_path : undefined
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
// Whether the payload edits a runtime file under `root` — the edit Step 0 and the lane plan precede.
|
|
62
|
+
function is_runtime_edit(raw_payload: string, root: string = process.cwd()): boolean {
|
|
63
|
+
return is_candidate(raw_payload, root) !== undefined
|
|
64
|
+
}
|
|
65
|
+
|
|
61
66
|
function notice(raw_payload: string, root: string = process.cwd()): string | undefined {
|
|
62
67
|
const transcript = is_candidate(raw_payload, root)
|
|
63
68
|
|
|
@@ -72,6 +77,6 @@ function notice(raw_payload: string, root: string = process.cwd()): string | und
|
|
|
72
77
|
return NOTICE
|
|
73
78
|
}
|
|
74
79
|
|
|
75
|
-
const step_zero_notice = { NOTICE, notice, stamp_path: STAMP.path }
|
|
80
|
+
const step_zero_notice = { NOTICE, is_runtime_edit, notice, stamp_path: STAMP.path }
|
|
76
81
|
|
|
77
82
|
export { step_zero_notice }
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { git_gh_repo } from '#scripts/gh/git-gh-repo'
|
|
2
2
|
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
3
|
-
import { issue_cite_cli } from '#scripts/issue/issue-cite-cli'
|
|
4
3
|
import { session_cite } from '#scripts/issue/session-cite'
|
|
5
4
|
import { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
6
5
|
import { stdout_on_stderr } from '#scripts/lib/stdout-on-stderr'
|
|
7
6
|
import { telegram_test } from '#scripts/notify/telegram-test'
|
|
8
7
|
import type { CliValues } from '#scripts/notify/telegram-test-logic'
|
|
9
|
-
import { issue_citation } from '#scripts/rules/issue-citation'
|
|
10
8
|
import { stop_rules, type StopAction, type StopOutcome } from '#scripts/rules/stop-rules'
|
|
11
9
|
import { run_hold } from '#scripts/run/hold/run-hold'
|
|
12
10
|
import { run_hold_cli } from '#scripts/run/hold/run-hold-cli'
|
|
@@ -15,9 +13,8 @@ import { run_hold_session } from '#scripts/run/hold/run-hold-session'
|
|
|
15
13
|
type NotifyAction = Extract<StopAction, { kind: 'notify' }>
|
|
16
14
|
|
|
17
15
|
// The `Stop` hook running the operations whose answer is fixed (joshuafolkken/kit#3919): the
|
|
18
|
-
// `confirmation` notify
|
|
19
|
-
// `josh
|
|
20
|
-
// launches would spend most of the hook's 20-second budget. What each did reaches the person as a
|
|
16
|
+
// `confirmation` notify and the hold release, through the very calls `josh notify` and
|
|
17
|
+
// `josh run:release` make — in process, since two `pnpm` launches would spend most of the hook's 20-second budget. What each did reaches the person as a
|
|
21
18
|
// `systemMessage`; one that did not take falls back to the refusal it replaced (`stop_rules.fallback_reason`).
|
|
22
19
|
|
|
23
20
|
const SUCCESS_EXIT_CODE = 0
|
|
@@ -109,20 +106,11 @@ async function release(issue: string): Promise<string | undefined> {
|
|
|
109
106
|
return code === SUCCESS_EXIT_CODE ? '🔓 stop:guard released the run:hold record.' : undefined
|
|
110
107
|
}
|
|
111
108
|
|
|
112
|
-
// Every line or none: a citation with a number missing is the half-fix the refusal exists to avoid.
|
|
113
|
-
async function cite(references: ReadonlyArray<string>): Promise<string | undefined> {
|
|
114
|
-
const cited = await issue_cite_cli.cite(issue_citation.cite_arguments(references))
|
|
115
|
-
if (cited === undefined || cited.failures.length > 0) return undefined
|
|
116
|
-
|
|
117
|
-
return ['Issue citations:', ...cited.lines].join(NOTICE_SEPARATOR)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
109
|
// An action's line for the person, or `undefined` when it did not take.
|
|
121
110
|
async function run_action(action: StopAction): Promise<string | undefined> {
|
|
122
111
|
if (action.kind === 'notify') return await notify(action)
|
|
123
|
-
if (action.kind === 'release') return await release(action.issue)
|
|
124
112
|
|
|
125
|
-
return await
|
|
113
|
+
return await release(action.issue)
|
|
126
114
|
}
|
|
127
115
|
|
|
128
116
|
// A throw is an action that did not take, the same as one that answered it had failed.
|
|
@@ -10,7 +10,6 @@ import { session_language } from '#scripts/josh/session-language'
|
|
|
10
10
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
11
11
|
import { lane_handoff } from '#scripts/lane/lane-handoff'
|
|
12
12
|
import { stdout_on_stderr } from '#scripts/lib/stdout-on-stderr'
|
|
13
|
-
import { filing_cap } from '#scripts/rules/filing-cap'
|
|
14
13
|
import { lane_background } from '#scripts/rules/lane-background'
|
|
15
14
|
import { lane_park } from '#scripts/rules/lane-park'
|
|
16
15
|
import { last_prompt } from '#scripts/rules/last-prompt'
|
|
@@ -18,6 +17,7 @@ import { pre_gate_cut } from '#scripts/rules/pre-gate-cut'
|
|
|
18
17
|
import { stop_decision } from '#scripts/rules/stop-decision'
|
|
19
18
|
import { stop_rules, type StopContext, type StopOutcome } from '#scripts/rules/stop-rules'
|
|
20
19
|
import { tail_commands } from '#scripts/rules/tail-commands'
|
|
20
|
+
import { turn_filings } from '#scripts/rules/turn-filings'
|
|
21
21
|
import { run_carry } from '#scripts/run/carry/run-carry'
|
|
22
22
|
import { run_cut } from '#scripts/run/cut/run-cut'
|
|
23
23
|
import { run_cut_report } from '#scripts/run/cut/run-cut-report'
|
|
@@ -82,10 +82,10 @@ function transcript_tail(transcript_path: string): string {
|
|
|
82
82
|
return time_density_hook.read_tail(transcript)
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
// An Issue was filed on this turn — the tail from the last prompt on. The count is `
|
|
86
|
-
// filing a guard refused is not counted, and one an earlier turn made does not stand this turn down.
|
|
85
|
+
// An Issue was filed on this turn — the tail from the last prompt on. The count is `turn_filings`', so
|
|
86
|
+
// a filing a guard refused is not counted, and one an earlier turn made does not stand this turn down.
|
|
87
87
|
function was_filed(tail: string): boolean {
|
|
88
|
-
return
|
|
88
|
+
return turn_filings.turn_filing_count(tail) > 0
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// This turn ended at a cut — a record still `carried`, or this turn's `run:cut` relaunching a successor.
|
|
@@ -95,7 +95,7 @@ function is_cut_stop(tail: string): boolean {
|
|
|
95
95
|
if (run_cut.carried_cut_sync() !== undefined) return true
|
|
96
96
|
|
|
97
97
|
return tail_commands.answered(
|
|
98
|
-
|
|
98
|
+
turn_filings.current_turn(tail),
|
|
99
99
|
pre_gate_cut.takes_the_cut,
|
|
100
100
|
run_cut_report.RELAUNCHED_CUT_MARKER,
|
|
101
101
|
)
|
|
@@ -129,7 +129,7 @@ async function build_context(
|
|
|
129
129
|
...(await hold_facts(tail)),
|
|
130
130
|
tree_clean: !(await run_hold.is_tree_dirty()),
|
|
131
131
|
message: payload_tail.message,
|
|
132
|
-
prompt: last_prompt.
|
|
132
|
+
prompt: last_prompt.person_prompt(tail),
|
|
133
133
|
answers_question: stop_decision.is_question(last_prompt.turn_prompt(tail)),
|
|
134
134
|
stop_hook_active: payload_tail.stop_hook_active,
|
|
135
135
|
cut_pending: is_cut_stop(tail),
|
|
@@ -139,6 +139,7 @@ async function build_context(
|
|
|
139
139
|
headless_refusals: stop_rules.count_headless_refusals(tail),
|
|
140
140
|
background_pending: lane_background.pending_background_ids(tail).length > 0,
|
|
141
141
|
agent_pending: lane_background.pending_agent_ids(tail).length > 0,
|
|
142
|
+
command_pending: lane_background.pending_command_ids(tail).length > 0,
|
|
142
143
|
handed_off: lane_handoff.is_handed_off(process.cwd()),
|
|
143
144
|
session_lang: session_lang(),
|
|
144
145
|
}
|
|
@@ -56,9 +56,13 @@ const LOCATION_VARIABLES =
|
|
|
56
56
|
'GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE'
|
|
57
57
|
const ROOT_LOOKUP = 'git rev-parse --show-toplevel'
|
|
58
58
|
const LEGACY_ROOT_PREFIX = `if project_root="$(unset ${LOCATION_VARIABLES}; ${ROOT_LOOKUP} 2>/dev/null)"; then unset ${LOCATION_VARIABLES}; else project_root="$(${ROOT_LOOKUP})"; fi && cd "$project_root" && `
|
|
59
|
+
// The root prefix kit wrote until joshuafolkken/kit#4617 exported the launch directory for a worktree.
|
|
60
|
+
// History, never edited; removable from kit 2.0.0.
|
|
61
|
+
const PRE_WORKTREE_ROOT_PREFIX = `project_root="\${CLAUDE_PROJECT_DIR:-$( (unset ${LOCATION_VARIABLES}; ${ROOT_LOOKUP} 2>/dev/null) || ${ROOT_LOOKUP})}" && cd "$project_root" && `
|
|
59
62
|
// The values below are matched inside raw JSON text, so each root prefix is taken in its escaped form.
|
|
60
63
|
const ROOT_PREFIXES: ReadonlyArray<string> = [
|
|
61
64
|
hook_launch.PROJECT_ROOT_PREFIX,
|
|
65
|
+
PRE_WORKTREE_ROOT_PREFIX,
|
|
62
66
|
LEGACY_ROOT_PREFIX,
|
|
63
67
|
].map((prefix) => JSON.stringify(prefix).slice(1, -1))
|
|
64
68
|
const [PROJECT_ROOT_PREFIX = ''] = ROOT_PREFIXES
|
|
@@ -87,7 +91,7 @@ function rewrite_command_value(value: string): string {
|
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
// kit's own commands already start from the root (`hook-launch.ts`), and so does an already-rewritten
|
|
90
|
-
// value. The prefix — the current one or
|
|
94
|
+
// value. The prefix — the current one or an earlier one — is taken off before the rewrite and the
|
|
91
95
|
// current one put back after it, so the install guard sits behind the `cd` it depends on and a second
|
|
92
96
|
// pass never doubles the prefix.
|
|
93
97
|
function without_root_prefix(value: string): string {
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
// first without the git location variables a git hook leaks, since a relative or bare `GIT_DIR` read
|
|
11
11
|
// from a subdirectory names the wrong work tree, and with them only when the checkout does not resolve
|
|
12
12
|
// without them (its metadata lives outside the work tree). A lookup that fails ends the command before
|
|
13
|
-
// the launcher (joshuafolkken/kit#4187).
|
|
13
|
+
// the launcher (joshuafolkken/kit#4187). Inside one of Claude Code's own worktrees `CLAUDE_PROJECT_DIR`
|
|
14
|
+
// still names the main checkout, so the prefix exports where the hook was launched as `JOSH_HOOK_CWD`
|
|
15
|
+
// and the launcher moves the hook's working directory into that worktree (joshuafolkken/kit#4617).
|
|
14
16
|
//
|
|
15
17
|
// **Everything after the root is one script** (`scripts/hooks/run-hook.sh`): the git location
|
|
16
18
|
// variables a git hook exports, the bundle-ready gate and the live-source fallback live there once, so
|
|
@@ -23,7 +25,7 @@ const HOOK_DIST_DIR = 'dist/hooks'
|
|
|
23
25
|
const RUN_HOOK_SCRIPT = 'scripts/hooks/run-hook.sh'
|
|
24
26
|
const ROOT_LOOKUP = 'git rev-parse --show-toplevel'
|
|
25
27
|
const CODEX_ROOT = `$( (unset ${GIT_LOCATION_VARIABLES.join(' ')}; ${ROOT_LOOKUP} 2>/dev/null) || ${ROOT_LOOKUP})`
|
|
26
|
-
const PROJECT_ROOT_PREFIX = `project_root="\${CLAUDE_PROJECT_DIR:-${CODEX_ROOT}}" && cd "$project_root" && `
|
|
28
|
+
const PROJECT_ROOT_PREFIX = `export JOSH_HOOK_CWD="$PWD" && project_root="\${CLAUDE_PROJECT_DIR:-${CODEX_ROOT}}" && cd "$project_root" && `
|
|
27
29
|
|
|
28
30
|
// `name` is the hook's bundle under `dist/hooks` without `.js` (e.g. `pretool-guard`), followed by any
|
|
29
31
|
// arguments it takes (e.g. `codex-hook-adapter pretool`).
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { markdown_section } from './markdown-section'
|
|
2
|
+
import { size_estimate } from './size-estimate'
|
|
3
|
+
|
|
4
|
+
// joshuafolkken/kit#5190: #5162 carried "aggregate the transcripts and record it as an Issue comment"
|
|
5
|
+
// beside a six-file implementation; the aggregation's output filled the lane's context before the
|
|
6
|
+
// implementation began and cut the session. The aggregation is a mergeable result of its own, so a body
|
|
7
|
+
// asking for both is refused and the aggregation routed to a prior `--route split` Issue — the
|
|
8
|
+
// implementation Issue then starts from the comment it cites.
|
|
9
|
+
|
|
10
|
+
const CRITERIA_HEADING = '## 受け入れ条件'
|
|
11
|
+
const CRITERION_PREFIX = '- ['
|
|
12
|
+
// Recording on an Issue, not a feature that posts a PR comment: every one of these words names the
|
|
13
|
+
// lane's own act.
|
|
14
|
+
const RECORDING_WORDS: ReadonlyArray<string> = ['Issue', 'コメント', '記録']
|
|
15
|
+
// What is recorded: an aggregation, or a measurement — #5202's before / after reach count, which carried
|
|
16
|
+
// no aggregation word and passed (joshuafolkken/kit#5238). One of them is enough.
|
|
17
|
+
const SUBJECT_WORDS: ReadonlyArray<string> = ['集計', '計測', 'before', '変更前後']
|
|
18
|
+
// A criterion citing the prior aggregation Issue is the implementation this rule asks for.
|
|
19
|
+
const ISSUE_REFERENCE = /#\d+/u
|
|
20
|
+
// The implementation the estimate declares: a prior aggregation Issue may add a script or two of its own.
|
|
21
|
+
const IMPLEMENTATION_FILES = 3
|
|
22
|
+
const REFUSAL = `an acceptance criterion records an aggregation or a measurement as an Issue comment beside an implementation of ${String(IMPLEMENTATION_FILES)}+ files — file it as a prior Issue (\`--route split\`) and cite its comment under ## 背景 in this one; issue-template.md → "\`## 背景\` 直下の宣言と分類ラベル"`
|
|
23
|
+
|
|
24
|
+
function is_aggregation_criterion(line: string): boolean {
|
|
25
|
+
const text = line.trim()
|
|
26
|
+
|
|
27
|
+
if (!text.startsWith(CRITERION_PREFIX) || ISSUE_REFERENCE.test(text)) return false
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
SUBJECT_WORDS.some((word) => text.includes(word)) &&
|
|
31
|
+
RECORDING_WORDS.every((word) => text.includes(word))
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function has_aggregation_criterion(body: string): boolean {
|
|
36
|
+
const criteria = markdown_section.section_lines(body, CRITERIA_HEADING).join('\n')
|
|
37
|
+
|
|
38
|
+
return markdown_section.unfenced_lines(criteria).some((line) => is_aggregation_criterion(line))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function declares_implementation(body: string): boolean {
|
|
42
|
+
return (size_estimate.declared_files(body) ?? 0) >= IMPLEMENTATION_FILES
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// The refusal for a body carrying both; empty for an aggregation alone or an implementation alone.
|
|
46
|
+
function problems(body: string): ReadonlyArray<string> {
|
|
47
|
+
return has_aggregation_criterion(body) && declares_implementation(body) ? [REFUSAL] : []
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const aggregation_split = { IMPLEMENTATION_FILES, problems }
|
|
51
|
+
|
|
52
|
+
export { aggregation_split }
|