@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,100 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
|
|
3
|
+
// `josh cases <path...>` (joshuafolkken/kit#2246): read the changed paths and answer which I/O
|
|
4
|
+
// boundaries the code crosses — network, process start, filesystem — then name the abnormal cases
|
|
5
|
+
// that boundary always owes. The unit suite blocks network by construction
|
|
6
|
+
// (`scripts/test/test-network-guard.ts`), so a boundary's abnormal cases never run there; this makes
|
|
7
|
+
// the declaration side name them instead, read off the diff rather than off judgement.
|
|
8
|
+
// `prompts/collaboration-workflow/report-format.md` is the single source of where the answer goes —
|
|
9
|
+
// the second tier of the case-based test declaration ("if it breaks").
|
|
10
|
+
|
|
11
|
+
type Boundary = 'network' | 'process' | 'fs' | 'time'
|
|
12
|
+
const NONE = 'none'
|
|
13
|
+
|
|
14
|
+
interface BoundaryDefinition {
|
|
15
|
+
boundary: Boundary
|
|
16
|
+
// A source pattern that marks the boundary being crossed — an import of, or a call into, it.
|
|
17
|
+
pattern: RegExp
|
|
18
|
+
// The abnormal cases this boundary always owes, so they land in the second tier.
|
|
19
|
+
cases: ReadonlyArray<string>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const BOUNDARIES: ReadonlyArray<BoundaryDefinition> = [
|
|
23
|
+
{
|
|
24
|
+
boundary: 'network',
|
|
25
|
+
// Keyed on a networking API, never a bare URL: a URL in a comment, a doc link or a
|
|
26
|
+
// string constant crosses no boundary at test time, so matching `https://` text alone
|
|
27
|
+
// would fire `network` on every markdown edit and defeat the oracle.
|
|
28
|
+
pattern: /\b(?:fetch|axios|undici|node:https?|XMLHttpRequest)\b/u,
|
|
29
|
+
cases: ['非200', 'タイムアウト', '接続断', '空レスポンス', '不正JSON', 'レート制限'],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
boundary: 'process',
|
|
33
|
+
// The module name and the `*Sync` forms are unambiguous; the short verbs (`exec`, `spawn`,
|
|
34
|
+
// `execFile`) require a call paren, so prose like "exec the plan" or a local named `exec`
|
|
35
|
+
// no longer fires the boundary.
|
|
36
|
+
pattern:
|
|
37
|
+
/\b(?:child_process|execSync|execFileSync|spawnSync)\b|\b(?:exec|execFile|spawn)\s*\(/u,
|
|
38
|
+
cases: ['非ゼロ終了', 'タイムアウト', '標準エラー出力', '実行ファイル不在'],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
boundary: 'fs',
|
|
42
|
+
// Same rule as process: the module names and `*Sync` forms are unambiguous, and the short
|
|
43
|
+
// verbs (`readFile`, `writeFile`, `mkdir`, `unlink`, `readdir`, `rm`) require a call paren,
|
|
44
|
+
// so prose like "rm the old files" no longer fires the boundary.
|
|
45
|
+
pattern:
|
|
46
|
+
/\b(?:node:fs|fs\/promises|readFileSync|writeFileSync)\b|\b(?:readFile|writeFile|mkdir|unlink|readdir|rm)\s*\(/u,
|
|
47
|
+
cases: ['ファイル不在', '権限エラー', '空ファイル', '不正な内容', '並行書き込み'],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
boundary: 'time',
|
|
51
|
+
// The absence boundary: a change that coordinates over time — timers, schedules, retries,
|
|
52
|
+
// heartbeats — owes the cases where the awaited thing never happens, which no diff of an I/O
|
|
53
|
+
// call can surface (joshuafolkken/kit#2356). Same over-firing discipline as process and fs: the
|
|
54
|
+
// verbs (`setInterval`, `schedule`, `retry`) require a call paren so prose like "schedule the
|
|
55
|
+
// release" no longer fires, while the domain nouns (`cron`, `heartbeat`, `watchdog`, `liveness`)
|
|
56
|
+
// are unambiguous enough in source to match bare.
|
|
57
|
+
pattern:
|
|
58
|
+
/\b(?:setInterval|setTimeout|setImmediate|schedule|reschedule|retry)\s*\(|\b(?:cron|crontab|heartbeat|watchdog|liveness)\b/u,
|
|
59
|
+
cases: ['期待した事象が到来しない', '期限超過', '重複発火', '再試行が尽きる'],
|
|
60
|
+
},
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
// A path that cannot be read counts as no boundary rather than an error: a deleted or renamed path in
|
|
64
|
+
// a diff is still passed in, and the answer for it is simply "nothing crossed here".
|
|
65
|
+
function read_file(path: string): string {
|
|
66
|
+
try {
|
|
67
|
+
return readFileSync(path, 'utf8')
|
|
68
|
+
} catch {
|
|
69
|
+
return ''
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// The distinct boundaries any of the paths cross. The content is joined and each boundary is tested
|
|
74
|
+
// once, so the same boundary is never reported twice however many paths cross it.
|
|
75
|
+
function boundaries_in(paths: ReadonlyArray<string>): ReadonlyArray<Boundary> {
|
|
76
|
+
const content = paths.map((path) => read_file(path)).join('\n')
|
|
77
|
+
|
|
78
|
+
return BOUNDARIES.filter((definition) => definition.pattern.test(content)).map(
|
|
79
|
+
(definition) => definition.boundary,
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// The abnormal cases owed by the given boundaries, in the fixed boundary order.
|
|
84
|
+
function cases_for(boundaries: ReadonlyArray<Boundary>): ReadonlyArray<string> {
|
|
85
|
+
return BOUNDARIES.filter((definition) => boundaries.includes(definition.boundary)).flatMap(
|
|
86
|
+
(definition) => definition.cases,
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// The fixed verdict vocabulary the command can print — the three boundary tokens and `none`. The
|
|
91
|
+
// decision-oracle test asserts its registered vocabulary equals this.
|
|
92
|
+
const VOCABULARY: ReadonlyArray<string> = [
|
|
93
|
+
...BOUNDARIES.map((definition) => definition.boundary),
|
|
94
|
+
NONE,
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
const cases = { BOUNDARIES, NONE, VOCABULARY, boundaries_in, cases_for }
|
|
98
|
+
|
|
99
|
+
export type { Boundary }
|
|
100
|
+
export { cases }
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Where a skill lives and how its frontmatter is read (joshuafolkken/kit#854, single-sourced for
|
|
2
|
+
// joshuafolkken/kit#1151).
|
|
3
|
+
//
|
|
4
|
+
// The suites that assert a skill ships correctly and the `josh cost` resident breakdown that sizes
|
|
5
|
+
// the skills index both need the same two facts: which directory holds the skills, and what the
|
|
6
|
+
// entry file's frontmatter says. This module is where those live, so the pattern is not written
|
|
7
|
+
// twice — `skill-fixture.ts` is a test fixture and is excluded from the published package, so
|
|
8
|
+
// shipped code cannot read it.
|
|
9
|
+
|
|
10
|
+
const SKILL_ROOT = '.claude/skills'
|
|
11
|
+
const SKILL_ENTRY_FILE = 'SKILL.md'
|
|
12
|
+
const FRONTMATTER_PATTERN = /^---\n([\S\s]*?)\n---\n/u
|
|
13
|
+
const DESCRIPTION_PATTERN = /^description: (.+)$/mu
|
|
14
|
+
|
|
15
|
+
function has_frontmatter(content: string): boolean {
|
|
16
|
+
return FRONTMATTER_PATTERN.test(content)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function frontmatter_of(content: string): string {
|
|
20
|
+
return FRONTMATTER_PATTERN.exec(content)?.[1] ?? ''
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// The description is the trigger for every agent that discovers a skill by reading descriptions
|
|
24
|
+
// rather than by being told a path, so it is read out rather than merely asserted present.
|
|
25
|
+
function description_of(content: string): string {
|
|
26
|
+
return DESCRIPTION_PATTERN.exec(frontmatter_of(content))?.[1] ?? ''
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const skill_meta = {
|
|
30
|
+
SKILL_ROOT,
|
|
31
|
+
SKILL_ENTRY_FILE,
|
|
32
|
+
has_frontmatter,
|
|
33
|
+
frontmatter_of,
|
|
34
|
+
description_of,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { skill_meta }
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Whether a path names a workflow file kit writes into a consumer. A leaf module on purpose: both
|
|
2
|
+
// the pin injection and the managed-marker library need this predicate, and the marker library is
|
|
3
|
+
// published (`@joshuafolkken/kit/managed-marker`), so reaching it through the pin logic would inline
|
|
4
|
+
// sync's whole `readdirSync`/`writeFileSync` graph into a bundle that only needs a regex.
|
|
5
|
+
//
|
|
6
|
+
// Matches a consumer workflow destination, absolute or repo-relative, on either separator.
|
|
7
|
+
const WORKFLOW_DESTINATION_PATTERN = /(?:^|[/\\])\.github[/\\]workflows[/\\][^/\\]+\.ya?ml$/u
|
|
8
|
+
|
|
9
|
+
function is_workflow_destination(destination: string): boolean {
|
|
10
|
+
return WORKFLOW_DESTINATION_PATTERN.test(destination)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { is_workflow_destination }
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Grouping fingerprints into clones, and classifying how far each clone spans (joshuafolkken/kit#2217).
|
|
2
|
+
//
|
|
3
|
+
// This is the pure core the `no-clones` rule was missing a measurement for: `sonarjs/no-identical-
|
|
4
|
+
// functions` sees only inside one file, and the rule's real target is duplication that crosses file
|
|
5
|
+
// and package boundaries. Here a clone is a fingerprint that occurs at two or more sites, and its
|
|
6
|
+
// category is the widest boundary any two of those sites straddle.
|
|
7
|
+
|
|
8
|
+
// One fingerprint occurrence: the hash of a normalized code window and where it was found.
|
|
9
|
+
interface Fingerprint {
|
|
10
|
+
hash: string
|
|
11
|
+
site: CloneSite
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Where a fingerprint occurs. `repo` is the identity duplication is measured against — two sites in
|
|
15
|
+
// different repositories are a cross-repository clone however identical their relative paths look.
|
|
16
|
+
interface CloneSite {
|
|
17
|
+
repo: string
|
|
18
|
+
file: string
|
|
19
|
+
line: number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// How far a clone spans. `same-file` is the narrowest, `cross-repo` the widest.
|
|
23
|
+
type CloneCategory = 'same-file' | 'cross-file' | 'cross-repo'
|
|
24
|
+
|
|
25
|
+
// A fingerprint that duplicated, its sites, and the boundary it crosses.
|
|
26
|
+
interface CloneGroup {
|
|
27
|
+
hash: string
|
|
28
|
+
sites: ReadonlyArray<CloneSite>
|
|
29
|
+
category: CloneCategory
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// A fingerprint is a clone only once it occurs at least twice.
|
|
33
|
+
const MIN_SITES = 2
|
|
34
|
+
|
|
35
|
+
// The widest boundary any two of the sites straddle: a second repository first, then a second file,
|
|
36
|
+
// else the sites share one file.
|
|
37
|
+
function categorize(sites: ReadonlyArray<CloneSite>): CloneCategory {
|
|
38
|
+
const repos = new Set(sites.map((site) => site.repo))
|
|
39
|
+
if (repos.size > 1) return 'cross-repo'
|
|
40
|
+
|
|
41
|
+
const files = new Set(sites.map((site) => site.file))
|
|
42
|
+
if (files.size > 1) return 'cross-file'
|
|
43
|
+
|
|
44
|
+
return 'same-file'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Every site collected under its fingerprint hash, insertion order preserved.
|
|
48
|
+
function group_sites(fingerprints: ReadonlyArray<Fingerprint>): Map<string, Array<CloneSite>> {
|
|
49
|
+
const groups = new Map<string, Array<CloneSite>>()
|
|
50
|
+
|
|
51
|
+
for (const fingerprint of fingerprints) {
|
|
52
|
+
const sites = groups.get(fingerprint.hash) ?? []
|
|
53
|
+
|
|
54
|
+
sites.push(fingerprint.site)
|
|
55
|
+
groups.set(fingerprint.hash, sites)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return groups
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// The clones among the fingerprints — those occurring at two or more sites — each classified. The
|
|
62
|
+
// count a caller reports is the length of this array.
|
|
63
|
+
function aggregate(fingerprints: ReadonlyArray<Fingerprint>): Array<CloneGroup> {
|
|
64
|
+
const clones: Array<CloneGroup> = []
|
|
65
|
+
|
|
66
|
+
for (const [hash, sites] of group_sites(fingerprints)) {
|
|
67
|
+
if (sites.length >= MIN_SITES) clones.push({ hash, sites, category: categorize(sites) })
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return clones
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const clone_aggregate = { categorize, aggregate }
|
|
74
|
+
|
|
75
|
+
export type { CloneCategory, CloneSite, Fingerprint, CloneGroup }
|
|
76
|
+
export { clone_aggregate }
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Fingerprint } from './clone-aggregate'
|
|
2
|
+
|
|
3
|
+
// Turning source text into fingerprints (joshuafolkken/kit#2217).
|
|
4
|
+
//
|
|
5
|
+
// A fingerprint is a block of consecutive significant lines, each normalized so that reindentation
|
|
6
|
+
// and reflowed whitespace do not hide a copy. Blank lines and comment-only lines are dropped before
|
|
7
|
+
// blocking, so a copied block still matches after its comments are edited. The block is the joined
|
|
8
|
+
// normalized text itself — two blocks are the same clone exactly when that text is equal — which needs
|
|
9
|
+
// no parser, so it works across package boundaries and file types the way the rule requires.
|
|
10
|
+
//
|
|
11
|
+
// The blocks are consecutive and non-overlapping (a stride equal to the window), so one copied region
|
|
12
|
+
// counts once rather than once per sliding offset: the number is a count of duplicated blocks, not an
|
|
13
|
+
// inflated tally of every window that happened to overlap the copy. The cost is that a copy whose
|
|
14
|
+
// significant lines do not align to the same block boundary in both files can be missed — an
|
|
15
|
+
// acceptable trade for a count that means what it says.
|
|
16
|
+
|
|
17
|
+
// How many significant lines make a block. Small enough to catch a copied helper, large enough that a
|
|
18
|
+
// run of ordinary statements does not match by accident.
|
|
19
|
+
const WINDOW_SIZE = 6
|
|
20
|
+
const LINE_SEPARATOR = '\n'
|
|
21
|
+
// Lines that begin a comment once trimmed. `*` covers the continuation lines of a block comment.
|
|
22
|
+
const COMMENT_PREFIXES = ['//', '/*', '*']
|
|
23
|
+
|
|
24
|
+
// A significant line: its normalized text and its 1-based line number in the original source.
|
|
25
|
+
interface SourceLine {
|
|
26
|
+
text: string
|
|
27
|
+
number: number
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Where a file's fingerprints belong, minus the line number the window fills in.
|
|
31
|
+
interface FileSite {
|
|
32
|
+
repo: string
|
|
33
|
+
file: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Collapse leading, trailing and interior whitespace so formatting differences do not defeat a match.
|
|
37
|
+
function normalize(text: string): string {
|
|
38
|
+
return text.trim().replaceAll(/\s+/gu, ' ')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Whether a line carries code — non-blank and not the start of a comment.
|
|
42
|
+
function is_significant(text: string): boolean {
|
|
43
|
+
const trimmed = text.trim()
|
|
44
|
+
if (trimmed.length === 0) return false
|
|
45
|
+
|
|
46
|
+
return COMMENT_PREFIXES.every((prefix) => !trimmed.startsWith(prefix))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The significant lines of a source, each normalized and tagged with its original line number.
|
|
50
|
+
function significant_lines(source: string): Array<SourceLine> {
|
|
51
|
+
const lines: Array<SourceLine> = []
|
|
52
|
+
|
|
53
|
+
for (const [index, text] of source.split(LINE_SEPARATOR).entries()) {
|
|
54
|
+
if (is_significant(text)) lines.push({ text: normalize(text), number: index + 1 })
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return lines
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// One window's fingerprint, or nothing when the slice came up empty.
|
|
61
|
+
function window_fingerprint(
|
|
62
|
+
window: ReadonlyArray<SourceLine>,
|
|
63
|
+
site: FileSite,
|
|
64
|
+
): Fingerprint | undefined {
|
|
65
|
+
const [first] = window
|
|
66
|
+
if (first === undefined) return undefined
|
|
67
|
+
|
|
68
|
+
const hash = window.map((line) => line.text).join(LINE_SEPARATOR)
|
|
69
|
+
|
|
70
|
+
return { hash, site: { repo: site.repo, file: site.file, line: first.number } }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Every non-overlapping block fingerprint of a source, keyed to `site`. A source with fewer than
|
|
74
|
+
// `WINDOW_SIZE` significant lines yields none.
|
|
75
|
+
function fingerprints_for(source: string, site: FileSite): Array<Fingerprint> {
|
|
76
|
+
const lines = significant_lines(source)
|
|
77
|
+
const fingerprints: Array<Fingerprint> = []
|
|
78
|
+
|
|
79
|
+
for (let start = 0; start + WINDOW_SIZE <= lines.length; start += WINDOW_SIZE) {
|
|
80
|
+
const fingerprint = window_fingerprint(lines.slice(start, start + WINDOW_SIZE), site)
|
|
81
|
+
if (fingerprint !== undefined) fingerprints.push(fingerprint)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return fingerprints
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const clone_fingerprint = {
|
|
88
|
+
WINDOW_SIZE,
|
|
89
|
+
normalize,
|
|
90
|
+
is_significant,
|
|
91
|
+
significant_lines,
|
|
92
|
+
fingerprints_for,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export type { FileSite }
|
|
96
|
+
export { clone_fingerprint }
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { clone_scan } from './clone-scan'
|
|
4
|
+
|
|
5
|
+
// `josh clone:scan` — count duplication across files and repositories (joshuafolkken/kit#2217).
|
|
6
|
+
//
|
|
7
|
+
// A command rather than a paragraph, for the reason `josh repo:party` is one: the `no-clones` rule
|
|
8
|
+
// fires on the agent's own recognition that it is about to copy something, which is exactly the moment
|
|
9
|
+
// the recognition is easiest to skip. This makes the duplication a number instead. `clean` on stdout
|
|
10
|
+
// so a caller can read the verdict; the count and the `file:line` sites follow it for a person.
|
|
11
|
+
|
|
12
|
+
const ARGV_OFFSET = 2
|
|
13
|
+
const USAGE = 'Usage: josh clone:scan'
|
|
14
|
+
const FAILURE_EXIT_CODE = 1
|
|
15
|
+
const FLAG_PREFIX = '-'
|
|
16
|
+
|
|
17
|
+
function run(argv: ReadonlyArray<string>): number {
|
|
18
|
+
if (argv.some((argument) => !argument.startsWith(FLAG_PREFIX))) {
|
|
19
|
+
console.error(USAGE)
|
|
20
|
+
|
|
21
|
+
return FAILURE_EXIT_CODE
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const report = clone_scan.format_report(clone_scan.scan(process.cwd()))
|
|
25
|
+
|
|
26
|
+
console.info(report)
|
|
27
|
+
|
|
28
|
+
return 0
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function main(argv: ReadonlyArray<string>): void {
|
|
32
|
+
process.exitCode = run(argv)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const clone_scan_cli = { USAGE, main, run }
|
|
36
|
+
|
|
37
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
|
|
38
|
+
|
|
39
|
+
export { clone_scan_cli }
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, type Dirent } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { repo_discovery } from '#scripts/discovery/repo-discovery'
|
|
4
|
+
import {
|
|
5
|
+
clone_aggregate,
|
|
6
|
+
type CloneGroup,
|
|
7
|
+
type CloneSite,
|
|
8
|
+
type Fingerprint,
|
|
9
|
+
} from './clone-aggregate'
|
|
10
|
+
import { clone_fingerprint } from './clone-fingerprint'
|
|
11
|
+
|
|
12
|
+
// Walking the source trees and reporting the clones (joshuafolkken/kit#2217).
|
|
13
|
+
//
|
|
14
|
+
// The current repository is always scanned; every first-party sibling `repo_discovery` finds —
|
|
15
|
+
// including the ones `JOSH_REPO_PATHS` adds — is scanned too, so a copy that crossed a package
|
|
16
|
+
// boundary is counted rather than left invisible. A repository is identified by its absolute root,
|
|
17
|
+
// which is what makes two identical relative paths in different repositories a cross-repository clone.
|
|
18
|
+
|
|
19
|
+
// The directories a package keeps its source in; whichever exist are scanned.
|
|
20
|
+
const SOURCE_ROOTS = ['scripts', 'src']
|
|
21
|
+
const SOURCE_EXTENSION = '.ts'
|
|
22
|
+
// Test files and declarations are not product code, so a shared test helper is not a clone to report.
|
|
23
|
+
const IGNORED_SUFFIXES = ['.test.ts', '.svelte.test.ts', '.d.ts']
|
|
24
|
+
const IGNORED_DIRECTORIES = new Set(['node_modules', '.git', '.svelte-kit', 'dist', 'build'])
|
|
25
|
+
const CLEAN_VERDICT = 'clean'
|
|
26
|
+
const CLONES_PREFIX = 'clones:'
|
|
27
|
+
|
|
28
|
+
// Whether a filename is a source file worth fingerprinting.
|
|
29
|
+
function is_source_file(name: string): boolean {
|
|
30
|
+
if (!name.endsWith(SOURCE_EXTENSION)) return false
|
|
31
|
+
|
|
32
|
+
return IGNORED_SUFFIXES.every((suffix) => !name.endsWith(suffix))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Whether a directory entry is one to descend into.
|
|
36
|
+
function is_scannable_directory(entry: Dirent): boolean {
|
|
37
|
+
return entry.isDirectory() && !IGNORED_DIRECTORIES.has(entry.name)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// The directory's entries, or none when it cannot be read: an unreadable directory is reported empty
|
|
41
|
+
// rather than failing the whole scan.
|
|
42
|
+
function read_entries(directory: string): Array<Dirent> {
|
|
43
|
+
try {
|
|
44
|
+
return readdirSync(directory, { withFileTypes: true })
|
|
45
|
+
} catch {
|
|
46
|
+
return []
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// The source files directly in a directory (not its subdirectories).
|
|
51
|
+
function direct_source_files(directory: string, entries: ReadonlyArray<Dirent>): Array<string> {
|
|
52
|
+
return entries
|
|
53
|
+
.filter((entry) => entry.isFile() && is_source_file(entry.name))
|
|
54
|
+
.map((entry) => path.join(directory, entry.name))
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Every source file under a directory, recursively. Only `walk` recurses, so there is no forward
|
|
58
|
+
// reference to resolve.
|
|
59
|
+
function walk(directory: string): Array<string> {
|
|
60
|
+
const entries = read_entries(directory)
|
|
61
|
+
const nested = entries
|
|
62
|
+
.filter((entry) => is_scannable_directory(entry))
|
|
63
|
+
.flatMap((entry) => walk(path.join(directory, entry.name)))
|
|
64
|
+
|
|
65
|
+
return [...direct_source_files(directory, entries), ...nested]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Every source file across a repository's source roots.
|
|
69
|
+
function source_files(repo_path: string): Array<string> {
|
|
70
|
+
return SOURCE_ROOTS.map((root) => path.join(repo_path, root))
|
|
71
|
+
.filter((root) => existsSync(root))
|
|
72
|
+
.flatMap((root) => walk(root))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// The fingerprints of one file, keyed to its repository and repo-relative path. An unreadable file
|
|
76
|
+
// contributes none.
|
|
77
|
+
function file_fingerprints(repo_path: string, file: string): Array<Fingerprint> {
|
|
78
|
+
try {
|
|
79
|
+
const source = readFileSync(file, 'utf8')
|
|
80
|
+
|
|
81
|
+
return clone_fingerprint.fingerprints_for(source, {
|
|
82
|
+
repo: repo_path,
|
|
83
|
+
file: path.relative(repo_path, file),
|
|
84
|
+
})
|
|
85
|
+
} catch {
|
|
86
|
+
return []
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Every fingerprint of every source file in a repository.
|
|
91
|
+
function repo_fingerprints(repo_path: string): Array<Fingerprint> {
|
|
92
|
+
return source_files(repo_path).flatMap((file) => file_fingerprints(repo_path, file))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// A repository's identity: its `origin` remote, or its resolved path when it declares none. Two
|
|
96
|
+
// worktrees of one repository share an `origin`, so this is what collapses them to a single scan —
|
|
97
|
+
// without it a lane sitting beside its sibling lanes would report every identical line as a clone.
|
|
98
|
+
function repo_identity(repo_path: string): string {
|
|
99
|
+
return repo_discovery.read_origin_url(repo_path) ?? path.resolve(repo_path)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// The absolute roots to scan: the current repository plus every first-party repository discovered
|
|
103
|
+
// beside it, de-duplicated by identity — the current tree wins, so a worktree of it is dropped — so
|
|
104
|
+
// each repository is scanned exactly once.
|
|
105
|
+
//
|
|
106
|
+
// **Discovery anchors on the main work tree, which `discover_repositories` resolves from `root`.** A
|
|
107
|
+
// `backlogrun` child runs in a lane, whose only neighbors are that repository's other lanes; asked
|
|
108
|
+
// from there, discovery walks up to the main checkout so it still finds the siblings. The current
|
|
109
|
+
// tree is scanned as `root` regardless, so a lane reports its own working state.
|
|
110
|
+
function scan_roots(root: string): Array<string> {
|
|
111
|
+
const map = repo_discovery.discover_repositories(root)
|
|
112
|
+
const seen = new Set<string>()
|
|
113
|
+
const roots: Array<string> = []
|
|
114
|
+
|
|
115
|
+
for (const repo_path of [root, ...map.values()]) {
|
|
116
|
+
const identity = repo_identity(repo_path)
|
|
117
|
+
if (seen.has(identity)) continue
|
|
118
|
+
|
|
119
|
+
seen.add(identity)
|
|
120
|
+
roots.push(path.resolve(repo_path))
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return roots
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// The clones found across the current repository and its first-party siblings.
|
|
127
|
+
function scan(root: string): Array<CloneGroup> {
|
|
128
|
+
const fingerprints = scan_roots(root).flatMap((repo_path) => repo_fingerprints(repo_path))
|
|
129
|
+
|
|
130
|
+
return clone_aggregate.aggregate(fingerprints)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// One site as `<repo>/<file>:<line>`; the repository basename disambiguates a cross-repository clone.
|
|
134
|
+
// **The main work tree's basename, not the scanned tree's.** A lane's directory is named after its
|
|
135
|
+
// issue, so a site found in one would otherwise print as `2217/…` — a repository nobody has.
|
|
136
|
+
function format_site(site: CloneSite): string {
|
|
137
|
+
const label = path.basename(repo_discovery.main_worktree(site.repo))
|
|
138
|
+
|
|
139
|
+
return `${label}/${site.file}:${String(site.line)}`
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// One clone group: its category and every site it occurs at.
|
|
143
|
+
function format_group(group: CloneGroup): string {
|
|
144
|
+
return ` [${group.category}] ${group.sites.map((site) => format_site(site)).join(', ')}`
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// The report: `clean` when nothing duplicated, otherwise the count and each clone's sites.
|
|
148
|
+
function format_report(groups: ReadonlyArray<CloneGroup>): string {
|
|
149
|
+
if (groups.length === 0) return CLEAN_VERDICT
|
|
150
|
+
|
|
151
|
+
const header = `${CLONES_PREFIX} ${String(groups.length)}`
|
|
152
|
+
|
|
153
|
+
return [header, ...groups.map((group) => format_group(group))].join('\n')
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const clone_scan = { CLEAN_VERDICT, CLONES_PREFIX, scan, format_site, format_group, format_report }
|
|
157
|
+
|
|
158
|
+
export { clone_scan }
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Public entry point for the parameterized config-merge library (`@joshuafolkken/kit/config-merge`).
|
|
2
|
+
// Both kit's own `josh sync` / `josh init` and downstream consumers (app-kit) drive their cspell
|
|
3
|
+
// `import` and tsconfig `extends` patches through `config_merge`, which exposes ensure + remove
|
|
4
|
+
// semantics for one YAML or JSON list field while preserving every other key, value, and ordering.
|
|
5
|
+
// JSON patches rewrite only the targeted field's own value, so comments, trailing commas and the
|
|
6
|
+
// consumer's hand-formatting elsewhere in the document survive (joshuafolkken/kit#798).
|
|
7
|
+
import { json_list } from './patch-json-list'
|
|
8
|
+
import { yaml_list } from './patch-yaml-list'
|
|
9
|
+
|
|
10
|
+
const config_merge = {
|
|
11
|
+
patch_yaml_list_field: yaml_list.patch_yaml_list_field,
|
|
12
|
+
read_yaml_list_field: yaml_list.read_yaml_list_field,
|
|
13
|
+
patch_json_list_field: json_list.patch_json_list_field,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type { ListEntryMatcher } from './list-patch'
|
|
17
|
+
export type { PatchYamlListOptions, YamlFieldPosition } from './patch-yaml-list'
|
|
18
|
+
export type { PatchJsonListOptions } from './patch-json-list'
|
|
19
|
+
export { config_merge }
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Serialize JSON config the way prettier would, so a file kit rewrites during `josh sync` stays
|
|
2
|
+
// `prettier --check`-clean. `JSON.stringify(value, undefined, '\t')` matches prettier everywhere
|
|
3
|
+
// EXCEPT one case: prettier keeps a short array of primitives on a single line when it fits within
|
|
4
|
+
// printWidth, whereas JSON.stringify always expands every non-empty array. We post-process the
|
|
5
|
+
// stringify output, collapsing exactly those arrays back inline — reusing JSON.stringify for all
|
|
6
|
+
// string escaping, number formatting, and key ordering so we never diverge on those. See
|
|
7
|
+
// joshuafolkken/kit#660 (a synced tsconfig `exclude` was emitted multi-line and failed prettier).
|
|
8
|
+
//
|
|
9
|
+
// Scope note: an OVER-width array is left one-element-per-line, which matches prettier for string
|
|
10
|
+
// arrays (the only kind these config files hold). prettier uses a packed "fill" layout only for
|
|
11
|
+
// over-width NUMBER arrays — a shape none of the managed JSON configs (tsconfig, package.json,
|
|
12
|
+
// .vscode/*) contain — so that one divergence is unreachable here and deliberately not replicated.
|
|
13
|
+
|
|
14
|
+
// Mirror the kit prettier preset: printWidth 100, tabs measured as 2 columns for width.
|
|
15
|
+
const PRINT_WIDTH = 100
|
|
16
|
+
const TAB_WIDTH = 2
|
|
17
|
+
const ARRAY_CLOSE = /^\t*\],?$/u
|
|
18
|
+
|
|
19
|
+
interface ArrayBlock {
|
|
20
|
+
elements: ReadonlyArray<string>
|
|
21
|
+
close: string
|
|
22
|
+
end: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// True when the line opens an array (`[` or `"key": [`). String / object opens never end in `[`.
|
|
26
|
+
function is_array_open(line: string): boolean {
|
|
27
|
+
return line.endsWith('[')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// A block is inline-able only when every element line is a leaf scalar. A nested object / array
|
|
31
|
+
// (which prettier and JSON.stringify always break) opens on its own line ending in `{`/`[`, whereas
|
|
32
|
+
// a scalar line ends in a quote, digit, comma, or literal — so a string value that merely CONTAINS
|
|
33
|
+
// a bracket (e.g. the glob `"src/[abc]/*.ts"`) is still correctly treated as a leaf.
|
|
34
|
+
function is_leaf_element(line: string): boolean {
|
|
35
|
+
return !line.endsWith('{') && !line.endsWith('[')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Printed column width of a single line: leading tabs count as TAB_WIDTH columns each, the rest as
|
|
39
|
+
// one column per character (config JSON never mixes tabs into the non-indent portion of a line).
|
|
40
|
+
function line_width(line: string): number {
|
|
41
|
+
const tabs = line.length - line.trimStart().length
|
|
42
|
+
|
|
43
|
+
return tabs * TAB_WIDTH + (line.length - tabs)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Flatten collected element lines into `[a, b, c]`, dropping each element's indentation and the
|
|
47
|
+
// trailing comma JSON.stringify placed between elements.
|
|
48
|
+
function flatten_elements(elements: ReadonlyArray<string>): string {
|
|
49
|
+
const scalars = elements.map((line) => line.trim().replace(/,$/u, ''))
|
|
50
|
+
|
|
51
|
+
return `[${scalars.join(', ')}]`
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Collect the element lines between an array-open at `start` and its matching close line. Returns
|
|
55
|
+
// undefined when any element is a nested structure (not inline-able) — the caller keeps it expanded.
|
|
56
|
+
function collect_block(lines: ReadonlyArray<string>, start: number): ArrayBlock | undefined {
|
|
57
|
+
const close = lines.findIndex((line, index) => index > start && ARRAY_CLOSE.test(line))
|
|
58
|
+
if (close === -1) return undefined
|
|
59
|
+
const elements = lines.slice(start + 1, close)
|
|
60
|
+
if (elements.some((line) => !is_leaf_element(line))) return undefined
|
|
61
|
+
|
|
62
|
+
return { elements, close: lines[close] ?? '', end: close }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Build the single-line form of an array block, or undefined when it would exceed printWidth (so
|
|
66
|
+
// the caller leaves it expanded, exactly as prettier would).
|
|
67
|
+
function try_inline(open: string, block: ArrayBlock): string | undefined {
|
|
68
|
+
const trailing_comma = block.close.trimStart() === '],' ? ',' : ''
|
|
69
|
+
const inlined = `${open.slice(0, -1)}${flatten_elements(block.elements)}${trailing_comma}`
|
|
70
|
+
|
|
71
|
+
return line_width(inlined) <= PRINT_WIDTH ? inlined : undefined
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface Rewrite {
|
|
75
|
+
lines: ReadonlyArray<string>
|
|
76
|
+
next: number
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Render `line` (at `index`), collapsing it to one line when it opens a short primitive array;
|
|
80
|
+
// otherwise emit it verbatim. `next` is the index to resume from (past a collapsed block).
|
|
81
|
+
function rewrite_at(lines: ReadonlyArray<string>, index: number, line: string): Rewrite {
|
|
82
|
+
const verbatim: Rewrite = { lines: [line], next: index + 1 }
|
|
83
|
+
const block = is_array_open(line) ? collect_block(lines, index) : undefined
|
|
84
|
+
if (block === undefined) return verbatim
|
|
85
|
+
const inlined = try_inline(line, block)
|
|
86
|
+
if (inlined === undefined) return verbatim
|
|
87
|
+
|
|
88
|
+
return { lines: [inlined], next: block.end + 1 }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function inline_short_arrays(text: string): string {
|
|
92
|
+
const lines = text.split('\n')
|
|
93
|
+
const output: Array<string> = []
|
|
94
|
+
let index = 0
|
|
95
|
+
|
|
96
|
+
while (index < lines.length) {
|
|
97
|
+
const rewrite = rewrite_at(lines, index, lines[index] ?? '')
|
|
98
|
+
|
|
99
|
+
output.push(...rewrite.lines)
|
|
100
|
+
index = rewrite.next
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return output.join('\n')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Prettier-clean replacement for `${JSON.stringify(value, undefined, '\t')}\n`. For every managed
|
|
107
|
+
// JSON config EXCEPT package.json — see format_package_json for why that one is different.
|
|
108
|
+
function format_json(value: unknown): string {
|
|
109
|
+
return `${inline_short_arrays(JSON.stringify(value, undefined, '\t'))}\n`
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Prettier-clean serialization for `package.json`, where prettier does NOT use the `json` parser.
|
|
113
|
+
// It selects `json-stringify` from the FILENAME, and that printer puts every array element on its
|
|
114
|
+
// own line regardless of printWidth — so the inlining above, correct everywhere else, produces a
|
|
115
|
+
// file the consumer's own `prettier --check` rejects. Plain `JSON.stringify` with tab indent is
|
|
116
|
+
// byte-for-byte what that printer emits, so the fix is to skip the inlining rather than model it.
|
|
117
|
+
// See joshuafolkken/kit#797.
|
|
118
|
+
function format_package_json(value: unknown): string {
|
|
119
|
+
return `${JSON.stringify(value, undefined, '\t')}\n`
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const json_format = {
|
|
123
|
+
inline_short_arrays,
|
|
124
|
+
format_json,
|
|
125
|
+
format_package_json,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { json_format }
|