@joshuafolkken/kit 1.1784.0 → 1.2116.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/reviewer-verification.md +19 -0
- package/.claude/agents/reviewer.md +19 -0
- package/.claude/settings.json +5 -6
- package/.claude/skills/dependency-update/SKILL.md +9 -10
- package/.claude/skills/workflow-commands/SKILL.md +6 -6
- package/.claude/skills/workflow-commands/background-commands.md +8 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +41 -32
- package/.claude/skills/workflow-commands/delegation.md +6 -6
- package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
- package/.claude/skills/workflow-commands/followup.md +7 -5
- package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
- package/.claude/skills/workflow-commands/fullrun.md +1 -1
- package/.claude/skills/workflow-commands/issue-comments.md +9 -4
- package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
- package/.claude/skills/workflow-commands/kickoff.md +2 -2
- package/.claude/skills/workflow-commands/observation-filing.md +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
- package/.claude/skills/workflow-commands/prerequisite.md +3 -2
- package/.claude/skills/workflow-commands/retrospective.md +2 -2
- package/.claude/skills/workflow-commands/split-assessment.md +7 -5
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-pnpm/action.yml +9 -16
- package/.github/dependabot.yml +16 -0
- package/.github/workflows/auto-tag.yml +45 -0
- package/.github/workflows/ci.yml +155 -15
- package/.github/workflows/dependabot-auto-merge.yml +63 -4
- package/.github/workflows/production.yml +8 -0
- package/.github/workflows/publish.yml +60 -45
- package/.vscode/settings.json +19 -0
- package/CLAUDE.md +5 -12
- package/SECURITY.md +2 -2
- package/dist/CLAUDE.md +5 -12
- package/dist/commands/document-read-cli.js +2 -1
- package/dist/commands/document-section-main.js +2 -1
- package/dist/commands/read-set-cli.js +194 -134
- package/dist/commands/run-prep-main.js +9694 -10173
- package/dist/commands/run-step-cli.js +22138 -18285
- package/dist/hooks/audit-provision.js +23 -5
- package/dist/hooks/chunk-3GKE653K.js +6204 -0
- package/dist/hooks/chunk-45CJJOO7.js +1243 -0
- package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
- package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
- package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
- package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
- package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
- package/dist/hooks/chunk-VVNYJWEI.js +30 -0
- package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
- package/dist/hooks/codex-hook-adapter.js +8 -8
- package/dist/hooks/format-edited.js +4 -5
- package/dist/hooks/inputs.json +386 -360
- package/dist/hooks/pretool-guard.js +7 -6
- package/dist/hooks/session-lang.js +101 -258
- package/dist/hooks/stop-guard.js +1744 -2576
- package/dist/josh.js +7133 -6368
- package/dist/version/index.js +161 -1
- package/eslint/rules/comment-why-only.js +108 -0
- package/package.json +16 -9
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +14 -11
- package/prompts/collaboration-workflow/issue-citation.md +0 -4
- package/prompts/collaboration-workflow/issue-template.md +40 -21
- package/prompts/collaboration-workflow/lane-instructions.md +3 -1
- package/prompts/collaboration-workflow/measurement.md +8 -1
- package/prompts/collaboration-workflow/operating-rules.md +11 -2
- package/prompts/collaboration-workflow/output-bounds.md +6 -2
- package/prompts/collaboration-workflow/plan-comment.md +1 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow/residency.md +3 -2
- package/prompts/collaboration-workflow/rule-delivery.md +13 -1
- package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
- package/prompts/collaboration-workflow/wip-cap.md +3 -1
- package/prompts/review-rubric.md +8 -0
- package/prompts/review.md +31 -22
- package/prompts/testing-guide.md +1 -0
- package/scripts/agent/agent-argv.ts +14 -16
- package/scripts/agent/agent-provider.ts +138 -0
- package/scripts/agent/agent-role-profile.ts +108 -156
- package/scripts/agent/agent-safe-text.ts +20 -5
- package/scripts/agent/api-usage-limit.ts +65 -0
- package/scripts/agent/claude-agent-argv.ts +19 -9
- package/scripts/agent/codex-agent-argv.ts +118 -22
- package/scripts/agent/usage-limit-reset.ts +179 -0
- package/scripts/auth/claude-token-output.ts +2 -2
- package/scripts/auto-ok/auto-ok-author.ts +53 -0
- package/scripts/auto-ok/auto-ok-cli.ts +20 -9
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-cli.ts +6 -1
- package/scripts/backlog/backlog-drive-hold.ts +3 -3
- package/scripts/backlog/backlog-drive-idle.ts +10 -0
- package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
- package/scripts/backlog/backlog-drive-launch.ts +8 -2
- package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
- package/scripts/backlog/backlog-drive-named.ts +28 -7
- package/scripts/backlog/backlog-drive-paused.ts +5 -4
- package/scripts/backlog/backlog-drive-restore.ts +11 -3
- package/scripts/backlog/backlog-drive.ts +21 -60
- package/scripts/backlog/backlog-gate-scope.ts +61 -0
- package/scripts/backlog/backlog-measure-close.ts +112 -0
- package/scripts/backlog/backlog-next.ts +39 -49
- package/scripts/backlog/backlog-occupied.ts +2 -2
- package/scripts/backlog/backlog-overlap.ts +42 -8
- package/scripts/backlog/backlog-plan-cli.ts +4 -1
- package/scripts/backlog/backlog-plan-comment.ts +81 -0
- package/scripts/backlog/backlog-plan-read.ts +19 -6
- package/scripts/backlog/backlog-pool.ts +50 -12
- package/scripts/backlog/backlog-rank.ts +60 -13
- package/scripts/backlog/backlog-stalled-detect.ts +2 -1
- package/scripts/backlog/backlog-waves.ts +17 -2
- package/scripts/backlog/backlogrun-launch.ts +7 -4
- package/scripts/cost-runtime/context-cut-payback.ts +27 -25
- package/scripts/cost-runtime/cost-cli.ts +37 -16
- package/scripts/cost-runtime/cost-pricing.ts +9 -0
- package/scripts/cost-runtime/cost-verdict.ts +4 -1
- package/scripts/delegation/delegation-policy.ts +2 -2
- package/scripts/delegation/duplicate-read-guard.ts +1 -0
- package/scripts/delegation/investigation-guard.ts +14 -2
- package/scripts/delegation/investigation-reads.ts +45 -23
- package/scripts/dependabot/dependabot-cooldown.ts +3 -2
- package/scripts/discovery/repo-party.ts +80 -20
- package/scripts/discovery/session-owner-pin.ts +51 -0
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/command-reference-line-budget.ts +42 -0
- package/scripts/document/document-byte-budget.ts +17 -7
- package/scripts/document/document-checks.ts +20 -0
- package/scripts/document/document-ratchet-check.ts +101 -0
- package/scripts/document/document-section.ts +1 -0
- package/scripts/document/entry-read-budget.ts +7 -3
- package/scripts/document/issue-citation-budget.ts +94 -0
- package/scripts/epic/epic-cli-argv.ts +2 -2
- package/scripts/epic/epic-fetch.ts +4 -2
- package/scripts/epic/epic-graph.ts +7 -2
- package/scripts/epic/epic-issue.ts +3 -1
- package/scripts/epic/epic-rank.ts +5 -0
- package/scripts/exports/unused-members-check.ts +62 -0
- package/scripts/exports/unused-members-cli.ts +6 -51
- package/scripts/followup/followup-ci-path.ts +67 -0
- package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
- package/scripts/followup/followup-coderabbit-wait.ts +13 -10
- package/scripts/followup/followup-failed-tests.ts +160 -0
- package/scripts/followup/followup-job-needs.ts +100 -0
- package/scripts/followup/followup-job-rerun.ts +303 -0
- package/scripts/followup/followup-main-move.ts +113 -0
- package/scripts/followup/git-followup-finish.ts +43 -11
- package/scripts/followup/git-followup-pending.ts +3 -3
- package/scripts/followup/git-followup-stages.ts +41 -11
- package/scripts/followup/git-pr-followup-checks.ts +55 -16
- package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
- package/scripts/followup/git-pr-followup.ts +62 -27
- package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
- package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
- package/scripts/gate/busy-average.ts +34 -2
- package/scripts/gate/check-related-pinned.ts +43 -0
- package/scripts/gate/check-related-reuse.ts +64 -0
- package/scripts/gate/check-related-section.ts +57 -0
- package/scripts/gate/check-related-unplanned.ts +34 -0
- package/scripts/gate/check-related.ts +265 -0
- package/scripts/gate/command-memory.ts +1 -1
- package/scripts/gate/core-admission.ts +24 -6
- package/scripts/gate/core-budget-timing.ts +20 -6
- package/scripts/gate/core-budget.ts +40 -11
- package/scripts/gate/core-wait-record.ts +3 -2
- package/scripts/gate/core-wait.ts +25 -2
- package/scripts/gate/core-weights.ts +15 -7
- package/scripts/gate/gate-labels.ts +46 -0
- package/scripts/gate/gate-ledger.ts +14 -6
- package/scripts/gate/gate-plan.ts +103 -58
- package/scripts/gate/gate-report.ts +9 -7
- package/scripts/gate/gate-run-steps.ts +26 -3
- package/scripts/gate/gate-skip.ts +45 -6
- package/scripts/gate/gate-static-group.ts +60 -0
- package/scripts/gate/gate-steps.ts +2 -1
- package/scripts/gate/gate-tree.ts +4 -2
- package/scripts/gate/hook-gate-reuse.ts +19 -2
- package/scripts/gate/metrics-totals.ts +59 -0
- package/scripts/gate/scoped-green.ts +68 -15
- package/scripts/gate/since-green.ts +14 -6
- package/scripts/gate/structural-checks.ts +96 -0
- package/scripts/gate/verification-gate.ts +51 -16
- package/scripts/gate/verification-inputs.ts +21 -6
- package/scripts/gate/verification-tail.ts +52 -0
- package/scripts/gh/gh-author-association.ts +23 -2
- package/scripts/gh/git-ai-review-scan.ts +1 -1
- package/scripts/gh/git-gh-api-path.ts +12 -3
- package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
- package/scripts/gh/git-gh-exec.ts +32 -2
- package/scripts/gh/git-gh-issue-read.ts +4 -2
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +8 -2
- package/scripts/gh/git-gh-issue.ts +12 -5
- package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
- package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
- package/scripts/gh/git-gh-pr-read.ts +74 -13
- package/scripts/gh/git-gh-pr-rest.ts +3 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
- package/scripts/gh/git-gh-pr-too-large.ts +20 -0
- package/scripts/gh/git-gh-pr.ts +21 -7
- package/scripts/gh/git-gh-retry.ts +141 -0
- package/scripts/gh/git-pr-ai-review.ts +15 -6
- package/scripts/gh/git-pr-checks-eval.ts +3 -0
- package/scripts/gh/git-pr-checks.ts +5 -5
- package/scripts/git/base-tree.ts +30 -0
- package/scripts/git/change-base.ts +4 -10
- package/scripts/git/changed-paths-sync.ts +63 -0
- package/scripts/git/changed-paths.ts +16 -1
- package/scripts/git/git-common-directory.ts +11 -1
- package/scripts/git/git-diff-reads.ts +66 -20
- package/scripts/git/git-error.ts +9 -2
- package/scripts/git/git-schemas.ts +13 -0
- package/scripts/git/git-worktree.ts +13 -0
- package/scripts/git/gone-branch.ts +4 -1
- package/scripts/git/main-merge-budget-conflict.ts +89 -0
- package/scripts/git/main-merge-guard.ts +55 -18
- package/scripts/git/main-merge-regenerate.ts +59 -25
- package/scripts/git/main-merge.ts +53 -5
- package/scripts/git/no-base-checkout.ts +127 -0
- package/scripts/git/stash/git-stash.ts +11 -2
- package/scripts/git/stash/stash-push-cli.ts +10 -0
- package/scripts/hooks/batch-guard.ts +40 -21
- package/scripts/hooks/edited-cspell.ts +37 -11
- package/scripts/hooks/format-edited-file.ts +22 -2
- package/scripts/hooks/lane-plan-guard.ts +50 -0
- package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
- package/scripts/hooks/pre-commit-lint.ts +14 -1
- package/scripts/hooks/pre-push-related-switch.ts +10 -0
- package/scripts/hooks/pre-push-unit.ts +76 -10
- package/scripts/hooks/pretool-guard.ts +2 -0
- package/scripts/hooks/reserved-run.ts +14 -1
- package/scripts/hooks/run-hook.sh +23 -8
- package/scripts/hooks/step-zero-notice.ts +6 -1
- package/scripts/hooks/stop-actions.ts +3 -15
- package/scripts/hooks/stop-guard.ts +7 -6
- package/scripts/init/distributed-paths.ts +1 -0
- package/scripts/init/hook-command-rewrite.ts +5 -1
- package/scripts/init/hook-launch.ts +4 -2
- package/scripts/issue/aggregation-split.ts +52 -0
- package/scripts/issue/defect-origin-line.ts +19 -1
- package/scripts/issue/defect-rate-cli.ts +5 -102
- package/scripts/issue/defect-report.ts +4 -4
- package/scripts/issue/effect-audit-cli.ts +178 -0
- package/scripts/issue/effect-audit.ts +185 -0
- package/scripts/issue/expected-effect-lint.ts +64 -9
- package/scripts/issue/git-next-issues.ts +5 -0
- package/scripts/issue/issue-body-or-comment.ts +38 -4
- package/scripts/issue/issue-cite-cli.ts +1 -3
- package/scripts/issue/issue-classification.ts +1 -0
- package/scripts/issue/issue-closing-pr.ts +8 -1
- package/scripts/issue/issue-evidence-exit.ts +4 -2
- package/scripts/issue/issue-file-cap.ts +58 -0
- package/scripts/issue/issue-file-cli.ts +111 -38
- package/scripts/issue/issue-file-deferral.ts +52 -0
- package/scripts/issue/issue-file-fold.ts +29 -10
- package/scripts/issue/issue-file-interrupt.ts +85 -0
- package/scripts/issue/issue-file-lane-hint.ts +30 -0
- package/scripts/issue/issue-file.ts +43 -6
- package/scripts/issue/issue-labels.ts +19 -2
- package/scripts/issue/issue-lint-cli.ts +27 -2
- package/scripts/issue/issue-measured-cli.ts +13 -35
- package/scripts/issue/issue-measured-close.ts +58 -0
- package/scripts/issue/issue-not-before-label.ts +2 -2
- package/scripts/issue/issue-not-before.ts +4 -1
- package/scripts/issue/issue-priority-cli.ts +60 -0
- package/scripts/issue/issue-priority-raise.ts +55 -0
- package/scripts/issue/issue-priority.ts +174 -43
- package/scripts/issue/issue-rank.ts +21 -4
- package/scripts/issue/issue-read-cli.ts +32 -6
- package/scripts/issue/issue-read.ts +37 -12
- package/scripts/issue/issue-sample-gate.ts +95 -74
- package/scripts/issue/issue-sample-prime.ts +127 -0
- package/scripts/issue/issue-sample-required.ts +57 -0
- package/scripts/issue/issue-sample-source.ts +12 -11
- package/scripts/issue/issue-search.ts +124 -0
- package/scripts/issue/issue-state.ts +13 -1
- package/scripts/issue/issue-template-section.ts +43 -0
- package/scripts/issue/issue-watch-diff.ts +31 -1
- package/scripts/issue/issue-watch-hook.ts +11 -2
- package/scripts/issue/issue-watch.ts +55 -12
- package/scripts/issue/markdown-section.ts +1 -0
- package/scripts/issue/measure-declaration.ts +121 -0
- package/scripts/issue/measure-rerun-cli.ts +7 -70
- package/scripts/issue/plan-consumers-section.ts +22 -1
- package/scripts/issue/reproduction-measure.ts +3 -1
- package/scripts/issue/size-estimate.ts +90 -0
- package/scripts/issue/trusted-measure.ts +84 -0
- package/scripts/josh/command-usage.ts +3 -2
- package/scripts/josh/durable-state-migrate.ts +105 -0
- package/scripts/josh/durable-state.ts +112 -0
- package/scripts/josh/josh-aliases.ts +95 -0
- package/scripts/josh/josh-command-map.ts +1 -82
- package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
- package/scripts/josh/josh-commands-ai.ts +5 -5
- package/scripts/josh/josh-commands-development.ts +59 -58
- package/scripts/josh/josh-commands-issue-write.ts +23 -4
- package/scripts/josh/josh-commands-issue.ts +32 -0
- package/scripts/josh/josh-commands-lane.ts +87 -4
- package/scripts/josh/josh-commands-lint.ts +16 -3
- package/scripts/josh/josh-commands-maintenance.ts +15 -0
- package/scripts/josh/josh-commands-review.ts +41 -6
- package/scripts/josh/josh-commands-ship.ts +56 -8
- package/scripts/josh/josh-commands-test-check.ts +80 -0
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/josh/josh-environment-file.ts +43 -3
- package/scripts/josh/josh-in-process.ts +2 -2
- package/scripts/josh/josh-logic.ts +5 -3
- package/scripts/josh/josh-run.ts +19 -1
- package/scripts/josh/run-record-path.ts +15 -0
- package/scripts/josh/stamp-file.ts +11 -2
- package/scripts/lane/lane-adopt-cli.ts +98 -0
- package/scripts/lane/lane-adopt.ts +208 -0
- package/scripts/lane/lane-await.ts +5 -8
- package/scripts/lane/lane-baseline.ts +123 -0
- package/scripts/lane/lane-breakdown-cli.ts +64 -0
- package/scripts/lane/lane-breakdown-implement.ts +170 -0
- package/scripts/lane/lane-breakdown-laps.ts +107 -0
- package/scripts/lane/lane-breakdown-pinned.ts +76 -0
- package/scripts/lane/lane-breakdown-text.ts +145 -0
- package/scripts/lane/lane-breakdown.ts +239 -0
- package/scripts/lane/lane-check-stats.ts +29 -8
- package/scripts/lane/lane-child-invocation.ts +9 -2
- package/scripts/lane/lane-child-mark-keys.ts +12 -0
- package/scripts/lane/lane-child-marker.ts +20 -1
- package/scripts/lane/lane-ci-path-stats.ts +73 -0
- package/scripts/lane/lane-claim-stats.ts +84 -0
- package/scripts/lane/lane-close.ts +8 -3
- package/scripts/lane/lane-dispatch-log.ts +3 -3
- package/scripts/lane/lane-dispatch.ts +2 -2
- package/scripts/lane/lane-gap-stats.ts +7 -6
- package/scripts/lane/lane-guard-policy.ts +7 -1
- package/scripts/lane/lane-implement-stats.ts +207 -0
- package/scripts/lane/lane-implement-subagents.ts +90 -0
- package/scripts/lane/lane-investigation-switch.ts +16 -0
- package/scripts/lane/lane-ledger-kind.ts +31 -0
- package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
- package/scripts/lane/lane-ledger-schema.ts +119 -36
- package/scripts/lane/lane-ledger-write.ts +257 -0
- package/scripts/lane/lane-ledger.ts +31 -177
- package/scripts/lane/lane-load.ts +1 -1
- package/scripts/lane/lane-measure-cli.ts +176 -59
- package/scripts/lane/lane-net-read.ts +44 -0
- package/scripts/lane/lane-net-time.ts +212 -0
- package/scripts/lane/lane-open.ts +16 -7
- package/scripts/lane/lane-output.ts +2 -4
- package/scripts/lane/lane-overrun-prompt.ts +147 -0
- package/scripts/lane/lane-overrun.ts +274 -0
- package/scripts/lane/lane-paths.ts +24 -1
- package/scripts/lane/lane-pause-cli.ts +4 -1
- package/scripts/lane/lane-paused-spans.ts +97 -0
- package/scripts/lane/lane-plan-check.ts +207 -0
- package/scripts/lane/lane-plan-cli.ts +41 -0
- package/scripts/lane/lane-plan.ts +144 -0
- package/scripts/lane/lane-registry.ts +14 -1
- package/scripts/lane/lane-relaunch.ts +1 -1
- package/scripts/lane/lane-round-one-stats.ts +51 -0
- package/scripts/lane/lane-sampler.ts +23 -4
- package/scripts/lane/lane-session-action.ts +93 -18
- package/scripts/lane/lane-session-broker.ts +49 -21
- package/scripts/lane/lane-session-reread-main.ts +14 -0
- package/scripts/lane/lane-session-reread.ts +51 -0
- package/scripts/lane/lane-ship-lap-stats.ts +74 -0
- package/scripts/lane/lane-sleep.ts +58 -0
- package/scripts/lane/lane-spent.ts +1 -1
- package/scripts/lane/lane-split-stats.ts +28 -0
- package/scripts/lane/lane-stage-stats.ts +13 -1
- package/scripts/lane/lane-state.ts +41 -9
- package/scripts/lane/lane-stats-tables.ts +58 -0
- package/scripts/lane/lane-stats.ts +21 -5
- package/scripts/lane/lane-stop-stats.ts +51 -19
- package/scripts/lane/lane-tail-stats.ts +32 -0
- package/scripts/lane/lane-transcript-calls.ts +67 -10
- package/scripts/lane/lane-transcript-stats.ts +44 -12
- package/scripts/lane/lane-value-cell.ts +72 -0
- package/scripts/lane/lane-value.ts +118 -0
- package/scripts/lane/lane-withdraw-closed.ts +124 -0
- package/scripts/lane/lane-withdraw.ts +108 -31
- package/scripts/lane/lane-yield.ts +85 -0
- package/scripts/lane/openai-lane-ship.ts +12 -11
- package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
- package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
- package/scripts/lane/openai-lane-supervisor.ts +5 -4
- package/scripts/lib/poll.ts +38 -9
- package/scripts/lib/settled-together.ts +10 -0
- package/scripts/lib/shell-quote.ts +21 -0
- package/scripts/lib/token-shape.ts +111 -0
- package/scripts/lint/eslint-daemon-sources.ts +79 -0
- package/scripts/lint/eslint-daemon.ts +45 -6
- package/scripts/lint/eslint-warm-cli.ts +7 -0
- package/scripts/lint/eslint-warm.ts +66 -0
- package/scripts/lint/import-graph.ts +141 -11
- package/scripts/lint/lint-gate-scope.ts +2 -2
- package/scripts/lint/lint-parallel.ts +54 -6
- package/scripts/lint/lint-related.ts +154 -33
- package/scripts/lint/rename-cli.ts +179 -0
- package/scripts/lint/rename-identifier.ts +192 -0
- package/scripts/lint/type-only-imports.ts +58 -0
- package/scripts/notify/telegram-notify.ts +12 -3
- package/scripts/observations/observation-record.ts +42 -16
- package/scripts/observations/observations-flush.ts +32 -9
- package/scripts/overrides/overrides-check.ts +9 -1
- package/scripts/release/release-approval-prune.ts +7 -1
- package/scripts/repo/required-checks-logic.ts +4 -1
- package/scripts/repo/ruleset-check.ts +4 -3
- package/scripts/report/markdown-shape.ts +28 -0
- package/scripts/report/report-format-reference.ts +15 -1
- package/scripts/report/report-labels.ts +12 -1
- package/scripts/report/report-lint-child-summary.ts +94 -0
- package/scripts/report/report-lint-cli.ts +26 -7
- package/scripts/report/report-lint.ts +2 -20
- package/scripts/review/prose-stale-cli.ts +88 -0
- package/scripts/review/prose-stale-scan.ts +152 -0
- package/scripts/review/review-attest.ts +73 -23
- package/scripts/review/review-brief-cli.ts +68 -19
- package/scripts/review/review-brief-paths.ts +22 -0
- package/scripts/review/review-brief.ts +14 -7
- package/scripts/review/review-comment-carry.ts +47 -0
- package/scripts/review/review-comment-round.ts +85 -22
- package/scripts/review/review-finding-ledger.ts +109 -7
- package/scripts/review/review-finding-text.ts +43 -0
- package/scripts/review/review-interaction.ts +11 -0
- package/scripts/review/review-lane-handover.ts +68 -0
- package/scripts/review/review-lint-cli.ts +57 -0
- package/scripts/review/review-lint-findings.ts +92 -0
- package/scripts/review/review-lint-sections.ts +80 -0
- package/scripts/review/review-lint.ts +221 -0
- package/scripts/review/review-prior-findings.ts +102 -0
- package/scripts/review/review-readers-scan.ts +4 -2
- package/scripts/review/review-record-cli.ts +177 -54
- package/scripts/review/review-record-code-round.ts +55 -0
- package/scripts/review/review-record-comment.ts +60 -0
- package/scripts/review/review-record-interaction.ts +35 -0
- package/scripts/review/review-record-pinned.ts +108 -0
- package/scripts/review/review-record.ts +25 -1
- package/scripts/review/review-reviewed-tree.ts +307 -0
- package/scripts/review/review-round-one-closure.ts +62 -0
- package/scripts/review/review-round-reuse.ts +106 -0
- package/scripts/review/review-round2-cli.ts +91 -29
- package/scripts/review/review-round2-skip-comment.ts +55 -0
- package/scripts/review/review-round2.ts +24 -8
- package/scripts/review/review-stamps.ts +7 -3
- package/scripts/review/review-stop-log.ts +20 -6
- package/scripts/review/review-stops-cli.ts +2 -1
- package/scripts/review/review-submit-cli.ts +101 -0
- package/scripts/rules/agent-model.ts +1 -1
- package/scripts/rules/bash-triggers.ts +3 -3
- package/scripts/rules/concise-reply.ts +88 -0
- package/scripts/rules/credential-body.ts +77 -0
- package/scripts/rules/decision-oracle.ts +1 -1
- package/scripts/rules/delivered-rules.ts +36 -17
- package/scripts/rules/destructive-command.ts +3 -11
- package/scripts/rules/direct-issue-comment.ts +34 -12
- package/scripts/rules/direct-issue-read.ts +191 -0
- package/scripts/rules/direct-pr-create.ts +4 -24
- package/scripts/rules/early-heartbeat.ts +2 -0
- package/scripts/rules/edit-tool.ts +27 -0
- package/scripts/rules/file-edit-rows.ts +17 -0
- package/scripts/rules/file-rewrite.ts +146 -0
- package/scripts/rules/firing-point.ts +3 -2
- package/scripts/rules/gh-api.ts +128 -7
- package/scripts/rules/gh-repo-selector.ts +84 -0
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/guard-remedy.ts +14 -5
- package/scripts/rules/implementation-cut.ts +61 -28
- package/scripts/rules/investigator-foreground.ts +231 -0
- package/scripts/rules/issue-citation.ts +15 -60
- package/scripts/rules/issue-comments.ts +9 -4
- package/scripts/rules/josh-git-bare.ts +1 -1
- package/scripts/rules/lane-background.ts +41 -13
- package/scripts/rules/lane-direct-tool.ts +107 -9
- package/scripts/rules/lane-interactive-ask.ts +4 -1
- package/scripts/rules/lane-park.ts +4 -2
- package/scripts/rules/lane-spilled-read.ts +90 -0
- package/scripts/rules/lane-split-park.ts +1 -1
- package/scripts/rules/lane-switch-main.ts +4 -4
- package/scripts/rules/last-prompt.ts +20 -47
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/permission-guards.ts +5 -1
- package/scripts/rules/piped-verification-shapes.ts +110 -0
- package/scripts/rules/piped-verification.ts +67 -17
- package/scripts/rules/poll-loop.ts +72 -9
- package/scripts/rules/pr-merge.ts +5 -5
- package/scripts/rules/pre-gate-cut.ts +3 -3
- package/scripts/rules/protected-files.ts +88 -24
- package/scripts/rules/reply-language.ts +3 -17
- package/scripts/rules/reply-prose.ts +34 -0
- package/scripts/rules/repo-admin.ts +132 -0
- package/scripts/rules/reviewer-foreground.ts +88 -0
- package/scripts/rules/round-one-check-related.ts +120 -0
- package/scripts/rules/rule-body-guard.ts +5 -15
- package/scripts/rules/rule-value-cache.ts +53 -5
- package/scripts/rules/rule-value-candidates.ts +84 -0
- package/scripts/rules/rule-value-cli.ts +59 -11
- package/scripts/rules/rule-value.ts +17 -4
- package/scripts/rules/run-tail-rule.ts +1 -1
- package/scripts/rules/sed-in-place.ts +196 -0
- package/scripts/rules/shell-segments.ts +10 -2
- package/scripts/rules/stop-rule-rows.ts +1 -13
- package/scripts/rules/stop-rules.ts +33 -58
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +110 -23
- package/scripts/rules/timed-rerun.ts +1 -1
- package/scripts/rules/turn-filings.ts +90 -0
- package/scripts/rules/worktree-guard.ts +22 -7
- package/scripts/run/board/run-board-ending-reason.ts +6 -2
- package/scripts/run/board/run-board-fit.ts +24 -1
- package/scripts/run/board/run-board-found.ts +134 -0
- package/scripts/run/board/run-board-header.ts +8 -0
- package/scripts/run/board/run-board-labels.ts +11 -1
- package/scripts/run/board/run-board-lane-time.ts +1 -0
- package/scripts/run/board/run-board-link.ts +15 -2
- package/scripts/run/board/run-board-notes.ts +7 -1
- package/scripts/run/board/run-board-operation.ts +4 -2
- package/scripts/run/board/run-board-phase.ts +2 -5
- package/scripts/run/board/run-board-plan.ts +1 -1
- package/scripts/run/board/run-board-read.ts +46 -1
- package/scripts/run/board/run-board-reason.ts +20 -8
- package/scripts/run/board/run-board-render-checks.ts +3 -2
- package/scripts/run/board/run-board-render-drawn.ts +11 -0
- package/scripts/run/board/run-board-render-found.ts +157 -0
- package/scripts/run/board/run-board-render-lead.ts +9 -0
- package/scripts/run/board/run-board-render-legend.ts +19 -0
- package/scripts/run/board/run-board-render-tail.ts +1 -1
- package/scripts/run/board/run-board-render.ts +82 -18
- package/scripts/run/board/run-board-spin.ts +1 -3
- package/scripts/run/board/run-board-status.ts +2 -0
- package/scripts/run/board/run-board-tick.ts +39 -10
- package/scripts/run/carry/run-carry-ended.ts +3 -2
- package/scripts/run/carry/run-carry.ts +3 -2
- package/scripts/run/cut/run-cut-cli.ts +33 -133
- package/scripts/run/cut/run-cut-digest.ts +152 -0
- package/scripts/run/cut/run-cut-handoff.ts +52 -8
- package/scripts/run/cut/run-cut-report.ts +24 -3
- package/scripts/run/cut/run-cut-resume.ts +129 -0
- package/scripts/run/cut/run-cut-review.ts +105 -0
- package/scripts/run/cut/run-cut.ts +18 -7
- package/scripts/run/detached-launch.ts +1 -1
- package/scripts/run/entry/run-entry-cli.ts +88 -19
- package/scripts/run/entry/run-entry-spill.ts +83 -0
- package/scripts/run/entry/run-entry-stop.ts +5 -1
- package/scripts/run/entry/run-entry-trust.ts +91 -0
- package/scripts/run/event/run-event-baseline.ts +56 -0
- package/scripts/run/event/run-event-filed.ts +9 -3
- package/scripts/run/event/run-event-overrun.ts +197 -0
- package/scripts/run/event/run-event-render.ts +4 -0
- package/scripts/run/event/run-event-stream.ts +25 -3
- package/scripts/run/hold/run-stop-notify.ts +3 -8
- package/scripts/run/merge/run-merge-cap.ts +57 -0
- package/scripts/run/merge/run-merge-cli.ts +66 -23
- package/scripts/run/merge/run-merge-outcome.ts +2 -0
- package/scripts/run/merge/run-merge-ship.ts +13 -3
- package/scripts/run/merge/run-merge-signals.ts +40 -23
- package/scripts/run/merge/run-merge-steps.ts +56 -36
- package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
- package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
- package/scripts/run/merge/run-merge.ts +41 -14
- package/scripts/run/review/run-review-cli.ts +306 -20
- package/scripts/run/review/run-review-early-push.ts +121 -0
- package/scripts/run/review/run-review-join-read.ts +94 -0
- package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
- package/scripts/run/review/run-review-pinned-join.ts +216 -0
- package/scripts/run/review/run-review-pinned-steps.ts +383 -0
- package/scripts/run/review/run-review-pinned-tree.ts +37 -0
- package/scripts/run/review/run-review-pinned.ts +53 -0
- package/scripts/run/review/run-review-steps.ts +70 -34
- package/scripts/run/review/run-review.ts +26 -6
- package/scripts/run/run-parent-cut-hook.ts +3 -4
- package/scripts/run/run-prep.ts +1 -0
- package/scripts/run/run-stage-read.ts +2 -6
- package/scripts/run/run-step-cli.ts +17 -5
- package/scripts/run/run-step-lane-plan.ts +27 -0
- package/scripts/run/run-step-section.ts +26 -7
- package/scripts/run/run-step.ts +5 -2
- package/scripts/run/ship/run-ship-args.ts +19 -0
- package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
- package/scripts/run/ship/run-ship-cli.ts +131 -39
- package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
- package/scripts/run/ship/run-ship-detach.ts +10 -4
- package/scripts/run/ship/run-ship-handover.ts +106 -0
- package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
- package/scripts/run/ship/run-ship-lap.ts +63 -0
- package/scripts/run/ship/run-ship-next.ts +27 -26
- package/scripts/run/ship/run-ship-overlap.ts +8 -3
- package/scripts/run/ship/run-ship-place.ts +9 -2
- package/scripts/run/ship/run-ship-planned.ts +92 -0
- package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
- package/scripts/run/ship/run-ship-preflight.ts +16 -4
- package/scripts/run/ship/run-ship-probe.ts +23 -9
- package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
- package/scripts/run/ship/run-ship-relaunch.ts +51 -0
- package/scripts/run/ship/run-ship-return.ts +103 -29
- package/scripts/run/ship/run-ship-review-reason.ts +24 -0
- package/scripts/run/ship/run-ship-review-steps.ts +230 -59
- package/scripts/run/ship/run-ship-review.ts +171 -51
- package/scripts/run/ship/run-ship-reviewer.ts +138 -42
- package/scripts/run/ship/run-ship-scoped.ts +39 -10
- package/scripts/run/ship/run-ship-stage.ts +49 -13
- package/scripts/run/ship/run-ship-steps.ts +24 -4
- package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
- package/scripts/run/ship/run-ship-stop-context.ts +50 -13
- package/scripts/run/ship/run-ship-sync.ts +171 -30
- package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
- package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
- package/scripts/run/ship/run-ship-waiter.ts +114 -0
- package/scripts/run/ship/run-ship.ts +16 -2
- package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
- package/scripts/run/wake/run-wake-cli.ts +6 -113
- package/scripts/run/wake/run-wake-code.ts +53 -11
- package/scripts/run/wake/run-wake-driver.ts +5 -3
- package/scripts/run/wake/run-wake-finish.ts +137 -0
- package/scripts/run/wake/run-wake-loop.ts +5 -3
- package/scripts/run/wake/run-wake-ports.ts +11 -3
- package/scripts/run/wake/run-wake-session.ts +2 -0
- package/scripts/run/wake/run-wake.ts +3 -2
- package/scripts/safe-chain/ci-installer-pin.ts +49 -8
- package/scripts/safe-chain/project-config.ts +3 -2
- package/scripts/security/secretlint-scan.ts +42 -9
- package/scripts/security/security-audit-provision-main.ts +9 -1
- package/scripts/security/security-audit-provision.ts +1 -1
- package/scripts/security/security-audit.ts +21 -1
- package/scripts/security/sonar-file.ts +10 -5
- package/scripts/split/split-assess.ts +12 -3
- package/scripts/split/split-early-notice.ts +116 -0
- package/scripts/split/split-measure.ts +20 -2
- package/scripts/split/split-resolution.ts +107 -0
- package/scripts/test/direct-importers.ts +185 -0
- package/scripts/test/pure-files-entries.ts +83 -0
- package/scripts/test/related-heavy-tests.ts +81 -0
- package/scripts/test/test-no-base.ts +88 -0
- package/scripts/test/test-pinned-cache-logic.ts +363 -0
- package/scripts/test/test-pinned-cache.ts +337 -0
- package/scripts/test/test-pinned-emit.ts +49 -0
- package/scripts/test/test-pinned-functions.ts +116 -0
- package/scripts/test/test-pinned-ledger.ts +80 -0
- package/scripts/test/test-pinned-logic.ts +208 -20
- package/scripts/test/test-pinned-main.ts +84 -18
- package/scripts/test/test-pinned-pool.ts +73 -0
- package/scripts/test/test-pinned-probe.ts +254 -0
- package/scripts/test/test-pinned-prune-logic.ts +118 -0
- package/scripts/test/test-pinned-reach.ts +194 -0
- package/scripts/test/test-pinned-record.ts +196 -0
- package/scripts/test/test-pinned-rewire.ts +148 -0
- package/scripts/test/test-pinned-spawn.ts +81 -0
- package/scripts/test/test-pinned-stage.ts +70 -0
- package/scripts/test/test-pinned.ts +258 -47
- package/scripts/test/test-reach-cli.ts +61 -0
- package/scripts/test/test-read-map.ts +35 -11
- package/scripts/test/test-read-recording.ts +17 -5
- package/scripts/test/test-read-trace.ts +26 -8
- package/scripts/test/test-red-logic.ts +46 -7
- package/scripts/test/test-red.ts +34 -14
- package/scripts/test/test-related-claim.ts +37 -0
- package/scripts/test/test-related-main.ts +4 -1
- package/scripts/test/test-related-moved.ts +91 -0
- package/scripts/test/test-related-record.ts +43 -23
- package/scripts/test/test-related-scope.ts +99 -34
- package/scripts/test/test-related-synced.ts +135 -0
- package/scripts/test/test-related-touched.ts +84 -0
- package/scripts/test/test-related.ts +167 -83
- package/scripts/test/test-unit-guard.ts +28 -5
- package/scripts/test/unit-durations.ts +41 -0
- package/scripts/test/unit-worker-share.ts +5 -4
- package/scripts/test/vitest-cache-directory.ts +19 -0
- package/scripts/test/vitest-cli-excludes.ts +14 -0
- package/scripts/test/vitest-failure-summary.ts +111 -0
- package/scripts/test/whole-suite-files.ts +12 -1
- package/scripts/time-runtime/time-batch-guard.ts +42 -4
- package/scripts/time-runtime/time-bundle-call.ts +1 -1
- package/scripts/time-runtime/time-bundles.ts +36 -5
- package/scripts/time-runtime/time-markers.ts +2 -2
- package/scripts/time-runtime/time-search-call.ts +38 -0
- package/scripts/time-runtime/time-shell.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +17 -5
- package/scripts/version/development-engines-verdict.ts +124 -0
- package/scripts/version/latest-corepack.ts +2 -0
- package/templates/gitignore +2 -0
- package/templates/workflows/ci.yml +41 -0
- package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
- package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
- package/dist/hooks/chunk-TUIFS5E7.js +0 -72
- package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
- package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
- package/scripts/rules/filing-cap.ts +0 -139
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { lane_net_read } from '#scripts/lane/lane-net-read'
|
|
2
|
+
import { issue_cite } from './issue-cite'
|
|
3
|
+
import { issue_priority } from './issue-priority'
|
|
4
|
+
|
|
5
|
+
// joshuafolkken/kit#5225: a refused `josh issue:file --found-during <N>` prints the causing-lane line
|
|
6
|
+
// filled from `josh lane:net <N>`, so the filer pastes it rather than running the command apart. Nothing
|
|
7
|
+
// is printed when the body already declares a causing lane, or the ledger holds no dispatch and merge of
|
|
8
|
+
// the lane yet.
|
|
9
|
+
|
|
10
|
+
async function lines_of(
|
|
11
|
+
found_during: string | undefined,
|
|
12
|
+
body: string,
|
|
13
|
+
): Promise<ReadonlyArray<string>> {
|
|
14
|
+
if (found_during === undefined || issue_priority.lane_minutes(body) > 0) return []
|
|
15
|
+
const minutes = await lane_net_read.net_minutes_of(Number(found_during))
|
|
16
|
+
|
|
17
|
+
if (minutes === undefined) return []
|
|
18
|
+
const line = `${issue_priority.LANE_PREFIX} ${String(minutes)} 分(${issue_cite.plain(found_during)})`
|
|
19
|
+
|
|
20
|
+
return [
|
|
21
|
+
`↳ the causing lane from \`josh lane:net ${found_during}\`, to paste under \`## 背景\` when it caused this Issue:`,
|
|
22
|
+
line,
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const issue_file_lane_hint = {
|
|
27
|
+
lines_of,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { issue_file_lane_hint }
|
|
@@ -36,6 +36,10 @@ interface FileArguments {
|
|
|
36
36
|
labels: ReadonlyArray<string>
|
|
37
37
|
repo: string | undefined
|
|
38
38
|
distinct: ReadonlyArray<number>
|
|
39
|
+
// `--found-during <N>`: the work item the filing came from when it is not the checkout's own — a
|
|
40
|
+
// long lane the parent investigated, the Issue a prerequisite or an observation came out of. The
|
|
41
|
+
// filing cap counts per origin (`issue-file-cap.ts`); absent, the finder is read (`issue-file-fold.ts`).
|
|
42
|
+
found_during: string | undefined
|
|
39
43
|
// `--over-cap`: the run is blocked by this filing, so the WIP cap does not hold it (`issue-wip.ts`).
|
|
40
44
|
is_over_cap: boolean
|
|
41
45
|
// `--no-auto-ok`: the Issue needs a person's judgement, so `auto-ok` is not applied (`issue-auto-ok.ts`).
|
|
@@ -43,6 +47,9 @@ interface FileArguments {
|
|
|
43
47
|
// `--release`: the change reaches a consumer only once published, so the Issue is linked to the
|
|
44
48
|
// repository's release Issue as a blocker (`issue-release-cli.ts`).
|
|
45
49
|
is_release: boolean
|
|
50
|
+
// `--blocks-finder`: an interrupt the finder cannot go on without, so the finder is recorded as
|
|
51
|
+
// blocked by it (`issue-file-interrupt.ts`). An interrupt that blocks nobody omits it (`wip-cap.md`).
|
|
52
|
+
is_blocking_finder: boolean
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
const OPTIONS = {
|
|
@@ -51,9 +58,11 @@ const OPTIONS = {
|
|
|
51
58
|
label: { type: 'string', multiple: true },
|
|
52
59
|
repo: { type: 'string' },
|
|
53
60
|
distinct: { type: 'string', multiple: true },
|
|
61
|
+
'found-during': { type: 'string' },
|
|
54
62
|
'over-cap': { type: 'boolean' },
|
|
55
63
|
'no-auto-ok': { type: 'boolean' },
|
|
56
64
|
release: { type: 'boolean' },
|
|
65
|
+
'blocks-finder': { type: 'boolean' },
|
|
57
66
|
} as const
|
|
58
67
|
|
|
59
68
|
// The label a `--route` value names, or `undefined` when it names none — read against the route
|
|
@@ -95,15 +104,27 @@ function has_text(value: string | undefined): value is string {
|
|
|
95
104
|
return value !== undefined && value.trim() !== ''
|
|
96
105
|
}
|
|
97
106
|
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
function
|
|
107
|
+
// `--found-during 3423` or `#3423` → `'3423'`; `undefined` when absent, `false` when it names no single
|
|
108
|
+
// issue number, so a typo is refused rather than counted against no origin.
|
|
109
|
+
function found_during_of(value: string | undefined): string | undefined | false {
|
|
110
|
+
if (value === undefined) return undefined
|
|
111
|
+
const numbers = distinct_numbers([value])
|
|
112
|
+
|
|
113
|
+
return numbers?.length === 1 ? String(numbers[0]) : false
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
type Labelled = Pick<FileArguments, 'route' | 'distinct' | 'found_during'>
|
|
117
|
+
|
|
118
|
+
// The labelled half of the arguments, or `undefined` when a route, `--distinct` or `--found-during`
|
|
119
|
+
// entry is not one the command knows.
|
|
120
|
+
function labelled_of(values: ParsedValues): Labelled | undefined {
|
|
101
121
|
const route = route_of(values)
|
|
102
122
|
const distinct = distinct_numbers(values.distinct ?? [])
|
|
123
|
+
const found_during = found_during_of(values['found-during'])
|
|
103
124
|
|
|
104
|
-
if (route === false || distinct === undefined) return undefined
|
|
125
|
+
if (route === false || distinct === undefined || found_during === false) return undefined
|
|
105
126
|
|
|
106
|
-
return { route, distinct }
|
|
127
|
+
return { route, distinct, found_during }
|
|
107
128
|
}
|
|
108
129
|
|
|
109
130
|
function arguments_of(values: ParsedValues, title: string | undefined): FileArguments | undefined {
|
|
@@ -121,6 +142,7 @@ function arguments_of(values: ParsedValues, title: string | undefined): FileArgu
|
|
|
121
142
|
is_over_cap: values['over-cap'] === true,
|
|
122
143
|
is_auto_ok_opted_out: values['no-auto-ok'] === true,
|
|
123
144
|
is_release: values.release === true,
|
|
145
|
+
is_blocking_finder: values['blocks-finder'] === true,
|
|
124
146
|
}
|
|
125
147
|
}
|
|
126
148
|
|
|
@@ -143,7 +165,7 @@ function is_undeclared_classification(label: string, body: string): boolean {
|
|
|
143
165
|
// the body declares (`issue_classification.labels_for`, which merges case-insensitively), then any
|
|
144
166
|
// extra `--label`, then `auto-ok` when the filing is judged in (`issue-auto-ok.ts`) and no `--label`
|
|
145
167
|
// already named it, `not-before` while the body's start time is ahead (`issue-not-before-label.ts`), and
|
|
146
|
-
// the
|
|
168
|
+
// the filed priority's label (the declaration, else its floor) unless a `--label` typed one (`issue-priority.ts`).
|
|
147
169
|
// One request applies them all, so no label is a separate step to forget.
|
|
148
170
|
function labels_of(args: FileArguments, body: string, is_auto_ok = false): ReadonlyArray<string> {
|
|
149
171
|
const extra = args.labels.filter((label) => !is_undeclared_classification(label, body))
|
|
@@ -221,12 +243,27 @@ function unacknowledged(
|
|
|
221
243
|
return candidates.filter((candidate) => !distinct.includes(candidate))
|
|
222
244
|
}
|
|
223
245
|
|
|
246
|
+
// The candidates the filing has already answered: its `--distinct` numbers and, filing into this
|
|
247
|
+
// repository, its `--found-during` origin. The work the finding turned up during is never its duplicate,
|
|
248
|
+
// though a body citing it makes the scout name it (joshuafolkken/kit#4762). The origin is an Issue here,
|
|
249
|
+
// so in another repository the same number is an unrelated Issue the scout may rightly hold.
|
|
250
|
+
function acknowledged(
|
|
251
|
+
args: Pick<FileArguments, 'distinct' | 'found_during'>,
|
|
252
|
+
target: string,
|
|
253
|
+
current: string,
|
|
254
|
+
): ReadonlyArray<number> {
|
|
255
|
+
if (args.found_during === undefined || !is_same_repository(target, current)) return args.distinct
|
|
256
|
+
|
|
257
|
+
return [...args.distinct, Number(args.found_during)]
|
|
258
|
+
}
|
|
259
|
+
|
|
224
260
|
const issue_file = {
|
|
225
261
|
parse,
|
|
226
262
|
labels_of,
|
|
227
263
|
origin_problem,
|
|
228
264
|
triage_problem,
|
|
229
265
|
unacknowledged,
|
|
266
|
+
acknowledged,
|
|
230
267
|
is_same_repository,
|
|
231
268
|
}
|
|
232
269
|
|
|
@@ -83,6 +83,9 @@ const ALREADY_DONE_LABEL = 'already-done'
|
|
|
83
83
|
// closes such an Issue, so the merge reference a sweep reads is missing; this label is what tells the
|
|
84
84
|
// run's own close from a person's, so every sweep counts it as merged (`issue-merged.ts`).
|
|
85
85
|
const MEASURED_LABEL = 'measured'
|
|
86
|
+
// Rides beside `measured` when the measurement fell short of the expected effect it checked
|
|
87
|
+
// (`josh issue:measured --unmet`); `josh effect:audit` reads it as the mechanism to retire or shrink.
|
|
88
|
+
const MEASURED_UNMET_LABEL = 'measured:unmet'
|
|
86
89
|
// Marks the Issue that tracks a repository's next release. An Issue whose
|
|
87
90
|
// change reaches a consumer only once published is linked to it as a `blocked_by` blocker
|
|
88
91
|
// (`josh issue:release`), so "merged but not yet released" is visible in the backlog. A run applies
|
|
@@ -255,6 +258,12 @@ const WORKFLOW_LABELS: ReadonlyArray<LabelDefinition> = [
|
|
|
255
258
|
color: '6f42c1',
|
|
256
259
|
description: 'Measurement-only — a run recorded the result and closed it',
|
|
257
260
|
},
|
|
261
|
+
{
|
|
262
|
+
name: MEASURED_UNMET_LABEL,
|
|
263
|
+
color: '6f42c1',
|
|
264
|
+
description:
|
|
265
|
+
'The measurement fell short of the expected effect — retire or shrink the mechanism',
|
|
266
|
+
},
|
|
258
267
|
{
|
|
259
268
|
name: DEFERRED_LABEL,
|
|
260
269
|
color: 'd4c5f9',
|
|
@@ -345,9 +354,14 @@ function has_label_name(labels: ReadonlyArray<string>, wanted: string): boolean
|
|
|
345
354
|
return label_name_of(labels, wanted) !== undefined
|
|
346
355
|
}
|
|
347
356
|
|
|
348
|
-
//
|
|
357
|
+
// The park label (`PARKED_LABELS`) label names carry, compared as `has_label_name` does.
|
|
358
|
+
function parked_label_of(labels: ReadonlyArray<string>): string | undefined {
|
|
359
|
+
return [...PARKED_LABELS].find((label) => has_label_name(labels, label))
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Whether label names carry any park label (`PARKED_LABELS`).
|
|
349
363
|
function has_parked_label(labels: ReadonlyArray<string>): boolean {
|
|
350
|
-
return
|
|
364
|
+
return parked_label_of(labels) !== undefined
|
|
351
365
|
}
|
|
352
366
|
|
|
353
367
|
// Every workflow label this package manages. The label-reference scan
|
|
@@ -368,6 +382,7 @@ const ALL_LABELS: ReadonlySet<string> = new Set([
|
|
|
368
382
|
NEEDS_HUMAN_REVIEW_LABEL,
|
|
369
383
|
ALREADY_DONE_LABEL,
|
|
370
384
|
MEASURED_LABEL,
|
|
385
|
+
MEASURED_UNMET_LABEL,
|
|
371
386
|
DEFERRED_LABEL,
|
|
372
387
|
PRIORITY_CRITICAL_LABEL,
|
|
373
388
|
PRIORITY_HIGH_LABEL,
|
|
@@ -410,11 +425,13 @@ export {
|
|
|
410
425
|
INTERRUPT_ROUTE_LABEL,
|
|
411
426
|
label_name_of,
|
|
412
427
|
MEASURED_LABEL,
|
|
428
|
+
MEASURED_UNMET_LABEL,
|
|
413
429
|
NEEDS_DECISION_LABEL,
|
|
414
430
|
NEEDS_HUMAN_REVIEW_LABEL,
|
|
415
431
|
NOT_BEFORE_LABEL,
|
|
416
432
|
NOT_DIRECTLY_RUNNABLE_LABELS,
|
|
417
433
|
OTHER_CHANGE_LABEL,
|
|
434
|
+
parked_label_of,
|
|
418
435
|
PARKED_LABELS,
|
|
419
436
|
PLANNED_LABEL,
|
|
420
437
|
PRIORITY_CRITICAL_LABEL,
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises'
|
|
2
|
+
import { aggregation_split } from './aggregation-split'
|
|
2
3
|
import { behavior_change_lint } from './behavior-change-lint'
|
|
3
4
|
import { expected_effect_lint } from './expected-effect-lint'
|
|
4
5
|
import { issue_classification } from './issue-classification'
|
|
5
6
|
import { issue_lint } from './issue-lint'
|
|
6
7
|
import { issue_not_before } from './issue-not-before'
|
|
8
|
+
import { issue_priority } from './issue-priority'
|
|
9
|
+
import { issue_template_section } from './issue-template-section'
|
|
10
|
+
import { measure_declaration } from './measure-declaration'
|
|
11
|
+
import { size_estimate } from './size-estimate'
|
|
7
12
|
|
|
8
13
|
// `josh issue:lint <path>` — read an Issue body from a file and print `ok`, or every template problem
|
|
9
14
|
// one per line, exiting non-zero. It reads a path rather than stdin so it can
|
|
10
15
|
// lint a body written to a file before the `gh api … issues` call that files it. A body that declares
|
|
11
16
|
// itself a behavior-change Issue is additionally held to the firing-point, baseline and reproduction
|
|
12
|
-
// rules, and one that declares a run-time-shortening aim to the expected-effect estimate.
|
|
17
|
+
// rules, and one that declares a run-time-shortening aim to the expected-effect estimate. Every
|
|
18
|
+
// non-epic body declares its size estimate; the guide it is judged against is `issue:file`'s check.
|
|
13
19
|
|
|
14
20
|
const SUCCESS_EXIT_CODE = 0
|
|
15
21
|
const FAILURE_EXIT_CODE = 1
|
|
@@ -17,10 +23,23 @@ const OK_MESSAGE = 'ok'
|
|
|
17
23
|
const NO_LABELS = 'none'
|
|
18
24
|
const USAGE = 'Usage: josh issue:lint <path-to-issue-body>'
|
|
19
25
|
|
|
26
|
+
const MISSING_HEADING_PREFIX = 'missing heading: '
|
|
27
|
+
|
|
28
|
+
// A missing-heading problem followed by that section of the template, so the filer pastes it in rather
|
|
29
|
+
// than reopening `issue-template.md`; any other problem, or a heading the template lacks, is unchanged.
|
|
30
|
+
function with_template(problem: string): string {
|
|
31
|
+
if (!problem.startsWith(MISSING_HEADING_PREFIX)) return problem
|
|
32
|
+
const template = issue_template_section.section(problem.slice(MISSING_HEADING_PREFIX.length))
|
|
33
|
+
|
|
34
|
+
return template === undefined ? problem : `${problem}\n${template}`
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
// Every problem a body has: the four base template headings it lacks, then the behavior-change and
|
|
21
38
|
// expected-effect problems (each empty for an Issue that does not declare itself one).
|
|
22
39
|
function problems(body: string): ReadonlyArray<string> {
|
|
23
|
-
const missing = issue_lint
|
|
40
|
+
const missing = issue_lint
|
|
41
|
+
.missing_headings(body)
|
|
42
|
+
.map((heading) => `${MISSING_HEADING_PREFIX}${heading}`)
|
|
24
43
|
|
|
25
44
|
return [
|
|
26
45
|
...missing,
|
|
@@ -28,7 +47,13 @@ function problems(body: string): ReadonlyArray<string> {
|
|
|
28
47
|
...expected_effect_lint.problems(body),
|
|
29
48
|
...issue_classification.problems(body),
|
|
30
49
|
...issue_not_before.problems(body),
|
|
50
|
+
...measure_declaration.problems(body),
|
|
51
|
+
...size_estimate.problems(body),
|
|
52
|
+
...aggregation_split.problems(body),
|
|
53
|
+
issue_priority.order_problem(body),
|
|
31
54
|
]
|
|
55
|
+
.filter((problem) => problem !== undefined)
|
|
56
|
+
.map((problem) => with_template(problem))
|
|
32
57
|
}
|
|
33
58
|
|
|
34
59
|
function report(found: ReadonlyArray<string>, body: string): number {
|
|
@@ -1,48 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import { epic_close } from '#scripts/epic/epic-close'
|
|
4
|
-
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
5
3
|
import { issue_evidence_exit } from '#scripts/issue/issue-evidence-exit'
|
|
6
|
-
import {
|
|
7
|
-
import { session_cite } from '#scripts/issue/session-cite'
|
|
4
|
+
import { issue_measured_close } from '#scripts/issue/issue-measured-close'
|
|
8
5
|
|
|
9
6
|
// `josh issue:measured <N> --evidence-file <path>` — the completion of a measurement-only Issue
|
|
10
7
|
// (`issue-comments.md` → "A measurement-only Issue"): the result comment, the
|
|
11
|
-
// `measured` label, the close and the `run:release`, in that order (`issue-evidence-exit.ts
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// can close it, and an OPEN child `run:merge` reads as `failed` and parks with `run:stalled`. A
|
|
15
|
-
// CLOSED one it reads as `merged` (`run-merge.ts` → `classify_child`). The label goes on before the
|
|
16
|
-
// close because it is what every sweep — `run:carry --end`, `run:tidy` — tells this close from a
|
|
17
|
-
// person's by (`issue-merged.ts`); a close without it would be one they never count as merged.
|
|
8
|
+
// `measured` label, the close and the `run:release`, in that order (`issue-evidence-exit.ts`,
|
|
9
|
+
// `issue-measured-close.ts`). `--unmet` records that the measurement fell short of the expected
|
|
10
|
+
// effect, with the `measured:unmet` label `josh effect:audit` reads.
|
|
18
11
|
|
|
19
12
|
const ARGV_OFFSET = 2
|
|
20
|
-
|
|
21
|
-
async function apply_label(issue_number: string): Promise<boolean> {
|
|
22
|
-
const write = await git_gh_command.issue_apply_label(issue_number, MEASURED_LABEL)
|
|
23
|
-
|
|
24
|
-
if (!write.is_applied) console.error(`${MEASURED_LABEL} not applied: ${write.reason}`)
|
|
25
|
-
|
|
26
|
-
return write.is_applied
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// A closed measurement may be its epic's last child, and no `followup` runs for it — so the epic
|
|
30
|
-
// auto-close is run here, through the one entry every child close takes (`epic-close.ts`).
|
|
31
|
-
async function close_issue(issue_number: string): Promise<boolean> {
|
|
32
|
-
const is_closed = await git_gh_command.issue_close(issue_number, undefined)
|
|
33
|
-
|
|
34
|
-
if (is_closed) await epic_close.close_completed_epics({ issue_number, is_merged: true })
|
|
35
|
-
else console.error(`Issue ${session_cite.issue(issue_number)} not closed`)
|
|
36
|
-
|
|
37
|
-
return is_closed
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function label_and_close(issue_number: string): Promise<boolean> {
|
|
41
|
-
return (await apply_label(issue_number)) && (await close_issue(issue_number))
|
|
42
|
-
}
|
|
13
|
+
const UNMET_FLAG = '--unmet'
|
|
43
14
|
|
|
44
15
|
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
45
|
-
|
|
16
|
+
const exit = argv.includes(UNMET_FLAG)
|
|
17
|
+
? issue_measured_close.MEASURED_UNMET_EXIT
|
|
18
|
+
: issue_measured_close.MEASURED_EXIT
|
|
19
|
+
|
|
20
|
+
return await issue_evidence_exit.run(
|
|
21
|
+
argv.filter((argument) => argument !== UNMET_FLAG),
|
|
22
|
+
exit,
|
|
23
|
+
)
|
|
46
24
|
}
|
|
47
25
|
|
|
48
26
|
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { epic_close } from '#scripts/epic/epic-close'
|
|
2
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
3
|
+
import { issue_evidence_exit, type EvidenceExit } from '#scripts/issue/issue-evidence-exit'
|
|
4
|
+
import { MEASURED_LABEL, MEASURED_UNMET_LABEL } from '#scripts/issue/issue-labels'
|
|
5
|
+
import { session_cite } from '#scripts/issue/session-cite'
|
|
6
|
+
|
|
7
|
+
// The writes that complete a measurement-only Issue — the result comment, the `measured` label and
|
|
8
|
+
// the close — shared by `josh issue:measured` and `backlog:drive`'s declared measurement
|
|
9
|
+
// (`backlog-measure-close.ts`), out of the CLI so the drive imports no main guard.
|
|
10
|
+
//
|
|
11
|
+
// **The close is the run's own**: such an Issue changes no code, so no pull request's `closes #N`
|
|
12
|
+
// can close it, and an OPEN child `run:merge` reads as `failed` and parks with `run:stalled`. A
|
|
13
|
+
// CLOSED one it reads as `merged` (`run-merge.ts` → `classify_child`). The label goes on before the
|
|
14
|
+
// close because it is what every sweep — `run:carry --end`, `run:tidy` — tells this close from a
|
|
15
|
+
// person's by (`issue-merged.ts`); a close without it would be one they never count as merged.
|
|
16
|
+
|
|
17
|
+
async function apply_label(issue_number: string, label: string = MEASURED_LABEL): Promise<boolean> {
|
|
18
|
+
const write = await git_gh_command.issue_apply_label(issue_number, label)
|
|
19
|
+
|
|
20
|
+
if (!write.is_applied) console.error(`${label} not applied: ${write.reason}`)
|
|
21
|
+
|
|
22
|
+
return write.is_applied
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// A closed measurement may be its epic's last child, and no `followup` runs for it — so the epic
|
|
26
|
+
// auto-close is run here, through the one entry every child close takes (`epic-close.ts`).
|
|
27
|
+
async function close_issue(issue_number: string): Promise<boolean> {
|
|
28
|
+
const is_closed = await git_gh_command.issue_close(issue_number, undefined)
|
|
29
|
+
|
|
30
|
+
if (is_closed) await epic_close.close_completed_epics({ issue_number, is_merged: true })
|
|
31
|
+
else console.error(`Issue ${session_cite.issue(issue_number)} not closed`)
|
|
32
|
+
|
|
33
|
+
return is_closed
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function label_and_close(issue_number: string): Promise<boolean> {
|
|
37
|
+
return (await apply_label(issue_number)) && (await close_issue(issue_number))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// A measurement that fell short carries `measured:unmet` too, put on first: the close is the last write.
|
|
41
|
+
async function mark_unmet_and_close(issue_number: string): Promise<boolean> {
|
|
42
|
+
return (
|
|
43
|
+
(await apply_label(issue_number, MEASURED_UNMET_LABEL)) && (await label_and_close(issue_number))
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const COMMAND = 'issue:measured'
|
|
48
|
+
const MEASURED_EXIT: EvidenceExit = { command: COMMAND, finish: label_and_close }
|
|
49
|
+
const MEASURED_UNMET_EXIT: EvidenceExit = { command: COMMAND, finish: mark_unmet_and_close }
|
|
50
|
+
|
|
51
|
+
// The same writes for evidence composed in process, with no hold of its own to release.
|
|
52
|
+
async function close(issue_number: string, evidence: string): Promise<boolean> {
|
|
53
|
+
return await issue_evidence_exit.write({ issue_number, evidence }, MEASURED_EXIT)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const issue_measured_close = { MEASURED_EXIT, MEASURED_UNMET_EXIT, close }
|
|
57
|
+
|
|
58
|
+
export { issue_measured_close }
|
|
@@ -5,7 +5,7 @@ import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
|
|
|
5
5
|
import { error_text } from '#scripts/lib/error-message'
|
|
6
6
|
import { has_label_name, NOT_BEFORE_LABEL, REPOSITORY_LABELS } from './issue-labels'
|
|
7
7
|
import { issue_not_before } from './issue-not-before'
|
|
8
|
-
import {
|
|
8
|
+
import { issue_sample_prime } from './issue-sample-prime'
|
|
9
9
|
import { session_cite } from './session-cite'
|
|
10
10
|
|
|
11
11
|
// joshuafolkken/kit#4079: the body's start-time declaration held an issue back from `backlog:next`,
|
|
@@ -126,7 +126,7 @@ async function sweep(
|
|
|
126
126
|
const seen = new Set(scanned.map((issue) => issue.number))
|
|
127
127
|
const labelled = await read_labelled()
|
|
128
128
|
|
|
129
|
-
await
|
|
129
|
+
await issue_sample_prime.prime(labelled.map((issue) => issue.body))
|
|
130
130
|
await sync([...scanned, ...labelled.filter((issue) => !seen.has(issue.number))], now)
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -13,7 +13,10 @@ const PREFIX = '- 実施可能日:'
|
|
|
13
13
|
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}Z$/u
|
|
14
14
|
// What `toISOString` writes after the minutes the declaration spells.
|
|
15
15
|
const ISO_TAIL = ':00.000Z'
|
|
16
|
-
|
|
16
|
+
// The refusal ends in a line ready to paste (joshuafolkken/kit#5225); a far-future date, so the
|
|
17
|
+
// example never reads as already due.
|
|
18
|
+
const EXAMPLE = `${PREFIX} 2099-01-01T09:00Z`
|
|
19
|
+
const MALFORMED = `\`${PREFIX}\` must be a UTC time written YYYY-MM-DDTHH:MMZ\n${EXAMPLE}`
|
|
17
20
|
const HEADING_MARKS = /^#{1,6}\s+/u
|
|
18
21
|
// joshuafolkken/kit#4438: a start condition written as its own heading is never read — every reader
|
|
19
22
|
// sees only the declaration line under the background heading — so the issue is offered at once.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
4
|
+
import { session_cite } from '#scripts/issue/session-cite'
|
|
5
|
+
import { issue_priority_raise, type RaiseResult } from './issue-priority-raise'
|
|
6
|
+
|
|
7
|
+
// `josh issue:priority <N>` — apply `priority:high` to an open issue whose body reached the high
|
|
8
|
+
// floor after filing, as a recurrence's appended cause-loss line does (joshuafolkken/kit#4960).
|
|
9
|
+
|
|
10
|
+
const SUCCESS_EXIT_CODE = 0
|
|
11
|
+
const FAILURE_EXIT_CODE = 1
|
|
12
|
+
const ARGV_OFFSET = 2
|
|
13
|
+
const USAGE = 'Usage: josh issue:priority <issue-number>'
|
|
14
|
+
|
|
15
|
+
const REPORTS: Readonly<Record<RaiseResult, string>> = {
|
|
16
|
+
raised: 'applied `priority:high` — its body reaches the high floor.',
|
|
17
|
+
labelled: 'already carries a priority label — left as it is.',
|
|
18
|
+
below: 'stays below the high floor — no label applied.',
|
|
19
|
+
unreadable: 'could not be read — no label applied.',
|
|
20
|
+
failed: 'reaches the high floor, but applying `priority:high` failed.',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const FAILURES: ReadonlySet<RaiseResult> = new Set(['unreadable', 'failed'])
|
|
24
|
+
|
|
25
|
+
function parse_number(argv: ReadonlyArray<string>): string | undefined {
|
|
26
|
+
const [first] = argv
|
|
27
|
+
|
|
28
|
+
if (first === undefined || argv.length !== 1) return undefined
|
|
29
|
+
|
|
30
|
+
return issue_number_shape.ISSUE_NUMBER_PATTERN.test(first) ? first : undefined
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
34
|
+
const issue_number = parse_number(argv)
|
|
35
|
+
|
|
36
|
+
if (issue_number === undefined) {
|
|
37
|
+
console.error(USAGE)
|
|
38
|
+
|
|
39
|
+
return FAILURE_EXIT_CODE
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const result = await issue_priority_raise.raise(issue_number)
|
|
43
|
+
const line = `Issue ${session_cite.issue(issue_number)} ${REPORTS[result]}`
|
|
44
|
+
const is_failure = FAILURES.has(result)
|
|
45
|
+
|
|
46
|
+
if (is_failure) console.error(line)
|
|
47
|
+
else console.info(line)
|
|
48
|
+
|
|
49
|
+
return is_failure ? FAILURE_EXIT_CODE : SUCCESS_EXIT_CODE
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
53
|
+
process.exitCode = await run(argv)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const issue_priority_cli = { run }
|
|
57
|
+
|
|
58
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
59
|
+
|
|
60
|
+
export { issue_priority_cli }
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
2
|
+
import { issue_label_schema } from '#scripts/git/git-schemas'
|
|
3
|
+
import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
|
|
4
|
+
import { z } from 'zod'
|
|
5
|
+
import { PRIORITY_HIGH_LABEL } from './issue-labels'
|
|
6
|
+
import { issue_priority } from './issue-priority'
|
|
7
|
+
|
|
8
|
+
// joshuafolkken/kit#4960: an open Issue's body can reach the high floor after it was filed — a
|
|
9
|
+
// recurrence appends a cause-loss line to it — and the body edit applies no label. This re-reads the
|
|
10
|
+
// body and applies `priority:high` once its floor is high, as `josh issue:file` would have.
|
|
11
|
+
|
|
12
|
+
type RaiseResult = 'raised' | 'labelled' | 'below' | 'unreadable' | 'failed'
|
|
13
|
+
|
|
14
|
+
const read_schema = z.object({
|
|
15
|
+
labels: z.array(issue_label_schema).optional(),
|
|
16
|
+
body: z.string().nullish(),
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
interface LabelsAndBody {
|
|
20
|
+
labels: ReadonlyArray<string>
|
|
21
|
+
body: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function read_issue(issue_number: string): Promise<LabelsAndBody | undefined> {
|
|
25
|
+
const raw = await git_gh_command.issue_get_labels_and_body(issue_number)
|
|
26
|
+
const parsed = raw === undefined ? undefined : parse_json_object_or_undefined(raw, read_schema)
|
|
27
|
+
|
|
28
|
+
if (parsed === undefined) return undefined
|
|
29
|
+
|
|
30
|
+
return { labels: (parsed.labels ?? []).map((label) => label.name), body: parsed.body ?? '' }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// A priority label already on the issue wins, as a typed one does at filing.
|
|
34
|
+
function decision(read: LabelsAndBody): RaiseResult | undefined {
|
|
35
|
+
if (issue_priority.is_typed(read.labels)) return 'labelled'
|
|
36
|
+
|
|
37
|
+
return issue_priority.floor_of(read.body) === 'high' ? undefined : 'below'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function raise(issue_number: string): Promise<RaiseResult> {
|
|
41
|
+
const read = await read_issue(issue_number)
|
|
42
|
+
|
|
43
|
+
if (read === undefined) return 'unreadable'
|
|
44
|
+
const decided = decision(read)
|
|
45
|
+
|
|
46
|
+
if (decided !== undefined) return decided
|
|
47
|
+
const is_applied = await git_gh_command.issue_add_label(issue_number, PRIORITY_HIGH_LABEL)
|
|
48
|
+
|
|
49
|
+
return is_applied ? 'raised' : 'failed'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const issue_priority_raise = { raise }
|
|
53
|
+
|
|
54
|
+
export type { RaiseResult }
|
|
55
|
+
export { issue_priority_raise }
|