@joshuafolkken/kit 1.1240.0 → 1.1370.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -0
- package/.claude/settings.json +4 -0
- package/.claude/skills/dependency-update/SKILL.md +5 -3
- package/.claude/skills/epic-commands/SKILL.md +82 -113
- package/.claude/skills/epic-commands/epic-bundle.md +38 -63
- package/.claude/skills/epic-commands/execution-waves.md +30 -51
- package/.claude/skills/verify-ui/SKILL.md +13 -20
- package/.claude/skills/workflow-commands/SKILL.md +10 -10
- package/.claude/skills/workflow-commands/background-commands.md +4 -4
- package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
- package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
- package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
- package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
- package/.claude/skills/workflow-commands/backlogrun.md +50 -61
- package/.claude/skills/workflow-commands/chain-rule.md +36 -40
- package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
- package/.claude/skills/workflow-commands/followup.md +19 -20
- package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
- package/.claude/skills/workflow-commands/fullrun.md +10 -10
- package/.claude/skills/workflow-commands/halfrun.md +9 -8
- package/.claude/skills/workflow-commands/into-target.md +12 -18
- package/.claude/skills/workflow-commands/issue-comments.md +11 -26
- package/.claude/skills/workflow-commands/kickoff.md +26 -16
- package/.claude/skills/workflow-commands/latest-gate.md +17 -28
- package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
- package/.claude/skills/workflow-commands/observation-filing.md +37 -28
- package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
- package/.claude/skills/workflow-commands/prerequisite.md +23 -15
- package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
- package/.claude/skills/workflow-commands/prrun.md +3 -3
- package/.claude/skills/workflow-commands/retrospective.md +13 -18
- package/.claude/skills/workflow-commands/split-assessment.md +6 -4
- package/.claude/skills/workflow-commands/target-repository.md +25 -28
- package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
- package/.gitattributes +2 -1
- package/.github/workflows/ci.yml +14 -0
- package/.vscode/tasks.json +14 -0
- package/CLAUDE.md +10 -61
- package/README.md +29 -47
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +10 -61
- package/dist/commands/document-section-cli.js +42 -10
- package/dist/config-merge/index.js +11 -2
- package/dist/hooks/audit-provision.js +2 -2
- package/dist/hooks/batch-guard.js +7 -7
- package/dist/hooks/{chunk-KHGB5S3Y.js → chunk-43G45XJF.js} +18 -20
- package/dist/hooks/{chunk-4TZVB44A.js → chunk-4TW4MQUL.js} +284 -362
- package/dist/hooks/{chunk-XZYKEM6J.js → chunk-76RK6E3H.js} +13 -11
- package/dist/hooks/{chunk-F3ELQ2AF.js → chunk-DZWZ3DKY.js} +4 -4
- package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
- package/dist/hooks/{chunk-GPTFMK5E.js → chunk-GG72ANKI.js} +1 -1
- package/dist/hooks/{chunk-ZQGD4GBY.js → chunk-KPM4YIIX.js} +8 -44
- package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
- package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
- package/dist/hooks/{chunk-QVSWU24O.js → chunk-NZBHG6FW.js} +7 -5
- package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
- package/dist/hooks/{chunk-KRBERBBI.js → chunk-R6CRQEAL.js} +4 -4
- package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
- package/dist/hooks/{chunk-WK2XSHSI.js → chunk-TLJYAGZK.js} +549 -874
- package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
- package/dist/hooks/codex-hook-adapter.js +26 -21
- package/dist/hooks/duplicate-read-guard.js +8 -8
- package/dist/hooks/format-edited.js +4 -4
- package/dist/hooks/inputs.json +216 -202
- package/dist/hooks/investigation-guard.js +8 -8
- package/dist/hooks/pretool-guard.js +15 -15
- package/dist/hooks/session-lang.js +406 -8
- package/dist/hooks/stop-guard.js +122 -187
- package/dist/josh.js +281 -94
- package/dist/version/index.js +15 -13
- package/eslint/base.js +43 -5
- package/eslint/rules/english-only-prose.js +3 -3
- package/eslint/rules/import.js +12 -0
- package/eslint/rules/namespace-object-export.js +2 -2
- package/package.json +16 -10
- package/pnpm-workspace.yaml +2 -4
- package/prompts/coding-standards.md +14 -48
- package/prompts/collaboration-workflow/file-edits.md +1 -1
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +3 -10
- package/prompts/collaboration-workflow/operating-rules.md +7 -8
- package/prompts/collaboration-workflow/output-bounds.md +1 -1
- package/prompts/collaboration-workflow/overview.md +1 -1
- package/prompts/collaboration-workflow/plan-comment.md +2 -1
- package/prompts/collaboration-workflow/principles.md +21 -3
- package/prompts/collaboration-workflow/report-format.md +16 -29
- package/prompts/collaboration-workflow/residency.md +1 -1
- package/prompts/collaboration-workflow/rule-delivery.md +7 -95
- package/prompts/collaboration-workflow/shell-body.md +3 -23
- package/prompts/collaboration-workflow/turn-batching.md +4 -13
- package/prompts/collaboration-workflow/wip-cap.md +5 -11
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +3 -22
- package/prompts/review.md +15 -38
- package/prompts/testing-guide.md +2 -4
- package/scripts/adopt/adopt-logic.ts +5 -5
- package/scripts/adopt/adopt-toolkits.ts +4 -5
- package/scripts/adopt/adopt.ts +2 -3
- package/scripts/agent/agent-argv.ts +7 -7
- package/scripts/agent/agent-diagnostics.ts +2 -2
- package/scripts/agent/agent-exit-record.ts +1 -1
- package/scripts/agent/agent-headless.ts +1 -1
- package/scripts/agent/agent-launch-environment.ts +6 -1
- package/scripts/agent/agent-role-profile.ts +49 -22
- package/scripts/agent/agent-session-role.ts +32 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/claude-agent-argv.ts +4 -4
- package/scripts/agent/claude-result-event.ts +4 -4
- package/scripts/agent/codex-hooks.ts +2 -2
- package/scripts/agent/interactive-ask.ts +3 -6
- package/scripts/auto-ok/auto-ok-cli.ts +46 -60
- package/scripts/backlog/backlog-arrival-added.ts +34 -0
- package/scripts/backlog/backlog-arrival.ts +54 -17
- package/scripts/backlog/backlog-budget-cli.ts +34 -6
- package/scripts/backlog/backlog-budget.ts +17 -24
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-args.ts +5 -4
- package/scripts/backlog/backlog-drive-cli.ts +14 -10
- package/scripts/backlog/backlog-drive-epic.ts +85 -0
- package/scripts/backlog/backlog-drive-launch.ts +1 -1
- package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
- package/scripts/backlog/backlog-drive-named.ts +39 -9
- package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
- package/scripts/backlog/backlog-drive-restore.ts +1 -1
- package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
- package/scripts/backlog/backlog-drive.ts +43 -28
- package/scripts/backlog/backlog-idle.ts +88 -0
- package/scripts/backlog/backlog-named.ts +11 -15
- package/scripts/backlog/backlog-next.ts +26 -30
- package/scripts/backlog/backlog-offer-cli.ts +28 -23
- package/scripts/backlog/backlog-offer.ts +7 -7
- package/scripts/backlog/backlog-overlap.ts +178 -0
- package/scripts/backlog/backlog-plan-cli.ts +14 -90
- package/scripts/backlog/backlog-plan-read.ts +111 -0
- package/scripts/backlog/backlog-plan.ts +11 -10
- package/scripts/backlog/backlog-pool.ts +13 -14
- package/scripts/backlog/backlog-rank.ts +11 -11
- package/scripts/backlog/backlog-ready.ts +15 -10
- package/scripts/backlog/backlog-scope.ts +14 -15
- package/scripts/backlog/backlog-stalled-cli.ts +2 -2
- package/scripts/backlog/backlog-stalled-detect.ts +4 -4
- package/scripts/backlog/backlog-stalled.ts +5 -6
- package/scripts/backlog/backlog-waves.ts +4 -4
- package/scripts/backlog/backlogrun-args.ts +74 -0
- package/scripts/backlog/backlogrun-cli.ts +113 -0
- package/scripts/backlog/backlogrun-launch.ts +178 -0
- package/scripts/behavior/behavior-assertion.ts +6 -8
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/behavior/behavior-rules.ts +3 -3
- package/scripts/build/build-claude-md.ts +4 -4
- package/scripts/build/build-codex-hooks.ts +2 -2
- package/scripts/build/build-commands.ts +1 -1
- package/scripts/build/build-hooks.ts +5 -5
- package/scripts/build/build.ts +1 -1
- package/scripts/build/hook-bundle-stamp.ts +109 -7
- package/scripts/build/local-bin.ts +2 -2
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +2 -2
- package/scripts/ci/composite-actions.ts +1 -2
- package/scripts/ci/pr-classification.ts +2 -2
- package/scripts/claude/workflow-destination.ts +1 -1
- package/scripts/clone/clone-aggregate.ts +1 -1
- package/scripts/clone/clone-fingerprint.ts +1 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/index.ts +1 -1
- package/scripts/config-merge/json-format.ts +1 -3
- package/scripts/config-merge/patch-json-array.ts +90 -0
- package/scripts/config-merge/patch-json-key.ts +6 -3
- package/scripts/config-merge/patch-json-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +1 -1
- package/scripts/cost-runtime/context-cut-payback.ts +4 -5
- package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
- package/scripts/cost-runtime/cost-attribute.ts +3 -3
- package/scripts/cost-runtime/cost-blocks.ts +3 -4
- package/scripts/cost-runtime/cost-cli.ts +14 -11
- package/scripts/cost-runtime/cost-corpus.ts +11 -11
- package/scripts/cost-runtime/cost-pricing.ts +4 -4
- package/scripts/cost-runtime/cost-tokens.ts +1 -2
- package/scripts/cost-runtime/cost-transcript.ts +29 -29
- package/scripts/cost-runtime/cost-usage.ts +6 -7
- package/scripts/cost-runtime/cost-verdict.ts +10 -11
- package/scripts/cost-runtime/own-session.ts +1 -1
- package/scripts/cost-runtime/transcript-cwd.ts +2 -2
- package/scripts/delegation/delegation-cli.ts +4 -4
- package/scripts/delegation/delegation-policy.ts +13 -15
- package/scripts/delegation/duplicate-read-guard.ts +9 -10
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +1 -1
- package/scripts/delegation/investigation-guard.ts +18 -22
- package/scripts/delegation/investigation-reads.ts +48 -238
- package/scripts/discovery/repo-discovery.ts +1 -1
- package/scripts/discovery/repo-map-logic.ts +1 -2
- package/scripts/discovery/repo-origin.ts +3 -3
- package/scripts/discovery/repo-party-cli.ts +2 -2
- package/scripts/discovery/repo-party.ts +2 -2
- package/scripts/doctor/doctor-consumer.ts +1 -1
- package/scripts/doctor/doctor-io.ts +6 -7
- package/scripts/doctor/doctor-logic.ts +1 -1
- package/scripts/doctor/doctor-ports.ts +1 -1
- package/scripts/doctor/doctor.ts +8 -9
- package/scripts/document/backlogrun-parent-read-set.ts +5 -6
- package/scripts/document/bash-output-cap.ts +5 -7
- package/scripts/document/capped-print-part.ts +1 -1
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/document-byte-budget.ts +33 -64
- package/scripts/document/document-byte-check.ts +4 -4
- package/scripts/document/document-reachability.ts +7 -8
- package/scripts/document/document-read-cli.ts +2 -2
- package/scripts/document/document-scan.ts +26 -2
- package/scripts/document/document-section-cli.ts +6 -8
- package/scripts/document/document-section.ts +8 -12
- package/scripts/document/edit-files-cli.ts +3 -4
- package/scripts/document/entry-read-budget.ts +8 -70
- package/scripts/document/entry-read-set.ts +51 -34
- package/scripts/document/lane-child-read-set.ts +9 -9
- package/scripts/document/read-files-cli.ts +1 -2
- package/scripts/document/read-set-cli.ts +16 -19
- package/scripts/document/read-set-cost.ts +4 -4
- package/scripts/document/read-set-point-of-use.ts +28 -38
- package/scripts/document/read-set-pricing.ts +1 -1
- package/scripts/document/read-set-trim.ts +3 -3
- package/scripts/document/resident-budget.ts +8 -10
- package/scripts/epic/epic-add-body.ts +15 -18
- package/scripts/epic/epic-add-plan.ts +26 -28
- package/scripts/epic/epic-add.ts +32 -25
- package/scripts/epic/epic-audit-checks.ts +27 -37
- package/scripts/epic/epic-audit-cli.ts +21 -22
- package/scripts/epic/epic-audit-orphans.ts +16 -17
- package/scripts/epic/epic-audit-rationale.ts +10 -15
- package/scripts/epic/epic-audit-report.ts +2 -5
- package/scripts/epic/epic-audit.ts +18 -14
- package/scripts/epic/epic-body.ts +10 -10
- package/scripts/epic/epic-bundle-cli.ts +36 -34
- package/scripts/epic/epic-bundle-evidence.ts +5 -5
- package/scripts/epic/epic-bundle-gaps.ts +6 -9
- package/scripts/epic/epic-bundle-poll.ts +1 -1
- package/scripts/epic/epic-bundle-referenced.ts +11 -14
- package/scripts/epic/epic-bundle.ts +19 -20
- package/scripts/epic/epic-busy.ts +44 -21
- package/scripts/epic/epic-candidate-confirm.ts +15 -18
- package/scripts/epic/epic-chains.ts +18 -23
- package/scripts/epic/epic-classify.ts +11 -12
- package/scripts/epic/epic-cli-argv.ts +5 -6
- package/scripts/epic/epic-cli-remove.ts +9 -4
- package/scripts/epic/epic-cli.ts +38 -26
- package/scripts/epic/epic-close-comment.ts +14 -15
- package/scripts/epic/epic-close.ts +25 -29
- package/scripts/epic/epic-cross-repo.ts +18 -21
- package/scripts/epic/epic-decision.ts +14 -18
- package/scripts/epic/epic-fetch.ts +25 -31
- package/scripts/epic/epic-graph.ts +15 -17
- package/scripts/epic/epic-index.ts +14 -16
- package/scripts/epic/epic-issue.ts +9 -11
- package/scripts/epic/epic-label-age.ts +74 -0
- package/scripts/epic/epic-lane-offer.ts +35 -24
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +8 -8
- package/scripts/epic/epic-next-views.ts +12 -12
- package/scripts/epic/epic-next.ts +29 -33
- package/scripts/epic/epic-outside-blocker.ts +11 -10
- package/scripts/epic/epic-parse.ts +22 -24
- package/scripts/epic/epic-promote.ts +3 -2
- package/scripts/epic/epic-rank.ts +1 -1
- package/scripts/epic/epic-read.ts +10 -8
- package/scripts/epic/epic-reconcile.ts +8 -6
- package/scripts/epic/epic-reference.ts +5 -4
- package/scripts/epic/epic-relation-recheck.ts +10 -11
- package/scripts/epic/epic-relations.ts +9 -8
- package/scripts/epic/epic-remove-plan.ts +4 -5
- package/scripts/epic/epic-remove.ts +7 -5
- package/scripts/epic/epic-report.ts +18 -20
- package/scripts/epic/epic-run.ts +6 -5
- package/scripts/epic/epic-sections.ts +2 -2
- package/scripts/epic/epic-shape.ts +3 -3
- package/scripts/epic/epic-solo-stale.ts +3 -2
- package/scripts/epic/epic-solo.ts +8 -8
- package/scripts/epic/epic-triage.ts +5 -4
- package/scripts/epic/epic-validate.ts +8 -7
- package/scripts/epic/epic.ts +5 -5
- package/scripts/exports/unused-members-cli.ts +1 -1
- package/scripts/followup/followup-issue-number.ts +1 -2
- package/scripts/followup/git-followup-cleanup.ts +6 -7
- package/scripts/followup/git-followup-finish.ts +11 -13
- package/scripts/followup/git-followup-flush.ts +11 -7
- package/scripts/followup/git-followup-issue-close.ts +16 -13
- package/scripts/followup/git-followup-label.ts +9 -6
- package/scripts/followup/git-followup-merged.ts +1 -1
- package/scripts/followup/git-followup-pending.ts +7 -9
- package/scripts/followup/git-followup-stages.ts +28 -17
- package/scripts/followup/git-followup-workflow.ts +19 -21
- package/scripts/followup/git-pr-followup-checks.ts +13 -20
- package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
- package/scripts/followup/git-pr-followup.ts +18 -17
- package/scripts/gate/core-admission.ts +2 -2
- package/scripts/gate/core-budget.ts +15 -26
- package/scripts/gate/gate-ledger.ts +114 -0
- package/scripts/gate/gate-log.ts +7 -9
- package/scripts/gate/gate-plan.ts +70 -35
- package/scripts/gate/gate-report.ts +14 -15
- package/scripts/gate/gate-skip.ts +11 -13
- package/scripts/gate/gate-steps.ts +5 -1
- package/scripts/gate/gate-tree.ts +3 -4
- package/scripts/gate/hook-gate-reuse.ts +9 -9
- package/scripts/gate/machine-capacity.ts +168 -30
- package/scripts/gate/pre-commit-type-check.ts +4 -4
- package/scripts/gate/project-checks.ts +12 -4
- package/scripts/gate/scoped-green.ts +11 -18
- package/scripts/gate/type-check-command.ts +2 -2
- package/scripts/gate/type-check-step.ts +4 -4
- package/scripts/gate/verification-gate.ts +53 -51
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/gh/git-ai-review-scan.ts +3 -2
- package/scripts/gh/git-gh-api-path.ts +10 -11
- package/scripts/gh/git-gh-exec.ts +43 -48
- package/scripts/gh/git-gh-failure.ts +6 -9
- package/scripts/gh/git-gh-helpers.ts +1 -1
- package/scripts/gh/git-gh-issue-list.ts +15 -19
- package/scripts/gh/git-gh-issue-read.ts +43 -60
- package/scripts/gh/git-gh-issue-rest.ts +14 -15
- package/scripts/gh/git-gh-issue-write.ts +52 -40
- package/scripts/gh/git-gh-issue.ts +23 -24
- package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
- package/scripts/gh/git-gh-pr-read.ts +46 -50
- package/scripts/gh/git-gh-pr-rest.ts +23 -26
- package/scripts/gh/git-gh-pr-review.ts +2 -2
- package/scripts/gh/git-gh-pr-rollup.ts +4 -4
- package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
- package/scripts/gh/git-gh-pr.ts +16 -16
- package/scripts/gh/git-gh-reachability.ts +11 -12
- package/scripts/gh/git-gh-repo.ts +2 -3
- package/scripts/gh/git-gh-rest-state.ts +1 -1
- package/scripts/gh/git-pr-ai-review.ts +6 -5
- package/scripts/gh/git-pr-checks-eval.ts +28 -30
- package/scripts/gh/git-pr-checks-parse.ts +14 -16
- package/scripts/gh/git-pr-checks-watch.ts +17 -17
- package/scripts/gh/git-pr-checks.ts +20 -23
- package/scripts/gh/git-pr-coderabbit.ts +8 -6
- package/scripts/gh/git-pr-confirmation.ts +5 -5
- package/scripts/gh/git-pr-managed-config.ts +7 -9
- package/scripts/gh/git-pr-messages.ts +1 -1
- package/scripts/gh/git-pr.ts +15 -16
- package/scripts/gh/github-issue-url.ts +8 -9
- package/scripts/git/base-tree.ts +66 -0
- package/scripts/git/change-base.ts +42 -2
- package/scripts/git/changed-file-scope.ts +5 -5
- package/scripts/git/changed-paths.ts +1 -2
- package/scripts/git/constants.ts +2 -2
- package/scripts/git/git-branch.ts +1 -1
- package/scripts/git/git-closes-keyword.ts +3 -3
- package/scripts/git/git-command.ts +53 -41
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +14 -15
- package/scripts/git/git-error.ts +1 -1
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/git/git-issue.ts +10 -8
- package/scripts/git/git-location-environment.ts +3 -4
- package/scripts/git/git-ls-remote.ts +6 -8
- package/scripts/git/git-pre-push-hook.ts +11 -10
- package/scripts/git/git-preflight.ts +5 -5
- package/scripts/git/git-push-transport.ts +2 -2
- package/scripts/git/git-remote-branch.ts +1 -2
- package/scripts/git/git-schemas.ts +16 -23
- package/scripts/git/git-spawn-sync.ts +1 -1
- package/scripts/git/git-spawn.ts +37 -14
- package/scripts/git/git-ssh-keepalive.ts +12 -5
- package/scripts/git/git-staging.ts +7 -8
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/git-worktree.ts +35 -27
- package/scripts/git/gone-branch.ts +2 -2
- package/scripts/git/listing-cutoff.ts +1 -2
- package/scripts/git/lockfile-sync.ts +65 -0
- package/scripts/git/main-merge-guard.ts +1 -2
- package/scripts/git/main-merge.ts +7 -7
- package/scripts/git/main-sync.ts +23 -8
- package/scripts/git/parse-json-array.ts +18 -23
- package/scripts/git/repository-lock.ts +34 -2
- package/scripts/git/stash/git-stash.ts +4 -5
- package/scripts/git/stash/stash-orphans.ts +5 -3
- package/scripts/git/stash/stash-pop-args.ts +1 -1
- package/scripts/git/stash/stash-pop-cli.ts +3 -3
- package/scripts/git/stash/stash-sweep-lock.ts +2 -2
- package/scripts/hooks/batch-guard.ts +11 -13
- package/scripts/hooks/check-commit-message.ts +12 -9
- package/scripts/hooks/codex-hook-adapter.ts +16 -10
- package/scripts/hooks/edited-cspell.ts +3 -4
- package/scripts/hooks/format-edited-cli.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +11 -17
- package/scripts/hooks/format-rewrite-notice.ts +19 -17
- package/scripts/hooks/pre-push-unit.ts +10 -14
- package/scripts/hooks/pretool-guard-cli.ts +4 -4
- package/scripts/hooks/pretool-guard.ts +93 -18
- package/scripts/hooks/reserved-run.ts +2 -2
- package/scripts/hooks/step-zero-notice.ts +1 -1
- package/scripts/hooks/stop-guard.ts +21 -10
- package/scripts/init/basic-path-migration.ts +2 -2
- package/scripts/init/claude-kit-only-settings.ts +2 -2
- package/scripts/init/claude-plugin-config.ts +2 -2
- package/scripts/init/distributed-paths.ts +4 -4
- package/scripts/init/hook-command-rewrite.ts +3 -3
- package/scripts/init/hook-launch.ts +5 -5
- package/scripts/init/init-actions.ts +13 -0
- package/scripts/init/init-ai-copy.ts +11 -11
- package/scripts/init/init-bootstrap.ts +3 -3
- package/scripts/init/init-copy-content.ts +4 -4
- package/scripts/init/init-logic-json-merge.ts +7 -9
- package/scripts/init/init-logic-migrate.ts +1 -1
- package/scripts/init/init-logic-templates.ts +1 -1
- package/scripts/init/init-logic-workspace.ts +4 -4
- package/scripts/init/init-logic-yaml-merge.ts +2 -2
- package/scripts/init/init-logic.ts +19 -22
- package/scripts/init/init.ts +7 -7
- package/scripts/init/kit-base-preset.ts +1 -1
- package/scripts/init/kit-setup-state.ts +1 -1
- package/scripts/init/kit-written-paths.ts +1 -2
- package/scripts/init/package-manager-pin.ts +1 -1
- package/scripts/init/project-profile-cli.ts +1 -1
- package/scripts/init/project-profile.ts +3 -3
- package/scripts/init/session-language-environment.ts +1 -1
- package/scripts/init/start-exec.ts +3 -4
- package/scripts/init/start-plan.ts +2 -2
- package/scripts/init/start-setup-pr.ts +3 -2
- package/scripts/init/start-steps.ts +2 -2
- package/scripts/init/tsconfig-preset-migration.ts +1 -1
- package/scripts/init/vscode-tasks.ts +62 -0
- package/scripts/issue/baseline-measure.ts +2 -2
- package/scripts/issue/behavior-change-lint.ts +2 -2
- package/scripts/issue/defect-rate-cli.ts +6 -7
- package/scripts/issue/defect-rate.ts +37 -27
- package/scripts/issue/git-next-issues.ts +9 -8
- package/scripts/issue/issue-auto-ok.ts +24 -11
- package/scripts/issue/issue-backlinks-cli.ts +5 -5
- package/scripts/issue/issue-backlinks.ts +6 -6
- package/scripts/issue/issue-cite-cli.ts +20 -18
- package/scripts/issue/issue-cite.ts +18 -8
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +6 -4
- package/scripts/issue/issue-file-cli.ts +52 -15
- package/scripts/issue/issue-file-fold.ts +155 -0
- package/scripts/issue/issue-file.ts +9 -6
- package/scripts/issue/issue-fold-cli.ts +14 -9
- package/scripts/issue/issue-fold.ts +23 -8
- package/scripts/issue/issue-labels.ts +34 -38
- package/scripts/issue/issue-lint-cli.ts +2 -2
- package/scripts/issue/issue-lint.ts +1 -1
- package/scripts/issue/issue-merged.ts +10 -4
- package/scripts/issue/issue-number-shape.ts +27 -0
- package/scripts/issue/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +4 -5
- package/scripts/issue/issue-read.ts +4 -5
- package/scripts/issue/issue-reference.ts +5 -5
- package/scripts/issue/issue-release-cli.ts +17 -7
- package/scripts/issue/issue-release.ts +3 -3
- package/scripts/issue/issue-report-failures.ts +7 -4
- package/scripts/issue/issue-scout-cli.ts +11 -11
- package/scripts/issue/issue-scout-closed.ts +4 -4
- package/scripts/issue/issue-scout.ts +4 -5
- package/scripts/issue/issue-state-cli.ts +17 -10
- package/scripts/issue/issue-state.ts +12 -13
- package/scripts/issue/issue-wip.ts +7 -7
- package/scripts/issue/markdown-section.ts +3 -3
- package/scripts/issue/measure-rerun-cli.ts +10 -9
- package/scripts/issue/reproduction-measure.ts +3 -3
- package/scripts/issue/session-cite.ts +56 -0
- package/scripts/josh/agent-session-environment.ts +10 -8
- package/scripts/josh/cli-body.ts +2 -2
- package/scripts/josh/command-suggest.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +20 -23
- package/scripts/josh/hook-decision.ts +24 -28
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +30 -35
- package/scripts/josh/josh-commands-ai.ts +6 -6
- package/scripts/josh/josh-commands-backlog.ts +15 -3
- package/scripts/josh/josh-commands-clone.ts +1 -1
- package/scripts/josh/josh-commands-development.ts +25 -4
- package/scripts/josh/josh-commands-document.ts +3 -3
- package/scripts/josh/josh-commands-guard.ts +3 -3
- package/scripts/josh/josh-commands-issue.ts +4 -5
- package/scripts/josh/josh-commands-lane.ts +14 -4
- package/scripts/josh/josh-commands-lint.ts +1 -1
- package/scripts/josh/josh-commands-run.ts +20 -6
- package/scripts/josh/josh-commands-split.ts +1 -2
- package/scripts/josh/josh-commands-versioning.ts +5 -5
- package/scripts/josh/josh-commands-workflow.ts +30 -22
- package/scripts/josh/josh-environment-file.ts +1 -1
- package/scripts/josh/josh-in-process.ts +3 -3
- package/scripts/josh/josh-logic.ts +6 -7
- package/scripts/josh/josh-run.ts +3 -3
- package/scripts/josh/josh-verdict.ts +9 -12
- package/scripts/josh/josh.ts +3 -3
- package/scripts/josh/kit-only.ts +2 -2
- package/scripts/josh/path-decision.ts +3 -3
- package/scripts/josh/platform-temporary.ts +7 -5
- package/scripts/josh/process-identity.ts +24 -6
- package/scripts/josh/process-owner.ts +4 -4
- package/scripts/josh/session-language-cli.ts +53 -11
- package/scripts/josh/session-language.ts +1 -1
- package/scripts/josh/stamp-file.ts +48 -29
- package/scripts/josh/stamp-record.ts +57 -0
- package/scripts/lane/lane-await.ts +35 -11
- package/scripts/lane/lane-cache.ts +6 -6
- package/scripts/lane/lane-capacity.ts +32 -17
- package/scripts/lane/lane-child-invocation.ts +17 -15
- package/scripts/lane/lane-child-marker.ts +12 -12
- package/scripts/lane/lane-cli.ts +12 -13
- package/scripts/lane/lane-close.ts +6 -6
- package/scripts/lane/lane-dispatch.ts +61 -72
- package/scripts/lane/lane-environment.ts +5 -5
- package/scripts/lane/lane-guard-policy.ts +7 -21
- package/scripts/lane/lane-handoff.ts +2 -2
- package/scripts/lane/lane-install.ts +9 -10
- package/scripts/lane/lane-launch-cli.ts +13 -8
- package/scripts/lane/lane-ledger.ts +73 -11
- package/scripts/lane/lane-leftover.ts +2 -2
- package/scripts/lane/lane-limit-cli.ts +160 -0
- package/scripts/lane/lane-limit-override.ts +74 -0
- package/scripts/lane/lane-load.ts +19 -68
- package/scripts/lane/lane-measure-cli.ts +15 -25
- package/scripts/lane/lane-occupancy.ts +6 -4
- package/scripts/lane/lane-open.ts +20 -19
- package/scripts/lane/lane-output.ts +4 -3
- package/scripts/lane/lane-paths.ts +12 -11
- package/scripts/lane/lane-phase.ts +33 -0
- package/scripts/lane/lane-reap.ts +2 -2
- package/scripts/lane/lane-registry.ts +16 -15
- package/scripts/lane/lane-relaunch.ts +9 -9
- package/scripts/lane/lane-report.ts +5 -4
- package/scripts/lane/lane-resume.ts +2 -2
- package/scripts/lane/lane-sampler.ts +55 -0
- package/scripts/lane/lane-seed.ts +7 -7
- package/scripts/lane/lane-stage-stats.ts +135 -0
- package/scripts/lane/lane-start-point.ts +8 -11
- package/scripts/lane/lane-stats.ts +60 -15
- package/scripts/lane/lane-stray.ts +1 -1
- package/scripts/lane/lane-vacant.ts +1 -1
- package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
- package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
- package/scripts/lane/openai-review-broker.ts +2 -4
- package/scripts/lib/ancestor-directories.ts +1 -1
- package/scripts/lib/bounded-pool.ts +2 -2
- package/scripts/lib/buffered-process.ts +4 -6
- package/scripts/lib/caddy-logs.sh +0 -0
- package/scripts/lib/cli-flags.ts +39 -6
- package/scripts/lib/error-message.ts +1 -1
- package/scripts/lib/json-value.ts +17 -3
- package/scripts/lib/poll.ts +1 -1
- package/scripts/lib/status-icons.ts +3 -3
- package/scripts/lib/timed-fetch.ts +1 -1
- package/scripts/lib/timeouts.ts +1 -1
- package/scripts/lines/bytes-command.ts +3 -4
- package/scripts/lines/effective-limit.ts +25 -12
- package/scripts/lines/line-budget.ts +47 -55
- package/scripts/lines/line-targets.ts +6 -2
- package/scripts/lines/lines-command.ts +3 -3
- package/scripts/lint/cspell-cached.ts +1 -1
- package/scripts/lint/cycle-recheck.ts +122 -0
- package/scripts/lint/format.ts +1 -2
- package/scripts/lint/lint-parallel.ts +34 -19
- package/scripts/lint/lint-related-scope.ts +25 -15
- package/scripts/lint/lint-related.ts +6 -7
- package/scripts/managed-marker/index.ts +1 -1
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/git-notify.ts +9 -7
- package/scripts/notify/telegram-notify.ts +53 -37
- package/scripts/notify/telegram-test-logic.ts +3 -3
- package/scripts/notify/telegram-test.ts +45 -30
- package/scripts/observations/observation-ledger-home.ts +14 -8
- package/scripts/observations/observation-ledger-line.ts +3 -2
- package/scripts/observations/observation-ledger-migrate.ts +3 -4
- package/scripts/observations/observation-ledger-prepare.ts +4 -4
- package/scripts/observations/observation-ledger.ts +14 -15
- package/scripts/observations/observation-record-cli.ts +83 -0
- package/scripts/observations/observation-record.ts +91 -0
- package/scripts/observations/observations-flush-cli.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +7 -6
- package/scripts/observations/observations-flush.ts +26 -27
- package/scripts/overrides/overrides-check.ts +18 -8
- package/scripts/package/package-scout-cli.ts +1 -1
- package/scripts/package/package-scout-format.ts +2 -2
- package/scripts/package/package-scout.ts +1 -1
- package/scripts/propagate/propagate-git-failure.ts +1 -1
- package/scripts/propagate/propagate-git.ts +7 -7
- package/scripts/propagate/propagate-plan.ts +2 -2
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +5 -7
- package/scripts/propagate/propagate-select.ts +1 -1
- package/scripts/propagate/propagate-steps.ts +19 -20
- package/scripts/propagate/propagate-targets.ts +6 -10
- package/scripts/propagate/propagate.ts +5 -5
- package/scripts/refactor/import-graph.ts +1 -1
- package/scripts/refactor/refactor-lint.ts +4 -10
- package/scripts/refactor/refactor-scan-cli.ts +1 -1
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +1 -1
- package/scripts/release/github-release-cli.ts +25 -3
- package/scripts/release/github-release-runs.ts +1 -1
- package/scripts/release/release-cli.ts +21 -4
- package/scripts/release/release-history.ts +6 -10
- package/scripts/release/release-plan.ts +3 -3
- package/scripts/release/release-progress.ts +3 -4
- package/scripts/release/release-publish.ts +8 -9
- package/scripts/release/release-scope-cli.ts +8 -10
- package/scripts/release/release-tag.ts +6 -8
- package/scripts/release/release-worktree.ts +5 -5
- package/scripts/repo/auto-merge-setting-logic.ts +7 -9
- package/scripts/repo/auto-merge-setting.ts +1 -1
- package/scripts/repo/repo-setting.ts +4 -4
- package/scripts/repo/repository-labels.ts +1 -1
- package/scripts/repo/required-checks-logic.ts +3 -3
- package/scripts/repo/required-checks-report.ts +1 -1
- package/scripts/repo/ruleset-check-cli.ts +1 -1
- package/scripts/repo/ruleset-check.ts +1 -1
- package/scripts/report/report-format-reference.ts +26 -0
- package/scripts/report/report-lint-cli.ts +2 -2
- package/scripts/report/report-lint.ts +16 -2
- package/scripts/review/disposition-cli.ts +2 -2
- package/scripts/review/disposition-logic.ts +1 -1
- package/scripts/review/live-evidence.ts +9 -6
- package/scripts/review/review-attest-cli.ts +1 -2
- package/scripts/review/review-attest.ts +3 -3
- package/scripts/review/review-brief-cli.ts +19 -20
- package/scripts/review/review-brief.ts +29 -32
- package/scripts/review/review-checkout.ts +2 -2
- package/scripts/review/review-diff-parts.ts +3 -5
- package/scripts/review/review-diff-write.ts +1 -1
- package/scripts/review/review-finding-ledger.ts +7 -4
- package/scripts/review/review-findings-cli.ts +2 -2
- package/scripts/review/review-level.ts +4 -7
- package/scripts/review/review-record-cli.ts +73 -16
- package/scripts/review/review-record.ts +5 -4
- package/scripts/review/review-round2-cli.ts +2 -3
- package/scripts/review/review-round2.ts +13 -21
- package/scripts/review/review-stamps.ts +9 -71
- package/scripts/review/review-tree.ts +4 -5
- package/scripts/rules/bash-triggers.ts +4 -4
- package/scripts/rules/decision-oracle-batch.ts +5 -6
- package/scripts/rules/decision-oracle-stage.ts +1 -1
- package/scripts/rules/decision-oracle-tokens.ts +1 -2
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +61 -406
- package/scripts/rules/destructive-command.ts +2 -2
- package/scripts/rules/direct-filing.ts +4 -4
- package/scripts/rules/direct-pr-create.ts +2 -2
- package/scripts/rules/early-heartbeat.ts +15 -19
- package/scripts/rules/file-body.ts +5 -6
- package/scripts/rules/filing-cap.ts +6 -7
- package/scripts/rules/filing-offer.ts +1 -1
- package/scripts/rules/firing-point.ts +6 -6
- package/scripts/rules/gh-api.ts +2 -2
- package/scripts/rules/git-argv.ts +3 -3
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/hook-context-line.ts +31 -0
- package/scripts/rules/implementation-cut-verdict.ts +5 -8
- package/scripts/rules/implementation-cut.ts +35 -32
- package/scripts/rules/index-guard.ts +2 -2
- package/scripts/rules/issue-citation.ts +7 -7
- package/scripts/rules/issue-comments.ts +21 -13
- package/scripts/rules/josh-git-bare.ts +2 -2
- package/scripts/rules/lane-background.ts +14 -16
- package/scripts/rules/lane-carry-conflict.ts +41 -5
- package/scripts/rules/lane-interactive-ask.ts +6 -9
- package/scripts/rules/lane-park.ts +12 -16
- package/scripts/rules/lane-split-park.ts +1 -2
- package/scripts/rules/lane-switch-main.ts +10 -13
- package/scripts/rules/last-prompt.ts +1 -1
- package/scripts/rules/oracle-consulted.ts +5 -5
- package/scripts/rules/oracle-firing.ts +6 -9
- package/scripts/rules/oracle-list-cli.ts +2 -2
- package/scripts/rules/permission-guards.ts +2 -2
- package/scripts/rules/piped-verification.ts +79 -9
- package/scripts/rules/poll-loop.ts +9 -11
- package/scripts/rules/pre-gate-cut.ts +33 -30
- package/scripts/rules/prior-comment-read.ts +3 -3
- package/scripts/rules/protected-files.ts +25 -13
- package/scripts/rules/raw-field-body.ts +3 -4
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +10 -12
- package/scripts/rules/rule-guard.ts +1 -1
- package/scripts/rules/rule-list.ts +51 -0
- package/scripts/rules/rule-registry-rows.ts +282 -0
- package/scripts/rules/rule-registry.ts +109 -0
- package/scripts/rules/rule-value-cache.ts +2 -2
- package/scripts/rules/rule-value-cli.ts +6 -4
- package/scripts/rules/rule-value.ts +61 -22
- package/scripts/rules/run-tail-rule.ts +11 -15
- package/scripts/rules/shell-body-trigger.ts +7 -7
- package/scripts/rules/shell-segments.ts +2 -4
- package/scripts/rules/stop-rules.ts +54 -41
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +2 -2
- package/scripts/rules/third-party-write.ts +3 -3
- package/scripts/rules/worktree-guard.ts +12 -5
- package/scripts/run/add/run-add-cli.ts +165 -0
- package/scripts/run/add/run-add.ts +124 -0
- package/scripts/run/board/run-board-cli.ts +207 -0
- package/scripts/run/board/run-board-closed.ts +95 -0
- package/scripts/run/board/run-board-every.ts +60 -0
- package/scripts/run/board/run-board-fetch.ts +38 -0
- package/scripts/run/board/run-board-fit.ts +219 -0
- package/scripts/run/board/run-board-github.ts +162 -0
- package/scripts/run/board/run-board-header.ts +275 -0
- package/scripts/run/board/run-board-kind.ts +35 -0
- package/scripts/run/board/run-board-labels.ts +299 -0
- package/scripts/run/board/run-board-layout.ts +222 -0
- package/scripts/run/board/run-board-link.ts +31 -0
- package/scripts/run/board/run-board-machine.ts +198 -0
- package/scripts/run/board/run-board-notes.ts +103 -0
- package/scripts/run/board/run-board-phase.ts +136 -0
- package/scripts/run/board/run-board-plan.ts +129 -0
- package/scripts/run/board/run-board-read.ts +62 -0
- package/scripts/run/board/run-board-render-legend.ts +82 -0
- package/scripts/run/board/run-board-render-notes.ts +77 -0
- package/scripts/run/board/run-board-render-slot.ts +50 -0
- package/scripts/run/board/run-board-render.ts +407 -0
- package/scripts/run/board/run-board-scope.ts +17 -0
- package/scripts/run/board/run-board-screen.ts +43 -0
- package/scripts/run/board/run-board-span.ts +66 -0
- package/scripts/run/board/run-board-spin.ts +115 -0
- package/scripts/run/board/run-board-state.ts +113 -0
- package/scripts/run/board/run-board-status.ts +279 -0
- package/scripts/run/board/run-board-tick.ts +210 -0
- package/scripts/run/board/run-board-track.ts +22 -0
- package/scripts/run/board/run-board-usage-read.ts +255 -0
- package/scripts/run/board/run-board-usage-rusage.ts +124 -0
- package/scripts/run/board/run-board-usage-text.ts +80 -0
- package/scripts/run/board/run-board-usage.ts +165 -0
- package/scripts/run/carry/run-carry-added.ts +62 -0
- package/scripts/run/carry/run-carry-args.ts +25 -22
- package/scripts/run/carry/run-carry-change.ts +1 -1
- package/scripts/run/carry/run-carry-cli.ts +71 -48
- package/scripts/run/carry/run-carry-conversation.ts +6 -7
- package/scripts/run/carry/run-carry-ended.ts +85 -0
- package/scripts/run/carry/run-carry-reclaim.ts +1 -1
- package/scripts/run/carry/run-carry-stash.ts +3 -2
- package/scripts/run/carry/run-carry-streak.ts +8 -10
- package/scripts/run/carry/run-carry.ts +85 -89
- package/scripts/run/cut/run-cut-args.ts +7 -7
- package/scripts/run/cut/run-cut-cli.ts +54 -36
- package/scripts/run/cut/run-cut-handoff.ts +15 -15
- package/scripts/run/cut/run-cut-report.ts +37 -16
- package/scripts/run/cut/run-cut.ts +63 -77
- package/scripts/run/detached-launch.ts +35 -50
- package/scripts/run/entry/run-entry-cli.ts +48 -27
- package/scripts/run/entry/run-entry-stop.ts +7 -9
- package/scripts/run/entry/run-entry.ts +5 -6
- package/scripts/run/event/run-event-cli.ts +5 -6
- package/scripts/run/event/run-event-filed.ts +69 -0
- package/scripts/run/event/run-event-follow.ts +3 -3
- package/scripts/run/event/run-event-plan.ts +38 -0
- package/scripts/run/event/run-event-render.ts +9 -4
- package/scripts/run/event/run-event-scope.ts +47 -18
- package/scripts/run/event/run-event-stream-emit.ts +64 -11
- package/scripts/run/event/run-event-stream.ts +171 -46
- package/scripts/run/event/run-event-watch.ts +4 -6
- package/scripts/run/hold/run-hold-cli.ts +65 -62
- package/scripts/run/hold/run-hold.ts +88 -46
- package/scripts/run/merge/run-merge-cli.ts +116 -77
- package/scripts/run/merge/run-merge-collect.ts +107 -0
- package/scripts/run/merge/run-merge-steps.ts +112 -65
- package/scripts/run/merge/run-merge-token.ts +30 -0
- package/scripts/run/merge/run-merge.ts +31 -22
- package/scripts/run/progress/run-progress-args.ts +4 -4
- package/scripts/run/progress/run-progress-cli.ts +39 -50
- package/scripts/run/progress/run-progress-clock.ts +25 -32
- package/scripts/run/progress/run-progress-config.ts +6 -9
- package/scripts/run/progress/run-progress-read.ts +9 -10
- package/scripts/run/progress/run-progress.ts +48 -53
- package/scripts/run/review/run-review-cli.ts +6 -6
- package/scripts/run/review/run-review-steps.ts +6 -6
- package/scripts/run/review/run-review.ts +9 -11
- package/scripts/run/run-cli-fault.ts +29 -0
- package/scripts/run/run-ending-cli.ts +3 -3
- package/scripts/run/run-ending.ts +10 -14
- package/scripts/run/run-halfrun-resume.ts +6 -8
- package/scripts/run/run-headless.ts +25 -12
- package/scripts/run/run-invocation.ts +17 -22
- package/scripts/run/run-label.ts +7 -5
- package/scripts/run/run-liveness-cli.ts +19 -6
- package/scripts/run/run-liveness.ts +27 -38
- package/scripts/run/run-next-cli.ts +5 -9
- package/scripts/run/run-next.ts +4 -5
- package/scripts/run/run-parent-cut-hook.ts +10 -12
- package/scripts/run/run-preflight.ts +25 -29
- package/scripts/run/run-prep-cli.ts +17 -13
- package/scripts/run/run-prep-locate.ts +4 -5
- package/scripts/run/run-prep.ts +7 -10
- package/scripts/run/run-prrun-resume.ts +2 -2
- package/scripts/run/run-report-cli.ts +4 -4
- package/scripts/run/run-report.ts +9 -14
- package/scripts/run/run-retrospective.ts +3 -3
- package/scripts/run/run-section.ts +42 -0
- package/scripts/run/run-stage-read.ts +2 -2
- package/scripts/run/run-stage.ts +6 -4
- package/scripts/run/run-status-cli.ts +7 -5
- package/scripts/run/run-status.ts +6 -7
- package/scripts/run/run-step-cli.ts +13 -15
- package/scripts/run/run-step.ts +58 -47
- package/scripts/run/run-stop-notify.ts +7 -8
- package/scripts/run/run-stranded-cli.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +4 -4
- package/scripts/run/run-stranded.ts +11 -13
- package/scripts/run/run-tail-cli.ts +15 -16
- package/scripts/run/run-tail.ts +14 -33
- package/scripts/run/run-watcher-guard-cli.ts +3 -4
- package/scripts/run/run-watcher-guard.ts +11 -12
- package/scripts/run/run-watcher-hook.ts +6 -12
- package/scripts/run/ship/run-ship-cli.ts +67 -33
- package/scripts/run/ship/run-ship-detach.ts +15 -13
- package/scripts/run/ship/run-ship-lock.ts +1 -1
- package/scripts/run/ship/run-ship-next.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
- package/scripts/run/ship/run-ship-preflight.ts +10 -11
- package/scripts/run/ship/run-ship-probe.ts +4 -4
- package/scripts/run/ship/run-ship-return.ts +1 -1
- package/scripts/run/ship/run-ship-review-steps.ts +43 -24
- package/scripts/run/ship/run-ship-review.ts +12 -14
- package/scripts/run/ship/run-ship-scoped.ts +15 -6
- package/scripts/run/ship/run-ship-stage.ts +80 -26
- package/scripts/run/ship/run-ship-steps.ts +26 -16
- package/scripts/run/ship/run-ship-stop-text.ts +4 -2
- package/scripts/run/ship/run-ship-sync.ts +9 -8
- package/scripts/run/ship/run-ship.ts +17 -32
- package/scripts/run/tidy/run-tidy-cli.ts +9 -5
- package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
- package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
- package/scripts/run/tidy/run-tidy.ts +4 -3
- package/scripts/run/wake/run-wake-cli.ts +27 -32
- package/scripts/run/wake/run-wake-describe.ts +24 -28
- package/scripts/run/wake/run-wake-driver.ts +14 -14
- package/scripts/run/wake/run-wake-handoff.ts +6 -6
- package/scripts/run/wake/run-wake-loop.ts +9 -9
- package/scripts/run/wake/run-wake-restart.ts +4 -5
- package/scripts/run/wake/run-wake-session.ts +23 -27
- package/scripts/run/wake/run-wake.ts +57 -279
- package/scripts/safe-chain/ci-installer-pin.ts +3 -3
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -2
- package/scripts/security/security-audit-logic.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +1 -1
- package/scripts/security/security-audit-provision.ts +2 -2
- package/scripts/security/security-audit.ts +5 -5
- package/scripts/security/security-updates-logic.ts +2 -3
- package/scripts/security/security-updates.ts +2 -4
- package/scripts/self-sync-guard/index.ts +1 -1
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
- package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
- package/scripts/sonar/sonar-hotspots.ts +1 -1
- package/scripts/sonar/sonar-new-code-cli.ts +1 -1
- package/scripts/sonar/sonar-new-code.ts +1 -1
- package/scripts/sonar/sonar-project.ts +1 -1
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +3 -3
- package/scripts/sync/directory-copy-guard.ts +2 -3
- package/scripts/sync/managed-config-scope-cli.ts +1 -2
- package/scripts/sync/managed-config-scope.ts +4 -4
- package/scripts/sync/plugin-skill-directories.ts +2 -2
- package/scripts/sync/reconcile-templates.ts +17 -8
- package/scripts/sync/removed-skill-manifest.ts +2 -3
- package/scripts/sync/sync-ai-files.ts +7 -7
- package/scripts/sync/sync-configs.ts +30 -3
- package/scripts/sync/sync-hook-safety.ts +2 -2
- package/scripts/sync/sync.ts +23 -10
- package/scripts/sync/synced-paths.ts +2 -1
- package/scripts/sync/workflow-pin-logic.ts +1 -1
- package/scripts/test/test-declared-changed.ts +4 -4
- package/scripts/test/test-declared-logic.ts +2 -3
- package/scripts/test/test-declared-match.ts +25 -4
- package/scripts/test/test-declared.ts +26 -9
- package/scripts/test/test-red-commit.ts +3 -2
- package/scripts/test/test-red-logic.ts +7 -14
- package/scripts/test/test-red.ts +12 -47
- package/scripts/test/test-related-scope.ts +2 -3
- package/scripts/test/test-related.ts +3 -3
- package/scripts/test/test-type-logic.ts +1 -2
- package/scripts/test/test-unit-guard.ts +13 -17
- package/scripts/test/unit-worker-share.ts +7 -8
- package/scripts/time-runtime/time-agent-bundles.ts +2 -4
- package/scripts/time-runtime/time-background.ts +17 -21
- package/scripts/time-runtime/time-batch-guard.ts +67 -342
- package/scripts/time-runtime/time-bundle-call.ts +26 -28
- package/scripts/time-runtime/time-bundles.ts +11 -12
- package/scripts/time-runtime/time-call-identity.ts +1 -1
- package/scripts/time-runtime/time-command-key.ts +2 -2
- package/scripts/time-runtime/time-density-hook.ts +8 -11
- package/scripts/time-runtime/time-density.ts +5 -5
- package/scripts/time-runtime/time-followup-stage.ts +7 -7
- package/scripts/time-runtime/time-format.ts +5 -5
- package/scripts/time-runtime/time-hook-transcript.ts +3 -3
- package/scripts/time-runtime/time-instant.ts +1 -1
- package/scripts/time-runtime/time-markers.ts +15 -19
- package/scripts/time-runtime/time-phase-names.ts +3 -3
- package/scripts/time-runtime/time-reported-failure.ts +15 -19
- package/scripts/time-runtime/time-round-trips.ts +20 -23
- package/scripts/time-runtime/time-shell.ts +8 -8
- package/scripts/time-runtime/time-single-check.ts +1 -2
- package/scripts/time-runtime/time-spans.ts +35 -40
- package/scripts/time-runtime/time-tool-call.ts +15 -16
- package/scripts/time-runtime/time-transcript-line.ts +53 -34
- package/scripts/time-runtime/time-writes.ts +5 -5
- package/scripts/ui/ui-routes-cli.ts +1 -2
- package/scripts/ui/ui-routes.ts +1 -2
- package/scripts/version/bump-version.ts +1 -1
- package/scripts/version/fresh-metadata-cache.ts +2 -2
- package/scripts/version/latest-corepack.ts +26 -26
- package/scripts/version/latest-lane-guard.ts +1 -1
- package/scripts/version/latest-scope-cli.ts +2 -2
- package/scripts/version/latest-stamp.ts +1 -2
- package/scripts/version/latest-update.ts +2 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/package-manager-version.ts +18 -0
- package/scripts/version/publishable-range-check.ts +2 -1
- package/scripts/version/publishable-range.ts +1 -1
- package/scripts/version/release-age.ts +11 -11
- package/scripts/version/release-hold.ts +2 -2
- package/scripts/version/safe-chain-version-update.ts +3 -3
- package/scripts/version/version-check-logic.ts +2 -3
- package/scripts/version/version-check.ts +1 -2
- package/scripts/version/version-command-config.ts +2 -2
- package/scripts/version/version-commands.ts +3 -3
- package/scripts/version/version-remote.ts +4 -4
- package/scripts/version/version-targets.ts +2 -2
- package/templates/gitignore +7 -0
- package/dist/hooks/chunk-KHX4U3BG.js +0 -6400
- package/dist/hooks/chunk-RKUAD3I6.js +0 -90
- package/dist/hooks/chunk-WPALEIRX.js +0 -18
- package/scripts/backlog/backlog-restructure.ts +0 -152
- package/scripts/rules/issue-fold-rule.ts +0 -72
- package/scripts/rules/wip-cap.ts +0 -63
- package/scripts/run/run-issue-number.ts +0 -19
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ENV_FILE_NAME
|
|
3
|
-
|
|
2
|
+
ENV_FILE_NAME,
|
|
3
|
+
cost_transcript,
|
|
4
|
+
json_value,
|
|
5
|
+
process_identity,
|
|
6
|
+
process_owner_schema,
|
|
7
|
+
run_carry,
|
|
8
|
+
time_instant
|
|
9
|
+
} from "./chunk-NZN2UFI6.js";
|
|
4
10
|
import {
|
|
5
11
|
PLATFORM_TEMP_ROOT,
|
|
6
12
|
PROBE_TIMEOUT_MS,
|
|
7
13
|
stamp_file
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
|
|
10
|
-
// scripts/lib/json-value.ts
|
|
11
|
-
function parse_or_undefined(text) {
|
|
12
|
-
try {
|
|
13
|
-
return JSON.parse(text);
|
|
14
|
-
} catch {
|
|
15
|
-
return void 0;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function is_record(value) {
|
|
19
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20
|
-
}
|
|
21
|
-
var json_value = { parse_or_undefined, is_record };
|
|
14
|
+
} from "./chunk-NEC4AT4Z.js";
|
|
22
15
|
|
|
23
16
|
// scripts/cost-runtime/cost-blocks.ts
|
|
24
17
|
import { z } from "zod";
|
|
@@ -151,6 +144,17 @@ var CSPELL_CACHE_FLAGS = content_cache_flags(CSPELL_CACHE_FILE);
|
|
|
151
144
|
|
|
152
145
|
// scripts/josh/josh-commands-backlog.ts
|
|
153
146
|
var BACKLOG_COMMANDS = {
|
|
147
|
+
// Started from a terminal: the `backlogrun` keyword's launcher, and the board.
|
|
148
|
+
backlogrun: {
|
|
149
|
+
script: "scripts/backlog/backlogrun-cli.ts",
|
|
150
|
+
description: "Start a backlogrun in the background and show its board; with one already running, only show the board",
|
|
151
|
+
category: "AI tools",
|
|
152
|
+
reference: [
|
|
153
|
+
"[#<n>...] [--only] [--max <n>] [--idle <minutes>] [--agent claude|codex]",
|
|
154
|
+
"developer",
|
|
155
|
+
["files", "network", "processes"]
|
|
156
|
+
]
|
|
157
|
+
},
|
|
154
158
|
"backlog:next": {
|
|
155
159
|
script: "scripts/backlog/backlog-next.ts",
|
|
156
160
|
description: "Order the whole opted-in backlog: auto-ok issues and the descendants of auto-ok epics, transitively through nested epics",
|
|
@@ -181,7 +185,7 @@ var BACKLOG_COMMANDS = {
|
|
|
181
185
|
},
|
|
182
186
|
"backlog:stalled": {
|
|
183
187
|
script: "scripts/backlog/backlog-stalled-cli.ts",
|
|
184
|
-
// A stall sends one Telegram warning
|
|
188
|
+
// A stall sends one Telegram warning. The `Stop` hook calls the detector
|
|
185
189
|
// directly, so this flag costs only the manual command its in-process dispatch.
|
|
186
190
|
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
187
191
|
description: "Report whether ready backlog work is sitting undispatched with a free lane and no recent dispatch",
|
|
@@ -276,7 +280,7 @@ var ISSUE_COMMANDS = {
|
|
|
276
280
|
},
|
|
277
281
|
"defect:rate": {
|
|
278
282
|
script: "scripts/issue/defect-rate-cli.ts",
|
|
279
|
-
description: "Print the defect rate of merged work: defects filed per
|
|
283
|
+
description: "Print the defect rate of merged work: defects filed per enhancement completed",
|
|
280
284
|
category: "AI tools",
|
|
281
285
|
reference: ["[--days <n>]", "automation", ["network"]]
|
|
282
286
|
},
|
|
@@ -306,10 +310,10 @@ var ISSUE_COMMANDS = {
|
|
|
306
310
|
},
|
|
307
311
|
"issue:file": {
|
|
308
312
|
script: "scripts/issue/issue-file-cli.ts",
|
|
309
|
-
description: "File an Issue with every filing step: lint, Origin, WIP cap, duplicate scout, labels, then epic:bundle",
|
|
313
|
+
description: "File an Issue with every filing step: lint, Origin, fold, WIP cap, duplicate scout, labels, then epic:bundle",
|
|
310
314
|
category: "AI tools",
|
|
311
315
|
reference: [
|
|
312
|
-
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok] [--release]",
|
|
316
|
+
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok] [--requested] [--release]",
|
|
313
317
|
"automation",
|
|
314
318
|
["network"]
|
|
315
319
|
]
|
|
@@ -386,18 +390,27 @@ var LANE_COMMANDS = {
|
|
|
386
390
|
category: "AI tools",
|
|
387
391
|
reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
|
|
388
392
|
},
|
|
389
|
-
//
|
|
393
|
+
// A live run's lane limit: `.env` is read so the bare form reports the
|
|
394
|
+
// `JOSH_LANE_LIMIT` a person set there when no override stands.
|
|
395
|
+
"lane:limit": {
|
|
396
|
+
script: "scripts/lane/lane-limit-cli.ts",
|
|
397
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
398
|
+
description: "Change a live backlogrun\u2019s lane limit without stopping it, or print the limit, lanes in use and free lanes",
|
|
399
|
+
category: "AI tools",
|
|
400
|
+
reference: ["[<limit>] [--reset]", "developer", ["files"]]
|
|
401
|
+
},
|
|
402
|
+
// The lane-limit measurement: `.env` is read so `lane:stats` labels the row
|
|
390
403
|
// with the `JOSH_LANE_LIMIT` a person set there.
|
|
391
404
|
"lane:sample": {
|
|
392
405
|
...MEASURE_ARGUMENTS,
|
|
393
|
-
description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger",
|
|
406
|
+
description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger \u2014 a backlogrun samples itself, this is for a reading outside one",
|
|
394
407
|
category: "AI tools",
|
|
395
408
|
reference: ["[--every <seconds>]", "maintainer", ["files"]],
|
|
396
409
|
default_script_arguments: ["sample"]
|
|
397
410
|
},
|
|
398
411
|
"lane:stats": {
|
|
399
412
|
...MEASURE_ARGUMENTS,
|
|
400
|
-
description: "Print one table row of lane throughput, gate duration and machine load over a period",
|
|
413
|
+
description: "Print one table row of lane throughput, gate duration and machine load over a period, and the per-stage durations of a lane under it",
|
|
401
414
|
category: "AI tools",
|
|
402
415
|
reference: ["--period <days> [--limit <lane-limit>]", "maintainer", ["none"]],
|
|
403
416
|
default_script_arguments: ["stats"]
|
|
@@ -429,12 +442,18 @@ var RUN_COMMANDS = {
|
|
|
429
442
|
"run:carry": {
|
|
430
443
|
script: "scripts/run/carry/run-carry-cli.ts",
|
|
431
444
|
// `--stopped` sends the stop confirmation, so the Telegram credentials come from `.env` as for
|
|
432
|
-
// `run:wake` below
|
|
445
|
+
// `run:wake` below.
|
|
433
446
|
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
434
447
|
description: "Carry one invocation\u2019s budget across its own session cuts",
|
|
435
448
|
category: "AI tools",
|
|
436
449
|
reference: ["<operation> [arguments...]", "automation", ["files"]]
|
|
437
450
|
},
|
|
451
|
+
"run:add": {
|
|
452
|
+
script: "scripts/run/add/run-add-cli.ts",
|
|
453
|
+
description: "Add issues to a live backlogrun, ahead of the queue unless --no-priority",
|
|
454
|
+
category: "AI tools",
|
|
455
|
+
reference: ["<issue...> [--no-priority]", "automation", ["network", "files"]]
|
|
456
|
+
},
|
|
438
457
|
"run:wake": {
|
|
439
458
|
script: "scripts/run/wake/run-wake-cli.ts",
|
|
440
459
|
// `.env` rather than the ambient environment:
|
|
@@ -473,18 +492,26 @@ var RUN_COMMANDS = {
|
|
|
473
492
|
["files"]
|
|
474
493
|
]
|
|
475
494
|
},
|
|
495
|
+
"run:board": {
|
|
496
|
+
script: "scripts/run/board/run-board-cli.ts",
|
|
497
|
+
// `--every` pushes its frame as a Telegram, so the credentials come from `.env` as for `run:carry`.
|
|
498
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
499
|
+
description: "Draw a live board of the running backlogrun, redrawn every second",
|
|
500
|
+
category: "AI tools",
|
|
501
|
+
reference: ["[--once | --chat | --every <minutes>]", "automation", ["files", "network"]]
|
|
502
|
+
},
|
|
476
503
|
"run:prep": {
|
|
477
504
|
script: "scripts/run/run-prep-cli.ts",
|
|
478
505
|
description: "Bundle a run\u2019s pre-edit reads: body, comments, state, dependency scope",
|
|
479
506
|
category: "AI tools",
|
|
480
507
|
reference: ["<issue>", "automation", ["network"]]
|
|
481
508
|
},
|
|
482
|
-
// The entry sequence a lane opened on, folded into one call
|
|
509
|
+
// The entry sequence a lane opened on, folded into one call: claim the tree,
|
|
483
510
|
// read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
|
|
484
511
|
// `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
|
|
485
512
|
"run:entry": {
|
|
486
513
|
script: "scripts/run/entry/run-entry-cli.ts",
|
|
487
|
-
// A `busy` hold or an `over` budget sends the stop confirmation
|
|
514
|
+
// A `busy` hold or an `over` budget sends the stop confirmation.
|
|
488
515
|
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
489
516
|
description: "Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step",
|
|
490
517
|
category: "AI tools",
|
|
@@ -587,12 +614,12 @@ var AI_COMMANDS = {
|
|
|
587
614
|
reference: ["[options]", "maintainer", ["none"]],
|
|
588
615
|
// Kit-only: it measures kit's own development runs and its report modules live under the
|
|
589
616
|
// undistributed `scripts/time/`, so it means nothing in a consumer project and is dropped from a
|
|
590
|
-
// consumer's help
|
|
617
|
+
// consumer's help. The runtime analysis hooks and guards rely on stays
|
|
591
618
|
// distributed under `scripts/time-runtime/`.
|
|
592
619
|
is_kit_only: true
|
|
593
620
|
},
|
|
594
621
|
// The tool-calls-per-round-trip density the batching guard is measured on, aggregated across the
|
|
595
|
-
// recent lane sessions
|
|
622
|
+
// recent lane sessions. Kit-only for the same reason `time` is: it reads
|
|
596
623
|
// kit's own lane transcripts and means nothing in a consumer project.
|
|
597
624
|
"time:density": {
|
|
598
625
|
script: "scripts/time/time-density-cli.ts",
|
|
@@ -608,7 +635,7 @@ var AI_COMMANDS = {
|
|
|
608
635
|
reference: ["", "maintainer", ["none"]],
|
|
609
636
|
// Kit-only: it reads kit's own development run — the transcript store, the review ledger and the
|
|
610
637
|
// run event stream — so it means nothing in a consumer project and is dropped from a consumer's
|
|
611
|
-
// help
|
|
638
|
+
// help, through the same declaration `josh time` uses for the same reason.
|
|
612
639
|
is_kit_only: true
|
|
613
640
|
},
|
|
614
641
|
"review:brief": {
|
|
@@ -660,7 +687,7 @@ var AI_COMMANDS = {
|
|
|
660
687
|
category: "AI tools",
|
|
661
688
|
reference: ["[--join]", "automation", ["processes", "files"]]
|
|
662
689
|
},
|
|
663
|
-
// The post-merge sequence a run closed on, folded into one call
|
|
690
|
+
// The post-merge sequence a run closed on, folded into one call: commit the
|
|
664
691
|
// observation ledger, read the completion citations and decide the release scope. `observations:flush`,
|
|
665
692
|
// `issue:cite` and `release:scope` were three round trips re-billing the run's full context each.
|
|
666
693
|
"run:tail": {
|
|
@@ -669,7 +696,7 @@ var AI_COMMANDS = {
|
|
|
669
696
|
category: "AI tools",
|
|
670
697
|
reference: ["[<issue> ...]", "automation", ["git", "network"]]
|
|
671
698
|
},
|
|
672
|
-
// The commit-to-report region a run ships a change on, folded into one call
|
|
699
|
+
// The commit-to-report region a run ships a change on, folded into one call:
|
|
673
700
|
// the gate, the commit/push/PR (`git -y`), the CI-wait merge (`followup`) and the report bookkeeping
|
|
674
701
|
// (`run:tail`) were four round trips re-billing the run's full context each. It stops at the first
|
|
675
702
|
// failed step and names it, so the run reads only the step to fix.
|
|
@@ -729,7 +756,7 @@ var AI_COMMANDS = {
|
|
|
729
756
|
category: "AI tools",
|
|
730
757
|
reference: ["[scenario...]", "maintainer", ["processes", "network"]],
|
|
731
758
|
// Kit-only: it replays kit's own distributed rules against real Claude sessions, so it means
|
|
732
|
-
// nothing in a consumer project and is dropped from a consumer's help
|
|
759
|
+
// nothing in a consumer project and is dropped from a consumer's help.
|
|
733
760
|
is_kit_only: true
|
|
734
761
|
}
|
|
735
762
|
};
|
|
@@ -745,186 +772,15 @@ var CLONE_COMMANDS = {
|
|
|
745
772
|
};
|
|
746
773
|
|
|
747
774
|
// scripts/gate/core-budget.ts
|
|
748
|
-
import { randomUUID
|
|
775
|
+
import { randomUUID } from "node:crypto";
|
|
749
776
|
import { readdirSync as readdirSync2 } from "node:fs";
|
|
750
777
|
import { availableParallelism as availableParallelism3 } from "node:os";
|
|
751
|
-
import
|
|
752
|
-
|
|
753
|
-
// scripts/josh/process-identity.ts
|
|
754
|
-
import { execFileSync, spawnSync } from "node:child_process";
|
|
755
|
-
import { randomUUID } from "node:crypto";
|
|
756
|
-
import { readFileSync, rmSync } from "node:fs";
|
|
757
|
-
import { createServer } from "node:net";
|
|
758
|
-
import path from "node:path";
|
|
759
|
-
var PS_COMMAND = "/bin/ps";
|
|
760
|
-
var FORMAT_FLAG = "-o";
|
|
761
|
-
var START_TIME_FORMAT = "lstart=";
|
|
762
|
-
var PID_FLAG = "-p";
|
|
763
|
-
var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
|
|
764
|
-
var LIVENESS_SIGNAL = 0;
|
|
765
|
-
var LOWEST_REAL_PID = 1;
|
|
766
|
-
var PROC_START_FIELD_INDEX = 19;
|
|
767
|
-
var BEACON_SCHEME = "socket:";
|
|
768
|
-
var BEACON_SUFFIX = ".sock";
|
|
769
|
-
var BEACON_PREFIX = `josh-process-identity-${String(process.getuid?.() ?? "")}-`;
|
|
770
|
-
var BEACON_ID_LENGTH = 36;
|
|
771
|
-
var BEACON_ID_PATTERN = /^[\da-f-]+$/u;
|
|
772
|
-
var WINDOWS_PLATFORM = "win32";
|
|
773
|
-
var SOCKET_PROBE_SOURCE = "const net=require('node:net');const socket=net.createConnection(process.argv[1]);socket.once('connect',()=>process.exit(0));socket.once('error',()=>process.exit(1));socket.setTimeout(1000,()=>process.exit(1));";
|
|
774
|
-
var beacons = /* @__PURE__ */ new Map();
|
|
775
|
-
var exit_cleanup = { is_registered: false };
|
|
776
|
-
function is_live_pid(pid) {
|
|
777
|
-
if (pid < LOWEST_REAL_PID) return false;
|
|
778
|
-
try {
|
|
779
|
-
process.kill(pid, LIVENESS_SIGNAL);
|
|
780
|
-
return true;
|
|
781
|
-
} catch {
|
|
782
|
-
return false;
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
function read_proc_start(pid) {
|
|
786
|
-
try {
|
|
787
|
-
const stat = readFileSync(`/proc/${String(pid)}/stat`, "utf8");
|
|
788
|
-
const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
|
|
789
|
-
const start = fields[PROC_START_FIELD_INDEX];
|
|
790
|
-
return start === void 0 ? void 0 : `proc:${start}`;
|
|
791
|
-
} catch {
|
|
792
|
-
return void 0;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
function read_ps_start(pid) {
|
|
796
|
-
try {
|
|
797
|
-
const printed = execFileSync(
|
|
798
|
-
PS_COMMAND,
|
|
799
|
-
[FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
|
|
800
|
-
{
|
|
801
|
-
encoding: "utf8",
|
|
802
|
-
timeout: PROBE_TIMEOUT_MS,
|
|
803
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
804
|
-
env: PROBE_ENVIRONMENT
|
|
805
|
-
}
|
|
806
|
-
).trim();
|
|
807
|
-
return printed.length > 0 ? printed : void 0;
|
|
808
|
-
} catch {
|
|
809
|
-
return void 0;
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
var START_PROBES = { read_proc_start, read_ps_start };
|
|
813
|
-
function safe_probe(probe, pid) {
|
|
814
|
-
try {
|
|
815
|
-
return probe(pid);
|
|
816
|
-
} catch {
|
|
817
|
-
return void 0;
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
function read_start(pid, probes = START_PROBES) {
|
|
821
|
-
return safe_probe(probes.read_proc_start, pid) ?? safe_probe(probes.read_ps_start, pid);
|
|
822
|
-
}
|
|
823
|
-
function close_beacon(token) {
|
|
824
|
-
const server = beacons.get(token);
|
|
825
|
-
if (server === void 0) return;
|
|
826
|
-
beacons.delete(token);
|
|
827
|
-
server.close();
|
|
828
|
-
rmSync(token.slice(BEACON_SCHEME.length), { force: true });
|
|
829
|
-
}
|
|
830
|
-
function close_beacons() {
|
|
831
|
-
for (const token of beacons.keys()) close_beacon(token);
|
|
832
|
-
}
|
|
833
|
-
function ensure_exit_cleanup() {
|
|
834
|
-
if (exit_cleanup.is_registered) return;
|
|
835
|
-
exit_cleanup.is_registered = true;
|
|
836
|
-
process.once("exit", close_beacons);
|
|
837
|
-
}
|
|
838
|
-
function ignore_beacon_error() {
|
|
839
|
-
}
|
|
840
|
-
function bind_beacon(target) {
|
|
841
|
-
return createServer().on("error", ignore_beacon_error).listen(target);
|
|
842
|
-
}
|
|
843
|
-
function try_bind_beacon(bind, target) {
|
|
844
|
-
try {
|
|
845
|
-
const server = bind(target);
|
|
846
|
-
return server.listening ? server : void 0;
|
|
847
|
-
} catch {
|
|
848
|
-
return void 0;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
function open_beacon(bind = bind_beacon) {
|
|
852
|
-
const target = path.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
|
|
853
|
-
const token = `${BEACON_SCHEME}${target}`;
|
|
854
|
-
const server = try_bind_beacon(bind, target);
|
|
855
|
-
if (server === void 0) return void 0;
|
|
856
|
-
server.unref();
|
|
857
|
-
beacons.set(token, server);
|
|
858
|
-
ensure_exit_cleanup();
|
|
859
|
-
return token;
|
|
860
|
-
}
|
|
861
|
-
function resolve_own_start(probes = START_PROBES, platform = process.platform) {
|
|
862
|
-
const start = read_start(process.pid, probes);
|
|
863
|
-
if (start !== void 0 || platform === WINDOWS_PLATFORM) return start;
|
|
864
|
-
return open_beacon();
|
|
865
|
-
}
|
|
866
|
-
function is_valid_beacon_name(name) {
|
|
867
|
-
if (!name.startsWith(BEACON_PREFIX) || !name.endsWith(BEACON_SUFFIX)) return false;
|
|
868
|
-
const id = name.slice(BEACON_PREFIX.length, -BEACON_SUFFIX.length);
|
|
869
|
-
return id.length === BEACON_ID_LENGTH && BEACON_ID_PATTERN.test(id);
|
|
870
|
-
}
|
|
871
|
-
function beacon_target(token) {
|
|
872
|
-
if (!token.startsWith(BEACON_SCHEME)) return void 0;
|
|
873
|
-
const target = token.slice(BEACON_SCHEME.length);
|
|
874
|
-
if (path.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
|
|
875
|
-
return is_valid_beacon_name(path.basename(target)) ? target : void 0;
|
|
876
|
-
}
|
|
877
|
-
function is_live_beacon(target) {
|
|
878
|
-
return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
|
|
879
|
-
stdio: "ignore",
|
|
880
|
-
timeout: PROBE_TIMEOUT_MS
|
|
881
|
-
}).status === 0;
|
|
882
|
-
}
|
|
883
|
-
function has_matching_start(pid, recorded_start, read) {
|
|
884
|
-
const observed = read(pid);
|
|
885
|
-
return observed === void 0 ? void 0 : observed === recorded_start;
|
|
886
|
-
}
|
|
887
|
-
function matches_recorded_start(pid, recorded_start, read) {
|
|
888
|
-
const target = beacon_target(recorded_start);
|
|
889
|
-
return target === void 0 ? has_matching_start(pid, recorded_start, read) : is_live_beacon(target);
|
|
890
|
-
}
|
|
891
|
-
var own_probe = /* @__PURE__ */ new Map();
|
|
892
|
-
function own_start() {
|
|
893
|
-
if (!own_probe.has(process.pid)) own_probe.set(process.pid, resolve_own_start());
|
|
894
|
-
return own_probe.get(process.pid);
|
|
895
|
-
}
|
|
896
|
-
function own_fields() {
|
|
897
|
-
const start = own_start();
|
|
898
|
-
return { pid: process.pid, ...start !== void 0 && { process_start: start } };
|
|
899
|
-
}
|
|
900
|
-
function is_same_process(pid, recorded_start, read = read_start) {
|
|
901
|
-
if (pid === void 0 || !is_live_pid(pid)) return false;
|
|
902
|
-
if (recorded_start === void 0) return void 0;
|
|
903
|
-
return matches_recorded_start(pid, recorded_start, read);
|
|
904
|
-
}
|
|
905
|
-
function is_own_process(pid, recorded_start) {
|
|
906
|
-
return pid === process.pid && recorded_start === own_start();
|
|
907
|
-
}
|
|
908
|
-
var process_identity = {
|
|
909
|
-
close_beacon,
|
|
910
|
-
is_live_pid,
|
|
911
|
-
is_own_process,
|
|
912
|
-
is_same_process,
|
|
913
|
-
open_beacon,
|
|
914
|
-
own_fields,
|
|
915
|
-
own_start,
|
|
916
|
-
read_start,
|
|
917
|
-
resolve_own_start
|
|
918
|
-
};
|
|
919
|
-
|
|
920
|
-
// scripts/josh/process-owner.ts
|
|
921
|
-
import { z as z2 } from "zod";
|
|
922
|
-
var process_owner_schema = z2.object({ pid: z2.number(), process_start: z2.string().optional() });
|
|
778
|
+
import path2 from "node:path";
|
|
923
779
|
|
|
924
780
|
// scripts/test/unit-worker-share.ts
|
|
925
781
|
import { readdirSync } from "node:fs";
|
|
926
782
|
import { availableParallelism } from "node:os";
|
|
927
|
-
import
|
|
783
|
+
import path from "node:path";
|
|
928
784
|
var RUN_PREFIX = "josh-unit-running-";
|
|
929
785
|
var WORKER_FLAG = "--maxWorkers";
|
|
930
786
|
var WORKER_FLAGS = [WORKER_FLAG, "--max-workers"];
|
|
@@ -963,7 +819,7 @@ function is_marker_live(source) {
|
|
|
963
819
|
return false;
|
|
964
820
|
}
|
|
965
821
|
function live_run_count(directory = PLATFORM_TEMP_ROOT) {
|
|
966
|
-
return marker_files(directory).filter((name) => is_marker_live(
|
|
822
|
+
return marker_files(directory).filter((name) => is_marker_live(path.join(directory, name))).length;
|
|
967
823
|
}
|
|
968
824
|
var NESTED_KEY = "JOSH_UNIT_RUN_MARKED";
|
|
969
825
|
var NESTED_VALUE = "1";
|
|
@@ -986,22 +842,22 @@ function worker_arguments(vitest_arguments, share) {
|
|
|
986
842
|
if (vitest_arguments.some((argument) => is_worker_flag(argument))) return [];
|
|
987
843
|
return [`${WORKER_FLAG}=${String(share)}`];
|
|
988
844
|
}
|
|
989
|
-
function mark_run_started(
|
|
845
|
+
function mark_run_started(target2) {
|
|
990
846
|
try {
|
|
991
|
-
stamp_file.write_stamp(
|
|
847
|
+
stamp_file.write_stamp(target2, process_identity.own_fields());
|
|
992
848
|
} catch {
|
|
993
849
|
}
|
|
994
850
|
}
|
|
995
851
|
async function with_run_marker(run) {
|
|
996
852
|
if (is_nested_run()) return await run();
|
|
997
|
-
const
|
|
998
|
-
mark_run_started(
|
|
853
|
+
const target2 = marker_path();
|
|
854
|
+
mark_run_started(target2);
|
|
999
855
|
process.env[NESTED_KEY] = NESTED_VALUE;
|
|
1000
856
|
try {
|
|
1001
857
|
return await run();
|
|
1002
858
|
} finally {
|
|
1003
859
|
process.env[NESTED_KEY] = "";
|
|
1004
|
-
stamp_file.remove_stamp(
|
|
860
|
+
stamp_file.remove_stamp(target2);
|
|
1005
861
|
}
|
|
1006
862
|
}
|
|
1007
863
|
var unit_worker_share = {
|
|
@@ -1021,7 +877,7 @@ var unit_worker_share = {
|
|
|
1021
877
|
};
|
|
1022
878
|
|
|
1023
879
|
// scripts/gate/core-budget.ts
|
|
1024
|
-
import { z as
|
|
880
|
+
import { z as z2 } from "zod";
|
|
1025
881
|
|
|
1026
882
|
// scripts/gate/core-admission.ts
|
|
1027
883
|
var MS_PER_SECOND = 1e3;
|
|
@@ -1104,9 +960,18 @@ var BYTES_PER_MB = 1048576;
|
|
|
1104
960
|
var KB_PER_MB = 1024;
|
|
1105
961
|
var PERCENT = 100;
|
|
1106
962
|
var MEMINFO_PATH = "/proc/meminfo";
|
|
963
|
+
var VMSTAT_PATH = "/proc/vmstat";
|
|
1107
964
|
var LINUX_AVAILABLE = /^MemAvailable:\s+(?<kb>\d+) kB/mu;
|
|
1108
|
-
var
|
|
1109
|
-
var
|
|
965
|
+
var LINUX_SWAP_IN = /^pswpin (?<pages>\d+)$/mu;
|
|
966
|
+
var LINUX_SWAP_OUT = /^pswpout (?<pages>\d+)$/mu;
|
|
967
|
+
var PAGE_SIZE_ARGUMENTS = ["PAGESIZE"];
|
|
968
|
+
var LEVEL_NAME = "kern.memorystatus_level";
|
|
969
|
+
var SWAP_IN_NAME = "vm.compressor.swapper.swapins_total";
|
|
970
|
+
var SWAP_OUT_NAME = "vm.compressor.swapper.swapouts_total";
|
|
971
|
+
var PAGE_SIZE_NAME = "hw.pagesize";
|
|
972
|
+
var PRESSURE_NAME = "kern.memorystatus_vm_pressure_level";
|
|
973
|
+
var SYSCTL_ARGUMENTS = [LEVEL_NAME, SWAP_IN_NAME, SWAP_OUT_NAME, PAGE_SIZE_NAME, PRESSURE_NAME];
|
|
974
|
+
var SYSCTL_LINE = /^(?<name>[\w.]+): (?<value>\d+)$/gmu;
|
|
1110
975
|
function cpu_times() {
|
|
1111
976
|
let busy = 0;
|
|
1112
977
|
let idle = 0;
|
|
@@ -1116,31 +981,96 @@ function cpu_times() {
|
|
|
1116
981
|
}
|
|
1117
982
|
return { busy, total: busy + idle };
|
|
1118
983
|
}
|
|
1119
|
-
function
|
|
984
|
+
function busy_share_between(before, after) {
|
|
1120
985
|
const total = after.total - before.total;
|
|
1121
986
|
if (total <= 0) return void 0;
|
|
1122
|
-
return (after.busy - before.busy) / total
|
|
987
|
+
return (after.busy - before.busy) / total;
|
|
988
|
+
}
|
|
989
|
+
function busy_cores_between(before, after, cores) {
|
|
990
|
+
const share = busy_share_between(before, after);
|
|
991
|
+
return share === void 0 ? void 0 : share * cores;
|
|
992
|
+
}
|
|
993
|
+
function sysctl_values(output) {
|
|
994
|
+
const values = [...output.matchAll(SYSCTL_LINE)].map(
|
|
995
|
+
(match) => [match.groups?.["name"] ?? "", Number(match.groups?.["value"])]
|
|
996
|
+
);
|
|
997
|
+
return new Map(values);
|
|
998
|
+
}
|
|
999
|
+
function swapped_pages(pages_in, pages_out) {
|
|
1000
|
+
return pages_in === void 0 || pages_out === void 0 ? void 0 : pages_in + pages_out;
|
|
1001
|
+
}
|
|
1002
|
+
function swapped_mb(pages, page_bytes) {
|
|
1003
|
+
if (pages === void 0 || page_bytes === void 0) return void 0;
|
|
1004
|
+
return pages * page_bytes / BYTES_PER_MB;
|
|
1123
1005
|
}
|
|
1124
|
-
function
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1006
|
+
function swapped_between(from, to) {
|
|
1007
|
+
if (from === void 0 || to === void 0) return void 0;
|
|
1008
|
+
return Math.max(0, to - from);
|
|
1009
|
+
}
|
|
1010
|
+
function parse_darwin_memory(output, total_bytes) {
|
|
1011
|
+
const values = sysctl_values(output);
|
|
1012
|
+
const level = values.get(LEVEL_NAME);
|
|
1013
|
+
return {
|
|
1014
|
+
available_mb: level === void 0 ? void 0 : level / PERCENT * (total_bytes / BYTES_PER_MB),
|
|
1015
|
+
swapped_mb: swapped_mb(
|
|
1016
|
+
swapped_pages(values.get(SWAP_IN_NAME), values.get(SWAP_OUT_NAME)),
|
|
1017
|
+
values.get(PAGE_SIZE_NAME)
|
|
1018
|
+
),
|
|
1019
|
+
pressure_level: values.get(PRESSURE_NAME)
|
|
1020
|
+
};
|
|
1128
1021
|
}
|
|
1129
1022
|
function parse_linux_available(meminfo) {
|
|
1130
1023
|
const kb = LINUX_AVAILABLE.exec(meminfo)?.groups?.["kb"];
|
|
1131
1024
|
return kb === void 0 ? void 0 : Number(kb) / KB_PER_MB;
|
|
1132
1025
|
}
|
|
1133
|
-
|
|
1026
|
+
function pages_of(pattern, vmstat) {
|
|
1027
|
+
const pages = pattern.exec(vmstat)?.groups?.["pages"];
|
|
1028
|
+
return pages === void 0 ? void 0 : Number(pages);
|
|
1029
|
+
}
|
|
1030
|
+
function parse_linux_swapped(vmstat, page_bytes) {
|
|
1031
|
+
const pages = swapped_pages(pages_of(LINUX_SWAP_IN, vmstat), pages_of(LINUX_SWAP_OUT, vmstat));
|
|
1032
|
+
return swapped_mb(pages, page_bytes);
|
|
1033
|
+
}
|
|
1034
|
+
async function settled(read) {
|
|
1134
1035
|
try {
|
|
1135
|
-
|
|
1136
|
-
const { stdout } = await execa("sysctl", PRESSURE_ARGUMENTS);
|
|
1137
|
-
return parse_darwin_pressure(stdout, totalmem());
|
|
1138
|
-
}
|
|
1139
|
-
return platform === "linux" ? parse_linux_available(await readFile(MEMINFO_PATH, "utf8")) : void 0;
|
|
1036
|
+
return await read();
|
|
1140
1037
|
} catch {
|
|
1141
1038
|
return void 0;
|
|
1142
1039
|
}
|
|
1143
1040
|
}
|
|
1041
|
+
async function read_darwin_memory() {
|
|
1042
|
+
const { stdout } = await execa("sysctl", SYSCTL_ARGUMENTS, {
|
|
1043
|
+
reject: false,
|
|
1044
|
+
timeout: PROBE_TIMEOUT_MS
|
|
1045
|
+
});
|
|
1046
|
+
return parse_darwin_memory(stdout, totalmem());
|
|
1047
|
+
}
|
|
1048
|
+
async function read_page_size() {
|
|
1049
|
+
const { stdout } = await execa("getconf", PAGE_SIZE_ARGUMENTS, { timeout: PROBE_TIMEOUT_MS });
|
|
1050
|
+
return stdout;
|
|
1051
|
+
}
|
|
1052
|
+
async function read_linux_memory() {
|
|
1053
|
+
const [meminfo, vmstat, page_size] = await Promise.all([
|
|
1054
|
+
settled(async () => await readFile(MEMINFO_PATH, "utf8")),
|
|
1055
|
+
settled(async () => await readFile(VMSTAT_PATH, "utf8")),
|
|
1056
|
+
settled(read_page_size)
|
|
1057
|
+
]);
|
|
1058
|
+
const page_bytes = page_size === void 0 ? void 0 : Number(page_size);
|
|
1059
|
+
return {
|
|
1060
|
+
available_mb: meminfo === void 0 ? void 0 : parse_linux_available(meminfo),
|
|
1061
|
+
swapped_mb: vmstat === void 0 || page_bytes === void 0 ? void 0 : parse_linux_swapped(vmstat, page_bytes),
|
|
1062
|
+
pressure_level: void 0
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
var UNREAD_MEMORY = {
|
|
1066
|
+
available_mb: void 0,
|
|
1067
|
+
swapped_mb: void 0,
|
|
1068
|
+
pressure_level: void 0
|
|
1069
|
+
};
|
|
1070
|
+
async function read_memory() {
|
|
1071
|
+
if (process.platform === "darwin") return await settled(read_darwin_memory) ?? UNREAD_MEMORY;
|
|
1072
|
+
return process.platform === "linux" ? await read_linux_memory() : UNREAD_MEMORY;
|
|
1073
|
+
}
|
|
1144
1074
|
function is_unquoted() {
|
|
1145
1075
|
return cpus().length > 0 && cpus().length === availableParallelism2();
|
|
1146
1076
|
}
|
|
@@ -1151,9 +1081,12 @@ async function default_sleep(ms) {
|
|
|
1151
1081
|
}
|
|
1152
1082
|
async function read_machine(sleep = default_sleep) {
|
|
1153
1083
|
const before = cpu_times();
|
|
1154
|
-
const [
|
|
1084
|
+
const [memory] = await Promise.all([read_memory(), sleep(SAMPLE_WINDOW_MS)]);
|
|
1155
1085
|
const busy_cores = is_unquoted() ? busy_cores_between(before, cpu_times(), cpus().length) : void 0;
|
|
1156
|
-
return { busy_cores, available_mb };
|
|
1086
|
+
return { busy_cores, available_mb: memory.available_mb };
|
|
1087
|
+
}
|
|
1088
|
+
async function read_sample() {
|
|
1089
|
+
return { cpu: cpu_times(), memory: await read_memory(), total_mb: totalmem() / BYTES_PER_MB };
|
|
1157
1090
|
}
|
|
1158
1091
|
function external_cores(busy_cores, ledger_cores) {
|
|
1159
1092
|
if (busy_cores === void 0) return 0;
|
|
@@ -1168,10 +1101,16 @@ function machine_budget(cores, reading, ledger) {
|
|
|
1168
1101
|
var machine_capacity = {
|
|
1169
1102
|
BASELINE_CORES,
|
|
1170
1103
|
busy_cores_between,
|
|
1104
|
+
busy_share_between,
|
|
1105
|
+
external_cores,
|
|
1171
1106
|
machine_budget,
|
|
1172
|
-
|
|
1107
|
+
parse_darwin_memory,
|
|
1173
1108
|
parse_linux_available,
|
|
1174
|
-
|
|
1109
|
+
parse_linux_swapped,
|
|
1110
|
+
read_machine,
|
|
1111
|
+
read_memory,
|
|
1112
|
+
read_sample,
|
|
1113
|
+
swapped_between
|
|
1175
1114
|
};
|
|
1176
1115
|
|
|
1177
1116
|
// scripts/gate/core-budget.ts
|
|
@@ -1196,10 +1135,10 @@ var MEMORY_MB = {
|
|
|
1196
1135
|
var HELD_KEY = "JOSH_CORE_RESERVED";
|
|
1197
1136
|
var HELD_VALUE = "1";
|
|
1198
1137
|
var reservation_schema = process_owner_schema.extend({
|
|
1199
|
-
weight:
|
|
1200
|
-
claimed_at:
|
|
1201
|
-
memory_mb:
|
|
1202
|
-
admitted_at:
|
|
1138
|
+
weight: z2.number(),
|
|
1139
|
+
claimed_at: z2.number(),
|
|
1140
|
+
memory_mb: z2.number().optional(),
|
|
1141
|
+
admitted_at: z2.number().optional()
|
|
1203
1142
|
});
|
|
1204
1143
|
function marker_name(key) {
|
|
1205
1144
|
return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`;
|
|
@@ -1210,12 +1149,7 @@ function is_running2(reservation) {
|
|
|
1210
1149
|
function read_reservation(source) {
|
|
1211
1150
|
const raw = stamp_file.read_stamp_text(source);
|
|
1212
1151
|
if (raw === void 0) return void 0;
|
|
1213
|
-
|
|
1214
|
-
const parsed = reservation_schema.safeParse(JSON.parse(raw));
|
|
1215
|
-
return parsed.success ? parsed.data : void 0;
|
|
1216
|
-
} catch {
|
|
1217
|
-
return void 0;
|
|
1218
|
-
}
|
|
1152
|
+
return json_value.parse_with(raw, reservation_schema);
|
|
1219
1153
|
}
|
|
1220
1154
|
function sweep_marker2(source) {
|
|
1221
1155
|
try {
|
|
@@ -1241,7 +1175,7 @@ function marker_files2(directory) {
|
|
|
1241
1175
|
}
|
|
1242
1176
|
function live_reservations(directory = PLATFORM_TEMP_ROOT) {
|
|
1243
1177
|
return marker_files2(directory).flatMap((name) => {
|
|
1244
|
-
const reservation = live_reservation(
|
|
1178
|
+
const reservation = live_reservation(path2.join(directory, name));
|
|
1245
1179
|
return reservation === void 0 ? [] : { key: name, reservation };
|
|
1246
1180
|
});
|
|
1247
1181
|
}
|
|
@@ -1253,8 +1187,8 @@ async function default_sleep2(ms) {
|
|
|
1253
1187
|
setTimeout(resolve, ms);
|
|
1254
1188
|
});
|
|
1255
1189
|
}
|
|
1256
|
-
function write_reservation(
|
|
1257
|
-
stamp_file.replace_stamp(
|
|
1190
|
+
function write_reservation(target2, fields) {
|
|
1191
|
+
stamp_file.replace_stamp(target2, { ...process_identity.own_fields(), ...fields });
|
|
1258
1192
|
}
|
|
1259
1193
|
function resolve_timing(options) {
|
|
1260
1194
|
return {
|
|
@@ -1303,21 +1237,21 @@ async function reserve(weight, options = {}) {
|
|
|
1303
1237
|
const timing = resolve_timing(options);
|
|
1304
1238
|
const directory = options.directory ?? PLATFORM_TEMP_ROOT;
|
|
1305
1239
|
const claimed_at = timing.now();
|
|
1306
|
-
const name = marker_name(
|
|
1307
|
-
const
|
|
1240
|
+
const name = marker_name(randomUUID());
|
|
1241
|
+
const target2 = path2.join(directory, name);
|
|
1308
1242
|
const fields = { weight, claimed_at, memory_mb: options.memory_mb };
|
|
1309
|
-
write_reservation(
|
|
1243
|
+
write_reservation(target2, fields);
|
|
1310
1244
|
const admission = await await_admission({
|
|
1311
1245
|
...timing,
|
|
1312
1246
|
key: name,
|
|
1313
|
-
target,
|
|
1247
|
+
target: target2,
|
|
1314
1248
|
directory,
|
|
1315
1249
|
budget: normalize_budget(options.budget ?? availableParallelism3()),
|
|
1316
1250
|
deadline: claimed_at + timing.wait_cap_ms,
|
|
1317
1251
|
fields,
|
|
1318
1252
|
read_machine: options.read_machine ?? machine_capacity.read_machine
|
|
1319
1253
|
});
|
|
1320
|
-
return { target, admission };
|
|
1254
|
+
return { target: target2, admission };
|
|
1321
1255
|
}
|
|
1322
1256
|
function release(handle) {
|
|
1323
1257
|
sweep_marker2(handle.target);
|
|
@@ -1416,6 +1350,7 @@ var LINT_LABEL = "lint";
|
|
|
1416
1350
|
var TYPE_CHECK_LABEL = "check";
|
|
1417
1351
|
var UNIT_LABEL = "test:unit";
|
|
1418
1352
|
var BEHAVIOR_LABEL = "behavior";
|
|
1353
|
+
var METRICS_LABEL = "metrics";
|
|
1419
1354
|
var WARNING_CHECKER_LABELS = [LINT_LABEL, TYPE_CHECK_LABEL];
|
|
1420
1355
|
var STATIC_CHECKS = [
|
|
1421
1356
|
{
|
|
@@ -1437,18 +1372,31 @@ var STATIC_CHECKS = [
|
|
|
1437
1372
|
memory_mb: core_budget.MEMORY_MB.spell_check
|
|
1438
1373
|
},
|
|
1439
1374
|
{ label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
|
|
1440
|
-
// **The unused-member check reserves no core
|
|
1375
|
+
// **The unused-member check reserves no core**: it builds one TypeScript
|
|
1441
1376
|
// program and walks it for about 5s, and it is over well before lint and the type check. A
|
|
1442
1377
|
// reservation would only take a place from the four-core CI runner's fan-out and a worker from the
|
|
1443
1378
|
// unit suite for the whole gate.
|
|
1444
|
-
{ label: "exports", target: "exports:unused", reserved_cores: 0 }
|
|
1379
|
+
{ label: "exports", target: "exports:unused", reserved_cores: 0 },
|
|
1380
|
+
// **The metrics ratchet is kit's own**: it holds kit's repository-wide
|
|
1381
|
+
// totals to the merge-base's. It is one in-process eslint pass with only `max-lines` enabled, over
|
|
1382
|
+
// in a few seconds, so it reserves no core for the reason the unused-member check above does not.
|
|
1383
|
+
// It times no startup here: beside the unit suite that reads the load, not josh.
|
|
1384
|
+
{
|
|
1385
|
+
label: METRICS_LABEL,
|
|
1386
|
+
target: METRICS_LABEL,
|
|
1387
|
+
args: ["--no-startup"],
|
|
1388
|
+
reserved_cores: 0,
|
|
1389
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan,
|
|
1390
|
+
is_kit_only: true
|
|
1391
|
+
}
|
|
1445
1392
|
];
|
|
1446
1393
|
var GATE_CHECKS = [
|
|
1447
1394
|
...STATIC_CHECKS,
|
|
1448
1395
|
{ label: UNIT_LABEL, target: UNIT_LABEL, reserved_cores: 0 }
|
|
1449
1396
|
];
|
|
1450
|
-
function select_gate_checks(is_unit_included) {
|
|
1451
|
-
|
|
1397
|
+
function select_gate_checks(is_unit_included, is_kit_repository = true) {
|
|
1398
|
+
const checks = is_unit_included ? GATE_CHECKS : STATIC_CHECKS;
|
|
1399
|
+
return is_kit_repository ? checks : checks.filter((check) => check.is_kit_only !== true);
|
|
1452
1400
|
}
|
|
1453
1401
|
function has_unit_check(checks) {
|
|
1454
1402
|
return checks.some((check) => check.label === UNIT_LABEL);
|
|
@@ -1502,15 +1450,19 @@ function direct_unit_weight(available_cores = availableParallelism4(), live_runs
|
|
|
1502
1450
|
function direct_unit_memory() {
|
|
1503
1451
|
return unit_memory(direct_unit_weight());
|
|
1504
1452
|
}
|
|
1453
|
+
function unit_cap_for(checks, available_cores, concurrent_runs) {
|
|
1454
|
+
if (!has_unit_check(checks)) return void 0;
|
|
1455
|
+
return resolve_unit_worker_cap(available_cores, concurrent_runs);
|
|
1456
|
+
}
|
|
1505
1457
|
function plan_of(concurrency, unit_worker_cap, checks = GATE_CHECKS) {
|
|
1506
1458
|
return { checks, concurrency, unit_worker_cap };
|
|
1507
1459
|
}
|
|
1508
|
-
function resolve_gate_plan(available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS, is_unit_included = true) {
|
|
1509
|
-
const checks = select_gate_checks(is_unit_included);
|
|
1460
|
+
function resolve_gate_plan(available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS, is_unit_included = true, is_kit_repository = true) {
|
|
1461
|
+
const checks = select_gate_checks(is_unit_included, is_kit_repository);
|
|
1510
1462
|
return {
|
|
1511
1463
|
checks,
|
|
1512
1464
|
concurrency: resolve_concurrency(available_cores, concurrent_runs, checks),
|
|
1513
|
-
unit_worker_cap:
|
|
1465
|
+
unit_worker_cap: unit_cap_for(checks, available_cores, concurrent_runs)
|
|
1514
1466
|
};
|
|
1515
1467
|
}
|
|
1516
1468
|
function format_machine(available_cores, concurrent_runs) {
|
|
@@ -1534,6 +1486,7 @@ var gate_plan = {
|
|
|
1534
1486
|
GATE_CHECKS,
|
|
1535
1487
|
LINT_LABEL,
|
|
1536
1488
|
MEASURED_CORES,
|
|
1489
|
+
METRICS_LABEL,
|
|
1537
1490
|
RESERVED_CORES,
|
|
1538
1491
|
STATIC_CHECKS,
|
|
1539
1492
|
TYPE_CHECK_LABEL,
|
|
@@ -1596,6 +1549,19 @@ var DEV_COMMANDS = {
|
|
|
1596
1549
|
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1597
1550
|
memory_mb: core_budget.MEMORY_MB.eslint_scan
|
|
1598
1551
|
},
|
|
1552
|
+
metrics: {
|
|
1553
|
+
script: "scripts/metrics/metrics-command.ts",
|
|
1554
|
+
description: "Print repository-wide quality totals and durations, and fail when a total grew past the merge-base or a duration past its baseline",
|
|
1555
|
+
category: "Development",
|
|
1556
|
+
reference: [
|
|
1557
|
+
'[--no-startup | --totals-only | --accept --reason "<why>"]',
|
|
1558
|
+
"developer",
|
|
1559
|
+
["files"]
|
|
1560
|
+
],
|
|
1561
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1562
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan,
|
|
1563
|
+
is_kit_only: true
|
|
1564
|
+
},
|
|
1599
1565
|
"refactor:scan": {
|
|
1600
1566
|
script: "scripts/refactor/refactor-scan-cli.ts",
|
|
1601
1567
|
description: "List refactoring candidates in the changed scope by category and answer clear/candidates",
|
|
@@ -1616,6 +1582,12 @@ var DEV_COMMANDS = {
|
|
|
1616
1582
|
category: "AI tools",
|
|
1617
1583
|
reference: ["[--refresh]", "developer", ["files"]]
|
|
1618
1584
|
},
|
|
1585
|
+
"rule:list": {
|
|
1586
|
+
script: "scripts/rules/rule-list.ts",
|
|
1587
|
+
description: "Print the trigger-delivered rules \u2014 each one's source, firing call and silent turn \u2014 from the guard rows",
|
|
1588
|
+
category: "AI tools",
|
|
1589
|
+
reference: ["", "automation", ["none"]]
|
|
1590
|
+
},
|
|
1619
1591
|
format: {
|
|
1620
1592
|
script: "scripts/lint/format.ts",
|
|
1621
1593
|
description: "Format code with prettier and eslint (skips a tool a basic project lacks)",
|
|
@@ -1636,8 +1608,8 @@ var DEV_COMMANDS = {
|
|
|
1636
1608
|
// **No `tsx_arguments`, deliberately.** `JOSH_BATCH_GUARD` is a per-machine preference kept in
|
|
1637
1609
|
// `.env`, which every other command reads through `OPTIONAL_ENV_FILE_FLAGS` — but declaring any
|
|
1638
1610
|
// `tsx_arguments` disqualifies a command from in-process dispatch (`josh-in-process.ts`), and
|
|
1639
|
-
// this one runs before every `Bash` call
|
|
1640
|
-
//
|
|
1611
|
+
// this one runs before every `Bash` call, where a second ~0.16 s tsx start is not affordable.
|
|
1612
|
+
// The script calls `process.loadEnvFile` itself instead, which is
|
|
1641
1613
|
// node's own `--env-file` parser with node's own precedence.
|
|
1642
1614
|
},
|
|
1643
1615
|
"pretool:guard": {
|
|
@@ -1661,7 +1633,7 @@ var DEV_COMMANDS = {
|
|
|
1661
1633
|
},
|
|
1662
1634
|
"session:lang": {
|
|
1663
1635
|
script: "scripts/josh/session-language-cli.ts",
|
|
1664
|
-
description: "Claude Code hook: print
|
|
1636
|
+
description: "Claude Code hook: print a non-default JOSH_SESSION_LANG for the session context, and the run:board reply rule while a backlogrun is live (otherwise nothing)",
|
|
1665
1637
|
category: "Development",
|
|
1666
1638
|
reference: ["", "automation", ["none"]]
|
|
1667
1639
|
// **No `tsx_arguments`, deliberately**, the same as `batch:guard` above: this runs on every
|
|
@@ -1674,7 +1646,7 @@ var DEV_COMMANDS = {
|
|
|
1674
1646
|
category: "Development",
|
|
1675
1647
|
reference: ["<pretool|posttool>", "automation", ["none"]]
|
|
1676
1648
|
// The live-source fallback `scripts/hooks/run-hook.sh` derives from the `codex-hook-adapter`
|
|
1677
|
-
// bundle name
|
|
1649
|
+
// bundle name. **No `tsx_arguments`**, the same as `pretool:guard`
|
|
1678
1650
|
// above: it runs before every guarded Codex call.
|
|
1679
1651
|
},
|
|
1680
1652
|
"cspell:dot": {
|
|
@@ -2028,16 +2000,16 @@ var VERSIONING_COMMANDS = {
|
|
|
2028
2000
|
category: "Versioning",
|
|
2029
2001
|
reference: ["", "developer", ["network"]]
|
|
2030
2002
|
},
|
|
2031
|
-
// The one place that decides a version
|
|
2003
|
+
// The one place that decides a version. A `script` entry for the same
|
|
2032
2004
|
// reason `ranges` is one: script paths resolve against the kit package root, so it keeps working
|
|
2033
2005
|
// from a consumer repository where the file lives under node_modules.
|
|
2034
2006
|
release: {
|
|
2035
2007
|
script: "scripts/release/release-cli.ts",
|
|
2036
2008
|
description: "Release the merges main has taken since the version last changed",
|
|
2037
2009
|
category: "Versioning",
|
|
2038
|
-
reference: ["[
|
|
2010
|
+
reference: ["[--dry-run]", "maintainer", ["git", "network", "release"]]
|
|
2039
2011
|
},
|
|
2040
|
-
// The read-only half of the one above
|
|
2012
|
+
// The read-only half of the one above. `release --dry-run` cannot
|
|
2041
2013
|
// answer this question: it refuses off the default branch and on a dirty tree, which is every
|
|
2042
2014
|
// position a run asks it from. A `script` entry for the same reason `release` is one.
|
|
2043
2015
|
"release:scope": {
|
|
@@ -2046,8 +2018,8 @@ var VERSIONING_COMMANDS = {
|
|
|
2046
2018
|
category: "Versioning",
|
|
2047
2019
|
reference: ["[--json]", "automation", ["none"]]
|
|
2048
2020
|
},
|
|
2049
|
-
// Run by the release workflows, kit's and the one sync distributes, after a tag has published
|
|
2050
|
-
//
|
|
2021
|
+
// Run by the release workflows, kit's and the one sync distributes, after a tag has published.
|
|
2022
|
+
// Settings come from the environment, so the workflow decides them.
|
|
2051
2023
|
"release:github": {
|
|
2052
2024
|
script: "scripts/release/github-release-cli.ts",
|
|
2053
2025
|
description: "Create the GitHub Release for a published tag, with generated notes",
|
|
@@ -2075,20 +2047,17 @@ var WORKFLOW_COMMANDS = {
|
|
|
2075
2047
|
reference: ["<message>", "developer", ["network"]],
|
|
2076
2048
|
default_script_arguments: ["-y", "--skip-commit", "--skip-push"]
|
|
2077
2049
|
},
|
|
2078
|
-
// **The optional form, on both
|
|
2079
|
-
//
|
|
2080
|
-
//
|
|
2081
|
-
//
|
|
2082
|
-
// session, and `followup` with them the merge step of every `fullrun` there. `doctor` was moved to
|
|
2083
|
-
// this form for the same reason in joshuafolkken/kit#869.
|
|
2050
|
+
// **The optional form, on both**. The mandatory `--env-file=.env` is resolved by node before the
|
|
2051
|
+
// script's first line: on a machine with no `.env` it dies as `.env: not found` with exit code 9,
|
|
2052
|
+
// even where `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` exist as real environment variables — a
|
|
2053
|
+
// cloud session, and `followup` with them the merge step of every `fullrun` there.
|
|
2084
2054
|
//
|
|
2085
2055
|
// Nothing is lost by relaxing it: both scripts already load `.env` through `josh_environment_file`
|
|
2086
2056
|
// themselves, so the file is read either way and node's precedence — an existing environment
|
|
2087
2057
|
// variable wins over the file — is node's own in both spellings.
|
|
2088
2058
|
//
|
|
2089
|
-
// **
|
|
2090
|
-
//
|
|
2091
|
-
// `josh notify` exits non-zero instead of warning and answering 0.
|
|
2059
|
+
// **A missing credential still fails loudly**: `telegram_notify.send` throws on missing credentials
|
|
2060
|
+
// and on a failed send, so `josh notify` exits non-zero instead of warning and answering 0.
|
|
2092
2061
|
followup: {
|
|
2093
2062
|
script: "scripts/followup/git-followup-workflow.ts",
|
|
2094
2063
|
description: "Follow-up git workflow",
|
|
@@ -2104,11 +2073,23 @@ var WORKFLOW_COMMANDS = {
|
|
|
2104
2073
|
script: "scripts/notify/telegram-test.ts",
|
|
2105
2074
|
description: "Send Telegram notification",
|
|
2106
2075
|
category: "Workflow",
|
|
2107
|
-
reference: [
|
|
2076
|
+
reference: [
|
|
2077
|
+
"[--task-type <type>] [--body <text> | --body-file <path>] [--issue-url <url>] [--pr-url <url>] [--issue-title <text>] [--repo-name <name>]",
|
|
2078
|
+
"automation",
|
|
2079
|
+
["notifications"]
|
|
2080
|
+
],
|
|
2108
2081
|
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
|
|
2109
2082
|
},
|
|
2110
|
-
//
|
|
2111
|
-
//
|
|
2083
|
+
// One observation-ledger sighting: the key's count, the append and the second-sighting verdict,
|
|
2084
|
+
// which a run used to type as a `cat | grep -c` and judge by hand.
|
|
2085
|
+
"observation:record": {
|
|
2086
|
+
script: "scripts/observations/observation-record-cli.ts",
|
|
2087
|
+
description: "Record an observation sighting and answer whether it is now filed",
|
|
2088
|
+
category: "Workflow",
|
|
2089
|
+
reference: ["<key> <depth> <where> <what> [--checkout <path>]", "automation", ["files"]]
|
|
2090
|
+
},
|
|
2091
|
+
// The observation ledger's commit path for the lines no run's own commit carried:
|
|
2092
|
+
// a lane's lines sit in the primary checkout, which
|
|
2112
2093
|
// its commit cannot see, and the recurrence count the promotion rule reads is a count of main.
|
|
2113
2094
|
"observations:flush": {
|
|
2114
2095
|
script: "scripts/observations/observations-flush-cli.ts",
|
|
@@ -2116,8 +2097,8 @@ var WORKFLOW_COMMANDS = {
|
|
|
2116
2097
|
category: "Workflow",
|
|
2117
2098
|
reference: ["", "automation", ["git", "network"]]
|
|
2118
2099
|
},
|
|
2119
|
-
// The one write path for a `/code-review` round's findings
|
|
2120
|
-
// `--check` gate `followup` runs before it merges
|
|
2100
|
+
// The one write path for a `/code-review` round's findings, plus the
|
|
2101
|
+
// `--check` gate `followup` runs before it merges. It appends a `- rf:`
|
|
2121
2102
|
// line per finding — or one zero-finding line for a clean round — to the observation ledger, so
|
|
2122
2103
|
// `observations:flush` commits them and the recurrence count survives the run.
|
|
2123
2104
|
"review:record": {
|
|
@@ -2125,12 +2106,12 @@ var WORKFLOW_COMMANDS = {
|
|
|
2125
2106
|
description: "Record a review round\u2019s findings, or check a round was recorded",
|
|
2126
2107
|
category: "Workflow",
|
|
2127
2108
|
reference: [
|
|
2128
|
-
"--issue <N> [<category>:<severity>:<file> ...] | --check --issue <N>",
|
|
2109
|
+
"--issue <N> [--comment] [<category>:<severity>:<file> ...] | --check --issue <N>",
|
|
2129
2110
|
"automation",
|
|
2130
|
-
["files"]
|
|
2111
|
+
["files", "network"]
|
|
2131
2112
|
]
|
|
2132
2113
|
},
|
|
2133
|
-
// The reader over what `review:record` wrote
|
|
2114
|
+
// The reader over what `review:record` wrote: each recurring category’s
|
|
2134
2115
|
// count, and the number of zero-finding rounds that distinguishes a quiet category from an unwatched one.
|
|
2135
2116
|
"review:findings": {
|
|
2136
2117
|
script: "scripts/review/review-findings-cli.ts",
|
|
@@ -2139,7 +2120,7 @@ var WORKFLOW_COMMANDS = {
|
|
|
2139
2120
|
reference: ["", "developer", ["files"]]
|
|
2140
2121
|
},
|
|
2141
2122
|
// After a behavior-change Issue merges, re-run its declared baseline and print before/after; a value
|
|
2142
|
-
// that did not move appends a refuted-premise line to the observation ledger
|
|
2123
|
+
// that did not move appends a refuted-premise line to the observation ledger.
|
|
2143
2124
|
"measure:rerun": {
|
|
2144
2125
|
script: "scripts/issue/measure-rerun-cli.ts",
|
|
2145
2126
|
description: "Re-run a merged issue\u2019s baseline command and print the before/after pair",
|
|
@@ -2147,7 +2128,7 @@ var WORKFLOW_COMMANDS = {
|
|
|
2147
2128
|
reference: ["<issue-number>", "automation", ["network", "processes", "files"]]
|
|
2148
2129
|
},
|
|
2149
2130
|
// A script rather than an `sh -c` chain, because it has a precondition to enforce: run inside a
|
|
2150
|
-
// linked work tree it would hijack the default branch from every other one
|
|
2131
|
+
// linked work tree it would hijack the default branch from every other one.
|
|
2151
2132
|
"main:sync": {
|
|
2152
2133
|
script: "scripts/git/main-sync.ts",
|
|
2153
2134
|
description: "Checkout default branch, pull latest, and prune merged remote-gone branches (refuses inside a lane)",
|
|
@@ -2155,9 +2136,8 @@ var WORKFLOW_COMMANDS = {
|
|
|
2155
2136
|
reference: ["", "developer", ["git", "network"]]
|
|
2156
2137
|
},
|
|
2157
2138
|
// A script rather than an `sh -c` chain, because the strategy has to be named rather than left to
|
|
2158
|
-
// the caller's git configuration:
|
|
2159
|
-
//
|
|
2160
|
-
// (joshuafolkken/kit#1659).
|
|
2139
|
+
// the caller's git configuration: a bare `git pull` aborts with `Need to specify how to reconcile
|
|
2140
|
+
// divergent branches` on exactly the diverged branch the command exists for.
|
|
2161
2141
|
"main:merge": {
|
|
2162
2142
|
script: "scripts/git/main-merge.ts",
|
|
2163
2143
|
description: "Merge origin default branch into the current branch",
|
|
@@ -2184,6 +2164,7 @@ var ALIASES = {
|
|
|
2184
2164
|
lr: "lint:related",
|
|
2185
2165
|
ln: "lines",
|
|
2186
2166
|
by: "bytes",
|
|
2167
|
+
mt: "metrics",
|
|
2187
2168
|
f: "format",
|
|
2188
2169
|
sd: "cspell:dot",
|
|
2189
2170
|
bh: "behavior",
|
|
@@ -2226,7 +2207,9 @@ var ALIASES = {
|
|
|
2226
2207
|
ruv: "rule:value",
|
|
2227
2208
|
ev: "eval",
|
|
2228
2209
|
lsm: "lane:sample",
|
|
2229
|
-
lst: "lane:stats"
|
|
2210
|
+
lst: "lane:stats",
|
|
2211
|
+
lli: "lane:limit",
|
|
2212
|
+
blr: "backlogrun"
|
|
2230
2213
|
};
|
|
2231
2214
|
function canonical_command(name) {
|
|
2232
2215
|
if (!Object.hasOwn(ALIASES, name)) return name;
|
|
@@ -2449,74 +2432,74 @@ var time_background = {
|
|
|
2449
2432
|
};
|
|
2450
2433
|
|
|
2451
2434
|
// scripts/git/git-schemas.ts
|
|
2452
|
-
import { z as
|
|
2453
|
-
var package_name_schema =
|
|
2454
|
-
var rollup_item_schema =
|
|
2435
|
+
import { z as z3 } from "zod";
|
|
2436
|
+
var package_name_schema = z3.object({ name: z3.string().min(1) });
|
|
2437
|
+
var rollup_item_schema = z3.looseObject({
|
|
2455
2438
|
// eslint-disable-next-line @typescript-eslint/naming-convention -- GraphQL field name from GitHub API
|
|
2456
|
-
__typename:
|
|
2457
|
-
state:
|
|
2458
|
-
status:
|
|
2459
|
-
conclusion:
|
|
2460
|
-
name:
|
|
2461
|
-
context:
|
|
2439
|
+
__typename: z3.string().optional(),
|
|
2440
|
+
state: z3.string().optional(),
|
|
2441
|
+
status: z3.string().optional(),
|
|
2442
|
+
conclusion: z3.string().optional(),
|
|
2443
|
+
name: z3.string().optional(),
|
|
2444
|
+
context: z3.string().optional()
|
|
2462
2445
|
});
|
|
2463
|
-
var pr_raw_schema =
|
|
2464
|
-
statusCheckRollup:
|
|
2465
|
-
mergeStateStatus:
|
|
2466
|
-
reviewDecision:
|
|
2446
|
+
var pr_raw_schema = z3.object({
|
|
2447
|
+
statusCheckRollup: z3.array(rollup_item_schema).optional(),
|
|
2448
|
+
mergeStateStatus: z3.string().optional(),
|
|
2449
|
+
reviewDecision: z3.string().optional()
|
|
2467
2450
|
});
|
|
2468
|
-
var pull_comment_schema =
|
|
2469
|
-
body:
|
|
2470
|
-
html_url:
|
|
2471
|
-
user:
|
|
2451
|
+
var pull_comment_schema = z3.object({
|
|
2452
|
+
body: z3.string().optional(),
|
|
2453
|
+
html_url: z3.string().optional(),
|
|
2454
|
+
user: z3.object({ login: z3.string().optional() }).optional()
|
|
2472
2455
|
});
|
|
2473
|
-
var ai_review_pull_comment_schema =
|
|
2474
|
-
body:
|
|
2475
|
-
url:
|
|
2476
|
-
author:
|
|
2456
|
+
var ai_review_pull_comment_schema = z3.object({
|
|
2457
|
+
body: z3.string().optional(),
|
|
2458
|
+
url: z3.string().optional(),
|
|
2459
|
+
author: z3.object({ login: z3.string().optional() }).optional()
|
|
2477
2460
|
});
|
|
2478
|
-
var pr_info_schema =
|
|
2479
|
-
mergeable:
|
|
2480
|
-
mergeStateStatus:
|
|
2481
|
-
state:
|
|
2461
|
+
var pr_info_schema = z3.object({
|
|
2462
|
+
mergeable: z3.union([z3.boolean(), z3.string()]).nullable().optional(),
|
|
2463
|
+
mergeStateStatus: z3.string().nullable().optional(),
|
|
2464
|
+
state: z3.string().optional()
|
|
2482
2465
|
});
|
|
2483
|
-
var epic_issue_schema =
|
|
2484
|
-
number:
|
|
2485
|
-
body:
|
|
2466
|
+
var epic_issue_schema = z3.object({
|
|
2467
|
+
number: z3.number(),
|
|
2468
|
+
body: z3.string().optional()
|
|
2486
2469
|
});
|
|
2487
|
-
var blocking_issue_schema =
|
|
2488
|
-
number:
|
|
2489
|
-
state:
|
|
2490
|
-
repository_url:
|
|
2470
|
+
var blocking_issue_schema = z3.object({
|
|
2471
|
+
number: z3.number(),
|
|
2472
|
+
state: z3.string().optional(),
|
|
2473
|
+
repository_url: z3.string().optional()
|
|
2491
2474
|
});
|
|
2492
|
-
var blocked_by_schema =
|
|
2493
|
-
nodes:
|
|
2494
|
-
totalCount:
|
|
2475
|
+
var blocked_by_schema = z3.object({
|
|
2476
|
+
nodes: z3.array(blocking_issue_schema).default([]),
|
|
2477
|
+
totalCount: z3.number().optional()
|
|
2495
2478
|
}).optional();
|
|
2496
|
-
var epic_child_schema =
|
|
2497
|
-
state:
|
|
2479
|
+
var epic_child_schema = z3.object({
|
|
2480
|
+
state: z3.string().optional(),
|
|
2498
2481
|
blockedBy: blocked_by_schema
|
|
2499
2482
|
});
|
|
2500
|
-
var rest_comment_schema =
|
|
2501
|
-
body:
|
|
2502
|
-
html_url:
|
|
2503
|
-
user:
|
|
2483
|
+
var rest_comment_schema = z3.looseObject({
|
|
2484
|
+
body: z3.string().nullish(),
|
|
2485
|
+
html_url: z3.string().optional(),
|
|
2486
|
+
user: z3.looseObject({ login: z3.string().optional() }).nullish()
|
|
2504
2487
|
});
|
|
2505
|
-
var issue_label_schema =
|
|
2506
|
-
var epic_subject_schema =
|
|
2507
|
-
number:
|
|
2508
|
-
state:
|
|
2509
|
-
labels:
|
|
2510
|
-
body:
|
|
2488
|
+
var issue_label_schema = z3.object({ name: z3.string() });
|
|
2489
|
+
var epic_subject_schema = z3.object({
|
|
2490
|
+
number: z3.number(),
|
|
2491
|
+
state: z3.string().optional(),
|
|
2492
|
+
labels: z3.array(issue_label_schema).optional(),
|
|
2493
|
+
body: z3.string().optional()
|
|
2511
2494
|
});
|
|
2512
|
-
var open_issue_schema =
|
|
2513
|
-
number:
|
|
2514
|
-
title:
|
|
2515
|
-
labels:
|
|
2516
|
-
createdAt:
|
|
2495
|
+
var open_issue_schema = z3.object({
|
|
2496
|
+
number: z3.number(),
|
|
2497
|
+
title: z3.string(),
|
|
2498
|
+
labels: z3.array(issue_label_schema).optional(),
|
|
2499
|
+
createdAt: z3.string(),
|
|
2517
2500
|
blockedBy: blocked_by_schema,
|
|
2518
|
-
// Present only on the pickup listing, which reads it for the
|
|
2519
|
-
body:
|
|
2501
|
+
// Present only on the pickup listing, which reads it for the paths each issue declares.
|
|
2502
|
+
body: z3.string().optional()
|
|
2520
2503
|
});
|
|
2521
2504
|
|
|
2522
2505
|
// scripts/gh/git-pr-checks-parse.ts
|
|
@@ -2692,6 +2675,132 @@ var PrConflictError = class extends Error {
|
|
|
2692
2675
|
name = "PrConflictError";
|
|
2693
2676
|
};
|
|
2694
2677
|
|
|
2678
|
+
// scripts/lane/lane-ledger.ts
|
|
2679
|
+
import { closeSync, constants, openSync, writeSync } from "node:fs";
|
|
2680
|
+
import { z as z4 } from "zod";
|
|
2681
|
+
var LEDGER_PREFIX = "josh-lane-ledger-";
|
|
2682
|
+
var LEDGER_SUFFIX = ".jsonl";
|
|
2683
|
+
var LINE_SEPARATOR = "\n";
|
|
2684
|
+
var CI_WAIT_STAGE = "ci-wait";
|
|
2685
|
+
var LEDGER_FILE_MODE = 384;
|
|
2686
|
+
var { O_APPEND, O_CREAT, O_NOFOLLOW, O_WRONLY } = constants;
|
|
2687
|
+
var APPEND_FLAGS = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW;
|
|
2688
|
+
var KIND = {
|
|
2689
|
+
MERGE: "merge",
|
|
2690
|
+
GATE: "gate",
|
|
2691
|
+
LOAD: "load",
|
|
2692
|
+
DISPATCH: "dispatch",
|
|
2693
|
+
STAGE: "stage"
|
|
2694
|
+
};
|
|
2695
|
+
var merge_schema = z4.object({ kind: z4.literal(KIND.MERGE), at: z4.string(), issue: z4.number() });
|
|
2696
|
+
var gate_schema = z4.object({
|
|
2697
|
+
kind: z4.literal(KIND.GATE),
|
|
2698
|
+
at: z4.string(),
|
|
2699
|
+
elapsed_ms: z4.number(),
|
|
2700
|
+
is_passed: z4.boolean(),
|
|
2701
|
+
// The unit suite's own duration, present when this gate ran it — the one
|
|
2702
|
+
// record of a full vitest run `josh metrics` reads, so the suite is never timed twice.
|
|
2703
|
+
unit_ms: z4.number().optional(),
|
|
2704
|
+
// The whole cores busy outside this gate, beyond the machine's baseline, at its start or its end —
|
|
2705
|
+
// whichever was higher. Absent when the machine could not be read.
|
|
2706
|
+
external_cores: z4.number().optional()
|
|
2707
|
+
});
|
|
2708
|
+
var load_schema = z4.object({
|
|
2709
|
+
kind: z4.literal(KIND.LOAD),
|
|
2710
|
+
at: z4.string(),
|
|
2711
|
+
load: z4.number(),
|
|
2712
|
+
available_mb: z4.number().optional(),
|
|
2713
|
+
swapped_mb: z4.number().optional(),
|
|
2714
|
+
lanes: z4.number().optional()
|
|
2715
|
+
});
|
|
2716
|
+
var dispatch_schema = z4.object({
|
|
2717
|
+
kind: z4.literal(KIND.DISPATCH),
|
|
2718
|
+
at: z4.string(),
|
|
2719
|
+
issue: z4.number()
|
|
2720
|
+
});
|
|
2721
|
+
var stage_schema = z4.object({
|
|
2722
|
+
kind: z4.literal(KIND.STAGE),
|
|
2723
|
+
at: z4.string(),
|
|
2724
|
+
stage: z4.string(),
|
|
2725
|
+
elapsed_ms: z4.number(),
|
|
2726
|
+
issue: z4.number().optional()
|
|
2727
|
+
});
|
|
2728
|
+
var entry_schema = z4.discriminatedUnion("kind", [
|
|
2729
|
+
merge_schema,
|
|
2730
|
+
gate_schema,
|
|
2731
|
+
load_schema,
|
|
2732
|
+
dispatch_schema,
|
|
2733
|
+
stage_schema
|
|
2734
|
+
]);
|
|
2735
|
+
function target_of(repository) {
|
|
2736
|
+
return stamp_file.stamp_path(LEDGER_PREFIX, repository, LEDGER_SUFFIX);
|
|
2737
|
+
}
|
|
2738
|
+
async function target() {
|
|
2739
|
+
if (process.env["VITEST"] !== void 0) return void 0;
|
|
2740
|
+
try {
|
|
2741
|
+
const repository = await run_carry.repository_directory();
|
|
2742
|
+
return repository === void 0 ? void 0 : target_of(repository);
|
|
2743
|
+
} catch {
|
|
2744
|
+
return void 0;
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
function append(path4, entry) {
|
|
2748
|
+
const descriptor = openSync(path4, APPEND_FLAGS, LEDGER_FILE_MODE);
|
|
2749
|
+
try {
|
|
2750
|
+
if (stamp_file.is_own_regular_file(path4)) {
|
|
2751
|
+
writeSync(descriptor, `${JSON.stringify(entry)}${LINE_SEPARATOR}`);
|
|
2752
|
+
}
|
|
2753
|
+
} finally {
|
|
2754
|
+
closeSync(descriptor);
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
async function record(entry, path4) {
|
|
2758
|
+
try {
|
|
2759
|
+
const destination = path4 ?? await target();
|
|
2760
|
+
if (destination !== void 0) append(destination, entry);
|
|
2761
|
+
} catch {
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
function now_iso() {
|
|
2765
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
2766
|
+
}
|
|
2767
|
+
async function record_gate(path4, gate) {
|
|
2768
|
+
await record({ kind: KIND.GATE, at: now_iso(), ...gate }, path4);
|
|
2769
|
+
}
|
|
2770
|
+
async function record_merge(issue) {
|
|
2771
|
+
await record({ kind: KIND.MERGE, at: now_iso(), issue });
|
|
2772
|
+
}
|
|
2773
|
+
async function record_dispatch(issue, path4) {
|
|
2774
|
+
await record({ kind: KIND.DISPATCH, at: now_iso(), issue }, path4);
|
|
2775
|
+
}
|
|
2776
|
+
async function record_stage(stage, path4) {
|
|
2777
|
+
await record({ kind: KIND.STAGE, at: now_iso(), ...stage }, path4);
|
|
2778
|
+
}
|
|
2779
|
+
function parse_line2(line) {
|
|
2780
|
+
return entry_schema.safeParse(json_value.parse_or_undefined(line)).data;
|
|
2781
|
+
}
|
|
2782
|
+
function is_present(entry) {
|
|
2783
|
+
return entry !== void 0;
|
|
2784
|
+
}
|
|
2785
|
+
function read_entries(path4) {
|
|
2786
|
+
const raw = stamp_file.read_stamp_text(path4);
|
|
2787
|
+
if (raw === void 0) return [];
|
|
2788
|
+
return raw.split(LINE_SEPARATOR).map((line) => parse_line2(line.trim())).filter(is_present);
|
|
2789
|
+
}
|
|
2790
|
+
var lane_ledger = {
|
|
2791
|
+
CI_WAIT_STAGE,
|
|
2792
|
+
KIND,
|
|
2793
|
+
append,
|
|
2794
|
+
read_entries,
|
|
2795
|
+
record,
|
|
2796
|
+
record_dispatch,
|
|
2797
|
+
record_gate,
|
|
2798
|
+
record_merge,
|
|
2799
|
+
record_stage,
|
|
2800
|
+
target,
|
|
2801
|
+
target_of
|
|
2802
|
+
};
|
|
2803
|
+
|
|
2695
2804
|
// scripts/time-runtime/time-format.ts
|
|
2696
2805
|
var MS_PER_MINUTE = 6e4;
|
|
2697
2806
|
var MS_PER_SECOND2 = 1e3;
|
|
@@ -2764,8 +2873,8 @@ var STAGE = {
|
|
|
2764
2873
|
// blocker and on a red check, and those are the runs whose wait is longest — reporting nothing for
|
|
2765
2874
|
// them would leave the measurement blind to exactly the invocations worth measuring.
|
|
2766
2875
|
interrupted: "interrupted",
|
|
2767
|
-
// The interrupted lap when the wait failed on a merge conflict
|
|
2768
|
-
// stage block names the cause a resumed session
|
|
2876
|
+
// The interrupted lap when the wait failed on a merge conflict, so the
|
|
2877
|
+
// stage block names the cause a resumed session would otherwise look up with `gh pr view`.
|
|
2769
2878
|
conflict: "conflict"
|
|
2770
2879
|
};
|
|
2771
2880
|
function stopped_lap(error) {
|
|
@@ -2795,6 +2904,14 @@ function format_stages(log) {
|
|
|
2795
2904
|
function print_stages(log) {
|
|
2796
2905
|
for (const line of format_stages(log)) console.info(line);
|
|
2797
2906
|
}
|
|
2907
|
+
async function record_ci_wait(log) {
|
|
2908
|
+
const wait = log.stages.find((stage) => stage.name === STAGE.checks_wait);
|
|
2909
|
+
if (wait === void 0) return;
|
|
2910
|
+
await lane_ledger.record_stage({
|
|
2911
|
+
stage: lane_ledger.CI_WAIT_STAGE,
|
|
2912
|
+
elapsed_ms: wait.duration_ms
|
|
2913
|
+
});
|
|
2914
|
+
}
|
|
2798
2915
|
var git_followup_stages = {
|
|
2799
2916
|
STAGE,
|
|
2800
2917
|
STAGE_LINE_PREFIX,
|
|
@@ -2804,11 +2921,12 @@ var git_followup_stages = {
|
|
|
2804
2921
|
total_ms,
|
|
2805
2922
|
format_stages,
|
|
2806
2923
|
print_stages,
|
|
2924
|
+
record_ci_wait,
|
|
2807
2925
|
stopped_lap
|
|
2808
2926
|
};
|
|
2809
2927
|
|
|
2810
2928
|
// scripts/time-runtime/time-followup-stage.ts
|
|
2811
|
-
var
|
|
2929
|
+
var LINE_SEPARATOR2 = "\n";
|
|
2812
2930
|
var SECONDS_SUFFIX = " s";
|
|
2813
2931
|
var DIGIT_OR_POINT = /[\d.]/u;
|
|
2814
2932
|
var MS_PER_SECOND3 = 1e3;
|
|
@@ -2838,7 +2956,7 @@ function to_stage(body) {
|
|
|
2838
2956
|
}
|
|
2839
2957
|
function read_stages(text) {
|
|
2840
2958
|
if (!text.includes(git_followup_stages.STAGE_LINE_PREFIX)) return NO_STAGES;
|
|
2841
|
-
return text.split(
|
|
2959
|
+
return text.split(LINE_SEPARATOR2).map((line) => stage_body(line)).filter((body) => body !== void 0).map((body) => to_stage(body)).filter((stage) => stage !== void 0);
|
|
2842
2960
|
}
|
|
2843
2961
|
var time_followup_stage = { NO_STAGES, read_stages };
|
|
2844
2962
|
|
|
@@ -2846,7 +2964,7 @@ var time_followup_stage = { NO_STAGES, read_stages };
|
|
|
2846
2964
|
import { z as z5 } from "zod";
|
|
2847
2965
|
var TEXT_BLOCK_SCHEMA = z5.object({ text: z5.string().nullish() });
|
|
2848
2966
|
var CONTENT_SCHEMA = z5.union([z5.string(), z5.array(z5.unknown())]);
|
|
2849
|
-
var
|
|
2967
|
+
var LINE_SEPARATOR3 = "\n";
|
|
2850
2968
|
function block_text(block) {
|
|
2851
2969
|
const parsed = TEXT_BLOCK_SCHEMA.safeParse(block);
|
|
2852
2970
|
return parsed.success ? parsed.data.text ?? "" : "";
|
|
@@ -2855,7 +2973,7 @@ function result_text2(content) {
|
|
|
2855
2973
|
const parsed = CONTENT_SCHEMA.safeParse(content);
|
|
2856
2974
|
if (!parsed.success) return "";
|
|
2857
2975
|
if (typeof parsed.data === "string") return parsed.data;
|
|
2858
|
-
return parsed.data.map((block) => block_text(block)).join(
|
|
2976
|
+
return parsed.data.map((block) => block_text(block)).join(LINE_SEPARATOR3);
|
|
2859
2977
|
}
|
|
2860
2978
|
function is_failure_line(line) {
|
|
2861
2979
|
return line.trimStart().startsWith(status_icons.FAIL_ICON);
|
|
@@ -2907,7 +3025,7 @@ function did_scan_find(scan) {
|
|
|
2907
3025
|
return scan.did_find || scan.has_failure_before_region || scan.has_failure_in_region;
|
|
2908
3026
|
}
|
|
2909
3027
|
function has_failure_line(content) {
|
|
2910
|
-
const lines = result_text2(content).split(
|
|
3028
|
+
const lines = result_text2(content).split(LINE_SEPARATOR3);
|
|
2911
3029
|
if (lines.some((line) => is_failed_verdict(line))) return true;
|
|
2912
3030
|
return did_scan_find(scan_body(lines));
|
|
2913
3031
|
}
|
|
@@ -3128,8 +3246,8 @@ function field_targets(input) {
|
|
|
3128
3246
|
}
|
|
3129
3247
|
function tool_targets(input) {
|
|
3130
3248
|
const scalar_targets = TARGET_FIELDS.map((field) => field_text(input, field));
|
|
3131
|
-
const targets = [...scalar_targets, ...field_targets(input)].map((
|
|
3132
|
-
return [...new Set(targets)].filter((
|
|
3249
|
+
const targets = [...scalar_targets, ...field_targets(input)].map((target2) => normalize(target2));
|
|
3250
|
+
return [...new Set(targets)].filter((target2) => target2 !== "");
|
|
3133
3251
|
}
|
|
3134
3252
|
function prompt_references_prior(input) {
|
|
3135
3253
|
const prompt = field_text(input, "prompt").toLowerCase();
|
|
@@ -3174,27 +3292,27 @@ var time_bundle_call = {
|
|
|
3174
3292
|
bash_facts,
|
|
3175
3293
|
call_facts,
|
|
3176
3294
|
tool_facts,
|
|
3177
|
-
// Exported for `time-agent-bundles.ts
|
|
3295
|
+
// Exported for `time-agent-bundles.ts`, which asks the launch question of a
|
|
3178
3296
|
// span's `label` — the tool name for a non-Bash call — so the set lives in one place.
|
|
3179
3297
|
is_launch_tool,
|
|
3180
|
-
// Exported for `time-writes.ts
|
|
3298
|
+
// Exported for `time-writes.ts`, which asks what a call *wrote* rather
|
|
3181
3299
|
// than what it named. The extraction is the same one either way — a second copy of it would let a
|
|
3182
3300
|
// path be recognized as a target when read and missed when written.
|
|
3183
3301
|
targets_in,
|
|
3184
3302
|
tool_targets,
|
|
3185
|
-
// Exported for the batching guard's own word scan
|
|
3303
|
+
// Exported for the batching guard's own word scan, so the two scanners
|
|
3186
3304
|
// cannot come to disagree about where one word of a shell line ends and the next begins.
|
|
3187
|
-
// Exported for the read-fold notice
|
|
3305
|
+
// Exported for the read-fold notice, which offers `read:files <path>` only
|
|
3188
3306
|
// over file-shaped targets — a bare directory like `scripts/` is a target here but not something
|
|
3189
3307
|
// `read:files` can read, so the notice reuses this test rather than keep a second copy that could
|
|
3190
3308
|
// drift from what counts as a file path.
|
|
3191
3309
|
has_extension,
|
|
3192
|
-
// Exported for `time-writes.ts
|
|
3310
|
+
// Exported for `time-writes.ts`, which needs the same two answers to say
|
|
3193
3311
|
// *which* files an in-place `sed` wrote. Two copies of this test disagreed in both directions at
|
|
3194
3312
|
// once — one called a piped `grep -i` a write, the other missed a bundled `sed -ni`.
|
|
3195
3313
|
write_segment,
|
|
3196
3314
|
is_in_place_sed,
|
|
3197
|
-
// Exported for the drift test in `time-bundle-call.test.ts
|
|
3315
|
+
// Exported for the drift test in `time-bundle-call.test.ts`, which pins that
|
|
3198
3316
|
// every name here is a real `josh` command and none of them writes.
|
|
3199
3317
|
READ_JOSH_SUBCOMMANDS
|
|
3200
3318
|
};
|
|
@@ -3206,9 +3324,9 @@ function issue_from_branch(branch) {
|
|
|
3206
3324
|
const matched = ISSUE_BRANCH_PATTERN.exec(branch);
|
|
3207
3325
|
return matched?.[1] === void 0 ? UNATTRIBUTED_KEY : Number(matched[1]);
|
|
3208
3326
|
}
|
|
3209
|
-
function declared_issue(
|
|
3210
|
-
const declared =
|
|
3211
|
-
return declared === UNATTRIBUTED_KEY ? issue_from_branch(
|
|
3327
|
+
function declared_issue(record2) {
|
|
3328
|
+
const declared = record2.issue ?? UNATTRIBUTED_KEY;
|
|
3329
|
+
return declared === UNATTRIBUTED_KEY ? issue_from_branch(record2.branch) : declared;
|
|
3212
3330
|
}
|
|
3213
3331
|
function fill(declared, is_reverse) {
|
|
3214
3332
|
const filled = Array.from({ length: declared.length }, () => UNATTRIBUTED_KEY);
|
|
@@ -3232,12 +3350,12 @@ function pick(own, carried, next, previous) {
|
|
|
3232
3350
|
}
|
|
3233
3351
|
function announcements(records) {
|
|
3234
3352
|
return fill(
|
|
3235
|
-
records.map((
|
|
3353
|
+
records.map((record2) => record2.issue ?? UNATTRIBUTED_KEY),
|
|
3236
3354
|
false
|
|
3237
3355
|
);
|
|
3238
3356
|
}
|
|
3239
3357
|
function attribute(records) {
|
|
3240
|
-
const declared = records.map((
|
|
3358
|
+
const declared = records.map((record2) => declared_issue(record2));
|
|
3241
3359
|
const carried = announcements(records);
|
|
3242
3360
|
const next = fill(declared, true);
|
|
3243
3361
|
const previous = fill(declared, false);
|
|
@@ -3248,9 +3366,9 @@ function attribute(records) {
|
|
|
3248
3366
|
function group_by_issue(records) {
|
|
3249
3367
|
const issues = attribute(records);
|
|
3250
3368
|
const grouped = /* @__PURE__ */ new Map();
|
|
3251
|
-
for (const [index,
|
|
3369
|
+
for (const [index, record2] of records.entries()) {
|
|
3252
3370
|
const bucket = grouped.get(issues[index] ?? UNATTRIBUTED_KEY) ?? [];
|
|
3253
|
-
bucket.push(
|
|
3371
|
+
bucket.push(record2);
|
|
3254
3372
|
grouped.set(issues[index] ?? UNATTRIBUTED_KEY, bucket);
|
|
3255
3373
|
}
|
|
3256
3374
|
return [...grouped].toSorted(([left], [right]) => left - right).map(([issue, bucket]) => ({ issue, records: bucket }));
|
|
@@ -3379,28 +3497,18 @@ var time_single_check = { NO_CHECK, check_key };
|
|
|
3379
3497
|
|
|
3380
3498
|
// scripts/time-runtime/time-transcript-line.ts
|
|
3381
3499
|
import { z as z6 } from "zod";
|
|
3382
|
-
|
|
3383
|
-
// scripts/time-runtime/time-instant.ts
|
|
3384
|
-
function parse_instant(raw) {
|
|
3385
|
-
if (raw === null || raw === void 0) return void 0;
|
|
3386
|
-
const parsed = Date.parse(raw);
|
|
3387
|
-
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
3388
|
-
}
|
|
3389
|
-
var time_instant = { parse_instant };
|
|
3390
|
-
|
|
3391
|
-
// scripts/time-runtime/time-transcript-line.ts
|
|
3392
3500
|
var BLOCK_SCHEMA2 = z6.object({
|
|
3393
3501
|
type: z6.string().nullish(),
|
|
3394
3502
|
name: z6.string().nullish(),
|
|
3395
3503
|
id: z6.string().nullish(),
|
|
3396
3504
|
tool_use_id: z6.string().nullish(),
|
|
3397
3505
|
input: z6.unknown().nullish(),
|
|
3398
|
-
// Whether the harness wrote this result back as a failure
|
|
3506
|
+
// Whether the harness wrote this result back as a failure. Present on a
|
|
3399
3507
|
// `tool_result` block and on nothing else, and absent even there for the tools that never report
|
|
3400
3508
|
// one — which is why it is read as three answers rather than as a boolean with a default.
|
|
3401
3509
|
is_error: z6.boolean().nullish(),
|
|
3402
|
-
// What the call printed. Read only to recover the outcome a pipeline threw away
|
|
3403
|
-
//
|
|
3510
|
+
// What the call printed. Read only to recover the outcome a pipeline threw away:
|
|
3511
|
+
// it is kept as flattened text rather than as blocks, because that is
|
|
3404
3512
|
// the whole of what `time-reported-failure.ts` asks of it.
|
|
3405
3513
|
content: z6.unknown().nullish()
|
|
3406
3514
|
});
|
|
@@ -3411,10 +3519,10 @@ var LINE_SCHEMA = z6.object({
|
|
|
3411
3519
|
timestamp: z6.string().nullish(),
|
|
3412
3520
|
// The branch the line was written on, which is where the issue number lives — `josh git` names a
|
|
3413
3521
|
// branch `<N>-<slug>`. Read here rather than re-parsed by a second reader so `josh time --issue`
|
|
3414
|
-
// and `josh cost --issue` answer from the same field
|
|
3522
|
+
// and `josh cost --issue` answer from the same field.
|
|
3415
3523
|
gitBranch: z6.string().nullish(),
|
|
3416
|
-
// The two fields outside `message` that the harness writes an end-of-task notice on
|
|
3417
|
-
//
|
|
3524
|
+
// The two fields outside `message` that the harness writes an end-of-task notice on.
|
|
3525
|
+
// **Both are read as `unknown` rather than as strings**: a schema
|
|
3418
3526
|
// insisting on a string here would reject every line whose `content` is a list of blocks — which is
|
|
3419
3527
|
// most of them — and a rejected line is dropped from the timeline entirely, so the shares would stop
|
|
3420
3528
|
// reconstructing the elapsed time. The shape is checked at the read below instead.
|
|
@@ -3428,6 +3536,7 @@ var NO_MESSAGE_ID = "";
|
|
|
3428
3536
|
var ERROR_TEXT_LIMIT = 256;
|
|
3429
3537
|
var REFUSAL_MARKER = "\u26D4";
|
|
3430
3538
|
var HOOK_ERROR_LABEL = /^PreToolUse:\S+ hook error: /u;
|
|
3539
|
+
var STOP_FEEDBACK_LABEL = /^Stop hook feedback:\s*/u;
|
|
3431
3540
|
var TOKEN_LINE = /^[a-z][a-z-]*$/u;
|
|
3432
3541
|
var TOKEN_LINE_LIMIT = 8;
|
|
3433
3542
|
function block_names(raw) {
|
|
@@ -3445,6 +3554,11 @@ function guard_from_refusal(text) {
|
|
|
3445
3554
|
const colon = headline.indexOf(":");
|
|
3446
3555
|
return (colon === -1 ? headline : headline.slice(0, colon)).trim();
|
|
3447
3556
|
}
|
|
3557
|
+
function stop_guard_of(data) {
|
|
3558
|
+
const content = data.message?.content;
|
|
3559
|
+
if (typeof content !== "string" || !STOP_FEEDBACK_LABEL.test(content)) return "";
|
|
3560
|
+
return guard_from_refusal(content.replace(STOP_FEEDBACK_LABEL, ""));
|
|
3561
|
+
}
|
|
3448
3562
|
function token_lines_of(text) {
|
|
3449
3563
|
return text.split("\n").map((line) => line.trim()).filter((line) => TOKEN_LINE.test(line)).slice(0, TOKEN_LINE_LIMIT);
|
|
3450
3564
|
}
|
|
@@ -3483,19 +3597,24 @@ function to_line(data) {
|
|
|
3483
3597
|
timestamp_ms,
|
|
3484
3598
|
branch: data.gitBranch ?? UNKNOWN_BRANCH,
|
|
3485
3599
|
finished_background: time_background.finished_id(notice_text(data)),
|
|
3600
|
+
stop_guard: stop_guard_of(data),
|
|
3486
3601
|
...message_fields(data.message)
|
|
3487
3602
|
};
|
|
3488
3603
|
}
|
|
3489
|
-
function
|
|
3604
|
+
function parse_line3(line) {
|
|
3490
3605
|
const parsed = LINE_SCHEMA.safeParse(json_value.parse_or_undefined(line));
|
|
3491
3606
|
return parsed.success ? to_line(parsed.data) : void 0;
|
|
3492
3607
|
}
|
|
3608
|
+
function parse_text(text) {
|
|
3609
|
+
return text.split("\n").flatMap((line) => parse_line3(line) ?? []);
|
|
3610
|
+
}
|
|
3493
3611
|
var time_transcript_line = {
|
|
3494
3612
|
ERROR_TEXT_LIMIT,
|
|
3495
3613
|
NO_MESSAGE_ID,
|
|
3496
3614
|
TOKEN_LINE_LIMIT,
|
|
3497
3615
|
guard_from_refusal,
|
|
3498
|
-
parse_line:
|
|
3616
|
+
parse_line: parse_line3,
|
|
3617
|
+
parse_text
|
|
3499
3618
|
};
|
|
3500
3619
|
|
|
3501
3620
|
// scripts/time-runtime/time-writes.ts
|
|
@@ -3584,7 +3703,7 @@ var time_tool_call = {
|
|
|
3584
3703
|
};
|
|
3585
3704
|
|
|
3586
3705
|
// scripts/time-runtime/time-spans.ts
|
|
3587
|
-
var { NO_MESSAGE_ID: NO_MESSAGE_ID3, parse_line:
|
|
3706
|
+
var { NO_MESSAGE_ID: NO_MESSAGE_ID3, parse_line: parse_line4 } = time_transcript_line;
|
|
3588
3707
|
var { NO_CALL: NO_CALL2, UNKNOWN_CALL: UNKNOWN_CALL2, UNKNOWN_TOOL: UNKNOWN_TOOL2, to_tool_call: to_tool_call2 } = time_tool_call;
|
|
3589
3708
|
var ASSISTANT_TYPE = "assistant";
|
|
3590
3709
|
var USER_TYPE = "user";
|
|
@@ -3704,12 +3823,12 @@ function to_spans(events, finished) {
|
|
|
3704
3823
|
}));
|
|
3705
3824
|
}
|
|
3706
3825
|
function parse_timeline(text) {
|
|
3707
|
-
const lines = text.split("\n").map((line) =>
|
|
3826
|
+
const lines = text.split("\n").map((line) => parse_line4(line)).filter((line) => line !== void 0);
|
|
3708
3827
|
const events = to_events(lines, collect_calls(lines));
|
|
3709
3828
|
return {
|
|
3710
3829
|
started_ms: events[0]?.timestamp_ms ?? 0,
|
|
3711
3830
|
ended_ms: events.at(-1)?.timestamp_ms ?? 0,
|
|
3712
|
-
// **The positioning happens here rather than in a caller
|
|
3831
|
+
// **The positioning happens here rather than in a caller**: a launch and
|
|
3713
3832
|
// the call that reads its output are in one transcript, and by the time spans have been merged
|
|
3714
3833
|
// across sessions and trimmed they are fragments rather than calls.
|
|
3715
3834
|
spans: time_background.positioned(to_spans(events, time_background.finished_at(lines)))
|
|
@@ -3732,12 +3851,12 @@ var time_spans = {
|
|
|
3732
3851
|
equal_durations,
|
|
3733
3852
|
no_background,
|
|
3734
3853
|
// Re-exported so the suites that measure how a command is read keep asking one namespace, and so
|
|
3735
|
-
// `time-shell.ts` moving out of this file changed no call site
|
|
3854
|
+
// `time-shell.ts` moving out of this file changed no call site.
|
|
3736
3855
|
bash_label: time_shell.bash_label,
|
|
3737
3856
|
josh_command_of: time_shell.josh_command_of,
|
|
3738
3857
|
josh_commands_of: time_shell.josh_commands_of,
|
|
3739
3858
|
to_tool_call: to_tool_call2,
|
|
3740
|
-
parse_line:
|
|
3859
|
+
parse_line: parse_line4,
|
|
3741
3860
|
parse_timeline
|
|
3742
3861
|
};
|
|
3743
3862
|
|
|
@@ -3830,23 +3949,21 @@ var time_round_trips = {
|
|
|
3830
3949
|
CALLS_PER_ROUND_TRIP_FLOOR,
|
|
3831
3950
|
count_calls,
|
|
3832
3951
|
count_round_trips,
|
|
3833
|
-
// Exported
|
|
3834
|
-
//
|
|
3952
|
+
// Exported so a turn is defined in the one module that already defines a round trip rather than
|
|
3953
|
+
// as a span filter in the report next door.
|
|
3835
3954
|
count_turns,
|
|
3836
3955
|
format_density,
|
|
3837
|
-
// Exported
|
|
3838
|
-
//
|
|
3956
|
+
// Exported so the per-tool counts are read off the very groups this module counts rather than off
|
|
3957
|
+
// a second grouping beside them.
|
|
3839
3958
|
group_round_trips,
|
|
3840
|
-
// Exported
|
|
3959
|
+
// Exported so the failure aggregation orders a run's spans through
|
|
3841
3960
|
// the one function that already knows why they need it — a second `toSorted` beside it would be
|
|
3842
3961
|
// the clone `CLAUDE.md` prohibits, and the seam it guards (a delegated unit's spans appended
|
|
3843
3962
|
// after the parent's) is not one a second copy would keep remembering.
|
|
3844
3963
|
in_time_order,
|
|
3845
3964
|
is_below_floor,
|
|
3846
|
-
//
|
|
3847
|
-
//
|
|
3848
|
-
// private copy there would be the clone `CLAUDE.md` prohibits, in the one place a drift would have
|
|
3849
|
-
// the distribution and the count disagreeing about what a round trip is.
|
|
3965
|
+
// Exported so callers price a round trip with the same divisor and guard rather than a private
|
|
3966
|
+
// copy — the clone `CLAUDE.md` prohibits.
|
|
3850
3967
|
per_round_trip
|
|
3851
3968
|
};
|
|
3852
3969
|
|
|
@@ -3986,9 +4103,9 @@ function tally_for(tallies, label) {
|
|
|
3986
4103
|
return created;
|
|
3987
4104
|
}
|
|
3988
4105
|
function count_trip(tallies, counted, label) {
|
|
3989
|
-
const
|
|
3990
|
-
|
|
3991
|
-
if (!counted.has(label))
|
|
4106
|
+
const tally = tally_for(tallies, label);
|
|
4107
|
+
tally.recoverable_round_trips += ONE_CALL;
|
|
4108
|
+
if (!counted.has(label)) tally.sequence_count += ONE_CALL;
|
|
3992
4109
|
counted.add(label);
|
|
3993
4110
|
}
|
|
3994
4111
|
function tally_sequence(tallies, sequence) {
|
|
@@ -4006,7 +4123,7 @@ function by_weight(left, right) {
|
|
|
4006
4123
|
function tool_rows(closed) {
|
|
4007
4124
|
const tallies = /* @__PURE__ */ new Map();
|
|
4008
4125
|
for (const sequence of closed) tally_sequence(tallies, sequence);
|
|
4009
|
-
return [...tallies].map(([label,
|
|
4126
|
+
return [...tallies].map(([label, tally]) => ({ label, ...tally })).toSorted(by_weight);
|
|
4010
4127
|
}
|
|
4011
4128
|
function attributed_of(rows) {
|
|
4012
4129
|
return rows.reduce((sum, row) => sum + row.recoverable_round_trips, NONE3);
|
|
@@ -4140,9 +4257,11 @@ var NONE4 = 0;
|
|
|
4140
4257
|
var NOTICE_REFIRE_EVERY = ONE_TURN;
|
|
4141
4258
|
var NAMED_CANDIDATE_COUNT = 3;
|
|
4142
4259
|
var SEQUENCE_BEFORE_LIMIT = CONSECUTIVE_LIMIT - ONE_TURN;
|
|
4143
|
-
var
|
|
4144
|
-
var
|
|
4145
|
-
var
|
|
4260
|
+
var RULE_POINTER = "`prompts/collaboration-workflow/turn-batching.md`";
|
|
4261
|
+
var STREAK = `${String(CONSECUTIVE_LIMIT)} single-call turns in a row`;
|
|
4262
|
+
var REASON = `\u26D4 batching: ${STREAK}. Reissue this with the calls that do not need its result \u2014 the test is whether a call's input needs another call's result, not what kind of call it is (edits are covered exactly as reads), and it never authorizes weakening a verification gate or a review. Already batching, or nothing to pair? Reissue it unchanged; this fires once per streak. ${RULE_POINTER}`;
|
|
4263
|
+
var NOTICE = `\u{1F4A1} batching: ${STREAK}; the Write proceeds. Issue the writes that do not need its result in one turn, never by weakening a gate or a review. ${RULE_POINTER}`;
|
|
4264
|
+
var LANE_NOTICE = `\u{1F4A1} batching: ${STREAK}; the call proceeds. Pair independent calls. ${RULE_POINTER}`;
|
|
4146
4265
|
var WHOLE_FILE_WRITE_TOOL = "Write";
|
|
4147
4266
|
var EDIT_TOOL = "Edit";
|
|
4148
4267
|
function is_guarded_call(call) {
|
|
@@ -4199,13 +4318,13 @@ function should_notify(text, call, notified_at_ms) {
|
|
|
4199
4318
|
return is_at_limit(spans, call, notified_at_ms, NOTICE_REFIRE_EVERY);
|
|
4200
4319
|
}
|
|
4201
4320
|
function describe_span(span) {
|
|
4202
|
-
const
|
|
4203
|
-
if (
|
|
4204
|
-
return `${span.label} ${
|
|
4321
|
+
const target2 = span.targets[0] ?? "";
|
|
4322
|
+
if (target2 === "" || span.label.includes(target2)) return span.label;
|
|
4323
|
+
return `${span.label} ${target2}`;
|
|
4205
4324
|
}
|
|
4206
4325
|
var FOLD_MINIMUM = 2;
|
|
4207
4326
|
function read_targets(sequence) {
|
|
4208
|
-
const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((
|
|
4327
|
+
const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((path4) => path4 !== "" && time_bundle_call.has_extension(path4));
|
|
4209
4328
|
return [...new Set(paths)];
|
|
4210
4329
|
}
|
|
4211
4330
|
function read_fold_directive(sequence) {
|
|
@@ -4214,7 +4333,7 @@ function read_fold_directive(sequence) {
|
|
|
4214
4333
|
return ` Fold them into one call: \`pnpm josh read:files ${paths.join(" ")}\`.`;
|
|
4215
4334
|
}
|
|
4216
4335
|
function write_targets(sequence) {
|
|
4217
|
-
const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((
|
|
4336
|
+
const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((path4) => path4 !== "" && time_bundle_call.has_extension(path4));
|
|
4218
4337
|
return [...new Set(paths)];
|
|
4219
4338
|
}
|
|
4220
4339
|
function write_fold_directive(sequence) {
|
|
@@ -4266,455 +4385,22 @@ var time_batch_guard = {
|
|
|
4266
4385
|
};
|
|
4267
4386
|
|
|
4268
4387
|
// scripts/time-runtime/time-hook-transcript.ts
|
|
4269
|
-
import
|
|
4270
|
-
|
|
4271
|
-
// scripts/cost-runtime/cost-transcript.ts
|
|
4272
|
-
import { readdirSync as readdirSync3, readFileSync as readFileSync3, statSync } from "node:fs";
|
|
4273
|
-
import { homedir } from "node:os";
|
|
4274
|
-
import path5 from "node:path";
|
|
4275
|
-
|
|
4276
|
-
// scripts/lane/lane-paths.ts
|
|
4277
|
-
import path4 from "node:path";
|
|
4278
|
-
var LANE_ROOT_KEY = "JOSH_LANE_ROOT";
|
|
4279
|
-
var LANE_DIRECTORY_SUFFIX = "-lanes";
|
|
4280
|
-
var LANE_BRANCH_SUFFIX = "-lane";
|
|
4281
|
-
function default_lane_root(repository_root) {
|
|
4282
|
-
const name = path4.basename(repository_root);
|
|
4283
|
-
return path4.join(path4.dirname(repository_root), `.${name}${LANE_DIRECTORY_SUFFIX}`);
|
|
4284
|
-
}
|
|
4285
|
-
function lane_root(repository_root, environment = process.env) {
|
|
4286
|
-
const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
|
|
4287
|
-
return configured.length === 0 ? default_lane_root(repository_root) : path4.resolve(configured);
|
|
4288
|
-
}
|
|
4289
|
-
function lane_directory(root, issue) {
|
|
4290
|
-
return path4.join(root, issue);
|
|
4291
|
-
}
|
|
4292
|
-
var LANE_ISSUE_PATTERN = /^\d+$/u;
|
|
4293
|
-
var DEFAULT_LANE_ROOT_PATTERN = new RegExp(String.raw`^\..+${LANE_DIRECTORY_SUFFIX}$`, "u");
|
|
4294
|
-
function is_lane_root(directory, environment) {
|
|
4295
|
-
const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
|
|
4296
|
-
if (configured.length > 0) return path4.resolve(configured) === directory;
|
|
4297
|
-
return DEFAULT_LANE_ROOT_PATTERN.test(path4.basename(directory));
|
|
4298
|
-
}
|
|
4299
|
-
function lane_issue_of(directory, environment = process.env) {
|
|
4300
|
-
const resolved = path4.resolve(directory);
|
|
4301
|
-
const issue = path4.basename(resolved);
|
|
4302
|
-
if (!LANE_ISSUE_PATTERN.test(issue)) return void 0;
|
|
4303
|
-
return is_lane_root(path4.dirname(resolved), environment) ? issue : void 0;
|
|
4304
|
-
}
|
|
4305
|
-
function lane_branch(issue) {
|
|
4306
|
-
return `${issue}${LANE_BRANCH_SUFFIX}`;
|
|
4307
|
-
}
|
|
4308
|
-
var SEAT_LOCK_DIR = ".seat-locks";
|
|
4309
|
-
function is_lane_entry(name) {
|
|
4310
|
-
return LANE_ISSUE_PATTERN.test(name) || DEFAULT_LANE_ROOT_PATTERN.test(name);
|
|
4311
|
-
}
|
|
4312
|
-
var lane_paths = {
|
|
4313
|
-
LANE_BRANCH_SUFFIX,
|
|
4314
|
-
LANE_ROOT_KEY,
|
|
4315
|
-
SEAT_LOCK_DIR,
|
|
4316
|
-
default_lane_root,
|
|
4317
|
-
is_lane_entry,
|
|
4318
|
-
lane_branch,
|
|
4319
|
-
lane_directory,
|
|
4320
|
-
lane_issue_of,
|
|
4321
|
-
lane_root
|
|
4322
|
-
};
|
|
4323
|
-
|
|
4324
|
-
// scripts/lib/read-file.ts
|
|
4325
|
-
import { readFileSync as readFileSync2 } from "node:fs";
|
|
4326
|
-
var ABSENT_CODE = "ENOENT";
|
|
4327
|
-
function is_absent(error) {
|
|
4328
|
-
return error instanceof Error && "code" in error && error.code === ABSENT_CODE;
|
|
4329
|
-
}
|
|
4330
|
-
function read_optional(path7) {
|
|
4331
|
-
try {
|
|
4332
|
-
return readFileSync2(path7, "utf8");
|
|
4333
|
-
} catch (error) {
|
|
4334
|
-
if (is_absent(error)) return void 0;
|
|
4335
|
-
throw error;
|
|
4336
|
-
}
|
|
4337
|
-
}
|
|
4338
|
-
function read_file_or_empty(path7) {
|
|
4339
|
-
return read_optional(path7) ?? "";
|
|
4340
|
-
}
|
|
4341
|
-
function read_if_readable(path7) {
|
|
4342
|
-
try {
|
|
4343
|
-
return readFileSync2(path7, "utf8");
|
|
4344
|
-
} catch {
|
|
4345
|
-
return void 0;
|
|
4346
|
-
}
|
|
4347
|
-
}
|
|
4348
|
-
var file_reader = { read_optional, read_file_or_empty, read_if_readable };
|
|
4349
|
-
|
|
4350
|
-
// scripts/cost-runtime/cost-usage.ts
|
|
4351
|
-
import { z as z7 } from "zod";
|
|
4352
|
-
var CACHE_CREATION_SCHEMA = z7.object({
|
|
4353
|
-
ephemeral_1h_input_tokens: z7.number().nullish(),
|
|
4354
|
-
ephemeral_5m_input_tokens: z7.number().nullish()
|
|
4355
|
-
});
|
|
4356
|
-
var USAGE_SCHEMA = z7.object({
|
|
4357
|
-
input_tokens: z7.number(),
|
|
4358
|
-
cache_creation_input_tokens: z7.number().nullish(),
|
|
4359
|
-
cache_read_input_tokens: z7.number().nullish(),
|
|
4360
|
-
output_tokens: z7.number(),
|
|
4361
|
-
output_tokens_details: z7.object({ thinking_tokens: z7.number().nullish() }).nullish(),
|
|
4362
|
-
cache_creation: CACHE_CREATION_SCHEMA.nullish()
|
|
4363
|
-
});
|
|
4364
|
-
var MESSAGE_SCHEMA3 = z7.object({
|
|
4365
|
-
id: z7.string().nullish(),
|
|
4366
|
-
model: z7.string().nullish(),
|
|
4367
|
-
usage: USAGE_SCHEMA.nullish()
|
|
4368
|
-
});
|
|
4369
|
-
var LINE_SCHEMA2 = z7.object({
|
|
4370
|
-
type: z7.string(),
|
|
4371
|
-
requestId: z7.string().nullish(),
|
|
4372
|
-
uuid: z7.string().nullish(),
|
|
4373
|
-
gitBranch: z7.string().nullish(),
|
|
4374
|
-
timestamp: z7.string().nullish(),
|
|
4375
|
-
message: MESSAGE_SCHEMA3.nullish()
|
|
4376
|
-
});
|
|
4377
|
-
var SYNTHETIC_MODEL = "<synthetic>";
|
|
4378
|
-
var EMPTY_TOTALS = {
|
|
4379
|
-
input_tokens: 0,
|
|
4380
|
-
cache_write_5m_tokens: 0,
|
|
4381
|
-
cache_write_1h_tokens: 0,
|
|
4382
|
-
cache_read_tokens: 0,
|
|
4383
|
-
output_tokens: 0,
|
|
4384
|
-
thinking_tokens: 0,
|
|
4385
|
-
thinking_measured: false
|
|
4386
|
-
};
|
|
4387
|
-
var UNKNOWN_MODEL = "unknown";
|
|
4388
|
-
var UNKNOWN_BRANCH2 = "";
|
|
4389
|
-
function split_cache_write(usage) {
|
|
4390
|
-
const total = usage.cache_creation_input_tokens ?? 0;
|
|
4391
|
-
const detail = usage.cache_creation;
|
|
4392
|
-
if (!detail) return { write_5m: total, write_1h: 0 };
|
|
4393
|
-
const write_1h = detail.ephemeral_1h_input_tokens ?? 0;
|
|
4394
|
-
return { write_5m: detail.ephemeral_5m_input_tokens ?? total - write_1h, write_1h };
|
|
4395
|
-
}
|
|
4396
|
-
function thinking_usage(usage) {
|
|
4397
|
-
const raw = usage.output_tokens_details?.thinking_tokens;
|
|
4398
|
-
return { tokens: raw ?? 0, measured: raw !== null && raw !== void 0 };
|
|
4399
|
-
}
|
|
4400
|
-
function to_totals(usage) {
|
|
4401
|
-
const { write_5m, write_1h } = split_cache_write(usage);
|
|
4402
|
-
const thinking = thinking_usage(usage);
|
|
4403
|
-
return {
|
|
4404
|
-
input_tokens: usage.input_tokens,
|
|
4405
|
-
cache_write_5m_tokens: write_5m,
|
|
4406
|
-
cache_write_1h_tokens: write_1h,
|
|
4407
|
-
cache_read_tokens: usage.cache_read_input_tokens ?? 0,
|
|
4408
|
-
output_tokens: usage.output_tokens,
|
|
4409
|
-
thinking_tokens: thinking.tokens,
|
|
4410
|
-
thinking_measured: thinking.measured
|
|
4411
|
-
};
|
|
4412
|
-
}
|
|
4413
|
-
function declared_id(data) {
|
|
4414
|
-
return data.requestId ?? data.message?.id ?? data.uuid ?? void 0;
|
|
4415
|
-
}
|
|
4416
|
-
function request_id_of(data, usage) {
|
|
4417
|
-
const fallback = `${data.timestamp ?? ""}-${String(usage.output_tokens)}`;
|
|
4418
|
-
return declared_id(data) ?? fallback;
|
|
4419
|
-
}
|
|
4420
|
-
function to_record(data, usage) {
|
|
4421
|
-
return {
|
|
4422
|
-
request_id: request_id_of(data, usage),
|
|
4423
|
-
model: data.message?.model ?? UNKNOWN_MODEL,
|
|
4424
|
-
branch: data.gitBranch ?? UNKNOWN_BRANCH2,
|
|
4425
|
-
at_ms: time_instant.parse_instant(data.timestamp),
|
|
4426
|
-
totals: to_totals(usage)
|
|
4427
|
-
};
|
|
4428
|
-
}
|
|
4429
|
-
var ASSISTANT_TYPE2 = "assistant";
|
|
4430
|
-
function is_priced_line(data) {
|
|
4431
|
-
return data.type === ASSISTANT_TYPE2 && data.message?.model !== SYNTHETIC_MODEL;
|
|
4432
|
-
}
|
|
4433
|
-
function classify(data) {
|
|
4434
|
-
if (!is_priced_line(data)) return { kind: "skipped" };
|
|
4435
|
-
const usage = data.message?.usage;
|
|
4436
|
-
return usage ? { kind: "record", record: to_record(data, usage) } : { kind: "no_usage" };
|
|
4437
|
-
}
|
|
4438
|
-
function parse_line4(line) {
|
|
4439
|
-
if (line.trim() === "") return { kind: "skipped" };
|
|
4440
|
-
const parsed = LINE_SCHEMA2.safeParse(json_value.parse_or_undefined(line));
|
|
4441
|
-
return parsed.success ? classify(parsed.data) : { kind: "malformed" };
|
|
4442
|
-
}
|
|
4443
|
-
function later_instant(left, right) {
|
|
4444
|
-
if (left === void 0) return right;
|
|
4445
|
-
if (right === void 0) return left;
|
|
4446
|
-
return Math.max(left, right);
|
|
4447
|
-
}
|
|
4448
|
-
function dedupe(records) {
|
|
4449
|
-
const by_id = /* @__PURE__ */ new Map();
|
|
4450
|
-
for (const record of records) {
|
|
4451
|
-
const seen = by_id.get(record.request_id);
|
|
4452
|
-
const at_ms = later_instant(seen?.at_ms, record.at_ms);
|
|
4453
|
-
by_id.set(record.request_id, { ...seen ?? record, at_ms });
|
|
4454
|
-
}
|
|
4455
|
-
return [...by_id.values()];
|
|
4456
|
-
}
|
|
4457
|
-
function add_totals(left, right) {
|
|
4458
|
-
return {
|
|
4459
|
-
input_tokens: left.input_tokens + right.input_tokens,
|
|
4460
|
-
cache_write_5m_tokens: left.cache_write_5m_tokens + right.cache_write_5m_tokens,
|
|
4461
|
-
cache_write_1h_tokens: left.cache_write_1h_tokens + right.cache_write_1h_tokens,
|
|
4462
|
-
cache_read_tokens: left.cache_read_tokens + right.cache_read_tokens,
|
|
4463
|
-
output_tokens: left.output_tokens + right.output_tokens,
|
|
4464
|
-
thinking_tokens: left.thinking_tokens + right.thinking_tokens,
|
|
4465
|
-
thinking_measured: left.thinking_measured || right.thinking_measured
|
|
4466
|
-
};
|
|
4467
|
-
}
|
|
4468
|
-
function sum_totals(records) {
|
|
4469
|
-
let total = EMPTY_TOTALS;
|
|
4470
|
-
for (const record of records) total = add_totals(total, record.totals);
|
|
4471
|
-
return total;
|
|
4472
|
-
}
|
|
4473
|
-
function billed_input(totals) {
|
|
4474
|
-
return totals.input_tokens + totals.cache_write_5m_tokens + totals.cache_write_1h_tokens + totals.cache_read_tokens;
|
|
4475
|
-
}
|
|
4476
|
-
var cost_usage = {
|
|
4477
|
-
EMPTY_TOTALS,
|
|
4478
|
-
UNKNOWN_MODEL,
|
|
4479
|
-
SYNTHETIC_MODEL,
|
|
4480
|
-
parse_line: parse_line4,
|
|
4481
|
-
dedupe,
|
|
4482
|
-
add_totals,
|
|
4483
|
-
sum_totals,
|
|
4484
|
-
billed_input
|
|
4485
|
-
};
|
|
4486
|
-
|
|
4487
|
-
// scripts/cost-runtime/cost-transcript.ts
|
|
4488
|
-
var TRANSCRIPT_ROOT = path5.join(".claude", "projects");
|
|
4489
|
-
var TRANSCRIPT_EXTENSION = ".jsonl";
|
|
4490
|
-
var SLUG_PATTERN = /[^a-zA-Z0-9-]/gu;
|
|
4491
|
-
var UNIT_DIRECTORY = "subagents";
|
|
4492
|
-
var UNIT_ID_SEPARATOR = "/";
|
|
4493
|
-
function project_slug(cwd) {
|
|
4494
|
-
return cwd.replaceAll(SLUG_PATTERN, "-");
|
|
4495
|
-
}
|
|
4496
|
-
function transcript_directory(cwd, home = homedir()) {
|
|
4497
|
-
return path5.join(home, TRANSCRIPT_ROOT, project_slug(cwd));
|
|
4498
|
-
}
|
|
4499
|
-
var GIT_ENTRY = ".git";
|
|
4500
|
-
var GITDIR_PREFIX = "gitdir:";
|
|
4501
|
-
var WORKTREE_SEGMENT = `/${GIT_ENTRY}/worktrees/`;
|
|
4502
|
-
var NOT_FOUND = -1;
|
|
4503
|
-
function linked_worktree_gitdir(cwd) {
|
|
4504
|
-
try {
|
|
4505
|
-
const contents = readFileSync3(path5.join(cwd, GIT_ENTRY), "utf8").trim();
|
|
4506
|
-
return contents.startsWith(GITDIR_PREFIX) ? contents.slice(GITDIR_PREFIX.length).trim() : "";
|
|
4507
|
-
} catch {
|
|
4508
|
-
return "";
|
|
4509
|
-
}
|
|
4510
|
-
}
|
|
4511
|
-
function session_cwd(cwd) {
|
|
4512
|
-
const gitdir = linked_worktree_gitdir(cwd);
|
|
4513
|
-
const absolute = gitdir === "" ? "" : path5.resolve(cwd, gitdir);
|
|
4514
|
-
const segment = absolute.indexOf(WORKTREE_SEGMENT);
|
|
4515
|
-
return segment === NOT_FOUND ? cwd : absolute.slice(0, segment);
|
|
4516
|
-
}
|
|
4517
|
-
function read_directory(directory) {
|
|
4518
|
-
try {
|
|
4519
|
-
return readdirSync3(directory);
|
|
4520
|
-
} catch {
|
|
4521
|
-
return [];
|
|
4522
|
-
}
|
|
4523
|
-
}
|
|
4524
|
-
var LANE_ISSUE_SLUG = /^\d+$/u;
|
|
4525
|
-
function lane_transcript_directories(main_cwd, home) {
|
|
4526
|
-
const projects = path5.join(home, TRANSCRIPT_ROOT);
|
|
4527
|
-
const prefix = `${project_slug(lane_paths.lane_root(main_cwd))}-`;
|
|
4528
|
-
return read_directory(projects).filter((name) => name.startsWith(prefix) && LANE_ISSUE_SLUG.test(name.slice(prefix.length))).map((name) => path5.join(projects, name));
|
|
4529
|
-
}
|
|
4530
|
-
function transcript_directories(cwd, home = homedir()) {
|
|
4531
|
-
const own = transcript_directory(cwd, home);
|
|
4532
|
-
const lanes = session_cwd(cwd) === cwd ? lane_transcript_directories(cwd, home) : [];
|
|
4533
|
-
return [.../* @__PURE__ */ new Set([own, ...lanes])];
|
|
4534
|
-
}
|
|
4535
|
-
var OWN_DEPTH = 0;
|
|
4536
|
-
function home_directory() {
|
|
4537
|
-
return homedir();
|
|
4538
|
-
}
|
|
4539
|
-
function to_session_file(full_path, session_id, depth) {
|
|
4540
|
-
try {
|
|
4541
|
-
return {
|
|
4542
|
-
session_id,
|
|
4543
|
-
path: full_path,
|
|
4544
|
-
modified_ms: statSync(full_path).mtimeMs,
|
|
4545
|
-
is_delegated: depth > OWN_DEPTH,
|
|
4546
|
-
depth
|
|
4547
|
-
};
|
|
4548
|
-
} catch {
|
|
4549
|
-
return void 0;
|
|
4550
|
-
}
|
|
4551
|
-
}
|
|
4552
|
-
function is_transcript(name) {
|
|
4553
|
-
return name.endsWith(TRANSCRIPT_EXTENSION);
|
|
4554
|
-
}
|
|
4555
|
-
function without_extension(name) {
|
|
4556
|
-
return name.slice(0, -TRANSCRIPT_EXTENSION.length);
|
|
4557
|
-
}
|
|
4558
|
-
function own_files(directory, names) {
|
|
4559
|
-
return names.filter((name) => is_transcript(name)).map((name) => to_session_file(path5.join(directory, name), without_extension(name), OWN_DEPTH)).filter((file) => file !== void 0);
|
|
4560
|
-
}
|
|
4561
|
-
function unit_directory(directory, session_id) {
|
|
4562
|
-
return path5.join(directory, session_id, UNIT_DIRECTORY);
|
|
4563
|
-
}
|
|
4564
|
-
var UNIT_DEPTH = 1;
|
|
4565
|
-
function level_units(subagents_directory, prefix, depth) {
|
|
4566
|
-
return read_directory(subagents_directory).filter((name) => is_transcript(name)).map(
|
|
4567
|
-
(name) => to_session_file(
|
|
4568
|
-
path5.join(subagents_directory, name),
|
|
4569
|
-
`${prefix}${UNIT_ID_SEPARATOR}${without_extension(name)}`,
|
|
4570
|
-
depth
|
|
4571
|
-
)
|
|
4572
|
-
).filter((file) => file !== void 0);
|
|
4573
|
-
}
|
|
4574
|
-
function collect_units(subagents_directory, prefix, depth) {
|
|
4575
|
-
const nested = read_directory(subagents_directory).filter((name) => !is_transcript(name)).flatMap(
|
|
4576
|
-
(name) => collect_units(
|
|
4577
|
-
unit_directory(subagents_directory, name),
|
|
4578
|
-
`${prefix}${UNIT_ID_SEPARATOR}${name}`,
|
|
4579
|
-
depth + 1
|
|
4580
|
-
)
|
|
4581
|
-
);
|
|
4582
|
-
return [...level_units(subagents_directory, prefix, depth), ...nested];
|
|
4583
|
-
}
|
|
4584
|
-
function unit_files(directory, session_name) {
|
|
4585
|
-
return collect_units(unit_directory(directory, session_name), session_name, UNIT_DEPTH);
|
|
4586
|
-
}
|
|
4587
|
-
function list_sessions(directory) {
|
|
4588
|
-
const names = read_directory(directory);
|
|
4589
|
-
const units = names.filter((name) => !is_transcript(name)).flatMap((name) => unit_files(directory, name));
|
|
4590
|
-
return [...own_files(directory, names), ...units].toSorted(
|
|
4591
|
-
(left, right) => right.modified_ms - left.modified_ms
|
|
4592
|
-
);
|
|
4593
|
-
}
|
|
4594
|
-
function list_sessions_across(directories) {
|
|
4595
|
-
const seen = /* @__PURE__ */ new Set();
|
|
4596
|
-
const merged = directories.flatMap((directory) => list_sessions(directory));
|
|
4597
|
-
const newest_first = merged.toSorted((left, right) => right.modified_ms - left.modified_ms);
|
|
4598
|
-
const kept = [];
|
|
4599
|
-
for (const file of newest_first) {
|
|
4600
|
-
if (seen.has(file.session_id)) continue;
|
|
4601
|
-
seen.add(file.session_id);
|
|
4602
|
-
kept.push(file);
|
|
4603
|
-
}
|
|
4604
|
-
return kept;
|
|
4605
|
-
}
|
|
4606
|
-
function owning_session_id(file) {
|
|
4607
|
-
const [owner] = file.session_id.split(UNIT_ID_SEPARATOR);
|
|
4608
|
-
return owner ?? file.session_id;
|
|
4609
|
-
}
|
|
4610
|
-
function parent_session_id(file) {
|
|
4611
|
-
const separator = file.session_id.lastIndexOf(UNIT_ID_SEPARATOR);
|
|
4612
|
-
return separator === NOT_FOUND ? file.session_id : file.session_id.slice(0, separator);
|
|
4613
|
-
}
|
|
4614
|
-
function latest_own_index(files) {
|
|
4615
|
-
const index = files.findIndex((file) => !file.is_delegated);
|
|
4616
|
-
return index === -1 ? 0 : index;
|
|
4617
|
-
}
|
|
4618
|
-
function empty_session() {
|
|
4619
|
-
return {
|
|
4620
|
-
records: [],
|
|
4621
|
-
no_usage_lines: 0,
|
|
4622
|
-
malformed_lines: 0,
|
|
4623
|
-
is_readable: false,
|
|
4624
|
-
baseline_tokens: 0
|
|
4625
|
-
};
|
|
4626
|
-
}
|
|
4627
|
-
function tally(content) {
|
|
4628
|
-
const outcomes = content.split("\n").map((line) => cost_usage.parse_line(line));
|
|
4629
|
-
const records = outcomes.flatMap(
|
|
4630
|
-
(outcome) => outcome.kind === "record" ? [outcome.record] : []
|
|
4631
|
-
);
|
|
4632
|
-
const unique = cost_usage.dedupe(records);
|
|
4633
|
-
const [first] = unique;
|
|
4634
|
-
return {
|
|
4635
|
-
records: unique,
|
|
4636
|
-
no_usage_lines: outcomes.filter((outcome) => outcome.kind === "no_usage").length,
|
|
4637
|
-
malformed_lines: outcomes.filter((outcome) => outcome.kind === "malformed").length,
|
|
4638
|
-
is_readable: true,
|
|
4639
|
-
baseline_tokens: first === void 0 ? 0 : cost_usage.billed_input(first.totals)
|
|
4640
|
-
};
|
|
4641
|
-
}
|
|
4642
|
-
function read_session(file) {
|
|
4643
|
-
const content = file_reader.read_if_readable(file.path);
|
|
4644
|
-
if (content === void 0) return { session_id: file.session_id, ...empty_session() };
|
|
4645
|
-
return { session_id: file.session_id, ...tally(content) };
|
|
4646
|
-
}
|
|
4647
|
-
function read_raw(file) {
|
|
4648
|
-
return file_reader.read_if_readable(file.path) ?? "";
|
|
4649
|
-
}
|
|
4650
|
-
function read_optional2(file) {
|
|
4651
|
-
return file_reader.read_if_readable(file.path);
|
|
4652
|
-
}
|
|
4653
|
-
function directory_exists(directory) {
|
|
4654
|
-
try {
|
|
4655
|
-
return statSync(directory).isDirectory();
|
|
4656
|
-
} catch {
|
|
4657
|
-
return false;
|
|
4658
|
-
}
|
|
4659
|
-
}
|
|
4660
|
-
function searched_directories(directories) {
|
|
4661
|
-
return directories.map((directory) => ({
|
|
4662
|
-
path: directory,
|
|
4663
|
-
exists: directory_exists(directory)
|
|
4664
|
-
}));
|
|
4665
|
-
}
|
|
4666
|
-
function describe_searched(directory) {
|
|
4667
|
-
return ` ${directory.path} \u2014 ${directory.exists ? "no transcripts here" : "no such directory"}`;
|
|
4668
|
-
}
|
|
4669
|
-
function missing_message(searched, session_id) {
|
|
4670
|
-
const lead = session_id === void 0 ? "No transcripts found. Searched:" : `No transcript named ${session_id}. Searched:`;
|
|
4671
|
-
const listed = searched.map((directory) => describe_searched(directory));
|
|
4672
|
-
if (session_id !== void 0) return [lead, ...listed];
|
|
4673
|
-
return [
|
|
4674
|
-
lead,
|
|
4675
|
-
...listed,
|
|
4676
|
-
"Claude Code writes them per project; run this from the project it ran in."
|
|
4677
|
-
];
|
|
4678
|
-
}
|
|
4679
|
-
var cost_transcript = {
|
|
4680
|
-
TRANSCRIPT_EXTENSION,
|
|
4681
|
-
TRANSCRIPT_ROOT,
|
|
4682
|
-
UNIT_DIRECTORY,
|
|
4683
|
-
project_slug,
|
|
4684
|
-
transcript_directory,
|
|
4685
|
-
transcript_directories,
|
|
4686
|
-
session_cwd,
|
|
4687
|
-
unit_directory,
|
|
4688
|
-
list_sessions,
|
|
4689
|
-
list_sessions_across,
|
|
4690
|
-
searched_directories,
|
|
4691
|
-
owning_session_id,
|
|
4692
|
-
parent_session_id,
|
|
4693
|
-
latest_own_index,
|
|
4694
|
-
tally,
|
|
4695
|
-
read_session,
|
|
4696
|
-
read_raw,
|
|
4697
|
-
read_optional: read_optional2,
|
|
4698
|
-
missing_message,
|
|
4699
|
-
home_directory
|
|
4700
|
-
};
|
|
4701
|
-
|
|
4702
|
-
// scripts/time-runtime/time-hook-transcript.ts
|
|
4703
|
-
var { TRANSCRIPT_EXTENSION: TRANSCRIPT_EXTENSION2 } = cost_transcript;
|
|
4388
|
+
import path3 from "node:path";
|
|
4389
|
+
var { TRANSCRIPT_EXTENSION } = cost_transcript;
|
|
4704
4390
|
var AGENT_PREFIX = "agent-";
|
|
4705
4391
|
var AGENT_ID_PATTERN = /^[\w-]+$/u;
|
|
4706
4392
|
function is_agent_id(value) {
|
|
4707
4393
|
return typeof value === "string" && AGENT_ID_PATTERN.test(value);
|
|
4708
4394
|
}
|
|
4709
4395
|
function fork_path(transcript_path, agent_id) {
|
|
4710
|
-
const directory =
|
|
4711
|
-
const session_id =
|
|
4712
|
-
const file_name = `${AGENT_PREFIX}${agent_id}${
|
|
4713
|
-
return
|
|
4396
|
+
const directory = path3.dirname(transcript_path);
|
|
4397
|
+
const session_id = path3.basename(transcript_path, TRANSCRIPT_EXTENSION);
|
|
4398
|
+
const file_name = `${AGENT_PREFIX}${agent_id}${TRANSCRIPT_EXTENSION}`;
|
|
4399
|
+
return path3.join(cost_transcript.unit_directory(directory, session_id), file_name);
|
|
4714
4400
|
}
|
|
4715
4401
|
function transcript_of(transcript_path, agent_id) {
|
|
4716
4402
|
if (!is_agent_id(agent_id)) return transcript_path;
|
|
4717
|
-
if (!transcript_path.endsWith(
|
|
4403
|
+
if (!transcript_path.endsWith(TRANSCRIPT_EXTENSION)) return transcript_path;
|
|
4718
4404
|
return fork_path(transcript_path, agent_id);
|
|
4719
4405
|
}
|
|
4720
4406
|
var time_hook_transcript = {
|
|
@@ -4723,8 +4409,8 @@ var time_hook_transcript = {
|
|
|
4723
4409
|
};
|
|
4724
4410
|
|
|
4725
4411
|
// scripts/time-runtime/time-density-hook.ts
|
|
4726
|
-
import { closeSync, fstatSync, openSync, readSync } from "node:fs";
|
|
4727
|
-
import { z as
|
|
4412
|
+
import { closeSync as closeSync2, fstatSync, openSync as openSync2, readSync } from "node:fs";
|
|
4413
|
+
import { z as z7 } from "zod";
|
|
4728
4414
|
|
|
4729
4415
|
// scripts/time-runtime/time-density.ts
|
|
4730
4416
|
var MIN_ROUND_TRIPS = 10;
|
|
@@ -4780,15 +4466,15 @@ var TAIL_BYTES = 262144;
|
|
|
4780
4466
|
var FILE_START = 0;
|
|
4781
4467
|
var NOTICE_PREFIX = "josh-density-notice-";
|
|
4782
4468
|
var NEVER_MS = 0;
|
|
4783
|
-
var payload_schema =
|
|
4784
|
-
transcript_path:
|
|
4469
|
+
var payload_schema = z7.object({
|
|
4470
|
+
transcript_path: z7.string().min(1).optional(),
|
|
4785
4471
|
// **`nullish`, not `optional`.** A payload spelling the absent agent as `null` has to read as "no
|
|
4786
4472
|
// fork"; rejected, it would fail `safeParse` for the whole payload and silence the line for every
|
|
4787
4473
|
// edit of the main line — the opposite of this module's stated failure direction.
|
|
4788
|
-
agent_id:
|
|
4474
|
+
agent_id: z7.string().nullish()
|
|
4789
4475
|
});
|
|
4790
|
-
var notice_schema =
|
|
4791
|
-
var call_schema =
|
|
4476
|
+
var notice_schema = z7.object({ notified_at_ms: z7.number() });
|
|
4477
|
+
var call_schema = z7.object({ tool_name: z7.string().min(1), tool_input: z7.unknown() });
|
|
4792
4478
|
function parse_transcript_path(raw_payload) {
|
|
4793
4479
|
const parsed = payload_schema.safeParse(JSON.parse(raw_payload));
|
|
4794
4480
|
if (!parsed.success || parsed.data.transcript_path === void 0) return void 0;
|
|
@@ -4800,7 +4486,7 @@ function parse_call(raw_payload) {
|
|
|
4800
4486
|
return { name: parsed.data.tool_name, input: parsed.data.tool_input };
|
|
4801
4487
|
}
|
|
4802
4488
|
function read_tail(file_path, max_bytes = TAIL_BYTES) {
|
|
4803
|
-
const descriptor =
|
|
4489
|
+
const descriptor = openSync2(file_path, "r");
|
|
4804
4490
|
try {
|
|
4805
4491
|
const { size } = fstatSync(descriptor);
|
|
4806
4492
|
const length = Math.min(size, max_bytes);
|
|
@@ -4808,7 +4494,7 @@ function read_tail(file_path, max_bytes = TAIL_BYTES) {
|
|
|
4808
4494
|
const read = readSync(descriptor, buffer, FILE_START, length, size - length);
|
|
4809
4495
|
return buffer.subarray(FILE_START, read).toString("utf8");
|
|
4810
4496
|
} finally {
|
|
4811
|
-
|
|
4497
|
+
closeSync2(descriptor);
|
|
4812
4498
|
}
|
|
4813
4499
|
}
|
|
4814
4500
|
function notice_path(transcript_path) {
|
|
@@ -4817,15 +4503,11 @@ function notice_path(transcript_path) {
|
|
|
4817
4503
|
function last_notice_ms(source) {
|
|
4818
4504
|
const raw = stamp_file.read_stamp_text(source);
|
|
4819
4505
|
if (raw === void 0) return NEVER_MS;
|
|
4820
|
-
|
|
4821
|
-
return notice_schema.parse(JSON.parse(raw)).notified_at_ms;
|
|
4822
|
-
} catch {
|
|
4823
|
-
return NEVER_MS;
|
|
4824
|
-
}
|
|
4506
|
+
return json_value.parse_with(raw, notice_schema)?.notified_at_ms ?? NEVER_MS;
|
|
4825
4507
|
}
|
|
4826
|
-
function arm_throttle(
|
|
4508
|
+
function arm_throttle(target2, now_ms) {
|
|
4827
4509
|
try {
|
|
4828
|
-
stamp_file.write_stamp(
|
|
4510
|
+
stamp_file.write_stamp(target2, { notified_at_ms: now_ms });
|
|
4829
4511
|
} catch {
|
|
4830
4512
|
}
|
|
4831
4513
|
}
|
|
@@ -4834,11 +4516,11 @@ function notice_for(raw_payload, now_ms) {
|
|
|
4834
4516
|
if (transcript_path === void 0) return void 0;
|
|
4835
4517
|
const tail = read_tail(transcript_path);
|
|
4836
4518
|
const reading = time_density.read_window(tail);
|
|
4837
|
-
const
|
|
4838
|
-
if (!time_density.is_due(reading, now_ms - last_notice_ms(
|
|
4519
|
+
const target2 = notice_path(transcript_path);
|
|
4520
|
+
if (!time_density.is_due(reading, now_ms - last_notice_ms(target2))) return void 0;
|
|
4839
4521
|
const candidates = time_batch_guard.pairing_candidates(tail, parse_call(raw_payload));
|
|
4840
4522
|
if (candidates === "") return void 0;
|
|
4841
|
-
arm_throttle(
|
|
4523
|
+
arm_throttle(target2, now_ms);
|
|
4842
4524
|
return time_density.format_notice(reading, candidates);
|
|
4843
4525
|
}
|
|
4844
4526
|
function density_notice(raw_payload, now_ms = Date.now()) {
|
|
@@ -4855,11 +4537,8 @@ var time_density_hook = {
|
|
|
4855
4537
|
};
|
|
4856
4538
|
|
|
4857
4539
|
export {
|
|
4858
|
-
json_value,
|
|
4859
4540
|
cost_blocks,
|
|
4860
4541
|
ESLINT_EDIT_CACHE_FLAGS,
|
|
4861
|
-
process_identity,
|
|
4862
|
-
process_owner_schema,
|
|
4863
4542
|
time_shell,
|
|
4864
4543
|
time_bundle_call,
|
|
4865
4544
|
blocking_issue_schema,
|
|
@@ -4881,10 +4560,6 @@ export {
|
|
|
4881
4560
|
time_transcript_line,
|
|
4882
4561
|
time_spans,
|
|
4883
4562
|
time_batch_guard,
|
|
4884
|
-
lane_paths,
|
|
4885
|
-
file_reader,
|
|
4886
|
-
cost_usage,
|
|
4887
|
-
cost_transcript,
|
|
4888
4563
|
time_hook_transcript,
|
|
4889
4564
|
time_density_hook
|
|
4890
4565
|
};
|