@joshuafolkken/kit 1.1514.0 → 1.2114.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -1
- package/.claude/agents/reviewer-verification.md +19 -0
- package/.claude/agents/reviewer.md +19 -0
- package/.claude/settings.json +5 -6
- package/.claude/skills/dependency-update/SKILL.md +9 -10
- package/.claude/skills/epic-commands/SKILL.md +26 -65
- package/.claude/skills/epic-commands/epic-bundle.md +3 -1
- package/.claude/skills/workflow-commands/SKILL.md +11 -11
- package/.claude/skills/workflow-commands/background-commands.md +13 -10
- package/.claude/skills/workflow-commands/backlogrun-child.md +12 -8
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +18 -14
- package/.claude/skills/workflow-commands/backlogrun-park.md +18 -24
- package/.claude/skills/workflow-commands/backlogrun-progress.md +4 -5
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +6 -6
- package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -11
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +43 -28
- package/.claude/skills/workflow-commands/delegation.md +11 -10
- package/.claude/skills/workflow-commands/entry-sequence.md +10 -10
- package/.claude/skills/workflow-commands/followup.md +16 -36
- package/.claude/skills/workflow-commands/fullrun-steps.md +38 -47
- package/.claude/skills/workflow-commands/fullrun.md +3 -3
- package/.claude/skills/workflow-commands/halfrun.md +17 -25
- package/.claude/skills/workflow-commands/issue-comments.md +25 -16
- package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
- package/.claude/skills/workflow-commands/issue-scout.md +2 -2
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +7 -12
- package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
- package/.claude/skills/workflow-commands/observation-filing.md +4 -36
- package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
- package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -37
- package/.claude/skills/workflow-commands/prerequisite.md +11 -16
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +3 -7
- package/.claude/skills/workflow-commands/retrospective.md +2 -2
- package/.claude/skills/workflow-commands/split-assessment.md +15 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-node/action.yml +9 -0
- package/.github/actions/setup-pnpm/action.yml +10 -17
- package/.github/dependabot.yml +32 -0
- package/.github/release.yml +0 -2
- package/.github/workflows/auto-tag.yml +45 -0
- package/.github/workflows/ci.yml +267 -17
- package/.github/workflows/dependabot-auto-merge.yml +63 -4
- package/.github/workflows/production.yml +8 -0
- package/.github/workflows/publish.yml +67 -46
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/settings.json +19 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +7 -18
- package/README.md +4 -2
- package/SECURITY.md +3 -3
- package/dist/CLAUDE.md +7 -18
- package/dist/commands/document-read-cli.js +883 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +81 -38
- package/dist/commands/read-set-cli.js +1927 -0
- package/dist/commands/run-prep-main.js +21174 -0
- package/dist/commands/run-step-cli.js +27733 -0
- package/dist/config-merge/index.js +5 -1
- package/dist/hooks/audit-provision.js +39 -36
- package/dist/hooks/chunk-3GKE653K.js +6204 -0
- package/dist/hooks/chunk-45CJJOO7.js +1243 -0
- package/dist/hooks/chunk-5PM2JRGV.js +7780 -0
- package/dist/hooks/chunk-7SIUNQXK.js +3591 -0
- package/dist/hooks/chunk-CQD4LJE6.js +4858 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-OPSRGWFU.js} +1 -1
- package/dist/hooks/chunk-UJ3FPMMM.js +628 -0
- package/dist/hooks/chunk-VVNYJWEI.js +30 -0
- package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
- package/dist/hooks/codex-hook-adapter.js +10 -22
- package/dist/hooks/format-edited.js +4 -6
- package/dist/hooks/inputs.json +460 -308
- package/dist/hooks/pretool-guard.js +8 -25
- package/dist/hooks/session-lang.js +135 -299
- package/dist/hooks/stop-guard.js +6496 -1799
- package/dist/josh.js +7412 -4228
- package/dist/self-sync-guard/index.js +74 -10
- package/dist/version/index.js +276 -407
- package/eslint/base.js +1 -1
- package/eslint/rules/comment-why-only.js +108 -0
- package/lefthook/base.yml +3 -1
- package/package.json +23 -54
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +2 -2
- package/prompts/collaboration-workflow/file-edits.md +14 -17
- package/prompts/collaboration-workflow/issue-citation.md +0 -4
- package/prompts/collaboration-workflow/issue-template.md +54 -18
- package/prompts/collaboration-workflow/lane-instructions.md +3 -2
- package/prompts/collaboration-workflow/measurement.md +44 -0
- package/prompts/collaboration-workflow/operating-rules.md +15 -8
- package/prompts/collaboration-workflow/output-bounds.md +6 -7
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +14 -0
- package/prompts/collaboration-workflow/report-format.md +31 -60
- package/prompts/collaboration-workflow/residency.md +3 -2
- package/prompts/collaboration-workflow/rule-delivery.md +13 -1
- package/prompts/collaboration-workflow/shell-body.md +6 -16
- package/prompts/collaboration-workflow/turn-batching.md +0 -2
- package/prompts/collaboration-workflow/upstream-interrupt.md +15 -5
- package/prompts/collaboration-workflow/wip-cap.md +4 -2
- package/prompts/collaboration-workflow.md +3 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +9 -2
- package/prompts/review.md +65 -36
- package/prompts/testing-guide.md +9 -43
- package/scripts/agent/agent-argv.ts +14 -16
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/agent-provider.ts +138 -0
- package/scripts/agent/agent-role-profile.ts +108 -156
- package/scripts/agent/agent-safe-text.ts +20 -5
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/api-usage-limit.ts +65 -0
- package/scripts/agent/claude-agent-argv.ts +19 -9
- package/scripts/agent/codex-agent-argv.ts +118 -22
- package/scripts/agent/usage-limit-reset.ts +179 -0
- package/scripts/auth/claude-token-output.ts +2 -2
- package/scripts/auto-ok/auto-ok-author.ts +53 -0
- package/scripts/auto-ok/auto-ok-cli.ts +25 -16
- package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
- package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
- package/scripts/auto-ok/auto-ok-judge.ts +13 -2
- package/scripts/auto-ok/auto-ok-main.ts +17 -0
- package/scripts/backlog/backlog-arrival.ts +14 -3
- package/scripts/backlog/backlog-budget-cli.ts +7 -33
- package/scripts/backlog/backlog-budget-main.ts +16 -0
- package/scripts/backlog/backlog-budget.ts +2 -3
- package/scripts/backlog/backlog-defect-priority.ts +5 -4
- package/scripts/backlog/backlog-drive-adopt.ts +67 -0
- package/scripts/backlog/backlog-drive-args.ts +4 -5
- package/scripts/backlog/backlog-drive-cli.ts +118 -28
- package/scripts/backlog/backlog-drive-hold.ts +162 -0
- package/scripts/backlog/backlog-drive-idle.ts +161 -0
- package/scripts/backlog/backlog-drive-judge.ts +25 -0
- package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
- package/scripts/backlog/backlog-drive-launch.ts +8 -2
- package/scripts/backlog/backlog-drive-memory.ts +126 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +73 -35
- package/scripts/backlog/backlog-drive-named.ts +81 -13
- package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
- package/scripts/backlog/backlog-drive-paused.ts +170 -0
- package/scripts/backlog/backlog-drive-restore.ts +39 -8
- package/scripts/backlog/backlog-drive-seats.ts +18 -8
- package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
- package/scripts/backlog/backlog-drive.ts +96 -131
- package/scripts/backlog/backlog-gate-scope.ts +61 -0
- package/scripts/backlog/backlog-measure-close.ts +112 -0
- package/scripts/backlog/backlog-next-main.ts +16 -0
- package/scripts/backlog/backlog-next-shared.ts +73 -0
- package/scripts/backlog/backlog-next.ts +78 -56
- package/scripts/backlog/backlog-occupied.ts +52 -39
- package/scripts/backlog/backlog-offer-cli.ts +6 -21
- package/scripts/backlog/backlog-offer-exclude.ts +15 -0
- package/scripts/backlog/backlog-offer-main.ts +12 -0
- package/scripts/backlog/backlog-offer.ts +36 -3
- package/scripts/backlog/backlog-overlap.ts +62 -10
- package/scripts/backlog/backlog-plan-cli.ts +4 -1
- package/scripts/backlog/backlog-plan-comment.ts +81 -0
- package/scripts/backlog/backlog-plan-read.ts +22 -5
- package/scripts/backlog/backlog-plan.ts +18 -4
- package/scripts/backlog/backlog-pool.ts +60 -22
- package/scripts/backlog/backlog-rank.ts +70 -15
- package/scripts/backlog/backlog-ready.ts +112 -30
- package/scripts/backlog/backlog-stalled-detect.ts +110 -36
- package/scripts/backlog/backlog-stalled.ts +52 -16
- package/scripts/backlog/backlog-wait-cause.ts +86 -0
- package/scripts/backlog/backlog-waves.ts +56 -15
- package/scripts/backlog/backlogrun-args.ts +19 -7
- package/scripts/backlog/backlogrun-cli.ts +19 -5
- package/scripts/backlog/backlogrun-launch.ts +13 -4
- package/scripts/backlog/backlogrun-restart.ts +97 -0
- package/scripts/backlog/backlogrun-stop.ts +79 -7
- package/scripts/behavior/behavior-cli.ts +2 -2
- package/scripts/behavior/behavior-rules.ts +47 -24
- package/scripts/build/build-bin.ts +2 -16
- package/scripts/build/build-claude-md.ts +0 -7
- package/scripts/build/build-commands.ts +0 -13
- package/scripts/build/build-hooks.ts +49 -48
- package/scripts/build/hook-bundle-stamp.ts +29 -11
- package/scripts/build/local-bin.ts +1 -1
- package/scripts/cases/cases-cli.ts +25 -13
- package/scripts/cases/cases-interaction-scan.ts +134 -0
- package/scripts/cases/cases-interaction.ts +183 -0
- package/scripts/cases/cases-logic.ts +39 -6
- package/scripts/ci/pr-classification-main.ts +18 -0
- package/scripts/ci/pr-classification.ts +10 -17
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/cost-runtime/context-cut-payback.ts +27 -25
- package/scripts/cost-runtime/cost-blocks.ts +22 -37
- package/scripts/cost-runtime/cost-cli.ts +67 -29
- package/scripts/cost-runtime/cost-main.ts +12 -0
- package/scripts/cost-runtime/cost-pricing.ts +9 -0
- package/scripts/cost-runtime/cost-transcript.ts +1 -0
- package/scripts/cost-runtime/cost-verdict.ts +4 -1
- package/scripts/delegation/delegation-policy.ts +18 -5
- package/scripts/delegation/duplicate-read-guard.ts +1 -8
- package/scripts/delegation/investigation-guard.ts +12 -8
- package/scripts/delegation/investigation-reads.ts +48 -27
- package/scripts/dependabot/dependabot-cooldown.ts +195 -0
- package/scripts/discovery/repo-discovery.ts +24 -6
- package/scripts/discovery/repo-party.ts +80 -20
- package/scripts/discovery/session-owner-pin.ts +51 -0
- package/scripts/doctor/doctor-consumer.ts +2 -5
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/command-reference-line-budget.ts +42 -0
- package/scripts/document/document-byte-budget.ts +18 -6
- package/scripts/document/document-checks.ts +20 -0
- package/scripts/document/document-ratchet-check.ts +101 -0
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +0 -8
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/document/document-section.ts +1 -0
- package/scripts/document/entry-read-budget.ts +7 -3
- package/scripts/document/issue-citation-budget.ts +94 -0
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-busy.ts +5 -12
- package/scripts/epic/epic-classify.ts +24 -15
- package/scripts/epic/epic-cli-argv.ts +33 -2
- package/scripts/epic/epic-cli-decide.ts +42 -0
- package/scripts/epic/epic-cli.ts +6 -38
- package/scripts/epic/epic-close.ts +112 -55
- package/scripts/epic/epic-cross-repo.ts +4 -7
- package/scripts/epic/epic-decide.ts +119 -0
- package/scripts/epic/epic-decision.ts +9 -0
- package/scripts/epic/epic-fetch.ts +6 -0
- package/scripts/epic/epic-graph.ts +8 -1
- package/scripts/epic/epic-issue.ts +8 -2
- package/scripts/epic/epic-label-age.ts +1 -1
- package/scripts/epic/epic-lane-offer.ts +39 -4
- package/scripts/epic/epic-next-main.ts +24 -0
- package/scripts/epic/epic-next.ts +6 -24
- package/scripts/epic/epic-outside-blocker.ts +6 -2
- package/scripts/epic/epic-parse.ts +9 -3
- package/scripts/epic/epic-rank.ts +5 -0
- package/scripts/epic/epic-read.ts +1 -0
- package/scripts/epic/epic-reconcile.ts +39 -0
- package/scripts/epic/epic-run.ts +10 -1
- package/scripts/epic/epic-solo.ts +50 -14
- package/scripts/epic/epic.ts +41 -7
- package/scripts/exports/unused-members-check.ts +62 -0
- package/scripts/exports/unused-members-cli.ts +6 -51
- package/scripts/followup/followup-checks-event.ts +8 -3
- package/scripts/followup/followup-ci-path.ts +67 -0
- package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
- package/scripts/followup/followup-coderabbit-wait.ts +85 -0
- package/scripts/followup/followup-failed-tests.ts +160 -0
- package/scripts/followup/followup-job-needs.ts +100 -0
- package/scripts/followup/followup-job-rerun.ts +303 -0
- package/scripts/followup/followup-main-move.ts +113 -0
- package/scripts/followup/followup-review-gates.ts +81 -0
- package/scripts/followup/git-followup-finish.ts +43 -11
- package/scripts/followup/git-followup-pending.ts +3 -3
- package/scripts/followup/git-followup-stages.ts +52 -12
- package/scripts/followup/git-followup-workflow.ts +19 -66
- package/scripts/followup/git-pr-followup-checks.ts +55 -16
- package/scripts/followup/git-pr-followup-wrapup.ts +32 -18
- package/scripts/followup/git-pr-followup.ts +96 -33
- package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
- package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
- package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
- package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +3 -3
- package/scripts/gate/busy-average.ts +90 -0
- package/scripts/gate/check-cpu.ts +60 -0
- package/scripts/gate/check-inputs.ts +39 -95
- package/scripts/gate/check-related-pinned.ts +43 -0
- package/scripts/gate/check-related-reuse.ts +64 -0
- package/scripts/gate/check-related-section.ts +57 -0
- package/scripts/gate/check-related-unplanned.ts +34 -0
- package/scripts/gate/check-related.ts +265 -0
- package/scripts/gate/check-reuse.ts +33 -54
- package/scripts/gate/command-memory.ts +192 -0
- package/scripts/gate/core-admission.ts +236 -28
- package/scripts/gate/core-budget-timing.ts +51 -0
- package/scripts/gate/core-budget.ts +111 -100
- package/scripts/gate/core-wait-record.ts +49 -0
- package/scripts/gate/core-wait.ts +62 -7
- package/scripts/gate/core-weights.ts +94 -0
- package/scripts/gate/free-cores.ts +27 -4
- package/scripts/gate/gate-labels.ts +46 -0
- package/scripts/gate/gate-ledger.ts +44 -8
- package/scripts/gate/gate-plan.ts +130 -78
- package/scripts/gate/gate-report.ts +23 -9
- package/scripts/gate/gate-run-steps.ts +77 -9
- package/scripts/gate/gate-skip.ts +57 -8
- package/scripts/gate/gate-static-group.ts +60 -0
- package/scripts/gate/gate-steps.ts +14 -2
- package/scripts/gate/gate-tree.ts +4 -2
- package/scripts/gate/hook-gate-reuse.ts +19 -2
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +65 -31
- package/scripts/gate/metrics-totals.ts +59 -0
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/project-checks.ts +5 -12
- package/scripts/gate/scoped-green.ts +76 -19
- package/scripts/gate/since-green.ts +70 -0
- package/scripts/gate/structural-checks.ts +96 -0
- package/scripts/gate/toolchain-inputs.ts +115 -0
- package/scripts/gate/verification-gate.ts +70 -32
- package/scripts/gate/verification-inputs.ts +265 -0
- package/scripts/gate/verification-tail.ts +52 -0
- package/scripts/gh/gh-author-association.ts +117 -9
- package/scripts/gh/git-ai-review-scan.ts +5 -3
- package/scripts/gh/git-gh-api-path.ts +26 -2
- package/scripts/gh/git-gh-branch-rules.ts +73 -0
- package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
- package/scripts/gh/git-gh-conditional.ts +5 -2
- package/scripts/gh/git-gh-exec.ts +32 -2
- package/scripts/gh/git-gh-issue-read.ts +7 -1
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +75 -31
- package/scripts/gh/git-gh-issue.ts +19 -8
- package/scripts/gh/git-gh-poll-read.ts +89 -0
- package/scripts/gh/git-gh-pr-auto-merge.ts +21 -9
- package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
- package/scripts/gh/git-gh-pr-read.ts +74 -13
- package/scripts/gh/git-gh-pr-rest.ts +4 -2
- package/scripts/gh/git-gh-pr-snapshot.ts +48 -20
- package/scripts/gh/git-gh-pr-too-large.ts +20 -0
- package/scripts/gh/git-gh-pr.ts +48 -22
- package/scripts/gh/git-gh-retry.ts +141 -0
- package/scripts/gh/git-pr-ai-review.ts +15 -6
- package/scripts/gh/git-pr-checks-eval.ts +42 -7
- package/scripts/gh/git-pr-checks-parse.ts +39 -9
- package/scripts/gh/git-pr-checks.ts +5 -5
- package/scripts/gh/git-pr-merge-checked.ts +80 -0
- package/scripts/git/base-tree.ts +49 -2
- package/scripts/git/change-base.ts +4 -10
- package/scripts/git/changed-file-scope.ts +6 -4
- package/scripts/git/changed-paths-sync.ts +63 -0
- package/scripts/git/changed-paths.ts +34 -2
- package/scripts/git/git-common-directory.ts +11 -1
- package/scripts/git/git-diff-reads.ts +91 -20
- package/scripts/git/git-error.ts +9 -2
- package/scripts/git/git-grep-hits.ts +85 -0
- package/scripts/git/git-location-environment.ts +1 -1
- package/scripts/git/git-merge-conflicts.ts +83 -0
- package/scripts/git/git-preflight.ts +37 -12
- package/scripts/git/git-push-transport.ts +1 -2
- package/scripts/git/git-schemas.ts +30 -7
- package/scripts/git/git-spawn.ts +1 -2
- package/scripts/git/git-status.ts +4 -4
- package/scripts/git/git-worktree.ts +13 -0
- package/scripts/git/gone-branch.ts +4 -1
- package/scripts/git/main-merge-budget-conflict.ts +89 -0
- package/scripts/git/main-merge-guard.ts +55 -18
- package/scripts/git/main-merge-main.ts +12 -0
- package/scripts/git/main-merge-regenerate.ts +59 -25
- package/scripts/git/main-merge.ts +77 -13
- package/scripts/git/main-sync-main.ts +12 -0
- package/scripts/git/main-sync.ts +0 -9
- package/scripts/git/no-base-checkout.ts +127 -0
- package/scripts/git/stash/git-stash.ts +38 -6
- package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
- package/scripts/git/stash/stash-pop-cli.ts +6 -12
- package/scripts/git/stash/stash-pop-main.ts +12 -0
- package/scripts/git/stash/stash-push-cli.ts +86 -0
- package/scripts/git/stash/stash-push-main.ts +12 -0
- package/scripts/hooks/batch-guard.ts +38 -27
- package/scripts/hooks/check-commit-message-main.ts +8 -0
- package/scripts/hooks/check-commit-message.ts +4 -7
- package/scripts/hooks/edited-cspell.ts +37 -11
- package/scripts/hooks/format-edited-file.ts +29 -25
- package/scripts/hooks/lane-plan-guard.ts +50 -0
- package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
- package/scripts/hooks/pre-commit-lint.ts +44 -4
- package/scripts/hooks/pre-push-related-switch.ts +10 -0
- package/scripts/hooks/pre-push-unit.ts +77 -9
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +34 -19
- package/scripts/hooks/reserved-run.ts +81 -10
- package/scripts/hooks/run-hook.sh +30 -6
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/step-zero-notice.ts +6 -1
- package/scripts/hooks/stop-actions.ts +5 -36
- package/scripts/hooks/stop-guard.ts +20 -15
- package/scripts/init/distributed-paths.ts +1 -0
- package/scripts/init/hook-command-rewrite.ts +23 -5
- package/scripts/init/hook-launch.ts +17 -17
- package/scripts/init/init-actions.ts +0 -6
- package/scripts/init/init-ai-copy.ts +10 -36
- package/scripts/init/init-bootstrap.ts +9 -8
- package/scripts/init/init-dry-run-report.ts +1 -1
- package/scripts/init/init-dry-run.ts +1 -1
- package/scripts/init/init-file-action.ts +7 -9
- package/scripts/init/init-logic-json-merge.ts +2 -2
- package/scripts/init/init-logic-migrate.ts +9 -82
- package/scripts/init/init-logic.ts +3 -2
- package/scripts/init/init-main.ts +12 -0
- package/scripts/init/init.ts +5 -12
- package/scripts/init/kit-development-versions.ts +3 -7
- package/scripts/init/kit-written-paths.ts +2 -2
- package/scripts/init/project-profile.ts +5 -4
- package/scripts/init/tsconfig-preset-migration.ts +2 -1
- package/scripts/init/vscode-tasks.ts +1 -1
- package/scripts/issue/aggregation-split.ts +52 -0
- package/scripts/issue/defect-origin-cli.ts +106 -0
- package/scripts/issue/defect-origin-line.ts +78 -0
- package/scripts/issue/defect-origin-main.ts +11 -0
- package/scripts/issue/defect-origin.ts +114 -0
- package/scripts/issue/defect-rate-cli.ts +38 -179
- package/scripts/issue/defect-rate.ts +0 -16
- package/scripts/issue/defect-report-cli.ts +128 -0
- package/scripts/issue/defect-report-format.ts +56 -0
- package/scripts/issue/defect-report-main.ts +11 -0
- package/scripts/issue/defect-report.ts +160 -0
- package/scripts/issue/effect-audit-cli.ts +178 -0
- package/scripts/issue/effect-audit.ts +185 -0
- package/scripts/issue/expected-effect-lint.ts +65 -9
- package/scripts/issue/git-next-issues.ts +5 -0
- package/scripts/issue/issue-already-done-cli.ts +62 -0
- package/scripts/issue/issue-body-or-comment.ts +74 -0
- package/scripts/issue/issue-cite-cli.ts +1 -12
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +13 -7
- package/scripts/issue/issue-closing-pr.ts +8 -1
- package/scripts/issue/issue-comment-cli.ts +10 -24
- package/scripts/issue/issue-comment-main.ts +12 -0
- package/scripts/issue/issue-evidence-exit.ts +102 -0
- package/scripts/issue/issue-file-cap.ts +58 -0
- package/scripts/issue/issue-file-cli.ts +131 -36
- package/scripts/issue/issue-file-deferral.ts +52 -0
- package/scripts/issue/issue-file-fold.ts +29 -10
- package/scripts/issue/issue-file-interrupt.ts +85 -0
- package/scripts/issue/issue-file-lane-hint.ts +30 -0
- package/scripts/issue/issue-file.ts +56 -19
- package/scripts/issue/issue-fold-cli.ts +2 -11
- package/scripts/issue/issue-fold-main.ts +12 -0
- package/scripts/issue/issue-labels.ts +97 -89
- package/scripts/issue/issue-lint-cli.ts +29 -12
- package/scripts/issue/issue-lint-main.ts +12 -0
- package/scripts/issue/issue-measured-cli.ts +34 -0
- package/scripts/issue/issue-measured-close.ts +58 -0
- package/scripts/issue/issue-merged.ts +19 -2
- package/scripts/issue/issue-not-before-label.ts +135 -0
- package/scripts/issue/issue-not-before.ts +114 -0
- package/scripts/issue/issue-number-shape.ts +15 -1
- package/scripts/issue/issue-park.ts +28 -0
- package/scripts/issue/issue-plan-cli.ts +151 -0
- package/scripts/issue/issue-priority-cli.ts +60 -0
- package/scripts/issue/issue-priority-raise.ts +55 -0
- package/scripts/issue/issue-priority.ts +282 -0
- package/scripts/issue/issue-rank.ts +27 -4
- package/scripts/issue/issue-read-cli.ts +35 -16
- package/scripts/issue/issue-read-main.ts +12 -0
- package/scripts/issue/issue-read.ts +62 -13
- package/scripts/issue/issue-release-cli.ts +0 -10
- package/scripts/issue/issue-release-main.ts +13 -0
- package/scripts/issue/issue-release.ts +7 -12
- package/scripts/issue/issue-sample-gate.ts +213 -0
- package/scripts/issue/issue-sample-prime.ts +127 -0
- package/scripts/issue/issue-sample-required.ts +57 -0
- package/scripts/issue/issue-sample-source.ts +77 -0
- package/scripts/issue/issue-scout-cli.ts +0 -11
- package/scripts/issue/issue-scout-main.ts +14 -0
- package/scripts/issue/issue-search.ts +124 -0
- package/scripts/issue/issue-state-cli.ts +0 -10
- package/scripts/issue/issue-state-main.ts +12 -0
- package/scripts/issue/issue-state.ts +13 -1
- package/scripts/issue/issue-template-section.ts +43 -0
- package/scripts/issue/issue-watch-diff.ts +87 -16
- package/scripts/issue/issue-watch-hook.ts +11 -2
- package/scripts/issue/issue-watch.ts +55 -11
- package/scripts/issue/issue-wip.ts +2 -7
- package/scripts/issue/markdown-section.ts +1 -0
- package/scripts/issue/measure-declaration.ts +121 -0
- package/scripts/issue/measure-rerun-cli.ts +7 -65
- package/scripts/issue/plan-consumers-cli.ts +39 -0
- package/scripts/issue/plan-consumers-main.ts +11 -0
- package/scripts/issue/plan-consumers-section.ts +76 -0
- package/scripts/issue/plan-consumers.ts +127 -0
- package/scripts/issue/reproduction-measure.ts +3 -1
- package/scripts/issue/size-estimate.ts +90 -0
- package/scripts/issue/trusted-measure.ts +84 -0
- package/scripts/josh/agent-session-environment.ts +1 -1
- package/scripts/josh/command-usage.ts +17 -44
- package/scripts/josh/durable-state-migrate.ts +105 -0
- package/scripts/josh/durable-state.ts +112 -0
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-aliases.ts +95 -0
- package/scripts/josh/josh-command-map.ts +1 -79
- package/scripts/josh/josh-command-types.ts +12 -6
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +160 -161
- package/scripts/josh/josh-commands-backlog.ts +82 -16
- package/scripts/josh/josh-commands-clone.ts +1 -0
- package/scripts/josh/josh-commands-development.ts +142 -101
- package/scripts/josh/josh-commands-document.ts +43 -1
- package/scripts/josh/josh-commands-epic.ts +171 -0
- package/scripts/josh/josh-commands-hooks.ts +25 -2
- package/scripts/josh/josh-commands-issue-write.ts +200 -0
- package/scripts/josh/josh-commands-issue.ts +156 -24
- package/scripts/josh/josh-commands-lane.ts +187 -3
- package/scripts/josh/josh-commands-lint.ts +34 -10
- package/scripts/josh/josh-commands-maintenance.ts +127 -4
- package/scripts/josh/josh-commands-pause.ts +29 -0
- package/scripts/josh/josh-commands-progress.ts +87 -0
- package/scripts/josh/josh-commands-project.ts +138 -9
- package/scripts/josh/josh-commands-review.ts +159 -0
- package/scripts/josh/josh-commands-run.ts +211 -23
- package/scripts/josh/josh-commands-ship.ts +217 -0
- package/scripts/josh/josh-commands-split.ts +9 -0
- package/scripts/josh/josh-commands-test-check.ts +80 -0
- package/scripts/josh/josh-commands-versioning.ts +49 -2
- package/scripts/josh/josh-commands-workflow.ts +144 -6
- package/scripts/josh/josh-environment-file.ts +43 -3
- package/scripts/josh/josh-in-process.ts +2 -2
- package/scripts/josh/josh-logic.ts +11 -16
- package/scripts/josh/josh-run.ts +19 -1
- package/scripts/josh/package-directory.ts +2 -4
- package/scripts/josh/process-identity.ts +13 -4
- package/scripts/josh/run-record-path.ts +15 -0
- package/scripts/josh/session-language-cli.ts +4 -8
- package/scripts/josh/session-language-main.ts +13 -0
- package/scripts/josh/session-language.ts +6 -1
- package/scripts/josh/shared-cache.ts +90 -0
- package/scripts/josh/stamp-file.ts +20 -17
- package/scripts/lane/lane-adopt-cli.ts +98 -0
- package/scripts/lane/lane-adopt.ts +208 -0
- package/scripts/lane/lane-await.ts +56 -20
- package/scripts/lane/lane-baseline.ts +123 -0
- package/scripts/lane/lane-breakdown-cli.ts +64 -0
- package/scripts/lane/lane-breakdown-implement.ts +170 -0
- package/scripts/lane/lane-breakdown-laps.ts +107 -0
- package/scripts/lane/lane-breakdown-pinned.ts +76 -0
- package/scripts/lane/lane-breakdown-text.ts +145 -0
- package/scripts/lane/lane-breakdown.ts +239 -0
- package/scripts/lane/lane-cache.ts +5 -30
- package/scripts/lane/lane-capacity.ts +14 -23
- package/scripts/lane/lane-check-stats.ts +84 -22
- package/scripts/lane/lane-child-invocation.ts +17 -2
- package/scripts/lane/lane-child-mark-keys.ts +12 -0
- package/scripts/lane/lane-child-marker.ts +20 -1
- package/scripts/lane/lane-ci-path-stats.ts +73 -0
- package/scripts/lane/lane-claim-stats.ts +84 -0
- package/scripts/lane/lane-cli.ts +15 -5
- package/scripts/lane/lane-close.ts +91 -18
- package/scripts/lane/lane-core-wait-stats.ts +66 -0
- package/scripts/lane/lane-dispatch-log.ts +3 -3
- package/scripts/lane/lane-dispatch.ts +26 -5
- package/scripts/lane/lane-gap-stats.ts +157 -0
- package/scripts/lane/lane-guard-policy.ts +7 -1
- package/scripts/lane/lane-handoff.ts +69 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-implement-stats.ts +207 -0
- package/scripts/lane/lane-implement-subagents.ts +90 -0
- package/scripts/lane/lane-install.ts +4 -11
- package/scripts/lane/lane-investigation-switch.ts +16 -0
- package/scripts/lane/lane-launch-cli.ts +0 -9
- package/scripts/lane/lane-launch-main.ts +12 -0
- package/scripts/lane/lane-ledger-kind.ts +31 -0
- package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
- package/scripts/lane/lane-ledger-schema.ts +349 -0
- package/scripts/lane/lane-ledger-write.ts +257 -0
- package/scripts/lane/lane-ledger.ts +56 -233
- package/scripts/lane/lane-limit-cli.ts +12 -1
- package/scripts/lane/lane-load.ts +1 -1
- package/scripts/lane/lane-measure-cli.ts +193 -30
- package/scripts/lane/lane-net-read.ts +44 -0
- package/scripts/lane/lane-net-time.ts +212 -0
- package/scripts/lane/lane-open.ts +25 -8
- package/scripts/lane/lane-output.ts +2 -4
- package/scripts/lane/lane-overrun-prompt.ts +147 -0
- package/scripts/lane/lane-overrun.ts +274 -0
- package/scripts/lane/lane-parked.ts +3 -3
- package/scripts/lane/lane-paths.ts +24 -1
- package/scripts/lane/lane-pause-cli.ts +133 -0
- package/scripts/lane/lane-pause.ts +158 -0
- package/scripts/lane/lane-paused-spans.ts +97 -0
- package/scripts/lane/lane-plan-check.ts +207 -0
- package/scripts/lane/lane-plan-cli.ts +41 -0
- package/scripts/lane/lane-plan.ts +144 -0
- package/scripts/lane/lane-process-table.ts +166 -0
- package/scripts/lane/lane-reap-settle.ts +124 -0
- package/scripts/lane/lane-reap.ts +50 -15
- package/scripts/lane/lane-registry.ts +38 -4
- package/scripts/lane/lane-relaunch.ts +1 -1
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +22 -2
- package/scripts/lane/lane-round-one-stats.ts +51 -0
- package/scripts/lane/lane-round-two-stats.ts +49 -0
- package/scripts/lane/lane-sampler.ts +26 -3
- package/scripts/lane/lane-session-action.ts +112 -23
- package/scripts/lane/lane-session-broker.ts +146 -37
- package/scripts/lane/lane-session-reread-main.ts +14 -0
- package/scripts/lane/lane-session-reread.ts +51 -0
- package/scripts/lane/lane-ship-lap-stats.ts +74 -0
- package/scripts/lane/lane-sleep.ts +58 -0
- package/scripts/lane/lane-snapshot-trace.ts +84 -0
- package/scripts/lane/lane-spans.ts +51 -0
- package/scripts/lane/lane-spent.ts +7 -4
- package/scripts/lane/lane-split-stats.ts +28 -0
- package/scripts/lane/lane-stage-stats.ts +20 -3
- package/scripts/lane/lane-state.ts +334 -0
- package/scripts/lane/lane-stats-tables.ts +58 -0
- package/scripts/lane/lane-stats.ts +74 -4
- package/scripts/lane/lane-stop-stats.ts +145 -37
- package/scripts/lane/lane-tail-stats.ts +32 -0
- package/scripts/lane/lane-test-related-stats.ts +127 -0
- package/scripts/lane/lane-transcript-calls.ts +202 -0
- package/scripts/lane/lane-transcript-stats.ts +200 -0
- package/scripts/lane/lane-vacant.ts +13 -3
- package/scripts/lane/lane-value-cell.ts +72 -0
- package/scripts/lane/lane-value.ts +118 -0
- package/scripts/lane/lane-withdraw-cli.ts +5 -4
- package/scripts/lane/lane-withdraw-closed.ts +124 -0
- package/scripts/lane/lane-withdraw.ts +149 -71
- package/scripts/lane/lane-yield.ts +85 -0
- package/scripts/lane/openai-lane-ship.ts +12 -11
- package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
- package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
- package/scripts/lane/openai-lane-supervisor.ts +5 -4
- package/scripts/lane/process-directories.ts +70 -0
- package/scripts/lane/process-lane-marks.ts +94 -0
- package/scripts/lib/atomic-write.ts +62 -0
- package/scripts/lib/buffered-process.ts +12 -5
- package/scripts/lib/cli-flags.ts +53 -0
- package/scripts/lib/figure-format.ts +63 -0
- package/scripts/lib/json-value.ts +9 -1
- package/scripts/lib/package-manifest.ts +35 -0
- package/scripts/lib/poll.ts +38 -9
- package/scripts/lib/read-file.ts +3 -1
- package/scripts/lib/settled-together.ts +10 -0
- package/scripts/lib/shell-quote.ts +21 -0
- package/scripts/lib/stamped-memo.ts +63 -0
- package/scripts/lib/stdout-on-stderr.ts +24 -0
- package/scripts/lib/timeouts.ts +9 -0
- package/scripts/lib/token-shape.ts +111 -0
- package/scripts/lib/transcript-record.ts +91 -0
- package/scripts/lines/effective-limit.ts +1 -1
- package/scripts/lint/eslint-cache-dependencies.ts +145 -0
- package/scripts/lint/eslint-daemon-sources.ts +79 -0
- package/scripts/lint/eslint-daemon.ts +304 -0
- package/scripts/lint/eslint-warm-cli.ts +7 -0
- package/scripts/lint/eslint-warm.ts +66 -0
- package/scripts/lint/format.ts +11 -2
- package/scripts/lint/import-graph.ts +409 -0
- package/scripts/lint/lint-gate-scope.ts +102 -0
- package/scripts/lint/lint-parallel-main.ts +19 -0
- package/scripts/lint/lint-parallel.ts +113 -33
- package/scripts/lint/lint-related-scope.ts +30 -24
- package/scripts/lint/lint-related.ts +183 -30
- package/scripts/lint/rename-cli.ts +179 -0
- package/scripts/lint/rename-identifier.ts +192 -0
- package/scripts/lint/type-only-imports.ts +58 -0
- package/scripts/notify/confirmation-options.ts +1 -2
- package/scripts/notify/telegram-notify.ts +32 -23
- package/scripts/notify/telegram-test-logic.ts +0 -1
- package/scripts/notify/telegram-test-main.ts +8 -0
- package/scripts/notify/telegram-test.ts +2 -6
- package/scripts/observations/observation-ledger.ts +13 -0
- package/scripts/observations/observation-record.ts +42 -16
- package/scripts/observations/observations-flush-landing.ts +5 -3
- package/scripts/observations/observations-flush.ts +38 -10
- package/scripts/overrides/overrides-check.ts +11 -6
- package/scripts/overrides/overrides-files.ts +2 -1
- package/scripts/overrides/overrides-logic.ts +3 -6
- package/scripts/package/verify-optional-eslint-install.ts +8 -6
- package/scripts/propagate/propagate-publish.ts +2 -7
- package/scripts/propagate/propagate-targets.ts +4 -12
- package/scripts/refactor/import-graph.ts +9 -7
- package/scripts/release/github-release-runs.ts +17 -6
- package/scripts/release/release-approval-prune.ts +24 -0
- package/scripts/release/release-history.ts +1 -3
- package/scripts/release/release-progress.ts +42 -22
- package/scripts/release/release-publish-run.ts +39 -0
- package/scripts/release/release-publish.ts +6 -6
- package/scripts/release/release-scope-cli.ts +0 -10
- package/scripts/release/release-scope-main.ts +12 -0
- package/scripts/repo/repo-setting.ts +3 -6
- package/scripts/repo/required-checks-logic.ts +10 -16
- package/scripts/repo/ruleset-check.ts +4 -3
- package/scripts/report/markdown-shape.ts +28 -0
- package/scripts/report/report-format-reference.ts +17 -1
- package/scripts/report/report-labels.ts +166 -0
- package/scripts/report/report-lint-child-summary.ts +94 -0
- package/scripts/report/report-lint-cli.ts +29 -7
- package/scripts/report/report-lint.ts +85 -128
- package/scripts/report/report-template-cli.ts +59 -0
- package/scripts/report/report-template.ts +112 -0
- package/scripts/review/acceptance-map.ts +1 -0
- package/scripts/review/prose-stale-cli.ts +88 -0
- package/scripts/review/prose-stale-scan.ts +152 -0
- package/scripts/review/removed-tests-check.ts +86 -0
- package/scripts/review/removed-tests.ts +149 -0
- package/scripts/review/review-attest.ts +73 -23
- package/scripts/review/review-brief-cli.ts +138 -23
- package/scripts/review/review-brief-main.ts +12 -0
- package/scripts/review/review-brief-paths.ts +22 -0
- package/scripts/review/review-brief.ts +45 -10
- package/scripts/review/review-code-tree.ts +10 -6
- package/scripts/review/review-comment-carry.ts +47 -0
- package/scripts/review/review-comment-round.ts +111 -30
- package/scripts/review/review-finding-ledger.ts +135 -18
- package/scripts/review/review-finding-text.ts +43 -0
- package/scripts/review/review-interaction.ts +105 -0
- package/scripts/review/review-lane-handover.ts +68 -0
- package/scripts/review/review-lint-cli.ts +57 -0
- package/scripts/review/review-lint-findings.ts +92 -0
- package/scripts/review/review-lint-sections.ts +80 -0
- package/scripts/review/review-lint.ts +221 -0
- package/scripts/review/review-prior-findings.ts +102 -0
- package/scripts/review/review-readers-scan.ts +165 -0
- package/scripts/review/review-record-cli.ts +236 -74
- package/scripts/review/review-record-code-round.ts +55 -0
- package/scripts/review/review-record-comment.ts +60 -0
- package/scripts/review/review-record-interaction.ts +35 -0
- package/scripts/review/review-record-main.ts +12 -0
- package/scripts/review/review-record-pinned.ts +108 -0
- package/scripts/review/review-record.ts +25 -1
- package/scripts/review/review-reviewed-tree.ts +307 -0
- package/scripts/review/review-round-one-blobs.ts +221 -0
- package/scripts/review/review-round-one-closure.ts +62 -0
- package/scripts/review/review-round-reuse.ts +106 -0
- package/scripts/review/review-round2-cli.ts +135 -36
- package/scripts/review/review-round2-skip-comment.ts +55 -0
- package/scripts/review/review-round2.ts +103 -19
- package/scripts/review/review-stamps.ts +23 -1
- package/scripts/review/review-stop-log.ts +110 -0
- package/scripts/review/review-stops-cli.ts +86 -0
- package/scripts/review/review-submit-cli.ts +101 -0
- package/scripts/review/review-tree.ts +6 -17
- package/scripts/review/review-untouched-readers.ts +146 -0
- package/scripts/review/test-titles.ts +118 -0
- package/scripts/rules/agent-model.ts +9 -1
- package/scripts/rules/bash-triggers.ts +49 -6
- package/scripts/rules/concise-reply.ts +88 -0
- package/scripts/rules/credential-body.ts +77 -0
- package/scripts/rules/decision-oracle-batch.ts +9 -1
- package/scripts/rules/decision-oracle.ts +3 -3
- package/scripts/rules/delivered-rules.ts +115 -18
- package/scripts/rules/destructive-command.ts +11 -12
- package/scripts/rules/direct-filing.ts +10 -2
- package/scripts/rules/direct-issue-comment.ts +139 -0
- package/scripts/rules/direct-issue-read.ts +191 -0
- package/scripts/rules/direct-pr-create.ts +72 -26
- package/scripts/rules/early-heartbeat.ts +4 -1
- package/scripts/rules/edit-tool.ts +27 -0
- package/scripts/rules/file-body.ts +7 -0
- package/scripts/rules/file-edit-rows.ts +17 -0
- package/scripts/rules/file-rewrite.ts +146 -0
- package/scripts/rules/firing-point.ts +3 -2
- package/scripts/rules/gh-api.ts +128 -7
- package/scripts/rules/gh-repo-selector.ts +84 -0
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +14 -4
- package/scripts/rules/guard-remedy.ts +17 -4
- package/scripts/rules/implementation-cut-verdict.ts +1 -1
- package/scripts/rules/implementation-cut.ts +68 -27
- package/scripts/rules/index-guard.ts +8 -1
- package/scripts/rules/investigator-foreground.ts +231 -0
- package/scripts/rules/issue-citation.ts +15 -60
- package/scripts/rules/issue-comments.ts +18 -5
- package/scripts/rules/josh-git-bare.ts +7 -0
- package/scripts/rules/lane-background.ts +103 -33
- package/scripts/rules/lane-carry-conflict.ts +6 -0
- package/scripts/rules/lane-direct-tool.ts +172 -0
- package/scripts/rules/lane-interactive-ask.ts +12 -2
- package/scripts/rules/lane-park.ts +49 -25
- package/scripts/rules/lane-spilled-read.ts +90 -0
- package/scripts/rules/lane-split-park.ts +11 -3
- package/scripts/rules/lane-switch-main.ts +11 -4
- package/scripts/rules/last-prompt.ts +20 -47
- package/scripts/rules/oracle-consulted.ts +11 -1
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/permission-guards.ts +7 -0
- package/scripts/rules/piped-verification-shapes.ts +110 -0
- package/scripts/rules/piped-verification.ts +68 -18
- package/scripts/rules/poll-loop.ts +78 -8
- package/scripts/rules/pr-merge.ts +123 -0
- package/scripts/rules/pre-gate-cut.ts +3 -3
- package/scripts/rules/protected-files.ts +113 -22
- package/scripts/rules/raw-field-body.ts +6 -0
- package/scripts/rules/reply-language.ts +3 -17
- package/scripts/rules/reply-prose.ts +34 -0
- package/scripts/rules/repo-admin.ts +132 -0
- package/scripts/rules/reviewer-foreground.ts +88 -0
- package/scripts/rules/round-one-check-related.ts +120 -0
- package/scripts/rules/rule-body-guard.ts +13 -15
- package/scripts/rules/rule-list.ts +9 -28
- package/scripts/rules/rule-value-cache.ts +57 -14
- package/scripts/rules/rule-value-candidates.ts +84 -0
- package/scripts/rules/rule-value-cli.ts +106 -39
- package/scripts/rules/rule-value.ts +18 -5
- package/scripts/rules/run-tail-rule.ts +1 -1
- package/scripts/rules/sed-in-place.ts +196 -0
- package/scripts/rules/shell-segments.ts +43 -0
- package/scripts/rules/stop-rule-rows.ts +52 -0
- package/scripts/rules/stop-rules.ts +36 -62
- package/scripts/rules/test-declared-commit.ts +11 -1
- package/scripts/rules/third-party-write.ts +115 -21
- package/scripts/rules/timed-rerun.ts +69 -0
- package/scripts/rules/turn-filings.ts +90 -0
- package/scripts/rules/worktree-guard.ts +32 -7
- package/scripts/run/board/run-board-app-name.ts +23 -0
- package/scripts/run/board/run-board-cli.ts +65 -32
- package/scripts/run/board/run-board-earlier.ts +94 -0
- package/scripts/run/board/run-board-ending-reason.ts +71 -0
- package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
- package/scripts/run/board/run-board-estimate.ts +98 -0
- package/scripts/run/board/run-board-fit.ts +177 -37
- package/scripts/run/board/run-board-fold.ts +123 -0
- package/scripts/run/board/run-board-found.ts +134 -0
- package/scripts/run/board/run-board-fresh.ts +2 -2
- package/scripts/run/board/run-board-gather-live.ts +29 -0
- package/scripts/run/board/run-board-gather-thread.ts +189 -0
- package/scripts/run/board/run-board-gather-worker.ts +29 -0
- package/scripts/run/board/run-board-gather.ts +187 -0
- package/scripts/run/board/run-board-github.ts +118 -38
- package/scripts/run/board/run-board-header.ts +90 -20
- package/scripts/run/board/run-board-keys.ts +58 -0
- package/scripts/run/board/run-board-kind.ts +20 -6
- package/scripts/run/board/run-board-labels.ts +126 -71
- package/scripts/run/board/run-board-lane-state.ts +109 -0
- package/scripts/run/board/run-board-lane-time.ts +123 -0
- package/scripts/run/board/run-board-layout.ts +239 -60
- package/scripts/run/board/run-board-length.ts +52 -0
- package/scripts/run/board/run-board-link.ts +15 -2
- package/scripts/run/board/run-board-machine.ts +8 -4
- package/scripts/run/board/run-board-main.ts +12 -0
- package/scripts/run/board/run-board-notes.ts +59 -32
- package/scripts/run/board/run-board-now.ts +1 -1
- package/scripts/run/board/run-board-operation.ts +19 -35
- package/scripts/run/board/run-board-phase.ts +3 -6
- package/scripts/run/board/run-board-plan-shared.ts +115 -0
- package/scripts/run/board/run-board-plan.ts +56 -4
- package/scripts/run/board/run-board-planning.ts +45 -0
- package/scripts/run/board/run-board-priority.ts +44 -0
- package/scripts/run/board/run-board-process-groups.ts +195 -0
- package/scripts/run/board/run-board-read.ts +197 -28
- package/scripts/run/board/run-board-reason.ts +247 -51
- package/scripts/run/board/run-board-released.ts +35 -0
- package/scripts/run/board/run-board-render-checks.ts +42 -7
- package/scripts/run/board/run-board-render-condition.ts +96 -0
- package/scripts/run/board/run-board-render-drawn.ts +78 -0
- package/scripts/run/board/run-board-render-foot.ts +59 -0
- package/scripts/run/board/run-board-render-found.ts +157 -0
- package/scripts/run/board/run-board-render-icon.ts +35 -0
- package/scripts/run/board/run-board-render-lanes.ts +145 -0
- package/scripts/run/board/run-board-render-lead.ts +89 -0
- package/scripts/run/board/run-board-render-legend.ts +136 -48
- package/scripts/run/board/run-board-render-notes.ts +156 -29
- package/scripts/run/board/run-board-render-processes.ts +196 -0
- package/scripts/run/board/run-board-render-section.ts +119 -0
- package/scripts/run/board/run-board-render-slot.ts +3 -36
- package/scripts/run/board/run-board-render-tail.ts +115 -48
- package/scripts/run/board/run-board-render-time.ts +56 -0
- package/scripts/run/board/run-board-render-title.ts +117 -24
- package/scripts/run/board/run-board-render-waits.ts +104 -20
- package/scripts/run/board/run-board-render.ts +264 -258
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +9 -4
- package/scripts/run/board/run-board-setup.ts +1 -12
- package/scripts/run/board/run-board-snapshot.ts +111 -0
- package/scripts/run/board/run-board-spin.ts +3 -5
- package/scripts/run/board/run-board-state.ts +22 -33
- package/scripts/run/board/run-board-status.ts +149 -71
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +158 -114
- package/scripts/run/board/run-board-usage-board.ts +78 -0
- package/scripts/run/board/run-board-usage-lanes.ts +113 -0
- package/scripts/run/board/run-board-usage-listing.ts +93 -0
- package/scripts/run/board/run-board-usage-read.ts +120 -150
- package/scripts/run/board/run-board-usage-rusage.ts +19 -7
- package/scripts/run/board/run-board-usage-text.ts +139 -51
- package/scripts/run/board/run-board-usage-top.ts +102 -0
- package/scripts/run/board/run-board-usage.ts +89 -72
- package/scripts/run/board/run-board-usual.ts +20 -9
- package/scripts/run/carry/run-carry-args.ts +4 -7
- package/scripts/run/carry/run-carry-conversation.ts +1 -1
- package/scripts/run/carry/run-carry-ended.ts +3 -2
- package/scripts/run/carry/run-carry.ts +12 -6
- package/scripts/run/cut/run-cut-cli.ts +33 -133
- package/scripts/run/cut/run-cut-digest.ts +152 -0
- package/scripts/run/cut/run-cut-handoff.ts +54 -10
- package/scripts/run/cut/run-cut-report.ts +24 -3
- package/scripts/run/cut/run-cut-resume.ts +129 -0
- package/scripts/run/cut/run-cut-review.ts +105 -0
- package/scripts/run/cut/run-cut.ts +18 -7
- package/scripts/run/detached-launch.ts +1 -1
- package/scripts/run/entry/run-entry-cli.ts +88 -19
- package/scripts/run/entry/run-entry-spill.ts +83 -0
- package/scripts/run/entry/run-entry-stop.ts +5 -1
- package/scripts/run/entry/run-entry-trust.ts +91 -0
- package/scripts/run/event/run-event-baseline.ts +56 -0
- package/scripts/run/event/run-event-cli.ts +1 -5
- package/scripts/run/event/run-event-filed.ts +18 -6
- package/scripts/run/event/run-event-follow.ts +2 -3
- package/scripts/run/event/run-event-overrun.ts +197 -0
- package/scripts/run/event/run-event-render.ts +10 -10
- package/scripts/run/event/run-event-scope.ts +2 -2
- package/scripts/run/event/run-event-stream-emit.ts +82 -22
- package/scripts/run/event/run-event-stream.ts +58 -10
- package/scripts/run/hold/run-hold-adopt.ts +65 -0
- package/scripts/run/hold/run-hold-cli.ts +93 -22
- package/scripts/run/hold/run-hold-main.ts +12 -0
- package/scripts/run/hold/run-hold-member.ts +37 -0
- package/scripts/run/hold/run-stop-notify.ts +178 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cap.ts +57 -0
- package/scripts/run/merge/run-merge-cli.ts +119 -62
- package/scripts/run/merge/run-merge-close.ts +74 -0
- package/scripts/run/merge/run-merge-collect.ts +6 -13
- package/scripts/run/merge/run-merge-driver.ts +71 -0
- package/scripts/run/merge/run-merge-main.ts +12 -0
- package/scripts/run/merge/run-merge-outcome.ts +25 -0
- package/scripts/run/merge/run-merge-restart.ts +39 -0
- package/scripts/run/merge/run-merge-ship.ts +33 -7
- package/scripts/run/merge/run-merge-signals.ts +66 -25
- package/scripts/run/merge/run-merge-steps.ts +162 -107
- package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
- package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
- package/scripts/run/merge/run-merge.ts +76 -48
- package/scripts/run/park/run-park-cli.ts +91 -0
- package/scripts/run/park/run-park.ts +88 -0
- package/scripts/run/park/run-stalled.ts +68 -0
- package/scripts/run/pause/run-pause-cli.ts +73 -0
- package/scripts/run/pause/run-pause.ts +251 -0
- package/scripts/run/progress/run-progress-cli.ts +4 -12
- package/scripts/run/progress/run-progress-clock.ts +1 -1
- package/scripts/run/progress/run-progress-config.ts +6 -14
- package/scripts/run/progress/run-progress-main.ts +12 -0
- package/scripts/run/progress/run-progress.ts +1 -4
- package/scripts/run/review/run-review-cli.ts +306 -20
- package/scripts/run/review/run-review-early-push.ts +121 -0
- package/scripts/run/review/run-review-join-read.ts +94 -0
- package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
- package/scripts/run/review/run-review-pinned-join.ts +216 -0
- package/scripts/run/review/run-review-pinned-steps.ts +383 -0
- package/scripts/run/review/run-review-pinned-tree.ts +37 -0
- package/scripts/run/review/run-review-pinned.ts +53 -0
- package/scripts/run/review/run-review-steps.ts +70 -34
- package/scripts/run/review/run-review.ts +28 -7
- package/scripts/run/run-ending.ts +1 -0
- package/scripts/run/run-invocation.ts +5 -6
- package/scripts/run/run-liveness-cli.ts +6 -8
- package/scripts/run/run-liveness.ts +60 -29
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +3 -4
- package/scripts/run/run-preflight.ts +18 -3
- package/scripts/run/run-prep-cli.ts +1 -10
- package/scripts/run/run-prep-locate.ts +7 -50
- package/scripts/run/run-prep-main.ts +12 -0
- package/scripts/run/run-prep.ts +7 -0
- package/scripts/run/run-report-cli.ts +101 -13
- package/scripts/run/run-report-handoff.ts +114 -0
- package/scripts/run/run-stage-read.ts +2 -6
- package/scripts/run/run-step-cli.ts +17 -5
- package/scripts/run/run-step-lane-plan.ts +27 -0
- package/scripts/run/run-step-section.ts +26 -7
- package/scripts/run/run-step.ts +6 -3
- package/scripts/run/run-stranded-detect.ts +13 -0
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +1 -1
- package/scripts/run/ship/run-ship-args.ts +140 -0
- package/scripts/run/ship/run-ship-body-draft.ts +110 -0
- package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
- package/scripts/run/ship/run-ship-cli.ts +181 -166
- package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
- package/scripts/run/ship/run-ship-detach.ts +29 -12
- package/scripts/run/ship/run-ship-handover.ts +106 -0
- package/scripts/run/ship/run-ship-infra-retry.ts +74 -0
- package/scripts/run/ship/run-ship-lap.ts +63 -0
- package/scripts/run/ship/run-ship-next.ts +44 -27
- package/scripts/run/ship/run-ship-overlap.ts +49 -7
- package/scripts/run/ship/run-ship-place.ts +103 -0
- package/scripts/run/ship/run-ship-planned.ts +92 -0
- package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +42 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +144 -33
- package/scripts/run/ship/run-ship-preflight.ts +150 -33
- package/scripts/run/ship/run-ship-probe.ts +28 -6
- package/scripts/run/ship/run-ship-relaunch-cap.ts +106 -0
- package/scripts/run/ship/run-ship-relaunch.ts +51 -0
- package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
- package/scripts/run/ship/run-ship-return.ts +183 -25
- package/scripts/run/ship/run-ship-review-reason.ts +24 -0
- package/scripts/run/ship/run-ship-review-steps.ts +296 -171
- package/scripts/run/ship/run-ship-review.ts +222 -35
- package/scripts/run/ship/run-ship-reviewer.ts +303 -0
- package/scripts/run/ship/run-ship-scoped.ts +39 -10
- package/scripts/run/ship/run-ship-stage.ts +101 -16
- package/scripts/run/ship/run-ship-steps.ts +68 -17
- package/scripts/run/ship/run-ship-stop-cause.ts +176 -0
- package/scripts/run/ship/run-ship-stop-context.ts +50 -13
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +212 -34
- package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
- package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
- package/scripts/run/ship/run-ship-waiter.ts +114 -0
- package/scripts/run/ship/run-ship.ts +44 -2
- package/scripts/run/tidy/run-tidy-cli.ts +0 -4
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
- package/scripts/run/tidy/run-tidy-main.ts +8 -0
- package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
- package/scripts/run/wake/run-wake-cli.ts +121 -209
- package/scripts/run/wake/run-wake-code.ts +125 -0
- package/scripts/run/wake/run-wake-driver.ts +22 -9
- package/scripts/run/wake/run-wake-finish.ts +137 -0
- package/scripts/run/wake/run-wake-loop.ts +36 -3
- package/scripts/run/wake/run-wake-main.ts +13 -0
- package/scripts/run/wake/run-wake-ports.ts +98 -0
- package/scripts/run/wake/run-wake-session.ts +2 -0
- package/scripts/run/wake/run-wake-takeover.ts +66 -0
- package/scripts/run/wake/run-wake.ts +5 -3
- package/scripts/safe-chain/ci-installer-pin.ts +49 -8
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -1
- package/scripts/safe-chain/project-config.ts +6 -11
- package/scripts/security/secretlint-scan.ts +42 -9
- package/scripts/security/security-audit-main.ts +8 -0
- package/scripts/security/security-audit-provision-logic.ts +0 -11
- package/scripts/security/security-audit-provision-main.ts +20 -0
- package/scripts/security/security-audit-provision.ts +12 -27
- package/scripts/security/security-audit.ts +27 -8
- package/scripts/security/sonar-file.ts +10 -5
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
- package/scripts/split/split-assess-cli.ts +2 -2
- package/scripts/split/split-assess.ts +25 -1
- package/scripts/split/split-early-notice.ts +116 -0
- package/scripts/split/split-measure.ts +83 -0
- package/scripts/split/split-resolution.ts +107 -0
- package/scripts/sync/claude-settings-merge.ts +8 -15
- package/scripts/sync/directory-copy-guard.ts +4 -9
- package/scripts/sync/file-content.ts +78 -8
- package/scripts/sync/sync-ai-files.ts +3 -5
- package/scripts/sync/sync-configs.ts +11 -23
- package/scripts/sync/sync-hook-safety.ts +4 -10
- package/scripts/sync/sync-main.ts +11 -0
- package/scripts/sync/sync.ts +25 -37
- package/scripts/test/direct-importers.ts +185 -0
- package/scripts/test/pure-files-entries.ts +83 -0
- package/scripts/test/related-heavy-tests.ts +81 -0
- package/scripts/test/test-declared-changed.ts +2 -2
- package/scripts/test/test-declared.ts +1 -1
- package/scripts/test/test-e2e-guard.ts +25 -1
- package/scripts/test/test-e2e-stamp.ts +38 -0
- package/scripts/test/test-no-base.ts +88 -0
- package/scripts/test/test-pinned-cache-logic.ts +363 -0
- package/scripts/test/test-pinned-cache.ts +337 -0
- package/scripts/test/test-pinned-emit.ts +49 -0
- package/scripts/test/test-pinned-functions.ts +116 -0
- package/scripts/test/test-pinned-ledger.ts +80 -0
- package/scripts/test/test-pinned-logic.ts +333 -0
- package/scripts/test/test-pinned-main.ts +144 -0
- package/scripts/test/test-pinned-pool.ts +73 -0
- package/scripts/test/test-pinned-probe.ts +254 -0
- package/scripts/test/test-pinned-prune-logic.ts +118 -0
- package/scripts/test/test-pinned-reach.ts +194 -0
- package/scripts/test/test-pinned-record.ts +196 -0
- package/scripts/test/test-pinned-rewire.ts +148 -0
- package/scripts/test/test-pinned-spawn.ts +81 -0
- package/scripts/test/test-pinned-stage.ts +70 -0
- package/scripts/test/test-pinned.ts +311 -0
- package/scripts/test/test-reach-cli.ts +61 -0
- package/scripts/test/test-read-map.ts +288 -0
- package/scripts/test/test-read-recording.ts +103 -0
- package/scripts/test/test-read-trace.ts +166 -0
- package/scripts/test/test-red-logic.ts +46 -7
- package/scripts/test/test-red-main.ts +12 -0
- package/scripts/test/test-red.ts +39 -37
- package/scripts/test/test-related-claim.ts +37 -0
- package/scripts/test/test-related-main.ts +21 -0
- package/scripts/test/test-related-moved.ts +91 -0
- package/scripts/test/test-related-record.ts +139 -0
- package/scripts/test/test-related-scope.ts +292 -41
- package/scripts/test/test-related-synced.ts +135 -0
- package/scripts/test/test-related-touched.ts +84 -0
- package/scripts/test/test-related.ts +381 -19
- package/scripts/test/test-unit-guard-main.ts +15 -0
- package/scripts/test/test-unit-guard.ts +66 -25
- package/scripts/test/unit-count-file.ts +37 -0
- package/scripts/test/unit-durations.ts +41 -0
- package/scripts/test/unit-run-marker.ts +162 -0
- package/scripts/test/unit-setup-files.ts +51 -0
- package/scripts/test/unit-worker-share.ts +64 -151
- package/scripts/test/vitest-cache-directory.ts +19 -0
- package/scripts/test/vitest-cli-excludes.ts +14 -0
- package/scripts/test/vitest-failure-summary.ts +111 -0
- package/scripts/test/whole-suite-files.ts +74 -0
- package/scripts/time-runtime/time-background.ts +20 -2
- package/scripts/time-runtime/time-batch-guard.ts +42 -4
- package/scripts/time-runtime/time-bundle-call.ts +1 -1
- package/scripts/time-runtime/time-bundles.ts +40 -8
- package/scripts/time-runtime/time-density-hook.ts +8 -6
- package/scripts/time-runtime/time-followup-stage.ts +1 -3
- package/scripts/time-runtime/time-format.ts +5 -28
- package/scripts/time-runtime/time-markers.ts +12 -3
- package/scripts/time-runtime/time-search-call.ts +38 -0
- package/scripts/time-runtime/time-shell.ts +98 -11
- package/scripts/time-runtime/time-transcript-line.ts +65 -66
- package/scripts/uninstall/uninstall.ts +1 -1
- package/scripts/version/bump-version-main.ts +12 -0
- package/scripts/version/bump-version.ts +25 -25
- package/scripts/version/development-engines-verdict.ts +124 -0
- package/scripts/version/effective-upstream.ts +6 -12
- package/scripts/version/latest-corepack.ts +19 -32
- package/scripts/version/latest-if-required-cli.ts +93 -0
- package/scripts/version/latest-lane-guard-main.ts +8 -0
- package/scripts/version/latest-lane-guard.ts +0 -4
- package/scripts/version/latest-scope-cli.ts +0 -9
- package/scripts/version/latest-scope-main.ts +12 -0
- package/scripts/version/latest-update.ts +5 -5
- package/scripts/version/npm-registry.ts +44 -6
- package/scripts/version/publishable-range-check.ts +5 -16
- package/scripts/version/release-age.ts +1 -1
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/release-window.ts +38 -0
- package/scripts/version/running-binary.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +3 -8
- package/scripts/version/version-targets.ts +6 -28
- package/templates/dependabot.yml +29 -0
- package/templates/gitignore +6 -1
- package/templates/pnpm-workspace.basic.yaml +1 -1
- package/templates/sonar-project.properties +3 -2
- package/templates/workflows/ci.yml +53 -4
- package/templates/workflows/github-release.yml +4 -0
- package/tsconfig.sonar.json +1 -1
- package/.ncurc.json +0 -3
- package/dist/hooks/batch-guard.js +0 -29
- package/dist/hooks/chunk-4KKD2UTK.js +0 -66
- package/dist/hooks/chunk-6TS2JD6D.js +0 -237
- package/dist/hooks/chunk-7DSBJVFH.js +0 -50
- package/dist/hooks/chunk-A65Y4YOR.js +0 -79
- package/dist/hooks/chunk-APUO6U4J.js +0 -2451
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-DGT54IH5.js +0 -161
- package/dist/hooks/chunk-EFXE6C37.js +0 -81
- package/dist/hooks/chunk-GP4IEC4O.js +0 -20
- package/dist/hooks/chunk-JP45SOCJ.js +0 -56
- package/dist/hooks/chunk-LAOV7NLM.js +0 -45
- package/dist/hooks/chunk-M4HGZV7U.js +0 -83
- package/dist/hooks/chunk-O6GDRNJB.js +0 -343
- package/dist/hooks/chunk-PF2NZL2A.js +0 -131
- package/dist/hooks/chunk-PTICX4OL.js +0 -358
- package/dist/hooks/chunk-RT27QRJW.js +0 -6247
- package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
- package/dist/hooks/chunk-TNUMY6NL.js +0 -4838
- package/dist/hooks/chunk-UPUZF3AN.js +0 -279
- package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -29
- package/scripts/backlog/backlog-stalled-cli.ts +0 -30
- package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
- package/scripts/cost-runtime/cost-format.ts +0 -29
- package/scripts/init/basic-path-migration.ts +0 -24
- package/scripts/issue/issue-backlinks-cli.ts +0 -93
- package/scripts/josh/josh-commands-guard.ts +0 -38
- package/scripts/josh/josh-usage-automation.ts +0 -121
- package/scripts/josh/josh-usage-backlog.ts +0 -180
- package/scripts/josh/josh-usage-developer.ts +0 -230
- package/scripts/josh/josh-usage-hooks.ts +0 -38
- package/scripts/josh/josh-usage-issue.ts +0 -205
- package/scripts/josh/josh-usage-review.ts +0 -101
- package/scripts/josh/josh-usage-run.ts +0 -252
- package/scripts/josh/josh-usage-session.ts +0 -238
- package/scripts/josh/josh-usage-workflow.ts +0 -212
- package/scripts/lint/cross-file-recheck.ts +0 -155
- package/scripts/registry-migration/migrate-logic.ts +0 -237
- package/scripts/registry-migration/migrate.ts +0 -292
- package/scripts/registry-migration/user-npmrc.ts +0 -15
- package/scripts/rules/filing-cap.ts +0 -132
- package/scripts/rules/rule-guard.ts +0 -23
- package/scripts/rules/rule-registry-rows.ts +0 -292
- package/scripts/rules/rule-registry.ts +0 -112
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -0,0 +1,2806 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PACKAGE_JSON,
|
|
3
|
+
ancestor_directories,
|
|
4
|
+
cost_transcript,
|
|
5
|
+
figure_format,
|
|
6
|
+
issue_cite,
|
|
7
|
+
json_value,
|
|
8
|
+
lane_ledger_write,
|
|
9
|
+
pr_raw_schema,
|
|
10
|
+
run_event_stream,
|
|
11
|
+
run_event_stream_emit,
|
|
12
|
+
time_instant
|
|
13
|
+
} from "./chunk-7SIUNQXK.js";
|
|
14
|
+
import {
|
|
15
|
+
MS_PER_SECOND,
|
|
16
|
+
stamp_file
|
|
17
|
+
} from "./chunk-45CJJOO7.js";
|
|
18
|
+
|
|
19
|
+
// scripts/time-runtime/time-hook-transcript.ts
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
var { TRANSCRIPT_EXTENSION } = cost_transcript;
|
|
22
|
+
var AGENT_PREFIX = "agent-";
|
|
23
|
+
var AGENT_ID_PATTERN = /^[\w-]+$/u;
|
|
24
|
+
function is_agent_id(value) {
|
|
25
|
+
return typeof value === "string" && AGENT_ID_PATTERN.test(value);
|
|
26
|
+
}
|
|
27
|
+
function fork_path(transcript_path, agent_id) {
|
|
28
|
+
const directory = path.dirname(transcript_path);
|
|
29
|
+
const session_id = path.basename(transcript_path, TRANSCRIPT_EXTENSION);
|
|
30
|
+
const file_name = `${AGENT_PREFIX}${agent_id}${TRANSCRIPT_EXTENSION}`;
|
|
31
|
+
return path.join(cost_transcript.unit_directory(directory, session_id), file_name);
|
|
32
|
+
}
|
|
33
|
+
function transcript_of(transcript_path, agent_id) {
|
|
34
|
+
if (!is_agent_id(agent_id) || !transcript_path.endsWith(TRANSCRIPT_EXTENSION)) {
|
|
35
|
+
return transcript_path;
|
|
36
|
+
}
|
|
37
|
+
return fork_path(transcript_path, agent_id);
|
|
38
|
+
}
|
|
39
|
+
var time_hook_transcript = {
|
|
40
|
+
fork_path,
|
|
41
|
+
transcript_of
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// scripts/time-runtime/time-density-hook.ts
|
|
45
|
+
import { closeSync, fstatSync, openSync, readSync } from "node:fs";
|
|
46
|
+
import { z as z4 } from "zod";
|
|
47
|
+
|
|
48
|
+
// scripts/lib/transcript-record.ts
|
|
49
|
+
import { z } from "zod";
|
|
50
|
+
var TEXT_TYPE = "text";
|
|
51
|
+
var TOOL_USE_TYPE = "tool_use";
|
|
52
|
+
var TOOL_RESULT_TYPE = "tool_result";
|
|
53
|
+
var BLOCK_SCHEMA = z.object({
|
|
54
|
+
type: z.string().nullish(),
|
|
55
|
+
text: z.string().nullish(),
|
|
56
|
+
name: z.string().nullish(),
|
|
57
|
+
id: z.string().nullish(),
|
|
58
|
+
tool_use_id: z.string().nullish(),
|
|
59
|
+
input: z.unknown().nullish(),
|
|
60
|
+
// Whether the harness wrote a `tool_result` back as a failure — absent on every other block, and
|
|
61
|
+
// on the results of tools that never report one.
|
|
62
|
+
is_error: z.boolean().nullish(),
|
|
63
|
+
// A result's body: a string or a list of blocks. Read as `unknown` because each reader flattens it
|
|
64
|
+
// its own way, and a narrower type here would drop the whole line over one odd item.
|
|
65
|
+
content: z.unknown().nullish()
|
|
66
|
+
});
|
|
67
|
+
var CONTENT_SCHEMA = z.union([z.string(), z.array(BLOCK_SCHEMA)]);
|
|
68
|
+
var MESSAGE_SCHEMA = z.object({ id: z.string().nullish(), content: CONTENT_SCHEMA.nullish() });
|
|
69
|
+
var LINE_SCHEMA = z.object({
|
|
70
|
+
type: z.string().nullish(),
|
|
71
|
+
timestamp: z.string().nullish(),
|
|
72
|
+
gitBranch: z.string().nullish(),
|
|
73
|
+
// The two fields outside `message` the harness writes an end-of-task notice on. `unknown`, since a
|
|
74
|
+
// string here would reject every line whose `content` is a list of blocks.
|
|
75
|
+
content: z.unknown().nullish(),
|
|
76
|
+
attachment: z.unknown().nullish(),
|
|
77
|
+
message: MESSAGE_SCHEMA.nullish()
|
|
78
|
+
});
|
|
79
|
+
function read(value) {
|
|
80
|
+
return LINE_SCHEMA.safeParse(value).data;
|
|
81
|
+
}
|
|
82
|
+
function parse(line) {
|
|
83
|
+
return read(json_value.parse_or_undefined(line));
|
|
84
|
+
}
|
|
85
|
+
function blocks_of(record2) {
|
|
86
|
+
const content = record2.message?.content;
|
|
87
|
+
return Array.isArray(content) ? content : [];
|
|
88
|
+
}
|
|
89
|
+
function is_tool_call(block) {
|
|
90
|
+
return block.type === TOOL_USE_TYPE && typeof block.name === "string";
|
|
91
|
+
}
|
|
92
|
+
function tool_calls_of(record2) {
|
|
93
|
+
return blocks_of(record2).filter((block) => is_tool_call(block));
|
|
94
|
+
}
|
|
95
|
+
var transcript_record = {
|
|
96
|
+
TEXT_TYPE,
|
|
97
|
+
TOOL_USE_TYPE,
|
|
98
|
+
TOOL_RESULT_TYPE,
|
|
99
|
+
read,
|
|
100
|
+
parse,
|
|
101
|
+
blocks_of,
|
|
102
|
+
tool_calls_of
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// scripts/cost-runtime/cost-blocks.ts
|
|
106
|
+
import { z as z2 } from "zod";
|
|
107
|
+
var CONTENT_ITEM_SCHEMA = z2.object({ text: z2.string().nullish() });
|
|
108
|
+
var RESULT_CONTENT_SCHEMA = z2.union([z2.string(), z2.array(CONTENT_ITEM_SCHEMA)]);
|
|
109
|
+
var { TEXT_TYPE: TEXT_TYPE2, TOOL_USE_TYPE: TOOL_USE_TYPE2, TOOL_RESULT_TYPE: TOOL_RESULT_TYPE2 } = transcript_record;
|
|
110
|
+
var BASH_TOOL = "Bash";
|
|
111
|
+
var COMMAND_KEY = "command";
|
|
112
|
+
function json_of(value) {
|
|
113
|
+
return value === void 0 || value === null ? "" : JSON.stringify(value);
|
|
114
|
+
}
|
|
115
|
+
function split_bash_input(input) {
|
|
116
|
+
if (!json_value.is_record(input)) return { command: "", rest: json_of(input) };
|
|
117
|
+
const command = input[COMMAND_KEY];
|
|
118
|
+
const rest = Object.entries(input).filter(([key]) => key !== COMMAND_KEY);
|
|
119
|
+
return {
|
|
120
|
+
command: typeof command === "string" ? command : "",
|
|
121
|
+
rest: json_of(Object.fromEntries(rest))
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function to_tool_use(block) {
|
|
125
|
+
const tool_name = block.name ?? "";
|
|
126
|
+
const is_bash = tool_name === BASH_TOOL;
|
|
127
|
+
const { command, rest } = is_bash ? split_bash_input(block.input) : { command: "", rest: json_of(block.input) };
|
|
128
|
+
return { type: TOOL_USE_TYPE2, tool_name, command, text: rest };
|
|
129
|
+
}
|
|
130
|
+
function result_text(content) {
|
|
131
|
+
const parsed = RESULT_CONTENT_SCHEMA.safeParse(content);
|
|
132
|
+
if (!parsed.success) return "";
|
|
133
|
+
if (typeof parsed.data === "string") return parsed.data;
|
|
134
|
+
return parsed.data.map((item) => item.text ?? "").join("");
|
|
135
|
+
}
|
|
136
|
+
function to_plain_block(block) {
|
|
137
|
+
const base = { type: block.type ?? "", tool_name: "", command: "" };
|
|
138
|
+
const text = block.type === TOOL_RESULT_TYPE2 ? result_text(block.content) : block.text ?? "";
|
|
139
|
+
return { ...base, text };
|
|
140
|
+
}
|
|
141
|
+
function to_block(block) {
|
|
142
|
+
return block.type === TOOL_USE_TYPE2 ? to_tool_use(block) : to_plain_block(block);
|
|
143
|
+
}
|
|
144
|
+
function to_blocks(content) {
|
|
145
|
+
if (typeof content === "string") {
|
|
146
|
+
return [{ type: TEXT_TYPE2, tool_name: "", command: "", text: content }];
|
|
147
|
+
}
|
|
148
|
+
return content.map((block) => to_block(block));
|
|
149
|
+
}
|
|
150
|
+
function content_of(line) {
|
|
151
|
+
return transcript_record.parse(line)?.message?.content ?? void 0;
|
|
152
|
+
}
|
|
153
|
+
function parse_line(line) {
|
|
154
|
+
const content = content_of(line);
|
|
155
|
+
return content === void 0 ? [] : to_blocks(content);
|
|
156
|
+
}
|
|
157
|
+
function parse_content(text) {
|
|
158
|
+
return text.split("\n").flatMap((line) => parse_line(line));
|
|
159
|
+
}
|
|
160
|
+
var cost_blocks = {
|
|
161
|
+
BASH_TOOL,
|
|
162
|
+
TEXT_TYPE: TEXT_TYPE2,
|
|
163
|
+
TOOL_USE_TYPE: TOOL_USE_TYPE2,
|
|
164
|
+
TOOL_RESULT_TYPE: TOOL_RESULT_TYPE2,
|
|
165
|
+
parse_line,
|
|
166
|
+
parse_content
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// scripts/josh/josh-aliases.ts
|
|
170
|
+
var ALIASES = {
|
|
171
|
+
ga: "gate",
|
|
172
|
+
l: "lint",
|
|
173
|
+
lr: "lint:related",
|
|
174
|
+
cr: "check:related",
|
|
175
|
+
ln: "lines",
|
|
176
|
+
by: "bytes",
|
|
177
|
+
mt: "metrics",
|
|
178
|
+
f: "format",
|
|
179
|
+
sd: "cspell:dot",
|
|
180
|
+
bh: "behavior",
|
|
181
|
+
eu: "exports:unused",
|
|
182
|
+
t: "test",
|
|
183
|
+
tu: "test:unit",
|
|
184
|
+
tr: "test:related",
|
|
185
|
+
td: "test:declared",
|
|
186
|
+
trd: "test:red",
|
|
187
|
+
tpn: "test:pinned",
|
|
188
|
+
te: "test:e2e",
|
|
189
|
+
c: "check",
|
|
190
|
+
pt: "port",
|
|
191
|
+
i: "init",
|
|
192
|
+
pf: "profile",
|
|
193
|
+
st: "start",
|
|
194
|
+
sy: "sync",
|
|
195
|
+
un: "uninstall",
|
|
196
|
+
g: "git",
|
|
197
|
+
gp: "pr",
|
|
198
|
+
ms: "main:sync",
|
|
199
|
+
mm: "main:merge",
|
|
200
|
+
bp: "bump",
|
|
201
|
+
re: "release",
|
|
202
|
+
v: "version",
|
|
203
|
+
r: "ranges",
|
|
204
|
+
dr: "doctor",
|
|
205
|
+
rc: "ruleset:check",
|
|
206
|
+
pg: "propagate",
|
|
207
|
+
ad: "adopt",
|
|
208
|
+
ov: "overrides",
|
|
209
|
+
a: "audit",
|
|
210
|
+
rt: "reconcile-templates",
|
|
211
|
+
cdv: "command:derive",
|
|
212
|
+
u: "latest",
|
|
213
|
+
lc: "latest:corepack",
|
|
214
|
+
lu: "latest:update",
|
|
215
|
+
tm: "time",
|
|
216
|
+
tmd: "time:density",
|
|
217
|
+
rtr: "retrospective",
|
|
218
|
+
ca: "cost:audit",
|
|
219
|
+
rvf: "review:findings",
|
|
220
|
+
rvs: "review:stops",
|
|
221
|
+
ruv: "rule:value",
|
|
222
|
+
ev: "eval",
|
|
223
|
+
fr: "fresh:run",
|
|
224
|
+
as: "auth:setup",
|
|
225
|
+
lsm: "lane:sample",
|
|
226
|
+
lst: "lane:stats",
|
|
227
|
+
lva: "lane:value",
|
|
228
|
+
lnt: "lane:net",
|
|
229
|
+
lbd: "lane:breakdown",
|
|
230
|
+
lli: "lane:limit",
|
|
231
|
+
lrs: "lane:restart",
|
|
232
|
+
lwd: "lane:withdraw",
|
|
233
|
+
lps: "lane:pause",
|
|
234
|
+
lru: "lane:resume",
|
|
235
|
+
lad: "lane:adopt",
|
|
236
|
+
blr: "backlogrun"
|
|
237
|
+
};
|
|
238
|
+
function canonical_command(name) {
|
|
239
|
+
if (!Object.hasOwn(ALIASES, name)) return name;
|
|
240
|
+
return ALIASES[name] ?? name;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// scripts/time-runtime/time-shell.ts
|
|
244
|
+
var BASH_SEPARATOR = ": ";
|
|
245
|
+
var WHITESPACE_PATTERN = /\s+/u;
|
|
246
|
+
var SEGMENT_PATTERN = /&&|\|\||;|\|/u;
|
|
247
|
+
var PIPE_PATTERN = /(?<!\|)\|(?!\|)/u;
|
|
248
|
+
var CHAIN_PATTERN = /&&|\|\||;|\n/u;
|
|
249
|
+
var SUBSTITUTION_ATOM = /\$\([^()]*\)/u;
|
|
250
|
+
var LONE_DOLLAR = /\$(?!\([^()]*\))/u;
|
|
251
|
+
var QUOTED_SPAN_PATTERN = new RegExp(
|
|
252
|
+
String.raw`\\[\s\S]|'[^']*'|"(?:\\[\s\S]|${SUBSTITUTION_ATOM.source}|${LONE_DOLLAR.source}|[^"\\$])*"`,
|
|
253
|
+
"gu"
|
|
254
|
+
);
|
|
255
|
+
var HEREDOC_MARKER = /(?<!<)<<-?\s*(['"]?)(\w+)\1/u;
|
|
256
|
+
var HEREDOC_DELIMITER_GROUP = 2;
|
|
257
|
+
var LINE_BREAK = "\n";
|
|
258
|
+
var DOUBLE_QUOTE = '"';
|
|
259
|
+
var SUBSTITUTION_PATTERN = /(?<!\\)\$\((?<dollar>[^()]*)\)|(?<!\\)`(?<tick>[^`]*)`/gu;
|
|
260
|
+
var PIPEFAIL_PATTERN = /\bset\s+-[a-z]*o\s+pipefail\b/u;
|
|
261
|
+
var COMMAND_WORD_PATTERN = /^[\w./@:+][\w./@:+-]*$/u;
|
|
262
|
+
var ASSIGNMENT_PATTERN = /^\w+=/u;
|
|
263
|
+
var SUBSHELL_OPENER = "$(";
|
|
264
|
+
var FLAG_PREFIX = "-";
|
|
265
|
+
var WRAPPER_COMMANDS = /* @__PURE__ */ new Map([
|
|
266
|
+
["time", { valued: /* @__PURE__ */ new Set(["-f", "-o", "--format", "--output"]), operands: 0 }],
|
|
267
|
+
["env", { valued: /* @__PURE__ */ new Set(["-u", "-C", "-S", "--unset", "--chdir"]), operands: 0 }],
|
|
268
|
+
["sudo", { valued: /* @__PURE__ */ new Set(["-u", "-g", "-C", "-D"]), operands: 0 }],
|
|
269
|
+
["timeout", { valued: /* @__PURE__ */ new Set(["-s", "-k", "--signal", "--kill-after"]), operands: 1 }],
|
|
270
|
+
["nohup", { valued: /* @__PURE__ */ new Set(), operands: 0 }],
|
|
271
|
+
["nice", { valued: /* @__PURE__ */ new Set(["-n", "--adjustment"]), operands: 0 }],
|
|
272
|
+
["command", { valued: /* @__PURE__ */ new Set(), operands: 0 }],
|
|
273
|
+
["exec", { valued: /* @__PURE__ */ new Set(["-a"]), operands: 0 }],
|
|
274
|
+
["stdbuf", { valued: /* @__PURE__ */ new Set(["-i", "-o", "-e"]), operands: 0 }]
|
|
275
|
+
]);
|
|
276
|
+
var NAVIGATION_COMMANDS = /* @__PURE__ */ new Set(["cd", "pushd", "popd", "export", "source", "set", "."]);
|
|
277
|
+
var PATH_SEPARATOR = "/";
|
|
278
|
+
var FLAG_AND_VALUE = 2;
|
|
279
|
+
var JOSH_PATTERN = /^(?:(?:pnpm|npx)\s+(?:exec\s+)?)?josh\s+([a-z][\w:-]*)/u;
|
|
280
|
+
var JOSH_PREFIX = "josh ";
|
|
281
|
+
var COMMAND_KEY2 = "command";
|
|
282
|
+
function bash_command(input) {
|
|
283
|
+
if (!json_value.is_record(input)) return "";
|
|
284
|
+
const command = input[COMMAND_KEY2];
|
|
285
|
+
return typeof command === "string" ? command : "";
|
|
286
|
+
}
|
|
287
|
+
function after_flags(words, start, valued) {
|
|
288
|
+
let index = start;
|
|
289
|
+
while (words[index]?.startsWith(FLAG_PREFIX) === true) {
|
|
290
|
+
index += valued.has(words[index] ?? "") ? FLAG_AND_VALUE : 1;
|
|
291
|
+
}
|
|
292
|
+
return index;
|
|
293
|
+
}
|
|
294
|
+
function after_prefix_word(words, index) {
|
|
295
|
+
const word = words[index] ?? "";
|
|
296
|
+
if (word.startsWith(FLAG_PREFIX) || ASSIGNMENT_PATTERN.test(word)) return index + 1;
|
|
297
|
+
const wrapper = WRAPPER_COMMANDS.get(word.slice(word.lastIndexOf(PATH_SEPARATOR) + 1));
|
|
298
|
+
if (wrapper === void 0) return index;
|
|
299
|
+
return after_flags(words, index + 1, wrapper.valued) + wrapper.operands;
|
|
300
|
+
}
|
|
301
|
+
function command_words(segment) {
|
|
302
|
+
const words = segment.replaceAll(SUBSHELL_OPENER, " ").trim().split(WHITESPACE_PATTERN);
|
|
303
|
+
let start = 0;
|
|
304
|
+
for (let next = after_prefix_word(words, start); next !== start; ) {
|
|
305
|
+
start = next;
|
|
306
|
+
next = after_prefix_word(words, start);
|
|
307
|
+
}
|
|
308
|
+
return words.slice(start);
|
|
309
|
+
}
|
|
310
|
+
function segment_command(segment) {
|
|
311
|
+
const [head] = command_words(segment);
|
|
312
|
+
if (head === void 0 || NAVIGATION_COMMANDS.has(head)) return "";
|
|
313
|
+
return COMMAND_WORD_PATTERN.test(head) ? head : "";
|
|
314
|
+
}
|
|
315
|
+
function command_segment(command) {
|
|
316
|
+
return command.split(SEGMENT_PATTERN).find((segment) => segment_command(segment) !== "") ?? "";
|
|
317
|
+
}
|
|
318
|
+
function leading_word(command) {
|
|
319
|
+
return segment_command(command_segment(command));
|
|
320
|
+
}
|
|
321
|
+
function open_heredoc(line, kept) {
|
|
322
|
+
kept.push(line.replace(HEREDOC_MARKER, " "));
|
|
323
|
+
return HEREDOC_MARKER.exec(line)?.[HEREDOC_DELIMITER_GROUP];
|
|
324
|
+
}
|
|
325
|
+
function close_heredoc(line, delimiter) {
|
|
326
|
+
return line.trim() === delimiter ? void 0 : delimiter;
|
|
327
|
+
}
|
|
328
|
+
function without_heredoc_bodies(command) {
|
|
329
|
+
const kept = [];
|
|
330
|
+
const body = {};
|
|
331
|
+
for (const line of command.split(LINE_BREAK)) {
|
|
332
|
+
body.delimiter = body.delimiter === void 0 ? open_heredoc(line, kept) : close_heredoc(line, body.delimiter);
|
|
333
|
+
}
|
|
334
|
+
return kept.join(LINE_BREAK);
|
|
335
|
+
}
|
|
336
|
+
function spoken_substitutions(span) {
|
|
337
|
+
if (!span.startsWith(DOUBLE_QUOTE)) return " ";
|
|
338
|
+
const inner = [...span.matchAll(SUBSTITUTION_PATTERN)].map(
|
|
339
|
+
(match) => (match.groups?.["dollar"] ?? match.groups?.["tick"] ?? "").replaceAll(QUOTED_SPAN_PATTERN, " ")
|
|
340
|
+
);
|
|
341
|
+
return inner.length === 0 ? " " : ` ; ${inner.join(" ; ")} ; `;
|
|
342
|
+
}
|
|
343
|
+
function unquoted(command) {
|
|
344
|
+
return without_heredoc_bodies(command).replaceAll(
|
|
345
|
+
QUOTED_SPAN_PATTERN,
|
|
346
|
+
(span) => spoken_substitutions(span)
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
function has_heredoc(command) {
|
|
350
|
+
return HEREDOC_MARKER.test(command);
|
|
351
|
+
}
|
|
352
|
+
function blanked(command) {
|
|
353
|
+
if (has_heredoc(command)) return void 0;
|
|
354
|
+
return command.replaceAll(QUOTED_SPAN_PATTERN, (span) => " ".repeat(span.length));
|
|
355
|
+
}
|
|
356
|
+
function discarded_commands(command) {
|
|
357
|
+
const plain = unquoted(command);
|
|
358
|
+
if (PIPEFAIL_PATTERN.test(plain)) return [];
|
|
359
|
+
return plain.split(PIPE_PATTERN).slice(0, -1).map((segment) => segment.split(CHAIN_PATTERN).at(-1) ?? "");
|
|
360
|
+
}
|
|
361
|
+
function bash_label(command) {
|
|
362
|
+
const word = leading_word(command);
|
|
363
|
+
return word === "" ? cost_blocks.BASH_TOOL : `${cost_blocks.BASH_TOOL}${BASH_SEPARATOR}${word}`;
|
|
364
|
+
}
|
|
365
|
+
function josh_command_of_segment(segment) {
|
|
366
|
+
const name = JOSH_PATTERN.exec(command_words(segment).join(" "))?.[1];
|
|
367
|
+
return name === void 0 ? "" : `${JOSH_PREFIX}${canonical_command(name)}`;
|
|
368
|
+
}
|
|
369
|
+
function josh_command_of(command) {
|
|
370
|
+
return josh_command_of_segment(command_segment(command));
|
|
371
|
+
}
|
|
372
|
+
function josh_commands_of(command) {
|
|
373
|
+
return unquoted(command).split(SEGMENT_PATTERN).map((segment) => josh_command_of_segment(segment)).filter((name) => name !== "");
|
|
374
|
+
}
|
|
375
|
+
var REDIRECTION_CHARACTERS = ["<", ">"];
|
|
376
|
+
function is_redirection(word) {
|
|
377
|
+
return REDIRECTION_CHARACTERS.some((character) => word.includes(character));
|
|
378
|
+
}
|
|
379
|
+
function ends_in_redirection(word) {
|
|
380
|
+
return REDIRECTION_CHARACTERS.some((character) => word.endsWith(character));
|
|
381
|
+
}
|
|
382
|
+
function drop_redirections(words) {
|
|
383
|
+
const kept = [];
|
|
384
|
+
let is_target2 = false;
|
|
385
|
+
for (const word of words) {
|
|
386
|
+
const is_dropped = is_target2 || is_redirection(word);
|
|
387
|
+
is_target2 = ends_in_redirection(word);
|
|
388
|
+
if (!is_dropped) kept.push(word);
|
|
389
|
+
}
|
|
390
|
+
return kept;
|
|
391
|
+
}
|
|
392
|
+
function josh_arguments_of_segment(segment) {
|
|
393
|
+
const text = command_words(segment).join(" ");
|
|
394
|
+
const match = JOSH_PATTERN.exec(text);
|
|
395
|
+
if (match === null) return [];
|
|
396
|
+
const words = text.slice(match[0].length).split(WHITESPACE_PATTERN).filter((word) => word !== "");
|
|
397
|
+
return drop_redirections(words);
|
|
398
|
+
}
|
|
399
|
+
function josh_arguments(command) {
|
|
400
|
+
return josh_arguments_of_segment(command_segment(command));
|
|
401
|
+
}
|
|
402
|
+
function josh_signature_of_segment(segment) {
|
|
403
|
+
const name = josh_command_of_segment(segment);
|
|
404
|
+
if (name === "") return "";
|
|
405
|
+
return [name, ...josh_arguments_of_segment(segment)].join(" ");
|
|
406
|
+
}
|
|
407
|
+
function josh_signatures_of(command) {
|
|
408
|
+
return unquoted(command).split(SEGMENT_PATTERN).map((segment) => josh_signature_of_segment(segment)).filter((signature) => signature !== "");
|
|
409
|
+
}
|
|
410
|
+
var time_shell = {
|
|
411
|
+
JOSH_PREFIX,
|
|
412
|
+
bash_command,
|
|
413
|
+
bash_label,
|
|
414
|
+
blanked,
|
|
415
|
+
command_segment,
|
|
416
|
+
discarded_commands,
|
|
417
|
+
has_heredoc,
|
|
418
|
+
josh_arguments,
|
|
419
|
+
josh_command_of,
|
|
420
|
+
josh_command_of_segment,
|
|
421
|
+
josh_commands_of,
|
|
422
|
+
josh_signatures_of,
|
|
423
|
+
leading_word,
|
|
424
|
+
unquoted,
|
|
425
|
+
without_heredoc_bodies
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
// scripts/time-runtime/time-bundle-call.ts
|
|
429
|
+
var { BASH_TOOL: BASH_TOOL2 } = cost_blocks;
|
|
430
|
+
var BUNDLEABLE_TOOLS = /* @__PURE__ */ new Set(["Edit", "Glob", "Grep", "Read", "WebFetch", "WebSearch", "Write"]);
|
|
431
|
+
var LAUNCH_TOOLS = /* @__PURE__ */ new Set(["Agent", "Task"]);
|
|
432
|
+
var PRIOR_REFERENCE_MARKERS = [
|
|
433
|
+
"previous finding",
|
|
434
|
+
"prior finding",
|
|
435
|
+
"earlier finding",
|
|
436
|
+
"previous result",
|
|
437
|
+
"prior result",
|
|
438
|
+
"earlier result",
|
|
439
|
+
"based on the previous",
|
|
440
|
+
"based on the earlier",
|
|
441
|
+
"from the previous agent",
|
|
442
|
+
"from the prior agent",
|
|
443
|
+
"the finding above",
|
|
444
|
+
"as found earlier",
|
|
445
|
+
"as found above",
|
|
446
|
+
"building on the previous"
|
|
447
|
+
];
|
|
448
|
+
var READ_COMMANDS = /* @__PURE__ */ new Set([
|
|
449
|
+
"awk",
|
|
450
|
+
"basename",
|
|
451
|
+
"cat",
|
|
452
|
+
"comm",
|
|
453
|
+
"cut",
|
|
454
|
+
"diff",
|
|
455
|
+
"dirname",
|
|
456
|
+
"du",
|
|
457
|
+
"echo",
|
|
458
|
+
"file",
|
|
459
|
+
"find",
|
|
460
|
+
"gh",
|
|
461
|
+
"grep",
|
|
462
|
+
"head",
|
|
463
|
+
"jq",
|
|
464
|
+
"ls",
|
|
465
|
+
"nl",
|
|
466
|
+
"printf",
|
|
467
|
+
"pwd",
|
|
468
|
+
"realpath",
|
|
469
|
+
"rg",
|
|
470
|
+
// **`sed -i` is deliberately not excluded.** An in-place edit is what `Edit` does, and `Edit` is on
|
|
471
|
+
// the allow-list above — a turn may issue several of them, so rejecting the shell spelling of the
|
|
472
|
+
// same thing would exclude a call the tool form counts. Two in-place edits of the *same* file are
|
|
473
|
+
// caught by the target test instead, which is where that ordering actually lives.
|
|
474
|
+
"sed",
|
|
475
|
+
"sort",
|
|
476
|
+
"stat",
|
|
477
|
+
"tail",
|
|
478
|
+
"tree",
|
|
479
|
+
"uniq",
|
|
480
|
+
"wc",
|
|
481
|
+
"which"
|
|
482
|
+
]);
|
|
483
|
+
var MUTATION_WORDS = /* @__PURE__ */ new Set([
|
|
484
|
+
"--field",
|
|
485
|
+
"--method",
|
|
486
|
+
"--raw-field",
|
|
487
|
+
"-F",
|
|
488
|
+
"-X",
|
|
489
|
+
"-delete",
|
|
490
|
+
"-exec",
|
|
491
|
+
"-f",
|
|
492
|
+
"add",
|
|
493
|
+
"chmod",
|
|
494
|
+
"chown",
|
|
495
|
+
"close",
|
|
496
|
+
"comment",
|
|
497
|
+
"cp",
|
|
498
|
+
"create",
|
|
499
|
+
"dd",
|
|
500
|
+
"delete",
|
|
501
|
+
"edit",
|
|
502
|
+
"git",
|
|
503
|
+
"install",
|
|
504
|
+
"kill",
|
|
505
|
+
"ln",
|
|
506
|
+
"merge",
|
|
507
|
+
"mkdir",
|
|
508
|
+
"mv",
|
|
509
|
+
"node",
|
|
510
|
+
"npm",
|
|
511
|
+
"npx",
|
|
512
|
+
"pkill",
|
|
513
|
+
"pnpm",
|
|
514
|
+
"remove",
|
|
515
|
+
"rm",
|
|
516
|
+
"scp",
|
|
517
|
+
"secret",
|
|
518
|
+
"set",
|
|
519
|
+
"ssh",
|
|
520
|
+
"sudo",
|
|
521
|
+
"tee",
|
|
522
|
+
"touch",
|
|
523
|
+
"truncate",
|
|
524
|
+
"tsx",
|
|
525
|
+
"upload",
|
|
526
|
+
"wget"
|
|
527
|
+
]);
|
|
528
|
+
var READ_JOSH_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
529
|
+
"backlog:budget",
|
|
530
|
+
"backlog:next",
|
|
531
|
+
"cost",
|
|
532
|
+
"delegate",
|
|
533
|
+
"epic:audit",
|
|
534
|
+
"epic:bundle",
|
|
535
|
+
"epic:check",
|
|
536
|
+
"epic:next",
|
|
537
|
+
"issue:read",
|
|
538
|
+
"issue:scout",
|
|
539
|
+
"issue:state",
|
|
540
|
+
"lane:list",
|
|
541
|
+
"latest:scope",
|
|
542
|
+
"release:scope",
|
|
543
|
+
"review:brief",
|
|
544
|
+
"review:round2",
|
|
545
|
+
"run:liveness"
|
|
546
|
+
]);
|
|
547
|
+
var JOSH_WORD = "josh";
|
|
548
|
+
var JOSH_SCRIPT_SUFFIX = "josh.ts";
|
|
549
|
+
var COMMAND_CHAIN = /[|;&`>]|\$\(/u;
|
|
550
|
+
var WHITESPACE_PATTERN2 = /\s+/u;
|
|
551
|
+
var TARGET_FIELDS = ["file_path", "notebook_path", "path", "url"];
|
|
552
|
+
var TARGET_ARRAY_FIELD = "file_paths";
|
|
553
|
+
var MAX_TARGETS = 8;
|
|
554
|
+
var WORD_PATTERN = /[\s'"=(),;:|&]+/u;
|
|
555
|
+
var EXTENSION_PATTERN = /^[A-Za-z]+$/u;
|
|
556
|
+
var MAX_EXTENSION = 5;
|
|
557
|
+
var AFTER_DOT = 1;
|
|
558
|
+
var FIRST_INDEX = 0;
|
|
559
|
+
var CURRENT_DIRECTORY = "./";
|
|
560
|
+
var LAST_CHARACTER = -1;
|
|
561
|
+
var FLAG_PREFIX2 = "-";
|
|
562
|
+
var PATH_SEPARATOR2 = "/";
|
|
563
|
+
var MIN_TARGET_LENGTH = 3;
|
|
564
|
+
var WRITING_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "NotebookEdit"]);
|
|
565
|
+
var WRITING_WORDS = /* @__PURE__ */ new Set(["dd", "sed", "tee"]);
|
|
566
|
+
var REDIRECTION = ">";
|
|
567
|
+
var IN_PLACE_COMMAND = "sed";
|
|
568
|
+
var IN_PLACE_FLAG_PATTERN = /^--in-place\b|^-[A-Za-z]*i/u;
|
|
569
|
+
function not_bundleable() {
|
|
570
|
+
return {
|
|
571
|
+
is_bundleable: false,
|
|
572
|
+
targets: [],
|
|
573
|
+
is_writing: false,
|
|
574
|
+
may_write: false,
|
|
575
|
+
has_prior_reference: false
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
function is_launch_tool(name) {
|
|
579
|
+
return LAUNCH_TOOLS.has(name);
|
|
580
|
+
}
|
|
581
|
+
function words_of(command) {
|
|
582
|
+
return command.split(WORD_PATTERN).filter((word) => word !== "");
|
|
583
|
+
}
|
|
584
|
+
function has_mutation(command) {
|
|
585
|
+
return words_of(command).some((word) => MUTATION_WORDS.has(word));
|
|
586
|
+
}
|
|
587
|
+
function josh_subcommand(command) {
|
|
588
|
+
const tokens = command.split(WHITESPACE_PATTERN2).filter((token) => token !== "");
|
|
589
|
+
const josh_index = tokens.findIndex(
|
|
590
|
+
(token) => token === JOSH_WORD || token.endsWith(JOSH_SCRIPT_SUFFIX)
|
|
591
|
+
);
|
|
592
|
+
return josh_index < FIRST_INDEX ? void 0 : tokens[josh_index + 1];
|
|
593
|
+
}
|
|
594
|
+
function is_read_josh(command) {
|
|
595
|
+
if (COMMAND_CHAIN.test(command)) return false;
|
|
596
|
+
const subcommand = josh_subcommand(command);
|
|
597
|
+
if (subcommand === void 0) return false;
|
|
598
|
+
return READ_JOSH_SUBCOMMANDS.has(canonical_command(subcommand));
|
|
599
|
+
}
|
|
600
|
+
function may_write_command(command) {
|
|
601
|
+
if (command.includes(REDIRECTION)) return true;
|
|
602
|
+
return words_of(command).some((word) => WRITING_WORDS.has(word));
|
|
603
|
+
}
|
|
604
|
+
function write_segment(command) {
|
|
605
|
+
return time_shell.command_segment(time_shell.unquoted(command));
|
|
606
|
+
}
|
|
607
|
+
function is_in_place_sed(segment) {
|
|
608
|
+
if (time_shell.leading_word(segment) !== IN_PLACE_COMMAND) return false;
|
|
609
|
+
return words_of(segment).some((word) => IN_PLACE_FLAG_PATTERN.test(word));
|
|
610
|
+
}
|
|
611
|
+
function normalize(word) {
|
|
612
|
+
const head = word.startsWith(CURRENT_DIRECTORY) ? word.slice(CURRENT_DIRECTORY.length) : word;
|
|
613
|
+
return head.endsWith(PATH_SEPARATOR2) ? head.slice(0, LAST_CHARACTER) : head;
|
|
614
|
+
}
|
|
615
|
+
function has_extension(word) {
|
|
616
|
+
const dot = word.lastIndexOf(".");
|
|
617
|
+
if (dot <= FIRST_INDEX) return false;
|
|
618
|
+
const suffix = word.slice(dot + AFTER_DOT);
|
|
619
|
+
return suffix.length <= MAX_EXTENSION && EXTENSION_PATTERN.test(suffix);
|
|
620
|
+
}
|
|
621
|
+
function is_target(word) {
|
|
622
|
+
if (word.startsWith(FLAG_PREFIX2) || word.length < MIN_TARGET_LENGTH) return false;
|
|
623
|
+
return word.includes(PATH_SEPARATOR2) || has_extension(word);
|
|
624
|
+
}
|
|
625
|
+
function targets_in(text) {
|
|
626
|
+
return words_of(text).map((word) => normalize(word)).filter((word) => is_target(word)).slice(0, MAX_TARGETS);
|
|
627
|
+
}
|
|
628
|
+
function field_text(input, field) {
|
|
629
|
+
if (!json_value.is_record(input)) return "";
|
|
630
|
+
const value = input[field];
|
|
631
|
+
return typeof value === "string" ? value : "";
|
|
632
|
+
}
|
|
633
|
+
function field_targets(input) {
|
|
634
|
+
if (!json_value.is_record(input)) return [];
|
|
635
|
+
const value = input[TARGET_ARRAY_FIELD];
|
|
636
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
|
|
637
|
+
}
|
|
638
|
+
function tool_targets(input) {
|
|
639
|
+
const scalar_targets = TARGET_FIELDS.map((field) => field_text(input, field));
|
|
640
|
+
const targets = [...scalar_targets, ...field_targets(input)].map((target) => normalize(target));
|
|
641
|
+
return [...new Set(targets)].filter((target) => target !== "");
|
|
642
|
+
}
|
|
643
|
+
function prompt_references_prior(input) {
|
|
644
|
+
const prompt = field_text(input, "prompt").toLowerCase();
|
|
645
|
+
return PRIOR_REFERENCE_MARKERS.some((marker) => prompt.includes(marker));
|
|
646
|
+
}
|
|
647
|
+
function tool_facts(name, input) {
|
|
648
|
+
const writes = { is_writing: WRITING_TOOLS.has(name), may_write: WRITING_TOOLS.has(name) };
|
|
649
|
+
const has_prior_reference = LAUNCH_TOOLS.has(name) && prompt_references_prior(input);
|
|
650
|
+
if (!BUNDLEABLE_TOOLS.has(name)) return { ...not_bundleable(), ...writes, has_prior_reference };
|
|
651
|
+
return { is_bundleable: true, targets: tool_targets(input), ...writes, has_prior_reference };
|
|
652
|
+
}
|
|
653
|
+
function bash_facts(command) {
|
|
654
|
+
const writes = {
|
|
655
|
+
is_writing: is_in_place_sed(write_segment(command)),
|
|
656
|
+
may_write: may_write_command(command)
|
|
657
|
+
};
|
|
658
|
+
if (is_read_josh(command)) {
|
|
659
|
+
return {
|
|
660
|
+
is_bundleable: true,
|
|
661
|
+
targets: targets_in(time_shell.unquoted(command)),
|
|
662
|
+
...writes,
|
|
663
|
+
has_prior_reference: false
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
if (!READ_COMMANDS.has(time_shell.leading_word(command)) || has_mutation(command)) {
|
|
667
|
+
return { ...not_bundleable(), ...writes };
|
|
668
|
+
}
|
|
669
|
+
return {
|
|
670
|
+
is_bundleable: true,
|
|
671
|
+
targets: targets_in(time_shell.unquoted(command)),
|
|
672
|
+
...writes,
|
|
673
|
+
has_prior_reference: false
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
function call_facts(name, input) {
|
|
677
|
+
if (name !== BASH_TOOL2) return tool_facts(name, input);
|
|
678
|
+
return bash_facts(time_shell.bash_command(input));
|
|
679
|
+
}
|
|
680
|
+
var time_bundle_call = {
|
|
681
|
+
MAX_TARGETS,
|
|
682
|
+
not_bundleable,
|
|
683
|
+
bash_facts,
|
|
684
|
+
call_facts,
|
|
685
|
+
tool_facts,
|
|
686
|
+
// Exported for `time-agent-bundles.ts`, which asks the launch question of a
|
|
687
|
+
// span's `label` — the tool name for a non-Bash call — so the set lives in one place.
|
|
688
|
+
is_launch_tool,
|
|
689
|
+
// Exported for `time-writes.ts`, which asks what a call *wrote* rather
|
|
690
|
+
// than what it named. The extraction is the same one either way — a second copy of it would let a
|
|
691
|
+
// path be recognized as a target when read and missed when written.
|
|
692
|
+
targets_in,
|
|
693
|
+
tool_targets,
|
|
694
|
+
// Exported for the batching guard's own word scan, so the two scanners
|
|
695
|
+
// cannot come to disagree about where one word of a shell line ends and the next begins.
|
|
696
|
+
// Exported for the read-fold notice, which offers `read:files <path>` only
|
|
697
|
+
// over file-shaped targets — a bare directory like `scripts/` is a target here but not something
|
|
698
|
+
// `read:files` can read, so the notice reuses this test rather than keep a second copy that could
|
|
699
|
+
// drift from what counts as a file path.
|
|
700
|
+
has_extension,
|
|
701
|
+
// Exported for `time-writes.ts`, which needs the same two answers to say
|
|
702
|
+
// *which* files an in-place `sed` wrote. Two copies of this test disagreed in both directions at
|
|
703
|
+
// once — one called a piped `grep -i` a write, the other missed a bundled `sed -ni`.
|
|
704
|
+
write_segment,
|
|
705
|
+
is_in_place_sed,
|
|
706
|
+
// Exported for the drift test in `time-bundle-call.test.ts`, which pins that
|
|
707
|
+
// every name here is a real `josh` command and none of them writes.
|
|
708
|
+
READ_JOSH_SUBCOMMANDS
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
// scripts/time-runtime/time-phase-names.ts
|
|
712
|
+
var GATE_PHASE = "gate";
|
|
713
|
+
var PR_PHASE = "pr";
|
|
714
|
+
var MERGE_PHASE = "merge";
|
|
715
|
+
var GATE_COMMAND = "josh gate";
|
|
716
|
+
var COMMAND_PHASES = /* @__PURE__ */ new Map([
|
|
717
|
+
[GATE_COMMAND, GATE_PHASE],
|
|
718
|
+
["josh git", PR_PHASE],
|
|
719
|
+
["josh pr", PR_PHASE],
|
|
720
|
+
["josh followup", MERGE_PHASE]
|
|
721
|
+
]);
|
|
722
|
+
|
|
723
|
+
// scripts/time-runtime/time-background.ts
|
|
724
|
+
var NO_BACKGROUND = "";
|
|
725
|
+
var NO_FINISH = 0;
|
|
726
|
+
var LAUNCH_PATTERN = /(?:running in background with ID:|moved to the background \(ID:)\s*([\w-]+)/iu;
|
|
727
|
+
var AGENT_LAUNCH_PATTERN = /^(?:Async agent launched[\s\S]*?\bagentId:\s*|\{"success":[^\n]*?"resumedAgentId":")([\w-]+)/u;
|
|
728
|
+
var FINISH_PATTERN = /^<task-notification>[\s\S]*?<task-id>([\w-]+)<\/task-id>/u;
|
|
729
|
+
var STOP_PATTERN = /^\{"message":"Successfully stopped task:\s*([\w-]+)/u;
|
|
730
|
+
var OUTPUT_PATTERN = /tasks\/([\w-]+)\.output/u;
|
|
731
|
+
var BASH_ID_KEY = "bash_id";
|
|
732
|
+
function read_id(command) {
|
|
733
|
+
return OUTPUT_PATTERN.exec(time_shell.unquoted(command))?.[1] ?? NO_BACKGROUND;
|
|
734
|
+
}
|
|
735
|
+
function read_id_of(input) {
|
|
736
|
+
if (!json_value.is_record(input)) return NO_BACKGROUND;
|
|
737
|
+
const id = input[BASH_ID_KEY];
|
|
738
|
+
return typeof id === "string" ? id : read_id(time_shell.bash_command(input));
|
|
739
|
+
}
|
|
740
|
+
function launch_id(text) {
|
|
741
|
+
return LAUNCH_PATTERN.exec(text)?.[1] ?? NO_BACKGROUND;
|
|
742
|
+
}
|
|
743
|
+
function agent_launch_id(text) {
|
|
744
|
+
return AGENT_LAUNCH_PATTERN.exec(text)?.[1] ?? NO_BACKGROUND;
|
|
745
|
+
}
|
|
746
|
+
function finished_id(text) {
|
|
747
|
+
return FINISH_PATTERN.exec(text)?.[1] ?? NO_BACKGROUND;
|
|
748
|
+
}
|
|
749
|
+
function stopped_id(text) {
|
|
750
|
+
return STOP_PATTERN.exec(text)?.[1] ?? NO_BACKGROUND;
|
|
751
|
+
}
|
|
752
|
+
function finished_at(lines) {
|
|
753
|
+
const notices = lines.filter((one) => one.finished_background !== NO_BACKGROUND).toSorted((left, right) => right.timestamp_ms - left.timestamp_ms);
|
|
754
|
+
return new Map(notices.map((one) => [one.finished_background, one.timestamp_ms]));
|
|
755
|
+
}
|
|
756
|
+
function started_ms(span) {
|
|
757
|
+
return span.ended_ms - span.duration_ms;
|
|
758
|
+
}
|
|
759
|
+
function read_end_ms(spans, run) {
|
|
760
|
+
if (run.background_ended_ms === NO_FINISH) return void 0;
|
|
761
|
+
const found = spans.find(
|
|
762
|
+
(span) => span.reads_background === run.background_id && span.ended_ms >= run.background_ended_ms
|
|
763
|
+
);
|
|
764
|
+
return found?.ended_ms;
|
|
765
|
+
}
|
|
766
|
+
function to_run(spans, launch) {
|
|
767
|
+
const read2 = read_end_ms(spans, launch);
|
|
768
|
+
return {
|
|
769
|
+
id: launch.background_id,
|
|
770
|
+
josh_command: launch.josh_command,
|
|
771
|
+
started_ms: started_ms(launch),
|
|
772
|
+
ended_ms: read2 ?? launch.ended_ms,
|
|
773
|
+
is_read: read2 !== void 0
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
function is_launch(span) {
|
|
777
|
+
return span.background_id !== NO_BACKGROUND;
|
|
778
|
+
}
|
|
779
|
+
function runs(spans) {
|
|
780
|
+
return spans.filter((span) => is_launch(span)).map((launch) => to_run(spans, launch));
|
|
781
|
+
}
|
|
782
|
+
function is_within(span, run) {
|
|
783
|
+
const start = started_ms(span);
|
|
784
|
+
return start >= run.started_ms && start < run.ended_ms;
|
|
785
|
+
}
|
|
786
|
+
function latest_first(all2) {
|
|
787
|
+
return all2.filter((run) => run.is_read).toSorted((left, right) => right.started_ms - left.started_ms);
|
|
788
|
+
}
|
|
789
|
+
function own_run(span, all2) {
|
|
790
|
+
return is_launch(span) ? all2.find((run) => run.id === span.background_id) : void 0;
|
|
791
|
+
}
|
|
792
|
+
function placed(span, all2, ordered) {
|
|
793
|
+
const own = own_run(span, all2);
|
|
794
|
+
const run = own ?? ordered.find((one) => is_within(span, one));
|
|
795
|
+
if (run === void 0) return span;
|
|
796
|
+
const beside = { ...span, background_command: run.josh_command };
|
|
797
|
+
return own === void 0 ? beside : { ...beside, own_duration_ms: own.ended_ms - own.started_ms };
|
|
798
|
+
}
|
|
799
|
+
function positioned(spans) {
|
|
800
|
+
const all2 = runs(spans);
|
|
801
|
+
if (all2.length === 0) return [...spans];
|
|
802
|
+
const ordered = latest_first(all2);
|
|
803
|
+
return spans.map((span) => placed(span, all2, ordered));
|
|
804
|
+
}
|
|
805
|
+
function unread_phases(spans) {
|
|
806
|
+
const names = runs(spans).filter((run) => !run.is_read).map((run) => COMMAND_PHASES.get(run.josh_command));
|
|
807
|
+
return new Set(names.filter((phase) => phase !== void 0));
|
|
808
|
+
}
|
|
809
|
+
var time_background = {
|
|
810
|
+
NO_BACKGROUND,
|
|
811
|
+
NO_FINISH,
|
|
812
|
+
launch_id,
|
|
813
|
+
agent_launch_id,
|
|
814
|
+
finished_id,
|
|
815
|
+
stopped_id,
|
|
816
|
+
finished_at,
|
|
817
|
+
read_id,
|
|
818
|
+
read_id_of,
|
|
819
|
+
runs,
|
|
820
|
+
positioned,
|
|
821
|
+
unread_phases
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
// scripts/gh/git-pr-checks-parse.ts
|
|
825
|
+
var CHECK_STATUS_PASS = "pass";
|
|
826
|
+
var CHECK_STATUS_PENDING = "pending";
|
|
827
|
+
var CHECK_STATUS_FAIL = "fail";
|
|
828
|
+
var CHECK_STATUS_MISSING = "missing";
|
|
829
|
+
var PASSING_CONCLUSIONS = /* @__PURE__ */ new Set(["success", "skipped", "neutral"]);
|
|
830
|
+
var KEY_TYPE_NAME = "__typename";
|
|
831
|
+
var KEY_STATE = "state";
|
|
832
|
+
var KEY_STATUS = "status";
|
|
833
|
+
var KEY_CONCLUSION = "conclusion";
|
|
834
|
+
var KEY_NAME = "name";
|
|
835
|
+
var KEY_CONTEXT = "context";
|
|
836
|
+
var KEY_DESCRIPTION = "description";
|
|
837
|
+
function read_string(value) {
|
|
838
|
+
if (typeof value !== "string") return void 0;
|
|
839
|
+
const trimmed = value.trim();
|
|
840
|
+
if (trimmed.length === 0) return void 0;
|
|
841
|
+
return trimmed;
|
|
842
|
+
}
|
|
843
|
+
var PENDING_STATUS_STATES = /* @__PURE__ */ new Set(["pending", "expected"]);
|
|
844
|
+
function parse_status_context(item) {
|
|
845
|
+
const state = read_string(item[KEY_STATE])?.toLowerCase();
|
|
846
|
+
if (state === "success") return CHECK_STATUS_PASS;
|
|
847
|
+
if (state !== void 0 && PENDING_STATUS_STATES.has(state)) return CHECK_STATUS_PENDING;
|
|
848
|
+
return CHECK_STATUS_FAIL;
|
|
849
|
+
}
|
|
850
|
+
function is_passing_conclusion(item) {
|
|
851
|
+
const conclusion = read_string(item[KEY_CONCLUSION])?.toLowerCase();
|
|
852
|
+
return conclusion !== void 0 && PASSING_CONCLUSIONS.has(conclusion);
|
|
853
|
+
}
|
|
854
|
+
function parse_check_run(item) {
|
|
855
|
+
const status = read_string(item[KEY_STATUS])?.toLowerCase();
|
|
856
|
+
if (status !== "completed") return CHECK_STATUS_PENDING;
|
|
857
|
+
return is_passing_conclusion(item) ? CHECK_STATUS_PASS : CHECK_STATUS_FAIL;
|
|
858
|
+
}
|
|
859
|
+
function parse_rollup_status(item) {
|
|
860
|
+
const type_name = read_string(item[KEY_TYPE_NAME]);
|
|
861
|
+
if (type_name === "StatusContext") return parse_status_context(item);
|
|
862
|
+
return parse_check_run(item);
|
|
863
|
+
}
|
|
864
|
+
function read_rollup_array(parsed) {
|
|
865
|
+
const result = pr_raw_schema.safeParse(parsed);
|
|
866
|
+
if (!result.success) return [];
|
|
867
|
+
return result.data.statusCheckRollup ?? [];
|
|
868
|
+
}
|
|
869
|
+
function parse_rollup_item(item) {
|
|
870
|
+
const name = read_string(item[KEY_NAME]) ?? read_string(item[KEY_CONTEXT]);
|
|
871
|
+
if (name === void 0) return void 0;
|
|
872
|
+
const check = { name, status: parse_rollup_status(item) };
|
|
873
|
+
const description = read_string(item[KEY_DESCRIPTION]);
|
|
874
|
+
return description === void 0 ? check : { ...check, description };
|
|
875
|
+
}
|
|
876
|
+
function parse_rollup_checks(raw_json) {
|
|
877
|
+
const parsed = json_value.parse_or_undefined(raw_json);
|
|
878
|
+
const rollup = read_rollup_array(parsed);
|
|
879
|
+
const checks = [];
|
|
880
|
+
for (const item of rollup) {
|
|
881
|
+
const parsed_item = parse_rollup_item(item);
|
|
882
|
+
if (parsed_item !== void 0) checks.push(parsed_item);
|
|
883
|
+
}
|
|
884
|
+
return checks;
|
|
885
|
+
}
|
|
886
|
+
function with_head_sha(snapshot, head_sha) {
|
|
887
|
+
return head_sha === void 0 ? snapshot : { ...snapshot, head_sha };
|
|
888
|
+
}
|
|
889
|
+
function with_required_contexts(snapshot, required_contexts) {
|
|
890
|
+
if (required_contexts === void 0 || required_contexts.length === 0) return snapshot;
|
|
891
|
+
return { ...snapshot, required_contexts };
|
|
892
|
+
}
|
|
893
|
+
function read_pr_raw_data(raw_json) {
|
|
894
|
+
const result = pr_raw_schema.safeParse(json_value.parse_or_undefined(raw_json));
|
|
895
|
+
return result.success ? result.data : {};
|
|
896
|
+
}
|
|
897
|
+
function parse_pr_state_snapshot(raw_json) {
|
|
898
|
+
const data = read_pr_raw_data(raw_json);
|
|
899
|
+
const snapshot = {
|
|
900
|
+
rollup: parse_rollup_checks(raw_json),
|
|
901
|
+
merge_state_status: read_string(data.mergeStateStatus),
|
|
902
|
+
review_decision: read_string(data.reviewDecision)
|
|
903
|
+
};
|
|
904
|
+
return with_required_contexts(
|
|
905
|
+
with_head_sha(snapshot, read_string(data.headRefOid)),
|
|
906
|
+
data.requiredContexts
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// scripts/gh/git-pr-checks-eval.ts
|
|
911
|
+
var DEFAULT_REQUIRED_CHECKS = ["SonarQube"];
|
|
912
|
+
var CODERABBIT_CHECK_NAME = "CodeRabbit";
|
|
913
|
+
var REQUIRED_CHECKS_ENV_VAR = "JOSH_REQUIRED_CHECKS";
|
|
914
|
+
function parse_required_checks() {
|
|
915
|
+
const raw = process.env[REQUIRED_CHECKS_ENV_VAR];
|
|
916
|
+
if (!raw) return DEFAULT_REQUIRED_CHECKS;
|
|
917
|
+
return raw.split(",").map((check) => check.trim()).filter((check) => check.length > 0);
|
|
918
|
+
}
|
|
919
|
+
var REQUIRED_CHECKS = parse_required_checks();
|
|
920
|
+
var MERGE_STATE_CLEAN = "CLEAN";
|
|
921
|
+
var MERGE_STATE_UNSTABLE = "UNSTABLE";
|
|
922
|
+
var MERGE_STATE_DIRTY = "DIRTY";
|
|
923
|
+
var REVIEW_CHANGES_REQUESTED = "CHANGES_REQUESTED";
|
|
924
|
+
var CHECK_SUITE_SEPARATOR = " / ";
|
|
925
|
+
var FAILURE_MESSAGE_PREFIX = "PR checks failed";
|
|
926
|
+
var FAILURE_REASON_REVIEW = "review requested changes";
|
|
927
|
+
var FAILURE_REASON_CHECKS = "failed checks";
|
|
928
|
+
var FAILURE_REASON_CONFLICT = "merge conflict";
|
|
929
|
+
function is_required_match(check_name, required_name) {
|
|
930
|
+
if (check_name === required_name) return true;
|
|
931
|
+
return check_name.startsWith(`${required_name}${CHECK_SUITE_SEPARATOR}`);
|
|
932
|
+
}
|
|
933
|
+
function find_required_check(checks, required_name) {
|
|
934
|
+
return checks.find((check) => is_required_match(check.name, required_name));
|
|
935
|
+
}
|
|
936
|
+
function read_required_statuses(checks) {
|
|
937
|
+
return REQUIRED_CHECKS.map(
|
|
938
|
+
(name) => find_required_check(checks, name)?.status ?? CHECK_STATUS_MISSING
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
function is_review_blocked(review_decision) {
|
|
942
|
+
return review_decision === REVIEW_CHANGES_REQUESTED;
|
|
943
|
+
}
|
|
944
|
+
function is_merge_conflict(merge_state_status) {
|
|
945
|
+
return merge_state_status === MERGE_STATE_DIRTY;
|
|
946
|
+
}
|
|
947
|
+
function evaluate_failure_state(input) {
|
|
948
|
+
if (is_merge_conflict(input.merge_state_status) || is_review_blocked(input.review_decision) || input.failed_checks.length > 0) {
|
|
949
|
+
return "failure";
|
|
950
|
+
}
|
|
951
|
+
return void 0;
|
|
952
|
+
}
|
|
953
|
+
function is_merge_state_clean(merge_state_status) {
|
|
954
|
+
return merge_state_status === MERGE_STATE_CLEAN;
|
|
955
|
+
}
|
|
956
|
+
function is_every_required_passing(statuses) {
|
|
957
|
+
return statuses.every((status) => status === CHECK_STATUS_PASS);
|
|
958
|
+
}
|
|
959
|
+
function is_coderabbit_check(check_name) {
|
|
960
|
+
return is_required_match(check_name, CODERABBIT_CHECK_NAME);
|
|
961
|
+
}
|
|
962
|
+
var CODERABBIT_RATE_LIMIT_DESCRIPTION = /rate limit/iu;
|
|
963
|
+
function is_coderabbit_rate_limited(check) {
|
|
964
|
+
return is_coderabbit_check(check.name) && CODERABBIT_RATE_LIMIT_DESCRIPTION.test(check.description ?? "");
|
|
965
|
+
}
|
|
966
|
+
function matches_any(check_name, required_names) {
|
|
967
|
+
return required_names.some((required) => is_required_match(check_name, required));
|
|
968
|
+
}
|
|
969
|
+
function is_optional_pending(check, required_contexts) {
|
|
970
|
+
if (required_contexts.length === 0 || check.status !== CHECK_STATUS_PENDING) return false;
|
|
971
|
+
return !matches_any(check.name, required_contexts);
|
|
972
|
+
}
|
|
973
|
+
function is_every_context_passing(checks, contexts) {
|
|
974
|
+
return contexts.every(
|
|
975
|
+
(context) => find_required_check(checks, context)?.status === CHECK_STATUS_PASS
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
function is_unstable_only_from_optional(snapshot) {
|
|
979
|
+
if (snapshot.merge_state_status !== MERGE_STATE_UNSTABLE) return false;
|
|
980
|
+
const required_contexts = snapshot.required_contexts ?? [];
|
|
981
|
+
const non_passing = snapshot.rollup.filter((check) => check.status !== CHECK_STATUS_PASS);
|
|
982
|
+
if (non_passing.length === 0) return false;
|
|
983
|
+
const is_tolerated = non_passing.every(
|
|
984
|
+
(check) => is_coderabbit_check(check.name) || is_optional_pending(check, required_contexts)
|
|
985
|
+
);
|
|
986
|
+
return is_tolerated && is_every_context_passing(snapshot.rollup, required_contexts);
|
|
987
|
+
}
|
|
988
|
+
function is_required_check(check_name) {
|
|
989
|
+
return REQUIRED_CHECKS.some((required) => is_required_match(check_name, required));
|
|
990
|
+
}
|
|
991
|
+
function is_blocking_failure(check) {
|
|
992
|
+
if (check.status !== CHECK_STATUS_FAIL) return false;
|
|
993
|
+
return !is_coderabbit_check(check.name) || is_required_check(check.name);
|
|
994
|
+
}
|
|
995
|
+
function collect_blocking_failures(snapshot) {
|
|
996
|
+
return snapshot.rollup.filter((check) => is_blocking_failure(check)).map((check) => check.name);
|
|
997
|
+
}
|
|
998
|
+
function is_mergeable_state(snapshot) {
|
|
999
|
+
if (is_merge_state_clean(snapshot.merge_state_status)) return true;
|
|
1000
|
+
return is_unstable_only_from_optional(snapshot);
|
|
1001
|
+
}
|
|
1002
|
+
function collect_failure_reasons(snapshot) {
|
|
1003
|
+
const reasons = [];
|
|
1004
|
+
if (is_merge_conflict(snapshot.merge_state_status)) reasons.push(FAILURE_REASON_CONFLICT);
|
|
1005
|
+
if (is_review_blocked(snapshot.review_decision)) reasons.push(FAILURE_REASON_REVIEW);
|
|
1006
|
+
const failed = collect_blocking_failures(snapshot);
|
|
1007
|
+
if (failed.length > 0) reasons.push(`${FAILURE_REASON_CHECKS}: ${failed.join(", ")}`);
|
|
1008
|
+
return reasons;
|
|
1009
|
+
}
|
|
1010
|
+
function describe_pr_failure(snapshot) {
|
|
1011
|
+
const reasons = collect_failure_reasons(snapshot);
|
|
1012
|
+
if (reasons.length === 0) return `${FAILURE_MESSAGE_PREFIX}.`;
|
|
1013
|
+
return `${FAILURE_MESSAGE_PREFIX} (${reasons.join("; ")}).`;
|
|
1014
|
+
}
|
|
1015
|
+
function evaluate_pr_state(snapshot) {
|
|
1016
|
+
const statuses = read_required_statuses(snapshot.rollup);
|
|
1017
|
+
const failure = evaluate_failure_state({
|
|
1018
|
+
review_decision: snapshot.review_decision,
|
|
1019
|
+
failed_checks: collect_blocking_failures(snapshot),
|
|
1020
|
+
merge_state_status: snapshot.merge_state_status
|
|
1021
|
+
});
|
|
1022
|
+
if (failure !== void 0) return failure;
|
|
1023
|
+
if (is_mergeable_state(snapshot) && is_every_required_passing(statuses)) return "success";
|
|
1024
|
+
return "pending";
|
|
1025
|
+
}
|
|
1026
|
+
function is_review_decision_decisive(snapshot) {
|
|
1027
|
+
return evaluate_pr_state(snapshot) !== "pending";
|
|
1028
|
+
}
|
|
1029
|
+
var PrConflictError = class extends Error {
|
|
1030
|
+
name = "PrConflictError";
|
|
1031
|
+
};
|
|
1032
|
+
|
|
1033
|
+
// scripts/time-runtime/time-format.ts
|
|
1034
|
+
var SECOND_DECIMALS = 1;
|
|
1035
|
+
var LABEL_WIDTH = 24;
|
|
1036
|
+
var MINUTES_WIDTH = 9;
|
|
1037
|
+
var NOT_MEASURED = "not measured";
|
|
1038
|
+
var NO_CALLS = "no tool call to divide";
|
|
1039
|
+
var MAX_ROWS = 15;
|
|
1040
|
+
function overflow_line(row_count) {
|
|
1041
|
+
if (row_count <= MAX_ROWS) return [];
|
|
1042
|
+
return [
|
|
1043
|
+
` \u2026 and ${String(row_count - MAX_ROWS)} more (--json carries every row this report holds)`
|
|
1044
|
+
];
|
|
1045
|
+
}
|
|
1046
|
+
function format_seconds(duration_ms) {
|
|
1047
|
+
return `${(duration_ms / MS_PER_SECOND).toFixed(SECOND_DECIMALS)} s`;
|
|
1048
|
+
}
|
|
1049
|
+
function format_columns(label, minutes, suffix) {
|
|
1050
|
+
return ` ${label.padEnd(LABEL_WIDTH)}${minutes.padStart(MINUTES_WIDTH)} ${suffix}`;
|
|
1051
|
+
}
|
|
1052
|
+
function format_row(label, duration_ms, suffix) {
|
|
1053
|
+
return format_columns(label, figure_format.format_minutes(duration_ms), suffix);
|
|
1054
|
+
}
|
|
1055
|
+
function unmeasured_row(label) {
|
|
1056
|
+
return format_columns(label, "", NOT_MEASURED);
|
|
1057
|
+
}
|
|
1058
|
+
var time_format = {
|
|
1059
|
+
MAX_ROWS,
|
|
1060
|
+
NO_CALLS,
|
|
1061
|
+
overflow_line,
|
|
1062
|
+
format_seconds,
|
|
1063
|
+
format_columns,
|
|
1064
|
+
format_row,
|
|
1065
|
+
// `format_clock` stays private: `format_window` is its only caller, and a namespace that offers
|
|
1066
|
+
// both invites a second renderer to join the two with its own arrow.
|
|
1067
|
+
unmeasured_row
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1070
|
+
// scripts/followup/followup-ci-path.ts
|
|
1071
|
+
function new_path() {
|
|
1072
|
+
return { pending: /* @__PURE__ */ new Set(), check_ms: {} };
|
|
1073
|
+
}
|
|
1074
|
+
function settle(path3, name, elapsed_ms) {
|
|
1075
|
+
if (path3.pending.delete(name)) path3.check_ms[name] = elapsed_ms;
|
|
1076
|
+
}
|
|
1077
|
+
function observe(path3, snapshot, now_ms) {
|
|
1078
|
+
path3.start_ms ??= now_ms;
|
|
1079
|
+
const elapsed_ms = now_ms - path3.start_ms;
|
|
1080
|
+
const checks = snapshot.rollup.filter((check) => !is_coderabbit_check(check.name));
|
|
1081
|
+
for (const check of checks) {
|
|
1082
|
+
if (check.status === CHECK_STATUS_PENDING) path3.pending.add(check.name);
|
|
1083
|
+
else settle(path3, check.name, elapsed_ms);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
function observer_of(path3) {
|
|
1087
|
+
const is_first_wait = path3.start_ms === void 0;
|
|
1088
|
+
return async function time_checks(snapshot) {
|
|
1089
|
+
if (is_first_wait) observe(path3, snapshot, performance.now());
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
function record_of(path3) {
|
|
1093
|
+
const [last] = Object.entries(path3.check_ms).toSorted((left, right) => right[1] - left[1]);
|
|
1094
|
+
if (last === void 0) return {};
|
|
1095
|
+
return { last_check: last[0], check_ms: { ...path3.check_ms } };
|
|
1096
|
+
}
|
|
1097
|
+
var followup_ci_path = { new_path, observe, observer_of, record_of };
|
|
1098
|
+
|
|
1099
|
+
// scripts/run/event/run-event-checks.ts
|
|
1100
|
+
var CODERABBIT_STATES = ["running", "done", "rate-limited", "failed", "none"];
|
|
1101
|
+
var CHECKS_PATTERN = /^#\d+ PR (?<pr>\d+) pass (?<pass>\d+) pending (?<pending>\d+) fail (?<fail>\d+) coderabbit (?<coderabbit>\S+)$/u;
|
|
1102
|
+
function text_of(issue, checks) {
|
|
1103
|
+
const { pr, pass, pending, fail, coderabbit } = checks;
|
|
1104
|
+
return `${issue_cite.plain(issue)} PR ${String(pr)} pass ${String(pass)} pending ${String(pending)} fail ${String(fail)} coderabbit ${coderabbit}`;
|
|
1105
|
+
}
|
|
1106
|
+
var STATE_NAMES = new Set(CODERABBIT_STATES);
|
|
1107
|
+
function is_coderabbit_state(value = "") {
|
|
1108
|
+
return STATE_NAMES.has(value);
|
|
1109
|
+
}
|
|
1110
|
+
function checks_of(text) {
|
|
1111
|
+
const groups = CHECKS_PATTERN.exec(text)?.groups;
|
|
1112
|
+
const coderabbit = groups?.["coderabbit"];
|
|
1113
|
+
if (groups === void 0 || !is_coderabbit_state(coderabbit)) return void 0;
|
|
1114
|
+
return {
|
|
1115
|
+
pr: Number(groups["pr"]),
|
|
1116
|
+
pass: Number(groups["pass"]),
|
|
1117
|
+
pending: Number(groups["pending"]),
|
|
1118
|
+
fail: Number(groups["fail"]),
|
|
1119
|
+
coderabbit
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
var run_event_checks = { checks_of, text_of };
|
|
1123
|
+
|
|
1124
|
+
// scripts/followup/followup-checks-event.ts
|
|
1125
|
+
var PR_NUMBER_PATTERN = /\/pull\/(?<number>\d+)/u;
|
|
1126
|
+
var { PR_CHECKS } = run_event_stream.EVENT_KIND;
|
|
1127
|
+
function count_of(checks, status) {
|
|
1128
|
+
return checks.filter((check) => check.status === status).length;
|
|
1129
|
+
}
|
|
1130
|
+
function coderabbit_state_of(check) {
|
|
1131
|
+
if (check === void 0) return "none";
|
|
1132
|
+
if (check.status === CHECK_STATUS_PENDING) return "running";
|
|
1133
|
+
if (check.status !== CHECK_STATUS_PASS) return "failed";
|
|
1134
|
+
return is_coderabbit_rate_limited(check) ? "rate-limited" : "done";
|
|
1135
|
+
}
|
|
1136
|
+
function coderabbit_of(snapshot) {
|
|
1137
|
+
return coderabbit_state_of(snapshot.rollup.find((check) => is_coderabbit_check(check.name)));
|
|
1138
|
+
}
|
|
1139
|
+
function summary_of(snapshot, pr) {
|
|
1140
|
+
const ci = snapshot.rollup.filter((check) => !is_coderabbit_check(check.name));
|
|
1141
|
+
return {
|
|
1142
|
+
pr,
|
|
1143
|
+
pass: count_of(ci, CHECK_STATUS_PASS),
|
|
1144
|
+
pending: count_of(ci, CHECK_STATUS_PENDING),
|
|
1145
|
+
fail: count_of(ci, CHECK_STATUS_FAIL),
|
|
1146
|
+
coderabbit: coderabbit_of(snapshot)
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
function pr_number_of(pr_url = "") {
|
|
1150
|
+
const number = PR_NUMBER_PATTERN.exec(pr_url)?.groups?.["number"];
|
|
1151
|
+
return number === void 0 ? void 0 : Number(number);
|
|
1152
|
+
}
|
|
1153
|
+
async function skip_snapshot() {
|
|
1154
|
+
}
|
|
1155
|
+
function observer_of2(issue, pr_url) {
|
|
1156
|
+
const pr = pr_number_of(pr_url);
|
|
1157
|
+
if (issue === void 0 || pr === void 0) return skip_snapshot;
|
|
1158
|
+
let last_text = "";
|
|
1159
|
+
return async function report_snapshot(snapshot) {
|
|
1160
|
+
const text = run_event_checks.text_of(issue, summary_of(snapshot, pr));
|
|
1161
|
+
if (text === last_text) return;
|
|
1162
|
+
last_text = text;
|
|
1163
|
+
await run_event_stream_emit.emit(PR_CHECKS, text);
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
var followup_checks_event = { coderabbit_of, observer_of: observer_of2, summary_of };
|
|
1167
|
+
|
|
1168
|
+
// scripts/followup/followup-coderabbit-wait.ts
|
|
1169
|
+
var NO_TIME = 0;
|
|
1170
|
+
var RATE_LIMITED = "rate-limited";
|
|
1171
|
+
var WAITING_STATES = /* @__PURE__ */ new Set(["running", RATE_LIMITED]);
|
|
1172
|
+
function new_wait() {
|
|
1173
|
+
return { wait_ms: NO_TIME, rate_limited_ms: NO_TIME };
|
|
1174
|
+
}
|
|
1175
|
+
function charge(wait, last, now_ms) {
|
|
1176
|
+
const elapsed_ms = now_ms - last.at_ms;
|
|
1177
|
+
if (WAITING_STATES.has(last.state)) wait.wait_ms += elapsed_ms;
|
|
1178
|
+
if (last.state === RATE_LIMITED) wait.rate_limited_ms += elapsed_ms;
|
|
1179
|
+
}
|
|
1180
|
+
function observe2(wait, snapshot, now_ms) {
|
|
1181
|
+
if (wait.last !== void 0) charge(wait, wait.last, now_ms);
|
|
1182
|
+
wait.last = { state: followup_checks_event.coderabbit_of(snapshot), at_ms: now_ms };
|
|
1183
|
+
}
|
|
1184
|
+
function observer_of3(wait) {
|
|
1185
|
+
delete wait.last;
|
|
1186
|
+
return async function time_snapshot(snapshot) {
|
|
1187
|
+
observe2(wait, snapshot, performance.now());
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
function all(...observers) {
|
|
1191
|
+
return async function observe_all(snapshot) {
|
|
1192
|
+
await Promise.all(
|
|
1193
|
+
observers.map(async (observer) => {
|
|
1194
|
+
await observer(snapshot);
|
|
1195
|
+
})
|
|
1196
|
+
);
|
|
1197
|
+
};
|
|
1198
|
+
}
|
|
1199
|
+
async function record_part(stage, elapsed_ms) {
|
|
1200
|
+
if (elapsed_ms > NO_TIME) await lane_ledger_write.record_stage({ stage, elapsed_ms });
|
|
1201
|
+
}
|
|
1202
|
+
async function record(wait) {
|
|
1203
|
+
await record_part(lane_ledger_write.CODERABBIT_WAIT_STAGE, wait.wait_ms);
|
|
1204
|
+
await record_part(lane_ledger_write.CODERABBIT_RATE_LIMIT_STAGE, wait.rate_limited_ms);
|
|
1205
|
+
}
|
|
1206
|
+
var followup_coderabbit_wait = { all, new_wait, observe: observe2, observer_of: observer_of3, record };
|
|
1207
|
+
|
|
1208
|
+
// scripts/followup/git-followup-stages.ts
|
|
1209
|
+
var STAGE_LINE_PREFIX = "followup stage: ";
|
|
1210
|
+
var STAGE_TOTAL_PREFIX = "followup stages total: ";
|
|
1211
|
+
var STAGE_NAME_WIDTH = 26;
|
|
1212
|
+
var VALUE_COLUMN = STAGE_LINE_PREFIX.length + STAGE_NAME_WIDTH;
|
|
1213
|
+
var NO_DURATION = 0;
|
|
1214
|
+
var STAGE = {
|
|
1215
|
+
closes_and_context: "closes-and-context",
|
|
1216
|
+
checks_wait: "checks-wait",
|
|
1217
|
+
// Only on a run that retriggered a rate-limited CodeRabbit: the window and the review after it
|
|
1218
|
+
// (joshuafolkken/kit#5289), kept out of `checks-wait` so the `ci-wait` row is the checks alone.
|
|
1219
|
+
coderabbit_retrigger: "coderabbit-retrigger",
|
|
1220
|
+
coderabbit_comments: "coderabbit-comments",
|
|
1221
|
+
ai_review_comments: "ai-review-comments",
|
|
1222
|
+
// The interval of a run that merged nothing, where the send has nothing to go beside.
|
|
1223
|
+
telegram: "telegram",
|
|
1224
|
+
telegram_and_merge: "telegram-and-merge",
|
|
1225
|
+
completion_and_epic_close: "completion-and-epic-close",
|
|
1226
|
+
// The completion tail `git-followup-finish.ts` prints after this block (#5131): the next-issue list
|
|
1227
|
+
// and the unreleased-merge count. Printed as its own row there, since the block is already out.
|
|
1228
|
+
completion: "completion",
|
|
1229
|
+
// The lap that was still running when a stage threw. `followup` exits non-zero on an AI-review
|
|
1230
|
+
// blocker and on a red check, and those are the runs whose wait is longest — reporting nothing for
|
|
1231
|
+
// them would leave the measurement blind to exactly the invocations worth measuring.
|
|
1232
|
+
interrupted: "interrupted",
|
|
1233
|
+
// The interrupted lap when the wait failed on a merge conflict, so the
|
|
1234
|
+
// stage block names the cause a resumed session would otherwise look up with `gh pr view`.
|
|
1235
|
+
conflict: "conflict"
|
|
1236
|
+
};
|
|
1237
|
+
function stopped_lap(error) {
|
|
1238
|
+
return error instanceof PrConflictError ? STAGE.conflict : STAGE.interrupted;
|
|
1239
|
+
}
|
|
1240
|
+
function new_log() {
|
|
1241
|
+
return {
|
|
1242
|
+
stages: [],
|
|
1243
|
+
last_ms: performance.now(),
|
|
1244
|
+
coderabbit: followup_coderabbit_wait.new_wait(),
|
|
1245
|
+
ci_path: followup_ci_path.new_path()
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
function hold_issue(log, issue_number) {
|
|
1249
|
+
const issue = Number(issue_number);
|
|
1250
|
+
if (Number.isSafeInteger(issue) && issue > 0) log.issue = issue;
|
|
1251
|
+
}
|
|
1252
|
+
function lap(log, name) {
|
|
1253
|
+
const now_ms = performance.now();
|
|
1254
|
+
log.stages.push({ name, duration_ms: now_ms - log.last_ms });
|
|
1255
|
+
log.last_ms = now_ms;
|
|
1256
|
+
}
|
|
1257
|
+
function total_ms(stages) {
|
|
1258
|
+
return stages.reduce((sum, stage) => sum + stage.duration_ms, NO_DURATION);
|
|
1259
|
+
}
|
|
1260
|
+
function format_stage(stage) {
|
|
1261
|
+
const name = stage.name.padEnd(STAGE_NAME_WIDTH);
|
|
1262
|
+
return `${STAGE_LINE_PREFIX}${name}${time_format.format_seconds(stage.duration_ms)}`;
|
|
1263
|
+
}
|
|
1264
|
+
function format_stages(log) {
|
|
1265
|
+
if (log.stages.length === 0) return [];
|
|
1266
|
+
const rows = log.stages.map((stage) => format_stage(stage));
|
|
1267
|
+
const total = time_format.format_seconds(total_ms(log.stages));
|
|
1268
|
+
return ["", ...rows, `${STAGE_TOTAL_PREFIX.padEnd(VALUE_COLUMN)}${total}`];
|
|
1269
|
+
}
|
|
1270
|
+
function print_stages(log) {
|
|
1271
|
+
for (const line of format_stages(log)) console.info(line);
|
|
1272
|
+
}
|
|
1273
|
+
async function record_ci_wait(log) {
|
|
1274
|
+
const wait = log.stages.find((stage) => stage.name === STAGE.checks_wait);
|
|
1275
|
+
if (wait === void 0) return;
|
|
1276
|
+
await lane_ledger_write.record_stage({
|
|
1277
|
+
stage: lane_ledger_write.CI_WAIT_STAGE,
|
|
1278
|
+
elapsed_ms: wait.duration_ms,
|
|
1279
|
+
...log.issue !== void 0 && { issue: log.issue },
|
|
1280
|
+
...followup_ci_path.record_of(log.ci_path)
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
async function record_waits(log) {
|
|
1284
|
+
await record_ci_wait(log);
|
|
1285
|
+
await followup_coderabbit_wait.record(log.coderabbit);
|
|
1286
|
+
}
|
|
1287
|
+
var git_followup_stages = {
|
|
1288
|
+
STAGE,
|
|
1289
|
+
STAGE_LINE_PREFIX,
|
|
1290
|
+
STAGE_TOTAL_PREFIX,
|
|
1291
|
+
new_log,
|
|
1292
|
+
hold_issue,
|
|
1293
|
+
lap,
|
|
1294
|
+
total_ms,
|
|
1295
|
+
format_stage,
|
|
1296
|
+
format_stages,
|
|
1297
|
+
print_stages,
|
|
1298
|
+
record_waits,
|
|
1299
|
+
stopped_lap
|
|
1300
|
+
};
|
|
1301
|
+
|
|
1302
|
+
// scripts/time-runtime/time-followup-stage.ts
|
|
1303
|
+
var LINE_SEPARATOR = "\n";
|
|
1304
|
+
var SECONDS_SUFFIX = " s";
|
|
1305
|
+
var DIGIT_OR_POINT = /[\d.]/u;
|
|
1306
|
+
var NO_STAGES = [];
|
|
1307
|
+
function stage_body(line) {
|
|
1308
|
+
const trimmed = line.trimStart();
|
|
1309
|
+
if (!trimmed.startsWith(git_followup_stages.STAGE_LINE_PREFIX)) return void 0;
|
|
1310
|
+
return trimmed.slice(git_followup_stages.STAGE_LINE_PREFIX.length);
|
|
1311
|
+
}
|
|
1312
|
+
function digits_start(head) {
|
|
1313
|
+
let index = head.length;
|
|
1314
|
+
while (index > 0 && DIGIT_OR_POINT.test(head.charAt(index - 1))) index -= 1;
|
|
1315
|
+
return index;
|
|
1316
|
+
}
|
|
1317
|
+
function is_duration(digits) {
|
|
1318
|
+
return digits !== "" && Number.isFinite(Number(digits));
|
|
1319
|
+
}
|
|
1320
|
+
function to_stage(body) {
|
|
1321
|
+
const text = body.trimEnd();
|
|
1322
|
+
if (!text.endsWith(SECONDS_SUFFIX)) return void 0;
|
|
1323
|
+
const head = text.slice(0, -SECONDS_SUFFIX.length);
|
|
1324
|
+
const start = digits_start(head);
|
|
1325
|
+
const name = head.slice(0, start).trim();
|
|
1326
|
+
const digits = head.slice(start);
|
|
1327
|
+
if (name === "" || !is_duration(digits)) return void 0;
|
|
1328
|
+
return { name, duration_ms: Number(digits) * MS_PER_SECOND };
|
|
1329
|
+
}
|
|
1330
|
+
function read_stages(text) {
|
|
1331
|
+
if (!text.includes(git_followup_stages.STAGE_LINE_PREFIX)) return NO_STAGES;
|
|
1332
|
+
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);
|
|
1333
|
+
}
|
|
1334
|
+
var time_followup_stage = { NO_STAGES, read_stages };
|
|
1335
|
+
|
|
1336
|
+
// scripts/lib/status-icons.ts
|
|
1337
|
+
var FAIL_ICON = "\u2717";
|
|
1338
|
+
var PASS_ICON = "\u2714";
|
|
1339
|
+
var WARN_ICON = "\u26A0";
|
|
1340
|
+
var status_icons = { FAIL_ICON, PASS_ICON, WARN_ICON };
|
|
1341
|
+
|
|
1342
|
+
// scripts/josh/josh-verdict.ts
|
|
1343
|
+
var { FAIL_ICON: FAIL_ICON2, PASS_ICON: PASS_ICON2, WARN_ICON: WARN_ICON2 } = status_icons;
|
|
1344
|
+
var GATE_SUBJECT = "verification gate";
|
|
1345
|
+
var GATE_PASSED_PREFIX = `${PASS_ICON2} ${GATE_SUBJECT} passed`;
|
|
1346
|
+
var GATE_FAILED_PREFIX = `${FAIL_ICON2} ${GATE_SUBJECT} failed`;
|
|
1347
|
+
var GATE_UNVERIFIED_PREFIX = `${WARN_ICON2} ${GATE_SUBJECT} not verified`;
|
|
1348
|
+
var PASSED_VERDICT = "passed";
|
|
1349
|
+
var FAILED_VERDICT = "failed";
|
|
1350
|
+
var UNVERIFIED_VERDICT = "unverified";
|
|
1351
|
+
function format_counts(counts) {
|
|
1352
|
+
if (counts.skipped === 0) return `${String(counts.ran)} checks`;
|
|
1353
|
+
return `${String(counts.ran)} ran, ${String(counts.skipped)} skipped`;
|
|
1354
|
+
}
|
|
1355
|
+
function format_gate_passed(counts, total) {
|
|
1356
|
+
return `${GATE_PASSED_PREFIX} (${format_counts(counts)}) in ${total}.`;
|
|
1357
|
+
}
|
|
1358
|
+
function format_gate_unverified(skipped, total) {
|
|
1359
|
+
return `${GATE_UNVERIFIED_PREFIX} (0 ran, ${String(skipped)} skipped) in ${total}.`;
|
|
1360
|
+
}
|
|
1361
|
+
function format_gate_failed(failed_labels, total) {
|
|
1362
|
+
return `${GATE_FAILED_PREFIX}: ${failed_labels} (${total})`;
|
|
1363
|
+
}
|
|
1364
|
+
var GATE_OPENING_PREFIX = "plan: ";
|
|
1365
|
+
var GATE_OPENING_MARK = " checks at once";
|
|
1366
|
+
function is_gate_opening(line) {
|
|
1367
|
+
const trimmed = line.trimStart();
|
|
1368
|
+
return trimmed.startsWith(GATE_OPENING_PREFIX) && trimmed.includes(GATE_OPENING_MARK);
|
|
1369
|
+
}
|
|
1370
|
+
function read_verdict(line) {
|
|
1371
|
+
const trimmed = line.trimStart();
|
|
1372
|
+
if (trimmed.startsWith(GATE_FAILED_PREFIX)) return FAILED_VERDICT;
|
|
1373
|
+
if (trimmed.startsWith(GATE_PASSED_PREFIX)) return PASSED_VERDICT;
|
|
1374
|
+
if (trimmed.startsWith(GATE_UNVERIFIED_PREFIX)) return UNVERIFIED_VERDICT;
|
|
1375
|
+
return void 0;
|
|
1376
|
+
}
|
|
1377
|
+
var josh_verdict = {
|
|
1378
|
+
PASSED_VERDICT,
|
|
1379
|
+
FAILED_VERDICT,
|
|
1380
|
+
UNVERIFIED_VERDICT,
|
|
1381
|
+
format_gate_passed,
|
|
1382
|
+
format_gate_failed,
|
|
1383
|
+
format_gate_unverified,
|
|
1384
|
+
GATE_OPENING_MARK,
|
|
1385
|
+
GATE_OPENING_PREFIX,
|
|
1386
|
+
is_gate_opening,
|
|
1387
|
+
read_verdict
|
|
1388
|
+
};
|
|
1389
|
+
|
|
1390
|
+
// scripts/time-runtime/time-reported-failure.ts
|
|
1391
|
+
import { z as z3 } from "zod";
|
|
1392
|
+
var TEXT_BLOCK_SCHEMA = z3.object({ text: z3.string().nullish() });
|
|
1393
|
+
var CONTENT_SCHEMA2 = z3.union([z3.string(), z3.array(z3.unknown())]);
|
|
1394
|
+
var LINE_SEPARATOR2 = "\n";
|
|
1395
|
+
function block_text(block) {
|
|
1396
|
+
const parsed = TEXT_BLOCK_SCHEMA.safeParse(block);
|
|
1397
|
+
return parsed.success ? parsed.data.text ?? "" : "";
|
|
1398
|
+
}
|
|
1399
|
+
function result_text2(content) {
|
|
1400
|
+
const parsed = CONTENT_SCHEMA2.safeParse(content);
|
|
1401
|
+
if (!parsed.success) return "";
|
|
1402
|
+
if (typeof parsed.data === "string") return parsed.data;
|
|
1403
|
+
return parsed.data.map((block) => block_text(block)).join(LINE_SEPARATOR2);
|
|
1404
|
+
}
|
|
1405
|
+
function is_failure_line(line) {
|
|
1406
|
+
return line.trimStart().startsWith(status_icons.FAIL_ICON);
|
|
1407
|
+
}
|
|
1408
|
+
function is_failed_verdict(line) {
|
|
1409
|
+
return josh_verdict.read_verdict(line) === josh_verdict.FAILED_VERDICT;
|
|
1410
|
+
}
|
|
1411
|
+
var GREEN_VERDICTS = /* @__PURE__ */ new Set([
|
|
1412
|
+
josh_verdict.PASSED_VERDICT,
|
|
1413
|
+
josh_verdict.UNVERIFIED_VERDICT
|
|
1414
|
+
]);
|
|
1415
|
+
function is_green_verdict(line) {
|
|
1416
|
+
return GREEN_VERDICTS.has(josh_verdict.read_verdict(line));
|
|
1417
|
+
}
|
|
1418
|
+
function new_scan() {
|
|
1419
|
+
return {
|
|
1420
|
+
did_find: false,
|
|
1421
|
+
has_failure_before_region: false,
|
|
1422
|
+
has_failure_in_region: false,
|
|
1423
|
+
is_region_open: false
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
function close_region(scan) {
|
|
1427
|
+
scan.did_find ||= scan.is_region_open && scan.has_failure_before_region;
|
|
1428
|
+
scan.has_failure_before_region = false;
|
|
1429
|
+
scan.has_failure_in_region = false;
|
|
1430
|
+
scan.is_region_open = false;
|
|
1431
|
+
}
|
|
1432
|
+
function note_failure(scan) {
|
|
1433
|
+
if (scan.is_region_open) {
|
|
1434
|
+
scan.has_failure_in_region = true;
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
scan.has_failure_before_region = true;
|
|
1438
|
+
}
|
|
1439
|
+
function scan_line(scan, line) {
|
|
1440
|
+
if (is_green_verdict(line)) {
|
|
1441
|
+
close_region(scan);
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
if (is_failure_line(line)) {
|
|
1445
|
+
note_failure(scan);
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
if (josh_verdict.is_gate_opening(line)) scan.is_region_open = true;
|
|
1449
|
+
}
|
|
1450
|
+
function scan_body(lines) {
|
|
1451
|
+
const scan = new_scan();
|
|
1452
|
+
for (const line of lines) scan_line(scan, line);
|
|
1453
|
+
return scan;
|
|
1454
|
+
}
|
|
1455
|
+
function did_scan_find(scan) {
|
|
1456
|
+
return scan.did_find || scan.has_failure_before_region || scan.has_failure_in_region;
|
|
1457
|
+
}
|
|
1458
|
+
function has_failure_line(content) {
|
|
1459
|
+
const lines = result_text2(content).split(LINE_SEPARATOR2);
|
|
1460
|
+
if (lines.some((line) => is_failed_verdict(line))) return true;
|
|
1461
|
+
return did_scan_find(scan_body(lines));
|
|
1462
|
+
}
|
|
1463
|
+
function is_reported_failure(josh_command, did_print_failure) {
|
|
1464
|
+
return josh_command !== "" && did_print_failure;
|
|
1465
|
+
}
|
|
1466
|
+
var time_reported_failure = { result_text: result_text2, has_failure_line, is_reported_failure };
|
|
1467
|
+
|
|
1468
|
+
// scripts/cost-runtime/cost-attribute.ts
|
|
1469
|
+
var ISSUE_BRANCH_PATTERN = /^(\d+)-/u;
|
|
1470
|
+
var UNATTRIBUTED_KEY = -1;
|
|
1471
|
+
function issue_from_branch(branch) {
|
|
1472
|
+
const matched = ISSUE_BRANCH_PATTERN.exec(branch);
|
|
1473
|
+
return matched?.[1] === void 0 ? UNATTRIBUTED_KEY : Number(matched[1]);
|
|
1474
|
+
}
|
|
1475
|
+
function declared_issue(record2) {
|
|
1476
|
+
const declared = record2.issue ?? UNATTRIBUTED_KEY;
|
|
1477
|
+
return declared === UNATTRIBUTED_KEY ? issue_from_branch(record2.branch) : declared;
|
|
1478
|
+
}
|
|
1479
|
+
function fill(declared, is_reverse) {
|
|
1480
|
+
const filled = Array.from({ length: declared.length }, () => UNATTRIBUTED_KEY);
|
|
1481
|
+
const order = declared.map((_value, index) => is_reverse ? declared.length - 1 - index : index);
|
|
1482
|
+
let carried = UNATTRIBUTED_KEY;
|
|
1483
|
+
for (const index of order) {
|
|
1484
|
+
const own = declared[index] ?? UNATTRIBUTED_KEY;
|
|
1485
|
+
carried = own === UNATTRIBUTED_KEY ? carried : own;
|
|
1486
|
+
filled[index] = carried;
|
|
1487
|
+
}
|
|
1488
|
+
return filled;
|
|
1489
|
+
}
|
|
1490
|
+
function is_attributed(value) {
|
|
1491
|
+
return value !== void 0 && value !== UNATTRIBUTED_KEY;
|
|
1492
|
+
}
|
|
1493
|
+
function pick(own, carried, next, previous) {
|
|
1494
|
+
if (is_attributed(own)) return own;
|
|
1495
|
+
if (is_attributed(carried)) return carried;
|
|
1496
|
+
if (is_attributed(next)) return next;
|
|
1497
|
+
return previous ?? UNATTRIBUTED_KEY;
|
|
1498
|
+
}
|
|
1499
|
+
function announcements(records) {
|
|
1500
|
+
return fill(
|
|
1501
|
+
records.map((record2) => record2.issue ?? UNATTRIBUTED_KEY),
|
|
1502
|
+
false
|
|
1503
|
+
);
|
|
1504
|
+
}
|
|
1505
|
+
function attribute(records) {
|
|
1506
|
+
const declared = records.map((record2) => declared_issue(record2));
|
|
1507
|
+
const carried = announcements(records);
|
|
1508
|
+
const next = fill(declared, true);
|
|
1509
|
+
const previous = fill(declared, false);
|
|
1510
|
+
return declared.map(
|
|
1511
|
+
(own, index) => pick(own, carried[index] ?? UNATTRIBUTED_KEY, next[index], previous[index])
|
|
1512
|
+
);
|
|
1513
|
+
}
|
|
1514
|
+
function group_by_issue(records) {
|
|
1515
|
+
const issues = attribute(records);
|
|
1516
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
1517
|
+
for (const [index, record2] of records.entries()) {
|
|
1518
|
+
const bucket = grouped.get(issues[index] ?? UNATTRIBUTED_KEY) ?? [];
|
|
1519
|
+
bucket.push(record2);
|
|
1520
|
+
grouped.set(issues[index] ?? UNATTRIBUTED_KEY, bucket);
|
|
1521
|
+
}
|
|
1522
|
+
return [...grouped].toSorted(([left], [right]) => left - right).map(([issue, bucket]) => ({ issue, records: bucket }));
|
|
1523
|
+
}
|
|
1524
|
+
function records_for_issue(records, issue_number) {
|
|
1525
|
+
const issues = attribute(records);
|
|
1526
|
+
return records.filter((_record, index) => issues[index] === issue_number);
|
|
1527
|
+
}
|
|
1528
|
+
var cost_attribute = {
|
|
1529
|
+
UNATTRIBUTED_KEY,
|
|
1530
|
+
issue_from_branch,
|
|
1531
|
+
declared_issue,
|
|
1532
|
+
attribute,
|
|
1533
|
+
group_by_issue,
|
|
1534
|
+
records_for_issue
|
|
1535
|
+
};
|
|
1536
|
+
|
|
1537
|
+
// scripts/time-runtime/time-markers.ts
|
|
1538
|
+
var NO_MARKER = "none";
|
|
1539
|
+
var PLAN_MARKER = "plan";
|
|
1540
|
+
var EDIT_MARKER = "edit";
|
|
1541
|
+
var REVIEW_MARKER = "review";
|
|
1542
|
+
var WORKFLOW_MARKER = "workflow";
|
|
1543
|
+
var EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
1544
|
+
var SKILL_TOOL = "Skill";
|
|
1545
|
+
var SKILL_KEY = "skill";
|
|
1546
|
+
var REVIEW_SKILL = "code-review";
|
|
1547
|
+
var WORKFLOW_SKILL = "workflow-commands";
|
|
1548
|
+
var AGENT_TOOL = "Agent";
|
|
1549
|
+
var PROMPT_KEY = "prompt";
|
|
1550
|
+
var REVIEW_INVOCATION = "/code-review";
|
|
1551
|
+
var REVIEW_ATTEST = "review:attest";
|
|
1552
|
+
var SKILL_MARKERS = /* @__PURE__ */ new Map([
|
|
1553
|
+
[REVIEW_SKILL, REVIEW_MARKER],
|
|
1554
|
+
[WORKFLOW_SKILL, WORKFLOW_MARKER]
|
|
1555
|
+
]);
|
|
1556
|
+
var ISSUE_API_PATTERN = /repos\/\S+\/issues\/\d+/u;
|
|
1557
|
+
var BODY_FIELD_PATTERN = /\bbody=/u;
|
|
1558
|
+
var ISSUE_COMMENT_PATTERN = /\bgh\s+issue\s+comment\b/u;
|
|
1559
|
+
var BODY_FLAG_PATTERN = /--body(?:-file)?\b/u;
|
|
1560
|
+
var ISSUE_PLAN_PATTERN = /(?:^|[;&|]\s*)pnpm\s+josh\s+issue:plan\b/u;
|
|
1561
|
+
var ISSUE_LABELS_PATTERN = /repos\/\S+\/issues\/(\d+)\/labels\b(?!\/)/u;
|
|
1562
|
+
var IN_PROGRESS_FIELD = "labels[]=in-progress";
|
|
1563
|
+
var RUN_ENTRY_PATTERN = /\bjosh\s+run:entry\s+(\d+)\b/u;
|
|
1564
|
+
var NO_ISSUE = cost_attribute.UNATTRIBUTED_KEY;
|
|
1565
|
+
function string_field(input, key) {
|
|
1566
|
+
if (!json_value.is_record(input)) return "";
|
|
1567
|
+
const value = input[key];
|
|
1568
|
+
return typeof value === "string" ? value : "";
|
|
1569
|
+
}
|
|
1570
|
+
function skill_name(input) {
|
|
1571
|
+
return string_field(input, SKILL_KEY);
|
|
1572
|
+
}
|
|
1573
|
+
function agent_marker(input) {
|
|
1574
|
+
const prompt = string_field(input, PROMPT_KEY);
|
|
1575
|
+
const is_review = prompt.includes(REVIEW_INVOCATION) && prompt.includes(REVIEW_ATTEST);
|
|
1576
|
+
return is_review ? REVIEW_MARKER : NO_MARKER;
|
|
1577
|
+
}
|
|
1578
|
+
function tool_marker(name, input) {
|
|
1579
|
+
if (EDIT_TOOLS.has(name)) return EDIT_MARKER;
|
|
1580
|
+
if (name === AGENT_TOOL) return agent_marker(input);
|
|
1581
|
+
if (name !== SKILL_TOOL) return NO_MARKER;
|
|
1582
|
+
return SKILL_MARKERS.get(skill_name(input)) ?? NO_MARKER;
|
|
1583
|
+
}
|
|
1584
|
+
function is_api_body_write(command) {
|
|
1585
|
+
return ISSUE_API_PATTERN.test(command) && BODY_FIELD_PATTERN.test(command);
|
|
1586
|
+
}
|
|
1587
|
+
function is_issue_comment(command) {
|
|
1588
|
+
return ISSUE_COMMENT_PATTERN.test(command) && BODY_FLAG_PATTERN.test(command);
|
|
1589
|
+
}
|
|
1590
|
+
function is_plan_write(command) {
|
|
1591
|
+
return is_api_body_write(command) || is_issue_comment(command) || ISSUE_PLAN_PATTERN.test(command);
|
|
1592
|
+
}
|
|
1593
|
+
function is_in_progress_label(command) {
|
|
1594
|
+
return ISSUE_LABELS_PATTERN.test(command) && command.includes(IN_PROGRESS_FIELD);
|
|
1595
|
+
}
|
|
1596
|
+
function is_run_start(command) {
|
|
1597
|
+
return is_in_progress_label(command) || RUN_ENTRY_PATTERN.test(command);
|
|
1598
|
+
}
|
|
1599
|
+
var COMMAND_SEPARATOR = /&&|\|\||;/u;
|
|
1600
|
+
function declared_issue2(part) {
|
|
1601
|
+
const pattern = is_in_progress_label(part) ? ISSUE_LABELS_PATTERN : RUN_ENTRY_PATTERN;
|
|
1602
|
+
const matched = pattern.exec(part);
|
|
1603
|
+
return matched?.[1] === void 0 ? NO_ISSUE : Number(matched[1]);
|
|
1604
|
+
}
|
|
1605
|
+
function bash_issue(command) {
|
|
1606
|
+
for (const part of command.split(COMMAND_SEPARATOR)) {
|
|
1607
|
+
if (is_run_start(part)) return declared_issue2(part);
|
|
1608
|
+
}
|
|
1609
|
+
return NO_ISSUE;
|
|
1610
|
+
}
|
|
1611
|
+
function bash_marker(command) {
|
|
1612
|
+
if (is_run_start(command)) return WORKFLOW_MARKER;
|
|
1613
|
+
return is_plan_write(command) ? PLAN_MARKER : NO_MARKER;
|
|
1614
|
+
}
|
|
1615
|
+
var time_markers = {
|
|
1616
|
+
NO_MARKER,
|
|
1617
|
+
PLAN_MARKER,
|
|
1618
|
+
EDIT_MARKER,
|
|
1619
|
+
REVIEW_MARKER,
|
|
1620
|
+
WORKFLOW_MARKER,
|
|
1621
|
+
NO_ISSUE,
|
|
1622
|
+
tool_marker,
|
|
1623
|
+
bash_marker,
|
|
1624
|
+
bash_issue
|
|
1625
|
+
};
|
|
1626
|
+
|
|
1627
|
+
// scripts/time-runtime/time-single-check.ts
|
|
1628
|
+
var CHECK_COMMANDS = /* @__PURE__ */ new Set([
|
|
1629
|
+
"josh check",
|
|
1630
|
+
"josh cspell",
|
|
1631
|
+
"josh cspell:dot",
|
|
1632
|
+
"josh lint",
|
|
1633
|
+
"josh lint:related",
|
|
1634
|
+
"josh test:related",
|
|
1635
|
+
"josh test:unit"
|
|
1636
|
+
]);
|
|
1637
|
+
var NO_CHECK = "";
|
|
1638
|
+
var KEY_SEPARATOR = " ";
|
|
1639
|
+
function argument_key(command) {
|
|
1640
|
+
return [...new Set(time_shell.josh_arguments(command))].toSorted(
|
|
1641
|
+
(left, right) => left.localeCompare(right)
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
function check_key(josh_command, command) {
|
|
1645
|
+
if (!CHECK_COMMANDS.has(josh_command)) return NO_CHECK;
|
|
1646
|
+
return [josh_command, ...argument_key(command)].join(KEY_SEPARATOR);
|
|
1647
|
+
}
|
|
1648
|
+
var time_single_check = { NO_CHECK, check_key };
|
|
1649
|
+
|
|
1650
|
+
// scripts/time-runtime/time-transcript-line.ts
|
|
1651
|
+
var UNKNOWN_BRANCH = "";
|
|
1652
|
+
var PROMPT_KEY2 = "prompt";
|
|
1653
|
+
var NO_MESSAGE_ID = "";
|
|
1654
|
+
var ERROR_TEXT_LIMIT = 256;
|
|
1655
|
+
var REFUSAL_MARKER = "\u26D4";
|
|
1656
|
+
var HOOK_ERROR_LABEL = /^PreToolUse:\S+ hook error: /u;
|
|
1657
|
+
var STOP_FEEDBACK_LABEL = /^Stop hook feedback:\s*/u;
|
|
1658
|
+
var TOKEN_LINE = /^[a-z][a-z-]*$/u;
|
|
1659
|
+
var TOKEN_LINE_LIMIT = 8;
|
|
1660
|
+
function block_names(raw) {
|
|
1661
|
+
return {
|
|
1662
|
+
type: raw.type ?? "",
|
|
1663
|
+
name: raw.name ?? "",
|
|
1664
|
+
id: raw.id ?? "",
|
|
1665
|
+
result_id: raw.tool_use_id ?? ""
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1668
|
+
function refusal_body(text) {
|
|
1669
|
+
return text.trimStart().replace(HOOK_ERROR_LABEL, "");
|
|
1670
|
+
}
|
|
1671
|
+
function guard_from_refusal(text) {
|
|
1672
|
+
const trimmed = refusal_body(text);
|
|
1673
|
+
if (!trimmed.startsWith(REFUSAL_MARKER)) return "";
|
|
1674
|
+
const headline = trimmed.slice(REFUSAL_MARKER.length).split("\n", 1)[0]?.trimStart() ?? "";
|
|
1675
|
+
const colon = headline.indexOf(":");
|
|
1676
|
+
return (colon === -1 ? headline : headline.slice(0, colon)).trim();
|
|
1677
|
+
}
|
|
1678
|
+
function stop_feedback_of(data) {
|
|
1679
|
+
const content = data.message?.content;
|
|
1680
|
+
if (typeof content !== "string" || !STOP_FEEDBACK_LABEL.test(content)) return "";
|
|
1681
|
+
return content.replace(STOP_FEEDBACK_LABEL, "").trim();
|
|
1682
|
+
}
|
|
1683
|
+
function token_lines_of(text) {
|
|
1684
|
+
return text.split("\n").map((line) => line.trim()).filter((line) => TOKEN_LINE.test(line)).slice(0, TOKEN_LINE_LIMIT);
|
|
1685
|
+
}
|
|
1686
|
+
function to_block2(raw) {
|
|
1687
|
+
const text = time_reported_failure.result_text(raw.content);
|
|
1688
|
+
const is_error = raw.is_error ?? void 0;
|
|
1689
|
+
return {
|
|
1690
|
+
...block_names(raw),
|
|
1691
|
+
input: raw.input,
|
|
1692
|
+
is_error,
|
|
1693
|
+
has_failure_line: time_reported_failure.has_failure_line(text),
|
|
1694
|
+
followup_stages: time_followup_stage.read_stages(text),
|
|
1695
|
+
error_text: is_error === true ? text.slice(0, ERROR_TEXT_LIMIT) : "",
|
|
1696
|
+
refusal_guard: is_error === true ? guard_from_refusal(text) : "",
|
|
1697
|
+
token_lines: is_error === true ? [] : token_lines_of(text),
|
|
1698
|
+
background_id: time_background.launch_id(text),
|
|
1699
|
+
agent_id: time_background.agent_launch_id(text)
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
function to_blocks2(content) {
|
|
1703
|
+
return typeof content === "string" || content === null || content === void 0 ? [] : content.map((block) => to_block2(block));
|
|
1704
|
+
}
|
|
1705
|
+
function message_fields(message) {
|
|
1706
|
+
return { message_id: message?.id ?? NO_MESSAGE_ID, blocks: to_blocks2(message?.content) };
|
|
1707
|
+
}
|
|
1708
|
+
function notice_text(data) {
|
|
1709
|
+
const attachment = json_value.is_record(data.attachment) ? data.attachment[PROMPT_KEY2] : void 0;
|
|
1710
|
+
const carried = [data.message?.content, data.content, attachment];
|
|
1711
|
+
return carried.find((one) => typeof one === "string") ?? "";
|
|
1712
|
+
}
|
|
1713
|
+
function stopped_background(content) {
|
|
1714
|
+
if (!Array.isArray(content)) return time_background.NO_BACKGROUND;
|
|
1715
|
+
const ids = content.map(
|
|
1716
|
+
(block) => typeof block.content === "string" ? time_background.stopped_id(block.content) : ""
|
|
1717
|
+
);
|
|
1718
|
+
return ids.find((id) => id !== time_background.NO_BACKGROUND) ?? time_background.NO_BACKGROUND;
|
|
1719
|
+
}
|
|
1720
|
+
function finished_background(data) {
|
|
1721
|
+
const notice = time_background.finished_id(notice_text(data));
|
|
1722
|
+
return notice === time_background.NO_BACKGROUND ? stopped_background(data.message?.content) : notice;
|
|
1723
|
+
}
|
|
1724
|
+
function to_line(data) {
|
|
1725
|
+
const timestamp_ms = time_instant.parse_instant(data.timestamp);
|
|
1726
|
+
if (timestamp_ms === void 0) return void 0;
|
|
1727
|
+
const stop_feedback = stop_feedback_of(data);
|
|
1728
|
+
return {
|
|
1729
|
+
type: data.type ?? "",
|
|
1730
|
+
timestamp_ms,
|
|
1731
|
+
branch: data.gitBranch ?? UNKNOWN_BRANCH,
|
|
1732
|
+
finished_background: finished_background(data),
|
|
1733
|
+
stop_feedback,
|
|
1734
|
+
stop_guard: guard_from_refusal(stop_feedback),
|
|
1735
|
+
...message_fields(data.message)
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1738
|
+
function parse_line2(line) {
|
|
1739
|
+
const record2 = transcript_record.parse(line);
|
|
1740
|
+
return record2 === void 0 ? void 0 : to_line(record2);
|
|
1741
|
+
}
|
|
1742
|
+
function parse_text(text) {
|
|
1743
|
+
return text.split("\n").flatMap((line) => parse_line2(line) ?? []);
|
|
1744
|
+
}
|
|
1745
|
+
var time_transcript_line = {
|
|
1746
|
+
ERROR_TEXT_LIMIT,
|
|
1747
|
+
NO_MESSAGE_ID,
|
|
1748
|
+
TOKEN_LINE_LIMIT,
|
|
1749
|
+
guard_from_refusal,
|
|
1750
|
+
parse_line: parse_line2,
|
|
1751
|
+
parse_text,
|
|
1752
|
+
refusal_body
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1755
|
+
// scripts/time-runtime/time-writes.ts
|
|
1756
|
+
function bash_writes(command) {
|
|
1757
|
+
const segment = time_bundle_call.write_segment(command);
|
|
1758
|
+
return time_bundle_call.is_in_place_sed(segment) ? time_bundle_call.targets_in(segment) : [];
|
|
1759
|
+
}
|
|
1760
|
+
function tool_writes(name, input) {
|
|
1761
|
+
if (time_markers.tool_marker(name, input) !== time_markers.EDIT_MARKER) return [];
|
|
1762
|
+
return time_bundle_call.tool_targets(input);
|
|
1763
|
+
}
|
|
1764
|
+
var time_writes = {
|
|
1765
|
+
bash_writes,
|
|
1766
|
+
tool_writes
|
|
1767
|
+
};
|
|
1768
|
+
|
|
1769
|
+
// scripts/time-runtime/time-tool-call.ts
|
|
1770
|
+
var { NO_MESSAGE_ID: NO_MESSAGE_ID2 } = time_transcript_line;
|
|
1771
|
+
var UNKNOWN_TOOL = "unknown";
|
|
1772
|
+
var NO_CALL = {
|
|
1773
|
+
label: "",
|
|
1774
|
+
josh_command: "",
|
|
1775
|
+
josh_commands: [],
|
|
1776
|
+
josh_signatures: [],
|
|
1777
|
+
check_key: time_single_check.NO_CHECK,
|
|
1778
|
+
marker: time_markers.NO_MARKER,
|
|
1779
|
+
message_id: NO_MESSAGE_ID2,
|
|
1780
|
+
writes: [],
|
|
1781
|
+
issue: time_markers.NO_ISSUE,
|
|
1782
|
+
reads_background: time_background.NO_BACKGROUND,
|
|
1783
|
+
...time_bundle_call.not_bundleable()
|
|
1784
|
+
};
|
|
1785
|
+
var UNKNOWN_CALL = {
|
|
1786
|
+
label: UNKNOWN_TOOL,
|
|
1787
|
+
josh_command: "",
|
|
1788
|
+
josh_commands: [],
|
|
1789
|
+
josh_signatures: [],
|
|
1790
|
+
check_key: time_single_check.NO_CHECK,
|
|
1791
|
+
marker: time_markers.NO_MARKER,
|
|
1792
|
+
message_id: NO_MESSAGE_ID2,
|
|
1793
|
+
writes: [],
|
|
1794
|
+
issue: time_markers.NO_ISSUE,
|
|
1795
|
+
reads_background: time_background.NO_BACKGROUND,
|
|
1796
|
+
...time_bundle_call.not_bundleable()
|
|
1797
|
+
};
|
|
1798
|
+
function non_bash_call(name, input, message_id) {
|
|
1799
|
+
return {
|
|
1800
|
+
label: name,
|
|
1801
|
+
josh_command: "",
|
|
1802
|
+
josh_commands: [],
|
|
1803
|
+
josh_signatures: [],
|
|
1804
|
+
check_key: time_single_check.NO_CHECK,
|
|
1805
|
+
marker: time_markers.tool_marker(name, input),
|
|
1806
|
+
message_id,
|
|
1807
|
+
writes: time_writes.tool_writes(name, input),
|
|
1808
|
+
issue: time_markers.NO_ISSUE,
|
|
1809
|
+
// A non-Bash tool joins a backgrounded command too — `BashOutput` carries the shell id in a
|
|
1810
|
+
// field of its own, `Monitor` names the same `…/tasks/<id>.output` path in a command — so the
|
|
1811
|
+
// same reader is asked here rather than the field being left empty for every tool but `Bash`.
|
|
1812
|
+
reads_background: time_background.read_id_of(input),
|
|
1813
|
+
...time_bundle_call.tool_facts(name, input)
|
|
1814
|
+
};
|
|
1815
|
+
}
|
|
1816
|
+
function bash_call(input, message_id) {
|
|
1817
|
+
const command = time_shell.bash_command(input);
|
|
1818
|
+
const josh_command = time_shell.josh_command_of(command);
|
|
1819
|
+
return {
|
|
1820
|
+
label: time_shell.bash_label(command),
|
|
1821
|
+
josh_command,
|
|
1822
|
+
josh_commands: time_shell.josh_commands_of(command),
|
|
1823
|
+
josh_signatures: time_shell.josh_signatures_of(command),
|
|
1824
|
+
check_key: time_single_check.check_key(josh_command, command),
|
|
1825
|
+
marker: time_markers.bash_marker(command),
|
|
1826
|
+
message_id,
|
|
1827
|
+
writes: time_writes.bash_writes(command),
|
|
1828
|
+
issue: time_markers.bash_issue(command),
|
|
1829
|
+
reads_background: time_background.read_id_of(input),
|
|
1830
|
+
...time_bundle_call.bash_facts(command)
|
|
1831
|
+
};
|
|
1832
|
+
}
|
|
1833
|
+
function to_tool_call(name, input, message_id) {
|
|
1834
|
+
if (name !== cost_blocks.BASH_TOOL) return non_bash_call(name, input, message_id);
|
|
1835
|
+
return bash_call(input, message_id);
|
|
1836
|
+
}
|
|
1837
|
+
var time_tool_call = {
|
|
1838
|
+
UNKNOWN_TOOL,
|
|
1839
|
+
NO_CALL,
|
|
1840
|
+
UNKNOWN_CALL,
|
|
1841
|
+
to_tool_call
|
|
1842
|
+
};
|
|
1843
|
+
|
|
1844
|
+
// scripts/time-runtime/time-spans.ts
|
|
1845
|
+
var { NO_MESSAGE_ID: NO_MESSAGE_ID3, parse_line: parse_line3 } = time_transcript_line;
|
|
1846
|
+
var { NO_CALL: NO_CALL2, UNKNOWN_CALL: UNKNOWN_CALL2, UNKNOWN_TOOL: UNKNOWN_TOOL2, to_tool_call: to_tool_call2 } = time_tool_call;
|
|
1847
|
+
var ASSISTANT_TYPE = "assistant";
|
|
1848
|
+
var USER_TYPE = "user";
|
|
1849
|
+
var MODEL_CATEGORY = "model";
|
|
1850
|
+
var TOOL_CATEGORY = "tool";
|
|
1851
|
+
var HUMAN_CATEGORY = "human";
|
|
1852
|
+
var OK_OUTCOME = "ok";
|
|
1853
|
+
var FAILED_OUTCOME = "failed";
|
|
1854
|
+
var UNKNOWN_OUTCOME = "unknown";
|
|
1855
|
+
var NO_RESULT = {
|
|
1856
|
+
call_id: "",
|
|
1857
|
+
outcome: UNKNOWN_OUTCOME,
|
|
1858
|
+
refusal_guard: "",
|
|
1859
|
+
background_id: time_background.NO_BACKGROUND,
|
|
1860
|
+
followup_stages: time_followup_stage.NO_STAGES
|
|
1861
|
+
};
|
|
1862
|
+
function tool_use_blocks(lines) {
|
|
1863
|
+
return lines.flatMap(
|
|
1864
|
+
(line) => line.blocks.filter((block) => block.type === cost_blocks.TOOL_USE_TYPE && block.id !== "").map((block) => ({ block, message_id: line.message_id }))
|
|
1865
|
+
);
|
|
1866
|
+
}
|
|
1867
|
+
function collect_calls(lines) {
|
|
1868
|
+
return new Map(
|
|
1869
|
+
tool_use_blocks(lines).map(({ block, message_id }) => [
|
|
1870
|
+
block.id,
|
|
1871
|
+
to_tool_call2(block.name, block.input, message_id)
|
|
1872
|
+
])
|
|
1873
|
+
);
|
|
1874
|
+
}
|
|
1875
|
+
function result_block(line) {
|
|
1876
|
+
return line.blocks.find((block) => block.type === cost_blocks.TOOL_RESULT_TYPE);
|
|
1877
|
+
}
|
|
1878
|
+
function event_of(line, category, call, result = NO_RESULT) {
|
|
1879
|
+
return { timestamp_ms: line.timestamp_ms, branch: line.branch, category, ...result, ...call };
|
|
1880
|
+
}
|
|
1881
|
+
function outcome_of(result, call) {
|
|
1882
|
+
if (time_reported_failure.is_reported_failure(call.josh_command, result.has_failure_line)) {
|
|
1883
|
+
return FAILED_OUTCOME;
|
|
1884
|
+
}
|
|
1885
|
+
if (result.is_error === void 0) return UNKNOWN_OUTCOME;
|
|
1886
|
+
return result.is_error ? FAILED_OUTCOME : OK_OUTCOME;
|
|
1887
|
+
}
|
|
1888
|
+
function facts_of(result, call) {
|
|
1889
|
+
return {
|
|
1890
|
+
call_id: result.result_id,
|
|
1891
|
+
outcome: outcome_of(result, call),
|
|
1892
|
+
refusal_guard: result.refusal_guard,
|
|
1893
|
+
background_id: result.background_id,
|
|
1894
|
+
followup_stages: result.followup_stages
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
function user_event(line, calls) {
|
|
1898
|
+
const result = result_block(line);
|
|
1899
|
+
if (result === void 0) return event_of(line, HUMAN_CATEGORY, NO_CALL2);
|
|
1900
|
+
const call = calls.get(result.result_id) ?? UNKNOWN_CALL2;
|
|
1901
|
+
return event_of(line, TOOL_CATEGORY, call, facts_of(result, call));
|
|
1902
|
+
}
|
|
1903
|
+
function to_event(line, calls) {
|
|
1904
|
+
if (line.type === ASSISTANT_TYPE) {
|
|
1905
|
+
return event_of(line, MODEL_CATEGORY, { ...NO_CALL2, message_id: line.message_id });
|
|
1906
|
+
}
|
|
1907
|
+
return line.type === USER_TYPE ? user_event(line, calls) : void 0;
|
|
1908
|
+
}
|
|
1909
|
+
function to_events(lines, calls) {
|
|
1910
|
+
return lines.map((line) => to_event(line, calls)).filter((event) => event !== void 0).toSorted((left, right) => left.timestamp_ms - right.timestamp_ms);
|
|
1911
|
+
}
|
|
1912
|
+
function equal_durations(duration_ms) {
|
|
1913
|
+
return { duration_ms, own_duration_ms: duration_ms };
|
|
1914
|
+
}
|
|
1915
|
+
function no_background() {
|
|
1916
|
+
const none = time_background.NO_BACKGROUND;
|
|
1917
|
+
return {
|
|
1918
|
+
background_id: none,
|
|
1919
|
+
reads_background: none,
|
|
1920
|
+
background_command: none,
|
|
1921
|
+
background_ended_ms: time_background.NO_FINISH
|
|
1922
|
+
};
|
|
1923
|
+
}
|
|
1924
|
+
function background_fields(event, finished) {
|
|
1925
|
+
return {
|
|
1926
|
+
background_id: event.background_id,
|
|
1927
|
+
reads_background: event.reads_background,
|
|
1928
|
+
background_command: time_background.NO_BACKGROUND,
|
|
1929
|
+
background_ended_ms: finished.get(event.background_id) ?? time_background.NO_FINISH
|
|
1930
|
+
};
|
|
1931
|
+
}
|
|
1932
|
+
function result_facts_of(event) {
|
|
1933
|
+
return {
|
|
1934
|
+
call_id: event.call_id,
|
|
1935
|
+
outcome: event.outcome,
|
|
1936
|
+
refusal_guard: event.refusal_guard,
|
|
1937
|
+
followup_stages: event.followup_stages
|
|
1938
|
+
};
|
|
1939
|
+
}
|
|
1940
|
+
function to_spans(events, finished) {
|
|
1941
|
+
return events.slice(1).map((event, index) => ({
|
|
1942
|
+
category: event.category,
|
|
1943
|
+
label: event.label,
|
|
1944
|
+
josh_command: event.josh_command,
|
|
1945
|
+
josh_commands: event.josh_commands,
|
|
1946
|
+
josh_signatures: event.josh_signatures,
|
|
1947
|
+
check_key: event.check_key,
|
|
1948
|
+
marker: event.marker,
|
|
1949
|
+
is_bundleable: event.is_bundleable,
|
|
1950
|
+
targets: event.targets,
|
|
1951
|
+
is_writing: event.is_writing,
|
|
1952
|
+
may_write: event.may_write,
|
|
1953
|
+
has_prior_reference: event.has_prior_reference,
|
|
1954
|
+
writes: event.writes,
|
|
1955
|
+
message_id: event.message_id,
|
|
1956
|
+
issue: event.issue,
|
|
1957
|
+
branch: event.branch,
|
|
1958
|
+
...result_facts_of(event),
|
|
1959
|
+
is_continuation: false,
|
|
1960
|
+
...background_fields(event, finished),
|
|
1961
|
+
ended_ms: event.timestamp_ms,
|
|
1962
|
+
...equal_durations(event.timestamp_ms - (events[index]?.timestamp_ms ?? event.timestamp_ms))
|
|
1963
|
+
}));
|
|
1964
|
+
}
|
|
1965
|
+
function parse_timeline(text) {
|
|
1966
|
+
const lines = text.split("\n").map((line) => parse_line3(line)).filter((line) => line !== void 0);
|
|
1967
|
+
const events = to_events(lines, collect_calls(lines));
|
|
1968
|
+
return {
|
|
1969
|
+
started_ms: events[0]?.timestamp_ms ?? 0,
|
|
1970
|
+
ended_ms: events.at(-1)?.timestamp_ms ?? 0,
|
|
1971
|
+
// **The positioning happens here rather than in a caller**: a launch and
|
|
1972
|
+
// the call that reads its output are in one transcript, and by the time spans have been merged
|
|
1973
|
+
// across sessions and trimmed they are fragments rather than calls.
|
|
1974
|
+
spans: time_background.positioned(to_spans(events, time_background.finished_at(lines)))
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
function has_transcript_data(span_count) {
|
|
1978
|
+
return span_count > 0;
|
|
1979
|
+
}
|
|
1980
|
+
var time_spans = {
|
|
1981
|
+
ASSISTANT_TYPE,
|
|
1982
|
+
MODEL_CATEGORY,
|
|
1983
|
+
TOOL_CATEGORY,
|
|
1984
|
+
HUMAN_CATEGORY,
|
|
1985
|
+
OK_OUTCOME,
|
|
1986
|
+
FAILED_OUTCOME,
|
|
1987
|
+
UNKNOWN_OUTCOME,
|
|
1988
|
+
NO_MESSAGE_ID: NO_MESSAGE_ID3,
|
|
1989
|
+
UNKNOWN_TOOL: UNKNOWN_TOOL2,
|
|
1990
|
+
has_transcript_data,
|
|
1991
|
+
equal_durations,
|
|
1992
|
+
no_background,
|
|
1993
|
+
// Re-exported so the suites that measure how a command is read keep asking one namespace, and so
|
|
1994
|
+
// `time-shell.ts` moving out of this file changed no call site.
|
|
1995
|
+
bash_label: time_shell.bash_label,
|
|
1996
|
+
josh_command_of: time_shell.josh_command_of,
|
|
1997
|
+
josh_commands_of: time_shell.josh_commands_of,
|
|
1998
|
+
to_tool_call: to_tool_call2,
|
|
1999
|
+
parse_line: parse_line3,
|
|
2000
|
+
parse_timeline
|
|
2001
|
+
};
|
|
2002
|
+
|
|
2003
|
+
// scripts/time-runtime/time-round-trips.ts
|
|
2004
|
+
var CALLS_PER_ROUND_TRIP_FLOOR = 1.5;
|
|
2005
|
+
var DENSITY_DECIMALS = 2;
|
|
2006
|
+
var NONE = 0;
|
|
2007
|
+
function is_tool(span) {
|
|
2008
|
+
return span.category === time_spans.TOOL_CATEGORY;
|
|
2009
|
+
}
|
|
2010
|
+
function is_model(span) {
|
|
2011
|
+
return span.category === time_spans.MODEL_CATEGORY;
|
|
2012
|
+
}
|
|
2013
|
+
function started_ms2(span) {
|
|
2014
|
+
return span.ended_ms - span.duration_ms;
|
|
2015
|
+
}
|
|
2016
|
+
function in_time_order(spans) {
|
|
2017
|
+
return spans.toSorted((left, right) => started_ms2(left) - started_ms2(right));
|
|
2018
|
+
}
|
|
2019
|
+
function is_tool_at(spans, index) {
|
|
2020
|
+
const span = spans[index];
|
|
2021
|
+
return span !== void 0 && is_tool(span);
|
|
2022
|
+
}
|
|
2023
|
+
function is_call(span) {
|
|
2024
|
+
return is_tool(span) && !span.is_continuation;
|
|
2025
|
+
}
|
|
2026
|
+
function count_calls(spans) {
|
|
2027
|
+
return spans.filter((span) => is_call(span)).length;
|
|
2028
|
+
}
|
|
2029
|
+
function previous_break(spans, index) {
|
|
2030
|
+
for (let back = index - 1; back >= 0; back -= 1) {
|
|
2031
|
+
const span = spans[back];
|
|
2032
|
+
if (span === void 0 || !is_model(span)) return span;
|
|
2033
|
+
}
|
|
2034
|
+
return void 0;
|
|
2035
|
+
}
|
|
2036
|
+
function continues_turn(spans, index, message_id) {
|
|
2037
|
+
if (message_id === time_spans.NO_MESSAGE_ID) return false;
|
|
2038
|
+
const earlier = previous_break(spans, index);
|
|
2039
|
+
return earlier !== void 0 && !earlier.is_continuation && earlier.message_id === message_id;
|
|
2040
|
+
}
|
|
2041
|
+
function opens_round_trip(spans, index) {
|
|
2042
|
+
const span = spans[index];
|
|
2043
|
+
if (span === void 0 || !is_tool(span) || span.is_continuation || is_tool_at(spans, index - 1)) {
|
|
2044
|
+
return false;
|
|
2045
|
+
}
|
|
2046
|
+
return !continues_turn(spans, index, span.message_id);
|
|
2047
|
+
}
|
|
2048
|
+
function open_trip(walk) {
|
|
2049
|
+
walk.open = [];
|
|
2050
|
+
walk.trips.push(walk.open);
|
|
2051
|
+
}
|
|
2052
|
+
function place_call(walk, span) {
|
|
2053
|
+
if (is_call(span)) walk.open?.push(span);
|
|
2054
|
+
}
|
|
2055
|
+
function step_trip(walk, span, is_opener) {
|
|
2056
|
+
if (is_opener) open_trip(walk);
|
|
2057
|
+
if (is_tool(span)) place_call(walk, span);
|
|
2058
|
+
else if (!is_model(span)) walk.open = void 0;
|
|
2059
|
+
}
|
|
2060
|
+
function group_round_trips(spans) {
|
|
2061
|
+
const ordered = in_time_order(spans);
|
|
2062
|
+
const walk = { trips: [], open: void 0 };
|
|
2063
|
+
for (const [index, span] of ordered.entries()) {
|
|
2064
|
+
step_trip(walk, span, opens_round_trip(ordered, index));
|
|
2065
|
+
}
|
|
2066
|
+
return walk.trips;
|
|
2067
|
+
}
|
|
2068
|
+
function count_round_trips(spans) {
|
|
2069
|
+
return group_round_trips(spans).length;
|
|
2070
|
+
}
|
|
2071
|
+
function turn_key(span, index) {
|
|
2072
|
+
return span.message_id === time_spans.NO_MESSAGE_ID ? `#${String(index)}` : span.message_id;
|
|
2073
|
+
}
|
|
2074
|
+
function count_turns(spans) {
|
|
2075
|
+
const keys = spans.filter((span) => is_model(span)).map((span, index) => turn_key(span, index));
|
|
2076
|
+
return new Set(keys).size;
|
|
2077
|
+
}
|
|
2078
|
+
function per_round_trip(total, round_trip_count) {
|
|
2079
|
+
if (round_trip_count === NONE) return NONE;
|
|
2080
|
+
return total / round_trip_count;
|
|
2081
|
+
}
|
|
2082
|
+
function format_density(density) {
|
|
2083
|
+
return density.toFixed(DENSITY_DECIMALS);
|
|
2084
|
+
}
|
|
2085
|
+
function is_below_floor(density) {
|
|
2086
|
+
return density > NONE && density < CALLS_PER_ROUND_TRIP_FLOOR;
|
|
2087
|
+
}
|
|
2088
|
+
var time_round_trips = {
|
|
2089
|
+
CALLS_PER_ROUND_TRIP_FLOOR,
|
|
2090
|
+
count_calls,
|
|
2091
|
+
count_round_trips,
|
|
2092
|
+
// Exported so a turn is defined in the one module that already defines a round trip rather than
|
|
2093
|
+
// as a span filter in the report next door.
|
|
2094
|
+
count_turns,
|
|
2095
|
+
format_density,
|
|
2096
|
+
// Exported so the per-tool counts are read off the very groups this module counts rather than off
|
|
2097
|
+
// a second grouping beside them.
|
|
2098
|
+
group_round_trips,
|
|
2099
|
+
// Exported so the failure aggregation orders a run's spans through
|
|
2100
|
+
// the one function that already knows why they need it — a second `toSorted` beside it would be
|
|
2101
|
+
// the clone `CLAUDE.md` prohibits, and the seam it guards (a delegated unit's spans appended
|
|
2102
|
+
// after the parent's) is not one a second copy would keep remembering.
|
|
2103
|
+
in_time_order,
|
|
2104
|
+
is_below_floor,
|
|
2105
|
+
// Exported so callers price a round trip with the same divisor and guard rather than a private
|
|
2106
|
+
// copy — the clone `CLAUDE.md` prohibits.
|
|
2107
|
+
per_round_trip
|
|
2108
|
+
};
|
|
2109
|
+
|
|
2110
|
+
// scripts/time-runtime/time-agent-bundles.ts
|
|
2111
|
+
var NONE2 = 0;
|
|
2112
|
+
var ONE = 1;
|
|
2113
|
+
var MIN_GROUP = 2;
|
|
2114
|
+
function is_launch2(span) {
|
|
2115
|
+
return span.category === time_spans.TOOL_CATEGORY && !span.is_continuation && time_bundle_call.is_launch_tool(span.label);
|
|
2116
|
+
}
|
|
2117
|
+
function new_walk() {
|
|
2118
|
+
return { closed: [], open: NONE2, wrote_since: false, turn_id: time_spans.NO_MESSAGE_ID };
|
|
2119
|
+
}
|
|
2120
|
+
function close_group(walk) {
|
|
2121
|
+
if (walk.open >= MIN_GROUP) walk.closed.push(walk.open);
|
|
2122
|
+
walk.open = NONE2;
|
|
2123
|
+
}
|
|
2124
|
+
function is_same_turn(walk, span) {
|
|
2125
|
+
return span.message_id !== time_spans.NO_MESSAGE_ID && span.message_id === walk.turn_id;
|
|
2126
|
+
}
|
|
2127
|
+
function open_turn(walk, span) {
|
|
2128
|
+
if (walk.wrote_since || span.has_prior_reference) close_group(walk);
|
|
2129
|
+
walk.open += ONE;
|
|
2130
|
+
walk.turn_id = span.message_id;
|
|
2131
|
+
walk.wrote_since = false;
|
|
2132
|
+
}
|
|
2133
|
+
function step(walk, span) {
|
|
2134
|
+
if (span.is_writing) {
|
|
2135
|
+
walk.wrote_since = true;
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2138
|
+
if (!is_launch2(span) || is_same_turn(walk, span)) return;
|
|
2139
|
+
open_turn(walk, span);
|
|
2140
|
+
}
|
|
2141
|
+
function agent_bundles(spans) {
|
|
2142
|
+
const walk = new_walk();
|
|
2143
|
+
for (const span of time_round_trips.in_time_order(spans)) step(walk, span);
|
|
2144
|
+
close_group(walk);
|
|
2145
|
+
return walk.closed;
|
|
2146
|
+
}
|
|
2147
|
+
var time_agent_bundles = { agent_bundles };
|
|
2148
|
+
|
|
2149
|
+
// scripts/time-runtime/time-bundles.ts
|
|
2150
|
+
var { unmeasured_row: unmeasured_row2 } = time_format;
|
|
2151
|
+
var HEADING = "Bundling:";
|
|
2152
|
+
var SEQUENCE_LABEL = "bundleable sequences";
|
|
2153
|
+
var RECOVERABLE_LABEL = "recoverable round trips";
|
|
2154
|
+
var SAVING_LABEL = "recoverable wait";
|
|
2155
|
+
var BY_TOOL_LABEL = "recoverable by tool";
|
|
2156
|
+
var AGENT_ROW_LABEL = "Agent";
|
|
2157
|
+
var ROW_INDENT = " ";
|
|
2158
|
+
var MIN_SEQUENCE = 2;
|
|
2159
|
+
var ONE_CALL = 1;
|
|
2160
|
+
var NONE3 = 0;
|
|
2161
|
+
var PATH_SEPARATOR3 = "/";
|
|
2162
|
+
var FIRST_CALL = 1;
|
|
2163
|
+
var NO_LABEL = "";
|
|
2164
|
+
var NO_BUNDLES = {
|
|
2165
|
+
sequence_count: 0,
|
|
2166
|
+
longest_sequence: 0,
|
|
2167
|
+
recoverable_round_trips: 0,
|
|
2168
|
+
by_tool: [],
|
|
2169
|
+
unattributed_round_trips: 0,
|
|
2170
|
+
single_call: { independent_round_trips: 0, dependent_round_trips: 0, by_tool: [] },
|
|
2171
|
+
is_measured: false
|
|
2172
|
+
};
|
|
2173
|
+
function contains_segments(whole, part) {
|
|
2174
|
+
if (whole.startsWith(`${part}${PATH_SEPARATOR3}`)) return true;
|
|
2175
|
+
return whole.endsWith(`${PATH_SEPARATOR3}${part}`) || whole.includes(`${PATH_SEPARATOR3}${part}${PATH_SEPARATOR3}`);
|
|
2176
|
+
}
|
|
2177
|
+
function is_related(left, right) {
|
|
2178
|
+
if (left === right) return true;
|
|
2179
|
+
return contains_segments(left, right) || contains_segments(right, left);
|
|
2180
|
+
}
|
|
2181
|
+
function shares_target(left, right) {
|
|
2182
|
+
return left.some((one) => right.some((other) => is_related(one, other)));
|
|
2183
|
+
}
|
|
2184
|
+
function is_dependent(earlier, later) {
|
|
2185
|
+
if (earlier.is_writing && later.is_writing) return false;
|
|
2186
|
+
return shares_target(earlier.targets, later.targets);
|
|
2187
|
+
}
|
|
2188
|
+
function conflicts(span, sequence) {
|
|
2189
|
+
return sequence.some((earlier) => is_dependent(earlier, span));
|
|
2190
|
+
}
|
|
2191
|
+
function is_call2(span) {
|
|
2192
|
+
return span.category === time_spans.TOOL_CATEGORY && !span.is_continuation;
|
|
2193
|
+
}
|
|
2194
|
+
function is_turn_boundary(span) {
|
|
2195
|
+
return span.category === time_spans.MODEL_CATEGORY;
|
|
2196
|
+
}
|
|
2197
|
+
function new_walk2() {
|
|
2198
|
+
return { pending: [], sequence: [], closed: [], dependent: NONE3 };
|
|
2199
|
+
}
|
|
2200
|
+
function flush(walk) {
|
|
2201
|
+
if (walk.sequence.length >= MIN_SEQUENCE) walk.closed.push(walk.sequence);
|
|
2202
|
+
walk.sequence = [];
|
|
2203
|
+
}
|
|
2204
|
+
function extend(walk, span) {
|
|
2205
|
+
if (conflicts(span, walk.sequence)) {
|
|
2206
|
+
walk.dependent += ONE_CALL;
|
|
2207
|
+
flush(walk);
|
|
2208
|
+
}
|
|
2209
|
+
walk.sequence.push(span);
|
|
2210
|
+
}
|
|
2211
|
+
function close_trip(walk) {
|
|
2212
|
+
const [only] = walk.pending;
|
|
2213
|
+
if (walk.pending.length === ONE_CALL && only?.is_bundleable === true) extend(walk, only);
|
|
2214
|
+
else if (walk.pending.length > NONE3) flush(walk);
|
|
2215
|
+
walk.pending = [];
|
|
2216
|
+
}
|
|
2217
|
+
function is_same_turn2(span, pending) {
|
|
2218
|
+
const [first] = pending;
|
|
2219
|
+
if (first === void 0 || span.is_continuation || span.message_id === time_spans.NO_MESSAGE_ID) {
|
|
2220
|
+
return false;
|
|
2221
|
+
}
|
|
2222
|
+
return span.message_id === first.message_id;
|
|
2223
|
+
}
|
|
2224
|
+
function step2(walk, span) {
|
|
2225
|
+
if (is_call2(span)) {
|
|
2226
|
+
walk.pending.push(span);
|
|
2227
|
+
return;
|
|
2228
|
+
}
|
|
2229
|
+
if (is_same_turn2(span, walk.pending)) return;
|
|
2230
|
+
close_trip(walk);
|
|
2231
|
+
if (!is_turn_boundary(span)) flush(walk);
|
|
2232
|
+
}
|
|
2233
|
+
function longest_of(sizes) {
|
|
2234
|
+
return sizes.length === NONE3 ? NONE3 : Math.max(...sizes);
|
|
2235
|
+
}
|
|
2236
|
+
function recoverable_of(sizes) {
|
|
2237
|
+
return sizes.reduce((sum, size) => sum + size - ONE_CALL, NONE3);
|
|
2238
|
+
}
|
|
2239
|
+
function sizes_of(closed) {
|
|
2240
|
+
return closed.map((sequence) => sequence.length);
|
|
2241
|
+
}
|
|
2242
|
+
function tally_for(tallies, label) {
|
|
2243
|
+
const found = tallies.get(label);
|
|
2244
|
+
if (found !== void 0) return found;
|
|
2245
|
+
const created = { sequence_count: NONE3, recoverable_round_trips: NONE3 };
|
|
2246
|
+
tallies.set(label, created);
|
|
2247
|
+
return created;
|
|
2248
|
+
}
|
|
2249
|
+
function count_trip(tallies, counted, label) {
|
|
2250
|
+
const tally = tally_for(tallies, label);
|
|
2251
|
+
tally.recoverable_round_trips += ONE_CALL;
|
|
2252
|
+
if (!counted.has(label)) tally.sequence_count += ONE_CALL;
|
|
2253
|
+
counted.add(label);
|
|
2254
|
+
}
|
|
2255
|
+
function tally_sequence(tallies, sequence) {
|
|
2256
|
+
const counted = /* @__PURE__ */ new Set();
|
|
2257
|
+
for (const span of sequence.slice(FIRST_CALL)) {
|
|
2258
|
+
if (span.label !== NO_LABEL) count_trip(tallies, counted, span.label);
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
function by_weight(left, right) {
|
|
2262
|
+
if (left.recoverable_round_trips !== right.recoverable_round_trips) {
|
|
2263
|
+
return right.recoverable_round_trips - left.recoverable_round_trips;
|
|
2264
|
+
}
|
|
2265
|
+
return left.label.localeCompare(right.label);
|
|
2266
|
+
}
|
|
2267
|
+
function tool_rows(closed) {
|
|
2268
|
+
const tallies = /* @__PURE__ */ new Map();
|
|
2269
|
+
for (const sequence of closed) tally_sequence(tallies, sequence);
|
|
2270
|
+
return [...tallies].map(([label, tally]) => ({ label, ...tally })).toSorted(by_weight);
|
|
2271
|
+
}
|
|
2272
|
+
function attributed_of(rows) {
|
|
2273
|
+
return rows.reduce((sum, row) => sum + row.recoverable_round_trips, NONE3);
|
|
2274
|
+
}
|
|
2275
|
+
function with_agent_row(rows, agent_sizes) {
|
|
2276
|
+
const recoverable_round_trips = recoverable_of(agent_sizes);
|
|
2277
|
+
if (recoverable_round_trips === NONE3) return [...rows];
|
|
2278
|
+
const row = {
|
|
2279
|
+
label: AGENT_ROW_LABEL,
|
|
2280
|
+
sequence_count: agent_sizes.length,
|
|
2281
|
+
recoverable_round_trips
|
|
2282
|
+
};
|
|
2283
|
+
return [...rows, row].toSorted(by_weight);
|
|
2284
|
+
}
|
|
2285
|
+
function single_call_split(walk, sizes) {
|
|
2286
|
+
return {
|
|
2287
|
+
independent_round_trips: recoverable_of(sizes),
|
|
2288
|
+
dependent_round_trips: walk.dependent,
|
|
2289
|
+
by_tool: tool_rows(walk.closed)
|
|
2290
|
+
};
|
|
2291
|
+
}
|
|
2292
|
+
function build_bundles(spans) {
|
|
2293
|
+
const walk = new_walk2();
|
|
2294
|
+
for (const span of time_round_trips.in_time_order(spans)) step2(walk, span);
|
|
2295
|
+
close_trip(walk);
|
|
2296
|
+
flush(walk);
|
|
2297
|
+
const sizes = sizes_of(walk.closed);
|
|
2298
|
+
const agent_sizes = time_agent_bundles.agent_bundles(spans);
|
|
2299
|
+
const single_call = single_call_split(walk, sizes);
|
|
2300
|
+
const by_tool = with_agent_row(single_call.by_tool, agent_sizes);
|
|
2301
|
+
const recoverable_round_trips = single_call.independent_round_trips + recoverable_of(agent_sizes);
|
|
2302
|
+
return {
|
|
2303
|
+
sequence_count: sizes.length + agent_sizes.length,
|
|
2304
|
+
longest_sequence: Math.max(longest_of(sizes), longest_of(agent_sizes)),
|
|
2305
|
+
recoverable_round_trips,
|
|
2306
|
+
by_tool,
|
|
2307
|
+
unattributed_round_trips: recoverable_round_trips - attributed_of(by_tool),
|
|
2308
|
+
single_call,
|
|
2309
|
+
is_measured: time_spans.has_transcript_data(spans.length)
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
function open_sequence(spans) {
|
|
2313
|
+
const walk = new_walk2();
|
|
2314
|
+
for (const span of time_round_trips.in_time_order(spans)) step2(walk, span);
|
|
2315
|
+
return walk.sequence;
|
|
2316
|
+
}
|
|
2317
|
+
function sequence_suffix(totals) {
|
|
2318
|
+
return `longest ${String(totals.longest_sequence)} turn(s)`;
|
|
2319
|
+
}
|
|
2320
|
+
function recoverable_suffix(totals, round_trip_count) {
|
|
2321
|
+
const share = figure_format.format_share(totals.recoverable_round_trips, round_trip_count);
|
|
2322
|
+
return `${share} of ${String(round_trip_count)} round trip(s)`;
|
|
2323
|
+
}
|
|
2324
|
+
function saving_line(totals, model_ms_per_round_trip) {
|
|
2325
|
+
const saved_ms = totals.recoverable_round_trips * model_ms_per_round_trip;
|
|
2326
|
+
const rate = `at ${time_format.format_seconds(model_ms_per_round_trip)} model time per round trip`;
|
|
2327
|
+
return time_format.format_row(SAVING_LABEL, saved_ms, rate);
|
|
2328
|
+
}
|
|
2329
|
+
function by_tool_suffix(totals) {
|
|
2330
|
+
const attributed = totals.recoverable_round_trips - totals.unattributed_round_trips;
|
|
2331
|
+
return `${String(attributed)} of ${String(totals.recoverable_round_trips)} attributed`;
|
|
2332
|
+
}
|
|
2333
|
+
function tool_row(row) {
|
|
2334
|
+
return time_format.format_columns(
|
|
2335
|
+
`${ROW_INDENT}${row.label}`,
|
|
2336
|
+
String(row.recoverable_round_trips),
|
|
2337
|
+
`in ${String(row.sequence_count)} sequence(s)`
|
|
2338
|
+
);
|
|
2339
|
+
}
|
|
2340
|
+
function by_tool_lines(totals) {
|
|
2341
|
+
const heading = time_format.format_columns(
|
|
2342
|
+
BY_TOOL_LABEL,
|
|
2343
|
+
String(totals.by_tool.length),
|
|
2344
|
+
by_tool_suffix(totals)
|
|
2345
|
+
);
|
|
2346
|
+
const rows = totals.by_tool.slice(NONE3, time_format.MAX_ROWS).map((row) => tool_row(row));
|
|
2347
|
+
return [heading, ...rows, ...time_format.overflow_line(totals.by_tool.length)];
|
|
2348
|
+
}
|
|
2349
|
+
function measured_lines(totals, price) {
|
|
2350
|
+
return [
|
|
2351
|
+
time_format.format_columns(
|
|
2352
|
+
SEQUENCE_LABEL,
|
|
2353
|
+
String(totals.sequence_count),
|
|
2354
|
+
sequence_suffix(totals)
|
|
2355
|
+
),
|
|
2356
|
+
time_format.format_columns(
|
|
2357
|
+
RECOVERABLE_LABEL,
|
|
2358
|
+
String(totals.recoverable_round_trips),
|
|
2359
|
+
recoverable_suffix(totals, price.round_trip_count)
|
|
2360
|
+
),
|
|
2361
|
+
saving_line(totals, price.model_ms_per_round_trip),
|
|
2362
|
+
...by_tool_lines(totals)
|
|
2363
|
+
];
|
|
2364
|
+
}
|
|
2365
|
+
var LABELS = [SEQUENCE_LABEL, RECOVERABLE_LABEL, SAVING_LABEL, BY_TOOL_LABEL];
|
|
2366
|
+
function no_divisor_lines() {
|
|
2367
|
+
return LABELS.map((label) => time_format.format_columns(label, "", time_format.NO_CALLS));
|
|
2368
|
+
}
|
|
2369
|
+
function bundle_lines(totals, price) {
|
|
2370
|
+
const heading = ["", HEADING];
|
|
2371
|
+
if (!totals.is_measured) return [...heading, ...LABELS.map((label) => unmeasured_row2(label))];
|
|
2372
|
+
if (price.round_trip_count === NONE3) return [...heading, ...no_divisor_lines()];
|
|
2373
|
+
return [...heading, ...measured_lines(totals, price)];
|
|
2374
|
+
}
|
|
2375
|
+
var time_bundles = {
|
|
2376
|
+
HEADING,
|
|
2377
|
+
BY_TOOL_LABEL,
|
|
2378
|
+
NO_BUNDLES,
|
|
2379
|
+
build_bundles,
|
|
2380
|
+
bundle_lines,
|
|
2381
|
+
by_weight,
|
|
2382
|
+
is_dependent,
|
|
2383
|
+
open_sequence,
|
|
2384
|
+
shares_target
|
|
2385
|
+
};
|
|
2386
|
+
|
|
2387
|
+
// scripts/time-runtime/time-command-key.ts
|
|
2388
|
+
var UNNAMED_KEY = "";
|
|
2389
|
+
function command_key(span) {
|
|
2390
|
+
if (span.label === time_spans.UNKNOWN_TOOL) return UNNAMED_KEY;
|
|
2391
|
+
return span.josh_command === "" ? span.label : span.josh_command;
|
|
2392
|
+
}
|
|
2393
|
+
var time_command_key = { UNNAMED_KEY, command_key };
|
|
2394
|
+
|
|
2395
|
+
// scripts/time-runtime/time-call-identity.ts
|
|
2396
|
+
var IDENTITY_SEPARATOR = "\0";
|
|
2397
|
+
function identity_of(call) {
|
|
2398
|
+
return [
|
|
2399
|
+
time_command_key.command_key(call),
|
|
2400
|
+
call.check_key,
|
|
2401
|
+
[...call.targets].toSorted((left, right) => left.localeCompare(right)).join(",")
|
|
2402
|
+
].join(IDENTITY_SEPARATOR);
|
|
2403
|
+
}
|
|
2404
|
+
var time_call_identity = { identity_of };
|
|
2405
|
+
|
|
2406
|
+
// scripts/time-runtime/time-search-call.ts
|
|
2407
|
+
var SEARCH_COMMANDS = ["fd", "find", "grep", "rg"];
|
|
2408
|
+
var SEARCH_LABELS = new Set(
|
|
2409
|
+
SEARCH_COMMANDS.map((command) => time_shell.bash_label(command))
|
|
2410
|
+
);
|
|
2411
|
+
var CHAIN_COMMANDS = [...SEARCH_COMMANDS, "sed"];
|
|
2412
|
+
var CHAIN_LABELS = new Set(
|
|
2413
|
+
CHAIN_COMMANDS.map((command) => time_shell.bash_label(command))
|
|
2414
|
+
);
|
|
2415
|
+
function is_read_only_search(call) {
|
|
2416
|
+
return SEARCH_LABELS.has(call.label) && call.is_bundleable && !call.may_write;
|
|
2417
|
+
}
|
|
2418
|
+
function is_search_chain_call(call) {
|
|
2419
|
+
return CHAIN_LABELS.has(call.label) && call.is_bundleable && !call.is_writing;
|
|
2420
|
+
}
|
|
2421
|
+
var time_search_call = {
|
|
2422
|
+
is_read_only_search,
|
|
2423
|
+
is_search_chain_call
|
|
2424
|
+
};
|
|
2425
|
+
|
|
2426
|
+
// scripts/time-runtime/time-batch-guard.ts
|
|
2427
|
+
var CONSECUTIVE_LIMIT = 3;
|
|
2428
|
+
var REFIRE_EVERY = CONSECUTIVE_LIMIT;
|
|
2429
|
+
var ONE_TURN = 1;
|
|
2430
|
+
var NONE4 = 0;
|
|
2431
|
+
var NOTICE_REFIRE_EVERY = ONE_TURN;
|
|
2432
|
+
var NAMED_CANDIDATE_COUNT = 3;
|
|
2433
|
+
var SEQUENCE_BEFORE_LIMIT = CONSECUTIVE_LIMIT - ONE_TURN;
|
|
2434
|
+
var RULE_POINTER = "`prompts/collaboration-workflow/turn-batching.md`";
|
|
2435
|
+
var STREAK = `${String(CONSECUTIVE_LIMIT)} single-call turns in a row`;
|
|
2436
|
+
var REASON = `\u26D4 batching: ${STREAK}. Reissue this with the calls that do not need its result \u2014 the test is whether a call's input needs another call's result, not what kind of call it is (edits are covered exactly as reads); it never authorizes weakening a verification gate or a review. Nothing to pair? Reissue it unchanged. ${RULE_POINTER}`;
|
|
2437
|
+
var NOTICE = `\u{1F4A1} batching: ${STREAK}; the Write proceeds. Issue the writes that do not need its result in one turn, never by weakening a gate or a review. ${RULE_POINTER}`;
|
|
2438
|
+
var LANE_NOTICE = `\u{1F4A1} batching: ${STREAK}; the call proceeds. Pair independent calls. ${RULE_POINTER}`;
|
|
2439
|
+
var WHOLE_FILE_WRITE_TOOL = "Write";
|
|
2440
|
+
var EDIT_TOOL = "Edit";
|
|
2441
|
+
function is_guarded_call(call) {
|
|
2442
|
+
if (call.name === WHOLE_FILE_WRITE_TOOL) return false;
|
|
2443
|
+
return time_bundle_call.call_facts(call.name, call.input).is_bundleable;
|
|
2444
|
+
}
|
|
2445
|
+
function is_notice_call(call) {
|
|
2446
|
+
return call.name === WHOLE_FILE_WRITE_TOOL;
|
|
2447
|
+
}
|
|
2448
|
+
function is_read_only_call(call) {
|
|
2449
|
+
const facts = time_bundle_call.call_facts(call.name, call.input);
|
|
2450
|
+
return facts.is_bundleable && !facts.may_write;
|
|
2451
|
+
}
|
|
2452
|
+
function depends_on_sequence(sequence, facts) {
|
|
2453
|
+
return sequence.some((span) => time_bundles.shares_target(span.targets, facts.targets));
|
|
2454
|
+
}
|
|
2455
|
+
function sequence_started_ms(sequence) {
|
|
2456
|
+
return sequence[0]?.ended_ms ?? NONE4;
|
|
2457
|
+
}
|
|
2458
|
+
function turns_since(sequence, last_fired_ms) {
|
|
2459
|
+
return sequence.filter((span) => span.ended_ms > last_fired_ms).length;
|
|
2460
|
+
}
|
|
2461
|
+
function is_sequence_at_limit(sequence, facts, last_fired_ms, refire_every) {
|
|
2462
|
+
if (sequence.length < SEQUENCE_BEFORE_LIMIT || depends_on_sequence(sequence, facts)) return false;
|
|
2463
|
+
if (last_fired_ms < sequence_started_ms(sequence)) return true;
|
|
2464
|
+
return turns_since(sequence, last_fired_ms) >= refire_every;
|
|
2465
|
+
}
|
|
2466
|
+
function is_at_limit(spans, call, last_fired_ms, refire_every) {
|
|
2467
|
+
return is_sequence_at_limit(
|
|
2468
|
+
time_bundles.open_sequence(spans),
|
|
2469
|
+
time_bundle_call.call_facts(call.name, call.input),
|
|
2470
|
+
last_fired_ms,
|
|
2471
|
+
refire_every
|
|
2472
|
+
);
|
|
2473
|
+
}
|
|
2474
|
+
var GUARD_LABEL = time_transcript_line.guard_from_refusal(REASON);
|
|
2475
|
+
function is_reissued_refusal(spans, call) {
|
|
2476
|
+
const identity = time_call_identity.identity_of(
|
|
2477
|
+
time_spans.to_tool_call(call.name, call.input, time_spans.NO_MESSAGE_ID)
|
|
2478
|
+
);
|
|
2479
|
+
return spans.some(
|
|
2480
|
+
(span) => span.refusal_guard === GUARD_LABEL && time_call_identity.identity_of(span) === identity
|
|
2481
|
+
);
|
|
2482
|
+
}
|
|
2483
|
+
function refusable_spans(text, call) {
|
|
2484
|
+
if (!is_guarded_call(call)) return [];
|
|
2485
|
+
const { spans } = time_spans.parse_timeline(text);
|
|
2486
|
+
return is_reissued_refusal(spans, call) ? [] : spans;
|
|
2487
|
+
}
|
|
2488
|
+
function should_block(text, call, refused_at_ms, refire_every = REFIRE_EVERY) {
|
|
2489
|
+
return is_at_limit(refusable_spans(text, call), call, refused_at_ms, refire_every);
|
|
2490
|
+
}
|
|
2491
|
+
function as_tool_call(call) {
|
|
2492
|
+
return time_spans.to_tool_call(call.name, call.input, time_spans.NO_MESSAGE_ID);
|
|
2493
|
+
}
|
|
2494
|
+
function is_search_chain_call2(call) {
|
|
2495
|
+
return is_guarded_call(call) && time_search_call.is_search_chain_call(as_tool_call(call));
|
|
2496
|
+
}
|
|
2497
|
+
function is_search_chain(spans, call) {
|
|
2498
|
+
const recent = time_bundles.open_sequence(spans).slice(-SEQUENCE_BEFORE_LIMIT);
|
|
2499
|
+
return [...recent, as_tool_call(call)].every(
|
|
2500
|
+
(turn) => time_search_call.is_search_chain_call(turn)
|
|
2501
|
+
);
|
|
2502
|
+
}
|
|
2503
|
+
function should_block_search_chain(text, call, refused_at_ms) {
|
|
2504
|
+
const spans = refusable_spans(text, call);
|
|
2505
|
+
return is_search_chain(spans, call) && is_at_limit(spans, call, refused_at_ms, REFIRE_EVERY);
|
|
2506
|
+
}
|
|
2507
|
+
function should_notify(text, call, notified_at_ms) {
|
|
2508
|
+
if (!is_notice_call(call)) return false;
|
|
2509
|
+
const { spans } = time_spans.parse_timeline(text);
|
|
2510
|
+
return is_at_limit(spans, call, notified_at_ms, NOTICE_REFIRE_EVERY);
|
|
2511
|
+
}
|
|
2512
|
+
function describe_span(span) {
|
|
2513
|
+
const target = span.targets[0] ?? "";
|
|
2514
|
+
if (target === "" || span.label.includes(target)) return span.label;
|
|
2515
|
+
return `${span.label} ${target}`;
|
|
2516
|
+
}
|
|
2517
|
+
var FOLD_MINIMUM = 2;
|
|
2518
|
+
function read_targets(sequence) {
|
|
2519
|
+
const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((path3) => path3 !== "" && time_bundle_call.has_extension(path3));
|
|
2520
|
+
return [...new Set(paths)];
|
|
2521
|
+
}
|
|
2522
|
+
function read_fold_directive(sequence) {
|
|
2523
|
+
const paths = read_targets(sequence);
|
|
2524
|
+
if (paths.length < FOLD_MINIMUM) return "";
|
|
2525
|
+
return ` Fold them into one call: \`pnpm josh read:files ${paths.join(" ")}\`.`;
|
|
2526
|
+
}
|
|
2527
|
+
function write_targets(sequence) {
|
|
2528
|
+
const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((path3) => path3 !== "" && time_bundle_call.has_extension(path3));
|
|
2529
|
+
return [...new Set(paths)];
|
|
2530
|
+
}
|
|
2531
|
+
function write_fold_directive(sequence) {
|
|
2532
|
+
const paths = write_targets(sequence);
|
|
2533
|
+
if (paths.length < FOLD_MINIMUM) return "";
|
|
2534
|
+
return ` Fold them into one \`pnpm josh edit:files\` call with a plan over: ${paths.join(" ")}.`;
|
|
2535
|
+
}
|
|
2536
|
+
function name_candidates(calls) {
|
|
2537
|
+
if (calls.length === NONE4) return "";
|
|
2538
|
+
const named = calls.map((call) => describe_span(call)).join(", ");
|
|
2539
|
+
const folds = `${read_fold_directive(calls)}${write_fold_directive(calls)}`;
|
|
2540
|
+
return ` Just issued one per turn, so at least these could have shared a turn: ${named}.${folds}`;
|
|
2541
|
+
}
|
|
2542
|
+
function recent_candidates(tail) {
|
|
2543
|
+
return name_candidates(
|
|
2544
|
+
time_bundles.open_sequence(time_spans.parse_timeline(tail).spans).slice(-NAMED_CANDIDATE_COUNT)
|
|
2545
|
+
);
|
|
2546
|
+
}
|
|
2547
|
+
function pairing_candidates(tail, call) {
|
|
2548
|
+
const sequence = time_bundles.open_sequence(time_spans.parse_timeline(tail).spans);
|
|
2549
|
+
if (call === void 0 || sequence.length === NONE4) {
|
|
2550
|
+
return name_candidates(sequence.slice(-NAMED_CANDIDATE_COUNT));
|
|
2551
|
+
}
|
|
2552
|
+
const facts = time_bundle_call.call_facts(call.name, call.input);
|
|
2553
|
+
if (!facts.is_bundleable || depends_on_sequence(sequence, facts)) return "";
|
|
2554
|
+
const current = time_spans.to_tool_call(call.name, call.input, time_spans.NO_MESSAGE_ID);
|
|
2555
|
+
return name_candidates([...sequence.slice(ONE_TURN - NAMED_CANDIDATE_COUNT), current]);
|
|
2556
|
+
}
|
|
2557
|
+
var STAMP_PREFIX = "josh-batch-guard-";
|
|
2558
|
+
var NOTICE_STAMP_PREFIX = "josh-batch-guard-notice-";
|
|
2559
|
+
var time_batch_guard = {
|
|
2560
|
+
CONSECUTIVE_LIMIT,
|
|
2561
|
+
GUARD_LABEL,
|
|
2562
|
+
LANE_NOTICE,
|
|
2563
|
+
NOTICE,
|
|
2564
|
+
NOTICE_REFIRE_EVERY,
|
|
2565
|
+
NOTICE_STAMP_PREFIX,
|
|
2566
|
+
REASON,
|
|
2567
|
+
REFIRE_EVERY,
|
|
2568
|
+
SEQUENCE_BEFORE_LIMIT,
|
|
2569
|
+
STAMP_PREFIX,
|
|
2570
|
+
is_guarded_call,
|
|
2571
|
+
is_notice_call,
|
|
2572
|
+
is_read_only_call,
|
|
2573
|
+
is_search_chain_call: is_search_chain_call2,
|
|
2574
|
+
pairing_candidates,
|
|
2575
|
+
recent_candidates,
|
|
2576
|
+
should_block,
|
|
2577
|
+
should_block_search_chain,
|
|
2578
|
+
should_notify
|
|
2579
|
+
};
|
|
2580
|
+
|
|
2581
|
+
// scripts/time-runtime/time-density.ts
|
|
2582
|
+
var MIN_ROUND_TRIPS = 10;
|
|
2583
|
+
var NOTICE_INTERVAL_MS = 3e5;
|
|
2584
|
+
var ONE_CALL2 = 1;
|
|
2585
|
+
var NONE5 = 0;
|
|
2586
|
+
function has_whole_tail(text) {
|
|
2587
|
+
const last = text.split("\n").findLast((line) => line.trim() !== "");
|
|
2588
|
+
return last !== void 0 && time_spans.parse_line(last) !== void 0;
|
|
2589
|
+
}
|
|
2590
|
+
function assistant_lines(text) {
|
|
2591
|
+
return text.split("\n").map((line) => time_spans.parse_line(line)).filter((line) => line?.type === time_spans.ASSISTANT_TYPE);
|
|
2592
|
+
}
|
|
2593
|
+
function last_turn_calls(text) {
|
|
2594
|
+
if (!has_whole_tail(text)) return NONE5;
|
|
2595
|
+
const lines = assistant_lines(text);
|
|
2596
|
+
const message_id = lines.at(-1)?.message_id;
|
|
2597
|
+
if (message_id === void 0 || message_id === time_spans.NO_MESSAGE_ID) return NONE5;
|
|
2598
|
+
return lines.filter((line) => line.message_id === message_id).flatMap((line) => line.blocks).filter((block) => block.type === cost_blocks.TOOL_USE_TYPE).length;
|
|
2599
|
+
}
|
|
2600
|
+
function read_window(text) {
|
|
2601
|
+
const { spans } = time_spans.parse_timeline(text);
|
|
2602
|
+
const round_trip_count = time_round_trips.count_round_trips(spans);
|
|
2603
|
+
const call_count = time_round_trips.count_calls(spans);
|
|
2604
|
+
return {
|
|
2605
|
+
density: time_round_trips.per_round_trip(call_count, round_trip_count),
|
|
2606
|
+
round_trip_count,
|
|
2607
|
+
turn_calls: last_turn_calls(text)
|
|
2608
|
+
};
|
|
2609
|
+
}
|
|
2610
|
+
function is_due(reading, since_last_ms) {
|
|
2611
|
+
if (reading.round_trip_count < MIN_ROUND_TRIPS || reading.turn_calls !== ONE_CALL2 || !time_round_trips.is_below_floor(reading.density)) {
|
|
2612
|
+
return false;
|
|
2613
|
+
}
|
|
2614
|
+
return since_last_ms >= NOTICE_INTERVAL_MS;
|
|
2615
|
+
}
|
|
2616
|
+
function format_notice(reading, candidates = "") {
|
|
2617
|
+
const density = time_round_trips.format_density(reading.density);
|
|
2618
|
+
const floor = time_round_trips.format_density(time_round_trips.CALLS_PER_ROUND_TRIP_FLOOR);
|
|
2619
|
+
return `\u26A0 batching: ${density} calls per round trip over the last ${String(reading.round_trip_count)}, under the ${floor} floor, and this turn issued one call. Independent reads, greps, gh queries and edits go out together; the criterion is whether this call's input needs another call's result, not what kind of call it is \u2014 prompts/collaboration-workflow/turn-batching.md.${candidates}`;
|
|
2620
|
+
}
|
|
2621
|
+
var time_density = {
|
|
2622
|
+
MIN_ROUND_TRIPS,
|
|
2623
|
+
NOTICE_INTERVAL_MS,
|
|
2624
|
+
format_notice,
|
|
2625
|
+
is_due,
|
|
2626
|
+
last_turn_calls,
|
|
2627
|
+
read_window
|
|
2628
|
+
};
|
|
2629
|
+
|
|
2630
|
+
// scripts/time-runtime/time-density-hook.ts
|
|
2631
|
+
var TAIL_BYTES = 262144;
|
|
2632
|
+
var FILE_START = 0;
|
|
2633
|
+
var NOTICE_PREFIX = "josh-density-notice-";
|
|
2634
|
+
var NEVER_MS = 0;
|
|
2635
|
+
var payload_schema = z4.object({
|
|
2636
|
+
transcript_path: z4.string().min(1).optional(),
|
|
2637
|
+
// **`nullish`, not `optional`.** A payload spelling the absent agent as `null` has to read as "no
|
|
2638
|
+
// fork"; rejected, it would fail `safeParse` for the whole payload and silence the line for every
|
|
2639
|
+
// edit of the main line — the opposite of this module's stated failure direction.
|
|
2640
|
+
agent_id: z4.string().nullish()
|
|
2641
|
+
});
|
|
2642
|
+
var notice_schema = z4.object({ notified_at_ms: z4.number() });
|
|
2643
|
+
var call_schema = z4.object({ tool_name: z4.string().min(1), tool_input: z4.unknown() });
|
|
2644
|
+
function parse_transcript_path(raw_payload) {
|
|
2645
|
+
const payload = json_value.parse_with(raw_payload, payload_schema);
|
|
2646
|
+
if (payload?.transcript_path === void 0) return void 0;
|
|
2647
|
+
return time_hook_transcript.transcript_of(payload.transcript_path, payload.agent_id);
|
|
2648
|
+
}
|
|
2649
|
+
function parse_call(raw_payload) {
|
|
2650
|
+
const call = json_value.parse_with(raw_payload, call_schema);
|
|
2651
|
+
if (call === void 0) return void 0;
|
|
2652
|
+
return { name: call.tool_name, input: call.tool_input };
|
|
2653
|
+
}
|
|
2654
|
+
function read_tail(file_path, max_bytes = TAIL_BYTES) {
|
|
2655
|
+
const descriptor = openSync(file_path, "r");
|
|
2656
|
+
try {
|
|
2657
|
+
const { size } = fstatSync(descriptor);
|
|
2658
|
+
const length = Math.min(size, max_bytes);
|
|
2659
|
+
const buffer = Buffer.alloc(length);
|
|
2660
|
+
const read2 = readSync(descriptor, buffer, FILE_START, length, size - length);
|
|
2661
|
+
return buffer.subarray(FILE_START, read2).toString("utf8");
|
|
2662
|
+
} finally {
|
|
2663
|
+
closeSync(descriptor);
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
function notice_path(transcript_path) {
|
|
2667
|
+
return stamp_file.stamp_path(NOTICE_PREFIX, transcript_path);
|
|
2668
|
+
}
|
|
2669
|
+
function last_notice_ms(source) {
|
|
2670
|
+
const raw = stamp_file.read_stamp_text(source);
|
|
2671
|
+
if (raw === void 0) return NEVER_MS;
|
|
2672
|
+
return json_value.parse_with(raw, notice_schema)?.notified_at_ms ?? NEVER_MS;
|
|
2673
|
+
}
|
|
2674
|
+
function arm_throttle(target, now_ms) {
|
|
2675
|
+
try {
|
|
2676
|
+
stamp_file.write_stamp(target, { notified_at_ms: now_ms });
|
|
2677
|
+
} catch {
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
function notice_for(raw_payload, now_ms) {
|
|
2681
|
+
const transcript_path = parse_transcript_path(raw_payload);
|
|
2682
|
+
if (transcript_path === void 0) return void 0;
|
|
2683
|
+
const tail = read_tail(transcript_path);
|
|
2684
|
+
const reading = time_density.read_window(tail);
|
|
2685
|
+
const target = notice_path(transcript_path);
|
|
2686
|
+
if (!time_density.is_due(reading, now_ms - last_notice_ms(target))) return void 0;
|
|
2687
|
+
const candidates = time_batch_guard.pairing_candidates(tail, parse_call(raw_payload));
|
|
2688
|
+
if (candidates === "") return void 0;
|
|
2689
|
+
arm_throttle(target, now_ms);
|
|
2690
|
+
return time_density.format_notice(reading, candidates);
|
|
2691
|
+
}
|
|
2692
|
+
function density_notice(raw_payload, now_ms = Date.now()) {
|
|
2693
|
+
try {
|
|
2694
|
+
return notice_for(raw_payload, now_ms);
|
|
2695
|
+
} catch {
|
|
2696
|
+
return void 0;
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
var time_density_hook = {
|
|
2700
|
+
density_notice,
|
|
2701
|
+
notice_path,
|
|
2702
|
+
parse_call,
|
|
2703
|
+
parse_transcript_path,
|
|
2704
|
+
read_tail
|
|
2705
|
+
};
|
|
2706
|
+
|
|
2707
|
+
// scripts/build/local-bin.ts
|
|
2708
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2709
|
+
import { createRequire } from "node:module";
|
|
2710
|
+
import path2 from "node:path";
|
|
2711
|
+
|
|
2712
|
+
// scripts/lib/schemas.ts
|
|
2713
|
+
import { z as z5 } from "zod";
|
|
2714
|
+
var overrides_snapshot_schema = z5.record(z5.string(), z5.string());
|
|
2715
|
+
var package_version_schema = z5.object({ version: z5.string() });
|
|
2716
|
+
var package_named_version_schema = z5.looseObject({ name: z5.string(), version: z5.string() });
|
|
2717
|
+
var package_with_version_schema = z5.looseObject({ version: z5.string() });
|
|
2718
|
+
var ls_global_dependency_schema = z5.looseObject({ version: z5.string() });
|
|
2719
|
+
var ls_global_dependencies_schema = z5.record(z5.string(), ls_global_dependency_schema).optional();
|
|
2720
|
+
var pnpm_ls_global_schema = z5.array(
|
|
2721
|
+
z5.looseObject({
|
|
2722
|
+
dependencies: ls_global_dependencies_schema
|
|
2723
|
+
})
|
|
2724
|
+
);
|
|
2725
|
+
var vscode_settings_schema = z5.record(z5.string(), z5.unknown());
|
|
2726
|
+
var with_scripts_schema = z5.looseObject({
|
|
2727
|
+
scripts: z5.record(z5.string(), z5.string()).optional()
|
|
2728
|
+
});
|
|
2729
|
+
var with_development_deps_schema = z5.looseObject({
|
|
2730
|
+
devDependencies: z5.record(z5.string(), z5.string()).optional()
|
|
2731
|
+
});
|
|
2732
|
+
var with_package_manager_schema = z5.looseObject({
|
|
2733
|
+
packageManager: z5.string().optional()
|
|
2734
|
+
});
|
|
2735
|
+
var with_development_engine_schema = z5.looseObject({
|
|
2736
|
+
devEngines: z5.record(z5.string(), z5.unknown()).optional()
|
|
2737
|
+
});
|
|
2738
|
+
var bin_entry_schema = z5.union([z5.string(), z5.record(z5.string(), z5.string())]).optional();
|
|
2739
|
+
var package_bin_schema = z5.looseObject({ bin: bin_entry_schema });
|
|
2740
|
+
var json_object_schema = z5.record(z5.string(), z5.unknown());
|
|
2741
|
+
var string_array_schema = z5.array(z5.string());
|
|
2742
|
+
var string_record_schema = z5.record(z5.string(), z5.string());
|
|
2743
|
+
|
|
2744
|
+
// scripts/build/local-bin.ts
|
|
2745
|
+
var NODE_MODULES = "node_modules";
|
|
2746
|
+
var BIN_DIR = ".bin";
|
|
2747
|
+
var WINDOWS_PLATFORM = "win32";
|
|
2748
|
+
var WINDOWS_SHIM_SUFFIX = ".cmd";
|
|
2749
|
+
function resolve_local_bin(project_root, bin_name) {
|
|
2750
|
+
const shim = process.platform === WINDOWS_PLATFORM ? `${bin_name}${WINDOWS_SHIM_SUFFIX}` : bin_name;
|
|
2751
|
+
return path2.join(project_root, NODE_MODULES, BIN_DIR, shim);
|
|
2752
|
+
}
|
|
2753
|
+
function find_local_bin_upwards(start_directory, bin_name) {
|
|
2754
|
+
return ancestor_directories.list(start_directory).map((directory) => resolve_local_bin(directory, bin_name)).find((candidate) => existsSync(candidate));
|
|
2755
|
+
}
|
|
2756
|
+
function read_bin_entry(manifest_path, package_name, bin_name) {
|
|
2757
|
+
const { bin } = package_bin_schema.parse(JSON.parse(readFileSync(manifest_path, "utf8")));
|
|
2758
|
+
if (typeof bin === "string") return bin_name === path2.basename(package_name) ? bin : void 0;
|
|
2759
|
+
return bin?.[bin_name];
|
|
2760
|
+
}
|
|
2761
|
+
function resolve_package_bin(base_directory, package_name, bin_name) {
|
|
2762
|
+
try {
|
|
2763
|
+
const resolve_from = createRequire(path2.join(base_directory, PACKAGE_JSON));
|
|
2764
|
+
const manifest_path = resolve_from.resolve(`${package_name}/${PACKAGE_JSON}`);
|
|
2765
|
+
const bin_entry = read_bin_entry(manifest_path, package_name, bin_name);
|
|
2766
|
+
if (bin_entry === void 0) return void 0;
|
|
2767
|
+
const cli_entry = path2.join(path2.dirname(manifest_path), bin_entry);
|
|
2768
|
+
return existsSync(cli_entry) ? cli_entry : void 0;
|
|
2769
|
+
} catch {
|
|
2770
|
+
return void 0;
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
export {
|
|
2775
|
+
transcript_record,
|
|
2776
|
+
cost_blocks,
|
|
2777
|
+
time_shell,
|
|
2778
|
+
time_bundle_call,
|
|
2779
|
+
CHECK_STATUS_PENDING,
|
|
2780
|
+
CHECK_STATUS_FAIL,
|
|
2781
|
+
read_string,
|
|
2782
|
+
parse_pr_state_snapshot,
|
|
2783
|
+
is_merge_conflict,
|
|
2784
|
+
is_coderabbit_check,
|
|
2785
|
+
is_required_check,
|
|
2786
|
+
describe_pr_failure,
|
|
2787
|
+
evaluate_pr_state,
|
|
2788
|
+
is_review_decision_decisive,
|
|
2789
|
+
PrConflictError,
|
|
2790
|
+
time_reported_failure,
|
|
2791
|
+
cost_attribute,
|
|
2792
|
+
time_markers,
|
|
2793
|
+
time_transcript_line,
|
|
2794
|
+
time_spans,
|
|
2795
|
+
time_search_call,
|
|
2796
|
+
time_batch_guard,
|
|
2797
|
+
time_hook_transcript,
|
|
2798
|
+
time_density_hook,
|
|
2799
|
+
vscode_settings_schema,
|
|
2800
|
+
json_object_schema,
|
|
2801
|
+
string_array_schema,
|
|
2802
|
+
string_record_schema,
|
|
2803
|
+
resolve_local_bin,
|
|
2804
|
+
find_local_bin_upwards,
|
|
2805
|
+
resolve_package_bin
|
|
2806
|
+
};
|