@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,322 @@
|
|
|
1
|
+
import { auto_ok_cli } from '#scripts/auto-ok/auto-ok-cli'
|
|
2
|
+
import type { Classification } from '#scripts/epic/epic-classify'
|
|
3
|
+
import { epic_graph, type EpicChild, type GraphAnomaly } from '#scripts/epic/epic-graph'
|
|
4
|
+
import { epic_index } from '#scripts/epic/epic-index'
|
|
5
|
+
import { epic_issue } from '#scripts/epic/epic-issue'
|
|
6
|
+
import type { EpicView } from '#scripts/epic/epic-next-views'
|
|
7
|
+
import { epic_outside_blocker } from '#scripts/epic/epic-outside-blocker'
|
|
8
|
+
import { git_next_issues } from '#scripts/git/git-next-issues'
|
|
9
|
+
import {
|
|
10
|
+
ALREADY_DONE_LABEL,
|
|
11
|
+
EPIC_LABEL,
|
|
12
|
+
has_any_label,
|
|
13
|
+
NEEDS_DECISION_LABEL,
|
|
14
|
+
} from '#scripts/git/issue-labels'
|
|
15
|
+
import type { OpenIssueData } from '#scripts/git/schemas'
|
|
16
|
+
|
|
17
|
+
// The candidate pool `josh backlog:next` answers from (joshuafolkken/kit#1630).
|
|
18
|
+
//
|
|
19
|
+
// Two sources feed one pool: the opted-in issues no epic tracks, and the children of the epics whose
|
|
20
|
+
// **root** carries `auto-ok`. Splitting them apart lives here so the command itself stays a list of
|
|
21
|
+
// steps, and so the two halves arrive as the one shape the verdict is decided from —
|
|
22
|
+
// `epic-classify.ts`'s `Classification`, which `epic-report.ts` then turns into the answer. Nothing
|
|
23
|
+
// here re-implements the dependency graph or the wave: the epic half arrives already classified by
|
|
24
|
+
// `epic:next`'s own pipeline, and this module only merges it with the standalone half.
|
|
25
|
+
|
|
26
|
+
const EPIC_LABELS: ReadonlySet<string> = new Set([EPIC_LABEL])
|
|
27
|
+
// The labels that put a withheld row in the "needs a person" bucket rather than the "waiting on
|
|
28
|
+
// time" one. `already-done` belongs with `needs-decision` because no amount of waiting moves it: the
|
|
29
|
+
// work is merged and the close is Tier C, so a person is the only thing that resolves it
|
|
30
|
+
// (joshuafolkken/kit#1679). Read as `time`, it would be reported as something that resolves itself
|
|
31
|
+
// and nobody would ever be told to close it.
|
|
32
|
+
const DECISION_LABELS: ReadonlySet<string> = new Set([NEEDS_DECISION_LABEL, ALREADY_DONE_LABEL])
|
|
33
|
+
|
|
34
|
+
// What decides whether a standalone row is offered: the children an opted-in epic is going to offer
|
|
35
|
+
// instead, the ones the caller has named as done, and the repository the rows belong to.
|
|
36
|
+
//
|
|
37
|
+
// `tracked` is the narrowed set `epic_index.withheld_children` builds, not every child an epic
|
|
38
|
+
// tracks (joshuafolkken/kit#1668) — the narrowing itself is defined there, once, for this half and
|
|
39
|
+
// `auto-ok:next` alike.
|
|
40
|
+
interface StandaloneContext {
|
|
41
|
+
tracked: ReadonlyMap<number, number>
|
|
42
|
+
exclude: ReadonlyArray<number>
|
|
43
|
+
repo: string
|
|
44
|
+
// Every issue this backlog may run (joshuafolkken/kit#1943). A row whose open blocker is outside it
|
|
45
|
+
// waits on a person rather than on time, exactly as an epic child's does.
|
|
46
|
+
running: ReadonlySet<string>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function is_epic_row(issue: OpenIssueData): boolean {
|
|
50
|
+
return has_any_label(issue.labels, EPIC_LABELS)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Whether a row is waiting on an open issue this backlog will never run. Only a blocker whose state
|
|
54
|
+
// was read counts: one with no state stays `time`, the fail-safe `auto_ok_cli.is_runnable` already
|
|
55
|
+
// applies to it.
|
|
56
|
+
function waits_outside(issue: OpenIssueData, running: ReadonlySet<string>, repo: string): boolean {
|
|
57
|
+
return epic_issue
|
|
58
|
+
.blocker_references_of(issue, repo)
|
|
59
|
+
.some((blocker) => blocker.state === 'OPEN' && !running.has(epic_graph.blocker_key(blocker)))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function needs_person(issue: OpenIssueData, context: StandaloneContext): boolean {
|
|
63
|
+
return (
|
|
64
|
+
has_any_label(issue.labels, DECISION_LABELS) ||
|
|
65
|
+
waits_outside(issue, context.running, context.repo)
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// The running set with every standalone row a person has to resolve taken out, repeated until a pass
|
|
70
|
+
// removes nothing — a row waiting on such a row waits on that person too, however long the chain.
|
|
71
|
+
function settle_standalone(
|
|
72
|
+
running: ReadonlySet<string>,
|
|
73
|
+
issues: ReadonlyArray<OpenIssueData>,
|
|
74
|
+
repo: string,
|
|
75
|
+
): ReadonlySet<string> {
|
|
76
|
+
const settled = new Set(running)
|
|
77
|
+
|
|
78
|
+
// An epic row is never in the set, so deleting its key changes nothing and it needs no filter.
|
|
79
|
+
for (const issue of issues) {
|
|
80
|
+
const is_stuck =
|
|
81
|
+
has_any_label(issue.labels, DECISION_LABELS) || waits_outside(issue, running, repo)
|
|
82
|
+
|
|
83
|
+
if (is_stuck) settled.delete(epic_graph.key_of({ repo, number: issue.number }))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return settled.size === running.size ? running : settle_standalone(settled, issues, repo)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// An opted-in row as the graph's node type. Both halves of the pool are then the same shape, so one
|
|
90
|
+
// classification covers all of them and the verdict is decided once rather than per source.
|
|
91
|
+
//
|
|
92
|
+
// `repo` stamps the row itself, never its blockers: issue numbers are unique per repository, so a
|
|
93
|
+
// blocker read bare resolves against the *reading* repository and names a different issue there
|
|
94
|
+
// (joshuafolkken/kit#1654). `epic_issue.blocker_references_of` is the epic side's own resolution —
|
|
95
|
+
// `repository_url` when the node names one, this repository only as the fallback an unqualified
|
|
96
|
+
// relation has always meant — and it is reused rather than repeated.
|
|
97
|
+
function to_child(issue: OpenIssueData, repo: string): EpicChild {
|
|
98
|
+
return {
|
|
99
|
+
number: issue.number,
|
|
100
|
+
repo,
|
|
101
|
+
state: 'OPEN',
|
|
102
|
+
labels: (issue.labels ?? []).map((label) => label.name),
|
|
103
|
+
blocked_by: epic_issue.blocker_references_of(issue, repo),
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function to_children(issues: ReadonlyArray<OpenIssueData>, repo: string): Array<EpicChild> {
|
|
108
|
+
return issues.map((issue) => to_child(issue, repo))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// The epics whose `auto-ok` stands for their children — the opted-in roots and, transitively, every
|
|
112
|
+
// nested epic reached through their task lists (joshuafolkken/kit#2244, extending joshuafolkken/kit#1668).
|
|
113
|
+
//
|
|
114
|
+
// The roots come out of the opted-in listing itself: an epic that carries `auto-ok` is a row in that
|
|
115
|
+
// listing which also carries `epic`, so no second listing reads an epic's labels. From each root the
|
|
116
|
+
// closure follows the tracking index down into a nested epic and its own nested epics, so a person's
|
|
117
|
+
// one label on the root approves the whole subtree — exactly as typing `epicrun #<E>` approves every
|
|
118
|
+
// merge inside `#<E>`, however deep.
|
|
119
|
+
function opted_in_epics(
|
|
120
|
+
issues: ReadonlyArray<OpenIssueData>,
|
|
121
|
+
tracking: ReadonlyMap<number, ReadonlyArray<number>>,
|
|
122
|
+
): ReadonlyArray<number> {
|
|
123
|
+
return [...epic_index.reachable_epic_numbers(tracking, issues)]
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// The rows that stand for themselves. An epic root is a container rather than work, so it is never a
|
|
127
|
+
// standalone candidate however it is labelled — `prioritize` drops it again below, and this keeps it
|
|
128
|
+
// out of the count as well.
|
|
129
|
+
function standalone_rows(issues: ReadonlyArray<OpenIssueData>): ReadonlyArray<OpenIssueData> {
|
|
130
|
+
return issues.filter((issue) => !is_epic_row(issue))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// A row an **opted-in** epic tracks belongs to that epic's order and never to the standalone half —
|
|
134
|
+
// the rule joshuafolkken/kit#1633 established, narrowed by joshuafolkken/kit#1668 to the epics that
|
|
135
|
+
// are actually going to offer their children and applied here for the same reason. Which rows those
|
|
136
|
+
// are is `epic_index.withheld_children`'s answer, not a second test made here. A row the caller
|
|
137
|
+
// excluded is out of the pool entirely rather than merely unoffered: it has just merged.
|
|
138
|
+
function is_considered(issue: OpenIssueData, context: StandaloneContext): boolean {
|
|
139
|
+
return !context.tracked.has(issue.number) && !context.exclude.includes(issue.number)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// The standalone half, in the buckets the verdict is read from.
|
|
143
|
+
//
|
|
144
|
+
// The order is `git_next_issues.prioritize`'s and not a second one — the same ranking the
|
|
145
|
+
// `🗒 Next issues` display and `auto-ok:next` already answer with, cap included, so the three cannot
|
|
146
|
+
// disagree about what comes next. Anything it withholds is still open work: `needs-decision` is
|
|
147
|
+
// waiting on a person, and everything else — a standing blocker, a run already in progress, a row
|
|
148
|
+
// past the cap — resolves on its own and is waiting on time. **The cap is one of those**: a sixth
|
|
149
|
+
// runnable standalone issue is reported as waiting rather than offered, and the next ask offers it
|
|
150
|
+
// once one of the five above it merges, so the backlog drains without it ever being lost. That is
|
|
151
|
+
// the cost of having one ranking rather than two, and `docs/josh-commands.md` states it.
|
|
152
|
+
function classify_standalone(
|
|
153
|
+
issues: ReadonlyArray<OpenIssueData>,
|
|
154
|
+
context: StandaloneContext,
|
|
155
|
+
): Classification {
|
|
156
|
+
const considered = issues.filter((issue) => is_considered(issue, context))
|
|
157
|
+
const runnable = git_next_issues.prioritize(
|
|
158
|
+
considered.filter((issue) => auto_ok_cli.is_runnable(issue, context.tracked, context.exclude)),
|
|
159
|
+
)
|
|
160
|
+
const offered = new Set(runnable.map((issue) => issue.number))
|
|
161
|
+
const withheld = considered.filter((issue) => !offered.has(issue.number))
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
runnable: to_children(runnable, context.repo),
|
|
165
|
+
time: to_children(
|
|
166
|
+
withheld.filter((issue) => !needs_person(issue, context)),
|
|
167
|
+
context.repo,
|
|
168
|
+
),
|
|
169
|
+
human: to_children(
|
|
170
|
+
withheld.filter((issue) => needs_person(issue, context)),
|
|
171
|
+
context.repo,
|
|
172
|
+
),
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Every issue the backlog may run: each opted-in epic's children and the standalone rows
|
|
177
|
+
// (joshuafolkken/kit#1943). A child is opted in through its epic's `auto-ok` even where it carries none
|
|
178
|
+
// of its own, which is why the set is built from the graphs that were read rather than from labels. A
|
|
179
|
+
// standalone row a person has to resolve is left out, so a row waiting on it waits for that person too;
|
|
180
|
+
// an epic child in the same state is taken out by `epic_next_views.settle_views`.
|
|
181
|
+
function running_set(
|
|
182
|
+
graphs: ReadonlyArray<ReadonlyArray<EpicChild>>,
|
|
183
|
+
issues: ReadonlyArray<OpenIssueData>,
|
|
184
|
+
repo: string,
|
|
185
|
+
): ReadonlySet<string> {
|
|
186
|
+
const running = epic_outside_blocker.running_keys([
|
|
187
|
+
...graphs.flat(),
|
|
188
|
+
...to_children(standalone_rows(issues), repo),
|
|
189
|
+
])
|
|
190
|
+
|
|
191
|
+
return settle_standalone(running, issues, repo)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// A cycle no single epic can see, because its links cross from one graph into another. Each epic's own
|
|
195
|
+
// cycle is already that epic's anomaly, and a loop among standalone rows alone has always left them
|
|
196
|
+
// waiting without stopping the backlog, so what is reported here is only what crossing a graph adds.
|
|
197
|
+
function cross_epic_cycles(
|
|
198
|
+
graphs: ReadonlyArray<ReadonlyArray<EpicChild>>,
|
|
199
|
+
standalone: ReadonlyArray<EpicChild>,
|
|
200
|
+
): Array<GraphAnomaly> {
|
|
201
|
+
const within = new Set(
|
|
202
|
+
[...graphs, standalone].flatMap((children) => epic_graph.find_stuck_children(children)),
|
|
203
|
+
)
|
|
204
|
+
// The loops already known are left out before the walk rather than filtered from its answer, so what
|
|
205
|
+
// only sits downstream of one peels away instead of being named as a loop of its own.
|
|
206
|
+
const union = [...epic_graph.index_children([...graphs.flat(), ...standalone]).values()]
|
|
207
|
+
const stuck = epic_graph.find_stuck_children(
|
|
208
|
+
union.filter((child) => !within.has(epic_graph.key_of(child))),
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
if (stuck.length === 0) return []
|
|
212
|
+
|
|
213
|
+
return [
|
|
214
|
+
{
|
|
215
|
+
kind: 'cycle',
|
|
216
|
+
message: `Dependency cycle across the backlog: ${stuck.join(', ')} can never start until a person breaks it`,
|
|
217
|
+
},
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Two epics can list the same child. `epic:next` answers about one epic at a time and never sees it;
|
|
222
|
+
// here the child would reach standard output twice, and a loop starting one run per line would start
|
|
223
|
+
// it twice. Keyed by repository and number, because two repositories legitimately have an issue of
|
|
224
|
+
// the same number.
|
|
225
|
+
function unique_children(children: ReadonlyArray<EpicChild>): Array<EpicChild> {
|
|
226
|
+
const seen = new Set<string>()
|
|
227
|
+
const unique: Array<EpicChild> = []
|
|
228
|
+
|
|
229
|
+
for (const child of children) {
|
|
230
|
+
if (seen.has(epic_graph.key_of(child))) continue
|
|
231
|
+
seen.add(epic_graph.key_of(child))
|
|
232
|
+
unique.push(child)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return unique
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function without(children: ReadonlyArray<EpicChild>, taken: ReadonlySet<string>): Array<EpicChild> {
|
|
239
|
+
return children.filter((child) => !taken.has(epic_graph.key_of(child)))
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function keys_of(children: ReadonlyArray<EpicChild>): Set<string> {
|
|
243
|
+
return new Set(children.map((child) => epic_graph.key_of(child)))
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// The epic half, already classified. `epic:next` decided each of these — the `blocked-by` graph, the
|
|
247
|
+
// wave, the anomalies — so this only flattens the per-repository bundles back into one list, in the
|
|
248
|
+
// order the epics' own task lists gave them.
|
|
249
|
+
//
|
|
250
|
+
// **Withholding wins across the buckets, not only within one.** Two epics can classify the same child
|
|
251
|
+
// differently — one tracks the blocker and calls it `time`, the other does not track it and calls it
|
|
252
|
+
// `runnable` — and a child offered on standard output while standard error lists it as waiting is
|
|
253
|
+
// work a loop would start against a dependency that is still standing. So `human` is settled first,
|
|
254
|
+
// `time` next, and `runnable` keeps only what neither claimed.
|
|
255
|
+
function epic_classification(views: ReadonlyArray<EpicView>): Classification {
|
|
256
|
+
const human = unique_children(views.flatMap((view) => view.result.blocked_on_people))
|
|
257
|
+
const time = without(
|
|
258
|
+
unique_children(views.flatMap((view) => view.result.waiting)),
|
|
259
|
+
keys_of(human),
|
|
260
|
+
)
|
|
261
|
+
const offered = views.flatMap((view) =>
|
|
262
|
+
view.result.candidates.flatMap((bundle) => bundle.children),
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
runnable: without(unique_children(offered), keys_of([...human, ...time])),
|
|
267
|
+
time,
|
|
268
|
+
human,
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// `--exclude` takes bare numbers, and a bare number names an issue of the repository the command is
|
|
273
|
+
// running in. A child elsewhere with the same number is a different issue, so the comparison carries
|
|
274
|
+
// the repository rather than the number alone.
|
|
275
|
+
function is_kept(child: EpicChild, exclude: ReadonlyArray<number>, repo: string): boolean {
|
|
276
|
+
return child.repo !== repo || !exclude.includes(child.number)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// A child that merged moments ago still reads as open until GitHub applies `closes #N`, so an
|
|
280
|
+
// exclusion drops it from every bucket rather than only from the offer: left in `time`, it would
|
|
281
|
+
// answer `wait` for a backlog with nothing left to wait for.
|
|
282
|
+
function drop_excluded(
|
|
283
|
+
classification: Classification,
|
|
284
|
+
exclude: ReadonlyArray<number>,
|
|
285
|
+
repo: string,
|
|
286
|
+
): Classification {
|
|
287
|
+
return {
|
|
288
|
+
runnable: classification.runnable.filter((child) => is_kept(child, exclude, repo)),
|
|
289
|
+
time: classification.time.filter((child) => is_kept(child, exclude, repo)),
|
|
290
|
+
human: classification.human.filter((child) => is_kept(child, exclude, repo)),
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// The epic half first, then the standalone half. An epic's children are work somebody has already
|
|
295
|
+
// planned and ordered, so finishing what is in flight comes before starting something new.
|
|
296
|
+
function merge_classifications(left: Classification, right: Classification): Classification {
|
|
297
|
+
return {
|
|
298
|
+
runnable: [...left.runnable, ...right.runnable],
|
|
299
|
+
time: [...left.time, ...right.time],
|
|
300
|
+
human: [...left.human, ...right.human],
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const backlog_pool = {
|
|
305
|
+
classify_standalone,
|
|
306
|
+
cross_epic_cycles,
|
|
307
|
+
running_set,
|
|
308
|
+
settle_standalone,
|
|
309
|
+
drop_excluded,
|
|
310
|
+
epic_classification,
|
|
311
|
+
is_epic_row,
|
|
312
|
+
keys_of,
|
|
313
|
+
merge_classifications,
|
|
314
|
+
opted_in_epics,
|
|
315
|
+
standalone_rows,
|
|
316
|
+
to_child,
|
|
317
|
+
to_children,
|
|
318
|
+
unique_children,
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export { backlog_pool }
|
|
322
|
+
export type { StandaloneContext }
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
|
|
2
|
+
import { lane_capacity } from '#scripts/lane/lane-capacity'
|
|
3
|
+
import { lane_registry } from '#scripts/lane/lane-registry'
|
|
4
|
+
import type { RunCarry } from '#scripts/run/run-carry'
|
|
5
|
+
import { run_headless } from '#scripts/run/run-headless'
|
|
6
|
+
import { run_invocation } from '#scripts/run/run-invocation'
|
|
7
|
+
import { backlog_stalled } from './backlog-stalled'
|
|
8
|
+
|
|
9
|
+
// The ready line reports runnable work to the driving backlogrun parent on a watcher wake.
|
|
10
|
+
|
|
11
|
+
const NO_FREE = 0
|
|
12
|
+
const NONE = 0
|
|
13
|
+
|
|
14
|
+
interface ReadyReading {
|
|
15
|
+
issues: ReadonlyArray<string>
|
|
16
|
+
free_lanes: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface ReadyPorts {
|
|
20
|
+
free_lane_count: () => Promise<number>
|
|
21
|
+
ready_issues: () => Promise<ReadonlyArray<string>>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Free lanes right now: the limit less the live lanes. An unreadable limit reads as no free lane — the
|
|
25
|
+
// safe direction, since both the stall and the ready line need a free lane and reporting one that is
|
|
26
|
+
// not there is the false positive neither may raise.
|
|
27
|
+
//
|
|
28
|
+
// **Occupancy is the local worktree count, not the dispatch budget's busy read.** `epic-lane-offer`
|
|
29
|
+
// measures occupancy with `epic_busy.occupied_lanes`, a network read of in-progress issue labels; this
|
|
30
|
+
// counts live worktrees instead, deliberately — it runs on the cheap-first path where the costly read
|
|
31
|
+
// (`backlog:next`) is gated behind a free lane, so a network read here would defeat that design. The
|
|
32
|
+
// two can diverge, but only toward over-counting live lanes → fewer free lanes, the safe direction.
|
|
33
|
+
async function free_lane_count(): Promise<number> {
|
|
34
|
+
const limit = lane_capacity.lane_limit()
|
|
35
|
+
|
|
36
|
+
if (limit.kind !== 'limit') return NO_FREE
|
|
37
|
+
|
|
38
|
+
const lanes = await lane_registry.list_lanes()
|
|
39
|
+
const live = lanes.filter((lane) => !lane.is_stranded).length
|
|
40
|
+
|
|
41
|
+
return lane_capacity.free_lanes(limit.limit, live)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// **A `--only` run has no pool to drain** (joshuafolkken/kit#2472). `backlog:next` lists the opted-in
|
|
45
|
+
// pool, and a `--only` run's work is its named list — issues and epics that run in order through their
|
|
46
|
+
// own step, never through the pick-up ask — so a ready pool issue is neither a stall nor an ask it owes.
|
|
47
|
+
// Without a `--only` record the pool is the run's, whole.
|
|
48
|
+
function drains_pool(carry: RunCarry | undefined): boolean {
|
|
49
|
+
return carry === undefined || !run_invocation.has_only(carry.invocation)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// The `backlog:next` read, or `undefined` for a `--only` run, which answers none before paying for the
|
|
53
|
+
// network read. A bounded read (joshuafolkken/kit#2503) keeps stderr piped: the arrival probe reads once
|
|
54
|
+
// a minute, and a forwarded refusal would fill the watcher's output.
|
|
55
|
+
async function read_backlog_next(timeout_ms?: number): Promise<JoshResult | undefined> {
|
|
56
|
+
if (!drains_pool(await run_headless.current_carry())) return undefined
|
|
57
|
+
|
|
58
|
+
return await josh_command.josh_run(['backlog:next'], timeout_ms === undefined, timeout_ms)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// The runnable issues for this checkout, read the way a loop reads them: `backlog:next`'s numeric lines.
|
|
62
|
+
async function ready_issues(): Promise<ReadonlyArray<string>> {
|
|
63
|
+
const result = await read_backlog_next()
|
|
64
|
+
|
|
65
|
+
return result === undefined ? [] : backlog_stalled.ready_tokens(result.out)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const DEFAULT_PORTS: ReadyPorts = { free_lane_count, ready_issues }
|
|
69
|
+
|
|
70
|
+
// Cheap first: a full pool answers without the network read, since ready work with nowhere to go is not
|
|
71
|
+
// a pick-up.
|
|
72
|
+
async function read_ready(ports: ReadyPorts = DEFAULT_PORTS): Promise<ReadyReading> {
|
|
73
|
+
const free_lanes = await ports.free_lane_count()
|
|
74
|
+
|
|
75
|
+
if (free_lanes <= NO_FREE) return { issues: [], free_lanes }
|
|
76
|
+
|
|
77
|
+
return { issues: await ports.ready_issues(), free_lanes }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// `undefined` unless there is both runnable work and a lane for it — the only state worth a line.
|
|
81
|
+
function ready_line(reading: ReadyReading): string | undefined {
|
|
82
|
+
if (reading.issues.length === NONE || reading.free_lanes <= NO_FREE) return undefined
|
|
83
|
+
|
|
84
|
+
const issues = reading.issues.map((issue) => `#${issue}`).join(' ')
|
|
85
|
+
|
|
86
|
+
return `ready ${issues} · free lanes ${String(reading.free_lanes)}`
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// The watcher's line on exit, for the driving parent alone — a `fullrun` watcher has no pool to pick
|
|
90
|
+
// from. Best-effort: a reading that fails prints nothing rather than failing the watcher whose exit is
|
|
91
|
+
// the wake.
|
|
92
|
+
async function parent_ready_line(
|
|
93
|
+
ports: ReadyPorts,
|
|
94
|
+
is_parent: () => Promise<boolean>,
|
|
95
|
+
): Promise<string | undefined> {
|
|
96
|
+
if (!(await is_parent())) return undefined
|
|
97
|
+
|
|
98
|
+
return ready_line(await read_ready(ports))
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function print_ready_line(
|
|
102
|
+
ports: ReadyPorts = DEFAULT_PORTS,
|
|
103
|
+
is_parent: () => Promise<boolean> = run_headless.is_backlog_parent,
|
|
104
|
+
): Promise<void> {
|
|
105
|
+
try {
|
|
106
|
+
const line = await parent_ready_line(ports, is_parent)
|
|
107
|
+
|
|
108
|
+
if (line !== undefined) console.info(line)
|
|
109
|
+
} catch {
|
|
110
|
+
// A pick-up line is a hint; the wake it rides must still be delivered.
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// The line `epic --add` prints once a child entered an epic while a `backlogrun` parent drives this
|
|
115
|
+
// checkout: a filing made mid-run joins the pool the moment it is placed, so the parent asks now rather
|
|
116
|
+
// than on the next wake (joshuafolkken/kit#2452). The recommendation commands (`issue:scout`,
|
|
117
|
+
// `epic:bundle`) carry none — before the insertion the child is in no pool the ask could find.
|
|
118
|
+
const OFFER_HINT =
|
|
119
|
+
'↻ backlogrun parent: a child just entered an epic — run `pnpm josh backlog:offer` next, so a ' +
|
|
120
|
+
'runnable filing is dispatched now rather than on the next wake.'
|
|
121
|
+
|
|
122
|
+
async function print_offer_hint(
|
|
123
|
+
is_parent: () => Promise<boolean> = run_headless.is_backlog_parent,
|
|
124
|
+
): Promise<void> {
|
|
125
|
+
try {
|
|
126
|
+
if (await is_parent()) console.info(OFFER_HINT)
|
|
127
|
+
} catch {
|
|
128
|
+
// A hint that cannot read the carry record says nothing; the insertion itself has landed.
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const backlog_ready = {
|
|
133
|
+
DEFAULT_PORTS,
|
|
134
|
+
OFFER_HINT,
|
|
135
|
+
read_backlog_next,
|
|
136
|
+
print_offer_hint,
|
|
137
|
+
free_lane_count,
|
|
138
|
+
drains_pool,
|
|
139
|
+
print_ready_line,
|
|
140
|
+
read_ready,
|
|
141
|
+
ready_issues,
|
|
142
|
+
ready_line,
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export { backlog_ready }
|
|
146
|
+
export type { ReadyPorts, ReadyReading }
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { EpicNextResult } from '#scripts/epic/epic-report'
|
|
2
|
+
import { AUTO_OK_LABEL, EPIC_LABEL, has_any_label } from '#scripts/git/issue-labels'
|
|
3
|
+
import type { OpenIssueData } from '#scripts/git/schemas'
|
|
4
|
+
|
|
5
|
+
// Which open issues the backlog will not run, and why (joshuafolkken/kit#1652).
|
|
6
|
+
//
|
|
7
|
+
// **The set is a subtraction, never a second membership rule.** Everything open that the pool did not
|
|
8
|
+
// classify is out of scope, so this cannot drift from what `backlog:next` offers the way a
|
|
9
|
+
// re-implemented "is it opted in" test would. What is decided per row is only the sentence saying
|
|
10
|
+
// why, and each of those is read off a label rather than judged.
|
|
11
|
+
//
|
|
12
|
+
// It exists because the exclusion used to be silent: an issue without `auto-ok`, or a child of an
|
|
13
|
+
// epic whose root lacks it, never enters the pool at all, so a person watching a `backlogrun` could
|
|
14
|
+
// not tell "not opted in" from "the backlog has not reached it yet".
|
|
15
|
+
//
|
|
16
|
+
// A child of an epic whose root lacks `auto-ok` is no longer one of those — since
|
|
17
|
+
// joshuafolkken/kit#1668 its own label carries it into the standalone half, so it is offered rather
|
|
18
|
+
// than explained. What is still explained here is the child of an epic that **is** opted in and that
|
|
19
|
+
// the epic did not place, and telling that apart from a row past the listing cap is the whole of
|
|
20
|
+
// `opted_in_reason` below.
|
|
21
|
+
|
|
22
|
+
const EPIC_LABELS: ReadonlySet<string> = new Set([EPIC_LABEL])
|
|
23
|
+
const AUTO_OK_LABELS: ReadonlySet<string> = new Set([AUTO_OK_LABEL])
|
|
24
|
+
|
|
25
|
+
const NO_OPT_IN_REASON = 'not opted in — no `auto-ok` label'
|
|
26
|
+
// Since joshuafolkken/kit#1668 this no longer speaks for the children: an epic that did not opt in
|
|
27
|
+
// offers none of them, but each child carrying `auto-ok` of its own is offered by the standalone
|
|
28
|
+
// half. Saying "its children are not offered" here would contradict the plan's own ready section.
|
|
29
|
+
const EPIC_NOT_OPTED_IN_REASON =
|
|
30
|
+
'epic root without `auto-ok` — it offers no children, and only a child carrying `auto-ok` itself is offered'
|
|
31
|
+
const EPIC_ROOT_REASON = 'epic root — a container, so its children are planned instead of it'
|
|
32
|
+
const OPTED_IN_UNPLACED_REASON = 'opted in, but past the listing cap this ask could read'
|
|
33
|
+
|
|
34
|
+
// The cap is what the row above says, and it used to be said of every opted-in row the plan could
|
|
35
|
+
// not place — including the ones the cap had nothing to do with (joshuafolkken/kit#1668). An issue an
|
|
36
|
+
// opted-in epic tracks is offered through that epic and not standalone, so when the epic did not
|
|
37
|
+
// place it either, the epic is the fact worth naming and the cap is a misreport a reader acts on:
|
|
38
|
+
// "past the cap" reads as "the next ask will offer it", and the next ask never does.
|
|
39
|
+
function epic_tracked_reason(epic: number): string {
|
|
40
|
+
return `tracked by epic #${String(epic)}, which offers it instead of the standalone half`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// `--exclude` drops an issue from every bucket, so an excluded one lands here. Named for what it is,
|
|
44
|
+
// because the label-derived reasons would otherwise report a cap that had nothing to do with it.
|
|
45
|
+
const EXCLUDED_REASON = 'excluded from this ask — it merged moments ago'
|
|
46
|
+
|
|
47
|
+
interface OutOfScopeRow {
|
|
48
|
+
number: number
|
|
49
|
+
title: string
|
|
50
|
+
reason: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// What the subtraction is made against: this repository, and the numbers the caller excluded.
|
|
54
|
+
interface ScopeContext {
|
|
55
|
+
repo: string
|
|
56
|
+
exclude: ReadonlyArray<number>
|
|
57
|
+
// Which **opted-in** epic is withholding which issue — `epic_index.withheld_children`'s own answer,
|
|
58
|
+
// the one the pool decided membership from, so the sentence and the decision cannot disagree
|
|
59
|
+
// (joshuafolkken/kit#1668). A row in here is one an epic is genuinely offering instead.
|
|
60
|
+
tracked: ReadonlyMap<number, number>
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// A child elsewhere is excluded by repository rather than by number: two repositories legitimately
|
|
64
|
+
// have an issue of the same number, and the open listing this is subtracted from is this one's.
|
|
65
|
+
function planned_numbers(result: EpicNextResult, repo: string): ReadonlySet<number> {
|
|
66
|
+
const children = [
|
|
67
|
+
...result.candidates.flatMap((bundle) => bundle.children),
|
|
68
|
+
...result.waiting,
|
|
69
|
+
...result.blocked_on_people,
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
return new Set(children.filter((child) => child.repo === repo).map((child) => child.number))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// An epic root carrying `auto-ok` is not an omission — it is a container whose children are planned
|
|
76
|
+
// individually, which is the distinction a person reading "why is this not running" most needs.
|
|
77
|
+
function opted_in_reason(issue: OpenIssueData, tracked: ReadonlyMap<number, number>): string {
|
|
78
|
+
const epic = tracked.get(issue.number)
|
|
79
|
+
|
|
80
|
+
return epic === undefined ? OPTED_IN_UNPLACED_REASON : epic_tracked_reason(epic)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function label_reason(issue: OpenIssueData, tracked: ReadonlyMap<number, number>): string {
|
|
84
|
+
const is_opted_in = has_any_label(issue.labels, AUTO_OK_LABELS)
|
|
85
|
+
|
|
86
|
+
if (has_any_label(issue.labels, EPIC_LABELS)) {
|
|
87
|
+
return is_opted_in ? EPIC_ROOT_REASON : EPIC_NOT_OPTED_IN_REASON
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return is_opted_in ? opted_in_reason(issue, tracked) : NO_OPT_IN_REASON
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// The exclusion is checked before the labels, because it is why the issue is here at all: an
|
|
94
|
+
// excluded row still carries whatever labels it had, and reading those would name a cause that had
|
|
95
|
+
// nothing to do with its absence from the plan.
|
|
96
|
+
function reason_for(issue: OpenIssueData, scope: ScopeContext): string {
|
|
97
|
+
return scope.exclude.includes(issue.number) ? EXCLUDED_REASON : label_reason(issue, scope.tracked)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function out_of_scope(
|
|
101
|
+
open_issues: ReadonlyArray<OpenIssueData>,
|
|
102
|
+
result: EpicNextResult,
|
|
103
|
+
scope: ScopeContext,
|
|
104
|
+
): ReadonlyArray<OutOfScopeRow> {
|
|
105
|
+
const planned = planned_numbers(result, scope.repo)
|
|
106
|
+
|
|
107
|
+
return open_issues
|
|
108
|
+
.filter((issue) => !planned.has(issue.number))
|
|
109
|
+
.map((issue) => ({
|
|
110
|
+
number: issue.number,
|
|
111
|
+
title: issue.title,
|
|
112
|
+
reason: reason_for(issue, scope),
|
|
113
|
+
}))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// The pool carries issue numbers and labels but no titles, and a plan of bare numbers is not a plan a
|
|
117
|
+
// person can read. The one open listing the subtraction already needs is where they come from, so no
|
|
118
|
+
// second read is made for them.
|
|
119
|
+
function titles_of(open_issues: ReadonlyArray<OpenIssueData>): ReadonlyMap<number, string> {
|
|
120
|
+
return new Map(open_issues.map((issue) => [issue.number, issue.title]))
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// The numbers still open in this repository, which is how a waiting row tells a standing blocker from
|
|
124
|
+
// one that has since closed. Same listing, so it costs nothing beyond the map above.
|
|
125
|
+
function open_numbers_of(open_issues: ReadonlyArray<OpenIssueData>): ReadonlySet<number> {
|
|
126
|
+
return new Set(open_issues.map((issue) => issue.number))
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const backlog_scope = {
|
|
130
|
+
epic_tracked_reason,
|
|
131
|
+
EPIC_NOT_OPTED_IN_REASON,
|
|
132
|
+
EPIC_ROOT_REASON,
|
|
133
|
+
EXCLUDED_REASON,
|
|
134
|
+
NO_OPT_IN_REASON,
|
|
135
|
+
OPTED_IN_UNPLACED_REASON,
|
|
136
|
+
open_numbers_of,
|
|
137
|
+
out_of_scope,
|
|
138
|
+
planned_numbers,
|
|
139
|
+
reason_for,
|
|
140
|
+
titles_of,
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export { backlog_scope }
|
|
144
|
+
export type { OutOfScopeRow, ScopeContext }
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { backlog_stalled } from './backlog-stalled'
|
|
4
|
+
import { backlog_stalled_detect } from './backlog-stalled-detect'
|
|
5
|
+
|
|
6
|
+
// `josh backlog:stalled` — read the three conditions once and print the verdict
|
|
7
|
+
// (joshuafolkken/kit#2359). This is the manual and testable face of the detector `stop-guard.ts` runs
|
|
8
|
+
// on every stop; both call the one `detect_and_report`, so the command and the hook can never drift.
|
|
9
|
+
//
|
|
10
|
+
// **It reports, it never stops.** The exit code is always success — a stall is a state to surface, not
|
|
11
|
+
// an error to fail on — so a caller (a person, a test, a wired hook) reads the verdict off stdout and is
|
|
12
|
+
// never halted by it. An unreadable record prints `unreadable` for the same reason: the run carries on.
|
|
13
|
+
|
|
14
|
+
const SUCCESS_EXIT_CODE = 0
|
|
15
|
+
|
|
16
|
+
async function main(): Promise<void> {
|
|
17
|
+
try {
|
|
18
|
+
console.info(await backlog_stalled_detect.detect_and_report())
|
|
19
|
+
} catch {
|
|
20
|
+
console.info(backlog_stalled.UNREADABLE)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
process.exitCode = SUCCESS_EXIT_CODE
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const backlog_stalled_cli = { main }
|
|
27
|
+
|
|
28
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
|
|
29
|
+
|
|
30
|
+
export { backlog_stalled_cli }
|