@sanurb/ringi 0.2.0 → 0.3.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/dist/cli.mjs +2132 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/mcp.mjs +1057 -0
- package/dist/mcp.mjs.map +1 -0
- package/dist/runtime.mjs +3116 -0
- package/dist/runtime.mjs.map +1 -0
- package/package.json +15 -14
- package/server/nitro.json +17 -0
- package/server/public/assets/ClientOnly-QdfAxyFs.js +1 -0
- package/server/public/assets/_reviewId-CmXHvWLn.js +1 -0
- package/server/public/assets/_reviewId-DdOpDx4U.js +1 -0
- package/server/public/assets/abap-B1dkBSPn.js +1 -0
- package/server/public/assets/action-bar-DLRNvLjj.js +45 -0
- package/server/public/assets/actionscript-3-BT4ibYlP.js +1 -0
- package/server/public/assets/ada-CD92zeps.js +1 -0
- package/server/public/assets/andromeeda-DqSmgxi0.js +1 -0
- package/server/public/assets/angular-html-BDC0PfKr.js +1 -0
- package/server/public/assets/angular-ts-B9yoQMtj.js +1 -0
- package/server/public/assets/apache-D5suuoa_.js +1 -0
- package/server/public/assets/apex-BL-m4VHy.js +1 -0
- package/server/public/assets/apl-CldhY0Pn.js +1 -0
- package/server/public/assets/applescript-CLiBqvKT.js +1 -0
- package/server/public/assets/ara-LdDF8cmv.js +1 -0
- package/server/public/assets/asciidoc-2DZ9hC2N.js +1 -0
- package/server/public/assets/asm-0ZPGRSUy.js +1 -0
- package/server/public/assets/astro-DR6labZJ.js +1 -0
- package/server/public/assets/aurora-x-Da7Zfvbg.js +1 -0
- package/server/public/assets/awk-Bn0gn_B_.js +1 -0
- package/server/public/assets/ayu-dark-bqYKoqpM.js +1 -0
- package/server/public/assets/ayu-light-C45jTIzZ.js +1 -0
- package/server/public/assets/ayu-mirage-BV_FCTQi.js +1 -0
- package/server/public/assets/ballerina-D2nw_w8Q.js +1 -0
- package/server/public/assets/bat-ByUBN5gS.js +1 -0
- package/server/public/assets/beancount-BTb2W6Mp.js +1 -0
- package/server/public/assets/berry-5SO2uITG.js +1 -0
- package/server/public/assets/bibtex-CDBTNfUI.js +1 -0
- package/server/public/assets/bicep-fgxG_4rP.js +1 -0
- package/server/public/assets/bird2-BCwzDhwX.js +1 -0
- package/server/public/assets/blade-BBTRu2-g.js +1 -0
- package/server/public/assets/bsl-CG-fq4sc.js +1 -0
- package/server/public/assets/c-CEvNj7xl.js +1 -0
- package/server/public/assets/c3-Dlaci63_.js +1 -0
- package/server/public/assets/cadence-DHbRuEmm.js +1 -0
- package/server/public/assets/cairo-Ds0kTeYT.js +1 -0
- package/server/public/assets/catppuccin-frappe-DrL1fUuH.js +1 -0
- package/server/public/assets/catppuccin-latte-C0REgVjl.js +1 -0
- package/server/public/assets/catppuccin-macchiato-ChQpylWO.js +1 -0
- package/server/public/assets/catppuccin-mocha-Dd0JU1T0.js +1 -0
- package/server/public/assets/clarity-DMoTOm4G.js +1 -0
- package/server/public/assets/clojure-DBhE3PpS.js +1 -0
- package/server/public/assets/cmake-DwMc40Or.js +1 -0
- package/server/public/assets/cobol-BdNJSMRt.js +1 -0
- package/server/public/assets/codeowners-1lVr8wqV.js +1 -0
- package/server/public/assets/codeql-DWflolvo.js +1 -0
- package/server/public/assets/coffee-RA4xA24H.js +1 -0
- package/server/public/assets/common-lisp-CrVQ5xT-.js +1 -0
- package/server/public/assets/compiler-runtime-DZXZ41-q.js +1 -0
- package/server/public/assets/coq-CjfoyYSh.js +1 -0
- package/server/public/assets/cpp-BoW7e2Ow.js +1 -0
- package/server/public/assets/createServerFn-DTk395iP.js +9 -0
- package/server/public/assets/crystal-CYKRo3F9.js +1 -0
- package/server/public/assets/csharp-C7bIWP5y.js +1 -0
- package/server/public/assets/css-Ck2tii2d.js +1 -0
- package/server/public/assets/csv-DsAkDVtA.js +1 -0
- package/server/public/assets/cue-BWmQgbOB.js +1 -0
- package/server/public/assets/cypher-D-jVC50Q.js +1 -0
- package/server/public/assets/d-CaviyOrm.js +1 -0
- package/server/public/assets/dark-plus-DIrnwZt9.js +1 -0
- package/server/public/assets/dart-CZEi7JgC.js +1 -0
- package/server/public/assets/dax-BK-8zffy.js +1 -0
- package/server/public/assets/desktop-D3cjbL4D.js +1 -0
- package/server/public/assets/diff-sHAzLvlp.js +1 -0
- package/server/public/assets/docker--xs2Ng3w.js +1 -0
- package/server/public/assets/dotenv-Cm4nwcJ7.js +1 -0
- package/server/public/assets/dracula-CAUSusef.js +1 -0
- package/server/public/assets/dracula-soft-cjNkMFza.js +1 -0
- package/server/public/assets/dream-maker-fjmWTFCO.js +1 -0
- package/server/public/assets/edge-DxycC9wl.js +1 -0
- package/server/public/assets/elixir-B-50Er3p.js +1 -0
- package/server/public/assets/elm-B4-ygIVo.js +1 -0
- package/server/public/assets/emacs-lisp-CJzqStIa.js +1 -0
- package/server/public/assets/erb-DJvYE1L1.js +1 -0
- package/server/public/assets/erlang-C-m_88FN.js +1 -0
- package/server/public/assets/everforest-dark-DBpaSMx1.js +1 -0
- package/server/public/assets/everforest-light-CiGrXwia.js +1 -0
- package/server/public/assets/fennel-DRaXF7k8.js +1 -0
- package/server/public/assets/file-tree-CI3Xwwid.js +1907 -0
- package/server/public/assets/fish-Bn-Yh3Jj.js +1 -0
- package/server/public/assets/fluent-DF5F8Ks_.js +1 -0
- package/server/public/assets/fortran-fixed-form-Cx1lv7HN.js +1 -0
- package/server/public/assets/fortran-free-form-hCQHRqew.js +1 -0
- package/server/public/assets/fsharp-DC5k9sy2.js +1 -0
- package/server/public/assets/gdresource-D0EsKdgH.js +1 -0
- package/server/public/assets/gdscript-_C9_Hi_w.js +1 -0
- package/server/public/assets/gdshader-BW7b1X1Y.js +1 -0
- package/server/public/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
- package/server/public/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
- package/server/public/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
- package/server/public/assets/genie-Ch_6TCHd.js +1 -0
- package/server/public/assets/gherkin-CaNUsmTq.js +1 -0
- package/server/public/assets/git-commit-BcFsuO5E.js +1 -0
- package/server/public/assets/git-rebase-ChGA-z50.js +1 -0
- package/server/public/assets/github-dark-B9ygjgg6.js +1 -0
- package/server/public/assets/github-dark-default-Br2bgYSx.js +1 -0
- package/server/public/assets/github-dark-dimmed-CmtqpPJ-.js +1 -0
- package/server/public/assets/github-dark-high-contrast-fSfmrZcC.js +1 -0
- package/server/public/assets/github-light-BZjUqfZl.js +1 -0
- package/server/public/assets/github-light-default-lIytXXhR.js +1 -0
- package/server/public/assets/github-light-high-contrast-BRrjFb7n.js +1 -0
- package/server/public/assets/gleam-DALMDpNs.js +1 -0
- package/server/public/assets/glimmer-js-maLb6ysA.js +1 -0
- package/server/public/assets/glimmer-ts-DGNr-OBA.js +1 -0
- package/server/public/assets/glsl-CmplqyQ1.js +1 -0
- package/server/public/assets/gn-DGjqrYN9.js +1 -0
- package/server/public/assets/gnuplot-BYckvgQI.js +1 -0
- package/server/public/assets/go-JycvP538.js +1 -0
- package/server/public/assets/graphql-VhP7n4--.js +1 -0
- package/server/public/assets/groovy-D5qMRONT.js +1 -0
- package/server/public/assets/gruvbox-dark-hard-M1dj1e6V.js +1 -0
- package/server/public/assets/gruvbox-dark-medium-cqq_ncQu.js +1 -0
- package/server/public/assets/gruvbox-dark-soft-B4QwL2a9.js +1 -0
- package/server/public/assets/gruvbox-light-hard-DLayMKOQ.js +1 -0
- package/server/public/assets/gruvbox-light-medium-D52XgPKf.js +1 -0
- package/server/public/assets/gruvbox-light-soft-Dola3KdD.js +1 -0
- package/server/public/assets/hack-BVSQ2bxM.js +1 -0
- package/server/public/assets/haml-CwTtRHoj.js +1 -0
- package/server/public/assets/handlebars-CcO01SVo.js +1 -0
- package/server/public/assets/haskell-ys7wPPEd.js +1 -0
- package/server/public/assets/haxe-94kiChn7.js +1 -0
- package/server/public/assets/hcl-DmHt_-wq.js +1 -0
- package/server/public/assets/hjson-xMmoJ0Gx.js +1 -0
- package/server/public/assets/hlsl-b-Pskdze.js +1 -0
- package/server/public/assets/horizon-BKMqttiR.js +1 -0
- package/server/public/assets/horizon-bright-HNkBlnm5.js +1 -0
- package/server/public/assets/houston-BkBSBSOQ.js +1 -0
- package/server/public/assets/html-derivative-Cz-cKMi2.js +1 -0
- package/server/public/assets/html-zQbUS8Is.js +1 -0
- package/server/public/assets/http-CaGQ9BgA.js +1 -0
- package/server/public/assets/hurl-BBoki9bg.js +1 -0
- package/server/public/assets/hxml-iQTOTWpM.js +1 -0
- package/server/public/assets/hy-DKl1XhBq.js +1 -0
- package/server/public/assets/imba-DPxkOTAg.js +1 -0
- package/server/public/assets/ini-lkLGq_1x.js +1 -0
- package/server/public/assets/java-LAx6oszV.js +1 -0
- package/server/public/assets/javascript-COqx-gKX.js +1 -0
- package/server/public/assets/jinja-x-G_qSCP.js +1 -0
- package/server/public/assets/jison-7oSeVkKJ.js +1 -0
- package/server/public/assets/json-sTLOVXhc.js +1 -0
- package/server/public/assets/json5-Cy6ypJuJ.js +1 -0
- package/server/public/assets/jsonc-Cw2ugYAK.js +1 -0
- package/server/public/assets/jsonl-Dp5_qBVH.js +1 -0
- package/server/public/assets/jsonnet-BTbmg_-u.js +1 -0
- package/server/public/assets/jssm-CnT7nPea.js +1 -0
- package/server/public/assets/jsx-zXeIBQLI.js +1 -0
- package/server/public/assets/julia-E-6Xm9nd.js +1 -0
- package/server/public/assets/just-D9n74gZy.js +1 -0
- package/server/public/assets/kanagawa-dragon-CxsBnuhV.js +1 -0
- package/server/public/assets/kanagawa-lotus-vHdxDDOS.js +1 -0
- package/server/public/assets/kanagawa-wave-CIkfTKWk.js +1 -0
- package/server/public/assets/kdl-BwK60g80.js +1 -0
- package/server/public/assets/kotlin-Dbd9Vi-v.js +1 -0
- package/server/public/assets/kusto-BuTk9usc.js +1 -0
- package/server/public/assets/laserwave-C0wf_d3o.js +1 -0
- package/server/public/assets/latex-D0t4RtEU.js +1 -0
- package/server/public/assets/lean-CYAW8bRN.js +1 -0
- package/server/public/assets/less-D4uen21c.js +1 -0
- package/server/public/assets/light-plus-oqYyWKEE.js +1 -0
- package/server/public/assets/liquid-BzXN12F6.js +1 -0
- package/server/public/assets/llvm-Z1xJzteV.js +1 -0
- package/server/public/assets/log-BGUxlsk3.js +1 -0
- package/server/public/assets/logo-wVUhvQ1b.js +1 -0
- package/server/public/assets/lua-B0Cg8RP4.js +1 -0
- package/server/public/assets/luau-rPFZzCmq.js +1 -0
- package/server/public/assets/main-FvxVz-kD.js +15 -0
- package/server/public/assets/make-BmPf6m0P.js +1 -0
- package/server/public/assets/markdown-AseU6zcW.js +1 -0
- package/server/public/assets/marko-BlRPXWOe.js +1 -0
- package/server/public/assets/material-theme-6_W6rQhR.js +1 -0
- package/server/public/assets/material-theme-darker-VPEo3Sem.js +1 -0
- package/server/public/assets/material-theme-lighter-CUhzCcZ9.js +1 -0
- package/server/public/assets/material-theme-ocean-B2JdsaGb.js +1 -0
- package/server/public/assets/material-theme-palenight-DhY-sklA.js +1 -0
- package/server/public/assets/matlab-BOj_BDQv.js +1 -0
- package/server/public/assets/mdc-FiVDZSZ4.js +1 -0
- package/server/public/assets/mdx-Cm6cDkDI.js +1 -0
- package/server/public/assets/mermaid-DLO-R4hv.js +1 -0
- package/server/public/assets/min-dark-D34a_pX7.js +1 -0
- package/server/public/assets/min-light-Cdd4KORE.js +1 -0
- package/server/public/assets/mipsasm-DYpHF-GA.js +1 -0
- package/server/public/assets/mojo-DqYVFv_G.js +1 -0
- package/server/public/assets/monokai-CDR4sQ2n.js +1 -0
- package/server/public/assets/moonbit-DRKee9wk.js +1 -0
- package/server/public/assets/move-DbRk6Vn9.js +1 -0
- package/server/public/assets/narrat-IOfmaXfb.js +1 -0
- package/server/public/assets/new-DOyplRwM.js +1 -0
- package/server/public/assets/nextflow-D-Ec_bsY.js +1 -0
- package/server/public/assets/nextflow-groovy-EYl0c2BQ.js +1 -0
- package/server/public/assets/nginx-3JLAqmJa.js +1 -0
- package/server/public/assets/night-owl-light-Bedht9b4.js +1 -0
- package/server/public/assets/night-owl-yQJ3-I0I.js +1 -0
- package/server/public/assets/nim-DyjFVMzT.js +1 -0
- package/server/public/assets/nix-C2IovEl2.js +1 -0
- package/server/public/assets/nord-BjZ63GNL.js +1 -0
- package/server/public/assets/nushell-BflTrRB5.js +1 -0
- package/server/public/assets/objective-c-GRClK1S7.js +1 -0
- package/server/public/assets/objective-cpp-l3qYw-v5.js +1 -0
- package/server/public/assets/ocaml-BBDyhyMH.js +1 -0
- package/server/public/assets/odin-jCJ7Js99.js +1 -0
- package/server/public/assets/one-dark-pro-PIx2Diul.js +1 -0
- package/server/public/assets/one-light-BFMEz49S.js +1 -0
- package/server/public/assets/openscad-Drf0LgCX.js +1 -0
- package/server/public/assets/pascal-BT2XAUTl.js +1 -0
- package/server/public/assets/perl-Dr47G_2Q.js +1 -0
- package/server/public/assets/php-BhBDWTJe.js +1 -0
- package/server/public/assets/pierre-dark-CTXzTLfO.js +1 -0
- package/server/public/assets/pierre-light-C_5rlJRo.js +1 -0
- package/server/public/assets/pkl-ML-dWShO.js +1 -0
- package/server/public/assets/plastic-BFI-Z5Z2.js +1 -0
- package/server/public/assets/plsql-0vd5cLro.js +1 -0
- package/server/public/assets/po-CbZ_uqQA.js +1 -0
- package/server/public/assets/poimandres-Cayhd01L.js +1 -0
- package/server/public/assets/polar-C4hfV8Nc.js +1 -0
- package/server/public/assets/postcss-osFUbTLw.js +1 -0
- package/server/public/assets/powerquery-CTlGUQPj.js +1 -0
- package/server/public/assets/powershell-DyZsOmuq.js +1 -0
- package/server/public/assets/preload-helper-D7oT-Xwl.js +20 -0
- package/server/public/assets/prisma-SS92PO_I.js +1 -0
- package/server/public/assets/prolog-B1O1NNVC.js +1 -0
- package/server/public/assets/proto-BWu3eZTs.js +1 -0
- package/server/public/assets/pug-Dij_IK5w.js +1 -0
- package/server/public/assets/puppet-tvtRVdr6.js +1 -0
- package/server/public/assets/purescript-Dtbpb7D-.js +1 -0
- package/server/public/assets/python-Dlk0Acio.js +1 -0
- package/server/public/assets/qml-qUwk3nhh.js +1 -0
- package/server/public/assets/qmldir-B-iEOngH.js +1 -0
- package/server/public/assets/qss-Ba0p-aHw.js +1 -0
- package/server/public/assets/r-WmtNicKM.js +1 -0
- package/server/public/assets/racket-BXDsxf2U.js +1 -0
- package/server/public/assets/raku-Dw1WWFXK.js +1 -0
- package/server/public/assets/razor-DaqiVx3Q.js +1 -0
- package/server/public/assets/red-BC3Ds49b.js +1 -0
- package/server/public/assets/reg-DXFHGaM4.js +1 -0
- package/server/public/assets/regexp-CiSWN5Ne.js +1 -0
- package/server/public/assets/rel-Dc5_Ytx2.js +1 -0
- package/server/public/assets/reviews-CJvVXRLH.js +1 -0
- package/server/public/assets/reviews-CfbuF6ib.js +1 -0
- package/server/public/assets/riscv-ZgswiWij.js +1 -0
- package/server/public/assets/ron-YghabWAH.js +1 -0
- package/server/public/assets/rose-pine-ByWLnVr3.js +1 -0
- package/server/public/assets/rose-pine-dawn-DBmeySrz.js +1 -0
- package/server/public/assets/rose-pine-moon-B9J-N3nK.js +1 -0
- package/server/public/assets/rosmsg-DTKmAsVH.js +1 -0
- package/server/public/assets/routes-DNxq1Fba.js +1 -0
- package/server/public/assets/routes-Dp0ODZ55.js +2 -0
- package/server/public/assets/rst-CP6xOYlY.js +1 -0
- package/server/public/assets/ruby-BXYLc1CM.js +1 -0
- package/server/public/assets/rust-nfXwuE6F.js +1 -0
- package/server/public/assets/sas-CFdtZutF.js +1 -0
- package/server/public/assets/sass-CbRjkld3.js +1 -0
- package/server/public/assets/scala-BzD3eypx.js +1 -0
- package/server/public/assets/scheme-D4d1PV1y.js +1 -0
- package/server/public/assets/scss-D8KhdObH.js +1 -0
- package/server/public/assets/sdbl-Cf-Ydnvx.js +1 -0
- package/server/public/assets/shaderlab-DGohHMiF.js +1 -0
- package/server/public/assets/shellscript-BHdEbumI.js +1 -0
- package/server/public/assets/shellsession-Dh-bxrap.js +1 -0
- package/server/public/assets/slack-dark-MszIyPZ2.js +1 -0
- package/server/public/assets/slack-ochin-tQ3Q0gE9.js +1 -0
- package/server/public/assets/smalltalk-_uWoArwn.js +1 -0
- package/server/public/assets/snazzy-light-9sniMEk5.js +1 -0
- package/server/public/assets/solarized-dark-CdD0Hxzv.js +1 -0
- package/server/public/assets/solarized-light-C-nsEdqF.js +1 -0
- package/server/public/assets/solidity-D6uC-xwP.js +1 -0
- package/server/public/assets/soy-cDuODfbT.js +1 -0
- package/server/public/assets/sparql-BgU2QITA.js +1 -0
- package/server/public/assets/splunk-LQYHRu14.js +1 -0
- package/server/public/assets/sql-CKZpK620.js +1 -0
- package/server/public/assets/ssh-config-B7BUl8Rd.js +1 -0
- package/server/public/assets/stata-BLJTbKOO.js +1 -0
- package/server/public/assets/styles-UDowwF7S.css +2 -0
- package/server/public/assets/stylus-Byjxdx_q.js +1 -0
- package/server/public/assets/surrealql-C96KvYaj.js +1 -0
- package/server/public/assets/svelte-Qnbj2GWx.js +1 -0
- package/server/public/assets/swift-BexLlMrU.js +1 -0
- package/server/public/assets/synthwave-84-BxMBwQMS.js +1 -0
- package/server/public/assets/system-verilog-DVGwm0mw.js +1 -0
- package/server/public/assets/systemd-H2IT3-p5.js +1 -0
- package/server/public/assets/talonscript-mKZIGM8n.js +1 -0
- package/server/public/assets/tasl-B7he_Ugr.js +1 -0
- package/server/public/assets/tcl-5mT3RxHH.js +1 -0
- package/server/public/assets/templ-CQPDll3D.js +1 -0
- package/server/public/assets/terraform-BZP0GLsT.js +1 -0
- package/server/public/assets/test-D7JRfog1.js +1 -0
- package/server/public/assets/tex-97QNLoBJ.js +1 -0
- package/server/public/assets/tokyo-night-CTPVdZt9.js +1 -0
- package/server/public/assets/toml-CTFA98he.js +1 -0
- package/server/public/assets/ts-tags-B8zlXe2n.js +1 -0
- package/server/public/assets/tsv-BayJtYdY.js +1 -0
- package/server/public/assets/tsx-VqRU8NCz.js +1 -0
- package/server/public/assets/turtle-TVCBh_kY.js +1 -0
- package/server/public/assets/twig-FTTF8rVk.js +1 -0
- package/server/public/assets/typescript-CuX0hIVY.js +1 -0
- package/server/public/assets/typespec-BUvaJDLF.js +1 -0
- package/server/public/assets/typst-8NBaY7Ec.js +1 -0
- package/server/public/assets/useStore-M3H8PB1v.js +1 -0
- package/server/public/assets/utils-DElCu2hq.js +1 -0
- package/server/public/assets/v-VihyTigi.js +1 -0
- package/server/public/assets/vala-DyFAPyX6.js +1 -0
- package/server/public/assets/vb-Dg1Iqi4J.js +1 -0
- package/server/public/assets/verilog-D2Xc-vhD.js +1 -0
- package/server/public/assets/vesper-DJbtqYNr.js +1 -0
- package/server/public/assets/vhdl-CU3BVeE7.js +1 -0
- package/server/public/assets/viml-hG2shuOW.js +1 -0
- package/server/public/assets/vitesse-black-DbG2gsc0.js +1 -0
- package/server/public/assets/vitesse-dark-B6WV4xXH.js +1 -0
- package/server/public/assets/vitesse-light-DC1pdD02.js +1 -0
- package/server/public/assets/vue-DXwaEU0U.js +1 -0
- package/server/public/assets/vue-html-QD7AJ6JJ.js +1 -0
- package/server/public/assets/vue-vine-Bh2m1D2Z.js +1 -0
- package/server/public/assets/vyper-C1wojIuk.js +1 -0
- package/server/public/assets/wasm-C6Y0s02M.js +1 -0
- package/server/public/assets/wasm-qTvCOSHz.js +1 -0
- package/server/public/assets/wenyan-BG5vPQF0.js +1 -0
- package/server/public/assets/wgsl-DrVb-Cub.js +1 -0
- package/server/public/assets/wikitext-PRC4s8sH.js +1 -0
- package/server/public/assets/wit-ChW5qvg_.js +1 -0
- package/server/public/assets/wolfram-B8mKuZSQ.js +1 -0
- package/server/public/assets/xml-BK-rcb5a.js +1 -0
- package/server/public/assets/xsl-dt-d2R7p.js +1 -0
- package/server/public/assets/yaml-UiXU3hGj.js +1 -0
- package/server/public/assets/zenscript-C-jEPC9j.js +1 -0
- package/server/public/assets/zig-EbnRGjcz.js +1 -0
- package/server/public/favicon.ico +0 -0
- package/server/public/logo192.png +0 -0
- package/server/public/logo512.png +0 -0
- package/server/public/manifest.json +25 -0
- package/server/public/robots.txt +3 -0
- package/server/public/tanstack-circle-logo.png +0 -0
- package/server/public/tanstack-word-logo-white.svg +1 -0
- package/server/server/_chunks/ssr-renderer.mjs +15 -0
- package/server/server/_libs/@floating-ui/core+[...].mjs +698 -0
- package/server/server/_libs/@floating-ui/dom+[...].mjs +644 -0
- package/server/server/_libs/@floating-ui/react-dom+[...].mjs +839 -0
- package/server/server/_libs/@pierre/diffs+[...].mjs +18578 -0
- package/server/server/_libs/@radix-ui/react-arrow+[...].mjs +174 -0
- package/server/server/_libs/@radix-ui/react-collection+[...].mjs +162 -0
- package/server/server/_libs/@radix-ui/react-dialog+[...].mjs +1666 -0
- package/server/server/_libs/@radix-ui/react-popper+[...].mjs +289 -0
- package/server/server/_libs/@radix-ui/react-radio-group+[...].mjs +420 -0
- package/server/server/_libs/@radix-ui/react-select+[...].mjs +990 -0
- package/server/server/_libs/@tanstack/react-router+[...].mjs +14113 -0
- package/server/server/_libs/_.mjs +2 -0
- package/server/server/_libs/chokidar+readdirp.mjs +1599 -0
- package/server/server/_libs/class-variance-authority+clsx.mjs +69 -0
- package/server/server/_libs/effect+[...].mjs +34047 -0
- package/server/server/_libs/h3+rou3+srvx.mjs +1195 -0
- package/server/server/_libs/hookable.mjs +41 -0
- package/server/server/_libs/lucide-react.mjs +298 -0
- package/server/server/_libs/pierre__theme.mjs +2668 -0
- package/server/server/_libs/radix-ui__number.mjs +6 -0
- package/server/server/_libs/radix-ui__primitive.mjs +9 -0
- package/server/server/_libs/radix-ui__react-direction.mjs +11 -0
- package/server/server/_libs/shiki.mjs +16 -0
- package/server/server/_libs/shikijs__langs.mjs +1355 -0
- package/server/server/_libs/shikijs__themes.mjs +262 -0
- package/server/server/_libs/tailwind-merge.mjs +1962 -0
- package/server/server/_libs/tanstack__history.mjs +342 -0
- package/server/server/_libs/tanstack__router-core.mjs +6 -0
- package/server/server/_libs/ufo.mjs +64 -0
- package/server/server/_reviewId-AWnOGz5k.mjs +33 -0
- package/server/server/_reviewId-Com4yOlc.mjs +29 -0
- package/server/server/_reviewId-DAhmekJ2.mjs +277 -0
- package/server/server/_reviewId-p9mhYVwa.mjs +18 -0
- package/server/server/_runtime.mjs +35 -0
- package/server/server/_ssr/action-bar-C68xGnWW.mjs +592 -0
- package/server/server/_ssr/api-handler-CstW2n82.mjs +189 -0
- package/server/server/_ssr/client-runtime-BoPuAEoA.mjs +245 -0
- package/server/server/_ssr/createServerRpc--0mcGlWK.mjs +12 -0
- package/server/server/_ssr/createSsrRpc-AwdiLXmF.mjs +16 -0
- package/server/server/_ssr/domain-rpc-3Ds9DPr0.mjs +287 -0
- package/server/server/_ssr/file-tree-CQ5w2GHh.mjs +1951 -0
- package/server/server/_ssr/load-scoped-diff-NL2XAcdz.mjs +45 -0
- package/server/server/_ssr/new-BKl_G2Ks.mjs +37 -0
- package/server/server/_ssr/new-BREdMFAM.mjs +12 -0
- package/server/server/_ssr/new-DCz5eHkb.mjs +137 -0
- package/server/server/_ssr/reviews-BL5Nsgst.mjs +7 -0
- package/server/server/_ssr/reviews-BoaEgGKs.mjs +100 -0
- package/server/server/_ssr/reviews-C7_NIhY8.mjs +19 -0
- package/server/server/_ssr/reviews-Dd69YBDa.mjs +12 -0
- package/server/server/_ssr/router-DLxN8FOm.mjs +415 -0
- package/server/server/_ssr/routes-D25G8OuS.mjs +80 -0
- package/server/server/_ssr/routes-lz0AN75A.mjs +929 -0
- package/server/server/_ssr/runtime-D9IbnMlF.mjs +1401 -0
- package/server/server/_ssr/server-runtime-D99qpmma.mjs +12 -0
- package/server/server/_ssr/ssr.mjs +5318 -0
- package/server/server/_ssr/start-BIQfOZtj.mjs +4 -0
- package/server/server/_ssr/test-CQdMYlqa.mjs +6 -0
- package/server/server/_ssr/todo-m_uUvxca.mjs +88 -0
- package/server/server/_ssr/use-keyboard-shortcuts-D5b1Mxpq.mjs +25 -0
- package/server/server/_ssr/utils-BuOt9_LA.mjs +8 -0
- package/server/server/_tanstack-start-manifest_v-CnL10NRH.mjs +71 -0
- package/server/server/index.mjs +2615 -0
- package/server/server/node_modules/detect-libc/lib/detect-libc.js +313 -0
- package/server/server/node_modules/detect-libc/lib/elf.js +39 -0
- package/server/server/node_modules/detect-libc/lib/filesystem.js +51 -0
- package/server/server/node_modules/detect-libc/lib/process.js +24 -0
- package/server/server/node_modules/detect-libc/package.json +44 -0
- package/server/server/node_modules/msgpackr-extract/index.js +1 -0
- package/server/server/node_modules/msgpackr-extract/package.json +50 -0
- package/server/server/node_modules/node-gyp-build-optional-packages/index.js +6 -0
- package/server/server/node_modules/node-gyp-build-optional-packages/node-gyp-build.js +236 -0
- package/server/server/node_modules/node-gyp-build-optional-packages/package.json +32 -0
- package/server/server/node_modules/tslib/modules/index.js +70 -0
- package/server/server/node_modules/tslib/modules/package.json +3 -0
- package/server/server/node_modules/tslib/package.json +47 -0
- package/server/server/node_modules/tslib/tslib.js +484 -0
- package/server/server/package.json +12 -0
- package/dist/chunk-KMYSGMD3.js +0 -3526
- package/dist/chunk-KMYSGMD3.js.map +0 -1
- package/dist/cli.js +0 -1839
- package/dist/cli.js.map +0 -1
- package/dist/mcp.js +0 -1228
- package/dist/mcp.js.map +0 -1
|
@@ -0,0 +1,929 @@
|
|
|
1
|
+
import { i as __toESM } from "../_runtime.mjs";
|
|
2
|
+
import { u as require_react } from "../_libs/@floating-ui/react-dom+[...].mjs";
|
|
3
|
+
import { d as useNavigate, f as useLoaderData, p as useRouter } from "../_libs/@tanstack/react-router+[...].mjs";
|
|
4
|
+
import { n as require_jsx_runtime } from "../_libs/@pierre/diffs+[...].mjs";
|
|
5
|
+
import { Ct as tap, H as Struct, Ht as none, L as Literals, Ot as void_, Vt as map, W as Unknown, X as optionalKey, dt as gen, it as catchCause, q as decodeUnknownOption, vt as promise, z as Number$1 } from "../_libs/effect+[...].mjs";
|
|
6
|
+
import { s as DIFF_SCOPES } from "./todo-m_uUvxca.mjs";
|
|
7
|
+
import { i as clientRuntime, t as ApiClient } from "./client-runtime-BoPuAEoA.mjs";
|
|
8
|
+
import { t as cn } from "./utils-BuOt9_LA.mjs";
|
|
9
|
+
import { _ as ChevronUp, b as Check, g as CircleCheckBig, h as CircleDot, m as Circle, o as LoaderCircle, s as GitCommitHorizontal, y as ChevronDown } from "../_libs/lucide-react.mjs";
|
|
10
|
+
import { a as ItemIndicator, c as Root2, d as Trigger, f as Viewport, i as Item, l as ScrollDownButton, n as Group, o as ItemText, r as Icon, s as Portal, t as Content2, u as ScrollUpButton } from "../_libs/@radix-ui/react-select+[...].mjs";
|
|
11
|
+
import { a as DialogFooter, i as DialogDescription, n as Dialog$1, o as DialogHeader, r as DialogContent, s as DialogTitle, t as ActionBar } from "./action-bar-C68xGnWW.mjs";
|
|
12
|
+
import { a as formatReviewFeedback, i as FileTree, n as DiffView, r as ExportFeedbackModal, t as DiffSummary } from "./file-tree-CQ5w2GHh.mjs";
|
|
13
|
+
import { t as useKeyboardShortcuts } from "./use-keyboard-shortcuts-D5b1Mxpq.mjs";
|
|
14
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/routes-lz0AN75A.js
|
|
15
|
+
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
16
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
17
|
+
var Select$1 = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root2, {
|
|
18
|
+
"data-slot": "select",
|
|
19
|
+
...props
|
|
20
|
+
});
|
|
21
|
+
var SelectGroup = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Group, {
|
|
22
|
+
"data-slot": "select-group",
|
|
23
|
+
className: cn("scroll-my-1 p-1", className),
|
|
24
|
+
...props
|
|
25
|
+
});
|
|
26
|
+
var SelectTrigger = ({ className, size = "default", children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Trigger, {
|
|
27
|
+
"data-slot": "select-trigger",
|
|
28
|
+
"data-size": size,
|
|
29
|
+
className: cn("flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
|
|
30
|
+
...props,
|
|
31
|
+
children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {
|
|
32
|
+
asChild: true,
|
|
33
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "pointer-events-none size-4 text-muted-foreground" })
|
|
34
|
+
})]
|
|
35
|
+
});
|
|
36
|
+
var SelectContent = ({ className, children, position = "item-aligned", align = "center", ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Content2, {
|
|
37
|
+
"data-slot": "select-content",
|
|
38
|
+
"data-align-trigger": position === "item-aligned",
|
|
39
|
+
className: cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
|
|
40
|
+
position,
|
|
41
|
+
align,
|
|
42
|
+
...props,
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectScrollUpButton, {}),
|
|
45
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Viewport, {
|
|
46
|
+
"data-position": position,
|
|
47
|
+
className: cn("data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)", position === "popper" && ""),
|
|
48
|
+
children
|
|
49
|
+
}),
|
|
50
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectScrollDownButton, {})
|
|
51
|
+
]
|
|
52
|
+
}) });
|
|
53
|
+
var SelectItem = ({ className, children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Item, {
|
|
54
|
+
"data-slot": "select-item",
|
|
55
|
+
className: cn("relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
|
|
56
|
+
...props,
|
|
57
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
58
|
+
className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center",
|
|
59
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, { className: "pointer-events-none" }) })
|
|
60
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ItemText, { children })]
|
|
61
|
+
});
|
|
62
|
+
var SelectScrollUpButton = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollUpButton, {
|
|
63
|
+
"data-slot": "select-scroll-up-button",
|
|
64
|
+
className: cn("z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className),
|
|
65
|
+
...props,
|
|
66
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronUp, {})
|
|
67
|
+
});
|
|
68
|
+
var SelectScrollDownButton = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollDownButton, {
|
|
69
|
+
"data-slot": "select-scroll-down-button",
|
|
70
|
+
className: cn("z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className),
|
|
71
|
+
...props,
|
|
72
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, {})
|
|
73
|
+
});
|
|
74
|
+
var DIFF_SCOPE_LABELS = {
|
|
75
|
+
"last-commit": "Last Commit",
|
|
76
|
+
staged: "Staged",
|
|
77
|
+
uncommitted: "Uncommitted",
|
|
78
|
+
unstaged: "Unstaged"
|
|
79
|
+
};
|
|
80
|
+
var DIFF_SCOPE_EMPTY_MESSAGES = {
|
|
81
|
+
"last-commit": "No previous commit found",
|
|
82
|
+
staged: "No staged changes — stage files with git add",
|
|
83
|
+
uncommitted: "Working tree clean — no uncommitted changes",
|
|
84
|
+
unstaged: "No unstaged changes — all modifications are staged"
|
|
85
|
+
};
|
|
86
|
+
var DIFF_SCOPE_ICONS = {
|
|
87
|
+
"last-commit": GitCommitHorizontal,
|
|
88
|
+
staged: CircleCheckBig,
|
|
89
|
+
uncommitted: CircleDot,
|
|
90
|
+
unstaged: Circle
|
|
91
|
+
};
|
|
92
|
+
var CountBadge = ({ fileCount, isLoading }) => {
|
|
93
|
+
if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
94
|
+
className: "inline-flex h-5 min-w-5 items-center justify-center rounded-full border border-border-default bg-surface-overlay px-1.5 text-[10px] text-text-tertiary motion-reduce:animate-none",
|
|
95
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, { className: "size-3 animate-spin motion-reduce:animate-none" })
|
|
96
|
+
});
|
|
97
|
+
if (typeof fileCount !== "number") return null;
|
|
98
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
99
|
+
className: "inline-flex h-5 min-w-5 items-center justify-center rounded-full border border-border-default bg-surface-overlay px-1.5 text-[10px] font-medium tabular-nums text-text-secondary",
|
|
100
|
+
children: fileCount
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
var DiffScopeSelector = ({ value, onChange, fileCount, isLoading = false }) => {
|
|
104
|
+
const SelectedIcon = isLoading ? LoaderCircle : DIFF_SCOPE_ICONS[value];
|
|
105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
|
|
106
|
+
disabled: isLoading,
|
|
107
|
+
onValueChange: (0, import_react.useCallback)((scope) => {
|
|
108
|
+
onChange(scope);
|
|
109
|
+
}, [onChange]),
|
|
110
|
+
value,
|
|
111
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SelectTrigger, {
|
|
112
|
+
"aria-label": "Diff scope",
|
|
113
|
+
className: cn("h-7 min-w-0 gap-1.5 rounded-[10px] border-border-subtle bg-surface-primary px-2 text-[11px] font-medium text-text-secondary shadow-none transition-[color,background-color,border-color,box-shadow,transform,opacity] duration-150 [transition-timing-function:cubic-bezier(0.23,1,0.32,1)] focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40 active:scale-[0.97] motion-reduce:transform-none motion-reduce:transition-[color,background-color,border-color,box-shadow,opacity] [&_svg]:text-text-tertiary"),
|
|
114
|
+
size: "sm",
|
|
115
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
116
|
+
className: "flex min-w-0 items-center gap-1.5",
|
|
117
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectedIcon, { className: cn("size-3.5 shrink-0", isLoading && "animate-spin motion-reduce:animate-none") }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
118
|
+
className: "truncate",
|
|
119
|
+
children: DIFF_SCOPE_LABELS[value]
|
|
120
|
+
})]
|
|
121
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountBadge, {
|
|
122
|
+
fileCount,
|
|
123
|
+
isLoading
|
|
124
|
+
})]
|
|
125
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, {
|
|
126
|
+
align: "end",
|
|
127
|
+
className: cn("min-w-44 rounded-xl border border-border-default bg-surface-elevated p-1 shadow-[0_18px_40px_-24px_rgba(0,0,0,0.7)] transition-[opacity,transform] duration-150 [transition-timing-function:cubic-bezier(0.23,1,0.32,1)] data-[state=closed]:scale-95 data-[state=closed]:opacity-0 data-[state=open]:scale-100 data-[state=open]:opacity-100 motion-reduce:transform-none motion-reduce:transition-opacity"),
|
|
128
|
+
position: "popper",
|
|
129
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectGroup, { children: DIFF_SCOPES.map((scope) => {
|
|
130
|
+
const Icon = DIFF_SCOPE_ICONS[scope];
|
|
131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
|
|
132
|
+
className: "rounded-lg px-2 py-1.5 text-xs text-text-secondary focus:bg-surface-overlay focus:text-text-primary",
|
|
133
|
+
value: scope,
|
|
134
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
135
|
+
className: "flex min-w-0 items-center gap-2",
|
|
136
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className: "size-3.5 shrink-0" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
137
|
+
className: "truncate",
|
|
138
|
+
children: DIFF_SCOPE_LABELS[scope]
|
|
139
|
+
})]
|
|
140
|
+
})
|
|
141
|
+
}, scope);
|
|
142
|
+
}) })
|
|
143
|
+
})]
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
var STORAGE_KEY = "ringi.session-draft.v1";
|
|
147
|
+
var MAX_AGE_MS = 1800 * 1e3;
|
|
148
|
+
var clearDraft = () => {
|
|
149
|
+
if (typeof window === "undefined") return;
|
|
150
|
+
try {
|
|
151
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
152
|
+
} catch {}
|
|
153
|
+
};
|
|
154
|
+
var saveDraft = (draft) => {
|
|
155
|
+
if (typeof window === "undefined") return;
|
|
156
|
+
const payload = {
|
|
157
|
+
...draft,
|
|
158
|
+
savedAt: Date.now()
|
|
159
|
+
};
|
|
160
|
+
try {
|
|
161
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
|
|
162
|
+
} catch {}
|
|
163
|
+
};
|
|
164
|
+
var loadDraft = () => {
|
|
165
|
+
if (typeof window === "undefined") return null;
|
|
166
|
+
try {
|
|
167
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
168
|
+
if (!raw) return null;
|
|
169
|
+
const data = JSON.parse(raw);
|
|
170
|
+
if (typeof data.savedAt !== "number" || !Array.isArray(data.viewedFiles) || typeof data.scope !== "string") return null;
|
|
171
|
+
if (Date.now() - data.savedAt > MAX_AGE_MS) {
|
|
172
|
+
clearDraft();
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
savedAt: data.savedAt,
|
|
177
|
+
scope: data.scope,
|
|
178
|
+
selectedFile: typeof data.selectedFile === "string" ? data.selectedFile : null,
|
|
179
|
+
viewedFiles: data.viewedFiles.filter((v) => typeof v === "string")
|
|
180
|
+
};
|
|
181
|
+
} catch {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Human-friendly relative time label for the recovery modal.
|
|
187
|
+
*
|
|
188
|
+
* Examples: "just now", "1 minute ago", "5 minutes ago", "1 hour ago"
|
|
189
|
+
*/
|
|
190
|
+
var formatRelativeTime$1 = (savedAt) => {
|
|
191
|
+
const diffMs = Date.now() - savedAt;
|
|
192
|
+
const diffSeconds = Math.floor(diffMs / 1e3);
|
|
193
|
+
const diffMinutes = Math.floor(diffSeconds / 60);
|
|
194
|
+
const diffHours = Math.floor(diffMinutes / 60);
|
|
195
|
+
if (diffSeconds < 30) return "just now";
|
|
196
|
+
if (diffMinutes < 1) return "less than a minute ago";
|
|
197
|
+
if (diffMinutes === 1) return "1 minute ago";
|
|
198
|
+
if (diffMinutes < 60) return `${diffMinutes} minutes ago`;
|
|
199
|
+
if (diffHours === 1) return "1 hour ago";
|
|
200
|
+
return `${diffHours} hours ago`;
|
|
201
|
+
};
|
|
202
|
+
var isDraftRecoverable = (draft, currentScope) => draft !== null && draft.scope === currentScope && draft.viewedFiles.length > 0;
|
|
203
|
+
var buttonMotionClass = "transition-[transform,background-color,color,border-color,box-shadow,opacity] duration-150 [transition-timing-function:cubic-bezier(0.23,1,0.32,1)] motion-reduce:transform-none";
|
|
204
|
+
var DraftRecoveryModal = ({ open, draft, onRestore, onDismiss }) => {
|
|
205
|
+
const fileCount = draft.viewedFiles.length;
|
|
206
|
+
const timeLabel = formatRelativeTime$1(draft.savedAt);
|
|
207
|
+
const handleRestore = (0, import_react.useCallback)(() => {
|
|
208
|
+
onRestore();
|
|
209
|
+
}, [onRestore]);
|
|
210
|
+
const handleDismiss = (0, import_react.useCallback)(() => {
|
|
211
|
+
onDismiss();
|
|
212
|
+
}, [onDismiss]);
|
|
213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog$1, {
|
|
214
|
+
open,
|
|
215
|
+
onOpenChange: (0, import_react.useCallback)((v) => {
|
|
216
|
+
if (!v) onDismiss();
|
|
217
|
+
}, [onDismiss]),
|
|
218
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent, {
|
|
219
|
+
className: "max-w-sm gap-0",
|
|
220
|
+
showCloseButton: false,
|
|
221
|
+
children: [
|
|
222
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogHeader, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitle, { children: "Draft Recovered" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription, { children: `Found ${fileCount} viewed file${fileCount === 1 ? "" : "s"} from ${timeLabel}.` })] }),
|
|
223
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
224
|
+
className: "px-5 py-3",
|
|
225
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("ul", {
|
|
226
|
+
className: "flex flex-col gap-1",
|
|
227
|
+
children: [draft.viewedFiles.slice(0, 5).map((filePath) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", {
|
|
228
|
+
className: "truncate font-mono text-xs text-text-secondary",
|
|
229
|
+
children: filePath
|
|
230
|
+
}, filePath)), fileCount > 5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", {
|
|
231
|
+
className: "text-xs text-text-tertiary",
|
|
232
|
+
children: `… and ${fileCount - 5} more`
|
|
233
|
+
}) : null]
|
|
234
|
+
})
|
|
235
|
+
}),
|
|
236
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogFooter, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
237
|
+
type: "button",
|
|
238
|
+
onClick: handleDismiss,
|
|
239
|
+
className: cn("rounded-lg border border-border-default bg-surface-elevated px-3 py-1.5 text-xs text-text-secondary hover:bg-surface-overlay hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 active:scale-[0.97]", buttonMotionClass),
|
|
240
|
+
children: "Dismiss"
|
|
241
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
242
|
+
type: "button",
|
|
243
|
+
onClick: handleRestore,
|
|
244
|
+
className: cn("rounded-lg bg-accent-primary px-3 py-1.5 text-xs font-medium text-white hover:bg-accent-primary-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-primary/40 active:scale-[0.97]", buttonMotionClass),
|
|
245
|
+
children: "Restore"
|
|
246
|
+
})] })
|
|
247
|
+
]
|
|
248
|
+
})
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
var EASE_OUT = "[transition-timing-function:cubic-bezier(0.23,1,0.32,1)]";
|
|
252
|
+
var pressScale = "active:scale-[0.97]";
|
|
253
|
+
var formatRelativeTime = (iso) => {
|
|
254
|
+
const date = new Date(iso);
|
|
255
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
256
|
+
const diffMs = Date.now() - date.getTime();
|
|
257
|
+
const diffMin = Math.floor(diffMs / 6e4);
|
|
258
|
+
if (diffMin < 1) return "just now";
|
|
259
|
+
if (diffMin < 60) return `${diffMin}m ago`;
|
|
260
|
+
const diffHours = Math.floor(diffMin / 60);
|
|
261
|
+
if (diffHours < 24) return `${diffHours}h ago`;
|
|
262
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
263
|
+
day: "numeric",
|
|
264
|
+
month: "short"
|
|
265
|
+
}).format(date);
|
|
266
|
+
};
|
|
267
|
+
var getFileName = (filePath) => {
|
|
268
|
+
return filePath.split("/").at(-1) ?? filePath;
|
|
269
|
+
};
|
|
270
|
+
var getDirPath = (filePath) => {
|
|
271
|
+
const parts = filePath.split("/");
|
|
272
|
+
if (parts.length <= 1) return "";
|
|
273
|
+
return parts.slice(0, -1).join("/");
|
|
274
|
+
};
|
|
275
|
+
var DeleteButton = ({ onDelete, annotationId }) => {
|
|
276
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
277
|
+
type: "button",
|
|
278
|
+
onClick: (0, import_react.useCallback)((e) => {
|
|
279
|
+
e.stopPropagation();
|
|
280
|
+
onDelete(annotationId);
|
|
281
|
+
}, [onDelete, annotationId]),
|
|
282
|
+
onKeyDown: (0, import_react.useCallback)((e) => {
|
|
283
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
284
|
+
e.preventDefault();
|
|
285
|
+
e.stopPropagation();
|
|
286
|
+
onDelete(annotationId);
|
|
287
|
+
}
|
|
288
|
+
}, [onDelete, annotationId]),
|
|
289
|
+
"aria-label": "Delete annotation",
|
|
290
|
+
tabIndex: 0,
|
|
291
|
+
className: cn("ml-auto shrink-0 rounded px-1 py-0.5 text-text-quaternary", "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100", "transition-[opacity,color,background-color] duration-100", EASE_OUT, "hover:bg-status-error/10 hover:text-status-error", "focus-visible:bg-status-error/10 focus-visible:text-status-error focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-status-error/30", "active:scale-[0.93]", "motion-reduce:transform-none"),
|
|
292
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
293
|
+
width: "11",
|
|
294
|
+
height: "11",
|
|
295
|
+
viewBox: "0 0 12 12",
|
|
296
|
+
fill: "none",
|
|
297
|
+
stroke: "currentColor",
|
|
298
|
+
strokeWidth: "1.25",
|
|
299
|
+
strokeLinecap: "round",
|
|
300
|
+
className: "shrink-0",
|
|
301
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 3h8M4.5 3V2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v1M5 5.5v3M7 5.5v3M3 3l.5 7a1 1 0 0 0 1 .9h3a1 1 0 0 0 1-.9L9 3" })
|
|
302
|
+
})
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
var AnnotationCard = ({ entry, onClick, onDelete }) => {
|
|
306
|
+
const handleClick = (0, import_react.useCallback)(() => onClick(entry), [entry, onClick]);
|
|
307
|
+
const handleKeyDown = (0, import_react.useCallback)((e) => {
|
|
308
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
309
|
+
e.preventDefault();
|
|
310
|
+
onClick(entry);
|
|
311
|
+
}
|
|
312
|
+
}, [entry, onClick]);
|
|
313
|
+
const linePrefix = entry.lineType === "added" ? "+" : "-";
|
|
314
|
+
const lineColor = entry.lineType === "added" ? "text-diff-add-text" : "text-diff-remove-text";
|
|
315
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
316
|
+
type: "button",
|
|
317
|
+
onClick: handleClick,
|
|
318
|
+
onKeyDown: handleKeyDown,
|
|
319
|
+
className: cn("group flex w-full cursor-pointer flex-col rounded-md px-2.5 py-2 text-left", "transition-[background-color,transform] duration-150", EASE_OUT, pressScale, "hover:bg-surface-overlay/60", "focus-visible:bg-surface-overlay/60 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent-primary/40", "motion-reduce:transform-none"),
|
|
320
|
+
children: [
|
|
321
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
322
|
+
className: "flex items-center gap-1.5",
|
|
323
|
+
children: [
|
|
324
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
325
|
+
className: cn("rounded bg-surface-primary/80 px-1 py-px font-mono text-[10px] font-medium tabular-nums", lineColor),
|
|
326
|
+
children: [
|
|
327
|
+
linePrefix,
|
|
328
|
+
"L",
|
|
329
|
+
entry.lineNumber
|
|
330
|
+
]
|
|
331
|
+
}),
|
|
332
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeleteButton, {
|
|
333
|
+
onDelete,
|
|
334
|
+
annotationId: entry.id
|
|
335
|
+
}),
|
|
336
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
337
|
+
className: "text-[10px] text-text-quaternary",
|
|
338
|
+
children: formatRelativeTime(entry.createdAt)
|
|
339
|
+
})
|
|
340
|
+
]
|
|
341
|
+
}),
|
|
342
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
343
|
+
className: "mt-1 line-clamp-2 text-[11px] leading-[16px] text-text-secondary group-hover:text-text-primary",
|
|
344
|
+
children: entry.content
|
|
345
|
+
}),
|
|
346
|
+
entry.suggestion ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
347
|
+
className: "mt-1 flex items-center text-[10px] text-accent-primary/70",
|
|
348
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
349
|
+
width: "10",
|
|
350
|
+
height: "10",
|
|
351
|
+
viewBox: "0 0 14 14",
|
|
352
|
+
fill: "none",
|
|
353
|
+
className: "shrink-0",
|
|
354
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
|
|
355
|
+
d: "M3 5l2.5 2.5L11 2M3 9h8",
|
|
356
|
+
stroke: "currentColor",
|
|
357
|
+
strokeWidth: "1.25",
|
|
358
|
+
strokeLinecap: "round",
|
|
359
|
+
strokeLinejoin: "round"
|
|
360
|
+
})
|
|
361
|
+
})
|
|
362
|
+
}) : null
|
|
363
|
+
]
|
|
364
|
+
});
|
|
365
|
+
};
|
|
366
|
+
var FileGroup = ({ group, onAnnotationClick, onDeleteAnnotation }) => {
|
|
367
|
+
const fileName = getFileName(group.filePath);
|
|
368
|
+
const dirPath = getDirPath(group.filePath);
|
|
369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
370
|
+
className: "py-1",
|
|
371
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
372
|
+
className: "flex items-center gap-1.5 px-3 py-1.5",
|
|
373
|
+
children: [
|
|
374
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
375
|
+
width: "12",
|
|
376
|
+
height: "12",
|
|
377
|
+
viewBox: "0 0 16 16",
|
|
378
|
+
fill: "currentColor",
|
|
379
|
+
className: "shrink-0 text-text-quaternary",
|
|
380
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 3.5A1.5 1.5 0 0 1 3.5 2h3.379a1.5 1.5 0 0 1 1.06.44l.622.621a.5.5 0 0 0 .353.146H12.5A1.5 1.5 0 0 1 14 4.707V12.5a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 2 12.5V3.5Z" })
|
|
381
|
+
}),
|
|
382
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
383
|
+
className: "min-w-0 truncate font-mono text-[11px] font-medium text-text-primary",
|
|
384
|
+
children: fileName
|
|
385
|
+
}),
|
|
386
|
+
dirPath ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
387
|
+
className: "min-w-0 truncate font-mono text-[10px] text-text-quaternary",
|
|
388
|
+
children: dirPath
|
|
389
|
+
}) : null,
|
|
390
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
391
|
+
className: "ml-auto shrink-0 rounded-full bg-surface-overlay px-1.5 py-px text-[10px] tabular-nums text-text-tertiary",
|
|
392
|
+
children: group.annotations.length
|
|
393
|
+
})
|
|
394
|
+
]
|
|
395
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
396
|
+
className: "space-y-0.5 px-1",
|
|
397
|
+
children: group.annotations.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AnnotationCard, {
|
|
398
|
+
entry,
|
|
399
|
+
onClick: onAnnotationClick,
|
|
400
|
+
onDelete: onDeleteAnnotation
|
|
401
|
+
}, entry.id))
|
|
402
|
+
})]
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
var EmptyState = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
406
|
+
className: "flex flex-col items-center justify-center px-4 py-12 text-center",
|
|
407
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
408
|
+
width: "28",
|
|
409
|
+
height: "28",
|
|
410
|
+
viewBox: "0 0 16 16",
|
|
411
|
+
fill: "currentColor",
|
|
412
|
+
className: "text-text-quaternary/40",
|
|
413
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M1 3.5A2.5 2.5 0 0 1 3.5 1h9A2.5 2.5 0 0 1 15 3.5v6a2.5 2.5 0 0 1-2.5 2.5H9l-3.5 3v-3H3.5A2.5 2.5 0 0 1 1 9.5v-6Z" })
|
|
414
|
+
})
|
|
415
|
+
});
|
|
416
|
+
var ClipboardIcon$1 = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
|
|
417
|
+
width: "12",
|
|
418
|
+
height: "12",
|
|
419
|
+
viewBox: "0 0 16 16",
|
|
420
|
+
fill: "none",
|
|
421
|
+
stroke: "currentColor",
|
|
422
|
+
strokeWidth: "1.25",
|
|
423
|
+
strokeLinecap: "round",
|
|
424
|
+
strokeLinejoin: "round",
|
|
425
|
+
className: "shrink-0",
|
|
426
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", {
|
|
427
|
+
x: "5",
|
|
428
|
+
y: "5",
|
|
429
|
+
width: "8",
|
|
430
|
+
height: "8",
|
|
431
|
+
rx: "1.5"
|
|
432
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 11H4.5A1.5 1.5 0 0 1 3 9.5V4.5A1.5 1.5 0 0 1 4.5 3H9.5A1.5 1.5 0 0 1 11 4.5V5" })]
|
|
433
|
+
});
|
|
434
|
+
var CheckIcon$1 = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
435
|
+
width: "12",
|
|
436
|
+
height: "12",
|
|
437
|
+
viewBox: "0 0 12 12",
|
|
438
|
+
fill: "none",
|
|
439
|
+
stroke: "currentColor",
|
|
440
|
+
strokeWidth: "1.5",
|
|
441
|
+
strokeLinecap: "round",
|
|
442
|
+
strokeLinejoin: "round",
|
|
443
|
+
className: "shrink-0 text-status-success",
|
|
444
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2.5 6.5L5 9l4.5-6" })
|
|
445
|
+
});
|
|
446
|
+
var ErrorIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
447
|
+
width: "12",
|
|
448
|
+
height: "12",
|
|
449
|
+
viewBox: "0 0 12 12",
|
|
450
|
+
fill: "none",
|
|
451
|
+
stroke: "currentColor",
|
|
452
|
+
strokeWidth: "1.5",
|
|
453
|
+
strokeLinecap: "round",
|
|
454
|
+
className: "shrink-0 text-status-error",
|
|
455
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 3l6 6M9 3l-6 6" })
|
|
456
|
+
});
|
|
457
|
+
var COPY_LABELS = {
|
|
458
|
+
copied: "Copied!",
|
|
459
|
+
error: "Failed",
|
|
460
|
+
idle: "Copy Feedback"
|
|
461
|
+
};
|
|
462
|
+
var COPY_STATUS_STYLES = {
|
|
463
|
+
copied: "text-status-success",
|
|
464
|
+
error: "text-status-error",
|
|
465
|
+
idle: "text-text-secondary hover:bg-surface-overlay hover:text-text-primary"
|
|
466
|
+
};
|
|
467
|
+
var CopyStatusIcon = ({ status }) => {
|
|
468
|
+
if (status === "copied") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckIcon$1, {});
|
|
469
|
+
if (status === "error") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorIcon, {});
|
|
470
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClipboardIcon$1, {});
|
|
471
|
+
};
|
|
472
|
+
var CopyFeedbackButton = ({ copyStatus, onCopyFeedback }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
473
|
+
type: "button",
|
|
474
|
+
onClick: onCopyFeedback,
|
|
475
|
+
disabled: copyStatus !== "idle",
|
|
476
|
+
className: cn("inline-flex h-7 items-center gap-1.5 rounded-md px-2 text-[11px] font-medium", "transition-[background-color,color,transform,opacity] duration-150", EASE_OUT, pressScale, COPY_STATUS_STYLES[copyStatus], copyStatus !== "idle" && "pointer-events-none", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent-primary/40", "motion-reduce:transform-none"),
|
|
477
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CopyStatusIcon, { status: copyStatus }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: COPY_LABELS[copyStatus] })]
|
|
478
|
+
});
|
|
479
|
+
var AnnotationsPanel = ({ isOpen, onClose, groups, totalCount, copyStatus, onAnnotationClick, onDeleteAnnotation, onCopyFeedback }) => {
|
|
480
|
+
const panelRef = (0, import_react.useRef)(null);
|
|
481
|
+
(0, import_react.useEffect)(() => {
|
|
482
|
+
if (!isOpen) return;
|
|
483
|
+
const handleKeyDown = (e) => {
|
|
484
|
+
if (e.key === "Escape") {
|
|
485
|
+
e.stopPropagation();
|
|
486
|
+
onClose();
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
490
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
491
|
+
}, [isOpen, onClose]);
|
|
492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
|
|
493
|
+
ref: panelRef,
|
|
494
|
+
role: "complementary",
|
|
495
|
+
"aria-label": "Annotations",
|
|
496
|
+
className: cn("flex h-full flex-col border-l border-border-default bg-surface-secondary", "transition-[width,opacity] duration-200", EASE_OUT, "motion-reduce:transition-none", isOpen ? "w-72 opacity-100" : "w-0 opacity-0 overflow-hidden"),
|
|
497
|
+
children: [
|
|
498
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
499
|
+
className: "flex h-10 shrink-0 items-center justify-end border-b border-border-default px-3",
|
|
500
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
501
|
+
type: "button",
|
|
502
|
+
onClick: onClose,
|
|
503
|
+
"aria-label": "Close annotations panel",
|
|
504
|
+
className: cn("inline-flex h-6 w-6 items-center justify-center rounded-md text-text-tertiary", "transition-[background-color,color,transform] duration-150", EASE_OUT, pressScale, "hover:bg-surface-overlay hover:text-text-primary", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent-primary/40", "motion-reduce:transform-none"),
|
|
505
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
506
|
+
width: "12",
|
|
507
|
+
height: "12",
|
|
508
|
+
viewBox: "0 0 12 12",
|
|
509
|
+
fill: "none",
|
|
510
|
+
stroke: "currentColor",
|
|
511
|
+
strokeWidth: "1.5",
|
|
512
|
+
strokeLinecap: "round",
|
|
513
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 3l6 6M9 3l-6 6" })
|
|
514
|
+
})
|
|
515
|
+
})
|
|
516
|
+
}),
|
|
517
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
518
|
+
className: "flex-1 overflow-y-auto overflow-x-hidden py-1",
|
|
519
|
+
children: groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyState, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
520
|
+
className: "divide-y divide-border-subtle",
|
|
521
|
+
children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileGroup, {
|
|
522
|
+
group,
|
|
523
|
+
onAnnotationClick,
|
|
524
|
+
onDeleteAnnotation
|
|
525
|
+
}, group.filePath))
|
|
526
|
+
})
|
|
527
|
+
}),
|
|
528
|
+
totalCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
529
|
+
className: "flex items-center border-t border-border-subtle px-3 py-1.5",
|
|
530
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CopyFeedbackButton, {
|
|
531
|
+
copyStatus,
|
|
532
|
+
onCopyFeedback
|
|
533
|
+
})
|
|
534
|
+
}) : null
|
|
535
|
+
]
|
|
536
|
+
});
|
|
537
|
+
};
|
|
538
|
+
var formatAnnotationFeedback = (groups) => {
|
|
539
|
+
const comments = [];
|
|
540
|
+
for (const group of groups) for (const entry of group.annotations) comments.push({
|
|
541
|
+
content: entry.content,
|
|
542
|
+
filePath: entry.filePath,
|
|
543
|
+
lineNumber: entry.lineNumber,
|
|
544
|
+
lineType: entry.lineType === "context" ? "context" : entry.lineType,
|
|
545
|
+
suggestion: entry.suggestion
|
|
546
|
+
});
|
|
547
|
+
return formatReviewFeedback(comments);
|
|
548
|
+
};
|
|
549
|
+
var useAnnotationsPanel = ({ getLocalComments, onNavigate, onDeleteAnnotation }) => {
|
|
550
|
+
const [isOpen, setIsOpen] = (0, import_react.useState)(false);
|
|
551
|
+
const [copyStatus, setCopyStatus] = (0, import_react.useState)("idle");
|
|
552
|
+
const handleToggle = (0, import_react.useCallback)(() => setIsOpen((prev) => !prev), []);
|
|
553
|
+
const handleClose = (0, import_react.useCallback)(() => setIsOpen(false), []);
|
|
554
|
+
const handleAnnotationClick = (0, import_react.useCallback)((entry) => {
|
|
555
|
+
onNavigate(entry.filePath, entry.lineNumber);
|
|
556
|
+
}, [onNavigate]);
|
|
557
|
+
const handleDeleteAnnotation = (0, import_react.useCallback)((id) => {
|
|
558
|
+
onDeleteAnnotation?.(id);
|
|
559
|
+
}, [onDeleteAnnotation]);
|
|
560
|
+
return {
|
|
561
|
+
buildGroups: (0, import_react.useCallback)(() => {
|
|
562
|
+
const commentsMap = getLocalComments();
|
|
563
|
+
const groups = [];
|
|
564
|
+
for (const [filePath, comments] of commentsMap) {
|
|
565
|
+
if (comments.length === 0) continue;
|
|
566
|
+
const annotations = comments.map((c) => ({
|
|
567
|
+
content: c.content,
|
|
568
|
+
createdAt: c.createdAt,
|
|
569
|
+
filePath: c.filePath,
|
|
570
|
+
id: c.id,
|
|
571
|
+
lineNumber: c.lineNumber,
|
|
572
|
+
lineType: c.lineType,
|
|
573
|
+
suggestion: c.suggestion
|
|
574
|
+
}));
|
|
575
|
+
groups.push({
|
|
576
|
+
annotations,
|
|
577
|
+
filePath
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
groups.sort((a, b) => a.filePath.localeCompare(b.filePath));
|
|
581
|
+
return groups;
|
|
582
|
+
}, [getLocalComments]),
|
|
583
|
+
copyStatus,
|
|
584
|
+
handleAnnotationClick,
|
|
585
|
+
handleClose,
|
|
586
|
+
handleCopyFeedback: (0, import_react.useCallback)(async (groups) => {
|
|
587
|
+
const markdown = formatAnnotationFeedback(groups);
|
|
588
|
+
if (!markdown) return;
|
|
589
|
+
try {
|
|
590
|
+
await navigator.clipboard.writeText(markdown);
|
|
591
|
+
setCopyStatus("copied");
|
|
592
|
+
} catch {
|
|
593
|
+
setCopyStatus("error");
|
|
594
|
+
}
|
|
595
|
+
setTimeout(() => setCopyStatus("idle"), 1500);
|
|
596
|
+
}, []),
|
|
597
|
+
handleDeleteAnnotation,
|
|
598
|
+
handleToggle,
|
|
599
|
+
isOpen,
|
|
600
|
+
totalCount: (0, import_react.useMemo)(() => {
|
|
601
|
+
const commentsMap = getLocalComments();
|
|
602
|
+
let count = 0;
|
|
603
|
+
for (const comments of commentsMap.values()) count += comments.length;
|
|
604
|
+
return count;
|
|
605
|
+
}, [getLocalComments])
|
|
606
|
+
};
|
|
607
|
+
};
|
|
608
|
+
var SSEEventSchema = Struct({
|
|
609
|
+
data: Unknown.pipe(optionalKey),
|
|
610
|
+
timestamp: Number$1,
|
|
611
|
+
type: Literals([
|
|
612
|
+
"todos",
|
|
613
|
+
"reviews",
|
|
614
|
+
"comments",
|
|
615
|
+
"files"
|
|
616
|
+
])
|
|
617
|
+
});
|
|
618
|
+
var decodeSSEEvent = (raw) => {
|
|
619
|
+
try {
|
|
620
|
+
const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
621
|
+
return decodeUnknownOption(SSEEventSchema)(parsed);
|
|
622
|
+
} catch {
|
|
623
|
+
return none();
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
function useEventSource(options = {}) {
|
|
627
|
+
const { url = "/api/events", onEvent, enabled = true } = options;
|
|
628
|
+
const [connected, setConnected] = (0, import_react.useState)(false);
|
|
629
|
+
const onEventRef = (0, import_react.useRef)(onEvent);
|
|
630
|
+
onEventRef.current = onEvent;
|
|
631
|
+
const reconnectTimeoutRef = (0, import_react.useRef)(null);
|
|
632
|
+
const esRef = (0, import_react.useRef)(null);
|
|
633
|
+
(0, import_react.useEffect)(() => {
|
|
634
|
+
if (!enabled || typeof window === "undefined") return;
|
|
635
|
+
function connect() {
|
|
636
|
+
const es = new EventSource(url);
|
|
637
|
+
esRef.current = es;
|
|
638
|
+
es.onopen = () => setConnected(true);
|
|
639
|
+
es.onerror = () => {
|
|
640
|
+
setConnected(false);
|
|
641
|
+
es.close();
|
|
642
|
+
esRef.current = null;
|
|
643
|
+
if (reconnectTimeoutRef.current === null) reconnectTimeoutRef.current = setTimeout(() => {
|
|
644
|
+
reconnectTimeoutRef.current = null;
|
|
645
|
+
connect();
|
|
646
|
+
}, 1e3);
|
|
647
|
+
};
|
|
648
|
+
es.onmessage = (event) => {
|
|
649
|
+
map(decodeSSEEvent(event.data), (data) => onEventRef.current?.(data));
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
connect();
|
|
653
|
+
return () => {
|
|
654
|
+
if (reconnectTimeoutRef.current !== null) {
|
|
655
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
656
|
+
reconnectTimeoutRef.current = null;
|
|
657
|
+
}
|
|
658
|
+
esRef.current?.close();
|
|
659
|
+
esRef.current = null;
|
|
660
|
+
setConnected(false);
|
|
661
|
+
};
|
|
662
|
+
}, [url, enabled]);
|
|
663
|
+
return { connected };
|
|
664
|
+
}
|
|
665
|
+
/** Pick the first non-binary, commentable file. */
|
|
666
|
+
var pickDefaultFile = (files) => {
|
|
667
|
+
for (const file of files) if (file.hunks.length > 0) return file.newPath;
|
|
668
|
+
return files[0]?.newPath ?? null;
|
|
669
|
+
};
|
|
670
|
+
var EmptyDiffState = ({ message }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
671
|
+
className: "rounded-sm border border-border-default bg-surface-elevated p-8 text-center",
|
|
672
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
673
|
+
className: "text-sm text-text-tertiary",
|
|
674
|
+
children: message
|
|
675
|
+
})
|
|
676
|
+
});
|
|
677
|
+
var DiffContent = ({ hasFiles, emptyMessage, file, diffMode, summary, onLocalCommentsChange, viewed, onToggleViewed, pendingDeleteId, onPendingDeleteHandled }) => {
|
|
678
|
+
if (!hasFiles) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyDiffState, { message: emptyMessage });
|
|
679
|
+
if (!file) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyDiffState, { message: "Select a file to view its diff." });
|
|
680
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
681
|
+
className: "space-y-3",
|
|
682
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiffSummary, { summary }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiffView, {
|
|
683
|
+
file,
|
|
684
|
+
diffMode,
|
|
685
|
+
onLocalCommentsChange,
|
|
686
|
+
viewed,
|
|
687
|
+
onToggleViewed,
|
|
688
|
+
pendingDeleteId,
|
|
689
|
+
onPendingDeleteHandled
|
|
690
|
+
})]
|
|
691
|
+
});
|
|
692
|
+
};
|
|
693
|
+
var ChangesPage = () => {
|
|
694
|
+
const data = useLoaderData({ from: "/" });
|
|
695
|
+
const navigate = useNavigate();
|
|
696
|
+
const router = useRouter();
|
|
697
|
+
useEventSource({ onEvent: () => router.invalidate() });
|
|
698
|
+
const [selectedFile, setSelectedFile] = (0, import_react.useState)(() => pickDefaultFile(data.files));
|
|
699
|
+
const [viewedFiles, setViewedFiles] = (0, import_react.useState)(/* @__PURE__ */ new Set());
|
|
700
|
+
const [diffMode, setDiffMode] = (0, import_react.useState)("split");
|
|
701
|
+
const [pendingScope, setPendingScope] = (0, import_react.useState)(null);
|
|
702
|
+
const [exportOpen, setExportOpen] = (0, import_react.useState)(false);
|
|
703
|
+
const localCommentsRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
704
|
+
const [localCommentSnapshot, setLocalCommentSnapshot] = (0, import_react.useState)([]);
|
|
705
|
+
const [annotationVersion, setAnnotationVersion] = (0, import_react.useState)(0);
|
|
706
|
+
const [recoveryDraft, setRecoveryDraft] = (0, import_react.useState)(() => {
|
|
707
|
+
const draft = loadDraft();
|
|
708
|
+
return isDraftRecoverable(draft, data.scope) ? draft : null;
|
|
709
|
+
});
|
|
710
|
+
const selectedFileData = (0, import_react.useMemo)(() => data.files.find((f) => f.newPath === selectedFile) ?? null, [data.files, selectedFile]);
|
|
711
|
+
const getLocalComments = (0, import_react.useCallback)(() => localCommentsRef.current, []);
|
|
712
|
+
const handleAnnotationNavigate = (0, import_react.useCallback)((filePath, _lineNumber) => {
|
|
713
|
+
setSelectedFile(filePath);
|
|
714
|
+
requestAnimationFrame(() => {
|
|
715
|
+
const anchorId = `diff-file-${filePath.replaceAll("/", "-")}`;
|
|
716
|
+
const el = document.querySelector(`#${anchorId}`);
|
|
717
|
+
if (el) el.scrollIntoView({
|
|
718
|
+
behavior: "smooth",
|
|
719
|
+
block: "start"
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
}, []);
|
|
723
|
+
const [pendingDeleteId, setPendingDeleteId] = (0, import_react.useState)(null);
|
|
724
|
+
const handleClearPendingDelete = (0, import_react.useCallback)(() => {
|
|
725
|
+
setPendingDeleteId(null);
|
|
726
|
+
}, []);
|
|
727
|
+
const annotationsPanel = useAnnotationsPanel({
|
|
728
|
+
getLocalComments,
|
|
729
|
+
onDeleteAnnotation: (0, import_react.useCallback)((id) => {
|
|
730
|
+
if ((selectedFile ? localCommentsRef.current.get(selectedFile) : void 0)?.some((c) => c.id === id)) setPendingDeleteId(id);
|
|
731
|
+
else {
|
|
732
|
+
for (const [filePath, comments] of localCommentsRef.current) {
|
|
733
|
+
const filtered = comments.filter((c) => c.id !== id);
|
|
734
|
+
if (filtered.length !== comments.length) {
|
|
735
|
+
if (filtered.length === 0) localCommentsRef.current.delete(filePath);
|
|
736
|
+
else localCommentsRef.current.set(filePath, filtered);
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
setAnnotationVersion((v) => v + 1);
|
|
741
|
+
}
|
|
742
|
+
}, [selectedFile]),
|
|
743
|
+
onNavigate: handleAnnotationNavigate
|
|
744
|
+
});
|
|
745
|
+
const { buildGroups: buildAnnotationGroups } = annotationsPanel;
|
|
746
|
+
const annotationGroups = (0, import_react.useMemo)(() => buildAnnotationGroups(), [buildAnnotationGroups, annotationVersion]);
|
|
747
|
+
(0, import_react.useEffect)(() => {
|
|
748
|
+
setSelectedFile(pickDefaultFile(data.files));
|
|
749
|
+
setViewedFiles(/* @__PURE__ */ new Set());
|
|
750
|
+
setPendingScope(null);
|
|
751
|
+
}, [data.scope, data.files]);
|
|
752
|
+
const handleToggleViewed = (0, import_react.useCallback)((filePath) => {
|
|
753
|
+
setViewedFiles((prev) => {
|
|
754
|
+
const next = new Set(prev);
|
|
755
|
+
if (next.has(filePath)) next.delete(filePath);
|
|
756
|
+
else next.add(filePath);
|
|
757
|
+
return next;
|
|
758
|
+
});
|
|
759
|
+
}, []);
|
|
760
|
+
(0, import_react.useEffect)(() => {
|
|
761
|
+
if (viewedFiles.size === 0) return;
|
|
762
|
+
saveDraft({
|
|
763
|
+
scope: data.scope,
|
|
764
|
+
selectedFile,
|
|
765
|
+
viewedFiles: [...viewedFiles]
|
|
766
|
+
});
|
|
767
|
+
}, [
|
|
768
|
+
viewedFiles,
|
|
769
|
+
selectedFile,
|
|
770
|
+
data.scope
|
|
771
|
+
]);
|
|
772
|
+
useKeyboardShortcuts((0, import_react.useMemo)(() => [{
|
|
773
|
+
description: "New review",
|
|
774
|
+
handler: () => {
|
|
775
|
+
window.location.href = "/reviews/new";
|
|
776
|
+
},
|
|
777
|
+
key: "n"
|
|
778
|
+
}, {
|
|
779
|
+
description: "Go to Reviews",
|
|
780
|
+
handler: () => navigate({ to: "/reviews" }),
|
|
781
|
+
key: "r"
|
|
782
|
+
}], [navigate]));
|
|
783
|
+
const handleSelectFile = (0, import_react.useCallback)((path) => {
|
|
784
|
+
setSelectedFile(path);
|
|
785
|
+
}, []);
|
|
786
|
+
const handleLocalCommentsChange = (0, import_react.useCallback)((filePath, comments) => {
|
|
787
|
+
if (comments.length === 0) localCommentsRef.current.delete(filePath);
|
|
788
|
+
else localCommentsRef.current.set(filePath, comments);
|
|
789
|
+
setAnnotationVersion((v) => v + 1);
|
|
790
|
+
}, []);
|
|
791
|
+
const handleExport = (0, import_react.useCallback)(() => {
|
|
792
|
+
const all = [];
|
|
793
|
+
for (const comments of localCommentsRef.current.values()) for (const c of comments) all.push({
|
|
794
|
+
content: c.content,
|
|
795
|
+
filePath: c.filePath,
|
|
796
|
+
lineNumber: c.lineNumber,
|
|
797
|
+
lineType: c.lineType,
|
|
798
|
+
suggestion: c.suggestion
|
|
799
|
+
});
|
|
800
|
+
setLocalCommentSnapshot(all);
|
|
801
|
+
setExportOpen(true);
|
|
802
|
+
}, []);
|
|
803
|
+
const { handleCopyFeedback } = annotationsPanel;
|
|
804
|
+
const handleCopyAnnotationFeedback = (0, import_react.useCallback)(() => {
|
|
805
|
+
handleCopyFeedback(annotationGroups);
|
|
806
|
+
}, [handleCopyFeedback, annotationGroups]);
|
|
807
|
+
const toggleDiffMode = (0, import_react.useCallback)(() => {
|
|
808
|
+
setDiffMode((prev) => prev === "split" ? "unified" : "split");
|
|
809
|
+
}, []);
|
|
810
|
+
const handleScopeChange = (0, import_react.useCallback)(async (scope) => {
|
|
811
|
+
if (scope === data.scope) return;
|
|
812
|
+
setPendingScope(scope);
|
|
813
|
+
setSelectedFile(null);
|
|
814
|
+
try {
|
|
815
|
+
await navigate({
|
|
816
|
+
search: (previous) => ({
|
|
817
|
+
...previous,
|
|
818
|
+
scope
|
|
819
|
+
}),
|
|
820
|
+
to: "/"
|
|
821
|
+
});
|
|
822
|
+
} finally {
|
|
823
|
+
setPendingScope(null);
|
|
824
|
+
}
|
|
825
|
+
}, [data.scope, navigate]);
|
|
826
|
+
const showStageAction = data.scope === "unstaged" || data.scope === "uncommitted";
|
|
827
|
+
const handleStageFile = (0, import_react.useCallback)((filePath) => {
|
|
828
|
+
clientRuntime.runFork(gen(function* stageFile() {
|
|
829
|
+
const { http } = yield* ApiClient;
|
|
830
|
+
return yield* http.git.stage({ payload: { files: [filePath] } });
|
|
831
|
+
}).pipe(tap(() => promise(() => router.invalidate())), catchCause(() => void_)));
|
|
832
|
+
}, [router]);
|
|
833
|
+
const handleCopyFileDiff = (0, import_react.useCallback)(async () => {
|
|
834
|
+
if (!selectedFileData) return;
|
|
835
|
+
const text = selectedFileData.hunks.flatMap((hunk) => hunk.lines.map((line) => line.content)).join("\n");
|
|
836
|
+
await navigator.clipboard.writeText(text);
|
|
837
|
+
}, [selectedFileData]);
|
|
838
|
+
const handleRestoreDraft = (0, import_react.useCallback)(() => {
|
|
839
|
+
if (!recoveryDraft) return;
|
|
840
|
+
setViewedFiles(new Set(recoveryDraft.viewedFiles));
|
|
841
|
+
if (recoveryDraft.selectedFile && data.files.some((f) => f.newPath === recoveryDraft.selectedFile)) setSelectedFile(recoveryDraft.selectedFile);
|
|
842
|
+
setRecoveryDraft(null);
|
|
843
|
+
clearDraft();
|
|
844
|
+
}, [recoveryDraft, data.files]);
|
|
845
|
+
const handleDismissDraft = (0, import_react.useCallback)(() => {
|
|
846
|
+
setRecoveryDraft(null);
|
|
847
|
+
clearDraft();
|
|
848
|
+
}, []);
|
|
849
|
+
const displayedScope = pendingScope ?? data.scope;
|
|
850
|
+
const isScopePending = pendingScope !== null && pendingScope !== data.scope;
|
|
851
|
+
const emptyStateMessage = DIFF_SCOPE_EMPTY_MESSAGES[data.scope];
|
|
852
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
853
|
+
className: "flex h-full flex-col",
|
|
854
|
+
children: [
|
|
855
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActionBar, {
|
|
856
|
+
repoName: data.repository.name,
|
|
857
|
+
branchName: data.repository.branch,
|
|
858
|
+
scopeLabel: `${DIFF_SCOPE_LABELS[data.scope]} changes`,
|
|
859
|
+
diffMode,
|
|
860
|
+
onToggleDiffMode: toggleDiffMode,
|
|
861
|
+
onExport: handleExport,
|
|
862
|
+
onCopyDiff: handleCopyFileDiff,
|
|
863
|
+
reviewedFileCount: viewedFiles.size,
|
|
864
|
+
totalFileCount: data.files.length,
|
|
865
|
+
unresolvedCount: annotationsPanel.totalCount,
|
|
866
|
+
isAnnotationsOpen: annotationsPanel.isOpen,
|
|
867
|
+
onToggleAnnotations: annotationsPanel.handleToggle
|
|
868
|
+
}),
|
|
869
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
870
|
+
className: "flex min-h-0 flex-1",
|
|
871
|
+
children: [
|
|
872
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileTree, {
|
|
873
|
+
emptyStateMessage,
|
|
874
|
+
files: data.files,
|
|
875
|
+
headerAction: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiffScopeSelector, {
|
|
876
|
+
fileCount: isScopePending ? void 0 : data.files.length,
|
|
877
|
+
isLoading: isScopePending,
|
|
878
|
+
onChange: handleScopeChange,
|
|
879
|
+
value: displayedScope
|
|
880
|
+
}),
|
|
881
|
+
onSelectFile: handleSelectFile,
|
|
882
|
+
selectedFile,
|
|
883
|
+
reviewedFiles: viewedFiles,
|
|
884
|
+
onToggleViewed: handleToggleViewed,
|
|
885
|
+
onStageFile: showStageAction ? handleStageFile : void 0
|
|
886
|
+
}, data.scope),
|
|
887
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
888
|
+
className: "flex-1 overflow-y-auto bg-surface-primary p-4",
|
|
889
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiffContent, {
|
|
890
|
+
hasFiles: data.files.length > 0,
|
|
891
|
+
emptyMessage: emptyStateMessage,
|
|
892
|
+
file: selectedFileData,
|
|
893
|
+
diffMode,
|
|
894
|
+
summary: data.summary,
|
|
895
|
+
onLocalCommentsChange: handleLocalCommentsChange,
|
|
896
|
+
viewed: selectedFile ? viewedFiles.has(selectedFile) : false,
|
|
897
|
+
onToggleViewed: handleToggleViewed,
|
|
898
|
+
pendingDeleteId,
|
|
899
|
+
onPendingDeleteHandled: handleClearPendingDelete
|
|
900
|
+
})
|
|
901
|
+
}),
|
|
902
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(AnnotationsPanel, {
|
|
903
|
+
isOpen: annotationsPanel.isOpen,
|
|
904
|
+
onClose: annotationsPanel.handleClose,
|
|
905
|
+
groups: annotationGroups,
|
|
906
|
+
totalCount: annotationsPanel.totalCount,
|
|
907
|
+
copyStatus: annotationsPanel.copyStatus,
|
|
908
|
+
onAnnotationClick: annotationsPanel.handleAnnotationClick,
|
|
909
|
+
onDeleteAnnotation: annotationsPanel.handleDeleteAnnotation,
|
|
910
|
+
onCopyFeedback: handleCopyAnnotationFeedback
|
|
911
|
+
})
|
|
912
|
+
]
|
|
913
|
+
}),
|
|
914
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExportFeedbackModal, {
|
|
915
|
+
open: exportOpen,
|
|
916
|
+
onOpenChange: setExportOpen,
|
|
917
|
+
localComments: localCommentSnapshot
|
|
918
|
+
}),
|
|
919
|
+
recoveryDraft ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DraftRecoveryModal, {
|
|
920
|
+
open: true,
|
|
921
|
+
draft: recoveryDraft,
|
|
922
|
+
onRestore: handleRestoreDraft,
|
|
923
|
+
onDismiss: handleDismissDraft
|
|
924
|
+
}) : null
|
|
925
|
+
]
|
|
926
|
+
});
|
|
927
|
+
};
|
|
928
|
+
//#endregion
|
|
929
|
+
export { ChangesPage as component };
|