@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,110 @@
|
|
|
1
|
+
import { canonical_command, COMMAND_MAP } from './josh-command-map'
|
|
2
|
+
import type { CommandUsage } from './josh-command-types'
|
|
3
|
+
import { AUTOMATION_USAGE } from './josh-usage-automation'
|
|
4
|
+
import { BACKLOG_USAGE } from './josh-usage-backlog'
|
|
5
|
+
import { DEVELOPER_USAGE } from './josh-usage-developer'
|
|
6
|
+
import { HOOK_USAGE } from './josh-usage-hooks'
|
|
7
|
+
import { ISSUE_USAGE } from './josh-usage-issue'
|
|
8
|
+
import { REVIEW_USAGE } from './josh-usage-review'
|
|
9
|
+
import { RUN_USAGE } from './josh-usage-run'
|
|
10
|
+
import { SESSION_USAGE } from './josh-usage-session'
|
|
11
|
+
import { WORKFLOW_USAGE } from './josh-usage-workflow'
|
|
12
|
+
|
|
13
|
+
// The single renderer of a command's usage. `josh help <command>` prints it and
|
|
14
|
+
// `scripts/document/generate-command-usage.ts` writes it between a reference page's usage markers,
|
|
15
|
+
// so the terminal and the page are one text (#3932).
|
|
16
|
+
|
|
17
|
+
type UsageTable = Readonly<Record<string, CommandUsage>>
|
|
18
|
+
|
|
19
|
+
// Which reference page renders each usage table — the one place a table is tied to its page, so the
|
|
20
|
+
// generator's coverage check and `josh help` read the same set (#3981).
|
|
21
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
22
|
+
const USAGE_PAGE_TABLES: Readonly<Record<string, ReadonlyArray<UsageTable>>> = {
|
|
23
|
+
'docs/josh-commands.md': [DEVELOPER_USAGE],
|
|
24
|
+
'docs/josh-commands-run.md': [RUN_USAGE, SESSION_USAGE],
|
|
25
|
+
'docs/josh-commands-backlog.md': [ISSUE_USAGE, BACKLOG_USAGE, REVIEW_USAGE],
|
|
26
|
+
'docs/josh-commands-automation.md': [AUTOMATION_USAGE, WORKFLOW_USAGE, HOOK_USAGE],
|
|
27
|
+
}
|
|
28
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
29
|
+
const COMMAND_USAGE: UsageTable = Object.fromEntries(
|
|
30
|
+
Object.values(USAGE_PAGE_TABLES)
|
|
31
|
+
.flat()
|
|
32
|
+
.flatMap((table) => Object.entries(table)),
|
|
33
|
+
)
|
|
34
|
+
const NOTE_GAP = 3
|
|
35
|
+
|
|
36
|
+
interface ExampleLine {
|
|
37
|
+
command: string
|
|
38
|
+
note: string | undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function usage_for(name: string): CommandUsage | undefined {
|
|
42
|
+
return Object.hasOwn(COMMAND_USAGE, name) ? COMMAND_USAGE[name] : undefined
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function example_line(name: string, example: CommandUsage['examples'][number]): ExampleLine {
|
|
46
|
+
const command = example.arguments ? `pnpm josh ${name} ${example.arguments}` : `pnpm josh ${name}`
|
|
47
|
+
|
|
48
|
+
return { command, note: example.note }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Every comment starts in one column, so a block reads as a table of what each spelling does.
|
|
52
|
+
function format_examples(name: string, usage: CommandUsage): string {
|
|
53
|
+
const lines = usage.examples.map((example) => example_line(name, example))
|
|
54
|
+
const width = Math.max(...lines.map((line) => line.command.length)) + NOTE_GAP
|
|
55
|
+
const rendered = lines.map((line) =>
|
|
56
|
+
line.note === undefined ? line.command : `${line.command.padEnd(width)}# ${line.note}`,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
return ['```bash', ...rendered, '```'].join('\n')
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function code_span(text: string): string {
|
|
63
|
+
return `\`${text}\``
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function format_flags(flags: NonNullable<CommandUsage['flags']>): string {
|
|
67
|
+
const items = flags.map(
|
|
68
|
+
(flag) =>
|
|
69
|
+
`- ${flag.names.map((spelling) => code_span(spelling)).join(' / ')} — ${flag.description}`,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
return ['**Options:**', '', ...items].join('\n')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function format_usage(name: string): string | undefined {
|
|
76
|
+
const usage = usage_for(name)
|
|
77
|
+
if (usage === undefined) return undefined
|
|
78
|
+
const flags = usage.flags === undefined ? [] : [format_flags(usage.flags)]
|
|
79
|
+
|
|
80
|
+
return [format_examples(name, usage), ...flags].join('\n\n')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// `josh help <command>`: the synopsis line, the description, then the usage block when the command
|
|
84
|
+
// has one. An alias resolves to its command; a name that is neither answers `undefined`.
|
|
85
|
+
function format_command_help(input: string): string | undefined {
|
|
86
|
+
const name = canonical_command(input)
|
|
87
|
+
const entry = Object.hasOwn(COMMAND_MAP, name) ? COMMAND_MAP[name] : undefined
|
|
88
|
+
if (entry === undefined) return undefined
|
|
89
|
+
const [synopsis] = entry.reference
|
|
90
|
+
const head = synopsis ? `josh ${name} ${synopsis}` : `josh ${name}`
|
|
91
|
+
const usage = format_usage(name)
|
|
92
|
+
|
|
93
|
+
return [head, '', entry.description, ...(usage === undefined ? [] : ['', usage])].join('\n')
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// The commands whose usage blocks a reference page renders — the keys of the tables tied to it.
|
|
97
|
+
function page_commands(page: string): Array<string> {
|
|
98
|
+
const tables = Object.hasOwn(USAGE_PAGE_TABLES, page) ? USAGE_PAGE_TABLES[page] : undefined
|
|
99
|
+
|
|
100
|
+
return (tables ?? []).flatMap((table) => Object.keys(table))
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const command_usage = {
|
|
104
|
+
USAGE_PAGES: Object.keys(USAGE_PAGE_TABLES),
|
|
105
|
+
format_command_help,
|
|
106
|
+
format_usage,
|
|
107
|
+
page_commands,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export { command_usage }
|
|
@@ -211,9 +211,7 @@ function is_own_record(stamp: FileMapStamp): boolean {
|
|
|
211
211
|
function complete_at(target: string): string | undefined {
|
|
212
212
|
const stamp = read_at(target)
|
|
213
213
|
|
|
214
|
-
if (stamp === undefined) return undefined
|
|
215
|
-
|
|
216
|
-
if (!is_own_record(stamp)) return undefined
|
|
214
|
+
if (stamp === undefined || !is_own_record(stamp)) return undefined
|
|
217
215
|
|
|
218
216
|
return stamp_file.write_stamp(target, { ...stamp, completed_at: new Date().toISOString() })
|
|
219
217
|
}
|
|
@@ -87,8 +87,8 @@ function deny_envelope(reason: string): string {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// **A rewrite, not a refusal**: the call proceeds with `updated_input` merged
|
|
90
|
-
// over its own
|
|
91
|
-
//
|
|
90
|
+
// over its own and is allowed past the permission prompt; a settings `deny` rule still wins over it.
|
|
91
|
+
// Where the line may carry commands the hook did not write, `flow_rewrite_envelope` is the one to use.
|
|
92
92
|
function rewrite_envelope(updated_input: Record<string, unknown>, context: string): string {
|
|
93
93
|
return JSON.stringify({
|
|
94
94
|
systemMessage: context,
|
|
@@ -101,6 +101,20 @@ function rewrite_envelope(updated_input: Record<string, unknown>, context: strin
|
|
|
101
101
|
})
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
// **A rewrite that leaves the permission to the harness.** No `permissionDecision`, so the rewritten
|
|
105
|
+
// call meets the same permission flow the typed one would have — whatever else rides the line beside
|
|
106
|
+
// the rewritten part is prompted for, or not, exactly as before (joshuafolkken/kit#3875).
|
|
107
|
+
function flow_rewrite_envelope(updated_input: Record<string, unknown>, context: string): string {
|
|
108
|
+
return JSON.stringify({
|
|
109
|
+
systemMessage: context,
|
|
110
|
+
hookSpecificOutput: {
|
|
111
|
+
hookEventName: HOOK_EVENT_NAME,
|
|
112
|
+
updatedInput: updated_input,
|
|
113
|
+
additionalContext: context,
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
104
118
|
// **A notice, not a decision.** It carries no `permissionDecision`, so the call proceeds exactly as it
|
|
105
119
|
// would have; `additionalContext` is what reaches the model, and `systemMessage` is what the person
|
|
106
120
|
// watching sees. Both are filled because either channel alone leaves one of the two blind — and the
|
|
@@ -476,6 +490,7 @@ const hook_decision = {
|
|
|
476
490
|
deny_envelope,
|
|
477
491
|
emit_outcome,
|
|
478
492
|
fault_notice,
|
|
493
|
+
flow_rewrite_envelope,
|
|
479
494
|
is_switch_enabled,
|
|
480
495
|
is_switch_opt_in,
|
|
481
496
|
load_environment_file,
|
|
@@ -77,6 +77,7 @@ const ALIASES: Record<string, string> = {
|
|
|
77
77
|
tm: 'time',
|
|
78
78
|
tmd: 'time:density',
|
|
79
79
|
rtr: 'retrospective',
|
|
80
|
+
ca: 'cost:audit',
|
|
80
81
|
rvf: 'review:findings',
|
|
81
82
|
ruv: 'rule:value',
|
|
82
83
|
ev: 'eval',
|
|
@@ -86,6 +87,7 @@ const ALIASES: Record<string, string> = {
|
|
|
86
87
|
lst: 'lane:stats',
|
|
87
88
|
lli: 'lane:limit',
|
|
88
89
|
lrs: 'lane:restart',
|
|
90
|
+
lwd: 'lane:withdraw',
|
|
89
91
|
blr: 'backlogrun',
|
|
90
92
|
}
|
|
91
93
|
|
|
@@ -43,6 +43,25 @@ type CommandReference = readonly [
|
|
|
43
43
|
side_effects: ReadonlyArray<CommandSideEffect>,
|
|
44
44
|
]
|
|
45
45
|
|
|
46
|
+
// One `pnpm josh <command> <arguments>` line of a usage block, with the comment printed after it.
|
|
47
|
+
interface CommandExample {
|
|
48
|
+
arguments: string
|
|
49
|
+
note?: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Spellings of one option — `-y` and `--yes` — rendered side by side.
|
|
53
|
+
interface CommandFlag {
|
|
54
|
+
names: ReadonlyArray<string>
|
|
55
|
+
description: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// What `josh help <command>` prints and what the reference pages render between their usage
|
|
59
|
+
// markers — one source for both, so the page and the terminal cannot disagree (#3932).
|
|
60
|
+
interface CommandUsage {
|
|
61
|
+
examples: ReadonlyArray<CommandExample>
|
|
62
|
+
flags?: ReadonlyArray<CommandFlag>
|
|
63
|
+
}
|
|
64
|
+
|
|
46
65
|
interface CommandEntry {
|
|
47
66
|
script?: string
|
|
48
67
|
shell?: ReadonlyArray<string>
|
|
@@ -109,6 +128,13 @@ const TS_BUILD_INFO_FILE = '.tsbuildinfo'
|
|
|
109
128
|
const CSPELL_CACHE_FILE = '.cspellcache'
|
|
110
129
|
const ESLINT_EDIT_CACHE_FILE = '.eslintcache.edit'
|
|
111
130
|
const ESLINT_RELATED_CACHE_FILE = '.eslintcache.related'
|
|
131
|
+
const PRETTIER_CACHE_FILE = '.prettiercache'
|
|
132
|
+
const PRETTIER_RELATED_CACHE_FILE = '.prettiercache.related'
|
|
133
|
+
// The pre-commit hook's own, because a staged-files run on the gate's file degrades it: cspell prunes
|
|
134
|
+
// every entry the run did not visit (measured 892 KB down to 18 KB), and `eslint --quiet` stores a
|
|
135
|
+
// report without its warnings under the same config hash the gate reads.
|
|
136
|
+
const CSPELL_COMMIT_CACHE_FILE = '.cspellcache.commit'
|
|
137
|
+
const ESLINT_COMMIT_CACHE_FILE = '.eslintcache.commit'
|
|
112
138
|
|
|
113
139
|
type GateCachePortability = 'raw' | 'rooted-json'
|
|
114
140
|
|
|
@@ -139,6 +165,10 @@ const ESLINT_RELATED_CACHE_SPEC: GateCacheSpec = {
|
|
|
139
165
|
cache_file: ESLINT_RELATED_CACHE_FILE,
|
|
140
166
|
portability: ROOTED_JSON_PORTABILITY,
|
|
141
167
|
}
|
|
168
|
+
// **Prettier's caches are in neither list: they do not survive a move to another checkout.**
|
|
169
|
+
// Prettier 3 hashes each file's resolved options, *its absolute `filepath` included*, into the entry,
|
|
170
|
+
// so rebasing the keys as ESLint's are still leaves every entry a miss — two checkouts of one tree
|
|
171
|
+
// were measured sharing none of their 3,526 option hashes. Each checkout keeps a warm cache of its own.
|
|
142
172
|
const GATE_CACHE_SPECS: ReadonlyArray<GateCacheSpec> = [
|
|
143
173
|
ESLINT_CACHE_SPEC,
|
|
144
174
|
TS_CACHE_SPEC,
|
|
@@ -175,14 +205,20 @@ const GATE_CACHE_FILES: ReadonlyArray<string> = GATE_CACHE_SPECS.map((spec) => s
|
|
|
175
205
|
//
|
|
176
206
|
// **The lint's target scope is untouched.** This is where a cache is written, not what is read:
|
|
177
207
|
// `josh lint:related` narrows in front of the gate and `josh gate` still runs `josh lint` over the
|
|
178
|
-
// whole tree before any commit.
|
|
208
|
+
// whole tree before any commit. The scoped lint's prettier cache is its own for the same reason:
|
|
209
|
+
// prettier rewrites its cache file whole as well.
|
|
179
210
|
// What the ignore rules are asserted against: every cache file this package writes, wherever it is
|
|
180
|
-
// written from. The gate's
|
|
181
|
-
// ignored is committed, or spell-checked, which is a red gate with nothing
|
|
211
|
+
// written from. The gate's, the edit hook's, the scoped lint's and the pre-commit hook's — a cache
|
|
212
|
+
// file that is not ignored is committed, or spell-checked, which is a red gate with nothing
|
|
213
|
+
// misspelled in the tree.
|
|
182
214
|
const IGNORED_CACHE_FILES: ReadonlyArray<string> = [
|
|
183
215
|
...GATE_CACHE_FILES,
|
|
184
216
|
ESLINT_EDIT_CACHE_FILE,
|
|
185
217
|
ESLINT_RELATED_CACHE_FILE,
|
|
218
|
+
PRETTIER_CACHE_FILE,
|
|
219
|
+
PRETTIER_RELATED_CACHE_FILE,
|
|
220
|
+
CSPELL_COMMIT_CACHE_FILE,
|
|
221
|
+
ESLINT_COMMIT_CACHE_FILE,
|
|
186
222
|
]
|
|
187
223
|
|
|
188
224
|
// `--cache --cache-strategy content` is one convention rather than two coincidences: cspell adopted
|
|
@@ -190,11 +226,11 @@ const IGNORED_CACHE_FILES: ReadonlyArray<string> = [
|
|
|
190
226
|
const CONTENT_CACHE_FLAGS = ['--cache', '--cache-strategy', 'content'] as const
|
|
191
227
|
const CACHE_LOCATION_FLAG = '--cache-location'
|
|
192
228
|
|
|
193
|
-
//
|
|
194
|
-
// the edit hook
|
|
195
|
-
// location, a fix to the order would have to be made
|
|
196
|
-
// and its value are one unit, and a wrong order makes the tool read
|
|
197
|
-
// name rather than erroring.
|
|
229
|
+
// Every location is written with these same four flags — the eslint, prettier and spell-check caches
|
|
230
|
+
// of the gate, the scoped lint, the edit hook and the pre-commit hook — so the sequence is built here
|
|
231
|
+
// once. Spelled out per location, a fix to the order would have to be made once per location and
|
|
232
|
+
// each copy fails silently: a flag and its value are one unit, and a wrong order makes the tool read
|
|
233
|
+
// `--cache-strategy` as the file name rather than erroring.
|
|
198
234
|
function content_cache_flags(cache_file: string): ReadonlyArray<string> {
|
|
199
235
|
return [...CONTENT_CACHE_FLAGS, CACHE_LOCATION_FLAG, cache_file]
|
|
200
236
|
}
|
|
@@ -204,8 +240,12 @@ const ESLINT_EDIT_CACHE_FLAGS = content_cache_flags(ESLINT_EDIT_CACHE_FILE)
|
|
|
204
240
|
const ESLINT_RELATED_CACHE_FLAGS = content_cache_flags(ESLINT_RELATED_CACHE_FILE)
|
|
205
241
|
const TS_CACHE_FLAGS = ['--incremental', '--tsBuildInfoFile', TS_BUILD_INFO_FILE] as const
|
|
206
242
|
const CSPELL_CACHE_FLAGS = content_cache_flags(CSPELL_CACHE_FILE)
|
|
243
|
+
const PRETTIER_CACHE_FLAGS = content_cache_flags(PRETTIER_CACHE_FILE)
|
|
244
|
+
const PRETTIER_RELATED_CACHE_FLAGS = content_cache_flags(PRETTIER_RELATED_CACHE_FILE)
|
|
245
|
+
const CSPELL_COMMIT_CACHE_FLAGS = content_cache_flags(CSPELL_COMMIT_CACHE_FILE)
|
|
246
|
+
const ESLINT_COMMIT_CACHE_FLAGS = content_cache_flags(ESLINT_COMMIT_CACHE_FILE)
|
|
207
247
|
|
|
208
|
-
export type { CommandCategory, CommandEntry, GateCacheSpec }
|
|
248
|
+
export type { CommandCategory, CommandEntry, CommandUsage, GateCacheSpec }
|
|
209
249
|
// The three cache files are exported one by one as well as as a list, because `josh bench` clears
|
|
210
250
|
// them per target: the lint step writes only the eslint one, so a target
|
|
211
251
|
// that cleared the list would report a cold type check as the lint's own cost. The edit hook's cache
|
|
@@ -216,8 +256,10 @@ export {
|
|
|
216
256
|
COMMAND_SIDE_EFFECTS,
|
|
217
257
|
CSPELL_CACHE_FILE,
|
|
218
258
|
CSPELL_CACHE_FLAGS,
|
|
259
|
+
CSPELL_COMMIT_CACHE_FLAGS,
|
|
219
260
|
ESLINT_CACHE_FILE,
|
|
220
261
|
ESLINT_CACHE_FLAGS,
|
|
262
|
+
ESLINT_COMMIT_CACHE_FLAGS,
|
|
221
263
|
ESLINT_EDIT_CACHE_FLAGS,
|
|
222
264
|
ESLINT_RELATED_CACHE_FLAGS,
|
|
223
265
|
ESLINT_RELATED_CACHE_FILE,
|
|
@@ -226,6 +268,10 @@ export {
|
|
|
226
268
|
GATE_COMMAND,
|
|
227
269
|
IGNORED_CACHE_FILES,
|
|
228
270
|
OPTIONAL_ENV_FILE_FLAGS,
|
|
271
|
+
PRETTIER_CACHE_FILE,
|
|
272
|
+
PRETTIER_CACHE_FLAGS,
|
|
273
|
+
PRETTIER_RELATED_CACHE_FILE,
|
|
274
|
+
PRETTIER_RELATED_CACHE_FLAGS,
|
|
229
275
|
SHARED_CACHE_SPECS,
|
|
230
276
|
TS_BUILD_INFO_FILE,
|
|
231
277
|
TS_CACHE_FLAGS,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { core_budget } from '#scripts/gate/core-budget'
|
|
1
2
|
import { OPTIONAL_ENV_FILE_FLAGS, type CommandEntry } from './josh-command-types'
|
|
2
3
|
import { BACKLOG_COMMANDS } from './josh-commands-backlog'
|
|
3
4
|
import { DOCUMENT_COMMANDS } from './josh-commands-document'
|
|
@@ -80,6 +81,16 @@ const AI_COMMANDS: Record<string, CommandEntry> = {
|
|
|
80
81
|
category: 'AI tools',
|
|
81
82
|
reference: ['(--cut | --over <tokens-per-request>) [--path <dir>]', 'automation', ['none']],
|
|
82
83
|
},
|
|
84
|
+
'cost:audit': {
|
|
85
|
+
script: 'scripts/cost-audit/cost-audit-cli.ts',
|
|
86
|
+
description:
|
|
87
|
+
'Report AI cost over a period by session kind, tool category and guard, with cost per merge and regressions against the period before',
|
|
88
|
+
category: 'AI tools',
|
|
89
|
+
reference: ['[--period <days>]', 'maintainer', ['none']],
|
|
90
|
+
// Kit-only: it reads kit's own transcript store, like `josh retrospective`, which carries its
|
|
91
|
+
// summary line.
|
|
92
|
+
is_kit_only: true,
|
|
93
|
+
},
|
|
83
94
|
...DOCUMENT_COMMANDS,
|
|
84
95
|
time: {
|
|
85
96
|
script: 'scripts/time/time-cli.ts',
|
|
@@ -108,6 +119,8 @@ const AI_COMMANDS: Record<string, CommandEntry> = {
|
|
|
108
119
|
"Aggregate a finished run's cost, review findings, observation ledger and events into one digest",
|
|
109
120
|
category: 'AI tools',
|
|
110
121
|
reference: ['', 'maintainer', ['none']],
|
|
122
|
+
core_weight: core_budget.CORE_WEIGHTS.retrospective,
|
|
123
|
+
memory_mb: core_budget.MEMORY_MB.retrospective,
|
|
111
124
|
// Kit-only: it reads kit's own development run — the transcript store, the review ledger and the
|
|
112
125
|
// run event stream — so it means nothing in a consumer project and is dropped from a consumer's
|
|
113
126
|
// help, through the same declaration `josh time` uses for the same reason.
|
|
@@ -129,7 +129,7 @@ const DEV_COMMANDS: Record<string, CommandEntry> = {
|
|
|
129
129
|
'stop:guard': {
|
|
130
130
|
script: 'scripts/hooks/stop-guard.ts',
|
|
131
131
|
description:
|
|
132
|
-
'Claude Code Stop hook:
|
|
132
|
+
'Claude Code Stop hook: send the hold notify, release the hold and print the issue citations itself; block on the rules that need the model (reads the Stop payload on stdin)',
|
|
133
133
|
category: 'Development',
|
|
134
134
|
reference: ['', 'automation', ['none']],
|
|
135
135
|
// **No `tsx_arguments`, deliberately**, the same as `pretool:guard` above: this runs at every
|
|
@@ -19,6 +19,12 @@ const HOOKS_COMMANDS: Record<string, CommandEntry> = {
|
|
|
19
19
|
category: 'Git hooks',
|
|
20
20
|
reference: ['[paths...]', 'automation', ['none']],
|
|
21
21
|
},
|
|
22
|
+
'pre-commit-lint': {
|
|
23
|
+
script: 'scripts/hooks/pre-commit-lint.ts',
|
|
24
|
+
description: 'Git hook: run cspell, prettier or eslint over staged files from a content cache',
|
|
25
|
+
category: 'Git hooks',
|
|
26
|
+
reference: ['<cspell|prettier|eslint> [paths...]', 'automation', ['files']],
|
|
27
|
+
},
|
|
22
28
|
'pre-push-unit': {
|
|
23
29
|
script: 'scripts/hooks/pre-push-unit.ts',
|
|
24
30
|
description: 'Git hook: run unit tests, reusing a green gate recorded on the pushed tree',
|
|
@@ -83,6 +83,15 @@ const LANE_COMMANDS: Record<string, CommandEntry> = {
|
|
|
83
83
|
category: 'AI tools',
|
|
84
84
|
reference: ['<issue>', 'developer', ['files', 'git', 'processes', 'network']],
|
|
85
85
|
},
|
|
86
|
+
// `.env` is read for `JOSH_LANE_ROOT`, as every lane command reads it, so the lane is found.
|
|
87
|
+
'lane:withdraw': {
|
|
88
|
+
script: 'scripts/lane/lane-withdraw-cli.ts',
|
|
89
|
+
tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
|
|
90
|
+
description:
|
|
91
|
+
'Stop a running lane child, stash its uncommitted work, close its issue as not planned and close the lane — booked withdrawn, not as an outage or a failure',
|
|
92
|
+
category: 'AI tools',
|
|
93
|
+
reference: ['<issue> --reason <text>', 'developer', ['files', 'git', 'processes', 'network']],
|
|
94
|
+
},
|
|
86
95
|
// A live run's lane limit: `.env` is read so the bare form reports the
|
|
87
96
|
// `JOSH_LANE_LIMIT` a person set there when no override stands.
|
|
88
97
|
'lane:limit': {
|
|
@@ -106,7 +115,7 @@ const LANE_COMMANDS: Record<string, CommandEntry> = {
|
|
|
106
115
|
'lane:stats': {
|
|
107
116
|
...MEASURE_ARGUMENTS,
|
|
108
117
|
description:
|
|
109
|
-
'Print one table row of lane throughput, gate duration and machine load over a period, the per-stage durations of a lane under it,
|
|
118
|
+
'Print one table row of lane throughput, gate duration and machine load over a period, the per-stage durations of a lane under it, the wait after each ship stop reason under those, and the duration and reuse count of each gate check last',
|
|
110
119
|
category: 'AI tools',
|
|
111
120
|
reference: ['--period <days> [--limit <lane-limit>]', 'maintainer', ['none']],
|
|
112
121
|
default_script_arguments: ['stats'],
|
|
@@ -112,6 +112,11 @@ const WORKFLOW_COMMANDS: Record<string, CommandEntry> = {
|
|
|
112
112
|
// A script rather than an `sh -c` chain, because the strategy has to be named rather than left to
|
|
113
113
|
// the caller's git configuration: a bare `git pull` aborts with `Need to specify how to reconcile
|
|
114
114
|
// divergent branches` on exactly the diverged branch the command exists for.
|
|
115
|
+
//
|
|
116
|
+
// **It declares no core weight, by measurement** (joshuafolkken/kit#3944): its own work is git, and
|
|
117
|
+
// the catalog it may regenerate took 0.6s of CPU. The heavy processes seen beside it are commit
|
|
118
|
+
// hooks — its regenerated catalog's commit runs them — which reserve themselves, and a weight here
|
|
119
|
+
// would set the held mark they inherit, folding the parallel hook tools into this one place.
|
|
115
120
|
'main:merge': {
|
|
116
121
|
script: 'scripts/git/main-merge.ts',
|
|
117
122
|
description: 'Merge origin default branch into the current branch',
|
|
@@ -3,7 +3,6 @@ import path from 'node:path'
|
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
4
|
import { resolve_local_bin, resolve_package_bin } from '#scripts/build/local-bin'
|
|
5
5
|
import { core_budget } from '#scripts/gate/core-budget'
|
|
6
|
-
import { ancestor_directories } from '#scripts/lib/ancestor-directories'
|
|
7
6
|
import { package_version_schema } from '#scripts/lib/schemas'
|
|
8
7
|
import { resolve_spawn_exit } from '#scripts/lib/spawn-exit'
|
|
9
8
|
import { execaSync } from 'execa'
|
|
@@ -18,6 +17,7 @@ import {
|
|
|
18
17
|
import { composite_arguments, USAGE_ERROR_EXIT_CODE } from './josh-composite-arguments'
|
|
19
18
|
import { josh_in_process } from './josh-in-process'
|
|
20
19
|
import { kit_only } from './kit-only'
|
|
20
|
+
import { find_package_directory } from './package-directory'
|
|
21
21
|
import { run_github_prerequisite } from './run-github-prerequisite'
|
|
22
22
|
|
|
23
23
|
const COLUMN_WIDTH = 26
|
|
@@ -35,17 +35,6 @@ interface TsxRunner {
|
|
|
35
35
|
leading_arguments: ReadonlyArray<string>
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
// Resolve the kit package root by ascending to the nearest package.json. This works both
|
|
39
|
-
// from the bundled dist/josh.js (one level under the root) and from the tsx source at
|
|
40
|
-
// scripts/josh/ (two levels), so this file's depth no longer has to be hard-coded.
|
|
41
|
-
function find_package_directory(start_directory: string): string {
|
|
42
|
-
return (
|
|
43
|
-
ancestor_directories.nearest(start_directory, (directory) =>
|
|
44
|
-
existsSync(path.join(directory, PACKAGE_JSON)),
|
|
45
|
-
) ?? start_directory
|
|
46
|
-
)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
38
|
const PACKAGE_DIR = find_package_directory(path.dirname(fileURLToPath(import.meta.url)))
|
|
50
39
|
|
|
51
40
|
function resolve_tsx_executable(): string {
|
|
@@ -287,6 +276,7 @@ function declared(value: number | (() => number) | undefined): number | undefine
|
|
|
287
276
|
// without claiming a place. A command under a parent that already holds its cores claims nothing:
|
|
288
277
|
// `core_budget.with_command_reservation` reads the mark that parent set.
|
|
289
278
|
async function dispatch_entry(
|
|
279
|
+
command: string,
|
|
290
280
|
entry: CommandEntry,
|
|
291
281
|
subcommand_arguments: Array<string>,
|
|
292
282
|
): Promise<number> {
|
|
@@ -297,7 +287,7 @@ async function dispatch_entry(
|
|
|
297
287
|
return await core_budget.with_command_reservation(
|
|
298
288
|
weight,
|
|
299
289
|
async () => await run_entry(entry, subcommand_arguments),
|
|
300
|
-
{ memory_mb: declared(entry.memory_mb) },
|
|
290
|
+
{ memory_mb: declared(entry.memory_mb), command },
|
|
301
291
|
)
|
|
302
292
|
}
|
|
303
293
|
|
|
@@ -314,7 +304,7 @@ async function run_command(
|
|
|
314
304
|
const early_exit = pre_dispatch_exit(resolved, entry, subcommand_arguments, is_consumer)
|
|
315
305
|
if (early_exit !== undefined) return early_exit
|
|
316
306
|
|
|
317
|
-
return await dispatch_entry(entry, subcommand_arguments)
|
|
307
|
+
return await dispatch_entry(resolved, entry, subcommand_arguments)
|
|
318
308
|
}
|
|
319
309
|
|
|
320
310
|
const josh_logic = {
|
|
@@ -330,10 +320,11 @@ export { ALIASES, COMMAND_MAP } from './josh-command-map'
|
|
|
330
320
|
export { SPAWN_ERROR_EXIT_CODE } from '#scripts/lib/spawn-exit'
|
|
331
321
|
export { composite_arguments, USAGE_ERROR_EXIT_CODE } from './josh-composite-arguments'
|
|
332
322
|
export {
|
|
333
|
-
find_package_directory,
|
|
334
323
|
josh_logic,
|
|
335
324
|
resolve_alias,
|
|
336
325
|
resolve_tsx_executable,
|
|
337
326
|
resolve_tsx_runner,
|
|
338
327
|
UNKNOWN_COMMAND_EXIT_CODE,
|
|
339
328
|
}
|
|
329
|
+
|
|
330
|
+
export { find_package_directory } from './package-directory'
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { CommandUsage } from './josh-command-types'
|
|
2
|
+
|
|
3
|
+
// The usage of the commands `docs/josh-commands-automation.md` documents under "Development",
|
|
4
|
+
// "Project" and "AI tools", keyed by command name. The page's usage blocks are generated from this
|
|
5
|
+
// table and `josh help <command>` prints it, so an example or a flag is written once, here (#3939).
|
|
6
|
+
const STAGED = '--staged'
|
|
7
|
+
const JSON_FLAG = '--json'
|
|
8
|
+
const BRANCH_DIFF = 'the branch diff'
|
|
9
|
+
const STAGED_DIFF = 'the staged diff instead'
|
|
10
|
+
const PR_NUMBER = '42'
|
|
11
|
+
const DRY_RUN = '--dry-run'
|
|
12
|
+
const SKIP_PUBLISH_WAIT = '--skip-publish-wait'
|
|
13
|
+
|
|
14
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
15
|
+
const AUTOMATION_USAGE: Readonly<Record<string, CommandUsage>> = {
|
|
16
|
+
'refactor:scan': { examples: [{ arguments: '' }] },
|
|
17
|
+
'time:density': {
|
|
18
|
+
examples: [{ arguments: '' }, { arguments: '--lanes 5', note: 'the five most recent lanes' }],
|
|
19
|
+
flags: [
|
|
20
|
+
{
|
|
21
|
+
names: ['--lanes <n>'],
|
|
22
|
+
description: 'average over a different count of recent qualifying lanes (default 10).',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
names: ['--path <dir>'],
|
|
26
|
+
description:
|
|
27
|
+
"read another project's lane transcripts, as `josh time` does. Run it from the main checkout — a lane reads only its own transcript.",
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
'e2e:retry-check': { examples: [{ arguments: '' }] },
|
|
32
|
+
'sync:scope': {
|
|
33
|
+
examples: [
|
|
34
|
+
{ arguments: '', note: BRANCH_DIFF },
|
|
35
|
+
{ arguments: STAGED, note: STAGED_DIFF },
|
|
36
|
+
{ arguments: JSON_FLAG, note: '{"scope":"managed","reason":"..."}' },
|
|
37
|
+
],
|
|
38
|
+
flags: [
|
|
39
|
+
{ names: [STAGED], description: 'inspect the staged diff instead of the branch diff.' },
|
|
40
|
+
{ names: [JSON_FLAG], description: 'emit `{"scope","reason"}` as JSON.' },
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
'dogfood:commit': { examples: [{ arguments: '~/Development/kit-test-html-start' }] },
|
|
44
|
+
'fresh:run': {
|
|
45
|
+
examples: [
|
|
46
|
+
{ arguments: '--list', note: "kit's six patterns" },
|
|
47
|
+
{ arguments: 'kit-test-html-init', note: 'one pattern, the packed checkout' },
|
|
48
|
+
{
|
|
49
|
+
arguments: 'kit-test-html-start',
|
|
50
|
+
note: 'a GitHub pattern, the latest published version',
|
|
51
|
+
},
|
|
52
|
+
{ arguments: '--spec fresh/html-init.json', note: 'a scenario another toolkit wrote' },
|
|
53
|
+
],
|
|
54
|
+
flags: [
|
|
55
|
+
{ names: ['--list'], description: 'print the pattern names and run nothing.' },
|
|
56
|
+
{
|
|
57
|
+
names: ['--spec <file.json>'],
|
|
58
|
+
description:
|
|
59
|
+
'run the scenario in this file instead of a named pattern; the path is relative to the project root.',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
names: ['--package-version <version>'],
|
|
63
|
+
description:
|
|
64
|
+
"the published version a `package_source: published` scenario installs. Default: the registry's latest version of the package the command is run from.",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
names: ['--log-dir <dir>'],
|
|
68
|
+
description: 'where the log is written. Default: `.claude/tmp/fresh-machine`.',
|
|
69
|
+
},
|
|
70
|
+
{ names: ['--rebuild'], description: 'build the machine image without the layer cache.' },
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
'auth:setup': {
|
|
74
|
+
examples: [
|
|
75
|
+
{ arguments: '', note: 'sign in and save the token' },
|
|
76
|
+
{ arguments: '--check', note: 'ok: … saved on <date>, or missing: … and exit 1' },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
'sonar:hotspots': { examples: [{ arguments: PR_NUMBER }] },
|
|
80
|
+
'sonar:new-code': { examples: [{ arguments: PR_NUMBER }] },
|
|
81
|
+
'ui:routes': {
|
|
82
|
+
examples: [
|
|
83
|
+
{ arguments: '', note: BRANCH_DIFF },
|
|
84
|
+
{ arguments: STAGED, note: STAGED_DIFF },
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
propagate: {
|
|
88
|
+
examples: [
|
|
89
|
+
{ arguments: '' },
|
|
90
|
+
{ arguments: DRY_RUN, note: 'report targets and steps, write nothing' },
|
|
91
|
+
{ arguments: SKIP_PUBLISH_WAIT, note: 'release already known to be published' },
|
|
92
|
+
{ arguments: '--target app-kit', note: 'carry the release into one consumer only' },
|
|
93
|
+
],
|
|
94
|
+
flags: [
|
|
95
|
+
{
|
|
96
|
+
names: [DRY_RUN],
|
|
97
|
+
description:
|
|
98
|
+
'report targets and steps without writing; skips the publish wait, opens no issues.',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
names: [SKIP_PUBLISH_WAIT],
|
|
102
|
+
description: 'skip the registry poll for an already-published release.',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
names: ['--target <repo>'],
|
|
106
|
+
description:
|
|
107
|
+
'process only that consumer (`app-kit` or `joshuafolkken/app-kit`); the rest are reported `skipped` and left untouched. An unknown, ambiguous or non-dependent name fails before the publish wait, writing nothing.',
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
'repo:party': {
|
|
112
|
+
examples: [
|
|
113
|
+
{ arguments: 'joshuafolkken/kit', note: '→ first-party (in the kit session)' },
|
|
114
|
+
{ arguments: 'sveltejs/kit', note: '→ third-party' },
|
|
115
|
+
{ arguments: '', note: "no argument: the session's own repository" },
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
120
|
+
|
|
121
|
+
export { AUTOMATION_USAGE }
|