@joshuafolkken/kit 1.1229.0 → 1.1370.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -0
- package/.claude/settings.json +4 -0
- package/.claude/skills/dependency-update/SKILL.md +5 -3
- package/.claude/skills/epic-commands/SKILL.md +82 -113
- package/.claude/skills/epic-commands/epic-bundle.md +38 -63
- package/.claude/skills/epic-commands/execution-waves.md +30 -51
- package/.claude/skills/verify-ui/SKILL.md +13 -20
- package/.claude/skills/workflow-commands/SKILL.md +10 -10
- package/.claude/skills/workflow-commands/background-commands.md +4 -4
- package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
- package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
- package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
- package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
- package/.claude/skills/workflow-commands/backlogrun.md +50 -61
- package/.claude/skills/workflow-commands/chain-rule.md +36 -40
- package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
- package/.claude/skills/workflow-commands/followup.md +24 -20
- package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
- package/.claude/skills/workflow-commands/fullrun.md +10 -10
- package/.claude/skills/workflow-commands/halfrun.md +9 -8
- package/.claude/skills/workflow-commands/into-target.md +12 -18
- package/.claude/skills/workflow-commands/issue-comments.md +11 -26
- package/.claude/skills/workflow-commands/kickoff.md +27 -16
- package/.claude/skills/workflow-commands/latest-gate.md +18 -29
- package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
- package/.claude/skills/workflow-commands/observation-filing.md +37 -28
- package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
- package/.claude/skills/workflow-commands/prerequisite.md +23 -15
- package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
- package/.claude/skills/workflow-commands/prrun.md +3 -3
- package/.claude/skills/workflow-commands/retrospective.md +13 -18
- package/.claude/skills/workflow-commands/split-assessment.md +6 -4
- package/.claude/skills/workflow-commands/target-repository.md +25 -28
- package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
- package/.gitattributes +2 -1
- package/.github/workflows/ci.yml +14 -0
- package/.github/workflows/publish.yml +2 -0
- package/.vscode/tasks.json +14 -0
- package/CLAUDE.md +10 -61
- package/README.md +38 -57
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +10 -61
- package/dist/commands/document-section-cli.js +42 -10
- package/dist/config-merge/index.js +11 -2
- package/dist/hooks/audit-provision.js +2 -2
- package/dist/hooks/batch-guard.js +7 -7
- package/dist/hooks/{chunk-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
- package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
- package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
- package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
- package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
- package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
- package/dist/hooks/{chunk-6HJJXRBX.js → chunk-KPM4YIIX.js} +8 -44
- package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
- package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
- package/dist/hooks/{chunk-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
- package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
- package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
- package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
- package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
- package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
- package/dist/hooks/codex-hook-adapter.js +26 -21
- package/dist/hooks/duplicate-read-guard.js +8 -8
- package/dist/hooks/format-edited.js +4 -4
- package/dist/hooks/inputs.json +213 -197
- package/dist/hooks/investigation-guard.js +8 -8
- package/dist/hooks/pretool-guard.js +15 -15
- package/dist/hooks/session-lang.js +406 -8
- package/dist/hooks/stop-guard.js +122 -201
- package/dist/josh.js +540 -137
- package/dist/version/index.js +15 -13
- package/eslint/base.js +43 -5
- package/eslint/rules/english-only-prose.js +3 -3
- package/eslint/rules/import.js +12 -0
- package/eslint/rules/namespace-object-export.js +2 -2
- package/package.json +16 -10
- package/pnpm-workspace.yaml +2 -4
- package/prompts/coding-standards.md +14 -48
- package/prompts/collaboration-workflow/file-edits.md +1 -1
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +4 -10
- package/prompts/collaboration-workflow/operating-rules.md +7 -8
- package/prompts/collaboration-workflow/output-bounds.md +1 -1
- package/prompts/collaboration-workflow/overview.md +1 -1
- package/prompts/collaboration-workflow/plan-comment.md +2 -1
- package/prompts/collaboration-workflow/principles.md +21 -3
- package/prompts/collaboration-workflow/report-format.md +16 -29
- package/prompts/collaboration-workflow/residency.md +1 -1
- package/prompts/collaboration-workflow/rule-delivery.md +7 -95
- package/prompts/collaboration-workflow/shell-body.md +3 -23
- package/prompts/collaboration-workflow/turn-batching.md +4 -13
- package/prompts/collaboration-workflow/wip-cap.md +5 -11
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +3 -22
- package/prompts/review.md +15 -38
- package/prompts/testing-guide.md +2 -4
- package/scripts/adopt/adopt-logic.ts +5 -5
- package/scripts/adopt/adopt-toolkits.ts +4 -5
- package/scripts/adopt/adopt.ts +2 -3
- package/scripts/agent/agent-argv.ts +7 -7
- package/scripts/agent/agent-diagnostics.ts +2 -2
- package/scripts/agent/agent-exit-record.ts +1 -1
- package/scripts/agent/agent-headless.ts +1 -1
- package/scripts/agent/agent-launch-environment.ts +6 -1
- package/scripts/agent/agent-role-profile.ts +49 -22
- package/scripts/agent/agent-session-role.ts +32 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/claude-agent-argv.ts +4 -4
- package/scripts/agent/claude-result-event.ts +4 -4
- package/scripts/agent/codex-hooks.ts +2 -2
- package/scripts/agent/interactive-ask.ts +3 -6
- package/scripts/auto-ok/auto-ok-cli.ts +46 -60
- package/scripts/backlog/backlog-arrival-added.ts +34 -0
- package/scripts/backlog/backlog-arrival.ts +54 -17
- package/scripts/backlog/backlog-budget-cli.ts +34 -6
- package/scripts/backlog/backlog-budget.ts +17 -24
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-args.ts +5 -4
- package/scripts/backlog/backlog-drive-cli.ts +14 -10
- package/scripts/backlog/backlog-drive-epic.ts +85 -0
- package/scripts/backlog/backlog-drive-launch.ts +1 -1
- package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
- package/scripts/backlog/backlog-drive-named.ts +39 -9
- package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
- package/scripts/backlog/backlog-drive-restore.ts +1 -1
- package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
- package/scripts/backlog/backlog-drive.ts +43 -28
- package/scripts/backlog/backlog-idle.ts +88 -0
- package/scripts/backlog/backlog-named.ts +11 -15
- package/scripts/backlog/backlog-next.ts +26 -30
- package/scripts/backlog/backlog-offer-cli.ts +28 -23
- package/scripts/backlog/backlog-offer.ts +7 -7
- package/scripts/backlog/backlog-overlap.ts +178 -0
- package/scripts/backlog/backlog-plan-cli.ts +14 -90
- package/scripts/backlog/backlog-plan-read.ts +111 -0
- package/scripts/backlog/backlog-plan.ts +11 -10
- package/scripts/backlog/backlog-pool.ts +13 -14
- package/scripts/backlog/backlog-rank.ts +11 -11
- package/scripts/backlog/backlog-ready.ts +15 -10
- package/scripts/backlog/backlog-scope.ts +14 -15
- package/scripts/backlog/backlog-stalled-cli.ts +2 -2
- package/scripts/backlog/backlog-stalled-detect.ts +4 -4
- package/scripts/backlog/backlog-stalled.ts +5 -6
- package/scripts/backlog/backlog-waves.ts +4 -4
- package/scripts/backlog/backlogrun-args.ts +74 -0
- package/scripts/backlog/backlogrun-cli.ts +113 -0
- package/scripts/backlog/backlogrun-launch.ts +178 -0
- package/scripts/behavior/behavior-assertion.ts +6 -8
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/behavior/behavior-rules.ts +3 -3
- package/scripts/build/build-claude-md.ts +4 -4
- package/scripts/build/build-codex-hooks.ts +2 -2
- package/scripts/build/build-commands.ts +1 -1
- package/scripts/build/build-hooks.ts +5 -5
- package/scripts/build/build.ts +1 -1
- package/scripts/build/hook-bundle-stamp.ts +109 -7
- package/scripts/build/local-bin.ts +2 -2
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +2 -2
- package/scripts/ci/composite-actions.ts +1 -2
- package/scripts/ci/pr-classification.ts +2 -2
- package/scripts/claude/workflow-destination.ts +1 -1
- package/scripts/clone/clone-aggregate.ts +1 -1
- package/scripts/clone/clone-fingerprint.ts +1 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/index.ts +1 -1
- package/scripts/config-merge/json-format.ts +1 -3
- package/scripts/config-merge/patch-json-array.ts +90 -0
- package/scripts/config-merge/patch-json-key.ts +6 -3
- package/scripts/config-merge/patch-json-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +1 -1
- package/scripts/cost-runtime/context-cut-payback.ts +4 -5
- package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
- package/scripts/cost-runtime/cost-attribute.ts +3 -3
- package/scripts/cost-runtime/cost-blocks.ts +3 -4
- package/scripts/cost-runtime/cost-cli.ts +14 -11
- package/scripts/cost-runtime/cost-corpus.ts +11 -11
- package/scripts/cost-runtime/cost-pricing.ts +4 -4
- package/scripts/cost-runtime/cost-tokens.ts +1 -2
- package/scripts/cost-runtime/cost-transcript.ts +29 -29
- package/scripts/cost-runtime/cost-usage.ts +6 -7
- package/scripts/cost-runtime/cost-verdict.ts +10 -11
- package/scripts/cost-runtime/own-session.ts +1 -1
- package/scripts/cost-runtime/transcript-cwd.ts +2 -2
- package/scripts/delegation/delegation-cli.ts +4 -4
- package/scripts/delegation/delegation-policy.ts +13 -15
- package/scripts/delegation/duplicate-read-guard.ts +9 -10
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +1 -1
- package/scripts/delegation/investigation-guard.ts +18 -22
- package/scripts/delegation/investigation-reads.ts +48 -238
- package/scripts/discovery/repo-discovery.ts +1 -1
- package/scripts/discovery/repo-map-logic.ts +1 -2
- package/scripts/discovery/repo-origin.ts +3 -3
- package/scripts/discovery/repo-party-cli.ts +2 -2
- package/scripts/discovery/repo-party.ts +2 -2
- package/scripts/doctor/doctor-consumer.ts +1 -1
- package/scripts/doctor/doctor-io.ts +6 -7
- package/scripts/doctor/doctor-logic.ts +1 -1
- package/scripts/doctor/doctor-ports.ts +1 -1
- package/scripts/doctor/doctor.ts +8 -9
- package/scripts/document/backlogrun-parent-read-set.ts +5 -6
- package/scripts/document/bash-output-cap.ts +5 -7
- package/scripts/document/capped-print-part.ts +1 -1
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/document-byte-budget.ts +33 -64
- package/scripts/document/document-byte-check.ts +4 -4
- package/scripts/document/document-reachability.ts +7 -8
- package/scripts/document/document-read-cli.ts +2 -2
- package/scripts/document/document-scan.ts +26 -2
- package/scripts/document/document-section-cli.ts +6 -8
- package/scripts/document/document-section.ts +8 -12
- package/scripts/document/edit-files-cli.ts +3 -4
- package/scripts/document/entry-read-budget.ts +8 -70
- package/scripts/document/entry-read-set.ts +51 -34
- package/scripts/document/lane-child-read-set.ts +9 -9
- package/scripts/document/read-files-cli.ts +1 -2
- package/scripts/document/read-set-cli.ts +16 -19
- package/scripts/document/read-set-cost.ts +4 -4
- package/scripts/document/read-set-point-of-use.ts +28 -38
- package/scripts/document/read-set-pricing.ts +1 -1
- package/scripts/document/read-set-trim.ts +3 -3
- package/scripts/document/resident-budget.ts +8 -10
- package/scripts/epic/epic-add-body.ts +15 -18
- package/scripts/epic/epic-add-plan.ts +26 -28
- package/scripts/epic/epic-add.ts +32 -25
- package/scripts/epic/epic-audit-checks.ts +27 -37
- package/scripts/epic/epic-audit-cli.ts +21 -22
- package/scripts/epic/epic-audit-orphans.ts +16 -17
- package/scripts/epic/epic-audit-rationale.ts +10 -15
- package/scripts/epic/epic-audit-report.ts +2 -5
- package/scripts/epic/epic-audit.ts +18 -14
- package/scripts/epic/epic-body.ts +10 -10
- package/scripts/epic/epic-bundle-cli.ts +36 -34
- package/scripts/epic/epic-bundle-evidence.ts +5 -5
- package/scripts/epic/epic-bundle-gaps.ts +6 -9
- package/scripts/epic/epic-bundle-poll.ts +1 -1
- package/scripts/epic/epic-bundle-referenced.ts +11 -14
- package/scripts/epic/epic-bundle.ts +19 -20
- package/scripts/epic/epic-busy.ts +44 -21
- package/scripts/epic/epic-candidate-confirm.ts +15 -18
- package/scripts/epic/epic-chains.ts +18 -23
- package/scripts/epic/epic-classify.ts +11 -12
- package/scripts/epic/epic-cli-argv.ts +5 -6
- package/scripts/epic/epic-cli-remove.ts +9 -4
- package/scripts/epic/epic-cli.ts +38 -26
- package/scripts/epic/epic-close-comment.ts +14 -15
- package/scripts/epic/epic-close.ts +25 -29
- package/scripts/epic/epic-cross-repo.ts +18 -21
- package/scripts/epic/epic-decision.ts +14 -18
- package/scripts/epic/epic-fetch.ts +25 -31
- package/scripts/epic/epic-graph.ts +15 -17
- package/scripts/epic/epic-index.ts +14 -16
- package/scripts/epic/epic-issue.ts +9 -11
- package/scripts/epic/epic-label-age.ts +74 -0
- package/scripts/epic/epic-lane-offer.ts +35 -24
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +8 -8
- package/scripts/epic/epic-next-views.ts +12 -12
- package/scripts/epic/epic-next.ts +29 -33
- package/scripts/epic/epic-outside-blocker.ts +11 -10
- package/scripts/epic/epic-parse.ts +22 -24
- package/scripts/epic/epic-promote.ts +3 -2
- package/scripts/epic/epic-rank.ts +1 -1
- package/scripts/epic/epic-read.ts +10 -8
- package/scripts/epic/epic-reconcile.ts +8 -6
- package/scripts/epic/epic-reference.ts +5 -4
- package/scripts/epic/epic-relation-recheck.ts +10 -11
- package/scripts/epic/epic-relations.ts +9 -8
- package/scripts/epic/epic-remove-plan.ts +4 -5
- package/scripts/epic/epic-remove.ts +7 -5
- package/scripts/epic/epic-report.ts +18 -20
- package/scripts/epic/epic-run.ts +6 -5
- package/scripts/epic/epic-sections.ts +2 -2
- package/scripts/epic/epic-shape.ts +3 -3
- package/scripts/epic/epic-solo-stale.ts +3 -2
- package/scripts/epic/epic-solo.ts +8 -8
- package/scripts/epic/epic-triage.ts +5 -4
- package/scripts/epic/epic-validate.ts +8 -7
- package/scripts/epic/epic.ts +5 -5
- package/scripts/exports/unused-members-cli.ts +1 -1
- package/scripts/followup/followup-issue-number.ts +1 -2
- package/scripts/followup/git-followup-cleanup.ts +6 -7
- package/scripts/followup/git-followup-finish.ts +11 -13
- package/scripts/followup/git-followup-flush.ts +11 -7
- package/scripts/followup/git-followup-issue-close.ts +16 -13
- package/scripts/followup/git-followup-label.ts +9 -6
- package/scripts/followup/git-followup-merged.ts +1 -1
- package/scripts/followup/git-followup-pending.ts +7 -9
- package/scripts/followup/git-followup-stages.ts +28 -17
- package/scripts/followup/git-followup-workflow.ts +19 -21
- package/scripts/followup/git-pr-followup-checks.ts +13 -20
- package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
- package/scripts/followup/git-pr-followup.ts +18 -17
- package/scripts/gate/core-admission.ts +162 -0
- package/scripts/gate/core-budget.ts +134 -91
- package/scripts/gate/gate-ledger.ts +114 -0
- package/scripts/gate/gate-log.ts +7 -9
- package/scripts/gate/gate-plan.ts +103 -35
- package/scripts/gate/gate-report.ts +39 -21
- package/scripts/gate/gate-skip.ts +11 -13
- package/scripts/gate/gate-steps.ts +5 -1
- package/scripts/gate/gate-tree.ts +3 -4
- package/scripts/gate/hook-gate-reuse.ts +9 -9
- package/scripts/gate/machine-capacity.ts +313 -0
- package/scripts/gate/pre-commit-type-check.ts +4 -4
- package/scripts/gate/project-checks.ts +12 -4
- package/scripts/gate/scoped-green.ts +11 -18
- package/scripts/gate/type-check-command.ts +2 -2
- package/scripts/gate/type-check-step.ts +4 -4
- package/scripts/gate/verification-gate.ts +60 -53
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/gh/git-ai-review-scan.ts +3 -2
- package/scripts/gh/git-gh-api-path.ts +10 -11
- package/scripts/gh/git-gh-exec.ts +43 -48
- package/scripts/gh/git-gh-failure.ts +6 -9
- package/scripts/gh/git-gh-helpers.ts +1 -1
- package/scripts/gh/git-gh-issue-list.ts +15 -19
- package/scripts/gh/git-gh-issue-read.ts +43 -60
- package/scripts/gh/git-gh-issue-rest.ts +14 -15
- package/scripts/gh/git-gh-issue-write.ts +52 -40
- package/scripts/gh/git-gh-issue.ts +23 -24
- package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
- package/scripts/gh/git-gh-pr-read.ts +46 -50
- package/scripts/gh/git-gh-pr-rest.ts +23 -26
- package/scripts/gh/git-gh-pr-review.ts +2 -2
- package/scripts/gh/git-gh-pr-rollup.ts +4 -4
- package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
- package/scripts/gh/git-gh-pr.ts +16 -16
- package/scripts/gh/git-gh-reachability.ts +11 -12
- package/scripts/gh/git-gh-repo.ts +2 -3
- package/scripts/gh/git-gh-rest-state.ts +1 -1
- package/scripts/gh/git-pr-ai-review.ts +6 -5
- package/scripts/gh/git-pr-checks-eval.ts +28 -30
- package/scripts/gh/git-pr-checks-parse.ts +14 -16
- package/scripts/gh/git-pr-checks-watch.ts +17 -17
- package/scripts/gh/git-pr-checks.ts +20 -23
- package/scripts/gh/git-pr-coderabbit.ts +8 -6
- package/scripts/gh/git-pr-confirmation.ts +5 -5
- package/scripts/gh/git-pr-managed-config.ts +7 -9
- package/scripts/gh/git-pr-messages.ts +1 -1
- package/scripts/gh/git-pr.ts +15 -16
- package/scripts/gh/github-issue-url.ts +8 -9
- package/scripts/git/base-tree.ts +66 -0
- package/scripts/git/change-base.ts +42 -2
- package/scripts/git/changed-file-scope.ts +5 -5
- package/scripts/git/changed-paths.ts +1 -2
- package/scripts/git/constants.ts +2 -2
- package/scripts/git/git-branch.ts +1 -1
- package/scripts/git/git-closes-keyword.ts +3 -3
- package/scripts/git/git-command.ts +53 -41
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +14 -15
- package/scripts/git/git-error.ts +1 -1
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/git/git-issue.ts +10 -8
- package/scripts/git/git-location-environment.ts +3 -4
- package/scripts/git/git-ls-remote.ts +6 -8
- package/scripts/git/git-pre-push-hook.ts +11 -10
- package/scripts/git/git-preflight.ts +5 -5
- package/scripts/git/git-push-transport.ts +2 -2
- package/scripts/git/git-remote-branch.ts +1 -2
- package/scripts/git/git-schemas.ts +16 -23
- package/scripts/git/git-spawn-sync.ts +1 -1
- package/scripts/git/git-spawn.ts +37 -14
- package/scripts/git/git-ssh-keepalive.ts +12 -5
- package/scripts/git/git-staging.ts +7 -8
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/git-worktree.ts +35 -27
- package/scripts/git/gone-branch.ts +2 -2
- package/scripts/git/listing-cutoff.ts +1 -2
- package/scripts/git/lockfile-sync.ts +65 -0
- package/scripts/git/main-merge-guard.ts +1 -2
- package/scripts/git/main-merge.ts +7 -7
- package/scripts/git/main-sync.ts +23 -8
- package/scripts/git/parse-json-array.ts +18 -23
- package/scripts/git/repository-lock.ts +34 -2
- package/scripts/git/stash/git-stash.ts +4 -5
- package/scripts/git/stash/stash-orphans.ts +5 -3
- package/scripts/git/stash/stash-pop-args.ts +1 -1
- package/scripts/git/stash/stash-pop-cli.ts +3 -3
- package/scripts/git/stash/stash-sweep-lock.ts +2 -2
- package/scripts/hooks/batch-guard.ts +11 -13
- package/scripts/hooks/check-commit-message.ts +12 -9
- package/scripts/hooks/codex-hook-adapter.ts +16 -10
- package/scripts/hooks/edited-cspell.ts +3 -4
- package/scripts/hooks/format-edited-cli.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +11 -17
- package/scripts/hooks/format-rewrite-notice.ts +19 -17
- package/scripts/hooks/pre-push-unit.ts +10 -14
- package/scripts/hooks/pretool-guard-cli.ts +4 -4
- package/scripts/hooks/pretool-guard.ts +93 -18
- package/scripts/hooks/reserved-run.ts +2 -2
- package/scripts/hooks/step-zero-notice.ts +1 -1
- package/scripts/hooks/stop-guard.ts +21 -10
- package/scripts/init/basic-path-migration.ts +2 -2
- package/scripts/init/claude-kit-only-settings.ts +2 -2
- package/scripts/init/claude-plugin-config.ts +2 -2
- package/scripts/init/distributed-paths.ts +4 -4
- package/scripts/init/hook-command-rewrite.ts +3 -3
- package/scripts/init/hook-launch.ts +5 -5
- package/scripts/init/init-actions.ts +13 -0
- package/scripts/init/init-ai-copy.ts +11 -11
- package/scripts/init/init-bootstrap.ts +3 -3
- package/scripts/init/init-copy-content.ts +4 -4
- package/scripts/init/init-logic-json-merge.ts +7 -9
- package/scripts/init/init-logic-migrate.ts +1 -1
- package/scripts/init/init-logic-templates.ts +1 -1
- package/scripts/init/init-logic-workspace.ts +4 -4
- package/scripts/init/init-logic-yaml-merge.ts +2 -2
- package/scripts/init/init-logic.ts +19 -22
- package/scripts/init/init.ts +12 -8
- package/scripts/init/kit-base-preset.ts +1 -1
- package/scripts/init/kit-setup-state.ts +1 -1
- package/scripts/init/kit-written-paths.ts +1 -2
- package/scripts/init/package-manager-pin.ts +35 -0
- package/scripts/init/project-profile-cli.ts +1 -1
- package/scripts/init/project-profile.ts +3 -3
- package/scripts/init/session-language-environment.ts +1 -1
- package/scripts/init/start-exec.ts +3 -4
- package/scripts/init/start-plan.ts +2 -2
- package/scripts/init/start-setup-pr.ts +3 -2
- package/scripts/init/start-steps.ts +2 -2
- package/scripts/init/tsconfig-preset-migration.ts +1 -1
- package/scripts/init/vscode-tasks.ts +62 -0
- package/scripts/issue/baseline-measure.ts +2 -2
- package/scripts/issue/behavior-change-lint.ts +2 -2
- package/scripts/issue/defect-rate-cli.ts +6 -7
- package/scripts/issue/defect-rate.ts +37 -27
- package/scripts/issue/git-next-issues.ts +9 -8
- package/scripts/issue/issue-auto-ok.ts +49 -11
- package/scripts/issue/issue-backlinks-cli.ts +5 -5
- package/scripts/issue/issue-backlinks.ts +6 -6
- package/scripts/issue/issue-cite-cli.ts +20 -18
- package/scripts/issue/issue-cite.ts +18 -8
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +6 -4
- package/scripts/issue/issue-file-cli.ts +75 -15
- package/scripts/issue/issue-file-fold.ts +155 -0
- package/scripts/issue/issue-file.ts +14 -6
- package/scripts/issue/issue-fold-cli.ts +14 -9
- package/scripts/issue/issue-fold.ts +23 -8
- package/scripts/issue/issue-labels.ts +46 -37
- package/scripts/issue/issue-lint-cli.ts +2 -2
- package/scripts/issue/issue-lint.ts +1 -1
- package/scripts/issue/issue-merged.ts +10 -4
- package/scripts/issue/issue-number-shape.ts +27 -0
- package/scripts/issue/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +4 -5
- package/scripts/issue/issue-read.ts +4 -5
- package/scripts/issue/issue-reference.ts +5 -5
- package/scripts/issue/issue-release-cli.ts +165 -0
- package/scripts/issue/issue-release.ts +58 -0
- package/scripts/issue/issue-report-failures.ts +7 -4
- package/scripts/issue/issue-scout-cli.ts +11 -11
- package/scripts/issue/issue-scout-closed.ts +4 -4
- package/scripts/issue/issue-scout.ts +4 -5
- package/scripts/issue/issue-state-cli.ts +17 -10
- package/scripts/issue/issue-state.ts +12 -13
- package/scripts/issue/issue-wip.ts +7 -7
- package/scripts/issue/markdown-section.ts +3 -3
- package/scripts/issue/measure-rerun-cli.ts +10 -9
- package/scripts/issue/reproduction-measure.ts +3 -3
- package/scripts/issue/session-cite.ts +56 -0
- package/scripts/josh/agent-session-environment.ts +10 -8
- package/scripts/josh/cli-body.ts +2 -2
- package/scripts/josh/command-suggest.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +20 -23
- package/scripts/josh/hook-decision.ts +24 -28
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +32 -34
- package/scripts/josh/josh-commands-ai.ts +6 -6
- package/scripts/josh/josh-commands-backlog.ts +15 -3
- package/scripts/josh/josh-commands-clone.ts +1 -1
- package/scripts/josh/josh-commands-development.ts +33 -4
- package/scripts/josh/josh-commands-document.ts +3 -3
- package/scripts/josh/josh-commands-guard.ts +3 -3
- package/scripts/josh/josh-commands-issue.ts +11 -5
- package/scripts/josh/josh-commands-lane.ts +16 -5
- package/scripts/josh/josh-commands-lint.ts +1 -1
- package/scripts/josh/josh-commands-maintenance.ts +2 -2
- package/scripts/josh/josh-commands-run.ts +20 -6
- package/scripts/josh/josh-commands-split.ts +1 -2
- package/scripts/josh/josh-commands-versioning.ts +5 -5
- package/scripts/josh/josh-commands-workflow.ts +30 -22
- package/scripts/josh/josh-environment-file.ts +1 -1
- package/scripts/josh/josh-in-process.ts +3 -3
- package/scripts/josh/josh-logic.ts +10 -10
- package/scripts/josh/josh-run.ts +3 -3
- package/scripts/josh/josh-verdict.ts +9 -12
- package/scripts/josh/josh.ts +3 -3
- package/scripts/josh/kit-only.ts +2 -2
- package/scripts/josh/path-decision.ts +3 -3
- package/scripts/josh/platform-temporary.ts +7 -5
- package/scripts/josh/process-identity.ts +24 -6
- package/scripts/josh/process-owner.ts +4 -4
- package/scripts/josh/session-language-cli.ts +53 -11
- package/scripts/josh/session-language.ts +1 -1
- package/scripts/josh/stamp-file.ts +48 -29
- package/scripts/josh/stamp-record.ts +57 -0
- package/scripts/lane/lane-await.ts +35 -11
- package/scripts/lane/lane-cache.ts +6 -6
- package/scripts/lane/lane-capacity.ts +32 -17
- package/scripts/lane/lane-child-invocation.ts +17 -15
- package/scripts/lane/lane-child-marker.ts +12 -12
- package/scripts/lane/lane-cli.ts +20 -13
- package/scripts/lane/lane-close.ts +6 -6
- package/scripts/lane/lane-dispatch.ts +61 -72
- package/scripts/lane/lane-environment.ts +5 -5
- package/scripts/lane/lane-guard-policy.ts +7 -21
- package/scripts/lane/lane-handoff.ts +2 -2
- package/scripts/lane/lane-install.ts +9 -10
- package/scripts/lane/lane-launch-cli.ts +13 -8
- package/scripts/lane/lane-ledger.ts +73 -11
- package/scripts/lane/lane-leftover.ts +44 -30
- package/scripts/lane/lane-limit-cli.ts +160 -0
- package/scripts/lane/lane-limit-override.ts +74 -0
- package/scripts/lane/lane-load.ts +19 -68
- package/scripts/lane/lane-measure-cli.ts +15 -25
- package/scripts/lane/lane-occupancy.ts +6 -4
- package/scripts/lane/lane-open.ts +25 -24
- package/scripts/lane/lane-output.ts +4 -3
- package/scripts/lane/lane-paths.ts +22 -8
- package/scripts/lane/lane-phase.ts +33 -0
- package/scripts/lane/lane-reap.ts +2 -2
- package/scripts/lane/lane-registry.ts +27 -15
- package/scripts/lane/lane-relaunch.ts +9 -9
- package/scripts/lane/lane-report.ts +5 -4
- package/scripts/lane/lane-resume.ts +2 -2
- package/scripts/lane/lane-sampler.ts +55 -0
- package/scripts/lane/lane-seed.ts +7 -7
- package/scripts/lane/lane-stage-stats.ts +135 -0
- package/scripts/lane/lane-start-point.ts +8 -11
- package/scripts/lane/lane-stats.ts +60 -15
- package/scripts/lane/lane-stray.ts +140 -0
- package/scripts/lane/lane-vacant.ts +1 -1
- package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
- package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
- package/scripts/lane/openai-review-broker.ts +2 -4
- package/scripts/lib/ancestor-directories.ts +1 -1
- package/scripts/lib/bounded-pool.ts +2 -2
- package/scripts/lib/buffered-process.ts +4 -6
- package/scripts/lib/caddy-logs.sh +0 -0
- package/scripts/lib/cli-flags.ts +39 -6
- package/scripts/lib/error-message.ts +1 -1
- package/scripts/lib/json-value.ts +17 -3
- package/scripts/lib/poll.ts +1 -1
- package/scripts/lib/status-icons.ts +3 -3
- package/scripts/lib/timed-fetch.ts +1 -1
- package/scripts/lib/timeouts.ts +1 -1
- package/scripts/lines/bytes-command.ts +3 -4
- package/scripts/lines/effective-limit.ts +25 -12
- package/scripts/lines/line-budget.ts +47 -55
- package/scripts/lines/line-targets.ts +6 -2
- package/scripts/lines/lines-command.ts +3 -3
- package/scripts/lint/cspell-cached.ts +1 -1
- package/scripts/lint/cycle-recheck.ts +122 -0
- package/scripts/lint/format.ts +1 -2
- package/scripts/lint/lint-parallel.ts +34 -19
- package/scripts/lint/lint-related-scope.ts +25 -15
- package/scripts/lint/lint-related.ts +6 -7
- package/scripts/managed-marker/index.ts +1 -1
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/git-notify.ts +9 -7
- package/scripts/notify/telegram-notify.ts +53 -37
- package/scripts/notify/telegram-test-logic.ts +3 -3
- package/scripts/notify/telegram-test.ts +45 -30
- package/scripts/observations/observation-ledger-home.ts +14 -8
- package/scripts/observations/observation-ledger-line.ts +3 -2
- package/scripts/observations/observation-ledger-migrate.ts +3 -4
- package/scripts/observations/observation-ledger-prepare.ts +4 -4
- package/scripts/observations/observation-ledger.ts +14 -15
- package/scripts/observations/observation-record-cli.ts +83 -0
- package/scripts/observations/observation-record.ts +91 -0
- package/scripts/observations/observations-flush-cli.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +7 -6
- package/scripts/observations/observations-flush.ts +26 -27
- package/scripts/overrides/overrides-check.ts +18 -8
- package/scripts/package/package-scout-cli.ts +1 -1
- package/scripts/package/package-scout-format.ts +2 -2
- package/scripts/package/package-scout.ts +1 -1
- package/scripts/propagate/propagate-git-failure.ts +1 -1
- package/scripts/propagate/propagate-git.ts +7 -7
- package/scripts/propagate/propagate-plan.ts +2 -2
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +5 -7
- package/scripts/propagate/propagate-select.ts +1 -1
- package/scripts/propagate/propagate-steps.ts +19 -20
- package/scripts/propagate/propagate-targets.ts +6 -10
- package/scripts/propagate/propagate.ts +5 -5
- package/scripts/refactor/import-graph.ts +1 -1
- package/scripts/refactor/refactor-lint.ts +4 -10
- package/scripts/refactor/refactor-scan-cli.ts +1 -1
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +1 -1
- package/scripts/release/github-release-cli.ts +25 -3
- package/scripts/release/github-release-environment.ts +1 -0
- package/scripts/release/github-release-runs.ts +115 -0
- package/scripts/release/github-release.ts +13 -67
- package/scripts/release/release-cli.ts +21 -4
- package/scripts/release/release-history.ts +6 -10
- package/scripts/release/release-plan.ts +3 -3
- package/scripts/release/release-progress.ts +3 -4
- package/scripts/release/release-publish.ts +8 -9
- package/scripts/release/release-scope-cli.ts +8 -10
- package/scripts/release/release-tag.ts +6 -8
- package/scripts/release/release-worktree.ts +5 -5
- package/scripts/repo/auto-merge-setting-logic.ts +7 -9
- package/scripts/repo/auto-merge-setting.ts +1 -1
- package/scripts/repo/repo-setting.ts +4 -4
- package/scripts/repo/repository-labels.ts +1 -1
- package/scripts/repo/required-checks-logic.ts +3 -3
- package/scripts/repo/required-checks-report.ts +1 -1
- package/scripts/repo/ruleset-check-cli.ts +1 -1
- package/scripts/repo/ruleset-check.ts +1 -1
- package/scripts/report/report-format-reference.ts +26 -0
- package/scripts/report/report-lint-cli.ts +2 -2
- package/scripts/report/report-lint.ts +16 -2
- package/scripts/review/disposition-cli.ts +2 -2
- package/scripts/review/disposition-logic.ts +1 -1
- package/scripts/review/live-evidence.ts +9 -6
- package/scripts/review/review-attest-cli.ts +1 -2
- package/scripts/review/review-attest.ts +3 -3
- package/scripts/review/review-brief-cli.ts +19 -20
- package/scripts/review/review-brief.ts +29 -32
- package/scripts/review/review-checkout.ts +2 -2
- package/scripts/review/review-diff-parts.ts +3 -5
- package/scripts/review/review-diff-write.ts +1 -1
- package/scripts/review/review-finding-ledger.ts +7 -4
- package/scripts/review/review-findings-cli.ts +2 -2
- package/scripts/review/review-level.ts +4 -7
- package/scripts/review/review-record-cli.ts +73 -16
- package/scripts/review/review-record.ts +5 -4
- package/scripts/review/review-round2-cli.ts +2 -3
- package/scripts/review/review-round2.ts +13 -21
- package/scripts/review/review-stamps.ts +9 -71
- package/scripts/review/review-tree.ts +4 -5
- package/scripts/rules/bash-triggers.ts +4 -4
- package/scripts/rules/decision-oracle-batch.ts +5 -6
- package/scripts/rules/decision-oracle-stage.ts +1 -1
- package/scripts/rules/decision-oracle-tokens.ts +1 -2
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +61 -406
- package/scripts/rules/destructive-command.ts +2 -2
- package/scripts/rules/direct-filing.ts +4 -4
- package/scripts/rules/direct-pr-create.ts +2 -2
- package/scripts/rules/early-heartbeat.ts +15 -19
- package/scripts/rules/file-body.ts +5 -6
- package/scripts/rules/filing-cap.ts +6 -7
- package/scripts/rules/filing-offer.ts +1 -1
- package/scripts/rules/firing-point.ts +6 -6
- package/scripts/rules/gh-api.ts +2 -2
- package/scripts/rules/git-argv.ts +3 -3
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/hook-context-line.ts +31 -0
- package/scripts/rules/implementation-cut-verdict.ts +5 -8
- package/scripts/rules/implementation-cut.ts +35 -32
- package/scripts/rules/index-guard.ts +2 -2
- package/scripts/rules/issue-citation.ts +7 -7
- package/scripts/rules/issue-comments.ts +21 -13
- package/scripts/rules/josh-git-bare.ts +2 -2
- package/scripts/rules/lane-background.ts +14 -16
- package/scripts/rules/lane-carry-conflict.ts +41 -5
- package/scripts/rules/lane-interactive-ask.ts +6 -9
- package/scripts/rules/lane-park.ts +12 -16
- package/scripts/rules/lane-split-park.ts +1 -2
- package/scripts/rules/lane-switch-main.ts +10 -13
- package/scripts/rules/last-prompt.ts +1 -1
- package/scripts/rules/oracle-consulted.ts +5 -5
- package/scripts/rules/oracle-firing.ts +6 -9
- package/scripts/rules/oracle-list-cli.ts +2 -2
- package/scripts/rules/permission-guards.ts +2 -2
- package/scripts/rules/piped-verification.ts +79 -9
- package/scripts/rules/poll-loop.ts +9 -11
- package/scripts/rules/pre-gate-cut.ts +33 -30
- package/scripts/rules/prior-comment-read.ts +3 -3
- package/scripts/rules/protected-files.ts +25 -13
- package/scripts/rules/raw-field-body.ts +3 -4
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +10 -12
- package/scripts/rules/rule-guard.ts +1 -1
- package/scripts/rules/rule-list.ts +51 -0
- package/scripts/rules/rule-registry-rows.ts +282 -0
- package/scripts/rules/rule-registry.ts +109 -0
- package/scripts/rules/rule-value-cache.ts +2 -2
- package/scripts/rules/rule-value-cli.ts +6 -4
- package/scripts/rules/rule-value.ts +61 -22
- package/scripts/rules/run-tail-rule.ts +11 -15
- package/scripts/rules/shell-body-trigger.ts +7 -7
- package/scripts/rules/shell-segments.ts +2 -4
- package/scripts/rules/stop-rules.ts +54 -41
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +2 -2
- package/scripts/rules/third-party-write.ts +3 -3
- package/scripts/rules/worktree-guard.ts +12 -5
- package/scripts/run/add/run-add-cli.ts +165 -0
- package/scripts/run/add/run-add.ts +124 -0
- package/scripts/run/board/run-board-cli.ts +207 -0
- package/scripts/run/board/run-board-closed.ts +95 -0
- package/scripts/run/board/run-board-every.ts +60 -0
- package/scripts/run/board/run-board-fetch.ts +38 -0
- package/scripts/run/board/run-board-fit.ts +219 -0
- package/scripts/run/board/run-board-github.ts +162 -0
- package/scripts/run/board/run-board-header.ts +275 -0
- package/scripts/run/board/run-board-kind.ts +35 -0
- package/scripts/run/board/run-board-labels.ts +299 -0
- package/scripts/run/board/run-board-layout.ts +222 -0
- package/scripts/run/board/run-board-link.ts +31 -0
- package/scripts/run/board/run-board-machine.ts +198 -0
- package/scripts/run/board/run-board-notes.ts +103 -0
- package/scripts/run/board/run-board-phase.ts +136 -0
- package/scripts/run/board/run-board-plan.ts +129 -0
- package/scripts/run/board/run-board-read.ts +62 -0
- package/scripts/run/board/run-board-render-legend.ts +82 -0
- package/scripts/run/board/run-board-render-notes.ts +77 -0
- package/scripts/run/board/run-board-render-slot.ts +50 -0
- package/scripts/run/board/run-board-render.ts +407 -0
- package/scripts/run/board/run-board-scope.ts +17 -0
- package/scripts/run/board/run-board-screen.ts +43 -0
- package/scripts/run/board/run-board-span.ts +66 -0
- package/scripts/run/board/run-board-spin.ts +115 -0
- package/scripts/run/board/run-board-state.ts +113 -0
- package/scripts/run/board/run-board-status.ts +279 -0
- package/scripts/run/board/run-board-tick.ts +210 -0
- package/scripts/run/board/run-board-track.ts +22 -0
- package/scripts/run/board/run-board-usage-read.ts +255 -0
- package/scripts/run/board/run-board-usage-rusage.ts +124 -0
- package/scripts/run/board/run-board-usage-text.ts +80 -0
- package/scripts/run/board/run-board-usage.ts +165 -0
- package/scripts/run/carry/run-carry-added.ts +62 -0
- package/scripts/run/carry/run-carry-args.ts +25 -22
- package/scripts/run/carry/run-carry-change.ts +1 -1
- package/scripts/run/carry/run-carry-cli.ts +71 -48
- package/scripts/run/carry/run-carry-conversation.ts +6 -7
- package/scripts/run/carry/run-carry-ended.ts +85 -0
- package/scripts/run/carry/run-carry-reclaim.ts +1 -1
- package/scripts/run/carry/run-carry-stash.ts +3 -2
- package/scripts/run/carry/run-carry-streak.ts +8 -10
- package/scripts/run/carry/run-carry.ts +85 -89
- package/scripts/run/cut/run-cut-args.ts +7 -7
- package/scripts/run/cut/run-cut-cli.ts +68 -37
- package/scripts/run/cut/run-cut-handoff.ts +15 -15
- package/scripts/run/cut/run-cut-report.ts +37 -16
- package/scripts/run/cut/run-cut.ts +63 -77
- package/scripts/run/detached-launch.ts +35 -50
- package/scripts/run/entry/run-entry-cli.ts +48 -27
- package/scripts/run/entry/run-entry-stop.ts +7 -9
- package/scripts/run/entry/run-entry.ts +5 -6
- package/scripts/run/event/run-event-cli.ts +5 -6
- package/scripts/run/event/run-event-filed.ts +69 -0
- package/scripts/run/event/run-event-follow.ts +3 -3
- package/scripts/run/event/run-event-plan.ts +38 -0
- package/scripts/run/event/run-event-render.ts +10 -4
- package/scripts/run/event/run-event-scope.ts +47 -18
- package/scripts/run/event/run-event-stream-emit.ts +64 -11
- package/scripts/run/event/run-event-stream.ts +172 -43
- package/scripts/run/event/run-event-watch.ts +4 -6
- package/scripts/run/hold/run-hold-cli.ts +65 -62
- package/scripts/run/hold/run-hold.ts +88 -46
- package/scripts/run/merge/run-merge-cli.ts +116 -77
- package/scripts/run/merge/run-merge-collect.ts +107 -0
- package/scripts/run/merge/run-merge-steps.ts +112 -65
- package/scripts/run/merge/run-merge-token.ts +30 -0
- package/scripts/run/merge/run-merge.ts +31 -22
- package/scripts/run/progress/run-progress-args.ts +4 -4
- package/scripts/run/progress/run-progress-cli.ts +39 -50
- package/scripts/run/progress/run-progress-clock.ts +25 -32
- package/scripts/run/progress/run-progress-config.ts +6 -9
- package/scripts/run/progress/run-progress-read.ts +9 -10
- package/scripts/run/progress/run-progress.ts +48 -53
- package/scripts/run/review/run-review-cli.ts +6 -6
- package/scripts/run/review/run-review-steps.ts +6 -6
- package/scripts/run/review/run-review.ts +9 -11
- package/scripts/run/run-cli-fault.ts +29 -0
- package/scripts/run/run-ending-cli.ts +3 -3
- package/scripts/run/run-ending.ts +10 -14
- package/scripts/run/run-halfrun-resume.ts +6 -8
- package/scripts/run/run-headless.ts +25 -12
- package/scripts/run/run-invocation.ts +17 -22
- package/scripts/run/run-label.ts +7 -5
- package/scripts/run/run-liveness-cli.ts +19 -6
- package/scripts/run/run-liveness.ts +27 -38
- package/scripts/run/run-next-cli.ts +5 -9
- package/scripts/run/run-next.ts +4 -5
- package/scripts/run/run-parent-cut-hook.ts +10 -12
- package/scripts/run/run-preflight.ts +25 -29
- package/scripts/run/run-prep-cli.ts +17 -13
- package/scripts/run/run-prep-locate.ts +4 -5
- package/scripts/run/run-prep.ts +7 -10
- package/scripts/run/run-prrun-resume.ts +2 -2
- package/scripts/run/run-report-cli.ts +4 -4
- package/scripts/run/run-report.ts +9 -14
- package/scripts/run/run-retrospective.ts +3 -3
- package/scripts/run/run-section.ts +42 -0
- package/scripts/run/run-stage-read.ts +2 -2
- package/scripts/run/run-stage.ts +6 -4
- package/scripts/run/run-status-cli.ts +7 -5
- package/scripts/run/run-status.ts +6 -7
- package/scripts/run/run-step-cli.ts +13 -15
- package/scripts/run/run-step.ts +62 -48
- package/scripts/run/run-stop-notify.ts +7 -8
- package/scripts/run/run-stranded-cli.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +4 -4
- package/scripts/run/run-stranded.ts +11 -13
- package/scripts/run/run-tail-cli.ts +15 -16
- package/scripts/run/run-tail.ts +14 -33
- package/scripts/run/run-watcher-guard-cli.ts +3 -4
- package/scripts/run/run-watcher-guard.ts +11 -12
- package/scripts/run/run-watcher-hook.ts +6 -12
- package/scripts/run/ship/run-ship-cli.ts +67 -33
- package/scripts/run/ship/run-ship-detach.ts +15 -13
- package/scripts/run/ship/run-ship-lock.ts +1 -1
- package/scripts/run/ship/run-ship-next.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
- package/scripts/run/ship/run-ship-preflight.ts +10 -11
- package/scripts/run/ship/run-ship-probe.ts +4 -4
- package/scripts/run/ship/run-ship-return.ts +1 -1
- package/scripts/run/ship/run-ship-review-steps.ts +43 -24
- package/scripts/run/ship/run-ship-review.ts +12 -14
- package/scripts/run/ship/run-ship-scoped.ts +15 -6
- package/scripts/run/ship/run-ship-stage.ts +80 -26
- package/scripts/run/ship/run-ship-steps.ts +26 -16
- package/scripts/run/ship/run-ship-stop-text.ts +4 -2
- package/scripts/run/ship/run-ship-sync.ts +9 -8
- package/scripts/run/ship/run-ship.ts +17 -32
- package/scripts/run/tidy/run-tidy-cli.ts +9 -5
- package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
- package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
- package/scripts/run/tidy/run-tidy.ts +4 -3
- package/scripts/run/wake/run-wake-cli.ts +27 -33
- package/scripts/run/wake/run-wake-describe.ts +76 -29
- package/scripts/run/wake/run-wake-driver.ts +14 -14
- package/scripts/run/wake/run-wake-handoff.ts +6 -6
- package/scripts/run/wake/run-wake-loop.ts +13 -21
- package/scripts/run/wake/run-wake-restart.ts +4 -5
- package/scripts/run/wake/run-wake-session.ts +23 -27
- package/scripts/run/wake/run-wake.ts +57 -328
- package/scripts/safe-chain/ci-installer-pin.ts +3 -3
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -2
- package/scripts/security/security-audit-logic.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +1 -1
- package/scripts/security/security-audit-provision.ts +2 -2
- package/scripts/security/security-audit.ts +5 -5
- package/scripts/security/security-updates-logic.ts +2 -3
- package/scripts/security/security-updates.ts +2 -4
- package/scripts/self-sync-guard/index.ts +1 -1
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
- package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
- package/scripts/sonar/sonar-hotspots.ts +1 -1
- package/scripts/sonar/sonar-new-code-cli.ts +1 -1
- package/scripts/sonar/sonar-new-code.ts +1 -1
- package/scripts/sonar/sonar-project.ts +1 -1
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +3 -3
- package/scripts/sync/directory-copy-guard.ts +2 -3
- package/scripts/sync/managed-config-scope-cli.ts +1 -2
- package/scripts/sync/managed-config-scope.ts +4 -4
- package/scripts/sync/plugin-skill-directories.ts +2 -2
- package/scripts/sync/reconcile-templates.ts +17 -8
- package/scripts/sync/removed-skill-manifest.ts +2 -3
- package/scripts/sync/sync-ai-files.ts +7 -7
- package/scripts/sync/sync-configs.ts +30 -3
- package/scripts/sync/sync-hook-safety.ts +2 -2
- package/scripts/sync/sync.ts +23 -10
- package/scripts/sync/synced-paths.ts +2 -1
- package/scripts/sync/workflow-pin-logic.ts +1 -1
- package/scripts/test/test-declared-changed.ts +4 -4
- package/scripts/test/test-declared-logic.ts +2 -3
- package/scripts/test/test-declared-match.ts +25 -4
- package/scripts/test/test-declared.ts +26 -9
- package/scripts/test/test-red-commit.ts +3 -2
- package/scripts/test/test-red-logic.ts +7 -14
- package/scripts/test/test-red.ts +12 -47
- package/scripts/test/test-related-scope.ts +2 -3
- package/scripts/test/test-related.ts +3 -3
- package/scripts/test/test-type-logic.ts +1 -2
- package/scripts/test/test-unit-guard.ts +13 -17
- package/scripts/test/unit-worker-share.ts +7 -8
- package/scripts/time-runtime/time-agent-bundles.ts +2 -4
- package/scripts/time-runtime/time-background.ts +17 -21
- package/scripts/time-runtime/time-batch-guard.ts +67 -342
- package/scripts/time-runtime/time-bundle-call.ts +26 -28
- package/scripts/time-runtime/time-bundles.ts +11 -12
- package/scripts/time-runtime/time-call-identity.ts +1 -1
- package/scripts/time-runtime/time-command-key.ts +2 -2
- package/scripts/time-runtime/time-density-hook.ts +8 -11
- package/scripts/time-runtime/time-density.ts +5 -5
- package/scripts/time-runtime/time-followup-stage.ts +7 -7
- package/scripts/time-runtime/time-format.ts +5 -5
- package/scripts/time-runtime/time-hook-transcript.ts +3 -3
- package/scripts/time-runtime/time-instant.ts +1 -1
- package/scripts/time-runtime/time-markers.ts +15 -19
- package/scripts/time-runtime/time-phase-names.ts +3 -3
- package/scripts/time-runtime/time-reported-failure.ts +15 -19
- package/scripts/time-runtime/time-round-trips.ts +20 -23
- package/scripts/time-runtime/time-shell.ts +8 -8
- package/scripts/time-runtime/time-single-check.ts +1 -2
- package/scripts/time-runtime/time-spans.ts +35 -40
- package/scripts/time-runtime/time-tool-call.ts +15 -16
- package/scripts/time-runtime/time-transcript-line.ts +53 -34
- package/scripts/time-runtime/time-writes.ts +5 -5
- package/scripts/ui/ui-routes-cli.ts +1 -2
- package/scripts/ui/ui-routes.ts +1 -2
- package/scripts/version/bump-version.ts +1 -1
- package/scripts/version/fresh-metadata-cache.ts +2 -2
- package/scripts/version/latest-corepack.ts +129 -98
- package/scripts/version/latest-lane-guard.ts +1 -1
- package/scripts/version/latest-scope-cli.ts +2 -2
- package/scripts/version/latest-stamp.ts +1 -2
- package/scripts/version/latest-update.ts +2 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/package-manager-version.ts +18 -0
- package/scripts/version/publishable-range-check.ts +2 -1
- package/scripts/version/publishable-range.ts +1 -1
- package/scripts/version/release-age.ts +11 -11
- package/scripts/version/release-hold.ts +2 -2
- package/scripts/version/safe-chain-version-update.ts +3 -3
- package/scripts/version/version-check-logic.ts +2 -3
- package/scripts/version/version-check.ts +1 -2
- package/scripts/version/version-command-config.ts +2 -2
- package/scripts/version/version-commands.ts +3 -3
- package/scripts/version/version-remote.ts +4 -4
- package/scripts/version/version-targets.ts +2 -2
- package/templates/gitignore +7 -0
- package/templates/workflows/github-release.yml +4 -0
- package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
- package/dist/hooks/chunk-RKUAD3I6.js +0 -90
- package/dist/hooks/chunk-WPALEIRX.js +0 -18
- package/scripts/backlog/backlog-restructure.ts +0 -152
- package/scripts/rules/issue-fold-rule.ts +0 -72
- package/scripts/rules/wip-cap.ts +0 -63
- package/scripts/run/run-issue-number.ts +0 -19
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ENV_FILE_NAME
|
|
3
|
-
|
|
2
|
+
ENV_FILE_NAME,
|
|
3
|
+
cost_transcript,
|
|
4
|
+
json_value,
|
|
5
|
+
process_identity,
|
|
6
|
+
process_owner_schema,
|
|
7
|
+
run_carry,
|
|
8
|
+
time_instant
|
|
9
|
+
} from "./chunk-NZN2UFI6.js";
|
|
4
10
|
import {
|
|
5
11
|
PLATFORM_TEMP_ROOT,
|
|
6
12
|
PROBE_TIMEOUT_MS,
|
|
7
13
|
stamp_file
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
|
|
10
|
-
// scripts/lib/json-value.ts
|
|
11
|
-
function parse_or_undefined(text) {
|
|
12
|
-
try {
|
|
13
|
-
return JSON.parse(text);
|
|
14
|
-
} catch {
|
|
15
|
-
return void 0;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function is_record(value) {
|
|
19
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20
|
-
}
|
|
21
|
-
var json_value = { parse_or_undefined, is_record };
|
|
14
|
+
} from "./chunk-NEC4AT4Z.js";
|
|
22
15
|
|
|
23
16
|
// scripts/cost-runtime/cost-blocks.ts
|
|
24
17
|
import { z } from "zod";
|
|
@@ -151,6 +144,17 @@ var CSPELL_CACHE_FLAGS = content_cache_flags(CSPELL_CACHE_FILE);
|
|
|
151
144
|
|
|
152
145
|
// scripts/josh/josh-commands-backlog.ts
|
|
153
146
|
var BACKLOG_COMMANDS = {
|
|
147
|
+
// Started from a terminal: the `backlogrun` keyword's launcher, and the board.
|
|
148
|
+
backlogrun: {
|
|
149
|
+
script: "scripts/backlog/backlogrun-cli.ts",
|
|
150
|
+
description: "Start a backlogrun in the background and show its board; with one already running, only show the board",
|
|
151
|
+
category: "AI tools",
|
|
152
|
+
reference: [
|
|
153
|
+
"[#<n>...] [--only] [--max <n>] [--idle <minutes>] [--agent claude|codex]",
|
|
154
|
+
"developer",
|
|
155
|
+
["files", "network", "processes"]
|
|
156
|
+
]
|
|
157
|
+
},
|
|
154
158
|
"backlog:next": {
|
|
155
159
|
script: "scripts/backlog/backlog-next.ts",
|
|
156
160
|
description: "Order the whole opted-in backlog: auto-ok issues and the descendants of auto-ok epics, transitively through nested epics",
|
|
@@ -181,7 +185,7 @@ var BACKLOG_COMMANDS = {
|
|
|
181
185
|
},
|
|
182
186
|
"backlog:stalled": {
|
|
183
187
|
script: "scripts/backlog/backlog-stalled-cli.ts",
|
|
184
|
-
// A stall sends one Telegram warning
|
|
188
|
+
// A stall sends one Telegram warning. The `Stop` hook calls the detector
|
|
185
189
|
// directly, so this flag costs only the manual command its in-process dispatch.
|
|
186
190
|
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
187
191
|
description: "Report whether ready backlog work is sitting undispatched with a free lane and no recent dispatch",
|
|
@@ -276,7 +280,7 @@ var ISSUE_COMMANDS = {
|
|
|
276
280
|
},
|
|
277
281
|
"defect:rate": {
|
|
278
282
|
script: "scripts/issue/defect-rate-cli.ts",
|
|
279
|
-
description: "Print the defect rate of merged work: defects filed per
|
|
283
|
+
description: "Print the defect rate of merged work: defects filed per enhancement completed",
|
|
280
284
|
category: "AI tools",
|
|
281
285
|
reference: ["[--days <n>]", "automation", ["network"]]
|
|
282
286
|
},
|
|
@@ -306,13 +310,19 @@ var ISSUE_COMMANDS = {
|
|
|
306
310
|
},
|
|
307
311
|
"issue:file": {
|
|
308
312
|
script: "scripts/issue/issue-file-cli.ts",
|
|
309
|
-
description: "File an Issue with every filing step: lint, Origin, WIP cap, duplicate scout, labels, then epic:bundle",
|
|
313
|
+
description: "File an Issue with every filing step: lint, Origin, fold, WIP cap, duplicate scout, labels, then epic:bundle",
|
|
310
314
|
category: "AI tools",
|
|
311
315
|
reference: [
|
|
312
|
-
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok]",
|
|
316
|
+
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok] [--requested] [--release]",
|
|
313
317
|
"automation",
|
|
314
318
|
["network"]
|
|
315
319
|
]
|
|
320
|
+
},
|
|
321
|
+
"issue:release": {
|
|
322
|
+
script: "scripts/issue/issue-release-cli.ts",
|
|
323
|
+
description: "Link an Issue to the repository's open release Issue as its blocker, filing one when none is open",
|
|
324
|
+
category: "AI tools",
|
|
325
|
+
reference: ["<issue>", "automation", ["network"]]
|
|
316
326
|
}
|
|
317
327
|
};
|
|
318
328
|
|
|
@@ -348,7 +358,7 @@ var LANE_COMMANDS = {
|
|
|
348
358
|
},
|
|
349
359
|
"lane:prune": {
|
|
350
360
|
...LANE_ARGUMENTS,
|
|
351
|
-
description: "Close every lane an interruption left without its work tree",
|
|
361
|
+
description: "Close every lane an interruption left without its work tree, then sweep unregistered leftovers under the lanes root",
|
|
352
362
|
category: "AI tools",
|
|
353
363
|
reference: ["", "automation", ["files", "git"]],
|
|
354
364
|
default_script_arguments: ["prune"]
|
|
@@ -380,18 +390,27 @@ var LANE_COMMANDS = {
|
|
|
380
390
|
category: "AI tools",
|
|
381
391
|
reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
|
|
382
392
|
},
|
|
383
|
-
//
|
|
393
|
+
// A live run's lane limit: `.env` is read so the bare form reports the
|
|
394
|
+
// `JOSH_LANE_LIMIT` a person set there when no override stands.
|
|
395
|
+
"lane:limit": {
|
|
396
|
+
script: "scripts/lane/lane-limit-cli.ts",
|
|
397
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
398
|
+
description: "Change a live backlogrun\u2019s lane limit without stopping it, or print the limit, lanes in use and free lanes",
|
|
399
|
+
category: "AI tools",
|
|
400
|
+
reference: ["[<limit>] [--reset]", "developer", ["files"]]
|
|
401
|
+
},
|
|
402
|
+
// The lane-limit measurement: `.env` is read so `lane:stats` labels the row
|
|
384
403
|
// with the `JOSH_LANE_LIMIT` a person set there.
|
|
385
404
|
"lane:sample": {
|
|
386
405
|
...MEASURE_ARGUMENTS,
|
|
387
|
-
description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger",
|
|
406
|
+
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",
|
|
388
407
|
category: "AI tools",
|
|
389
408
|
reference: ["[--every <seconds>]", "maintainer", ["files"]],
|
|
390
409
|
default_script_arguments: ["sample"]
|
|
391
410
|
},
|
|
392
411
|
"lane:stats": {
|
|
393
412
|
...MEASURE_ARGUMENTS,
|
|
394
|
-
description: "Print one table row of lane throughput, gate duration and machine load over a period",
|
|
413
|
+
description: "Print one table row of lane throughput, gate duration and machine load over a period, and the per-stage durations of a lane under it",
|
|
395
414
|
category: "AI tools",
|
|
396
415
|
reference: ["--period <days> [--limit <lane-limit>]", "maintainer", ["none"]],
|
|
397
416
|
default_script_arguments: ["stats"]
|
|
@@ -423,12 +442,18 @@ var RUN_COMMANDS = {
|
|
|
423
442
|
"run:carry": {
|
|
424
443
|
script: "scripts/run/carry/run-carry-cli.ts",
|
|
425
444
|
// `--stopped` sends the stop confirmation, so the Telegram credentials come from `.env` as for
|
|
426
|
-
// `run:wake` below
|
|
445
|
+
// `run:wake` below.
|
|
427
446
|
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
428
447
|
description: "Carry one invocation\u2019s budget across its own session cuts",
|
|
429
448
|
category: "AI tools",
|
|
430
449
|
reference: ["<operation> [arguments...]", "automation", ["files"]]
|
|
431
450
|
},
|
|
451
|
+
"run:add": {
|
|
452
|
+
script: "scripts/run/add/run-add-cli.ts",
|
|
453
|
+
description: "Add issues to a live backlogrun, ahead of the queue unless --no-priority",
|
|
454
|
+
category: "AI tools",
|
|
455
|
+
reference: ["<issue...> [--no-priority]", "automation", ["network", "files"]]
|
|
456
|
+
},
|
|
432
457
|
"run:wake": {
|
|
433
458
|
script: "scripts/run/wake/run-wake-cli.ts",
|
|
434
459
|
// `.env` rather than the ambient environment:
|
|
@@ -467,18 +492,26 @@ var RUN_COMMANDS = {
|
|
|
467
492
|
["files"]
|
|
468
493
|
]
|
|
469
494
|
},
|
|
495
|
+
"run:board": {
|
|
496
|
+
script: "scripts/run/board/run-board-cli.ts",
|
|
497
|
+
// `--every` pushes its frame as a Telegram, so the credentials come from `.env` as for `run:carry`.
|
|
498
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
499
|
+
description: "Draw a live board of the running backlogrun, redrawn every second",
|
|
500
|
+
category: "AI tools",
|
|
501
|
+
reference: ["[--once | --chat | --every <minutes>]", "automation", ["files", "network"]]
|
|
502
|
+
},
|
|
470
503
|
"run:prep": {
|
|
471
504
|
script: "scripts/run/run-prep-cli.ts",
|
|
472
505
|
description: "Bundle a run\u2019s pre-edit reads: body, comments, state, dependency scope",
|
|
473
506
|
category: "AI tools",
|
|
474
507
|
reference: ["<issue>", "automation", ["network"]]
|
|
475
508
|
},
|
|
476
|
-
// The entry sequence a lane opened on, folded into one call
|
|
509
|
+
// The entry sequence a lane opened on, folded into one call: claim the tree,
|
|
477
510
|
// read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
|
|
478
511
|
// `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
|
|
479
512
|
"run:entry": {
|
|
480
513
|
script: "scripts/run/entry/run-entry-cli.ts",
|
|
481
|
-
// A `busy` hold or an `over` budget sends the stop confirmation
|
|
514
|
+
// A `busy` hold or an `over` budget sends the stop confirmation.
|
|
482
515
|
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
483
516
|
description: "Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step",
|
|
484
517
|
category: "AI tools",
|
|
@@ -581,12 +614,12 @@ var AI_COMMANDS = {
|
|
|
581
614
|
reference: ["[options]", "maintainer", ["none"]],
|
|
582
615
|
// Kit-only: it measures kit's own development runs and its report modules live under the
|
|
583
616
|
// undistributed `scripts/time/`, so it means nothing in a consumer project and is dropped from a
|
|
584
|
-
// consumer's help
|
|
617
|
+
// consumer's help. The runtime analysis hooks and guards rely on stays
|
|
585
618
|
// distributed under `scripts/time-runtime/`.
|
|
586
619
|
is_kit_only: true
|
|
587
620
|
},
|
|
588
621
|
// The tool-calls-per-round-trip density the batching guard is measured on, aggregated across the
|
|
589
|
-
// recent lane sessions
|
|
622
|
+
// recent lane sessions. Kit-only for the same reason `time` is: it reads
|
|
590
623
|
// kit's own lane transcripts and means nothing in a consumer project.
|
|
591
624
|
"time:density": {
|
|
592
625
|
script: "scripts/time/time-density-cli.ts",
|
|
@@ -602,7 +635,7 @@ var AI_COMMANDS = {
|
|
|
602
635
|
reference: ["", "maintainer", ["none"]],
|
|
603
636
|
// Kit-only: it reads kit's own development run — the transcript store, the review ledger and the
|
|
604
637
|
// run event stream — so it means nothing in a consumer project and is dropped from a consumer's
|
|
605
|
-
// help
|
|
638
|
+
// help, through the same declaration `josh time` uses for the same reason.
|
|
606
639
|
is_kit_only: true
|
|
607
640
|
},
|
|
608
641
|
"review:brief": {
|
|
@@ -654,7 +687,7 @@ var AI_COMMANDS = {
|
|
|
654
687
|
category: "AI tools",
|
|
655
688
|
reference: ["[--join]", "automation", ["processes", "files"]]
|
|
656
689
|
},
|
|
657
|
-
// The post-merge sequence a run closed on, folded into one call
|
|
690
|
+
// The post-merge sequence a run closed on, folded into one call: commit the
|
|
658
691
|
// observation ledger, read the completion citations and decide the release scope. `observations:flush`,
|
|
659
692
|
// `issue:cite` and `release:scope` were three round trips re-billing the run's full context each.
|
|
660
693
|
"run:tail": {
|
|
@@ -663,7 +696,7 @@ var AI_COMMANDS = {
|
|
|
663
696
|
category: "AI tools",
|
|
664
697
|
reference: ["[<issue> ...]", "automation", ["git", "network"]]
|
|
665
698
|
},
|
|
666
|
-
// The commit-to-report region a run ships a change on, folded into one call
|
|
699
|
+
// The commit-to-report region a run ships a change on, folded into one call:
|
|
667
700
|
// the gate, the commit/push/PR (`git -y`), the CI-wait merge (`followup`) and the report bookkeeping
|
|
668
701
|
// (`run:tail`) were four round trips re-billing the run's full context each. It stops at the first
|
|
669
702
|
// failed step and names it, so the run reads only the step to fix.
|
|
@@ -723,7 +756,7 @@ var AI_COMMANDS = {
|
|
|
723
756
|
category: "AI tools",
|
|
724
757
|
reference: ["[scenario...]", "maintainer", ["processes", "network"]],
|
|
725
758
|
// Kit-only: it replays kit's own distributed rules against real Claude sessions, so it means
|
|
726
|
-
// nothing in a consumer project and is dropped from a consumer's help
|
|
759
|
+
// nothing in a consumer project and is dropped from a consumer's help.
|
|
727
760
|
is_kit_only: true
|
|
728
761
|
}
|
|
729
762
|
};
|
|
@@ -739,186 +772,15 @@ var CLONE_COMMANDS = {
|
|
|
739
772
|
};
|
|
740
773
|
|
|
741
774
|
// scripts/gate/core-budget.ts
|
|
742
|
-
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
743
|
-
import { readdirSync as readdirSync2 } from "node:fs";
|
|
744
|
-
import { availableParallelism as availableParallelism2 } from "node:os";
|
|
745
|
-
import path3 from "node:path";
|
|
746
|
-
|
|
747
|
-
// scripts/josh/process-identity.ts
|
|
748
|
-
import { execFileSync, spawnSync } from "node:child_process";
|
|
749
775
|
import { randomUUID } from "node:crypto";
|
|
750
|
-
import {
|
|
751
|
-
import {
|
|
752
|
-
import
|
|
753
|
-
var PS_COMMAND = "/bin/ps";
|
|
754
|
-
var FORMAT_FLAG = "-o";
|
|
755
|
-
var START_TIME_FORMAT = "lstart=";
|
|
756
|
-
var PID_FLAG = "-p";
|
|
757
|
-
var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
|
|
758
|
-
var LIVENESS_SIGNAL = 0;
|
|
759
|
-
var LOWEST_REAL_PID = 1;
|
|
760
|
-
var PROC_START_FIELD_INDEX = 19;
|
|
761
|
-
var BEACON_SCHEME = "socket:";
|
|
762
|
-
var BEACON_SUFFIX = ".sock";
|
|
763
|
-
var BEACON_PREFIX = `josh-process-identity-${String(process.getuid?.() ?? "")}-`;
|
|
764
|
-
var BEACON_ID_LENGTH = 36;
|
|
765
|
-
var BEACON_ID_PATTERN = /^[\da-f-]+$/u;
|
|
766
|
-
var WINDOWS_PLATFORM = "win32";
|
|
767
|
-
var SOCKET_PROBE_SOURCE = "const net=require('node:net');const socket=net.createConnection(process.argv[1]);socket.once('connect',()=>process.exit(0));socket.once('error',()=>process.exit(1));socket.setTimeout(1000,()=>process.exit(1));";
|
|
768
|
-
var beacons = /* @__PURE__ */ new Map();
|
|
769
|
-
var exit_cleanup = { is_registered: false };
|
|
770
|
-
function is_live_pid(pid) {
|
|
771
|
-
if (pid < LOWEST_REAL_PID) return false;
|
|
772
|
-
try {
|
|
773
|
-
process.kill(pid, LIVENESS_SIGNAL);
|
|
774
|
-
return true;
|
|
775
|
-
} catch {
|
|
776
|
-
return false;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
function read_proc_start(pid) {
|
|
780
|
-
try {
|
|
781
|
-
const stat = readFileSync(`/proc/${String(pid)}/stat`, "utf8");
|
|
782
|
-
const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
|
|
783
|
-
const start = fields[PROC_START_FIELD_INDEX];
|
|
784
|
-
return start === void 0 ? void 0 : `proc:${start}`;
|
|
785
|
-
} catch {
|
|
786
|
-
return void 0;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
function read_ps_start(pid) {
|
|
790
|
-
try {
|
|
791
|
-
const printed = execFileSync(
|
|
792
|
-
PS_COMMAND,
|
|
793
|
-
[FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
|
|
794
|
-
{
|
|
795
|
-
encoding: "utf8",
|
|
796
|
-
timeout: PROBE_TIMEOUT_MS,
|
|
797
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
798
|
-
env: PROBE_ENVIRONMENT
|
|
799
|
-
}
|
|
800
|
-
).trim();
|
|
801
|
-
return printed.length > 0 ? printed : void 0;
|
|
802
|
-
} catch {
|
|
803
|
-
return void 0;
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
var START_PROBES = { read_proc_start, read_ps_start };
|
|
807
|
-
function safe_probe(probe, pid) {
|
|
808
|
-
try {
|
|
809
|
-
return probe(pid);
|
|
810
|
-
} catch {
|
|
811
|
-
return void 0;
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
function read_start(pid, probes = START_PROBES) {
|
|
815
|
-
return safe_probe(probes.read_proc_start, pid) ?? safe_probe(probes.read_ps_start, pid);
|
|
816
|
-
}
|
|
817
|
-
function close_beacon(token) {
|
|
818
|
-
const server = beacons.get(token);
|
|
819
|
-
if (server === void 0) return;
|
|
820
|
-
beacons.delete(token);
|
|
821
|
-
server.close();
|
|
822
|
-
rmSync(token.slice(BEACON_SCHEME.length), { force: true });
|
|
823
|
-
}
|
|
824
|
-
function close_beacons() {
|
|
825
|
-
for (const token of beacons.keys()) close_beacon(token);
|
|
826
|
-
}
|
|
827
|
-
function ensure_exit_cleanup() {
|
|
828
|
-
if (exit_cleanup.is_registered) return;
|
|
829
|
-
exit_cleanup.is_registered = true;
|
|
830
|
-
process.once("exit", close_beacons);
|
|
831
|
-
}
|
|
832
|
-
function ignore_beacon_error() {
|
|
833
|
-
}
|
|
834
|
-
function bind_beacon(target) {
|
|
835
|
-
return createServer().on("error", ignore_beacon_error).listen(target);
|
|
836
|
-
}
|
|
837
|
-
function try_bind_beacon(bind, target) {
|
|
838
|
-
try {
|
|
839
|
-
const server = bind(target);
|
|
840
|
-
return server.listening ? server : void 0;
|
|
841
|
-
} catch {
|
|
842
|
-
return void 0;
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
function open_beacon(bind = bind_beacon) {
|
|
846
|
-
const target = path.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
|
|
847
|
-
const token = `${BEACON_SCHEME}${target}`;
|
|
848
|
-
const server = try_bind_beacon(bind, target);
|
|
849
|
-
if (server === void 0) return void 0;
|
|
850
|
-
server.unref();
|
|
851
|
-
beacons.set(token, server);
|
|
852
|
-
ensure_exit_cleanup();
|
|
853
|
-
return token;
|
|
854
|
-
}
|
|
855
|
-
function resolve_own_start(probes = START_PROBES, platform = process.platform) {
|
|
856
|
-
const start = read_start(process.pid, probes);
|
|
857
|
-
if (start !== void 0 || platform === WINDOWS_PLATFORM) return start;
|
|
858
|
-
return open_beacon();
|
|
859
|
-
}
|
|
860
|
-
function is_valid_beacon_name(name) {
|
|
861
|
-
if (!name.startsWith(BEACON_PREFIX) || !name.endsWith(BEACON_SUFFIX)) return false;
|
|
862
|
-
const id = name.slice(BEACON_PREFIX.length, -BEACON_SUFFIX.length);
|
|
863
|
-
return id.length === BEACON_ID_LENGTH && BEACON_ID_PATTERN.test(id);
|
|
864
|
-
}
|
|
865
|
-
function beacon_target(token) {
|
|
866
|
-
if (!token.startsWith(BEACON_SCHEME)) return void 0;
|
|
867
|
-
const target = token.slice(BEACON_SCHEME.length);
|
|
868
|
-
if (path.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
|
|
869
|
-
return is_valid_beacon_name(path.basename(target)) ? target : void 0;
|
|
870
|
-
}
|
|
871
|
-
function is_live_beacon(target) {
|
|
872
|
-
return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
|
|
873
|
-
stdio: "ignore",
|
|
874
|
-
timeout: PROBE_TIMEOUT_MS
|
|
875
|
-
}).status === 0;
|
|
876
|
-
}
|
|
877
|
-
function has_matching_start(pid, recorded_start, read) {
|
|
878
|
-
const observed = read(pid);
|
|
879
|
-
return observed === void 0 ? void 0 : observed === recorded_start;
|
|
880
|
-
}
|
|
881
|
-
function matches_recorded_start(pid, recorded_start, read) {
|
|
882
|
-
const target = beacon_target(recorded_start);
|
|
883
|
-
return target === void 0 ? has_matching_start(pid, recorded_start, read) : is_live_beacon(target);
|
|
884
|
-
}
|
|
885
|
-
var own_probe = /* @__PURE__ */ new Map();
|
|
886
|
-
function own_start() {
|
|
887
|
-
if (!own_probe.has(process.pid)) own_probe.set(process.pid, resolve_own_start());
|
|
888
|
-
return own_probe.get(process.pid);
|
|
889
|
-
}
|
|
890
|
-
function own_fields() {
|
|
891
|
-
const start = own_start();
|
|
892
|
-
return { pid: process.pid, ...start !== void 0 && { process_start: start } };
|
|
893
|
-
}
|
|
894
|
-
function is_same_process(pid, recorded_start, read = read_start) {
|
|
895
|
-
if (pid === void 0 || !is_live_pid(pid)) return false;
|
|
896
|
-
if (recorded_start === void 0) return void 0;
|
|
897
|
-
return matches_recorded_start(pid, recorded_start, read);
|
|
898
|
-
}
|
|
899
|
-
function is_own_process(pid, recorded_start) {
|
|
900
|
-
return pid === process.pid && recorded_start === own_start();
|
|
901
|
-
}
|
|
902
|
-
var process_identity = {
|
|
903
|
-
close_beacon,
|
|
904
|
-
is_live_pid,
|
|
905
|
-
is_own_process,
|
|
906
|
-
is_same_process,
|
|
907
|
-
open_beacon,
|
|
908
|
-
own_fields,
|
|
909
|
-
own_start,
|
|
910
|
-
read_start,
|
|
911
|
-
resolve_own_start
|
|
912
|
-
};
|
|
913
|
-
|
|
914
|
-
// scripts/josh/process-owner.ts
|
|
915
|
-
import { z as z2 } from "zod";
|
|
916
|
-
var process_owner_schema = z2.object({ pid: z2.number(), process_start: z2.string().optional() });
|
|
776
|
+
import { readdirSync as readdirSync2 } from "node:fs";
|
|
777
|
+
import { availableParallelism as availableParallelism3 } from "node:os";
|
|
778
|
+
import path2 from "node:path";
|
|
917
779
|
|
|
918
780
|
// scripts/test/unit-worker-share.ts
|
|
919
781
|
import { readdirSync } from "node:fs";
|
|
920
782
|
import { availableParallelism } from "node:os";
|
|
921
|
-
import
|
|
783
|
+
import path from "node:path";
|
|
922
784
|
var RUN_PREFIX = "josh-unit-running-";
|
|
923
785
|
var WORKER_FLAG = "--maxWorkers";
|
|
924
786
|
var WORKER_FLAGS = [WORKER_FLAG, "--max-workers"];
|
|
@@ -957,7 +819,7 @@ function is_marker_live(source) {
|
|
|
957
819
|
return false;
|
|
958
820
|
}
|
|
959
821
|
function live_run_count(directory = PLATFORM_TEMP_ROOT) {
|
|
960
|
-
return marker_files(directory).filter((name) => is_marker_live(
|
|
822
|
+
return marker_files(directory).filter((name) => is_marker_live(path.join(directory, name))).length;
|
|
961
823
|
}
|
|
962
824
|
var NESTED_KEY = "JOSH_UNIT_RUN_MARKED";
|
|
963
825
|
var NESTED_VALUE = "1";
|
|
@@ -980,22 +842,22 @@ function worker_arguments(vitest_arguments, share) {
|
|
|
980
842
|
if (vitest_arguments.some((argument) => is_worker_flag(argument))) return [];
|
|
981
843
|
return [`${WORKER_FLAG}=${String(share)}`];
|
|
982
844
|
}
|
|
983
|
-
function mark_run_started(
|
|
845
|
+
function mark_run_started(target2) {
|
|
984
846
|
try {
|
|
985
|
-
stamp_file.write_stamp(
|
|
847
|
+
stamp_file.write_stamp(target2, process_identity.own_fields());
|
|
986
848
|
} catch {
|
|
987
849
|
}
|
|
988
850
|
}
|
|
989
851
|
async function with_run_marker(run) {
|
|
990
852
|
if (is_nested_run()) return await run();
|
|
991
|
-
const
|
|
992
|
-
mark_run_started(
|
|
853
|
+
const target2 = marker_path();
|
|
854
|
+
mark_run_started(target2);
|
|
993
855
|
process.env[NESTED_KEY] = NESTED_VALUE;
|
|
994
856
|
try {
|
|
995
857
|
return await run();
|
|
996
858
|
} finally {
|
|
997
859
|
process.env[NESTED_KEY] = "";
|
|
998
|
-
stamp_file.remove_stamp(
|
|
860
|
+
stamp_file.remove_stamp(target2);
|
|
999
861
|
}
|
|
1000
862
|
}
|
|
1001
863
|
var unit_worker_share = {
|
|
@@ -1015,7 +877,243 @@ var unit_worker_share = {
|
|
|
1015
877
|
};
|
|
1016
878
|
|
|
1017
879
|
// scripts/gate/core-budget.ts
|
|
1018
|
-
import { z as
|
|
880
|
+
import { z as z2 } from "zod";
|
|
881
|
+
|
|
882
|
+
// scripts/gate/core-admission.ts
|
|
883
|
+
var MS_PER_SECOND = 1e3;
|
|
884
|
+
var RAMP_UP_MS = 3e4;
|
|
885
|
+
function compare_claim(left, right) {
|
|
886
|
+
const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
|
|
887
|
+
return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
|
|
888
|
+
}
|
|
889
|
+
function add_load(totals, reservation) {
|
|
890
|
+
totals.cores += reservation.weight;
|
|
891
|
+
totals.memory_mb += reservation.memory_mb ?? 0;
|
|
892
|
+
}
|
|
893
|
+
function exceeds(totals, budget) {
|
|
894
|
+
return totals.cores > budget.cores || totals.memory_mb > budget.memory_mb;
|
|
895
|
+
}
|
|
896
|
+
function admitted_keys(reservations, budget, memory_budget = Infinity) {
|
|
897
|
+
const limit = { cores: budget, memory_mb: memory_budget };
|
|
898
|
+
const totals = { cores: 0, memory_mb: 0 };
|
|
899
|
+
const admitted = /* @__PURE__ */ new Set();
|
|
900
|
+
for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
|
|
901
|
+
add_load(totals, entry.reservation);
|
|
902
|
+
if (index !== 0 && exceeds(totals, limit)) break;
|
|
903
|
+
admitted.add(entry.key);
|
|
904
|
+
}
|
|
905
|
+
return admitted;
|
|
906
|
+
}
|
|
907
|
+
function is_admitted(key, reservations, budget) {
|
|
908
|
+
return admitted_keys(reservations, budget.cores, budget.memory_mb).has(key);
|
|
909
|
+
}
|
|
910
|
+
function sum_load(reservations) {
|
|
911
|
+
const load = { cores: 0, memory_mb: 0 };
|
|
912
|
+
for (const entry of reservations) add_load(load, entry.reservation);
|
|
913
|
+
return load;
|
|
914
|
+
}
|
|
915
|
+
function is_ramped(reservation, now) {
|
|
916
|
+
const { admitted_at } = reservation;
|
|
917
|
+
return admitted_at !== void 0 && now - admitted_at >= RAMP_UP_MS;
|
|
918
|
+
}
|
|
919
|
+
function ledger_load(reservations, now) {
|
|
920
|
+
const admitted = reservations.filter((entry) => entry.reservation.admitted_at !== void 0);
|
|
921
|
+
const ramped = admitted.filter((entry) => is_ramped(entry.reservation, now));
|
|
922
|
+
return { cores: sum_load(admitted).cores, memory_mb: sum_load(ramped).memory_mb };
|
|
923
|
+
}
|
|
924
|
+
function total_weight(reservations) {
|
|
925
|
+
return sum_load(reservations).cores;
|
|
926
|
+
}
|
|
927
|
+
function admitted_load(reservations, budget) {
|
|
928
|
+
const admitted = admitted_keys(reservations, budget);
|
|
929
|
+
return total_weight(reservations.filter((entry) => admitted.has(entry.key)));
|
|
930
|
+
}
|
|
931
|
+
function describe_memory(ledger, budget) {
|
|
932
|
+
if (!Number.isFinite(budget.memory_mb)) return "";
|
|
933
|
+
return ` and ${String(Math.round(ledger.memory_mb))} MB of memory against ${String(Math.round(budget.memory_mb))} MB`;
|
|
934
|
+
}
|
|
935
|
+
function describe_overflow(admission) {
|
|
936
|
+
const { overflow } = admission;
|
|
937
|
+
if (overflow === void 0) return void 0;
|
|
938
|
+
const { ledger, budget } = overflow;
|
|
939
|
+
const waited = String(Math.round(overflow.waited_ms / MS_PER_SECOND));
|
|
940
|
+
const cores = `the ledger held ${String(ledger.cores)} cores against a budget of ${String(budget.cores)}`;
|
|
941
|
+
return `started past the core budget after ${waited}s \u2014 ${cores}${describe_memory(ledger, budget)}`;
|
|
942
|
+
}
|
|
943
|
+
var core_admission = {
|
|
944
|
+
RAMP_UP_MS,
|
|
945
|
+
admitted_keys,
|
|
946
|
+
admitted_load,
|
|
947
|
+
describe_overflow,
|
|
948
|
+
is_admitted,
|
|
949
|
+
ledger_load,
|
|
950
|
+
sum_load
|
|
951
|
+
};
|
|
952
|
+
|
|
953
|
+
// scripts/gate/machine-capacity.ts
|
|
954
|
+
import { readFile } from "node:fs/promises";
|
|
955
|
+
import { availableParallelism as availableParallelism2, cpus, totalmem } from "node:os";
|
|
956
|
+
import { execa } from "execa";
|
|
957
|
+
var SAMPLE_WINDOW_MS = 250;
|
|
958
|
+
var BASELINE_CORES = 2;
|
|
959
|
+
var BYTES_PER_MB = 1048576;
|
|
960
|
+
var KB_PER_MB = 1024;
|
|
961
|
+
var PERCENT = 100;
|
|
962
|
+
var MEMINFO_PATH = "/proc/meminfo";
|
|
963
|
+
var VMSTAT_PATH = "/proc/vmstat";
|
|
964
|
+
var LINUX_AVAILABLE = /^MemAvailable:\s+(?<kb>\d+) kB/mu;
|
|
965
|
+
var LINUX_SWAP_IN = /^pswpin (?<pages>\d+)$/mu;
|
|
966
|
+
var LINUX_SWAP_OUT = /^pswpout (?<pages>\d+)$/mu;
|
|
967
|
+
var PAGE_SIZE_ARGUMENTS = ["PAGESIZE"];
|
|
968
|
+
var LEVEL_NAME = "kern.memorystatus_level";
|
|
969
|
+
var SWAP_IN_NAME = "vm.compressor.swapper.swapins_total";
|
|
970
|
+
var SWAP_OUT_NAME = "vm.compressor.swapper.swapouts_total";
|
|
971
|
+
var PAGE_SIZE_NAME = "hw.pagesize";
|
|
972
|
+
var PRESSURE_NAME = "kern.memorystatus_vm_pressure_level";
|
|
973
|
+
var SYSCTL_ARGUMENTS = [LEVEL_NAME, SWAP_IN_NAME, SWAP_OUT_NAME, PAGE_SIZE_NAME, PRESSURE_NAME];
|
|
974
|
+
var SYSCTL_LINE = /^(?<name>[\w.]+): (?<value>\d+)$/gmu;
|
|
975
|
+
function cpu_times() {
|
|
976
|
+
let busy = 0;
|
|
977
|
+
let idle = 0;
|
|
978
|
+
for (const { times } of cpus()) {
|
|
979
|
+
busy += times.user + times.nice + times.sys + times.irq;
|
|
980
|
+
idle += times.idle;
|
|
981
|
+
}
|
|
982
|
+
return { busy, total: busy + idle };
|
|
983
|
+
}
|
|
984
|
+
function busy_share_between(before, after) {
|
|
985
|
+
const total = after.total - before.total;
|
|
986
|
+
if (total <= 0) return void 0;
|
|
987
|
+
return (after.busy - before.busy) / total;
|
|
988
|
+
}
|
|
989
|
+
function busy_cores_between(before, after, cores) {
|
|
990
|
+
const share = busy_share_between(before, after);
|
|
991
|
+
return share === void 0 ? void 0 : share * cores;
|
|
992
|
+
}
|
|
993
|
+
function sysctl_values(output) {
|
|
994
|
+
const values = [...output.matchAll(SYSCTL_LINE)].map(
|
|
995
|
+
(match) => [match.groups?.["name"] ?? "", Number(match.groups?.["value"])]
|
|
996
|
+
);
|
|
997
|
+
return new Map(values);
|
|
998
|
+
}
|
|
999
|
+
function swapped_pages(pages_in, pages_out) {
|
|
1000
|
+
return pages_in === void 0 || pages_out === void 0 ? void 0 : pages_in + pages_out;
|
|
1001
|
+
}
|
|
1002
|
+
function swapped_mb(pages, page_bytes) {
|
|
1003
|
+
if (pages === void 0 || page_bytes === void 0) return void 0;
|
|
1004
|
+
return pages * page_bytes / BYTES_PER_MB;
|
|
1005
|
+
}
|
|
1006
|
+
function swapped_between(from, to) {
|
|
1007
|
+
if (from === void 0 || to === void 0) return void 0;
|
|
1008
|
+
return Math.max(0, to - from);
|
|
1009
|
+
}
|
|
1010
|
+
function parse_darwin_memory(output, total_bytes) {
|
|
1011
|
+
const values = sysctl_values(output);
|
|
1012
|
+
const level = values.get(LEVEL_NAME);
|
|
1013
|
+
return {
|
|
1014
|
+
available_mb: level === void 0 ? void 0 : level / PERCENT * (total_bytes / BYTES_PER_MB),
|
|
1015
|
+
swapped_mb: swapped_mb(
|
|
1016
|
+
swapped_pages(values.get(SWAP_IN_NAME), values.get(SWAP_OUT_NAME)),
|
|
1017
|
+
values.get(PAGE_SIZE_NAME)
|
|
1018
|
+
),
|
|
1019
|
+
pressure_level: values.get(PRESSURE_NAME)
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
function parse_linux_available(meminfo) {
|
|
1023
|
+
const kb = LINUX_AVAILABLE.exec(meminfo)?.groups?.["kb"];
|
|
1024
|
+
return kb === void 0 ? void 0 : Number(kb) / KB_PER_MB;
|
|
1025
|
+
}
|
|
1026
|
+
function pages_of(pattern, vmstat) {
|
|
1027
|
+
const pages = pattern.exec(vmstat)?.groups?.["pages"];
|
|
1028
|
+
return pages === void 0 ? void 0 : Number(pages);
|
|
1029
|
+
}
|
|
1030
|
+
function parse_linux_swapped(vmstat, page_bytes) {
|
|
1031
|
+
const pages = swapped_pages(pages_of(LINUX_SWAP_IN, vmstat), pages_of(LINUX_SWAP_OUT, vmstat));
|
|
1032
|
+
return swapped_mb(pages, page_bytes);
|
|
1033
|
+
}
|
|
1034
|
+
async function settled(read) {
|
|
1035
|
+
try {
|
|
1036
|
+
return await read();
|
|
1037
|
+
} catch {
|
|
1038
|
+
return void 0;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
async function read_darwin_memory() {
|
|
1042
|
+
const { stdout } = await execa("sysctl", SYSCTL_ARGUMENTS, {
|
|
1043
|
+
reject: false,
|
|
1044
|
+
timeout: PROBE_TIMEOUT_MS
|
|
1045
|
+
});
|
|
1046
|
+
return parse_darwin_memory(stdout, totalmem());
|
|
1047
|
+
}
|
|
1048
|
+
async function read_page_size() {
|
|
1049
|
+
const { stdout } = await execa("getconf", PAGE_SIZE_ARGUMENTS, { timeout: PROBE_TIMEOUT_MS });
|
|
1050
|
+
return stdout;
|
|
1051
|
+
}
|
|
1052
|
+
async function read_linux_memory() {
|
|
1053
|
+
const [meminfo, vmstat, page_size] = await Promise.all([
|
|
1054
|
+
settled(async () => await readFile(MEMINFO_PATH, "utf8")),
|
|
1055
|
+
settled(async () => await readFile(VMSTAT_PATH, "utf8")),
|
|
1056
|
+
settled(read_page_size)
|
|
1057
|
+
]);
|
|
1058
|
+
const page_bytes = page_size === void 0 ? void 0 : Number(page_size);
|
|
1059
|
+
return {
|
|
1060
|
+
available_mb: meminfo === void 0 ? void 0 : parse_linux_available(meminfo),
|
|
1061
|
+
swapped_mb: vmstat === void 0 || page_bytes === void 0 ? void 0 : parse_linux_swapped(vmstat, page_bytes),
|
|
1062
|
+
pressure_level: void 0
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
var UNREAD_MEMORY = {
|
|
1066
|
+
available_mb: void 0,
|
|
1067
|
+
swapped_mb: void 0,
|
|
1068
|
+
pressure_level: void 0
|
|
1069
|
+
};
|
|
1070
|
+
async function read_memory() {
|
|
1071
|
+
if (process.platform === "darwin") return await settled(read_darwin_memory) ?? UNREAD_MEMORY;
|
|
1072
|
+
return process.platform === "linux" ? await read_linux_memory() : UNREAD_MEMORY;
|
|
1073
|
+
}
|
|
1074
|
+
function is_unquoted() {
|
|
1075
|
+
return cpus().length > 0 && cpus().length === availableParallelism2();
|
|
1076
|
+
}
|
|
1077
|
+
async function default_sleep(ms) {
|
|
1078
|
+
await new Promise((resolve) => {
|
|
1079
|
+
setTimeout(resolve, ms);
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
async function read_machine(sleep = default_sleep) {
|
|
1083
|
+
const before = cpu_times();
|
|
1084
|
+
const [memory] = await Promise.all([read_memory(), sleep(SAMPLE_WINDOW_MS)]);
|
|
1085
|
+
const busy_cores = is_unquoted() ? busy_cores_between(before, cpu_times(), cpus().length) : void 0;
|
|
1086
|
+
return { busy_cores, available_mb: memory.available_mb };
|
|
1087
|
+
}
|
|
1088
|
+
async function read_sample() {
|
|
1089
|
+
return { cpu: cpu_times(), memory: await read_memory(), total_mb: totalmem() / BYTES_PER_MB };
|
|
1090
|
+
}
|
|
1091
|
+
function external_cores(busy_cores, ledger_cores) {
|
|
1092
|
+
if (busy_cores === void 0) return 0;
|
|
1093
|
+
return Math.floor(Math.max(0, busy_cores - ledger_cores - BASELINE_CORES));
|
|
1094
|
+
}
|
|
1095
|
+
function machine_budget(cores, reading, ledger) {
|
|
1096
|
+
return {
|
|
1097
|
+
cores: cores - external_cores(reading.busy_cores, ledger.cores),
|
|
1098
|
+
memory_mb: reading.available_mb === void 0 ? Infinity : reading.available_mb + ledger.memory_mb
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
var machine_capacity = {
|
|
1102
|
+
BASELINE_CORES,
|
|
1103
|
+
busy_cores_between,
|
|
1104
|
+
busy_share_between,
|
|
1105
|
+
external_cores,
|
|
1106
|
+
machine_budget,
|
|
1107
|
+
parse_darwin_memory,
|
|
1108
|
+
parse_linux_available,
|
|
1109
|
+
parse_linux_swapped,
|
|
1110
|
+
read_machine,
|
|
1111
|
+
read_memory,
|
|
1112
|
+
read_sample,
|
|
1113
|
+
swapped_between
|
|
1114
|
+
};
|
|
1115
|
+
|
|
1116
|
+
// scripts/gate/core-budget.ts
|
|
1019
1117
|
var RESERVED_PREFIX = "josh-core-reserved-";
|
|
1020
1118
|
var RESERVED_SUFFIX = ".json";
|
|
1021
1119
|
var POLL_INTERVAL_MS = 50;
|
|
@@ -1027,11 +1125,20 @@ var CORE_WEIGHTS = {
|
|
|
1027
1125
|
spell_check: 1,
|
|
1028
1126
|
eslint_scan: 1
|
|
1029
1127
|
};
|
|
1128
|
+
var MEMORY_MB = {
|
|
1129
|
+
lint: 2400,
|
|
1130
|
+
type_check: 1300,
|
|
1131
|
+
spell_check: 350,
|
|
1132
|
+
eslint_scan: 2400,
|
|
1133
|
+
unit_worker: 350
|
|
1134
|
+
};
|
|
1030
1135
|
var HELD_KEY = "JOSH_CORE_RESERVED";
|
|
1031
1136
|
var HELD_VALUE = "1";
|
|
1032
1137
|
var reservation_schema = process_owner_schema.extend({
|
|
1033
|
-
weight:
|
|
1034
|
-
claimed_at:
|
|
1138
|
+
weight: z2.number(),
|
|
1139
|
+
claimed_at: z2.number(),
|
|
1140
|
+
memory_mb: z2.number().optional(),
|
|
1141
|
+
admitted_at: z2.number().optional()
|
|
1035
1142
|
});
|
|
1036
1143
|
function marker_name(key) {
|
|
1037
1144
|
return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`;
|
|
@@ -1042,12 +1149,7 @@ function is_running2(reservation) {
|
|
|
1042
1149
|
function read_reservation(source) {
|
|
1043
1150
|
const raw = stamp_file.read_stamp_text(source);
|
|
1044
1151
|
if (raw === void 0) return void 0;
|
|
1045
|
-
|
|
1046
|
-
const parsed = reservation_schema.safeParse(JSON.parse(raw));
|
|
1047
|
-
return parsed.success ? parsed.data : void 0;
|
|
1048
|
-
} catch {
|
|
1049
|
-
return void 0;
|
|
1050
|
-
}
|
|
1152
|
+
return json_value.parse_with(raw, reservation_schema);
|
|
1051
1153
|
}
|
|
1052
1154
|
function sweep_marker2(source) {
|
|
1053
1155
|
try {
|
|
@@ -1064,78 +1166,92 @@ function live_reservation(source) {
|
|
|
1064
1166
|
}
|
|
1065
1167
|
function marker_files2(directory) {
|
|
1066
1168
|
try {
|
|
1067
|
-
return readdirSync2(directory).filter(
|
|
1169
|
+
return readdirSync2(directory).filter(
|
|
1170
|
+
(name) => name.startsWith(RESERVED_PREFIX) && name.endsWith(RESERVED_SUFFIX)
|
|
1171
|
+
);
|
|
1068
1172
|
} catch {
|
|
1069
1173
|
return [];
|
|
1070
1174
|
}
|
|
1071
1175
|
}
|
|
1072
1176
|
function live_reservations(directory = PLATFORM_TEMP_ROOT) {
|
|
1073
1177
|
return marker_files2(directory).flatMap((name) => {
|
|
1074
|
-
const reservation = live_reservation(
|
|
1178
|
+
const reservation = live_reservation(path2.join(directory, name));
|
|
1075
1179
|
return reservation === void 0 ? [] : { key: name, reservation };
|
|
1076
1180
|
});
|
|
1077
1181
|
}
|
|
1078
|
-
function compare_claim(left, right) {
|
|
1079
|
-
const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
|
|
1080
|
-
return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
|
|
1081
|
-
}
|
|
1082
|
-
function admitted_keys(reservations, budget) {
|
|
1083
|
-
const admitted = /* @__PURE__ */ new Set();
|
|
1084
|
-
let cumulative = 0;
|
|
1085
|
-
for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
|
|
1086
|
-
cumulative += entry.reservation.weight;
|
|
1087
|
-
if (index !== 0 && cumulative > budget) break;
|
|
1088
|
-
admitted.add(entry.key);
|
|
1089
|
-
}
|
|
1090
|
-
return admitted;
|
|
1091
|
-
}
|
|
1092
|
-
function is_admitted(key, reservations, budget) {
|
|
1093
|
-
return admitted_keys(reservations, budget).has(key);
|
|
1094
|
-
}
|
|
1095
|
-
function admitted_load(reservations, budget) {
|
|
1096
|
-
const admitted = admitted_keys(reservations, budget);
|
|
1097
|
-
return reservations.filter((entry) => admitted.has(entry.key)).reduce((total, entry) => total + entry.reservation.weight, 0);
|
|
1098
|
-
}
|
|
1099
1182
|
function normalize_budget(budget) {
|
|
1100
1183
|
return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET;
|
|
1101
1184
|
}
|
|
1102
|
-
async function
|
|
1185
|
+
async function default_sleep2(ms) {
|
|
1103
1186
|
await new Promise((resolve) => {
|
|
1104
1187
|
setTimeout(resolve, ms);
|
|
1105
1188
|
});
|
|
1106
1189
|
}
|
|
1107
|
-
function write_reservation(
|
|
1108
|
-
stamp_file.
|
|
1190
|
+
function write_reservation(target2, fields) {
|
|
1191
|
+
stamp_file.replace_stamp(target2, { ...process_identity.own_fields(), ...fields });
|
|
1109
1192
|
}
|
|
1110
1193
|
function resolve_timing(options) {
|
|
1111
1194
|
return {
|
|
1112
1195
|
now: options.now ?? Date.now,
|
|
1113
|
-
sleep: options.sleep ??
|
|
1114
|
-
poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS
|
|
1196
|
+
sleep: options.sleep ?? default_sleep2,
|
|
1197
|
+
poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
|
|
1198
|
+
wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
async function current_budget(context, reservations) {
|
|
1202
|
+
if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity };
|
|
1203
|
+
const reading = await context.read_machine();
|
|
1204
|
+
const ledger = core_admission.ledger_load(reservations, context.now());
|
|
1205
|
+
const budget = machine_capacity.machine_budget(context.budget, reading, ledger);
|
|
1206
|
+
return { ...budget, cores: normalize_budget(budget.cores) };
|
|
1207
|
+
}
|
|
1208
|
+
function admit(context, overflow) {
|
|
1209
|
+
write_reservation(context.target, { ...context.fields, admitted_at: context.now() });
|
|
1210
|
+
return { overflow };
|
|
1211
|
+
}
|
|
1212
|
+
function overflow_of(context, reservations, budget) {
|
|
1213
|
+
return {
|
|
1214
|
+
waited_ms: context.now() - context.fields.claimed_at,
|
|
1215
|
+
ledger: core_admission.sum_load(reservations),
|
|
1216
|
+
budget
|
|
1115
1217
|
};
|
|
1116
1218
|
}
|
|
1219
|
+
async function poll_admission(context) {
|
|
1220
|
+
const reservations = live_reservations(context.directory);
|
|
1221
|
+
const budget = await current_budget(context, reservations);
|
|
1222
|
+
if (core_admission.is_admitted(context.key, reservations, budget)) return admit(context);
|
|
1223
|
+
if (context.now() >= context.deadline) {
|
|
1224
|
+
return admit(context, overflow_of(context, reservations, budget));
|
|
1225
|
+
}
|
|
1226
|
+
return void 0;
|
|
1227
|
+
}
|
|
1117
1228
|
async function await_admission(context) {
|
|
1118
|
-
|
|
1119
|
-
|
|
1229
|
+
let admission = await poll_admission(context);
|
|
1230
|
+
while (admission === void 0) {
|
|
1120
1231
|
await context.sleep(context.poll_interval_ms);
|
|
1232
|
+
admission = await poll_admission(context);
|
|
1121
1233
|
}
|
|
1234
|
+
return admission;
|
|
1122
1235
|
}
|
|
1123
1236
|
async function reserve(weight, options = {}) {
|
|
1124
1237
|
const timing = resolve_timing(options);
|
|
1125
1238
|
const directory = options.directory ?? PLATFORM_TEMP_ROOT;
|
|
1126
|
-
const budget = normalize_budget(options.budget ?? availableParallelism2());
|
|
1127
1239
|
const claimed_at = timing.now();
|
|
1128
|
-
const name = marker_name(
|
|
1129
|
-
const
|
|
1130
|
-
|
|
1131
|
-
|
|
1240
|
+
const name = marker_name(randomUUID());
|
|
1241
|
+
const target2 = path2.join(directory, name);
|
|
1242
|
+
const fields = { weight, claimed_at, memory_mb: options.memory_mb };
|
|
1243
|
+
write_reservation(target2, fields);
|
|
1244
|
+
const admission = await await_admission({
|
|
1132
1245
|
...timing,
|
|
1133
1246
|
key: name,
|
|
1247
|
+
target: target2,
|
|
1134
1248
|
directory,
|
|
1135
|
-
budget,
|
|
1136
|
-
deadline: claimed_at +
|
|
1249
|
+
budget: normalize_budget(options.budget ?? availableParallelism3()),
|
|
1250
|
+
deadline: claimed_at + timing.wait_cap_ms,
|
|
1251
|
+
fields,
|
|
1252
|
+
read_machine: options.read_machine ?? machine_capacity.read_machine
|
|
1137
1253
|
});
|
|
1138
|
-
return { target };
|
|
1254
|
+
return { target: target2, admission };
|
|
1139
1255
|
}
|
|
1140
1256
|
function release(handle) {
|
|
1141
1257
|
sweep_marker2(handle.target);
|
|
@@ -1143,7 +1259,7 @@ function release(handle) {
|
|
|
1143
1259
|
async function with_core_reservation(weight, run, options = {}) {
|
|
1144
1260
|
const handle = await reserve(weight, options);
|
|
1145
1261
|
try {
|
|
1146
|
-
return await run();
|
|
1262
|
+
return await run(handle.admission);
|
|
1147
1263
|
} finally {
|
|
1148
1264
|
release(handle);
|
|
1149
1265
|
}
|
|
@@ -1171,9 +1287,11 @@ var core_budget = {
|
|
|
1171
1287
|
CORE_WEIGHTS,
|
|
1172
1288
|
HELD_KEY,
|
|
1173
1289
|
HELD_VALUE,
|
|
1290
|
+
MEMORY_MB,
|
|
1174
1291
|
RESERVED_PREFIX,
|
|
1175
|
-
admitted_keys,
|
|
1176
|
-
admitted_load,
|
|
1292
|
+
admitted_keys: core_admission.admitted_keys,
|
|
1293
|
+
admitted_load: core_admission.admitted_load,
|
|
1294
|
+
describe_overflow: core_admission.describe_overflow,
|
|
1177
1295
|
is_held,
|
|
1178
1296
|
live_reservations,
|
|
1179
1297
|
release,
|
|
@@ -1184,7 +1302,7 @@ var core_budget = {
|
|
|
1184
1302
|
};
|
|
1185
1303
|
|
|
1186
1304
|
// scripts/gate/gate-plan.ts
|
|
1187
|
-
import { availableParallelism as
|
|
1305
|
+
import { availableParallelism as availableParallelism4 } from "node:os";
|
|
1188
1306
|
|
|
1189
1307
|
// scripts/lib/status-icons.ts
|
|
1190
1308
|
var FAIL_ICON = "\u2717";
|
|
@@ -1232,28 +1350,53 @@ var LINT_LABEL = "lint";
|
|
|
1232
1350
|
var TYPE_CHECK_LABEL = "check";
|
|
1233
1351
|
var UNIT_LABEL = "test:unit";
|
|
1234
1352
|
var BEHAVIOR_LABEL = "behavior";
|
|
1353
|
+
var METRICS_LABEL = "metrics";
|
|
1235
1354
|
var WARNING_CHECKER_LABELS = [LINT_LABEL, TYPE_CHECK_LABEL];
|
|
1236
1355
|
var STATIC_CHECKS = [
|
|
1237
|
-
{
|
|
1356
|
+
{
|
|
1357
|
+
label: LINT_LABEL,
|
|
1358
|
+
target: "lint",
|
|
1359
|
+
reserved_cores: core_budget.CORE_WEIGHTS.lint,
|
|
1360
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
1361
|
+
},
|
|
1238
1362
|
{
|
|
1239
1363
|
label: TYPE_CHECK_LABEL,
|
|
1240
1364
|
target: "check",
|
|
1241
|
-
reserved_cores: core_budget.CORE_WEIGHTS.type_check
|
|
1365
|
+
reserved_cores: core_budget.CORE_WEIGHTS.type_check,
|
|
1366
|
+
memory_mb: core_budget.MEMORY_MB.type_check
|
|
1367
|
+
},
|
|
1368
|
+
{
|
|
1369
|
+
label: "cspell",
|
|
1370
|
+
target: "cspell:dot",
|
|
1371
|
+
reserved_cores: core_budget.CORE_WEIGHTS.spell_check,
|
|
1372
|
+
memory_mb: core_budget.MEMORY_MB.spell_check
|
|
1242
1373
|
},
|
|
1243
|
-
{ label: "cspell", target: "cspell:dot", reserved_cores: core_budget.CORE_WEIGHTS.spell_check },
|
|
1244
1374
|
{ label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
|
|
1245
|
-
// **The unused-member check reserves no core
|
|
1375
|
+
// **The unused-member check reserves no core**: it builds one TypeScript
|
|
1246
1376
|
// program and walks it for about 5s, and it is over well before lint and the type check. A
|
|
1247
1377
|
// reservation would only take a place from the four-core CI runner's fan-out and a worker from the
|
|
1248
1378
|
// unit suite for the whole gate.
|
|
1249
|
-
{ label: "exports", target: "exports:unused", reserved_cores: 0 }
|
|
1379
|
+
{ label: "exports", target: "exports:unused", reserved_cores: 0 },
|
|
1380
|
+
// **The metrics ratchet is kit's own**: it holds kit's repository-wide
|
|
1381
|
+
// totals to the merge-base's. It is one in-process eslint pass with only `max-lines` enabled, over
|
|
1382
|
+
// in a few seconds, so it reserves no core for the reason the unused-member check above does not.
|
|
1383
|
+
// It times no startup here: beside the unit suite that reads the load, not josh.
|
|
1384
|
+
{
|
|
1385
|
+
label: METRICS_LABEL,
|
|
1386
|
+
target: METRICS_LABEL,
|
|
1387
|
+
args: ["--no-startup"],
|
|
1388
|
+
reserved_cores: 0,
|
|
1389
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan,
|
|
1390
|
+
is_kit_only: true
|
|
1391
|
+
}
|
|
1250
1392
|
];
|
|
1251
1393
|
var GATE_CHECKS = [
|
|
1252
1394
|
...STATIC_CHECKS,
|
|
1253
1395
|
{ label: UNIT_LABEL, target: UNIT_LABEL, reserved_cores: 0 }
|
|
1254
1396
|
];
|
|
1255
|
-
function select_gate_checks(is_unit_included) {
|
|
1256
|
-
|
|
1397
|
+
function select_gate_checks(is_unit_included, is_kit_repository = true) {
|
|
1398
|
+
const checks = is_unit_included ? GATE_CHECKS : STATIC_CHECKS;
|
|
1399
|
+
return is_kit_repository ? checks : checks.filter((check) => check.is_kit_only !== true);
|
|
1257
1400
|
}
|
|
1258
1401
|
function has_unit_check(checks) {
|
|
1259
1402
|
return checks.some((check) => check.label === UNIT_LABEL);
|
|
@@ -1293,19 +1436,33 @@ function check_weight(check, plan, available_cores) {
|
|
|
1293
1436
|
if (check.label !== UNIT_LABEL) return check.reserved_cores;
|
|
1294
1437
|
return plan.unit_worker_cap ?? solo_unit_weight(available_cores);
|
|
1295
1438
|
}
|
|
1296
|
-
function
|
|
1439
|
+
function unit_memory(workers) {
|
|
1440
|
+
return workers * core_budget.MEMORY_MB.unit_worker;
|
|
1441
|
+
}
|
|
1442
|
+
function check_memory(check, plan, available_cores) {
|
|
1443
|
+
if (check.label !== UNIT_LABEL) return check.memory_mb ?? 0;
|
|
1444
|
+
return unit_memory(check_weight(check, plan, available_cores));
|
|
1445
|
+
}
|
|
1446
|
+
function direct_unit_weight(available_cores = availableParallelism4(), live_runs = unit_worker_share.live_run_count()) {
|
|
1297
1447
|
const weight = unit_worker_share.current_share(available_cores, live_runs) ?? solo_unit_weight(available_cores);
|
|
1298
1448
|
return Math.max(unit_worker_share.MIN_WORKERS, weight);
|
|
1299
1449
|
}
|
|
1450
|
+
function direct_unit_memory() {
|
|
1451
|
+
return unit_memory(direct_unit_weight());
|
|
1452
|
+
}
|
|
1453
|
+
function unit_cap_for(checks, available_cores, concurrent_runs) {
|
|
1454
|
+
if (!has_unit_check(checks)) return void 0;
|
|
1455
|
+
return resolve_unit_worker_cap(available_cores, concurrent_runs);
|
|
1456
|
+
}
|
|
1300
1457
|
function plan_of(concurrency, unit_worker_cap, checks = GATE_CHECKS) {
|
|
1301
1458
|
return { checks, concurrency, unit_worker_cap };
|
|
1302
1459
|
}
|
|
1303
|
-
function resolve_gate_plan(available_cores =
|
|
1304
|
-
const checks = select_gate_checks(is_unit_included);
|
|
1460
|
+
function resolve_gate_plan(available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS, is_unit_included = true, is_kit_repository = true) {
|
|
1461
|
+
const checks = select_gate_checks(is_unit_included, is_kit_repository);
|
|
1305
1462
|
return {
|
|
1306
1463
|
checks,
|
|
1307
1464
|
concurrency: resolve_concurrency(available_cores, concurrent_runs, checks),
|
|
1308
|
-
unit_worker_cap:
|
|
1465
|
+
unit_worker_cap: unit_cap_for(checks, available_cores, concurrent_runs)
|
|
1309
1466
|
};
|
|
1310
1467
|
}
|
|
1311
1468
|
function format_machine(available_cores, concurrent_runs) {
|
|
@@ -1318,7 +1475,7 @@ function format_unit_cap(plan) {
|
|
|
1318
1475
|
if (plan.unit_worker_cap === void 0) return `${UNIT_LABEL} unrestricted`;
|
|
1319
1476
|
return `${UNIT_LABEL} at ${String(plan.unit_worker_cap)} workers`;
|
|
1320
1477
|
}
|
|
1321
|
-
function format_gate_plan(plan, available_cores =
|
|
1478
|
+
function format_gate_plan(plan, available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS) {
|
|
1322
1479
|
const cap = format_unit_cap(plan);
|
|
1323
1480
|
const count = `${String(plan.concurrency)} of ${String(plan.checks.length)}`;
|
|
1324
1481
|
const width = `${count}${josh_verdict.GATE_OPENING_MARK}`;
|
|
@@ -1329,12 +1486,15 @@ var gate_plan = {
|
|
|
1329
1486
|
GATE_CHECKS,
|
|
1330
1487
|
LINT_LABEL,
|
|
1331
1488
|
MEASURED_CORES,
|
|
1489
|
+
METRICS_LABEL,
|
|
1332
1490
|
RESERVED_CORES,
|
|
1333
1491
|
STATIC_CHECKS,
|
|
1334
1492
|
TYPE_CHECK_LABEL,
|
|
1335
1493
|
UNIT_LABEL,
|
|
1336
1494
|
WARNING_CHECKER_LABELS,
|
|
1495
|
+
check_memory,
|
|
1337
1496
|
check_weight,
|
|
1497
|
+
direct_unit_memory,
|
|
1338
1498
|
direct_unit_weight,
|
|
1339
1499
|
format_gate_plan,
|
|
1340
1500
|
format_machine,
|
|
@@ -1370,28 +1530,45 @@ var DEV_COMMANDS = {
|
|
|
1370
1530
|
description: "Check code with prettier and eslint (skips a tool a basic project lacks)",
|
|
1371
1531
|
category: "Development",
|
|
1372
1532
|
reference: ["", "developer", ["processes"]],
|
|
1373
|
-
core_weight: core_budget.CORE_WEIGHTS.lint
|
|
1533
|
+
core_weight: core_budget.CORE_WEIGHTS.lint,
|
|
1534
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
1374
1535
|
},
|
|
1375
1536
|
"lint:related": {
|
|
1376
1537
|
script: "scripts/lint/lint-related.ts",
|
|
1377
1538
|
description: "Check only the changed files with prettier and eslint (whole tree on fallback)",
|
|
1378
1539
|
category: "Development",
|
|
1379
1540
|
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
1380
|
-
core_weight: core_budget.CORE_WEIGHTS.lint
|
|
1541
|
+
core_weight: core_budget.CORE_WEIGHTS.lint,
|
|
1542
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
1381
1543
|
},
|
|
1382
1544
|
lines: {
|
|
1383
1545
|
script: "scripts/lines/lines-command.ts",
|
|
1384
1546
|
description: "Print a file's code lines against the max-lines limit and the headroom left",
|
|
1385
1547
|
category: "Development",
|
|
1386
1548
|
reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]],
|
|
1387
|
-
core_weight: core_budget.CORE_WEIGHTS.eslint_scan
|
|
1549
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1550
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan
|
|
1551
|
+
},
|
|
1552
|
+
metrics: {
|
|
1553
|
+
script: "scripts/metrics/metrics-command.ts",
|
|
1554
|
+
description: "Print repository-wide quality totals and durations, and fail when a total grew past the merge-base or a duration past its baseline",
|
|
1555
|
+
category: "Development",
|
|
1556
|
+
reference: [
|
|
1557
|
+
'[--no-startup | --totals-only | --accept --reason "<why>"]',
|
|
1558
|
+
"developer",
|
|
1559
|
+
["files"]
|
|
1560
|
+
],
|
|
1561
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1562
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan,
|
|
1563
|
+
is_kit_only: true
|
|
1388
1564
|
},
|
|
1389
1565
|
"refactor:scan": {
|
|
1390
1566
|
script: "scripts/refactor/refactor-scan-cli.ts",
|
|
1391
1567
|
description: "List refactoring candidates in the changed scope by category and answer clear/candidates",
|
|
1392
1568
|
category: "Development",
|
|
1393
1569
|
reference: ["", "automation", ["processes"]],
|
|
1394
|
-
core_weight: core_budget.CORE_WEIGHTS.eslint_scan
|
|
1570
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1571
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan
|
|
1395
1572
|
},
|
|
1396
1573
|
bytes: {
|
|
1397
1574
|
script: "scripts/lines/bytes-command.ts",
|
|
@@ -1405,6 +1582,12 @@ var DEV_COMMANDS = {
|
|
|
1405
1582
|
category: "AI tools",
|
|
1406
1583
|
reference: ["[--refresh]", "developer", ["files"]]
|
|
1407
1584
|
},
|
|
1585
|
+
"rule:list": {
|
|
1586
|
+
script: "scripts/rules/rule-list.ts",
|
|
1587
|
+
description: "Print the trigger-delivered rules \u2014 each one's source, firing call and silent turn \u2014 from the guard rows",
|
|
1588
|
+
category: "AI tools",
|
|
1589
|
+
reference: ["", "automation", ["none"]]
|
|
1590
|
+
},
|
|
1408
1591
|
format: {
|
|
1409
1592
|
script: "scripts/lint/format.ts",
|
|
1410
1593
|
description: "Format code with prettier and eslint (skips a tool a basic project lacks)",
|
|
@@ -1425,8 +1608,8 @@ var DEV_COMMANDS = {
|
|
|
1425
1608
|
// **No `tsx_arguments`, deliberately.** `JOSH_BATCH_GUARD` is a per-machine preference kept in
|
|
1426
1609
|
// `.env`, which every other command reads through `OPTIONAL_ENV_FILE_FLAGS` — but declaring any
|
|
1427
1610
|
// `tsx_arguments` disqualifies a command from in-process dispatch (`josh-in-process.ts`), and
|
|
1428
|
-
// this one runs before every `Bash` call
|
|
1429
|
-
//
|
|
1611
|
+
// this one runs before every `Bash` call, where a second ~0.16 s tsx start is not affordable.
|
|
1612
|
+
// The script calls `process.loadEnvFile` itself instead, which is
|
|
1430
1613
|
// node's own `--env-file` parser with node's own precedence.
|
|
1431
1614
|
},
|
|
1432
1615
|
"pretool:guard": {
|
|
@@ -1450,7 +1633,7 @@ var DEV_COMMANDS = {
|
|
|
1450
1633
|
},
|
|
1451
1634
|
"session:lang": {
|
|
1452
1635
|
script: "scripts/josh/session-language-cli.ts",
|
|
1453
|
-
description: "Claude Code hook: print
|
|
1636
|
+
description: "Claude Code hook: print a non-default JOSH_SESSION_LANG for the session context, and the run:board reply rule while a backlogrun is live (otherwise nothing)",
|
|
1454
1637
|
category: "Development",
|
|
1455
1638
|
reference: ["", "automation", ["none"]]
|
|
1456
1639
|
// **No `tsx_arguments`, deliberately**, the same as `batch:guard` above: this runs on every
|
|
@@ -1463,7 +1646,7 @@ var DEV_COMMANDS = {
|
|
|
1463
1646
|
category: "Development",
|
|
1464
1647
|
reference: ["<pretool|posttool>", "automation", ["none"]]
|
|
1465
1648
|
// The live-source fallback `scripts/hooks/run-hook.sh` derives from the `codex-hook-adapter`
|
|
1466
|
-
// bundle name
|
|
1649
|
+
// bundle name. **No `tsx_arguments`**, the same as `pretool:guard`
|
|
1467
1650
|
// above: it runs before every guarded Codex call.
|
|
1468
1651
|
},
|
|
1469
1652
|
"cspell:dot": {
|
|
@@ -1471,7 +1654,8 @@ var DEV_COMMANDS = {
|
|
|
1471
1654
|
description: "Run spell check including dotfiles",
|
|
1472
1655
|
category: "Development",
|
|
1473
1656
|
reference: ["", "developer", ["processes"]],
|
|
1474
|
-
core_weight: core_budget.CORE_WEIGHTS.spell_check
|
|
1657
|
+
core_weight: core_budget.CORE_WEIGHTS.spell_check,
|
|
1658
|
+
memory_mb: core_budget.MEMORY_MB.spell_check
|
|
1475
1659
|
},
|
|
1476
1660
|
behavior: {
|
|
1477
1661
|
script: "scripts/behavior/behavior-cli.ts",
|
|
@@ -1490,14 +1674,16 @@ var DEV_COMMANDS = {
|
|
|
1490
1674
|
description: "Run unit tests with Vitest (skips when Vitest is absent; fails when it has no tests)",
|
|
1491
1675
|
category: "Development",
|
|
1492
1676
|
reference: [FILTER_ARGUMENTS, "developer", ["processes"]],
|
|
1493
|
-
core_weight: gate_plan.direct_unit_weight
|
|
1677
|
+
core_weight: gate_plan.direct_unit_weight,
|
|
1678
|
+
memory_mb: gate_plan.direct_unit_memory
|
|
1494
1679
|
},
|
|
1495
1680
|
"test:related": {
|
|
1496
1681
|
script: "scripts/test/test-related.ts",
|
|
1497
1682
|
description: "Run only the unit tests related to the changed files (full suite on fallback)",
|
|
1498
1683
|
category: "Development",
|
|
1499
1684
|
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
1500
|
-
core_weight: gate_plan.direct_unit_weight
|
|
1685
|
+
core_weight: gate_plan.direct_unit_weight,
|
|
1686
|
+
memory_mb: gate_plan.direct_unit_memory
|
|
1501
1687
|
},
|
|
1502
1688
|
"test:declared": {
|
|
1503
1689
|
script: "scripts/test/test-declared.ts",
|
|
@@ -1541,7 +1727,8 @@ var DEV_COMMANDS = {
|
|
|
1541
1727
|
description: "Type-check with tsc (skips a basic project with no TypeScript to check)",
|
|
1542
1728
|
category: "Development",
|
|
1543
1729
|
reference: ["[arguments...]", "developer", ["processes"]],
|
|
1544
|
-
core_weight: core_budget.CORE_WEIGHTS.type_check
|
|
1730
|
+
core_weight: core_budget.CORE_WEIGHTS.type_check,
|
|
1731
|
+
memory_mb: core_budget.MEMORY_MB.type_check
|
|
1545
1732
|
},
|
|
1546
1733
|
port: {
|
|
1547
1734
|
script: "scripts/ports/port-command.ts",
|
|
@@ -1662,9 +1849,9 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1662
1849
|
shell: [
|
|
1663
1850
|
"sh",
|
|
1664
1851
|
"-c",
|
|
1665
|
-
"export NODE_AUTH_TOKEN=$(gh auth token) && pnpm josh latest:guard && pnpm josh latest:
|
|
1852
|
+
"export NODE_AUTH_TOKEN=$(gh auth token) && pnpm josh latest:guard && pnpm josh latest:update && pnpm josh ranges && pnpm josh audit && pnpm josh latest:corepack && pnpm josh latest:scope --record"
|
|
1666
1853
|
],
|
|
1667
|
-
description: "Update
|
|
1854
|
+
description: "Update dependencies, run security audit, then update pnpm",
|
|
1668
1855
|
category: "Maintenance",
|
|
1669
1856
|
reference: ["", "developer", ["files", "network", "processes"]],
|
|
1670
1857
|
argument_targets: ["latest:corepack", "latest:update", "audit"]
|
|
@@ -1813,16 +2000,16 @@ var VERSIONING_COMMANDS = {
|
|
|
1813
2000
|
category: "Versioning",
|
|
1814
2001
|
reference: ["", "developer", ["network"]]
|
|
1815
2002
|
},
|
|
1816
|
-
// The one place that decides a version
|
|
2003
|
+
// The one place that decides a version. A `script` entry for the same
|
|
1817
2004
|
// reason `ranges` is one: script paths resolve against the kit package root, so it keeps working
|
|
1818
2005
|
// from a consumer repository where the file lives under node_modules.
|
|
1819
2006
|
release: {
|
|
1820
2007
|
script: "scripts/release/release-cli.ts",
|
|
1821
2008
|
description: "Release the merges main has taken since the version last changed",
|
|
1822
2009
|
category: "Versioning",
|
|
1823
|
-
reference: ["[
|
|
2010
|
+
reference: ["[--dry-run]", "maintainer", ["git", "network", "release"]]
|
|
1824
2011
|
},
|
|
1825
|
-
// The read-only half of the one above
|
|
2012
|
+
// The read-only half of the one above. `release --dry-run` cannot
|
|
1826
2013
|
// answer this question: it refuses off the default branch and on a dirty tree, which is every
|
|
1827
2014
|
// position a run asks it from. A `script` entry for the same reason `release` is one.
|
|
1828
2015
|
"release:scope": {
|
|
@@ -1831,8 +2018,8 @@ var VERSIONING_COMMANDS = {
|
|
|
1831
2018
|
category: "Versioning",
|
|
1832
2019
|
reference: ["[--json]", "automation", ["none"]]
|
|
1833
2020
|
},
|
|
1834
|
-
// Run by the release workflows, kit's and the one sync distributes, after a tag has published
|
|
1835
|
-
//
|
|
2021
|
+
// Run by the release workflows, kit's and the one sync distributes, after a tag has published.
|
|
2022
|
+
// Settings come from the environment, so the workflow decides them.
|
|
1836
2023
|
"release:github": {
|
|
1837
2024
|
script: "scripts/release/github-release-cli.ts",
|
|
1838
2025
|
description: "Create the GitHub Release for a published tag, with generated notes",
|
|
@@ -1860,20 +2047,17 @@ var WORKFLOW_COMMANDS = {
|
|
|
1860
2047
|
reference: ["<message>", "developer", ["network"]],
|
|
1861
2048
|
default_script_arguments: ["-y", "--skip-commit", "--skip-push"]
|
|
1862
2049
|
},
|
|
1863
|
-
// **The optional form, on both
|
|
1864
|
-
//
|
|
1865
|
-
//
|
|
1866
|
-
//
|
|
1867
|
-
// session, and `followup` with them the merge step of every `fullrun` there. `doctor` was moved to
|
|
1868
|
-
// this form for the same reason in joshuafolkken/kit#869.
|
|
2050
|
+
// **The optional form, on both**. The mandatory `--env-file=.env` is resolved by node before the
|
|
2051
|
+
// script's first line: on a machine with no `.env` it dies as `.env: not found` with exit code 9,
|
|
2052
|
+
// even where `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` exist as real environment variables — a
|
|
2053
|
+
// cloud session, and `followup` with them the merge step of every `fullrun` there.
|
|
1869
2054
|
//
|
|
1870
2055
|
// Nothing is lost by relaxing it: both scripts already load `.env` through `josh_environment_file`
|
|
1871
2056
|
// themselves, so the file is read either way and node's precedence — an existing environment
|
|
1872
2057
|
// variable wins over the file — is node's own in both spellings.
|
|
1873
2058
|
//
|
|
1874
|
-
// **
|
|
1875
|
-
//
|
|
1876
|
-
// `josh notify` exits non-zero instead of warning and answering 0.
|
|
2059
|
+
// **A missing credential still fails loudly**: `telegram_notify.send` throws on missing credentials
|
|
2060
|
+
// and on a failed send, so `josh notify` exits non-zero instead of warning and answering 0.
|
|
1877
2061
|
followup: {
|
|
1878
2062
|
script: "scripts/followup/git-followup-workflow.ts",
|
|
1879
2063
|
description: "Follow-up git workflow",
|
|
@@ -1889,11 +2073,23 @@ var WORKFLOW_COMMANDS = {
|
|
|
1889
2073
|
script: "scripts/notify/telegram-test.ts",
|
|
1890
2074
|
description: "Send Telegram notification",
|
|
1891
2075
|
category: "Workflow",
|
|
1892
|
-
reference: [
|
|
2076
|
+
reference: [
|
|
2077
|
+
"[--task-type <type>] [--body <text> | --body-file <path>] [--issue-url <url>] [--pr-url <url>] [--issue-title <text>] [--repo-name <name>]",
|
|
2078
|
+
"automation",
|
|
2079
|
+
["notifications"]
|
|
2080
|
+
],
|
|
1893
2081
|
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
|
|
1894
2082
|
},
|
|
1895
|
-
//
|
|
1896
|
-
//
|
|
2083
|
+
// One observation-ledger sighting: the key's count, the append and the second-sighting verdict,
|
|
2084
|
+
// which a run used to type as a `cat | grep -c` and judge by hand.
|
|
2085
|
+
"observation:record": {
|
|
2086
|
+
script: "scripts/observations/observation-record-cli.ts",
|
|
2087
|
+
description: "Record an observation sighting and answer whether it is now filed",
|
|
2088
|
+
category: "Workflow",
|
|
2089
|
+
reference: ["<key> <depth> <where> <what> [--checkout <path>]", "automation", ["files"]]
|
|
2090
|
+
},
|
|
2091
|
+
// The observation ledger's commit path for the lines no run's own commit carried:
|
|
2092
|
+
// a lane's lines sit in the primary checkout, which
|
|
1897
2093
|
// its commit cannot see, and the recurrence count the promotion rule reads is a count of main.
|
|
1898
2094
|
"observations:flush": {
|
|
1899
2095
|
script: "scripts/observations/observations-flush-cli.ts",
|
|
@@ -1901,8 +2097,8 @@ var WORKFLOW_COMMANDS = {
|
|
|
1901
2097
|
category: "Workflow",
|
|
1902
2098
|
reference: ["", "automation", ["git", "network"]]
|
|
1903
2099
|
},
|
|
1904
|
-
// The one write path for a `/code-review` round's findings
|
|
1905
|
-
// `--check` gate `followup` runs before it merges
|
|
2100
|
+
// The one write path for a `/code-review` round's findings, plus the
|
|
2101
|
+
// `--check` gate `followup` runs before it merges. It appends a `- rf:`
|
|
1906
2102
|
// line per finding — or one zero-finding line for a clean round — to the observation ledger, so
|
|
1907
2103
|
// `observations:flush` commits them and the recurrence count survives the run.
|
|
1908
2104
|
"review:record": {
|
|
@@ -1910,12 +2106,12 @@ var WORKFLOW_COMMANDS = {
|
|
|
1910
2106
|
description: "Record a review round\u2019s findings, or check a round was recorded",
|
|
1911
2107
|
category: "Workflow",
|
|
1912
2108
|
reference: [
|
|
1913
|
-
"--issue <N> [<category>:<severity>:<file> ...] | --check --issue <N>",
|
|
2109
|
+
"--issue <N> [--comment] [<category>:<severity>:<file> ...] | --check --issue <N>",
|
|
1914
2110
|
"automation",
|
|
1915
|
-
["files"]
|
|
2111
|
+
["files", "network"]
|
|
1916
2112
|
]
|
|
1917
2113
|
},
|
|
1918
|
-
// The reader over what `review:record` wrote
|
|
2114
|
+
// The reader over what `review:record` wrote: each recurring category’s
|
|
1919
2115
|
// count, and the number of zero-finding rounds that distinguishes a quiet category from an unwatched one.
|
|
1920
2116
|
"review:findings": {
|
|
1921
2117
|
script: "scripts/review/review-findings-cli.ts",
|
|
@@ -1924,7 +2120,7 @@ var WORKFLOW_COMMANDS = {
|
|
|
1924
2120
|
reference: ["", "developer", ["files"]]
|
|
1925
2121
|
},
|
|
1926
2122
|
// After a behavior-change Issue merges, re-run its declared baseline and print before/after; a value
|
|
1927
|
-
// that did not move appends a refuted-premise line to the observation ledger
|
|
2123
|
+
// that did not move appends a refuted-premise line to the observation ledger.
|
|
1928
2124
|
"measure:rerun": {
|
|
1929
2125
|
script: "scripts/issue/measure-rerun-cli.ts",
|
|
1930
2126
|
description: "Re-run a merged issue\u2019s baseline command and print the before/after pair",
|
|
@@ -1932,7 +2128,7 @@ var WORKFLOW_COMMANDS = {
|
|
|
1932
2128
|
reference: ["<issue-number>", "automation", ["network", "processes", "files"]]
|
|
1933
2129
|
},
|
|
1934
2130
|
// A script rather than an `sh -c` chain, because it has a precondition to enforce: run inside a
|
|
1935
|
-
// linked work tree it would hijack the default branch from every other one
|
|
2131
|
+
// linked work tree it would hijack the default branch from every other one.
|
|
1936
2132
|
"main:sync": {
|
|
1937
2133
|
script: "scripts/git/main-sync.ts",
|
|
1938
2134
|
description: "Checkout default branch, pull latest, and prune merged remote-gone branches (refuses inside a lane)",
|
|
@@ -1940,9 +2136,8 @@ var WORKFLOW_COMMANDS = {
|
|
|
1940
2136
|
reference: ["", "developer", ["git", "network"]]
|
|
1941
2137
|
},
|
|
1942
2138
|
// A script rather than an `sh -c` chain, because the strategy has to be named rather than left to
|
|
1943
|
-
// the caller's git configuration:
|
|
1944
|
-
//
|
|
1945
|
-
// (joshuafolkken/kit#1659).
|
|
2139
|
+
// the caller's git configuration: a bare `git pull` aborts with `Need to specify how to reconcile
|
|
2140
|
+
// divergent branches` on exactly the diverged branch the command exists for.
|
|
1946
2141
|
"main:merge": {
|
|
1947
2142
|
script: "scripts/git/main-merge.ts",
|
|
1948
2143
|
description: "Merge origin default branch into the current branch",
|
|
@@ -1969,6 +2164,7 @@ var ALIASES = {
|
|
|
1969
2164
|
lr: "lint:related",
|
|
1970
2165
|
ln: "lines",
|
|
1971
2166
|
by: "bytes",
|
|
2167
|
+
mt: "metrics",
|
|
1972
2168
|
f: "format",
|
|
1973
2169
|
sd: "cspell:dot",
|
|
1974
2170
|
bh: "behavior",
|
|
@@ -2011,7 +2207,9 @@ var ALIASES = {
|
|
|
2011
2207
|
ruv: "rule:value",
|
|
2012
2208
|
ev: "eval",
|
|
2013
2209
|
lsm: "lane:sample",
|
|
2014
|
-
lst: "lane:stats"
|
|
2210
|
+
lst: "lane:stats",
|
|
2211
|
+
lli: "lane:limit",
|
|
2212
|
+
blr: "backlogrun"
|
|
2015
2213
|
};
|
|
2016
2214
|
function canonical_command(name) {
|
|
2017
2215
|
if (!Object.hasOwn(ALIASES, name)) return name;
|
|
@@ -2234,74 +2432,74 @@ var time_background = {
|
|
|
2234
2432
|
};
|
|
2235
2433
|
|
|
2236
2434
|
// scripts/git/git-schemas.ts
|
|
2237
|
-
import { z as
|
|
2238
|
-
var package_name_schema =
|
|
2239
|
-
var rollup_item_schema =
|
|
2435
|
+
import { z as z3 } from "zod";
|
|
2436
|
+
var package_name_schema = z3.object({ name: z3.string().min(1) });
|
|
2437
|
+
var rollup_item_schema = z3.looseObject({
|
|
2240
2438
|
// eslint-disable-next-line @typescript-eslint/naming-convention -- GraphQL field name from GitHub API
|
|
2241
|
-
__typename:
|
|
2242
|
-
state:
|
|
2243
|
-
status:
|
|
2244
|
-
conclusion:
|
|
2245
|
-
name:
|
|
2246
|
-
context:
|
|
2439
|
+
__typename: z3.string().optional(),
|
|
2440
|
+
state: z3.string().optional(),
|
|
2441
|
+
status: z3.string().optional(),
|
|
2442
|
+
conclusion: z3.string().optional(),
|
|
2443
|
+
name: z3.string().optional(),
|
|
2444
|
+
context: z3.string().optional()
|
|
2247
2445
|
});
|
|
2248
|
-
var pr_raw_schema =
|
|
2249
|
-
statusCheckRollup:
|
|
2250
|
-
mergeStateStatus:
|
|
2251
|
-
reviewDecision:
|
|
2446
|
+
var pr_raw_schema = z3.object({
|
|
2447
|
+
statusCheckRollup: z3.array(rollup_item_schema).optional(),
|
|
2448
|
+
mergeStateStatus: z3.string().optional(),
|
|
2449
|
+
reviewDecision: z3.string().optional()
|
|
2252
2450
|
});
|
|
2253
|
-
var pull_comment_schema =
|
|
2254
|
-
body:
|
|
2255
|
-
html_url:
|
|
2256
|
-
user:
|
|
2451
|
+
var pull_comment_schema = z3.object({
|
|
2452
|
+
body: z3.string().optional(),
|
|
2453
|
+
html_url: z3.string().optional(),
|
|
2454
|
+
user: z3.object({ login: z3.string().optional() }).optional()
|
|
2257
2455
|
});
|
|
2258
|
-
var ai_review_pull_comment_schema =
|
|
2259
|
-
body:
|
|
2260
|
-
url:
|
|
2261
|
-
author:
|
|
2456
|
+
var ai_review_pull_comment_schema = z3.object({
|
|
2457
|
+
body: z3.string().optional(),
|
|
2458
|
+
url: z3.string().optional(),
|
|
2459
|
+
author: z3.object({ login: z3.string().optional() }).optional()
|
|
2262
2460
|
});
|
|
2263
|
-
var pr_info_schema =
|
|
2264
|
-
mergeable:
|
|
2265
|
-
mergeStateStatus:
|
|
2266
|
-
state:
|
|
2461
|
+
var pr_info_schema = z3.object({
|
|
2462
|
+
mergeable: z3.union([z3.boolean(), z3.string()]).nullable().optional(),
|
|
2463
|
+
mergeStateStatus: z3.string().nullable().optional(),
|
|
2464
|
+
state: z3.string().optional()
|
|
2267
2465
|
});
|
|
2268
|
-
var epic_issue_schema =
|
|
2269
|
-
number:
|
|
2270
|
-
body:
|
|
2466
|
+
var epic_issue_schema = z3.object({
|
|
2467
|
+
number: z3.number(),
|
|
2468
|
+
body: z3.string().optional()
|
|
2271
2469
|
});
|
|
2272
|
-
var blocking_issue_schema =
|
|
2273
|
-
number:
|
|
2274
|
-
state:
|
|
2275
|
-
repository_url:
|
|
2470
|
+
var blocking_issue_schema = z3.object({
|
|
2471
|
+
number: z3.number(),
|
|
2472
|
+
state: z3.string().optional(),
|
|
2473
|
+
repository_url: z3.string().optional()
|
|
2276
2474
|
});
|
|
2277
|
-
var blocked_by_schema =
|
|
2278
|
-
nodes:
|
|
2279
|
-
totalCount:
|
|
2475
|
+
var blocked_by_schema = z3.object({
|
|
2476
|
+
nodes: z3.array(blocking_issue_schema).default([]),
|
|
2477
|
+
totalCount: z3.number().optional()
|
|
2280
2478
|
}).optional();
|
|
2281
|
-
var epic_child_schema =
|
|
2282
|
-
state:
|
|
2479
|
+
var epic_child_schema = z3.object({
|
|
2480
|
+
state: z3.string().optional(),
|
|
2283
2481
|
blockedBy: blocked_by_schema
|
|
2284
2482
|
});
|
|
2285
|
-
var rest_comment_schema =
|
|
2286
|
-
body:
|
|
2287
|
-
html_url:
|
|
2288
|
-
user:
|
|
2483
|
+
var rest_comment_schema = z3.looseObject({
|
|
2484
|
+
body: z3.string().nullish(),
|
|
2485
|
+
html_url: z3.string().optional(),
|
|
2486
|
+
user: z3.looseObject({ login: z3.string().optional() }).nullish()
|
|
2289
2487
|
});
|
|
2290
|
-
var issue_label_schema =
|
|
2291
|
-
var epic_subject_schema =
|
|
2292
|
-
number:
|
|
2293
|
-
state:
|
|
2294
|
-
labels:
|
|
2295
|
-
body:
|
|
2488
|
+
var issue_label_schema = z3.object({ name: z3.string() });
|
|
2489
|
+
var epic_subject_schema = z3.object({
|
|
2490
|
+
number: z3.number(),
|
|
2491
|
+
state: z3.string().optional(),
|
|
2492
|
+
labels: z3.array(issue_label_schema).optional(),
|
|
2493
|
+
body: z3.string().optional()
|
|
2296
2494
|
});
|
|
2297
|
-
var open_issue_schema =
|
|
2298
|
-
number:
|
|
2299
|
-
title:
|
|
2300
|
-
labels:
|
|
2301
|
-
createdAt:
|
|
2495
|
+
var open_issue_schema = z3.object({
|
|
2496
|
+
number: z3.number(),
|
|
2497
|
+
title: z3.string(),
|
|
2498
|
+
labels: z3.array(issue_label_schema).optional(),
|
|
2499
|
+
createdAt: z3.string(),
|
|
2302
2500
|
blockedBy: blocked_by_schema,
|
|
2303
|
-
// Present only on the pickup listing, which reads it for the
|
|
2304
|
-
body:
|
|
2501
|
+
// Present only on the pickup listing, which reads it for the paths each issue declares.
|
|
2502
|
+
body: z3.string().optional()
|
|
2305
2503
|
});
|
|
2306
2504
|
|
|
2307
2505
|
// scripts/gh/git-pr-checks-parse.ts
|
|
@@ -2477,9 +2675,135 @@ var PrConflictError = class extends Error {
|
|
|
2477
2675
|
name = "PrConflictError";
|
|
2478
2676
|
};
|
|
2479
2677
|
|
|
2678
|
+
// scripts/lane/lane-ledger.ts
|
|
2679
|
+
import { closeSync, constants, openSync, writeSync } from "node:fs";
|
|
2680
|
+
import { z as z4 } from "zod";
|
|
2681
|
+
var LEDGER_PREFIX = "josh-lane-ledger-";
|
|
2682
|
+
var LEDGER_SUFFIX = ".jsonl";
|
|
2683
|
+
var LINE_SEPARATOR = "\n";
|
|
2684
|
+
var CI_WAIT_STAGE = "ci-wait";
|
|
2685
|
+
var LEDGER_FILE_MODE = 384;
|
|
2686
|
+
var { O_APPEND, O_CREAT, O_NOFOLLOW, O_WRONLY } = constants;
|
|
2687
|
+
var APPEND_FLAGS = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW;
|
|
2688
|
+
var KIND = {
|
|
2689
|
+
MERGE: "merge",
|
|
2690
|
+
GATE: "gate",
|
|
2691
|
+
LOAD: "load",
|
|
2692
|
+
DISPATCH: "dispatch",
|
|
2693
|
+
STAGE: "stage"
|
|
2694
|
+
};
|
|
2695
|
+
var merge_schema = z4.object({ kind: z4.literal(KIND.MERGE), at: z4.string(), issue: z4.number() });
|
|
2696
|
+
var gate_schema = z4.object({
|
|
2697
|
+
kind: z4.literal(KIND.GATE),
|
|
2698
|
+
at: z4.string(),
|
|
2699
|
+
elapsed_ms: z4.number(),
|
|
2700
|
+
is_passed: z4.boolean(),
|
|
2701
|
+
// The unit suite's own duration, present when this gate ran it — the one
|
|
2702
|
+
// record of a full vitest run `josh metrics` reads, so the suite is never timed twice.
|
|
2703
|
+
unit_ms: z4.number().optional(),
|
|
2704
|
+
// The whole cores busy outside this gate, beyond the machine's baseline, at its start or its end —
|
|
2705
|
+
// whichever was higher. Absent when the machine could not be read.
|
|
2706
|
+
external_cores: z4.number().optional()
|
|
2707
|
+
});
|
|
2708
|
+
var load_schema = z4.object({
|
|
2709
|
+
kind: z4.literal(KIND.LOAD),
|
|
2710
|
+
at: z4.string(),
|
|
2711
|
+
load: z4.number(),
|
|
2712
|
+
available_mb: z4.number().optional(),
|
|
2713
|
+
swapped_mb: z4.number().optional(),
|
|
2714
|
+
lanes: z4.number().optional()
|
|
2715
|
+
});
|
|
2716
|
+
var dispatch_schema = z4.object({
|
|
2717
|
+
kind: z4.literal(KIND.DISPATCH),
|
|
2718
|
+
at: z4.string(),
|
|
2719
|
+
issue: z4.number()
|
|
2720
|
+
});
|
|
2721
|
+
var stage_schema = z4.object({
|
|
2722
|
+
kind: z4.literal(KIND.STAGE),
|
|
2723
|
+
at: z4.string(),
|
|
2724
|
+
stage: z4.string(),
|
|
2725
|
+
elapsed_ms: z4.number(),
|
|
2726
|
+
issue: z4.number().optional()
|
|
2727
|
+
});
|
|
2728
|
+
var entry_schema = z4.discriminatedUnion("kind", [
|
|
2729
|
+
merge_schema,
|
|
2730
|
+
gate_schema,
|
|
2731
|
+
load_schema,
|
|
2732
|
+
dispatch_schema,
|
|
2733
|
+
stage_schema
|
|
2734
|
+
]);
|
|
2735
|
+
function target_of(repository) {
|
|
2736
|
+
return stamp_file.stamp_path(LEDGER_PREFIX, repository, LEDGER_SUFFIX);
|
|
2737
|
+
}
|
|
2738
|
+
async function target() {
|
|
2739
|
+
if (process.env["VITEST"] !== void 0) return void 0;
|
|
2740
|
+
try {
|
|
2741
|
+
const repository = await run_carry.repository_directory();
|
|
2742
|
+
return repository === void 0 ? void 0 : target_of(repository);
|
|
2743
|
+
} catch {
|
|
2744
|
+
return void 0;
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
function append(path4, entry) {
|
|
2748
|
+
const descriptor = openSync(path4, APPEND_FLAGS, LEDGER_FILE_MODE);
|
|
2749
|
+
try {
|
|
2750
|
+
if (stamp_file.is_own_regular_file(path4)) {
|
|
2751
|
+
writeSync(descriptor, `${JSON.stringify(entry)}${LINE_SEPARATOR}`);
|
|
2752
|
+
}
|
|
2753
|
+
} finally {
|
|
2754
|
+
closeSync(descriptor);
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
async function record(entry, path4) {
|
|
2758
|
+
try {
|
|
2759
|
+
const destination = path4 ?? await target();
|
|
2760
|
+
if (destination !== void 0) append(destination, entry);
|
|
2761
|
+
} catch {
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
function now_iso() {
|
|
2765
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
2766
|
+
}
|
|
2767
|
+
async function record_gate(path4, gate) {
|
|
2768
|
+
await record({ kind: KIND.GATE, at: now_iso(), ...gate }, path4);
|
|
2769
|
+
}
|
|
2770
|
+
async function record_merge(issue) {
|
|
2771
|
+
await record({ kind: KIND.MERGE, at: now_iso(), issue });
|
|
2772
|
+
}
|
|
2773
|
+
async function record_dispatch(issue, path4) {
|
|
2774
|
+
await record({ kind: KIND.DISPATCH, at: now_iso(), issue }, path4);
|
|
2775
|
+
}
|
|
2776
|
+
async function record_stage(stage, path4) {
|
|
2777
|
+
await record({ kind: KIND.STAGE, at: now_iso(), ...stage }, path4);
|
|
2778
|
+
}
|
|
2779
|
+
function parse_line2(line) {
|
|
2780
|
+
return entry_schema.safeParse(json_value.parse_or_undefined(line)).data;
|
|
2781
|
+
}
|
|
2782
|
+
function is_present(entry) {
|
|
2783
|
+
return entry !== void 0;
|
|
2784
|
+
}
|
|
2785
|
+
function read_entries(path4) {
|
|
2786
|
+
const raw = stamp_file.read_stamp_text(path4);
|
|
2787
|
+
if (raw === void 0) return [];
|
|
2788
|
+
return raw.split(LINE_SEPARATOR).map((line) => parse_line2(line.trim())).filter(is_present);
|
|
2789
|
+
}
|
|
2790
|
+
var lane_ledger = {
|
|
2791
|
+
CI_WAIT_STAGE,
|
|
2792
|
+
KIND,
|
|
2793
|
+
append,
|
|
2794
|
+
read_entries,
|
|
2795
|
+
record,
|
|
2796
|
+
record_dispatch,
|
|
2797
|
+
record_gate,
|
|
2798
|
+
record_merge,
|
|
2799
|
+
record_stage,
|
|
2800
|
+
target,
|
|
2801
|
+
target_of
|
|
2802
|
+
};
|
|
2803
|
+
|
|
2480
2804
|
// scripts/time-runtime/time-format.ts
|
|
2481
2805
|
var MS_PER_MINUTE = 6e4;
|
|
2482
|
-
var
|
|
2806
|
+
var MS_PER_SECOND2 = 1e3;
|
|
2483
2807
|
var MINUTE_DECIMALS = 1;
|
|
2484
2808
|
var SECOND_DECIMALS = 1;
|
|
2485
2809
|
var PERCENT_SCALE = 100;
|
|
@@ -2499,7 +2823,7 @@ function format_minutes(duration_ms) {
|
|
|
2499
2823
|
return `${(duration_ms / MS_PER_MINUTE).toFixed(MINUTE_DECIMALS)} min`;
|
|
2500
2824
|
}
|
|
2501
2825
|
function format_seconds(duration_ms) {
|
|
2502
|
-
return `${(duration_ms /
|
|
2826
|
+
return `${(duration_ms / MS_PER_SECOND2).toFixed(SECOND_DECIMALS)} s`;
|
|
2503
2827
|
}
|
|
2504
2828
|
function format_share(part, whole) {
|
|
2505
2829
|
if (whole === 0) return "n/a";
|
|
@@ -2549,8 +2873,8 @@ var STAGE = {
|
|
|
2549
2873
|
// blocker and on a red check, and those are the runs whose wait is longest — reporting nothing for
|
|
2550
2874
|
// them would leave the measurement blind to exactly the invocations worth measuring.
|
|
2551
2875
|
interrupted: "interrupted",
|
|
2552
|
-
// The interrupted lap when the wait failed on a merge conflict
|
|
2553
|
-
// stage block names the cause a resumed session
|
|
2876
|
+
// The interrupted lap when the wait failed on a merge conflict, so the
|
|
2877
|
+
// stage block names the cause a resumed session would otherwise look up with `gh pr view`.
|
|
2554
2878
|
conflict: "conflict"
|
|
2555
2879
|
};
|
|
2556
2880
|
function stopped_lap(error) {
|
|
@@ -2580,6 +2904,14 @@ function format_stages(log) {
|
|
|
2580
2904
|
function print_stages(log) {
|
|
2581
2905
|
for (const line of format_stages(log)) console.info(line);
|
|
2582
2906
|
}
|
|
2907
|
+
async function record_ci_wait(log) {
|
|
2908
|
+
const wait = log.stages.find((stage) => stage.name === STAGE.checks_wait);
|
|
2909
|
+
if (wait === void 0) return;
|
|
2910
|
+
await lane_ledger.record_stage({
|
|
2911
|
+
stage: lane_ledger.CI_WAIT_STAGE,
|
|
2912
|
+
elapsed_ms: wait.duration_ms
|
|
2913
|
+
});
|
|
2914
|
+
}
|
|
2583
2915
|
var git_followup_stages = {
|
|
2584
2916
|
STAGE,
|
|
2585
2917
|
STAGE_LINE_PREFIX,
|
|
@@ -2589,14 +2921,15 @@ var git_followup_stages = {
|
|
|
2589
2921
|
total_ms,
|
|
2590
2922
|
format_stages,
|
|
2591
2923
|
print_stages,
|
|
2924
|
+
record_ci_wait,
|
|
2592
2925
|
stopped_lap
|
|
2593
2926
|
};
|
|
2594
2927
|
|
|
2595
2928
|
// scripts/time-runtime/time-followup-stage.ts
|
|
2596
|
-
var
|
|
2929
|
+
var LINE_SEPARATOR2 = "\n";
|
|
2597
2930
|
var SECONDS_SUFFIX = " s";
|
|
2598
2931
|
var DIGIT_OR_POINT = /[\d.]/u;
|
|
2599
|
-
var
|
|
2932
|
+
var MS_PER_SECOND3 = 1e3;
|
|
2600
2933
|
var NO_STAGES = [];
|
|
2601
2934
|
function stage_body(line) {
|
|
2602
2935
|
const trimmed = line.trimStart();
|
|
@@ -2619,11 +2952,11 @@ function to_stage(body) {
|
|
|
2619
2952
|
const name = head.slice(0, start).trim();
|
|
2620
2953
|
const digits = head.slice(start);
|
|
2621
2954
|
if (name === "" || !is_duration(digits)) return void 0;
|
|
2622
|
-
return { name, duration_ms: Number(digits) *
|
|
2955
|
+
return { name, duration_ms: Number(digits) * MS_PER_SECOND3 };
|
|
2623
2956
|
}
|
|
2624
2957
|
function read_stages(text) {
|
|
2625
2958
|
if (!text.includes(git_followup_stages.STAGE_LINE_PREFIX)) return NO_STAGES;
|
|
2626
|
-
return text.split(
|
|
2959
|
+
return text.split(LINE_SEPARATOR2).map((line) => stage_body(line)).filter((body) => body !== void 0).map((body) => to_stage(body)).filter((stage) => stage !== void 0);
|
|
2627
2960
|
}
|
|
2628
2961
|
var time_followup_stage = { NO_STAGES, read_stages };
|
|
2629
2962
|
|
|
@@ -2631,7 +2964,7 @@ var time_followup_stage = { NO_STAGES, read_stages };
|
|
|
2631
2964
|
import { z as z5 } from "zod";
|
|
2632
2965
|
var TEXT_BLOCK_SCHEMA = z5.object({ text: z5.string().nullish() });
|
|
2633
2966
|
var CONTENT_SCHEMA = z5.union([z5.string(), z5.array(z5.unknown())]);
|
|
2634
|
-
var
|
|
2967
|
+
var LINE_SEPARATOR3 = "\n";
|
|
2635
2968
|
function block_text(block) {
|
|
2636
2969
|
const parsed = TEXT_BLOCK_SCHEMA.safeParse(block);
|
|
2637
2970
|
return parsed.success ? parsed.data.text ?? "" : "";
|
|
@@ -2640,7 +2973,7 @@ function result_text2(content) {
|
|
|
2640
2973
|
const parsed = CONTENT_SCHEMA.safeParse(content);
|
|
2641
2974
|
if (!parsed.success) return "";
|
|
2642
2975
|
if (typeof parsed.data === "string") return parsed.data;
|
|
2643
|
-
return parsed.data.map((block) => block_text(block)).join(
|
|
2976
|
+
return parsed.data.map((block) => block_text(block)).join(LINE_SEPARATOR3);
|
|
2644
2977
|
}
|
|
2645
2978
|
function is_failure_line(line) {
|
|
2646
2979
|
return line.trimStart().startsWith(status_icons.FAIL_ICON);
|
|
@@ -2692,7 +3025,7 @@ function did_scan_find(scan) {
|
|
|
2692
3025
|
return scan.did_find || scan.has_failure_before_region || scan.has_failure_in_region;
|
|
2693
3026
|
}
|
|
2694
3027
|
function has_failure_line(content) {
|
|
2695
|
-
const lines = result_text2(content).split(
|
|
3028
|
+
const lines = result_text2(content).split(LINE_SEPARATOR3);
|
|
2696
3029
|
if (lines.some((line) => is_failed_verdict(line))) return true;
|
|
2697
3030
|
return did_scan_find(scan_body(lines));
|
|
2698
3031
|
}
|
|
@@ -2913,8 +3246,8 @@ function field_targets(input) {
|
|
|
2913
3246
|
}
|
|
2914
3247
|
function tool_targets(input) {
|
|
2915
3248
|
const scalar_targets = TARGET_FIELDS.map((field) => field_text(input, field));
|
|
2916
|
-
const targets = [...scalar_targets, ...field_targets(input)].map((
|
|
2917
|
-
return [...new Set(targets)].filter((
|
|
3249
|
+
const targets = [...scalar_targets, ...field_targets(input)].map((target2) => normalize(target2));
|
|
3250
|
+
return [...new Set(targets)].filter((target2) => target2 !== "");
|
|
2918
3251
|
}
|
|
2919
3252
|
function prompt_references_prior(input) {
|
|
2920
3253
|
const prompt = field_text(input, "prompt").toLowerCase();
|
|
@@ -2959,27 +3292,27 @@ var time_bundle_call = {
|
|
|
2959
3292
|
bash_facts,
|
|
2960
3293
|
call_facts,
|
|
2961
3294
|
tool_facts,
|
|
2962
|
-
// Exported for `time-agent-bundles.ts
|
|
3295
|
+
// Exported for `time-agent-bundles.ts`, which asks the launch question of a
|
|
2963
3296
|
// span's `label` — the tool name for a non-Bash call — so the set lives in one place.
|
|
2964
3297
|
is_launch_tool,
|
|
2965
|
-
// Exported for `time-writes.ts
|
|
3298
|
+
// Exported for `time-writes.ts`, which asks what a call *wrote* rather
|
|
2966
3299
|
// than what it named. The extraction is the same one either way — a second copy of it would let a
|
|
2967
3300
|
// path be recognized as a target when read and missed when written.
|
|
2968
3301
|
targets_in,
|
|
2969
3302
|
tool_targets,
|
|
2970
|
-
// Exported for the batching guard's own word scan
|
|
3303
|
+
// Exported for the batching guard's own word scan, so the two scanners
|
|
2971
3304
|
// cannot come to disagree about where one word of a shell line ends and the next begins.
|
|
2972
|
-
// Exported for the read-fold notice
|
|
3305
|
+
// Exported for the read-fold notice, which offers `read:files <path>` only
|
|
2973
3306
|
// over file-shaped targets — a bare directory like `scripts/` is a target here but not something
|
|
2974
3307
|
// `read:files` can read, so the notice reuses this test rather than keep a second copy that could
|
|
2975
3308
|
// drift from what counts as a file path.
|
|
2976
3309
|
has_extension,
|
|
2977
|
-
// Exported for `time-writes.ts
|
|
3310
|
+
// Exported for `time-writes.ts`, which needs the same two answers to say
|
|
2978
3311
|
// *which* files an in-place `sed` wrote. Two copies of this test disagreed in both directions at
|
|
2979
3312
|
// once — one called a piped `grep -i` a write, the other missed a bundled `sed -ni`.
|
|
2980
3313
|
write_segment,
|
|
2981
3314
|
is_in_place_sed,
|
|
2982
|
-
// Exported for the drift test in `time-bundle-call.test.ts
|
|
3315
|
+
// Exported for the drift test in `time-bundle-call.test.ts`, which pins that
|
|
2983
3316
|
// every name here is a real `josh` command and none of them writes.
|
|
2984
3317
|
READ_JOSH_SUBCOMMANDS
|
|
2985
3318
|
};
|
|
@@ -2991,9 +3324,9 @@ function issue_from_branch(branch) {
|
|
|
2991
3324
|
const matched = ISSUE_BRANCH_PATTERN.exec(branch);
|
|
2992
3325
|
return matched?.[1] === void 0 ? UNATTRIBUTED_KEY : Number(matched[1]);
|
|
2993
3326
|
}
|
|
2994
|
-
function declared_issue(
|
|
2995
|
-
const declared =
|
|
2996
|
-
return declared === UNATTRIBUTED_KEY ? issue_from_branch(
|
|
3327
|
+
function declared_issue(record2) {
|
|
3328
|
+
const declared = record2.issue ?? UNATTRIBUTED_KEY;
|
|
3329
|
+
return declared === UNATTRIBUTED_KEY ? issue_from_branch(record2.branch) : declared;
|
|
2997
3330
|
}
|
|
2998
3331
|
function fill(declared, is_reverse) {
|
|
2999
3332
|
const filled = Array.from({ length: declared.length }, () => UNATTRIBUTED_KEY);
|
|
@@ -3017,12 +3350,12 @@ function pick(own, carried, next, previous) {
|
|
|
3017
3350
|
}
|
|
3018
3351
|
function announcements(records) {
|
|
3019
3352
|
return fill(
|
|
3020
|
-
records.map((
|
|
3353
|
+
records.map((record2) => record2.issue ?? UNATTRIBUTED_KEY),
|
|
3021
3354
|
false
|
|
3022
3355
|
);
|
|
3023
3356
|
}
|
|
3024
3357
|
function attribute(records) {
|
|
3025
|
-
const declared = records.map((
|
|
3358
|
+
const declared = records.map((record2) => declared_issue(record2));
|
|
3026
3359
|
const carried = announcements(records);
|
|
3027
3360
|
const next = fill(declared, true);
|
|
3028
3361
|
const previous = fill(declared, false);
|
|
@@ -3033,9 +3366,9 @@ function attribute(records) {
|
|
|
3033
3366
|
function group_by_issue(records) {
|
|
3034
3367
|
const issues = attribute(records);
|
|
3035
3368
|
const grouped = /* @__PURE__ */ new Map();
|
|
3036
|
-
for (const [index,
|
|
3369
|
+
for (const [index, record2] of records.entries()) {
|
|
3037
3370
|
const bucket = grouped.get(issues[index] ?? UNATTRIBUTED_KEY) ?? [];
|
|
3038
|
-
bucket.push(
|
|
3371
|
+
bucket.push(record2);
|
|
3039
3372
|
grouped.set(issues[index] ?? UNATTRIBUTED_KEY, bucket);
|
|
3040
3373
|
}
|
|
3041
3374
|
return [...grouped].toSorted(([left], [right]) => left - right).map(([issue, bucket]) => ({ issue, records: bucket }));
|
|
@@ -3164,28 +3497,18 @@ var time_single_check = { NO_CHECK, check_key };
|
|
|
3164
3497
|
|
|
3165
3498
|
// scripts/time-runtime/time-transcript-line.ts
|
|
3166
3499
|
import { z as z6 } from "zod";
|
|
3167
|
-
|
|
3168
|
-
// scripts/time-runtime/time-instant.ts
|
|
3169
|
-
function parse_instant(raw) {
|
|
3170
|
-
if (raw === null || raw === void 0) return void 0;
|
|
3171
|
-
const parsed = Date.parse(raw);
|
|
3172
|
-
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
3173
|
-
}
|
|
3174
|
-
var time_instant = { parse_instant };
|
|
3175
|
-
|
|
3176
|
-
// scripts/time-runtime/time-transcript-line.ts
|
|
3177
3500
|
var BLOCK_SCHEMA2 = z6.object({
|
|
3178
3501
|
type: z6.string().nullish(),
|
|
3179
3502
|
name: z6.string().nullish(),
|
|
3180
3503
|
id: z6.string().nullish(),
|
|
3181
3504
|
tool_use_id: z6.string().nullish(),
|
|
3182
3505
|
input: z6.unknown().nullish(),
|
|
3183
|
-
// Whether the harness wrote this result back as a failure
|
|
3506
|
+
// Whether the harness wrote this result back as a failure. Present on a
|
|
3184
3507
|
// `tool_result` block and on nothing else, and absent even there for the tools that never report
|
|
3185
3508
|
// one — which is why it is read as three answers rather than as a boolean with a default.
|
|
3186
3509
|
is_error: z6.boolean().nullish(),
|
|
3187
|
-
// What the call printed. Read only to recover the outcome a pipeline threw away
|
|
3188
|
-
//
|
|
3510
|
+
// What the call printed. Read only to recover the outcome a pipeline threw away:
|
|
3511
|
+
// it is kept as flattened text rather than as blocks, because that is
|
|
3189
3512
|
// the whole of what `time-reported-failure.ts` asks of it.
|
|
3190
3513
|
content: z6.unknown().nullish()
|
|
3191
3514
|
});
|
|
@@ -3196,10 +3519,10 @@ var LINE_SCHEMA = z6.object({
|
|
|
3196
3519
|
timestamp: z6.string().nullish(),
|
|
3197
3520
|
// The branch the line was written on, which is where the issue number lives — `josh git` names a
|
|
3198
3521
|
// branch `<N>-<slug>`. Read here rather than re-parsed by a second reader so `josh time --issue`
|
|
3199
|
-
// and `josh cost --issue` answer from the same field
|
|
3522
|
+
// and `josh cost --issue` answer from the same field.
|
|
3200
3523
|
gitBranch: z6.string().nullish(),
|
|
3201
|
-
// The two fields outside `message` that the harness writes an end-of-task notice on
|
|
3202
|
-
//
|
|
3524
|
+
// The two fields outside `message` that the harness writes an end-of-task notice on.
|
|
3525
|
+
// **Both are read as `unknown` rather than as strings**: a schema
|
|
3203
3526
|
// insisting on a string here would reject every line whose `content` is a list of blocks — which is
|
|
3204
3527
|
// most of them — and a rejected line is dropped from the timeline entirely, so the shares would stop
|
|
3205
3528
|
// reconstructing the elapsed time. The shape is checked at the read below instead.
|
|
@@ -3213,6 +3536,7 @@ var NO_MESSAGE_ID = "";
|
|
|
3213
3536
|
var ERROR_TEXT_LIMIT = 256;
|
|
3214
3537
|
var REFUSAL_MARKER = "\u26D4";
|
|
3215
3538
|
var HOOK_ERROR_LABEL = /^PreToolUse:\S+ hook error: /u;
|
|
3539
|
+
var STOP_FEEDBACK_LABEL = /^Stop hook feedback:\s*/u;
|
|
3216
3540
|
var TOKEN_LINE = /^[a-z][a-z-]*$/u;
|
|
3217
3541
|
var TOKEN_LINE_LIMIT = 8;
|
|
3218
3542
|
function block_names(raw) {
|
|
@@ -3230,6 +3554,11 @@ function guard_from_refusal(text) {
|
|
|
3230
3554
|
const colon = headline.indexOf(":");
|
|
3231
3555
|
return (colon === -1 ? headline : headline.slice(0, colon)).trim();
|
|
3232
3556
|
}
|
|
3557
|
+
function stop_guard_of(data) {
|
|
3558
|
+
const content = data.message?.content;
|
|
3559
|
+
if (typeof content !== "string" || !STOP_FEEDBACK_LABEL.test(content)) return "";
|
|
3560
|
+
return guard_from_refusal(content.replace(STOP_FEEDBACK_LABEL, ""));
|
|
3561
|
+
}
|
|
3233
3562
|
function token_lines_of(text) {
|
|
3234
3563
|
return text.split("\n").map((line) => line.trim()).filter((line) => TOKEN_LINE.test(line)).slice(0, TOKEN_LINE_LIMIT);
|
|
3235
3564
|
}
|
|
@@ -3268,19 +3597,24 @@ function to_line(data) {
|
|
|
3268
3597
|
timestamp_ms,
|
|
3269
3598
|
branch: data.gitBranch ?? UNKNOWN_BRANCH,
|
|
3270
3599
|
finished_background: time_background.finished_id(notice_text(data)),
|
|
3600
|
+
stop_guard: stop_guard_of(data),
|
|
3271
3601
|
...message_fields(data.message)
|
|
3272
3602
|
};
|
|
3273
3603
|
}
|
|
3274
|
-
function
|
|
3604
|
+
function parse_line3(line) {
|
|
3275
3605
|
const parsed = LINE_SCHEMA.safeParse(json_value.parse_or_undefined(line));
|
|
3276
3606
|
return parsed.success ? to_line(parsed.data) : void 0;
|
|
3277
3607
|
}
|
|
3608
|
+
function parse_text(text) {
|
|
3609
|
+
return text.split("\n").flatMap((line) => parse_line3(line) ?? []);
|
|
3610
|
+
}
|
|
3278
3611
|
var time_transcript_line = {
|
|
3279
3612
|
ERROR_TEXT_LIMIT,
|
|
3280
3613
|
NO_MESSAGE_ID,
|
|
3281
3614
|
TOKEN_LINE_LIMIT,
|
|
3282
3615
|
guard_from_refusal,
|
|
3283
|
-
parse_line:
|
|
3616
|
+
parse_line: parse_line3,
|
|
3617
|
+
parse_text
|
|
3284
3618
|
};
|
|
3285
3619
|
|
|
3286
3620
|
// scripts/time-runtime/time-writes.ts
|
|
@@ -3369,7 +3703,7 @@ var time_tool_call = {
|
|
|
3369
3703
|
};
|
|
3370
3704
|
|
|
3371
3705
|
// scripts/time-runtime/time-spans.ts
|
|
3372
|
-
var { NO_MESSAGE_ID: NO_MESSAGE_ID3, parse_line:
|
|
3706
|
+
var { NO_MESSAGE_ID: NO_MESSAGE_ID3, parse_line: parse_line4 } = time_transcript_line;
|
|
3373
3707
|
var { NO_CALL: NO_CALL2, UNKNOWN_CALL: UNKNOWN_CALL2, UNKNOWN_TOOL: UNKNOWN_TOOL2, to_tool_call: to_tool_call2 } = time_tool_call;
|
|
3374
3708
|
var ASSISTANT_TYPE = "assistant";
|
|
3375
3709
|
var USER_TYPE = "user";
|
|
@@ -3489,12 +3823,12 @@ function to_spans(events, finished) {
|
|
|
3489
3823
|
}));
|
|
3490
3824
|
}
|
|
3491
3825
|
function parse_timeline(text) {
|
|
3492
|
-
const lines = text.split("\n").map((line) =>
|
|
3826
|
+
const lines = text.split("\n").map((line) => parse_line4(line)).filter((line) => line !== void 0);
|
|
3493
3827
|
const events = to_events(lines, collect_calls(lines));
|
|
3494
3828
|
return {
|
|
3495
3829
|
started_ms: events[0]?.timestamp_ms ?? 0,
|
|
3496
3830
|
ended_ms: events.at(-1)?.timestamp_ms ?? 0,
|
|
3497
|
-
// **The positioning happens here rather than in a caller
|
|
3831
|
+
// **The positioning happens here rather than in a caller**: a launch and
|
|
3498
3832
|
// the call that reads its output are in one transcript, and by the time spans have been merged
|
|
3499
3833
|
// across sessions and trimmed they are fragments rather than calls.
|
|
3500
3834
|
spans: time_background.positioned(to_spans(events, time_background.finished_at(lines)))
|
|
@@ -3517,12 +3851,12 @@ var time_spans = {
|
|
|
3517
3851
|
equal_durations,
|
|
3518
3852
|
no_background,
|
|
3519
3853
|
// Re-exported so the suites that measure how a command is read keep asking one namespace, and so
|
|
3520
|
-
// `time-shell.ts` moving out of this file changed no call site
|
|
3854
|
+
// `time-shell.ts` moving out of this file changed no call site.
|
|
3521
3855
|
bash_label: time_shell.bash_label,
|
|
3522
3856
|
josh_command_of: time_shell.josh_command_of,
|
|
3523
3857
|
josh_commands_of: time_shell.josh_commands_of,
|
|
3524
3858
|
to_tool_call: to_tool_call2,
|
|
3525
|
-
parse_line:
|
|
3859
|
+
parse_line: parse_line4,
|
|
3526
3860
|
parse_timeline
|
|
3527
3861
|
};
|
|
3528
3862
|
|
|
@@ -3615,23 +3949,21 @@ var time_round_trips = {
|
|
|
3615
3949
|
CALLS_PER_ROUND_TRIP_FLOOR,
|
|
3616
3950
|
count_calls,
|
|
3617
3951
|
count_round_trips,
|
|
3618
|
-
// Exported
|
|
3619
|
-
//
|
|
3952
|
+
// Exported so a turn is defined in the one module that already defines a round trip rather than
|
|
3953
|
+
// as a span filter in the report next door.
|
|
3620
3954
|
count_turns,
|
|
3621
3955
|
format_density,
|
|
3622
|
-
// Exported
|
|
3623
|
-
//
|
|
3956
|
+
// Exported so the per-tool counts are read off the very groups this module counts rather than off
|
|
3957
|
+
// a second grouping beside them.
|
|
3624
3958
|
group_round_trips,
|
|
3625
|
-
// Exported
|
|
3959
|
+
// Exported so the failure aggregation orders a run's spans through
|
|
3626
3960
|
// the one function that already knows why they need it — a second `toSorted` beside it would be
|
|
3627
3961
|
// the clone `CLAUDE.md` prohibits, and the seam it guards (a delegated unit's spans appended
|
|
3628
3962
|
// after the parent's) is not one a second copy would keep remembering.
|
|
3629
3963
|
in_time_order,
|
|
3630
3964
|
is_below_floor,
|
|
3631
|
-
//
|
|
3632
|
-
//
|
|
3633
|
-
// private copy there would be the clone `CLAUDE.md` prohibits, in the one place a drift would have
|
|
3634
|
-
// the distribution and the count disagreeing about what a round trip is.
|
|
3965
|
+
// Exported so callers price a round trip with the same divisor and guard rather than a private
|
|
3966
|
+
// copy — the clone `CLAUDE.md` prohibits.
|
|
3635
3967
|
per_round_trip
|
|
3636
3968
|
};
|
|
3637
3969
|
|
|
@@ -3771,9 +4103,9 @@ function tally_for(tallies, label) {
|
|
|
3771
4103
|
return created;
|
|
3772
4104
|
}
|
|
3773
4105
|
function count_trip(tallies, counted, label) {
|
|
3774
|
-
const
|
|
3775
|
-
|
|
3776
|
-
if (!counted.has(label))
|
|
4106
|
+
const tally = tally_for(tallies, label);
|
|
4107
|
+
tally.recoverable_round_trips += ONE_CALL;
|
|
4108
|
+
if (!counted.has(label)) tally.sequence_count += ONE_CALL;
|
|
3777
4109
|
counted.add(label);
|
|
3778
4110
|
}
|
|
3779
4111
|
function tally_sequence(tallies, sequence) {
|
|
@@ -3791,7 +4123,7 @@ function by_weight(left, right) {
|
|
|
3791
4123
|
function tool_rows(closed) {
|
|
3792
4124
|
const tallies = /* @__PURE__ */ new Map();
|
|
3793
4125
|
for (const sequence of closed) tally_sequence(tallies, sequence);
|
|
3794
|
-
return [...tallies].map(([label,
|
|
4126
|
+
return [...tallies].map(([label, tally]) => ({ label, ...tally })).toSorted(by_weight);
|
|
3795
4127
|
}
|
|
3796
4128
|
function attributed_of(rows) {
|
|
3797
4129
|
return rows.reduce((sum, row) => sum + row.recoverable_round_trips, NONE3);
|
|
@@ -3925,9 +4257,11 @@ var NONE4 = 0;
|
|
|
3925
4257
|
var NOTICE_REFIRE_EVERY = ONE_TURN;
|
|
3926
4258
|
var NAMED_CANDIDATE_COUNT = 3;
|
|
3927
4259
|
var SEQUENCE_BEFORE_LIMIT = CONSECUTIVE_LIMIT - ONE_TURN;
|
|
3928
|
-
var
|
|
3929
|
-
var
|
|
3930
|
-
var
|
|
4260
|
+
var RULE_POINTER = "`prompts/collaboration-workflow/turn-batching.md`";
|
|
4261
|
+
var STREAK = `${String(CONSECUTIVE_LIMIT)} single-call turns in a row`;
|
|
4262
|
+
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), and it never authorizes weakening a verification gate or a review. Already batching, or nothing to pair? Reissue it unchanged; this fires once per streak. ${RULE_POINTER}`;
|
|
4263
|
+
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}`;
|
|
4264
|
+
var LANE_NOTICE = `\u{1F4A1} batching: ${STREAK}; the call proceeds. Pair independent calls. ${RULE_POINTER}`;
|
|
3931
4265
|
var WHOLE_FILE_WRITE_TOOL = "Write";
|
|
3932
4266
|
var EDIT_TOOL = "Edit";
|
|
3933
4267
|
function is_guarded_call(call) {
|
|
@@ -3984,13 +4318,13 @@ function should_notify(text, call, notified_at_ms) {
|
|
|
3984
4318
|
return is_at_limit(spans, call, notified_at_ms, NOTICE_REFIRE_EVERY);
|
|
3985
4319
|
}
|
|
3986
4320
|
function describe_span(span) {
|
|
3987
|
-
const
|
|
3988
|
-
if (
|
|
3989
|
-
return `${span.label} ${
|
|
4321
|
+
const target2 = span.targets[0] ?? "";
|
|
4322
|
+
if (target2 === "" || span.label.includes(target2)) return span.label;
|
|
4323
|
+
return `${span.label} ${target2}`;
|
|
3990
4324
|
}
|
|
3991
4325
|
var FOLD_MINIMUM = 2;
|
|
3992
4326
|
function read_targets(sequence) {
|
|
3993
|
-
const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((
|
|
4327
|
+
const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((path4) => path4 !== "" && time_bundle_call.has_extension(path4));
|
|
3994
4328
|
return [...new Set(paths)];
|
|
3995
4329
|
}
|
|
3996
4330
|
function read_fold_directive(sequence) {
|
|
@@ -3999,7 +4333,7 @@ function read_fold_directive(sequence) {
|
|
|
3999
4333
|
return ` Fold them into one call: \`pnpm josh read:files ${paths.join(" ")}\`.`;
|
|
4000
4334
|
}
|
|
4001
4335
|
function write_targets(sequence) {
|
|
4002
|
-
const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((
|
|
4336
|
+
const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((path4) => path4 !== "" && time_bundle_call.has_extension(path4));
|
|
4003
4337
|
return [...new Set(paths)];
|
|
4004
4338
|
}
|
|
4005
4339
|
function write_fold_directive(sequence) {
|
|
@@ -4051,449 +4385,22 @@ var time_batch_guard = {
|
|
|
4051
4385
|
};
|
|
4052
4386
|
|
|
4053
4387
|
// scripts/time-runtime/time-hook-transcript.ts
|
|
4054
|
-
import
|
|
4055
|
-
|
|
4056
|
-
// scripts/cost-runtime/cost-transcript.ts
|
|
4057
|
-
import { readdirSync as readdirSync3, readFileSync as readFileSync3, statSync } from "node:fs";
|
|
4058
|
-
import { homedir } from "node:os";
|
|
4059
|
-
import path5 from "node:path";
|
|
4060
|
-
|
|
4061
|
-
// scripts/lane/lane-paths.ts
|
|
4062
|
-
import path4 from "node:path";
|
|
4063
|
-
var LANE_ROOT_KEY = "JOSH_LANE_ROOT";
|
|
4064
|
-
var LANE_DIRECTORY_SUFFIX = "-lanes";
|
|
4065
|
-
var LANE_BRANCH_SUFFIX = "-lane";
|
|
4066
|
-
function default_lane_root(repository_root) {
|
|
4067
|
-
const name = path4.basename(repository_root);
|
|
4068
|
-
return path4.join(path4.dirname(repository_root), `.${name}${LANE_DIRECTORY_SUFFIX}`);
|
|
4069
|
-
}
|
|
4070
|
-
function lane_root(repository_root, environment = process.env) {
|
|
4071
|
-
const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
|
|
4072
|
-
return configured.length === 0 ? default_lane_root(repository_root) : path4.resolve(configured);
|
|
4073
|
-
}
|
|
4074
|
-
function lane_directory(root, issue) {
|
|
4075
|
-
return path4.join(root, issue);
|
|
4076
|
-
}
|
|
4077
|
-
var LANE_ISSUE_PATTERN = /^\d+$/u;
|
|
4078
|
-
var DEFAULT_LANE_ROOT_PATTERN = new RegExp(String.raw`^\..+${LANE_DIRECTORY_SUFFIX}$`, "u");
|
|
4079
|
-
function is_lane_root(directory, environment) {
|
|
4080
|
-
const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
|
|
4081
|
-
if (configured.length > 0) return path4.resolve(configured) === directory;
|
|
4082
|
-
return DEFAULT_LANE_ROOT_PATTERN.test(path4.basename(directory));
|
|
4083
|
-
}
|
|
4084
|
-
function lane_issue_of(directory, environment = process.env) {
|
|
4085
|
-
const resolved = path4.resolve(directory);
|
|
4086
|
-
const issue = path4.basename(resolved);
|
|
4087
|
-
if (!LANE_ISSUE_PATTERN.test(issue)) return void 0;
|
|
4088
|
-
return is_lane_root(path4.dirname(resolved), environment) ? issue : void 0;
|
|
4089
|
-
}
|
|
4090
|
-
function lane_branch(issue) {
|
|
4091
|
-
return `${issue}${LANE_BRANCH_SUFFIX}`;
|
|
4092
|
-
}
|
|
4093
|
-
var lane_paths = {
|
|
4094
|
-
LANE_BRANCH_SUFFIX,
|
|
4095
|
-
LANE_ROOT_KEY,
|
|
4096
|
-
default_lane_root,
|
|
4097
|
-
lane_branch,
|
|
4098
|
-
lane_directory,
|
|
4099
|
-
lane_issue_of,
|
|
4100
|
-
lane_root
|
|
4101
|
-
};
|
|
4102
|
-
|
|
4103
|
-
// scripts/lib/read-file.ts
|
|
4104
|
-
import { readFileSync as readFileSync2 } from "node:fs";
|
|
4105
|
-
var ABSENT_CODE = "ENOENT";
|
|
4106
|
-
function is_absent(error) {
|
|
4107
|
-
return error instanceof Error && "code" in error && error.code === ABSENT_CODE;
|
|
4108
|
-
}
|
|
4109
|
-
function read_optional(path7) {
|
|
4110
|
-
try {
|
|
4111
|
-
return readFileSync2(path7, "utf8");
|
|
4112
|
-
} catch (error) {
|
|
4113
|
-
if (is_absent(error)) return void 0;
|
|
4114
|
-
throw error;
|
|
4115
|
-
}
|
|
4116
|
-
}
|
|
4117
|
-
function read_file_or_empty(path7) {
|
|
4118
|
-
return read_optional(path7) ?? "";
|
|
4119
|
-
}
|
|
4120
|
-
function read_if_readable(path7) {
|
|
4121
|
-
try {
|
|
4122
|
-
return readFileSync2(path7, "utf8");
|
|
4123
|
-
} catch {
|
|
4124
|
-
return void 0;
|
|
4125
|
-
}
|
|
4126
|
-
}
|
|
4127
|
-
var file_reader = { read_optional, read_file_or_empty, read_if_readable };
|
|
4128
|
-
|
|
4129
|
-
// scripts/cost-runtime/cost-usage.ts
|
|
4130
|
-
import { z as z7 } from "zod";
|
|
4131
|
-
var CACHE_CREATION_SCHEMA = z7.object({
|
|
4132
|
-
ephemeral_1h_input_tokens: z7.number().nullish(),
|
|
4133
|
-
ephemeral_5m_input_tokens: z7.number().nullish()
|
|
4134
|
-
});
|
|
4135
|
-
var USAGE_SCHEMA = z7.object({
|
|
4136
|
-
input_tokens: z7.number(),
|
|
4137
|
-
cache_creation_input_tokens: z7.number().nullish(),
|
|
4138
|
-
cache_read_input_tokens: z7.number().nullish(),
|
|
4139
|
-
output_tokens: z7.number(),
|
|
4140
|
-
output_tokens_details: z7.object({ thinking_tokens: z7.number().nullish() }).nullish(),
|
|
4141
|
-
cache_creation: CACHE_CREATION_SCHEMA.nullish()
|
|
4142
|
-
});
|
|
4143
|
-
var MESSAGE_SCHEMA3 = z7.object({
|
|
4144
|
-
id: z7.string().nullish(),
|
|
4145
|
-
model: z7.string().nullish(),
|
|
4146
|
-
usage: USAGE_SCHEMA.nullish()
|
|
4147
|
-
});
|
|
4148
|
-
var LINE_SCHEMA2 = z7.object({
|
|
4149
|
-
type: z7.string(),
|
|
4150
|
-
requestId: z7.string().nullish(),
|
|
4151
|
-
uuid: z7.string().nullish(),
|
|
4152
|
-
gitBranch: z7.string().nullish(),
|
|
4153
|
-
timestamp: z7.string().nullish(),
|
|
4154
|
-
message: MESSAGE_SCHEMA3.nullish()
|
|
4155
|
-
});
|
|
4156
|
-
var SYNTHETIC_MODEL = "<synthetic>";
|
|
4157
|
-
var EMPTY_TOTALS = {
|
|
4158
|
-
input_tokens: 0,
|
|
4159
|
-
cache_write_5m_tokens: 0,
|
|
4160
|
-
cache_write_1h_tokens: 0,
|
|
4161
|
-
cache_read_tokens: 0,
|
|
4162
|
-
output_tokens: 0,
|
|
4163
|
-
thinking_tokens: 0,
|
|
4164
|
-
thinking_measured: false
|
|
4165
|
-
};
|
|
4166
|
-
var UNKNOWN_MODEL = "unknown";
|
|
4167
|
-
var UNKNOWN_BRANCH2 = "";
|
|
4168
|
-
function split_cache_write(usage) {
|
|
4169
|
-
const total = usage.cache_creation_input_tokens ?? 0;
|
|
4170
|
-
const detail = usage.cache_creation;
|
|
4171
|
-
if (!detail) return { write_5m: total, write_1h: 0 };
|
|
4172
|
-
const write_1h = detail.ephemeral_1h_input_tokens ?? 0;
|
|
4173
|
-
return { write_5m: detail.ephemeral_5m_input_tokens ?? total - write_1h, write_1h };
|
|
4174
|
-
}
|
|
4175
|
-
function thinking_usage(usage) {
|
|
4176
|
-
const raw = usage.output_tokens_details?.thinking_tokens;
|
|
4177
|
-
return { tokens: raw ?? 0, measured: raw !== null && raw !== void 0 };
|
|
4178
|
-
}
|
|
4179
|
-
function to_totals(usage) {
|
|
4180
|
-
const { write_5m, write_1h } = split_cache_write(usage);
|
|
4181
|
-
const thinking = thinking_usage(usage);
|
|
4182
|
-
return {
|
|
4183
|
-
input_tokens: usage.input_tokens,
|
|
4184
|
-
cache_write_5m_tokens: write_5m,
|
|
4185
|
-
cache_write_1h_tokens: write_1h,
|
|
4186
|
-
cache_read_tokens: usage.cache_read_input_tokens ?? 0,
|
|
4187
|
-
output_tokens: usage.output_tokens,
|
|
4188
|
-
thinking_tokens: thinking.tokens,
|
|
4189
|
-
thinking_measured: thinking.measured
|
|
4190
|
-
};
|
|
4191
|
-
}
|
|
4192
|
-
function declared_id(data) {
|
|
4193
|
-
return data.requestId ?? data.message?.id ?? data.uuid ?? void 0;
|
|
4194
|
-
}
|
|
4195
|
-
function request_id_of(data, usage) {
|
|
4196
|
-
const fallback = `${data.timestamp ?? ""}-${String(usage.output_tokens)}`;
|
|
4197
|
-
return declared_id(data) ?? fallback;
|
|
4198
|
-
}
|
|
4199
|
-
function to_record(data, usage) {
|
|
4200
|
-
return {
|
|
4201
|
-
request_id: request_id_of(data, usage),
|
|
4202
|
-
model: data.message?.model ?? UNKNOWN_MODEL,
|
|
4203
|
-
branch: data.gitBranch ?? UNKNOWN_BRANCH2,
|
|
4204
|
-
at_ms: time_instant.parse_instant(data.timestamp),
|
|
4205
|
-
totals: to_totals(usage)
|
|
4206
|
-
};
|
|
4207
|
-
}
|
|
4208
|
-
var ASSISTANT_TYPE2 = "assistant";
|
|
4209
|
-
function is_priced_line(data) {
|
|
4210
|
-
return data.type === ASSISTANT_TYPE2 && data.message?.model !== SYNTHETIC_MODEL;
|
|
4211
|
-
}
|
|
4212
|
-
function classify(data) {
|
|
4213
|
-
if (!is_priced_line(data)) return { kind: "skipped" };
|
|
4214
|
-
const usage = data.message?.usage;
|
|
4215
|
-
return usage ? { kind: "record", record: to_record(data, usage) } : { kind: "no_usage" };
|
|
4216
|
-
}
|
|
4217
|
-
function parse_line4(line) {
|
|
4218
|
-
if (line.trim() === "") return { kind: "skipped" };
|
|
4219
|
-
const parsed = LINE_SCHEMA2.safeParse(json_value.parse_or_undefined(line));
|
|
4220
|
-
return parsed.success ? classify(parsed.data) : { kind: "malformed" };
|
|
4221
|
-
}
|
|
4222
|
-
function later_instant(left, right) {
|
|
4223
|
-
if (left === void 0) return right;
|
|
4224
|
-
if (right === void 0) return left;
|
|
4225
|
-
return Math.max(left, right);
|
|
4226
|
-
}
|
|
4227
|
-
function dedupe(records) {
|
|
4228
|
-
const by_id = /* @__PURE__ */ new Map();
|
|
4229
|
-
for (const record of records) {
|
|
4230
|
-
const seen = by_id.get(record.request_id);
|
|
4231
|
-
const at_ms = later_instant(seen?.at_ms, record.at_ms);
|
|
4232
|
-
by_id.set(record.request_id, { ...seen ?? record, at_ms });
|
|
4233
|
-
}
|
|
4234
|
-
return [...by_id.values()];
|
|
4235
|
-
}
|
|
4236
|
-
function add_totals(left, right) {
|
|
4237
|
-
return {
|
|
4238
|
-
input_tokens: left.input_tokens + right.input_tokens,
|
|
4239
|
-
cache_write_5m_tokens: left.cache_write_5m_tokens + right.cache_write_5m_tokens,
|
|
4240
|
-
cache_write_1h_tokens: left.cache_write_1h_tokens + right.cache_write_1h_tokens,
|
|
4241
|
-
cache_read_tokens: left.cache_read_tokens + right.cache_read_tokens,
|
|
4242
|
-
output_tokens: left.output_tokens + right.output_tokens,
|
|
4243
|
-
thinking_tokens: left.thinking_tokens + right.thinking_tokens,
|
|
4244
|
-
thinking_measured: left.thinking_measured || right.thinking_measured
|
|
4245
|
-
};
|
|
4246
|
-
}
|
|
4247
|
-
function sum_totals(records) {
|
|
4248
|
-
let total = EMPTY_TOTALS;
|
|
4249
|
-
for (const record of records) total = add_totals(total, record.totals);
|
|
4250
|
-
return total;
|
|
4251
|
-
}
|
|
4252
|
-
function billed_input(totals) {
|
|
4253
|
-
return totals.input_tokens + totals.cache_write_5m_tokens + totals.cache_write_1h_tokens + totals.cache_read_tokens;
|
|
4254
|
-
}
|
|
4255
|
-
var cost_usage = {
|
|
4256
|
-
EMPTY_TOTALS,
|
|
4257
|
-
UNKNOWN_MODEL,
|
|
4258
|
-
SYNTHETIC_MODEL,
|
|
4259
|
-
parse_line: parse_line4,
|
|
4260
|
-
dedupe,
|
|
4261
|
-
add_totals,
|
|
4262
|
-
sum_totals,
|
|
4263
|
-
billed_input
|
|
4264
|
-
};
|
|
4265
|
-
|
|
4266
|
-
// scripts/cost-runtime/cost-transcript.ts
|
|
4267
|
-
var TRANSCRIPT_ROOT = path5.join(".claude", "projects");
|
|
4268
|
-
var TRANSCRIPT_EXTENSION = ".jsonl";
|
|
4269
|
-
var SLUG_PATTERN = /[^a-zA-Z0-9-]/gu;
|
|
4270
|
-
var UNIT_DIRECTORY = "subagents";
|
|
4271
|
-
var UNIT_ID_SEPARATOR = "/";
|
|
4272
|
-
function project_slug(cwd) {
|
|
4273
|
-
return cwd.replaceAll(SLUG_PATTERN, "-");
|
|
4274
|
-
}
|
|
4275
|
-
function transcript_directory(cwd, home = homedir()) {
|
|
4276
|
-
return path5.join(home, TRANSCRIPT_ROOT, project_slug(cwd));
|
|
4277
|
-
}
|
|
4278
|
-
var GIT_ENTRY = ".git";
|
|
4279
|
-
var GITDIR_PREFIX = "gitdir:";
|
|
4280
|
-
var WORKTREE_SEGMENT = `/${GIT_ENTRY}/worktrees/`;
|
|
4281
|
-
var NOT_FOUND = -1;
|
|
4282
|
-
function linked_worktree_gitdir(cwd) {
|
|
4283
|
-
try {
|
|
4284
|
-
const contents = readFileSync3(path5.join(cwd, GIT_ENTRY), "utf8").trim();
|
|
4285
|
-
return contents.startsWith(GITDIR_PREFIX) ? contents.slice(GITDIR_PREFIX.length).trim() : "";
|
|
4286
|
-
} catch {
|
|
4287
|
-
return "";
|
|
4288
|
-
}
|
|
4289
|
-
}
|
|
4290
|
-
function session_cwd(cwd) {
|
|
4291
|
-
const gitdir = linked_worktree_gitdir(cwd);
|
|
4292
|
-
const absolute = gitdir === "" ? "" : path5.resolve(cwd, gitdir);
|
|
4293
|
-
const segment = absolute.indexOf(WORKTREE_SEGMENT);
|
|
4294
|
-
return segment === NOT_FOUND ? cwd : absolute.slice(0, segment);
|
|
4295
|
-
}
|
|
4296
|
-
function read_directory(directory) {
|
|
4297
|
-
try {
|
|
4298
|
-
return readdirSync3(directory);
|
|
4299
|
-
} catch {
|
|
4300
|
-
return [];
|
|
4301
|
-
}
|
|
4302
|
-
}
|
|
4303
|
-
var LANE_ISSUE_SLUG = /^\d+$/u;
|
|
4304
|
-
function lane_transcript_directories(main_cwd, home) {
|
|
4305
|
-
const projects = path5.join(home, TRANSCRIPT_ROOT);
|
|
4306
|
-
const prefix = `${project_slug(lane_paths.lane_root(main_cwd))}-`;
|
|
4307
|
-
return read_directory(projects).filter((name) => name.startsWith(prefix) && LANE_ISSUE_SLUG.test(name.slice(prefix.length))).map((name) => path5.join(projects, name));
|
|
4308
|
-
}
|
|
4309
|
-
function transcript_directories(cwd, home = homedir()) {
|
|
4310
|
-
const own = transcript_directory(cwd, home);
|
|
4311
|
-
const lanes = session_cwd(cwd) === cwd ? lane_transcript_directories(cwd, home) : [];
|
|
4312
|
-
return [.../* @__PURE__ */ new Set([own, ...lanes])];
|
|
4313
|
-
}
|
|
4314
|
-
var OWN_DEPTH = 0;
|
|
4315
|
-
function home_directory() {
|
|
4316
|
-
return homedir();
|
|
4317
|
-
}
|
|
4318
|
-
function to_session_file(full_path, session_id, depth) {
|
|
4319
|
-
try {
|
|
4320
|
-
return {
|
|
4321
|
-
session_id,
|
|
4322
|
-
path: full_path,
|
|
4323
|
-
modified_ms: statSync(full_path).mtimeMs,
|
|
4324
|
-
is_delegated: depth > OWN_DEPTH,
|
|
4325
|
-
depth
|
|
4326
|
-
};
|
|
4327
|
-
} catch {
|
|
4328
|
-
return void 0;
|
|
4329
|
-
}
|
|
4330
|
-
}
|
|
4331
|
-
function is_transcript(name) {
|
|
4332
|
-
return name.endsWith(TRANSCRIPT_EXTENSION);
|
|
4333
|
-
}
|
|
4334
|
-
function without_extension(name) {
|
|
4335
|
-
return name.slice(0, -TRANSCRIPT_EXTENSION.length);
|
|
4336
|
-
}
|
|
4337
|
-
function own_files(directory, names) {
|
|
4338
|
-
return names.filter((name) => is_transcript(name)).map((name) => to_session_file(path5.join(directory, name), without_extension(name), OWN_DEPTH)).filter((file) => file !== void 0);
|
|
4339
|
-
}
|
|
4340
|
-
function unit_directory(directory, session_id) {
|
|
4341
|
-
return path5.join(directory, session_id, UNIT_DIRECTORY);
|
|
4342
|
-
}
|
|
4343
|
-
var UNIT_DEPTH = 1;
|
|
4344
|
-
function level_units(subagents_directory, prefix, depth) {
|
|
4345
|
-
return read_directory(subagents_directory).filter((name) => is_transcript(name)).map(
|
|
4346
|
-
(name) => to_session_file(
|
|
4347
|
-
path5.join(subagents_directory, name),
|
|
4348
|
-
`${prefix}${UNIT_ID_SEPARATOR}${without_extension(name)}`,
|
|
4349
|
-
depth
|
|
4350
|
-
)
|
|
4351
|
-
).filter((file) => file !== void 0);
|
|
4352
|
-
}
|
|
4353
|
-
function collect_units(subagents_directory, prefix, depth) {
|
|
4354
|
-
const nested = read_directory(subagents_directory).filter((name) => !is_transcript(name)).flatMap(
|
|
4355
|
-
(name) => collect_units(
|
|
4356
|
-
unit_directory(subagents_directory, name),
|
|
4357
|
-
`${prefix}${UNIT_ID_SEPARATOR}${name}`,
|
|
4358
|
-
depth + 1
|
|
4359
|
-
)
|
|
4360
|
-
);
|
|
4361
|
-
return [...level_units(subagents_directory, prefix, depth), ...nested];
|
|
4362
|
-
}
|
|
4363
|
-
function unit_files(directory, session_name) {
|
|
4364
|
-
return collect_units(unit_directory(directory, session_name), session_name, UNIT_DEPTH);
|
|
4365
|
-
}
|
|
4366
|
-
function list_sessions(directory) {
|
|
4367
|
-
const names = read_directory(directory);
|
|
4368
|
-
const units = names.filter((name) => !is_transcript(name)).flatMap((name) => unit_files(directory, name));
|
|
4369
|
-
return [...own_files(directory, names), ...units].toSorted(
|
|
4370
|
-
(left, right) => right.modified_ms - left.modified_ms
|
|
4371
|
-
);
|
|
4372
|
-
}
|
|
4373
|
-
function list_sessions_across(directories) {
|
|
4374
|
-
const seen = /* @__PURE__ */ new Set();
|
|
4375
|
-
const merged = directories.flatMap((directory) => list_sessions(directory));
|
|
4376
|
-
const newest_first = merged.toSorted((left, right) => right.modified_ms - left.modified_ms);
|
|
4377
|
-
const kept = [];
|
|
4378
|
-
for (const file of newest_first) {
|
|
4379
|
-
if (seen.has(file.session_id)) continue;
|
|
4380
|
-
seen.add(file.session_id);
|
|
4381
|
-
kept.push(file);
|
|
4382
|
-
}
|
|
4383
|
-
return kept;
|
|
4384
|
-
}
|
|
4385
|
-
function owning_session_id(file) {
|
|
4386
|
-
const [owner] = file.session_id.split(UNIT_ID_SEPARATOR);
|
|
4387
|
-
return owner ?? file.session_id;
|
|
4388
|
-
}
|
|
4389
|
-
function parent_session_id(file) {
|
|
4390
|
-
const separator = file.session_id.lastIndexOf(UNIT_ID_SEPARATOR);
|
|
4391
|
-
return separator === NOT_FOUND ? file.session_id : file.session_id.slice(0, separator);
|
|
4392
|
-
}
|
|
4393
|
-
function latest_own_index(files) {
|
|
4394
|
-
const index = files.findIndex((file) => !file.is_delegated);
|
|
4395
|
-
return index === -1 ? 0 : index;
|
|
4396
|
-
}
|
|
4397
|
-
function empty_session() {
|
|
4398
|
-
return {
|
|
4399
|
-
records: [],
|
|
4400
|
-
no_usage_lines: 0,
|
|
4401
|
-
malformed_lines: 0,
|
|
4402
|
-
is_readable: false,
|
|
4403
|
-
baseline_tokens: 0
|
|
4404
|
-
};
|
|
4405
|
-
}
|
|
4406
|
-
function tally(content) {
|
|
4407
|
-
const outcomes = content.split("\n").map((line) => cost_usage.parse_line(line));
|
|
4408
|
-
const records = outcomes.flatMap(
|
|
4409
|
-
(outcome) => outcome.kind === "record" ? [outcome.record] : []
|
|
4410
|
-
);
|
|
4411
|
-
const unique = cost_usage.dedupe(records);
|
|
4412
|
-
const [first] = unique;
|
|
4413
|
-
return {
|
|
4414
|
-
records: unique,
|
|
4415
|
-
no_usage_lines: outcomes.filter((outcome) => outcome.kind === "no_usage").length,
|
|
4416
|
-
malformed_lines: outcomes.filter((outcome) => outcome.kind === "malformed").length,
|
|
4417
|
-
is_readable: true,
|
|
4418
|
-
baseline_tokens: first === void 0 ? 0 : cost_usage.billed_input(first.totals)
|
|
4419
|
-
};
|
|
4420
|
-
}
|
|
4421
|
-
function read_session(file) {
|
|
4422
|
-
const content = file_reader.read_if_readable(file.path);
|
|
4423
|
-
if (content === void 0) return { session_id: file.session_id, ...empty_session() };
|
|
4424
|
-
return { session_id: file.session_id, ...tally(content) };
|
|
4425
|
-
}
|
|
4426
|
-
function read_raw(file) {
|
|
4427
|
-
return file_reader.read_if_readable(file.path) ?? "";
|
|
4428
|
-
}
|
|
4429
|
-
function read_optional2(file) {
|
|
4430
|
-
return file_reader.read_if_readable(file.path);
|
|
4431
|
-
}
|
|
4432
|
-
function directory_exists(directory) {
|
|
4433
|
-
try {
|
|
4434
|
-
return statSync(directory).isDirectory();
|
|
4435
|
-
} catch {
|
|
4436
|
-
return false;
|
|
4437
|
-
}
|
|
4438
|
-
}
|
|
4439
|
-
function searched_directories(directories) {
|
|
4440
|
-
return directories.map((directory) => ({
|
|
4441
|
-
path: directory,
|
|
4442
|
-
exists: directory_exists(directory)
|
|
4443
|
-
}));
|
|
4444
|
-
}
|
|
4445
|
-
function describe_searched(directory) {
|
|
4446
|
-
return ` ${directory.path} \u2014 ${directory.exists ? "no transcripts here" : "no such directory"}`;
|
|
4447
|
-
}
|
|
4448
|
-
function missing_message(searched, session_id) {
|
|
4449
|
-
const lead = session_id === void 0 ? "No transcripts found. Searched:" : `No transcript named ${session_id}. Searched:`;
|
|
4450
|
-
const listed = searched.map((directory) => describe_searched(directory));
|
|
4451
|
-
if (session_id !== void 0) return [lead, ...listed];
|
|
4452
|
-
return [
|
|
4453
|
-
lead,
|
|
4454
|
-
...listed,
|
|
4455
|
-
"Claude Code writes them per project; run this from the project it ran in."
|
|
4456
|
-
];
|
|
4457
|
-
}
|
|
4458
|
-
var cost_transcript = {
|
|
4459
|
-
TRANSCRIPT_EXTENSION,
|
|
4460
|
-
TRANSCRIPT_ROOT,
|
|
4461
|
-
UNIT_DIRECTORY,
|
|
4462
|
-
project_slug,
|
|
4463
|
-
transcript_directory,
|
|
4464
|
-
transcript_directories,
|
|
4465
|
-
session_cwd,
|
|
4466
|
-
unit_directory,
|
|
4467
|
-
list_sessions,
|
|
4468
|
-
list_sessions_across,
|
|
4469
|
-
searched_directories,
|
|
4470
|
-
owning_session_id,
|
|
4471
|
-
parent_session_id,
|
|
4472
|
-
latest_own_index,
|
|
4473
|
-
tally,
|
|
4474
|
-
read_session,
|
|
4475
|
-
read_raw,
|
|
4476
|
-
read_optional: read_optional2,
|
|
4477
|
-
missing_message,
|
|
4478
|
-
home_directory
|
|
4479
|
-
};
|
|
4480
|
-
|
|
4481
|
-
// scripts/time-runtime/time-hook-transcript.ts
|
|
4482
|
-
var { TRANSCRIPT_EXTENSION: TRANSCRIPT_EXTENSION2 } = cost_transcript;
|
|
4388
|
+
import path3 from "node:path";
|
|
4389
|
+
var { TRANSCRIPT_EXTENSION } = cost_transcript;
|
|
4483
4390
|
var AGENT_PREFIX = "agent-";
|
|
4484
4391
|
var AGENT_ID_PATTERN = /^[\w-]+$/u;
|
|
4485
4392
|
function is_agent_id(value) {
|
|
4486
4393
|
return typeof value === "string" && AGENT_ID_PATTERN.test(value);
|
|
4487
4394
|
}
|
|
4488
4395
|
function fork_path(transcript_path, agent_id) {
|
|
4489
|
-
const directory =
|
|
4490
|
-
const session_id =
|
|
4491
|
-
const file_name = `${AGENT_PREFIX}${agent_id}${
|
|
4492
|
-
return
|
|
4396
|
+
const directory = path3.dirname(transcript_path);
|
|
4397
|
+
const session_id = path3.basename(transcript_path, TRANSCRIPT_EXTENSION);
|
|
4398
|
+
const file_name = `${AGENT_PREFIX}${agent_id}${TRANSCRIPT_EXTENSION}`;
|
|
4399
|
+
return path3.join(cost_transcript.unit_directory(directory, session_id), file_name);
|
|
4493
4400
|
}
|
|
4494
4401
|
function transcript_of(transcript_path, agent_id) {
|
|
4495
4402
|
if (!is_agent_id(agent_id)) return transcript_path;
|
|
4496
|
-
if (!transcript_path.endsWith(
|
|
4403
|
+
if (!transcript_path.endsWith(TRANSCRIPT_EXTENSION)) return transcript_path;
|
|
4497
4404
|
return fork_path(transcript_path, agent_id);
|
|
4498
4405
|
}
|
|
4499
4406
|
var time_hook_transcript = {
|
|
@@ -4502,8 +4409,8 @@ var time_hook_transcript = {
|
|
|
4502
4409
|
};
|
|
4503
4410
|
|
|
4504
4411
|
// scripts/time-runtime/time-density-hook.ts
|
|
4505
|
-
import { closeSync, fstatSync, openSync, readSync } from "node:fs";
|
|
4506
|
-
import { z as
|
|
4412
|
+
import { closeSync as closeSync2, fstatSync, openSync as openSync2, readSync } from "node:fs";
|
|
4413
|
+
import { z as z7 } from "zod";
|
|
4507
4414
|
|
|
4508
4415
|
// scripts/time-runtime/time-density.ts
|
|
4509
4416
|
var MIN_ROUND_TRIPS = 10;
|
|
@@ -4559,15 +4466,15 @@ var TAIL_BYTES = 262144;
|
|
|
4559
4466
|
var FILE_START = 0;
|
|
4560
4467
|
var NOTICE_PREFIX = "josh-density-notice-";
|
|
4561
4468
|
var NEVER_MS = 0;
|
|
4562
|
-
var payload_schema =
|
|
4563
|
-
transcript_path:
|
|
4469
|
+
var payload_schema = z7.object({
|
|
4470
|
+
transcript_path: z7.string().min(1).optional(),
|
|
4564
4471
|
// **`nullish`, not `optional`.** A payload spelling the absent agent as `null` has to read as "no
|
|
4565
4472
|
// fork"; rejected, it would fail `safeParse` for the whole payload and silence the line for every
|
|
4566
4473
|
// edit of the main line — the opposite of this module's stated failure direction.
|
|
4567
|
-
agent_id:
|
|
4474
|
+
agent_id: z7.string().nullish()
|
|
4568
4475
|
});
|
|
4569
|
-
var notice_schema =
|
|
4570
|
-
var call_schema =
|
|
4476
|
+
var notice_schema = z7.object({ notified_at_ms: z7.number() });
|
|
4477
|
+
var call_schema = z7.object({ tool_name: z7.string().min(1), tool_input: z7.unknown() });
|
|
4571
4478
|
function parse_transcript_path(raw_payload) {
|
|
4572
4479
|
const parsed = payload_schema.safeParse(JSON.parse(raw_payload));
|
|
4573
4480
|
if (!parsed.success || parsed.data.transcript_path === void 0) return void 0;
|
|
@@ -4579,7 +4486,7 @@ function parse_call(raw_payload) {
|
|
|
4579
4486
|
return { name: parsed.data.tool_name, input: parsed.data.tool_input };
|
|
4580
4487
|
}
|
|
4581
4488
|
function read_tail(file_path, max_bytes = TAIL_BYTES) {
|
|
4582
|
-
const descriptor =
|
|
4489
|
+
const descriptor = openSync2(file_path, "r");
|
|
4583
4490
|
try {
|
|
4584
4491
|
const { size } = fstatSync(descriptor);
|
|
4585
4492
|
const length = Math.min(size, max_bytes);
|
|
@@ -4587,7 +4494,7 @@ function read_tail(file_path, max_bytes = TAIL_BYTES) {
|
|
|
4587
4494
|
const read = readSync(descriptor, buffer, FILE_START, length, size - length);
|
|
4588
4495
|
return buffer.subarray(FILE_START, read).toString("utf8");
|
|
4589
4496
|
} finally {
|
|
4590
|
-
|
|
4497
|
+
closeSync2(descriptor);
|
|
4591
4498
|
}
|
|
4592
4499
|
}
|
|
4593
4500
|
function notice_path(transcript_path) {
|
|
@@ -4596,15 +4503,11 @@ function notice_path(transcript_path) {
|
|
|
4596
4503
|
function last_notice_ms(source) {
|
|
4597
4504
|
const raw = stamp_file.read_stamp_text(source);
|
|
4598
4505
|
if (raw === void 0) return NEVER_MS;
|
|
4599
|
-
|
|
4600
|
-
return notice_schema.parse(JSON.parse(raw)).notified_at_ms;
|
|
4601
|
-
} catch {
|
|
4602
|
-
return NEVER_MS;
|
|
4603
|
-
}
|
|
4506
|
+
return json_value.parse_with(raw, notice_schema)?.notified_at_ms ?? NEVER_MS;
|
|
4604
4507
|
}
|
|
4605
|
-
function arm_throttle(
|
|
4508
|
+
function arm_throttle(target2, now_ms) {
|
|
4606
4509
|
try {
|
|
4607
|
-
stamp_file.write_stamp(
|
|
4510
|
+
stamp_file.write_stamp(target2, { notified_at_ms: now_ms });
|
|
4608
4511
|
} catch {
|
|
4609
4512
|
}
|
|
4610
4513
|
}
|
|
@@ -4613,11 +4516,11 @@ function notice_for(raw_payload, now_ms) {
|
|
|
4613
4516
|
if (transcript_path === void 0) return void 0;
|
|
4614
4517
|
const tail = read_tail(transcript_path);
|
|
4615
4518
|
const reading = time_density.read_window(tail);
|
|
4616
|
-
const
|
|
4617
|
-
if (!time_density.is_due(reading, now_ms - last_notice_ms(
|
|
4519
|
+
const target2 = notice_path(transcript_path);
|
|
4520
|
+
if (!time_density.is_due(reading, now_ms - last_notice_ms(target2))) return void 0;
|
|
4618
4521
|
const candidates = time_batch_guard.pairing_candidates(tail, parse_call(raw_payload));
|
|
4619
4522
|
if (candidates === "") return void 0;
|
|
4620
|
-
arm_throttle(
|
|
4523
|
+
arm_throttle(target2, now_ms);
|
|
4621
4524
|
return time_density.format_notice(reading, candidates);
|
|
4622
4525
|
}
|
|
4623
4526
|
function density_notice(raw_payload, now_ms = Date.now()) {
|
|
@@ -4634,11 +4537,8 @@ var time_density_hook = {
|
|
|
4634
4537
|
};
|
|
4635
4538
|
|
|
4636
4539
|
export {
|
|
4637
|
-
json_value,
|
|
4638
4540
|
cost_blocks,
|
|
4639
4541
|
ESLINT_EDIT_CACHE_FLAGS,
|
|
4640
|
-
process_identity,
|
|
4641
|
-
process_owner_schema,
|
|
4642
4542
|
time_shell,
|
|
4643
4543
|
time_bundle_call,
|
|
4644
4544
|
blocking_issue_schema,
|
|
@@ -4660,10 +4560,6 @@ export {
|
|
|
4660
4560
|
time_transcript_line,
|
|
4661
4561
|
time_spans,
|
|
4662
4562
|
time_batch_guard,
|
|
4663
|
-
lane_paths,
|
|
4664
|
-
file_reader,
|
|
4665
|
-
cost_usage,
|
|
4666
|
-
cost_transcript,
|
|
4667
4563
|
time_hook_transcript,
|
|
4668
4564
|
time_density_hook
|
|
4669
4565
|
};
|