@joshuafolkken/kit 1.1240.0 → 1.1370.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/investigator.md +1 -0
- package/.claude/settings.json +4 -0
- package/.claude/skills/dependency-update/SKILL.md +5 -3
- package/.claude/skills/epic-commands/SKILL.md +82 -113
- package/.claude/skills/epic-commands/epic-bundle.md +38 -63
- package/.claude/skills/epic-commands/execution-waves.md +30 -51
- package/.claude/skills/verify-ui/SKILL.md +13 -20
- package/.claude/skills/workflow-commands/SKILL.md +10 -10
- package/.claude/skills/workflow-commands/background-commands.md +4 -4
- package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
- package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
- package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
- package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
- package/.claude/skills/workflow-commands/backlogrun.md +50 -61
- package/.claude/skills/workflow-commands/chain-rule.md +36 -40
- package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
- package/.claude/skills/workflow-commands/followup.md +19 -20
- package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
- package/.claude/skills/workflow-commands/fullrun.md +10 -10
- package/.claude/skills/workflow-commands/halfrun.md +9 -8
- package/.claude/skills/workflow-commands/into-target.md +12 -18
- package/.claude/skills/workflow-commands/issue-comments.md +11 -26
- package/.claude/skills/workflow-commands/kickoff.md +26 -16
- package/.claude/skills/workflow-commands/latest-gate.md +17 -28
- package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
- package/.claude/skills/workflow-commands/observation-filing.md +37 -28
- package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
- package/.claude/skills/workflow-commands/prerequisite.md +23 -15
- package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
- package/.claude/skills/workflow-commands/prrun.md +3 -3
- package/.claude/skills/workflow-commands/retrospective.md +13 -18
- package/.claude/skills/workflow-commands/split-assessment.md +6 -4
- package/.claude/skills/workflow-commands/target-repository.md +25 -28
- package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
- package/.gitattributes +2 -1
- package/.github/workflows/ci.yml +14 -0
- package/.vscode/tasks.json +14 -0
- package/CLAUDE.md +10 -61
- package/README.md +29 -47
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +10 -61
- package/dist/commands/document-section-cli.js +42 -10
- package/dist/config-merge/index.js +11 -2
- package/dist/hooks/audit-provision.js +2 -2
- package/dist/hooks/batch-guard.js +7 -7
- package/dist/hooks/{chunk-KHGB5S3Y.js → chunk-43G45XJF.js} +18 -20
- package/dist/hooks/{chunk-4TZVB44A.js → chunk-4TW4MQUL.js} +284 -362
- package/dist/hooks/{chunk-XZYKEM6J.js → chunk-76RK6E3H.js} +13 -11
- package/dist/hooks/{chunk-F3ELQ2AF.js → chunk-DZWZ3DKY.js} +4 -4
- package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
- package/dist/hooks/{chunk-GPTFMK5E.js → chunk-GG72ANKI.js} +1 -1
- package/dist/hooks/{chunk-ZQGD4GBY.js → chunk-KPM4YIIX.js} +8 -44
- package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
- package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
- package/dist/hooks/{chunk-QVSWU24O.js → chunk-NZBHG6FW.js} +7 -5
- package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
- package/dist/hooks/{chunk-KRBERBBI.js → chunk-R6CRQEAL.js} +4 -4
- package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
- package/dist/hooks/{chunk-WK2XSHSI.js → chunk-TLJYAGZK.js} +549 -874
- package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
- package/dist/hooks/codex-hook-adapter.js +26 -21
- package/dist/hooks/duplicate-read-guard.js +8 -8
- package/dist/hooks/format-edited.js +4 -4
- package/dist/hooks/inputs.json +216 -202
- package/dist/hooks/investigation-guard.js +8 -8
- package/dist/hooks/pretool-guard.js +15 -15
- package/dist/hooks/session-lang.js +406 -8
- package/dist/hooks/stop-guard.js +122 -187
- package/dist/josh.js +281 -94
- package/dist/version/index.js +15 -13
- package/eslint/base.js +43 -5
- package/eslint/rules/english-only-prose.js +3 -3
- package/eslint/rules/import.js +12 -0
- package/eslint/rules/namespace-object-export.js +2 -2
- package/package.json +16 -10
- package/pnpm-workspace.yaml +2 -4
- package/prompts/coding-standards.md +14 -48
- package/prompts/collaboration-workflow/file-edits.md +1 -1
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +3 -10
- package/prompts/collaboration-workflow/operating-rules.md +7 -8
- package/prompts/collaboration-workflow/output-bounds.md +1 -1
- package/prompts/collaboration-workflow/overview.md +1 -1
- package/prompts/collaboration-workflow/plan-comment.md +2 -1
- package/prompts/collaboration-workflow/principles.md +21 -3
- package/prompts/collaboration-workflow/report-format.md +16 -29
- package/prompts/collaboration-workflow/residency.md +1 -1
- package/prompts/collaboration-workflow/rule-delivery.md +7 -95
- package/prompts/collaboration-workflow/shell-body.md +3 -23
- package/prompts/collaboration-workflow/turn-batching.md +4 -13
- package/prompts/collaboration-workflow/wip-cap.md +5 -11
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +3 -22
- package/prompts/review.md +15 -38
- package/prompts/testing-guide.md +2 -4
- package/scripts/adopt/adopt-logic.ts +5 -5
- package/scripts/adopt/adopt-toolkits.ts +4 -5
- package/scripts/adopt/adopt.ts +2 -3
- package/scripts/agent/agent-argv.ts +7 -7
- package/scripts/agent/agent-diagnostics.ts +2 -2
- package/scripts/agent/agent-exit-record.ts +1 -1
- package/scripts/agent/agent-headless.ts +1 -1
- package/scripts/agent/agent-launch-environment.ts +6 -1
- package/scripts/agent/agent-role-profile.ts +49 -22
- package/scripts/agent/agent-session-role.ts +32 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/claude-agent-argv.ts +4 -4
- package/scripts/agent/claude-result-event.ts +4 -4
- package/scripts/agent/codex-hooks.ts +2 -2
- package/scripts/agent/interactive-ask.ts +3 -6
- package/scripts/auto-ok/auto-ok-cli.ts +46 -60
- package/scripts/backlog/backlog-arrival-added.ts +34 -0
- package/scripts/backlog/backlog-arrival.ts +54 -17
- package/scripts/backlog/backlog-budget-cli.ts +34 -6
- package/scripts/backlog/backlog-budget.ts +17 -24
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-args.ts +5 -4
- package/scripts/backlog/backlog-drive-cli.ts +14 -10
- package/scripts/backlog/backlog-drive-epic.ts +85 -0
- package/scripts/backlog/backlog-drive-launch.ts +1 -1
- package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
- package/scripts/backlog/backlog-drive-named.ts +39 -9
- package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
- package/scripts/backlog/backlog-drive-restore.ts +1 -1
- package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
- package/scripts/backlog/backlog-drive.ts +43 -28
- package/scripts/backlog/backlog-idle.ts +88 -0
- package/scripts/backlog/backlog-named.ts +11 -15
- package/scripts/backlog/backlog-next.ts +26 -30
- package/scripts/backlog/backlog-offer-cli.ts +28 -23
- package/scripts/backlog/backlog-offer.ts +7 -7
- package/scripts/backlog/backlog-overlap.ts +178 -0
- package/scripts/backlog/backlog-plan-cli.ts +14 -90
- package/scripts/backlog/backlog-plan-read.ts +111 -0
- package/scripts/backlog/backlog-plan.ts +11 -10
- package/scripts/backlog/backlog-pool.ts +13 -14
- package/scripts/backlog/backlog-rank.ts +11 -11
- package/scripts/backlog/backlog-ready.ts +15 -10
- package/scripts/backlog/backlog-scope.ts +14 -15
- package/scripts/backlog/backlog-stalled-cli.ts +2 -2
- package/scripts/backlog/backlog-stalled-detect.ts +4 -4
- package/scripts/backlog/backlog-stalled.ts +5 -6
- package/scripts/backlog/backlog-waves.ts +4 -4
- package/scripts/backlog/backlogrun-args.ts +74 -0
- package/scripts/backlog/backlogrun-cli.ts +113 -0
- package/scripts/backlog/backlogrun-launch.ts +178 -0
- package/scripts/behavior/behavior-assertion.ts +6 -8
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/behavior/behavior-rules.ts +3 -3
- package/scripts/build/build-claude-md.ts +4 -4
- package/scripts/build/build-codex-hooks.ts +2 -2
- package/scripts/build/build-commands.ts +1 -1
- package/scripts/build/build-hooks.ts +5 -5
- package/scripts/build/build.ts +1 -1
- package/scripts/build/hook-bundle-stamp.ts +109 -7
- package/scripts/build/local-bin.ts +2 -2
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +2 -2
- package/scripts/ci/composite-actions.ts +1 -2
- package/scripts/ci/pr-classification.ts +2 -2
- package/scripts/claude/workflow-destination.ts +1 -1
- package/scripts/clone/clone-aggregate.ts +1 -1
- package/scripts/clone/clone-fingerprint.ts +1 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/index.ts +1 -1
- package/scripts/config-merge/json-format.ts +1 -3
- package/scripts/config-merge/patch-json-array.ts +90 -0
- package/scripts/config-merge/patch-json-key.ts +6 -3
- package/scripts/config-merge/patch-json-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +1 -1
- package/scripts/cost-runtime/context-cut-payback.ts +4 -5
- package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
- package/scripts/cost-runtime/cost-attribute.ts +3 -3
- package/scripts/cost-runtime/cost-blocks.ts +3 -4
- package/scripts/cost-runtime/cost-cli.ts +14 -11
- package/scripts/cost-runtime/cost-corpus.ts +11 -11
- package/scripts/cost-runtime/cost-pricing.ts +4 -4
- package/scripts/cost-runtime/cost-tokens.ts +1 -2
- package/scripts/cost-runtime/cost-transcript.ts +29 -29
- package/scripts/cost-runtime/cost-usage.ts +6 -7
- package/scripts/cost-runtime/cost-verdict.ts +10 -11
- package/scripts/cost-runtime/own-session.ts +1 -1
- package/scripts/cost-runtime/transcript-cwd.ts +2 -2
- package/scripts/delegation/delegation-cli.ts +4 -4
- package/scripts/delegation/delegation-policy.ts +13 -15
- package/scripts/delegation/duplicate-read-guard.ts +9 -10
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +1 -1
- package/scripts/delegation/investigation-guard.ts +18 -22
- package/scripts/delegation/investigation-reads.ts +48 -238
- package/scripts/discovery/repo-discovery.ts +1 -1
- package/scripts/discovery/repo-map-logic.ts +1 -2
- package/scripts/discovery/repo-origin.ts +3 -3
- package/scripts/discovery/repo-party-cli.ts +2 -2
- package/scripts/discovery/repo-party.ts +2 -2
- package/scripts/doctor/doctor-consumer.ts +1 -1
- package/scripts/doctor/doctor-io.ts +6 -7
- package/scripts/doctor/doctor-logic.ts +1 -1
- package/scripts/doctor/doctor-ports.ts +1 -1
- package/scripts/doctor/doctor.ts +8 -9
- package/scripts/document/backlogrun-parent-read-set.ts +5 -6
- package/scripts/document/bash-output-cap.ts +5 -7
- package/scripts/document/capped-print-part.ts +1 -1
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/document-byte-budget.ts +33 -64
- package/scripts/document/document-byte-check.ts +4 -4
- package/scripts/document/document-reachability.ts +7 -8
- package/scripts/document/document-read-cli.ts +2 -2
- package/scripts/document/document-scan.ts +26 -2
- package/scripts/document/document-section-cli.ts +6 -8
- package/scripts/document/document-section.ts +8 -12
- package/scripts/document/edit-files-cli.ts +3 -4
- package/scripts/document/entry-read-budget.ts +8 -70
- package/scripts/document/entry-read-set.ts +51 -34
- package/scripts/document/lane-child-read-set.ts +9 -9
- package/scripts/document/read-files-cli.ts +1 -2
- package/scripts/document/read-set-cli.ts +16 -19
- package/scripts/document/read-set-cost.ts +4 -4
- package/scripts/document/read-set-point-of-use.ts +28 -38
- package/scripts/document/read-set-pricing.ts +1 -1
- package/scripts/document/read-set-trim.ts +3 -3
- package/scripts/document/resident-budget.ts +8 -10
- package/scripts/epic/epic-add-body.ts +15 -18
- package/scripts/epic/epic-add-plan.ts +26 -28
- package/scripts/epic/epic-add.ts +32 -25
- package/scripts/epic/epic-audit-checks.ts +27 -37
- package/scripts/epic/epic-audit-cli.ts +21 -22
- package/scripts/epic/epic-audit-orphans.ts +16 -17
- package/scripts/epic/epic-audit-rationale.ts +10 -15
- package/scripts/epic/epic-audit-report.ts +2 -5
- package/scripts/epic/epic-audit.ts +18 -14
- package/scripts/epic/epic-body.ts +10 -10
- package/scripts/epic/epic-bundle-cli.ts +36 -34
- package/scripts/epic/epic-bundle-evidence.ts +5 -5
- package/scripts/epic/epic-bundle-gaps.ts +6 -9
- package/scripts/epic/epic-bundle-poll.ts +1 -1
- package/scripts/epic/epic-bundle-referenced.ts +11 -14
- package/scripts/epic/epic-bundle.ts +19 -20
- package/scripts/epic/epic-busy.ts +44 -21
- package/scripts/epic/epic-candidate-confirm.ts +15 -18
- package/scripts/epic/epic-chains.ts +18 -23
- package/scripts/epic/epic-classify.ts +11 -12
- package/scripts/epic/epic-cli-argv.ts +5 -6
- package/scripts/epic/epic-cli-remove.ts +9 -4
- package/scripts/epic/epic-cli.ts +38 -26
- package/scripts/epic/epic-close-comment.ts +14 -15
- package/scripts/epic/epic-close.ts +25 -29
- package/scripts/epic/epic-cross-repo.ts +18 -21
- package/scripts/epic/epic-decision.ts +14 -18
- package/scripts/epic/epic-fetch.ts +25 -31
- package/scripts/epic/epic-graph.ts +15 -17
- package/scripts/epic/epic-index.ts +14 -16
- package/scripts/epic/epic-issue.ts +9 -11
- package/scripts/epic/epic-label-age.ts +74 -0
- package/scripts/epic/epic-lane-offer.ts +35 -24
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +8 -8
- package/scripts/epic/epic-next-views.ts +12 -12
- package/scripts/epic/epic-next.ts +29 -33
- package/scripts/epic/epic-outside-blocker.ts +11 -10
- package/scripts/epic/epic-parse.ts +22 -24
- package/scripts/epic/epic-promote.ts +3 -2
- package/scripts/epic/epic-rank.ts +1 -1
- package/scripts/epic/epic-read.ts +10 -8
- package/scripts/epic/epic-reconcile.ts +8 -6
- package/scripts/epic/epic-reference.ts +5 -4
- package/scripts/epic/epic-relation-recheck.ts +10 -11
- package/scripts/epic/epic-relations.ts +9 -8
- package/scripts/epic/epic-remove-plan.ts +4 -5
- package/scripts/epic/epic-remove.ts +7 -5
- package/scripts/epic/epic-report.ts +18 -20
- package/scripts/epic/epic-run.ts +6 -5
- package/scripts/epic/epic-sections.ts +2 -2
- package/scripts/epic/epic-shape.ts +3 -3
- package/scripts/epic/epic-solo-stale.ts +3 -2
- package/scripts/epic/epic-solo.ts +8 -8
- package/scripts/epic/epic-triage.ts +5 -4
- package/scripts/epic/epic-validate.ts +8 -7
- package/scripts/epic/epic.ts +5 -5
- package/scripts/exports/unused-members-cli.ts +1 -1
- package/scripts/followup/followup-issue-number.ts +1 -2
- package/scripts/followup/git-followup-cleanup.ts +6 -7
- package/scripts/followup/git-followup-finish.ts +11 -13
- package/scripts/followup/git-followup-flush.ts +11 -7
- package/scripts/followup/git-followup-issue-close.ts +16 -13
- package/scripts/followup/git-followup-label.ts +9 -6
- package/scripts/followup/git-followup-merged.ts +1 -1
- package/scripts/followup/git-followup-pending.ts +7 -9
- package/scripts/followup/git-followup-stages.ts +28 -17
- package/scripts/followup/git-followup-workflow.ts +19 -21
- package/scripts/followup/git-pr-followup-checks.ts +13 -20
- package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
- package/scripts/followup/git-pr-followup.ts +18 -17
- package/scripts/gate/core-admission.ts +2 -2
- package/scripts/gate/core-budget.ts +15 -26
- package/scripts/gate/gate-ledger.ts +114 -0
- package/scripts/gate/gate-log.ts +7 -9
- package/scripts/gate/gate-plan.ts +70 -35
- package/scripts/gate/gate-report.ts +14 -15
- package/scripts/gate/gate-skip.ts +11 -13
- package/scripts/gate/gate-steps.ts +5 -1
- package/scripts/gate/gate-tree.ts +3 -4
- package/scripts/gate/hook-gate-reuse.ts +9 -9
- package/scripts/gate/machine-capacity.ts +168 -30
- package/scripts/gate/pre-commit-type-check.ts +4 -4
- package/scripts/gate/project-checks.ts +12 -4
- package/scripts/gate/scoped-green.ts +11 -18
- package/scripts/gate/type-check-command.ts +2 -2
- package/scripts/gate/type-check-step.ts +4 -4
- package/scripts/gate/verification-gate.ts +53 -51
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/gh/git-ai-review-scan.ts +3 -2
- package/scripts/gh/git-gh-api-path.ts +10 -11
- package/scripts/gh/git-gh-exec.ts +43 -48
- package/scripts/gh/git-gh-failure.ts +6 -9
- package/scripts/gh/git-gh-helpers.ts +1 -1
- package/scripts/gh/git-gh-issue-list.ts +15 -19
- package/scripts/gh/git-gh-issue-read.ts +43 -60
- package/scripts/gh/git-gh-issue-rest.ts +14 -15
- package/scripts/gh/git-gh-issue-write.ts +52 -40
- package/scripts/gh/git-gh-issue.ts +23 -24
- package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
- package/scripts/gh/git-gh-pr-read.ts +46 -50
- package/scripts/gh/git-gh-pr-rest.ts +23 -26
- package/scripts/gh/git-gh-pr-review.ts +2 -2
- package/scripts/gh/git-gh-pr-rollup.ts +4 -4
- package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
- package/scripts/gh/git-gh-pr.ts +16 -16
- package/scripts/gh/git-gh-reachability.ts +11 -12
- package/scripts/gh/git-gh-repo.ts +2 -3
- package/scripts/gh/git-gh-rest-state.ts +1 -1
- package/scripts/gh/git-pr-ai-review.ts +6 -5
- package/scripts/gh/git-pr-checks-eval.ts +28 -30
- package/scripts/gh/git-pr-checks-parse.ts +14 -16
- package/scripts/gh/git-pr-checks-watch.ts +17 -17
- package/scripts/gh/git-pr-checks.ts +20 -23
- package/scripts/gh/git-pr-coderabbit.ts +8 -6
- package/scripts/gh/git-pr-confirmation.ts +5 -5
- package/scripts/gh/git-pr-managed-config.ts +7 -9
- package/scripts/gh/git-pr-messages.ts +1 -1
- package/scripts/gh/git-pr.ts +15 -16
- package/scripts/gh/github-issue-url.ts +8 -9
- package/scripts/git/base-tree.ts +66 -0
- package/scripts/git/change-base.ts +42 -2
- package/scripts/git/changed-file-scope.ts +5 -5
- package/scripts/git/changed-paths.ts +1 -2
- package/scripts/git/constants.ts +2 -2
- package/scripts/git/git-branch.ts +1 -1
- package/scripts/git/git-closes-keyword.ts +3 -3
- package/scripts/git/git-command.ts +53 -41
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +14 -15
- package/scripts/git/git-error.ts +1 -1
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/git/git-issue.ts +10 -8
- package/scripts/git/git-location-environment.ts +3 -4
- package/scripts/git/git-ls-remote.ts +6 -8
- package/scripts/git/git-pre-push-hook.ts +11 -10
- package/scripts/git/git-preflight.ts +5 -5
- package/scripts/git/git-push-transport.ts +2 -2
- package/scripts/git/git-remote-branch.ts +1 -2
- package/scripts/git/git-schemas.ts +16 -23
- package/scripts/git/git-spawn-sync.ts +1 -1
- package/scripts/git/git-spawn.ts +37 -14
- package/scripts/git/git-ssh-keepalive.ts +12 -5
- package/scripts/git/git-staging.ts +7 -8
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/git-worktree.ts +35 -27
- package/scripts/git/gone-branch.ts +2 -2
- package/scripts/git/listing-cutoff.ts +1 -2
- package/scripts/git/lockfile-sync.ts +65 -0
- package/scripts/git/main-merge-guard.ts +1 -2
- package/scripts/git/main-merge.ts +7 -7
- package/scripts/git/main-sync.ts +23 -8
- package/scripts/git/parse-json-array.ts +18 -23
- package/scripts/git/repository-lock.ts +34 -2
- package/scripts/git/stash/git-stash.ts +4 -5
- package/scripts/git/stash/stash-orphans.ts +5 -3
- package/scripts/git/stash/stash-pop-args.ts +1 -1
- package/scripts/git/stash/stash-pop-cli.ts +3 -3
- package/scripts/git/stash/stash-sweep-lock.ts +2 -2
- package/scripts/hooks/batch-guard.ts +11 -13
- package/scripts/hooks/check-commit-message.ts +12 -9
- package/scripts/hooks/codex-hook-adapter.ts +16 -10
- package/scripts/hooks/edited-cspell.ts +3 -4
- package/scripts/hooks/format-edited-cli.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +11 -17
- package/scripts/hooks/format-rewrite-notice.ts +19 -17
- package/scripts/hooks/pre-push-unit.ts +10 -14
- package/scripts/hooks/pretool-guard-cli.ts +4 -4
- package/scripts/hooks/pretool-guard.ts +93 -18
- package/scripts/hooks/reserved-run.ts +2 -2
- package/scripts/hooks/step-zero-notice.ts +1 -1
- package/scripts/hooks/stop-guard.ts +21 -10
- package/scripts/init/basic-path-migration.ts +2 -2
- package/scripts/init/claude-kit-only-settings.ts +2 -2
- package/scripts/init/claude-plugin-config.ts +2 -2
- package/scripts/init/distributed-paths.ts +4 -4
- package/scripts/init/hook-command-rewrite.ts +3 -3
- package/scripts/init/hook-launch.ts +5 -5
- package/scripts/init/init-actions.ts +13 -0
- package/scripts/init/init-ai-copy.ts +11 -11
- package/scripts/init/init-bootstrap.ts +3 -3
- package/scripts/init/init-copy-content.ts +4 -4
- package/scripts/init/init-logic-json-merge.ts +7 -9
- package/scripts/init/init-logic-migrate.ts +1 -1
- package/scripts/init/init-logic-templates.ts +1 -1
- package/scripts/init/init-logic-workspace.ts +4 -4
- package/scripts/init/init-logic-yaml-merge.ts +2 -2
- package/scripts/init/init-logic.ts +19 -22
- package/scripts/init/init.ts +7 -7
- package/scripts/init/kit-base-preset.ts +1 -1
- package/scripts/init/kit-setup-state.ts +1 -1
- package/scripts/init/kit-written-paths.ts +1 -2
- package/scripts/init/package-manager-pin.ts +1 -1
- package/scripts/init/project-profile-cli.ts +1 -1
- package/scripts/init/project-profile.ts +3 -3
- package/scripts/init/session-language-environment.ts +1 -1
- package/scripts/init/start-exec.ts +3 -4
- package/scripts/init/start-plan.ts +2 -2
- package/scripts/init/start-setup-pr.ts +3 -2
- package/scripts/init/start-steps.ts +2 -2
- package/scripts/init/tsconfig-preset-migration.ts +1 -1
- package/scripts/init/vscode-tasks.ts +62 -0
- package/scripts/issue/baseline-measure.ts +2 -2
- package/scripts/issue/behavior-change-lint.ts +2 -2
- package/scripts/issue/defect-rate-cli.ts +6 -7
- package/scripts/issue/defect-rate.ts +37 -27
- package/scripts/issue/git-next-issues.ts +9 -8
- package/scripts/issue/issue-auto-ok.ts +24 -11
- package/scripts/issue/issue-backlinks-cli.ts +5 -5
- package/scripts/issue/issue-backlinks.ts +6 -6
- package/scripts/issue/issue-cite-cli.ts +20 -18
- package/scripts/issue/issue-cite.ts +18 -8
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +6 -4
- package/scripts/issue/issue-file-cli.ts +52 -15
- package/scripts/issue/issue-file-fold.ts +155 -0
- package/scripts/issue/issue-file.ts +9 -6
- package/scripts/issue/issue-fold-cli.ts +14 -9
- package/scripts/issue/issue-fold.ts +23 -8
- package/scripts/issue/issue-labels.ts +34 -38
- package/scripts/issue/issue-lint-cli.ts +2 -2
- package/scripts/issue/issue-lint.ts +1 -1
- package/scripts/issue/issue-merged.ts +10 -4
- package/scripts/issue/issue-number-shape.ts +27 -0
- package/scripts/issue/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +4 -5
- package/scripts/issue/issue-read.ts +4 -5
- package/scripts/issue/issue-reference.ts +5 -5
- package/scripts/issue/issue-release-cli.ts +17 -7
- package/scripts/issue/issue-release.ts +3 -3
- package/scripts/issue/issue-report-failures.ts +7 -4
- package/scripts/issue/issue-scout-cli.ts +11 -11
- package/scripts/issue/issue-scout-closed.ts +4 -4
- package/scripts/issue/issue-scout.ts +4 -5
- package/scripts/issue/issue-state-cli.ts +17 -10
- package/scripts/issue/issue-state.ts +12 -13
- package/scripts/issue/issue-wip.ts +7 -7
- package/scripts/issue/markdown-section.ts +3 -3
- package/scripts/issue/measure-rerun-cli.ts +10 -9
- package/scripts/issue/reproduction-measure.ts +3 -3
- package/scripts/issue/session-cite.ts +56 -0
- package/scripts/josh/agent-session-environment.ts +10 -8
- package/scripts/josh/cli-body.ts +2 -2
- package/scripts/josh/command-suggest.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +20 -23
- package/scripts/josh/hook-decision.ts +24 -28
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +30 -35
- package/scripts/josh/josh-commands-ai.ts +6 -6
- package/scripts/josh/josh-commands-backlog.ts +15 -3
- package/scripts/josh/josh-commands-clone.ts +1 -1
- package/scripts/josh/josh-commands-development.ts +25 -4
- package/scripts/josh/josh-commands-document.ts +3 -3
- package/scripts/josh/josh-commands-guard.ts +3 -3
- package/scripts/josh/josh-commands-issue.ts +4 -5
- package/scripts/josh/josh-commands-lane.ts +14 -4
- package/scripts/josh/josh-commands-lint.ts +1 -1
- package/scripts/josh/josh-commands-run.ts +20 -6
- package/scripts/josh/josh-commands-split.ts +1 -2
- package/scripts/josh/josh-commands-versioning.ts +5 -5
- package/scripts/josh/josh-commands-workflow.ts +30 -22
- package/scripts/josh/josh-environment-file.ts +1 -1
- package/scripts/josh/josh-in-process.ts +3 -3
- package/scripts/josh/josh-logic.ts +6 -7
- package/scripts/josh/josh-run.ts +3 -3
- package/scripts/josh/josh-verdict.ts +9 -12
- package/scripts/josh/josh.ts +3 -3
- package/scripts/josh/kit-only.ts +2 -2
- package/scripts/josh/path-decision.ts +3 -3
- package/scripts/josh/platform-temporary.ts +7 -5
- package/scripts/josh/process-identity.ts +24 -6
- package/scripts/josh/process-owner.ts +4 -4
- package/scripts/josh/session-language-cli.ts +53 -11
- package/scripts/josh/session-language.ts +1 -1
- package/scripts/josh/stamp-file.ts +48 -29
- package/scripts/josh/stamp-record.ts +57 -0
- package/scripts/lane/lane-await.ts +35 -11
- package/scripts/lane/lane-cache.ts +6 -6
- package/scripts/lane/lane-capacity.ts +32 -17
- package/scripts/lane/lane-child-invocation.ts +17 -15
- package/scripts/lane/lane-child-marker.ts +12 -12
- package/scripts/lane/lane-cli.ts +12 -13
- package/scripts/lane/lane-close.ts +6 -6
- package/scripts/lane/lane-dispatch.ts +61 -72
- package/scripts/lane/lane-environment.ts +5 -5
- package/scripts/lane/lane-guard-policy.ts +7 -21
- package/scripts/lane/lane-handoff.ts +2 -2
- package/scripts/lane/lane-install.ts +9 -10
- package/scripts/lane/lane-launch-cli.ts +13 -8
- package/scripts/lane/lane-ledger.ts +73 -11
- package/scripts/lane/lane-leftover.ts +2 -2
- package/scripts/lane/lane-limit-cli.ts +160 -0
- package/scripts/lane/lane-limit-override.ts +74 -0
- package/scripts/lane/lane-load.ts +19 -68
- package/scripts/lane/lane-measure-cli.ts +15 -25
- package/scripts/lane/lane-occupancy.ts +6 -4
- package/scripts/lane/lane-open.ts +20 -19
- package/scripts/lane/lane-output.ts +4 -3
- package/scripts/lane/lane-paths.ts +12 -11
- package/scripts/lane/lane-phase.ts +33 -0
- package/scripts/lane/lane-reap.ts +2 -2
- package/scripts/lane/lane-registry.ts +16 -15
- package/scripts/lane/lane-relaunch.ts +9 -9
- package/scripts/lane/lane-report.ts +5 -4
- package/scripts/lane/lane-resume.ts +2 -2
- package/scripts/lane/lane-sampler.ts +55 -0
- package/scripts/lane/lane-seed.ts +7 -7
- package/scripts/lane/lane-stage-stats.ts +135 -0
- package/scripts/lane/lane-start-point.ts +8 -11
- package/scripts/lane/lane-stats.ts +60 -15
- package/scripts/lane/lane-stray.ts +1 -1
- package/scripts/lane/lane-vacant.ts +1 -1
- package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
- package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
- package/scripts/lane/openai-review-broker.ts +2 -4
- package/scripts/lib/ancestor-directories.ts +1 -1
- package/scripts/lib/bounded-pool.ts +2 -2
- package/scripts/lib/buffered-process.ts +4 -6
- package/scripts/lib/caddy-logs.sh +0 -0
- package/scripts/lib/cli-flags.ts +39 -6
- package/scripts/lib/error-message.ts +1 -1
- package/scripts/lib/json-value.ts +17 -3
- package/scripts/lib/poll.ts +1 -1
- package/scripts/lib/status-icons.ts +3 -3
- package/scripts/lib/timed-fetch.ts +1 -1
- package/scripts/lib/timeouts.ts +1 -1
- package/scripts/lines/bytes-command.ts +3 -4
- package/scripts/lines/effective-limit.ts +25 -12
- package/scripts/lines/line-budget.ts +47 -55
- package/scripts/lines/line-targets.ts +6 -2
- package/scripts/lines/lines-command.ts +3 -3
- package/scripts/lint/cspell-cached.ts +1 -1
- package/scripts/lint/cycle-recheck.ts +122 -0
- package/scripts/lint/format.ts +1 -2
- package/scripts/lint/lint-parallel.ts +34 -19
- package/scripts/lint/lint-related-scope.ts +25 -15
- package/scripts/lint/lint-related.ts +6 -7
- package/scripts/managed-marker/index.ts +1 -1
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/git-notify.ts +9 -7
- package/scripts/notify/telegram-notify.ts +53 -37
- package/scripts/notify/telegram-test-logic.ts +3 -3
- package/scripts/notify/telegram-test.ts +45 -30
- package/scripts/observations/observation-ledger-home.ts +14 -8
- package/scripts/observations/observation-ledger-line.ts +3 -2
- package/scripts/observations/observation-ledger-migrate.ts +3 -4
- package/scripts/observations/observation-ledger-prepare.ts +4 -4
- package/scripts/observations/observation-ledger.ts +14 -15
- package/scripts/observations/observation-record-cli.ts +83 -0
- package/scripts/observations/observation-record.ts +91 -0
- package/scripts/observations/observations-flush-cli.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +7 -6
- package/scripts/observations/observations-flush.ts +26 -27
- package/scripts/overrides/overrides-check.ts +18 -8
- package/scripts/package/package-scout-cli.ts +1 -1
- package/scripts/package/package-scout-format.ts +2 -2
- package/scripts/package/package-scout.ts +1 -1
- package/scripts/propagate/propagate-git-failure.ts +1 -1
- package/scripts/propagate/propagate-git.ts +7 -7
- package/scripts/propagate/propagate-plan.ts +2 -2
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +5 -7
- package/scripts/propagate/propagate-select.ts +1 -1
- package/scripts/propagate/propagate-steps.ts +19 -20
- package/scripts/propagate/propagate-targets.ts +6 -10
- package/scripts/propagate/propagate.ts +5 -5
- package/scripts/refactor/import-graph.ts +1 -1
- package/scripts/refactor/refactor-lint.ts +4 -10
- package/scripts/refactor/refactor-scan-cli.ts +1 -1
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +1 -1
- package/scripts/release/github-release-cli.ts +25 -3
- package/scripts/release/github-release-runs.ts +1 -1
- package/scripts/release/release-cli.ts +21 -4
- package/scripts/release/release-history.ts +6 -10
- package/scripts/release/release-plan.ts +3 -3
- package/scripts/release/release-progress.ts +3 -4
- package/scripts/release/release-publish.ts +8 -9
- package/scripts/release/release-scope-cli.ts +8 -10
- package/scripts/release/release-tag.ts +6 -8
- package/scripts/release/release-worktree.ts +5 -5
- package/scripts/repo/auto-merge-setting-logic.ts +7 -9
- package/scripts/repo/auto-merge-setting.ts +1 -1
- package/scripts/repo/repo-setting.ts +4 -4
- package/scripts/repo/repository-labels.ts +1 -1
- package/scripts/repo/required-checks-logic.ts +3 -3
- package/scripts/repo/required-checks-report.ts +1 -1
- package/scripts/repo/ruleset-check-cli.ts +1 -1
- package/scripts/repo/ruleset-check.ts +1 -1
- package/scripts/report/report-format-reference.ts +26 -0
- package/scripts/report/report-lint-cli.ts +2 -2
- package/scripts/report/report-lint.ts +16 -2
- package/scripts/review/disposition-cli.ts +2 -2
- package/scripts/review/disposition-logic.ts +1 -1
- package/scripts/review/live-evidence.ts +9 -6
- package/scripts/review/review-attest-cli.ts +1 -2
- package/scripts/review/review-attest.ts +3 -3
- package/scripts/review/review-brief-cli.ts +19 -20
- package/scripts/review/review-brief.ts +29 -32
- package/scripts/review/review-checkout.ts +2 -2
- package/scripts/review/review-diff-parts.ts +3 -5
- package/scripts/review/review-diff-write.ts +1 -1
- package/scripts/review/review-finding-ledger.ts +7 -4
- package/scripts/review/review-findings-cli.ts +2 -2
- package/scripts/review/review-level.ts +4 -7
- package/scripts/review/review-record-cli.ts +73 -16
- package/scripts/review/review-record.ts +5 -4
- package/scripts/review/review-round2-cli.ts +2 -3
- package/scripts/review/review-round2.ts +13 -21
- package/scripts/review/review-stamps.ts +9 -71
- package/scripts/review/review-tree.ts +4 -5
- package/scripts/rules/bash-triggers.ts +4 -4
- package/scripts/rules/decision-oracle-batch.ts +5 -6
- package/scripts/rules/decision-oracle-stage.ts +1 -1
- package/scripts/rules/decision-oracle-tokens.ts +1 -2
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +61 -406
- package/scripts/rules/destructive-command.ts +2 -2
- package/scripts/rules/direct-filing.ts +4 -4
- package/scripts/rules/direct-pr-create.ts +2 -2
- package/scripts/rules/early-heartbeat.ts +15 -19
- package/scripts/rules/file-body.ts +5 -6
- package/scripts/rules/filing-cap.ts +6 -7
- package/scripts/rules/filing-offer.ts +1 -1
- package/scripts/rules/firing-point.ts +6 -6
- package/scripts/rules/gh-api.ts +2 -2
- package/scripts/rules/git-argv.ts +3 -3
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/hook-context-line.ts +31 -0
- package/scripts/rules/implementation-cut-verdict.ts +5 -8
- package/scripts/rules/implementation-cut.ts +35 -32
- package/scripts/rules/index-guard.ts +2 -2
- package/scripts/rules/issue-citation.ts +7 -7
- package/scripts/rules/issue-comments.ts +21 -13
- package/scripts/rules/josh-git-bare.ts +2 -2
- package/scripts/rules/lane-background.ts +14 -16
- package/scripts/rules/lane-carry-conflict.ts +41 -5
- package/scripts/rules/lane-interactive-ask.ts +6 -9
- package/scripts/rules/lane-park.ts +12 -16
- package/scripts/rules/lane-split-park.ts +1 -2
- package/scripts/rules/lane-switch-main.ts +10 -13
- package/scripts/rules/last-prompt.ts +1 -1
- package/scripts/rules/oracle-consulted.ts +5 -5
- package/scripts/rules/oracle-firing.ts +6 -9
- package/scripts/rules/oracle-list-cli.ts +2 -2
- package/scripts/rules/permission-guards.ts +2 -2
- package/scripts/rules/piped-verification.ts +79 -9
- package/scripts/rules/poll-loop.ts +9 -11
- package/scripts/rules/pre-gate-cut.ts +33 -30
- package/scripts/rules/prior-comment-read.ts +3 -3
- package/scripts/rules/protected-files.ts +25 -13
- package/scripts/rules/raw-field-body.ts +3 -4
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +10 -12
- package/scripts/rules/rule-guard.ts +1 -1
- package/scripts/rules/rule-list.ts +51 -0
- package/scripts/rules/rule-registry-rows.ts +282 -0
- package/scripts/rules/rule-registry.ts +109 -0
- package/scripts/rules/rule-value-cache.ts +2 -2
- package/scripts/rules/rule-value-cli.ts +6 -4
- package/scripts/rules/rule-value.ts +61 -22
- package/scripts/rules/run-tail-rule.ts +11 -15
- package/scripts/rules/shell-body-trigger.ts +7 -7
- package/scripts/rules/shell-segments.ts +2 -4
- package/scripts/rules/stop-rules.ts +54 -41
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +2 -2
- package/scripts/rules/third-party-write.ts +3 -3
- package/scripts/rules/worktree-guard.ts +12 -5
- package/scripts/run/add/run-add-cli.ts +165 -0
- package/scripts/run/add/run-add.ts +124 -0
- package/scripts/run/board/run-board-cli.ts +207 -0
- package/scripts/run/board/run-board-closed.ts +95 -0
- package/scripts/run/board/run-board-every.ts +60 -0
- package/scripts/run/board/run-board-fetch.ts +38 -0
- package/scripts/run/board/run-board-fit.ts +219 -0
- package/scripts/run/board/run-board-github.ts +162 -0
- package/scripts/run/board/run-board-header.ts +275 -0
- package/scripts/run/board/run-board-kind.ts +35 -0
- package/scripts/run/board/run-board-labels.ts +299 -0
- package/scripts/run/board/run-board-layout.ts +222 -0
- package/scripts/run/board/run-board-link.ts +31 -0
- package/scripts/run/board/run-board-machine.ts +198 -0
- package/scripts/run/board/run-board-notes.ts +103 -0
- package/scripts/run/board/run-board-phase.ts +136 -0
- package/scripts/run/board/run-board-plan.ts +129 -0
- package/scripts/run/board/run-board-read.ts +62 -0
- package/scripts/run/board/run-board-render-legend.ts +82 -0
- package/scripts/run/board/run-board-render-notes.ts +77 -0
- package/scripts/run/board/run-board-render-slot.ts +50 -0
- package/scripts/run/board/run-board-render.ts +407 -0
- package/scripts/run/board/run-board-scope.ts +17 -0
- package/scripts/run/board/run-board-screen.ts +43 -0
- package/scripts/run/board/run-board-span.ts +66 -0
- package/scripts/run/board/run-board-spin.ts +115 -0
- package/scripts/run/board/run-board-state.ts +113 -0
- package/scripts/run/board/run-board-status.ts +279 -0
- package/scripts/run/board/run-board-tick.ts +210 -0
- package/scripts/run/board/run-board-track.ts +22 -0
- package/scripts/run/board/run-board-usage-read.ts +255 -0
- package/scripts/run/board/run-board-usage-rusage.ts +124 -0
- package/scripts/run/board/run-board-usage-text.ts +80 -0
- package/scripts/run/board/run-board-usage.ts +165 -0
- package/scripts/run/carry/run-carry-added.ts +62 -0
- package/scripts/run/carry/run-carry-args.ts +25 -22
- package/scripts/run/carry/run-carry-change.ts +1 -1
- package/scripts/run/carry/run-carry-cli.ts +71 -48
- package/scripts/run/carry/run-carry-conversation.ts +6 -7
- package/scripts/run/carry/run-carry-ended.ts +85 -0
- package/scripts/run/carry/run-carry-reclaim.ts +1 -1
- package/scripts/run/carry/run-carry-stash.ts +3 -2
- package/scripts/run/carry/run-carry-streak.ts +8 -10
- package/scripts/run/carry/run-carry.ts +85 -89
- package/scripts/run/cut/run-cut-args.ts +7 -7
- package/scripts/run/cut/run-cut-cli.ts +54 -36
- package/scripts/run/cut/run-cut-handoff.ts +15 -15
- package/scripts/run/cut/run-cut-report.ts +37 -16
- package/scripts/run/cut/run-cut.ts +63 -77
- package/scripts/run/detached-launch.ts +35 -50
- package/scripts/run/entry/run-entry-cli.ts +48 -27
- package/scripts/run/entry/run-entry-stop.ts +7 -9
- package/scripts/run/entry/run-entry.ts +5 -6
- package/scripts/run/event/run-event-cli.ts +5 -6
- package/scripts/run/event/run-event-filed.ts +69 -0
- package/scripts/run/event/run-event-follow.ts +3 -3
- package/scripts/run/event/run-event-plan.ts +38 -0
- package/scripts/run/event/run-event-render.ts +9 -4
- package/scripts/run/event/run-event-scope.ts +47 -18
- package/scripts/run/event/run-event-stream-emit.ts +64 -11
- package/scripts/run/event/run-event-stream.ts +171 -46
- package/scripts/run/event/run-event-watch.ts +4 -6
- package/scripts/run/hold/run-hold-cli.ts +65 -62
- package/scripts/run/hold/run-hold.ts +88 -46
- package/scripts/run/merge/run-merge-cli.ts +116 -77
- package/scripts/run/merge/run-merge-collect.ts +107 -0
- package/scripts/run/merge/run-merge-steps.ts +112 -65
- package/scripts/run/merge/run-merge-token.ts +30 -0
- package/scripts/run/merge/run-merge.ts +31 -22
- package/scripts/run/progress/run-progress-args.ts +4 -4
- package/scripts/run/progress/run-progress-cli.ts +39 -50
- package/scripts/run/progress/run-progress-clock.ts +25 -32
- package/scripts/run/progress/run-progress-config.ts +6 -9
- package/scripts/run/progress/run-progress-read.ts +9 -10
- package/scripts/run/progress/run-progress.ts +48 -53
- package/scripts/run/review/run-review-cli.ts +6 -6
- package/scripts/run/review/run-review-steps.ts +6 -6
- package/scripts/run/review/run-review.ts +9 -11
- package/scripts/run/run-cli-fault.ts +29 -0
- package/scripts/run/run-ending-cli.ts +3 -3
- package/scripts/run/run-ending.ts +10 -14
- package/scripts/run/run-halfrun-resume.ts +6 -8
- package/scripts/run/run-headless.ts +25 -12
- package/scripts/run/run-invocation.ts +17 -22
- package/scripts/run/run-label.ts +7 -5
- package/scripts/run/run-liveness-cli.ts +19 -6
- package/scripts/run/run-liveness.ts +27 -38
- package/scripts/run/run-next-cli.ts +5 -9
- package/scripts/run/run-next.ts +4 -5
- package/scripts/run/run-parent-cut-hook.ts +10 -12
- package/scripts/run/run-preflight.ts +25 -29
- package/scripts/run/run-prep-cli.ts +17 -13
- package/scripts/run/run-prep-locate.ts +4 -5
- package/scripts/run/run-prep.ts +7 -10
- package/scripts/run/run-prrun-resume.ts +2 -2
- package/scripts/run/run-report-cli.ts +4 -4
- package/scripts/run/run-report.ts +9 -14
- package/scripts/run/run-retrospective.ts +3 -3
- package/scripts/run/run-section.ts +42 -0
- package/scripts/run/run-stage-read.ts +2 -2
- package/scripts/run/run-stage.ts +6 -4
- package/scripts/run/run-status-cli.ts +7 -5
- package/scripts/run/run-status.ts +6 -7
- package/scripts/run/run-step-cli.ts +13 -15
- package/scripts/run/run-step.ts +58 -47
- package/scripts/run/run-stop-notify.ts +7 -8
- package/scripts/run/run-stranded-cli.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +4 -4
- package/scripts/run/run-stranded.ts +11 -13
- package/scripts/run/run-tail-cli.ts +15 -16
- package/scripts/run/run-tail.ts +14 -33
- package/scripts/run/run-watcher-guard-cli.ts +3 -4
- package/scripts/run/run-watcher-guard.ts +11 -12
- package/scripts/run/run-watcher-hook.ts +6 -12
- package/scripts/run/ship/run-ship-cli.ts +67 -33
- package/scripts/run/ship/run-ship-detach.ts +15 -13
- package/scripts/run/ship/run-ship-lock.ts +1 -1
- package/scripts/run/ship/run-ship-next.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
- package/scripts/run/ship/run-ship-preflight.ts +10 -11
- package/scripts/run/ship/run-ship-probe.ts +4 -4
- package/scripts/run/ship/run-ship-return.ts +1 -1
- package/scripts/run/ship/run-ship-review-steps.ts +43 -24
- package/scripts/run/ship/run-ship-review.ts +12 -14
- package/scripts/run/ship/run-ship-scoped.ts +15 -6
- package/scripts/run/ship/run-ship-stage.ts +80 -26
- package/scripts/run/ship/run-ship-steps.ts +26 -16
- package/scripts/run/ship/run-ship-stop-text.ts +4 -2
- package/scripts/run/ship/run-ship-sync.ts +9 -8
- package/scripts/run/ship/run-ship.ts +17 -32
- package/scripts/run/tidy/run-tidy-cli.ts +9 -5
- package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
- package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
- package/scripts/run/tidy/run-tidy.ts +4 -3
- package/scripts/run/wake/run-wake-cli.ts +27 -32
- package/scripts/run/wake/run-wake-describe.ts +24 -28
- package/scripts/run/wake/run-wake-driver.ts +14 -14
- package/scripts/run/wake/run-wake-handoff.ts +6 -6
- package/scripts/run/wake/run-wake-loop.ts +9 -9
- package/scripts/run/wake/run-wake-restart.ts +4 -5
- package/scripts/run/wake/run-wake-session.ts +23 -27
- package/scripts/run/wake/run-wake.ts +57 -279
- package/scripts/safe-chain/ci-installer-pin.ts +3 -3
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -2
- package/scripts/security/security-audit-logic.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +1 -1
- package/scripts/security/security-audit-provision.ts +2 -2
- package/scripts/security/security-audit.ts +5 -5
- package/scripts/security/security-updates-logic.ts +2 -3
- package/scripts/security/security-updates.ts +2 -4
- package/scripts/self-sync-guard/index.ts +1 -1
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
- package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
- package/scripts/sonar/sonar-hotspots.ts +1 -1
- package/scripts/sonar/sonar-new-code-cli.ts +1 -1
- package/scripts/sonar/sonar-new-code.ts +1 -1
- package/scripts/sonar/sonar-project.ts +1 -1
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +3 -3
- package/scripts/sync/directory-copy-guard.ts +2 -3
- package/scripts/sync/managed-config-scope-cli.ts +1 -2
- package/scripts/sync/managed-config-scope.ts +4 -4
- package/scripts/sync/plugin-skill-directories.ts +2 -2
- package/scripts/sync/reconcile-templates.ts +17 -8
- package/scripts/sync/removed-skill-manifest.ts +2 -3
- package/scripts/sync/sync-ai-files.ts +7 -7
- package/scripts/sync/sync-configs.ts +30 -3
- package/scripts/sync/sync-hook-safety.ts +2 -2
- package/scripts/sync/sync.ts +23 -10
- package/scripts/sync/synced-paths.ts +2 -1
- package/scripts/sync/workflow-pin-logic.ts +1 -1
- package/scripts/test/test-declared-changed.ts +4 -4
- package/scripts/test/test-declared-logic.ts +2 -3
- package/scripts/test/test-declared-match.ts +25 -4
- package/scripts/test/test-declared.ts +26 -9
- package/scripts/test/test-red-commit.ts +3 -2
- package/scripts/test/test-red-logic.ts +7 -14
- package/scripts/test/test-red.ts +12 -47
- package/scripts/test/test-related-scope.ts +2 -3
- package/scripts/test/test-related.ts +3 -3
- package/scripts/test/test-type-logic.ts +1 -2
- package/scripts/test/test-unit-guard.ts +13 -17
- package/scripts/test/unit-worker-share.ts +7 -8
- package/scripts/time-runtime/time-agent-bundles.ts +2 -4
- package/scripts/time-runtime/time-background.ts +17 -21
- package/scripts/time-runtime/time-batch-guard.ts +67 -342
- package/scripts/time-runtime/time-bundle-call.ts +26 -28
- package/scripts/time-runtime/time-bundles.ts +11 -12
- package/scripts/time-runtime/time-call-identity.ts +1 -1
- package/scripts/time-runtime/time-command-key.ts +2 -2
- package/scripts/time-runtime/time-density-hook.ts +8 -11
- package/scripts/time-runtime/time-density.ts +5 -5
- package/scripts/time-runtime/time-followup-stage.ts +7 -7
- package/scripts/time-runtime/time-format.ts +5 -5
- package/scripts/time-runtime/time-hook-transcript.ts +3 -3
- package/scripts/time-runtime/time-instant.ts +1 -1
- package/scripts/time-runtime/time-markers.ts +15 -19
- package/scripts/time-runtime/time-phase-names.ts +3 -3
- package/scripts/time-runtime/time-reported-failure.ts +15 -19
- package/scripts/time-runtime/time-round-trips.ts +20 -23
- package/scripts/time-runtime/time-shell.ts +8 -8
- package/scripts/time-runtime/time-single-check.ts +1 -2
- package/scripts/time-runtime/time-spans.ts +35 -40
- package/scripts/time-runtime/time-tool-call.ts +15 -16
- package/scripts/time-runtime/time-transcript-line.ts +53 -34
- package/scripts/time-runtime/time-writes.ts +5 -5
- package/scripts/ui/ui-routes-cli.ts +1 -2
- package/scripts/ui/ui-routes.ts +1 -2
- package/scripts/version/bump-version.ts +1 -1
- package/scripts/version/fresh-metadata-cache.ts +2 -2
- package/scripts/version/latest-corepack.ts +26 -26
- package/scripts/version/latest-lane-guard.ts +1 -1
- package/scripts/version/latest-scope-cli.ts +2 -2
- package/scripts/version/latest-stamp.ts +1 -2
- package/scripts/version/latest-update.ts +2 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/package-manager-version.ts +18 -0
- package/scripts/version/publishable-range-check.ts +2 -1
- package/scripts/version/publishable-range.ts +1 -1
- package/scripts/version/release-age.ts +11 -11
- package/scripts/version/release-hold.ts +2 -2
- package/scripts/version/safe-chain-version-update.ts +3 -3
- package/scripts/version/version-check-logic.ts +2 -3
- package/scripts/version/version-check.ts +1 -2
- package/scripts/version/version-command-config.ts +2 -2
- package/scripts/version/version-commands.ts +3 -3
- package/scripts/version/version-remote.ts +4 -4
- package/scripts/version/version-targets.ts +2 -2
- package/templates/gitignore +7 -0
- package/dist/hooks/chunk-KHX4U3BG.js +0 -6400
- package/dist/hooks/chunk-RKUAD3I6.js +0 -90
- package/dist/hooks/chunk-WPALEIRX.js +0 -18
- package/scripts/backlog/backlog-restructure.ts +0 -152
- package/scripts/rules/issue-fold-rule.ts +0 -72
- package/scripts/rules/wip-cap.ts +0 -63
- package/scripts/run/run-issue-number.ts +0 -19
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// The paste-ready citation line `josh issue:cite` prints, kept apart from the reading and the
|
|
2
|
-
// printing so the shape of the line is decided by one pure function
|
|
2
|
+
// printing so the shape of the line is decided by one pure function.
|
|
3
3
|
//
|
|
4
4
|
// **It exists because the correct citation form has a cost the bare `#N` does not.** `CLAUDE.md` and
|
|
5
5
|
// `prompts/collaboration-workflow/issue-citation.md` require session-facing output to cite an Issue
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// translate deterministically, and an LLM call per Issue would defeat the point of a cheap citation
|
|
13
13
|
// helper and make the output untestable; the title already says what the Issue does, which is all the
|
|
14
14
|
// rule asks of the summary — knowing what it does is enough. The reader adapts it to the session
|
|
15
|
-
// language when it matters, without
|
|
15
|
+
// language when it matters, without a round trip to learn the title at all.
|
|
16
16
|
|
|
17
17
|
const GITHUB_URL_PREFIX = 'https://github.com/'
|
|
18
18
|
const ISSUE_PATH = '/issues/'
|
|
@@ -32,27 +32,36 @@ interface CiteTarget {
|
|
|
32
32
|
repo: string | undefined
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
// The plain `#N`, or `owner/repo#N` when a repository is named — the one place the bare form is
|
|
36
|
+
// assembled. It is for text GitHub renders or a program reads: an Issue or PR
|
|
37
|
+
// body, a comment, a commit message, a pattern, a key. GitHub links that text itself, so it needs no
|
|
38
|
+
// link of its own; what a session reads goes through `session_cite.issue` instead, and the scan in
|
|
39
|
+
// `session-cite-scan.test.ts` refuses a bare `#${…}` assembled anywhere else.
|
|
40
|
+
function plain(number: number | string, repo = ''): string {
|
|
41
|
+
return `${repo}#${String(number)}`
|
|
42
|
+
}
|
|
43
|
+
|
|
35
44
|
function issue_url(slug: string, number: string): string {
|
|
36
45
|
return `${GITHUB_URL_PREFIX}${slug}${ISSUE_PATH}${number}`
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
function citation_line(slug: string, number: string, summary: string): string {
|
|
40
|
-
return `[
|
|
49
|
+
return `[${plain(number)}](${issue_url(slug, number)})${SUMMARY_SEPARATOR}${summary}`
|
|
41
50
|
}
|
|
42
51
|
|
|
43
|
-
// How a listing names one issue, given what it already holds
|
|
52
|
+
// How a listing names one issue, given what it already holds. A progress
|
|
44
53
|
// command's output is copied into a report verbatim, so the line it prints is the citation the report
|
|
45
54
|
// carries: the full form when the title is in hand, the bare number-link when only the repository is,
|
|
46
55
|
// and the plain `#N` only when the repository could not be read at all.
|
|
47
56
|
type IssueCiter = (number: string) => string
|
|
48
57
|
|
|
49
58
|
// One issue, named from what the caller holds — the single decision every listing's citation goes
|
|
50
|
-
// through
|
|
59
|
+
// through, so a renderer holding one title never re-derives the fallback.
|
|
51
60
|
function reference(slug: string | undefined, number: string, title: string | undefined): string {
|
|
52
|
-
if (slug === undefined) return
|
|
61
|
+
if (slug === undefined) return plain(number)
|
|
53
62
|
|
|
54
63
|
return title === undefined
|
|
55
|
-
? `[
|
|
64
|
+
? `[${plain(number)}](${issue_url(slug, number)})`
|
|
56
65
|
: citation_line(slug, number, title)
|
|
57
66
|
}
|
|
58
67
|
|
|
@@ -89,7 +98,7 @@ function parse_target(token: string, default_repo: string | undefined): CiteTarg
|
|
|
89
98
|
// How a target is named in a failure line: `owner/repo#N` when it names another repository, `#N`
|
|
90
99
|
// otherwise — the form the reader typed, so the line points back at the argument it is about.
|
|
91
100
|
function label(target: CiteTarget): string {
|
|
92
|
-
return target.
|
|
101
|
+
return plain(target.number, target.repo)
|
|
93
102
|
}
|
|
94
103
|
|
|
95
104
|
// A number that resolves to nothing, told apart from a read that failed: this one will not change on a
|
|
@@ -116,6 +125,7 @@ const issue_cite = {
|
|
|
116
125
|
missing_line,
|
|
117
126
|
no_repo_line,
|
|
118
127
|
parse_target,
|
|
128
|
+
plain,
|
|
119
129
|
reference,
|
|
120
130
|
unreadable_line,
|
|
121
131
|
}
|
|
@@ -2,12 +2,12 @@ import { git_gh_api_path } from '#scripts/gh/git-gh-api-path'
|
|
|
2
2
|
import { git_gh_exec } from '#scripts/gh/git-gh-exec'
|
|
3
3
|
import { git_gh_repo } from '#scripts/gh/git-gh-repo'
|
|
4
4
|
import { git_closes_keyword } from '#scripts/git/git-closes-keyword'
|
|
5
|
-
import {
|
|
5
|
+
import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
|
|
6
6
|
import { z } from 'zod'
|
|
7
7
|
|
|
8
|
-
// **The merged pull request that closes an issue GitHub left open
|
|
8
|
+
// **The merged pull request that closes an issue GitHub left open**. A
|
|
9
9
|
// `backlogrun` child whose pull request merged while GitHub did not apply its `closes #N`
|
|
10
|
-
//
|
|
10
|
+
// came back OPEN, and `run:merge` counted it a failure and parked it — the
|
|
11
11
|
// work had landed, only the issue's close had not.
|
|
12
12
|
//
|
|
13
13
|
// **A merged reference is not enough; the body must close this issue.** A merged pull request that
|
|
@@ -48,7 +48,7 @@ function is_reference(row: TimelineRow): row is MergedReference {
|
|
|
48
48
|
function parse_references(raw: string): Array<MergedReference> {
|
|
49
49
|
const rows = raw
|
|
50
50
|
.split(LINE_SEPARATOR)
|
|
51
|
-
.map((line) =>
|
|
51
|
+
.map((line) => parse_json_object_or_undefined(line, row_schema))
|
|
52
52
|
.filter((row) => row !== undefined)
|
|
53
53
|
const last_reopen = rows.findLastIndex((row) => !is_reference(row))
|
|
54
54
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
3
|
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
4
|
+
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
4
5
|
import { cli_body } from '#scripts/josh/cli-body'
|
|
5
6
|
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
6
7
|
import { error_text } from '#scripts/lib/error-message'
|
|
7
8
|
|
|
8
9
|
// `josh issue:comment <N> --body <text> | --body-file <path>` — post one comment to an issue (a PR
|
|
9
|
-
// comment is an issue comment over REST) and print the comment URL
|
|
10
|
+
// comment is an issue comment over REST) and print the comment URL.
|
|
10
11
|
//
|
|
11
12
|
// **The write side had no command, so every park, decision record and plan comment fell to a raw
|
|
12
13
|
// `gh api … body=@<path>`.** The read side already had `issue:read` / `issue:state` / `issue:cite` /
|
|
@@ -21,7 +22,6 @@ const FAILURE_EXIT_CODE = 1
|
|
|
21
22
|
const ARGV_OFFSET = 2
|
|
22
23
|
const BODY_FLAG = '--body'
|
|
23
24
|
const BODY_FILE_FLAG = '--body-file'
|
|
24
|
-
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
25
25
|
const USAGE = `Usage: josh issue:comment <issue-number> ${BODY_FLAG} <text> | ${BODY_FILE_FLAG} <path>`
|
|
26
26
|
|
|
27
27
|
interface CommentRequest {
|
|
@@ -29,7 +29,7 @@ interface CommentRequest {
|
|
|
29
29
|
body: string
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
// The read is strict
|
|
32
|
+
// The read is strict: an unknown flag refuses the call rather than being
|
|
33
33
|
// ignored. `cli_body.resolve` owns the both-flags-at-once refusal and the file read.
|
|
34
34
|
const OPTIONS = { body: { type: 'string' }, 'body-file': { type: 'string' } } as const
|
|
35
35
|
|
|
@@ -39,7 +39,9 @@ function single_issue_number(positionals: ReadonlyArray<string>): string | undef
|
|
|
39
39
|
const [issue_number, ...rest] = positionals
|
|
40
40
|
const is_single = rest.length === 0 && issue_number !== undefined
|
|
41
41
|
|
|
42
|
-
return is_single && ISSUE_NUMBER_PATTERN.test(issue_number)
|
|
42
|
+
return is_single && issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue_number)
|
|
43
|
+
? issue_number
|
|
44
|
+
: undefined
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
// `resolve` may throw when both body flags are given, which `run` reports — the message names the two
|
|
@@ -11,27 +11,33 @@ import { github_issue_url } from '#scripts/gh/github-issue-url'
|
|
|
11
11
|
import { error_text } from '#scripts/lib/error-message'
|
|
12
12
|
import type { PollOptions } from '#scripts/lib/poll'
|
|
13
13
|
import { repository_labels } from '#scripts/repo/repository-labels'
|
|
14
|
+
import { run_event_filed } from '#scripts/run/event/run-event-filed'
|
|
15
|
+
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
16
|
+
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
14
17
|
import { issue_auto_ok } from './issue-auto-ok'
|
|
18
|
+
import { issue_cite } from './issue-cite'
|
|
15
19
|
import { issue_file, type FileArguments } from './issue-file'
|
|
20
|
+
import { issue_file_fold } from './issue-file-fold'
|
|
16
21
|
import { issue_lint_cli } from './issue-lint-cli'
|
|
17
22
|
import { issue_release_cli } from './issue-release-cli'
|
|
18
23
|
import { issue_scout_cli } from './issue-scout-cli'
|
|
19
24
|
import { issue_wip } from './issue-wip'
|
|
20
25
|
|
|
21
26
|
// `josh issue:file "<title>" --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>]…
|
|
22
|
-
// [--repo <owner/repo>] [--distinct <N,…>] [--over-cap] [--no-auto-ok] [--release]` — file an Issue
|
|
23
|
-
// with every filing step run in order
|
|
24
|
-
// lint, the `## Origin` check for another repository, the `auto-ok` decision
|
|
25
|
-
// with the run label it owes
|
|
26
|
-
//
|
|
27
|
-
//
|
|
27
|
+
// [--repo <owner/repo>] [--distinct <N,…>] [--over-cap] [--no-auto-ok] [--requested] [--release]` — file an Issue
|
|
28
|
+
// with every filing step run in order: the third-party refusal, the body
|
|
29
|
+
// lint, the `## Origin` check for another repository, the `auto-ok` decision
|
|
30
|
+
// with the run label it owes, the fold question against the run's earlier
|
|
31
|
+
// filings, the WIP cap count, the
|
|
32
|
+
// duplicate scout, the missing workflow labels created, the create call
|
|
33
|
+
// carrying every label, the release link on `--release`, and `epic:bundle`.
|
|
28
34
|
// A direct `gh api …/issues` filing is refused by the `direct-filing` delivered rule and pointed here.
|
|
29
35
|
|
|
30
36
|
const SUCCESS_EXIT_CODE = 0
|
|
31
37
|
const FAILURE_EXIT_CODE = 1
|
|
32
38
|
const ARGV_OFFSET = 2
|
|
33
39
|
const USAGE =
|
|
34
|
-
'Usage: josh issue:file "<title>" --body-file <path> --depth <0|1|2> [--route <tier-a|split|interrupt|review-cap>] [--label <name>]… [--repo <owner/repo>] [--distinct <N,…>] [--over-cap] [--no-auto-ok] [--release]'
|
|
40
|
+
'Usage: josh issue:file "<title>" --body-file <path> --depth <0|1|2> [--route <tier-a|split|interrupt|review-cap>] [--label <name>]… [--repo <owner/repo>] [--distinct <N,…>] [--over-cap] [--no-auto-ok] [--requested] [--release]'
|
|
35
41
|
const UNKNOWN_REPO_MESSAGE =
|
|
36
42
|
'Could not read this repository from `git remote`, so the filing has no repository to compare against — check `gh auth status`.'
|
|
37
43
|
const THIRD_PARTY_MESSAGE =
|
|
@@ -40,7 +46,7 @@ const THIRD_PARTY_MESSAGE =
|
|
|
40
46
|
// scout and `epic:bundle` make at the target repository rather than at this checkout.
|
|
41
47
|
const GH_REPO_VARIABLE = 'GH_REPO'
|
|
42
48
|
// The open listing `epic:bundle` reads trails the create call, so the issue just filed is looked for
|
|
43
|
-
// again for up to ten seconds before the placement is given up
|
|
49
|
+
// again for up to ten seconds before the placement is given up.
|
|
44
50
|
const FRESH_ISSUE_POLL: PollOptions = { attempts: 6, interval_ms: 2000 }
|
|
45
51
|
|
|
46
52
|
interface Filing {
|
|
@@ -136,11 +142,15 @@ async function is_scout_clear(filing: Filing): Promise<boolean> {
|
|
|
136
142
|
return open.length === 0
|
|
137
143
|
}
|
|
138
144
|
|
|
139
|
-
// Every label the create call carries, or `undefined` when an `auto-ok` filing names neither run label
|
|
140
|
-
//
|
|
145
|
+
// Every label the create call carries, or `undefined` when an `auto-ok` filing names neither run label.
|
|
146
|
+
// Decided before the WIP count and the scout, so a refusal costs no listing.
|
|
141
147
|
async function labels_of(filing: Filing): Promise<ReadonlyArray<string> | undefined> {
|
|
148
|
+
const declared = {
|
|
149
|
+
is_opted_out: filing.args.is_auto_ok_opted_out,
|
|
150
|
+
is_requested: filing.args.is_requested,
|
|
151
|
+
}
|
|
142
152
|
const auto_ok = await issue_auto_ok.resolve(
|
|
143
|
-
|
|
153
|
+
declared,
|
|
144
154
|
filing.target,
|
|
145
155
|
filing.current,
|
|
146
156
|
filing.args.labels,
|
|
@@ -183,7 +193,7 @@ function issue_number_of(url: string): number {
|
|
|
183
193
|
return Number(github_issue_url.parse(url)?.issue_number)
|
|
184
194
|
}
|
|
185
195
|
|
|
186
|
-
// `--release`: the filed Issue blocks the target's release Issue
|
|
196
|
+
// `--release`: the filed Issue blocks the target's release Issue. Reported,
|
|
187
197
|
// never failed, for the reason `place` gives. The re-run hint names the target through `GH_REPO`:
|
|
188
198
|
// `issue:release` links in the repository `gh` resolves, which is not the target on a `--repo` filing.
|
|
189
199
|
async function link_release(url: string, filing: Filing): Promise<void> {
|
|
@@ -212,6 +222,22 @@ async function place(url: string, target: string): Promise<void> {
|
|
|
212
222
|
}
|
|
213
223
|
}
|
|
214
224
|
|
|
225
|
+
// Every filing lands on the run's event stream: this is the one filing path, so
|
|
226
|
+
// one append here reaches `run:board` from every route. A filing outside a run lands too and is left
|
|
227
|
+
// out by the board's own scope to the invocation; the append is best-effort, as every emit is.
|
|
228
|
+
async function record(url: string, filing: Filing, labels: ReadonlyArray<string>): Promise<void> {
|
|
229
|
+
const number = String(issue_number_of(url))
|
|
230
|
+
const reference = issue_cite.plain(
|
|
231
|
+
number,
|
|
232
|
+
issue_file_fold.reference_prefix(filing.target, filing.current),
|
|
233
|
+
)
|
|
234
|
+
const found_during = await issue_file_fold.finder()
|
|
235
|
+
const kind = run_event_filed.kind_of(labels)
|
|
236
|
+
const text = run_event_filed.text_of({ reference, kind, title: filing.args.title, found_during })
|
|
237
|
+
|
|
238
|
+
await run_event_stream_emit.emit(run_event_stream.EVENT_KIND.FILED, text)
|
|
239
|
+
}
|
|
240
|
+
|
|
215
241
|
function is_admitted(filing: Filing): boolean {
|
|
216
242
|
const refusals = refusals_of(filing)
|
|
217
243
|
|
|
@@ -226,18 +252,28 @@ async function send(filing: Filing, labels: ReadonlyArray<string>): Promise<numb
|
|
|
226
252
|
|
|
227
253
|
if (url === undefined) return FAILURE_EXIT_CODE
|
|
228
254
|
console.info(url)
|
|
255
|
+
await record(url, filing, labels)
|
|
229
256
|
await link_release(url, filing)
|
|
230
257
|
await place(url, filing.target)
|
|
231
258
|
|
|
232
259
|
return SUCCESS_EXIT_CODE
|
|
233
260
|
}
|
|
234
261
|
|
|
262
|
+
// The holds that read the run and the backlog, in the order they cost: the fold reads the local event
|
|
263
|
+
// stream and diff, the WIP count one listing, the scout a search.
|
|
264
|
+
async function is_clear(filing: Filing): Promise<boolean> {
|
|
265
|
+
const prefix = issue_file_fold.reference_prefix(filing.target, filing.current)
|
|
266
|
+
|
|
267
|
+
if (!(await issue_file_fold.is_fold_clear(prefix, filing.args))) return false
|
|
268
|
+
|
|
269
|
+
return (await is_wip_clear(filing)) && (await is_scout_clear(filing))
|
|
270
|
+
}
|
|
271
|
+
|
|
235
272
|
async function file(filing: Filing): Promise<number> {
|
|
236
273
|
if (!is_admitted(filing)) return FAILURE_EXIT_CODE
|
|
237
274
|
const labels = await labels_of(filing)
|
|
238
275
|
|
|
239
|
-
if (labels === undefined) return FAILURE_EXIT_CODE
|
|
240
|
-
if (!(await is_wip_clear(filing)) || !(await is_scout_clear(filing))) return FAILURE_EXIT_CODE
|
|
276
|
+
if (labels === undefined || !(await is_clear(filing))) return FAILURE_EXIT_CODE
|
|
241
277
|
|
|
242
278
|
return await send(filing, labels)
|
|
243
279
|
}
|
|
@@ -278,8 +314,9 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
278
314
|
process.exitCode = await run(argv)
|
|
279
315
|
}
|
|
280
316
|
|
|
281
|
-
const issue_file_cli = { FRESH_ISSUE_POLL, THIRD_PARTY_MESSAGE, run }
|
|
317
|
+
const issue_file_cli = { FRESH_ISSUE_POLL, THIRD_PARTY_MESSAGE, record, run }
|
|
282
318
|
|
|
283
319
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
284
320
|
|
|
285
321
|
export { issue_file_cli }
|
|
322
|
+
export type { Filing }
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { git_branch } from '#scripts/git/git-branch'
|
|
2
|
+
import { git_command } from '#scripts/git/git-command'
|
|
3
|
+
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
4
|
+
import { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
5
|
+
import { run_event_filed, type Filed } from '#scripts/run/event/run-event-filed'
|
|
6
|
+
import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
|
|
7
|
+
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
8
|
+
import { issue_file } from './issue-file'
|
|
9
|
+
import { issue_fold, type FoldVerdict } from './issue-fold'
|
|
10
|
+
import { issue_fold_cli } from './issue-fold-cli'
|
|
11
|
+
import { SPLIT_ROUTE_LABEL } from './issue-labels'
|
|
12
|
+
import { issue_state_cli } from './issue-state-cli'
|
|
13
|
+
|
|
14
|
+
// The fold question asked by `josh issue:file` itself, as the scout and
|
|
15
|
+
// `epic:bundle` already are. A separate `pnpm josh issue:fold` would cost two or three round trips per
|
|
16
|
+
// filing, for a question whose every input the command can read: the run's earlier filings are the `filed` events
|
|
17
|
+
// it appends to the event stream itself, and the size is `issue:fold`'s own reading of the diff.
|
|
18
|
+
//
|
|
19
|
+
// **The verdict is `issue_fold.fold_verdict`, called rather than restated**, with separability
|
|
20
|
+
// presumed as `issue:fold` presumes it. Only `fold` holds the filing; `undetermined` — no diff that
|
|
21
|
+
// measures the findings' size — files, the size then being the whole request's estimate the filer
|
|
22
|
+
// already made.
|
|
23
|
+
|
|
24
|
+
const REFERENCE_NUMBER = /#(?<number>\d+)$/u
|
|
25
|
+
const CLOSED_STATE = 'CLOSED'
|
|
26
|
+
|
|
27
|
+
// What the fold reads off the filing's arguments.
|
|
28
|
+
interface FoldArguments {
|
|
29
|
+
route: string | undefined
|
|
30
|
+
distinct: ReadonlyArray<number>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function number_of(reference: string): number {
|
|
34
|
+
return Number(REFERENCE_NUMBER.exec(reference)?.groups?.['number'])
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// What a filed reference carries before `#<N>`: nothing for this repository's Issue, `<owner>/<repo>`
|
|
38
|
+
// for one filed elsewhere. `issue:file` writes its references with it and the fold compares by it, so
|
|
39
|
+
// a finding is never folded into another repository's Issue. Compared as the Origin check compares,
|
|
40
|
+
// case-insensitively, so `--repo JoshuaFolkken/kit` and no `--repo` name one repository here too.
|
|
41
|
+
function reference_prefix(target: string, current: string): string {
|
|
42
|
+
return issue_file.is_same_repository(target, current) ? '' : target
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function prefix_of(reference: string): string {
|
|
46
|
+
return reference.slice(0, reference.lastIndexOf('#'))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The Issue the checkout's branch names; a git read that fails names none.
|
|
50
|
+
async function branch_issue(): Promise<number | undefined> {
|
|
51
|
+
try {
|
|
52
|
+
return git_branch.issue_from_branch(await git_command.branch())
|
|
53
|
+
} catch {
|
|
54
|
+
return undefined
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Whose work turned the finding up: the lane child's mark, else the Issue the checkout's branch names,
|
|
59
|
+
// so a person's `fullrun` on `3423-x` is one finder across its filings just as a lane child is. A
|
|
60
|
+
// checkout on no Issue's branch — a `backlogrun` parent on `main` — has none.
|
|
61
|
+
async function finder(): Promise<string | undefined> {
|
|
62
|
+
const marked = lane_child_marker.marked_issue()
|
|
63
|
+
|
|
64
|
+
if (marked !== undefined) return marked
|
|
65
|
+
const issue = await branch_issue()
|
|
66
|
+
|
|
67
|
+
return issue === undefined ? undefined : String(issue)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// The events the fold reads. A finder's filings are its own wherever they fall on the stream, so they
|
|
71
|
+
// are read whole — a person's run has no carry record to scope by. With no finder, the invocation the
|
|
72
|
+
// carry record scopes is the run.
|
|
73
|
+
async function events_of(found_during: string | undefined): Promise<ReadonlyArray<RunEvent>> {
|
|
74
|
+
if (found_during === undefined) return await run_event_stream_emit.current_events()
|
|
75
|
+
|
|
76
|
+
return await run_event_stream_emit.all_events()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// This run's earlier filings by the same finder — so a parallel lane's filing is never what this one
|
|
80
|
+
// folds into — in the repository this filing targets. One the caller named in `--distinct` has been
|
|
81
|
+
// declared a separate deliverable and is left out, the same declaration the scout's candidates take.
|
|
82
|
+
function prior_filings(
|
|
83
|
+
events: ReadonlyArray<RunEvent>,
|
|
84
|
+
found_during: string | undefined,
|
|
85
|
+
prefix: string,
|
|
86
|
+
distinct: ReadonlyArray<number>,
|
|
87
|
+
): ReadonlyArray<Filed> {
|
|
88
|
+
return events
|
|
89
|
+
.filter((event) => event.kind === run_event_stream.EVENT_KIND.FILED)
|
|
90
|
+
.flatMap((event) => run_event_filed.parse(event.text) ?? [])
|
|
91
|
+
.filter((filed) => filed.found_during === found_during && prefix_of(filed.reference) === prefix)
|
|
92
|
+
.filter((filed) => !distinct.includes(number_of(filed.reference)))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Whether an earlier filing is still in the backlog. A finder's filings are read across invocations,
|
|
96
|
+
// so one may have closed since — folding into it would take the finding out of the backlog. A state
|
|
97
|
+
// that could not be read keeps the filing: a failed read is never taken as closed.
|
|
98
|
+
async function is_open(filed: Filed, prefix: string): Promise<boolean> {
|
|
99
|
+
const repo = prefix === '' ? undefined : prefix
|
|
100
|
+
const read = await issue_state_cli.read_issue(String(number_of(filed.reference)), repo)
|
|
101
|
+
|
|
102
|
+
return read.kind !== 'state' || read.state.state !== CLOSED_STATE
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Through the shared pool at `issue:state`'s bound rather than a raw `Promise.all`, so a finder's
|
|
106
|
+
// filings never draw the secondary rate limiting that reads back as `unreadable`.
|
|
107
|
+
async function open_filings(
|
|
108
|
+
priors: ReadonlyArray<Filed>,
|
|
109
|
+
prefix: string,
|
|
110
|
+
): Promise<ReadonlyArray<Filed>> {
|
|
111
|
+
const verdicts = await bounded_pool.bounded_map(
|
|
112
|
+
priors,
|
|
113
|
+
issue_state_cli.READ_CONCURRENCY,
|
|
114
|
+
async (filed) => await is_open(filed, prefix),
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
return priors.filter((_filed, index) => verdicts[index])
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function references_of(priors: ReadonlyArray<Filed>): string {
|
|
121
|
+
return priors.map((filed) => filed.reference).join(', ')
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function line_of(verdict: FoldVerdict, priors: ReadonlyArray<Filed>): string {
|
|
125
|
+
return `fold: ${issue_fold_cli.REASONS[verdict]} · filed earlier by this finder: ${references_of(priors)}`
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function held_message(priors: ReadonlyArray<Filed>): string {
|
|
129
|
+
const listed = priors.map((filed) => String(number_of(filed.reference))).join(',')
|
|
130
|
+
|
|
131
|
+
return `✖ fold: add this finding to ${references_of(priors)} (its body or a comment) rather than filing it; a finding that is really a separate deliverable reissues with \`--distinct ${listed}\` (\`split-assessment.md\` → "The question").`
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Whether the filing may go on: `true` with no open earlier filing to fold with, and on every verdict
|
|
135
|
+
// but `fold`. The verdict is printed whenever there was something to fold with. A split child is
|
|
136
|
+
// exempt, as it is from the WIP cap: the split assessment already decided it is a separate deliverable.
|
|
137
|
+
async function is_fold_clear(prefix: string, args: FoldArguments): Promise<boolean> {
|
|
138
|
+
if (args.route === SPLIT_ROUTE_LABEL) return true
|
|
139
|
+
const found_during = await finder()
|
|
140
|
+
const filings = prior_filings(await events_of(found_during), found_during, prefix, args.distinct)
|
|
141
|
+
const priors = await open_filings(filings, prefix)
|
|
142
|
+
|
|
143
|
+
if (priors.length === 0) return true
|
|
144
|
+
const size = await issue_fold_cli.size_verdict()
|
|
145
|
+
const verdict = issue_fold.fold_verdict(priors.length + 1, true, size)
|
|
146
|
+
|
|
147
|
+
console.info(line_of(verdict, priors))
|
|
148
|
+
if (verdict === issue_fold.FOLD) console.error(held_message(priors))
|
|
149
|
+
|
|
150
|
+
return verdict !== issue_fold.FOLD
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const issue_file_fold = { finder, is_fold_clear, prior_filings, reference_prefix }
|
|
154
|
+
|
|
155
|
+
export { issue_file_fold }
|
|
@@ -15,11 +15,9 @@ import {
|
|
|
15
15
|
} from './issue-labels'
|
|
16
16
|
import { markdown_section } from './markdown-section'
|
|
17
17
|
|
|
18
|
-
// The decisions behind `josh issue:file
|
|
19
|
-
// reads the network so each one is a pure answer a test can pin.
|
|
20
|
-
//
|
|
21
|
-
// ran two of them and skipped the lint and the labels. Here the steps are the command's arguments:
|
|
22
|
-
// a label the filing owes is a required option rather than a line to remember.
|
|
18
|
+
// The decisions behind `josh issue:file`, kept apart from the command that
|
|
19
|
+
// reads the network so each one is a pure answer a test can pin. The filing steps are the command's
|
|
20
|
+
// arguments: a label the filing owes is a required option rather than a line to remember.
|
|
23
21
|
|
|
24
22
|
const DEPTH_PREFIX = 'depth:'
|
|
25
23
|
const ROUTE_PREFIX = 'route:'
|
|
@@ -43,6 +41,9 @@ interface FileArguments {
|
|
|
43
41
|
is_over_cap: boolean
|
|
44
42
|
// `--no-auto-ok`: the Issue needs a person's judgement, so `auto-ok` is not applied (`issue-auto-ok.ts`).
|
|
45
43
|
is_auto_ok_opted_out: boolean
|
|
44
|
+
// `--requested`: a person asked for this filing, so `auto-ok` is applied only when a `--label` names
|
|
45
|
+
// it (`issue-auto-ok.ts`).
|
|
46
|
+
is_requested: boolean
|
|
46
47
|
// `--release`: the change reaches a consumer only once published, so the Issue is linked to the
|
|
47
48
|
// repository's release Issue as a blocker (`issue-release-cli.ts`).
|
|
48
49
|
is_release: boolean
|
|
@@ -57,6 +58,7 @@ const OPTIONS = {
|
|
|
57
58
|
distinct: { type: 'string', multiple: true },
|
|
58
59
|
'over-cap': { type: 'boolean' },
|
|
59
60
|
'no-auto-ok': { type: 'boolean' },
|
|
61
|
+
requested: { type: 'boolean' },
|
|
60
62
|
release: { type: 'boolean' },
|
|
61
63
|
} as const
|
|
62
64
|
|
|
@@ -127,6 +129,7 @@ function arguments_of(values: ParsedValues, title: string | undefined): FileArgu
|
|
|
127
129
|
repo: values.repo,
|
|
128
130
|
is_over_cap: values['over-cap'] === true,
|
|
129
131
|
is_auto_ok_opted_out: values['no-auto-ok'] === true,
|
|
132
|
+
is_requested: values.requested === true,
|
|
130
133
|
is_release: values.release === true,
|
|
131
134
|
}
|
|
132
135
|
}
|
|
@@ -161,7 +164,7 @@ function labels_of(args: FileArguments, body: string, is_auto_ok = false): Reado
|
|
|
161
164
|
}
|
|
162
165
|
|
|
163
166
|
// Why an `auto-ok` filing with neither `run:lane` nor `run:solo` is refused, or `undefined` when it is
|
|
164
|
-
// not
|
|
167
|
+
// not. The offer paths withhold every candidate while one opted-in Issue is
|
|
165
168
|
// untriaged, so a run's own filing without the judgement stopped every lane. No default is applied:
|
|
166
169
|
// `run:solo` is the answer that keeps a verification defect from running beside others, and only a
|
|
167
170
|
// reading of the Issue gives it (`backlogrun-lanes.md`).
|
|
@@ -7,7 +7,7 @@ import { split_assess, type SplitVerdict } from '#scripts/split/split-assess'
|
|
|
7
7
|
import { issue_fold, type FoldVerdict } from './issue-fold'
|
|
8
8
|
|
|
9
9
|
// `josh issue:fold "<title>" "<title>" …` — before a run files a second finding, answer whether the
|
|
10
|
-
// findings this session holds fold into one Issue
|
|
10
|
+
// findings this session holds fold into one Issue.
|
|
11
11
|
//
|
|
12
12
|
// It is the filing-time counterpart to `split:assess`: the size half is that command's own verdict,
|
|
13
13
|
// called rather than recomputed (the counting and the guide live in `split-assess.ts`), and
|
|
@@ -25,6 +25,8 @@ const REASONS: Record<FoldVerdict, string> = {
|
|
|
25
25
|
separate:
|
|
26
26
|
'separate — file these apart; they are separable and their combined size clears the split guide',
|
|
27
27
|
'no-fold-needed': 'no fold needed — a single candidate is filed on its own',
|
|
28
|
+
undetermined:
|
|
29
|
+
'undetermined — the diff measures no size, so the whole request\'s estimate decides (`split-assessment.md` → "The question")',
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
interface FoldArguments {
|
|
@@ -50,20 +52,23 @@ function read_arguments(argv: ReadonlyArray<string>): FoldArguments | undefined
|
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
// The size half, single-sourced from `split:assess
|
|
54
|
-
// same guide.
|
|
55
|
-
//
|
|
56
|
-
|
|
55
|
+
// The size half, single-sourced from `split:assess`: the same counting, the
|
|
56
|
+
// same guide. `undefined` when the diff says nothing about size — no changed non-test file, or a diff
|
|
57
|
+
// that cannot be read (no base, not a checkout) — which `fold_verdict` answers as `undetermined`
|
|
58
|
+
// rather than folding on no evidence. `issue:file` asks it too.
|
|
59
|
+
async function size_verdict(): Promise<SplitVerdict | undefined> {
|
|
57
60
|
try {
|
|
58
|
-
|
|
61
|
+
const measurement = split_assess.assess(await git_command.diff_main_numstat())
|
|
62
|
+
|
|
63
|
+
return measurement.files === 0 ? undefined : measurement.verdict
|
|
59
64
|
} catch {
|
|
60
|
-
return
|
|
65
|
+
return undefined
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
// The size question is only asked once there is something to fold; a lone candidate is answered
|
|
65
70
|
// without measuring anything.
|
|
66
|
-
async function size_for(args: FoldArguments): Promise<SplitVerdict> {
|
|
71
|
+
async function size_for(args: FoldArguments): Promise<SplitVerdict | undefined> {
|
|
67
72
|
if (args.titles.length < issue_fold.MIN_CANDIDATES) return split_assess.SINGLE_VERDICT
|
|
68
73
|
|
|
69
74
|
return await size_verdict()
|
|
@@ -90,7 +95,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
90
95
|
process.exitCode = await run(argv)
|
|
91
96
|
}
|
|
92
97
|
|
|
93
|
-
const issue_fold_cli = { read_arguments, size_verdict, run }
|
|
98
|
+
const issue_fold_cli = { REASONS, read_arguments, size_verdict, run }
|
|
94
99
|
|
|
95
100
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
96
101
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { split_assess, type SplitVerdict } from '#scripts/split/split-assess'
|
|
2
2
|
|
|
3
|
-
// The filing-time counterpart to the split assessment
|
|
3
|
+
// The filing-time counterpart to the split assessment.
|
|
4
4
|
//
|
|
5
5
|
// `split-assessment.md` → "The question" decides whether *one request* is really several
|
|
6
6
|
// deliverables; this decides whether *several findings filed from one session* fold into one Issue or
|
|
@@ -11,32 +11,47 @@ import { split_assess, type SplitVerdict } from '#scripts/split/split-assess'
|
|
|
11
11
|
//
|
|
12
12
|
// **The default is `fold`.** Separability alone never separates — it is necessary, not sufficient —
|
|
13
13
|
// and a size that does not clear the split guide folds however separable the findings are. That is
|
|
14
|
-
// why an unmeasurable size
|
|
15
|
-
//
|
|
14
|
+
// why an unmeasurable size never tips to `separate`: that would reproduce the every-finding-its-own-Issue
|
|
15
|
+
// behavior this exists to end.
|
|
16
|
+
//
|
|
17
|
+
// **Nor does an unmeasurable size fold**. The size half is read off the working
|
|
18
|
+
// tree's diff, and a filing made before any implementation — `kickoff new`, a split's children — has
|
|
19
|
+
// no diff that says anything about the findings' size. Reading that as `single` folded every such
|
|
20
|
+
// filing; it answers `undetermined` instead, which leaves the size to the whole request's estimate
|
|
21
|
+
// (`split-assessment.md` → "The question").
|
|
16
22
|
|
|
17
|
-
type FoldVerdict = 'fold' | 'separate' | 'no-fold-needed'
|
|
23
|
+
type FoldVerdict = 'fold' | 'separate' | 'no-fold-needed' | 'undetermined'
|
|
18
24
|
|
|
19
25
|
const FOLD: FoldVerdict = 'fold'
|
|
20
26
|
const SEPARATE: FoldVerdict = 'separate'
|
|
21
27
|
const NO_FOLD_NEEDED: FoldVerdict = 'no-fold-needed'
|
|
28
|
+
const UNDETERMINED: FoldVerdict = 'undetermined'
|
|
22
29
|
|
|
23
30
|
// One finding is nothing to fold: the question only arises once a session holds two or more.
|
|
24
31
|
const MIN_CANDIDATES = 2
|
|
25
32
|
|
|
33
|
+
// Separable findings: the size alone decides, and a size nobody measured decides nothing.
|
|
34
|
+
function separable_verdict(size_verdict: SplitVerdict | undefined): FoldVerdict {
|
|
35
|
+
if (size_verdict === undefined) return UNDETERMINED
|
|
36
|
+
|
|
37
|
+
return size_verdict === split_assess.SPLIT_VERDICT ? SEPARATE : FOLD
|
|
38
|
+
}
|
|
39
|
+
|
|
26
40
|
// The same two questions as the split assessment, in the same conjunction: `separate` only when the
|
|
27
41
|
// findings are separable **and** their combined size clears the split guide. Either half alone folds,
|
|
28
|
-
// and fewer than two candidates is not a fold question at all.
|
|
42
|
+
// and fewer than two candidates is not a fold question at all. An `undefined` size is one the diff
|
|
43
|
+
// could not measure, which decides nothing.
|
|
29
44
|
function fold_verdict(
|
|
30
45
|
candidate_count: number,
|
|
31
46
|
is_separable: boolean,
|
|
32
|
-
size_verdict: SplitVerdict,
|
|
47
|
+
size_verdict: SplitVerdict | undefined,
|
|
33
48
|
): FoldVerdict {
|
|
34
49
|
if (candidate_count < MIN_CANDIDATES) return NO_FOLD_NEEDED
|
|
35
50
|
|
|
36
|
-
return is_separable
|
|
51
|
+
return is_separable ? separable_verdict(size_verdict) : FOLD
|
|
37
52
|
}
|
|
38
53
|
|
|
39
|
-
const issue_fold = { FOLD, SEPARATE, NO_FOLD_NEEDED, MIN_CANDIDATES, fold_verdict }
|
|
54
|
+
const issue_fold = { FOLD, SEPARATE, NO_FOLD_NEEDED, UNDETERMINED, MIN_CANDIDATES, fold_verdict }
|
|
40
55
|
|
|
41
56
|
export type { FoldVerdict }
|
|
42
57
|
export { issue_fold }
|