@joshuafolkken/kit 1.1050.0 → 1.1128.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +9 -8
- package/.claude/skills/epic-commands/SKILL.md +5 -7
- package/.claude/skills/workflow-commands/SKILL.md +20 -12
- package/.claude/skills/workflow-commands/background-commands.md +36 -84
- package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
- package/.claude/skills/workflow-commands/backlogrun-progress.md +30 -33
- package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -12
- package/.claude/skills/workflow-commands/backlogrun.md +2 -2
- package/.claude/skills/workflow-commands/chain-rule.md +4 -2
- package/.claude/skills/workflow-commands/delegation.md +3 -3
- package/.claude/skills/workflow-commands/followup-reference.md +1 -1
- package/.claude/skills/workflow-commands/followup.md +7 -3
- package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/fullrun.md +8 -6
- package/.claude/skills/workflow-commands/halfrun.md +19 -21
- package/.claude/skills/workflow-commands/issue-comments.md +1 -1
- package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
- package/.claude/skills/workflow-commands/issue-scout.md +1 -1
- package/.claude/skills/workflow-commands/kickoff.md +9 -4
- package/.claude/skills/workflow-commands/latest-gate.md +8 -16
- package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
- package/.claude/skills/workflow-commands/observation-filing.md +3 -3
- package/.claude/skills/workflow-commands/pre-gate-cut.md +4 -8
- package/.claude/skills/workflow-commands/prerequisite.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +36 -0
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +4 -18
- package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
- package/.codex/hooks.json +16 -20
- package/.github/actions/setup-node/action.yml +33 -0
- package/.github/actions/setup-pnpm/action.yml +93 -0
- package/.github/dependabot.yml +5 -1
- package/.github/workflows/auto-tag.yml +2 -3
- package/.github/workflows/ci.yml +31 -134
- package/.github/workflows/dependabot-auto-merge.yml +1 -0
- package/.github/workflows/pr-classification.yml +6 -44
- package/.github/workflows/production.yml +1 -0
- package/.github/workflows/publish.yml +43 -47
- package/.github/workflows/sonar-qube.yml +41 -4
- package/.pnpmfile.mjs +29 -0
- package/AGENTS.md +5 -2
- package/CLAUDE.md +33 -27
- package/GEMINI.md +5 -2
- package/README.md +66 -20
- package/SECURITY.md +37 -6
- package/cspell/index.yaml +6 -1
- package/dist/CLAUDE.basic.md +6 -6
- package/dist/CLAUDE.md +33 -27
- package/dist/CLAUDE.static.md +6 -6
- package/dist/config-merge/index.js +48 -12
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-7VPDUBRN.js → chunk-4JZDP5X5.js} +152 -155
- package/dist/hooks/{chunk-HJIISEAC.js → chunk-5SD2YM7Z.js} +5 -13
- package/dist/hooks/{chunk-NAS4C7GP.js → chunk-77J7IEQM.js} +2 -2
- package/dist/hooks/{chunk-DMQN45FN.js → chunk-7HVB7SZG.js} +3 -3
- package/dist/hooks/{chunk-RLDX5SOC.js → chunk-AIOIOMPX.js} +4413 -1970
- package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M7QKEKWO.js} +873 -2049
- package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-MKVGBQPA.js} +2 -2
- package/dist/hooks/{chunk-EJDX2TOB.js → chunk-NXYMNPUQ.js} +7 -88
- package/dist/hooks/{chunk-NJQOBE6L.js → chunk-QVLT52OV.js} +2 -7
- package/dist/hooks/{chunk-GQ7KP45M.js → chunk-XYUIQOW3.js} +2 -2
- package/dist/hooks/codex-hook-adapter.js +12 -48
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +280 -0
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/session-lang.js +0 -1
- package/dist/hooks/stop-guard.js +192 -333
- package/dist/josh.js +240 -148
- package/dist/managed-marker/index.js +2 -1
- package/dist/version/index.js +70 -78
- package/eslint/rules/promise.js +5 -0
- package/eslint/rules/unicorn.js +3 -2
- package/package.json +26 -5
- package/pnpm-workspace.yaml +5 -7
- package/prompts/collaboration-workflow/glossary.md +17 -0
- package/prompts/collaboration-workflow/issue-citation.md +5 -5
- package/prompts/collaboration-workflow/issue-template.md +1 -1
- package/prompts/collaboration-workflow/operating-rules.md +5 -5
- package/prompts/collaboration-workflow/overview.md +13 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow/report-format.md +1 -1
- package/prompts/collaboration-workflow/residency.md +3 -3
- package/prompts/collaboration-workflow/rule-delivery.md +1 -1
- package/prompts/collaboration-workflow/turn-batching.md +3 -3
- package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
- package/prompts/collaboration-workflow/wip-cap.md +25 -22
- package/prompts/collaboration-workflow.md +6 -8
- package/prompts/review-rubric.md +1 -1
- package/prompts/review.md +3 -3
- package/prompts/sonar-hotspot-handling.md +11 -3
- package/prompts/testing-guide.md +3 -3
- package/scripts/adopt/adopt-toolkits.ts +0 -2
- package/scripts/adopt/adopt.ts +0 -2
- package/scripts/agent/agent-argv.ts +0 -2
- package/scripts/agent/agent-diagnostics.ts +1 -1
- package/scripts/agent/agent-role-profile.ts +0 -7
- package/scripts/agent/claude-agent-argv.ts +0 -2
- package/scripts/agent/codex-agent-argv.ts +1 -1
- package/scripts/agent/codex-hooks.ts +92 -0
- package/scripts/agent/interactive-ask.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +6 -16
- package/scripts/backlog/backlog-arrival.ts +30 -10
- package/scripts/backlog/backlog-budget-cli.ts +15 -16
- package/scripts/backlog/backlog-budget.ts +0 -2
- package/scripts/backlog/backlog-defect-priority.ts +2 -2
- package/scripts/backlog/backlog-drive-cli.ts +10 -8
- package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
- package/scripts/backlog/backlog-drive-named.ts +2 -1
- package/scripts/backlog/backlog-drive.ts +76 -16
- package/scripts/backlog/backlog-named.ts +0 -3
- package/scripts/backlog/backlog-next.ts +9 -15
- package/scripts/backlog/backlog-offer-cli.ts +6 -19
- package/scripts/backlog/backlog-plan-cli.ts +1 -7
- package/scripts/backlog/backlog-plan.ts +30 -19
- package/scripts/backlog/backlog-pool.ts +3 -6
- package/scripts/backlog/backlog-rank.ts +2 -2
- package/scripts/backlog/backlog-ready.ts +39 -10
- package/scripts/backlog/backlog-scope.ts +1 -3
- package/scripts/backlog/backlog-stalled-detect.ts +2 -2
- package/scripts/backlog/backlog-stalled.ts +0 -1
- package/scripts/backlog/backlog-waves.ts +5 -2
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/build/build-codex-hooks.ts +26 -0
- package/scripts/build/build-hooks.ts +85 -9
- package/scripts/build/hook-bundle-stamp.ts +111 -0
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +1 -1
- package/scripts/ci/composite-actions.ts +30 -0
- package/scripts/ci/pr-classification.ts +3 -3
- package/scripts/claude/workflow-destination.ts +10 -1
- package/scripts/clone/clone-fingerprint.ts +0 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/json-format.ts +0 -1
- package/scripts/config-merge/parse-jsonc.ts +33 -3
- package/scripts/config-merge/patch-json-key.ts +13 -6
- package/scripts/config-merge/patch-yaml-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +2 -9
- package/scripts/cost-runtime/cost-attribute.ts +0 -1
- package/scripts/cost-runtime/cost-cli.ts +3 -10
- package/scripts/cost-runtime/cost-corpus.ts +0 -2
- package/scripts/cost-runtime/cost-format.ts +0 -3
- package/scripts/cost-runtime/cost-pricing.ts +0 -1
- package/scripts/cost-runtime/cost-tokens.ts +0 -1
- package/scripts/delegation/delegation-cli.ts +1 -1
- package/scripts/delegation/delegation-policy.ts +0 -1
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +0 -2
- package/scripts/delegation/investigation-reads.ts +1 -164
- package/scripts/discovery/repo-map-logic.ts +0 -1
- package/scripts/discovery/repo-party-cli.ts +1 -1
- package/scripts/doctor/doctor-consumer.ts +6 -10
- package/scripts/doctor/doctor-io.ts +9 -13
- package/scripts/doctor/doctor-logic.ts +0 -4
- package/scripts/doctor/doctor.ts +14 -9
- package/scripts/document/backlogrun-parent-read-set.ts +12 -1
- package/scripts/document/document-byte-budget.ts +5 -5
- package/scripts/document/document-byte-check.ts +0 -1
- package/scripts/document/document-read-cli.ts +0 -2
- package/scripts/document/document-section-cli.ts +1 -1
- package/scripts/document/document-section.ts +0 -3
- package/scripts/document/edit-files-cli.ts +0 -1
- package/scripts/document/entry-read-budget.ts +21 -7
- package/scripts/document/entry-read-set.ts +32 -8
- package/scripts/document/lane-child-read-set.ts +8 -6
- package/scripts/document/read-files-cli.ts +0 -4
- package/scripts/document/read-set-cli.ts +0 -2
- package/scripts/document/read-set-point-of-use.ts +9 -3
- package/scripts/document/read-set-pricing.ts +0 -1
- package/scripts/document/read-set-trim.ts +4 -2
- package/scripts/epic/epic-add.ts +1 -1
- package/scripts/epic/epic-audit-cli.ts +1 -4
- package/scripts/epic/epic-audit-orphans.ts +1 -3
- package/scripts/epic/epic-audit-rationale.ts +0 -1
- package/scripts/epic/epic-audit-report.ts +0 -2
- package/scripts/epic/epic-audit.ts +8 -22
- package/scripts/epic/epic-bundle-cli.ts +1 -1
- package/scripts/epic/epic-bundle-evidence.ts +0 -1
- package/scripts/epic/epic-bundle-referenced.ts +1 -5
- package/scripts/epic/epic-bundle.ts +0 -4
- package/scripts/epic/epic-busy.ts +4 -5
- package/scripts/epic/epic-candidate-confirm.ts +0 -5
- package/scripts/epic/epic-classify.ts +2 -2
- package/scripts/epic/epic-cli-argv.ts +0 -1
- package/scripts/epic/epic-close-comment.ts +1 -1
- package/scripts/epic/epic-close.ts +5 -2
- package/scripts/epic/epic-cross-repo.ts +2 -4
- package/scripts/epic/epic-decision.ts +0 -1
- package/scripts/epic/epic-fetch.ts +2 -2
- package/scripts/epic/epic-index.ts +2 -3
- package/scripts/epic/epic-issue.ts +1 -15
- package/scripts/epic/epic-lane-offer.ts +9 -8
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +1 -3
- package/scripts/epic/epic-next-views.ts +0 -1
- package/scripts/epic/epic-next.ts +1 -10
- package/scripts/epic/epic-parse.ts +0 -1
- package/scripts/epic/epic-promote.ts +0 -9
- package/scripts/epic/epic-rank.ts +2 -2
- package/scripts/epic/epic-read.ts +1 -2
- package/scripts/epic/epic-reconcile.ts +1 -1
- package/scripts/epic/epic-reference.ts +1 -13
- package/scripts/epic/epic-relation-recheck.ts +1 -1
- package/scripts/epic/epic-relations.ts +1 -1
- package/scripts/epic/epic-remove.ts +1 -1
- package/scripts/epic/epic-report.ts +0 -1
- package/scripts/epic/epic-run.ts +2 -3
- package/scripts/epic/epic-shape.ts +1 -1
- package/scripts/epic/epic-solo-stale.ts +107 -0
- package/scripts/epic/epic-solo.ts +3 -2
- package/scripts/epic/epic-triage.ts +1 -1
- package/scripts/epic/epic-validate.ts +1 -1
- package/scripts/epic/epic.ts +1 -1
- package/scripts/exports/unused-members-cli.ts +53 -0
- package/scripts/{git → followup}/followup-issue-number.ts +1 -6
- package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
- package/scripts/{git → followup}/git-followup-finish.ts +1 -3
- package/scripts/{git → followup}/git-followup-flush.ts +2 -2
- package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
- package/scripts/{git → followup}/git-followup-label.ts +4 -4
- package/scripts/followup/git-followup-merged.ts +112 -0
- package/scripts/{git → followup}/git-followup-pending.ts +1 -1
- package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
- package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
- package/scripts/{git → followup}/git-pr-followup.ts +53 -16
- package/scripts/gate/core-budget.ts +3 -9
- package/scripts/gate/gate-plan.ts +7 -4
- package/scripts/gate/gate-report.ts +0 -6
- package/scripts/gate/gate-tree.ts +1 -1
- package/scripts/gate/pre-commit-type-check.ts +0 -6
- package/scripts/gate/project-checks.ts +7 -8
- package/scripts/gate/scoped-green.ts +0 -1
- package/scripts/gate/type-check-step.ts +1 -1
- package/scripts/gate/verification-gate.ts +0 -2
- package/scripts/gh/fix-gh-packages.ts +15 -12
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
- package/scripts/{git → gh}/git-gh-check.ts +2 -1
- package/scripts/{git → gh}/git-gh-exec.ts +1 -1
- package/scripts/{git → gh}/git-gh-failure.ts +1 -1
- package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
- package/scripts/{git → gh}/git-gh-issue-list.ts +13 -10
- package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
- package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
- package/scripts/{git → gh}/git-gh-issue-write.ts +4 -1
- package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +4 -1
- package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
- package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
- package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
- package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
- package/scripts/{git → gh}/git-gh-pr.ts +3 -1
- package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
- package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
- package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
- package/scripts/{git → gh}/git-pr-checks.ts +2 -1
- package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
- package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
- package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
- package/scripts/{git → gh}/git-pr.ts +3 -3
- package/scripts/git/changed-file-scope.ts +0 -1
- package/scripts/git/git-branch.ts +3 -6
- package/scripts/git/git-command.ts +6 -1
- package/scripts/git/git-commit.ts +1 -1
- package/scripts/git/git-common-directory.ts +80 -24
- package/scripts/git/git-error.ts +66 -9
- package/scripts/git/git-issue.ts +1 -1
- package/scripts/git/git-preflight.ts +2 -2
- package/scripts/git/git-prompt.ts +6 -31
- package/scripts/git/git-push.ts +1 -1
- package/scripts/git/git-spawn-sync.ts +65 -0
- package/scripts/git/git-spawn.ts +5 -4
- package/scripts/git/git-staging.ts +1 -0
- package/scripts/git/git-status.ts +1 -1
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/gone-branch.ts +1 -0
- package/scripts/git/listing-cutoff.ts +1 -1
- package/scripts/git/main-merge.ts +1 -1
- package/scripts/git/main-sync.ts +19 -1
- package/scripts/git/parse-json-array.ts +0 -3
- package/scripts/git/repository-lock.ts +16 -16
- package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
- package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +2 -7
- package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
- package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
- package/scripts/hooks/codex-hook-adapter.ts +0 -1
- package/scripts/hooks/edited-cspell.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +2 -0
- package/scripts/hooks/pre-push-unit.ts +0 -4
- package/scripts/hooks/pretool-guard.ts +22 -4
- package/scripts/hooks/reserved-run.ts +1 -1
- package/scripts/hooks/step-zero-notice.ts +76 -0
- package/scripts/hooks/stop-guard.ts +47 -21
- package/scripts/init/claude-plugin-config.ts +4 -5
- package/scripts/init/hook-command-rewrite.ts +16 -8
- package/scripts/init/hook-launch.ts +41 -15
- package/scripts/init/init-basic.ts +2 -5
- package/scripts/init/init-file-action.ts +54 -0
- package/scripts/init/init-logic-migrate.ts +35 -17
- package/scripts/init/init-logic-secretlint.ts +1 -1
- package/scripts/init/init-logic.ts +10 -19
- package/scripts/init/init.ts +11 -71
- package/scripts/init/kit-written-paths.ts +2 -0
- package/scripts/init/project-profile.ts +9 -17
- package/scripts/init/start-exec.ts +1 -1
- package/scripts/init/start-setup-pr.ts +6 -6
- package/scripts/init/start-steps.ts +3 -1
- package/scripts/issue/behavior-change-lint.ts +0 -1
- package/scripts/issue/defect-rate-cli.ts +64 -23
- package/scripts/issue/defect-rate.ts +1 -2
- package/scripts/{git → issue}/git-next-issues.ts +3 -3
- package/scripts/issue/issue-backlinks-cli.ts +1 -5
- package/scripts/issue/issue-backlinks.ts +7 -14
- package/scripts/issue/issue-cite-cli.ts +2 -6
- package/scripts/issue/issue-cite.ts +12 -8
- package/scripts/issue/issue-classification.ts +1 -9
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +2 -2
- package/scripts/issue/issue-file-cli.ts +5 -5
- package/scripts/issue/issue-file.ts +7 -14
- package/scripts/issue/issue-fold-cli.ts +1 -1
- package/scripts/issue/issue-fold-existing-cli.ts +1 -1
- package/scripts/{git → issue}/issue-labels.ts +8 -0
- package/scripts/issue/issue-lint-cli.ts +1 -1
- package/scripts/issue/issue-merged.ts +2 -2
- package/scripts/{git → issue}/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +8 -47
- package/scripts/issue/issue-read.ts +0 -2
- package/scripts/issue/issue-report-failures.ts +80 -0
- package/scripts/issue/issue-scout-cli.ts +1 -7
- package/scripts/issue/issue-scout-closed.ts +2 -2
- package/scripts/issue/issue-scout.ts +0 -2
- package/scripts/issue/issue-state-cli.ts +5 -46
- package/scripts/issue/issue-state.ts +1 -5
- package/scripts/issue/markdown-section.ts +21 -6
- package/scripts/issue/measure-rerun-cli.ts +74 -15
- package/scripts/issue/reproduction-measure.ts +1 -1
- package/scripts/josh/cli-body.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +0 -3
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-commands-ai.ts +9 -102
- package/scripts/josh/josh-commands-backlog.ts +5 -1
- package/scripts/josh/josh-commands-development.ts +8 -1
- package/scripts/josh/josh-commands-issue.ts +2 -2
- package/scripts/josh/josh-commands-maintenance.ts +7 -0
- package/scripts/josh/josh-commands-project.ts +7 -1
- package/scripts/josh/josh-commands-run.ts +114 -0
- package/scripts/josh/josh-commands-versioning.ts +8 -0
- package/scripts/josh/josh-commands-workflow.ts +3 -3
- package/scripts/josh/path-decision.ts +0 -3
- package/scripts/josh/process-owner.ts +16 -0
- package/scripts/josh/run-github-prerequisite.ts +3 -6
- package/scripts/josh/session-language-cli.ts +0 -1
- package/scripts/lane/lane-await.ts +46 -19
- package/scripts/lane/lane-capacity.ts +6 -3
- package/scripts/lane/lane-child-invocation.ts +20 -7
- package/scripts/lane/lane-cli.ts +1 -4
- package/scripts/lane/lane-close.ts +5 -4
- package/scripts/lane/lane-dispatch.ts +3 -4
- package/scripts/lane/lane-environment.ts +0 -9
- package/scripts/lane/lane-handoff.ts +38 -0
- package/scripts/lane/lane-launch-cli.ts +31 -27
- package/scripts/lane/lane-open.ts +0 -3
- package/scripts/lane/lane-output.ts +0 -1
- package/scripts/lane/lane-registry.ts +9 -0
- package/scripts/lane/openai-lane-ship.ts +2 -0
- package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
- package/scripts/lane/openai-lane-supervisor.ts +6 -4
- package/scripts/lane/openai-review-broker.ts +7 -1
- package/scripts/lib/bounded-pool.ts +1 -0
- package/scripts/lib/cli-flags.ts +31 -2
- package/scripts/lib/error-message.ts +12 -1
- package/scripts/lib/json-value.ts +5 -4
- package/scripts/lib/poll.ts +3 -1
- package/scripts/lib/timed-fetch.ts +15 -0
- package/scripts/lib/timeouts.ts +13 -0
- package/scripts/{yaml → lib}/yaml-document.ts +3 -1
- package/scripts/{bytes → lines}/bytes-command.ts +0 -2
- package/scripts/lines/line-targets.ts +0 -11
- package/scripts/lines/lines-command.ts +5 -4
- package/scripts/lint/lint-related-scope.ts +0 -1
- package/scripts/lint/lint-related.ts +1 -1
- package/scripts/{git → notify}/telegram-notify.ts +2 -2
- package/scripts/{git → notify}/telegram-test.ts +4 -4
- package/scripts/observations/observation-ledger-home.ts +0 -1
- package/scripts/observations/observation-ledger-line.ts +0 -1
- package/scripts/observations/observation-ledger-migrate.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +3 -3
- package/scripts/observations/observations-flush.ts +2 -2
- package/scripts/overrides/lockfile-overrides.ts +1 -1
- package/scripts/overrides/overrides-logic.ts +1 -1
- package/scripts/package/package-scout-cli.ts +2 -7
- package/scripts/package/package-scout.ts +0 -2
- package/scripts/propagate/propagate-git-failure.ts +0 -1
- package/scripts/propagate/propagate-git.ts +3 -10
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +0 -2
- package/scripts/propagate/propagate-steps.ts +3 -5
- package/scripts/propagate/propagate-targets.ts +0 -4
- package/scripts/propagate/propagate.ts +0 -4
- package/scripts/refactor/import-graph.ts +0 -1
- package/scripts/refactor/refactor-lint.ts +0 -2
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +0 -1
- package/scripts/registry-migration/migrate-logic.ts +28 -21
- package/scripts/registry-migration/migrate.ts +25 -14
- package/scripts/release/github-release-cli.ts +19 -6
- package/scripts/release/github-release-environment.ts +46 -0
- package/scripts/release/github-release.ts +151 -94
- package/scripts/release/release-history.ts +0 -1
- package/scripts/release/release-plan.ts +0 -1
- package/scripts/release/release-publish.ts +38 -5
- package/scripts/release/release-scope-cli.ts +1 -2
- package/scripts/release/release-tag.ts +2 -4
- package/scripts/release/release-worktree.ts +97 -2
- package/scripts/repo/auto-merge-setting-logic.ts +1 -4
- package/scripts/repo/repo-setting.ts +1 -1
- package/scripts/repo/repository-labels.ts +3 -3
- package/scripts/repo/required-checks-logic.ts +206 -0
- package/scripts/repo/required-checks-report.ts +71 -0
- package/scripts/repo/ruleset-check-cli.ts +53 -0
- package/scripts/repo/ruleset-check.ts +147 -0
- package/scripts/report/report-lint-cli.ts +0 -4
- package/scripts/review/disposition-cli.ts +1 -1
- package/scripts/review/live-evidence.ts +1 -1
- package/scripts/review/review-attest-cli.ts +0 -6
- package/scripts/review/review-attest.ts +4 -16
- package/scripts/review/review-brief-cli.ts +23 -6
- package/scripts/review/review-brief.ts +21 -8
- package/scripts/review/review-checkout.ts +3 -2
- package/scripts/review/review-diff-parts.ts +89 -0
- package/scripts/review/review-diff-write.ts +97 -0
- package/scripts/review/review-finding-ledger.ts +0 -1
- package/scripts/review/review-record-cli.ts +10 -17
- package/scripts/review/review-record.ts +0 -1
- package/scripts/review/review-round2-cli.ts +1 -1
- package/scripts/review/review-stamps.ts +0 -3
- package/scripts/review/review-tree.ts +14 -2
- package/scripts/rules/decision-oracle-stage.ts +18 -0
- package/scripts/rules/decision-oracle.ts +10 -7
- package/scripts/rules/delivered-rules.ts +9 -1
- package/scripts/rules/destructive-command.ts +119 -0
- package/scripts/rules/direct-filing.ts +1 -1
- package/scripts/rules/early-heartbeat.ts +4 -3
- package/scripts/rules/file-body.ts +0 -3
- package/scripts/rules/filing-cap.ts +0 -2
- package/scripts/rules/gh-api.ts +7 -2
- package/scripts/rules/git-argv.ts +18 -7
- package/scripts/rules/git-force.ts +0 -2
- package/scripts/rules/implementation-cut.ts +0 -1
- package/scripts/rules/index-guard.ts +71 -0
- package/scripts/rules/issue-citation.ts +50 -25
- package/scripts/rules/lane-background.ts +15 -7
- package/scripts/rules/lane-park.ts +22 -6
- package/scripts/rules/last-prompt.ts +1 -0
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/oracle-list-cli.ts +0 -3
- package/scripts/rules/permission-guards.ts +14 -0
- package/scripts/rules/protected-files.ts +74 -0
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +0 -3
- package/scripts/rules/rule-value-cli.ts +0 -1
- package/scripts/rules/shell-body-trigger.ts +0 -1
- package/scripts/rules/shell-segments.ts +0 -1
- package/scripts/rules/stop-rules.ts +20 -9
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +0 -1
- package/scripts/rules/worktree-guard.ts +26 -9
- package/scripts/run/run-carry-args.ts +8 -12
- package/scripts/run/run-carry-cli.ts +0 -2
- package/scripts/run/run-carry-stash.ts +2 -2
- package/scripts/run/run-carry-streak.ts +1 -1
- package/scripts/run/run-cut-args.ts +1 -6
- package/scripts/run/run-cut-cli.ts +0 -7
- package/scripts/run/run-cut.ts +8 -54
- package/scripts/run/run-ending-cli.ts +2 -6
- package/scripts/run/run-ending.ts +1 -4
- package/scripts/run/run-entry-cli.ts +133 -25
- package/scripts/run/run-entry-stop.ts +104 -0
- package/scripts/run/run-entry.ts +0 -1
- package/scripts/run/run-event-cli.ts +0 -2
- package/scripts/run/run-event-follow.ts +1 -0
- package/scripts/run/run-event-render.ts +1 -1
- package/scripts/run/run-event-scope.ts +53 -4
- package/scripts/run/run-event-stream-emit.ts +7 -2
- package/scripts/run/run-event-stream.ts +0 -3
- package/scripts/run/run-event-watch.ts +1 -0
- package/scripts/run/run-halfrun-resume.ts +20 -7
- package/scripts/run/run-headless.ts +2 -2
- package/scripts/run/run-hold-cli.ts +33 -10
- package/scripts/run/run-hold.ts +29 -6
- package/scripts/run/run-issue-number.ts +1 -1
- package/scripts/run/run-liveness-cli.ts +2 -6
- package/scripts/run/run-liveness.ts +2 -3
- package/scripts/run/run-merge-cli.ts +7 -23
- package/scripts/run/run-merge-steps.ts +5 -5
- package/scripts/run/run-merge.ts +1 -1
- package/scripts/run/run-next-cli.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +4 -2
- package/scripts/run/run-preflight.ts +2 -9
- package/scripts/run/run-prep-cli.ts +6 -3
- package/scripts/run/run-prep-locate.ts +1 -1
- package/scripts/run/run-progress-args.ts +20 -4
- package/scripts/run/run-progress-cli.ts +35 -36
- package/scripts/run/run-progress-clock.ts +10 -35
- package/scripts/run/run-progress-config.ts +0 -4
- package/scripts/run/run-progress-read.ts +1 -2
- package/scripts/run/run-progress.ts +1 -2
- package/scripts/run/run-prrun-resume.ts +117 -0
- package/scripts/run/run-report-cli.ts +1 -2
- package/scripts/run/run-report.ts +0 -1
- package/scripts/run/run-retrospective.ts +1 -1
- package/scripts/run/run-review-cli.ts +0 -3
- package/scripts/run/run-review-steps.ts +2 -0
- package/scripts/run/run-review.ts +0 -2
- package/scripts/run/run-ship-cli.ts +29 -19
- package/scripts/run/run-ship-detach.ts +1 -0
- package/scripts/run/run-ship-next.ts +106 -0
- package/scripts/run/run-ship-preflight.ts +1 -1
- package/scripts/run/run-ship-probe.ts +4 -1
- package/scripts/run/run-ship-return.ts +8 -3
- package/scripts/run/run-ship-review-steps.ts +18 -4
- package/scripts/run/run-ship-review.ts +11 -0
- package/scripts/run/run-ship-scoped.ts +1 -0
- package/scripts/run/run-ship-steps.ts +1 -1
- package/scripts/run/run-ship.ts +0 -1
- package/scripts/run/run-stage-read.ts +62 -0
- package/scripts/run/run-stage.ts +160 -0
- package/scripts/run/run-status-cli.ts +3 -16
- package/scripts/run/run-step-cli.ts +21 -14
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stop-notify.ts +1 -3
- package/scripts/run/run-stranded-cli.ts +0 -4
- package/scripts/run/run-stranded-detect.ts +2 -2
- package/scripts/run/run-tail-cli.ts +17 -11
- package/scripts/run/run-tail.ts +2 -0
- package/scripts/run/run-tidy-lanes.ts +6 -2
- package/scripts/run/run-tidy-stashes.ts +12 -12
- package/scripts/run/run-wake-cli.ts +4 -13
- package/scripts/run/run-wake-loop.ts +2 -2
- package/scripts/run/run-wake.ts +2 -4
- package/scripts/run/run-watcher-guard-cli.ts +0 -4
- package/scripts/run/run-watcher-guard.ts +18 -12
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/safe-chain/ci-installer-pin.ts +11 -5
- package/scripts/safe-chain/pack-hook.ts +92 -0
- package/scripts/safe-chain/project-config.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +0 -1
- package/scripts/security/security-audit-provision.ts +3 -2
- package/scripts/security/security-audit.ts +0 -1
- package/scripts/security/security-updates-logic.ts +0 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
- package/scripts/sonar/sonar-hotspots.ts +0 -1
- package/scripts/sonar/sonar-new-code-cli.ts +150 -0
- package/scripts/sonar/sonar-new-code.ts +79 -0
- package/scripts/sonar/sonar-project.ts +97 -0
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +2 -5
- package/scripts/sync/managed-config-scope-cli.ts +1 -1
- package/scripts/sync/skill-migration.ts +0 -1
- package/scripts/sync/sync-ai-files.ts +4 -0
- package/scripts/sync/sync-hook-safety.ts +2 -3
- package/scripts/sync/sync.ts +1 -8
- package/scripts/sync/template-source-logic.ts +0 -1
- package/scripts/sync/workflow-pin-logic.ts +16 -28
- package/scripts/test/test-declared-changed.ts +13 -16
- package/scripts/test/test-declared-logic.ts +0 -1
- package/scripts/test/test-declared.ts +3 -9
- package/scripts/test/test-red-commit.ts +2 -2
- package/scripts/test/test-red.ts +14 -7
- package/scripts/test/test-type-logic.ts +1 -1
- package/scripts/test/unit-worker-share.ts +7 -16
- package/scripts/time-runtime/time-batch-guard.ts +1 -2
- package/scripts/time-runtime/time-bundle-call.ts +0 -1
- package/scripts/time-runtime/time-bundles.ts +0 -4
- package/scripts/time-runtime/time-density-hook.ts +0 -2
- package/scripts/time-runtime/time-followup-stage.ts +1 -1
- package/scripts/time-runtime/time-format.ts +0 -73
- package/scripts/time-runtime/time-round-trips.ts +0 -4
- package/scripts/time-runtime/time-single-check.ts +1 -1
- package/scripts/time-runtime/time-spans.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +1 -2
- package/scripts/ui/ui-routes-cli.ts +0 -5
- package/scripts/ui/ui-routes.ts +0 -5
- package/scripts/version/effective-upstream.ts +2 -2
- package/scripts/version/latest-corepack.ts +7 -9
- package/scripts/version/latest-scope-cli.ts +0 -2
- package/scripts/version/latest-update.ts +0 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/publishable-range-check.ts +1 -1
- package/scripts/version/release-hold.ts +0 -4
- package/scripts/version/running-binary.ts +2 -2
- package/scripts/version/version-check-logic.ts +0 -2
- package/scripts/version/version-commands.ts +11 -1
- package/scripts/version/version-remote.ts +3 -3
- package/scripts/version/version-targets.ts +4 -4
- package/templates/CLAUDE.basic.md +6 -6
- package/templates/sonar-project.properties +28 -1
- package/templates/workflows/ci.yml +16 -82
- package/templates/workflows/dependabot-auto-merge.yml +6 -3
- package/templates/workflows/github-release.yml +79 -0
- package/tsconfig.sonar.json +4 -22
- package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
- package/prompts/collaboration-workflow/epic-audit.md +0 -5
- package/prompts/collaboration-workflow/epic-bundle.md +0 -5
- package/scripts/init/plugin-install-hint.ts +0 -47
- package/scripts/version/parse-json.ts +0 -13
- /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
- /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
- /package/scripts/{git → gh}/git-gh-command.ts +0 -0
- /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
- /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
- /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
- /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
- /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
- /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
- /package/scripts/{git → gh}/git-pr-error.ts +0 -0
- /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
- /package/scripts/{git → gh}/github-issue-url.ts +0 -0
- /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
- /package/scripts/{git → issue}/issue-reference.ts +0 -0
- /package/scripts/{git → lib}/animation-helpers.ts +0 -0
- /package/scripts/{git → lib}/git-animation.ts +0 -0
- /package/scripts/{git → notify}/git-notify.ts +0 -0
- /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
+
import { git_spawn_sync } from '#scripts/git/git-spawn-sync'
|
|
2
3
|
import { error_text } from '#scripts/lib/error-message'
|
|
3
4
|
import { repository_labels } from '#scripts/repo/repository-labels'
|
|
4
5
|
import { self_sync_guard } from '#scripts/self-sync-guard/self-sync-guard-logic'
|
|
@@ -44,7 +45,7 @@ function read_git_state(root: string, shape: ProjectShape): GitState {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
const has_origin =
|
|
48
|
+
const has_origin = git_spawn_sync.origin_url(root) !== undefined
|
|
48
49
|
const branch = read_output('git', ['symbolic-ref', '--short', 'HEAD'], root)
|
|
49
50
|
const has_commits = succeeds('git', ['rev-parse', '--verify', '--quiet', 'HEAD'], root)
|
|
50
51
|
const has_kit_committed = kit_setup_state.is_kit_committed(root)
|
|
@@ -163,6 +164,7 @@ async function run_steps(steps: ReadonlyArray<StartStep>, context: StepContext):
|
|
|
163
164
|
const position = `${String(index + 1)}/${String(steps.length)}`
|
|
164
165
|
|
|
165
166
|
console.info(`\n[${position}] ${labels[step]}`)
|
|
167
|
+
// eslint-disable-next-line no-await-in-loop -- each step builds on what the earlier ones set up
|
|
166
168
|
await run_step(step, run_context, steps.slice(0, index))
|
|
167
169
|
}
|
|
168
170
|
}
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
|
|
3
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
4
|
+
import { git_gh_exec } from '#scripts/gh/git-gh-exec'
|
|
5
|
+
import { parse_json } from '#scripts/git/parse-json-array'
|
|
7
6
|
import { issue_label_schema } from '#scripts/git/schemas'
|
|
7
|
+
import { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
8
|
+
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
8
9
|
import { z } from 'zod'
|
|
9
10
|
import { defect_rate, type DefectRate, type RateIssue } from './defect-rate'
|
|
10
11
|
|
|
11
12
|
const SUCCESS_EXIT_CODE = 0
|
|
12
13
|
const FAILURE_EXIT_CODE = 1
|
|
13
14
|
const PER_PAGE = '100'
|
|
15
|
+
const FIRST_PAGE = 1
|
|
16
|
+
const SECOND_PAGE = 2
|
|
17
|
+
// The search API serves at most this many results, so a window past it holds no further page.
|
|
18
|
+
const SEARCH_RESULT_CEILING = 1000
|
|
19
|
+
// The search API allows 30 requests a minute; both searches together stay at the ~10 requests the
|
|
20
|
+
// sequential walk made, so this bounds only how many are in flight at once.
|
|
21
|
+
const PAGE_CONCURRENCY = 4
|
|
14
22
|
const USAGE = 'Usage: pnpm josh defect:rate [--days <n>]'
|
|
15
23
|
const UNKNOWN_REPO_MESSAGE =
|
|
16
24
|
'Could not read this repository from `git remote`, so no issue can be searched — check `gh auth status` and that this is a checkout with an `origin` remote.'
|
|
@@ -33,7 +41,7 @@ const search_item_schema = z.object({
|
|
|
33
41
|
labels: z.array(issue_label_schema),
|
|
34
42
|
})
|
|
35
43
|
|
|
36
|
-
// One page of `search/issues`.
|
|
44
|
+
// One page of `search/issues`.
|
|
37
45
|
const search_page_schema = z.object({
|
|
38
46
|
total_count: z.number(),
|
|
39
47
|
incomplete_results: z.boolean(),
|
|
@@ -48,22 +56,60 @@ interface SearchResult {
|
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
function read_days(argv: ReadonlyArray<string>): number | undefined {
|
|
51
|
-
|
|
52
|
-
const { values } = parseArgs({ args: [...argv], options: OPTIONS, strict: true })
|
|
53
|
-
const raw = values.days ?? String(defect_rate.DEFAULT_WINDOW_DAYS)
|
|
59
|
+
const values = cli_flags.values_of(argv, OPTIONS)
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
if (values === undefined) return undefined
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
const raw = values.days ?? String(defect_rate.DEFAULT_WINDOW_DAYS)
|
|
58
64
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
if (!DAYS_PATTERN.test(raw)) return undefined
|
|
66
|
+
|
|
67
|
+
const days = Number(raw)
|
|
68
|
+
|
|
69
|
+
return days <= MAX_WINDOW_DAYS ? days : undefined
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function search_path(query: string, page: number = FIRST_PAGE): string {
|
|
73
|
+
const parameters = new URLSearchParams({ q: query, per_page: PER_PAGE })
|
|
74
|
+
|
|
75
|
+
if (page !== FIRST_PAGE) parameters.set('page', String(page))
|
|
76
|
+
|
|
77
|
+
return `search/issues?${parameters.toString()}`
|
|
63
78
|
}
|
|
64
79
|
|
|
65
|
-
|
|
66
|
-
|
|
80
|
+
// How many pages the search holds, read off the first page's own count. Bounded by the API's
|
|
81
|
+
// ceiling, past which GitHub serves no page at all — so this asks for exactly the pages `gh api
|
|
82
|
+
// --paginate` used to walk to.
|
|
83
|
+
function page_count(first: SearchPage): number {
|
|
84
|
+
return Math.ceil(Math.min(first.total_count, SEARCH_RESULT_CEILING) / Number(PER_PAGE))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function read_page(query: string, page: number): Promise<SearchPage | undefined> {
|
|
88
|
+
const raw = await git_gh_exec.exec_gh_api({ path: search_path(query, page) })
|
|
89
|
+
|
|
90
|
+
return parse_json.parse_json_object_safe(raw, search_page_schema)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Every page of one search. joshuafolkken/kit#3103: `--paginate` follows each page's `next` link, so
|
|
94
|
+
// a two-week window of ~5 pages cost ~1.5 s a page, one after another, on every `backlog:plan`. The
|
|
95
|
+
// first page names the total, so the rest are fetched together; any page that does not read fails
|
|
96
|
+
// the whole search, as a failed `--paginate` did.
|
|
97
|
+
async function read_pages(query: string): Promise<ReadonlyArray<SearchPage> | undefined> {
|
|
98
|
+
const first = await read_page(query, FIRST_PAGE)
|
|
99
|
+
|
|
100
|
+
if (first === undefined) return undefined
|
|
101
|
+
|
|
102
|
+
const rest_numbers = Array.from(
|
|
103
|
+
{ length: Math.max(page_count(first) - FIRST_PAGE, 0) },
|
|
104
|
+
(_value, index) => index + SECOND_PAGE,
|
|
105
|
+
)
|
|
106
|
+
const rest = await bounded_pool.bounded_map(
|
|
107
|
+
rest_numbers,
|
|
108
|
+
PAGE_CONCURRENCY,
|
|
109
|
+
async (page) => await read_page(query, page),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return rest.every((page) => page !== undefined) ? [first, ...rest] : undefined
|
|
67
113
|
}
|
|
68
114
|
|
|
69
115
|
function to_result(pages: ReadonlyArray<SearchPage>): SearchResult {
|
|
@@ -83,12 +129,7 @@ function to_result(pages: ReadonlyArray<SearchPage>): SearchResult {
|
|
|
83
129
|
|
|
84
130
|
async function search(query: string): Promise<SearchResult | undefined> {
|
|
85
131
|
try {
|
|
86
|
-
const
|
|
87
|
-
path: search_path(query),
|
|
88
|
-
should_paginate: true,
|
|
89
|
-
should_slurp: true,
|
|
90
|
-
})
|
|
91
|
-
const pages = parse_json_array_or_undefined(raw, search_page_schema)
|
|
132
|
+
const pages = await read_pages(query)
|
|
92
133
|
|
|
93
134
|
return pages === undefined ? undefined : to_result(pages)
|
|
94
135
|
} catch {
|
|
@@ -160,7 +201,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
160
201
|
process.exitCode = await run(argv)
|
|
161
202
|
}
|
|
162
203
|
|
|
163
|
-
const defect_rate_cli = { USAGE, read_days, search_path, measure_window, run
|
|
204
|
+
const defect_rate_cli = { USAGE, read_days, search_path, measure_window, run }
|
|
164
205
|
|
|
165
206
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
166
207
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { has_label_name, INTERRUPT_ROUTE_LABEL } from '#scripts/git/issue-labels'
|
|
2
1
|
import { behavior_change_lint } from './behavior-change-lint'
|
|
2
|
+
import { has_label_name, INTERRUPT_ROUTE_LABEL } from './issue-labels'
|
|
3
3
|
import { markdown_section } from './markdown-section'
|
|
4
4
|
|
|
5
5
|
// The defect rate of merged work over a window (joshuafolkken/kit#2449): issues filed as defects
|
|
@@ -132,7 +132,6 @@ const defect_rate = {
|
|
|
132
132
|
filed_query,
|
|
133
133
|
format,
|
|
134
134
|
is_above_baseline,
|
|
135
|
-
is_behavior_change,
|
|
136
135
|
is_defect,
|
|
137
136
|
kind_of,
|
|
138
137
|
measure,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { git_gh_command } from '
|
|
1
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
2
|
+
import { parse_json_array_safe } from '#scripts/git/parse-json-array'
|
|
3
|
+
import { open_issue_schema, type OpenIssueData } from '#scripts/git/schemas'
|
|
2
4
|
import { has_any_label, NOT_DIRECTLY_RUNNABLE_LABELS } from './issue-labels'
|
|
3
5
|
import { issue_rank, type DependencyRow } from './issue-rank'
|
|
4
|
-
import { parse_json_array_safe } from './parse-json-array'
|
|
5
|
-
import { open_issue_schema, type OpenIssueData } from './schemas'
|
|
6
6
|
|
|
7
7
|
// The next-issues display printed when a workflow completes (#821): up to five open issues in
|
|
8
8
|
// priority order, so the user picks the next run from the completion output instead of opening the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import { git_gh_command } from '#scripts/
|
|
3
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
4
4
|
import { parse_json_object_safe } from '#scripts/git/parse-json-array'
|
|
5
5
|
import { z } from 'zod'
|
|
6
6
|
import { issue_backlinks, type UpstreamEntry } from './issue-backlinks'
|
|
@@ -90,8 +90,4 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
90
90
|
process.exitCode = await run(argv)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
const issue_backlinks_cli = { run, USAGE }
|
|
94
|
-
|
|
95
93
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
96
|
-
|
|
97
|
-
export { issue_backlinks_cli }
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
// undetected. This classifies an origin issue's filed backlinks into one of four fixed words
|
|
5
5
|
// (joshuafolkken/kit#2123). The headings are the single source's, pinned by the document test.
|
|
6
6
|
|
|
7
|
+
import { markdown_section } from './markdown-section'
|
|
8
|
+
|
|
7
9
|
const ORIGIN_HEADING = '## Origin'
|
|
8
10
|
const UPSTREAM_ISSUES_HEADING = '## Upstream issues'
|
|
9
11
|
const UPSTREAM_CANDIDATE_HEADING = '## Upstream candidate'
|
|
10
12
|
const CHECKBOX_PATTERN = /^\s*-\s*\[[ xX]\]/u
|
|
11
13
|
const WRONG_UPSTREAM_HEADING_PATTERN = /^##\s+Upstream\b/iu
|
|
12
|
-
const SUBHEADING_PATTERN = /^##\s/u
|
|
13
14
|
const BARE_REFERENCE_PATTERN = /^#\d+$/u
|
|
14
15
|
const DIGITS_PATTERN = /^\d+$/u
|
|
15
16
|
const REFERENCE_MARK = '#'
|
|
@@ -27,31 +28,23 @@ interface UpstreamEntry {
|
|
|
27
28
|
body: string
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
return body.split('\n').map((line) => line.trimEnd())
|
|
32
|
-
}
|
|
33
|
-
|
|
31
|
+
// A heading inside a code fence is example text, so neither lookup counts one (joshuafolkken/kit#3066).
|
|
34
32
|
function has_heading(body: string, heading: string): boolean {
|
|
35
|
-
return
|
|
33
|
+
return markdown_section.has_line(body, heading)
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
// The lines under `heading`, up to the next `##` heading; `undefined` when the heading is absent.
|
|
39
37
|
function section_lines(body: string, heading: string): ReadonlyArray<string> | undefined {
|
|
40
|
-
|
|
41
|
-
const start = lines.findIndex((line) => line.trim() === heading)
|
|
42
|
-
if (start === -1) return undefined
|
|
43
|
-
|
|
44
|
-
const rest = lines.slice(start + 1)
|
|
45
|
-
const end = rest.findIndex((line) => SUBHEADING_PATTERN.test(line.trim()))
|
|
38
|
+
if (!has_heading(body, heading)) return undefined
|
|
46
39
|
|
|
47
|
-
return
|
|
40
|
+
return markdown_section.section_lines(body, heading)
|
|
48
41
|
}
|
|
49
42
|
|
|
50
43
|
// A heading that looks like the upstream one but is not exactly it (`## Upstream`, `## Upstreams`,
|
|
51
44
|
// wrong case) — the grep the template promises would miss it, so it is a wrong-heading rather than a
|
|
52
45
|
// missing one. `## Upstream candidate` is a legitimate separate heading and is excluded.
|
|
53
46
|
function has_wrong_upstream_heading(body: string): boolean {
|
|
54
|
-
return
|
|
47
|
+
return markdown_section.unfenced_lines(body).some((line) => {
|
|
55
48
|
const heading = line.trim()
|
|
56
49
|
if (heading === UPSTREAM_ISSUES_HEADING || heading === UPSTREAM_CANDIDATE_HEADING) return false
|
|
57
50
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
3
|
import { parseArgs } from 'node:util'
|
|
4
|
-
import { git_gh_command } from '#scripts/
|
|
5
|
-
import type { IssueRead } from '#scripts/
|
|
4
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
5
|
+
import type { IssueRead } from '#scripts/gh/git-gh-issue-read'
|
|
6
6
|
import { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
7
7
|
import { z } from 'zod'
|
|
8
8
|
import { issue_cite, type CiteTarget } from './issue-cite'
|
|
@@ -145,12 +145,8 @@ async function main(args: ReadonlyArray<string>): Promise<void> {
|
|
|
145
145
|
|
|
146
146
|
const issue_cite_cli = {
|
|
147
147
|
USAGE,
|
|
148
|
-
main,
|
|
149
148
|
parse_targets,
|
|
150
|
-
parse_title,
|
|
151
|
-
report,
|
|
152
149
|
run,
|
|
153
|
-
to_line,
|
|
154
150
|
}
|
|
155
151
|
|
|
156
152
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
@@ -46,14 +46,19 @@ function citation_line(slug: string, number: string, summary: string): string {
|
|
|
46
46
|
// and the plain `#N` only when the repository could not be read at all.
|
|
47
47
|
type IssueCiter = (number: string) => string
|
|
48
48
|
|
|
49
|
+
// One issue, named from what the caller holds — the single decision every listing's citation goes
|
|
50
|
+
// through (joshuafolkken/kit#3099), so a renderer holding one title never re-derives the fallback.
|
|
51
|
+
function reference(slug: string | undefined, number: string, title: string | undefined): string {
|
|
52
|
+
if (slug === undefined) return `#${number}`
|
|
53
|
+
|
|
54
|
+
return title === undefined
|
|
55
|
+
? `[#${number}](${issue_url(slug, number)})`
|
|
56
|
+
: citation_line(slug, number, title)
|
|
57
|
+
}
|
|
58
|
+
|
|
49
59
|
function citer(slug: string | undefined, titles: ReadonlyMap<string, string>): IssueCiter {
|
|
50
60
|
return function cite(number: string): string {
|
|
51
|
-
|
|
52
|
-
const title = titles.get(number)
|
|
53
|
-
|
|
54
|
-
return title === undefined
|
|
55
|
-
? `[#${number}](${issue_url(slug, number)})`
|
|
56
|
-
: citation_line(slug, number, title)
|
|
61
|
+
return reference(slug, number, titles.get(number))
|
|
57
62
|
}
|
|
58
63
|
}
|
|
59
64
|
|
|
@@ -105,14 +110,13 @@ function no_repo_line(target: CiteTarget): string {
|
|
|
105
110
|
}
|
|
106
111
|
|
|
107
112
|
const issue_cite = {
|
|
108
|
-
SUMMARY_SEPARATOR,
|
|
109
113
|
citation_line,
|
|
110
114
|
citer,
|
|
111
115
|
issue_url,
|
|
112
|
-
label,
|
|
113
116
|
missing_line,
|
|
114
117
|
no_repo_line,
|
|
115
118
|
parse_target,
|
|
119
|
+
reference,
|
|
116
120
|
unreadable_line,
|
|
117
121
|
}
|
|
118
122
|
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BREAKING_CHANGE_LABEL,
|
|
3
|
-
BUG_LABEL,
|
|
4
|
-
ENHANCEMENT_LABEL,
|
|
5
|
-
has_label_name,
|
|
6
|
-
} from '#scripts/git/issue-labels'
|
|
7
1
|
import { issue_bug_label } from './issue-bug-label'
|
|
2
|
+
import { BREAKING_CHANGE_LABEL, BUG_LABEL, ENHANCEMENT_LABEL, has_label_name } from './issue-labels'
|
|
8
3
|
import { markdown_section } from './markdown-section'
|
|
9
4
|
|
|
10
5
|
const FEATURE_DECLARATIONS = ['- 目的: 機能追加', '- 目的: 機能改善']
|
|
@@ -62,10 +57,7 @@ function problems(body: string): ReadonlyArray<string> {
|
|
|
62
57
|
}
|
|
63
58
|
|
|
64
59
|
const issue_classification = {
|
|
65
|
-
BREAKING_DECLARATION,
|
|
66
60
|
CLASSIFICATION_LABELS,
|
|
67
|
-
FEATURE_DECLARATIONS,
|
|
68
|
-
NON_BUG_DECLARATION,
|
|
69
61
|
labels_for,
|
|
70
62
|
problems,
|
|
71
63
|
required_labels,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { git_gh_api_path } from '#scripts/gh/git-gh-api-path'
|
|
2
|
+
import { git_gh_exec } from '#scripts/gh/git-gh-exec'
|
|
3
|
+
import { git_gh_repo } from '#scripts/gh/git-gh-repo'
|
|
1
4
|
import { git_closes_keyword } from '#scripts/git/git-closes-keyword'
|
|
2
|
-
import { git_gh_api_path } from '#scripts/git/git-gh-api-path'
|
|
3
|
-
import { git_gh_exec } from '#scripts/git/git-gh-exec'
|
|
4
|
-
import { git_gh_repo } from '#scripts/git/git-gh-repo'
|
|
5
5
|
import { parse_json_object_safe } from '#scripts/git/parse-json-array'
|
|
6
6
|
import { z } from 'zod'
|
|
7
7
|
|
|
@@ -88,6 +88,6 @@ async function read_closing_pr(issue: string): Promise<string | undefined> {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
const issue_closing_pr = {
|
|
91
|
+
const issue_closing_pr = { read_closing_pr }
|
|
92
92
|
|
|
93
93
|
export { issue_closing_pr }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import { git_gh_command } from '#scripts/
|
|
3
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
4
4
|
import { cli_body } from '#scripts/josh/cli-body'
|
|
5
5
|
import { error_text } from '#scripts/lib/error-message'
|
|
6
6
|
|
|
@@ -89,7 +89,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
89
89
|
process.exitCode = await run(argv)
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
const issue_comment_cli = { USAGE,
|
|
92
|
+
const issue_comment_cli = { USAGE, run }
|
|
93
93
|
|
|
94
94
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
95
95
|
|
|
@@ -3,10 +3,10 @@ import { readFile } from 'node:fs/promises'
|
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
4
|
import { repo_party } from '#scripts/discovery/repo-party'
|
|
5
5
|
import { epic_bundle_cli } from '#scripts/epic/epic-bundle-cli'
|
|
6
|
-
import { git_gh_command } from '#scripts/
|
|
7
|
-
import { git_gh_exec } from '#scripts/
|
|
8
|
-
import { git_gh_issue_write } from '#scripts/
|
|
9
|
-
import { github_issue_url } from '#scripts/
|
|
6
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
7
|
+
import { git_gh_exec } from '#scripts/gh/git-gh-exec'
|
|
8
|
+
import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
|
|
9
|
+
import { github_issue_url } from '#scripts/gh/github-issue-url'
|
|
10
10
|
import { error_text } from '#scripts/lib/error-message'
|
|
11
11
|
import { issue_file, type FileArguments } from './issue-file'
|
|
12
12
|
import { issue_lint_cli } from './issue-lint-cli'
|
|
@@ -182,7 +182,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
182
182
|
process.exitCode = await run(argv)
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
const issue_file_cli = {
|
|
185
|
+
const issue_file_cli = { THIRD_PARTY_MESSAGE, run }
|
|
186
186
|
|
|
187
187
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
188
188
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { parseArgs } from 'node:util'
|
|
1
|
+
import type { parseArgs } from 'node:util'
|
|
2
2
|
import { epic_issue } from '#scripts/epic/epic-issue'
|
|
3
|
-
import { github_issue_url } from '#scripts/
|
|
4
|
-
import {
|
|
3
|
+
import { github_issue_url } from '#scripts/gh/github-issue-url'
|
|
4
|
+
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
5
5
|
import { issue_backlinks } from './issue-backlinks'
|
|
6
6
|
import { issue_classification } from './issue-classification'
|
|
7
|
+
import { DEPTH_LABEL_ORDER, FILING_ROUTE_LABELS, has_label_name } from './issue-labels'
|
|
7
8
|
import { markdown_section } from './markdown-section'
|
|
8
9
|
|
|
9
10
|
// The decisions behind `josh issue:file` (joshuafolkken/kit#2808), kept apart from the command that
|
|
@@ -103,19 +104,11 @@ function arguments_of(values: ParsedValues, title: string | undefined): FileArgu
|
|
|
103
104
|
return { title, body_file, ...labelled, labels: values.label ?? [], repo: values.repo }
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
// An unknown flag
|
|
107
|
+
// An unknown flag is `undefined` rather than a throw, so the answer is the usage line, not a stack trace.
|
|
107
108
|
function parse(argv: ReadonlyArray<string>): FileArguments | undefined {
|
|
108
|
-
|
|
109
|
-
const { values, positionals } = parseArgs({
|
|
110
|
-
args: [...argv],
|
|
111
|
-
options: OPTIONS,
|
|
112
|
-
allowPositionals: true,
|
|
113
|
-
})
|
|
109
|
+
const parsed = cli_flags.arguments_of(argv, OPTIONS)
|
|
114
110
|
|
|
115
|
-
|
|
116
|
-
} catch {
|
|
117
|
-
return undefined
|
|
118
|
-
}
|
|
111
|
+
return parsed === undefined ? undefined : arguments_of(parsed.values, parsed.positionals[0])
|
|
119
112
|
}
|
|
120
113
|
|
|
121
114
|
// A classification label is the body's to declare, so an extra `--label` naming one the body does not
|
|
@@ -90,7 +90,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
90
90
|
process.exitCode = await run(argv)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
const issue_fold_cli = {
|
|
93
|
+
const issue_fold_cli = { read_arguments, size_verdict, run }
|
|
94
94
|
|
|
95
95
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
96
96
|
|
|
@@ -74,7 +74,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
74
74
|
process.exitCode = await run(argv)
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
const issue_fold_existing_cli = { run
|
|
77
|
+
const issue_fold_existing_cli = { run }
|
|
78
78
|
|
|
79
79
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
80
80
|
|
|
@@ -6,6 +6,11 @@ const BUG_LABEL = 'bug'
|
|
|
6
6
|
const ENHANCEMENT_LABEL = 'enhancement'
|
|
7
7
|
const BREAKING_CHANGE_LABEL = 'breaking-change'
|
|
8
8
|
const IN_PROGRESS_LABEL = 'in-progress'
|
|
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 (joshuafolkken/kit#3042).
|
|
11
|
+
// Namespaced like `run:solo`: a bare `planned` is a common roadmap label a person may already apply,
|
|
12
|
+
// and reading one as kickoff's mark would skip the planning that never happened.
|
|
13
|
+
const PLANNED_LABEL = 'run:planned'
|
|
9
14
|
// Parks a child that cannot advance without a person deciding something. `epic:next` is what reads
|
|
10
15
|
// it: a parked child is why a run reports "nothing left that time will fix" rather than waiting
|
|
11
16
|
// forever (joshuafolkken/kit#860).
|
|
@@ -207,6 +212,7 @@ const WORKFLOW_LABELS: ReadonlyArray<LabelDefinition> = [
|
|
|
207
212
|
description: 'Tracks a batch of child issues from one split',
|
|
208
213
|
},
|
|
209
214
|
{ name: IN_PROGRESS_LABEL, color: '0075ca', description: 'Work is actively in progress' },
|
|
215
|
+
{ name: PLANNED_LABEL, color: 'c2e0c6', description: 'kickoff posted the plan' },
|
|
210
216
|
{
|
|
211
217
|
name: RUN_SOLO_LABEL,
|
|
212
218
|
color: 'b60205',
|
|
@@ -328,6 +334,7 @@ const ALL_LABELS: ReadonlySet<string> = new Set([
|
|
|
328
334
|
ENHANCEMENT_LABEL,
|
|
329
335
|
BREAKING_CHANGE_LABEL,
|
|
330
336
|
IN_PROGRESS_LABEL,
|
|
337
|
+
PLANNED_LABEL,
|
|
331
338
|
NEEDS_DECISION_LABEL,
|
|
332
339
|
AUTO_OK_LABEL,
|
|
333
340
|
NEEDS_HUMAN_REVIEW_LABEL,
|
|
@@ -375,6 +382,7 @@ export {
|
|
|
375
382
|
NEEDS_HUMAN_REVIEW_LABEL,
|
|
376
383
|
NOT_DIRECTLY_RUNNABLE_LABELS,
|
|
377
384
|
OTHER_CHANGE_LABEL,
|
|
385
|
+
PLANNED_LABEL,
|
|
378
386
|
PRIORITY_HIGH_LABEL,
|
|
379
387
|
RELEASE_CLASSIFICATION_LABELS,
|
|
380
388
|
RELEASE_CLASSIFICATION_NAMES,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { git_gh_api_path } from '#scripts/
|
|
2
|
-
import { git_gh_exec } from '#scripts/
|
|
1
|
+
import { git_gh_api_path } from '#scripts/gh/git-gh-api-path'
|
|
2
|
+
import { git_gh_exec } from '#scripts/gh/git-gh-exec'
|
|
3
3
|
|
|
4
4
|
// Whether an issue was closed by a merge, read from its REST timeline (joshuafolkken/kit#2701). The
|
|
5
5
|
// issue's own `state_reason` cannot tell: a pull request's `closes #N` and a person's "Close as
|
|
@@ -83,7 +83,7 @@ function rank<T>(items: ReadonlyArray<T>, row_of: (item: T) => RankRow): Array<T
|
|
|
83
83
|
.map((entry) => entry.item)
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
const issue_rank = {
|
|
86
|
+
const issue_rank = { count_dependents, rank }
|
|
87
87
|
|
|
88
88
|
export { issue_rank }
|
|
89
89
|
export type { DependencyRow, RankRow }
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import { git_gh_command } from '#scripts/
|
|
3
|
+
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
4
4
|
import { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
5
5
|
import { issue_read, type IssueComment, type IssueFields } from './issue-read'
|
|
6
|
+
import { issue_report_failures, type ReadFailureKind } from './issue-report-failures'
|
|
6
7
|
|
|
7
8
|
// `josh issue:read <N> [<N> ...]` — the body *and* the comments of every issue named, in one call
|
|
8
9
|
// (joshuafolkken/kit#1715).
|
|
@@ -25,7 +26,6 @@ import { issue_read, type IssueComment, type IssueFields } from './issue-read'
|
|
|
25
26
|
// "no comments" — the block says which of the two it holds, because §2g's rule is that the later text
|
|
26
27
|
// wins, and a comment nobody read cannot win anything.
|
|
27
28
|
|
|
28
|
-
const SUCCESS_EXIT_CODE = 0
|
|
29
29
|
const FAILURE_EXIT_CODE = 1
|
|
30
30
|
const ARGV_OFFSET = 2
|
|
31
31
|
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
@@ -35,8 +35,7 @@ const BLOCK_SEPARATOR = '\n\n---\n\n'
|
|
|
35
35
|
// process, and an unbounded fan-out is answered with secondary rate limiting rather than with issues.
|
|
36
36
|
const READ_CONCURRENCY = 8
|
|
37
37
|
const ISSUE_FIELDS = 'title,state,body'
|
|
38
|
-
|
|
39
|
-
type ReadFailureKind = 'missing' | 'unreadable'
|
|
38
|
+
const FAILURE_TERMS = { success_kind: 'issue', misreading: 'the issue is empty' } as const
|
|
40
39
|
|
|
41
40
|
interface IssueContent {
|
|
42
41
|
fields: IssueFields
|
|
@@ -69,16 +68,6 @@ function parse_numbers(argv: ReadonlyArray<string>): ReadonlyArray<string> | und
|
|
|
69
68
|
return [...new Set(numbers)]
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
function report_failure(kind: ReadFailureKind, issue_number: string): void {
|
|
73
|
-
if (kind === 'missing') {
|
|
74
|
-
console.error(`✖ issue #${issue_number} does not resolve — check the number and the repository`)
|
|
75
|
-
} else {
|
|
76
|
-
console.error(
|
|
77
|
-
`✖ could not read issue #${issue_number} — a rate limit, expired auth, or a dropped connection. This is not "the issue is empty"`,
|
|
78
|
-
)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
71
|
// The comments are read beside the fields rather than after them: the two requests need nothing from
|
|
83
72
|
// one another, and reading them in sequence would put back one of the two round trips this command
|
|
84
73
|
// exists to remove.
|
|
@@ -126,34 +115,6 @@ function issue_blocks(report: IssueReport): ReadonlyArray<string> {
|
|
|
126
115
|
return [issue_read.format_issue(report.issue_number, fields, comments)]
|
|
127
116
|
}
|
|
128
117
|
|
|
129
|
-
function print_issues(reports: ReadonlyArray<IssueReport>): void {
|
|
130
|
-
const blocks = reports.flatMap((report) => issue_blocks(report))
|
|
131
|
-
|
|
132
|
-
if (blocks.length === 0) return
|
|
133
|
-
|
|
134
|
-
console.info(blocks.join(BLOCK_SEPARATOR))
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function report_one_failure(report: IssueReport): boolean {
|
|
138
|
-
if (report.result.kind === 'issue') return false
|
|
139
|
-
|
|
140
|
-
report_failure(report.result.kind, report.issue_number)
|
|
141
|
-
|
|
142
|
-
return true
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Every number that produced no issue is named, so a caller is told which ones it has no answer for
|
|
146
|
-
// rather than being left to subtract the printed blocks from what it asked.
|
|
147
|
-
function report_failures(reports: ReadonlyArray<IssueReport>): number {
|
|
148
|
-
let has_failure = false
|
|
149
|
-
|
|
150
|
-
for (const report of reports) {
|
|
151
|
-
has_failure = report_one_failure(report) || has_failure
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return has_failure ? FAILURE_EXIT_CODE : SUCCESS_EXIT_CODE
|
|
155
|
-
}
|
|
156
|
-
|
|
157
118
|
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
158
119
|
const issue_numbers = parse_numbers(argv)
|
|
159
120
|
|
|
@@ -165,9 +126,12 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
|
165
126
|
|
|
166
127
|
const reports = await read_all(issue_numbers)
|
|
167
128
|
|
|
168
|
-
|
|
129
|
+
issue_report_failures.print_blocks(
|
|
130
|
+
reports.flatMap((report) => issue_blocks(report)),
|
|
131
|
+
BLOCK_SEPARATOR,
|
|
132
|
+
)
|
|
169
133
|
|
|
170
|
-
return report_failures(reports)
|
|
134
|
+
return issue_report_failures.report_failures(reports, FAILURE_TERMS)
|
|
171
135
|
}
|
|
172
136
|
|
|
173
137
|
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
@@ -175,10 +139,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
175
139
|
}
|
|
176
140
|
|
|
177
141
|
const issue_read_cli = {
|
|
178
|
-
BLOCK_SEPARATOR,
|
|
179
|
-
ISSUE_FIELDS,
|
|
180
142
|
USAGE,
|
|
181
|
-
main,
|
|
182
143
|
parse_numbers,
|
|
183
144
|
read_block,
|
|
184
145
|
run,
|