@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,73 @@
|
|
|
1
|
+
import { epic_fetch } from '#scripts/epic/epic-fetch'
|
|
2
|
+
import { epic_graph, type EpicChild } from '#scripts/epic/epic-graph'
|
|
3
|
+
import { git_epic_parse } from './git-epic-parse'
|
|
4
|
+
import { git_epic_validate, type EpicSubject } from './git-epic-validate'
|
|
5
|
+
import { git_gh_command } from './git-gh-command'
|
|
6
|
+
|
|
7
|
+
// Reading an epic and its current graph, for the two commands that edit its declared order.
|
|
8
|
+
//
|
|
9
|
+
// `--add` and `--remove` need exactly the same three things before they may compute anything: the
|
|
10
|
+
// epic's labels and body, the repository a declared bare number names, and every child with its
|
|
11
|
+
// native relations. They were the same forty lines twice until joshuafolkken/kit#1712 gave the
|
|
12
|
+
// removal a home; a second copy is where one of them comes to accept a graph the other refuses.
|
|
13
|
+
|
|
14
|
+
// Refused rather than stood in for, and both callers *write*. Since joshuafolkken/kit#1126 a plan
|
|
15
|
+
// filters recorded relations by the declared repository, so a placeholder drops every one of them:
|
|
16
|
+
// the "reconcile them before inserting" guard never fires, the superseded link is never dropped, and
|
|
17
|
+
// relations that already exist are re-POSTed — leaving the epic in exactly the mismatched state
|
|
18
|
+
// `epic:audit` refuses to run on.
|
|
19
|
+
const UNKNOWN_REPO =
|
|
20
|
+
"Could not read this repository from `git remote`, so the epic's relations cannot be keyed by repository — check `gh auth status` and that this is a checkout with an `origin` remote."
|
|
21
|
+
|
|
22
|
+
interface EpicReading {
|
|
23
|
+
subject: EpicSubject
|
|
24
|
+
recorded: ReadonlyArray<EpicChild>
|
|
25
|
+
repo: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function read_subject(epic_number: number): Promise<EpicSubject | undefined> {
|
|
29
|
+
return git_epic_validate.parse_epic_subject(
|
|
30
|
+
await git_gh_command.issue_get_labels_and_body(String(epic_number)),
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// The current children with their native relations. A child that cannot be read stops the command
|
|
35
|
+
// for the reason it stops `epic:next`: a missing node makes whatever it blocks look unblocked, and
|
|
36
|
+
// an edit computed against that graph would record or drop the wrong order.
|
|
37
|
+
async function read_recorded(
|
|
38
|
+
body: string | undefined,
|
|
39
|
+
): Promise<{ children: ReadonlyArray<EpicChild>; repo: string } | { error: string }> {
|
|
40
|
+
const repo = await git_gh_command.repo_get_name_with_owner()
|
|
41
|
+
if (repo === undefined) return { error: UNKNOWN_REPO }
|
|
42
|
+
const tracked = git_epic_parse.parse_task_list_issue_numbers(body)
|
|
43
|
+
if (tracked.length === 0) return { children: [], repo }
|
|
44
|
+
|
|
45
|
+
const fetched = await epic_fetch.fetch_children(tracked, repo)
|
|
46
|
+
|
|
47
|
+
if (fetched.unreadable.length > 0) {
|
|
48
|
+
const list = epic_graph.format_references(fetched.unreadable, repo)
|
|
49
|
+
|
|
50
|
+
return { error: `Could not read ${list}; the epic's dependency graph is incomplete.` }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return { children: fetched.children, repo }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// The epic and its current graph, or the reason neither could be read.
|
|
57
|
+
async function read_epic(epic_number: number): Promise<EpicReading | { error: string }> {
|
|
58
|
+
const subject = await read_subject(epic_number)
|
|
59
|
+
if (subject === undefined) return { error: `Could not read issue #${String(epic_number)}.` }
|
|
60
|
+
|
|
61
|
+
const recorded = await read_recorded(subject.body)
|
|
62
|
+
if ('error' in recorded) return { error: recorded.error }
|
|
63
|
+
|
|
64
|
+
return { subject, recorded: recorded.children, repo: recorded.repo }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const git_epic_read = {
|
|
68
|
+
UNKNOWN_REPO,
|
|
69
|
+
read_epic,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { git_epic_read }
|
|
73
|
+
export type { EpicReading }
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { epic_graph, type EpicChild, type IssueReference } from '#scripts/epic/epic-graph'
|
|
2
|
+
import { git_epic_add_body } from './git-epic-add-body'
|
|
3
|
+
import { git_epic_chains } from './git-epic-chains'
|
|
4
|
+
import { git_epic_parse, type DependencyLink } from './git-epic-parse'
|
|
5
|
+
import { git_epic_read } from './git-epic-read'
|
|
6
|
+
import { format_dependency_links } from './git-epic-reference'
|
|
7
|
+
import { git_epic_relations } from './git-epic-relations'
|
|
8
|
+
import { git_gh_command } from './git-gh-command'
|
|
9
|
+
|
|
10
|
+
// `josh epic --reconcile <E>` — bring an epic's `## Dependencies` declaration and its native
|
|
11
|
+
// `blocked-by` relations back into agreement, without a hand edit and without recording a decision
|
|
12
|
+
// (joshuafolkken/kit#2235).
|
|
13
|
+
//
|
|
14
|
+
// `--add` and `--remove` refuse the moment the two disagree, and `backlog:next` reports the graph
|
|
15
|
+
// unusable, so the only exit was to edit the epic body by hand — the very edit those commands exist
|
|
16
|
+
// to remove. There is no judgement in the repair: a relation recorded but never declared is written
|
|
17
|
+
// into the declaration (the relation is the GitHub-side fact, the body its copy), and an order
|
|
18
|
+
// declared but never recorded is aligned by recording it. The result declares exactly what it
|
|
19
|
+
// records, which is what `epic:audit` and `backlog:next` read.
|
|
20
|
+
//
|
|
21
|
+
// **It writes no `## Decisions`.** Synchronizing a copy is not a decision — there is no judgement to
|
|
22
|
+
// record — so the body edit carries the declaration alone, unlike `--add` / `--remove` whose
|
|
23
|
+
// `--decision-file` half rides on the same edit.
|
|
24
|
+
|
|
25
|
+
const FAILURE_EXIT_CODE = 1
|
|
26
|
+
const SUCCESS_EXIT_CODE = 0
|
|
27
|
+
|
|
28
|
+
const NOTHING_TO_RECONCILE = 'nothing to reconcile'
|
|
29
|
+
|
|
30
|
+
// The verdict the success path leads with, so a reader distinguishes a repair from a no-op by the
|
|
31
|
+
// token rather than by the exit code alone. The `lane:list` oracle reads its vocabulary from the
|
|
32
|
+
// emitting module the same way (`lane_occupancy`).
|
|
33
|
+
const RECONCILED = 'reconciled'
|
|
34
|
+
|
|
35
|
+
interface ReconcilePlanInput {
|
|
36
|
+
body: string | undefined
|
|
37
|
+
// The epic's children with their native relations, exactly as `git_epic_read` reads them.
|
|
38
|
+
recorded: ReadonlyArray<EpicChild>
|
|
39
|
+
// The epic's own repository — what a declared bare number names (joshuafolkken/kit#1126).
|
|
40
|
+
repo: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// What the repair will write. `declare` are relations recorded but never declared — added to the
|
|
44
|
+
// body; `record` are orders declared but never recorded — written as `blocked-by`. A `body` of
|
|
45
|
+
// `undefined` means only relations changed, so the body is left byte-identical.
|
|
46
|
+
interface Reconciliation {
|
|
47
|
+
body: string | undefined
|
|
48
|
+
declare: ReadonlyArray<DependencyLink>
|
|
49
|
+
record: ReadonlyArray<DependencyLink>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type ReconcilePlan =
|
|
53
|
+
| { kind: 'nothing' }
|
|
54
|
+
| { kind: 'cycle'; message: string }
|
|
55
|
+
| { kind: 'reconciled'; reconciliation: Reconciliation }
|
|
56
|
+
| { kind: 'error'; error: string }
|
|
57
|
+
|
|
58
|
+
function to_chain(link: DependencyLink): Array<number> {
|
|
59
|
+
return [link.blocker, link.blocked]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// A blocker of `blocked`, keyed to the epic's own repository so a declared bare number names the
|
|
63
|
+
// right issue (joshuafolkken/kit#1126).
|
|
64
|
+
function to_blocker(link: DependencyLink, repo: string): IssueReference {
|
|
65
|
+
return { repo, number: link.blocker }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// The union link set as children, so the shared cycle check can read it. Each node carries the
|
|
69
|
+
// blockers the union records; an isolated node carries none and can never be stuck.
|
|
70
|
+
function to_children(links: ReadonlyArray<DependencyLink>, repo: string): Array<EpicChild> {
|
|
71
|
+
const blockers = new Map<number, Array<IssueReference>>()
|
|
72
|
+
|
|
73
|
+
for (const link of links) {
|
|
74
|
+
blockers.set(link.blocked, [...(blockers.get(link.blocked) ?? []), to_blocker(link, repo)])
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const numbers = new Set(links.flatMap((link) => [link.blocker, link.blocked]))
|
|
78
|
+
|
|
79
|
+
return [...numbers].map((number) => ({
|
|
80
|
+
number,
|
|
81
|
+
repo,
|
|
82
|
+
state: 'OPEN' as const,
|
|
83
|
+
labels: [],
|
|
84
|
+
blocked_by: blockers.get(number) ?? [],
|
|
85
|
+
}))
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Whether the union of declared and recorded orders is circular, read through the one anomaly finder
|
|
89
|
+
// `epic:next` uses rather than a second cycle walk. With the children built from the links, only a
|
|
90
|
+
// cycle can surface — the declaration and the relations are equal by construction.
|
|
91
|
+
function find_cycle(links: ReadonlyArray<DependencyLink>, repo: string): string | undefined {
|
|
92
|
+
const anomalies = epic_graph.find_anomalies(to_children(links, repo), links, true, repo)
|
|
93
|
+
|
|
94
|
+
return anomalies.find((anomaly) => anomaly.kind === 'cycle')?.message
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// The body that declares the union order, or the reason it could not be written. Reuses the insertion
|
|
98
|
+
// rewriter with no rows and no decision, so "declare these links" goes through the one code path that
|
|
99
|
+
// already rewrites `## Dependencies` and verifies the round trip.
|
|
100
|
+
function to_reconciled_body(
|
|
101
|
+
body: string | undefined,
|
|
102
|
+
target_chains: ReadonlyArray<ReadonlyArray<number>>,
|
|
103
|
+
): { body: string } | { error: string } {
|
|
104
|
+
return git_epic_add_body.rewrite_body({
|
|
105
|
+
body: body ?? '',
|
|
106
|
+
placed: [],
|
|
107
|
+
position: undefined,
|
|
108
|
+
chains_after: target_chains,
|
|
109
|
+
decision: undefined,
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// The two-directional difference between what the body declares and what the relations record, with
|
|
114
|
+
// the chains the body already carries. `declare` are relations recorded but never declared; `record`
|
|
115
|
+
// are orders declared but never recorded.
|
|
116
|
+
interface Mismatch {
|
|
117
|
+
chains_before: ReadonlyArray<ReadonlyArray<number>>
|
|
118
|
+
declare: ReadonlyArray<DependencyLink>
|
|
119
|
+
record: ReadonlyArray<DependencyLink>
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function read_mismatch(input: ReconcilePlanInput): Mismatch {
|
|
123
|
+
const chains_before = git_epic_parse.parse_dependency_chains(input.body)
|
|
124
|
+
const declared = git_epic_chains.links_of(chains_before)
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
chains_before,
|
|
128
|
+
declare: epic_graph.undeclared_relations(declared, input.recorded, input.repo),
|
|
129
|
+
record: epic_graph.missing_relations(declared, input.recorded, input.repo),
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The reconciliation for a non-empty mismatch: refuse a cycle, record alone when only relations are
|
|
134
|
+
// missing, and otherwise rewrite the body to declare the union order.
|
|
135
|
+
function to_reconciled_plan(input: ReconcilePlanInput, mismatch: Mismatch): ReconcilePlan {
|
|
136
|
+
const declared_chains = mismatch.declare.map((link) => to_chain(link))
|
|
137
|
+
const target_chains = [...mismatch.chains_before, ...declared_chains]
|
|
138
|
+
const cycle = find_cycle(git_epic_chains.links_of(target_chains), input.repo)
|
|
139
|
+
if (cycle !== undefined) return { kind: 'cycle', message: cycle }
|
|
140
|
+
|
|
141
|
+
const { declare, record } = mismatch
|
|
142
|
+
|
|
143
|
+
if (declare.length === 0) {
|
|
144
|
+
return { kind: 'reconciled', reconciliation: { body: undefined, declare, record } }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const rewritten = to_reconciled_body(input.body, target_chains)
|
|
148
|
+
if ('error' in rewritten) return { kind: 'error', error: rewritten.error }
|
|
149
|
+
|
|
150
|
+
return { kind: 'reconciled', reconciliation: { body: rewritten.body, declare, record } }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function build_reconcile_plan(input: ReconcilePlanInput): ReconcilePlan {
|
|
154
|
+
const mismatch = read_mismatch(input)
|
|
155
|
+
if (mismatch.declare.length === 0 && mismatch.record.length === 0) return { kind: 'nothing' }
|
|
156
|
+
|
|
157
|
+
return to_reconciled_plan(input, mismatch)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// The one line the acceptance asks the repair to state itself: after this, the two readers that
|
|
161
|
+
// refused the mismatched epic agree on its order.
|
|
162
|
+
function report_agreement(epic_number: number): void {
|
|
163
|
+
console.info(
|
|
164
|
+
`${RECONCILED} #${String(epic_number)} — epic:audit and backlog:next now agree on this epic's order.`,
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function report_declared(epic_number: number, declare: ReadonlyArray<DependencyLink>): void {
|
|
169
|
+
if (declare.length === 0) return
|
|
170
|
+
|
|
171
|
+
console.info(
|
|
172
|
+
`📋 Declared ${format_dependency_links(declare)} in epic #${String(epic_number)} to match the recorded relations.`,
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async function record_relations(record: ReadonlyArray<DependencyLink>): Promise<void> {
|
|
177
|
+
if (record.length === 0) return
|
|
178
|
+
|
|
179
|
+
const failures = await git_epic_relations.apply_relations(record, 'record')
|
|
180
|
+
|
|
181
|
+
console.info(
|
|
182
|
+
git_epic_relations.format_relation_report({ links: record, failures, action: 'record' }),
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async function apply_reconciliation(
|
|
187
|
+
epic_number: number,
|
|
188
|
+
reconciliation: Reconciliation,
|
|
189
|
+
): Promise<number> {
|
|
190
|
+
if (reconciliation.body !== undefined) {
|
|
191
|
+
await git_gh_command.issue_edit_body(String(epic_number), reconciliation.body)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
report_declared(epic_number, reconciliation.declare)
|
|
195
|
+
await record_relations(reconciliation.record)
|
|
196
|
+
report_agreement(epic_number)
|
|
197
|
+
|
|
198
|
+
return SUCCESS_EXIT_CODE
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function apply_plan(epic_number: number, plan: ReconcilePlan): Promise<number> {
|
|
202
|
+
if (plan.kind === 'nothing') {
|
|
203
|
+
console.info(NOTHING_TO_RECONCILE)
|
|
204
|
+
|
|
205
|
+
return SUCCESS_EXIT_CODE
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (plan.kind === 'reconciled') {
|
|
209
|
+
return await apply_reconciliation(epic_number, plan.reconciliation)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
console.error(`✖ ${plan.kind === 'cycle' ? plan.message : plan.error}`)
|
|
213
|
+
|
|
214
|
+
return FAILURE_EXIT_CODE
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Reconcile an epic's declaration with its recorded relations, or refuse without writing anything.
|
|
218
|
+
// Every refusal — an unreadable epic, an unreadable graph, a cycle — happens before the body edit,
|
|
219
|
+
// so a rejected invocation leaves the epic exactly as it was.
|
|
220
|
+
async function reconcile_epic(epic_number: number): Promise<number> {
|
|
221
|
+
const epic = await git_epic_read.read_epic(epic_number)
|
|
222
|
+
|
|
223
|
+
if ('error' in epic) {
|
|
224
|
+
console.error(`✖ ${epic.error}`)
|
|
225
|
+
|
|
226
|
+
return FAILURE_EXIT_CODE
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const plan = build_reconcile_plan({
|
|
230
|
+
body: epic.subject.body,
|
|
231
|
+
recorded: epic.recorded,
|
|
232
|
+
repo: epic.repo,
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
return await apply_plan(epic_number, plan)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const git_epic_reconcile = {
|
|
239
|
+
NOTHING_TO_RECONCILE,
|
|
240
|
+
RECONCILED,
|
|
241
|
+
build_reconcile_plan,
|
|
242
|
+
reconcile_epic,
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export { git_epic_reconcile }
|
|
246
|
+
export type { ReconcilePlan, ReconcilePlanInput, Reconciliation }
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { DependencyLink } from './git-epic-parse'
|
|
2
|
+
|
|
3
|
+
// How an issue and a dependency between two of them are written down.
|
|
4
|
+
//
|
|
5
|
+
// Both spellings had accumulated a copy per module — the body generator, the graph, the chain model
|
|
6
|
+
// and the insertion planner each rendered `#N` and `#B -> #M` themselves. They are one-liners, which
|
|
7
|
+
// is exactly why the copies spread; and a link rendered one way in a message and another way as a
|
|
8
|
+
// dedup key is a difference nothing would report (joshuafolkken/kit#890).
|
|
9
|
+
|
|
10
|
+
const DEPENDENCY_ARROW = ' -> '
|
|
11
|
+
// How a list of references is written out. One definition rather than a `join` per caller: the
|
|
12
|
+
// repository-aware list in `epic-graph` renders the same kind of list from a different element type,
|
|
13
|
+
// and two separators would let the two disagree over something a reader reads side by side.
|
|
14
|
+
const REFERENCE_SEPARATOR = ', '
|
|
15
|
+
|
|
16
|
+
// An issue named from outside any one graph — a task-list row, a citation in prose, a blocker
|
|
17
|
+
// relation, a child that could not be read. Repository **and** number, because a number alone cannot
|
|
18
|
+
// identify one: issue numbers are unique per repository, so the same `#40` names two different issues
|
|
19
|
+
// depending on who wrote it (joshuafolkken/kit#1014).
|
|
20
|
+
//
|
|
21
|
+
// It lives here rather than in `epic-graph` because the `blocked-by` relations are read in the git
|
|
22
|
+
// layer and carry a repository of their own (joshuafolkken/kit#1126) — a second declaration there
|
|
23
|
+
// would be the clone `CLAUDE.md` prohibits, and an import the other way would point the lower layer
|
|
24
|
+
// at the higher one. `epic-graph` re-exports it, so every existing importer is unchanged.
|
|
25
|
+
//
|
|
26
|
+
// `state` is present only on a reference read from a `blocked-by` relation whose response carried it
|
|
27
|
+
// (joshuafolkken/kit#1943). The classifier needs it for a blocker no named graph tracks, where there is
|
|
28
|
+
// no child record to read the state from; every other reference leaves it out.
|
|
29
|
+
interface IssueReference {
|
|
30
|
+
repo: string
|
|
31
|
+
number: number
|
|
32
|
+
state?: 'OPEN' | 'CLOSED'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function to_issue_reference(issue_number: number): string {
|
|
36
|
+
return `#${String(issue_number)}`
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function format_dependency_link(link: DependencyLink): string {
|
|
40
|
+
return `${to_issue_reference(link.blocker)}${DEPENDENCY_ARROW}${to_issue_reference(link.blocked)}`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function join_references(references: ReadonlyArray<string>): string {
|
|
44
|
+
return references.join(REFERENCE_SEPARATOR)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// A list of links, in the same form a single one takes. One definition rather than a `map().join()`
|
|
48
|
+
// per caller: the insertion planner and the relation reporter now print the same list side by side,
|
|
49
|
+
// and two spellings of it would read as two different things (joshuafolkken/kit#1080).
|
|
50
|
+
function format_dependency_links(links: ReadonlyArray<DependencyLink>): string {
|
|
51
|
+
return join_references(links.map((link) => format_dependency_link(link)))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function format_issue_references(issue_numbers: ReadonlyArray<number>): string {
|
|
55
|
+
return join_references(issue_numbers.map((issue_number) => to_issue_reference(issue_number)))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The `blocked-by` relations a positioned `--add` dropped, named the same way wherever they are
|
|
59
|
+
// reported — on stdout and inside the `--decision-file` record (joshuafolkken/kit#1711). One string
|
|
60
|
+
// rather than two, because the two are read side by side: a reader comparing the console against the
|
|
61
|
+
// record must not have to decide whether two spellings mean the same thing.
|
|
62
|
+
//
|
|
63
|
+
// **Each chain is backticked, never bare and never several to a span.** A line that is *nothing but*
|
|
64
|
+
// `#A -> #B` is read as a dependency declaration anywhere in an epic body — which is what
|
|
65
|
+
// `find_decision_error` refuses a record for — and the `## Decisions` section is parsed with the rest
|
|
66
|
+
// of the body. The label in front already keeps this line out of that pattern; the backticks are what
|
|
67
|
+
// keeps it out if the label is ever reworded. One span **per link** rather than one around the list,
|
|
68
|
+
// because a relocation drops two at once and a single span holding `#890 -> #891, #891 -> #892` reads
|
|
69
|
+
// as one malformed chain in the artifact this line exists to leave behind.
|
|
70
|
+
function format_replaced_relations(links: ReadonlyArray<DependencyLink>): string {
|
|
71
|
+
const quoted = links.map((link) => `\`${format_dependency_link(link)}\``)
|
|
72
|
+
|
|
73
|
+
return `Replaced blocked-by: ${join_references(quoted)}.`
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const git_epic_reference = {
|
|
77
|
+
DEPENDENCY_ARROW,
|
|
78
|
+
REFERENCE_SEPARATOR,
|
|
79
|
+
to_issue_reference,
|
|
80
|
+
join_references,
|
|
81
|
+
format_dependency_link,
|
|
82
|
+
format_dependency_links,
|
|
83
|
+
format_issue_references,
|
|
84
|
+
format_replaced_relations,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export type { IssueReference }
|
|
88
|
+
export {
|
|
89
|
+
git_epic_reference,
|
|
90
|
+
DEPENDENCY_ARROW,
|
|
91
|
+
REFERENCE_SEPARATOR,
|
|
92
|
+
to_issue_reference,
|
|
93
|
+
join_references,
|
|
94
|
+
format_dependency_link,
|
|
95
|
+
format_dependency_links,
|
|
96
|
+
format_issue_references,
|
|
97
|
+
format_replaced_relations,
|
|
98
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { DependencyLink } from './git-epic-parse'
|
|
2
|
+
import { format_dependency_links } from './git-epic-reference'
|
|
3
|
+
import { git_gh_command } from './git-gh-command'
|
|
4
|
+
|
|
5
|
+
// Recording and dropping the native `blocked-by` relations an epic's declared order implies.
|
|
6
|
+
//
|
|
7
|
+
// The relation is a nicety, not part of the contract: losing it costs only the native link, while
|
|
8
|
+
// the Issue and its task list are already correct. A failure is therefore counted and reported
|
|
9
|
+
// rather than aborting a batch that is otherwise fine. It no longer depends on the gh CLI's version
|
|
10
|
+
// — the relation is written through the REST dependencies endpoint (joshuafolkken/kit#1026).
|
|
11
|
+
//
|
|
12
|
+
// Shared by epic creation and `--add` rather than written once per caller: both apply the same
|
|
13
|
+
// relations for the same reason, and a second copy would be the place a fix is forgotten
|
|
14
|
+
// (joshuafolkken/kit#890).
|
|
15
|
+
|
|
16
|
+
type RelationAction = 'record' | 'drop'
|
|
17
|
+
|
|
18
|
+
async function apply_one(link: DependencyLink, action: RelationAction): Promise<boolean> {
|
|
19
|
+
const blocked = String(link.blocked)
|
|
20
|
+
const blocker = String(link.blocker)
|
|
21
|
+
|
|
22
|
+
return action === 'record'
|
|
23
|
+
? await git_gh_command.issue_add_blocked_by(blocked, blocker)
|
|
24
|
+
: await git_gh_command.issue_remove_blocked_by(blocked, blocker)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// How many of the relations could not be applied. Applied concurrently, as epic creation already
|
|
28
|
+
// does: they are independent edits on different issues.
|
|
29
|
+
async function apply_relations(
|
|
30
|
+
links: ReadonlyArray<DependencyLink>,
|
|
31
|
+
action: RelationAction,
|
|
32
|
+
): Promise<number> {
|
|
33
|
+
if (links.length === 0) return 0
|
|
34
|
+
|
|
35
|
+
const applied = await Promise.all(links.map(async (link) => await apply_one(link, action)))
|
|
36
|
+
|
|
37
|
+
return applied.filter((is_applied) => !is_applied).length
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function describe_action(action: RelationAction): string {
|
|
41
|
+
return action === 'record' ? 'recorded' : 'removed'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// What happened, and to which pairs. The count used to stand on its own, and a count cannot be
|
|
45
|
+
// checked: an insertion that recorded an order nobody declared printed the same
|
|
46
|
+
// `1 blocked-by relation(s) recorded.` as a correct one, so the invented chains of
|
|
47
|
+
// joshuafolkken/kit#1080 were caught only by whoever thought to open the epic body afterwards. The
|
|
48
|
+
// links are named in the `#blocker -> #blocked` form the declaration itself uses, so the reader
|
|
49
|
+
// compares like with like.
|
|
50
|
+
//
|
|
51
|
+
// The failure line still carries no list: `apply_relations` reports how many writes failed and not
|
|
52
|
+
// which, so naming the whole set there would assert more than is known.
|
|
53
|
+
function format_relation_report(input: {
|
|
54
|
+
links: ReadonlyArray<DependencyLink>
|
|
55
|
+
failures: number
|
|
56
|
+
action: RelationAction
|
|
57
|
+
}): string {
|
|
58
|
+
const verb = describe_action(input.action)
|
|
59
|
+
const total = String(input.links.length)
|
|
60
|
+
|
|
61
|
+
// Nothing to name. Every caller already skips the report on an empty list, but the invariant
|
|
62
|
+
// belongs with the message rather than with each of them.
|
|
63
|
+
if (input.links.length === 0) return `🔗 No blocked-by relation was ${verb}.`
|
|
64
|
+
|
|
65
|
+
if (input.failures === 0) {
|
|
66
|
+
return `🔗 ${total} blocked-by relation(s) ${verb}: ${format_dependency_links(input.links)}.`
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return `⚠️ ${String(input.failures)} of ${total} blocked-by relation(s) could not be ${verb}; the epic body is intact.`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const git_epic_relations = {
|
|
73
|
+
apply_relations,
|
|
74
|
+
format_relation_report,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export { git_epic_relations }
|
|
78
|
+
export type { RelationAction }
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { epic_graph, type EpicChild } from '#scripts/epic/epic-graph'
|
|
2
|
+
import { git_epic_add_body, type RewriteOutcome } from './git-epic-add-body'
|
|
3
|
+
import { git_epic_chains } from './git-epic-chains'
|
|
4
|
+
import { git_epic_decision } from './git-epic-decision'
|
|
5
|
+
import { chain_links, git_epic_parse, type DependencyLink } from './git-epic-parse'
|
|
6
|
+
import { format_dependency_link, format_dependency_links } from './git-epic-reference'
|
|
7
|
+
import { git_epic_shape } from './git-epic-shape'
|
|
8
|
+
|
|
9
|
+
// Everything `josh epic --remove` decides before it writes anything.
|
|
10
|
+
//
|
|
11
|
+
// A declared order lives in two places at once — the epic body's `Dependencies` declaration and the
|
|
12
|
+
// native `blocked-by` relations — and until this command there was no way to delete one from both at
|
|
13
|
+
// once. The only route was the hand edit `CLAUDE.md` forbids plus a bare `DELETE` on the
|
|
14
|
+
// dependencies endpoint, and doing either half alone leaves `epic:next` answering
|
|
15
|
+
// `declaration_mismatch`, which stops an unattended run. Epic joshuafolkken/kit#1262 recorded
|
|
16
|
+
// twenty-nine such removals before the command existed (joshuafolkken/kit#1712).
|
|
17
|
+
//
|
|
18
|
+
// Kept apart from the GitHub calls for the reason `git-epic-add-plan.ts` is: the whole decision is
|
|
19
|
+
// asserted without a network, and a refusal path only reachable through `gh` is one nobody tests.
|
|
20
|
+
|
|
21
|
+
// The path whose consecutive pairs name the orders to delete. `--remove <E> 101 102 103` deletes
|
|
22
|
+
// `#101 -> #102` and `#102 -> #103`, which is the shape a declared chain is written in — so removing
|
|
23
|
+
// a whole chain is one invocation rather than one per link.
|
|
24
|
+
interface RemovePlanInput {
|
|
25
|
+
epic_number: number
|
|
26
|
+
body: string | undefined
|
|
27
|
+
labels: ReadonlyArray<string>
|
|
28
|
+
path: ReadonlyArray<number>
|
|
29
|
+
// The epic's current children with their native relations, as `epic:next` reads them.
|
|
30
|
+
recorded: ReadonlyArray<EpicChild>
|
|
31
|
+
repo: string
|
|
32
|
+
// The record `--decision-file` supplied, or `undefined`. It says why the order was deleted, and it
|
|
33
|
+
// reaches the epic's `## Decisions` and both ends of every deleted order.
|
|
34
|
+
decision?: string | undefined
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface RemovePlan {
|
|
38
|
+
body: string
|
|
39
|
+
// Every order deleted from the declaration — what the report names.
|
|
40
|
+
links: ReadonlyArray<DependencyLink>
|
|
41
|
+
// The subset of them a native relation actually backs, which is what there is to drop.
|
|
42
|
+
removed: ReadonlyArray<DependencyLink>
|
|
43
|
+
// The children a decision record is posted on: both ends of every deleted order.
|
|
44
|
+
ends: ReadonlyArray<number>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type RemoveOutcome = { plan: RemovePlan } | { error: string }
|
|
48
|
+
|
|
49
|
+
const MINIMUM_PATH_LENGTH = 2
|
|
50
|
+
|
|
51
|
+
// The consecutive pairs of the path, as links. `chain_links` rather than a second walk of its own:
|
|
52
|
+
// what the caller typed is a chain, and it must be read exactly as a declared one is.
|
|
53
|
+
function to_path_links(path: ReadonlyArray<number>): Array<DependencyLink> {
|
|
54
|
+
return chain_links(path)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function find_path_error(path: ReadonlyArray<number>): string | undefined {
|
|
58
|
+
if (path.length < MINIMUM_PATH_LENGTH) {
|
|
59
|
+
return 'Two issue numbers are required after the epic: the order to remove is `<M> <N>`, and a longer list removes each consecutive pair.'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return to_path_links(path).length === path.length - 1
|
|
63
|
+
? undefined
|
|
64
|
+
: 'The path names the same issue twice in a row, which declares no order.'
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// A link the declaration does not name. Refused rather than passed through as a no-op: the caller
|
|
68
|
+
// believes an order exists, and answering "done" to a removal that removed nothing is how a false
|
|
69
|
+
// order survives the one command written to delete it.
|
|
70
|
+
function find_undeclared_error(
|
|
71
|
+
links: ReadonlyArray<DependencyLink>,
|
|
72
|
+
chains: ReadonlyArray<ReadonlyArray<number>>,
|
|
73
|
+
): string | undefined {
|
|
74
|
+
const declared = new Set(
|
|
75
|
+
git_epic_chains.links_of(chains).map((link) => format_dependency_link(link)),
|
|
76
|
+
)
|
|
77
|
+
const missing = links.filter((link) => !declared.has(format_dependency_link(link)))
|
|
78
|
+
|
|
79
|
+
return missing.length === 0
|
|
80
|
+
? undefined
|
|
81
|
+
: `The declared dependency order does not name ${format_dependency_links(missing)}; there is nothing to remove.`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// A decision record that cannot be written is refused here rather than dropped, exactly as it is for
|
|
85
|
+
// an insertion: `--decision-file` was given because the record has to exist.
|
|
86
|
+
function find_decision_error(decision: string | undefined): string | undefined {
|
|
87
|
+
return decision === undefined ? undefined : git_epic_decision.find_decision_error(decision)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function find_input_error(
|
|
91
|
+
input: RemovePlanInput,
|
|
92
|
+
tracked: ReadonlyArray<number>,
|
|
93
|
+
chains: ReadonlyArray<ReadonlyArray<number>>,
|
|
94
|
+
): string | undefined {
|
|
95
|
+
return (
|
|
96
|
+
git_epic_shape.find_subject_error(input, tracked) ??
|
|
97
|
+
find_path_error(input.path) ??
|
|
98
|
+
find_undeclared_error(to_path_links(input.path), chains) ??
|
|
99
|
+
find_decision_error(input.decision)
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function to_ends(links: ReadonlyArray<DependencyLink>): Array<number> {
|
|
104
|
+
return [...new Set(links.flatMap((link) => [link.blocker, link.blocked]))]
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// The rewrite is the insertion's, with nothing placed: a removal touches the declaration and never
|
|
108
|
+
// the task list, so the children stay exactly where they are and only the arrows go. What it does
|
|
109
|
+
// have to say is `does_clear_declaration` — deleting the last link means writing that there is no
|
|
110
|
+
// order rather than leaving the deleted chain in place.
|
|
111
|
+
function to_body(
|
|
112
|
+
input: RemovePlanInput,
|
|
113
|
+
chains_after: ReadonlyArray<ReadonlyArray<number>>,
|
|
114
|
+
): RewriteOutcome {
|
|
115
|
+
return git_epic_add_body.rewrite_body({
|
|
116
|
+
body: input.body ?? '',
|
|
117
|
+
placed: [],
|
|
118
|
+
chains_after,
|
|
119
|
+
decision: input.decision,
|
|
120
|
+
does_clear_declaration: true,
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function build_removal_plan(input: RemovePlanInput): RemoveOutcome {
|
|
125
|
+
const tracked = git_epic_parse.parse_task_list_issue_numbers(input.body)
|
|
126
|
+
const chains_before = git_epic_parse.parse_dependency_chains(input.body)
|
|
127
|
+
const error = find_input_error(input, tracked, chains_before)
|
|
128
|
+
if (error !== undefined) return { error }
|
|
129
|
+
|
|
130
|
+
const links = to_path_links(input.path)
|
|
131
|
+
const chains_after = git_epic_chains.remove_links(chains_before, links)
|
|
132
|
+
const rewritten = to_body(input, chains_after)
|
|
133
|
+
if ('error' in rewritten) return { error: rewritten.error }
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
plan: {
|
|
137
|
+
body: rewritten.body,
|
|
138
|
+
links,
|
|
139
|
+
// Only the links a relation actually backs: asking `gh` to remove one that was never
|
|
140
|
+
// recorded is reported as a failure the user cannot act on.
|
|
141
|
+
removed: epic_graph.recorded_relations(links, input.recorded, input.repo),
|
|
142
|
+
ends: to_ends(links),
|
|
143
|
+
},
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const git_epic_remove_plan = {
|
|
148
|
+
build_removal_plan,
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export { git_epic_remove_plan }
|
|
152
|
+
export type { RemovePlan, RemovePlanInput, RemoveOutcome }
|