@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,410 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { epic_busy } from '#scripts/epic/epic-busy'
|
|
4
|
+
import { git_gh_command } from '#scripts/git/git-gh-command'
|
|
5
|
+
import { run_carry } from '#scripts/run/run-carry'
|
|
6
|
+
import { lane_await } from './lane-await'
|
|
7
|
+
import { lane_close, type CloseOutcome, type SweepOutcome } from './lane-close'
|
|
8
|
+
import { lane_dispatch, type DispatchOutcome } from './lane-dispatch'
|
|
9
|
+
import { lane_occupancy } from './lane-occupancy'
|
|
10
|
+
import { lane_open, type OpenOutcome } from './lane-open'
|
|
11
|
+
import { lane_output, type ReadOutcome, type RecordOutcome } from './lane-output'
|
|
12
|
+
import { lane_registry, type LaneInfo } from './lane-registry'
|
|
13
|
+
import { lane_report } from './lane-report'
|
|
14
|
+
import { lane_seed_policy } from './lane-seed'
|
|
15
|
+
|
|
16
|
+
// `josh lane:open` / `lane:close` / `lane:list` / `lane:prune` — the lane's whole lifecycle
|
|
17
|
+
// (joshuafolkken/kit#1490).
|
|
18
|
+
//
|
|
19
|
+
// **`lane:open` prints the lane's directory on standard output and nothing else**, so
|
|
20
|
+
// `dir=$(pnpm josh lane:open 1490)` is what a caller needs and a refusal is an empty capture beside
|
|
21
|
+
// a non-zero exit. The other three follow the contract `run:hold` and `epic:next` set: a token per
|
|
22
|
+
// line on standard output, every explanation on standard error.
|
|
23
|
+
|
|
24
|
+
const SUCCESS_EXIT_CODE = 0
|
|
25
|
+
const FAILURE_EXIT_CODE = 1
|
|
26
|
+
const ARGV_OFFSET = 2
|
|
27
|
+
const SINGLE_ARGUMENT = 1
|
|
28
|
+
const ISSUE_AND_PATH_ARGUMENTS = 2
|
|
29
|
+
const ALL_FLAG = '--all'
|
|
30
|
+
const NONE_TOKEN = 'none'
|
|
31
|
+
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
32
|
+
|
|
33
|
+
const USAGE = [
|
|
34
|
+
'Usage: josh lane:open <issue-number>',
|
|
35
|
+
' josh lane:close <issue-number> | josh lane:close --all',
|
|
36
|
+
' josh lane:list',
|
|
37
|
+
' josh lane:prune',
|
|
38
|
+
' josh lane:output <issue-number> [<path>]',
|
|
39
|
+
' josh lane:dispatch <issue-number>',
|
|
40
|
+
' josh lane:await <issue-number> ...',
|
|
41
|
+
].join('\n')
|
|
42
|
+
|
|
43
|
+
type Handler = (rest: ReadonlyArray<string>) => Promise<number>
|
|
44
|
+
|
|
45
|
+
function report_usage(): number {
|
|
46
|
+
console.error(USAGE)
|
|
47
|
+
|
|
48
|
+
return FAILURE_EXIT_CODE
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Read the carry record and refuse if this session has already handed off its budget via `--cut`.
|
|
52
|
+
// A cut session must not open new lanes or dispatch new children — the successor owns the budget
|
|
53
|
+
// (joshuafolkken/kit#2114).
|
|
54
|
+
async function guard_cut_session(): Promise<string | undefined> {
|
|
55
|
+
const directory = await run_carry.repository_directory()
|
|
56
|
+
|
|
57
|
+
if (directory === undefined) return undefined
|
|
58
|
+
|
|
59
|
+
const read = run_carry.read_carry(run_carry.carry_path(directory))
|
|
60
|
+
|
|
61
|
+
if ((read.kind !== 'carried' && read.kind !== 'expired') || read.carry.is_handed_off !== true) {
|
|
62
|
+
return undefined
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return run_carry.count_refused_message(read.carry)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function parse_lane_issue(value: string | undefined): string | undefined {
|
|
69
|
+
if (value === undefined) return undefined
|
|
70
|
+
|
|
71
|
+
return ISSUE_NUMBER_PATTERN.test(value) ? value : undefined
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function parse_issue(rest: ReadonlyArray<string>): string | undefined {
|
|
75
|
+
if (rest.length > SINGLE_ARGUMENT) return undefined
|
|
76
|
+
|
|
77
|
+
return parse_lane_issue(rest[0])
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// The two refusals name what to type next, because both are states a person recovers from rather
|
|
81
|
+
// than reports: one lane is already there, or every index is spoken for.
|
|
82
|
+
function refusal_message(outcome: Exclude<OpenOutcome, { kind: 'opened' }>): string {
|
|
83
|
+
if (outcome.kind === 'full') {
|
|
84
|
+
return `All ${String(lane_seed_policy.LAST_LANE_SEAT)} lane seats are taken. Run \`pnpm josh lane:list\` to see them and \`pnpm josh lane:close <issue-number>\` to free one.`
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return `A lane for #${outcome.lane.issue} is already open at ${outcome.lane.directory}. Run \`pnpm josh lane:close ${outcome.lane.issue}\` before opening it again.`
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function report_open(outcome: OpenOutcome): number {
|
|
91
|
+
if (outcome.kind !== 'opened') {
|
|
92
|
+
console.error(refusal_message(outcome))
|
|
93
|
+
|
|
94
|
+
return FAILURE_EXIT_CODE
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.error(lane_report.describe_opened(outcome.lane))
|
|
98
|
+
console.info(outcome.lane.directory)
|
|
99
|
+
|
|
100
|
+
return SUCCESS_EXIT_CODE
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// One token per closed lane, `none` when there was nothing to close — so a caller sweeping up after
|
|
104
|
+
// an interruption can branch on the output without reading the prose.
|
|
105
|
+
function report_issues(issues: ReadonlyArray<string>): number {
|
|
106
|
+
console.info(issues.length === 0 ? NONE_TOKEN : issues.join('\n'))
|
|
107
|
+
|
|
108
|
+
return SUCCESS_EXIT_CODE
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// A close that left something behind exits non-zero and names it. Reported as a success, it would
|
|
112
|
+
// send the caller to the next `lane:open`, which then fails on git's own message about a branch that
|
|
113
|
+
// still exists.
|
|
114
|
+
function report_close(outcome: CloseOutcome): number {
|
|
115
|
+
if (outcome.reaped.length > 0) {
|
|
116
|
+
console.error(
|
|
117
|
+
`Terminated the lane child for #${outcome.issue} that had not ended by itself: process ${outcome.reaped.join(', ')}.`,
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (outcome.kind !== 'incomplete') {
|
|
122
|
+
return report_issues(outcome.kind === 'closed' ? [outcome.issue] : [])
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
console.error(
|
|
126
|
+
`Closing the lane for #${outcome.issue} left this behind: ${outcome.left_behind.join(', ')}. Remove it and run \`pnpm josh lane:close ${outcome.issue}\` again.`,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
return FAILURE_EXIT_CODE
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// The closed lanes still go to standard output, because a sweep that failed on one of them has
|
|
133
|
+
// closed the rest and the caller has to know which.
|
|
134
|
+
function report_sweep(outcome: SweepOutcome): number {
|
|
135
|
+
const code = report_issues(outcome.closed)
|
|
136
|
+
|
|
137
|
+
if (outcome.failed.length === 0) return code
|
|
138
|
+
|
|
139
|
+
const named = outcome.failed.map((issue) => `#${issue}`).join(', ')
|
|
140
|
+
|
|
141
|
+
// `lane:list` reads git's work trees, and the usual survivor is a branch whose work tree is
|
|
142
|
+
// already gone — which that listing cannot show. Closing each one again is what names it.
|
|
143
|
+
console.error(
|
|
144
|
+
`These lanes could not be closed: ${named}. Run \`pnpm josh lane:close <issue-number>\` on each to see what is left of it.`,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return FAILURE_EXIT_CODE
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// `none` on standard output for the empty case as well, so `lane:list` keeps the contract the rest
|
|
151
|
+
// of the commands follow — the prose belongs on standard error with every other explanation.
|
|
152
|
+
function report_lanes(lanes: ReadonlyArray<LaneInfo>): number {
|
|
153
|
+
if (lanes.length === 0) console.error(lane_report.NO_LANES)
|
|
154
|
+
|
|
155
|
+
console.info(lanes.length === 0 ? NONE_TOKEN : lane_report.describe_lanes(lanes))
|
|
156
|
+
|
|
157
|
+
return SUCCESS_EXIT_CODE
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function open_command(rest: ReadonlyArray<string>): Promise<number> {
|
|
161
|
+
const issue = parse_issue(rest)
|
|
162
|
+
|
|
163
|
+
if (issue === undefined) return report_usage()
|
|
164
|
+
|
|
165
|
+
const refused = await guard_cut_session()
|
|
166
|
+
|
|
167
|
+
if (refused !== undefined) {
|
|
168
|
+
console.error(refused)
|
|
169
|
+
|
|
170
|
+
return FAILURE_EXIT_CODE
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return report_open(await lane_open.open_lane(issue))
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async function close_command(rest: ReadonlyArray<string>): Promise<number> {
|
|
177
|
+
if (rest[0] === ALL_FLAG && rest.length === SINGLE_ARGUMENT) {
|
|
178
|
+
return report_sweep(await lane_close.close_all_lanes())
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const issue = parse_issue(rest)
|
|
182
|
+
|
|
183
|
+
if (issue === undefined) return report_usage()
|
|
184
|
+
|
|
185
|
+
return report_close(await lane_close.close_lane(issue))
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const OCCUPANCY_UNREADABLE =
|
|
189
|
+
'Could not read the `in-progress` listing, so the lane/label difference was not checked — that is not "everything agrees"; check `gh auth status`.'
|
|
190
|
+
|
|
191
|
+
// The `in-progress` issues this repository shows running, read the way `epic:next` reads lane
|
|
192
|
+
// occupancy — never rebuilt (joshuafolkken/kit#2235). A read that could not see the whole listing is
|
|
193
|
+
// `undefined`, so the difference is skipped rather than computed against a set known to be partial.
|
|
194
|
+
async function to_holder_numbers(repo: string): Promise<ReadonlyArray<number> | undefined> {
|
|
195
|
+
const read = await epic_busy.read_repository(repo)
|
|
196
|
+
if (read.kind === 'idle') return []
|
|
197
|
+
|
|
198
|
+
return read.kind === 'busy' ? read.issues.map((issue) => issue.number) : undefined
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function read_in_progress(): Promise<ReadonlyArray<number> | undefined> {
|
|
202
|
+
try {
|
|
203
|
+
const repo = await git_gh_command.repo_get_name_with_owner()
|
|
204
|
+
|
|
205
|
+
return repo === undefined ? undefined : await to_holder_numbers(repo)
|
|
206
|
+
} catch {
|
|
207
|
+
return undefined
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// A stranded lane's work tree is gone, so it holds no issue: it counts as no lane rather than a live
|
|
212
|
+
// one, which is what turns its surviving `in-progress` label into a `stopped` anomaly.
|
|
213
|
+
function live_lane_issues(lanes: ReadonlyArray<LaneInfo>): Array<number> {
|
|
214
|
+
return lanes.filter((lane) => !lane.is_stranded).map((lane) => Number(lane.issue))
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// The lane/label difference, printed to standard error beside the listing. Wrapped so a GitHub read
|
|
218
|
+
// that fails skips only this section — `lane:list`'s job is to list the lanes it already read.
|
|
219
|
+
async function report_occupancy(lanes: ReadonlyArray<LaneInfo>): Promise<void> {
|
|
220
|
+
const in_progress = await read_in_progress()
|
|
221
|
+
|
|
222
|
+
if (in_progress === undefined) {
|
|
223
|
+
console.error(OCCUPANCY_UNREADABLE)
|
|
224
|
+
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const report = lane_occupancy.classify(in_progress, {
|
|
229
|
+
kind: 'lanes',
|
|
230
|
+
issues: live_lane_issues(lanes),
|
|
231
|
+
})
|
|
232
|
+
const described = lane_occupancy.describe(report)
|
|
233
|
+
|
|
234
|
+
if (described !== undefined) console.error(described)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async function list_command(rest: ReadonlyArray<string>): Promise<number> {
|
|
238
|
+
if (rest.length > 0) return report_usage()
|
|
239
|
+
|
|
240
|
+
const lanes = await lane_registry.list_lanes()
|
|
241
|
+
const code = report_lanes(lanes)
|
|
242
|
+
|
|
243
|
+
await report_occupancy(lanes)
|
|
244
|
+
|
|
245
|
+
return code
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async function prune_command(rest: ReadonlyArray<string>): Promise<number> {
|
|
249
|
+
if (rest.length > 0) return report_usage()
|
|
250
|
+
|
|
251
|
+
return report_sweep(await lane_close.prune_lanes())
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// The recorded path goes to standard output on both arms, so
|
|
255
|
+
// `unit_output=$(pnpm josh lane:output <N>) && pnpm josh run:liveness <N> --output "$unit_output"`
|
|
256
|
+
// works in a session that opened the lane and in one that never saw it alike. **The `&&` rather than
|
|
257
|
+
// a substitution inside the argument**: a substitution discards the exit status, so the `none` below
|
|
258
|
+
// would reach `--output` as a relative path and poll `undetermined` for ever.
|
|
259
|
+
function report_record(outcome: RecordOutcome, issue: string): number {
|
|
260
|
+
if (outcome.kind !== 'recorded') {
|
|
261
|
+
console.error(lane_output.describe_refusal(outcome, issue))
|
|
262
|
+
|
|
263
|
+
return FAILURE_EXIT_CODE
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
console.info(outcome.output)
|
|
267
|
+
|
|
268
|
+
return SUCCESS_EXIT_CODE
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// `none` for a lane that records nothing yet — the same token `lane:list` and `lane:close` print for
|
|
272
|
+
// an empty answer — but with a **non-zero** exit, unlike either of those. The reader here is a
|
|
273
|
+
// command substitution, and `--output none` is a relative path `run:liveness` answers `undetermined`
|
|
274
|
+
// for: polled that way a lane says "could not read" for ever rather than "the record is missing". A
|
|
275
|
+
// non-zero exit is what stops the `&&` in the documented one-liner before it gets there.
|
|
276
|
+
function report_output(outcome: ReadOutcome, issue: string): number {
|
|
277
|
+
if (outcome.kind === 'no-lane') {
|
|
278
|
+
console.error(lane_output.describe_refusal(outcome, issue))
|
|
279
|
+
|
|
280
|
+
return FAILURE_EXIT_CODE
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (outcome.kind === 'none') {
|
|
284
|
+
console.error(lane_output.NO_OUTPUT)
|
|
285
|
+
console.info(NONE_TOKEN)
|
|
286
|
+
|
|
287
|
+
return FAILURE_EXIT_CODE
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
console.info(outcome.output)
|
|
291
|
+
|
|
292
|
+
return SUCCESS_EXIT_CODE
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async function output_command(rest: ReadonlyArray<string>): Promise<number> {
|
|
296
|
+
const [first, second] = rest
|
|
297
|
+
const issue = parse_lane_issue(first)
|
|
298
|
+
|
|
299
|
+
if (issue === undefined || rest.length > ISSUE_AND_PATH_ARGUMENTS) return report_usage()
|
|
300
|
+
|
|
301
|
+
if (second === undefined) return report_output(await lane_output.read_output(issue), issue)
|
|
302
|
+
|
|
303
|
+
return report_record(await lane_output.record_output(issue, second), issue)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// The child's pid goes to standard output alone, so `pid=$(pnpm josh lane:dispatch <N>)` is what a
|
|
307
|
+
// caller needs — and a refusal is an empty capture beside a non-zero exit, exactly as `lane:open`'s is.
|
|
308
|
+
// **Every refusal also warns**, because the session that issued the dispatch may be the one about to be
|
|
309
|
+
// cut: a lane that never started its child is indistinguishable from one whose child is still thinking,
|
|
310
|
+
// and nothing else would ever say which it was. **So does a launch that started a child with nowhere to
|
|
311
|
+
// write** — `is_worth_warning` is what decides, rather than this function reading the outcome's shape.
|
|
312
|
+
async function report_dispatch(outcome: DispatchOutcome, issue: string): Promise<number> {
|
|
313
|
+
console.error(lane_dispatch.describe(outcome, issue))
|
|
314
|
+
|
|
315
|
+
if (lane_dispatch.is_worth_warning(outcome)) await lane_dispatch.warn_of_problem(outcome, issue)
|
|
316
|
+
|
|
317
|
+
if (outcome.kind !== 'dispatched') return FAILURE_EXIT_CODE
|
|
318
|
+
|
|
319
|
+
console.info(String(outcome.pid))
|
|
320
|
+
|
|
321
|
+
return SUCCESS_EXIT_CODE
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
async function dispatch_command(rest: ReadonlyArray<string>): Promise<number> {
|
|
325
|
+
const issue = parse_issue(rest)
|
|
326
|
+
|
|
327
|
+
if (issue === undefined) return report_usage()
|
|
328
|
+
|
|
329
|
+
const refused = await guard_cut_session()
|
|
330
|
+
|
|
331
|
+
if (refused !== undefined) {
|
|
332
|
+
console.error(refused)
|
|
333
|
+
|
|
334
|
+
return FAILURE_EXIT_CODE
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return await report_dispatch(await lane_dispatch.dispatch_child(issue), issue)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Each valid argument is an issue number; any non-number stops parsing and triggers usage.
|
|
341
|
+
function parse_issues(rest: ReadonlyArray<string>): ReadonlyArray<string> | undefined {
|
|
342
|
+
if (rest.length === 0) return undefined
|
|
343
|
+
const issues = rest.filter((value) => lane_await.ISSUE_PATTERN.test(value))
|
|
344
|
+
|
|
345
|
+
return issues.length === rest.length ? issues : undefined
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// The completed issue number goes to standard output so `N=$(pnpm josh lane:await ...)` captures
|
|
349
|
+
// which child finished without parsing stderr.
|
|
350
|
+
async function await_command(rest: ReadonlyArray<string>): Promise<number> {
|
|
351
|
+
const issues = parse_issues(rest)
|
|
352
|
+
|
|
353
|
+
if (issues === undefined) return report_usage()
|
|
354
|
+
|
|
355
|
+
const completed = await lane_await.wait_for_any(issues)
|
|
356
|
+
|
|
357
|
+
console.info(completed)
|
|
358
|
+
|
|
359
|
+
return SUCCESS_EXIT_CODE
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const HANDLERS: Record<string, Handler> = {
|
|
363
|
+
open: open_command,
|
|
364
|
+
close: close_command,
|
|
365
|
+
list: list_command,
|
|
366
|
+
prune: prune_command,
|
|
367
|
+
output: output_command,
|
|
368
|
+
dispatch: dispatch_command,
|
|
369
|
+
await: await_command,
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
async function dispatch(argv: ReadonlyArray<string>): Promise<number> {
|
|
373
|
+
const [verb, ...rest] = argv
|
|
374
|
+
const handler = verb === undefined ? undefined : HANDLERS[verb]
|
|
375
|
+
|
|
376
|
+
if (handler === undefined) return report_usage()
|
|
377
|
+
|
|
378
|
+
return await handler(rest)
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// A git failure — no repository, a path a work tree cannot be created at — is reported and exits
|
|
382
|
+
// non-zero rather than throwing a stack trace at a caller that is capturing standard output.
|
|
383
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
384
|
+
try {
|
|
385
|
+
return await dispatch(argv)
|
|
386
|
+
} catch (error) {
|
|
387
|
+
console.error(error instanceof Error ? error.message : String(error))
|
|
388
|
+
|
|
389
|
+
return FAILURE_EXIT_CODE
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
394
|
+
process.exitCode = await run(argv)
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const lane_cli = {
|
|
398
|
+
ALL_FLAG,
|
|
399
|
+
NONE_TOKEN,
|
|
400
|
+
USAGE,
|
|
401
|
+
main,
|
|
402
|
+
parse_issue,
|
|
403
|
+
parse_lane_issue,
|
|
404
|
+
refusal_message,
|
|
405
|
+
run,
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
409
|
+
|
|
410
|
+
export { lane_cli }
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { existsSync, rmSync } from 'node:fs'
|
|
2
|
+
import { git_command } from '#scripts/git/git-command'
|
|
3
|
+
import { git_worktree } from '#scripts/git/git-worktree'
|
|
4
|
+
import { lane_paths } from './lane-paths'
|
|
5
|
+
import { lane_reap } from './lane-reap'
|
|
6
|
+
import { lane_registry, type LaneInfo } from './lane-registry'
|
|
7
|
+
|
|
8
|
+
// Closing a lane: no work tree, no branch, no directory (joshuafolkken/kit#1490).
|
|
9
|
+
//
|
|
10
|
+
// **A lane is closed after a park, a failure or an interruption as readily as after a success**, so
|
|
11
|
+
// every step here is written to run over a subject that is already gone or that still holds
|
|
12
|
+
// uncommitted work. A close that refused either would leave exactly the debris it exists to remove,
|
|
13
|
+
// and the next lane for that issue would then fail on a directory nobody could account for. There
|
|
14
|
+
// is no ledger entry to remove: the lane's seat lived in the `.env` that goes with the work tree.
|
|
15
|
+
|
|
16
|
+
interface LaneTargets {
|
|
17
|
+
directory: string
|
|
18
|
+
branch: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// The lane an issue number names: its registration, when there is one, and the paths a close acts on.
|
|
22
|
+
// Resolved once here so a caller that has to look inside the tree before closing it reads the same
|
|
23
|
+
// directory the close removes (joshuafolkken/kit#2476).
|
|
24
|
+
interface ResolvedLane {
|
|
25
|
+
existing: LaneInfo | undefined
|
|
26
|
+
targets: LaneTargets
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type CloseKind = 'closed' | 'incomplete' | 'none'
|
|
30
|
+
|
|
31
|
+
interface CloseOutcome {
|
|
32
|
+
issue: string
|
|
33
|
+
kind: CloseKind
|
|
34
|
+
left_behind: Array<string>
|
|
35
|
+
// The lane child's processes this close terminated — empty for a child that ended by itself.
|
|
36
|
+
reaped: Array<number>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface SweepOutcome {
|
|
40
|
+
closed: Array<string>
|
|
41
|
+
failed: Array<string>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function ignore_failure(action: () => Promise<string>): Promise<void> {
|
|
45
|
+
try {
|
|
46
|
+
await action()
|
|
47
|
+
} catch {
|
|
48
|
+
// Expected on every path this command was written for: a work tree git no longer registers, a
|
|
49
|
+
// branch already deleted, a prune with nothing to prune. What matters is that the next step
|
|
50
|
+
// still runs — the outcome is judged by what is left on disk, not by these exit codes.
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Without a registration — the state a crash between `worktree add` and the `.env` write leaves —
|
|
55
|
+
// the issue number still implies both paths, which is what makes such a lane closable at all.
|
|
56
|
+
function lane_targets(root: string, issue: string, lane: LaneInfo | undefined): LaneTargets {
|
|
57
|
+
return {
|
|
58
|
+
directory: lane?.directory ?? lane_paths.lane_directory(root, issue),
|
|
59
|
+
branch: lane?.branch ?? lane_paths.lane_branch(issue),
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// A directory that will not go — a permission, a busy mount — is left for the check below to report
|
|
64
|
+
// rather than thrown out of the middle of the removal, where it would abandon the steps after it
|
|
65
|
+
// and, inside a sweep, every lane after this one.
|
|
66
|
+
function remove_directory(directory: string): void {
|
|
67
|
+
try {
|
|
68
|
+
rmSync(directory, { force: true, recursive: true })
|
|
69
|
+
} catch {
|
|
70
|
+
// Reported by `residue`, which is what judges the close.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// **The order is load bearing.** `worktree remove` unregisters and deletes in one step; the explicit
|
|
75
|
+
// removal after it covers a tree git had already forgotten; `prune` covers the opposite case, a
|
|
76
|
+
// registration whose directory someone deleted by hand; and the branch goes last, because git
|
|
77
|
+
// refuses to delete one that is still checked out in a registered work tree.
|
|
78
|
+
async function remove_lane(targets: LaneTargets): Promise<void> {
|
|
79
|
+
await ignore_failure(async () => await git_worktree.worktree_remove(targets.directory))
|
|
80
|
+
remove_directory(targets.directory)
|
|
81
|
+
await ignore_failure(async () => await git_worktree.worktree_prune())
|
|
82
|
+
await ignore_failure(async () => await git_worktree.branch_delete(targets.branch))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* What the removal left behind — the empty list is what "closed" means.
|
|
87
|
+
*
|
|
88
|
+
* **The verdict comes from the end state, not from the exit codes above**, every one of which is
|
|
89
|
+
* expected to fail on some legitimate path. The branch is the case that matters: one git refused to
|
|
90
|
+
* delete survives, the next `lane:open` for that issue dies on `worktree add` with git's own message
|
|
91
|
+
* instead of this command's, and a close that had reported success said nothing about it.
|
|
92
|
+
*/
|
|
93
|
+
async function residue(targets: LaneTargets): Promise<Array<string>> {
|
|
94
|
+
const left: Array<string> = []
|
|
95
|
+
|
|
96
|
+
if (existsSync(targets.directory)) left.push(targets.directory)
|
|
97
|
+
if (await git_command.branch_exists(targets.branch)) left.push(targets.branch)
|
|
98
|
+
|
|
99
|
+
return left
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function close_kind(did_exist: boolean, left_behind: ReadonlyArray<string>): CloseKind {
|
|
103
|
+
if (left_behind.length > 0) return 'incomplete'
|
|
104
|
+
|
|
105
|
+
return did_exist ? 'closed' : 'none'
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// The main work tree's root, not this one's — the same reading `list_lanes` uses, so the fallback
|
|
109
|
+
// directory an unregistered lane is closed by is the one `lane:open` would have created
|
|
110
|
+
// (joshuafolkken/kit#1497). Derived here from the current work tree, a close run inside a lane
|
|
111
|
+
// reports `none` over a directory that is still on disk.
|
|
112
|
+
async function lane_root_directory(): Promise<string> {
|
|
113
|
+
return lane_paths.lane_root(await lane_registry.main_repository_root())
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Close the lane for `issue`. `none` means there was nothing there, which is not a failure: a caller
|
|
118
|
+
* cleaning up after an interruption cannot know whether the lane was ever opened. `incomplete` means
|
|
119
|
+
* something survived the removal, and `left_behind` names it.
|
|
120
|
+
*/
|
|
121
|
+
async function resolve_lane(issue: string): Promise<ResolvedLane> {
|
|
122
|
+
const root = await lane_root_directory()
|
|
123
|
+
const existing = lane_registry.find_lane(await lane_registry.list_lanes(), issue)
|
|
124
|
+
|
|
125
|
+
return { existing, targets: lane_targets(root, issue, existing) }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function close_lane(issue: string): Promise<CloseOutcome> {
|
|
129
|
+
const { existing, targets } = await resolve_lane(issue)
|
|
130
|
+
const did_exist = existing !== undefined || existsSync(targets.directory)
|
|
131
|
+
// Before the removal, not after: a child still running in the tree would keep writing into a
|
|
132
|
+
// directory being deleted, and a process outliving its lane is the half-discarded state
|
|
133
|
+
// joshuafolkken/kit#2421 found — the work tree gone, the child still answering `alive`.
|
|
134
|
+
const reaped = lane_reap.reap_child(issue)
|
|
135
|
+
|
|
136
|
+
await remove_lane(targets)
|
|
137
|
+
|
|
138
|
+
const left_behind = await residue(targets)
|
|
139
|
+
|
|
140
|
+
return { issue, kind: close_kind(did_exist, left_behind), left_behind, reaped }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// A lane that could not be closed is recorded rather than thrown: a sweep has to attempt every lane,
|
|
144
|
+
// and the caller has to be told which ones are still there.
|
|
145
|
+
async function try_close(issue: string): Promise<boolean> {
|
|
146
|
+
try {
|
|
147
|
+
const outcome = await close_lane(issue)
|
|
148
|
+
|
|
149
|
+
return outcome.kind !== 'incomplete'
|
|
150
|
+
} catch {
|
|
151
|
+
return false
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Sequential on purpose: two `git worktree` writes at once contend for the same registration
|
|
156
|
+
// directory, and the whole point of the command is that nothing is left half-removed.
|
|
157
|
+
async function close_each(issues: ReadonlyArray<string>): Promise<SweepOutcome> {
|
|
158
|
+
const sweep: SweepOutcome = { closed: [], failed: [] }
|
|
159
|
+
|
|
160
|
+
for (const issue of issues) {
|
|
161
|
+
const bucket = (await try_close(issue)) ? sweep.closed : sweep.failed
|
|
162
|
+
|
|
163
|
+
bucket.push(issue)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return sweep
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Close every lane whose work tree is no longer on disk — the route out of an interruption that took
|
|
171
|
+
* the directory with it and left git's registration behind.
|
|
172
|
+
*/
|
|
173
|
+
async function prune_lanes(): Promise<SweepOutcome> {
|
|
174
|
+
const lanes = await lane_registry.list_lanes()
|
|
175
|
+
const stranded = lanes.filter((lane) => lane.is_stranded)
|
|
176
|
+
|
|
177
|
+
return await close_each(stranded.map((lane) => lane.issue))
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function close_all_lanes(): Promise<SweepOutcome> {
|
|
181
|
+
const lanes = await lane_registry.list_lanes()
|
|
182
|
+
|
|
183
|
+
return await close_each(lanes.map((lane) => lane.issue))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const lane_close = {
|
|
187
|
+
close_all_lanes,
|
|
188
|
+
close_lane,
|
|
189
|
+
lane_root_directory,
|
|
190
|
+
lane_targets,
|
|
191
|
+
prune_lanes,
|
|
192
|
+
remove_lane,
|
|
193
|
+
resolve_lane,
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export type { CloseKind, CloseOutcome, ResolvedLane, SweepOutcome }
|
|
197
|
+
export { lane_close }
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
2
|
+
import type { LaneInfo } from './lane-registry'
|
|
3
|
+
|
|
4
|
+
const LOG_PREFIX = 'josh-lane-dispatch-'
|
|
5
|
+
const LOG_SUFFIX = '.log'
|
|
6
|
+
|
|
7
|
+
function default_log_path(lane: LaneInfo): string {
|
|
8
|
+
return stamp_file.stamp_path(`${LOG_PREFIX}${lane.issue}-`, lane.directory, LOG_SUFFIX)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const lane_dispatch_log = { default_log_path }
|
|
12
|
+
|
|
13
|
+
export { lane_dispatch_log }
|