@joshuafolkken/kit 1.1178.0 → 1.1240.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/.claude-plugin/plugin.json +1 -1
- package/.claude/settings.json +2 -2
- package/.claude/skills/dependency-update/SKILL.md +4 -8
- package/.claude/skills/epic-commands/SKILL.md +2 -2
- package/.claude/skills/epic-commands/epic-bundle.md +1 -1
- package/.claude/skills/workflow-commands/SKILL.md +2 -4
- package/.claude/skills/workflow-commands/backlogrun-child.md +6 -4
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +7 -3
- package/.claude/skills/workflow-commands/backlogrun-park.md +23 -2
- package/.claude/skills/workflow-commands/backlogrun-progress.md +9 -4
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +4 -3
- package/.claude/skills/workflow-commands/backlogrun-steps.md +21 -13
- package/.claude/skills/workflow-commands/chain-rule.md +1 -1
- package/.claude/skills/workflow-commands/delegation.md +2 -2
- package/.claude/skills/workflow-commands/followup.md +10 -0
- package/.claude/skills/workflow-commands/fullrun-steps.md +1 -1
- package/.claude/skills/workflow-commands/halfrun.md +1 -1
- package/.claude/skills/workflow-commands/issue-scout.md +1 -1
- package/.claude/skills/workflow-commands/kickoff.md +2 -1
- package/.claude/skills/workflow-commands/latest-gate.md +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +3 -3
- package/.claude/skills/workflow-commands/pre-gate-cut.md +6 -1
- package/.claude/skills/workflow-commands/prerequisite.md +2 -2
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +1 -1
- package/.codex/hooks.json +2 -2
- package/.cursorrules +6 -41
- package/.github/actions/setup-node/action.yml +1 -1
- package/.github/workflows/auto-tag.yml +3 -4
- package/.github/workflows/ci.yml +32 -31
- package/.github/workflows/dependabot-auto-merge.yml +13 -6
- package/.github/workflows/publish.yml +50 -4
- package/.github/workflows/sonar-qube.yml +3 -0
- package/.pnpmfile.mjs +4 -3
- package/.prettierignore +8 -2
- package/CLAUDE.md +18 -20
- package/README.md +44 -38
- package/SECURITY.md +15 -1
- package/dist/CLAUDE.md +18 -20
- package/dist/commands/document-section-cli.js +734 -0
- package/dist/hooks/audit-provision.js +346 -0
- package/dist/hooks/batch-guard.js +5 -4
- package/dist/hooks/{chunk-G6KRCKEC.js → chunk-4TZVB44A.js} +496 -378
- package/dist/hooks/chunk-5VNDSNG3.js +12 -0
- package/dist/hooks/chunk-CDY4NFQG.js +15 -0
- package/dist/hooks/chunk-ELCN5LCH.js +135 -0
- package/dist/hooks/{chunk-VQLLNFNT.js → chunk-F3ELQ2AF.js} +3 -3
- package/dist/hooks/{chunk-I4XSL4TT.js → chunk-GPTFMK5E.js} +1 -1
- package/dist/hooks/{chunk-3V37IID6.js → chunk-JBBMAPC4.js} +23 -14
- package/dist/hooks/{chunk-UAGLLIGZ.js → chunk-KHGB5S3Y.js} +7 -6
- package/dist/hooks/{chunk-GDS5N2KB.js → chunk-KHX4U3BG.js} +735 -683
- package/dist/hooks/{chunk-VESKRQOF.js → chunk-KRBERBBI.js} +3 -3
- package/dist/hooks/{chunk-DO6NWWHU.js → chunk-QVSWU24O.js} +4 -4
- package/dist/hooks/{chunk-S6X6WYKR.js → chunk-WK2XSHSI.js} +1643 -923
- package/dist/hooks/{chunk-ZAL3NRGL.js → chunk-XZYKEM6J.js} +25 -10
- package/dist/hooks/{chunk-32GQTL4F.js → chunk-ZQGD4GBY.js} +4 -2
- package/dist/hooks/codex-hook-adapter.js +14 -12
- package/dist/hooks/duplicate-read-guard.js +6 -5
- package/dist/hooks/format-edited.js +4 -3
- package/dist/hooks/inputs.json +203 -179
- package/dist/hooks/investigation-guard.js +6 -5
- package/dist/hooks/pretool-guard.js +12 -10
- package/dist/hooks/session-lang.js +2 -4
- package/dist/hooks/stop-guard.js +66 -72
- package/dist/josh.js +1088 -78
- package/dist/version/index.d.ts +7 -2
- package/dist/version/index.js +152 -75
- package/eslint/base.js +23 -1
- package/eslint/rules/code-quality.js +3 -0
- package/eslint/rules/early-return-one-liner.js +98 -0
- package/eslint/rules/unicorn.js +16 -1
- package/package.json +7 -6
- package/pnpm-workspace.yaml +9 -4
- package/prettier/basic.d.ts +3 -1
- package/prettier/index.d.ts +3 -1
- package/prettier/static.d.ts +3 -1
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +4 -4
- package/prompts/collaboration-workflow/glossary.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +1 -0
- package/prompts/collaboration-workflow/operating-rules.md +17 -9
- package/prompts/collaboration-workflow/overview.md +2 -2
- package/prompts/collaboration-workflow/principles.md +14 -12
- package/prompts/collaboration-workflow/report-format.md +1 -1
- package/prompts/collaboration-workflow/residency.md +1 -1
- package/prompts/collaboration-workflow/rule-delivery.md +6 -6
- package/prompts/collaboration-workflow/shell-body.md +6 -6
- package/prompts/collaboration-workflow/turn-batching.md +1 -1
- package/prompts/collaboration-workflow/upstream-interrupt.md +12 -2
- package/prompts/collaboration-workflow/wip-cap.md +10 -10
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +1 -1
- package/scripts/agent/agent-headless.ts +29 -0
- package/scripts/agent/agent-launch-environment.ts +6 -2
- package/scripts/agent/codex-agent-argv.ts +2 -1
- package/scripts/auto-ok/auto-ok-cli.ts +1 -1
- package/scripts/backlog/backlog-arrival.ts +3 -3
- package/scripts/backlog/backlog-budget.ts +1 -1
- package/scripts/backlog/backlog-drive-args.ts +135 -0
- package/scripts/backlog/backlog-drive-cli.ts +11 -137
- package/scripts/backlog/backlog-drive-launch.ts +39 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +3 -5
- package/scripts/backlog/backlog-drive-named.ts +3 -3
- package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
- package/scripts/backlog/backlog-drive-owner.ts +1 -1
- package/scripts/backlog/backlog-drive-restore.ts +1 -1
- package/scripts/backlog/backlog-drive-retrospective.ts +1 -1
- package/scripts/backlog/backlog-drive.ts +1 -1
- package/scripts/backlog/backlog-next.ts +16 -5
- package/scripts/backlog/backlog-offer-cli.ts +6 -6
- package/scripts/backlog/backlog-offer.ts +1 -1
- package/scripts/backlog/backlog-plan-cli.ts +1 -1
- package/scripts/backlog/backlog-pool.ts +57 -11
- package/scripts/backlog/backlog-ready.ts +1 -1
- package/scripts/backlog/backlog-scope.ts +1 -1
- package/scripts/backlog/backlog-stalled-detect.ts +2 -2
- package/scripts/backlog/backlog-stalled.ts +1 -1
- package/scripts/build/build-codex-hooks.ts +3 -1
- package/scripts/build/build-commands.ts +66 -0
- package/scripts/build/build-hooks.ts +2 -1
- package/scripts/build/build-library.ts +12 -3
- package/scripts/build/build.ts +70 -0
- package/scripts/build/local-bin.ts +3 -13
- package/scripts/delegation/investigation-reads.ts +3 -1
- package/scripts/discovery/repo-origin.ts +5 -5
- package/scripts/doctor/doctor-consumer.ts +2 -2
- package/scripts/doctor/doctor-io.ts +2 -3
- package/scripts/document/capped-print-part.ts +30 -0
- package/scripts/document/capped-print.ts +3 -4
- package/scripts/document/document-byte-budget.ts +11 -2
- package/scripts/document/document-scan.ts +117 -0
- package/scripts/document/document-section.ts +143 -16
- package/scripts/document/entry-read-budget.ts +5 -3
- package/scripts/document/entry-read-set.ts +10 -89
- package/scripts/document/read-set-cost.ts +98 -0
- package/scripts/epic/epic-add-body.ts +1 -0
- package/scripts/epic/epic-audit-checks.ts +1 -1
- package/scripts/epic/epic-audit-rationale.ts +4 -3
- package/scripts/epic/epic-bundle-cli.ts +14 -3
- package/scripts/epic/epic-bundle-poll.ts +41 -0
- package/scripts/epic/epic-busy.ts +1 -1
- package/scripts/epic/epic-candidate-confirm.ts +3 -2
- package/scripts/epic/epic-classify.ts +1 -1
- package/scripts/epic/epic-cli-argv.ts +78 -46
- package/scripts/epic/epic-cli-remove.ts +11 -19
- package/scripts/epic/epic-cli.ts +74 -73
- package/scripts/epic/epic-close-comment.ts +1 -1
- package/scripts/epic/epic-close.ts +1 -1
- package/scripts/epic/epic-cross-repo.ts +5 -5
- package/scripts/epic/epic-graph.ts +1 -1
- package/scripts/epic/epic-index.ts +1 -1
- package/scripts/epic/epic-issue.ts +2 -6
- package/scripts/epic/epic-lane-offer.ts +2 -2
- package/scripts/epic/epic-next.ts +29 -42
- package/scripts/epic/epic-solo-stale.ts +1 -1
- package/scripts/epic/epic-triage.ts +8 -4
- package/scripts/epic/epic-validate.ts +1 -1
- package/scripts/followup/git-followup-finish.ts +2 -2
- package/scripts/followup/git-followup-label.ts +2 -2
- package/scripts/followup/git-followup-merged.ts +2 -2
- package/scripts/followup/git-pr-followup-checks.ts +142 -0
- package/scripts/followup/git-pr-followup.ts +4 -129
- package/scripts/gate/core-admission.ts +162 -0
- package/scripts/gate/core-budget.ts +190 -68
- package/scripts/gate/gate-plan.ts +80 -7
- package/scripts/gate/gate-report.ts +28 -9
- package/scripts/gate/gate-skip.ts +38 -7
- package/scripts/gate/hook-gate-reuse.ts +12 -10
- package/scripts/gate/machine-capacity.ts +175 -0
- package/scripts/gate/pre-commit-type-check.ts +4 -1
- package/scripts/gate/project-checks.ts +6 -9
- package/scripts/gate/type-check-step.ts +2 -3
- package/scripts/gate/verification-gate.ts +34 -10
- package/scripts/gh/git-gh-api-path.ts +2 -2
- package/scripts/gh/git-gh-issue-rest.ts +3 -3
- package/scripts/gh/git-gh-issue-write.ts +53 -7
- package/scripts/gh/git-gh-pr-read.ts +64 -19
- package/scripts/gh/git-gh-pr-rest.ts +1 -1
- package/scripts/gh/git-gh-pr.ts +5 -1
- package/scripts/gh/git-pr-ai-review.ts +1 -1
- package/scripts/gh/git-pr-checks-eval.ts +1 -3
- package/scripts/gh/git-pr-checks-parse.ts +1 -1
- package/scripts/gh/git-pr-checks-watch.ts +6 -5
- package/scripts/gh/git-pr-checks.ts +7 -5
- package/scripts/gh/git-pr-coderabbit.ts +1 -1
- package/scripts/gh/git-pr-error.ts +1 -3
- package/scripts/gh/git-pr.ts +9 -13
- package/scripts/gh/github-issue-url.ts +2 -2
- package/scripts/git/constants.ts +2 -6
- package/scripts/git/git-command.ts +20 -218
- package/scripts/git/git-diff-reads.ts +225 -0
- package/scripts/git/git-error.ts +4 -12
- package/scripts/git/git-pre-push-hook.ts +139 -0
- package/scripts/git/git-prompt.ts +2 -6
- package/scripts/git/git-spawn-sync.ts +3 -1
- package/scripts/git/git-spawn.ts +1 -1
- package/scripts/git/git-staging.ts +4 -6
- package/scripts/git/git-status.ts +3 -9
- package/scripts/hooks/codex-hook-adapter.ts +1 -1
- package/scripts/hooks/edited-cspell.ts +2 -4
- package/scripts/hooks/format-edited-file.ts +3 -12
- package/scripts/hooks/pre-push-unit.ts +31 -9
- package/scripts/hooks/reserved-run.ts +2 -2
- package/scripts/hooks/run-hook.sh +5 -4
- package/scripts/hooks/stop-guard.ts +5 -3
- package/scripts/init/init-actions.ts +0 -5
- package/scripts/init/init-ai-copy.ts +13 -2
- package/scripts/init/init-logic-json-merge.ts +19 -0
- package/scripts/init/init-logic-secretlint.ts +7 -7
- package/scripts/init/init-logic-workspace.ts +41 -2
- package/scripts/init/init-logic.ts +16 -26
- package/scripts/init/init.ts +10 -16
- package/scripts/init/initial-commit.ts +4 -4
- package/scripts/init/kit-development-versions.ts +40 -0
- package/scripts/init/kit-setup-state.ts +2 -2
- package/scripts/init/package-manager-pin.ts +35 -0
- package/scripts/init/start-exec.ts +68 -19
- package/scripts/init/start-setup-pr.ts +9 -9
- package/scripts/init/start-steps.ts +6 -10
- package/scripts/issue/defect-rate-cli.ts +1 -1
- package/scripts/issue/git-next-issues.ts +1 -1
- package/scripts/issue/issue-auto-ok.ts +32 -7
- package/scripts/issue/issue-backlinks-cli.ts +2 -2
- package/scripts/issue/issue-backlinks.ts +9 -9
- package/scripts/issue/issue-comment-cli.ts +19 -13
- package/scripts/issue/issue-file-cli.ts +72 -22
- package/scripts/issue/issue-file.ts +29 -1
- package/scripts/issue/issue-labels.ts +13 -0
- package/scripts/issue/issue-release-cli.ts +155 -0
- package/scripts/issue/issue-release.ts +58 -0
- package/scripts/issue/issue-scout-closed.ts +1 -1
- package/scripts/issue/issue-state-cli.ts +30 -74
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-command-types.ts +14 -0
- package/scripts/josh/josh-commands-ai.ts +4 -4
- package/scripts/josh/josh-commands-backlog.ts +4 -1
- package/scripts/josh/josh-commands-development.ts +18 -0
- package/scripts/josh/josh-commands-document.ts +1 -0
- package/scripts/josh/josh-commands-issue.ts +8 -1
- package/scripts/josh/josh-commands-lane.ts +24 -1
- package/scripts/josh/josh-commands-maintenance.ts +6 -6
- package/scripts/josh/josh-commands-run.ts +12 -7
- package/scripts/josh/josh-in-process.ts +28 -9
- package/scripts/josh/josh-logic.ts +34 -15
- package/scripts/josh/process-identity.ts +1 -3
- package/scripts/josh/session-language-cli.ts +3 -4
- package/scripts/lane/lane-await.ts +5 -1
- package/scripts/lane/lane-child-invocation.ts +2 -2
- package/scripts/lane/lane-cli.ts +12 -4
- package/scripts/lane/lane-dispatch.ts +14 -10
- package/scripts/lane/lane-environment.ts +5 -1
- package/scripts/lane/lane-handoff.ts +1 -1
- package/scripts/lane/lane-install.ts +2 -13
- package/scripts/lane/lane-launch-cli.ts +15 -1
- package/scripts/lane/lane-ledger.ts +145 -0
- package/scripts/lane/lane-leftover.ts +44 -30
- package/scripts/lane/lane-load.ts +108 -0
- package/scripts/lane/lane-measure-cli.ts +149 -0
- package/scripts/lane/lane-occupancy.ts +3 -0
- package/scripts/lane/lane-open.ts +5 -5
- package/scripts/lane/lane-paths.ts +13 -0
- package/scripts/lane/lane-reap.ts +1 -3
- package/scripts/lane/lane-registry.ts +11 -0
- package/scripts/lane/lane-relaunch.ts +1 -1
- package/scripts/lane/lane-stats.ts +224 -0
- package/scripts/lane/lane-stray.ts +140 -0
- package/scripts/lane/lane-vacant.ts +36 -0
- package/scripts/lane/openai-lane-ship.ts +2 -2
- package/scripts/lane/openai-lane-supervisor-owner.ts +180 -0
- package/scripts/lane/openai-lane-supervisor.ts +7 -165
- package/scripts/lane/openai-review-broker.ts +2 -4
- package/scripts/lib/ancestor-directories.ts +35 -0
- package/scripts/lib/animation-helpers.ts +2 -2
- package/scripts/lib/buffered-process.ts +3 -7
- package/scripts/lib/cli-flags.ts +71 -1
- package/scripts/lib/spawn-exit.ts +2 -2
- package/scripts/lib/timeouts.ts +35 -2
- package/scripts/lines/line-budget.ts +4 -6
- package/scripts/notify/telegram-test.ts +6 -0
- package/scripts/observations/observation-ledger-line.ts +6 -6
- package/scripts/observations/observation-ledger-migrate.ts +55 -4
- package/scripts/observations/observation-ledger.ts +26 -7
- package/scripts/overrides/lockfile-overrides.ts +1 -1
- package/scripts/overrides/overrides-logic.ts +1 -1
- package/scripts/propagate/propagate-git.ts +1 -1
- package/scripts/propagate/propagate-publish.ts +2 -2
- package/scripts/propagate/propagate-steps.ts +20 -15
- package/scripts/propagate/propagate.ts +36 -27
- package/scripts/refactor/import-graph.ts +18 -1
- package/scripts/refactor/refactor-lint.ts +4 -4
- 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/repo/repository-labels.ts +2 -2
- package/scripts/repo/required-checks-logic.ts +1 -3
- package/scripts/review/live-evidence.ts +2 -4
- package/scripts/review/review-brief-cli.ts +1 -1
- package/scripts/review/review-finding-ledger.ts +1 -1
- package/scripts/review/review-findings-cli.ts +1 -3
- package/scripts/rules/decision-oracle-batch.ts +128 -0
- package/scripts/rules/decision-oracle-tokens.ts +21 -0
- package/scripts/rules/decision-oracle.ts +8 -120
- package/scripts/rules/delivered-rules.ts +26 -182
- package/scripts/rules/direct-filing.ts +1 -1
- package/scripts/rules/early-heartbeat.ts +3 -3
- package/scripts/rules/git-argv.ts +1 -1
- package/scripts/rules/git-force.ts +1 -1
- package/scripts/rules/implementation-cut.ts +2 -2
- package/scripts/rules/index-guard.ts +1 -1
- package/scripts/rules/issue-comments.ts +118 -0
- package/scripts/rules/{issue-fold.ts → issue-fold-rule.ts} +2 -2
- package/scripts/rules/lane-background.ts +2 -2
- package/scripts/rules/lane-park.ts +18 -0
- package/scripts/rules/lane-split-park.ts +128 -0
- package/scripts/rules/oracle-firing.ts +1 -1
- package/scripts/rules/poll-loop.ts +1 -1
- package/scripts/rules/pre-gate-cut.ts +1 -1
- package/scripts/rules/protected-files.ts +59 -4
- package/scripts/rules/{run-tail.ts → run-tail-rule.ts} +2 -2
- package/scripts/rules/shell-body-trigger.ts +1 -1
- package/scripts/rules/stop-rules.ts +18 -7
- package/scripts/rules/test-declared-commit.ts +4 -4
- package/scripts/rules/wip-cap.ts +63 -0
- package/scripts/run/{run-carry-args.ts → carry/run-carry-args.ts} +37 -13
- package/scripts/run/{run-carry-change.ts → carry/run-carry-change.ts} +29 -7
- package/scripts/run/{run-carry-cli.ts → carry/run-carry-cli.ts} +4 -6
- package/scripts/run/{run-carry.ts → carry/run-carry.ts} +1 -1
- package/scripts/run/{run-cut-args.ts → cut/run-cut-args.ts} +1 -1
- package/scripts/run/{run-cut-cli.ts → cut/run-cut-cli.ts} +18 -5
- package/scripts/run/{run-cut.ts → cut/run-cut.ts} +1 -1
- package/scripts/run/{run-entry-cli.ts → entry/run-entry-cli.ts} +11 -11
- package/scripts/run/{run-entry.ts → entry/run-entry.ts} +2 -2
- package/scripts/run/{run-event-render.ts → event/run-event-render.ts} +1 -0
- package/scripts/run/{run-event-scope.ts → event/run-event-scope.ts} +1 -1
- package/scripts/run/{run-event-stream-emit.ts → event/run-event-stream-emit.ts} +1 -1
- package/scripts/run/{run-event-stream.ts → event/run-event-stream.ts} +20 -2
- package/scripts/run/{run-hold-cli.ts → hold/run-hold-cli.ts} +5 -5
- package/scripts/run/{run-merge-cli.ts → merge/run-merge-cli.ts} +10 -5
- package/scripts/run/{run-merge-steps.ts → merge/run-merge-steps.ts} +53 -5
- package/scripts/run/{run-merge.ts → merge/run-merge.ts} +1 -1
- package/scripts/run/{run-progress-cli.ts → progress/run-progress-cli.ts} +1 -1
- package/scripts/run/{run-progress-config.ts → progress/run-progress-config.ts} +2 -17
- package/scripts/run/{run-progress-read.ts → progress/run-progress-read.ts} +5 -5
- package/scripts/run/{run-progress.ts → progress/run-progress.ts} +1 -1
- package/scripts/run/{run-review-steps.ts → review/run-review-steps.ts} +2 -3
- package/scripts/run/run-ending.ts +2 -2
- package/scripts/run/run-halfrun-resume.ts +6 -1
- package/scripts/run/run-headless.ts +1 -1
- package/scripts/run/run-invocation.ts +85 -84
- package/scripts/run/run-liveness.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +1 -1
- package/scripts/run/run-preflight.ts +6 -6
- package/scripts/run/run-prep-cli.ts +1 -1
- package/scripts/run/run-prrun-resume.ts +1 -1
- package/scripts/run/run-report-cli.ts +4 -4
- package/scripts/run/run-report.ts +2 -2
- package/scripts/run/run-status-cli.ts +1 -1
- package/scripts/run/run-step-cli.ts +3 -3
- package/scripts/run/run-step.ts +7 -4
- package/scripts/run/run-stop-notify.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +4 -4
- package/scripts/run/run-stranded.ts +2 -2
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +5 -3
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/run/{run-ship-cli.ts → ship/run-ship-cli.ts} +2 -2
- package/scripts/run/{run-ship-detach.ts → ship/run-ship-detach.ts} +3 -3
- package/scripts/run/ship/run-ship-lock.ts +50 -0
- package/scripts/run/{run-ship-preflight.ts → ship/run-ship-preflight.ts} +6 -2
- package/scripts/run/{run-ship-probe.ts → ship/run-ship-probe.ts} +2 -2
- package/scripts/run/{run-ship-return.ts → ship/run-ship-return.ts} +4 -3
- package/scripts/run/{run-ship-review-steps.ts → ship/run-ship-review-steps.ts} +3 -3
- package/scripts/run/{run-ship-scoped.ts → ship/run-ship-scoped.ts} +10 -1
- package/scripts/run/{run-ship-steps.ts → ship/run-ship-steps.ts} +11 -12
- package/scripts/run/ship/run-ship-stop-text.ts +13 -0
- package/scripts/run/{run-ship-sync.ts → ship/run-ship-sync.ts} +25 -11
- package/scripts/run/{run-tidy-lanes.ts → tidy/run-tidy-lanes.ts} +1 -1
- package/scripts/run/{run-wake-cli.ts → wake/run-wake-cli.ts} +25 -11
- package/scripts/run/{run-wake-describe.ts → wake/run-wake-describe.ts} +58 -7
- package/scripts/run/{run-wake-driver.ts → wake/run-wake-driver.ts} +59 -8
- package/scripts/run/{run-wake-handoff.ts → wake/run-wake-handoff.ts} +1 -1
- package/scripts/run/{run-wake-loop.ts → wake/run-wake-loop.ts} +13 -15
- package/scripts/run/wake/run-wake-restart.ts +58 -0
- package/scripts/run/{run-wake-session.ts → wake/run-wake-session.ts} +3 -3
- package/scripts/run/{run-wake.ts → wake/run-wake.ts} +16 -65
- package/scripts/safe-chain/preinstall-command.ts +20 -21
- package/scripts/safe-chain/project-config.ts +19 -15
- package/scripts/sync/sync-ai-files.ts +1 -1
- package/scripts/sync/sync-configs.ts +2 -1
- package/scripts/sync/sync.ts +15 -2
- package/scripts/test/unit-worker-share.ts +1 -0
- package/scripts/time-runtime/time-background.ts +5 -1
- package/scripts/time-runtime/time-instant.ts +3 -1
- package/scripts/time-runtime/time-spans.ts +6 -139
- package/scripts/time-runtime/time-tool-call.ts +160 -0
- package/scripts/version/effective-upstream.ts +2 -20
- package/scripts/version/latest-corepack.ts +124 -93
- package/scripts/version/latest-regression.ts +1 -1
- package/scripts/version/latest-update.ts +4 -4
- package/scripts/version/npm-registry.ts +20 -5
- package/scripts/version/publishable-range-check.ts +2 -2
- package/scripts/version/publishable-range.ts +1 -1
- package/scripts/version/release-age.ts +48 -38
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +40 -0
- package/scripts/version/upgrade-shell-command.ts +48 -8
- package/scripts/version/version-check-logic.ts +23 -14
- package/scripts/version/version-commands.ts +23 -11
- package/scripts/version/version-remote.ts +28 -13
- package/templates/pnpm-workspace.basic.yaml +4 -0
- package/templates/workflows/dependabot-auto-merge.yml +5 -5
- package/templates/workflows/github-release.yml +6 -0
- package/scripts/build/build-config-merge.ts +0 -27
- package/scripts/build/build-managed-marker.ts +0 -27
- package/scripts/build/build-self-sync-guard.ts +0 -27
- package/scripts/build/build-version.ts +0 -26
- package/scripts/version/preinstall-version-update.ts +0 -86
- /package/scripts/git/{schemas.ts → git-schemas.ts} +0 -0
- /package/scripts/overrides/{schemas.ts → overrides-schemas.ts} +0 -0
- /package/scripts/run/{run-carry-conversation.ts → carry/run-carry-conversation.ts} +0 -0
- /package/scripts/run/{run-carry-reclaim.ts → carry/run-carry-reclaim.ts} +0 -0
- /package/scripts/run/{run-carry-stash.ts → carry/run-carry-stash.ts} +0 -0
- /package/scripts/run/{run-carry-streak.ts → carry/run-carry-streak.ts} +0 -0
- /package/scripts/run/{run-cut-handoff.ts → cut/run-cut-handoff.ts} +0 -0
- /package/scripts/run/{run-cut-report.ts → cut/run-cut-report.ts} +0 -0
- /package/scripts/run/{run-entry-stop.ts → entry/run-entry-stop.ts} +0 -0
- /package/scripts/run/{run-event-cli.ts → event/run-event-cli.ts} +0 -0
- /package/scripts/run/{run-event-follow.ts → event/run-event-follow.ts} +0 -0
- /package/scripts/run/{run-event-watch.ts → event/run-event-watch.ts} +0 -0
- /package/scripts/run/{run-hold.ts → hold/run-hold.ts} +0 -0
- /package/scripts/run/{run-progress-args.ts → progress/run-progress-args.ts} +0 -0
- /package/scripts/run/{run-progress-clock.ts → progress/run-progress-clock.ts} +0 -0
- /package/scripts/run/{run-review-cli.ts → review/run-review-cli.ts} +0 -0
- /package/scripts/run/{run-review.ts → review/run-review.ts} +0 -0
- /package/scripts/run/{run-ship-next.ts → ship/run-ship-next.ts} +0 -0
- /package/scripts/run/{run-ship-pre-detach.ts → ship/run-ship-pre-detach.ts} +0 -0
- /package/scripts/run/{run-ship-review.ts → ship/run-ship-review.ts} +0 -0
- /package/scripts/run/{run-ship-stage.ts → ship/run-ship-stage.ts} +0 -0
- /package/scripts/run/{run-ship.ts → ship/run-ship.ts} +0 -0
- /package/scripts/run/{run-tidy-cli.ts → tidy/run-tidy-cli.ts} +0 -0
- /package/scripts/run/{run-tidy-stashes.ts → tidy/run-tidy-stashes.ts} +0 -0
- /package/scripts/run/{run-tidy.ts → tidy/run-tidy.ts} +0 -0
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ENV_FILE_NAME
|
|
3
3
|
} from "./chunk-RKUAD3I6.js";
|
|
4
|
+
import {
|
|
5
|
+
PLATFORM_TEMP_ROOT,
|
|
6
|
+
PROBE_TIMEOUT_MS,
|
|
7
|
+
stamp_file
|
|
8
|
+
} from "./chunk-ELCN5LCH.js";
|
|
4
9
|
|
|
5
10
|
// scripts/lib/json-value.ts
|
|
6
11
|
function parse_or_undefined(text) {
|
|
@@ -176,6 +181,9 @@ var BACKLOG_COMMANDS = {
|
|
|
176
181
|
},
|
|
177
182
|
"backlog:stalled": {
|
|
178
183
|
script: "scripts/backlog/backlog-stalled-cli.ts",
|
|
184
|
+
// A stall sends one Telegram warning (joshuafolkken/kit#3357). The `Stop` hook calls the detector
|
|
185
|
+
// directly, so this flag costs only the manual command its in-process dispatch.
|
|
186
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
179
187
|
description: "Report whether ready backlog work is sitting undispatched with a free lane and no recent dispatch",
|
|
180
188
|
category: "AI tools",
|
|
181
189
|
reference: ["", "automation", ["network"]]
|
|
@@ -194,7 +202,8 @@ var DOCUMENT_COMMANDS = {
|
|
|
194
202
|
script: "scripts/document/document-section-cli.ts",
|
|
195
203
|
description: 'Print one section of a markdown document, for a `file.md` \u2192 "Heading" reference',
|
|
196
204
|
category: "AI tools",
|
|
197
|
-
reference: ["<file> <heading>", "automation", ["none"]]
|
|
205
|
+
reference: ["<file> <heading>", "automation", ["none"]],
|
|
206
|
+
is_bundled: true
|
|
198
207
|
},
|
|
199
208
|
"read:set": {
|
|
200
209
|
script: "scripts/document/read-set-cli.ts",
|
|
@@ -300,10 +309,16 @@ var ISSUE_COMMANDS = {
|
|
|
300
309
|
description: "File an Issue with every filing step: lint, Origin, WIP cap, duplicate scout, labels, then epic:bundle",
|
|
301
310
|
category: "AI tools",
|
|
302
311
|
reference: [
|
|
303
|
-
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok]",
|
|
312
|
+
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok] [--release]",
|
|
304
313
|
"automation",
|
|
305
314
|
["network"]
|
|
306
315
|
]
|
|
316
|
+
},
|
|
317
|
+
"issue:release": {
|
|
318
|
+
script: "scripts/issue/issue-release-cli.ts",
|
|
319
|
+
description: "Link an Issue to the repository's open release Issue as its blocker, filing one when none is open",
|
|
320
|
+
category: "AI tools",
|
|
321
|
+
reference: ["<issue>", "automation", ["network"]]
|
|
307
322
|
}
|
|
308
323
|
};
|
|
309
324
|
|
|
@@ -311,6 +326,10 @@ var ISSUE_COMMANDS = {
|
|
|
311
326
|
var LANE_SCRIPT = "scripts/lane/lane-cli.ts";
|
|
312
327
|
var LANE_ARGUMENTS = { script: LANE_SCRIPT, tsx_arguments: OPTIONAL_ENV_FILE_FLAGS };
|
|
313
328
|
var ISSUE_WITH_OPTIONS = "<issue> [options]";
|
|
329
|
+
var MEASURE_ARGUMENTS = {
|
|
330
|
+
script: "scripts/lane/lane-measure-cli.ts",
|
|
331
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
|
|
332
|
+
};
|
|
314
333
|
var LANE_COMMANDS = {
|
|
315
334
|
"lane:open": {
|
|
316
335
|
...LANE_ARGUMENTS,
|
|
@@ -335,7 +354,7 @@ var LANE_COMMANDS = {
|
|
|
335
354
|
},
|
|
336
355
|
"lane:prune": {
|
|
337
356
|
...LANE_ARGUMENTS,
|
|
338
|
-
description: "Close every lane an interruption left without its work tree",
|
|
357
|
+
description: "Close every lane an interruption left without its work tree, then sweep unregistered leftovers under the lanes root",
|
|
339
358
|
category: "AI tools",
|
|
340
359
|
reference: ["", "automation", ["files", "git"]],
|
|
341
360
|
default_script_arguments: ["prune"]
|
|
@@ -366,11 +385,27 @@ var LANE_COMMANDS = {
|
|
|
366
385
|
description: "Collapse a backlogrun lane-start event into one call: open the lane, pop and re-install on the first, dispatch the child",
|
|
367
386
|
category: "AI tools",
|
|
368
387
|
reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
|
|
388
|
+
},
|
|
389
|
+
// The lane-limit measurement (joshuafolkken/kit#3355): `.env` is read so `lane:stats` labels the row
|
|
390
|
+
// with the `JOSH_LANE_LIMIT` a person set there.
|
|
391
|
+
"lane:sample": {
|
|
392
|
+
...MEASURE_ARGUMENTS,
|
|
393
|
+
description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger",
|
|
394
|
+
category: "AI tools",
|
|
395
|
+
reference: ["[--every <seconds>]", "maintainer", ["files"]],
|
|
396
|
+
default_script_arguments: ["sample"]
|
|
397
|
+
},
|
|
398
|
+
"lane:stats": {
|
|
399
|
+
...MEASURE_ARGUMENTS,
|
|
400
|
+
description: "Print one table row of lane throughput, gate duration and machine load over a period",
|
|
401
|
+
category: "AI tools",
|
|
402
|
+
reference: ["--period <days> [--limit <lane-limit>]", "maintainer", ["none"]],
|
|
403
|
+
default_script_arguments: ["stats"]
|
|
369
404
|
}
|
|
370
405
|
};
|
|
371
406
|
|
|
372
407
|
// scripts/josh/josh-commands-run.ts
|
|
373
|
-
var RUN_HOLD_SCRIPT = "scripts/run/run-hold-cli.ts";
|
|
408
|
+
var RUN_HOLD_SCRIPT = "scripts/run/hold/run-hold-cli.ts";
|
|
374
409
|
var RUN_COMMANDS = {
|
|
375
410
|
"run:hold": {
|
|
376
411
|
script: RUN_HOLD_SCRIPT,
|
|
@@ -386,19 +421,22 @@ var RUN_COMMANDS = {
|
|
|
386
421
|
default_script_arguments: ["--release"]
|
|
387
422
|
},
|
|
388
423
|
"run:tidy": {
|
|
389
|
-
script: "scripts/run/run-tidy-cli.ts",
|
|
424
|
+
script: "scripts/run/tidy/run-tidy-cli.ts",
|
|
390
425
|
description: "Close merged lanes and drop stashes whose issues are all merged",
|
|
391
426
|
category: "AI tools",
|
|
392
427
|
reference: ["", "automation", ["git", "network", "files"]]
|
|
393
428
|
},
|
|
394
429
|
"run:carry": {
|
|
395
|
-
script: "scripts/run/run-carry-cli.ts",
|
|
430
|
+
script: "scripts/run/carry/run-carry-cli.ts",
|
|
431
|
+
// `--stopped` sends the stop confirmation, so the Telegram credentials come from `.env` as for
|
|
432
|
+
// `run:wake` below (joshuafolkken/kit#3357).
|
|
433
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
396
434
|
description: "Carry one invocation\u2019s budget across its own session cuts",
|
|
397
435
|
category: "AI tools",
|
|
398
436
|
reference: ["<operation> [arguments...]", "automation", ["files"]]
|
|
399
437
|
},
|
|
400
438
|
"run:wake": {
|
|
401
|
-
script: "scripts/run/run-wake-cli.ts",
|
|
439
|
+
script: "scripts/run/wake/run-wake-cli.ts",
|
|
402
440
|
// `.env` rather than the ambient environment:
|
|
403
441
|
// the failure warning needs the Telegram credentials, the same
|
|
404
442
|
// reasons `notify` and `followup` carry these flags.
|
|
@@ -408,7 +446,7 @@ var RUN_COMMANDS = {
|
|
|
408
446
|
reference: ["[options]", "automation", ["processes", "notifications"]]
|
|
409
447
|
},
|
|
410
448
|
"run:cut": {
|
|
411
|
-
script: "scripts/run/run-cut-cli.ts",
|
|
449
|
+
script: "scripts/run/cut/run-cut-cli.ts",
|
|
412
450
|
description: "Cut a lane child before the gate and resume a fresh process",
|
|
413
451
|
category: "AI tools",
|
|
414
452
|
reference: ["[--resume] <issue> [--impl] [--handoff <path>]", "automation", ["files"]]
|
|
@@ -426,7 +464,7 @@ var RUN_COMMANDS = {
|
|
|
426
464
|
reference: ["<issue> --output <path> [--repo <owner/repo>]", "automation", ["network"]]
|
|
427
465
|
},
|
|
428
466
|
"run:progress": {
|
|
429
|
-
script: "scripts/run/run-progress-cli.ts",
|
|
467
|
+
script: "scripts/run/progress/run-progress-cli.ts",
|
|
430
468
|
description: "Report an unattended run\u2019s progress once it has gone quiet for an interval",
|
|
431
469
|
category: "AI tools",
|
|
432
470
|
reference: [
|
|
@@ -445,7 +483,9 @@ var RUN_COMMANDS = {
|
|
|
445
483
|
// read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
|
|
446
484
|
// `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
|
|
447
485
|
"run:entry": {
|
|
448
|
-
script: "scripts/run/run-entry-cli.ts",
|
|
486
|
+
script: "scripts/run/entry/run-entry-cli.ts",
|
|
487
|
+
// A `busy` hold or an `over` budget sends the stop confirmation (joshuafolkken/kit#3357).
|
|
488
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
449
489
|
description: "Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step",
|
|
450
490
|
category: "AI tools",
|
|
451
491
|
reference: ["<issue> [--to <command>]", "automation", ["git", "network", "files"]]
|
|
@@ -609,13 +649,13 @@ var AI_COMMANDS = {
|
|
|
609
649
|
reference: ["[<owner/repo>]", "automation", ["none"]]
|
|
610
650
|
},
|
|
611
651
|
"run:merge": {
|
|
612
|
-
script: "scripts/run/run-merge-cli.ts",
|
|
652
|
+
script: "scripts/run/merge/run-merge-cli.ts",
|
|
613
653
|
description: "Collapse a backlogrun merge event into one call: confirm the child, do the post-merge steps, offer the next child",
|
|
614
654
|
category: "AI tools",
|
|
615
655
|
reference: [ISSUE_WITH_OPTIONS2, "automation", ["git", "network"]]
|
|
616
656
|
},
|
|
617
657
|
"run:review": {
|
|
618
|
-
script: "scripts/run/run-review-cli.ts",
|
|
658
|
+
script: "scripts/run/review/run-review-cli.ts",
|
|
619
659
|
description: "Start the gate in the background and print the /code-review brief in one call so the two overlap (--join to join the gate and check its verdict)",
|
|
620
660
|
category: "AI tools",
|
|
621
661
|
reference: ["[--join]", "automation", ["processes", "files"]]
|
|
@@ -634,7 +674,7 @@ var AI_COMMANDS = {
|
|
|
634
674
|
// (`run:tail`) were four round trips re-billing the run's full context each. It stops at the first
|
|
635
675
|
// failed step and names it, so the run reads only the step to fix.
|
|
636
676
|
ship: {
|
|
637
|
-
script: "scripts/run/run-ship-cli.ts",
|
|
677
|
+
script: "scripts/run/ship/run-ship-cli.ts",
|
|
638
678
|
description: "Ship a change in one call: gate, commit/push/PR, the CI-wait merge and the report bookkeeping, stopping at the first failed step",
|
|
639
679
|
category: "AI tools",
|
|
640
680
|
reference: [
|
|
@@ -644,7 +684,7 @@ var AI_COMMANDS = {
|
|
|
644
684
|
]
|
|
645
685
|
},
|
|
646
686
|
"run:event": {
|
|
647
|
-
script: "scripts/run/run-event-cli.ts",
|
|
687
|
+
script: "scripts/run/event/run-event-cli.ts",
|
|
648
688
|
description: "Append to, read or watch the run\u2019s append-only event stream (--append <kind> <text> | --from|--follow <n> | --watch [<n>] | --last)",
|
|
649
689
|
category: "AI tools",
|
|
650
690
|
reference: [
|
|
@@ -704,6 +744,815 @@ var CLONE_COMMANDS = {
|
|
|
704
744
|
}
|
|
705
745
|
};
|
|
706
746
|
|
|
747
|
+
// scripts/gate/core-budget.ts
|
|
748
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
749
|
+
import { readdirSync as readdirSync2 } from "node:fs";
|
|
750
|
+
import { availableParallelism as availableParallelism3 } from "node:os";
|
|
751
|
+
import path3 from "node:path";
|
|
752
|
+
|
|
753
|
+
// scripts/josh/process-identity.ts
|
|
754
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
755
|
+
import { randomUUID } from "node:crypto";
|
|
756
|
+
import { readFileSync, rmSync } from "node:fs";
|
|
757
|
+
import { createServer } from "node:net";
|
|
758
|
+
import path from "node:path";
|
|
759
|
+
var PS_COMMAND = "/bin/ps";
|
|
760
|
+
var FORMAT_FLAG = "-o";
|
|
761
|
+
var START_TIME_FORMAT = "lstart=";
|
|
762
|
+
var PID_FLAG = "-p";
|
|
763
|
+
var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
|
|
764
|
+
var LIVENESS_SIGNAL = 0;
|
|
765
|
+
var LOWEST_REAL_PID = 1;
|
|
766
|
+
var PROC_START_FIELD_INDEX = 19;
|
|
767
|
+
var BEACON_SCHEME = "socket:";
|
|
768
|
+
var BEACON_SUFFIX = ".sock";
|
|
769
|
+
var BEACON_PREFIX = `josh-process-identity-${String(process.getuid?.() ?? "")}-`;
|
|
770
|
+
var BEACON_ID_LENGTH = 36;
|
|
771
|
+
var BEACON_ID_PATTERN = /^[\da-f-]+$/u;
|
|
772
|
+
var WINDOWS_PLATFORM = "win32";
|
|
773
|
+
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));";
|
|
774
|
+
var beacons = /* @__PURE__ */ new Map();
|
|
775
|
+
var exit_cleanup = { is_registered: false };
|
|
776
|
+
function is_live_pid(pid) {
|
|
777
|
+
if (pid < LOWEST_REAL_PID) return false;
|
|
778
|
+
try {
|
|
779
|
+
process.kill(pid, LIVENESS_SIGNAL);
|
|
780
|
+
return true;
|
|
781
|
+
} catch {
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
function read_proc_start(pid) {
|
|
786
|
+
try {
|
|
787
|
+
const stat = readFileSync(`/proc/${String(pid)}/stat`, "utf8");
|
|
788
|
+
const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
|
|
789
|
+
const start = fields[PROC_START_FIELD_INDEX];
|
|
790
|
+
return start === void 0 ? void 0 : `proc:${start}`;
|
|
791
|
+
} catch {
|
|
792
|
+
return void 0;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
function read_ps_start(pid) {
|
|
796
|
+
try {
|
|
797
|
+
const printed = execFileSync(
|
|
798
|
+
PS_COMMAND,
|
|
799
|
+
[FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
|
|
800
|
+
{
|
|
801
|
+
encoding: "utf8",
|
|
802
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
803
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
804
|
+
env: PROBE_ENVIRONMENT
|
|
805
|
+
}
|
|
806
|
+
).trim();
|
|
807
|
+
return printed.length > 0 ? printed : void 0;
|
|
808
|
+
} catch {
|
|
809
|
+
return void 0;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
var START_PROBES = { read_proc_start, read_ps_start };
|
|
813
|
+
function safe_probe(probe, pid) {
|
|
814
|
+
try {
|
|
815
|
+
return probe(pid);
|
|
816
|
+
} catch {
|
|
817
|
+
return void 0;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
function read_start(pid, probes = START_PROBES) {
|
|
821
|
+
return safe_probe(probes.read_proc_start, pid) ?? safe_probe(probes.read_ps_start, pid);
|
|
822
|
+
}
|
|
823
|
+
function close_beacon(token) {
|
|
824
|
+
const server = beacons.get(token);
|
|
825
|
+
if (server === void 0) return;
|
|
826
|
+
beacons.delete(token);
|
|
827
|
+
server.close();
|
|
828
|
+
rmSync(token.slice(BEACON_SCHEME.length), { force: true });
|
|
829
|
+
}
|
|
830
|
+
function close_beacons() {
|
|
831
|
+
for (const token of beacons.keys()) close_beacon(token);
|
|
832
|
+
}
|
|
833
|
+
function ensure_exit_cleanup() {
|
|
834
|
+
if (exit_cleanup.is_registered) return;
|
|
835
|
+
exit_cleanup.is_registered = true;
|
|
836
|
+
process.once("exit", close_beacons);
|
|
837
|
+
}
|
|
838
|
+
function ignore_beacon_error() {
|
|
839
|
+
}
|
|
840
|
+
function bind_beacon(target) {
|
|
841
|
+
return createServer().on("error", ignore_beacon_error).listen(target);
|
|
842
|
+
}
|
|
843
|
+
function try_bind_beacon(bind, target) {
|
|
844
|
+
try {
|
|
845
|
+
const server = bind(target);
|
|
846
|
+
return server.listening ? server : void 0;
|
|
847
|
+
} catch {
|
|
848
|
+
return void 0;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
function open_beacon(bind = bind_beacon) {
|
|
852
|
+
const target = path.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
|
|
853
|
+
const token = `${BEACON_SCHEME}${target}`;
|
|
854
|
+
const server = try_bind_beacon(bind, target);
|
|
855
|
+
if (server === void 0) return void 0;
|
|
856
|
+
server.unref();
|
|
857
|
+
beacons.set(token, server);
|
|
858
|
+
ensure_exit_cleanup();
|
|
859
|
+
return token;
|
|
860
|
+
}
|
|
861
|
+
function resolve_own_start(probes = START_PROBES, platform = process.platform) {
|
|
862
|
+
const start = read_start(process.pid, probes);
|
|
863
|
+
if (start !== void 0 || platform === WINDOWS_PLATFORM) return start;
|
|
864
|
+
return open_beacon();
|
|
865
|
+
}
|
|
866
|
+
function is_valid_beacon_name(name) {
|
|
867
|
+
if (!name.startsWith(BEACON_PREFIX) || !name.endsWith(BEACON_SUFFIX)) return false;
|
|
868
|
+
const id = name.slice(BEACON_PREFIX.length, -BEACON_SUFFIX.length);
|
|
869
|
+
return id.length === BEACON_ID_LENGTH && BEACON_ID_PATTERN.test(id);
|
|
870
|
+
}
|
|
871
|
+
function beacon_target(token) {
|
|
872
|
+
if (!token.startsWith(BEACON_SCHEME)) return void 0;
|
|
873
|
+
const target = token.slice(BEACON_SCHEME.length);
|
|
874
|
+
if (path.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
|
|
875
|
+
return is_valid_beacon_name(path.basename(target)) ? target : void 0;
|
|
876
|
+
}
|
|
877
|
+
function is_live_beacon(target) {
|
|
878
|
+
return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
|
|
879
|
+
stdio: "ignore",
|
|
880
|
+
timeout: PROBE_TIMEOUT_MS
|
|
881
|
+
}).status === 0;
|
|
882
|
+
}
|
|
883
|
+
function has_matching_start(pid, recorded_start, read) {
|
|
884
|
+
const observed = read(pid);
|
|
885
|
+
return observed === void 0 ? void 0 : observed === recorded_start;
|
|
886
|
+
}
|
|
887
|
+
function matches_recorded_start(pid, recorded_start, read) {
|
|
888
|
+
const target = beacon_target(recorded_start);
|
|
889
|
+
return target === void 0 ? has_matching_start(pid, recorded_start, read) : is_live_beacon(target);
|
|
890
|
+
}
|
|
891
|
+
var own_probe = /* @__PURE__ */ new Map();
|
|
892
|
+
function own_start() {
|
|
893
|
+
if (!own_probe.has(process.pid)) own_probe.set(process.pid, resolve_own_start());
|
|
894
|
+
return own_probe.get(process.pid);
|
|
895
|
+
}
|
|
896
|
+
function own_fields() {
|
|
897
|
+
const start = own_start();
|
|
898
|
+
return { pid: process.pid, ...start !== void 0 && { process_start: start } };
|
|
899
|
+
}
|
|
900
|
+
function is_same_process(pid, recorded_start, read = read_start) {
|
|
901
|
+
if (pid === void 0 || !is_live_pid(pid)) return false;
|
|
902
|
+
if (recorded_start === void 0) return void 0;
|
|
903
|
+
return matches_recorded_start(pid, recorded_start, read);
|
|
904
|
+
}
|
|
905
|
+
function is_own_process(pid, recorded_start) {
|
|
906
|
+
return pid === process.pid && recorded_start === own_start();
|
|
907
|
+
}
|
|
908
|
+
var process_identity = {
|
|
909
|
+
close_beacon,
|
|
910
|
+
is_live_pid,
|
|
911
|
+
is_own_process,
|
|
912
|
+
is_same_process,
|
|
913
|
+
open_beacon,
|
|
914
|
+
own_fields,
|
|
915
|
+
own_start,
|
|
916
|
+
read_start,
|
|
917
|
+
resolve_own_start
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
// scripts/josh/process-owner.ts
|
|
921
|
+
import { z as z2 } from "zod";
|
|
922
|
+
var process_owner_schema = z2.object({ pid: z2.number(), process_start: z2.string().optional() });
|
|
923
|
+
|
|
924
|
+
// scripts/test/unit-worker-share.ts
|
|
925
|
+
import { readdirSync } from "node:fs";
|
|
926
|
+
import { availableParallelism } from "node:os";
|
|
927
|
+
import path2 from "node:path";
|
|
928
|
+
var RUN_PREFIX = "josh-unit-running-";
|
|
929
|
+
var WORKER_FLAG = "--maxWorkers";
|
|
930
|
+
var WORKER_FLAGS = [WORKER_FLAG, "--max-workers"];
|
|
931
|
+
var MIN_WORKERS = 1;
|
|
932
|
+
var SOLO_RUNS = 1;
|
|
933
|
+
function marker_path(pid = process.pid) {
|
|
934
|
+
return stamp_file.stamp_path(RUN_PREFIX, String(pid));
|
|
935
|
+
}
|
|
936
|
+
function is_running(marker) {
|
|
937
|
+
return process_identity.is_same_process(marker.pid, marker.process_start) !== false;
|
|
938
|
+
}
|
|
939
|
+
function read_marker(source) {
|
|
940
|
+
const raw = stamp_file.read_stamp_text(source);
|
|
941
|
+
if (raw === void 0) return void 0;
|
|
942
|
+
const parsed = process_owner_schema.safeParse(json_value.parse_or_undefined(raw));
|
|
943
|
+
return parsed.success ? parsed.data : void 0;
|
|
944
|
+
}
|
|
945
|
+
function marker_files(directory = PLATFORM_TEMP_ROOT) {
|
|
946
|
+
try {
|
|
947
|
+
return readdirSync(directory).filter((name) => name.startsWith(RUN_PREFIX));
|
|
948
|
+
} catch {
|
|
949
|
+
return [];
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
function sweep_marker(source) {
|
|
953
|
+
try {
|
|
954
|
+
stamp_file.remove_stamp(source);
|
|
955
|
+
} catch {
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
function is_marker_live(source) {
|
|
959
|
+
const marker = read_marker(source);
|
|
960
|
+
if (marker === void 0) return false;
|
|
961
|
+
if (is_running(marker)) return true;
|
|
962
|
+
sweep_marker(source);
|
|
963
|
+
return false;
|
|
964
|
+
}
|
|
965
|
+
function live_run_count(directory = PLATFORM_TEMP_ROOT) {
|
|
966
|
+
return marker_files(directory).filter((name) => is_marker_live(path2.join(directory, name))).length;
|
|
967
|
+
}
|
|
968
|
+
var NESTED_KEY = "JOSH_UNIT_RUN_MARKED";
|
|
969
|
+
var NESTED_VALUE = "1";
|
|
970
|
+
function is_nested_run() {
|
|
971
|
+
return process.env[NESTED_KEY] === NESTED_VALUE;
|
|
972
|
+
}
|
|
973
|
+
function resolve_unit_workers(available_cores, runs2) {
|
|
974
|
+
if (runs2 <= SOLO_RUNS) return void 0;
|
|
975
|
+
return Math.max(MIN_WORKERS, Math.floor(available_cores / runs2));
|
|
976
|
+
}
|
|
977
|
+
function current_share(available_cores = availableParallelism(), live_runs = live_run_count()) {
|
|
978
|
+
const own_run2 = is_nested_run() ? 0 : SOLO_RUNS;
|
|
979
|
+
return resolve_unit_workers(available_cores, live_runs + own_run2);
|
|
980
|
+
}
|
|
981
|
+
function is_worker_flag(argument) {
|
|
982
|
+
return WORKER_FLAGS.some((flag) => argument === flag || argument.startsWith(`${flag}=`));
|
|
983
|
+
}
|
|
984
|
+
function worker_arguments(vitest_arguments, share) {
|
|
985
|
+
if (share === void 0) return [];
|
|
986
|
+
if (vitest_arguments.some((argument) => is_worker_flag(argument))) return [];
|
|
987
|
+
return [`${WORKER_FLAG}=${String(share)}`];
|
|
988
|
+
}
|
|
989
|
+
function mark_run_started(target) {
|
|
990
|
+
try {
|
|
991
|
+
stamp_file.write_stamp(target, process_identity.own_fields());
|
|
992
|
+
} catch {
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
async function with_run_marker(run) {
|
|
996
|
+
if (is_nested_run()) return await run();
|
|
997
|
+
const target = marker_path();
|
|
998
|
+
mark_run_started(target);
|
|
999
|
+
process.env[NESTED_KEY] = NESTED_VALUE;
|
|
1000
|
+
try {
|
|
1001
|
+
return await run();
|
|
1002
|
+
} finally {
|
|
1003
|
+
process.env[NESTED_KEY] = "";
|
|
1004
|
+
stamp_file.remove_stamp(target);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
var unit_worker_share = {
|
|
1008
|
+
MIN_WORKERS,
|
|
1009
|
+
NESTED_KEY,
|
|
1010
|
+
NESTED_VALUE,
|
|
1011
|
+
RUN_PREFIX,
|
|
1012
|
+
SOLO_RUNS,
|
|
1013
|
+
current_share,
|
|
1014
|
+
is_nested_run,
|
|
1015
|
+
live_run_count,
|
|
1016
|
+
marker_path,
|
|
1017
|
+
read_marker,
|
|
1018
|
+
resolve_unit_workers,
|
|
1019
|
+
with_run_marker,
|
|
1020
|
+
worker_arguments
|
|
1021
|
+
};
|
|
1022
|
+
|
|
1023
|
+
// scripts/gate/core-budget.ts
|
|
1024
|
+
import { z as z3 } from "zod";
|
|
1025
|
+
|
|
1026
|
+
// scripts/gate/core-admission.ts
|
|
1027
|
+
var MS_PER_SECOND = 1e3;
|
|
1028
|
+
var RAMP_UP_MS = 3e4;
|
|
1029
|
+
function compare_claim(left, right) {
|
|
1030
|
+
const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
|
|
1031
|
+
return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
|
|
1032
|
+
}
|
|
1033
|
+
function add_load(totals, reservation) {
|
|
1034
|
+
totals.cores += reservation.weight;
|
|
1035
|
+
totals.memory_mb += reservation.memory_mb ?? 0;
|
|
1036
|
+
}
|
|
1037
|
+
function exceeds(totals, budget) {
|
|
1038
|
+
return totals.cores > budget.cores || totals.memory_mb > budget.memory_mb;
|
|
1039
|
+
}
|
|
1040
|
+
function admitted_keys(reservations, budget, memory_budget = Infinity) {
|
|
1041
|
+
const limit = { cores: budget, memory_mb: memory_budget };
|
|
1042
|
+
const totals = { cores: 0, memory_mb: 0 };
|
|
1043
|
+
const admitted = /* @__PURE__ */ new Set();
|
|
1044
|
+
for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
|
|
1045
|
+
add_load(totals, entry.reservation);
|
|
1046
|
+
if (index !== 0 && exceeds(totals, limit)) break;
|
|
1047
|
+
admitted.add(entry.key);
|
|
1048
|
+
}
|
|
1049
|
+
return admitted;
|
|
1050
|
+
}
|
|
1051
|
+
function is_admitted(key, reservations, budget) {
|
|
1052
|
+
return admitted_keys(reservations, budget.cores, budget.memory_mb).has(key);
|
|
1053
|
+
}
|
|
1054
|
+
function sum_load(reservations) {
|
|
1055
|
+
const load = { cores: 0, memory_mb: 0 };
|
|
1056
|
+
for (const entry of reservations) add_load(load, entry.reservation);
|
|
1057
|
+
return load;
|
|
1058
|
+
}
|
|
1059
|
+
function is_ramped(reservation, now) {
|
|
1060
|
+
const { admitted_at } = reservation;
|
|
1061
|
+
return admitted_at !== void 0 && now - admitted_at >= RAMP_UP_MS;
|
|
1062
|
+
}
|
|
1063
|
+
function ledger_load(reservations, now) {
|
|
1064
|
+
const admitted = reservations.filter((entry) => entry.reservation.admitted_at !== void 0);
|
|
1065
|
+
const ramped = admitted.filter((entry) => is_ramped(entry.reservation, now));
|
|
1066
|
+
return { cores: sum_load(admitted).cores, memory_mb: sum_load(ramped).memory_mb };
|
|
1067
|
+
}
|
|
1068
|
+
function total_weight(reservations) {
|
|
1069
|
+
return sum_load(reservations).cores;
|
|
1070
|
+
}
|
|
1071
|
+
function admitted_load(reservations, budget) {
|
|
1072
|
+
const admitted = admitted_keys(reservations, budget);
|
|
1073
|
+
return total_weight(reservations.filter((entry) => admitted.has(entry.key)));
|
|
1074
|
+
}
|
|
1075
|
+
function describe_memory(ledger, budget) {
|
|
1076
|
+
if (!Number.isFinite(budget.memory_mb)) return "";
|
|
1077
|
+
return ` and ${String(Math.round(ledger.memory_mb))} MB of memory against ${String(Math.round(budget.memory_mb))} MB`;
|
|
1078
|
+
}
|
|
1079
|
+
function describe_overflow(admission) {
|
|
1080
|
+
const { overflow } = admission;
|
|
1081
|
+
if (overflow === void 0) return void 0;
|
|
1082
|
+
const { ledger, budget } = overflow;
|
|
1083
|
+
const waited = String(Math.round(overflow.waited_ms / MS_PER_SECOND));
|
|
1084
|
+
const cores = `the ledger held ${String(ledger.cores)} cores against a budget of ${String(budget.cores)}`;
|
|
1085
|
+
return `started past the core budget after ${waited}s \u2014 ${cores}${describe_memory(ledger, budget)}`;
|
|
1086
|
+
}
|
|
1087
|
+
var core_admission = {
|
|
1088
|
+
RAMP_UP_MS,
|
|
1089
|
+
admitted_keys,
|
|
1090
|
+
admitted_load,
|
|
1091
|
+
describe_overflow,
|
|
1092
|
+
is_admitted,
|
|
1093
|
+
ledger_load,
|
|
1094
|
+
sum_load
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
// scripts/gate/machine-capacity.ts
|
|
1098
|
+
import { readFile } from "node:fs/promises";
|
|
1099
|
+
import { availableParallelism as availableParallelism2, cpus, totalmem } from "node:os";
|
|
1100
|
+
import { execa } from "execa";
|
|
1101
|
+
var SAMPLE_WINDOW_MS = 250;
|
|
1102
|
+
var BASELINE_CORES = 2;
|
|
1103
|
+
var BYTES_PER_MB = 1048576;
|
|
1104
|
+
var KB_PER_MB = 1024;
|
|
1105
|
+
var PERCENT = 100;
|
|
1106
|
+
var MEMINFO_PATH = "/proc/meminfo";
|
|
1107
|
+
var LINUX_AVAILABLE = /^MemAvailable:\s+(?<kb>\d+) kB/mu;
|
|
1108
|
+
var PRESSURE_ARGUMENTS = ["-n", "kern.memorystatus_level"];
|
|
1109
|
+
var PRESSURE_LEVEL = /^\s*(?<level>\d+)\s*$/u;
|
|
1110
|
+
function cpu_times() {
|
|
1111
|
+
let busy = 0;
|
|
1112
|
+
let idle = 0;
|
|
1113
|
+
for (const { times } of cpus()) {
|
|
1114
|
+
busy += times.user + times.nice + times.sys + times.irq;
|
|
1115
|
+
idle += times.idle;
|
|
1116
|
+
}
|
|
1117
|
+
return { busy, total: busy + idle };
|
|
1118
|
+
}
|
|
1119
|
+
function busy_cores_between(before, after, cores) {
|
|
1120
|
+
const total = after.total - before.total;
|
|
1121
|
+
if (total <= 0) return void 0;
|
|
1122
|
+
return (after.busy - before.busy) / total * cores;
|
|
1123
|
+
}
|
|
1124
|
+
function parse_darwin_pressure(output, total_bytes) {
|
|
1125
|
+
const level = PRESSURE_LEVEL.exec(output)?.groups?.["level"];
|
|
1126
|
+
if (level === void 0) return void 0;
|
|
1127
|
+
return Number(level) / PERCENT * (total_bytes / BYTES_PER_MB);
|
|
1128
|
+
}
|
|
1129
|
+
function parse_linux_available(meminfo) {
|
|
1130
|
+
const kb = LINUX_AVAILABLE.exec(meminfo)?.groups?.["kb"];
|
|
1131
|
+
return kb === void 0 ? void 0 : Number(kb) / KB_PER_MB;
|
|
1132
|
+
}
|
|
1133
|
+
async function read_available_mb(platform = process.platform) {
|
|
1134
|
+
try {
|
|
1135
|
+
if (platform === "darwin") {
|
|
1136
|
+
const { stdout } = await execa("sysctl", PRESSURE_ARGUMENTS);
|
|
1137
|
+
return parse_darwin_pressure(stdout, totalmem());
|
|
1138
|
+
}
|
|
1139
|
+
return platform === "linux" ? parse_linux_available(await readFile(MEMINFO_PATH, "utf8")) : void 0;
|
|
1140
|
+
} catch {
|
|
1141
|
+
return void 0;
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
function is_unquoted() {
|
|
1145
|
+
return cpus().length > 0 && cpus().length === availableParallelism2();
|
|
1146
|
+
}
|
|
1147
|
+
async function default_sleep(ms) {
|
|
1148
|
+
await new Promise((resolve) => {
|
|
1149
|
+
setTimeout(resolve, ms);
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
async function read_machine(sleep = default_sleep) {
|
|
1153
|
+
const before = cpu_times();
|
|
1154
|
+
const [available_mb] = await Promise.all([read_available_mb(), sleep(SAMPLE_WINDOW_MS)]);
|
|
1155
|
+
const busy_cores = is_unquoted() ? busy_cores_between(before, cpu_times(), cpus().length) : void 0;
|
|
1156
|
+
return { busy_cores, available_mb };
|
|
1157
|
+
}
|
|
1158
|
+
function external_cores(busy_cores, ledger_cores) {
|
|
1159
|
+
if (busy_cores === void 0) return 0;
|
|
1160
|
+
return Math.floor(Math.max(0, busy_cores - ledger_cores - BASELINE_CORES));
|
|
1161
|
+
}
|
|
1162
|
+
function machine_budget(cores, reading, ledger) {
|
|
1163
|
+
return {
|
|
1164
|
+
cores: cores - external_cores(reading.busy_cores, ledger.cores),
|
|
1165
|
+
memory_mb: reading.available_mb === void 0 ? Infinity : reading.available_mb + ledger.memory_mb
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
var machine_capacity = {
|
|
1169
|
+
BASELINE_CORES,
|
|
1170
|
+
busy_cores_between,
|
|
1171
|
+
machine_budget,
|
|
1172
|
+
parse_darwin_pressure,
|
|
1173
|
+
parse_linux_available,
|
|
1174
|
+
read_machine
|
|
1175
|
+
};
|
|
1176
|
+
|
|
1177
|
+
// scripts/gate/core-budget.ts
|
|
1178
|
+
var RESERVED_PREFIX = "josh-core-reserved-";
|
|
1179
|
+
var RESERVED_SUFFIX = ".json";
|
|
1180
|
+
var POLL_INTERVAL_MS = 50;
|
|
1181
|
+
var WAIT_CAP_MS = 12e4;
|
|
1182
|
+
var MIN_BUDGET = 1;
|
|
1183
|
+
var CORE_WEIGHTS = {
|
|
1184
|
+
lint: 2,
|
|
1185
|
+
type_check: 1,
|
|
1186
|
+
spell_check: 1,
|
|
1187
|
+
eslint_scan: 1
|
|
1188
|
+
};
|
|
1189
|
+
var MEMORY_MB = {
|
|
1190
|
+
lint: 2400,
|
|
1191
|
+
type_check: 1300,
|
|
1192
|
+
spell_check: 350,
|
|
1193
|
+
eslint_scan: 2400,
|
|
1194
|
+
unit_worker: 350
|
|
1195
|
+
};
|
|
1196
|
+
var HELD_KEY = "JOSH_CORE_RESERVED";
|
|
1197
|
+
var HELD_VALUE = "1";
|
|
1198
|
+
var reservation_schema = process_owner_schema.extend({
|
|
1199
|
+
weight: z3.number(),
|
|
1200
|
+
claimed_at: z3.number(),
|
|
1201
|
+
memory_mb: z3.number().optional(),
|
|
1202
|
+
admitted_at: z3.number().optional()
|
|
1203
|
+
});
|
|
1204
|
+
function marker_name(key) {
|
|
1205
|
+
return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`;
|
|
1206
|
+
}
|
|
1207
|
+
function is_running2(reservation) {
|
|
1208
|
+
return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false;
|
|
1209
|
+
}
|
|
1210
|
+
function read_reservation(source) {
|
|
1211
|
+
const raw = stamp_file.read_stamp_text(source);
|
|
1212
|
+
if (raw === void 0) return void 0;
|
|
1213
|
+
try {
|
|
1214
|
+
const parsed = reservation_schema.safeParse(JSON.parse(raw));
|
|
1215
|
+
return parsed.success ? parsed.data : void 0;
|
|
1216
|
+
} catch {
|
|
1217
|
+
return void 0;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
function sweep_marker2(source) {
|
|
1221
|
+
try {
|
|
1222
|
+
stamp_file.remove_stamp(source);
|
|
1223
|
+
} catch {
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
function live_reservation(source) {
|
|
1227
|
+
const reservation = read_reservation(source);
|
|
1228
|
+
if (reservation === void 0) return void 0;
|
|
1229
|
+
if (is_running2(reservation)) return reservation;
|
|
1230
|
+
sweep_marker2(source);
|
|
1231
|
+
return void 0;
|
|
1232
|
+
}
|
|
1233
|
+
function marker_files2(directory) {
|
|
1234
|
+
try {
|
|
1235
|
+
return readdirSync2(directory).filter(
|
|
1236
|
+
(name) => name.startsWith(RESERVED_PREFIX) && name.endsWith(RESERVED_SUFFIX)
|
|
1237
|
+
);
|
|
1238
|
+
} catch {
|
|
1239
|
+
return [];
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
function live_reservations(directory = PLATFORM_TEMP_ROOT) {
|
|
1243
|
+
return marker_files2(directory).flatMap((name) => {
|
|
1244
|
+
const reservation = live_reservation(path3.join(directory, name));
|
|
1245
|
+
return reservation === void 0 ? [] : { key: name, reservation };
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
function normalize_budget(budget) {
|
|
1249
|
+
return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET;
|
|
1250
|
+
}
|
|
1251
|
+
async function default_sleep2(ms) {
|
|
1252
|
+
await new Promise((resolve) => {
|
|
1253
|
+
setTimeout(resolve, ms);
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
function write_reservation(target, fields) {
|
|
1257
|
+
stamp_file.replace_stamp(target, { ...process_identity.own_fields(), ...fields });
|
|
1258
|
+
}
|
|
1259
|
+
function resolve_timing(options) {
|
|
1260
|
+
return {
|
|
1261
|
+
now: options.now ?? Date.now,
|
|
1262
|
+
sleep: options.sleep ?? default_sleep2,
|
|
1263
|
+
poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
|
|
1264
|
+
wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
async function current_budget(context, reservations) {
|
|
1268
|
+
if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity };
|
|
1269
|
+
const reading = await context.read_machine();
|
|
1270
|
+
const ledger = core_admission.ledger_load(reservations, context.now());
|
|
1271
|
+
const budget = machine_capacity.machine_budget(context.budget, reading, ledger);
|
|
1272
|
+
return { ...budget, cores: normalize_budget(budget.cores) };
|
|
1273
|
+
}
|
|
1274
|
+
function admit(context, overflow) {
|
|
1275
|
+
write_reservation(context.target, { ...context.fields, admitted_at: context.now() });
|
|
1276
|
+
return { overflow };
|
|
1277
|
+
}
|
|
1278
|
+
function overflow_of(context, reservations, budget) {
|
|
1279
|
+
return {
|
|
1280
|
+
waited_ms: context.now() - context.fields.claimed_at,
|
|
1281
|
+
ledger: core_admission.sum_load(reservations),
|
|
1282
|
+
budget
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
async function poll_admission(context) {
|
|
1286
|
+
const reservations = live_reservations(context.directory);
|
|
1287
|
+
const budget = await current_budget(context, reservations);
|
|
1288
|
+
if (core_admission.is_admitted(context.key, reservations, budget)) return admit(context);
|
|
1289
|
+
if (context.now() >= context.deadline) {
|
|
1290
|
+
return admit(context, overflow_of(context, reservations, budget));
|
|
1291
|
+
}
|
|
1292
|
+
return void 0;
|
|
1293
|
+
}
|
|
1294
|
+
async function await_admission(context) {
|
|
1295
|
+
let admission = await poll_admission(context);
|
|
1296
|
+
while (admission === void 0) {
|
|
1297
|
+
await context.sleep(context.poll_interval_ms);
|
|
1298
|
+
admission = await poll_admission(context);
|
|
1299
|
+
}
|
|
1300
|
+
return admission;
|
|
1301
|
+
}
|
|
1302
|
+
async function reserve(weight, options = {}) {
|
|
1303
|
+
const timing = resolve_timing(options);
|
|
1304
|
+
const directory = options.directory ?? PLATFORM_TEMP_ROOT;
|
|
1305
|
+
const claimed_at = timing.now();
|
|
1306
|
+
const name = marker_name(randomUUID2());
|
|
1307
|
+
const target = path3.join(directory, name);
|
|
1308
|
+
const fields = { weight, claimed_at, memory_mb: options.memory_mb };
|
|
1309
|
+
write_reservation(target, fields);
|
|
1310
|
+
const admission = await await_admission({
|
|
1311
|
+
...timing,
|
|
1312
|
+
key: name,
|
|
1313
|
+
target,
|
|
1314
|
+
directory,
|
|
1315
|
+
budget: normalize_budget(options.budget ?? availableParallelism3()),
|
|
1316
|
+
deadline: claimed_at + timing.wait_cap_ms,
|
|
1317
|
+
fields,
|
|
1318
|
+
read_machine: options.read_machine ?? machine_capacity.read_machine
|
|
1319
|
+
});
|
|
1320
|
+
return { target, admission };
|
|
1321
|
+
}
|
|
1322
|
+
function release(handle) {
|
|
1323
|
+
sweep_marker2(handle.target);
|
|
1324
|
+
}
|
|
1325
|
+
async function with_core_reservation(weight, run, options = {}) {
|
|
1326
|
+
const handle = await reserve(weight, options);
|
|
1327
|
+
try {
|
|
1328
|
+
return await run(handle.admission);
|
|
1329
|
+
} finally {
|
|
1330
|
+
release(handle);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
function is_held() {
|
|
1334
|
+
return process.env[HELD_KEY] === HELD_VALUE;
|
|
1335
|
+
}
|
|
1336
|
+
function set_held_mark(value) {
|
|
1337
|
+
process.env[HELD_KEY] = value;
|
|
1338
|
+
}
|
|
1339
|
+
async function with_held_mark(run) {
|
|
1340
|
+
const previous = process.env[HELD_KEY] ?? "";
|
|
1341
|
+
set_held_mark(HELD_VALUE);
|
|
1342
|
+
try {
|
|
1343
|
+
return await run();
|
|
1344
|
+
} finally {
|
|
1345
|
+
set_held_mark(previous);
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
async function with_command_reservation(weight, run, options = {}) {
|
|
1349
|
+
if (is_held() || unit_worker_share.is_nested_run()) return await run();
|
|
1350
|
+
return await with_core_reservation(weight, async () => await with_held_mark(run), options);
|
|
1351
|
+
}
|
|
1352
|
+
var core_budget = {
|
|
1353
|
+
CORE_WEIGHTS,
|
|
1354
|
+
HELD_KEY,
|
|
1355
|
+
HELD_VALUE,
|
|
1356
|
+
MEMORY_MB,
|
|
1357
|
+
RESERVED_PREFIX,
|
|
1358
|
+
admitted_keys: core_admission.admitted_keys,
|
|
1359
|
+
admitted_load: core_admission.admitted_load,
|
|
1360
|
+
describe_overflow: core_admission.describe_overflow,
|
|
1361
|
+
is_held,
|
|
1362
|
+
live_reservations,
|
|
1363
|
+
release,
|
|
1364
|
+
reserve,
|
|
1365
|
+
with_command_reservation,
|
|
1366
|
+
with_core_reservation,
|
|
1367
|
+
with_held_mark
|
|
1368
|
+
};
|
|
1369
|
+
|
|
1370
|
+
// scripts/gate/gate-plan.ts
|
|
1371
|
+
import { availableParallelism as availableParallelism4 } from "node:os";
|
|
1372
|
+
|
|
1373
|
+
// scripts/lib/status-icons.ts
|
|
1374
|
+
var FAIL_ICON = "\u2717";
|
|
1375
|
+
var PASS_ICON = "\u2714";
|
|
1376
|
+
var status_icons = { FAIL_ICON, PASS_ICON };
|
|
1377
|
+
|
|
1378
|
+
// scripts/josh/josh-verdict.ts
|
|
1379
|
+
var { FAIL_ICON: FAIL_ICON2, PASS_ICON: PASS_ICON2 } = status_icons;
|
|
1380
|
+
var GATE_SUBJECT = "verification gate";
|
|
1381
|
+
var GATE_PASSED_PREFIX = `${PASS_ICON2} ${GATE_SUBJECT} passed`;
|
|
1382
|
+
var GATE_FAILED_PREFIX = `${FAIL_ICON2} ${GATE_SUBJECT} failed`;
|
|
1383
|
+
var PASSED_VERDICT = "passed";
|
|
1384
|
+
var FAILED_VERDICT = "failed";
|
|
1385
|
+
function format_gate_passed(step_count, total) {
|
|
1386
|
+
return `${GATE_PASSED_PREFIX} (${step_count} checks) in ${total}.`;
|
|
1387
|
+
}
|
|
1388
|
+
function format_gate_failed(failed_labels, total) {
|
|
1389
|
+
return `${GATE_FAILED_PREFIX}: ${failed_labels} (${total})`;
|
|
1390
|
+
}
|
|
1391
|
+
var GATE_OPENING_PREFIX = "plan: ";
|
|
1392
|
+
var GATE_OPENING_MARK = " checks at once";
|
|
1393
|
+
function is_gate_opening(line) {
|
|
1394
|
+
const trimmed = line.trimStart();
|
|
1395
|
+
return trimmed.startsWith(GATE_OPENING_PREFIX) && trimmed.includes(GATE_OPENING_MARK);
|
|
1396
|
+
}
|
|
1397
|
+
function read_verdict(line) {
|
|
1398
|
+
const trimmed = line.trimStart();
|
|
1399
|
+
if (trimmed.startsWith(GATE_FAILED_PREFIX)) return FAILED_VERDICT;
|
|
1400
|
+
if (trimmed.startsWith(GATE_PASSED_PREFIX)) return PASSED_VERDICT;
|
|
1401
|
+
return void 0;
|
|
1402
|
+
}
|
|
1403
|
+
var josh_verdict = {
|
|
1404
|
+
PASSED_VERDICT,
|
|
1405
|
+
FAILED_VERDICT,
|
|
1406
|
+
format_gate_passed,
|
|
1407
|
+
format_gate_failed,
|
|
1408
|
+
GATE_OPENING_MARK,
|
|
1409
|
+
GATE_OPENING_PREFIX,
|
|
1410
|
+
is_gate_opening,
|
|
1411
|
+
read_verdict
|
|
1412
|
+
};
|
|
1413
|
+
|
|
1414
|
+
// scripts/gate/gate-plan.ts
|
|
1415
|
+
var LINT_LABEL = "lint";
|
|
1416
|
+
var TYPE_CHECK_LABEL = "check";
|
|
1417
|
+
var UNIT_LABEL = "test:unit";
|
|
1418
|
+
var BEHAVIOR_LABEL = "behavior";
|
|
1419
|
+
var WARNING_CHECKER_LABELS = [LINT_LABEL, TYPE_CHECK_LABEL];
|
|
1420
|
+
var STATIC_CHECKS = [
|
|
1421
|
+
{
|
|
1422
|
+
label: LINT_LABEL,
|
|
1423
|
+
target: "lint",
|
|
1424
|
+
reserved_cores: core_budget.CORE_WEIGHTS.lint,
|
|
1425
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
1426
|
+
},
|
|
1427
|
+
{
|
|
1428
|
+
label: TYPE_CHECK_LABEL,
|
|
1429
|
+
target: "check",
|
|
1430
|
+
reserved_cores: core_budget.CORE_WEIGHTS.type_check,
|
|
1431
|
+
memory_mb: core_budget.MEMORY_MB.type_check
|
|
1432
|
+
},
|
|
1433
|
+
{
|
|
1434
|
+
label: "cspell",
|
|
1435
|
+
target: "cspell:dot",
|
|
1436
|
+
reserved_cores: core_budget.CORE_WEIGHTS.spell_check,
|
|
1437
|
+
memory_mb: core_budget.MEMORY_MB.spell_check
|
|
1438
|
+
},
|
|
1439
|
+
{ label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
|
|
1440
|
+
// **The unused-member check reserves no core** (joshuafolkken/kit#2987): it builds one TypeScript
|
|
1441
|
+
// program and walks it for about 5s, and it is over well before lint and the type check. A
|
|
1442
|
+
// reservation would only take a place from the four-core CI runner's fan-out and a worker from the
|
|
1443
|
+
// unit suite for the whole gate.
|
|
1444
|
+
{ label: "exports", target: "exports:unused", reserved_cores: 0 }
|
|
1445
|
+
];
|
|
1446
|
+
var GATE_CHECKS = [
|
|
1447
|
+
...STATIC_CHECKS,
|
|
1448
|
+
{ label: UNIT_LABEL, target: UNIT_LABEL, reserved_cores: 0 }
|
|
1449
|
+
];
|
|
1450
|
+
function select_gate_checks(is_unit_included) {
|
|
1451
|
+
return is_unit_included ? GATE_CHECKS : STATIC_CHECKS;
|
|
1452
|
+
}
|
|
1453
|
+
function has_unit_check(checks) {
|
|
1454
|
+
return checks.some((check) => check.label === UNIT_LABEL);
|
|
1455
|
+
}
|
|
1456
|
+
var RESERVED_CORES = STATIC_CHECKS.reduce(
|
|
1457
|
+
(total, check) => total + check.reserved_cores,
|
|
1458
|
+
0
|
|
1459
|
+
);
|
|
1460
|
+
var MEASURED_CORES = 11;
|
|
1461
|
+
var MIN_CONCURRENCY = 1;
|
|
1462
|
+
var MIN_SHARED_CORES = 1;
|
|
1463
|
+
function shared_cores(available_cores, concurrent_runs) {
|
|
1464
|
+
const runs2 = Number.isFinite(concurrent_runs) ? Math.max(unit_worker_share.SOLO_RUNS, concurrent_runs) : unit_worker_share.SOLO_RUNS;
|
|
1465
|
+
return Math.max(MIN_SHARED_CORES, Math.floor(available_cores / runs2));
|
|
1466
|
+
}
|
|
1467
|
+
function resolve_concurrency(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS, checks = GATE_CHECKS) {
|
|
1468
|
+
const share = shared_cores(available_cores, concurrent_runs);
|
|
1469
|
+
let admitted = 0;
|
|
1470
|
+
let reserved = 0;
|
|
1471
|
+
for (const check of checks) {
|
|
1472
|
+
reserved += check.reserved_cores;
|
|
1473
|
+
if (reserved > share) break;
|
|
1474
|
+
admitted += 1;
|
|
1475
|
+
}
|
|
1476
|
+
return Math.max(MIN_CONCURRENCY, admitted);
|
|
1477
|
+
}
|
|
1478
|
+
function resolve_unit_worker_cap(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS) {
|
|
1479
|
+
const share = unit_worker_share.resolve_unit_workers(available_cores, concurrent_runs);
|
|
1480
|
+
if (share !== void 0) return share;
|
|
1481
|
+
if (available_cores < MEASURED_CORES) return void 0;
|
|
1482
|
+
return available_cores - RESERVED_CORES;
|
|
1483
|
+
}
|
|
1484
|
+
function solo_unit_weight(available_cores) {
|
|
1485
|
+
return Math.max(0, available_cores - RESERVED_CORES);
|
|
1486
|
+
}
|
|
1487
|
+
function check_weight(check, plan, available_cores) {
|
|
1488
|
+
if (check.label !== UNIT_LABEL) return check.reserved_cores;
|
|
1489
|
+
return plan.unit_worker_cap ?? solo_unit_weight(available_cores);
|
|
1490
|
+
}
|
|
1491
|
+
function unit_memory(workers) {
|
|
1492
|
+
return workers * core_budget.MEMORY_MB.unit_worker;
|
|
1493
|
+
}
|
|
1494
|
+
function check_memory(check, plan, available_cores) {
|
|
1495
|
+
if (check.label !== UNIT_LABEL) return check.memory_mb ?? 0;
|
|
1496
|
+
return unit_memory(check_weight(check, plan, available_cores));
|
|
1497
|
+
}
|
|
1498
|
+
function direct_unit_weight(available_cores = availableParallelism4(), live_runs = unit_worker_share.live_run_count()) {
|
|
1499
|
+
const weight = unit_worker_share.current_share(available_cores, live_runs) ?? solo_unit_weight(available_cores);
|
|
1500
|
+
return Math.max(unit_worker_share.MIN_WORKERS, weight);
|
|
1501
|
+
}
|
|
1502
|
+
function direct_unit_memory() {
|
|
1503
|
+
return unit_memory(direct_unit_weight());
|
|
1504
|
+
}
|
|
1505
|
+
function plan_of(concurrency, unit_worker_cap, checks = GATE_CHECKS) {
|
|
1506
|
+
return { checks, concurrency, unit_worker_cap };
|
|
1507
|
+
}
|
|
1508
|
+
function resolve_gate_plan(available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS, is_unit_included = true) {
|
|
1509
|
+
const checks = select_gate_checks(is_unit_included);
|
|
1510
|
+
return {
|
|
1511
|
+
checks,
|
|
1512
|
+
concurrency: resolve_concurrency(available_cores, concurrent_runs, checks),
|
|
1513
|
+
unit_worker_cap: is_unit_included ? resolve_unit_worker_cap(available_cores, concurrent_runs) : void 0
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
function format_machine(available_cores, concurrent_runs) {
|
|
1517
|
+
const cores = `${String(available_cores)} cores`;
|
|
1518
|
+
if (concurrent_runs <= unit_worker_share.SOLO_RUNS) return cores;
|
|
1519
|
+
return `${cores}, ${String(concurrent_runs)} unit runs`;
|
|
1520
|
+
}
|
|
1521
|
+
function format_unit_cap(plan) {
|
|
1522
|
+
if (!has_unit_check(plan.checks)) return `${UNIT_LABEL} elsewhere`;
|
|
1523
|
+
if (plan.unit_worker_cap === void 0) return `${UNIT_LABEL} unrestricted`;
|
|
1524
|
+
return `${UNIT_LABEL} at ${String(plan.unit_worker_cap)} workers`;
|
|
1525
|
+
}
|
|
1526
|
+
function format_gate_plan(plan, available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS) {
|
|
1527
|
+
const cap = format_unit_cap(plan);
|
|
1528
|
+
const count = `${String(plan.concurrency)} of ${String(plan.checks.length)}`;
|
|
1529
|
+
const width = `${count}${josh_verdict.GATE_OPENING_MARK}`;
|
|
1530
|
+
const machine = format_machine(available_cores, concurrent_runs);
|
|
1531
|
+
return `${josh_verdict.GATE_OPENING_PREFIX}${width}, ${cap} (${machine})`;
|
|
1532
|
+
}
|
|
1533
|
+
var gate_plan = {
|
|
1534
|
+
GATE_CHECKS,
|
|
1535
|
+
LINT_LABEL,
|
|
1536
|
+
MEASURED_CORES,
|
|
1537
|
+
RESERVED_CORES,
|
|
1538
|
+
STATIC_CHECKS,
|
|
1539
|
+
TYPE_CHECK_LABEL,
|
|
1540
|
+
UNIT_LABEL,
|
|
1541
|
+
WARNING_CHECKER_LABELS,
|
|
1542
|
+
check_memory,
|
|
1543
|
+
check_weight,
|
|
1544
|
+
direct_unit_memory,
|
|
1545
|
+
direct_unit_weight,
|
|
1546
|
+
format_gate_plan,
|
|
1547
|
+
format_machine,
|
|
1548
|
+
has_unit_check,
|
|
1549
|
+
plan_of,
|
|
1550
|
+
resolve_concurrency,
|
|
1551
|
+
resolve_gate_plan,
|
|
1552
|
+
resolve_unit_worker_cap,
|
|
1553
|
+
select_gate_checks
|
|
1554
|
+
};
|
|
1555
|
+
|
|
707
1556
|
// scripts/josh/josh-commands-development.ts
|
|
708
1557
|
var FILE_ARGUMENTS = "[files...]";
|
|
709
1558
|
var REQUIRED_FILE_ARGUMENTS = "<files...>";
|
|
@@ -727,25 +1576,33 @@ var DEV_COMMANDS = {
|
|
|
727
1576
|
script: "scripts/lint/lint-parallel.ts",
|
|
728
1577
|
description: "Check code with prettier and eslint (skips a tool a basic project lacks)",
|
|
729
1578
|
category: "Development",
|
|
730
|
-
reference: ["", "developer", ["processes"]]
|
|
1579
|
+
reference: ["", "developer", ["processes"]],
|
|
1580
|
+
core_weight: core_budget.CORE_WEIGHTS.lint,
|
|
1581
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
731
1582
|
},
|
|
732
1583
|
"lint:related": {
|
|
733
1584
|
script: "scripts/lint/lint-related.ts",
|
|
734
1585
|
description: "Check only the changed files with prettier and eslint (whole tree on fallback)",
|
|
735
1586
|
category: "Development",
|
|
736
|
-
reference: [FILE_ARGUMENTS, "developer", ["processes"]]
|
|
1587
|
+
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
1588
|
+
core_weight: core_budget.CORE_WEIGHTS.lint,
|
|
1589
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
737
1590
|
},
|
|
738
1591
|
lines: {
|
|
739
1592
|
script: "scripts/lines/lines-command.ts",
|
|
740
1593
|
description: "Print a file's code lines against the max-lines limit and the headroom left",
|
|
741
1594
|
category: "Development",
|
|
742
|
-
reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]]
|
|
1595
|
+
reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]],
|
|
1596
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1597
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan
|
|
743
1598
|
},
|
|
744
1599
|
"refactor:scan": {
|
|
745
1600
|
script: "scripts/refactor/refactor-scan-cli.ts",
|
|
746
1601
|
description: "List refactoring candidates in the changed scope by category and answer clear/candidates",
|
|
747
1602
|
category: "Development",
|
|
748
|
-
reference: ["", "automation", ["processes"]]
|
|
1603
|
+
reference: ["", "automation", ["processes"]],
|
|
1604
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1605
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan
|
|
749
1606
|
},
|
|
750
1607
|
bytes: {
|
|
751
1608
|
script: "scripts/lines/bytes-command.ts",
|
|
@@ -824,7 +1681,9 @@ var DEV_COMMANDS = {
|
|
|
824
1681
|
script: "scripts/lint/cspell-cached.ts",
|
|
825
1682
|
description: "Run spell check including dotfiles",
|
|
826
1683
|
category: "Development",
|
|
827
|
-
reference: ["", "developer", ["processes"]]
|
|
1684
|
+
reference: ["", "developer", ["processes"]],
|
|
1685
|
+
core_weight: core_budget.CORE_WEIGHTS.spell_check,
|
|
1686
|
+
memory_mb: core_budget.MEMORY_MB.spell_check
|
|
828
1687
|
},
|
|
829
1688
|
behavior: {
|
|
830
1689
|
script: "scripts/behavior/behavior-cli.ts",
|
|
@@ -842,13 +1701,17 @@ var DEV_COMMANDS = {
|
|
|
842
1701
|
script: "scripts/test/test-unit-guard.ts",
|
|
843
1702
|
description: "Run unit tests with Vitest (skips when Vitest is absent; fails when it has no tests)",
|
|
844
1703
|
category: "Development",
|
|
845
|
-
reference: [FILTER_ARGUMENTS, "developer", ["processes"]]
|
|
1704
|
+
reference: [FILTER_ARGUMENTS, "developer", ["processes"]],
|
|
1705
|
+
core_weight: gate_plan.direct_unit_weight,
|
|
1706
|
+
memory_mb: gate_plan.direct_unit_memory
|
|
846
1707
|
},
|
|
847
1708
|
"test:related": {
|
|
848
1709
|
script: "scripts/test/test-related.ts",
|
|
849
1710
|
description: "Run only the unit tests related to the changed files (full suite on fallback)",
|
|
850
1711
|
category: "Development",
|
|
851
|
-
reference: [FILE_ARGUMENTS, "developer", ["processes"]]
|
|
1712
|
+
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
1713
|
+
core_weight: gate_plan.direct_unit_weight,
|
|
1714
|
+
memory_mb: gate_plan.direct_unit_memory
|
|
852
1715
|
},
|
|
853
1716
|
"test:declared": {
|
|
854
1717
|
script: "scripts/test/test-declared.ts",
|
|
@@ -891,7 +1754,9 @@ var DEV_COMMANDS = {
|
|
|
891
1754
|
script: "scripts/gate/type-check-command.ts",
|
|
892
1755
|
description: "Type-check with tsc (skips a basic project with no TypeScript to check)",
|
|
893
1756
|
category: "Development",
|
|
894
|
-
reference: ["[arguments...]", "developer", ["processes"]]
|
|
1757
|
+
reference: ["[arguments...]", "developer", ["processes"]],
|
|
1758
|
+
core_weight: core_budget.CORE_WEIGHTS.type_check,
|
|
1759
|
+
memory_mb: core_budget.MEMORY_MB.type_check
|
|
895
1760
|
},
|
|
896
1761
|
port: {
|
|
897
1762
|
script: "scripts/ports/port-command.ts",
|
|
@@ -988,7 +1853,7 @@ var MAINTENANCE_COMMANDS = {
|
|
|
988
1853
|
script: "scripts/overrides/overrides-check.ts",
|
|
989
1854
|
description: "Check pnpm overrides for drift",
|
|
990
1855
|
category: "Maintenance",
|
|
991
|
-
reference: ["[--save]", "
|
|
1856
|
+
reference: ["[--save]", "developer", ["files"]]
|
|
992
1857
|
},
|
|
993
1858
|
audit: {
|
|
994
1859
|
script: "scripts/security/security-audit.ts",
|
|
@@ -1012,11 +1877,11 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1012
1877
|
shell: [
|
|
1013
1878
|
"sh",
|
|
1014
1879
|
"-c",
|
|
1015
|
-
"export NODE_AUTH_TOKEN=$(gh auth token) && pnpm josh latest:guard && pnpm josh latest:
|
|
1880
|
+
"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"
|
|
1016
1881
|
],
|
|
1017
|
-
description: "Update
|
|
1882
|
+
description: "Update dependencies, run security audit, then update pnpm",
|
|
1018
1883
|
category: "Maintenance",
|
|
1019
|
-
reference: ["", "
|
|
1884
|
+
reference: ["", "developer", ["files", "network", "processes"]],
|
|
1020
1885
|
argument_targets: ["latest:corepack", "latest:update", "audit"]
|
|
1021
1886
|
},
|
|
1022
1887
|
"latest:scope": {
|
|
@@ -1039,13 +1904,13 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1039
1904
|
script: "scripts/version/latest-corepack.ts",
|
|
1040
1905
|
description: "Update pnpm on the current major while preserving the integrity pin",
|
|
1041
1906
|
category: "Maintenance",
|
|
1042
|
-
reference: ["", "
|
|
1907
|
+
reference: ["", "developer", ["files", "network"]]
|
|
1043
1908
|
},
|
|
1044
1909
|
"latest:update": {
|
|
1045
1910
|
script: "scripts/version/latest-update.ts",
|
|
1046
1911
|
description: "Update all dependencies to latest",
|
|
1047
1912
|
category: "Maintenance",
|
|
1048
|
-
reference: ["", "
|
|
1913
|
+
reference: ["", "developer", ["files", "network"]]
|
|
1049
1914
|
}
|
|
1050
1915
|
};
|
|
1051
1916
|
|
|
@@ -1359,7 +2224,9 @@ var ALIASES = {
|
|
|
1359
2224
|
rtr: "retrospective",
|
|
1360
2225
|
rvf: "review:findings",
|
|
1361
2226
|
ruv: "rule:value",
|
|
1362
|
-
ev: "eval"
|
|
2227
|
+
ev: "eval",
|
|
2228
|
+
lsm: "lane:sample",
|
|
2229
|
+
lst: "lane:stats"
|
|
1363
2230
|
};
|
|
1364
2231
|
function canonical_command(name) {
|
|
1365
2232
|
if (!Object.hasOwn(ALIASES, name)) return name;
|
|
@@ -1488,7 +2355,7 @@ var time_shell = {
|
|
|
1488
2355
|
// scripts/time-runtime/time-background.ts
|
|
1489
2356
|
var NO_BACKGROUND = "";
|
|
1490
2357
|
var NO_FINISH = 0;
|
|
1491
|
-
var LAUNCH_PATTERN = /running in background with ID
|
|
2358
|
+
var LAUNCH_PATTERN = /(?:running in background with ID:|moved to the background \(ID:)\s*([\w-]+)/iu;
|
|
1492
2359
|
var AGENT_LAUNCH_PATTERN = /^Async agent launched[\s\S]*?\bagentId:\s*([\w-]+)/u;
|
|
1493
2360
|
var FINISH_PATTERN = /^<task-notification>[\s\S]*?<task-id>([\w-]+)<\/task-id>/u;
|
|
1494
2361
|
var OUTPUT_PATTERN = /tasks\/([\w-]+)\.output/u;
|
|
@@ -1581,358 +2448,75 @@ var time_background = {
|
|
|
1581
2448
|
unread_phases
|
|
1582
2449
|
};
|
|
1583
2450
|
|
|
1584
|
-
// scripts/
|
|
1585
|
-
|
|
1586
|
-
var
|
|
1587
|
-
var
|
|
1588
|
-
var PRIOR_REFERENCE_MARKERS = [
|
|
1589
|
-
"previous finding",
|
|
1590
|
-
"prior finding",
|
|
1591
|
-
"earlier finding",
|
|
1592
|
-
"previous result",
|
|
1593
|
-
"prior result",
|
|
1594
|
-
"earlier result",
|
|
1595
|
-
"based on the previous",
|
|
1596
|
-
"based on the earlier",
|
|
1597
|
-
"from the previous agent",
|
|
1598
|
-
"from the prior agent",
|
|
1599
|
-
"the finding above",
|
|
1600
|
-
"as found earlier",
|
|
1601
|
-
"as found above",
|
|
1602
|
-
"building on the previous"
|
|
1603
|
-
];
|
|
1604
|
-
var READ_COMMANDS = /* @__PURE__ */ new Set([
|
|
1605
|
-
"awk",
|
|
1606
|
-
"basename",
|
|
1607
|
-
"cat",
|
|
1608
|
-
"comm",
|
|
1609
|
-
"cut",
|
|
1610
|
-
"diff",
|
|
1611
|
-
"dirname",
|
|
1612
|
-
"du",
|
|
1613
|
-
"echo",
|
|
1614
|
-
"file",
|
|
1615
|
-
"find",
|
|
1616
|
-
"gh",
|
|
1617
|
-
"grep",
|
|
1618
|
-
"head",
|
|
1619
|
-
"jq",
|
|
1620
|
-
"ls",
|
|
1621
|
-
"nl",
|
|
1622
|
-
"printf",
|
|
1623
|
-
"pwd",
|
|
1624
|
-
"realpath",
|
|
1625
|
-
"rg",
|
|
1626
|
-
// **`sed -i` is deliberately not excluded.** An in-place edit is what `Edit` does, and `Edit` is on
|
|
1627
|
-
// the allow-list above — a turn may issue several of them, so rejecting the shell spelling of the
|
|
1628
|
-
// same thing would exclude a call the tool form counts. Two in-place edits of the *same* file are
|
|
1629
|
-
// caught by the target test instead, which is where that ordering actually lives.
|
|
1630
|
-
"sed",
|
|
1631
|
-
"sort",
|
|
1632
|
-
"stat",
|
|
1633
|
-
"tail",
|
|
1634
|
-
"tree",
|
|
1635
|
-
"uniq",
|
|
1636
|
-
"wc",
|
|
1637
|
-
"which"
|
|
1638
|
-
]);
|
|
1639
|
-
var MUTATION_WORDS = /* @__PURE__ */ new Set([
|
|
1640
|
-
"--field",
|
|
1641
|
-
"--method",
|
|
1642
|
-
"--raw-field",
|
|
1643
|
-
"-F",
|
|
1644
|
-
"-X",
|
|
1645
|
-
"-delete",
|
|
1646
|
-
"-exec",
|
|
1647
|
-
"-f",
|
|
1648
|
-
"add",
|
|
1649
|
-
"chmod",
|
|
1650
|
-
"chown",
|
|
1651
|
-
"close",
|
|
1652
|
-
"comment",
|
|
1653
|
-
"cp",
|
|
1654
|
-
"create",
|
|
1655
|
-
"dd",
|
|
1656
|
-
"delete",
|
|
1657
|
-
"edit",
|
|
1658
|
-
"git",
|
|
1659
|
-
"install",
|
|
1660
|
-
"kill",
|
|
1661
|
-
"ln",
|
|
1662
|
-
"merge",
|
|
1663
|
-
"mkdir",
|
|
1664
|
-
"mv",
|
|
1665
|
-
"node",
|
|
1666
|
-
"npm",
|
|
1667
|
-
"npx",
|
|
1668
|
-
"pkill",
|
|
1669
|
-
"pnpm",
|
|
1670
|
-
"remove",
|
|
1671
|
-
"rm",
|
|
1672
|
-
"scp",
|
|
1673
|
-
"secret",
|
|
1674
|
-
"set",
|
|
1675
|
-
"ssh",
|
|
1676
|
-
"sudo",
|
|
1677
|
-
"tee",
|
|
1678
|
-
"touch",
|
|
1679
|
-
"truncate",
|
|
1680
|
-
"tsx",
|
|
1681
|
-
"upload",
|
|
1682
|
-
"wget"
|
|
1683
|
-
]);
|
|
1684
|
-
var READ_JOSH_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
1685
|
-
"backlog:budget",
|
|
1686
|
-
"backlog:next",
|
|
1687
|
-
"cost",
|
|
1688
|
-
"delegate",
|
|
1689
|
-
"epic:audit",
|
|
1690
|
-
"epic:bundle",
|
|
1691
|
-
"epic:check",
|
|
1692
|
-
"epic:next",
|
|
1693
|
-
"issue:read",
|
|
1694
|
-
"issue:scout",
|
|
1695
|
-
"issue:state",
|
|
1696
|
-
"lane:list",
|
|
1697
|
-
"latest:scope",
|
|
1698
|
-
"release:scope",
|
|
1699
|
-
"review:brief",
|
|
1700
|
-
"review:round2",
|
|
1701
|
-
"run:liveness"
|
|
1702
|
-
]);
|
|
1703
|
-
var JOSH_WORD = "josh";
|
|
1704
|
-
var JOSH_SCRIPT_SUFFIX = "josh.ts";
|
|
1705
|
-
var COMMAND_CHAIN = /[|;&`>]|\$\(/u;
|
|
1706
|
-
var WHITESPACE_PATTERN2 = /\s+/u;
|
|
1707
|
-
var TARGET_FIELDS = ["file_path", "notebook_path", "path", "url"];
|
|
1708
|
-
var TARGET_ARRAY_FIELD = "file_paths";
|
|
1709
|
-
var MAX_TARGETS = 8;
|
|
1710
|
-
var WORD_PATTERN = /[\s'"=(),;:|&]+/u;
|
|
1711
|
-
var EXTENSION_PATTERN = /^[A-Za-z]+$/u;
|
|
1712
|
-
var MAX_EXTENSION = 5;
|
|
1713
|
-
var AFTER_DOT = 1;
|
|
1714
|
-
var FIRST_INDEX = 0;
|
|
1715
|
-
var CURRENT_DIRECTORY = "./";
|
|
1716
|
-
var LAST_CHARACTER = -1;
|
|
1717
|
-
var FLAG_PREFIX2 = "-";
|
|
1718
|
-
var PATH_SEPARATOR = "/";
|
|
1719
|
-
var MIN_TARGET_LENGTH = 3;
|
|
1720
|
-
var WRITING_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "NotebookEdit"]);
|
|
1721
|
-
var WRITING_WORDS = /* @__PURE__ */ new Set(["dd", "sed", "tee"]);
|
|
1722
|
-
var REDIRECTION = ">";
|
|
1723
|
-
var IN_PLACE_COMMAND = "sed";
|
|
1724
|
-
var IN_PLACE_FLAG_PATTERN = /^--in-place\b|^-[A-Za-z]*i/u;
|
|
1725
|
-
function not_bundleable() {
|
|
1726
|
-
return {
|
|
1727
|
-
is_bundleable: false,
|
|
1728
|
-
targets: [],
|
|
1729
|
-
is_writing: false,
|
|
1730
|
-
may_write: false,
|
|
1731
|
-
has_prior_reference: false
|
|
1732
|
-
};
|
|
1733
|
-
}
|
|
1734
|
-
function is_launch_tool(name) {
|
|
1735
|
-
return LAUNCH_TOOLS.has(name);
|
|
1736
|
-
}
|
|
1737
|
-
function words_of(command) {
|
|
1738
|
-
return command.split(WORD_PATTERN).filter((word) => word !== "");
|
|
1739
|
-
}
|
|
1740
|
-
function has_mutation(command) {
|
|
1741
|
-
return words_of(command).some((word) => MUTATION_WORDS.has(word));
|
|
1742
|
-
}
|
|
1743
|
-
function josh_subcommand(command) {
|
|
1744
|
-
const tokens = command.split(WHITESPACE_PATTERN2).filter((token) => token !== "");
|
|
1745
|
-
const josh_index = tokens.findIndex(
|
|
1746
|
-
(token) => token === JOSH_WORD || token.endsWith(JOSH_SCRIPT_SUFFIX)
|
|
1747
|
-
);
|
|
1748
|
-
return josh_index < FIRST_INDEX ? void 0 : tokens[josh_index + 1];
|
|
1749
|
-
}
|
|
1750
|
-
function is_read_josh(command) {
|
|
1751
|
-
if (COMMAND_CHAIN.test(command)) return false;
|
|
1752
|
-
const subcommand = josh_subcommand(command);
|
|
1753
|
-
if (subcommand === void 0) return false;
|
|
1754
|
-
return READ_JOSH_SUBCOMMANDS.has(canonical_command(subcommand));
|
|
1755
|
-
}
|
|
1756
|
-
function may_write_command(command) {
|
|
1757
|
-
if (command.includes(REDIRECTION)) return true;
|
|
1758
|
-
return words_of(command).some((word) => WRITING_WORDS.has(word));
|
|
1759
|
-
}
|
|
1760
|
-
function write_segment(command) {
|
|
1761
|
-
return time_shell.command_segment(time_shell.unquoted(command));
|
|
1762
|
-
}
|
|
1763
|
-
function is_in_place_sed(segment) {
|
|
1764
|
-
if (time_shell.leading_word(segment) !== IN_PLACE_COMMAND) return false;
|
|
1765
|
-
return words_of(segment).some((word) => IN_PLACE_FLAG_PATTERN.test(word));
|
|
1766
|
-
}
|
|
1767
|
-
function normalize(word) {
|
|
1768
|
-
const head = word.startsWith(CURRENT_DIRECTORY) ? word.slice(CURRENT_DIRECTORY.length) : word;
|
|
1769
|
-
return head.endsWith(PATH_SEPARATOR) ? head.slice(0, LAST_CHARACTER) : head;
|
|
1770
|
-
}
|
|
1771
|
-
function has_extension(word) {
|
|
1772
|
-
const dot = word.lastIndexOf(".");
|
|
1773
|
-
if (dot <= FIRST_INDEX) return false;
|
|
1774
|
-
const suffix = word.slice(dot + AFTER_DOT);
|
|
1775
|
-
return suffix.length <= MAX_EXTENSION && EXTENSION_PATTERN.test(suffix);
|
|
1776
|
-
}
|
|
1777
|
-
function is_target(word) {
|
|
1778
|
-
if (word.startsWith(FLAG_PREFIX2) || word.length < MIN_TARGET_LENGTH) return false;
|
|
1779
|
-
return word.includes(PATH_SEPARATOR) || has_extension(word);
|
|
1780
|
-
}
|
|
1781
|
-
function targets_in(text) {
|
|
1782
|
-
return words_of(text).map((word) => normalize(word)).filter((word) => is_target(word)).slice(0, MAX_TARGETS);
|
|
1783
|
-
}
|
|
1784
|
-
function field_text(input, field) {
|
|
1785
|
-
if (!json_value.is_record(input)) return "";
|
|
1786
|
-
const value = input[field];
|
|
1787
|
-
return typeof value === "string" ? value : "";
|
|
1788
|
-
}
|
|
1789
|
-
function field_targets(input) {
|
|
1790
|
-
if (!json_value.is_record(input)) return [];
|
|
1791
|
-
const value = input[TARGET_ARRAY_FIELD];
|
|
1792
|
-
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
|
|
1793
|
-
}
|
|
1794
|
-
function tool_targets(input) {
|
|
1795
|
-
const scalar_targets = TARGET_FIELDS.map((field) => field_text(input, field));
|
|
1796
|
-
const targets = [...scalar_targets, ...field_targets(input)].map((target) => normalize(target));
|
|
1797
|
-
return [...new Set(targets)].filter((target) => target !== "");
|
|
1798
|
-
}
|
|
1799
|
-
function prompt_references_prior(input) {
|
|
1800
|
-
const prompt = field_text(input, "prompt").toLowerCase();
|
|
1801
|
-
return PRIOR_REFERENCE_MARKERS.some((marker) => prompt.includes(marker));
|
|
1802
|
-
}
|
|
1803
|
-
function tool_facts(name, input) {
|
|
1804
|
-
const writes = { is_writing: WRITING_TOOLS.has(name), may_write: WRITING_TOOLS.has(name) };
|
|
1805
|
-
const has_prior_reference = LAUNCH_TOOLS.has(name) && prompt_references_prior(input);
|
|
1806
|
-
if (!BUNDLEABLE_TOOLS.has(name)) return { ...not_bundleable(), ...writes, has_prior_reference };
|
|
1807
|
-
return { is_bundleable: true, targets: tool_targets(input), ...writes, has_prior_reference };
|
|
1808
|
-
}
|
|
1809
|
-
function bash_facts(command) {
|
|
1810
|
-
const writes = {
|
|
1811
|
-
is_writing: is_in_place_sed(write_segment(command)),
|
|
1812
|
-
may_write: may_write_command(command)
|
|
1813
|
-
};
|
|
1814
|
-
if (is_read_josh(command)) {
|
|
1815
|
-
return {
|
|
1816
|
-
is_bundleable: true,
|
|
1817
|
-
targets: targets_in(time_shell.unquoted(command)),
|
|
1818
|
-
...writes,
|
|
1819
|
-
has_prior_reference: false
|
|
1820
|
-
};
|
|
1821
|
-
}
|
|
1822
|
-
if (!READ_COMMANDS.has(time_shell.leading_word(command)) || has_mutation(command)) {
|
|
1823
|
-
return { ...not_bundleable(), ...writes };
|
|
1824
|
-
}
|
|
1825
|
-
return {
|
|
1826
|
-
is_bundleable: true,
|
|
1827
|
-
targets: targets_in(time_shell.unquoted(command)),
|
|
1828
|
-
...writes,
|
|
1829
|
-
has_prior_reference: false
|
|
1830
|
-
};
|
|
1831
|
-
}
|
|
1832
|
-
function call_facts(name, input) {
|
|
1833
|
-
if (name !== BASH_TOOL2) return tool_facts(name, input);
|
|
1834
|
-
return bash_facts(time_shell.bash_command(input));
|
|
1835
|
-
}
|
|
1836
|
-
var time_bundle_call = {
|
|
1837
|
-
MAX_TARGETS,
|
|
1838
|
-
not_bundleable,
|
|
1839
|
-
bash_facts,
|
|
1840
|
-
call_facts,
|
|
1841
|
-
tool_facts,
|
|
1842
|
-
// Exported for `time-agent-bundles.ts` (joshuafolkken/kit#1854), which asks the launch question of a
|
|
1843
|
-
// span's `label` — the tool name for a non-Bash call — so the set lives in one place.
|
|
1844
|
-
is_launch_tool,
|
|
1845
|
-
// Exported for `time-writes.ts` (joshuafolkken/kit#1472), which asks what a call *wrote* rather
|
|
1846
|
-
// than what it named. The extraction is the same one either way — a second copy of it would let a
|
|
1847
|
-
// path be recognized as a target when read and missed when written.
|
|
1848
|
-
targets_in,
|
|
1849
|
-
tool_targets,
|
|
1850
|
-
// Exported for the batching guard's own word scan (joshuafolkken/kit#1390), so the two scanners
|
|
1851
|
-
// cannot come to disagree about where one word of a shell line ends and the next begins.
|
|
1852
|
-
// Exported for the read-fold notice (joshuafolkken/kit#2311), which offers `read:files <path>` only
|
|
1853
|
-
// over file-shaped targets — a bare directory like `scripts/` is a target here but not something
|
|
1854
|
-
// `read:files` can read, so the notice reuses this test rather than keep a second copy that could
|
|
1855
|
-
// drift from what counts as a file path.
|
|
1856
|
-
has_extension,
|
|
1857
|
-
// Exported for `time-writes.ts` (joshuafolkken/kit#1509), which needs the same two answers to say
|
|
1858
|
-
// *which* files an in-place `sed` wrote. Two copies of this test disagreed in both directions at
|
|
1859
|
-
// once — one called a piped `grep -i` a write, the other missed a bundled `sed -ni`.
|
|
1860
|
-
write_segment,
|
|
1861
|
-
is_in_place_sed,
|
|
1862
|
-
// Exported for the drift test in `time-bundle-call.test.ts` (joshuafolkken/kit#1875), which pins that
|
|
1863
|
-
// every name here is a real `josh` command and none of them writes.
|
|
1864
|
-
READ_JOSH_SUBCOMMANDS
|
|
1865
|
-
};
|
|
1866
|
-
|
|
1867
|
-
// scripts/git/schemas.ts
|
|
1868
|
-
import { z as z2 } from "zod";
|
|
1869
|
-
var package_name_schema = z2.object({ name: z2.string().min(1) });
|
|
1870
|
-
var rollup_item_schema = z2.looseObject({
|
|
2451
|
+
// scripts/git/git-schemas.ts
|
|
2452
|
+
import { z as z4 } from "zod";
|
|
2453
|
+
var package_name_schema = z4.object({ name: z4.string().min(1) });
|
|
2454
|
+
var rollup_item_schema = z4.looseObject({
|
|
1871
2455
|
// eslint-disable-next-line @typescript-eslint/naming-convention -- GraphQL field name from GitHub API
|
|
1872
|
-
__typename:
|
|
1873
|
-
state:
|
|
1874
|
-
status:
|
|
1875
|
-
conclusion:
|
|
1876
|
-
name:
|
|
1877
|
-
context:
|
|
2456
|
+
__typename: z4.string().optional(),
|
|
2457
|
+
state: z4.string().optional(),
|
|
2458
|
+
status: z4.string().optional(),
|
|
2459
|
+
conclusion: z4.string().optional(),
|
|
2460
|
+
name: z4.string().optional(),
|
|
2461
|
+
context: z4.string().optional()
|
|
1878
2462
|
});
|
|
1879
|
-
var pr_raw_schema =
|
|
1880
|
-
statusCheckRollup:
|
|
1881
|
-
mergeStateStatus:
|
|
1882
|
-
reviewDecision:
|
|
2463
|
+
var pr_raw_schema = z4.object({
|
|
2464
|
+
statusCheckRollup: z4.array(rollup_item_schema).optional(),
|
|
2465
|
+
mergeStateStatus: z4.string().optional(),
|
|
2466
|
+
reviewDecision: z4.string().optional()
|
|
1883
2467
|
});
|
|
1884
|
-
var pull_comment_schema =
|
|
1885
|
-
body:
|
|
1886
|
-
html_url:
|
|
1887
|
-
user:
|
|
2468
|
+
var pull_comment_schema = z4.object({
|
|
2469
|
+
body: z4.string().optional(),
|
|
2470
|
+
html_url: z4.string().optional(),
|
|
2471
|
+
user: z4.object({ login: z4.string().optional() }).optional()
|
|
1888
2472
|
});
|
|
1889
|
-
var ai_review_pull_comment_schema =
|
|
1890
|
-
body:
|
|
1891
|
-
url:
|
|
1892
|
-
author:
|
|
2473
|
+
var ai_review_pull_comment_schema = z4.object({
|
|
2474
|
+
body: z4.string().optional(),
|
|
2475
|
+
url: z4.string().optional(),
|
|
2476
|
+
author: z4.object({ login: z4.string().optional() }).optional()
|
|
1893
2477
|
});
|
|
1894
|
-
var pr_info_schema =
|
|
1895
|
-
mergeable:
|
|
1896
|
-
mergeStateStatus:
|
|
1897
|
-
state:
|
|
2478
|
+
var pr_info_schema = z4.object({
|
|
2479
|
+
mergeable: z4.union([z4.boolean(), z4.string()]).nullable().optional(),
|
|
2480
|
+
mergeStateStatus: z4.string().nullable().optional(),
|
|
2481
|
+
state: z4.string().optional()
|
|
1898
2482
|
});
|
|
1899
|
-
var epic_issue_schema =
|
|
1900
|
-
number:
|
|
1901
|
-
body:
|
|
2483
|
+
var epic_issue_schema = z4.object({
|
|
2484
|
+
number: z4.number(),
|
|
2485
|
+
body: z4.string().optional()
|
|
1902
2486
|
});
|
|
1903
|
-
var blocking_issue_schema =
|
|
1904
|
-
number:
|
|
1905
|
-
state:
|
|
1906
|
-
repository_url:
|
|
2487
|
+
var blocking_issue_schema = z4.object({
|
|
2488
|
+
number: z4.number(),
|
|
2489
|
+
state: z4.string().optional(),
|
|
2490
|
+
repository_url: z4.string().optional()
|
|
1907
2491
|
});
|
|
1908
|
-
var blocked_by_schema =
|
|
1909
|
-
nodes:
|
|
1910
|
-
totalCount:
|
|
2492
|
+
var blocked_by_schema = z4.object({
|
|
2493
|
+
nodes: z4.array(blocking_issue_schema).default([]),
|
|
2494
|
+
totalCount: z4.number().optional()
|
|
1911
2495
|
}).optional();
|
|
1912
|
-
var epic_child_schema =
|
|
1913
|
-
state:
|
|
2496
|
+
var epic_child_schema = z4.object({
|
|
2497
|
+
state: z4.string().optional(),
|
|
1914
2498
|
blockedBy: blocked_by_schema
|
|
1915
2499
|
});
|
|
1916
|
-
var rest_comment_schema =
|
|
1917
|
-
body:
|
|
1918
|
-
html_url:
|
|
1919
|
-
user:
|
|
2500
|
+
var rest_comment_schema = z4.looseObject({
|
|
2501
|
+
body: z4.string().nullish(),
|
|
2502
|
+
html_url: z4.string().optional(),
|
|
2503
|
+
user: z4.looseObject({ login: z4.string().optional() }).nullish()
|
|
1920
2504
|
});
|
|
1921
|
-
var issue_label_schema =
|
|
1922
|
-
var epic_subject_schema =
|
|
1923
|
-
number:
|
|
1924
|
-
state:
|
|
1925
|
-
labels:
|
|
1926
|
-
body:
|
|
2505
|
+
var issue_label_schema = z4.object({ name: z4.string() });
|
|
2506
|
+
var epic_subject_schema = z4.object({
|
|
2507
|
+
number: z4.number(),
|
|
2508
|
+
state: z4.string().optional(),
|
|
2509
|
+
labels: z4.array(issue_label_schema).optional(),
|
|
2510
|
+
body: z4.string().optional()
|
|
1927
2511
|
});
|
|
1928
|
-
var open_issue_schema =
|
|
1929
|
-
number:
|
|
1930
|
-
title:
|
|
1931
|
-
labels:
|
|
1932
|
-
createdAt:
|
|
2512
|
+
var open_issue_schema = z4.object({
|
|
2513
|
+
number: z4.number(),
|
|
2514
|
+
title: z4.string(),
|
|
2515
|
+
labels: z4.array(issue_label_schema).optional(),
|
|
2516
|
+
createdAt: z4.string(),
|
|
1933
2517
|
blockedBy: blocked_by_schema,
|
|
1934
2518
|
// Present only on the pickup listing, which reads it for the restructures each issue declares.
|
|
1935
|
-
body:
|
|
2519
|
+
body: z4.string().optional()
|
|
1936
2520
|
});
|
|
1937
2521
|
|
|
1938
2522
|
// scripts/gh/git-pr-checks-parse.ts
|
|
@@ -2005,260 +2589,615 @@ function parse_pr_state_snapshot(raw_json) {
|
|
|
2005
2589
|
};
|
|
2006
2590
|
}
|
|
2007
2591
|
|
|
2008
|
-
// scripts/gh/git-pr-checks-eval.ts
|
|
2009
|
-
var DEFAULT_REQUIRED_CHECKS = ["SonarQube"];
|
|
2010
|
-
var CODERABBIT_CHECK_NAME = "CodeRabbit";
|
|
2011
|
-
var REQUIRED_CHECKS_ENV_VAR = "JOSH_REQUIRED_CHECKS";
|
|
2012
|
-
function parse_required_checks() {
|
|
2013
|
-
const raw = process.env[REQUIRED_CHECKS_ENV_VAR];
|
|
2014
|
-
if (!raw) return DEFAULT_REQUIRED_CHECKS;
|
|
2015
|
-
return raw.split(",").map((check) => check.trim()).filter((check) => check.length > 0);
|
|
2016
|
-
}
|
|
2017
|
-
var REQUIRED_CHECKS = parse_required_checks();
|
|
2018
|
-
var MERGE_STATE_CLEAN = "CLEAN";
|
|
2019
|
-
var MERGE_STATE_UNSTABLE = "UNSTABLE";
|
|
2020
|
-
var MERGE_STATE_DIRTY = "DIRTY";
|
|
2021
|
-
var REVIEW_CHANGES_REQUESTED = "CHANGES_REQUESTED";
|
|
2022
|
-
var CHECK_SUITE_SEPARATOR = " / ";
|
|
2023
|
-
var FAILURE_MESSAGE_PREFIX = "PR checks failed";
|
|
2024
|
-
var FAILURE_REASON_REVIEW = "review requested changes";
|
|
2025
|
-
var FAILURE_REASON_CHECKS = "failed checks";
|
|
2026
|
-
var FAILURE_REASON_CONFLICT = "merge conflict";
|
|
2027
|
-
function is_required_match(check_name, required_name) {
|
|
2028
|
-
if (check_name === required_name) return true;
|
|
2029
|
-
return check_name.startsWith(`${required_name}${CHECK_SUITE_SEPARATOR}`);
|
|
2592
|
+
// scripts/gh/git-pr-checks-eval.ts
|
|
2593
|
+
var DEFAULT_REQUIRED_CHECKS = ["SonarQube"];
|
|
2594
|
+
var CODERABBIT_CHECK_NAME = "CodeRabbit";
|
|
2595
|
+
var REQUIRED_CHECKS_ENV_VAR = "JOSH_REQUIRED_CHECKS";
|
|
2596
|
+
function parse_required_checks() {
|
|
2597
|
+
const raw = process.env[REQUIRED_CHECKS_ENV_VAR];
|
|
2598
|
+
if (!raw) return DEFAULT_REQUIRED_CHECKS;
|
|
2599
|
+
return raw.split(",").map((check) => check.trim()).filter((check) => check.length > 0);
|
|
2600
|
+
}
|
|
2601
|
+
var REQUIRED_CHECKS = parse_required_checks();
|
|
2602
|
+
var MERGE_STATE_CLEAN = "CLEAN";
|
|
2603
|
+
var MERGE_STATE_UNSTABLE = "UNSTABLE";
|
|
2604
|
+
var MERGE_STATE_DIRTY = "DIRTY";
|
|
2605
|
+
var REVIEW_CHANGES_REQUESTED = "CHANGES_REQUESTED";
|
|
2606
|
+
var CHECK_SUITE_SEPARATOR = " / ";
|
|
2607
|
+
var FAILURE_MESSAGE_PREFIX = "PR checks failed";
|
|
2608
|
+
var FAILURE_REASON_REVIEW = "review requested changes";
|
|
2609
|
+
var FAILURE_REASON_CHECKS = "failed checks";
|
|
2610
|
+
var FAILURE_REASON_CONFLICT = "merge conflict";
|
|
2611
|
+
function is_required_match(check_name, required_name) {
|
|
2612
|
+
if (check_name === required_name) return true;
|
|
2613
|
+
return check_name.startsWith(`${required_name}${CHECK_SUITE_SEPARATOR}`);
|
|
2614
|
+
}
|
|
2615
|
+
function find_required_check(checks, required_name) {
|
|
2616
|
+
return checks.find((check) => is_required_match(check.name, required_name));
|
|
2617
|
+
}
|
|
2618
|
+
function read_required_statuses(checks) {
|
|
2619
|
+
return REQUIRED_CHECKS.map(
|
|
2620
|
+
(name) => find_required_check(checks, name)?.status ?? CHECK_STATUS_MISSING
|
|
2621
|
+
);
|
|
2622
|
+
}
|
|
2623
|
+
function is_review_blocked(review_decision) {
|
|
2624
|
+
return review_decision === REVIEW_CHANGES_REQUESTED;
|
|
2625
|
+
}
|
|
2626
|
+
function is_merge_conflict(merge_state_status) {
|
|
2627
|
+
return merge_state_status === MERGE_STATE_DIRTY;
|
|
2628
|
+
}
|
|
2629
|
+
function evaluate_failure_state(input) {
|
|
2630
|
+
if (is_merge_conflict(input.merge_state_status) || is_review_blocked(input.review_decision) || input.failed_checks.length > 0) {
|
|
2631
|
+
return "failure";
|
|
2632
|
+
}
|
|
2633
|
+
return void 0;
|
|
2634
|
+
}
|
|
2635
|
+
function is_merge_state_clean(merge_state_status) {
|
|
2636
|
+
return merge_state_status === MERGE_STATE_CLEAN;
|
|
2637
|
+
}
|
|
2638
|
+
function is_every_required_passing(statuses) {
|
|
2639
|
+
return statuses.every((status) => status === CHECK_STATUS_PASS);
|
|
2640
|
+
}
|
|
2641
|
+
function is_coderabbit_check(check_name) {
|
|
2642
|
+
return is_required_match(check_name, CODERABBIT_CHECK_NAME);
|
|
2643
|
+
}
|
|
2644
|
+
function is_unstable_only_from_coderabbit(snapshot) {
|
|
2645
|
+
if (snapshot.merge_state_status !== MERGE_STATE_UNSTABLE) return false;
|
|
2646
|
+
const non_passing = snapshot.rollup.filter((check) => check.status !== CHECK_STATUS_PASS);
|
|
2647
|
+
if (non_passing.length === 0) return false;
|
|
2648
|
+
return non_passing.every((check) => is_coderabbit_check(check.name));
|
|
2649
|
+
}
|
|
2650
|
+
function is_required_check(check_name) {
|
|
2651
|
+
return REQUIRED_CHECKS.some((required) => is_required_match(check_name, required));
|
|
2652
|
+
}
|
|
2653
|
+
function is_blocking_failure(check) {
|
|
2654
|
+
if (check.status !== CHECK_STATUS_FAIL) return false;
|
|
2655
|
+
return !is_coderabbit_check(check.name) || is_required_check(check.name);
|
|
2656
|
+
}
|
|
2657
|
+
function collect_blocking_failures(snapshot) {
|
|
2658
|
+
return snapshot.rollup.filter((check) => is_blocking_failure(check)).map((check) => check.name);
|
|
2659
|
+
}
|
|
2660
|
+
function is_mergeable_state(snapshot) {
|
|
2661
|
+
if (is_merge_state_clean(snapshot.merge_state_status)) return true;
|
|
2662
|
+
return is_unstable_only_from_coderabbit(snapshot);
|
|
2663
|
+
}
|
|
2664
|
+
function collect_failure_reasons(snapshot) {
|
|
2665
|
+
const reasons = [];
|
|
2666
|
+
if (is_merge_conflict(snapshot.merge_state_status)) reasons.push(FAILURE_REASON_CONFLICT);
|
|
2667
|
+
if (is_review_blocked(snapshot.review_decision)) reasons.push(FAILURE_REASON_REVIEW);
|
|
2668
|
+
const failed = collect_blocking_failures(snapshot);
|
|
2669
|
+
if (failed.length > 0) reasons.push(`${FAILURE_REASON_CHECKS}: ${failed.join(", ")}`);
|
|
2670
|
+
return reasons;
|
|
2671
|
+
}
|
|
2672
|
+
function describe_pr_failure(snapshot) {
|
|
2673
|
+
const reasons = collect_failure_reasons(snapshot);
|
|
2674
|
+
if (reasons.length === 0) return `${FAILURE_MESSAGE_PREFIX}.`;
|
|
2675
|
+
return `${FAILURE_MESSAGE_PREFIX} (${reasons.join("; ")}).`;
|
|
2676
|
+
}
|
|
2677
|
+
function evaluate_pr_state(snapshot) {
|
|
2678
|
+
const statuses = read_required_statuses(snapshot.rollup);
|
|
2679
|
+
const failure = evaluate_failure_state({
|
|
2680
|
+
review_decision: snapshot.review_decision,
|
|
2681
|
+
failed_checks: collect_blocking_failures(snapshot),
|
|
2682
|
+
merge_state_status: snapshot.merge_state_status
|
|
2683
|
+
});
|
|
2684
|
+
if (failure !== void 0) return failure;
|
|
2685
|
+
if (is_mergeable_state(snapshot) && is_every_required_passing(statuses)) return "success";
|
|
2686
|
+
return "pending";
|
|
2687
|
+
}
|
|
2688
|
+
function is_review_decision_decisive(snapshot) {
|
|
2689
|
+
return evaluate_pr_state(snapshot) !== "pending";
|
|
2690
|
+
}
|
|
2691
|
+
var PrConflictError = class extends Error {
|
|
2692
|
+
name = "PrConflictError";
|
|
2693
|
+
};
|
|
2694
|
+
|
|
2695
|
+
// scripts/time-runtime/time-format.ts
|
|
2696
|
+
var MS_PER_MINUTE = 6e4;
|
|
2697
|
+
var MS_PER_SECOND2 = 1e3;
|
|
2698
|
+
var MINUTE_DECIMALS = 1;
|
|
2699
|
+
var SECOND_DECIMALS = 1;
|
|
2700
|
+
var PERCENT_SCALE = 100;
|
|
2701
|
+
var PERCENT_DECIMALS = 1;
|
|
2702
|
+
var LABEL_WIDTH = 24;
|
|
2703
|
+
var MINUTES_WIDTH = 9;
|
|
2704
|
+
var NOT_MEASURED = "not measured";
|
|
2705
|
+
var NO_CALLS = "no tool call to divide";
|
|
2706
|
+
var MAX_ROWS = 15;
|
|
2707
|
+
function overflow_line(row_count) {
|
|
2708
|
+
if (row_count <= MAX_ROWS) return [];
|
|
2709
|
+
return [
|
|
2710
|
+
` \u2026 and ${String(row_count - MAX_ROWS)} more (--json carries every row this report holds)`
|
|
2711
|
+
];
|
|
2712
|
+
}
|
|
2713
|
+
function format_minutes(duration_ms) {
|
|
2714
|
+
return `${(duration_ms / MS_PER_MINUTE).toFixed(MINUTE_DECIMALS)} min`;
|
|
2715
|
+
}
|
|
2716
|
+
function format_seconds(duration_ms) {
|
|
2717
|
+
return `${(duration_ms / MS_PER_SECOND2).toFixed(SECOND_DECIMALS)} s`;
|
|
2718
|
+
}
|
|
2719
|
+
function format_share(part, whole) {
|
|
2720
|
+
if (whole === 0) return "n/a";
|
|
2721
|
+
return `${(part / whole * PERCENT_SCALE).toFixed(PERCENT_DECIMALS)}%`;
|
|
2722
|
+
}
|
|
2723
|
+
function usd(amount, decimals) {
|
|
2724
|
+
return `$${amount.toFixed(decimals)}`;
|
|
2725
|
+
}
|
|
2726
|
+
function format_columns(label, minutes, suffix) {
|
|
2727
|
+
return ` ${label.padEnd(LABEL_WIDTH)}${minutes.padStart(MINUTES_WIDTH)} ${suffix}`;
|
|
2728
|
+
}
|
|
2729
|
+
function format_row(label, duration_ms, suffix) {
|
|
2730
|
+
return format_columns(label, format_minutes(duration_ms), suffix);
|
|
2731
|
+
}
|
|
2732
|
+
function unmeasured_row(label) {
|
|
2733
|
+
return format_columns(label, "", NOT_MEASURED);
|
|
2734
|
+
}
|
|
2735
|
+
var time_format = {
|
|
2736
|
+
MAX_ROWS,
|
|
2737
|
+
NO_CALLS,
|
|
2738
|
+
overflow_line,
|
|
2739
|
+
format_seconds,
|
|
2740
|
+
format_share,
|
|
2741
|
+
usd,
|
|
2742
|
+
format_columns,
|
|
2743
|
+
format_row,
|
|
2744
|
+
// `format_clock` stays private: `format_window` is its only caller, and a namespace that offers
|
|
2745
|
+
// both invites a second renderer to join the two with its own arrow.
|
|
2746
|
+
unmeasured_row
|
|
2747
|
+
};
|
|
2748
|
+
|
|
2749
|
+
// scripts/followup/git-followup-stages.ts
|
|
2750
|
+
var STAGE_LINE_PREFIX = "followup stage: ";
|
|
2751
|
+
var STAGE_TOTAL_PREFIX = "followup stages total: ";
|
|
2752
|
+
var STAGE_NAME_WIDTH = 26;
|
|
2753
|
+
var VALUE_COLUMN = STAGE_LINE_PREFIX.length + STAGE_NAME_WIDTH;
|
|
2754
|
+
var NO_DURATION = 0;
|
|
2755
|
+
var STAGE = {
|
|
2756
|
+
closes_and_context: "closes-and-context",
|
|
2757
|
+
checks_wait: "checks-wait",
|
|
2758
|
+
coderabbit_comments: "coderabbit-comments",
|
|
2759
|
+
ai_review_comments: "ai-review-comments",
|
|
2760
|
+
telegram: "telegram",
|
|
2761
|
+
merge: "merge",
|
|
2762
|
+
completion_and_epic_close: "completion-and-epic-close",
|
|
2763
|
+
// The lap that was still running when a stage threw. `followup` exits non-zero on an AI-review
|
|
2764
|
+
// blocker and on a red check, and those are the runs whose wait is longest — reporting nothing for
|
|
2765
|
+
// them would leave the measurement blind to exactly the invocations worth measuring.
|
|
2766
|
+
interrupted: "interrupted",
|
|
2767
|
+
// The interrupted lap when the wait failed on a merge conflict (joshuafolkken/kit#3221), so the
|
|
2768
|
+
// stage block names the cause a resumed session used to look up with `gh pr view`.
|
|
2769
|
+
conflict: "conflict"
|
|
2770
|
+
};
|
|
2771
|
+
function stopped_lap(error) {
|
|
2772
|
+
return error instanceof PrConflictError ? STAGE.conflict : STAGE.interrupted;
|
|
2773
|
+
}
|
|
2774
|
+
function new_log() {
|
|
2775
|
+
return { stages: [], last_ms: performance.now() };
|
|
2776
|
+
}
|
|
2777
|
+
function lap(log, name) {
|
|
2778
|
+
const now_ms = performance.now();
|
|
2779
|
+
log.stages.push({ name, duration_ms: now_ms - log.last_ms });
|
|
2780
|
+
log.last_ms = now_ms;
|
|
2781
|
+
}
|
|
2782
|
+
function total_ms(stages) {
|
|
2783
|
+
return stages.reduce((sum, stage) => sum + stage.duration_ms, NO_DURATION);
|
|
2784
|
+
}
|
|
2785
|
+
function format_stage(stage) {
|
|
2786
|
+
const name = stage.name.padEnd(STAGE_NAME_WIDTH);
|
|
2787
|
+
return `${STAGE_LINE_PREFIX}${name}${time_format.format_seconds(stage.duration_ms)}`;
|
|
2788
|
+
}
|
|
2789
|
+
function format_stages(log) {
|
|
2790
|
+
if (log.stages.length === 0) return [];
|
|
2791
|
+
const rows = log.stages.map((stage) => format_stage(stage));
|
|
2792
|
+
const total = time_format.format_seconds(total_ms(log.stages));
|
|
2793
|
+
return ["", ...rows, `${STAGE_TOTAL_PREFIX.padEnd(VALUE_COLUMN)}${total}`];
|
|
2794
|
+
}
|
|
2795
|
+
function print_stages(log) {
|
|
2796
|
+
for (const line of format_stages(log)) console.info(line);
|
|
2797
|
+
}
|
|
2798
|
+
var git_followup_stages = {
|
|
2799
|
+
STAGE,
|
|
2800
|
+
STAGE_LINE_PREFIX,
|
|
2801
|
+
STAGE_TOTAL_PREFIX,
|
|
2802
|
+
new_log,
|
|
2803
|
+
lap,
|
|
2804
|
+
total_ms,
|
|
2805
|
+
format_stages,
|
|
2806
|
+
print_stages,
|
|
2807
|
+
stopped_lap
|
|
2808
|
+
};
|
|
2809
|
+
|
|
2810
|
+
// scripts/time-runtime/time-followup-stage.ts
|
|
2811
|
+
var LINE_SEPARATOR = "\n";
|
|
2812
|
+
var SECONDS_SUFFIX = " s";
|
|
2813
|
+
var DIGIT_OR_POINT = /[\d.]/u;
|
|
2814
|
+
var MS_PER_SECOND3 = 1e3;
|
|
2815
|
+
var NO_STAGES = [];
|
|
2816
|
+
function stage_body(line) {
|
|
2817
|
+
const trimmed = line.trimStart();
|
|
2818
|
+
if (!trimmed.startsWith(git_followup_stages.STAGE_LINE_PREFIX)) return void 0;
|
|
2819
|
+
return trimmed.slice(git_followup_stages.STAGE_LINE_PREFIX.length);
|
|
2030
2820
|
}
|
|
2031
|
-
function
|
|
2032
|
-
|
|
2821
|
+
function digits_start(head) {
|
|
2822
|
+
let index = head.length;
|
|
2823
|
+
while (index > 0 && DIGIT_OR_POINT.test(head.charAt(index - 1))) index -= 1;
|
|
2824
|
+
return index;
|
|
2033
2825
|
}
|
|
2034
|
-
function
|
|
2035
|
-
return
|
|
2036
|
-
(name) => find_required_check(checks, name)?.status ?? CHECK_STATUS_MISSING
|
|
2037
|
-
);
|
|
2826
|
+
function is_duration(digits) {
|
|
2827
|
+
return digits !== "" && Number.isFinite(Number(digits));
|
|
2038
2828
|
}
|
|
2039
|
-
function
|
|
2040
|
-
|
|
2829
|
+
function to_stage(body) {
|
|
2830
|
+
const text = body.trimEnd();
|
|
2831
|
+
if (!text.endsWith(SECONDS_SUFFIX)) return void 0;
|
|
2832
|
+
const head = text.slice(0, -SECONDS_SUFFIX.length);
|
|
2833
|
+
const start = digits_start(head);
|
|
2834
|
+
const name = head.slice(0, start).trim();
|
|
2835
|
+
const digits = head.slice(start);
|
|
2836
|
+
if (name === "" || !is_duration(digits)) return void 0;
|
|
2837
|
+
return { name, duration_ms: Number(digits) * MS_PER_SECOND3 };
|
|
2041
2838
|
}
|
|
2042
|
-
function
|
|
2043
|
-
|
|
2839
|
+
function read_stages(text) {
|
|
2840
|
+
if (!text.includes(git_followup_stages.STAGE_LINE_PREFIX)) return NO_STAGES;
|
|
2841
|
+
return text.split(LINE_SEPARATOR).map((line) => stage_body(line)).filter((body) => body !== void 0).map((body) => to_stage(body)).filter((stage) => stage !== void 0);
|
|
2044
2842
|
}
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2843
|
+
var time_followup_stage = { NO_STAGES, read_stages };
|
|
2844
|
+
|
|
2845
|
+
// scripts/time-runtime/time-reported-failure.ts
|
|
2846
|
+
import { z as z5 } from "zod";
|
|
2847
|
+
var TEXT_BLOCK_SCHEMA = z5.object({ text: z5.string().nullish() });
|
|
2848
|
+
var CONTENT_SCHEMA = z5.union([z5.string(), z5.array(z5.unknown())]);
|
|
2849
|
+
var LINE_SEPARATOR2 = "\n";
|
|
2850
|
+
function block_text(block) {
|
|
2851
|
+
const parsed = TEXT_BLOCK_SCHEMA.safeParse(block);
|
|
2852
|
+
return parsed.success ? parsed.data.text ?? "" : "";
|
|
2050
2853
|
}
|
|
2051
|
-
function
|
|
2052
|
-
|
|
2854
|
+
function result_text2(content) {
|
|
2855
|
+
const parsed = CONTENT_SCHEMA.safeParse(content);
|
|
2856
|
+
if (!parsed.success) return "";
|
|
2857
|
+
if (typeof parsed.data === "string") return parsed.data;
|
|
2858
|
+
return parsed.data.map((block) => block_text(block)).join(LINE_SEPARATOR2);
|
|
2053
2859
|
}
|
|
2054
|
-
function
|
|
2055
|
-
return
|
|
2860
|
+
function is_failure_line(line) {
|
|
2861
|
+
return line.trimStart().startsWith(status_icons.FAIL_ICON);
|
|
2056
2862
|
}
|
|
2057
|
-
function
|
|
2058
|
-
return
|
|
2863
|
+
function is_failed_verdict(line) {
|
|
2864
|
+
return josh_verdict.read_verdict(line) === josh_verdict.FAILED_VERDICT;
|
|
2059
2865
|
}
|
|
2060
|
-
function
|
|
2061
|
-
|
|
2062
|
-
const non_passing = snapshot.rollup.filter((check) => check.status !== CHECK_STATUS_PASS);
|
|
2063
|
-
if (non_passing.length === 0) return false;
|
|
2064
|
-
return non_passing.every((check) => is_coderabbit_check(check.name));
|
|
2866
|
+
function is_passed_verdict(line) {
|
|
2867
|
+
return josh_verdict.read_verdict(line) === josh_verdict.PASSED_VERDICT;
|
|
2065
2868
|
}
|
|
2066
|
-
function
|
|
2067
|
-
return
|
|
2869
|
+
function new_scan() {
|
|
2870
|
+
return {
|
|
2871
|
+
did_find: false,
|
|
2872
|
+
has_failure_before_region: false,
|
|
2873
|
+
has_failure_in_region: false,
|
|
2874
|
+
is_region_open: false
|
|
2875
|
+
};
|
|
2068
2876
|
}
|
|
2069
|
-
function
|
|
2070
|
-
|
|
2071
|
-
|
|
2877
|
+
function close_region(scan) {
|
|
2878
|
+
scan.did_find ||= scan.is_region_open && scan.has_failure_before_region;
|
|
2879
|
+
scan.has_failure_before_region = false;
|
|
2880
|
+
scan.has_failure_in_region = false;
|
|
2881
|
+
scan.is_region_open = false;
|
|
2072
2882
|
}
|
|
2073
|
-
function
|
|
2074
|
-
|
|
2883
|
+
function note_failure(scan) {
|
|
2884
|
+
if (scan.is_region_open) {
|
|
2885
|
+
scan.has_failure_in_region = true;
|
|
2886
|
+
return;
|
|
2887
|
+
}
|
|
2888
|
+
scan.has_failure_before_region = true;
|
|
2075
2889
|
}
|
|
2076
|
-
function
|
|
2077
|
-
if (
|
|
2078
|
-
|
|
2890
|
+
function scan_line(scan, line) {
|
|
2891
|
+
if (is_passed_verdict(line)) {
|
|
2892
|
+
close_region(scan);
|
|
2893
|
+
return;
|
|
2894
|
+
}
|
|
2895
|
+
if (is_failure_line(line)) {
|
|
2896
|
+
note_failure(scan);
|
|
2897
|
+
return;
|
|
2898
|
+
}
|
|
2899
|
+
if (josh_verdict.is_gate_opening(line)) scan.is_region_open = true;
|
|
2079
2900
|
}
|
|
2080
|
-
function
|
|
2081
|
-
const
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
const failed = collect_blocking_failures(snapshot);
|
|
2085
|
-
if (failed.length > 0) reasons.push(`${FAILURE_REASON_CHECKS}: ${failed.join(", ")}`);
|
|
2086
|
-
return reasons;
|
|
2901
|
+
function scan_body(lines) {
|
|
2902
|
+
const scan = new_scan();
|
|
2903
|
+
for (const line of lines) scan_line(scan, line);
|
|
2904
|
+
return scan;
|
|
2087
2905
|
}
|
|
2088
|
-
function
|
|
2089
|
-
|
|
2090
|
-
if (reasons.length === 0) return `${FAILURE_MESSAGE_PREFIX}.`;
|
|
2091
|
-
return `${FAILURE_MESSAGE_PREFIX} (${reasons.join("; ")}).`;
|
|
2906
|
+
function did_scan_find(scan) {
|
|
2907
|
+
return scan.did_find || scan.has_failure_before_region || scan.has_failure_in_region;
|
|
2092
2908
|
}
|
|
2093
|
-
function
|
|
2094
|
-
const
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
failed_checks: collect_blocking_failures(snapshot),
|
|
2098
|
-
merge_state_status: snapshot.merge_state_status
|
|
2099
|
-
});
|
|
2100
|
-
if (failure !== void 0) return failure;
|
|
2101
|
-
if (is_mergeable_state(snapshot) && is_every_required_passing(statuses)) {
|
|
2102
|
-
return "success";
|
|
2103
|
-
}
|
|
2104
|
-
return "pending";
|
|
2909
|
+
function has_failure_line(content) {
|
|
2910
|
+
const lines = result_text2(content).split(LINE_SEPARATOR2);
|
|
2911
|
+
if (lines.some((line) => is_failed_verdict(line))) return true;
|
|
2912
|
+
return did_scan_find(scan_body(lines));
|
|
2105
2913
|
}
|
|
2106
|
-
function
|
|
2107
|
-
return
|
|
2914
|
+
function is_reported_failure(josh_command, did_print_failure) {
|
|
2915
|
+
return josh_command !== "" && did_print_failure;
|
|
2108
2916
|
}
|
|
2109
|
-
var
|
|
2110
|
-
name = "PrConflictError";
|
|
2111
|
-
};
|
|
2917
|
+
var time_reported_failure = { result_text: result_text2, has_failure_line, is_reported_failure };
|
|
2112
2918
|
|
|
2113
|
-
// scripts/time-runtime/time-
|
|
2114
|
-
var
|
|
2115
|
-
var
|
|
2116
|
-
var
|
|
2117
|
-
var
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2919
|
+
// scripts/time-runtime/time-bundle-call.ts
|
|
2920
|
+
var { BASH_TOOL: BASH_TOOL2 } = cost_blocks;
|
|
2921
|
+
var BUNDLEABLE_TOOLS = /* @__PURE__ */ new Set(["Edit", "Glob", "Grep", "Read", "WebFetch", "WebSearch", "Write"]);
|
|
2922
|
+
var LAUNCH_TOOLS = /* @__PURE__ */ new Set(["Agent", "Task"]);
|
|
2923
|
+
var PRIOR_REFERENCE_MARKERS = [
|
|
2924
|
+
"previous finding",
|
|
2925
|
+
"prior finding",
|
|
2926
|
+
"earlier finding",
|
|
2927
|
+
"previous result",
|
|
2928
|
+
"prior result",
|
|
2929
|
+
"earlier result",
|
|
2930
|
+
"based on the previous",
|
|
2931
|
+
"based on the earlier",
|
|
2932
|
+
"from the previous agent",
|
|
2933
|
+
"from the prior agent",
|
|
2934
|
+
"the finding above",
|
|
2935
|
+
"as found earlier",
|
|
2936
|
+
"as found above",
|
|
2937
|
+
"building on the previous"
|
|
2938
|
+
];
|
|
2939
|
+
var READ_COMMANDS = /* @__PURE__ */ new Set([
|
|
2940
|
+
"awk",
|
|
2941
|
+
"basename",
|
|
2942
|
+
"cat",
|
|
2943
|
+
"comm",
|
|
2944
|
+
"cut",
|
|
2945
|
+
"diff",
|
|
2946
|
+
"dirname",
|
|
2947
|
+
"du",
|
|
2948
|
+
"echo",
|
|
2949
|
+
"file",
|
|
2950
|
+
"find",
|
|
2951
|
+
"gh",
|
|
2952
|
+
"grep",
|
|
2953
|
+
"head",
|
|
2954
|
+
"jq",
|
|
2955
|
+
"ls",
|
|
2956
|
+
"nl",
|
|
2957
|
+
"printf",
|
|
2958
|
+
"pwd",
|
|
2959
|
+
"realpath",
|
|
2960
|
+
"rg",
|
|
2961
|
+
// **`sed -i` is deliberately not excluded.** An in-place edit is what `Edit` does, and `Edit` is on
|
|
2962
|
+
// the allow-list above — a turn may issue several of them, so rejecting the shell spelling of the
|
|
2963
|
+
// same thing would exclude a call the tool form counts. Two in-place edits of the *same* file are
|
|
2964
|
+
// caught by the target test instead, which is where that ordering actually lives.
|
|
2965
|
+
"sed",
|
|
2966
|
+
"sort",
|
|
2967
|
+
"stat",
|
|
2968
|
+
"tail",
|
|
2969
|
+
"tree",
|
|
2970
|
+
"uniq",
|
|
2971
|
+
"wc",
|
|
2972
|
+
"which"
|
|
2973
|
+
]);
|
|
2974
|
+
var MUTATION_WORDS = /* @__PURE__ */ new Set([
|
|
2975
|
+
"--field",
|
|
2976
|
+
"--method",
|
|
2977
|
+
"--raw-field",
|
|
2978
|
+
"-F",
|
|
2979
|
+
"-X",
|
|
2980
|
+
"-delete",
|
|
2981
|
+
"-exec",
|
|
2982
|
+
"-f",
|
|
2983
|
+
"add",
|
|
2984
|
+
"chmod",
|
|
2985
|
+
"chown",
|
|
2986
|
+
"close",
|
|
2987
|
+
"comment",
|
|
2988
|
+
"cp",
|
|
2989
|
+
"create",
|
|
2990
|
+
"dd",
|
|
2991
|
+
"delete",
|
|
2992
|
+
"edit",
|
|
2993
|
+
"git",
|
|
2994
|
+
"install",
|
|
2995
|
+
"kill",
|
|
2996
|
+
"ln",
|
|
2997
|
+
"merge",
|
|
2998
|
+
"mkdir",
|
|
2999
|
+
"mv",
|
|
3000
|
+
"node",
|
|
3001
|
+
"npm",
|
|
3002
|
+
"npx",
|
|
3003
|
+
"pkill",
|
|
3004
|
+
"pnpm",
|
|
3005
|
+
"remove",
|
|
3006
|
+
"rm",
|
|
3007
|
+
"scp",
|
|
3008
|
+
"secret",
|
|
3009
|
+
"set",
|
|
3010
|
+
"ssh",
|
|
3011
|
+
"sudo",
|
|
3012
|
+
"tee",
|
|
3013
|
+
"touch",
|
|
3014
|
+
"truncate",
|
|
3015
|
+
"tsx",
|
|
3016
|
+
"upload",
|
|
3017
|
+
"wget"
|
|
3018
|
+
]);
|
|
3019
|
+
var READ_JOSH_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
3020
|
+
"backlog:budget",
|
|
3021
|
+
"backlog:next",
|
|
3022
|
+
"cost",
|
|
3023
|
+
"delegate",
|
|
3024
|
+
"epic:audit",
|
|
3025
|
+
"epic:bundle",
|
|
3026
|
+
"epic:check",
|
|
3027
|
+
"epic:next",
|
|
3028
|
+
"issue:read",
|
|
3029
|
+
"issue:scout",
|
|
3030
|
+
"issue:state",
|
|
3031
|
+
"lane:list",
|
|
3032
|
+
"latest:scope",
|
|
3033
|
+
"release:scope",
|
|
3034
|
+
"review:brief",
|
|
3035
|
+
"review:round2",
|
|
3036
|
+
"run:liveness"
|
|
3037
|
+
]);
|
|
3038
|
+
var JOSH_WORD = "josh";
|
|
3039
|
+
var JOSH_SCRIPT_SUFFIX = "josh.ts";
|
|
3040
|
+
var COMMAND_CHAIN = /[|;&`>]|\$\(/u;
|
|
3041
|
+
var WHITESPACE_PATTERN2 = /\s+/u;
|
|
3042
|
+
var TARGET_FIELDS = ["file_path", "notebook_path", "path", "url"];
|
|
3043
|
+
var TARGET_ARRAY_FIELD = "file_paths";
|
|
3044
|
+
var MAX_TARGETS = 8;
|
|
3045
|
+
var WORD_PATTERN = /[\s'"=(),;:|&]+/u;
|
|
3046
|
+
var EXTENSION_PATTERN = /^[A-Za-z]+$/u;
|
|
3047
|
+
var MAX_EXTENSION = 5;
|
|
3048
|
+
var AFTER_DOT = 1;
|
|
3049
|
+
var FIRST_INDEX = 0;
|
|
3050
|
+
var CURRENT_DIRECTORY = "./";
|
|
3051
|
+
var LAST_CHARACTER = -1;
|
|
3052
|
+
var FLAG_PREFIX2 = "-";
|
|
3053
|
+
var PATH_SEPARATOR = "/";
|
|
3054
|
+
var MIN_TARGET_LENGTH = 3;
|
|
3055
|
+
var WRITING_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "NotebookEdit"]);
|
|
3056
|
+
var WRITING_WORDS = /* @__PURE__ */ new Set(["dd", "sed", "tee"]);
|
|
3057
|
+
var REDIRECTION = ">";
|
|
3058
|
+
var IN_PLACE_COMMAND = "sed";
|
|
3059
|
+
var IN_PLACE_FLAG_PATTERN = /^--in-place\b|^-[A-Za-z]*i/u;
|
|
3060
|
+
function not_bundleable() {
|
|
3061
|
+
return {
|
|
3062
|
+
is_bundleable: false,
|
|
3063
|
+
targets: [],
|
|
3064
|
+
is_writing: false,
|
|
3065
|
+
may_write: false,
|
|
3066
|
+
has_prior_reference: false
|
|
3067
|
+
};
|
|
2130
3068
|
}
|
|
2131
|
-
function
|
|
2132
|
-
return
|
|
3069
|
+
function is_launch_tool(name) {
|
|
3070
|
+
return LAUNCH_TOOLS.has(name);
|
|
2133
3071
|
}
|
|
2134
|
-
function
|
|
2135
|
-
return
|
|
3072
|
+
function words_of(command) {
|
|
3073
|
+
return command.split(WORD_PATTERN).filter((word) => word !== "");
|
|
2136
3074
|
}
|
|
2137
|
-
function
|
|
2138
|
-
|
|
2139
|
-
return `${(part / whole * PERCENT_SCALE).toFixed(PERCENT_DECIMALS)}%`;
|
|
3075
|
+
function has_mutation(command) {
|
|
3076
|
+
return words_of(command).some((word) => MUTATION_WORDS.has(word));
|
|
2140
3077
|
}
|
|
2141
|
-
function
|
|
2142
|
-
|
|
3078
|
+
function josh_subcommand(command) {
|
|
3079
|
+
const tokens = command.split(WHITESPACE_PATTERN2).filter((token) => token !== "");
|
|
3080
|
+
const josh_index = tokens.findIndex(
|
|
3081
|
+
(token) => token === JOSH_WORD || token.endsWith(JOSH_SCRIPT_SUFFIX)
|
|
3082
|
+
);
|
|
3083
|
+
return josh_index < FIRST_INDEX ? void 0 : tokens[josh_index + 1];
|
|
2143
3084
|
}
|
|
2144
|
-
function
|
|
2145
|
-
|
|
3085
|
+
function is_read_josh(command) {
|
|
3086
|
+
if (COMMAND_CHAIN.test(command)) return false;
|
|
3087
|
+
const subcommand = josh_subcommand(command);
|
|
3088
|
+
if (subcommand === void 0) return false;
|
|
3089
|
+
return READ_JOSH_SUBCOMMANDS.has(canonical_command(subcommand));
|
|
2146
3090
|
}
|
|
2147
|
-
function
|
|
2148
|
-
|
|
3091
|
+
function may_write_command(command) {
|
|
3092
|
+
if (command.includes(REDIRECTION)) return true;
|
|
3093
|
+
return words_of(command).some((word) => WRITING_WORDS.has(word));
|
|
2149
3094
|
}
|
|
2150
|
-
function
|
|
2151
|
-
return
|
|
3095
|
+
function write_segment(command) {
|
|
3096
|
+
return time_shell.command_segment(time_shell.unquoted(command));
|
|
2152
3097
|
}
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
overflow_line,
|
|
2157
|
-
format_seconds,
|
|
2158
|
-
format_share,
|
|
2159
|
-
usd,
|
|
2160
|
-
format_columns,
|
|
2161
|
-
format_row,
|
|
2162
|
-
// `format_clock` stays private: `format_window` is its only caller, and a namespace that offers
|
|
2163
|
-
// both invites a second renderer to join the two with its own arrow.
|
|
2164
|
-
unmeasured_row
|
|
2165
|
-
};
|
|
2166
|
-
|
|
2167
|
-
// scripts/followup/git-followup-stages.ts
|
|
2168
|
-
var STAGE_LINE_PREFIX = "followup stage: ";
|
|
2169
|
-
var STAGE_TOTAL_PREFIX = "followup stages total: ";
|
|
2170
|
-
var STAGE_NAME_WIDTH = 26;
|
|
2171
|
-
var VALUE_COLUMN = STAGE_LINE_PREFIX.length + STAGE_NAME_WIDTH;
|
|
2172
|
-
var NO_DURATION = 0;
|
|
2173
|
-
var STAGE = {
|
|
2174
|
-
closes_and_context: "closes-and-context",
|
|
2175
|
-
checks_wait: "checks-wait",
|
|
2176
|
-
coderabbit_comments: "coderabbit-comments",
|
|
2177
|
-
ai_review_comments: "ai-review-comments",
|
|
2178
|
-
telegram: "telegram",
|
|
2179
|
-
merge: "merge",
|
|
2180
|
-
completion_and_epic_close: "completion-and-epic-close",
|
|
2181
|
-
// The lap that was still running when a stage threw. `followup` exits non-zero on an AI-review
|
|
2182
|
-
// blocker and on a red check, and those are the runs whose wait is longest — reporting nothing for
|
|
2183
|
-
// them would leave the measurement blind to exactly the invocations worth measuring.
|
|
2184
|
-
interrupted: "interrupted",
|
|
2185
|
-
// The interrupted lap when the wait failed on a merge conflict (joshuafolkken/kit#3221), so the
|
|
2186
|
-
// stage block names the cause a resumed session used to look up with `gh pr view`.
|
|
2187
|
-
conflict: "conflict"
|
|
2188
|
-
};
|
|
2189
|
-
function stopped_lap(error) {
|
|
2190
|
-
return error instanceof PrConflictError ? STAGE.conflict : STAGE.interrupted;
|
|
3098
|
+
function is_in_place_sed(segment) {
|
|
3099
|
+
if (time_shell.leading_word(segment) !== IN_PLACE_COMMAND) return false;
|
|
3100
|
+
return words_of(segment).some((word) => IN_PLACE_FLAG_PATTERN.test(word));
|
|
2191
3101
|
}
|
|
2192
|
-
function
|
|
2193
|
-
|
|
3102
|
+
function normalize(word) {
|
|
3103
|
+
const head = word.startsWith(CURRENT_DIRECTORY) ? word.slice(CURRENT_DIRECTORY.length) : word;
|
|
3104
|
+
return head.endsWith(PATH_SEPARATOR) ? head.slice(0, LAST_CHARACTER) : head;
|
|
2194
3105
|
}
|
|
2195
|
-
function
|
|
2196
|
-
const
|
|
2197
|
-
|
|
2198
|
-
|
|
3106
|
+
function has_extension(word) {
|
|
3107
|
+
const dot = word.lastIndexOf(".");
|
|
3108
|
+
if (dot <= FIRST_INDEX) return false;
|
|
3109
|
+
const suffix = word.slice(dot + AFTER_DOT);
|
|
3110
|
+
return suffix.length <= MAX_EXTENSION && EXTENSION_PATTERN.test(suffix);
|
|
2199
3111
|
}
|
|
2200
|
-
function
|
|
2201
|
-
|
|
3112
|
+
function is_target(word) {
|
|
3113
|
+
if (word.startsWith(FLAG_PREFIX2) || word.length < MIN_TARGET_LENGTH) return false;
|
|
3114
|
+
return word.includes(PATH_SEPARATOR) || has_extension(word);
|
|
2202
3115
|
}
|
|
2203
|
-
function
|
|
2204
|
-
|
|
2205
|
-
return `${STAGE_LINE_PREFIX}${name}${time_format.format_seconds(stage.duration_ms)}`;
|
|
3116
|
+
function targets_in(text) {
|
|
3117
|
+
return words_of(text).map((word) => normalize(word)).filter((word) => is_target(word)).slice(0, MAX_TARGETS);
|
|
2206
3118
|
}
|
|
2207
|
-
function
|
|
2208
|
-
if (
|
|
2209
|
-
const
|
|
2210
|
-
|
|
2211
|
-
return ["", ...rows, `${STAGE_TOTAL_PREFIX.padEnd(VALUE_COLUMN)}${total}`];
|
|
3119
|
+
function field_text(input, field) {
|
|
3120
|
+
if (!json_value.is_record(input)) return "";
|
|
3121
|
+
const value = input[field];
|
|
3122
|
+
return typeof value === "string" ? value : "";
|
|
2212
3123
|
}
|
|
2213
|
-
function
|
|
2214
|
-
|
|
3124
|
+
function field_targets(input) {
|
|
3125
|
+
if (!json_value.is_record(input)) return [];
|
|
3126
|
+
const value = input[TARGET_ARRAY_FIELD];
|
|
3127
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
|
|
2215
3128
|
}
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
new_log,
|
|
2221
|
-
lap,
|
|
2222
|
-
total_ms,
|
|
2223
|
-
format_stages,
|
|
2224
|
-
print_stages,
|
|
2225
|
-
stopped_lap
|
|
2226
|
-
};
|
|
2227
|
-
|
|
2228
|
-
// scripts/time-runtime/time-followup-stage.ts
|
|
2229
|
-
var LINE_SEPARATOR = "\n";
|
|
2230
|
-
var SECONDS_SUFFIX = " s";
|
|
2231
|
-
var DIGIT_OR_POINT = /[\d.]/u;
|
|
2232
|
-
var MS_PER_SECOND2 = 1e3;
|
|
2233
|
-
var NO_STAGES = [];
|
|
2234
|
-
function stage_body(line) {
|
|
2235
|
-
const trimmed = line.trimStart();
|
|
2236
|
-
if (!trimmed.startsWith(git_followup_stages.STAGE_LINE_PREFIX)) return void 0;
|
|
2237
|
-
return trimmed.slice(git_followup_stages.STAGE_LINE_PREFIX.length);
|
|
3129
|
+
function tool_targets(input) {
|
|
3130
|
+
const scalar_targets = TARGET_FIELDS.map((field) => field_text(input, field));
|
|
3131
|
+
const targets = [...scalar_targets, ...field_targets(input)].map((target) => normalize(target));
|
|
3132
|
+
return [...new Set(targets)].filter((target) => target !== "");
|
|
2238
3133
|
}
|
|
2239
|
-
function
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
return index;
|
|
3134
|
+
function prompt_references_prior(input) {
|
|
3135
|
+
const prompt = field_text(input, "prompt").toLowerCase();
|
|
3136
|
+
return PRIOR_REFERENCE_MARKERS.some((marker) => prompt.includes(marker));
|
|
2243
3137
|
}
|
|
2244
|
-
function
|
|
2245
|
-
|
|
3138
|
+
function tool_facts(name, input) {
|
|
3139
|
+
const writes = { is_writing: WRITING_TOOLS.has(name), may_write: WRITING_TOOLS.has(name) };
|
|
3140
|
+
const has_prior_reference = LAUNCH_TOOLS.has(name) && prompt_references_prior(input);
|
|
3141
|
+
if (!BUNDLEABLE_TOOLS.has(name)) return { ...not_bundleable(), ...writes, has_prior_reference };
|
|
3142
|
+
return { is_bundleable: true, targets: tool_targets(input), ...writes, has_prior_reference };
|
|
2246
3143
|
}
|
|
2247
|
-
function
|
|
2248
|
-
const
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
3144
|
+
function bash_facts(command) {
|
|
3145
|
+
const writes = {
|
|
3146
|
+
is_writing: is_in_place_sed(write_segment(command)),
|
|
3147
|
+
may_write: may_write_command(command)
|
|
3148
|
+
};
|
|
3149
|
+
if (is_read_josh(command)) {
|
|
3150
|
+
return {
|
|
3151
|
+
is_bundleable: true,
|
|
3152
|
+
targets: targets_in(time_shell.unquoted(command)),
|
|
3153
|
+
...writes,
|
|
3154
|
+
has_prior_reference: false
|
|
3155
|
+
};
|
|
3156
|
+
}
|
|
3157
|
+
if (!READ_COMMANDS.has(time_shell.leading_word(command)) || has_mutation(command)) {
|
|
3158
|
+
return { ...not_bundleable(), ...writes };
|
|
3159
|
+
}
|
|
3160
|
+
return {
|
|
3161
|
+
is_bundleable: true,
|
|
3162
|
+
targets: targets_in(time_shell.unquoted(command)),
|
|
3163
|
+
...writes,
|
|
3164
|
+
has_prior_reference: false
|
|
3165
|
+
};
|
|
2256
3166
|
}
|
|
2257
|
-
function
|
|
2258
|
-
if (
|
|
2259
|
-
return
|
|
3167
|
+
function call_facts(name, input) {
|
|
3168
|
+
if (name !== BASH_TOOL2) return tool_facts(name, input);
|
|
3169
|
+
return bash_facts(time_shell.bash_command(input));
|
|
2260
3170
|
}
|
|
2261
|
-
var
|
|
3171
|
+
var time_bundle_call = {
|
|
3172
|
+
MAX_TARGETS,
|
|
3173
|
+
not_bundleable,
|
|
3174
|
+
bash_facts,
|
|
3175
|
+
call_facts,
|
|
3176
|
+
tool_facts,
|
|
3177
|
+
// Exported for `time-agent-bundles.ts` (joshuafolkken/kit#1854), which asks the launch question of a
|
|
3178
|
+
// span's `label` — the tool name for a non-Bash call — so the set lives in one place.
|
|
3179
|
+
is_launch_tool,
|
|
3180
|
+
// Exported for `time-writes.ts` (joshuafolkken/kit#1472), which asks what a call *wrote* rather
|
|
3181
|
+
// than what it named. The extraction is the same one either way — a second copy of it would let a
|
|
3182
|
+
// path be recognized as a target when read and missed when written.
|
|
3183
|
+
targets_in,
|
|
3184
|
+
tool_targets,
|
|
3185
|
+
// Exported for the batching guard's own word scan (joshuafolkken/kit#1390), so the two scanners
|
|
3186
|
+
// cannot come to disagree about where one word of a shell line ends and the next begins.
|
|
3187
|
+
// Exported for the read-fold notice (joshuafolkken/kit#2311), which offers `read:files <path>` only
|
|
3188
|
+
// over file-shaped targets — a bare directory like `scripts/` is a target here but not something
|
|
3189
|
+
// `read:files` can read, so the notice reuses this test rather than keep a second copy that could
|
|
3190
|
+
// drift from what counts as a file path.
|
|
3191
|
+
has_extension,
|
|
3192
|
+
// Exported for `time-writes.ts` (joshuafolkken/kit#1509), which needs the same two answers to say
|
|
3193
|
+
// *which* files an in-place `sed` wrote. Two copies of this test disagreed in both directions at
|
|
3194
|
+
// once — one called a piped `grep -i` a write, the other missed a bundled `sed -ni`.
|
|
3195
|
+
write_segment,
|
|
3196
|
+
is_in_place_sed,
|
|
3197
|
+
// Exported for the drift test in `time-bundle-call.test.ts` (joshuafolkken/kit#1875), which pins that
|
|
3198
|
+
// every name here is a real `josh` command and none of them writes.
|
|
3199
|
+
READ_JOSH_SUBCOMMANDS
|
|
3200
|
+
};
|
|
2262
3201
|
|
|
2263
3202
|
// scripts/cost-runtime/cost-attribute.ts
|
|
2264
3203
|
var ISSUE_BRANCH_PATTERN = /^(\d+)-/u;
|
|
@@ -2415,121 +3354,6 @@ var time_markers = {
|
|
|
2415
3354
|
bash_issue
|
|
2416
3355
|
};
|
|
2417
3356
|
|
|
2418
|
-
// scripts/lib/status-icons.ts
|
|
2419
|
-
var FAIL_ICON = "\u2717";
|
|
2420
|
-
var PASS_ICON = "\u2714";
|
|
2421
|
-
var status_icons = { FAIL_ICON, PASS_ICON };
|
|
2422
|
-
|
|
2423
|
-
// scripts/josh/josh-verdict.ts
|
|
2424
|
-
var { FAIL_ICON: FAIL_ICON2, PASS_ICON: PASS_ICON2 } = status_icons;
|
|
2425
|
-
var GATE_SUBJECT = "verification gate";
|
|
2426
|
-
var GATE_PASSED_PREFIX = `${PASS_ICON2} ${GATE_SUBJECT} passed`;
|
|
2427
|
-
var GATE_FAILED_PREFIX = `${FAIL_ICON2} ${GATE_SUBJECT} failed`;
|
|
2428
|
-
var PASSED_VERDICT = "passed";
|
|
2429
|
-
var FAILED_VERDICT = "failed";
|
|
2430
|
-
function format_gate_passed(step_count, total) {
|
|
2431
|
-
return `${GATE_PASSED_PREFIX} (${step_count} checks) in ${total}.`;
|
|
2432
|
-
}
|
|
2433
|
-
function format_gate_failed(failed_labels, total) {
|
|
2434
|
-
return `${GATE_FAILED_PREFIX}: ${failed_labels} (${total})`;
|
|
2435
|
-
}
|
|
2436
|
-
var GATE_OPENING_PREFIX = "plan: ";
|
|
2437
|
-
var GATE_OPENING_MARK = " checks at once";
|
|
2438
|
-
function is_gate_opening(line) {
|
|
2439
|
-
const trimmed = line.trimStart();
|
|
2440
|
-
return trimmed.startsWith(GATE_OPENING_PREFIX) && trimmed.includes(GATE_OPENING_MARK);
|
|
2441
|
-
}
|
|
2442
|
-
function read_verdict(line) {
|
|
2443
|
-
const trimmed = line.trimStart();
|
|
2444
|
-
if (trimmed.startsWith(GATE_FAILED_PREFIX)) return FAILED_VERDICT;
|
|
2445
|
-
if (trimmed.startsWith(GATE_PASSED_PREFIX)) return PASSED_VERDICT;
|
|
2446
|
-
return void 0;
|
|
2447
|
-
}
|
|
2448
|
-
var josh_verdict = {
|
|
2449
|
-
PASSED_VERDICT,
|
|
2450
|
-
FAILED_VERDICT,
|
|
2451
|
-
format_gate_passed,
|
|
2452
|
-
format_gate_failed,
|
|
2453
|
-
GATE_OPENING_MARK,
|
|
2454
|
-
GATE_OPENING_PREFIX,
|
|
2455
|
-
is_gate_opening,
|
|
2456
|
-
read_verdict
|
|
2457
|
-
};
|
|
2458
|
-
|
|
2459
|
-
// scripts/time-runtime/time-reported-failure.ts
|
|
2460
|
-
import { z as z3 } from "zod";
|
|
2461
|
-
var TEXT_BLOCK_SCHEMA = z3.object({ text: z3.string().nullish() });
|
|
2462
|
-
var CONTENT_SCHEMA = z3.union([z3.string(), z3.array(z3.unknown())]);
|
|
2463
|
-
var LINE_SEPARATOR2 = "\n";
|
|
2464
|
-
function block_text(block) {
|
|
2465
|
-
const parsed = TEXT_BLOCK_SCHEMA.safeParse(block);
|
|
2466
|
-
return parsed.success ? parsed.data.text ?? "" : "";
|
|
2467
|
-
}
|
|
2468
|
-
function result_text2(content) {
|
|
2469
|
-
const parsed = CONTENT_SCHEMA.safeParse(content);
|
|
2470
|
-
if (!parsed.success) return "";
|
|
2471
|
-
if (typeof parsed.data === "string") return parsed.data;
|
|
2472
|
-
return parsed.data.map((block) => block_text(block)).join(LINE_SEPARATOR2);
|
|
2473
|
-
}
|
|
2474
|
-
function is_failure_line(line) {
|
|
2475
|
-
return line.trimStart().startsWith(status_icons.FAIL_ICON);
|
|
2476
|
-
}
|
|
2477
|
-
function is_failed_verdict(line) {
|
|
2478
|
-
return josh_verdict.read_verdict(line) === josh_verdict.FAILED_VERDICT;
|
|
2479
|
-
}
|
|
2480
|
-
function is_passed_verdict(line) {
|
|
2481
|
-
return josh_verdict.read_verdict(line) === josh_verdict.PASSED_VERDICT;
|
|
2482
|
-
}
|
|
2483
|
-
function new_scan() {
|
|
2484
|
-
return {
|
|
2485
|
-
did_find: false,
|
|
2486
|
-
has_failure_before_region: false,
|
|
2487
|
-
has_failure_in_region: false,
|
|
2488
|
-
is_region_open: false
|
|
2489
|
-
};
|
|
2490
|
-
}
|
|
2491
|
-
function close_region(scan) {
|
|
2492
|
-
scan.did_find ||= scan.is_region_open && scan.has_failure_before_region;
|
|
2493
|
-
scan.has_failure_before_region = false;
|
|
2494
|
-
scan.has_failure_in_region = false;
|
|
2495
|
-
scan.is_region_open = false;
|
|
2496
|
-
}
|
|
2497
|
-
function note_failure(scan) {
|
|
2498
|
-
if (scan.is_region_open) {
|
|
2499
|
-
scan.has_failure_in_region = true;
|
|
2500
|
-
return;
|
|
2501
|
-
}
|
|
2502
|
-
scan.has_failure_before_region = true;
|
|
2503
|
-
}
|
|
2504
|
-
function scan_line(scan, line) {
|
|
2505
|
-
if (is_passed_verdict(line)) {
|
|
2506
|
-
close_region(scan);
|
|
2507
|
-
return;
|
|
2508
|
-
}
|
|
2509
|
-
if (is_failure_line(line)) {
|
|
2510
|
-
note_failure(scan);
|
|
2511
|
-
return;
|
|
2512
|
-
}
|
|
2513
|
-
if (josh_verdict.is_gate_opening(line)) scan.is_region_open = true;
|
|
2514
|
-
}
|
|
2515
|
-
function scan_body(lines) {
|
|
2516
|
-
const scan = new_scan();
|
|
2517
|
-
for (const line of lines) scan_line(scan, line);
|
|
2518
|
-
return scan;
|
|
2519
|
-
}
|
|
2520
|
-
function did_scan_find(scan) {
|
|
2521
|
-
return scan.did_find || scan.has_failure_before_region || scan.has_failure_in_region;
|
|
2522
|
-
}
|
|
2523
|
-
function has_failure_line(content) {
|
|
2524
|
-
const lines = result_text2(content).split(LINE_SEPARATOR2);
|
|
2525
|
-
if (lines.some((line) => is_failed_verdict(line))) return true;
|
|
2526
|
-
return did_scan_find(scan_body(lines));
|
|
2527
|
-
}
|
|
2528
|
-
function is_reported_failure(josh_command, did_print_failure) {
|
|
2529
|
-
return josh_command !== "" && did_print_failure;
|
|
2530
|
-
}
|
|
2531
|
-
var time_reported_failure = { result_text: result_text2, has_failure_line, is_reported_failure };
|
|
2532
|
-
|
|
2533
3357
|
// scripts/time-runtime/time-single-check.ts
|
|
2534
3358
|
var CHECK_COMMANDS = /* @__PURE__ */ new Set([
|
|
2535
3359
|
"josh check",
|
|
@@ -2554,47 +3378,48 @@ function check_key(josh_command, command) {
|
|
|
2554
3378
|
var time_single_check = { NO_CHECK, check_key };
|
|
2555
3379
|
|
|
2556
3380
|
// scripts/time-runtime/time-transcript-line.ts
|
|
2557
|
-
import { z as
|
|
3381
|
+
import { z as z6 } from "zod";
|
|
2558
3382
|
|
|
2559
3383
|
// scripts/time-runtime/time-instant.ts
|
|
2560
3384
|
function parse_instant(raw) {
|
|
2561
|
-
|
|
3385
|
+
if (raw === null || raw === void 0) return void 0;
|
|
3386
|
+
const parsed = Date.parse(raw);
|
|
2562
3387
|
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
2563
3388
|
}
|
|
2564
3389
|
var time_instant = { parse_instant };
|
|
2565
3390
|
|
|
2566
3391
|
// scripts/time-runtime/time-transcript-line.ts
|
|
2567
|
-
var BLOCK_SCHEMA2 =
|
|
2568
|
-
type:
|
|
2569
|
-
name:
|
|
2570
|
-
id:
|
|
2571
|
-
tool_use_id:
|
|
2572
|
-
input:
|
|
3392
|
+
var BLOCK_SCHEMA2 = z6.object({
|
|
3393
|
+
type: z6.string().nullish(),
|
|
3394
|
+
name: z6.string().nullish(),
|
|
3395
|
+
id: z6.string().nullish(),
|
|
3396
|
+
tool_use_id: z6.string().nullish(),
|
|
3397
|
+
input: z6.unknown().nullish(),
|
|
2573
3398
|
// Whether the harness wrote this result back as a failure (joshuafolkken/kit#1309). Present on a
|
|
2574
3399
|
// `tool_result` block and on nothing else, and absent even there for the tools that never report
|
|
2575
3400
|
// one — which is why it is read as three answers rather than as a boolean with a default.
|
|
2576
|
-
is_error:
|
|
3401
|
+
is_error: z6.boolean().nullish(),
|
|
2577
3402
|
// What the call printed. Read only to recover the outcome a pipeline threw away
|
|
2578
3403
|
// (joshuafolkken/kit#1361): it is kept as flattened text rather than as blocks, because that is
|
|
2579
3404
|
// the whole of what `time-reported-failure.ts` asks of it.
|
|
2580
|
-
content:
|
|
3405
|
+
content: z6.unknown().nullish()
|
|
2581
3406
|
});
|
|
2582
|
-
var CONTENT_SCHEMA2 =
|
|
2583
|
-
var MESSAGE_SCHEMA2 =
|
|
2584
|
-
var LINE_SCHEMA =
|
|
2585
|
-
type:
|
|
2586
|
-
timestamp:
|
|
3407
|
+
var CONTENT_SCHEMA2 = z6.union([z6.string(), z6.array(BLOCK_SCHEMA2)]);
|
|
3408
|
+
var MESSAGE_SCHEMA2 = z6.object({ id: z6.string().nullish(), content: CONTENT_SCHEMA2.nullish() });
|
|
3409
|
+
var LINE_SCHEMA = z6.object({
|
|
3410
|
+
type: z6.string().nullish(),
|
|
3411
|
+
timestamp: z6.string().nullish(),
|
|
2587
3412
|
// The branch the line was written on, which is where the issue number lives — `josh git` names a
|
|
2588
3413
|
// branch `<N>-<slug>`. Read here rather than re-parsed by a second reader so `josh time --issue`
|
|
2589
3414
|
// and `josh cost --issue` answer from the same field (joshuafolkken/kit#1268).
|
|
2590
|
-
gitBranch:
|
|
3415
|
+
gitBranch: z6.string().nullish(),
|
|
2591
3416
|
// The two fields outside `message` that the harness writes an end-of-task notice on
|
|
2592
3417
|
// (joshuafolkken/kit#1696). **Both are read as `unknown` rather than as strings**: a schema
|
|
2593
3418
|
// insisting on a string here would reject every line whose `content` is a list of blocks — which is
|
|
2594
3419
|
// most of them — and a rejected line is dropped from the timeline entirely, so the shares would stop
|
|
2595
3420
|
// reconstructing the elapsed time. The shape is checked at the read below instead.
|
|
2596
|
-
content:
|
|
2597
|
-
attachment:
|
|
3421
|
+
content: z6.unknown().nullish(),
|
|
3422
|
+
attachment: z6.unknown().nullish(),
|
|
2598
3423
|
message: MESSAGE_SCHEMA2.nullish()
|
|
2599
3424
|
});
|
|
2600
3425
|
var UNKNOWN_BRANCH = "";
|
|
@@ -2687,24 +3512,9 @@ var time_writes = {
|
|
|
2687
3512
|
tool_writes
|
|
2688
3513
|
};
|
|
2689
3514
|
|
|
2690
|
-
// scripts/time-runtime/time-
|
|
2691
|
-
var { NO_MESSAGE_ID: NO_MESSAGE_ID2
|
|
2692
|
-
var ASSISTANT_TYPE = "assistant";
|
|
2693
|
-
var USER_TYPE = "user";
|
|
3515
|
+
// scripts/time-runtime/time-tool-call.ts
|
|
3516
|
+
var { NO_MESSAGE_ID: NO_MESSAGE_ID2 } = time_transcript_line;
|
|
2694
3517
|
var UNKNOWN_TOOL = "unknown";
|
|
2695
|
-
var MODEL_CATEGORY = "model";
|
|
2696
|
-
var TOOL_CATEGORY = "tool";
|
|
2697
|
-
var HUMAN_CATEGORY = "human";
|
|
2698
|
-
var OK_OUTCOME = "ok";
|
|
2699
|
-
var FAILED_OUTCOME = "failed";
|
|
2700
|
-
var UNKNOWN_OUTCOME = "unknown";
|
|
2701
|
-
var NO_RESULT = {
|
|
2702
|
-
call_id: "",
|
|
2703
|
-
outcome: UNKNOWN_OUTCOME,
|
|
2704
|
-
refusal_guard: "",
|
|
2705
|
-
background_id: time_background.NO_BACKGROUND,
|
|
2706
|
-
followup_stages: time_followup_stage.NO_STAGES
|
|
2707
|
-
};
|
|
2708
3518
|
var NO_CALL = {
|
|
2709
3519
|
label: "",
|
|
2710
3520
|
josh_command: "",
|
|
@@ -2766,6 +3576,31 @@ function to_tool_call(name, input, message_id) {
|
|
|
2766
3576
|
if (name !== cost_blocks.BASH_TOOL) return non_bash_call(name, input, message_id);
|
|
2767
3577
|
return bash_call(input, message_id);
|
|
2768
3578
|
}
|
|
3579
|
+
var time_tool_call = {
|
|
3580
|
+
UNKNOWN_TOOL,
|
|
3581
|
+
NO_CALL,
|
|
3582
|
+
UNKNOWN_CALL,
|
|
3583
|
+
to_tool_call
|
|
3584
|
+
};
|
|
3585
|
+
|
|
3586
|
+
// scripts/time-runtime/time-spans.ts
|
|
3587
|
+
var { NO_MESSAGE_ID: NO_MESSAGE_ID3, parse_line: parse_line3 } = time_transcript_line;
|
|
3588
|
+
var { NO_CALL: NO_CALL2, UNKNOWN_CALL: UNKNOWN_CALL2, UNKNOWN_TOOL: UNKNOWN_TOOL2, to_tool_call: to_tool_call2 } = time_tool_call;
|
|
3589
|
+
var ASSISTANT_TYPE = "assistant";
|
|
3590
|
+
var USER_TYPE = "user";
|
|
3591
|
+
var MODEL_CATEGORY = "model";
|
|
3592
|
+
var TOOL_CATEGORY = "tool";
|
|
3593
|
+
var HUMAN_CATEGORY = "human";
|
|
3594
|
+
var OK_OUTCOME = "ok";
|
|
3595
|
+
var FAILED_OUTCOME = "failed";
|
|
3596
|
+
var UNKNOWN_OUTCOME = "unknown";
|
|
3597
|
+
var NO_RESULT = {
|
|
3598
|
+
call_id: "",
|
|
3599
|
+
outcome: UNKNOWN_OUTCOME,
|
|
3600
|
+
refusal_guard: "",
|
|
3601
|
+
background_id: time_background.NO_BACKGROUND,
|
|
3602
|
+
followup_stages: time_followup_stage.NO_STAGES
|
|
3603
|
+
};
|
|
2769
3604
|
function tool_use_blocks(lines) {
|
|
2770
3605
|
return lines.flatMap(
|
|
2771
3606
|
(line) => line.blocks.filter((block) => block.type === cost_blocks.TOOL_USE_TYPE && block.id !== "").map((block) => ({ block, message_id: line.message_id }))
|
|
@@ -2775,7 +3610,7 @@ function collect_calls(lines) {
|
|
|
2775
3610
|
return new Map(
|
|
2776
3611
|
tool_use_blocks(lines).map(({ block, message_id }) => [
|
|
2777
3612
|
block.id,
|
|
2778
|
-
|
|
3613
|
+
to_tool_call2(block.name, block.input, message_id)
|
|
2779
3614
|
])
|
|
2780
3615
|
);
|
|
2781
3616
|
}
|
|
@@ -2803,13 +3638,13 @@ function facts_of(result, call) {
|
|
|
2803
3638
|
}
|
|
2804
3639
|
function user_event(line, calls) {
|
|
2805
3640
|
const result = result_block(line);
|
|
2806
|
-
if (result === void 0) return event_of(line, HUMAN_CATEGORY,
|
|
2807
|
-
const call = calls.get(result.result_id) ??
|
|
3641
|
+
if (result === void 0) return event_of(line, HUMAN_CATEGORY, NO_CALL2);
|
|
3642
|
+
const call = calls.get(result.result_id) ?? UNKNOWN_CALL2;
|
|
2808
3643
|
return event_of(line, TOOL_CATEGORY, call, facts_of(result, call));
|
|
2809
3644
|
}
|
|
2810
3645
|
function to_event(line, calls) {
|
|
2811
3646
|
if (line.type === ASSISTANT_TYPE) {
|
|
2812
|
-
return event_of(line, MODEL_CATEGORY, { ...
|
|
3647
|
+
return event_of(line, MODEL_CATEGORY, { ...NO_CALL2, message_id: line.message_id });
|
|
2813
3648
|
}
|
|
2814
3649
|
return line.type === USER_TYPE ? user_event(line, calls) : void 0;
|
|
2815
3650
|
}
|
|
@@ -2891,8 +3726,8 @@ var time_spans = {
|
|
|
2891
3726
|
OK_OUTCOME,
|
|
2892
3727
|
FAILED_OUTCOME,
|
|
2893
3728
|
UNKNOWN_OUTCOME,
|
|
2894
|
-
NO_MESSAGE_ID:
|
|
2895
|
-
UNKNOWN_TOOL,
|
|
3729
|
+
NO_MESSAGE_ID: NO_MESSAGE_ID3,
|
|
3730
|
+
UNKNOWN_TOOL: UNKNOWN_TOOL2,
|
|
2896
3731
|
has_transcript_data,
|
|
2897
3732
|
equal_durations,
|
|
2898
3733
|
no_background,
|
|
@@ -2901,7 +3736,7 @@ var time_spans = {
|
|
|
2901
3736
|
bash_label: time_shell.bash_label,
|
|
2902
3737
|
josh_command_of: time_shell.josh_command_of,
|
|
2903
3738
|
josh_commands_of: time_shell.josh_commands_of,
|
|
2904
|
-
to_tool_call,
|
|
3739
|
+
to_tool_call: to_tool_call2,
|
|
2905
3740
|
parse_line: parse_line3,
|
|
2906
3741
|
parse_timeline
|
|
2907
3742
|
};
|
|
@@ -3370,7 +4205,7 @@ function describe_span(span) {
|
|
|
3370
4205
|
}
|
|
3371
4206
|
var FOLD_MINIMUM = 2;
|
|
3372
4207
|
function read_targets(sequence) {
|
|
3373
|
-
const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((
|
|
4208
|
+
const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((path7) => path7 !== "" && time_bundle_call.has_extension(path7));
|
|
3374
4209
|
return [...new Set(paths)];
|
|
3375
4210
|
}
|
|
3376
4211
|
function read_fold_directive(sequence) {
|
|
@@ -3379,7 +4214,7 @@ function read_fold_directive(sequence) {
|
|
|
3379
4214
|
return ` Fold them into one call: \`pnpm josh read:files ${paths.join(" ")}\`.`;
|
|
3380
4215
|
}
|
|
3381
4216
|
function write_targets(sequence) {
|
|
3382
|
-
const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((
|
|
4217
|
+
const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((path7) => path7 !== "" && time_bundle_call.has_extension(path7));
|
|
3383
4218
|
return [...new Set(paths)];
|
|
3384
4219
|
}
|
|
3385
4220
|
function write_fold_directive(sequence) {
|
|
@@ -3431,49 +4266,55 @@ var time_batch_guard = {
|
|
|
3431
4266
|
};
|
|
3432
4267
|
|
|
3433
4268
|
// scripts/time-runtime/time-hook-transcript.ts
|
|
3434
|
-
import
|
|
4269
|
+
import path6 from "node:path";
|
|
3435
4270
|
|
|
3436
4271
|
// scripts/cost-runtime/cost-transcript.ts
|
|
3437
|
-
import { readdirSync, readFileSync as
|
|
4272
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync3, statSync } from "node:fs";
|
|
3438
4273
|
import { homedir } from "node:os";
|
|
3439
|
-
import
|
|
4274
|
+
import path5 from "node:path";
|
|
3440
4275
|
|
|
3441
4276
|
// scripts/lane/lane-paths.ts
|
|
3442
|
-
import
|
|
4277
|
+
import path4 from "node:path";
|
|
3443
4278
|
var LANE_ROOT_KEY = "JOSH_LANE_ROOT";
|
|
3444
4279
|
var LANE_DIRECTORY_SUFFIX = "-lanes";
|
|
3445
4280
|
var LANE_BRANCH_SUFFIX = "-lane";
|
|
3446
4281
|
function default_lane_root(repository_root) {
|
|
3447
|
-
const name =
|
|
3448
|
-
return
|
|
4282
|
+
const name = path4.basename(repository_root);
|
|
4283
|
+
return path4.join(path4.dirname(repository_root), `.${name}${LANE_DIRECTORY_SUFFIX}`);
|
|
3449
4284
|
}
|
|
3450
4285
|
function lane_root(repository_root, environment = process.env) {
|
|
3451
4286
|
const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
|
|
3452
|
-
return configured.length === 0 ? default_lane_root(repository_root) :
|
|
4287
|
+
return configured.length === 0 ? default_lane_root(repository_root) : path4.resolve(configured);
|
|
3453
4288
|
}
|
|
3454
4289
|
function lane_directory(root, issue) {
|
|
3455
|
-
return
|
|
4290
|
+
return path4.join(root, issue);
|
|
3456
4291
|
}
|
|
3457
4292
|
var LANE_ISSUE_PATTERN = /^\d+$/u;
|
|
3458
4293
|
var DEFAULT_LANE_ROOT_PATTERN = new RegExp(String.raw`^\..+${LANE_DIRECTORY_SUFFIX}$`, "u");
|
|
3459
4294
|
function is_lane_root(directory, environment) {
|
|
3460
4295
|
const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
|
|
3461
|
-
if (configured.length > 0) return
|
|
3462
|
-
return DEFAULT_LANE_ROOT_PATTERN.test(
|
|
4296
|
+
if (configured.length > 0) return path4.resolve(configured) === directory;
|
|
4297
|
+
return DEFAULT_LANE_ROOT_PATTERN.test(path4.basename(directory));
|
|
3463
4298
|
}
|
|
3464
4299
|
function lane_issue_of(directory, environment = process.env) {
|
|
3465
|
-
const resolved =
|
|
3466
|
-
const issue =
|
|
4300
|
+
const resolved = path4.resolve(directory);
|
|
4301
|
+
const issue = path4.basename(resolved);
|
|
3467
4302
|
if (!LANE_ISSUE_PATTERN.test(issue)) return void 0;
|
|
3468
|
-
return is_lane_root(
|
|
4303
|
+
return is_lane_root(path4.dirname(resolved), environment) ? issue : void 0;
|
|
3469
4304
|
}
|
|
3470
4305
|
function lane_branch(issue) {
|
|
3471
4306
|
return `${issue}${LANE_BRANCH_SUFFIX}`;
|
|
3472
4307
|
}
|
|
4308
|
+
var SEAT_LOCK_DIR = ".seat-locks";
|
|
4309
|
+
function is_lane_entry(name) {
|
|
4310
|
+
return LANE_ISSUE_PATTERN.test(name) || DEFAULT_LANE_ROOT_PATTERN.test(name);
|
|
4311
|
+
}
|
|
3473
4312
|
var lane_paths = {
|
|
3474
4313
|
LANE_BRANCH_SUFFIX,
|
|
3475
4314
|
LANE_ROOT_KEY,
|
|
4315
|
+
SEAT_LOCK_DIR,
|
|
3476
4316
|
default_lane_root,
|
|
4317
|
+
is_lane_entry,
|
|
3477
4318
|
lane_branch,
|
|
3478
4319
|
lane_directory,
|
|
3479
4320
|
lane_issue_of,
|
|
@@ -3481,25 +4322,25 @@ var lane_paths = {
|
|
|
3481
4322
|
};
|
|
3482
4323
|
|
|
3483
4324
|
// scripts/lib/read-file.ts
|
|
3484
|
-
import { readFileSync } from "node:fs";
|
|
4325
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
3485
4326
|
var ABSENT_CODE = "ENOENT";
|
|
3486
4327
|
function is_absent(error) {
|
|
3487
4328
|
return error instanceof Error && "code" in error && error.code === ABSENT_CODE;
|
|
3488
4329
|
}
|
|
3489
|
-
function read_optional(
|
|
4330
|
+
function read_optional(path7) {
|
|
3490
4331
|
try {
|
|
3491
|
-
return
|
|
4332
|
+
return readFileSync2(path7, "utf8");
|
|
3492
4333
|
} catch (error) {
|
|
3493
4334
|
if (is_absent(error)) return void 0;
|
|
3494
4335
|
throw error;
|
|
3495
4336
|
}
|
|
3496
4337
|
}
|
|
3497
|
-
function read_file_or_empty(
|
|
3498
|
-
return read_optional(
|
|
4338
|
+
function read_file_or_empty(path7) {
|
|
4339
|
+
return read_optional(path7) ?? "";
|
|
3499
4340
|
}
|
|
3500
|
-
function read_if_readable(
|
|
4341
|
+
function read_if_readable(path7) {
|
|
3501
4342
|
try {
|
|
3502
|
-
return
|
|
4343
|
+
return readFileSync2(path7, "utf8");
|
|
3503
4344
|
} catch {
|
|
3504
4345
|
return void 0;
|
|
3505
4346
|
}
|
|
@@ -3507,30 +4348,30 @@ function read_if_readable(path6) {
|
|
|
3507
4348
|
var file_reader = { read_optional, read_file_or_empty, read_if_readable };
|
|
3508
4349
|
|
|
3509
4350
|
// scripts/cost-runtime/cost-usage.ts
|
|
3510
|
-
import { z as
|
|
3511
|
-
var CACHE_CREATION_SCHEMA =
|
|
3512
|
-
ephemeral_1h_input_tokens:
|
|
3513
|
-
ephemeral_5m_input_tokens:
|
|
4351
|
+
import { z as z7 } from "zod";
|
|
4352
|
+
var CACHE_CREATION_SCHEMA = z7.object({
|
|
4353
|
+
ephemeral_1h_input_tokens: z7.number().nullish(),
|
|
4354
|
+
ephemeral_5m_input_tokens: z7.number().nullish()
|
|
3514
4355
|
});
|
|
3515
|
-
var USAGE_SCHEMA =
|
|
3516
|
-
input_tokens:
|
|
3517
|
-
cache_creation_input_tokens:
|
|
3518
|
-
cache_read_input_tokens:
|
|
3519
|
-
output_tokens:
|
|
3520
|
-
output_tokens_details:
|
|
4356
|
+
var USAGE_SCHEMA = z7.object({
|
|
4357
|
+
input_tokens: z7.number(),
|
|
4358
|
+
cache_creation_input_tokens: z7.number().nullish(),
|
|
4359
|
+
cache_read_input_tokens: z7.number().nullish(),
|
|
4360
|
+
output_tokens: z7.number(),
|
|
4361
|
+
output_tokens_details: z7.object({ thinking_tokens: z7.number().nullish() }).nullish(),
|
|
3521
4362
|
cache_creation: CACHE_CREATION_SCHEMA.nullish()
|
|
3522
4363
|
});
|
|
3523
|
-
var MESSAGE_SCHEMA3 =
|
|
3524
|
-
id:
|
|
3525
|
-
model:
|
|
4364
|
+
var MESSAGE_SCHEMA3 = z7.object({
|
|
4365
|
+
id: z7.string().nullish(),
|
|
4366
|
+
model: z7.string().nullish(),
|
|
3526
4367
|
usage: USAGE_SCHEMA.nullish()
|
|
3527
4368
|
});
|
|
3528
|
-
var LINE_SCHEMA2 =
|
|
3529
|
-
type:
|
|
3530
|
-
requestId:
|
|
3531
|
-
uuid:
|
|
3532
|
-
gitBranch:
|
|
3533
|
-
timestamp:
|
|
4369
|
+
var LINE_SCHEMA2 = z7.object({
|
|
4370
|
+
type: z7.string(),
|
|
4371
|
+
requestId: z7.string().nullish(),
|
|
4372
|
+
uuid: z7.string().nullish(),
|
|
4373
|
+
gitBranch: z7.string().nullish(),
|
|
4374
|
+
timestamp: z7.string().nullish(),
|
|
3534
4375
|
message: MESSAGE_SCHEMA3.nullish()
|
|
3535
4376
|
});
|
|
3536
4377
|
var SYNTHETIC_MODEL = "<synthetic>";
|
|
@@ -3644,7 +4485,7 @@ var cost_usage = {
|
|
|
3644
4485
|
};
|
|
3645
4486
|
|
|
3646
4487
|
// scripts/cost-runtime/cost-transcript.ts
|
|
3647
|
-
var TRANSCRIPT_ROOT =
|
|
4488
|
+
var TRANSCRIPT_ROOT = path5.join(".claude", "projects");
|
|
3648
4489
|
var TRANSCRIPT_EXTENSION = ".jsonl";
|
|
3649
4490
|
var SLUG_PATTERN = /[^a-zA-Z0-9-]/gu;
|
|
3650
4491
|
var UNIT_DIRECTORY = "subagents";
|
|
@@ -3653,7 +4494,7 @@ function project_slug(cwd) {
|
|
|
3653
4494
|
return cwd.replaceAll(SLUG_PATTERN, "-");
|
|
3654
4495
|
}
|
|
3655
4496
|
function transcript_directory(cwd, home = homedir()) {
|
|
3656
|
-
return
|
|
4497
|
+
return path5.join(home, TRANSCRIPT_ROOT, project_slug(cwd));
|
|
3657
4498
|
}
|
|
3658
4499
|
var GIT_ENTRY = ".git";
|
|
3659
4500
|
var GITDIR_PREFIX = "gitdir:";
|
|
@@ -3661,7 +4502,7 @@ var WORKTREE_SEGMENT = `/${GIT_ENTRY}/worktrees/`;
|
|
|
3661
4502
|
var NOT_FOUND = -1;
|
|
3662
4503
|
function linked_worktree_gitdir(cwd) {
|
|
3663
4504
|
try {
|
|
3664
|
-
const contents =
|
|
4505
|
+
const contents = readFileSync3(path5.join(cwd, GIT_ENTRY), "utf8").trim();
|
|
3665
4506
|
return contents.startsWith(GITDIR_PREFIX) ? contents.slice(GITDIR_PREFIX.length).trim() : "";
|
|
3666
4507
|
} catch {
|
|
3667
4508
|
return "";
|
|
@@ -3669,22 +4510,22 @@ function linked_worktree_gitdir(cwd) {
|
|
|
3669
4510
|
}
|
|
3670
4511
|
function session_cwd(cwd) {
|
|
3671
4512
|
const gitdir = linked_worktree_gitdir(cwd);
|
|
3672
|
-
const absolute = gitdir === "" ? "" :
|
|
4513
|
+
const absolute = gitdir === "" ? "" : path5.resolve(cwd, gitdir);
|
|
3673
4514
|
const segment = absolute.indexOf(WORKTREE_SEGMENT);
|
|
3674
4515
|
return segment === NOT_FOUND ? cwd : absolute.slice(0, segment);
|
|
3675
4516
|
}
|
|
3676
4517
|
function read_directory(directory) {
|
|
3677
4518
|
try {
|
|
3678
|
-
return
|
|
4519
|
+
return readdirSync3(directory);
|
|
3679
4520
|
} catch {
|
|
3680
4521
|
return [];
|
|
3681
4522
|
}
|
|
3682
4523
|
}
|
|
3683
4524
|
var LANE_ISSUE_SLUG = /^\d+$/u;
|
|
3684
4525
|
function lane_transcript_directories(main_cwd, home) {
|
|
3685
|
-
const projects =
|
|
4526
|
+
const projects = path5.join(home, TRANSCRIPT_ROOT);
|
|
3686
4527
|
const prefix = `${project_slug(lane_paths.lane_root(main_cwd))}-`;
|
|
3687
|
-
return read_directory(projects).filter((name) => name.startsWith(prefix) && LANE_ISSUE_SLUG.test(name.slice(prefix.length))).map((name) =>
|
|
4528
|
+
return read_directory(projects).filter((name) => name.startsWith(prefix) && LANE_ISSUE_SLUG.test(name.slice(prefix.length))).map((name) => path5.join(projects, name));
|
|
3688
4529
|
}
|
|
3689
4530
|
function transcript_directories(cwd, home = homedir()) {
|
|
3690
4531
|
const own = transcript_directory(cwd, home);
|
|
@@ -3715,16 +4556,16 @@ function without_extension(name) {
|
|
|
3715
4556
|
return name.slice(0, -TRANSCRIPT_EXTENSION.length);
|
|
3716
4557
|
}
|
|
3717
4558
|
function own_files(directory, names) {
|
|
3718
|
-
return names.filter((name) => is_transcript(name)).map((name) => to_session_file(
|
|
4559
|
+
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);
|
|
3719
4560
|
}
|
|
3720
4561
|
function unit_directory(directory, session_id) {
|
|
3721
|
-
return
|
|
4562
|
+
return path5.join(directory, session_id, UNIT_DIRECTORY);
|
|
3722
4563
|
}
|
|
3723
4564
|
var UNIT_DEPTH = 1;
|
|
3724
4565
|
function level_units(subagents_directory, prefix, depth) {
|
|
3725
4566
|
return read_directory(subagents_directory).filter((name) => is_transcript(name)).map(
|
|
3726
4567
|
(name) => to_session_file(
|
|
3727
|
-
|
|
4568
|
+
path5.join(subagents_directory, name),
|
|
3728
4569
|
`${prefix}${UNIT_ID_SEPARATOR}${without_extension(name)}`,
|
|
3729
4570
|
depth
|
|
3730
4571
|
)
|
|
@@ -3866,10 +4707,10 @@ function is_agent_id(value) {
|
|
|
3866
4707
|
return typeof value === "string" && AGENT_ID_PATTERN.test(value);
|
|
3867
4708
|
}
|
|
3868
4709
|
function fork_path(transcript_path, agent_id) {
|
|
3869
|
-
const directory =
|
|
3870
|
-
const session_id =
|
|
4710
|
+
const directory = path6.dirname(transcript_path);
|
|
4711
|
+
const session_id = path6.basename(transcript_path, TRANSCRIPT_EXTENSION2);
|
|
3871
4712
|
const file_name = `${AGENT_PREFIX}${agent_id}${TRANSCRIPT_EXTENSION2}`;
|
|
3872
|
-
return
|
|
4713
|
+
return path6.join(cost_transcript.unit_directory(directory, session_id), file_name);
|
|
3873
4714
|
}
|
|
3874
4715
|
function transcript_of(transcript_path, agent_id) {
|
|
3875
4716
|
if (!is_agent_id(agent_id)) return transcript_path;
|
|
@@ -3883,127 +4724,7 @@ var time_hook_transcript = {
|
|
|
3883
4724
|
|
|
3884
4725
|
// scripts/time-runtime/time-density-hook.ts
|
|
3885
4726
|
import { closeSync, fstatSync, openSync, readSync } from "node:fs";
|
|
3886
|
-
|
|
3887
|
-
// scripts/josh/stamp-file.ts
|
|
3888
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
3889
|
-
import { lstatSync, readFileSync as readFileSync3, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
3890
|
-
import path5 from "node:path";
|
|
3891
|
-
|
|
3892
|
-
// scripts/init/init-paths.ts
|
|
3893
|
-
import path4 from "node:path";
|
|
3894
|
-
import { fileURLToPath } from "node:url";
|
|
3895
|
-
var PACKAGE_DIR = path4.join(path4.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
3896
|
-
var PROJECT_ROOT = process.cwd();
|
|
3897
|
-
|
|
3898
|
-
// scripts/josh/platform-temporary.ts
|
|
3899
|
-
import { accessSync, constants } from "node:fs";
|
|
3900
|
-
import { tmpdir } from "node:os";
|
|
3901
|
-
var POSIX_TEMP_ROOT = "/tmp";
|
|
3902
|
-
var WINDOWS_PLATFORM = "win32";
|
|
3903
|
-
function is_writable_directory(directory) {
|
|
3904
|
-
try {
|
|
3905
|
-
accessSync(directory, constants.W_OK);
|
|
3906
|
-
return true;
|
|
3907
|
-
} catch {
|
|
3908
|
-
return false;
|
|
3909
|
-
}
|
|
3910
|
-
}
|
|
3911
|
-
function resolve_temporary_root(platform, can_write = is_writable_directory) {
|
|
3912
|
-
if (platform === WINDOWS_PLATFORM) return tmpdir();
|
|
3913
|
-
return can_write(POSIX_TEMP_ROOT) ? POSIX_TEMP_ROOT : tmpdir();
|
|
3914
|
-
}
|
|
3915
|
-
var TEMP_ROOT_KEY = "JOSH_TEMP_ROOT";
|
|
3916
|
-
function temporary_root(override, platform) {
|
|
3917
|
-
return override === void 0 || override === "" ? resolve_temporary_root(platform) : override;
|
|
3918
|
-
}
|
|
3919
|
-
var PLATFORM_TEMP_ROOT = temporary_root(process.env[TEMP_ROOT_KEY], process.platform);
|
|
3920
|
-
|
|
3921
|
-
// scripts/josh/stamp-file.ts
|
|
3922
|
-
var HASH_ALGORITHM = "sha256";
|
|
3923
|
-
var STAMP_SUFFIX = ".json";
|
|
3924
|
-
var STAMP_KEY_LENGTH = 16;
|
|
3925
|
-
var STAMP_FILE_MODE = 384;
|
|
3926
|
-
var STAMP_WRITE_FLAG = "wx";
|
|
3927
|
-
var STAMP_CREATE_FLAG = STAMP_WRITE_FLAG;
|
|
3928
|
-
var EXISTS_ERROR_CODE = "EEXIST";
|
|
3929
|
-
var ACCOUNT_KEY_SEPARATOR = ":";
|
|
3930
|
-
function digest(content) {
|
|
3931
|
-
return createHash(HASH_ALGORITHM).update(content).digest("hex");
|
|
3932
|
-
}
|
|
3933
|
-
function account_key() {
|
|
3934
|
-
return String(process.getuid?.() ?? "");
|
|
3935
|
-
}
|
|
3936
|
-
function stamp_path(prefix, root = PACKAGE_DIR, suffix = STAMP_SUFFIX) {
|
|
3937
|
-
const key = digest(`${account_key()}${ACCOUNT_KEY_SEPARATOR}${root}`).slice(0, STAMP_KEY_LENGTH);
|
|
3938
|
-
return path5.join(PLATFORM_TEMP_ROOT, `${prefix}${key}${suffix}`);
|
|
3939
|
-
}
|
|
3940
|
-
function write_exclusively(target, content) {
|
|
3941
|
-
rmSync(target, { force: true });
|
|
3942
|
-
writeFileSync(target, content, { flag: STAMP_WRITE_FLAG, mode: STAMP_FILE_MODE });
|
|
3943
|
-
return target;
|
|
3944
|
-
}
|
|
3945
|
-
function write_stamp(target, payload) {
|
|
3946
|
-
return write_exclusively(target, JSON.stringify(payload));
|
|
3947
|
-
}
|
|
3948
|
-
function replace_stamp(target, payload) {
|
|
3949
|
-
const temporary = `${target}.${String(process.pid)}.${randomUUID()}`;
|
|
3950
|
-
try {
|
|
3951
|
-
writeFileSync(temporary, JSON.stringify(payload), {
|
|
3952
|
-
flag: STAMP_CREATE_FLAG,
|
|
3953
|
-
mode: STAMP_FILE_MODE
|
|
3954
|
-
});
|
|
3955
|
-
renameSync(temporary, target);
|
|
3956
|
-
return target;
|
|
3957
|
-
} finally {
|
|
3958
|
-
rmSync(temporary, { force: true });
|
|
3959
|
-
}
|
|
3960
|
-
}
|
|
3961
|
-
function write_text_stamp(target, text) {
|
|
3962
|
-
return write_exclusively(target, text);
|
|
3963
|
-
}
|
|
3964
|
-
function create_stamp(target, payload) {
|
|
3965
|
-
try {
|
|
3966
|
-
writeFileSync(target, JSON.stringify(payload), {
|
|
3967
|
-
flag: STAMP_CREATE_FLAG,
|
|
3968
|
-
mode: STAMP_FILE_MODE
|
|
3969
|
-
});
|
|
3970
|
-
return true;
|
|
3971
|
-
} catch (error) {
|
|
3972
|
-
if (error.code === EXISTS_ERROR_CODE) return false;
|
|
3973
|
-
throw error;
|
|
3974
|
-
}
|
|
3975
|
-
}
|
|
3976
|
-
function remove_stamp(target) {
|
|
3977
|
-
rmSync(target, { force: true });
|
|
3978
|
-
}
|
|
3979
|
-
function is_own_regular_file(source) {
|
|
3980
|
-
const stats = lstatSync(source);
|
|
3981
|
-
if (!stats.isFile()) return false;
|
|
3982
|
-
const uid = process.getuid?.();
|
|
3983
|
-
return uid === void 0 || stats.uid === uid;
|
|
3984
|
-
}
|
|
3985
|
-
function read_stamp_text(source) {
|
|
3986
|
-
try {
|
|
3987
|
-
if (!is_own_regular_file(source)) return void 0;
|
|
3988
|
-
return readFileSync3(source, "utf8");
|
|
3989
|
-
} catch {
|
|
3990
|
-
return void 0;
|
|
3991
|
-
}
|
|
3992
|
-
}
|
|
3993
|
-
var stamp_file = {
|
|
3994
|
-
create_stamp,
|
|
3995
|
-
digest,
|
|
3996
|
-
is_own_regular_file,
|
|
3997
|
-
read_stamp_text,
|
|
3998
|
-
replace_stamp,
|
|
3999
|
-
remove_stamp,
|
|
4000
|
-
stamp_path,
|
|
4001
|
-
write_stamp,
|
|
4002
|
-
write_text_stamp
|
|
4003
|
-
};
|
|
4004
|
-
|
|
4005
|
-
// scripts/time-runtime/time-density-hook.ts
|
|
4006
|
-
import { z as z6 } from "zod";
|
|
4727
|
+
import { z as z8 } from "zod";
|
|
4007
4728
|
|
|
4008
4729
|
// scripts/time-runtime/time-density.ts
|
|
4009
4730
|
var MIN_ROUND_TRIPS = 10;
|
|
@@ -4059,15 +4780,15 @@ var TAIL_BYTES = 262144;
|
|
|
4059
4780
|
var FILE_START = 0;
|
|
4060
4781
|
var NOTICE_PREFIX = "josh-density-notice-";
|
|
4061
4782
|
var NEVER_MS = 0;
|
|
4062
|
-
var payload_schema =
|
|
4063
|
-
transcript_path:
|
|
4783
|
+
var payload_schema = z8.object({
|
|
4784
|
+
transcript_path: z8.string().min(1).optional(),
|
|
4064
4785
|
// **`nullish`, not `optional`.** A payload spelling the absent agent as `null` has to read as "no
|
|
4065
4786
|
// fork"; rejected, it would fail `safeParse` for the whole payload and silence the line for every
|
|
4066
4787
|
// edit of the main line — the opposite of this module's stated failure direction.
|
|
4067
|
-
agent_id:
|
|
4788
|
+
agent_id: z8.string().nullish()
|
|
4068
4789
|
});
|
|
4069
|
-
var notice_schema =
|
|
4070
|
-
var call_schema =
|
|
4790
|
+
var notice_schema = z8.object({ notified_at_ms: z8.number() });
|
|
4791
|
+
var call_schema = z8.object({ tool_name: z8.string().min(1), tool_input: z8.unknown() });
|
|
4071
4792
|
function parse_transcript_path(raw_payload) {
|
|
4072
4793
|
const parsed = payload_schema.safeParse(JSON.parse(raw_payload));
|
|
4073
4794
|
if (!parsed.success || parsed.data.transcript_path === void 0) return void 0;
|
|
@@ -4134,12 +4855,11 @@ var time_density_hook = {
|
|
|
4134
4855
|
};
|
|
4135
4856
|
|
|
4136
4857
|
export {
|
|
4137
|
-
PROJECT_ROOT,
|
|
4138
|
-
PLATFORM_TEMP_ROOT,
|
|
4139
|
-
stamp_file,
|
|
4140
4858
|
json_value,
|
|
4141
4859
|
cost_blocks,
|
|
4142
4860
|
ESLINT_EDIT_CACHE_FLAGS,
|
|
4861
|
+
process_identity,
|
|
4862
|
+
process_owner_schema,
|
|
4143
4863
|
time_shell,
|
|
4144
4864
|
time_bundle_call,
|
|
4145
4865
|
blocking_issue_schema,
|
|
@@ -4156,8 +4876,8 @@ export {
|
|
|
4156
4876
|
evaluate_pr_state,
|
|
4157
4877
|
is_review_decision_decisive,
|
|
4158
4878
|
PrConflictError,
|
|
4159
|
-
cost_attribute,
|
|
4160
4879
|
time_reported_failure,
|
|
4880
|
+
cost_attribute,
|
|
4161
4881
|
time_transcript_line,
|
|
4162
4882
|
time_spans,
|
|
4163
4883
|
time_batch_guard,
|