@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,59 @@
|
|
|
1
|
+
import { lane_registry } from '#scripts/lane/lane-registry'
|
|
2
|
+
import { run_progress_clock } from './run-progress-clock'
|
|
3
|
+
|
|
4
|
+
// A watcher that stopped while children are still in-flight leaves the parent blind to completions
|
|
5
|
+
// for up to the full heartbeat interval. This guard detects that state so a hook can refuse the
|
|
6
|
+
// calls that follow a missed restart (joshuafolkken/kit#2113).
|
|
7
|
+
//
|
|
8
|
+
// **Staleness threshold is `TICK_MULTIPLIER` watcher ticks.** The watcher pings its life record on
|
|
9
|
+
// every tick (every 30 s), so a gap wider than three ticks means the process has almost certainly
|
|
10
|
+
// stopped: either the bound expired or the session was cut without a restart. Three gives one missed
|
|
11
|
+
// tick of slack before the guard fires.
|
|
12
|
+
//
|
|
13
|
+
// **It watches no relay** (joshuafolkken/kit#2492). A session following the run's event stream after a
|
|
14
|
+
// cut used to be held to it here; that relay re-read the session's whole history per event, so the
|
|
15
|
+
// stream is now watched from a pane of its own (`run:event --watch`) and no session owes it.
|
|
16
|
+
|
|
17
|
+
const WATCHER_TICK_MS = 30_000
|
|
18
|
+
const TICK_MULTIPLIER = 3
|
|
19
|
+
const MS_PER_SECOND = 1000
|
|
20
|
+
|
|
21
|
+
const STALE_THRESHOLD_MS = WATCHER_TICK_MS * TICK_MULTIPLIER
|
|
22
|
+
const STALE_THRESHOLD_S = STALE_THRESHOLD_MS / MS_PER_SECOND
|
|
23
|
+
|
|
24
|
+
const STALE_NOTE =
|
|
25
|
+
`Lane children are in-flight but the progress watcher has not pinged in the last ` +
|
|
26
|
+
`${String(STALE_THRESHOLD_S)}s — run \`pnpm josh run:progress --wait\` in the background before proceeding`
|
|
27
|
+
|
|
28
|
+
type GuardResult = { kind: 'ok' } | { kind: 'stale'; note: string }
|
|
29
|
+
|
|
30
|
+
const OK_RESULT: GuardResult = { kind: 'ok' }
|
|
31
|
+
|
|
32
|
+
// The lanes a parent is still waiting on. A stranded lane has no child working in it, so it is not
|
|
33
|
+
// in-flight — the one definition both this guard and the headless stop rule read (`run-headless.ts`).
|
|
34
|
+
async function has_lanes_in_flight(): Promise<boolean> {
|
|
35
|
+
const all_lanes = await lane_registry.list_lanes()
|
|
36
|
+
|
|
37
|
+
return all_lanes.some((lane) => !lane.is_stranded)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// `life_target` is the path returned by `run_progress_read.stamp_target()` or
|
|
41
|
+
// `run_progress_clock.life_target_of(git_directory)`. Passed in rather than resolved here so the
|
|
42
|
+
// caller can use whichever resolution fits its sync/async context.
|
|
43
|
+
async function check(life_target: string): Promise<GuardResult> {
|
|
44
|
+
if (!(await has_lanes_in_flight())) return OK_RESULT
|
|
45
|
+
|
|
46
|
+
if (run_progress_clock.is_life_fresh(life_target, STALE_THRESHOLD_MS)) return OK_RESULT
|
|
47
|
+
|
|
48
|
+
return { kind: 'stale', note: STALE_NOTE }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const run_watcher_guard = {
|
|
52
|
+
STALE_NOTE,
|
|
53
|
+
STALE_THRESHOLD_MS,
|
|
54
|
+
check,
|
|
55
|
+
has_lanes_in_flight,
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type { GuardResult }
|
|
59
|
+
export { run_watcher_guard }
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { hook_decision } from '#scripts/josh/hook-decision'
|
|
2
|
+
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
import { run_progress_read } from './run-progress-read'
|
|
5
|
+
import { run_watcher_guard } from './run-watcher-guard'
|
|
6
|
+
|
|
7
|
+
// The `PreToolUse` adapter that turns `run_watcher_guard`'s verdict into a deny reason, so the guard
|
|
8
|
+
// the CLI already carries is finally *called* on every tool call rather than left to prose asking the
|
|
9
|
+
// run to call it (joshuafolkken/kit#2353). It is composed into `pretool-guard.ts` — the one PreToolUse
|
|
10
|
+
// hook, kept one by joshuafolkken/kit#1930 — rather than added as a second `.claude/settings.json`
|
|
11
|
+
// entry, so the consolidation invariant holds; the detection itself is unchanged.
|
|
12
|
+
//
|
|
13
|
+
// **It fires once per run, for the same reason every guard here stamps.** A stale watcher would other-
|
|
14
|
+
// wise refuse *every* tool call, including the `pnpm josh run:progress --wait` that fixes it — a wedge.
|
|
15
|
+
// So the first stale call is refused and that refusal is recorded; the next call, the restart, is
|
|
16
|
+
// allowed. Restarting the watcher pings its life record fresh, so the guard falls silent on its own.
|
|
17
|
+
//
|
|
18
|
+
// **A dispatched lane child is exempt.** Only the outermost run keeps a watcher (`run-progress-cli.ts`),
|
|
19
|
+
// so a child carrying `JOSH_LANE_CHILD` must not be refused for a watcher it was never meant to start.
|
|
20
|
+
|
|
21
|
+
const SWITCH_ENV_KEY = 'JOSH_WATCHER_GUARD'
|
|
22
|
+
const STAMP_PREFIX = 'josh-watcher-guard-'
|
|
23
|
+
|
|
24
|
+
const payload_schema = z.object({ transcript_path: z.string().min(1) })
|
|
25
|
+
|
|
26
|
+
function transcript_of(raw_payload: string): string | undefined {
|
|
27
|
+
try {
|
|
28
|
+
const parsed = payload_schema.safeParse(JSON.parse(raw_payload))
|
|
29
|
+
|
|
30
|
+
return parsed.success ? parsed.data.transcript_path : undefined
|
|
31
|
+
} catch {
|
|
32
|
+
return undefined
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// The once-per-run arm: refuse only when nothing has been recorded yet, and record before returning so
|
|
37
|
+
// the refusal cannot repeat on the call in hand. A record that cannot be written allows the call — the
|
|
38
|
+
// fail-open direction the transcript guards take for the same reason.
|
|
39
|
+
function fires_once(transcript: string, now_ms: number): boolean {
|
|
40
|
+
const stamp = hook_decision.create_refusal_stamp(STAMP_PREFIX)
|
|
41
|
+
const target = stamp.path(transcript)
|
|
42
|
+
|
|
43
|
+
if (stamp.last_ms(target) !== hook_decision.NEVER_MS) return false
|
|
44
|
+
|
|
45
|
+
return stamp.record(target, now_ms)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// The guard is off when its switch is disabled or when this session is a dispatched lane child, which
|
|
49
|
+
// runs no watcher of its own.
|
|
50
|
+
function is_active(): boolean {
|
|
51
|
+
return (
|
|
52
|
+
hook_decision.is_switch_enabled(SWITCH_ENV_KEY) &&
|
|
53
|
+
lane_child_marker.marked_issue() === undefined
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// The guard's note when the watcher is stale and this call is the once-per-run one that refuses, or
|
|
58
|
+
// `undefined` when the watcher is fresh (or the refusal was already spent this run). No session is asked
|
|
59
|
+
// to relay the run's stream any more — the watch pane does (joshuafolkken/kit#2492).
|
|
60
|
+
async function stale_reason(transcript: string, now_ms: number): Promise<string | undefined> {
|
|
61
|
+
const result = await run_watcher_guard.check(await run_progress_read.live_target())
|
|
62
|
+
|
|
63
|
+
if (result.kind === 'ok') return undefined
|
|
64
|
+
|
|
65
|
+
return fires_once(transcript, now_ms) ? result.note : undefined
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// The deny reason for a tool call that arrives while lane children are in-flight and the watcher has
|
|
69
|
+
// gone stale, or `undefined` when the call proceeds. Async because the lane listing and the life
|
|
70
|
+
// record are read from disk; the composing hook already awaits.
|
|
71
|
+
async function watcher_hook_reason(
|
|
72
|
+
raw_payload: string,
|
|
73
|
+
now_ms: number = Date.now(),
|
|
74
|
+
): Promise<string | undefined> {
|
|
75
|
+
if (!is_active()) return undefined
|
|
76
|
+
|
|
77
|
+
const transcript = transcript_of(raw_payload)
|
|
78
|
+
|
|
79
|
+
if (transcript === undefined) return undefined
|
|
80
|
+
|
|
81
|
+
return await stale_reason(transcript, now_ms)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const run_watcher_hook = { SWITCH_ENV_KEY, STAMP_PREFIX, watcher_hook_reason }
|
|
85
|
+
|
|
86
|
+
export { run_watcher_hook }
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { existsSync } from 'node:fs'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { resolve_local_bin } from '#scripts/build/local-bin'
|
|
5
|
+
import { resolve_spawn_exit } from '#scripts/lib/spawn-exit'
|
|
6
|
+
import { execaSync } from 'execa'
|
|
7
|
+
|
|
8
|
+
const SECRETLINT_BIN = 'secretlint'
|
|
9
|
+
const NO_GLOB_FLAG = '--no-glob'
|
|
10
|
+
const ARGV_OFFSET = 2
|
|
11
|
+
|
|
12
|
+
// The scan is defense in depth ahead of GitHub push protection, not the only gate, so a
|
|
13
|
+
// missing binary must not block the commit. kit ships the pre-commit rule inside
|
|
14
|
+
// lefthook/base.yml, but secretlint itself resolves from the consumer project — `josh init`
|
|
15
|
+
// and `josh sync` add it to the consumer devDependencies, because pnpm's isolated layout
|
|
16
|
+
// never exposes a kit dependency's bin to the consumer's `pnpm exec`. Upgrading kit therefore
|
|
17
|
+
// activates this hook one `josh sync` + `pnpm install` ahead of the binary, and a bare
|
|
18
|
+
// `pnpm exec secretlint` turns that window into a hard failure on every commit (kit#695).
|
|
19
|
+
const MISSING_NOTICE =
|
|
20
|
+
`⚠️ secretlint is not installed — skipping the staged-file secret scan.\n` +
|
|
21
|
+
` The kit pre-commit hook ships ahead of the dependency it needs.\n` +
|
|
22
|
+
` Run \`pnpm josh sync && pnpm install\` to provision it.`
|
|
23
|
+
|
|
24
|
+
type ScanDecision = { kind: 'skip'; notice?: string } | { kind: 'scan'; binary: string }
|
|
25
|
+
|
|
26
|
+
function resolve_secretlint_binary(project_root: string): string | undefined {
|
|
27
|
+
const candidate = resolve_local_bin(project_root, SECRETLINT_BIN)
|
|
28
|
+
|
|
29
|
+
return existsSync(candidate) ? candidate : undefined
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// lefthook substitutes literal paths, so `--no-glob` is mandatory: a SvelteKit route directory
|
|
33
|
+
// such as `(app)` or `[id]` would otherwise reach secretlint's glob engine as a pattern.
|
|
34
|
+
// Masking and the .gitignore cascade are both on by default in v13 — no flag adds them.
|
|
35
|
+
function build_scan_arguments(staged_files: ReadonlyArray<string>): Array<string> {
|
|
36
|
+
return [NO_GLOB_FLAG, ...staged_files]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function plan_scan(staged_files: ReadonlyArray<string>, project_root: string): ScanDecision {
|
|
40
|
+
if (staged_files.length === 0) return { kind: 'skip' }
|
|
41
|
+
|
|
42
|
+
const binary = resolve_secretlint_binary(project_root)
|
|
43
|
+
|
|
44
|
+
if (binary === undefined) return { kind: 'skip', notice: MISSING_NOTICE }
|
|
45
|
+
|
|
46
|
+
return { kind: 'scan', binary }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// No `shell` option on purpose. execa resolves a Windows `.cmd` shim itself and escapes the
|
|
50
|
+
// arguments for cmd.exe's double expansion; turning the shell on would bypass that and let a
|
|
51
|
+
// staged path containing a space split into two paths — the scanner would then quietly walk
|
|
52
|
+
// the wrong files and report clean.
|
|
53
|
+
function run_scan(binary: string, staged_files: ReadonlyArray<string>): number {
|
|
54
|
+
const result = execaSync(binary, build_scan_arguments(staged_files), {
|
|
55
|
+
stdio: 'inherit',
|
|
56
|
+
reject: false,
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
return resolve_spawn_exit(binary, result)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function main(staged_files: ReadonlyArray<string>, project_root: string): number {
|
|
63
|
+
const decision = plan_scan(staged_files, project_root)
|
|
64
|
+
|
|
65
|
+
if (decision.kind === 'scan') return run_scan(decision.binary, staged_files)
|
|
66
|
+
|
|
67
|
+
if (decision.notice !== undefined) console.warn(decision.notice)
|
|
68
|
+
|
|
69
|
+
return 0
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
73
|
+
const exit_code = main(process.argv.slice(ARGV_OFFSET), process.cwd())
|
|
74
|
+
|
|
75
|
+
if (exit_code !== 0) process.exit(exit_code)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const secretlint_scan = {
|
|
79
|
+
build_scan_arguments,
|
|
80
|
+
main,
|
|
81
|
+
plan_scan,
|
|
82
|
+
resolve_secretlint_binary,
|
|
83
|
+
run_scan,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { MISSING_NOTICE, secretlint_scan }
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
|
|
3
|
+
const BINARY_NAME = 'osv-scanner'
|
|
4
|
+
const LOCKFILE_PATH = 'pnpm-lock.yaml'
|
|
5
|
+
|
|
6
|
+
// Where `josh audit:provision` puts a scanner it fetched itself, and the second place `josh audit`
|
|
7
|
+
// looks once PATH has come up empty (joshuafolkken/kit#1563). Under `node_modules` because that is
|
|
8
|
+
// the one directory every consumer of this package already ignores: a directory of our own would
|
|
9
|
+
// need a `.gitignore` entry distributed to every repository `josh sync` reaches, and a home-relative
|
|
10
|
+
// cache is refused outright by `no-global-shim-write.test.ts`. Losing the binary to `pnpm install`
|
|
11
|
+
// costs one re-fetch at the next session start, which is the cheap side of that trade.
|
|
12
|
+
const MANAGED_TOOL_SEGMENTS = ['node_modules', '.cache', 'josh-tools'] as const
|
|
13
|
+
const WINDOWS_PLATFORM = 'win32'
|
|
14
|
+
const WINDOWS_BINARY_SUFFIX = '.exe'
|
|
15
|
+
|
|
16
|
+
const INSTALL_INSTRUCTIONS = [
|
|
17
|
+
'',
|
|
18
|
+
'Install options:',
|
|
19
|
+
' Managed: pnpm josh audit:provision',
|
|
20
|
+
' macOS: brew install osv-scanner',
|
|
21
|
+
' Go: go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest',
|
|
22
|
+
' Docker: docker run --rm -v "$PWD:/src" ghcr.io/google/osv-scanner --lockfile=/src/pnpm-lock.yaml',
|
|
23
|
+
'',
|
|
24
|
+
'Docs: https://google.github.io/osv-scanner/',
|
|
25
|
+
].join('\n')
|
|
26
|
+
|
|
27
|
+
function build_scanner_arguments(lockfile_path: string): ReadonlyArray<string> {
|
|
28
|
+
return [`--lockfile=${lockfile_path}`]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// The `.exe` suffix is not cosmetic on Windows: a file written without it is not executable there,
|
|
32
|
+
// so the provisioner and the audit would disagree about whether the scanner had been installed.
|
|
33
|
+
function build_managed_binary_path(project_root: string, platform: string): string {
|
|
34
|
+
const suffix = platform === WINDOWS_PLATFORM ? WINDOWS_BINARY_SUFFIX : ''
|
|
35
|
+
|
|
36
|
+
return path.join(project_root, ...MANAGED_TOOL_SEGMENTS, `${BINARY_NAME}${suffix}`)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function format_missing_binary_error(binary_name: string): string {
|
|
40
|
+
return `${binary_name} is not installed.\n${INSTALL_INSTRUCTIONS}`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const security_audit_logic = {
|
|
44
|
+
BINARY_NAME,
|
|
45
|
+
LOCKFILE_PATH,
|
|
46
|
+
build_managed_binary_path,
|
|
47
|
+
build_scanner_arguments,
|
|
48
|
+
format_missing_binary_error,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { security_audit_logic }
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { security_audit_logic } from './security-audit-logic'
|
|
2
|
+
|
|
3
|
+
// Pinned, because an unpinned fetch is a binary nobody chose running against every lockfile in every
|
|
4
|
+
// consumer repository. The checksums below belong to this exact tag: bumping one without the other
|
|
5
|
+
// installs nothing at all, which is the failure that is visible rather than the one that is not.
|
|
6
|
+
//
|
|
7
|
+
// v2.6.0 is the floor because every earlier build parses only a fraction of pnpm-lock.yaml — the
|
|
8
|
+
// 2.5.1 and 2.3.5 scanners both read 19 of 584 packages and reported the tree clean while four High
|
|
9
|
+
// advisories sat in it (joshuafolkken/kit#2200). A scanner below the floor is a false negative, so
|
|
10
|
+
// the provisioned version and the floor move together.
|
|
11
|
+
const SCANNER_VERSION = '2.6.0'
|
|
12
|
+
const MINIMUM_SCANNER_VERSION = SCANNER_VERSION
|
|
13
|
+
const RELEASE_BASE_URL = 'https://github.com/google/osv-scanner/releases/download'
|
|
14
|
+
|
|
15
|
+
const WINDOWS_PLATFORM = 'win32'
|
|
16
|
+
const WINDOWS_ASSET_SUFFIX = '.exe'
|
|
17
|
+
const STAGING_SUFFIX = '.download'
|
|
18
|
+
|
|
19
|
+
// The asset is ~55 MB, and a link delivering it at 300 KB/s — measured, not hypothetical — takes
|
|
20
|
+
// over three minutes. A `SessionStart` hook is waited on, so a single bound generous enough to
|
|
21
|
+
// finish that download would be a three-minute stall at session start, and one short enough not to
|
|
22
|
+
// stall would abort every slow link for ever.
|
|
23
|
+
//
|
|
24
|
+
// So the bound depends on how the command was reached. The automatic attempt gives up quickly and
|
|
25
|
+
// says what to run; `--force` is a person typing a command in the foreground, where waiting for a
|
|
26
|
+
// large download is exactly what was asked for. Declared here rather than beside the `fetch` so the
|
|
27
|
+
// hook suite can derive the harness budget from the session bound: raising that without raising the
|
|
28
|
+
// declared timeout would have the harness kill the request at a moment the script did not choose.
|
|
29
|
+
const SESSION_DOWNLOAD_TIMEOUT_MS = 60_000
|
|
30
|
+
const FORCED_DOWNLOAD_TIMEOUT_MS = 600_000
|
|
31
|
+
|
|
32
|
+
function build_download_timeout(is_forced: boolean): number {
|
|
33
|
+
return is_forced ? FORCED_DOWNLOAD_TIMEOUT_MS : SESSION_DOWNLOAD_TIMEOUT_MS
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// How long a failed attempt suppresses the next one. Without it an offline machine — or one behind a
|
|
37
|
+
// proxy that blocks release assets — pays the whole download timeout again at every session start,
|
|
38
|
+
// and the `SessionStart` matcher is empty, so that is every startup, resume, clear and compact rather
|
|
39
|
+
// than once per machine. `--force` ignores the record, so a person who has just fixed their network
|
|
40
|
+
// never has to wait it out.
|
|
41
|
+
const MS_PER_HOUR = 3_600_000
|
|
42
|
+
const HOURS_BEFORE_RETRY = 6
|
|
43
|
+
const RETRY_INTERVAL_MS = HOURS_BEFORE_RETRY * MS_PER_HOUR
|
|
44
|
+
|
|
45
|
+
// node's names for the host on the left, the release's names on the right. A host missing from
|
|
46
|
+
// either map has no asset published for it, and the provisioner says so instead of guessing a URL.
|
|
47
|
+
const PLATFORM_NAMES: Readonly<Record<string, string>> = {
|
|
48
|
+
darwin: 'darwin',
|
|
49
|
+
linux: 'linux',
|
|
50
|
+
win32: 'windows',
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const ARCHITECTURE_NAMES: Readonly<Record<string, string>> = {
|
|
54
|
+
arm64: 'arm64',
|
|
55
|
+
x64: 'amd64',
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Transcribed from `osv-scanner_SHA256SUMS` of the tag above. Keyed by asset name so a wrong
|
|
59
|
+
// platform mapping cannot silently pick up a neighboring platform's checksum — which is why the keys
|
|
60
|
+
// are the release's own file names rather than anything this project's naming convention covers.
|
|
61
|
+
/* eslint-disable @typescript-eslint/naming-convention -- upstream release asset file names */
|
|
62
|
+
const ASSET_CHECKSUMS: Readonly<Record<string, string>> = {
|
|
63
|
+
'osv-scanner_darwin_amd64': '60c5296637e977b28eeda5c7f13573e447659a632922737f94d11fa7e30ad6ca',
|
|
64
|
+
'osv-scanner_darwin_arm64': '98c460dcd37de25819babd757d04542045b6243113e209edcd4d89fedb0256b4',
|
|
65
|
+
'osv-scanner_linux_amd64': 'ca69b3d3cd08f889a49dc0a383122f71cc528b83803671df5fd874d97485b108',
|
|
66
|
+
'osv-scanner_linux_arm64': '2c71403eb443d05891c4f268c3ad771cf4f16e5443463fd7851ef8f454d3c7e4',
|
|
67
|
+
'osv-scanner_windows_amd64.exe':
|
|
68
|
+
'e0ed7644118b717b028c249ee9d3515024e55e8510747ca08906eb96765354d6',
|
|
69
|
+
'osv-scanner_windows_arm64.exe':
|
|
70
|
+
'ca1379da0e408279ef2c85cde0846a903495738a91c7b065a208048437c1686c',
|
|
71
|
+
}
|
|
72
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
73
|
+
|
|
74
|
+
interface ScannerAsset {
|
|
75
|
+
name: string
|
|
76
|
+
url: string
|
|
77
|
+
sha256: string
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function build_asset_name(platform: string, architecture: string): string | undefined {
|
|
81
|
+
const platform_name = PLATFORM_NAMES[platform]
|
|
82
|
+
const architecture_name = ARCHITECTURE_NAMES[architecture]
|
|
83
|
+
if (platform_name === undefined || architecture_name === undefined) return undefined
|
|
84
|
+
|
|
85
|
+
const suffix = platform === WINDOWS_PLATFORM ? WINDOWS_ASSET_SUFFIX : ''
|
|
86
|
+
|
|
87
|
+
return `${security_audit_logic.BINARY_NAME}_${platform_name}_${architecture_name}${suffix}`
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function build_download_url(asset_name: string): string {
|
|
91
|
+
return `${RELEASE_BASE_URL}/v${SCANNER_VERSION}/${asset_name}`
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// The staging file the download is written to before it is renamed onto the target. The process id
|
|
95
|
+
// is what keeps two sessions of one project apart — the `SessionStart` matcher is empty, so a
|
|
96
|
+
// `clear` during a startup's download is exactly that — and without it their writes interleave into
|
|
97
|
+
// one file that both then rename into place, which the checksum cannot catch because each verified
|
|
98
|
+
// its own buffer.
|
|
99
|
+
function build_staging_path(target_path: string, process_id: number): string {
|
|
100
|
+
return `${target_path}.${String(process_id)}${STAGING_SUFFIX}`
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// The whole "where do we fetch from" decision in one pure call, so the table above is testable
|
|
104
|
+
// without a network round trip — which the unit suite forbids anyway (`test-network-guard.ts`).
|
|
105
|
+
function resolve_asset(platform: string, architecture: string): ScannerAsset | undefined {
|
|
106
|
+
const name = build_asset_name(platform, architecture)
|
|
107
|
+
if (name === undefined) return undefined
|
|
108
|
+
|
|
109
|
+
const sha256 = ASSET_CHECKSUMS[name]
|
|
110
|
+
if (sha256 === undefined) return undefined
|
|
111
|
+
|
|
112
|
+
return { name, sha256, url: build_download_url(name) }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function format_already_present(location: string): string {
|
|
116
|
+
return `osv-scanner is already available (${location}); nothing to provision.`
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function format_unsupported_platform(platform: string, architecture: string): string {
|
|
120
|
+
return `No pinned osv-scanner build for ${platform}/${architecture}; install it manually to run the pre-push audit.`
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// The `--force` hint is on this message rather than only on the backoff one because the failure this
|
|
124
|
+
// most often reports is the session bound running out on a slow link, and the command that finishes
|
|
125
|
+
// that download is the one thing the reader needs.
|
|
126
|
+
function format_download_failure(url: string, reason: string): string {
|
|
127
|
+
return `Could not fetch osv-scanner from ${url}: ${reason}. Run \`pnpm josh audit:provision --force\` to retry with a longer timeout; until then the pre-push audit will report the missing binary.`
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// The mismatch is reported with both digests because the two things it can mean — a re-cut release
|
|
131
|
+
// asset and a tampered download — are told apart by comparing the actual digest with the tag's own
|
|
132
|
+
// published sums, and a message that hid it would leave nothing to compare.
|
|
133
|
+
function format_checksum_mismatch(asset_name: string, expected: string, actual: string): string {
|
|
134
|
+
return `Checksum mismatch for ${asset_name}: expected ${expected}, got ${actual}. Nothing was installed.`
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function format_installed(target_path: string): string {
|
|
138
|
+
return `Installed osv-scanner v${SCANNER_VERSION} at ${target_path}.`
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function format_recent_failure(): string {
|
|
142
|
+
return `A previous attempt to provision osv-scanner failed less than ${String(HOURS_BEFORE_RETRY)} hours ago; not retrying at session start. Run \`pnpm josh audit:provision --force\` to try again now.`
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// The catch-all, kept separate from `format_download_failure`: writing the binary can fail on its own
|
|
146
|
+
// terms — a read-only mount, a full disk, a directory the running user may not create — and pointing
|
|
147
|
+
// the reader at the network for a disk problem sends them to the wrong place entirely.
|
|
148
|
+
function format_provision_error(reason: string): string {
|
|
149
|
+
return `Could not provision osv-scanner: ${reason}. The pre-push audit will report the missing binary.`
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// `osv-scanner --version` prints `osv-scanner version: X.Y.Z` on its first line; the rest of the
|
|
153
|
+
// block (`osv-scalibr version:`, `commit:`) is deliberately not matched so a scalibr version never
|
|
154
|
+
// stands in for the scanner's. `undefined` means the output did not carry a scanner version at all,
|
|
155
|
+
// which the caller treats as "cannot confirm the floor" rather than as a pass.
|
|
156
|
+
const SCANNER_VERSION_PATTERN = /osv-scanner version:\s*(\d+\.\d+\.\d+)/u
|
|
157
|
+
|
|
158
|
+
function parse_scanner_version(version_output: string): string | undefined {
|
|
159
|
+
return SCANNER_VERSION_PATTERN.exec(version_output)?.[1]
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function to_version_parts(version: string): Array<number> {
|
|
163
|
+
return version.split('.').map(Number)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Numeric per-segment compare rather than a string one, so `2.10.0` is not read as older than
|
|
167
|
+
// `2.6.0`. A missing segment counts as zero, which is what lets a two-part version compare against a
|
|
168
|
+
// three-part floor without a special case.
|
|
169
|
+
function compare_versions(left: string, right: string): number {
|
|
170
|
+
const left_parts = to_version_parts(left)
|
|
171
|
+
const right_parts = to_version_parts(right)
|
|
172
|
+
const length = Math.max(left_parts.length, right_parts.length)
|
|
173
|
+
|
|
174
|
+
for (let index = 0; index < length; index += 1) {
|
|
175
|
+
const difference = (left_parts[index] ?? 0) - (right_parts[index] ?? 0)
|
|
176
|
+
if (difference !== 0) return difference
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return 0
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function meets_version_floor(version: string): boolean {
|
|
183
|
+
return compare_versions(version, MINIMUM_SCANNER_VERSION) >= 0
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Printed when the only scanner available parses the lockfile short of the floor: its "no issues
|
|
187
|
+
// found" is not proof the tree is clean, only that a blinkered scanner read too little to object. The
|
|
188
|
+
// distinction the acceptance criteria ask for — a small package count told apart from a genuine pass.
|
|
189
|
+
function format_below_floor(version: string): string {
|
|
190
|
+
return `osv-scanner ${version} is below the required v${MINIMUM_SCANNER_VERSION}; older builds parse only part of pnpm-lock.yaml, so a clean result here is not proof the lockfile is clean. Run \`pnpm josh audit:provision --force\` to install v${SCANNER_VERSION}.`
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const security_audit_provision_logic = {
|
|
194
|
+
FORCED_DOWNLOAD_TIMEOUT_MS,
|
|
195
|
+
RETRY_INTERVAL_MS,
|
|
196
|
+
SESSION_DOWNLOAD_TIMEOUT_MS,
|
|
197
|
+
SCANNER_VERSION,
|
|
198
|
+
MINIMUM_SCANNER_VERSION,
|
|
199
|
+
build_asset_name,
|
|
200
|
+
build_download_timeout,
|
|
201
|
+
build_download_url,
|
|
202
|
+
build_staging_path,
|
|
203
|
+
format_already_present,
|
|
204
|
+
format_below_floor,
|
|
205
|
+
format_checksum_mismatch,
|
|
206
|
+
format_download_failure,
|
|
207
|
+
format_installed,
|
|
208
|
+
format_provision_error,
|
|
209
|
+
format_recent_failure,
|
|
210
|
+
format_unsupported_platform,
|
|
211
|
+
meets_version_floor,
|
|
212
|
+
parse_scanner_version,
|
|
213
|
+
resolve_asset,
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export { security_audit_provision_logic }
|
|
217
|
+
export type { ScannerAsset }
|