@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,71 @@
|
|
|
1
|
+
import { epic_cli_argv, ISSUE_NUMBER_PATTERN } from './epic-cli-argv'
|
|
2
|
+
|
|
3
|
+
// `josh epic --remove <E> <M> <N> …`'s argument rules (joshuafolkken/kit#1712).
|
|
4
|
+
//
|
|
5
|
+
// Its own module rather than a fourth parser inside `epic-cli.ts`, which sits at its line ceiling —
|
|
6
|
+
// and because the rules read as one thing: the arguments after the epic are a **path**, which is the
|
|
7
|
+
// one place this command departs from every other form's bare set of child numbers.
|
|
8
|
+
|
|
9
|
+
const REMOVE_FLAG = '--remove'
|
|
10
|
+
const DECISION_FLAG = '--decision-file'
|
|
11
|
+
// `--remove` takes no positioning flag: there is nothing for a removal to be relative to, and the
|
|
12
|
+
// path itself says which orders go.
|
|
13
|
+
const REMOVE_VALUE_FLAGS: ReadonlySet<string> = new Set([DECISION_FLAG])
|
|
14
|
+
const REMOVE_KNOWN_FLAGS: ReadonlySet<string> = new Set([REMOVE_FLAG, DECISION_FLAG])
|
|
15
|
+
// The shortest path that names an order at all: `<M> <N>`.
|
|
16
|
+
const MINIMUM_PATH_LENGTH = 2
|
|
17
|
+
|
|
18
|
+
interface RemoveArguments {
|
|
19
|
+
epic_number: number
|
|
20
|
+
path: Array<number>
|
|
21
|
+
decision_path?: string | undefined
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Whether the invocation deletes a declared order rather than creating, promoting or inserting.
|
|
25
|
+
function is_removal(argv: ReadonlyArray<string>): boolean {
|
|
26
|
+
return argv.includes(REMOVE_FLAG)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// **Not deduplicated, and a non-number refuses the whole path** — unlike a child list, which is a
|
|
30
|
+
// set. The path is a sequence, so its order and its repeats are what the caller said: dropping a
|
|
31
|
+
// repeat would silently delete a different set of orders than the one typed, and skipping an
|
|
32
|
+
// unparsable argument would shift every pair after it.
|
|
33
|
+
function to_path_numbers(raw_path: ReadonlyArray<string>): Array<number> | undefined {
|
|
34
|
+
if (raw_path.some((raw) => !ISSUE_NUMBER_PATTERN.test(raw))) return undefined
|
|
35
|
+
|
|
36
|
+
return raw_path.length < MINIMUM_PATH_LENGTH ? undefined : raw_path.map(Number)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// A flag that makes the whole invocation unreadable, whatever the positional arguments say.
|
|
40
|
+
function has_flag_refusal(argv: ReadonlyArray<string>): boolean {
|
|
41
|
+
return (
|
|
42
|
+
epic_cli_argv.has_unknown_flag(argv, REMOVE_KNOWN_FLAGS) ||
|
|
43
|
+
epic_cli_argv.is_value_unusable(argv, DECISION_FLAG)
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function read_subject(
|
|
48
|
+
argv: ReadonlyArray<string>,
|
|
49
|
+
): { epic_number: number; path: Array<number> } | undefined {
|
|
50
|
+
const [raw_epic, ...raw_path] = epic_cli_argv.to_positional_arguments(argv, REMOVE_VALUE_FLAGS)
|
|
51
|
+
if (raw_epic === undefined || !ISSUE_NUMBER_PATTERN.test(raw_epic)) return undefined
|
|
52
|
+
const path = to_path_numbers(raw_path)
|
|
53
|
+
|
|
54
|
+
return path === undefined ? undefined : { epic_number: Number(raw_epic), path }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function parse_remove_arguments(argv: ReadonlyArray<string>): RemoveArguments | undefined {
|
|
58
|
+
if (has_flag_refusal(argv)) return undefined
|
|
59
|
+
const subject = read_subject(argv)
|
|
60
|
+
if (subject === undefined) return undefined
|
|
61
|
+
|
|
62
|
+
return { ...subject, decision_path: epic_cli_argv.read_flag_value(argv, DECISION_FLAG) }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const epic_cli_remove = {
|
|
66
|
+
is_removal,
|
|
67
|
+
parse_remove_arguments,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { epic_cli_remove, REMOVE_FLAG }
|
|
71
|
+
export type { RemoveArguments }
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import type { InsertKind, InsertPosition } from '../scripts/git/git-epic-chains'
|
|
2
|
+
import { git_epic_parse, type ExternalChild } from '../scripts/git/git-epic-parse'
|
|
3
|
+
import { cli_body } from '../scripts/josh/cli-body'
|
|
4
|
+
import { epic_cli_argv, ISSUE_NUMBER_PATTERN } from './epic-cli-argv'
|
|
5
|
+
import { epic_cli_remove } from './epic-cli-remove'
|
|
6
|
+
|
|
7
|
+
// Parsing lives apart from the entry point so the argument rules can be asserted without spawning a
|
|
8
|
+
// process or reaching GitHub. The entry point is then a thin shell around these two functions.
|
|
9
|
+
|
|
10
|
+
const ORDERED_FLAG = '--ordered'
|
|
11
|
+
const RATIONALE_FLAG = '--rationale-file'
|
|
12
|
+
const ORIGIN_FLAG = '--origin'
|
|
13
|
+
const PROMOTE_FLAG = '--promote'
|
|
14
|
+
const ADD_FLAG = '--add'
|
|
15
|
+
// `--reconcile <E>`: bring the epic's declaration and its recorded relations back into agreement
|
|
16
|
+
// (joshuafolkken/kit#2235). It takes no value flags — the epic number is the whole subject.
|
|
17
|
+
const RECONCILE_FLAG = '--reconcile'
|
|
18
|
+
const BEFORE_FLAG = '--before'
|
|
19
|
+
const AFTER_FLAG = '--after'
|
|
20
|
+
// The same two places with the declaration withheld: move the task-list row and write neither the
|
|
21
|
+
// dependency declaration nor the `blocked-by` relation (joshuafolkken/kit#1738). They exist because
|
|
22
|
+
// `epic:next` offers children in task-list order, so "no dependency, but run this one first" had no
|
|
23
|
+
// spelling at all — only a false dependency, or a row nobody would reach.
|
|
24
|
+
const ORDER_BEFORE_FLAG = '--order-before'
|
|
25
|
+
const ORDER_AFTER_FLAG = '--order-after'
|
|
26
|
+
// The decision record for an insertion, read the same way `--rationale-file` is read for a creation:
|
|
27
|
+
// from a file, or from stdin as `-`. The text is a judgement, so the caller writes it; what the command
|
|
28
|
+
// contributes is placing it in the epic's `## Decisions` and on each child (joshuafolkken/kit#1350).
|
|
29
|
+
const DECISION_FLAG = '--decision-file'
|
|
30
|
+
// Which flags consume the argument after them — per parser, for the reason `epic-cli-argv.ts` gives.
|
|
31
|
+
const VALUE_FLAGS: ReadonlySet<string> = new Set([RATIONALE_FLAG, ORIGIN_FLAG])
|
|
32
|
+
const ADD_VALUE_FLAGS: ReadonlySet<string> = new Set([
|
|
33
|
+
BEFORE_FLAG,
|
|
34
|
+
AFTER_FLAG,
|
|
35
|
+
ORDER_BEFORE_FLAG,
|
|
36
|
+
ORDER_AFTER_FLAG,
|
|
37
|
+
DECISION_FLAG,
|
|
38
|
+
])
|
|
39
|
+
const ADD_KNOWN_FLAGS: ReadonlySet<string> = new Set([
|
|
40
|
+
ADD_FLAG,
|
|
41
|
+
BEFORE_FLAG,
|
|
42
|
+
AFTER_FLAG,
|
|
43
|
+
ORDER_BEFORE_FLAG,
|
|
44
|
+
ORDER_AFTER_FLAG,
|
|
45
|
+
DECISION_FLAG,
|
|
46
|
+
])
|
|
47
|
+
|
|
48
|
+
const { count_flag, is_value_unusable, read_flag_value } = epic_cli_argv
|
|
49
|
+
|
|
50
|
+
interface CreateArguments {
|
|
51
|
+
title: string
|
|
52
|
+
children: Array<number>
|
|
53
|
+
is_ordered: boolean
|
|
54
|
+
rationale_path?: string | undefined
|
|
55
|
+
origin?: string | undefined
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// `--promote <N> <N1> <N2> …`: the issue to promote, then its children. No title — the issue already
|
|
59
|
+
// has one, and the discussion in it is usually the split rationale (joshuafolkken/kit#865).
|
|
60
|
+
interface PromoteArguments {
|
|
61
|
+
epic_number: number
|
|
62
|
+
children: Array<number>
|
|
63
|
+
is_ordered: boolean
|
|
64
|
+
rationale_path?: string | undefined
|
|
65
|
+
origin?: string | undefined
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function to_positional_arguments(
|
|
69
|
+
argv: ReadonlyArray<string>,
|
|
70
|
+
value_flags: ReadonlySet<string> = VALUE_FLAGS,
|
|
71
|
+
): Array<string> {
|
|
72
|
+
return epic_cli_argv.to_positional_arguments(argv, value_flags)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Deduplicated because a repeated number would render a duplicate task-list row, and with
|
|
76
|
+
// `--ordered` would ask GitHub to make an issue block itself.
|
|
77
|
+
function to_child_numbers(raw_children: ReadonlyArray<string>): Array<number> {
|
|
78
|
+
const numbers = raw_children
|
|
79
|
+
.filter((raw) => ISSUE_NUMBER_PATTERN.test(raw))
|
|
80
|
+
.map(Number)
|
|
81
|
+
.filter((value) => Number.isSafeInteger(value))
|
|
82
|
+
|
|
83
|
+
return [...new Set(numbers)]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// The title comes first so the children can stay a bare list of numbers, which is how they are
|
|
87
|
+
// written down when the split is made.
|
|
88
|
+
function parse_create_arguments(argv: ReadonlyArray<string>): CreateArguments | undefined {
|
|
89
|
+
const [title, ...raw_children] = to_positional_arguments(argv)
|
|
90
|
+
if (title === undefined || title.length === 0) return undefined
|
|
91
|
+
|
|
92
|
+
const children = to_child_numbers(raw_children)
|
|
93
|
+
if (children.length === 0) return undefined
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
title,
|
|
97
|
+
children,
|
|
98
|
+
is_ordered: argv.includes(ORDERED_FLAG),
|
|
99
|
+
rationale_path: read_flag_value(argv, RATIONALE_FLAG),
|
|
100
|
+
origin: read_flag_value(argv, ORIGIN_FLAG),
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Whether the invocation is a promotion rather than a creation.
|
|
105
|
+
function is_promotion(argv: ReadonlyArray<string>): boolean {
|
|
106
|
+
return argv.includes(PROMOTE_FLAG)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Whether the invocation reconciles an epic rather than creating, promoting or editing one.
|
|
110
|
+
function is_reconciliation(argv: ReadonlyArray<string>): boolean {
|
|
111
|
+
return argv.includes(RECONCILE_FLAG)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface ReconcileArguments {
|
|
115
|
+
epic_number: number
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// The epic to reconcile. The number after `--reconcile` is the only subject; there are no children
|
|
119
|
+
// and no position — the repair reads what the epic already records rather than being told an order.
|
|
120
|
+
function parse_reconcile_arguments(argv: ReadonlyArray<string>): ReconcileArguments | undefined {
|
|
121
|
+
const [raw_epic] = to_positional_arguments(argv)
|
|
122
|
+
if (raw_epic === undefined || !ISSUE_NUMBER_PATTERN.test(raw_epic)) return undefined
|
|
123
|
+
|
|
124
|
+
return { epic_number: Number(raw_epic) }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// The promoted issue and its children. The number after `--promote` is the epic; everything else
|
|
128
|
+
// positional is a child. Refused when the epic would also be listed as its own child, which would
|
|
129
|
+
// have it block itself under `--ordered`.
|
|
130
|
+
function parse_promote_arguments(argv: ReadonlyArray<string>): PromoteArguments | undefined {
|
|
131
|
+
const [raw_epic, ...raw_children] = to_positional_arguments(argv)
|
|
132
|
+
if (raw_epic === undefined || !ISSUE_NUMBER_PATTERN.test(raw_epic)) return undefined
|
|
133
|
+
const epic_number = Number(raw_epic)
|
|
134
|
+
const children = to_child_numbers(raw_children).filter((child) => child !== epic_number)
|
|
135
|
+
if (children.length === 0) return undefined
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
epic_number,
|
|
139
|
+
children,
|
|
140
|
+
is_ordered: argv.includes(ORDERED_FLAG),
|
|
141
|
+
rationale_path: read_flag_value(argv, RATIONALE_FLAG),
|
|
142
|
+
origin: read_flag_value(argv, ORIGIN_FLAG),
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// `--add <E> <N...> [--before <M> | --after <M> | --order-before <M> | --order-after <M>]`: the epic
|
|
147
|
+
// to insert into, then the children. The epic comes first for the same reason it does under
|
|
148
|
+
// `--promote`, so the children stay a bare list of numbers (joshuafolkken/kit#890).
|
|
149
|
+
interface AddArguments {
|
|
150
|
+
epic_number: number
|
|
151
|
+
children: Array<number>
|
|
152
|
+
position?: InsertPosition | undefined
|
|
153
|
+
// `--order-before` / `--order-after` rather than `--before` / `--after`: the row moves and nothing
|
|
154
|
+
// else is written (joshuafolkken/kit#1738).
|
|
155
|
+
is_order_only?: boolean | undefined
|
|
156
|
+
decision_path?: string | undefined
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Whether the invocation inserts into an existing epic rather than creating or promoting one.
|
|
160
|
+
function is_addition(argv: ReadonlyArray<string>): boolean {
|
|
161
|
+
return argv.includes(ADD_FLAG)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// The outcome of reading a positioning flag: the position, nothing, or a refusal. One shape for all
|
|
165
|
+
// three so the caller branches on a field rather than on a value's type. `is_order_only` rides on the
|
|
166
|
+
// same value because one flag decides both halves — where the row goes, and whether a dependency is
|
|
167
|
+
// written behind it (joshuafolkken/kit#1738).
|
|
168
|
+
interface PositionOutcome {
|
|
169
|
+
position?: InsertPosition
|
|
170
|
+
is_order_only?: boolean
|
|
171
|
+
is_refused: boolean
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const NO_POSITION: PositionOutcome = { is_refused: false }
|
|
175
|
+
const REFUSED_POSITION: PositionOutcome = { is_refused: true }
|
|
176
|
+
|
|
177
|
+
// The four positioning flags as one table: the place each one names, and whether a dependency is
|
|
178
|
+
// written behind the row it moves. **One table rather than two branches** (joshuafolkken/kit#1738) —
|
|
179
|
+
// `--order-before` asks the same placement question `--before` does, so a second parsing path could
|
|
180
|
+
// come to disagree with this one about what a repeated flag or a non-numeric target means.
|
|
181
|
+
interface PositionFlag {
|
|
182
|
+
flag: string
|
|
183
|
+
kind: InsertKind
|
|
184
|
+
is_order_only: boolean
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const POSITION_FLAGS: ReadonlyArray<PositionFlag> = [
|
|
188
|
+
{ flag: BEFORE_FLAG, kind: 'before', is_order_only: false },
|
|
189
|
+
{ flag: AFTER_FLAG, kind: 'after', is_order_only: false },
|
|
190
|
+
{ flag: ORDER_BEFORE_FLAG, kind: 'before', is_order_only: true },
|
|
191
|
+
{ flag: ORDER_AFTER_FLAG, kind: 'after', is_order_only: true },
|
|
192
|
+
]
|
|
193
|
+
|
|
194
|
+
// More than one positioning flag names more than one place, whether they are the same flag twice, one
|
|
195
|
+
// of each direction, or a dependency-writing flag beside an order-only one. `read_flag_value` would
|
|
196
|
+
// answer with the first, which is a silent choice rather than a refusal — and here the silent choice
|
|
197
|
+
// would decide whether a `blocked-by` is written at all.
|
|
198
|
+
function is_position_ambiguous(argv: ReadonlyArray<string>): boolean {
|
|
199
|
+
return POSITION_FLAGS.reduce((total, entry) => total + count_flag(argv, entry.flag), 0) > 1
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
interface PositionTarget extends PositionFlag {
|
|
203
|
+
raw: string
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function to_position_target(
|
|
207
|
+
argv: ReadonlyArray<string>,
|
|
208
|
+
entry: PositionFlag,
|
|
209
|
+
): PositionTarget | undefined {
|
|
210
|
+
const raw = read_flag_value(argv, entry.flag)
|
|
211
|
+
|
|
212
|
+
return raw === undefined ? undefined : { ...entry, raw }
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function read_position_target(argv: ReadonlyArray<string>): PositionTarget | undefined {
|
|
216
|
+
if (is_position_ambiguous(argv)) return undefined
|
|
217
|
+
|
|
218
|
+
return POSITION_FLAGS.map((entry) => to_position_target(argv, entry)).find(
|
|
219
|
+
(found) => found !== undefined,
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// A target that is not an issue number is refused for the same reason two flags are: guessing would
|
|
224
|
+
// insert somewhere.
|
|
225
|
+
function parse_position(argv: ReadonlyArray<string>): PositionOutcome {
|
|
226
|
+
const has_flag = POSITION_FLAGS.some((entry) => argv.includes(entry.flag))
|
|
227
|
+
const target = read_position_target(argv)
|
|
228
|
+
if (target === undefined) return has_flag ? REFUSED_POSITION : NO_POSITION
|
|
229
|
+
if (!ISSUE_NUMBER_PATTERN.test(target.raw)) return REFUSED_POSITION
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
position: { kind: target.kind, target: Number(target.raw) },
|
|
233
|
+
is_order_only: target.is_order_only,
|
|
234
|
+
is_refused: false,
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function has_unknown_flag(argv: ReadonlyArray<string>): boolean {
|
|
239
|
+
return epic_cli_argv.has_unknown_flag(argv, ADD_KNOWN_FLAGS)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Whether *this* is why the insertion could not be read, so the refusal can say so. Without it the
|
|
243
|
+
// caller prints the generic requirements line, and a shell that expanded `--decision-file $REC` to
|
|
244
|
+
// nothing is answered with "an epic number and at least one child issue number are required" — advice
|
|
245
|
+
// about the part the person got right.
|
|
246
|
+
function is_decision_path_unusable(argv: ReadonlyArray<string>): boolean {
|
|
247
|
+
return is_value_unusable(argv, DECISION_FLAG)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function read_add_subject(
|
|
251
|
+
argv: ReadonlyArray<string>,
|
|
252
|
+
): { epic_number: number; children: Array<number> } | undefined {
|
|
253
|
+
const [raw_epic, ...raw_children] = to_positional_arguments(argv, ADD_VALUE_FLAGS)
|
|
254
|
+
if (raw_epic === undefined || !ISSUE_NUMBER_PATTERN.test(raw_epic)) return undefined
|
|
255
|
+
const epic_number = Number(raw_epic)
|
|
256
|
+
const children = to_child_numbers(raw_children).filter((child) => child !== epic_number)
|
|
257
|
+
|
|
258
|
+
return children.length === 0 ? undefined : { epic_number, children }
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function parse_add_arguments(argv: ReadonlyArray<string>): AddArguments | undefined {
|
|
262
|
+
if (has_unknown_flag(argv) || is_decision_path_unusable(argv)) return undefined
|
|
263
|
+
const subject = read_add_subject(argv)
|
|
264
|
+
if (subject === undefined) return undefined
|
|
265
|
+
const outcome = parse_position(argv)
|
|
266
|
+
if (outcome.is_refused) return undefined
|
|
267
|
+
|
|
268
|
+
return {
|
|
269
|
+
...subject,
|
|
270
|
+
position: outcome.position,
|
|
271
|
+
is_order_only: outcome.is_order_only,
|
|
272
|
+
decision_path: read_flag_value(argv, DECISION_FLAG),
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// The one refusal `--add` has to explain rather than merely report. `into owner/repo#N` is a legal
|
|
277
|
+
// thing for a person to type, and this command cannot serve it: it reads and edits issues in the
|
|
278
|
+
// repository it is run from. Falling through to the usage line would read as "that form does not
|
|
279
|
+
// exist" when what it means is "run it in the other checkout" (joshuafolkken/kit#985).
|
|
280
|
+
interface CrossRepoAddTarget {
|
|
281
|
+
epic: ExternalChild
|
|
282
|
+
local: AddArguments
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// The same invocation with the cross-repository target replaced by its bare number. Answering only
|
|
286
|
+
// when *that* parses is what keeps the suggestion honest: an invocation wrong in some other way — a
|
|
287
|
+
// mistyped positioning flag, no children, a `--before` naming two places — is not a repository
|
|
288
|
+
// problem, and
|
|
289
|
+
// a suggestion built from it would drop or mangle what the person typed.
|
|
290
|
+
function find_cross_repo_add_target(argv: ReadonlyArray<string>): CrossRepoAddTarget | undefined {
|
|
291
|
+
const [raw_epic] = to_positional_arguments(argv, ADD_VALUE_FLAGS)
|
|
292
|
+
if (raw_epic === undefined) return undefined
|
|
293
|
+
const epic = git_epic_parse.parse_external_reference(raw_epic)
|
|
294
|
+
if (epic === undefined) return undefined
|
|
295
|
+
|
|
296
|
+
const local = parse_add_arguments(
|
|
297
|
+
argv.map((argument) => (argument === raw_epic ? String(epic.number) : argument)),
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
return local === undefined ? undefined : { epic, local }
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Rebuilt from the parsed values rather than echoed from `argv`, so the suggested command is exactly
|
|
304
|
+
// what the other checkout would read — and carries the position, which is the one part of the
|
|
305
|
+
// instruction the epic itself does not record.
|
|
306
|
+
function format_add_arguments(local: AddArguments): string {
|
|
307
|
+
const { position } = local
|
|
308
|
+
// The order-only prefix rides along, since it is what decides whether the other checkout writes a
|
|
309
|
+
// dependency — a suggestion that dropped it would be a different instruction (joshuafolkken/kit#1738).
|
|
310
|
+
const prefix = local.is_order_only === true ? '--order-' : '--'
|
|
311
|
+
const suffix =
|
|
312
|
+
position === undefined ? '' : ` ${prefix}${position.kind} ${String(position.target)}`
|
|
313
|
+
|
|
314
|
+
return `${[local.epic_number, ...local.children].map(String).join(' ')}${suffix}`
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// **`--decision-file` is named rather than relayed** (joshuafolkken/kit#1350). The suggestion is a
|
|
318
|
+
// command to run in a *different* checkout, and the path was resolved against this one: a relative path
|
|
319
|
+
// does not exist there, `-` cannot be re-read from a consumed stdin, and an unquoted path with a space
|
|
320
|
+
// would break the line the person copies. So the flag is asked for again instead of pasted in wrong.
|
|
321
|
+
function format_decision_note(local: AddArguments): Array<string> {
|
|
322
|
+
if (local.decision_path === undefined) return []
|
|
323
|
+
|
|
324
|
+
return [
|
|
325
|
+
` The decision record is not carried over — pass \`${DECISION_FLAG}\` there with a path that checkout can read.`,
|
|
326
|
+
]
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// A fully-qualified reference to *this* repository is the same instruction spelled longer, not a
|
|
330
|
+
// cross-repository one — and `into owner/repo#N` is exactly how the suffix is documented, so a run
|
|
331
|
+
// inside that repository would otherwise be refused and told to go to the checkout it is already in
|
|
332
|
+
// (joshuafolkken/kit#985). An unreadable current repository resolves to a refusal rather than to a
|
|
333
|
+
// write: refusing costs one command, and guessing wrong writes into the wrong epic.
|
|
334
|
+
function resolve_local_add(
|
|
335
|
+
found: CrossRepoAddTarget,
|
|
336
|
+
current_repo: string | undefined,
|
|
337
|
+
): AddArguments | undefined {
|
|
338
|
+
return current_repo === found.epic.repo ? found.local : undefined
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// What to type instead. `josh doctor` prints the checkout for each repository, which is the part a
|
|
342
|
+
// run cannot guess.
|
|
343
|
+
function format_cross_repo_refusal(found: CrossRepoAddTarget): string {
|
|
344
|
+
const reference = `${found.epic.repo}#${String(found.epic.number)}`
|
|
345
|
+
|
|
346
|
+
return [
|
|
347
|
+
`✖ ${reference} is an epic in another repository; this command reads and writes issues in the repository it runs from.`,
|
|
348
|
+
` Run \`pnpm josh epic --add ${format_add_arguments(found.local)}\` in that repository's checkout (\`pnpm josh doctor\` prints where each one is).`,
|
|
349
|
+
...format_decision_note(found.local),
|
|
350
|
+
].join('\n')
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function parse_check_argument(argv: ReadonlyArray<string>): number | undefined {
|
|
354
|
+
const [raw] = to_positional_arguments(argv)
|
|
355
|
+
if (raw === undefined || !ISSUE_NUMBER_PATTERN.test(raw)) return undefined
|
|
356
|
+
|
|
357
|
+
return Number(raw)
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// `-` reads stdin, matching `gh issue create --body-file -`. The reader is `cli_body`'s, shared with
|
|
361
|
+
// `josh notify --body-file` and `josh followup --notify-message-file` rather than copied per entry
|
|
362
|
+
// point (joshuafolkken/kit#1198), so the stdin form cannot come to mean one thing here and something
|
|
363
|
+
// else there.
|
|
364
|
+
const { read_file_or_stdin } = cli_body
|
|
365
|
+
|
|
366
|
+
// An omitted path yields an empty rationale, which the body builder replaces with a visible
|
|
367
|
+
// placeholder rather than a blank section.
|
|
368
|
+
function read_rationale(rationale_path: string | undefined): string {
|
|
369
|
+
return rationale_path === undefined ? '' : read_file_or_stdin(rationale_path)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// `undefined` rather than `''` for an omitted path: an insertion that records no decision is the
|
|
373
|
+
// ordinary case, and an empty string is a record that says nothing — which `epic --add` refuses
|
|
374
|
+
// (joshuafolkken/kit#1350).
|
|
375
|
+
function read_decision(decision_path: string | undefined): string | undefined {
|
|
376
|
+
return decision_path === undefined ? undefined : read_file_or_stdin(decision_path)
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const epic_cli = {
|
|
380
|
+
is_promotion,
|
|
381
|
+
is_addition,
|
|
382
|
+
is_reconciliation,
|
|
383
|
+
...epic_cli_remove,
|
|
384
|
+
find_cross_repo_add_target,
|
|
385
|
+
is_decision_path_unusable,
|
|
386
|
+
resolve_local_add,
|
|
387
|
+
format_cross_repo_refusal,
|
|
388
|
+
parse_add_arguments,
|
|
389
|
+
parse_create_arguments,
|
|
390
|
+
parse_promote_arguments,
|
|
391
|
+
parse_reconcile_arguments,
|
|
392
|
+
parse_check_argument,
|
|
393
|
+
read_decision,
|
|
394
|
+
read_rationale,
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export {
|
|
398
|
+
epic_cli,
|
|
399
|
+
ADD_FLAG,
|
|
400
|
+
AFTER_FLAG,
|
|
401
|
+
BEFORE_FLAG,
|
|
402
|
+
DECISION_FLAG,
|
|
403
|
+
ORDER_AFTER_FLAG,
|
|
404
|
+
ORDER_BEFORE_FLAG,
|
|
405
|
+
ORDERED_FLAG,
|
|
406
|
+
ORIGIN_FLAG,
|
|
407
|
+
PROMOTE_FLAG,
|
|
408
|
+
RATIONALE_FLAG,
|
|
409
|
+
RECONCILE_FLAG,
|
|
410
|
+
}
|
|
411
|
+
export { REMOVE_FLAG } from './epic-cli-remove'
|
|
412
|
+
export type { AddArguments, CreateArguments, CrossRepoAddTarget, PromoteArguments }
|
|
413
|
+
export type { RemoveArguments } from './epic-cli-remove'
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Create an epic Issue that satisfies every requirement the auto-close and the order warning read.
|
|
4
|
+
*
|
|
5
|
+
* Usage: tsx scripts-ai/epic.ts "<title>" <N1> <N2> ... [--ordered] [--rationale-file <path|->]
|
|
6
|
+
* [--origin <owner/repo#N>]
|
|
7
|
+
* tsx scripts-ai/epic.ts --promote <N> <N1> <N2> ... [same flags]
|
|
8
|
+
* tsx scripts-ai/epic.ts --add <E> <N1> <N2> ... [--before <M> | --after <M>]
|
|
9
|
+
* [--decision-file <path|->]
|
|
10
|
+
* tsx scripts-ai/epic.ts --remove <E> <M> <N> ... [--decision-file <path|->]
|
|
11
|
+
*/
|
|
12
|
+
import { git_epic_add, type AddChildrenInput } from '../scripts/git/git-epic-add'
|
|
13
|
+
import { git_epic_reconcile } from '../scripts/git/git-epic-reconcile'
|
|
14
|
+
import { git_epic_remove } from '../scripts/git/git-epic-remove'
|
|
15
|
+
import { git_epic_run } from '../scripts/git/git-epic-run'
|
|
16
|
+
import { git_gh_command } from '../scripts/git/git-gh-command'
|
|
17
|
+
import { epic_cli, type AddArguments, type CrossRepoAddTarget } from './epic-cli'
|
|
18
|
+
|
|
19
|
+
const ARGV_OFFSET = 2
|
|
20
|
+
const FLAGS = '[--ordered] [--rationale-file <path|->] [--origin <owner/repo#N>]'
|
|
21
|
+
const USAGE = [
|
|
22
|
+
`Usage: josh epic "<title>" <N1> <N2> ... ${FLAGS}`,
|
|
23
|
+
` josh epic --promote <N> <N1> <N2> ... ${FLAGS}`,
|
|
24
|
+
' josh epic --add <E> <N1> <N2> ... [--before <M> | --after <M>] [--decision-file <path|->]',
|
|
25
|
+
' josh epic --add <E> <N1> <N2> ... [--order-before <M> | --order-after <M>] [--decision-file <path|->]',
|
|
26
|
+
' josh epic --remove <E> <M> <N> ... [--decision-file <path|->]',
|
|
27
|
+
' josh epic --reconcile <E>',
|
|
28
|
+
].join('\n')
|
|
29
|
+
const FAILURE_EXIT_CODE = 1
|
|
30
|
+
|
|
31
|
+
async function run_promotion(argv: ReadonlyArray<string>): Promise<number> {
|
|
32
|
+
const parsed = epic_cli.parse_promote_arguments(argv)
|
|
33
|
+
|
|
34
|
+
if (parsed === undefined) {
|
|
35
|
+
console.error(`✖ An issue number and at least one child issue number are required.\n${USAGE}`)
|
|
36
|
+
|
|
37
|
+
return FAILURE_EXIT_CODE
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return await git_epic_run.promote_epic({
|
|
41
|
+
epic_number: parsed.epic_number,
|
|
42
|
+
children: parsed.children,
|
|
43
|
+
rationale: epic_cli.read_rationale(parsed.rationale_path),
|
|
44
|
+
is_ordered: parsed.is_ordered,
|
|
45
|
+
origin: parsed.origin,
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The parsed insertion as the writer's input: the decision file becomes the decision itself, read here
|
|
50
|
+
// rather than inside the writer so nothing reaches GitHub before the file has been found. **Both
|
|
51
|
+
// insertion paths go through it** — the bare form and the `owner/repo#N` one that resolves to this
|
|
52
|
+
// repository — because passing the parsed arguments straight through drops `decision_path` in silence,
|
|
53
|
+
// the field having a different name on either side.
|
|
54
|
+
function to_add_input(parsed: AddArguments): AddChildrenInput {
|
|
55
|
+
return {
|
|
56
|
+
epic_number: parsed.epic_number,
|
|
57
|
+
children: parsed.children,
|
|
58
|
+
position: parsed.position,
|
|
59
|
+
is_order_only: parsed.is_order_only,
|
|
60
|
+
decision: epic_cli.read_decision(parsed.decision_path),
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// A qualified target — `owner/repo#N`. Naming this repository it is the same insertion written
|
|
65
|
+
// longer, so it is performed; naming another it is refused with the command to run there, because
|
|
66
|
+
// this command reads and writes only the repository it runs from (joshuafolkken/kit#985).
|
|
67
|
+
async function run_qualified_addition(found: CrossRepoAddTarget): Promise<number> {
|
|
68
|
+
const local = epic_cli.resolve_local_add(found, await git_gh_command.repo_get_name_with_owner())
|
|
69
|
+
|
|
70
|
+
if (local !== undefined) return await git_epic_add.add_children(to_add_input(local))
|
|
71
|
+
|
|
72
|
+
console.error(epic_cli.format_cross_repo_refusal(found))
|
|
73
|
+
|
|
74
|
+
return FAILURE_EXIT_CODE
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Why an insertion could not be read. A qualified target is answered on its own terms; an unusable
|
|
78
|
+
// `--decision-file` path is named, because the generic line below would send the person after the epic
|
|
79
|
+
// number and the positioning flag when what went missing is the record path a shell expanded to
|
|
80
|
+
// nothing (joshuafolkken/kit#1350); anything else gets the requirements and the usage line.
|
|
81
|
+
async function refuse_addition(argv: ReadonlyArray<string>): Promise<number> {
|
|
82
|
+
const qualified = epic_cli.find_cross_repo_add_target(argv)
|
|
83
|
+
|
|
84
|
+
if (qualified !== undefined) return await run_qualified_addition(qualified)
|
|
85
|
+
|
|
86
|
+
if (epic_cli.is_decision_path_unusable(argv)) {
|
|
87
|
+
console.error(
|
|
88
|
+
`✖ \`--decision-file\` needs exactly one readable path (\`-\` reads stdin); nothing was written.\n${USAGE}`,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
return FAILURE_EXIT_CODE
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.error(
|
|
95
|
+
`✖ An epic number, at least one child issue number, and at most one valid \`--before\` / \`--after\` target are required.\n${USAGE}`,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
return FAILURE_EXIT_CODE
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Insertion into an existing epic. No rationale and no `--ordered`: the epic already declares both,
|
|
102
|
+
// and the insertion is positioned relative to what is there rather than restating it.
|
|
103
|
+
//
|
|
104
|
+
// `--decision-file` is the one text an insertion does carry, and it is a *decision* rather than the
|
|
105
|
+
// epic's rationale: it says why this child was placed here, and it goes to the epic's `## Decisions`
|
|
106
|
+
// and to each child (joshuafolkken/kit#1350).
|
|
107
|
+
async function run_addition(argv: ReadonlyArray<string>): Promise<number> {
|
|
108
|
+
const parsed = epic_cli.parse_add_arguments(argv)
|
|
109
|
+
|
|
110
|
+
if (parsed === undefined) return await refuse_addition(argv)
|
|
111
|
+
|
|
112
|
+
return await git_epic_add.add_children(to_add_input(parsed))
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Deleting a declared order. No position and no `--ordered`: the path itself says which orders go,
|
|
116
|
+
// and what is deleted is only ever what it names — the ends are never reconnected, since a removal
|
|
117
|
+
// that wrote an order would be declaring one nobody stated (joshuafolkken/kit#1712).
|
|
118
|
+
async function run_removal(argv: ReadonlyArray<string>): Promise<number> {
|
|
119
|
+
const parsed = epic_cli.parse_remove_arguments(argv)
|
|
120
|
+
|
|
121
|
+
if (parsed === undefined) {
|
|
122
|
+
console.error(
|
|
123
|
+
`✖ An epic number and at least two child issue numbers are required, and \`--decision-file\` needs exactly one readable path (\`-\` reads stdin).\n${USAGE}`,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
return FAILURE_EXIT_CODE
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return await git_epic_remove.remove_order({
|
|
130
|
+
epic_number: parsed.epic_number,
|
|
131
|
+
path: parsed.path,
|
|
132
|
+
decision: epic_cli.read_decision(parsed.decision_path),
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Reconcile an epic's declaration with its recorded relations. No decision file and no children: the
|
|
137
|
+
// repair reads what the epic already records rather than being told an order (joshuafolkken/kit#2235).
|
|
138
|
+
async function run_reconciliation(argv: ReadonlyArray<string>): Promise<number> {
|
|
139
|
+
const parsed = epic_cli.parse_reconcile_arguments(argv)
|
|
140
|
+
|
|
141
|
+
if (parsed === undefined) {
|
|
142
|
+
console.error(`✖ An epic number is required.\n${USAGE}`)
|
|
143
|
+
|
|
144
|
+
return FAILURE_EXIT_CODE
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return await git_epic_reconcile.reconcile_epic(parsed.epic_number)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async function run_creation(argv: ReadonlyArray<string>): Promise<number> {
|
|
151
|
+
const parsed = epic_cli.parse_create_arguments(argv)
|
|
152
|
+
|
|
153
|
+
if (parsed === undefined) {
|
|
154
|
+
console.error(`✖ A title and at least one child issue number are required.\n${USAGE}`)
|
|
155
|
+
|
|
156
|
+
return FAILURE_EXIT_CODE
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return await git_epic_run.create_epic({
|
|
160
|
+
title: parsed.title,
|
|
161
|
+
children: parsed.children,
|
|
162
|
+
rationale: epic_cli.read_rationale(parsed.rationale_path),
|
|
163
|
+
is_ordered: parsed.is_ordered,
|
|
164
|
+
origin: parsed.origin,
|
|
165
|
+
})
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// `--add` is checked before `--promote`: both name an existing issue first, and only the flag
|
|
169
|
+
// distinguishes "insert into this epic" from "turn this issue into one".
|
|
170
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
171
|
+
if (epic_cli.is_reconciliation(argv)) return await run_reconciliation(argv)
|
|
172
|
+
if (epic_cli.is_removal(argv)) return await run_removal(argv)
|
|
173
|
+
if (epic_cli.is_addition(argv)) return await run_addition(argv)
|
|
174
|
+
if (epic_cli.is_promotion(argv)) return await run_promotion(argv)
|
|
175
|
+
|
|
176
|
+
return await run_creation(argv)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function main(): Promise<void> {
|
|
180
|
+
const exit_code = await run(process.argv.slice(ARGV_OFFSET))
|
|
181
|
+
|
|
182
|
+
if (exit_code !== 0) process.exit(exit_code)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// A `gh` failure carries its stderr as the message, which is the useful part; printing it alone
|
|
186
|
+
// keeps a routine "not authenticated" or "label not found" from arriving as a stack trace.
|
|
187
|
+
try {
|
|
188
|
+
await main()
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error(`✖ ${error instanceof Error ? error.message : String(error)}`)
|
|
191
|
+
process.exit(FAILURE_EXIT_CODE)
|
|
192
|
+
}
|