@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,11 +2,13 @@ import {
|
|
|
2
2
|
ENV_FILE_NAME,
|
|
3
3
|
cost_transcript,
|
|
4
4
|
json_value,
|
|
5
|
+
lane_paths,
|
|
6
|
+
pr_raw_schema,
|
|
5
7
|
process_identity,
|
|
6
8
|
process_owner_schema,
|
|
7
9
|
run_carry,
|
|
8
10
|
time_instant
|
|
9
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-APUO6U4J.js";
|
|
10
12
|
import {
|
|
11
13
|
PLATFORM_TEMP_ROOT,
|
|
12
14
|
PROBE_TIMEOUT_MS,
|
|
@@ -100,1014 +102,438 @@ var COMMAND_PHASES = /* @__PURE__ */ new Map([
|
|
|
100
102
|
["josh followup", MERGE_PHASE]
|
|
101
103
|
]);
|
|
102
104
|
|
|
103
|
-
// scripts/
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
var CSPELL_CACHE_FILE = ".cspellcache";
|
|
109
|
-
var ESLINT_EDIT_CACHE_FILE = ".eslintcache.edit";
|
|
110
|
-
var ESLINT_RELATED_CACHE_FILE = ".eslintcache.related";
|
|
111
|
-
var ROOTED_JSON_PORTABILITY = "rooted-json";
|
|
112
|
-
var ESLINT_CACHE_SPEC = {
|
|
113
|
-
cache_file: ESLINT_CACHE_FILE,
|
|
114
|
-
portability: ROOTED_JSON_PORTABILITY
|
|
115
|
-
};
|
|
116
|
-
var TS_CACHE_SPEC = {
|
|
117
|
-
cache_file: TS_BUILD_INFO_FILE,
|
|
118
|
-
portability: "raw"
|
|
119
|
-
};
|
|
120
|
-
var CSPELL_CACHE_SPEC = {
|
|
121
|
-
cache_file: CSPELL_CACHE_FILE,
|
|
122
|
-
portability: "raw"
|
|
123
|
-
};
|
|
124
|
-
var GATE_CACHE_SPECS = [
|
|
125
|
-
ESLINT_CACHE_SPEC,
|
|
126
|
-
TS_CACHE_SPEC,
|
|
127
|
-
CSPELL_CACHE_SPEC
|
|
128
|
-
];
|
|
129
|
-
var GATE_CACHE_FILES = GATE_CACHE_SPECS.map((spec) => spec.cache_file);
|
|
130
|
-
var IGNORED_CACHE_FILES = [
|
|
131
|
-
...GATE_CACHE_FILES,
|
|
132
|
-
ESLINT_EDIT_CACHE_FILE,
|
|
133
|
-
ESLINT_RELATED_CACHE_FILE
|
|
134
|
-
];
|
|
135
|
-
var CONTENT_CACHE_FLAGS = ["--cache", "--cache-strategy", "content"];
|
|
136
|
-
var CACHE_LOCATION_FLAG = "--cache-location";
|
|
137
|
-
function content_cache_flags(cache_file) {
|
|
138
|
-
return [...CONTENT_CACHE_FLAGS, CACHE_LOCATION_FLAG, cache_file];
|
|
139
|
-
}
|
|
140
|
-
var ESLINT_CACHE_FLAGS = content_cache_flags(ESLINT_CACHE_FILE);
|
|
141
|
-
var ESLINT_EDIT_CACHE_FLAGS = content_cache_flags(ESLINT_EDIT_CACHE_FILE);
|
|
142
|
-
var ESLINT_RELATED_CACHE_FLAGS = content_cache_flags(ESLINT_RELATED_CACHE_FILE);
|
|
143
|
-
var CSPELL_CACHE_FLAGS = content_cache_flags(CSPELL_CACHE_FILE);
|
|
105
|
+
// scripts/gate/core-budget.ts
|
|
106
|
+
import { randomUUID } from "node:crypto";
|
|
107
|
+
import { readdirSync as readdirSync2 } from "node:fs";
|
|
108
|
+
import { availableParallelism as availableParallelism3 } from "node:os";
|
|
109
|
+
import path3 from "node:path";
|
|
144
110
|
|
|
145
|
-
// scripts/
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
script: "scripts/backlog/backlog-drive-cli.ts",
|
|
172
|
-
description: "Drive backlogrun through offer, launch and merge; restore this run\u2019s lanes and report when complete",
|
|
173
|
-
category: "AI tools",
|
|
174
|
-
reference: ["--owner <pid> [options]", "automation", ["network"]]
|
|
175
|
-
},
|
|
176
|
-
"backlog:plan": {
|
|
177
|
-
script: "scripts/backlog/backlog-plan-cli.ts",
|
|
178
|
-
description: "Print the whole backlog as a plan: ready now, waiting on what, waiting on a person, out of scope",
|
|
179
|
-
category: "AI tools",
|
|
180
|
-
reference: [
|
|
181
|
-
"[issue...] [--only] [--waves] [--exclude <n>[,<n>...]]",
|
|
182
|
-
"automation",
|
|
183
|
-
["network"]
|
|
184
|
-
]
|
|
185
|
-
},
|
|
186
|
-
"backlog:stalled": {
|
|
187
|
-
script: "scripts/backlog/backlog-stalled-cli.ts",
|
|
188
|
-
// A stall sends one Telegram warning. The `Stop` hook calls the detector
|
|
189
|
-
// directly, so this flag costs only the manual command its in-process dispatch.
|
|
190
|
-
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
191
|
-
description: "Report whether ready backlog work is sitting undispatched with a free lane and no recent dispatch",
|
|
192
|
-
category: "AI tools",
|
|
193
|
-
reference: ["", "automation", ["network"]]
|
|
194
|
-
},
|
|
195
|
-
"backlog:budget": {
|
|
196
|
-
script: "scripts/backlog/backlog-budget-cli.ts",
|
|
197
|
-
description: "Say whether a backlogrun may start more work, keep watching, or finish",
|
|
198
|
-
category: "AI tools",
|
|
199
|
-
reference: ["[options]", "automation", ["none"]]
|
|
111
|
+
// scripts/test/unit-worker-share.ts
|
|
112
|
+
import { readdirSync } from "node:fs";
|
|
113
|
+
import { availableParallelism } from "node:os";
|
|
114
|
+
import path from "node:path";
|
|
115
|
+
var RUN_PREFIX = "josh-unit-running-";
|
|
116
|
+
var WORKER_FLAG = "--maxWorkers";
|
|
117
|
+
var WORKER_FLAGS = [WORKER_FLAG, "--max-workers"];
|
|
118
|
+
var MIN_WORKERS = 1;
|
|
119
|
+
var SOLO_RUNS = 1;
|
|
120
|
+
function marker_path(pid = process.pid) {
|
|
121
|
+
return stamp_file.stamp_path(RUN_PREFIX, String(pid));
|
|
122
|
+
}
|
|
123
|
+
function is_running(marker) {
|
|
124
|
+
return process_identity.is_same_process(marker.pid, marker.process_start) !== false;
|
|
125
|
+
}
|
|
126
|
+
function read_marker(source) {
|
|
127
|
+
const raw = stamp_file.read_stamp_text(source);
|
|
128
|
+
if (raw === void 0) return void 0;
|
|
129
|
+
const parsed = process_owner_schema.safeParse(json_value.parse_or_undefined(raw));
|
|
130
|
+
return parsed.success ? parsed.data : void 0;
|
|
131
|
+
}
|
|
132
|
+
function marker_files(directory = PLATFORM_TEMP_ROOT) {
|
|
133
|
+
try {
|
|
134
|
+
return readdirSync(directory).filter((name) => name.startsWith(RUN_PREFIX));
|
|
135
|
+
} catch {
|
|
136
|
+
return [];
|
|
200
137
|
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
script: "scripts/document/document-section-cli.ts",
|
|
207
|
-
description: 'Print one section of a markdown document, for a `file.md` \u2192 "Heading" reference',
|
|
208
|
-
category: "AI tools",
|
|
209
|
-
reference: ["<file> <heading>", "automation", ["none"]],
|
|
210
|
-
is_bundled: true
|
|
211
|
-
},
|
|
212
|
-
"read:set": {
|
|
213
|
-
script: "scripts/document/read-set-cli.ts",
|
|
214
|
-
description: "Print what an entry point reads before it starts, and what that read costs",
|
|
215
|
-
category: "AI tools",
|
|
216
|
-
reference: ["[<entry>] [--json]", "automation", ["none"]]
|
|
217
|
-
},
|
|
218
|
-
"doc:read": {
|
|
219
|
-
script: "scripts/document/document-read-cli.ts",
|
|
220
|
-
description: "Read a whole document safely: print it, or point at the Read tool when over the Bash cap",
|
|
221
|
-
category: "AI tools",
|
|
222
|
-
reference: ["<file>", "automation", ["none"]]
|
|
223
|
-
},
|
|
224
|
-
"read:files": {
|
|
225
|
-
script: "scripts/document/read-files-cli.ts",
|
|
226
|
-
description: "Read several files in one call so edit targets fold into one turn",
|
|
227
|
-
category: "AI tools",
|
|
228
|
-
reference: ["<path> [<path> ...]", "automation", ["none"]]
|
|
229
|
-
},
|
|
230
|
-
"edit:files": {
|
|
231
|
-
script: "scripts/document/edit-files-cli.ts",
|
|
232
|
-
description: "Apply several content-addressed edits from a plan in one call",
|
|
233
|
-
category: "AI tools",
|
|
234
|
-
reference: ["<plan-path | ->", "automation", ["none"]]
|
|
138
|
+
}
|
|
139
|
+
function sweep_marker(source) {
|
|
140
|
+
try {
|
|
141
|
+
stamp_file.remove_stamp(source);
|
|
142
|
+
} catch {
|
|
235
143
|
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
144
|
+
}
|
|
145
|
+
function is_marker_live(source) {
|
|
146
|
+
const marker = read_marker(source);
|
|
147
|
+
if (marker === void 0) return false;
|
|
148
|
+
if (is_running(marker)) return true;
|
|
149
|
+
sweep_marker(source);
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
function live_run_count(directory = PLATFORM_TEMP_ROOT) {
|
|
153
|
+
return marker_files(directory).filter((name) => is_marker_live(path.join(directory, name))).length;
|
|
154
|
+
}
|
|
155
|
+
var NESTED_KEY = "JOSH_UNIT_RUN_MARKED";
|
|
156
|
+
var NESTED_VALUE = "1";
|
|
157
|
+
function is_nested_run() {
|
|
158
|
+
return process.env[NESTED_KEY] === NESTED_VALUE;
|
|
159
|
+
}
|
|
160
|
+
function resolve_unit_workers(available_cores, runs2) {
|
|
161
|
+
if (runs2 <= SOLO_RUNS) return void 0;
|
|
162
|
+
return Math.max(MIN_WORKERS, Math.floor(available_cores / runs2));
|
|
163
|
+
}
|
|
164
|
+
function cap_to_free(workers, free_cores, available_cores) {
|
|
165
|
+
if (free_cores === void 0 || free_cores >= (workers ?? available_cores)) return workers;
|
|
166
|
+
return Math.max(MIN_WORKERS, Math.floor(free_cores));
|
|
167
|
+
}
|
|
168
|
+
function current_share(available_cores = availableParallelism(), live_runs = live_run_count(), free_cores) {
|
|
169
|
+
const own_run2 = is_nested_run() ? 0 : SOLO_RUNS;
|
|
170
|
+
const share = resolve_unit_workers(available_cores, live_runs + own_run2);
|
|
171
|
+
return cap_to_free(share, free_cores, available_cores);
|
|
172
|
+
}
|
|
173
|
+
function is_worker_flag(argument) {
|
|
174
|
+
return WORKER_FLAGS.some((flag) => argument === flag || argument.startsWith(`${flag}=`));
|
|
175
|
+
}
|
|
176
|
+
function has_worker_flag(vitest_arguments) {
|
|
177
|
+
return vitest_arguments.some((argument) => is_worker_flag(argument));
|
|
178
|
+
}
|
|
179
|
+
function worker_arguments(vitest_arguments, share) {
|
|
180
|
+
if (share === void 0 || has_worker_flag(vitest_arguments)) return [];
|
|
181
|
+
return [`${WORKER_FLAG}=${String(share)}`];
|
|
182
|
+
}
|
|
183
|
+
function mark_run_started(target2) {
|
|
184
|
+
try {
|
|
185
|
+
stamp_file.write_stamp(target2, process_identity.own_fields());
|
|
186
|
+
} catch {
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
async function with_run_marker(run) {
|
|
190
|
+
if (is_nested_run()) return await run();
|
|
191
|
+
const target2 = marker_path();
|
|
192
|
+
mark_run_started(target2);
|
|
193
|
+
process.env[NESTED_KEY] = NESTED_VALUE;
|
|
194
|
+
try {
|
|
195
|
+
return await run();
|
|
196
|
+
} finally {
|
|
197
|
+
process.env[NESTED_KEY] = "";
|
|
198
|
+
stamp_file.remove_stamp(target2);
|
|
257
199
|
}
|
|
200
|
+
}
|
|
201
|
+
var unit_worker_share = {
|
|
202
|
+
MIN_WORKERS,
|
|
203
|
+
NESTED_KEY,
|
|
204
|
+
NESTED_VALUE,
|
|
205
|
+
RUN_PREFIX,
|
|
206
|
+
SOLO_RUNS,
|
|
207
|
+
cap_to_free,
|
|
208
|
+
current_share,
|
|
209
|
+
has_worker_flag,
|
|
210
|
+
is_nested_run,
|
|
211
|
+
live_run_count,
|
|
212
|
+
marker_path,
|
|
213
|
+
read_marker,
|
|
214
|
+
resolve_unit_workers,
|
|
215
|
+
with_run_marker,
|
|
216
|
+
worker_arguments
|
|
258
217
|
};
|
|
259
218
|
|
|
260
|
-
// scripts/
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
reference: ["<title> [--body <summary> | --body-file <path>]", "automation", ["network"]]
|
|
286
|
-
},
|
|
287
|
-
"defect:rate": {
|
|
288
|
-
script: "scripts/issue/defect-rate-cli.ts",
|
|
289
|
-
description: "Print the defect rate of merged work: defects filed per enhancement completed",
|
|
290
|
-
category: "AI tools",
|
|
291
|
-
reference: ["[--days <n>]", "automation", ["network"]]
|
|
292
|
-
},
|
|
293
|
-
"issue:fold": {
|
|
294
|
-
script: "scripts/issue/issue-fold-cli.ts",
|
|
295
|
-
description: "Before a second filing: say whether findings from this session fold into one issue",
|
|
296
|
-
category: "AI tools",
|
|
297
|
-
reference: ["<title>... [--not-separable] [--json]", "automation", ["none"]]
|
|
298
|
-
},
|
|
299
|
-
"issue:fold-existing": {
|
|
300
|
-
script: "scripts/issue/issue-fold-existing-cli.ts",
|
|
301
|
-
description: "Assess whether a complete draft can join an unstarted issue",
|
|
302
|
-
category: "AI tools",
|
|
303
|
-
reference: ["<assessment.json> [--json]", "automation", ["none"]]
|
|
304
|
-
},
|
|
305
|
-
"issue:cite": {
|
|
306
|
-
script: "scripts/issue/issue-cite-cli.ts",
|
|
307
|
-
description: "Print the paste-ready number-link citation line for each issue, in one call",
|
|
308
|
-
category: "AI tools",
|
|
309
|
-
reference: [ISSUES_WITH_REPO, "automation", ["network"]]
|
|
310
|
-
},
|
|
311
|
-
"issue:comment": {
|
|
312
|
-
script: "scripts/issue/issue-comment-cli.ts",
|
|
313
|
-
description: "Post one comment to an issue from a file, so no shell expands the body",
|
|
314
|
-
category: "AI tools",
|
|
315
|
-
reference: ["<issue> --body <text> | --body-file <path>", "automation", ["network"]]
|
|
316
|
-
},
|
|
317
|
-
"issue:file": {
|
|
318
|
-
script: "scripts/issue/issue-file-cli.ts",
|
|
319
|
-
description: "File an Issue with every filing step: lint, Origin, fold, WIP cap, duplicate scout, labels, then epic:bundle",
|
|
320
|
-
category: "AI tools",
|
|
321
|
-
reference: [
|
|
322
|
-
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok] [--release]",
|
|
323
|
-
"automation",
|
|
324
|
-
["network"]
|
|
325
|
-
]
|
|
326
|
-
},
|
|
327
|
-
"issue:release": {
|
|
328
|
-
script: "scripts/issue/issue-release-cli.ts",
|
|
329
|
-
description: "Link an Issue to the repository's open release Issue as its blocker (or, with --wait, as waiting on it), filing one when none is open",
|
|
330
|
-
category: "AI tools",
|
|
331
|
-
reference: ["<issue> [--wait]", "automation", ["network"]]
|
|
219
|
+
// scripts/gate/core-budget.ts
|
|
220
|
+
import { z as z2 } from "zod";
|
|
221
|
+
|
|
222
|
+
// scripts/gate/core-admission.ts
|
|
223
|
+
var MS_PER_SECOND = 1e3;
|
|
224
|
+
var RAMP_UP_MS = 3e4;
|
|
225
|
+
function compare_claim(left, right) {
|
|
226
|
+
const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
|
|
227
|
+
return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
|
|
228
|
+
}
|
|
229
|
+
function add_load(totals, reservation) {
|
|
230
|
+
totals.cores += reservation.weight;
|
|
231
|
+
totals.memory_mb += reservation.memory_mb ?? 0;
|
|
232
|
+
}
|
|
233
|
+
function exceeds(totals, budget) {
|
|
234
|
+
return totals.cores > budget.cores || totals.memory_mb > budget.memory_mb;
|
|
235
|
+
}
|
|
236
|
+
function admitted_keys(reservations, budget, memory_budget = Infinity) {
|
|
237
|
+
const limit = { cores: budget, memory_mb: memory_budget };
|
|
238
|
+
const totals = { cores: 0, memory_mb: 0 };
|
|
239
|
+
const admitted = /* @__PURE__ */ new Set();
|
|
240
|
+
for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
|
|
241
|
+
add_load(totals, entry.reservation);
|
|
242
|
+
if (index !== 0 && exceeds(totals, limit)) break;
|
|
243
|
+
admitted.add(entry.key);
|
|
332
244
|
}
|
|
245
|
+
return admitted;
|
|
246
|
+
}
|
|
247
|
+
function is_admitted(key, reservations, budget) {
|
|
248
|
+
return admitted_keys(reservations, budget.cores, budget.memory_mb).has(key);
|
|
249
|
+
}
|
|
250
|
+
function sum_load(reservations) {
|
|
251
|
+
const load = { cores: 0, memory_mb: 0 };
|
|
252
|
+
for (const entry of reservations) add_load(load, entry.reservation);
|
|
253
|
+
return load;
|
|
254
|
+
}
|
|
255
|
+
function is_ramped(reservation, now) {
|
|
256
|
+
const { admitted_at } = reservation;
|
|
257
|
+
return admitted_at !== void 0 && now - admitted_at >= RAMP_UP_MS;
|
|
258
|
+
}
|
|
259
|
+
function ledger_load(reservations, now) {
|
|
260
|
+
const admitted = reservations.filter((entry) => entry.reservation.admitted_at !== void 0);
|
|
261
|
+
const ramped = admitted.filter((entry) => is_ramped(entry.reservation, now));
|
|
262
|
+
return { cores: sum_load(admitted).cores, memory_mb: sum_load(ramped).memory_mb };
|
|
263
|
+
}
|
|
264
|
+
function total_weight(reservations) {
|
|
265
|
+
return sum_load(reservations).cores;
|
|
266
|
+
}
|
|
267
|
+
function admitted_load(reservations, budget) {
|
|
268
|
+
const admitted = admitted_keys(reservations, budget);
|
|
269
|
+
return total_weight(reservations.filter((entry) => admitted.has(entry.key)));
|
|
270
|
+
}
|
|
271
|
+
function describe_memory(ledger, budget) {
|
|
272
|
+
if (!Number.isFinite(budget.memory_mb)) return "";
|
|
273
|
+
return ` and ${String(Math.round(ledger.memory_mb))} MB of memory against ${String(Math.round(budget.memory_mb))} MB`;
|
|
274
|
+
}
|
|
275
|
+
function describe_overflow(admission) {
|
|
276
|
+
const { overflow } = admission;
|
|
277
|
+
if (overflow === void 0) return void 0;
|
|
278
|
+
const { ledger, budget } = overflow;
|
|
279
|
+
const waited = String(Math.round(overflow.waited_ms / MS_PER_SECOND));
|
|
280
|
+
const cores = `the ledger held ${String(ledger.cores)} cores against a budget of ${String(budget.cores)}`;
|
|
281
|
+
return `started past the core budget after ${waited}s \u2014 ${cores}${describe_memory(ledger, budget)}`;
|
|
282
|
+
}
|
|
283
|
+
var core_admission = {
|
|
284
|
+
RAMP_UP_MS,
|
|
285
|
+
admitted_keys,
|
|
286
|
+
admitted_load,
|
|
287
|
+
describe_overflow,
|
|
288
|
+
is_admitted,
|
|
289
|
+
ledger_load,
|
|
290
|
+
sum_load
|
|
333
291
|
};
|
|
334
292
|
|
|
335
|
-
// scripts/
|
|
336
|
-
|
|
337
|
-
var
|
|
338
|
-
var
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
293
|
+
// scripts/gate/core-wait.ts
|
|
294
|
+
import path2 from "node:path";
|
|
295
|
+
var WAIT_REASONS = ["cores", "memory", "pressure"];
|
|
296
|
+
var REASON_TEXT = {
|
|
297
|
+
cores: "not enough free cores",
|
|
298
|
+
memory: "not enough free memory",
|
|
299
|
+
pressure: "memory under pressure"
|
|
342
300
|
};
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
reference: ["", "automation", ["none"]],
|
|
363
|
-
default_script_arguments: ["list"]
|
|
364
|
-
},
|
|
365
|
-
"lane:prune": {
|
|
366
|
-
...LANE_ARGUMENTS,
|
|
367
|
-
description: "Close every lane an interruption left without its work tree and every spent lane, then sweep unregistered leftovers under the lanes root",
|
|
368
|
-
category: "AI tools",
|
|
369
|
-
reference: ["", "automation", ["files", "git"]],
|
|
370
|
-
default_script_arguments: ["prune"]
|
|
371
|
-
},
|
|
372
|
-
"lane:output": {
|
|
373
|
-
...LANE_ARGUMENTS,
|
|
374
|
-
description: "Record, or read back, where the unit running a lane\u2019s child writes",
|
|
375
|
-
category: "AI tools",
|
|
376
|
-
reference: ["<issue> [path]", "automation", ["files"]],
|
|
377
|
-
default_script_arguments: ["output"]
|
|
378
|
-
},
|
|
379
|
-
"lane:dispatch": {
|
|
380
|
-
...LANE_ARGUMENTS,
|
|
381
|
-
description: "Start a lane\u2019s child as a detached process that outlives this session",
|
|
382
|
-
category: "AI tools",
|
|
383
|
-
reference: ["<issue> <prompt>", "automation", ["processes"]],
|
|
384
|
-
default_script_arguments: ["dispatch"]
|
|
385
|
-
},
|
|
386
|
-
"lane:await": {
|
|
387
|
-
...LANE_ARGUMENTS,
|
|
388
|
-
description: "Block until any of the named in-flight lane children completes; prints which one finished",
|
|
389
|
-
category: "AI tools",
|
|
390
|
-
reference: ["<issue> [<issue>...] [--owner <pid>]", "automation", ["files", "processes"]],
|
|
391
|
-
default_script_arguments: ["await"]
|
|
392
|
-
},
|
|
393
|
-
"lane:launch": {
|
|
394
|
-
script: "scripts/lane/lane-launch-cli.ts",
|
|
395
|
-
description: "Collapse a backlogrun lane-start event into one call: open the lane, pop and re-install on the first, dispatch the child",
|
|
396
|
-
category: "AI tools",
|
|
397
|
-
reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
|
|
398
|
-
},
|
|
399
|
-
// `.env` is read for `JOSH_LANE_ROOT`, as every lane command reads it, so the lane is found.
|
|
400
|
-
"lane:restart": {
|
|
401
|
-
script: "scripts/lane/lane-restart-cli.ts",
|
|
402
|
-
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
403
|
-
description: "Stop a running lane child, stash its uncommitted work and re-dispatch its issue in a fresh session \u2014 not counted as an outage or a failure",
|
|
404
|
-
category: "AI tools",
|
|
405
|
-
reference: ["<issue>", "developer", ["files", "git", "processes", "network"]]
|
|
406
|
-
},
|
|
407
|
-
// A live run's lane limit: `.env` is read so the bare form reports the
|
|
408
|
-
// `JOSH_LANE_LIMIT` a person set there when no override stands.
|
|
409
|
-
"lane:limit": {
|
|
410
|
-
script: "scripts/lane/lane-limit-cli.ts",
|
|
411
|
-
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
412
|
-
description: "Change a live backlogrun\u2019s lane limit without stopping it, or print the limit, lanes in use and free lanes",
|
|
413
|
-
category: "AI tools",
|
|
414
|
-
reference: ["[<limit>] [--reset]", "developer", ["files"]]
|
|
415
|
-
},
|
|
416
|
-
// The lane-limit measurement: `.env` is read so `lane:stats` labels the row
|
|
417
|
-
// with the `JOSH_LANE_LIMIT` a person set there.
|
|
418
|
-
"lane:sample": {
|
|
419
|
-
...MEASURE_ARGUMENTS,
|
|
420
|
-
description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger \u2014 a backlogrun samples itself, this is for a reading outside one",
|
|
421
|
-
category: "AI tools",
|
|
422
|
-
reference: ["[--every <seconds>]", "maintainer", ["files"]],
|
|
423
|
-
default_script_arguments: ["sample"]
|
|
424
|
-
},
|
|
425
|
-
"lane:stats": {
|
|
426
|
-
...MEASURE_ARGUMENTS,
|
|
427
|
-
description: "Print one table row of lane throughput, gate duration and machine load over a period, the per-stage durations of a lane under it, and the wait after each ship stop reason under those",
|
|
428
|
-
category: "AI tools",
|
|
429
|
-
reference: ["--period <days> [--limit <lane-limit>]", "maintainer", ["none"]],
|
|
430
|
-
default_script_arguments: ["stats"]
|
|
301
|
+
function wait_reason(key, reservations, budget) {
|
|
302
|
+
const cores_only = { cores: budget.cores, memory_mb: Infinity };
|
|
303
|
+
if (!core_admission.is_admitted(key, reservations, cores_only)) return "cores";
|
|
304
|
+
return budget.memory_pressured === true ? "pressure" : "memory";
|
|
305
|
+
}
|
|
306
|
+
function wait_line(command, reason) {
|
|
307
|
+
return `\u23F3 ${command ?? "a step"} waits for the core budget \u2014 ${REASON_TEXT[reason]}`;
|
|
308
|
+
}
|
|
309
|
+
function lanes_root_of(checkout) {
|
|
310
|
+
if (lane_paths.lane_issue_of(checkout) === void 0) return lane_paths.lane_root(checkout);
|
|
311
|
+
return path2.dirname(path2.resolve(checkout));
|
|
312
|
+
}
|
|
313
|
+
function where_of(checkout) {
|
|
314
|
+
return { checkout, lane: lane_paths.lane_issue_of(checkout), lanes_root: lanes_root_of(checkout) };
|
|
315
|
+
}
|
|
316
|
+
function place_of(marker, home_root) {
|
|
317
|
+
const { checkout, lane, lanes_root } = marker;
|
|
318
|
+
if (checkout === void 0 || lanes_root === void 0 || lanes_root === home_root) {
|
|
319
|
+
return { lane, elsewhere: void 0 };
|
|
431
320
|
}
|
|
321
|
+
const name = lane === void 0 ? path2.basename(checkout) : `${path2.basename(lanes_root)}/${lane}`;
|
|
322
|
+
return { lane: void 0, elsewhere: name };
|
|
323
|
+
}
|
|
324
|
+
function wait_of(marker, now, home_root) {
|
|
325
|
+
const { command, wait_reason: reason } = marker;
|
|
326
|
+
if (reason === void 0 || marker.admitted_at !== void 0) return [];
|
|
327
|
+
return [{ command, ...place_of(marker, home_root), waited_ms: now - marker.claimed_at, reason }];
|
|
328
|
+
}
|
|
329
|
+
function waits_of(entries, now, home) {
|
|
330
|
+
const home_root = lanes_root_of(home);
|
|
331
|
+
return entries.flatMap((entry) => wait_of(entry.reservation, now, home_root)).toSorted((left, right) => right.waited_ms - left.waited_ms);
|
|
332
|
+
}
|
|
333
|
+
var core_wait = {
|
|
334
|
+
REASON_TEXT,
|
|
335
|
+
WAIT_REASONS,
|
|
336
|
+
wait_line,
|
|
337
|
+
wait_reason,
|
|
338
|
+
waits_of,
|
|
339
|
+
where_of
|
|
432
340
|
};
|
|
433
341
|
|
|
434
|
-
// scripts/
|
|
435
|
-
var
|
|
436
|
-
var
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
"
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
"
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
script: "scripts/run/carry/run-carry-cli.ts",
|
|
458
|
-
// `--stopped` sends the stop confirmation, so the Telegram credentials come from `.env` as for
|
|
459
|
-
// `run:wake` below.
|
|
460
|
-
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
461
|
-
description: "Carry one invocation\u2019s budget across its own session cuts",
|
|
462
|
-
category: "AI tools",
|
|
463
|
-
reference: ["<operation> [arguments...]", "automation", ["files"]]
|
|
464
|
-
},
|
|
465
|
-
"run:add": {
|
|
466
|
-
script: "scripts/run/add/run-add-cli.ts",
|
|
467
|
-
description: "Add issues to a live backlogrun, ahead of the queue unless --no-priority",
|
|
468
|
-
category: "AI tools",
|
|
469
|
-
reference: ["<issue...> [--no-priority]", "automation", ["network", "files"]]
|
|
470
|
-
},
|
|
471
|
-
"run:wake": {
|
|
472
|
-
script: "scripts/run/wake/run-wake-cli.ts",
|
|
473
|
-
// `.env` rather than the ambient environment:
|
|
474
|
-
// the failure warning needs the Telegram credentials, the same
|
|
475
|
-
// reasons `notify` and `followup` carry these flags.
|
|
476
|
-
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
477
|
-
description: "Wake the next session of a cut backlogrun from outside the conversation",
|
|
478
|
-
category: "AI tools",
|
|
479
|
-
reference: ["[options]", "automation", ["processes", "notifications"]]
|
|
480
|
-
},
|
|
481
|
-
"run:cut": {
|
|
482
|
-
script: "scripts/run/cut/run-cut-cli.ts",
|
|
483
|
-
description: "Cut a lane child before the gate and resume a fresh process",
|
|
484
|
-
category: "AI tools",
|
|
485
|
-
reference: ["[--resume] <issue> [--impl] [--handoff <path>]", "automation", ["files"]]
|
|
486
|
-
},
|
|
487
|
-
"run:liveness": {
|
|
488
|
-
script: "scripts/run/run-liveness-cli.ts",
|
|
489
|
-
description: "Say whether a delegated unit is still working, or stopped without reporting",
|
|
490
|
-
category: "AI tools",
|
|
491
|
-
reference: ["<issue> --output <path> [options]", "automation", ["processes"]]
|
|
492
|
-
},
|
|
493
|
-
"run:ending": {
|
|
494
|
-
script: "scripts/run/run-ending-cli.ts",
|
|
495
|
-
description: "Classify how a dispatched lane child ended (merged, cut, abandoned, unreadable)",
|
|
496
|
-
category: "AI tools",
|
|
497
|
-
reference: ["<issue> --output <path> [--repo <owner/repo>]", "automation", ["network"]]
|
|
498
|
-
},
|
|
499
|
-
"run:progress": {
|
|
500
|
-
script: "scripts/run/progress/run-progress-cli.ts",
|
|
501
|
-
description: "Report an unattended run\u2019s progress once it has gone quiet for an interval",
|
|
502
|
-
category: "AI tools",
|
|
503
|
-
reference: [
|
|
504
|
-
"[--once | --wait] [--interval <minutes>] [--hours <hours>] [--repo <owner/repo>] [--output <path>] | --mark | --path",
|
|
505
|
-
"automation",
|
|
506
|
-
["files"]
|
|
507
|
-
]
|
|
508
|
-
},
|
|
509
|
-
"run:board": {
|
|
510
|
-
script: "scripts/run/board/run-board-cli.ts",
|
|
511
|
-
// `--every` pushes its frame as a Telegram, so the credentials come from `.env` as for `run:carry`.
|
|
512
|
-
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
513
|
-
description: "Draw a live board of the running backlogrun, redrawn every second",
|
|
514
|
-
category: "AI tools",
|
|
515
|
-
reference: ["[--once | --chat | --every <minutes>]", "automation", ["files", "network"]]
|
|
516
|
-
},
|
|
517
|
-
"run:prep": {
|
|
518
|
-
script: "scripts/run/run-prep-cli.ts",
|
|
519
|
-
description: "Bundle a run\u2019s pre-edit reads: body, comments, state, dependency scope",
|
|
520
|
-
category: "AI tools",
|
|
521
|
-
reference: ["<issue>", "automation", ["network"]]
|
|
522
|
-
},
|
|
523
|
-
// The entry sequence a lane opened on, folded into one call: claim the tree,
|
|
524
|
-
// read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
|
|
525
|
-
// `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
|
|
526
|
-
"run:entry": {
|
|
527
|
-
script: "scripts/run/entry/run-entry-cli.ts",
|
|
528
|
-
// A `busy` hold or an `over` budget sends the stop confirmation.
|
|
529
|
-
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
530
|
-
description: "Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step",
|
|
531
|
-
category: "AI tools",
|
|
532
|
-
reference: ["<issue> [--to <command>]", "automation", ["git", "network", "files"]]
|
|
533
|
-
},
|
|
534
|
-
"run:status": {
|
|
535
|
-
script: "scripts/run/run-status-cli.ts",
|
|
536
|
-
description: "Bundle a run\u2019s read-only status: issue state, cost verdict, carry counters",
|
|
537
|
-
category: "AI tools",
|
|
538
|
-
reference: ["<issue> [--repo <owner/repo>]", "automation", ["network"]]
|
|
539
|
-
},
|
|
540
|
-
"run:next": {
|
|
541
|
-
script: "scripts/run/run-next-cli.ts",
|
|
542
|
-
description: "Print the next step a fullrun takes, computed from the run\u2019s state",
|
|
543
|
-
category: "AI tools",
|
|
544
|
-
reference: ["<issue>", "automation", ["network"]]
|
|
545
|
-
},
|
|
546
|
-
"run:step": {
|
|
547
|
-
script: "scripts/run/run-step-cli.ts",
|
|
548
|
-
description: "Print the run\u2019s next single action, computed from the event stream, carry record and issue state",
|
|
549
|
-
category: "AI tools",
|
|
550
|
-
reference: ["[<issue>]", "automation", ["network", "files"]]
|
|
342
|
+
// scripts/gate/held-mark.ts
|
|
343
|
+
var HELD_KEY = "JOSH_CORE_RESERVED";
|
|
344
|
+
var HELD_VALUE = "1";
|
|
345
|
+
var HELD_RESERVATION_KEY = "JOSH_CORE_RESERVATION";
|
|
346
|
+
function is_held() {
|
|
347
|
+
return process.env[HELD_KEY] === HELD_VALUE;
|
|
348
|
+
}
|
|
349
|
+
function held_reservation() {
|
|
350
|
+
const key = process.env[HELD_RESERVATION_KEY] ?? "";
|
|
351
|
+
return key === "" ? void 0 : key;
|
|
352
|
+
}
|
|
353
|
+
function set_held_mark(value, reservation) {
|
|
354
|
+
process.env[HELD_KEY] = value;
|
|
355
|
+
process.env[HELD_RESERVATION_KEY] = reservation;
|
|
356
|
+
}
|
|
357
|
+
async function with_held_mark(run, reservation = "") {
|
|
358
|
+
const previous = process.env[HELD_KEY] ?? "";
|
|
359
|
+
const previous_reservation = process.env[HELD_RESERVATION_KEY] ?? "";
|
|
360
|
+
set_held_mark(HELD_VALUE, reservation);
|
|
361
|
+
try {
|
|
362
|
+
return await run();
|
|
363
|
+
} finally {
|
|
364
|
+
set_held_mark(previous, previous_reservation);
|
|
551
365
|
}
|
|
366
|
+
}
|
|
367
|
+
var held_mark = {
|
|
368
|
+
HELD_KEY,
|
|
369
|
+
HELD_RESERVATION_KEY,
|
|
370
|
+
HELD_VALUE,
|
|
371
|
+
held_reservation,
|
|
372
|
+
is_held,
|
|
373
|
+
with_held_mark
|
|
552
374
|
};
|
|
553
375
|
|
|
554
|
-
// scripts/
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
376
|
+
// scripts/gate/machine-capacity.ts
|
|
377
|
+
import { readFile } from "node:fs/promises";
|
|
378
|
+
import { availableParallelism as availableParallelism2, cpus, totalmem } from "node:os";
|
|
379
|
+
import { execa } from "execa";
|
|
380
|
+
var SAMPLE_WINDOW_MS = 250;
|
|
381
|
+
var BASELINE_CORES = 2;
|
|
382
|
+
var BYTES_PER_MB = 1048576;
|
|
383
|
+
var KB_PER_MB = 1024;
|
|
384
|
+
var PERCENT = 100;
|
|
385
|
+
var MEMINFO_PATH = "/proc/meminfo";
|
|
386
|
+
var VMSTAT_PATH = "/proc/vmstat";
|
|
387
|
+
var LINUX_AVAILABLE = /^MemAvailable:\s+(?<kb>\d+) kB/mu;
|
|
388
|
+
var LINUX_SWAP_IN = /^pswpin (?<pages>\d+)$/mu;
|
|
389
|
+
var LINUX_SWAP_OUT = /^pswpout (?<pages>\d+)$/mu;
|
|
390
|
+
var PAGE_SIZE_ARGUMENTS = ["PAGESIZE"];
|
|
391
|
+
var LEVEL_NAME = "kern.memorystatus_level";
|
|
392
|
+
var SWAP_IN_NAME = "vm.compressor.swapper.swapins_total";
|
|
393
|
+
var SWAP_OUT_NAME = "vm.compressor.swapper.swapouts_total";
|
|
394
|
+
var COMPRESSED_NAME = "vm.compressor_input_bytes";
|
|
395
|
+
var PAGE_SIZE_NAME = "hw.pagesize";
|
|
396
|
+
var PRESSURE_NAME = "kern.memorystatus_vm_pressure_level";
|
|
397
|
+
var PRESSURE_WARNING = 2;
|
|
398
|
+
var SWAP_PRESSURE_MB = 16;
|
|
399
|
+
var COMPRESSION_PRESSURE_MB = 64;
|
|
400
|
+
var SYSCTL_ARGUMENTS = [
|
|
401
|
+
LEVEL_NAME,
|
|
402
|
+
SWAP_IN_NAME,
|
|
403
|
+
SWAP_OUT_NAME,
|
|
404
|
+
COMPRESSED_NAME,
|
|
405
|
+
PAGE_SIZE_NAME,
|
|
406
|
+
PRESSURE_NAME
|
|
407
|
+
];
|
|
408
|
+
var SYSCTL_LINE = /^(?<name>[\w.]+): (?<value>\d+)$/gmu;
|
|
409
|
+
function cpu_times() {
|
|
410
|
+
let busy = 0;
|
|
411
|
+
let idle = 0;
|
|
412
|
+
for (const { times } of cpus()) {
|
|
413
|
+
busy += times.user + times.nice + times.sys + times.irq;
|
|
414
|
+
idle += times.idle;
|
|
415
|
+
}
|
|
416
|
+
return { busy, total: busy + idle };
|
|
417
|
+
}
|
|
418
|
+
function busy_share_between(before, after) {
|
|
419
|
+
const total = after.total - before.total;
|
|
420
|
+
if (total <= 0) return void 0;
|
|
421
|
+
return (after.busy - before.busy) / total;
|
|
422
|
+
}
|
|
423
|
+
function busy_cores_between(before, after, cores) {
|
|
424
|
+
const share = busy_share_between(before, after);
|
|
425
|
+
return share === void 0 ? void 0 : share * cores;
|
|
426
|
+
}
|
|
427
|
+
function sysctl_values(output) {
|
|
428
|
+
const values = [...output.matchAll(SYSCTL_LINE)].map(
|
|
429
|
+
(match) => [match.groups?.["name"] ?? "", Number(match.groups?.["value"])]
|
|
430
|
+
);
|
|
431
|
+
return new Map(values);
|
|
432
|
+
}
|
|
433
|
+
function swapped_pages(pages_in, pages_out) {
|
|
434
|
+
return pages_in === void 0 || pages_out === void 0 ? void 0 : pages_in + pages_out;
|
|
435
|
+
}
|
|
436
|
+
function mb_of(units, unit_bytes) {
|
|
437
|
+
if (units === void 0 || unit_bytes === void 0) return void 0;
|
|
438
|
+
return units * unit_bytes / BYTES_PER_MB;
|
|
439
|
+
}
|
|
440
|
+
function swapped_between(from, to) {
|
|
441
|
+
if (from === void 0 || to === void 0) return void 0;
|
|
442
|
+
return Math.max(0, to - from);
|
|
443
|
+
}
|
|
444
|
+
function parse_darwin_memory(output, total_bytes) {
|
|
445
|
+
const values = sysctl_values(output);
|
|
446
|
+
const level = values.get(LEVEL_NAME);
|
|
447
|
+
return {
|
|
448
|
+
available_mb: level === void 0 ? void 0 : level / PERCENT * (total_bytes / BYTES_PER_MB),
|
|
449
|
+
swapped_mb: mb_of(
|
|
450
|
+
swapped_pages(values.get(SWAP_IN_NAME), values.get(SWAP_OUT_NAME)),
|
|
451
|
+
values.get(PAGE_SIZE_NAME)
|
|
452
|
+
),
|
|
453
|
+
pressure_level: values.get(PRESSURE_NAME),
|
|
454
|
+
compressed_mb: mb_of(values.get(COMPRESSED_NAME), 1)
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function parse_linux_available(meminfo) {
|
|
458
|
+
const kb = LINUX_AVAILABLE.exec(meminfo)?.groups?.["kb"];
|
|
459
|
+
return kb === void 0 ? void 0 : Number(kb) / KB_PER_MB;
|
|
460
|
+
}
|
|
461
|
+
function pages_of(pattern, vmstat) {
|
|
462
|
+
const pages = pattern.exec(vmstat)?.groups?.["pages"];
|
|
463
|
+
return pages === void 0 ? void 0 : Number(pages);
|
|
464
|
+
}
|
|
465
|
+
function parse_linux_swapped(vmstat, page_bytes) {
|
|
466
|
+
const pages = swapped_pages(pages_of(LINUX_SWAP_IN, vmstat), pages_of(LINUX_SWAP_OUT, vmstat));
|
|
467
|
+
return mb_of(pages, page_bytes);
|
|
468
|
+
}
|
|
469
|
+
async function settled(read) {
|
|
470
|
+
try {
|
|
471
|
+
return await read();
|
|
472
|
+
} catch {
|
|
473
|
+
return void 0;
|
|
561
474
|
}
|
|
475
|
+
}
|
|
476
|
+
async function read_darwin_memory() {
|
|
477
|
+
const { stdout } = await execa("sysctl", SYSCTL_ARGUMENTS, {
|
|
478
|
+
reject: false,
|
|
479
|
+
timeout: PROBE_TIMEOUT_MS
|
|
480
|
+
});
|
|
481
|
+
return parse_darwin_memory(stdout, totalmem());
|
|
482
|
+
}
|
|
483
|
+
async function read_page_size() {
|
|
484
|
+
const { stdout } = await execa("getconf", PAGE_SIZE_ARGUMENTS, { timeout: PROBE_TIMEOUT_MS });
|
|
485
|
+
return stdout;
|
|
486
|
+
}
|
|
487
|
+
async function read_linux_memory() {
|
|
488
|
+
const [meminfo, vmstat, page_size] = await Promise.all([
|
|
489
|
+
settled(async () => await readFile(MEMINFO_PATH, "utf8")),
|
|
490
|
+
settled(async () => await readFile(VMSTAT_PATH, "utf8")),
|
|
491
|
+
settled(read_page_size)
|
|
492
|
+
]);
|
|
493
|
+
const page_bytes = page_size === void 0 ? void 0 : Number(page_size);
|
|
494
|
+
return {
|
|
495
|
+
available_mb: meminfo === void 0 ? void 0 : parse_linux_available(meminfo),
|
|
496
|
+
swapped_mb: vmstat === void 0 || page_bytes === void 0 ? void 0 : parse_linux_swapped(vmstat, page_bytes),
|
|
497
|
+
pressure_level: void 0
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
var UNREAD_MEMORY = {
|
|
501
|
+
available_mb: void 0,
|
|
502
|
+
swapped_mb: void 0,
|
|
503
|
+
pressure_level: void 0
|
|
562
504
|
};
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
var AI_COMMANDS = {
|
|
567
|
-
...ISSUE_COMMANDS,
|
|
568
|
-
"pkg:scout": {
|
|
569
|
-
script: "scripts/package/package-scout-cli.ts",
|
|
570
|
-
description: "Rank package candidates by measured metrics so the Package-First tier decision is read, not judged",
|
|
571
|
-
category: "AI tools",
|
|
572
|
-
reference: ["<keywords> [--size <n>]", "automation", ["network"]]
|
|
573
|
-
},
|
|
574
|
-
"stash:pop": {
|
|
575
|
-
script: "scripts/git/stash/stash-pop-cli.ts",
|
|
576
|
-
description: "Pop the stash matching this message, not whichever a shared stack has on top",
|
|
577
|
-
category: "AI tools",
|
|
578
|
-
reference: ["<message>", "automation", ["git"]]
|
|
579
|
-
},
|
|
580
|
-
epic: {
|
|
581
|
-
script: "scripts/epic/epic.ts",
|
|
582
|
-
description: "Create an epic issue from its child issue numbers",
|
|
583
|
-
category: "AI tools",
|
|
584
|
-
reference: ["<title> <issue...> [--ordered]", "automation", ["network"]]
|
|
585
|
-
},
|
|
586
|
-
"epic:next": {
|
|
587
|
-
script: "scripts/epic/epic-next.ts",
|
|
588
|
-
description: "List an epic's runnable children, bundled per repository",
|
|
589
|
-
category: "AI tools",
|
|
590
|
-
reference: ["<epic>... [--repo <owner/repo>] [--lanes]", "automation", ["network"]]
|
|
591
|
-
},
|
|
592
|
-
"epic:bundle": {
|
|
593
|
-
script: "scripts/epic/epic-bundle-cli.ts",
|
|
594
|
-
description: "Say whether a newly filed issue belongs with ones already in the backlog",
|
|
595
|
-
category: "AI tools",
|
|
596
|
-
reference: ["<issue>", "automation", ["network"]]
|
|
597
|
-
},
|
|
598
|
-
"epic:audit": {
|
|
599
|
-
script: "scripts/epic/epic-audit-cli.ts",
|
|
600
|
-
description: "Audit an epic's children against each other for contradictions",
|
|
601
|
-
category: "AI tools",
|
|
602
|
-
reference: ["<epic>", "automation", ["network"]]
|
|
603
|
-
},
|
|
604
|
-
"epic:check": {
|
|
605
|
-
script: "scripts/epic/epic-check.ts",
|
|
606
|
-
description: "Check an epic issue against the tracking requirements",
|
|
607
|
-
category: "AI tools",
|
|
608
|
-
reference: ["<epic>", "automation", ["network"]]
|
|
609
|
-
},
|
|
610
|
-
"auto-ok:next": {
|
|
611
|
-
script: "scripts/auto-ok/auto-ok-cli.ts",
|
|
612
|
-
description: "Print the next opted-in issue an unattended run may pick up outside an epic",
|
|
613
|
-
category: "AI tools",
|
|
614
|
-
reference: ["[--exclude <n>[,<n>...]] [--label <name>]", "automation", ["network"]]
|
|
615
|
-
},
|
|
616
|
-
"auto-ok:judge": {
|
|
617
|
-
script: "scripts/auto-ok/auto-ok-judge-cli.ts",
|
|
618
|
-
description: "List the open issues backlogrun owes an auto-ok judgement, or record one (--apply / --decline)",
|
|
619
|
-
category: "AI tools",
|
|
620
|
-
reference: [
|
|
621
|
-
"[--apply <n> (--lane | --solo) | --decline <n> --reason <text>]",
|
|
622
|
-
"automation",
|
|
623
|
-
["network"]
|
|
624
|
-
]
|
|
625
|
-
},
|
|
626
|
-
...BACKLOG_COMMANDS,
|
|
627
|
-
cost: {
|
|
628
|
-
script: "scripts/cost-runtime/cost-cli.ts",
|
|
629
|
-
description: "Say whether the next turn of a run crosses the context-cut threshold (--cut) or a given tokens-per-request figure (--over)",
|
|
630
|
-
category: "AI tools",
|
|
631
|
-
reference: ["(--cut | --over <tokens-per-request>) [--path <dir>]", "automation", ["none"]]
|
|
632
|
-
},
|
|
633
|
-
...DOCUMENT_COMMANDS,
|
|
634
|
-
time: {
|
|
635
|
-
script: "scripts/time/time-cli.ts",
|
|
636
|
-
description: "Report where a run's wall clock went: model wait, tool execution, human wait",
|
|
637
|
-
category: "AI tools",
|
|
638
|
-
reference: ["[options]", "maintainer", ["none"]],
|
|
639
|
-
// Kit-only: it measures kit's own development runs and its report modules live under the
|
|
640
|
-
// undistributed `scripts/time/`, so it means nothing in a consumer project and is dropped from a
|
|
641
|
-
// consumer's help. The runtime analysis hooks and guards rely on stays
|
|
642
|
-
// distributed under `scripts/time-runtime/`.
|
|
643
|
-
is_kit_only: true
|
|
644
|
-
},
|
|
645
|
-
// The tool-calls-per-round-trip density the batching guard is measured on, aggregated across the
|
|
646
|
-
// recent lane sessions. Kit-only for the same reason `time` is: it reads
|
|
647
|
-
// kit's own lane transcripts and means nothing in a consumer project.
|
|
648
|
-
"time:density": {
|
|
649
|
-
script: "scripts/time/time-density-cli.ts",
|
|
650
|
-
description: "Report tool calls per round trip across the recent lane sessions",
|
|
651
|
-
category: "AI tools",
|
|
652
|
-
reference: ["[--lanes <n>] [--path <dir>]", "maintainer", ["none"]],
|
|
653
|
-
is_kit_only: true
|
|
654
|
-
},
|
|
655
|
-
retrospective: {
|
|
656
|
-
script: "scripts/retrospective/retrospective-cli.ts",
|
|
657
|
-
description: "Aggregate a finished run's cost, review findings, observation ledger and events into one digest",
|
|
658
|
-
category: "AI tools",
|
|
659
|
-
reference: ["", "maintainer", ["none"]],
|
|
660
|
-
// Kit-only: it reads kit's own development run — the transcript store, the review ledger and the
|
|
661
|
-
// run event stream — so it means nothing in a consumer project and is dropped from a consumer's
|
|
662
|
-
// help, through the same declaration `josh time` uses for the same reason.
|
|
663
|
-
is_kit_only: true
|
|
664
|
-
},
|
|
665
|
-
"review:brief": {
|
|
666
|
-
script: "scripts/review/review-brief-cli.ts",
|
|
667
|
-
description: "Print the whole /code-review invocation: level, what the gate already proved, target (--level-only for the level alone)",
|
|
668
|
-
category: "AI tools",
|
|
669
|
-
reference: ["[--round <1|2>] | --level-only [--staged] [--json]", "automation", ["files"]]
|
|
670
|
-
},
|
|
671
|
-
"review:attest": {
|
|
672
|
-
script: "scripts/review/review-attest-cli.ts",
|
|
673
|
-
description: "Record, or verify, which checkout a /code-review actually read",
|
|
674
|
-
category: "AI tools",
|
|
675
|
-
reference: ["<nonce> | --check", "automation", ["files"]]
|
|
676
|
-
},
|
|
677
|
-
"review:round2": {
|
|
678
|
-
script: "scripts/review/review-round2-cli.ts",
|
|
679
|
-
description: "Say whether the second /code-review round is due, or may be skipped entirely",
|
|
680
|
-
category: "AI tools",
|
|
681
|
-
reference: ["[--round-1-closed] [--json]", "automation", ["none"]]
|
|
682
|
-
},
|
|
683
|
-
delegate: {
|
|
684
|
-
script: "scripts/delegation/delegation-cli.ts",
|
|
685
|
-
description: "Say whether a run step may go to a cheaper execution tier",
|
|
686
|
-
category: "AI tools",
|
|
687
|
-
reference: ["<step> | --list", "automation", ["none"]]
|
|
688
|
-
},
|
|
689
|
-
fanout: {
|
|
690
|
-
script: "scripts/delegation/fanout-cli.ts",
|
|
691
|
-
description: "Say whether proposed implementation units are file-disjoint, so they may run in parallel",
|
|
692
|
-
category: "AI tools",
|
|
693
|
-
reference: ["<unit-files> <unit-files> [<unit-files> \u2026]", "automation", ["none"]]
|
|
694
|
-
},
|
|
695
|
-
...RUN_COMMANDS,
|
|
696
|
-
"repo:party": {
|
|
697
|
-
script: "scripts/discovery/repo-party-cli.ts",
|
|
698
|
-
description: "Say whether a repository is first-party or third-party by owner equality (computed, not judged)",
|
|
699
|
-
category: "AI tools",
|
|
700
|
-
reference: ["[<owner/repo>]", "automation", ["none"]]
|
|
701
|
-
},
|
|
702
|
-
"run:merge": {
|
|
703
|
-
script: "scripts/run/merge/run-merge-cli.ts",
|
|
704
|
-
description: "Collapse a backlogrun merge event into one call: confirm the child, do the post-merge steps, offer the next child",
|
|
705
|
-
category: "AI tools",
|
|
706
|
-
reference: [ISSUE_WITH_OPTIONS2, "automation", ["git", "network"]]
|
|
707
|
-
},
|
|
708
|
-
"run:review": {
|
|
709
|
-
script: "scripts/run/review/run-review-cli.ts",
|
|
710
|
-
description: "Start the gate in the background and print the /code-review brief in one call so the two overlap (--join to join the gate and check its verdict)",
|
|
711
|
-
category: "AI tools",
|
|
712
|
-
reference: ["[--join]", "automation", ["processes", "files"]]
|
|
713
|
-
},
|
|
714
|
-
// The post-merge sequence a run closed on, folded into one call: commit the
|
|
715
|
-
// observation ledger, read the completion citations and decide the release scope. `observations:flush`,
|
|
716
|
-
// `issue:cite` and `release:scope` were three round trips re-billing the run's full context each.
|
|
717
|
-
"run:tail": {
|
|
718
|
-
script: "scripts/run/run-tail-cli.ts",
|
|
719
|
-
description: "Close a run in one call: return to the default branch, commit the observation ledger, read the citations, decide the release scope",
|
|
720
|
-
category: "AI tools",
|
|
721
|
-
reference: ["[<issue> ...]", "automation", ["git", "network"]]
|
|
722
|
-
},
|
|
723
|
-
// The commit-to-report region a run ships a change on, folded into one call:
|
|
724
|
-
// the gate, the commit/push/PR (`git -y`), the CI-wait merge (`followup`) and the report bookkeeping
|
|
725
|
-
// (`run:tail`) were four round trips re-billing the run's full context each. It stops at the first
|
|
726
|
-
// failed step and names it, so the run reads only the step to fix.
|
|
727
|
-
ship: {
|
|
728
|
-
script: "scripts/run/ship/run-ship-cli.ts",
|
|
729
|
-
description: "Ship a change in one call: gate, commit/push/PR, the CI-wait merge and the report bookkeeping, stopping at the first failed step",
|
|
730
|
-
category: "AI tools",
|
|
731
|
-
reference: [
|
|
732
|
-
'"<title> #<N>" [<follow-up-N> ...] [--cite <N>] [--review] [--detach] [--body-file <path>] [--notify-message <text> | --notify-message-file <path>] | --log <N>',
|
|
733
|
-
"automation",
|
|
734
|
-
["git", "network"]
|
|
735
|
-
]
|
|
736
|
-
},
|
|
737
|
-
"run:event": {
|
|
738
|
-
script: "scripts/run/event/run-event-cli.ts",
|
|
739
|
-
description: "Append to, read or watch the run\u2019s append-only event stream (--append <kind> <text> | --from|--follow <n> | --watch [<n>] | --last)",
|
|
740
|
-
category: "AI tools",
|
|
741
|
-
reference: [
|
|
742
|
-
"--append <kind> <text> | --from|--follow <n> | --watch [<n>] | --last",
|
|
743
|
-
"automation",
|
|
744
|
-
["files"]
|
|
745
|
-
]
|
|
746
|
-
},
|
|
747
|
-
"run:report": {
|
|
748
|
-
script: "scripts/run/run-report-cli.ts",
|
|
749
|
-
description: "Generate the session-facing report for this invocation from the run\u2019s event stream (merges, parks, cuts) with the release tail \u2014 the same text josh notify sends",
|
|
750
|
-
category: "AI tools",
|
|
751
|
-
reference: ["", "automation", ["files", "network"]]
|
|
752
|
-
},
|
|
753
|
-
...LANE_COMMANDS,
|
|
754
|
-
...GUARD_COMMANDS,
|
|
755
|
-
"run:watcher:guard": {
|
|
756
|
-
script: "scripts/run/run-watcher-guard-cli.ts",
|
|
757
|
-
description: "Guard: exits non-zero when lane children are in-flight but the watcher has not pinged recently",
|
|
758
|
-
category: "AI tools",
|
|
759
|
-
reference: ["", "automation", ["none"]]
|
|
760
|
-
},
|
|
761
|
-
"run:stranded": {
|
|
762
|
-
script: "scripts/run/run-stranded-cli.ts",
|
|
763
|
-
// `.env` rather than the ambient environment: the strand notification needs the Telegram
|
|
764
|
-
// credentials, the same reason `run:wake` carries these flags.
|
|
765
|
-
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
766
|
-
description: "Report whether the run is stranded \u2014 owner gone, no successor holding the budget, and no supervisor watching",
|
|
767
|
-
category: "AI tools",
|
|
768
|
-
reference: ["", "automation", ["processes", "notifications"]]
|
|
769
|
-
},
|
|
770
|
-
...SPLIT_COMMANDS,
|
|
771
|
-
"oracle:list": {
|
|
772
|
-
script: "scripts/rules/oracle-list-cli.ts",
|
|
773
|
-
description: "Print the decision oracles \u2014 commands that answer a rule question mechanically",
|
|
774
|
-
category: "AI tools",
|
|
775
|
-
reference: ["", "automation", ["none"]]
|
|
776
|
-
},
|
|
777
|
-
eval: {
|
|
778
|
-
script: "scripts/eval/eval-run.ts",
|
|
779
|
-
description: "Run the agent rule-compliance scenarios (real Claude sessions)",
|
|
780
|
-
category: "AI tools",
|
|
781
|
-
reference: ["[scenario...]", "maintainer", ["processes", "network"]],
|
|
782
|
-
// Kit-only: it replays kit's own distributed rules against real Claude sessions, so it means
|
|
783
|
-
// nothing in a consumer project and is dropped from a consumer's help.
|
|
784
|
-
is_kit_only: true
|
|
785
|
-
}
|
|
786
|
-
};
|
|
787
|
-
|
|
788
|
-
// scripts/josh/josh-commands-clone.ts
|
|
789
|
-
var CLONE_COMMANDS = {
|
|
790
|
-
"clone:scan": {
|
|
791
|
-
script: "scripts/clone/clone-scan-cli.ts",
|
|
792
|
-
description: "Count code duplication across files and first-party repositories, printing each clone as file:line pairs",
|
|
793
|
-
category: "AI tools",
|
|
794
|
-
reference: ["", "automation", ["files"]]
|
|
795
|
-
}
|
|
796
|
-
};
|
|
797
|
-
|
|
798
|
-
// scripts/gate/core-budget.ts
|
|
799
|
-
import { randomUUID } from "node:crypto";
|
|
800
|
-
import { readdirSync as readdirSync2 } from "node:fs";
|
|
801
|
-
import { availableParallelism as availableParallelism3 } from "node:os";
|
|
802
|
-
import path2 from "node:path";
|
|
803
|
-
|
|
804
|
-
// scripts/test/unit-worker-share.ts
|
|
805
|
-
import { readdirSync } from "node:fs";
|
|
806
|
-
import { availableParallelism } from "node:os";
|
|
807
|
-
import path from "node:path";
|
|
808
|
-
var RUN_PREFIX = "josh-unit-running-";
|
|
809
|
-
var WORKER_FLAG = "--maxWorkers";
|
|
810
|
-
var WORKER_FLAGS = [WORKER_FLAG, "--max-workers"];
|
|
811
|
-
var MIN_WORKERS = 1;
|
|
812
|
-
var SOLO_RUNS = 1;
|
|
813
|
-
function marker_path(pid = process.pid) {
|
|
814
|
-
return stamp_file.stamp_path(RUN_PREFIX, String(pid));
|
|
505
|
+
async function read_memory() {
|
|
506
|
+
if (process.platform === "darwin") return await settled(read_darwin_memory) ?? UNREAD_MEMORY;
|
|
507
|
+
return process.platform === "linux" ? await read_linux_memory() : UNREAD_MEMORY;
|
|
815
508
|
}
|
|
816
|
-
function
|
|
817
|
-
return
|
|
509
|
+
function is_unquoted() {
|
|
510
|
+
return cpus().length > 0 && cpus().length === availableParallelism2();
|
|
818
511
|
}
|
|
819
|
-
function
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
return parsed.success ? parsed.data : void 0;
|
|
512
|
+
async function default_sleep(ms) {
|
|
513
|
+
await new Promise((resolve) => {
|
|
514
|
+
setTimeout(resolve, ms);
|
|
515
|
+
});
|
|
824
516
|
}
|
|
825
|
-
function
|
|
826
|
-
|
|
827
|
-
return readdirSync(directory).filter((name) => name.startsWith(RUN_PREFIX));
|
|
828
|
-
} catch {
|
|
829
|
-
return [];
|
|
830
|
-
}
|
|
517
|
+
function moved_over(from, to, limit) {
|
|
518
|
+
return (swapped_between(from, to) ?? 0) > limit;
|
|
831
519
|
}
|
|
832
|
-
function
|
|
833
|
-
|
|
834
|
-
stamp_file.remove_stamp(source);
|
|
835
|
-
} catch {
|
|
836
|
-
}
|
|
520
|
+
function is_pressured(before, after) {
|
|
521
|
+
return (after.pressure_level ?? 0) >= PRESSURE_WARNING || moved_over(before.swapped_mb, after.swapped_mb, SWAP_PRESSURE_MB) || moved_over(before.compressed_mb, after.compressed_mb, COMPRESSION_PRESSURE_MB);
|
|
837
522
|
}
|
|
838
|
-
function
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
if (is_running(marker)) return true;
|
|
842
|
-
sweep_marker(source);
|
|
843
|
-
return false;
|
|
844
|
-
}
|
|
845
|
-
function live_run_count(directory = PLATFORM_TEMP_ROOT) {
|
|
846
|
-
return marker_files(directory).filter((name) => is_marker_live(path.join(directory, name))).length;
|
|
847
|
-
}
|
|
848
|
-
var NESTED_KEY = "JOSH_UNIT_RUN_MARKED";
|
|
849
|
-
var NESTED_VALUE = "1";
|
|
850
|
-
function is_nested_run() {
|
|
851
|
-
return process.env[NESTED_KEY] === NESTED_VALUE;
|
|
852
|
-
}
|
|
853
|
-
function resolve_unit_workers(available_cores, runs2) {
|
|
854
|
-
if (runs2 <= SOLO_RUNS) return void 0;
|
|
855
|
-
return Math.max(MIN_WORKERS, Math.floor(available_cores / runs2));
|
|
856
|
-
}
|
|
857
|
-
function current_share(available_cores = availableParallelism(), live_runs = live_run_count()) {
|
|
858
|
-
const own_run2 = is_nested_run() ? 0 : SOLO_RUNS;
|
|
859
|
-
return resolve_unit_workers(available_cores, live_runs + own_run2);
|
|
860
|
-
}
|
|
861
|
-
function is_worker_flag(argument) {
|
|
862
|
-
return WORKER_FLAGS.some((flag) => argument === flag || argument.startsWith(`${flag}=`));
|
|
863
|
-
}
|
|
864
|
-
function worker_arguments(vitest_arguments, share) {
|
|
865
|
-
if (share === void 0) return [];
|
|
866
|
-
if (vitest_arguments.some((argument) => is_worker_flag(argument))) return [];
|
|
867
|
-
return [`${WORKER_FLAG}=${String(share)}`];
|
|
868
|
-
}
|
|
869
|
-
function mark_run_started(target2) {
|
|
870
|
-
try {
|
|
871
|
-
stamp_file.write_stamp(target2, process_identity.own_fields());
|
|
872
|
-
} catch {
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
async function with_run_marker(run) {
|
|
876
|
-
if (is_nested_run()) return await run();
|
|
877
|
-
const target2 = marker_path();
|
|
878
|
-
mark_run_started(target2);
|
|
879
|
-
process.env[NESTED_KEY] = NESTED_VALUE;
|
|
880
|
-
try {
|
|
881
|
-
return await run();
|
|
882
|
-
} finally {
|
|
883
|
-
process.env[NESTED_KEY] = "";
|
|
884
|
-
stamp_file.remove_stamp(target2);
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
var unit_worker_share = {
|
|
888
|
-
MIN_WORKERS,
|
|
889
|
-
NESTED_KEY,
|
|
890
|
-
NESTED_VALUE,
|
|
891
|
-
RUN_PREFIX,
|
|
892
|
-
SOLO_RUNS,
|
|
893
|
-
current_share,
|
|
894
|
-
is_nested_run,
|
|
895
|
-
live_run_count,
|
|
896
|
-
marker_path,
|
|
897
|
-
read_marker,
|
|
898
|
-
resolve_unit_workers,
|
|
899
|
-
with_run_marker,
|
|
900
|
-
worker_arguments
|
|
901
|
-
};
|
|
902
|
-
|
|
903
|
-
// scripts/gate/core-budget.ts
|
|
904
|
-
import { z as z2 } from "zod";
|
|
905
|
-
|
|
906
|
-
// scripts/gate/core-admission.ts
|
|
907
|
-
var MS_PER_SECOND = 1e3;
|
|
908
|
-
var RAMP_UP_MS = 3e4;
|
|
909
|
-
function compare_claim(left, right) {
|
|
910
|
-
const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
|
|
911
|
-
return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
|
|
912
|
-
}
|
|
913
|
-
function add_load(totals, reservation) {
|
|
914
|
-
totals.cores += reservation.weight;
|
|
915
|
-
totals.memory_mb += reservation.memory_mb ?? 0;
|
|
916
|
-
}
|
|
917
|
-
function exceeds(totals, budget) {
|
|
918
|
-
return totals.cores > budget.cores || totals.memory_mb > budget.memory_mb;
|
|
919
|
-
}
|
|
920
|
-
function admitted_keys(reservations, budget, memory_budget = Infinity) {
|
|
921
|
-
const limit = { cores: budget, memory_mb: memory_budget };
|
|
922
|
-
const totals = { cores: 0, memory_mb: 0 };
|
|
923
|
-
const admitted = /* @__PURE__ */ new Set();
|
|
924
|
-
for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
|
|
925
|
-
add_load(totals, entry.reservation);
|
|
926
|
-
if (index !== 0 && exceeds(totals, limit)) break;
|
|
927
|
-
admitted.add(entry.key);
|
|
928
|
-
}
|
|
929
|
-
return admitted;
|
|
930
|
-
}
|
|
931
|
-
function is_admitted(key, reservations, budget) {
|
|
932
|
-
return admitted_keys(reservations, budget.cores, budget.memory_mb).has(key);
|
|
933
|
-
}
|
|
934
|
-
function sum_load(reservations) {
|
|
935
|
-
const load = { cores: 0, memory_mb: 0 };
|
|
936
|
-
for (const entry of reservations) add_load(load, entry.reservation);
|
|
937
|
-
return load;
|
|
938
|
-
}
|
|
939
|
-
function is_ramped(reservation, now) {
|
|
940
|
-
const { admitted_at } = reservation;
|
|
941
|
-
return admitted_at !== void 0 && now - admitted_at >= RAMP_UP_MS;
|
|
942
|
-
}
|
|
943
|
-
function ledger_load(reservations, now) {
|
|
944
|
-
const admitted = reservations.filter((entry) => entry.reservation.admitted_at !== void 0);
|
|
945
|
-
const ramped = admitted.filter((entry) => is_ramped(entry.reservation, now));
|
|
946
|
-
return { cores: sum_load(admitted).cores, memory_mb: sum_load(ramped).memory_mb };
|
|
947
|
-
}
|
|
948
|
-
function total_weight(reservations) {
|
|
949
|
-
return sum_load(reservations).cores;
|
|
950
|
-
}
|
|
951
|
-
function admitted_load(reservations, budget) {
|
|
952
|
-
const admitted = admitted_keys(reservations, budget);
|
|
953
|
-
return total_weight(reservations.filter((entry) => admitted.has(entry.key)));
|
|
954
|
-
}
|
|
955
|
-
function describe_memory(ledger, budget) {
|
|
956
|
-
if (!Number.isFinite(budget.memory_mb)) return "";
|
|
957
|
-
return ` and ${String(Math.round(ledger.memory_mb))} MB of memory against ${String(Math.round(budget.memory_mb))} MB`;
|
|
958
|
-
}
|
|
959
|
-
function describe_overflow(admission) {
|
|
960
|
-
const { overflow } = admission;
|
|
961
|
-
if (overflow === void 0) return void 0;
|
|
962
|
-
const { ledger, budget } = overflow;
|
|
963
|
-
const waited = String(Math.round(overflow.waited_ms / MS_PER_SECOND));
|
|
964
|
-
const cores = `the ledger held ${String(ledger.cores)} cores against a budget of ${String(budget.cores)}`;
|
|
965
|
-
return `started past the core budget after ${waited}s \u2014 ${cores}${describe_memory(ledger, budget)}`;
|
|
966
|
-
}
|
|
967
|
-
var core_admission = {
|
|
968
|
-
RAMP_UP_MS,
|
|
969
|
-
admitted_keys,
|
|
970
|
-
admitted_load,
|
|
971
|
-
describe_overflow,
|
|
972
|
-
is_admitted,
|
|
973
|
-
ledger_load,
|
|
974
|
-
sum_load
|
|
975
|
-
};
|
|
976
|
-
|
|
977
|
-
// scripts/gate/machine-capacity.ts
|
|
978
|
-
import { readFile } from "node:fs/promises";
|
|
979
|
-
import { availableParallelism as availableParallelism2, cpus, totalmem } from "node:os";
|
|
980
|
-
import { execa } from "execa";
|
|
981
|
-
var SAMPLE_WINDOW_MS = 250;
|
|
982
|
-
var BASELINE_CORES = 2;
|
|
983
|
-
var BYTES_PER_MB = 1048576;
|
|
984
|
-
var KB_PER_MB = 1024;
|
|
985
|
-
var PERCENT = 100;
|
|
986
|
-
var MEMINFO_PATH = "/proc/meminfo";
|
|
987
|
-
var VMSTAT_PATH = "/proc/vmstat";
|
|
988
|
-
var LINUX_AVAILABLE = /^MemAvailable:\s+(?<kb>\d+) kB/mu;
|
|
989
|
-
var LINUX_SWAP_IN = /^pswpin (?<pages>\d+)$/mu;
|
|
990
|
-
var LINUX_SWAP_OUT = /^pswpout (?<pages>\d+)$/mu;
|
|
991
|
-
var PAGE_SIZE_ARGUMENTS = ["PAGESIZE"];
|
|
992
|
-
var LEVEL_NAME = "kern.memorystatus_level";
|
|
993
|
-
var SWAP_IN_NAME = "vm.compressor.swapper.swapins_total";
|
|
994
|
-
var SWAP_OUT_NAME = "vm.compressor.swapper.swapouts_total";
|
|
995
|
-
var PAGE_SIZE_NAME = "hw.pagesize";
|
|
996
|
-
var PRESSURE_NAME = "kern.memorystatus_vm_pressure_level";
|
|
997
|
-
var SYSCTL_ARGUMENTS = [LEVEL_NAME, SWAP_IN_NAME, SWAP_OUT_NAME, PAGE_SIZE_NAME, PRESSURE_NAME];
|
|
998
|
-
var SYSCTL_LINE = /^(?<name>[\w.]+): (?<value>\d+)$/gmu;
|
|
999
|
-
function cpu_times() {
|
|
1000
|
-
let busy = 0;
|
|
1001
|
-
let idle = 0;
|
|
1002
|
-
for (const { times } of cpus()) {
|
|
1003
|
-
busy += times.user + times.nice + times.sys + times.irq;
|
|
1004
|
-
idle += times.idle;
|
|
1005
|
-
}
|
|
1006
|
-
return { busy, total: busy + idle };
|
|
1007
|
-
}
|
|
1008
|
-
function busy_share_between(before, after) {
|
|
1009
|
-
const total = after.total - before.total;
|
|
1010
|
-
if (total <= 0) return void 0;
|
|
1011
|
-
return (after.busy - before.busy) / total;
|
|
1012
|
-
}
|
|
1013
|
-
function busy_cores_between(before, after, cores) {
|
|
1014
|
-
const share = busy_share_between(before, after);
|
|
1015
|
-
return share === void 0 ? void 0 : share * cores;
|
|
1016
|
-
}
|
|
1017
|
-
function sysctl_values(output) {
|
|
1018
|
-
const values = [...output.matchAll(SYSCTL_LINE)].map(
|
|
1019
|
-
(match) => [match.groups?.["name"] ?? "", Number(match.groups?.["value"])]
|
|
1020
|
-
);
|
|
1021
|
-
return new Map(values);
|
|
1022
|
-
}
|
|
1023
|
-
function swapped_pages(pages_in, pages_out) {
|
|
1024
|
-
return pages_in === void 0 || pages_out === void 0 ? void 0 : pages_in + pages_out;
|
|
1025
|
-
}
|
|
1026
|
-
function swapped_mb(pages, page_bytes) {
|
|
1027
|
-
if (pages === void 0 || page_bytes === void 0) return void 0;
|
|
1028
|
-
return pages * page_bytes / BYTES_PER_MB;
|
|
1029
|
-
}
|
|
1030
|
-
function swapped_between(from, to) {
|
|
1031
|
-
if (from === void 0 || to === void 0) return void 0;
|
|
1032
|
-
return Math.max(0, to - from);
|
|
1033
|
-
}
|
|
1034
|
-
function parse_darwin_memory(output, total_bytes) {
|
|
1035
|
-
const values = sysctl_values(output);
|
|
1036
|
-
const level = values.get(LEVEL_NAME);
|
|
1037
|
-
return {
|
|
1038
|
-
available_mb: level === void 0 ? void 0 : level / PERCENT * (total_bytes / BYTES_PER_MB),
|
|
1039
|
-
swapped_mb: swapped_mb(
|
|
1040
|
-
swapped_pages(values.get(SWAP_IN_NAME), values.get(SWAP_OUT_NAME)),
|
|
1041
|
-
values.get(PAGE_SIZE_NAME)
|
|
1042
|
-
),
|
|
1043
|
-
pressure_level: values.get(PRESSURE_NAME)
|
|
1044
|
-
};
|
|
1045
|
-
}
|
|
1046
|
-
function parse_linux_available(meminfo) {
|
|
1047
|
-
const kb = LINUX_AVAILABLE.exec(meminfo)?.groups?.["kb"];
|
|
1048
|
-
return kb === void 0 ? void 0 : Number(kb) / KB_PER_MB;
|
|
1049
|
-
}
|
|
1050
|
-
function pages_of(pattern, vmstat) {
|
|
1051
|
-
const pages = pattern.exec(vmstat)?.groups?.["pages"];
|
|
1052
|
-
return pages === void 0 ? void 0 : Number(pages);
|
|
1053
|
-
}
|
|
1054
|
-
function parse_linux_swapped(vmstat, page_bytes) {
|
|
1055
|
-
const pages = swapped_pages(pages_of(LINUX_SWAP_IN, vmstat), pages_of(LINUX_SWAP_OUT, vmstat));
|
|
1056
|
-
return swapped_mb(pages, page_bytes);
|
|
1057
|
-
}
|
|
1058
|
-
async function settled(read) {
|
|
1059
|
-
try {
|
|
1060
|
-
return await read();
|
|
1061
|
-
} catch {
|
|
1062
|
-
return void 0;
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
async function read_darwin_memory() {
|
|
1066
|
-
const { stdout } = await execa("sysctl", SYSCTL_ARGUMENTS, {
|
|
1067
|
-
reject: false,
|
|
1068
|
-
timeout: PROBE_TIMEOUT_MS
|
|
1069
|
-
});
|
|
1070
|
-
return parse_darwin_memory(stdout, totalmem());
|
|
1071
|
-
}
|
|
1072
|
-
async function read_page_size() {
|
|
1073
|
-
const { stdout } = await execa("getconf", PAGE_SIZE_ARGUMENTS, { timeout: PROBE_TIMEOUT_MS });
|
|
1074
|
-
return stdout;
|
|
1075
|
-
}
|
|
1076
|
-
async function read_linux_memory() {
|
|
1077
|
-
const [meminfo, vmstat, page_size] = await Promise.all([
|
|
1078
|
-
settled(async () => await readFile(MEMINFO_PATH, "utf8")),
|
|
1079
|
-
settled(async () => await readFile(VMSTAT_PATH, "utf8")),
|
|
1080
|
-
settled(read_page_size)
|
|
1081
|
-
]);
|
|
1082
|
-
const page_bytes = page_size === void 0 ? void 0 : Number(page_size);
|
|
1083
|
-
return {
|
|
1084
|
-
available_mb: meminfo === void 0 ? void 0 : parse_linux_available(meminfo),
|
|
1085
|
-
swapped_mb: vmstat === void 0 || page_bytes === void 0 ? void 0 : parse_linux_swapped(vmstat, page_bytes),
|
|
1086
|
-
pressure_level: void 0
|
|
1087
|
-
};
|
|
1088
|
-
}
|
|
1089
|
-
var UNREAD_MEMORY = {
|
|
1090
|
-
available_mb: void 0,
|
|
1091
|
-
swapped_mb: void 0,
|
|
1092
|
-
pressure_level: void 0
|
|
1093
|
-
};
|
|
1094
|
-
async function read_memory() {
|
|
1095
|
-
if (process.platform === "darwin") return await settled(read_darwin_memory) ?? UNREAD_MEMORY;
|
|
1096
|
-
return process.platform === "linux" ? await read_linux_memory() : UNREAD_MEMORY;
|
|
1097
|
-
}
|
|
1098
|
-
function is_unquoted() {
|
|
1099
|
-
return cpus().length > 0 && cpus().length === availableParallelism2();
|
|
1100
|
-
}
|
|
1101
|
-
async function default_sleep(ms) {
|
|
1102
|
-
await new Promise((resolve) => {
|
|
1103
|
-
setTimeout(resolve, ms);
|
|
1104
|
-
});
|
|
523
|
+
function pressured_available(before, after) {
|
|
524
|
+
if (after.available_mb === void 0) return void 0;
|
|
525
|
+
return is_pressured(before, after) ? 0 : after.available_mb;
|
|
1105
526
|
}
|
|
1106
527
|
async function read_machine(sleep = default_sleep) {
|
|
1107
528
|
const before = cpu_times();
|
|
1108
|
-
const [
|
|
529
|
+
const [memory_before] = await Promise.all([read_memory(), sleep(SAMPLE_WINDOW_MS)]);
|
|
530
|
+
const memory_after = await read_memory();
|
|
1109
531
|
const busy_cores = is_unquoted() ? busy_cores_between(before, cpu_times(), cpus().length) : void 0;
|
|
1110
|
-
return {
|
|
532
|
+
return {
|
|
533
|
+
busy_cores,
|
|
534
|
+
available_mb: pressured_available(memory_before, memory_after),
|
|
535
|
+
memory_pressured: is_pressured(memory_before, memory_after)
|
|
536
|
+
};
|
|
1111
537
|
}
|
|
1112
538
|
async function read_sample() {
|
|
1113
539
|
return { cpu: cpu_times(), memory: await read_memory(), total_mb: totalmem() / BYTES_PER_MB };
|
|
@@ -1119,210 +545,965 @@ function external_cores(busy_cores, ledger_cores) {
|
|
|
1119
545
|
function machine_budget(cores, reading, ledger) {
|
|
1120
546
|
return {
|
|
1121
547
|
cores: cores - external_cores(reading.busy_cores, ledger.cores),
|
|
1122
|
-
memory_mb: reading.available_mb === void 0 ? Infinity : reading.available_mb + ledger.memory_mb
|
|
548
|
+
memory_mb: reading.available_mb === void 0 ? Infinity : reading.available_mb + ledger.memory_mb,
|
|
549
|
+
memory_pressured: reading.memory_pressured
|
|
1123
550
|
};
|
|
1124
551
|
}
|
|
1125
552
|
var machine_capacity = {
|
|
1126
553
|
BASELINE_CORES,
|
|
1127
554
|
busy_cores_between,
|
|
1128
555
|
busy_share_between,
|
|
556
|
+
COMPRESSION_PRESSURE_MB,
|
|
1129
557
|
external_cores,
|
|
1130
558
|
machine_budget,
|
|
1131
559
|
parse_darwin_memory,
|
|
1132
560
|
parse_linux_available,
|
|
1133
561
|
parse_linux_swapped,
|
|
562
|
+
pressured_available,
|
|
1134
563
|
read_machine,
|
|
1135
564
|
read_memory,
|
|
1136
565
|
read_sample,
|
|
566
|
+
SWAP_PRESSURE_MB,
|
|
1137
567
|
swapped_between
|
|
1138
568
|
};
|
|
1139
569
|
|
|
1140
|
-
// scripts/gate/core-budget.ts
|
|
1141
|
-
var RESERVED_PREFIX = "josh-core-reserved-";
|
|
1142
|
-
var RESERVED_SUFFIX = ".json";
|
|
1143
|
-
var POLL_INTERVAL_MS = 50;
|
|
1144
|
-
var WAIT_CAP_MS = 12e4;
|
|
1145
|
-
var MIN_BUDGET = 1;
|
|
1146
|
-
var CORE_WEIGHTS = {
|
|
1147
|
-
lint: 2,
|
|
1148
|
-
type_check: 1,
|
|
1149
|
-
spell_check: 1,
|
|
1150
|
-
eslint_scan: 1
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
return
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
const
|
|
1266
|
-
const
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
const
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
570
|
+
// scripts/gate/core-budget.ts
|
|
571
|
+
var RESERVED_PREFIX = "josh-core-reserved-";
|
|
572
|
+
var RESERVED_SUFFIX = ".json";
|
|
573
|
+
var POLL_INTERVAL_MS = 50;
|
|
574
|
+
var WAIT_CAP_MS = 12e4;
|
|
575
|
+
var MIN_BUDGET = 1;
|
|
576
|
+
var CORE_WEIGHTS = {
|
|
577
|
+
lint: 2,
|
|
578
|
+
type_check: 1,
|
|
579
|
+
spell_check: 1,
|
|
580
|
+
eslint_scan: 1,
|
|
581
|
+
format: 1,
|
|
582
|
+
retrospective: 1,
|
|
583
|
+
install: 1,
|
|
584
|
+
e2e: 2
|
|
585
|
+
};
|
|
586
|
+
var MEMORY_MB = {
|
|
587
|
+
lint: 2400,
|
|
588
|
+
type_check: 1300,
|
|
589
|
+
spell_check: 350,
|
|
590
|
+
eslint_scan: 2400,
|
|
591
|
+
unit_worker: 350,
|
|
592
|
+
format: 300,
|
|
593
|
+
retrospective: 900,
|
|
594
|
+
install: 100
|
|
595
|
+
};
|
|
596
|
+
var reservation_schema = process_owner_schema.extend({
|
|
597
|
+
weight: z2.number(),
|
|
598
|
+
claimed_at: z2.number(),
|
|
599
|
+
memory_mb: z2.number().optional(),
|
|
600
|
+
admitted_at: z2.number().optional(),
|
|
601
|
+
command: z2.string().optional(),
|
|
602
|
+
checkout: z2.string().optional(),
|
|
603
|
+
lane: z2.string().optional(),
|
|
604
|
+
lanes_root: z2.string().optional(),
|
|
605
|
+
wait_reason: z2.enum(core_wait.WAIT_REASONS).optional()
|
|
606
|
+
});
|
|
607
|
+
function marker_name(key) {
|
|
608
|
+
return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`;
|
|
609
|
+
}
|
|
610
|
+
function is_running2(reservation) {
|
|
611
|
+
return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false;
|
|
612
|
+
}
|
|
613
|
+
function read_reservation(source) {
|
|
614
|
+
const raw = stamp_file.read_stamp_text(source);
|
|
615
|
+
if (raw === void 0) return void 0;
|
|
616
|
+
return json_value.parse_with(raw, reservation_schema);
|
|
617
|
+
}
|
|
618
|
+
function sweep_marker2(source) {
|
|
619
|
+
try {
|
|
620
|
+
stamp_file.remove_stamp(source);
|
|
621
|
+
} catch {
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
function live_reservation(source) {
|
|
625
|
+
const reservation = read_reservation(source);
|
|
626
|
+
if (reservation === void 0) return void 0;
|
|
627
|
+
if (is_running2(reservation)) return reservation;
|
|
628
|
+
sweep_marker2(source);
|
|
629
|
+
return void 0;
|
|
630
|
+
}
|
|
631
|
+
function marker_files2(directory) {
|
|
632
|
+
try {
|
|
633
|
+
return readdirSync2(directory).filter(
|
|
634
|
+
(name) => name.startsWith(RESERVED_PREFIX) && name.endsWith(RESERVED_SUFFIX)
|
|
635
|
+
);
|
|
636
|
+
} catch {
|
|
637
|
+
return [];
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
function live_reservations(directory = PLATFORM_TEMP_ROOT) {
|
|
641
|
+
return marker_files2(directory).flatMap((name) => {
|
|
642
|
+
const reservation = live_reservation(path3.join(directory, name));
|
|
643
|
+
return reservation === void 0 ? [] : { key: name, reservation };
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
function normalize_budget(budget) {
|
|
647
|
+
return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET;
|
|
648
|
+
}
|
|
649
|
+
async function default_sleep2(ms) {
|
|
650
|
+
await new Promise((resolve) => {
|
|
651
|
+
setTimeout(resolve, ms);
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
function write_reservation(target2, fields) {
|
|
655
|
+
stamp_file.replace_stamp(target2, { ...process_identity.own_fields(), ...fields });
|
|
656
|
+
}
|
|
657
|
+
function report_wait(line) {
|
|
658
|
+
process.stderr.write(`${line}
|
|
659
|
+
`);
|
|
660
|
+
}
|
|
661
|
+
function resolve_timing(options) {
|
|
662
|
+
return {
|
|
663
|
+
now: options.now ?? Date.now,
|
|
664
|
+
sleep: options.sleep ?? default_sleep2,
|
|
665
|
+
poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
|
|
666
|
+
wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
async function current_budget(context, reservations) {
|
|
670
|
+
if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity };
|
|
671
|
+
const reading = await context.read_machine();
|
|
672
|
+
const ledger = core_admission.ledger_load(reservations, context.now());
|
|
673
|
+
const budget = machine_capacity.machine_budget(context.budget, reading, ledger);
|
|
674
|
+
return { ...budget, cores: normalize_budget(budget.cores) };
|
|
675
|
+
}
|
|
676
|
+
function admit(context, overflow) {
|
|
677
|
+
write_reservation(context.target, { ...context.fields, admitted_at: context.now() });
|
|
678
|
+
return { overflow };
|
|
679
|
+
}
|
|
680
|
+
function overflow_of(context, reservations, budget) {
|
|
681
|
+
return {
|
|
682
|
+
waited_ms: context.now() - context.fields.claimed_at,
|
|
683
|
+
ledger: core_admission.sum_load(reservations),
|
|
684
|
+
budget
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
function mark_waiting(context, reason) {
|
|
688
|
+
const previous = context.fields.wait_reason;
|
|
689
|
+
if (previous === reason) return;
|
|
690
|
+
context.fields = { ...context.fields, wait_reason: reason };
|
|
691
|
+
write_reservation(context.target, context.fields);
|
|
692
|
+
if (previous === void 0) context.report(core_wait.wait_line(context.fields.command, reason));
|
|
693
|
+
}
|
|
694
|
+
async function poll_admission(context) {
|
|
695
|
+
const reservations = live_reservations(context.directory);
|
|
696
|
+
const budget = await current_budget(context, reservations);
|
|
697
|
+
if (core_admission.is_admitted(context.key, reservations, budget)) return admit(context);
|
|
698
|
+
if (context.now() >= context.deadline) {
|
|
699
|
+
return admit(context, overflow_of(context, reservations, budget));
|
|
700
|
+
}
|
|
701
|
+
mark_waiting(context, core_wait.wait_reason(context.key, reservations, budget));
|
|
702
|
+
return void 0;
|
|
703
|
+
}
|
|
704
|
+
async function await_admission(context) {
|
|
705
|
+
let admission = await poll_admission(context);
|
|
706
|
+
while (admission === void 0) {
|
|
707
|
+
await context.sleep(context.poll_interval_ms);
|
|
708
|
+
admission = await poll_admission(context);
|
|
709
|
+
}
|
|
710
|
+
return admission;
|
|
711
|
+
}
|
|
712
|
+
function resolve_ports(options) {
|
|
713
|
+
return {
|
|
714
|
+
read_machine: options.read_machine ?? machine_capacity.read_machine,
|
|
715
|
+
report: options.report ?? report_wait
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
function claim_fields(weight, claimed_at, options) {
|
|
719
|
+
const { memory_mb, command } = options;
|
|
720
|
+
return { weight, claimed_at, memory_mb, command, ...core_wait.where_of(process.cwd()) };
|
|
721
|
+
}
|
|
722
|
+
async function reserve(weight, options = {}) {
|
|
723
|
+
const timing = resolve_timing(options);
|
|
724
|
+
const directory = options.directory ?? PLATFORM_TEMP_ROOT;
|
|
725
|
+
const claimed_at = timing.now();
|
|
726
|
+
const name = marker_name(randomUUID());
|
|
727
|
+
const target2 = path3.join(directory, name);
|
|
728
|
+
const fields = claim_fields(weight, claimed_at, options);
|
|
729
|
+
write_reservation(target2, fields);
|
|
730
|
+
const admission = await await_admission({
|
|
731
|
+
...timing,
|
|
732
|
+
key: name,
|
|
733
|
+
target: target2,
|
|
734
|
+
directory,
|
|
735
|
+
budget: normalize_budget(options.budget ?? availableParallelism3()),
|
|
736
|
+
deadline: claimed_at + timing.wait_cap_ms,
|
|
737
|
+
fields,
|
|
738
|
+
...resolve_ports(options)
|
|
739
|
+
});
|
|
740
|
+
return { target: target2, admission };
|
|
741
|
+
}
|
|
742
|
+
function budget_waits(directory = PLATFORM_TEMP_ROOT, now = Date.now(), home = process.cwd()) {
|
|
743
|
+
return core_wait.waits_of(live_reservations(directory), now, home);
|
|
744
|
+
}
|
|
745
|
+
function release(handle) {
|
|
746
|
+
sweep_marker2(handle.target);
|
|
747
|
+
}
|
|
748
|
+
async function with_core_reservation(weight, run, options = {}) {
|
|
749
|
+
const handle = await reserve(weight, options);
|
|
750
|
+
try {
|
|
751
|
+
return await run(handle.admission, path3.basename(handle.target));
|
|
752
|
+
} finally {
|
|
753
|
+
release(handle);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
async function with_command_reservation(weight, run, options = {}) {
|
|
757
|
+
if (held_mark.is_held() || unit_worker_share.is_nested_run()) return await run();
|
|
758
|
+
return await with_core_reservation(
|
|
759
|
+
weight,
|
|
760
|
+
async (_admission, key) => await held_mark.with_held_mark(run, key),
|
|
761
|
+
options
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
var core_budget = {
|
|
765
|
+
CORE_WEIGHTS,
|
|
766
|
+
HELD_KEY: held_mark.HELD_KEY,
|
|
767
|
+
HELD_VALUE: held_mark.HELD_VALUE,
|
|
768
|
+
MEMORY_MB,
|
|
769
|
+
RESERVED_PREFIX,
|
|
770
|
+
admitted_keys: core_admission.admitted_keys,
|
|
771
|
+
admitted_load: core_admission.admitted_load,
|
|
772
|
+
budget_waits,
|
|
773
|
+
describe_overflow: core_admission.describe_overflow,
|
|
774
|
+
is_held: held_mark.is_held,
|
|
775
|
+
live_reservations,
|
|
776
|
+
release,
|
|
777
|
+
reserve,
|
|
778
|
+
with_command_reservation,
|
|
779
|
+
with_core_reservation,
|
|
780
|
+
with_held_mark: held_mark.with_held_mark
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
// scripts/josh/josh-command-types.ts
|
|
784
|
+
var OPTIONAL_ENV_FILE_FLAGS = [`--env-file-if-exists=${ENV_FILE_NAME}`];
|
|
785
|
+
var GATE_COMMAND2 = "gate";
|
|
786
|
+
var ESLINT_CACHE_FILE = ".eslintcache";
|
|
787
|
+
var TS_BUILD_INFO_FILE = ".tsbuildinfo";
|
|
788
|
+
var CSPELL_CACHE_FILE = ".cspellcache";
|
|
789
|
+
var ESLINT_EDIT_CACHE_FILE = ".eslintcache.edit";
|
|
790
|
+
var ESLINT_RELATED_CACHE_FILE = ".eslintcache.related";
|
|
791
|
+
var PRETTIER_CACHE_FILE = ".prettiercache";
|
|
792
|
+
var PRETTIER_RELATED_CACHE_FILE = ".prettiercache.related";
|
|
793
|
+
var CSPELL_COMMIT_CACHE_FILE = ".cspellcache.commit";
|
|
794
|
+
var ESLINT_COMMIT_CACHE_FILE = ".eslintcache.commit";
|
|
795
|
+
var ROOTED_JSON_PORTABILITY = "rooted-json";
|
|
796
|
+
var ESLINT_CACHE_SPEC = {
|
|
797
|
+
cache_file: ESLINT_CACHE_FILE,
|
|
798
|
+
portability: ROOTED_JSON_PORTABILITY
|
|
799
|
+
};
|
|
800
|
+
var TS_CACHE_SPEC = {
|
|
801
|
+
cache_file: TS_BUILD_INFO_FILE,
|
|
802
|
+
portability: "raw"
|
|
803
|
+
};
|
|
804
|
+
var CSPELL_CACHE_SPEC = {
|
|
805
|
+
cache_file: CSPELL_CACHE_FILE,
|
|
806
|
+
portability: "raw"
|
|
807
|
+
};
|
|
808
|
+
var GATE_CACHE_SPECS = [
|
|
809
|
+
ESLINT_CACHE_SPEC,
|
|
810
|
+
TS_CACHE_SPEC,
|
|
811
|
+
CSPELL_CACHE_SPEC
|
|
812
|
+
];
|
|
813
|
+
var GATE_CACHE_FILES = GATE_CACHE_SPECS.map((spec) => spec.cache_file);
|
|
814
|
+
var IGNORED_CACHE_FILES = [
|
|
815
|
+
...GATE_CACHE_FILES,
|
|
816
|
+
ESLINT_EDIT_CACHE_FILE,
|
|
817
|
+
ESLINT_RELATED_CACHE_FILE,
|
|
818
|
+
PRETTIER_CACHE_FILE,
|
|
819
|
+
PRETTIER_RELATED_CACHE_FILE,
|
|
820
|
+
CSPELL_COMMIT_CACHE_FILE,
|
|
821
|
+
ESLINT_COMMIT_CACHE_FILE
|
|
822
|
+
];
|
|
823
|
+
var CONTENT_CACHE_FLAGS = ["--cache", "--cache-strategy", "content"];
|
|
824
|
+
var CACHE_LOCATION_FLAG = "--cache-location";
|
|
825
|
+
function content_cache_flags(cache_file) {
|
|
826
|
+
return [...CONTENT_CACHE_FLAGS, CACHE_LOCATION_FLAG, cache_file];
|
|
827
|
+
}
|
|
828
|
+
var ESLINT_CACHE_FLAGS = content_cache_flags(ESLINT_CACHE_FILE);
|
|
829
|
+
var ESLINT_EDIT_CACHE_FLAGS = content_cache_flags(ESLINT_EDIT_CACHE_FILE);
|
|
830
|
+
var ESLINT_RELATED_CACHE_FLAGS = content_cache_flags(ESLINT_RELATED_CACHE_FILE);
|
|
831
|
+
var CSPELL_CACHE_FLAGS = content_cache_flags(CSPELL_CACHE_FILE);
|
|
832
|
+
var PRETTIER_CACHE_FLAGS = content_cache_flags(PRETTIER_CACHE_FILE);
|
|
833
|
+
var PRETTIER_RELATED_CACHE_FLAGS = content_cache_flags(PRETTIER_RELATED_CACHE_FILE);
|
|
834
|
+
var CSPELL_COMMIT_CACHE_FLAGS = content_cache_flags(CSPELL_COMMIT_CACHE_FILE);
|
|
835
|
+
var ESLINT_COMMIT_CACHE_FLAGS = content_cache_flags(ESLINT_COMMIT_CACHE_FILE);
|
|
836
|
+
|
|
837
|
+
// scripts/josh/josh-commands-backlog.ts
|
|
838
|
+
var BACKLOG_COMMANDS = {
|
|
839
|
+
// Started from a terminal: the `backlogrun` keyword's launcher, and the board.
|
|
840
|
+
backlogrun: {
|
|
841
|
+
script: "scripts/backlog/backlogrun-cli.ts",
|
|
842
|
+
description: "Start a backlogrun in the background and show its board; with one already running, only show the board, or replace it when it is idle and the invocation differs; --stop stops it",
|
|
843
|
+
category: "AI tools",
|
|
844
|
+
reference: [
|
|
845
|
+
"[<n>...] [--only] [--max <n>] [--idle <minutes>] [--agent claude|codex] | --stop",
|
|
846
|
+
"developer",
|
|
847
|
+
["files", "network", "processes"]
|
|
848
|
+
]
|
|
849
|
+
},
|
|
850
|
+
"backlog:next": {
|
|
851
|
+
script: "scripts/backlog/backlog-next.ts",
|
|
852
|
+
description: "Order the whole opted-in backlog: auto-ok issues and the descendants of auto-ok epics, transitively through nested epics",
|
|
853
|
+
category: "AI tools",
|
|
854
|
+
reference: ["[--exclude <n>[,<n>...]] [--repo <owner/repo>]", "automation", ["network"]]
|
|
855
|
+
},
|
|
856
|
+
"backlog:offer": {
|
|
857
|
+
script: "scripts/backlog/backlog-offer-cli.ts",
|
|
858
|
+
description: "Collapse a backlogrun loop-head event into one call: read backlog:next, ask backlog:budget, return the verdict and any issues to start",
|
|
859
|
+
category: "AI tools",
|
|
860
|
+
reference: ["[options]", "automation", ["files", "network", "processes"]]
|
|
861
|
+
},
|
|
862
|
+
"backlog:drive": {
|
|
863
|
+
script: "scripts/backlog/backlog-drive-cli.ts",
|
|
864
|
+
description: "Drive backlogrun through offer, launch and merge; restore this run\u2019s lanes and report when complete",
|
|
865
|
+
category: "AI tools",
|
|
866
|
+
reference: ["--owner <pid> [options]", "automation", ["network"]]
|
|
867
|
+
},
|
|
868
|
+
"backlog:plan": {
|
|
869
|
+
script: "scripts/backlog/backlog-plan-cli.ts",
|
|
870
|
+
description: "Print the whole backlog as a plan: ready now, waiting on what, waiting on a person, out of scope",
|
|
871
|
+
category: "AI tools",
|
|
872
|
+
reference: [
|
|
873
|
+
"[issue...] [--only] [--waves] [--exclude <n>[,<n>...]]",
|
|
874
|
+
"automation",
|
|
875
|
+
["network"]
|
|
876
|
+
]
|
|
877
|
+
},
|
|
878
|
+
"backlog:stalled": {
|
|
879
|
+
script: "scripts/backlog/backlog-stalled-cli.ts",
|
|
880
|
+
// A stall sends one Telegram warning. The `Stop` hook calls the detector
|
|
881
|
+
// directly, so this flag costs only the manual command its in-process dispatch.
|
|
882
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
883
|
+
description: "Report whether ready backlog work is sitting undispatched with a free lane and no recent dispatch",
|
|
884
|
+
category: "AI tools",
|
|
885
|
+
reference: ["", "automation", ["network"]]
|
|
886
|
+
},
|
|
887
|
+
"backlog:budget": {
|
|
888
|
+
script: "scripts/backlog/backlog-budget-cli.ts",
|
|
889
|
+
description: "Say whether a backlogrun may start more work, keep watching, or finish",
|
|
890
|
+
category: "AI tools",
|
|
891
|
+
reference: ["[options]", "automation", ["none"]]
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
|
|
895
|
+
// scripts/josh/josh-commands-document.ts
|
|
896
|
+
var DOCUMENT_COMMANDS = {
|
|
897
|
+
"doc:section": {
|
|
898
|
+
script: "scripts/document/document-section-cli.ts",
|
|
899
|
+
description: 'Print one section of a markdown document, for a `file.md` \u2192 "Heading" reference',
|
|
900
|
+
category: "AI tools",
|
|
901
|
+
reference: ["<file> <heading>", "automation", ["none"]],
|
|
902
|
+
is_bundled: true
|
|
903
|
+
},
|
|
904
|
+
"read:set": {
|
|
905
|
+
script: "scripts/document/read-set-cli.ts",
|
|
906
|
+
description: "Print what an entry point reads before it starts, and what that read costs",
|
|
907
|
+
category: "AI tools",
|
|
908
|
+
reference: ["[<entry>] [--json]", "automation", ["none"]]
|
|
909
|
+
},
|
|
910
|
+
"doc:read": {
|
|
911
|
+
script: "scripts/document/document-read-cli.ts",
|
|
912
|
+
description: "Read a whole document safely: print it, or point at the Read tool when over the Bash cap",
|
|
913
|
+
category: "AI tools",
|
|
914
|
+
reference: ["<file>", "automation", ["none"]]
|
|
915
|
+
},
|
|
916
|
+
"read:files": {
|
|
917
|
+
script: "scripts/document/read-files-cli.ts",
|
|
918
|
+
description: "Read several files in one call so edit targets fold into one turn",
|
|
919
|
+
category: "AI tools",
|
|
920
|
+
reference: ["<path> [<path> ...]", "automation", ["none"]]
|
|
921
|
+
},
|
|
922
|
+
"edit:files": {
|
|
923
|
+
script: "scripts/document/edit-files-cli.ts",
|
|
924
|
+
description: "Apply several content-addressed edits from a plan in one call",
|
|
925
|
+
category: "AI tools",
|
|
926
|
+
reference: ["<plan-path | ->", "automation", ["none"]]
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
|
|
930
|
+
// scripts/josh/josh-commands-guard.ts
|
|
931
|
+
var GUARD_COMMANDS = {
|
|
932
|
+
"investigation:guard": {
|
|
933
|
+
script: "scripts/delegation/investigation-guard.ts",
|
|
934
|
+
description: "Claude Code hook: refuse a read once the unedited-read threshold is reached again (reads the tool call on stdin)",
|
|
935
|
+
category: "AI tools",
|
|
936
|
+
reference: ["", "automation", ["none"]]
|
|
937
|
+
},
|
|
938
|
+
"duplicate-read:guard": {
|
|
939
|
+
script: "scripts/delegation/duplicate-read-guard.ts",
|
|
940
|
+
description: "Claude Code hook: refuse a second whole-file read of a path whose content has not changed since the run last read it (reads the tool call on stdin)",
|
|
941
|
+
category: "AI tools",
|
|
942
|
+
reference: ["", "automation", ["none"]]
|
|
943
|
+
},
|
|
944
|
+
"rule:guard": {
|
|
945
|
+
script: "scripts/rules/rule-guard.ts",
|
|
946
|
+
description: "Claude Code hook: deliver a trigger-delivered rule at the call that binds it (reads the tool call on stdin)",
|
|
947
|
+
category: "AI tools",
|
|
948
|
+
reference: ["", "automation", ["none"]]
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
|
|
952
|
+
// scripts/josh/josh-commands-issue.ts
|
|
953
|
+
var ISSUES_WITH_REPO = "<issue...> [--repo <owner/repo>]";
|
|
954
|
+
var ISSUE_COMMANDS = {
|
|
955
|
+
"issue:ack": {
|
|
956
|
+
script: "scripts/issue/issue-ack-cli.ts",
|
|
957
|
+
description: "Record that the run read a person's update to its issue, printing the update it acknowledges",
|
|
958
|
+
category: "AI tools",
|
|
959
|
+
reference: ["<issue>", "automation", ["network"]]
|
|
960
|
+
},
|
|
961
|
+
"issue:read": {
|
|
962
|
+
script: "scripts/issue/issue-read-cli.ts",
|
|
963
|
+
description: "Print each issue's title, body and every comment on it, in one call",
|
|
964
|
+
category: "AI tools",
|
|
965
|
+
reference: ["<issue...>", "automation", ["network"]]
|
|
966
|
+
},
|
|
967
|
+
"issue:state": {
|
|
968
|
+
script: "scripts/issue/issue-state-cli.ts",
|
|
969
|
+
description: "Print each issue's state and labels, in the spelling the documents compare against",
|
|
970
|
+
category: "AI tools",
|
|
971
|
+
reference: [ISSUES_WITH_REPO, "automation", ["network"]]
|
|
972
|
+
},
|
|
973
|
+
"issue:scout": {
|
|
974
|
+
script: "scripts/issue/issue-scout-cli.ts",
|
|
975
|
+
description: "Before filing: say whether an issue like this exists and which epic it belongs to",
|
|
976
|
+
category: "AI tools",
|
|
977
|
+
reference: ["<title> [--body <summary> | --body-file <path>]", "automation", ["network"]]
|
|
978
|
+
},
|
|
979
|
+
"defect:rate": {
|
|
980
|
+
script: "scripts/issue/defect-rate-cli.ts",
|
|
981
|
+
description: "Print the defect rate of merged work: defects filed per enhancement completed",
|
|
982
|
+
category: "AI tools",
|
|
983
|
+
reference: ["[--days <n>]", "automation", ["network"]]
|
|
984
|
+
},
|
|
985
|
+
"issue:fold": {
|
|
986
|
+
script: "scripts/issue/issue-fold-cli.ts",
|
|
987
|
+
description: "Before a second filing: say whether findings from this session fold into one issue",
|
|
988
|
+
category: "AI tools",
|
|
989
|
+
reference: ["<title>... [--not-separable] [--json]", "automation", ["none"]]
|
|
990
|
+
},
|
|
991
|
+
"issue:fold-existing": {
|
|
992
|
+
script: "scripts/issue/issue-fold-existing-cli.ts",
|
|
993
|
+
description: "Assess whether a complete draft can join an unstarted issue",
|
|
994
|
+
category: "AI tools",
|
|
995
|
+
reference: ["<assessment.json> [--json]", "automation", ["none"]]
|
|
996
|
+
},
|
|
997
|
+
"issue:cite": {
|
|
998
|
+
script: "scripts/issue/issue-cite-cli.ts",
|
|
999
|
+
description: "Print the paste-ready number-link citation line for each issue, in one call",
|
|
1000
|
+
category: "AI tools",
|
|
1001
|
+
reference: [ISSUES_WITH_REPO, "automation", ["network"]]
|
|
1002
|
+
},
|
|
1003
|
+
"issue:comment": {
|
|
1004
|
+
script: "scripts/issue/issue-comment-cli.ts",
|
|
1005
|
+
description: "Post one comment to an issue from a file, so no shell expands the body",
|
|
1006
|
+
category: "AI tools",
|
|
1007
|
+
reference: ["<issue> --body <text> | --body-file <path>", "automation", ["network"]]
|
|
1008
|
+
},
|
|
1009
|
+
"issue:file": {
|
|
1010
|
+
script: "scripts/issue/issue-file-cli.ts",
|
|
1011
|
+
description: "File an Issue with every filing step: lint, Origin, fold, WIP cap, duplicate scout, labels, then epic:bundle",
|
|
1012
|
+
category: "AI tools",
|
|
1013
|
+
reference: [
|
|
1014
|
+
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok] [--release]",
|
|
1015
|
+
"automation",
|
|
1016
|
+
["network"]
|
|
1017
|
+
]
|
|
1018
|
+
},
|
|
1019
|
+
"issue:release": {
|
|
1020
|
+
script: "scripts/issue/issue-release-cli.ts",
|
|
1021
|
+
description: "Link an Issue to the repository's open release Issue as its blocker (or, with --wait, as waiting on it), filing one when none is open",
|
|
1022
|
+
category: "AI tools",
|
|
1023
|
+
reference: ["<issue> [--wait]", "automation", ["network"]]
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
// scripts/josh/josh-commands-lane.ts
|
|
1028
|
+
var LANE_SCRIPT = "scripts/lane/lane-cli.ts";
|
|
1029
|
+
var LANE_ARGUMENTS = { script: LANE_SCRIPT, tsx_arguments: OPTIONAL_ENV_FILE_FLAGS };
|
|
1030
|
+
var ISSUE_WITH_OPTIONS = "<issue> [options]";
|
|
1031
|
+
var MEASURE_ARGUMENTS = {
|
|
1032
|
+
script: "scripts/lane/lane-measure-cli.ts",
|
|
1033
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
|
|
1034
|
+
};
|
|
1035
|
+
var LANE_COMMANDS = {
|
|
1036
|
+
"lane:open": {
|
|
1037
|
+
...LANE_ARGUMENTS,
|
|
1038
|
+
description: "Open a lane: a linked work tree with its own branch and its own port seed",
|
|
1039
|
+
category: "AI tools",
|
|
1040
|
+
reference: [ISSUE_WITH_OPTIONS, "automation", ["files", "git"]],
|
|
1041
|
+
default_script_arguments: ["open"]
|
|
1042
|
+
},
|
|
1043
|
+
"lane:close": {
|
|
1044
|
+
...LANE_ARGUMENTS,
|
|
1045
|
+
description: "Close a lane, leaving no work tree, branch or directory behind",
|
|
1046
|
+
category: "AI tools",
|
|
1047
|
+
reference: ["<issue>", "automation", ["files", "git"]],
|
|
1048
|
+
default_script_arguments: ["close"]
|
|
1049
|
+
},
|
|
1050
|
+
"lane:list": {
|
|
1051
|
+
...LANE_ARGUMENTS,
|
|
1052
|
+
description: "List the open lanes: which issue, which ports, and where each one is",
|
|
1053
|
+
category: "AI tools",
|
|
1054
|
+
reference: ["", "automation", ["none"]],
|
|
1055
|
+
default_script_arguments: ["list"]
|
|
1056
|
+
},
|
|
1057
|
+
"lane:prune": {
|
|
1058
|
+
...LANE_ARGUMENTS,
|
|
1059
|
+
description: "Close every lane an interruption left without its work tree and every spent lane, then sweep unregistered leftovers under the lanes root",
|
|
1060
|
+
category: "AI tools",
|
|
1061
|
+
reference: ["", "automation", ["files", "git"]],
|
|
1062
|
+
default_script_arguments: ["prune"]
|
|
1063
|
+
},
|
|
1064
|
+
"lane:output": {
|
|
1065
|
+
...LANE_ARGUMENTS,
|
|
1066
|
+
description: "Record, or read back, where the unit running a lane\u2019s child writes",
|
|
1067
|
+
category: "AI tools",
|
|
1068
|
+
reference: ["<issue> [path]", "automation", ["files"]],
|
|
1069
|
+
default_script_arguments: ["output"]
|
|
1070
|
+
},
|
|
1071
|
+
"lane:dispatch": {
|
|
1072
|
+
...LANE_ARGUMENTS,
|
|
1073
|
+
description: "Start a lane\u2019s child as a detached process that outlives this session",
|
|
1074
|
+
category: "AI tools",
|
|
1075
|
+
reference: ["<issue> <prompt>", "automation", ["processes"]],
|
|
1076
|
+
default_script_arguments: ["dispatch"]
|
|
1077
|
+
},
|
|
1078
|
+
"lane:await": {
|
|
1079
|
+
...LANE_ARGUMENTS,
|
|
1080
|
+
description: "Block until any of the named in-flight lane children completes; prints which one finished",
|
|
1081
|
+
category: "AI tools",
|
|
1082
|
+
reference: ["<issue> [<issue>...] [--owner <pid>]", "automation", ["files", "processes"]],
|
|
1083
|
+
default_script_arguments: ["await"]
|
|
1084
|
+
},
|
|
1085
|
+
"lane:launch": {
|
|
1086
|
+
script: "scripts/lane/lane-launch-cli.ts",
|
|
1087
|
+
description: "Collapse a backlogrun lane-start event into one call: open the lane, pop and re-install on the first, dispatch the child",
|
|
1088
|
+
category: "AI tools",
|
|
1089
|
+
reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
|
|
1090
|
+
},
|
|
1091
|
+
// `.env` is read for `JOSH_LANE_ROOT`, as every lane command reads it, so the lane is found.
|
|
1092
|
+
"lane:restart": {
|
|
1093
|
+
script: "scripts/lane/lane-restart-cli.ts",
|
|
1094
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
1095
|
+
description: "Stop a running lane child, stash its uncommitted work and re-dispatch its issue in a fresh session \u2014 not counted as an outage or a failure",
|
|
1096
|
+
category: "AI tools",
|
|
1097
|
+
reference: ["<issue>", "developer", ["files", "git", "processes", "network"]]
|
|
1098
|
+
},
|
|
1099
|
+
// `.env` is read for `JOSH_LANE_ROOT`, as every lane command reads it, so the lane is found.
|
|
1100
|
+
"lane:withdraw": {
|
|
1101
|
+
script: "scripts/lane/lane-withdraw-cli.ts",
|
|
1102
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
1103
|
+
description: "Stop a running lane child, stash its uncommitted work, close its issue as not planned and close the lane \u2014 booked withdrawn, not as an outage or a failure",
|
|
1104
|
+
category: "AI tools",
|
|
1105
|
+
reference: ["<issue> --reason <text>", "developer", ["files", "git", "processes", "network"]]
|
|
1106
|
+
},
|
|
1107
|
+
// A live run's lane limit: `.env` is read so the bare form reports the
|
|
1108
|
+
// `JOSH_LANE_LIMIT` a person set there when no override stands.
|
|
1109
|
+
"lane:limit": {
|
|
1110
|
+
script: "scripts/lane/lane-limit-cli.ts",
|
|
1111
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
1112
|
+
description: "Change a live backlogrun\u2019s lane limit without stopping it, or print the limit, lanes in use and free lanes",
|
|
1113
|
+
category: "AI tools",
|
|
1114
|
+
reference: ["[<limit>] [--reset]", "developer", ["files"]]
|
|
1115
|
+
},
|
|
1116
|
+
// The lane-limit measurement: `.env` is read so `lane:stats` labels the row
|
|
1117
|
+
// with the `JOSH_LANE_LIMIT` a person set there.
|
|
1118
|
+
"lane:sample": {
|
|
1119
|
+
...MEASURE_ARGUMENTS,
|
|
1120
|
+
description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger \u2014 a backlogrun samples itself, this is for a reading outside one",
|
|
1121
|
+
category: "AI tools",
|
|
1122
|
+
reference: ["[--every <seconds>]", "maintainer", ["files"]],
|
|
1123
|
+
default_script_arguments: ["sample"]
|
|
1124
|
+
},
|
|
1125
|
+
"lane:stats": {
|
|
1126
|
+
...MEASURE_ARGUMENTS,
|
|
1127
|
+
description: "Print one table row of lane throughput, gate duration and machine load over a period, the per-stage durations of a lane under it, the wait after each ship stop reason under those, and the duration and reuse count of each gate check last",
|
|
1128
|
+
category: "AI tools",
|
|
1129
|
+
reference: ["--period <days> [--limit <lane-limit>]", "maintainer", ["none"]],
|
|
1130
|
+
default_script_arguments: ["stats"]
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1133
|
+
|
|
1134
|
+
// scripts/josh/josh-commands-run.ts
|
|
1135
|
+
var RUN_HOLD_SCRIPT = "scripts/run/hold/run-hold-cli.ts";
|
|
1136
|
+
var RUN_COMMANDS = {
|
|
1137
|
+
"run:hold": {
|
|
1138
|
+
script: RUN_HOLD_SCRIPT,
|
|
1139
|
+
description: "Claim this working tree for a run, or say which run already holds it",
|
|
1140
|
+
category: "AI tools",
|
|
1141
|
+
reference: ["[<issue> [--fullrun | --halfrun-stop | --prrun-stop]]", "automation", ["files"]]
|
|
1142
|
+
},
|
|
1143
|
+
"run:release": {
|
|
1144
|
+
script: RUN_HOLD_SCRIPT,
|
|
1145
|
+
description: "Release this working tree's run record",
|
|
1146
|
+
category: "AI tools",
|
|
1147
|
+
reference: ["[issue|--force]", "automation", ["files"]],
|
|
1148
|
+
default_script_arguments: ["--release"]
|
|
1149
|
+
},
|
|
1150
|
+
"run:tidy": {
|
|
1151
|
+
script: "scripts/run/tidy/run-tidy-cli.ts",
|
|
1152
|
+
description: "Close merged lanes and drop stashes whose issues are all merged",
|
|
1153
|
+
category: "AI tools",
|
|
1154
|
+
reference: ["", "automation", ["git", "network", "files"]]
|
|
1155
|
+
},
|
|
1156
|
+
"run:carry": {
|
|
1157
|
+
script: "scripts/run/carry/run-carry-cli.ts",
|
|
1158
|
+
// `--stopped` sends the stop confirmation, so the Telegram credentials come from `.env` as for
|
|
1159
|
+
// `run:wake` below.
|
|
1160
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
1161
|
+
description: "Carry one invocation\u2019s budget across its own session cuts",
|
|
1162
|
+
category: "AI tools",
|
|
1163
|
+
reference: ["<operation> [arguments...]", "automation", ["files"]]
|
|
1164
|
+
},
|
|
1165
|
+
"run:add": {
|
|
1166
|
+
script: "scripts/run/add/run-add-cli.ts",
|
|
1167
|
+
description: "Add issues to a live backlogrun, ahead of the queue unless --no-priority",
|
|
1168
|
+
category: "AI tools",
|
|
1169
|
+
reference: ["<issue...> [--no-priority]", "automation", ["network", "files"]]
|
|
1170
|
+
},
|
|
1171
|
+
"run:wake": {
|
|
1172
|
+
script: "scripts/run/wake/run-wake-cli.ts",
|
|
1173
|
+
// `.env` rather than the ambient environment:
|
|
1174
|
+
// the failure warning needs the Telegram credentials, the same
|
|
1175
|
+
// reasons `notify` and `followup` carry these flags.
|
|
1176
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
1177
|
+
description: "Wake the next session of a cut backlogrun from outside the conversation",
|
|
1178
|
+
category: "AI tools",
|
|
1179
|
+
reference: ["[options]", "automation", ["processes", "notifications"]]
|
|
1180
|
+
},
|
|
1181
|
+
"run:cut": {
|
|
1182
|
+
script: "scripts/run/cut/run-cut-cli.ts",
|
|
1183
|
+
description: "Cut a lane child before the gate and resume a fresh process",
|
|
1184
|
+
category: "AI tools",
|
|
1185
|
+
reference: ["[--resume] <issue> [--impl] [--handoff <path>]", "automation", ["files"]]
|
|
1186
|
+
},
|
|
1187
|
+
"run:liveness": {
|
|
1188
|
+
script: "scripts/run/run-liveness-cli.ts",
|
|
1189
|
+
description: "Say whether a delegated unit is still working, or stopped without reporting",
|
|
1190
|
+
category: "AI tools",
|
|
1191
|
+
reference: ["<issue> --output <path> [options]", "automation", ["processes"]]
|
|
1192
|
+
},
|
|
1193
|
+
"run:ending": {
|
|
1194
|
+
script: "scripts/run/run-ending-cli.ts",
|
|
1195
|
+
description: "Classify how a dispatched lane child ended (merged, cut, abandoned, unreadable)",
|
|
1196
|
+
category: "AI tools",
|
|
1197
|
+
reference: ["<issue> --output <path> [--repo <owner/repo>]", "automation", ["network"]]
|
|
1198
|
+
},
|
|
1199
|
+
"run:progress": {
|
|
1200
|
+
script: "scripts/run/progress/run-progress-cli.ts",
|
|
1201
|
+
description: "Report an unattended run\u2019s progress once it has gone quiet for an interval",
|
|
1202
|
+
category: "AI tools",
|
|
1203
|
+
reference: [
|
|
1204
|
+
"[--once | --wait] [--interval <minutes>] [--hours <hours>] [--repo <owner/repo>] [--output <path>] | --mark | --path",
|
|
1205
|
+
"automation",
|
|
1206
|
+
["files"]
|
|
1207
|
+
]
|
|
1208
|
+
},
|
|
1209
|
+
"run:board": {
|
|
1210
|
+
script: "scripts/run/board/run-board-cli.ts",
|
|
1211
|
+
// `--every` pushes its frame as a Telegram, so the credentials come from `.env` as for `run:carry`.
|
|
1212
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
1213
|
+
description: "Draw a live board of the running backlogrun, redrawn every second",
|
|
1214
|
+
category: "AI tools",
|
|
1215
|
+
reference: ["[--once | --chat | --every <minutes>]", "automation", ["files", "network"]]
|
|
1216
|
+
},
|
|
1217
|
+
"run:prep": {
|
|
1218
|
+
script: "scripts/run/run-prep-cli.ts",
|
|
1219
|
+
description: "Bundle a run\u2019s pre-edit reads: body, comments, state, dependency scope",
|
|
1220
|
+
category: "AI tools",
|
|
1221
|
+
reference: ["<issue>", "automation", ["network"]]
|
|
1222
|
+
},
|
|
1223
|
+
// The entry sequence a lane opened on, folded into one call: claim the tree,
|
|
1224
|
+
// read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
|
|
1225
|
+
// `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
|
|
1226
|
+
"run:entry": {
|
|
1227
|
+
script: "scripts/run/entry/run-entry-cli.ts",
|
|
1228
|
+
// A `busy` hold or an `over` budget sends the stop confirmation.
|
|
1229
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
1230
|
+
description: "Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step",
|
|
1231
|
+
category: "AI tools",
|
|
1232
|
+
reference: ["<issue> [--to <command>]", "automation", ["git", "network", "files"]]
|
|
1233
|
+
},
|
|
1234
|
+
"run:status": {
|
|
1235
|
+
script: "scripts/run/run-status-cli.ts",
|
|
1236
|
+
description: "Bundle a run\u2019s read-only status: issue state, cost verdict, carry counters",
|
|
1237
|
+
category: "AI tools",
|
|
1238
|
+
reference: ["<issue> [--repo <owner/repo>]", "automation", ["network"]]
|
|
1239
|
+
},
|
|
1240
|
+
"run:next": {
|
|
1241
|
+
script: "scripts/run/run-next-cli.ts",
|
|
1242
|
+
description: "Print the next step a fullrun takes, computed from the run\u2019s state",
|
|
1243
|
+
category: "AI tools",
|
|
1244
|
+
reference: ["<issue>", "automation", ["network"]]
|
|
1245
|
+
},
|
|
1246
|
+
"run:step": {
|
|
1247
|
+
script: "scripts/run/run-step-cli.ts",
|
|
1248
|
+
description: "Print the run\u2019s next single action, computed from the event stream, carry record and issue state",
|
|
1249
|
+
category: "AI tools",
|
|
1250
|
+
reference: ["[<issue>]", "automation", ["network", "files"]]
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
|
|
1254
|
+
// scripts/josh/josh-commands-split.ts
|
|
1255
|
+
var SPLIT_COMMANDS = {
|
|
1256
|
+
"split:assess": {
|
|
1257
|
+
script: "scripts/split/split-assess-cli.ts",
|
|
1258
|
+
description: "Measure the branch change size (tests excluded) and answer the split assessment size question: split | single",
|
|
1259
|
+
category: "AI tools",
|
|
1260
|
+
reference: ["[--json]", "automation", ["none"]]
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
|
|
1264
|
+
// scripts/josh/josh-commands-ai.ts
|
|
1265
|
+
var ISSUE_WITH_OPTIONS2 = "<issue> [options]";
|
|
1266
|
+
var AI_COMMANDS = {
|
|
1267
|
+
...ISSUE_COMMANDS,
|
|
1268
|
+
"pkg:scout": {
|
|
1269
|
+
script: "scripts/package/package-scout-cli.ts",
|
|
1270
|
+
description: "Rank package candidates by measured metrics so the Package-First tier decision is read, not judged",
|
|
1271
|
+
category: "AI tools",
|
|
1272
|
+
reference: ["<keywords> [--size <n>]", "automation", ["network"]]
|
|
1273
|
+
},
|
|
1274
|
+
"stash:pop": {
|
|
1275
|
+
script: "scripts/git/stash/stash-pop-cli.ts",
|
|
1276
|
+
description: "Pop the stash matching this message, not whichever a shared stack has on top",
|
|
1277
|
+
category: "AI tools",
|
|
1278
|
+
reference: ["<message>", "automation", ["git"]]
|
|
1279
|
+
},
|
|
1280
|
+
epic: {
|
|
1281
|
+
script: "scripts/epic/epic.ts",
|
|
1282
|
+
description: "Create an epic issue from its child issue numbers",
|
|
1283
|
+
category: "AI tools",
|
|
1284
|
+
reference: ["<title> <issue...> [--ordered]", "automation", ["network"]]
|
|
1285
|
+
},
|
|
1286
|
+
"epic:next": {
|
|
1287
|
+
script: "scripts/epic/epic-next.ts",
|
|
1288
|
+
description: "List an epic's runnable children, bundled per repository",
|
|
1289
|
+
category: "AI tools",
|
|
1290
|
+
reference: ["<epic>... [--repo <owner/repo>] [--lanes]", "automation", ["network"]]
|
|
1291
|
+
},
|
|
1292
|
+
"epic:bundle": {
|
|
1293
|
+
script: "scripts/epic/epic-bundle-cli.ts",
|
|
1294
|
+
description: "Say whether a newly filed issue belongs with ones already in the backlog",
|
|
1295
|
+
category: "AI tools",
|
|
1296
|
+
reference: ["<issue>", "automation", ["network"]]
|
|
1297
|
+
},
|
|
1298
|
+
"epic:audit": {
|
|
1299
|
+
script: "scripts/epic/epic-audit-cli.ts",
|
|
1300
|
+
description: "Audit an epic's children against each other for contradictions",
|
|
1301
|
+
category: "AI tools",
|
|
1302
|
+
reference: ["<epic>", "automation", ["network"]]
|
|
1303
|
+
},
|
|
1304
|
+
"epic:check": {
|
|
1305
|
+
script: "scripts/epic/epic-check.ts",
|
|
1306
|
+
description: "Check an epic issue against the tracking requirements",
|
|
1307
|
+
category: "AI tools",
|
|
1308
|
+
reference: ["<epic>", "automation", ["network"]]
|
|
1309
|
+
},
|
|
1310
|
+
"auto-ok:next": {
|
|
1311
|
+
script: "scripts/auto-ok/auto-ok-cli.ts",
|
|
1312
|
+
description: "Print the next opted-in issue an unattended run may pick up outside an epic",
|
|
1313
|
+
category: "AI tools",
|
|
1314
|
+
reference: ["[--exclude <n>[,<n>...]] [--label <name>]", "automation", ["network"]]
|
|
1315
|
+
},
|
|
1316
|
+
"auto-ok:judge": {
|
|
1317
|
+
script: "scripts/auto-ok/auto-ok-judge-cli.ts",
|
|
1318
|
+
description: "List the open issues backlogrun owes an auto-ok judgement, or record one (--apply / --decline)",
|
|
1319
|
+
category: "AI tools",
|
|
1320
|
+
reference: [
|
|
1321
|
+
"[--apply <n> (--lane | --solo) | --decline <n> --reason <text>]",
|
|
1322
|
+
"automation",
|
|
1323
|
+
["network"]
|
|
1324
|
+
]
|
|
1325
|
+
},
|
|
1326
|
+
...BACKLOG_COMMANDS,
|
|
1327
|
+
cost: {
|
|
1328
|
+
script: "scripts/cost-runtime/cost-cli.ts",
|
|
1329
|
+
description: "Say whether the next turn of a run crosses the context-cut threshold (--cut) or a given tokens-per-request figure (--over)",
|
|
1330
|
+
category: "AI tools",
|
|
1331
|
+
reference: ["(--cut | --over <tokens-per-request>) [--path <dir>]", "automation", ["none"]]
|
|
1332
|
+
},
|
|
1333
|
+
"cost:audit": {
|
|
1334
|
+
script: "scripts/cost-audit/cost-audit-cli.ts",
|
|
1335
|
+
description: "Report AI cost over a period by session kind, tool category and guard, with cost per merge and regressions against the period before",
|
|
1336
|
+
category: "AI tools",
|
|
1337
|
+
reference: ["[--period <days>]", "maintainer", ["none"]],
|
|
1338
|
+
// Kit-only: it reads kit's own transcript store, like `josh retrospective`, which carries its
|
|
1339
|
+
// summary line.
|
|
1340
|
+
is_kit_only: true
|
|
1341
|
+
},
|
|
1342
|
+
...DOCUMENT_COMMANDS,
|
|
1343
|
+
time: {
|
|
1344
|
+
script: "scripts/time/time-cli.ts",
|
|
1345
|
+
description: "Report where a run's wall clock went: model wait, tool execution, human wait",
|
|
1346
|
+
category: "AI tools",
|
|
1347
|
+
reference: ["[options]", "maintainer", ["none"]],
|
|
1348
|
+
// Kit-only: it measures kit's own development runs and its report modules live under the
|
|
1349
|
+
// undistributed `scripts/time/`, so it means nothing in a consumer project and is dropped from a
|
|
1350
|
+
// consumer's help. The runtime analysis hooks and guards rely on stays
|
|
1351
|
+
// distributed under `scripts/time-runtime/`.
|
|
1352
|
+
is_kit_only: true
|
|
1353
|
+
},
|
|
1354
|
+
// The tool-calls-per-round-trip density the batching guard is measured on, aggregated across the
|
|
1355
|
+
// recent lane sessions. Kit-only for the same reason `time` is: it reads
|
|
1356
|
+
// kit's own lane transcripts and means nothing in a consumer project.
|
|
1357
|
+
"time:density": {
|
|
1358
|
+
script: "scripts/time/time-density-cli.ts",
|
|
1359
|
+
description: "Report tool calls per round trip across the recent lane sessions",
|
|
1360
|
+
category: "AI tools",
|
|
1361
|
+
reference: ["[--lanes <n>] [--path <dir>]", "maintainer", ["none"]],
|
|
1362
|
+
is_kit_only: true
|
|
1363
|
+
},
|
|
1364
|
+
retrospective: {
|
|
1365
|
+
script: "scripts/retrospective/retrospective-cli.ts",
|
|
1366
|
+
description: "Aggregate a finished run's cost, review findings, observation ledger and events into one digest",
|
|
1367
|
+
category: "AI tools",
|
|
1368
|
+
reference: ["", "maintainer", ["none"]],
|
|
1369
|
+
core_weight: core_budget.CORE_WEIGHTS.retrospective,
|
|
1370
|
+
memory_mb: core_budget.MEMORY_MB.retrospective,
|
|
1371
|
+
// Kit-only: it reads kit's own development run — the transcript store, the review ledger and the
|
|
1372
|
+
// run event stream — so it means nothing in a consumer project and is dropped from a consumer's
|
|
1373
|
+
// help, through the same declaration `josh time` uses for the same reason.
|
|
1374
|
+
is_kit_only: true
|
|
1375
|
+
},
|
|
1376
|
+
"review:brief": {
|
|
1377
|
+
script: "scripts/review/review-brief-cli.ts",
|
|
1378
|
+
description: "Print the whole /code-review invocation: level, what the gate already proved, target (--level-only for the level alone)",
|
|
1379
|
+
category: "AI tools",
|
|
1380
|
+
reference: ["[--round <1|2>] | --level-only [--staged] [--json]", "automation", ["files"]]
|
|
1381
|
+
},
|
|
1382
|
+
"review:attest": {
|
|
1383
|
+
script: "scripts/review/review-attest-cli.ts",
|
|
1384
|
+
description: "Record, or verify, which checkout a /code-review actually read",
|
|
1385
|
+
category: "AI tools",
|
|
1386
|
+
reference: ["<nonce> | --check", "automation", ["files"]]
|
|
1387
|
+
},
|
|
1388
|
+
"review:round2": {
|
|
1389
|
+
script: "scripts/review/review-round2-cli.ts",
|
|
1390
|
+
description: "Say whether the second /code-review round is due, or may be skipped entirely",
|
|
1391
|
+
category: "AI tools",
|
|
1392
|
+
reference: ["[--round-1-closed] [--json]", "automation", ["none"]]
|
|
1393
|
+
},
|
|
1394
|
+
delegate: {
|
|
1395
|
+
script: "scripts/delegation/delegation-cli.ts",
|
|
1396
|
+
description: "Say whether a run step may go to a cheaper execution tier",
|
|
1397
|
+
category: "AI tools",
|
|
1398
|
+
reference: ["<step> | --list", "automation", ["none"]]
|
|
1399
|
+
},
|
|
1400
|
+
fanout: {
|
|
1401
|
+
script: "scripts/delegation/fanout-cli.ts",
|
|
1402
|
+
description: "Say whether proposed implementation units are file-disjoint, so they may run in parallel",
|
|
1403
|
+
category: "AI tools",
|
|
1404
|
+
reference: ["<unit-files> <unit-files> [<unit-files> \u2026]", "automation", ["none"]]
|
|
1405
|
+
},
|
|
1406
|
+
...RUN_COMMANDS,
|
|
1407
|
+
"repo:party": {
|
|
1408
|
+
script: "scripts/discovery/repo-party-cli.ts",
|
|
1409
|
+
description: "Say whether a repository is first-party or third-party by owner equality (computed, not judged)",
|
|
1410
|
+
category: "AI tools",
|
|
1411
|
+
reference: ["[<owner/repo>]", "automation", ["none"]]
|
|
1412
|
+
},
|
|
1413
|
+
"run:merge": {
|
|
1414
|
+
script: "scripts/run/merge/run-merge-cli.ts",
|
|
1415
|
+
description: "Collapse a backlogrun merge event into one call: confirm the child, do the post-merge steps, offer the next child",
|
|
1416
|
+
category: "AI tools",
|
|
1417
|
+
reference: [ISSUE_WITH_OPTIONS2, "automation", ["git", "network"]]
|
|
1418
|
+
},
|
|
1419
|
+
"run:review": {
|
|
1420
|
+
script: "scripts/run/review/run-review-cli.ts",
|
|
1421
|
+
description: "Start the gate in the background and print the /code-review brief in one call so the two overlap (--join to join the gate and check its verdict)",
|
|
1422
|
+
category: "AI tools",
|
|
1423
|
+
reference: ["[--join]", "automation", ["processes", "files"]]
|
|
1424
|
+
},
|
|
1425
|
+
// The post-merge sequence a run closed on, folded into one call: commit the
|
|
1426
|
+
// observation ledger, read the completion citations and decide the release scope. `observations:flush`,
|
|
1427
|
+
// `issue:cite` and `release:scope` were three round trips re-billing the run's full context each.
|
|
1428
|
+
"run:tail": {
|
|
1429
|
+
script: "scripts/run/run-tail-cli.ts",
|
|
1430
|
+
description: "Close a run in one call: return to the default branch, commit the observation ledger, read the citations, decide the release scope",
|
|
1431
|
+
category: "AI tools",
|
|
1432
|
+
reference: ["[<issue> ...]", "automation", ["git", "network"]]
|
|
1433
|
+
},
|
|
1434
|
+
// The commit-to-report region a run ships a change on, folded into one call:
|
|
1435
|
+
// the gate, the commit/push/PR (`git -y`), the CI-wait merge (`followup`) and the report bookkeeping
|
|
1436
|
+
// (`run:tail`) were four round trips re-billing the run's full context each. It stops at the first
|
|
1437
|
+
// failed step and names it, so the run reads only the step to fix.
|
|
1438
|
+
ship: {
|
|
1439
|
+
script: "scripts/run/ship/run-ship-cli.ts",
|
|
1440
|
+
description: "Ship a change in one call: gate, commit/push/PR, the CI-wait merge and the report bookkeeping, stopping at the first failed step",
|
|
1441
|
+
category: "AI tools",
|
|
1442
|
+
reference: [
|
|
1443
|
+
'"<title> #<N>" [<follow-up-N> ...] [--cite <N>] [--review] [--detach] [--body-file <path>] [--notify-message <text> | --notify-message-file <path>] | --log <N>',
|
|
1444
|
+
"automation",
|
|
1445
|
+
["git", "network"]
|
|
1446
|
+
]
|
|
1447
|
+
},
|
|
1448
|
+
"run:event": {
|
|
1449
|
+
script: "scripts/run/event/run-event-cli.ts",
|
|
1450
|
+
description: "Append to, read or watch the run\u2019s append-only event stream (--append <kind> <text> | --from|--follow <n> | --watch [<n>] | --last)",
|
|
1451
|
+
category: "AI tools",
|
|
1452
|
+
reference: [
|
|
1453
|
+
"--append <kind> <text> | --from|--follow <n> | --watch [<n>] | --last",
|
|
1454
|
+
"automation",
|
|
1455
|
+
["files"]
|
|
1456
|
+
]
|
|
1457
|
+
},
|
|
1458
|
+
"run:report": {
|
|
1459
|
+
script: "scripts/run/run-report-cli.ts",
|
|
1460
|
+
description: "Generate the session-facing report for this invocation from the run\u2019s event stream (merges, parks, cuts) with the release tail \u2014 the same text josh notify sends",
|
|
1461
|
+
category: "AI tools",
|
|
1462
|
+
reference: ["", "automation", ["files", "network"]]
|
|
1463
|
+
},
|
|
1464
|
+
...LANE_COMMANDS,
|
|
1465
|
+
...GUARD_COMMANDS,
|
|
1466
|
+
"run:watcher:guard": {
|
|
1467
|
+
script: "scripts/run/run-watcher-guard-cli.ts",
|
|
1468
|
+
description: "Guard: exits non-zero when lane children are in-flight but the watcher has not pinged recently",
|
|
1469
|
+
category: "AI tools",
|
|
1470
|
+
reference: ["", "automation", ["none"]]
|
|
1471
|
+
},
|
|
1472
|
+
"run:stranded": {
|
|
1473
|
+
script: "scripts/run/run-stranded-cli.ts",
|
|
1474
|
+
// `.env` rather than the ambient environment: the strand notification needs the Telegram
|
|
1475
|
+
// credentials, the same reason `run:wake` carries these flags.
|
|
1476
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
1477
|
+
description: "Report whether the run is stranded \u2014 owner gone, no successor holding the budget, and no supervisor watching",
|
|
1478
|
+
category: "AI tools",
|
|
1479
|
+
reference: ["", "automation", ["processes", "notifications"]]
|
|
1480
|
+
},
|
|
1481
|
+
...SPLIT_COMMANDS,
|
|
1482
|
+
"oracle:list": {
|
|
1483
|
+
script: "scripts/rules/oracle-list-cli.ts",
|
|
1484
|
+
description: "Print the decision oracles \u2014 commands that answer a rule question mechanically",
|
|
1485
|
+
category: "AI tools",
|
|
1486
|
+
reference: ["", "automation", ["none"]]
|
|
1487
|
+
},
|
|
1488
|
+
eval: {
|
|
1489
|
+
script: "scripts/eval/eval-run.ts",
|
|
1490
|
+
description: "Run the agent rule-compliance scenarios (real Claude sessions)",
|
|
1491
|
+
category: "AI tools",
|
|
1492
|
+
reference: ["[scenario...]", "maintainer", ["processes", "network"]],
|
|
1493
|
+
// Kit-only: it replays kit's own distributed rules against real Claude sessions, so it means
|
|
1494
|
+
// nothing in a consumer project and is dropped from a consumer's help.
|
|
1495
|
+
is_kit_only: true
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
|
|
1499
|
+
// scripts/josh/josh-commands-clone.ts
|
|
1500
|
+
var CLONE_COMMANDS = {
|
|
1501
|
+
"clone:scan": {
|
|
1502
|
+
script: "scripts/clone/clone-scan-cli.ts",
|
|
1503
|
+
description: "Count code duplication across files and first-party repositories, printing each clone as file:line pairs",
|
|
1504
|
+
category: "AI tools",
|
|
1505
|
+
reference: ["", "automation", ["files"]]
|
|
1304
1506
|
}
|
|
1305
|
-
}
|
|
1306
|
-
async function with_command_reservation(weight, run, options = {}) {
|
|
1307
|
-
if (is_held() || unit_worker_share.is_nested_run()) return await run();
|
|
1308
|
-
return await with_core_reservation(weight, async () => await with_held_mark(run), options);
|
|
1309
|
-
}
|
|
1310
|
-
var core_budget = {
|
|
1311
|
-
CORE_WEIGHTS,
|
|
1312
|
-
HELD_KEY,
|
|
1313
|
-
HELD_VALUE,
|
|
1314
|
-
MEMORY_MB,
|
|
1315
|
-
RESERVED_PREFIX,
|
|
1316
|
-
admitted_keys: core_admission.admitted_keys,
|
|
1317
|
-
admitted_load: core_admission.admitted_load,
|
|
1318
|
-
describe_overflow: core_admission.describe_overflow,
|
|
1319
|
-
is_held,
|
|
1320
|
-
live_reservations,
|
|
1321
|
-
release,
|
|
1322
|
-
reserve,
|
|
1323
|
-
with_command_reservation,
|
|
1324
|
-
with_core_reservation,
|
|
1325
|
-
with_held_mark
|
|
1326
1507
|
};
|
|
1327
1508
|
|
|
1328
1509
|
// scripts/gate/gate-plan.ts
|
|
@@ -1388,6 +1569,7 @@ var TYPE_CHECK_LABEL = "check";
|
|
|
1388
1569
|
var UNIT_LABEL = "test:unit";
|
|
1389
1570
|
var BEHAVIOR_LABEL = "behavior";
|
|
1390
1571
|
var METRICS_LABEL = "metrics";
|
|
1572
|
+
var EXPORTS_LABEL = "exports";
|
|
1391
1573
|
var WARNING_CHECKER_LABELS = [LINT_LABEL, TYPE_CHECK_LABEL];
|
|
1392
1574
|
var STATIC_CHECKS = [
|
|
1393
1575
|
{
|
|
@@ -1413,7 +1595,7 @@ var STATIC_CHECKS = [
|
|
|
1413
1595
|
// program and walks it for about 5s, and it is over well before lint and the type check. A
|
|
1414
1596
|
// reservation would only take a place from the four-core CI runner's fan-out and a worker from the
|
|
1415
1597
|
// unit suite for the whole gate.
|
|
1416
|
-
{ label:
|
|
1598
|
+
{ label: EXPORTS_LABEL, target: "exports:unused", reserved_cores: 0 },
|
|
1417
1599
|
// **The metrics ratchet is kit's own**: it holds kit's repository-wide
|
|
1418
1600
|
// totals to the merge-base's. It is one in-process eslint pass with only `max-lines` enabled, over
|
|
1419
1601
|
// in a few seconds, so it reserves no core for the reason the unused-member check above does not.
|
|
@@ -1502,6 +1684,15 @@ function resolve_gate_plan(available_cores = availableParallelism4(), concurrent
|
|
|
1502
1684
|
unit_worker_cap: unit_cap_for(checks, available_cores, concurrent_runs)
|
|
1503
1685
|
};
|
|
1504
1686
|
}
|
|
1687
|
+
function bound_by_free(plan, available_cores, free_cores) {
|
|
1688
|
+
if (!has_unit_check(plan.checks)) return plan;
|
|
1689
|
+
const unit_worker_cap = unit_worker_share.cap_to_free(
|
|
1690
|
+
plan.unit_worker_cap,
|
|
1691
|
+
free_cores,
|
|
1692
|
+
available_cores
|
|
1693
|
+
);
|
|
1694
|
+
return { ...plan, unit_worker_cap };
|
|
1695
|
+
}
|
|
1505
1696
|
function format_machine(available_cores, concurrent_runs) {
|
|
1506
1697
|
const cores = `${String(available_cores)} cores`;
|
|
1507
1698
|
if (concurrent_runs <= unit_worker_share.SOLO_RUNS) return cores;
|
|
@@ -1520,6 +1711,7 @@ function format_gate_plan(plan, available_cores = availableParallelism4(), concu
|
|
|
1520
1711
|
return `${josh_verdict.GATE_OPENING_PREFIX}${width}, ${cap} (${machine})`;
|
|
1521
1712
|
}
|
|
1522
1713
|
var gate_plan = {
|
|
1714
|
+
EXPORTS_LABEL,
|
|
1523
1715
|
GATE_CHECKS,
|
|
1524
1716
|
LINT_LABEL,
|
|
1525
1717
|
MEASURED_CORES,
|
|
@@ -1529,6 +1721,7 @@ var gate_plan = {
|
|
|
1529
1721
|
TYPE_CHECK_LABEL,
|
|
1530
1722
|
UNIT_LABEL,
|
|
1531
1723
|
WARNING_CHECKER_LABELS,
|
|
1724
|
+
bound_by_free,
|
|
1532
1725
|
check_memory,
|
|
1533
1726
|
check_weight,
|
|
1534
1727
|
direct_unit_memory,
|
|
@@ -1661,7 +1854,7 @@ var DEV_COMMANDS = {
|
|
|
1661
1854
|
},
|
|
1662
1855
|
"stop:guard": {
|
|
1663
1856
|
script: "scripts/hooks/stop-guard.ts",
|
|
1664
|
-
description: "Claude Code Stop hook:
|
|
1857
|
+
description: "Claude Code Stop hook: send the hold notify, release the hold and print the issue citations itself; block on the rules that need the model (reads the Stop payload on stdin)",
|
|
1665
1858
|
category: "Development",
|
|
1666
1859
|
reference: ["", "automation", ["none"]]
|
|
1667
1860
|
// **No `tsx_arguments`, deliberately**, the same as `pretool:guard` above: this runs at every
|
|
@@ -1795,6 +1988,12 @@ var HOOKS_COMMANDS = {
|
|
|
1795
1988
|
category: "Git hooks",
|
|
1796
1989
|
reference: ["[paths...]", "automation", ["none"]]
|
|
1797
1990
|
},
|
|
1991
|
+
"pre-commit-lint": {
|
|
1992
|
+
script: "scripts/hooks/pre-commit-lint.ts",
|
|
1993
|
+
description: "Git hook: run cspell, prettier or eslint over staged files from a content cache",
|
|
1994
|
+
category: "Git hooks",
|
|
1995
|
+
reference: ["<cspell|prettier|eslint> [paths...]", "automation", ["files"]]
|
|
1996
|
+
},
|
|
1798
1997
|
"pre-push-unit": {
|
|
1799
1998
|
script: "scripts/hooks/pre-push-unit.ts",
|
|
1800
1999
|
description: "Git hook: run unit tests, reusing a green gate recorded on the pushed tree",
|
|
@@ -2200,6 +2399,11 @@ var WORKFLOW_COMMANDS = {
|
|
|
2200
2399
|
// A script rather than an `sh -c` chain, because the strategy has to be named rather than left to
|
|
2201
2400
|
// the caller's git configuration: a bare `git pull` aborts with `Need to specify how to reconcile
|
|
2202
2401
|
// divergent branches` on exactly the diverged branch the command exists for.
|
|
2402
|
+
//
|
|
2403
|
+
// **It declares no core weight, by measurement** (joshuafolkken/kit#3944): its own work is git, and
|
|
2404
|
+
// the catalog it may regenerate took 0.6s of CPU. The heavy processes seen beside it are commit
|
|
2405
|
+
// hooks — its regenerated catalog's commit runs them — which reserve themselves, and a weight here
|
|
2406
|
+
// would set the held mark they inherit, folding the parallel hook tools into this one place.
|
|
2203
2407
|
"main:merge": {
|
|
2204
2408
|
script: "scripts/git/main-merge.ts",
|
|
2205
2409
|
description: "Merge origin default branch into the current branch",
|
|
@@ -2266,6 +2470,7 @@ var ALIASES = {
|
|
|
2266
2470
|
tm: "time",
|
|
2267
2471
|
tmd: "time:density",
|
|
2268
2472
|
rtr: "retrospective",
|
|
2473
|
+
ca: "cost:audit",
|
|
2269
2474
|
rvf: "review:findings",
|
|
2270
2475
|
ruv: "rule:value",
|
|
2271
2476
|
ev: "eval",
|
|
@@ -2275,6 +2480,7 @@ var ALIASES = {
|
|
|
2275
2480
|
lst: "lane:stats",
|
|
2276
2481
|
lli: "lane:limit",
|
|
2277
2482
|
lrs: "lane:restart",
|
|
2483
|
+
lwd: "lane:withdraw",
|
|
2278
2484
|
blr: "backlogrun"
|
|
2279
2485
|
};
|
|
2280
2486
|
function canonical_command(name) {
|
|
@@ -2287,7 +2493,7 @@ var BASH_SEPARATOR = ": ";
|
|
|
2287
2493
|
var WHITESPACE_PATTERN = /\s+/u;
|
|
2288
2494
|
var SEGMENT_PATTERN = /&&|\|\||;|\|/u;
|
|
2289
2495
|
var PIPE_PATTERN = /(?<!\|)\|(?!\|)/u;
|
|
2290
|
-
var CHAIN_PATTERN =
|
|
2496
|
+
var CHAIN_PATTERN = /&&|\|\||;|\n/u;
|
|
2291
2497
|
var QUOTED_SPAN_PATTERN = /\\[\s\S]|'[^']*'|"(?:\\[\s\S]|[^"\\])*"/gu;
|
|
2292
2498
|
var HEREDOC_MARKER = /(?<!<)<<-?\s*(['"]?)(\w+)\1/u;
|
|
2293
2499
|
var HEREDOC_DELIMITER_GROUP = 2;
|
|
@@ -2345,6 +2551,10 @@ function without_heredoc_bodies(command) {
|
|
|
2345
2551
|
function unquoted(command) {
|
|
2346
2552
|
return without_heredoc_bodies(command).replaceAll(QUOTED_SPAN_PATTERN, " ");
|
|
2347
2553
|
}
|
|
2554
|
+
function blanked(command) {
|
|
2555
|
+
if (HEREDOC_MARKER.test(command)) return void 0;
|
|
2556
|
+
return command.replaceAll(QUOTED_SPAN_PATTERN, (span) => " ".repeat(span.length));
|
|
2557
|
+
}
|
|
2348
2558
|
function discarded_commands(command) {
|
|
2349
2559
|
const plain = unquoted(command);
|
|
2350
2560
|
if (PIPEFAIL_PATTERN.test(plain)) return [];
|
|
@@ -2381,22 +2591,35 @@ function drop_redirections(words) {
|
|
|
2381
2591
|
}
|
|
2382
2592
|
return kept;
|
|
2383
2593
|
}
|
|
2384
|
-
function
|
|
2385
|
-
const text = command_words(
|
|
2594
|
+
function josh_arguments_of_segment(segment) {
|
|
2595
|
+
const text = command_words(segment).join(" ");
|
|
2386
2596
|
const match = JOSH_PATTERN.exec(text);
|
|
2387
2597
|
if (match === null) return [];
|
|
2388
2598
|
const words = text.slice(match[0].length).split(WHITESPACE_PATTERN).filter((word) => word !== "");
|
|
2389
2599
|
return drop_redirections(words);
|
|
2390
2600
|
}
|
|
2601
|
+
function josh_arguments(command) {
|
|
2602
|
+
return josh_arguments_of_segment(command_segment(command));
|
|
2603
|
+
}
|
|
2604
|
+
function josh_signature_of_segment(segment) {
|
|
2605
|
+
const name = josh_command_of_segment(segment);
|
|
2606
|
+
if (name === "") return "";
|
|
2607
|
+
return [name, ...josh_arguments_of_segment(segment)].join(" ");
|
|
2608
|
+
}
|
|
2609
|
+
function josh_signatures_of(command) {
|
|
2610
|
+
return unquoted(command).split(SEGMENT_PATTERN).map((segment) => josh_signature_of_segment(segment)).filter((signature) => signature !== "");
|
|
2611
|
+
}
|
|
2391
2612
|
var time_shell = {
|
|
2392
2613
|
JOSH_PREFIX,
|
|
2393
2614
|
bash_command,
|
|
2394
2615
|
bash_label,
|
|
2616
|
+
blanked,
|
|
2395
2617
|
command_segment,
|
|
2396
2618
|
discarded_commands,
|
|
2397
2619
|
josh_arguments,
|
|
2398
2620
|
josh_command_of,
|
|
2399
2621
|
josh_commands_of,
|
|
2622
|
+
josh_signatures_of,
|
|
2400
2623
|
leading_word,
|
|
2401
2624
|
unquoted
|
|
2402
2625
|
};
|
|
@@ -2497,78 +2720,6 @@ var time_background = {
|
|
|
2497
2720
|
unread_phases
|
|
2498
2721
|
};
|
|
2499
2722
|
|
|
2500
|
-
// scripts/git/git-schemas.ts
|
|
2501
|
-
import { z as z3 } from "zod";
|
|
2502
|
-
var package_name_schema = z3.object({ name: z3.string().min(1) });
|
|
2503
|
-
var rollup_item_schema = z3.looseObject({
|
|
2504
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention -- GraphQL field name from GitHub API
|
|
2505
|
-
__typename: z3.string().optional(),
|
|
2506
|
-
state: z3.string().optional(),
|
|
2507
|
-
status: z3.string().optional(),
|
|
2508
|
-
conclusion: z3.string().optional(),
|
|
2509
|
-
name: z3.string().optional(),
|
|
2510
|
-
context: z3.string().optional(),
|
|
2511
|
-
description: z3.string().nullish()
|
|
2512
|
-
});
|
|
2513
|
-
var pr_raw_schema = z3.object({
|
|
2514
|
-
statusCheckRollup: z3.array(rollup_item_schema).optional(),
|
|
2515
|
-
mergeStateStatus: z3.string().optional(),
|
|
2516
|
-
reviewDecision: z3.string().optional()
|
|
2517
|
-
});
|
|
2518
|
-
var pull_comment_schema = z3.object({
|
|
2519
|
-
body: z3.string().optional(),
|
|
2520
|
-
html_url: z3.string().optional(),
|
|
2521
|
-
user: z3.object({ login: z3.string().optional() }).optional()
|
|
2522
|
-
});
|
|
2523
|
-
var ai_review_pull_comment_schema = z3.object({
|
|
2524
|
-
body: z3.string().optional(),
|
|
2525
|
-
url: z3.string().optional(),
|
|
2526
|
-
author: z3.object({ login: z3.string().optional() }).optional()
|
|
2527
|
-
});
|
|
2528
|
-
var pr_info_schema = z3.object({
|
|
2529
|
-
mergeable: z3.union([z3.boolean(), z3.string()]).nullable().optional(),
|
|
2530
|
-
mergeStateStatus: z3.string().nullable().optional(),
|
|
2531
|
-
state: z3.string().optional()
|
|
2532
|
-
});
|
|
2533
|
-
var epic_issue_schema = z3.object({
|
|
2534
|
-
number: z3.number(),
|
|
2535
|
-
body: z3.string().optional()
|
|
2536
|
-
});
|
|
2537
|
-
var blocking_issue_schema = z3.object({
|
|
2538
|
-
number: z3.number(),
|
|
2539
|
-
state: z3.string().optional(),
|
|
2540
|
-
repository_url: z3.string().optional()
|
|
2541
|
-
});
|
|
2542
|
-
var blocked_by_schema = z3.object({
|
|
2543
|
-
nodes: z3.array(blocking_issue_schema).default([]),
|
|
2544
|
-
totalCount: z3.number().optional()
|
|
2545
|
-
}).optional();
|
|
2546
|
-
var epic_child_schema = z3.object({
|
|
2547
|
-
state: z3.string().optional(),
|
|
2548
|
-
blockedBy: blocked_by_schema
|
|
2549
|
-
});
|
|
2550
|
-
var rest_comment_schema = z3.looseObject({
|
|
2551
|
-
body: z3.string().nullish(),
|
|
2552
|
-
html_url: z3.string().optional(),
|
|
2553
|
-
user: z3.looseObject({ login: z3.string().optional() }).nullish()
|
|
2554
|
-
});
|
|
2555
|
-
var issue_label_schema = z3.object({ name: z3.string() });
|
|
2556
|
-
var epic_subject_schema = z3.object({
|
|
2557
|
-
number: z3.number(),
|
|
2558
|
-
state: z3.string().optional(),
|
|
2559
|
-
labels: z3.array(issue_label_schema).optional(),
|
|
2560
|
-
body: z3.string().optional()
|
|
2561
|
-
});
|
|
2562
|
-
var open_issue_schema = z3.object({
|
|
2563
|
-
number: z3.number(),
|
|
2564
|
-
title: z3.string(),
|
|
2565
|
-
labels: z3.array(issue_label_schema).optional(),
|
|
2566
|
-
createdAt: z3.string(),
|
|
2567
|
-
blockedBy: blocked_by_schema,
|
|
2568
|
-
// Present only on the pickup listing, which reads it for the paths each issue declares.
|
|
2569
|
-
body: z3.string().optional()
|
|
2570
|
-
});
|
|
2571
|
-
|
|
2572
2723
|
// scripts/gh/git-pr-checks-parse.ts
|
|
2573
2724
|
var CHECK_STATUS_PASS = "pass";
|
|
2574
2725
|
var CHECK_STATUS_PENDING = "pending";
|
|
@@ -2747,7 +2898,7 @@ var PrConflictError = class extends Error {
|
|
|
2747
2898
|
|
|
2748
2899
|
// scripts/lane/lane-ledger.ts
|
|
2749
2900
|
import { closeSync, constants, openSync, writeSync } from "node:fs";
|
|
2750
|
-
import { z as
|
|
2901
|
+
import { z as z3 } from "zod";
|
|
2751
2902
|
var LEDGER_PREFIX = "josh-lane-ledger-";
|
|
2752
2903
|
var LEDGER_SUFFIX = ".jsonl";
|
|
2753
2904
|
var LINE_SEPARATOR = "\n";
|
|
@@ -2761,54 +2912,83 @@ var KIND = {
|
|
|
2761
2912
|
LOAD: "load",
|
|
2762
2913
|
DISPATCH: "dispatch",
|
|
2763
2914
|
STAGE: "stage",
|
|
2764
|
-
STOP: "stop"
|
|
2915
|
+
STOP: "stop",
|
|
2916
|
+
OVERLAP: "overlap"
|
|
2765
2917
|
};
|
|
2766
|
-
var merge_schema =
|
|
2767
|
-
var
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2918
|
+
var merge_schema = z3.object({ kind: z3.literal(KIND.MERGE), at: z3.string(), issue: z3.number() });
|
|
2919
|
+
var check_schema = z3.object({
|
|
2920
|
+
label: z3.string(),
|
|
2921
|
+
elapsed_ms: z3.number(),
|
|
2922
|
+
is_passed: z3.boolean(),
|
|
2923
|
+
is_reused: z3.boolean().optional()
|
|
2924
|
+
});
|
|
2925
|
+
var gate_schema = z3.object({
|
|
2926
|
+
kind: z3.literal(KIND.GATE),
|
|
2927
|
+
at: z3.string(),
|
|
2928
|
+
elapsed_ms: z3.number(),
|
|
2929
|
+
is_passed: z3.boolean(),
|
|
2772
2930
|
// The unit suite's own duration, present when this gate ran it — the one
|
|
2773
2931
|
// record of a full vitest run `josh metrics` reads, so the suite is never timed twice.
|
|
2774
|
-
unit_ms:
|
|
2932
|
+
unit_ms: z3.number().optional(),
|
|
2775
2933
|
// The whole cores busy outside this gate, beyond the machine's baseline, at its start or its end —
|
|
2776
2934
|
// whichever was higher. Absent when the machine could not be read.
|
|
2777
|
-
external_cores:
|
|
2935
|
+
external_cores: z3.number().optional(),
|
|
2936
|
+
// Each check's own duration and verdict, so `josh lane:stats` can name the check a slow gate waited
|
|
2937
|
+
// on. A reused check started no process: its row says so, and its zero is no timing.
|
|
2938
|
+
checks: z3.array(check_schema).optional()
|
|
2939
|
+
});
|
|
2940
|
+
var process_kind_schema = z3.object({
|
|
2941
|
+
kind: z3.string(),
|
|
2942
|
+
cpu_percent: z3.number(),
|
|
2943
|
+
rss_mb: z3.number(),
|
|
2944
|
+
count: z3.number()
|
|
2945
|
+
});
|
|
2946
|
+
var load_schema = z3.object({
|
|
2947
|
+
kind: z3.literal(KIND.LOAD),
|
|
2948
|
+
at: z3.string(),
|
|
2949
|
+
load: z3.number(),
|
|
2950
|
+
available_mb: z3.number().optional(),
|
|
2951
|
+
swapped_mb: z3.number().optional(),
|
|
2952
|
+
lanes: z3.number().optional(),
|
|
2953
|
+
// The heaviest process kinds at the instant of the sample (`lane-process-load.ts`), so the load the
|
|
2954
|
+
// core budget's ledger does not explain can be read back by what made it (joshuafolkken/kit#3874).
|
|
2955
|
+
processes: z3.array(process_kind_schema).optional()
|
|
2778
2956
|
});
|
|
2779
|
-
var
|
|
2780
|
-
kind:
|
|
2781
|
-
at:
|
|
2782
|
-
|
|
2783
|
-
available_mb: z4.number().optional(),
|
|
2784
|
-
swapped_mb: z4.number().optional(),
|
|
2785
|
-
lanes: z4.number().optional()
|
|
2957
|
+
var dispatch_schema = z3.object({
|
|
2958
|
+
kind: z3.literal(KIND.DISPATCH),
|
|
2959
|
+
at: z3.string(),
|
|
2960
|
+
issue: z3.number()
|
|
2786
2961
|
});
|
|
2787
|
-
var
|
|
2788
|
-
kind:
|
|
2789
|
-
at:
|
|
2790
|
-
|
|
2962
|
+
var stage_schema = z3.object({
|
|
2963
|
+
kind: z3.literal(KIND.STAGE),
|
|
2964
|
+
at: z3.string(),
|
|
2965
|
+
stage: z3.string(),
|
|
2966
|
+
elapsed_ms: z3.number(),
|
|
2967
|
+
issue: z3.number().optional()
|
|
2791
2968
|
});
|
|
2792
|
-
var
|
|
2793
|
-
kind:
|
|
2794
|
-
at:
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
issue: z4.number().optional()
|
|
2969
|
+
var stop_schema = z3.object({
|
|
2970
|
+
kind: z3.literal(KIND.STOP),
|
|
2971
|
+
at: z3.string(),
|
|
2972
|
+
issue: z3.number(),
|
|
2973
|
+
reason: z3.string()
|
|
2798
2974
|
});
|
|
2799
|
-
var
|
|
2800
|
-
kind:
|
|
2801
|
-
at:
|
|
2802
|
-
issue:
|
|
2803
|
-
|
|
2975
|
+
var overlap_schema = z3.object({
|
|
2976
|
+
kind: z3.literal(KIND.OVERLAP),
|
|
2977
|
+
at: z3.string(),
|
|
2978
|
+
issue: z3.number(),
|
|
2979
|
+
lanes: z3.array(z3.number()),
|
|
2980
|
+
paths: z3.array(z3.string()),
|
|
2981
|
+
waited_ms: z3.number(),
|
|
2982
|
+
is_cleared: z3.boolean()
|
|
2804
2983
|
});
|
|
2805
|
-
var entry_schema =
|
|
2984
|
+
var entry_schema = z3.discriminatedUnion("kind", [
|
|
2806
2985
|
merge_schema,
|
|
2807
2986
|
gate_schema,
|
|
2808
2987
|
load_schema,
|
|
2809
2988
|
dispatch_schema,
|
|
2810
2989
|
stage_schema,
|
|
2811
|
-
stop_schema
|
|
2990
|
+
stop_schema,
|
|
2991
|
+
overlap_schema
|
|
2812
2992
|
]);
|
|
2813
2993
|
function target_of(repository) {
|
|
2814
2994
|
return stamp_file.stamp_path(LEDGER_PREFIX, repository, LEDGER_SUFFIX);
|
|
@@ -2822,19 +3002,19 @@ async function target() {
|
|
|
2822
3002
|
return void 0;
|
|
2823
3003
|
}
|
|
2824
3004
|
}
|
|
2825
|
-
function append(
|
|
2826
|
-
const descriptor = openSync(
|
|
3005
|
+
function append(path5, entry) {
|
|
3006
|
+
const descriptor = openSync(path5, APPEND_FLAGS, LEDGER_FILE_MODE);
|
|
2827
3007
|
try {
|
|
2828
|
-
if (stamp_file.is_own_regular_file(
|
|
3008
|
+
if (stamp_file.is_own_regular_file(path5)) {
|
|
2829
3009
|
writeSync(descriptor, `${JSON.stringify(entry)}${LINE_SEPARATOR}`);
|
|
2830
3010
|
}
|
|
2831
3011
|
} finally {
|
|
2832
3012
|
closeSync(descriptor);
|
|
2833
3013
|
}
|
|
2834
3014
|
}
|
|
2835
|
-
async function record(entry,
|
|
3015
|
+
async function record(entry, path5) {
|
|
2836
3016
|
try {
|
|
2837
|
-
const destination =
|
|
3017
|
+
const destination = path5 ?? await target();
|
|
2838
3018
|
if (destination !== void 0) append(destination, entry);
|
|
2839
3019
|
} catch {
|
|
2840
3020
|
}
|
|
@@ -2842,20 +3022,23 @@ async function record(entry, path4) {
|
|
|
2842
3022
|
function now_iso() {
|
|
2843
3023
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
2844
3024
|
}
|
|
2845
|
-
async function record_gate(
|
|
2846
|
-
await record({ kind: KIND.GATE, at: now_iso(), ...gate },
|
|
3025
|
+
async function record_gate(path5, gate) {
|
|
3026
|
+
await record({ kind: KIND.GATE, at: now_iso(), ...gate }, path5);
|
|
2847
3027
|
}
|
|
2848
3028
|
async function record_merge(issue) {
|
|
2849
3029
|
await record({ kind: KIND.MERGE, at: now_iso(), issue });
|
|
2850
3030
|
}
|
|
2851
|
-
async function record_dispatch(issue,
|
|
2852
|
-
await record({ kind: KIND.DISPATCH, at: now_iso(), issue },
|
|
3031
|
+
async function record_dispatch(issue, path5) {
|
|
3032
|
+
await record({ kind: KIND.DISPATCH, at: now_iso(), issue }, path5);
|
|
2853
3033
|
}
|
|
2854
|
-
async function record_stage(stage,
|
|
2855
|
-
await record({ kind: KIND.STAGE, at: now_iso(), ...stage },
|
|
3034
|
+
async function record_stage(stage, path5) {
|
|
3035
|
+
await record({ kind: KIND.STAGE, at: now_iso(), ...stage }, path5);
|
|
2856
3036
|
}
|
|
2857
|
-
async function record_stop(stop,
|
|
2858
|
-
await record({ kind: KIND.STOP, at: now_iso(), ...stop },
|
|
3037
|
+
async function record_stop(stop, path5) {
|
|
3038
|
+
await record({ kind: KIND.STOP, at: now_iso(), ...stop }, path5);
|
|
3039
|
+
}
|
|
3040
|
+
async function record_overlap(overlap, path5) {
|
|
3041
|
+
await record({ kind: KIND.OVERLAP, at: now_iso(), ...overlap }, path5);
|
|
2859
3042
|
}
|
|
2860
3043
|
function parse_line2(line) {
|
|
2861
3044
|
return entry_schema.safeParse(json_value.parse_or_undefined(line)).data;
|
|
@@ -2863,8 +3046,8 @@ function parse_line2(line) {
|
|
|
2863
3046
|
function is_present(entry) {
|
|
2864
3047
|
return entry !== void 0;
|
|
2865
3048
|
}
|
|
2866
|
-
function read_entries(
|
|
2867
|
-
const raw = stamp_file.read_stamp_text(
|
|
3049
|
+
function read_entries(path5) {
|
|
3050
|
+
const raw = stamp_file.read_stamp_text(path5);
|
|
2868
3051
|
if (raw === void 0) return [];
|
|
2869
3052
|
return raw.split(LINE_SEPARATOR).map((line) => parse_line2(line.trim())).filter(is_present);
|
|
2870
3053
|
}
|
|
@@ -2877,6 +3060,7 @@ var lane_ledger = {
|
|
|
2877
3060
|
record_dispatch,
|
|
2878
3061
|
record_gate,
|
|
2879
3062
|
record_merge,
|
|
3063
|
+
record_overlap,
|
|
2880
3064
|
record_stage,
|
|
2881
3065
|
record_stop,
|
|
2882
3066
|
target,
|
|
@@ -3043,9 +3227,9 @@ function read_stages(text) {
|
|
|
3043
3227
|
var time_followup_stage = { NO_STAGES, read_stages };
|
|
3044
3228
|
|
|
3045
3229
|
// scripts/time-runtime/time-reported-failure.ts
|
|
3046
|
-
import { z as
|
|
3047
|
-
var TEXT_BLOCK_SCHEMA =
|
|
3048
|
-
var CONTENT_SCHEMA =
|
|
3230
|
+
import { z as z4 } from "zod";
|
|
3231
|
+
var TEXT_BLOCK_SCHEMA = z4.object({ text: z4.string().nullish() });
|
|
3232
|
+
var CONTENT_SCHEMA = z4.union([z4.string(), z4.array(z4.unknown())]);
|
|
3049
3233
|
var LINE_SEPARATOR3 = "\n";
|
|
3050
3234
|
function block_text(block) {
|
|
3051
3235
|
const parsed = TEXT_BLOCK_SCHEMA.safeParse(block);
|
|
@@ -3582,38 +3766,38 @@ function check_key(josh_command, command) {
|
|
|
3582
3766
|
var time_single_check = { NO_CHECK, check_key };
|
|
3583
3767
|
|
|
3584
3768
|
// scripts/time-runtime/time-transcript-line.ts
|
|
3585
|
-
import { z as
|
|
3586
|
-
var BLOCK_SCHEMA2 =
|
|
3587
|
-
type:
|
|
3588
|
-
name:
|
|
3589
|
-
id:
|
|
3590
|
-
tool_use_id:
|
|
3591
|
-
input:
|
|
3769
|
+
import { z as z5 } from "zod";
|
|
3770
|
+
var BLOCK_SCHEMA2 = z5.object({
|
|
3771
|
+
type: z5.string().nullish(),
|
|
3772
|
+
name: z5.string().nullish(),
|
|
3773
|
+
id: z5.string().nullish(),
|
|
3774
|
+
tool_use_id: z5.string().nullish(),
|
|
3775
|
+
input: z5.unknown().nullish(),
|
|
3592
3776
|
// Whether the harness wrote this result back as a failure. Present on a
|
|
3593
3777
|
// `tool_result` block and on nothing else, and absent even there for the tools that never report
|
|
3594
3778
|
// one — which is why it is read as three answers rather than as a boolean with a default.
|
|
3595
|
-
is_error:
|
|
3779
|
+
is_error: z5.boolean().nullish(),
|
|
3596
3780
|
// What the call printed. Read only to recover the outcome a pipeline threw away:
|
|
3597
3781
|
// it is kept as flattened text rather than as blocks, because that is
|
|
3598
3782
|
// the whole of what `time-reported-failure.ts` asks of it.
|
|
3599
|
-
content:
|
|
3783
|
+
content: z5.unknown().nullish()
|
|
3600
3784
|
});
|
|
3601
|
-
var CONTENT_SCHEMA2 =
|
|
3602
|
-
var MESSAGE_SCHEMA2 =
|
|
3603
|
-
var LINE_SCHEMA =
|
|
3604
|
-
type:
|
|
3605
|
-
timestamp:
|
|
3785
|
+
var CONTENT_SCHEMA2 = z5.union([z5.string(), z5.array(BLOCK_SCHEMA2)]);
|
|
3786
|
+
var MESSAGE_SCHEMA2 = z5.object({ id: z5.string().nullish(), content: CONTENT_SCHEMA2.nullish() });
|
|
3787
|
+
var LINE_SCHEMA = z5.object({
|
|
3788
|
+
type: z5.string().nullish(),
|
|
3789
|
+
timestamp: z5.string().nullish(),
|
|
3606
3790
|
// The branch the line was written on, which is where the issue number lives — `josh git` names a
|
|
3607
3791
|
// branch `<N>-<slug>`. Read here rather than re-parsed by a second reader so `josh time --issue`
|
|
3608
3792
|
// and `josh cost --issue` answer from the same field.
|
|
3609
|
-
gitBranch:
|
|
3793
|
+
gitBranch: z5.string().nullish(),
|
|
3610
3794
|
// The two fields outside `message` that the harness writes an end-of-task notice on.
|
|
3611
3795
|
// **Both are read as `unknown` rather than as strings**: a schema
|
|
3612
3796
|
// insisting on a string here would reject every line whose `content` is a list of blocks — which is
|
|
3613
3797
|
// most of them — and a rejected line is dropped from the timeline entirely, so the shares would stop
|
|
3614
3798
|
// reconstructing the elapsed time. The shape is checked at the read below instead.
|
|
3615
|
-
content:
|
|
3616
|
-
attachment:
|
|
3799
|
+
content: z5.unknown().nullish(),
|
|
3800
|
+
attachment: z5.unknown().nullish(),
|
|
3617
3801
|
message: MESSAGE_SCHEMA2.nullish()
|
|
3618
3802
|
});
|
|
3619
3803
|
var UNKNOWN_BRANCH = "";
|
|
@@ -3724,6 +3908,7 @@ var NO_CALL = {
|
|
|
3724
3908
|
label: "",
|
|
3725
3909
|
josh_command: "",
|
|
3726
3910
|
josh_commands: [],
|
|
3911
|
+
josh_signatures: [],
|
|
3727
3912
|
check_key: time_single_check.NO_CHECK,
|
|
3728
3913
|
marker: time_markers.NO_MARKER,
|
|
3729
3914
|
message_id: NO_MESSAGE_ID2,
|
|
@@ -3736,6 +3921,7 @@ var UNKNOWN_CALL = {
|
|
|
3736
3921
|
label: UNKNOWN_TOOL,
|
|
3737
3922
|
josh_command: "",
|
|
3738
3923
|
josh_commands: [],
|
|
3924
|
+
josh_signatures: [],
|
|
3739
3925
|
check_key: time_single_check.NO_CHECK,
|
|
3740
3926
|
marker: time_markers.NO_MARKER,
|
|
3741
3927
|
message_id: NO_MESSAGE_ID2,
|
|
@@ -3749,6 +3935,7 @@ function non_bash_call(name, input, message_id) {
|
|
|
3749
3935
|
label: name,
|
|
3750
3936
|
josh_command: "",
|
|
3751
3937
|
josh_commands: [],
|
|
3938
|
+
josh_signatures: [],
|
|
3752
3939
|
check_key: time_single_check.NO_CHECK,
|
|
3753
3940
|
marker: time_markers.tool_marker(name, input),
|
|
3754
3941
|
message_id,
|
|
@@ -3768,6 +3955,7 @@ function bash_call(input, message_id) {
|
|
|
3768
3955
|
label: time_shell.bash_label(command),
|
|
3769
3956
|
josh_command,
|
|
3770
3957
|
josh_commands: time_shell.josh_commands_of(command),
|
|
3958
|
+
josh_signatures: time_shell.josh_signatures_of(command),
|
|
3771
3959
|
check_key: time_single_check.check_key(josh_command, command),
|
|
3772
3960
|
marker: time_markers.bash_marker(command),
|
|
3773
3961
|
message_id,
|
|
@@ -3890,6 +4078,7 @@ function to_spans(events, finished) {
|
|
|
3890
4078
|
label: event.label,
|
|
3891
4079
|
josh_command: event.josh_command,
|
|
3892
4080
|
josh_commands: event.josh_commands,
|
|
4081
|
+
josh_signatures: event.josh_signatures,
|
|
3893
4082
|
check_key: event.check_key,
|
|
3894
4083
|
marker: event.marker,
|
|
3895
4084
|
is_bundleable: event.is_bundleable,
|
|
@@ -4345,7 +4534,7 @@ var NAMED_CANDIDATE_COUNT = 3;
|
|
|
4345
4534
|
var SEQUENCE_BEFORE_LIMIT = CONSECUTIVE_LIMIT - ONE_TURN;
|
|
4346
4535
|
var RULE_POINTER = "`prompts/collaboration-workflow/turn-batching.md`";
|
|
4347
4536
|
var STREAK = `${String(CONSECUTIVE_LIMIT)} single-call turns in a row`;
|
|
4348
|
-
var REASON = `\u26D4 batching: ${STREAK}. Reissue this with the calls that do not need its result \u2014 the test is whether a call's input needs another call's result, not what kind of call it is (edits are covered exactly as reads)
|
|
4537
|
+
var REASON = `\u26D4 batching: ${STREAK}. Reissue this with the calls that do not need its result \u2014 the test is whether a call's input needs another call's result, not what kind of call it is (edits are covered exactly as reads); it never authorizes weakening a verification gate or a review. Nothing to pair? Reissue it unchanged. ${RULE_POINTER}`;
|
|
4349
4538
|
var NOTICE = `\u{1F4A1} batching: ${STREAK}; the Write proceeds. Issue the writes that do not need its result in one turn, never by weakening a gate or a review. ${RULE_POINTER}`;
|
|
4350
4539
|
var LANE_NOTICE = `\u{1F4A1} batching: ${STREAK}; the call proceeds. Pair independent calls. ${RULE_POINTER}`;
|
|
4351
4540
|
var WHOLE_FILE_WRITE_TOOL = "Write";
|
|
@@ -4410,7 +4599,7 @@ function describe_span(span) {
|
|
|
4410
4599
|
}
|
|
4411
4600
|
var FOLD_MINIMUM = 2;
|
|
4412
4601
|
function read_targets(sequence) {
|
|
4413
|
-
const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((
|
|
4602
|
+
const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((path5) => path5 !== "" && time_bundle_call.has_extension(path5));
|
|
4414
4603
|
return [...new Set(paths)];
|
|
4415
4604
|
}
|
|
4416
4605
|
function read_fold_directive(sequence) {
|
|
@@ -4419,7 +4608,7 @@ function read_fold_directive(sequence) {
|
|
|
4419
4608
|
return ` Fold them into one call: \`pnpm josh read:files ${paths.join(" ")}\`.`;
|
|
4420
4609
|
}
|
|
4421
4610
|
function write_targets(sequence) {
|
|
4422
|
-
const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((
|
|
4611
|
+
const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((path5) => path5 !== "" && time_bundle_call.has_extension(path5));
|
|
4423
4612
|
return [...new Set(paths)];
|
|
4424
4613
|
}
|
|
4425
4614
|
function write_fold_directive(sequence) {
|
|
@@ -4471,7 +4660,7 @@ var time_batch_guard = {
|
|
|
4471
4660
|
};
|
|
4472
4661
|
|
|
4473
4662
|
// scripts/time-runtime/time-hook-transcript.ts
|
|
4474
|
-
import
|
|
4663
|
+
import path4 from "node:path";
|
|
4475
4664
|
var { TRANSCRIPT_EXTENSION } = cost_transcript;
|
|
4476
4665
|
var AGENT_PREFIX = "agent-";
|
|
4477
4666
|
var AGENT_ID_PATTERN = /^[\w-]+$/u;
|
|
@@ -4479,14 +4668,15 @@ function is_agent_id(value) {
|
|
|
4479
4668
|
return typeof value === "string" && AGENT_ID_PATTERN.test(value);
|
|
4480
4669
|
}
|
|
4481
4670
|
function fork_path(transcript_path, agent_id) {
|
|
4482
|
-
const directory =
|
|
4483
|
-
const session_id =
|
|
4671
|
+
const directory = path4.dirname(transcript_path);
|
|
4672
|
+
const session_id = path4.basename(transcript_path, TRANSCRIPT_EXTENSION);
|
|
4484
4673
|
const file_name = `${AGENT_PREFIX}${agent_id}${TRANSCRIPT_EXTENSION}`;
|
|
4485
|
-
return
|
|
4674
|
+
return path4.join(cost_transcript.unit_directory(directory, session_id), file_name);
|
|
4486
4675
|
}
|
|
4487
4676
|
function transcript_of(transcript_path, agent_id) {
|
|
4488
|
-
if (!is_agent_id(agent_id)
|
|
4489
|
-
|
|
4677
|
+
if (!is_agent_id(agent_id) || !transcript_path.endsWith(TRANSCRIPT_EXTENSION)) {
|
|
4678
|
+
return transcript_path;
|
|
4679
|
+
}
|
|
4490
4680
|
return fork_path(transcript_path, agent_id);
|
|
4491
4681
|
}
|
|
4492
4682
|
var time_hook_transcript = {
|
|
@@ -4496,7 +4686,7 @@ var time_hook_transcript = {
|
|
|
4496
4686
|
|
|
4497
4687
|
// scripts/time-runtime/time-density-hook.ts
|
|
4498
4688
|
import { closeSync as closeSync2, fstatSync, openSync as openSync2, readSync } from "node:fs";
|
|
4499
|
-
import { z as
|
|
4689
|
+
import { z as z6 } from "zod";
|
|
4500
4690
|
|
|
4501
4691
|
// scripts/time-runtime/time-density.ts
|
|
4502
4692
|
var MIN_ROUND_TRIPS = 10;
|
|
@@ -4552,15 +4742,15 @@ var TAIL_BYTES = 262144;
|
|
|
4552
4742
|
var FILE_START = 0;
|
|
4553
4743
|
var NOTICE_PREFIX = "josh-density-notice-";
|
|
4554
4744
|
var NEVER_MS = 0;
|
|
4555
|
-
var payload_schema =
|
|
4556
|
-
transcript_path:
|
|
4745
|
+
var payload_schema = z6.object({
|
|
4746
|
+
transcript_path: z6.string().min(1).optional(),
|
|
4557
4747
|
// **`nullish`, not `optional`.** A payload spelling the absent agent as `null` has to read as "no
|
|
4558
4748
|
// fork"; rejected, it would fail `safeParse` for the whole payload and silence the line for every
|
|
4559
4749
|
// edit of the main line — the opposite of this module's stated failure direction.
|
|
4560
|
-
agent_id:
|
|
4750
|
+
agent_id: z6.string().nullish()
|
|
4561
4751
|
});
|
|
4562
|
-
var notice_schema =
|
|
4563
|
-
var call_schema =
|
|
4752
|
+
var notice_schema = z6.object({ notified_at_ms: z6.number() });
|
|
4753
|
+
var call_schema = z6.object({ tool_name: z6.string().min(1), tool_input: z6.unknown() });
|
|
4564
4754
|
function parse_transcript_path(raw_payload) {
|
|
4565
4755
|
const parsed = payload_schema.safeParse(JSON.parse(raw_payload));
|
|
4566
4756
|
if (!parsed.success || parsed.data.transcript_path === void 0) return void 0;
|
|
@@ -4627,9 +4817,6 @@ export {
|
|
|
4627
4817
|
ESLINT_EDIT_CACHE_FLAGS,
|
|
4628
4818
|
time_shell,
|
|
4629
4819
|
time_bundle_call,
|
|
4630
|
-
blocking_issue_schema,
|
|
4631
|
-
rest_comment_schema,
|
|
4632
|
-
open_issue_schema,
|
|
4633
4820
|
CHECK_STATUS_PENDING,
|
|
4634
4821
|
CHECK_STATUS_FAIL,
|
|
4635
4822
|
read_string,
|