diffsplain 0.4.3 → 0.6.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/README.md +17 -12
- package/dist/assets/abap-CLvhMVsD.js +1 -0
- package/dist/assets/actionscript-3--17pq3dv.js +1 -0
- package/dist/assets/ada-C5qYipkI.js +1 -0
- package/dist/assets/andromeeda-vGVdxbeo.js +1 -0
- package/dist/assets/angular-html-vBvPnd6a.js +1 -0
- package/dist/assets/angular-ts-CDzF1Z6a.js +1 -0
- package/dist/assets/apache-U0d_L8uA.js +1 -0
- package/dist/assets/apex-VAyPSnFM.js +1 -0
- package/dist/assets/apl-Bm9bxvP7.js +1 -0
- package/dist/assets/applescript-CCn79oCD.js +1 -0
- package/dist/assets/ara-4CJ0cIlV.js +1 -0
- package/dist/assets/asciidoc-DE70LPWp.js +1 -0
- package/dist/assets/asm-Cmm7eHzH.js +1 -0
- package/dist/assets/astro-RNrNWCYO.js +1 -0
- package/dist/assets/aurora-x-CDeNXAV0.js +1 -0
- package/dist/assets/awk-BWXHIvNe.js +1 -0
- package/dist/assets/ayu-dark-DluEY0Gj.js +1 -0
- package/dist/assets/ayu-light-C3h-C4tm.js +1 -0
- package/dist/assets/ayu-mirage-Bqwy1Gya.js +1 -0
- package/dist/assets/ballerina-B7ZEbQpA.js +1 -0
- package/dist/assets/bat-Bo4NYOV-.js +1 -0
- package/dist/assets/beancount-D-usSTwE.js +1 -0
- package/dist/assets/berry-DKpUyyne.js +1 -0
- package/dist/assets/bibtex-Ci_nEsc7.js +1 -0
- package/dist/assets/bicep-CUHmPFLl.js +1 -0
- package/dist/assets/bird2-C6vDhewU.js +1 -0
- package/dist/assets/blade-On-NBYUv.js +1 -0
- package/dist/assets/bsl-BkkzgIyY.js +1 -0
- package/dist/assets/c-hRmhFgD0.js +1 -0
- package/dist/assets/c3-BFHwR3_K.js +1 -0
- package/dist/assets/cadence-CQ2zXKGN.js +1 -0
- package/dist/assets/cairo-DLTphjLi.js +1 -0
- package/dist/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
- package/dist/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
- package/dist/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
- package/dist/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
- package/dist/assets/clarity-SemFz856.js +1 -0
- package/dist/assets/clojure-DqKBuwfJ.js +1 -0
- package/dist/assets/cmake-Bj61d0ZC.js +1 -0
- package/dist/assets/cobol-CIqc3k2t.js +1 -0
- package/dist/assets/codeowners-C8r90Shi.js +1 -0
- package/dist/assets/codeql-oeQT6MSM.js +1 -0
- package/dist/assets/coffee-Cd5EyvvS.js +1 -0
- package/dist/assets/common-lisp-Cv5bFMCO.js +1 -0
- package/dist/assets/coq-BrsZFFmf.js +1 -0
- package/dist/assets/cpp-zXFAAp_S.js +1 -0
- package/dist/assets/crystal-DRYY4cSw.js +1 -0
- package/dist/assets/csharp-oqKa8noW.js +1 -0
- package/dist/assets/css-C4op_MsD.js +1 -0
- package/dist/assets/csv-Dx-8-gkx.js +1 -0
- package/dist/assets/cue-CE9AQfxI.js +1 -0
- package/dist/assets/cypher-ClKdZ_lG.js +1 -0
- package/dist/assets/d-qD-0Kul2.js +1 -0
- package/dist/assets/dark-plus-Cs2F2srj.js +1 -0
- package/dist/assets/dart-CnvKMtbv.js +1 -0
- package/dist/assets/dax-BkyTk9wS.js +1 -0
- package/dist/assets/desktop-Dlh5hvp9.js +1 -0
- package/dist/assets/diff-woXpYk--.js +1 -0
- package/dist/assets/docker-IyjqRm3v.js +1 -0
- package/dist/assets/dotenv-_5a1GRtc.js +1 -0
- package/dist/assets/dracula-BHWKrbxM.js +1 -0
- package/dist/assets/dracula-soft-5eyTD99u.js +1 -0
- package/dist/assets/dream-maker-DW3nJb8Q.js +1 -0
- package/dist/assets/edge-d3rJkErf.js +1 -0
- package/dist/assets/elixir-DPqlJhYM.js +1 -0
- package/dist/assets/elm-DgU37I8a.js +1 -0
- package/dist/assets/emacs-lisp-B4R74twV.js +1 -0
- package/dist/assets/erb-CZVB_ntC.js +1 -0
- package/dist/assets/erlang-Cphh6RMH.js +1 -0
- package/dist/assets/everforest-dark-sB-x3p7T.js +1 -0
- package/dist/assets/everforest-light-Df2xbC6M.js +1 -0
- package/dist/assets/fennel-DQxkIbk2.js +1 -0
- package/dist/assets/fish-BJitypiv.js +1 -0
- package/dist/assets/fluent-C03EYrpw.js +1 -0
- package/dist/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
- package/dist/assets/fortran-free-form-CYNrtFtB.js +1 -0
- package/dist/assets/fsharp-D13ZGOAj.js +1 -0
- package/dist/assets/gdresource-C0sCabJj.js +1 -0
- package/dist/assets/gdscript-Cp2uCuqX.js +1 -0
- package/dist/assets/gdshader-CBce3t8t.js +1 -0
- package/dist/assets/genie-CV2tkWYe.js +1 -0
- package/dist/assets/gherkin-DExj1W_8.js +1 -0
- package/dist/assets/git-commit-BSykSTBG.js +1 -0
- package/dist/assets/git-rebase-hUkltHZG.js +1 -0
- package/dist/assets/github-dark-C-LZuMrd.js +1 -0
- package/dist/assets/github-dark-default-DXG-b-1a.js +1 -0
- package/dist/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
- package/dist/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
- package/dist/assets/github-light-EUqPIrTm.js +1 -0
- package/dist/assets/github-light-default-BXViO-2h.js +1 -0
- package/dist/assets/github-light-high-contrast-B68TUdTA.js +1 -0
- package/dist/assets/gleam-CSRkHgEL.js +1 -0
- package/dist/assets/glimmer-js-5XOT9GQ8.js +1 -0
- package/dist/assets/glimmer-ts-DT7D0Kfq.js +1 -0
- package/dist/assets/glsl-Br4_Eh5O.js +1 -0
- package/dist/assets/gn-ilITqXS6.js +1 -0
- package/dist/assets/gnuplot-7GGW24-e.js +1 -0
- package/dist/assets/go-rLFTqkRN.js +1 -0
- package/dist/assets/graphql--BmZ_AYP.js +1 -0
- package/dist/assets/groovy-CacY0gHj.js +1 -0
- package/dist/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
- package/dist/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
- package/dist/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
- package/dist/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
- package/dist/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
- package/dist/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
- package/dist/assets/hack-CMdqGDoA.js +1 -0
- package/dist/assets/haml-DLEOHGmg.js +1 -0
- package/dist/assets/handlebars-BfUftoV0.js +1 -0
- package/dist/assets/haskell-D8IpX4py.js +1 -0
- package/dist/assets/haxe-OTjmBuCE.js +1 -0
- package/dist/assets/hcl-Dh228itO.js +1 -0
- package/dist/assets/hjson-CxZEssPk.js +1 -0
- package/dist/assets/hlsl-Cvrh5tZx.js +1 -0
- package/dist/assets/horizon-CE9ld1lL.js +1 -0
- package/dist/assets/horizon-bright-DSNQnXHK.js +1 -0
- package/dist/assets/houston-CsvMBhTu.js +1 -0
- package/dist/assets/html-derivative-D5cZE6C4.js +1 -0
- package/dist/assets/html-uOgx2iYC.js +1 -0
- package/dist/assets/http-cW9c66J_.js +1 -0
- package/dist/assets/hurl-BztURO2n.js +1 -0
- package/dist/assets/hxml-B0Qn7Nwc.js +1 -0
- package/dist/assets/hy-CZbG8q4J.js +1 -0
- package/dist/assets/imba-DsUTQ-LC.js +1 -0
- package/dist/assets/{index-BB6eHlnY.css → index-C2p_1iAk.css} +1 -1
- package/dist/assets/index-DZFM4-3L.js +1568 -0
- package/dist/assets/ini-B5eOa1yu.js +1 -0
- package/dist/assets/java-Cy4mnKaj.js +1 -0
- package/dist/assets/javascript-_Z02t_9Q.js +1 -0
- package/dist/assets/jinja-BppBm5gt.js +1 -0
- package/dist/assets/jison-Dzns436M.js +1 -0
- package/dist/assets/json-BYkfLOry.js +1 -0
- package/dist/assets/json5-BR5RXkoi.js +1 -0
- package/dist/assets/jsonc-CYpm1nAK.js +1 -0
- package/dist/assets/jsonl-CmCQp5Yx.js +1 -0
- package/dist/assets/jsonnet-CJTPZ8u_.js +1 -0
- package/dist/assets/jssm-DXw9l8Rf.js +1 -0
- package/dist/assets/jsx-DtAm8NUb.js +1 -0
- package/dist/assets/julia-CLIMRuh0.js +1 -0
- package/dist/assets/just-DMg47an6.js +1 -0
- package/dist/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
- package/dist/assets/kanagawa-lotus-BN08jTvb.js +1 -0
- package/dist/assets/kanagawa-wave-CTweb8Dz.js +1 -0
- package/dist/assets/kdl-CsD5j6eV.js +1 -0
- package/dist/assets/kotlin-DhhofPvG.js +1 -0
- package/dist/assets/kusto-C7mF5XQf.js +1 -0
- package/dist/assets/laserwave-C_8bwKvT.js +1 -0
- package/dist/assets/latex-D05ztCOx.js +1 -0
- package/dist/assets/lean-CewbzKMR.js +1 -0
- package/dist/assets/less-DVTAwKKz.js +1 -0
- package/dist/assets/light-plus-DVQuIRkW.js +1 -0
- package/dist/assets/liquid-DpImQR4t.js +1 -0
- package/dist/assets/llvm-Cm23YOpf.js +1 -0
- package/dist/assets/log-BNLmms1o.js +1 -0
- package/dist/assets/logo-Cluzi2Zq.js +1 -0
- package/dist/assets/lua--ZHUYQUU.js +1 -0
- package/dist/assets/luau-FMPmPwt6.js +1 -0
- package/dist/assets/make-Dixweg8N.js +1 -0
- package/dist/assets/markdown-BYOwaDjH.js +1 -0
- package/dist/assets/marko-Dh3Xi08i.js +1 -0
- package/dist/assets/material-theme-Bm3Qr25_.js +1 -0
- package/dist/assets/material-theme-darker-2IIEA8gg.js +1 -0
- package/dist/assets/material-theme-lighter-uhdI0v04.js +1 -0
- package/dist/assets/material-theme-ocean-CHQ94UKr.js +1 -0
- package/dist/assets/material-theme-palenight-B5W6OYN7.js +1 -0
- package/dist/assets/matlab-D7qyCx1q.js +1 -0
- package/dist/assets/mdc-Br6Pt78u.js +1 -0
- package/dist/assets/mdx-DQZ5AkYe.js +1 -0
- package/dist/assets/mermaid-Bk4SNUv9.js +1 -0
- package/dist/assets/min-dark-BSWPekZh.js +1 -0
- package/dist/assets/min-light-DDpmG2fV.js +1 -0
- package/dist/assets/mipsasm-BMqwQI7S.js +1 -0
- package/dist/assets/mojo-BgCJLMeH.js +1 -0
- package/dist/assets/monokai-CdkpiU2Y.js +1 -0
- package/dist/assets/moonbit-CaWjb8XO.js +1 -0
- package/dist/assets/move-B1IS1UjX.js +1 -0
- package/dist/assets/narrat-_X_XdTYD.js +1 -0
- package/dist/assets/nextflow-BJtWHP5T.js +1 -0
- package/dist/assets/nextflow-groovy-DJMQeKeT.js +1 -0
- package/dist/assets/nginx-CwSU6U6d.js +1 -0
- package/dist/assets/night-owl-DhmEMT88.js +1 -0
- package/dist/assets/night-owl-light-eJ-hLW7d.js +1 -0
- package/dist/assets/nim-CBbTwyeq.js +1 -0
- package/dist/assets/nix-IvuFDN5E.js +1 -0
- package/dist/assets/nord-Cb4Vim4T.js +1 -0
- package/dist/assets/nushell-DcLAeLz5.js +1 -0
- package/dist/assets/objective-c-D1A_Heim.js +1 -0
- package/dist/assets/objective-cpp-BsSzOQcm.js +1 -0
- package/dist/assets/ocaml-O90oeIOV.js +1 -0
- package/dist/assets/odin-B1RWQWA5.js +1 -0
- package/dist/assets/one-dark-pro-CLwyXe_n.js +1 -0
- package/dist/assets/one-light-D7Lr4KcI.js +1 -0
- package/dist/assets/openscad-BUDT5pXO.js +1 -0
- package/dist/assets/pascal-4ZHwLPI5.js +1 -0
- package/dist/assets/perl-D3jQu3LN.js +1 -0
- package/dist/assets/php-BMeXBzlU.js +1 -0
- package/dist/assets/pierre-dark-CpLgRqie.js +1 -0
- package/dist/assets/pierre-dark-protanopia-deuteranopia-B35FxJx-.js +1 -0
- package/dist/assets/pierre-dark-soft-kZQmAZld.js +1 -0
- package/dist/assets/pierre-dark-tritanopia-CpjhbsIL.js +1 -0
- package/dist/assets/pierre-dark-vibrant-CpQYzh95.js +1 -0
- package/dist/assets/pierre-light-CoaEpmwp.js +1 -0
- package/dist/assets/pierre-light-protanopia-deuteranopia-0fSaH845.js +1 -0
- package/dist/assets/pierre-light-soft-lWLdNTOI.js +1 -0
- package/dist/assets/pierre-light-tritanopia-CEbqgOJL.js +1 -0
- package/dist/assets/pierre-light-vibrant-D80Fkn33.js +1 -0
- package/dist/assets/pkl-ot-7Btpt.js +1 -0
- package/dist/assets/plastic-DQwYfKfQ.js +1 -0
- package/dist/assets/plsql-DGHpHOYJ.js +1 -0
- package/dist/assets/po-BiJDBrnU.js +1 -0
- package/dist/assets/poimandres-DRFjx7u4.js +1 -0
- package/dist/assets/polar-C7UOKdEL.js +1 -0
- package/dist/assets/postcss-BXeXVLqQ.js +1 -0
- package/dist/assets/powerquery-DNMTfnFr.js +1 -0
- package/dist/assets/powershell-DshXNtvi.js +1 -0
- package/dist/assets/prisma-BsRQq5mF.js +1 -0
- package/dist/assets/prolog-iXnhIJG7.js +1 -0
- package/dist/assets/proto-DB4EqR-F.js +1 -0
- package/dist/assets/pug-BGdY1g5E.js +1 -0
- package/dist/assets/puppet-CDv2pdJW.js +1 -0
- package/dist/assets/purescript-9MfHhQsQ.js +1 -0
- package/dist/assets/python-gzcpVVnB.js +1 -0
- package/dist/assets/qml-DsT5biza.js +1 -0
- package/dist/assets/qmldir-DCQb3MpD.js +1 -0
- package/dist/assets/qss-Fe1Jh2GI.js +1 -0
- package/dist/assets/r-CbS9PfN5.js +1 -0
- package/dist/assets/racket-DcIDlBhZ.js +1 -0
- package/dist/assets/raku-B3gFvitq.js +1 -0
- package/dist/assets/razor-Bwm8roHi.js +1 -0
- package/dist/assets/red-CJ3rzSJv.js +1 -0
- package/dist/assets/reg-CRGYupPL.js +1 -0
- package/dist/assets/regexp-Bc_9DyAu.js +1 -0
- package/dist/assets/rel-BtDbiS_P.js +1 -0
- package/dist/assets/riscv-Ckw8ddFX.js +1 -0
- package/dist/assets/ron-VUp2lXgN.js +1 -0
- package/dist/assets/rose-pine-BthvhNj6.js +1 -0
- package/dist/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
- package/dist/assets/rose-pine-moon-hon4tzzS.js +1 -0
- package/dist/assets/rosmsg-CAekHB0j.js +1 -0
- package/dist/assets/rst-Cj1Aii91.js +1 -0
- package/dist/assets/ruby-BPMtFZnc.js +1 -0
- package/dist/assets/rust-Cfkwpbl8.js +1 -0
- package/dist/assets/sas-CoOau1t2.js +1 -0
- package/dist/assets/sass-DXrisJhu.js +1 -0
- package/dist/assets/scala-DKOlJaKm.js +1 -0
- package/dist/assets/scheme-DQCgrYNe.js +1 -0
- package/dist/assets/scss-CvfaI808.js +1 -0
- package/dist/assets/sdbl-bTVj8UrX.js +1 -0
- package/dist/assets/shaderlab-TOUzSsQk.js +1 -0
- package/dist/assets/shellscript-B0C-TdLE.js +1 -0
- package/dist/assets/shellsession-UhmLiqcA.js +1 -0
- package/dist/assets/slack-dark-DnToyrRv.js +1 -0
- package/dist/assets/slack-ochin-B2OO5cIa.js +1 -0
- package/dist/assets/smalltalk-B16xEiuN.js +1 -0
- package/dist/assets/snazzy-light-4G7pJPwS.js +1 -0
- package/dist/assets/solarized-dark-DV17i1UV.js +1 -0
- package/dist/assets/solarized-light-DSh2HLQt.js +1 -0
- package/dist/assets/solidity-CKzVLygQ.js +1 -0
- package/dist/assets/soy-D419u0RL.js +1 -0
- package/dist/assets/sparql-D_iOobhT.js +1 -0
- package/dist/assets/splunk-BC2Px7Mm.js +1 -0
- package/dist/assets/sql-Do9k0rRn.js +1 -0
- package/dist/assets/ssh-config-BgfXC-Er.js +1 -0
- package/dist/assets/stata-x47J6BC4.js +1 -0
- package/dist/assets/stylus-B6D30XZt.js +1 -0
- package/dist/assets/surrealql-BERQ6pHu.js +1 -0
- package/dist/assets/svelte-dRWkyqKW.js +1 -0
- package/dist/assets/swift-DonLKvLd.js +1 -0
- package/dist/assets/synthwave-84-nFMaYfgc.js +1 -0
- package/dist/assets/system-verilog-DJ5XKQeo.js +1 -0
- package/dist/assets/systemd-BxMlprV5.js +1 -0
- package/dist/assets/talonscript-CohzipZa.js +1 -0
- package/dist/assets/tasl-DMoTqEGO.js +1 -0
- package/dist/assets/tcl-CZd0xW_V.js +1 -0
- package/dist/assets/templ-CTq-KoWN.js +1 -0
- package/dist/assets/terraform-DswuEJGm.js +1 -0
- package/dist/assets/tex-CdRGjyYI.js +1 -0
- package/dist/assets/tokyo-night-oM2G3aXe.js +1 -0
- package/dist/assets/toml-CcmNWLt0.js +1 -0
- package/dist/assets/ts-tags-CgaMqyVb.js +1 -0
- package/dist/assets/tsv-sltzmVWM.js +1 -0
- package/dist/assets/tsx-cpBQKcPG.js +1 -0
- package/dist/assets/turtle-ByJddavk.js +1 -0
- package/dist/assets/twig-vbs_PM4-.js +1 -0
- package/dist/assets/typescript-Cc--nwIo.js +1 -0
- package/dist/assets/typespec-BRdr0IET.js +1 -0
- package/dist/assets/typst-DI99ib-x.js +1 -0
- package/dist/assets/v-DETTlOr0.js +1 -0
- package/dist/assets/vala-zf12oZj6.js +1 -0
- package/dist/assets/vb-Djn5o6TS.js +1 -0
- package/dist/assets/verilog-CiiDBU1e.js +1 -0
- package/dist/assets/vesper-DdrHHSXu.js +1 -0
- package/dist/assets/vhdl-BroJfC0k.js +1 -0
- package/dist/assets/viml-DvXPmvsu.js +1 -0
- package/dist/assets/vitesse-black-fwtXNY1n.js +1 -0
- package/dist/assets/vitesse-dark-BZCL-v6S.js +1 -0
- package/dist/assets/vitesse-light-VbXTXTou.js +1 -0
- package/dist/assets/vue-CgHwdBmB.js +1 -0
- package/dist/assets/vue-html-BHfoMw47.js +1 -0
- package/dist/assets/vue-vine-_lVRp_NK.js +1 -0
- package/dist/assets/vyper-CgoNMtux.js +1 -0
- package/dist/assets/wasm-BnjxR4X6.js +1 -0
- package/dist/assets/wasm-ByWQv1Qj.js +1 -0
- package/dist/assets/wenyan-C8pVoKbM.js +1 -0
- package/dist/assets/wgsl-BsKzXJz4.js +1 -0
- package/dist/assets/wikitext-ClFFjSW2.js +1 -0
- package/dist/assets/wit-DdvCle-K.js +1 -0
- package/dist/assets/wolfram-DLL8P-h_.js +1 -0
- package/dist/assets/xml-G4NVmTde.js +1 -0
- package/dist/assets/xsl-s0so2M1i.js +1 -0
- package/dist/assets/yaml-CpsmW05t.js +1 -0
- package/dist/assets/zenscript-BnlCZFoB.js +1 -0
- package/dist/assets/zig-CMLA9XwU.js +1 -0
- package/dist/index.html +2 -2
- package/package.json +52 -23
- package/scripts/access-token.mjs +21 -0
- package/scripts/build-diff-data.mjs +297 -62
- package/scripts/cache.mjs +301 -0
- package/scripts/cli-args.mjs +206 -57
- package/scripts/coding-agents.mjs +279 -162
- package/scripts/dev.mjs +218 -0
- package/scripts/doctor.mjs +265 -46
- package/scripts/generate-summaries.mjs +760 -260
- package/scripts/mock-agent.mjs +165 -0
- package/scripts/present.mjs +394 -85
- package/scripts/presenter-runtime.mjs +148 -0
- package/scripts/serve-built.mjs +343 -71
- package/scripts/summary-path.mjs +24 -7
- package/scripts/support-record.mjs +242 -0
- package/dist/assets/index-D5201POe.js +0 -10
|
@@ -1,21 +1,77 @@
|
|
|
1
1
|
import { constants } from 'node:fs';
|
|
2
2
|
import { access } from 'node:fs/promises';
|
|
3
3
|
import {
|
|
4
|
-
basename,
|
|
5
4
|
delimiter,
|
|
6
5
|
dirname,
|
|
7
6
|
isAbsolute,
|
|
8
7
|
join,
|
|
9
8
|
} from 'node:path';
|
|
10
9
|
|
|
11
|
-
export const
|
|
12
|
-
'codex',
|
|
13
|
-
'claude',
|
|
14
|
-
'copilot',
|
|
15
|
-
'cursor',
|
|
16
|
-
'opencode',
|
|
10
|
+
export const codingAgentCapabilities = {
|
|
11
|
+
codex: { binary: 'codex', model: true, reasoning: true },
|
|
12
|
+
claude: { binary: 'claude', model: true, reasoning: false },
|
|
13
|
+
copilot: { binary: 'copilot', model: true, reasoning: false },
|
|
14
|
+
cursor: { binary: 'cursor-agent', model: true, reasoning: false },
|
|
15
|
+
opencode: { binary: 'opencode', model: true, reasoning: true },
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const codingAgents = Object.keys(codingAgentCapabilities);
|
|
19
|
+
|
|
20
|
+
export function agentSupportsReasoning(agent) {
|
|
21
|
+
return codingAgentCapabilities[agent]?.reasoning === true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function assertReasoningSupported(agent, reasoning) {
|
|
25
|
+
if (reasoning && !agentSupportsReasoning(agent)) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
`--reasoning is supported only by codex and opencode; ${agent} does not support it.`,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const summaryEnvironmentNames = [
|
|
33
|
+
'CODEX_HOME',
|
|
34
|
+
'COMSPEC',
|
|
35
|
+
'HOME',
|
|
36
|
+
'HOMEDRIVE',
|
|
37
|
+
'HOMEPATH',
|
|
38
|
+
'HTTP_PROXY',
|
|
39
|
+
'HTTPS_PROXY',
|
|
40
|
+
'LANG',
|
|
41
|
+
'LC_ALL',
|
|
42
|
+
'NODE_EXTRA_CA_CERTS',
|
|
43
|
+
'NO_PROXY',
|
|
44
|
+
'PATH',
|
|
45
|
+
'SSL_CERT_FILE',
|
|
46
|
+
'SystemRoot',
|
|
47
|
+
'SYSTEMROOT',
|
|
48
|
+
'TEMP',
|
|
49
|
+
'TERM',
|
|
50
|
+
'TMP',
|
|
51
|
+
'TMPDIR',
|
|
52
|
+
'USERPROFILE',
|
|
17
53
|
];
|
|
18
54
|
|
|
55
|
+
export function summaryAgentEnvironment(env = process.env) {
|
|
56
|
+
return Object.fromEntries(
|
|
57
|
+
summaryEnvironmentNames
|
|
58
|
+
.filter((name) => typeof env[name] === 'string')
|
|
59
|
+
.map((name) => [name, env[name]]),
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const cursorDisabledReason =
|
|
64
|
+
'Cursor review is disabled: Cursor Agent has no supported read-only, no-network, no-tool mode.';
|
|
65
|
+
|
|
66
|
+
export function agentDisabledReason(agent) {
|
|
67
|
+
if (agent === 'cursor') return cursorDisabledReason;
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const enabledCodingAgents = codingAgents.filter(
|
|
72
|
+
(agent) => !agentDisabledReason(agent),
|
|
73
|
+
);
|
|
74
|
+
|
|
19
75
|
async function executable(path) {
|
|
20
76
|
try {
|
|
21
77
|
await access(
|
|
@@ -28,25 +84,15 @@ async function executable(path) {
|
|
|
28
84
|
}
|
|
29
85
|
}
|
|
30
86
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} = {},
|
|
37
|
-
) {
|
|
38
|
-
if (
|
|
39
|
-
isAbsolute(command) ||
|
|
40
|
-
command.includes('/') ||
|
|
41
|
-
command.includes('\\')
|
|
42
|
-
) {
|
|
43
|
-
return (await executable(command)) ? command : undefined;
|
|
44
|
-
}
|
|
87
|
+
function commandExtensions(platform, env) {
|
|
88
|
+
return platform === 'win32'
|
|
89
|
+
? (env.PATHEXT || '.COM;.EXE;.BAT;.CMD').split(';')
|
|
90
|
+
: [''];
|
|
91
|
+
}
|
|
45
92
|
|
|
93
|
+
async function findOnPath(command, env, platform) {
|
|
46
94
|
const extensions =
|
|
47
|
-
platform
|
|
48
|
-
? (env.PATHEXT || '.COM;.EXE;.BAT;.CMD').split(';')
|
|
49
|
-
: [''];
|
|
95
|
+
commandExtensions(platform, env);
|
|
50
96
|
const directories = (env.PATH || '').split(delimiter).filter(Boolean);
|
|
51
97
|
for (const directory of directories) {
|
|
52
98
|
for (const extension of extensions) {
|
|
@@ -58,10 +104,26 @@ export async function findCommand(
|
|
|
58
104
|
return undefined;
|
|
59
105
|
}
|
|
60
106
|
|
|
107
|
+
export async function findCommand(
|
|
108
|
+
command,
|
|
109
|
+
{
|
|
110
|
+
env = process.env,
|
|
111
|
+
platform = process.platform,
|
|
112
|
+
} = {},
|
|
113
|
+
) {
|
|
114
|
+
const direct =
|
|
115
|
+
isAbsolute(command) ||
|
|
116
|
+
command.includes('/') ||
|
|
117
|
+
command.includes('\\');
|
|
118
|
+
if (direct) return (await executable(command)) ? command : undefined;
|
|
119
|
+
return findOnPath(command, env, platform);
|
|
120
|
+
}
|
|
121
|
+
|
|
61
122
|
export async function commandAvailable(command, options) {
|
|
62
123
|
return Boolean(await findCommand(command, options));
|
|
63
124
|
}
|
|
64
125
|
|
|
126
|
+
// fallow-ignore-next-line complexity -- validation and fallback share one public selector.
|
|
65
127
|
export async function selectCodingAgent(
|
|
66
128
|
requested,
|
|
67
129
|
available = commandAvailable,
|
|
@@ -69,23 +131,26 @@ export async function selectCodingAgent(
|
|
|
69
131
|
if (requested) {
|
|
70
132
|
if (!codingAgents.includes(requested)) {
|
|
71
133
|
throw new Error(
|
|
72
|
-
`Unsupported agent "${requested}". Choose ${
|
|
134
|
+
`Unsupported agent "${requested}". Choose ${enabledCodingAgents.join(', ')}.`,
|
|
73
135
|
);
|
|
74
136
|
}
|
|
137
|
+
const disabled = agentDisabledReason(requested);
|
|
138
|
+
if (disabled) throw new Error(disabled);
|
|
75
139
|
if (!(await available(requested))) {
|
|
76
140
|
throw new Error(`Coding agent "${requested}" is not available.`);
|
|
77
141
|
}
|
|
78
142
|
return requested;
|
|
79
143
|
}
|
|
80
144
|
|
|
81
|
-
for (const agent of
|
|
145
|
+
for (const agent of enabledCodingAgents) {
|
|
82
146
|
if (await available(agent)) return agent;
|
|
83
147
|
}
|
|
84
148
|
throw new Error(
|
|
85
|
-
`No coding agent is available. Install one of: ${
|
|
149
|
+
`No coding agent is available. Install one of: ${enabledCodingAgents.join(', ')}. ${cursorDisabledReason}`,
|
|
86
150
|
);
|
|
87
151
|
}
|
|
88
152
|
|
|
153
|
+
// fallow-ignore-next-line complexity -- each supported agent has one override rule.
|
|
89
154
|
export function codingAgentBinary(
|
|
90
155
|
agent,
|
|
91
156
|
{
|
|
@@ -94,8 +159,14 @@ export function codingAgentBinary(
|
|
|
94
159
|
} = {},
|
|
95
160
|
) {
|
|
96
161
|
if (agent === 'codex') return codexBin || env.CODEX_BIN || agent;
|
|
97
|
-
if (agent === 'cursor')
|
|
98
|
-
|
|
162
|
+
if (agent === 'cursor') {
|
|
163
|
+
return env.CURSOR_BIN || codingAgentCapabilities.cursor.binary;
|
|
164
|
+
}
|
|
165
|
+
return (
|
|
166
|
+
env[`${agent.toUpperCase()}_BIN`] ||
|
|
167
|
+
codingAgentCapabilities[agent]?.binary ||
|
|
168
|
+
agent
|
|
169
|
+
);
|
|
99
170
|
}
|
|
100
171
|
|
|
101
172
|
function parseJsonText(text, agent) {
|
|
@@ -108,161 +179,179 @@ function parseJsonText(text, agent) {
|
|
|
108
179
|
}
|
|
109
180
|
}
|
|
110
181
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return parseJsonText(envelope.result, 'Claude');
|
|
117
|
-
}
|
|
118
|
-
return envelope;
|
|
182
|
+
function parseClaudeResponse(stdout) {
|
|
183
|
+
const envelope = parseJsonText(stdout, 'Claude');
|
|
184
|
+
if (envelope?.structured_output) return envelope.structured_output;
|
|
185
|
+
if (typeof envelope?.result === 'string') {
|
|
186
|
+
return parseJsonText(envelope.result, 'Claude');
|
|
119
187
|
}
|
|
188
|
+
return envelope;
|
|
189
|
+
}
|
|
120
190
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
return JSON.parse(line);
|
|
128
|
-
} catch {
|
|
129
|
-
return undefined;
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
const parts = events
|
|
133
|
-
.filter((event) => event?.type === 'text' && event.part?.text)
|
|
134
|
-
.map((event) => event.part.text);
|
|
135
|
-
if (parts.length) return parseJsonText(parts.join(''), 'OpenCode');
|
|
136
|
-
throw new Error('OpenCode did not return summary JSON');
|
|
191
|
+
function parseEvent(line) {
|
|
192
|
+
try {
|
|
193
|
+
return JSON.parse(line);
|
|
194
|
+
} catch {
|
|
195
|
+
return undefined;
|
|
137
196
|
}
|
|
197
|
+
}
|
|
138
198
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
199
|
+
function parseOpenCodeResponse(stdout) {
|
|
200
|
+
const parts = stdout
|
|
201
|
+
.split('\n')
|
|
202
|
+
.filter(Boolean)
|
|
203
|
+
.map(parseEvent)
|
|
204
|
+
.filter((event) => event?.type === 'text' && event.part?.text)
|
|
205
|
+
.map((event) => event.part.text);
|
|
206
|
+
if (!parts.length) throw new Error('OpenCode did not return summary JSON');
|
|
207
|
+
return parseJsonText(parts.join(''), 'OpenCode');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function parseCursorResponse(stdout) {
|
|
211
|
+
const envelope = parseJsonText(stdout, 'Cursor');
|
|
212
|
+
if (typeof envelope?.result === 'string') {
|
|
213
|
+
return parseJsonText(envelope.result, 'Cursor');
|
|
145
214
|
}
|
|
215
|
+
return envelope;
|
|
216
|
+
}
|
|
146
217
|
|
|
218
|
+
export function parseAgentResponse(agent, stdout) {
|
|
219
|
+
if (agent === 'claude') return parseClaudeResponse(stdout);
|
|
220
|
+
if (agent === 'opencode') return parseOpenCodeResponse(stdout);
|
|
221
|
+
if (agent === 'cursor') return parseCursorResponse(stdout);
|
|
147
222
|
const label = agent === 'copilot' ? 'Copilot' : 'Codex';
|
|
148
223
|
return parseJsonText(stdout, label);
|
|
149
224
|
}
|
|
150
225
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
binary = agent,
|
|
226
|
+
function codexCommand({
|
|
227
|
+
binary,
|
|
154
228
|
model,
|
|
155
229
|
reasoning,
|
|
156
230
|
prompt,
|
|
157
|
-
schema,
|
|
158
231
|
schemaPath,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
env = process.env,
|
|
232
|
+
summaryDirectory,
|
|
233
|
+
summaryEnv,
|
|
162
234
|
}) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (
|
|
190
|
-
const args = [
|
|
191
|
-
'--print',
|
|
192
|
-
'--output-format',
|
|
193
|
-
'json',
|
|
194
|
-
'--json-schema',
|
|
195
|
-
JSON.stringify(schema),
|
|
196
|
-
'--tools',
|
|
197
|
-
'',
|
|
198
|
-
'--no-session-persistence',
|
|
199
|
-
];
|
|
200
|
-
if (model) args.push('--model', model);
|
|
201
|
-
args.push(prompt);
|
|
202
|
-
return { command: binary, args, input: 'stdin' };
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (agent === 'copilot') {
|
|
206
|
-
const schemaText = JSON.stringify(schema);
|
|
207
|
-
const args = [
|
|
208
|
-
'--silent',
|
|
209
|
-
'--no-ask-user',
|
|
210
|
-
'--no-color',
|
|
211
|
-
'--no-custom-instructions',
|
|
212
|
-
'--no-remote',
|
|
213
|
-
'--no-remote-export',
|
|
214
|
-
`--add-dir=${dirname(inputPath)}`,
|
|
215
|
-
];
|
|
216
|
-
if (model) args.push('--model', model);
|
|
235
|
+
const args = [
|
|
236
|
+
'exec',
|
|
237
|
+
'--ephemeral',
|
|
238
|
+
'--sandbox',
|
|
239
|
+
'read-only',
|
|
240
|
+
'--ignore-user-config',
|
|
241
|
+
'--ignore-rules',
|
|
242
|
+
'--color',
|
|
243
|
+
'never',
|
|
244
|
+
'--skip-git-repo-check',
|
|
245
|
+
'-C',
|
|
246
|
+
summaryDirectory,
|
|
247
|
+
'--output-schema',
|
|
248
|
+
schemaPath,
|
|
249
|
+
'--config',
|
|
250
|
+
'mcp_servers={}',
|
|
251
|
+
'--config',
|
|
252
|
+
'plugins={}',
|
|
253
|
+
'--config',
|
|
254
|
+
'shell_environment_policy.inherit="none"',
|
|
255
|
+
'--config',
|
|
256
|
+
'sandbox_workspace_write.network_access=false',
|
|
257
|
+
'--config',
|
|
258
|
+
'web_search="disabled"',
|
|
259
|
+
];
|
|
260
|
+
if (model) args.push('--model', model);
|
|
261
|
+
if (reasoning) {
|
|
217
262
|
args.push(
|
|
218
|
-
'--
|
|
219
|
-
|
|
263
|
+
'--config',
|
|
264
|
+
`model_reasoning_effort=${JSON.stringify(reasoning)}`,
|
|
220
265
|
);
|
|
221
|
-
return { command: binary, args, input: 'none' };
|
|
222
266
|
}
|
|
267
|
+
args.push(prompt);
|
|
268
|
+
return {
|
|
269
|
+
command: binary,
|
|
270
|
+
args,
|
|
271
|
+
input: 'stdin',
|
|
272
|
+
cwd: summaryDirectory,
|
|
273
|
+
env: summaryEnv,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
223
276
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
277
|
+
function claudeCommand({
|
|
278
|
+
binary,
|
|
279
|
+
model,
|
|
280
|
+
prompt,
|
|
281
|
+
schema,
|
|
282
|
+
summaryDirectory,
|
|
283
|
+
summaryEnv,
|
|
284
|
+
}) {
|
|
285
|
+
const args = [
|
|
286
|
+
'--print',
|
|
287
|
+
'--output-format',
|
|
288
|
+
'json',
|
|
289
|
+
'--json-schema',
|
|
290
|
+
JSON.stringify(schema),
|
|
291
|
+
'--tools',
|
|
292
|
+
'',
|
|
293
|
+
'--no-session-persistence',
|
|
294
|
+
];
|
|
295
|
+
if (model) args.push('--model', model);
|
|
296
|
+
args.push(prompt);
|
|
297
|
+
return {
|
|
298
|
+
command: binary,
|
|
299
|
+
args,
|
|
300
|
+
input: 'stdin',
|
|
301
|
+
cwd: summaryDirectory,
|
|
302
|
+
env: summaryEnv,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
237
305
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
306
|
+
function copilotCommand({
|
|
307
|
+
binary,
|
|
308
|
+
inputPath,
|
|
309
|
+
model,
|
|
310
|
+
prompt,
|
|
311
|
+
schema,
|
|
312
|
+
summaryDirectory,
|
|
313
|
+
summaryEnv,
|
|
314
|
+
}) {
|
|
315
|
+
const schemaText = JSON.stringify(schema);
|
|
316
|
+
const args = [
|
|
317
|
+
'--silent',
|
|
318
|
+
'--no-ask-user',
|
|
319
|
+
'--no-color',
|
|
320
|
+
'--no-custom-instructions',
|
|
321
|
+
'--no-remote',
|
|
322
|
+
'--no-remote-export',
|
|
323
|
+
`--add-dir=${dirname(inputPath)}`,
|
|
324
|
+
];
|
|
325
|
+
if (model) args.push('--model', model);
|
|
326
|
+
args.push(
|
|
327
|
+
'--prompt',
|
|
328
|
+
`${prompt}\n\nRead the snapshot from @${inputPath}. Return JSON that matches this schema:\n${schemaText}`,
|
|
329
|
+
);
|
|
330
|
+
return {
|
|
331
|
+
command: binary,
|
|
332
|
+
args,
|
|
333
|
+
input: 'none',
|
|
334
|
+
cwd: summaryDirectory,
|
|
335
|
+
env: summaryEnv,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function openCodeCommand({
|
|
340
|
+
binary,
|
|
341
|
+
model,
|
|
342
|
+
reasoning,
|
|
343
|
+
prompt,
|
|
344
|
+
schema,
|
|
345
|
+
summaryDirectory,
|
|
346
|
+
summaryEnv,
|
|
347
|
+
}) {
|
|
259
348
|
const args = [
|
|
260
349
|
'run',
|
|
261
350
|
'--pure',
|
|
262
351
|
'--format',
|
|
263
352
|
'json',
|
|
264
353
|
'--dir',
|
|
265
|
-
|
|
354
|
+
summaryDirectory,
|
|
266
355
|
'--agent',
|
|
267
356
|
'build',
|
|
268
357
|
];
|
|
@@ -275,16 +364,14 @@ export function agentCommand({
|
|
|
275
364
|
command: binary,
|
|
276
365
|
args,
|
|
277
366
|
input: 'stdin',
|
|
278
|
-
cwd:
|
|
367
|
+
cwd: summaryDirectory,
|
|
279
368
|
env: {
|
|
369
|
+
...summaryEnv,
|
|
280
370
|
OPENCODE_DB: ':memory:',
|
|
281
371
|
OPENCODE_CONFIG_CONTENT: JSON.stringify({
|
|
282
|
-
...config,
|
|
283
372
|
permission: { '*': 'deny' },
|
|
284
373
|
agent: {
|
|
285
|
-
...configuredAgents,
|
|
286
374
|
build: {
|
|
287
|
-
...configuredBuild,
|
|
288
375
|
permission: { '*': 'deny' },
|
|
289
376
|
},
|
|
290
377
|
},
|
|
@@ -292,3 +379,33 @@ export function agentCommand({
|
|
|
292
379
|
},
|
|
293
380
|
};
|
|
294
381
|
}
|
|
382
|
+
|
|
383
|
+
export function agentCommand({
|
|
384
|
+
agent,
|
|
385
|
+
binary = agent,
|
|
386
|
+
model,
|
|
387
|
+
reasoning,
|
|
388
|
+
prompt,
|
|
389
|
+
schema,
|
|
390
|
+
schemaPath,
|
|
391
|
+
inputPath,
|
|
392
|
+
env = process.env,
|
|
393
|
+
}) {
|
|
394
|
+
const disabled = agentDisabledReason(agent);
|
|
395
|
+
if (disabled) throw new Error(disabled);
|
|
396
|
+
const options = {
|
|
397
|
+
binary,
|
|
398
|
+
inputPath,
|
|
399
|
+
model,
|
|
400
|
+
prompt,
|
|
401
|
+
reasoning,
|
|
402
|
+
schema,
|
|
403
|
+
schemaPath,
|
|
404
|
+
summaryDirectory: dirname(inputPath),
|
|
405
|
+
summaryEnv: summaryAgentEnvironment(env),
|
|
406
|
+
};
|
|
407
|
+
if (agent === 'codex') return codexCommand(options);
|
|
408
|
+
if (agent === 'claude') return claudeCommand(options);
|
|
409
|
+
if (agent === 'copilot') return copilotCommand(options);
|
|
410
|
+
return openCodeCommand(options);
|
|
411
|
+
}
|