@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,440 @@
|
|
|
1
|
+
import { agent_role_profile, type AgentProfile } from '#scripts/agent/agent-role-profile'
|
|
2
|
+
import { file_map_stamp, type FileMapStamp } from '#scripts/josh/file-map-stamp'
|
|
3
|
+
import { review_checkout, type ReviewCheckout } from './review-checkout'
|
|
4
|
+
|
|
5
|
+
// The text `josh review:brief` prints — the `/code-review` invocation, composed from what the run
|
|
6
|
+
// already knows (joshuafolkken/kit#1241).
|
|
7
|
+
//
|
|
8
|
+
// **Why a command and not a paragraph in `prompts/review.md`.** `/code-review` runs in a forked
|
|
9
|
+
// process and reads none of this repository's documents; the only thing that reaches it is the
|
|
10
|
+
// argument it is invoked with. Measured on joshuafolkken/kit#1240: both rounds re-ran the unit suite
|
|
11
|
+
// `josh gate` had just passed, both fumbled the runner (`npx vitest`, then a retry), and round 2
|
|
12
|
+
// re-read the whole diff — 439 seconds for a seven-file change. joshuafolkken/kit#1219 had already
|
|
13
|
+
// redefined round 2 as a verification pass **in a document the agent never opens**, which is why it
|
|
14
|
+
// cut nothing.
|
|
15
|
+
//
|
|
16
|
+
// **What is mechanical and what is only an instruction.** The round-2 target is mechanical: the
|
|
17
|
+
// paths are computed from a digest comparison and handed over as the scope. The "already verified"
|
|
18
|
+
// block is an instruction — the agent has a shell and can run whatever it likes — so the effect of
|
|
19
|
+
// that half is measured, never assumed.
|
|
20
|
+
|
|
21
|
+
const TEST_COMMAND_LINE =
|
|
22
|
+
'- The unit suite is `pnpm josh test:unit`. Do not reach for `npx vitest`; it is not how this project runs them.'
|
|
23
|
+
|
|
24
|
+
// **The checkout block, and why the target below names a path instead of assuming one**
|
|
25
|
+
// (joshuafolkken/kit#1522). `/code-review` is forked by the harness and inherits the session's
|
|
26
|
+
// working directory, so during a lane run it starts in a tree that holds the previous child's
|
|
27
|
+
// already-merged code. Reading that tree, it finds nothing wrong and says so — and the run reads
|
|
28
|
+
// that silence as a clean review. Neither half of this block is a paragraph a person has to remember
|
|
29
|
+
// to type: the path is generated from `git rev-parse --show-toplevel` in the checkout the run is
|
|
30
|
+
// implementing in, and the nonce is written to a record before it is printed.
|
|
31
|
+
// **The root is interpolated rather than left as a placeholder.** Every other path this brief prints
|
|
32
|
+
// is absolute for one reason — a forked agent resolves a relative path against its own tree — and a
|
|
33
|
+
// literal `<path>` in the line that says *how* to run the commands undoes exactly that: copied
|
|
34
|
+
// verbatim it fails, and the agent falls back to the checkout it inherited, which is the wrong one.
|
|
35
|
+
function checkout_warning(root: string): string {
|
|
36
|
+
return `You do not inherit that working directory. Run every command for this review against it — \`git -C ${root} …\` — and read no file outside it.`
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function attest_line(nonce: string): string {
|
|
40
|
+
return `Attest before you report: run \`pnpm josh review:attest ${nonce}\` from the checkout you actually read. A non-zero exit means it was not the one above — report \`REVIEW TARGET MISMATCH\` and no findings. Never report "no findings" without that command having passed: a review of the wrong tree finds nothing wrong, and the run cannot tell that apart from approval (joshuafolkken/kit#1522).`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// **The rubric is handed over by path, not pasted in** (joshuafolkken/kit#1927). `/code-review` runs
|
|
44
|
+
// in a forked process that reads none of this repository's documents, so the severity tests, the nine
|
|
45
|
+
// categories and the output format never reached it — the review scored the diff on whatever the
|
|
46
|
+
// forked skill happened to carry. The reviewer has file access (it already runs `git -C <root> …` and
|
|
47
|
+
// `pnpm josh review:attest`), so the brief names the rubric's absolute path and requires it be read
|
|
48
|
+
// and applied before anything is reported. Absolute because a forked agent resolves a relative path
|
|
49
|
+
// against the tree it was spawned in, which is the wrong one during a lane run.
|
|
50
|
+
//
|
|
51
|
+
// **The path is the kit package's, not the review checkout's** (joshuafolkken/kit#2402). The rubric
|
|
52
|
+
// ships inside the kit package (`node_modules/@joshuafolkken/kit/prompts/`), not in a consumer's own
|
|
53
|
+
// tree — so deriving it from the review checkout root pointed at a `prompts/` a `docs/`-less consumer
|
|
54
|
+
// never receives, and the review ran without the scoring rules. The caller resolves it against the
|
|
55
|
+
// package directory instead and hands the absolute path in.
|
|
56
|
+
const RUBRIC_RELATIVE_PATH = 'prompts/review-rubric.md'
|
|
57
|
+
|
|
58
|
+
function rubric_line(rubric_path: string): string {
|
|
59
|
+
return `Rubric: read \`${rubric_path}\` first and apply it — it is the severity tests, the round output format, the nine categories and the stop conditions this review is scored against. You do not carry them otherwise, so a review that skips it is scored on the wrong rules.`
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function checkout_block(checkout: ReviewCheckout, nonce: string): string {
|
|
63
|
+
return [
|
|
64
|
+
`Checkout: ${review_checkout.describe_checkout(checkout)}`,
|
|
65
|
+
checkout_warning(checkout.root),
|
|
66
|
+
attest_line(nonce),
|
|
67
|
+
].join('\n')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// `-C <root>` rather than a bare `git diff`, so the command works from whatever directory the
|
|
71
|
+
// forked agent happens to be sitting in rather than only from the right one.
|
|
72
|
+
//
|
|
73
|
+
// **The base is the merge base, not `main` itself** (joshuafolkken/kit#1527). A linked work tree
|
|
74
|
+
// shares the `main` ref with every other lane, so a two-dot `git diff main` run in an unmerged lane
|
|
75
|
+
// lists whatever another lane merged in the meantime — in reverse. This line is a command the forked
|
|
76
|
+
// agent runs, so printing the old spelling would hand it exactly the mixed-in listing the reading
|
|
77
|
+
// itself no longer produces.
|
|
78
|
+
//
|
|
79
|
+
// **The base is resolved here and embedded as a value, never printed as a `$(…)` substitution.** A
|
|
80
|
+
// subshell that fails expands to the empty string, and `git -C <root> diff` with no revision exits 0
|
|
81
|
+
// listing only the *unstaged* working tree — so a `merge-base` that could not answer would silently
|
|
82
|
+
// narrow the review to a fraction of the change and the agent would report "no findings" on code it
|
|
83
|
+
// never read. `git_command.change_base` already degrades to the default branch name instead, which
|
|
84
|
+
// is the previous command and fails loudly rather than open.
|
|
85
|
+
function whole_change_target(root: string, base: string): string {
|
|
86
|
+
const command = `git -C ${root} diff ${base}`
|
|
87
|
+
|
|
88
|
+
return `Target: the whole change — \`${command}\` plus the untracked files beside it.`
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const ROUND_TWO_HEADING =
|
|
92
|
+
'Round 2 — a verification pass over the fix delta, not a second full review.'
|
|
93
|
+
|
|
94
|
+
const ROUND_TWO_QUESTION =
|
|
95
|
+
'Ask whether each first-round finding closed and whether the fix itself introduced a defect. Do not re-read the parts of the diff no fix touched.'
|
|
96
|
+
|
|
97
|
+
function no_snapshot_line(root: string, base: string): string {
|
|
98
|
+
return `No round-1 snapshot was recorded, so the fix delta cannot be named. ${whole_change_target(root, base)}`
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const EMPTY_DELTA_LINE =
|
|
102
|
+
'The fix delta is empty — nothing changed since round 1, so there is nothing for a verification pass to read.'
|
|
103
|
+
|
|
104
|
+
const NOT_VERIFIED_LINE =
|
|
105
|
+
'Not verified: `pnpm josh gate` has not passed on this exact tree. Nothing here claims lint, the type check, the spell check or the unit tests are green.'
|
|
106
|
+
|
|
107
|
+
// Named so the caller and the test agree on the sentence without either restating it: a brief that
|
|
108
|
+
// says the gate passed when it did not is the one failure this whole record exists to prevent.
|
|
109
|
+
//
|
|
110
|
+
// The stamp comes back rather than a boolean so the caller reaches `taken_at` on a value it has
|
|
111
|
+
// already narrowed — a record that does not describe this tree has no timestamp worth printing, and
|
|
112
|
+
// the two answers should not be reachable through the same variable.
|
|
113
|
+
function matching_stamp(
|
|
114
|
+
stamp: FileMapStamp | undefined,
|
|
115
|
+
tree: Record<string, string>,
|
|
116
|
+
): FileMapStamp | undefined {
|
|
117
|
+
if (stamp === undefined || file_map_stamp.changed_since(stamp, tree).length > 0) return undefined
|
|
118
|
+
|
|
119
|
+
return stamp
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function verified_line(taken_at: string): string {
|
|
123
|
+
return `Already verified — do not re-run these:\n- lint, the type check, the spell check and the unit tests all passed on this exact tree at ${taken_at} (\`pnpm josh gate\`).`
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// **The in-flight sentence claims no result, and that is the point** (joshuafolkken/kit#1242). The
|
|
127
|
+
// gate and this review are started together, so the honest thing to say is that a gate is running —
|
|
128
|
+
// not that it passed. What it forbids is re-running the unit suite, which is wasted whether the gate
|
|
129
|
+
// ends green or red, and it names who joins the result so the reader knows the check is not being
|
|
130
|
+
// skipped.
|
|
131
|
+
function in_flight_line(taken_at: string): string {
|
|
132
|
+
return `Running now — do not re-run these:\n- \`pnpm josh gate\` started against this exact tree at ${taken_at} and has not recorded a result. Lint, the type check, the spell check and the unit tests are being run beside this review; the run joins that result before it commits, and it is that result — never one you produce here — that gates the merge. Nothing here claims any of them are green.`
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// **The marker asserts a live process, so matching the tree is not enough.** `josh gate` clears it in
|
|
136
|
+
// a `finally`, and a `finally` does not run when the gate is killed — Ctrl-C, Stop, SIGTERM — so an
|
|
137
|
+
// interrupted gate leaves the file on disk with the tree it was reading still intact. Believed on the
|
|
138
|
+
// digests alone it would say a gate is running for as long as nobody edits that tree, about a process
|
|
139
|
+
// that no longer exists: exactly the state the record must never describe.
|
|
140
|
+
//
|
|
141
|
+
// **The written pid alone did not separate the two** (joshuafolkken/kit#1245). It names whatever holds
|
|
142
|
+
// that number now, so once the operating system reissued it the abandoned marker passed the liveness
|
|
143
|
+
// probe again and this line went back to printing `Running now` about nothing — the same untrue
|
|
144
|
+
// sentence, reached by a longer route. The record therefore carries the writing process's start time
|
|
145
|
+
// beside its pid, and `is_writer_running` requires the pair. A marker carrying neither, or one whose
|
|
146
|
+
// platform cannot report a start time, is read as not running and falls back to `Not verified`.
|
|
147
|
+
function live_marker(
|
|
148
|
+
stamp: FileMapStamp | undefined,
|
|
149
|
+
tree: Record<string, string>,
|
|
150
|
+
): FileMapStamp | undefined {
|
|
151
|
+
const matched = matching_stamp(stamp, tree)
|
|
152
|
+
|
|
153
|
+
if (!file_map_stamp.is_writer_running(matched)) return undefined
|
|
154
|
+
|
|
155
|
+
return matched
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// **Matching digests are not enough for the green claim** (joshuafolkken/kit#1537). The map covers
|
|
159
|
+
// the paths the change makes changed, so a merge of the default branch that touches nothing the
|
|
160
|
+
// branch touches leaves every digest identical while the tree gains code the gate never read —
|
|
161
|
+
// and the brief would tell the reviewer that lint, the type check, the spell check and the unit tests
|
|
162
|
+
// passed on "this exact tree". The gate already records the commit it measured against, and
|
|
163
|
+
// `gate-skip.ts` already refuses reuse on it; this is the same refusal for the same record.
|
|
164
|
+
//
|
|
165
|
+
// **The in-flight marker is deliberately left alone.** It carries no base, and it claims no result:
|
|
166
|
+
// the worst a moved base does there is report that a gate is running, which is true.
|
|
167
|
+
function green_stamp(
|
|
168
|
+
stamp: FileMapStamp | undefined,
|
|
169
|
+
tree: Record<string, string>,
|
|
170
|
+
base: string,
|
|
171
|
+
): FileMapStamp | undefined {
|
|
172
|
+
const matched = matching_stamp(stamp, tree)
|
|
173
|
+
|
|
174
|
+
if (matched === undefined || !file_map_stamp.describes_base(matched, base)) return undefined
|
|
175
|
+
|
|
176
|
+
return matched
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Green first: a matching gate stamp is a proven result, and a gate running beside it can only be a
|
|
180
|
+
// second one over the same unverified tree.
|
|
181
|
+
function gate_line(
|
|
182
|
+
stamps: { gate: FileMapStamp | undefined; in_flight: FileMapStamp | undefined },
|
|
183
|
+
tree: Record<string, string>,
|
|
184
|
+
base: string,
|
|
185
|
+
): string {
|
|
186
|
+
const green = green_stamp(stamps.gate, tree, base)
|
|
187
|
+
|
|
188
|
+
if (green !== undefined) return verified_line(green.taken_at)
|
|
189
|
+
|
|
190
|
+
const running = live_marker(stamps.in_flight, tree)
|
|
191
|
+
|
|
192
|
+
if (running !== undefined) return in_flight_line(running.taken_at)
|
|
193
|
+
|
|
194
|
+
return NOT_VERIFIED_LINE
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Absolute, for the same reason the round-1 target carries `-C`: git prints repository-root-relative
|
|
198
|
+
// paths, and a forked agent sitting in another checkout resolves them against that one — where the
|
|
199
|
+
// same relative path names a different file, or none.
|
|
200
|
+
function format_paths(root: string, paths: ReadonlyArray<string>): string {
|
|
201
|
+
return paths.map((relative) => ` ${root}/${relative}`).join('\n')
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// **An empty target has two readings, and only one of them is "nothing changed"**
|
|
205
|
+
// (joshuafolkken/kit#1537). Since the delta is intersected with the change, round 1's fixes can be
|
|
206
|
+
// real and still leave no target — a fix that reverts a file to its base content takes that path out
|
|
207
|
+
// of `git diff` altogether. Printing "nothing changed since round 1" there would contradict the
|
|
208
|
+
// `Not in this change` list directly below it, which is the self-disagreement this whole change
|
|
209
|
+
// exists to remove.
|
|
210
|
+
const NOTHING_LEFT_LINE =
|
|
211
|
+
'The fix delta is empty once reconciled against this change — every path the comparison offered has left it, so there is nothing here for a verification pass to read.'
|
|
212
|
+
|
|
213
|
+
function round_two_target(root: string, scope: RoundTwoScope): string {
|
|
214
|
+
if (scope.target.length > 0) {
|
|
215
|
+
return `Target: only these files, which are the ones round 1's fixes changed:\n${format_paths(root, scope.target)}`
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return scope.dropped.length > 0 ? NOTHING_LEFT_LINE : EMPTY_DELTA_LINE
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// **What round 2 is sent to read, reconciled against the change it is meant to cover**
|
|
222
|
+
// (joshuafolkken/kit#1537). The delta alone is not that list. It is the difference between two file
|
|
223
|
+
// maps, each one a diff against `change_base` **as it stood when that map was taken** — and nothing
|
|
224
|
+
// used to record which commit that was. Move the base between the rounds, which is exactly what a
|
|
225
|
+
// resumed run's merge of the default branch does, and the two maps stop covering the same set of
|
|
226
|
+
// paths: their difference then names files the branch never touched and misses files it did.
|
|
227
|
+
//
|
|
228
|
+
// The three fields are the whole reconciliation, and the run needs all three rather than the first:
|
|
229
|
+
// `target` is what to read, `dropped` is what the comparison offered that this change does not
|
|
230
|
+
// contain, and `carried` counts what this change contains that round 1 already read. A brief that
|
|
231
|
+
// printed `target` alone would still be silently disagreeing with `git diff` — the failure the Issue
|
|
232
|
+
// was filed on — it would just be disagreeing in a smaller way.
|
|
233
|
+
//
|
|
234
|
+
// **`recorded_at` is present exactly when the round is narrow.** It is the timestamp of the record the
|
|
235
|
+
// delta was measured from, and its absence is what says the round was widened — so the block below
|
|
236
|
+
// branches on this one decision rather than making a second one of its own.
|
|
237
|
+
interface RoundTwoScope {
|
|
238
|
+
recorded_at: string | undefined
|
|
239
|
+
target: ReadonlyArray<string>
|
|
240
|
+
dropped: ReadonlyArray<string>
|
|
241
|
+
carried: ReadonlyArray<string>
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function sorted_names(names: ReadonlyArray<string>): ReadonlyArray<string> {
|
|
245
|
+
return [...names].toSorted((left, right) => left.localeCompare(right))
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// A record that cannot be compared widens the round to the whole change rather than narrowing it, so
|
|
249
|
+
// every path the change touches is a target. This is the same direction joshuafolkken/kit#1241 chose
|
|
250
|
+
// for a missing record, extended to a record that is present and unusable.
|
|
251
|
+
function whole_change_scope(tree: Record<string, string>): RoundTwoScope {
|
|
252
|
+
return {
|
|
253
|
+
recorded_at: undefined,
|
|
254
|
+
target: sorted_names(Object.keys(tree)),
|
|
255
|
+
dropped: [],
|
|
256
|
+
carried: [],
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// `tree`'s keys are this change's paths — `git diff <base>` plus the untracked files beside it — so
|
|
261
|
+
// intersecting against them is what keeps a path the change does not contain out of the target.
|
|
262
|
+
function delta_scope(
|
|
263
|
+
delta: ReadonlyArray<string>,
|
|
264
|
+
tree: Record<string, string>,
|
|
265
|
+
recorded_at: string,
|
|
266
|
+
): RoundTwoScope {
|
|
267
|
+
const target = delta.filter((name) => Object.hasOwn(tree, name))
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
recorded_at,
|
|
271
|
+
target,
|
|
272
|
+
dropped: delta.filter((name) => !Object.hasOwn(tree, name)),
|
|
273
|
+
carried: sorted_names(Object.keys(tree).filter((name) => !target.includes(name))),
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// A type predicate rather than two spellings of the same condition: the scope and the printed block
|
|
278
|
+
// must never disagree about whether the record was usable.
|
|
279
|
+
function is_comparable(snapshot: FileMapStamp | undefined, base: string): snapshot is FileMapStamp {
|
|
280
|
+
return snapshot !== undefined && file_map_stamp.describes_base(snapshot, base)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function round_two_scope(
|
|
284
|
+
snapshot: FileMapStamp | undefined,
|
|
285
|
+
tree: Record<string, string>,
|
|
286
|
+
base: string,
|
|
287
|
+
): RoundTwoScope {
|
|
288
|
+
if (!is_comparable(snapshot, base)) return whole_change_scope(tree)
|
|
289
|
+
|
|
290
|
+
return delta_scope(file_map_stamp.changed_since(snapshot, tree), tree, snapshot.taken_at)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const BASE_MOVED_PREFIX = 'The change base moved since round 1 was recorded'
|
|
294
|
+
|
|
295
|
+
function base_moved_line(snapshot: FileMapStamp, root: string, base: string): string {
|
|
296
|
+
const recorded = snapshot.base ?? 'a commit it did not record'
|
|
297
|
+
|
|
298
|
+
return `${BASE_MOVED_PREFIX} — round 1 measured this change against ${recorded}, this round measures it against ${base}. The two file maps therefore cover different sets of files, and their difference is not the fix delta. ${whole_change_target(root, base)}`
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function widened_line(snapshot: FileMapStamp | undefined, root: string, base: string): string {
|
|
302
|
+
if (snapshot === undefined) return no_snapshot_line(root, base)
|
|
303
|
+
|
|
304
|
+
return base_moved_line(snapshot, root, base)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function dropped_line(root: string, dropped: ReadonlyArray<string>): string {
|
|
308
|
+
return `Not in this change, so not a target here — the comparison offered them and \`git diff\` does not list them:\n${format_paths(root, dropped)}`
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function carried_line(root: string, base: string, count: number): string {
|
|
312
|
+
return `${String(count)} further file(s) this change touches are byte-identical to round 1 and were read there, so they are deliberately out of scope. Reconcile before you report: \`git -C ${root} diff --name-only ${base}\` plus the untracked files beside it is this change, and every path in it is either a target above or one of those.`
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function reconciliation(root: string, base: string, scope: RoundTwoScope): ReadonlyArray<string> {
|
|
316
|
+
return [
|
|
317
|
+
...(scope.dropped.length > 0 ? [dropped_line(root, scope.dropped)] : []),
|
|
318
|
+
...(scope.carried.length > 0 ? [carried_line(root, base, scope.carried.length)] : []),
|
|
319
|
+
]
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// The snapshot's own timestamp, printed rather than assumed. Since joshuafolkken/kit#1441 the record
|
|
323
|
+
// is round 1's own — written once per run, and kept by a later round-1 invocation rather than retaken
|
|
324
|
+
// against the fixed tree — so this line says how far back the target below is measured from. A record
|
|
325
|
+
// left behind by a run that never reached `josh followup` makes the target wider, and its timestamp is
|
|
326
|
+
// the only thing that shows that from here.
|
|
327
|
+
function narrow_block(
|
|
328
|
+
recorded_at: string,
|
|
329
|
+
scope: RoundTwoScope,
|
|
330
|
+
root: string,
|
|
331
|
+
base: string,
|
|
332
|
+
): string {
|
|
333
|
+
return [
|
|
334
|
+
ROUND_TWO_HEADING,
|
|
335
|
+
`Round 1 was recorded at ${recorded_at}.`,
|
|
336
|
+
round_two_target(root, scope),
|
|
337
|
+
...reconciliation(root, base, scope),
|
|
338
|
+
ROUND_TWO_QUESTION,
|
|
339
|
+
].join('\n')
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// `undefined` for the snapshot and "the whole change" as the answer: a missing record must widen the
|
|
343
|
+
// review, never narrow it. A brief that silently reviewed nothing would be the cheapest possible run
|
|
344
|
+
// and the most dangerous.
|
|
345
|
+
function round_two_block(
|
|
346
|
+
snapshot: FileMapStamp | undefined,
|
|
347
|
+
tree: Record<string, string>,
|
|
348
|
+
root: string,
|
|
349
|
+
base: string,
|
|
350
|
+
): string {
|
|
351
|
+
const scope = round_two_scope(snapshot, tree, base)
|
|
352
|
+
|
|
353
|
+
if (scope.recorded_at === undefined) {
|
|
354
|
+
return `${ROUND_TWO_HEADING}\n${widened_line(snapshot, root, base)}`
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return narrow_block(scope.recorded_at, scope, root, base)
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
interface BriefStamps {
|
|
361
|
+
gate: FileMapStamp | undefined
|
|
362
|
+
in_flight: FileMapStamp | undefined
|
|
363
|
+
round_one: FileMapStamp | undefined
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
interface BriefInput {
|
|
367
|
+
level: string
|
|
368
|
+
profile?: AgentProfile
|
|
369
|
+
round: number
|
|
370
|
+
tree: Record<string, string>
|
|
371
|
+
stamps: BriefStamps
|
|
372
|
+
checkout: ReviewCheckout
|
|
373
|
+
nonce: string
|
|
374
|
+
// The commit the change is measured against, resolved by the caller so the printed target carries
|
|
375
|
+
// a value rather than a subshell that can fail open (joshuafolkken/kit#1527).
|
|
376
|
+
base: string
|
|
377
|
+
// The rubric's absolute path, resolved by the caller against the kit package rather than the review
|
|
378
|
+
// checkout, so it resolves in a consumer that ships no `prompts/` of its own (joshuafolkken/kit#2402).
|
|
379
|
+
rubric_path: string
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const SECOND_ROUND = 2
|
|
383
|
+
|
|
384
|
+
function target_block(input: BriefInput): string {
|
|
385
|
+
if (input.round < SECOND_ROUND) return whole_change_target(input.checkout.root, input.base)
|
|
386
|
+
|
|
387
|
+
return round_two_block(input.stamps.round_one, input.tree, input.checkout.root, input.base)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// The level alone on the first line, because the level-only mode's contract — a caller reading the
|
|
391
|
+
// answer with `$(...)` — is the one thing a brief must not break.
|
|
392
|
+
function compose(input: BriefInput): string {
|
|
393
|
+
const profile = input.profile ?? agent_role_profile.DEFAULT_PROFILES.reviewer
|
|
394
|
+
|
|
395
|
+
return [
|
|
396
|
+
input.level,
|
|
397
|
+
'',
|
|
398
|
+
`Agent profile: ${agent_role_profile.describe(profile)}`,
|
|
399
|
+
'',
|
|
400
|
+
rubric_line(input.rubric_path),
|
|
401
|
+
'',
|
|
402
|
+
checkout_block(input.checkout, input.nonce),
|
|
403
|
+
'',
|
|
404
|
+
gate_line(input.stamps, input.tree, input.base),
|
|
405
|
+
TEST_COMMAND_LINE,
|
|
406
|
+
'',
|
|
407
|
+
target_block(input),
|
|
408
|
+
].join('\n')
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const review_brief = {
|
|
412
|
+
attest_line,
|
|
413
|
+
BASE_MOVED_PREFIX,
|
|
414
|
+
base_moved_line,
|
|
415
|
+
carried_line,
|
|
416
|
+
checkout_block,
|
|
417
|
+
checkout_warning,
|
|
418
|
+
compose,
|
|
419
|
+
dropped_line,
|
|
420
|
+
EMPTY_DELTA_LINE,
|
|
421
|
+
gate_line,
|
|
422
|
+
green_stamp,
|
|
423
|
+
in_flight_line,
|
|
424
|
+
live_marker,
|
|
425
|
+
matching_stamp,
|
|
426
|
+
no_snapshot_line,
|
|
427
|
+
NOTHING_LEFT_LINE,
|
|
428
|
+
NOT_VERIFIED_LINE,
|
|
429
|
+
rubric_line,
|
|
430
|
+
RUBRIC_RELATIVE_PATH,
|
|
431
|
+
ROUND_TWO_HEADING,
|
|
432
|
+
ROUND_TWO_QUESTION,
|
|
433
|
+
round_two_block,
|
|
434
|
+
round_two_scope,
|
|
435
|
+
SECOND_ROUND,
|
|
436
|
+
TEST_COMMAND_LINE,
|
|
437
|
+
whole_change_target,
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
export { review_brief }
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { git_command } from '#scripts/git/git-command'
|
|
2
|
+
|
|
3
|
+
// The checkout `josh review:brief` is describing — the one thing the forked `/code-review` agent
|
|
4
|
+
// cannot work out for itself (joshuafolkken/kit#1522).
|
|
5
|
+
//
|
|
6
|
+
// **`/code-review` runs in a fork that inherits the *session's* working directory, not the run's.**
|
|
7
|
+
// Where the run implementing the change is a lane — a linked work tree under `.kit-lanes/` — that is
|
|
8
|
+
// a different tree entirely, so the review reads the session's checkout: usually the default branch,
|
|
9
|
+
// with the previous child already merged into it. Nothing there is wrong, so the review comes back
|
|
10
|
+
// with no findings, and **the failure arrives as approval**. Naming the checkout is what removes the
|
|
11
|
+
// guess, and it is generated here rather than typed into a brief by hand: an absolute path a person
|
|
12
|
+
// has to remember to pass reopens the hole the first time it is forgotten, and reopens it silently.
|
|
13
|
+
//
|
|
14
|
+
// **The root is asked of git, never read from `process.cwd()`** — the same reading `review-tree.ts`
|
|
15
|
+
// makes, and for the same reason: run from a subdirectory, `cwd()` names a directory that is not the
|
|
16
|
+
// repository, and every path built on it resolves to nothing.
|
|
17
|
+
|
|
18
|
+
interface ReviewCheckout {
|
|
19
|
+
root: string
|
|
20
|
+
branch: string
|
|
21
|
+
head: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Three git spawns that do not depend on each other, so they are issued together rather than one
|
|
25
|
+
// after another: the brief is printed in front of a review the run is waiting on.
|
|
26
|
+
async function read_checkout(): Promise<ReviewCheckout> {
|
|
27
|
+
const [root, branch, head] = await Promise.all([
|
|
28
|
+
git_command.repository_root(),
|
|
29
|
+
git_command.branch(),
|
|
30
|
+
git_command.head_commit(),
|
|
31
|
+
])
|
|
32
|
+
|
|
33
|
+
return { root, branch, head }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// **All three, not the root alone.** A second work tree of the same repository has a different root,
|
|
37
|
+
// which the root test catches on its own; a `git switch` inside the right tree does not, and that is
|
|
38
|
+
// the case `backlogrun-lanes.md` → "Lanes" warns about, since a lane's branch is what its commit lands on.
|
|
39
|
+
// The head is the third: a tree that moved between the brief and the review is not the tree the
|
|
40
|
+
// brief described.
|
|
41
|
+
function is_same_checkout(expected: ReviewCheckout, actual: ReviewCheckout): boolean {
|
|
42
|
+
return (
|
|
43
|
+
expected.root === actual.root &&
|
|
44
|
+
expected.branch === actual.branch &&
|
|
45
|
+
expected.head === actual.head
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function describe_checkout(checkout: ReviewCheckout): string {
|
|
50
|
+
return `${checkout.root} (branch ${checkout.branch}, HEAD ${checkout.head})`
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const review_checkout = { describe_checkout, is_same_checkout, read_checkout }
|
|
54
|
+
|
|
55
|
+
export type { ReviewCheckout }
|
|
56
|
+
export { review_checkout }
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// The review-finding line's grammar, its category vocabulary and the aggregation over it — the single
|
|
2
|
+
// place all three are defined (joshuafolkken/kit#2325). A `/code-review` round's findings evaporated
|
|
3
|
+
// the moment they were fixed, so no one could say which category recurred. They now land in the same
|
|
4
|
+
// append-only ledger the observation lines use (`docs/observations.md`), under a distinct `- rf:`
|
|
5
|
+
// prefix so `observation-ledger-line.ts`'s `- k:` grammar never treats them as its own — one ledger
|
|
6
|
+
// file, one flush path, a second line *type* rather than a second ledger.
|
|
7
|
+
|
|
8
|
+
const FINDING_PREFIX = '- rf:'
|
|
9
|
+
const FIELD_SEPARATOR = ' | '
|
|
10
|
+
const FIELD_COUNT = 5
|
|
11
|
+
|
|
12
|
+
// The nine review-rubric categories, as slugs (`prompts/review-rubric.md` → "Review categories"). A
|
|
13
|
+
// finding's category must be one of these so the aggregate stays countable rather than free text.
|
|
14
|
+
const CATEGORIES = [
|
|
15
|
+
'bug-risks',
|
|
16
|
+
'security',
|
|
17
|
+
'performance',
|
|
18
|
+
'project-conventions',
|
|
19
|
+
'i18n',
|
|
20
|
+
'tests',
|
|
21
|
+
'comments',
|
|
22
|
+
'assumptions',
|
|
23
|
+
'confidence',
|
|
24
|
+
] as const
|
|
25
|
+
|
|
26
|
+
const SEVERITIES = ['high', 'medium', 'low'] as const
|
|
27
|
+
|
|
28
|
+
// The sentinel a zero-finding round writes, so "a round ran and found nothing" is a recorded line
|
|
29
|
+
// rather than an absent one — the count's denominator survives.
|
|
30
|
+
const NONE = 'none'
|
|
31
|
+
const NO_FILE = '-'
|
|
32
|
+
|
|
33
|
+
type Category = (typeof CATEGORIES)[number]
|
|
34
|
+
type Severity = (typeof SEVERITIES)[number]
|
|
35
|
+
|
|
36
|
+
interface Finding {
|
|
37
|
+
category: Category
|
|
38
|
+
severity: Severity
|
|
39
|
+
file: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface CategoryCount {
|
|
43
|
+
category: string
|
|
44
|
+
count: number
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function is_category(value: string): value is Category {
|
|
48
|
+
return (CATEGORIES as ReadonlyArray<string>).includes(value)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function is_severity(value: string): value is Severity {
|
|
52
|
+
return (SEVERITIES as ReadonlyArray<string>).includes(value)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// A file field is valid only when it is non-empty and carries no field separator — a ` | ` inside it
|
|
56
|
+
// would split into an extra field the reader counts as malformed and drops from the tally, so the
|
|
57
|
+
// writer refuses it here where the separator is defined rather than letting it ride into the ledger.
|
|
58
|
+
function is_valid_file(file: string): boolean {
|
|
59
|
+
return file.length > 0 && !file.includes(FIELD_SEPARATOR)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function issue_field(issue: number): string {
|
|
63
|
+
return `#${String(issue)}`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function line_of(fields: ReadonlyArray<string>): string {
|
|
67
|
+
return `${FINDING_PREFIX}${fields.join(FIELD_SEPARATOR)}`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function finding_line(finding: Finding, date: string, issue: number): string {
|
|
71
|
+
return line_of([finding.category, finding.severity, finding.file, date, issue_field(issue)])
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// **A zero-finding round records `none`, not nothing.** Reading its absence as "no findings" would
|
|
75
|
+
// merge the round that found nothing with the round nobody recorded, which is the exact confusion the
|
|
76
|
+
// ledger exists to end.
|
|
77
|
+
function zero_round_line(date: string, issue: number): string {
|
|
78
|
+
return line_of([NONE, NONE, NO_FILE, date, issue_field(issue)])
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function is_finding_line(line: string): boolean {
|
|
82
|
+
return line.trimStart().startsWith(FINDING_PREFIX)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function category_of(line: string): string | undefined {
|
|
86
|
+
const fields = line.trimStart().slice(FINDING_PREFIX.length).split(FIELD_SEPARATOR)
|
|
87
|
+
|
|
88
|
+
return fields.length === FIELD_COUNT ? fields[0] : undefined
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function increment(counts: Map<string, number>, category: string): void {
|
|
92
|
+
counts.set(category, (counts.get(category) ?? 0) + 1)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// The category a line contributes to the tally, or `undefined` for a non-finding line and for the
|
|
96
|
+
// `none` zero-round sentinel — which is a marker, not a category, and counted by `zero_round_count`.
|
|
97
|
+
function finding_category(line: string): string | undefined {
|
|
98
|
+
if (!is_finding_line(line)) return undefined
|
|
99
|
+
|
|
100
|
+
const category = category_of(line)
|
|
101
|
+
|
|
102
|
+
return category === NONE ? undefined : category
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function tally(content: string): Map<string, number> {
|
|
106
|
+
const counts = new Map<string, number>()
|
|
107
|
+
|
|
108
|
+
for (const line of content.split('\n')) {
|
|
109
|
+
const category = finding_category(line)
|
|
110
|
+
|
|
111
|
+
if (category !== undefined) increment(counts, category)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return counts
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Every real finding's category paired with its count, most frequent first, ties broken by name.
|
|
118
|
+
function category_counts(content: string): ReadonlyArray<CategoryCount> {
|
|
119
|
+
return [...tally(content)]
|
|
120
|
+
.map(([category, count]) => ({ category, count }))
|
|
121
|
+
.toSorted(
|
|
122
|
+
(left, right) => right.count - left.count || left.category.localeCompare(right.category),
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// The number of rounds that recorded zero findings — the denominator half that a bare category count
|
|
127
|
+
// cannot show.
|
|
128
|
+
function zero_round_count(content: string): number {
|
|
129
|
+
return content.split('\n').filter((line) => is_finding_line(line) && category_of(line) === NONE)
|
|
130
|
+
.length
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The issue a finding line is keyed to — its fifth field, the `#<N>` token — or `undefined` for a
|
|
134
|
+
// non-finding or malformed line. The record check reads this to ask whether a given issue's round was
|
|
135
|
+
// recorded at all (joshuafolkken/kit#2343).
|
|
136
|
+
function issue_of(line: string): string | undefined {
|
|
137
|
+
const fields = line.trimStart().slice(FINDING_PREFIX.length).split(FIELD_SEPARATOR)
|
|
138
|
+
|
|
139
|
+
return fields.length === FIELD_COUNT ? fields[FIELD_COUNT - 1] : undefined
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// **A `none` zero-round line counts as recorded, exactly like a real finding line does.** The gate
|
|
143
|
+
// asks whether the round was recorded, not whether it found anything — reading the issue field, which
|
|
144
|
+
// a zero-finding line carries too, is what keeps a clean round's single line from reading as "nobody
|
|
145
|
+
// recorded this" (joshuafolkken/kit#2343).
|
|
146
|
+
function has_issue_record(content: string, issue: number): boolean {
|
|
147
|
+
const target = issue_field(issue)
|
|
148
|
+
|
|
149
|
+
return content.split('\n').some((line) => is_finding_line(line) && issue_of(line) === target)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const review_finding_ledger = {
|
|
153
|
+
CATEGORIES,
|
|
154
|
+
SEVERITIES,
|
|
155
|
+
category_counts,
|
|
156
|
+
finding_line,
|
|
157
|
+
has_issue_record,
|
|
158
|
+
is_category,
|
|
159
|
+
is_finding_line,
|
|
160
|
+
is_severity,
|
|
161
|
+
is_valid_file,
|
|
162
|
+
zero_round_count,
|
|
163
|
+
zero_round_line,
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export type { CategoryCount, Finding }
|
|
167
|
+
export { review_finding_ledger }
|