@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,91 @@
|
|
|
1
|
+
import { run_preflight } from '#scripts/run/run-preflight'
|
|
2
|
+
import type { StashEntry } from './git-stash'
|
|
3
|
+
|
|
4
|
+
// Which stashes nobody is coming back for (joshuafolkken/kit#2505). A parked or paused run pushes its
|
|
5
|
+
// work with a message `josh stash:pop` later targets, but an issue closed by another route leaves that
|
|
6
|
+
// entry with no run to pop it — the pile #2168 sorted by hand. This reads the owning issue out of each
|
|
7
|
+
// entry's subject so the closed ones, and the ones with no readable owner, can be put in front of a
|
|
8
|
+
// person. **Nothing here drops a stash**: the entry may hold work nobody recovered, so the decision stays
|
|
9
|
+
// with the person the report is printed for.
|
|
10
|
+
|
|
11
|
+
// The three shapes a run's stash subject takes, tried in this order. An explicit `#N` in the message
|
|
12
|
+
// (`backlogrun: parked #N`) names the issue outright; a message that
|
|
13
|
+
// opens with `N: ` is `git_stash.work_message`'s; and a lane branch (`On N-lane: …`) names it by where
|
|
14
|
+
// the work was pushed from. A subject is `On <branch>: <message>` (or `WIP on <branch>: …` without
|
|
15
|
+
// `-m`), and a branch name carries no `:`, so `(?:^|: )` anchors the message start either way.
|
|
16
|
+
const MESSAGE_PATTERNS: ReadonlyArray<RegExp> = [/#(?<issue>\d+)\b/u, /(?:^|: )(?<issue>\d+): /u]
|
|
17
|
+
const BRANCH_PATTERN = /^(?:WIP on|On) (?<issue>\d+)-lane: /u
|
|
18
|
+
// A stash pushed without `-m` lists as `WIP on <branch>: <sha> <HEAD's commit subject>` — text no run
|
|
19
|
+
// wrote. This repository's commit subjects end in `#N` and merges read `Merge pull request #N`, so a
|
|
20
|
+
// message pattern there would name the last merged pull request, closed by definition, as the owner of
|
|
21
|
+
// live work. Only the branch can name the owner of such an entry.
|
|
22
|
+
const WIP_PREFIX = 'WIP on '
|
|
23
|
+
// `run:hold` stashes an earlier run's leftovers before claiming the tree for `#N`, so the `#N` in that
|
|
24
|
+
// message is the run that found the work, not its owner — the entry has none, and no run pops it.
|
|
25
|
+
const NO_PATTERNS: ReadonlyArray<RegExp> = []
|
|
26
|
+
|
|
27
|
+
const HEADER =
|
|
28
|
+
'Stashes whose issue is closed, or whose owner cannot be read — decide for each whether to revive or discard it (none is dropped automatically):'
|
|
29
|
+
const FOOTER =
|
|
30
|
+
'Revive: `pnpm josh stash:pop "<message>"` · Discard: `git stash drop <selector>` — re-read the selector first, the stack is shared by every lane.'
|
|
31
|
+
const UNKNOWN_OWNER = 'owner unknown'
|
|
32
|
+
const COLUMN_SEPARATOR = ' '
|
|
33
|
+
const LINE_SEPARATOR = '\n'
|
|
34
|
+
|
|
35
|
+
interface OrphanStash {
|
|
36
|
+
selector: string
|
|
37
|
+
subject: string
|
|
38
|
+
issue: string | undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function patterns_for(subject: string): ReadonlyArray<RegExp> {
|
|
42
|
+
if (subject.includes(run_preflight.STASH_LABEL_PREFIX)) return NO_PATTERNS
|
|
43
|
+
|
|
44
|
+
return subject.startsWith(WIP_PREFIX) ? [BRANCH_PATTERN] : [...MESSAGE_PATTERNS, BRANCH_PATTERN]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function issue_of(subject: string): string | undefined {
|
|
48
|
+
for (const pattern of patterns_for(subject)) {
|
|
49
|
+
const issue = pattern.exec(subject)?.groups?.['issue']
|
|
50
|
+
|
|
51
|
+
if (issue !== undefined) return issue
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return undefined
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Each owning issue once, so a stack holding two entries for one issue reads its state once.
|
|
58
|
+
function issues_of(entries: ReadonlyArray<StashEntry>): Array<string> {
|
|
59
|
+
const issues = entries.map((entry) => issue_of(entry.subject))
|
|
60
|
+
|
|
61
|
+
return [...new Set(issues.filter((issue): issue is string => issue !== undefined))]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// An entry is reported when its issue is in `closed`, or when it names no issue at all — an entry with
|
|
65
|
+
// no owner is exactly the one no run will ever pop. An open issue's entry is still some run's to resume.
|
|
66
|
+
function orphans(
|
|
67
|
+
entries: ReadonlyArray<StashEntry>,
|
|
68
|
+
closed: ReadonlySet<string>,
|
|
69
|
+
): Array<OrphanStash> {
|
|
70
|
+
return entries
|
|
71
|
+
.map((entry) => ({ ...entry, issue: issue_of(entry.subject) }))
|
|
72
|
+
.filter((entry) => entry.issue === undefined || closed.has(entry.issue))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function format_line(orphan: OrphanStash): string {
|
|
76
|
+
const owner = orphan.issue === undefined ? UNKNOWN_OWNER : `#${orphan.issue} closed`
|
|
77
|
+
|
|
78
|
+
return ` ${[orphan.selector, owner, orphan.subject].join(COLUMN_SEPARATOR)}`
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// `undefined` when there is nothing to report, so a clean stack prints nothing at all.
|
|
82
|
+
function format_report(found: ReadonlyArray<OrphanStash>): string | undefined {
|
|
83
|
+
if (found.length === 0) return undefined
|
|
84
|
+
|
|
85
|
+
return [HEADER, ...found.map((orphan) => format_line(orphan)), FOOTER].join(LINE_SEPARATOR)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const stash_orphans = { format_report, issue_of, issues_of, orphans }
|
|
89
|
+
|
|
90
|
+
export type { OrphanStash }
|
|
91
|
+
export { stash_orphans }
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util'
|
|
2
|
+
|
|
3
|
+
// `josh stash:pop` turns its `argv` into a single request: the message of the stash to pop. Parsing
|
|
4
|
+
// lives here, acting on the stack lives in `stash-pop-cli.ts`, and a malformed command line is
|
|
5
|
+
// `undefined` rather than a guessed intent — a pop run on a misread argument would take the wrong
|
|
6
|
+
// entry off a stack shared by every lane (joshuafolkken/kit#2050).
|
|
7
|
+
|
|
8
|
+
const USAGE = 'Usage: josh stash:pop "<message>" [--dir <path>]'
|
|
9
|
+
|
|
10
|
+
// `--dir` points the pop at a lane's work tree; without it the pop lands in the current checkout.
|
|
11
|
+
const OPTIONS = { dir: { type: 'string' } } as const
|
|
12
|
+
|
|
13
|
+
interface ParsedValues {
|
|
14
|
+
values: { dir?: string }
|
|
15
|
+
positionals: ReadonlyArray<string>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface Request {
|
|
19
|
+
message: string
|
|
20
|
+
dir: string | undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function read_arguments(argv: ReadonlyArray<string>): ParsedValues | undefined {
|
|
24
|
+
try {
|
|
25
|
+
const parsed = parseArgs({
|
|
26
|
+
args: [...argv],
|
|
27
|
+
options: OPTIONS,
|
|
28
|
+
strict: true,
|
|
29
|
+
allowPositionals: true,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
return { values: parsed.values, positionals: parsed.positionals }
|
|
33
|
+
} catch {
|
|
34
|
+
return undefined
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// The message is the sole positional and must be a non-empty string: an empty message matches every
|
|
39
|
+
// stash pushed without a message, which is exactly the ambiguity this command exists to refuse.
|
|
40
|
+
function message_of(positionals: ReadonlyArray<string>): string | undefined {
|
|
41
|
+
if (positionals.length !== 1) return undefined
|
|
42
|
+
|
|
43
|
+
const [message] = positionals
|
|
44
|
+
|
|
45
|
+
return message === '' ? undefined : message
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function to_request(parsed: ParsedValues): Request | undefined {
|
|
49
|
+
const message = message_of(parsed.positionals)
|
|
50
|
+
|
|
51
|
+
if (message === undefined) return undefined
|
|
52
|
+
|
|
53
|
+
return { message, dir: parsed.values.dir }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const stash_pop_args = { USAGE, message_of, read_arguments, to_request }
|
|
57
|
+
|
|
58
|
+
export type { Request }
|
|
59
|
+
export { stash_pop_args }
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url'
|
|
2
|
+
import { git_stash } from './git-stash'
|
|
3
|
+
import { stash_pop_args, type Request } from './stash-pop-args'
|
|
4
|
+
|
|
5
|
+
// `josh stash:pop "<message>"` — pop the stash whose message matches, and no other
|
|
6
|
+
// (joshuafolkken/kit#2050). The stash stack is shared by every working tree of the repository, so a
|
|
7
|
+
// procedure that pops by position takes whatever another lane last pushed. This resolves the
|
|
8
|
+
// selector from the message and pops that entry alone; no match and more than one match are both
|
|
9
|
+
// refusals rather than a guess at which was meant.
|
|
10
|
+
|
|
11
|
+
const POPPED_VERDICT = 'popped'
|
|
12
|
+
const CONFLICTED_VERDICT = 'conflicted'
|
|
13
|
+
const NO_MATCH_VERDICT = 'no-match'
|
|
14
|
+
const AMBIGUOUS_VERDICT = 'ambiguous'
|
|
15
|
+
|
|
16
|
+
const SUCCESS_EXIT_CODE = 0
|
|
17
|
+
const FAILURE_EXIT_CODE = 1
|
|
18
|
+
const ARGV_OFFSET = 2
|
|
19
|
+
|
|
20
|
+
function report(verdict: string, detail: string, code: number): number {
|
|
21
|
+
console.info(verdict)
|
|
22
|
+
console.error(detail)
|
|
23
|
+
|
|
24
|
+
return code
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function refuse(): number {
|
|
28
|
+
console.error(stash_pop_args.USAGE)
|
|
29
|
+
|
|
30
|
+
return FAILURE_EXIT_CODE
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// A pop that leaves unmerged paths applied the stash and only needs the conflicts resolved, so it is
|
|
34
|
+
// reported `conflicted` at exit 0 rather than raised as an unknown failure (joshuafolkken/kit#2050);
|
|
35
|
+
// any other pop error is re-thrown for `run` to report. `has_conflict` reads the tree the pop wrote.
|
|
36
|
+
async function pop_selected(selector: string, directory: string | undefined): Promise<number> {
|
|
37
|
+
try {
|
|
38
|
+
await git_stash.pop(selector, directory)
|
|
39
|
+
} catch (error) {
|
|
40
|
+
if (await git_stash.has_conflict(directory)) {
|
|
41
|
+
const detail = `Popped ${selector} with conflicts — resolve them.`
|
|
42
|
+
|
|
43
|
+
return report(CONFLICTED_VERDICT, detail, SUCCESS_EXIT_CODE)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
throw error
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return report(POPPED_VERDICT, `Popped ${selector}.`, SUCCESS_EXIT_CODE)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function answer(request: Request): Promise<number> {
|
|
53
|
+
const selection = git_stash.select(await git_stash.list(request.dir), request.message)
|
|
54
|
+
|
|
55
|
+
if (selection.kind === 'none') {
|
|
56
|
+
return report(NO_MATCH_VERDICT, `No stash matches "${request.message}".`, FAILURE_EXIT_CODE)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (selection.kind === 'ambiguous') {
|
|
60
|
+
const detail = `More than one stash matches "${request.message}": ${selection.selectors.join(', ')}.`
|
|
61
|
+
|
|
62
|
+
return report(AMBIGUOUS_VERDICT, detail, FAILURE_EXIT_CODE)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return await pop_selected(selection.selector, request.dir)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function report_unknown(error: unknown): number {
|
|
69
|
+
console.error(error instanceof Error ? error.message : String(error))
|
|
70
|
+
|
|
71
|
+
return FAILURE_EXIT_CODE
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
75
|
+
const parsed = stash_pop_args.read_arguments(argv)
|
|
76
|
+
|
|
77
|
+
if (parsed === undefined) return refuse()
|
|
78
|
+
|
|
79
|
+
const request = stash_pop_args.to_request(parsed)
|
|
80
|
+
|
|
81
|
+
if (request === undefined) return refuse()
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
return await answer(request)
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return report_unknown(error)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
91
|
+
process.exitCode = await run(argv)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const stash_pop_cli = {
|
|
95
|
+
AMBIGUOUS_VERDICT,
|
|
96
|
+
CONFLICTED_VERDICT,
|
|
97
|
+
NO_MATCH_VERDICT,
|
|
98
|
+
POPPED_VERDICT,
|
|
99
|
+
main,
|
|
100
|
+
run,
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
104
|
+
|
|
105
|
+
export { stash_pop_cli }
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import { gh_spawn } from '#scripts/gh/gh-spawn'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
|
|
4
|
+
const TELEGRAM_API_BASE = 'https://api.telegram.org'
|
|
5
|
+
|
|
6
|
+
const telegram_environment_schema = z.object({
|
|
7
|
+
telegram_bot_token: z.string().min(1, { message: 'TELEGRAM_BOT_TOKEN is required' }),
|
|
8
|
+
telegram_chat_id: z.string().min(1, { message: 'TELEGRAM_CHAT_ID is required' }),
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
// **`warning` is not `failure`** (joshuafolkken/kit#1628). It names a run that finished and merged,
|
|
12
|
+
// alongside something that did not work — a post-merge cleanup step that could not complete is one.
|
|
13
|
+
// Sending `failure` (❌) there would say the merge failed, which is false and is
|
|
14
|
+
// the more expensive lie of the two; sending `completion` (✅) twice says nothing went wrong, which
|
|
15
|
+
// is the silence this type exists to end.
|
|
16
|
+
// **`stalled` is not `warning`** (joshuafolkken/kit#2359). `warning` names a run that *finished* and
|
|
17
|
+
// merged alongside something that did not work; a stall is the opposite — the run is alive and has not
|
|
18
|
+
// finished, it has simply stopped advancing while ready work waits for a free lane. The ⏳ icon says
|
|
19
|
+
// exactly that: not done, not broken, just not moving.
|
|
20
|
+
// **`stranded` is not `stalled`** (joshuafolkken/kit#2375). A stall is a *live* run that is not
|
|
21
|
+
// dispatching; a strand is the step before it — the run's own driver is gone. The session that cut the
|
|
22
|
+
// budget handed it off and died, no successor claimed it, and no supervisor is watching, so nothing can
|
|
23
|
+
// take the next step at all. The 🚨 icon says a run needs a hand, not that ready work is merely waiting.
|
|
24
|
+
type TelegramTaskType =
|
|
25
|
+
| 'planning'
|
|
26
|
+
| 'completion'
|
|
27
|
+
| 'failure'
|
|
28
|
+
| 'warning'
|
|
29
|
+
| 'kickoff_retry'
|
|
30
|
+
| 'confirmation'
|
|
31
|
+
| 'stalled'
|
|
32
|
+
| 'stranded'
|
|
33
|
+
|
|
34
|
+
interface TelegramSendInput {
|
|
35
|
+
task_type: TelegramTaskType
|
|
36
|
+
repo_name: string | undefined
|
|
37
|
+
issue_title: string | undefined
|
|
38
|
+
body: string | undefined
|
|
39
|
+
issue_url: string | undefined
|
|
40
|
+
pr_url: string | undefined
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface TelegramConfig {
|
|
44
|
+
bot_token: string
|
|
45
|
+
chat_id: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface TaskDefinition {
|
|
49
|
+
icon: string
|
|
50
|
+
label: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const TASK_DEFINITIONS: Record<TelegramTaskType, TaskDefinition> = {
|
|
54
|
+
planning: { icon: '📋', label: 'Planning' },
|
|
55
|
+
completion: { icon: '✅', label: 'Completion' },
|
|
56
|
+
failure: { icon: '❌', label: 'Failure' },
|
|
57
|
+
warning: { icon: '⚠️', label: 'Completed with a warning' },
|
|
58
|
+
kickoff_retry: { icon: '🔄', label: 'Kickoff retry' },
|
|
59
|
+
confirmation: { icon: '⏸️', label: 'Confirmation required' },
|
|
60
|
+
stalled: { icon: '⏳', label: 'Ready work is sitting undispatched' },
|
|
61
|
+
stranded: { icon: '🚨', label: 'Run stranded — nobody is driving it' },
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const NOT_CONFIGURED_PREFIX = 'Telegram is not configured'
|
|
65
|
+
const SEND_FAILED_PREFIX = 'Telegram notification failed'
|
|
66
|
+
const REDACTED = '<redacted>'
|
|
67
|
+
const UNKNOWN_ERROR_TEXT = 'unknown error'
|
|
68
|
+
|
|
69
|
+
function parse_environment_string(value: string | undefined): string {
|
|
70
|
+
return value?.trim() ?? ''
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Not `git_gh_helpers.get_error_message_with_stderr`, which the two nearest callers use: that one
|
|
74
|
+
// appends the `stderr` an execa-shaped error carries, and nothing in this module runs a subprocess —
|
|
75
|
+
// so it would pull a subprocess concern into an HTTP one and degrade to exactly this line anyway.
|
|
76
|
+
// **The `cause` is read, not only the message.** A `fetch` rejection's own message is the bare string
|
|
77
|
+
// `fetch failed`; what says whether this was DNS, a refused connection or a timeout lives one level
|
|
78
|
+
// down. Reporting the top line alone would exit non-zero with nothing a reader can act on, which is
|
|
79
|
+
// half of what joshuafolkken/kit#1564 set out to fix. Redaction runs over the joined text, so the
|
|
80
|
+
// deeper line is covered exactly as the top one is.
|
|
81
|
+
function join_cause(error: Error): string {
|
|
82
|
+
const { cause } = error
|
|
83
|
+
|
|
84
|
+
if (!(cause instanceof Error) || cause.message.length === 0) return error.message
|
|
85
|
+
|
|
86
|
+
return `${error.message}: ${cause.message}`
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// A non-`Error` throw is stated rather than stringified: `String({})` is `[object Object]`, which
|
|
90
|
+
// tells a reader nothing and is what `typescript:S6551` flags.
|
|
91
|
+
function describe_non_error(error: unknown): string {
|
|
92
|
+
return typeof error === 'string' ? error : UNKNOWN_ERROR_TEXT
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function describe_error(error: unknown): string {
|
|
96
|
+
if (error instanceof Error) return join_cause(error)
|
|
97
|
+
|
|
98
|
+
return describe_non_error(error)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// **The message alone, for an error this module built itself.** What `send` throws already carries
|
|
102
|
+
// the joined cause inside its own message, and its `cause` is a redacted copy of that same text — so
|
|
103
|
+
// walking the chain again here printed the whole reason twice on one line.
|
|
104
|
+
function describe_symptom(error: unknown): string {
|
|
105
|
+
return error instanceof Error ? error.message : describe_non_error(error)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// The request URL carries the bot token in its own path, so an error raised anywhere near the
|
|
109
|
+
// request can carry a credential into a log. Both values are taken out of the text before it leaves
|
|
110
|
+
// this module, so no caller has to remember to do it (joshuafolkken/kit#1564).
|
|
111
|
+
function redact_credentials(text: string, config: TelegramConfig): string {
|
|
112
|
+
return text.split(config.bot_token).join(REDACTED).split(config.chat_id).join(REDACTED)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// **Missing credentials are a failure, not a skip** (joshuafolkken/kit#1564). This used to warn and
|
|
116
|
+
// return `undefined`, and `send` then returned quietly — so a run with no credentials was
|
|
117
|
+
// indistinguishable from one whose notification arrived. Until this Issue the mandatory
|
|
118
|
+
// `--env-file=.env` flag on `josh notify` and `josh followup` made a machine without that file die
|
|
119
|
+
// before node started, which was loud by accident; with the flag relaxed to the optional form, this
|
|
120
|
+
// is where the noise has to come from instead.
|
|
121
|
+
//
|
|
122
|
+
// The message names the variables and never their values — the schema's own messages are the
|
|
123
|
+
// variable names, so nothing read out of the environment reaches it.
|
|
124
|
+
function load_config(): TelegramConfig {
|
|
125
|
+
const result = telegram_environment_schema.safeParse({
|
|
126
|
+
telegram_bot_token: parse_environment_string(process.env['TELEGRAM_BOT_TOKEN']),
|
|
127
|
+
telegram_chat_id: parse_environment_string(process.env['TELEGRAM_CHAT_ID']),
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
if (!result.success) {
|
|
131
|
+
const error_list = result.error.issues.map((issue) => issue.message).join(', ')
|
|
132
|
+
|
|
133
|
+
throw new Error(`${NOT_CONFIGURED_PREFIX}: ${error_list}`)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { bot_token: result.data.telegram_bot_token, chat_id: result.data.telegram_chat_id }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function build_header(task_type: TelegramTaskType, repo_name: string | undefined): string {
|
|
140
|
+
const { icon, label } = TASK_DEFINITIONS[task_type]
|
|
141
|
+
if (repo_name === undefined || repo_name.length === 0) return `${icon} ${label}`
|
|
142
|
+
|
|
143
|
+
return `${icon} ${repo_name}: ${label}`
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function push_if_present(target: Array<string>, value: string | undefined): void {
|
|
147
|
+
if (value !== undefined && value.length > 0) target.push(value)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function build_title_block(input: TelegramSendInput): string {
|
|
151
|
+
const lines: Array<string> = [build_header(input.task_type, input.repo_name)]
|
|
152
|
+
|
|
153
|
+
push_if_present(lines, input.issue_title)
|
|
154
|
+
|
|
155
|
+
return lines.join('\n')
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function append_url(parts: Array<string>, label: string, value: string | undefined): void {
|
|
159
|
+
if (value !== undefined && value.length > 0) parts.push(`${label}: ${value}`)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function build_url_parts(input: TelegramSendInput): Array<string> {
|
|
163
|
+
const parts: Array<string> = []
|
|
164
|
+
|
|
165
|
+
append_url(parts, 'Issue', input.issue_url)
|
|
166
|
+
append_url(parts, 'PR', input.pr_url)
|
|
167
|
+
|
|
168
|
+
return parts
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function build_blocks(input: TelegramSendInput): Array<string> {
|
|
172
|
+
const blocks: Array<string> = [build_title_block(input)]
|
|
173
|
+
|
|
174
|
+
push_if_present(blocks, input.body)
|
|
175
|
+
blocks.push(...build_url_parts(input))
|
|
176
|
+
|
|
177
|
+
return blocks
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function build_text(input: TelegramSendInput): string {
|
|
181
|
+
return build_blocks(input).join('\n\n')
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function post_message(config: TelegramConfig, text: string): Promise<void> {
|
|
185
|
+
const url = `${TELEGRAM_API_BASE}/bot${config.bot_token}/sendMessage`
|
|
186
|
+
const response = await fetch(url, {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
headers: { 'Content-Type': 'application/json' },
|
|
189
|
+
body: JSON.stringify({ chat_id: config.chat_id, text }),
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
throw new Error(`Telegram API error: ${String(response.status)} ${response.statusText}`)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// **The cause is re-wrapped rather than passed through** (joshuafolkken/kit#1564). The chain is kept,
|
|
198
|
+
// because a symptom error that drops its cause loses where the failure came from — but the original
|
|
199
|
+
// is the one object on this path nothing has redacted, and `git_error.handle` prints a cause's own
|
|
200
|
+
// message straight to the console. Both layers therefore carry the same already-redacted text.
|
|
201
|
+
function build_send_failure(error: unknown, config: TelegramConfig): Error {
|
|
202
|
+
const reason = redact_credentials(describe_error(error), config)
|
|
203
|
+
|
|
204
|
+
return new Error(`${SEND_FAILED_PREFIX}: ${reason}`, { cause: new Error(reason) })
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// **The strict form.** A caller whose whole job is the notification has nothing left to report when
|
|
208
|
+
// this fails, so it throws and `pnpm josh notify` exits non-zero. joshuafolkken/kit#1564 measured
|
|
209
|
+
// the state this replaces: three notifications lost to a `504 Gateway Time-out`, each one printing a
|
|
210
|
+
// warning and exiting 0, so a message that reached nobody looked exactly like one that arrived.
|
|
211
|
+
//
|
|
212
|
+
// The failure it throws carries a `cause`, and that cause is redacted too — see `build_send_failure`.
|
|
213
|
+
async function send(input: TelegramSendInput): Promise<void> {
|
|
214
|
+
const config = load_config()
|
|
215
|
+
const text = build_text(input)
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
await post_message(config, text)
|
|
219
|
+
} catch (error) {
|
|
220
|
+
throw build_send_failure(error, config)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
console.info('📱 Telegram notification sent.')
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// **The tolerant form**, for a caller whose job is something other than the notification.
|
|
227
|
+
// `followup` sends the completion message on its way to the merge, and a gateway timeout at
|
|
228
|
+
// Telegram is not a reason to leave a reviewed, green pull request unmerged — joshuafolkken/kit#1564
|
|
229
|
+
// measured exactly that 504 with six lanes running at once. So the failure is reported and the run
|
|
230
|
+
// carries on.
|
|
231
|
+
//
|
|
232
|
+
// **Reported under `❗` on stderr, in its own block, with the caller's own recovery line** — the bar
|
|
233
|
+
// joshuafolkken/kit#1539 set for a step that failed and was not allowed to end the run. The `⚠️`
|
|
234
|
+
// this used to print is what every routine notice prints, which is how the failure got buried.
|
|
235
|
+
//
|
|
236
|
+
// `recovery` is the caller's because only the caller knows one. It is `string | undefined` and not
|
|
237
|
+
// optional for the reason `CleanupStep.recovery` is: a caller with no command that finishes the job
|
|
238
|
+
// has to say so rather than leave the field off, and naming a command that would not work sends the
|
|
239
|
+
// reader somewhere useless.
|
|
240
|
+
//
|
|
241
|
+
// **Not routed through `git_followup_cleanup`**, which is that Issue's mechanism: it guards the
|
|
242
|
+
// steps a merge has already earned and says "failed after the merge" in its own wording, while this
|
|
243
|
+
// send happens *before* the merge. Borrowing it would print a sentence that is not true.
|
|
244
|
+
function report_send_failure(error: unknown, recovery: string | undefined): void {
|
|
245
|
+
console.error('')
|
|
246
|
+
console.error(`❗ ${describe_symptom(error)}`)
|
|
247
|
+
console.error(' Nobody was notified, and the run carried on.')
|
|
248
|
+
|
|
249
|
+
if (recovery !== undefined) console.error(` Recovery: ${recovery}`)
|
|
250
|
+
|
|
251
|
+
console.error('')
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async function send_or_report(
|
|
255
|
+
input: TelegramSendInput,
|
|
256
|
+
recovery: string | undefined,
|
|
257
|
+
): Promise<boolean> {
|
|
258
|
+
try {
|
|
259
|
+
await send(input)
|
|
260
|
+
|
|
261
|
+
return true
|
|
262
|
+
} catch (error) {
|
|
263
|
+
report_send_failure(error, recovery)
|
|
264
|
+
|
|
265
|
+
return false
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Long enough that a stalled `gh` never holds a warning back, short enough that the message still
|
|
270
|
+
// names the repository it is about.
|
|
271
|
+
const REPO_LOOKUP_TIMEOUT_MS = 5000
|
|
272
|
+
|
|
273
|
+
interface WarningInput {
|
|
274
|
+
issue_title: string
|
|
275
|
+
body: string
|
|
276
|
+
recovery: string
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Warn that something an unattended run depended on did not work.
|
|
281
|
+
*
|
|
282
|
+
* **One function rather than one per caller** (joshuafolkken/kit#1749). Every warning fills in the
|
|
283
|
+
* same four fields the same way — the task type, the repository looked up under the same bound, and
|
|
284
|
+
* two urls that are never known here — so a second caller composing its own would be free to drift
|
|
285
|
+
* on the one field that is not obvious: a repository lookup with no timeout hangs the warning behind
|
|
286
|
+
* the failure it is reporting.
|
|
287
|
+
*/
|
|
288
|
+
async function warn(input: WarningInput): Promise<boolean> {
|
|
289
|
+
return await send_or_report(
|
|
290
|
+
{
|
|
291
|
+
task_type: 'warning',
|
|
292
|
+
repo_name: gh_spawn.get_repo_name_with_owner_within(REPO_LOOKUP_TIMEOUT_MS),
|
|
293
|
+
issue_title: input.issue_title,
|
|
294
|
+
body: input.body,
|
|
295
|
+
issue_url: undefined,
|
|
296
|
+
pr_url: undefined,
|
|
297
|
+
},
|
|
298
|
+
input.recovery,
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
interface ConfirmInput {
|
|
303
|
+
issue_title: string
|
|
304
|
+
body: string
|
|
305
|
+
recovery: string
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Push the ⏸️ confirmation type — a state change an unattended run made that a person now has to act
|
|
310
|
+
* on, a `backlogrun` that stopped needing a decision being the one this was written for
|
|
311
|
+
* (joshuafolkken/kit#2136).
|
|
312
|
+
*
|
|
313
|
+
* **One function rather than one per caller, for `warn`'s reason exactly**: the repository lookup
|
|
314
|
+
* under a timeout is the field a second caller composing the four itself would drift on, and a lookup
|
|
315
|
+
* with no bound hangs the confirmation behind the very stop it is announcing. The tolerant `send_or_report`
|
|
316
|
+
* is used, not the strict `send`: the run is ending either way, so a gateway timeout at Telegram must
|
|
317
|
+
* not turn a stop into a crash — the pull path (`pnpm josh run:wake --list`) is the fallback the
|
|
318
|
+
* `recovery` line names.
|
|
319
|
+
*/
|
|
320
|
+
async function confirm(input: ConfirmInput): Promise<boolean> {
|
|
321
|
+
return await send_or_report(
|
|
322
|
+
{
|
|
323
|
+
task_type: 'confirmation',
|
|
324
|
+
repo_name: gh_spawn.get_repo_name_with_owner_within(REPO_LOOKUP_TIMEOUT_MS),
|
|
325
|
+
issue_title: input.issue_title,
|
|
326
|
+
body: input.body,
|
|
327
|
+
issue_url: undefined,
|
|
328
|
+
pr_url: undefined,
|
|
329
|
+
},
|
|
330
|
+
input.recovery,
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
interface StalledInput {
|
|
335
|
+
body: string
|
|
336
|
+
recovery: string
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Push the ⏳ stalled type — ready backlog work with a free lane that nothing has dispatched for a while
|
|
341
|
+
* (joshuafolkken/kit#2359). Off-screen is the whole point: the state is invisible on the terminal until
|
|
342
|
+
* a person asks, so it reaches them where they are not watching.
|
|
343
|
+
*
|
|
344
|
+
* **`warn`'s shape exactly** — the repository looked up under the shared bound, the tolerant
|
|
345
|
+
* `send_or_report` so a gateway timeout at Telegram never fails the detector that is only reporting, and
|
|
346
|
+
* the caller's own `recovery` line. No `issue_title`: the header label already names what this is, and
|
|
347
|
+
* the body carries what is waiting, so a title line would only repeat the header.
|
|
348
|
+
*/
|
|
349
|
+
async function stalled(input: StalledInput): Promise<boolean> {
|
|
350
|
+
return await send_or_report(
|
|
351
|
+
{
|
|
352
|
+
task_type: 'stalled',
|
|
353
|
+
repo_name: gh_spawn.get_repo_name_with_owner_within(REPO_LOOKUP_TIMEOUT_MS),
|
|
354
|
+
issue_title: undefined,
|
|
355
|
+
body: input.body,
|
|
356
|
+
issue_url: undefined,
|
|
357
|
+
pr_url: undefined,
|
|
358
|
+
},
|
|
359
|
+
input.recovery,
|
|
360
|
+
)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
interface StrandedInput {
|
|
364
|
+
body: string
|
|
365
|
+
recovery: string
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Push the 🚨 stranded type — a run whose driver is gone and which nothing can advance
|
|
370
|
+
* (joshuafolkken/kit#2375). Off-screen is the whole point, as it is for `stalled`: the state is
|
|
371
|
+
* invisible on the terminal because the session that would show it has died, so the person hears about
|
|
372
|
+
* it where they are not watching, rather than by asking.
|
|
373
|
+
*
|
|
374
|
+
* **`stalled`'s shape exactly** — the repository looked up under the shared bound, the tolerant
|
|
375
|
+
* `send_or_report` so a Telegram timeout never fails the detector that is only reporting, and the
|
|
376
|
+
* caller's own `recovery` line naming the command that hands the run to a fresh supervisor. No
|
|
377
|
+
* `issue_title`: the header label already names what this is.
|
|
378
|
+
*/
|
|
379
|
+
async function stranded(input: StrandedInput): Promise<boolean> {
|
|
380
|
+
return await send_or_report(
|
|
381
|
+
{
|
|
382
|
+
task_type: 'stranded',
|
|
383
|
+
repo_name: gh_spawn.get_repo_name_with_owner_within(REPO_LOOKUP_TIMEOUT_MS),
|
|
384
|
+
issue_title: undefined,
|
|
385
|
+
body: input.body,
|
|
386
|
+
issue_url: undefined,
|
|
387
|
+
pr_url: undefined,
|
|
388
|
+
},
|
|
389
|
+
input.recovery,
|
|
390
|
+
)
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const telegram_notify = {
|
|
394
|
+
REPO_LOOKUP_TIMEOUT_MS,
|
|
395
|
+
confirm,
|
|
396
|
+
send,
|
|
397
|
+
send_or_report,
|
|
398
|
+
stalled,
|
|
399
|
+
stranded,
|
|
400
|
+
warn,
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export { telegram_notify, build_text, TASK_DEFINITIONS, telegram_environment_schema }
|
|
404
|
+
export type { TelegramSendInput, TelegramTaskType }
|