@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,253 @@
|
|
|
1
|
+
import { LANE_SEAT_KEY, PORT_SEED_KEY, ports } from '#ports'
|
|
2
|
+
import { agent_role_profile, type AgentProfile } from '#scripts/agent/agent-role-profile'
|
|
3
|
+
|
|
4
|
+
// The lane's `.env`, built from the root's (joshuafolkken/kit#1490, joshuafolkken/kit#1494).
|
|
5
|
+
//
|
|
6
|
+
// **Port separation is required here, not optional.** `ports/index.js` resolves the project root as
|
|
7
|
+
// the nearest ancestor holding a `package.json` — which, inside a linked work tree, is the lane's
|
|
8
|
+
// own directory — so a lane with no `.env` runs on seed 0 and a lane handed a verbatim copy of the
|
|
9
|
+
// root's runs on the root's exact offset; either way every lane lands on one pair of ports, and a
|
|
10
|
+
// busy port fails without retrying on another. At the default six lanes that turns E2E from "fails
|
|
11
|
+
// sometimes" into "fails nearly always". So the lane's `.env` keeps the project's `PORT_SEED`
|
|
12
|
+
// unchanged and adds `JOSH_LANE_SEAT`, and `ports/index.js` combines them as `seed × 10 + seat`
|
|
13
|
+
// (joshuafolkken/kit#1494): the file plainly shows which number is the project's and which is the
|
|
14
|
+
// seat, and the multiplication that separates the bands lives in one place rather than here.
|
|
15
|
+
//
|
|
16
|
+
// **Everything else in the file is carried across verbatim**, comments and blank lines included:
|
|
17
|
+
// `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`, `JOSH_SESSION_LANG` and whatever else the person has set
|
|
18
|
+
// are as necessary inside a lane as outside one, and a lane that had to have them re-entered would
|
|
19
|
+
// not be a place a run could start unattended.
|
|
20
|
+
|
|
21
|
+
// Where the delegated unit running this lane's child writes (joshuafolkken/kit#1713). It goes in the
|
|
22
|
+
// lane's own `.env` — the store `lane-registry.ts` already reads — rather than in a ledger beside the
|
|
23
|
+
// trees, so `git worktree remove` erases the record along with the lane it described and there is
|
|
24
|
+
// nothing left to go stale. `.env` is gitignored in kit and in every consumer `josh sync` reaches,
|
|
25
|
+
// which is the objection that sent the run hold's stamp to the temp directory instead.
|
|
26
|
+
const LANE_OUTPUT_KEY = 'JOSH_LANE_OUTPUT'
|
|
27
|
+
const LANE_PROVIDER_KEY = 'JOSH_LANE_AGENT_PROVIDER'
|
|
28
|
+
const LANE_ROLE_KEY = 'JOSH_LANE_AGENT_ROLE'
|
|
29
|
+
const LANE_MODEL_KEY = 'JOSH_LANE_AGENT_MODEL'
|
|
30
|
+
const LANE_EFFORT_KEY = 'JOSH_LANE_AGENT_EFFORT'
|
|
31
|
+
const ASSIGNMENT_SEPARATOR = '='
|
|
32
|
+
// `export PORT_SEED=3` is a form dotenv readers accept, so an assignment written that way has to be
|
|
33
|
+
// read as the seed line rather than copied through beside the one appended below.
|
|
34
|
+
const EXPORT_PREFIX = 'export '
|
|
35
|
+
// `PORT_SEED="3"` and `PORT_SEED='3'` are both accepted by `process.loadEnvFile`, and the quotes are
|
|
36
|
+
// not part of the value — passing them to the seed validator would fail a file that works.
|
|
37
|
+
const QUOTE_CHARACTERS = new Set(['"', "'"])
|
|
38
|
+
const MIN_QUOTED_LENGTH = 2
|
|
39
|
+
const FIRST_CHARACTER_END = 1
|
|
40
|
+
const LAST_CHARACTER_START = -1
|
|
41
|
+
|
|
42
|
+
// Read character by character rather than by regular expression: the pattern this replaced —
|
|
43
|
+
// optional leading blanks, an optional `export`, more blanks — backtracks super-linearly on a long
|
|
44
|
+
// line of spaces, which `.env` files pick up from careless editors.
|
|
45
|
+
function strip_export(line: string): string {
|
|
46
|
+
const trimmed = line.trimStart()
|
|
47
|
+
|
|
48
|
+
return trimmed.startsWith(EXPORT_PREFIX)
|
|
49
|
+
? trimmed.slice(EXPORT_PREFIX.length).trimStart()
|
|
50
|
+
: trimmed
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function is_key_line(line: string, key: string): boolean {
|
|
54
|
+
const body = strip_export(line)
|
|
55
|
+
|
|
56
|
+
if (!body.startsWith(key)) return false
|
|
57
|
+
|
|
58
|
+
return body.slice(key.length).trimStart().startsWith(ASSIGNMENT_SEPARATOR)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function is_seed_line(line: string): boolean {
|
|
62
|
+
return is_key_line(line, PORT_SEED_KEY)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function is_seat_line(line: string): boolean {
|
|
66
|
+
return is_key_line(line, LANE_SEAT_KEY)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function is_output_line(line: string): boolean {
|
|
70
|
+
return is_key_line(line, LANE_OUTPUT_KEY)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// `trimEnd` rather than a trailing-newline pattern: the file is rejoined with one newline at the end
|
|
74
|
+
// whatever it arrived with, so what is dropped here is only ever whitespace nothing reads.
|
|
75
|
+
function split_lines(content: string): Array<string> {
|
|
76
|
+
const trimmed = content.trimEnd()
|
|
77
|
+
|
|
78
|
+
return trimmed.length === 0 ? [] : trimmed.split('\n')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function is_quoted(raw: string): boolean {
|
|
82
|
+
const first = raw.slice(0, FIRST_CHARACTER_END)
|
|
83
|
+
|
|
84
|
+
if (!QUOTE_CHARACTERS.has(first)) return false
|
|
85
|
+
|
|
86
|
+
return raw.length >= MIN_QUOTED_LENGTH && raw.endsWith(first)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function unquote(raw: string): string {
|
|
90
|
+
return is_quoted(raw) ? raw.slice(FIRST_CHARACTER_END, LAST_CHARACTER_START) : raw
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function assignment_value(line: string): string {
|
|
94
|
+
return unquote(line.slice(line.indexOf(ASSIGNMENT_SEPARATOR) + FIRST_CHARACTER_END).trim())
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The last value assigned to `key` in the file, or `undefined` when it is never assigned.
|
|
99
|
+
*
|
|
100
|
+
* **The last assignment wins, which is what `.env` itself means.** A file that kept the blank
|
|
101
|
+
* `PORT_SEED=` from `.env.example` and appended a real one later would otherwise read as unset here
|
|
102
|
+
* while reading as the real seed everywhere else.
|
|
103
|
+
*/
|
|
104
|
+
function read_assignment(content: string, key: string): string | undefined {
|
|
105
|
+
const line = split_lines(content).findLast((entry) => is_key_line(entry, key))
|
|
106
|
+
|
|
107
|
+
return line === undefined ? undefined : assignment_value(line)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The project's port seed a `.env` sets, validated by `ports.resolve_seed`.
|
|
112
|
+
*
|
|
113
|
+
* A missing or blank seed is 0, the documented default; a malformed one throws for the same reason
|
|
114
|
+
* and with the same message it does everywhere else. `josh doctor` reads it to report each
|
|
115
|
+
* repository's seed, and it is the base every lane's seat sits on top of.
|
|
116
|
+
*/
|
|
117
|
+
function read_root_seed(content: string): number {
|
|
118
|
+
return ports.resolve_seed({ [PORT_SEED_KEY]: read_assignment(content, PORT_SEED_KEY) })
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* The lane's seat, or `undefined` when the file assigns none.
|
|
123
|
+
*
|
|
124
|
+
* The validation is `ports.resolve_lane`'s rather than a second copy of it, so a malformed
|
|
125
|
+
* `JOSH_LANE_SEAT` fails when a lane is read for the same reason and with the same message it fails
|
|
126
|
+
* when `ports/index.js` reads it. A file that assigns no seat is `undefined` — a lane must carry one
|
|
127
|
+
* to be readable, and `undefined` is not seat 0, which is the main work tree's own.
|
|
128
|
+
*/
|
|
129
|
+
function read_lane_seat(content: string): number | undefined {
|
|
130
|
+
const raw = read_assignment(content, LANE_SEAT_KEY)
|
|
131
|
+
|
|
132
|
+
return raw === undefined ? undefined : ports.resolve_lane({ [LANE_SEAT_KEY]: raw })
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The dev and preview ports a lane's `.env` resolves to, through the one formula in `ports`.
|
|
137
|
+
*
|
|
138
|
+
* The seed and the seat are read straight out of the file and handed to `ports`, so the
|
|
139
|
+
* `seed × 10 + seat` multiplication stays in `ports/index.js` and is never re-implemented here.
|
|
140
|
+
*/
|
|
141
|
+
function read_lane_ports(content: string): { development: number; preview: number } {
|
|
142
|
+
const environment = {
|
|
143
|
+
[PORT_SEED_KEY]: read_assignment(content, PORT_SEED_KEY),
|
|
144
|
+
[LANE_SEAT_KEY]: read_assignment(content, LANE_SEAT_KEY),
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
development: ports.resolve_development_port(environment),
|
|
149
|
+
preview: ports.resolve_preview_port(environment),
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The output path a lane's `.env` records, or `undefined` where it records none.
|
|
155
|
+
*
|
|
156
|
+
* **A blank assignment is `undefined` rather than an empty path** (joshuafolkken/kit#1713). A lane
|
|
157
|
+
* whose record was cleared has nothing to poll, and an empty string handed to
|
|
158
|
+
* `pnpm josh run:liveness --output` is a relative path — refused by its own root check, so the
|
|
159
|
+
* child would come back `undetermined` for ever rather than saying the record is missing.
|
|
160
|
+
*/
|
|
161
|
+
function read_lane_output(content: string): string | undefined {
|
|
162
|
+
const line = split_lines(content).findLast((entry) => is_output_line(entry))
|
|
163
|
+
const raw = line === undefined ? undefined : assignment_value(line)
|
|
164
|
+
|
|
165
|
+
return raw === undefined || raw.length === 0 ? undefined : raw
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function read_lane_profile(content: string): AgentProfile | undefined {
|
|
169
|
+
return agent_role_profile.parse({
|
|
170
|
+
provider: read_assignment(content, LANE_PROVIDER_KEY),
|
|
171
|
+
role: read_assignment(content, LANE_ROLE_KEY),
|
|
172
|
+
model: read_assignment(content, LANE_MODEL_KEY),
|
|
173
|
+
effort: read_assignment(content, LANE_EFFORT_KEY),
|
|
174
|
+
})
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* The root file with its seed replaced, or with one appended where it had none.
|
|
179
|
+
*
|
|
180
|
+
* Replacing in place rather than appending is what keeps the file honest for a person reading it:
|
|
181
|
+
* two `PORT_SEED` lines would work — the last wins — and would say two different things.
|
|
182
|
+
*/
|
|
183
|
+
// Every other line for the same key is dropped rather than rewritten alongside: a file carrying two
|
|
184
|
+
// of them works — the last wins — and says two different things to the person reading it.
|
|
185
|
+
function replace_assignment(
|
|
186
|
+
lines: ReadonlyArray<string>,
|
|
187
|
+
keep: number,
|
|
188
|
+
assignment: string,
|
|
189
|
+
key: string,
|
|
190
|
+
): Array<string> {
|
|
191
|
+
return lines.flatMap((entry, index) => {
|
|
192
|
+
if (index === keep) return [assignment]
|
|
193
|
+
|
|
194
|
+
return is_key_line(entry, key) ? [] : [entry]
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function upsert_assignment(content: string, key: string, value: string): string {
|
|
199
|
+
const assignment = `${key}${ASSIGNMENT_SEPARATOR}${value}`
|
|
200
|
+
const lines = split_lines(content)
|
|
201
|
+
const last = lines.findLastIndex((entry) => is_key_line(entry, key))
|
|
202
|
+
const body =
|
|
203
|
+
last === -1 ? [...lines, assignment] : replace_assignment(lines, last, assignment, key)
|
|
204
|
+
|
|
205
|
+
return `${body.join('\n')}\n`
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The root file with the lane's seat added, its `PORT_SEED` left exactly as it was.
|
|
210
|
+
*
|
|
211
|
+
* The project's seed is the lane's too — only the seat distinguishes them — so it is carried across
|
|
212
|
+
* verbatim and a `JOSH_LANE_SEAT` line is set beside it. `ports/index.js` then reads both and
|
|
213
|
+
* offsets the ports by `seed × 10 + seat`.
|
|
214
|
+
*/
|
|
215
|
+
function lane_file_content(root_content: string, seat: number): string {
|
|
216
|
+
return upsert_assignment(root_content, LANE_SEAT_KEY, String(seat))
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* The lane's `.env` with its recorded output path replaced, or with one appended where it had none.
|
|
221
|
+
*
|
|
222
|
+
* **The value is quoted, and the seed's is not.** A seed is digits; a path can hold a space or a
|
|
223
|
+
* `#`, and dotenv readers cut a value at an unquoted ` #` — so an unquoted record would come back
|
|
224
|
+
* truncated to something that still looks like a path. `read_lane_output` unquotes symmetrically.
|
|
225
|
+
*/
|
|
226
|
+
function with_lane_output(content: string, output: string, profile?: AgentProfile): string {
|
|
227
|
+
const recorded = upsert_assignment(content, LANE_OUTPUT_KEY, `"${output}"`)
|
|
228
|
+
if (profile === undefined) return recorded
|
|
229
|
+
|
|
230
|
+
const with_provider = upsert_assignment(recorded, LANE_PROVIDER_KEY, profile.provider)
|
|
231
|
+
const with_role = upsert_assignment(with_provider, LANE_ROLE_KEY, profile.role)
|
|
232
|
+
const with_model = upsert_assignment(with_role, LANE_MODEL_KEY, profile.model)
|
|
233
|
+
|
|
234
|
+
return upsert_assignment(with_model, LANE_EFFORT_KEY, profile.effort)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const lane_environment = {
|
|
238
|
+
LANE_OUTPUT_KEY,
|
|
239
|
+
LANE_PROVIDER_KEY,
|
|
240
|
+
LANE_ROLE_KEY,
|
|
241
|
+
is_output_line,
|
|
242
|
+
is_seat_line,
|
|
243
|
+
is_seed_line,
|
|
244
|
+
lane_file_content,
|
|
245
|
+
read_lane_output,
|
|
246
|
+
read_lane_profile,
|
|
247
|
+
read_lane_ports,
|
|
248
|
+
read_lane_seat,
|
|
249
|
+
read_root_seed,
|
|
250
|
+
with_lane_output,
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export { lane_environment }
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { lane_child_marker, type MarkerSource } from './lane-child-marker'
|
|
2
|
+
|
|
3
|
+
// How each `PreToolUse` guard behaves in a dispatched lane child, as an enumeration rather than a
|
|
4
|
+
// judgement (joshuafolkken/kit#2138, joshuafolkken/kit#2164).
|
|
5
|
+
//
|
|
6
|
+
// **The three guards were built for the interactive main line, where a refusal is guidance.** A denial
|
|
7
|
+
// rewrites the next move of a person's session. A dispatched lane child is a headless `claude -p`
|
|
8
|
+
// process, so a *denial* ends the conversation with nothing committed — joshuafolkken/kit#2138 measured
|
|
9
|
+
// a child killed before its commit by two investigation refusals and one batching refusal, every one of
|
|
10
|
+
// them a read of a file the child was about to edit. So a guard whose correction is a denial cannot fire
|
|
11
|
+
// as one in a child.
|
|
12
|
+
//
|
|
13
|
+
// **But a denial is not the only way a guard can speak, and that is what kit#2164 tried.** A guard can
|
|
14
|
+
// also raise a *notice* — a non-blocking `additionalContext` that carries the same guidance without a
|
|
15
|
+
// `permissionDecision`, so the turn is never ended. kit#2164 downgraded the batching guard to a notice
|
|
16
|
+
// in the child for exactly that reason. So the choice is three-valued, not two:
|
|
17
|
+
//
|
|
18
|
+
// - `refuse` — deny the call (the main-line default; the child keeps this for the safety rules).
|
|
19
|
+
// - `notice` — let the call through but attach the guidance, so a headless child is nudged, not killed.
|
|
20
|
+
// - `off` — say nothing at all, for a guard whose remedy the child cannot carry out.
|
|
21
|
+
//
|
|
22
|
+
// **The notice did not move the number, kit#2178 took it off, and kit#2276 restores it changed.** The
|
|
23
|
+
// lane child that ran right after kit#2164 merged came in at 1.00 calls per turn on both sides of the
|
|
24
|
+
// first notice (transcript `f39efeb5`), so kit#2178 turned the batching notice `off` in the child rather
|
|
25
|
+
// than pay the per-turn context cost of guidance measured not to work. But with it off, the notice fired
|
|
26
|
+
// **zero** times across the 2026-09-21 backlogrun the density was next measured on, so the 1.147 read
|
|
27
|
+
// there is the rate with no guidance at all — not a second measurement of the notice failing. kit#2276
|
|
28
|
+
// therefore restores it as `notice`, with the two things #2164's lacked: it names the concrete recent
|
|
29
|
+
// calls the run issued one-per-turn, and it recurs every single-call turn rather than every three. The
|
|
30
|
+
// mode stays a genuine experiment — the density is re-measured on the next backlogrun, and a notice that
|
|
31
|
+
// still does not move it is redesigned rather than kept.
|
|
32
|
+
//
|
|
33
|
+
// **It is an enumeration and not a judgement, for the reason `delegation-policy.ts` is one.** "This
|
|
34
|
+
// guard's mode in a child" is a call made under the same pressure that produced the misfire. The list is
|
|
35
|
+
// the whole of it, and a guard nobody classified refuses — the safe direction, since a wrongly-silenced
|
|
36
|
+
// rule ships unnoticed while a wrongly-kept one costs at most the one round trip the child already
|
|
37
|
+
// survived once. `lane-guard-policy.test.ts` pins that the enumeration and the guards' live behavior
|
|
38
|
+
// cannot disagree.
|
|
39
|
+
|
|
40
|
+
// The three ways a guard may behave in a lane child (joshuafolkken/kit#2164). Outside a lane child every
|
|
41
|
+
// guard is `refuse`, which is why that is also the fail-safe default below.
|
|
42
|
+
type LaneGuardMode = 'refuse' | 'notice' | 'off'
|
|
43
|
+
type LaneGuardId = 'investigation' | 'batching' | 'rule' | 'duplicate-read'
|
|
44
|
+
|
|
45
|
+
// The mode outside a lane child, and the fail-safe for a guard nobody enumerated: a denial, the same
|
|
46
|
+
// direction `delegation-policy.ts` takes, because a silenced rule is the one mistake that ships unseen.
|
|
47
|
+
const DEFAULT_MODE: LaneGuardMode = 'refuse'
|
|
48
|
+
const OFF_MODE: LaneGuardMode = 'off'
|
|
49
|
+
|
|
50
|
+
interface LaneGuardEntry {
|
|
51
|
+
id: LaneGuardId
|
|
52
|
+
// How this guard behaves when the session is a dispatched lane child.
|
|
53
|
+
mode_in_lane_child: LaneGuardMode
|
|
54
|
+
// Why. A mode with no reason is a choice nobody can check; the reason names what the child still needs
|
|
55
|
+
// the guard for, or why the guard cannot fire as a refusal there.
|
|
56
|
+
because: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const LANE_GUARD_POLICY: ReadonlyArray<LaneGuardEntry> = [
|
|
60
|
+
{
|
|
61
|
+
id: 'investigation',
|
|
62
|
+
mode_in_lane_child: 'notice',
|
|
63
|
+
because:
|
|
64
|
+
'a refusal ends a child turn so it cannot fire as one (kit#2138), which is why it was `off` from #2138 to #2382. The exemption reason — "the child is itself the delegated unit, so it cannot dispatch a sub-unit to read its own edit targets" — did not hold in measurement: kit#2382 re-measured the six lane children after #2347 (#2366 #2370 #2371 #2372 #2374 #2375) and every one dispatched sub-agents (10 launches, 2 of them investigation fan-outs) and read 4–17 files it never edited, all six over the threshold of 3. So the reading the guard exists to send out was there to send. It takes `notice`, not `off`: the child is nudged to delegate rather than killed, on the `additionalContext` path batching and duplicate-read already use, and the notice names the concrete unedited files this run read (the #2276 precedent) rather than the generic "delegate" #2164 → #2178 measured not to move the number. The density is a genuine experiment — re-measured on the next backlogrun, and a notice that still does not move it is redesigned rather than kept',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'batching',
|
|
68
|
+
mode_in_lane_child: 'off',
|
|
69
|
+
because:
|
|
70
|
+
'a refusal ends a child turn so it cannot fire as one (kit#2138); kit#2164 replaced it with a notice, kit#2178 took that notice off after it did not move the density, and kit#2276 restored it — naming the concrete recent calls and recurring every single-call turn — as a genuine experiment to be redesigned rather than kept if the next backlogrun still missed 1.40. kit#2405 is that re-measurement, and it cuts the notice off (`off`). `josh time:density` read 1.13 calls per round trip over the ten most recent lanes (1.04 in the Issue’s per-message frame), short of the 1.40 target as every advisory attempt before it was (kit#1304/#1329/#1337/#1390/#2164/#2276). The cause is structural rather than wording: a `PreToolUse` hook cannot see the turn it is in — a turn’s later `tool_use` lines arrive 1.4–15s after its first — so it judges only closed turns, and a notice at turn close still asks for the parallel `tool_use` blocks the model resists. The one lever measured to move the density is a composite command the model emits in a single call (`read:files`/`edit:files`, kit#2202/#2311), which needs no notice. So per the issue’s instruction to discontinue advisory means when the target is missed, the notice is cut off rather than rewritten a seventh time; the density stays readable through `josh time:density`',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'duplicate-read',
|
|
74
|
+
mode_in_lane_child: 'notice',
|
|
75
|
+
because:
|
|
76
|
+
'a refusal ends a child turn so it cannot fire as one (kit#2138), and the unchanged re-reads the guard catches are measured in lane children above all (kit#2298 baseline: 8.0 per lane run) — so silencing it there (`off`) would neuter it exactly where the count lives. It takes `notice` instead: the child is nudged to scroll up to the earlier read rather than killed. The mode is a genuine experiment, as the batching notice is — a notice that does not reduce the duplicate reads on the next backlogrun is redesigned rather than kept',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: 'rule',
|
|
80
|
+
mode_in_lane_child: 'refuse',
|
|
81
|
+
because:
|
|
82
|
+
"it carries the lane-only rules a child depends on (`pre-gate-cut`, `implementation-cut`, `lane-park`) and the safety rules a child must still obey (`shell-body`, `piped-verification`); a blanket suppression would disarm exactly the guards written for the child. `implementation-cut` (joshuafolkken/kit#2310) needs `refuse` for the same reason the pre-gate cut does — kit#1864 and kit#2310 both measured a cut carried as prose firing 0 times, so a notice, being prose in front of the run, would drop enforcement without a procedural replacement. The pre-gate-cut refusal does collateral a sibling call batched in the same turn — a `PreToolUse` deny cancels the turn's other parallel calls, which is the harness behavior kit#2177 measured on #2160 (gate refused, its batched `review:brief` cancelled) — and that collateral is not avoidable at the guard level. `notice` was considered for the pre-gate-cut point and rejected: kit#1864 measured the cut taken 0 times while it was carried as prose, and a notice is prose in front of the run (kit#2178 measured a lane-child notice not moving the number), so a notice would drop enforcement without a procedural replacement. kit#2177 supplies that replacement in the procedure instead — the chain orders the cut before the gate, so the cut is issued on its own (its `cut` verdict ends the turn, batching with nothing) and the gate runs in the fresh process where the carried cut keeps this guard silent; the refusal therefore stays `refuse` as insurance and the collateral is gone from the default path rather than from the guard",
|
|
83
|
+
},
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
const KNOWN_GUARD_IDS: ReadonlyArray<LaneGuardId> = LANE_GUARD_POLICY.map((entry) => entry.id)
|
|
87
|
+
|
|
88
|
+
function entry_for(id: string): LaneGuardEntry | undefined {
|
|
89
|
+
return LANE_GUARD_POLICY.find((entry) => entry.id === id.trim())
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// **An unenumerated guard refuses**, the same fail-safe direction `delegation-policy.ts` takes: a guard
|
|
93
|
+
// nobody listed keeps the main-line default rather than being silently downgraded, because a downgrade
|
|
94
|
+
// is what ships a missed rule.
|
|
95
|
+
function mode_in_lane_child(id: string): LaneGuardMode {
|
|
96
|
+
return entry_for(id)?.mode_in_lane_child ?? DEFAULT_MODE
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// The mode that applies to this guard right now. Outside a lane child every guard is `refuse`; inside
|
|
100
|
+
// one it is the enumerated mode. A guard whose lane-child mode is already `refuse` reads the same either
|
|
101
|
+
// way, so the marker — the dispatch mark against this checkout's own issue — is consulted only for a
|
|
102
|
+
// guard the enumeration would actually change, never on every call.
|
|
103
|
+
function mode_here(
|
|
104
|
+
id: string,
|
|
105
|
+
directory: string = process.cwd(),
|
|
106
|
+
source: MarkerSource = process.env,
|
|
107
|
+
): LaneGuardMode {
|
|
108
|
+
const lane_mode = mode_in_lane_child(id)
|
|
109
|
+
|
|
110
|
+
if (lane_mode === DEFAULT_MODE) return DEFAULT_MODE
|
|
111
|
+
|
|
112
|
+
return lane_child_marker.is_child_of(directory, source) ? lane_mode : DEFAULT_MODE
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// True when this guard must say nothing at all because the session is a dispatched lane child — the
|
|
116
|
+
// `off` mode alone. A `notice`-mode guard is not suppressed: it still speaks, just without a
|
|
117
|
+
// `permissionDecision`, so this must not answer `true` for it.
|
|
118
|
+
function is_suppressed_here(
|
|
119
|
+
id: string,
|
|
120
|
+
directory: string = process.cwd(),
|
|
121
|
+
source: MarkerSource = process.env,
|
|
122
|
+
): boolean {
|
|
123
|
+
return mode_here(id, directory, source) === OFF_MODE
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const lane_guard_policy = {
|
|
127
|
+
LANE_GUARD_POLICY,
|
|
128
|
+
KNOWN_GUARD_IDS,
|
|
129
|
+
entry_for,
|
|
130
|
+
mode_in_lane_child,
|
|
131
|
+
mode_here,
|
|
132
|
+
is_suppressed_here,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export type { LaneGuardMode }
|
|
136
|
+
export { lane_guard_policy }
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { buffered_process } from '#scripts/lib/buffered-process'
|
|
4
|
+
|
|
5
|
+
// Filling the lane, which is the other half of opening one (joshuafolkken/kit#1554).
|
|
6
|
+
//
|
|
7
|
+
// **A work tree with no `node_modules` is not a lane yet.** A linked work tree starts as a checkout
|
|
8
|
+
// and nothing else, and the lane root is a hidden *sibling* of the repository, so nothing above it
|
|
9
|
+
// resolves either — every `pnpm josh …` typed inside a fresh lane failed with `tsx: command not
|
|
10
|
+
// found`. The install itself is cheap, about 3.5 s from a warm store because pnpm hard-links out of
|
|
11
|
+
// it; what it cost was one failed command and one diagnostic round trip, per lane, every time.
|
|
12
|
+
//
|
|
13
|
+
// **The seconds are not the reason this module exists.** `tsx: command not found` reads like a
|
|
14
|
+
// broken toolchain to anyone who does not know the cause, and the way around a broken toolchain is
|
|
15
|
+
// to verify by some other means — a verification nobody would report as non-standard, because
|
|
16
|
+
// whoever ran it believed it was the only one available.
|
|
17
|
+
//
|
|
18
|
+
// The child is spawned through `buffered_process` rather than through `execa` here. What this needs
|
|
19
|
+
// is exactly that module's contract — output buffered rather than inherited, a non-zero exit
|
|
20
|
+
// reported rather than thrown, and a bound on how long the child may hang — and a second copy of it
|
|
21
|
+
// is how a fix to one missed the other before (joshuafolkken/kit#914).
|
|
22
|
+
|
|
23
|
+
// `--frozen-lockfile` because a lane is cut from `refs/remotes/origin/<default>` and has to build
|
|
24
|
+
// exactly the lock committed there. A lock the install would rather rewrite is a finding, not
|
|
25
|
+
// something to absorb silently into six parallel lanes.
|
|
26
|
+
const INSTALL_ARGUMENTS = ['install', '--frozen-lockfile']
|
|
27
|
+
// The manifest whose absence is the whole skip condition. A lane cut from a repository that has no
|
|
28
|
+
// `package.json` has nothing to install, so running `pnpm install` there could only fail on a
|
|
29
|
+
// manifest that was never there — which is exactly the fixture a cross-process lane test needs
|
|
30
|
+
// (joshuafolkken/kit#2148). The condition is strictly "the file does not exist": a manifest that is
|
|
31
|
+
// present but unreadable or broken still runs the install and still fails as before, so a genuinely
|
|
32
|
+
// broken repository is never passed silently.
|
|
33
|
+
const MANIFEST_FILE_NAME = 'package.json'
|
|
34
|
+
// The lane opens with no dependencies installed, and that is the reported state rather than a
|
|
35
|
+
// failure — there was nothing to install, so nothing failed.
|
|
36
|
+
const NO_MANIFEST_OUTPUT = `No ${MANIFEST_FILE_NAME} in the lane, so the dependency install was skipped.`
|
|
37
|
+
// The 3.5 s above is a warm store; a first run, or one after a dependency change, goes to the
|
|
38
|
+
// network, so that figure is not the bound to write here. Ten minutes covers that fetch and still
|
|
39
|
+
// ends `lane:open` when a registry never answers, rather than holding a parallel run open with
|
|
40
|
+
// nothing printed. It is well under the fan-out's own half hour because this one blocks a command a
|
|
41
|
+
// person is waiting on, not a check suite.
|
|
42
|
+
const INSTALL_TIMEOUT_MS = 600_000
|
|
43
|
+
|
|
44
|
+
interface InstallResult {
|
|
45
|
+
is_installed: boolean
|
|
46
|
+
// Captured rather than inherited, and reported only on a failure: `lane:open` prints the lane
|
|
47
|
+
// directory on standard output and nothing else, so an install writing there directly would
|
|
48
|
+
// break `dir=$(pnpm josh lane:open 1554)` for every caller.
|
|
49
|
+
output: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// A lane with no manifest has nothing to install, so the install is skipped rather than run — the
|
|
53
|
+
// seam a cross-process lane test needs, and a root-cause fix rather than a switch, because running
|
|
54
|
+
// an install with no install target was the defect (joshuafolkken/kit#2148). The condition is
|
|
55
|
+
// strictly the file's absence: `existsSync` answers only whether the path is there, never whether
|
|
56
|
+
// its contents parse, so a present-but-broken manifest falls through to the real install and fails
|
|
57
|
+
// exactly as before.
|
|
58
|
+
function has_manifest(directory: string): boolean {
|
|
59
|
+
return existsSync(path.join(directory, MANIFEST_FILE_NAME))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Install the lane's dependencies, and report whether it worked rather than throwing.
|
|
64
|
+
*
|
|
65
|
+
* **A lane with no `package.json` skips the install** — there is nothing to install, so the reported
|
|
66
|
+
* state is installed rather than failed, and no child is spawned (joshuafolkken/kit#2148). This is
|
|
67
|
+
* the only seam: the production call path, its arguments and its environment are all unchanged.
|
|
68
|
+
*
|
|
69
|
+
* **The verdict is the exit code and only the exit code.** `pnpm install` runs `prepare`, which runs
|
|
70
|
+
* the lefthook installer, and in a linked work tree the hooks are shared with the primary repository
|
|
71
|
+
* — so a warning from it is expected and correct (joshuafolkken/kit#1503, #1507). Reading the child's
|
|
72
|
+
* text for a word like "failed" would turn that correct warning into a refusal to open a lane.
|
|
73
|
+
*/
|
|
74
|
+
async function install_dependencies(directory: string): Promise<InstallResult> {
|
|
75
|
+
if (!has_manifest(directory)) return { is_installed: true, output: NO_MANIFEST_OUTPUT }
|
|
76
|
+
|
|
77
|
+
const result = await buffered_process.run_buffered_process(INSTALL_ARGUMENTS, {
|
|
78
|
+
cwd: directory,
|
|
79
|
+
timeout_ms: INSTALL_TIMEOUT_MS,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return { is_installed: !buffered_process.is_process_failed(result), output: result.output }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const lane_install = { install_dependencies }
|
|
86
|
+
|
|
87
|
+
export type { InstallResult }
|
|
88
|
+
export {
|
|
89
|
+
lane_install,
|
|
90
|
+
INSTALL_ARGUMENTS,
|
|
91
|
+
INSTALL_TIMEOUT_MS,
|
|
92
|
+
MANIFEST_FILE_NAME,
|
|
93
|
+
NO_MANIFEST_OUTPUT,
|
|
94
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { parseArgs } from 'node:util'
|
|
4
|
+
import { josh_command } from '#scripts/josh/josh-run'
|
|
5
|
+
import { execa } from 'execa'
|
|
6
|
+
|
|
7
|
+
// `josh lane:launch <issue> [--stash <message>]` — one composite command for a `backlogrun` lane-start
|
|
8
|
+
// event (joshuafolkken/kit#2162). Opening one lane was four to six turns of the parent: `lane:open`,
|
|
9
|
+
// then — only the first lane, and only when `josh latest` had stashed — `stash:pop` and a re-install,
|
|
10
|
+
// then `lane:dispatch`. This collapses them into one call that returns the child's pid, or a refusal,
|
|
11
|
+
// the same shape `lane:dispatch` alone has.
|
|
12
|
+
//
|
|
13
|
+
// **It is a thin layer over the existing commands**, shelling out to each so their guards, refusals
|
|
14
|
+
// and messages are reused rather than cloned — `lane:open`'s cut-session guard and its `full` /
|
|
15
|
+
// `already-open` refusals, `stash:pop`'s message-matched pop, `lane:dispatch`'s in-progress claim and
|
|
16
|
+
// warning. Their explanations stream through to stderr; the child's pid is the one thing on stdout.
|
|
17
|
+
|
|
18
|
+
const ARGV_OFFSET = 2
|
|
19
|
+
const SUCCESS_EXIT_CODE = 0
|
|
20
|
+
const FAILURE_EXIT_CODE = 1
|
|
21
|
+
const should_forward_stderr = true
|
|
22
|
+
const PNPM = 'pnpm'
|
|
23
|
+
const ISSUE_PATTERN = /^[1-9]\d*$/u
|
|
24
|
+
|
|
25
|
+
const USAGE = 'Usage: josh lane:launch <issue-number> [--stash <message>]'
|
|
26
|
+
|
|
27
|
+
const OPTIONS = { stash: { type: 'string' } } as const
|
|
28
|
+
|
|
29
|
+
// The stash message is present only for the first lane — the caller passes `--stash` there and nowhere
|
|
30
|
+
// else, so "only the first lane pops and re-installs" is preserved by which invocation carries it.
|
|
31
|
+
interface LaunchContext {
|
|
32
|
+
issue: string
|
|
33
|
+
stash: string | undefined
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function read_context(argv: ReadonlyArray<string>): LaunchContext | undefined {
|
|
37
|
+
try {
|
|
38
|
+
const parsed = parseArgs({
|
|
39
|
+
args: [...argv],
|
|
40
|
+
options: OPTIONS,
|
|
41
|
+
strict: true,
|
|
42
|
+
allowPositionals: true,
|
|
43
|
+
})
|
|
44
|
+
const [issue, ...rest] = parsed.positionals
|
|
45
|
+
|
|
46
|
+
if (issue === undefined || rest.length > 0 || !ISSUE_PATTERN.test(issue)) return undefined
|
|
47
|
+
|
|
48
|
+
return { issue, stash: parsed.values.stash }
|
|
49
|
+
} catch {
|
|
50
|
+
return undefined
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The pop brought in the `pnpm-lock.yaml` `josh latest` rewrote, so this one lane installs a second
|
|
55
|
+
// time against it. Output is captured and surfaced only on failure, so the composite's stdout stays
|
|
56
|
+
// the child's pid alone.
|
|
57
|
+
async function install(directory: string): Promise<boolean> {
|
|
58
|
+
const result = await execa(PNPM, ['--dir', directory, 'install', '--frozen-lockfile'], {
|
|
59
|
+
reject: false,
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
if ((result.exitCode ?? FAILURE_EXIT_CODE) === SUCCESS_EXIT_CODE) return true
|
|
63
|
+
|
|
64
|
+
console.error(result.stderr === '' ? result.stdout : result.stderr)
|
|
65
|
+
|
|
66
|
+
return false
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// The first lane pops the shared stash and re-installs against the lock it brought in; a pop that
|
|
70
|
+
// refused (`no-match` / `ambiguous`) stops the lane rather than dispatching onto an unprepared tree.
|
|
71
|
+
// A caller without `--stash` skips both, which is every lane after the first.
|
|
72
|
+
async function prepare(stash: string | undefined, directory: string): Promise<boolean> {
|
|
73
|
+
if (stash === undefined) return true
|
|
74
|
+
|
|
75
|
+
const popped = await josh_command.josh_run(
|
|
76
|
+
['stash:pop', stash, '--dir', directory],
|
|
77
|
+
should_forward_stderr,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if (popped.code !== SUCCESS_EXIT_CODE) return false
|
|
81
|
+
|
|
82
|
+
return await install(directory)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// The launch chain in-process: the dispatched child's pid, or `undefined` when a step refused. The CLI
|
|
86
|
+
// prints the pid; `backlog:drive` launches through this same chain (joshuafolkken/kit#2508).
|
|
87
|
+
async function launch_lane(context: LaunchContext): Promise<string | undefined> {
|
|
88
|
+
const opened = await josh_command.josh_run(['lane:open', context.issue], should_forward_stderr)
|
|
89
|
+
|
|
90
|
+
if (opened.code !== SUCCESS_EXIT_CODE) return undefined
|
|
91
|
+
|
|
92
|
+
if (!(await prepare(context.stash, opened.out))) return undefined
|
|
93
|
+
|
|
94
|
+
const dispatched = await josh_command.josh_run(
|
|
95
|
+
['lane:dispatch', context.issue],
|
|
96
|
+
should_forward_stderr,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
return dispatched.code === SUCCESS_EXIT_CODE ? dispatched.out : undefined
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function launch(context: LaunchContext): Promise<number> {
|
|
103
|
+
const pid = await launch_lane(context)
|
|
104
|
+
|
|
105
|
+
if (pid === undefined) return FAILURE_EXIT_CODE
|
|
106
|
+
|
|
107
|
+
console.info(pid)
|
|
108
|
+
|
|
109
|
+
return SUCCESS_EXIT_CODE
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
113
|
+
const context = read_context(argv)
|
|
114
|
+
|
|
115
|
+
if (context === undefined) {
|
|
116
|
+
console.error(USAGE)
|
|
117
|
+
|
|
118
|
+
return FAILURE_EXIT_CODE
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return await launch(context)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
125
|
+
process.exitCode = await run(argv)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const lane_launch_cli = { USAGE, install, launch, launch_lane, prepare, read_context, run }
|
|
129
|
+
|
|
130
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
131
|
+
|
|
132
|
+
export type { LaunchContext }
|
|
133
|
+
export { lane_launch_cli }
|