comprehende 0.6.1 → 0.8.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 +7 -3
- package/dist/api/agent-md.js +9 -19
- package/dist/api/live.js +21 -11
- package/dist/api/paths.js +34 -36
- package/dist/api/types.js +5 -1
- package/dist/cli/args.js +12 -5
- package/dist/cli/commands.js +4 -27
- package/dist/cli/main.js +7 -4
- package/dist/git/exec.js +9 -6
- package/dist/git/repo.js +14 -7
- package/dist/git/show.js +2 -8
- package/dist/package-root.js +20 -3
- package/dist/review/coverage.js +11 -11
- package/dist/review/load.js +20 -0
- package/dist/review/pins.js +6 -3
- package/dist/schema/cli-pin.js +4 -0
- package/dist/schema/hunk-meta.js +0 -78
- package/dist/schema/identity.js +3 -2
- package/dist/schema/image.js +2 -7
- package/dist/schema/lockfile.js +2 -1
- package/dist/schema/parse.js +28 -429
- package/dist/schema/review.js +229 -0
- package/dist/schema/skill-sync.js +4 -9
- package/dist/schema/source.js +13 -8
- package/dist/schema/types.js +14 -1
- package/dist/server/http.js +37 -39
- package/dist/ui/assets/andromeeda-vGVdxbeo.js +1 -0
- package/dist/ui/assets/aurora-x-CDeNXAV0.js +1 -0
- package/dist/ui/assets/ayu-dark-DluEY0Gj.js +1 -0
- package/dist/ui/assets/ayu-light-C3h-C4tm.js +1 -0
- package/dist/ui/assets/ayu-mirage-Bqwy1Gya.js +1 -0
- package/dist/ui/assets/catppuccin-frappe-C9Q5zVZY.js +1 -0
- package/dist/ui/assets/catppuccin-latte-CtsyrtPq.js +1 -0
- package/dist/ui/assets/catppuccin-macchiato-R8nAf1vR.js +1 -0
- package/dist/ui/assets/catppuccin-mocha-DjuaAJKi.js +1 -0
- package/dist/ui/assets/dark-plus-Cs2F2srj.js +1 -0
- package/dist/ui/assets/dracula-BHWKrbxM.js +1 -0
- package/dist/ui/assets/dracula-soft-5eyTD99u.js +1 -0
- package/dist/ui/assets/everforest-dark-sB-x3p7T.js +1 -0
- package/dist/ui/assets/everforest-light-Df2xbC6M.js +1 -0
- package/dist/ui/assets/github-dark-C-LZuMrd.js +1 -0
- package/dist/ui/assets/github-dark-default-DXG-b-1a.js +1 -0
- package/dist/ui/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
- package/dist/ui/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
- package/dist/ui/assets/github-light-EUqPIrTm.js +1 -0
- package/dist/ui/assets/github-light-default-BXViO-2h.js +1 -0
- package/dist/ui/assets/github-light-high-contrast-B68TUdTA.js +1 -0
- package/dist/ui/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
- package/dist/ui/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
- package/dist/ui/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
- package/dist/ui/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
- package/dist/ui/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
- package/dist/ui/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
- package/dist/ui/assets/horizon-CE9ld1lL.js +1 -0
- package/dist/ui/assets/horizon-bright-DSNQnXHK.js +1 -0
- package/dist/ui/assets/houston-CsvMBhTu.js +1 -0
- package/dist/ui/assets/index-BPpt3lUW.css +1 -0
- package/dist/ui/assets/index-Cw3dQOi7.js +1744 -0
- package/dist/ui/assets/kanagawa-dragon-Bozd7klA.js +1 -0
- package/dist/ui/assets/kanagawa-lotus-BmuOG9ZW.js +1 -0
- package/dist/ui/assets/kanagawa-wave-BML5mF2J.js +1 -0
- package/dist/ui/assets/laserwave-C_8bwKvT.js +1 -0
- package/dist/ui/assets/light-plus-DVQuIRkW.js +1 -0
- package/dist/ui/assets/material-theme-Bm3Qr25_.js +1 -0
- package/dist/ui/assets/material-theme-darker-2IIEA8gg.js +1 -0
- package/dist/ui/assets/material-theme-lighter-uhdI0v04.js +1 -0
- package/dist/ui/assets/material-theme-ocean-CHQ94UKr.js +1 -0
- package/dist/ui/assets/material-theme-palenight-B5W6OYN7.js +1 -0
- package/dist/ui/assets/min-dark-BSWPekZh.js +1 -0
- package/dist/ui/assets/min-light-DDpmG2fV.js +1 -0
- package/dist/ui/assets/monokai-B_bV9PQ9.js +1 -0
- package/dist/ui/assets/night-owl-DhmEMT88.js +1 -0
- package/dist/ui/assets/night-owl-light-eJ-hLW7d.js +1 -0
- package/dist/ui/assets/nord-Cb4Vim4T.js +1 -0
- package/dist/ui/assets/one-dark-pro-CLwyXe_n.js +1 -0
- package/dist/ui/assets/one-light-D7Lr4KcI.js +1 -0
- package/dist/ui/assets/pierre-dark-CpLgRqie.js +1 -0
- package/dist/ui/assets/pierre-dark-protanopia-deuteranopia-B35FxJx-.js +1 -0
- package/dist/ui/assets/pierre-dark-soft-kZQmAZld.js +1 -0
- package/dist/ui/assets/pierre-dark-tritanopia-CpjhbsIL.js +1 -0
- package/dist/ui/assets/pierre-dark-vibrant-CpQYzh95.js +1 -0
- package/dist/ui/assets/pierre-light-CoaEpmwp.js +1 -0
- package/dist/ui/assets/pierre-light-protanopia-deuteranopia-0fSaH845.js +1 -0
- package/dist/ui/assets/pierre-light-soft-lWLdNTOI.js +1 -0
- package/dist/ui/assets/pierre-light-tritanopia-CEbqgOJL.js +1 -0
- package/dist/ui/assets/pierre-light-vibrant-D80Fkn33.js +1 -0
- package/dist/ui/assets/plastic-DQwYfKfQ.js +1 -0
- package/dist/ui/assets/poimandres-DRFjx7u4.js +1 -0
- package/dist/ui/assets/red-DX1BQOs8.js +1 -0
- package/dist/ui/assets/rose-pine-aMsaMD1D.js +1 -0
- package/dist/ui/assets/rose-pine-dawn-8PwUyIlP.js +1 -0
- package/dist/ui/assets/rose-pine-moon-DO-qXg-I.js +1 -0
- package/dist/ui/assets/shiki-lang-abap-BuHPl3Px.js +1 -0
- package/dist/ui/assets/shiki-lang-actionscript-3-DT7i6v_4.js +1 -0
- package/dist/ui/assets/shiki-lang-ada-QB58RKQb.js +1 -0
- package/dist/ui/assets/shiki-lang-ahk-Deo8ZsxI.js +1 -0
- package/dist/ui/assets/shiki-lang-ahk2-DWQ-qmQe.js +1 -0
- package/dist/ui/assets/shiki-lang-angular-expression-CWExdM8x.js +1 -0
- package/dist/ui/assets/shiki-lang-angular-html-BZS7pisj.js +1 -0
- package/dist/ui/assets/shiki-lang-angular-inline-style-B4bPMr5O.js +1 -0
- package/dist/ui/assets/shiki-lang-angular-inline-template-obnrrKUv.js +1 -0
- package/dist/ui/assets/shiki-lang-angular-let-declaration-BvqQakFa.js +1 -0
- package/dist/ui/assets/shiki-lang-angular-template-blocks-DlxKd-FQ.js +1 -0
- package/dist/ui/assets/shiki-lang-angular-template-oRYn081P.js +1 -0
- package/dist/ui/assets/shiki-lang-angular-ts-Bg0EOCRA.js +1 -0
- package/dist/ui/assets/shiki-lang-apache-CaeBCo1H.js +1 -0
- package/dist/ui/assets/shiki-lang-apex-C0P1xrr7.js +1 -0
- package/dist/ui/assets/shiki-lang-apl-DpghvkS9.js +1 -0
- package/dist/ui/assets/shiki-lang-applescript-qHXCUv9W.js +1 -0
- package/dist/ui/assets/shiki-lang-ara-CnKLzTh0.js +1 -0
- package/dist/ui/assets/shiki-lang-asciidoc-BFyWQdTW.js +1 -0
- package/dist/ui/assets/shiki-lang-asm-BDAQRHlr.js +1 -0
- package/dist/ui/assets/shiki-lang-astro-eLzdEfkh.js +1 -0
- package/dist/ui/assets/shiki-lang-awk-nbK03rsj.js +1 -0
- package/dist/ui/assets/shiki-lang-ballerina-BvFIoPjv.js +1 -0
- package/dist/ui/assets/shiki-lang-bat-DeZWaK2t.js +1 -0
- package/dist/ui/assets/shiki-lang-beancount-D3PEpbaR.js +1 -0
- package/dist/ui/assets/shiki-lang-berry-q4KduTOe.js +1 -0
- package/dist/ui/assets/shiki-lang-bibtex-BK_j-Uh8.js +1 -0
- package/dist/ui/assets/shiki-lang-bicep-BAz0ZWPk.js +1 -0
- package/dist/ui/assets/shiki-lang-bird2-CexT8W9C.js +1 -0
- package/dist/ui/assets/shiki-lang-blade-EiwCWvW-.js +1 -0
- package/dist/ui/assets/shiki-lang-bsl-BJlZfp3d.js +1 -0
- package/dist/ui/assets/shiki-lang-c-cUgVXYtZ.js +1 -0
- package/dist/ui/assets/shiki-lang-c3-DkIGQwpj.js +1 -0
- package/dist/ui/assets/shiki-lang-cadence-D0f5xasM.js +1 -0
- package/dist/ui/assets/shiki-lang-cairo-BhNbTAo2.js +1 -0
- package/dist/ui/assets/shiki-lang-chapel-C41a-Vfc.js +1 -0
- package/dist/ui/assets/shiki-lang-clarity-D30seMWU.js +1 -0
- package/dist/ui/assets/shiki-lang-clojure-uuUteQ-I.js +1 -0
- package/dist/ui/assets/shiki-lang-cmake-TS4v06Lq.js +1 -0
- package/dist/ui/assets/shiki-lang-cobol-DR4--xqM.js +1 -0
- package/dist/ui/assets/shiki-lang-codeowners-Dq4wI_wj.js +1 -0
- package/dist/ui/assets/shiki-lang-codeql-C2YFz6nZ.js +1 -0
- package/dist/ui/assets/shiki-lang-coffee-BoP47XOy.js +1 -0
- package/dist/ui/assets/shiki-lang-common-lisp-BI2P6pYW.js +1 -0
- package/dist/ui/assets/shiki-lang-coq-DGJ-LtGn.js +1 -0
- package/dist/ui/assets/shiki-lang-cpp-Dal4zAhU.js +1 -0
- package/dist/ui/assets/shiki-lang-cpp-macro-BNcMYQzK.js +1 -0
- package/dist/ui/assets/shiki-lang-crystal-C8kllMvh.js +1 -0
- package/dist/ui/assets/shiki-lang-csharp-xjiDMJUR.js +1 -0
- package/dist/ui/assets/shiki-lang-css-BtK5ec9f.js +1 -0
- package/dist/ui/assets/shiki-lang-csv-p-Fkolpm.js +1 -0
- package/dist/ui/assets/shiki-lang-cue-rpKFDnrP.js +1 -0
- package/dist/ui/assets/shiki-lang-cypher-COrMSn75.js +1 -0
- package/dist/ui/assets/shiki-lang-d-i8h2-tT8.js +1 -0
- package/dist/ui/assets/shiki-lang-dart-Dio4c9vd.js +1 -0
- package/dist/ui/assets/shiki-lang-dax-CPTkOeIN.js +1 -0
- package/dist/ui/assets/shiki-lang-desktop-DFiSEBxz.js +1 -0
- package/dist/ui/assets/shiki-lang-diff-D6COc5hs.js +1 -0
- package/dist/ui/assets/shiki-lang-docker-XIMjEzG8.js +1 -0
- package/dist/ui/assets/shiki-lang-dotenv-QSkQX7h5.js +1 -0
- package/dist/ui/assets/shiki-lang-dream-maker-USSOZfUq.js +1 -0
- package/dist/ui/assets/shiki-lang-edge-BPDV4Q0u.js +1 -0
- package/dist/ui/assets/shiki-lang-elixir-BKE9OPDF.js +1 -0
- package/dist/ui/assets/shiki-lang-elm-WG-wF2ge.js +1 -0
- package/dist/ui/assets/shiki-lang-emacs-lisp-YvLEIlvI.js +1 -0
- package/dist/ui/assets/shiki-lang-erb-CbW7_yrm.js +1 -0
- package/dist/ui/assets/shiki-lang-erlang-tQ2Conzb.js +1 -0
- package/dist/ui/assets/shiki-lang-es-tag-css-CwAevhtf.js +1 -0
- package/dist/ui/assets/shiki-lang-es-tag-glsl-dqP1Yz9Z.js +1 -0
- package/dist/ui/assets/shiki-lang-es-tag-html--KbvnLgJ.js +1 -0
- package/dist/ui/assets/shiki-lang-es-tag-sql-D8eF3fs-.js +1 -0
- package/dist/ui/assets/shiki-lang-es-tag-xml-C1XCREhg.js +1 -0
- package/dist/ui/assets/shiki-lang-fennel-ByuP2T_N.js +1 -0
- package/dist/ui/assets/shiki-lang-fish-Bl6JSWxf.js +1 -0
- package/dist/ui/assets/shiki-lang-fluent-DcjpW-CJ.js +1 -0
- package/dist/ui/assets/shiki-lang-fortran-fixed-form-Jm96oYxt.js +1 -0
- package/dist/ui/assets/shiki-lang-fortran-free-form-DBXJeZhO.js +1 -0
- package/dist/ui/assets/shiki-lang-fsharp-C1Axgpg7.js +1 -0
- package/dist/ui/assets/{shiki-lang-gdresource-CPMZsTRs.js → shiki-lang-gdresource-Cb2Lv_Hg.js} +1 -1
- package/dist/ui/assets/shiki-lang-gdscript-BqpET1Hp.js +1 -0
- package/dist/ui/assets/shiki-lang-gdshader-EJVyKmd9.js +1 -0
- package/dist/ui/assets/shiki-lang-genie-C580asv3.js +1 -0
- package/dist/ui/assets/shiki-lang-gherkin-1-_7jqIt.js +1 -0
- package/dist/ui/assets/shiki-lang-git-commit-C1CitGA9.js +1 -0
- package/dist/ui/assets/shiki-lang-git-rebase-CafoN6im.js +1 -0
- package/dist/ui/assets/shiki-lang-gleam-DzCfrYgh.js +1 -0
- package/dist/ui/assets/shiki-lang-glimmer-js-DFqhoMH-.js +1 -0
- package/dist/ui/assets/shiki-lang-glimmer-ts-BpmACrHW.js +1 -0
- package/dist/ui/assets/shiki-lang-glsl-CZJe7hbK.js +1 -0
- package/dist/ui/assets/shiki-lang-gn-Rjzf9iJq.js +1 -0
- package/dist/ui/assets/shiki-lang-gnuplot-eeygxHmA.js +1 -0
- package/dist/ui/assets/shiki-lang-go-NVEOzY7_.js +1 -0
- package/dist/ui/assets/shiki-lang-graphql-DhZ5TXkF.js +1 -0
- package/dist/ui/assets/shiki-lang-groovy-CEZdlCsP.js +1 -0
- package/dist/ui/assets/shiki-lang-hack-BmcjITAv.js +1 -0
- package/dist/ui/assets/{shiki-lang-haml-B5ggipOx.js → shiki-lang-haml-HJ2Ueb86.js} +1 -1
- package/dist/ui/assets/shiki-lang-handlebars-DxaLlHkn.js +1 -0
- package/dist/ui/assets/shiki-lang-haskell-DiddM2MJ.js +1 -0
- package/dist/ui/assets/shiki-lang-haxe-pMfP0LCc.js +1 -0
- package/dist/ui/assets/shiki-lang-hcl-Bap936O0.js +1 -0
- package/dist/ui/assets/shiki-lang-hjson-BYTDlyGA.js +1 -0
- package/dist/ui/assets/shiki-lang-hlsl-fyyNP_qi.js +1 -0
- package/dist/ui/assets/{shiki-lang-html-D3aYWL0H.js → shiki-lang-html-CP9Hm1lR.js} +1 -1
- package/dist/ui/assets/shiki-lang-html-derivative--x4x2jCE.js +1 -0
- package/dist/ui/assets/shiki-lang-http-CwwtjO5s.js +1 -0
- package/dist/ui/assets/shiki-lang-hurl-CQo_d2_V.js +1 -0
- package/dist/ui/assets/shiki-lang-hxml-CJQUEG21.js +1 -0
- package/dist/ui/assets/shiki-lang-hy-BHZn1Bjp.js +1 -0
- package/dist/ui/assets/shiki-lang-imba-QC3P1YWQ.js +1 -0
- package/dist/ui/assets/shiki-lang-ini-kwRikv0S.js +1 -0
- package/dist/ui/assets/shiki-lang-java-d1M2cgqP.js +1 -0
- package/dist/ui/assets/shiki-lang-javascript-CoQwDVkE.js +1 -0
- package/dist/ui/assets/shiki-lang-jinja-html-C-rrI0jb.js +1 -0
- package/dist/ui/assets/shiki-lang-jinja-oWNRr7NO.js +1 -0
- package/dist/ui/assets/shiki-lang-jison-DlYeb9b8.js +1 -0
- package/dist/ui/assets/shiki-lang-json-yQGkCSm9.js +1 -0
- package/dist/ui/assets/shiki-lang-json5-BBK18-F7.js +1 -0
- package/dist/ui/assets/shiki-lang-jsonc-C492qAh6.js +1 -0
- package/dist/ui/assets/shiki-lang-jsonl-Df74WKjQ.js +1 -0
- package/dist/ui/assets/shiki-lang-jsonnet-doyqAZP2.js +1 -0
- package/dist/ui/assets/shiki-lang-jssm-Cn74Pd6Y.js +1 -0
- package/dist/ui/assets/shiki-lang-jsx-mYZ0_grh.js +1 -0
- package/dist/ui/assets/shiki-lang-julia-By3XtwRn.js +1 -0
- package/dist/ui/assets/shiki-lang-just-BTkdamae.js +1 -0
- package/dist/ui/assets/shiki-lang-kdl-hCt96Ltw.js +1 -0
- package/dist/ui/assets/shiki-lang-kotlin-BFL6W1VK.js +1 -0
- package/dist/ui/assets/shiki-lang-kusto-Bi9Fd-uE.js +1 -0
- package/dist/ui/assets/shiki-lang-latex-C1gH_y7D.js +1 -0
- package/dist/ui/assets/shiki-lang-lean-DJESOId2.js +1 -0
- package/dist/ui/assets/shiki-lang-less-BlBwe5lT.js +1 -0
- package/dist/ui/assets/shiki-lang-liquid-_aQQlg5i.js +1 -0
- package/dist/ui/assets/shiki-lang-llvm-BEpgvxue.js +1 -0
- package/dist/ui/assets/shiki-lang-log-COUzL5MF.js +1 -0
- package/dist/ui/assets/shiki-lang-logo-BzFyBpUa.js +1 -0
- package/dist/ui/assets/shiki-lang-lua-D86t0AFA.js +1 -0
- package/dist/ui/assets/shiki-lang-luau-D1iPfPp8.js +1 -0
- package/dist/ui/assets/shiki-lang-make-CKHn0pN_.js +1 -0
- package/dist/ui/assets/shiki-lang-markdown-DvqJlRaX.js +1 -0
- package/dist/ui/assets/shiki-lang-markdown-nix-DOLw_s_D.js +1 -0
- package/dist/ui/assets/shiki-lang-markdown-vue-DDYW27gg.js +1 -0
- package/dist/ui/assets/shiki-lang-marko-Bx5Ys3zf.js +1 -0
- package/dist/ui/assets/shiki-lang-matlab-Bsmpzlgg.js +1 -0
- package/dist/ui/assets/shiki-lang-mdc-BD8Hug0K.js +1 -0
- package/dist/ui/assets/shiki-lang-mdx-D6-XzQ1O.js +1 -0
- package/dist/ui/assets/shiki-lang-mermaid-CyNo_sGZ.js +1 -0
- package/dist/ui/assets/shiki-lang-mipsasm-DA63Htym.js +1 -0
- package/dist/ui/assets/shiki-lang-mojo-COJJ3_fN.js +1 -0
- package/dist/ui/assets/shiki-lang-moonbit-CuNFBU2r.js +1 -0
- package/dist/ui/assets/shiki-lang-move-BX2BqAEI.js +1 -0
- package/dist/ui/assets/shiki-lang-narrat-DRT2PRBR.js +1 -0
- package/dist/ui/assets/shiki-lang-nextflow-CXbNYeNi.js +1 -0
- package/dist/ui/assets/shiki-lang-nextflow-groovy-CBn50lGS.js +1 -0
- package/dist/ui/assets/shiki-lang-nginx-VuJMgGAK.js +1 -0
- package/dist/ui/assets/shiki-lang-nim-gUyAmDNe.js +1 -0
- package/dist/ui/assets/shiki-lang-nix-ZWhismn0.js +1 -0
- package/dist/ui/assets/shiki-lang-nsis-DiLH_ad1.js +1 -0
- package/dist/ui/assets/shiki-lang-nushell-D3HeAm2_.js +1 -0
- package/dist/ui/assets/shiki-lang-objective-c-Bf-vgIFL.js +1 -0
- package/dist/ui/assets/shiki-lang-objective-cpp-BIkOqJvP.js +1 -0
- package/dist/ui/assets/shiki-lang-ocaml-DWguduvb.js +1 -0
- package/dist/ui/assets/shiki-lang-odin-BH-7UUWe.js +1 -0
- package/dist/ui/assets/shiki-lang-openscad-BSzJHkmP.js +1 -0
- package/dist/ui/assets/shiki-lang-org-DbleOP5Y.js +1 -0
- package/dist/ui/assets/shiki-lang-pascal-gTsGvL1D.js +1 -0
- package/dist/ui/assets/shiki-lang-perl-BKMLvgdT.js +1 -0
- package/dist/ui/assets/shiki-lang-php-B7Gwh9ef.js +1 -0
- package/dist/ui/assets/shiki-lang-pkl-CopbDshc.js +1 -0
- package/dist/ui/assets/shiki-lang-plsql-DQMF8idG.js +1 -0
- package/dist/ui/assets/shiki-lang-po-DwBJCip-.js +1 -0
- package/dist/ui/assets/shiki-lang-polar-DnF9YeeS.js +1 -0
- package/dist/ui/assets/shiki-lang-postcss-CXWa9_la.js +1 -0
- package/dist/ui/assets/shiki-lang-powerquery-MZ135DUG.js +1 -0
- package/dist/ui/assets/shiki-lang-powershell-BhvOQ-ow.js +1 -0
- package/dist/ui/assets/shiki-lang-prisma-ehoeHrFh.js +1 -0
- package/dist/ui/assets/shiki-lang-prolog-CbsViES-.js +1 -0
- package/dist/ui/assets/shiki-lang-proto-DzSxeFhe.js +1 -0
- package/dist/ui/assets/shiki-lang-pug-Cx8nw1GZ.js +1 -0
- package/dist/ui/assets/shiki-lang-puppet-Btc-vtJB.js +1 -0
- package/dist/ui/assets/shiki-lang-purescript-BRNRwNAr.js +1 -0
- package/dist/ui/assets/shiki-lang-python-CHKKXXi8.js +1 -0
- package/dist/ui/assets/shiki-lang-qml-8dXsP_KG.js +1 -0
- package/dist/ui/assets/shiki-lang-qmldir-wsrRkenJ.js +1 -0
- package/dist/ui/assets/shiki-lang-qss-Cddq0YPK.js +1 -0
- package/dist/ui/assets/shiki-lang-r-DSZvQ2bf.js +1 -0
- package/dist/ui/assets/shiki-lang-racket-CPkaj6O_.js +1 -0
- package/dist/ui/assets/shiki-lang-raku-C-j9AeHY.js +1 -0
- package/dist/ui/assets/shiki-lang-razor-Cw-zhqTO.js +1 -0
- package/dist/ui/assets/shiki-lang-rbs-Bcy0mDBQ.js +1 -0
- package/dist/ui/assets/shiki-lang-reg-BdP2Aq_3.js +1 -0
- package/dist/ui/assets/shiki-lang-regexp-Dr8RsTV5.js +1 -0
- package/dist/ui/assets/shiki-lang-rel-ItxKk1t2.js +1 -0
- package/dist/ui/assets/shiki-lang-riscv-sAXJO5va.js +1 -0
- package/dist/ui/assets/shiki-lang-ron-BVZi4ZmK.js +1 -0
- package/dist/ui/assets/shiki-lang-rosmsg-BwJgk5sN.js +1 -0
- package/dist/ui/assets/shiki-lang-rst-D5hzYB0l.js +1 -0
- package/dist/ui/assets/shiki-lang-ruby-D9gEja1t.js +1 -0
- package/dist/ui/assets/shiki-lang-rust-BzGhc63A.js +1 -0
- package/dist/ui/assets/shiki-lang-sas-BFWf1cyL.js +1 -0
- package/dist/ui/assets/shiki-lang-sass-fiWvE1E6.js +1 -0
- package/dist/ui/assets/shiki-lang-scala-KEPZWw7Q.js +1 -0
- package/dist/ui/assets/shiki-lang-scheme-WjM1Xspu.js +1 -0
- package/dist/ui/assets/shiki-lang-scss-CG7e8fco.js +1 -0
- package/dist/ui/assets/shiki-lang-sdbl-D-fUhBMJ.js +1 -0
- package/dist/ui/assets/shiki-lang-shaderlab-CeQUIb-m.js +1 -0
- package/dist/ui/assets/shiki-lang-shellscript-BHRoVZ9B.js +1 -0
- package/dist/ui/assets/shiki-lang-shellsession-oQPRyNtJ.js +1 -0
- package/dist/ui/assets/shiki-lang-smalltalk-BCn5pML6.js +1 -0
- package/dist/ui/assets/shiki-lang-smithy-Bnew5vAI.js +1 -0
- package/dist/ui/assets/shiki-lang-solidity-DYWBIpKd.js +1 -0
- package/dist/ui/assets/shiki-lang-soy-BU_I37b3.js +1 -0
- package/dist/ui/assets/shiki-lang-sparql-CUzHwOAc.js +1 -0
- package/dist/ui/assets/shiki-lang-splunk-CuMQ-bQj.js +1 -0
- package/dist/ui/assets/shiki-lang-sql-D_91z_KC.js +1 -0
- package/dist/ui/assets/shiki-lang-ssh-config-E7f5J40j.js +1 -0
- package/dist/ui/assets/shiki-lang-stata-CcxlnAAd.js +1 -0
- package/dist/ui/assets/shiki-lang-stylus-QdNMd2Ol.js +1 -0
- package/dist/ui/assets/shiki-lang-surrealql-BY3L-U6I.js +1 -0
- package/dist/ui/assets/shiki-lang-svelte-BraYXbN1.js +1 -0
- package/dist/ui/assets/shiki-lang-swift-GBk9P9bD.js +1 -0
- package/dist/ui/assets/shiki-lang-system-verilog-CcFNB-9G.js +1 -0
- package/dist/ui/assets/shiki-lang-systemd-CfyxEp-3.js +1 -0
- package/dist/ui/assets/shiki-lang-talonscript-EiloZNHt.js +1 -0
- package/dist/ui/assets/shiki-lang-tasl-D2hiq4aP.js +1 -0
- package/dist/ui/assets/shiki-lang-tcl-DmPeea8t.js +1 -0
- package/dist/ui/assets/shiki-lang-templ-CNQsuMTo.js +1 -0
- package/dist/ui/assets/shiki-lang-terraform-Bk9FujxB.js +1 -0
- package/dist/ui/assets/shiki-lang-tex-DqCIQlTN.js +1 -0
- package/dist/ui/assets/shiki-lang-toml-CTaoLtIw.js +1 -0
- package/dist/ui/assets/shiki-lang-ts-tags-kbOGoo3o.js +1 -0
- package/dist/ui/assets/shiki-lang-tsv-n2qFIoSV.js +1 -0
- package/dist/ui/assets/shiki-lang-tsx-DHN5AfF-.js +1 -0
- package/dist/ui/assets/shiki-lang-turtle-BhxMO6m_.js +1 -0
- package/dist/ui/assets/shiki-lang-twig-BI3wu5j1.js +1 -0
- package/dist/ui/assets/shiki-lang-typescript-Bi84_wAX.js +1 -0
- package/dist/ui/assets/shiki-lang-typespec-BUSudTwB.js +1 -0
- package/dist/ui/assets/shiki-lang-typst-BeQRnfsh.js +1 -0
- package/dist/ui/assets/shiki-lang-v-DcmtCCfh.js +1 -0
- package/dist/ui/assets/shiki-lang-vala-ACNpIZyT.js +1 -0
- package/dist/ui/assets/shiki-lang-vb-UxeHUT4-.js +1 -0
- package/dist/ui/assets/shiki-lang-verilog-D_z-DWcI.js +1 -0
- package/dist/ui/assets/shiki-lang-vhdl-DjYxR0oh.js +1 -0
- package/dist/ui/assets/shiki-lang-viml-35sdc6lh.js +1 -0
- package/dist/ui/assets/shiki-lang-vue-CXmuYyCC.js +1 -0
- package/dist/ui/assets/shiki-lang-vue-directives-2-MeLAcz.js +1 -0
- package/dist/ui/assets/shiki-lang-vue-html-D7p54nmB.js +1 -0
- package/dist/ui/assets/shiki-lang-vue-interpolations-D6IW37Bp.js +1 -0
- package/dist/ui/assets/shiki-lang-vue-sfc-style-variable-injection-OrVM63MP.js +1 -0
- package/dist/ui/assets/shiki-lang-vue-vine-jXgUN14Y.js +1 -0
- package/dist/ui/assets/shiki-lang-vyper-CkzXvo5f.js +1 -0
- package/dist/ui/assets/shiki-lang-wasm-YV5MrSFG.js +1 -0
- package/dist/ui/assets/shiki-lang-wenyan-BEAREdij.js +1 -0
- package/dist/ui/assets/shiki-lang-wgsl-DKljNrqo.js +1 -0
- package/dist/ui/assets/shiki-lang-wikitext-zQrLZOLl.js +1 -0
- package/dist/ui/assets/shiki-lang-wit-oxy4vW-x.js +1 -0
- package/dist/ui/assets/shiki-lang-wolfram-CBPWnKO2.js +1 -0
- package/dist/ui/assets/shiki-lang-xml-Dbri-bZ6.js +1 -0
- package/dist/ui/assets/shiki-lang-xsl-HtA9ymS7.js +1 -0
- package/dist/ui/assets/shiki-lang-yaml-CC6ddTCm.js +1 -0
- package/dist/ui/assets/shiki-lang-zenscript-B5ajX4si.js +1 -0
- package/dist/ui/assets/shiki-lang-zig-DXnhftle.js +1 -0
- package/dist/ui/assets/slack-dark-DnToyrRv.js +1 -0
- package/dist/ui/assets/slack-ochin-B2OO5cIa.js +1 -0
- package/dist/ui/assets/snazzy-light-4G7pJPwS.js +1 -0
- package/dist/ui/assets/solarized-dark-UdsmMDCL.js +1 -0
- package/dist/ui/assets/solarized-light-C1IUL_tW.js +1 -0
- package/dist/ui/assets/synthwave-84-nFMaYfgc.js +1 -0
- package/dist/ui/assets/tokyo-night-oM2G3aXe.js +1 -0
- package/dist/ui/assets/vesper-DdrHHSXu.js +1 -0
- package/dist/ui/assets/vitesse-black-fwtXNY1n.js +1 -0
- package/dist/ui/assets/vitesse-dark-BZCL-v6S.js +1 -0
- package/dist/ui/assets/vitesse-light-VbXTXTou.js +1 -0
- package/dist/ui/assets/{wasm-CG6Dc4jp.js → wasm-BnjxR4X6.js} +1 -1
- package/dist/ui/assets/wasm-S0UXjx1m.js +1 -0
- package/dist/ui/assets/worker-DrorqVhi.js +162 -0
- package/dist/ui/index.html +3 -2
- package/dist/ui/shiki-langs.json +1 -1
- package/package.json +19 -12
- package/skills/comprehende/SKILL.md +11 -9
- package/skills/comprehende/references/example.md +5 -0
- package/skills/comprehende/references/review.schema.json +58 -49
- package/dist/ui/assets/andromeeda-C4gqWexZ.js +0 -1
- package/dist/ui/assets/aurora-x-D-2ljcwZ.js +0 -1
- package/dist/ui/assets/ayu-dark-DYE7WIF3.js +0 -1
- package/dist/ui/assets/ayu-light-BA47KaF1.js +0 -1
- package/dist/ui/assets/ayu-mirage-32ctXXKs.js +0 -1
- package/dist/ui/assets/catppuccin-frappe-CZL1YF0i.js +0 -1
- package/dist/ui/assets/catppuccin-latte-DH-8KZSZ.js +0 -1
- package/dist/ui/assets/catppuccin-macchiato-B7yYVSCf.js +0 -1
- package/dist/ui/assets/catppuccin-mocha-Ct7hS0mc.js +0 -1
- package/dist/ui/assets/dark-plus-C3mMm8J8.js +0 -1
- package/dist/ui/assets/dracula-BzJJZx-M.js +0 -1
- package/dist/ui/assets/dracula-soft-BXkSAIEj.js +0 -1
- package/dist/ui/assets/everforest-dark-BgDCqdQA.js +0 -1
- package/dist/ui/assets/everforest-light-C8M2exoo.js +0 -1
- package/dist/ui/assets/github-dark-DHJKELXO.js +0 -1
- package/dist/ui/assets/github-dark-default-Cuk6v7N8.js +0 -1
- package/dist/ui/assets/github-dark-dimmed-DH5Ifo-i.js +0 -1
- package/dist/ui/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -1
- package/dist/ui/assets/github-light-DAi9KRSo.js +0 -1
- package/dist/ui/assets/github-light-default-D7oLnXFd.js +0 -1
- package/dist/ui/assets/github-light-high-contrast-BfjtVDDH.js +0 -1
- package/dist/ui/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -1
- package/dist/ui/assets/gruvbox-dark-medium-GsRaNv29.js +0 -1
- package/dist/ui/assets/gruvbox-dark-soft-CVdnzihN.js +0 -1
- package/dist/ui/assets/gruvbox-light-hard-CH1njM8p.js +0 -1
- package/dist/ui/assets/gruvbox-light-medium-DRw_LuNl.js +0 -1
- package/dist/ui/assets/gruvbox-light-soft-hJgmCMqR.js +0 -1
- package/dist/ui/assets/horizon-BUw7H-hv.js +0 -1
- package/dist/ui/assets/horizon-bright-CUuTKBJd.js +0 -1
- package/dist/ui/assets/houston-DnULxvSX.js +0 -1
- package/dist/ui/assets/index-C1EoRByu.css +0 -1
- package/dist/ui/assets/index-DczIQS6v.js +0 -1713
- package/dist/ui/assets/kanagawa-dragon-BuwD2xS4.js +0 -1
- package/dist/ui/assets/kanagawa-lotus-C3DzagqV.js +0 -1
- package/dist/ui/assets/kanagawa-wave-DFGoQZhC.js +0 -1
- package/dist/ui/assets/laserwave-DUszq2jm.js +0 -1
- package/dist/ui/assets/light-plus-B7mTdjB0.js +0 -1
- package/dist/ui/assets/material-theme-D5KoaKCx.js +0 -1
- package/dist/ui/assets/material-theme-darker-BfHTSMKl.js +0 -1
- package/dist/ui/assets/material-theme-lighter-B0m2ddpp.js +0 -1
- package/dist/ui/assets/material-theme-ocean-CyktbL80.js +0 -1
- package/dist/ui/assets/material-theme-palenight-Csfq5Kiy.js +0 -1
- package/dist/ui/assets/min-dark-CafNBF8u.js +0 -1
- package/dist/ui/assets/min-light-CTRr51gU.js +0 -1
- package/dist/ui/assets/monokai-BRVnQi9A.js +0 -1
- package/dist/ui/assets/night-owl-C39BiMTA.js +0 -1
- package/dist/ui/assets/night-owl-light-CMTm3GFP.js +0 -1
- package/dist/ui/assets/nord-Ddv68eIx.js +0 -1
- package/dist/ui/assets/one-dark-pro-DVMEJ2y_.js +0 -1
- package/dist/ui/assets/one-light-C3Wv6jpd.js +0 -1
- package/dist/ui/assets/pierre-dark-CyvmCCZW.js +0 -1
- package/dist/ui/assets/pierre-dark-protanopia-deuteranopia-Rgc0TwpF.js +0 -1
- package/dist/ui/assets/pierre-dark-soft-BHGpRqa4.js +0 -1
- package/dist/ui/assets/pierre-dark-tritanopia-Beq2gCRQ.js +0 -1
- package/dist/ui/assets/pierre-dark-vibrant-BWBVywrn.js +0 -1
- package/dist/ui/assets/pierre-light-480U9XYS.js +0 -1
- package/dist/ui/assets/pierre-light-protanopia-deuteranopia-CaVOBURG.js +0 -1
- package/dist/ui/assets/pierre-light-soft-CVdyfjmI.js +0 -1
- package/dist/ui/assets/pierre-light-tritanopia-B4_gpKOM.js +0 -1
- package/dist/ui/assets/pierre-light-vibrant-DdTDNdfJ.js +0 -1
- package/dist/ui/assets/plastic-3e1v2bzS.js +0 -1
- package/dist/ui/assets/poimandres-CS3Unz2-.js +0 -1
- package/dist/ui/assets/red-hvxz__6c.js +0 -1
- package/dist/ui/assets/rose-pine-5qJOZa0Y.js +0 -1
- package/dist/ui/assets/rose-pine-dawn-zx0QlTCp.js +0 -1
- package/dist/ui/assets/rose-pine-moon-C9pEdX9L.js +0 -1
- package/dist/ui/assets/shiki-lang-abap-BdImnpbu.js +0 -1
- package/dist/ui/assets/shiki-lang-actionscript-3-B3316cI-.js +0 -1
- package/dist/ui/assets/shiki-lang-ada-bCR0ucgS.js +0 -1
- package/dist/ui/assets/shiki-lang-ahk-CsyLZFj1.js +0 -1
- package/dist/ui/assets/shiki-lang-ahk2-8Zs4aa1G.js +0 -1
- package/dist/ui/assets/shiki-lang-angular-expression-18AzvmH7.js +0 -1
- package/dist/ui/assets/shiki-lang-angular-html-QylgGsSV.js +0 -1
- package/dist/ui/assets/shiki-lang-angular-inline-style-CLIjy_D1.js +0 -1
- package/dist/ui/assets/shiki-lang-angular-inline-template-DivDh-Md.js +0 -1
- package/dist/ui/assets/shiki-lang-angular-let-declaration-D-jsw5PQ.js +0 -1
- package/dist/ui/assets/shiki-lang-angular-template-D8JUSKlm.js +0 -1
- package/dist/ui/assets/shiki-lang-angular-template-blocks-CGYc0CHO.js +0 -1
- package/dist/ui/assets/shiki-lang-angular-ts-DYfXTSRq.js +0 -1
- package/dist/ui/assets/shiki-lang-apache-Pmp26Uib.js +0 -1
- package/dist/ui/assets/shiki-lang-apex-DhZFqWV2.js +0 -1
- package/dist/ui/assets/shiki-lang-apl-D33AMsfu.js +0 -1
- package/dist/ui/assets/shiki-lang-applescript-Co6uUVPk.js +0 -1
- package/dist/ui/assets/shiki-lang-ara-BRHolxvo.js +0 -1
- package/dist/ui/assets/shiki-lang-asciidoc-CSVQ5wI8.js +0 -1
- package/dist/ui/assets/shiki-lang-asm-D_Q5rh1f.js +0 -1
- package/dist/ui/assets/shiki-lang-astro-C5iwtRWy.js +0 -1
- package/dist/ui/assets/shiki-lang-awk-DMzUqQB5.js +0 -1
- package/dist/ui/assets/shiki-lang-ballerina-BFfxhgS-.js +0 -1
- package/dist/ui/assets/shiki-lang-bat-CickPsom.js +0 -1
- package/dist/ui/assets/shiki-lang-beancount-k_qm7-4y.js +0 -1
- package/dist/ui/assets/shiki-lang-berry-uYugtg8r.js +0 -1
- package/dist/ui/assets/shiki-lang-bibtex-CHM0blh-.js +0 -1
- package/dist/ui/assets/shiki-lang-bicep-Bmn6On1c.js +0 -1
- package/dist/ui/assets/shiki-lang-bird2-Bx8U0n9b.js +0 -1
- package/dist/ui/assets/shiki-lang-blade-BjANHr7J.js +0 -1
- package/dist/ui/assets/shiki-lang-bsl-yjnClznE.js +0 -1
- package/dist/ui/assets/shiki-lang-c-BIGW1oBm.js +0 -1
- package/dist/ui/assets/shiki-lang-c3-Dp5svz6Z.js +0 -1
- package/dist/ui/assets/shiki-lang-cadence-Bv_4Rxtq.js +0 -1
- package/dist/ui/assets/shiki-lang-cairo-D0VTnW3Z.js +0 -1
- package/dist/ui/assets/shiki-lang-chapel-DEeFbMvd.js +0 -1
- package/dist/ui/assets/shiki-lang-clarity-Dn5IMItf.js +0 -1
- package/dist/ui/assets/shiki-lang-clojure-P80f7IUj.js +0 -1
- package/dist/ui/assets/shiki-lang-cmake-D1j8_8rp.js +0 -1
- package/dist/ui/assets/shiki-lang-cobol-CEHSLdUX.js +0 -1
- package/dist/ui/assets/shiki-lang-codeowners-Bp6g37R7.js +0 -1
- package/dist/ui/assets/shiki-lang-codeql-DsOJ9woJ.js +0 -1
- package/dist/ui/assets/shiki-lang-coffee-C2SFSLa5.js +0 -1
- package/dist/ui/assets/shiki-lang-common-lisp-Cg-RD9OK.js +0 -1
- package/dist/ui/assets/shiki-lang-coq-C7JzOVbR.js +0 -1
- package/dist/ui/assets/shiki-lang-cpp-Czz1CvUk.js +0 -1
- package/dist/ui/assets/shiki-lang-cpp-macro-BytbzYqp.js +0 -1
- package/dist/ui/assets/shiki-lang-crystal-CBpenpwC.js +0 -1
- package/dist/ui/assets/shiki-lang-csharp-DSvCPggb.js +0 -1
- package/dist/ui/assets/shiki-lang-css-CLj8gQPS.js +0 -1
- package/dist/ui/assets/shiki-lang-csv-fuZLfV_i.js +0 -1
- package/dist/ui/assets/shiki-lang-cue-D82EKSYY.js +0 -1
- package/dist/ui/assets/shiki-lang-cypher-COkxafJQ.js +0 -1
- package/dist/ui/assets/shiki-lang-d-85-TOEBH.js +0 -1
- package/dist/ui/assets/shiki-lang-dart-bE4Kk8sk.js +0 -1
- package/dist/ui/assets/shiki-lang-dax-CEL-wOlO.js +0 -1
- package/dist/ui/assets/shiki-lang-desktop-BmXAJ9_W.js +0 -1
- package/dist/ui/assets/shiki-lang-diff-D97Zzqfu.js +0 -1
- package/dist/ui/assets/shiki-lang-docker-BcOcwvcX.js +0 -1
- package/dist/ui/assets/shiki-lang-dotenv-Da5cRb03.js +0 -1
- package/dist/ui/assets/shiki-lang-dream-maker-BtqSS_iP.js +0 -1
- package/dist/ui/assets/shiki-lang-edge-B6n-4du_.js +0 -1
- package/dist/ui/assets/shiki-lang-elixir-B_21P7TP.js +0 -1
- package/dist/ui/assets/shiki-lang-elm-BhwBe0Iz.js +0 -1
- package/dist/ui/assets/shiki-lang-emacs-lisp-C_m_b--Z.js +0 -1
- package/dist/ui/assets/shiki-lang-erb-g6AWwbWh.js +0 -1
- package/dist/ui/assets/shiki-lang-erlang-C1-mE0_u.js +0 -1
- package/dist/ui/assets/shiki-lang-es-tag-css-BEhnidaP.js +0 -1
- package/dist/ui/assets/shiki-lang-es-tag-glsl-BPGpRRbJ.js +0 -1
- package/dist/ui/assets/shiki-lang-es-tag-html-BAAjMQoR.js +0 -1
- package/dist/ui/assets/shiki-lang-es-tag-sql--3_Ne07y.js +0 -1
- package/dist/ui/assets/shiki-lang-es-tag-xml-CbEfPPAn.js +0 -1
- package/dist/ui/assets/shiki-lang-fennel-BYunw83y.js +0 -1
- package/dist/ui/assets/shiki-lang-fish-BvzEVeQv.js +0 -1
- package/dist/ui/assets/shiki-lang-fluent-C4IJs8-o.js +0 -1
- package/dist/ui/assets/shiki-lang-fortran-fixed-form-BtBWY50U.js +0 -1
- package/dist/ui/assets/shiki-lang-fortran-free-form-BxgE0vQu.js +0 -1
- package/dist/ui/assets/shiki-lang-fsharp-6SDwCc8t.js +0 -1
- package/dist/ui/assets/shiki-lang-gdscript-DqcFQ5yU.js +0 -1
- package/dist/ui/assets/shiki-lang-gdshader-DkwncUOv.js +0 -1
- package/dist/ui/assets/shiki-lang-genie-D0YGMca9.js +0 -1
- package/dist/ui/assets/shiki-lang-gherkin-DyxjwDmM.js +0 -1
- package/dist/ui/assets/shiki-lang-git-commit-DavtHCRV.js +0 -1
- package/dist/ui/assets/shiki-lang-git-rebase-Db7FSZFE.js +0 -1
- package/dist/ui/assets/shiki-lang-gleam-BspZqrRM.js +0 -1
- package/dist/ui/assets/shiki-lang-glimmer-js-D_dejnIT.js +0 -1
- package/dist/ui/assets/shiki-lang-glimmer-ts-CK9oT1LX.js +0 -1
- package/dist/ui/assets/shiki-lang-glsl-DgYrmVye.js +0 -1
- package/dist/ui/assets/shiki-lang-gn-n2N0HUVH.js +0 -1
- package/dist/ui/assets/shiki-lang-gnuplot-DdkO51Og.js +0 -1
- package/dist/ui/assets/shiki-lang-go-C27-OAKa.js +0 -1
- package/dist/ui/assets/shiki-lang-graphql-B2fodP1i.js +0 -1
- package/dist/ui/assets/shiki-lang-groovy-gcz8RCvz.js +0 -1
- package/dist/ui/assets/shiki-lang-hack-3fAmn-Yd.js +0 -1
- package/dist/ui/assets/shiki-lang-handlebars-CwuYkNpJ.js +0 -1
- package/dist/ui/assets/shiki-lang-haskell-Df6bDoY_.js +0 -1
- package/dist/ui/assets/shiki-lang-haxe-CfZj7gIn.js +0 -1
- package/dist/ui/assets/shiki-lang-hcl-BWvSN4gD.js +0 -1
- package/dist/ui/assets/shiki-lang-hjson-D5-asLiD.js +0 -1
- package/dist/ui/assets/shiki-lang-hlsl-D3lLCCz7.js +0 -1
- package/dist/ui/assets/shiki-lang-html-derivative-ByDQxhtI.js +0 -1
- package/dist/ui/assets/shiki-lang-http-wB1irth9.js +0 -1
- package/dist/ui/assets/shiki-lang-hurl-C98mAZkp.js +0 -1
- package/dist/ui/assets/shiki-lang-hxml-O4x38oJr.js +0 -1
- package/dist/ui/assets/shiki-lang-hy-DFXneXwc.js +0 -1
- package/dist/ui/assets/shiki-lang-imba-DGztddWO.js +0 -1
- package/dist/ui/assets/shiki-lang-ini-BEwlwnbL.js +0 -1
- package/dist/ui/assets/shiki-lang-java-CylS5w8V.js +0 -1
- package/dist/ui/assets/shiki-lang-javascript-wDzz0qaB.js +0 -1
- package/dist/ui/assets/shiki-lang-jinja-COi1gYwR.js +0 -1
- package/dist/ui/assets/shiki-lang-jinja-html-DzJAgftF.js +0 -1
- package/dist/ui/assets/shiki-lang-jison-CA27ooGo.js +0 -1
- package/dist/ui/assets/shiki-lang-json-Cp-IABpG.js +0 -1
- package/dist/ui/assets/shiki-lang-json5-C9tS-k6U.js +0 -1
- package/dist/ui/assets/shiki-lang-jsonc-Des-eS-w.js +0 -1
- package/dist/ui/assets/shiki-lang-jsonl-DcaNXYhu.js +0 -1
- package/dist/ui/assets/shiki-lang-jsonnet-DFQXde-d.js +0 -1
- package/dist/ui/assets/shiki-lang-jssm-C2t-YnRu.js +0 -1
- package/dist/ui/assets/shiki-lang-jsx-g9-lgVsj.js +0 -1
- package/dist/ui/assets/shiki-lang-julia-DWcJqbPK.js +0 -1
- package/dist/ui/assets/shiki-lang-just-DgUC6AYi.js +0 -1
- package/dist/ui/assets/shiki-lang-kdl-DV7GczEv.js +0 -1
- package/dist/ui/assets/shiki-lang-kotlin-BdnUsdx6.js +0 -1
- package/dist/ui/assets/shiki-lang-kusto-wEQ09or8.js +0 -1
- package/dist/ui/assets/shiki-lang-latex-CmUXxkfy.js +0 -1
- package/dist/ui/assets/shiki-lang-lean-BZvkOJ9d.js +0 -1
- package/dist/ui/assets/shiki-lang-less-B1dDrJ26.js +0 -1
- package/dist/ui/assets/shiki-lang-liquid-BIWOSLXI.js +0 -1
- package/dist/ui/assets/shiki-lang-llvm-BZoOZj88.js +0 -1
- package/dist/ui/assets/shiki-lang-log-2UxHyX5q.js +0 -1
- package/dist/ui/assets/shiki-lang-logo-BtOb2qkB.js +0 -1
- package/dist/ui/assets/shiki-lang-lua-xHKCfFex.js +0 -1
- package/dist/ui/assets/shiki-lang-luau-BnpPk5vE.js +0 -1
- package/dist/ui/assets/shiki-lang-make-CHLpvVh8.js +0 -1
- package/dist/ui/assets/shiki-lang-markdown-Cvjx9yec.js +0 -1
- package/dist/ui/assets/shiki-lang-markdown-nix-BdjWkH0i.js +0 -1
- package/dist/ui/assets/shiki-lang-markdown-vue-B2VTuFQ6.js +0 -1
- package/dist/ui/assets/shiki-lang-marko-CCwpwraH.js +0 -1
- package/dist/ui/assets/shiki-lang-matlab-D7o27uSR.js +0 -1
- package/dist/ui/assets/shiki-lang-mdc-RXLzxXpy.js +0 -1
- package/dist/ui/assets/shiki-lang-mdx-Cmh6b_Ma.js +0 -1
- package/dist/ui/assets/shiki-lang-mermaid-CQcHuHx7.js +0 -1
- package/dist/ui/assets/shiki-lang-mipsasm-CKIfxQSi.js +0 -1
- package/dist/ui/assets/shiki-lang-mojo-DJz3ZmWd.js +0 -1
- package/dist/ui/assets/shiki-lang-moonbit-CHtswR0a.js +0 -1
- package/dist/ui/assets/shiki-lang-move-el3G9tDJ.js +0 -1
- package/dist/ui/assets/shiki-lang-narrat-DRg8JJMk.js +0 -1
- package/dist/ui/assets/shiki-lang-nextflow-D1Hwl2jV.js +0 -1
- package/dist/ui/assets/shiki-lang-nextflow-groovy-vE_lwT2v.js +0 -1
- package/dist/ui/assets/shiki-lang-nginx-CdnGOWaL.js +0 -1
- package/dist/ui/assets/shiki-lang-nim-OOUtdPk6.js +0 -1
- package/dist/ui/assets/shiki-lang-nix-CB_6xJbh.js +0 -1
- package/dist/ui/assets/shiki-lang-nsis-BlV79W_Q.js +0 -1
- package/dist/ui/assets/shiki-lang-nushell-D3jzshHO.js +0 -1
- package/dist/ui/assets/shiki-lang-objective-c-DXmwc3jG.js +0 -1
- package/dist/ui/assets/shiki-lang-objective-cpp-CLxacb5B.js +0 -1
- package/dist/ui/assets/shiki-lang-ocaml-C0hk2d4L.js +0 -1
- package/dist/ui/assets/shiki-lang-odin-BBf5iR-q.js +0 -1
- package/dist/ui/assets/shiki-lang-openscad-C4EeE6gA.js +0 -1
- package/dist/ui/assets/shiki-lang-org-B2im9gxM.js +0 -1
- package/dist/ui/assets/shiki-lang-pascal-D93ZcfNL.js +0 -1
- package/dist/ui/assets/shiki-lang-perl-BOHVV1HZ.js +0 -1
- package/dist/ui/assets/shiki-lang-php-DjAfRze_.js +0 -1
- package/dist/ui/assets/shiki-lang-pkl-u5AG7uiY.js +0 -1
- package/dist/ui/assets/shiki-lang-plsql-ChMvpjG-.js +0 -1
- package/dist/ui/assets/shiki-lang-po-BTJTHyun.js +0 -1
- package/dist/ui/assets/shiki-lang-polar-C0HS_06l.js +0 -1
- package/dist/ui/assets/shiki-lang-postcss-CXtECtnM.js +0 -1
- package/dist/ui/assets/shiki-lang-powerquery-CEu0bR-o.js +0 -1
- package/dist/ui/assets/shiki-lang-powershell-BmBUJMz7.js +0 -1
- package/dist/ui/assets/shiki-lang-prisma-Vru482bI.js +0 -1
- package/dist/ui/assets/shiki-lang-prolog-CbFg5uaA.js +0 -1
- package/dist/ui/assets/shiki-lang-proto-C7zT0LnQ.js +0 -1
- package/dist/ui/assets/shiki-lang-pug-a5xe6YCG.js +0 -1
- package/dist/ui/assets/shiki-lang-puppet-BMWR74SV.js +0 -1
- package/dist/ui/assets/shiki-lang-purescript-CklMAg4u.js +0 -1
- package/dist/ui/assets/shiki-lang-python-B6aJPvgy.js +0 -1
- package/dist/ui/assets/shiki-lang-qml-4gxL1odC.js +0 -1
- package/dist/ui/assets/shiki-lang-qmldir-C8lEn-DE.js +0 -1
- package/dist/ui/assets/shiki-lang-qss-IeuSbFQv.js +0 -1
- package/dist/ui/assets/shiki-lang-r-Cf5RLm7j.js +0 -1
- package/dist/ui/assets/shiki-lang-racket-BqYA7rlc.js +0 -1
- package/dist/ui/assets/shiki-lang-raku-DXvB9xmW.js +0 -1
- package/dist/ui/assets/shiki-lang-razor-BBzT8ybq.js +0 -1
- package/dist/ui/assets/shiki-lang-rbs-CpoqiR4B.js +0 -1
- package/dist/ui/assets/shiki-lang-reg-C-SQnVFl.js +0 -1
- package/dist/ui/assets/shiki-lang-regexp-CDVJQ6XC.js +0 -1
- package/dist/ui/assets/shiki-lang-rel-C3B-1QV4.js +0 -1
- package/dist/ui/assets/shiki-lang-riscv-BM1_JUlF.js +0 -1
- package/dist/ui/assets/shiki-lang-ron-D8l8udqQ.js +0 -1
- package/dist/ui/assets/shiki-lang-rosmsg-BJDFO7_C.js +0 -1
- package/dist/ui/assets/shiki-lang-rst-Bp6ncCmx.js +0 -1
- package/dist/ui/assets/shiki-lang-ruby-BZIZ_1-x.js +0 -1
- package/dist/ui/assets/shiki-lang-rust-B1yitclQ.js +0 -1
- package/dist/ui/assets/shiki-lang-sas-yO3CuBDk.js +0 -1
- package/dist/ui/assets/shiki-lang-sass-Cj5Yp3dK.js +0 -1
- package/dist/ui/assets/shiki-lang-scala-CqE71os6.js +0 -1
- package/dist/ui/assets/shiki-lang-scheme-C98Dy4si.js +0 -1
- package/dist/ui/assets/shiki-lang-scss-m-4-QPZd.js +0 -1
- package/dist/ui/assets/shiki-lang-sdbl-DVxCFoDh.js +0 -1
- package/dist/ui/assets/shiki-lang-shaderlab-BoRclLx6.js +0 -1
- package/dist/ui/assets/shiki-lang-shellscript-Yzrsuije.js +0 -1
- package/dist/ui/assets/shiki-lang-shellsession-BhTOBsOq.js +0 -1
- package/dist/ui/assets/shiki-lang-smalltalk-BOQMe2GC.js +0 -1
- package/dist/ui/assets/shiki-lang-smithy-cds9vsN8.js +0 -1
- package/dist/ui/assets/shiki-lang-solidity-DijEV5ha.js +0 -1
- package/dist/ui/assets/shiki-lang-soy-D1j1eck3.js +0 -1
- package/dist/ui/assets/shiki-lang-sparql-D_PtPRod.js +0 -1
- package/dist/ui/assets/shiki-lang-splunk-BtCnVYZw.js +0 -1
- package/dist/ui/assets/shiki-lang-sql-CRqJ_cUM.js +0 -1
- package/dist/ui/assets/shiki-lang-ssh-config-_ykCGR6B.js +0 -1
- package/dist/ui/assets/shiki-lang-stata-CqWsybMy.js +0 -1
- package/dist/ui/assets/shiki-lang-stylus-BEDo0Tqx.js +0 -1
- package/dist/ui/assets/shiki-lang-surrealql-B6Ue5sS6.js +0 -1
- package/dist/ui/assets/shiki-lang-svelte-rGUXZTmH.js +0 -1
- package/dist/ui/assets/shiki-lang-swift-C2oV4EkX.js +0 -1
- package/dist/ui/assets/shiki-lang-system-verilog-0hqHdDBg.js +0 -1
- package/dist/ui/assets/shiki-lang-systemd-4A_iFExJ.js +0 -1
- package/dist/ui/assets/shiki-lang-talonscript-CkByrt1z.js +0 -1
- package/dist/ui/assets/shiki-lang-tasl-QIJgUcNo.js +0 -1
- package/dist/ui/assets/shiki-lang-tcl-dwOrl1Do.js +0 -1
- package/dist/ui/assets/shiki-lang-templ-B4iNmN4w.js +0 -1
- package/dist/ui/assets/shiki-lang-terraform-BETggiCN.js +0 -1
- package/dist/ui/assets/shiki-lang-tex-DWfsXeKl.js +0 -1
- package/dist/ui/assets/shiki-lang-toml-vGWfd6FD.js +0 -1
- package/dist/ui/assets/shiki-lang-ts-tags-CLbH6hBz.js +0 -1
- package/dist/ui/assets/shiki-lang-tsv-B_m7g4N7.js +0 -1
- package/dist/ui/assets/shiki-lang-tsx-COt5Ahok.js +0 -1
- package/dist/ui/assets/shiki-lang-turtle-BsS91CYL.js +0 -1
- package/dist/ui/assets/shiki-lang-twig-WIwJS9fZ.js +0 -1
- package/dist/ui/assets/shiki-lang-typescript-BPQ3VLAy.js +0 -1
- package/dist/ui/assets/shiki-lang-typespec-CAFt9gP4.js +0 -1
- package/dist/ui/assets/shiki-lang-typst-CZjGHRRw.js +0 -1
- package/dist/ui/assets/shiki-lang-v-BGw2Nkan.js +0 -1
- package/dist/ui/assets/shiki-lang-vala-CsfeWuGM.js +0 -1
- package/dist/ui/assets/shiki-lang-vb-Cu-pLBUe.js +0 -1
- package/dist/ui/assets/shiki-lang-verilog-nZwndyjY.js +0 -1
- package/dist/ui/assets/shiki-lang-vhdl-CeAyd5Ju.js +0 -1
- package/dist/ui/assets/shiki-lang-viml-CJc9bBzg.js +0 -1
- package/dist/ui/assets/shiki-lang-vue-VBLKUFTw.js +0 -1
- package/dist/ui/assets/shiki-lang-vue-directives-DB6IPGVS.js +0 -1
- package/dist/ui/assets/shiki-lang-vue-html-BZSTfcAd.js +0 -1
- package/dist/ui/assets/shiki-lang-vue-interpolations-B333VrTX.js +0 -1
- package/dist/ui/assets/shiki-lang-vue-sfc-style-variable-injection-COC9CTDq.js +0 -1
- package/dist/ui/assets/shiki-lang-vue-vine-Dwbf9xGA.js +0 -1
- package/dist/ui/assets/shiki-lang-vyper-CDx5xZoG.js +0 -1
- package/dist/ui/assets/shiki-lang-wasm-MzD3tlZU.js +0 -1
- package/dist/ui/assets/shiki-lang-wenyan-BV7otONQ.js +0 -1
- package/dist/ui/assets/shiki-lang-wgsl-Dx-B1_4e.js +0 -1
- package/dist/ui/assets/shiki-lang-wikitext-BhOHFoWU.js +0 -1
- package/dist/ui/assets/shiki-lang-wit-5i3qLPDT.js +0 -1
- package/dist/ui/assets/shiki-lang-wolfram-lXgVvXCa.js +0 -1
- package/dist/ui/assets/shiki-lang-xml-CahHRakx.js +0 -1
- package/dist/ui/assets/shiki-lang-xsl-C0UDC1a3.js +0 -1
- package/dist/ui/assets/shiki-lang-yaml-Buea-lGh.js +0 -1
- package/dist/ui/assets/shiki-lang-zenscript-DVFEvuxE.js +0 -1
- package/dist/ui/assets/shiki-lang-zig-VOosw3JB.js +0 -1
- package/dist/ui/assets/slack-dark-BthQWCQV.js +0 -1
- package/dist/ui/assets/slack-ochin-DqwNpetd.js +0 -1
- package/dist/ui/assets/snazzy-light-Bw305WKR.js +0 -1
- package/dist/ui/assets/solarized-dark-CpvCGNkr.js +0 -1
- package/dist/ui/assets/solarized-light-Dlz6yCKv.js +0 -1
- package/dist/ui/assets/synthwave-84-CbfX1IO0.js +0 -1
- package/dist/ui/assets/tokyo-night-hegEt444.js +0 -1
- package/dist/ui/assets/vesper-DRje8inN.js +0 -1
- package/dist/ui/assets/vitesse-black-Bkuqu6BP.js +0 -1
- package/dist/ui/assets/vitesse-dark-D0r3Knsf.js +0 -1
- package/dist/ui/assets/vitesse-light-CVO1_9PV.js +0 -1
- package/dist/ui/assets/worker-DsKBD11i.js +0 -156
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Comprehende
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/comprehende)
|
|
4
|
+
|
|
3
5
|
Local review assistant for git diffs. Groups changes by review concern and shows them in a fixed UI. Diffs always come from git in the repo you run the CLI in — never from the model, never stored in the review document.
|
|
4
6
|
|
|
5
7
|
## Install the skill
|
|
@@ -40,15 +42,17 @@ This tool is for preventing this cognitive surrender while trying to maintain mo
|
|
|
40
42
|
|
|
41
43
|
`pnpm sync:skill` copies the JSON Schema into `skills-next/comprehende/`, pins `npx comprehende@<version>` there, and mirrors that tree into `.agents/skills/comprehende` so agents in this checkout use the next skill. It does not touch `skills/comprehende/`.
|
|
42
44
|
|
|
43
|
-
`comprehende serve` and `comprehende export` share one UI and one git payload. Serve resolves refs to commit SHAs when it starts, then computes those payloads from the objects on each request. Export writes the same JSON (and image bytes) next to the UI so any static file server can host the review.
|
|
45
|
+
`comprehende serve` and `comprehende export` share one UI and one git payload. Serve resolves refs to commit SHAs when it starts, then computes those payloads from the objects on each request. Export writes the same JSON (and image bytes) next to the UI so any static file server can host the review. The URL hash is the UI location (`#overview`, `#group/<id>`, `#unassigned`, `#lockfiles`), so a refresh or a shared link opens the same view in either mode.
|
|
46
|
+
|
|
47
|
+
This repository publishes those exports to GitHub Pages. A pull request review lives at `https://matemolnar8.github.io/comprehende/pr/<number>/`. A named site lives at `https://matemolnar8.github.io/comprehende/site/<name>/`. Enable Pages once. In the GitHub repo, open Settings, Pages, Deploy from a branch, branch `gh-pages`, folder `/`. A workflow removes the pull request folder when that pull request closes, and drops sites older than 30 days.
|
|
44
48
|
|
|
45
|
-
`pnpm dev` and `pnpm exec` run with this package as cwd, so they only make sense when _this_ repo is the one under review. To review a different project from a checkout, `cd` into it and run `npx comprehende@0.
|
|
49
|
+
`pnpm dev` and `pnpm exec` run with this package as cwd, so they only make sense when _this_ repo is the one under review. To review a different project from a checkout, `cd` into it and run `npx comprehende@0.8.0` (or `node /path/to/comprehende/dist/cli/main.js` after `pnpm build`).
|
|
46
50
|
|
|
47
51
|
## Release
|
|
48
52
|
|
|
49
53
|
Edit the skill in `skills-next/comprehende/`. `npx skills add` reads `skills/comprehende/` only.
|
|
50
54
|
|
|
51
|
-
Bump `version` in `package.json` when the CLI or UI changes, then run `pnpm sync:skill` so the next skill pin matches. Pre-commit and `pnpm test` fail if the staged package version and next skill pin differ. Do not bump for skill-only edits.
|
|
55
|
+
Bump `version` in `package.json` when the CLI or UI changes, then run `pnpm sync:skill` so the next skill pin matches. Pre-commit and `pnpm test` fail if the staged package version and next skill pin differ. Do not bump for skill-only edits. Use the number the user names. If they name none, use the next semver: patch for fixes, minor for new use, major for breaking.
|
|
52
56
|
|
|
53
57
|
When that next skill should ship with `npx skills add`, run `pnpm release:skill`. That copies `skills-next/comprehende/` onto `skills/comprehende/`. Run it in the same change that publishes a new CLI. Then `npx skills add` installs instructions that match the package they pin.
|
|
54
58
|
|
package/dist/api/agent-md.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
+
import { formatHunkRef } from "../schema/identity.js";
|
|
2
|
+
import { padIndex, sizeLabel } from "../schema/types.js";
|
|
3
|
+
import { agentMdGroupHref } from "./paths.js";
|
|
1
4
|
export const AGENT_MD_MEDIA_TYPE = "text/markdown; charset=utf-8";
|
|
2
|
-
export
|
|
3
|
-
const rename = ref.oldPath !== undefined ? `${ref.oldPath} -> ` : "";
|
|
4
|
-
return `${rename}${ref.path} @@ -${ref.oldStart},${ref.oldLines} +${ref.newStart},${ref.newLines} @@`;
|
|
5
|
-
}
|
|
5
|
+
export { formatHunkRef };
|
|
6
6
|
export function isImageSlot(ref) {
|
|
7
7
|
return ref.oldStart === 0 && ref.oldLines === 0 && ref.newStart === 0 && ref.newLines === 0;
|
|
8
8
|
}
|
|
9
9
|
export function agentClipboardPrompt(url) {
|
|
10
10
|
return `Answer the following questions by using ${url}`;
|
|
11
11
|
}
|
|
12
|
-
function groupAgentMdHref(id) {
|
|
13
|
-
return `groups/${encodeURIComponent(id)}.md`;
|
|
14
|
-
}
|
|
15
12
|
export function agentMd(review, resource) {
|
|
16
13
|
if (resource.target === "overview") {
|
|
17
14
|
return overviewAgentMd(review);
|
|
@@ -28,6 +25,7 @@ function overviewAgentMd(review) {
|
|
|
28
25
|
joinBlocks(["The title:", review.document.title]),
|
|
29
26
|
review.document.why !== undefined ? joinBlocks(["The why:", review.document.why]) : null,
|
|
30
27
|
joinBlocks([`The what (${sizeLabel(review.document.size)}):`, review.document.summary]),
|
|
28
|
+
lookForBlock(review.document.lookFor ?? []),
|
|
31
29
|
reviewConcernsBlock(review),
|
|
32
30
|
]);
|
|
33
31
|
}
|
|
@@ -103,7 +101,7 @@ function coverageBlock(review) {
|
|
|
103
101
|
}
|
|
104
102
|
function reviewConcernsBlock(review) {
|
|
105
103
|
const sections = review.groups.map((group, i) => {
|
|
106
|
-
const href =
|
|
104
|
+
const href = agentMdGroupHref(group.id);
|
|
107
105
|
return joinBlocks([
|
|
108
106
|
`### ${padIndex(i + 1)} ${group.title} (\`${group.id}\`)`,
|
|
109
107
|
group.summary,
|
|
@@ -159,7 +157,7 @@ function overviewSteps(review) {
|
|
|
159
157
|
"",
|
|
160
158
|
"3. Answer from live git.",
|
|
161
159
|
" Follow those files. Use the why and the what as interpretation. Live git wins when they disagree.",
|
|
162
|
-
` ${
|
|
160
|
+
` ${SHOW_CODE_RULE}`,
|
|
163
161
|
" Done when the answer quotes the live code.",
|
|
164
162
|
].join("\n");
|
|
165
163
|
}
|
|
@@ -179,7 +177,7 @@ function groupSteps(review) {
|
|
|
179
177
|
"",
|
|
180
178
|
"3. Answer from live git.",
|
|
181
179
|
" Read those hunks. Use the why and the what as interpretation. Live git wins when they disagree.",
|
|
182
|
-
` ${
|
|
180
|
+
` ${SHOW_CODE_RULE}`,
|
|
183
181
|
" Done when the answer quotes the live code.",
|
|
184
182
|
].join("\n");
|
|
185
183
|
}
|
|
@@ -191,15 +189,7 @@ function resolveShaSteps(review) {
|
|
|
191
189
|
" Done when both objects exist.",
|
|
192
190
|
];
|
|
193
191
|
}
|
|
194
|
-
|
|
195
|
-
return "When you show code, quote the live git lines.";
|
|
196
|
-
}
|
|
197
|
-
function padIndex(index) {
|
|
198
|
-
return String(index).padStart(2, "0");
|
|
199
|
-
}
|
|
200
|
-
function sizeLabel(size) {
|
|
201
|
-
return size.replace("-", " ");
|
|
202
|
-
}
|
|
192
|
+
const SHOW_CODE_RULE = "When you show code, quote the live git lines.";
|
|
203
193
|
function joinBlocks(parts) {
|
|
204
194
|
return parts.filter((part) => part !== null && part !== undefined && part.length > 0).join("\n\n");
|
|
205
195
|
}
|
package/dist/api/live.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadDocument } from "../
|
|
1
|
+
import { loadDocument } from "../review/load.js";
|
|
2
2
|
import { blameFile } from "../git/blame.js";
|
|
3
3
|
import { readImageBlob } from "../git/blob.js";
|
|
4
4
|
import { fileLanguage, filePatchFromGit, readPathDiff, toHunkRef } from "../git/diff.js";
|
|
@@ -12,12 +12,13 @@ import { isLockfilePath } from "../schema/lockfile.js";
|
|
|
12
12
|
import { sourceCitationErrors } from "../schema/source.js";
|
|
13
13
|
import { AGENT_MD_MEDIA_TYPE, agentMd } from "./agent-md.js";
|
|
14
14
|
import { ApiError } from "./error.js";
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
import { REVIEW_BUCKETS } from "./types.js";
|
|
16
|
+
export async function pinReviewSource(cwd, data) {
|
|
17
|
+
const document = typeof data === "string" ? await loadDocument(data) : data;
|
|
17
18
|
return pinRange(cwd, document.source.baseRef, document.source.headRef);
|
|
18
19
|
}
|
|
19
|
-
export async function openReview(cwd,
|
|
20
|
-
const document = await loadDocument(
|
|
20
|
+
export async function openReview(cwd, data, pin) {
|
|
21
|
+
const document = typeof data === "string" ? await loadDocument(data) : data;
|
|
21
22
|
const range = pin ?? (await pinRange(cwd, document.source.baseRef, document.source.headRef));
|
|
22
23
|
const { files, coverage } = await coverReview(cwd, document, range);
|
|
23
24
|
const pins = await staleCommentPins(cwd, document, range);
|
|
@@ -110,10 +111,10 @@ export function hunksPayload(ctx, groupId) {
|
|
|
110
111
|
if (groupId === "") {
|
|
111
112
|
throw new ApiError(400, "missing group");
|
|
112
113
|
}
|
|
113
|
-
if (groupId ===
|
|
114
|
+
if (groupId === REVIEW_BUCKETS.unassigned) {
|
|
114
115
|
return serializeGroup(ctx.files, ctx.coverage.unassigned);
|
|
115
116
|
}
|
|
116
|
-
if (groupId ===
|
|
117
|
+
if (groupId === REVIEW_BUCKETS.lockfiles) {
|
|
117
118
|
return serializeLockfiles(ctx.files);
|
|
118
119
|
}
|
|
119
120
|
const group = ctx.coverage.groups.find((item) => item.group.id === groupId);
|
|
@@ -198,8 +199,8 @@ export function listResources(ctx) {
|
|
|
198
199
|
const resources = [
|
|
199
200
|
{ kind: "review" },
|
|
200
201
|
{ kind: "agent-md", target: "overview" },
|
|
201
|
-
{ kind: "hunks", group:
|
|
202
|
-
{ kind: "hunks", group:
|
|
202
|
+
{ kind: "hunks", group: REVIEW_BUCKETS.unassigned },
|
|
203
|
+
{ kind: "hunks", group: REVIEW_BUCKETS.lockfiles },
|
|
203
204
|
];
|
|
204
205
|
for (const group of ctx.document.groups) {
|
|
205
206
|
resources.push({ kind: "hunks", group: group.id });
|
|
@@ -260,12 +261,20 @@ async function patchPayload(ctx, path) {
|
|
|
260
261
|
if (!isLockfilePath(file.path) || file.binary || file.image) {
|
|
261
262
|
throw new ApiError(404, "path is not a deferred lockfile");
|
|
262
263
|
}
|
|
263
|
-
const live = await
|
|
264
|
+
const live = await readPathDiffSafe(ctx, file.path);
|
|
264
265
|
if (live === undefined) {
|
|
265
266
|
throw new ApiError(404, `no live diff for ${path}`);
|
|
266
267
|
}
|
|
267
268
|
return serializeGroupFile(live, live.hunks, false);
|
|
268
269
|
}
|
|
270
|
+
async function readPathDiffSafe(ctx, path) {
|
|
271
|
+
try {
|
|
272
|
+
return await readPathDiff(ctx.cwd, ctx.resolved.baseSha, ctx.resolved.headSha, path);
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
throw new ApiError(404, error instanceof Error ? error.message : "diff not available");
|
|
276
|
+
}
|
|
277
|
+
}
|
|
269
278
|
function serializeGroupFile(file, fileHunks, deferLockfile) {
|
|
270
279
|
const lockfile = isLockfilePath(file.path) && !file.binary && !file.image;
|
|
271
280
|
const deferred = deferLockfile && lockfile;
|
|
@@ -317,9 +326,10 @@ function uniquePaths(hunks) {
|
|
|
317
326
|
export function snapshotJson(body) {
|
|
318
327
|
return `${JSON.stringify(body)}\n`;
|
|
319
328
|
}
|
|
329
|
+
/** 404 (and transient git failures) mean the live object moved. Skip it in export. 400 is a bad request, not a skip. */
|
|
320
330
|
export function isUnavailableSnapshot(error) {
|
|
321
331
|
if (error instanceof ApiError) {
|
|
322
|
-
return error.status === 404
|
|
332
|
+
return error.status === 404;
|
|
323
333
|
}
|
|
324
334
|
return error instanceof GitError;
|
|
325
335
|
}
|
package/dist/api/paths.js
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
1
|
+
import { isSourceSide } from "../schema/types.js";
|
|
1
2
|
export function apiHref(resource) {
|
|
2
|
-
|
|
3
|
-
case "review":
|
|
4
|
-
return "api/review.json";
|
|
5
|
-
case "agent-md":
|
|
6
|
-
return agentMdRel(resource);
|
|
7
|
-
case "hunks":
|
|
8
|
-
return `api/hunks/${encodeURIComponent(resource.group)}.json`;
|
|
9
|
-
case "file":
|
|
10
|
-
return `api/files/${resource.side}/${encodeFilePath(resource.path)}.json`;
|
|
11
|
-
case "blame":
|
|
12
|
-
return `api/blame/${resource.side}/${encodeFilePath(resource.path)}.json`;
|
|
13
|
-
case "image":
|
|
14
|
-
return `api/images/${resource.side}/${encodeFilePath(resource.path)}`;
|
|
15
|
-
case "patch":
|
|
16
|
-
return `api/patches/${encodeFilePath(resource.path)}.json`;
|
|
17
|
-
}
|
|
3
|
+
return apiRel(resource, true);
|
|
18
4
|
}
|
|
19
5
|
/** Decoded relative path under the site root. Static hosts map encoded request URLs onto this. */
|
|
20
6
|
export function apiFsRel(resource) {
|
|
7
|
+
return apiRel(resource, false);
|
|
8
|
+
}
|
|
9
|
+
/** Relative link from overview.md to a group file. Overview lives in api/agent, groups live in api/agent/groups. */
|
|
10
|
+
export function agentMdGroupHref(group) {
|
|
11
|
+
return `groups/${encodeURIComponent(group)}.md`;
|
|
12
|
+
}
|
|
13
|
+
function apiRel(resource, encodeFiles) {
|
|
14
|
+
const filePath = (path) => (encodeFiles ? encodeFilePath(path) : path);
|
|
21
15
|
switch (resource.kind) {
|
|
22
16
|
case "review":
|
|
23
17
|
return "api/review.json";
|
|
@@ -26,13 +20,13 @@ export function apiFsRel(resource) {
|
|
|
26
20
|
case "hunks":
|
|
27
21
|
return `api/hunks/${encodeURIComponent(resource.group)}.json`;
|
|
28
22
|
case "file":
|
|
29
|
-
return `api/files/${resource.side}/${resource.path}.json`;
|
|
23
|
+
return `api/files/${resource.side}/${filePath(resource.path)}.json`;
|
|
30
24
|
case "blame":
|
|
31
|
-
return `api/blame/${resource.side}/${resource.path}.json`;
|
|
25
|
+
return `api/blame/${resource.side}/${filePath(resource.path)}.json`;
|
|
32
26
|
case "image":
|
|
33
|
-
return `api/images/${resource.side}/${resource.path}`;
|
|
27
|
+
return `api/images/${resource.side}/${filePath(resource.path)}`;
|
|
34
28
|
case "patch":
|
|
35
|
-
return `api/patches/${resource.path}.json`;
|
|
29
|
+
return `api/patches/${filePath(resource.path)}.json`;
|
|
36
30
|
}
|
|
37
31
|
}
|
|
38
32
|
export function parseApiPath(pathname) {
|
|
@@ -65,11 +59,11 @@ export function parseApiPath(pathname) {
|
|
|
65
59
|
}
|
|
66
60
|
if (parts[1] === "images" && parts.length >= 4 && parts[2] !== undefined) {
|
|
67
61
|
const side = parts[2];
|
|
68
|
-
if (side
|
|
62
|
+
if (!isSourceSide(side)) {
|
|
69
63
|
return undefined;
|
|
70
64
|
}
|
|
71
65
|
const path = parts.slice(3).join("/");
|
|
72
|
-
if (!
|
|
66
|
+
if (!isSafePath(path)) {
|
|
73
67
|
return undefined;
|
|
74
68
|
}
|
|
75
69
|
return { kind: "image", path, side };
|
|
@@ -83,14 +77,14 @@ export function parseApiPath(pathname) {
|
|
|
83
77
|
}
|
|
84
78
|
rest[rest.length - 1] = stem;
|
|
85
79
|
const path = rest.join("/");
|
|
86
|
-
if (!
|
|
80
|
+
if (!isSafePath(path)) {
|
|
87
81
|
return undefined;
|
|
88
82
|
}
|
|
89
83
|
return { kind: "patch", path };
|
|
90
84
|
}
|
|
91
85
|
if ((parts[1] === "files" || parts[1] === "blame") && parts.length >= 4 && parts[2] !== undefined) {
|
|
92
86
|
const side = parts[2];
|
|
93
|
-
if (side
|
|
87
|
+
if (!isSourceSide(side)) {
|
|
94
88
|
return undefined;
|
|
95
89
|
}
|
|
96
90
|
const rest = parts.slice(3);
|
|
@@ -101,7 +95,7 @@ export function parseApiPath(pathname) {
|
|
|
101
95
|
}
|
|
102
96
|
rest[rest.length - 1] = stem;
|
|
103
97
|
const path = rest.join("/");
|
|
104
|
-
if (!
|
|
98
|
+
if (!isSafePath(path)) {
|
|
105
99
|
return undefined;
|
|
106
100
|
}
|
|
107
101
|
return { kind: parts[1] === "files" ? "file" : "blame", path, side };
|
|
@@ -123,22 +117,26 @@ function agentMdRel(resource) {
|
|
|
123
117
|
if (resource.target === "overview") {
|
|
124
118
|
return "api/agent/overview.md";
|
|
125
119
|
}
|
|
126
|
-
return `api/agent
|
|
120
|
+
return `api/agent/${agentMdGroupHref(resource.group)}`;
|
|
127
121
|
}
|
|
128
122
|
function jsonStem(file) {
|
|
129
|
-
|
|
130
|
-
return undefined;
|
|
131
|
-
}
|
|
132
|
-
const stem = file.slice(0, -".json".length);
|
|
133
|
-
return stem === "" ? undefined : stem;
|
|
123
|
+
return stem(file, ".json");
|
|
134
124
|
}
|
|
135
125
|
function mdStem(file) {
|
|
136
|
-
|
|
126
|
+
return stem(file, ".md");
|
|
127
|
+
}
|
|
128
|
+
function stem(file, ext) {
|
|
129
|
+
if (!file.endsWith(ext)) {
|
|
137
130
|
return undefined;
|
|
138
131
|
}
|
|
139
|
-
const
|
|
140
|
-
return
|
|
132
|
+
const bare = file.slice(0, -ext.length);
|
|
133
|
+
return bare === "" ? undefined : bare;
|
|
141
134
|
}
|
|
142
|
-
function
|
|
143
|
-
return path !== "" && !path.startsWith("/") && !path.includes("\0") && !path.split("/").includes("..");
|
|
135
|
+
export function isSafePath(path) {
|
|
136
|
+
return (path.trim() !== "" && !path.startsWith("/") && !path.includes("\0") && !path.split("/").includes(".."));
|
|
137
|
+
}
|
|
138
|
+
export function assertSafePath(path) {
|
|
139
|
+
if (!isSafePath(path)) {
|
|
140
|
+
throw new Error(`invalid path: ${path}`);
|
|
141
|
+
}
|
|
144
142
|
}
|
package/dist/api/types.js
CHANGED
package/dist/cli/args.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
const COMMANDS = new Set(["index", "validate", "serve", "export"]);
|
|
2
|
+
export const DEFAULT_PORT = 4567;
|
|
3
|
+
export class ArgError extends Error {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "ArgError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
2
9
|
export const USAGE = `Usage: comprehende <command> [options]
|
|
3
10
|
|
|
4
11
|
Run inside the git repository under review. Cwd is the repo.
|
|
@@ -22,7 +29,7 @@ Options:
|
|
|
22
29
|
--head <ref> Head ref (default: HEAD)
|
|
23
30
|
--data <path> Review document path
|
|
24
31
|
--out <dir> Output directory for export
|
|
25
|
-
--port <n> Listen port (default:
|
|
32
|
+
--port <n> Listen port (default: ${DEFAULT_PORT}, 0 for ephemeral)
|
|
26
33
|
--open Open the UI in a browser
|
|
27
34
|
-h, --help Show this help
|
|
28
35
|
-v, --version Show version
|
|
@@ -47,9 +54,9 @@ export function parseArgv(argv, cwd = process.cwd()) {
|
|
|
47
54
|
}
|
|
48
55
|
const rest = args.slice(1);
|
|
49
56
|
try {
|
|
50
|
-
const port = Number(flag(rest, "--port") ??
|
|
57
|
+
const port = Number(flag(rest, "--port") ?? String(DEFAULT_PORT));
|
|
51
58
|
if (!Number.isInteger(port) || port < 0) {
|
|
52
|
-
throw new
|
|
59
|
+
throw new ArgError("--port must be a non-negative integer");
|
|
53
60
|
}
|
|
54
61
|
return {
|
|
55
62
|
kind: "command",
|
|
@@ -80,14 +87,14 @@ function flag(args, name) {
|
|
|
80
87
|
if (arg === name) {
|
|
81
88
|
const value = args[i + 1];
|
|
82
89
|
if (value === undefined || value.startsWith("-")) {
|
|
83
|
-
throw new
|
|
90
|
+
throw new ArgError(`${name} requires a value`);
|
|
84
91
|
}
|
|
85
92
|
return value;
|
|
86
93
|
}
|
|
87
94
|
if (arg.startsWith(prefix)) {
|
|
88
95
|
const value = arg.slice(prefix.length);
|
|
89
96
|
if (value === "") {
|
|
90
|
-
throw new
|
|
97
|
+
throw new ArgError(`${name} requires a value`);
|
|
91
98
|
}
|
|
92
99
|
return value;
|
|
93
100
|
}
|
package/dist/cli/commands.js
CHANGED
|
@@ -1,40 +1,17 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { isAbsolute, resolve } from "node:path";
|
|
3
1
|
import { readHunkIndex, resolveSource } from "../git/diff.js";
|
|
4
2
|
import { defaultBaseRef } from "../git/repo.js";
|
|
5
3
|
import { coverReview, coverageErrors } from "../review/coverage.js";
|
|
4
|
+
import { loadDocument, resolveCliPath } from "../review/load.js";
|
|
6
5
|
import { commentPinErrors, staleCommentPins } from "../review/pins.js";
|
|
7
|
-
import { parseReviewJson } from "../schema/parse.js";
|
|
8
6
|
import { sourceCitationErrors } from "../schema/source.js";
|
|
9
|
-
export async function
|
|
7
|
+
export async function cmdIndex(cwd, base, head) {
|
|
10
8
|
const baseRef = base ?? (await defaultBaseRef(cwd));
|
|
11
9
|
const headRef = head ?? "HEAD";
|
|
12
10
|
await resolveSource(cwd, baseRef, headRef);
|
|
13
|
-
return
|
|
14
|
-
}
|
|
15
|
-
export async function cmdIndex(cwd, base, head) {
|
|
16
|
-
const range = await resolveRange(cwd, base, head);
|
|
17
|
-
return readHunkIndex(cwd, range.baseRef, range.headRef);
|
|
18
|
-
}
|
|
19
|
-
export async function loadDocument(dataPath) {
|
|
20
|
-
const text = await readFile(dataPath, "utf8");
|
|
21
|
-
const parsed = parseReviewJson(text);
|
|
22
|
-
if (!parsed.ok) {
|
|
23
|
-
throw new Error(`invalid review document:\n${parsed.errors.map((error) => ` - ${error}`).join("\n")}`);
|
|
24
|
-
}
|
|
25
|
-
return parsed.document;
|
|
26
|
-
}
|
|
27
|
-
export function resolveDataPath(data, cwd) {
|
|
28
|
-
if (data === undefined) {
|
|
29
|
-
throw new Error("missing --data <review.json>");
|
|
30
|
-
}
|
|
31
|
-
return isAbsolute(data) ? data : resolve(cwd, data);
|
|
11
|
+
return readHunkIndex(cwd, baseRef, headRef);
|
|
32
12
|
}
|
|
33
13
|
export function resolveOutPath(out, cwd) {
|
|
34
|
-
|
|
35
|
-
throw new Error("missing --out <dir>");
|
|
36
|
-
}
|
|
37
|
-
return isAbsolute(out) ? out : resolve(cwd, out);
|
|
14
|
+
return resolveCliPath(out, cwd, "--out <dir>");
|
|
38
15
|
}
|
|
39
16
|
export async function cmdValidate(cwd, dataPath) {
|
|
40
17
|
const document = await loadDocument(dataPath);
|
package/dist/cli/main.js
CHANGED
|
@@ -4,7 +4,8 @@ import { realpathSync } from "node:fs";
|
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { parseArgv, USAGE } from "./args.js";
|
|
7
|
-
import { cmdIndex, cmdValidate,
|
|
7
|
+
import { cmdIndex, cmdValidate, resolveOutPath } from "./commands.js";
|
|
8
|
+
import { loadDocument, resolveDataPath } from "../review/load.js";
|
|
8
9
|
import { exportStaticSite } from "../api/snapshot.js";
|
|
9
10
|
import { openReview, pinReviewSource, reviewProblems } from "../api/live.js";
|
|
10
11
|
import { assertWorkTree } from "../git/repo.js";
|
|
@@ -41,8 +42,9 @@ export async function run(argv) {
|
|
|
41
42
|
}
|
|
42
43
|
case "serve": {
|
|
43
44
|
const dataPath = resolveDataPath(request.data, request.cwd);
|
|
44
|
-
const
|
|
45
|
-
const
|
|
45
|
+
const document = await loadDocument(dataPath);
|
|
46
|
+
const pin = await pinReviewSource(request.cwd, document);
|
|
47
|
+
const ctx = await openReview(request.cwd, document, pin);
|
|
46
48
|
warnReview(ctx, "serve continues; git wins, unassigned/stale are visible");
|
|
47
49
|
const running = await startServer({ cwd: request.cwd, dataPath, port: request.port, pin });
|
|
48
50
|
console.log(running.url);
|
|
@@ -56,7 +58,8 @@ export async function run(argv) {
|
|
|
56
58
|
case "export": {
|
|
57
59
|
const dataPath = resolveDataPath(request.data, request.cwd);
|
|
58
60
|
const outDir = resolveOutPath(request.out, request.cwd);
|
|
59
|
-
const
|
|
61
|
+
const document = await loadDocument(dataPath);
|
|
62
|
+
const ctx = await openReview(request.cwd, document);
|
|
60
63
|
warnReview(ctx, "export continues; git wins, unassigned/stale are visible");
|
|
61
64
|
const result = await exportStaticSite({ cwd: request.cwd, dataPath, outDir, ctx });
|
|
62
65
|
console.log(result.outDir);
|
package/dist/git/exec.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
2
|
import { promisify } from "node:util";
|
|
3
3
|
const execFileAsync = promisify(execFile);
|
|
4
|
+
/** Mirrored in scripts/install-git-hooks.js, which runs as plain node without tsx. Update both. */
|
|
4
5
|
const GIT_DIR_VARS = new Set([
|
|
5
6
|
"GIT_DIR",
|
|
6
7
|
"GIT_WORK_TREE",
|
|
@@ -76,13 +77,12 @@ export async function gitOk(cwd, args) {
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
function asExecFailure(error) {
|
|
79
|
-
if (
|
|
80
|
-
const record = error;
|
|
80
|
+
if (isRecord(error)) {
|
|
81
81
|
return {
|
|
82
|
-
message: typeof
|
|
83
|
-
stdout: bufferText(
|
|
84
|
-
stderr: bufferText(
|
|
85
|
-
code: typeof
|
|
82
|
+
message: typeof error.message === "string" ? error.message : "git failed",
|
|
83
|
+
stdout: bufferText(error.stdout),
|
|
84
|
+
stderr: bufferText(error.stderr),
|
|
85
|
+
code: typeof error.code === "number" ? error.code : null,
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
return { message: "git failed", stdout: "", stderr: "", code: null };
|
|
@@ -96,6 +96,9 @@ function bufferText(value) {
|
|
|
96
96
|
}
|
|
97
97
|
return "";
|
|
98
98
|
}
|
|
99
|
+
function isRecord(value) {
|
|
100
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
101
|
+
}
|
|
99
102
|
function gitFailure(args, failure) {
|
|
100
103
|
return new GitError(`git ${args.join(" ")} failed: ${failure.stderr.trim() || failure.message}`, args, failure.stderr, failure.code);
|
|
101
104
|
}
|
package/dist/git/repo.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { basename, dirname, isAbsolute, resolve } from "node:path";
|
|
1
|
+
import { basename as nodeBasename, dirname, isAbsolute, resolve } from "node:path";
|
|
2
|
+
import { assertSafePath, isSafePath } from "../api/paths.js";
|
|
3
|
+
import { basename as posixBasename } from "../schema/types.js";
|
|
2
4
|
import { git, gitOk } from "./exec.js";
|
|
5
|
+
export { assertSafePath, isSafePath };
|
|
3
6
|
export async function assertWorkTree(cwd) {
|
|
4
7
|
const inside = await git(cwd, ["rev-parse", "--is-inside-work-tree"], { allowFail: true });
|
|
5
8
|
if (inside.trim() !== "true") {
|
|
@@ -27,8 +30,8 @@ export function nameFromRemoteUrl(url) {
|
|
|
27
30
|
: value.includes(":")
|
|
28
31
|
? value.slice(value.lastIndexOf(":") + 1)
|
|
29
32
|
: value;
|
|
30
|
-
const last = pathPart
|
|
31
|
-
return last ===
|
|
33
|
+
const last = posixBasename(pathPart);
|
|
34
|
+
return last === "" ? null : last;
|
|
32
35
|
}
|
|
33
36
|
export async function gitCommonDir(cwd) {
|
|
34
37
|
const raw = (await git(cwd, ["rev-parse", "--path-format=absolute", "--git-common-dir"])).trim();
|
|
@@ -41,7 +44,7 @@ export async function readRepoIdentity(cwd) {
|
|
|
41
44
|
if (fromOrigin !== null) {
|
|
42
45
|
return { name: fromOrigin, origin };
|
|
43
46
|
}
|
|
44
|
-
return { name:
|
|
47
|
+
return { name: nodeBasename(dirname(await gitCommonDir(cwd))), origin };
|
|
45
48
|
}
|
|
46
49
|
/** Drop userinfo from an http(s) remote so a copied prompt never carries a token. */
|
|
47
50
|
export function stripRemoteCredentials(url) {
|
|
@@ -93,8 +96,12 @@ export function assertSafeRef(ref) {
|
|
|
93
96
|
throw new Error(`invalid git ref: ${ref}`);
|
|
94
97
|
}
|
|
95
98
|
}
|
|
96
|
-
export function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
export function resolveInsideRoot(root, relative) {
|
|
100
|
+
assertSafePath(relative);
|
|
101
|
+
const rootAbs = resolve(root);
|
|
102
|
+
const abs = resolve(root, relative);
|
|
103
|
+
if (abs !== rootAbs && !abs.startsWith(`${rootAbs}/`)) {
|
|
104
|
+
throw new Error(`invalid path: ${relative}`);
|
|
99
105
|
}
|
|
106
|
+
return abs;
|
|
100
107
|
}
|
package/dist/git/show.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readBlob } from "./blob.js";
|
|
2
2
|
import { assertSafePath, assertSafeRef } from "./repo.js";
|
|
3
|
-
import {
|
|
3
|
+
import { gitOk } from "./exec.js";
|
|
4
4
|
export async function showFile(cwd, ref, path) {
|
|
5
5
|
const bytes = await readBlob(cwd, ref, path);
|
|
6
6
|
return bytes.toString("utf8");
|
|
@@ -8,11 +8,5 @@ export async function showFile(cwd, ref, path) {
|
|
|
8
8
|
export async function fileExistsAt(cwd, ref, path) {
|
|
9
9
|
assertSafeRef(ref);
|
|
10
10
|
assertSafePath(path);
|
|
11
|
-
|
|
12
|
-
await git(cwd, ["cat-file", "-e", `${ref}:${path}`]);
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
11
|
+
return gitOk(cwd, ["cat-file", "-e", `${ref}:${path}`]);
|
|
18
12
|
}
|
package/dist/package-root.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
2
3
|
import { dirname, join } from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
5
|
export function findPackageRoot(from = import.meta.url) {
|
|
@@ -7,7 +8,7 @@ export function findPackageRoot(from = import.meta.url) {
|
|
|
7
8
|
const pkgPath = join(dir, "package.json");
|
|
8
9
|
if (existsSync(pkgPath)) {
|
|
9
10
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
10
|
-
if (pkg.name === "comprehende") {
|
|
11
|
+
if (isRecord(pkg) && pkg.name === "comprehende") {
|
|
11
12
|
return dir;
|
|
12
13
|
}
|
|
13
14
|
}
|
|
@@ -20,6 +21,22 @@ export function findPackageRoot(from = import.meta.url) {
|
|
|
20
21
|
}
|
|
21
22
|
export function readPackageVersion() {
|
|
22
23
|
const pkgPath = join(findPackageRoot(), "package.json");
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
return parsePackageVersion(readFileSync(pkgPath, "utf8"));
|
|
25
|
+
}
|
|
26
|
+
export function parsePackageVersion(text) {
|
|
27
|
+
const parsed = JSON.parse(text);
|
|
28
|
+
if (!isRecord(parsed)) {
|
|
29
|
+
throw new Error("package.json version must be a non-empty string");
|
|
30
|
+
}
|
|
31
|
+
const version = parsed.version;
|
|
32
|
+
if (typeof version !== "string" || version === "") {
|
|
33
|
+
throw new Error("package.json version must be a non-empty string");
|
|
34
|
+
}
|
|
35
|
+
return version;
|
|
36
|
+
}
|
|
37
|
+
export async function readPackageVersionFromDir(root) {
|
|
38
|
+
return parsePackageVersion(await readFile(join(root, "package.json"), "utf8"));
|
|
39
|
+
}
|
|
40
|
+
function isRecord(value) {
|
|
41
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25
42
|
}
|
package/dist/review/coverage.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { flattenHunks, readDiff, toHunkRef } from "../git/diff.js";
|
|
2
2
|
import { pinRange } from "../git/repo.js";
|
|
3
|
-
import { hunkKey } from "../schema/identity.js";
|
|
3
|
+
import { formatHunkRef, hunkKey } from "../schema/identity.js";
|
|
4
4
|
import { isLockfilePath } from "../schema/lockfile.js";
|
|
5
5
|
export async function coverReview(cwd, document, pin) {
|
|
6
6
|
const range = pin ?? (await pinRange(cwd, document.source.baseRef, document.source.headRef));
|
|
@@ -11,7 +11,8 @@ export async function coverReview(cwd, document, pin) {
|
|
|
11
11
|
export function joinCoverage(document, live) {
|
|
12
12
|
const liveByKey = new Map();
|
|
13
13
|
for (const hunk of live) {
|
|
14
|
-
|
|
14
|
+
const key = hunkKey(hunk);
|
|
15
|
+
liveByKey.set(key, hunk);
|
|
15
16
|
}
|
|
16
17
|
const assignedKeys = new Set();
|
|
17
18
|
const allStale = [];
|
|
@@ -22,18 +23,22 @@ export function joinCoverage(document, live) {
|
|
|
22
23
|
if (isLockfilePath(ref.path)) {
|
|
23
24
|
continue;
|
|
24
25
|
}
|
|
25
|
-
const
|
|
26
|
+
const key = hunkKey(ref);
|
|
27
|
+
const match = liveByKey.get(key);
|
|
26
28
|
if (match === undefined) {
|
|
27
29
|
stale.push(ref);
|
|
28
30
|
allStale.push(ref);
|
|
29
31
|
continue;
|
|
30
32
|
}
|
|
31
33
|
hunks.push(match);
|
|
32
|
-
assignedKeys.add(
|
|
34
|
+
assignedKeys.add(key);
|
|
33
35
|
}
|
|
34
36
|
return { group, hunks, stale };
|
|
35
37
|
});
|
|
36
|
-
const unassigned = live.filter((hunk) =>
|
|
38
|
+
const unassigned = live.filter((hunk) => {
|
|
39
|
+
const key = hunkKey(hunk);
|
|
40
|
+
return !assignedKeys.has(key);
|
|
41
|
+
});
|
|
37
42
|
return {
|
|
38
43
|
groups,
|
|
39
44
|
unassigned,
|
|
@@ -53,10 +58,5 @@ export function coverageErrors(coverage) {
|
|
|
53
58
|
return errors;
|
|
54
59
|
}
|
|
55
60
|
function formatRefs(refs) {
|
|
56
|
-
return refs
|
|
57
|
-
.map((ref) => {
|
|
58
|
-
const rename = ref.oldPath !== undefined ? `${ref.oldPath} -> ` : "";
|
|
59
|
-
return ` ${rename}${ref.path} @@ -${ref.oldStart},${ref.oldLines} +${ref.newStart},${ref.newLines} @@`;
|
|
60
|
-
})
|
|
61
|
-
.join("\n");
|
|
61
|
+
return refs.map((ref) => ` ${formatHunkRef(ref)}`).join("\n");
|
|
62
62
|
}
|