@joshuafolkken/kit 1.1455.0 → 1.1514.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +6 -6
- package/.claude/skills/dependency-update/SKILL.md +26 -55
- package/.claude/skills/epic-commands/SKILL.md +83 -156
- package/.claude/skills/epic-commands/epic-bundle.md +51 -79
- package/.claude/skills/epic-commands/execution-waves.md +43 -81
- package/.claude/skills/verify-ui/SKILL.md +24 -50
- package/.claude/skills/workflow-commands/SKILL.md +7 -9
- package/.claude/skills/workflow-commands/background-commands.md +31 -46
- package/.claude/skills/workflow-commands/backlogrun-child.md +65 -85
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +86 -125
- package/.claude/skills/workflow-commands/backlogrun-park.md +68 -118
- package/.claude/skills/workflow-commands/backlogrun-progress.md +17 -28
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +17 -26
- package/.claude/skills/workflow-commands/backlogrun-steps.md +35 -52
- package/.claude/skills/workflow-commands/backlogrun.md +31 -50
- package/.claude/skills/workflow-commands/chain-rule.md +31 -40
- package/.claude/skills/workflow-commands/delegation.md +12 -8
- package/.claude/skills/workflow-commands/entry-sequence.md +1 -3
- package/.claude/skills/workflow-commands/followup.md +55 -77
- package/.claude/skills/workflow-commands/fullrun-steps.md +3 -5
- package/.claude/skills/workflow-commands/fullrun.md +4 -6
- package/.claude/skills/workflow-commands/halfrun.md +3 -7
- package/.claude/skills/workflow-commands/into-target.md +1 -2
- package/.claude/skills/workflow-commands/issue-comments.md +43 -60
- package/.claude/skills/workflow-commands/issue-scout.md +3 -2
- package/.claude/skills/workflow-commands/kickoff.md +65 -74
- package/.claude/skills/workflow-commands/latest-gate.md +2 -6
- package/.claude/skills/workflow-commands/needs-human-review.md +2 -5
- package/.claude/skills/workflow-commands/observation-filing.md +59 -118
- package/.claude/skills/workflow-commands/observation-ledger.md +52 -112
- package/.claude/skills/workflow-commands/pre-gate-cut.md +88 -142
- package/.claude/skills/workflow-commands/prerequisite.md +11 -17
- package/.claude/skills/workflow-commands/progress-watcher.md +23 -33
- package/.claude/skills/workflow-commands/prrun.md +3 -5
- package/.claude/skills/workflow-commands/retrospective.md +35 -54
- package/.claude/skills/workflow-commands/split-assessment.md +32 -58
- package/.claude/skills/workflow-commands/target-repository.md +1 -2
- package/.claude/skills/workflow-commands/working-tree-hold.md +54 -73
- package/.codex/hooks.json +6 -6
- package/.github/actions/setup-node/action.yml +1 -1
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/publish.yml +2 -2
- package/CLAUDE.md +7 -6
- package/cspell/index.yaml +7 -0
- package/dist/CLAUDE.md +7 -6
- package/dist/commands/document-section-cli.js +67 -34
- package/dist/hooks/batch-guard.js +6 -6
- package/dist/hooks/chunk-4KKD2UTK.js +66 -0
- package/dist/hooks/{chunk-GPLGZ6IC.js → chunk-6TS2JD6D.js} +14 -3
- package/dist/hooks/chunk-7DSBJVFH.js +50 -0
- package/dist/hooks/{chunk-5H4SSDSD.js → chunk-A65Y4YOR.js} +3 -3
- package/dist/hooks/{chunk-3C4XRYG6.js → chunk-APUO6U4J.js} +102 -19
- package/dist/hooks/{chunk-IX6TTTI6.js → chunk-EFXE6C37.js} +8 -22
- package/dist/hooks/chunk-GP4IEC4O.js +20 -0
- package/dist/hooks/chunk-JP45SOCJ.js +56 -0
- package/dist/hooks/{chunk-OLMO72ON.js → chunk-LAOV7NLM.js} +1 -1
- package/dist/hooks/chunk-M4HGZV7U.js +83 -0
- package/dist/hooks/{chunk-TBJFTSUY.js → chunk-O6GDRNJB.js} +9 -7
- package/dist/hooks/{chunk-HFGWYGUV.js → chunk-PF2NZL2A.js} +5 -5
- package/dist/hooks/{chunk-WNLVGT7E.js → chunk-PTICX4OL.js} +4 -5
- package/dist/hooks/{chunk-HHI6FO3R.js → chunk-RT27QRJW.js} +763 -1515
- package/dist/hooks/{chunk-7WQBPLUN.js → chunk-SYOTDYCI.js} +1149 -1095
- package/dist/hooks/{chunk-LIAFCXL7.js → chunk-TNUMY6NL.js} +1519 -1332
- package/dist/hooks/chunk-UPUZF3AN.js +279 -0
- package/dist/hooks/{chunk-Z4XI7CZS.js → chunk-WK6SMBIC.js} +1932 -784
- package/dist/hooks/codex-hook-adapter.js +17 -14
- package/dist/hooks/duplicate-read-guard.js +7 -7
- package/dist/hooks/format-edited.js +5 -4
- package/dist/hooks/inputs.json +302 -247
- package/dist/hooks/investigation-guard.js +8 -11
- package/dist/hooks/pretool-guard.js +16 -13
- package/dist/hooks/session-lang.js +372 -26
- package/dist/hooks/stop-guard.js +2593 -189
- package/dist/josh.js +2128 -282
- package/dist/managed-marker/index.js +1 -2
- package/dist/version/index.js +15 -12
- package/eslint/base.js +2 -1
- package/eslint/rules/unicorn.js +16 -0
- package/lefthook/base.yml +5 -3
- package/package.json +14 -12
- package/prompts/coding-standards.md +12 -22
- package/prompts/collaboration-workflow/file-edits.md +25 -45
- package/prompts/collaboration-workflow/gh-rest.md +19 -36
- package/prompts/collaboration-workflow/glossary.md +5 -7
- package/prompts/collaboration-workflow/issue-citation.md +6 -14
- package/prompts/collaboration-workflow/issue-template.md +40 -32
- package/prompts/collaboration-workflow/lane-instructions.md +35 -0
- package/prompts/collaboration-workflow/operating-rules.md +33 -46
- package/prompts/collaboration-workflow/output-bounds.md +15 -15
- package/prompts/collaboration-workflow/overview.md +14 -19
- package/prompts/collaboration-workflow/plan-comment.md +13 -13
- package/prompts/collaboration-workflow/principles.md +57 -54
- package/prompts/collaboration-workflow/proposal-request.md +1 -9
- package/prompts/collaboration-workflow/report-format.md +41 -49
- package/prompts/collaboration-workflow/residency.md +15 -11
- package/prompts/collaboration-workflow/rule-delivery.md +7 -15
- package/prompts/collaboration-workflow/shell-body.md +10 -20
- package/prompts/collaboration-workflow/turn-batching.md +8 -14
- package/prompts/collaboration-workflow/upstream-interrupt.md +26 -34
- package/prompts/collaboration-workflow/wip-cap.md +26 -32
- package/prompts/collaboration-workflow.md +25 -25
- package/prompts/refactoring.md +33 -43
- package/prompts/review-rubric.md +84 -129
- package/prompts/review.md +110 -141
- package/prompts/sonar-hotspot-handling.md +22 -50
- package/prompts/testing-guide.md +48 -99
- package/scripts/adopt/adopt-toolkits.ts +2 -4
- package/scripts/agent/agent-argv.ts +20 -4
- package/scripts/agent/agent-exit-record.ts +23 -1
- package/scripts/agent/agent-role-profile.ts +101 -45
- package/scripts/agent/agent-safe-text.ts +60 -0
- package/scripts/agent/claude-agent-argv.ts +14 -0
- package/scripts/agent/codex-agent-argv.ts +9 -2
- package/scripts/agent/lane-instructions.ts +144 -0
- package/scripts/backlog/backlog-budget-cli.ts +1 -2
- package/scripts/backlog/backlog-budget.ts +4 -4
- package/scripts/backlog/backlog-drive-carried.ts +26 -0
- package/scripts/backlog/backlog-drive-cli.ts +10 -5
- package/scripts/backlog/backlog-drive-named.ts +3 -5
- package/scripts/backlog/backlog-drive-restore.ts +28 -2
- package/scripts/backlog/backlog-drive-seats.ts +27 -0
- package/scripts/backlog/backlog-drive.ts +11 -6
- package/scripts/backlog/backlog-occupied.ts +56 -0
- package/scripts/backlog/backlog-ready.ts +59 -15
- package/scripts/behavior/behavior-rules.ts +3 -2
- package/scripts/cost-runtime/codex-usage.ts +4 -2
- package/scripts/cost-runtime/cost-cli.ts +1 -2
- package/scripts/delegation/duplicate-read-guard.ts +2 -2
- package/scripts/delegation/investigation-guard.ts +15 -65
- package/scripts/delegation/investigation-reads.ts +1 -2
- package/scripts/discovery/repo-discovery.ts +4 -2
- package/scripts/discovery/repo-origin.ts +2 -4
- package/scripts/doctor/doctor-logic.ts +6 -3
- package/scripts/document/document-byte-budget.ts +28 -27
- package/scripts/document/document-byte-check.ts +1 -2
- package/scripts/document/document-section-cli.ts +17 -5
- package/scripts/document/entry-read-budget.ts +3 -3
- package/scripts/document/read-set-cli.ts +4 -1
- package/scripts/epic/epic-audit-orphans.ts +5 -8
- package/scripts/epic/epic-audit-rationale.ts +8 -2
- package/scripts/epic/epic-audit.ts +52 -1
- package/scripts/epic/epic-bundle-cli.ts +1 -2
- package/scripts/epic/epic-bundle-evidence.ts +49 -26
- package/scripts/epic/epic-bundle-referenced.ts +14 -3
- package/scripts/epic/epic-bundle.ts +17 -9
- package/scripts/epic/epic-chains.ts +6 -2
- package/scripts/epic/epic-close-comment.ts +1 -2
- package/scripts/followup/git-followup-workflow.ts +19 -1
- package/scripts/gate/check-inputs.ts +129 -0
- package/scripts/gate/check-reuse.ts +162 -0
- package/scripts/gate/core-budget.ts +93 -44
- package/scripts/gate/core-wait.ts +130 -0
- package/scripts/gate/free-cores.ts +49 -0
- package/scripts/gate/gate-ledger.ts +17 -3
- package/scripts/gate/gate-plan.ts +23 -1
- package/scripts/gate/gate-report.ts +15 -2
- package/scripts/gate/gate-run-steps.ts +150 -0
- package/scripts/gate/held-mark.ts +55 -0
- package/scripts/gate/machine-capacity.ts +70 -11
- package/scripts/gate/pre-commit-type-check.ts +14 -1
- package/scripts/gate/verification-gate.ts +65 -127
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +24 -2
- package/scripts/gh/git-pr.ts +19 -3
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +16 -9
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/git/main-merge-regenerate.ts +78 -0
- package/scripts/git/main-merge.ts +14 -5
- package/scripts/hooks/batch-guard.ts +5 -8
- package/scripts/hooks/format-edited-file.ts +10 -4
- package/scripts/hooks/pre-commit-lint.ts +91 -0
- package/scripts/hooks/pre-push-unit.ts +15 -4
- package/scripts/hooks/pretool-guard.ts +48 -79
- package/scripts/hooks/reserved-run.ts +1 -0
- package/scripts/hooks/run-hook.sh +10 -12
- package/scripts/hooks/step-zero-notice.ts +3 -2
- package/scripts/hooks/stop-actions.ts +204 -0
- package/scripts/hooks/stop-guard.ts +62 -21
- package/scripts/init/hook-command-rewrite.ts +6 -2
- package/scripts/init/hook-launch.ts +12 -7
- package/scripts/init/init-logic-deploy-vps.ts +4 -2
- package/scripts/issue/behavior-change-lint.ts +12 -6
- package/scripts/issue/expected-effect-lint.ts +59 -0
- package/scripts/issue/issue-cite-cli.ts +35 -15
- package/scripts/issue/issue-classification.ts +1 -1
- package/scripts/issue/issue-lint-cli.ts +5 -3
- package/scripts/issue/issue-scout-cli.ts +22 -16
- package/scripts/issue/markdown-section.ts +19 -5
- package/scripts/josh/command-usage.ts +110 -0
- package/scripts/josh/file-map-stamp.ts +1 -3
- package/scripts/josh/hook-decision.ts +17 -2
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-command-types.ts +55 -9
- package/scripts/josh/josh-commands-ai.ts +13 -0
- package/scripts/josh/josh-commands-development.ts +1 -1
- package/scripts/josh/josh-commands-hooks.ts +6 -0
- package/scripts/josh/josh-commands-lane.ts +10 -1
- package/scripts/josh/josh-commands-workflow.ts +5 -0
- package/scripts/josh/josh-logic.ts +6 -15
- package/scripts/josh/josh-usage-automation.ts +121 -0
- package/scripts/josh/josh-usage-backlog.ts +180 -0
- package/scripts/josh/josh-usage-developer.ts +230 -0
- package/scripts/josh/josh-usage-hooks.ts +38 -0
- package/scripts/josh/josh-usage-issue.ts +205 -0
- package/scripts/josh/josh-usage-review.ts +101 -0
- package/scripts/josh/josh-usage-run.ts +252 -0
- package/scripts/josh/josh-usage-session.ts +238 -0
- package/scripts/josh/josh-usage-workflow.ts +212 -0
- package/scripts/josh/josh.ts +14 -5
- package/scripts/josh/package-directory.ts +20 -0
- package/scripts/lane/lane-await.ts +3 -2
- package/scripts/lane/lane-capacity.ts +8 -2
- package/scripts/lane/lane-check-stats.ts +56 -0
- package/scripts/lane/lane-child-invocation.ts +49 -5
- package/scripts/lane/lane-dispatch.ts +3 -3
- package/scripts/lane/lane-guard-policy.ts +5 -5
- package/scripts/lane/lane-handoff.ts +8 -1
- package/scripts/lane/lane-install.ts +12 -4
- package/scripts/lane/lane-ledger.ts +52 -1
- package/scripts/lane/lane-limit-cli.ts +8 -9
- package/scripts/lane/lane-load.ts +9 -2
- package/scripts/lane/lane-measure-cli.ts +4 -0
- package/scripts/lane/lane-parked.ts +18 -0
- package/scripts/lane/lane-preserve.ts +29 -1
- package/scripts/lane/lane-process-load.ts +125 -0
- package/scripts/lane/lane-process-stats.ts +93 -0
- package/scripts/lane/lane-registry.ts +17 -10
- package/scripts/lane/lane-restart.ts +5 -26
- package/scripts/lane/lane-session-action.ts +146 -0
- package/scripts/lane/lane-session-broker.ts +68 -125
- package/scripts/lane/lane-spent.ts +14 -3
- package/scripts/lane/lane-stats.ts +1 -0
- package/scripts/lane/lane-withdraw-cli.ts +71 -0
- package/scripts/lane/lane-withdraw.ts +182 -0
- package/scripts/lint/format.ts +4 -4
- package/scripts/lint/lint-parallel.ts +10 -3
- package/scripts/lint/lint-related-scope.ts +4 -1
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/telegram-test.ts +10 -5
- package/scripts/overrides/lockfile-overrides.ts +1 -3
- package/scripts/propagate/propagate.ts +1 -2
- package/scripts/release/release-progress.ts +3 -2
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-lint.ts +7 -4
- package/scripts/review/acceptance-map-check.ts +61 -0
- package/scripts/review/acceptance-map.ts +205 -0
- package/scripts/review/review-brief-cli.ts +1 -1
- package/scripts/review/review-record-cli.ts +6 -2
- package/scripts/rules/agent-model.ts +59 -0
- package/scripts/rules/delivered-rules.ts +11 -2
- package/scripts/rules/destructive-command.ts +6 -9
- package/scripts/rules/direct-filing.ts +3 -7
- package/scripts/rules/early-heartbeat.ts +7 -18
- package/scripts/rules/file-body.ts +6 -13
- package/scripts/rules/filing-cap.ts +4 -6
- package/scripts/rules/firing-point.ts +6 -5
- package/scripts/rules/git-force.ts +5 -9
- package/scripts/rules/guard-remedy.ts +117 -0
- package/scripts/rules/implementation-cut.ts +37 -35
- package/scripts/rules/index-guard.ts +4 -7
- package/scripts/rules/issue-comments.ts +67 -16
- package/scripts/rules/josh-git-bare.ts +3 -6
- package/scripts/rules/lane-background.ts +10 -21
- package/scripts/rules/lane-carry-conflict.ts +7 -17
- package/scripts/rules/lane-interactive-ask.ts +6 -11
- package/scripts/rules/lane-park.ts +5 -13
- package/scripts/rules/lane-split-park.ts +2 -7
- package/scripts/rules/lane-switch-main.ts +9 -12
- package/scripts/rules/last-prompt.ts +50 -5
- package/scripts/rules/oracle-consulted.ts +4 -5
- package/scripts/rules/oracle-list-cli.ts +7 -0
- package/scripts/rules/piped-verification.ts +84 -32
- package/scripts/rules/poll-loop.ts +7 -17
- package/scripts/rules/pre-gate-cut.ts +7 -21
- package/scripts/rules/prior-comment-read.ts +7 -5
- package/scripts/rules/protected-files.ts +5 -9
- package/scripts/rules/raw-field-body.ts +3 -7
- package/scripts/rules/rule-body-guard.ts +4 -11
- package/scripts/rules/rule-list.ts +4 -1
- package/scripts/rules/rule-registry-rows.ts +10 -0
- package/scripts/rules/rule-registry.ts +7 -4
- package/scripts/rules/rule-rewrite.ts +114 -0
- package/scripts/rules/rule-value.ts +7 -1
- package/scripts/rules/run-tail-rule.ts +6 -22
- package/scripts/rules/shell-body-trigger.ts +4 -6
- package/scripts/rules/shell-segments.ts +22 -0
- package/scripts/rules/stop-decision.ts +77 -0
- package/scripts/rules/stop-rules.ts +164 -77
- package/scripts/rules/tail-commands.ts +15 -1
- package/scripts/rules/test-declared-commit.ts +4 -10
- package/scripts/rules/third-party-write.ts +5 -10
- package/scripts/rules/worktree-guard.ts +5 -12
- package/scripts/run/board/run-board-cli.ts +2 -0
- package/scripts/run/board/run-board-closed.ts +8 -2
- package/scripts/run/board/run-board-github.ts +19 -3
- package/scripts/run/board/run-board-header.ts +4 -1
- package/scripts/run/board/run-board-idle.ts +31 -0
- package/scripts/run/board/run-board-labels.ts +2 -0
- package/scripts/run/board/run-board-layout.ts +1 -1
- package/scripts/run/board/run-board-read.ts +25 -12
- package/scripts/run/board/run-board-reason.ts +17 -4
- package/scripts/run/board/run-board-render-legend.ts +1 -0
- package/scripts/run/board/run-board-render-slot.ts +1 -1
- package/scripts/run/board/run-board-render-waits.ts +41 -0
- package/scripts/run/board/run-board-render.ts +6 -1
- package/scripts/run/board/run-board-row-yield.ts +1 -0
- package/scripts/run/board/run-board-state.ts +9 -0
- package/scripts/run/board/run-board-status.ts +89 -23
- package/scripts/run/board/run-board-thanks.ts +7 -2
- package/scripts/run/board/run-board-tick.ts +37 -8
- package/scripts/run/carry/run-carry-args.ts +1 -3
- package/scripts/run/carry/run-carry-conversation.ts +7 -2
- package/scripts/run/cut/run-cut-cli.ts +18 -22
- package/scripts/run/cut/run-cut-decline.ts +72 -0
- package/scripts/run/cut/run-cut-ready.ts +74 -0
- package/scripts/run/cut/run-cut-report.ts +29 -0
- package/scripts/run/cut/run-cut.ts +10 -1
- package/scripts/run/detached-launch.ts +23 -4
- package/scripts/run/entry/run-entry-cli.ts +8 -1
- package/scripts/run/event/run-event-render.ts +1 -0
- package/scripts/run/event/run-event-scope.ts +19 -1
- package/scripts/run/event/run-event-stream-emit.ts +13 -6
- package/scripts/run/event/run-event-stream.ts +4 -0
- package/scripts/run/hold/run-hold-cli.ts +14 -3
- package/scripts/run/hold/run-hold-session.ts +46 -0
- package/scripts/run/hold/run-hold.ts +13 -4
- package/scripts/run/launch-priority.ts +32 -0
- package/scripts/run/merge/run-merge-cli.ts +16 -42
- package/scripts/run/merge/run-merge-ship.ts +59 -1
- package/scripts/run/merge/run-merge-signals.ts +99 -0
- package/scripts/run/merge/run-merge-steps.ts +11 -1
- package/scripts/run/merge/run-merge.ts +22 -9
- package/scripts/run/run-ending.ts +31 -3
- package/scripts/run/run-liveness.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +5 -10
- package/scripts/run/run-poll-hook.ts +157 -0
- package/scripts/run/run-preflight.ts +1 -2
- package/scripts/run/run-step-cli.ts +22 -15
- package/scripts/run/run-step-section.ts +85 -0
- package/scripts/run/run-stop-notify.ts +1 -2
- package/scripts/run/run-watcher-guard.ts +6 -3
- package/scripts/run/ship/run-ship-cli.ts +5 -12
- package/scripts/run/ship/run-ship-detach.ts +9 -0
- package/scripts/run/ship/run-ship-next.ts +10 -2
- package/scripts/run/ship/run-ship-overlap.ts +195 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +33 -15
- package/scripts/run/ship/run-ship-preflight.ts +28 -2
- package/scripts/run/ship/run-ship-return.ts +31 -7
- package/scripts/run/ship/run-ship-review-steps.ts +25 -14
- package/scripts/run/ship/run-ship-review.ts +15 -2
- package/scripts/run/ship/run-ship-steps.ts +1 -1
- package/scripts/run/ship/run-ship-stop-context.ts +206 -0
- package/scripts/run/ship/run-ship-sync.ts +14 -6
- package/scripts/run/tidy/run-tidy-cli.ts +3 -3
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -2
- package/scripts/safe-chain/project-config.ts +7 -2
- package/scripts/sync/sync-hook-safety.ts +8 -2
- package/scripts/test/test-e2e-guard.ts +30 -5
- package/scripts/test/test-unit-guard.ts +16 -1
- package/scripts/test/unit-worker-share.ts +26 -3
- package/scripts/time-runtime/time-batch-guard.ts +3 -3
- package/scripts/time-runtime/time-hook-transcript.ts +3 -2
- package/scripts/time-runtime/time-shell.ts +39 -4
- package/scripts/time-runtime/time-spans.ts +1 -0
- package/scripts/time-runtime/time-tool-call.ts +7 -0
- package/scripts/version/effective-upstream.ts +3 -4
- package/scripts/version/kit-version-config.ts +8 -2
- package/scripts/version/latest-corepack.ts +1 -2
- package/scripts/version/release-hold.ts +11 -4
- package/scripts/version/version-commands.ts +12 -4
- package/templates/gitignore +6 -2
- package/dist/hooks/chunk-D5QBTOCZ.js +0 -68
- package/dist/hooks/chunk-UT7YC3N2.js +0 -56
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { setTimeout as sleep } from 'node:timers/promises'
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
4
|
import { styleText } from 'node:util'
|
|
5
|
+
import { core_budget } from '#scripts/gate/core-budget'
|
|
5
6
|
import { machine_capacity } from '#scripts/gate/machine-capacity'
|
|
6
7
|
import { telegram_notify } from '#scripts/notify/telegram-notify'
|
|
7
8
|
import { run_progress } from '#scripts/run/progress/run-progress'
|
|
@@ -51,6 +52,7 @@ const LIVE_PORTS: BoardPorts = {
|
|
|
51
52
|
read_plan: async (scope) => await run_board_plan.read_plan(scope),
|
|
52
53
|
read_local: run_board_read.read_local,
|
|
53
54
|
read_machine: machine_capacity.read_sample,
|
|
55
|
+
read_waits: () => core_budget.budget_waits(),
|
|
54
56
|
read_usage: run_board_usage_read.usage_reader(),
|
|
55
57
|
read_closed: async (issues) => await run_board_closed.read_all(issues),
|
|
56
58
|
read_thanks: async () => await run_board_thanks_read.read_thanks(),
|
|
@@ -18,10 +18,13 @@ interface ClosedIssue {
|
|
|
18
18
|
closed_ms: number | undefined
|
|
19
19
|
// Closed by a merged pull request, rather than closed by hand.
|
|
20
20
|
is_merged: boolean
|
|
21
|
+
// Closed as not planned — withdrawn rather than finished (joshuafolkken/kit#3958).
|
|
22
|
+
is_not_planned: boolean
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
const CLOSED_FIELDS = 'title,state,closedAt,labels'
|
|
25
|
+
const CLOSED_FIELDS = 'title,state,stateReason,closedAt,labels'
|
|
24
26
|
const CLOSED_STATE = 'CLOSED'
|
|
27
|
+
const NOT_PLANNED_REASON = 'not_planned'
|
|
25
28
|
const STILL_OPEN = 'open' as const
|
|
26
29
|
|
|
27
30
|
// What one issue answered: closed, still open, or `undefined` when it could not be read.
|
|
@@ -41,6 +44,7 @@ const READ_CONCURRENCY = 4
|
|
|
41
44
|
const closed_schema = z.looseObject({
|
|
42
45
|
title: z.string(),
|
|
43
46
|
state: z.string(),
|
|
47
|
+
stateReason: z.string().nullish(),
|
|
44
48
|
closedAt: z.string().nullish(),
|
|
45
49
|
labels: z.array(issue_label_schema).default([]),
|
|
46
50
|
})
|
|
@@ -69,7 +73,9 @@ async function read_closed(issue: number): Promise<ClosedRead> {
|
|
|
69
73
|
|
|
70
74
|
const labels = view.labels.map((label) => label.name)
|
|
71
75
|
|
|
72
|
-
|
|
76
|
+
const is_not_planned = view.stateReason === NOT_PLANNED_REASON
|
|
77
|
+
|
|
78
|
+
return { title: view.title, labels, closed_ms: closed_ms_of(view), is_merged, is_not_planned }
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
async function read_all(
|
|
@@ -2,6 +2,7 @@ import { run_progress } from '#scripts/run/progress/run-progress'
|
|
|
2
2
|
import { run_progress_cli } from '#scripts/run/progress/run-progress-cli'
|
|
3
3
|
import type { ClosedAnswer } from './run-board-closed'
|
|
4
4
|
import { run_board_fetch, type Fetch } from './run-board-fetch'
|
|
5
|
+
import { run_board_idle } from './run-board-idle'
|
|
5
6
|
import { run_board_layout, type BoardPlan } from './run-board-layout'
|
|
6
7
|
import type { LocalRead } from './run-board-read'
|
|
7
8
|
import { run_board_state, type BoardPorts, type BoardState, type Pace } from './run-board-state'
|
|
@@ -72,8 +73,23 @@ function fold_plan(state: BoardState): BoardState {
|
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
// joshuafolkken/kit#3969: the planned issues whose open lane may be this run's though the stream never
|
|
77
|
+
// saw it launched. An earlier run's lane is not, so its issue waits until this run launches it.
|
|
78
|
+
function lanes_in_run(plan: BoardPlan, local: LocalRead): ReadonlySet<number> {
|
|
79
|
+
const earlier = new Set(local.earlier_lanes?.map(Number))
|
|
80
|
+
|
|
81
|
+
return new Set([...run_board_layout.numbers_of(plan)].filter((issue) => !earlier.has(issue)))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function statuses_for(
|
|
85
|
+
state: BoardState,
|
|
86
|
+
plan: BoardPlan,
|
|
87
|
+
local: LocalRead,
|
|
88
|
+
): ReadonlyMap<number, ItemStatus> {
|
|
89
|
+
const in_run = lanes_in_run(plan, local)
|
|
90
|
+
const stopped = run_board_idle.stopped_of(state.idle_since, state.read_ms)
|
|
91
|
+
|
|
92
|
+
return run_board_status.statuses_of(local.events, local.lanes, in_run, stopped)
|
|
77
93
|
}
|
|
78
94
|
|
|
79
95
|
// The children the run touched that the open listing no longer holds and the board has not read yet.
|
|
@@ -83,7 +99,7 @@ function unread_closed(state: BoardState, local: LocalRead): Array<number> {
|
|
|
83
99
|
|
|
84
100
|
if (open === undefined || state.plan === undefined) return []
|
|
85
101
|
|
|
86
|
-
const touched = [...statuses_for(state.plan, local).keys()]
|
|
102
|
+
const touched = [...statuses_for(state, state.plan, local).keys()]
|
|
87
103
|
|
|
88
104
|
return touched.filter((issue) => !open.has(issue) && !state.closed.has(issue))
|
|
89
105
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { styleText } from 'node:util'
|
|
2
2
|
import { backlog_budget } from '#scripts/backlog/backlog-budget'
|
|
3
|
+
import type { BudgetWait } from '#scripts/gate/core-wait'
|
|
3
4
|
import { run_board_fit } from './run-board-fit'
|
|
4
5
|
import { run_board_fresh } from './run-board-fresh'
|
|
5
6
|
import { run_board_labels } from './run-board-labels'
|
|
@@ -65,6 +66,8 @@ interface BoardHeader {
|
|
|
65
66
|
machine: MachineGauges | undefined
|
|
66
67
|
// Each running lane's CPU and memory, `undefined` where none could be read.
|
|
67
68
|
usages?: LaneUsages | undefined
|
|
69
|
+
// The claims waiting in the machine-wide core budget (`run-board-render-waits.ts`).
|
|
70
|
+
budget_waits?: ReadonlyArray<BudgetWait> | undefined
|
|
68
71
|
// How long each phase usually takes; a running row's phase time is colored against it.
|
|
69
72
|
usual?: UsualTimes | undefined
|
|
70
73
|
// The spinner's frame a running run and a running row turn, `undefined` where the output is not a
|
|
@@ -107,7 +110,7 @@ function count_state(rows: ReadonlyArray<BoardRow>, state: BoardRow['state']): n
|
|
|
107
110
|
function counts_of(layout: BoardLayout): BoardCounts {
|
|
108
111
|
const total = run_board_layout.rows_of(layout).length
|
|
109
112
|
const parked = count_state(layout.active, 'parked')
|
|
110
|
-
const settled =
|
|
113
|
+
const settled = layout.active.filter((row) => run_board_layout.is_settled(row.state)).length
|
|
111
114
|
const running = count_state(layout.active, 'running')
|
|
112
115
|
|
|
113
116
|
return { total, settled, parked, running, remaining: total - settled - running }
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { lane_await } from '#scripts/lane/lane-await'
|
|
2
|
+
|
|
3
|
+
// A lane is drawn stopped only once it has read idle for `lane_await.RECONFIRM_MS`: a boundary cut drops
|
|
4
|
+
// the child's process for a moment before its resume takes over, and one bare probe cannot tell that
|
|
5
|
+
// handoff from a child that died — `lane:await` re-confirms a disappearance over the same window. A live
|
|
6
|
+
// board carries when each lane was first read idle across its reads; a single frame has no earlier read,
|
|
7
|
+
// so it reads the lanes again after the window (`run-board-tick.ts`).
|
|
8
|
+
|
|
9
|
+
/** When each lane the last read found idle was first read so. */
|
|
10
|
+
type IdleSince = ReadonlyMap<string, number>
|
|
11
|
+
|
|
12
|
+
const NO_IDLE: IdleSince = new Map()
|
|
13
|
+
|
|
14
|
+
// The lanes read idle now, each keeping the moment it was first read so; a lane read working drops out.
|
|
15
|
+
function since_of(before: IdleSince, idle: ReadonlyArray<string>, now_ms: number): IdleSince {
|
|
16
|
+
return new Map(idle.map((lane) => [lane, before.get(lane) ?? now_ms]))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// The lanes idle for the whole window as of the read at `read_ms`; none before any read.
|
|
20
|
+
function stopped_of(since: IdleSince, read_ms: number | undefined): Array<string> {
|
|
21
|
+
if (read_ms === undefined) return []
|
|
22
|
+
|
|
23
|
+
const lasted = [...since].filter(([, at]) => read_ms - at >= lane_await.RECONFIRM_MS)
|
|
24
|
+
|
|
25
|
+
return lasted.map(([lane]) => lane)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const run_board_idle = { NO_IDLE, since_of, stopped_of }
|
|
29
|
+
|
|
30
|
+
export type { IdleSince }
|
|
31
|
+
export { run_board_idle }
|
|
@@ -43,6 +43,7 @@ const WORDS = {
|
|
|
43
43
|
merged: 'merged',
|
|
44
44
|
parked: 'parked',
|
|
45
45
|
done: 'done',
|
|
46
|
+
withdrawn: 'withdrawn',
|
|
46
47
|
in_progress: 'running',
|
|
47
48
|
stopped: 'stopped',
|
|
48
49
|
waiting: 'waiting',
|
|
@@ -104,6 +105,7 @@ const STATE_ICONS: Readonly<Record<ItemState, string>> = {
|
|
|
104
105
|
waiting: '⏳',
|
|
105
106
|
human: '🙋',
|
|
106
107
|
stopped: '🛑',
|
|
108
|
+
withdrawn: '🚫',
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
// The blocking edge, chosen on the same rule: ⛓ is a text symbol.
|
|
@@ -82,7 +82,7 @@ interface Drawn extends Overlay {
|
|
|
82
82
|
reason_of: ReasonOf | undefined
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
const SETTLED_STATES: ReadonlySet<ItemState> = new Set(['merged', 'parked', 'done'])
|
|
85
|
+
const SETTLED_STATES: ReadonlySet<ItemState> = new Set(['merged', 'parked', 'done', 'withdrawn'])
|
|
86
86
|
|
|
87
87
|
function is_settled(state: ItemState): boolean {
|
|
88
88
|
return SETTLED_STATES.has(state)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { NamedPlan } from '#scripts/backlog/backlog-plan'
|
|
2
|
+
import { backlog_ready } from '#scripts/backlog/backlog-ready'
|
|
2
3
|
import { backlogrun_launch } from '#scripts/backlog/backlogrun-launch'
|
|
3
|
-
import { lane_capacity } from '#scripts/lane/lane-capacity'
|
|
4
4
|
import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
|
|
5
|
+
import { lane_spent } from '#scripts/lane/lane-spent'
|
|
5
6
|
import { run_carry } from '#scripts/run/carry/run-carry'
|
|
6
7
|
import { run_carry_ended } from '#scripts/run/carry/run-carry-ended'
|
|
7
8
|
import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
|
|
@@ -33,21 +34,22 @@ interface LocalRead {
|
|
|
33
34
|
is_stranded: boolean
|
|
34
35
|
// The newest operation of each session of the run, read off the end of its log.
|
|
35
36
|
operations?: SessionOperations | undefined
|
|
36
|
-
//
|
|
37
|
-
//
|
|
37
|
+
// The open lanes no child is working in at this read (`lane-spent.ts`); one is drawn stopped once it
|
|
38
|
+
// has stayed so (`run-board-idle.ts`).
|
|
39
|
+
idle_lanes?: ReadonlyArray<string> | undefined
|
|
40
|
+
// The open lanes that last took a child before the run started — an earlier run's, until this run
|
|
41
|
+
// dispatches into one again.
|
|
42
|
+
earlier_lanes?: ReadonlyArray<string> | undefined
|
|
43
|
+
// How many more lanes the limit allows beside the live ones, as `lane:limit` counts them;
|
|
44
|
+
// `undefined` where the limit could not be read, so nothing is said about it.
|
|
38
45
|
free_lanes?: number | undefined
|
|
46
|
+
// The issues whose lanes hold a place under the limit (`backlog-occupied.ts`), named beside a row
|
|
47
|
+
// that waits for a free lane.
|
|
48
|
+
occupied_lanes?: ReadonlyArray<string> | undefined
|
|
39
49
|
// How long each phase usually takes, from the repository's lane ledger.
|
|
40
50
|
usual?: UsualTimes | undefined
|
|
41
51
|
}
|
|
42
52
|
|
|
43
|
-
async function free_lanes_of(lanes: ReadonlyArray<LaneInfo>): Promise<number | undefined> {
|
|
44
|
-
const choice = await lane_capacity.lane_limit()
|
|
45
|
-
|
|
46
|
-
if (choice.kind !== 'limit') return undefined
|
|
47
|
-
|
|
48
|
-
return lane_capacity.free_lanes(choice.limit, lane_registry.live_count(lanes))
|
|
49
|
-
}
|
|
50
|
-
|
|
51
53
|
const NO_SPAN: SpanHere = { span: undefined, resume: undefined, transcript: undefined }
|
|
52
54
|
|
|
53
55
|
interface SpanHere {
|
|
@@ -85,6 +87,13 @@ function sources_of(
|
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
|
|
90
|
+
// joshuafolkken/kit#3969: a lane whose last dispatch is unknown is not called earlier.
|
|
91
|
+
function earlier_lanes(lanes: ReadonlyArray<LaneInfo>, started_ms: number): Array<string> {
|
|
92
|
+
return lanes
|
|
93
|
+
.filter((lane) => lane.dispatched_ms !== undefined && lane.dispatched_ms < started_ms)
|
|
94
|
+
.map((lane) => lane.issue)
|
|
95
|
+
}
|
|
96
|
+
|
|
88
97
|
// `undefined` when no run has started here.
|
|
89
98
|
async function read_local(): Promise<LocalRead | undefined> {
|
|
90
99
|
const repository = await run_carry.repository_directory()
|
|
@@ -94,6 +103,7 @@ async function read_local(): Promise<LocalRead | undefined> {
|
|
|
94
103
|
|
|
95
104
|
const events = run_event_stream.read_events(run_event_stream.target_of(repository))
|
|
96
105
|
const lanes = await lane_registry.list_lanes()
|
|
106
|
+
const occupied = await backlog_ready.occupied_lanes(lanes)
|
|
97
107
|
|
|
98
108
|
return {
|
|
99
109
|
started_ms: span.started_ms,
|
|
@@ -104,7 +114,10 @@ async function read_local(): Promise<LocalRead | undefined> {
|
|
|
104
114
|
resume,
|
|
105
115
|
is_stranded: run_stranded_detect.is_stranded_at(repository),
|
|
106
116
|
operations: run_board_operation_read.read(sources_of(repository, lanes, transcript)),
|
|
107
|
-
|
|
117
|
+
idle_lanes: lane_spent.idle_lanes(lanes),
|
|
118
|
+
earlier_lanes: earlier_lanes(lanes, span.started_ms),
|
|
119
|
+
free_lanes: await backlog_ready.free_lanes_beside(lanes),
|
|
120
|
+
occupied_lanes: occupied.map((lane) => lane.issue),
|
|
108
121
|
usual: run_board_usual.read(repository),
|
|
109
122
|
}
|
|
110
123
|
}
|
|
@@ -5,6 +5,7 @@ import { run_event_setup } from '#scripts/run/event/run-event-setup'
|
|
|
5
5
|
import type { RunEvent } from '#scripts/run/event/run-event-stream'
|
|
6
6
|
import { run_board_layout, type Overlay, type ReasonOf, type RowReason } from './run-board-layout'
|
|
7
7
|
import { run_board_setup } from './run-board-setup'
|
|
8
|
+
import type { ItemStatus } from './run-board-status'
|
|
8
9
|
|
|
9
10
|
// Why each waiting row waits — pure, so the words are tested apart from the screen. A row whose lane is
|
|
10
11
|
// being opened says the stage that lane is at; any other says what `backlog:next` would answer for it,
|
|
@@ -35,6 +36,9 @@ interface ReasonRead extends Overlay {
|
|
|
35
36
|
events: ReadonlyArray<RunEvent>
|
|
36
37
|
// How many more lanes the limit allows; `undefined` where it could not be read.
|
|
37
38
|
free_lanes: number | undefined
|
|
39
|
+
// The issues whose lanes fill the limit, named after `no free lane` so a lane an earlier run left
|
|
40
|
+
// behind shows on the row it holds back.
|
|
41
|
+
occupied_lanes?: ReadonlyArray<string> | undefined
|
|
38
42
|
// A stopped run opens no lane, so a stage its stream ends on is not one any lane is at.
|
|
39
43
|
is_stopped: boolean
|
|
40
44
|
}
|
|
@@ -63,10 +67,13 @@ function is_untriaged_candidate(child: EpicChild, read: ReasonRead): boolean {
|
|
|
63
67
|
return !epic_triage.is_triaged(child) && !run_board_layout.is_blocked(child, read)
|
|
64
68
|
}
|
|
65
69
|
|
|
70
|
+
// A child whose lane stands with no one in it still holds the paths it declared, as its open lane does.
|
|
71
|
+
function holds_paths(status: ItemStatus): boolean {
|
|
72
|
+
return status.state === 'running' || status.lane !== undefined
|
|
73
|
+
}
|
|
74
|
+
|
|
66
75
|
function running_of(read: ReasonRead): Array<number> {
|
|
67
|
-
return [...read.statuses]
|
|
68
|
-
.filter(([, status]) => status.state === 'running')
|
|
69
|
-
.map(([issue]) => issue)
|
|
76
|
+
return [...read.statuses].filter(([, status]) => holds_paths(status)).map(([issue]) => issue)
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
function pool_of(read: ReasonRead): Pool {
|
|
@@ -88,6 +95,12 @@ function overlap_of(child: EpicChild, read: ReasonRead, pool: Pool): string | un
|
|
|
88
95
|
: `${WORDS.overlaps} ${String(clash.holder)} (${clash.path})`
|
|
89
96
|
}
|
|
90
97
|
|
|
98
|
+
function no_lane_of(occupied: ReadonlyArray<string> = []): string {
|
|
99
|
+
if (occupied.length === 0) return WORDS.no_lane
|
|
100
|
+
|
|
101
|
+
return `${WORDS.no_lane} — ${occupied.join(' ')}`
|
|
102
|
+
}
|
|
103
|
+
|
|
91
104
|
// A candidate nothing blocks, in the order `backlog:next` answers: the pool held for a judgment, then
|
|
92
105
|
// a path a running issue declares, then a pool with no lane left.
|
|
93
106
|
function offer_wait(child: EpicChild, read: ReasonRead, pool: Pool): string | undefined {
|
|
@@ -97,7 +110,7 @@ function offer_wait(child: EpicChild, read: ReasonRead, pool: Pool): string | un
|
|
|
97
110
|
|
|
98
111
|
if (overlap !== undefined) return overlap
|
|
99
112
|
|
|
100
|
-
return read.free_lanes === NO_FREE_LANES ?
|
|
113
|
+
return read.free_lanes === NO_FREE_LANES ? no_lane_of(read.occupied_lanes) : undefined
|
|
101
114
|
}
|
|
102
115
|
|
|
103
116
|
function wait_of(child: EpicChild, read: ReasonRead, pool: Pool): RowReason | undefined {
|
|
@@ -9,7 +9,7 @@ import { run_board_usage_text } from './run-board-usage-text'
|
|
|
9
9
|
// blanks on any other row.
|
|
10
10
|
|
|
11
11
|
const { finish_of, text_of } = run_board_usage_text
|
|
12
|
-
const FINISHED: ReadonlySet<ItemState> = new Set(['merged', 'done'])
|
|
12
|
+
const FINISHED: ReadonlySet<ItemState> = new Set(['merged', 'done', 'withdrawn'])
|
|
13
13
|
const BLANK = ' '
|
|
14
14
|
|
|
15
15
|
// What one frame's column is drawn from: each lane's usage, and the running rows the frame draws —
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { core_wait, type BudgetWait } from '#scripts/gate/core-wait'
|
|
2
|
+
|
|
3
|
+
// The claims waiting in the machine-wide core budget, under the header (joshuafolkken/kit#3943): a lane
|
|
4
|
+
// held back by memory pressure otherwise reads the same as one that is stuck. Each line names the
|
|
5
|
+
// command, the lane it runs in — the main checkout where none, and another repository's checkout by
|
|
6
|
+
// name, unlinked — how long it has waited, and why.
|
|
7
|
+
|
|
8
|
+
const MS_PER_SECOND = 1000
|
|
9
|
+
// 🚧 rather than ⏳, which a waiting row already draws, or 🚦, the gate stage's; an emoji a terminal
|
|
10
|
+
// draws two columns wide.
|
|
11
|
+
const BUDGET_ICON = '🚧'
|
|
12
|
+
const GAP = ' '
|
|
13
|
+
const MAIN_CHECKOUT = 'main'
|
|
14
|
+
|
|
15
|
+
function place_text(wait: BudgetWait, link: (reference: string) => string): string {
|
|
16
|
+
if (wait.elsewhere !== undefined) return wait.elsewhere
|
|
17
|
+
|
|
18
|
+
return wait.lane === undefined ? MAIN_CHECKOUT : link(wait.lane)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function wait_text(wait: BudgetWait, link: (reference: string) => string): string {
|
|
22
|
+
const lane = place_text(wait, link)
|
|
23
|
+
const seconds = `${String(Math.round(wait.waited_ms / MS_PER_SECOND))}s`
|
|
24
|
+
const parts = [wait.command ?? 'a step', lane, seconds, core_wait.REASON_TEXT[wait.reason]]
|
|
25
|
+
|
|
26
|
+
return `${BUDGET_ICON} ${parts.join(GAP)}`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Nothing is drawn while no claim waits.
|
|
30
|
+
function wait_lines(
|
|
31
|
+
waits: ReadonlyArray<BudgetWait> | undefined,
|
|
32
|
+
link: (reference: string) => string,
|
|
33
|
+
): Array<string> {
|
|
34
|
+
if (waits === undefined || waits.length === 0) return []
|
|
35
|
+
|
|
36
|
+
return ['', ...waits.map((wait) => wait_text(wait, link))]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const run_board_render_waits = { BUDGET_ICON, wait_lines }
|
|
40
|
+
|
|
41
|
+
export { run_board_render_waits }
|
|
@@ -24,6 +24,7 @@ import { run_board_render_slot, type UsageSlot } from './run-board-render-slot'
|
|
|
24
24
|
import { run_board_render_tail } from './run-board-render-tail'
|
|
25
25
|
import { run_board_render_thanks } from './run-board-render-thanks'
|
|
26
26
|
import { run_board_render_title } from './run-board-render-title'
|
|
27
|
+
import { run_board_render_waits } from './run-board-render-waits'
|
|
27
28
|
import { run_board_row_yield } from './run-board-row-yield'
|
|
28
29
|
import type { Thanks } from './run-board-thanks-csv'
|
|
29
30
|
|
|
@@ -388,7 +389,11 @@ function bounded(parts: FrameParts, bounds: FrameBounds): Array<string> {
|
|
|
388
389
|
|
|
389
390
|
function render(view: BoardView): Array<string> {
|
|
390
391
|
const { header, notes } = view
|
|
391
|
-
const above = [
|
|
392
|
+
const above = [
|
|
393
|
+
...run_board_header.header_lines(header),
|
|
394
|
+
...run_board_render_waits.wait_lines(header.budget_waits, header.link),
|
|
395
|
+
...resume_lines(view.resume),
|
|
396
|
+
]
|
|
392
397
|
const parts = {
|
|
393
398
|
above,
|
|
394
399
|
plan: plan_sections(header, view.size),
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { NamedPlan } from '#scripts/backlog/backlog-plan'
|
|
2
|
+
import type { BudgetWait } from '#scripts/gate/core-wait'
|
|
2
3
|
import type { MachineSample } from '#scripts/gate/machine-capacity'
|
|
3
4
|
import type { ClosedAnswer, ClosedIssue } from './run-board-closed'
|
|
4
5
|
import type { Fetch } from './run-board-fetch'
|
|
5
6
|
import type { TerminalSize } from './run-board-fit'
|
|
6
7
|
import type { BoardForm } from './run-board-header'
|
|
8
|
+
import { run_board_idle, type IdleSince } from './run-board-idle'
|
|
7
9
|
import type { BoardPlan } from './run-board-layout'
|
|
8
10
|
import type { Link } from './run-board-link'
|
|
9
11
|
import type { MachineGauges, MachineMark } from './run-board-machine'
|
|
@@ -20,6 +22,8 @@ interface BoardPorts {
|
|
|
20
22
|
// `undefined` when no run has started here.
|
|
21
23
|
read_local: () => Promise<LocalRead | undefined>
|
|
22
24
|
read_machine: () => Promise<MachineSample>
|
|
25
|
+
// The claims waiting in the core budget, read on the machine's second; none where it is not given.
|
|
26
|
+
read_waits?: (() => Array<BudgetWait>) | undefined
|
|
23
27
|
// Every process and its lane, the last reading's lanes reused (`run-board-usage-read.ts`).
|
|
24
28
|
read_usage: (before: UsageMark | undefined) => Promise<UsageMark | undefined>
|
|
25
29
|
// The issues that answered as closed, and whether every issue answered (`run-board-closed.ts`).
|
|
@@ -56,6 +60,8 @@ interface BoardState {
|
|
|
56
60
|
// The last local read, drawn until the next is due; `undefined` when no run had started.
|
|
57
61
|
local: LocalRead | undefined
|
|
58
62
|
read_ms: number | undefined
|
|
63
|
+
// When each lane the reads found idle was first read so (`run-board-idle.ts`).
|
|
64
|
+
idle_since: IdleSince
|
|
59
65
|
// The start of the run the plan state was built for, so a run that begins draws nothing of the last.
|
|
60
66
|
run_started_ms: number | undefined
|
|
61
67
|
plan: BoardPlan | undefined
|
|
@@ -82,6 +88,7 @@ interface BoardState {
|
|
|
82
88
|
// them.
|
|
83
89
|
usage: UsageMark | undefined
|
|
84
90
|
usages: LaneUsages | undefined
|
|
91
|
+
budget_waits: ReadonlyArray<BudgetWait>
|
|
85
92
|
// The reviewers drawn above the legend, the read of them in flight, and when it was last launched.
|
|
86
93
|
thanks: Thanks
|
|
87
94
|
thanks_fetch: Fetch<Thanks> | undefined
|
|
@@ -91,6 +98,7 @@ interface BoardState {
|
|
|
91
98
|
const FRESH_STATE: BoardState = {
|
|
92
99
|
local: undefined,
|
|
93
100
|
read_ms: undefined,
|
|
101
|
+
idle_since: run_board_idle.NO_IDLE,
|
|
94
102
|
run_started_ms: undefined,
|
|
95
103
|
plan: undefined,
|
|
96
104
|
plan_fetch: undefined,
|
|
@@ -108,6 +116,7 @@ const FRESH_STATE: BoardState = {
|
|
|
108
116
|
spots: [],
|
|
109
117
|
usage: undefined,
|
|
110
118
|
usages: undefined,
|
|
119
|
+
budget_waits: [],
|
|
111
120
|
thanks: [],
|
|
112
121
|
thanks_fetch: undefined,
|
|
113
122
|
thanks_attempted_ms: undefined,
|