@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,126 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
|
|
4
|
+
// The session state a cut carries across the process boundary (joshuafolkken/kit#2354). `RunCut`'s six
|
|
5
|
+
// scalar fields say *which* tree a fresh process resumes into — the branch, the issue, that a declared
|
|
6
|
+
// cut put it here. This says *what the run was told to do* there, which nothing else recovers: the
|
|
7
|
+
// user's instruction is not on GitHub, and what was done — or deliberately left alone — is not written
|
|
8
|
+
// on the diff. Without it a resumed session sees a working tree it did not build, is handed no
|
|
9
|
+
// instruction, and is put under the refactoring limits `CLAUDE.md` sets, so the shortest path out is to
|
|
10
|
+
// restructure or delete code it does not understand.
|
|
11
|
+
//
|
|
12
|
+
// **This is not the conversation the cut exists to drop.** joshuafolkken/kit#1839 measured 176K of a
|
|
13
|
+
// lane's 204K output as accumulated thinking, and the cut's whole point is to shed it. The instruction
|
|
14
|
+
// and a curated list of what is done, left, and untouched is the irreducible intent under that
|
|
15
|
+
// thinking — a few short lines, bounded by `MAX_HANDOFF_BYTES` in `run-cut.ts` — so carrying it keeps
|
|
16
|
+
// the resume on course without re-establishing the context the cut dropped.
|
|
17
|
+
interface Handoff {
|
|
18
|
+
// The user's instruction for this run, verbatim — the constraints and the "leave this alone" nuances
|
|
19
|
+
// a fresh process has no other way to learn.
|
|
20
|
+
instruction: string
|
|
21
|
+
// What the run has finished, what it has not, and what it chose not to touch. Each is a short list,
|
|
22
|
+
// empty when there is nothing yet to say — an empty `untouched` is a legitimate "nothing was left
|
|
23
|
+
// alone", not a missing field.
|
|
24
|
+
completed: ReadonlyArray<string>
|
|
25
|
+
remaining: ReadonlyArray<string>
|
|
26
|
+
untouched: ReadonlyArray<string>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const handoff_schema = z.object({
|
|
30
|
+
instruction: z.string(),
|
|
31
|
+
completed: z.array(z.string()),
|
|
32
|
+
remaining: z.array(z.string()),
|
|
33
|
+
untouched: z.array(z.string()),
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// The label each list is printed under when the handoff is shown to the resumed session, kept beside
|
|
37
|
+
// the field so a rename cannot drift them apart.
|
|
38
|
+
const COMPLETED_LABEL = 'Completed'
|
|
39
|
+
const REMAINING_LABEL = 'Remaining'
|
|
40
|
+
const UNTOUCHED_LABEL = 'Deliberately untouched'
|
|
41
|
+
const INSTRUCTION_LABEL = 'Instruction (verbatim)'
|
|
42
|
+
const EMPTY_LIST_NOTE = '(none)'
|
|
43
|
+
|
|
44
|
+
function parse_handoff(raw: string): Handoff | undefined {
|
|
45
|
+
try {
|
|
46
|
+
const parsed = handoff_schema.safeParse(JSON.parse(raw))
|
|
47
|
+
|
|
48
|
+
return parsed.success ? parsed.data : undefined
|
|
49
|
+
} catch {
|
|
50
|
+
return undefined
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// A path given but unreadable, or holding text that is not a well-formed handoff, is `undefined` — the
|
|
55
|
+
// caller refuses the cut rather than writing a record that cannot carry the instruction it was for.
|
|
56
|
+
function read_handoff_file(handoff_path: string): Handoff | undefined {
|
|
57
|
+
try {
|
|
58
|
+
return parse_handoff(readFileSync(handoff_path, 'utf8'))
|
|
59
|
+
} catch {
|
|
60
|
+
return undefined
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// A complete handoff carries a non-empty instruction; the lists may be empty. This is the required
|
|
65
|
+
// field the resume checks so a session is never silently continued without the instruction it needs
|
|
66
|
+
// (joshuafolkken/kit#2354).
|
|
67
|
+
function is_complete_handoff(handoff: Handoff | undefined): boolean {
|
|
68
|
+
return handoff !== undefined && handoff.instruction.trim() !== ''
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// The outcome of reading a `--handoff` path: `ok` with the handoff (or `undefined` when no path was
|
|
72
|
+
// given), or `bad` when the path was given but could not be read or was too large for the record.
|
|
73
|
+
type HandoffLoad = { kind: 'ok'; handoff?: Handoff | undefined } | { kind: 'bad'; note: string }
|
|
74
|
+
|
|
75
|
+
function is_within_bound(handoff: Handoff, max_bytes: number): boolean {
|
|
76
|
+
return Buffer.byteLength(JSON.stringify(handoff), 'utf8') <= max_bytes
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// A path is read into a handoff, refused when it will not parse or would push the record past its
|
|
80
|
+
// bound — the cut is only worth its resume while the record stays small (joshuafolkken/kit#2354).
|
|
81
|
+
function load_handoff(handoff_path: string | undefined, max_bytes: number): HandoffLoad {
|
|
82
|
+
if (handoff_path === undefined) return { kind: 'ok', handoff: undefined }
|
|
83
|
+
|
|
84
|
+
const handoff = read_handoff_file(handoff_path)
|
|
85
|
+
|
|
86
|
+
if (handoff === undefined) {
|
|
87
|
+
return { kind: 'bad', note: `--handoff ${handoff_path} is not a readable handoff file` }
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!is_within_bound(handoff, max_bytes)) {
|
|
91
|
+
return { kind: 'bad', note: `--handoff ${handoff_path} is too large to carry across the cut` }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return { kind: 'ok', handoff }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function describe_list(label: string, items: ReadonlyArray<string>): string {
|
|
98
|
+
if (items.length === 0) return `${label}: ${EMPTY_LIST_NOTE}`
|
|
99
|
+
|
|
100
|
+
const bullets = items.map((item) => ` - ${item}`).join('\n')
|
|
101
|
+
|
|
102
|
+
return `${label}:\n${bullets}`
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// The block the resume prints to standard error so the fresh process continues on the original
|
|
106
|
+
// instruction rather than the tree alone.
|
|
107
|
+
function describe_handoff(handoff: Handoff): string {
|
|
108
|
+
return [
|
|
109
|
+
`${INSTRUCTION_LABEL}:\n${handoff.instruction}`,
|
|
110
|
+
describe_list(COMPLETED_LABEL, handoff.completed),
|
|
111
|
+
describe_list(REMAINING_LABEL, handoff.remaining),
|
|
112
|
+
describe_list(UNTOUCHED_LABEL, handoff.untouched),
|
|
113
|
+
].join('\n\n')
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const run_cut_handoff = {
|
|
117
|
+
describe_handoff,
|
|
118
|
+
handoff_schema,
|
|
119
|
+
is_complete_handoff,
|
|
120
|
+
load_handoff,
|
|
121
|
+
parse_handoff,
|
|
122
|
+
read_handoff_file,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export type { Handoff, HandoffLoad }
|
|
126
|
+
export { run_cut_handoff }
|
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process'
|
|
2
|
+
import { agent_role_profile } from '#scripts/agent/agent-role-profile'
|
|
3
|
+
import { backlog_budget } from '#scripts/backlog/backlog-budget'
|
|
4
|
+
import { CONTEXT_CUT_THRESHOLD } from '#scripts/cost-runtime/context-cut-threshold'
|
|
5
|
+
import { git_utilities } from '#scripts/git/constants'
|
|
6
|
+
import { git_command } from '#scripts/git/git-command'
|
|
7
|
+
import { git_location_environment } from '#scripts/git/git-location-environment'
|
|
8
|
+
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
9
|
+
import { lane_child_invocation } from '#scripts/lane/lane-child-invocation'
|
|
10
|
+
import { z } from 'zod'
|
|
11
|
+
import { run_cut_handoff, type Handoff } from './run-cut-handoff'
|
|
12
|
+
import { run_hold } from './run-hold'
|
|
13
|
+
|
|
14
|
+
// joshuafolkken/kit#1839: a lane child is a detached `fullrun #<N>` process, and the thinking it
|
|
15
|
+
// accumulates while implementing rides on every later API call in the same session — measured at 176K
|
|
16
|
+
// of 204K output on joshuafolkken/kit#1837. This record lets that child **end its process before the
|
|
17
|
+
// gate** and have a fresh one resume from the gate onward, so the accumulated thinking is dropped
|
|
18
|
+
// rather than carried. The conversation is not persisted: joshuafolkken/kit#1567 found a compaction
|
|
19
|
+
// does not reduce billing, so the fresh session reads the plan and the recorded decisions back off
|
|
20
|
+
// GitHub and finds the implementation still sitting in the lane's own working tree.
|
|
21
|
+
//
|
|
22
|
+
// **The unit is the working tree, exactly as `run-hold.ts` keys itself** — one branch and one
|
|
23
|
+
// uncommitted diff, a single lane — so the key is the work tree's own git directory (index 0), reused
|
|
24
|
+
// from `run-hold.ts` rather than re-derived. The two records sit side by side: `run-hold` guards the
|
|
25
|
+
// tree, and this one carries a single child's pre-gate resume point across the process boundary.
|
|
26
|
+
//
|
|
27
|
+
// **The working tree is not in the record, because it never left the disk.** Ending the process does
|
|
28
|
+
// not touch the lane directory: the branch and the uncommitted implementation are still there when
|
|
29
|
+
// the fresh process starts in the same directory. The record carries only what a fresh process cannot
|
|
30
|
+
// recover on its own — which issue, which branch, and that a declared cut (not a crash) put it here —
|
|
31
|
+
// and the resume *verifies* the tree against it rather than restoring it.
|
|
32
|
+
//
|
|
33
|
+
// **No owner is recorded, and that is deliberate** (joshuafolkken/kit#1839 review). A cut relaunches
|
|
34
|
+
// exactly one fresh process — `begin_cut`'s exclusive create refuses a second cut — so there is no
|
|
35
|
+
// live owner a resume must be blocked against, and recording the cutting session's pid would only
|
|
36
|
+
// stall the resume against a process that is on its way out. **Resume uniqueness rests on the
|
|
37
|
+
// hand-off instead**: `adopt_cut` spends `is_handed_off`, so a second resume reads a record no longer
|
|
38
|
+
// handed off and is refused `stale`, and its exclusive create refuses a truly concurrent second
|
|
39
|
+
// adopter.
|
|
40
|
+
|
|
41
|
+
const CUT_PREFIX = 'josh-run-cut-'
|
|
42
|
+
// **The two phase names are `agent-role-profile.ts`'s** (joshuafolkken/kit#2382): a lane child resumes
|
|
43
|
+
// into a phase, and that module resolves the effort the resumed child runs at from the same name. Reading
|
|
44
|
+
// them from there rather than restating the literals here is what keeps the phase a cut records and the
|
|
45
|
+
// phase the effort table is keyed on from drifting. `PRE_GATE_PHASE` is the boundary before the gate;
|
|
46
|
+
// `IMPLEMENTATION_PHASE` (joshuafolkken/kit#1933) drops the thinking accumulated *during* implementation
|
|
47
|
+
// and resumes back into implementation (`resumes_into_implementation`); only the pre-gate cut resumes
|
|
48
|
+
// into the gate. The setup-phase cut (joshuafolkken/kit#2346) was retired by joshuafolkken/kit#2489.
|
|
49
|
+
const { PRE_GATE_PHASE, IMPLEMENTATION_PHASE } = agent_role_profile
|
|
50
|
+
// **The measurement is the parent hand-off's, never a second one** (joshuafolkken/kit#1933). The lane
|
|
51
|
+
// child decides whether to take this cut with `pnpm josh cost --cut`
|
|
52
|
+
// — the same per-request billed-input measurement (`cost_verdict.per_request_cost`) the parent's
|
|
53
|
+
// `pnpm josh cost --cut` hand-off uses (`backlogrun-progress.md` → "The hand-off"). The shared
|
|
54
|
+
// threshold prevents the scheduler and worker boundaries from drifting apart.
|
|
55
|
+
const IMPLEMENTATION_CONTEXT_THRESHOLD = CONTEXT_CUT_THRESHOLD
|
|
56
|
+
// **The whole-run bound is `backlog-budget.ts`'s, imported rather than restated** — the same reuse
|
|
57
|
+
// `run-carry.ts` makes. A resume is expected within seconds of the cut, so this age is only a backstop
|
|
58
|
+
// against a fresh process that never started; an expired record is cleared and replaced by the next
|
|
59
|
+
// cut rather than blocking it.
|
|
60
|
+
const CUT_MAX_AGE_MS = backlog_budget.WHOLE_RUN_BUDGET_MS
|
|
61
|
+
const CUT_MAX_AGE_HOURS = backlog_budget.WHOLE_RUN_BUDGET_HOURS
|
|
62
|
+
|
|
63
|
+
// The synchronous git read runs inside a `PreToolUse` hook, which holds the tool call for as long as
|
|
64
|
+
// it takes; `rev-parse` takes no lock, so anything past a second is a fault rather than slow work.
|
|
65
|
+
const GIT_READ_TIMEOUT_MS = 5000
|
|
66
|
+
|
|
67
|
+
// The two lines `GIT_DIRECTORY_ARGUMENTS` prints, in order: the work tree's own git directory, then the
|
|
68
|
+
// common one every lane of a repository shares. `git_directories` reads the same two asynchronously.
|
|
69
|
+
const WORKTREE_DIRECTORY_INDEX = 0
|
|
70
|
+
|
|
71
|
+
const END_COMMAND = 'pnpm josh run:cut --end'
|
|
72
|
+
const READ_COMMAND = 'pnpm josh run:cut --json'
|
|
73
|
+
|
|
74
|
+
// The mechanical bound on the hand-off record's serialized size (joshuafolkken/kit#2346,
|
|
75
|
+
// joshuafolkken/kit#2354). The cut is only worth its resume while the record a fresh process reads back
|
|
76
|
+
// stays small — a record that grew to carry the conversation would defeat the whole point,
|
|
77
|
+
// re-establishing at the resume the context the cut dropped. The scalar fields are each tiny (an issue
|
|
78
|
+
// number, a branch name, a phase, an ISO timestamp, a flag); the `handoff` (joshuafolkken/kit#2354)
|
|
79
|
+
// carries the user's instruction and a curated list of what is done, left and untouched — the
|
|
80
|
+
// irreducible intent, not the conversation, so it stays a few short lines. The cap is set to hold that
|
|
81
|
+
// and refuse a field that ever grew unbounded at the write rather than carrying it. `begin_cut`
|
|
82
|
+
// enforces it.
|
|
83
|
+
const MAX_HANDOFF_BYTES = 8192
|
|
84
|
+
|
|
85
|
+
interface RunCut {
|
|
86
|
+
// The identity of the run this cut belongs to — `fullrun #<N>`, built through
|
|
87
|
+
// `lane_child_invocation.child_invocation` so it is single-sourced with the dispatch that first launched the
|
|
88
|
+
// child. **It is the resume-matching key, not the relaunch prompt** (joshuafolkken/kit#2022): the
|
|
89
|
+
// relaunch gives the fresh process `lane_child_invocation.resume_invocation` instead, while
|
|
90
|
+
// `is_declared_cut` / `is_adopted_cut` still compare this field against `invocation_for(issue)` to
|
|
91
|
+
// confirm the record belongs to the resuming issue.
|
|
92
|
+
invocation: string
|
|
93
|
+
issue: string
|
|
94
|
+
// The branch the implementation sits on. The resume refuses to continue on any other branch, so a
|
|
95
|
+
// fresh process that started in the wrong tree is caught rather than gating someone else's work.
|
|
96
|
+
branch: string
|
|
97
|
+
// Where in the run the cut happened. One boundary exists today (`pre-gate`); the field is here so a
|
|
98
|
+
// second one can be told apart rather than guessed.
|
|
99
|
+
phase: string
|
|
100
|
+
cut_at: string
|
|
101
|
+
// Set by the cut, and spent by the adoption. A crash never sets it, which is what makes a declared
|
|
102
|
+
// cut the only state that resumes, and spending it is what makes a resume unique.
|
|
103
|
+
is_handed_off?: boolean | undefined
|
|
104
|
+
// The instruction and work state the run was told to carry across the cut (joshuafolkken/kit#2354).
|
|
105
|
+
// Optional so a record written by the six scalar fields alone still parses — the backward-compatible
|
|
106
|
+
// legacy shape — while a resume into implementation refuses to continue without it (`classify_resume`
|
|
107
|
+
// → `incomplete`), so a session is never silently continued lacking the instruction it needs.
|
|
108
|
+
handoff?: Handoff | undefined
|
|
109
|
+
// Set when `run:merge` found this cut still unadopted after every process of the lane had gone and
|
|
110
|
+
// relaunched its successor itself (joshuafolkken/kit#2484). The fallback fires once per cut: a
|
|
111
|
+
// successor that dies again before adopting is not relaunched a second time, so a lane that keeps
|
|
112
|
+
// failing its resume is parked rather than relaunched forever.
|
|
113
|
+
is_merge_relaunched?: boolean | undefined
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// The current tree's state, read once and handed to the pure classifier.
|
|
117
|
+
interface CutState {
|
|
118
|
+
branch: string
|
|
119
|
+
is_dirty: boolean
|
|
120
|
+
is_held: boolean
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// The fields a cut is written from, bundled so `begin_cut` stays within the parameter limit. `phase`
|
|
124
|
+
// is which boundary the cut was taken at — `PRE_GATE_PHASE` or `IMPLEMENTATION_PHASE` — and it is what
|
|
125
|
+
// the resume reads to decide whether the fresh process continues to the gate or back into
|
|
126
|
+
// implementation (joshuafolkken/kit#1933).
|
|
127
|
+
interface CutSpec {
|
|
128
|
+
issue: string
|
|
129
|
+
branch: string
|
|
130
|
+
phase: string
|
|
131
|
+
// The instruction and work state to carry, absent for a pre-gate cut that resumes into the gate
|
|
132
|
+
// rather than into implementation (joshuafolkken/kit#2354).
|
|
133
|
+
handoff?: Handoff | undefined
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// What the resume classifier is asked about, gathered from the fresh process's own git state so the
|
|
137
|
+
// record can be checked against reality rather than trusted.
|
|
138
|
+
interface CutResumeRequest {
|
|
139
|
+
issue: string
|
|
140
|
+
current_branch: string
|
|
141
|
+
is_dirty: boolean
|
|
142
|
+
is_held: boolean
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// **`resume` carries the run on; `stale` stops it; `handed-off` says a successor already took it.** A
|
|
146
|
+
// resume failure — wrong branch, a clean tree, an expired record, no declared cut, or a tree no longer
|
|
147
|
+
// under its hold — is `stale`. A record a successor has already adopted — `is_handed_off` spent back to
|
|
148
|
+
// `false` — is `handed-off`, so a process woken after its own cut is told to stop rather than sent to
|
|
149
|
+
// investigate a tree that is not wrong (joshuafolkken/kit#1935). A record that matches the tree but
|
|
150
|
+
// resumes into implementation without an instruction is `incomplete` — the run is not silently
|
|
151
|
+
// continued lacking what it was told to do (joshuafolkken/kit#2354).
|
|
152
|
+
type CutResume = 'resume' | 'stale' | 'handed-off' | 'incomplete'
|
|
153
|
+
|
|
154
|
+
type CutRead =
|
|
155
|
+
| { kind: 'none' }
|
|
156
|
+
| { kind: 'carried'; cut: RunCut }
|
|
157
|
+
| { kind: 'expired'; cut: RunCut }
|
|
158
|
+
| { kind: 'unreadable' }
|
|
159
|
+
|
|
160
|
+
const NONE_READ: CutRead = { kind: 'none' }
|
|
161
|
+
const UNREADABLE_READ: CutRead = { kind: 'unreadable' }
|
|
162
|
+
|
|
163
|
+
const run_cut_schema = z.object({
|
|
164
|
+
invocation: z.string(),
|
|
165
|
+
issue: z.string(),
|
|
166
|
+
branch: z.string(),
|
|
167
|
+
phase: z.string(),
|
|
168
|
+
cut_at: z.string(),
|
|
169
|
+
is_handed_off: z.boolean().optional(),
|
|
170
|
+
handoff: run_cut_handoff.handoff_schema.optional(),
|
|
171
|
+
is_merge_relaunched: z.boolean().optional(),
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
function cut_path(git_directory: string): string {
|
|
175
|
+
return stamp_file.stamp_path(CUT_PREFIX, git_directory)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// The work tree's own git directory (index 0), reused from `run-hold.ts` so a cut and the hold it
|
|
179
|
+
// resumes under key to exactly the same tree — never a second copy of the index-0 derivation.
|
|
180
|
+
const { worktree_directory } = run_hold
|
|
181
|
+
|
|
182
|
+
// `fullrun #<N>`, validated and formatted once in `lane_child_invocation` so the record and
|
|
183
|
+
// the dispatch cannot disagree about what a lane child is.
|
|
184
|
+
function invocation_for(issue: string): string {
|
|
185
|
+
return lane_child_invocation.child_invocation(issue)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function parse_cut(raw: string): RunCut | undefined {
|
|
189
|
+
try {
|
|
190
|
+
const parsed = run_cut_schema.safeParse(JSON.parse(raw))
|
|
191
|
+
|
|
192
|
+
return parsed.success ? parsed.data : undefined
|
|
193
|
+
} catch {
|
|
194
|
+
return undefined
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// A `cut_at` that is not a date is read as expired, for the reason `run-carry.ts` reads an unparsable
|
|
199
|
+
// `started_at` that way: a record nothing can ever expire is the one state the bound exists to
|
|
200
|
+
// prevent.
|
|
201
|
+
function is_expired(cut: RunCut, now: Date): boolean {
|
|
202
|
+
const started = Date.parse(cut.cut_at)
|
|
203
|
+
|
|
204
|
+
if (Number.isNaN(started)) return true
|
|
205
|
+
|
|
206
|
+
return now.getTime() - started > CUT_MAX_AGE_MS
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function classify(raw: string | undefined, now: Date): CutRead {
|
|
210
|
+
if (raw === undefined) return NONE_READ
|
|
211
|
+
|
|
212
|
+
const cut = parse_cut(raw)
|
|
213
|
+
|
|
214
|
+
if (cut === undefined) return UNREADABLE_READ
|
|
215
|
+
|
|
216
|
+
return { kind: is_expired(cut, now) ? 'expired' : 'carried', cut }
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function read_cut(target: string, now: Date = new Date()): CutRead {
|
|
220
|
+
return classify(stamp_file.read_stamp_text(target), now)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// **The same read as `read_cut(cut_path(await worktree_directory()))`, taken synchronously**
|
|
224
|
+
// (joshuafolkken/kit#1864). The pre-gate cut is enforced from a `PreToolUse` guard, and a guard
|
|
225
|
+
// answers synchronously or not at all — so the one git call the path derivation needs is made here
|
|
226
|
+
// with `git_command.GIT_DIRECTORY_ARGUMENTS`, the same argument list the asynchronous reader uses,
|
|
227
|
+
// rather than a second spelling of it. Everything after the path is already shared: `cut_path` keys
|
|
228
|
+
// the record and `classify` parses and expires it.
|
|
229
|
+
//
|
|
230
|
+
// **A fault reads as "no cut was taken", and that direction is deliberate rather than fail-open.** A
|
|
231
|
+
// checkout git cannot describe, a record that will not parse and an expired one all come back
|
|
232
|
+
// `undefined`, which the pre-gate guard treats as uncut — so it speaks rather than staying silent.
|
|
233
|
+
// The alternative errs the other way: a read fault would be taken for "already cut" and the guard
|
|
234
|
+
// would go quiet on exactly the run it exists for. The cost of this direction is one refusal a lane
|
|
235
|
+
// can answer by reissuing, since that row is delivered once per run.
|
|
236
|
+
function git_directories_sync(cwd?: string): ReadonlyArray<string> {
|
|
237
|
+
try {
|
|
238
|
+
// The binary is resolved through `git_utilities` exactly as `git-spawn.ts` resolves it, so this
|
|
239
|
+
// call does not answer to whatever `PATH` happens to hold. It runs the binary directly with an
|
|
240
|
+
// argument array and no `shell` option, and both are internally controlled, never untrusted
|
|
241
|
+
// input.
|
|
242
|
+
const output = execFileSync(
|
|
243
|
+
git_utilities.get_git_command_for_spawn(),
|
|
244
|
+
[...git_command.GIT_DIRECTORY_ARGUMENTS],
|
|
245
|
+
// git's own diagnostics are discarded: a checkout it cannot describe is already the
|
|
246
|
+
// `undefined` below, and a hook that let `fatal: not a git repository` through would print it
|
|
247
|
+
// in front of a tool call that is about to be allowed.
|
|
248
|
+
// A `PreToolUse` hook holds the tool call while it runs, so the read is bounded rather than
|
|
249
|
+
// left to whatever git does.
|
|
250
|
+
// `cwd` is set only by `lane_cut_sync`, which reads another lane's record from the parent.
|
|
251
|
+
// With a `cwd`, the git location variables are cleared so it is what git answers for: a hook
|
|
252
|
+
// exports `GIT_DIR`, which beats `cwd` and would name the hook's checkout instead
|
|
253
|
+
// (joshuafolkken/kit#2515). Without one the environment is kept, so this read resolves the same
|
|
254
|
+
// checkout as the asynchronous `git_directories` that writes the record.
|
|
255
|
+
{
|
|
256
|
+
cwd,
|
|
257
|
+
env:
|
|
258
|
+
cwd === undefined
|
|
259
|
+
? process.env
|
|
260
|
+
: { ...process.env, ...git_location_environment.location_free_environment() },
|
|
261
|
+
encoding: 'utf8',
|
|
262
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
263
|
+
timeout: GIT_READ_TIMEOUT_MS,
|
|
264
|
+
},
|
|
265
|
+
) // NOSONAR
|
|
266
|
+
|
|
267
|
+
return output.split('\n').filter((line) => line !== '')
|
|
268
|
+
} catch {
|
|
269
|
+
return []
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// The work tree's own git directory (index 0), the same read `git_directories` makes asynchronously —
|
|
274
|
+
// the record and the pre-gate guard both key on it.
|
|
275
|
+
function worktree_git_directory_sync(): string | undefined {
|
|
276
|
+
return git_directories_sync()[WORKTREE_DIRECTORY_INDEX]
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// **The directory is injectable so a test never has to write to the live record.** Keyed to the work
|
|
280
|
+
// tree, that record is the one a resumed lane child depends on, and a suite that wrote to it would
|
|
281
|
+
// erase the very state the guard reads — the unit suite runs inside `pnpm josh gate`, which is the
|
|
282
|
+
// call the guard is standing in front of.
|
|
283
|
+
function carried_cut_sync(
|
|
284
|
+
now: Date = new Date(),
|
|
285
|
+
directory: string | undefined = worktree_git_directory_sync(),
|
|
286
|
+
): RunCut | undefined {
|
|
287
|
+
if (directory === undefined) return undefined
|
|
288
|
+
|
|
289
|
+
const read = read_cut(cut_path(directory), now)
|
|
290
|
+
|
|
291
|
+
return read.kind === 'carried' ? read.cut : undefined
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// A lane's carried cut, read from outside the lane (joshuafolkken/kit#2484). The record is keyed to the
|
|
295
|
+
// lane's own git directory, so the parent — standing in the main checkout — resolves that directory
|
|
296
|
+
// from the lane's path rather than its own, and gets the record path back to mark it.
|
|
297
|
+
function lane_cut_sync(lane_directory: string): { target: string; cut: RunCut } | undefined {
|
|
298
|
+
const directory = git_directories_sync(lane_directory)[WORKTREE_DIRECTORY_INDEX]
|
|
299
|
+
|
|
300
|
+
if (directory === undefined) return undefined
|
|
301
|
+
|
|
302
|
+
const cut = carried_cut_sync(new Date(), directory)
|
|
303
|
+
|
|
304
|
+
return cut === undefined ? undefined : { target: cut_path(directory), cut }
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function fresh_cut(spec: CutSpec, now: Date): RunCut {
|
|
308
|
+
return {
|
|
309
|
+
invocation: invocation_for(spec.issue),
|
|
310
|
+
issue: spec.issue,
|
|
311
|
+
branch: spec.branch,
|
|
312
|
+
phase: spec.phase,
|
|
313
|
+
cut_at: now.toISOString(),
|
|
314
|
+
is_handed_off: true,
|
|
315
|
+
handoff: spec.handoff,
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// **The implementation cut resumes back into implementation; the pre-gate cut resumes into the gate**
|
|
320
|
+
// (joshuafolkken/kit#1933). The resume shape — the `resume-impl` verdict and the record cleared on
|
|
321
|
+
// adoption — is named once here rather than spelled as a phase comparison at each call site.
|
|
322
|
+
function resumes_into_implementation(phase: string): boolean {
|
|
323
|
+
return phase === IMPLEMENTATION_PHASE
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Whether a record serializes within the hand-off bound. The record a fresh process reads back must
|
|
327
|
+
// stay small, or the resume re-establishes the very context the cut dropped (joshuafolkken/kit#2346).
|
|
328
|
+
function within_handoff_bound(cut: RunCut): boolean {
|
|
329
|
+
return Buffer.byteLength(JSON.stringify(cut), 'utf8') <= MAX_HANDOFF_BYTES
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Whether the record a spec would write fits the bound. `load_handoff` bounds the handoff alone, but the
|
|
333
|
+
// record also carries the scalar fields, so a handoff just under the cap can still overflow once
|
|
334
|
+
// assembled — the caller checks this before `begin_cut` so that case reports `bad-handoff` rather than
|
|
335
|
+
// the exclusive-create's `busy` (joshuafolkken/kit#2354).
|
|
336
|
+
function record_within_bound(spec: CutSpec, now: Date = new Date()): boolean {
|
|
337
|
+
return within_handoff_bound(fresh_cut(spec, now))
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// **Create-exclusively, exactly as `run-hold.ts` claims a tree.** A record already here means a cut is
|
|
341
|
+
// already in flight for this tree, so `undefined` is "do not launch a second one" rather than an
|
|
342
|
+
// error — the exclusive create is what makes a double cut, and so a double relaunch, impossible. A
|
|
343
|
+
// record that would not fit the hand-off bound is refused the same way rather than written and carried.
|
|
344
|
+
function begin_cut(target: string, spec: CutSpec, now: Date = new Date()): RunCut | undefined {
|
|
345
|
+
const cut = fresh_cut(spec, now)
|
|
346
|
+
|
|
347
|
+
if (!within_handoff_bound(cut)) return undefined
|
|
348
|
+
|
|
349
|
+
return stamp_file.create_stamp(target, cut) ? cut : undefined
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// A declared cut for exactly this invocation. A crash leaves `is_handed_off` unset, so it never
|
|
353
|
+
// matches; a record left by another issue's run names a different invocation; and a spent hand-off —
|
|
354
|
+
// the mark an adoption already took — is no longer a declared cut, which is what stops a second
|
|
355
|
+
// resume.
|
|
356
|
+
function is_declared_cut(cut: RunCut, issue: string): boolean {
|
|
357
|
+
return cut.is_handed_off === true && cut.invocation === invocation_for(issue)
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// The tree the fresh process is standing in matches the one the cut recorded: same branch, same
|
|
361
|
+
// issue, the implementation still uncommitted, and still under the hold the cutting run held. A clean
|
|
362
|
+
// tree means the work is gone; a tree with no hold is not the one the cut was taken in.
|
|
363
|
+
function matches_state(cut: RunCut, request: CutResumeRequest): boolean {
|
|
364
|
+
return (
|
|
365
|
+
cut.branch === request.current_branch &&
|
|
366
|
+
cut.issue === request.issue &&
|
|
367
|
+
request.is_dirty &&
|
|
368
|
+
request.is_held
|
|
369
|
+
)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// A record a successor already adopted — the hand-off spent back to `false` for this issue's
|
|
373
|
+
// invocation. It is told apart from a crash record (`is_handed_off` never set) so a process woken after
|
|
374
|
+
// its own cut learns the run was carried on rather than being sent to investigate
|
|
375
|
+
// (joshuafolkken/kit#1935).
|
|
376
|
+
function is_adopted_cut(cut: RunCut, issue: string): boolean {
|
|
377
|
+
return cut.is_handed_off === false && cut.invocation === invocation_for(issue)
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// A cut that resumes into implementation must carry the instruction; a pre-gate cut resumes into the
|
|
381
|
+
// gate and needs none, so it always passes (joshuafolkken/kit#2354).
|
|
382
|
+
// It reads a spec as well as a record, so `run:cut` refuses to write the cut its resume would refuse
|
|
383
|
+
// (joshuafolkken/kit#2484) with the same predicate the resume answers `incomplete` on.
|
|
384
|
+
function has_required_handoff(cut: Pick<RunCut, 'phase' | 'handoff'>): boolean {
|
|
385
|
+
return !resumes_into_implementation(cut.phase) || run_cut_handoff.is_complete_handoff(cut.handoff)
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Whether `run:merge` may relaunch the successor of a lane whose processes have all gone
|
|
389
|
+
// (joshuafolkken/kit#2484): a cut this issue declared and no successor adopted, carrying what its resume
|
|
390
|
+
// needs, and not relaunched by the fallback before. The tree itself is verified by the resume.
|
|
391
|
+
function is_relaunchable(cut: RunCut, issue: string): boolean {
|
|
392
|
+
return (
|
|
393
|
+
is_declared_cut(cut, issue) && has_required_handoff(cut) && cut.is_merge_relaunched !== true
|
|
394
|
+
)
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Marks the fallback relaunch spent, with the same remove-then-exclusive-create `adopt_cut` uses. A
|
|
398
|
+
// later `run:merge` reads the mark and does not relaunch. It does not arbitrate two truly concurrent
|
|
399
|
+
// ones — both creates can succeed — so a stray session is refused by the carry ownership check
|
|
400
|
+
// `run:merge` asks first.
|
|
401
|
+
function mark_merge_relaunched(target: string, cut: RunCut): boolean {
|
|
402
|
+
stamp_file.remove_stamp(target)
|
|
403
|
+
|
|
404
|
+
return stamp_file.create_stamp(target, { ...cut, is_merge_relaunched: true })
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// A resume requires a declared cut, a matching tree, and — for a resume into implementation — the
|
|
408
|
+
// instruction. Anything short of a match is `stale`, which stops the run rather than gating a
|
|
409
|
+
// half-written or foreign tree, or one no longer under its hold; a match that lacks the instruction is
|
|
410
|
+
// `incomplete`, so the run is not silently continued without what it was told to do. A record a
|
|
411
|
+
// successor already adopted is `handed-off` — a benign stop rather than a failure.
|
|
412
|
+
function classify_resume(cut: RunCut, request: CutResumeRequest): CutResume {
|
|
413
|
+
if (is_adopted_cut(cut, request.issue)) return 'handed-off'
|
|
414
|
+
|
|
415
|
+
if (!is_declared_cut(cut, request.issue) || !matches_state(cut, request)) return 'stale'
|
|
416
|
+
|
|
417
|
+
return has_required_handoff(cut) ? 'resume' : 'incomplete'
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Taking the hand-off over spends it, so a second `--resume` reads `is_handed_off: false` and is
|
|
421
|
+
// refused `stale`. It removes and then creates exclusively, so two truly concurrent resumes cannot
|
|
422
|
+
// both win the create.
|
|
423
|
+
function adopt_cut(target: string, cut: RunCut): RunCut | undefined {
|
|
424
|
+
const next: RunCut = { ...cut, is_handed_off: false }
|
|
425
|
+
|
|
426
|
+
stamp_file.remove_stamp(target)
|
|
427
|
+
|
|
428
|
+
return stamp_file.create_stamp(target, next) ? next : undefined
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function end_cut(target: string): void {
|
|
432
|
+
stamp_file.remove_stamp(target)
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Whether a run hold still stands over this tree — present as `held` or as an aged-out `stale`, but
|
|
436
|
+
// present. A tree with no hold at all is not the one a cut was taken in, so the resume refuses it.
|
|
437
|
+
function tree_is_held(directory: string | undefined): boolean {
|
|
438
|
+
if (directory === undefined) return false
|
|
439
|
+
|
|
440
|
+
const read = run_hold.read_hold(run_hold.hold_path(directory))
|
|
441
|
+
|
|
442
|
+
return read.kind === 'held' || read.kind === 'stale'
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async function current_state(): Promise<CutState> {
|
|
446
|
+
const branch = await git_command.branch()
|
|
447
|
+
const is_dirty = await run_hold.is_tree_dirty()
|
|
448
|
+
const directory = await worktree_directory()
|
|
449
|
+
|
|
450
|
+
return { branch, is_dirty, is_held: tree_is_held(directory) }
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function describe_cut(cut: RunCut): string {
|
|
454
|
+
return `${cut.invocation} cut at ${cut.cut_at} on ${cut.branch} (${cut.phase})`
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// With no owner recorded, a `busy` can only be the exclusive create losing: another process adopted
|
|
458
|
+
// this cut first. It is the double-launch signal a resume reports rather than a live-owner refusal.
|
|
459
|
+
function busy_message(cut: RunCut): string {
|
|
460
|
+
return `Another process already resumed this cut — ${describe_cut(cut)}. Nothing was resumed here; a double launch was detected.`
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// A successor already resumed this cut, so a process that reaches `--resume` after its own hand-off is
|
|
464
|
+
// told to stop quietly rather than to investigate a tree that is not wrong (joshuafolkken/kit#1935).
|
|
465
|
+
function handed_off_message(cut: RunCut): string {
|
|
466
|
+
return `This cut was already handed off to a successor — ${describe_cut(cut)}. Nothing was resumed here; the run is being carried on by the process that adopted it, so this one has nothing to do.`
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// The record does not match the tree the fresh process is in — wrong branch, a clean tree, an expired
|
|
470
|
+
// record, no declared cut, or a tree no longer under its hold. It is a resume failure, said as such
|
|
471
|
+
// rather than reported as a success, so the run stops instead of gating the wrong tree.
|
|
472
|
+
function stale_message(cut: RunCut): string {
|
|
473
|
+
return `This cut does not match the current tree — ${describe_cut(cut)}. Resume failed; verify the branch and the uncommitted work, then clear it with \`${END_COMMAND}\` if the run is over.`
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// The record matches the tree but resumes into implementation without an instruction, so the run would
|
|
477
|
+
// be continued blind to what it was told to do — the failure mode joshuafolkken/kit#2354 exists to stop.
|
|
478
|
+
// It is reported as a failure rather than a success, so the fresh process recovers the instruction
|
|
479
|
+
// rather than restructuring a tree it does not understand.
|
|
480
|
+
function incomplete_message(cut: RunCut): string {
|
|
481
|
+
return `This cut carries no instruction to resume on — ${describe_cut(cut)}. Resume was refused rather than continuing without it; recover the run's instruction and work state before implementing, and clear the record with \`${END_COMMAND}\` if the run is over.`
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function unreadable_message(): string {
|
|
485
|
+
return `A cut record is here but could not be read; clear it with \`${END_COMMAND}\` once you know no run is using it. Read it with \`${READ_COMMAND}\`.`
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function unknown_message(): string {
|
|
489
|
+
return 'This working tree’s git directory could not be read, so no cut record was acted on.'
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const run_cut = {
|
|
493
|
+
CUT_MAX_AGE_HOURS,
|
|
494
|
+
CUT_MAX_AGE_MS,
|
|
495
|
+
END_COMMAND,
|
|
496
|
+
IMPLEMENTATION_CONTEXT_THRESHOLD,
|
|
497
|
+
IMPLEMENTATION_PHASE,
|
|
498
|
+
MAX_HANDOFF_BYTES,
|
|
499
|
+
PRE_GATE_PHASE,
|
|
500
|
+
adopt_cut,
|
|
501
|
+
begin_cut,
|
|
502
|
+
busy_message,
|
|
503
|
+
carried_cut_sync,
|
|
504
|
+
classify,
|
|
505
|
+
classify_resume,
|
|
506
|
+
current_state,
|
|
507
|
+
cut_path,
|
|
508
|
+
describe_cut,
|
|
509
|
+
end_cut,
|
|
510
|
+
fresh_cut,
|
|
511
|
+
handed_off_message,
|
|
512
|
+
has_required_handoff,
|
|
513
|
+
incomplete_message,
|
|
514
|
+
invocation_for,
|
|
515
|
+
is_expired,
|
|
516
|
+
is_relaunchable,
|
|
517
|
+
lane_cut_sync,
|
|
518
|
+
mark_merge_relaunched,
|
|
519
|
+
read_cut,
|
|
520
|
+
record_within_bound,
|
|
521
|
+
resumes_into_implementation,
|
|
522
|
+
stale_message,
|
|
523
|
+
unknown_message,
|
|
524
|
+
unreadable_message,
|
|
525
|
+
within_handoff_bound,
|
|
526
|
+
worktree_directory,
|
|
527
|
+
worktree_git_directory_sync,
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
export type { CutResumeRequest, CutState, RunCut }
|
|
531
|
+
export { run_cut }
|