@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,477 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { repo_discovery } from '#scripts/discovery/repo-discovery'
|
|
4
|
+
import { git_epic_parse } from '#scripts/git/git-epic-parse'
|
|
5
|
+
import { git_gh_command } from '#scripts/git/git-gh-command'
|
|
6
|
+
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
7
|
+
import { josh_environment_file } from '#scripts/josh/josh-environment-file'
|
|
8
|
+
import { lane_capacity } from '#scripts/lane/lane-capacity'
|
|
9
|
+
import { issue_citation } from '#scripts/rules/issue-citation'
|
|
10
|
+
import { epic_classify } from './epic-classify'
|
|
11
|
+
import { epic_cross_repo } from './epic-cross-repo'
|
|
12
|
+
import { epic_fetch, type EpicSnapshot } from './epic-fetch'
|
|
13
|
+
import { epic_graph, type GraphAnomaly } from './epic-graph'
|
|
14
|
+
import { epic_issue, type EpicReference } from './epic-issue'
|
|
15
|
+
import { epic_lane_offer, type LaneOffer, type LaneRequest } from './epic-lane-offer'
|
|
16
|
+
import { epic_next_read, type EpicRead, type SnapshotReads } from './epic-next-read'
|
|
17
|
+
import { epic_next_views, type EpicView } from './epic-next-views'
|
|
18
|
+
import { epic_outside_blocker } from './epic-outside-blocker'
|
|
19
|
+
import { epic_report, type EpicNextResult, type EpicVerdict } from './epic-report'
|
|
20
|
+
|
|
21
|
+
// `josh epic:next <E…>` — which of the named epics' children can be started right now, bundled per
|
|
22
|
+
// repository, and what the rest are waiting on (joshuafolkken/kit#860).
|
|
23
|
+
//
|
|
24
|
+
// **Several epics answer as one** (joshuafolkken/kit#1493). Every leading argument is an epic
|
|
25
|
+
// reference, and their children merge into one candidate pool per repository — so a repository with
|
|
26
|
+
// six free lanes fills them from every named epic rather than from whichever one was typed first.
|
|
27
|
+
// The merge itself, and why the priority order is the order they were named, is
|
|
28
|
+
// `epic-next-views.ts`; the de-duplication of a child two epics both track is
|
|
29
|
+
// `epic_lane_offer.dedupe_pools`.
|
|
30
|
+
|
|
31
|
+
const SUCCESS_EXIT_CODE = 0
|
|
32
|
+
const FAILURE_EXIT_CODE = 1
|
|
33
|
+
const ARGV_OFFSET = 2
|
|
34
|
+
const REPO_FLAG = '--repo'
|
|
35
|
+
// Asking for every free lane is opt-in, so the answer stays one token for a caller that has not been
|
|
36
|
+
// changed. `--repo` alone still prints exactly one number — what joshuafolkken/kit#1491 changed for
|
|
37
|
+
// it is *when* that number appears, not how many arrive (joshuafolkken/kit#1491).
|
|
38
|
+
const LANES_FLAG = '--lanes'
|
|
39
|
+
const FLAG_PREFIX = '--'
|
|
40
|
+
const USAGE =
|
|
41
|
+
'Usage: josh epic:next <epic-number|owner/repo#number>... [--repo <owner/repo>] [--lanes]'
|
|
42
|
+
// A repository that could not be read is refused rather than stood in for. Since
|
|
43
|
+
// joshuafolkken/kit#1126 a blocker carries the repository it lives in, so a placeholder on the
|
|
44
|
+
// children keys them as `unknown/unknown#N` while their blockers keep their real names: every
|
|
45
|
+
// relation misses, `from_blockers([])` calls the child runnable, and an unattended run starts a
|
|
46
|
+
// dependent before its prerequisite. The old placeholder was harmless only while every blocker
|
|
47
|
+
// inherited the child's own repository — it matched itself.
|
|
48
|
+
const UNKNOWN_REPO =
|
|
49
|
+
'Could not read this repository from `git remote`, so the children cannot be keyed by repository — check `gh auth status` and that this is a checkout with an `origin` remote.'
|
|
50
|
+
const EXTERNAL_NOTICE = 'Note: this epic tracks children in other repositories.'
|
|
51
|
+
const { FOREIGN_EPIC } = epic_next_read
|
|
52
|
+
const NO_CHILDREN = 0
|
|
53
|
+
const ONE_EPIC = 1
|
|
54
|
+
const UNCHECKED_EXCLUSION =
|
|
55
|
+
'Note: the per-repository lane count is applied by `--repo`; a child listed here may still be held back there while every lane is in use.'
|
|
56
|
+
|
|
57
|
+
interface NextOptions {
|
|
58
|
+
// Every epic named, in the order they were named — which is the order their children then take
|
|
59
|
+
// free lanes in (joshuafolkken/kit#1493). Each reference carries the repository the *epic* lives
|
|
60
|
+
// in when it was qualified (`owner/repo#858`).
|
|
61
|
+
references?: ReadonlyArray<EpicReference>
|
|
62
|
+
// The repository to narrow the candidates to (`--repo`).
|
|
63
|
+
repo?: string
|
|
64
|
+
// Whether to fill every free lane (`--lanes`) rather than answering with a single child.
|
|
65
|
+
is_all_lanes?: boolean
|
|
66
|
+
usage?: string
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// A value that is itself a flag is no value at all. `--repo --lanes` used to narrow to a repository
|
|
70
|
+
// literally named `--lanes` and report `No runnable child in --lanes` with exit 0; refused here, it
|
|
71
|
+
// reaches the usage line instead — the caller meant a repository and named none.
|
|
72
|
+
function parse_repo(rest: ReadonlyArray<string>): string | undefined {
|
|
73
|
+
const flag_index = rest.indexOf(REPO_FLAG)
|
|
74
|
+
const value = flag_index === -1 ? undefined : rest[flag_index + 1]
|
|
75
|
+
|
|
76
|
+
return value?.startsWith(FLAG_PREFIX) === true ? undefined : value
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// The leading arguments are epic references and everything from the first flag on is options. Split
|
|
80
|
+
// on the flag rather than taking a fixed count, so `epic:next 858 909 --repo X` reads two epics and
|
|
81
|
+
// `epic:next 858 --repo X` still reads one (joshuafolkken/kit#1493).
|
|
82
|
+
function split_at_flag(argv: ReadonlyArray<string>): {
|
|
83
|
+
head: ReadonlyArray<string>
|
|
84
|
+
rest: ReadonlyArray<string>
|
|
85
|
+
} {
|
|
86
|
+
const flag_at = argv.findIndex((entry) => entry.startsWith(FLAG_PREFIX))
|
|
87
|
+
|
|
88
|
+
return flag_at === -1
|
|
89
|
+
? { head: argv, rest: [] }
|
|
90
|
+
: { head: argv.slice(0, flag_at), rest: argv.slice(flag_at) }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Every leading entry, or nothing. One entry that does not parse fails the whole read rather than
|
|
94
|
+
// being dropped: a mistyped second epic would otherwise run the first one alone and report nothing
|
|
95
|
+
// at all about the one that was missed — an unattended run silently doing half of what was asked.
|
|
96
|
+
function parse_references(head: ReadonlyArray<string>): ReadonlyArray<EpicReference> | undefined {
|
|
97
|
+
const references: Array<EpicReference> = []
|
|
98
|
+
|
|
99
|
+
for (const entry of head) {
|
|
100
|
+
const reference = epic_issue.parse_epic_reference(entry)
|
|
101
|
+
|
|
102
|
+
if (reference === undefined) return undefined
|
|
103
|
+
references.push(reference)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return references.length === 0 ? undefined : references
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// `--lanes` without `--repo` is refused rather than ignored: the lane count is a property of one
|
|
110
|
+
// repository, so the aggregate listing has nothing to apply it to, and a flag that silently does
|
|
111
|
+
// nothing is a caller believing it asked for something.
|
|
112
|
+
function parse_options(argv: ReadonlyArray<string>): NextOptions {
|
|
113
|
+
const { head, rest } = split_at_flag(argv)
|
|
114
|
+
const references = parse_references(head)
|
|
115
|
+
if (references === undefined) return { usage: USAGE }
|
|
116
|
+
const repo = parse_repo(rest)
|
|
117
|
+
const is_all_lanes = rest.includes(LANES_FLAG)
|
|
118
|
+
|
|
119
|
+
if (repo === undefined) {
|
|
120
|
+
return is_all_lanes || rest.includes(REPO_FLAG) ? { usage: USAGE } : { references }
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return { references, repo, is_all_lanes }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// The answer for one epic, from an already-fetched snapshot. Split from the fetch so the whole
|
|
127
|
+
// decision is testable without GitHub.
|
|
128
|
+
// A child that could not be read stops the run. Continuing would answer with a graph that is
|
|
129
|
+
// missing a node: an epic whose children all failed to read reads as complete, and one missing child
|
|
130
|
+
// leaves whatever it blocks looking unblocked.
|
|
131
|
+
//
|
|
132
|
+
// Each one is named with the repository it lives in, through the same writer the audit uses: an epic
|
|
133
|
+
// tracking `- [ ] sveltejs/kit#7` reported `Could not read #7`, and a reader sent to this
|
|
134
|
+
// repository's issue 7 finds a different issue or none (joshuafolkken/kit#1016).
|
|
135
|
+
// **The epic's own body failing to read is its own anomaly, ahead of the children's**
|
|
136
|
+
// (joshuafolkken/kit#1690). Without it the failure is silent: a body that never arrived parses to
|
|
137
|
+
// zero children, the epic is dropped from the views as an unpopulated one, no anomaly is raised, and
|
|
138
|
+
// the verdict falls through to `complete` — which `backlog:next` prints as `none`, so the run reports
|
|
139
|
+
// the backlog exhausted over one request that never left the machine. It is checked first because a
|
|
140
|
+
// body nobody read says nothing about the children either.
|
|
141
|
+
function body_anomaly(snapshot: EpicSnapshot): GraphAnomaly | undefined {
|
|
142
|
+
if (snapshot.body_failure === undefined) return undefined
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
kind: 'unreadable_epic_body',
|
|
146
|
+
message: `Could not read the body of the epic in ${snapshot.repo}. Its task list is what names the children, so nothing is offered — check \`gh auth status\` and that the epic exists.`,
|
|
147
|
+
is_unreachable: snapshot.is_unreachable,
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function unreadable_anomaly(snapshot: EpicSnapshot): GraphAnomaly | undefined {
|
|
152
|
+
const missing = epic_fetch.missing_children(snapshot)
|
|
153
|
+
if (missing.length === 0) return undefined
|
|
154
|
+
const list = epic_graph.format_references(missing, snapshot.current_repo)
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
kind: 'unreadable_children',
|
|
158
|
+
message: `Could not read ${list}. The dependency graph would be missing them, so nothing is offered — check \`gh auth status\` and that the issues exist.`,
|
|
159
|
+
is_unreachable: snapshot.is_unreachable,
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Whether the body states an order at all. Read through the same parser the links come from, so a
|
|
164
|
+
// body whose arrows are all prose cannot count as a declaration with zero links — which would report
|
|
165
|
+
// every correct relation as undeclared.
|
|
166
|
+
//
|
|
167
|
+
// Deliberately a disjunction where `epic:check` takes exactly one of the two: a body declaring both
|
|
168
|
+
// a chain and the `None — ...` literal is a contradiction, and reporting it is the check's job
|
|
169
|
+
// (joshuafolkken/kit#1155). Refusing to hand out work here as well would stop an unattended run on a
|
|
170
|
+
// body whose declared chain and recorded relations agree — a worse outcome than following the chain
|
|
171
|
+
// the run's own `epic:check` already flagged.
|
|
172
|
+
function is_order_declared(body: string | undefined, links: ReadonlyArray<unknown>): boolean {
|
|
173
|
+
return links.length > 0 || git_epic_parse.has_unordered_declaration(body)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function decide(
|
|
177
|
+
snapshot: EpicSnapshot,
|
|
178
|
+
paths: ReadonlyMap<string, string> = new Map(),
|
|
179
|
+
running?: ReadonlySet<string>,
|
|
180
|
+
): EpicNextResult {
|
|
181
|
+
const links = git_epic_parse.parse_dependency_links(snapshot.body)
|
|
182
|
+
const unreadable = body_anomaly(snapshot) ?? unreadable_anomaly(snapshot)
|
|
183
|
+
const anomalies =
|
|
184
|
+
unreadable === undefined
|
|
185
|
+
? epic_graph.find_anomalies(
|
|
186
|
+
snapshot.children,
|
|
187
|
+
links,
|
|
188
|
+
is_order_declared(snapshot.body, links),
|
|
189
|
+
snapshot.repo,
|
|
190
|
+
)
|
|
191
|
+
: [unreadable]
|
|
192
|
+
// The cross-repository resolver, not the default one: a blocker in another repository is not
|
|
193
|
+
// finished when it closes, only when its release is published (joshuafolkken/kit#864).
|
|
194
|
+
const classification = epic_classify.classify_children(
|
|
195
|
+
snapshot.children,
|
|
196
|
+
epic_cross_repo.resolve_cross_repo,
|
|
197
|
+
running,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
return epic_report.build_result(classification, anomalies, paths)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// A refusal: the reason on stderr, where every other explanation this command prints goes.
|
|
204
|
+
function refuse(reason: string): number {
|
|
205
|
+
console.error(reason)
|
|
206
|
+
|
|
207
|
+
return FAILURE_EXIT_CODE
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// The verdict as it applies to *this* repository. `run` never reaches a caller here: it means some
|
|
211
|
+
// other repository has work, which for this session is something to wait on rather than a state its
|
|
212
|
+
// loop has a branch for. The whole-run timeout is what bounds that wait.
|
|
213
|
+
function repo_verdict(verdict: EpicVerdict): EpicVerdict {
|
|
214
|
+
return verdict === 'run' ? 'wait' : verdict
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// The confirmed candidates' numbers, one per line, or the verdict that stands in their place when
|
|
218
|
+
// there was no free lane or the relations listing withheld every one of them
|
|
219
|
+
// (joshuafolkken/kit#1121). Standard output carries numbers or a verdict and nothing else, so
|
|
220
|
+
// `child=$(josh epic:next … --repo …)` is unchanged for the caller that asked for one child — which
|
|
221
|
+
// is every caller that did not pass `--lanes`.
|
|
222
|
+
function report_offer(offer: LaneOffer): number {
|
|
223
|
+
if (offer.notice !== '') console.error(offer.notice)
|
|
224
|
+
|
|
225
|
+
if (offer.children.length === NO_CHILDREN) {
|
|
226
|
+
console.info(repo_verdict(offer.verdict))
|
|
227
|
+
|
|
228
|
+
return SUCCESS_EXIT_CODE
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
for (const child of offer.children) console.info(String(child.number))
|
|
232
|
+
|
|
233
|
+
return SUCCESS_EXIT_CODE
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// The candidates, once the repository has been asked **how many lanes it already has running** —
|
|
237
|
+
// whichever epic those belong to (joshuafolkken/kit#925, counted rather than excluded since
|
|
238
|
+
// joshuafolkken/kit#1491). The invariant is per *repository* rather than per epic, and it is a
|
|
239
|
+
// ceiling on how many children run there at once rather than a lock on the whole checkout.
|
|
240
|
+
//
|
|
241
|
+
// Asked only when there *is* a candidate: consulted on `stop` or `complete` too, an unrelated
|
|
242
|
+
// `in-progress` issue would turn a finished epic into a permanent `wait`, and neither of those
|
|
243
|
+
// verdicts is about to start anything. It also never reaches a third party's tracker, since a child
|
|
244
|
+
// in a repository with another owner is refused before it is read (joshuafolkken/kit#869).
|
|
245
|
+
//
|
|
246
|
+
// **A read that failed answers `wait` too** — never a child, and not an error either
|
|
247
|
+
// (`epic-busy.ts` records why both wrong answers are wrong). **So does a listing that was cut
|
|
248
|
+
// short**: since joshuafolkken/kit#1067 the page ceiling bounds this listing as well, and a short
|
|
249
|
+
// listing with no visible holder is not "nothing is running".
|
|
250
|
+
//
|
|
251
|
+
// One pool per named epic, in the order they were named. Nothing below this line knows what an epic
|
|
252
|
+
// is (`epic-lane-offer.ts` records why), so the whole cost of running several of them is here: build
|
|
253
|
+
// the pools, and let the scheduler spend the free lanes across them (joshuafolkken/kit#1493).
|
|
254
|
+
async function offer_children(
|
|
255
|
+
views: ReadonlyArray<EpicView>,
|
|
256
|
+
request: LaneRequest,
|
|
257
|
+
): Promise<number> {
|
|
258
|
+
const pools = epic_next_views.pools_of(views, request.repo)
|
|
259
|
+
|
|
260
|
+
return report_offer(await epic_lane_offer.offer_for_repo(pools, request))
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Print the answer for one repository, as one machine-readable token: the issue number when there
|
|
264
|
+
// is a child to run, otherwise the verdict — `wait`, `stop` or `complete`.
|
|
265
|
+
//
|
|
266
|
+
// The verdict is on stdout rather than only in prose because a loop has to tell "poll again" from
|
|
267
|
+
// "stop and report" from "finished"; collapsing all three into one line and exit 0 leaves the caller
|
|
268
|
+
// unable to make the distinction the whole classification exists for. Explanations go to stderr, so
|
|
269
|
+
// `child=$(josh epic:next 858 --repo …)` still captures a single token.
|
|
270
|
+
//
|
|
271
|
+
// An unusable graph is checked before a candidate is picked: printing a runnable child while the
|
|
272
|
+
// graph is broken would hand a caller work the anomaly says must not start. **One broken graph
|
|
273
|
+
// refuses the whole answer**, whichever epic it belongs to — handing out another epic's child in the
|
|
274
|
+
// same breath would let an unattended run walk past a graph a person has to look at.
|
|
275
|
+
async function report_single(
|
|
276
|
+
views: ReadonlyArray<EpicView>,
|
|
277
|
+
request: LaneRequest,
|
|
278
|
+
): Promise<number> {
|
|
279
|
+
const broken = epic_next_views.error_view(views)
|
|
280
|
+
|
|
281
|
+
if (broken !== undefined) {
|
|
282
|
+
return refuse(epic_next_views.format_view(broken, views.length > ONE_EPIC, request.repo))
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const has_candidate = views.some(
|
|
286
|
+
(view) => epic_report.candidates_for_repo(view.result, request.repo).length > NO_CHILDREN,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
if (!has_candidate) {
|
|
290
|
+
console.error(`No runnable child in ${request.repo}.`)
|
|
291
|
+
console.info(repo_verdict(epic_next_views.combined_verdict(views)))
|
|
292
|
+
|
|
293
|
+
return SUCCESS_EXIT_CODE
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return await offer_children(views, request)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// The aggregate listing does not consult the repository-level exclusion — `--repo` is what asks a
|
|
300
|
+
// repository whether it is busy, and doing it here would be one listing per repository for a report
|
|
301
|
+
// nobody branches on. Said out loud rather than left implicit: this output names runnable children,
|
|
302
|
+
// and the `--repo` form may answer `wait` for the very same child (joshuafolkken/kit#925).
|
|
303
|
+
function note_unchecked_exclusion(views: ReadonlyArray<EpicView>): void {
|
|
304
|
+
if (epic_next_views.combined_verdict(views) === 'run') console.error(UNCHECKED_EXCLUSION)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// One block per epic, and the notice printed once for all of them rather than once each: it says
|
|
308
|
+
// what this listing does not check, which is the same sentence however many graphs it covers. The
|
|
309
|
+
// listing names each epic and its children as `#N`, linkified against the current repository so the
|
|
310
|
+
// output a run reads carries clickable references rather than bare ones (joshuafolkken/kit#2329).
|
|
311
|
+
function report_aggregate(views: ReadonlyArray<EpicView>, current_repo: string): number {
|
|
312
|
+
note_unchecked_exclusion(views)
|
|
313
|
+
|
|
314
|
+
const text = epic_next_views.aggregate_text(views, current_repo)
|
|
315
|
+
|
|
316
|
+
if (epic_next_views.error_view(views) !== undefined) {
|
|
317
|
+
console.error(text)
|
|
318
|
+
|
|
319
|
+
return FAILURE_EXIT_CODE
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
console.info(issue_citation.linkify(text, current_repo))
|
|
323
|
+
|
|
324
|
+
return SUCCESS_EXIT_CODE
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Named per epic where there is more than one to tell apart: the notice's own wording says "this
|
|
328
|
+
// epic", which is exact for a single one and says nothing at all about which of several.
|
|
329
|
+
function external_notice(view: EpicView, is_many: boolean): string {
|
|
330
|
+
return is_many
|
|
331
|
+
? `${epic_next_views.format_reference(view.reference)} ${EXTERNAL_NOTICE}`
|
|
332
|
+
: EXTERNAL_NOTICE
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function note_external(views: ReadonlyArray<EpicView>): void {
|
|
336
|
+
const is_many = views.length > ONE_EPIC
|
|
337
|
+
|
|
338
|
+
for (const view of views) {
|
|
339
|
+
if (view.snapshot.has_external_children) console.error(external_notice(view, is_many))
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
async function report(
|
|
344
|
+
views: ReadonlyArray<EpicView>,
|
|
345
|
+
request: LaneRequest | undefined,
|
|
346
|
+
current_repo: string,
|
|
347
|
+
): Promise<number> {
|
|
348
|
+
note_external(views)
|
|
349
|
+
if (request !== undefined) return await report_single(views, request)
|
|
350
|
+
|
|
351
|
+
return report_aggregate(views, current_repo)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// The checkout each repository's children would be run in comes from joshuafolkken/kit#869's map. A
|
|
355
|
+
// repository absent from it is reported without a path rather than cloned.
|
|
356
|
+
//
|
|
357
|
+
// **Every epic is classified against the same reset**, not one reset each: `reset_reported` and
|
|
358
|
+
// `reset_publish_cache` are per *invocation*, so clearing them between epics would let the same
|
|
359
|
+
// blocker be warned about once per epic that tracks it.
|
|
360
|
+
async function report_epics(
|
|
361
|
+
views: ReadonlyArray<EpicView>,
|
|
362
|
+
options: NextOptions,
|
|
363
|
+
current_repo: string,
|
|
364
|
+
): Promise<number> {
|
|
365
|
+
if (options.repo === undefined) return await report(views, undefined, current_repo)
|
|
366
|
+
|
|
367
|
+
const choice = lane_capacity.lane_limit()
|
|
368
|
+
if (choice.kind === 'problem') return refuse(choice.problem)
|
|
369
|
+
|
|
370
|
+
return await report(
|
|
371
|
+
views,
|
|
372
|
+
{ repo: options.repo, limit: choice.limit, is_all_lanes: options.is_all_lanes ?? false },
|
|
373
|
+
current_repo,
|
|
374
|
+
)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// One view per named epic, classified against one shared registry read. `running` is every named
|
|
378
|
+
// epic's children unless a caller that runs more — `backlog:next` — passes its own set, so a blocker
|
|
379
|
+
// in another named epic waits rather than stops (joshuafolkken/kit#1943).
|
|
380
|
+
function views_of(
|
|
381
|
+
reads: ReadonlyArray<EpicRead>,
|
|
382
|
+
running = epic_outside_blocker.running_keys(reads.flatMap((read) => read.snapshot.children)),
|
|
383
|
+
): ReadonlyArray<EpicView> {
|
|
384
|
+
const paths = repo_discovery.discover_repositories(PROJECT_ROOT)
|
|
385
|
+
|
|
386
|
+
// One registry answer per repository per invocation. A polling `epicrun` calls this command
|
|
387
|
+
// again each round, and a release that appeared in between has to be seen.
|
|
388
|
+
epic_cross_repo.reset_publish_cache()
|
|
389
|
+
epic_classify.reset_reported()
|
|
390
|
+
|
|
391
|
+
return epic_next_views.settle_views(running, (settled) =>
|
|
392
|
+
reads.map((read) => ({
|
|
393
|
+
...read,
|
|
394
|
+
running: settled,
|
|
395
|
+
result: decide(read.snapshot, paths, settled),
|
|
396
|
+
})),
|
|
397
|
+
)
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// What the read walk produced, or nothing when there is still work to report. A skipped epic is
|
|
401
|
+
// named on standard error only where some other epic survived: with none left, the notices *are* the
|
|
402
|
+
// refusal, which is exactly the line a single childless epic printed before several were allowed.
|
|
403
|
+
function refuse_reads(result: SnapshotReads): number | undefined {
|
|
404
|
+
if (result.refusal !== undefined) return refuse(result.refusal)
|
|
405
|
+
if (result.reads.length === NO_CHILDREN) return refuse(result.notices.join('\n'))
|
|
406
|
+
|
|
407
|
+
for (const notice of result.notices) console.error(notice)
|
|
408
|
+
|
|
409
|
+
return undefined
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
async function run_epics(options: NextOptions): Promise<number> {
|
|
413
|
+
const references = options.references ?? []
|
|
414
|
+
if (references.length === NO_CHILDREN) return refuse(USAGE)
|
|
415
|
+
const current_repo = await git_gh_command.repo_get_name_with_owner()
|
|
416
|
+
if (current_repo === undefined) return refuse(UNKNOWN_REPO)
|
|
417
|
+
const result = await epic_next_read.read_snapshots(references, current_repo)
|
|
418
|
+
const stopped = refuse_reads(result)
|
|
419
|
+
|
|
420
|
+
return stopped ?? (await report_epics(views_of(result.reads), options, current_repo))
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
424
|
+
const options = parse_options(argv)
|
|
425
|
+
|
|
426
|
+
if (options.references === undefined) {
|
|
427
|
+
console.error(options.usage ?? USAGE)
|
|
428
|
+
|
|
429
|
+
return FAILURE_EXIT_CODE
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return await run_epics(options)
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// `process.exitCode` rather than `process.exit()`, for the reason `scripts/cost-runtime/cost-cli.ts` records:
|
|
436
|
+
// the answer goes to standard output and a write to a pipe is asynchronous on macOS, so exiting can
|
|
437
|
+
// tear the process down before it drains. This command's contract is `answer=$(pnpm josh epic:next
|
|
438
|
+
// <E>)`, which is exactly that pipe (joshuafolkken/kit#996).
|
|
439
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
440
|
+
process.exitCode = await run(argv)
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const epic_next = {
|
|
444
|
+
USAGE,
|
|
445
|
+
EXTERNAL_NOTICE,
|
|
446
|
+
FOREIGN_EPIC,
|
|
447
|
+
body_anomaly,
|
|
448
|
+
unreadable_anomaly,
|
|
449
|
+
is_order_declared,
|
|
450
|
+
repo_verdict,
|
|
451
|
+
offer_children,
|
|
452
|
+
report_offer,
|
|
453
|
+
UNCHECKED_EXCLUSION,
|
|
454
|
+
split_at_flag,
|
|
455
|
+
parse_references,
|
|
456
|
+
parse_options,
|
|
457
|
+
note_external,
|
|
458
|
+
refuse_reads,
|
|
459
|
+
views_of,
|
|
460
|
+
run_epics,
|
|
461
|
+
decide,
|
|
462
|
+
report,
|
|
463
|
+
run,
|
|
464
|
+
main,
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// `.env` is read here rather than through the dispatcher's `tsx_arguments`: declaring any would
|
|
468
|
+
// disqualify this command from in-process dispatch, and an unattended `epicrun` asks it every sixty
|
|
469
|
+
// seconds for the whole life of a run (`josh-environment-file.ts` records the measurement). Inside the guard
|
|
470
|
+
// rather than in `main`, so a developer's own `.env` cannot decide what the unit tests see.
|
|
471
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
472
|
+
josh_environment_file.load_environment_file()
|
|
473
|
+
await main(process.argv.slice(ARGV_OFFSET))
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
export type { NextOptions }
|
|
477
|
+
export { epic_next }
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { epic_graph, type EpicChild, type IssueReference } from './epic-graph'
|
|
2
|
+
|
|
3
|
+
// A blocker no graph in this invocation tracks, weighed rather than ignored (joshuafolkken/kit#1943).
|
|
4
|
+
//
|
|
5
|
+
// Until this, a relation pointing outside the epic was announced and dropped, so a child waiting on
|
|
6
|
+
// another epic's open issue was offered as runnable — `backlogrun` would start joshuafolkken/kit#1936's
|
|
7
|
+
// children before joshuafolkken/kit#1921 had restored CI, whatever `blocked-by` said. What decides the
|
|
8
|
+
// answer is whether *this run* can finish the blocker: an open blocker the run also runs is `time`
|
|
9
|
+
// (waiting resolves it), one it does not is `human` (only a person can), and a blocker whose state was
|
|
10
|
+
// never read is `time` rather than runnable, because an unknown is never read as finished.
|
|
11
|
+
|
|
12
|
+
// What one dependency means for the child that carries it. Declared here rather than in
|
|
13
|
+
// `epic-classify.ts` so the two modules share it without importing each other; the classifier
|
|
14
|
+
// re-exports both names, so every existing importer is unchanged.
|
|
15
|
+
//
|
|
16
|
+
// `inherit` is the ordinary answer: the blocker is not finished, so this child's fate is the
|
|
17
|
+
// blocker's fate. `time` and `human` are for a dependency that is unresolved for a reason the
|
|
18
|
+
// blocker's own state does not show — joshuafolkken/kit#864's case, where a blocker is closed but
|
|
19
|
+
// its package has not been published yet, is `time`.
|
|
20
|
+
type DependencyVerdict = 'resolved' | 'time' | 'human' | 'inherit'
|
|
21
|
+
|
|
22
|
+
// The extension point. Replaced wholesale by joshuafolkken/kit#864 to add the publish condition;
|
|
23
|
+
// the default knows only that a closed blocker is a finished one.
|
|
24
|
+
type ResolveDependency = (blocker: EpicChild, blocked: EpicChild) => DependencyVerdict
|
|
25
|
+
|
|
26
|
+
type OutsideCategory = 'time' | 'human'
|
|
27
|
+
|
|
28
|
+
// A line to announce once per invocation, keyed so the classifier's de-duplication can drop repeats.
|
|
29
|
+
interface OutsideNotice {
|
|
30
|
+
key: string
|
|
31
|
+
message: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface OutsideAnswer {
|
|
35
|
+
category: OutsideCategory | undefined
|
|
36
|
+
notice?: OutsideNotice
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const CLOSED = 'CLOSED'
|
|
40
|
+
|
|
41
|
+
function name_of(child: EpicChild): string {
|
|
42
|
+
return `#${String(child.number)}`
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// A closed reference as the child record a resolver takes, so a closed blocker in another repository
|
|
46
|
+
// still waits for its release exactly as a tracked one does (joshuafolkken/kit#864).
|
|
47
|
+
function as_closed_child(reference: IssueReference): EpicChild {
|
|
48
|
+
return {
|
|
49
|
+
number: reference.number,
|
|
50
|
+
repo: reference.repo,
|
|
51
|
+
state: CLOSED,
|
|
52
|
+
labels: [],
|
|
53
|
+
blocked_by: [],
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function unread_answer(child: EpicChild, reference: IssueReference): OutsideAnswer {
|
|
58
|
+
const blocker = epic_graph.key_of(reference)
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
category: 'time',
|
|
62
|
+
notice: {
|
|
63
|
+
key: `unread:${epic_graph.key_of(child)}:${blocker}`,
|
|
64
|
+
message: `⚠ ${name_of(child)} is blocked by ${blocker}, whose state could not be read — it waits rather than runs`,
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function open_answer(
|
|
70
|
+
child: EpicChild,
|
|
71
|
+
reference: IssueReference,
|
|
72
|
+
running: ReadonlySet<string>,
|
|
73
|
+
): OutsideAnswer {
|
|
74
|
+
if (running.has(epic_graph.blocker_key(reference))) return { category: 'time' }
|
|
75
|
+
|
|
76
|
+
const blocker = epic_graph.key_of(reference)
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
category: 'human',
|
|
80
|
+
notice: {
|
|
81
|
+
key: `outside:${epic_graph.key_of(child)}:${blocker}`,
|
|
82
|
+
message: `⚠ ${name_of(child)} waits on ${blocker}, which this run will not finish — withheld for a person`,
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function closed_category(verdict: DependencyVerdict): OutsideCategory | undefined {
|
|
88
|
+
if (verdict === 'resolved') return undefined
|
|
89
|
+
|
|
90
|
+
return verdict === 'human' ? 'human' : 'time'
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function outside_category(
|
|
94
|
+
child: EpicChild,
|
|
95
|
+
reference: IssueReference,
|
|
96
|
+
resolve: ResolveDependency,
|
|
97
|
+
running: ReadonlySet<string>,
|
|
98
|
+
): OutsideAnswer {
|
|
99
|
+
if (reference.state === undefined) return unread_answer(child, reference)
|
|
100
|
+
if (reference.state !== CLOSED) return open_answer(child, reference, running)
|
|
101
|
+
|
|
102
|
+
return { category: closed_category(resolve(as_closed_child(reference), child)) }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// The keys of every issue this invocation may run, in the form a blocker reference is looked up by.
|
|
106
|
+
function running_keys(issues: ReadonlyArray<IssueReference>): ReadonlySet<string> {
|
|
107
|
+
return new Set(issues.map((issue) => epic_graph.key_of(issue)))
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const epic_outside_blocker = { outside_category, running_keys }
|
|
111
|
+
|
|
112
|
+
export type { DependencyVerdict, OutsideAnswer, OutsideNotice, ResolveDependency }
|
|
113
|
+
export { epic_outside_blocker }
|