@joshuafolkken/kit 1.1240.0 → 1.1370.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -0
- package/.claude/settings.json +4 -0
- package/.claude/skills/dependency-update/SKILL.md +5 -3
- package/.claude/skills/epic-commands/SKILL.md +82 -113
- package/.claude/skills/epic-commands/epic-bundle.md +38 -63
- package/.claude/skills/epic-commands/execution-waves.md +30 -51
- package/.claude/skills/verify-ui/SKILL.md +13 -20
- package/.claude/skills/workflow-commands/SKILL.md +10 -10
- package/.claude/skills/workflow-commands/background-commands.md +4 -4
- package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
- package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
- package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
- package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
- package/.claude/skills/workflow-commands/backlogrun.md +50 -61
- package/.claude/skills/workflow-commands/chain-rule.md +36 -40
- package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
- package/.claude/skills/workflow-commands/followup.md +19 -20
- package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
- package/.claude/skills/workflow-commands/fullrun.md +10 -10
- package/.claude/skills/workflow-commands/halfrun.md +9 -8
- package/.claude/skills/workflow-commands/into-target.md +12 -18
- package/.claude/skills/workflow-commands/issue-comments.md +11 -26
- package/.claude/skills/workflow-commands/kickoff.md +26 -16
- package/.claude/skills/workflow-commands/latest-gate.md +17 -28
- package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
- package/.claude/skills/workflow-commands/observation-filing.md +37 -28
- package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
- package/.claude/skills/workflow-commands/prerequisite.md +23 -15
- package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
- package/.claude/skills/workflow-commands/prrun.md +3 -3
- package/.claude/skills/workflow-commands/retrospective.md +13 -18
- package/.claude/skills/workflow-commands/split-assessment.md +6 -4
- package/.claude/skills/workflow-commands/target-repository.md +25 -28
- package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
- package/.gitattributes +2 -1
- package/.github/workflows/ci.yml +14 -0
- package/.vscode/tasks.json +14 -0
- package/CLAUDE.md +10 -61
- package/README.md +29 -47
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +10 -61
- package/dist/commands/document-section-cli.js +42 -10
- package/dist/config-merge/index.js +11 -2
- package/dist/hooks/audit-provision.js +2 -2
- package/dist/hooks/batch-guard.js +7 -7
- package/dist/hooks/{chunk-KHGB5S3Y.js → chunk-43G45XJF.js} +18 -20
- package/dist/hooks/{chunk-4TZVB44A.js → chunk-4TW4MQUL.js} +284 -362
- package/dist/hooks/{chunk-XZYKEM6J.js → chunk-76RK6E3H.js} +13 -11
- package/dist/hooks/{chunk-F3ELQ2AF.js → chunk-DZWZ3DKY.js} +4 -4
- package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
- package/dist/hooks/{chunk-GPTFMK5E.js → chunk-GG72ANKI.js} +1 -1
- package/dist/hooks/{chunk-ZQGD4GBY.js → chunk-KPM4YIIX.js} +8 -44
- package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
- package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
- package/dist/hooks/{chunk-QVSWU24O.js → chunk-NZBHG6FW.js} +7 -5
- package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
- package/dist/hooks/{chunk-KRBERBBI.js → chunk-R6CRQEAL.js} +4 -4
- package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
- package/dist/hooks/{chunk-WK2XSHSI.js → chunk-TLJYAGZK.js} +549 -874
- package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
- package/dist/hooks/codex-hook-adapter.js +26 -21
- package/dist/hooks/duplicate-read-guard.js +8 -8
- package/dist/hooks/format-edited.js +4 -4
- package/dist/hooks/inputs.json +216 -202
- package/dist/hooks/investigation-guard.js +8 -8
- package/dist/hooks/pretool-guard.js +15 -15
- package/dist/hooks/session-lang.js +406 -8
- package/dist/hooks/stop-guard.js +122 -187
- package/dist/josh.js +281 -94
- package/dist/version/index.js +15 -13
- package/eslint/base.js +43 -5
- package/eslint/rules/english-only-prose.js +3 -3
- package/eslint/rules/import.js +12 -0
- package/eslint/rules/namespace-object-export.js +2 -2
- package/package.json +16 -10
- package/pnpm-workspace.yaml +2 -4
- package/prompts/coding-standards.md +14 -48
- package/prompts/collaboration-workflow/file-edits.md +1 -1
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +3 -10
- package/prompts/collaboration-workflow/operating-rules.md +7 -8
- package/prompts/collaboration-workflow/output-bounds.md +1 -1
- package/prompts/collaboration-workflow/overview.md +1 -1
- package/prompts/collaboration-workflow/plan-comment.md +2 -1
- package/prompts/collaboration-workflow/principles.md +21 -3
- package/prompts/collaboration-workflow/report-format.md +16 -29
- package/prompts/collaboration-workflow/residency.md +1 -1
- package/prompts/collaboration-workflow/rule-delivery.md +7 -95
- package/prompts/collaboration-workflow/shell-body.md +3 -23
- package/prompts/collaboration-workflow/turn-batching.md +4 -13
- package/prompts/collaboration-workflow/wip-cap.md +5 -11
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +3 -22
- package/prompts/review.md +15 -38
- package/prompts/testing-guide.md +2 -4
- package/scripts/adopt/adopt-logic.ts +5 -5
- package/scripts/adopt/adopt-toolkits.ts +4 -5
- package/scripts/adopt/adopt.ts +2 -3
- package/scripts/agent/agent-argv.ts +7 -7
- package/scripts/agent/agent-diagnostics.ts +2 -2
- package/scripts/agent/agent-exit-record.ts +1 -1
- package/scripts/agent/agent-headless.ts +1 -1
- package/scripts/agent/agent-launch-environment.ts +6 -1
- package/scripts/agent/agent-role-profile.ts +49 -22
- package/scripts/agent/agent-session-role.ts +32 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/claude-agent-argv.ts +4 -4
- package/scripts/agent/claude-result-event.ts +4 -4
- package/scripts/agent/codex-hooks.ts +2 -2
- package/scripts/agent/interactive-ask.ts +3 -6
- package/scripts/auto-ok/auto-ok-cli.ts +46 -60
- package/scripts/backlog/backlog-arrival-added.ts +34 -0
- package/scripts/backlog/backlog-arrival.ts +54 -17
- package/scripts/backlog/backlog-budget-cli.ts +34 -6
- package/scripts/backlog/backlog-budget.ts +17 -24
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-args.ts +5 -4
- package/scripts/backlog/backlog-drive-cli.ts +14 -10
- package/scripts/backlog/backlog-drive-epic.ts +85 -0
- package/scripts/backlog/backlog-drive-launch.ts +1 -1
- package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
- package/scripts/backlog/backlog-drive-named.ts +39 -9
- package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
- package/scripts/backlog/backlog-drive-restore.ts +1 -1
- package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
- package/scripts/backlog/backlog-drive.ts +43 -28
- package/scripts/backlog/backlog-idle.ts +88 -0
- package/scripts/backlog/backlog-named.ts +11 -15
- package/scripts/backlog/backlog-next.ts +26 -30
- package/scripts/backlog/backlog-offer-cli.ts +28 -23
- package/scripts/backlog/backlog-offer.ts +7 -7
- package/scripts/backlog/backlog-overlap.ts +178 -0
- package/scripts/backlog/backlog-plan-cli.ts +14 -90
- package/scripts/backlog/backlog-plan-read.ts +111 -0
- package/scripts/backlog/backlog-plan.ts +11 -10
- package/scripts/backlog/backlog-pool.ts +13 -14
- package/scripts/backlog/backlog-rank.ts +11 -11
- package/scripts/backlog/backlog-ready.ts +15 -10
- package/scripts/backlog/backlog-scope.ts +14 -15
- package/scripts/backlog/backlog-stalled-cli.ts +2 -2
- package/scripts/backlog/backlog-stalled-detect.ts +4 -4
- package/scripts/backlog/backlog-stalled.ts +5 -6
- package/scripts/backlog/backlog-waves.ts +4 -4
- package/scripts/backlog/backlogrun-args.ts +74 -0
- package/scripts/backlog/backlogrun-cli.ts +113 -0
- package/scripts/backlog/backlogrun-launch.ts +178 -0
- package/scripts/behavior/behavior-assertion.ts +6 -8
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/behavior/behavior-rules.ts +3 -3
- package/scripts/build/build-claude-md.ts +4 -4
- package/scripts/build/build-codex-hooks.ts +2 -2
- package/scripts/build/build-commands.ts +1 -1
- package/scripts/build/build-hooks.ts +5 -5
- package/scripts/build/build.ts +1 -1
- package/scripts/build/hook-bundle-stamp.ts +109 -7
- package/scripts/build/local-bin.ts +2 -2
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +2 -2
- package/scripts/ci/composite-actions.ts +1 -2
- package/scripts/ci/pr-classification.ts +2 -2
- package/scripts/claude/workflow-destination.ts +1 -1
- package/scripts/clone/clone-aggregate.ts +1 -1
- package/scripts/clone/clone-fingerprint.ts +1 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/index.ts +1 -1
- package/scripts/config-merge/json-format.ts +1 -3
- package/scripts/config-merge/patch-json-array.ts +90 -0
- package/scripts/config-merge/patch-json-key.ts +6 -3
- package/scripts/config-merge/patch-json-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +1 -1
- package/scripts/cost-runtime/context-cut-payback.ts +4 -5
- package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
- package/scripts/cost-runtime/cost-attribute.ts +3 -3
- package/scripts/cost-runtime/cost-blocks.ts +3 -4
- package/scripts/cost-runtime/cost-cli.ts +14 -11
- package/scripts/cost-runtime/cost-corpus.ts +11 -11
- package/scripts/cost-runtime/cost-pricing.ts +4 -4
- package/scripts/cost-runtime/cost-tokens.ts +1 -2
- package/scripts/cost-runtime/cost-transcript.ts +29 -29
- package/scripts/cost-runtime/cost-usage.ts +6 -7
- package/scripts/cost-runtime/cost-verdict.ts +10 -11
- package/scripts/cost-runtime/own-session.ts +1 -1
- package/scripts/cost-runtime/transcript-cwd.ts +2 -2
- package/scripts/delegation/delegation-cli.ts +4 -4
- package/scripts/delegation/delegation-policy.ts +13 -15
- package/scripts/delegation/duplicate-read-guard.ts +9 -10
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +1 -1
- package/scripts/delegation/investigation-guard.ts +18 -22
- package/scripts/delegation/investigation-reads.ts +48 -238
- package/scripts/discovery/repo-discovery.ts +1 -1
- package/scripts/discovery/repo-map-logic.ts +1 -2
- package/scripts/discovery/repo-origin.ts +3 -3
- package/scripts/discovery/repo-party-cli.ts +2 -2
- package/scripts/discovery/repo-party.ts +2 -2
- package/scripts/doctor/doctor-consumer.ts +1 -1
- package/scripts/doctor/doctor-io.ts +6 -7
- package/scripts/doctor/doctor-logic.ts +1 -1
- package/scripts/doctor/doctor-ports.ts +1 -1
- package/scripts/doctor/doctor.ts +8 -9
- package/scripts/document/backlogrun-parent-read-set.ts +5 -6
- package/scripts/document/bash-output-cap.ts +5 -7
- package/scripts/document/capped-print-part.ts +1 -1
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/document-byte-budget.ts +33 -64
- package/scripts/document/document-byte-check.ts +4 -4
- package/scripts/document/document-reachability.ts +7 -8
- package/scripts/document/document-read-cli.ts +2 -2
- package/scripts/document/document-scan.ts +26 -2
- package/scripts/document/document-section-cli.ts +6 -8
- package/scripts/document/document-section.ts +8 -12
- package/scripts/document/edit-files-cli.ts +3 -4
- package/scripts/document/entry-read-budget.ts +8 -70
- package/scripts/document/entry-read-set.ts +51 -34
- package/scripts/document/lane-child-read-set.ts +9 -9
- package/scripts/document/read-files-cli.ts +1 -2
- package/scripts/document/read-set-cli.ts +16 -19
- package/scripts/document/read-set-cost.ts +4 -4
- package/scripts/document/read-set-point-of-use.ts +28 -38
- package/scripts/document/read-set-pricing.ts +1 -1
- package/scripts/document/read-set-trim.ts +3 -3
- package/scripts/document/resident-budget.ts +8 -10
- package/scripts/epic/epic-add-body.ts +15 -18
- package/scripts/epic/epic-add-plan.ts +26 -28
- package/scripts/epic/epic-add.ts +32 -25
- package/scripts/epic/epic-audit-checks.ts +27 -37
- package/scripts/epic/epic-audit-cli.ts +21 -22
- package/scripts/epic/epic-audit-orphans.ts +16 -17
- package/scripts/epic/epic-audit-rationale.ts +10 -15
- package/scripts/epic/epic-audit-report.ts +2 -5
- package/scripts/epic/epic-audit.ts +18 -14
- package/scripts/epic/epic-body.ts +10 -10
- package/scripts/epic/epic-bundle-cli.ts +36 -34
- package/scripts/epic/epic-bundle-evidence.ts +5 -5
- package/scripts/epic/epic-bundle-gaps.ts +6 -9
- package/scripts/epic/epic-bundle-poll.ts +1 -1
- package/scripts/epic/epic-bundle-referenced.ts +11 -14
- package/scripts/epic/epic-bundle.ts +19 -20
- package/scripts/epic/epic-busy.ts +44 -21
- package/scripts/epic/epic-candidate-confirm.ts +15 -18
- package/scripts/epic/epic-chains.ts +18 -23
- package/scripts/epic/epic-classify.ts +11 -12
- package/scripts/epic/epic-cli-argv.ts +5 -6
- package/scripts/epic/epic-cli-remove.ts +9 -4
- package/scripts/epic/epic-cli.ts +38 -26
- package/scripts/epic/epic-close-comment.ts +14 -15
- package/scripts/epic/epic-close.ts +25 -29
- package/scripts/epic/epic-cross-repo.ts +18 -21
- package/scripts/epic/epic-decision.ts +14 -18
- package/scripts/epic/epic-fetch.ts +25 -31
- package/scripts/epic/epic-graph.ts +15 -17
- package/scripts/epic/epic-index.ts +14 -16
- package/scripts/epic/epic-issue.ts +9 -11
- package/scripts/epic/epic-label-age.ts +74 -0
- package/scripts/epic/epic-lane-offer.ts +35 -24
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +8 -8
- package/scripts/epic/epic-next-views.ts +12 -12
- package/scripts/epic/epic-next.ts +29 -33
- package/scripts/epic/epic-outside-blocker.ts +11 -10
- package/scripts/epic/epic-parse.ts +22 -24
- package/scripts/epic/epic-promote.ts +3 -2
- package/scripts/epic/epic-rank.ts +1 -1
- package/scripts/epic/epic-read.ts +10 -8
- package/scripts/epic/epic-reconcile.ts +8 -6
- package/scripts/epic/epic-reference.ts +5 -4
- package/scripts/epic/epic-relation-recheck.ts +10 -11
- package/scripts/epic/epic-relations.ts +9 -8
- package/scripts/epic/epic-remove-plan.ts +4 -5
- package/scripts/epic/epic-remove.ts +7 -5
- package/scripts/epic/epic-report.ts +18 -20
- package/scripts/epic/epic-run.ts +6 -5
- package/scripts/epic/epic-sections.ts +2 -2
- package/scripts/epic/epic-shape.ts +3 -3
- package/scripts/epic/epic-solo-stale.ts +3 -2
- package/scripts/epic/epic-solo.ts +8 -8
- package/scripts/epic/epic-triage.ts +5 -4
- package/scripts/epic/epic-validate.ts +8 -7
- package/scripts/epic/epic.ts +5 -5
- package/scripts/exports/unused-members-cli.ts +1 -1
- package/scripts/followup/followup-issue-number.ts +1 -2
- package/scripts/followup/git-followup-cleanup.ts +6 -7
- package/scripts/followup/git-followup-finish.ts +11 -13
- package/scripts/followup/git-followup-flush.ts +11 -7
- package/scripts/followup/git-followup-issue-close.ts +16 -13
- package/scripts/followup/git-followup-label.ts +9 -6
- package/scripts/followup/git-followup-merged.ts +1 -1
- package/scripts/followup/git-followup-pending.ts +7 -9
- package/scripts/followup/git-followup-stages.ts +28 -17
- package/scripts/followup/git-followup-workflow.ts +19 -21
- package/scripts/followup/git-pr-followup-checks.ts +13 -20
- package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
- package/scripts/followup/git-pr-followup.ts +18 -17
- package/scripts/gate/core-admission.ts +2 -2
- package/scripts/gate/core-budget.ts +15 -26
- package/scripts/gate/gate-ledger.ts +114 -0
- package/scripts/gate/gate-log.ts +7 -9
- package/scripts/gate/gate-plan.ts +70 -35
- package/scripts/gate/gate-report.ts +14 -15
- package/scripts/gate/gate-skip.ts +11 -13
- package/scripts/gate/gate-steps.ts +5 -1
- package/scripts/gate/gate-tree.ts +3 -4
- package/scripts/gate/hook-gate-reuse.ts +9 -9
- package/scripts/gate/machine-capacity.ts +168 -30
- package/scripts/gate/pre-commit-type-check.ts +4 -4
- package/scripts/gate/project-checks.ts +12 -4
- package/scripts/gate/scoped-green.ts +11 -18
- package/scripts/gate/type-check-command.ts +2 -2
- package/scripts/gate/type-check-step.ts +4 -4
- package/scripts/gate/verification-gate.ts +53 -51
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/gh/git-ai-review-scan.ts +3 -2
- package/scripts/gh/git-gh-api-path.ts +10 -11
- package/scripts/gh/git-gh-exec.ts +43 -48
- package/scripts/gh/git-gh-failure.ts +6 -9
- package/scripts/gh/git-gh-helpers.ts +1 -1
- package/scripts/gh/git-gh-issue-list.ts +15 -19
- package/scripts/gh/git-gh-issue-read.ts +43 -60
- package/scripts/gh/git-gh-issue-rest.ts +14 -15
- package/scripts/gh/git-gh-issue-write.ts +52 -40
- package/scripts/gh/git-gh-issue.ts +23 -24
- package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
- package/scripts/gh/git-gh-pr-read.ts +46 -50
- package/scripts/gh/git-gh-pr-rest.ts +23 -26
- package/scripts/gh/git-gh-pr-review.ts +2 -2
- package/scripts/gh/git-gh-pr-rollup.ts +4 -4
- package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
- package/scripts/gh/git-gh-pr.ts +16 -16
- package/scripts/gh/git-gh-reachability.ts +11 -12
- package/scripts/gh/git-gh-repo.ts +2 -3
- package/scripts/gh/git-gh-rest-state.ts +1 -1
- package/scripts/gh/git-pr-ai-review.ts +6 -5
- package/scripts/gh/git-pr-checks-eval.ts +28 -30
- package/scripts/gh/git-pr-checks-parse.ts +14 -16
- package/scripts/gh/git-pr-checks-watch.ts +17 -17
- package/scripts/gh/git-pr-checks.ts +20 -23
- package/scripts/gh/git-pr-coderabbit.ts +8 -6
- package/scripts/gh/git-pr-confirmation.ts +5 -5
- package/scripts/gh/git-pr-managed-config.ts +7 -9
- package/scripts/gh/git-pr-messages.ts +1 -1
- package/scripts/gh/git-pr.ts +15 -16
- package/scripts/gh/github-issue-url.ts +8 -9
- package/scripts/git/base-tree.ts +66 -0
- package/scripts/git/change-base.ts +42 -2
- package/scripts/git/changed-file-scope.ts +5 -5
- package/scripts/git/changed-paths.ts +1 -2
- package/scripts/git/constants.ts +2 -2
- package/scripts/git/git-branch.ts +1 -1
- package/scripts/git/git-closes-keyword.ts +3 -3
- package/scripts/git/git-command.ts +53 -41
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +14 -15
- package/scripts/git/git-error.ts +1 -1
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/git/git-issue.ts +10 -8
- package/scripts/git/git-location-environment.ts +3 -4
- package/scripts/git/git-ls-remote.ts +6 -8
- package/scripts/git/git-pre-push-hook.ts +11 -10
- package/scripts/git/git-preflight.ts +5 -5
- package/scripts/git/git-push-transport.ts +2 -2
- package/scripts/git/git-remote-branch.ts +1 -2
- package/scripts/git/git-schemas.ts +16 -23
- package/scripts/git/git-spawn-sync.ts +1 -1
- package/scripts/git/git-spawn.ts +37 -14
- package/scripts/git/git-ssh-keepalive.ts +12 -5
- package/scripts/git/git-staging.ts +7 -8
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/git-worktree.ts +35 -27
- package/scripts/git/gone-branch.ts +2 -2
- package/scripts/git/listing-cutoff.ts +1 -2
- package/scripts/git/lockfile-sync.ts +65 -0
- package/scripts/git/main-merge-guard.ts +1 -2
- package/scripts/git/main-merge.ts +7 -7
- package/scripts/git/main-sync.ts +23 -8
- package/scripts/git/parse-json-array.ts +18 -23
- package/scripts/git/repository-lock.ts +34 -2
- package/scripts/git/stash/git-stash.ts +4 -5
- package/scripts/git/stash/stash-orphans.ts +5 -3
- package/scripts/git/stash/stash-pop-args.ts +1 -1
- package/scripts/git/stash/stash-pop-cli.ts +3 -3
- package/scripts/git/stash/stash-sweep-lock.ts +2 -2
- package/scripts/hooks/batch-guard.ts +11 -13
- package/scripts/hooks/check-commit-message.ts +12 -9
- package/scripts/hooks/codex-hook-adapter.ts +16 -10
- package/scripts/hooks/edited-cspell.ts +3 -4
- package/scripts/hooks/format-edited-cli.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +11 -17
- package/scripts/hooks/format-rewrite-notice.ts +19 -17
- package/scripts/hooks/pre-push-unit.ts +10 -14
- package/scripts/hooks/pretool-guard-cli.ts +4 -4
- package/scripts/hooks/pretool-guard.ts +93 -18
- package/scripts/hooks/reserved-run.ts +2 -2
- package/scripts/hooks/step-zero-notice.ts +1 -1
- package/scripts/hooks/stop-guard.ts +21 -10
- package/scripts/init/basic-path-migration.ts +2 -2
- package/scripts/init/claude-kit-only-settings.ts +2 -2
- package/scripts/init/claude-plugin-config.ts +2 -2
- package/scripts/init/distributed-paths.ts +4 -4
- package/scripts/init/hook-command-rewrite.ts +3 -3
- package/scripts/init/hook-launch.ts +5 -5
- package/scripts/init/init-actions.ts +13 -0
- package/scripts/init/init-ai-copy.ts +11 -11
- package/scripts/init/init-bootstrap.ts +3 -3
- package/scripts/init/init-copy-content.ts +4 -4
- package/scripts/init/init-logic-json-merge.ts +7 -9
- package/scripts/init/init-logic-migrate.ts +1 -1
- package/scripts/init/init-logic-templates.ts +1 -1
- package/scripts/init/init-logic-workspace.ts +4 -4
- package/scripts/init/init-logic-yaml-merge.ts +2 -2
- package/scripts/init/init-logic.ts +19 -22
- package/scripts/init/init.ts +7 -7
- package/scripts/init/kit-base-preset.ts +1 -1
- package/scripts/init/kit-setup-state.ts +1 -1
- package/scripts/init/kit-written-paths.ts +1 -2
- package/scripts/init/package-manager-pin.ts +1 -1
- package/scripts/init/project-profile-cli.ts +1 -1
- package/scripts/init/project-profile.ts +3 -3
- package/scripts/init/session-language-environment.ts +1 -1
- package/scripts/init/start-exec.ts +3 -4
- package/scripts/init/start-plan.ts +2 -2
- package/scripts/init/start-setup-pr.ts +3 -2
- package/scripts/init/start-steps.ts +2 -2
- package/scripts/init/tsconfig-preset-migration.ts +1 -1
- package/scripts/init/vscode-tasks.ts +62 -0
- package/scripts/issue/baseline-measure.ts +2 -2
- package/scripts/issue/behavior-change-lint.ts +2 -2
- package/scripts/issue/defect-rate-cli.ts +6 -7
- package/scripts/issue/defect-rate.ts +37 -27
- package/scripts/issue/git-next-issues.ts +9 -8
- package/scripts/issue/issue-auto-ok.ts +24 -11
- package/scripts/issue/issue-backlinks-cli.ts +5 -5
- package/scripts/issue/issue-backlinks.ts +6 -6
- package/scripts/issue/issue-cite-cli.ts +20 -18
- package/scripts/issue/issue-cite.ts +18 -8
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +6 -4
- package/scripts/issue/issue-file-cli.ts +52 -15
- package/scripts/issue/issue-file-fold.ts +155 -0
- package/scripts/issue/issue-file.ts +9 -6
- package/scripts/issue/issue-fold-cli.ts +14 -9
- package/scripts/issue/issue-fold.ts +23 -8
- package/scripts/issue/issue-labels.ts +34 -38
- package/scripts/issue/issue-lint-cli.ts +2 -2
- package/scripts/issue/issue-lint.ts +1 -1
- package/scripts/issue/issue-merged.ts +10 -4
- package/scripts/issue/issue-number-shape.ts +27 -0
- package/scripts/issue/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +4 -5
- package/scripts/issue/issue-read.ts +4 -5
- package/scripts/issue/issue-reference.ts +5 -5
- package/scripts/issue/issue-release-cli.ts +17 -7
- package/scripts/issue/issue-release.ts +3 -3
- package/scripts/issue/issue-report-failures.ts +7 -4
- package/scripts/issue/issue-scout-cli.ts +11 -11
- package/scripts/issue/issue-scout-closed.ts +4 -4
- package/scripts/issue/issue-scout.ts +4 -5
- package/scripts/issue/issue-state-cli.ts +17 -10
- package/scripts/issue/issue-state.ts +12 -13
- package/scripts/issue/issue-wip.ts +7 -7
- package/scripts/issue/markdown-section.ts +3 -3
- package/scripts/issue/measure-rerun-cli.ts +10 -9
- package/scripts/issue/reproduction-measure.ts +3 -3
- package/scripts/issue/session-cite.ts +56 -0
- package/scripts/josh/agent-session-environment.ts +10 -8
- package/scripts/josh/cli-body.ts +2 -2
- package/scripts/josh/command-suggest.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +20 -23
- package/scripts/josh/hook-decision.ts +24 -28
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +30 -35
- package/scripts/josh/josh-commands-ai.ts +6 -6
- package/scripts/josh/josh-commands-backlog.ts +15 -3
- package/scripts/josh/josh-commands-clone.ts +1 -1
- package/scripts/josh/josh-commands-development.ts +25 -4
- package/scripts/josh/josh-commands-document.ts +3 -3
- package/scripts/josh/josh-commands-guard.ts +3 -3
- package/scripts/josh/josh-commands-issue.ts +4 -5
- package/scripts/josh/josh-commands-lane.ts +14 -4
- package/scripts/josh/josh-commands-lint.ts +1 -1
- package/scripts/josh/josh-commands-run.ts +20 -6
- package/scripts/josh/josh-commands-split.ts +1 -2
- package/scripts/josh/josh-commands-versioning.ts +5 -5
- package/scripts/josh/josh-commands-workflow.ts +30 -22
- package/scripts/josh/josh-environment-file.ts +1 -1
- package/scripts/josh/josh-in-process.ts +3 -3
- package/scripts/josh/josh-logic.ts +6 -7
- package/scripts/josh/josh-run.ts +3 -3
- package/scripts/josh/josh-verdict.ts +9 -12
- package/scripts/josh/josh.ts +3 -3
- package/scripts/josh/kit-only.ts +2 -2
- package/scripts/josh/path-decision.ts +3 -3
- package/scripts/josh/platform-temporary.ts +7 -5
- package/scripts/josh/process-identity.ts +24 -6
- package/scripts/josh/process-owner.ts +4 -4
- package/scripts/josh/session-language-cli.ts +53 -11
- package/scripts/josh/session-language.ts +1 -1
- package/scripts/josh/stamp-file.ts +48 -29
- package/scripts/josh/stamp-record.ts +57 -0
- package/scripts/lane/lane-await.ts +35 -11
- package/scripts/lane/lane-cache.ts +6 -6
- package/scripts/lane/lane-capacity.ts +32 -17
- package/scripts/lane/lane-child-invocation.ts +17 -15
- package/scripts/lane/lane-child-marker.ts +12 -12
- package/scripts/lane/lane-cli.ts +12 -13
- package/scripts/lane/lane-close.ts +6 -6
- package/scripts/lane/lane-dispatch.ts +61 -72
- package/scripts/lane/lane-environment.ts +5 -5
- package/scripts/lane/lane-guard-policy.ts +7 -21
- package/scripts/lane/lane-handoff.ts +2 -2
- package/scripts/lane/lane-install.ts +9 -10
- package/scripts/lane/lane-launch-cli.ts +13 -8
- package/scripts/lane/lane-ledger.ts +73 -11
- package/scripts/lane/lane-leftover.ts +2 -2
- package/scripts/lane/lane-limit-cli.ts +160 -0
- package/scripts/lane/lane-limit-override.ts +74 -0
- package/scripts/lane/lane-load.ts +19 -68
- package/scripts/lane/lane-measure-cli.ts +15 -25
- package/scripts/lane/lane-occupancy.ts +6 -4
- package/scripts/lane/lane-open.ts +20 -19
- package/scripts/lane/lane-output.ts +4 -3
- package/scripts/lane/lane-paths.ts +12 -11
- package/scripts/lane/lane-phase.ts +33 -0
- package/scripts/lane/lane-reap.ts +2 -2
- package/scripts/lane/lane-registry.ts +16 -15
- package/scripts/lane/lane-relaunch.ts +9 -9
- package/scripts/lane/lane-report.ts +5 -4
- package/scripts/lane/lane-resume.ts +2 -2
- package/scripts/lane/lane-sampler.ts +55 -0
- package/scripts/lane/lane-seed.ts +7 -7
- package/scripts/lane/lane-stage-stats.ts +135 -0
- package/scripts/lane/lane-start-point.ts +8 -11
- package/scripts/lane/lane-stats.ts +60 -15
- package/scripts/lane/lane-stray.ts +1 -1
- package/scripts/lane/lane-vacant.ts +1 -1
- package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
- package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
- package/scripts/lane/openai-review-broker.ts +2 -4
- package/scripts/lib/ancestor-directories.ts +1 -1
- package/scripts/lib/bounded-pool.ts +2 -2
- package/scripts/lib/buffered-process.ts +4 -6
- package/scripts/lib/caddy-logs.sh +0 -0
- package/scripts/lib/cli-flags.ts +39 -6
- package/scripts/lib/error-message.ts +1 -1
- package/scripts/lib/json-value.ts +17 -3
- package/scripts/lib/poll.ts +1 -1
- package/scripts/lib/status-icons.ts +3 -3
- package/scripts/lib/timed-fetch.ts +1 -1
- package/scripts/lib/timeouts.ts +1 -1
- package/scripts/lines/bytes-command.ts +3 -4
- package/scripts/lines/effective-limit.ts +25 -12
- package/scripts/lines/line-budget.ts +47 -55
- package/scripts/lines/line-targets.ts +6 -2
- package/scripts/lines/lines-command.ts +3 -3
- package/scripts/lint/cspell-cached.ts +1 -1
- package/scripts/lint/cycle-recheck.ts +122 -0
- package/scripts/lint/format.ts +1 -2
- package/scripts/lint/lint-parallel.ts +34 -19
- package/scripts/lint/lint-related-scope.ts +25 -15
- package/scripts/lint/lint-related.ts +6 -7
- package/scripts/managed-marker/index.ts +1 -1
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/git-notify.ts +9 -7
- package/scripts/notify/telegram-notify.ts +53 -37
- package/scripts/notify/telegram-test-logic.ts +3 -3
- package/scripts/notify/telegram-test.ts +45 -30
- package/scripts/observations/observation-ledger-home.ts +14 -8
- package/scripts/observations/observation-ledger-line.ts +3 -2
- package/scripts/observations/observation-ledger-migrate.ts +3 -4
- package/scripts/observations/observation-ledger-prepare.ts +4 -4
- package/scripts/observations/observation-ledger.ts +14 -15
- package/scripts/observations/observation-record-cli.ts +83 -0
- package/scripts/observations/observation-record.ts +91 -0
- package/scripts/observations/observations-flush-cli.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +7 -6
- package/scripts/observations/observations-flush.ts +26 -27
- package/scripts/overrides/overrides-check.ts +18 -8
- package/scripts/package/package-scout-cli.ts +1 -1
- package/scripts/package/package-scout-format.ts +2 -2
- package/scripts/package/package-scout.ts +1 -1
- package/scripts/propagate/propagate-git-failure.ts +1 -1
- package/scripts/propagate/propagate-git.ts +7 -7
- package/scripts/propagate/propagate-plan.ts +2 -2
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +5 -7
- package/scripts/propagate/propagate-select.ts +1 -1
- package/scripts/propagate/propagate-steps.ts +19 -20
- package/scripts/propagate/propagate-targets.ts +6 -10
- package/scripts/propagate/propagate.ts +5 -5
- package/scripts/refactor/import-graph.ts +1 -1
- package/scripts/refactor/refactor-lint.ts +4 -10
- package/scripts/refactor/refactor-scan-cli.ts +1 -1
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +1 -1
- package/scripts/release/github-release-cli.ts +25 -3
- package/scripts/release/github-release-runs.ts +1 -1
- package/scripts/release/release-cli.ts +21 -4
- package/scripts/release/release-history.ts +6 -10
- package/scripts/release/release-plan.ts +3 -3
- package/scripts/release/release-progress.ts +3 -4
- package/scripts/release/release-publish.ts +8 -9
- package/scripts/release/release-scope-cli.ts +8 -10
- package/scripts/release/release-tag.ts +6 -8
- package/scripts/release/release-worktree.ts +5 -5
- package/scripts/repo/auto-merge-setting-logic.ts +7 -9
- package/scripts/repo/auto-merge-setting.ts +1 -1
- package/scripts/repo/repo-setting.ts +4 -4
- package/scripts/repo/repository-labels.ts +1 -1
- package/scripts/repo/required-checks-logic.ts +3 -3
- package/scripts/repo/required-checks-report.ts +1 -1
- package/scripts/repo/ruleset-check-cli.ts +1 -1
- package/scripts/repo/ruleset-check.ts +1 -1
- package/scripts/report/report-format-reference.ts +26 -0
- package/scripts/report/report-lint-cli.ts +2 -2
- package/scripts/report/report-lint.ts +16 -2
- package/scripts/review/disposition-cli.ts +2 -2
- package/scripts/review/disposition-logic.ts +1 -1
- package/scripts/review/live-evidence.ts +9 -6
- package/scripts/review/review-attest-cli.ts +1 -2
- package/scripts/review/review-attest.ts +3 -3
- package/scripts/review/review-brief-cli.ts +19 -20
- package/scripts/review/review-brief.ts +29 -32
- package/scripts/review/review-checkout.ts +2 -2
- package/scripts/review/review-diff-parts.ts +3 -5
- package/scripts/review/review-diff-write.ts +1 -1
- package/scripts/review/review-finding-ledger.ts +7 -4
- package/scripts/review/review-findings-cli.ts +2 -2
- package/scripts/review/review-level.ts +4 -7
- package/scripts/review/review-record-cli.ts +73 -16
- package/scripts/review/review-record.ts +5 -4
- package/scripts/review/review-round2-cli.ts +2 -3
- package/scripts/review/review-round2.ts +13 -21
- package/scripts/review/review-stamps.ts +9 -71
- package/scripts/review/review-tree.ts +4 -5
- package/scripts/rules/bash-triggers.ts +4 -4
- package/scripts/rules/decision-oracle-batch.ts +5 -6
- package/scripts/rules/decision-oracle-stage.ts +1 -1
- package/scripts/rules/decision-oracle-tokens.ts +1 -2
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +61 -406
- package/scripts/rules/destructive-command.ts +2 -2
- package/scripts/rules/direct-filing.ts +4 -4
- package/scripts/rules/direct-pr-create.ts +2 -2
- package/scripts/rules/early-heartbeat.ts +15 -19
- package/scripts/rules/file-body.ts +5 -6
- package/scripts/rules/filing-cap.ts +6 -7
- package/scripts/rules/filing-offer.ts +1 -1
- package/scripts/rules/firing-point.ts +6 -6
- package/scripts/rules/gh-api.ts +2 -2
- package/scripts/rules/git-argv.ts +3 -3
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/hook-context-line.ts +31 -0
- package/scripts/rules/implementation-cut-verdict.ts +5 -8
- package/scripts/rules/implementation-cut.ts +35 -32
- package/scripts/rules/index-guard.ts +2 -2
- package/scripts/rules/issue-citation.ts +7 -7
- package/scripts/rules/issue-comments.ts +21 -13
- package/scripts/rules/josh-git-bare.ts +2 -2
- package/scripts/rules/lane-background.ts +14 -16
- package/scripts/rules/lane-carry-conflict.ts +41 -5
- package/scripts/rules/lane-interactive-ask.ts +6 -9
- package/scripts/rules/lane-park.ts +12 -16
- package/scripts/rules/lane-split-park.ts +1 -2
- package/scripts/rules/lane-switch-main.ts +10 -13
- package/scripts/rules/last-prompt.ts +1 -1
- package/scripts/rules/oracle-consulted.ts +5 -5
- package/scripts/rules/oracle-firing.ts +6 -9
- package/scripts/rules/oracle-list-cli.ts +2 -2
- package/scripts/rules/permission-guards.ts +2 -2
- package/scripts/rules/piped-verification.ts +79 -9
- package/scripts/rules/poll-loop.ts +9 -11
- package/scripts/rules/pre-gate-cut.ts +33 -30
- package/scripts/rules/prior-comment-read.ts +3 -3
- package/scripts/rules/protected-files.ts +25 -13
- package/scripts/rules/raw-field-body.ts +3 -4
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +10 -12
- package/scripts/rules/rule-guard.ts +1 -1
- package/scripts/rules/rule-list.ts +51 -0
- package/scripts/rules/rule-registry-rows.ts +282 -0
- package/scripts/rules/rule-registry.ts +109 -0
- package/scripts/rules/rule-value-cache.ts +2 -2
- package/scripts/rules/rule-value-cli.ts +6 -4
- package/scripts/rules/rule-value.ts +61 -22
- package/scripts/rules/run-tail-rule.ts +11 -15
- package/scripts/rules/shell-body-trigger.ts +7 -7
- package/scripts/rules/shell-segments.ts +2 -4
- package/scripts/rules/stop-rules.ts +54 -41
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +2 -2
- package/scripts/rules/third-party-write.ts +3 -3
- package/scripts/rules/worktree-guard.ts +12 -5
- package/scripts/run/add/run-add-cli.ts +165 -0
- package/scripts/run/add/run-add.ts +124 -0
- package/scripts/run/board/run-board-cli.ts +207 -0
- package/scripts/run/board/run-board-closed.ts +95 -0
- package/scripts/run/board/run-board-every.ts +60 -0
- package/scripts/run/board/run-board-fetch.ts +38 -0
- package/scripts/run/board/run-board-fit.ts +219 -0
- package/scripts/run/board/run-board-github.ts +162 -0
- package/scripts/run/board/run-board-header.ts +275 -0
- package/scripts/run/board/run-board-kind.ts +35 -0
- package/scripts/run/board/run-board-labels.ts +299 -0
- package/scripts/run/board/run-board-layout.ts +222 -0
- package/scripts/run/board/run-board-link.ts +31 -0
- package/scripts/run/board/run-board-machine.ts +198 -0
- package/scripts/run/board/run-board-notes.ts +103 -0
- package/scripts/run/board/run-board-phase.ts +136 -0
- package/scripts/run/board/run-board-plan.ts +129 -0
- package/scripts/run/board/run-board-read.ts +62 -0
- package/scripts/run/board/run-board-render-legend.ts +82 -0
- package/scripts/run/board/run-board-render-notes.ts +77 -0
- package/scripts/run/board/run-board-render-slot.ts +50 -0
- package/scripts/run/board/run-board-render.ts +407 -0
- package/scripts/run/board/run-board-scope.ts +17 -0
- package/scripts/run/board/run-board-screen.ts +43 -0
- package/scripts/run/board/run-board-span.ts +66 -0
- package/scripts/run/board/run-board-spin.ts +115 -0
- package/scripts/run/board/run-board-state.ts +113 -0
- package/scripts/run/board/run-board-status.ts +279 -0
- package/scripts/run/board/run-board-tick.ts +210 -0
- package/scripts/run/board/run-board-track.ts +22 -0
- package/scripts/run/board/run-board-usage-read.ts +255 -0
- package/scripts/run/board/run-board-usage-rusage.ts +124 -0
- package/scripts/run/board/run-board-usage-text.ts +80 -0
- package/scripts/run/board/run-board-usage.ts +165 -0
- package/scripts/run/carry/run-carry-added.ts +62 -0
- package/scripts/run/carry/run-carry-args.ts +25 -22
- package/scripts/run/carry/run-carry-change.ts +1 -1
- package/scripts/run/carry/run-carry-cli.ts +71 -48
- package/scripts/run/carry/run-carry-conversation.ts +6 -7
- package/scripts/run/carry/run-carry-ended.ts +85 -0
- package/scripts/run/carry/run-carry-reclaim.ts +1 -1
- package/scripts/run/carry/run-carry-stash.ts +3 -2
- package/scripts/run/carry/run-carry-streak.ts +8 -10
- package/scripts/run/carry/run-carry.ts +85 -89
- package/scripts/run/cut/run-cut-args.ts +7 -7
- package/scripts/run/cut/run-cut-cli.ts +54 -36
- package/scripts/run/cut/run-cut-handoff.ts +15 -15
- package/scripts/run/cut/run-cut-report.ts +37 -16
- package/scripts/run/cut/run-cut.ts +63 -77
- package/scripts/run/detached-launch.ts +35 -50
- package/scripts/run/entry/run-entry-cli.ts +48 -27
- package/scripts/run/entry/run-entry-stop.ts +7 -9
- package/scripts/run/entry/run-entry.ts +5 -6
- package/scripts/run/event/run-event-cli.ts +5 -6
- package/scripts/run/event/run-event-filed.ts +69 -0
- package/scripts/run/event/run-event-follow.ts +3 -3
- package/scripts/run/event/run-event-plan.ts +38 -0
- package/scripts/run/event/run-event-render.ts +9 -4
- package/scripts/run/event/run-event-scope.ts +47 -18
- package/scripts/run/event/run-event-stream-emit.ts +64 -11
- package/scripts/run/event/run-event-stream.ts +171 -46
- package/scripts/run/event/run-event-watch.ts +4 -6
- package/scripts/run/hold/run-hold-cli.ts +65 -62
- package/scripts/run/hold/run-hold.ts +88 -46
- package/scripts/run/merge/run-merge-cli.ts +116 -77
- package/scripts/run/merge/run-merge-collect.ts +107 -0
- package/scripts/run/merge/run-merge-steps.ts +112 -65
- package/scripts/run/merge/run-merge-token.ts +30 -0
- package/scripts/run/merge/run-merge.ts +31 -22
- package/scripts/run/progress/run-progress-args.ts +4 -4
- package/scripts/run/progress/run-progress-cli.ts +39 -50
- package/scripts/run/progress/run-progress-clock.ts +25 -32
- package/scripts/run/progress/run-progress-config.ts +6 -9
- package/scripts/run/progress/run-progress-read.ts +9 -10
- package/scripts/run/progress/run-progress.ts +48 -53
- package/scripts/run/review/run-review-cli.ts +6 -6
- package/scripts/run/review/run-review-steps.ts +6 -6
- package/scripts/run/review/run-review.ts +9 -11
- package/scripts/run/run-cli-fault.ts +29 -0
- package/scripts/run/run-ending-cli.ts +3 -3
- package/scripts/run/run-ending.ts +10 -14
- package/scripts/run/run-halfrun-resume.ts +6 -8
- package/scripts/run/run-headless.ts +25 -12
- package/scripts/run/run-invocation.ts +17 -22
- package/scripts/run/run-label.ts +7 -5
- package/scripts/run/run-liveness-cli.ts +19 -6
- package/scripts/run/run-liveness.ts +27 -38
- package/scripts/run/run-next-cli.ts +5 -9
- package/scripts/run/run-next.ts +4 -5
- package/scripts/run/run-parent-cut-hook.ts +10 -12
- package/scripts/run/run-preflight.ts +25 -29
- package/scripts/run/run-prep-cli.ts +17 -13
- package/scripts/run/run-prep-locate.ts +4 -5
- package/scripts/run/run-prep.ts +7 -10
- package/scripts/run/run-prrun-resume.ts +2 -2
- package/scripts/run/run-report-cli.ts +4 -4
- package/scripts/run/run-report.ts +9 -14
- package/scripts/run/run-retrospective.ts +3 -3
- package/scripts/run/run-section.ts +42 -0
- package/scripts/run/run-stage-read.ts +2 -2
- package/scripts/run/run-stage.ts +6 -4
- package/scripts/run/run-status-cli.ts +7 -5
- package/scripts/run/run-status.ts +6 -7
- package/scripts/run/run-step-cli.ts +13 -15
- package/scripts/run/run-step.ts +58 -47
- package/scripts/run/run-stop-notify.ts +7 -8
- package/scripts/run/run-stranded-cli.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +4 -4
- package/scripts/run/run-stranded.ts +11 -13
- package/scripts/run/run-tail-cli.ts +15 -16
- package/scripts/run/run-tail.ts +14 -33
- package/scripts/run/run-watcher-guard-cli.ts +3 -4
- package/scripts/run/run-watcher-guard.ts +11 -12
- package/scripts/run/run-watcher-hook.ts +6 -12
- package/scripts/run/ship/run-ship-cli.ts +67 -33
- package/scripts/run/ship/run-ship-detach.ts +15 -13
- package/scripts/run/ship/run-ship-lock.ts +1 -1
- package/scripts/run/ship/run-ship-next.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
- package/scripts/run/ship/run-ship-preflight.ts +10 -11
- package/scripts/run/ship/run-ship-probe.ts +4 -4
- package/scripts/run/ship/run-ship-return.ts +1 -1
- package/scripts/run/ship/run-ship-review-steps.ts +43 -24
- package/scripts/run/ship/run-ship-review.ts +12 -14
- package/scripts/run/ship/run-ship-scoped.ts +15 -6
- package/scripts/run/ship/run-ship-stage.ts +80 -26
- package/scripts/run/ship/run-ship-steps.ts +26 -16
- package/scripts/run/ship/run-ship-stop-text.ts +4 -2
- package/scripts/run/ship/run-ship-sync.ts +9 -8
- package/scripts/run/ship/run-ship.ts +17 -32
- package/scripts/run/tidy/run-tidy-cli.ts +9 -5
- package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
- package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
- package/scripts/run/tidy/run-tidy.ts +4 -3
- package/scripts/run/wake/run-wake-cli.ts +27 -32
- package/scripts/run/wake/run-wake-describe.ts +24 -28
- package/scripts/run/wake/run-wake-driver.ts +14 -14
- package/scripts/run/wake/run-wake-handoff.ts +6 -6
- package/scripts/run/wake/run-wake-loop.ts +9 -9
- package/scripts/run/wake/run-wake-restart.ts +4 -5
- package/scripts/run/wake/run-wake-session.ts +23 -27
- package/scripts/run/wake/run-wake.ts +57 -279
- package/scripts/safe-chain/ci-installer-pin.ts +3 -3
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -2
- package/scripts/security/security-audit-logic.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +1 -1
- package/scripts/security/security-audit-provision.ts +2 -2
- package/scripts/security/security-audit.ts +5 -5
- package/scripts/security/security-updates-logic.ts +2 -3
- package/scripts/security/security-updates.ts +2 -4
- package/scripts/self-sync-guard/index.ts +1 -1
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
- package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
- package/scripts/sonar/sonar-hotspots.ts +1 -1
- package/scripts/sonar/sonar-new-code-cli.ts +1 -1
- package/scripts/sonar/sonar-new-code.ts +1 -1
- package/scripts/sonar/sonar-project.ts +1 -1
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +3 -3
- package/scripts/sync/directory-copy-guard.ts +2 -3
- package/scripts/sync/managed-config-scope-cli.ts +1 -2
- package/scripts/sync/managed-config-scope.ts +4 -4
- package/scripts/sync/plugin-skill-directories.ts +2 -2
- package/scripts/sync/reconcile-templates.ts +17 -8
- package/scripts/sync/removed-skill-manifest.ts +2 -3
- package/scripts/sync/sync-ai-files.ts +7 -7
- package/scripts/sync/sync-configs.ts +30 -3
- package/scripts/sync/sync-hook-safety.ts +2 -2
- package/scripts/sync/sync.ts +23 -10
- package/scripts/sync/synced-paths.ts +2 -1
- package/scripts/sync/workflow-pin-logic.ts +1 -1
- package/scripts/test/test-declared-changed.ts +4 -4
- package/scripts/test/test-declared-logic.ts +2 -3
- package/scripts/test/test-declared-match.ts +25 -4
- package/scripts/test/test-declared.ts +26 -9
- package/scripts/test/test-red-commit.ts +3 -2
- package/scripts/test/test-red-logic.ts +7 -14
- package/scripts/test/test-red.ts +12 -47
- package/scripts/test/test-related-scope.ts +2 -3
- package/scripts/test/test-related.ts +3 -3
- package/scripts/test/test-type-logic.ts +1 -2
- package/scripts/test/test-unit-guard.ts +13 -17
- package/scripts/test/unit-worker-share.ts +7 -8
- package/scripts/time-runtime/time-agent-bundles.ts +2 -4
- package/scripts/time-runtime/time-background.ts +17 -21
- package/scripts/time-runtime/time-batch-guard.ts +67 -342
- package/scripts/time-runtime/time-bundle-call.ts +26 -28
- package/scripts/time-runtime/time-bundles.ts +11 -12
- package/scripts/time-runtime/time-call-identity.ts +1 -1
- package/scripts/time-runtime/time-command-key.ts +2 -2
- package/scripts/time-runtime/time-density-hook.ts +8 -11
- package/scripts/time-runtime/time-density.ts +5 -5
- package/scripts/time-runtime/time-followup-stage.ts +7 -7
- package/scripts/time-runtime/time-format.ts +5 -5
- package/scripts/time-runtime/time-hook-transcript.ts +3 -3
- package/scripts/time-runtime/time-instant.ts +1 -1
- package/scripts/time-runtime/time-markers.ts +15 -19
- package/scripts/time-runtime/time-phase-names.ts +3 -3
- package/scripts/time-runtime/time-reported-failure.ts +15 -19
- package/scripts/time-runtime/time-round-trips.ts +20 -23
- package/scripts/time-runtime/time-shell.ts +8 -8
- package/scripts/time-runtime/time-single-check.ts +1 -2
- package/scripts/time-runtime/time-spans.ts +35 -40
- package/scripts/time-runtime/time-tool-call.ts +15 -16
- package/scripts/time-runtime/time-transcript-line.ts +53 -34
- package/scripts/time-runtime/time-writes.ts +5 -5
- package/scripts/ui/ui-routes-cli.ts +1 -2
- package/scripts/ui/ui-routes.ts +1 -2
- package/scripts/version/bump-version.ts +1 -1
- package/scripts/version/fresh-metadata-cache.ts +2 -2
- package/scripts/version/latest-corepack.ts +26 -26
- package/scripts/version/latest-lane-guard.ts +1 -1
- package/scripts/version/latest-scope-cli.ts +2 -2
- package/scripts/version/latest-stamp.ts +1 -2
- package/scripts/version/latest-update.ts +2 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/package-manager-version.ts +18 -0
- package/scripts/version/publishable-range-check.ts +2 -1
- package/scripts/version/publishable-range.ts +1 -1
- package/scripts/version/release-age.ts +11 -11
- package/scripts/version/release-hold.ts +2 -2
- package/scripts/version/safe-chain-version-update.ts +3 -3
- package/scripts/version/version-check-logic.ts +2 -3
- package/scripts/version/version-check.ts +1 -2
- package/scripts/version/version-command-config.ts +2 -2
- package/scripts/version/version-commands.ts +3 -3
- package/scripts/version/version-remote.ts +4 -4
- package/scripts/version/version-targets.ts +2 -2
- package/templates/gitignore +7 -0
- package/dist/hooks/chunk-KHX4U3BG.js +0 -6400
- package/dist/hooks/chunk-RKUAD3I6.js +0 -90
- package/dist/hooks/chunk-WPALEIRX.js +0 -18
- package/scripts/backlog/backlog-restructure.ts +0 -152
- package/scripts/rules/issue-fold-rule.ts +0 -72
- package/scripts/rules/wip-cap.ts +0 -63
- package/scripts/run/run-issue-number.ts +0 -19
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
// `epic:next` has to build this graph anyway to decide what is runnable, so the anomaly checks live
|
|
12
12
|
// here rather than in a separate auditor: a cycle makes every session wait forever, and a body that
|
|
13
13
|
// declares one order while the `blocked-by` relations record another means the implementation would
|
|
14
|
-
// proceed in an order nobody agreed to
|
|
14
|
+
// proceed in an order nobody agreed to.
|
|
15
15
|
|
|
16
16
|
// One child, as the graph sees it. `repo` is the `owner/repo` the child lives in, so a caller can
|
|
17
17
|
// bundle candidates per repository.
|
|
18
18
|
//
|
|
19
|
-
// `blocked_by` carries the native relations **with their repository**, not as bare numbers
|
|
20
|
-
//
|
|
19
|
+
// `blocked_by` carries the native relations **with their repository**, not as bare numbers.
|
|
20
|
+
// A relation may cross a repository — REST records and returns one — and a
|
|
21
21
|
// number alone cannot say which repository it names, so a bare read resolved every blocker against
|
|
22
22
|
// the blocked child's own repository. A cross-repository blocker then keyed to an issue that does not
|
|
23
23
|
// exist, `blocker_categories` dropped it, and the child ran as though nothing blocked it. It also
|
|
@@ -41,15 +41,15 @@ interface GraphAnomaly {
|
|
|
41
41
|
// Set when the reads behind this anomaly failed on the transport, so a caller can ask again
|
|
42
42
|
// instead of reporting an unusable graph. It travels from the failed request itself rather than
|
|
43
43
|
// from a probe fired afterwards, which is what let a connection that recovered in a few hundred
|
|
44
|
-
// milliseconds report the graph as permanently broken
|
|
44
|
+
// milliseconds report the graph as permanently broken.
|
|
45
45
|
is_unreachable?: boolean
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// An issue's identity across the whole epic. Issue numbers are unique per repository, not globally:
|
|
49
49
|
// an epic tracking both `#7` and `app-kit#7` has two different children, and keying by number alone
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
// one function rather than a second spelling of it
|
|
50
|
+
// would have them overwrite each other — and one's blockers resolve against the other.
|
|
51
|
+
// The audit keys the issues its children *cite* the same way, through this
|
|
52
|
+
// one function rather than a second spelling of it.
|
|
53
53
|
function reference_key(repo: string, issue_number: number): string {
|
|
54
54
|
return `${repo}${to_issue_reference(issue_number)}`
|
|
55
55
|
}
|
|
@@ -61,13 +61,11 @@ function key_of(reference: IssueReference): string {
|
|
|
61
61
|
|
|
62
62
|
// How a reference is written in a message. Bare inside the repository the command runs in — the form
|
|
63
63
|
// every body writes and every existing message used — and `owner/repo#N` outside it, because a bare
|
|
64
|
-
// number resolves against the reader's own repository and names a different issue there
|
|
65
|
-
// (joshuafolkken/kit#864).
|
|
64
|
+
// number resolves against the reader's own repository and names a different issue there.
|
|
66
65
|
//
|
|
67
66
|
// It lives here rather than in the audit, beside the key it is the readable half of: `epic:next`
|
|
68
67
|
// reports the children it could not read too, and a second spelling there would print a bare `#7`
|
|
69
|
-
// for a child in another repository — the very misreading this exists to prevent
|
|
70
|
-
// (joshuafolkken/kit#1016).
|
|
68
|
+
// for a child in another repository — the very misreading this exists to prevent.
|
|
71
69
|
function format_reference(reference: IssueReference, current_repo: string): string {
|
|
72
70
|
const is_local = reference.repo === '' || reference.repo === current_repo
|
|
73
71
|
|
|
@@ -81,9 +79,9 @@ function format_references(
|
|
|
81
79
|
return join_references(references.map((reference) => format_reference(reference, current_repo)))
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
// A blocker's key, read from the blocker's own repository rather than from the child it blocks
|
|
85
|
-
//
|
|
86
|
-
//
|
|
82
|
+
// A blocker's key, read from the blocker's own repository rather than from the child it blocks.
|
|
83
|
+
// The child is not part of the answer: taking the repository from it
|
|
84
|
+
// would send a cross-repository blocker to this repository's issue of that number.
|
|
87
85
|
function blocker_key(blocker: IssueReference): string {
|
|
88
86
|
return key_of(blocker)
|
|
89
87
|
}
|
|
@@ -140,7 +138,7 @@ function find_stuck_children(children: ReadonlyArray<EpicChild>): Array<string>
|
|
|
140
138
|
//
|
|
141
139
|
// Declared links are always written as bare numbers, which name issues in the epic's own repository —
|
|
142
140
|
// so the blocker they name is matched against that repository rather than against any relation that
|
|
143
|
-
// happens to carry the number
|
|
141
|
+
// happens to carry the number.
|
|
144
142
|
function is_link_recorded(
|
|
145
143
|
link: DependencyLink,
|
|
146
144
|
children: ReadonlyArray<EpicChild>,
|
|
@@ -171,7 +169,7 @@ function missing_relations(
|
|
|
171
169
|
// The other half: declared links a relation actually backs. It is what a caller about to *drop*
|
|
172
170
|
// relations needs — asking `gh` to remove a link that was never recorded is reported as a failure
|
|
173
171
|
// nobody can act on. Written beside `missing_relations` rather than as a subtraction in each caller,
|
|
174
|
-
// so the two answers cannot come to disagree about what "recorded" means
|
|
172
|
+
// so the two answers cannot come to disagree about what "recorded" means.
|
|
175
173
|
function recorded_relations(
|
|
176
174
|
links: ReadonlyArray<DependencyLink>,
|
|
177
175
|
children: ReadonlyArray<EpicChild>,
|
|
@@ -182,7 +180,7 @@ function recorded_relations(
|
|
|
182
180
|
|
|
183
181
|
// Every relation recorded on one child, as links between children of this epic.
|
|
184
182
|
//
|
|
185
|
-
// Matched by identity rather than by number
|
|
183
|
+
// Matched by identity rather than by number: keyed by number alone, a child
|
|
186
184
|
// in another repository whose number happened to equal a blocker's was reported as a relation nobody
|
|
187
185
|
// recorded. Only relations inside the declared repository become links, because a declared link is
|
|
188
186
|
// written as a bare number and has no way to name one that crosses a repository.
|
|
@@ -6,9 +6,9 @@ import { EPIC_LABEL, has_any_label } from '#scripts/issue/issue-labels'
|
|
|
6
6
|
import { z } from 'zod'
|
|
7
7
|
import { epic_parse } from './epic-parse'
|
|
8
8
|
|
|
9
|
-
// Which epic tracks which issue — the one answer, in one place
|
|
9
|
+
// Which epic tracks which issue — the one answer, in one place.
|
|
10
10
|
//
|
|
11
|
-
// `epic:bundle`
|
|
11
|
+
// `epic:bundle` asks it to keep an issue an epic already tracks
|
|
12
12
|
// from being recommended a second one. The `auto-ok` pickup needs the same answer for the opposite
|
|
13
13
|
// reason: an issue tracked by an epic that will offer it must run through that epic's order and
|
|
14
14
|
// never be picked up standalone. Two callers, one question, so the read and the index live here
|
|
@@ -27,7 +27,7 @@ interface FetchedEpics {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// Which epics track each issue, from the epics' own task lists. **A child can be named by more than
|
|
30
|
-
// one
|
|
30
|
+
// one**: a task list expresses at most one epic per row, and nothing stops
|
|
31
31
|
// two epics writing the same row — `epic_lane_offer.dedupe_pools` has handled exactly that collision
|
|
32
32
|
// on the `epic:next` side since it was written. So the tracking is recorded whole here, and each
|
|
33
33
|
// caller collapses it for its own question rather than losing the other epics at build time.
|
|
@@ -104,8 +104,8 @@ function child_epics_of(
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
// Every epic an `auto-ok` root opts in — the root itself and, transitively, every nested epic reached
|
|
107
|
-
// through its task list and theirs in turn
|
|
108
|
-
// to approve everything under it, and the direct-children-only reading
|
|
107
|
+
// through its task list and theirs in turn. A person puts `auto-ok` on a root
|
|
108
|
+
// to approve everything under it, and the direct-children-only reading stopped
|
|
109
109
|
// one level short: a grandchild fell out as "not opted in", though the same reasoning that admits the
|
|
110
110
|
// child admits it. So the root's approval is read down the whole subtree rather than one level of it.
|
|
111
111
|
//
|
|
@@ -132,32 +132,30 @@ function reachable_epic_numbers(
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
// **Which wins when an epic's declared order and a child's own `auto-ok` disagree — the single
|
|
135
|
-
// source
|
|
135
|
+
// source**.
|
|
136
136
|
//
|
|
137
137
|
// The epic wins wherever the epic is actually going to offer the child, and only there. So the
|
|
138
138
|
// standalone half withholds a tracked child when the epic tracking it carries `auto-ok`: that epic's
|
|
139
139
|
// `blocked-by` graph sequences its children, and offering the child standalone as well would both
|
|
140
140
|
// skip that order and hand the same issue over twice.
|
|
141
141
|
//
|
|
142
|
-
// It withholds nothing when the tracking epic is **not** opted in.
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
// on the child silently inert — no path offered it at all, because the epic side never reads an epic
|
|
148
|
-
// that did not opt in.
|
|
142
|
+
// It withholds nothing when the tracking epic is **not** opted in. The standalone route keeps the
|
|
143
|
+
// order: `auto_ok_cli.is_runnable` refuses a candidate whose `blockedBy` is still open, and
|
|
144
|
+
// `josh epic --ordered` records an epic's declared order as exactly those native relations. Withholding
|
|
145
|
+
// that child too would leave a person's `auto-ok` on it silently inert — no path would offer it at
|
|
146
|
+
// all, because the epic side never reads an epic that did not opt in.
|
|
149
147
|
// **It answers with the epic, not merely with membership**, because the withholding and the sentence
|
|
150
148
|
// `backlog:plan` prints about it have to come from one answer. Handing the scope layer the whole
|
|
151
|
-
// index instead let it name an epic that was not withholding anything
|
|
149
|
+
// index instead would let it name an epic that was not withholding anything.
|
|
152
150
|
//
|
|
153
|
-
// **Any one opted-in epic withholds the child
|
|
151
|
+
// **Any one opted-in epic withholds the child**. It reads the whole tracking
|
|
154
152
|
// rather than one collapsed winner because the two are not the same answer when two epics name the
|
|
155
153
|
// same child: collapsed, an opted-in epic that merely came earlier in the listing is gone, the child
|
|
156
154
|
// reads as tracked by nobody who would offer it, and the standalone half hands it over while the
|
|
157
155
|
// opted-in epic hands it over too. The epic named as the reason is the first opted-in one in listing
|
|
158
156
|
// order — any of them is withholding it, and picking by position keeps the sentence deterministic.
|
|
159
157
|
//
|
|
160
|
-
// **The opted-in set is the transitive closure, not one level of it
|
|
158
|
+
// **The opted-in set is the transitive closure, not one level of it**. A
|
|
161
159
|
// child of a nested epic is withheld from the standalone half exactly when that nested epic is one the
|
|
162
160
|
// backlog is going to offer — which, since the closure reaches it, it now is. Withholding only the
|
|
163
161
|
// direct roots' children here would leave a nested epic's child offered both through the epic and
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { git_gh_issue_rest } from '#scripts/gh/git-gh-issue-rest'
|
|
2
2
|
import { blocked_by_schema } from '#scripts/git/git-schemas'
|
|
3
|
-
import {
|
|
3
|
+
import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
|
|
4
4
|
import { z } from 'zod'
|
|
5
5
|
import type { IssueReference } from './epic-reference'
|
|
6
6
|
|
|
7
7
|
// The shapes one issue is read as, and the argument every epic command takes.
|
|
8
8
|
//
|
|
9
|
-
// The read goes through `gh api` (REST)
|
|
10
|
-
//
|
|
11
|
-
// the ones they always were.
|
|
9
|
+
// The read goes through `gh api` (REST); `git-gh-issue-rest.ts` maps the response back into the
|
|
10
|
+
// field names `gh issue view --json …` uses, so the shapes below are those.
|
|
12
11
|
//
|
|
13
12
|
// Single-sourced because three commands read the same JSON and take the same argument. Each had its
|
|
14
13
|
// own copy of the schema, the `blockedBy` unwrapping and the number parser, which is three places to
|
|
15
|
-
// fix the next time `gh` changes shape — and the one place a divergence would not be noticed
|
|
16
|
-
// (joshuafolkken/kit#862).
|
|
14
|
+
// fix the next time `gh` changes shape — and the one place a divergence would not be noticed.
|
|
17
15
|
|
|
18
16
|
const label_schema = z.object({ name: z.string() })
|
|
19
17
|
|
|
@@ -33,7 +31,7 @@ const epic_issue_schema = z.object({
|
|
|
33
31
|
state: z.string().default(UNKNOWN_STATE),
|
|
34
32
|
// The issue endpoint answers for a pull request as readily as for an issue, and nothing in the
|
|
35
33
|
// other fields separates them — an open PR reports `state: OPEN`, a merged one `MERGED`. The URL
|
|
36
|
-
// is what says which it is: `/pull/<n>` against `/issues/<n
|
|
34
|
+
// is what says which it is: `/pull/<n>` against `/issues/<n>`.
|
|
37
35
|
url: z.string().default(''),
|
|
38
36
|
labels: z.array(label_schema).default([]),
|
|
39
37
|
blockedBy: blocked_by_schema,
|
|
@@ -47,14 +45,14 @@ function parse_epic_issue(raw: string | undefined): EpicIssue | undefined {
|
|
|
47
45
|
if (raw === undefined) return undefined
|
|
48
46
|
|
|
49
47
|
try {
|
|
50
|
-
return
|
|
48
|
+
return parse_json_object_or_undefined(raw, epic_issue_schema)
|
|
51
49
|
} catch {
|
|
52
50
|
return undefined
|
|
53
51
|
}
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
// The blockers an issue declares, unwrapped from the connection and carrying the repository each one
|
|
57
|
-
// lives in
|
|
55
|
+
// lives in.
|
|
58
56
|
//
|
|
59
57
|
// `fallback_repo` is what an unqualified relation has always meant: the repository the issue itself is
|
|
60
58
|
// read in. REST names the blocker's repository in `repository_url`, and a relation may cross one — so
|
|
@@ -63,7 +61,7 @@ function parse_epic_issue(raw: string | undefined): EpicIssue | undefined {
|
|
|
63
61
|
//
|
|
64
62
|
// The parameter is narrowed to the one field this reads, so a caller holding a differently-shaped
|
|
65
63
|
// issue — `backlog-pool.ts`'s standalone rows arrive as `OpenIssueData` — resolves through this same
|
|
66
|
-
// function instead of repeating the `repository_url` unwrapping
|
|
64
|
+
// function instead of repeating the `repository_url` unwrapping.
|
|
67
65
|
function blocker_references_of(
|
|
68
66
|
issue: Pick<EpicIssue, 'blockedBy'>,
|
|
69
67
|
fallback_repo = '',
|
|
@@ -112,7 +110,7 @@ function parse_epic_number(raw = ''): number | undefined {
|
|
|
112
110
|
//
|
|
113
111
|
// A cross-repository epic must be qualified. A bare `#858` resolves to *this* repository's issue 858
|
|
114
112
|
// — a different issue entirely — so reading it as the other repository's would silently point at the
|
|
115
|
-
// wrong thing
|
|
113
|
+
// wrong thing.
|
|
116
114
|
interface EpicReference {
|
|
117
115
|
repo?: string
|
|
118
116
|
number: number
|
|
@@ -0,0 +1,74 @@
|
|
|
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 { IN_PROGRESS_LABEL } from '#scripts/issue/issue-labels'
|
|
4
|
+
|
|
5
|
+
// How long each lane holder has carried `in-progress`. The stale-label rule
|
|
6
|
+
// in `backlogrun-progress.md` is applied by age, and until this read the age was a hand-written
|
|
7
|
+
// `gh api …/timeline` query a parent ran per holder. `epic:next` now prints it beside each holder, so
|
|
8
|
+
// the number the rule is applied against is the one the scheduler already showed.
|
|
9
|
+
//
|
|
10
|
+
// **Read only in `epic:next`'s offer, and only when it names holders.** A timeline read per holder is
|
|
11
|
+
// a request per lane, so the listing polled by `run:progress` / `backlog:next` does not pay it.
|
|
12
|
+
|
|
13
|
+
// Matches the `Stale \`in-progress\`` row of the table in `backlogrun-progress.md`.
|
|
14
|
+
const STALE_MINUTES = 90
|
|
15
|
+
const MS_PER_MINUTE = 60_000
|
|
16
|
+
const TIMELINE_PAGE = 100
|
|
17
|
+
|
|
18
|
+
const LABELED_FILTER = `.[] | select(.event == "labeled" and (.label.name | ascii_downcase) == "${IN_PROGRESS_LABEL}") | .created_at`
|
|
19
|
+
|
|
20
|
+
// The newest time the label was applied. `absent` is a timeline holding no such event — the label is
|
|
21
|
+
// older than what the timeline keeps — and `unread` is a timeline that could not be read at all. Kept
|
|
22
|
+
// apart because only the first is a reason to call the label stale.
|
|
23
|
+
type LabeledAt = { kind: 'at'; at: string } | { kind: 'absent' } | { kind: 'unread' }
|
|
24
|
+
|
|
25
|
+
async function read_labeled_at(issue: number, repo: string): Promise<LabeledAt> {
|
|
26
|
+
try {
|
|
27
|
+
const raw = await git_gh_exec.exec_gh_api({
|
|
28
|
+
path: `${git_gh_api_path.issue_api_path(String(issue), repo)}/timeline?per_page=${String(TIMELINE_PAGE)}`,
|
|
29
|
+
should_paginate: true,
|
|
30
|
+
jq_filter: LABELED_FILTER,
|
|
31
|
+
})
|
|
32
|
+
const at = raw.split('\n').findLast((line) => line.trim() !== '')
|
|
33
|
+
|
|
34
|
+
return at === undefined ? { kind: 'absent' } : { kind: 'at', at }
|
|
35
|
+
} catch {
|
|
36
|
+
return { kind: 'unread' }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function age_text(labeled_at: LabeledAt, now: Date): string {
|
|
41
|
+
if (labeled_at.kind === 'unread') return 'label age unread'
|
|
42
|
+
if (labeled_at.kind === 'absent') return `${IN_PROGRESS_LABEL} older than the timeline — stale`
|
|
43
|
+
|
|
44
|
+
const minutes = Math.floor((now.getTime() - Date.parse(labeled_at.at)) / MS_PER_MINUTE)
|
|
45
|
+
const stale = minutes > STALE_MINUTES ? ' — stale' : ''
|
|
46
|
+
|
|
47
|
+
return `${IN_PROGRESS_LABEL} for ${String(minutes)} min${stale}`
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function read_ages(
|
|
51
|
+
issues: ReadonlyArray<number>,
|
|
52
|
+
repo: string,
|
|
53
|
+
now: Date,
|
|
54
|
+
): Promise<ReadonlyMap<number, string>> {
|
|
55
|
+
const ages = await Promise.all(
|
|
56
|
+
issues.map(async (issue) => {
|
|
57
|
+
const labeled_at = await read_labeled_at(issue, repo)
|
|
58
|
+
|
|
59
|
+
return [issue, age_text(labeled_at, now)] as const
|
|
60
|
+
}),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return new Map(ages)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const epic_label_age = {
|
|
67
|
+
STALE_MINUTES,
|
|
68
|
+
read_labeled_at,
|
|
69
|
+
age_text,
|
|
70
|
+
read_ages,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type { LabeledAt }
|
|
74
|
+
export { epic_label_age }
|
|
@@ -6,26 +6,23 @@ import {
|
|
|
6
6
|
type RepoAnswer,
|
|
7
7
|
} from './epic-candidate-confirm'
|
|
8
8
|
import { epic_graph, type EpicChild } from './epic-graph'
|
|
9
|
+
import { epic_label_age } from './epic-label-age'
|
|
9
10
|
import { epic_rank } from './epic-rank'
|
|
10
11
|
import type { EpicVerdict } from './epic-report'
|
|
11
12
|
import { epic_solo } from './epic-solo'
|
|
12
13
|
import { epic_solo_stale } from './epic-solo-stale'
|
|
13
14
|
import { epic_triage, type TriageVerdict } from './epic-triage'
|
|
14
15
|
|
|
15
|
-
// Which children a repository has room to start right now
|
|
16
|
+
// Which children a repository has room to start right now.
|
|
16
17
|
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
// own checkout, so the question became how many are free — the repository's occupancy counted from
|
|
20
|
-
// GitHub, compared against `lane_capacity`'s limit.
|
|
18
|
+
// A lane is its own checkout, so the question is how many are free — the repository's occupancy
|
|
19
|
+
// counted from GitHub, compared against `lane_capacity`'s limit.
|
|
21
20
|
//
|
|
22
21
|
// **The pool takes several sources, and none of them is an epic.** `RepoPool` is a candidate list
|
|
23
|
-
// with the context needed to confirm it.
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
// is
|
|
27
|
-
// thing several sources did add is `dedupe_pools` below — two epics can name the same child, and one
|
|
28
|
-
// child is one lane.
|
|
22
|
+
// with the context needed to confirm it. `epic:next` builds one per named epic and passes them all;
|
|
23
|
+
// the signatures never learn what an epic is, because once the guarded resource is the lane rather
|
|
24
|
+
// than the repository, which epic a child came from stops mattering. The one thing several sources
|
|
25
|
+
// add is `dedupe_pools` below — two epics can name the same child, and one child is one lane.
|
|
29
26
|
|
|
30
27
|
const WAIT_VERDICT: EpicVerdict = 'wait'
|
|
31
28
|
const RUN_VERDICT: EpicVerdict = 'run'
|
|
@@ -83,11 +80,24 @@ function offered_notice(
|
|
|
83
80
|
children: ReadonlyArray<EpicChild>,
|
|
84
81
|
read: BusyRead,
|
|
85
82
|
request: LaneRequest,
|
|
83
|
+
ages: ReadonlyMap<number, string>,
|
|
86
84
|
): string {
|
|
87
85
|
if (children.length === NO_LANES) return withheld_message(request.repo)
|
|
88
86
|
if (read.kind !== 'busy') return ''
|
|
89
87
|
|
|
90
|
-
return epic_busy.occupancy_message(read.issues, request.repo, request.limit)
|
|
88
|
+
return epic_busy.occupancy_message(read.issues, request.repo, request.limit, ages)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Each holder's label age, read only when there are holders to print — a
|
|
92
|
+
// timeline request per lane is paid for nothing on a read that names no one.
|
|
93
|
+
async function holder_ages(read: BusyRead, repo: string): Promise<ReadonlyMap<number, string>> {
|
|
94
|
+
if (read.kind !== 'busy') return new Map()
|
|
95
|
+
|
|
96
|
+
return await epic_label_age.read_ages(
|
|
97
|
+
read.issues.map((issue) => issue.number),
|
|
98
|
+
repo,
|
|
99
|
+
new Date(),
|
|
100
|
+
)
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
// Two pools that both offered nothing can disagree about why, and the answer has to be the one that
|
|
@@ -102,7 +112,7 @@ function combine_verdicts(left: EpicVerdict, right: EpicVerdict): EpicVerdict {
|
|
|
102
112
|
|
|
103
113
|
// Every pool is a source of candidates **for the repository the request names**. The free-lane count
|
|
104
114
|
// was read for that one repository, so spending it on a child that lives somewhere else would
|
|
105
|
-
// allocate a lane nobody counted
|
|
115
|
+
// allocate a lane nobody counted.
|
|
106
116
|
// Dropped rather than offered: a caller with children in two repositories asks twice, once per
|
|
107
117
|
// repository, exactly as `--repo` already makes it.
|
|
108
118
|
function candidates_in(pool: RepoPool, repo: string): RepoPool {
|
|
@@ -110,7 +120,7 @@ function candidates_in(pool: RepoPool, repo: string): RepoPool {
|
|
|
110
120
|
}
|
|
111
121
|
|
|
112
122
|
// A pool's candidates for the repository in `epic_rank.rank` order — the ranking `backlog:next` offers
|
|
113
|
-
// in
|
|
123
|
+
// in, counted against the pool's own graph. **Within a pool, not across
|
|
114
124
|
// pools**: the pool order is the order a person named the epics in, and that stays the outer key.
|
|
115
125
|
function ranked_in(pool: RepoPool, repo: string): RepoPool {
|
|
116
126
|
const scoped = candidates_in(pool, repo)
|
|
@@ -135,8 +145,8 @@ function unseen_candidates(pool: RepoPool, seen: Set<string>): RepoPool {
|
|
|
135
145
|
}
|
|
136
146
|
|
|
137
147
|
// A child two epics both track is still one child, and entering it twice would open two lanes on one
|
|
138
|
-
// issue — two branches, two pull requests, and the second one merging over the first
|
|
139
|
-
//
|
|
148
|
+
// issue — two branches, two pull requests, and the second one merging over the first.
|
|
149
|
+
// Keyed through `epic_graph.key_of`, the one spelling of an issue's
|
|
140
150
|
// identity in this package: a bare number names a different issue in another repository.
|
|
141
151
|
//
|
|
142
152
|
// **The earlier pool keeps it**, and that is a decision rather than an accident of iteration order.
|
|
@@ -179,13 +189,14 @@ async function collect(
|
|
|
179
189
|
return { children, verdict: children.length > NO_LANES ? RUN_VERDICT : verdict }
|
|
180
190
|
}
|
|
181
191
|
|
|
182
|
-
// The `run:solo` gate `backlog:next` applies, applied to a named epic's lanes too
|
|
183
|
-
//
|
|
192
|
+
// The `run:solo` gate `backlog:next` applies, applied to a named epic's lanes too:
|
|
193
|
+
// the confirmed children are cut where `epic_solo.select` says, so a
|
|
184
194
|
// `run:solo` child never opens a lane beside another one on either path.
|
|
185
195
|
function solo_offer(
|
|
186
196
|
answer: { children: ReadonlyArray<EpicChild>; verdict: EpicVerdict },
|
|
187
197
|
read: BusyRead,
|
|
188
198
|
request: LaneRequest,
|
|
199
|
+
ages: ReadonlyMap<number, string>,
|
|
189
200
|
): LaneOffer {
|
|
190
201
|
const { offered, notice = '' } = epic_solo.select(answer.children, read, request.repo)
|
|
191
202
|
|
|
@@ -193,15 +204,14 @@ function solo_offer(
|
|
|
193
204
|
return { children: [], verdict: WAIT_VERDICT, notice }
|
|
194
205
|
}
|
|
195
206
|
|
|
196
|
-
return { ...answer, children: offered, notice: offered_notice(offered, read, request) }
|
|
207
|
+
return { ...answer, children: offered, notice: offered_notice(offered, read, request, ages) }
|
|
197
208
|
}
|
|
198
209
|
|
|
199
|
-
// The repository is asked how full it is **before** any candidate is confirmed,
|
|
200
|
-
// joshuafolkken/kit#1121 records: a repository with no free lane is handed nothing, so the relations
|
|
210
|
+
// The repository is asked how full it is **before** any candidate is confirmed: a repository with no free lane is handed nothing, so the relations
|
|
201
211
|
// request that would confirm a candidate there buys an answer nobody reads — and a polling `epicrun`
|
|
202
212
|
// would pay it every round.
|
|
203
213
|
//
|
|
204
|
-
// **Triage is asked before even that
|
|
214
|
+
// **Triage is asked before even that**: an untriaged candidate withholds every
|
|
205
215
|
// candidate whatever the occupancy, and it needs only the labels already read. Only a `--lanes` ask
|
|
206
216
|
// is gated — it is the one that opens children beside each other; the single-child form starts one.
|
|
207
217
|
function triage_offer(pools: ReadonlyArray<RepoPool>, request: LaneRequest): LaneOffer | undefined {
|
|
@@ -238,18 +248,19 @@ async function offer_for_repo(
|
|
|
238
248
|
if (notice !== undefined) console.error(notice)
|
|
239
249
|
|
|
240
250
|
const free = free_lanes(read, request.limit)
|
|
251
|
+
const ages = await holder_ages(read, request.repo)
|
|
241
252
|
|
|
242
253
|
if (free === NO_LANES) {
|
|
243
254
|
return {
|
|
244
255
|
children: [],
|
|
245
256
|
verdict: WAIT_VERDICT,
|
|
246
|
-
notice: epic_busy.busy_reason(read, request.repo, request.limit),
|
|
257
|
+
notice: epic_busy.busy_reason(read, request.repo, request.limit, ages),
|
|
247
258
|
}
|
|
248
259
|
}
|
|
249
260
|
|
|
250
261
|
const for_repo = dedupe_pools(pools.map((pool) => ranked_in(pool, request.repo)))
|
|
251
262
|
|
|
252
|
-
return solo_offer(await collect(for_repo, wanted_of(request, free)), read, request)
|
|
263
|
+
return solo_offer(await collect(for_repo, wanted_of(request, free)), read, request, ages)
|
|
253
264
|
}
|
|
254
265
|
|
|
255
266
|
const epic_lane_offer = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EPIC_LABEL, has_label_name } from '#scripts/issue/issue-labels'
|
|
2
2
|
import type { EpicChild } from './epic-graph'
|
|
3
3
|
|
|
4
|
-
// Whether a task-list row points at another epic
|
|
4
|
+
// Whether a task-list row points at another epic.
|
|
5
5
|
//
|
|
6
6
|
// An epic's body can hold `- [ ] #<another epic>` — nothing stops it being typed — and until this
|
|
7
7
|
// module nothing read it. `epic-classify.ts` sorted the row like any other child and
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
import { session_cite } from '#scripts/issue/session-cite'
|
|
1
2
|
import { epic_cross_repo } from './epic-cross-repo'
|
|
2
3
|
import { epic_fetch, type EpicSnapshot } from './epic-fetch'
|
|
3
4
|
import { epic_graph } from './epic-graph'
|
|
4
5
|
import type { EpicReference } from './epic-issue'
|
|
5
6
|
|
|
6
|
-
// Reading the epics `josh epic:next` was given, before anything is classified
|
|
7
|
+
// Reading the epics `josh epic:next` was given, before anything is classified.
|
|
7
8
|
//
|
|
8
9
|
// Split from the command itself because naming several epics turned one read into a walk, and a walk
|
|
9
10
|
// has answers a single read did not: an epic that was skipped, and one that stopped everything.
|
|
10
11
|
|
|
11
12
|
// A qualified epic is read by naming its repository in the read's REST path, so naming one we do
|
|
12
|
-
// not own would send this command to a third party's tracker —
|
|
13
|
-
//
|
|
13
|
+
// not own would send this command to a third party's tracker — forbidden for a child, and forbidden
|
|
14
|
+
// here for the same reason.
|
|
14
15
|
const FOREIGN_EPIC = 'That epic belongs to another owner; this command only reads our own.'
|
|
15
16
|
const NO_CHILDREN = 0
|
|
16
17
|
|
|
@@ -46,7 +47,7 @@ function epic_repo_of(reference: EpicReference, current_repo: string): string |
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
function childless(reference: EpicReference): string {
|
|
49
|
-
return
|
|
50
|
+
return `${session_cite.issue(reference.number, undefined, reference.repo)} tracks no children in a task list.`
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
// The same epic named twice is one epic. Removed here rather than left to
|
|
@@ -76,8 +77,7 @@ function unique_references(
|
|
|
76
77
|
// **An epic whose body could not be read is not a childless epic.** The two are indistinguishable
|
|
77
78
|
// downstream — a body that never arrived parses to zero children exactly as an unpopulated task list
|
|
78
79
|
// does — and skipping it drops the epic from the views with no anomaly anywhere, so the run reports
|
|
79
|
-
// the backlog empty and ends. Kept as a read instead, so `epic:next` sees the failed body and says so
|
|
80
|
-
// (joshuafolkken/kit#1690).
|
|
80
|
+
// the backlog empty and ends. Kept as a read instead, so `epic:next` sees the failed body and says so.
|
|
81
81
|
function is_childless(snapshot: EpicSnapshot): boolean {
|
|
82
82
|
if (snapshot.body_failure !== undefined) return false
|
|
83
83
|
|
|
@@ -89,7 +89,7 @@ function is_childless(snapshot: EpicSnapshot): boolean {
|
|
|
89
89
|
// stops the command. An epic that is simply not populated yet is a valid, readable epic of ours — an
|
|
90
90
|
// epic whose task list has not been filled in is the ordinary case — and refusing the
|
|
91
91
|
// whole command for it would stop every *other* named epic's children being offered, on every
|
|
92
|
-
// polling round, until a person noticed
|
|
92
|
+
// polling round, until a person noticed.
|
|
93
93
|
async function read_one(reference: EpicReference, current_repo: string): Promise<ReadOutcome> {
|
|
94
94
|
const epic_repo = epic_repo_of(reference, current_repo)
|
|
95
95
|
if (epic_repo === undefined) return { refusal: FOREIGN_EPIC }
|
|
@@ -107,7 +107,7 @@ function collect(outcome: ReadOutcome, reads: Array<EpicRead>, notices: Array<st
|
|
|
107
107
|
|
|
108
108
|
// **The reads are serial on purpose.** A reference naming another owner has to stop the command
|
|
109
109
|
// before that repository is asked anything, and issuing them together would send every fetch before
|
|
110
|
-
// the first refusal was seen — the read
|
|
110
|
+
// the first refusal was seen — the very read the refusal exists to prevent. The latency is the
|
|
111
111
|
// price of that guarantee, and `unique_references` above is what keeps it from being paid twice for
|
|
112
112
|
// one epic.
|
|
113
113
|
async function read_snapshots(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
1
2
|
import type { ConfirmContext } from './epic-candidate-confirm'
|
|
2
3
|
import { epic_cross_repo } from './epic-cross-repo'
|
|
3
4
|
import { epic_fetch, type EpicSnapshot } from './epic-fetch'
|
|
@@ -6,13 +7,12 @@ import type { EpicReference } from './epic-issue'
|
|
|
6
7
|
import { epic_lane_offer, type RepoPool } from './epic-lane-offer'
|
|
7
8
|
import { epic_report, type EpicNextResult, type EpicVerdict } from './epic-report'
|
|
8
9
|
|
|
9
|
-
// Several epics, answered as one
|
|
10
|
+
// Several epics, answered as one.
|
|
10
11
|
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
// one view per named epic, merged into one pool list and one verdict.
|
|
12
|
+
// The lane pool is epic-agnostic on purpose: `epic-lane-offer.ts` takes an array of `RepoPool`s and
|
|
13
|
+
// nothing below it knows what an epic is. A *caller* that read a single reference and built a single
|
|
14
|
+
// pool would still leave a repository with six free lanes filling them from one graph. This module is
|
|
15
|
+
// that caller's other half: one view per named epic, merged into one pool list and one verdict.
|
|
16
16
|
//
|
|
17
17
|
// **The priority order is the order the epics were named**, and it is a decision rather than a
|
|
18
18
|
// fallback. Dependency depth was the alternative and it does not compare across graphs: depth is
|
|
@@ -37,20 +37,20 @@ interface EpicView {
|
|
|
37
37
|
snapshot: EpicSnapshot
|
|
38
38
|
result: EpicNextResult
|
|
39
39
|
// Every issue this invocation may run — the children of all the named epics, plus a backlog's
|
|
40
|
-
// standalone issues — which a candidate's blockers are re-weighed against at confirmation
|
|
41
|
-
//
|
|
40
|
+
// standalone issues — which a candidate's blockers are re-weighed against at confirmation.
|
|
41
|
+
// Absent, a view confirms against its own epic's children alone.
|
|
42
42
|
running?: ReadonlySet<string>
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// Written exactly as it was typed. A bare number stays bare, because qualifying it here would name
|
|
46
46
|
// this repository in an answer about an epic the caller referred to without one.
|
|
47
47
|
function format_reference(reference: EpicReference): string {
|
|
48
|
-
return
|
|
48
|
+
return issue_cite.plain(reference.number, reference.repo)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// What the candidate confirmation reads with. The blockers come from `epic_fetch`'s own reader, so
|
|
52
52
|
// a candidate is addressed exactly as every other read of a child is — a cross-repository child
|
|
53
|
-
// through its own repository, and a local one bare
|
|
53
|
+
// through its own repository, and a local one bare.
|
|
54
54
|
function confirm_context(snapshot: EpicSnapshot, running?: ReadonlySet<string>): ConfirmContext {
|
|
55
55
|
return {
|
|
56
56
|
children: snapshot.children,
|
|
@@ -108,8 +108,8 @@ function aggregate_text(views: ReadonlyArray<EpicView>, current_repo: string): s
|
|
|
108
108
|
return views.map((view) => format_view(view, is_many, current_repo)).join(BLOCK_SEPARATOR)
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
// The running set with every issue that waits on a person taken out, and the views built from it
|
|
112
|
-
//
|
|
111
|
+
// The running set with every issue that waits on a person taken out, and the views built from it.
|
|
112
|
+
// A blocker in another named epic only waits when that blocker itself can
|
|
113
113
|
// finish: one parked, or one that is itself blocked from outside, holds its dependants for a person
|
|
114
114
|
// exactly as a parked blocker inside one epic does. Each pass removes what the previous one sent to a
|
|
115
115
|
// person, so the set only shrinks, and the walk ends at the first pass that removes nothing.
|