@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,97 @@
|
|
|
1
|
+
import { git_gh_command } from '#scripts/git/git-gh-command'
|
|
2
|
+
import type { OpenPull } from '#scripts/git/git-gh-pr-auto-merge'
|
|
3
|
+
import { git_pr_checks } from '#scripts/git/git-pr-checks'
|
|
4
|
+
|
|
5
|
+
// **A flush pull request lands whether or not the flush that opened it is still alive**
|
|
6
|
+
// (joshuafolkken/kit#2497). The merge used to happen only inside the flush's own wait, so a session
|
|
7
|
+
// cut or a killed process left a green pull request open with nobody to merge it — and once a later
|
|
8
|
+
// flush appended to the same ledger tail, it conflicted and could not land at all. Auto-merge moves
|
|
9
|
+
// the merge to GitHub, and the wait that remains is only for fast-forwarding the local default
|
|
10
|
+
// branch.
|
|
11
|
+
|
|
12
|
+
const AUTO_MERGE_WARNING =
|
|
13
|
+
'Could not enable auto-merge on the flush pull request, so it merges only if this command stays alive to merge it:'
|
|
14
|
+
const MERGE_TIMEOUT_REASON =
|
|
15
|
+
'auto-merge is enabled, but the pull request did not merge within the checks budget'
|
|
16
|
+
const MERGE_FAILED_REASON =
|
|
17
|
+
'a required check failed or the branch conflicts, so auto-merge will not land the pull request'
|
|
18
|
+
|
|
19
|
+
// **Best-effort, and the answer says which wait to use.** GraphQL — the only way to enable auto-merge
|
|
20
|
+
// — can be refused in a cloud session (joshuafolkken/kit#1022), and that loses the safety net rather
|
|
21
|
+
// than the flush: the in-process wait-and-merge still runs, exactly as before auto-merge existed.
|
|
22
|
+
async function request_auto_merge(branch_name: string): Promise<boolean> {
|
|
23
|
+
try {
|
|
24
|
+
await git_gh_command.pr_enable_auto_merge(branch_name)
|
|
25
|
+
|
|
26
|
+
return true
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.warn(AUTO_MERGE_WARNING, error instanceof Error ? error.message : String(error))
|
|
29
|
+
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// With auto-merge on, GitHub merges and this only waits to see it; `pr_merge` is not called, because
|
|
35
|
+
// the merge gate's wait would run out its budget on a pull request that is already merged.
|
|
36
|
+
async function wait_for_landing(branch_name: string, is_auto_merge: boolean): Promise<void> {
|
|
37
|
+
if (!is_auto_merge) {
|
|
38
|
+
await git_pr_checks.wait_for_pr_success(branch_name)
|
|
39
|
+
await git_gh_command.pr_merge(branch_name)
|
|
40
|
+
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const progress = await git_pr_checks.wait_for_pr_merged(branch_name)
|
|
45
|
+
|
|
46
|
+
if (progress === 'failed') throw new Error(MERGE_FAILED_REASON)
|
|
47
|
+
if (progress === 'waiting') throw new Error(MERGE_TIMEOUT_REASON)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function describe_pull(pull: OpenPull): string {
|
|
51
|
+
return `#${String(pull.number)} (\`${pull.head_ref}\`)`
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// **Landing means GitHub will merge it with nobody watching**: auto-merge is on and the merge gate has
|
|
55
|
+
// not failed it — a red check or a conflict leaves auto-merge armed but never firing. One that merged
|
|
56
|
+
// between the listing and this read has landed, so it defers rather than reading as stuck.
|
|
57
|
+
async function is_landing(pull: OpenPull): Promise<boolean> {
|
|
58
|
+
if (!pull.has_auto_merge) return false
|
|
59
|
+
|
|
60
|
+
return (await git_pr_checks.read_merge_progress(pull.head_ref)) !== 'failed'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function landing_flush_message(pulls: ReadonlyArray<OpenPull>): string {
|
|
64
|
+
return `deferred — an earlier flush pull request is still landing with auto-merge on: ${pulls.map((pull) => describe_pull(pull)).join(', ')}. A new flush branch would conflict with it at the ledger's tail, so the appended observations stay in this working tree for the next flush.`
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// **Named rather than silently skipped**, because its lines exist only on its branch: once a later
|
|
68
|
+
// flush appends to the same tail it conflicts and can no longer land by itself. A flush still running
|
|
69
|
+
// in another checkout without auto-merge reads the same way, so the message allows for it.
|
|
70
|
+
function stuck_flush_message(pulls: ReadonlyArray<OpenPull>): string {
|
|
71
|
+
return `An earlier \`pnpm josh observations:flush\` left a pull request open that nothing will merge — unless a flush in another checkout is still waiting on it: ${pulls.map((pull) => describe_pull(pull)).join(', ')}. Its appended observations exist only on that branch — land it (resolve the ledger conflict if there is one, then merge) before flushing again, or a new flush would conflict with it.`
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// **`undefined` means no earlier flush is open, and a flush may cut its branch.** An earlier one that
|
|
75
|
+
// is still landing defers this flush with a message; one that will never land refuses it.
|
|
76
|
+
async function refuse_open_flush(branch_prefix: string): Promise<string | undefined> {
|
|
77
|
+
const pulls = await git_gh_command.pr_list_open_with_head_prefix(branch_prefix)
|
|
78
|
+
if (pulls.length === 0) return undefined
|
|
79
|
+
|
|
80
|
+
const verdicts = await Promise.all(pulls.map(async (pull) => await is_landing(pull)))
|
|
81
|
+
const stuck = pulls.filter((_pull, index) => verdicts[index] !== true)
|
|
82
|
+
if (stuck.length > 0) throw new Error(stuck_flush_message(stuck))
|
|
83
|
+
|
|
84
|
+
return landing_flush_message(pulls)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const observations_flush_landing = {
|
|
88
|
+
landing_flush_message,
|
|
89
|
+
MERGE_FAILED_REASON,
|
|
90
|
+
MERGE_TIMEOUT_REASON,
|
|
91
|
+
refuse_open_flush,
|
|
92
|
+
request_auto_merge,
|
|
93
|
+
stuck_flush_message,
|
|
94
|
+
wait_for_landing,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { observations_flush_landing }
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises'
|
|
2
|
+
import { git_command } from '#scripts/git/git-command'
|
|
3
|
+
import { git_gh_command } from '#scripts/git/git-gh-command'
|
|
4
|
+
import { main_sync } from '#scripts/git/main-sync'
|
|
5
|
+
import { observation_ledger, OBSERVATION_LEDGER_PATH } from './observation-ledger'
|
|
6
|
+
import { observation_ledger_line, type BrokenLine } from './observation-ledger-line'
|
|
7
|
+
import { observations_flush_landing } from './observations-flush-landing'
|
|
8
|
+
|
|
9
|
+
// The commit path the observation ledger did not have (joshuafolkken/kit#1756). The parent session
|
|
10
|
+
// that appends a line never runs `pnpm josh git`; a child runs it inside a lane work tree, which
|
|
11
|
+
// cannot see the parent's checkout at all; and in the primary checkout `git add -u` swept the line
|
|
12
|
+
// into whatever unrelated pull request that run was opening. So the ledger is excluded from ordinary
|
|
13
|
+
// staging (`scripts/git/git-staging.ts`) and this is the one thing that stages it.
|
|
14
|
+
//
|
|
15
|
+
// **The shape is `scripts/release/release-publish.ts`'s, deliberately.** Both open a pull request of
|
|
16
|
+
// their own over one path, wait on the same required checks every other pull request waits on, and
|
|
17
|
+
// merge — so this reuses the same primitives rather than growing a second answer to "how does a
|
|
18
|
+
// josh command open and land a pull request". The one difference is that this pull request is handed
|
|
19
|
+
// to GitHub's auto-merge as soon as it opens (joshuafolkken/kit#2497), so it lands even when the wait
|
|
20
|
+
// below does not survive — `observations-flush-landing.ts` carries why.
|
|
21
|
+
|
|
22
|
+
const COMMIT_MESSAGE = 'Record observation ledger entries'
|
|
23
|
+
const CLEAN_MESSAGE = `clean — ${OBSERVATION_LEDGER_PATH} matches the commit it sits on, so there is nothing to flush`
|
|
24
|
+
const BRANCH_PREFIX = 'observations/'
|
|
25
|
+
const SUCCESS_EXIT_CODE = 0
|
|
26
|
+
const RETURN_FAILURE_MESSAGE =
|
|
27
|
+
'Could not return this checkout to the default branch; `pnpm josh ms` printed the reason above.'
|
|
28
|
+
const FAST_FORWARD_FAILURE_MESSAGE =
|
|
29
|
+
'The flush pull request merged, but the local default branch could not be fast-forwarded to it, so this checkout is still on the flush branch:'
|
|
30
|
+
const DATE_END = 10
|
|
31
|
+
const TIME_START = 11
|
|
32
|
+
const TIME_END = 19
|
|
33
|
+
const COLON = ':'
|
|
34
|
+
const NO_COMMITS = 0
|
|
35
|
+
|
|
36
|
+
// **A count that could not be read is treated as "it may hold a commit".** Of the two refusals below
|
|
37
|
+
// it chooses the one that warns about the only copy, because printing "nothing is stranded" on a
|
|
38
|
+
// branch nobody could measure is the answer that loses lines.
|
|
39
|
+
const UNKNOWN_COMMIT_COUNT = 1
|
|
40
|
+
|
|
41
|
+
// **Stamped to the second rather than to the minute.** A flush that fails after its commit leaves the
|
|
42
|
+
// branch behind, and a retry inside the same clock unit would die on git's raw `a branch named …
|
|
43
|
+
// already exists` instead of the message below — so the unit is the one a person cannot retry
|
|
44
|
+
// inside.
|
|
45
|
+
function timestamp_for(now: Date): string {
|
|
46
|
+
const iso = now.toISOString()
|
|
47
|
+
|
|
48
|
+
return `${iso.slice(0, DATE_END)}-${iso.slice(TIME_START, TIME_END).replaceAll(COLON, '')}`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function branch_name_for(stamp: string): string {
|
|
52
|
+
return `${BRANCH_PREFIX}${stamp}`
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// **No `closes #N`.** A flush carries whatever observations the last cycle recorded; it answers to no
|
|
56
|
+
// single issue, and the ledger's own lines say where each one was seen.
|
|
57
|
+
function pull_request_body(): string {
|
|
58
|
+
return [
|
|
59
|
+
`Appended observations from \`${OBSERVATION_LEDGER_PATH}\`, which \`pnpm josh git\` never stages.`,
|
|
60
|
+
'',
|
|
61
|
+
'The ledger is append-only, and a second line under one key is what promotes an observation to an issue — so this pull request adds lines and changes none.',
|
|
62
|
+
'',
|
|
63
|
+
'Opened by `pnpm josh observations:flush` (joshuafolkken/kit#1756).',
|
|
64
|
+
].join('\n')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function status_paths(status_output: string): ReadonlyArray<string> {
|
|
68
|
+
return status_output
|
|
69
|
+
.split('\n')
|
|
70
|
+
.filter((line) => line.trim().length > 0)
|
|
71
|
+
.map((line) => observation_ledger.status_path(line))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// **Single-sourced with `pnpm josh followup`'s pre-flush short-circuit** (joshuafolkken/kit#1810):
|
|
75
|
+
// the ledger-change test lives in `observation-ledger.ts`, so the two callers cannot drift.
|
|
76
|
+
function has_ledger_change(status_output: string): boolean {
|
|
77
|
+
return observation_ledger.has_pending_append(status_output)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function other_changed_paths(status_output: string): ReadonlyArray<string> {
|
|
81
|
+
return status_paths(status_output).filter((file_path) => file_path !== OBSERVATION_LEDGER_PATH)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function message_of(error: unknown): string {
|
|
85
|
+
return error instanceof Error ? error.message : String(error)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// **The branch a failed flush leaves behind holds the only copy of those lines**, because the working
|
|
89
|
+
// tree no longer shows them once they are committed. Sending a person to `pnpm josh ms` here — which
|
|
90
|
+
// is what the ordinary off-default refusal says — would abandon them without a word, so this branch
|
|
91
|
+
// of the refusal says the opposite.
|
|
92
|
+
//
|
|
93
|
+
// **The exits it names are ones the caller can actually take** (joshuafolkken/kit#1785). It used to
|
|
94
|
+
// say "finish or delete that branch", and both are closed to an agent: the distributed
|
|
95
|
+
// `.claude/settings.json` denies `Bash(git commit*)` and `Bash(git branch -d*)`, and `pnpm josh git`
|
|
96
|
+
// excludes the ledger from staging by design (joshuafolkken/kit#1756), so finishing through it is not
|
|
97
|
+
// possible either. Pushing the branch and landing its pull request is the route that is open.
|
|
98
|
+
function stranded_flush_message(current: string): string {
|
|
99
|
+
return `\`${current}\` is a flush branch an earlier \`pnpm josh observations:flush\` left behind, and its appended observations are committed only there. Land it before flushing again — \`git push -u origin ${current}\`, then open and merge its pull request; \`pnpm josh ms\` here would leave the only copy of those lines behind.`
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// **A flush branch with no commit on it strands nothing, so it is told the opposite**
|
|
103
|
+
// (joshuafolkken/kit#1785). The appended lines never left the working tree, which makes the "only
|
|
104
|
+
// copy" premise above factually false here — and makes `pnpm josh ms` the correct exit, the very one
|
|
105
|
+
// the other message forbids.
|
|
106
|
+
function empty_flush_message(current: string): string {
|
|
107
|
+
return `\`${current}\` is a flush branch an earlier \`pnpm josh observations:flush\` left behind with no commit on it, so nothing is stranded: the appended observations are still in this working tree. Run \`pnpm josh ms\` and flush again — that cuts a fresh branch and loses no line, leaving \`${current}\` as an empty branch to clear whenever it suits you.`
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function flush_branch_message(current: string, commit_count: number): string {
|
|
111
|
+
return commit_count === NO_COMMITS
|
|
112
|
+
? empty_flush_message(current)
|
|
113
|
+
: stranded_flush_message(current)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// **Two refusals rather than one taking a count it may not use.** Only the flush-branch arm reads a
|
|
117
|
+
// commit count, so the ordinary off-default refusal is a function of its own and
|
|
118
|
+
// `refuse_off_default` below spawns `git rev-list` for the arm that needs it alone.
|
|
119
|
+
function off_default_message(current: string, default_branch: string): string {
|
|
120
|
+
return `\`pnpm josh observations:flush\` opens a branch of its own, so it starts from \`${default_branch}\` — this checkout is on \`${current}\`. Run \`pnpm josh ms\` first.`
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// **A branch cut from a default branch that predates another merged flush conflicts by
|
|
124
|
+
// construction** (joshuafolkken/kit#1768). The ledger is append-only and every writer adds at the
|
|
125
|
+
// same tail, so a stale start point opens a pull request `wait_for_pr_success` waits on until it
|
|
126
|
+
// exhausts its budget rather than merging. The flush fast-forwards first (joshuafolkken/kit#2462), so
|
|
127
|
+
// this is printed only when that fast-forward was refused — the reason is git's own.
|
|
128
|
+
function behind_default_message(default_branch: string, reason: string): string {
|
|
129
|
+
return `\`pnpm josh observations:flush\` cuts its branch from \`${default_branch}\`, which is behind \`origin/${default_branch}\` and could not be fast-forwarded (${reason}) — a branch cut here would open a pull request that cannot merge. Run \`pnpm josh ms\` first.`
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function is_flush_branch(current: string): boolean {
|
|
133
|
+
return current.startsWith(BRANCH_PREFIX)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// **The rollback has already run, so this says what is now true rather than what to go and do.** The
|
|
137
|
+
// checkout is back on the default branch, the branch is gone, and the appended lines are where they
|
|
138
|
+
// always were — so the next attempt is this same command, once whatever rejected the commit is fixed.
|
|
139
|
+
function rejected_commit_message(branch_name: string, reason: string): string {
|
|
140
|
+
return `The ledger's commit was rejected, so \`${branch_name}\` was removed and this checkout is back on the default branch: ${reason} — the appended observations are still in the working tree. Fix what was rejected and run \`pnpm josh observations:flush\` again.`
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// **The rollback did not finish, so nothing here claims the branch is gone.** The message above
|
|
144
|
+
// would assert a removal that did not happen, which is worse than saying nothing: it is what sends
|
|
145
|
+
// somebody looking for a branch that is still sitting in the checkout. Both reasons are carried in
|
|
146
|
+
// the one error the command exits with rather than one of them being printed above it.
|
|
147
|
+
//
|
|
148
|
+
// **"Nothing was committed to it" is traceable rather than measured** — the commit that would have
|
|
149
|
+
// put something there is the one that was just rejected — so the exit is `empty_flush_message`'s,
|
|
150
|
+
// which is also the refusal the next run will print.
|
|
151
|
+
function roll_back_failure_message(
|
|
152
|
+
branch_name: string,
|
|
153
|
+
reason: string,
|
|
154
|
+
roll_back_reason: string,
|
|
155
|
+
): string {
|
|
156
|
+
return `The ledger's commit was rejected and \`${branch_name}\` could not be cleaned up afterwards. The commit was rejected by: ${reason}. The cleanup failed with: ${roll_back_reason}. Nothing was committed to that branch and the appended observations are still in the working tree, so \`pnpm josh ms\` followed by another flush loses no line.`
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// **A tree holding anything else is somebody's work in progress**, and a flush that carried it would
|
|
160
|
+
// be the contamination this command exists to end, pointing the other way.
|
|
161
|
+
function other_changes_message(paths: ReadonlyArray<string>): string {
|
|
162
|
+
return `The working tree holds changes besides the ledger, so \`pnpm josh observations:flush\` stops rather than committing them: ${paths.join(', ')}`
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// One message for every failure after the commit, because they all leave the same thing behind: the
|
|
166
|
+
// appended lines committed on the flush branch and nowhere the working tree can show them. The
|
|
167
|
+
// checkout is deliberately left on that branch, so the refusal above fires on the next attempt.
|
|
168
|
+
function stranded_branch_message(branch_name: string, reason: string): string {
|
|
169
|
+
return `The ledger is committed on \`${branch_name}\` and the flush then failed: ${reason} — those lines now exist only on that branch, and this checkout is still on it. Finish that branch's pull request before running \`pnpm josh ms\` here.`
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async function commits_beyond(base: string, tip: string): Promise<number> {
|
|
173
|
+
try {
|
|
174
|
+
return await git_command.commit_count_beyond(base, tip)
|
|
175
|
+
} catch {
|
|
176
|
+
return UNKNOWN_COMMIT_COUNT
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function refuse_off_default(current: string, default_branch: string): Promise<never> {
|
|
181
|
+
if (!is_flush_branch(current)) throw new Error(off_default_message(current, default_branch))
|
|
182
|
+
|
|
183
|
+
throw new Error(flush_branch_message(current, await commits_beyond(default_branch, current)))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// **The start point's freshness is judged without moving the working tree**, which is the whole
|
|
187
|
+
// point of doing it here rather than pulling (joshuafolkken/kit#1768). `git fetch` updates the
|
|
188
|
+
// remote-tracking ref and `git rev-list --count HEAD..origin/<default>` reads it — neither writes a
|
|
189
|
+
// file, so the ledger, dirty by definition when this runs, is left exactly as it is.
|
|
190
|
+
async function commits_behind_default(default_branch: string): Promise<number> {
|
|
191
|
+
await git_command.fetch_branch(default_branch)
|
|
192
|
+
|
|
193
|
+
return await git_command.commit_count_beyond('HEAD', `origin/${default_branch}`)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// **A default branch that is only behind is brought forward rather than refused**
|
|
197
|
+
// (joshuafolkken/kit#2462). A lane's flush acts on the primary checkout, whose default branch is
|
|
198
|
+
// behind by the lane's own merge every time — so the refusal alone stopped every lane close. A
|
|
199
|
+
// `--ff-only` merge moves no file the dirty ledger conflicts with: git refuses it, untouched, when an
|
|
200
|
+
// incoming commit changes the ledger too, and only that case is still refused.
|
|
201
|
+
async function catch_up_default(default_branch: string): Promise<void> {
|
|
202
|
+
if ((await commits_behind_default(default_branch)) === NO_COMMITS) return
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
await git_command.merge_fast_forward(default_branch)
|
|
206
|
+
} catch (error) {
|
|
207
|
+
throw new Error(behind_default_message(default_branch, message_of(error)), { cause: error })
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Returns the default branch, which is what the rollback below checks out again.
|
|
212
|
+
async function refuse_unsafe_flush(status_output: string): Promise<string> {
|
|
213
|
+
const current = await git_command.branch()
|
|
214
|
+
const default_branch = await git_command.get_default_branch()
|
|
215
|
+
|
|
216
|
+
if (current !== default_branch) await refuse_off_default(current, default_branch)
|
|
217
|
+
|
|
218
|
+
const others = other_changed_paths(status_output)
|
|
219
|
+
|
|
220
|
+
if (others.length > 0) throw new Error(other_changes_message(others))
|
|
221
|
+
|
|
222
|
+
return default_branch
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// **`main_sync.run` rather than a third copy of its three lines.** `pnpm josh ms` and
|
|
226
|
+
// `pnpm josh release`'s own `finally` already spell out "read the default branch, check it out, pull
|
|
227
|
+
// it", and writing it again here would be the clone `CLAUDE.md` prohibits. Reusing the command also
|
|
228
|
+
// brings its refusal inside a linked work tree, which is a precondition this flush wants anyway.
|
|
229
|
+
//
|
|
230
|
+
// **Its exit code is read rather than discarded**: `run` catches its own errors and returns `1`, so a
|
|
231
|
+
// checkout left on the flush branch would otherwise be reported as a completed flush.
|
|
232
|
+
//
|
|
233
|
+
// **The local default branch is fast-forwarded before it is checked out** (joshuafolkken/kit#2462).
|
|
234
|
+
// Lines appended while the pull request waited leave the ledger dirty, and git refuses to check out a
|
|
235
|
+
// default branch whose ledger differs from the flush branch's. Once the merge is in, the fast-forwarded
|
|
236
|
+
// default branch holds the same ledger the flush branch does, so the checkout carries those lines over.
|
|
237
|
+
//
|
|
238
|
+
// **A failed fast-forward says the merge is already in**, so the person reading it knows the ledger
|
|
239
|
+
// lines are safe and only this checkout is left on the flush branch.
|
|
240
|
+
async function return_to_default_branch(default_branch: string): Promise<void> {
|
|
241
|
+
try {
|
|
242
|
+
await git_command.fast_forward_local(default_branch)
|
|
243
|
+
} catch (error) {
|
|
244
|
+
throw new Error(`${FAST_FORWARD_FAILURE_MESSAGE} ${message_of(error)}`, { cause: error })
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const exit_code = await main_sync.run([])
|
|
248
|
+
|
|
249
|
+
if (exit_code !== SUCCESS_EXIT_CODE) throw new Error(RETURN_FAILURE_MESSAGE)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Everything after the commit, so a failure here can say what is on the branch and what it costs to
|
|
253
|
+
// walk away from it.
|
|
254
|
+
async function push_and_open(branch_name: string): Promise<string> {
|
|
255
|
+
try {
|
|
256
|
+
await git_command.push()
|
|
257
|
+
|
|
258
|
+
return await git_gh_command.pr_create(COMMIT_MESSAGE, pull_request_body())
|
|
259
|
+
} catch (error) {
|
|
260
|
+
throw new Error(stranded_branch_message(branch_name, message_of(error)), { cause: error })
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// **The side that created the branch is the side that rolls it back** (joshuafolkken/kit#1785). A
|
|
265
|
+
// commit rejected by the pre-commit hook used to leave the branch behind with nothing on it, and the
|
|
266
|
+
// refusal the next run printed named two exits an agent cannot take. Nothing is stranded at this
|
|
267
|
+
// point — the appended lines are still in the working tree, staged and uncommitted — so returning to
|
|
268
|
+
// the default branch and removing the branch loses none of them.
|
|
269
|
+
//
|
|
270
|
+
// **Its own failure is returned rather than thrown or printed**, so the single error the command
|
|
271
|
+
// exits with can carry both facts — why the commit was rejected, and whether the branch is still
|
|
272
|
+
// there. Printed above the throw it scrolled past the message that mattered; thrown over it, the
|
|
273
|
+
// reason for the rejection was lost outright. `undefined` means the rollback finished.
|
|
274
|
+
async function roll_back(branch_name: string, default_branch: string): Promise<string | undefined> {
|
|
275
|
+
try {
|
|
276
|
+
await git_command.checkout(default_branch)
|
|
277
|
+
await git_command.delete_branch(branch_name)
|
|
278
|
+
|
|
279
|
+
return undefined
|
|
280
|
+
} catch (error) {
|
|
281
|
+
return message_of(error)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// **The message is chosen from what the rollback did, never assumed.** A rollback that could not
|
|
286
|
+
// check the default branch out leaves the branch exactly where it was, and a message asserting its
|
|
287
|
+
// removal would send somebody looking for something that is still in the checkout.
|
|
288
|
+
function rejection_message(
|
|
289
|
+
branch_name: string,
|
|
290
|
+
reason: string,
|
|
291
|
+
roll_back_reason: string | undefined,
|
|
292
|
+
): string {
|
|
293
|
+
if (roll_back_reason === undefined) return rejected_commit_message(branch_name, reason)
|
|
294
|
+
|
|
295
|
+
return roll_back_failure_message(branch_name, reason, roll_back_reason)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async function commit_ledger(branch_name: string, default_branch: string): Promise<void> {
|
|
299
|
+
try {
|
|
300
|
+
await git_command.add_path(OBSERVATION_LEDGER_PATH)
|
|
301
|
+
await git_command.commit(COMMIT_MESSAGE)
|
|
302
|
+
} catch (error) {
|
|
303
|
+
const roll_back_reason = await roll_back(branch_name, default_branch)
|
|
304
|
+
|
|
305
|
+
throw new Error(rejection_message(branch_name, message_of(error), roll_back_reason), {
|
|
306
|
+
cause: error,
|
|
307
|
+
})
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
async function open_pull_request(branch_name: string, default_branch: string): Promise<string> {
|
|
312
|
+
await git_command.checkout_b(branch_name)
|
|
313
|
+
await commit_ledger(branch_name, default_branch)
|
|
314
|
+
|
|
315
|
+
return await push_and_open(branch_name)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// **The checkout goes back to the default branch only on the way that merged.** A `finally` here
|
|
319
|
+
// would check the default branch out after a red check too — and `docs/observations.md` would then
|
|
320
|
+
// revert to main's content, leaving the appended lines on a branch nothing in this checkout points
|
|
321
|
+
// at any more. The next flush would read `has_ledger_change` as false and report `clean`, which is
|
|
322
|
+
// the silent loss the refusals above exist to prevent. Left on the branch, the refusal fires.
|
|
323
|
+
//
|
|
324
|
+
// With auto-merge on, a failed wait no longer strands the lines for good — GitHub still merges once
|
|
325
|
+
// the checks pass (joshuafolkken/kit#2497) — but the checkout stays on the branch all the same,
|
|
326
|
+
// because only a merge this command has seen makes returning to the default branch safe.
|
|
327
|
+
async function land(
|
|
328
|
+
branch_name: string,
|
|
329
|
+
default_branch: string,
|
|
330
|
+
is_auto_merge: boolean,
|
|
331
|
+
): Promise<void> {
|
|
332
|
+
try {
|
|
333
|
+
await observations_flush_landing.wait_for_landing(branch_name, is_auto_merge)
|
|
334
|
+
} catch (error) {
|
|
335
|
+
throw new Error(stranded_branch_message(branch_name, message_of(error)), { cause: error })
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
await return_to_default_branch(default_branch)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
async function open_and_land(branch_name: string, default_branch: string): Promise<void> {
|
|
342
|
+
console.info(await open_pull_request(branch_name, default_branch))
|
|
343
|
+
|
|
344
|
+
const is_auto_merge = await observations_flush_landing.request_auto_merge(branch_name)
|
|
345
|
+
|
|
346
|
+
await land(branch_name, default_branch, is_auto_merge)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function merged_message(branch_name: string): string {
|
|
350
|
+
return `merged \`${branch_name}\` — the appended observations are on the default branch`
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function broken_lines_message(broken: ReadonlyArray<BrokenLine>): string {
|
|
354
|
+
const rows = broken.map((entry) => ` ${entry.line}\n ↳ ${entry.reason}`).join('\n')
|
|
355
|
+
|
|
356
|
+
return `\`${OBSERVATION_LEDGER_PATH}\` has ${String(broken.length)} line(s) that break the ledger grammar, so \`pnpm josh observations:flush\` stops rather than committing them:\n${rows}`
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// **A malformed line is refused before a branch is cut, not after.** The ledger path was collected
|
|
360
|
+
// without a line ever being parsed (joshuafolkken/kit#2123), so a broken append could ride a flush
|
|
361
|
+
// through; validating here keeps the committed ledger to its grammar.
|
|
362
|
+
async function refuse_broken_ledger(): Promise<void> {
|
|
363
|
+
const broken = observation_ledger_line.broken_ledger_lines(
|
|
364
|
+
await readFile(OBSERVATION_LEDGER_PATH, 'utf8'),
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
if (broken.length > 0) throw new Error(broken_lines_message(broken))
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// **Nothing pulls in front of the branch, and that is deliberate.** The ledger is dirty by
|
|
371
|
+
// definition at this point, so `git pull --ff-only` aborts on it in exactly the case a pull would
|
|
372
|
+
// have been for — an upstream flush that already advanced the ledger — and reports a failure about
|
|
373
|
+
// the wrong thing (joshuafolkken/kit#1756's second review round). So the freshness of the start
|
|
374
|
+
// point is read from the remote first (joshuafolkken/kit#1768), and `catch_up_default` fast-forwards
|
|
375
|
+
// only where git can do it without touching the ledger (joshuafolkken/kit#2462): a default branch
|
|
376
|
+
// that predates another merged flush still stops here — before a branch is cut — rather than opening
|
|
377
|
+
// a pull request that cannot merge. An earlier flush pull request still open is checked for the same
|
|
378
|
+
// reason (joshuafolkken/kit#2497): a branch cut beside it conflicts with it at the ledger's tail.
|
|
379
|
+
async function flush(now: Date): Promise<string> {
|
|
380
|
+
const status_output = await git_command.status()
|
|
381
|
+
const default_branch = await refuse_unsafe_flush(status_output)
|
|
382
|
+
|
|
383
|
+
if (!has_ledger_change(status_output)) return CLEAN_MESSAGE
|
|
384
|
+
|
|
385
|
+
await refuse_broken_ledger()
|
|
386
|
+
|
|
387
|
+
const deferred = await observations_flush_landing.refuse_open_flush(BRANCH_PREFIX)
|
|
388
|
+
if (deferred !== undefined) return deferred
|
|
389
|
+
|
|
390
|
+
await catch_up_default(default_branch)
|
|
391
|
+
|
|
392
|
+
const branch_name = branch_name_for(timestamp_for(now))
|
|
393
|
+
|
|
394
|
+
await open_and_land(branch_name, default_branch)
|
|
395
|
+
|
|
396
|
+
return merged_message(branch_name)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const observations_flush = {
|
|
400
|
+
behind_default_message,
|
|
401
|
+
branch_name_for,
|
|
402
|
+
broken_lines_message,
|
|
403
|
+
CLEAN_MESSAGE,
|
|
404
|
+
COMMIT_MESSAGE,
|
|
405
|
+
empty_flush_message,
|
|
406
|
+
flush,
|
|
407
|
+
flush_branch_message,
|
|
408
|
+
has_ledger_change,
|
|
409
|
+
merged_message,
|
|
410
|
+
off_default_message,
|
|
411
|
+
other_changed_paths,
|
|
412
|
+
other_changes_message,
|
|
413
|
+
pull_request_body,
|
|
414
|
+
rejected_commit_message,
|
|
415
|
+
roll_back_failure_message,
|
|
416
|
+
stranded_branch_message,
|
|
417
|
+
timestamp_for,
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export { observations_flush }
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { yaml_document } from '#scripts/yaml/yaml-document'
|
|
2
|
+
import { overrides_check } from './overrides-logic'
|
|
3
|
+
import { lockfile_importers_schema, type LockfileImporter } from './schemas'
|
|
4
|
+
|
|
5
|
+
// The importer sections whose entries pnpm rewrites through `overrides` before resolving.
|
|
6
|
+
const DEPENDENCY_GROUPS = ['dependencies', 'devDependencies', 'optionalDependencies'] as const
|
|
7
|
+
|
|
8
|
+
// Specifier protocols that name a source rather than a registry range. An override cannot rewrite
|
|
9
|
+
// one into a comparable range, so comparing it against an override value could only ever produce a
|
|
10
|
+
// false mismatch.
|
|
11
|
+
const NON_REGISTRY_PREFIXES = ['link:', 'file:', 'workspace:', 'catalog:', 'npm:', '$']
|
|
12
|
+
|
|
13
|
+
interface SpecifierMismatch {
|
|
14
|
+
importer: string
|
|
15
|
+
name: string
|
|
16
|
+
lockfile_specifier: string
|
|
17
|
+
override: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function is_non_registry(value: string): boolean {
|
|
21
|
+
return NON_REGISTRY_PREFIXES.some((prefix) => value.startsWith(prefix))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// A key carrying a version selector (`pkg@>=5`) applies only to the dependents whose declared range
|
|
25
|
+
// matches the selector, which cannot be decided from the lockfile alone. Only a bare key rewrites
|
|
26
|
+
// every occurrence of the package, so only a bare key yields a specifier the importer must equal.
|
|
27
|
+
function is_comparable_entry(key: string, value: string): boolean {
|
|
28
|
+
return overrides_check.extract_package_name(key) === key && !is_non_registry(value)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function read_unconditional_overrides(overrides: Record<string, string>): Map<string, string> {
|
|
32
|
+
const comparable = Object.entries(overrides).filter(([key, value]) =>
|
|
33
|
+
is_comparable_entry(key, value),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
return new Map(comparable)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function find_entry_mismatch(
|
|
40
|
+
importer: string,
|
|
41
|
+
name: string,
|
|
42
|
+
specifier: string,
|
|
43
|
+
override: string | undefined,
|
|
44
|
+
): Array<SpecifierMismatch> {
|
|
45
|
+
if (override === undefined) return []
|
|
46
|
+
if (is_non_registry(specifier)) return []
|
|
47
|
+
if (specifier === override) return []
|
|
48
|
+
|
|
49
|
+
return [{ importer, name, lockfile_specifier: specifier, override }]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function find_importer_mismatches(
|
|
53
|
+
importer: string,
|
|
54
|
+
sections: LockfileImporter,
|
|
55
|
+
overrides: Map<string, string>,
|
|
56
|
+
): Array<SpecifierMismatch> {
|
|
57
|
+
return DEPENDENCY_GROUPS.flatMap((group) =>
|
|
58
|
+
Object.entries(sections[group] ?? {}).flatMap(([name, entry]) =>
|
|
59
|
+
find_entry_mismatch(importer, name, entry.specifier, overrides.get(name)),
|
|
60
|
+
),
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function read_document_importers(
|
|
65
|
+
document: Record<string, unknown>,
|
|
66
|
+
): Array<[string, LockfileImporter]> {
|
|
67
|
+
return Object.entries(lockfile_importers_schema.parse(document).importers ?? {})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function read_importers(lockfile_content: string): Array<[string, LockfileImporter]> {
|
|
71
|
+
return yaml_document
|
|
72
|
+
.parse_yaml_documents(lockfile_content)
|
|
73
|
+
.flatMap((document) => read_document_importers(document))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Compares what the lockfile records against what the overrides declare. pnpm writes the
|
|
77
|
+
// override-applied specifier into each importer entry, so a difference means the lockfile no longer
|
|
78
|
+
// matches the manifest pnpm derives — the state that fails `pnpm install --frozen-lockfile` in CI
|
|
79
|
+
// while `trustLockfile: true` keeps the same command quiet locally (kit #744).
|
|
80
|
+
function find_specifier_mismatches(
|
|
81
|
+
lockfile_content: string,
|
|
82
|
+
overrides: Record<string, string>,
|
|
83
|
+
): Array<SpecifierMismatch> {
|
|
84
|
+
const unconditional = read_unconditional_overrides(overrides)
|
|
85
|
+
if (unconditional.size === 0) return []
|
|
86
|
+
|
|
87
|
+
return read_importers(lockfile_content).flatMap(([importer, sections]) =>
|
|
88
|
+
find_importer_mismatches(importer, sections, unconditional),
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function format_mismatch_line(mismatch: SpecifierMismatch): string {
|
|
93
|
+
const recorded = `lockfile ${mismatch.lockfile_specifier}, override ${mismatch.override}`
|
|
94
|
+
|
|
95
|
+
return ` ${mismatch.name} (importer ${mismatch.importer}): ${recorded}`
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function format_mismatch_lines(mismatches: ReadonlyArray<SpecifierMismatch>): Array<string> {
|
|
99
|
+
return mismatches.map((mismatch) => format_mismatch_line(mismatch))
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const lockfile_overrides = { find_specifier_mismatches, format_mismatch_lines }
|
|
103
|
+
|
|
104
|
+
export type { SpecifierMismatch }
|
|
105
|
+
export { lockfile_overrides }
|