@joshuafolkken/kit 1.1455.0 → 1.1514.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/settings.json +6 -6
- package/.claude/skills/dependency-update/SKILL.md +26 -55
- package/.claude/skills/epic-commands/SKILL.md +83 -156
- package/.claude/skills/epic-commands/epic-bundle.md +51 -79
- package/.claude/skills/epic-commands/execution-waves.md +43 -81
- package/.claude/skills/verify-ui/SKILL.md +24 -50
- package/.claude/skills/workflow-commands/SKILL.md +7 -9
- package/.claude/skills/workflow-commands/background-commands.md +31 -46
- package/.claude/skills/workflow-commands/backlogrun-child.md +65 -85
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +86 -125
- package/.claude/skills/workflow-commands/backlogrun-park.md +68 -118
- package/.claude/skills/workflow-commands/backlogrun-progress.md +17 -28
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +17 -26
- package/.claude/skills/workflow-commands/backlogrun-steps.md +35 -52
- package/.claude/skills/workflow-commands/backlogrun.md +31 -50
- package/.claude/skills/workflow-commands/chain-rule.md +31 -40
- package/.claude/skills/workflow-commands/delegation.md +12 -8
- package/.claude/skills/workflow-commands/entry-sequence.md +1 -3
- package/.claude/skills/workflow-commands/followup.md +55 -77
- package/.claude/skills/workflow-commands/fullrun-steps.md +3 -5
- package/.claude/skills/workflow-commands/fullrun.md +4 -6
- package/.claude/skills/workflow-commands/halfrun.md +3 -7
- package/.claude/skills/workflow-commands/into-target.md +1 -2
- package/.claude/skills/workflow-commands/issue-comments.md +43 -60
- package/.claude/skills/workflow-commands/issue-scout.md +3 -2
- package/.claude/skills/workflow-commands/kickoff.md +65 -74
- package/.claude/skills/workflow-commands/latest-gate.md +2 -6
- package/.claude/skills/workflow-commands/needs-human-review.md +2 -5
- package/.claude/skills/workflow-commands/observation-filing.md +59 -118
- package/.claude/skills/workflow-commands/observation-ledger.md +52 -112
- package/.claude/skills/workflow-commands/pre-gate-cut.md +88 -142
- package/.claude/skills/workflow-commands/prerequisite.md +11 -17
- package/.claude/skills/workflow-commands/progress-watcher.md +23 -33
- package/.claude/skills/workflow-commands/prrun.md +3 -5
- package/.claude/skills/workflow-commands/retrospective.md +35 -54
- package/.claude/skills/workflow-commands/split-assessment.md +32 -58
- package/.claude/skills/workflow-commands/target-repository.md +1 -2
- package/.claude/skills/workflow-commands/working-tree-hold.md +54 -73
- package/.codex/hooks.json +6 -6
- package/.github/actions/setup-node/action.yml +1 -1
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/publish.yml +2 -2
- package/CLAUDE.md +7 -6
- package/cspell/index.yaml +7 -0
- package/dist/CLAUDE.md +7 -6
- package/dist/commands/document-section-cli.js +67 -34
- package/dist/hooks/batch-guard.js +6 -6
- package/dist/hooks/chunk-4KKD2UTK.js +66 -0
- package/dist/hooks/{chunk-GPLGZ6IC.js → chunk-6TS2JD6D.js} +14 -3
- package/dist/hooks/chunk-7DSBJVFH.js +50 -0
- package/dist/hooks/{chunk-5H4SSDSD.js → chunk-A65Y4YOR.js} +3 -3
- package/dist/hooks/{chunk-3C4XRYG6.js → chunk-APUO6U4J.js} +102 -19
- package/dist/hooks/{chunk-IX6TTTI6.js → chunk-EFXE6C37.js} +8 -22
- package/dist/hooks/chunk-GP4IEC4O.js +20 -0
- package/dist/hooks/chunk-JP45SOCJ.js +56 -0
- package/dist/hooks/{chunk-OLMO72ON.js → chunk-LAOV7NLM.js} +1 -1
- package/dist/hooks/chunk-M4HGZV7U.js +83 -0
- package/dist/hooks/{chunk-TBJFTSUY.js → chunk-O6GDRNJB.js} +9 -7
- package/dist/hooks/{chunk-HFGWYGUV.js → chunk-PF2NZL2A.js} +5 -5
- package/dist/hooks/{chunk-WNLVGT7E.js → chunk-PTICX4OL.js} +4 -5
- package/dist/hooks/{chunk-HHI6FO3R.js → chunk-RT27QRJW.js} +763 -1515
- package/dist/hooks/{chunk-7WQBPLUN.js → chunk-SYOTDYCI.js} +1149 -1095
- package/dist/hooks/{chunk-LIAFCXL7.js → chunk-TNUMY6NL.js} +1519 -1332
- package/dist/hooks/chunk-UPUZF3AN.js +279 -0
- package/dist/hooks/{chunk-Z4XI7CZS.js → chunk-WK6SMBIC.js} +1932 -784
- package/dist/hooks/codex-hook-adapter.js +17 -14
- package/dist/hooks/duplicate-read-guard.js +7 -7
- package/dist/hooks/format-edited.js +5 -4
- package/dist/hooks/inputs.json +302 -247
- package/dist/hooks/investigation-guard.js +8 -11
- package/dist/hooks/pretool-guard.js +16 -13
- package/dist/hooks/session-lang.js +372 -26
- package/dist/hooks/stop-guard.js +2593 -189
- package/dist/josh.js +2128 -282
- package/dist/managed-marker/index.js +1 -2
- package/dist/version/index.js +15 -12
- package/eslint/base.js +2 -1
- package/eslint/rules/unicorn.js +16 -0
- package/lefthook/base.yml +5 -3
- package/package.json +14 -12
- package/prompts/coding-standards.md +12 -22
- package/prompts/collaboration-workflow/file-edits.md +25 -45
- package/prompts/collaboration-workflow/gh-rest.md +19 -36
- package/prompts/collaboration-workflow/glossary.md +5 -7
- package/prompts/collaboration-workflow/issue-citation.md +6 -14
- package/prompts/collaboration-workflow/issue-template.md +40 -32
- package/prompts/collaboration-workflow/lane-instructions.md +35 -0
- package/prompts/collaboration-workflow/operating-rules.md +33 -46
- package/prompts/collaboration-workflow/output-bounds.md +15 -15
- package/prompts/collaboration-workflow/overview.md +14 -19
- package/prompts/collaboration-workflow/plan-comment.md +13 -13
- package/prompts/collaboration-workflow/principles.md +57 -54
- package/prompts/collaboration-workflow/proposal-request.md +1 -9
- package/prompts/collaboration-workflow/report-format.md +41 -49
- package/prompts/collaboration-workflow/residency.md +15 -11
- package/prompts/collaboration-workflow/rule-delivery.md +7 -15
- package/prompts/collaboration-workflow/shell-body.md +10 -20
- package/prompts/collaboration-workflow/turn-batching.md +8 -14
- package/prompts/collaboration-workflow/upstream-interrupt.md +26 -34
- package/prompts/collaboration-workflow/wip-cap.md +26 -32
- package/prompts/collaboration-workflow.md +25 -25
- package/prompts/refactoring.md +33 -43
- package/prompts/review-rubric.md +84 -129
- package/prompts/review.md +110 -141
- package/prompts/sonar-hotspot-handling.md +22 -50
- package/prompts/testing-guide.md +48 -99
- package/scripts/adopt/adopt-toolkits.ts +2 -4
- package/scripts/agent/agent-argv.ts +20 -4
- package/scripts/agent/agent-exit-record.ts +23 -1
- package/scripts/agent/agent-role-profile.ts +101 -45
- package/scripts/agent/agent-safe-text.ts +60 -0
- package/scripts/agent/claude-agent-argv.ts +14 -0
- package/scripts/agent/codex-agent-argv.ts +9 -2
- package/scripts/agent/lane-instructions.ts +144 -0
- package/scripts/backlog/backlog-budget-cli.ts +1 -2
- package/scripts/backlog/backlog-budget.ts +4 -4
- package/scripts/backlog/backlog-drive-carried.ts +26 -0
- package/scripts/backlog/backlog-drive-cli.ts +10 -5
- package/scripts/backlog/backlog-drive-named.ts +3 -5
- package/scripts/backlog/backlog-drive-restore.ts +28 -2
- package/scripts/backlog/backlog-drive-seats.ts +27 -0
- package/scripts/backlog/backlog-drive.ts +11 -6
- package/scripts/backlog/backlog-occupied.ts +56 -0
- package/scripts/backlog/backlog-ready.ts +59 -15
- package/scripts/behavior/behavior-rules.ts +3 -2
- package/scripts/cost-runtime/codex-usage.ts +4 -2
- package/scripts/cost-runtime/cost-cli.ts +1 -2
- package/scripts/delegation/duplicate-read-guard.ts +2 -2
- package/scripts/delegation/investigation-guard.ts +15 -65
- package/scripts/delegation/investigation-reads.ts +1 -2
- package/scripts/discovery/repo-discovery.ts +4 -2
- package/scripts/discovery/repo-origin.ts +2 -4
- package/scripts/doctor/doctor-logic.ts +6 -3
- package/scripts/document/document-byte-budget.ts +28 -27
- package/scripts/document/document-byte-check.ts +1 -2
- package/scripts/document/document-section-cli.ts +17 -5
- package/scripts/document/entry-read-budget.ts +3 -3
- package/scripts/document/read-set-cli.ts +4 -1
- package/scripts/epic/epic-audit-orphans.ts +5 -8
- package/scripts/epic/epic-audit-rationale.ts +8 -2
- package/scripts/epic/epic-audit.ts +52 -1
- package/scripts/epic/epic-bundle-cli.ts +1 -2
- package/scripts/epic/epic-bundle-evidence.ts +49 -26
- package/scripts/epic/epic-bundle-referenced.ts +14 -3
- package/scripts/epic/epic-bundle.ts +17 -9
- package/scripts/epic/epic-chains.ts +6 -2
- package/scripts/epic/epic-close-comment.ts +1 -2
- package/scripts/followup/git-followup-workflow.ts +19 -1
- package/scripts/gate/check-inputs.ts +129 -0
- package/scripts/gate/check-reuse.ts +162 -0
- package/scripts/gate/core-budget.ts +93 -44
- package/scripts/gate/core-wait.ts +130 -0
- package/scripts/gate/free-cores.ts +49 -0
- package/scripts/gate/gate-ledger.ts +17 -3
- package/scripts/gate/gate-plan.ts +23 -1
- package/scripts/gate/gate-report.ts +15 -2
- package/scripts/gate/gate-run-steps.ts +150 -0
- package/scripts/gate/held-mark.ts +55 -0
- package/scripts/gate/machine-capacity.ts +70 -11
- package/scripts/gate/pre-commit-type-check.ts +14 -1
- package/scripts/gate/verification-gate.ts +65 -127
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +24 -2
- package/scripts/gh/git-pr.ts +19 -3
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +16 -9
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/git/main-merge-regenerate.ts +78 -0
- package/scripts/git/main-merge.ts +14 -5
- package/scripts/hooks/batch-guard.ts +5 -8
- package/scripts/hooks/format-edited-file.ts +10 -4
- package/scripts/hooks/pre-commit-lint.ts +91 -0
- package/scripts/hooks/pre-push-unit.ts +15 -4
- package/scripts/hooks/pretool-guard.ts +48 -79
- package/scripts/hooks/reserved-run.ts +1 -0
- package/scripts/hooks/run-hook.sh +10 -12
- package/scripts/hooks/step-zero-notice.ts +3 -2
- package/scripts/hooks/stop-actions.ts +204 -0
- package/scripts/hooks/stop-guard.ts +62 -21
- package/scripts/init/hook-command-rewrite.ts +6 -2
- package/scripts/init/hook-launch.ts +12 -7
- package/scripts/init/init-logic-deploy-vps.ts +4 -2
- package/scripts/issue/behavior-change-lint.ts +12 -6
- package/scripts/issue/expected-effect-lint.ts +59 -0
- package/scripts/issue/issue-cite-cli.ts +35 -15
- package/scripts/issue/issue-classification.ts +1 -1
- package/scripts/issue/issue-lint-cli.ts +5 -3
- package/scripts/issue/issue-scout-cli.ts +22 -16
- package/scripts/issue/markdown-section.ts +19 -5
- package/scripts/josh/command-usage.ts +110 -0
- package/scripts/josh/file-map-stamp.ts +1 -3
- package/scripts/josh/hook-decision.ts +17 -2
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-command-types.ts +55 -9
- package/scripts/josh/josh-commands-ai.ts +13 -0
- package/scripts/josh/josh-commands-development.ts +1 -1
- package/scripts/josh/josh-commands-hooks.ts +6 -0
- package/scripts/josh/josh-commands-lane.ts +10 -1
- package/scripts/josh/josh-commands-workflow.ts +5 -0
- package/scripts/josh/josh-logic.ts +6 -15
- package/scripts/josh/josh-usage-automation.ts +121 -0
- package/scripts/josh/josh-usage-backlog.ts +180 -0
- package/scripts/josh/josh-usage-developer.ts +230 -0
- package/scripts/josh/josh-usage-hooks.ts +38 -0
- package/scripts/josh/josh-usage-issue.ts +205 -0
- package/scripts/josh/josh-usage-review.ts +101 -0
- package/scripts/josh/josh-usage-run.ts +252 -0
- package/scripts/josh/josh-usage-session.ts +238 -0
- package/scripts/josh/josh-usage-workflow.ts +212 -0
- package/scripts/josh/josh.ts +14 -5
- package/scripts/josh/package-directory.ts +20 -0
- package/scripts/lane/lane-await.ts +3 -2
- package/scripts/lane/lane-capacity.ts +8 -2
- package/scripts/lane/lane-check-stats.ts +56 -0
- package/scripts/lane/lane-child-invocation.ts +49 -5
- package/scripts/lane/lane-dispatch.ts +3 -3
- package/scripts/lane/lane-guard-policy.ts +5 -5
- package/scripts/lane/lane-handoff.ts +8 -1
- package/scripts/lane/lane-install.ts +12 -4
- package/scripts/lane/lane-ledger.ts +52 -1
- package/scripts/lane/lane-limit-cli.ts +8 -9
- package/scripts/lane/lane-load.ts +9 -2
- package/scripts/lane/lane-measure-cli.ts +4 -0
- package/scripts/lane/lane-parked.ts +18 -0
- package/scripts/lane/lane-preserve.ts +29 -1
- package/scripts/lane/lane-process-load.ts +125 -0
- package/scripts/lane/lane-process-stats.ts +93 -0
- package/scripts/lane/lane-registry.ts +17 -10
- package/scripts/lane/lane-restart.ts +5 -26
- package/scripts/lane/lane-session-action.ts +146 -0
- package/scripts/lane/lane-session-broker.ts +68 -125
- package/scripts/lane/lane-spent.ts +14 -3
- package/scripts/lane/lane-stats.ts +1 -0
- package/scripts/lane/lane-withdraw-cli.ts +71 -0
- package/scripts/lane/lane-withdraw.ts +182 -0
- package/scripts/lint/format.ts +4 -4
- package/scripts/lint/lint-parallel.ts +10 -3
- package/scripts/lint/lint-related-scope.ts +4 -1
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/telegram-test.ts +10 -5
- package/scripts/overrides/lockfile-overrides.ts +1 -3
- package/scripts/propagate/propagate.ts +1 -2
- package/scripts/release/release-progress.ts +3 -2
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-lint.ts +7 -4
- package/scripts/review/acceptance-map-check.ts +61 -0
- package/scripts/review/acceptance-map.ts +205 -0
- package/scripts/review/review-brief-cli.ts +1 -1
- package/scripts/review/review-record-cli.ts +6 -2
- package/scripts/rules/agent-model.ts +59 -0
- package/scripts/rules/delivered-rules.ts +11 -2
- package/scripts/rules/destructive-command.ts +6 -9
- package/scripts/rules/direct-filing.ts +3 -7
- package/scripts/rules/early-heartbeat.ts +7 -18
- package/scripts/rules/file-body.ts +6 -13
- package/scripts/rules/filing-cap.ts +4 -6
- package/scripts/rules/firing-point.ts +6 -5
- package/scripts/rules/git-force.ts +5 -9
- package/scripts/rules/guard-remedy.ts +117 -0
- package/scripts/rules/implementation-cut.ts +37 -35
- package/scripts/rules/index-guard.ts +4 -7
- package/scripts/rules/issue-comments.ts +67 -16
- package/scripts/rules/josh-git-bare.ts +3 -6
- package/scripts/rules/lane-background.ts +10 -21
- package/scripts/rules/lane-carry-conflict.ts +7 -17
- package/scripts/rules/lane-interactive-ask.ts +6 -11
- package/scripts/rules/lane-park.ts +5 -13
- package/scripts/rules/lane-split-park.ts +2 -7
- package/scripts/rules/lane-switch-main.ts +9 -12
- package/scripts/rules/last-prompt.ts +50 -5
- package/scripts/rules/oracle-consulted.ts +4 -5
- package/scripts/rules/oracle-list-cli.ts +7 -0
- package/scripts/rules/piped-verification.ts +84 -32
- package/scripts/rules/poll-loop.ts +7 -17
- package/scripts/rules/pre-gate-cut.ts +7 -21
- package/scripts/rules/prior-comment-read.ts +7 -5
- package/scripts/rules/protected-files.ts +5 -9
- package/scripts/rules/raw-field-body.ts +3 -7
- package/scripts/rules/rule-body-guard.ts +4 -11
- package/scripts/rules/rule-list.ts +4 -1
- package/scripts/rules/rule-registry-rows.ts +10 -0
- package/scripts/rules/rule-registry.ts +7 -4
- package/scripts/rules/rule-rewrite.ts +114 -0
- package/scripts/rules/rule-value.ts +7 -1
- package/scripts/rules/run-tail-rule.ts +6 -22
- package/scripts/rules/shell-body-trigger.ts +4 -6
- package/scripts/rules/shell-segments.ts +22 -0
- package/scripts/rules/stop-decision.ts +77 -0
- package/scripts/rules/stop-rules.ts +164 -77
- package/scripts/rules/tail-commands.ts +15 -1
- package/scripts/rules/test-declared-commit.ts +4 -10
- package/scripts/rules/third-party-write.ts +5 -10
- package/scripts/rules/worktree-guard.ts +5 -12
- package/scripts/run/board/run-board-cli.ts +2 -0
- package/scripts/run/board/run-board-closed.ts +8 -2
- package/scripts/run/board/run-board-github.ts +19 -3
- package/scripts/run/board/run-board-header.ts +4 -1
- package/scripts/run/board/run-board-idle.ts +31 -0
- package/scripts/run/board/run-board-labels.ts +2 -0
- package/scripts/run/board/run-board-layout.ts +1 -1
- package/scripts/run/board/run-board-read.ts +25 -12
- package/scripts/run/board/run-board-reason.ts +17 -4
- package/scripts/run/board/run-board-render-legend.ts +1 -0
- package/scripts/run/board/run-board-render-slot.ts +1 -1
- package/scripts/run/board/run-board-render-waits.ts +41 -0
- package/scripts/run/board/run-board-render.ts +6 -1
- package/scripts/run/board/run-board-row-yield.ts +1 -0
- package/scripts/run/board/run-board-state.ts +9 -0
- package/scripts/run/board/run-board-status.ts +89 -23
- package/scripts/run/board/run-board-thanks.ts +7 -2
- package/scripts/run/board/run-board-tick.ts +37 -8
- package/scripts/run/carry/run-carry-args.ts +1 -3
- package/scripts/run/carry/run-carry-conversation.ts +7 -2
- package/scripts/run/cut/run-cut-cli.ts +18 -22
- package/scripts/run/cut/run-cut-decline.ts +72 -0
- package/scripts/run/cut/run-cut-ready.ts +74 -0
- package/scripts/run/cut/run-cut-report.ts +29 -0
- package/scripts/run/cut/run-cut.ts +10 -1
- package/scripts/run/detached-launch.ts +23 -4
- package/scripts/run/entry/run-entry-cli.ts +8 -1
- package/scripts/run/event/run-event-render.ts +1 -0
- package/scripts/run/event/run-event-scope.ts +19 -1
- package/scripts/run/event/run-event-stream-emit.ts +13 -6
- package/scripts/run/event/run-event-stream.ts +4 -0
- package/scripts/run/hold/run-hold-cli.ts +14 -3
- package/scripts/run/hold/run-hold-session.ts +46 -0
- package/scripts/run/hold/run-hold.ts +13 -4
- package/scripts/run/launch-priority.ts +32 -0
- package/scripts/run/merge/run-merge-cli.ts +16 -42
- package/scripts/run/merge/run-merge-ship.ts +59 -1
- package/scripts/run/merge/run-merge-signals.ts +99 -0
- package/scripts/run/merge/run-merge-steps.ts +11 -1
- package/scripts/run/merge/run-merge.ts +22 -9
- package/scripts/run/run-ending.ts +31 -3
- package/scripts/run/run-liveness.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +5 -10
- package/scripts/run/run-poll-hook.ts +157 -0
- package/scripts/run/run-preflight.ts +1 -2
- package/scripts/run/run-step-cli.ts +22 -15
- package/scripts/run/run-step-section.ts +85 -0
- package/scripts/run/run-stop-notify.ts +1 -2
- package/scripts/run/run-watcher-guard.ts +6 -3
- package/scripts/run/ship/run-ship-cli.ts +5 -12
- package/scripts/run/ship/run-ship-detach.ts +9 -0
- package/scripts/run/ship/run-ship-next.ts +10 -2
- package/scripts/run/ship/run-ship-overlap.ts +195 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +33 -15
- package/scripts/run/ship/run-ship-preflight.ts +28 -2
- package/scripts/run/ship/run-ship-return.ts +31 -7
- package/scripts/run/ship/run-ship-review-steps.ts +25 -14
- package/scripts/run/ship/run-ship-review.ts +15 -2
- package/scripts/run/ship/run-ship-steps.ts +1 -1
- package/scripts/run/ship/run-ship-stop-context.ts +206 -0
- package/scripts/run/ship/run-ship-sync.ts +14 -6
- package/scripts/run/tidy/run-tidy-cli.ts +3 -3
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -2
- package/scripts/safe-chain/project-config.ts +7 -2
- package/scripts/sync/sync-hook-safety.ts +8 -2
- package/scripts/test/test-e2e-guard.ts +30 -5
- package/scripts/test/test-unit-guard.ts +16 -1
- package/scripts/test/unit-worker-share.ts +26 -3
- package/scripts/time-runtime/time-batch-guard.ts +3 -3
- package/scripts/time-runtime/time-hook-transcript.ts +3 -2
- package/scripts/time-runtime/time-shell.ts +39 -4
- package/scripts/time-runtime/time-spans.ts +1 -0
- package/scripts/time-runtime/time-tool-call.ts +7 -0
- package/scripts/version/effective-upstream.ts +3 -4
- package/scripts/version/kit-version-config.ts +8 -2
- package/scripts/version/latest-corepack.ts +1 -2
- package/scripts/version/release-hold.ts +11 -4
- package/scripts/version/version-commands.ts +12 -4
- package/templates/gitignore +6 -2
- package/dist/hooks/chunk-D5QBTOCZ.js +0 -68
- package/dist/hooks/chunk-UT7YC3N2.js +0 -56
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import type { CommandUsage } from './josh-command-types'
|
|
2
|
+
|
|
3
|
+
// The usage of the commands `docs/josh-commands-automation.md` documents under "Workflow",
|
|
4
|
+
// "Versioning", "Maintenance" and "Git hooks", keyed by command name. The page's usage blocks are
|
|
5
|
+
// generated from this table and `josh help <command>` prints it, so an example or a flag is written
|
|
6
|
+
// once, here (#3939).
|
|
7
|
+
const PR_TITLE = '"PR title #N"'
|
|
8
|
+
const ISSUE_URL = '--issue-url "https://..."'
|
|
9
|
+
const REVIEW_ISSUE = '--issue 2325'
|
|
10
|
+
const CHECK = '--check'
|
|
11
|
+
const JSON_FLAG = '--json'
|
|
12
|
+
const BODY_FILE_NOTE =
|
|
13
|
+
'(`-` reads stdin); use this whenever the body carries a backtick or `$`. Passing both forms is refused.'
|
|
14
|
+
|
|
15
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
16
|
+
const WORKFLOW_USAGE: Readonly<Record<string, CommandUsage>> = {
|
|
17
|
+
followup: {
|
|
18
|
+
examples: [
|
|
19
|
+
{ arguments: PR_TITLE, note: 'merges (default)' },
|
|
20
|
+
{ arguments: String.raw`${PR_TITLE} --notify-message "Implemented X:\n- change 1"` },
|
|
21
|
+
{ arguments: `${PR_TITLE} --notify-message-file completion.md` },
|
|
22
|
+
{ arguments: `${PR_TITLE} --ai-review-ignore-reason "false positive"` },
|
|
23
|
+
{ arguments: `${PR_TITLE} --no-merge`, note: 'do the work, leave the PR open' },
|
|
24
|
+
],
|
|
25
|
+
flags: [
|
|
26
|
+
{
|
|
27
|
+
names: ['--no-merge'],
|
|
28
|
+
description:
|
|
29
|
+
'do the follow-up work but do not merge; leaves the PR open (the only flag that stops the merge). `--merge` is a deprecated no-op. A PR already merged by hand skips the CI wait, the AI-review scan and the merge and runs only the post-merge tail; a completion report already on the Issue is not posted again.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
names: ['--notify-message'],
|
|
33
|
+
description: 'inline completion body; `\\n` expands to newlines.',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
names: ['--notify-message-file'],
|
|
37
|
+
description: `read the completion body from a file ${BODY_FILE_NOTE}`,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
names: ['--ai-review-ignore-reason'],
|
|
41
|
+
description: 'reason to dismiss an AI-review finding.',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
notify: {
|
|
46
|
+
examples: [
|
|
47
|
+
{ arguments: String.raw`--task-type planning ${ISSUE_URL} --body="- bullet 1\n- bullet 2"` },
|
|
48
|
+
{
|
|
49
|
+
arguments: `--task-type confirmation ${ISSUE_URL} --body-file r.md --recommended "Go" --alternative "Wait"`,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
flags: [
|
|
53
|
+
{
|
|
54
|
+
names: ['--task-type'],
|
|
55
|
+
description:
|
|
56
|
+
'one of `planning` 📋, `completion` ✅, `failure` ❌, `warning` ⚠️, `kickoff_retry` 🔄, `confirmation` ⏸️. Do not send `completion` or `warning` by hand — `josh followup` sends them.',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
names: ['--body', "--body=$'…'"],
|
|
60
|
+
description: "inline body; use `--body=$'…'` when it starts with `-`.",
|
|
61
|
+
},
|
|
62
|
+
{ names: ['--body-file'], description: `read the body from a file ${BODY_FILE_NOTE}` },
|
|
63
|
+
{
|
|
64
|
+
names: ['--repo-name', '--issue-url', '--pr-url'],
|
|
65
|
+
description:
|
|
66
|
+
'header repository, resolved in that order, then the working directory. The issue title is read from `--issue-url`.',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
names: ['--recommended', '--alternative'],
|
|
70
|
+
description:
|
|
71
|
+
'the choices appended under `JOSH_SESSION_LANG` headings; `--recommended` is required for `confirmation`, `--alternative` is repeatable.',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
'observations:flush': { examples: [{ arguments: '' }] },
|
|
76
|
+
'measure:rerun': { examples: [{ arguments: '2212' }] },
|
|
77
|
+
'review:record': {
|
|
78
|
+
examples: [
|
|
79
|
+
{ arguments: `${REVIEW_ISSUE} bug-risks:medium:src/foo.ts:42 tests:low:a.test.ts` },
|
|
80
|
+
{ arguments: REVIEW_ISSUE, note: 'a zero-finding round — records one `none` line' },
|
|
81
|
+
{
|
|
82
|
+
arguments: `${REVIEW_ISSUE} --comment`,
|
|
83
|
+
note: 'a round that passed after the PR opened — an Issue comment, no append',
|
|
84
|
+
},
|
|
85
|
+
{ arguments: `${CHECK} ${REVIEW_ISSUE}`, note: 'the merge gate: was it recorded?' },
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
bump: { examples: [{ arguments: 'major' }, { arguments: 'minor' }, { arguments: 'patch' }] },
|
|
89
|
+
release: {
|
|
90
|
+
examples: [
|
|
91
|
+
{ arguments: '' },
|
|
92
|
+
{ arguments: '--dry-run', note: 'count and report, write nothing' },
|
|
93
|
+
],
|
|
94
|
+
flags: [
|
|
95
|
+
{
|
|
96
|
+
names: ['--dry-run'],
|
|
97
|
+
description:
|
|
98
|
+
'count and report only; writes nothing, fetches nothing, and creates no work tree.',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
names: ['--help', '-h'],
|
|
102
|
+
description:
|
|
103
|
+
'print the usage line and exit 0 without fetching or releasing. Any other argument is refused with the usage line and a non-zero exit, before anything is fetched.',
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
'release:scope': {
|
|
108
|
+
examples: [
|
|
109
|
+
{ arguments: '', note: '→ required | skip | unknown' },
|
|
110
|
+
{ arguments: '--json', note: '{"scope":"…","reason":"…"} on one line' },
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
'ruleset:check': {
|
|
114
|
+
examples: [
|
|
115
|
+
{ arguments: '', note: 'report only' },
|
|
116
|
+
{ arguments: '--apply', note: 'add the missing checks to the existing rule' },
|
|
117
|
+
],
|
|
118
|
+
flags: [
|
|
119
|
+
{
|
|
120
|
+
names: ['--apply'],
|
|
121
|
+
description:
|
|
122
|
+
"append the missing checks to the ruleset's required-checks rule (or to the branch protection's contexts). It never creates a ruleset: with none, create one under Settings → Rules → Rulesets, then rerun. Writing a repository setting needs admin access, so only this flag writes — `josh sync` and `josh doctor` never do.",
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
'audit:provision': {
|
|
127
|
+
examples: [
|
|
128
|
+
{ arguments: '', note: 'no-op if a scanner is already present' },
|
|
129
|
+
{ arguments: '--force', note: 'ignore backoff, allow a longer download' },
|
|
130
|
+
],
|
|
131
|
+
flags: [
|
|
132
|
+
{
|
|
133
|
+
names: ['--force'],
|
|
134
|
+
description:
|
|
135
|
+
'ignore the 6-hour failure backoff and allow a longer download window; the command to run after fixing a network problem.',
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
'reconcile-templates': {
|
|
140
|
+
examples: [
|
|
141
|
+
{ arguments: '', note: 'regenerate copy templates + record tripwire hashes' },
|
|
142
|
+
{ arguments: CHECK, note: 'verify templates are in sync; non-zero on drift' },
|
|
143
|
+
],
|
|
144
|
+
flags: [
|
|
145
|
+
{
|
|
146
|
+
names: [CHECK],
|
|
147
|
+
description:
|
|
148
|
+
'verify only; exits non-zero on drift. A pre-commit hook runs this when a tracked source or copy template is staged.',
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
'pre-push-unit': { examples: [{ arguments: '' }] },
|
|
153
|
+
'reserved-run': {
|
|
154
|
+
examples: [
|
|
155
|
+
{ arguments: '2 -- pnpm install', note: 'hold 2 cores while installing' },
|
|
156
|
+
{ arguments: '1 -- pnpm josh audit', note: 'hold 1 core while scanning' },
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
'pre-commit-type-check': { examples: [{ arguments: '' }] },
|
|
160
|
+
'pr:classification': {
|
|
161
|
+
examples: [{ arguments: '', note: 'run by CI on a pull request; fails without one label' }],
|
|
162
|
+
},
|
|
163
|
+
'observation:record': {
|
|
164
|
+
examples: [
|
|
165
|
+
{ arguments: "flaky-e2e d1 'tests/e2e/login.test.ts' 'times out on CI only'" },
|
|
166
|
+
{
|
|
167
|
+
arguments: "flaky-e2e d1 'src/app.ts' 'fails there too' --checkout ~/Development/app",
|
|
168
|
+
note: "another repository's ledger",
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
flags: [
|
|
172
|
+
{
|
|
173
|
+
names: ['--checkout <path>'],
|
|
174
|
+
description: "count and append in that repository's `.josh/observations/` instead.",
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
'release:github': {
|
|
179
|
+
examples: [
|
|
180
|
+
{ arguments: '', note: 'run by CI with GH_TOKEN, RELEASE_TAG and GITHUB_REPOSITORY set' },
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
'latest:scope': {
|
|
184
|
+
examples: [
|
|
185
|
+
{ arguments: '', note: 'required or skip, the reason on stderr' },
|
|
186
|
+
{ arguments: '--record', note: 'note a finished josh latest run' },
|
|
187
|
+
{ arguments: JSON_FLAG, note: 'the verdict and the reason as JSON' },
|
|
188
|
+
],
|
|
189
|
+
flags: [
|
|
190
|
+
{ names: ['--record'], description: 'write the completion record `josh latest` ends with.' },
|
|
191
|
+
{ names: [JSON_FLAG], description: 'emit the verdict and its reason as JSON.' },
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
'latest:guard': { examples: [{ arguments: '', note: 'refuses inside a lane' }] },
|
|
195
|
+
'prevent-main-commit': { examples: [{ arguments: '', note: 'run by the pre-commit hook' }] },
|
|
196
|
+
'check-commit-message': {
|
|
197
|
+
examples: [{ arguments: '.git/COMMIT_EDITMSG', note: 'run by the commit-msg hook' }],
|
|
198
|
+
},
|
|
199
|
+
'secretlint-scan': {
|
|
200
|
+
examples: [{ arguments: 'src/app.ts .env.example', note: 'the staged paths' }],
|
|
201
|
+
},
|
|
202
|
+
'pre-commit-lint': {
|
|
203
|
+
examples: [
|
|
204
|
+
{ arguments: 'cspell src/app.ts' },
|
|
205
|
+
{ arguments: 'prettier src/app.ts' },
|
|
206
|
+
{ arguments: 'eslint src/app.ts' },
|
|
207
|
+
],
|
|
208
|
+
},
|
|
209
|
+
}
|
|
210
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
211
|
+
|
|
212
|
+
export { WORKFLOW_USAGE }
|
package/scripts/josh/josh.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { doctor_consumer } from '#scripts/doctor/doctor-consumer'
|
|
2
|
+
import { command_usage } from './command-usage'
|
|
2
3
|
import { find_package_directory, josh_logic, UNKNOWN_COMMAND_EXIT_CODE } from './josh-logic'
|
|
3
4
|
|
|
4
5
|
const ARGV_OFFSET = 2
|
|
@@ -12,10 +13,6 @@ const HELP_COMMANDS: ReadonlySet<string> = new Set(['help', '--help', '-h'])
|
|
|
12
13
|
// A bare `--all` in the command slot is a help request, not a command.
|
|
13
14
|
const ALL_FLAG = '--all'
|
|
14
15
|
|
|
15
|
-
function print_help(is_all: boolean, is_consumer: boolean): void {
|
|
16
|
-
console.info(josh_logic.format_help(is_all, is_consumer))
|
|
17
|
-
}
|
|
18
|
-
|
|
19
16
|
// Both halves go to stderr. The help listing is a diagnosis here, not the answer, and a shell
|
|
20
17
|
// wiring `--port $(josh port dev)` reads stdout alone, so a command name this kit cannot resolve
|
|
21
18
|
// has to leave that stream empty rather than substitute the whole toolkit index (#825).
|
|
@@ -24,6 +21,18 @@ function handle_unknown(cmd: string): never {
|
|
|
24
21
|
process.exit(1)
|
|
25
22
|
}
|
|
26
23
|
|
|
24
|
+
// `josh help <command>` prints that one command's usage — the text its reference page renders
|
|
25
|
+
// (#3932); a flag in the topic slot is still a listing request (`josh --help --all`).
|
|
26
|
+
function print_help(is_all: boolean, is_consumer: boolean, topic: string | undefined): void {
|
|
27
|
+
if (topic === undefined || topic.startsWith('-')) {
|
|
28
|
+
console.info(josh_logic.format_help(is_all, is_consumer))
|
|
29
|
+
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.info(command_usage.format_command_help(topic) ?? handle_unknown(topic))
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
// `process.exit` truncates a piped stdout at its buffer size, and the output at risk is the script's
|
|
28
37
|
// own — `scripts/gate/verification-gate.ts` writes its per-check blocks
|
|
29
38
|
// and its failure summary through this process, and sets `process.exitCode` rather than exiting for
|
|
@@ -44,7 +53,7 @@ async function main(): Promise<void> {
|
|
|
44
53
|
const is_consumer = doctor_consumer.is_kit_consumer(find_package_directory(process.cwd()))
|
|
45
54
|
|
|
46
55
|
if (!cmd || cmd === ALL_FLAG || HELP_COMMANDS.has(cmd)) {
|
|
47
|
-
print_help(is_all, is_consumer)
|
|
56
|
+
print_help(is_all, is_consumer, process.argv[ARGV_OFFSET + 1])
|
|
48
57
|
|
|
49
58
|
return
|
|
50
59
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { ancestor_directories } from '#scripts/lib/ancestor-directories'
|
|
4
|
+
|
|
5
|
+
const PACKAGE_JSON = 'package.json'
|
|
6
|
+
|
|
7
|
+
// Resolve the kit package root by ascending to the nearest package.json. This works both
|
|
8
|
+
// from the bundled dist/josh.js (one level under the root) and from the tsx source at
|
|
9
|
+
// scripts/josh/ (two levels), so this file's depth no longer has to be hard-coded.
|
|
10
|
+
// A leaf apart from `josh-logic`, so a bundled command can import it without pulling the
|
|
11
|
+
// dispatcher's main-guarded closure into its single-file bundle.
|
|
12
|
+
function find_package_directory(start_directory: string): string {
|
|
13
|
+
return (
|
|
14
|
+
ancestor_directories.nearest(start_directory, (directory) =>
|
|
15
|
+
existsSync(path.join(directory, PACKAGE_JSON)),
|
|
16
|
+
) ?? start_directory
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { find_package_directory }
|
|
@@ -89,8 +89,9 @@ function process_trace_default(issue: string): ProcessTrace {
|
|
|
89
89
|
|
|
90
90
|
process_tools.throw_if_missing(PGREP_COMMAND, result.error)
|
|
91
91
|
|
|
92
|
-
if (result.status === PROCESS_FOUND)
|
|
93
|
-
|
|
92
|
+
if (result.status === PROCESS_FOUND || lane_handoff.is_ship_running(issue, process.cwd())) {
|
|
93
|
+
return PROCESS_ALIVE
|
|
94
|
+
}
|
|
94
95
|
|
|
95
96
|
return result.status === PROCESS_NOT_FOUND ? PROCESS_NONE : PROCESS_UNKNOWN
|
|
96
97
|
}
|
|
@@ -73,8 +73,14 @@ function seated_limit(limit: number): number {
|
|
|
73
73
|
// Never negative: a repository holding more `in-progress` issues than the limit allows — the limit
|
|
74
74
|
// was lowered, or a stale label outlived its run — has no free lane, and a negative count read as
|
|
75
75
|
// "how many to offer" would be a slice nobody meant.
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
//
|
|
77
|
+
// **A lane that holds no place under the limit still holds its port seat** (joshuafolkken/kit#3967):
|
|
78
|
+
// `seated` counts every open lane, so the free count never offers more launches than seats are left.
|
|
79
|
+
function free_lanes(limit: number, occupied: number, seated = occupied): number {
|
|
80
|
+
const by_limit = seated_limit(limit) - occupied
|
|
81
|
+
const by_seats = lane_seed_policy.LAST_LANE_SEAT - seated
|
|
82
|
+
|
|
83
|
+
return Math.max(NO_LANES, Math.min(by_limit, by_seats))
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
const lane_capacity = {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { lane_ledger, type GateCheckRecord, type GateEntry, type LedgerEntry } from './lane-ledger'
|
|
2
|
+
import { lane_stage_stats } from './lane-stage-stats'
|
|
3
|
+
import { lane_stats, type StatsWindow } from './lane-stats'
|
|
4
|
+
|
|
5
|
+
// Which check a gate waited on: the ledger's per-check rows of one period reduced to one row per check
|
|
6
|
+
// — median, maximum, how many runs and how many were reused — printed last by `josh lane:stats`. The
|
|
7
|
+
// rows are in the order the checks first appear.
|
|
8
|
+
//
|
|
9
|
+
// **A reused check is counted, never timed.** It started no process, so its zero would pull the median
|
|
10
|
+
// toward a check that never ran; a check with only reused rows prints `not measured`.
|
|
11
|
+
|
|
12
|
+
const MS_PER_SECOND = 1000
|
|
13
|
+
const DECIMALS = 1
|
|
14
|
+
const COLUMNS = ['check', 'median (s)', 'max (s)', 'runs', 'reused'] as const
|
|
15
|
+
|
|
16
|
+
function is_gate(entry: LedgerEntry): entry is GateEntry {
|
|
17
|
+
return entry.kind === lane_ledger.KIND.GATE
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function cell(milliseconds: number | undefined): string {
|
|
21
|
+
return milliseconds === undefined
|
|
22
|
+
? lane_stage_stats.NOT_MEASURED
|
|
23
|
+
: (milliseconds / MS_PER_SECOND).toFixed(DECIMALS)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function check_row(label: string, checks: ReadonlyArray<GateCheckRecord>): string {
|
|
27
|
+
const runs = checks.filter((check) => check.label === label)
|
|
28
|
+
const timed = runs.filter((check) => check.is_reused !== true).map((check) => check.elapsed_ms)
|
|
29
|
+
|
|
30
|
+
return lane_stats.to_row([
|
|
31
|
+
label,
|
|
32
|
+
cell(lane_stats.median(timed)),
|
|
33
|
+
cell(lane_stats.peak(timed)),
|
|
34
|
+
String(runs.length),
|
|
35
|
+
String(runs.length - timed.length),
|
|
36
|
+
])
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// The period's table: `entries` is the whole ledger, filtered here to `window`.
|
|
40
|
+
function table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string {
|
|
41
|
+
const checks = lane_stats
|
|
42
|
+
.in_window(entries, window)
|
|
43
|
+
.filter(is_gate)
|
|
44
|
+
.flatMap((gate) => gate.checks ?? [])
|
|
45
|
+
const labels = [...new Set(checks.map((check) => check.label))]
|
|
46
|
+
|
|
47
|
+
return [
|
|
48
|
+
lane_stats.to_row(COLUMNS),
|
|
49
|
+
lane_stats.to_row(COLUMNS.map(() => '---')),
|
|
50
|
+
...labels.map((label) => check_row(label, checks)),
|
|
51
|
+
].join('\n')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const lane_check_stats = { table }
|
|
55
|
+
|
|
56
|
+
export { lane_check_stats }
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
import { agent_role_profile } from '#scripts/agent/agent-role-profile'
|
|
1
2
|
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
2
3
|
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
3
4
|
import { run_ship_next, type ShipResume } from '#scripts/run/ship/run-ship-next'
|
|
4
5
|
import type { Stage } from '#scripts/run/ship/run-ship-stage'
|
|
6
|
+
import { run_ship_stop_context, type StopContext } from '#scripts/run/ship/run-ship-stop-context'
|
|
5
7
|
|
|
6
8
|
interface ShipStop extends ShipResume {
|
|
7
9
|
stage: Stage
|
|
10
|
+
context?: StopContext
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
const CHILD_INVOCATION = 'fullrun'
|
|
14
|
+
const LINE_BREAK = '\n'
|
|
15
|
+
// What a brokered reviewer's prompt ends with, so the one pattern below finds it too.
|
|
16
|
+
const REVIEW_INVOCATION = 'the reviewer of lane'
|
|
11
17
|
const RESUME_GUIDE = '.claude/skills/workflow-commands/pre-gate-cut.md'
|
|
12
18
|
// What a detached `josh ship --detach` supervisor's command line carries. It ends
|
|
13
19
|
// with the `"<title> #<N>"` title on purpose, so the liveness pattern below finds it by the same trailing
|
|
@@ -31,10 +37,20 @@ function child_invocation(issue: string): string {
|
|
|
31
37
|
// pattern stopped matching as finished — parking an issue that was still shipping. The supervisor's
|
|
32
38
|
// command line ends with its `#<N>` title, so the one extended pattern covers both, and the wait, the
|
|
33
39
|
// liveness read and the reaper keep searching with a single pattern.
|
|
40
|
+
//
|
|
41
|
+
// **A brokered reviewer counts as the child too** (joshuafolkken/kit#3878). The lane's broker starts it
|
|
42
|
+
// for a ship and it outlives a ship that stopped waiting: unmatched, the lane read as finished, the
|
|
43
|
+
// run parked the issue under it, and the reap left it running checks in the parked lane.
|
|
34
44
|
function process_pattern(issue: string): string {
|
|
35
45
|
issue_number_shape.require_issue_number(issue)
|
|
36
46
|
|
|
37
|
-
return `(${CHILD_INVOCATION}|${SHIP_PROCESS} .*) ${issue_cite.plain(issue)}$`
|
|
47
|
+
return `(${CHILD_INVOCATION}|${REVIEW_INVOCATION}|${SHIP_PROCESS} .*) ${issue_cite.plain(issue)}$`
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function review_invocation(issue: string): string {
|
|
51
|
+
issue_number_shape.require_issue_number(issue)
|
|
52
|
+
|
|
53
|
+
return `${REVIEW_INVOCATION} ${issue_cite.plain(issue)}`
|
|
38
54
|
}
|
|
39
55
|
|
|
40
56
|
function resume_invocation(issue: string): string {
|
|
@@ -67,14 +83,41 @@ function outage_resume_invocation(issue: string): string {
|
|
|
67
83
|
// **A known stage puts the next command in the prompt**, so the relaunched
|
|
68
84
|
// session runs it rather than re-deriving it from `chain-rule.md`. An OpenAI lane's supervisor sees only
|
|
69
85
|
// that the ship failed, not where, so without a stage the prompt points at `run:step` as before.
|
|
86
|
+
//
|
|
87
|
+
// **A stop that carries its context puts it in the prompt too** — the failed output's
|
|
88
|
+
// tail and the changed files (`run-ship-stop-context.ts`), so the session starts at the fix rather than
|
|
89
|
+
// at `josh ship --log` and `git diff` (joshuafolkken/kit#3923).
|
|
90
|
+
//
|
|
91
|
+
// The context gets what the rest of the prompt leaves of the one argv element's cap, so the whole
|
|
92
|
+
// prompt still launches (joshuafolkken/kit#3964).
|
|
93
|
+
function known_stop_lines(
|
|
94
|
+
issue: string,
|
|
95
|
+
stop: ShipStop,
|
|
96
|
+
frame: ReadonlyArray<string>,
|
|
97
|
+
): ReadonlyArray<string> {
|
|
98
|
+
const { context } = stop
|
|
99
|
+
const is_excerpted = run_ship_stop_context.has_excerpt(context)
|
|
100
|
+
const next = run_ship_next.next_step(issue, stop.stage, stop, is_excerpted)
|
|
101
|
+
|
|
102
|
+
if (context === undefined) return [next]
|
|
103
|
+
|
|
104
|
+
const fixed = [...frame, next].join(LINE_BREAK).length + LINE_BREAK.length
|
|
105
|
+
const budget = agent_role_profile.MAX_VALUE_LENGTH - fixed
|
|
106
|
+
|
|
107
|
+
return [next, run_ship_stop_context.describe(issue, context, budget)]
|
|
108
|
+
}
|
|
109
|
+
|
|
70
110
|
function ship_stop_invocation(issue: string, stop?: ShipStop): string {
|
|
71
111
|
const opening = `Resuming the lane child for issue ${issue_cite.plain(issue)} after its detached ship supervisor stopped at a failed stage — do not re-read the workflow-commands entry documents (SKILL.md, fullrun.md).`
|
|
72
|
-
const
|
|
112
|
+
const closing = `Do not re-plan or re-implement what is already on the branch. ${child_invocation(issue)}`
|
|
113
|
+
const middle =
|
|
73
114
|
stop === undefined
|
|
74
|
-
?
|
|
75
|
-
|
|
115
|
+
? [
|
|
116
|
+
`Run \`pnpm josh run:step ${issue}\` and read the stopped report it names, fix what stopped the ship, then hand the region back per chain-rule.md.`,
|
|
117
|
+
]
|
|
118
|
+
: known_stop_lines(issue, stop, [opening, closing])
|
|
76
119
|
|
|
77
|
-
return
|
|
120
|
+
return [opening, ...middle, closing].join(LINE_BREAK)
|
|
78
121
|
}
|
|
79
122
|
|
|
80
123
|
const lane_child_invocation = {
|
|
@@ -82,6 +125,7 @@ const lane_child_invocation = {
|
|
|
82
125
|
outage_resume_invocation,
|
|
83
126
|
process_pattern,
|
|
84
127
|
resume_invocation,
|
|
128
|
+
review_invocation,
|
|
85
129
|
ship_stop_invocation,
|
|
86
130
|
}
|
|
87
131
|
|
|
@@ -7,7 +7,7 @@ import { IN_PROGRESS_LABEL } from '#scripts/issue/issue-labels'
|
|
|
7
7
|
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
8
8
|
import { session_cite } from '#scripts/issue/session-cite'
|
|
9
9
|
import { telegram_notify } from '#scripts/notify/telegram-notify'
|
|
10
|
-
import { detached_launch } from '#scripts/run/detached-launch'
|
|
10
|
+
import { detached_launch, type LaunchArgv } from '#scripts/run/detached-launch'
|
|
11
11
|
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
12
12
|
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
13
13
|
import { run_ending } from '#scripts/run/run-ending'
|
|
@@ -197,7 +197,7 @@ function existing_dispatch(request: StartRequest): DispatchOutcome | undefined {
|
|
|
197
197
|
return dispatched_of(request, active.pid, [])
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
function launch_argv(request: StartRequest, nonce: string | undefined):
|
|
200
|
+
function launch_argv(request: StartRequest, nonce: string | undefined): LaunchArgv {
|
|
201
201
|
if (request.profile.provider !== 'openai') return request.argv
|
|
202
202
|
if (nonce === undefined) throw new Error('OpenAI supervisor nonce is missing')
|
|
203
203
|
|
|
@@ -404,7 +404,7 @@ function log_sentence(outcome: Dispatched, issue: string): string {
|
|
|
404
404
|
return ` Its output is NOT being kept — ${outcome.notes.join(NOTE_SEPARATOR)} — so ${outcome.log_path} will not grow and the process trace is the only answer: ${poll}.`
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
return ` It writes to ${outcome.log_path}.
|
|
407
|
+
return ` It writes to ${outcome.log_path}. Wait on it with \`pnpm josh lane:await ${issue} --owner "$PPID"\` in the background and end the turn; once that output falls silent, ${poll}.`
|
|
408
408
|
}
|
|
409
409
|
|
|
410
410
|
// Whether this dispatch resumed the disconnected child's session or started fresh — the report the
|
|
@@ -45,27 +45,27 @@ interface LaneGuardEntry {
|
|
|
45
45
|
const LANE_GUARD_POLICY: ReadonlyArray<LaneGuardEntry> = [
|
|
46
46
|
{
|
|
47
47
|
id: 'investigation',
|
|
48
|
-
mode_in_lane_child: '
|
|
48
|
+
mode_in_lane_child: 'refuse',
|
|
49
49
|
because:
|
|
50
|
-
'
|
|
50
|
+
'the notice was measured not to move the reading — 52% of lane cost stayed in main-line exploration — and the refusal fires once per accumulation, a round trip the child survives as it survives the rule row, so the child is refused like the main line',
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
id: 'batching',
|
|
54
54
|
mode_in_lane_child: 'off',
|
|
55
55
|
because:
|
|
56
|
-
'a refusal ends a child turn
|
|
56
|
+
'a refusal ends a child turn and every advisory notice was measured not to move the call density, so the guard is off and the density stays readable through `josh time:density`',
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
id: 'duplicate-read',
|
|
60
60
|
mode_in_lane_child: 'notice',
|
|
61
61
|
because:
|
|
62
|
-
'a refusal ends a child turn
|
|
62
|
+
'a refusal ends a child turn, yet unchanged re-reads are measured in lane children above all, so the child is nudged to scroll up to the earlier read by a notice rather than killed',
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
id: 'rule',
|
|
66
66
|
mode_in_lane_child: 'refuse',
|
|
67
67
|
because:
|
|
68
|
-
|
|
68
|
+
'it carries the lane-only rules a child depends on (`pre-gate-cut`, `implementation-cut`, `lane-park`) and the safety rules it must still obey, and a notice was rejected despite the collateral a refusal costs a batched sibling, because a cut carried as prose was measured never to fire',
|
|
69
69
|
},
|
|
70
70
|
]
|
|
71
71
|
|
|
@@ -24,6 +24,13 @@ function is_ship_running(issue: string, directory: string): boolean {
|
|
|
24
24
|
)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// When the detached ship for `issue` that is still live was launched, or `undefined` where none is.
|
|
28
|
+
function ship_running_since(issue: string, directory: string): number | undefined {
|
|
29
|
+
const repository = git_common_directory.repository(directory)
|
|
30
|
+
|
|
31
|
+
return repository === undefined ? undefined : run_ship_detach.running_since(repository, issue)
|
|
32
|
+
}
|
|
33
|
+
|
|
27
34
|
// This session is the dispatched lane child for `directory` and its own ship is running.
|
|
28
35
|
function is_handed_off(directory: string, source: MarkerSource = process.env): boolean {
|
|
29
36
|
const issue = lane_child_marker.marked_issue(source)
|
|
@@ -33,6 +40,6 @@ function is_handed_off(directory: string, source: MarkerSource = process.env): b
|
|
|
33
40
|
return is_ship_running(issue, directory)
|
|
34
41
|
}
|
|
35
42
|
|
|
36
|
-
const lane_handoff = { is_handed_off, is_ship_running }
|
|
43
|
+
const lane_handoff = { is_handed_off, is_ship_running, ship_running_since }
|
|
37
44
|
|
|
38
45
|
export { lane_handoff }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
|
+
import { core_budget } from '#scripts/gate/core-budget'
|
|
3
4
|
import { buffered_process } from '#scripts/lib/buffered-process'
|
|
4
5
|
import { INSTALL_TIMEOUT_MS } from '#scripts/lib/timeouts'
|
|
5
6
|
|
|
@@ -68,10 +69,17 @@ function has_manifest(directory: string): boolean {
|
|
|
68
69
|
async function install_dependencies(directory: string): Promise<InstallResult> {
|
|
69
70
|
if (!has_manifest(directory)) return { is_installed: true, output: NO_MANIFEST_OUTPUT }
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
// The install claims its place in the core budget (joshuafolkken/kit#3944): a batch opens its lanes
|
|
73
|
+
// together, and each install ran beside the other lanes' gates off the ledger.
|
|
74
|
+
const result = await core_budget.with_command_reservation(
|
|
75
|
+
core_budget.CORE_WEIGHTS.install,
|
|
76
|
+
async () =>
|
|
77
|
+
await buffered_process.run_buffered_process(INSTALL_ARGUMENTS, {
|
|
78
|
+
cwd: directory,
|
|
79
|
+
timeout_ms: INSTALL_TIMEOUT_MS,
|
|
80
|
+
}),
|
|
81
|
+
{ memory_mb: core_budget.MEMORY_MB.install, command: 'lane install' },
|
|
82
|
+
)
|
|
75
83
|
|
|
76
84
|
return { is_installed: !buffered_process.is_process_failed(result), output: result.output }
|
|
77
85
|
}
|