@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,95 @@
|
|
|
1
|
+
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
2
|
+
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
3
|
+
|
|
4
|
+
// The verification gate's full output, kept somewhere the console's size limit cannot reach
|
|
5
|
+
// (joshuafolkken/kit#1227).
|
|
6
|
+
//
|
|
7
|
+
// **The problem is that the only copy of a failure's detail was the console.** `josh gate` buffers
|
|
8
|
+
// every check and prints the failing ones whole, and joshuafolkken/kit#1173 then declared
|
|
9
|
+
// `BASH_MAX_OUTPUT_LENGTH` at 8,000 characters — a cap on what a command may carry into an agent's
|
|
10
|
+
// context, with a measured p99 of 15,989 characters for a Bash call. The verdict is the last line and
|
|
11
|
+
// so always survives, which is why a red gate can never read as green; what does not survive is the
|
|
12
|
+
// middle, and the middle is where the failure says what it was. The escape hatch was to re-run one
|
|
13
|
+
// check by hand, which is a judgement the reader has to make about output they cannot see.
|
|
14
|
+
//
|
|
15
|
+
// So the gate writes every check's output to a file and prints where it is. Nothing about the
|
|
16
|
+
// verdict changes; what changes is that the detail behind it no longer exists only in a window that
|
|
17
|
+
// may have been elided.
|
|
18
|
+
|
|
19
|
+
const GATE_LOG_PREFIX = 'josh-gate-log-'
|
|
20
|
+
const GATE_LOG_SUFFIX = '.log'
|
|
21
|
+
|
|
22
|
+
// **The temp directory, per checkout, deterministic — the convention `stamp-file.ts` already
|
|
23
|
+
// defines**, and it is imported rather than re-derived. A file inside the repository would need a
|
|
24
|
+
// gitignore entry here and in every consumer `josh sync` reaches, bought for something nobody keeps.
|
|
25
|
+
// The path is stable across runs, so each gate overwrites the last one's log: one file per checkout,
|
|
26
|
+
// and nothing accumulates.
|
|
27
|
+
function gate_log_path(target?: string): string {
|
|
28
|
+
return target ?? stamp_file.stamp_path(GATE_LOG_PREFIX, PROJECT_ROOT, GATE_LOG_SUFFIX)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// The header the console already prints for this step, reused verbatim. The gate builds it once and
|
|
32
|
+
// hands it here, so a log section can never name a check differently from the block above it.
|
|
33
|
+
interface GateLogEntry {
|
|
34
|
+
header: string
|
|
35
|
+
output: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function format_gate_log_entry(entry: GateLogEntry): string {
|
|
39
|
+
return `=== ${entry.header} ===\n${entry.output}\n`
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function format_gate_log(entries: ReadonlyArray<GateLogEntry>): string {
|
|
43
|
+
return entries.map((entry) => format_gate_log_entry(entry)).join('\n')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// **Written on every run that started a check, passing ones included.** Writing only on failure
|
|
47
|
+
// would make the record a judgement about which runs are worth keeping, and the judgement is wrong
|
|
48
|
+
// in both of the cases that already print a body on a green gate: a check that passed with warnings,
|
|
49
|
+
// and one that passed without running. It also costs a reader nothing — the file is overwritten, so
|
|
50
|
+
// a green run leaves exactly as many files behind as a red one. A gate that reused a recorded green
|
|
51
|
+
// result started no check and has nothing to write, which is why this is called from the checked
|
|
52
|
+
// path alone.
|
|
53
|
+
//
|
|
54
|
+
// **A write that fails never changes the verdict.** The log is a convenience for whoever reads the
|
|
55
|
+
// output next, and a temp-directory problem must not turn a green gate red — the same rule the
|
|
56
|
+
// green-gate record and the in-flight marker already follow. `undefined` is that failure, and the
|
|
57
|
+
// notice below says so out loud rather than leaving the reader to notice a missing line.
|
|
58
|
+
function write_gate_log(entries: ReadonlyArray<GateLogEntry>, target?: string): string | undefined {
|
|
59
|
+
const destination = gate_log_path(target)
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
return stamp_file.write_text_stamp(destination, format_gate_log(entries))
|
|
63
|
+
} catch {
|
|
64
|
+
return undefined
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const LOG_NOTICE_PREFIX = 'full output: '
|
|
69
|
+
const LOG_FAILED_NOTICE = 'full output: could not be written; re-run with `> gate.log 2>&1`'
|
|
70
|
+
|
|
71
|
+
// **The notice goes immediately *above* the verdict, never below it.** `josh-verdict.ts` documents
|
|
72
|
+
// the gate's verdict as its last line and builds two readers on that: `time-reported-failure.ts`
|
|
73
|
+
// resumes its scan after the verdict, and the `2>&1 | tail -40` in
|
|
74
|
+
// `prompts/collaboration-workflow/output-bounds.md` keeps the end of the output. A line after the
|
|
75
|
+
// verdict would sit inside both of those windows and take the property away for a line that is not
|
|
76
|
+
// the answer. Above it, the path survives a `tail` exactly as the verdict does.
|
|
77
|
+
function format_log_notice(log_path: string | undefined): string {
|
|
78
|
+
if (log_path === undefined) return `${LOG_FAILED_NOTICE}\n`
|
|
79
|
+
|
|
80
|
+
return `${LOG_NOTICE_PREFIX}${log_path}\n`
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const gate_log = {
|
|
84
|
+
format_gate_log,
|
|
85
|
+
format_log_notice,
|
|
86
|
+
gate_log_path,
|
|
87
|
+
GATE_LOG_PREFIX,
|
|
88
|
+
GATE_LOG_SUFFIX,
|
|
89
|
+
LOG_FAILED_NOTICE,
|
|
90
|
+
LOG_NOTICE_PREFIX,
|
|
91
|
+
write_gate_log,
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type { GateLogEntry }
|
|
95
|
+
export { gate_log }
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { availableParallelism } from 'node:os'
|
|
2
|
+
import { josh_verdict } from '#scripts/josh/josh-verdict'
|
|
3
|
+
import { unit_worker_share } from '#scripts/test/unit-worker-share'
|
|
4
|
+
|
|
5
|
+
// How many of the gate's checks run at once, and how wide the one elastic check may fan out —
|
|
6
|
+
// both derived from the machine rather than fixed at four (joshuafolkken/kit#1258).
|
|
7
|
+
//
|
|
8
|
+
// **The measurement this table is built from.** Apple M3 Pro, 11 logical cores (5 performance +
|
|
9
|
+
// 6 efficiency, about 9 cores of aggregate throughput on this workload), warm caches, each check
|
|
10
|
+
// run alone. `CPU-seconds ÷ wall-seconds` is how many cores the check actually occupies:
|
|
11
|
+
//
|
|
12
|
+
// | check | wall | CPU | cores |
|
|
13
|
+
// | --------- | ----- | ------ | ----- |
|
|
14
|
+
// | lint | 5.2s | 10.8s | 2.1 |
|
|
15
|
+
// | check | 1.4s | 2.3s | 1.7 |
|
|
16
|
+
// | cspell | 1.1s | 1.5s | 1.3 |
|
|
17
|
+
// | test:unit | 12.6s | 107.0s | 8.5 |
|
|
18
|
+
//
|
|
19
|
+
// Two things follow. **The concurrent gate is already the faster shape** — 15.1s together against
|
|
20
|
+
// 19.1s back to back, the median of three interleaved runs on the same tree, and the one pair
|
|
21
|
+
// `verification-gate.ts` and `docs/josh-commands.md` quote too — so this is a widening of an
|
|
22
|
+
// existing win, not a repair of the regression joshuafolkken/kit#1258 was filed for: that was
|
|
23
|
+
// real when the type check and the spell check cost 6.9s and 3.6s of CPU, and joshuafolkken/kit#1256
|
|
24
|
+
// removed it by giving both a cache. **And the unit suite is the only check worth sizing**: it
|
|
25
|
+
// alone accounts for 107 of the 122 CPU-seconds, because vitest opens one worker per core while
|
|
26
|
+
// the other three are one or two processes each.
|
|
27
|
+
|
|
28
|
+
interface GateCheck {
|
|
29
|
+
label: string
|
|
30
|
+
// The `josh` sub-command that defines the check, and the one an appended argument belongs to.
|
|
31
|
+
target: string
|
|
32
|
+
// Cores this check holds for as long as it runs — the measured ratio above, floored to whole
|
|
33
|
+
// cores and never below one. Floored rather than rounded because this is the share the *other*
|
|
34
|
+
// checks must give up: over-reserving costs the elastic check workers it would have used.
|
|
35
|
+
// The unit suite reserves nothing: it sizes its own pool from the machine, so it is capped
|
|
36
|
+
// instead of reserved, and counting it here would reserve cores against itself.
|
|
37
|
+
reserved_cores: number
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const LINT_LABEL = 'lint'
|
|
41
|
+
const TYPE_CHECK_LABEL = 'check'
|
|
42
|
+
const UNIT_LABEL = 'test:unit'
|
|
43
|
+
const BEHAVIOR_LABEL = 'behavior'
|
|
44
|
+
|
|
45
|
+
// The checks whose warnings must survive the green record: eslint (the `lint` step) and svelte-check
|
|
46
|
+
// (the `check` step) both exit 0 while reporting per-tree warnings a developer needs to see again, so
|
|
47
|
+
// reusing a record taken from such a run would hide them (joshuafolkken/kit#1328). Every other step's
|
|
48
|
+
// warning-shaped output — a Vite config deprecation printed by `test:unit`, say — is not a per-tree
|
|
49
|
+
// finding and repeats every run, so it must not withhold the record. This is what `has_checker_warning`
|
|
50
|
+
// narrows the withholding path down to (joshuafolkken/kit#2318).
|
|
51
|
+
const WARNING_CHECKER_LABELS: ReadonlyArray<string> = [LINT_LABEL, TYPE_CHECK_LABEL]
|
|
52
|
+
|
|
53
|
+
// The checks that do not fan out across every core, in the order their output is printed. They are
|
|
54
|
+
// named apart from the unit suite because CI runs them on their own runner (joshuafolkken/kit#1226):
|
|
55
|
+
// the unit suite is the only check that fans out across every core, so on a 4-core GitHub runner it
|
|
56
|
+
// and the others spent the whole job taking cores off each other.
|
|
57
|
+
//
|
|
58
|
+
// **The behavior check belongs here, and it reserves no core** (joshuafolkken/kit#2365). It reads one
|
|
59
|
+
// recorded transcript rather than the tree, so it is I/O-bound and a zero reservation leaves
|
|
60
|
+
// `RESERVED_CORES` and the unit worker cap exactly where the other three were measured. Being a static
|
|
61
|
+
// check rather than one appended after the unit suite is what keeps the plan's shape intact: the
|
|
62
|
+
// `--no-unit` set stays "the whole gate minus the unit suite", and a CI runner — which has no recorded
|
|
63
|
+
// transcripts — runs it as a trivial green rather than skipping it.
|
|
64
|
+
const STATIC_CHECKS: ReadonlyArray<GateCheck> = [
|
|
65
|
+
{ label: LINT_LABEL, target: 'lint', reserved_cores: 2 },
|
|
66
|
+
{ label: TYPE_CHECK_LABEL, target: 'check', reserved_cores: 1 },
|
|
67
|
+
{ label: 'cspell', target: 'cspell:dot', reserved_cores: 1 },
|
|
68
|
+
{ label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
// The checks, in the order their output is printed — the static set, then the unit suite last (the
|
|
72
|
+
// one check that fans out across every core, and the one the `--no-unit` split drops).
|
|
73
|
+
const GATE_CHECKS: ReadonlyArray<GateCheck> = [
|
|
74
|
+
...STATIC_CHECKS,
|
|
75
|
+
{ label: UNIT_LABEL, target: UNIT_LABEL, reserved_cores: 0 },
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
// **Selecting is not skipping, and the difference is where the unit suite runs rather than whether
|
|
79
|
+
// it runs.** `josh gate --no-unit` exists for one caller — the CI job that has handed the unit suite
|
|
80
|
+
// to a runner of its own — and every other entry point still gets all four. What makes the narrower
|
|
81
|
+
// set safe is that nothing downstream may mistake it for the full gate: `verification-gate.ts`
|
|
82
|
+
// withholds both the green-gate record and the in-flight marker on a partial run, so a `--no-unit`
|
|
83
|
+
// gate can never tell `josh review:brief` that the unit suite passed on this tree.
|
|
84
|
+
function select_gate_checks(is_unit_included: boolean): ReadonlyArray<GateCheck> {
|
|
85
|
+
return is_unit_included ? GATE_CHECKS : STATIC_CHECKS
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Asked of the plan rather than of the flag, so the one question "did this gate run the unit suite"
|
|
89
|
+
// has one answer however the plan was built.
|
|
90
|
+
function has_unit_check(checks: ReadonlyArray<GateCheck>): boolean {
|
|
91
|
+
return checks.some((check) => check.label === UNIT_LABEL)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// What the three non-elastic checks hold between them: 2 + 1 + 1. Reduced over `STATIC_CHECKS`
|
|
95
|
+
// rather than over all four, because that is the set the sentence above names: `resolve_unit_worker_cap`
|
|
96
|
+
// spends this as the cores the unit suite must leave to its siblings, so summing the unit check into
|
|
97
|
+
// it would have the suite subtract its own reservation from its own budget the day that reservation
|
|
98
|
+
// stops being zero. The two sets give the same number today, which is exactly why the narrower one
|
|
99
|
+
// has to be the declared one.
|
|
100
|
+
const RESERVED_CORES: number = STATIC_CHECKS.reduce(
|
|
101
|
+
(total, check) => total + check.reserved_cores,
|
|
102
|
+
0,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
// The machine the table above was measured on, and the smallest one the cap is applied to.
|
|
106
|
+
//
|
|
107
|
+
// **Below it the plan leaves the unit suite alone**, because four reserved cores are a far larger
|
|
108
|
+
// share of a small machine than of this one — half an 8-core machine against a third of this — and
|
|
109
|
+
// the one measurement that exists says nothing about whether the reservation still pays there.
|
|
110
|
+
// Extrapolating it downward is what would hurt: the suite takes 11.7s at 8 workers and 16.7s at 4,
|
|
111
|
+
// so a rule that handed an 8-core machine four workers would pin the longest check at the slow end
|
|
112
|
+
// of a curve nobody measured on that machine. An unmeasured machine gets the behavior `josh gate`
|
|
113
|
+
// had before this plan existed — vitest sizing its own pool — rather than an extrapolated one, and
|
|
114
|
+
// a 4-core CI runner is far below the line, which is why this leaves CI running exactly as it did.
|
|
115
|
+
const MEASURED_CORES = 11
|
|
116
|
+
|
|
117
|
+
// At least one check at a time, whatever the machine reports.
|
|
118
|
+
const MIN_CONCURRENCY = 1
|
|
119
|
+
|
|
120
|
+
// At least one core to plan against, however many gates are sharing the machine. Without it a
|
|
121
|
+
// twelfth lane would divide 11 cores to zero and admit nothing, and `MIN_CONCURRENCY` would be
|
|
122
|
+
// covering for an arithmetic accident rather than for a genuinely tiny machine.
|
|
123
|
+
const MIN_SHARED_CORES = 1
|
|
124
|
+
|
|
125
|
+
interface GatePlan {
|
|
126
|
+
// The checks this run fans out to — all four, or the static three when the unit suite has a
|
|
127
|
+
// runner of its own. Carried on the plan rather than re-derived at each use, so the concurrency,
|
|
128
|
+
// the printed plan line and the steps that actually run can never describe different sets.
|
|
129
|
+
checks: ReadonlyArray<GateCheck>
|
|
130
|
+
// How many checks run at once.
|
|
131
|
+
concurrency: number
|
|
132
|
+
// `--maxWorkers` for the unit suite, or `undefined` to leave the choice to vitest.
|
|
133
|
+
unit_worker_cap: number | undefined
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// This gate's share of the machine — the cores it may plan against once the other gates in flight
|
|
137
|
+
// have theirs (joshuafolkken/kit#1547).
|
|
138
|
+
//
|
|
139
|
+
// **At one run this is the identity, and that is the whole argument that solo behavior is
|
|
140
|
+
// unchanged.** `Math.floor(cores / 1)` is `cores`, so a solo gate and a CI runner hand the admission
|
|
141
|
+
// below exactly the number they always handed it — not a number that happens to come out the same,
|
|
142
|
+
// the same number, by arithmetic — and no branch, flag or environment probe stands between the two
|
|
143
|
+
// cases to be got wrong later.
|
|
144
|
+
//
|
|
145
|
+
// **A run count that is not a number leaves the machine undivided, and the clamp is not cosmetic.**
|
|
146
|
+
// `Math.max` propagates `NaN` rather than clamping it, so an unusable count would sail through
|
|
147
|
+
// `MIN_SHARED_CORES`, make every `reserved > share` comparison false and admit all four checks —
|
|
148
|
+
// the exact opposite of what this function is for. `bounded-pool.ts` closes the same hole for the
|
|
149
|
+
// same reason. A count below one is nonsense too and is read as one run, which is the direction
|
|
150
|
+
// that leaves behavior where it was rather than throttling a gate on a bad input.
|
|
151
|
+
function shared_cores(available_cores: number, concurrent_runs: number): number {
|
|
152
|
+
const runs = Number.isFinite(concurrent_runs)
|
|
153
|
+
? Math.max(unit_worker_share.SOLO_RUNS, concurrent_runs)
|
|
154
|
+
: unit_worker_share.SOLO_RUNS
|
|
155
|
+
|
|
156
|
+
return Math.max(MIN_SHARED_CORES, Math.floor(available_cores / runs))
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Admit checks in declaration order while the running set's reserved cores still fit **this run's
|
|
160
|
+
// share** of the machine. On a machine running one gate that share is the machine, so this bites
|
|
161
|
+
// only below four cores — the three reserving checks want four between them — and there it is the
|
|
162
|
+
// difference between two checks sharing a core and four fighting over it.
|
|
163
|
+
//
|
|
164
|
+
// **Under concurrency it is the only lever there is, and that is a measurement rather than a
|
|
165
|
+
// preference** (joshuafolkken/kit#1547). `josh gate` starts four checks at once and joshuafolkken/kit#1515
|
|
166
|
+
// sized only the fourth, so six lanes put 18 unbounded checks on 11 cores: measured on that machine,
|
|
167
|
+
// one gate took 254.1s with lint alone at 252.9s against the 5.2s the table above records for it
|
|
168
|
+
// solo. The obvious repair — hand each of the other three a worker count the way the unit suite gets
|
|
169
|
+
// one — **does not exist to be applied**: eslint 10's `--concurrency` defaults to `off` and is
|
|
170
|
+
// already single-threaded, `tsc` is one process, and cspell's CLI exposes no thread count at all.
|
|
171
|
+
// Nothing in those three takes a number, so how many of them run beside each other is the only
|
|
172
|
+
// quantity the gate controls, and dividing the machine before admitting them is how it controls it.
|
|
173
|
+
//
|
|
174
|
+
// **Narrowing is not skipping.** Every one of the four checks still runs, over the same files, and
|
|
175
|
+
// the gate still reports every failure in one pass — `bounded_pool` queues what it does not start,
|
|
176
|
+
// and no check ever rejects (see `run_gate_steps`). What changes is how many are in flight at
|
|
177
|
+
// once, which is scheduling and never coverage.
|
|
178
|
+
function resolve_concurrency(
|
|
179
|
+
available_cores: number,
|
|
180
|
+
concurrent_runs: number = unit_worker_share.SOLO_RUNS,
|
|
181
|
+
checks: ReadonlyArray<GateCheck> = GATE_CHECKS,
|
|
182
|
+
): number {
|
|
183
|
+
const share = shared_cores(available_cores, concurrent_runs)
|
|
184
|
+
let admitted = 0
|
|
185
|
+
let reserved = 0
|
|
186
|
+
|
|
187
|
+
for (const check of checks) {
|
|
188
|
+
reserved += check.reserved_cores
|
|
189
|
+
|
|
190
|
+
if (reserved > share) break
|
|
191
|
+
|
|
192
|
+
admitted += 1
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return Math.max(MIN_CONCURRENCY, admitted)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// The cores left once the other three have their share — on the measured machine, 7 of 11, which
|
|
199
|
+
// held the gate's wall time inside run-to-run noise while burning 5–6% less CPU (101s against
|
|
200
|
+
// 107s). A machine smaller than the measured one is left uncapped; see `MEASURED_CORES`.
|
|
201
|
+
//
|
|
202
|
+
// **The table above is a measurement of one gate on an idle machine, and `concurrent_runs` is what
|
|
203
|
+
// says whether that is the situation** (joshuafolkken/kit#1515). Six lanes each reading "11 cores,
|
|
204
|
+
// take 7" put 42 workers on 11 cores, at a load average of 14.97, and the gate had no way to know the
|
|
205
|
+
// other five existed. Where more than one unit run is in flight the machine is divided between them
|
|
206
|
+
// instead, by `unit-worker-share.ts`, which is the same answer `test-unit-guard.ts` gives the pre-push
|
|
207
|
+
// hook. At one run — every solo gate, CI included — the number is exactly what it was.
|
|
208
|
+
//
|
|
209
|
+
// **The shared branch drops `RESERVED_CORES`, knowingly, and it is not a strict improvement.** Each
|
|
210
|
+
// concurrent gate still runs lint, the type check and the spell check beside its unit step, and the
|
|
211
|
+
// share below does not subtract them: on 12 cores a solo gate takes 8 unit workers plus 3 siblings —
|
|
212
|
+
// 11 processes for 12 cores — while two concurrent gates take 6 each plus 3 siblings each, which is 18.
|
|
213
|
+
// The obvious correction, `⌊(cores − RESERVED_CORES × runs) ÷ runs⌋`, is **not** applied because
|
|
214
|
+
// nothing has measured it: it hands two gates on an 11-core machine one worker apiece, against the
|
|
215
|
+
// 11.7s-at-8-workers / 16.7s-at-4 curve the table above was built from, and trading a measured
|
|
216
|
+
// oversubscription for an unmeasured starvation is not an improvement anyone can defend. What *is*
|
|
217
|
+
// measured is the unit half — six concurrent suites went from ten timeouts to none at this share.
|
|
218
|
+
//
|
|
219
|
+
// **joshuafolkken/kit#1547 narrowed `resolve_concurrency` and deliberately left this number alone.**
|
|
220
|
+
// A narrowed gate no longer runs its three siblings *beside* its unit step, so the paragraph above
|
|
221
|
+
// now over-states what the share is competing with — which is an argument for widening it, and
|
|
222
|
+
// widening it is exactly the unmeasured move that paragraph refuses. The number #1515 measured stays
|
|
223
|
+
// until something measures a better one on this machine.
|
|
224
|
+
//
|
|
225
|
+
// **The count is a parameter rather than a read.** This module stays a pure function of its inputs, so
|
|
226
|
+
// its own assertions are about arithmetic and not about what happened to be running while they ran;
|
|
227
|
+
// `verification-gate.ts` is where the machine is asked.
|
|
228
|
+
function resolve_unit_worker_cap(
|
|
229
|
+
available_cores: number,
|
|
230
|
+
concurrent_runs: number = unit_worker_share.SOLO_RUNS,
|
|
231
|
+
): number | undefined {
|
|
232
|
+
const share = unit_worker_share.resolve_unit_workers(available_cores, concurrent_runs)
|
|
233
|
+
|
|
234
|
+
if (share !== undefined) return share
|
|
235
|
+
if (available_cores < MEASURED_CORES) return undefined
|
|
236
|
+
|
|
237
|
+
return available_cores - RESERVED_CORES
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// The cores a check reserves from the machine-wide budget while it runs (joshuafolkken/kit#2351). The
|
|
241
|
+
// static checks declare their measured reservation; the unit suite declares the pool it will open,
|
|
242
|
+
// which `unit_worker_cap` has already sized against the runs in flight. **This is the same table, read
|
|
243
|
+
// once**: no second set of weights is introduced, so a change to the measured reservation moves the
|
|
244
|
+
// admission with it.
|
|
245
|
+
//
|
|
246
|
+
// **A solo gate's four weights sum to exactly the core count** — `reserved(2 + 1 + 1) +
|
|
247
|
+
// unit_cap(cores - 4)` is `cores` — which is what lets every check of a lone gate be admitted at once,
|
|
248
|
+
// its concurrency unchanged. A machine below the measured one leaves the unit suite uncapped and reads
|
|
249
|
+
// its weight from the same identity, `cores - RESERVED_CORES` clamped at zero, so the sum is the core
|
|
250
|
+
// count there too.
|
|
251
|
+
function check_weight(check: GateCheck, plan: GatePlan, available_cores: number): number {
|
|
252
|
+
if (check.label !== UNIT_LABEL) return check.reserved_cores
|
|
253
|
+
|
|
254
|
+
return plan.unit_worker_cap ?? Math.max(0, available_cores - RESERVED_CORES)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// `availableParallelism()` rather than `cpus().length`: it reports what this process may actually
|
|
258
|
+
// use, so a container with a CPU quota is sized by the quota rather than by the host.
|
|
259
|
+
// The three fields together, for a caller that has already decided the numbers. The gate's own
|
|
260
|
+
// suites need plans the resolver would never produce — a serial one, a capped one — and building
|
|
261
|
+
// them by hand meant restating the check list at every literal, so a field added to `GatePlan` broke
|
|
262
|
+
// each of them individually. One constructor is what keeps a new field from being an edit per plan.
|
|
263
|
+
function plan_of(
|
|
264
|
+
concurrency: number,
|
|
265
|
+
unit_worker_cap?: number,
|
|
266
|
+
checks: ReadonlyArray<GateCheck> = GATE_CHECKS,
|
|
267
|
+
): GatePlan {
|
|
268
|
+
return { checks, concurrency, unit_worker_cap }
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
//
|
|
272
|
+
// **The worker cap follows the checks rather than the machine.** A plan with no unit step has no
|
|
273
|
+
// unit suite to size, so it carries no cap — leaving one on would print a worker count for a check
|
|
274
|
+
// this run never starts.
|
|
275
|
+
function resolve_gate_plan(
|
|
276
|
+
available_cores: number = availableParallelism(),
|
|
277
|
+
concurrent_runs: number = unit_worker_share.SOLO_RUNS,
|
|
278
|
+
is_unit_included = true,
|
|
279
|
+
): GatePlan {
|
|
280
|
+
const checks = select_gate_checks(is_unit_included)
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
checks,
|
|
284
|
+
concurrency: resolve_concurrency(available_cores, concurrent_runs, checks),
|
|
285
|
+
unit_worker_cap: is_unit_included
|
|
286
|
+
? resolve_unit_worker_cap(available_cores, concurrent_runs)
|
|
287
|
+
: undefined,
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Printed once per run, so a gate that was slow on someone else's machine can be read without
|
|
292
|
+
// re-deriving the plan from their core count.
|
|
293
|
+
//
|
|
294
|
+
// **The two fragments come from `josh-verdict.ts` since joshuafolkken/kit#1379.** `josh time` matches
|
|
295
|
+
// this line to tell where a gate run's output begins — it is the one line the gate prints before any
|
|
296
|
+
// check body exists — so the printer and the detector build it from the same strings, exactly as they
|
|
297
|
+
// already do for the verdict.
|
|
298
|
+
// **The machine is described as shared only when it is.** A solo gate prints exactly the line it
|
|
299
|
+
// always printed — which is what keeps `josh time`'s detector, and every reader used to the old
|
|
300
|
+
// output, unaffected — while a narrowed one says why it is narrow, so a lane owner reading a slow
|
|
301
|
+
// gate is not left deriving the reason from a worker count that looks wrong (joshuafolkken/kit#1515).
|
|
302
|
+
function format_machine(available_cores: number, concurrent_runs: number): string {
|
|
303
|
+
const cores = `${String(available_cores)} cores`
|
|
304
|
+
|
|
305
|
+
if (concurrent_runs <= unit_worker_share.SOLO_RUNS) return cores
|
|
306
|
+
|
|
307
|
+
return `${cores}, ${String(concurrent_runs)} unit runs`
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// **A gate that is not running the unit suite says so where the worker count would go.** The line is
|
|
311
|
+
// what a slow or surprising gate is read against, and "3 of 3" alone would leave a reader deriving
|
|
312
|
+
// which three from the check bodies below it.
|
|
313
|
+
function format_unit_cap(plan: GatePlan): string {
|
|
314
|
+
if (!has_unit_check(plan.checks)) return `${UNIT_LABEL} elsewhere`
|
|
315
|
+
if (plan.unit_worker_cap === undefined) return `${UNIT_LABEL} unrestricted`
|
|
316
|
+
|
|
317
|
+
return `${UNIT_LABEL} at ${String(plan.unit_worker_cap)} workers`
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function format_gate_plan(
|
|
321
|
+
plan: GatePlan,
|
|
322
|
+
available_cores: number = availableParallelism(),
|
|
323
|
+
concurrent_runs: number = unit_worker_share.SOLO_RUNS,
|
|
324
|
+
): string {
|
|
325
|
+
const cap = format_unit_cap(plan)
|
|
326
|
+
const count = `${String(plan.concurrency)} of ${String(plan.checks.length)}`
|
|
327
|
+
const width = `${count}${josh_verdict.GATE_OPENING_MARK}`
|
|
328
|
+
const machine = format_machine(available_cores, concurrent_runs)
|
|
329
|
+
|
|
330
|
+
return `${josh_verdict.GATE_OPENING_PREFIX}${width}, ${cap} (${machine})`
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const gate_plan = {
|
|
334
|
+
BEHAVIOR_LABEL,
|
|
335
|
+
GATE_CHECKS,
|
|
336
|
+
LINT_LABEL,
|
|
337
|
+
MEASURED_CORES,
|
|
338
|
+
RESERVED_CORES,
|
|
339
|
+
STATIC_CHECKS,
|
|
340
|
+
TYPE_CHECK_LABEL,
|
|
341
|
+
UNIT_LABEL,
|
|
342
|
+
WARNING_CHECKER_LABELS,
|
|
343
|
+
check_weight,
|
|
344
|
+
format_gate_plan,
|
|
345
|
+
format_machine,
|
|
346
|
+
format_unit_cap,
|
|
347
|
+
has_unit_check,
|
|
348
|
+
plan_of,
|
|
349
|
+
resolve_concurrency,
|
|
350
|
+
resolve_gate_plan,
|
|
351
|
+
resolve_unit_worker_cap,
|
|
352
|
+
select_gate_checks,
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export type { GateCheck, GatePlan }
|
|
356
|
+
export { gate_plan }
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { GATE_COMMAND } from '#scripts/josh/josh-command-types'
|
|
2
|
+
import { josh_verdict } from '#scripts/josh/josh-verdict'
|
|
3
|
+
import { buffered_process, type BufferedProcessResult } from '#scripts/lib/buffered-process'
|
|
4
|
+
import { status_icons } from '#scripts/lib/status-icons'
|
|
5
|
+
import { test_unit_guard } from '#scripts/test/test-unit-guard'
|
|
6
|
+
import { gate_log } from './gate-log'
|
|
7
|
+
import { gate_plan } from './gate-plan'
|
|
8
|
+
|
|
9
|
+
// The gate's console reporting, split out of `verification-gate.ts` so that file stays under its line
|
|
10
|
+
// ceiling while it grows the scoped pre-check and the failure summary (joshuafolkken/kit#2296). Nothing
|
|
11
|
+
// about what is printed changes in the move: the four blocks, the log notice and the verdict come out
|
|
12
|
+
// exactly as before, with one addition — the per-failure action lines below.
|
|
13
|
+
|
|
14
|
+
const { FAIL_ICON, PASS_ICON } = status_icons
|
|
15
|
+
|
|
16
|
+
interface GateStep {
|
|
17
|
+
label: string
|
|
18
|
+
command_args: ReadonlyArray<string>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface GateStepResult extends BufferedProcessResult {
|
|
22
|
+
label: string
|
|
23
|
+
// What was actually run. The type check's command is resolved per project, so a failure on the
|
|
24
|
+
// `check` step is only reproducible if the header names the command rather than the label.
|
|
25
|
+
command: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function is_gate_step_failed(result: GateStepResult): boolean {
|
|
29
|
+
return buffered_process.is_process_failed(result)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// A passing check's output is not read. What a green gate has to say is "all four passed", and
|
|
33
|
+
// `print_gate_summary` already says it in one line — while the four bodies, vitest's per-file
|
|
34
|
+
// listing among them, run to tens of kilobytes that then sit in the conversation and are re-read on
|
|
35
|
+
// every later turn. The gate runs more than once per Issue, so the cost is per run, not per Issue
|
|
36
|
+
// (joshuafolkken/kit#967).
|
|
37
|
+
//
|
|
38
|
+
// A failing check keeps its whole output: that is the one time the body is the answer. So does a
|
|
39
|
+
// check that **passed without running** — `test-unit-guard` exits 0 with a notice when vitest is
|
|
40
|
+
// absent, and suppressing that made a gate which ran zero tests print the same five lines as one
|
|
41
|
+
// that ran them all. The marker comes from the guard itself rather than being matched by eye, so
|
|
42
|
+
// the two cannot drift apart.
|
|
43
|
+
function is_skip_notice(result: GateStepResult): boolean {
|
|
44
|
+
return result.output.includes(test_unit_guard.SKIP_MARKER)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// A check can exit 0 and still have something to say: `lint-parallel` runs eslint without
|
|
48
|
+
// `--max-warnings 0`, and svelte-check reports warnings the same way. Suppressing those would let a
|
|
49
|
+
// gate report "passed" with the warnings invisible, which is the same failure as hiding a skip.
|
|
50
|
+
//
|
|
51
|
+
// Unlike the skip marker this *is* a heuristic — the words come from third-party tools, so there is
|
|
52
|
+
// no constant to share with them. It is deliberately loose: a false positive costs one printed body,
|
|
53
|
+
// a false negative hides a warning, and only one of those is worth avoiding.
|
|
54
|
+
const WARNING_MARKERS: ReadonlyArray<string> = ['warning', 'Warning', '⚠']
|
|
55
|
+
|
|
56
|
+
function has_warnings(result: GateStepResult): boolean {
|
|
57
|
+
return WARNING_MARKERS.some((marker) => result.output.includes(marker))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// The withholding path's counterpart to `has_warnings`, and deliberately narrower than it
|
|
61
|
+
// (joshuafolkken/kit#2318). `has_warnings` is read by `should_print_body`, where a false positive
|
|
62
|
+
// costs one printed body — the loose match above is right there. `record_green_gate` reads *this*
|
|
63
|
+
// one, where a false positive is not one printed line but the whole green record withheld, which
|
|
64
|
+
// turns a green gate's `run:review --join` red. So the record is withheld only for a warning from a
|
|
65
|
+
// checker that actually emits per-tree warnings (`WARNING_CHECKER_LABELS`), never for a benign line
|
|
66
|
+
// from another tool that happens to contain the word — a Vite config deprecation on `test:unit` was
|
|
67
|
+
// the line that stopped a green gate's commit chain.
|
|
68
|
+
//
|
|
69
|
+
// **The safe-chain shim's banner is not the checker's either** (joshuafolkken/kit#2447). Where
|
|
70
|
+
// `setup-ci` installed the shims but the binary cannot be reached, every `pnpm` a check spawns prints
|
|
71
|
+
// "Warning: safe-chain is not available …" into that check's output, so a green lint withheld the
|
|
72
|
+
// record on every CI run. The banner's lines are dropped before the match; a real warning on any
|
|
73
|
+
// other line still withholds.
|
|
74
|
+
const SAFE_CHAIN_BANNER = 'safe-chain is not available'
|
|
75
|
+
|
|
76
|
+
function has_checker_warning(result: GateStepResult): boolean {
|
|
77
|
+
if (!gate_plan.WARNING_CHECKER_LABELS.includes(result.label)) return false
|
|
78
|
+
|
|
79
|
+
return result.output
|
|
80
|
+
.split('\n')
|
|
81
|
+
.some(
|
|
82
|
+
(line) =>
|
|
83
|
+
!line.includes(SAFE_CHAIN_BANNER) &&
|
|
84
|
+
WARNING_MARKERS.some((marker) => line.includes(marker)),
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function should_print_body(result: GateStepResult, is_verbose: boolean): boolean {
|
|
89
|
+
if (is_verbose || is_gate_step_failed(result)) return true
|
|
90
|
+
|
|
91
|
+
return is_skip_notice(result) || has_warnings(result)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Seconds to one decimal, which is the resolution the answer is read at: the question a gate's
|
|
95
|
+
// timing answers is "which of the four is the long pole", and no check is ever separated from
|
|
96
|
+
// another by less than a tenth of a second (joshuafolkken/kit#1248).
|
|
97
|
+
const MS_PER_SECOND = 1000
|
|
98
|
+
const SECONDS_DECIMALS = 1
|
|
99
|
+
|
|
100
|
+
function format_seconds(elapsed_ms: number): string {
|
|
101
|
+
return `${(elapsed_ms / MS_PER_SECOND).toFixed(SECONDS_DECIMALS)}s`
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// The duration goes at the **end** of the header, after the command. The header's first job is
|
|
105
|
+
// naming the one command to re-run while fixing (`docs/josh-commands.md` → `josh gate`), and a
|
|
106
|
+
// number spliced in front of it would push that name out of the place a reader scans for it.
|
|
107
|
+
//
|
|
108
|
+
// Built rather than inlined because the log file names each section with the same string
|
|
109
|
+
// (joshuafolkken/kit#1227): a header written twice is a header the two copies can disagree about,
|
|
110
|
+
// and the log exists precisely to be read when the console's copy has been elided.
|
|
111
|
+
function gate_step_header(result: GateStepResult): string {
|
|
112
|
+
const icon = is_gate_step_failed(result) ? FAIL_ICON : PASS_ICON
|
|
113
|
+
|
|
114
|
+
return `${icon} ${result.label} (pnpm ${result.command}) ${format_seconds(result.elapsed_ms)}`
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function print_gate_step(result: GateStepResult, is_verbose: boolean): void {
|
|
118
|
+
process.stdout.write(`\n${gate_step_header(result)}\n`)
|
|
119
|
+
|
|
120
|
+
if (should_print_body(result, is_verbose) && result.output) {
|
|
121
|
+
process.stdout.write(`${result.output}\n`)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// **One line per failed check, naming the command that reproduces it, printed at the tail just above
|
|
126
|
+
// the verdict** (joshuafolkken/kit#2296). A red gate used to report every failing check only in its
|
|
127
|
+
// bodies, which is where truncation lands: the run picked one failure at a time across separate gate
|
|
128
|
+
// runs because it could not read the rest. The verdict names *which* checks failed; this names *what
|
|
129
|
+
// to run* for each, and it sits in the same tail window the verdict and the log notice already
|
|
130
|
+
// occupy, so a `tail -40` keeps it. The verdict stays the last line for the reason `josh-verdict.ts`
|
|
131
|
+
// gives.
|
|
132
|
+
function format_failure_actions(failed: ReadonlyArray<GateStepResult>): string {
|
|
133
|
+
if (failed.length === 0) return ''
|
|
134
|
+
|
|
135
|
+
const lines = failed.map(
|
|
136
|
+
(result) => ` ${FAIL_ICON} ${result.label} — re-run: pnpm ${result.command}`,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
return `${GATE_COMMAND} — next:\n${lines.join('\n')}\n`
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// The total is wall-clock for the whole command, not the sum of the four — they run concurrently,
|
|
143
|
+
// so a sum would report about three times what the caller waited.
|
|
144
|
+
//
|
|
145
|
+
// The failure actions and the log path are printed with the summary and immediately **above** the
|
|
146
|
+
// verdict line, which stays last for the reason `josh-verdict.ts` gives (joshuafolkken/kit#1227).
|
|
147
|
+
function print_gate_summary(
|
|
148
|
+
failed: ReadonlyArray<GateStepResult>,
|
|
149
|
+
elapsed_ms: number,
|
|
150
|
+
step_count: string,
|
|
151
|
+
log_path?: string,
|
|
152
|
+
): void {
|
|
153
|
+
const total = format_seconds(elapsed_ms)
|
|
154
|
+
const verdict =
|
|
155
|
+
failed.length === 0
|
|
156
|
+
? josh_verdict.format_gate_passed(step_count, total)
|
|
157
|
+
: josh_verdict.format_gate_failed(failed.map((result) => result.label).join(', '), total)
|
|
158
|
+
|
|
159
|
+
process.stdout.write(
|
|
160
|
+
`\n${format_failure_actions(failed)}${gate_log.format_log_notice(log_path)}${verdict}\n`,
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
interface GateReport {
|
|
165
|
+
is_verbose: boolean
|
|
166
|
+
log_path: string | undefined
|
|
167
|
+
elapsed_ms: number
|
|
168
|
+
step_count: string
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Everything a finished run says, in the order a reader meets it: the four blocks, then the log the
|
|
172
|
+
// blocks may have been elided out of, then the failure actions and the verdict. **Every check's whole
|
|
173
|
+
// output goes into the log, the ones the console dropped included** (joshuafolkken/kit#967).
|
|
174
|
+
function report_gate_steps(
|
|
175
|
+
results: ReadonlyArray<GateStepResult>,
|
|
176
|
+
report: GateReport,
|
|
177
|
+
): ReadonlyArray<string> {
|
|
178
|
+
for (const result of results) print_gate_step(result, report.is_verbose)
|
|
179
|
+
|
|
180
|
+
const entries = results.map((result) => ({
|
|
181
|
+
header: gate_step_header(result),
|
|
182
|
+
output: result.output,
|
|
183
|
+
}))
|
|
184
|
+
const failed = results.filter((result) => is_gate_step_failed(result))
|
|
185
|
+
const written_log = gate_log.write_gate_log(entries, report.log_path)
|
|
186
|
+
|
|
187
|
+
print_gate_summary(failed, report.elapsed_ms, report.step_count, written_log)
|
|
188
|
+
|
|
189
|
+
return failed.map((result) => result.label)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const gate_report = {
|
|
193
|
+
format_failure_actions,
|
|
194
|
+
format_seconds,
|
|
195
|
+
gate_step_header,
|
|
196
|
+
has_checker_warning,
|
|
197
|
+
has_warnings,
|
|
198
|
+
is_gate_step_failed,
|
|
199
|
+
is_skip_notice,
|
|
200
|
+
print_gate_step,
|
|
201
|
+
print_gate_summary,
|
|
202
|
+
report_gate_steps,
|
|
203
|
+
should_print_body,
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export type { GateReport, GateStep, GateStepResult }
|
|
207
|
+
export { gate_report }
|