@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
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { styleText } from 'node:util'
|
|
2
|
+
import type { FiledKind } from '#scripts/run/event/run-event-filed'
|
|
3
|
+
import { run_board_kind } from './run-board-kind'
|
|
4
|
+
import { run_board_labels, type Words } from './run-board-labels'
|
|
5
|
+
import type { BoardRow } from './run-board-layout'
|
|
6
|
+
import type { BoardNote } from './run-board-notes'
|
|
7
|
+
import { run_board_phase } from './run-board-phase'
|
|
8
|
+
import { run_board_render_notes } from './run-board-render-notes'
|
|
9
|
+
import type { ItemState } from './run-board-status'
|
|
10
|
+
|
|
11
|
+
// The legend at the foot of `run:board`: the symbols named once, so a row carries only what differs
|
|
12
|
+
// between rows. Drawn apart from the rows, which tell it the icons they lead with.
|
|
13
|
+
|
|
14
|
+
const { FILED_KIND_ICONS, KIND_WORDS, PHASE_ICONS, PHASE_WORDS, STATE_ICONS, WAITS_ICON, WORDS } =
|
|
15
|
+
run_board_labels
|
|
16
|
+
const GAP = ' '
|
|
17
|
+
|
|
18
|
+
// Every phase a run passes through, in the track's own order and whatever is on screen: a row's phase
|
|
19
|
+
// moves between redraws, so fixed lines keep each icon where the eye last found it — six to a line, so
|
|
20
|
+
// the twelve fit a narrow pane.
|
|
21
|
+
const PHASES_PER_LINE = 6
|
|
22
|
+
const PHASE_ENTRIES = run_board_phase.PHASES.map(
|
|
23
|
+
(phase) => `${PHASE_ICONS[phase]} ${WORDS[PHASE_WORDS[phase]]}`,
|
|
24
|
+
)
|
|
25
|
+
const PHASE_LEGEND = Array.from(
|
|
26
|
+
{ length: Math.ceil(PHASE_ENTRIES.length / PHASES_PER_LINE) },
|
|
27
|
+
(_, line) => PHASE_ENTRIES.slice(line * PHASES_PER_LINE, (line + 1) * PHASES_PER_LINE).join(GAP),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
// The row states the legend can name, in its order, each with its word.
|
|
31
|
+
const STATE_LEGEND: ReadonlyArray<readonly [ItemState, keyof Words]> = [
|
|
32
|
+
['merged', 'merged'],
|
|
33
|
+
['parked', 'parked'],
|
|
34
|
+
['done', 'done'],
|
|
35
|
+
['running', 'in_progress'],
|
|
36
|
+
['stopped', 'stopped'],
|
|
37
|
+
['waiting', 'waiting'],
|
|
38
|
+
['human', 'decision'],
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
// The states some row on screen leads with (`drawn`) — a running row leads with its phase, so 🔄 is
|
|
42
|
+
// named only while a row draws it.
|
|
43
|
+
function state_legend(drawn: ReadonlySet<string>): Array<string> {
|
|
44
|
+
return STATE_LEGEND.filter(([state]) => drawn.has(STATE_ICONS[state])).map(
|
|
45
|
+
([state, word]) => `${STATE_ICONS[state]} ${WORDS[word]}`,
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The release kinds the rows draw (joshuafolkken/kit#3577), in the release notes' order.
|
|
50
|
+
function kinds_of(rows: ReadonlyArray<BoardRow>): Array<FiledKind> {
|
|
51
|
+
const drawn = new Set(rows.map((row) => row.kind))
|
|
52
|
+
|
|
53
|
+
return run_board_kind.KIND_ORDER.filter((kind) => drawn.has(kind))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function waits_legend(rows: ReadonlyArray<BoardRow>): Array<string> {
|
|
57
|
+
return rows.some((row) => row.waits.length > 0) ? [`${WAITS_ICON} ${WORDS.waits}`] : []
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// The phases on their lines and what the screen draws on one more, drawn only when it names something.
|
|
61
|
+
// The header's gauges and marks read by their place, so the legend leaves them.
|
|
62
|
+
// `drawn` is the icons the rows lead with.
|
|
63
|
+
function legend_of(
|
|
64
|
+
rows: ReadonlyArray<BoardRow>,
|
|
65
|
+
drawn: ReadonlySet<string>,
|
|
66
|
+
notes: ReadonlyArray<BoardNote>,
|
|
67
|
+
): Array<string> {
|
|
68
|
+
const kinds = kinds_of(rows)
|
|
69
|
+
const kind_icons = kinds.map((kind) => FILED_KIND_ICONS[kind])
|
|
70
|
+
const notes_named = run_board_render_notes.notes_legend(notes, new Set([...drawn, ...kind_icons]))
|
|
71
|
+
const kind_named = kinds.map((kind) => `${FILED_KIND_ICONS[kind]} ${WORDS[KIND_WORDS[kind]]}`)
|
|
72
|
+
const shown = [...state_legend(drawn), ...kind_named, ...waits_legend(rows), ...notes_named]
|
|
73
|
+
const lines = shown.length === 0 ? PHASE_LEGEND : [...PHASE_LEGEND, shown.join(GAP)]
|
|
74
|
+
|
|
75
|
+
return lines.map((line) => styleText('dim', line))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const run_board_render_legend = {
|
|
79
|
+
legend_of,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export { run_board_render_legend }
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { run_board_kind } from './run-board-kind'
|
|
2
|
+
import { run_board_labels, type Words } from './run-board-labels'
|
|
3
|
+
import type { BoardNote } from './run-board-notes'
|
|
4
|
+
|
|
5
|
+
// The findings section at the foot of `run:board` and the part of the legend that names its symbols.
|
|
6
|
+
// A finding is read to the minute, and the legend names only the kinds the section draws — the rows'
|
|
7
|
+
// legend's rule — so a section of filed Issues alone is not explained with 💬 and 💤.
|
|
8
|
+
|
|
9
|
+
const { FILED_KIND_ICONS, KIND_WORDS, NOTES_ICON, NOTE_ICONS, STATE_ICONS, WORDS, minute_of } =
|
|
10
|
+
run_board_labels
|
|
11
|
+
const NOTE_LIMIT = 6
|
|
12
|
+
const GAP = ' '
|
|
13
|
+
const INDENT = ' '
|
|
14
|
+
const NUMBER_PLACEHOLDER = '{n}'
|
|
15
|
+
|
|
16
|
+
type Link = (reference: string) => string
|
|
17
|
+
|
|
18
|
+
// The icons the legend can name, in its order, each with its word — a filed kind's the rows' own
|
|
19
|
+
// (joshuafolkken/kit#3577), so one icon is never named with two words.
|
|
20
|
+
const NOTE_LEGEND: ReadonlyArray<readonly [string, keyof Words]> = [
|
|
21
|
+
...run_board_kind.KIND_ORDER.map((kind) => [FILED_KIND_ICONS[kind], KIND_WORDS[kind]] as const),
|
|
22
|
+
[NOTE_ICONS.filed, 'filed'],
|
|
23
|
+
[NOTE_ICONS.park, 'parked'],
|
|
24
|
+
[NOTE_ICONS.note, 'note'],
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
function note_icon(note: BoardNote): string {
|
|
28
|
+
if (note.is_decision) return STATE_ICONS.human
|
|
29
|
+
|
|
30
|
+
return note.filed_kind === undefined ? NOTE_ICONS[note.kind] : FILED_KIND_ICONS[note.filed_kind]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function found_of(note: BoardNote, link: Link): string {
|
|
34
|
+
if (note.found_during === undefined) return ''
|
|
35
|
+
|
|
36
|
+
return WORDS.found_during.split(NUMBER_PLACEHOLDER).join(link(note.found_during))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Where the legend names the symbols a note leads with its icon alone; where no legend is drawn it
|
|
40
|
+
// keeps the kind's word.
|
|
41
|
+
function note_text(note: BoardNote, has_legend: boolean, link: Link): string {
|
|
42
|
+
const kind = has_legend ? undefined : WORDS[note.kind]
|
|
43
|
+
const issue = note.issue === undefined ? undefined : link(note.issue)
|
|
44
|
+
const lead = [note_icon(note), minute_of(note.at_ms), issue, kind]
|
|
45
|
+
.filter((part) => part !== undefined)
|
|
46
|
+
.join(' ')
|
|
47
|
+
|
|
48
|
+
return `${INDENT}${lead}${GAP}${note.text}${found_of(note, link)}`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// The newest few, so the section never pushes the plan off the screen; the frame counts the rest
|
|
52
|
+
// together with any it cuts to fit. Their numbers go through the board's `header.link`, so they open
|
|
53
|
+
// their GitHub issue as the plan's rows do.
|
|
54
|
+
function note_lines(
|
|
55
|
+
notes: ReadonlyArray<BoardNote>,
|
|
56
|
+
has_legend: boolean,
|
|
57
|
+
link: Link,
|
|
58
|
+
): Array<string> {
|
|
59
|
+
return notes.slice(0, NOTE_LIMIT).map((note) => note_text(note, has_legend, link))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 📌 while the section is on screen, then each kind a drawn line leads with —
|
|
63
|
+
// one the rows' legend already names (`named`) is not named twice.
|
|
64
|
+
function notes_legend(notes: ReadonlyArray<BoardNote>, named: ReadonlySet<string>): Array<string> {
|
|
65
|
+
if (notes.length === 0) return []
|
|
66
|
+
|
|
67
|
+
const drawn = new Set(notes.slice(0, NOTE_LIMIT).map((note) => note_icon(note)))
|
|
68
|
+
const kinds = NOTE_LEGEND.filter(([icon]) => drawn.has(icon) && !named.has(icon)).map(
|
|
69
|
+
([icon, word]) => `${icon} ${WORDS[word]}`,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
return [`${NOTES_ICON} ${WORDS.notes}`, ...kinds]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const run_board_render_notes = { NOTE_LIMIT, note_lines, notes_legend }
|
|
76
|
+
|
|
77
|
+
export { run_board_render_notes }
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { run_board_fit } from './run-board-fit'
|
|
2
|
+
import type { BoardRow } from './run-board-layout'
|
|
3
|
+
import type { ItemState } from './run-board-status'
|
|
4
|
+
import type { LaneUsages } from './run-board-usage'
|
|
5
|
+
import { run_board_usage_text } from './run-board-usage-text'
|
|
6
|
+
|
|
7
|
+
// The column between a row's time and its track, one width on every row it is drawn on, so every
|
|
8
|
+
// track starts in one column: a running row's CPU and memory, a finished row's finish time, and
|
|
9
|
+
// blanks on any other row.
|
|
10
|
+
|
|
11
|
+
const { finish_of, text_of } = run_board_usage_text
|
|
12
|
+
const FINISHED: ReadonlySet<ItemState> = new Set(['merged', 'done'])
|
|
13
|
+
const BLANK = ' '
|
|
14
|
+
|
|
15
|
+
// What one frame's column is drawn from: each lane's usage, and the running rows the frame draws —
|
|
16
|
+
// counted once a frame, the count a lane's share of the machine is divided by.
|
|
17
|
+
interface UsageSlot {
|
|
18
|
+
usages: LaneUsages
|
|
19
|
+
running: number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function usage_slot(rows: ReadonlyArray<BoardRow>, usages: LaneUsages): UsageSlot {
|
|
23
|
+
return { usages, running: rows.filter((row) => row.state === 'running').length }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function slot_of(row: BoardRow, slot: UsageSlot, now_ms: number): string | undefined {
|
|
27
|
+
if (row.state === 'running') return text_of(slot.usages.get(row.number), slot.running)
|
|
28
|
+
if (FINISHED.has(row.state)) return finish_of(row.status?.ended_ms, now_ms)
|
|
29
|
+
|
|
30
|
+
return undefined
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// The widest any row of the frame draws, as the terminal counts it — an emoji takes two columns.
|
|
34
|
+
function column_width(rows: ReadonlyArray<BoardRow>, slot: UsageSlot, now_ms: number): number {
|
|
35
|
+
const widths = rows.map((row) => run_board_fit.width_of(slot_of(row, slot, now_ms) ?? ''))
|
|
36
|
+
|
|
37
|
+
return Math.max(0, ...widths)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// A row's column padded with blanks to the frame's width.
|
|
41
|
+
function cell_of(text: string | undefined, width: number): string {
|
|
42
|
+
const drawn = text ?? ''
|
|
43
|
+
|
|
44
|
+
return `${drawn}${BLANK.repeat(Math.max(0, width - run_board_fit.width_of(drawn)))}`
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const run_board_render_slot = { cell_of, column_width, slot_of, usage_slot }
|
|
48
|
+
|
|
49
|
+
export { run_board_render_slot }
|
|
50
|
+
export type { UsageSlot }
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
import {
|
|
2
|
+
run_board_fit,
|
|
3
|
+
type FrameParts,
|
|
4
|
+
type NotesPart,
|
|
5
|
+
type PlanLine,
|
|
6
|
+
type PlanSection,
|
|
7
|
+
type RowYield,
|
|
8
|
+
type TerminalSize,
|
|
9
|
+
type YieldStage,
|
|
10
|
+
} from './run-board-fit'
|
|
11
|
+
import { run_board_header, type BoardHeader } from './run-board-header'
|
|
12
|
+
import { run_board_labels } from './run-board-labels'
|
|
13
|
+
import {
|
|
14
|
+
run_board_layout,
|
|
15
|
+
type BoardLayout,
|
|
16
|
+
type BoardRow,
|
|
17
|
+
type WaveEntry,
|
|
18
|
+
} from './run-board-layout'
|
|
19
|
+
import type { BoardNote } from './run-board-notes'
|
|
20
|
+
import type { Phase } from './run-board-phase'
|
|
21
|
+
import { run_board_render_legend } from './run-board-render-legend'
|
|
22
|
+
import { run_board_render_notes } from './run-board-render-notes'
|
|
23
|
+
import { run_board_render_slot, type UsageSlot } from './run-board-render-slot'
|
|
24
|
+
import type { ItemState } from './run-board-status'
|
|
25
|
+
import { run_board_track } from './run-board-track'
|
|
26
|
+
|
|
27
|
+
// The whole `run:board` screen as lines — pure, so what a person sees is tested apart from the
|
|
28
|
+
// terminal. The header says where the run is; the sections below it follow the plan's order; the
|
|
29
|
+
// findings at the bottom are what the run would otherwise have said in no chat anyone reads. A section
|
|
30
|
+
// is a rule rather than a heading, and the legend at the foot names the symbols, so a row carries only
|
|
31
|
+
// what differs between rows. Every word is English whatever the session language: one set of words
|
|
32
|
+
// reads the same on every board.
|
|
33
|
+
|
|
34
|
+
const { FILED_KIND_ICONS, KIND_BLANK, NOTES_ICON, PHASE_ICONS, STATE_ICONS, WAITS_ICON, WORDS } =
|
|
35
|
+
run_board_labels
|
|
36
|
+
const { clock_of, elapsed_of } = run_board_labels
|
|
37
|
+
const { NOTE_LIMIT } = run_board_render_notes
|
|
38
|
+
const { cell_of, column_width, slot_of, usage_slot } = run_board_render_slot
|
|
39
|
+
// The columns a terminal row gives its title: a longer one is cut to an ellipsis.
|
|
40
|
+
const TITLE_LIMIT = 48
|
|
41
|
+
const ELLIPSIS = '…'
|
|
42
|
+
const GAP = ' '
|
|
43
|
+
const INDENT = ' '
|
|
44
|
+
const BRANCH = ' ├ '
|
|
45
|
+
const LAST_BRANCH = ' └ '
|
|
46
|
+
const RULE = '─'
|
|
47
|
+
const RULE_LEAD = `${RULE}${RULE}`
|
|
48
|
+
const RULE_WIDTH = 50
|
|
49
|
+
|
|
50
|
+
// The live terminal a frame is kept within, and the footer the frame ends on and gives way first;
|
|
51
|
+
// neither for a frame that is not redrawn in place.
|
|
52
|
+
interface FrameBounds {
|
|
53
|
+
size?: TerminalSize | undefined
|
|
54
|
+
footer?: ReadonlyArray<string> | undefined
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface BoardView extends FrameBounds {
|
|
58
|
+
header: BoardHeader
|
|
59
|
+
notes: ReadonlyArray<BoardNote>
|
|
60
|
+
// The session a stopped run resumes from.
|
|
61
|
+
resume?: string | undefined
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// What every row of one frame is drawn with: the header, how wide the time column is, so a three-digit
|
|
65
|
+
// `125:30` and a `00:42` end in the same column, and each lane's usage where its column is drawn, with
|
|
66
|
+
// the column's width.
|
|
67
|
+
interface RowFrame {
|
|
68
|
+
header: BoardHeader
|
|
69
|
+
time_width: number
|
|
70
|
+
usage: UsageSlot | undefined
|
|
71
|
+
slot_width: number
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// A title cut to the title column, so every time after it starts in one column.
|
|
75
|
+
function title_of(title = ''): string {
|
|
76
|
+
return title.length > TITLE_LIMIT ? `${title.slice(0, TITLE_LIMIT - 1)}${ELLIPSIS}` : title
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// A row drawn before the plan is read has no title yet, and says so.
|
|
80
|
+
function row_title(row: BoardRow, header: BoardHeader): string | undefined {
|
|
81
|
+
if (row.title !== undefined || run_board_header.is_plan_read(header)) return row.title
|
|
82
|
+
|
|
83
|
+
return ELLIPSIS
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// A running row runs until now; a settled one until its recorded end. A child settled from the open
|
|
87
|
+
// listing has none, so it draws no time rather than one that keeps counting.
|
|
88
|
+
function end_of(row: BoardRow, now_ms: number): number | undefined {
|
|
89
|
+
return row.state === 'running' ? now_ms : row.status?.ended_ms
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// How long a row has run: a running one until now, a settled one its whole span.
|
|
93
|
+
function elapsed_ms(row: BoardRow, now_ms: number): number | undefined {
|
|
94
|
+
const started = row.status?.started_ms
|
|
95
|
+
const ended = end_of(row, now_ms)
|
|
96
|
+
|
|
97
|
+
if (started === undefined || ended === undefined) return undefined
|
|
98
|
+
|
|
99
|
+
return ended - started
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function time_of(row: BoardRow, now_ms: number): string | undefined {
|
|
103
|
+
const elapsed = elapsed_ms(row, now_ms)
|
|
104
|
+
|
|
105
|
+
return elapsed === undefined ? undefined : elapsed_of(elapsed)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// The phases a row's track draws — every one the child passed while running, kept once it settles.
|
|
109
|
+
function drawn_phases(row: BoardRow): ReadonlyArray<Phase> {
|
|
110
|
+
return row.status?.track ?? []
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// A row's phases as its track, drawn last: it grows with every round, so the
|
|
114
|
+
// columns before it stay where they are whatever its length. A settled row's ends on its state icon.
|
|
115
|
+
function track_text(row: BoardRow): string | undefined {
|
|
116
|
+
const phases = drawn_phases(row)
|
|
117
|
+
|
|
118
|
+
return phases.length === 0 ? undefined : run_board_track.track_of(phases, row.state)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function waits_of(row: BoardRow, header: BoardHeader): string | undefined {
|
|
122
|
+
if (row.waits.length === 0) return undefined
|
|
123
|
+
|
|
124
|
+
return `${WAITS_ICON} ${row.waits.map((reference) => header.link(reference)).join(', ')}`
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// The title is padded to the title column where a time or the usage column follows it, so the times
|
|
128
|
+
// form one column; a row with no time draws blanks in its place before the usage column.
|
|
129
|
+
function timed_parts(
|
|
130
|
+
row: BoardRow,
|
|
131
|
+
frame: RowFrame,
|
|
132
|
+
is_slotted: boolean,
|
|
133
|
+
): Array<string | undefined> {
|
|
134
|
+
const time = time_of(row, frame.header.now_ms)
|
|
135
|
+
|
|
136
|
+
const title = title_of(row_title(row, frame.header))
|
|
137
|
+
|
|
138
|
+
if (time === undefined && !is_slotted) return [title]
|
|
139
|
+
|
|
140
|
+
return [title.padEnd(TITLE_LIMIT), (time ?? '').padStart(frame.time_width)]
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// A running row leads with the icon of the phase it is in now — the rightmost
|
|
144
|
+
// icon of its track — and with 🔄 while its track draws none yet.
|
|
145
|
+
function state_icon(row: BoardRow): string {
|
|
146
|
+
const current = row.state === 'running' ? drawn_phases(row).at(-1) : undefined
|
|
147
|
+
|
|
148
|
+
return current === undefined ? STATE_ICONS[row.state] : PHASE_ICONS[current]
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// A running row turns the spinner in the first column of its indent where the header has one, so its
|
|
152
|
+
// title starts in the same column as every other row's.
|
|
153
|
+
function indent_of(prefix: string, row: BoardRow, header: BoardHeader): string {
|
|
154
|
+
if (row.state !== 'running' || header.spinner === undefined) return prefix
|
|
155
|
+
|
|
156
|
+
return `${header.spinner}${prefix.slice(1)}`
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// A row's usage column where the frame draws one, padded to one width on every row so every track
|
|
160
|
+
// starts in one column. A plan row the run has not touched has no time, usage or track to align, so it
|
|
161
|
+
// draws none and what it waits on stays beside its title.
|
|
162
|
+
function cell_text(row: BoardRow, frame: RowFrame): string | undefined {
|
|
163
|
+
const { usage, slot_width } = frame
|
|
164
|
+
|
|
165
|
+
if (usage === undefined || slot_width === 0 || row.status === undefined) return undefined
|
|
166
|
+
|
|
167
|
+
return cell_of(slot_of(row, usage, frame.header.now_ms), slot_width)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function joined(parts: ReadonlyArray<string | undefined>): string {
|
|
171
|
+
return parts.filter((part) => part !== undefined && part !== '').join(GAP)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// The release kind's icon between the number and the title, one space either side; a row with no title
|
|
175
|
+
// ends at its icon, so what follows keeps its usual gap.
|
|
176
|
+
function lead_of(row: BoardRow, header: BoardHeader, title: string): string {
|
|
177
|
+
const kind = row.kind === undefined ? KIND_BLANK : FILED_KIND_ICONS[row.kind]
|
|
178
|
+
const lead = `${state_icon(row)} ${header.link(String(row.number))} ${kind}`
|
|
179
|
+
|
|
180
|
+
return title === '' ? lead : `${lead} ${title}`
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// A row up to its usage column — the columns that stay where they are whatever the track's length.
|
|
184
|
+
function head_text(row: BoardRow, frame: RowFrame): string {
|
|
185
|
+
const cell = cell_text(row, frame)
|
|
186
|
+
const [title = '', ...time] = timed_parts(row, frame, cell !== undefined)
|
|
187
|
+
|
|
188
|
+
return joined([lead_of(row, frame.header, title), ...time, cell])
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Every row carries its state's icon, a waiting one ⏳ too; a row with nothing
|
|
192
|
+
// after its padded columns ends where its text does.
|
|
193
|
+
function row_text(row: BoardRow, frame: RowFrame): string {
|
|
194
|
+
return joined([head_text(row, frame), track_text(row), waits_of(row, frame.header)]).trimEnd()
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// The stage each state's row gives way in when the pane is short.
|
|
198
|
+
const YIELD_STAGES: Readonly<Record<ItemState, YieldStage>> = {
|
|
199
|
+
merged: 'finished',
|
|
200
|
+
done: 'finished',
|
|
201
|
+
waiting: 'pending',
|
|
202
|
+
human: 'pending',
|
|
203
|
+
parked: 'parked',
|
|
204
|
+
stopped: 'parked',
|
|
205
|
+
running: 'running',
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// A running row is as old as its start; a settled one as its end, or its start where it has none.
|
|
209
|
+
function aged_ms(row: BoardRow): number | undefined {
|
|
210
|
+
const started = row.status?.started_ms
|
|
211
|
+
|
|
212
|
+
return row.state === 'running' ? started : (row.status?.ended_ms ?? started)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function yield_of(row: BoardRow): RowYield {
|
|
216
|
+
return { stage: YIELD_STAGES[row.state], at_ms: aged_ms(row) }
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// A plan line that draws one issue row, and one that draws none — a blank, a rule, an epic's own line.
|
|
220
|
+
function row_line(prefix: string, row: BoardRow, frame: RowFrame): PlanLine {
|
|
221
|
+
const text = `${indent_of(prefix, row, frame.header)}${row_text(row, frame)}`
|
|
222
|
+
|
|
223
|
+
return { text, row: yield_of(row) }
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function bare(text: string): PlanLine {
|
|
227
|
+
return { text, row: undefined }
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function epic_lines(entry: Extract<WaveEntry, { kind: 'epic' }>, frame: RowFrame): Array<PlanLine> {
|
|
231
|
+
const last = entry.rows.length - 1
|
|
232
|
+
const children = entry.rows.map((row, index) =>
|
|
233
|
+
row_line(index === last ? LAST_BRANCH : BRANCH, row, frame),
|
|
234
|
+
)
|
|
235
|
+
const title = title_of(entry.title)
|
|
236
|
+
const number = frame.header.link(String(entry.epic))
|
|
237
|
+
const epic = title === '' ? number : `${number}${GAP}${title}`
|
|
238
|
+
|
|
239
|
+
return [bare(`${INDENT}📁 ${epic}`), ...children]
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function entry_lines(entry: WaveEntry, frame: RowFrame): Array<PlanLine> {
|
|
243
|
+
if (entry.kind === 'row') return [row_line(INDENT, entry.row, frame)]
|
|
244
|
+
|
|
245
|
+
return epic_lines(entry, frame)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function rule_of(label: string): string {
|
|
249
|
+
return `${RULE_LEAD} ${label} `.padEnd(RULE_WIDTH, RULE)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function heading_lines(heading: string | undefined): Array<string> {
|
|
253
|
+
return heading === undefined ? [''] : ['', rule_of(heading)]
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function plan_section(
|
|
257
|
+
heading: string | undefined,
|
|
258
|
+
lines: ReadonlyArray<PlanLine>,
|
|
259
|
+
): Array<PlanSection> {
|
|
260
|
+
if (lines.length === 0) return []
|
|
261
|
+
|
|
262
|
+
return [{ head: heading_lines(heading), lines }]
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function rows_section(
|
|
266
|
+
heading: string | undefined,
|
|
267
|
+
rows: ReadonlyArray<BoardRow>,
|
|
268
|
+
frame: RowFrame,
|
|
269
|
+
): Array<PlanSection> {
|
|
270
|
+
return plan_section(
|
|
271
|
+
heading,
|
|
272
|
+
rows.map((row) => row_line(INDENT, row, frame)),
|
|
273
|
+
)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// The time column's width: the widest time any active row draws in this frame.
|
|
277
|
+
function time_width(header: BoardHeader): number {
|
|
278
|
+
const times = (header.layout?.active ?? []).map((row) => time_of(row, header.now_ms) ?? '')
|
|
279
|
+
|
|
280
|
+
return Math.max(0, ...times.map((time) => time.length))
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Whether every row's usage column still fits one terminal line — measured as the deepest, an epic's
|
|
284
|
+
// child — where a frame is kept within a terminal. The track after it is left out: it grows without
|
|
285
|
+
// bound, so one long history would otherwise take the usage column off every row.
|
|
286
|
+
function is_usage_fitting(
|
|
287
|
+
rows: ReadonlyArray<BoardRow>,
|
|
288
|
+
frame: RowFrame,
|
|
289
|
+
size: TerminalSize | undefined,
|
|
290
|
+
): boolean {
|
|
291
|
+
if (size === undefined) return true
|
|
292
|
+
|
|
293
|
+
return rows.every(
|
|
294
|
+
(row) => run_board_fit.height_of(`${BRANCH}${head_text(row, frame)}`, size.columns) === 1,
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// The usage column is drawn on every row or on none: a pane too narrow for it on any row draws it on
|
|
299
|
+
// none — a finish time with it.
|
|
300
|
+
function frame_of(
|
|
301
|
+
header: BoardHeader,
|
|
302
|
+
layout: BoardLayout,
|
|
303
|
+
size: TerminalSize | undefined,
|
|
304
|
+
): RowFrame {
|
|
305
|
+
const rows = run_board_layout.rows_of(layout)
|
|
306
|
+
const usage = header.usages === undefined ? undefined : usage_slot(rows, header.usages)
|
|
307
|
+
const frame = {
|
|
308
|
+
header,
|
|
309
|
+
time_width: time_width(header),
|
|
310
|
+
usage,
|
|
311
|
+
slot_width: usage === undefined ? 0 : column_width(rows, usage, header.now_ms),
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return is_usage_fitting(rows, frame, size) ? frame : { ...frame, usage: undefined }
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function plan_sections(header: BoardHeader, size: TerminalSize | undefined): Array<PlanSection> {
|
|
318
|
+
const { layout } = header
|
|
319
|
+
|
|
320
|
+
if (layout === undefined) return []
|
|
321
|
+
|
|
322
|
+
const frame = frame_of(header, layout, size)
|
|
323
|
+
const waves = layout.waves.flatMap((wave, index) =>
|
|
324
|
+
plan_section(
|
|
325
|
+
String(index + 1),
|
|
326
|
+
wave.flatMap((entry) => entry_lines(entry, frame)),
|
|
327
|
+
),
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
return [
|
|
331
|
+
...rows_section(undefined, layout.active, frame),
|
|
332
|
+
...waves,
|
|
333
|
+
...rows_section(STATE_ICONS.human, layout.people, frame),
|
|
334
|
+
...rows_section(WAITS_ICON, layout.unreached, frame),
|
|
335
|
+
]
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// The findings under a rule, led by 📌 where a legend names it and by its word where none does, and how
|
|
339
|
+
// many more there are, so the section never pushes the plan off the screen.
|
|
340
|
+
function notes_part(notes: ReadonlyArray<BoardNote>, header: BoardHeader): NotesPart {
|
|
341
|
+
const has_legend = header.layout !== undefined
|
|
342
|
+
const lines = run_board_render_notes.note_lines(notes, has_legend, header.link)
|
|
343
|
+
const label = has_legend ? NOTES_ICON : WORDS.notes
|
|
344
|
+
|
|
345
|
+
return { head: heading_lines(label), lines, hidden: notes.length - lines.length }
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// The command that resumes a stopped run's session, under the header where the person looks first.
|
|
349
|
+
function resume_lines(resume: string | undefined): Array<string> {
|
|
350
|
+
if (resume === undefined) return []
|
|
351
|
+
|
|
352
|
+
return ['', `${STATE_ICONS.human} ${WORDS.resume}${GAP}claude --resume ${resume}`]
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// No legend is drawn before a plan is read: there are no rows whose symbols it would name.
|
|
356
|
+
function legend_lines(header: BoardHeader, notes: ReadonlyArray<BoardNote>): Array<string> {
|
|
357
|
+
const { layout } = header
|
|
358
|
+
|
|
359
|
+
if (layout === undefined) return []
|
|
360
|
+
|
|
361
|
+
const rows = run_board_layout.rows_of(layout)
|
|
362
|
+
const drawn = new Set(rows.map((row) => state_icon(row)))
|
|
363
|
+
|
|
364
|
+
return ['', ...run_board_render_legend.legend_of(rows, drawn, notes)]
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// A live frame is kept within its terminal; any other is drawn whole.
|
|
368
|
+
function bounded(parts: FrameParts, bounds: FrameBounds): Array<string> {
|
|
369
|
+
const { size } = bounds
|
|
370
|
+
|
|
371
|
+
return size === undefined ? run_board_fit.whole(parts) : run_board_fit.fit(parts, size)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function render(view: BoardView): Array<string> {
|
|
375
|
+
const { header, notes } = view
|
|
376
|
+
const above = [
|
|
377
|
+
...run_board_header.header_lines(header),
|
|
378
|
+
...resume_lines(view.resume),
|
|
379
|
+
...run_board_header.idle_lines(header),
|
|
380
|
+
]
|
|
381
|
+
const parts = {
|
|
382
|
+
above,
|
|
383
|
+
plan: plan_sections(header, view.size),
|
|
384
|
+
notes: notes_part(notes, header),
|
|
385
|
+
legend: legend_lines(header, notes),
|
|
386
|
+
footer: view.footer ?? [],
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return bounded(parts, view)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function render_no_run(now_ms: number, bounds: FrameBounds = {}): Array<string> {
|
|
393
|
+
const above = [`■ backlogrun${GAP}${WORDS.no_run}${GAP}${clock_of(now_ms)}`]
|
|
394
|
+
const notes = { head: [], lines: [], hidden: 0 }
|
|
395
|
+
|
|
396
|
+
return bounded({ above, plan: [], notes, legend: [], footer: bounds.footer ?? [] }, bounds)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const run_board_render = {
|
|
400
|
+
NOTE_LIMIT,
|
|
401
|
+
TITLE_LIMIT,
|
|
402
|
+
render,
|
|
403
|
+
render_no_run,
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export { run_board_render }
|
|
407
|
+
export type { BoardView, FrameBounds }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { NamedPlan } from '#scripts/backlog/backlog-plan'
|
|
2
|
+
import { run_invocation } from '#scripts/run/run-invocation'
|
|
3
|
+
|
|
4
|
+
// Which plan a run covers, read off the invocation its carry record kept, so the board draws only what
|
|
5
|
+
// the run was asked to do. The invocation is parsed through the grammar the run itself uses, into the
|
|
6
|
+
// shape `backlog:plan` renders a named prefix from, so the board and the plan agree on it.
|
|
7
|
+
// An invocation that does not parse names nothing, which is the bare `backlogrun`'s plan.
|
|
8
|
+
function scope_of(invocation: string): NamedPlan {
|
|
9
|
+
return {
|
|
10
|
+
issues: run_invocation.issue_numbers(invocation) ?? [],
|
|
11
|
+
only: run_invocation.has_only(invocation),
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const run_board_scope = { scope_of }
|
|
16
|
+
|
|
17
|
+
export { run_board_scope }
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// How `josh run:board` puts its frames on the terminal. A board kept open
|
|
2
|
+
// draws on the alternate screen, as `top` and `less` do: clearing the normal screen pushes every
|
|
3
|
+
// redraw into the scrollback, so the board would grow like a log. Leaving restores the screen and the
|
|
4
|
+
// cursor the person had. One frame — `--once`, or a pipe — draws no screen control; a terminal still
|
|
5
|
+
// gets its colors.
|
|
6
|
+
|
|
7
|
+
type ScreenMode = 'live' | 'plain'
|
|
8
|
+
|
|
9
|
+
// The control bytes written on entering, before each frame, and on leaving.
|
|
10
|
+
interface Screen {
|
|
11
|
+
enter: string
|
|
12
|
+
frame: string
|
|
13
|
+
leave: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const ESC = '\u{1B}['
|
|
17
|
+
const ALTERNATE_SCREEN_ON = `${ESC}?1049h`
|
|
18
|
+
const ALTERNATE_SCREEN_OFF = `${ESC}?1049l`
|
|
19
|
+
const CURSOR_HIDE = `${ESC}?25l`
|
|
20
|
+
const CURSOR_SHOW = `${ESC}?25h`
|
|
21
|
+
const CURSOR_HOME = `${ESC}H`
|
|
22
|
+
const ERASE_BELOW = `${ESC}J`
|
|
23
|
+
|
|
24
|
+
const LIVE: Screen = {
|
|
25
|
+
enter: `${ALTERNATE_SCREEN_ON}${CURSOR_HIDE}`,
|
|
26
|
+
frame: `${CURSOR_HOME}${ERASE_BELOW}`,
|
|
27
|
+
leave: `${CURSOR_SHOW}${ALTERNATE_SCREEN_OFF}`,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const PLAIN: Screen = { enter: '', frame: '', leave: '' }
|
|
31
|
+
|
|
32
|
+
function mode_of(options: { is_tty: boolean; is_once: boolean }): ScreenMode {
|
|
33
|
+
return options.is_tty && !options.is_once ? 'live' : 'plain'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function screen_of(mode: ScreenMode): Screen {
|
|
37
|
+
return mode === 'live' ? LIVE : PLAIN
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const run_board_screen = { mode_of, screen_of }
|
|
41
|
+
|
|
42
|
+
export { run_board_screen }
|
|
43
|
+
export type { Screen, ScreenMode }
|