@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,292 @@
|
|
|
1
|
+
import { git_stash } from '#scripts/git/git-stash'
|
|
2
|
+
import { latest_scope_cli } from '#scripts/version/latest-scope-cli'
|
|
3
|
+
import type { CarryRead } from './run-carry'
|
|
4
|
+
import { run_event_stream } from './run-event-stream'
|
|
5
|
+
|
|
6
|
+
// `josh run:step <N>` — the run's next single action, computed from three mechanical inputs and nothing
|
|
7
|
+
// else (joshuafolkken/kit#2248). It is the child of epic #2166 that lifts the fold from an *event* to a
|
|
8
|
+
// whole *run*: `run:next` printed one prose line for a `fullrun`'s pre-implementation position, and the
|
|
9
|
+
// backlogrun loop stayed a state machine written in English that the reader rebuilt every turn. This
|
|
10
|
+
// computes the position from the event stream (`run-event-stream.ts`), the carry record
|
|
11
|
+
// (`run-carry.ts`) and the issue state (`run-prep.ts`) — never the conversation — and prints one line.
|
|
12
|
+
//
|
|
13
|
+
// **The print is one of two shapes, never a procedure.** A runnable command the reader pastes, or a
|
|
14
|
+
// single point a person has to judge (`decide: … — a | b`). The short verdict tokens below are the
|
|
15
|
+
// non-command answers, exactly as `backlog:next` prints an issue command or one of its fixed verdicts;
|
|
16
|
+
// an issue number is never a verdict token, only the named strings here are.
|
|
17
|
+
//
|
|
18
|
+
// **It does not re-decide what another command already answers.** A merged child's next step is
|
|
19
|
+
// `run:merge`'s to classify, the next backlog issue is `backlog:next`'s, the merge chain is
|
|
20
|
+
// `followup`'s — so this dispatches to them rather than cloning their logic. The one thing it owns is
|
|
21
|
+
// *which* of them is next, read off the run's own position.
|
|
22
|
+
|
|
23
|
+
const CLOSED = 'CLOSED'
|
|
24
|
+
|
|
25
|
+
// The fixed verdict tokens — the non-command, non-decide answers. Kept as the oracle's declared
|
|
26
|
+
// vocabulary (joshuafolkken/kit#2248), so `decision-oracle.test.ts` pins the list against these.
|
|
27
|
+
const IMPLEMENT = 'implement'
|
|
28
|
+
const HUMAN_REVIEW = 'human-review'
|
|
29
|
+
const UPDATE_DEPS = 'update-deps'
|
|
30
|
+
const ALREADY_DONE = 'already-done'
|
|
31
|
+
// A closed issue whose lane tree still holds uncommitted work (joshuafolkken/kit#2476) — `run:step`
|
|
32
|
+
// itself prints the `decide:` line naming the stash, and this is the token `run:entry` reports.
|
|
33
|
+
const KEEP_WORK = 'keep-work'
|
|
34
|
+
const WAIT = 'wait'
|
|
35
|
+
const STOP = 'stop'
|
|
36
|
+
const UNKNOWN = 'unknown'
|
|
37
|
+
|
|
38
|
+
const VOCABULARY: ReadonlyArray<string> = [
|
|
39
|
+
IMPLEMENT,
|
|
40
|
+
HUMAN_REVIEW,
|
|
41
|
+
UPDATE_DEPS,
|
|
42
|
+
ALREADY_DONE,
|
|
43
|
+
KEEP_WORK,
|
|
44
|
+
WAIT,
|
|
45
|
+
STOP,
|
|
46
|
+
UNKNOWN,
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
// The whole-run bound is spent, and carrying the budget or discarding it is a person's call — the one
|
|
50
|
+
// Tier-B point this machine surfaces rather than choosing.
|
|
51
|
+
const EXPIRED_DECISION =
|
|
52
|
+
'decide: whole-run budget spent — resume with `pnpm josh run:carry --resume` | discard with `pnpm josh run:carry --end`'
|
|
53
|
+
|
|
54
|
+
// The one step a stopped run still owes before it ends: the end-of-run retrospective
|
|
55
|
+
// (joshuafolkken/kit#2328). It reads the run's own measurements and files the improvements worth
|
|
56
|
+
// carrying into the next run; the command is kit-only, so it means nothing — and is never printed — in a
|
|
57
|
+
// consumer project.
|
|
58
|
+
const RETROSPECTIVE_COMMAND = 'pnpm josh retrospective'
|
|
59
|
+
|
|
60
|
+
// The pre-implementation verdict `run:next` degenerates to: the position of a run that has emitted no
|
|
61
|
+
// event yet. `run-next.ts` maps each of these to its prose sentence, so this is the single copy of the
|
|
62
|
+
// state → step mapping and there is no second implementation (joshuafolkken/kit#2248).
|
|
63
|
+
type PreVerdict =
|
|
64
|
+
| typeof IMPLEMENT
|
|
65
|
+
| typeof HUMAN_REVIEW
|
|
66
|
+
| typeof UPDATE_DEPS
|
|
67
|
+
| typeof ALREADY_DONE
|
|
68
|
+
| typeof KEEP_WORK
|
|
69
|
+
| typeof UNKNOWN
|
|
70
|
+
|
|
71
|
+
interface PreInput {
|
|
72
|
+
state: string | undefined
|
|
73
|
+
is_human_review: boolean
|
|
74
|
+
latest_scope: string
|
|
75
|
+
// Whether a lane child's tree holds uncommitted work, read by `run:prep`'s gather
|
|
76
|
+
// (joshuafolkken/kit#2476). A closed issue over such a tree is not "nothing to do": the work was
|
|
77
|
+
// popped back from a park and is lost with the lane unless it is kept, so `already-done` gives way to
|
|
78
|
+
// `keep-work`.
|
|
79
|
+
has_changes: boolean
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function closed_verdict(input: PreInput): typeof ALREADY_DONE | typeof KEEP_WORK {
|
|
83
|
+
return input.has_changes ? KEEP_WORK : ALREADY_DONE
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// The three facts the run branches on before its first edit, ordered because they are not independent:
|
|
87
|
+
// an unreadable state answers first, a closed issue is terminal, a required update is the earliest
|
|
88
|
+
// action, and `needs-human-review` changes where the run ends so it precedes the ordinary implement.
|
|
89
|
+
function pre_verdict(input: PreInput): PreVerdict {
|
|
90
|
+
if (input.state === undefined) return UNKNOWN
|
|
91
|
+
if (input.state === CLOSED) return closed_verdict(input)
|
|
92
|
+
if (input.latest_scope === latest_scope_cli.REQUIRED_SCOPE) return UPDATE_DEPS
|
|
93
|
+
if (input.is_human_review) return HUMAN_REVIEW
|
|
94
|
+
|
|
95
|
+
return IMPLEMENT
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface StepInput extends PreInput {
|
|
99
|
+
// The last event kind on the stream, or `undefined` for a stream with nothing on it. Only the newest
|
|
100
|
+
// event is read: the position is where the run *is*, not how it got there.
|
|
101
|
+
last_event: string | undefined
|
|
102
|
+
carry_kind: CarryRead['kind']
|
|
103
|
+
// Whether this invocation's end-of-run retrospective has already run, read off the carry record
|
|
104
|
+
// (joshuafolkken/kit#2328). At the stop position it is what tells a run that still owes a
|
|
105
|
+
// retrospective from one that has run it, so the step is printed exactly once.
|
|
106
|
+
is_retrospective_done: boolean
|
|
107
|
+
// Whether this checkout is a kit consumer rather than kit itself (joshuafolkken/kit#2328). The
|
|
108
|
+
// retrospective command is kit-only — refused in a consumer — so the step is never printed there; the
|
|
109
|
+
// consumer determination is the existing `doctor-consumer.ts` one, never a new judgement.
|
|
110
|
+
is_consumer: boolean
|
|
111
|
+
issue_number: string
|
|
112
|
+
// Whether this run is a dispatched lane child, read by the CLI from the dispatch mark
|
|
113
|
+
// (`lane-child-marker.ts`). A child must never be handed `run:merge` — that is the parent's own
|
|
114
|
+
// budget command and returns `busy` in a child (joshuafolkken/kit#2267, joshuafolkken/kit#2297).
|
|
115
|
+
is_lane_child: boolean
|
|
116
|
+
// Whether the end-of-run retrospective is switched on, read by the CLI from `JOSH_RETROSPECTIVE`
|
|
117
|
+
// (joshuafolkken/kit#2370). It defaults **off** — the auto-filed improvement issues the step drives
|
|
118
|
+
// are opt-in — so a run that leaves the variable unset never prints the retrospective step, while the
|
|
119
|
+
// retrospective's own logic is untouched and `pnpm josh retrospective` still runs by hand.
|
|
120
|
+
is_retrospective_enabled: boolean
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
interface StepAction {
|
|
124
|
+
kind: 'command' | 'verdict' | 'decide'
|
|
125
|
+
line: string
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function verdict(token: string): StepAction {
|
|
129
|
+
return { kind: 'verdict', line: token }
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function command(line: string): StepAction {
|
|
133
|
+
return { kind: 'command', line }
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// The action for each event a run can be positioned at, keyed on the newest one. Each dispatches to the
|
|
137
|
+
// command that owns that phase; `child-launch` is the one position with no command to run — the parent
|
|
138
|
+
// waits for its child. `stop` and `drain` are handled apart in `stop_action` / `drain_action`, because
|
|
139
|
+
// whether either still owes a retrospective needs more than the issue number. A merge and an outage share a next step: `run:merge`
|
|
140
|
+
// classifies both, including the outage's stop condition.
|
|
141
|
+
const KIND = run_event_stream.EVENT_KIND
|
|
142
|
+
// A park and a stall share this next step: both mean runnable work is waiting to be offered
|
|
143
|
+
// (joshuafolkken/kit#2359), so both are pointed at the backlog.
|
|
144
|
+
const OFFER_BACKLOG = 'pnpm josh backlog:next'
|
|
145
|
+
const EVENT_ACTIONS: Record<string, (issue_number: string) => StepAction> = {
|
|
146
|
+
[KIND.PR_OPENED]: () => command('pnpm josh followup'),
|
|
147
|
+
[KIND.REVIEW_ROUND]: () => command('pnpm josh review:round2'),
|
|
148
|
+
[KIND.MERGE]: (issue_number) => command(`pnpm josh run:merge ${issue_number}`),
|
|
149
|
+
[KIND.OUTAGE]: (issue_number) => command(`pnpm josh run:merge ${issue_number}`),
|
|
150
|
+
[KIND.PARK]: () => command(OFFER_BACKLOG),
|
|
151
|
+
[KIND.CUT]: (issue_number) => command(`pnpm josh run:cut --resume ${issue_number}`),
|
|
152
|
+
[KIND.CHILD_LAUNCH]: () => verdict(WAIT),
|
|
153
|
+
// A stall is undispatched ready work with a free lane, so its next step is exactly a park's: offer
|
|
154
|
+
// the backlog. The detector only reports the stall; reading it here as a dispatch is what turns the
|
|
155
|
+
// report into the action that resolves it.
|
|
156
|
+
[KIND.STALL]: () => command(OFFER_BACKLOG),
|
|
157
|
+
// The post-implementation region is with a detached ship supervisor (joshuafolkken/kit#2428): nothing
|
|
158
|
+
// is the agent's until the supervisor stops or the issue closes, which the terminal read answers.
|
|
159
|
+
[KIND.SHIP_LAUNCH]: () => verdict(WAIT),
|
|
160
|
+
// The supervisor stopped at a failed stage and handed control back — the next step is reading the
|
|
161
|
+
// report it stopped on, which names the stage and why.
|
|
162
|
+
[KIND.SHIP_STOP]: (issue_number) => command(`pnpm josh ship --log ${issue_number}`),
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// The parent-only positions a dispatched lane child must never act on. `run:merge` is the parent's
|
|
166
|
+
// budget command — a child that ran it read the `busy` it got back as a competing session and parked
|
|
167
|
+
// its Issue unimplemented (joshuafolkken/kit#2267). A merge or an outage is the parent's to classify,
|
|
168
|
+
// so a child at one has nothing to run and stops rather than being handed `run:merge`
|
|
169
|
+
// (joshuafolkken/kit#2297).
|
|
170
|
+
const PARENT_ONLY_EVENTS: ReadonlySet<string> = new Set([KIND.MERGE, KIND.OUTAGE])
|
|
171
|
+
|
|
172
|
+
// Whether a run at a winding-down position still owes its end-of-run retrospective
|
|
173
|
+
// (joshuafolkken/kit#2328) — false when the switch is off (the opt-in default, joshuafolkken/kit#2370),
|
|
174
|
+
// for a dispatched lane child, where the batch runs one at its own end and never a child's (the
|
|
175
|
+
// `release:scope` precedent), for a run whose retrospective has already run this invocation, and in a
|
|
176
|
+
// consumer checkout, where the kit-only command is refused. The switch is read first, so a run that has
|
|
177
|
+
// not opted in never consults the other three. The two positions that consult it are the drain and the
|
|
178
|
+
// stop; both read exactly this, so the exclusion set is single-sourced.
|
|
179
|
+
function is_retrospective_owed(input: StepInput): boolean {
|
|
180
|
+
if (!input.is_retrospective_enabled) return false
|
|
181
|
+
|
|
182
|
+
return !input.is_lane_child && !input.is_retrospective_done && !input.is_consumer
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// A stopped run's last owed step is the end-of-run retrospective. When it is not owed the position stops
|
|
186
|
+
// with no command to run, which is what the position meant before the retrospective existed.
|
|
187
|
+
function stop_action(input: StepInput): StepAction {
|
|
188
|
+
return is_retrospective_owed(input) ? command(RETROSPECTIVE_COMMAND) : verdict(STOP)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// The drain fires the retrospective *before* the idle watch, not after it (joshuafolkken/kit#2335): the
|
|
192
|
+
// retrospective files the improvement issues the watch then picks up, so running it after the watch — as
|
|
193
|
+
// the stop position alone did — spent the watch on an empty pool. When the retrospective is not owed the
|
|
194
|
+
// run proceeds to that watch, which is a `WAIT` rather than a `STOP`: the backlog is empty but the run is
|
|
195
|
+
// not ending, and the real `STOP` follows when the watch expires with the retrospective already done.
|
|
196
|
+
function drain_action(input: StepInput): StepAction {
|
|
197
|
+
return is_retrospective_owed(input) ? command(RETROSPECTIVE_COMMAND) : verdict(WAIT)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// The two positions whose action needs the whole input rather than the issue number — a stop and a
|
|
201
|
+
// drain both turn on whether the retrospective is still owed. Kept in a map so `next_action` dispatches
|
|
202
|
+
// them in one branch rather than one `if` apiece (`is_retrospective_owed` is the shared gate).
|
|
203
|
+
const FULL_INPUT_ACTIONS: Record<string, (input: StepInput) => StepAction> = {
|
|
204
|
+
[KIND.STOP]: stop_action,
|
|
205
|
+
[KIND.DRAIN]: drain_action,
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// An event the table does not name leaves the position unknown rather than guessing a next step. A
|
|
209
|
+
// lane child at a parent-only position stops instead — the runtime refusal `lane-carry-conflict.ts`
|
|
210
|
+
// delivers is the same rule one call later, so this keeps a child from ever being pointed at it. The
|
|
211
|
+
// stop position is dispatched by `next_action`, so it is not among the events this handles.
|
|
212
|
+
function event_action(event: string, issue_number: string, is_lane_child: boolean): StepAction {
|
|
213
|
+
if (is_lane_child && PARENT_ONLY_EVENTS.has(event)) return verdict(STOP)
|
|
214
|
+
|
|
215
|
+
return EVENT_ACTIONS[event]?.(issue_number) ?? verdict(UNKNOWN)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// A run that has planned but emitted nothing else is still at its pre-implementation position, so a
|
|
219
|
+
// `plan` reads the same as an empty stream.
|
|
220
|
+
function is_pre_implementation(last_event: string | undefined): boolean {
|
|
221
|
+
return last_event === undefined || last_event === run_event_stream.EVENT_KIND.PLAN
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// **No cut at the setup→implementation boundary** (joshuafolkken/kit#2489). A lane child's context is
|
|
225
|
+
// bounded by the threshold-gated implementation cut alone (`implementation-cut.ts`): the first edit is
|
|
226
|
+
// the moment both would have looked at, and below the threshold a cut there is one that does not pay
|
|
227
|
+
// for itself (`context-cut-payback.ts`), so a planned lane child implements in the same session.
|
|
228
|
+
function pre_implementation_action(input: StepInput): StepAction {
|
|
229
|
+
return verdict(pre_verdict(input))
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// A closed issue ends the run, but a tree still holding uncommitted work is surfaced rather than
|
|
233
|
+
// answered `already-done` — the answer a child read as "nothing to do" before its lane was removed
|
|
234
|
+
// with the work in it (joshuafolkken/kit#2476).
|
|
235
|
+
function closed_action(input: StepInput): StepAction {
|
|
236
|
+
if (closed_verdict(input) === ALREADY_DONE) return verdict(ALREADY_DONE)
|
|
237
|
+
|
|
238
|
+
const message = git_stash.work_message(input.issue_number, ALREADY_DONE)
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
kind: 'decide',
|
|
242
|
+
line: `decide: #${input.issue_number} is closed but this tree holds uncommitted work — keep it with \`git stash push -u -m "${message}"\` | carry it into a new issue`,
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// The terminal answers read before the run's position matters: an unreadable carry record leaves the
|
|
247
|
+
// position unknowable, a spent budget is the person's call, and the issue's own state can end the run
|
|
248
|
+
// whatever the events say. `undefined` when none applies and the position decides.
|
|
249
|
+
function terminal_action(input: StepInput): StepAction | undefined {
|
|
250
|
+
if (input.carry_kind === 'unreadable') return verdict(UNKNOWN)
|
|
251
|
+
if (input.carry_kind === 'expired') return { kind: 'decide', line: EXPIRED_DECISION }
|
|
252
|
+
if (input.state === undefined) return verdict(UNKNOWN)
|
|
253
|
+
if (input.state === CLOSED) return closed_action(input)
|
|
254
|
+
|
|
255
|
+
return undefined
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// The one entry point: the run's next action, from the three inputs and nothing else. A terminal answer
|
|
259
|
+
// wins first; otherwise a run with nothing emitted yet is at its pre-implementation position, and a run
|
|
260
|
+
// that has begun is placed by its newest event.
|
|
261
|
+
function next_action(input: StepInput): StepAction {
|
|
262
|
+
const terminal = terminal_action(input)
|
|
263
|
+
|
|
264
|
+
if (terminal !== undefined) return terminal
|
|
265
|
+
if (is_pre_implementation(input.last_event)) return pre_implementation_action(input)
|
|
266
|
+
|
|
267
|
+
const event = input.last_event ?? ''
|
|
268
|
+
const full_input_action = FULL_INPUT_ACTIONS[event]
|
|
269
|
+
|
|
270
|
+
if (full_input_action !== undefined) return full_input_action(input)
|
|
271
|
+
|
|
272
|
+
return event_action(event, input.issue_number, input.is_lane_child)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const run_step = {
|
|
276
|
+
ALREADY_DONE,
|
|
277
|
+
EXPIRED_DECISION,
|
|
278
|
+
HUMAN_REVIEW,
|
|
279
|
+
IMPLEMENT,
|
|
280
|
+
KEEP_WORK,
|
|
281
|
+
RETROSPECTIVE_COMMAND,
|
|
282
|
+
STOP,
|
|
283
|
+
UNKNOWN,
|
|
284
|
+
UPDATE_DEPS,
|
|
285
|
+
VOCABULARY,
|
|
286
|
+
WAIT,
|
|
287
|
+
next_action,
|
|
288
|
+
pre_verdict,
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export type { PreInput, PreVerdict, StepAction, StepInput }
|
|
292
|
+
export { run_step }
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { telegram_notify } from '#scripts/git/telegram-notify'
|
|
2
|
+
import type { CarryRead } from './run-carry'
|
|
3
|
+
|
|
4
|
+
// **A `backlogrun` that halts because a person is needed used to reach nobody once the session was
|
|
5
|
+
// cut** (joshuafolkken/kit#2136). Every remaining child blocked behind a parked one, the backlog
|
|
6
|
+
// drained of anything runnable, the failure streak tripped — each ends the run, and while the session
|
|
7
|
+
// was the person's the stop was there in the conversation. After a cut the parent is a headless
|
|
8
|
+
// `claude -p backlogrun`, so the stop reached its own transcript and nowhere else, and the run sat
|
|
9
|
+
// stopped until someone thought to ask. The 15-minute heartbeat stays a pull; a *stop* is a state
|
|
10
|
+
// change, and a state change is what `confirmation` exists to push.
|
|
11
|
+
//
|
|
12
|
+
// **This is the decision, kept apart from the send so the dedup can be pinned without a Telegram.**
|
|
13
|
+
// `run:carry --end` calls `plan` on the record it is about to remove; `announce` only runs when a
|
|
14
|
+
// notice comes back.
|
|
15
|
+
|
|
16
|
+
interface StopNotice {
|
|
17
|
+
reason: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const STOP_TITLE = 'backlogrun stopped'
|
|
21
|
+
const STOP_RECOVERY =
|
|
22
|
+
'If this did not arrive, `pnpm josh run:wake --list` relays the last progress line.'
|
|
23
|
+
|
|
24
|
+
// **Only a stop over a record that is still there is announced, and that is the whole of the dedup**
|
|
25
|
+
// (joshuafolkken/kit#2136). `--end` removes the record, so a second `--end --stopped` — a retried
|
|
26
|
+
// turn, a re-evaluation — reads `none` and plans nothing, which is why one event never sends twice. A
|
|
27
|
+
// clean finish passes no reason and stays silent, because a completed run has its own notification and
|
|
28
|
+
// this type is for the run that halted needing a person. An `unreadable` record is not announced: with
|
|
29
|
+
// nothing readable there is no run this can honestly say stopped.
|
|
30
|
+
function plan(read: CarryRead, reason: string | undefined): StopNotice | undefined {
|
|
31
|
+
if (reason === undefined || reason.length === 0) return undefined
|
|
32
|
+
if (read.kind !== 'carried' && read.kind !== 'expired') return undefined
|
|
33
|
+
|
|
34
|
+
return { reason }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function announce(notice: StopNotice): Promise<boolean> {
|
|
38
|
+
return await telegram_notify.confirm({
|
|
39
|
+
issue_title: STOP_TITLE,
|
|
40
|
+
body: notice.reason,
|
|
41
|
+
recovery: STOP_RECOVERY,
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const run_stop_notify = {
|
|
46
|
+
STOP_RECOVERY,
|
|
47
|
+
STOP_TITLE,
|
|
48
|
+
announce,
|
|
49
|
+
plan,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { run_stop_notify }
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { run_stranded } from './run-stranded'
|
|
4
|
+
import { run_stranded_detect } from './run-stranded-detect'
|
|
5
|
+
|
|
6
|
+
// `josh run:stranded` — read the three facts once and print the verdict (joshuafolkken/kit#2375). This
|
|
7
|
+
// is the manual and testable face of the detector `stop-guard.ts` runs on every stop; both call the one
|
|
8
|
+
// `detect_and_report`, so the command and the hook can never drift.
|
|
9
|
+
//
|
|
10
|
+
// **It reports, it never stops.** The exit code is always success — a strand is a state to surface, not
|
|
11
|
+
// an error to fail on — so a caller (a person, a test, the wired hook) reads the verdict off stdout and
|
|
12
|
+
// is never halted by it. Anything unreadable prints `ok` for the same reason: nothing carried to strand,
|
|
13
|
+
// so the caller carries on.
|
|
14
|
+
|
|
15
|
+
const SUCCESS_EXIT_CODE = 0
|
|
16
|
+
|
|
17
|
+
async function main(): Promise<void> {
|
|
18
|
+
try {
|
|
19
|
+
console.info(await run_stranded_detect.detect_and_report())
|
|
20
|
+
} catch {
|
|
21
|
+
console.info(run_stranded.OK)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
process.exitCode = SUCCESS_EXIT_CODE
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const run_stranded_cli = { main }
|
|
28
|
+
|
|
29
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
|
|
30
|
+
|
|
31
|
+
export { run_stranded_cli }
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { telegram_notify } from '#scripts/git/telegram-notify'
|
|
2
|
+
import { run_carry, type CarryRead, type RunCarry } from './run-carry'
|
|
3
|
+
import { run_event_stream } from './run-event-stream'
|
|
4
|
+
import { run_event_stream_emit } from './run-event-stream-emit'
|
|
5
|
+
import {
|
|
6
|
+
run_stranded,
|
|
7
|
+
type StrandedInput,
|
|
8
|
+
type StrandedVerdict,
|
|
9
|
+
type SupervisorLiveness,
|
|
10
|
+
} from './run-stranded'
|
|
11
|
+
import { run_wake, type RunWake } from './run-wake'
|
|
12
|
+
|
|
13
|
+
// The I/O half of the strand detector (joshuafolkken/kit#2375): it gathers the three facts the pure
|
|
14
|
+
// judge in `run-stranded.ts` weighs, then — on a strand — leaves the marker and sends the one
|
|
15
|
+
// notification. `stop-guard.ts` wires it into the Stop hook, so it runs at each loop boundary beside the
|
|
16
|
+
// stall detector it mirrors (joshuafolkken/kit#2359); the CLI exposes the same call for a person to run
|
|
17
|
+
// by hand.
|
|
18
|
+
//
|
|
19
|
+
// **Cheap and local.** Every read is a file on disk — the carry record, the wake record — and a process
|
|
20
|
+
// liveness probe; there is no network call, so unlike the stall detector this makes every read every
|
|
21
|
+
// time. The gate is the carry record itself: nothing carried, or a record that is expired or unreadable,
|
|
22
|
+
// returns before the wake record is even read.
|
|
23
|
+
|
|
24
|
+
// The recovery line names the command that hands the run to a fresh supervisor — the same one the pure
|
|
25
|
+
// judge holds, so the notification and the recovery can never drift. It is deliberately not
|
|
26
|
+
// `run:carry --resume`: the cutting session is refused `busy` and must stay refused
|
|
27
|
+
// (joshuafolkken/kit#1935), so recovery is another actor's.
|
|
28
|
+
const STRAND_RECOVERY = `Restart supervision with \`${run_stranded.RECOVERY_COMMAND}\` — it wakes a fresh successor to claim the budget; the cutting session must not resume it itself.`
|
|
29
|
+
|
|
30
|
+
// The seams a test replaces: the two record targets, the two record reads, the owner and supervisor
|
|
31
|
+
// liveness probes, and the two side effects. The defaults are the real readers; a test hands fakes so
|
|
32
|
+
// the gather and report logic run without a git tree, a process table or a network.
|
|
33
|
+
interface DetectPorts {
|
|
34
|
+
resolve_targets: () => Promise<RecordTargets | undefined>
|
|
35
|
+
read_carry: (target: string) => CarryRead
|
|
36
|
+
is_owner_live: (carry: RunCarry) => boolean
|
|
37
|
+
read_wake: (target: string) => RunWake | undefined
|
|
38
|
+
supervisor_liveness: (wake: RunWake | undefined) => SupervisorLiveness
|
|
39
|
+
emit_stranded: (text: string) => Promise<boolean>
|
|
40
|
+
notify_stranded: (body: string) => Promise<boolean>
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface RecordTargets {
|
|
44
|
+
carry: string
|
|
45
|
+
wake: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Both records key on the common git directory, the same one `run-carry.ts` and `run-wake.ts` resolve,
|
|
49
|
+
// so a strand read from any lane reads the one run's records. `undefined` outside a repository: no git
|
|
50
|
+
// directory to key on, so no run to be stranded.
|
|
51
|
+
async function real_resolve_targets(): Promise<RecordTargets | undefined> {
|
|
52
|
+
const directory = await run_carry.repository_directory()
|
|
53
|
+
|
|
54
|
+
if (directory === undefined) return undefined
|
|
55
|
+
|
|
56
|
+
return { carry: run_carry.carry_path(directory), wake: run_wake.wake_path(directory) }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function real_emit_stranded(text: string): Promise<boolean> {
|
|
60
|
+
return await run_event_stream_emit.emit_once(run_event_stream.EVENT_KIND.STRANDED, text)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function real_notify_stranded(body: string): Promise<boolean> {
|
|
64
|
+
return await telegram_notify.stranded({ body, recovery: STRAND_RECOVERY })
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const DEFAULT_PORTS: DetectPorts = {
|
|
68
|
+
resolve_targets: real_resolve_targets,
|
|
69
|
+
read_carry: (target) => run_carry.read_carry(target),
|
|
70
|
+
is_owner_live: run_carry.is_owner_live,
|
|
71
|
+
read_wake: (target) => run_wake.read_wake(target),
|
|
72
|
+
supervisor_liveness: (wake) => run_stranded.supervisor_liveness(wake),
|
|
73
|
+
emit_stranded: real_emit_stranded,
|
|
74
|
+
notify_stranded: real_notify_stranded,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// The three facts, assembled behind the carry-record gate. A non-`carried` read — nothing carried, a
|
|
78
|
+
// spent bound, or an unreadable record — is `undefined`: there is no live budget to be stranded, so the
|
|
79
|
+
// wake record is never read and the judge is never asked.
|
|
80
|
+
async function gather(ports: DetectPorts): Promise<StrandedInput | undefined> {
|
|
81
|
+
const targets = await ports.resolve_targets()
|
|
82
|
+
|
|
83
|
+
if (targets === undefined) return undefined
|
|
84
|
+
|
|
85
|
+
const read = ports.read_carry(targets.carry)
|
|
86
|
+
|
|
87
|
+
if (read.kind !== 'carried') return undefined
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
read,
|
|
91
|
+
is_owner_live: ports.is_owner_live(read.carry),
|
|
92
|
+
supervisor: ports.supervisor_liveness(ports.read_wake(targets.wake)),
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// The marker and the notification, both once per strand episode. `emit_stranded` refuses a second while
|
|
97
|
+
// the strand event is still the newest, and its `false` is what holds the notification back too — so a
|
|
98
|
+
// strand polled every stop reaches the person once, not once a turn.
|
|
99
|
+
async function report(ports: DetectPorts, input: StrandedInput): Promise<void> {
|
|
100
|
+
if (input.read.kind !== 'carried') return
|
|
101
|
+
|
|
102
|
+
const text = run_stranded.describe(input.read.carry)
|
|
103
|
+
|
|
104
|
+
if (await ports.emit_stranded(text)) await ports.notify_stranded(text)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Read the three facts, print nothing, and on a strand leave the marker and notify. The verdict is
|
|
108
|
+
// returned for the CLI to print; the side effects are the report's.
|
|
109
|
+
async function detect_and_report(ports: DetectPorts = DEFAULT_PORTS): Promise<StrandedVerdict> {
|
|
110
|
+
const input = await gather(ports)
|
|
111
|
+
|
|
112
|
+
if (input === undefined) return run_stranded.OK
|
|
113
|
+
|
|
114
|
+
const is_run_stranded = run_stranded.is_stranded(input)
|
|
115
|
+
|
|
116
|
+
if (is_run_stranded) await report(ports, input)
|
|
117
|
+
|
|
118
|
+
return run_stranded.verdict_of(is_run_stranded)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Best-effort for the Stop hook: the detector is a report, so a failure to gather or notify is dropped
|
|
122
|
+
// rather than raised into the stop decision it rides alongside.
|
|
123
|
+
async function run_stranded_check(): Promise<void> {
|
|
124
|
+
try {
|
|
125
|
+
await detect_and_report()
|
|
126
|
+
} catch {
|
|
127
|
+
// Reporting is best-effort: a strand we could not read or send is dropped, never a blocked stop.
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const run_stranded_detect = { DEFAULT_PORTS, detect_and_report, gather, report, run_stranded_check }
|
|
132
|
+
|
|
133
|
+
export { run_stranded_detect }
|
|
134
|
+
export type { DetectPorts, RecordTargets }
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { process_identity } from '#scripts/josh/process-identity'
|
|
2
|
+
import { run_carry, type CarryRead, type RunCarry } from './run-carry'
|
|
3
|
+
import type { RunWake } from './run-wake'
|
|
4
|
+
|
|
5
|
+
// The mechanical judge of a *stranded* run (joshuafolkken/kit#2375). On 2026-09-22 a `backlogrun`'s
|
|
6
|
+
// cost hand-off left the record carried and handed off, the session that cut it died, no successor ever
|
|
7
|
+
// claimed the budget, and no supervisor was watching — so five lanes ran on with nobody driving, and the
|
|
8
|
+
// only way forward was a person noticing and running the recovery by hand. Three facts, read and never
|
|
9
|
+
// weighed, are what say that state has been reached: the budget was handed off, its owner is gone, and
|
|
10
|
+
// no supervisor is alive to wake a successor.
|
|
11
|
+
//
|
|
12
|
+
// **Pure by design, exactly as `backlog-stalled.ts` is.** The carry read, the owner's liveness and the
|
|
13
|
+
// supervisor's are handed in, so the four acceptance cases — all three holding, a live owner, a claimed
|
|
14
|
+
// successor, and an unreadable record — and the supervisor's three-valued liveness are unit-tested
|
|
15
|
+
// without a process table or a wall clock. The I/O that gathers the three facts is
|
|
16
|
+
// `run-stranded-detect.ts`; this file only decides.
|
|
17
|
+
//
|
|
18
|
+
// **It is a report, never a stop.** A false positive costs one notification, never a halted run or a
|
|
19
|
+
// torn-down lane — so every axis is read toward *not* stranded when it cannot be proven: an unreadable
|
|
20
|
+
// carry record is not stranded, and a supervisor whose liveness cannot be established counts as watching.
|
|
21
|
+
// **And recovery is another actor's, not the reader's** (joshuafolkken/kit#1935): the cutting session is
|
|
22
|
+
// refused `busy` and must stay refused, so what the notification names is `run:wake --start`, which
|
|
23
|
+
// starts a supervisor that wakes a *fresh* successor rather than driving the run itself.
|
|
24
|
+
|
|
25
|
+
// **The recovery the notification names.** A supervisor started here reads the handed-off record and
|
|
26
|
+
// wakes a successor that claims it with `--owner "$PPID"` — the reader never adopts the budget itself,
|
|
27
|
+
// which is the `busy` refusal `run-carry.ts` → `is_count_refused` exists to keep.
|
|
28
|
+
const RECOVERY_COMMAND = 'pnpm josh run:wake --start'
|
|
29
|
+
|
|
30
|
+
// The three answers a supervisor's liveness probe gives, named (joshuafolkken/kit#2375). `live` is a
|
|
31
|
+
// supervisor still watching, `gone` is one whose process has died or a record that was never there at
|
|
32
|
+
// all, and `unknown` is the platform answering for nobody — a pid that is alive paired with a start
|
|
33
|
+
// token this machine could not read. The three are kept apart because the strand judge resolves
|
|
34
|
+
// `unknown` toward safety (it counts as watching) while `gone` is the one answer that contributes to a
|
|
35
|
+
// strand.
|
|
36
|
+
type SupervisorLiveness = 'live' | 'gone' | 'unknown'
|
|
37
|
+
|
|
38
|
+
const LIVE: SupervisorLiveness = 'live'
|
|
39
|
+
const GONE: SupervisorLiveness = 'gone'
|
|
40
|
+
const UNKNOWN: SupervisorLiveness = 'unknown'
|
|
41
|
+
|
|
42
|
+
type StrandedVerdict = 'stranded' | 'ok'
|
|
43
|
+
|
|
44
|
+
const STRANDED: StrandedVerdict = 'stranded'
|
|
45
|
+
const OK: StrandedVerdict = 'ok'
|
|
46
|
+
|
|
47
|
+
// The three facts, assembled by the detect layer and consumed only here. `read` carries the carry
|
|
48
|
+
// record's state, `is_owner_live` whether the process the record names still runs, and `supervisor` the
|
|
49
|
+
// three-valued liveness of the wake record.
|
|
50
|
+
interface StrandedInput {
|
|
51
|
+
read: CarryRead
|
|
52
|
+
is_owner_live: boolean
|
|
53
|
+
supervisor: SupervisorLiveness
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// **The supervisor's liveness, three-valued** (joshuafolkken/kit#2375). An absent wake record is `gone`:
|
|
57
|
+
// `run:wake --list` reported `none` in the run this fixes, and nothing watching is the very state a
|
|
58
|
+
// strand needs. A present record is read through `process_identity.is_same_process`, whose own three
|
|
59
|
+
// answers this passes straight through — `true` is `live`, `false` is `gone`, and the platform's "cannot
|
|
60
|
+
// tell" is `unknown`. The prober is injected so the three cases are tested without a real process.
|
|
61
|
+
function supervisor_liveness(
|
|
62
|
+
wake: RunWake | undefined,
|
|
63
|
+
same_process: (
|
|
64
|
+
pid: number | undefined,
|
|
65
|
+
start: string | undefined,
|
|
66
|
+
) => boolean | undefined = process_identity.is_same_process,
|
|
67
|
+
): SupervisorLiveness {
|
|
68
|
+
if (wake === undefined) return GONE
|
|
69
|
+
|
|
70
|
+
const is_same = same_process(wake.pid, wake.process_start)
|
|
71
|
+
|
|
72
|
+
if (is_same === undefined) return UNKNOWN
|
|
73
|
+
|
|
74
|
+
return is_same ? LIVE : GONE
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// **The whole of the judgement, in four reads.** The carry record must be `carried` — an `expired`,
|
|
78
|
+
// `none` or `unreadable` read is never a strand, because there is either no budget to strand or no way
|
|
79
|
+
// to trust what the record says. It must be handed off and *not* yet adopted — `adopt_carry` spends
|
|
80
|
+
// `is_handed_off` the instant a successor claims it, so a claimed successor reads `false` here. The owner
|
|
81
|
+
// must be gone — a live owner is a session still spending the budget, the ordinary in-flight state. And
|
|
82
|
+
// the supervisor must be `gone` — `live` or `unknown` both count as something that could still wake a
|
|
83
|
+
// successor, so only a proven-absent supervisor completes the strand.
|
|
84
|
+
function is_stranded(input: StrandedInput): boolean {
|
|
85
|
+
if (
|
|
86
|
+
input.read.kind !== 'carried' ||
|
|
87
|
+
input.read.carry.is_handed_off !== true ||
|
|
88
|
+
input.is_owner_live
|
|
89
|
+
) {
|
|
90
|
+
return false
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return input.supervisor === GONE
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// The one line a person reads in the notification and on the stream: which run is stranded, and why. The
|
|
97
|
+
// carry record's own summary carries the counts; this frames it as the strand it is.
|
|
98
|
+
function describe(carry: RunCarry): string {
|
|
99
|
+
return `Run stranded — ${run_carry.describe_carry(carry)}. The owner is gone, no cut successor claimed the budget, and no supervisor is watching.`
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function verdict_of(is_run_stranded: boolean): StrandedVerdict {
|
|
103
|
+
return is_run_stranded ? STRANDED : OK
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const run_stranded = {
|
|
107
|
+
GONE,
|
|
108
|
+
LIVE,
|
|
109
|
+
OK,
|
|
110
|
+
RECOVERY_COMMAND,
|
|
111
|
+
STRANDED,
|
|
112
|
+
UNKNOWN,
|
|
113
|
+
describe,
|
|
114
|
+
is_stranded,
|
|
115
|
+
supervisor_liveness,
|
|
116
|
+
verdict_of,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export { run_stranded }
|
|
120
|
+
export type { StrandedInput, StrandedVerdict, SupervisorLiveness }
|