@joshuafolkken/kit 1.872.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/.claude-plugin/plugin.json +11 -0
- package/.claude/settings.json +110 -0
- package/.claude/skills/dependency-update/SKILL.md +76 -0
- package/.claude/skills/epic-commands/SKILL.md +463 -0
- package/.claude/skills/verify-ui/SKILL.md +96 -0
- package/.claude/skills/workflow-commands/SKILL.md +265 -0
- package/.claude/skills/workflow-commands/background-commands.md +130 -0
- package/.claude/skills/workflow-commands/backlogrun-child.md +364 -0
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +345 -0
- package/.claude/skills/workflow-commands/backlogrun-park.md +179 -0
- package/.claude/skills/workflow-commands/backlogrun-progress.md +600 -0
- package/.claude/skills/workflow-commands/backlogrun-steps.md +604 -0
- package/.claude/skills/workflow-commands/backlogrun.md +109 -0
- package/.claude/skills/workflow-commands/chain-rule.md +98 -0
- package/.claude/skills/workflow-commands/delegation.md +52 -0
- package/.claude/skills/workflow-commands/followup-reference.md +118 -0
- package/.claude/skills/workflow-commands/followup.md +222 -0
- package/.claude/skills/workflow-commands/fullrun-steps.md +93 -0
- package/.claude/skills/workflow-commands/fullrun.md +82 -0
- package/.claude/skills/workflow-commands/halfrun.md +73 -0
- package/.claude/skills/workflow-commands/into-target.md +48 -0
- package/.claude/skills/workflow-commands/issue-comments.md +109 -0
- package/.claude/skills/workflow-commands/issue-fold-existing.md +27 -0
- package/.claude/skills/workflow-commands/issue-scout.md +45 -0
- package/.claude/skills/workflow-commands/kickoff.md +82 -0
- package/.claude/skills/workflow-commands/latest-gate.md +85 -0
- package/.claude/skills/workflow-commands/needs-human-review.md +64 -0
- package/.claude/skills/workflow-commands/observation-filing.md +349 -0
- package/.claude/skills/workflow-commands/pre-gate-cut.md +340 -0
- package/.claude/skills/workflow-commands/prerequisite.md +62 -0
- package/.claude/skills/workflow-commands/retrospective.md +81 -0
- package/.claude/skills/workflow-commands/rule-residency.md +267 -0
- package/.claude/skills/workflow-commands/split-assessment.md +130 -0
- package/.claude/skills/workflow-commands/target-repository.md +58 -0
- package/.claude/skills/workflow-commands/working-tree-hold.md +66 -0
- package/.claude-plugin/marketplace.json +15 -0
- package/.coderabbit.yaml +50 -0
- package/.codex/config.toml +8 -0
- package/.codex/hooks.json +71 -0
- package/.cursorrules +45 -0
- package/.gitattributes +7 -0
- package/.github/dependabot.yml +19 -0
- package/.github/pull_request_template.md +1 -0
- package/.github/release.yml +18 -0
- package/.github/workflows/auto-tag.yml +111 -0
- package/.github/workflows/ci.yml +681 -0
- package/.github/workflows/dependabot-auto-merge.yml +55 -0
- package/.github/workflows/production.yml +47 -0
- package/.github/workflows/publish.yml +39 -0
- package/.github/workflows/sonar-qube.yml +34 -0
- package/.mcp.json +8 -0
- package/.ncurc.json +3 -0
- package/.prettierignore +20 -0
- package/.vscode/extensions.json +21 -0
- package/.vscode/settings.json +41 -0
- package/AGENTS.md +29 -0
- package/CLAUDE.md +207 -0
- package/CODE_OF_CONDUCT.md +132 -0
- package/GEMINI.md +30 -0
- package/LICENSE +21 -0
- package/README.md +41 -0
- package/SECURITY.md +34 -0
- package/cspell/index.yaml +177 -0
- package/dist/CLAUDE.md +207 -0
- package/dist/config-merge/index.d.ts +29 -0
- package/dist/config-merge/index.js +459 -0
- package/dist/hooks/batch-guard.js +28 -0
- package/dist/hooks/chunk-25JL6FMS.js +4970 -0
- package/dist/hooks/chunk-2ANGT3XM.js +375 -0
- package/dist/hooks/chunk-2EI5GBSW.js +42 -0
- package/dist/hooks/chunk-2OT5XE2N.js +5014 -0
- package/dist/hooks/chunk-2RUPMGGV.js +137 -0
- package/dist/hooks/chunk-2XIGZQMQ.js +3299 -0
- package/dist/hooks/chunk-33ELOKEV.js +910 -0
- package/dist/hooks/chunk-33YRTKM7.js +230 -0
- package/dist/hooks/chunk-36JQU5NN.js +77 -0
- package/dist/hooks/chunk-3EJBTWVS.js +1769 -0
- package/dist/hooks/chunk-3FK5SFAC.js +432 -0
- package/dist/hooks/chunk-3PWPYDD2.js +240 -0
- package/dist/hooks/chunk-3TQU7TDH.js +375 -0
- package/dist/hooks/chunk-3TVLSFZ6.js +432 -0
- package/dist/hooks/chunk-3VXYCB4E.js +77 -0
- package/dist/hooks/chunk-44M6JXGV.js +3398 -0
- package/dist/hooks/chunk-46EEEHC3.js +240 -0
- package/dist/hooks/chunk-4A7UVP2P.js +364 -0
- package/dist/hooks/chunk-4LFQEZS4.js +137 -0
- package/dist/hooks/chunk-4OCX3V2T.js +469 -0
- package/dist/hooks/chunk-4OHA5DE7.js +49 -0
- package/dist/hooks/chunk-4PMDW3YD.js +68 -0
- package/dist/hooks/chunk-4QHBNAI4.js +68 -0
- package/dist/hooks/chunk-4SSB3FEE.js +3273 -0
- package/dist/hooks/chunk-5A2WQ2CQ.js +5390 -0
- package/dist/hooks/chunk-5EVA2JQB.js +5390 -0
- package/dist/hooks/chunk-5P7VF5VE.js +3230 -0
- package/dist/hooks/chunk-5QWJGGZP.js +49 -0
- package/dist/hooks/chunk-5U5EZYG6.js +77 -0
- package/dist/hooks/chunk-5VUUF3ZV.js +240 -0
- package/dist/hooks/chunk-5WA7UBT3.js +374 -0
- package/dist/hooks/chunk-6EBGRQ3Q.js +301 -0
- package/dist/hooks/chunk-6TVHWMD3.js +432 -0
- package/dist/hooks/chunk-6V5OPIUU.js +13 -0
- package/dist/hooks/chunk-6VAGLEMB.js +68 -0
- package/dist/hooks/chunk-75BTXKFJ.js +3424 -0
- package/dist/hooks/chunk-75RHN67S.js +137 -0
- package/dist/hooks/chunk-76KC3BDD.js +3414 -0
- package/dist/hooks/chunk-76SLS7CZ.js +898 -0
- package/dist/hooks/chunk-7DHZ4DWT.js +5015 -0
- package/dist/hooks/chunk-7INSJDGE.js +458 -0
- package/dist/hooks/chunk-7VJ4FTDX.js +268 -0
- package/dist/hooks/chunk-7XCYNHQK.js +77 -0
- package/dist/hooks/chunk-A5YJ3H7E.js +375 -0
- package/dist/hooks/chunk-AAEXXUUL.js +268 -0
- package/dist/hooks/chunk-ABVEVV2M.js +432 -0
- package/dist/hooks/chunk-ACN3YXFL.js +68 -0
- package/dist/hooks/chunk-AD3XE3QZ.js +397 -0
- package/dist/hooks/chunk-AENFZPZH.js +230 -0
- package/dist/hooks/chunk-AFKRFQ6W.js +68 -0
- package/dist/hooks/chunk-AHD5IPWI.js +375 -0
- package/dist/hooks/chunk-AMK5JGV7.js +77 -0
- package/dist/hooks/chunk-ARN7NCQI.js +425 -0
- package/dist/hooks/chunk-AUFY653N.js +3425 -0
- package/dist/hooks/chunk-AXQBNFEF.js +375 -0
- package/dist/hooks/chunk-AYC7R6U4.js +3316 -0
- package/dist/hooks/chunk-AYEA2FJ7.js +5015 -0
- package/dist/hooks/chunk-B2LIXYFL.js +77 -0
- package/dist/hooks/chunk-B4HPNY2I.js +375 -0
- package/dist/hooks/chunk-B4YNCUGB.js +469 -0
- package/dist/hooks/chunk-B57S3VWT.js +922 -0
- package/dist/hooks/chunk-BINZ3PLI.js +364 -0
- package/dist/hooks/chunk-BIWLABFK.js +432 -0
- package/dist/hooks/chunk-BODUSXKK.js +410 -0
- package/dist/hooks/chunk-BQBAT2YK.js +375 -0
- package/dist/hooks/chunk-BUJEBW75.js +391 -0
- package/dist/hooks/chunk-BVNWORKA.js +72 -0
- package/dist/hooks/chunk-BWI47LQS.js +5205 -0
- package/dist/hooks/chunk-C25HRMJX.js +137 -0
- package/dist/hooks/chunk-CBFZNC74.js +375 -0
- package/dist/hooks/chunk-CECYXS4Y.js +3424 -0
- package/dist/hooks/chunk-CELGUP5F.js +49 -0
- package/dist/hooks/chunk-CMHANU3F.js +3442 -0
- package/dist/hooks/chunk-CMN372LI.js +68 -0
- package/dist/hooks/chunk-CPGZLMMK.js +3299 -0
- package/dist/hooks/chunk-CTQKXDC7.js +268 -0
- package/dist/hooks/chunk-CYAT4RIT.js +68 -0
- package/dist/hooks/chunk-CYTWYCH2.js +5014 -0
- package/dist/hooks/chunk-CZSOLRBA.js +77 -0
- package/dist/hooks/chunk-D2PIDYJR.js +3438 -0
- package/dist/hooks/chunk-DE57HI6T.js +137 -0
- package/dist/hooks/chunk-DGXDGAPG.js +5306 -0
- package/dist/hooks/chunk-DNYRSYQG.js +5014 -0
- package/dist/hooks/chunk-DTAXH2A2.js +240 -0
- package/dist/hooks/chunk-E2IZUWI5.js +375 -0
- package/dist/hooks/chunk-E4L2K2BL.js +397 -0
- package/dist/hooks/chunk-E55NKX5F.js +68 -0
- package/dist/hooks/chunk-ECXVCCVD.js +3079 -0
- package/dist/hooks/chunk-EPHO443D.js +68 -0
- package/dist/hooks/chunk-EUFK2BI2.js +375 -0
- package/dist/hooks/chunk-EYCD5ZAV.js +137 -0
- package/dist/hooks/chunk-F2SDYJU4.js +240 -0
- package/dist/hooks/chunk-F4B5D5TF.js +68 -0
- package/dist/hooks/chunk-FGEO3NDX.js +432 -0
- package/dist/hooks/chunk-FJYI52RE.js +137 -0
- package/dist/hooks/chunk-FXAKJKTB.js +18 -0
- package/dist/hooks/chunk-FYTZHIY4.js +3085 -0
- package/dist/hooks/chunk-G7JL2A5K.js +375 -0
- package/dist/hooks/chunk-GA3ITDBW.js +42 -0
- package/dist/hooks/chunk-GDR4H4SV.js +469 -0
- package/dist/hooks/chunk-GFKDXPSM.js +2855 -0
- package/dist/hooks/chunk-GIMRTKFU.js +566 -0
- package/dist/hooks/chunk-GOPHRLGO.js +240 -0
- package/dist/hooks/chunk-GX4HO7SJ.js +230 -0
- package/dist/hooks/chunk-GXKKK23T.js +240 -0
- package/dist/hooks/chunk-GZ6FUVIK.js +566 -0
- package/dist/hooks/chunk-H5HPY5M5.js +2869 -0
- package/dist/hooks/chunk-HCF3OGEE.js +1829 -0
- package/dist/hooks/chunk-HDEXAOUM.js +469 -0
- package/dist/hooks/chunk-HM2TY3TN.js +469 -0
- package/dist/hooks/chunk-HOA7NXA2.js +55 -0
- package/dist/hooks/chunk-HOFEWH6H.js +240 -0
- package/dist/hooks/chunk-HUUI6S5J.js +2669 -0
- package/dist/hooks/chunk-I4D3NVUD.js +469 -0
- package/dist/hooks/chunk-I4Q6WAJE.js +68 -0
- package/dist/hooks/chunk-IB6N4CR2.js +432 -0
- package/dist/hooks/chunk-IFLDYJMD.js +469 -0
- package/dist/hooks/chunk-IGU466YD.js +77 -0
- package/dist/hooks/chunk-IJCQUHKY.js +375 -0
- package/dist/hooks/chunk-IKUMBDJB.js +230 -0
- package/dist/hooks/chunk-IM3BDIBJ.js +5005 -0
- package/dist/hooks/chunk-IMYMAODK.js +3431 -0
- package/dist/hooks/chunk-IN2ZVGXA.js +5005 -0
- package/dist/hooks/chunk-ITVJ2MKQ.js +18 -0
- package/dist/hooks/chunk-J5RIJYTM.js +2669 -0
- package/dist/hooks/chunk-JFLMH4K5.js +3460 -0
- package/dist/hooks/chunk-JR25IFML.js +77 -0
- package/dist/hooks/chunk-JT5AUXFI.js +432 -0
- package/dist/hooks/chunk-JY5YVN6N.js +3234 -0
- package/dist/hooks/chunk-K5Q4ETVI.js +391 -0
- package/dist/hooks/chunk-K67V2F24.js +137 -0
- package/dist/hooks/chunk-KABG6AEW.js +3460 -0
- package/dist/hooks/chunk-KATZESEC.js +3273 -0
- package/dist/hooks/chunk-KFH4H7W7.js +469 -0
- package/dist/hooks/chunk-KMUEI6RX.js +910 -0
- package/dist/hooks/chunk-KMV4OY77.js +3438 -0
- package/dist/hooks/chunk-KQAZNWEY.js +137 -0
- package/dist/hooks/chunk-KZZR6JER.js +5015 -0
- package/dist/hooks/chunk-LAR6DREP.js +77 -0
- package/dist/hooks/chunk-LNCJWEZD.js +5015 -0
- package/dist/hooks/chunk-LRYD2GLM.js +6 -0
- package/dist/hooks/chunk-LXBKYHDV.js +77 -0
- package/dist/hooks/chunk-LYLKIUNE.js +5024 -0
- package/dist/hooks/chunk-LZKCFOVC.js +432 -0
- package/dist/hooks/chunk-M4FCIYRI.js +77 -0
- package/dist/hooks/chunk-M5M7327Q.js +3425 -0
- package/dist/hooks/chunk-MF72MHSX.js +3455 -0
- package/dist/hooks/chunk-MK56LKDO.js +397 -0
- package/dist/hooks/chunk-N3MJADY7.js +240 -0
- package/dist/hooks/chunk-NFQSUDBN.js +458 -0
- package/dist/hooks/chunk-NHREKY45.js +137 -0
- package/dist/hooks/chunk-NP5TTAAW.js +375 -0
- package/dist/hooks/chunk-NQTLTKTJ.js +2993 -0
- package/dist/hooks/chunk-NVRCZPBZ.js +391 -0
- package/dist/hooks/chunk-O46HMMLJ.js +469 -0
- package/dist/hooks/chunk-OFJGH2L4.js +240 -0
- package/dist/hooks/chunk-OLFMCZH5.js +240 -0
- package/dist/hooks/chunk-OMCZS46I.js +49 -0
- package/dist/hooks/chunk-OQZEZW5G.js +469 -0
- package/dist/hooks/chunk-P2MDAT2Y.js +1897 -0
- package/dist/hooks/chunk-P3M2JJIF.js +68 -0
- package/dist/hooks/chunk-PDVHQITQ.js +3453 -0
- package/dist/hooks/chunk-PNT2AMDH.js +391 -0
- package/dist/hooks/chunk-PR2LVSY6.js +3445 -0
- package/dist/hooks/chunk-PRR5R4JK.js +137 -0
- package/dist/hooks/chunk-PXT44QVN.js +566 -0
- package/dist/hooks/chunk-PZLWJLAP.js +469 -0
- package/dist/hooks/chunk-Q2FEAZJ2.js +77 -0
- package/dist/hooks/chunk-Q32WETDO.js +3265 -0
- package/dist/hooks/chunk-Q45DUBLE.js +3600 -0
- package/dist/hooks/chunk-Q7NZSWQ5.js +240 -0
- package/dist/hooks/chunk-QH2JNAMK.js +3085 -0
- package/dist/hooks/chunk-QNNWYQ2R.js +375 -0
- package/dist/hooks/chunk-QPU5H2OS.js +68 -0
- package/dist/hooks/chunk-QRAHZ5TO.js +1829 -0
- package/dist/hooks/chunk-QUZ5HPIE.js +469 -0
- package/dist/hooks/chunk-QVCRG34O.js +2893 -0
- package/dist/hooks/chunk-R3MY4E3S.js +1675 -0
- package/dist/hooks/chunk-R6TXJJXP.js +77 -0
- package/dist/hooks/chunk-REJU6VT7.js +1829 -0
- package/dist/hooks/chunk-REQAQLRC.js +2993 -0
- package/dist/hooks/chunk-RFCXPAHH.js +391 -0
- package/dist/hooks/chunk-RHI6Y22X.js +137 -0
- package/dist/hooks/chunk-RKZVOBBS.js +469 -0
- package/dist/hooks/chunk-RL57TT2Y.js +566 -0
- package/dist/hooks/chunk-RORDOD4S.js +3321 -0
- package/dist/hooks/chunk-RZKYW5P2.js +77 -0
- package/dist/hooks/chunk-SJPJ6VSI.js +391 -0
- package/dist/hooks/chunk-SKSIJQQQ.js +432 -0
- package/dist/hooks/chunk-SSQDZKXG.js +268 -0
- package/dist/hooks/chunk-SSX23SJ2.js +89 -0
- package/dist/hooks/chunk-SYHFKE4C.js +77 -0
- package/dist/hooks/chunk-TCGNI2ZY.js +42 -0
- package/dist/hooks/chunk-TG3WXJF5.js +137 -0
- package/dist/hooks/chunk-TH7IJAY5.js +77 -0
- package/dist/hooks/chunk-TLZ27PCY.js +240 -0
- package/dist/hooks/chunk-U652FXTN.js +566 -0
- package/dist/hooks/chunk-UEK47YUF.js +268 -0
- package/dist/hooks/chunk-UIO45H3O.js +432 -0
- package/dist/hooks/chunk-UNLZEEVH.js +5005 -0
- package/dist/hooks/chunk-UNRVF3SZ.js +432 -0
- package/dist/hooks/chunk-USLFAFOI.js +3453 -0
- package/dist/hooks/chunk-VAEELMLL.js +442 -0
- package/dist/hooks/chunk-VALSWLDQ.js +3453 -0
- package/dist/hooks/chunk-VC5JEPNY.js +3398 -0
- package/dist/hooks/chunk-VEZVK6C7.js +230 -0
- package/dist/hooks/chunk-VK5JKFAR.js +49 -0
- package/dist/hooks/chunk-VNF2KP7Z.js +469 -0
- package/dist/hooks/chunk-VWWCUMW6.js +2669 -0
- package/dist/hooks/chunk-W4JARUQV.js +137 -0
- package/dist/hooks/chunk-WCYPBPJC.js +5014 -0
- package/dist/hooks/chunk-WEOBMNJG.js +2993 -0
- package/dist/hooks/chunk-WKJU3J5Y.js +5390 -0
- package/dist/hooks/chunk-WMN4TSVF.js +3299 -0
- package/dist/hooks/chunk-WNON54PT.js +3469 -0
- package/dist/hooks/chunk-WOVKBPPX.js +137 -0
- package/dist/hooks/chunk-WRVFORYJ.js +432 -0
- package/dist/hooks/chunk-WUBVYGQZ.js +240 -0
- package/dist/hooks/chunk-WWULTUOM.js +68 -0
- package/dist/hooks/chunk-WXHKKB45.js +4962 -0
- package/dist/hooks/chunk-XAI3YTHJ.js +469 -0
- package/dist/hooks/chunk-XFZH6JZJ.js +77 -0
- package/dist/hooks/chunk-XGPWX6IA.js +137 -0
- package/dist/hooks/chunk-XIXXIVGY.js +566 -0
- package/dist/hooks/chunk-XKDOYJGA.js +922 -0
- package/dist/hooks/chunk-YALTVBHM.js +432 -0
- package/dist/hooks/chunk-YEBEPBFK.js +5014 -0
- package/dist/hooks/chunk-YI2BQ3DK.js +3441 -0
- package/dist/hooks/chunk-YVNBCFGG.js +1829 -0
- package/dist/hooks/chunk-YXBN3RGG.js +432 -0
- package/dist/hooks/chunk-Z2OOJSW3.js +3163 -0
- package/dist/hooks/chunk-ZA3HVBOY.js +2644 -0
- package/dist/hooks/chunk-ZKID46U3.js +137 -0
- package/dist/hooks/chunk-ZPMU2JV6.js +49 -0
- package/dist/hooks/chunk-ZRKY4W7O.js +432 -0
- package/dist/hooks/chunk-ZTMRB7LJ.js +268 -0
- package/dist/hooks/chunk-ZVPPBQ3L.js +3413 -0
- package/dist/hooks/codex-hook-adapter.js +164 -0
- package/dist/hooks/duplicate-read-guard.js +29 -0
- package/dist/hooks/format-edited.js +37 -0
- package/dist/hooks/investigation-guard.js +31 -0
- package/dist/hooks/pretool-guard.js +21 -0
- package/dist/hooks/session-lang.js +34 -0
- package/dist/hooks/stop-guard.js +1597 -0
- package/dist/josh.js +1795 -0
- package/dist/managed-marker/index.d.ts +10 -0
- package/dist/managed-marker/index.js +32 -0
- package/dist/self-sync-guard/index.d.ts +10 -0
- package/dist/self-sync-guard/index.js +49 -0
- package/dist/version/index.d.ts +93 -0
- package/dist/version/index.js +1024 -0
- package/env/index.d.ts +7 -0
- package/env/index.js +62 -0
- package/eslint/base.js +233 -0
- package/eslint/checkout-rooted-parser.js +34 -0
- package/eslint/config-fingerprint.js +103 -0
- package/eslint/rules/code-quality.js +292 -0
- package/eslint/rules/english-only-prose.js +135 -0
- package/eslint/rules/formatting.js +44 -0
- package/eslint/rules/import.js +83 -0
- package/eslint/rules/namespace-object-export.js +107 -0
- package/eslint/rules/naming-convention.js +109 -0
- package/eslint/rules/promise.js +17 -0
- package/eslint/rules/sonarjs.js +45 -0
- package/eslint/rules/test-filename.js +91 -0
- package/eslint/rules/typescript.js +186 -0
- package/eslint/rules/unicorn.js +191 -0
- package/eslint/vanilla.js +1 -0
- package/evals/scenarios/consult-not-execute.json +20 -0
- package/evals/scenarios/no-implicit-workflow.json +26 -0
- package/evals/scenarios/overrides-both-locations.json +29 -0
- package/evals/scenarios/upstream-interrupt.json +23 -0
- package/evals/scenarios/workflow-skill-loaded.json +16 -0
- package/lefthook/base.yml +131 -0
- package/lefthook/vanilla.yml +7 -0
- package/package.json +169 -0
- package/playwright.config.ts +160 -0
- package/pnpm-workspace.yaml +41 -0
- package/ports/index.d.ts +17 -0
- package/ports/index.js +256 -0
- package/prettier/index.d.ts +3 -0
- package/prettier/index.js +31 -0
- package/prompts/agent-lint-protocol.json +79 -0
- package/prompts/agent-rules.md +63 -0
- package/prompts/coding-standards.md +382 -0
- package/prompts/collaboration-workflow/consultation-vs-execution.md +8 -0
- package/prompts/collaboration-workflow/cross-repo-epic.md +54 -0
- package/prompts/collaboration-workflow/distributed-docs.md +7 -0
- package/prompts/collaboration-workflow/durable-rules.md +24 -0
- package/prompts/collaboration-workflow/epic-audit.md +56 -0
- package/prompts/collaboration-workflow/epic-bundle.md +109 -0
- package/prompts/collaboration-workflow/file-edits.md +124 -0
- package/prompts/collaboration-workflow/gh-rest.md +57 -0
- package/prompts/collaboration-workflow/issue-citation.md +38 -0
- package/prompts/collaboration-workflow/issue-template.md +190 -0
- package/prompts/collaboration-workflow/latest-first.md +14 -0
- package/prompts/collaboration-workflow/no-clones.md +11 -0
- package/prompts/collaboration-workflow/operating-rules.md +123 -0
- package/prompts/collaboration-workflow/output-bounds.md +107 -0
- package/prompts/collaboration-workflow/overview.md +35 -0
- package/prompts/collaboration-workflow/plan-comment.md +85 -0
- package/prompts/collaboration-workflow/proposal-request.md +23 -0
- package/prompts/collaboration-workflow/report-format.md +206 -0
- package/prompts/collaboration-workflow/residency.md +94 -0
- package/prompts/collaboration-workflow/rule-delivery.md +146 -0
- package/prompts/collaboration-workflow/shell-body.md +82 -0
- package/prompts/collaboration-workflow/simplicity-first.md +9 -0
- package/prompts/collaboration-workflow/single-source-rules.md +13 -0
- package/prompts/collaboration-workflow/turn-batching.md +137 -0
- package/prompts/collaboration-workflow/upstream-interrupt.md +51 -0
- package/prompts/collaboration-workflow/wip-cap.md +118 -0
- package/prompts/collaboration-workflow.md +52 -0
- package/prompts/refactoring.md +103 -0
- package/prompts/review-rubric.md +338 -0
- package/prompts/review.md +217 -0
- package/prompts/sonar-hotspot-handling.md +77 -0
- package/prompts/testing-guide.md +277 -0
- package/scripts/adopt/adopt-logic.ts +107 -0
- package/scripts/adopt/adopt-toolkits.ts +181 -0
- package/scripts/adopt/adopt.ts +171 -0
- package/scripts/agent/agent-argv.ts +140 -0
- package/scripts/agent/agent-diagnostics.ts +120 -0
- package/scripts/agent/agent-event.ts +173 -0
- package/scripts/agent/agent-exit-record.ts +32 -0
- package/scripts/agent/agent-launch-environment.ts +71 -0
- package/scripts/agent/agent-role-profile.ts +329 -0
- package/scripts/agent/api-outage.ts +51 -0
- package/scripts/agent/claude-agent-argv.ts +151 -0
- package/scripts/agent/claude-result-event.ts +98 -0
- package/scripts/agent/codex-agent-argv.ts +94 -0
- package/scripts/agent/codex-home-source.ts +11 -0
- package/scripts/agent/interactive-ask.ts +91 -0
- package/scripts/auto-ok/auto-ok-cli.ts +516 -0
- package/scripts/backlog/backlog-arrival.ts +147 -0
- package/scripts/backlog/backlog-budget-cli.ts +220 -0
- package/scripts/backlog/backlog-budget.ts +284 -0
- package/scripts/backlog/backlog-defect-priority.ts +77 -0
- package/scripts/backlog/backlog-drive-cli.ts +377 -0
- package/scripts/backlog/backlog-drive-finish.ts +23 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +81 -0
- package/scripts/backlog/backlog-drive-named.ts +101 -0
- package/scripts/backlog/backlog-drive-offer-argv.ts +29 -0
- package/scripts/backlog/backlog-drive-owner.ts +22 -0
- package/scripts/backlog/backlog-drive-restore.ts +67 -0
- package/scripts/backlog/backlog-drive.ts +322 -0
- package/scripts/backlog/backlog-named.ts +164 -0
- package/scripts/backlog/backlog-next.ts +376 -0
- package/scripts/backlog/backlog-offer-cli.ts +279 -0
- package/scripts/backlog/backlog-offer.ts +93 -0
- package/scripts/backlog/backlog-plan-cli.ts +235 -0
- package/scripts/backlog/backlog-plan.ts +231 -0
- package/scripts/backlog/backlog-pool.ts +322 -0
- package/scripts/backlog/backlog-ready.ts +146 -0
- package/scripts/backlog/backlog-scope.ts +144 -0
- package/scripts/backlog/backlog-stalled-cli.ts +30 -0
- package/scripts/backlog/backlog-stalled-detect.ts +143 -0
- package/scripts/backlog/backlog-stalled.ts +118 -0
- package/scripts/behavior/behavior-assertion.ts +87 -0
- package/scripts/behavior/behavior-cli.ts +88 -0
- package/scripts/behavior/behavior-rules.ts +128 -0
- package/scripts/build/build-bin.ts +36 -0
- package/scripts/build/build-claude-md.ts +42 -0
- package/scripts/build/build-config-merge.ts +26 -0
- package/scripts/build/build-hooks.ts +79 -0
- package/scripts/build/build-library.ts +83 -0
- package/scripts/build/build-managed-marker.ts +26 -0
- package/scripts/build/build-self-sync-guard.ts +26 -0
- package/scripts/build/build-version.ts +25 -0
- package/scripts/build/local-bin.ts +97 -0
- package/scripts/build/shim-shell.ts +25 -0
- package/scripts/bytes/bytes-command.ts +181 -0
- package/scripts/cases/cases-cli.ts +48 -0
- package/scripts/cases/cases-logic.ts +100 -0
- package/scripts/claude/skill-meta.ts +37 -0
- package/scripts/claude/workflow-destination.ts +13 -0
- package/scripts/clone/clone-aggregate.ts +76 -0
- package/scripts/clone/clone-fingerprint.ts +96 -0
- package/scripts/clone/clone-scan-cli.ts +39 -0
- package/scripts/clone/clone-scan.ts +158 -0
- package/scripts/config-merge/index.ts +19 -0
- package/scripts/config-merge/json-format.ts +128 -0
- package/scripts/config-merge/list-patch.ts +61 -0
- package/scripts/config-merge/parse-jsonc.ts +14 -0
- package/scripts/config-merge/patch-json-key.ts +439 -0
- package/scripts/config-merge/patch-json-list.ts +38 -0
- package/scripts/config-merge/patch-yaml-list.ts +107 -0
- package/scripts/cost-runtime/codex-usage.ts +119 -0
- package/scripts/cost-runtime/context-cut-payback.ts +77 -0
- package/scripts/cost-runtime/context-cut-threshold.ts +21 -0
- package/scripts/cost-runtime/cost-attribute.ts +168 -0
- package/scripts/cost-runtime/cost-blocks.ts +149 -0
- package/scripts/cost-runtime/cost-cli.ts +318 -0
- package/scripts/cost-runtime/cost-corpus.ts +278 -0
- package/scripts/cost-runtime/cost-format.ts +32 -0
- package/scripts/cost-runtime/cost-pricing.ts +176 -0
- package/scripts/cost-runtime/cost-tokens.ts +84 -0
- package/scripts/cost-runtime/cost-transcript.ts +531 -0
- package/scripts/cost-runtime/cost-usage.ts +287 -0
- package/scripts/cost-runtime/cost-verdict.ts +89 -0
- package/scripts/cost-runtime/own-session.ts +58 -0
- package/scripts/cost-runtime/transcript-cwd.ts +14 -0
- package/scripts/delegation/delegation-cli.ts +91 -0
- package/scripts/delegation/delegation-policy.ts +178 -0
- package/scripts/delegation/duplicate-read-guard.ts +244 -0
- package/scripts/delegation/fanout-cli.ts +61 -0
- package/scripts/delegation/fanout.ts +95 -0
- package/scripts/delegation/investigation-guard.ts +131 -0
- package/scripts/delegation/investigation-reads.ts +637 -0
- package/scripts/discovery/repo-discovery.ts +166 -0
- package/scripts/discovery/repo-map-logic.ts +102 -0
- package/scripts/discovery/repo-origin.ts +153 -0
- package/scripts/discovery/repo-party-cli.ts +69 -0
- package/scripts/discovery/repo-party.ts +46 -0
- package/scripts/doctor/doctor-consumer.ts +181 -0
- package/scripts/doctor/doctor-io.ts +210 -0
- package/scripts/doctor/doctor-logic.ts +122 -0
- package/scripts/doctor/doctor-ports.ts +117 -0
- package/scripts/doctor/doctor.ts +232 -0
- package/scripts/document/backlogrun-parent-read-set.ts +48 -0
- package/scripts/document/bash-output-cap.ts +45 -0
- package/scripts/document/document-byte-budget.ts +183 -0
- package/scripts/document/document-byte-check.ts +131 -0
- package/scripts/document/document-reachability.ts +131 -0
- package/scripts/document/document-read-cli.ts +82 -0
- package/scripts/document/document-scan.ts +108 -0
- package/scripts/document/document-section-cli.ts +101 -0
- package/scripts/document/document-section.ts +156 -0
- package/scripts/document/edit-files-cli.ts +280 -0
- package/scripts/document/entry-read-budget.ts +154 -0
- package/scripts/document/entry-read-set.ts +471 -0
- package/scripts/document/generate-catalog.ts +69 -0
- package/scripts/document/lane-child-read-set.ts +88 -0
- package/scripts/document/read-files-cli.ts +135 -0
- package/scripts/document/read-set-cli.ts +295 -0
- package/scripts/document/read-set-point-of-use.ts +89 -0
- package/scripts/document/read-set-pricing.ts +52 -0
- package/scripts/document/read-set-trim.ts +78 -0
- package/scripts/document/retired-phrases.ts +143 -0
- package/scripts/document/review-agent-type.ts +46 -0
- package/scripts/document/single-source.ts +73 -0
- package/scripts/epic/epic-audit-checks.ts +452 -0
- package/scripts/epic/epic-audit-cli.ts +374 -0
- package/scripts/epic/epic-audit-orphans.ts +142 -0
- package/scripts/epic/epic-audit-rationale.ts +191 -0
- package/scripts/epic/epic-audit-report.ts +101 -0
- package/scripts/epic/epic-audit.ts +240 -0
- package/scripts/epic/epic-bundle-cli.ts +472 -0
- package/scripts/epic/epic-bundle-evidence.ts +147 -0
- package/scripts/epic/epic-bundle-gaps.ts +86 -0
- package/scripts/epic/epic-bundle-referenced.ts +195 -0
- package/scripts/epic/epic-bundle.ts +309 -0
- package/scripts/epic/epic-busy.ts +204 -0
- package/scripts/epic/epic-candidate-confirm.ts +279 -0
- package/scripts/epic/epic-classify.ts +294 -0
- package/scripts/epic/epic-cross-repo.ts +366 -0
- package/scripts/epic/epic-fetch.ts +370 -0
- package/scripts/epic/epic-graph.ts +279 -0
- package/scripts/epic/epic-index.ts +209 -0
- package/scripts/epic/epic-issue.ts +172 -0
- package/scripts/epic/epic-lane-offer.ts +207 -0
- package/scripts/epic/epic-nested.ts +37 -0
- package/scripts/epic/epic-next-read.ts +141 -0
- package/scripts/epic/epic-next-views.ts +144 -0
- package/scripts/epic/epic-next.ts +477 -0
- package/scripts/epic/epic-outside-blocker.ts +113 -0
- package/scripts/epic/epic-relation-recheck.ts +108 -0
- package/scripts/epic/epic-report.ts +200 -0
- package/scripts/gate/core-budget.ts +292 -0
- package/scripts/gate/gate-log.ts +95 -0
- package/scripts/gate/gate-plan.ts +356 -0
- package/scripts/gate/gate-report.ts +207 -0
- package/scripts/gate/gate-skip.ts +123 -0
- package/scripts/gate/gate-tree.ts +49 -0
- package/scripts/gate/hook-gate-reuse.ts +130 -0
- package/scripts/gate/pre-commit-type-check.ts +187 -0
- package/scripts/gate/scoped-green.ts +260 -0
- package/scripts/gate/type-check-step.ts +90 -0
- package/scripts/gate/verification-gate.ts +531 -0
- package/scripts/gh/fix-gh-packages-logic.ts +232 -0
- package/scripts/gh/fix-gh-packages.ts +129 -0
- package/scripts/gh/gh-cli-token.ts +18 -0
- package/scripts/gh/gh-spawn.ts +44 -0
- package/scripts/git/animation-helpers.ts +81 -0
- package/scripts/git/change-base.ts +26 -0
- package/scripts/git/changed-file-scope.ts +209 -0
- package/scripts/git/changed-paths.ts +30 -0
- package/scripts/git/constants.ts +41 -0
- package/scripts/git/git-ai-review-scan.ts +154 -0
- package/scripts/git/git-animation.ts +41 -0
- package/scripts/git/git-branch.ts +127 -0
- package/scripts/git/git-command.ts +587 -0
- package/scripts/git/git-commit.ts +27 -0
- package/scripts/git/git-common-directory.ts +38 -0
- package/scripts/git/git-epic-add-body.ts +365 -0
- package/scripts/git/git-epic-add-plan.ts +421 -0
- package/scripts/git/git-epic-add.ts +249 -0
- package/scripts/git/git-epic-body.ts +150 -0
- package/scripts/git/git-epic-chains.ts +411 -0
- package/scripts/git/git-epic-close-comment.ts +199 -0
- package/scripts/git/git-epic-close.ts +393 -0
- package/scripts/git/git-epic-decision.ts +171 -0
- package/scripts/git/git-epic-parse.ts +351 -0
- package/scripts/git/git-epic-promote.ts +102 -0
- package/scripts/git/git-epic-read.ts +73 -0
- package/scripts/git/git-epic-reconcile.ts +246 -0
- package/scripts/git/git-epic-reference.ts +98 -0
- package/scripts/git/git-epic-relations.ts +78 -0
- package/scripts/git/git-epic-remove-plan.ts +152 -0
- package/scripts/git/git-epic-remove.ts +101 -0
- package/scripts/git/git-epic-run.ts +223 -0
- package/scripts/git/git-epic-sections.ts +98 -0
- package/scripts/git/git-epic-shape.ts +81 -0
- package/scripts/git/git-epic-validate.ts +155 -0
- package/scripts/git/git-error.ts +78 -0
- package/scripts/git/git-execa-error.ts +35 -0
- package/scripts/git/git-fixture-workspace.ts +88 -0
- package/scripts/git/git-followup-cleanup.ts +88 -0
- package/scripts/git/git-followup-flush.ts +63 -0
- package/scripts/git/git-followup-label.ts +67 -0
- package/scripts/git/git-followup-pending.ts +95 -0
- package/scripts/git/git-followup-stages.ts +149 -0
- package/scripts/git/git-gh-api-path.ts +118 -0
- package/scripts/git/git-gh-check.ts +21 -0
- package/scripts/git/git-gh-command.ts +17 -0
- package/scripts/git/git-gh-exec.ts +344 -0
- package/scripts/git/git-gh-failure.ts +103 -0
- package/scripts/git/git-gh-helpers.ts +44 -0
- package/scripts/git/git-gh-issue-list.ts +257 -0
- package/scripts/git/git-gh-issue-read.ts +457 -0
- package/scripts/git/git-gh-issue-rest.ts +238 -0
- package/scripts/git/git-gh-issue-write.ts +285 -0
- package/scripts/git/git-gh-issue.ts +161 -0
- package/scripts/git/git-gh-pr-auto-merge.ts +85 -0
- package/scripts/git/git-gh-pr-read.ts +322 -0
- package/scripts/git/git-gh-pr-rest.ts +172 -0
- package/scripts/git/git-gh-pr-review.ts +103 -0
- package/scripts/git/git-gh-pr-rollup.ts +91 -0
- package/scripts/git/git-gh-pr-snapshot.ts +138 -0
- package/scripts/git/git-gh-pr.ts +219 -0
- package/scripts/git/git-gh-reachability.ts +56 -0
- package/scripts/git/git-gh-repo.ts +37 -0
- package/scripts/git/git-gh-rest-state.ts +14 -0
- package/scripts/git/git-issue.ts +168 -0
- package/scripts/git/git-location-environment.ts +62 -0
- package/scripts/git/git-ls-remote.ts +28 -0
- package/scripts/git/git-next-issues.ts +98 -0
- package/scripts/git/git-notify.ts +104 -0
- package/scripts/git/git-pr-ai-review.ts +180 -0
- package/scripts/git/git-pr-checks-eval.ts +265 -0
- package/scripts/git/git-pr-checks-parse.ts +153 -0
- package/scripts/git/git-pr-checks-watch.ts +184 -0
- package/scripts/git/git-pr-checks.ts +387 -0
- package/scripts/git/git-pr-coderabbit.ts +129 -0
- package/scripts/git/git-pr-confirmation.ts +64 -0
- package/scripts/git/git-pr-error.ts +25 -0
- package/scripts/git/git-pr-followup-wrapup.ts +225 -0
- package/scripts/git/git-pr-followup.ts +436 -0
- package/scripts/git/git-pr-managed-config.ts +69 -0
- package/scripts/git/git-pr-messages.ts +37 -0
- package/scripts/git/git-pr.ts +181 -0
- package/scripts/git/git-prompt-display.ts +22 -0
- package/scripts/git/git-prompt.ts +207 -0
- package/scripts/git/git-push-transport.ts +173 -0
- package/scripts/git/git-push.ts +27 -0
- package/scripts/git/git-remote-branch.ts +40 -0
- package/scripts/git/git-spawn.ts +47 -0
- package/scripts/git/git-staging.ts +128 -0
- package/scripts/git/git-stash.ts +124 -0
- package/scripts/git/git-status.ts +198 -0
- package/scripts/git/git-worktree.ts +110 -0
- package/scripts/git/github-issue-url.ts +105 -0
- package/scripts/git/gone-branch.ts +113 -0
- package/scripts/git/issue-labels.ts +279 -0
- package/scripts/git/listing-cutoff.ts +51 -0
- package/scripts/git/main-merge-guard.ts +134 -0
- package/scripts/git/main-merge.ts +120 -0
- package/scripts/git/main-sync.ts +121 -0
- package/scripts/git/parse-json-array.ts +102 -0
- package/scripts/git/schemas.ts +166 -0
- package/scripts/git/stash-orphans.ts +91 -0
- package/scripts/git/stash-pop-args.ts +59 -0
- package/scripts/git/stash-pop-cli.ts +105 -0
- package/scripts/git/telegram-notify.ts +404 -0
- package/scripts/hooks/batch-guard.ts +144 -0
- package/scripts/hooks/check-commit-message.ts +134 -0
- package/scripts/hooks/codex-hook-adapter.ts +155 -0
- package/scripts/hooks/edited-cspell.ts +128 -0
- package/scripts/hooks/format-edited-file-fixtures.ts +109 -0
- package/scripts/hooks/format-edited-file.ts +510 -0
- package/scripts/hooks/format-rewrite-notice.ts +99 -0
- package/scripts/hooks/pre-push-unit.ts +146 -0
- package/scripts/hooks/pretool-guard.ts +96 -0
- package/scripts/hooks/prevent-main-commit.ts +38 -0
- package/scripts/hooks/prompt-hooks.ts +38 -0
- package/scripts/hooks/reserved-run.ts +90 -0
- package/scripts/hooks/stop-guard.ts +135 -0
- package/scripts/init/claude-plugin-config.ts +51 -0
- package/scripts/init/distributed-paths.ts +100 -0
- package/scripts/init/hook-command-rewrite.ts +85 -0
- package/scripts/init/hook-launch.ts +31 -0
- package/scripts/init/init-actions.ts +147 -0
- package/scripts/init/init-ai-copy.ts +235 -0
- package/scripts/init/init-copy-content.ts +50 -0
- package/scripts/init/init-logic-deploy-vps.ts +43 -0
- package/scripts/init/init-logic-json-merge.ts +340 -0
- package/scripts/init/init-logic-migrate.ts +62 -0
- package/scripts/init/init-logic-package-key-order.ts +50 -0
- package/scripts/init/init-logic-secretlint.ts +36 -0
- package/scripts/init/init-logic-sonar.ts +197 -0
- package/scripts/init/init-logic-templates.ts +142 -0
- package/scripts/init/init-logic-workspace.ts +59 -0
- package/scripts/init/init-logic-yaml-merge.ts +57 -0
- package/scripts/init/init-logic.ts +474 -0
- package/scripts/init/init-paths.ts +11 -0
- package/scripts/init/init-sonar.ts +32 -0
- package/scripts/init/init.ts +219 -0
- package/scripts/init/kit-base-preset.ts +60 -0
- package/scripts/init/plugin-install-hint.ts +47 -0
- package/scripts/init/tsconfig-preset-migration.ts +67 -0
- package/scripts/issue/baseline-measure.ts +105 -0
- package/scripts/issue/behavior-change-lint.ts +122 -0
- package/scripts/issue/defect-rate-cli.ts +167 -0
- package/scripts/issue/defect-rate.ts +145 -0
- package/scripts/issue/issue-backlinks-cli.ts +97 -0
- package/scripts/issue/issue-backlinks.ts +164 -0
- package/scripts/issue/issue-cite-cli.ts +158 -0
- package/scripts/issue/issue-cite.ts +102 -0
- package/scripts/issue/issue-comment-cli.ts +95 -0
- package/scripts/issue/issue-fold-cli.ts +104 -0
- package/scripts/issue/issue-fold-existing-cli.ts +81 -0
- package/scripts/issue/issue-fold-existing.ts +73 -0
- package/scripts/issue/issue-fold.ts +42 -0
- package/scripts/issue/issue-lint-cli.ts +60 -0
- package/scripts/issue/issue-lint.ts +26 -0
- package/scripts/issue/issue-logic.ts +50 -0
- package/scripts/issue/issue-read-cli.ts +190 -0
- package/scripts/issue/issue-read.ts +145 -0
- package/scripts/issue/issue-scout-cli.ts +482 -0
- package/scripts/issue/issue-scout.ts +244 -0
- package/scripts/issue/issue-state-cli.ts +260 -0
- package/scripts/issue/issue-state.ts +109 -0
- package/scripts/issue/markdown-section.ts +39 -0
- package/scripts/issue/measure-rerun-cli.ts +98 -0
- package/scripts/issue/reproduction-measure.ts +59 -0
- package/scripts/josh/__snapshots__/josh-command-map.test.ts.snap +1171 -0
- package/scripts/josh/agent-session-environment.ts +188 -0
- package/scripts/josh/cli-body.ts +96 -0
- package/scripts/josh/command-suggest.ts +57 -0
- package/scripts/josh/file-map-stamp.ts +264 -0
- package/scripts/josh/hook-decision.ts +479 -0
- package/scripts/josh/josh-command-map.ts +196 -0
- package/scripts/josh/josh-command-types.ts +226 -0
- package/scripts/josh/josh-commands-ai.ts +327 -0
- package/scripts/josh/josh-commands-backlog.ts +54 -0
- package/scripts/josh/josh-commands-clone.ts +18 -0
- package/scripts/josh/josh-commands-development.ts +206 -0
- package/scripts/josh/josh-commands-document.ts +45 -0
- package/scripts/josh/josh-commands-guard.ts +38 -0
- package/scripts/josh/josh-commands-hooks.ts +42 -0
- package/scripts/josh/josh-commands-issue.ts +69 -0
- package/scripts/josh/josh-commands-lane.ts +75 -0
- package/scripts/josh/josh-commands-lint.ts +37 -0
- package/scripts/josh/josh-commands-maintenance.ts +80 -0
- package/scripts/josh/josh-commands-project.ts +53 -0
- package/scripts/josh/josh-commands-split.ts +20 -0
- package/scripts/josh/josh-commands-versioning.ts +48 -0
- package/scripts/josh/josh-commands-workflow.ts +116 -0
- package/scripts/josh/josh-composite-arguments.ts +55 -0
- package/scripts/josh/josh-environment-file.ts +31 -0
- package/scripts/josh/josh-in-process.ts +80 -0
- package/scripts/josh/josh-logic.ts +308 -0
- package/scripts/josh/josh-run.ts +53 -0
- package/scripts/josh/josh-script-reader.ts +11 -0
- package/scripts/josh/josh-verdict.ts +111 -0
- package/scripts/josh/josh.ts +60 -0
- package/scripts/josh/kit-only.ts +33 -0
- package/scripts/josh/path-decision.ts +104 -0
- package/scripts/josh/platform-temporary.ts +66 -0
- package/scripts/josh/process-identity.ts +335 -0
- package/scripts/josh/session-language-cli.ts +51 -0
- package/scripts/josh/session-language.ts +30 -0
- package/scripts/josh/stamp-file.ts +194 -0
- package/scripts/lane/lane-await.ts +165 -0
- package/scripts/lane/lane-cache-run.ts +39 -0
- package/scripts/lane/lane-cache.ts +135 -0
- package/scripts/lane/lane-capacity.ts +69 -0
- package/scripts/lane/lane-child-invocation.ts +73 -0
- package/scripts/lane/lane-child-marker.ts +58 -0
- package/scripts/lane/lane-cli.ts +410 -0
- package/scripts/lane/lane-close.ts +197 -0
- package/scripts/lane/lane-dispatch-log.ts +13 -0
- package/scripts/lane/lane-dispatch.ts +458 -0
- package/scripts/lane/lane-environment.ts +253 -0
- package/scripts/lane/lane-guard-policy.ts +136 -0
- package/scripts/lane/lane-install.ts +94 -0
- package/scripts/lane/lane-launch-cli.ts +133 -0
- package/scripts/lane/lane-occupancy.ts +112 -0
- package/scripts/lane/lane-open.ts +275 -0
- package/scripts/lane/lane-output.ts +124 -0
- package/scripts/lane/lane-paths.ts +96 -0
- package/scripts/lane/lane-reap.ts +137 -0
- package/scripts/lane/lane-registry.ts +261 -0
- package/scripts/lane/lane-relaunch.ts +68 -0
- package/scripts/lane/lane-report.ts +95 -0
- package/scripts/lane/lane-resume.ts +61 -0
- package/scripts/lane/lane-seed.ts +44 -0
- package/scripts/lane/lane-start-point.ts +175 -0
- package/scripts/lane/openai-lane-supervisor-cli.ts +32 -0
- package/scripts/lane/openai-lane-supervisor-decision.ts +63 -0
- package/scripts/lane/openai-lane-supervisor.ts +337 -0
- package/scripts/lib/bounded-pool.ts +109 -0
- package/scripts/lib/buffered-process.ts +82 -0
- package/scripts/lib/caddy-logs.sh +45 -0
- package/scripts/lib/cli-flags.ts +19 -0
- package/scripts/lib/json-value.ts +24 -0
- package/scripts/lib/poll.ts +57 -0
- package/scripts/lib/read-file.ts +16 -0
- package/scripts/lib/schemas.ts +67 -0
- package/scripts/lib/spawn-exit.ts +45 -0
- package/scripts/lib/status-icons.ts +24 -0
- package/scripts/lines/effective-limit.ts +156 -0
- package/scripts/lines/line-budget.ts +404 -0
- package/scripts/lines/line-targets.ts +80 -0
- package/scripts/lines/lines-command.ts +174 -0
- package/scripts/lint/cspell-cached.ts +41 -0
- package/scripts/lint/lint-parallel.ts +72 -0
- package/scripts/lint/lint-related-scope.ts +128 -0
- package/scripts/lint/lint-related.ts +104 -0
- package/scripts/managed-marker/index.ts +5 -0
- package/scripts/managed-marker/managed-marker-logic.ts +67 -0
- package/scripts/observations/observation-ledger-home.ts +32 -0
- package/scripts/observations/observation-ledger-line.ts +93 -0
- package/scripts/observations/observation-ledger.ts +35 -0
- package/scripts/observations/observations-flush-cli.ts +42 -0
- package/scripts/observations/observations-flush-landing.ts +97 -0
- package/scripts/observations/observations-flush.ts +420 -0
- package/scripts/overrides/lockfile-overrides.ts +105 -0
- package/scripts/overrides/overrides-check.ts +84 -0
- package/scripts/overrides/overrides-files.ts +19 -0
- package/scripts/overrides/overrides-logic.ts +211 -0
- package/scripts/overrides/schemas.ts +49 -0
- package/scripts/package/package-scout-cli.ts +195 -0
- package/scripts/package/package-scout-format.ts +151 -0
- package/scripts/package/package-scout.ts +121 -0
- package/scripts/ports/port-command.ts +87 -0
- package/scripts/propagate/propagate-git-failure.ts +191 -0
- package/scripts/propagate/propagate-git.ts +224 -0
- package/scripts/propagate/propagate-publish.ts +181 -0
- package/scripts/propagate/propagate-run.ts +201 -0
- package/scripts/propagate/propagate-steps.ts +421 -0
- package/scripts/propagate/propagate-targets.ts +160 -0
- package/scripts/propagate/propagate.ts +216 -0
- package/scripts/refactor/import-graph.ts +187 -0
- package/scripts/refactor/refactor-lint.ts +250 -0
- package/scripts/refactor/refactor-scan-cli.ts +10 -0
- package/scripts/refactor/refactor-scan.ts +124 -0
- package/scripts/refactor/refactor-targets.ts +103 -0
- package/scripts/release/release-cli.ts +88 -0
- package/scripts/release/release-history.ts +132 -0
- package/scripts/release/release-plan.ts +130 -0
- package/scripts/release/release-publish.ts +152 -0
- package/scripts/release/release-scope-cli.ts +103 -0
- package/scripts/release/release-tag.ts +93 -0
- package/scripts/release/release-worktree.ts +71 -0
- package/scripts/repo/auto-merge-setting-logic.ts +100 -0
- package/scripts/repo/auto-merge-setting.ts +37 -0
- package/scripts/repo/repo-setting.ts +112 -0
- package/scripts/report/report-lint-cli.ts +49 -0
- package/scripts/report/report-lint.ts +250 -0
- package/scripts/retrospective/retrospective-cli.ts +97 -0
- package/scripts/retrospective/retrospective.ts +127 -0
- package/scripts/review/disposition-cli.ts +44 -0
- package/scripts/review/disposition-logic.ts +45 -0
- package/scripts/review/live-evidence.ts +62 -0
- package/scripts/review/review-attest-cli.ts +115 -0
- package/scripts/review/review-attest.ts +319 -0
- package/scripts/review/review-brief-cli.ts +290 -0
- package/scripts/review/review-brief.ts +440 -0
- package/scripts/review/review-checkout.ts +56 -0
- package/scripts/review/review-finding-ledger.ts +167 -0
- package/scripts/review/review-findings-cli.ts +57 -0
- package/scripts/review/review-level.ts +86 -0
- package/scripts/review/review-record-cli.ts +196 -0
- package/scripts/review/review-record.ts +74 -0
- package/scripts/review/review-round2-cli.ts +84 -0
- package/scripts/review/review-round2.ts +139 -0
- package/scripts/review/review-stamps.ts +113 -0
- package/scripts/review/review-tree.ts +58 -0
- package/scripts/rules/bash-triggers.ts +44 -0
- package/scripts/rules/decision-oracle.ts +342 -0
- package/scripts/rules/delivered-rules-harness.ts +72 -0
- package/scripts/rules/delivered-rules.ts +793 -0
- package/scripts/rules/early-heartbeat.ts +241 -0
- package/scripts/rules/file-body.ts +150 -0
- package/scripts/rules/filing-cap.ts +133 -0
- package/scripts/rules/filing-offer.ts +81 -0
- package/scripts/rules/firing-point.ts +63 -0
- package/scripts/rules/gh-api.ts +65 -0
- package/scripts/rules/git-argv.ts +129 -0
- package/scripts/rules/git-force.ts +104 -0
- package/scripts/rules/implementation-cut-verdict.ts +84 -0
- package/scripts/rules/implementation-cut.ts +202 -0
- package/scripts/rules/issue-citation.ts +242 -0
- package/scripts/rules/issue-fold.ts +73 -0
- package/scripts/rules/issue-scout.ts +64 -0
- package/scripts/rules/josh-git-bare.ts +80 -0
- package/scripts/rules/lane-carry-conflict.ts +96 -0
- package/scripts/rules/lane-interactive-ask.ts +71 -0
- package/scripts/rules/lane-park.ts +122 -0
- package/scripts/rules/lane-switch-main.ts +139 -0
- package/scripts/rules/oracle-consulted.ts +81 -0
- package/scripts/rules/oracle-firing.ts +151 -0
- package/scripts/rules/oracle-list-cli.ts +81 -0
- package/scripts/rules/piped-verification.ts +126 -0
- package/scripts/rules/poll-loop.ts +125 -0
- package/scripts/rules/pre-gate-cut.ts +207 -0
- package/scripts/rules/prior-comment-read.ts +106 -0
- package/scripts/rules/raw-field-body.ts +56 -0
- package/scripts/rules/reply-language.ts +116 -0
- package/scripts/rules/rule-body-guard.ts +206 -0
- package/scripts/rules/rule-guard.ts +23 -0
- package/scripts/rules/rule-value-cli.ts +129 -0
- package/scripts/rules/rule-value.ts +397 -0
- package/scripts/rules/run-tail.ts +178 -0
- package/scripts/rules/shell-body-trigger.ts +204 -0
- package/scripts/rules/shell-segments.ts +45 -0
- package/scripts/rules/stop-rules.ts +329 -0
- package/scripts/rules/tail-commands.ts +35 -0
- package/scripts/rules/test-declared-commit.ts +51 -0
- package/scripts/rules/third-party-write.ts +90 -0
- package/scripts/rules/top-level-scripts-guard.ts +47 -0
- package/scripts/rules/worktree-guard.ts +130 -0
- package/scripts/run/detached-launch.ts +360 -0
- package/scripts/run/run-carry-args.ts +264 -0
- package/scripts/run/run-carry-change.ts +69 -0
- package/scripts/run/run-carry-cli.ts +441 -0
- package/scripts/run/run-carry-flush.ts +63 -0
- package/scripts/run/run-carry-stash.ts +71 -0
- package/scripts/run/run-carry-streak.ts +113 -0
- package/scripts/run/run-carry.ts +550 -0
- package/scripts/run/run-cut-args.ts +132 -0
- package/scripts/run/run-cut-cli.ts +461 -0
- package/scripts/run/run-cut-handoff.ts +126 -0
- package/scripts/run/run-cut.ts +531 -0
- package/scripts/run/run-ending-cli.ts +111 -0
- package/scripts/run/run-ending.ts +239 -0
- package/scripts/run/run-entry-cli.ts +135 -0
- package/scripts/run/run-entry.ts +95 -0
- package/scripts/run/run-event-cli.ts +210 -0
- package/scripts/run/run-event-follow.ts +65 -0
- package/scripts/run/run-event-render.ts +75 -0
- package/scripts/run/run-event-scope.ts +127 -0
- package/scripts/run/run-event-stream-emit.ts +140 -0
- package/scripts/run/run-event-stream.ts +258 -0
- package/scripts/run/run-event-watch.ts +37 -0
- package/scripts/run/run-headless.ts +105 -0
- package/scripts/run/run-hold-cli.ts +310 -0
- package/scripts/run/run-hold.ts +264 -0
- package/scripts/run/run-invocation.ts +237 -0
- package/scripts/run/run-issue-number.ts +19 -0
- package/scripts/run/run-liveness-cli.ts +169 -0
- package/scripts/run/run-liveness.ts +424 -0
- package/scripts/run/run-merge-cli.ts +385 -0
- package/scripts/run/run-merge-steps.ts +326 -0
- package/scripts/run/run-merge.ts +158 -0
- package/scripts/run/run-next-cli.ts +48 -0
- package/scripts/run/run-next.ts +80 -0
- package/scripts/run/run-preflight.ts +337 -0
- package/scripts/run/run-prep-cli.ts +151 -0
- package/scripts/run/run-prep.ts +84 -0
- package/scripts/run/run-progress-args.ts +65 -0
- package/scripts/run/run-progress-cli.ts +508 -0
- package/scripts/run/run-progress-clock.ts +320 -0
- package/scripts/run/run-progress-config.ts +119 -0
- package/scripts/run/run-progress-read.ts +199 -0
- package/scripts/run/run-progress.ts +366 -0
- package/scripts/run/run-report-cli.ts +71 -0
- package/scripts/run/run-report.ts +78 -0
- package/scripts/run/run-review-cli.ts +130 -0
- package/scripts/run/run-review-steps.ts +161 -0
- package/scripts/run/run-review.ts +121 -0
- package/scripts/run/run-ship-cli.ts +431 -0
- package/scripts/run/run-ship-detach.ts +200 -0
- package/scripts/run/run-ship-probe.ts +103 -0
- package/scripts/run/run-ship-return.ts +75 -0
- package/scripts/run/run-ship-review-steps.ts +227 -0
- package/scripts/run/run-ship-review.ts +177 -0
- package/scripts/run/run-ship-stage.ts +150 -0
- package/scripts/run/run-ship.ts +78 -0
- package/scripts/run/run-status-cli.ts +175 -0
- package/scripts/run/run-status.ts +77 -0
- package/scripts/run/run-step-cli.ts +111 -0
- package/scripts/run/run-step.ts +292 -0
- package/scripts/run/run-stop-notify.ts +52 -0
- package/scripts/run/run-stranded-cli.ts +31 -0
- package/scripts/run/run-stranded-detect.ts +134 -0
- package/scripts/run/run-stranded.ts +120 -0
- package/scripts/run/run-tail-cli.ts +105 -0
- package/scripts/run/run-tail.ts +61 -0
- package/scripts/run/run-transcript.golden.txt +57 -0
- package/scripts/run/run-wake-cli.ts +428 -0
- package/scripts/run/run-wake-describe.ts +97 -0
- package/scripts/run/run-wake-driver.ts +80 -0
- package/scripts/run/run-wake-handoff.ts +29 -0
- package/scripts/run/run-wake-loop.ts +223 -0
- package/scripts/run/run-wake-session.ts +150 -0
- package/scripts/run/run-wake-work.ts +104 -0
- package/scripts/run/run-wake.ts +607 -0
- package/scripts/run/run-watcher-guard-cli.ts +37 -0
- package/scripts/run/run-watcher-guard.ts +59 -0
- package/scripts/run/run-watcher-hook.ts +86 -0
- package/scripts/security/secretlint-scan.ts +86 -0
- package/scripts/security/security-audit-logic.ts +51 -0
- package/scripts/security/security-audit-provision-logic.ts +217 -0
- package/scripts/security/security-audit-provision.ts +186 -0
- package/scripts/security/security-audit.ts +132 -0
- package/scripts/security/security-updates-logic.ts +131 -0
- package/scripts/security/security-updates.ts +38 -0
- package/scripts/security/sonar-file.ts +44 -0
- package/scripts/self-sync-guard/index.ts +5 -0
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +98 -0
- package/scripts/self-sync-guard/self-sync-refusal.ts +22 -0
- package/scripts/sonar/sonar-hotspots-cli.ts +149 -0
- package/scripts/sonar/sonar-hotspots.ts +111 -0
- package/scripts/split/split-assess-cli.ts +52 -0
- package/scripts/split/split-assess.ts +124 -0
- package/scripts/sync/dependabot-pin-logic.ts +135 -0
- package/scripts/sync/directory-copy-guard.ts +187 -0
- package/scripts/sync/file-content.ts +49 -0
- package/scripts/sync/managed-config-scope-cli.ts +64 -0
- package/scripts/sync/managed-config-scope.ts +123 -0
- package/scripts/sync/plugin-skill-directories.ts +15 -0
- package/scripts/sync/reconcile-templates.ts +53 -0
- package/scripts/sync/removed-skill-manifest.ts +27 -0
- package/scripts/sync/skill-migration.ts +192 -0
- package/scripts/sync/sync-configs.ts +156 -0
- package/scripts/sync/sync-hook-safety.ts +82 -0
- package/scripts/sync/sync.ts +417 -0
- package/scripts/sync/synced-paths.ts +52 -0
- package/scripts/sync/template-source-logic.ts +122 -0
- package/scripts/sync/workflow-pin-logic.ts +240 -0
- package/scripts/test/classify-isolation.ts +149 -0
- package/scripts/test/e2e-retry-check.ts +150 -0
- package/scripts/test/http-fault-injection.ts +79 -0
- package/scripts/test/josh-harness-environment.ts +260 -0
- package/scripts/test/josh-harness.ts +96 -0
- package/scripts/test/pilot-files.ts +457 -0
- package/scripts/test/pilot-measure.ts +78 -0
- package/scripts/test/test-declared-changed.ts +99 -0
- package/scripts/test/test-declared-logic.ts +91 -0
- package/scripts/test/test-declared-match.ts +106 -0
- package/scripts/test/test-declared.ts +180 -0
- package/scripts/test/test-e2e-guard.ts +86 -0
- package/scripts/test/test-network-guard.ts +453 -0
- package/scripts/test/test-red-commit.ts +51 -0
- package/scripts/test/test-red-logic.ts +76 -0
- package/scripts/test/test-red.ts +154 -0
- package/scripts/test/test-related-scope.ts +115 -0
- package/scripts/test/test-related.ts +73 -0
- package/scripts/test/test-repository-guard.ts +317 -0
- package/scripts/test/test-state-guard.ts +85 -0
- package/scripts/test/test-stdout-guard.ts +54 -0
- package/scripts/test/test-telegram-guard.ts +90 -0
- package/scripts/test/test-type-logic.ts +31 -0
- package/scripts/test/test-unit-guard.ts +185 -0
- package/scripts/test/unit-guard-environment.ts +12 -0
- package/scripts/test/unit-projects.ts +139 -0
- package/scripts/test/unit-worker-share.ts +251 -0
- package/scripts/test/vitest-include-globs.ts +12 -0
- package/scripts/time-runtime/time-agent-bundles.ts +128 -0
- package/scripts/time-runtime/time-background.ts +300 -0
- package/scripts/time-runtime/time-batch-guard-fixtures.ts +66 -0
- package/scripts/time-runtime/time-batch-guard.ts +529 -0
- package/scripts/time-runtime/time-bundle-call.ts +575 -0
- package/scripts/time-runtime/time-bundles.ts +536 -0
- package/scripts/time-runtime/time-call-identity.ts +37 -0
- package/scripts/time-runtime/time-command-key.ts +35 -0
- package/scripts/time-runtime/time-density-hook.ts +166 -0
- package/scripts/time-runtime/time-density.ts +147 -0
- package/scripts/time-runtime/time-followup-stage.ts +107 -0
- package/scripts/time-runtime/time-format.ts +186 -0
- package/scripts/time-runtime/time-hook-transcript.ts +82 -0
- package/scripts/time-runtime/time-instant.ts +20 -0
- package/scripts/time-runtime/time-markers.ts +228 -0
- package/scripts/time-runtime/time-phase-names.ts +123 -0
- package/scripts/time-runtime/time-reported-failure.ts +227 -0
- package/scripts/time-runtime/time-round-trips.ts +279 -0
- package/scripts/time-runtime/time-shell.ts +286 -0
- package/scripts/time-runtime/time-single-check.ts +65 -0
- package/scripts/time-runtime/time-spans.ts +545 -0
- package/scripts/time-runtime/time-transcript-line.ts +253 -0
- package/scripts/time-runtime/time-writes.ts +71 -0
- package/scripts/ui/ui-routes-cli.ts +122 -0
- package/scripts/ui/ui-routes.ts +102 -0
- package/scripts/version/bump-version.ts +71 -0
- package/scripts/version/effective-upstream.ts +93 -0
- package/scripts/version/index.ts +25 -0
- package/scripts/version/kit-descriptor.ts +10 -0
- package/scripts/version/kit-version-config.ts +30 -0
- package/scripts/version/latest-corepack.ts +404 -0
- package/scripts/version/latest-lane-guard.ts +49 -0
- package/scripts/version/latest-regression.ts +93 -0
- package/scripts/version/latest-scope-cli.ts +147 -0
- package/scripts/version/latest-stamp.ts +107 -0
- package/scripts/version/latest-update.ts +198 -0
- package/scripts/version/package-manager-version.ts +95 -0
- package/scripts/version/parse-json.ts +13 -0
- package/scripts/version/preinstall-version-update.ts +84 -0
- package/scripts/version/publishable-range-check.ts +74 -0
- package/scripts/version/publishable-range.ts +123 -0
- package/scripts/version/release-age.ts +146 -0
- package/scripts/version/release-hold.ts +142 -0
- package/scripts/version/running-binary.ts +42 -0
- package/scripts/version/upgrade-command-guard.ts +49 -0
- package/scripts/version/upgrade-shell-command.ts +30 -0
- package/scripts/version/version-check-logic.ts +333 -0
- package/scripts/version/version-check.ts +14 -0
- package/scripts/version/version-command-config.ts +177 -0
- package/scripts/version/version-commands.ts +296 -0
- package/scripts/version/version-remote.ts +86 -0
- package/scripts/version/version-targets.ts +81 -0
- package/scripts/yaml/yaml-document.ts +46 -0
- package/scripts-ai/completion-gate.ts +13 -0
- package/scripts-ai/environment-loader.ts +9 -0
- package/scripts-ai/epic-check.ts +34 -0
- package/scripts-ai/epic-cli-argv.ts +77 -0
- package/scripts-ai/epic-cli-remove.ts +71 -0
- package/scripts-ai/epic-cli.ts +413 -0
- package/scripts-ai/epic.ts +192 -0
- package/scripts-ai/followup-issue-number.ts +31 -0
- package/scripts-ai/git-followup-finish.ts +217 -0
- package/scripts-ai/git-followup-workflow.ts +252 -0
- package/scripts-ai/git-workflow.ts +246 -0
- package/scripts-ai/telegram-test-logic.ts +88 -0
- package/scripts-ai/telegram-test.ts +130 -0
- package/templates/gitignore +76 -0
- package/templates/sonar-project.properties +52 -0
- package/templates/workflows/ci.yml +639 -0
- package/templates/workflows/dependabot-auto-merge.yml +428 -0
- package/tsconfig/base.json +50 -0
- package/tsconfig.sonar.json +34 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { git_command } from '#scripts/git/git-command'
|
|
2
|
+
import { git_gh_pr_read } from '#scripts/git/git-gh-pr-read'
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
import { run_hold } from './run-hold'
|
|
5
|
+
import { run_issue_number } from './run-issue-number'
|
|
6
|
+
|
|
7
|
+
// The preflight check — what an interrupted run left in this working tree, and what the rule says to
|
|
8
|
+
// do about it before the next child starts (joshuafolkken/kit#926). It once had its own
|
|
9
|
+
// `josh run:preflight` CLI; joshuafolkken/kit#1965 folded the check into `run:hold`, which now runs it
|
|
10
|
+
// before it claims the tree, so this module is the shared logic behind that claim and behind
|
|
11
|
+
// `run:progress`, and no longer a command of its own.
|
|
12
|
+
//
|
|
13
|
+
// joshuafolkken/kit#1091 gave a run a way to say "this tree is mine". This is the sibling question,
|
|
14
|
+
// and it is about the run that never said anything again: an unattended run ends abnormally — a
|
|
15
|
+
// crash, a Ctrl-C, a laptop asleep, an expired token — and leaves its feature branch, its open pull
|
|
16
|
+
// request and its uncommitted changes behind. Every child of an `epicrun` starts with
|
|
17
|
+
// `git switch main && git pull`, which refuses over a dirty tree, and an agent may not reach for
|
|
18
|
+
// `git stash` on its own judgement, so the batch could not recover without a person.
|
|
19
|
+
//
|
|
20
|
+
// **The rule answers, so the run does not judge.** "There is a branch already, I will carry on from
|
|
21
|
+
// it" and "there is a branch already, I had better stop" are both defensible in the moment, which is
|
|
22
|
+
// exactly why the choice is not left to the moment — the same reason `josh delegate` and
|
|
23
|
+
// `josh review:level` refuse to leave their answers to an agent.
|
|
24
|
+
//
|
|
25
|
+
// **The check is re-askable, which the claim it now gates deliberately is not.** A claim asked twice
|
|
26
|
+
// answers `busy`, because the second ask is a second run. This check reads state and writes nothing,
|
|
27
|
+
// so the reclaim recovery ends by asking `run:hold` again on the tree it just cleaned.
|
|
28
|
+
|
|
29
|
+
const CLEAN_VERDICT = 'clean'
|
|
30
|
+
const RECLAIM_VERDICT = 'reclaim'
|
|
31
|
+
const RESUME_VERDICT = 'resume'
|
|
32
|
+
const PARK_VERDICT = 'park'
|
|
33
|
+
|
|
34
|
+
type PreflightVerdict =
|
|
35
|
+
typeof CLEAN_VERDICT | typeof PARK_VERDICT | typeof RECLAIM_VERDICT | typeof RESUME_VERDICT
|
|
36
|
+
|
|
37
|
+
const NO_PR = 'none'
|
|
38
|
+
const OPEN_PR = 'open'
|
|
39
|
+
const MERGED_PR = 'merged'
|
|
40
|
+
const CLOSED_PR = 'closed'
|
|
41
|
+
|
|
42
|
+
type PrState = typeof CLOSED_PR | typeof MERGED_PR | typeof NO_PR | typeof OPEN_PR
|
|
43
|
+
|
|
44
|
+
interface TreeState {
|
|
45
|
+
branch: string
|
|
46
|
+
default_branch: string
|
|
47
|
+
is_dirty: boolean
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface ChildState {
|
|
51
|
+
branch_name: string | undefined
|
|
52
|
+
pr_state: PrState
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface PreflightDecision {
|
|
56
|
+
advice: string
|
|
57
|
+
reason: string
|
|
58
|
+
verdict: PreflightVerdict
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const NO_CHILD_WORK: ChildState = { branch_name: undefined, pr_state: NO_PR }
|
|
62
|
+
|
|
63
|
+
// `pr_view` answers with the three fields `to_pr_info` selects; only the state matters here, and it
|
|
64
|
+
// is already normalized to upper case by `git-gh-rest-state.ts`, so a lower-case REST spelling never
|
|
65
|
+
// reaches this map.
|
|
66
|
+
const pr_info_schema = z.object({ state: z.string().optional() })
|
|
67
|
+
|
|
68
|
+
const GH_PR_STATES: ReadonlyMap<string, PrState> = new Map([
|
|
69
|
+
['CLOSED', CLOSED_PR],
|
|
70
|
+
['MERGED', MERGED_PR],
|
|
71
|
+
['OPEN', OPEN_PR],
|
|
72
|
+
])
|
|
73
|
+
|
|
74
|
+
const CLEAN_REASON =
|
|
75
|
+
'Nothing was left behind: the tree is clean, HEAD is on the default branch, and this issue has no branch or pull request.'
|
|
76
|
+
|
|
77
|
+
const CLEAN_ADVICE = 'Start the child.'
|
|
78
|
+
|
|
79
|
+
const RESUME_ADVICE =
|
|
80
|
+
'Reuse the branch and run the whole verification gate from the start — refactor, `pnpm josh gate`, `/code-review` — never only the part the interrupted run had not reached. Nobody verified what it already committed.'
|
|
81
|
+
|
|
82
|
+
const PARK_ADVICE =
|
|
83
|
+
'Park the child: add `needs-decision` and comment what was found. Do not delete the branch, do not reopen the pull request, and do not commit on top of it.'
|
|
84
|
+
|
|
85
|
+
const STASH_LABEL_PREFIX = 'run:hold reclaimed before #'
|
|
86
|
+
|
|
87
|
+
// The issue number reaches the advice inside a double-quoted shell command a caller is told to paste,
|
|
88
|
+
// so the shape it may take is pinned beside the interpolation rather than only in the CLI that
|
|
89
|
+
// happens to be today's single caller. `run:liveness` interpolates it the same way, so the pattern
|
|
90
|
+
// and the refusal live in one module both read (joshuafolkken/kit#1485).
|
|
91
|
+
const { ISSUE_NUMBER_PATTERN, require_issue_number } = run_issue_number
|
|
92
|
+
const UNREADABLE_PR_MESSAGE = 'The pull request could not be read for branch '
|
|
93
|
+
|
|
94
|
+
function needs_reclaim(tree: TreeState): boolean {
|
|
95
|
+
return tree.is_dirty || tree.branch !== tree.default_branch
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// A pull request that was merged or closed is a decision somebody already made. Carrying on over a
|
|
99
|
+
// merged one duplicates work that landed; carrying on over a closed one revives work that was
|
|
100
|
+
// rejected. Which of those is happening is a person's read, so this is the one verdict that parks.
|
|
101
|
+
function is_pr_decided(state: PrState): boolean {
|
|
102
|
+
return state === MERGED_PR || state === CLOSED_PR
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// **The second clause is `decide`'s contract, not a case `check` produces.** A pull request is only
|
|
106
|
+
// ever reached through one of the candidate branches, so a state read from `check` never carries an
|
|
107
|
+
// open pull request without the branch it belongs to — and a pull request whose head branch is gone
|
|
108
|
+
// from the checkout *and* the remote is outside what this command can see at all, which is what
|
|
109
|
+
// `docs/josh-commands.md` says rather than implying coverage the read does not have.
|
|
110
|
+
function has_leftover_work(child: ChildState): boolean {
|
|
111
|
+
return child.branch_name !== undefined || child.pr_state === OPEN_PR
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// The precedence is fixed, and the first row is why it has to be. A `resume` or a `park` decided over
|
|
115
|
+
// a dirty tree hands the next child a checkout it cannot switch — so the tree is reclaimed first and
|
|
116
|
+
// the question asked again on the clean tree, rather than two answers being merged into one.
|
|
117
|
+
function to_verdict(tree: TreeState, child: ChildState): PreflightVerdict {
|
|
118
|
+
if (needs_reclaim(tree)) return RECLAIM_VERDICT
|
|
119
|
+
|
|
120
|
+
if (is_pr_decided(child.pr_state)) return PARK_VERDICT
|
|
121
|
+
|
|
122
|
+
if (has_leftover_work(child)) return RESUME_VERDICT
|
|
123
|
+
|
|
124
|
+
return CLEAN_VERDICT
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function reclaim_reason(tree: TreeState): string {
|
|
128
|
+
const findings = [
|
|
129
|
+
tree.is_dirty ? 'uncommitted changes' : undefined,
|
|
130
|
+
tree.branch === tree.default_branch ? undefined : `HEAD on ${tree.branch}`,
|
|
131
|
+
].filter((entry): entry is string => entry !== undefined)
|
|
132
|
+
|
|
133
|
+
return `An earlier run left ${findings.join(' and ')} in this working tree.`
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function park_reason(state: PrState): string {
|
|
137
|
+
return `The pull request for this issue is ${state}, so whether any work is still owed is a person's call.`
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function resume_reason(child: ChildState): string {
|
|
141
|
+
const branch_part = child.branch_name === undefined ? '' : ` on branch ${child.branch_name}`
|
|
142
|
+
const pr_part = child.pr_state === OPEN_PR ? ', and its pull request is still open' : ''
|
|
143
|
+
|
|
144
|
+
return `An earlier run left a partial implementation${branch_part}${pr_part}.`
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function to_reason(verdict: PreflightVerdict, tree: TreeState, child: ChildState): string {
|
|
148
|
+
if (verdict === RECLAIM_VERDICT) return reclaim_reason(tree)
|
|
149
|
+
|
|
150
|
+
if (verdict === PARK_VERDICT) return park_reason(child.pr_state)
|
|
151
|
+
|
|
152
|
+
if (verdict === RESUME_VERDICT) return resume_reason(child)
|
|
153
|
+
|
|
154
|
+
return CLEAN_REASON
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// **`-u` is not optional.** What an interrupted run leaves almost always includes a new `*.test.ts`,
|
|
158
|
+
// which is untracked, and a stash without it leaves exactly those files for the `git switch` that
|
|
159
|
+
// follows to refuse over. **And the stash is recorded rather than popped**, which is what sets this
|
|
160
|
+
// stash apart from every other sanctioned one: the work belongs to a run that is gone, so the Issue
|
|
161
|
+
// comment is the only thing that can ever bring it back.
|
|
162
|
+
//
|
|
163
|
+
// **The stash lines appear only over a dirty tree.** `reclaim` also answers a clean checkout parked on
|
|
164
|
+
// a feature branch, and printing them there tells the caller to record a stash `git stash push` never
|
|
165
|
+
// created — an Issue comment naming nothing, under a rule that says the comment is what restores it.
|
|
166
|
+
function reclaim_steps(tree: TreeState, issue: string): Array<string> {
|
|
167
|
+
if (!tree.is_dirty) return []
|
|
168
|
+
|
|
169
|
+
return [
|
|
170
|
+
`git stash push -u -m "${STASH_LABEL_PREFIX}${issue}"`,
|
|
171
|
+
`Record the stash on #${issue} — the comment is what gets it popped; nothing pops it for you.`,
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function reclaim_advice(tree: TreeState, issue: string): string {
|
|
176
|
+
return [
|
|
177
|
+
...reclaim_steps(tree, issue),
|
|
178
|
+
`git switch ${tree.default_branch} && git pull`,
|
|
179
|
+
'Then ask this command again: it is re-askable, and the clean tree gets its own answer.',
|
|
180
|
+
].join('\n')
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function to_advice(verdict: PreflightVerdict, issue: string, tree: TreeState): string {
|
|
184
|
+
if (verdict === RECLAIM_VERDICT) return reclaim_advice(tree, issue)
|
|
185
|
+
|
|
186
|
+
if (verdict === RESUME_VERDICT) return RESUME_ADVICE
|
|
187
|
+
|
|
188
|
+
if (verdict === PARK_VERDICT) return PARK_ADVICE
|
|
189
|
+
|
|
190
|
+
return CLEAN_ADVICE
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function decide(tree: TreeState, child: ChildState, issue: string): PreflightDecision {
|
|
194
|
+
const verdict = to_verdict(tree, child)
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
advice: to_advice(verdict, issue, tree),
|
|
198
|
+
reason: to_reason(verdict, tree, child),
|
|
199
|
+
verdict,
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function read_pr_field(raw: string): string | undefined {
|
|
204
|
+
try {
|
|
205
|
+
return pr_info_schema.parse(JSON.parse(raw)).state
|
|
206
|
+
} catch {
|
|
207
|
+
return undefined
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function to_pr_state(raw: string): PrState {
|
|
212
|
+
const state = read_pr_field(raw)
|
|
213
|
+
|
|
214
|
+
return (state === undefined ? undefined : GH_PR_STATES.get(state)) ?? NO_PR
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function read_tree_state(): Promise<TreeState> {
|
|
218
|
+
const [is_dirty, current, default_branch] = await Promise.all([
|
|
219
|
+
run_hold.is_tree_dirty(),
|
|
220
|
+
git_command.branch(),
|
|
221
|
+
git_command.get_default_branch(),
|
|
222
|
+
])
|
|
223
|
+
|
|
224
|
+
return { branch: current, default_branch, is_dirty }
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// **An unreadable `gh` is not an absent pull request.** `pr_view` folds both into `''` and cannot tell
|
|
228
|
+
// them apart, so the existence question is asked through `pr_exists`, which throws on a lookup it
|
|
229
|
+
// could not complete (joshuafolkken/kit#1048). That throw reaches the CLI as `unknown`; without it a
|
|
230
|
+
// rate-limited or logged-out `gh` turns a **merged** pull request into `resume`, and the run commits
|
|
231
|
+
// on top of work somebody already landed — the exact hazard `park` exists for.
|
|
232
|
+
// **The second half of the same guard.** `pr_exists` refuses to read an unreadable lookup as an
|
|
233
|
+
// absence, but `pr_view` still folds any failure of its own into `''` — and the two are separate
|
|
234
|
+
// round trips, so a rate limit or a 5xx arriving between them would put a **merged** pull request
|
|
235
|
+
// back through `NO_PR` and out as `resume`. An empty answer for a branch `pr_exists` has just
|
|
236
|
+
// confirmed is therefore a failed read by construction, and it throws rather than answering.
|
|
237
|
+
async function read_pr_state(branch_name: string): Promise<PrState> {
|
|
238
|
+
if (!(await git_gh_pr_read.pr_exists(branch_name))) return NO_PR
|
|
239
|
+
|
|
240
|
+
const raw = await git_gh_pr_read.pr_view(branch_name)
|
|
241
|
+
|
|
242
|
+
if (raw === '') throw new Error(`${UNREADABLE_PR_MESSAGE}${branch_name}`)
|
|
243
|
+
|
|
244
|
+
return to_pr_state(raw)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function is_pr_open(state: PrState): boolean {
|
|
248
|
+
return state === OPEN_PR
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function read_pr_of_branch(branch_name: string): Promise<ChildState> {
|
|
252
|
+
return { branch_name, pr_state: await read_pr_state(branch_name) }
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// **A decided pull request on any candidate branch outranks an open one on another.** An interrupted
|
|
256
|
+
// run can leave more than one branch for an issue — a retry beside the original — and reading only
|
|
257
|
+
// whichever git lists first hides a merged pull request behind a branch that has none. **The branch
|
|
258
|
+
// reported is the one that produced the winning state**, so the reason never names branch A while the
|
|
259
|
+
// verdict came from branch B's pull request.
|
|
260
|
+
function pick_child_state(reads: ReadonlyArray<ChildState>): ChildState {
|
|
261
|
+
const decided = reads.find((read) => is_pr_decided(read.pr_state))
|
|
262
|
+
const open = reads.find((read) => is_pr_open(read.pr_state))
|
|
263
|
+
|
|
264
|
+
return decided ?? open ?? { branch_name: reads[0]?.branch_name, pr_state: NO_PR }
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// `git branch --list` takes a glob, so the branch is found without knowing its slug: `pnpm josh git`
|
|
268
|
+
// builds `<N>-<slug>` (`scripts/git/git-issue.ts` → `create_branch_name`), and `<N>-*` matches it
|
|
269
|
+
// whatever the title was, while never matching `<N><digit>-…`.
|
|
270
|
+
//
|
|
271
|
+
// **Remote-tracking branches are searched too**, and the remote name is stripped back off, because the
|
|
272
|
+
// pull request is keyed by its head branch: a run interrupted on another machine — or in a checkout
|
|
273
|
+
// since re-cloned — leaves the branch on the remote with no local counterpart, and searching locally
|
|
274
|
+
// alone would answer `clean` over an open pull request.
|
|
275
|
+
const ISSUE_BRANCH_SUFFIX = '-*'
|
|
276
|
+
const ANY_REMOTE_PREFIX = '*/'
|
|
277
|
+
const REMOTE_SEPARATOR = '/'
|
|
278
|
+
const NOT_FOUND_INDEX = -1
|
|
279
|
+
|
|
280
|
+
function to_head_branch(name: string): string {
|
|
281
|
+
const separator_index = name.indexOf(REMOTE_SEPARATOR)
|
|
282
|
+
|
|
283
|
+
return separator_index === NOT_FOUND_INDEX ? name : name.slice(separator_index + 1)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
async function read_branch_candidates(issue: string): Promise<Array<string>> {
|
|
287
|
+
const pattern = `${issue}${ISSUE_BRANCH_SUFFIX}`
|
|
288
|
+
const [local, remote] = await Promise.all([
|
|
289
|
+
git_command.branch_names(pattern),
|
|
290
|
+
git_command.branch_names_remote(`${ANY_REMOTE_PREFIX}${pattern}`),
|
|
291
|
+
])
|
|
292
|
+
|
|
293
|
+
return [...new Set([...local, ...remote.map((name) => to_head_branch(name))])]
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async function read_child_state(issue: string): Promise<ChildState> {
|
|
297
|
+
const candidates = await read_branch_candidates(issue)
|
|
298
|
+
|
|
299
|
+
return pick_child_state(
|
|
300
|
+
await Promise.all(candidates.map(async (name) => await read_pr_of_branch(name))),
|
|
301
|
+
)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// The child read is skipped where the tree already answers `reclaim`: a `gh` round trip buys nothing
|
|
305
|
+
// there, because the verdict would be `reclaim` whatever it said, and the recovery ends by asking
|
|
306
|
+
// this command again on the clean tree.
|
|
307
|
+
async function check(issue: string): Promise<PreflightDecision> {
|
|
308
|
+
require_issue_number(issue)
|
|
309
|
+
|
|
310
|
+
const tree = await read_tree_state()
|
|
311
|
+
|
|
312
|
+
if (needs_reclaim(tree)) return decide(tree, NO_CHILD_WORK, issue)
|
|
313
|
+
|
|
314
|
+
return decide(tree, await read_child_state(issue), issue)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const run_preflight = {
|
|
318
|
+
CLEAN_ADVICE,
|
|
319
|
+
CLEAN_REASON,
|
|
320
|
+
CLEAN_VERDICT,
|
|
321
|
+
ISSUE_NUMBER_PATTERN,
|
|
322
|
+
PARK_ADVICE,
|
|
323
|
+
PARK_VERDICT,
|
|
324
|
+
RECLAIM_VERDICT,
|
|
325
|
+
RESUME_ADVICE,
|
|
326
|
+
RESUME_VERDICT,
|
|
327
|
+
MERGED_PR,
|
|
328
|
+
STASH_LABEL_PREFIX,
|
|
329
|
+
check,
|
|
330
|
+
decide,
|
|
331
|
+
read_child_state,
|
|
332
|
+
read_pr_state,
|
|
333
|
+
to_pr_state,
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export type { ChildState, PreflightDecision, PreflightVerdict, PrState, TreeState }
|
|
337
|
+
export { run_preflight }
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { git_stash } from '#scripts/git/git-stash'
|
|
4
|
+
import { issue_read_cli, type BlockRead } from '#scripts/issue/issue-read-cli'
|
|
5
|
+
import { issue_state_cli, type StateRead } from '#scripts/issue/issue-state-cli'
|
|
6
|
+
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
7
|
+
import { latest_scope_cli } from '#scripts/version/latest-scope-cli'
|
|
8
|
+
import { run_prep, type PrepParts } from './run-prep'
|
|
9
|
+
|
|
10
|
+
// `josh run:prep <N>` — one call for the reads a `fullrun` makes before its first edit
|
|
11
|
+
// (joshuafolkken/kit#1978): the issue body and comments (`issue:read`), the state, labels and
|
|
12
|
+
// `human_review` line (`issue:state`), and the dependency-update scope (`latest:scope`). Each is
|
|
13
|
+
// reused rather than reproduced, and the two body reads run concurrently, so three round trips become
|
|
14
|
+
// one.
|
|
15
|
+
//
|
|
16
|
+
// **The hold and the cost check stay their own calls.** `run:hold` writes the working-tree record and
|
|
17
|
+
// `cost --over` reads the session, not the issue; folding a side effect and a session read into a
|
|
18
|
+
// bundle of issue reads would make one command answer three unrelated questions. They are batched in
|
|
19
|
+
// the same turn as this one instead.
|
|
20
|
+
|
|
21
|
+
const SUCCESS_EXIT_CODE = 0
|
|
22
|
+
const FAILURE_EXIT_CODE = 1
|
|
23
|
+
const ARGV_OFFSET = 2
|
|
24
|
+
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
25
|
+
const USAGE = 'Usage: josh run:prep <issue-number>'
|
|
26
|
+
const LANE_SKIP_SCOPE = 'not asked'
|
|
27
|
+
const LANE_SKIP_REASON =
|
|
28
|
+
'a dispatched lane child does not run josh latest — the parent does, once per session'
|
|
29
|
+
|
|
30
|
+
interface LatestDecision {
|
|
31
|
+
scope: string
|
|
32
|
+
reason: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface PrepReads {
|
|
36
|
+
content: BlockRead
|
|
37
|
+
state: StateRead
|
|
38
|
+
latest: LatestDecision
|
|
39
|
+
has_changes: boolean
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Exactly one issue number, or the call is refused: `run:prep` prepares one run, and a second number
|
|
43
|
+
// would print a second issue's body a caller reads as this run's own.
|
|
44
|
+
function parse_number(argv: ReadonlyArray<string>): string | undefined {
|
|
45
|
+
const [first] = argv
|
|
46
|
+
|
|
47
|
+
if (first === undefined || argv.length !== 1 || !ISSUE_NUMBER_PATTERN.test(first)) {
|
|
48
|
+
return undefined
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return first
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// One note for a read that produced nothing, naming which of the two it was — the same distinction
|
|
55
|
+
// `issue:read` and `issue:state` keep, so a bundled failure still tells a retry from an answer.
|
|
56
|
+
function failure_note(issue_number: string, kind: string): string {
|
|
57
|
+
return `(issue #${issue_number} not bundled: ${kind})`
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// A dispatched lane child never runs `josh latest` — the parent does it once per session
|
|
61
|
+
// (`backlogrun.md` → "`josh latest` runs once per session, not once per child"), so computing the
|
|
62
|
+
// dependency scope inside a lane would report a decision nothing there acts on. Skip the read and say
|
|
63
|
+
// so, rather than printing a `required` a lane never honors.
|
|
64
|
+
function latest_decision(): LatestDecision {
|
|
65
|
+
if (lane_child_marker.is_child_of(process.cwd())) {
|
|
66
|
+
return { scope: LANE_SKIP_SCOPE, reason: LANE_SKIP_REASON }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return latest_scope_cli.decide()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Whether a dispatched lane child's tree holds uncommitted work (joshuafolkken/kit#2476). A lane child
|
|
73
|
+
// that popped its parked work back and then found its issue closed is the one position that work is
|
|
74
|
+
// lost from — the lane is removed by force — so only a lane is asked; a person's own checkout keeps its
|
|
75
|
+
// unrelated edits out of the verdict. A status that cannot be read reports none, leaving the verdict
|
|
76
|
+
// printed before this read existed.
|
|
77
|
+
async function lane_has_changes(): Promise<boolean> {
|
|
78
|
+
if (!lane_child_marker.is_child_of(process.cwd())) return false
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
return await git_stash.has_changes(process.cwd())
|
|
82
|
+
} catch {
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function gather(issue_number: string): Promise<PrepReads> {
|
|
88
|
+
const [content, state, has_changes] = await Promise.all([
|
|
89
|
+
issue_read_cli.read_block(issue_number),
|
|
90
|
+
issue_state_cli.read_issue(issue_number),
|
|
91
|
+
lane_has_changes(),
|
|
92
|
+
])
|
|
93
|
+
|
|
94
|
+
return { content, state, latest: latest_decision(), has_changes }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function content_body(issue_number: string, content: BlockRead): string {
|
|
98
|
+
return content.kind === 'ok' ? content.block : failure_note(issue_number, content.kind)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function to_parts(issue_number: string, reads: PrepReads): PrepParts {
|
|
102
|
+
const state = reads.state.kind === 'state' ? reads.state.state : undefined
|
|
103
|
+
const state_failure = state === undefined ? failure_note(issue_number, reads.state.kind) : ''
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
issue_number,
|
|
107
|
+
content_body: content_body(issue_number, reads.content),
|
|
108
|
+
state,
|
|
109
|
+
state_failure,
|
|
110
|
+
latest_scope: reads.latest.scope,
|
|
111
|
+
latest_reason: reads.latest.reason,
|
|
112
|
+
has_changes: reads.has_changes,
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Non-zero when either issue read failed, exactly as `issue:read` and `issue:state` each exit, so a
|
|
117
|
+
// bundle missing a part is never read as a complete one.
|
|
118
|
+
function exit_code(reads: PrepReads): number {
|
|
119
|
+
const is_complete = reads.content.kind === 'ok' && reads.state.kind === 'state'
|
|
120
|
+
|
|
121
|
+
return is_complete ? SUCCESS_EXIT_CODE : FAILURE_EXIT_CODE
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
125
|
+
const issue_number = parse_number(argv)
|
|
126
|
+
|
|
127
|
+
if (issue_number === undefined) {
|
|
128
|
+
console.error(USAGE)
|
|
129
|
+
|
|
130
|
+
return FAILURE_EXIT_CODE
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const reads = await gather(issue_number)
|
|
134
|
+
|
|
135
|
+
console.info(run_prep.format_report(to_parts(issue_number, reads)))
|
|
136
|
+
|
|
137
|
+
return exit_code(reads)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
141
|
+
process.exitCode = await run(argv)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// `gather` and `to_parts` are exported so `run:next` reads the same state from the same three reads
|
|
145
|
+
// rather than growing a second copy of the gather (joshuafolkken/kit#2188) — `run:next` is the
|
|
146
|
+
// consumer of `run:prep` the epic #2166 wanted.
|
|
147
|
+
const run_prep_cli = { USAGE, gather, main, parse_number, run, to_parts }
|
|
148
|
+
|
|
149
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
150
|
+
|
|
151
|
+
export { run_prep_cli }
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { issue_state, type IssueState } from '#scripts/issue/issue-state'
|
|
2
|
+
|
|
3
|
+
// `josh run:prep <N>` — the reads a `fullrun` makes before its first edit, assembled into one report
|
|
4
|
+
// (joshuafolkken/kit#1978). Two earlier passes at the setup phase were a documentation rule
|
|
5
|
+
// (joshuafolkken/kit#1847) and a measurement (joshuafolkken/kit#1868); neither was an execution-side
|
|
6
|
+
// change, and the `setup` median did not move. This joins the issue body and comments, the state and
|
|
7
|
+
// `human_review` line, and the dependency-update scope that `issue:read`, `issue:state` and
|
|
8
|
+
// `latest:scope` answered in three separate calls — reusing each rather than reproducing it.
|
|
9
|
+
//
|
|
10
|
+
// The leading summary line carries the three facts a run branches on — the state, whether the issue
|
|
11
|
+
// stops before its commit, and whether a dependency update is owed — so the decision is read off the
|
|
12
|
+
// first line without parsing the sections below it.
|
|
13
|
+
|
|
14
|
+
const SUMMARY_PREFIX = 'prep #'
|
|
15
|
+
const STATE_LABEL = 'state: '
|
|
16
|
+
const HUMAN_REVIEW_LABEL = 'human_review: '
|
|
17
|
+
const LATEST_LABEL = 'latest: '
|
|
18
|
+
const FIELD_SEPARATOR = ' · '
|
|
19
|
+
const SUMMARY_DASH = ' — '
|
|
20
|
+
const UNKNOWN = '?'
|
|
21
|
+
const YES = 'yes'
|
|
22
|
+
const NO = 'no'
|
|
23
|
+
const CONTENT_HEADER = '=== issue ==='
|
|
24
|
+
const STATE_HEADER = '=== state ==='
|
|
25
|
+
const LATEST_HEADER = '=== dependency update ==='
|
|
26
|
+
const SECTION_SEPARATOR = '\n\n'
|
|
27
|
+
const LATEST_JOINER = ' — '
|
|
28
|
+
|
|
29
|
+
interface PrepParts {
|
|
30
|
+
issue_number: string
|
|
31
|
+
content_body: string
|
|
32
|
+
// `undefined` when the state read failed; `state_failure` then carries the note that stands in for
|
|
33
|
+
// the three-line block, so a bundled failure never prints as an empty state.
|
|
34
|
+
state: IssueState | undefined
|
|
35
|
+
state_failure: string
|
|
36
|
+
latest_scope: string
|
|
37
|
+
latest_reason: string
|
|
38
|
+
// Whether a lane child's tree holds uncommitted work — read for the verdict, not printed in the
|
|
39
|
+
// report (joshuafolkken/kit#2476).
|
|
40
|
+
has_changes: boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function human_review_value(state: IssueState | undefined): string {
|
|
44
|
+
if (state === undefined) return UNKNOWN
|
|
45
|
+
|
|
46
|
+
return state.is_human_review ? YES : NO
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function summary(parts: PrepParts): string {
|
|
50
|
+
const state_value = parts.state === undefined ? UNKNOWN : parts.state.state
|
|
51
|
+
const fields = [
|
|
52
|
+
`${STATE_LABEL}${state_value}`,
|
|
53
|
+
`${HUMAN_REVIEW_LABEL}${human_review_value(parts.state)}`,
|
|
54
|
+
`${LATEST_LABEL}${parts.latest_scope}`,
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
return `${SUMMARY_PREFIX}${parts.issue_number}${SUMMARY_DASH}${fields.join(FIELD_SEPARATOR)}`
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// The state's three lines come from `issue:state`'s own formatter, so the spelling a document compares
|
|
61
|
+
// against — `human_review: yes` included — is the one this bundle prints.
|
|
62
|
+
function state_body(parts: PrepParts): string {
|
|
63
|
+
return parts.state === undefined
|
|
64
|
+
? parts.state_failure
|
|
65
|
+
: issue_state.format_issue_state(parts.state)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function section(header: string, body: string): string {
|
|
69
|
+
return `${header}\n${body}`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function format_report(parts: PrepParts): string {
|
|
73
|
+
return [
|
|
74
|
+
summary(parts),
|
|
75
|
+
section(CONTENT_HEADER, parts.content_body),
|
|
76
|
+
section(STATE_HEADER, state_body(parts)),
|
|
77
|
+
section(LATEST_HEADER, `${parts.latest_scope}${LATEST_JOINER}${parts.latest_reason}`),
|
|
78
|
+
].join(SECTION_SEPARATOR)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const run_prep = { CONTENT_HEADER, LATEST_HEADER, STATE_HEADER, SUMMARY_PREFIX, format_report }
|
|
82
|
+
|
|
83
|
+
export type { PrepParts }
|
|
84
|
+
export { run_prep }
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util'
|
|
2
|
+
import { run_progress_config } from './run-progress-config'
|
|
3
|
+
|
|
4
|
+
// The argument half of `josh run:progress`, kept apart from the watcher so the CLI stays inside the file
|
|
5
|
+
// limit (joshuafolkken/kit#2503). Everything here is pure: argv in, values out.
|
|
6
|
+
|
|
7
|
+
// A watcher outlives the turn that started it, so something has to end it. One hour is three of the
|
|
8
|
+
// default twenty-minute intervals: long enough that the bound never truncates a report, short enough
|
|
9
|
+
// that a watcher left waiting on a run that has already merged is gone within the hour. It is
|
|
10
|
+
// deliberately **not** `run:hold`'s eight-hour expiry — that holds an uncommitted working tree across
|
|
11
|
+
// a person's latency and is trampled by being short (joshuafolkken/kit#1091), while a watcher holds
|
|
12
|
+
// only a heartbeat the caller restarts on the next interval, so the two guard different things and
|
|
13
|
+
// only one has anything to lose by being short.
|
|
14
|
+
const DEFAULT_MAX_HOURS = 1
|
|
15
|
+
const MS_PER_HOUR = 3_600_000
|
|
16
|
+
|
|
17
|
+
const OPTIONS = {
|
|
18
|
+
hours: { type: 'string' },
|
|
19
|
+
interval: { type: 'string' },
|
|
20
|
+
mark: { type: 'boolean' },
|
|
21
|
+
once: { type: 'boolean' },
|
|
22
|
+
output: { type: 'string', multiple: true },
|
|
23
|
+
path: { type: 'boolean' },
|
|
24
|
+
repo: { type: 'string' },
|
|
25
|
+
wait: { type: 'boolean' },
|
|
26
|
+
} as const
|
|
27
|
+
|
|
28
|
+
interface ParsedValues {
|
|
29
|
+
hours?: string
|
|
30
|
+
interval?: string
|
|
31
|
+
mark?: boolean
|
|
32
|
+
once?: boolean
|
|
33
|
+
output?: Array<string>
|
|
34
|
+
path?: boolean
|
|
35
|
+
repo?: string
|
|
36
|
+
wait?: boolean
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function read_arguments(argv: ReadonlyArray<string>): ParsedValues | undefined {
|
|
40
|
+
try {
|
|
41
|
+
return parseArgs({ args: [...argv], options: OPTIONS }).values
|
|
42
|
+
} catch {
|
|
43
|
+
return undefined
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// A hand-typed `--interval` outranks the environment, the environment outranks the interval the
|
|
48
|
+
// repository commits, and that outranks the twenty-minute default. Every step goes through the same
|
|
49
|
+
// reader, so an unusable value falls back rather than ending an unattended run over an optional
|
|
50
|
+
// setting — `run-progress-config.ts` → `resolve_interval_ms` is where that order is written down.
|
|
51
|
+
function to_interval_ms(raw: string | undefined): number {
|
|
52
|
+
return run_progress_config.resolve_interval_ms(raw)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function to_max_ms(raw: string | undefined): number {
|
|
56
|
+
const hours = Number(raw)
|
|
57
|
+
const is_usable = raw !== undefined && Number.isFinite(hours) && hours > 0
|
|
58
|
+
|
|
59
|
+
return (is_usable ? hours : DEFAULT_MAX_HOURS) * MS_PER_HOUR
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const run_progress_args = { DEFAULT_MAX_HOURS, read_arguments, to_interval_ms, to_max_ms }
|
|
63
|
+
|
|
64
|
+
export type { ParsedValues }
|
|
65
|
+
export { run_progress_args }
|