@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,137 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process'
|
|
2
|
+
import { lane_child_invocation } from './lane-child-invocation'
|
|
3
|
+
|
|
4
|
+
// Ending a lane child that did not end itself (joshuafolkken/kit#2421).
|
|
5
|
+
//
|
|
6
|
+
// **A detached child is kept alive on purpose and was never ended by anything.** `detached_launch`
|
|
7
|
+
// lets a child outlive its parent's session, and every reader of it — `run:liveness`, the 30-minute
|
|
8
|
+
// silence window — only *reads* whether it stopped. So a child that merged and then hung on a wait
|
|
9
|
+
// loop of its own lived on for a day, and the documented `pgrep -laf "fullrun #<N>$"` answered
|
|
10
|
+
// `alive` for that issue number forever, which is a verification answering wrongly. The close and the
|
|
11
|
+
// park are where the run has already decided the child is finished, so the reaping lives with them.
|
|
12
|
+
//
|
|
13
|
+
// **The whole process tree goes, collected before anything is signalled.** The hang is usually in a
|
|
14
|
+
// shell the child spawned, not in the child itself, and a descendant signalled after its parent died
|
|
15
|
+
// has already been re-parented out of reach — so the tree is read first, then terminated.
|
|
16
|
+
//
|
|
17
|
+
// **The caller's own ancestry is never touched.** A `lane:close` issued from inside the lane it
|
|
18
|
+
// closes would otherwise end the very session running it, before it could report.
|
|
19
|
+
|
|
20
|
+
const PGREP_COMMAND = 'pgrep'
|
|
21
|
+
const MATCH_FULL_COMMAND_LINE = '-f'
|
|
22
|
+
const CHILDREN_OF_FLAG = '-P'
|
|
23
|
+
// The same absolute `ps` `process-identity.ts` probes with, so the lookup does not depend on `PATH`.
|
|
24
|
+
const PS_COMMAND = '/bin/ps'
|
|
25
|
+
const PARENT_FORMAT = ['-o', 'ppid=', '-p']
|
|
26
|
+
const TERMINATE_SIGNAL = 'SIGTERM'
|
|
27
|
+
// A probe that hung would hang the close it runs inside; failing answers "no process", which leaves
|
|
28
|
+
// the lane exactly as it was before this module existed.
|
|
29
|
+
const PROBE_TIMEOUT_MS = 2000
|
|
30
|
+
// `0` addresses the caller's own process group and `1` is init — neither is ever a lane child.
|
|
31
|
+
const LOWEST_CHILD_PID = 2
|
|
32
|
+
|
|
33
|
+
interface ReapProbes {
|
|
34
|
+
matching: (pattern: string) => Array<number>
|
|
35
|
+
children_of: (pid: number) => Array<number>
|
|
36
|
+
parent_of: (pid: number) => number | undefined
|
|
37
|
+
terminate: (pid: number) => boolean
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parse_pids(printed: string): Array<number> {
|
|
41
|
+
return printed
|
|
42
|
+
.split('\n')
|
|
43
|
+
.map((line) => Number(line.trim()))
|
|
44
|
+
.filter((pid) => Number.isSafeInteger(pid) && pid >= LOWEST_CHILD_PID)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// `pgrep` exits 1 when nothing matches, which `execFileSync` throws — the empty list either way.
|
|
48
|
+
function run_probe(command: string, args: ReadonlyArray<string>): string {
|
|
49
|
+
try {
|
|
50
|
+
return execFileSync(command, [...args], {
|
|
51
|
+
encoding: 'utf8',
|
|
52
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
53
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
54
|
+
})
|
|
55
|
+
} catch {
|
|
56
|
+
return ''
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function parent_of(pid: number): number | undefined {
|
|
61
|
+
return parse_pids(run_probe(PS_COMMAND, [...PARENT_FORMAT, String(pid)]))[0]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function terminate(pid: number): boolean {
|
|
65
|
+
try {
|
|
66
|
+
process.kill(pid, TERMINATE_SIGNAL)
|
|
67
|
+
|
|
68
|
+
return true
|
|
69
|
+
} catch {
|
|
70
|
+
return false
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const SYSTEM_PROBES: ReapProbes = {
|
|
75
|
+
matching: (pattern) => parse_pids(run_probe(PGREP_COMMAND, [MATCH_FULL_COMMAND_LINE, pattern])),
|
|
76
|
+
children_of: (pid) => parse_pids(run_probe(PGREP_COMMAND, [CHILDREN_OF_FLAG, String(pid)])),
|
|
77
|
+
parent_of,
|
|
78
|
+
terminate,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function ancestry_of(pid: number, probes: ReapProbes): Set<number> {
|
|
82
|
+
const ancestry = new Set<number>([pid])
|
|
83
|
+
let current = probes.parent_of(pid)
|
|
84
|
+
|
|
85
|
+
while (current !== undefined && !ancestry.has(current)) {
|
|
86
|
+
ancestry.add(current)
|
|
87
|
+
current = probes.parent_of(current)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return ancestry
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// This process and every process above it. The Stop hook reads it to tell whether the session that
|
|
94
|
+
// declared a carry record's `--owner "$PPID"` is the one it runs under (joshuafolkken/kit#2472).
|
|
95
|
+
function own_ancestry(probes: ReapProbes = SYSTEM_PROBES): Set<number> {
|
|
96
|
+
return ancestry_of(process.pid, probes)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function tree_of(roots: ReadonlyArray<number>, probes: ReapProbes): Array<number> {
|
|
100
|
+
const tree: Array<number> = []
|
|
101
|
+
const pending = [...roots]
|
|
102
|
+
let next = pending.shift()
|
|
103
|
+
|
|
104
|
+
while (next !== undefined) {
|
|
105
|
+
if (!tree.includes(next)) {
|
|
106
|
+
tree.push(next)
|
|
107
|
+
pending.push(...probes.children_of(next))
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
next = pending.shift()
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return tree
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Terminate every process of the lane child for `issue` and everything under it, sparing the caller's
|
|
118
|
+
* own ancestry. Returns the pids that were signalled — the empty list is the healthy case, a child
|
|
119
|
+
* that had already ended by itself.
|
|
120
|
+
*/
|
|
121
|
+
function reap_child(issue: string, probes: ReapProbes = SYSTEM_PROBES): Array<number> {
|
|
122
|
+
const own = own_ancestry(probes)
|
|
123
|
+
const pattern = lane_child_invocation.process_pattern(issue)
|
|
124
|
+
const roots = probes.matching(pattern).filter((pid) => !own.has(pid))
|
|
125
|
+
const doomed = tree_of(roots, probes).filter((pid) => !own.has(pid))
|
|
126
|
+
|
|
127
|
+
return doomed.filter((pid) => probes.terminate(pid))
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const lane_reap = {
|
|
131
|
+
own_ancestry,
|
|
132
|
+
parse_pids,
|
|
133
|
+
reap_child,
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export type { ReapProbes }
|
|
137
|
+
export { lane_reap }
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { ENV_FILE_NAME } from '#ports'
|
|
4
|
+
import type { AgentProfile } from '#scripts/agent/agent-role-profile'
|
|
5
|
+
import { repo_discovery } from '#scripts/discovery/repo-discovery'
|
|
6
|
+
import { git_command } from '#scripts/git/git-command'
|
|
7
|
+
import { git_worktree } from '#scripts/git/git-worktree'
|
|
8
|
+
import { lane_environment } from './lane-environment'
|
|
9
|
+
import { lane_paths } from './lane-paths'
|
|
10
|
+
|
|
11
|
+
// The open lanes, read from git and from each lane's own `.env` (joshuafolkken/kit#1490).
|
|
12
|
+
//
|
|
13
|
+
// **There is no ledger file, and that is the design rather than an omission.** A lane's seat has to
|
|
14
|
+
// live in its `.env` anyway — that file is what `josh port` and `playwright.config.ts` read inside
|
|
15
|
+
// the work tree — so keeping a second copy of it anywhere else buys nothing and can disagree with
|
|
16
|
+
// the first. Reading the seats back out of the live lanes means `git worktree remove` erases the
|
|
17
|
+
// record of a seat along with the tree that held it: there is nothing to keep in step and nothing
|
|
18
|
+
// that can go stale. A counter, or a ledger beside the trees, would let a lane that was closed and
|
|
19
|
+
// reopened take a seat a running lane is still using.
|
|
20
|
+
|
|
21
|
+
interface LaneInfo {
|
|
22
|
+
issue: string
|
|
23
|
+
branch: string
|
|
24
|
+
directory: string
|
|
25
|
+
// The lane's seat (`JOSH_LANE_SEAT`, 1..9), and the dev/preview ports it resolves to through
|
|
26
|
+
// `ports/index.js` — all `undefined` when the lane's `.env` cannot be read. The seat is what a new
|
|
27
|
+
// lane's allocation has to avoid; the ports are what the report shows (joshuafolkken/kit#1494).
|
|
28
|
+
seat: number | undefined
|
|
29
|
+
development_port: number | undefined
|
|
30
|
+
preview_port: number | undefined
|
|
31
|
+
// Where the delegated unit running this lane's child writes (joshuafolkken/kit#1713), or
|
|
32
|
+
// `undefined` where the lane records none. It is the one thing about a lane that a session which
|
|
33
|
+
// did not open it cannot derive: the harness names a unit's file after the dispatching session
|
|
34
|
+
// and the unit's own id, neither of which is written anywhere else on disk. Recorded here, a
|
|
35
|
+
// fresh session can poll a running child with `pnpm josh run:liveness <N> --output <path>`
|
|
36
|
+
// instead of waiting for the pool to drain before it can be cut.
|
|
37
|
+
output: string | undefined
|
|
38
|
+
profile?: AgentProfile | undefined
|
|
39
|
+
is_stranded: boolean
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const WORKTREE_PREFIX = 'worktree '
|
|
43
|
+
const BRANCH_PREFIX = 'branch refs/heads/'
|
|
44
|
+
const BLOCK_SEPARATOR = '\n\n'
|
|
45
|
+
// The same shape `lane:open` accepts. Nothing reserves the `-lane` suffix, so a hand-made
|
|
46
|
+
// `spike-lane` branch with a work tree would otherwise be read as a lane — and `lane:close --all`
|
|
47
|
+
// would delete its directory and its branch on an issue number that never existed.
|
|
48
|
+
const ISSUE_PATTERN = /^[1-9]\d*$/u
|
|
49
|
+
|
|
50
|
+
function line_value(lines: ReadonlyArray<string>, prefix: string): string | undefined {
|
|
51
|
+
return lines.find((line) => line.startsWith(prefix))?.slice(prefix.length)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface LaneSeat {
|
|
55
|
+
seat: number
|
|
56
|
+
development_port: number
|
|
57
|
+
preview_port: number
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The seat and ports a lane holds, or `undefined` when its `.env` records no seat.
|
|
62
|
+
*
|
|
63
|
+
* **Unreadable is reported, never treated as free.** A seat read as free is handed to the next lane
|
|
64
|
+
* while the ports it actually holds are still bound, and the collision then surfaces as an E2E
|
|
65
|
+
* failure in a different work tree — the kind of silent failure `playwright.config.ts` refuses to
|
|
66
|
+
* add by dying on a busy port instead of retrying on another.
|
|
67
|
+
*
|
|
68
|
+
* **A file with no `JOSH_LANE_SEAT` line is not seat 0.** Seat 0 is the main work tree's own, so a
|
|
69
|
+
* lane whose seat line was lost would be booked as sharing it while it in fact still runs on
|
|
70
|
+
* whatever ports it was started with, and `lane:open` would allocate straight over them.
|
|
71
|
+
*/
|
|
72
|
+
function seat_from_content(content: string): LaneSeat | undefined {
|
|
73
|
+
const seat = lane_environment.read_lane_seat(content)
|
|
74
|
+
if (seat === undefined) return undefined
|
|
75
|
+
|
|
76
|
+
const port_pair = lane_environment.read_lane_ports(content)
|
|
77
|
+
|
|
78
|
+
return { seat, development_port: port_pair.development, preview_port: port_pair.preview }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface SeatPorts {
|
|
82
|
+
seat: number | undefined
|
|
83
|
+
development_port: number | undefined
|
|
84
|
+
preview_port: number | undefined
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const EMPTY_SEAT: SeatPorts = {
|
|
88
|
+
seat: undefined,
|
|
89
|
+
development_port: undefined,
|
|
90
|
+
preview_port: undefined,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// A stranded or unreadable lane holds no seat and binds no ports, so all three fields read undefined.
|
|
94
|
+
function held_seat(content: string | undefined): SeatPorts {
|
|
95
|
+
if (content === undefined) return EMPTY_SEAT
|
|
96
|
+
|
|
97
|
+
return seat_from_content(content) ?? EMPTY_SEAT
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The lane's own `.env`, or `undefined` when it cannot be read.
|
|
102
|
+
*
|
|
103
|
+
* One read serves both the seat and the recorded output path (joshuafolkken/kit#1713). Reading the
|
|
104
|
+
* file twice would let the two disagree about whether it could be read at all, and `unreadable` is
|
|
105
|
+
* a state the report shows rather than a state anything falls back from.
|
|
106
|
+
*/
|
|
107
|
+
function read_environment(directory: string): string | undefined {
|
|
108
|
+
try {
|
|
109
|
+
return readFileSync(path.join(directory, ENV_FILE_NAME), 'utf8')
|
|
110
|
+
} catch {
|
|
111
|
+
return undefined
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// A lane is identified by its branch rather than by where it sits, so nothing here compares two
|
|
116
|
+
// spellings of one path — git prints the resolved one, and a lane root reached through a symlink
|
|
117
|
+
// would otherwise read as no lane at all.
|
|
118
|
+
function branch_issue(branch: string | undefined): string | undefined {
|
|
119
|
+
if (!branch?.endsWith(lane_paths.LANE_BRANCH_SUFFIX)) return undefined
|
|
120
|
+
|
|
121
|
+
const issue = branch.slice(0, -lane_paths.LANE_BRANCH_SUFFIX.length)
|
|
122
|
+
|
|
123
|
+
return ISSUE_PATTERN.test(issue) ? issue : undefined
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// **Stranded means the work tree is gone from disk, and nothing else.** git also marks a
|
|
127
|
+
// registration prunable when its `.git` pointer is damaged while the directory — and whatever server
|
|
128
|
+
// is running in it — is still there; read as stranded, that lane's seat would be handed to the next
|
|
129
|
+
// one while its ports are still bound.
|
|
130
|
+
function is_gone(directory: string): boolean {
|
|
131
|
+
return !existsSync(directory)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function build_lane(
|
|
135
|
+
issue: string,
|
|
136
|
+
branch: string,
|
|
137
|
+
directory: string,
|
|
138
|
+
is_stranded: boolean,
|
|
139
|
+
): LaneInfo {
|
|
140
|
+
// A stranded lane binds no ports and runs nothing, so its seat is free and there is nothing to
|
|
141
|
+
// read — its work tree is gone from disk along with the `.env` that held both records.
|
|
142
|
+
const content = is_stranded ? undefined : read_environment(directory)
|
|
143
|
+
const held = held_seat(content)
|
|
144
|
+
const output = content === undefined ? undefined : lane_environment.read_lane_output(content)
|
|
145
|
+
const profile = content === undefined ? undefined : lane_environment.read_lane_profile(content)
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
issue,
|
|
149
|
+
branch,
|
|
150
|
+
directory,
|
|
151
|
+
seat: held.seat,
|
|
152
|
+
development_port: held.development_port,
|
|
153
|
+
preview_port: held.preview_port,
|
|
154
|
+
output,
|
|
155
|
+
profile,
|
|
156
|
+
is_stranded,
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// **A lane is its branch *and* its place, and the place is what makes the identification safe**
|
|
161
|
+
// (joshuafolkken/kit#1497). The branch alone is not a namespace anyone stays out of: `pnpm josh git`
|
|
162
|
+
// builds an issue branch as `<N>-<slug of the title>`, so an issue titled "Lane" produces `<N>-lane`
|
|
163
|
+
// — byte for byte the name `lane_paths.lane_branch` builds. Read as a lane, that work tree is
|
|
164
|
+
// whichever checkout the person was working in, and `lane:close --all` would delete it, because
|
|
165
|
+
// `lane-close.ts` → `remove_directory` runs `rmSync` on whatever directory the registry reported.
|
|
166
|
+
// Requiring the directory to be exactly `<lane root>/<N>` costs a real lane nothing — `lane:open`
|
|
167
|
+
// puts it there and nowhere else — and takes the whole class of collision out. The cost is that a
|
|
168
|
+
// lane root reached through a symlink stops reading as a lane; that fails safe, where the branch
|
|
169
|
+
// check alone failed destructively.
|
|
170
|
+
function is_lane_directory(root: string, issue: string, directory: string): boolean {
|
|
171
|
+
return directory === lane_paths.lane_directory(root, issue)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function parse_block(block: string, root: string): LaneInfo | undefined {
|
|
175
|
+
const lines = block.split('\n')
|
|
176
|
+
const directory = line_value(lines, WORKTREE_PREFIX)
|
|
177
|
+
const branch = line_value(lines, BRANCH_PREFIX)
|
|
178
|
+
const issue = branch_issue(branch)
|
|
179
|
+
|
|
180
|
+
if (directory === undefined || branch === undefined || issue === undefined) return undefined
|
|
181
|
+
|
|
182
|
+
if (!is_lane_directory(root, issue, directory)) return undefined
|
|
183
|
+
|
|
184
|
+
return build_lane(issue, branch, directory, is_gone(directory))
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function is_lane(lane: LaneInfo | undefined): lane is LaneInfo {
|
|
188
|
+
return lane !== undefined
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function worktree_blocks(): Promise<Array<string>> {
|
|
192
|
+
const listing = await git_worktree.worktree_list()
|
|
193
|
+
|
|
194
|
+
return listing.split(BLOCK_SEPARATOR)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* The main work tree's root, whichever work tree this was run in.
|
|
199
|
+
*
|
|
200
|
+
* **Every lane path is derived from here, and `git rev-parse --show-toplevel` is not it**
|
|
201
|
+
* (joshuafolkken/kit#1497). That answers the *current* work tree, which inside a lane is the lane
|
|
202
|
+
* itself — so `lane:list` run there would look for lanes under `<lane>/.<lane>-lanes` and report that
|
|
203
|
+
* none are open while six are running. The step from the current work tree to the main one is exactly
|
|
204
|
+
* what `repo_discovery.main_worktree` resolves from the filesystem (joshuafolkken/kit#2233), so this
|
|
205
|
+
* is a thin async layer over it: `repository_root()` names the current work tree, and the shared
|
|
206
|
+
* resolver walks its `.git`/`commondir` up to the main checkout. Keeping that walk in one place lets
|
|
207
|
+
* the synchronous discovery callers — which cannot await this — share the same answer. For an ordinary
|
|
208
|
+
* checkout the resolver is a no-op, so `main_repository_root` is unchanged outside a lane.
|
|
209
|
+
*/
|
|
210
|
+
async function main_repository_root(): Promise<string> {
|
|
211
|
+
return repo_discovery.main_worktree(await git_command.repository_root())
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Every open lane of this repository, lowest issue number first. */
|
|
215
|
+
async function list_lanes(): Promise<Array<LaneInfo>> {
|
|
216
|
+
const root = lane_paths.lane_root(await main_repository_root())
|
|
217
|
+
const blocks = await worktree_blocks()
|
|
218
|
+
const lanes = blocks.map((block) => parse_block(block, root)).filter(is_lane)
|
|
219
|
+
|
|
220
|
+
return lanes.toSorted((left, right) => Number(left.issue) - Number(right.issue))
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** The seats live lanes hold — what a new lane's seat has to avoid. */
|
|
224
|
+
function used_seats(lanes: ReadonlyArray<LaneInfo>): Array<number> {
|
|
225
|
+
return lanes.map((lane) => lane.seat).filter((seat): seat is number => seat !== undefined)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** The live lanes whose seat could not be read, which is what stops an allocation. */
|
|
229
|
+
function unreadable_lanes(lanes: ReadonlyArray<LaneInfo>): Array<LaneInfo> {
|
|
230
|
+
return lanes.filter((lane) => !lane.is_stranded && lane.seat === undefined)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function find_lane(lanes: ReadonlyArray<LaneInfo>, issue: string): LaneInfo | undefined {
|
|
234
|
+
return lanes.find((lane) => lane.issue === issue)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* The open lane for one issue, read from the listing every other lane reading goes through.
|
|
239
|
+
*
|
|
240
|
+
* **The listing and the find are one call because every caller needs both** (joshuafolkken/kit#1749).
|
|
241
|
+
* Each one that wrote the pair itself is a place the listing could be read differently — from a cache,
|
|
242
|
+
* from a stale array — and the whole point of reading it live is that the answer is the same in every
|
|
243
|
+
* session, including one that never opened the lane.
|
|
244
|
+
*/
|
|
245
|
+
async function find_open_lane(issue: string): Promise<LaneInfo | undefined> {
|
|
246
|
+
return find_lane(await list_lanes(), issue)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const lane_registry = {
|
|
250
|
+
find_lane,
|
|
251
|
+
find_open_lane,
|
|
252
|
+
list_lanes,
|
|
253
|
+
main_repository_root,
|
|
254
|
+
parse_block,
|
|
255
|
+
read_environment,
|
|
256
|
+
unreadable_lanes,
|
|
257
|
+
used_seats,
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export type { LaneInfo }
|
|
261
|
+
export { lane_registry }
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { agent_argv } from '#scripts/agent/agent-argv'
|
|
2
|
+
import { detached_launch, type LaunchResult } from '#scripts/run/detached-launch'
|
|
3
|
+
import { run_ship_detach } from '#scripts/run/run-ship-detach'
|
|
4
|
+
import { lane_child_invocation } from './lane-child-invocation'
|
|
5
|
+
import { lane_child_marker } from './lane-child-marker'
|
|
6
|
+
import { lane_dispatch_log } from './lane-dispatch-log'
|
|
7
|
+
import type { LaneInfo } from './lane-registry'
|
|
8
|
+
|
|
9
|
+
// Relaunching a lane child session into its own lane — a fresh agent process started detached, under
|
|
10
|
+
// the lane's stored profile at the effort of the phase it resumes into, logging to the lane's dispatch
|
|
11
|
+
// log and carrying the dispatch mark afresh. **It was `run:cut`'s alone until a second caller needed it**
|
|
12
|
+
// (joshuafolkken/kit#2428): the detached `josh ship` supervisor hands a stopped stage back to an agent
|
|
13
|
+
// the same way the pre-gate cut hands the gate to one, so the launch is shared rather than copied — the
|
|
14
|
+
// copy that drifts is the one that forgets the mark and is read as a person by every guard.
|
|
15
|
+
//
|
|
16
|
+
// The prompt is the caller's: each composes it from `lane-child-invocation.ts`, and every one of them
|
|
17
|
+
// ends with the bare `fullrun #<N>` so the parent's liveness poll keeps matching the relaunched process.
|
|
18
|
+
|
|
19
|
+
const { SUPERVISED_KEY } = run_ship_detach
|
|
20
|
+
const OPENAI_PROVIDER = 'openai'
|
|
21
|
+
|
|
22
|
+
type RelaunchResult = LaunchResult | { kind: 'rejected'; note: string }
|
|
23
|
+
|
|
24
|
+
function relaunch(
|
|
25
|
+
lane: LaneInfo,
|
|
26
|
+
invocation: string,
|
|
27
|
+
phase: string,
|
|
28
|
+
on_note: (note: string) => void,
|
|
29
|
+
): RelaunchResult {
|
|
30
|
+
const built = agent_argv.resume_argv(invocation, lane.profile, phase, lane.directory)
|
|
31
|
+
|
|
32
|
+
if (built.kind === 'rejected') return built
|
|
33
|
+
|
|
34
|
+
return detached_launch.launch(
|
|
35
|
+
{
|
|
36
|
+
argv: built.argv,
|
|
37
|
+
cwd: lane.directory,
|
|
38
|
+
log_path: lane_dispatch_log.default_log_path(lane),
|
|
39
|
+
profile: built.profile,
|
|
40
|
+
// The relaunch keeps the mark, so the resumed child is still a dispatched child to every rule
|
|
41
|
+
// that reads it (joshuafolkken/kit#1904); the inherited environment cannot be relied on here,
|
|
42
|
+
// since the parent-session strip runs on the way in. **The ship supervisor's mark is dropped**
|
|
43
|
+
// (joshuafolkken/kit#2428): a detached supervisor is what relaunches after a stopped stage, and an
|
|
44
|
+
// agent that inherited its mark would read its own in-turn `josh ship` failure as a supervisor's —
|
|
45
|
+
// relaunching a second child into the lane beside itself.
|
|
46
|
+
env: { ...lane_child_marker.env_for(lane.issue), [SUPERVISED_KEY]: undefined },
|
|
47
|
+
},
|
|
48
|
+
on_note,
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// An OpenAI lane's process is started by its supervisor, never by a relaunch — both `run:cut` and the
|
|
53
|
+
// `run:merge` cut fallback ask this one predicate (joshuafolkken/kit#2484).
|
|
54
|
+
function is_openai_lane(lane: LaneInfo): boolean {
|
|
55
|
+
return lane.profile?.provider === OPENAI_PROVIDER
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The relaunch after a cut: the resume-specific prompt, not the record's bare `fullrun #<N>`
|
|
59
|
+
// (joshuafolkken/kit#2022), so the successor goes straight to `run:cut --resume` without reading the
|
|
60
|
+
// workflow-commands entry documents. Shared by `run:cut` and the `run:merge` fallback (joshuafolkken/kit#2484).
|
|
61
|
+
function resume(lane: LaneInfo, phase: string, on_note: (note: string) => void): RelaunchResult {
|
|
62
|
+
return relaunch(lane, lane_child_invocation.resume_invocation(lane.issue), phase, on_note)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const lane_relaunch = { is_openai_lane, relaunch, resume }
|
|
66
|
+
|
|
67
|
+
export type { RelaunchResult }
|
|
68
|
+
export { lane_relaunch }
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { agent_role_profile } from '#scripts/agent/agent-role-profile'
|
|
2
|
+
import { run_liveness } from '#scripts/run/run-liveness'
|
|
3
|
+
import type { LaneInfo } from './lane-registry'
|
|
4
|
+
|
|
5
|
+
// What a person reads when they ask what is open (joshuafolkken/kit#1490, joshuafolkken/kit#1494).
|
|
6
|
+
//
|
|
7
|
+
// The dev and preview ports are the ones the registry already resolved through `ports/index.js`
|
|
8
|
+
// when it read each lane's `.env`, so the numbers printed here are the same ones `josh port` and
|
|
9
|
+
// `playwright.config.ts` resolve inside the lane — nothing recomputes them, so there is no second
|
|
10
|
+
// formula for the two to disagree over.
|
|
11
|
+
|
|
12
|
+
const NO_LANES = 'No lanes are open.'
|
|
13
|
+
const OPEN_STATE = 'open'
|
|
14
|
+
// A registration whose work tree is gone: what an interruption leaves, and what `lane:prune` clears.
|
|
15
|
+
const STRANDED_STATE = 'stranded'
|
|
16
|
+
// A live lane whose `.env` cannot be read. It is shown rather than hidden, because it is what stops
|
|
17
|
+
// the next `lane:open` — a state nobody could see would look like an unexplained refusal.
|
|
18
|
+
const UNREADABLE_STATE = 'unreadable'
|
|
19
|
+
const UNKNOWN_VALUE = '-'
|
|
20
|
+
const COLUMN_SEPARATOR = ' '
|
|
21
|
+
|
|
22
|
+
function lane_state(lane: LaneInfo): string {
|
|
23
|
+
if (lane.is_stranded) return STRANDED_STATE
|
|
24
|
+
|
|
25
|
+
return lane.seat === undefined ? UNREADABLE_STATE : OPEN_STATE
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function value_or_unknown(value: number | undefined): string {
|
|
29
|
+
return value === undefined ? UNKNOWN_VALUE : String(value)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// The recorded output path goes last and is labelled, so it is told apart from the directory beside
|
|
33
|
+
// it (joshuafolkken/kit#1713). A lane that records none prints `output -` rather than nothing at
|
|
34
|
+
// all: a session that did not open the lane has to be able to see that the record is missing, not
|
|
35
|
+
// read a shorter row as one field it failed to notice.
|
|
36
|
+
function output_column(output: string | undefined): string {
|
|
37
|
+
return `output ${output ?? UNKNOWN_VALUE}`
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function profile_column(lane: LaneInfo): string {
|
|
41
|
+
return `profile ${lane.profile === undefined ? UNKNOWN_VALUE : agent_role_profile.describe(lane.profile)}`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function event_column(lane: LaneInfo): string {
|
|
45
|
+
if (lane.output === undefined) return 'agent -'
|
|
46
|
+
const state = run_liveness.describe_agent_state(lane.output)
|
|
47
|
+
|
|
48
|
+
return state ?? 'agent -'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function describe_lane(lane: LaneInfo): string {
|
|
52
|
+
return [
|
|
53
|
+
`#${lane.issue}`,
|
|
54
|
+
`seat ${value_or_unknown(lane.seat)}`,
|
|
55
|
+
`dev ${value_or_unknown(lane.development_port)}`,
|
|
56
|
+
`preview ${value_or_unknown(lane.preview_port)}`,
|
|
57
|
+
lane.branch,
|
|
58
|
+
lane_state(lane),
|
|
59
|
+
lane.directory,
|
|
60
|
+
output_column(lane.output),
|
|
61
|
+
profile_column(lane),
|
|
62
|
+
event_column(lane),
|
|
63
|
+
].join(COLUMN_SEPARATOR)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function describe_lanes(lanes: ReadonlyArray<LaneInfo>): string {
|
|
67
|
+
if (lanes.length === 0) return NO_LANES
|
|
68
|
+
|
|
69
|
+
return lanes.map((lane) => describe_lane(lane)).join('\n')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function describe_ports(lane: LaneInfo): string {
|
|
73
|
+
if (lane.seat === undefined) return 'no lane seat could be read'
|
|
74
|
+
|
|
75
|
+
return `seat ${String(lane.seat)}, dev ${value_or_unknown(lane.development_port)}, preview ${value_or_unknown(lane.preview_port)}`
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// The one-line confirmation a person reads on standard error while standard output carries the
|
|
79
|
+
// directory alone, so `dir=$(pnpm josh lane:open 1490)` stays usable.
|
|
80
|
+
function describe_opened(lane: LaneInfo): string {
|
|
81
|
+
return `Opened a lane for #${lane.issue} on ${lane.branch}: ${describe_ports(lane)}.`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const lane_report = {
|
|
85
|
+
NO_LANES,
|
|
86
|
+
OPEN_STATE,
|
|
87
|
+
STRANDED_STATE,
|
|
88
|
+
UNREADABLE_STATE,
|
|
89
|
+
describe_lane,
|
|
90
|
+
describe_lanes,
|
|
91
|
+
describe_opened,
|
|
92
|
+
lane_state,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { lane_report }
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { AgentProvider } from '#scripts/agent/agent-role-profile'
|
|
2
|
+
import { api_outage } from '#scripts/agent/api-outage'
|
|
3
|
+
import type { ClaudeResultEvent } from '#scripts/agent/claude-result-event'
|
|
4
|
+
import { lane_child_invocation } from './lane-child-invocation'
|
|
5
|
+
|
|
6
|
+
// How a lane re-dispatch chooses between resuming the disconnected child's session and starting fresh
|
|
7
|
+
// (joshuafolkken/kit#2317). The premise the whole issue rests on: a child that could not reach the API
|
|
8
|
+
// left a `session_id` in its exit record, and re-dispatching it as a bare `fullrun #<N>` threw that
|
|
9
|
+
// context away — a resumed child keeps it and loses only the last round-trip.
|
|
10
|
+
//
|
|
11
|
+
// **The decision is pure and reads three inputs**: the child's exit record, and the provider the lane
|
|
12
|
+
// runs under. It resumes only when all three hold — the record is an API outage (a child that stalled
|
|
13
|
+
// on its own has nothing to recover), it carries a `session_id`, and the provider is Anthropic (the
|
|
14
|
+
// `--resume` mechanism is Claude Code's; an OpenAI lane has no session id here and falls back to fresh).
|
|
15
|
+
// Every other case is `fresh`, which is the exact behavior a first dispatch and a non-outage ending had
|
|
16
|
+
// before this existed, so the fallback is never a regression.
|
|
17
|
+
|
|
18
|
+
const ANTHROPIC: AgentProvider = 'anthropic'
|
|
19
|
+
|
|
20
|
+
// A resume carries the stored session and the resume-specific prompt; a fresh start carries the
|
|
21
|
+
// ordinary `fullrun #<N>`. The caller reads `kind` to report which path it took and to pick the argv
|
|
22
|
+
// builder — the resume builder needs the `session_id` the fresh one does not.
|
|
23
|
+
type ResumePlan =
|
|
24
|
+
{ kind: 'resume'; session_id: string; invocation: string } | { kind: 'fresh'; invocation: string }
|
|
25
|
+
|
|
26
|
+
function fresh_plan(issue: string): ResumePlan {
|
|
27
|
+
return { kind: 'fresh', invocation: lane_child_invocation.child_invocation(issue) }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// The session id to resume from, or `undefined` when this ending is not resumable — the three
|
|
31
|
+
// conditions named in the header, read in one place so the caller's fallback is a single branch. An
|
|
32
|
+
// Anthropic outage child that left a session id is the only case that yields one.
|
|
33
|
+
function resumable_session(
|
|
34
|
+
record: ClaudeResultEvent | undefined,
|
|
35
|
+
provider: AgentProvider,
|
|
36
|
+
): string | undefined {
|
|
37
|
+
if (provider !== ANTHROPIC || record === undefined) return undefined
|
|
38
|
+
|
|
39
|
+
return api_outage.is_outage(record) ? record.session_id : undefined
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function plan(
|
|
43
|
+
issue: string,
|
|
44
|
+
record: ClaudeResultEvent | undefined,
|
|
45
|
+
provider: AgentProvider,
|
|
46
|
+
): ResumePlan {
|
|
47
|
+
const session_id = resumable_session(record, provider)
|
|
48
|
+
|
|
49
|
+
if (session_id === undefined) return fresh_plan(issue)
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
kind: 'resume',
|
|
53
|
+
session_id,
|
|
54
|
+
invocation: lane_child_invocation.outage_resume_invocation(issue),
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const lane_resume = { plan }
|
|
59
|
+
|
|
60
|
+
export type { ResumePlan }
|
|
61
|
+
export { lane_resume }
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Which seat a lane gets (joshuafolkken/kit#1490, joshuafolkken/kit#1494).
|
|
2
|
+
|
|
3
|
+
// **The main work tree is seat 0, and nothing here can move it.** Lanes take seats 1..9, so a
|
|
4
|
+
// project that has never opened one stays on exactly the ports `ports/index.js` already gives it —
|
|
5
|
+
// `seed × 10` for its seed, the bases themselves for an unset seed, which is what CI runs on.
|
|
6
|
+
const FIRST_LANE_SEAT = 1
|
|
7
|
+
// **Nine seats, because the seat is the units digit of the offset `seed × 10 + lane`.** The seat no
|
|
8
|
+
// longer carries the whole port band — the seed does, multiplied by ten — so a lane holds a single
|
|
9
|
+
// seat number rather than an absolute seed, and there is no ceiling to check and no "multiple of
|
|
10
|
+
// ten" convention for anyone to break (joshuafolkken/kit#1494 removed the band mechanism).
|
|
11
|
+
const LAST_LANE_SEAT = 9
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The free seats, lowest first — the ones no live lane holds.
|
|
15
|
+
*
|
|
16
|
+
* **Read from the lanes themselves — never from a counter.** A number derived from how many lanes
|
|
17
|
+
* have ever been opened hands a closed-and-reopened lane the seat a running lane is still using; the
|
|
18
|
+
* seats here come from the `JOSH_LANE_SEAT` of each open work tree, so closing one frees its seat and
|
|
19
|
+
* nothing else has to be told. **An empty result means the caller fails** — the range is never
|
|
20
|
+
* wrapped, because wrapping is that same collision under a friendlier name.
|
|
21
|
+
*
|
|
22
|
+
* The whole ascending list is returned rather than only the lowest, because the caller claims each
|
|
23
|
+
* seat atomically and steps to the next when a concurrent `lane:open` claimed it first
|
|
24
|
+
* (joshuafolkken/kit#1494): reading a free set and picking from it are two moments, and the gap
|
|
25
|
+
* between them is where two opens once chose the same seat.
|
|
26
|
+
*/
|
|
27
|
+
function free_seats(used: ReadonlyArray<number>): Array<number> {
|
|
28
|
+
const taken = new Set(used)
|
|
29
|
+
const free: Array<number> = []
|
|
30
|
+
|
|
31
|
+
for (let seat = FIRST_LANE_SEAT; seat <= LAST_LANE_SEAT; seat += 1) {
|
|
32
|
+
if (!taken.has(seat)) free.push(seat)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return free
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const lane_seed_policy = {
|
|
39
|
+
FIRST_LANE_SEAT,
|
|
40
|
+
LAST_LANE_SEAT,
|
|
41
|
+
free_seats,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { lane_seed_policy }
|