@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,134 @@
|
|
|
1
|
+
import { git_spawn } from './git-spawn'
|
|
2
|
+
|
|
3
|
+
// What `josh main:merge` refuses before it merges, and what it tells the run to do instead
|
|
4
|
+
// (joshuafolkken/kit#2445).
|
|
5
|
+
//
|
|
6
|
+
// **A dirty tree is not refused as such.** The chain runs `main:merge` before the commit, over the
|
|
7
|
+
// uncommitted implementation, and git carries uncommitted changes through a merge that touches none of
|
|
8
|
+
// them. What goes wrong is the two states git itself cannot merge over — a path both sides changed, and
|
|
9
|
+
// an index still holding unresolved paths. Git's own refusal there names no way forward, and the way a
|
|
10
|
+
// lane child found was a stash round trip around the merge, whose reapply left `UU` in the index and a
|
|
11
|
+
// run asking a person for `git add`. The refusal here is the same condition with the sanctioned way out.
|
|
12
|
+
|
|
13
|
+
// `XY <path>` — two status letters and a space before the path.
|
|
14
|
+
const STATUS_CODE_LENGTH = 2
|
|
15
|
+
const STATUS_PREFIX_LENGTH = STATUS_CODE_LENGTH + 1
|
|
16
|
+
const RENAME_SEPARATOR = ' -> '
|
|
17
|
+
const UNMERGED_CODES = new Set(['DD', 'AU', 'UD', 'UA', 'DU', 'AA', 'UU'])
|
|
18
|
+
// The index column of a line whose path has nothing staged — unchanged, untracked, or ignored.
|
|
19
|
+
const UNSTAGED_INDEX_CODES = new Set([' ', '?', '!'])
|
|
20
|
+
const DIRECTORY_SUFFIX = '/'
|
|
21
|
+
const COMMIT_COMMAND = '`pnpm josh git -y`'
|
|
22
|
+
const PROCEDURE_POINTER =
|
|
23
|
+
'`.claude/skills/workflow-commands/chain-rule.md` → "origin/main is merged in before the gate"'
|
|
24
|
+
|
|
25
|
+
function status_lines(status: string): Array<string> {
|
|
26
|
+
return status.split('\n').filter((line) => line.length > STATUS_PREFIX_LENGTH)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// A rename line names both sides; either one is a path the merge could collide with.
|
|
30
|
+
function line_paths(line: string): Array<string> {
|
|
31
|
+
return line.slice(STATUS_PREFIX_LENGTH).split(RENAME_SEPARATOR)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function unmerged_paths(status: string): Array<string> {
|
|
35
|
+
return status_lines(status)
|
|
36
|
+
.filter((line) => UNMERGED_CODES.has(line.slice(0, STATUS_CODE_LENGTH)))
|
|
37
|
+
.flatMap((line) => line_paths(line))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Git's ort strategy refuses a merge whenever the index differs from HEAD, whatever paths the staged
|
|
41
|
+
// changes touch — a stash reapply that conflicted leaves its merged half staged in exactly this way.
|
|
42
|
+
function staged_paths(status: string): Array<string> {
|
|
43
|
+
return status_lines(status)
|
|
44
|
+
.filter((line) => !UNSTAGED_INDEX_CODES.has(line.charAt(0)))
|
|
45
|
+
.flatMap((line) => line_paths(line))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// An untracked directory is reported as `dir/`, so it covers every incoming path beneath it.
|
|
49
|
+
function covers(uncommitted: string, incoming: string): boolean {
|
|
50
|
+
if (uncommitted.endsWith(DIRECTORY_SUFFIX)) return incoming.startsWith(uncommitted)
|
|
51
|
+
|
|
52
|
+
return uncommitted === incoming
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function overlapping_paths(status: string, incoming: ReadonlyArray<string>): Array<string> {
|
|
56
|
+
const uncommitted = status_lines(status).flatMap((line) => line_paths(line))
|
|
57
|
+
|
|
58
|
+
return uncommitted.filter((path) => incoming.some((changed) => covers(path, changed)))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function unmerged_message(paths: ReadonlyArray<string>): string {
|
|
62
|
+
return (
|
|
63
|
+
`main:merge: the index still holds unresolved paths (${paths.join(', ')}). Remove the conflict ` +
|
|
64
|
+
`markers, then finish through ${COMMIT_COMMAND} — it stages and commits them, so no \`git add\` ` +
|
|
65
|
+
`permission is needed, and inside a lane this is Tier A. Rerun \`pnpm josh main:merge\` after it ` +
|
|
66
|
+
`(${PROCEDURE_POINTER}).`
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function staged_message(paths: ReadonlyArray<string>): string {
|
|
71
|
+
return (
|
|
72
|
+
`main:merge: the index holds staged changes (${paths.join(', ')}), which git refuses to merge ` +
|
|
73
|
+
`over. Commit them first through ${COMMIT_COMMAND}, then rerun \`pnpm josh main:merge\` ` +
|
|
74
|
+
`(${PROCEDURE_POINTER}).`
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function overlap_message(default_branch: string, paths: ReadonlyArray<string>): string {
|
|
79
|
+
return (
|
|
80
|
+
`main:merge: uncommitted changes touch files origin/${default_branch} also changed ` +
|
|
81
|
+
`(${paths.join(', ')}). Commit the work first through ${COMMIT_COMMAND}, then rerun ` +
|
|
82
|
+
`\`pnpm josh main:merge\`. Never stash around the merge — a stash reapplied over it leaves the ` +
|
|
83
|
+
`conflict half-recorded in the index (${PROCEDURE_POINTER}).`
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Appended to git's own report when the merge itself stops on a conflict.
|
|
88
|
+
const CONFLICT_HINT =
|
|
89
|
+
`main:merge: finish a conflicted merge by removing the conflict markers, then ${COMMIT_COMMAND} ` +
|
|
90
|
+
`records the merge commit — no \`git add\` permission is needed (${PROCEDURE_POINTER}).`
|
|
91
|
+
|
|
92
|
+
function refusal(
|
|
93
|
+
status: string,
|
|
94
|
+
incoming: ReadonlyArray<string>,
|
|
95
|
+
default_branch: string,
|
|
96
|
+
): string | undefined {
|
|
97
|
+
const unmerged = unmerged_paths(status)
|
|
98
|
+
|
|
99
|
+
if (unmerged.length > 0) return unmerged_message(unmerged)
|
|
100
|
+
// Nothing incoming means git answers "Already up to date" whatever the index holds.
|
|
101
|
+
if (incoming.length === 0) return undefined
|
|
102
|
+
|
|
103
|
+
const staged = staged_paths(status)
|
|
104
|
+
|
|
105
|
+
if (staged.length > 0) return staged_message(staged)
|
|
106
|
+
|
|
107
|
+
const overlap = overlapping_paths(status, incoming)
|
|
108
|
+
|
|
109
|
+
return overlap.length > 0 ? overlap_message(default_branch, overlap) : undefined
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// The paths the default branch changed since this branch left it — what the merge would bring in.
|
|
113
|
+
// `--no-renames` lists both sides of a rename, so an edit to the old name still counts as an overlap.
|
|
114
|
+
async function incoming_paths(default_branch: string): Promise<Array<string>> {
|
|
115
|
+
const output = await git_spawn.read([
|
|
116
|
+
'diff',
|
|
117
|
+
'--name-only',
|
|
118
|
+
'--no-renames',
|
|
119
|
+
`HEAD...origin/${default_branch}`,
|
|
120
|
+
])
|
|
121
|
+
|
|
122
|
+
return output.split('\n').filter((line) => line !== '')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const main_merge_guard = {
|
|
126
|
+
CONFLICT_HINT,
|
|
127
|
+
incoming_paths,
|
|
128
|
+
overlapping_paths,
|
|
129
|
+
refusal,
|
|
130
|
+
staged_paths,
|
|
131
|
+
unmerged_paths,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { main_merge_guard }
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { extract_issue_number } from '#scripts/hooks/check-commit-message'
|
|
4
|
+
import { composite_arguments, USAGE_ERROR_EXIT_CODE } from '#scripts/josh/josh-composite-arguments'
|
|
5
|
+
import { git_command } from './git-command'
|
|
6
|
+
import { main_merge_guard } from './main-merge-guard'
|
|
7
|
+
|
|
8
|
+
// `josh main:merge` (`josh mm`) — bring the default branch into the branch this checkout is on
|
|
9
|
+
// (joshuafolkken/kit#1659).
|
|
10
|
+
//
|
|
11
|
+
// **It stopped being a `git pull` because `git pull` cannot decide anything on a diverged branch.**
|
|
12
|
+
// With neither `pull.rebase` nor `pull.ff` set — the state of a checkout nobody has configured — git
|
|
13
|
+
// refuses the moment the two sides have each moved:
|
|
14
|
+
//
|
|
15
|
+
// fatal: Need to specify how to reconcile divergent branches
|
|
16
|
+
//
|
|
17
|
+
// Divergence is not the edge case here; it is the entire reason to type this command. A lane whose
|
|
18
|
+
// branch has fallen behind `origin/<default>` has its own commits on it by definition, so **the one
|
|
19
|
+
// state the command exists for was the one state it could not run in.**
|
|
20
|
+
//
|
|
21
|
+
// The strategy is therefore named by this file rather than read out of whoever's git configuration
|
|
22
|
+
// happens to be in force: **fetch, then merge `origin/<default>` into the current branch.** Merging
|
|
23
|
+
// rather than rebasing is joshuafolkken/kit#1446's decision and not a fresh one — a rebase rewrites
|
|
24
|
+
// commits that are already pushed, so it needs a force push, which `.claude/settings.json` denies.
|
|
25
|
+
//
|
|
26
|
+
// `git_command.merge_fast_forward` is deliberately not reused: it passes `--ff-only`, which fails
|
|
27
|
+
// loudly on exactly the divergence this command has to absorb.
|
|
28
|
+
|
|
29
|
+
const SUCCESS_EXIT_CODE = 0
|
|
30
|
+
const FAILURE_EXIT_CODE = 1
|
|
31
|
+
const ARGV_OFFSET = 2
|
|
32
|
+
const COMMAND_NAME = 'main:merge'
|
|
33
|
+
|
|
34
|
+
// git's default merge message carries no `#N`, so on an issue branch the `commit-msg` hook refuses
|
|
35
|
+
// it and leaves the index mid-merge (joshuafolkken/kit#2439). The number is read with the hook's
|
|
36
|
+
// own parser, so the message this writes is exactly the one that hook accepts; a branch without a
|
|
37
|
+
// number keeps git's default.
|
|
38
|
+
function merge_message(default_branch: string, current_branch: string): string | undefined {
|
|
39
|
+
const issue_number = extract_issue_number(current_branch)
|
|
40
|
+
|
|
41
|
+
if (issue_number === undefined) return undefined
|
|
42
|
+
|
|
43
|
+
return `Merge ${default_branch} into ${current_branch} #${issue_number}`
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// The refusal is read after the fetch, so the incoming paths are the ones the merge would bring in
|
|
47
|
+
// (joshuafolkken/kit#2445).
|
|
48
|
+
async function merge_refusal(default_branch: string): Promise<string | undefined> {
|
|
49
|
+
const status = await git_command.status()
|
|
50
|
+
const incoming = await main_merge_guard.incoming_paths(default_branch)
|
|
51
|
+
|
|
52
|
+
return main_merge_guard.refusal(status, incoming, default_branch)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// A merge that stops on a conflict keeps git's report and adds how to finish it, so the next step is
|
|
56
|
+
// the sanctioned commit rather than a request for `git add`.
|
|
57
|
+
async function merge_with_hint(default_branch: string, message: string | undefined): Promise<void> {
|
|
58
|
+
try {
|
|
59
|
+
await git_command.merge_branch(default_branch, message)
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error(main_merge_guard.CONFLICT_HINT)
|
|
62
|
+
throw error
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// The fetch is what makes `origin/<default>` current before the merge reads it. `git pull` did the
|
|
67
|
+
// two together, which is the only thing it was doing here that is worth keeping.
|
|
68
|
+
async function merge_default_branch(): Promise<number> {
|
|
69
|
+
const default_branch = await git_command.get_default_branch()
|
|
70
|
+
const current_branch = await git_command.branch()
|
|
71
|
+
|
|
72
|
+
await git_command.fetch_branch(default_branch)
|
|
73
|
+
|
|
74
|
+
const refusal = await merge_refusal(default_branch)
|
|
75
|
+
|
|
76
|
+
if (refusal !== undefined) {
|
|
77
|
+
console.error(refusal)
|
|
78
|
+
|
|
79
|
+
return FAILURE_EXIT_CODE
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
await merge_with_hint(default_branch, merge_message(default_branch, current_branch))
|
|
83
|
+
console.info(default_branch)
|
|
84
|
+
|
|
85
|
+
return SUCCESS_EXIT_CODE
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// The argument refusal is kept even though this is no longer an `sh -c` entry: the message is the
|
|
89
|
+
// same one every composite prints, and silently discarding a flag is what it exists to prevent.
|
|
90
|
+
async function dispatch(argv: ReadonlyArray<string>): Promise<number> {
|
|
91
|
+
if (argv.length > 0) {
|
|
92
|
+
console.error(composite_arguments.format_rejection(COMMAND_NAME, []))
|
|
93
|
+
|
|
94
|
+
return USAGE_ERROR_EXIT_CODE
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return await merge_default_branch()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// A git failure — a merge conflict, a remote that cannot be reached — is reported as a message
|
|
101
|
+
// rather than a stack trace, matching every other josh CLI.
|
|
102
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
103
|
+
try {
|
|
104
|
+
return await dispatch(argv)
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.error(error instanceof Error ? error.message : String(error))
|
|
107
|
+
|
|
108
|
+
return FAILURE_EXIT_CODE
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
113
|
+
process.exitCode = await run(argv)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const main_merge = { COMMAND_NAME, main, run }
|
|
117
|
+
|
|
118
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
119
|
+
|
|
120
|
+
export { main_merge }
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { composite_arguments, USAGE_ERROR_EXIT_CODE } from '#scripts/josh/josh-composite-arguments'
|
|
4
|
+
import { git_command } from './git-command'
|
|
5
|
+
import { gone_branch, type PruneResult } from './gone-branch'
|
|
6
|
+
|
|
7
|
+
// `josh main:sync` (`josh ms`) — return this checkout to the default branch and pull
|
|
8
|
+
// (joshuafolkken/kit#1535), then prune the local branches whose merged remote branch is gone
|
|
9
|
+
// (joshuafolkken/kit#2504; the rule for which ones is `gone-branch.ts`).
|
|
10
|
+
//
|
|
11
|
+
// **It refuses inside a linked work tree, and that refusal is the reason this stopped being a
|
|
12
|
+
// one-line `sh -c` entry.** The default branch is a *branch*: advancing it means checking it out
|
|
13
|
+
// somewhere, and git allows one branch in one work tree at a time. Run from a lane, `git checkout
|
|
14
|
+
// <default>` therefore does two things nobody asked for — measured on 2026-09-07 while five lanes
|
|
15
|
+
// were open:
|
|
16
|
+
//
|
|
17
|
+
// 1. **The lane stops being a lane.** `lane:list` matches on the branch name, so the work tree drops
|
|
18
|
+
// out of the listing, `lane:close` can no longer reach it, and the port seat its `.env` holds is
|
|
19
|
+
// never reclaimed.
|
|
20
|
+
// 2. **Every other lane's `josh ms` then fails**, with `fatal: '<default>' is already used by
|
|
21
|
+
// worktree at '<the hijacked lane>'` — one lane's tidy-up step breaks the other four.
|
|
22
|
+
//
|
|
23
|
+
// A lane's terminal step is `pnpm josh lane:close <issue-number>`; the refusal says so. Nothing about
|
|
24
|
+
// the main work tree's behavior changes.
|
|
25
|
+
|
|
26
|
+
const SUCCESS_EXIT_CODE = 0
|
|
27
|
+
const FAILURE_EXIT_CODE = 1
|
|
28
|
+
const ARGV_OFFSET = 2
|
|
29
|
+
const COMMAND_NAME = 'main:sync'
|
|
30
|
+
|
|
31
|
+
// `git_directories()` returns `[--absolute-git-dir, --git-common-dir]`. They are the same path in the
|
|
32
|
+
// main work tree and differ in a linked one, which is git's own definition of the distinction rather
|
|
33
|
+
// than a guess from a directory name.
|
|
34
|
+
const OWN_GIT_DIRECTORY = 0
|
|
35
|
+
const COMMON_GIT_DIRECTORY = 1
|
|
36
|
+
|
|
37
|
+
// The refusal covers every linked work tree, not lanes alone, because the hijack is a property of
|
|
38
|
+
// the work tree rather than of what opened it. It names both ways out for that reason.
|
|
39
|
+
const LANE_REFUSAL = [
|
|
40
|
+
`josh ${COMMAND_NAME} cannot run inside a linked work tree.`,
|
|
41
|
+
'Checking the default branch out here takes it from whichever work tree holds it, and a lane that loses its own branch drops out of `josh lane:list` with its port seat still allocated.',
|
|
42
|
+
'Run `pnpm josh ms` in the primary checkout instead; a lane is finished with `pnpm josh lane:close <issue-number>`.',
|
|
43
|
+
].join('\n')
|
|
44
|
+
|
|
45
|
+
async function is_linked_work_tree(): Promise<boolean> {
|
|
46
|
+
const directories = await git_command.git_directories()
|
|
47
|
+
|
|
48
|
+
return directories[OWN_GIT_DIRECTORY] !== directories[COMMON_GIT_DIRECTORY]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// The count rather than the names: the first run on a long-lived checkout removes hundreds. A branch
|
|
52
|
+
// `git branch -d` refused is named, because that one is left for a person to look at.
|
|
53
|
+
function report_prune(result: PruneResult): void {
|
|
54
|
+
if (result.deleted.length > 0) {
|
|
55
|
+
console.info(`pruned ${String(result.deleted.length)} merged branch(es) whose remote is gone`)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const name of result.failed) console.error(`kept ${name}: git branch -d refused it`)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// The sync has already succeeded when the prune runs, so a prune that cannot finish — a fetch that
|
|
62
|
+
// loses the network, a git too old for `%(worktreepath)` — is reported and does not turn the exit code
|
|
63
|
+
// into the one a failed checkout or pull gives.
|
|
64
|
+
async function prune_quietly(default_branch: string): Promise<void> {
|
|
65
|
+
try {
|
|
66
|
+
report_prune(await gone_branch.prune(default_branch))
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error(`branch prune skipped: ${error instanceof Error ? error.message : String(error)}`)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function synchronize(): Promise<number> {
|
|
73
|
+
const default_branch = await git_command.get_default_branch()
|
|
74
|
+
|
|
75
|
+
await git_command.checkout(default_branch)
|
|
76
|
+
await git_command.pull_fast_forward()
|
|
77
|
+
await prune_quietly(default_branch)
|
|
78
|
+
console.info(default_branch)
|
|
79
|
+
|
|
80
|
+
return SUCCESS_EXIT_CODE
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// The argument refusal is kept even though this is no longer an `sh -c` entry: the message is the
|
|
84
|
+
// same one every composite prints, and silently discarding a flag is what it exists to prevent.
|
|
85
|
+
async function dispatch(argv: ReadonlyArray<string>): Promise<number> {
|
|
86
|
+
if (argv.length > 0) {
|
|
87
|
+
console.error(composite_arguments.format_rejection(COMMAND_NAME, []))
|
|
88
|
+
|
|
89
|
+
return USAGE_ERROR_EXIT_CODE
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (await is_linked_work_tree()) {
|
|
93
|
+
console.error(LANE_REFUSAL)
|
|
94
|
+
|
|
95
|
+
return FAILURE_EXIT_CODE
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return await synchronize()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// A git failure — a dirty tree the checkout refuses to leave, a pull that cannot reach the remote —
|
|
102
|
+
// is reported as a message rather than a stack trace, matching every other josh CLI.
|
|
103
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
104
|
+
try {
|
|
105
|
+
return await dispatch(argv)
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error(error instanceof Error ? error.message : String(error))
|
|
108
|
+
|
|
109
|
+
return FAILURE_EXIT_CODE
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
114
|
+
process.exitCode = await run(argv)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const main_sync = { COMMAND_NAME, LANE_REFUSAL, main, run }
|
|
118
|
+
|
|
119
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
120
|
+
|
|
121
|
+
export { main_sync }
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
// Marks input that is not JSON at all, letting each caller pick its own empty value. Schema
|
|
4
|
+
// mismatches are deliberately not folded in here: those rethrow, so a shape change stays visible
|
|
5
|
+
// instead of silently degrading to a fallback.
|
|
6
|
+
const MALFORMED_JSON = Symbol('malformed-json')
|
|
7
|
+
|
|
8
|
+
function parse_json_loose(raw_json: string): unknown {
|
|
9
|
+
try {
|
|
10
|
+
return JSON.parse(raw_json)
|
|
11
|
+
} catch (error) {
|
|
12
|
+
if (error instanceof SyntaxError) return MALFORMED_JSON
|
|
13
|
+
throw error
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Parse a JSON string into an array validated by the given element schema.
|
|
19
|
+
* Malformed JSON yields undefined, so a caller can tell it apart from an empty listing.
|
|
20
|
+
*
|
|
21
|
+
* `parse_json_array_safe` answers `[]` for both, which reads as "there is nothing" — and a command
|
|
22
|
+
* that acts on that reports a confident absence built on a response it could not parse
|
|
23
|
+
* (joshuafolkken/kit#950).
|
|
24
|
+
*/
|
|
25
|
+
function parse_json_array_or_undefined<T>(
|
|
26
|
+
raw_json: string,
|
|
27
|
+
element_schema: z.ZodType<T>,
|
|
28
|
+
): Array<T> | undefined {
|
|
29
|
+
const value = parse_json_loose(raw_json)
|
|
30
|
+
// Not an array at all — `gh` answering `{"message":"API rate limit exceeded"}` rather than a
|
|
31
|
+
// listing. That is the same kind of gap as unparseable output, not a change in the shape of the
|
|
32
|
+
// elements, so it reads as unreadable instead of throwing out of the command.
|
|
33
|
+
if (value === MALFORMED_JSON || !Array.isArray(value)) return undefined
|
|
34
|
+
|
|
35
|
+
return element_schema.array().parse(value)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// What one listing read produced. The two gaps are deliberately apart: JSON that is not a listing at
|
|
39
|
+
// all is an access or connectivity problem, while elements the schema rejects mean the tool's fields
|
|
40
|
+
// changed — and those send a reader to two different places (joshuafolkken/kit#996). A caller that
|
|
41
|
+
// treats them the same still reads them from here rather than writing the try/catch again.
|
|
42
|
+
type ListingRead<T> =
|
|
43
|
+
{ kind: 'read'; rows: Array<T> } | { kind: 'unreadable' } | { kind: 'unexpected_shape' }
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Parse a listing, telling the two gaps apart.
|
|
47
|
+
*
|
|
48
|
+
* The rethrow `parse_json_array_or_undefined` performs is the whole point, and every caller that
|
|
49
|
+
* wants both gaps named was catching it itself — the `auto-ok` pickup and `epic:next`'s
|
|
50
|
+
* repository-level busy check wrote the same six lines (joshuafolkken/kit#925).
|
|
51
|
+
*/
|
|
52
|
+
function read_json_listing<T>(raw_json: string, element_schema: z.ZodType<T>): ListingRead<T> {
|
|
53
|
+
try {
|
|
54
|
+
const rows = parse_json_array_or_undefined(raw_json, element_schema)
|
|
55
|
+
|
|
56
|
+
return rows === undefined ? { kind: 'unreadable' } : { kind: 'read', rows }
|
|
57
|
+
} catch {
|
|
58
|
+
return { kind: 'unexpected_shape' }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Parse a JSON string into an array validated by the given element schema.
|
|
64
|
+
* Malformed JSON yields an empty array.
|
|
65
|
+
*
|
|
66
|
+
* Deliberately **not** `parse_json_array_or_undefined(...) ?? []`, near-identical though the bodies
|
|
67
|
+
* are. The two differ on the branch that matters: valid JSON that is not an array throws here, so a
|
|
68
|
+
* `gh` field that changed shape stays visible, while the variant above reads it as a gap. Folding
|
|
69
|
+
* them together silences that throw for every existing caller (joshuafolkken/kit#950).
|
|
70
|
+
*/
|
|
71
|
+
function parse_json_array_safe<T>(raw_json: string, element_schema: z.ZodType<T>): Array<T> {
|
|
72
|
+
const value = parse_json_loose(raw_json)
|
|
73
|
+
if (value === MALFORMED_JSON) return []
|
|
74
|
+
|
|
75
|
+
return element_schema.array().parse(value)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Parse a JSON string into a single object validated by the given schema.
|
|
80
|
+
* Malformed JSON yields undefined.
|
|
81
|
+
*/
|
|
82
|
+
function parse_json_object_safe<T>(raw_json: string, schema: z.ZodType<T>): T | undefined {
|
|
83
|
+
const value = parse_json_loose(raw_json)
|
|
84
|
+
if (value === MALFORMED_JSON) return undefined
|
|
85
|
+
|
|
86
|
+
return schema.parse(value)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const parse_json = {
|
|
90
|
+
parse_json_array_safe,
|
|
91
|
+
parse_json_array_or_undefined,
|
|
92
|
+
parse_json_object_safe,
|
|
93
|
+
read_json_listing,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export {
|
|
97
|
+
parse_json,
|
|
98
|
+
parse_json_array_or_undefined,
|
|
99
|
+
parse_json_array_safe,
|
|
100
|
+
parse_json_object_safe,
|
|
101
|
+
read_json_listing,
|
|
102
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
const package_name_schema = z.object({ name: z.string().min(1) })
|
|
4
|
+
|
|
5
|
+
const rollup_item_schema = z.looseObject({
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention -- GraphQL field name from GitHub API
|
|
7
|
+
__typename: z.string().optional(),
|
|
8
|
+
state: z.string().optional(),
|
|
9
|
+
status: z.string().optional(),
|
|
10
|
+
conclusion: z.string().optional(),
|
|
11
|
+
name: z.string().optional(),
|
|
12
|
+
context: z.string().optional(),
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const pr_raw_schema = z.object({
|
|
16
|
+
statusCheckRollup: z.array(rollup_item_schema).optional(),
|
|
17
|
+
mergeStateStatus: z.string().optional(),
|
|
18
|
+
reviewDecision: z.string().optional(),
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const pull_comment_schema = z.object({
|
|
22
|
+
body: z.string().optional(),
|
|
23
|
+
html_url: z.string().optional(),
|
|
24
|
+
user: z.object({ login: z.string().optional() }).optional(),
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const ai_review_pull_comment_schema = z.object({
|
|
28
|
+
body: z.string().optional(),
|
|
29
|
+
url: z.string().optional(),
|
|
30
|
+
author: z.object({ login: z.string().optional() }).optional(),
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const pr_info_schema = z.object({
|
|
34
|
+
mergeable: z.union([z.boolean(), z.string()]).nullable().optional(),
|
|
35
|
+
mergeStateStatus: z.string().nullable().optional(),
|
|
36
|
+
state: z.string().optional(),
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const epic_issue_schema = z.object({
|
|
40
|
+
number: z.number(),
|
|
41
|
+
body: z.string().optional(),
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// One blocker as `gh` reports it inside the `blockedBy` connection. `state` comes back with the
|
|
45
|
+
// number, so telling a resolved blocker from a standing one costs no extra request
|
|
46
|
+
// (joshuafolkken/kit#996).
|
|
47
|
+
// `number` is **required**. Relaxing it looks harmless and is not: `epic_issue.blockers_of` maps the
|
|
48
|
+
// nodes to their numbers, so an optional one turns a `blockedBy` shape change from a failed parse —
|
|
49
|
+
// which marks the child unreadable — into an empty blocker list, and `epic:next` then hands a
|
|
50
|
+
// dependent to an unattended run before its prerequisite. Fail-safe is the direction that matters
|
|
51
|
+
// here (joshuafolkken/kit#1005).
|
|
52
|
+
//
|
|
53
|
+
// `repository_url` is the repository the blocker lives in, as REST names it
|
|
54
|
+
// (`https://api.github.com/repos/<owner>/<repo>`). Carried since joshuafolkken/kit#1126: a
|
|
55
|
+
// `blocked-by` relation may cross a repository, and a reader that keeps only the number resolves it
|
|
56
|
+
// against the blocked child's own repository — a different issue, or none. Optional because a
|
|
57
|
+
// caller that only wants numbers must not be made to fail on a response shape it never reads.
|
|
58
|
+
const blocking_issue_schema = z.object({
|
|
59
|
+
number: z.number(),
|
|
60
|
+
state: z.string().optional(),
|
|
61
|
+
repository_url: z.string().optional(),
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
// The blocker relations arrive as a connection — `{ nodes, totalCount }` — not a bare array.
|
|
65
|
+
// Measured against a real issue rather than assumed (joshuafolkken/kit#860). `gh issue view`
|
|
66
|
+
// answered the connection itself; since joshuafolkken/kit#1024 REST serves a bare array from the
|
|
67
|
+
// issue's own `dependencies/blocked_by` endpoint and `git-gh-issue-rest.ts` maps it back into this
|
|
68
|
+
// shape, so every reader below is unchanged.
|
|
69
|
+
//
|
|
70
|
+
// **One definition, every reader.** The same connection was written out three times — twice here and
|
|
71
|
+
// once in `scripts/epic/epic-issue.ts` — each naming only the fields its own caller happened to want,
|
|
72
|
+
// so a shape change had three places to reach and one of them would not be noticed. That is the
|
|
73
|
+
// duplication joshuafolkken/kit#862 removed from the epic commands, reintroduced by the readers that
|
|
74
|
+
// came after (joshuafolkken/kit#1005).
|
|
75
|
+
//
|
|
76
|
+
// `nodes` is a page — `blockedBy(first:50)` under GraphQL, one unpaged `per_page=100` request under
|
|
77
|
+
// REST — while `totalCount` is exact, read from the issue's own dependency summary. A reader that
|
|
78
|
+
// compares them can tell a complete page from a truncated one, with one exception: where GitHub
|
|
79
|
+
// reports no summary at all the count falls back to the page's own size, and a truncated page then
|
|
80
|
+
// reads as complete. Every issue the reads go through carries one, so that is a guard rather than
|
|
81
|
+
// a case. **Only the `auto-ok` pickup compares them**; the epic readers judge from the page they
|
|
82
|
+
// were given, so an epic child declaring more blockers than one page holds is read from the first
|
|
83
|
+
// page. Carried here so the field is available, not because every reader consults it
|
|
84
|
+
// (joshuafolkken/kit#1005).
|
|
85
|
+
const blocked_by_schema = z
|
|
86
|
+
.object({
|
|
87
|
+
nodes: z.array(blocking_issue_schema).default([]),
|
|
88
|
+
totalCount: z.number().optional(),
|
|
89
|
+
})
|
|
90
|
+
.optional()
|
|
91
|
+
|
|
92
|
+
const epic_child_schema = z.object({
|
|
93
|
+
state: z.string().optional(),
|
|
94
|
+
blockedBy: blocked_by_schema,
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
// One conversation comment as `repos/{owner}/{repo}/issues/{N}/comments` serves it — the listing
|
|
98
|
+
// both the AI-review scan and the epic auto-close read.
|
|
99
|
+
//
|
|
100
|
+
// Carried here rather than beside either reader: the pull request's conversation comments and an
|
|
101
|
+
// epic's are the *same endpoint* answering the same objects, so a second declaration of this shape
|
|
102
|
+
// would be the clone `CLAUDE.md` prohibits (joshuafolkken/kit#1039). `ai_review_pull_comment_schema`
|
|
103
|
+
// above is the `gh --json` spelling the scan reads after the mapping, not this one.
|
|
104
|
+
const rest_comment_schema = z.looseObject({
|
|
105
|
+
body: z.string().nullish(),
|
|
106
|
+
html_url: z.string().optional(),
|
|
107
|
+
user: z.looseObject({ login: z.string().optional() }).nullish(),
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// The `number,state,labels,body` read, for the epic check and the `--add` closed-epic refusal.
|
|
111
|
+
// Labels come back as objects, so the name is picked out here rather than at every call site.
|
|
112
|
+
const issue_label_schema = z.object({ name: z.string() })
|
|
113
|
+
|
|
114
|
+
// `state` is optional because most readers ignore it — only `git-epic-add.ts` consults it, to refuse
|
|
115
|
+
// adding a child to a closed epic (joshuafolkken/kit#2337). A reader that never asks the state field
|
|
116
|
+
// still parses cleanly.
|
|
117
|
+
const epic_subject_schema = z.object({
|
|
118
|
+
number: z.number(),
|
|
119
|
+
state: z.string().optional(),
|
|
120
|
+
labels: z.array(issue_label_schema).optional(),
|
|
121
|
+
body: z.string().optional(),
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
// One row of an open-issue listing, under the field names `gh issue list --json` answered with.
|
|
125
|
+
// Three readers parse a listing through this shape: the next-issues display printed when a workflow
|
|
126
|
+
// completes (#821), the `auto-ok` pickup (joshuafolkken/kit#906), and the per-repository busy check
|
|
127
|
+
// `epic:next` makes before it offers a child (joshuafolkken/kit#925).
|
|
128
|
+
//
|
|
129
|
+
// The row is *assembled* under those names rather than returned under them. Since
|
|
130
|
+
// joshuafolkken/kit#1025 the listing is REST, and `blockedBy` is not part of a listing response at
|
|
131
|
+
// all: `git-gh-issue-list.ts` reads the relations from each row's own dependencies endpoint, and
|
|
132
|
+
// only for the pickup, which is the one caller whose field list names `blockedBy` at all.
|
|
133
|
+
//
|
|
134
|
+
// So `blockedBy` is optional for the reason it is absent in practice — the display and the busy
|
|
135
|
+
// check never ask for it, and a field that was not asked for is left out of the mapped row rather
|
|
136
|
+
// than filled in.
|
|
137
|
+
const open_issue_schema = z.object({
|
|
138
|
+
number: z.number(),
|
|
139
|
+
title: z.string(),
|
|
140
|
+
labels: z.array(issue_label_schema).optional(),
|
|
141
|
+
createdAt: z.string(),
|
|
142
|
+
blockedBy: blocked_by_schema,
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
type RollupItemData = z.infer<typeof rollup_item_schema>
|
|
146
|
+
type EpicChildData = z.infer<typeof epic_child_schema>
|
|
147
|
+
type OpenIssueData = z.infer<typeof open_issue_schema>
|
|
148
|
+
type RestCommentData = z.infer<typeof rest_comment_schema>
|
|
149
|
+
|
|
150
|
+
export {
|
|
151
|
+
package_name_schema,
|
|
152
|
+
rollup_item_schema,
|
|
153
|
+
pr_raw_schema,
|
|
154
|
+
pull_comment_schema,
|
|
155
|
+
rest_comment_schema,
|
|
156
|
+
ai_review_pull_comment_schema,
|
|
157
|
+
pr_info_schema,
|
|
158
|
+
epic_issue_schema,
|
|
159
|
+
issue_label_schema,
|
|
160
|
+
epic_child_schema,
|
|
161
|
+
epic_subject_schema,
|
|
162
|
+
open_issue_schema,
|
|
163
|
+
blocking_issue_schema,
|
|
164
|
+
blocked_by_schema,
|
|
165
|
+
}
|
|
166
|
+
export type { RollupItemData, EpicChildData, OpenIssueData, RestCommentData }
|