@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,158 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { parseArgs } from 'node:util'
|
|
4
|
+
import { git_gh_command } from '#scripts/git/git-gh-command'
|
|
5
|
+
import type { IssueRead } from '#scripts/git/git-gh-issue-read'
|
|
6
|
+
import { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
7
|
+
import { z } from 'zod'
|
|
8
|
+
import { issue_cite, type CiteTarget } from './issue-cite'
|
|
9
|
+
|
|
10
|
+
// `josh issue:cite <N> [<N> ...] [--repo <owner/repo>]` — the paste-ready citation line for every
|
|
11
|
+
// Issue named, in one call (joshuafolkken/kit#2220).
|
|
12
|
+
//
|
|
13
|
+
// It answers the cost that made the bare `#N` cheaper than the correct citation: the title each line
|
|
14
|
+
// needs used to be a per-Issue `gh api` read, and naming several Issues at once — a backlog listing, a
|
|
15
|
+
// lane status report — meant several round trips before a single correct line could be written. The
|
|
16
|
+
// numbers go in together and the titles come back together, so the correct form is now the cheap one.
|
|
17
|
+
//
|
|
18
|
+
// **A token that is not a number refuses the whole invocation**, exactly as `issue:read` does: an
|
|
19
|
+
// argument the parser cannot read is a mistake, and dropping it answers fewer Issues than were asked
|
|
20
|
+
// for while still exiting zero. **A number that resolves to nothing, or a read that failed, is named
|
|
21
|
+
// as a failure line** rather than silently missing — the reader is told which numbers have no citation
|
|
22
|
+
// instead of subtracting the printed lines from what was asked.
|
|
23
|
+
|
|
24
|
+
const SUCCESS_EXIT_CODE = 0
|
|
25
|
+
const FAILURE_EXIT_CODE = 1
|
|
26
|
+
const ARGV_OFFSET = 2
|
|
27
|
+
// The same bound `issue:read` puts on its batch read: every read is a `gh` process, and an unbounded
|
|
28
|
+
// fan-out is answered with secondary rate limiting rather than with titles.
|
|
29
|
+
const READ_CONCURRENCY = 8
|
|
30
|
+
const TITLE_FIELD = 'title'
|
|
31
|
+
const LINE_SEPARATOR = '\n'
|
|
32
|
+
const USAGE = 'Usage: josh issue:cite <issue-number|owner/repo#N> [ ... ] [--repo <owner/repo>]'
|
|
33
|
+
|
|
34
|
+
const title_schema = z.looseObject({ title: z.string() })
|
|
35
|
+
|
|
36
|
+
type LineResult = { kind: 'ok'; line: string } | { kind: 'fail'; line: string }
|
|
37
|
+
|
|
38
|
+
// The title out of the one-field read, or `undefined` for an empty or unparseable one — an empty title
|
|
39
|
+
// is not a summary, so it is reported as a read that produced nothing rather than cited as a blank.
|
|
40
|
+
function parse_title(json: string): string | undefined {
|
|
41
|
+
try {
|
|
42
|
+
const title = title_schema.parse(JSON.parse(json)).title.trim()
|
|
43
|
+
|
|
44
|
+
return title === '' ? undefined : title
|
|
45
|
+
} catch {
|
|
46
|
+
return undefined
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// A read's outcome as one line: the citation on success, the matching failure line otherwise. The
|
|
51
|
+
// classification is the reader's own — `missing` will not change on a retry, `unreadable` may.
|
|
52
|
+
function to_line(target: CiteTarget, slug: string, read: IssueRead): LineResult {
|
|
53
|
+
if (read.kind === 'missing') return { kind: 'fail', line: issue_cite.missing_line(target) }
|
|
54
|
+
if (read.kind !== 'read') return { kind: 'fail', line: issue_cite.unreadable_line(target) }
|
|
55
|
+
|
|
56
|
+
const title = parse_title(read.json)
|
|
57
|
+
if (title === undefined) return { kind: 'fail', line: issue_cite.unreadable_line(target) }
|
|
58
|
+
|
|
59
|
+
return { kind: 'ok', line: issue_cite.citation_line(slug, target.number, title) }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// The repository the link names: the target's own when it is qualified, the local one otherwise. A
|
|
63
|
+
// bare number with no local repository has no link to build, so it fails rather than citing a
|
|
64
|
+
// repository it could not read.
|
|
65
|
+
async function cite_target(
|
|
66
|
+
target: CiteTarget,
|
|
67
|
+
local_slug: string | undefined,
|
|
68
|
+
): Promise<LineResult> {
|
|
69
|
+
const slug = target.repo ?? local_slug
|
|
70
|
+
if (slug === undefined) return { kind: 'fail', line: issue_cite.no_repo_line(target) }
|
|
71
|
+
|
|
72
|
+
const read = await git_gh_command.issue_view_json_classified(
|
|
73
|
+
target.number,
|
|
74
|
+
TITLE_FIELD,
|
|
75
|
+
target.repo,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return to_line(target, slug, read)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Every positional as a target, or `undefined` if any one of them is not a number — the invocation is
|
|
82
|
+
// refused whole so a mistyped argument never silently loses its citation.
|
|
83
|
+
function parse_targets(
|
|
84
|
+
positionals: ReadonlyArray<string>,
|
|
85
|
+
default_repo: string | undefined,
|
|
86
|
+
): ReadonlyArray<CiteTarget> | undefined {
|
|
87
|
+
const targets: Array<CiteTarget> = []
|
|
88
|
+
|
|
89
|
+
for (const token of positionals) {
|
|
90
|
+
const target = issue_cite.parse_target(token, default_repo)
|
|
91
|
+
if (target === undefined) return undefined
|
|
92
|
+
targets.push(target)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return targets.length === 0 ? undefined : targets
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// The local `owner/repo`, read once and only when a bare target needs it: a run that names every
|
|
99
|
+
// target with a repository never makes the request.
|
|
100
|
+
async function local_slug_for(targets: ReadonlyArray<CiteTarget>): Promise<string | undefined> {
|
|
101
|
+
const has_bare_target = targets.some((target) => target.repo === undefined)
|
|
102
|
+
|
|
103
|
+
return has_bare_target ? await git_gh_command.repo_get_name_with_owner() : undefined
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Citations to stdout so the block stays paste-ready; failures to stderr so each unanswered number is
|
|
107
|
+
// named without landing in what gets pasted. A failure sets a non-zero exit.
|
|
108
|
+
function report(results: ReadonlyArray<LineResult>): number {
|
|
109
|
+
const lines = results.filter((result) => result.kind === 'ok').map((result) => result.line)
|
|
110
|
+
const failures = results.filter((result) => result.kind === 'fail').map((result) => result.line)
|
|
111
|
+
|
|
112
|
+
if (lines.length > 0) console.info(lines.join(LINE_SEPARATOR))
|
|
113
|
+
for (const failure of failures) console.error(failure)
|
|
114
|
+
|
|
115
|
+
return failures.length === 0 ? SUCCESS_EXIT_CODE : FAILURE_EXIT_CODE
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function run(args: ReadonlyArray<string>): Promise<number> {
|
|
119
|
+
const parsed = parseArgs({
|
|
120
|
+
args: [...args],
|
|
121
|
+
options: { repo: { type: 'string' } },
|
|
122
|
+
allowPositionals: true,
|
|
123
|
+
})
|
|
124
|
+
const targets = parse_targets(parsed.positionals, parsed.values.repo)
|
|
125
|
+
|
|
126
|
+
if (targets === undefined) {
|
|
127
|
+
console.error(USAGE)
|
|
128
|
+
|
|
129
|
+
return FAILURE_EXIT_CODE
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const local_slug = await local_slug_for(targets)
|
|
133
|
+
const results = await bounded_pool.bounded_map(
|
|
134
|
+
targets,
|
|
135
|
+
READ_CONCURRENCY,
|
|
136
|
+
async (target) => await cite_target(target, local_slug),
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
return report(results)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function main(args: ReadonlyArray<string>): Promise<void> {
|
|
143
|
+
process.exitCode = await run(args)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const issue_cite_cli = {
|
|
147
|
+
USAGE,
|
|
148
|
+
main,
|
|
149
|
+
parse_targets,
|
|
150
|
+
parse_title,
|
|
151
|
+
report,
|
|
152
|
+
run,
|
|
153
|
+
to_line,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
157
|
+
|
|
158
|
+
export { issue_cite_cli }
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// The paste-ready citation line `josh issue:cite` prints, kept apart from the reading and the
|
|
2
|
+
// printing so the shape of the line is decided by one pure function (joshuafolkken/kit#2220).
|
|
3
|
+
//
|
|
4
|
+
// **It exists because the correct citation form has a cost the bare `#N` does not.** `CLAUDE.md` and
|
|
5
|
+
// `prompts/collaboration-workflow/issue-citation.md` require session-facing output to cite an Issue
|
|
6
|
+
// as `[#<N>](https://github.com/<owner>/<repo>/issues/<N>) — <summary>`, and assembling that by hand
|
|
7
|
+
// means reading each Issue's title first — a per-Issue round trip that lands exactly where several
|
|
8
|
+
// Issues are named at once (a backlog listing, a lane status report), which is where the bare `#N`
|
|
9
|
+
// falls out. This command makes the cheap path and the correct path the same one.
|
|
10
|
+
//
|
|
11
|
+
// **The summary is the Issue's own title, fetched, not a translation of it.** A script cannot
|
|
12
|
+
// translate deterministically, and an LLM call per Issue would defeat the point of a cheap citation
|
|
13
|
+
// helper and make the output untestable; the title already says what the Issue does, which is all the
|
|
14
|
+
// rule asks of the summary — knowing what it does is enough. The reader adapts it to the session
|
|
15
|
+
// language when it matters, without the round trip that used to be needed to learn the title at all.
|
|
16
|
+
|
|
17
|
+
const GITHUB_URL_PREFIX = 'https://github.com/'
|
|
18
|
+
const ISSUE_PATH = '/issues/'
|
|
19
|
+
const SUMMARY_SEPARATOR = ' — '
|
|
20
|
+
|
|
21
|
+
// `owner/repo#N`, so a citation can name another repository's Issue; the two segment classes exclude a
|
|
22
|
+
// slash and a `#` so the split between the repository and the number is unambiguous.
|
|
23
|
+
const REPO_QUALIFIED = /^([^\s/#]+\/[^\s/#]+)#(\d+)$/u
|
|
24
|
+
// A bare number, with the `#` optional: the source is usually a `#N` copied out of prose, and refusing
|
|
25
|
+
// the `#` would make the command reject exactly what it exists to correct.
|
|
26
|
+
const BARE_NUMBER = /^#?(\d+)$/u
|
|
27
|
+
|
|
28
|
+
// `repo` is `owner/repo`, or `undefined` for the repository the command runs in — the same contract
|
|
29
|
+
// the reads underneath take, so a bare number and a qualified one flow through one path.
|
|
30
|
+
interface CiteTarget {
|
|
31
|
+
number: string
|
|
32
|
+
repo: string | undefined
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function issue_url(slug: string, number: string): string {
|
|
36
|
+
return `${GITHUB_URL_PREFIX}${slug}${ISSUE_PATH}${number}`
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function citation_line(slug: string, number: string, summary: string): string {
|
|
40
|
+
return `[#${number}](${issue_url(slug, number)})${SUMMARY_SEPARATOR}${summary}`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function qualified_target(token: string): CiteTarget | undefined {
|
|
44
|
+
const match = REPO_QUALIFIED.exec(token)
|
|
45
|
+
if (match === null) return undefined
|
|
46
|
+
|
|
47
|
+
const [, repo = '', number = ''] = match
|
|
48
|
+
|
|
49
|
+
return { number, repo }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function bare_target(token: string, default_repo: string | undefined): CiteTarget | undefined {
|
|
53
|
+
const match = BARE_NUMBER.exec(token)
|
|
54
|
+
if (match === null) return undefined
|
|
55
|
+
|
|
56
|
+
const [, number = ''] = match
|
|
57
|
+
|
|
58
|
+
return { number, repo: default_repo }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// `undefined` for a token that is neither a bare number nor an `owner/repo#N` — the caller refuses the
|
|
62
|
+
// whole invocation rather than dropping it, so a mistyped argument never silently loses its citation.
|
|
63
|
+
function parse_target(token: string, default_repo: string | undefined): CiteTarget | undefined {
|
|
64
|
+
return qualified_target(token) ?? bare_target(token, default_repo)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// How a target is named in a failure line: `owner/repo#N` when it names another repository, `#N`
|
|
68
|
+
// otherwise — the form the reader typed, so the line points back at the argument it is about.
|
|
69
|
+
function label(target: CiteTarget): string {
|
|
70
|
+
return target.repo === undefined ? `#${target.number}` : `${target.repo}#${target.number}`
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// A number that resolves to nothing, told apart from a read that failed: this one will not change on a
|
|
74
|
+
// retry, so it names the number and the repository rather than suggesting a wait.
|
|
75
|
+
function missing_line(target: CiteTarget): string {
|
|
76
|
+
return `✖ ${label(target)}: issue does not resolve — check the number and the repository`
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// A read that failed over something the number is not responsible for — a rate limit, expired auth, a
|
|
80
|
+
// dropped connection — so the same call a moment later may succeed.
|
|
81
|
+
function unreadable_line(target: CiteTarget): string {
|
|
82
|
+
return `✖ ${label(target)}: could not be read — a rate limit, expired auth, or a dropped connection`
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// The repository itself could not be read, so a bare number has no `owner/repo` to build a link from.
|
|
86
|
+
function no_repo_line(target: CiteTarget): string {
|
|
87
|
+
return `✖ ${label(target)}: could not read this repository — check gh auth and the origin remote`
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const issue_cite = {
|
|
91
|
+
SUMMARY_SEPARATOR,
|
|
92
|
+
citation_line,
|
|
93
|
+
issue_url,
|
|
94
|
+
label,
|
|
95
|
+
missing_line,
|
|
96
|
+
no_repo_line,
|
|
97
|
+
parse_target,
|
|
98
|
+
unreadable_line,
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export type { CiteTarget }
|
|
102
|
+
export { issue_cite }
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { git_gh_command } from '#scripts/git/git-gh-command'
|
|
4
|
+
import { cli_body } from '#scripts/josh/cli-body'
|
|
5
|
+
|
|
6
|
+
// `josh issue:comment <N> --body <text> | --body-file <path>` — post one comment to an issue (a PR
|
|
7
|
+
// comment is an issue comment over REST) and print the comment URL (joshuafolkken/kit#2304).
|
|
8
|
+
//
|
|
9
|
+
// **The write side had no command, so every park, decision record and plan comment fell to a raw
|
|
10
|
+
// `gh api … body=@<path>`.** The read side already had `issue:read` / `issue:state` / `issue:cite` /
|
|
11
|
+
// `issue:scout`, but a comment was posted by hand — and `gh`'s two path spellings differ by one
|
|
12
|
+
// character: `-F` / `--field` reads the file, `-f` / `--raw-field` sends the literal `@<path>`, and
|
|
13
|
+
// `gh` exits 0 with a URL either way. One command removes the choice: the body travels by path through
|
|
14
|
+
// `cli-body.ts` (shared with `notify` / `followup`), so no shell evaluates it and the wrong-flag
|
|
15
|
+
// misfire has nowhere left to happen.
|
|
16
|
+
|
|
17
|
+
const SUCCESS_EXIT_CODE = 0
|
|
18
|
+
const FAILURE_EXIT_CODE = 1
|
|
19
|
+
const ARGV_OFFSET = 2
|
|
20
|
+
const BODY_FLAG = '--body'
|
|
21
|
+
const BODY_FILE_FLAG = '--body-file'
|
|
22
|
+
const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
|
|
23
|
+
const USAGE = `Usage: josh issue:comment <issue-number> ${BODY_FLAG} <text> | ${BODY_FILE_FLAG} <path>`
|
|
24
|
+
|
|
25
|
+
interface CommentRequest {
|
|
26
|
+
issue_number: string
|
|
27
|
+
body: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// The value after a flag word, or `undefined` when the flag is absent. `cli_body.resolve` owns the
|
|
31
|
+
// both-flags-at-once refusal and the file read, so this stays the one narrow job of finding the token.
|
|
32
|
+
function flag_value(argv: ReadonlyArray<string>, flag: string): string | undefined {
|
|
33
|
+
const index = argv.indexOf(flag)
|
|
34
|
+
|
|
35
|
+
return index === -1 ? undefined : argv[index + 1]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// The number is the first argument, and it must be a real issue number: a missing or malformed one
|
|
39
|
+
// refuses the whole call rather than posting to some other issue. `resolve` may throw when both body
|
|
40
|
+
// flags are given, which `run` reports — the message names the two flags a caller must pick between.
|
|
41
|
+
function parse_request(argv: ReadonlyArray<string>): CommentRequest | undefined {
|
|
42
|
+
const [issue_number] = argv
|
|
43
|
+
|
|
44
|
+
if (issue_number === undefined || !ISSUE_NUMBER_PATTERN.test(issue_number)) return undefined
|
|
45
|
+
|
|
46
|
+
const body = cli_body.resolve({
|
|
47
|
+
inline: flag_value(argv, BODY_FLAG),
|
|
48
|
+
file_path: flag_value(argv, BODY_FILE_FLAG),
|
|
49
|
+
inline_flag: BODY_FLAG,
|
|
50
|
+
file_flag: BODY_FILE_FLAG,
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
if (body === undefined || body.length === 0) return undefined
|
|
54
|
+
|
|
55
|
+
return { issue_number, body }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// A both-flags refusal and a file-read failure both surface as an `Error` from `resolve`, and its
|
|
59
|
+
// message already names the flags or the resolved path — so it is printed as-is and `USAGE` is
|
|
60
|
+
// withheld. `undefined` is the other refusal: a bad number or an empty body, which `USAGE` explains.
|
|
61
|
+
function resolve_request(argv: ReadonlyArray<string>): CommentRequest | undefined {
|
|
62
|
+
try {
|
|
63
|
+
const request = parse_request(argv)
|
|
64
|
+
|
|
65
|
+
if (request === undefined) console.error(USAGE)
|
|
66
|
+
|
|
67
|
+
return request
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error(error instanceof Error ? error.message : String(error))
|
|
70
|
+
|
|
71
|
+
return undefined
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
76
|
+
const request = resolve_request(argv)
|
|
77
|
+
|
|
78
|
+
if (request === undefined) return FAILURE_EXIT_CODE
|
|
79
|
+
|
|
80
|
+
const url = await git_gh_command.issue_comment(request.issue_number, request.body)
|
|
81
|
+
|
|
82
|
+
console.info(url)
|
|
83
|
+
|
|
84
|
+
return SUCCESS_EXIT_CODE
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
88
|
+
process.exitCode = await run(argv)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const issue_comment_cli = { USAGE, main, parse_request, run }
|
|
92
|
+
|
|
93
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
94
|
+
|
|
95
|
+
export { issue_comment_cli }
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { parseArgs } from 'node:util'
|
|
4
|
+
import { git_command } from '#scripts/git/git-command'
|
|
5
|
+
import { path_decision } from '#scripts/josh/path-decision'
|
|
6
|
+
import { split_assess, type SplitVerdict } from '#scripts/split/split-assess'
|
|
7
|
+
import { issue_fold, type FoldVerdict } from './issue-fold'
|
|
8
|
+
|
|
9
|
+
// `josh issue:fold "<title>" "<title>" …` — before a run files a second finding, answer whether the
|
|
10
|
+
// findings this session holds fold into one Issue (joshuafolkken/kit#2213).
|
|
11
|
+
//
|
|
12
|
+
// It is the filing-time counterpart to `split:assess`: the size half is that command's own verdict,
|
|
13
|
+
// called rather than recomputed (the counting and the guide live in `split-assess.ts`), and
|
|
14
|
+
// separability stays the judgement it is at the entry — presumed here, and overridden with
|
|
15
|
+
// `--not-separable` when the findings are really one deliverable. The verdict logic is in
|
|
16
|
+
// `issue-fold.ts`; everything here is the invocation.
|
|
17
|
+
|
|
18
|
+
const ARGV_OFFSET = 2
|
|
19
|
+
const USAGE = 'Usage: josh issue:fold "<title>" "<title>" … [--not-separable] [--json]'
|
|
20
|
+
const JSON_KEY = 'fold'
|
|
21
|
+
const FAILURE_EXIT_CODE = 1
|
|
22
|
+
|
|
23
|
+
const REASONS: Record<FoldVerdict, string> = {
|
|
24
|
+
fold: 'fold — file one Issue covering these findings; the split guide is not cleared, so they are one Issue however separable',
|
|
25
|
+
separate:
|
|
26
|
+
'separate — file these apart; they are separable and their combined size clears the split guide',
|
|
27
|
+
'no-fold-needed': 'no fold needed — a single candidate is filed on its own',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface FoldArguments {
|
|
31
|
+
titles: Array<string>
|
|
32
|
+
is_separable: boolean
|
|
33
|
+
is_json: boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function parse_arguments(argv: ReadonlyArray<string>): FoldArguments {
|
|
37
|
+
const { values, positionals } = parseArgs({
|
|
38
|
+
args: [...argv],
|
|
39
|
+
options: { json: { type: 'boolean' }, 'not-separable': { type: 'boolean' } },
|
|
40
|
+
allowPositionals: true,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
titles: positionals,
|
|
45
|
+
is_separable: values['not-separable'] !== true,
|
|
46
|
+
is_json: values.json === true,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// An unknown flag makes `parseArgs` throw. Caught so the answer is the usage line rather than a stack
|
|
51
|
+
// trace, on a command whose output a workflow reads.
|
|
52
|
+
function read_arguments(argv: ReadonlyArray<string>): FoldArguments | undefined {
|
|
53
|
+
try {
|
|
54
|
+
return parse_arguments(argv)
|
|
55
|
+
} catch {
|
|
56
|
+
return undefined
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// The size half, single-sourced from `split:assess` (joshuafolkken/kit#2183): the same counting, the
|
|
61
|
+
// same guide. A diff that cannot be read — no base, not a checkout — measures as empty, which
|
|
62
|
+
// `split_assess` reads as `single`, so an unanswerable size folds rather than tipping to `separate`.
|
|
63
|
+
async function size_verdict(): Promise<SplitVerdict> {
|
|
64
|
+
try {
|
|
65
|
+
return split_assess.assess(await git_command.diff_main_numstat()).verdict
|
|
66
|
+
} catch {
|
|
67
|
+
return split_assess.SINGLE_VERDICT
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// The size question is only asked once there is something to fold; a lone candidate is answered
|
|
72
|
+
// without measuring anything.
|
|
73
|
+
async function size_for(args: FoldArguments): Promise<SplitVerdict> {
|
|
74
|
+
if (args.titles.length < issue_fold.MIN_CANDIDATES) return split_assess.SINGLE_VERDICT
|
|
75
|
+
|
|
76
|
+
return await size_verdict()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
80
|
+
const args = read_arguments(argv)
|
|
81
|
+
|
|
82
|
+
if (args === undefined) {
|
|
83
|
+
console.error(USAGE)
|
|
84
|
+
|
|
85
|
+
return FAILURE_EXIT_CODE
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const size = await size_for(args)
|
|
89
|
+
const verdict = issue_fold.fold_verdict(args.titles.length, args.is_separable, size)
|
|
90
|
+
|
|
91
|
+
path_decision.print_decision(JSON_KEY, verdict, REASONS[verdict], args.is_json)
|
|
92
|
+
|
|
93
|
+
return 0
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
97
|
+
process.exitCode = await run(argv)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const issue_fold_cli = { JSON_KEY, USAGE, REASONS, read_arguments, size_verdict, run, main }
|
|
101
|
+
|
|
102
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
103
|
+
|
|
104
|
+
export { issue_fold_cli }
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { readFile } from 'node:fs/promises'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { z } from 'zod'
|
|
5
|
+
import { issue_fold_existing } from './issue-fold-existing'
|
|
6
|
+
|
|
7
|
+
const ARGV_OFFSET = 2
|
|
8
|
+
const FAILURE_EXIT_CODE = 1
|
|
9
|
+
const SUCCESS_EXIT_CODE = 0
|
|
10
|
+
const USAGE = 'Usage: josh issue:fold-existing <assessment.json> [--json]'
|
|
11
|
+
|
|
12
|
+
const assessment_schema = z.object({
|
|
13
|
+
content: z.enum(['duplicate', 'compatible', 'separate', 'unknown']),
|
|
14
|
+
is_open: z.boolean().optional(),
|
|
15
|
+
is_unstarted: z.boolean().optional(),
|
|
16
|
+
has_pull_request: z.boolean().optional(),
|
|
17
|
+
has_complete_read: z.boolean(),
|
|
18
|
+
has_dependency_conflict: z.boolean().optional(),
|
|
19
|
+
is_separable: z.boolean().optional(),
|
|
20
|
+
size_verdict: z.enum(['split', 'single']).optional(),
|
|
21
|
+
existing_body: z.string(),
|
|
22
|
+
draft_body: z.string().trim().min(1),
|
|
23
|
+
verification: z.string().trim().min(1),
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
function print_assessment(input: z.infer<typeof assessment_schema>, should_json: boolean): void {
|
|
27
|
+
const verdict = issue_fold_existing.decide(input)
|
|
28
|
+
const body =
|
|
29
|
+
verdict === 'fold'
|
|
30
|
+
? issue_fold_existing.append_requirements(
|
|
31
|
+
input.existing_body,
|
|
32
|
+
input.draft_body,
|
|
33
|
+
input.verification,
|
|
34
|
+
)
|
|
35
|
+
: undefined
|
|
36
|
+
|
|
37
|
+
if (should_json) {
|
|
38
|
+
console.info(JSON.stringify({ verdict, body }))
|
|
39
|
+
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.info(`Fold: ${verdict}`)
|
|
44
|
+
if (body !== undefined) console.info(body)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function assess(path: string, should_json: boolean): Promise<number> {
|
|
48
|
+
try {
|
|
49
|
+
const input = assessment_schema.parse(JSON.parse(await readFile(path, 'utf8')))
|
|
50
|
+
|
|
51
|
+
print_assessment(input, should_json)
|
|
52
|
+
|
|
53
|
+
return SUCCESS_EXIT_CODE
|
|
54
|
+
} catch {
|
|
55
|
+
console.error('Could not read a complete assessment; no fold recommendation was made.')
|
|
56
|
+
|
|
57
|
+
return FAILURE_EXIT_CODE
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
62
|
+
const [path, option, extra] = argv
|
|
63
|
+
|
|
64
|
+
if (path !== undefined && extra === undefined && (option === undefined || option === '--json')) {
|
|
65
|
+
return await assess(path, option === '--json')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
console.error(USAGE)
|
|
69
|
+
|
|
70
|
+
return FAILURE_EXIT_CODE
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
74
|
+
process.exitCode = await run(argv)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const issue_fold_existing_cli = { run, main, USAGE }
|
|
78
|
+
|
|
79
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
80
|
+
|
|
81
|
+
export { issue_fold_existing_cli }
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { SplitVerdict } from '#scripts/split/split-assess'
|
|
2
|
+
import { issue_fold } from './issue-fold'
|
|
3
|
+
|
|
4
|
+
type ExistingVerdict = 'duplicate' | 'fold' | 'separate' | 'inspect'
|
|
5
|
+
type ContentVerdict = 'duplicate' | 'compatible' | 'separate' | 'unknown'
|
|
6
|
+
const FOLD_CANDIDATE_COUNT = 2
|
|
7
|
+
|
|
8
|
+
interface ExistingAssessment {
|
|
9
|
+
content: ContentVerdict
|
|
10
|
+
is_open?: boolean | undefined
|
|
11
|
+
is_unstarted?: boolean | undefined
|
|
12
|
+
has_pull_request?: boolean | undefined
|
|
13
|
+
has_complete_read: boolean
|
|
14
|
+
has_dependency_conflict?: boolean | undefined
|
|
15
|
+
is_separable?: boolean | undefined
|
|
16
|
+
size_verdict?: SplitVerdict | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function has_unknown_facts(facts: ExistingAssessment): boolean {
|
|
20
|
+
const required = [
|
|
21
|
+
facts.is_open,
|
|
22
|
+
facts.is_unstarted,
|
|
23
|
+
facts.has_pull_request,
|
|
24
|
+
facts.has_dependency_conflict,
|
|
25
|
+
facts.is_separable,
|
|
26
|
+
facts.size_verdict,
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
return facts.content === 'unknown' || !facts.has_complete_read || required.includes(undefined)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function has_active_conflict(facts: ExistingAssessment): boolean {
|
|
33
|
+
return (
|
|
34
|
+
facts.is_open === false ||
|
|
35
|
+
facts.is_unstarted === false ||
|
|
36
|
+
facts.has_pull_request === true ||
|
|
37
|
+
facts.has_dependency_conflict === true
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function fold_or_separate(facts: ExistingAssessment): ExistingVerdict {
|
|
42
|
+
const verdict = issue_fold.fold_verdict(
|
|
43
|
+
FOLD_CANDIDATE_COUNT,
|
|
44
|
+
facts.is_separable ?? false,
|
|
45
|
+
facts.size_verdict ?? 'split',
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return verdict === issue_fold.FOLD ? 'fold' : 'separate'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function decide(facts: ExistingAssessment): ExistingVerdict {
|
|
52
|
+
if (has_unknown_facts(facts)) return 'inspect'
|
|
53
|
+
if (facts.content === 'separate') return 'separate'
|
|
54
|
+
if (facts.content === 'duplicate') return 'duplicate'
|
|
55
|
+
if (has_active_conflict(facts)) return 'separate'
|
|
56
|
+
|
|
57
|
+
return fold_or_separate(facts)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function append_requirements(
|
|
61
|
+
existing_body: string,
|
|
62
|
+
draft_body: string,
|
|
63
|
+
verification: string,
|
|
64
|
+
): string {
|
|
65
|
+
const addition = `## 追加要件\n\n${draft_body.trim()}\n\n### 検証方法\n\n${verification.trim()}`
|
|
66
|
+
|
|
67
|
+
return `${existing_body.trimEnd()}\n\n${addition}\n`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const issue_fold_existing = { decide, append_requirements }
|
|
71
|
+
|
|
72
|
+
export type { ExistingAssessment, ExistingVerdict }
|
|
73
|
+
export { issue_fold_existing }
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { split_assess, type SplitVerdict } from '#scripts/split/split-assess'
|
|
2
|
+
|
|
3
|
+
// The filing-time counterpart to the split assessment (joshuafolkken/kit#2213).
|
|
4
|
+
//
|
|
5
|
+
// `split-assessment.md` → "The question" decides whether *one request* is really several
|
|
6
|
+
// deliverables; this decides whether *several findings filed from one session* fold into one Issue or
|
|
7
|
+
// stay apart. **Both read the same two questions** — are the pieces separable, and does the whole
|
|
8
|
+
// clearly exceed what one verification gate confirms in one pass — so the criterion is single-sourced,
|
|
9
|
+
// never restated: the size half is `split_assess`'s own verdict, and `separate` needs both halves in
|
|
10
|
+
// the same conjunction `split` does.
|
|
11
|
+
//
|
|
12
|
+
// **The default is `fold`.** Separability alone never separates — it is necessary, not sufficient —
|
|
13
|
+
// and a size that does not clear the split guide folds however separable the findings are. That is
|
|
14
|
+
// why an unmeasurable size is treated by the caller as under the guide: tipping the doubt toward
|
|
15
|
+
// `separate` would reproduce the every-finding-its-own-Issue behavior this exists to end.
|
|
16
|
+
|
|
17
|
+
type FoldVerdict = 'fold' | 'separate' | 'no-fold-needed'
|
|
18
|
+
|
|
19
|
+
const FOLD: FoldVerdict = 'fold'
|
|
20
|
+
const SEPARATE: FoldVerdict = 'separate'
|
|
21
|
+
const NO_FOLD_NEEDED: FoldVerdict = 'no-fold-needed'
|
|
22
|
+
|
|
23
|
+
// One finding is nothing to fold: the question only arises once a session holds two or more.
|
|
24
|
+
const MIN_CANDIDATES = 2
|
|
25
|
+
|
|
26
|
+
// The same two questions as the split assessment, in the same conjunction: `separate` only when the
|
|
27
|
+
// findings are separable **and** their combined size clears the split guide. Either half alone folds,
|
|
28
|
+
// and fewer than two candidates is not a fold question at all.
|
|
29
|
+
function fold_verdict(
|
|
30
|
+
candidate_count: number,
|
|
31
|
+
is_separable: boolean,
|
|
32
|
+
size_verdict: SplitVerdict,
|
|
33
|
+
): FoldVerdict {
|
|
34
|
+
if (candidate_count < MIN_CANDIDATES) return NO_FOLD_NEEDED
|
|
35
|
+
|
|
36
|
+
return is_separable && size_verdict === split_assess.SPLIT_VERDICT ? SEPARATE : FOLD
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const issue_fold = { FOLD, SEPARATE, NO_FOLD_NEEDED, MIN_CANDIDATES, fold_verdict }
|
|
40
|
+
|
|
41
|
+
export type { FoldVerdict }
|
|
42
|
+
export { issue_fold }
|