@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,240 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { is_workflow_destination } from '#scripts/claude/workflow-destination'
|
|
4
|
+
import { package_path } from '#scripts/init/init-paths'
|
|
5
|
+
|
|
6
|
+
// .github/workflows is the single source of truth for action SHA pins. The
|
|
7
|
+
// distributed templates/workflows/* intentionally diverge in structure (steps,
|
|
8
|
+
// commands, comment language), so only the `uses:` pins are propagated.
|
|
9
|
+
//
|
|
10
|
+
// The refs committed in templates/workflows/* are NOT authoritative: every consumer
|
|
11
|
+
// workflow is written through apply_pins_for_destination, which resolves the pins from
|
|
12
|
+
// .github/workflows at write time. Dependabot only ever updates .github/workflows (its
|
|
13
|
+
// github-actions ecosystem cannot scan templates/), so a stale template ref must not be
|
|
14
|
+
// able to reach a consumer — and must not fail CI either. `josh sync-workflow-pins`
|
|
15
|
+
// stays available to refresh the committed refs, but nothing depends on it having run.
|
|
16
|
+
const RUNTIME_WORKFLOWS_DIR = '.github/workflows'
|
|
17
|
+
const TEMPLATE_WORKFLOWS_DIR = 'templates/workflows'
|
|
18
|
+
const USES_KEY = 'uses:'
|
|
19
|
+
const YAML_PATTERN = /\.ya?ml$/u
|
|
20
|
+
const SYNC_HINT = ' Run `pnpm josh sync-workflow-pins` to sync template workflow pins.'
|
|
21
|
+
|
|
22
|
+
interface ActionPin {
|
|
23
|
+
name: string
|
|
24
|
+
ref: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface PinDrift {
|
|
28
|
+
template: string
|
|
29
|
+
line: number
|
|
30
|
+
action: string
|
|
31
|
+
from: string
|
|
32
|
+
to: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface WorkflowSource {
|
|
36
|
+
file: string
|
|
37
|
+
text: string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface UnknownAction {
|
|
41
|
+
template: string
|
|
42
|
+
line: number
|
|
43
|
+
action: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function parse_uses_line(line: string): ActionPin | undefined {
|
|
47
|
+
const key_index = line.indexOf(USES_KEY)
|
|
48
|
+
if (key_index === -1 || line.slice(0, key_index).trim() !== '') return undefined
|
|
49
|
+
|
|
50
|
+
const value = line.slice(key_index + USES_KEY.length).trim()
|
|
51
|
+
const at_index = value.indexOf('@')
|
|
52
|
+
if (at_index === -1) return undefined
|
|
53
|
+
|
|
54
|
+
return { name: value.slice(0, at_index), ref: value.slice(at_index + 1) }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function conflict_message(name: string, existing: string, found: string, file: string): string {
|
|
58
|
+
return `Action ${name} pinned to conflicting refs in .github/workflows: "${existing}" vs "${found}" (${file})`
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function add_pin(pins: Map<string, string>, pin: ActionPin, file: string): void {
|
|
62
|
+
const existing = pins.get(pin.name)
|
|
63
|
+
|
|
64
|
+
if (existing !== undefined && existing !== pin.ref) {
|
|
65
|
+
throw new Error(conflict_message(pin.name, existing, pin.ref, file))
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
pins.set(pin.name, pin.ref)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function collect_into(pins: Map<string, string>, source: WorkflowSource): void {
|
|
72
|
+
for (const line of source.text.split('\n')) {
|
|
73
|
+
const pin = parse_uses_line(line)
|
|
74
|
+
if (pin) add_pin(pins, pin, source.file)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function collect_canonical(sources: ReadonlyArray<WorkflowSource>): Map<string, string> {
|
|
79
|
+
const pins = new Map<string, string>()
|
|
80
|
+
for (const source of sources) collect_into(pins, source)
|
|
81
|
+
|
|
82
|
+
return pins
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function drift_for_line(
|
|
86
|
+
template: string,
|
|
87
|
+
line: string,
|
|
88
|
+
index: number,
|
|
89
|
+
canonical: ReadonlyMap<string, string>,
|
|
90
|
+
): PinDrift | undefined {
|
|
91
|
+
const pin = parse_uses_line(line)
|
|
92
|
+
if (!pin) return undefined
|
|
93
|
+
|
|
94
|
+
const want = canonical.get(pin.name)
|
|
95
|
+
if (want === undefined || want === pin.ref) return undefined
|
|
96
|
+
|
|
97
|
+
return { template, line: index + 1, action: pin.name, from: pin.ref, to: want }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function find_drift_in_text(
|
|
101
|
+
template: string,
|
|
102
|
+
text: string,
|
|
103
|
+
canonical: ReadonlyMap<string, string>,
|
|
104
|
+
): Array<PinDrift> {
|
|
105
|
+
const drifts: Array<PinDrift> = []
|
|
106
|
+
|
|
107
|
+
for (const [index, line] of text.split('\n').entries()) {
|
|
108
|
+
const drift = drift_for_line(template, line, index, canonical)
|
|
109
|
+
if (drift) drifts.push(drift)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return drifts
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function rewrite_line(line: string, canonical: ReadonlyMap<string, string>): string {
|
|
116
|
+
const pin = parse_uses_line(line)
|
|
117
|
+
if (!pin) return line
|
|
118
|
+
|
|
119
|
+
const want = canonical.get(pin.name)
|
|
120
|
+
if (want === undefined || want === pin.ref) return line
|
|
121
|
+
|
|
122
|
+
const key_index = line.indexOf(USES_KEY)
|
|
123
|
+
|
|
124
|
+
return `${line.slice(0, key_index)}${USES_KEY} ${pin.name}@${want}`
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function apply_to_text(text: string, canonical: ReadonlyMap<string, string>): string {
|
|
128
|
+
return text
|
|
129
|
+
.split('\n')
|
|
130
|
+
.map((line) => rewrite_line(line, canonical))
|
|
131
|
+
.join('\n')
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function read_source(relative_directory: string, name: string): WorkflowSource {
|
|
135
|
+
const file = path.join(relative_directory, name)
|
|
136
|
+
|
|
137
|
+
return { file, text: readFileSync(package_path(file), 'utf8') }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function list_workflow_sources(relative_directory: string): Array<WorkflowSource> {
|
|
141
|
+
return readdirSync(package_path(relative_directory))
|
|
142
|
+
.filter((name) => YAML_PATTERN.test(name))
|
|
143
|
+
.toSorted((left, right) => left.localeCompare(right))
|
|
144
|
+
.map((name) => read_source(relative_directory, name))
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function build_canonical_pins(): Map<string, string> {
|
|
148
|
+
return collect_canonical(list_workflow_sources(RUNTIME_WORKFLOWS_DIR))
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// An action the templates use but .github/workflows does not: write-time injection has no
|
|
152
|
+
// ref to resolve, so the stale template ref would reach the consumer unnoticed.
|
|
153
|
+
function unknown_actions_in_source(
|
|
154
|
+
source: WorkflowSource,
|
|
155
|
+
canonical: ReadonlyMap<string, string>,
|
|
156
|
+
): Array<UnknownAction> {
|
|
157
|
+
const unknown: Array<UnknownAction> = []
|
|
158
|
+
|
|
159
|
+
for (const [index, line] of source.text.split('\n').entries()) {
|
|
160
|
+
const pin = parse_uses_line(line)
|
|
161
|
+
|
|
162
|
+
if (pin && !canonical.has(pin.name)) {
|
|
163
|
+
unknown.push({ template: source.file, line: index + 1, action: pin.name })
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return unknown
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function apply_pins_for_destination(destination: string, text: string): string {
|
|
171
|
+
if (!is_workflow_destination(destination)) return text
|
|
172
|
+
|
|
173
|
+
return apply_to_text(text, build_canonical_pins())
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function scan_templates<T>(
|
|
177
|
+
scan: (source: WorkflowSource, canonical: ReadonlyMap<string, string>) => Array<T>,
|
|
178
|
+
): Array<T> {
|
|
179
|
+
const canonical = build_canonical_pins()
|
|
180
|
+
|
|
181
|
+
return list_workflow_sources(TEMPLATE_WORKFLOWS_DIR).flatMap((source) => scan(source, canonical))
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function find_pin_drift(): Array<PinDrift> {
|
|
185
|
+
return scan_templates((source, canonical) =>
|
|
186
|
+
find_drift_in_text(source.file, source.text, canonical),
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function find_unknown_template_actions(): Array<UnknownAction> {
|
|
191
|
+
return scan_templates(unknown_actions_in_source)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function write_synced(source: WorkflowSource, canonical: ReadonlyMap<string, string>): void {
|
|
195
|
+
const synced = apply_to_text(source.text, canonical)
|
|
196
|
+
if (synced !== source.text) writeFileSync(package_path(source.file), synced)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function sync_pins(): Array<PinDrift> {
|
|
200
|
+
const canonical = build_canonical_pins()
|
|
201
|
+
const drifts = find_pin_drift()
|
|
202
|
+
|
|
203
|
+
for (const source of list_workflow_sources(TEMPLATE_WORKFLOWS_DIR)) {
|
|
204
|
+
write_synced(source, canonical)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return drifts
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function format_drift_message(drifts: ReadonlyArray<PinDrift>): string {
|
|
211
|
+
const lines = drifts.map(
|
|
212
|
+
(drift) =>
|
|
213
|
+
` - ${drift.template}:${String(drift.line)} ${drift.action}: ${drift.from} → ${drift.to}`,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
return [
|
|
217
|
+
'✖ Template workflow action pins drifted from .github/workflows:',
|
|
218
|
+
...lines,
|
|
219
|
+
SYNC_HINT,
|
|
220
|
+
].join('\n')
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const workflow_pin_logic = {
|
|
224
|
+
RUNTIME_WORKFLOWS_DIR,
|
|
225
|
+
TEMPLATE_WORKFLOWS_DIR,
|
|
226
|
+
parse_uses_line,
|
|
227
|
+
collect_canonical,
|
|
228
|
+
find_drift_in_text,
|
|
229
|
+
apply_to_text,
|
|
230
|
+
is_workflow_destination,
|
|
231
|
+
apply_pins_for_destination,
|
|
232
|
+
build_canonical_pins,
|
|
233
|
+
find_pin_drift,
|
|
234
|
+
find_unknown_template_actions,
|
|
235
|
+
sync_pins,
|
|
236
|
+
format_drift_message,
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export { workflow_pin_logic }
|
|
240
|
+
export type { PinDrift }
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { globSync, readFileSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
import { VITEST_INCLUDE_GLOBS } from './vitest-include-globs'
|
|
6
|
+
|
|
7
|
+
// Isolation requirements — a test matching ANY condition below mutates state a sibling test running
|
|
8
|
+
// in the same worker could observe, so it must run with the default isolate:true and must NOT appear
|
|
9
|
+
// in the generated pilot list. The classifier is deliberately conservative: a file it cannot decide
|
|
10
|
+
// is left isolated, because a false "pure" costs a flaky pilot while a false "isolate" costs only a
|
|
11
|
+
// little speed.
|
|
12
|
+
// 1. Module mocks: vi.mock / vi.spyOn / vi.stubEnv / vi.stubGlobal / vi.resetModules /
|
|
13
|
+
// vi.unstubAllEnvs / vi.unstubAllGlobals
|
|
14
|
+
// 2. Environment variable writes: process.env.X = ... or delete process.env.X
|
|
15
|
+
// 3. Subprocess calls: execSync / spawnSync / spawn / exec / execa / child_process.*
|
|
16
|
+
// 4. Filesystem writes: writeFileSync / mkdirSync / mkdtemp / rmSync / unlinkSync / rimraf
|
|
17
|
+
// 5. Git operations: enforced by condition 3 — every git operation spawns a process, so a file
|
|
18
|
+
// that runs git already matches the subprocess pattern.
|
|
19
|
+
|
|
20
|
+
const MOCK_TOKENS: ReadonlyArray<string> = [
|
|
21
|
+
'mock',
|
|
22
|
+
'spyOn',
|
|
23
|
+
'stubEnv',
|
|
24
|
+
'stubGlobal',
|
|
25
|
+
'resetModules',
|
|
26
|
+
'unstubAllEnvs',
|
|
27
|
+
'unstubAllGlobals',
|
|
28
|
+
]
|
|
29
|
+
// Bare `exec` is deliberately absent: it matches the pure word (`pnpm exec …`, `regex.exec(…)`) more
|
|
30
|
+
// often than the child_process call, which an `execSync` / `child_process` token catches anyway.
|
|
31
|
+
const SUBPROCESS_TOKENS: ReadonlyArray<string> = [
|
|
32
|
+
'execSync',
|
|
33
|
+
'execFileSync',
|
|
34
|
+
'spawnSync',
|
|
35
|
+
'execaSync',
|
|
36
|
+
'execa',
|
|
37
|
+
'spawn',
|
|
38
|
+
'child_process',
|
|
39
|
+
]
|
|
40
|
+
const FS_WRITE_TOKENS: ReadonlyArray<string> = [
|
|
41
|
+
'writeFileSync',
|
|
42
|
+
'writeFile',
|
|
43
|
+
'appendFileSync',
|
|
44
|
+
'mkdirSync',
|
|
45
|
+
'mkdtempSync',
|
|
46
|
+
'mkdtemp',
|
|
47
|
+
'rmSync',
|
|
48
|
+
'rmdirSync',
|
|
49
|
+
'unlinkSync',
|
|
50
|
+
'cpSync',
|
|
51
|
+
'copyFileSync',
|
|
52
|
+
'renameSync',
|
|
53
|
+
'rimraf',
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
function word_pattern(tokens: ReadonlyArray<string>): RegExp {
|
|
57
|
+
return new RegExp(String.raw`\b(?:${tokens.join('|')})\b`, 'u')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const MODULE_MOCKS = new RegExp(String.raw`\bvi\.(?:${MOCK_TOKENS.join('|')})\b`, 'u')
|
|
61
|
+
const ENV_WRITES =
|
|
62
|
+
/(?:process\.env\.\w+\s*=(?!=)|process\.env\[[^\]]+\]\s*=(?!=)|delete\s+process\.env)/u
|
|
63
|
+
const SUBPROCESS = word_pattern(SUBPROCESS_TOKENS)
|
|
64
|
+
const FS_WRITES = word_pattern(FS_WRITE_TOKENS)
|
|
65
|
+
|
|
66
|
+
const ISOLATION_PATTERNS: ReadonlyArray<RegExp> = [MODULE_MOCKS, ENV_WRITES, SUBPROCESS, FS_WRITES]
|
|
67
|
+
|
|
68
|
+
// Excluded from the main suite in vitest.config.ts (packs and installs the real tarball), so it must
|
|
69
|
+
// never reach the pilot either.
|
|
70
|
+
const MAIN_EXCLUDE = new Set(['scripts/build/packed-consumer.test.ts'])
|
|
71
|
+
const NODE_MODULES = 'node_modules'
|
|
72
|
+
const PILOT_FILES_PATH = 'scripts/test/pilot-files.ts'
|
|
73
|
+
const WRITE_FLAG = '--write'
|
|
74
|
+
const INDENT = '\t'
|
|
75
|
+
const UTF8 = 'utf8'
|
|
76
|
+
|
|
77
|
+
const GENERATED_HEADER = `/* eslint-disable max-lines */
|
|
78
|
+
// GENERATED FILE — do not edit by hand.
|
|
79
|
+
// Regenerate with: pnpm exec tsx scripts/test/classify-isolation.ts --write
|
|
80
|
+
// Every entry is a test file the classifier judges free of the isolation requirements documented in
|
|
81
|
+
// classify-isolation.ts; these files run with isolate:false in vitest.pilot.config.ts.`
|
|
82
|
+
|
|
83
|
+
function normalize_path(file: string): string {
|
|
84
|
+
return file.split(path.sep).join('/')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function is_in_node_modules(entry: string): boolean {
|
|
88
|
+
return entry.split(/[/\\]/u).includes(NODE_MODULES)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function collect_glob(glob: string): Array<string> {
|
|
92
|
+
return globSync(glob, { exclude: is_in_node_modules }).map((file) => normalize_path(file))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Code-point order, never localeCompare: the list is generated on one machine and re-derived in CI,
|
|
96
|
+
// and ICU collation differs across platforms — so localeCompare reorders the list under CI's Linux
|
|
97
|
+
// ICU and fails the drift test on order alone (joshuafolkken/kit#2170).
|
|
98
|
+
function by_code_point(left: string, right: string): number {
|
|
99
|
+
if (left < right) return -1
|
|
100
|
+
|
|
101
|
+
return left > right ? 1 : 0
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function all_test_files(): Array<string> {
|
|
105
|
+
const files = VITEST_INCLUDE_GLOBS.flatMap((glob) => collect_glob(glob))
|
|
106
|
+
|
|
107
|
+
return [...new Set(files)].filter((file) => !MAIN_EXCLUDE.has(file)).toSorted(by_code_point)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function requires_isolation(source: string): boolean {
|
|
111
|
+
return ISOLATION_PATTERNS.some((pattern) => pattern.test(source))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function is_pilot_candidate(file: string): boolean {
|
|
115
|
+
return !requires_isolation(readFileSync(file, UTF8))
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function classify_pilot_files(): Array<string> {
|
|
119
|
+
return all_test_files().filter((file) => is_pilot_candidate(file))
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function render_pilot_files(files: ReadonlyArray<string>): string {
|
|
123
|
+
const entries = files.map((file) => `${INDENT}'${file}',`).join('\n')
|
|
124
|
+
const body = `const PILOT_FILES: ReadonlyArray<string> = [\n${entries}\n]`
|
|
125
|
+
|
|
126
|
+
return `${GENERATED_HEADER}\n\n${body}\n\nexport { PILOT_FILES }\n`
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function write_pilot_files(): void {
|
|
130
|
+
writeFileSync(PILOT_FILES_PATH, render_pilot_files(classify_pilot_files()))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
134
|
+
if (process.argv.includes(WRITE_FLAG)) write_pilot_files()
|
|
135
|
+
else process.stdout.write(`${classify_pilot_files().join('\n')}\n`)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const classify_isolation = {
|
|
139
|
+
ISOLATION_PATTERNS,
|
|
140
|
+
all_test_files,
|
|
141
|
+
by_code_point,
|
|
142
|
+
classify_pilot_files,
|
|
143
|
+
is_pilot_candidate,
|
|
144
|
+
render_pilot_files,
|
|
145
|
+
requires_isolation,
|
|
146
|
+
write_pilot_files,
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export { classify_isolation }
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { appendFileSync, readdirSync, readFileSync, statSync } from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
|
|
6
|
+
// Whether the preview server process died during a failed E2E attempt.
|
|
7
|
+
//
|
|
8
|
+
// This command reports a fact and nothing else. Whether that fact should produce a retry is the
|
|
9
|
+
// workflow's decision, and it has to be, because a step that errors publishes no output at all: a
|
|
10
|
+
// default-branch push must retry whatever happens here, so its rule cannot depend on this command
|
|
11
|
+
// succeeding. `templates/workflows/ci.yml` therefore ORs `E2E_RETRY_UNCONDITIONAL` in front of this
|
|
12
|
+
// output rather than passing the flag down — one rule, in the one place that survives a failure.
|
|
13
|
+
//
|
|
14
|
+
// The distinction being drawn is between a suite that failed and a suite that never got to run. A
|
|
15
|
+
// pull request must not retry the first: that is what hides a real flake before it is merged
|
|
16
|
+
// (#872). It may retry the second, because the preview server dying is produced by the CI substrate
|
|
17
|
+
// rather than by the diff under review. The rule lives in a script rather than in the workflow's
|
|
18
|
+
// shell because it is the one part of the chain that can be wrong without anyone noticing — a
|
|
19
|
+
// signature that stops matching silently stops retrying — and here it has unit tests that turn that
|
|
20
|
+
// drift into a red build.
|
|
21
|
+
|
|
22
|
+
// The crash, spelled as wrangler spells it in the debug log the E2E job already uploads as
|
|
23
|
+
// `e2e-web-server-log`. **Every** string here must be present, not any of them, and the conjunction
|
|
24
|
+
// is the point: each half is individually weaker than it looks. `Network connection lost.` is
|
|
25
|
+
// logged by workerd for any aborted in-flight request — a page closing, a navigation, a timeout —
|
|
26
|
+
// so a suite that merely failed can produce it with the server perfectly healthy. `Error in
|
|
27
|
+
// ProxyController` is the structural marker for a worker that is gone. Requiring both costs
|
|
28
|
+
// nothing — every observed crash carries them together — and each one narrows the other's exposure.
|
|
29
|
+
//
|
|
30
|
+
// Both halves have now been read against logs wrangler actually wrote, which #872 could only
|
|
31
|
+
// assume (#911). Every `e2e-web-server-log` game-kit retains — 8 artifacts across 6 runs — is from
|
|
32
|
+
// a server that genuinely died, and the pair matches all of them. The open worry was the other
|
|
33
|
+
// direction: that wrangler emits `Error in ProxyController` while tearing the proxy down, which
|
|
34
|
+
// happens at the end of every run including a failing one, and would hand a retry to exactly the
|
|
35
|
+
// flake this gate exists to expose. A run of game-kit's own suite against the same preview server,
|
|
36
|
+
// failing on an assertion with the server serving every request throughout, emits neither string
|
|
37
|
+
// anywhere in its log — it ends on a routine heartbeat with nothing logged behind the last request.
|
|
38
|
+
// That is what this rule reads and all it claims: the log of a healthy failing run is clean, so no
|
|
39
|
+
// shutdown path reachable from one puts a signature in front of this check. It is quoted complete
|
|
40
|
+
// in `e2e-retry-check-healthy-fixture.ts`, the crash in `e2e-retry-check-crash-fixture.ts`, and the
|
|
41
|
+
// suite reads this rule against both rather than against the paragraph above.
|
|
42
|
+
//
|
|
43
|
+
// One marker #872 listed is deliberately absent from this list: the bare `✘ [ERROR]` wrangler
|
|
44
|
+
// prints to the console. It is in the healthy log three times over, each an ordinary 404.
|
|
45
|
+
const CRASH_SIGNATURES: ReadonlyArray<string> = [
|
|
46
|
+
'Error in ProxyController',
|
|
47
|
+
'Network connection lost.',
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
// Both are the workflow's values, exported so the guard in `ci-yml-e2e-retry.test.ts` can assert
|
|
51
|
+
// this command reads the log that job actually writes. A rename on one side alone would leave the
|
|
52
|
+
// check reading nothing and quietly reporting "no crash" on every run.
|
|
53
|
+
const LOG_PATH_VARIABLE = 'WRANGLER_LOG_PATH'
|
|
54
|
+
const DEFAULT_LOG_DIRECTORY = 'e2e-web-server-logs'
|
|
55
|
+
const OUTPUT_NAME = 'crashed'
|
|
56
|
+
|
|
57
|
+
function has_crash_signature(log_text: string): boolean {
|
|
58
|
+
return CRASH_SIGNATURES.every((signature) => log_text.includes(signature))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function read_file_safe(file_path: string): string {
|
|
62
|
+
try {
|
|
63
|
+
return readFileSync(file_path, 'utf8')
|
|
64
|
+
} catch {
|
|
65
|
+
return ''
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Every file under the directory, because wrangler names the debug log after the run and a job that
|
|
70
|
+
// restarted the server leaves more than one. They stay separate rather than being joined, and the
|
|
71
|
+
// verdict below is taken per file: a crash is one process reporting its own death, so both
|
|
72
|
+
// signatures have to be in the same log. Concatenating them first would let `Network connection
|
|
73
|
+
// lost.` from an aborted request in one file meet `Error in ProxyController` in another — the
|
|
74
|
+
// conjunction satisfied by two unrelated events, and a retry handed to exactly the failing pull
|
|
75
|
+
// request suite this rule exists to keep exposed. Every observed crash carries the pair inside one
|
|
76
|
+
// error record, so nothing is lost by requiring it (#911).
|
|
77
|
+
function read_directory_texts(directory: string): ReadonlyArray<string> {
|
|
78
|
+
return readdirSync(directory, { recursive: true, withFileTypes: true })
|
|
79
|
+
.filter((entry) => entry.isFile())
|
|
80
|
+
.map((entry) => read_file_safe(path.join(entry.parentPath, entry.name)))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Nothing about reading a log may be fatal: this command decides whether to spend one more CI
|
|
84
|
+
// minute, and throwing would fail the job over a diagnostic. Every way the path can disappoint ends
|
|
85
|
+
// at the same answer — it is missing, it is a file rather than the expected directory (a spelling
|
|
86
|
+
// `WRANGLER_LOG_PATH` supports, which is why the workflow strips a trailing slash), or it cannot be
|
|
87
|
+
// read at all. An empty read is then reported as "no crash", which is the safe verdict: a consumer
|
|
88
|
+
// whose preview script is not wrangler writes no log, and reading silence as a crash would retry
|
|
89
|
+
// every failing suite in that project — the masking this rule exists to prevent.
|
|
90
|
+
function read_log_texts(target: string): ReadonlyArray<string> {
|
|
91
|
+
try {
|
|
92
|
+
return statSync(target).isDirectory() ? read_directory_texts(target) : [read_file_safe(target)]
|
|
93
|
+
} catch {
|
|
94
|
+
return []
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// One file carrying every signature, never the set of them between them — see `read_directory_texts`.
|
|
99
|
+
function has_crashed_log(log_texts: ReadonlyArray<string>): boolean {
|
|
100
|
+
return log_texts.some((log_text) => has_crash_signature(log_text))
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// The one write this command makes, and the only call left that could throw: a full disk, a
|
|
104
|
+
// read-only mount, an output file the runner removed. Nothing here may be fatal — a job must not go
|
|
105
|
+
// red over a step that only decides whether to spend one more CI minute — so the failure is
|
|
106
|
+
// announced and stepped over. A verdict that cannot be published simply does not produce a retry,
|
|
107
|
+
// which for a pull request is the status quo and for the default branch is nothing at all, since
|
|
108
|
+
// the flag there is read ahead of this output.
|
|
109
|
+
function write_github_output(has_crashed: boolean): void {
|
|
110
|
+
const output_path = process.env['GITHUB_OUTPUT']
|
|
111
|
+
if (output_path === undefined || output_path === '') return
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
appendFileSync(output_path, `${OUTPUT_NAME}=${String(has_crashed)}\n`)
|
|
115
|
+
} catch {
|
|
116
|
+
console.info('::warning::Could not publish the E2E crash check verdict; no retry will follow.')
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function resolve_log_directory(): string {
|
|
121
|
+
const configured = process.env[LOG_PATH_VARIABLE] ?? ''
|
|
122
|
+
|
|
123
|
+
return configured === '' ? DEFAULT_LOG_DIRECTORY : configured
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function run_retry_check(): boolean {
|
|
127
|
+
const has_crashed = has_crashed_log(read_log_texts(resolve_log_directory()))
|
|
128
|
+
const verdict = has_crashed
|
|
129
|
+
? 'the preview server log carries a crash signature'
|
|
130
|
+
: 'no crash signature in the preview server log, so the suite itself failed'
|
|
131
|
+
|
|
132
|
+
console.info(`::notice::E2E preview server crash check: ${verdict}`)
|
|
133
|
+
write_github_output(has_crashed)
|
|
134
|
+
|
|
135
|
+
return has_crashed
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
139
|
+
run_retry_check()
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const e2e_retry_check = {
|
|
143
|
+
has_crash_signature,
|
|
144
|
+
has_crashed_log,
|
|
145
|
+
read_log_texts,
|
|
146
|
+
resolve_log_directory,
|
|
147
|
+
run_retry_check,
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { e2e_retry_check, CRASH_SIGNATURES, DEFAULT_LOG_DIRECTORY, LOG_PATH_VARIABLE, OUTPUT_NAME }
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { cases } from '#scripts/cases/cases-logic'
|
|
2
|
+
|
|
3
|
+
// joshuafolkken/kit#2355: the network boundary's abnormal cases were declared and never run. The unit
|
|
4
|
+
// suite blocks the network by construction (`test-network-guard.ts` shims the `gh` and `git`
|
|
5
|
+
// binaries), so `josh cases`' network vocabulary had no way to be *executed* — only named in a test
|
|
6
|
+
// declaration, where the failure mode nobody anticipated is exactly the one that never gets declared
|
|
7
|
+
// (the transport failure of joshuafolkken/kit#2317 was hit before it was foreseen).
|
|
8
|
+
//
|
|
9
|
+
// This makes each of those failure modes injectable as a `fetch` stand-in that produces the failure
|
|
10
|
+
// without opening a connection. It does not weaken the guard: the shims are untouched, no real request
|
|
11
|
+
// leaves the machine, and the stand-in only shapes the `Response` (or rejection) the caller's error
|
|
12
|
+
// path already has to survive. The mode set is single-sourced from `cases`, so the vocabulary the
|
|
13
|
+
// command prints and the failures that can be injected cannot drift apart — `INJECTORS` is asserted
|
|
14
|
+
// exhaustive against it in the colocated test.
|
|
15
|
+
|
|
16
|
+
// A `fetch` stand-in: the real signature takes an input and an optional init, both ignored here since
|
|
17
|
+
// the failure is fixed by the mode rather than the request.
|
|
18
|
+
type FetchStub = (input?: unknown, init?: unknown) => Promise<Response>
|
|
19
|
+
|
|
20
|
+
const NON_200_STATUS = 500
|
|
21
|
+
const RATE_LIMIT_STATUS = 429
|
|
22
|
+
const OK_STATUS = 200
|
|
23
|
+
|
|
24
|
+
// The two rejection failures wear the shapes the platform itself throws, so a caller's `catch` sees
|
|
25
|
+
// what a real timeout or dropped connection would produce: `AbortSignal.timeout` rejects with a
|
|
26
|
+
// `TimeoutError` DOMException, and a transport failure rejects with a `TypeError`.
|
|
27
|
+
const TIMEOUT_MESSAGE = 'The operation timed out.'
|
|
28
|
+
const TIMEOUT_NAME = 'TimeoutError'
|
|
29
|
+
const CONNECTION_DROP_MESSAGE = 'fetch failed'
|
|
30
|
+
// A body that is present but not JSON, told apart from the empty body by having content at all.
|
|
31
|
+
const INVALID_JSON_BODY = '{'
|
|
32
|
+
const EMPTY_BODY = ''
|
|
33
|
+
|
|
34
|
+
function ok_body(body: string): FetchStub {
|
|
35
|
+
return async () => new Response(body, { status: OK_STATUS })
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function non_ok(code: number): FetchStub {
|
|
39
|
+
return async () => new Response(EMPTY_BODY, { status: code })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function rejecting(error: Error): FetchStub {
|
|
43
|
+
return async () => {
|
|
44
|
+
throw error
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Keyed by the exact vocabulary term `josh cases` prints for the network boundary. The colocated test
|
|
49
|
+
// proves this key set equals that vocabulary, so a term added there without an injector here fails.
|
|
50
|
+
const INJECTORS: Readonly<Record<string, FetchStub>> = {
|
|
51
|
+
非200: non_ok(NON_200_STATUS),
|
|
52
|
+
タイムアウト: rejecting(new DOMException(TIMEOUT_MESSAGE, TIMEOUT_NAME)),
|
|
53
|
+
接続断: rejecting(new TypeError(CONNECTION_DROP_MESSAGE)),
|
|
54
|
+
空レスポンス: ok_body(EMPTY_BODY),
|
|
55
|
+
不正JSON: ok_body(INVALID_JSON_BODY),
|
|
56
|
+
レート制限: non_ok(RATE_LIMIT_STATUS),
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// The failure modes that can be injected — the injector key set, for the correspondence assertion.
|
|
60
|
+
function supported_modes(): ReadonlyArray<string> {
|
|
61
|
+
return Object.keys(INJECTORS)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// A `fetch` stand-in producing the named failure. An unknown mode throws rather than silently passing:
|
|
65
|
+
// a typo in a test must not degrade into a request that quietly does nothing.
|
|
66
|
+
function faulty_fetch(mode: string): FetchStub {
|
|
67
|
+
const injector = INJECTORS[mode]
|
|
68
|
+
if (injector === undefined) throw new Error(`unknown network failure mode: ${mode}`)
|
|
69
|
+
|
|
70
|
+
return injector
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// The network vocabulary this injector must cover, single-sourced from the command's own definition.
|
|
74
|
+
const NETWORK_MODES: ReadonlyArray<string> = cases.cases_for(['network'])
|
|
75
|
+
|
|
76
|
+
const http_fault_injection = { NETWORK_MODES, faulty_fetch, supported_modes }
|
|
77
|
+
|
|
78
|
+
export type { FetchStub }
|
|
79
|
+
export { http_fault_injection }
|