@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,360 @@
|
|
|
1
|
+
import { spawn, type SpawnOptions } from 'node:child_process'
|
|
2
|
+
import { closeSync, constants, openSync, writeSync } from 'node:fs'
|
|
3
|
+
import { agent_launch_environment } from '#scripts/agent/agent-launch-environment'
|
|
4
|
+
import { agent_role_profile, type AgentProfile } from '#scripts/agent/agent-role-profile'
|
|
5
|
+
import { agent_session_environment } from '#scripts/josh/agent-session-environment'
|
|
6
|
+
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
7
|
+
|
|
8
|
+
// Starting a process that outlives this one, and keeping what it writes.
|
|
9
|
+
//
|
|
10
|
+
// **It was `run-wake-session.ts`'s until a second caller needed it** (joshuafolkken/kit#1749). The
|
|
11
|
+
// supervisor was the only thing launching a detached session, so the launcher and the
|
|
12
|
+
// `backlogrun`-specific invocation parsing sat in one file; a delegated child launched into a lane
|
|
13
|
+
// needs exactly the launcher and none of the parsing. Copying it across would be the clone
|
|
14
|
+
// `CLAUDE.md` prohibits — and this is the shape of clone that fails silently, because the copy that
|
|
15
|
+
// drifts is the one that forgets to strip the parent session's environment and dies at its first API
|
|
16
|
+
// request with nothing naming the cause (joshuafolkken/kit#1760).
|
|
17
|
+
//
|
|
18
|
+
// **What is shared is the mechanism, never the argument vector.** Each caller composes its own
|
|
19
|
+
// `LaunchArgv` out of its own constants and validated values — `run-wake-session.ts` rebuilds a
|
|
20
|
+
// `backlogrun` invocation, `lane-dispatch.ts` composes a `fullrun #<N>` out of a digits-only issue
|
|
21
|
+
// number — and this module refuses one that carries anything a command line has no business holding.
|
|
22
|
+
|
|
23
|
+
const NO_PID_NOTE = 'the process started without a pid'
|
|
24
|
+
const UNSAFE_NOTE =
|
|
25
|
+
'the wake command or its arguments contain characters that are not safe to execute'
|
|
26
|
+
|
|
27
|
+
// Provider-specific commands and flags are composed before this boundary. This module accepts only
|
|
28
|
+
// an argv vector and never infers policy from it; role/model/effort arrive separately as log metadata.
|
|
29
|
+
// The provider adapter keeps the fixed binary and permission flags in one reviewed place.
|
|
30
|
+
// **The inputs that reach `spawn` are validated rather than trusted, and that is a control rather than
|
|
31
|
+
// a formality.** Two things already bound this — the argument vector never goes through a shell, so
|
|
32
|
+
// there is no shell to inject into, and the invocation travels as exactly one argv element rather than
|
|
33
|
+
// being interpolated into a command string — but neither is visible at the call site, and "it cannot be
|
|
34
|
+
// exploited the way this is written today" is an argument, not a check. A later edit that added
|
|
35
|
+
// `shell: true` would silently turn both into nothing.
|
|
36
|
+
//
|
|
37
|
+
// A NUL byte is what `execve` treats as the end of a string, so a value carrying one executes as a
|
|
38
|
+
// prefix of itself; the other control characters have no business in a command line and their presence
|
|
39
|
+
// means the value did not come from where it was supposed to.
|
|
40
|
+
//
|
|
41
|
+
// The shared value validation lives with the role policy so environment overrides and argv elements
|
|
42
|
+
// cannot disagree about which control characters or lengths are safe.
|
|
43
|
+
interface LaunchArgv {
|
|
44
|
+
command: string
|
|
45
|
+
args: ReadonlyArray<string>
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type LaunchResult = { kind: 'launched'; pid: number } | { kind: 'failed'; note: string }
|
|
49
|
+
type AttachedLaunchResult =
|
|
50
|
+
{ kind: 'completed'; pid: number; exit_code: number | null } | { kind: 'failed'; note: string }
|
|
51
|
+
|
|
52
|
+
interface LaunchRequest {
|
|
53
|
+
argv: LaunchArgv
|
|
54
|
+
cwd: string
|
|
55
|
+
// Where to keep what the child writes. **Absent means the output is discarded**, which is what every
|
|
56
|
+
// launch did before joshuafolkken/kit#1746 and what a caller with nowhere to write still gets — the
|
|
57
|
+
// log is an improvement on the diagnosis, never a precondition for starting a session.
|
|
58
|
+
log_path?: string | undefined
|
|
59
|
+
// Extra variables to set on the child, spread **after** the parent-session strip below, so a caller
|
|
60
|
+
// can hand the child a fact the inherited environment does not carry — a dispatched lane child's mark
|
|
61
|
+
// among them (joshuafolkken/kit#1904). Setting it here rather than mutating `process.env` keeps the
|
|
62
|
+
// launcher's own environment untouched, and spreading it last means an explicit value wins over an
|
|
63
|
+
// inherited one of the same name.
|
|
64
|
+
env?: Readonly<Record<string, string | undefined>>
|
|
65
|
+
// Resolved before this provider-independent launcher is called. It is launch metadata, not an
|
|
66
|
+
// argument source: the provider adapter already placed the same model and effort in `argv`.
|
|
67
|
+
profile?: AgentProfile | undefined
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const { is_safe_value } = agent_role_profile
|
|
71
|
+
|
|
72
|
+
// The single gate every argument vector passes before it reaches the operating system, whoever
|
|
73
|
+
// composed it.
|
|
74
|
+
function is_safe_argv(argv: LaunchArgv): boolean {
|
|
75
|
+
return is_safe_value(argv.command) && argv.args.every((value) => is_safe_value(value))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function note_of(error: unknown): string {
|
|
79
|
+
return error instanceof Error ? error.message : JSON.stringify(error)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function launched(pid: number): LaunchResult {
|
|
83
|
+
return { kind: 'launched', pid }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// **Appended to without following a symlink, and refused unless the file is this account's own.** The
|
|
87
|
+
// path is deterministic — the temp directory plus a digest of the repository — so on a shared `/tmp`
|
|
88
|
+
// anyone who knows the checkout can work it out and pre-create it. `O_NOFOLLOW` is what stops the
|
|
89
|
+
// append landing wherever a symlink pointed, and the ownership test is the second half, against a
|
|
90
|
+
// plain file another account left at the same path. It is `stamp_file`'s own test rather than a second
|
|
91
|
+
// copy of one, and together the two give this file the defense `write_exclusively` already gives the
|
|
92
|
+
// wake and carry records beside it.
|
|
93
|
+
//
|
|
94
|
+
// `LOG_MODE` applies on creation alone, which is why the ownership test is not redundant: a file this
|
|
95
|
+
// account already owns is trusted whatever mode it carries, and one it does not is refused outright.
|
|
96
|
+
// eslint-disable-next-line no-bitwise -- POSIX open flags are a bit field; `||` here would be a bug
|
|
97
|
+
const LOG_FLAGS = constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW
|
|
98
|
+
const LOG_MODE = 0o600
|
|
99
|
+
|
|
100
|
+
function profile_suffix(profile: AgentProfile | undefined): string {
|
|
101
|
+
return profile === undefined ? '' : ` · ${agent_role_profile.describe(profile)}`
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// One line in front of each launch, so the sessions started into one file can be told apart. The
|
|
105
|
+
// child's own pid is not known until `spawn` returns, and a header written afterwards would race the
|
|
106
|
+
// child's first output; the time and the launching process separate the runs.
|
|
107
|
+
function log_header(argv: LaunchArgv, profile?: AgentProfile): string {
|
|
108
|
+
const stamp = new Date().toISOString()
|
|
109
|
+
|
|
110
|
+
return `\n=== ${stamp} · started by process ${String(process.pid)} · ${argv.command}${profile_suffix(profile)} ===\n`
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function opened_log(log_path: string, on_error: (note: string) => void): number | undefined {
|
|
114
|
+
const descriptor = openSync(log_path, LOG_FLAGS, LOG_MODE)
|
|
115
|
+
|
|
116
|
+
if (!stamp_file.is_own_regular_file(log_path)) {
|
|
117
|
+
closeSync(descriptor)
|
|
118
|
+
// Worded for both callers: `ensure_log` reaches this from `--list` and `--stop`, where nothing
|
|
119
|
+
// has been launched and "the session output is discarded" would describe an event that did not
|
|
120
|
+
// happen. What holds on every path is that nothing is kept there.
|
|
121
|
+
on_error(`${log_path} is not this account's own file, so nothing is kept there`)
|
|
122
|
+
|
|
123
|
+
return undefined
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return descriptor
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// **The header is written by the launch and by nothing else.** Opening the file and announcing a
|
|
130
|
+
// launch into it were one function until joshuafolkken/kit#1759, which is what made the file's
|
|
131
|
+
// existence a side effect of launching: there was no way to obtain the descriptor without also
|
|
132
|
+
// claiming a session had started. Split, `ensure_log` below can create the file the moment its path
|
|
133
|
+
// is named, and a log nothing has launched into stays empty rather than carrying a header for a
|
|
134
|
+
// session that never ran.
|
|
135
|
+
//
|
|
136
|
+
// **It swallows its own failure, because a log failure is never a failed launch.** In `opened_log`
|
|
137
|
+
// this write sat inside `open_log`'s `try`, so a full disk lost the header and started the session
|
|
138
|
+
// anyway; reached from `launch`'s `try` it would answer `failed` instead and leave a cut
|
|
139
|
+
// `backlogrun` asleep — the one outcome `open_log`'s comment below rules out.
|
|
140
|
+
function stamped(
|
|
141
|
+
descriptor: number | undefined,
|
|
142
|
+
argv: LaunchArgv,
|
|
143
|
+
profile: AgentProfile | undefined,
|
|
144
|
+
on_error: (note: string) => void,
|
|
145
|
+
): void {
|
|
146
|
+
if (descriptor === undefined) return
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
writeSync(descriptor, log_header(argv, profile))
|
|
150
|
+
} catch (error) {
|
|
151
|
+
on_error(`the session log could not be written: ${note_of(error)}`)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// **Opening the log is allowed to fail, and a failure is not a failed launch.** A temp directory that
|
|
156
|
+
// cannot be written to is a reason to lose the diagnosis, never a reason to leave the run asleep — so
|
|
157
|
+
// this answers `undefined` and the spawn goes ahead discarding output, exactly as it did before
|
|
158
|
+
// joshuafolkken/kit#1746.
|
|
159
|
+
//
|
|
160
|
+
// **It says so rather than failing quietly, though.** `--list` and every warning name this path
|
|
161
|
+
// unconditionally, so a silent failure would send a person at three in the morning to a file holding
|
|
162
|
+
// nothing of this run — the silent diagnosis joshuafolkken/kit#1746 was filed about, arrived at from
|
|
163
|
+
// the other side.
|
|
164
|
+
function open_log(
|
|
165
|
+
log_path: string | undefined,
|
|
166
|
+
on_error: (note: string) => void,
|
|
167
|
+
): number | undefined {
|
|
168
|
+
if (log_path === undefined) return undefined
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
return opened_log(log_path, on_error)
|
|
172
|
+
} catch (error) {
|
|
173
|
+
on_error(`the session log at ${log_path} could not be opened: ${note_of(error)}`)
|
|
174
|
+
|
|
175
|
+
return undefined
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// **The file exists because its path was resolved, not because something launched into it**
|
|
180
|
+
// (joshuafolkken/kit#1759). `--list`, the already-running branch of `--start` and every warning name
|
|
181
|
+
// this path unconditionally, and until this existed none of the three created anything: the file was
|
|
182
|
+
// written only by the process that launched, at the moment it launched. So a supervisor started
|
|
183
|
+
// before the log existed — detached, and alive for the hours a `backlogrun` takes — left the path
|
|
184
|
+
// named for the whole run with nothing ever at it, and the one report a failure could make went to
|
|
185
|
+
// that same absent file. Creating it where it is named is what makes the name a promise the reader
|
|
186
|
+
// can check: an empty log says "this supervisor started nothing", which is an answer, where a
|
|
187
|
+
// missing one said nothing at all.
|
|
188
|
+
//
|
|
189
|
+
// **No header is written here**, because nothing has been launched — see `stamped` above.
|
|
190
|
+
function ensure_log(log_path: string, on_error: (note: string) => void): void {
|
|
191
|
+
const descriptor = open_log(log_path, on_error)
|
|
192
|
+
|
|
193
|
+
if (descriptor !== undefined) closeSync(descriptor)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// **`detached` is what puts the child outside the conversation, and discarding its output was never
|
|
197
|
+
// part of that** (joshuafolkken/kit#1746). A process left attached is a child of the agent session,
|
|
198
|
+
// and the session cut is exactly the moment this has to survive — so a supervisor that the harness
|
|
199
|
+
// backgrounds, the way `run:progress` is backgrounded, would die at the one event it exists to handle.
|
|
200
|
+
// That argument is about the parent link alone. `stdio: 'ignore'` rode along with it and threw away
|
|
201
|
+
// the one record that could say why a woken session exited without claiming the carry record, which is
|
|
202
|
+
// the whole of what joshuafolkken/kit#1746 could not diagnose. Pointed at a file, the child is just as
|
|
203
|
+
// detached and the output survives it.
|
|
204
|
+
//
|
|
205
|
+
// **The parent session's environment is removed here, and that is why it is here rather than at each
|
|
206
|
+
// call site** (joshuafolkken/kit#1760). A detached child outlives the invocation that spawned it, so a
|
|
207
|
+
// loopback proxy exported into that invocation is a dead address by the time the child dials it —
|
|
208
|
+
// `ConnectionRefused` at the first API request, with nothing anywhere naming the cause. A second
|
|
209
|
+
// launcher that composed its own `SpawnOptions` would be one edit away from that failure.
|
|
210
|
+
//
|
|
211
|
+
// The `error` listener is not decoration: an unhandled `error` on a child process throws in this
|
|
212
|
+
// process, and an agent CLI that is not on `PATH` raises one asynchronously, after `spawn` has
|
|
213
|
+
// already returned. It reports rather than decides — the grace window in `run-wake.ts` is what turns a failed
|
|
214
|
+
// launch into a verdict, so that one detector covers a missing binary, a session that dies during boot
|
|
215
|
+
// and a session that runs without ever picking the run up.
|
|
216
|
+
// Lifted out of the call so the `spawn` fits on one line, which is where the suppression below has to
|
|
217
|
+
// sit: SonarQube's marker applies to the line the issue is raised on and to nothing else.
|
|
218
|
+
function spawn_options(
|
|
219
|
+
cwd: string,
|
|
220
|
+
log: number | undefined,
|
|
221
|
+
environment: Readonly<Record<string, string | undefined>> = {},
|
|
222
|
+
is_detached = true,
|
|
223
|
+
): SpawnOptions {
|
|
224
|
+
return {
|
|
225
|
+
cwd,
|
|
226
|
+
detached: is_detached,
|
|
227
|
+
stdio: log === undefined ? 'ignore' : ['ignore', log, log],
|
|
228
|
+
env: { ...process.env, ...agent_session_environment.removed_environment(), ...environment },
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function notify_spawn(
|
|
233
|
+
pid: number | undefined,
|
|
234
|
+
on_spawn: (pid: number) => void,
|
|
235
|
+
on_error: (note: string) => void,
|
|
236
|
+
): void {
|
|
237
|
+
if (pid === undefined) return
|
|
238
|
+
|
|
239
|
+
try {
|
|
240
|
+
on_spawn(pid)
|
|
241
|
+
} catch (error) {
|
|
242
|
+
on_error(`the child state could not be recorded: ${note_of(error)}`)
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async function attached_spawn(
|
|
247
|
+
request: LaunchRequest,
|
|
248
|
+
log: number | undefined,
|
|
249
|
+
on_error: (note: string) => void,
|
|
250
|
+
on_spawn: (pid: number) => void,
|
|
251
|
+
): Promise<AttachedLaunchResult> {
|
|
252
|
+
return await new Promise((resolve) => {
|
|
253
|
+
const environment = agent_launch_environment.build(request.cwd, request.profile, request.env)
|
|
254
|
+
const child = spawn(
|
|
255
|
+
request.argv.command,
|
|
256
|
+
[...request.argv.args],
|
|
257
|
+
spawn_options(request.cwd, log, environment, false),
|
|
258
|
+
) // NOSONAR — shell stays false
|
|
259
|
+
|
|
260
|
+
child.once('error', (error) => {
|
|
261
|
+
on_error(note_of(error))
|
|
262
|
+
resolve({ kind: 'failed', note: note_of(error) })
|
|
263
|
+
})
|
|
264
|
+
child.once('exit', (exit_code) => {
|
|
265
|
+
resolve({ kind: 'completed', pid: child.pid ?? 0, exit_code })
|
|
266
|
+
})
|
|
267
|
+
notify_spawn(child.pid, on_spawn, on_error)
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function ignore_spawn(_pid: number): void {
|
|
272
|
+
/* caller does not need the attached child's pid */
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// **`tssecurity:S8705` is suppressed on the `spawn` line, and this is the reason it is allowed to be.**
|
|
276
|
+
// The rule's premise is a shell escape — it fires where untrusted text can become shell syntax. There
|
|
277
|
+
// is no shell on this path to escape from: `spawn` is handed a command and an argument **array**,
|
|
278
|
+
// `shell` is left at its default of false, so nothing here is ever parsed by `sh`. And every element of
|
|
279
|
+
// that array is a constant or an integer the caller composed, because each caller takes the text it was
|
|
280
|
+
// handed apart and rebuilds it rather than passing it on.
|
|
281
|
+
//
|
|
282
|
+
// **It is what was left after the flow was actually broken, not something used instead of breaking
|
|
283
|
+
// it.** Three earlier rounds tried to satisfy the rule by inspecting the string harder and moved it not
|
|
284
|
+
// at all; the rebuild is what severed the flow, and the same change retired the pattern CodeQL had
|
|
285
|
+
// found an exponential backtrack in — **`js/redos` is gone from this file rather than suppressed, and
|
|
286
|
+
// this marker covers nothing of it.** What the rule still sees is the shape of a `spawn` reached from a
|
|
287
|
+
// file that was read, and that shape is the design: starting a process from a record is the whole of
|
|
288
|
+
// what a supervisor does.
|
|
289
|
+
//
|
|
290
|
+
// Scoped to that one line on the user's explicit instruction of 2026-09-10 (joshuafolkken/kit#1719).
|
|
291
|
+
// No project-wide exclusion and no change to the Sonar configuration.
|
|
292
|
+
function spawned(
|
|
293
|
+
request: LaunchRequest,
|
|
294
|
+
log: number | undefined,
|
|
295
|
+
on_error: (note: string) => void,
|
|
296
|
+
): LaunchResult {
|
|
297
|
+
const { command, args } = request.argv
|
|
298
|
+
const environment = agent_launch_environment.build(request.cwd, request.profile, request.env)
|
|
299
|
+
const child = spawn(command, [...args], spawn_options(request.cwd, log, environment)) // NOSONAR — see above
|
|
300
|
+
|
|
301
|
+
child.on('error', (error) => {
|
|
302
|
+
on_error(note_of(error))
|
|
303
|
+
})
|
|
304
|
+
child.unref()
|
|
305
|
+
|
|
306
|
+
return child.pid === undefined ? { kind: 'failed', note: NO_PID_NOTE } : launched(child.pid)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// **The descriptor is closed as soon as the spawn returns, and that loses nothing.** `spawn` forks and
|
|
310
|
+
// execs before it returns, so the child already holds its own duplicate of the descriptor by then;
|
|
311
|
+
// what is closed here is this process's copy. Left open it would outlive the launch in a supervisor
|
|
312
|
+
// that runs for hours and launches once per cut.
|
|
313
|
+
function launch(request: LaunchRequest, on_error: (note: string) => void): LaunchResult {
|
|
314
|
+
if (!is_safe_argv(request.argv)) return { kind: 'failed', note: UNSAFE_NOTE }
|
|
315
|
+
|
|
316
|
+
const log = open_log(request.log_path, on_error)
|
|
317
|
+
|
|
318
|
+
try {
|
|
319
|
+
stamped(log, request.argv, request.profile, on_error)
|
|
320
|
+
|
|
321
|
+
return spawned(request, log, on_error)
|
|
322
|
+
} catch (error) {
|
|
323
|
+
return { kind: 'failed', note: note_of(error) }
|
|
324
|
+
} finally {
|
|
325
|
+
if (log !== undefined) closeSync(log)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
async function launch_attached(
|
|
330
|
+
request: LaunchRequest,
|
|
331
|
+
on_error: (note: string) => void,
|
|
332
|
+
on_spawn: (pid: number) => void = ignore_spawn,
|
|
333
|
+
): Promise<AttachedLaunchResult> {
|
|
334
|
+
if (!is_safe_argv(request.argv)) return { kind: 'failed', note: UNSAFE_NOTE }
|
|
335
|
+
const log = open_log(request.log_path, on_error)
|
|
336
|
+
|
|
337
|
+
try {
|
|
338
|
+
stamped(log, request.argv, request.profile, on_error)
|
|
339
|
+
|
|
340
|
+
return await attached_spawn(request, log, on_error, on_spawn)
|
|
341
|
+
} catch (error) {
|
|
342
|
+
return { kind: 'failed', note: note_of(error) }
|
|
343
|
+
} finally {
|
|
344
|
+
if (log !== undefined) closeSync(log)
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const detached_launch = {
|
|
349
|
+
UNSAFE_NOTE,
|
|
350
|
+
ensure_log,
|
|
351
|
+
is_safe_argv,
|
|
352
|
+
is_safe_value,
|
|
353
|
+
launch,
|
|
354
|
+
launch_attached,
|
|
355
|
+
log_header,
|
|
356
|
+
note_of,
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export type { LaunchArgv, LaunchRequest, LaunchResult }
|
|
360
|
+
export { detached_launch }
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util'
|
|
2
|
+
import { run_carry, type CarryChange, type CarryClaimRequest, type CarryOwner } from './run-carry'
|
|
3
|
+
import { run_issue_number } from './run-issue-number'
|
|
4
|
+
|
|
5
|
+
// The argument half of `josh run:carry`. It sat inside `run-carry-cli.ts` until the ownership answers
|
|
6
|
+
// joshuafolkken/kit#1722 added took that file to 96% of the 300-line limit, and the seam it split on
|
|
7
|
+
// was already there: everything here turns `argv` into one `Request` and reads no record, while
|
|
8
|
+
// everything left there acts on a record and prints. Nothing about the behavior moved with it.
|
|
9
|
+
|
|
10
|
+
const NO_INCREMENT = 0
|
|
11
|
+
const ONE_CUT = 1
|
|
12
|
+
// The four request groups below are mutually exclusive, so more than one of them named in a single
|
|
13
|
+
// invocation is a usage error rather than an order to guess.
|
|
14
|
+
const ONE_GROUP = 1
|
|
15
|
+
const COUNT_PATTERN = /^\d+$/u
|
|
16
|
+
const EMPTY_INVOCATION = ''
|
|
17
|
+
// A pid below this addresses a process group rather than a process, which `process-identity.ts`
|
|
18
|
+
// rejects on the read side. Refused here too, so a record never records an owner nothing can be.
|
|
19
|
+
const MIN_PID = 1
|
|
20
|
+
// `--owner` is read by the two claiming alternatives and by the counting group (joshuafolkken/kit#1935):
|
|
21
|
+
// a count checks the owner so a session whose record was handed off, or taken over by a successor,
|
|
22
|
+
// cannot advance a budget that is no longer its own. `--end` alone accepts it and ignores it, and a
|
|
23
|
+
// usage line that offered it there would be promising an ownership check nothing performs.
|
|
24
|
+
const USAGE =
|
|
25
|
+
'Usage: josh run:carry [--json] | --begin <invocation> [--owner <pid>] | --resume <invocation> [--owner <pid>] | (--cut | --merged <count> | --filed <count> | --done <issue> | --retrospective --summary <text>) [--owner <pid>] | --end [--stopped <reason>]'
|
|
26
|
+
|
|
27
|
+
const OPTIONS = {
|
|
28
|
+
begin: { type: 'string' },
|
|
29
|
+
cut: { type: 'boolean' },
|
|
30
|
+
done: { type: 'string' },
|
|
31
|
+
end: { type: 'boolean' },
|
|
32
|
+
filed: { type: 'string' },
|
|
33
|
+
json: { type: 'boolean' },
|
|
34
|
+
merged: { type: 'string' },
|
|
35
|
+
owner: { type: 'string' },
|
|
36
|
+
// A boolean like `--cut`: it marks the end-of-run retrospective as run rather than counting an
|
|
37
|
+
// amount (joshuafolkken/kit#2328). It joins the counting group, so it carries `--owner` and is
|
|
38
|
+
// refused from a session that no longer owns the record, exactly as a merge count is.
|
|
39
|
+
retrospective: { type: 'boolean' },
|
|
40
|
+
resume: { type: 'string' },
|
|
41
|
+
// The retrospective's result carried to the event stream (joshuafolkken/kit#2342). It pairs with
|
|
42
|
+
// `--retrospective` and only with it: the mark and the result it records are one action, so a mark
|
|
43
|
+
// with nothing to read and a result no mark records are both usage errors rather than half-done
|
|
44
|
+
// closes. It is not a record field — `to_change` never carries it — so it rides the count request to
|
|
45
|
+
// the emit side alone.
|
|
46
|
+
summary: { type: 'string' },
|
|
47
|
+
// **`--stopped <reason>` rides on `--end`, so it is a modifier rather than a fifth group.** A run
|
|
48
|
+
// that halts needing a person ends its record exactly as a clean one does; the reason is what turns
|
|
49
|
+
// that end into the ⏸️ confirmation the person gets after a session cut (joshuafolkken/kit#2136).
|
|
50
|
+
// Named without `--end` it is ignored, the way a read ignores every counting flag.
|
|
51
|
+
stopped: { type: 'string' },
|
|
52
|
+
} as const
|
|
53
|
+
|
|
54
|
+
type OptionName = keyof typeof OPTIONS
|
|
55
|
+
type ParsedValues = Partial<Record<OptionName, string | boolean>>
|
|
56
|
+
// What `parseArgs` hands back for one option: the flag's own type, or nothing where it was not named.
|
|
57
|
+
type OptionValue = string | boolean | undefined
|
|
58
|
+
|
|
59
|
+
// The counting request carries the owner so `count` can refuse a write from a session that is no
|
|
60
|
+
// longer the record's owner (joshuafolkken/kit#1935).
|
|
61
|
+
interface CountRequest {
|
|
62
|
+
kind: 'count'
|
|
63
|
+
change: CarryChange
|
|
64
|
+
owner: CarryOwner
|
|
65
|
+
// The retrospective result to emit, present exactly when `change.retrospective` is set and never
|
|
66
|
+
// otherwise (joshuafolkken/kit#2342). The CLI reads it to append one event as it applies the mark.
|
|
67
|
+
summary?: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
type Request =
|
|
71
|
+
| CountRequest
|
|
72
|
+
| { kind: 'read' }
|
|
73
|
+
| { kind: 'claim'; claim: CarryClaimRequest }
|
|
74
|
+
| { kind: 'end'; stopped: string | undefined }
|
|
75
|
+
|
|
76
|
+
const READ_REQUEST: Request = { kind: 'read' }
|
|
77
|
+
|
|
78
|
+
function read_arguments(argv: ReadonlyArray<string>): ParsedValues | undefined {
|
|
79
|
+
try {
|
|
80
|
+
return parseArgs({ args: [...argv], options: OPTIONS, strict: true }).values
|
|
81
|
+
} catch {
|
|
82
|
+
return undefined
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function text_of(value: OptionValue): string | undefined {
|
|
87
|
+
return typeof value === 'string' ? value : undefined
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Absent is zero; present but not a count is `undefined`, which invalidates the whole invocation
|
|
91
|
+
// rather than quietly counting nothing.
|
|
92
|
+
function to_count(value: OptionValue): number | undefined {
|
|
93
|
+
const text = text_of(value)
|
|
94
|
+
|
|
95
|
+
if (text === undefined) return NO_INCREMENT
|
|
96
|
+
|
|
97
|
+
return COUNT_PATTERN.test(text) ? Number(text) : undefined
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// **`--done` names an issue, so it is checked as one and not as a count.** The shape is
|
|
101
|
+
// `run-issue-number.ts`'s, which already refuses `0` and a leading zero — the same rule the `run:*`
|
|
102
|
+
// commands interpolate a number under, imported rather than restated. Absent is an empty object rather
|
|
103
|
+
// than a zero: there is no issue to record, which is a different fact from recording issue zero. A
|
|
104
|
+
// present-but-malformed value invalidates the whole invocation, exactly as a bad `--merged` does.
|
|
105
|
+
function to_done(value: OptionValue): Pick<CarryChange, 'done'> | undefined {
|
|
106
|
+
const text = text_of(value)
|
|
107
|
+
|
|
108
|
+
if (text === undefined) return {}
|
|
109
|
+
|
|
110
|
+
if (!run_issue_number.ISSUE_NUMBER_PATTERN.test(text)) return undefined
|
|
111
|
+
|
|
112
|
+
const issue = Number(text)
|
|
113
|
+
|
|
114
|
+
// The pattern is anchored on digits and bounds nothing, so the magnitude check is separate — the
|
|
115
|
+
// same shape `backlog_budget_cli.to_count` ends with. A number past the safe range would be
|
|
116
|
+
// recorded as a different number and never match anything in `remaining`.
|
|
117
|
+
return Number.isSafeInteger(issue) ? { done: issue } : undefined
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// The two boolean marks in the counting group — `--cut` and `--retrospective` — as the partial the
|
|
121
|
+
// change spreads. Kept apart from `to_change` so its own decision count stays under the limit.
|
|
122
|
+
function to_marks(values: ParsedValues): Pick<CarryChange, 'cuts' | 'retrospective'> {
|
|
123
|
+
const cuts = values.cut === true ? ONE_CUT : NO_INCREMENT
|
|
124
|
+
const retrospective = values.retrospective === true ? { retrospective: true } : {}
|
|
125
|
+
|
|
126
|
+
return { cuts, ...retrospective }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function to_change(values: ParsedValues): CarryChange | undefined {
|
|
130
|
+
const merged = to_count(values.merged)
|
|
131
|
+
const filed = to_count(values.filed)
|
|
132
|
+
const done = to_done(values.done)
|
|
133
|
+
|
|
134
|
+
if (merged === undefined || filed === undefined || done === undefined) return undefined
|
|
135
|
+
|
|
136
|
+
return { merged, filed, ...to_marks(values), ...done }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// **A counting flag is what makes a count, never the sum of one.** `--merged 0` is a run reporting
|
|
140
|
+
// that a wave merged nothing, and reading it as a bare read would answer `none` with exit 0 against
|
|
141
|
+
// a record that is not there — the silent zero `docs/josh-commands.md` says exits 1.
|
|
142
|
+
function has_count(values: ParsedValues): boolean {
|
|
143
|
+
return (
|
|
144
|
+
values.cut === true ||
|
|
145
|
+
values.retrospective === true ||
|
|
146
|
+
values.merged !== undefined ||
|
|
147
|
+
values.filed !== undefined ||
|
|
148
|
+
values.done !== undefined
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// The four groups are mutually exclusive: `--begin` starts a run, `--resume` adopts one, `--end`
|
|
153
|
+
// finishes one, and the counters change one that is already there. Two groups in one invocation is a
|
|
154
|
+
// usage error, never a guessed order between them.
|
|
155
|
+
function group_count(values: ParsedValues): number {
|
|
156
|
+
const groups = [
|
|
157
|
+
values.begin !== undefined,
|
|
158
|
+
values.resume !== undefined,
|
|
159
|
+
values.end === true,
|
|
160
|
+
has_count(values),
|
|
161
|
+
]
|
|
162
|
+
|
|
163
|
+
return groups.filter(Boolean).length
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// **`--owner` is what makes liveness answerable at all.** The process that runs this command is a
|
|
167
|
+
// short-lived `tsx`, so its own pid says nothing about whether the run is still going; the caller
|
|
168
|
+
// names the process that is — its own session — and a `backlogrun` passes `--owner "$PPID"`. Absent,
|
|
169
|
+
// the record simply declares no owner and every standing record reads as not provably live, which
|
|
170
|
+
// refuses rather than resumes.
|
|
171
|
+
function to_owner(value: OptionValue): CarryOwner | undefined {
|
|
172
|
+
const text = text_of(value)
|
|
173
|
+
|
|
174
|
+
if (text === undefined) return run_carry.NO_OWNER
|
|
175
|
+
|
|
176
|
+
if (!COUNT_PATTERN.test(text)) return undefined
|
|
177
|
+
|
|
178
|
+
const pid = Number(text)
|
|
179
|
+
|
|
180
|
+
return pid < MIN_PID ? undefined : run_carry.owner_of(pid)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// A non-empty `--summary`, or nothing. An empty string is nothing here, so it reads as absent and the
|
|
184
|
+
// pairing check below refuses it against `--retrospective`.
|
|
185
|
+
function summary_text(values: ParsedValues): string | undefined {
|
|
186
|
+
const summary = text_of(values.summary)
|
|
187
|
+
|
|
188
|
+
return summary === undefined || summary === '' ? undefined : summary
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// The mark and its result are one close: `--retrospective` needs a `--summary` to record, and a
|
|
192
|
+
// `--summary` names a result no other flag records (joshuafolkken/kit#2342). Either flag without the
|
|
193
|
+
// other is a usage error, so each must be present exactly when the other is.
|
|
194
|
+
function is_summary_paired(values: ParsedValues): boolean {
|
|
195
|
+
return (summary_text(values) !== undefined) === (values.retrospective === true)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// The counting group, split out so the shape below stays a flat list of exits. The summary rides along
|
|
199
|
+
// only when it is there — guaranteed paired with `--retrospective` by `is_summary_paired` — so a plain
|
|
200
|
+
// `--merged` count never carries one.
|
|
201
|
+
function to_count_request(values: ParsedValues, owner: CarryOwner): Request | undefined {
|
|
202
|
+
const change = to_change(values)
|
|
203
|
+
|
|
204
|
+
if (change === undefined) return undefined
|
|
205
|
+
|
|
206
|
+
const summary = summary_text(values)
|
|
207
|
+
|
|
208
|
+
return summary === undefined
|
|
209
|
+
? { kind: 'count', change, owner }
|
|
210
|
+
: { kind: 'count', change, owner, summary }
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// `--begin ""` is a loop whose invocation variable was unset. A record named by nothing is one every
|
|
214
|
+
// other empty `--begin` then reads as its own, which is the cross-run inheritance `classify_claim`
|
|
215
|
+
// exists to refuse — so it is a usage error rather than a record.
|
|
216
|
+
function to_claim_request(
|
|
217
|
+
invocation: string,
|
|
218
|
+
owner: CarryOwner,
|
|
219
|
+
is_adoption: boolean,
|
|
220
|
+
): Request | undefined {
|
|
221
|
+
if (invocation === EMPTY_INVOCATION) return undefined
|
|
222
|
+
|
|
223
|
+
return { kind: 'claim', claim: { invocation, owner, is_adoption } }
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function to_other_request(values: ParsedValues, owner: CarryOwner): Request | undefined {
|
|
227
|
+
if (values.end === true) return { kind: 'end', stopped: text_of(values.stopped) }
|
|
228
|
+
|
|
229
|
+
return has_count(values) ? to_count_request(values, owner) : READ_REQUEST
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function to_named_request(values: ParsedValues, owner: CarryOwner): Request | undefined {
|
|
233
|
+
const begun = text_of(values.begin)
|
|
234
|
+
|
|
235
|
+
if (begun !== undefined) return to_claim_request(begun, owner, false)
|
|
236
|
+
|
|
237
|
+
const adopted = text_of(values.resume)
|
|
238
|
+
|
|
239
|
+
if (adopted !== undefined) return to_claim_request(adopted, owner, true)
|
|
240
|
+
|
|
241
|
+
return to_other_request(values, owner)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function to_request(values: ParsedValues): Request | undefined {
|
|
245
|
+
if (group_count(values) > ONE_GROUP) return undefined
|
|
246
|
+
|
|
247
|
+
if (!is_summary_paired(values)) return undefined
|
|
248
|
+
|
|
249
|
+
const owner = to_owner(values.owner)
|
|
250
|
+
|
|
251
|
+
if (owner === undefined) return undefined
|
|
252
|
+
|
|
253
|
+
return to_named_request(values, owner)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const run_carry_args = {
|
|
257
|
+
OPTIONS,
|
|
258
|
+
USAGE,
|
|
259
|
+
read_arguments,
|
|
260
|
+
to_request,
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export type { CountRequest, ParsedValues, Request }
|
|
264
|
+
export { run_carry_args }
|