@joshuafolkken/kit 1.1229.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 +24 -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 +27 -16
- package/.claude/skills/workflow-commands/latest-gate.md +18 -29
- 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/.github/workflows/publish.yml +2 -0
- package/.vscode/tasks.json +14 -0
- package/CLAUDE.md +10 -61
- package/README.md +38 -57
- 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-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
- package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
- package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
- package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
- package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
- package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
- package/dist/hooks/{chunk-6HJJXRBX.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-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
- package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
- package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
- package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
- package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
- 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 +213 -197
- 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 -201
- package/dist/josh.js +540 -137
- 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 +4 -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 +162 -0
- package/scripts/gate/core-budget.ts +134 -91
- package/scripts/gate/gate-ledger.ts +114 -0
- package/scripts/gate/gate-log.ts +7 -9
- package/scripts/gate/gate-plan.ts +103 -35
- package/scripts/gate/gate-report.ts +39 -21
- 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 +313 -0
- 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 +60 -53
- 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 +12 -8
- 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 +35 -0
- 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 +49 -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 +75 -15
- package/scripts/issue/issue-file-fold.ts +155 -0
- package/scripts/issue/issue-file.ts +14 -6
- package/scripts/issue/issue-fold-cli.ts +14 -9
- package/scripts/issue/issue-fold.ts +23 -8
- package/scripts/issue/issue-labels.ts +46 -37
- 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 +165 -0
- package/scripts/issue/issue-release.ts +58 -0
- 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 +32 -34
- 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 +33 -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 +11 -5
- package/scripts/josh/josh-commands-lane.ts +16 -5
- package/scripts/josh/josh-commands-lint.ts +1 -1
- package/scripts/josh/josh-commands-maintenance.ts +2 -2
- 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 +10 -10
- 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 +20 -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 +44 -30
- 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 +25 -24
- package/scripts/lane/lane-output.ts +4 -3
- package/scripts/lane/lane-paths.ts +22 -8
- package/scripts/lane/lane-phase.ts +33 -0
- package/scripts/lane/lane-reap.ts +2 -2
- package/scripts/lane/lane-registry.ts +27 -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 +140 -0
- 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-environment.ts +1 -0
- package/scripts/release/github-release-runs.ts +115 -0
- package/scripts/release/github-release.ts +13 -67
- 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 +68 -37
- 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 +10 -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 +172 -43
- 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 +62 -48
- 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 -33
- package/scripts/run/wake/run-wake-describe.ts +76 -29
- 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 +13 -21
- 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 -328
- 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 +129 -98
- 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/templates/workflows/github-release.yml +4 -0
- package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
- 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,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 }
|
|
@@ -7,41 +7,41 @@ const ENHANCEMENT_LABEL = 'enhancement'
|
|
|
7
7
|
const BREAKING_CHANGE_LABEL = 'breaking-change'
|
|
8
8
|
const IN_PROGRESS_LABEL = 'in-progress'
|
|
9
9
|
// Applied by `kickoff` once its plan is on the issue, so the next command's `run:entry` reads the issue
|
|
10
|
-
// as planned and starts at the implementation rather than planning again
|
|
10
|
+
// as planned and starts at the implementation rather than planning again.
|
|
11
11
|
// Namespaced like `run:solo`: a bare `planned` is a common roadmap label a person may already apply,
|
|
12
12
|
// and reading one as kickoff's mark would skip the planning that never happened.
|
|
13
13
|
const PLANNED_LABEL = 'run:planned'
|
|
14
14
|
// Parks a child that cannot advance without a person deciding something. `epic:next` is what reads
|
|
15
15
|
// it: a parked child is why a run reports "nothing left that time will fix" rather than waiting
|
|
16
|
-
// forever
|
|
16
|
+
// forever.
|
|
17
17
|
const NEEDS_DECISION_LABEL = 'needs-decision'
|
|
18
|
-
// Marks an issue whose defect reaches the verification path, so it runs with nothing beside it
|
|
19
|
-
//
|
|
18
|
+
// Marks an issue whose defect reaches the verification path, so it runs with nothing beside it.
|
|
19
|
+
// A run applies it from the verification-path enumeration in `backlogrun-lanes.md`;
|
|
20
20
|
// `backlog:next` enforces it (`backlog-solo.ts`), so the rule no longer rests on a judgement at
|
|
21
21
|
// dispatch time.
|
|
22
22
|
const RUN_SOLO_LABEL = 'run:solo'
|
|
23
|
-
// The other half of the same judgement: an issue a run read and found safe to run beside others
|
|
24
|
-
//
|
|
23
|
+
// The other half of the same judgement: an issue a run read and found safe to run beside others.
|
|
24
|
+
// Without it an issue lacking `run:solo` could mean "judged parallel" or
|
|
25
25
|
// "never judged", and `backlog:next` withholds the second (`epic-triage.ts`).
|
|
26
26
|
const RUN_LANE_LABEL = 'run:lane'
|
|
27
|
-
// Puts an issue at the head of the backlog's ranking
|
|
27
|
+
// Puts an issue at the head of the backlog's ranking. A person or a run may
|
|
28
28
|
// apply it — a run only where it can cite a deadline or a stated urgency, or a policy a person wrote
|
|
29
29
|
// (`backlogrun-steps.md`) — and **only a person removes it**: a run that could clear it could undo
|
|
30
30
|
// the person's ordering. Read by `issue-rank.ts`, the one place the ranking keys are decided.
|
|
31
31
|
const PRIORITY_HIGH_LABEL = 'priority:high'
|
|
32
|
-
// Opts one issue outside any epic into unattended execution
|
|
32
|
+
// Opts one issue outside any epic into unattended execution. **Only a
|
|
33
33
|
// person applies it.** `epicrun #<E>` approves the merges inside `#<E>`; this label is the only way
|
|
34
34
|
// a person extends that approval past the epic's edge, so a label an AI could apply to itself would
|
|
35
35
|
// let an unattended run widen its own authorization — which is not a guard at all.
|
|
36
36
|
const AUTO_OK_LABEL = 'auto-ok'
|
|
37
37
|
// Degrades one issue's run to a `halfrun`-shaped stop: it is implemented and taken through the
|
|
38
|
-
// verification gate, and then nothing is committed, pushed, opened as a pull request or merged
|
|
39
|
-
//
|
|
38
|
+
// verification gate, and then nothing is committed, pushed, opened as a pull request or merged.
|
|
39
|
+
// **Only a person applies it** — a mark a run could clear for itself is not
|
|
40
40
|
// a mark.
|
|
41
41
|
//
|
|
42
42
|
// It is the opposite of `auto-ok` in what it does: one widens unattended execution past an epic's
|
|
43
43
|
// edge, the other withholds the last step of it. Unlike `auto-ok`, which `issue:file` applies by
|
|
44
|
-
// default to work found by opted-in work
|
|
44
|
+
// default to work found by opted-in work, no run ever applies it. `auto-ok`
|
|
45
45
|
// answers "may this run at all", this one answers "may its result ship without a person looking".
|
|
46
46
|
//
|
|
47
47
|
// **Not `needs-decision`, and the difference is what the two sets below encode.** A parked issue is
|
|
@@ -51,10 +51,9 @@ const AUTO_OK_LABEL = 'auto-ok'
|
|
|
51
51
|
// checkout and must go on holding the repository. Read as parked in either place, the next child
|
|
52
52
|
// would start on top of that work.
|
|
53
53
|
const NEEDS_HUMAN_REVIEW_LABEL = 'needs-human-review'
|
|
54
|
-
// Marks an issue whose work a run verified is **already merged
|
|
55
|
-
// an Issue is Tier C, so a run that reaches that conclusion may not act on it —
|
|
56
|
-
//
|
|
57
|
-
// `main` from joshuafolkken/kit#1623 and closed the Issue itself.
|
|
54
|
+
// Marks an issue whose work a run verified is **already merged**. Closing
|
|
55
|
+
// an Issue is Tier C, so a run that reaches that conclusion may not act on it — this label is its
|
|
56
|
+
// exit that is not Tier C.
|
|
58
57
|
//
|
|
59
58
|
// **It is not `needs-decision`, and the difference is the whole reason it exists.** A parked issue
|
|
60
59
|
// waits for an answer nobody has given; this one has its answer already — the work is done, and all
|
|
@@ -65,6 +64,12 @@ const NEEDS_HUMAN_REVIEW_LABEL = 'needs-human-review'
|
|
|
65
64
|
// takes it off, because taking it off asserts the work is *not* done, which is the same claim in
|
|
66
65
|
// reverse and is no more a run's to make.
|
|
67
66
|
const ALREADY_DONE_LABEL = 'already-done'
|
|
67
|
+
// Marks the Issue that tracks a repository's next release. An Issue whose
|
|
68
|
+
// change reaches a consumer only once published is linked to it as a `blocked_by` blocker
|
|
69
|
+
// (`josh issue:release`), so "merged but not yet released" is visible in the backlog. A run applies
|
|
70
|
+
// it; **`auto-ok` never rides on it** — `issue-auto-ok.ts` refuses the default for it on every path,
|
|
71
|
+
// since a release is Tier C — and only a person opts it into unattended execution.
|
|
72
|
+
const RELEASE_LABEL = 'release'
|
|
68
73
|
|
|
69
74
|
// The four labels that mean an open issue must not be handed to a run as it stands: an `epic`
|
|
70
75
|
// tracks a batch and is never run directly (its children are), `in-progress` is already claimed by
|
|
@@ -84,20 +89,19 @@ const NOT_DIRECTLY_RUNNABLE_LABELS: ReadonlySet<string> = new Set([
|
|
|
84
89
|
ALREADY_DONE_LABEL,
|
|
85
90
|
])
|
|
86
91
|
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
92
|
+
// Filing-route labels, applied at filing time so the backlog's composition — a review-cap
|
|
93
|
+
// carry-forward vs a split child vs a Tier A in-implementation filing — is countable with
|
|
94
|
+
// `gh api "repos/{owner}/{repo}/issues?labels=<route>"` instead of grepping issue bodies by hand,
|
|
95
|
+
// which does not reproduce. Purely
|
|
91
96
|
// informational: unlike the three above, a route label says nothing about whether an issue may run,
|
|
92
97
|
// so none of them joins NOT_DIRECTLY_RUNNABLE_LABELS. The names are duplicated as literals in the
|
|
93
98
|
// filing procedures (prose cannot import this module); `scripts/rules/filing-route-label.test.ts` keys the
|
|
94
99
|
// docs to these constants so a filing command that drops the label fails rather than drifting.
|
|
95
100
|
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
// a prerequisite), and reading the two as one is what lost #1517.
|
|
101
|
+
// `route:interrupt` is a defect found in *this* repository that does not block the run that found
|
|
102
|
+
// it, and which the WIP cap would otherwise push into the discretionary exit, surviving only as a
|
|
103
|
+
// comment on another issue. It is not `route:tier-a`: that one is a filing the run is blocked by (an
|
|
104
|
+
// upstream defect or a prerequisite), and reading the two as one loses the interrupt.
|
|
101
105
|
const INTERRUPT_ROUTE_LABEL = 'route:interrupt'
|
|
102
106
|
const REVIEW_CAP_ROUTE_LABEL = 'route:review-cap'
|
|
103
107
|
const SPLIT_ROUTE_LABEL = 'route:split'
|
|
@@ -139,7 +143,7 @@ const FILING_ROUTE_LABELS: ReadonlyArray<{
|
|
|
139
143
|
},
|
|
140
144
|
]
|
|
141
145
|
|
|
142
|
-
//
|
|
146
|
+
// The depth of an issue's subject, recorded as a label at filing time.
|
|
143
147
|
//
|
|
144
148
|
// **The definition is not here.** `.claude/skills/workflow-commands/observation-filing.md` → "The depth test",
|
|
145
149
|
// is the single source: depth 0 is what a consumer of this package touches, depth 1 the run
|
|
@@ -148,10 +152,9 @@ const FILING_ROUTE_LABELS: ReadonlyArray<{
|
|
|
148
152
|
// would be the clone `CLAUDE.md` prohibits, and the descriptions below therefore name the section
|
|
149
153
|
// rather than paraphrase it.
|
|
150
154
|
//
|
|
151
|
-
// **Why a label at all.**
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
// therefore not comparable, which is the failure a recorded label removes.
|
|
155
|
+
// **Why a label at all.** The share of open issues at depth 0 is a measured target, and without a
|
|
156
|
+
// recorded depth it could only be obtained by reading every open issue's body by hand — hand counts
|
|
157
|
+
// disagree on the denominator and are not comparable, which is the failure a recorded label removes.
|
|
155
158
|
//
|
|
156
159
|
// **The depth is read off the subject, so a run applies it.** Unlike `auto-ok` and
|
|
157
160
|
// `needs-human-review` this is not a person's judgement about authorization; it is the same reading
|
|
@@ -163,8 +166,7 @@ const DEPTH_2_LABEL = 'depth:2'
|
|
|
163
166
|
|
|
164
167
|
// Ordered shallowest first, which is what makes `depth_label_of` deterministic: an issue carrying
|
|
165
168
|
// more than one depth label counts as the **lowest** depth present, the one closest to the consumer.
|
|
166
|
-
// Without a fixed tie-break the same listing measured twice could answer differently
|
|
167
|
-
// whole defect joshuafolkken/kit#1729 was filed for.
|
|
169
|
+
// Without a fixed tie-break the same listing measured twice could answer differently.
|
|
168
170
|
const DEPTH_LABEL_ORDER: ReadonlyArray<string> = [DEPTH_0_LABEL, DEPTH_1_LABEL, DEPTH_2_LABEL]
|
|
169
171
|
|
|
170
172
|
// The metadata `gh api ... labels` needs, in the shape `FILING_ROUTE_LABELS` above uses and for the
|
|
@@ -173,7 +175,7 @@ const DEPTH_LABEL_ORDER: ReadonlyArray<string> = [DEPTH_0_LABEL, DEPTH_1_LABEL,
|
|
|
173
175
|
// Green, amber and pale blue, so the consumer-facing depth is the one that stands out in a listing.
|
|
174
176
|
//
|
|
175
177
|
// **`josh issue:file` provisions them** through `repository_labels.ensure_labels` before its create
|
|
176
|
-
// call
|
|
178
|
+
// call, so no document carries a creation command to keep in step.
|
|
177
179
|
const DEPTH_LABELS: ReadonlyArray<{
|
|
178
180
|
name: string
|
|
179
181
|
color: string
|
|
@@ -203,7 +205,7 @@ interface LabelDefinition {
|
|
|
203
205
|
}
|
|
204
206
|
|
|
205
207
|
// What `josh start` provisions on a new repository so the first `kickoff` finds every label a run
|
|
206
|
-
// applies with its intended color
|
|
208
|
+
// applies with its intended color. The `epic` and `in-progress` metadata is
|
|
207
209
|
// the one the workflow documents create them with; the labels only a person applies are left out.
|
|
208
210
|
const WORKFLOW_LABELS: ReadonlyArray<LabelDefinition> = [
|
|
209
211
|
{
|
|
@@ -228,12 +230,17 @@ const WORKFLOW_LABELS: ReadonlyArray<LabelDefinition> = [
|
|
|
228
230
|
color: 'e99695',
|
|
229
231
|
description: 'Offered first in a backlogrun; only a person removes it',
|
|
230
232
|
},
|
|
233
|
+
{
|
|
234
|
+
name: RELEASE_LABEL,
|
|
235
|
+
color: 'fef2c0',
|
|
236
|
+
description: 'Tracks the next release; its blockers are the merged work it publishes',
|
|
237
|
+
},
|
|
231
238
|
...FILING_ROUTE_LABELS,
|
|
232
239
|
...DEPTH_LABELS,
|
|
233
240
|
]
|
|
234
241
|
|
|
235
|
-
// The pull request release classifications `pr-classification.yml` requires exactly one of
|
|
236
|
-
//
|
|
242
|
+
// The pull request release classifications `pr-classification.yml` requires exactly one of.
|
|
243
|
+
// The check is distributed by `josh sync`, so the labels it asks for are
|
|
237
244
|
// provisioned from this same list — a repository that never had them would otherwise fail the check
|
|
238
245
|
// on every pull request that is not an `enhancement`.
|
|
239
246
|
const BUGFIX_LABEL = 'bugfix'
|
|
@@ -289,7 +296,7 @@ function has_any_label(
|
|
|
289
296
|
// A membership test answers whether the label is there; a *removal* has to name it, and
|
|
290
297
|
// `DELETE …/issues/<N>/labels/<name>` names it in the path. Lowercasing the wanted name and sending
|
|
291
298
|
// that would be a second comparison — GitHub's, on a spelling we did not read — so the removal reads
|
|
292
|
-
// the stored one and sends it back
|
|
299
|
+
// the stored one and sends it back.
|
|
293
300
|
function label_name_of(labels: ReadonlyArray<string>, wanted: string): string | undefined {
|
|
294
301
|
const target = wanted.toLowerCase()
|
|
295
302
|
|
|
@@ -318,7 +325,7 @@ function depth_label_of(labels: ReadonlyArray<LabelReference> | undefined): stri
|
|
|
318
325
|
}
|
|
319
326
|
|
|
320
327
|
// Every workflow label this package manages. The label-reference scan
|
|
321
|
-
// (`scripts/document/label-reference.test.ts
|
|
328
|
+
// (`scripts/document/label-reference.test.ts`) reads this to check that no
|
|
322
329
|
// document operates on a label name that does not exist here — a stale or mistyped `labels[]=…`
|
|
323
330
|
// otherwise fails silently at run time. One source, so a label added above joins the scan without a
|
|
324
331
|
// second edit.
|
|
@@ -340,6 +347,7 @@ const ALL_LABELS: ReadonlySet<string> = new Set([
|
|
|
340
347
|
NEEDS_HUMAN_REVIEW_LABEL,
|
|
341
348
|
ALREADY_DONE_LABEL,
|
|
342
349
|
PRIORITY_HIGH_LABEL,
|
|
350
|
+
RELEASE_LABEL,
|
|
343
351
|
INTERRUPT_ROUTE_LABEL,
|
|
344
352
|
REVIEW_CAP_ROUTE_LABEL,
|
|
345
353
|
REVIEW_ROUND2_SKIPPED_LABEL,
|
|
@@ -386,6 +394,7 @@ export {
|
|
|
386
394
|
PRIORITY_HIGH_LABEL,
|
|
387
395
|
RELEASE_CLASSIFICATION_LABELS,
|
|
388
396
|
RELEASE_CLASSIFICATION_NAMES,
|
|
397
|
+
RELEASE_LABEL,
|
|
389
398
|
REPOSITORY_LABELS,
|
|
390
399
|
REVIEW_CAP_ROUTE_LABEL,
|
|
391
400
|
REVIEW_ROUND2_SKIPPED_LABEL,
|
|
@@ -6,10 +6,10 @@ import { issue_classification } from './issue-classification'
|
|
|
6
6
|
import { issue_lint } from './issue-lint'
|
|
7
7
|
|
|
8
8
|
// `josh issue:lint <path>` — read an Issue body from a file and print `ok`, or every template problem
|
|
9
|
-
// one per line, exiting non-zero
|
|
9
|
+
// one per line, exiting non-zero. It reads a path rather than stdin so it can
|
|
10
10
|
// lint a body written to a file before the `gh api … issues` call that files it. A body that declares
|
|
11
11
|
// itself a behavior-change Issue is additionally held to the firing-point, baseline and reproduction
|
|
12
|
-
// rules
|
|
12
|
+
// rules.
|
|
13
13
|
|
|
14
14
|
const SUCCESS_EXIT_CODE = 0
|
|
15
15
|
const FAILURE_EXIT_CODE = 1
|
|
@@ -2,7 +2,7 @@ import { markdown_section } from './markdown-section'
|
|
|
2
2
|
|
|
3
3
|
// The Issue body template's four headings (`prompts/collaboration-workflow/issue-template.md`) are a
|
|
4
4
|
// fixed shape, but unlike an epic — which `josh epic:check` verifies — nothing checks that a filed
|
|
5
|
-
// Issue carries them. This reports the ones a body is missing
|
|
5
|
+
// Issue carries them. This reports the ones a body is missing. The headings
|
|
6
6
|
// are the single source's, and the document test pins that these match it.
|
|
7
7
|
const REQUIRED_HEADINGS: ReadonlyArray<string> = [
|
|
8
8
|
'## 背景',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
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
|
|
|
4
|
-
// Whether an issue was closed by a merge, read from its REST timeline
|
|
4
|
+
// Whether an issue was closed by a merge, read from its REST timeline. The
|
|
5
5
|
// issue's own `state_reason` cannot tell: a pull request's `closes #N` and a person's "Close as
|
|
6
6
|
// completed" both answer `completed`. What only a merge leaves is a merged pull request referencing
|
|
7
7
|
// the issue, so the answer is the conjunction — closed now, as completed, and referenced by a merged
|
|
@@ -55,7 +55,9 @@ function is_merged_close(rows: ReadonlyArray<TimelineRow>): boolean {
|
|
|
55
55
|
return rows.some((row) => row.event === MERGED_REFERENCE)
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
// `undefined` when the timeline could not be read, so a caller that keeps the answer can tell "not
|
|
59
|
+
// merged" from "ask again".
|
|
60
|
+
async function read_merge_state(issue: string): Promise<boolean | undefined> {
|
|
59
61
|
try {
|
|
60
62
|
const raw = await git_gh_exec.exec_gh_api({
|
|
61
63
|
path: `${git_gh_api_path.issue_api_path(issue)}/timeline?per_page=100`,
|
|
@@ -65,11 +67,15 @@ async function read_merged(issue: string): Promise<boolean> {
|
|
|
65
67
|
|
|
66
68
|
return is_merged_close(parse_rows(raw))
|
|
67
69
|
} catch {
|
|
68
|
-
return
|
|
70
|
+
return undefined
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
async function read_merged(issue: string): Promise<boolean> {
|
|
75
|
+
return (await read_merge_state(issue)) ?? false
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const issue_merged = { is_merged_close, parse_rows, read_merge_state, read_merged }
|
|
73
79
|
|
|
74
80
|
export type { TimelineRow }
|
|
75
81
|
export { issue_merged }
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// The shape an issue number may take, and the refusal when it does not — the one declaration every
|
|
2
|
+
// command reads.
|
|
3
|
+
//
|
|
4
|
+
// It sits in its own module because a rule copied into two files is a rule kept correct in one: a
|
|
5
|
+
// copy that read `/^\d+$/u` accepted issue `0` and a leading zero where every other command refused
|
|
6
|
+
// them. A command that interpolates the number into a shell command a caller is told to paste, a
|
|
7
|
+
// GitHub path, a branch or a lane directory refuses before the interpolation rather than leaving the
|
|
8
|
+
// check to whichever entry point remembered.
|
|
9
|
+
//
|
|
10
|
+
// `ISSUE_NUMBER_PATTERN` stays exported beside `is_issue_number`: a taint analyzer credits a literal
|
|
11
|
+
// pattern test in the expression that returns the value as a sanitizer, but not one reached through a
|
|
12
|
+
// call (`run-merge-cli.ts`).
|
|
13
|
+
|
|
14
|
+
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
15
|
+
const BAD_ISSUE_MESSAGE = 'Not an issue number: '
|
|
16
|
+
|
|
17
|
+
function is_issue_number(value: string): boolean {
|
|
18
|
+
return ISSUE_NUMBER_PATTERN.test(value)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function require_issue_number(issue: string): void {
|
|
22
|
+
if (!is_issue_number(issue)) throw new Error(`${BAD_ISSUE_MESSAGE}${issue}`)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const issue_number_shape = { ISSUE_NUMBER_PATTERN, is_issue_number, require_issue_number }
|
|
26
|
+
|
|
27
|
+
export { issue_number_shape }
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
RUN_SOLO_LABEL,
|
|
7
7
|
} from './issue-labels'
|
|
8
8
|
|
|
9
|
-
// The keys that decide which open issue is offered first
|
|
9
|
+
// The keys that decide which open issue is offered first, defined once for
|
|
10
10
|
// every ranking that asks: the `🗒 Next issues` display, the `auto-ok` pickup and `backlog:next`.
|
|
11
11
|
//
|
|
12
12
|
// In order: `priority:high`, then a defect on the verification path (`bug` with `run:solo`, or
|
|
@@ -1,12 +1,12 @@
|
|
|
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 { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
5
6
|
import { issue_read, type IssueComment, type IssueFields } from './issue-read'
|
|
6
7
|
import { issue_report_failures, type ReadFailureKind } from './issue-report-failures'
|
|
7
8
|
|
|
8
|
-
// `josh issue:read <N> [<N> ...]` — the body *and* the comments of every issue named, in one call
|
|
9
|
-
// (joshuafolkken/kit#1715).
|
|
9
|
+
// `josh issue:read <N> [<N> ...]` — the body *and* the comments of every issue named, in one call.
|
|
10
10
|
//
|
|
11
11
|
// It replaces the two `gh api` reads `.claude/skills/workflow-commands/issue-comments.md` tells an agent
|
|
12
12
|
// to type per issue. Measured over four recorded `backlogrun` parents, `issue bookkeeping` was the
|
|
@@ -28,7 +28,6 @@ import { issue_report_failures, type ReadFailureKind } from './issue-report-fail
|
|
|
28
28
|
|
|
29
29
|
const FAILURE_EXIT_CODE = 1
|
|
30
30
|
const ARGV_OFFSET = 2
|
|
31
|
-
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
32
31
|
const USAGE = 'Usage: josh issue:read <issue-number> [<issue-number> ...]'
|
|
33
32
|
const BLOCK_SEPARATOR = '\n\n---\n\n'
|
|
34
33
|
// The same bound `issue:state` puts on its batch read, for the same reason: every read is a `gh`
|
|
@@ -45,7 +44,7 @@ interface IssueContent {
|
|
|
45
44
|
type NumberResult = { kind: 'issue'; content: IssueContent } | { kind: ReadFailureKind }
|
|
46
45
|
|
|
47
46
|
// The formatted block for one issue, or the failure kind — what `run:prep` bundles beside the state
|
|
48
|
-
// and the dependency-update scope
|
|
47
|
+
// and the dependency-update scope. It reuses this file's read and the shared
|
|
49
48
|
// `format_issue` rather than reproducing either, so the two `gh` reads and the block shape stay
|
|
50
49
|
// single-sourced here.
|
|
51
50
|
type BlockRead = { kind: 'ok'; block: string } | { kind: ReadFailureKind }
|
|
@@ -59,7 +58,7 @@ interface IssueReport {
|
|
|
59
58
|
// Dropping it answers fewer numbers than were asked for and still exits zero — and nothing in the
|
|
60
59
|
// output then says a number went unanswered. `#1262` copied out of a table is exactly that token.
|
|
61
60
|
function parse_numbers(argv: ReadonlyArray<string>): ReadonlyArray<string> | undefined {
|
|
62
|
-
const numbers = argv.filter((argument) =>
|
|
61
|
+
const numbers = argv.filter((argument) => issue_number_shape.is_issue_number(argument))
|
|
63
62
|
|
|
64
63
|
if (numbers.length === 0 || numbers.length !== argv.length) return undefined
|
|
65
64
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parse_json_object_or_undefined, read_json_listing } from '#scripts/git/parse-json-array'
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
4
|
// The block `josh issue:read` prints for one issue, kept apart from the reading and the printing so
|
|
5
|
-
// the shape of the report is decided by one pure function — the seam `issue-state.ts` already has
|
|
6
|
-
// (joshuafolkken/kit#1715).
|
|
5
|
+
// the shape of the report is decided by one pure function — the seam `issue-state.ts` already has.
|
|
7
6
|
//
|
|
8
7
|
// **It exists because reading one issue costs a parent two turns.** `.claude/skills/workflow-commands/SKILL.md`
|
|
9
8
|
// `issue-comments.md` requires the body *and* the comments, since a decision recorded after the body was written
|
|
@@ -11,7 +10,7 @@ import { z } from 'zod'
|
|
|
11
10
|
// `gh api repos/{owner}/{repo}/issues/<N>/comments`. Measured over four recorded `backlogrun`
|
|
12
11
|
// parents, `issue bookkeeping` was the single largest contributor to the parent's turn count — 110 of
|
|
13
12
|
// 414 turns, 26.6% — and one-issue-at-a-time `gh api` reads were its dominant shape. A parent's cost
|
|
14
|
-
// grows as n²/2 in its own request count
|
|
13
|
+
// grows as n²/2 in its own request count, so those turns are the
|
|
15
14
|
// distribution this collapses.
|
|
16
15
|
//
|
|
17
16
|
// **The comments are never silently absent.** A listing that could not be read prints a line saying
|
|
@@ -65,7 +64,7 @@ const UNKNOWN_TIME = '(undated)'
|
|
|
65
64
|
// parse.
|
|
66
65
|
function parse_issue_fields(json: string): IssueFields | undefined {
|
|
67
66
|
try {
|
|
68
|
-
const parsed =
|
|
67
|
+
const parsed = parse_json_object_or_undefined(json, issue_fields_schema)
|
|
69
68
|
|
|
70
69
|
if (parsed === undefined) return undefined
|
|
71
70
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// An issue named from outside any one graph — a task-list row, a citation in prose, a blocker
|
|
2
2
|
// relation, a child that could not be read. Repository **and** number, because a number alone cannot
|
|
3
3
|
// identify one: issue numbers are unique per repository, so the same `#40` names two different issues
|
|
4
|
-
// depending on who wrote it
|
|
4
|
+
// depending on who wrote it.
|
|
5
5
|
//
|
|
6
6
|
// It lives in the git layer because the `blocked-by` relations are read here and carry a repository
|
|
7
|
-
// of their own
|
|
8
|
-
// round
|
|
7
|
+
// of their own; the epic domain builds on this layer, never the other way
|
|
8
|
+
// round. `epic-reference` re-exports it, so every epic importer is unchanged.
|
|
9
9
|
//
|
|
10
|
-
// `state` is present only on a reference read from a `blocked-by` relation whose response carried it
|
|
11
|
-
//
|
|
10
|
+
// `state` is present only on a reference read from a `blocked-by` relation whose response carried it.
|
|
11
|
+
// The classifier needs it for a blocker no named graph tracks, where there is
|
|
12
12
|
// no child record to read the state from; every other reference leaves it out.
|
|
13
13
|
interface IssueReference {
|
|
14
14
|
repo: string
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
4
|
+
import { git_gh_exec } from '#scripts/gh/git-gh-exec'
|
|
5
|
+
import { git_gh_issue_list, MAX_SCANNED } from '#scripts/gh/git-gh-issue-list'
|
|
6
|
+
import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
|
|
7
|
+
import { github_issue_url } from '#scripts/gh/github-issue-url'
|
|
8
|
+
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
9
|
+
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
10
|
+
import { error_text } from '#scripts/lib/error-message'
|
|
11
|
+
import { repository_labels } from '#scripts/repo/repository-labels'
|
|
12
|
+
import { RELEASE_LABEL } from './issue-labels'
|
|
13
|
+
import { issue_release } from './issue-release'
|
|
14
|
+
import { session_cite } from './session-cite'
|
|
15
|
+
|
|
16
|
+
// `josh issue:release <N>` — link Issue `<N>` to its repository's release Issue as a `blocked_by`
|
|
17
|
+
// blocker, filing the release Issue when none is open. `josh issue:file
|
|
18
|
+
// --release` calls the same `link` once its Issue exists, so a new and an existing Issue are linked
|
|
19
|
+
// by one body of code.
|
|
20
|
+
//
|
|
21
|
+
// The relation is written through `issue_add_blocked_by`, which addresses the repository `gh`
|
|
22
|
+
// resolves — the current one, or the target a cross-repository `issue:file` has pointed `GH_REPO` at.
|
|
23
|
+
|
|
24
|
+
const SUCCESS_EXIT_CODE = 0
|
|
25
|
+
const FAILURE_EXIT_CODE = 1
|
|
26
|
+
const ARGV_OFFSET = 2
|
|
27
|
+
const USAGE = 'Usage: josh issue:release <issue-number>'
|
|
28
|
+
const NONE = 'none'
|
|
29
|
+
const UNKNOWN_REPO_MESSAGE =
|
|
30
|
+
'Could not read this repository from `git remote` — check `gh auth status`.'
|
|
31
|
+
|
|
32
|
+
interface ReleaseIssue {
|
|
33
|
+
issue_number: number
|
|
34
|
+
// Filed by this call, rather than found open.
|
|
35
|
+
is_filed: boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// `undefined` when the listing is unreadable, `NONE` when it reads and names no open release Issue.
|
|
39
|
+
async function find_open(target: string): Promise<number | typeof NONE | undefined> {
|
|
40
|
+
const outcome = await git_gh_issue_list.issue_list({
|
|
41
|
+
json_fields: 'number',
|
|
42
|
+
limit: MAX_SCANNED,
|
|
43
|
+
label: RELEASE_LABEL,
|
|
44
|
+
repo: target,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
if (outcome.json === undefined) return undefined
|
|
48
|
+
|
|
49
|
+
return issue_release.open_release_of(outcome.json) ?? NONE
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// The new release Issue's number, or `undefined` when the create call failed. Never `auto-ok`: the
|
|
53
|
+
// labels are `RELEASE_LABELS`, decided here rather than by `issue_auto_ok`, which refuses the label too.
|
|
54
|
+
async function file_release(target: string): Promise<number | undefined> {
|
|
55
|
+
repository_labels.ensure_labels(target)
|
|
56
|
+
const request = git_gh_issue_write.issue_create_request({
|
|
57
|
+
title: issue_release.title_of(target),
|
|
58
|
+
body: issue_release.body_of(target),
|
|
59
|
+
labels: issue_release.RELEASE_LABELS,
|
|
60
|
+
repo: target,
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const url = await git_gh_exec.exec_gh_api(request)
|
|
65
|
+
const issue_number = Number(github_issue_url.parse(url)?.issue_number) || undefined
|
|
66
|
+
|
|
67
|
+
if (issue_number === undefined) console.error(`✖ the release number is unreadable: ${url}`)
|
|
68
|
+
|
|
69
|
+
return issue_number
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error(`✖ the release Issue could not be filed: ${error_text.message_of(error)}`)
|
|
72
|
+
|
|
73
|
+
return undefined
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// An unreadable listing files nothing: a second release Issue beside one the listing failed to show
|
|
78
|
+
// would split the blockers between two releases.
|
|
79
|
+
async function release_of(target: string): Promise<ReleaseIssue | undefined> {
|
|
80
|
+
const open = await find_open(target)
|
|
81
|
+
|
|
82
|
+
if (open === undefined) {
|
|
83
|
+
console.error(`✖ the open ${RELEASE_LABEL} Issues of ${target} could not be listed`)
|
|
84
|
+
|
|
85
|
+
return undefined
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (open !== NONE) return { issue_number: open, is_filed: false }
|
|
89
|
+
const filed = await file_release(target)
|
|
90
|
+
|
|
91
|
+
return filed === undefined ? undefined : { issue_number: filed, is_filed: true }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function linked_line(release: ReleaseIssue, issue_number: number, target: string): string {
|
|
95
|
+
const how = release.is_filed ? 'filed' : 'open'
|
|
96
|
+
const release_cite = session_cite.issue(release.issue_number, undefined, target)
|
|
97
|
+
|
|
98
|
+
return `release: ${release_cite} (${how}) is blocked by ${session_cite.issue(issue_number, undefined, target)}`
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function unlinked_line(issue_number: number, blocked: string, target: string): string {
|
|
102
|
+
const blocker = session_cite.issue(issue_number, undefined, target)
|
|
103
|
+
|
|
104
|
+
return `✖ ${blocker} could not be recorded as a blocker of ${session_cite.issue(blocked, undefined, target)}`
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Whether Issue `issue_number` of `target` now blocks the release Issue. Every outcome is printed.
|
|
108
|
+
async function link(issue_number: number, target: string): Promise<boolean> {
|
|
109
|
+
const release = await release_of(target)
|
|
110
|
+
|
|
111
|
+
if (release === undefined) return false
|
|
112
|
+
const blocked = String(release.issue_number)
|
|
113
|
+
const is_linked = await git_gh_issue_write.issue_add_blocked_by(blocked, String(issue_number))
|
|
114
|
+
|
|
115
|
+
if (is_linked) console.info(linked_line(release, issue_number, target))
|
|
116
|
+
else console.error(unlinked_line(issue_number, blocked, target))
|
|
117
|
+
|
|
118
|
+
return is_linked
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// An unknown flag parses to no positionals, so it refuses the call like a missing number.
|
|
122
|
+
function positionals_of(argv: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
123
|
+
return cli_flags.arguments_of(argv, {})?.positionals ?? []
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// The number is the one positional: a missing, malformed or second one refuses the whole call.
|
|
127
|
+
function issue_number_of(argv: ReadonlyArray<string>): number | undefined {
|
|
128
|
+
const [issue_number, ...rest] = positionals_of(argv)
|
|
129
|
+
const is_single = rest.length === 0 && issue_number !== undefined
|
|
130
|
+
|
|
131
|
+
return is_single && issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue_number)
|
|
132
|
+
? Number(issue_number)
|
|
133
|
+
: undefined
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
137
|
+
const issue_number = issue_number_of(argv)
|
|
138
|
+
|
|
139
|
+
if (issue_number === undefined) {
|
|
140
|
+
console.error(USAGE)
|
|
141
|
+
|
|
142
|
+
return FAILURE_EXIT_CODE
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const current = await git_gh_command.repo_get_name_with_owner()
|
|
146
|
+
|
|
147
|
+
if (current === undefined) {
|
|
148
|
+
console.error(UNKNOWN_REPO_MESSAGE)
|
|
149
|
+
|
|
150
|
+
return FAILURE_EXIT_CODE
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return (await link(issue_number, current)) ? SUCCESS_EXIT_CODE : FAILURE_EXIT_CODE
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// `process.exitCode` rather than `process.exit()`, so the report on standard output drains first.
|
|
157
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
158
|
+
process.exitCode = await run(argv)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const issue_release_cli = { link, run }
|
|
162
|
+
|
|
163
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
164
|
+
|
|
165
|
+
export { issue_release_cli }
|