@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,421 @@
|
|
|
1
|
+
import { epic_graph, type EpicChild } from '#scripts/epic/epic-graph'
|
|
2
|
+
import { git_epic_add_body, type RewriteInput } from './git-epic-add-body'
|
|
3
|
+
import { git_epic_chains, type InsertOutcome, type InsertPosition } from './git-epic-chains'
|
|
4
|
+
import { git_epic_decision } from './git-epic-decision'
|
|
5
|
+
import { git_epic_parse, type DependencyLink } from './git-epic-parse'
|
|
6
|
+
import { format_dependency_links, to_issue_reference } from './git-epic-reference'
|
|
7
|
+
import { git_epic_shape } from './git-epic-shape'
|
|
8
|
+
|
|
9
|
+
// Everything `josh epic --add` decides before it writes anything.
|
|
10
|
+
//
|
|
11
|
+
// Kept apart from the GitHub calls so the whole decision — which rows to add, which declaration to
|
|
12
|
+
// write, which relations to record and which to drop — is asserted without a network. That
|
|
13
|
+
// separation is the point: the command's value is that it refuses rather than half-applies, and a
|
|
14
|
+
// refusal path only reachable through `gh` is a refusal path nobody tests (joshuafolkken/kit#890).
|
|
15
|
+
|
|
16
|
+
interface PlanInput {
|
|
17
|
+
epic_number: number
|
|
18
|
+
body: string | undefined
|
|
19
|
+
labels: ReadonlyArray<string>
|
|
20
|
+
children: ReadonlyArray<number>
|
|
21
|
+
position?: InsertPosition | undefined
|
|
22
|
+
// `--order-before` / `--order-after`: move the task-list row to `position` and write nothing else —
|
|
23
|
+
// no declaration, no `blocked-by` (joshuafolkken/kit#1738). The position is carried in the field
|
|
24
|
+
// above rather than in one of its own, because where the row goes is the same question either way;
|
|
25
|
+
// what this flag decides is whether a dependency is recorded behind it.
|
|
26
|
+
is_order_only?: boolean | undefined
|
|
27
|
+
// The epic's current children with their native relations, as `epic:next` reads them.
|
|
28
|
+
recorded: ReadonlyArray<EpicChild>
|
|
29
|
+
// The epic's own repository — what a declared bare number names. Needed since
|
|
30
|
+
// joshuafolkken/kit#1126 made a recorded relation carry the repository it lives in.
|
|
31
|
+
repo: string
|
|
32
|
+
// The decision record `--decision-file` supplied, or `undefined` for an insertion that records
|
|
33
|
+
// none. It reaches the body rewrite rather than being posted separately, so the epic half of the
|
|
34
|
+
// record rides on the body edit the insertion already makes (joshuafolkken/kit#1350).
|
|
35
|
+
decision?: string | undefined
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface AddPlan {
|
|
39
|
+
body: string
|
|
40
|
+
additions: ReadonlyArray<number>
|
|
41
|
+
// The children the epic already tracked, moved to the position the caller named. Kept apart from
|
|
42
|
+
// `additions` because the two write different things: an addition gains a task-list row, while a
|
|
43
|
+
// relocation only moves the row it already had (joshuafolkken/kit#1701).
|
|
44
|
+
relocations: ReadonlyArray<number>
|
|
45
|
+
added: ReadonlyArray<DependencyLink>
|
|
46
|
+
removed: ReadonlyArray<DependencyLink>
|
|
47
|
+
// Every link the declaration dropped, whether or not GitHub had recorded it natively — which is what
|
|
48
|
+
// separates it from `removed` above (joshuafolkken/kit#1711). `removed` is a work list for `gh` and
|
|
49
|
+
// is therefore filtered down to relations that exist to be removed; this is the *report*, and a
|
|
50
|
+
// declared-but-unrecorded order the caller re-pointed is exactly as much a replacement as a recorded
|
|
51
|
+
// one. Reporting from `removed` let those vanish without a word.
|
|
52
|
+
replaced: ReadonlyArray<DependencyLink>
|
|
53
|
+
// The placed children an order-only move puts on the wrong side of an order the declaration already
|
|
54
|
+
// states — ahead of an issue declared to block them, or behind one they are declared to block
|
|
55
|
+
// (joshuafolkken/kit#1738). **The wrong side is judged against the whole resulting row order, not
|
|
56
|
+
// against the move target alone** (joshuafolkken/kit#1753): a relocation can seat a row on the wrong
|
|
57
|
+
// side of a *third* child the target never named, and a check that only compared the target missed
|
|
58
|
+
// it. `epic:next` filters by `blocked_by` **before** it applies task-list
|
|
59
|
+
// order, so such a row cannot take effect until the declaration itself changes, and a run that only
|
|
60
|
+
// printed `📋 Placed …` would report a reordering that nothing can observe.
|
|
61
|
+
//
|
|
62
|
+
// **Reported rather than refused.** Reordering inside a partly-ordered epic is legitimate — the row
|
|
63
|
+
// still decides where the child sits among the runnable ones once its blocker closes — so only this
|
|
64
|
+
// one pairing is worth a word, and refusing it would take a route the Issue did not ask to close.
|
|
65
|
+
// It is empty for every insertion that writes its own declaration, since that declaration is what
|
|
66
|
+
// the move would have contradicted.
|
|
67
|
+
contradicted: ReadonlyArray<number>
|
|
68
|
+
// The `--decision-file` record as it will be written, with `replaced` appended. Carried on the plan
|
|
69
|
+
// rather than recomposed by the caller so the epic's `## Decisions` and the child comments cannot
|
|
70
|
+
// end up with two different texts.
|
|
71
|
+
decision?: string | undefined
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
type PlanOutcome = { plan: AddPlan } | { error: string }
|
|
75
|
+
|
|
76
|
+
// The requested children minus the ones there is nothing to do for. The epic itself is dropped
|
|
77
|
+
// rather than refused for the same reason `--promote` drops it: it would be asked to block itself.
|
|
78
|
+
function to_additions(
|
|
79
|
+
input: PlanInput,
|
|
80
|
+
tracked: ReadonlyArray<number>,
|
|
81
|
+
declared: ReadonlyArray<number>,
|
|
82
|
+
): Array<number> {
|
|
83
|
+
return input.children.filter(
|
|
84
|
+
(child) => child !== input.epic_number && !tracked.includes(child) && !declared.includes(child),
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Every issue the declaration names, whether or not the task list still tracks it. Filtered against
|
|
89
|
+
// as well as `tracked`, because the two can disagree — and re-adding an issue the chain already
|
|
90
|
+
// names is what produces a cycle.
|
|
91
|
+
function declared_numbers(chains: ReadonlyArray<ReadonlyArray<number>>): Array<number> {
|
|
92
|
+
return [...new Set(chains.flat())]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// The children the epic already tracks, given a position: what used to be filtered out as "nothing to
|
|
96
|
+
// do" is a reorder the moment `--before` / `--after` says where they go. Without a position there is
|
|
97
|
+
// still nothing to do, so the refusal below stands for that case (joshuafolkken/kit#1701).
|
|
98
|
+
//
|
|
99
|
+
// **The task list decides, not the declaration.** An issue a chain names while no row tracks it is
|
|
100
|
+
// what joshuafolkken/kit#890's cycle came out of, and a move that re-rendered its missing row would
|
|
101
|
+
// repair a body somebody has to reconcile by hand — so it stays outside a move and keeps the refusal
|
|
102
|
+
// it already had.
|
|
103
|
+
function to_relocations(input: PlanInput, tracked: ReadonlyArray<number>): Array<number> {
|
|
104
|
+
if (input.position === undefined) return []
|
|
105
|
+
|
|
106
|
+
return input.children.filter((child) => child !== input.epic_number && tracked.includes(child))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// The issues to place, in the order the caller gave them. Additions and relocations enter one chain
|
|
110
|
+
// segment together, so which comes first is the caller's word rather than which bucket it fell into
|
|
111
|
+
// — and the task list is written from this same list, which is what keeps the two agreeing
|
|
112
|
+
// (joshuafolkken/kit#1704).
|
|
113
|
+
function to_placed(
|
|
114
|
+
children: ReadonlyArray<number>,
|
|
115
|
+
additions: ReadonlyArray<number>,
|
|
116
|
+
relocations: ReadonlyArray<number>,
|
|
117
|
+
): Array<number> {
|
|
118
|
+
const placed = new Set([...additions, ...relocations])
|
|
119
|
+
|
|
120
|
+
return [...new Set(children.filter((child) => placed.has(child)))]
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// A position naming one of the issues being placed. `--after #N` for `#N` itself is neither an
|
|
124
|
+
// addition nor a move, and falling through to the refusal below would describe the wrong thing.
|
|
125
|
+
function find_self_position_error(input: PlanInput): string | undefined {
|
|
126
|
+
const { position } = input
|
|
127
|
+
if (position === undefined || !input.children.includes(position.target)) return undefined
|
|
128
|
+
|
|
129
|
+
return `${to_issue_reference(position.target)} cannot position an insertion of itself.`
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Nothing to add and nothing to move. The remedy is named only where it applies: with a position
|
|
133
|
+
// already given, the issues are ones the declaration names but no row tracks, and telling the caller
|
|
134
|
+
// to name a position would send them round the same refusal.
|
|
135
|
+
function to_nothing_to_do_error(position: InsertPosition | undefined): string {
|
|
136
|
+
const nothing = 'Every issue given is already tracked by this epic; nothing to add.'
|
|
137
|
+
if (position !== undefined) return nothing
|
|
138
|
+
|
|
139
|
+
return `${nothing} Name \`--before <M>\` or \`--after <M>\` to declare an order between children it already tracks, or \`--order-before <M>\` / \`--order-after <M>\` to move the row without declaring one.`
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function find_movement_error(
|
|
143
|
+
moves: { additions: ReadonlyArray<number>; relocations: ReadonlyArray<number> },
|
|
144
|
+
position: InsertPosition | undefined,
|
|
145
|
+
tracked: ReadonlyArray<number>,
|
|
146
|
+
): string | undefined {
|
|
147
|
+
if (moves.additions.length === 0 && moves.relocations.length === 0) {
|
|
148
|
+
return to_nothing_to_do_error(position)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (position !== undefined && !tracked.includes(position.target)) {
|
|
152
|
+
const reference = to_issue_reference(position.target)
|
|
153
|
+
|
|
154
|
+
return `${reference} is not a child of this epic, so it cannot position an insertion.`
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return undefined
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// A relation recorded between two children that the body never declares. Refused rather than
|
|
161
|
+
// repaired: someone recorded it deliberately, and rewriting the declaration around it would either
|
|
162
|
+
// drop that intent or leave the epic disagreeing with itself, which is what stops an unattended run.
|
|
163
|
+
//
|
|
164
|
+
// The other direction — declared but never recorded, which an older epic or a failed recording
|
|
165
|
+
// leaves behind — is not an error here. It is folded into the relations this command records, so the write repairs it.
|
|
166
|
+
function find_relation_error(
|
|
167
|
+
links: ReadonlyArray<DependencyLink>,
|
|
168
|
+
recorded: ReadonlyArray<EpicChild>,
|
|
169
|
+
repo: string,
|
|
170
|
+
): string | undefined {
|
|
171
|
+
const undeclared = epic_graph.undeclared_relations(links, recorded, repo)
|
|
172
|
+
if (undeclared.length === 0) return undefined
|
|
173
|
+
|
|
174
|
+
const list = format_dependency_links(undeclared)
|
|
175
|
+
|
|
176
|
+
return `The epic already records relations its body does not declare (${list}); reconcile them before inserting.`
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// What `build_plan` computed, handed to the composition below as one value: the epic's own input, the
|
|
180
|
+
// two kinds of placement, and the declaration before and after.
|
|
181
|
+
interface PlanContext {
|
|
182
|
+
input: PlanInput
|
|
183
|
+
additions: ReadonlyArray<number>
|
|
184
|
+
relocations: ReadonlyArray<number>
|
|
185
|
+
// The two above as one list, in the order the caller named them — what both the chain segment and
|
|
186
|
+
// the task list are written from (joshuafolkken/kit#1704).
|
|
187
|
+
placed: ReadonlyArray<number>
|
|
188
|
+
chains_before: ReadonlyArray<ReadonlyArray<number>>
|
|
189
|
+
chains_after: ReadonlyArray<ReadonlyArray<number>>
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function to_rewrite_input(context: PlanContext, decision: string | undefined): RewriteInput {
|
|
193
|
+
return {
|
|
194
|
+
body: context.input.body ?? '',
|
|
195
|
+
placed: context.placed,
|
|
196
|
+
position: context.input.position,
|
|
197
|
+
chains_after: context.chains_after,
|
|
198
|
+
decision,
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// The write itself, once every refusal above has passed. Split out so `build_plan` stays a list of
|
|
203
|
+
// checks rather than a function that both checks and composes.
|
|
204
|
+
//
|
|
205
|
+
// **The replacements are folded into the decision record before the body is rewritten**, because the
|
|
206
|
+
// epic's `## Decisions` half rides on that same edit (joshuafolkken/kit#1350) — composing it afterwards
|
|
207
|
+
// would put the line on the child comments and leave the epic without it. The caller-supplied record
|
|
208
|
+
// has already been validated by `find_decision_error`; what is appended here is generated, not read
|
|
209
|
+
// from a file.
|
|
210
|
+
// An ordinary insertion records every link the declaration names that GitHub does not, which repairs a
|
|
211
|
+
// declared-but-unrecorded order in passing. **An order-only move records nothing at all**
|
|
212
|
+
// (joshuafolkken/kit#1738): `--order-*` exists so a row can move with no dependency appearing behind
|
|
213
|
+
// it, and a repair made under it would put back exactly the `blocked-by` the caller asked not to have.
|
|
214
|
+
// The declaration is unchanged either way, so the repair is still there for the next insertion to make.
|
|
215
|
+
function to_added_links(
|
|
216
|
+
context: PlanContext,
|
|
217
|
+
links_after: ReadonlyArray<DependencyLink>,
|
|
218
|
+
): ReadonlyArray<DependencyLink> {
|
|
219
|
+
if (context.input.is_order_only === true) return []
|
|
220
|
+
|
|
221
|
+
return epic_graph.missing_relations(links_after, context.input.recorded, context.input.repo)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Whether the declaration already says `blocker` has to finish before `blocked`. A chain is written in
|
|
225
|
+
// execution order, so naming the blocker at a lower index is the whole test — and it covers the
|
|
226
|
+
// transitive case for free, which is what makes `#890 -> #891 -> #892` answer for `#890` and `#892`.
|
|
227
|
+
function does_declare_order(
|
|
228
|
+
chains: ReadonlyArray<ReadonlyArray<number>>,
|
|
229
|
+
blocker: number,
|
|
230
|
+
blocked: number,
|
|
231
|
+
): boolean {
|
|
232
|
+
return chains.some((chain) => {
|
|
233
|
+
const at_blocker = chain.indexOf(blocker)
|
|
234
|
+
|
|
235
|
+
return at_blocker !== -1 && at_blocker < chain.indexOf(blocked)
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Whether the resulting row order puts `child` on the wrong side of any issue the declaration orders
|
|
240
|
+
// it against — ahead of one declared to block it, or behind one it is declared to block. The move
|
|
241
|
+
// target is not privileged: a relocation can seat a row on the wrong side of a *third* child the
|
|
242
|
+
// target never named, so the whole resulting order is cross-checked rather than the target alone
|
|
243
|
+
// (joshuafolkken/kit#1753).
|
|
244
|
+
function does_row_contradict_order(
|
|
245
|
+
chains: ReadonlyArray<ReadonlyArray<number>>,
|
|
246
|
+
rows: ReadonlyArray<number>,
|
|
247
|
+
child: number,
|
|
248
|
+
): boolean {
|
|
249
|
+
const child_at = rows.indexOf(child)
|
|
250
|
+
|
|
251
|
+
return rows.some((other, other_at) => {
|
|
252
|
+
if (other === child) return false
|
|
253
|
+
if (other_at < child_at) return does_declare_order(chains, child, other)
|
|
254
|
+
|
|
255
|
+
return does_declare_order(chains, other, child)
|
|
256
|
+
})
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// The placed children the resulting row order puts on the wrong side of a declared order — see
|
|
260
|
+
// `contradicted` above. Asked only of an order-only move: every other insertion rewrites the
|
|
261
|
+
// declaration to match the row it placed, so there is nothing left for the row to contradict. The
|
|
262
|
+
// rows are the ones the body rewrite produced, so the check reads the order that will actually be
|
|
263
|
+
// written rather than reconstructing it.
|
|
264
|
+
function to_contradicted(
|
|
265
|
+
context: PlanContext,
|
|
266
|
+
result_rows: ReadonlyArray<number>,
|
|
267
|
+
): ReadonlyArray<number> {
|
|
268
|
+
if (context.input.position === undefined || context.input.is_order_only !== true) return []
|
|
269
|
+
|
|
270
|
+
return context.placed.filter((child) =>
|
|
271
|
+
does_row_contradict_order(context.chains_before, result_rows, child),
|
|
272
|
+
)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function to_plan(context: PlanContext): PlanOutcome {
|
|
276
|
+
const { removed: replaced } = git_epic_chains.diff_links(
|
|
277
|
+
context.chains_before,
|
|
278
|
+
context.chains_after,
|
|
279
|
+
)
|
|
280
|
+
const decision = git_epic_decision.append_replacements(context.input.decision, replaced)
|
|
281
|
+
const rewritten = git_epic_add_body.rewrite_body(to_rewrite_input(context, decision))
|
|
282
|
+
if ('error' in rewritten) return { error: rewritten.error }
|
|
283
|
+
|
|
284
|
+
const links_after = git_epic_chains.links_of(context.chains_after)
|
|
285
|
+
const result_rows = git_epic_parse.parse_task_list_issue_numbers(rewritten.body)
|
|
286
|
+
|
|
287
|
+
return {
|
|
288
|
+
plan: {
|
|
289
|
+
body: rewritten.body,
|
|
290
|
+
additions: context.additions,
|
|
291
|
+
relocations: context.relocations,
|
|
292
|
+
added: to_added_links(context, links_after),
|
|
293
|
+
// Only the links a relation actually backs: asking `gh` to remove one that was never
|
|
294
|
+
// recorded is reported as a failure the user cannot act on.
|
|
295
|
+
removed: epic_graph.recorded_relations(replaced, context.input.recorded, context.input.repo),
|
|
296
|
+
replaced,
|
|
297
|
+
contradicted: to_contradicted(context, result_rows),
|
|
298
|
+
decision,
|
|
299
|
+
},
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// A decision record that cannot be written is refused here rather than dropped: `--decision-file` was
|
|
304
|
+
// given because the record has to exist, so writing the insertion without it would report success for
|
|
305
|
+
// half the job (joshuafolkken/kit#1350). `undefined` is "none was asked for", which is not a refusal.
|
|
306
|
+
function find_decision_error(decision: string | undefined): string | undefined {
|
|
307
|
+
return decision === undefined ? undefined : git_epic_decision.find_decision_error(decision)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Asked of the declaration as it stands, because a relocation's removal can collapse the very
|
|
311
|
+
// ambiguity this refuses (joshuafolkken/kit#1701).
|
|
312
|
+
//
|
|
313
|
+
// **An order-only move is not asked at all** (joshuafolkken/kit#1738). The ambiguity is about where a
|
|
314
|
+
// *dependency* would attach — `--before <hub>` cannot say which of the chains running through the hub
|
|
315
|
+
// the new link joins — and `--order-*` attaches no link, so the question has no subject. Asking it
|
|
316
|
+
// anyway would refuse a row move on the strength of a declaration the move never touches.
|
|
317
|
+
function find_ambiguity_error(
|
|
318
|
+
input: PlanInput,
|
|
319
|
+
chains_before: ReadonlyArray<ReadonlyArray<number>>,
|
|
320
|
+
): string | undefined {
|
|
321
|
+
if (input.is_order_only === true) return undefined
|
|
322
|
+
|
|
323
|
+
return git_epic_chains.find_position_ambiguity(chains_before, input.position)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// The refusals about what is being placed and where: the position may not name one of the issues
|
|
327
|
+
// being placed, there has to be something to add or move, and the position has to identify one place.
|
|
328
|
+
function find_placement_error(
|
|
329
|
+
input: PlanInput,
|
|
330
|
+
tracked: ReadonlyArray<number>,
|
|
331
|
+
chains_before: ReadonlyArray<ReadonlyArray<number>>,
|
|
332
|
+
): string | undefined {
|
|
333
|
+
const declared = declared_numbers(chains_before)
|
|
334
|
+
|
|
335
|
+
return (
|
|
336
|
+
find_self_position_error(input) ??
|
|
337
|
+
find_movement_error(
|
|
338
|
+
{
|
|
339
|
+
additions: to_additions(input, tracked, declared),
|
|
340
|
+
relocations: to_relocations(input, tracked),
|
|
341
|
+
},
|
|
342
|
+
input.position,
|
|
343
|
+
tracked,
|
|
344
|
+
) ??
|
|
345
|
+
find_ambiguity_error(input, chains_before)
|
|
346
|
+
)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Every refusal, in the order a reader needs them: is this an epic, is there something to place and
|
|
350
|
+
// somewhere to put it, do the body and the relations already agree, and can the decision record be
|
|
351
|
+
// written.
|
|
352
|
+
function find_input_error(
|
|
353
|
+
input: PlanInput,
|
|
354
|
+
tracked: ReadonlyArray<number>,
|
|
355
|
+
chains_before: ReadonlyArray<ReadonlyArray<number>>,
|
|
356
|
+
): string | undefined {
|
|
357
|
+
return (
|
|
358
|
+
git_epic_shape.find_subject_error(input, tracked) ??
|
|
359
|
+
find_placement_error(input, tracked, chains_before) ??
|
|
360
|
+
find_relation_error(git_epic_chains.links_of(chains_before), input.recorded, input.repo) ??
|
|
361
|
+
find_decision_error(input.decision)
|
|
362
|
+
)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// The declaration the body will carry. A relocation is a removal followed by the ordinary insertion,
|
|
366
|
+
// so `--before` re-points the chain it lands in and the vacated chain closes around it — both by
|
|
367
|
+
// construction rather than by a second code path (joshuafolkken/kit#1701).
|
|
368
|
+
//
|
|
369
|
+
// **An order-only move takes neither step** (joshuafolkken/kit#1738): the declaration it started with
|
|
370
|
+
// is the declaration it ends with, which is `keep_declaration` — the same passthrough `--add` with no
|
|
371
|
+
// position already uses. Because the chains come back identical, `diff_links` finds nothing replaced
|
|
372
|
+
// and the body rewrite leaves the `## Dependencies` section byte-identical, so "writes no dependency"
|
|
373
|
+
// holds by construction rather than by a filter applied afterwards.
|
|
374
|
+
function to_chains_after(
|
|
375
|
+
input: PlanInput,
|
|
376
|
+
chains_before: ReadonlyArray<ReadonlyArray<number>>,
|
|
377
|
+
moves: { placed: ReadonlyArray<number>; relocations: ReadonlyArray<number> },
|
|
378
|
+
tracked: ReadonlyArray<number>,
|
|
379
|
+
): InsertOutcome {
|
|
380
|
+
if (input.is_order_only === true) return git_epic_chains.keep_declaration(chains_before)
|
|
381
|
+
|
|
382
|
+
return git_epic_chains.insert_children(
|
|
383
|
+
git_epic_chains.remove_children(chains_before, moves.relocations),
|
|
384
|
+
moves.placed,
|
|
385
|
+
input.position,
|
|
386
|
+
tracked,
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function build_plan(input: PlanInput): PlanOutcome {
|
|
391
|
+
const tracked = git_epic_parse.parse_task_list_issue_numbers(input.body)
|
|
392
|
+
const chains_before = git_epic_parse.parse_dependency_chains(input.body)
|
|
393
|
+
const error = find_input_error(input, tracked, chains_before)
|
|
394
|
+
if (error !== undefined) return { error }
|
|
395
|
+
|
|
396
|
+
const additions = to_additions(input, tracked, declared_numbers(chains_before))
|
|
397
|
+
const relocations = to_relocations(input, tracked)
|
|
398
|
+
// `tracked` reaches the chain builder so it can tell a child with no order yet from a number that is
|
|
399
|
+
// not a child at all; `find_movement_error` has already refused the second (joshuafolkken/kit#949).
|
|
400
|
+
// What the builder does with a relocation, and what an order-only move does instead, is on
|
|
401
|
+
// `to_chains_after` above.
|
|
402
|
+
const placed = to_placed(input.children, additions, relocations)
|
|
403
|
+
const inserted = to_chains_after(input, chains_before, { placed, relocations }, tracked)
|
|
404
|
+
if ('error' in inserted) return { error: inserted.error }
|
|
405
|
+
|
|
406
|
+
return to_plan({
|
|
407
|
+
input,
|
|
408
|
+
additions,
|
|
409
|
+
relocations,
|
|
410
|
+
placed,
|
|
411
|
+
chains_before,
|
|
412
|
+
chains_after: inserted.chains,
|
|
413
|
+
})
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const git_epic_add_plan = {
|
|
417
|
+
build_plan,
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export { git_epic_add_plan }
|
|
421
|
+
export type { AddPlan, PlanInput, PlanOutcome }
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { backlog_ready } from '#scripts/backlog/backlog-ready'
|
|
2
|
+
import { epic_issue } from '#scripts/epic/epic-issue'
|
|
3
|
+
import { git_epic_add_plan, type AddPlan } from './git-epic-add-plan'
|
|
4
|
+
import type { InsertPosition } from './git-epic-chains'
|
|
5
|
+
import { git_epic_decision } from './git-epic-decision'
|
|
6
|
+
import { git_epic_read, type EpicReading } from './git-epic-read'
|
|
7
|
+
import {
|
|
8
|
+
format_issue_references,
|
|
9
|
+
format_replaced_relations,
|
|
10
|
+
to_issue_reference,
|
|
11
|
+
} from './git-epic-reference'
|
|
12
|
+
import { git_epic_relations } from './git-epic-relations'
|
|
13
|
+
import { git_gh_command } from './git-gh-command'
|
|
14
|
+
|
|
15
|
+
// `josh epic --add <E> <N...> [--before <M> | --after <M> | --order-before <M> | --order-after <M>]
|
|
16
|
+
// [--decision-file <path|->]` — insert children into an existing epic.
|
|
17
|
+
//
|
|
18
|
+
// **`--order-*` moves the row and writes nothing else** (joshuafolkken/kit#1738). `epic:next` offers
|
|
19
|
+
// children in task-list order, so putting one first meant `--before`, which records a `blocked-by`:
|
|
20
|
+
// "no dependency, but run this one first" had no spelling, and an order written that way stops every
|
|
21
|
+
// child behind the one that stalls.
|
|
22
|
+
//
|
|
23
|
+
// Adding a child by editing the body is what the procedure told an agent to do, and it is what stops
|
|
24
|
+
// an unattended run: the body then declares an order the native `blocked-by` relations do not record,
|
|
25
|
+
// `epic:next` reports `declaration_mismatch`, and the verdict is `error`. This command writes the
|
|
26
|
+
// task-list row, the declaration and the relations from one input, so the three cannot disagree
|
|
27
|
+
// (joshuafolkken/kit#890).
|
|
28
|
+
//
|
|
29
|
+
// **`--decision-file` folds the fourth and fifth writes in** (joshuafolkken/kit#1350). An auto-decided
|
|
30
|
+
// placement has to be recorded in the epic's `## Decisions` and on each child, and no command wrote the
|
|
31
|
+
// epic half — so a run read the body, edited it and `PATCH`ed it back, which is the hand edit
|
|
32
|
+
// `CLAUDE.md` forbids. The epic half now rides on the body edit this command already makes, so it costs
|
|
33
|
+
// no round trip; the child half is one comment per addition, counted rather than thrown.
|
|
34
|
+
|
|
35
|
+
const FAILURE_EXIT_CODE = 1
|
|
36
|
+
const SUCCESS_EXIT_CODE = 0
|
|
37
|
+
|
|
38
|
+
// A completed epic takes no new children: adding one silently produces a closed epic with unfinished
|
|
39
|
+
// children, whose backlog opt-in no longer fires, so the child never surfaces and the addition is
|
|
40
|
+
// lost (joshuafolkken/kit#2337). The refusal is only fired on a *confirmed* closed state — an
|
|
41
|
+
// unreadable state field leaves the addition to proceed, since blocking on a lookup that never
|
|
42
|
+
// answered would be the worse failure.
|
|
43
|
+
function is_closed_epic(state: string | undefined): boolean {
|
|
44
|
+
return state !== undefined && epic_issue.normalize_state(state) === epic_issue.CLOSED
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function closed_epic_error(epic_number: number): string {
|
|
48
|
+
return `Epic #${String(epic_number)} is closed — a completed epic takes no new children. Reopen it if it is not actually done, or run \`pnpm josh epic:bundle <child>\` to place the child in an open epic instead.`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface AddChildrenInput {
|
|
52
|
+
epic_number: number
|
|
53
|
+
children: ReadonlyArray<number>
|
|
54
|
+
position?: InsertPosition | undefined
|
|
55
|
+
// `--order-before` / `--order-after`: place the row at `position` and write nothing else — no
|
|
56
|
+
// declaration, no `blocked-by` (joshuafolkken/kit#1738).
|
|
57
|
+
is_order_only?: boolean | undefined
|
|
58
|
+
// The decision record to write, from `--decision-file`. It goes to two places, and both used to be
|
|
59
|
+
// separate calls a run made afterwards: the epic's `## Decisions` section — folded into the body
|
|
60
|
+
// edit below, so it costs no round trip — and a comment on each child added
|
|
61
|
+
// (joshuafolkken/kit#1350).
|
|
62
|
+
decision?: string | undefined
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function report_relations(plan: AddPlan, failures: { added: number; removed: number }): void {
|
|
66
|
+
if (plan.removed.length > 0) {
|
|
67
|
+
console.info(
|
|
68
|
+
git_epic_relations.format_relation_report({
|
|
69
|
+
links: plan.removed,
|
|
70
|
+
failures: failures.removed,
|
|
71
|
+
action: 'drop',
|
|
72
|
+
}),
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (plan.added.length === 0) return
|
|
77
|
+
|
|
78
|
+
console.info(
|
|
79
|
+
git_epic_relations.format_relation_report({
|
|
80
|
+
links: plan.added,
|
|
81
|
+
failures: failures.added,
|
|
82
|
+
action: 'record',
|
|
83
|
+
}),
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Dropped before recorded: inserting `#N` between `#B` and `#M` replaces `#B -> #M`, and applying the
|
|
88
|
+
// new link first would leave `#M` momentarily blocked by both.
|
|
89
|
+
async function apply_plan(plan: AddPlan): Promise<void> {
|
|
90
|
+
const removed = await git_epic_relations.apply_relations(plan.removed, 'drop')
|
|
91
|
+
const added = await git_epic_relations.apply_relations(plan.added, 'record')
|
|
92
|
+
|
|
93
|
+
report_relations(plan, { added, removed })
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// The two things one insertion can do, reported separately because they are different edits: an
|
|
97
|
+
// addition gains a task-list row, a relocation moves the row it already had. Either list can be empty
|
|
98
|
+
// — `--before` / `--after` on children the epic already tracks adds nothing at all
|
|
99
|
+
// (joshuafolkken/kit#1701) — so neither line is printed unconditionally.
|
|
100
|
+
// A row moved onto the wrong side of an order the declaration already states. `epic:next` filters by
|
|
101
|
+
// `blocked_by` before it applies task-list order, so the move cannot change when that child is offered
|
|
102
|
+
// until the declaration itself changes — and the placement line above, read alone, says the opposite.
|
|
103
|
+
// It is a warning rather than a refusal for the reason `contradicted` gives (joshuafolkken/kit#1738).
|
|
104
|
+
function report_contradiction(plan: AddPlan): void {
|
|
105
|
+
if (plan.contradicted.length === 0) return
|
|
106
|
+
|
|
107
|
+
console.info(
|
|
108
|
+
`⚠️ ${format_issue_references(plan.contradicted)} is still held by a declared order, so \`epic:next\` will not offer it any earlier until that order is changed — \`--remove\` deletes one.`,
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// **An order-only move reports the place, because nothing else will** (joshuafolkken/kit#1738). An
|
|
113
|
+
// ordinary insertion is followed by the replaced-relation line and the relation report, which between
|
|
114
|
+
// them say where the child landed; `--order-*` writes neither, so without this line the console says a
|
|
115
|
+
// row moved and never says where to. The position is read from the input rather than the plan: the
|
|
116
|
+
// plan deliberately carries no record of it, the declaration being what it did not change.
|
|
117
|
+
function report_order(input: AddChildrenInput, plan: AddPlan): void {
|
|
118
|
+
const { position } = input
|
|
119
|
+
if (position === undefined) return
|
|
120
|
+
|
|
121
|
+
const placed = format_issue_references([...plan.additions, ...plan.relocations])
|
|
122
|
+
const target = to_issue_reference(position.target)
|
|
123
|
+
|
|
124
|
+
console.info(
|
|
125
|
+
`📋 Placed ${placed} ${position.kind} ${target} in epic #${String(input.epic_number)} — order only, no dependency written.`,
|
|
126
|
+
)
|
|
127
|
+
report_contradiction(plan)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function report_placements(input: AddChildrenInput, plan: AddPlan): void {
|
|
131
|
+
if (input.is_order_only === true) {
|
|
132
|
+
report_order(input, plan)
|
|
133
|
+
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const epic = `epic #${String(input.epic_number)}`
|
|
138
|
+
|
|
139
|
+
if (plan.additions.length > 0) {
|
|
140
|
+
console.info(`📋 Added ${format_issue_references(plan.additions)} to ${epic}.`)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (plan.relocations.length > 0) {
|
|
144
|
+
console.info(`📋 Moved ${format_issue_references(plan.relocations)} within ${epic}.`)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// **What the insertion discarded, printed from `plan.replaced` rather than `plan.removed`**
|
|
149
|
+
// (joshuafolkken/kit#1711). The two differ by the filter `removed` carries for `gh`'s sake: a link the
|
|
150
|
+
// body declared but nobody ever recorded natively is dropped from the declaration all the same, and
|
|
151
|
+
// reporting from the work list let exactly those go by without a word. A positioned `--add` is the
|
|
152
|
+
// only invocation that can replace anything, so an addition that re-points nothing prints nothing.
|
|
153
|
+
function report_success(input: AddChildrenInput, plan: AddPlan): void {
|
|
154
|
+
report_placements(input, plan)
|
|
155
|
+
|
|
156
|
+
if (plan.replaced.length > 0) {
|
|
157
|
+
console.info(`↪ ${format_replaced_relations(plan.replaced)}`)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// The child half of the decision record, posted after the epic's body carries its own half. A failure
|
|
162
|
+
// is counted rather than thrown for the reason a relation failure is: the insertion itself has landed,
|
|
163
|
+
// and an exception here would leave the caller unable to tell that from a refusal that wrote nothing.
|
|
164
|
+
async function comment_decision(children: ReadonlyArray<number>, decision: string): Promise<void> {
|
|
165
|
+
const posted = await Promise.all(
|
|
166
|
+
children.map(async (child) => await git_gh_command.issue_try_comment(String(child), decision)),
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
console.info(
|
|
170
|
+
git_epic_decision.format_decision_report({
|
|
171
|
+
total: children.length,
|
|
172
|
+
failures: posted.filter((is_posted) => !is_posted).length,
|
|
173
|
+
}),
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// The record posted to the children is `plan.decision`, not the caller's file: the plan is what folded
|
|
178
|
+
// the replaced relations into it, and reading the raw input here would leave the epic's `## Decisions`
|
|
179
|
+
// carrying a line the child comments do not (joshuafolkken/kit#1711).
|
|
180
|
+
// A child new to the epic, not a reordering — the only insertion that can put runnable work in the pool.
|
|
181
|
+
function has_new_child(input: AddChildrenInput, plan: AddPlan): boolean {
|
|
182
|
+
return input.is_order_only !== true && plan.additions.length > 0
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function write_plan(input: AddChildrenInput, plan: AddPlan): Promise<void> {
|
|
186
|
+
await git_gh_command.issue_edit_body(String(input.epic_number), plan.body)
|
|
187
|
+
report_success(input, plan)
|
|
188
|
+
await apply_plan(plan)
|
|
189
|
+
|
|
190
|
+
// A relocation is a placement decision as much as an addition is, so the record reaches the child
|
|
191
|
+
// that was moved too (joshuafolkken/kit#1701).
|
|
192
|
+
if (plan.decision !== undefined) {
|
|
193
|
+
await comment_decision([...plan.additions, ...plan.relocations], plan.decision)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (has_new_child(input, plan)) await backlog_ready.print_offer_hint()
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// The epic ready to receive children, or the reason it cannot be added to: unreadable, or closed
|
|
200
|
+
// (joshuafolkken/kit#2337). Both reasons come back as a bare string the one caller prefixes `✖` onto,
|
|
201
|
+
// so the two refusals read identically on stderr.
|
|
202
|
+
async function read_open_epic(epic_number: number): Promise<EpicReading | { error: string }> {
|
|
203
|
+
const epic = await git_epic_read.read_epic(epic_number)
|
|
204
|
+
if ('error' in epic) return epic
|
|
205
|
+
if (is_closed_epic(epic.subject.state)) return { error: closed_epic_error(epic_number) }
|
|
206
|
+
|
|
207
|
+
return epic
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Insert children into an existing epic, or refuse without writing anything. Every refusal happens
|
|
211
|
+
// before the body edit, so a rejected invocation leaves the epic exactly as it was.
|
|
212
|
+
async function add_children(input: AddChildrenInput): Promise<number> {
|
|
213
|
+
const epic = await read_open_epic(input.epic_number)
|
|
214
|
+
|
|
215
|
+
if ('error' in epic) {
|
|
216
|
+
console.error(`✖ ${epic.error}`)
|
|
217
|
+
|
|
218
|
+
return FAILURE_EXIT_CODE
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const outcome = git_epic_add_plan.build_plan({
|
|
222
|
+
epic_number: input.epic_number,
|
|
223
|
+
body: epic.subject.body,
|
|
224
|
+
labels: epic.subject.labels,
|
|
225
|
+
children: input.children,
|
|
226
|
+
position: input.position,
|
|
227
|
+
is_order_only: input.is_order_only,
|
|
228
|
+
recorded: epic.recorded,
|
|
229
|
+
repo: epic.repo,
|
|
230
|
+
decision: input.decision,
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
if ('error' in outcome) {
|
|
234
|
+
console.error(`✖ ${outcome.error}`)
|
|
235
|
+
|
|
236
|
+
return FAILURE_EXIT_CODE
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
await write_plan(input, outcome.plan)
|
|
240
|
+
|
|
241
|
+
return SUCCESS_EXIT_CODE
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const git_epic_add = {
|
|
245
|
+
add_children,
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export { git_epic_add }
|
|
249
|
+
export type { AddChildrenInput }
|