@joshuafolkken/kit 1.1229.0 → 1.1370.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/investigator.md +1 -0
- package/.claude/settings.json +4 -0
- package/.claude/skills/dependency-update/SKILL.md +5 -3
- package/.claude/skills/epic-commands/SKILL.md +82 -113
- package/.claude/skills/epic-commands/epic-bundle.md +38 -63
- package/.claude/skills/epic-commands/execution-waves.md +30 -51
- package/.claude/skills/verify-ui/SKILL.md +13 -20
- package/.claude/skills/workflow-commands/SKILL.md +10 -10
- package/.claude/skills/workflow-commands/background-commands.md +4 -4
- package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
- package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
- package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
- package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
- package/.claude/skills/workflow-commands/backlogrun.md +50 -61
- package/.claude/skills/workflow-commands/chain-rule.md +36 -40
- package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
- package/.claude/skills/workflow-commands/followup.md +24 -20
- package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
- package/.claude/skills/workflow-commands/fullrun.md +10 -10
- package/.claude/skills/workflow-commands/halfrun.md +9 -8
- package/.claude/skills/workflow-commands/into-target.md +12 -18
- package/.claude/skills/workflow-commands/issue-comments.md +11 -26
- package/.claude/skills/workflow-commands/kickoff.md +27 -16
- package/.claude/skills/workflow-commands/latest-gate.md +18 -29
- package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
- package/.claude/skills/workflow-commands/observation-filing.md +37 -28
- package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
- package/.claude/skills/workflow-commands/prerequisite.md +23 -15
- package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
- package/.claude/skills/workflow-commands/prrun.md +3 -3
- package/.claude/skills/workflow-commands/retrospective.md +13 -18
- package/.claude/skills/workflow-commands/split-assessment.md +6 -4
- package/.claude/skills/workflow-commands/target-repository.md +25 -28
- package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
- package/.gitattributes +2 -1
- package/.github/workflows/ci.yml +14 -0
- package/.github/workflows/publish.yml +2 -0
- package/.vscode/tasks.json +14 -0
- package/CLAUDE.md +10 -61
- package/README.md +38 -57
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +10 -61
- package/dist/commands/document-section-cli.js +42 -10
- package/dist/config-merge/index.js +11 -2
- package/dist/hooks/audit-provision.js +2 -2
- package/dist/hooks/batch-guard.js +7 -7
- package/dist/hooks/{chunk-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
- package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
- package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
- package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
- package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
- package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
- package/dist/hooks/{chunk-6HJJXRBX.js → chunk-KPM4YIIX.js} +8 -44
- package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
- package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
- package/dist/hooks/{chunk-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
- package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
- package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
- package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
- package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
- package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
- package/dist/hooks/codex-hook-adapter.js +26 -21
- package/dist/hooks/duplicate-read-guard.js +8 -8
- package/dist/hooks/format-edited.js +4 -4
- package/dist/hooks/inputs.json +213 -197
- package/dist/hooks/investigation-guard.js +8 -8
- package/dist/hooks/pretool-guard.js +15 -15
- package/dist/hooks/session-lang.js +406 -8
- package/dist/hooks/stop-guard.js +122 -201
- package/dist/josh.js +540 -137
- package/dist/version/index.js +15 -13
- package/eslint/base.js +43 -5
- package/eslint/rules/english-only-prose.js +3 -3
- package/eslint/rules/import.js +12 -0
- package/eslint/rules/namespace-object-export.js +2 -2
- package/package.json +16 -10
- package/pnpm-workspace.yaml +2 -4
- package/prompts/coding-standards.md +14 -48
- package/prompts/collaboration-workflow/file-edits.md +1 -1
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +4 -10
- package/prompts/collaboration-workflow/operating-rules.md +7 -8
- package/prompts/collaboration-workflow/output-bounds.md +1 -1
- package/prompts/collaboration-workflow/overview.md +1 -1
- package/prompts/collaboration-workflow/plan-comment.md +2 -1
- package/prompts/collaboration-workflow/principles.md +21 -3
- package/prompts/collaboration-workflow/report-format.md +16 -29
- package/prompts/collaboration-workflow/residency.md +1 -1
- package/prompts/collaboration-workflow/rule-delivery.md +7 -95
- package/prompts/collaboration-workflow/shell-body.md +3 -23
- package/prompts/collaboration-workflow/turn-batching.md +4 -13
- package/prompts/collaboration-workflow/wip-cap.md +5 -11
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +3 -22
- package/prompts/review.md +15 -38
- package/prompts/testing-guide.md +2 -4
- package/scripts/adopt/adopt-logic.ts +5 -5
- package/scripts/adopt/adopt-toolkits.ts +4 -5
- package/scripts/adopt/adopt.ts +2 -3
- package/scripts/agent/agent-argv.ts +7 -7
- package/scripts/agent/agent-diagnostics.ts +2 -2
- package/scripts/agent/agent-exit-record.ts +1 -1
- package/scripts/agent/agent-headless.ts +1 -1
- package/scripts/agent/agent-launch-environment.ts +6 -1
- package/scripts/agent/agent-role-profile.ts +49 -22
- package/scripts/agent/agent-session-role.ts +32 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/claude-agent-argv.ts +4 -4
- package/scripts/agent/claude-result-event.ts +4 -4
- package/scripts/agent/codex-hooks.ts +2 -2
- package/scripts/agent/interactive-ask.ts +3 -6
- package/scripts/auto-ok/auto-ok-cli.ts +46 -60
- package/scripts/backlog/backlog-arrival-added.ts +34 -0
- package/scripts/backlog/backlog-arrival.ts +54 -17
- package/scripts/backlog/backlog-budget-cli.ts +34 -6
- package/scripts/backlog/backlog-budget.ts +17 -24
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-args.ts +5 -4
- package/scripts/backlog/backlog-drive-cli.ts +14 -10
- package/scripts/backlog/backlog-drive-epic.ts +85 -0
- package/scripts/backlog/backlog-drive-launch.ts +1 -1
- package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
- package/scripts/backlog/backlog-drive-named.ts +39 -9
- package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
- package/scripts/backlog/backlog-drive-restore.ts +1 -1
- package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
- package/scripts/backlog/backlog-drive.ts +43 -28
- package/scripts/backlog/backlog-idle.ts +88 -0
- package/scripts/backlog/backlog-named.ts +11 -15
- package/scripts/backlog/backlog-next.ts +26 -30
- package/scripts/backlog/backlog-offer-cli.ts +28 -23
- package/scripts/backlog/backlog-offer.ts +7 -7
- package/scripts/backlog/backlog-overlap.ts +178 -0
- package/scripts/backlog/backlog-plan-cli.ts +14 -90
- package/scripts/backlog/backlog-plan-read.ts +111 -0
- package/scripts/backlog/backlog-plan.ts +11 -10
- package/scripts/backlog/backlog-pool.ts +13 -14
- package/scripts/backlog/backlog-rank.ts +11 -11
- package/scripts/backlog/backlog-ready.ts +15 -10
- package/scripts/backlog/backlog-scope.ts +14 -15
- package/scripts/backlog/backlog-stalled-cli.ts +2 -2
- package/scripts/backlog/backlog-stalled-detect.ts +4 -4
- package/scripts/backlog/backlog-stalled.ts +5 -6
- package/scripts/backlog/backlog-waves.ts +4 -4
- package/scripts/backlog/backlogrun-args.ts +74 -0
- package/scripts/backlog/backlogrun-cli.ts +113 -0
- package/scripts/backlog/backlogrun-launch.ts +178 -0
- package/scripts/behavior/behavior-assertion.ts +6 -8
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/behavior/behavior-rules.ts +3 -3
- package/scripts/build/build-claude-md.ts +4 -4
- package/scripts/build/build-codex-hooks.ts +2 -2
- package/scripts/build/build-commands.ts +1 -1
- package/scripts/build/build-hooks.ts +5 -5
- package/scripts/build/build.ts +1 -1
- package/scripts/build/hook-bundle-stamp.ts +109 -7
- package/scripts/build/local-bin.ts +2 -2
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +2 -2
- package/scripts/ci/composite-actions.ts +1 -2
- package/scripts/ci/pr-classification.ts +2 -2
- package/scripts/claude/workflow-destination.ts +1 -1
- package/scripts/clone/clone-aggregate.ts +1 -1
- package/scripts/clone/clone-fingerprint.ts +1 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/index.ts +1 -1
- package/scripts/config-merge/json-format.ts +1 -3
- package/scripts/config-merge/patch-json-array.ts +90 -0
- package/scripts/config-merge/patch-json-key.ts +6 -3
- package/scripts/config-merge/patch-json-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +1 -1
- package/scripts/cost-runtime/context-cut-payback.ts +4 -5
- package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
- package/scripts/cost-runtime/cost-attribute.ts +3 -3
- package/scripts/cost-runtime/cost-blocks.ts +3 -4
- package/scripts/cost-runtime/cost-cli.ts +14 -11
- package/scripts/cost-runtime/cost-corpus.ts +11 -11
- package/scripts/cost-runtime/cost-pricing.ts +4 -4
- package/scripts/cost-runtime/cost-tokens.ts +1 -2
- package/scripts/cost-runtime/cost-transcript.ts +29 -29
- package/scripts/cost-runtime/cost-usage.ts +6 -7
- package/scripts/cost-runtime/cost-verdict.ts +10 -11
- package/scripts/cost-runtime/own-session.ts +1 -1
- package/scripts/cost-runtime/transcript-cwd.ts +2 -2
- package/scripts/delegation/delegation-cli.ts +4 -4
- package/scripts/delegation/delegation-policy.ts +13 -15
- package/scripts/delegation/duplicate-read-guard.ts +9 -10
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +1 -1
- package/scripts/delegation/investigation-guard.ts +18 -22
- package/scripts/delegation/investigation-reads.ts +48 -238
- package/scripts/discovery/repo-discovery.ts +1 -1
- package/scripts/discovery/repo-map-logic.ts +1 -2
- package/scripts/discovery/repo-origin.ts +3 -3
- package/scripts/discovery/repo-party-cli.ts +2 -2
- package/scripts/discovery/repo-party.ts +2 -2
- package/scripts/doctor/doctor-consumer.ts +1 -1
- package/scripts/doctor/doctor-io.ts +6 -7
- package/scripts/doctor/doctor-logic.ts +1 -1
- package/scripts/doctor/doctor-ports.ts +1 -1
- package/scripts/doctor/doctor.ts +8 -9
- package/scripts/document/backlogrun-parent-read-set.ts +5 -6
- package/scripts/document/bash-output-cap.ts +5 -7
- package/scripts/document/capped-print-part.ts +1 -1
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/document-byte-budget.ts +33 -64
- package/scripts/document/document-byte-check.ts +4 -4
- package/scripts/document/document-reachability.ts +7 -8
- package/scripts/document/document-read-cli.ts +2 -2
- package/scripts/document/document-scan.ts +26 -2
- package/scripts/document/document-section-cli.ts +6 -8
- package/scripts/document/document-section.ts +8 -12
- package/scripts/document/edit-files-cli.ts +3 -4
- package/scripts/document/entry-read-budget.ts +8 -70
- package/scripts/document/entry-read-set.ts +51 -34
- package/scripts/document/lane-child-read-set.ts +9 -9
- package/scripts/document/read-files-cli.ts +1 -2
- package/scripts/document/read-set-cli.ts +16 -19
- package/scripts/document/read-set-cost.ts +4 -4
- package/scripts/document/read-set-point-of-use.ts +28 -38
- package/scripts/document/read-set-pricing.ts +1 -1
- package/scripts/document/read-set-trim.ts +3 -3
- package/scripts/document/resident-budget.ts +8 -10
- package/scripts/epic/epic-add-body.ts +15 -18
- package/scripts/epic/epic-add-plan.ts +26 -28
- package/scripts/epic/epic-add.ts +32 -25
- package/scripts/epic/epic-audit-checks.ts +27 -37
- package/scripts/epic/epic-audit-cli.ts +21 -22
- package/scripts/epic/epic-audit-orphans.ts +16 -17
- package/scripts/epic/epic-audit-rationale.ts +10 -15
- package/scripts/epic/epic-audit-report.ts +2 -5
- package/scripts/epic/epic-audit.ts +18 -14
- package/scripts/epic/epic-body.ts +10 -10
- package/scripts/epic/epic-bundle-cli.ts +36 -34
- package/scripts/epic/epic-bundle-evidence.ts +5 -5
- package/scripts/epic/epic-bundle-gaps.ts +6 -9
- package/scripts/epic/epic-bundle-poll.ts +1 -1
- package/scripts/epic/epic-bundle-referenced.ts +11 -14
- package/scripts/epic/epic-bundle.ts +19 -20
- package/scripts/epic/epic-busy.ts +44 -21
- package/scripts/epic/epic-candidate-confirm.ts +15 -18
- package/scripts/epic/epic-chains.ts +18 -23
- package/scripts/epic/epic-classify.ts +11 -12
- package/scripts/epic/epic-cli-argv.ts +5 -6
- package/scripts/epic/epic-cli-remove.ts +9 -4
- package/scripts/epic/epic-cli.ts +38 -26
- package/scripts/epic/epic-close-comment.ts +14 -15
- package/scripts/epic/epic-close.ts +25 -29
- package/scripts/epic/epic-cross-repo.ts +18 -21
- package/scripts/epic/epic-decision.ts +14 -18
- package/scripts/epic/epic-fetch.ts +25 -31
- package/scripts/epic/epic-graph.ts +15 -17
- package/scripts/epic/epic-index.ts +14 -16
- package/scripts/epic/epic-issue.ts +9 -11
- package/scripts/epic/epic-label-age.ts +74 -0
- package/scripts/epic/epic-lane-offer.ts +35 -24
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +8 -8
- package/scripts/epic/epic-next-views.ts +12 -12
- package/scripts/epic/epic-next.ts +29 -33
- package/scripts/epic/epic-outside-blocker.ts +11 -10
- package/scripts/epic/epic-parse.ts +22 -24
- package/scripts/epic/epic-promote.ts +3 -2
- package/scripts/epic/epic-rank.ts +1 -1
- package/scripts/epic/epic-read.ts +10 -8
- package/scripts/epic/epic-reconcile.ts +8 -6
- package/scripts/epic/epic-reference.ts +5 -4
- package/scripts/epic/epic-relation-recheck.ts +10 -11
- package/scripts/epic/epic-relations.ts +9 -8
- package/scripts/epic/epic-remove-plan.ts +4 -5
- package/scripts/epic/epic-remove.ts +7 -5
- package/scripts/epic/epic-report.ts +18 -20
- package/scripts/epic/epic-run.ts +6 -5
- package/scripts/epic/epic-sections.ts +2 -2
- package/scripts/epic/epic-shape.ts +3 -3
- package/scripts/epic/epic-solo-stale.ts +3 -2
- package/scripts/epic/epic-solo.ts +8 -8
- package/scripts/epic/epic-triage.ts +5 -4
- package/scripts/epic/epic-validate.ts +8 -7
- package/scripts/epic/epic.ts +5 -5
- package/scripts/exports/unused-members-cli.ts +1 -1
- package/scripts/followup/followup-issue-number.ts +1 -2
- package/scripts/followup/git-followup-cleanup.ts +6 -7
- package/scripts/followup/git-followup-finish.ts +11 -13
- package/scripts/followup/git-followup-flush.ts +11 -7
- package/scripts/followup/git-followup-issue-close.ts +16 -13
- package/scripts/followup/git-followup-label.ts +9 -6
- package/scripts/followup/git-followup-merged.ts +1 -1
- package/scripts/followup/git-followup-pending.ts +7 -9
- package/scripts/followup/git-followup-stages.ts +28 -17
- package/scripts/followup/git-followup-workflow.ts +19 -21
- package/scripts/followup/git-pr-followup-checks.ts +13 -20
- package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
- package/scripts/followup/git-pr-followup.ts +18 -17
- package/scripts/gate/core-admission.ts +162 -0
- package/scripts/gate/core-budget.ts +134 -91
- package/scripts/gate/gate-ledger.ts +114 -0
- package/scripts/gate/gate-log.ts +7 -9
- package/scripts/gate/gate-plan.ts +103 -35
- package/scripts/gate/gate-report.ts +39 -21
- package/scripts/gate/gate-skip.ts +11 -13
- package/scripts/gate/gate-steps.ts +5 -1
- package/scripts/gate/gate-tree.ts +3 -4
- package/scripts/gate/hook-gate-reuse.ts +9 -9
- package/scripts/gate/machine-capacity.ts +313 -0
- package/scripts/gate/pre-commit-type-check.ts +4 -4
- package/scripts/gate/project-checks.ts +12 -4
- package/scripts/gate/scoped-green.ts +11 -18
- package/scripts/gate/type-check-command.ts +2 -2
- package/scripts/gate/type-check-step.ts +4 -4
- package/scripts/gate/verification-gate.ts +60 -53
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/gh/git-ai-review-scan.ts +3 -2
- package/scripts/gh/git-gh-api-path.ts +10 -11
- package/scripts/gh/git-gh-exec.ts +43 -48
- package/scripts/gh/git-gh-failure.ts +6 -9
- package/scripts/gh/git-gh-helpers.ts +1 -1
- package/scripts/gh/git-gh-issue-list.ts +15 -19
- package/scripts/gh/git-gh-issue-read.ts +43 -60
- package/scripts/gh/git-gh-issue-rest.ts +14 -15
- package/scripts/gh/git-gh-issue-write.ts +52 -40
- package/scripts/gh/git-gh-issue.ts +23 -24
- package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
- package/scripts/gh/git-gh-pr-read.ts +46 -50
- package/scripts/gh/git-gh-pr-rest.ts +23 -26
- package/scripts/gh/git-gh-pr-review.ts +2 -2
- package/scripts/gh/git-gh-pr-rollup.ts +4 -4
- package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
- package/scripts/gh/git-gh-pr.ts +16 -16
- package/scripts/gh/git-gh-reachability.ts +11 -12
- package/scripts/gh/git-gh-repo.ts +2 -3
- package/scripts/gh/git-gh-rest-state.ts +1 -1
- package/scripts/gh/git-pr-ai-review.ts +6 -5
- package/scripts/gh/git-pr-checks-eval.ts +28 -30
- package/scripts/gh/git-pr-checks-parse.ts +14 -16
- package/scripts/gh/git-pr-checks-watch.ts +17 -17
- package/scripts/gh/git-pr-checks.ts +20 -23
- package/scripts/gh/git-pr-coderabbit.ts +8 -6
- package/scripts/gh/git-pr-confirmation.ts +5 -5
- package/scripts/gh/git-pr-managed-config.ts +7 -9
- package/scripts/gh/git-pr-messages.ts +1 -1
- package/scripts/gh/git-pr.ts +15 -16
- package/scripts/gh/github-issue-url.ts +8 -9
- package/scripts/git/base-tree.ts +66 -0
- package/scripts/git/change-base.ts +42 -2
- package/scripts/git/changed-file-scope.ts +5 -5
- package/scripts/git/changed-paths.ts +1 -2
- package/scripts/git/constants.ts +2 -2
- package/scripts/git/git-branch.ts +1 -1
- package/scripts/git/git-closes-keyword.ts +3 -3
- package/scripts/git/git-command.ts +53 -41
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +14 -15
- package/scripts/git/git-error.ts +1 -1
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/git/git-issue.ts +10 -8
- package/scripts/git/git-location-environment.ts +3 -4
- package/scripts/git/git-ls-remote.ts +6 -8
- package/scripts/git/git-pre-push-hook.ts +11 -10
- package/scripts/git/git-preflight.ts +5 -5
- package/scripts/git/git-push-transport.ts +2 -2
- package/scripts/git/git-remote-branch.ts +1 -2
- package/scripts/git/git-schemas.ts +16 -23
- package/scripts/git/git-spawn-sync.ts +1 -1
- package/scripts/git/git-spawn.ts +37 -14
- package/scripts/git/git-ssh-keepalive.ts +12 -5
- package/scripts/git/git-staging.ts +7 -8
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/git-worktree.ts +35 -27
- package/scripts/git/gone-branch.ts +2 -2
- package/scripts/git/listing-cutoff.ts +1 -2
- package/scripts/git/lockfile-sync.ts +65 -0
- package/scripts/git/main-merge-guard.ts +1 -2
- package/scripts/git/main-merge.ts +7 -7
- package/scripts/git/main-sync.ts +23 -8
- package/scripts/git/parse-json-array.ts +18 -23
- package/scripts/git/repository-lock.ts +34 -2
- package/scripts/git/stash/git-stash.ts +4 -5
- package/scripts/git/stash/stash-orphans.ts +5 -3
- package/scripts/git/stash/stash-pop-args.ts +1 -1
- package/scripts/git/stash/stash-pop-cli.ts +3 -3
- package/scripts/git/stash/stash-sweep-lock.ts +2 -2
- package/scripts/hooks/batch-guard.ts +11 -13
- package/scripts/hooks/check-commit-message.ts +12 -9
- package/scripts/hooks/codex-hook-adapter.ts +16 -10
- package/scripts/hooks/edited-cspell.ts +3 -4
- package/scripts/hooks/format-edited-cli.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +11 -17
- package/scripts/hooks/format-rewrite-notice.ts +19 -17
- package/scripts/hooks/pre-push-unit.ts +10 -14
- package/scripts/hooks/pretool-guard-cli.ts +4 -4
- package/scripts/hooks/pretool-guard.ts +93 -18
- package/scripts/hooks/reserved-run.ts +2 -2
- package/scripts/hooks/step-zero-notice.ts +1 -1
- package/scripts/hooks/stop-guard.ts +21 -10
- package/scripts/init/basic-path-migration.ts +2 -2
- package/scripts/init/claude-kit-only-settings.ts +2 -2
- package/scripts/init/claude-plugin-config.ts +2 -2
- package/scripts/init/distributed-paths.ts +4 -4
- package/scripts/init/hook-command-rewrite.ts +3 -3
- package/scripts/init/hook-launch.ts +5 -5
- package/scripts/init/init-actions.ts +13 -0
- package/scripts/init/init-ai-copy.ts +11 -11
- package/scripts/init/init-bootstrap.ts +3 -3
- package/scripts/init/init-copy-content.ts +4 -4
- package/scripts/init/init-logic-json-merge.ts +7 -9
- package/scripts/init/init-logic-migrate.ts +1 -1
- package/scripts/init/init-logic-templates.ts +1 -1
- package/scripts/init/init-logic-workspace.ts +4 -4
- package/scripts/init/init-logic-yaml-merge.ts +2 -2
- package/scripts/init/init-logic.ts +19 -22
- package/scripts/init/init.ts +12 -8
- package/scripts/init/kit-base-preset.ts +1 -1
- package/scripts/init/kit-setup-state.ts +1 -1
- package/scripts/init/kit-written-paths.ts +1 -2
- package/scripts/init/package-manager-pin.ts +35 -0
- package/scripts/init/project-profile-cli.ts +1 -1
- package/scripts/init/project-profile.ts +3 -3
- package/scripts/init/session-language-environment.ts +1 -1
- package/scripts/init/start-exec.ts +3 -4
- package/scripts/init/start-plan.ts +2 -2
- package/scripts/init/start-setup-pr.ts +3 -2
- package/scripts/init/start-steps.ts +2 -2
- package/scripts/init/tsconfig-preset-migration.ts +1 -1
- package/scripts/init/vscode-tasks.ts +62 -0
- package/scripts/issue/baseline-measure.ts +2 -2
- package/scripts/issue/behavior-change-lint.ts +2 -2
- package/scripts/issue/defect-rate-cli.ts +6 -7
- package/scripts/issue/defect-rate.ts +37 -27
- package/scripts/issue/git-next-issues.ts +9 -8
- package/scripts/issue/issue-auto-ok.ts +49 -11
- package/scripts/issue/issue-backlinks-cli.ts +5 -5
- package/scripts/issue/issue-backlinks.ts +6 -6
- package/scripts/issue/issue-cite-cli.ts +20 -18
- package/scripts/issue/issue-cite.ts +18 -8
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +6 -4
- package/scripts/issue/issue-file-cli.ts +75 -15
- package/scripts/issue/issue-file-fold.ts +155 -0
- package/scripts/issue/issue-file.ts +14 -6
- package/scripts/issue/issue-fold-cli.ts +14 -9
- package/scripts/issue/issue-fold.ts +23 -8
- package/scripts/issue/issue-labels.ts +46 -37
- package/scripts/issue/issue-lint-cli.ts +2 -2
- package/scripts/issue/issue-lint.ts +1 -1
- package/scripts/issue/issue-merged.ts +10 -4
- package/scripts/issue/issue-number-shape.ts +27 -0
- package/scripts/issue/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +4 -5
- package/scripts/issue/issue-read.ts +4 -5
- package/scripts/issue/issue-reference.ts +5 -5
- package/scripts/issue/issue-release-cli.ts +165 -0
- package/scripts/issue/issue-release.ts +58 -0
- package/scripts/issue/issue-report-failures.ts +7 -4
- package/scripts/issue/issue-scout-cli.ts +11 -11
- package/scripts/issue/issue-scout-closed.ts +4 -4
- package/scripts/issue/issue-scout.ts +4 -5
- package/scripts/issue/issue-state-cli.ts +17 -10
- package/scripts/issue/issue-state.ts +12 -13
- package/scripts/issue/issue-wip.ts +7 -7
- package/scripts/issue/markdown-section.ts +3 -3
- package/scripts/issue/measure-rerun-cli.ts +10 -9
- package/scripts/issue/reproduction-measure.ts +3 -3
- package/scripts/issue/session-cite.ts +56 -0
- package/scripts/josh/agent-session-environment.ts +10 -8
- package/scripts/josh/cli-body.ts +2 -2
- package/scripts/josh/command-suggest.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +20 -23
- package/scripts/josh/hook-decision.ts +24 -28
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +32 -34
- package/scripts/josh/josh-commands-ai.ts +6 -6
- package/scripts/josh/josh-commands-backlog.ts +15 -3
- package/scripts/josh/josh-commands-clone.ts +1 -1
- package/scripts/josh/josh-commands-development.ts +33 -4
- package/scripts/josh/josh-commands-document.ts +3 -3
- package/scripts/josh/josh-commands-guard.ts +3 -3
- package/scripts/josh/josh-commands-issue.ts +11 -5
- package/scripts/josh/josh-commands-lane.ts +16 -5
- package/scripts/josh/josh-commands-lint.ts +1 -1
- package/scripts/josh/josh-commands-maintenance.ts +2 -2
- package/scripts/josh/josh-commands-run.ts +20 -6
- package/scripts/josh/josh-commands-split.ts +1 -2
- package/scripts/josh/josh-commands-versioning.ts +5 -5
- package/scripts/josh/josh-commands-workflow.ts +30 -22
- package/scripts/josh/josh-environment-file.ts +1 -1
- package/scripts/josh/josh-in-process.ts +3 -3
- package/scripts/josh/josh-logic.ts +10 -10
- package/scripts/josh/josh-run.ts +3 -3
- package/scripts/josh/josh-verdict.ts +9 -12
- package/scripts/josh/josh.ts +3 -3
- package/scripts/josh/kit-only.ts +2 -2
- package/scripts/josh/path-decision.ts +3 -3
- package/scripts/josh/platform-temporary.ts +7 -5
- package/scripts/josh/process-identity.ts +24 -6
- package/scripts/josh/process-owner.ts +4 -4
- package/scripts/josh/session-language-cli.ts +53 -11
- package/scripts/josh/session-language.ts +1 -1
- package/scripts/josh/stamp-file.ts +48 -29
- package/scripts/josh/stamp-record.ts +57 -0
- package/scripts/lane/lane-await.ts +35 -11
- package/scripts/lane/lane-cache.ts +6 -6
- package/scripts/lane/lane-capacity.ts +32 -17
- package/scripts/lane/lane-child-invocation.ts +17 -15
- package/scripts/lane/lane-child-marker.ts +12 -12
- package/scripts/lane/lane-cli.ts +20 -13
- package/scripts/lane/lane-close.ts +6 -6
- package/scripts/lane/lane-dispatch.ts +61 -72
- package/scripts/lane/lane-environment.ts +5 -5
- package/scripts/lane/lane-guard-policy.ts +7 -21
- package/scripts/lane/lane-handoff.ts +2 -2
- package/scripts/lane/lane-install.ts +9 -10
- package/scripts/lane/lane-launch-cli.ts +13 -8
- package/scripts/lane/lane-ledger.ts +73 -11
- package/scripts/lane/lane-leftover.ts +44 -30
- package/scripts/lane/lane-limit-cli.ts +160 -0
- package/scripts/lane/lane-limit-override.ts +74 -0
- package/scripts/lane/lane-load.ts +19 -68
- package/scripts/lane/lane-measure-cli.ts +15 -25
- package/scripts/lane/lane-occupancy.ts +6 -4
- package/scripts/lane/lane-open.ts +25 -24
- package/scripts/lane/lane-output.ts +4 -3
- package/scripts/lane/lane-paths.ts +22 -8
- package/scripts/lane/lane-phase.ts +33 -0
- package/scripts/lane/lane-reap.ts +2 -2
- package/scripts/lane/lane-registry.ts +27 -15
- package/scripts/lane/lane-relaunch.ts +9 -9
- package/scripts/lane/lane-report.ts +5 -4
- package/scripts/lane/lane-resume.ts +2 -2
- package/scripts/lane/lane-sampler.ts +55 -0
- package/scripts/lane/lane-seed.ts +7 -7
- package/scripts/lane/lane-stage-stats.ts +135 -0
- package/scripts/lane/lane-start-point.ts +8 -11
- package/scripts/lane/lane-stats.ts +60 -15
- package/scripts/lane/lane-stray.ts +140 -0
- package/scripts/lane/lane-vacant.ts +1 -1
- package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
- package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
- package/scripts/lane/openai-review-broker.ts +2 -4
- package/scripts/lib/ancestor-directories.ts +1 -1
- package/scripts/lib/bounded-pool.ts +2 -2
- package/scripts/lib/buffered-process.ts +4 -6
- package/scripts/lib/caddy-logs.sh +0 -0
- package/scripts/lib/cli-flags.ts +39 -6
- package/scripts/lib/error-message.ts +1 -1
- package/scripts/lib/json-value.ts +17 -3
- package/scripts/lib/poll.ts +1 -1
- package/scripts/lib/status-icons.ts +3 -3
- package/scripts/lib/timed-fetch.ts +1 -1
- package/scripts/lib/timeouts.ts +1 -1
- package/scripts/lines/bytes-command.ts +3 -4
- package/scripts/lines/effective-limit.ts +25 -12
- package/scripts/lines/line-budget.ts +47 -55
- package/scripts/lines/line-targets.ts +6 -2
- package/scripts/lines/lines-command.ts +3 -3
- package/scripts/lint/cspell-cached.ts +1 -1
- package/scripts/lint/cycle-recheck.ts +122 -0
- package/scripts/lint/format.ts +1 -2
- package/scripts/lint/lint-parallel.ts +34 -19
- package/scripts/lint/lint-related-scope.ts +25 -15
- package/scripts/lint/lint-related.ts +6 -7
- package/scripts/managed-marker/index.ts +1 -1
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/git-notify.ts +9 -7
- package/scripts/notify/telegram-notify.ts +53 -37
- package/scripts/notify/telegram-test-logic.ts +3 -3
- package/scripts/notify/telegram-test.ts +45 -30
- package/scripts/observations/observation-ledger-home.ts +14 -8
- package/scripts/observations/observation-ledger-line.ts +3 -2
- package/scripts/observations/observation-ledger-migrate.ts +3 -4
- package/scripts/observations/observation-ledger-prepare.ts +4 -4
- package/scripts/observations/observation-ledger.ts +14 -15
- package/scripts/observations/observation-record-cli.ts +83 -0
- package/scripts/observations/observation-record.ts +91 -0
- package/scripts/observations/observations-flush-cli.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +7 -6
- package/scripts/observations/observations-flush.ts +26 -27
- package/scripts/overrides/overrides-check.ts +18 -8
- package/scripts/package/package-scout-cli.ts +1 -1
- package/scripts/package/package-scout-format.ts +2 -2
- package/scripts/package/package-scout.ts +1 -1
- package/scripts/propagate/propagate-git-failure.ts +1 -1
- package/scripts/propagate/propagate-git.ts +7 -7
- package/scripts/propagate/propagate-plan.ts +2 -2
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +5 -7
- package/scripts/propagate/propagate-select.ts +1 -1
- package/scripts/propagate/propagate-steps.ts +19 -20
- package/scripts/propagate/propagate-targets.ts +6 -10
- package/scripts/propagate/propagate.ts +5 -5
- package/scripts/refactor/import-graph.ts +1 -1
- package/scripts/refactor/refactor-lint.ts +4 -10
- package/scripts/refactor/refactor-scan-cli.ts +1 -1
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +1 -1
- package/scripts/release/github-release-cli.ts +25 -3
- package/scripts/release/github-release-environment.ts +1 -0
- package/scripts/release/github-release-runs.ts +115 -0
- package/scripts/release/github-release.ts +13 -67
- package/scripts/release/release-cli.ts +21 -4
- package/scripts/release/release-history.ts +6 -10
- package/scripts/release/release-plan.ts +3 -3
- package/scripts/release/release-progress.ts +3 -4
- package/scripts/release/release-publish.ts +8 -9
- package/scripts/release/release-scope-cli.ts +8 -10
- package/scripts/release/release-tag.ts +6 -8
- package/scripts/release/release-worktree.ts +5 -5
- package/scripts/repo/auto-merge-setting-logic.ts +7 -9
- package/scripts/repo/auto-merge-setting.ts +1 -1
- package/scripts/repo/repo-setting.ts +4 -4
- package/scripts/repo/repository-labels.ts +1 -1
- package/scripts/repo/required-checks-logic.ts +3 -3
- package/scripts/repo/required-checks-report.ts +1 -1
- package/scripts/repo/ruleset-check-cli.ts +1 -1
- package/scripts/repo/ruleset-check.ts +1 -1
- package/scripts/report/report-format-reference.ts +26 -0
- package/scripts/report/report-lint-cli.ts +2 -2
- package/scripts/report/report-lint.ts +16 -2
- package/scripts/review/disposition-cli.ts +2 -2
- package/scripts/review/disposition-logic.ts +1 -1
- package/scripts/review/live-evidence.ts +9 -6
- package/scripts/review/review-attest-cli.ts +1 -2
- package/scripts/review/review-attest.ts +3 -3
- package/scripts/review/review-brief-cli.ts +19 -20
- package/scripts/review/review-brief.ts +29 -32
- package/scripts/review/review-checkout.ts +2 -2
- package/scripts/review/review-diff-parts.ts +3 -5
- package/scripts/review/review-diff-write.ts +1 -1
- package/scripts/review/review-finding-ledger.ts +7 -4
- package/scripts/review/review-findings-cli.ts +2 -2
- package/scripts/review/review-level.ts +4 -7
- package/scripts/review/review-record-cli.ts +73 -16
- package/scripts/review/review-record.ts +5 -4
- package/scripts/review/review-round2-cli.ts +2 -3
- package/scripts/review/review-round2.ts +13 -21
- package/scripts/review/review-stamps.ts +9 -71
- package/scripts/review/review-tree.ts +4 -5
- package/scripts/rules/bash-triggers.ts +4 -4
- package/scripts/rules/decision-oracle-batch.ts +5 -6
- package/scripts/rules/decision-oracle-stage.ts +1 -1
- package/scripts/rules/decision-oracle-tokens.ts +1 -2
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +61 -406
- package/scripts/rules/destructive-command.ts +2 -2
- package/scripts/rules/direct-filing.ts +4 -4
- package/scripts/rules/direct-pr-create.ts +2 -2
- package/scripts/rules/early-heartbeat.ts +15 -19
- package/scripts/rules/file-body.ts +5 -6
- package/scripts/rules/filing-cap.ts +6 -7
- package/scripts/rules/filing-offer.ts +1 -1
- package/scripts/rules/firing-point.ts +6 -6
- package/scripts/rules/gh-api.ts +2 -2
- package/scripts/rules/git-argv.ts +3 -3
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/hook-context-line.ts +31 -0
- package/scripts/rules/implementation-cut-verdict.ts +5 -8
- package/scripts/rules/implementation-cut.ts +35 -32
- package/scripts/rules/index-guard.ts +2 -2
- package/scripts/rules/issue-citation.ts +7 -7
- package/scripts/rules/issue-comments.ts +21 -13
- package/scripts/rules/josh-git-bare.ts +2 -2
- package/scripts/rules/lane-background.ts +14 -16
- package/scripts/rules/lane-carry-conflict.ts +41 -5
- package/scripts/rules/lane-interactive-ask.ts +6 -9
- package/scripts/rules/lane-park.ts +12 -16
- package/scripts/rules/lane-split-park.ts +1 -2
- package/scripts/rules/lane-switch-main.ts +10 -13
- package/scripts/rules/last-prompt.ts +1 -1
- package/scripts/rules/oracle-consulted.ts +5 -5
- package/scripts/rules/oracle-firing.ts +6 -9
- package/scripts/rules/oracle-list-cli.ts +2 -2
- package/scripts/rules/permission-guards.ts +2 -2
- package/scripts/rules/piped-verification.ts +79 -9
- package/scripts/rules/poll-loop.ts +9 -11
- package/scripts/rules/pre-gate-cut.ts +33 -30
- package/scripts/rules/prior-comment-read.ts +3 -3
- package/scripts/rules/protected-files.ts +25 -13
- package/scripts/rules/raw-field-body.ts +3 -4
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +10 -12
- package/scripts/rules/rule-guard.ts +1 -1
- package/scripts/rules/rule-list.ts +51 -0
- package/scripts/rules/rule-registry-rows.ts +282 -0
- package/scripts/rules/rule-registry.ts +109 -0
- package/scripts/rules/rule-value-cache.ts +2 -2
- package/scripts/rules/rule-value-cli.ts +6 -4
- package/scripts/rules/rule-value.ts +61 -22
- package/scripts/rules/run-tail-rule.ts +11 -15
- package/scripts/rules/shell-body-trigger.ts +7 -7
- package/scripts/rules/shell-segments.ts +2 -4
- package/scripts/rules/stop-rules.ts +54 -41
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +2 -2
- package/scripts/rules/third-party-write.ts +3 -3
- package/scripts/rules/worktree-guard.ts +12 -5
- package/scripts/run/add/run-add-cli.ts +165 -0
- package/scripts/run/add/run-add.ts +124 -0
- package/scripts/run/board/run-board-cli.ts +207 -0
- package/scripts/run/board/run-board-closed.ts +95 -0
- package/scripts/run/board/run-board-every.ts +60 -0
- package/scripts/run/board/run-board-fetch.ts +38 -0
- package/scripts/run/board/run-board-fit.ts +219 -0
- package/scripts/run/board/run-board-github.ts +162 -0
- package/scripts/run/board/run-board-header.ts +275 -0
- package/scripts/run/board/run-board-kind.ts +35 -0
- package/scripts/run/board/run-board-labels.ts +299 -0
- package/scripts/run/board/run-board-layout.ts +222 -0
- package/scripts/run/board/run-board-link.ts +31 -0
- package/scripts/run/board/run-board-machine.ts +198 -0
- package/scripts/run/board/run-board-notes.ts +103 -0
- package/scripts/run/board/run-board-phase.ts +136 -0
- package/scripts/run/board/run-board-plan.ts +129 -0
- package/scripts/run/board/run-board-read.ts +62 -0
- package/scripts/run/board/run-board-render-legend.ts +82 -0
- package/scripts/run/board/run-board-render-notes.ts +77 -0
- package/scripts/run/board/run-board-render-slot.ts +50 -0
- package/scripts/run/board/run-board-render.ts +407 -0
- package/scripts/run/board/run-board-scope.ts +17 -0
- package/scripts/run/board/run-board-screen.ts +43 -0
- package/scripts/run/board/run-board-span.ts +66 -0
- package/scripts/run/board/run-board-spin.ts +115 -0
- package/scripts/run/board/run-board-state.ts +113 -0
- package/scripts/run/board/run-board-status.ts +279 -0
- package/scripts/run/board/run-board-tick.ts +210 -0
- package/scripts/run/board/run-board-track.ts +22 -0
- package/scripts/run/board/run-board-usage-read.ts +255 -0
- package/scripts/run/board/run-board-usage-rusage.ts +124 -0
- package/scripts/run/board/run-board-usage-text.ts +80 -0
- package/scripts/run/board/run-board-usage.ts +165 -0
- package/scripts/run/carry/run-carry-added.ts +62 -0
- package/scripts/run/carry/run-carry-args.ts +25 -22
- package/scripts/run/carry/run-carry-change.ts +1 -1
- package/scripts/run/carry/run-carry-cli.ts +71 -48
- package/scripts/run/carry/run-carry-conversation.ts +6 -7
- package/scripts/run/carry/run-carry-ended.ts +85 -0
- package/scripts/run/carry/run-carry-reclaim.ts +1 -1
- package/scripts/run/carry/run-carry-stash.ts +3 -2
- package/scripts/run/carry/run-carry-streak.ts +8 -10
- package/scripts/run/carry/run-carry.ts +85 -89
- package/scripts/run/cut/run-cut-args.ts +7 -7
- package/scripts/run/cut/run-cut-cli.ts +68 -37
- package/scripts/run/cut/run-cut-handoff.ts +15 -15
- package/scripts/run/cut/run-cut-report.ts +37 -16
- package/scripts/run/cut/run-cut.ts +63 -77
- package/scripts/run/detached-launch.ts +35 -50
- package/scripts/run/entry/run-entry-cli.ts +48 -27
- package/scripts/run/entry/run-entry-stop.ts +7 -9
- package/scripts/run/entry/run-entry.ts +5 -6
- package/scripts/run/event/run-event-cli.ts +5 -6
- package/scripts/run/event/run-event-filed.ts +69 -0
- package/scripts/run/event/run-event-follow.ts +3 -3
- package/scripts/run/event/run-event-plan.ts +38 -0
- package/scripts/run/event/run-event-render.ts +10 -4
- package/scripts/run/event/run-event-scope.ts +47 -18
- package/scripts/run/event/run-event-stream-emit.ts +64 -11
- package/scripts/run/event/run-event-stream.ts +172 -43
- package/scripts/run/event/run-event-watch.ts +4 -6
- package/scripts/run/hold/run-hold-cli.ts +65 -62
- package/scripts/run/hold/run-hold.ts +88 -46
- package/scripts/run/merge/run-merge-cli.ts +116 -77
- package/scripts/run/merge/run-merge-collect.ts +107 -0
- package/scripts/run/merge/run-merge-steps.ts +112 -65
- package/scripts/run/merge/run-merge-token.ts +30 -0
- package/scripts/run/merge/run-merge.ts +31 -22
- package/scripts/run/progress/run-progress-args.ts +4 -4
- package/scripts/run/progress/run-progress-cli.ts +39 -50
- package/scripts/run/progress/run-progress-clock.ts +25 -32
- package/scripts/run/progress/run-progress-config.ts +6 -9
- package/scripts/run/progress/run-progress-read.ts +9 -10
- package/scripts/run/progress/run-progress.ts +48 -53
- package/scripts/run/review/run-review-cli.ts +6 -6
- package/scripts/run/review/run-review-steps.ts +6 -6
- package/scripts/run/review/run-review.ts +9 -11
- package/scripts/run/run-cli-fault.ts +29 -0
- package/scripts/run/run-ending-cli.ts +3 -3
- package/scripts/run/run-ending.ts +10 -14
- package/scripts/run/run-halfrun-resume.ts +6 -8
- package/scripts/run/run-headless.ts +25 -12
- package/scripts/run/run-invocation.ts +17 -22
- package/scripts/run/run-label.ts +7 -5
- package/scripts/run/run-liveness-cli.ts +19 -6
- package/scripts/run/run-liveness.ts +27 -38
- package/scripts/run/run-next-cli.ts +5 -9
- package/scripts/run/run-next.ts +4 -5
- package/scripts/run/run-parent-cut-hook.ts +10 -12
- package/scripts/run/run-preflight.ts +25 -29
- package/scripts/run/run-prep-cli.ts +17 -13
- package/scripts/run/run-prep-locate.ts +4 -5
- package/scripts/run/run-prep.ts +7 -10
- package/scripts/run/run-prrun-resume.ts +2 -2
- package/scripts/run/run-report-cli.ts +4 -4
- package/scripts/run/run-report.ts +9 -14
- package/scripts/run/run-retrospective.ts +3 -3
- package/scripts/run/run-section.ts +42 -0
- package/scripts/run/run-stage-read.ts +2 -2
- package/scripts/run/run-stage.ts +6 -4
- package/scripts/run/run-status-cli.ts +7 -5
- package/scripts/run/run-status.ts +6 -7
- package/scripts/run/run-step-cli.ts +13 -15
- package/scripts/run/run-step.ts +62 -48
- package/scripts/run/run-stop-notify.ts +7 -8
- package/scripts/run/run-stranded-cli.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +4 -4
- package/scripts/run/run-stranded.ts +11 -13
- package/scripts/run/run-tail-cli.ts +15 -16
- package/scripts/run/run-tail.ts +14 -33
- package/scripts/run/run-watcher-guard-cli.ts +3 -4
- package/scripts/run/run-watcher-guard.ts +11 -12
- package/scripts/run/run-watcher-hook.ts +6 -12
- package/scripts/run/ship/run-ship-cli.ts +67 -33
- package/scripts/run/ship/run-ship-detach.ts +15 -13
- package/scripts/run/ship/run-ship-lock.ts +1 -1
- package/scripts/run/ship/run-ship-next.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
- package/scripts/run/ship/run-ship-preflight.ts +10 -11
- package/scripts/run/ship/run-ship-probe.ts +4 -4
- package/scripts/run/ship/run-ship-return.ts +1 -1
- package/scripts/run/ship/run-ship-review-steps.ts +43 -24
- package/scripts/run/ship/run-ship-review.ts +12 -14
- package/scripts/run/ship/run-ship-scoped.ts +15 -6
- package/scripts/run/ship/run-ship-stage.ts +80 -26
- package/scripts/run/ship/run-ship-steps.ts +26 -16
- package/scripts/run/ship/run-ship-stop-text.ts +4 -2
- package/scripts/run/ship/run-ship-sync.ts +9 -8
- package/scripts/run/ship/run-ship.ts +17 -32
- package/scripts/run/tidy/run-tidy-cli.ts +9 -5
- package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
- package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
- package/scripts/run/tidy/run-tidy.ts +4 -3
- package/scripts/run/wake/run-wake-cli.ts +27 -33
- package/scripts/run/wake/run-wake-describe.ts +76 -29
- package/scripts/run/wake/run-wake-driver.ts +14 -14
- package/scripts/run/wake/run-wake-handoff.ts +6 -6
- package/scripts/run/wake/run-wake-loop.ts +13 -21
- package/scripts/run/wake/run-wake-restart.ts +4 -5
- package/scripts/run/wake/run-wake-session.ts +23 -27
- package/scripts/run/wake/run-wake.ts +57 -328
- package/scripts/safe-chain/ci-installer-pin.ts +3 -3
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -2
- package/scripts/security/security-audit-logic.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +1 -1
- package/scripts/security/security-audit-provision.ts +2 -2
- package/scripts/security/security-audit.ts +5 -5
- package/scripts/security/security-updates-logic.ts +2 -3
- package/scripts/security/security-updates.ts +2 -4
- package/scripts/self-sync-guard/index.ts +1 -1
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
- package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
- package/scripts/sonar/sonar-hotspots.ts +1 -1
- package/scripts/sonar/sonar-new-code-cli.ts +1 -1
- package/scripts/sonar/sonar-new-code.ts +1 -1
- package/scripts/sonar/sonar-project.ts +1 -1
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +3 -3
- package/scripts/sync/directory-copy-guard.ts +2 -3
- package/scripts/sync/managed-config-scope-cli.ts +1 -2
- package/scripts/sync/managed-config-scope.ts +4 -4
- package/scripts/sync/plugin-skill-directories.ts +2 -2
- package/scripts/sync/reconcile-templates.ts +17 -8
- package/scripts/sync/removed-skill-manifest.ts +2 -3
- package/scripts/sync/sync-ai-files.ts +7 -7
- package/scripts/sync/sync-configs.ts +30 -3
- package/scripts/sync/sync-hook-safety.ts +2 -2
- package/scripts/sync/sync.ts +23 -10
- package/scripts/sync/synced-paths.ts +2 -1
- package/scripts/sync/workflow-pin-logic.ts +1 -1
- package/scripts/test/test-declared-changed.ts +4 -4
- package/scripts/test/test-declared-logic.ts +2 -3
- package/scripts/test/test-declared-match.ts +25 -4
- package/scripts/test/test-declared.ts +26 -9
- package/scripts/test/test-red-commit.ts +3 -2
- package/scripts/test/test-red-logic.ts +7 -14
- package/scripts/test/test-red.ts +12 -47
- package/scripts/test/test-related-scope.ts +2 -3
- package/scripts/test/test-related.ts +3 -3
- package/scripts/test/test-type-logic.ts +1 -2
- package/scripts/test/test-unit-guard.ts +13 -17
- package/scripts/test/unit-worker-share.ts +7 -8
- package/scripts/time-runtime/time-agent-bundles.ts +2 -4
- package/scripts/time-runtime/time-background.ts +17 -21
- package/scripts/time-runtime/time-batch-guard.ts +67 -342
- package/scripts/time-runtime/time-bundle-call.ts +26 -28
- package/scripts/time-runtime/time-bundles.ts +11 -12
- package/scripts/time-runtime/time-call-identity.ts +1 -1
- package/scripts/time-runtime/time-command-key.ts +2 -2
- package/scripts/time-runtime/time-density-hook.ts +8 -11
- package/scripts/time-runtime/time-density.ts +5 -5
- package/scripts/time-runtime/time-followup-stage.ts +7 -7
- package/scripts/time-runtime/time-format.ts +5 -5
- package/scripts/time-runtime/time-hook-transcript.ts +3 -3
- package/scripts/time-runtime/time-instant.ts +1 -1
- package/scripts/time-runtime/time-markers.ts +15 -19
- package/scripts/time-runtime/time-phase-names.ts +3 -3
- package/scripts/time-runtime/time-reported-failure.ts +15 -19
- package/scripts/time-runtime/time-round-trips.ts +20 -23
- package/scripts/time-runtime/time-shell.ts +8 -8
- package/scripts/time-runtime/time-single-check.ts +1 -2
- package/scripts/time-runtime/time-spans.ts +35 -40
- package/scripts/time-runtime/time-tool-call.ts +15 -16
- package/scripts/time-runtime/time-transcript-line.ts +53 -34
- package/scripts/time-runtime/time-writes.ts +5 -5
- package/scripts/ui/ui-routes-cli.ts +1 -2
- package/scripts/ui/ui-routes.ts +1 -2
- package/scripts/version/bump-version.ts +1 -1
- package/scripts/version/fresh-metadata-cache.ts +2 -2
- package/scripts/version/latest-corepack.ts +129 -98
- package/scripts/version/latest-lane-guard.ts +1 -1
- package/scripts/version/latest-scope-cli.ts +2 -2
- package/scripts/version/latest-stamp.ts +1 -2
- package/scripts/version/latest-update.ts +2 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/package-manager-version.ts +18 -0
- package/scripts/version/publishable-range-check.ts +2 -1
- package/scripts/version/publishable-range.ts +1 -1
- package/scripts/version/release-age.ts +11 -11
- package/scripts/version/release-hold.ts +2 -2
- package/scripts/version/safe-chain-version-update.ts +3 -3
- package/scripts/version/version-check-logic.ts +2 -3
- package/scripts/version/version-check.ts +1 -2
- package/scripts/version/version-command-config.ts +2 -2
- package/scripts/version/version-commands.ts +3 -3
- package/scripts/version/version-remote.ts +4 -4
- package/scripts/version/version-targets.ts +2 -2
- package/templates/gitignore +7 -0
- package/templates/workflows/github-release.yml +4 -0
- package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
- package/dist/hooks/chunk-RKUAD3I6.js +0 -90
- package/dist/hooks/chunk-WPALEIRX.js +0 -18
- package/scripts/backlog/backlog-restructure.ts +0 -152
- package/scripts/rules/issue-fold-rule.ts +0 -72
- package/scripts/rules/wip-cap.ts +0 -63
- package/scripts/run/run-issue-number.ts +0 -19
|
@@ -10,20 +10,20 @@ interface MissingData {
|
|
|
10
10
|
malformed_lines: number
|
|
11
11
|
unreadable_sessions: number
|
|
12
12
|
// Delegated units whose owning session's issue could not be determined, so their cost is charged
|
|
13
|
-
// to no issue at all
|
|
13
|
+
// to no issue at all. Filled by the attribution, which is the only step
|
|
14
14
|
// that knows a unit could not follow its parent; zero from a per-session tally.
|
|
15
15
|
unattributed_sessions: number
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
// The corpus of a project's session transcripts, and how each request in it attributes to an issue
|
|
19
|
-
//
|
|
18
|
+
// The corpus of a project's session transcripts, and how each request in it attributes to an issue.
|
|
19
|
+
// Split out of `cost-cli.ts` when that file passed
|
|
20
20
|
// its length limit: the CLI parses flags and prints reports, and this is the reading underneath every
|
|
21
21
|
// scope it prints — the same walk `josh time`'s phase costs read through `cost_cli.attributed`.
|
|
22
22
|
|
|
23
23
|
interface Corpus {
|
|
24
24
|
sessions: Array<SessionUsage>
|
|
25
25
|
// Kept beside the sessions so the whole-session scope can re-read its transcript for the two
|
|
26
|
-
// decompositions
|
|
26
|
+
// decompositions. Parsed lazily and only for that one file: classifying
|
|
27
27
|
// the content blocks of all 158 transcripts to print one issue's cost would be work nothing reads.
|
|
28
28
|
files: Array<SessionFile>
|
|
29
29
|
missing: MissingData
|
|
@@ -59,7 +59,7 @@ interface AttributedRecord {
|
|
|
59
59
|
baseline_tokens: number
|
|
60
60
|
// The session this record was read from, and whether that session is a delegated unit. The cost
|
|
61
61
|
// curve is built from the non-delegated (main-line) sessions' records alone, so it needs both to
|
|
62
|
-
// group an issue's records back by session and drop the units
|
|
62
|
+
// group an issue's records back by session and drop the units.
|
|
63
63
|
session_id: string
|
|
64
64
|
is_delegated: boolean
|
|
65
65
|
}
|
|
@@ -82,7 +82,7 @@ function session_meta(corpus: Corpus): Map<string, SessionMeta> {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
// Every distinct issue a session's own records attribute to. A delegated unit reads this from the
|
|
85
|
-
// session that delegated it
|
|
85
|
+
// session that delegated it: a `fullrun`'s parent names exactly one, so its
|
|
86
86
|
// units follow it; a parent that ran several names them all, and its unattributed unit could belong to
|
|
87
87
|
// any of them.
|
|
88
88
|
function issue_set(records: ReadonlyArray<UsageRecord>): Set<number> {
|
|
@@ -116,7 +116,7 @@ function owner_sets(
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// A session's records, each tagged with the issue its own branch names — and, for a delegated unit,
|
|
119
|
-
// the parent's sole issue substituted wherever the branch named none
|
|
119
|
+
// the parent's sole issue substituted wherever the branch named none. A child
|
|
120
120
|
// that committed carries its own `<N>-` branch exactly as a top-level session does, so it attributes
|
|
121
121
|
// by its own records; only a sub-step that never commits — a review, a survey — carries `main`
|
|
122
122
|
// throughout and falls to the inherited issue. `inherited` is `UNATTRIBUTED_KEY` for a non-delegated
|
|
@@ -183,8 +183,8 @@ interface CorpusAttribution {
|
|
|
183
183
|
unattributed: Array<ReadonlySet<number>>
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
// Attribution across the whole corpus, delegated units followed to the session that delegated them
|
|
187
|
-
//
|
|
186
|
+
// Attribution across the whole corpus, delegated units followed to the session that delegated them.
|
|
187
|
+
// The fill-forward walk itself is untouched — a unit is tagged with its
|
|
188
188
|
// parent's issue and a non-delegated session keeps `group_by_issue` exactly as before — so
|
|
189
189
|
// `josh cost --issue` and `josh time`'s phase costs, which both read this, stay in step.
|
|
190
190
|
function attribute_corpus(corpus: Corpus): CorpusAttribution {
|
|
@@ -249,8 +249,8 @@ function attributed(corpus: Corpus): Array<AttributedRecord> {
|
|
|
249
249
|
|
|
250
250
|
// The in-scope records of each non-delegated (main-line) session, grouped and kept in the order they
|
|
251
251
|
// were read. The curve is built from these: a delegated unit starts from low context, so mixing its
|
|
252
|
-
// records into the positional quartiles breaks the growth curve a hand-off decision reads
|
|
253
|
-
//
|
|
252
|
+
// records into the positional quartiles breaks the growth curve a hand-off decision reads.
|
|
253
|
+
// A single-issue run on one session yields one group; a run resumed in a
|
|
254
254
|
// second session yields two, which the curve then withholds rather than mixing.
|
|
255
255
|
function mainline_records(pairs: ReadonlyArray<AttributedRecord>): Array<Array<UsageRecord>> {
|
|
256
256
|
const groups = new Map<string, Array<UsageRecord>>()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cost_usage, type UsageTotals } from './cost-usage'
|
|
2
2
|
|
|
3
3
|
// The current Claude price list, and the three multipliers that make a token's price depend on how
|
|
4
|
-
// it was sent
|
|
4
|
+
// it was sent.
|
|
5
5
|
//
|
|
6
6
|
// A run's cost is not "tokens x one rate". A cache read costs a tenth of base input, a 5-minute
|
|
7
7
|
// cache write 1.25x, a 1-hour cache write 2x, and output 5x. On a measured request with
|
|
@@ -44,7 +44,7 @@ const CONTEXT_MARKER = '['
|
|
|
44
44
|
// to its longest prefix that the table knows rather than reported as unknown.
|
|
45
45
|
//
|
|
46
46
|
// The `[1m]` marker is the 1M-context beta, and stripping it to the base rate is confirmed correct,
|
|
47
|
-
// not an approximation
|
|
47
|
+
// not an approximation. The published price list — platform.claude.com
|
|
48
48
|
// "Long context pricing", read 2026-09 — states that Claude 4.6 and later models "include the full
|
|
49
49
|
// 1M token context window at standard pricing (a 900k-token request is billed at the same per-token
|
|
50
50
|
// rate as a 9k-token request)". Every id in `MODEL_PRICES` is 4.6-or-later, so no request has an
|
|
@@ -76,7 +76,7 @@ function estimate_cost(totals: UsageTotals, price: ModelPrice): number {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// The five dollar terms `estimate_cost` sums, kept apart so a report can say what a run's dollars
|
|
79
|
-
// were spent on rather than only their total
|
|
79
|
+
// were spent on rather than only their total. Each is priced by the same
|
|
80
80
|
// multipliers `estimate_cost` uses — the exported constants above — so the five always sum to
|
|
81
81
|
// `estimate_cost(totals, price)`. It is a decomposition of the same arithmetic, not a second price
|
|
82
82
|
// list, which is why the weights live in the constants both read rather than in either function.
|
|
@@ -154,7 +154,7 @@ function total_cost(costs: ReadonlyArray<ModelCost>): { usd: number; unpriced: A
|
|
|
154
154
|
|
|
155
155
|
// The priced total in dollars, discarding the unpriced-model list — the one-line composition of
|
|
156
156
|
// `total_cost` over `cost_by_model` that callers reach for when they need only the number, kept here
|
|
157
|
-
// so it is not spelled out at each call site
|
|
157
|
+
// so it is not spelled out at each call site.
|
|
158
158
|
function cost_of(records: ReadonlyArray<ModelUsage>): number {
|
|
159
159
|
return total_cost(cost_by_model(records)).usd
|
|
160
160
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
// Estimating tokens for the parts of the context the transcript records as text
|
|
2
|
-
// (joshuafolkken/kit#1151).
|
|
1
|
+
// Estimating tokens for the parts of the context the transcript records as text.
|
|
3
2
|
//
|
|
4
3
|
// **Why an estimate exists at all.** The transcript reports real token counts for exactly two
|
|
5
4
|
// things: what each request was billed, and how many of a response's output tokens were thinking.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { readdirSync, readFileSync, statSync } from 'node:fs'
|
|
2
2
|
import { homedir } from 'node:os'
|
|
3
3
|
import path from 'node:path'
|
|
4
|
+
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
4
5
|
import { lane_paths } from '#scripts/lane/lane-paths'
|
|
5
6
|
import { file_reader } from '#scripts/lib/read-file'
|
|
6
7
|
import { cost_usage, type UsageRecord } from './cost-usage'
|
|
7
8
|
|
|
8
|
-
// Finding and reading Claude Code's session transcripts
|
|
9
|
+
// Finding and reading Claude Code's session transcripts.
|
|
9
10
|
//
|
|
10
11
|
// They live at `~/.claude/projects/<slug>/<session-id>.jsonl`, where the slug is the working
|
|
11
12
|
// directory with every character that is not a letter, digit or hyphen turned into a hyphen.
|
|
@@ -23,7 +24,7 @@ const TRANSCRIPT_ROOT = path.join('.claude', 'projects')
|
|
|
23
24
|
const TRANSCRIPT_EXTENSION = '.jsonl'
|
|
24
25
|
const SLUG_PATTERN = /[^a-zA-Z0-9-]/gu
|
|
25
26
|
|
|
26
|
-
// Where a delegated unit's transcript is written
|
|
27
|
+
// Where a delegated unit's transcript is written.
|
|
27
28
|
//
|
|
28
29
|
// `epicrun` and `queue` run each child in a delegated unit, and `gate-fix` / `survey` delegate one
|
|
29
30
|
// step of a run. **None of that lands beside the session's own transcript**: the unit writes to
|
|
@@ -45,7 +46,7 @@ function transcript_directory(cwd: string, home: string = homedir()): string {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
// The checkout a session's transcripts are filed under, which is not always the one a command runs
|
|
48
|
-
// in
|
|
49
|
+
// in.
|
|
49
50
|
//
|
|
50
51
|
// **A lane is a checkout no session ever ran in.** `epicrun` gives each child a linked work tree and
|
|
51
52
|
// the child prefixes every command with it, but the Claude session itself stays in the main checkout
|
|
@@ -100,7 +101,7 @@ function read_directory(directory: string): Array<string> {
|
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
// The lane transcript directories filed under a main checkout's lane root
|
|
104
|
+
// The lane transcript directories filed under a main checkout's lane root.
|
|
104
105
|
//
|
|
105
106
|
// **`session_cwd` resolved a lane to its main checkout, but nothing resolved a main checkout to its
|
|
106
107
|
// lanes.** From the main checkout `own === rewritten`, so the search collapsed to one directory and a
|
|
@@ -114,19 +115,21 @@ function read_directory(directory: string): Array<string> {
|
|
|
114
115
|
// store by the slug prefix every lane of this repository shares — `lane_paths.lane_root` slugged, which
|
|
115
116
|
// honors `JOSH_LANE_ROOT` — rather than any directory that may no longer exist.
|
|
116
117
|
//
|
|
117
|
-
// **A lane's directory is its issue number**, so a lane project slug is exactly `<root-slug>-<
|
|
118
|
+
// **A lane's directory is its issue number**, so a lane project slug is exactly `<root-slug>-<issue>`:
|
|
118
119
|
// `lane_paths.lane_directory` joins the root with the issue and the registry sorts lanes by
|
|
119
120
|
// `Number(issue)`. Matching the digits rather than the bare prefix keeps out a coincidental sibling
|
|
120
121
|
// such as `.kit-lanes-backup` and a slug filed under a nested cwd — both share the prefix but are not a
|
|
121
122
|
// lane.
|
|
122
|
-
const LANE_ISSUE_SLUG = /^\d+$/u
|
|
123
|
-
|
|
124
123
|
function lane_transcript_directories(main_cwd: string, home: string): Array<string> {
|
|
125
124
|
const projects = path.join(home, TRANSCRIPT_ROOT)
|
|
126
125
|
const prefix = `${project_slug(lane_paths.lane_root(main_cwd))}-`
|
|
127
126
|
|
|
128
127
|
return read_directory(projects)
|
|
129
|
-
.filter(
|
|
128
|
+
.filter(
|
|
129
|
+
(name) =>
|
|
130
|
+
name.startsWith(prefix) &&
|
|
131
|
+
issue_number_shape.ISSUE_NUMBER_PATTERN.test(name.slice(prefix.length)),
|
|
132
|
+
)
|
|
130
133
|
.map((name) => path.join(projects, name))
|
|
131
134
|
}
|
|
132
135
|
|
|
@@ -134,17 +137,15 @@ function lane_transcript_directories(main_cwd: string, home: string): Array<stri
|
|
|
134
137
|
// in. Two sources are legitimate, so both are searched and `list_sessions_across` merges what they
|
|
135
138
|
// hold:
|
|
136
139
|
// - the cwd's own slug — where a *dispatched* lane child writes, because `lane:dispatch` launches it
|
|
137
|
-
// as a `claude -p fullrun #N` process whose working directory is the lane
|
|
140
|
+
// as a `claude -p fullrun #N` process whose working directory is the lane;
|
|
138
141
|
// - every lane transcript directory under the main checkout's lane root — so a report run *from the
|
|
139
|
-
// main checkout* reaches the lane runs it dispatched
|
|
142
|
+
// main checkout* reaches the lane runs it dispatched.
|
|
140
143
|
//
|
|
141
|
-
// **A lane never reads the main checkout it resolves to
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
// transcript, which the child then measured as its own — its `--cut` verdict read that session's cost
|
|
147
|
-
// and every dispatched child stopped before implementing. So the main slug is no longer a candidate
|
|
144
|
+
// **A lane never reads the main checkout it resolves to.** `lane:dispatch` runs the child *in* the
|
|
145
|
+
// lane, so the child's transcript is under the lane's own slug; the main slug holds only a connected
|
|
146
|
+
// conversation session's transcript, which the child would measure as its own — its `--cut` verdict
|
|
147
|
+
// would read that session's cost and every dispatched child would stop before implementing. So the
|
|
148
|
+
// main slug is not a candidate
|
|
148
149
|
// from a lane, and a lane's measurement reads its own records alone.
|
|
149
150
|
//
|
|
150
151
|
// **Only a checkout that resolves to itself reads the lane root**, which is what keeps the from-main
|
|
@@ -175,8 +176,8 @@ interface SessionFile {
|
|
|
175
176
|
// units.
|
|
176
177
|
is_delegated: boolean
|
|
177
178
|
// How many `subagents/` levels down from a session's own transcript this was found: `0` for a
|
|
178
|
-
// session's own file, `1` for a unit it delegated, `2` for a unit that unit delegated, and so on
|
|
179
|
-
//
|
|
179
|
+
// session's own file, `1` for a unit it delegated, `2` for a unit that unit delegated, and so on.
|
|
180
|
+
// The filesystem is the only record of it — no transcript line carries a
|
|
180
181
|
// parent link — so the run-tree scope reads depth and the immediate parent from where the file sat.
|
|
181
182
|
depth: number
|
|
182
183
|
}
|
|
@@ -249,7 +250,7 @@ function level_units(
|
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
// The units under one `subagents/` directory, and — recursively — the units those units delegated in
|
|
252
|
-
// a `subagents/` of their own
|
|
253
|
+
// a `subagents/` of their own. A subdirectory beside the transcripts is an
|
|
253
254
|
// agent that itself delegated, so its own `subagents/` is walked one level deeper and the qualified
|
|
254
255
|
// id gains another segment. Nested units do not occur today — a subagent has no `Agent` tool to
|
|
255
256
|
// dispatch with — but the run-tree scope's depth is defined by this walk rather than by what exists.
|
|
@@ -297,7 +298,7 @@ function list_sessions(directory: string): Array<SessionFile> {
|
|
|
297
298
|
)
|
|
298
299
|
}
|
|
299
300
|
|
|
300
|
-
// Every session found across a set of candidate directories
|
|
301
|
+
// Every session found across a set of candidate directories, newest first and
|
|
301
302
|
// each `session_id` kept once. `transcript_directories` is what produces the set; a session file lives
|
|
302
303
|
// under exactly one slug, so the candidates normally hold disjoint sets and the dedupe is what keeps a
|
|
303
304
|
// run counted a single time should the same session ever surface under more than one candidate
|
|
@@ -331,7 +332,7 @@ function owning_session_id(file: SessionFile): string {
|
|
|
331
332
|
}
|
|
332
333
|
|
|
333
334
|
// The immediate parent a delegated unit was written under: everything before the *last* separator of
|
|
334
|
-
// its qualified id
|
|
335
|
+
// its qualified id. `owning_session_id` returns the *root* session — the id
|
|
335
336
|
// before the first separator — which the overlap reader needs; the run-tree scope needs the direct
|
|
336
337
|
// parent instead, so a depth-2 unit links to the depth-1 unit that spawned it rather than to the
|
|
337
338
|
// session at the top. A session's own file has no separator and is its own parent.
|
|
@@ -342,7 +343,7 @@ function parent_session_id(file: SessionFile): string {
|
|
|
342
343
|
}
|
|
343
344
|
|
|
344
345
|
// Which of a listing is "the run that just finished": the newest transcript that is a session's own
|
|
345
|
-
// rather than one of its delegated units
|
|
346
|
+
// rather than one of its delegated units.
|
|
346
347
|
//
|
|
347
348
|
// **A delegated unit is part of a run, not a run of its own**, and it writes the newer file whenever
|
|
348
349
|
// a session delegates — the parent is waiting while the unit works. Taking the head of the listing
|
|
@@ -422,7 +423,7 @@ function read_raw(file: SessionFile): string {
|
|
|
422
423
|
return file_reader.read_if_readable(file.path) ?? ''
|
|
423
424
|
}
|
|
424
425
|
|
|
425
|
-
// The same read, with the failure left visible
|
|
426
|
+
// The same read, with the failure left visible. **An unreadable transcript
|
|
426
427
|
// and an empty one are different answers**, and `read_raw` folds both to `''` — right for a reader
|
|
427
428
|
// that only wants lines to parse, and wrong for one that has to report a transcript as *not
|
|
428
429
|
// measured* rather than as measured at zero. `is_readable` on `SessionUsage` is the same distinction
|
|
@@ -432,9 +433,8 @@ function read_optional(file: SessionFile): string | undefined {
|
|
|
432
433
|
}
|
|
433
434
|
|
|
434
435
|
// One directory the search looked in, and whether it was there to look in. `exists` tells a directory
|
|
435
|
-
// that was absent from one that was present but held no transcript
|
|
436
|
-
//
|
|
437
|
-
// read the same as an empty one and delayed finding this bug (joshuafolkken/kit#1825).
|
|
436
|
+
// that was absent from one that was present but held no transcript, so a lane's missing slug does
|
|
437
|
+
// not read the same as an empty one.
|
|
438
438
|
interface SearchedDirectory {
|
|
439
439
|
path: string
|
|
440
440
|
exists: boolean
|
|
@@ -467,14 +467,14 @@ function describe_searched(directory: SearchedDirectory): string {
|
|
|
467
467
|
|
|
468
468
|
// What to say when the discovery above found nothing. It lives here rather than in either command
|
|
469
469
|
// because both `josh cost` and `josh time` reach it, and a second copy would drift the moment one of
|
|
470
|
-
// them learned something about where transcripts live
|
|
470
|
+
// them learned something about where transcripts live. The message, not the
|
|
471
471
|
// printing: each command owns its own streams and exit code.
|
|
472
472
|
//
|
|
473
473
|
// **The directories are passed in, not resolved here.** The whole point of the message is to name
|
|
474
474
|
// where the command looked, so they have to be the same paths the search used — resolving them a
|
|
475
475
|
// second time can name a directory that was never searched. Both candidates are listed, each with its
|
|
476
476
|
// own reason (absent, or present but empty), so a run whose lane slug does not exist reads differently
|
|
477
|
-
// from one whose main slug exists and is empty
|
|
477
|
+
// from one whose main slug exists and is empty.
|
|
478
478
|
//
|
|
479
479
|
// "No transcript was found" and "this run cost nothing" are different answers, and only one of them
|
|
480
480
|
// is ever true — which is why neither command may report an empty corpus as a zero.
|
|
@@ -2,8 +2,7 @@ import { json_value } from '#scripts/lib/json-value'
|
|
|
2
2
|
import { time_instant } from '#scripts/time-runtime/time-instant'
|
|
3
3
|
import { z } from 'zod'
|
|
4
4
|
|
|
5
|
-
// Reading Claude Code's own session transcripts for what a run actually cost
|
|
6
|
-
// (joshuafolkken/kit#962).
|
|
5
|
+
// Reading Claude Code's own session transcripts for what a run actually cost.
|
|
7
6
|
//
|
|
8
7
|
// **One API response is written to the transcript as several lines.** Every content block —
|
|
9
8
|
// thinking, text, each `tool_use` — becomes its own `assistant` line, and all of them carry the
|
|
@@ -65,7 +64,7 @@ interface UsageTotals {
|
|
|
65
64
|
thinking_tokens: number
|
|
66
65
|
// Whether the API actually reported a thinking-token count, kept apart from the count itself
|
|
67
66
|
// because `thinking_tokens: 0` cannot tell "the model did no thinking" from "the field was
|
|
68
|
-
// absent"
|
|
67
|
+
// absent". A session row prints "not measured" for the second rather
|
|
69
68
|
// than a confident 0%, so the distinction has to survive `sum_totals`; it is OR-combined, so a
|
|
70
69
|
// session is measured once any one of its requests carried a count.
|
|
71
70
|
thinking_measured: boolean
|
|
@@ -76,9 +75,9 @@ interface UsageRecord {
|
|
|
76
75
|
model: string
|
|
77
76
|
branch: string
|
|
78
77
|
// The request's instant, as epoch milliseconds — `undefined` where no line of the request carried
|
|
79
|
-
// a readable timestamp
|
|
78
|
+
// a readable timestamp. On a single line it is that line's timestamp;
|
|
80
79
|
// after `dedupe` folds the request's several lines into one record it is the *latest* of them,
|
|
81
|
-
// which is the response-completion instant a cost window is keyed to
|
|
80
|
+
// which is the response-completion instant a cost window is keyed to.
|
|
82
81
|
//
|
|
83
82
|
// **`undefined` rather than a sentinel, for the reason `time_instant` exists**: a request whose
|
|
84
83
|
// instant cannot be read belongs in the unattributed bucket, and a `0` would place it at the
|
|
@@ -210,7 +209,7 @@ function parse_line(line: string): LineOutcome {
|
|
|
210
209
|
|
|
211
210
|
// The later of two request instants, treating `undefined` as no reading rather than as an early one:
|
|
212
211
|
// a line that carried no timestamp must not pull a request's instant back to nothing when a sibling
|
|
213
|
-
// line of the same request does carry one
|
|
212
|
+
// line of the same request does carry one.
|
|
214
213
|
function later_instant(left: number | undefined, right: number | undefined): number | undefined {
|
|
215
214
|
if (left === undefined) return right
|
|
216
215
|
if (right === undefined) return left
|
|
@@ -222,7 +221,7 @@ function later_instant(left: number | undefined, right: number | undefined): num
|
|
|
222
221
|
// the branch sequence, so a Map (which preserves insertion order) is the right container and a Set
|
|
223
222
|
// of ids plus a filter would be the same thing written twice.
|
|
224
223
|
//
|
|
225
|
-
// **`at_ms` is folded to the request's latest line, not its first
|
|
224
|
+
// **`at_ms` is folded to the request's latest line, not its first.** One
|
|
226
225
|
// response is written thinking → text → `tool_use` (see the file header), all sharing one request id,
|
|
227
226
|
// and a round trip's cost window opens at the `tool_use` line — the last of them. Keeping the first
|
|
228
227
|
// line's instant put every tool-issuing request *before* its own window, where it fell to the
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// The `--over` hand-off flag of `josh cost`, kept apart from the CLI wiring because it turns a run
|
|
2
|
-
// into a one-line verdict rather than a table
|
|
2
|
+
// into a one-line verdict rather than a table. It answers what the next turn
|
|
3
3
|
// of a session will cost, and takes only the figures its verdict needs — an over measurement — never
|
|
4
4
|
// a whole report. The `--cap` counterfactual it once sat beside was retired in #2016 as readerless.
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ const UNDER_VERDICT = 'under'
|
|
|
9
9
|
|
|
10
10
|
// What `--over` reads of a session: the billed input each request paid, oldest first. The sequence
|
|
11
11
|
// is carried rather than a single sum because the hand-off prices the newest request alone
|
|
12
|
-
//
|
|
12
|
+
// — a sum could not answer what the session's current context costs.
|
|
13
13
|
interface OverMeasurement {
|
|
14
14
|
billed_input_per_request: ReadonlyArray<number>
|
|
15
15
|
}
|
|
@@ -17,21 +17,20 @@ interface OverMeasurement {
|
|
|
17
17
|
// What a turn costs is decided by the accumulated preamble, not by what the turn does, so the
|
|
18
18
|
// marginal cost of a session is the billed input its newest request paid. Measured across one
|
|
19
19
|
// `epicrun` that ran six children in one context: 222k per request during the first child, 645k
|
|
20
|
-
// during the sixth — the same work at 2.9x the price
|
|
20
|
+
// during the sixth — the same work at 2.9x the price.
|
|
21
21
|
//
|
|
22
|
-
// **The newest request, not an average.**
|
|
23
|
-
//
|
|
24
|
-
// lagged. A session's billed input only grows between compactions (a unit writes its own transcript),
|
|
22
|
+
// **The newest request, not an average.** A whole-session average lags a long parent by dozens of
|
|
23
|
+
// requests, and even the average of the last ten lags. A session's billed input only grows between compactions (a unit writes its own transcript),
|
|
25
24
|
// so an average smooths no outlier — it only trails the context it averages. On 2026-10-05 wake
|
|
26
|
-
// session 03367124 crossed the threshold at request 65 and its ten-request average at request 70
|
|
27
|
-
//
|
|
25
|
+
// session 03367124 crossed the threshold at request 65 and its ten-request average at request 70.
|
|
26
|
+
// The threshold is a break-even on the *current* context
|
|
28
27
|
// (`context-cut-payback.ts`), so the current context is what it is compared against.
|
|
29
28
|
function per_request_cost(measurement: OverMeasurement): number {
|
|
30
29
|
return measurement.billed_input_per_request.at(-1) ?? 0
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
// The bare over/under decision, without a report: `run:status` reads this same verdict read-only
|
|
34
|
-
//
|
|
32
|
+
// The bare over/under decision, without a report: `run:status` reads this same verdict read-only,
|
|
33
|
+
// so the comparison lives here once rather than being copied there. A
|
|
35
34
|
// threshold of exactly `cost` is under, matching the `>` the printed report used.
|
|
36
35
|
function classify(
|
|
37
36
|
measurement: OverMeasurement,
|
|
@@ -41,7 +40,7 @@ function classify(
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
// The stderr line names which request was priced, so the reader can tell the newest request's cost
|
|
44
|
-
// from an average over the session
|
|
43
|
+
// from an average over the session.
|
|
45
44
|
function over_summary(measurement: OverMeasurement, limit: number): string {
|
|
46
45
|
const total = measurement.billed_input_per_request.length
|
|
47
46
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { agent_session_environment } from '#scripts/josh/agent-session-environment'
|
|
2
2
|
import { cost_transcript, type SessionFile } from './cost-transcript'
|
|
3
3
|
|
|
4
|
-
// Which transcript in a listing is the *calling* session's own
|
|
4
|
+
// Which transcript in a listing is the *calling* session's own.
|
|
5
5
|
//
|
|
6
6
|
// **The mtime was measuring another session.** `latest_own_index` took the newest non-delegated
|
|
7
7
|
// transcript as "the run that just finished", which is right for a report run after a run ends but
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
2
|
|
|
3
|
-
// `--path <dir>` names the target project whose transcripts to read, resolved to an absolute path
|
|
4
|
-
//
|
|
3
|
+
// `--path <dir>` names the target project whose transcripts to read, resolved to an absolute path.
|
|
4
|
+
// The transcript slug is derived from the exact cwd string and
|
|
5
5
|
// `~/.claude/projects/<slug>` was written from an absolute one, so a relative `--path` would slugify
|
|
6
6
|
// to a folder that was never written. Shared by `josh cost` and `josh time` so the two resolve a
|
|
7
7
|
// target identically — a second copy of this rule is how one of the two quietly stops finding it.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
3
|
import { delegation_policy } from './delegation-policy'
|
|
4
4
|
|
|
5
|
-
// `josh delegate <step>` — may this step run in a cheaper execution tier?
|
|
5
|
+
// `josh delegate <step>` — may this step run in a cheaper execution tier?
|
|
6
6
|
//
|
|
7
7
|
// A command rather than a paragraph, for the reason `josh review:level` is one: a rule an agent
|
|
8
8
|
// applies from memory is a rule an agent can talk itself out of, and this is the rule that decides
|
|
@@ -36,15 +36,15 @@ const FLAG_PREFIX = '-'
|
|
|
36
36
|
// Every reading of the argument goes through this one function, because the guard and the branch
|
|
37
37
|
// disagreeing about surrounding whitespace is the defect itself: the guard trimmed and `run` did
|
|
38
38
|
// not, so `josh delegate ' --list'` passed as a known flag and then fell through to a verdict about
|
|
39
|
-
// a step called ` --list
|
|
40
|
-
// `josh delegate ' --help'` had already slipped past an untrimmed guard
|
|
39
|
+
// a step called ` --list`. The policy lookup trims too, which is why
|
|
40
|
+
// `josh delegate ' --help'` had already slipped past an untrimmed guard.
|
|
41
41
|
function normalized(argument: string): string {
|
|
42
42
|
return argument.trim()
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// A step name never starts with a dash, so anything that does is a flag — and the only flag this
|
|
46
46
|
// command has is `--list`. Without this, `josh delegate --help` answered `keep`: a mistyped
|
|
47
|
-
// invocation would read as a verdict about a step called `--help
|
|
47
|
+
// invocation would read as a verdict about a step called `--help`.
|
|
48
48
|
function is_unknown_flag(argument: string): boolean {
|
|
49
49
|
const trimmed = normalized(argument)
|
|
50
50
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Which steps of a run may be delegated to a cheaper execution tier
|
|
1
|
+
// Which steps of a run may be delegated to a cheaper execution tier.
|
|
2
2
|
//
|
|
3
3
|
// **The decision takes no judgement.** "This one is simple enough" is a judgement made under cost
|
|
4
4
|
// pressure, and cost pressure resolves it toward "simple enough" exactly when a mistake is most
|
|
@@ -23,19 +23,18 @@ interface DelegatableStep {
|
|
|
23
23
|
verifier: string
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
// Where the pre-implementation reading stops being cheaper in the main line
|
|
26
|
+
// Where the pre-implementation reading stops being cheaper in the main line.
|
|
27
27
|
//
|
|
28
28
|
// **A count, not a forecast.** The reads are counted as they are made rather than predicted before
|
|
29
29
|
// the investigation starts, so nothing here rests on guessing how large it will be. Two files the run
|
|
30
30
|
// will not edit stay in the main line, because delegating costs two extra main-line turns — one to
|
|
31
|
-
// write the brief, one to read the result, about 18 seconds at
|
|
31
|
+
// write the brief, one to read the result, about 18 seconds at roughly 8.8 s of model
|
|
32
32
|
// wait per turn — and below the threshold that round trip costs more than carrying the text.
|
|
33
33
|
const INVESTIGATION_FILE_THRESHOLD = 3
|
|
34
34
|
|
|
35
|
-
// The same boundary for searches, counted in turns
|
|
36
|
-
// text, so it never
|
|
37
|
-
//
|
|
38
|
-
// re-reading the whole main-line context. Three keeps the first two searches, which locate an edit
|
|
35
|
+
// The same boundary for searches, counted in turns. A `grep` carries no file
|
|
36
|
+
// text, so it never reaches the file count — yet a search that comes third or later since the last
|
|
37
|
+
// edit or delegation re-reads the whole main-line context all the same. Three keeps the first two searches, which locate an edit
|
|
39
38
|
// target, in the main line and sends the continuing sweep to a unit.
|
|
40
39
|
const INVESTIGATION_SEARCH_TURN_THRESHOLD = 3
|
|
41
40
|
|
|
@@ -50,10 +49,9 @@ const DELEGATABLE_STEPS: ReadonlyArray<DelegatableStep> = [
|
|
|
50
49
|
},
|
|
51
50
|
{
|
|
52
51
|
name: 'epic-child',
|
|
53
|
-
// One row, two entry points: an epic's child
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
// second row for the batch would be the clone `CLAUDE.md` prohibits.
|
|
52
|
+
// One row, two entry points: an epic's child and one named issue of a `backlogrun` are the same
|
|
53
|
+
// unit — same brief, same summary, same verifier. A second row for the batch would be the clone
|
|
54
|
+
// `CLAUDE.md` prohibits.
|
|
57
55
|
does: "run one child of a batch end to end in an isolated unit — an epic's child or one named issue of a `backlogrun` alike — plan, verification gate, PR, merge — and return only its summary to the parent loop",
|
|
58
56
|
verifier:
|
|
59
57
|
"the parent reads the child's state from GitHub with `pnpm josh issue:state`, not from the summary; a child reported done but not merged is still open, which is the failure showing rather than a run continuing, and its own gate, `/code-review` and CI ran inside the unit before `followup` would touch the PR",
|
|
@@ -61,9 +59,9 @@ const DELEGATABLE_STEPS: ReadonlyArray<DelegatableStep> = [
|
|
|
61
59
|
{
|
|
62
60
|
name: 'followup-filing',
|
|
63
61
|
// The late-run follow-up filing chain — `issue:file` (which scouts, lints, labels and runs
|
|
64
|
-
// epic:bundle itself
|
|
62
|
+
// epic:bundle itself) → epic --add — is a dependency chain `batch:guard`
|
|
65
63
|
// correctly keeps one call per step, and what makes it expensive is the ~340k context it runs in
|
|
66
|
-
// at the tail of a run, not the step count
|
|
64
|
+
// at the tail of a run, not the step count. A fresh unit runs the same
|
|
67
65
|
// chain at a small context, and the review round cap already composed the finding text, so what
|
|
68
66
|
// the unit is handed is mechanical: run the commands and act on their deterministic answers. This
|
|
69
67
|
// is not `batch:guard`'s business — delegation only moves the chain to a cheaper context.
|
|
@@ -77,7 +75,7 @@ const DELEGATABLE_STEPS: ReadonlyArray<DelegatableStep> = [
|
|
|
77
75
|
// which is why `design` is rejected below. What is delegated is the *writing* of one unit of that
|
|
78
76
|
// list, and only a unit whose files are disjoint from every other dispatched unit: two subagents
|
|
79
77
|
// editing one file in parallel race on it. `pnpm josh fanout` confirms that disjointness
|
|
80
|
-
// mechanically, so the split is read off the file sets rather than judged
|
|
78
|
+
// mechanically, so the split is read off the file sets rather than judged.
|
|
81
79
|
does: 'implement one file-disjoint unit of the Step 0 change list in an isolated subagent — the files it edits shared with no other dispatched unit, confirmed by `pnpm josh fanout` — and return the edited files, never a summary standing in for the diff; the main line keeps integration and the verification gate. Units that share a file, or an Issue that will not split, stay serial',
|
|
82
80
|
verifier:
|
|
83
81
|
"the parent runs the whole integrated change through `pnpm josh gate` and a `/code-review` subagent it would run anyway — a unit's mistake fails the same gate and review a serial edit passes through, so delegating writes nothing the backstop does not already catch, and the `pnpm josh fanout` disjointness removes the one failure parallelism adds, two units colliding on a file",
|
|
@@ -101,7 +99,7 @@ const DELEGATABLE_STEPS: ReadonlyArray<DelegatableStep> = [
|
|
|
101
99
|
},
|
|
102
100
|
{
|
|
103
101
|
name: 'lane-failure-investigation',
|
|
104
|
-
// The `backlogrun` parent's counterpart of `investigation
|
|
102
|
+
// The `backlogrun` parent's counterpart of `investigation`. The parent
|
|
105
103
|
// orchestrates and never implements, yet it read a failed lane's logs, records and sources in its
|
|
106
104
|
// own context — about 150 grep / cat / sed calls on 2026-10-02 — and every later request of the
|
|
107
105
|
// batch re-read them. The verifier is `investigation`'s, and so is the boundary: the unit reports
|
|
@@ -10,10 +10,9 @@ import { time_spans, type Span } from '#scripts/time-runtime/time-spans'
|
|
|
10
10
|
import { investigation_reads } from './investigation-reads'
|
|
11
11
|
|
|
12
12
|
// Refuse the second whole-file `Read` of a path whose content has not changed since the run last read
|
|
13
|
-
// it
|
|
14
|
-
// path 8.0 times on average — `#2282` read `pre-gate-cut.md` three times — and each round trip pays
|
|
13
|
+
// it. Left alone, a run re-reads the same unchanged path again and again, and each round trip pays
|
|
15
14
|
// ~17 seconds to return text the run already holds. The remedy is the one `investigation-guard.ts`
|
|
16
|
-
//
|
|
15
|
+
// applies: intervene in the `PreToolUse` decision rather than describe the rule in prose.
|
|
17
16
|
//
|
|
18
17
|
// **It is unchanged content that is caught, never a repeat read.** The transcript says *when* the run
|
|
19
18
|
// last read the path; the filesystem says *whether* it has changed since. A file whose `mtime` is
|
|
@@ -24,12 +23,12 @@ import { investigation_reads } from './investigation-reads'
|
|
|
24
23
|
//
|
|
25
24
|
// **How it speaks is decided by the one-place lane enumeration, exactly as the batching guard's is.**
|
|
26
25
|
// On the interactive main line a refusal is guidance, so the guard `refuse`s; in a dispatched lane
|
|
27
|
-
// child a denial ends the headless turn with nothing committed
|
|
28
|
-
// duplicates
|
|
26
|
+
// child a denial ends the headless turn with nothing committed, and the
|
|
27
|
+
// duplicates mostly occur in those very children — so there it is a `notice`, nudging the run
|
|
29
28
|
// without killing it. `lane-guard-policy.ts` is the single source of both modes.
|
|
30
29
|
//
|
|
31
30
|
// **The escape hatch is on by default**, for `investigation-guard.ts`'s reason: a distributed guard
|
|
32
|
-
// nobody enables leaves the
|
|
31
|
+
// nobody enables leaves the problem where it started. The variable buys a way to switch it off without
|
|
33
32
|
// editing the settings file — debugging the guard, or a session whose re-reads really are all needed.
|
|
34
33
|
const SWITCH_ENV_KEY = 'JOSH_DUPLICATE_READ_GUARD'
|
|
35
34
|
const LANE_GUARD_ID = 'duplicate-read'
|
|
@@ -45,12 +44,12 @@ const GLOB_CHARACTERS = /[*?]/u
|
|
|
45
44
|
const REASON = `⛔ duplicate read: this file was already read in this session and has not changed since (its mtime predates that read), so reading it again returns nothing new. Scroll up to the earlier result instead of re-reading it. A read with a new offset/limit, or of a file that has since changed, is allowed; set \`JOSH_DUPLICATE_READ_GUARD=off\` to disable this guard.`
|
|
46
45
|
|
|
47
46
|
// The same guidance carried without a `permissionDecision`, for a dispatched lane child where a denial
|
|
48
|
-
// would end the turn
|
|
47
|
+
// would end the turn. It nudges rather than blocks, so the run survives.
|
|
49
48
|
const NOTICE = `⚠ duplicate read: this file was already read in this session and has not changed since, so re-reading it returns nothing new — scroll up to the earlier result instead of re-reading it. Set \`JOSH_DUPLICATE_READ_GUARD=off\` to silence this.`
|
|
50
49
|
|
|
51
50
|
// **A paginated read is a read of a different region, not a repeat.** A run that read lines 1–100 and
|
|
52
51
|
// now wants 101–200 needs the second call, so a read carrying an `offset` or a `limit` is never the
|
|
53
|
-
// whole-file re-read this guard is about
|
|
52
|
+
// whole-file re-read this guard is about.
|
|
54
53
|
function is_paginated(input: Record<string, unknown>): boolean {
|
|
55
54
|
return input['offset'] !== undefined || input['limit'] !== undefined
|
|
56
55
|
}
|
|
@@ -163,7 +162,7 @@ function is_redundant_reread(tail: string, call: GuardedCall, fired_at_ms: numbe
|
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
// **How this guard behaves for the session in hand, from the one-place enumeration** — `refuse` on the
|
|
166
|
-
// main line, `notice` in a dispatched lane child
|
|
165
|
+
// main line, `notice` in a dispatched lane child. The enumeration reads the
|
|
167
166
|
// dispatch mark against this checkout's own issue only for a mode it would change, so a person working
|
|
168
167
|
// in a lane sees the guard refuse exactly as the main line does.
|
|
169
168
|
function duplicate_mode(): LaneGuardMode {
|
|
@@ -178,7 +177,7 @@ function is_candidate(call: GuardedCall): boolean {
|
|
|
178
177
|
|
|
179
178
|
// A refusable call is refused only where the mode is `refuse`. A lane child is `notice`, so it reaches
|
|
180
179
|
// here and is withheld the refusal — the notice branch carries the guidance instead, because a refusal
|
|
181
|
-
// ends a headless child's turn
|
|
180
|
+
// ends a headless child's turn.
|
|
182
181
|
function should_block_here(tail: string, call: GuardedCall, refused_at_ms: number): boolean {
|
|
183
182
|
if (duplicate_mode() !== 'refuse') return false
|
|
184
183
|
|
|
@@ -3,7 +3,7 @@ import { fileURLToPath } from 'node:url'
|
|
|
3
3
|
import { fanout, type FanoutUnit } from './fanout'
|
|
4
4
|
|
|
5
5
|
// `josh fanout <unit-files> <unit-files> …` — may the Step 0 change list be cut into file-disjoint
|
|
6
|
-
// units and dispatched in one fan-out turn?
|
|
6
|
+
// units and dispatched in one fan-out turn?
|
|
7
7
|
//
|
|
8
8
|
// A command rather than a paragraph, for the reason `josh delegate` is one: "these units look
|
|
9
9
|
// independent" is a judgement made under the same cost pressure, and the answer is mechanical — read
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Whether the Step 0 change list can be cut into file-disjoint units and dispatched in one fan-out
|
|
2
|
-
// turn, or must stay serial because two proposed units would edit the same file
|
|
2
|
+
// turn, or must stay serial because two proposed units would edit the same file.
|
|
3
3
|
//
|
|
4
4
|
// **File-disjointness is the necessary condition, and it is mechanical.** Two subagents editing the
|
|
5
5
|
// same file in parallel race on that file — the later write lands on top of the earlier, or the gate
|