@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,366 @@
|
|
|
1
|
+
// `josh run:progress` — the one line an unattended run prints when it has gone quiet, and the clock
|
|
2
|
+
// that decides when that is (joshuafolkken/kit#1520).
|
|
3
|
+
//
|
|
4
|
+
// **The trigger is silence, not a timer.** An `epicrun` reports when a child merges or is parked, and
|
|
5
|
+
// a child is 20–46 minutes of wall clock; between those two events it says nothing at all, so the
|
|
6
|
+
// person watching has to type "how is it going" to find out — the polling this command exists to
|
|
7
|
+
// remove. What it deliberately does **not** do is print on a fixed clock: the interval is measured
|
|
8
|
+
// from the last report of *any* kind, so a heartbeat never lands immediately behind a real one, where
|
|
9
|
+
// it would be noise rather than news. `--mark` is how the run tells this clock a real report happened.
|
|
10
|
+
//
|
|
11
|
+
// **A line that could say "still running" is a line not worth printing.** Five minutes was measured in
|
|
12
|
+
// live use on 2026-09-07 and 6 of 15 reports carried no changed number at all, which is the same
|
|
13
|
+
// information as silence. Ten was measured next and was still short of a stage change, so the default
|
|
14
|
+
// is twenty minutes (joshuafolkken/kit#1570): a child measures 20–46 minutes, and twenty gives one to
|
|
15
|
+
// two reports per child rather than a run of lines saying what the last one said. Every field below is
|
|
16
|
+
// re-read on each tick rather than remembered — a child's labels, whether a pull request exists yet,
|
|
17
|
+
// which lanes are open, the load average, and how long the whole set has been identical.
|
|
18
|
+
//
|
|
19
|
+
// **The interval is kept here so one number answers for both halves of the mechanism.** The watcher
|
|
20
|
+
// asks `is_due` before it prints, and the trigger-delivered rule that refuses an early heartbeat
|
|
21
|
+
// (`scripts/rules/early-heartbeat.ts`) asks the same two functions rather than carrying a second copy
|
|
22
|
+
// of the clock — a guard that could disagree with the watcher it guards is worse than no guard.
|
|
23
|
+
//
|
|
24
|
+
// **Nothing here reports a verification result.** No gate conclusion, no CI conclusion, no check
|
|
25
|
+
// rollup: this module reads none of them, and a result nobody read must never be printed as one. What
|
|
26
|
+
// it prints about a pull request is that one exists and what state GitHub calls it — which is a read
|
|
27
|
+
// it actually performs.
|
|
28
|
+
//
|
|
29
|
+
// **The line also says *when* it was observed, and not only how long the silence had run**
|
|
30
|
+
// (joshuafolkken/kit#1560). A relative figure means something only while the reports keep coming: an
|
|
31
|
+
// `epicrun` suspended overnight resumed and read its own `quiet 11m` as if no time had passed, and
|
|
32
|
+
// concluded the machine's clock was broken when it matched GitHub's `Date` header to the second. Three
|
|
33
|
+
// decisions follow from that, and each is a decision rather than a default:
|
|
34
|
+
//
|
|
35
|
+
// - **The date is carried, not just the clock time.** The confusion above happened across a day
|
|
36
|
+
// boundary, so an `HH:MM` alone would have left the same hole open.
|
|
37
|
+
// - **The local clock leads, and UTC is printed beside it.** The local half is the one a person can
|
|
38
|
+
// act on without converting anything, which is what UTC alone denied a reader seven hours from it
|
|
39
|
+
// (joshuafolkken/kit#1589). UTC is kept rather than replaced: the line is read from other machines
|
|
40
|
+
// and from cloud sessions, and joshuafolkken/kit#1245 already paid for a timestamp rendered in the
|
|
41
|
+
// reader's zone making one process look like a stranger. The printed offset ties the two halves
|
|
42
|
+
// together, so a reader on a third machine can place both.
|
|
43
|
+
// - **It is added beside the elapsed figures, never in place of them.** How long it has been quiet and
|
|
44
|
+
// when the observation was taken are two different facts, and neither can be reconstructed from the
|
|
45
|
+
// other without knowing the answer already.
|
|
46
|
+
|
|
47
|
+
const DEFAULT_INTERVAL_MINUTES = 20
|
|
48
|
+
// The one name for the setting, so the watcher and the guard read the same variable rather than two
|
|
49
|
+
// spellings of it.
|
|
50
|
+
const INTERVAL_KEY = 'JOSH_PROGRESS_INTERVAL_MINUTES'
|
|
51
|
+
const MS_PER_MINUTE = 60_000
|
|
52
|
+
const MS_PER_SECOND = 1000
|
|
53
|
+
const DEFAULT_INTERVAL_MS = DEFAULT_INTERVAL_MINUTES * MS_PER_MINUTE
|
|
54
|
+
|
|
55
|
+
// What one child looked like on this tick. `pr_state` is `run_preflight`'s own vocabulary rather than
|
|
56
|
+
// a second spelling of it — `none` / `open` / `merged` / `closed`.
|
|
57
|
+
interface ChildObservation {
|
|
58
|
+
issue: string
|
|
59
|
+
labels: ReadonlyArray<string>
|
|
60
|
+
pr_state: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface LaneObservation {
|
|
64
|
+
issue: string
|
|
65
|
+
state: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface Observations {
|
|
69
|
+
children: ReadonlyArray<ChildObservation>
|
|
70
|
+
lanes: ReadonlyArray<LaneObservation>
|
|
71
|
+
load_average: number
|
|
72
|
+
// Absent when no transcript path was given, and absent is printed as absent. Guessing an age for
|
|
73
|
+
// a file nobody named would be exactly the unread result this command refuses to print.
|
|
74
|
+
record_age_ms: number | undefined
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// How long the *changing* part of the observation has been identical. Carried between ticks by the
|
|
78
|
+
// caller, because the loop is the only thing that lives across them.
|
|
79
|
+
interface ProgressState {
|
|
80
|
+
key: string
|
|
81
|
+
unchanged_since_ms: number
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const NO_LANES = 'none'
|
|
85
|
+
// The children slot when the run has started but no child carries `in-progress` yet
|
|
86
|
+
// (joshuafolkken/kit#1900). It is an observed fact — zero in-progress children — not a guess about
|
|
87
|
+
// what will appear: `read_observations` returns an observation at all only because a mechanical record
|
|
88
|
+
// (a lane, a hold, or a carried budget) says a run is underway, and the lanes field beside this one
|
|
89
|
+
// carries whatever evidence exists.
|
|
90
|
+
const NO_CHILD_YET = 'no in-progress child yet'
|
|
91
|
+
// The fifth line's value when there is no scheduled next report. The command always supplies one, so
|
|
92
|
+
// this is the migrated form of the rule `backlogrun.md` used to hold — a line with no `next` field says
|
|
93
|
+
// the field was absent rather than inventing a time (joshuafolkken/kit#2026). `format_report` is a pure
|
|
94
|
+
// renderer, so its contract states the absence rather than assuming a stamp is always there.
|
|
95
|
+
const NO_NEXT = 'none'
|
|
96
|
+
const QUIET_MARKER = '⏳'
|
|
97
|
+
// `1970-01-01T00:00:00.000Z` cut after the minutes. Seconds are dropped because the interval this line
|
|
98
|
+
// breaks is measured in minutes, and a heartbeat that claims a precision nobody uses is noise.
|
|
99
|
+
const STAMP_END = 16
|
|
100
|
+
// Two digits for every calendar and clock field the local half prints, and for each half of the offset.
|
|
101
|
+
const PAD_WIDTH = 2
|
|
102
|
+
const MINUTES_PER_HOUR = 60
|
|
103
|
+
|
|
104
|
+
function to_minutes(elapsed_ms: number): number {
|
|
105
|
+
return Math.floor(elapsed_ms / MS_PER_MINUTE)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function format_minutes(elapsed_ms: number): string {
|
|
109
|
+
return `${String(to_minutes(elapsed_ms))}m`
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function pad(value: number): string {
|
|
113
|
+
return String(value).padStart(PAD_WIDTH, '0')
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The local clock's offset from UTC, in whole minutes, signed the way a reader expects to see it.
|
|
118
|
+
*
|
|
119
|
+
* `getTimezoneOffset` counts minutes the local zone is *behind* UTC, so the sign is inverted here — a
|
|
120
|
+
* zone ahead of UTC answers a negative number there and has to read `+`.
|
|
121
|
+
*
|
|
122
|
+
* **It is rounded**, because a historic offset is not a whole number of minutes: `Asia/Kathmandu` was
|
|
123
|
+
* `+05:41:16` until 1986, so a stamp taken at an instant in that era answers `-341.2666…` and the
|
|
124
|
+
* minutes field would print `41.26666666666667` rather than `41`.
|
|
125
|
+
*/
|
|
126
|
+
function offset_minutes(date: Date): number {
|
|
127
|
+
return Math.round(-date.getTimezoneOffset())
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** That offset written `+HH:MM` or `-HH:MM`, from the same rounded minute total the stamp is built on. */
|
|
131
|
+
function format_offset(total_minutes: number): string {
|
|
132
|
+
const sign = total_minutes < 0 ? '-' : '+'
|
|
133
|
+
const absolute = Math.abs(total_minutes)
|
|
134
|
+
|
|
135
|
+
return `${sign}${pad(Math.floor(absolute / MINUTES_PER_HOUR))}:${pad(absolute % MINUTES_PER_HOUR)}`
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The instant this observation was taken, on the local clock and in UTC, with its date on both.
|
|
140
|
+
*
|
|
141
|
+
* **The local half leads because it is the half a person can act on.** The line used to carry UTC
|
|
142
|
+
* alone, and on a machine seven hours ahead every stamp in the report was a number the reader had to
|
|
143
|
+
* convert before it meant anything — which is the same failure joshuafolkken/kit#1560 filed, arriving
|
|
144
|
+
* from the other side: a stamp nobody can place is a stamp nobody reads.
|
|
145
|
+
*
|
|
146
|
+
* **UTC is kept beside it rather than replaced.** The reason it was pinned is real and unchanged: the
|
|
147
|
+
* line is relayed to other machines and read in cloud sessions, and joshuafolkken/kit#1245 already
|
|
148
|
+
* paid for a timestamp rendered in the reader's zone making one process look like a stranger. Printing
|
|
149
|
+
* both costs twenty-five characters and leaves neither reader guessing — the offset is what ties the
|
|
150
|
+
* two halves together, so a reader on a third machine can place the local half as well.
|
|
151
|
+
*
|
|
152
|
+
* **The local half is read off the instant shifted by that same rounded offset, never off `getHours`
|
|
153
|
+
* and `getMinutes`.** Those truncate the seconds of a sub-minute offset while the offset beside them
|
|
154
|
+
* is rounded, so the two would disagree by a minute in a zone such as `Africa/Monrovia` (`-00:44:30`
|
|
155
|
+
* in 1970) and the stamp would no longer parse back to the instant it was taken at. Shifting first and
|
|
156
|
+
* reading UTC fields off the result makes the two halves consistent by construction.
|
|
157
|
+
*
|
|
158
|
+
* It reads the `now_ms` the line is already formatted against rather than calling a clock of its own,
|
|
159
|
+
* so the stamp can never disagree with the elapsed figures printed beside it.
|
|
160
|
+
*/
|
|
161
|
+
function format_observed_at(now_ms: number): string {
|
|
162
|
+
const minutes = offset_minutes(new Date(now_ms))
|
|
163
|
+
const local = new Date(now_ms + minutes * MS_PER_MINUTE)
|
|
164
|
+
const day = `${String(local.getUTCFullYear())}-${pad(local.getUTCMonth() + 1)}-${pad(local.getUTCDate())}`
|
|
165
|
+
const clock = `${pad(local.getUTCHours())}:${pad(local.getUTCMinutes())}${format_offset(minutes)}`
|
|
166
|
+
|
|
167
|
+
return `${day} ${clock} / ${new Date(now_ms).toISOString().slice(0, STAMP_END)}Z`
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* The part of an observation that is compared across ticks.
|
|
172
|
+
*
|
|
173
|
+
* **The load average and the record age are deliberately left out.** Both move on every tick by
|
|
174
|
+
* construction, so including either would make "unchanged" impossible to reach and would throw away
|
|
175
|
+
* the one field that says a run may be stuck. What is left is the set that only moves when the run
|
|
176
|
+
* itself moves: which children are in flight, what they carry, and which lanes are open.
|
|
177
|
+
*/
|
|
178
|
+
function observation_key(observations: Observations): string {
|
|
179
|
+
return JSON.stringify({ children: observations.children, lanes: observations.lanes })
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The unchanged-since clock, carried forward when the key matches and restarted when it does not.
|
|
184
|
+
*
|
|
185
|
+
* The first tick has no previous state and starts the clock at `now_ms`, which reads as `unchanged 0m`
|
|
186
|
+
* — true, and honest about the fact that nothing has been compared yet.
|
|
187
|
+
*/
|
|
188
|
+
function next_state(
|
|
189
|
+
previous: ProgressState | undefined,
|
|
190
|
+
key: string,
|
|
191
|
+
now_ms: number,
|
|
192
|
+
): ProgressState {
|
|
193
|
+
if (previous?.key === key) return previous
|
|
194
|
+
|
|
195
|
+
return { key, unchanged_since_ms: now_ms }
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function format_child(child: ChildObservation): string {
|
|
199
|
+
const labels = child.labels.length > 0 ? child.labels.join(',') : '(no labels)'
|
|
200
|
+
|
|
201
|
+
return `#${child.issue} ${labels} PR:${child.pr_state}`
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// An empty set is the pre-label stage, said as such rather than left as a blank slot between the
|
|
205
|
+
// separators (joshuafolkken/kit#1900). After that change a `read_observations` result carries no
|
|
206
|
+
// children exactly when a run has started and none has reached `in-progress` yet, so this is the one
|
|
207
|
+
// place the two cases are told apart on the line.
|
|
208
|
+
function format_children(children: ReadonlyArray<ChildObservation>): string {
|
|
209
|
+
if (children.length === 0) return NO_CHILD_YET
|
|
210
|
+
|
|
211
|
+
return children.map((child) => format_child(child)).join(' · ')
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function format_lanes(lanes: ReadonlyArray<LaneObservation>): string {
|
|
215
|
+
if (lanes.length === 0) return NO_LANES
|
|
216
|
+
|
|
217
|
+
return lanes.map((lane) => `${lane.issue}:${lane.state}`).join(' ')
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Absent is said, never filled in. A run started without a transcript path prints `unread` here, which
|
|
221
|
+
// is what it is.
|
|
222
|
+
function format_record(record_age_ms: number | undefined): string {
|
|
223
|
+
return record_age_ms === undefined ? 'unread' : `+${format_minutes(record_age_ms)}`
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
interface LineTiming {
|
|
227
|
+
// The interval in force, already resolved by `run-progress-config.ts` → `resolve_interval_ms`. It
|
|
228
|
+
// is passed in rather than read here so that the printed schedule and the clock `is_due` consults
|
|
229
|
+
// can never be two different numbers.
|
|
230
|
+
interval_ms: number
|
|
231
|
+
now_ms: number
|
|
232
|
+
quiet_since_ms: number
|
|
233
|
+
unchanged_since_ms: number
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* When the next line is due if the silence holds — printed, never left for a reader to work out.
|
|
238
|
+
*
|
|
239
|
+
* **The two inputs were both here already and only one of them was printed** (joshuafolkken/kit#1726).
|
|
240
|
+
* `backlogrun.md` asked the run to derive this from the `at` stamp plus the interval in force, and a run
|
|
241
|
+
* that derives a time by hand eventually derives it wrong: one report reached a person as `20:1x`,
|
|
242
|
+
* placeholder digits and all. Every comparable judgement in this repository has moved to the command
|
|
243
|
+
* that already holds the inputs — `run:hold`, `delegate`, `review:level`, `latest:scope` — and
|
|
244
|
+
* this is that same move for one value.
|
|
245
|
+
*
|
|
246
|
+
* **It is a schedule rather than an observation, and the two conditions on it are said in prose**
|
|
247
|
+
* (`docs/josh-commands.md` → `josh run:progress`): it holds only while the silence continues, and a
|
|
248
|
+
* real report arriving first restarts the clock through `--mark` and supersedes it. The line printing
|
|
249
|
+
* it is itself a report, so the clock starts at this observation.
|
|
250
|
+
*/
|
|
251
|
+
function format_next_report(now_ms: number, interval_ms: number): string {
|
|
252
|
+
return format_observed_at(now_ms + interval_ms)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// The already-formatted field strings the five labelled lines are built from. They are kept as strings
|
|
256
|
+
// rather than the raw observation so that `format_report` stays a pure renderer the tests can drive with
|
|
257
|
+
// an absent `next`, which is the migrated home of the doc's absent-field rule.
|
|
258
|
+
interface ReportFields {
|
|
259
|
+
observed_at: string
|
|
260
|
+
quiet: string
|
|
261
|
+
unchanged: string
|
|
262
|
+
children: string
|
|
263
|
+
lanes: string
|
|
264
|
+
load: string
|
|
265
|
+
record: string
|
|
266
|
+
next: string | undefined
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// `next none` when there is no scheduled report, the stamp otherwise — the absence said the same way the
|
|
270
|
+
// other absent fields are (`record unread`, `lanes none`).
|
|
271
|
+
function format_next_line(next: string | undefined): string {
|
|
272
|
+
return `next ${next ?? NO_NEXT}`
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* The five labelled lines a quiet run prints — one field group per line, a label in front of every
|
|
277
|
+
* field — so a person reads them without anything downstream re-labelling them (joshuafolkken/kit#2026).
|
|
278
|
+
* The command used to emit one `·`-joined run of values that `backlogrun.md` asked the parent to rewrite
|
|
279
|
+
* by hand every interval; the labels and the line breaks live here now, so the parent relays the output
|
|
280
|
+
* verbatim and rounds, rephrases or re-labels nothing.
|
|
281
|
+
*
|
|
282
|
+
* The observation instant leads and the scheduled next closes it, for the reason the single line kept
|
|
283
|
+
* them at its two ends: the first field says whether everything after it is still about now, and the
|
|
284
|
+
* last is the one field about a moment that has not happened yet.
|
|
285
|
+
*/
|
|
286
|
+
function format_report(fields: ReportFields): string {
|
|
287
|
+
return [
|
|
288
|
+
`${QUIET_MARKER} at ${fields.observed_at}`,
|
|
289
|
+
`quiet ${fields.quiet} · unchanged ${fields.unchanged}`,
|
|
290
|
+
`children ${fields.children}`,
|
|
291
|
+
`lanes ${fields.lanes} · load ${fields.load} · record ${fields.record}`,
|
|
292
|
+
format_next_line(fields.next),
|
|
293
|
+
].join('\n')
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* The observations rendered into those five lines. It reads `now_ms` for both the observation stamp and
|
|
298
|
+
* the scheduled next so the two can never disagree, and hands `format_report` already-formatted strings
|
|
299
|
+
* so the rendering has one home.
|
|
300
|
+
*/
|
|
301
|
+
function format_line(observations: Observations, timing: LineTiming): string {
|
|
302
|
+
return format_report({
|
|
303
|
+
observed_at: format_observed_at(timing.now_ms),
|
|
304
|
+
quiet: format_minutes(timing.now_ms - timing.quiet_since_ms),
|
|
305
|
+
unchanged: format_minutes(timing.now_ms - timing.unchanged_since_ms),
|
|
306
|
+
children: format_children(observations.children),
|
|
307
|
+
lanes: format_lanes(observations.lanes),
|
|
308
|
+
load: observations.load_average.toFixed(1),
|
|
309
|
+
record: format_record(observations.record_age_ms),
|
|
310
|
+
next: format_next_report(timing.now_ms, timing.interval_ms),
|
|
311
|
+
})
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Whether the silence has run long enough to be worth breaking.
|
|
316
|
+
*
|
|
317
|
+
* `>=` rather than `>`: the loop wakes on a timer that can land a millisecond early or late, and a
|
|
318
|
+
* strict comparison there costs a whole extra sleep for no reason anyone could observe.
|
|
319
|
+
*/
|
|
320
|
+
function is_due(last_report_ms: number, now_ms: number, interval_ms: number): boolean {
|
|
321
|
+
return now_ms - last_report_ms >= interval_ms
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* One setting's minutes, or `undefined` for everything that is not a positive number.
|
|
326
|
+
*
|
|
327
|
+
* **Invalid answers `undefined` rather than throwing**, the reading `JOSH_CI_TIMEOUT_SECONDS` already
|
|
328
|
+
* uses: this runs unattended in the background, and a run that dies on a typo in an optional setting
|
|
329
|
+
* has removed the reporting the setting was there to tune. Which source is asked next, and in what
|
|
330
|
+
* order, is `run-progress-config.ts` → `resolve_interval_ms`; this module answers about one value and
|
|
331
|
+
* asks nothing else, which is what lets both the watcher and the guard read it the same way.
|
|
332
|
+
*/
|
|
333
|
+
function minutes_from(raw: string | undefined): number | undefined {
|
|
334
|
+
const minutes = Number(raw)
|
|
335
|
+
|
|
336
|
+
if (raw === undefined || raw.trim() === '' || !Number.isFinite(minutes) || minutes <= 0) {
|
|
337
|
+
return undefined
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return minutes
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const run_progress = {
|
|
344
|
+
DEFAULT_INTERVAL_MINUTES,
|
|
345
|
+
DEFAULT_INTERVAL_MS,
|
|
346
|
+
INTERVAL_KEY,
|
|
347
|
+
MS_PER_MINUTE,
|
|
348
|
+
MS_PER_SECOND,
|
|
349
|
+
NO_CHILD_YET,
|
|
350
|
+
NO_NEXT,
|
|
351
|
+
format_child,
|
|
352
|
+
format_children,
|
|
353
|
+
format_lanes,
|
|
354
|
+
format_line,
|
|
355
|
+
format_next_line,
|
|
356
|
+
format_next_report,
|
|
357
|
+
format_record,
|
|
358
|
+
format_report,
|
|
359
|
+
is_due,
|
|
360
|
+
minutes_from,
|
|
361
|
+
next_state,
|
|
362
|
+
observation_key,
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export type { ChildObservation, LaneObservation, Observations, ProgressState }
|
|
366
|
+
export { run_progress }
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { git_followup_pending } from '#scripts/git/git-followup-pending'
|
|
4
|
+
import { release_scope_cli } from '#scripts/release/release-scope-cli'
|
|
5
|
+
import { run_carry } from './run-carry'
|
|
6
|
+
import { run_event_scope, type EventScope } from './run-event-scope'
|
|
7
|
+
import { run_event_stream, type RunEvent } from './run-event-stream'
|
|
8
|
+
import { run_event_stream_emit } from './run-event-stream-emit'
|
|
9
|
+
import { run_report } from './run-report'
|
|
10
|
+
|
|
11
|
+
// `josh run:report` — the session-facing report, generated from the run's event stream rather than
|
|
12
|
+
// composed by hand (joshuafolkken/kit#2249). It reads the events the run appended, asks `release:scope`
|
|
13
|
+
// the same question `josh followup` already asks, and prints `run_report.build_report` of the two. The AI
|
|
14
|
+
// writes only Step 0's three lines (Now / Change / Check), which `report-format.md` names as the half a
|
|
15
|
+
// machine cannot answer; this owns the mechanical half — what merged, what parked and why, what was cut,
|
|
16
|
+
// and whether a release is owed.
|
|
17
|
+
//
|
|
18
|
+
// **The body it prints is the Telegram body too.** `josh notify --body-file <file>` sends exactly this
|
|
19
|
+
// output, so the summary a session shows and the message a person reads off-screen are one string from one
|
|
20
|
+
// generator, never a second wording of the same facts.
|
|
21
|
+
|
|
22
|
+
const SUCCESS_EXIT_CODE = 0
|
|
23
|
+
|
|
24
|
+
// An absent or unreadable stream is an empty run, the same fail-quiet direction the stream's own reader
|
|
25
|
+
// takes — a report with no events is a report, not an error.
|
|
26
|
+
async function read_stream(): Promise<ReadonlyArray<RunEvent>> {
|
|
27
|
+
const target = await run_event_stream_emit.stream_target()
|
|
28
|
+
|
|
29
|
+
if (target === undefined) return []
|
|
30
|
+
|
|
31
|
+
return run_event_stream.read_events(target)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// The invocation this report covers, taken from the run record that already holds the start time
|
|
35
|
+
// (joshuafolkken/kit#2393). A checkout whose git directory cannot be resolved has no record to read, which is
|
|
36
|
+
// the same undetermined answer an absent record gives — and neither one falls back to the whole stream.
|
|
37
|
+
async function read_scope(): Promise<EventScope> {
|
|
38
|
+
const directory = await run_carry.repository_directory()
|
|
39
|
+
|
|
40
|
+
if (directory === undefined) return run_event_scope.UNKNOWN_EVENT_SCOPE
|
|
41
|
+
|
|
42
|
+
return run_event_scope.scope_of(run_carry.read_carry(run_carry.carry_path(directory)))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// The three reads are independent, so they are issued together rather than one after another — the stream, the
|
|
46
|
+
// pending-merge count and the run record share no input.
|
|
47
|
+
async function run(): Promise<number> {
|
|
48
|
+
const [events, pending, scope] = await Promise.all([
|
|
49
|
+
read_stream(),
|
|
50
|
+
git_followup_pending.read_pending({}),
|
|
51
|
+
read_scope(),
|
|
52
|
+
])
|
|
53
|
+
const release = release_scope_cli.decide(pending)
|
|
54
|
+
|
|
55
|
+
process.stdout.write(`${run_report.build_report({ events, release, scope })}\n`)
|
|
56
|
+
|
|
57
|
+
return SUCCESS_EXIT_CODE
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function main(): Promise<void> {
|
|
61
|
+
process.exitCode = await run()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const run_report_cli = {
|
|
65
|
+
main,
|
|
66
|
+
run,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
|
|
70
|
+
|
|
71
|
+
export { run_report_cli }
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { release_scope_cli, type Decision } from '#scripts/release/release-scope-cli'
|
|
2
|
+
import { run_event_scope, type EventScope } from './run-event-scope'
|
|
3
|
+
import { run_event_stream, type RunEvent } from './run-event-stream'
|
|
4
|
+
|
|
5
|
+
// The session-facing report generated *from* the run's event stream, rather than composed by hand each
|
|
6
|
+
// time (joshuafolkken/kit#2249). #2205 gave the run a typed, ordered stream of what happened — a plan, a
|
|
7
|
+
// launch, a merge, a park, a cut — and `format_event` already single-sources what one of those reads as.
|
|
8
|
+
// What was never single-sourced is the report a person receives: `backlogrun-progress.md` defined the
|
|
9
|
+
// epic completion summary in prose ("naming what was merged, what was parked and why, and what was
|
|
10
|
+
// filed"), so the AI reassembled the wording every run and two runs' summaries never lined up.
|
|
11
|
+
//
|
|
12
|
+
// **This is that generator, and it owns nothing `format_event` owns.** Each event line is `format_event`'s
|
|
13
|
+
// verbatim — the merges, the parks with their reason in the text, the cuts — so the enumeration is the
|
|
14
|
+
// stream rendered, not a second rendering of it. The only thing this adds is the release tail, which is
|
|
15
|
+
// not on the stream: whether a release is owed is `release:scope`'s answer, appended once at the end.
|
|
16
|
+
//
|
|
17
|
+
// **The Telegram body is this same string.** `run:report` prints it, and `josh notify --body-file` sends
|
|
18
|
+
// exactly what was printed, so the body a person reads off-screen and the summary a session shows are one
|
|
19
|
+
// text with one generator — the "no second format" the acceptance criteria pin.
|
|
20
|
+
//
|
|
21
|
+
// **And it covers one invocation, not the whole stream** (joshuafolkken/kit#2393, reported a second time
|
|
22
|
+
// after #2308 was closed with no fix behind it). The stream outlives an invocation by design — it is the
|
|
23
|
+
// repository's event log, not this run's — so a generator handed every event renders every run that ever
|
|
24
|
+
// appended one. Two days of merges arrived in one completion summary, and the Telegram body built from that
|
|
25
|
+
// output was rejected for length, which is the failure the generated report exists to prevent. The scope is
|
|
26
|
+
// therefore an **input**: the caller answers which invocation this is, from the run record that already
|
|
27
|
+
// holds the start time, and a scope nobody could determine prints a notice rather than everything. **The
|
|
28
|
+
// scoping itself is `run-event-scope.ts`'s** (joshuafolkken/kit#2395), shared with every other stream
|
|
29
|
+
// consumer rather than kept private here.
|
|
30
|
+
|
|
31
|
+
const LINE_SEPARATOR = '\n'
|
|
32
|
+
|
|
33
|
+
// What an undetermined scope prints in place of every event. It is a line rather than silence for the reason
|
|
34
|
+
// `release:scope` keeps `unknown` apart from `skip`: a reader given no line at all would read the empty
|
|
35
|
+
// report as an empty run, which is the rounding the criteria forbid.
|
|
36
|
+
const UNKNOWN_SCOPE_NOTICE =
|
|
37
|
+
'Could not determine which invocation these events belong to, so none are shown rather than the whole stream. Begin a run record with `pnpm josh run:carry --begin` first.'
|
|
38
|
+
|
|
39
|
+
interface ReportInput {
|
|
40
|
+
events: ReadonlyArray<RunEvent>
|
|
41
|
+
release: Decision
|
|
42
|
+
scope: EventScope
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// The release verdict as the report's closing line, or nothing. `required` closes with the request and
|
|
46
|
+
// the exact command, and `unknown` says `unknown` — both carried verbatim in `release:scope`'s own reason,
|
|
47
|
+
// so the wording is that command's and not a second copy. **`skip` alone is silent**: appending a line for
|
|
48
|
+
// it is what would round `unknown` toward "nothing is owed", the mistake the criteria forbid, so the two
|
|
49
|
+
// stay distinguishable by the presence of the line itself.
|
|
50
|
+
function release_tail(release: Decision): string | undefined {
|
|
51
|
+
if (release.scope === release_scope_cli.SKIPPED_SCOPE) return undefined
|
|
52
|
+
|
|
53
|
+
return release.reason
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// The report: this invocation's events as `format_event`'s lines, then the release tail when there is one.
|
|
57
|
+
// Handed the same events, scope and verdict it returns the same string, which is what the determinism test
|
|
58
|
+
// pins — nothing here reads a clock or the environment. The scoping is `run-event-scope.ts`'s, shared with
|
|
59
|
+
// every other stream consumer (joshuafolkken/kit#2395).
|
|
60
|
+
function build_report(input: ReportInput): string {
|
|
61
|
+
const scoped = run_event_scope.scoped_events(input.events, input.scope)
|
|
62
|
+
const lines =
|
|
63
|
+
scoped === undefined
|
|
64
|
+
? [UNKNOWN_SCOPE_NOTICE]
|
|
65
|
+
: scoped.map((event) => run_event_stream.format_event(event))
|
|
66
|
+
const tail = release_tail(input.release)
|
|
67
|
+
|
|
68
|
+
return [...lines, ...(tail === undefined ? [] : [tail])].join(LINE_SEPARATOR)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const run_report = {
|
|
72
|
+
UNKNOWN_SCOPE_NOTICE,
|
|
73
|
+
build_report,
|
|
74
|
+
release_tail,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type { ReportInput }
|
|
78
|
+
export { run_report }
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { review_brief_cli } from '#scripts/review/review-brief-cli'
|
|
4
|
+
import { review_stamps } from '#scripts/review/review-stamps'
|
|
5
|
+
import { run_review, type GateState, type ReviewTiming } from './run-review'
|
|
6
|
+
import { run_review_steps } from './run-review-steps'
|
|
7
|
+
|
|
8
|
+
// `josh run:review` — one call that leaves `josh gate` running in the background and prints the whole
|
|
9
|
+
// `/code-review` brief, so a lane child launches the two together and they overlap
|
|
10
|
+
// (joshuafolkken/kit#2179). It composes `josh gate` and `josh review:brief` and changes neither: the
|
|
11
|
+
// gate is the same command spawned detached, and the brief is `review:brief` run unchanged, so the
|
|
12
|
+
// nonce/checkout contract `review:attest --check` enforces is minted exactly as before.
|
|
13
|
+
//
|
|
14
|
+
// **The default mode opens the pair; `--join` closes it.** The child runs the default, reads the brief
|
|
15
|
+
// off stdout, launches the review subagent, and — once it returns — runs `--join`, which waits for the
|
|
16
|
+
// gate to finish, records the overlap, and exits non-zero if the gate came back red. That exit code is
|
|
17
|
+
// what makes "a red gate is not adopted over" a mechanical guarantee rather than an ordering the child
|
|
18
|
+
// used to get for free (`run-review.ts` → `adopt_verdict`).
|
|
19
|
+
|
|
20
|
+
const ARGV_OFFSET = 2
|
|
21
|
+
const JOIN_FLAG = '--join'
|
|
22
|
+
const SUCCESS_EXIT_CODE = 0
|
|
23
|
+
const FAILURE_EXIT_CODE = 1
|
|
24
|
+
const USAGE = 'Usage: josh run:review [--join]'
|
|
25
|
+
|
|
26
|
+
function now_iso(): string {
|
|
27
|
+
return new Date().toISOString()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// The join exits 0 only on a green gate. `--join` is run before the review verdict is acted on, so a
|
|
31
|
+
// non-zero exit here is what stops a run adopting a review over a red gate.
|
|
32
|
+
function join_exit_code(state: GateState): number {
|
|
33
|
+
return run_review.adopt_verdict(state === run_review.GATE_GREEN) === run_review.ADOPT
|
|
34
|
+
? SUCCESS_EXIT_CODE
|
|
35
|
+
: FAILURE_EXIT_CODE
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const JOIN_HINT =
|
|
39
|
+
'Gate is running in the background. Launch the /code-review subagent with the brief above; when it returns, run `pnpm josh run:review --join` to join the gate and check its verdict before committing.'
|
|
40
|
+
|
|
41
|
+
async function run_start(): Promise<number> {
|
|
42
|
+
const gate_started_at = now_iso()
|
|
43
|
+
const launch = run_review_steps.launch_gate()
|
|
44
|
+
|
|
45
|
+
if (launch.kind === 'failed') {
|
|
46
|
+
process.stderr.write(`the background gate could not be started: ${launch.note}\n`)
|
|
47
|
+
|
|
48
|
+
return FAILURE_EXIT_CODE
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await run_review_steps.mark_gate_starting()
|
|
52
|
+
run_review_steps.write_timing_start({ gate_started_at, review_started_at: now_iso() })
|
|
53
|
+
const code = await review_brief_cli.run([])
|
|
54
|
+
|
|
55
|
+
// The hint follows a printed brief and nothing else: a brief that refused (a tree the scoped pair
|
|
56
|
+
// has not been green on) exits non-zero, and a "gate running, launch the review" line under that
|
|
57
|
+
// refusal would send the child to review a tree there is no brief for.
|
|
58
|
+
if (code === SUCCESS_EXIT_CODE) process.stderr.write(`${JOIN_HINT}\n`)
|
|
59
|
+
|
|
60
|
+
return code
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// The gate's own green stamp carries the moment it finished; a red gate leaves none, so the join's own
|
|
64
|
+
// clock is the end there — the review overlapped a gate that ran up to this point either way.
|
|
65
|
+
function gate_ended_at(is_green: boolean): string {
|
|
66
|
+
if (!is_green) return now_iso()
|
|
67
|
+
|
|
68
|
+
return review_stamps.gate_stamp.read()?.taken_at ?? now_iso()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const GREEN_NOTE = 'Gate green — the review verdict may be adopted.'
|
|
72
|
+
const RED_NOTE =
|
|
73
|
+
'Gate RED — the review verdict is blocked; fix the gate and re-run it before committing.'
|
|
74
|
+
|
|
75
|
+
function report_gate(state: GateState): void {
|
|
76
|
+
if (state === run_review.GATE_GREEN) {
|
|
77
|
+
process.stdout.write(`${GREEN_NOTE}\n`)
|
|
78
|
+
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const log = run_review_steps.read_gate_log()
|
|
83
|
+
|
|
84
|
+
if (log !== undefined) process.stdout.write(`${log}\n`)
|
|
85
|
+
process.stdout.write(`${RED_NOTE}\n`)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function report_timing(timing: ReviewTiming | undefined): void {
|
|
89
|
+
if (timing === undefined) return
|
|
90
|
+
|
|
91
|
+
process.stdout.write(`${run_review.format_timing(timing)}\n`)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function run_join(): Promise<number> {
|
|
95
|
+
const state = await run_review_steps.wait_for_gate_finish()
|
|
96
|
+
const timing = run_review_steps.complete_timing({
|
|
97
|
+
gate_ended_at: gate_ended_at(state === run_review.GATE_GREEN),
|
|
98
|
+
review_ended_at: now_iso(),
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
report_gate(state)
|
|
102
|
+
report_timing(timing)
|
|
103
|
+
|
|
104
|
+
return join_exit_code(state)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
108
|
+
if (argv.length === 0) return await run_start()
|
|
109
|
+
if (argv.length === 1 && argv[0] === JOIN_FLAG) return await run_join()
|
|
110
|
+
|
|
111
|
+
process.stderr.write(`${USAGE}\n`)
|
|
112
|
+
|
|
113
|
+
return FAILURE_EXIT_CODE
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
117
|
+
process.exitCode = await run(argv)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const run_review_cli = {
|
|
121
|
+
JOIN_FLAG,
|
|
122
|
+
USAGE,
|
|
123
|
+
join_exit_code,
|
|
124
|
+
main,
|
|
125
|
+
run,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
129
|
+
|
|
130
|
+
export { run_review_cli }
|