@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,118 @@
|
|
|
1
|
+
// REST path construction for `gh api`, in one place.
|
|
2
|
+
//
|
|
3
|
+
// Every repository-scoped path starts with the same segment, and the same `repo ?? '{owner}/{repo}'`
|
|
4
|
+
// decision was already being spelled out per call site — in `git-gh-issue-read.ts`, and as a bare
|
|
5
|
+
// string concatenation in `git-gh-pr.ts` and `epic-cross-repo.ts`. All three now build their paths
|
|
6
|
+
// from here. Converting kit's GitHub calls to REST multiplies those call sites, so the decision is
|
|
7
|
+
// made once rather than at each one (joshuafolkken/kit#1023).
|
|
8
|
+
|
|
9
|
+
// One full page of a listing. REST answers 30 rows by default, and every listing this tooling reads
|
|
10
|
+
// is paged through with `--paginate`, so asking for the largest page turns a long listing into fewer
|
|
11
|
+
// round trips. Named once because three readers append it (joshuafolkken/kit#1028).
|
|
12
|
+
const FULL_PAGE_QUERY = '?per_page=100'
|
|
13
|
+
|
|
14
|
+
// `gh api` expands `{owner}` and `{repo}` from the current repository, so the unqualified form needs
|
|
15
|
+
// no extra lookup to name a path. An explicit `repo` names another repository — the form a
|
|
16
|
+
// cross-repository reference takes.
|
|
17
|
+
function repo_api_path(repo?: string): string {
|
|
18
|
+
return `repos/${repo ?? '{owner}/{repo}'}`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// The issue collection — what a listing pages through and what a creation posts to. One segment,
|
|
22
|
+
// named once: the reads, the listing and the writes all build on it (joshuafolkken/kit#1026).
|
|
23
|
+
function issues_api_path(repo?: string): string {
|
|
24
|
+
return `${repo_api_path(repo)}/issues`
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function issue_api_path(issue_number: string, repo?: string): string {
|
|
28
|
+
return `${issues_api_path(repo)}/${issue_number}`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// The dependency relations, which REST serves from their own endpoint rather than inside the issue.
|
|
32
|
+
// Named here because three call sites address it — the read in `git-gh-issue-read.ts` and both
|
|
33
|
+
// writes in `git-gh-issue-write.ts` (joshuafolkken/kit#1026).
|
|
34
|
+
function blocked_by_api_path(issue_number: string, repo?: string): string {
|
|
35
|
+
return `${issue_api_path(issue_number, repo)}/dependencies/blocked_by`
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// A pull request's *conversation* comments. REST serves them from the issue endpoint rather than the
|
|
39
|
+
// pull one — `pulls/{N}/comments` is the review thread, which is a different listing with a
|
|
40
|
+
// different shape, and reading one where the other was meant is a silent mistake rather than a 404
|
|
41
|
+
// (joshuafolkken/kit#1027).
|
|
42
|
+
function issue_comments_api_path(issue_number: string, repo?: string): string {
|
|
43
|
+
return `${issue_api_path(issue_number, repo)}/comments`
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// The pull request collection — what a branch lookup filters with `?head=<owner>:<branch>`.
|
|
47
|
+
function pulls_api_path(repo?: string): string {
|
|
48
|
+
return `${repo_api_path(repo)}/pulls`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// One pull request, addressed by number. `gh pr view` accepted a branch name and REST does not, so
|
|
52
|
+
// every read below the branch lookup names the number instead (joshuafolkken/kit#1027).
|
|
53
|
+
function pull_api_path(pr_number: string, repo?: string): string {
|
|
54
|
+
return `${pulls_api_path(repo)}/${pr_number}`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// The merge of one pull request. `gh pr merge <branch> --merge` is the GraphQL call this replaces,
|
|
58
|
+
// and the method it named is sent as the `merge_method` field of the request body rather than being
|
|
59
|
+
// left to the endpoint's default (joshuafolkken/kit#1029).
|
|
60
|
+
function pull_merge_api_path(pr_number: string, repo?: string): string {
|
|
61
|
+
return `${pull_api_path(pr_number, repo)}/merge`
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// The review thread — the line comments a reviewer left on the diff, which is what the CodeRabbit
|
|
65
|
+
// gate reads and is not the same listing as `issue_comments_api_path`.
|
|
66
|
+
function pull_comments_api_path(pr_number: string, repo?: string): string {
|
|
67
|
+
return `${pull_api_path(pr_number, repo)}/comments`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// The review history of one pull request. There is no REST counterpart to GraphQL's
|
|
71
|
+
// `reviewDecision`, so the merge gate folds this listing into one instead (joshuafolkken/kit#1028).
|
|
72
|
+
function pull_reviews_api_path(pr_number: string, repo?: string): string {
|
|
73
|
+
return `${pull_api_path(pr_number, repo)}/reviews`
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// One commit, addressed by SHA. The two halves of what `gh` merged into `statusCheckRollup` hang off
|
|
77
|
+
// it, and they are keyed by the pull request's *head* commit rather than by its number.
|
|
78
|
+
function commit_api_path(commit_sha: string, repo?: string): string {
|
|
79
|
+
return `${repo_api_path(repo)}/commits/${commit_sha}`
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// The check runs GitHub Actions and check-run apps post — the `CheckRun` half of the rollup.
|
|
83
|
+
function commit_check_runs_api_path(commit_sha: string, repo?: string): string {
|
|
84
|
+
return `${commit_api_path(commit_sha, repo)}/check-runs`
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// The combined commit status — the `StatusContext` half. A different endpoint with a different
|
|
88
|
+
// element shape (`state` / `context` rather than `status` / `conclusion` / `name`), which is why the
|
|
89
|
+
// two are merged by the caller rather than read as one listing.
|
|
90
|
+
function commit_status_api_path(commit_sha: string, repo?: string): string {
|
|
91
|
+
return `${commit_api_path(commit_sha, repo)}/status`
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// A single tag reference. REST answers 404 when the tag does not exist, which is the whole of the
|
|
95
|
+
// question the release command's tag watch asks (joshuafolkken/kit#1169).
|
|
96
|
+
function tag_reference_api_path(tag: string, repo?: string): string {
|
|
97
|
+
return `${repo_api_path(repo)}/git/ref/tags/${tag}`
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const git_gh_api_path = {
|
|
101
|
+
FULL_PAGE_QUERY,
|
|
102
|
+
repo_api_path,
|
|
103
|
+
tag_ref_api_path: tag_reference_api_path,
|
|
104
|
+
issues_api_path,
|
|
105
|
+
issue_api_path,
|
|
106
|
+
blocked_by_api_path,
|
|
107
|
+
issue_comments_api_path,
|
|
108
|
+
pulls_api_path,
|
|
109
|
+
pull_api_path,
|
|
110
|
+
pull_merge_api_path,
|
|
111
|
+
pull_comments_api_path,
|
|
112
|
+
pull_reviews_api_path,
|
|
113
|
+
commit_api_path,
|
|
114
|
+
commit_check_runs_api_path,
|
|
115
|
+
commit_status_api_path,
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export { git_gh_api_path, FULL_PAGE_QUERY }
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { execa } from 'execa'
|
|
2
|
+
|
|
3
|
+
const GH_NOT_INSTALLED_MSG = 'gh CLI is not installed. Install it from https://cli.github.com/'
|
|
4
|
+
|
|
5
|
+
const gh_check: { promise?: Promise<void> } = {}
|
|
6
|
+
|
|
7
|
+
async function run_gh_check(): Promise<void> {
|
|
8
|
+
try {
|
|
9
|
+
await execa('gh', ['--version'])
|
|
10
|
+
} catch {
|
|
11
|
+
delete gh_check.promise
|
|
12
|
+
throw new Error(GH_NOT_INSTALLED_MSG)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function check_gh_installed(): Promise<void> {
|
|
17
|
+
gh_check.promise ??= run_gh_check()
|
|
18
|
+
await gh_check.promise
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { check_gh_installed, GH_NOT_INSTALLED_MSG }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { git_gh_issue } from './git-gh-issue'
|
|
2
|
+
import { git_gh_pr } from './git-gh-pr'
|
|
3
|
+
import { git_gh_pr_auto_merge } from './git-gh-pr-auto-merge'
|
|
4
|
+
import { git_gh_repo } from './git-gh-repo'
|
|
5
|
+
import { git_pr_checks_watch } from './git-pr-checks-watch'
|
|
6
|
+
|
|
7
|
+
const git_gh_command = {
|
|
8
|
+
...git_gh_pr,
|
|
9
|
+
...git_gh_pr_auto_merge,
|
|
10
|
+
pr_checks_watch: git_pr_checks_watch.pr_checks_watch,
|
|
11
|
+
...git_gh_issue,
|
|
12
|
+
...git_gh_repo,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { git_gh_command }
|
|
16
|
+
export { parse_pr_state_string } from './git-gh-helpers'
|
|
17
|
+
export { PR_CHECKS_WATCH_TIMEOUT_MS } from './git-pr-checks-watch'
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { agent_session_environment } from '#scripts/josh/agent-session-environment'
|
|
2
|
+
import { execa, execaSync } from 'execa'
|
|
3
|
+
import { has_timed_out } from './git-execa-error'
|
|
4
|
+
import { check_gh_installed } from './git-gh-check'
|
|
5
|
+
import { gh_failure } from './git-gh-failure'
|
|
6
|
+
|
|
7
|
+
const BODY_FROM_STDIN = '-'
|
|
8
|
+
|
|
9
|
+
// The budget for **one** request through this layer, and the reason nothing here waits forever
|
|
10
|
+
// (joshuafolkken/kit#1065). Every GitHub access kit makes funnels through the four entries below, so
|
|
11
|
+
// until this existed a single hung `gh` held the caller open with no upper bound — most visibly in
|
|
12
|
+
// `josh propagate`, whose runner is single-threaded and processed no further consumer at all.
|
|
13
|
+
//
|
|
14
|
+
// **It is a request's budget, not a step's.** `STEP_TIMEOUT_MS` (30 minutes, `propagate-steps.ts`)
|
|
15
|
+
// covers a consumer's whole unit suite and a `pnpm add`; one REST call has no business borrowing
|
|
16
|
+
// that number. The value is read off what the callers actually do instead:
|
|
17
|
+
//
|
|
18
|
+
// - `CHECK_WAIT_INTERVAL_MS` is 10 seconds — the merge gate's poll cadence. A request still in
|
|
19
|
+
// flight six polls later is not slow, it is stuck.
|
|
20
|
+
// - `PR_CHECKS_WATCH_TIMEOUT_MS` is 120 seconds: `followup`'s look-ahead, which bounds its own
|
|
21
|
+
// *sleeps* rather than the wall clock, so each poll's requests sit on top of it. A request allowed
|
|
22
|
+
// to outlast that whole window would make the budget meaningless; half of it keeps one request
|
|
23
|
+
// from dominating the look-ahead.
|
|
24
|
+
// - kit's other `gh` spawns already sit at 5 seconds (`repo-setting.ts`) and 20
|
|
25
|
+
// (`propagate-publish.ts`, `epic-cross-repo.ts`). Sixty is deliberately the most generous of them,
|
|
26
|
+
// because this entry also serves `--paginate` requests — several HTTP round trips inside one
|
|
27
|
+
// spawn — which a 5-second budget would break.
|
|
28
|
+
//
|
|
29
|
+
// The aggregate is not what this bounds and must not be read as one: `followup` makes roughly 573
|
|
30
|
+
// requests across a 32-minute wait, and what caps that wait is its own attempt count. All this
|
|
31
|
+
// guarantees is that no single request holds it forever.
|
|
32
|
+
//
|
|
33
|
+
// **What a timed-out read costs its caller is decided by that caller, and two are worth naming.**
|
|
34
|
+
// In the merge gate's poll loop (`wait_for_pr_success`) it is one unreadable poll: the loop retries
|
|
35
|
+
// on its next interval and gives up on the third consecutive failure (joshuafolkken/kit#1077), so a
|
|
36
|
+
// timeout, a 403, a rate limit and a dropped connection all end the wait loudly rather than hanging
|
|
37
|
+
// or reading as a verdict, and re-running `followup` resumes it. In `followup`'s look-ahead it costs
|
|
38
|
+
// a log line: `handle_watch_failure` absorbs the error and falls through to the polling.
|
|
39
|
+
//
|
|
40
|
+
// **A timed-out *write* is not proof the write did not land.** The request may have reached GitHub
|
|
41
|
+
// before the spawn was killed, so a caller that retries one can duplicate it — `josh propagate`'s
|
|
42
|
+
// consumer issue is the case, and it reports the step as failed rather than retrying for exactly
|
|
43
|
+
// that reason. This is not new with the budget (a dropped connection has always had the property),
|
|
44
|
+
// but the budget makes it reachable on a healthy network, so it is written down here.
|
|
45
|
+
const GH_REQUEST_TIMEOUT_MS = 60_000
|
|
46
|
+
|
|
47
|
+
// **The override is a field on the request, not a second argument.** Every other knob on this layer
|
|
48
|
+
// — `method`, `body`, `should_paginate`, `should_slurp`, `jq_filter` — is already a field of
|
|
49
|
+
// `GhApiRequest`, and a budget is one more property of the request rather than of the call; putting
|
|
50
|
+
// it in a positional slot would be the only property of a request described somewhere else, and both
|
|
51
|
+
// `exec_gh_api` and `exec_gh_api_sync` would have to thread it separately. None of the ~27 REST call
|
|
52
|
+
// sites overrides it today, so a positional argument would buy no ergonomics it could spend.
|
|
53
|
+
//
|
|
54
|
+
// The two `gh`-command entries take it as a plain forwarded parameter instead: they have no call
|
|
55
|
+
// site outside this module — they exist as `exec_gh_api`'s transport — so there is no calling
|
|
56
|
+
// convention out there for them to keep consistent with.
|
|
57
|
+
function to_timeout_option(timeout_ms?: number): { timeout: number } {
|
|
58
|
+
return { timeout: timeout_ms ?? GH_REQUEST_TIMEOUT_MS }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// **`gh` dials GitHub directly, never through a proxy this machine stood up on loopback**
|
|
62
|
+
// (joshuafolkken/kit#2436). A package-manager wrapper writes one into the environment of everything
|
|
63
|
+
// its invocation spawns, and it exists to inspect package downloads — api.github.com crosses it
|
|
64
|
+
// without inspection, so the hop buys nothing and can fail on its own: measured on
|
|
65
|
+
// joshuafolkken/kit#2422, one 30-second stall made the wrapper refuse every later GitHub connection
|
|
66
|
+
// of that `followup`, and the retries in the poll loop could only ever fail. The loopback test and
|
|
67
|
+
// the list of spellings are the agent-session launcher's (joshuafolkken/kit#1760), shared rather than
|
|
68
|
+
// restated. Only the scanner's proxy goes — recognized by its CA — because any other loopback proxy
|
|
69
|
+
// may be this machine's only route out; a proxy naming a real host is somebody's network and stays.
|
|
70
|
+
// Nothing is spread when there is nothing to remove, so a spawn outside such a wrapper keeps its
|
|
71
|
+
// options exactly as they were.
|
|
72
|
+
//
|
|
73
|
+
// **It is exported because this file is not the only place `gh` is spawned.** The synchronous
|
|
74
|
+
// readers that spell their own `gh api` (`gh-spawn.ts`, `repo-setting.ts`, `epic-cross-repo.ts`,
|
|
75
|
+
// `version-remote.ts`, `propagate-publish.ts`) spread it too, and `git-gh-exec-proxy.test.ts` refuses
|
|
76
|
+
// a new `gh api` spawn anywhere under `scripts/` that does not.
|
|
77
|
+
interface DirectEnvironment {
|
|
78
|
+
env?: Record<string, undefined>
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function direct_environment(): DirectEnvironment {
|
|
82
|
+
const removed = agent_session_environment.removed_proxy_environment()
|
|
83
|
+
|
|
84
|
+
return Object.keys(removed).length > 0 ? { env: removed } : {}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function to_spawn_options(timeout_ms?: number): { timeout: number } & DirectEnvironment {
|
|
88
|
+
return { ...to_timeout_option(timeout_ms), ...direct_environment() }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// What a request that ran out of time is labelled with, ahead of whatever gh managed to write.
|
|
92
|
+
//
|
|
93
|
+
// The distinction is joshuafolkken/kit#1048's, on a new failure: "the server said no" and "nobody
|
|
94
|
+
// ever got an answer" are different diagnoses, and a timeout is the second. execa names it on the
|
|
95
|
+
// error it throws, and without the prefix a hang that had written a line to stderr first would
|
|
96
|
+
// arrive as that line — reported as whatever it happened to say instead of as a timeout.
|
|
97
|
+
const GH_REQUEST_TIMEOUT_MESSAGE = 'gh request timed out'
|
|
98
|
+
|
|
99
|
+
function has_stderr_field(error: unknown): error is Error & { stderr: string } {
|
|
100
|
+
return error instanceof Error && 'stderr' in error && typeof error.stderr === 'string'
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// execa attaches the captured output to the error it throws, which is where the status line lands
|
|
104
|
+
// when `gh api` exits non-zero — the case the whole probe exists for.
|
|
105
|
+
function has_stdout_field(error: unknown): error is Error & { stdout: string } {
|
|
106
|
+
return error instanceof Error && 'stdout' in error && typeof error.stdout === 'string'
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// `has_timed_out` is shared with the push transport rather than restated here: execa marks a spawn
|
|
110
|
+
// it killed the same way whichever binary was spawned, and `git push` gained a budget of its own in
|
|
111
|
+
// joshuafolkken/kit#1251.
|
|
112
|
+
function to_timeout_prefix(error: unknown): string {
|
|
113
|
+
return has_timed_out(error) ? `${GH_REQUEST_TIMEOUT_MESSAGE}: ` : ''
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function to_error_message(error: unknown): string {
|
|
117
|
+
return error instanceof Error ? error.message : String(error)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Surface the gh CLI's stderr as the thrown message when present (matching the previous spawn
|
|
121
|
+
// behavior), otherwise fall back to execa's own message — **and append what gh wrote to stdout**.
|
|
122
|
+
//
|
|
123
|
+
// The append is not cosmetic. `gh api` splits a failed request across both streams: stderr carries
|
|
124
|
+
// one summary line (`gh: Validation Failed (HTTP 422)`) and **stdout carries the JSON error body**,
|
|
125
|
+
// which is the only place the reason is written. Every caller here is now a REST request, so
|
|
126
|
+
// dropping stdout dropped the diagnosis from every REST failure — and `handle_pr_create_error`
|
|
127
|
+
// reads the reason: a duplicate pull request is `A pull request already exists for <owner>:<branch>.`
|
|
128
|
+
// inside that body, and matching it against stderr alone answers no (measured on
|
|
129
|
+
// joshuafolkken/kit#1029).
|
|
130
|
+
//
|
|
131
|
+
// The same stdout is what carries the request's own failure nature, so the classification is
|
|
132
|
+
// attached here rather than reconstructed by a later probe: GitHub's error document names its status
|
|
133
|
+
// and a request that never arrived wrote no document at all (joshuafolkken/kit#1690).
|
|
134
|
+
function to_gh_error(error: unknown): Error {
|
|
135
|
+
const stderr = has_stderr_field(error) ? error.stderr.trim() : ''
|
|
136
|
+
const stdout = has_stdout_field(error) ? error.stdout.trim() : ''
|
|
137
|
+
const summary = stderr.length > 0 ? stderr : to_error_message(error)
|
|
138
|
+
const detail = stdout.length > 0 ? `${summary}\n${stdout}` : summary
|
|
139
|
+
|
|
140
|
+
return gh_failure.attach(
|
|
141
|
+
new Error(`${to_timeout_prefix(error)}${detail}`, { cause: error }),
|
|
142
|
+
gh_failure.classify_stdout(stdout),
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function exec_gh_command(arguments_: Array<string>, timeout_ms?: number): Promise<string> {
|
|
147
|
+
await check_gh_installed()
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const { stdout } = await execa('gh', arguments_, to_spawn_options(timeout_ms)) // NOSONAR S8705: execa array args (no shell), trusted dev CLI tooling
|
|
151
|
+
|
|
152
|
+
return stdout.trimEnd()
|
|
153
|
+
} catch (error) {
|
|
154
|
+
throw to_gh_error(error)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function exec_gh_command_with_stdin(input: {
|
|
159
|
+
args: Array<string>
|
|
160
|
+
stdin_body: string
|
|
161
|
+
// `number | undefined` rather than plain optional: `exec_gh_api` forwards its own optional field,
|
|
162
|
+
// which `exactOptionalPropertyTypes` will not narrow for it.
|
|
163
|
+
timeout_ms?: number | undefined
|
|
164
|
+
}): Promise<string> {
|
|
165
|
+
await check_gh_installed()
|
|
166
|
+
|
|
167
|
+
// Built ahead of the call so the spawn itself stays on one line: `// NOSONAR` suppresses the rule
|
|
168
|
+
// only on the line it sits on, and a wrapped call moves that line away from the reported one.
|
|
169
|
+
const options = { input: input.stdin_body, ...to_spawn_options(input.timeout_ms) }
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
const { stdout } = await execa('gh', input.args, options) // NOSONAR S8705: execa array args (no shell), trusted dev CLI tooling
|
|
173
|
+
|
|
174
|
+
return stdout.trimEnd()
|
|
175
|
+
} catch (error) {
|
|
176
|
+
throw to_gh_error(error)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// The status line `gh api --include` prints before the headers, e.g. `HTTP/2.0 404 Not Found`.
|
|
181
|
+
const STATUS_LINE_PATTERN = /^HTTP\/[\d.]+ (?<status>\d{3})\b/u
|
|
182
|
+
|
|
183
|
+
function parse_status_line(output: string): number | undefined {
|
|
184
|
+
const { status } = STATUS_LINE_PATTERN.exec(output)?.groups ?? {}
|
|
185
|
+
|
|
186
|
+
return status === undefined ? undefined : Number(status)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// The HTTP status of one `gh api` request, read from the status line rather than from `gh`'s error
|
|
190
|
+
// text. A message is prose that can be reworded between releases; the status code is the protocol,
|
|
191
|
+
// so a caller distinguishing "there is nothing at that number" (404) from "the read failed" (403,
|
|
192
|
+
// 429, 5xx) is matching a contract instead of a string (joshuafolkken/kit#957).
|
|
193
|
+
//
|
|
194
|
+
// `--silent` drops the response body, so only the headers are parsed; `--include` keeps them even
|
|
195
|
+
// when the request failed, and execa carries that output on the error it throws. `undefined` means
|
|
196
|
+
// no status was reached at all — gh missing, a dropped connection — which is itself a failed read.
|
|
197
|
+
//
|
|
198
|
+
// **The fifth spawn in this file, and guarded like the other four** (joshuafolkken/kit#1065). It is
|
|
199
|
+
// not one of the entries joshuafolkken/kit#1065 enumerated, and that is exactly why it is included:
|
|
200
|
+
// leaving one unbounded `gh` spawn beside four bounded ones is the inconsistency that Issue argues
|
|
201
|
+
// against, in the same file. Its contract is unchanged — a timeout reaches the `catch` and answers
|
|
202
|
+
// `undefined`, which already means "no status was reached", which its one caller already reads as a
|
|
203
|
+
// failed read rather than as a 404.
|
|
204
|
+
async function exec_gh_api_status(path: string, timeout_ms?: number): Promise<number | undefined> {
|
|
205
|
+
// Hoisted so the spawn below fits on one line, which `// NOSONAR` requires — it suppresses only
|
|
206
|
+
// the line it sits on. The **argument list** stays an inline literal for the opposite reason:
|
|
207
|
+
// `gh-subcommand-guard.ts` resolves the subcommand from it, and hoisting that into a `const`
|
|
208
|
+
// makes the scan report `<dynamic>` instead of `api`, leaving a future edit to
|
|
209
|
+
// `['issue', 'view', …]` uncaught (joshuafolkken/kit#1063).
|
|
210
|
+
const options = to_spawn_options(timeout_ms)
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
await check_gh_installed()
|
|
214
|
+
const { stdout } = await execa('gh', ['api', '--include', '--silent', path], options) // NOSONAR S8705: execa array args (no shell), trusted dev CLI tooling
|
|
215
|
+
|
|
216
|
+
return parse_status_line(stdout)
|
|
217
|
+
} catch (error) {
|
|
218
|
+
return has_stdout_field(error) ? parse_status_line(error.stdout) : undefined
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const METHOD_FLAG = '--method'
|
|
223
|
+
const INPUT_FLAG = '--input'
|
|
224
|
+
const PAGINATE_FLAG = '--paginate'
|
|
225
|
+
const SLURP_FLAG = '--slurp'
|
|
226
|
+
const JQ_FLAG = '--jq'
|
|
227
|
+
|
|
228
|
+
// One REST request through `gh api`. `path` is the only required field: a read names nothing else,
|
|
229
|
+
// because `gh api` sends GET when neither `--method` nor a request body is given. **A `body` alone
|
|
230
|
+
// is not a read** — gh promotes a request carrying `--input` to POST — so a caller that means to
|
|
231
|
+
// send a body under another verb has to say `method` as well.
|
|
232
|
+
//
|
|
233
|
+
// `body` is handed to gh on stdin (`--input -`) rather than as a file or as repeated `-f key=value`
|
|
234
|
+
// pairs — a JSON body then needs no temporary file and no per-field escaping. `jq_filter` unwraps
|
|
235
|
+
// one value out of the response, so a caller wanting a single field gets the value rather than an
|
|
236
|
+
// object to parse.
|
|
237
|
+
//
|
|
238
|
+
// `should_slurp` goes with `should_paginate`, and **which endpoints need it is the whole point**:
|
|
239
|
+
// gh merges the pages of an endpoint that answers a bare JSON *array* into one array, so a paged
|
|
240
|
+
// comment listing arrives already parseable and must NOT slurp — `--slurp` would wrap it as
|
|
241
|
+
// `[[…],[…]]`, which every array schema then rejects. An endpoint answering an *object* is the case
|
|
242
|
+
// this field exists for: `--paginate` alone emits one document per page, so a two-page response
|
|
243
|
+
// arrives as `{…}{…}`, which `JSON.parse` rejects, and `--slurp` wraps those pages in one outer
|
|
244
|
+
// array instead. It is a separate field rather than implied by `should_paginate` for that reason,
|
|
245
|
+
// and because gh refuses it alongside `--jq` (joshuafolkken/kit#1027).
|
|
246
|
+
interface GhApiRequest {
|
|
247
|
+
path: string
|
|
248
|
+
method?: string
|
|
249
|
+
body?: string
|
|
250
|
+
should_paginate?: boolean
|
|
251
|
+
should_slurp?: boolean
|
|
252
|
+
jq_filter?: string
|
|
253
|
+
// The budget for this one request, overriding `GH_REQUEST_TIMEOUT_MS`. A field rather than a
|
|
254
|
+
// second argument for the reason recorded beside that constant (joshuafolkken/kit#1065).
|
|
255
|
+
timeout_ms?: number
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function optional_flag(flag: string, value?: string): Array<string> {
|
|
259
|
+
return value === undefined ? [] : [flag, value]
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function to_gh_api_args(request: GhApiRequest): Array<string> {
|
|
263
|
+
const body_args = request.body === undefined ? [] : [INPUT_FLAG, BODY_FROM_STDIN]
|
|
264
|
+
const paginate_args = request.should_paginate === true ? [PAGINATE_FLAG] : []
|
|
265
|
+
const slurp_args = request.should_slurp === true ? [SLURP_FLAG] : []
|
|
266
|
+
|
|
267
|
+
return [
|
|
268
|
+
'api',
|
|
269
|
+
request.path,
|
|
270
|
+
...optional_flag(METHOD_FLAG, request.method),
|
|
271
|
+
...body_args,
|
|
272
|
+
...paginate_args,
|
|
273
|
+
...slurp_args,
|
|
274
|
+
...optional_flag(JQ_FLAG, request.jq_filter),
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// The response body of one `gh api` request, as text. Every REST caller that can await one goes
|
|
279
|
+
// through it, so the verb, the body and the paging stop being spelled out per call site
|
|
280
|
+
// (joshuafolkken/kit#1023). The synchronous readers that cannot — `gh-spawn.ts`, `epic-cross-repo.ts`
|
|
281
|
+
// — still share its path builder.
|
|
282
|
+
//
|
|
283
|
+
// Failure handling funnels through `to_gh_error` on both paths below, so a failed request throws
|
|
284
|
+
// with gh's stderr summary *and* the JSON error body it wrote to stdout.
|
|
285
|
+
async function exec_gh_api(request: GhApiRequest): Promise<string> {
|
|
286
|
+
const args = to_gh_api_args(request)
|
|
287
|
+
|
|
288
|
+
if (request.body === undefined) return await exec_gh_command(args, request.timeout_ms)
|
|
289
|
+
|
|
290
|
+
return await exec_gh_command_with_stdin({
|
|
291
|
+
args,
|
|
292
|
+
stdin_body: request.body,
|
|
293
|
+
timeout_ms: request.timeout_ms,
|
|
294
|
+
})
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// The synchronous twin of `exec_gh_api`, for a caller that cannot await. `josh propagate` runs each
|
|
298
|
+
// consumer's steps as a sequential chain of `execaSync` spawns with inherited stdio, and that shape
|
|
299
|
+
// reaches from `open_issue` up through `RunStep`, `run_target` and `run_targets` — so the issue it
|
|
300
|
+
// opens in the consumer is created here rather than by turning the whole runner asynchronous for
|
|
301
|
+
// one request (joshuafolkken/kit#1042).
|
|
302
|
+
//
|
|
303
|
+
// It is the **write** side's synchronous entry, and the only one so far. The synchronous *readers*
|
|
304
|
+
// named above `exec_gh_api` — `gh-spawn.ts`, `epic-cross-repo.ts`, `repo-setting.ts`,
|
|
305
|
+
// `propagate-publish.ts`, `version-remote.ts` — each spell their own `['api', path, '--jq', …]` out
|
|
306
|
+
// and share only the path builder; a read has no body and no verb to get wrong, which is why they
|
|
307
|
+
// were left as they are rather than migrated here in passing.
|
|
308
|
+
//
|
|
309
|
+
// **It is the same layer, not a second one.** The argument builder and the error translation are
|
|
310
|
+
// shared with the asynchronous path above, so `--input -` for the body, `--jq` for the unwrap, and
|
|
311
|
+
// the failure text that carries the JSON reason REST writes to stdout are each defined once.
|
|
312
|
+
//
|
|
313
|
+
// The body travels over stdin here too: `execaSync` accepts `input`, so multi-line markdown depends
|
|
314
|
+
// on no shell quoting — the same property `exec_gh_command_with_stdin` gives the asynchronous path.
|
|
315
|
+
//
|
|
316
|
+
// `check_gh_installed` is the one thing it cannot share, because it awaits. A missing gh surfaces as
|
|
317
|
+
// the spawn's own failure and is reported like any other, which is what the direct spawn this
|
|
318
|
+
// replaced already did.
|
|
319
|
+
function exec_gh_api_sync(request: GhApiRequest): string {
|
|
320
|
+
const body_option = request.body === undefined ? {} : { input: request.body }
|
|
321
|
+
const options = { ...body_option, ...to_spawn_options(request.timeout_ms) }
|
|
322
|
+
|
|
323
|
+
try {
|
|
324
|
+
const { stdout } = execaSync('gh', to_gh_api_args(request), options) // NOSONAR S8705: execa array args (no shell), trusted dev CLI tooling
|
|
325
|
+
|
|
326
|
+
return stdout.trimEnd()
|
|
327
|
+
} catch (error) {
|
|
328
|
+
throw to_gh_error(error)
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const git_gh_exec = {
|
|
333
|
+
direct_environment,
|
|
334
|
+
exec_gh_command,
|
|
335
|
+
exec_gh_command_with_stdin,
|
|
336
|
+
exec_gh_api,
|
|
337
|
+
exec_gh_api_sync,
|
|
338
|
+
exec_gh_api_status,
|
|
339
|
+
parse_status_line,
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export type { GhApiRequest }
|
|
343
|
+
export { git_gh_exec, has_stderr_field, has_stdout_field }
|
|
344
|
+
export { BODY_FROM_STDIN, GH_REQUEST_TIMEOUT_MESSAGE, GH_REQUEST_TIMEOUT_MS }
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { parse_json } from './parse-json-array'
|
|
3
|
+
|
|
4
|
+
// Why one `gh api` request failed, taken from **that request** rather than from a later probe
|
|
5
|
+
// (joshuafolkken/kit#1690).
|
|
6
|
+
//
|
|
7
|
+
// joshuafolkken/kit#957 asked the same question by issuing a second request — `exec_gh_api_status`
|
|
8
|
+
// against the same path — and joshuafolkken/kit#1663 asked it again with a reachability probe fired
|
|
9
|
+
// after the answer was otherwise final. Both are inferences about a request that is already over: a
|
|
10
|
+
// connection that dropped for three hundred milliseconds fails the read and answers the probe
|
|
11
|
+
// `reachable`, so the failure keeps the meaning the probe gave it and not the one it had.
|
|
12
|
+
//
|
|
13
|
+
// The nature is available on the failed request itself, and structurally rather than by wording:
|
|
14
|
+
// `gh api` writes the **response body** to stdout, and GitHub's REST error document carries its own
|
|
15
|
+
// status — `{"message":"Not Found","documentation_url":…,"status":"404"}`. A request that never
|
|
16
|
+
// reached GitHub has no response body at all, so stdout is empty. That is the whole classification,
|
|
17
|
+
// and neither half reads gh's stderr prose, which is what joshuafolkken/kit#1024 refused to key on.
|
|
18
|
+
|
|
19
|
+
// GitHub's REST error document. Only the status is read: `message` and `documentation_url` are prose
|
|
20
|
+
// for a person, and every other field varies by endpoint.
|
|
21
|
+
//
|
|
22
|
+
// The status arrives as a string (`"404"`), and a number is accepted beside it so that a future
|
|
23
|
+
// serialization of the same field is read rather than dropped.
|
|
24
|
+
//
|
|
25
|
+
// `.catch({})` because anything at all can arrive on this path — an HTML error page from a proxy, a
|
|
26
|
+
// JSON array, a bare `null`. A schema that threw there would turn "the response was not GitHub's
|
|
27
|
+
// error document" into an exception the caller has to catch a second time, when the honest answer is
|
|
28
|
+
// simply that no status was reported.
|
|
29
|
+
const error_document_schema = z
|
|
30
|
+
.object({ status: z.union([z.string(), z.number()]).optional() })
|
|
31
|
+
.catch({})
|
|
32
|
+
|
|
33
|
+
// What a failed `gh api` request said about itself.
|
|
34
|
+
interface GhFailure {
|
|
35
|
+
// The HTTP status GitHub reported in the error document it wrote. `undefined` is the transport
|
|
36
|
+
// case: nothing answered, so there is no status to report — deliberately the same shape
|
|
37
|
+
// `exec_gh_api_status` already answers `undefined` for, so `gh_reachability.classify_status` reads
|
|
38
|
+
// this without a second spelling of the rule.
|
|
39
|
+
status: number | undefined
|
|
40
|
+
// Whether the request that failed came *after* one that had already succeeded — a second endpoint
|
|
41
|
+
// for a related resource, reached only because the first answered. Such a request fails about
|
|
42
|
+
// itself, so its 404 says nothing about whether the subject exists: an issue read whose blocker
|
|
43
|
+
// relations then 404 on a host without that endpoint is a readable issue, not a missing one. Only
|
|
44
|
+
// the caller knows which of its requests was which, so it is the caller that sets this
|
|
45
|
+
// (joshuafolkken/kit#1690).
|
|
46
|
+
is_followup?: boolean
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Attached to the thrown `Error` rather than expressed as an `Error` subclass, matching
|
|
50
|
+
// `has_stderr_field` / `has_stdout_field` in `git-gh-exec.ts`: every failure in `scripts/` is a bare
|
|
51
|
+
// `Error` distinguished by a field, and one subclass among them would be a second convention.
|
|
52
|
+
const GH_FAILURE_FIELD = 'gh_failure'
|
|
53
|
+
|
|
54
|
+
function has_gh_failure(error: unknown): error is Error & { gh_failure: GhFailure } {
|
|
55
|
+
return error instanceof Error && Object.hasOwn(error, GH_FAILURE_FIELD)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The status GitHub itself reported, or `undefined` when the request produced no response body.
|
|
59
|
+
//
|
|
60
|
+
// A body that is not GitHub's error document — an HTML error page from a proxy, a truncated
|
|
61
|
+
// response — answers `undefined` as well. That is the honest answer: something came back, but
|
|
62
|
+
// nothing in it says what the status was, and guessing one would be the inference this module
|
|
63
|
+
// exists to remove.
|
|
64
|
+
function parse_response_status(stdout: string): number | undefined {
|
|
65
|
+
const document = parse_json.parse_json_object_safe(stdout, error_document_schema)
|
|
66
|
+
if (document?.status === undefined) return undefined
|
|
67
|
+
const status = Number(document.status)
|
|
68
|
+
|
|
69
|
+
return Number.isSafeInteger(status) ? status : undefined
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// The classification, from the failed request's own stdout.
|
|
73
|
+
function classify_stdout(stdout: string): GhFailure {
|
|
74
|
+
return { status: parse_response_status(stdout) }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Put the classification on the error the caller will catch, so the nature travels with the throw
|
|
78
|
+
// instead of being reconstructed from it.
|
|
79
|
+
//
|
|
80
|
+
// **Non-enumerable deliberately.** An error is compared, logged and serialized all over this project
|
|
81
|
+
// — `expect(...).rejects.toThrow(new Error(text))` compares own enumerable properties — and an
|
|
82
|
+
// annotation nobody asked for must not change what any of those see. `in` finds it regardless.
|
|
83
|
+
function attach<T extends Error>(error: T, failure: GhFailure): T {
|
|
84
|
+
Object.defineProperty(error, GH_FAILURE_FIELD, {
|
|
85
|
+
value: failure,
|
|
86
|
+
enumerable: false,
|
|
87
|
+
configurable: true,
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
return error
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// What a caught error said about the request that produced it, or `undefined` when it did not come
|
|
94
|
+
// from a `gh api` request at all — a parse or a schema rejection, which is a read that arrived and
|
|
95
|
+
// could not be used.
|
|
96
|
+
function failure_of(error: unknown): GhFailure | undefined {
|
|
97
|
+
return has_gh_failure(error) ? error.gh_failure : undefined
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const gh_failure = { attach, classify_stdout, failure_of, parse_response_status }
|
|
101
|
+
|
|
102
|
+
export type { GhFailure }
|
|
103
|
+
export { gh_failure, GH_FAILURE_FIELD }
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { has_stderr_field } from './git-gh-exec'
|
|
2
|
+
|
|
3
|
+
// One optional string answer from `gh`. Every caller asks with `--jq`, which unwraps the JSON
|
|
4
|
+
// string itself, so the value arrives raw and there is nothing to unquote — this used to strip a
|
|
5
|
+
// leading and trailing `"` anyway, which ate real characters from any answer that legitimately
|
|
6
|
+
// carried them. A title of `"queue" should stop at the first failure` reached Telegram as
|
|
7
|
+
// `queue" should stop at the first failure` (joshuafolkken/kit#993). Trimming and the empty answer
|
|
8
|
+
// are the whole contract.
|
|
9
|
+
function parse_pr_state_string(result: string): string | undefined {
|
|
10
|
+
const trimmed = result.trim()
|
|
11
|
+
|
|
12
|
+
return trimmed.length > 0 ? trimmed : undefined
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function is_pr_already_exists_message(error_message: string): boolean {
|
|
16
|
+
return error_message.toLowerCase().includes('already exists')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function get_error_message_with_stderr(error: unknown): string {
|
|
20
|
+
if (!(error instanceof Error)) return String(error)
|
|
21
|
+
|
|
22
|
+
if (has_stderr_field(error) && error.stderr.length > 0) return `${error.message}\n${error.stderr}`
|
|
23
|
+
|
|
24
|
+
return error.message
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function handle_pr_create_error(error: unknown): never {
|
|
28
|
+
const error_message = get_error_message_with_stderr(error)
|
|
29
|
+
|
|
30
|
+
if (is_pr_already_exists_message(error_message)) {
|
|
31
|
+
throw new Error('PR_ALREADY_EXISTS')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
throw error
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const git_gh_helpers = {
|
|
38
|
+
parse_pr_state_string,
|
|
39
|
+
is_pr_already_exists_message,
|
|
40
|
+
get_error_message_with_stderr,
|
|
41
|
+
handle_pr_create_error,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { git_gh_helpers, parse_pr_state_string }
|