@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
package/dist/cli.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../../../packages/core/src/services/pr-preflight.ts","../../../packages/core/src/services/pr-session.ts","../../../packages/core/src/services/pr-url.ts","../src/cli/config.ts","../src/cli/contracts.ts","../src/cli/commands.ts","../src/cli/parser.ts","../src/cli/runtime.ts","../src/cli/main.ts"],"sourcesContent":["import * as Effect from \"effect/Effect\";\nimport * as Schema from \"effect/Schema\";\n\nimport type { PrMetadata, PrTarget } from \"../schemas/pr\";\nimport { GhService } from \"./gh.service\";\nimport { GitService } from \"./git.service\";\n\n// ---------------------------------------------------------------------------\n// Error\n// ---------------------------------------------------------------------------\n\nexport class PreflightFailure extends Schema.TaggedErrorClass<PreflightFailure>()(\n \"PreflightFailure\",\n {\n exitCode: Schema.Number,\n message: Schema.String,\n phase: Schema.String,\n }\n) {}\n\n// ---------------------------------------------------------------------------\n// Result\n// ---------------------------------------------------------------------------\n\nexport interface PreflightResult {\n readonly affinityMatch: boolean;\n readonly affinityWarning: string | null;\n readonly diff: string;\n readonly localRepoPath: string;\n readonly metadata: PrMetadata;\n readonly target: PrTarget;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extract repository name from a git remote URL.\n *\n * Handles:\n * - SSH: `git@github.com:owner/repo.git`\n * - HTTPS: `https://github.com/owner/repo.git`\n * - HTTPS: `https://github.com/owner/repo`\n */\nconst extractRepoNameFromRemote = (remote: string): string | null => {\n const match = remote.match(/[/:]([^/]+?)(?:\\.git)?$/);\n return match?.[1] ?? null;\n};\n\n// ---------------------------------------------------------------------------\n// Preflight pipeline\n// ---------------------------------------------------------------------------\n\n/**\n * Runs the strict fail-fast preflight sequence for a PR review:\n *\n * 1. Verify `gh` installed\n * 2. Verify `gh` auth for target host\n * 3. Verify local git repository\n * 4. Check repository affinity (warn if mismatch, fail if no repo)\n * 5. Fetch PR metadata and validate it has changed files\n * 6. Fetch PR diff\n */\nexport const runPreflight = Effect.fn(\"PrPreflight.run\")(function* (\n target: PrTarget\n) {\n const gh = yield* GhService;\n const git = yield* GitService;\n\n // Step 1: gh installed\n yield* gh.ensureInstalled.pipe(\n Effect.mapError(\n (e) =>\n new PreflightFailure({\n exitCode: 1,\n message: e.message,\n phase: \"gh_install\",\n })\n )\n );\n\n // Step 2: gh auth\n yield* gh.ensureAuthenticated(target.host).pipe(\n Effect.mapError(\n (e) =>\n new PreflightFailure({\n exitCode: 5,\n message: e.message,\n phase: \"gh_auth\",\n })\n )\n );\n\n // Step 3: local repo\n const localRepoPath = yield* git.getRepositoryPath.pipe(\n Effect.mapError(\n () =>\n new PreflightFailure({\n exitCode: 4,\n message:\n \"Not inside a git repository. Navigate to a repo or use --repo.\",\n phase: \"repo_discovery\",\n })\n )\n );\n\n // Step 4: affinity check\n const repoInfo = yield* git.getRepositoryInfo.pipe(\n Effect.mapError(\n () =>\n new PreflightFailure({\n exitCode: 1,\n message: \"Could not read repository info.\",\n phase: \"repo_info\",\n })\n )\n );\n\n let affinityMatch = false;\n let affinityWarning: string | null = null;\n\n if (repoInfo.remote) {\n const remoteRepo = extractRepoNameFromRemote(repoInfo.remote);\n if (remoteRepo?.toLowerCase() === target.repo.toLowerCase()) {\n affinityMatch = true;\n } else {\n affinityWarning = `PR is from ${target.nwoRef} but local remote points to ${repoInfo.remote}. Review will be stored in ${localRepoPath}/.ringi/`;\n }\n } else {\n affinityWarning = `Local repository has no remote configured. Review will be stored in ${localRepoPath}/.ringi/`;\n }\n\n // Step 5: fetch PR metadata\n const metadata = yield* gh.fetchPrMetadata(target).pipe(\n Effect.mapError(\n (e) =>\n new PreflightFailure({\n exitCode: 1,\n message: `PR not accessible: ${e.message}`,\n phase: \"pr_fetch\",\n })\n )\n );\n\n if (metadata.changedFiles === 0) {\n return yield* new PreflightFailure({\n exitCode: 1,\n message: `PR #${target.prNumber} has no changed files.`,\n phase: \"pr_validation\",\n });\n }\n\n // Step 6: fetch diff\n const diff = yield* gh.fetchPrDiff(target).pipe(\n Effect.mapError(\n (e) =>\n new PreflightFailure({\n exitCode: 1,\n message: `Failed to fetch PR diff: ${e.message}`,\n phase: \"diff_fetch\",\n })\n )\n );\n\n if (!diff.trim()) {\n return yield* new PreflightFailure({\n exitCode: 1,\n message: `PR #${target.prNumber} returned an empty diff.`,\n phase: \"diff_fetch\",\n });\n }\n\n return {\n affinityMatch,\n affinityWarning,\n diff,\n localRepoPath,\n metadata,\n target,\n } satisfies PreflightResult;\n});\n","import * as Effect from \"effect/Effect\";\nimport * as Schema from \"effect/Schema\";\n\nimport { ReviewFileRepo, serializeHunks } from \"../repos/review-file.repo\";\nimport { ReviewRepo } from \"../repos/review.repo\";\nimport type { DiffHunk } from \"../schemas/diff\";\nimport type { PrTarget } from \"../schemas/pr\";\nimport type { ReviewId } from \"../schemas/review\";\nimport { parseDiff, getDiffSummary } from \"./diff.service\";\nimport { GhService } from \"./gh.service\";\nimport type { PreflightResult } from \"./pr-preflight\";\n\n// ---------------------------------------------------------------------------\n// Error\n// ---------------------------------------------------------------------------\n\nexport class PrSessionError extends Schema.TaggedErrorClass<PrSessionError>()(\n \"PrSessionError\",\n {\n code: Schema.String,\n message: Schema.String,\n }\n) {}\n\n// ---------------------------------------------------------------------------\n// Result\n// ---------------------------------------------------------------------------\n\nexport interface PrSessionResult {\n readonly isResumed: boolean;\n readonly isStale: boolean;\n readonly reviewId: ReviewId;\n readonly staleWarning: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Canonical source_ref for a PR: `host/owner/repo#number`. */\nexport const prSourceRef = (target: PrTarget): string =>\n `${target.host}/${target.owner}/${target.repo}#${target.prNumber}`;\n\ninterface StoredManifest {\n headOidAtFetch?: string;\n}\n\nconst parseStoredManifest = (raw: string): StoredManifest => {\n try {\n return JSON.parse(raw) as StoredManifest;\n } catch {\n return {};\n }\n};\n\n// ---------------------------------------------------------------------------\n// Create or resume\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a new PR review session or resumes an existing non-terminal one.\n *\n * Resume logic:\n * - Looks for an existing review with `source_type = \"pull_request\"` and\n * matching `source_ref`.\n * - If found and non-terminal (`in_progress` or `changes_requested`):\n * resumes, checking for upstream drift via head OID comparison.\n * - If found but terminal (`approved`): creates a new session.\n * - If not found: creates a new session.\n *\n * New sessions persist the full diff as hunks in `review_files`, making\n * the review fully offline-resumable after initial fetch.\n */\nexport const createOrResumePrSession = Effect.fn(\"PrSession.createOrResume\")(\n function* (preflight: PreflightResult) {\n const gh = yield* GhService;\n const repo = yield* ReviewRepo;\n const fileRepo = yield* ReviewFileRepo;\n const { target, metadata, diff } = preflight;\n\n const sourceRef = prSourceRef(target);\n\n // ----- Check for existing session ----------------------------------------\n\n const existing = yield* repo.findAll({\n repositoryPath: preflight.localRepoPath,\n sourceType: \"pull_request\",\n pageSize: 100,\n });\n\n const resumable = existing.data.find(\n (r) => r.sourceRef === sourceRef && r.status !== \"approved\"\n );\n\n if (resumable) {\n // Check for upstream drift — fallback to fetched OID if offline\n const currentHeadOid = yield* gh\n .fetchPrHeadOid(target)\n .pipe(\n Effect.catch((e) =>\n Effect.logDebug(\n `Could not fetch current head OID for drift check: ${e.message}`\n ).pipe(Effect.as(metadata.headRefOid))\n )\n );\n\n const manifest = parseStoredManifest(resumable.snapshotData);\n const storedHeadOid = manifest.headOidAtFetch ?? \"\";\n const isStale = storedHeadOid !== \"\" && storedHeadOid !== currentHeadOid;\n\n return {\n isResumed: true,\n isStale,\n reviewId: resumable.id,\n staleWarning: isStale\n ? `PR head has changed (${storedHeadOid.slice(0, 7)} → ${currentHeadOid.slice(0, 7)}). Review data reflects the previous version. Use --force-refresh to re-fetch.`\n : null,\n } satisfies PrSessionResult;\n }\n\n // ----- Create new session ------------------------------------------------\n\n const files = parseDiff(diff);\n if (files.length === 0) {\n return yield* new PrSessionError({\n code: \"NO_CHANGES\",\n message: `PR #${target.prNumber} diff parsed to zero files.`,\n });\n }\n\n const reviewId = crypto.randomUUID() as ReviewId;\n\n const snapshotData = JSON.stringify({\n diffByteSize: Buffer.byteLength(diff, \"utf8\"),\n fetchedAt: new Date().toISOString(),\n headOidAtFetch: metadata.headRefOid,\n metadata,\n source: \"pull_request\",\n target,\n version: 1,\n });\n\n // PR reviews always persist hunks for offline resumability\n const fileInputs = files.map((f) => ({\n additions: f.additions,\n deletions: f.deletions,\n filePath: f.newPath,\n hunksData: serializeHunks(f.hunks as DiffHunk[]),\n oldPath: f.oldPath !== f.newPath ? f.oldPath : null,\n reviewId,\n status: f.status,\n }));\n\n yield* repo.create({\n baseRef: metadata.baseRefOid,\n id: reviewId,\n repositoryPath: preflight.localRepoPath,\n snapshotData,\n sourceRef,\n sourceType: \"pull_request\",\n status: \"in_progress\",\n });\n\n yield* fileRepo.createBulk(fileInputs);\n\n return {\n isResumed: false,\n isStale: false,\n reviewId,\n staleWarning: null,\n } satisfies PrSessionResult;\n }\n);\n\n// ---------------------------------------------------------------------------\n// Force refresh\n// ---------------------------------------------------------------------------\n\n/**\n * Re-fetches PR data for an existing session and updates stored diff/metadata.\n * Existing annotations are preserved (re-anchoring is a v1.1 feature).\n */\nexport const forceRefreshPrSession = Effect.fn(\"PrSession.forceRefresh\")(\n function* (reviewId: ReviewId, target: PrTarget) {\n const gh = yield* GhService;\n const repo = yield* ReviewRepo;\n const fileRepo = yield* ReviewFileRepo;\n\n const review = yield* repo.findById(reviewId);\n if (!review) {\n return yield* new PrSessionError({\n code: \"NOT_FOUND\",\n message: `Review session ${reviewId} not found.`,\n });\n }\n\n // Fetch fresh data\n const metadata = yield* gh.fetchPrMetadata(target);\n const diff = yield* gh.fetchPrDiff(target);\n const files = parseDiff(diff);\n\n const snapshotData = JSON.stringify({\n diffByteSize: Buffer.byteLength(diff, \"utf8\"),\n fetchedAt: new Date().toISOString(),\n headOidAtFetch: metadata.headRefOid,\n metadata,\n source: \"pull_request\",\n target,\n version: 1,\n });\n\n // Update review row\n yield* repo.updateSnapshotData(reviewId, snapshotData);\n\n // Replace file rows (annotations are in a separate table, preserved)\n yield* fileRepo.deleteByReview(reviewId);\n\n const fileInputs = files.map((f) => ({\n additions: f.additions,\n deletions: f.deletions,\n filePath: f.newPath,\n hunksData: serializeHunks(f.hunks as DiffHunk[]),\n oldPath: f.oldPath !== f.newPath ? f.oldPath : null,\n reviewId,\n status: f.status,\n }));\n\n yield* fileRepo.createBulk(fileInputs);\n\n return {\n filesUpdated: files.length,\n headOid: metadata.headRefOid,\n reviewId,\n summary: getDiffSummary(files),\n };\n }\n);\n","import * as Effect from \"effect/Effect\";\nimport * as Schema from \"effect/Schema\";\n\nimport type { PrTarget } from \"../schemas/pr\";\n\n// ---------------------------------------------------------------------------\n// Error\n// ---------------------------------------------------------------------------\n\nexport class InvalidPrUrl extends Schema.TaggedErrorClass<InvalidPrUrl>()(\n \"InvalidPrUrl\",\n {\n message: Schema.String,\n url: Schema.String,\n }\n) {}\n\n// ---------------------------------------------------------------------------\n// Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Quick heuristic: does this string look like a PR URL?\n *\n * Used by the CLI parser to distinguish `review <url>` from `review <verb>`.\n * No ambiguity: no review verb starts with `http`.\n */\nexport const looksLikePrUrl = (s: string): boolean =>\n /^https?:\\/\\/[^/]+\\/[^/]+\\/[^/]+\\/pull\\/\\d+/.test(s);\n\n/**\n * Parses a GitHub PR URL into structured components.\n *\n * Supports:\n * - `https://github.com/owner/repo/pull/42`\n * - `https://github.com/owner/repo/pull/42/files`\n * - `https://github.com/owner/repo/pull/42/commits`\n * - `https://ghe.corp.com/owner/repo/pull/42`\n * - `http://...` (for GHE behind VPN)\n *\n * Does NOT support:\n * - SSH URLs, API URLs, short references like `owner/repo#42`\n */\nexport const parsePrUrl = Effect.fn(\"parsePrUrl\")(function* (raw: string) {\n const url = yield* Effect.try({\n catch: () =>\n new InvalidPrUrl({\n message:\n \"Not a valid URL. Expected: https://github.com/<owner>/<repo>/pull/<number>\",\n url: raw,\n }),\n try: () => new URL(raw),\n });\n\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n return yield* new InvalidPrUrl({\n message: `Unsupported protocol: ${url.protocol}. Expected https:// or http://`,\n url: raw,\n });\n }\n\n // Path: /owner/repo/pull/123[/files|/commits|...]\n const segments = url.pathname.split(\"/\").filter(Boolean);\n\n if (segments.length < 4 || segments[2] !== \"pull\") {\n return yield* new InvalidPrUrl({\n message: \"URL path must match /<owner>/<repo>/pull/<number>\",\n url: raw,\n });\n }\n\n const owner = segments[0]!;\n const repo = segments[1]!;\n const prNumber = Number.parseInt(segments[3]!, 10);\n\n if (!Number.isFinite(prNumber) || prNumber <= 0) {\n return yield* new InvalidPrUrl({\n message: `Invalid PR number: ${segments[3]}`,\n url: raw,\n });\n }\n\n return {\n host: url.host,\n nwoRef: `${owner}/${repo}`,\n owner,\n prNumber,\n repo,\n url: `${url.protocol}//${url.host}/${owner}/${repo}/pull/${prNumber}`,\n } satisfies PrTarget;\n});\n","import { ServiceMap } from \"effect\";\nimport * as Layer from \"effect/Layer\";\n\nexport type CliOutputMode = \"human\" | \"json\";\n\n/**\n * Captures the resolved CLI environment once so downstream layers do not each\n * read process state independently.\n */\nexport interface CliConfigShape {\n readonly color: boolean;\n readonly cwd: string;\n readonly dbPath: string;\n readonly outputMode: CliOutputMode;\n readonly quiet: boolean;\n readonly repoRoot: string;\n readonly verbose: boolean;\n}\n\nexport class CliConfig extends ServiceMap.Service<CliConfig, CliConfigShape>()(\n \"@ringi/CliConfig\"\n) {}\n\n/**\n * Wraps a concrete {@link CliConfigShape} in a layer for the Effect runtime.\n */\nexport const CliConfigLive = (config: CliConfigShape) =>\n Layer.succeed(CliConfig, CliConfig.of(config));\n","import type {\n ReviewSourceType,\n ReviewStatus,\n} from \"@ringi/core/schemas/review\";\nimport * as Schema from \"effect/Schema\";\n\nexport const ExitCode = {\n AuthFailure: 5,\n ResourceNotFound: 3,\n RuntimeFailure: 1,\n StateUnavailable: 4,\n Success: 0,\n UsageError: 2,\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\n// ---------------------------------------------------------------------------\n// Agent-first response envelope (RFC 9457-inspired)\n// ---------------------------------------------------------------------------\n\n/** Error family for agent routing logic — branch on category, not message text. */\nexport type ErrorCategory =\n | \"auth\"\n | \"config\"\n | \"conflict\"\n | \"connection\"\n | \"not_found\"\n | \"server\"\n | \"validation\";\n\n/** Machine-readable param descriptor for a HATEOAS next-action template. */\nexport interface NextActionParam {\n readonly default?: number | string;\n readonly description?: string;\n readonly enum?: readonly string[];\n readonly required?: boolean;\n readonly value?: number | string;\n}\n\n/**\n * A command the agent can run next. Literal commands omit `params`;\n * template commands use `<required>` / `[--flag <value>]` POSIX syntax\n * and include a `params` map so the agent knows what to fill.\n */\nexport interface NextAction {\n readonly command: string;\n readonly description: string;\n readonly params?: Readonly<Record<string, NextActionParam>>;\n}\n\n/** Structured error detail — stable fields agents can branch on. */\nexport interface CliErrorDetail {\n /** Error family for routing logic. */\n readonly category: ErrorCategory;\n /** Machine-readable error code, e.g. `REVIEW_NOT_FOUND`. */\n readonly code: string;\n /** Human-readable explanation of this occurrence. */\n readonly message: string;\n /** Whether a retry can succeed. */\n readonly retryable: boolean;\n /** Seconds to wait before retrying, when `retryable` is true. */\n readonly retry_after?: number;\n /** Documentation URI, e.g. `ringi://errors/REVIEW_NOT_FOUND`. */\n readonly type?: string;\n}\n\ninterface CliSuccessEnvelope<T> {\n readonly command: string;\n readonly next_actions: readonly NextAction[];\n readonly ok: true;\n readonly result: T;\n}\n\nexport interface CliErrorEnvelope {\n readonly command: string;\n readonly error: CliErrorDetail;\n /** Plain-language actionable guidance for the agent. */\n readonly fix: string;\n readonly next_actions: readonly NextAction[];\n readonly ok: false;\n}\n\n// --- Envelope factory helpers ------------------------------------------------\n\nexport const success = <T>(\n command: string,\n result: T,\n nextActions: readonly NextAction[] = []\n): CliSuccessEnvelope<T> => ({\n command,\n next_actions: nextActions,\n ok: true,\n result,\n});\n\nexport const failure = (\n command: string,\n error: CliErrorDetail,\n fix: string,\n nextActions: readonly NextAction[] = []\n): CliErrorEnvelope => ({\n command,\n error,\n fix,\n next_actions: nextActions,\n ok: false,\n});\n\nexport interface GlobalOptions {\n color: boolean;\n dbPath?: string;\n help: boolean;\n json: boolean;\n quiet: boolean;\n repo?: string;\n verbose: boolean;\n version: boolean;\n}\n\nexport interface CommandOutput<T> {\n readonly data: T;\n readonly human?: string;\n readonly nextActions?: readonly NextAction[];\n}\n\n/**\n * Carries an exit code and optional operator-facing details so callers can\n * present a short message without losing the underlying reason.\n */\nexport class CliFailure extends Schema.TaggedErrorClass<CliFailure>()(\n \"CliFailure\",\n {\n details: Schema.String.pipe(Schema.optionalKey),\n exitCode: Schema.Number,\n message: Schema.String,\n }\n) {}\n\n/**\n * Normalized CLI intent shared by the parser and executors so command handlers\n * never have to reason about raw argv tokens.\n */\nexport type ParsedCommand =\n | { readonly kind: \"help\"; readonly topic: readonly string[] }\n | { readonly kind: \"version\" }\n | {\n readonly kind: \"review-list\";\n readonly limit: number;\n readonly page: number;\n readonly source?: ReviewSourceType;\n readonly status?: ReviewStatus;\n }\n | {\n readonly comments: boolean;\n readonly id: string;\n readonly kind: \"review-show\";\n readonly todos: boolean;\n }\n | {\n readonly id: string;\n readonly kind: \"review-export\";\n readonly noResolved: boolean;\n readonly noSnippets: boolean;\n readonly outputPath?: string;\n readonly stdout: boolean;\n }\n | {\n readonly branch?: string;\n readonly commits?: string;\n readonly kind: \"review-create\";\n readonly source: ReviewSourceType;\n readonly title?: string;\n }\n | {\n readonly kind: \"source-list\";\n }\n | {\n readonly branch?: string;\n readonly commits?: string;\n readonly kind: \"source-diff\";\n readonly source: ReviewSourceType;\n readonly stat: boolean;\n }\n | {\n readonly kind: \"todo-list\";\n readonly limit?: number;\n readonly offset: number;\n readonly reviewId?: string;\n readonly status: \"all\" | \"done\" | \"pending\";\n }\n | {\n readonly kind: \"todo-add\";\n readonly position?: number;\n readonly reviewId?: string;\n readonly text: string;\n }\n | {\n readonly id: string;\n readonly kind: \"todo-done\";\n }\n | {\n readonly id: string;\n readonly kind: \"todo-undone\";\n }\n | {\n readonly id: string;\n readonly kind: \"todo-move\";\n readonly position: number;\n }\n | {\n readonly id: string;\n readonly kind: \"todo-remove\";\n readonly yes: boolean;\n }\n | {\n readonly all: boolean;\n readonly doneOnly: boolean;\n readonly kind: \"todo-clear\";\n readonly reviewId?: string;\n readonly yes: boolean;\n }\n | {\n readonly kind: \"review-status\";\n readonly reviewId?: string;\n readonly source?: ReviewSourceType;\n }\n | {\n readonly allComments: boolean;\n readonly id: string;\n readonly kind: \"review-resolve\";\n readonly yes: boolean;\n }\n | {\n readonly auth: boolean;\n readonly cert?: string;\n readonly host: string;\n readonly https: boolean;\n readonly key?: string;\n readonly kind: \"serve\";\n readonly noOpen: boolean;\n readonly password?: string;\n readonly port: number;\n readonly username?: string;\n }\n | {\n readonly kind: \"mcp\";\n readonly logLevel: \"debug\" | \"error\" | \"info\" | \"silent\";\n readonly readonly: boolean;\n }\n | {\n readonly kind: \"doctor\";\n }\n | {\n readonly kind: \"data-migrate\";\n }\n | {\n readonly keepExports: boolean;\n readonly kind: \"data-reset\";\n readonly yes: boolean;\n }\n | {\n readonly kind: \"events\";\n readonly since?: number;\n readonly type?: \"comments\" | \"files\" | \"reviews\" | \"todos\";\n }\n | {\n readonly forceRefresh: boolean;\n readonly kind: \"review-pr\";\n readonly noOpen: boolean;\n readonly port: number;\n readonly prUrl: string;\n };\n","import { writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\n\nimport type { ReviewId } from \"@ringi/core/schemas/review\";\nimport { CommentService } from \"@ringi/core/services/comment.service\";\nimport { getDiffSummary, parseDiff } from \"@ringi/core/services/diff.service\";\nimport { ExportService } from \"@ringi/core/services/export.service\";\nimport { GitService } from \"@ringi/core/services/git.service\";\nimport { runPreflight } from \"@ringi/core/services/pr-preflight\";\nimport {\n createOrResumePrSession,\n forceRefreshPrSession,\n prSourceRef,\n} from \"@ringi/core/services/pr-session\";\nimport { parsePrUrl } from \"@ringi/core/services/pr-url\";\nimport { ReviewService } from \"@ringi/core/services/review.service\";\nimport { TodoService } from \"@ringi/core/services/todo.service\";\nimport * as Effect from \"effect/Effect\";\n\nimport { CliConfig } from \"@/cli/config\";\nimport { CliFailure, ExitCode } from \"@/cli/contracts\";\nimport type { CommandOutput, NextAction, ParsedCommand } from \"@/cli/contracts\";\n\n// ---------------------------------------------------------------------------\n// View-model interfaces (decoupled from service response shapes)\n// ---------------------------------------------------------------------------\n\ninterface ReviewListRow {\n readonly createdAt: string;\n readonly fileCount: number;\n readonly id: string;\n readonly sourceType: string;\n readonly status: string;\n}\n\ninterface ReviewShowComment {\n readonly content: string;\n readonly filePath: string;\n readonly lineNumber: number | null;\n readonly resolved: boolean;\n}\n\ninterface ReviewShowFile {\n readonly additions: number;\n readonly deletions: number;\n readonly filePath: string;\n readonly status: string;\n}\n\ninterface ReviewShowSummary {\n readonly totalAdditions: number;\n readonly totalDeletions: number;\n readonly totalFiles: number;\n}\n\ninterface ReviewShowReview {\n readonly createdAt: string;\n readonly files: readonly ReviewShowFile[];\n readonly id: string;\n readonly sourceRef: string | null;\n readonly sourceType: string;\n readonly status: string;\n readonly summary: ReviewShowSummary;\n}\n\ninterface ReviewShowTodo {\n readonly completed: boolean;\n readonly content: string;\n readonly position: number;\n}\n\ninterface ReviewShowData {\n readonly comments?: readonly ReviewShowComment[];\n readonly review: ReviewShowReview;\n readonly todos?: readonly ReviewShowTodo[];\n}\n\ninterface TodoListItem {\n readonly completed: boolean;\n readonly content: string;\n readonly position: number;\n}\n\ninterface SourceListBranch {\n readonly current: boolean;\n readonly name: string;\n}\n\ninterface SourceListCommit {\n readonly author: string;\n readonly hash: string;\n readonly message: string;\n}\n\ninterface SourceListRepo {\n readonly branch: string;\n readonly name: string;\n readonly path: string;\n readonly remote: string | null;\n}\n\ninterface SourceListStagedFile {\n readonly path: string;\n readonly status: string;\n}\n\ninterface SourceListData {\n readonly branches: readonly SourceListBranch[];\n readonly commits: readonly SourceListCommit[];\n readonly repo: SourceListRepo;\n readonly stagedFiles: readonly SourceListStagedFile[];\n}\n\n// ---------------------------------------------------------------------------\n// Renderers (pure functions, no effects)\n// ---------------------------------------------------------------------------\n\nconst formatTable = (\n headers: readonly string[],\n rows: readonly (readonly string[])[]\n): string => {\n const widths = headers.map((header, index) => {\n const cellWidths = rows.map((row) => row[index]?.length ?? 0);\n return Math.max(header.length, ...cellWidths);\n });\n\n const renderRow = (row: readonly string[]) =>\n row\n .map((cell, index) => cell.padEnd(widths.at(index) ?? 0))\n .join(\" \")\n .trimEnd();\n\n return [\n renderRow(headers),\n renderRow(widths.map((width) => \"-\".repeat(width))),\n ...rows.map(renderRow),\n ].join(\"\\n\");\n};\n\nconst renderReviewList = (reviews: readonly ReviewListRow[]): string => {\n if (reviews.length === 0) {\n return \"No reviews found.\";\n }\n\n return formatTable(\n [\"ID\", \"STATUS\", \"SOURCE\", \"FILES\", \"CREATED\"],\n reviews.map((review) => [\n review.id,\n review.status,\n review.sourceType,\n String(review.fileCount),\n review.createdAt,\n ])\n );\n};\n\nconst renderReviewShow = (input: ReviewShowData): string => {\n const { comments, review, todos } = input;\n const lines = [\n `Review ${review.id}`,\n `Status: ${review.status}`,\n `Source: ${review.sourceType}${review.sourceRef ? ` (${review.sourceRef})` : \"\"}`,\n `Created: ${review.createdAt}`,\n `Files: ${review.summary.totalFiles}`,\n `Diff: +${review.summary.totalAdditions} / -${review.summary.totalDeletions}`,\n ];\n\n if (review.files.length > 0) {\n lines.push(\"\", \"Files:\");\n for (const file of review.files) {\n lines.push(\n `- ${file.status.toUpperCase()} ${file.filePath} (+${file.additions} -${file.deletions})`\n );\n }\n }\n\n if (comments && comments.length > 0) {\n lines.push(\"\", \"Comments:\");\n for (const comment of comments) {\n const location = `${comment.filePath}:${comment.lineNumber ?? \"-\"}`;\n const state = comment.resolved ? \"resolved\" : \"open\";\n lines.push(`- [${state}] ${location} ${comment.content}`);\n }\n }\n\n if (todos && todos.length > 0) {\n lines.push(\"\", \"Todos:\");\n for (const todo of todos) {\n const marker = todo.completed ? \"x\" : \" \";\n lines.push(`- [${marker}] (${todo.position + 1}) ${todo.content}`);\n }\n }\n\n return lines.join(\"\\n\");\n};\n\nconst renderTodoList = (todos: readonly TodoListItem[]): string => {\n if (todos.length === 0) {\n return \"No todos found.\";\n }\n\n return todos\n .map(\n (todo) =>\n `- [${todo.completed ? \"x\" : \" \"}] (${todo.position + 1}) ${todo.content}`\n )\n .join(\"\\n\");\n};\n\nconst renderSourceList = (input: SourceListData): string => {\n const lines = [\n `Repository: ${input.repo.name}`,\n `Path: ${input.repo.path}`,\n `Current branch: ${input.repo.branch}`,\n `Staged files: ${input.stagedFiles.length}`,\n ];\n\n if (input.stagedFiles.length > 0) {\n lines.push(\"\", \"Staged:\");\n for (const file of input.stagedFiles) {\n lines.push(`- ${file.status} ${file.path}`);\n }\n }\n\n if (input.branches.length > 0) {\n lines.push(\"\", \"Branches:\");\n for (const branch of input.branches.slice(0, 10)) {\n lines.push(`- ${branch.current ? \"*\" : \" \"} ${branch.name}`);\n }\n }\n\n if (input.commits.length > 0) {\n lines.push(\"\", \"Recent commits:\");\n for (const commit of input.commits.slice(0, 5)) {\n lines.push(\n `- ${commit.hash.slice(0, 8)} ${commit.message} (${commit.author})`\n );\n }\n }\n\n return lines.join(\"\\n\");\n};\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolves the special \"last\" selector before show/export handlers ask the\n * shared services for a concrete review id.\n */\nconst resolveReviewSelector = Effect.fn(\"CLI.resolveReviewSelector\")(\n function* resolveReviewSelector(selector: string) {\n if (selector !== \"last\") {\n return selector as ReviewId;\n }\n\n const cliConfig = yield* CliConfig;\n const reviewService = yield* ReviewService;\n const result = yield* reviewService.list({\n page: 1,\n pageSize: 1,\n repositoryPath: cliConfig.repoRoot,\n });\n const [review] = result.reviews;\n\n if (!review) {\n return yield* new CliFailure({\n exitCode: ExitCode.ResourceNotFound,\n message: \"No review sessions exist for this repository yet.\",\n });\n }\n\n return review.id;\n }\n);\n\n/**\n * Mutating CLI commands stay server-backed so they share the same write path as\n * the other clients instead of growing a second local-only behavior surface.\n */\nconst requireServerMode = (label: string) =>\n Effect.fail(\n new CliFailure({\n details: \"Start 'ringi serve' and retry the command.\",\n exitCode: ExitCode.StateUnavailable,\n message: `${label} requires a running local Ringi server. Standalone local writes are intentionally unsupported.`,\n })\n );\n\n// ---------------------------------------------------------------------------\n// Diff source strategies (replaces switch in runSourceDiff)\n// ---------------------------------------------------------------------------\n\ntype DiffSourceStrategy = (\n git: GitService[\"Service\"],\n command: Extract<ParsedCommand, { kind: \"source-diff\" }>\n) => Effect.Effect<string, unknown>;\n\nconst diffSourceStrategies: Readonly<Record<string, DiffSourceStrategy>> = {\n branch: (git, command) => git.getBranchDiff(command.branch ?? \"\"),\n commits: (git, command) =>\n git.getCommitDiff(\n (command.commits ?? \"\")\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n ),\n staged: (git) => git.getStagedDiff,\n};\n\n// ---------------------------------------------------------------------------\n// Command handlers (Effect.fn for tracing)\n// ---------------------------------------------------------------------------\n\nconst runReviewList = Effect.fn(\"CLI.reviewList\")(function* runReviewList(\n command: Extract<ParsedCommand, { kind: \"review-list\" }>\n) {\n const reviewService = yield* ReviewService;\n const cliConfig = yield* CliConfig;\n const result = yield* reviewService.list({\n page: command.page,\n pageSize: command.limit,\n repositoryPath: cliConfig.repoRoot,\n sourceType: command.source,\n status: command.status,\n });\n\n const nextActions: NextAction[] = [];\n for (const review of result.reviews.slice(0, 3)) {\n nextActions.push({\n command: `ringi review show ${review.id} --comments --todos`,\n description: `Inspect review ${review.id} (${review.status})`,\n });\n }\n if (result.reviews.length > 0) {\n nextActions.push({\n command: \"ringi review show <id> [--comments] [--todos]\",\n description: \"Show full review details\",\n params: {\n id: { description: \"Review ID or 'last'\", required: true },\n },\n });\n }\n nextActions.push({\n command: \"ringi review create [--source <source>]\",\n description: \"Create a new review session\",\n params: {\n source: { default: \"staged\", enum: [\"staged\", \"branch\", \"commits\"] },\n },\n });\n\n return {\n data: result,\n human: renderReviewList(result.reviews),\n nextActions,\n } satisfies CommandOutput<typeof result>;\n});\n\nconst runReviewShow = Effect.fn(\"CLI.reviewShow\")(function* runReviewShow(\n command: Extract<ParsedCommand, { kind: \"review-show\" }>\n) {\n const reviewService = yield* ReviewService;\n const todoService = yield* TodoService;\n const commentService = yield* CommentService;\n const reviewId = yield* resolveReviewSelector(command.id);\n const review = yield* reviewService.getById(reviewId);\n const comments = command.comments\n ? yield* commentService.getByReview(reviewId)\n : undefined;\n const todos = command.todos\n ? (yield* todoService.list({ reviewId })).data\n : undefined;\n\n const data = { comments, review, todos };\n const nextActions: NextAction[] = [\n {\n command: `ringi review export ${reviewId}`,\n description: \"Export this review as markdown\",\n },\n {\n command: `ringi review show ${reviewId} --comments --todos`,\n description: \"Show with comments and todos\",\n },\n {\n command: \"ringi todo list [--review <review-id>] [--status <status>]\",\n description: \"List todos for this review\",\n params: {\n \"review-id\": { value: reviewId },\n status: { default: \"pending\", enum: [\"pending\", \"done\", \"all\"] },\n },\n },\n {\n command: \"ringi review list\",\n description: \"Back to review list\",\n },\n ];\n\n return {\n data,\n human: renderReviewShow(data),\n nextActions,\n } satisfies CommandOutput<typeof data>;\n});\n\nconst runReviewExport = Effect.fn(\"CLI.reviewExport\")(function* runReviewExport(\n command: Extract<ParsedCommand, { kind: \"review-export\" }>\n) {\n if (command.noResolved || command.noSnippets) {\n yield* new CliFailure({\n exitCode: ExitCode.UsageError,\n message:\n \"--no-resolved and --no-snippets are documented, but the shared export service does not support adapter-level filtering yet.\",\n });\n }\n\n const exportService = yield* ExportService;\n const cliConfig = yield* CliConfig;\n const reviewId = yield* resolveReviewSelector(command.id);\n const markdown = yield* exportService.exportReview(reviewId);\n const outputPath = command.outputPath\n ? resolve(cliConfig.cwd, command.outputPath)\n : undefined;\n\n if (outputPath) {\n yield* Effect.tryPromise({\n catch: (error) =>\n new CliFailure({\n exitCode: ExitCode.RuntimeFailure,\n message: `Failed to write export to ${outputPath}: ${String(error)}`,\n }),\n try: () => writeFile(outputPath, markdown, \"utf8\"),\n });\n }\n\n const shouldPrintMarkdown = command.stdout || !outputPath;\n const data = { markdown, outputPath: outputPath ?? null, reviewId };\n\n const nextActions: NextAction[] = [\n {\n command: `ringi review show ${reviewId}`,\n description: \"View the exported review\",\n },\n {\n command: \"ringi review list\",\n description: \"Back to review list\",\n },\n ];\n\n return {\n data,\n human: shouldPrintMarkdown\n ? markdown\n : `Exported review ${reviewId} to ${outputPath}.`,\n nextActions,\n } satisfies CommandOutput<typeof data>;\n});\n\nconst runSourceList = Effect.fn(\"CLI.sourceList\")(function* runSourceList() {\n const gitService = yield* GitService;\n const repo = yield* gitService.getRepositoryInfo;\n const stagedFiles = yield* gitService.getStagedFiles;\n const branches = yield* gitService.getBranches;\n const commitsResult = yield* gitService.getCommits({\n limit: 10,\n offset: 0,\n });\n const data = {\n branches,\n commits: commitsResult.commits,\n repo,\n stagedFiles,\n };\n\n const nextActions: NextAction[] = [\n {\n command: \"ringi source diff <source> [--stat]\",\n description: \"View diff for a source\",\n params: {\n source: { enum: [\"staged\", \"branch\", \"commits\"] },\n },\n },\n {\n command: \"ringi review create [--source <source>]\",\n description: \"Create a review from a source\",\n params: {\n source: { default: \"staged\", enum: [\"staged\", \"branch\", \"commits\"] },\n },\n },\n {\n command: \"ringi review list\",\n description: \"List existing reviews\",\n },\n ];\n\n return {\n data,\n human: renderSourceList(data),\n nextActions,\n } satisfies CommandOutput<typeof data>;\n});\n\nconst runSourceDiff = Effect.fn(\"CLI.sourceDiff\")(function* runSourceDiff(\n command: Extract<ParsedCommand, { kind: \"source-diff\" }>\n) {\n const gitService = yield* GitService;\n const strategy = diffSourceStrategies[command.source];\n\n if (!strategy) {\n return yield* new CliFailure({\n exitCode: ExitCode.UsageError,\n message: \"Unsupported review source.\",\n });\n }\n\n const diffText = yield* strategy(gitService, command);\n\n if (!diffText.trim()) {\n yield* new CliFailure({\n exitCode: ExitCode.RuntimeFailure,\n message: \"No diff available for the requested source.\",\n });\n }\n\n const files = parseDiff(diffText);\n const data = {\n diff: diffText,\n source: command.source,\n summary: getDiffSummary(files),\n };\n\n const nextActions: NextAction[] = [\n {\n command: `ringi review create --source ${command.source}`,\n description: `Create a review from this ${command.source} diff`,\n },\n {\n command: \"ringi source list\",\n description: \"List repository sources\",\n },\n ];\n\n return {\n data,\n human: command.stat\n ? [\n `Source: ${command.source}`,\n `Files: ${data.summary.totalFiles}`,\n `Additions: ${data.summary.totalAdditions}`,\n `Deletions: ${data.summary.totalDeletions}`,\n ].join(\"\\n\")\n : diffText,\n nextActions,\n } satisfies CommandOutput<typeof data>;\n});\n\nconst runReviewStatus = Effect.fn(\"CLI.reviewStatus\")(function* runReviewStatus(\n command: Extract<ParsedCommand, { kind: \"review-status\" }>\n) {\n const reviewService = yield* ReviewService;\n const todoService = yield* TodoService;\n const commentService = yield* CommentService;\n const gitService = yield* GitService;\n const cliConfig = yield* CliConfig;\n\n const repo = yield* gitService.getRepositoryInfo;\n const stagedFiles = yield* gitService.getStagedFiles;\n\n // Resolve which review to show status for\n let reviewId: string | undefined;\n if (command.reviewId) {\n reviewId = yield* resolveReviewSelector(command.reviewId);\n }\n\n // Get the latest review if none specified\n const reviews = yield* reviewService.list({\n page: 1,\n pageSize: 1,\n repositoryPath: cliConfig.repoRoot,\n sourceType: command.source,\n });\n const latestReview = reviewId\n ? yield* reviewService.getById(reviewId as ReviewId)\n : reviews.reviews[0];\n\n let commentStats:\n | { resolved: number; total: number; unresolved: number }\n | undefined;\n let todoStats:\n | { completed: number; pending: number; total: number }\n | undefined;\n\n if (latestReview) {\n commentStats = yield* commentService.getStats(latestReview.id);\n todoStats = yield* todoService.getStats();\n }\n\n const data = {\n commentStats: commentStats ?? null,\n repository: {\n branch: repo.branch,\n name: repo.name,\n path: repo.path,\n stagedFileCount: stagedFiles.length,\n },\n review: latestReview\n ? {\n createdAt: latestReview.createdAt,\n id: latestReview.id,\n sourceType: latestReview.sourceType,\n status: latestReview.status,\n }\n : null,\n todoStats: todoStats ?? null,\n };\n\n const lines = [\n `Repository: ${repo.name}`,\n `Branch: ${repo.branch}`,\n `Staged files: ${stagedFiles.length}`,\n ];\n\n if (latestReview) {\n lines.push(\n \"\",\n `Review: ${latestReview.id}`,\n `Status: ${latestReview.status}`,\n `Source: ${latestReview.sourceType}`\n );\n if (commentStats) {\n lines.push(\n `Comments: ${commentStats.unresolved ?? 0} unresolved / ${commentStats.total} total`\n );\n }\n if (todoStats) {\n lines.push(\n `Todos: ${todoStats.pending} pending / ${todoStats.total} total`\n );\n }\n } else {\n lines.push(\"\", \"No review sessions found.\");\n }\n\n const nextActions: NextAction[] = [];\n if (latestReview) {\n nextActions.push(\n {\n command: `ringi review show ${latestReview.id} --comments --todos`,\n description: \"Inspect the latest review\",\n },\n {\n command: `ringi review export ${latestReview.id}`,\n description: \"Export the latest review\",\n }\n );\n }\n nextActions.push({\n command: \"ringi review create [--source <source>]\",\n description: \"Create a new review session\",\n params: {\n source: { default: \"staged\", enum: [\"staged\", \"branch\", \"commits\"] },\n },\n });\n\n return {\n data,\n human: lines.join(\"\\n\"),\n nextActions,\n } satisfies CommandOutput<typeof data>;\n});\n\nconst runTodoList = Effect.fn(\"CLI.todoList\")(function* runTodoList(\n command: Extract<ParsedCommand, { kind: \"todo-list\" }>\n) {\n const todoService = yield* TodoService;\n const result = yield* todoService.list({\n completed: command.status === \"all\" ? undefined : command.status === \"done\",\n limit: command.limit,\n offset: command.offset,\n reviewId: command.reviewId,\n });\n\n const nextActions: NextAction[] = [];\n if (command.reviewId) {\n nextActions.push({\n command: `ringi review show ${command.reviewId}`,\n description: \"View the associated review\",\n });\n }\n nextActions.push(\n {\n command: \"ringi todo add --text <text> [--review <review-id>]\",\n description: \"Add a new todo\",\n params: {\n text: { description: \"Todo text\", required: true },\n },\n },\n {\n command: \"ringi review list\",\n description: \"List reviews\",\n }\n );\n\n return {\n data: result,\n human: renderTodoList(result.data),\n nextActions,\n } satisfies CommandOutput<typeof result>;\n});\n\n// ---------------------------------------------------------------------------\n// Command registry (replaces switch-based dispatch)\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// PR review handler\n// ---------------------------------------------------------------------------\n\nconst runReviewPr = Effect.fn(\"CLI.reviewPr\")(function* runReviewPr(\n command: Extract<ParsedCommand, { kind: \"review-pr\" }>\n) {\n // Step 1: parse and validate URL\n const target = yield* parsePrUrl(command.prUrl).pipe(\n Effect.mapError(\n (e) =>\n new CliFailure({\n exitCode: ExitCode.UsageError,\n message: e.message,\n })\n )\n );\n\n // Step 2: run preflight (gh install, auth, repo, metadata, diff)\n const preflight = yield* runPreflight(target).pipe(\n Effect.mapError(\n (e) =>\n new CliFailure({\n exitCode: e.exitCode as ExitCode,\n message: e.message,\n })\n )\n );\n\n if (preflight.affinityWarning) {\n yield* Effect.logWarning(preflight.affinityWarning);\n }\n\n // Step 3: check for force-refresh on existing session\n let session: {\n isResumed: boolean;\n isStale: boolean;\n reviewId: ReviewId;\n staleWarning: string | null;\n };\n\n if (command.forceRefresh) {\n // Find existing session to refresh\n const reviewService = yield* ReviewService;\n const sourceRef = prSourceRef(target);\n const cliConfig = yield* CliConfig;\n const existing = yield* reviewService.list({\n repositoryPath: cliConfig.repoRoot,\n sourceType: \"pull_request\",\n pageSize: 100,\n });\n\n const resumable = existing.reviews.find(\n (r: { sourceRef: string | null; status: string }) =>\n r.sourceRef === sourceRef && r.status !== \"approved\"\n );\n\n if (resumable) {\n yield* forceRefreshPrSession(resumable.id as ReviewId, target).pipe(\n Effect.mapError(\n (e) =>\n new CliFailure({\n exitCode: ExitCode.RuntimeFailure,\n message: e.message,\n })\n )\n );\n session = {\n isResumed: true,\n isStale: false,\n reviewId: resumable.id as ReviewId,\n staleWarning: null,\n };\n } else {\n // No existing session — create fresh\n session = yield* createOrResumePrSession(preflight).pipe(\n Effect.mapError(\n (e) =>\n new CliFailure({\n exitCode: ExitCode.RuntimeFailure,\n message: e.message,\n })\n )\n );\n }\n } else {\n // Normal create-or-resume\n session = yield* createOrResumePrSession(preflight).pipe(\n Effect.mapError(\n (e) =>\n new CliFailure({\n exitCode: ExitCode.RuntimeFailure,\n message: e.message,\n })\n )\n );\n }\n\n if (session.staleWarning) {\n yield* Effect.logWarning(session.staleWarning);\n }\n\n const serverUrl = `http://localhost:${command.port}`;\n const reviewUrl = `${serverUrl}/review/${session.reviewId}`;\n\n const data = {\n isResumed: session.isResumed,\n isStale: session.isStale,\n prNumber: target.prNumber,\n prUrl: target.url,\n reviewId: session.reviewId,\n reviewUrl,\n };\n\n const statusLabel = session.isResumed\n ? command.forceRefresh\n ? \"(refreshed)\"\n : \"(resumed)\"\n : \"(new)\";\n\n const humanLines = [\n `PR #${target.prNumber}: ${preflight.metadata.title}`,\n `Review: ${session.reviewId} ${statusLabel}`,\n `Author: ${preflight.metadata.author.login}`,\n `Branch: ${preflight.metadata.headRefName} → ${preflight.metadata.baseRefName}`,\n `Files: ${preflight.metadata.changedFiles} (+${preflight.metadata.additions} -${preflight.metadata.deletions})`,\n \"\",\n `Server: ${serverUrl}`,\n `Review: ${reviewUrl}`,\n ];\n\n if (preflight.metadata.isDraft) {\n humanLines.splice(1, 0, \"⚠ Draft PR\");\n }\n\n if (\n preflight.metadata.state === \"CLOSED\" ||\n preflight.metadata.state === \"MERGED\"\n ) {\n humanLines.splice(1, 0, `⚠ This PR is ${preflight.metadata.state}`);\n }\n\n const nextActions: NextAction[] = [\n {\n command: `ringi review show ${session.reviewId} --comments --todos`,\n description: \"Inspect review details\",\n },\n {\n command: `ringi review export ${session.reviewId}`,\n description: \"Export review as markdown\",\n },\n ];\n\n if (session.isStale) {\n nextActions.unshift({\n command: `ringi review ${command.prUrl} --force-refresh`,\n description: \"Re-fetch PR data with latest changes\",\n });\n }\n\n return {\n data,\n human: humanLines.join(\"\\n\"),\n nextActions,\n } satisfies CommandOutput<typeof data>;\n});\n\n// ---------------------------------------------------------------------------\n// Command registry (replaces switch-based dispatch)\n// ---------------------------------------------------------------------------\n\ntype CommandHandler = (\n command: ParsedCommand\n) => Effect.Effect<CommandOutput<unknown>, unknown, unknown>;\n\n/**\n * Data-driven command registry. Each command kind maps to its handler.\n * Adding a new command means adding one entry — no switch duplication.\n */\nconst COMMAND_HANDLERS: Readonly<Record<string, CommandHandler>> = {\n \"data-migrate\": () => requireServerMode(\"ringi data migrate\"),\n \"data-reset\": () => requireServerMode(\"ringi data reset\"),\n doctor: () =>\n Effect.succeed({\n data: { checks: [], ok: true },\n human: \"ringi doctor: not yet implemented.\",\n nextActions: [],\n } satisfies CommandOutput<unknown>),\n events: () => requireServerMode(\"ringi events\"),\n mcp: () =>\n Effect.fail(\n new CliFailure({\n exitCode: ExitCode.UsageError,\n message:\n \"ringi mcp is a runtime command. Use it directly, not through the command dispatcher.\",\n })\n ),\n \"review-create\": () => requireServerMode(\"ringi review create\"),\n \"review-export\": (c) =>\n runReviewExport(c as Extract<ParsedCommand, { kind: \"review-export\" }>),\n \"review-list\": (c) =>\n runReviewList(c as Extract<ParsedCommand, { kind: \"review-list\" }>),\n \"review-pr\": (c) =>\n runReviewPr(c as Extract<ParsedCommand, { kind: \"review-pr\" }>),\n \"review-resolve\": () => requireServerMode(\"ringi review resolve\"),\n \"review-show\": (c) =>\n runReviewShow(c as Extract<ParsedCommand, { kind: \"review-show\" }>),\n \"review-status\": (c) =>\n runReviewStatus(c as Extract<ParsedCommand, { kind: \"review-status\" }>),\n serve: () =>\n Effect.fail(\n new CliFailure({\n exitCode: ExitCode.UsageError,\n message:\n \"ringi serve is a runtime command. Use it directly, not through the command dispatcher.\",\n })\n ),\n \"source-diff\": (c) =>\n runSourceDiff(c as Extract<ParsedCommand, { kind: \"source-diff\" }>),\n \"source-list\": () => runSourceList(),\n \"todo-add\": () => requireServerMode(\"ringi todo add\"),\n \"todo-clear\": () => requireServerMode(\"ringi todo clear\"),\n \"todo-done\": () => requireServerMode(\"ringi todo done\"),\n \"todo-list\": (c) =>\n runTodoList(c as Extract<ParsedCommand, { kind: \"todo-list\" }>),\n \"todo-move\": () => requireServerMode(\"ringi todo move\"),\n \"todo-remove\": () => requireServerMode(\"ringi todo remove\"),\n \"todo-undone\": () => requireServerMode(\"ringi todo undone\"),\n};\n\n/** Human-readable command label for the JSON envelope `command` field. */\nconst COMMAND_LABELS: Readonly<Record<string, string>> = {\n \"data-migrate\": \"ringi data migrate\",\n \"data-reset\": \"ringi data reset\",\n doctor: \"ringi doctor\",\n events: \"ringi events\",\n mcp: \"ringi mcp\",\n \"review-create\": \"ringi review create\",\n \"review-export\": \"ringi review export\",\n \"review-list\": \"ringi review list\",\n \"review-pr\": \"ringi review <pr-url>\",\n \"review-resolve\": \"ringi review resolve\",\n \"review-show\": \"ringi review show\",\n \"review-status\": \"ringi review status\",\n serve: \"ringi serve\",\n \"source-diff\": \"ringi source diff\",\n \"source-list\": \"ringi source list\",\n \"todo-add\": \"ringi todo add\",\n \"todo-clear\": \"ringi todo clear\",\n \"todo-done\": \"ringi todo done\",\n \"todo-list\": \"ringi todo list\",\n \"todo-move\": \"ringi todo move\",\n \"todo-remove\": \"ringi todo remove\",\n \"todo-undone\": \"ringi todo undone\",\n};\n\nexport const commandLabel = (command: ParsedCommand): string =>\n COMMAND_LABELS[command.kind] ?? `ringi ${command.kind}`;\n\nexport const runCommand = (command: ParsedCommand) => {\n const handler = COMMAND_HANDLERS[command.kind];\n if (!handler) {\n return Effect.fail(\n new CliFailure({\n exitCode: ExitCode.UsageError,\n message: `No executable handler exists for ${command.kind}.`,\n })\n );\n }\n return handler(command);\n};\n","import type {\n ReviewSourceType,\n ReviewStatus,\n} from \"@ringi/core/schemas/review\";\nimport { looksLikePrUrl } from \"@ringi/core/services/pr-url\";\nimport * as Option from \"effect/Option\";\nimport * as Result from \"effect/Result\";\n\nimport { CliFailure, ExitCode } from \"@/cli/contracts\";\nimport type { GlobalOptions, ParsedCommand } from \"@/cli/contracts\";\n\n// ---------------------------------------------------------------------------\n// Shared validation sets\n// ---------------------------------------------------------------------------\n\nconst REVIEW_SOURCES = new Set<ReviewSourceType>([\n \"branch\",\n \"commits\",\n \"pull_request\",\n \"staged\",\n]);\nconst REVIEW_STATUSES = new Set<ReviewStatus>([\n \"approved\",\n \"changes_requested\",\n \"in_progress\",\n]);\nconst TODO_STATUSES = new Set<string>([\"all\", \"done\", \"pending\"]);\n\n// ---------------------------------------------------------------------------\n// Parse state\n// ---------------------------------------------------------------------------\n\ninterface ParseState {\n index: number;\n readonly options: GlobalOptions;\n readonly tokens: readonly string[];\n}\n\ntype ParseResult = Result.Result<ParsedCommand, CliFailure>;\n\nconst usageError = (message: string): CliFailure =>\n new CliFailure({ exitCode: ExitCode.UsageError, message });\n\n// ---------------------------------------------------------------------------\n// Reusable value extractors\n// ---------------------------------------------------------------------------\n\n/**\n * Consumes the next token as a flag value, advancing the cursor by 2.\n * Rejects another flag in the value slot so typos fail fast.\n */\nconst requireValue = (\n state: ParseState,\n flag: string\n): Option.Option<CliFailure> => {\n const value = state.tokens[state.index + 1];\n if (!value || value.startsWith(\"-\")) {\n return Option.some(usageError(`Missing value for ${flag}.`));\n }\n state.index += 2;\n return Option.none();\n};\n\n/** Peek at the value that {@link requireValue} would consume. */\nconst peekValue = (state: ParseState): string =>\n state.tokens[state.index + 1] ?? \"\";\n\nconst decodePositiveInt = (\n raw: string,\n flag: string\n): Result.Result<number, CliFailure> => {\n const value = Number.parseInt(raw, 10);\n if (!Number.isInteger(value) || value < 0) {\n return Result.fail(usageError(`${flag} must be a non-negative integer.`));\n }\n return Result.succeed(value);\n};\n\nconst decodeEnum = <T extends string>(\n raw: string,\n valid: ReadonlySet<T>,\n label: string\n): Result.Result<T, CliFailure> => {\n if (!valid.has(raw as T)) {\n return Result.fail(usageError(`Invalid ${label}: ${raw}.`));\n }\n return Result.succeed(raw as T);\n};\n\n// ---------------------------------------------------------------------------\n// Flag handler framework\n// ---------------------------------------------------------------------------\n\n/**\n * A flag handler receives the parse state and a mutable accumulator.\n * It returns `Option.some(CliFailure)` on error, `Option.none()` on success.\n * Cursor advancement is handled by the handler (1 for booleans, 2 for values\n * via {@link requireValue}).\n */\ntype FlagHandler<Acc> = (\n state: ParseState,\n acc: Acc\n) => Option.Option<CliFailure>;\n\n// -- Flag handler factories -------------------------------------------------\n\n/** Boolean flag: sets a key to `true`, advances cursor by 1. */\nconst boolFlag =\n <Acc>(key: keyof Acc & string): FlagHandler<Acc> =>\n (state, acc) => {\n (acc as Record<string, unknown>)[key] = true;\n state.index += 1;\n return Option.none();\n };\n\n/** String flag: consumes next token, assigns to key. */\nconst stringFlag =\n <Acc>(key: keyof Acc & string): FlagHandler<Acc> =>\n (state, acc) => {\n const flag = state.tokens[state.index] ?? \"\";\n const value = peekValue(state);\n const error = requireValue(state, flag);\n if (Option.isSome(error)) {\n return error;\n }\n (acc as Record<string, unknown>)[key] = value;\n return Option.none();\n };\n\n/** Positive integer flag with an optional minimum (exclusive). */\nconst positiveIntFlag =\n <Acc>(\n key: keyof Acc & string,\n opts?: { readonly min?: number }\n ): FlagHandler<Acc> =>\n (state, acc) => {\n const flag = state.tokens[state.index] ?? \"\";\n const raw = peekValue(state);\n const error = requireValue(state, flag);\n if (Option.isSome(error)) {\n return error;\n }\n const decoded = decodePositiveInt(raw, flag);\n if (Result.isFailure(decoded)) {\n return Option.some(decoded.failure);\n }\n if (opts?.min !== undefined && decoded.success <= opts.min) {\n return Option.some(\n usageError(`${flag} must be greater than ${opts.min}.`)\n );\n }\n (acc as Record<string, unknown>)[key] = decoded.success;\n return Option.none();\n };\n\n/** Enum flag: consumes next token, validates membership, assigns to key. */\nconst enumFlag =\n <Acc>(\n key: keyof Acc & string,\n valid: ReadonlySet<string>,\n label: string\n ): FlagHandler<Acc> =>\n (state, acc) => {\n const flag = state.tokens[state.index] ?? \"\";\n const raw = peekValue(state);\n const error = requireValue(state, flag);\n if (Option.isSome(error)) {\n return error;\n }\n const decoded = decodeEnum(raw, valid, label);\n if (Result.isFailure(decoded)) {\n return Option.some(decoded.failure);\n }\n (acc as Record<string, unknown>)[key] = decoded.success;\n return Option.none();\n };\n\n// ---------------------------------------------------------------------------\n// Global flags (must precede runFlagLoop which calls maybeParseGlobalFlag)\n// ---------------------------------------------------------------------------\n\nconst createDefaultOptions = (): GlobalOptions => ({\n color: true,\n dbPath: undefined,\n help: false,\n json: false,\n quiet: false,\n repo: undefined,\n verbose: false,\n version: false,\n});\n\n/**\n * Global flags are accepted before or after subcommands because wrappers often\n * prepend them without preserving the CLI's preferred ordering.\n */\nconst GLOBAL_FLAG_HANDLERS: Readonly<\n Record<string, FlagHandler<GlobalOptions>>\n> = {\n \"--db-path\": stringFlag(\"dbPath\"),\n \"--help\": boolFlag(\"help\"),\n \"--json\": boolFlag(\"json\"),\n \"--no-color\": (state, acc) => {\n acc.color = false;\n state.index += 1;\n return Option.none();\n },\n \"--quiet\": boolFlag(\"quiet\"),\n \"--repo\": stringFlag(\"repo\"),\n \"--verbose\": boolFlag(\"verbose\"),\n \"--version\": boolFlag(\"version\"),\n};\n\nconst maybeParseGlobalFlag = (state: ParseState): boolean => {\n const token = state.tokens[state.index];\n if (!token) {\n return false;\n }\n const handler = GLOBAL_FLAG_HANDLERS[token];\n if (!handler) {\n return false;\n }\n // Global flag handlers do not fail — they just set values.\n handler(state, state.options);\n return true;\n};\n\n// -- Generic flag loop runner -----------------------------------------------\n\n/**\n * Consumes all remaining tokens in {@link state} by dispatching to the matching\n * handler in {@link handlers}. Global flags are tried first. Unknown flags\n * produce a usage error naming the {@link commandLabel}.\n */\nconst runFlagLoop = <Acc>(\n state: ParseState,\n acc: Acc,\n handlers: Readonly<Record<string, FlagHandler<Acc>>>,\n commandLabel: string\n): Option.Option<CliFailure> => {\n while (state.index < state.tokens.length) {\n if (maybeParseGlobalFlag(state)) {\n continue;\n }\n const token = state.tokens[state.index] ?? \"\";\n const handler = handlers[token];\n if (!handler) {\n return Option.some(\n usageError(`Unknown flag for ${commandLabel}: ${token}.`)\n );\n }\n const error = handler(state, acc);\n if (Option.isSome(error)) {\n return error;\n }\n }\n return Option.none();\n};\n\n// ---------------------------------------------------------------------------\n// Command parsers (table-driven)\n// ---------------------------------------------------------------------------\n\n// -- review list ------------------------------------------------------------\n\ninterface ReviewListAcc {\n limit: number;\n page: number;\n source: ReviewSourceType | undefined;\n status: ReviewStatus | undefined;\n}\n\nconst REVIEW_LIST_FLAGS: Readonly<Record<string, FlagHandler<ReviewListAcc>>> =\n {\n \"--limit\": positiveIntFlag(\"limit\", { min: 0 }),\n \"--page\": positiveIntFlag(\"page\", { min: 0 }),\n \"--source\": enumFlag(\"source\", REVIEW_SOURCES, \"review source\"),\n \"--status\": enumFlag(\"status\", REVIEW_STATUSES, \"review status\"),\n };\n\nconst parseReviewList = (state: ParseState): ParseResult => {\n const acc: ReviewListAcc = {\n limit: 20,\n page: 1,\n source: undefined,\n status: undefined,\n };\n const error = runFlagLoop(state, acc, REVIEW_LIST_FLAGS, \"review list\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"review-list\" as const, ...acc });\n};\n\n// -- review show ------------------------------------------------------------\n\ninterface ReviewShowAcc {\n comments: boolean;\n todos: boolean;\n}\n\nconst REVIEW_SHOW_FLAGS: Readonly<Record<string, FlagHandler<ReviewShowAcc>>> =\n {\n \"--comments\": boolFlag(\"comments\"),\n \"--todos\": boolFlag(\"todos\"),\n };\n\nconst parseReviewShow = (state: ParseState): ParseResult => {\n const id = state.tokens[state.index];\n if (!id) {\n return Result.fail(usageError(\"review show requires <id|last>.\"));\n }\n state.index += 1;\n\n const acc: ReviewShowAcc = { comments: false, todos: false };\n const error = runFlagLoop(state, acc, REVIEW_SHOW_FLAGS, \"review show\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ id, kind: \"review-show\" as const, ...acc });\n};\n\n// -- review export ----------------------------------------------------------\n\ninterface ReviewExportAcc {\n noResolved: boolean;\n noSnippets: boolean;\n outputPath: string | undefined;\n stdout: boolean;\n}\n\nconst REVIEW_EXPORT_FLAGS: Readonly<\n Record<string, FlagHandler<ReviewExportAcc>>\n> = {\n \"--no-resolved\": boolFlag(\"noResolved\"),\n \"--no-snippets\": boolFlag(\"noSnippets\"),\n \"--output\": stringFlag(\"outputPath\"),\n \"--stdout\": boolFlag(\"stdout\"),\n};\n\nconst parseReviewExport = (state: ParseState): ParseResult => {\n const id = state.tokens[state.index];\n if (!id) {\n return Result.fail(usageError(\"review export requires <id|last>.\"));\n }\n state.index += 1;\n\n const acc: ReviewExportAcc = {\n noResolved: false,\n noSnippets: false,\n outputPath: undefined,\n stdout: false,\n };\n const error = runFlagLoop(state, acc, REVIEW_EXPORT_FLAGS, \"review export\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ id, kind: \"review-export\" as const, ...acc });\n};\n\n// -- review create ----------------------------------------------------------\n\ninterface ReviewCreateAcc {\n branch: string | undefined;\n commits: string | undefined;\n source: ReviewSourceType;\n title: string | undefined;\n}\n\nconst REVIEW_CREATE_FLAGS: Readonly<\n Record<string, FlagHandler<ReviewCreateAcc>>\n> = {\n \"--branch\": stringFlag(\"branch\"),\n \"--commits\": stringFlag(\"commits\"),\n \"--source\": enumFlag(\"source\", REVIEW_SOURCES, \"review source\"),\n \"--title\": stringFlag(\"title\"),\n};\n\nconst validateReviewCreate = (\n acc: ReviewCreateAcc\n): Option.Option<CliFailure> => {\n if (acc.source === \"branch\" && !acc.branch) {\n return Option.some(\n usageError(\"review create --source branch requires --branch.\")\n );\n }\n if (acc.source === \"commits\" && !acc.commits) {\n return Option.some(\n usageError(\"review create --source commits requires --commits.\")\n );\n }\n if (acc.source === \"staged\" && (acc.branch || acc.commits)) {\n return Option.some(\n usageError(\n \"review create --source staged does not accept --branch or --commits.\"\n )\n );\n }\n return Option.none();\n};\n\nconst parseReviewCreate = (state: ParseState): ParseResult => {\n const acc: ReviewCreateAcc = {\n branch: undefined,\n commits: undefined,\n source: \"staged\",\n title: undefined,\n };\n const error = runFlagLoop(state, acc, REVIEW_CREATE_FLAGS, \"review create\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n const validationError = validateReviewCreate(acc);\n if (Option.isSome(validationError)) {\n return Result.fail(validationError.value);\n }\n return Result.succeed({ kind: \"review-create\" as const, ...acc });\n};\n\n// -- source diff ------------------------------------------------------------\n\ninterface SourceDiffAcc {\n branch: string | undefined;\n commits: string | undefined;\n stat: boolean;\n}\n\nconst SOURCE_DIFF_FLAGS: Readonly<Record<string, FlagHandler<SourceDiffAcc>>> =\n {\n \"--branch\": stringFlag(\"branch\"),\n \"--commits\": stringFlag(\"commits\"),\n \"--stat\": boolFlag(\"stat\"),\n };\n\nconst validateSourceDiff = (\n source: ReviewSourceType,\n acc: SourceDiffAcc\n): Option.Option<CliFailure> => {\n if (source === \"branch\" && !acc.branch) {\n return Option.some(usageError(\"source diff branch requires --branch.\"));\n }\n if (source === \"commits\" && !acc.commits) {\n return Option.some(usageError(\"source diff commits requires --commits.\"));\n }\n return Option.none();\n};\n\nconst parseSourceDiff = (state: ParseState): ParseResult => {\n const source = state.tokens[state.index] as ReviewSourceType | undefined;\n if (!source || !REVIEW_SOURCES.has(source)) {\n return Result.fail(\n usageError(\"source diff requires <staged|branch|commits>.\")\n );\n }\n state.index += 1;\n\n const acc: SourceDiffAcc = {\n branch: undefined,\n commits: undefined,\n stat: false,\n };\n const error = runFlagLoop(state, acc, SOURCE_DIFF_FLAGS, \"source diff\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n const validationError = validateSourceDiff(source, acc);\n if (Option.isSome(validationError)) {\n return Result.fail(validationError.value);\n }\n return Result.succeed({ kind: \"source-diff\" as const, source, ...acc });\n};\n\n// -- todo list --------------------------------------------------------------\n\ninterface TodoListAcc {\n limit: number | undefined;\n offset: number;\n reviewId: string | undefined;\n status: \"all\" | \"done\" | \"pending\";\n}\n\nconst TODO_LIST_FLAGS: Readonly<Record<string, FlagHandler<TodoListAcc>>> = {\n \"--limit\": positiveIntFlag(\"limit\"),\n \"--offset\": positiveIntFlag(\"offset\"),\n \"--review\": stringFlag(\"reviewId\"),\n \"--status\": enumFlag(\"status\", TODO_STATUSES, \"todo status\"),\n};\n\nconst parseTodoList = (state: ParseState): ParseResult => {\n const acc: TodoListAcc = {\n limit: undefined,\n offset: 0,\n reviewId: undefined,\n status: \"pending\",\n };\n const error = runFlagLoop(state, acc, TODO_LIST_FLAGS, \"todo list\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"todo-list\" as const, ...acc });\n};\n\n// -- positional-id-only commands (shared factory) ---------------------------\n\n/**\n * Factory for commands that take exactly one positional `<id>` and no\n * command-specific flags (only globals). Avoids duplication for done/undone.\n */\nconst positionalIdParser =\n <K extends string>(kind: K, label: string) =>\n (state: ParseState): ParseResult => {\n const id = state.tokens[state.index];\n if (!id) {\n return Result.fail(usageError(`${label} requires <id>.`));\n }\n state.index += 1;\n\n while (state.index < state.tokens.length) {\n if (!maybeParseGlobalFlag(state)) {\n return Result.fail(\n usageError(`Unknown flag for ${label}: ${state.tokens[state.index]}.`)\n );\n }\n }\n return Result.succeed({ id, kind } as ParsedCommand);\n };\n\nconst parseTodoDone = positionalIdParser(\"todo-done\" as const, \"todo done\");\nconst parseTodoUndone = positionalIdParser(\n \"todo-undone\" as const,\n \"todo undone\"\n);\n\n// -- todo move --------------------------------------------------------------\n\ninterface TodoMoveAcc {\n position: number | undefined;\n}\n\nconst TODO_MOVE_FLAGS: Readonly<Record<string, FlagHandler<TodoMoveAcc>>> = {\n \"--position\": positiveIntFlag(\"position\"),\n};\n\nconst parseTodoMove = (state: ParseState): ParseResult => {\n const id = state.tokens[state.index];\n if (!id) {\n return Result.fail(usageError(\"todo move requires <id>.\"));\n }\n state.index += 1;\n\n const acc: TodoMoveAcc = { position: undefined };\n const error = runFlagLoop(state, acc, TODO_MOVE_FLAGS, \"todo move\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n if (acc.position === undefined) {\n return Result.fail(usageError(\"todo move requires --position.\"));\n }\n return Result.succeed({\n id,\n kind: \"todo-move\" as const,\n position: acc.position,\n });\n};\n\n// -- todo remove ------------------------------------------------------------\n\ninterface TodoRemoveAcc {\n yes: boolean;\n}\n\nconst TODO_REMOVE_FLAGS: Readonly<Record<string, FlagHandler<TodoRemoveAcc>>> =\n {\n \"--yes\": boolFlag(\"yes\"),\n };\n\nconst parseTodoRemove = (state: ParseState): ParseResult => {\n const id = state.tokens[state.index];\n if (!id) {\n return Result.fail(usageError(\"todo remove requires <id>.\"));\n }\n state.index += 1;\n\n const acc: TodoRemoveAcc = { yes: false };\n const error = runFlagLoop(state, acc, TODO_REMOVE_FLAGS, \"todo remove\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ id, kind: \"todo-remove\" as const, ...acc });\n};\n\n// -- todo clear -------------------------------------------------------------\n\ninterface TodoClearAcc {\n all: boolean;\n doneOnly: boolean;\n reviewId: string | undefined;\n yes: boolean;\n}\n\nconst TODO_CLEAR_FLAGS: Readonly<Record<string, FlagHandler<TodoClearAcc>>> = {\n \"--all\": boolFlag(\"all\"),\n \"--done-only\": boolFlag(\"doneOnly\"),\n \"--review\": stringFlag(\"reviewId\"),\n \"--yes\": boolFlag(\"yes\"),\n};\n\nconst parseTodoClear = (state: ParseState): ParseResult => {\n const acc: TodoClearAcc = {\n all: false,\n doneOnly: true,\n reviewId: undefined,\n yes: false,\n };\n const error = runFlagLoop(state, acc, TODO_CLEAR_FLAGS, \"todo clear\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"todo-clear\" as const, ...acc });\n};\n\n// -- review status ----------------------------------------------------------\n\ninterface ReviewStatusAcc {\n reviewId: string | undefined;\n source: ReviewSourceType | undefined;\n}\n\nconst REVIEW_STATUS_FLAGS: Readonly<\n Record<string, FlagHandler<ReviewStatusAcc>>\n> = {\n \"--review\": stringFlag(\"reviewId\"),\n \"--source\": enumFlag(\"source\", REVIEW_SOURCES, \"review source\"),\n};\n\nconst parseReviewStatus = (state: ParseState): ParseResult => {\n const acc: ReviewStatusAcc = { reviewId: undefined, source: undefined };\n const error = runFlagLoop(state, acc, REVIEW_STATUS_FLAGS, \"review status\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"review-status\" as const, ...acc });\n};\n\n// -- review resolve ---------------------------------------------------------\n\ninterface ReviewResolveAcc {\n allComments: boolean;\n yes: boolean;\n}\n\nconst REVIEW_RESOLVE_FLAGS: Readonly<\n Record<string, FlagHandler<ReviewResolveAcc>>\n> = {\n \"--all-comments\": boolFlag(\"allComments\"),\n \"--yes\": boolFlag(\"yes\"),\n};\n\nconst parseReviewResolve = (state: ParseState): ParseResult => {\n const id = state.tokens[state.index];\n if (!id) {\n return Result.fail(usageError(\"review resolve requires <id|last>.\"));\n }\n state.index += 1;\n\n const acc: ReviewResolveAcc = { allComments: true, yes: false };\n const error = runFlagLoop(state, acc, REVIEW_RESOLVE_FLAGS, \"review resolve\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ id, kind: \"review-resolve\" as const, ...acc });\n};\n\n// -- todo add ---------------------------------------------------------------\n\ninterface TodoAddAcc {\n position: number | undefined;\n reviewId: string | undefined;\n text: string;\n}\n\nconst TODO_ADD_FLAGS: Readonly<Record<string, FlagHandler<TodoAddAcc>>> = {\n \"--position\": positiveIntFlag(\"position\"),\n \"--review\": stringFlag(\"reviewId\"),\n \"--text\": stringFlag(\"text\"),\n};\n\nconst parseTodoAdd = (state: ParseState): ParseResult => {\n const acc: TodoAddAcc = {\n position: undefined,\n reviewId: undefined,\n text: \"\",\n };\n const error = runFlagLoop(state, acc, TODO_ADD_FLAGS, \"todo add\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n if (!acc.text.trim()) {\n return Result.fail(usageError(\"todo add requires --text.\"));\n }\n return Result.succeed({ kind: \"todo-add\" as const, ...acc });\n};\n\n// -- serve ------------------------------------------------------------------\n\ninterface ServeAcc {\n auth: boolean;\n cert: string | undefined;\n host: string;\n https: boolean;\n key: string | undefined;\n noOpen: boolean;\n password: string | undefined;\n port: number;\n username: string | undefined;\n}\n\nconst SERVE_FLAGS: Readonly<Record<string, FlagHandler<ServeAcc>>> = {\n \"--auth\": boolFlag(\"auth\"),\n \"--cert\": stringFlag(\"cert\"),\n \"--host\": stringFlag(\"host\"),\n \"--https\": boolFlag(\"https\"),\n \"--key\": stringFlag(\"key\"),\n \"--no-open\": boolFlag(\"noOpen\"),\n \"--password\": stringFlag(\"password\"),\n \"--port\": positiveIntFlag(\"port\", { min: 0 }),\n \"--username\": stringFlag(\"username\"),\n};\n\nconst parseServe = (state: ParseState): ParseResult => {\n const acc: ServeAcc = {\n auth: false,\n cert: undefined,\n host: \"127.0.0.1\",\n https: false,\n key: undefined,\n noOpen: false,\n password: undefined,\n port: 3000,\n username: undefined,\n };\n const error = runFlagLoop(state, acc, SERVE_FLAGS, \"serve\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"serve\" as const, ...acc });\n};\n\n// -- mcp --------------------------------------------------------------------\n\nconst MCP_LOG_LEVELS = new Set<string>([\"debug\", \"error\", \"info\", \"silent\"]);\n\ninterface McpAcc {\n logLevel: \"debug\" | \"error\" | \"info\" | \"silent\";\n readonly: boolean;\n}\n\nconst MCP_FLAGS: Readonly<Record<string, FlagHandler<McpAcc>>> = {\n \"--log-level\": enumFlag(\"logLevel\", MCP_LOG_LEVELS, \"log level\"),\n \"--readonly\": boolFlag(\"readonly\"),\n};\n\nconst parseMcp = (state: ParseState): ParseResult => {\n const acc: McpAcc = { logLevel: \"error\", readonly: false };\n const error = runFlagLoop(state, acc, MCP_FLAGS, \"mcp\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"mcp\" as const, ...acc });\n};\n\n// -- events -----------------------------------------------------------------\n\nconst EVENT_TYPES = new Set<string>([\"comments\", \"files\", \"reviews\", \"todos\"]);\n\ninterface EventsAcc {\n since: number | undefined;\n type: \"comments\" | \"files\" | \"reviews\" | \"todos\" | undefined;\n}\n\nconst EVENTS_FLAGS: Readonly<Record<string, FlagHandler<EventsAcc>>> = {\n \"--since\": positiveIntFlag(\"since\"),\n \"--type\": enumFlag(\"type\", EVENT_TYPES, \"event type\"),\n};\n\nconst parseEvents = (state: ParseState): ParseResult => {\n const acc: EventsAcc = { since: undefined, type: undefined };\n const error = runFlagLoop(state, acc, EVENTS_FLAGS, \"events\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"events\" as const, ...acc });\n};\n\n// -- data reset -------------------------------------------------------------\n\ninterface DataResetAcc {\n keepExports: boolean;\n yes: boolean;\n}\n\nconst DATA_RESET_FLAGS: Readonly<Record<string, FlagHandler<DataResetAcc>>> = {\n \"--keep-exports\": boolFlag(\"keepExports\"),\n \"--yes\": boolFlag(\"yes\"),\n};\n\nconst parseDataReset = (state: ParseState): ParseResult => {\n const acc: DataResetAcc = { keepExports: false, yes: false };\n const error = runFlagLoop(state, acc, DATA_RESET_FLAGS, \"data reset\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"data-reset\" as const, ...acc });\n};\n\n// ---------------------------------------------------------------------------\n// Command family dispatch (lookup tables)\n// ---------------------------------------------------------------------------\n\nconst ensureNoExtraArgs = (\n state: ParseState,\n label: string\n): Option.Option<CliFailure> => {\n if (state.index < state.tokens.length) {\n return Option.some(\n usageError(\n `Unexpected argument for ${label}: ${state.tokens[state.index]}.`\n )\n );\n }\n return Option.none();\n};\n\n/** Review verb parsers keyed by verb name. */\nconst REVIEW_VERB_PARSERS: Readonly<\n Record<string, (state: ParseState) => ParseResult>\n> = {\n create: parseReviewCreate,\n export: parseReviewExport,\n list: parseReviewList,\n resolve: parseReviewResolve,\n show: parseReviewShow,\n status: parseReviewStatus,\n};\n\n/** Todo verb parsers keyed by verb name. */\nconst TODO_VERB_PARSERS: Readonly<\n Record<string, (state: ParseState) => ParseResult>\n> = {\n add: parseTodoAdd,\n clear: parseTodoClear,\n done: parseTodoDone,\n list: parseTodoList,\n move: parseTodoMove,\n remove: parseTodoRemove,\n undone: parseTodoUndone,\n};\n\n// -- review pr (URL shortcut) -----------------------------------------------\n\ninterface ReviewPrAcc {\n forceRefresh: boolean;\n noOpen: boolean;\n port: number;\n}\n\nconst REVIEW_PR_FLAGS: Readonly<Record<string, FlagHandler<ReviewPrAcc>>> = {\n \"--force-refresh\": boolFlag(\"forceRefresh\"),\n \"--no-open\": boolFlag(\"noOpen\"),\n \"--port\": positiveIntFlag(\"port\", { min: 0 }),\n};\n\nconst parseReviewPr = (state: ParseState, prUrl: string): ParseResult => {\n const acc: ReviewPrAcc = { forceRefresh: false, noOpen: false, port: 3000 };\n const error = runFlagLoop(state, acc, REVIEW_PR_FLAGS, \"review <pr-url>\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({\n kind: \"review-pr\" as const,\n prUrl,\n ...acc,\n });\n};\n\n/** Subcommand family parsers keyed by family name. */\n/** Data verb parsers keyed by verb name. */\nconst DATA_VERB_PARSERS: Readonly<\n Record<string, (state: ParseState) => ParseResult>\n> = {\n migrate: (state) => {\n const error = ensureNoExtraArgs(state, \"data migrate\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"data-migrate\" as const });\n },\n reset: parseDataReset,\n};\n\n/** Subcommand family parsers keyed by family name. */\nconst FAMILY_PARSERS: Readonly<\n Record<string, (state: ParseState) => ParseResult>\n> = {\n data: (state) => {\n const verb = state.tokens[state.index];\n if (!verb) {\n return Result.succeed({\n kind: \"help\" as const,\n topic: [\"data\"] as const,\n });\n }\n state.index += 1;\n const parser = DATA_VERB_PARSERS[verb];\n if (!parser) {\n return Result.fail(usageError(`Unknown data command: ${verb}.`));\n }\n return parser(state);\n },\n doctor: (state) => {\n const error = ensureNoExtraArgs(state, \"doctor\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"doctor\" as const });\n },\n events: parseEvents,\n export: parseReviewExport,\n mcp: parseMcp,\n review: (state) => {\n const verb = state.tokens[state.index];\n if (!verb) {\n return Result.succeed({\n kind: \"help\" as const,\n topic: [\"review\"] as const,\n });\n }\n // URL shortcut: `ringi review https://github.com/owner/repo/pull/42`\n if (looksLikePrUrl(verb)) {\n state.index += 1;\n return parseReviewPr(state, verb);\n }\n state.index += 1;\n const parser = REVIEW_VERB_PARSERS[verb];\n if (!parser) {\n return Result.fail(usageError(`Unknown review command: ${verb}.`));\n }\n return parser(state);\n },\n serve: parseServe,\n source: (state) => {\n const verb = state.tokens[state.index];\n if (!verb) {\n return Result.succeed({\n kind: \"help\" as const,\n topic: [\"source\"] as const,\n });\n }\n state.index += 1;\n if (verb === \"list\") {\n const error = ensureNoExtraArgs(state, \"source list\");\n if (Option.isSome(error)) {\n return Result.fail(error.value);\n }\n return Result.succeed({ kind: \"source-list\" as const });\n }\n if (verb === \"diff\") {\n return parseSourceDiff(state);\n }\n return Result.fail(usageError(`Unknown source command: ${verb}.`));\n },\n todo: (state) => {\n const verb = state.tokens[state.index];\n if (!verb) {\n return Result.succeed({\n kind: \"help\" as const,\n topic: [\"todo\"] as const,\n });\n }\n state.index += 1;\n const parser = TODO_VERB_PARSERS[verb];\n if (!parser) {\n return Result.fail(usageError(`Unknown todo command: ${verb}.`));\n }\n return parser(state);\n },\n};\n\n// ---------------------------------------------------------------------------\n// Top-level entry\n// ---------------------------------------------------------------------------\n\n/**\n * Strips any leading globals with {@link maybeParseGlobalFlag} before dispatching\n * into a command family so `--help` and `--version` behave consistently.\n */\nconst parseWithState = (state: ParseState): ParseResult => {\n while (state.index < state.tokens.length && maybeParseGlobalFlag(state)) {\n // Keep consuming top-level flags before the command token.\n }\n\n if (state.options.version) {\n return Result.succeed({ kind: \"version\" as const });\n }\n\n if (state.index >= state.tokens.length) {\n return Result.succeed({ kind: \"help\" as const, topic: [] });\n }\n\n const first = state.tokens[state.index];\n if (!first) {\n return Result.succeed({ kind: \"help\" as const, topic: [] });\n }\n if (first === \"help\") {\n const topic = state.tokens.slice(state.index + 1);\n state.index = state.tokens.length;\n return Result.succeed({ kind: \"help\" as const, topic });\n }\n\n if (state.options.help) {\n return Result.succeed({\n kind: \"help\" as const,\n topic: state.tokens.slice(state.index),\n });\n }\n\n state.index += 1;\n\n const familyParser = FAMILY_PARSERS[first];\n if (!familyParser) {\n return Result.fail(usageError(`Unknown command: ${first}.`));\n }\n return familyParser(state);\n};\n\nexport const parseCliArgs = (\n argv: readonly string[]\n): Result.Result<\n { readonly command: ParsedCommand; readonly options: GlobalOptions },\n CliFailure\n> => {\n const options = createDefaultOptions();\n const state: ParseState = { index: 0, options, tokens: argv };\n const result = parseWithState(state);\n if (Result.isFailure(result)) {\n return Result.fail(result.failure);\n }\n return Result.succeed({ command: result.success, options });\n};\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nimport { CoreLive } from \"@ringi/core/runtime\";\nimport { GitService } from \"@ringi/core/services/git.service\";\nimport * as ConfigProvider from \"effect/ConfigProvider\";\nimport * as Layer from \"effect/Layer\";\nimport * as ManagedRuntime from \"effect/ManagedRuntime\";\n\nimport { CliConfigLive } from \"@/cli/config\";\nimport type { CliConfigShape } from \"@/cli/config\";\nimport { CliFailure, ExitCode } from \"@/cli/contracts\";\nimport type { ParsedCommand } from \"@/cli/contracts\";\n\n/**\n * Bundles the resolved config with the matching runtime so the CLI can share\n * one setup and disposal path.\n */\nexport interface CliRuntimeResources {\n readonly config: CliConfigShape;\n readonly runtime: ManagedRuntime.ManagedRuntime<any, any>;\n}\n\nconst resolveRepositoryRoot = (repoOverride?: string): CliFailure | string => {\n const cwd = repoOverride ? resolve(repoOverride) : process.cwd();\n\n try {\n return execFileSync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd,\n encoding: \"utf8\",\n }).trim();\n } catch {\n return new CliFailure({\n exitCode: ExitCode.StateUnavailable,\n message: repoOverride\n ? `Path ${cwd} is not a Git repository. Use --repo <path> with a valid repository root.`\n : `Could not resolve a Git repository from ${cwd}. Use --repo <path> with a valid repository root.`,\n });\n }\n};\n\nconst resolveDbPath = (repoRoot: string, dbPathOverride?: string): string =>\n dbPathOverride\n ? resolve(dbPathOverride)\n : resolve(repoRoot, \".ringi/reviews.db\");\n\nconst commandNeedsRepository = (command: ParsedCommand): boolean =>\n command.kind !== \"help\" &&\n command.kind !== \"version\" &&\n command.kind !== \"mcp\" &&\n command.kind !== \"serve\";\n\n/**\n * Commands that need the database to already exist. `review-pr` is NOT here\n * because it auto-initializes `.ringi/` (like `serve` does).\n */\nexport const commandNeedsDatabase = (command: ParsedCommand): boolean =>\n command.kind === \"review-list\" ||\n command.kind === \"review-show\" ||\n command.kind === \"review-export\" ||\n command.kind === \"review-status\" ||\n command.kind === \"todo-list\" ||\n command.kind === \"doctor\";\n\nexport const commandUsesCoreRuntime = (command: ParsedCommand): boolean =>\n command.kind === \"review-list\" ||\n command.kind === \"review-show\" ||\n command.kind === \"review-export\" ||\n command.kind === \"review-pr\" ||\n command.kind === \"review-status\" ||\n command.kind === \"todo-list\" ||\n command.kind === \"review-create\" ||\n command.kind === \"todo-add\" ||\n command.kind === \"doctor\";\n\nexport const resolveCliConfig = (args: {\n color: boolean;\n dbPath?: string;\n quiet: boolean;\n repo?: string;\n verbose: boolean;\n}): CliConfigShape | CliFailure => {\n const repoRootResult = resolveRepositoryRoot(args.repo);\n if (repoRootResult instanceof CliFailure) {\n return repoRootResult;\n }\n\n return {\n color: args.color,\n cwd: process.cwd(),\n dbPath: resolveDbPath(repoRootResult, args.dbPath),\n outputMode: \"human\",\n quiet: args.quiet,\n repoRoot: repoRootResult,\n verbose: args.verbose,\n };\n};\n\nexport const ensureLocalStateAvailable = (\n config: CliConfigShape\n): CliFailure | undefined => {\n if (!existsSync(config.dbPath)) {\n return new CliFailure({\n exitCode: ExitCode.StateUnavailable,\n message: `Local state is missing at ${config.dbPath}. Run 'ringi data migrate' or start 'ringi serve' once to initialize local state.`,\n });\n }\n return undefined;\n};\n\nconst makeConfigLayer = (config: CliConfigShape) =>\n ConfigProvider.layer(\n ConfigProvider.fromUnknown({\n DB_PATH: config.dbPath,\n REPOSITORY_PATH: config.repoRoot,\n })\n );\n\nexport const createCoreCliRuntime = (config: CliConfigShape) =>\n ManagedRuntime.make(\n Layer.mergeAll(CoreLive, CliConfigLive(config)).pipe(\n Layer.provideMerge(makeConfigLayer(config))\n )\n );\n\nexport const createGitCliRuntime = (config: CliConfigShape) =>\n ManagedRuntime.make(\n Layer.mergeAll(GitService.Default, CliConfigLive(config)).pipe(\n Layer.provideMerge(makeConfigLayer(config))\n )\n );\n\nexport const createCliRuntimeResources = (\n command: ParsedCommand,\n args: {\n color: boolean;\n dbPath?: string;\n quiet: boolean;\n repo?: string;\n verbose: boolean;\n }\n): CliFailure | CliRuntimeResources | null => {\n if (!commandNeedsRepository(command)) {\n return null;\n }\n\n const configResult = resolveCliConfig(args);\n if (configResult instanceof CliFailure) {\n return configResult;\n }\n\n if (commandNeedsDatabase(command)) {\n const stateError = ensureLocalStateAvailable(configResult);\n if (stateError) {\n return stateError;\n }\n }\n\n return {\n config: configResult,\n runtime: commandUsesCoreRuntime(command)\n ? createCoreCliRuntime(configResult)\n : createGitCliRuntime(configResult),\n };\n};\n","#!/usr/bin/env node\n\nimport { exec, fork } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nimport { ReviewNotFound } from \"@ringi/core/schemas/review\";\nimport { TodoNotFound } from \"@ringi/core/schemas/todo\";\nimport type * as Effect from \"effect/Effect\";\nimport * as Result from \"effect/Result\";\n\nimport { commandLabel, runCommand } from \"@/cli/commands\";\nimport { CliFailure, ExitCode, failure, success } from \"@/cli/contracts\";\nimport type {\n CliErrorDetail,\n CliErrorEnvelope,\n CommandOutput,\n ErrorCategory,\n ExitCode as ExitCodeType,\n NextAction,\n ParsedCommand,\n} from \"@/cli/contracts\";\nimport { parseCliArgs } from \"@/cli/parser\";\nimport { createCliRuntimeResources } from \"@/cli/runtime\";\n\nconst CLI_VERSION =\n process.env.RINGI_VERSION ?? process.env.npm_package_version ?? \"0.0.0-dev\";\n\n// ---------------------------------------------------------------------------\n// Self-documenting command tree (returned for `ringi --json` with no command)\n// ---------------------------------------------------------------------------\n\nconst COMMAND_TREE = {\n commands: [\n {\n description: \"List review sessions\",\n name: \"review list\",\n usage:\n \"ringi review list [--status <status>] [--source <type>] [--limit <n>] [--page <n>]\",\n },\n {\n description: \"Show review details\",\n name: \"review show\",\n usage: \"ringi review show <id|last> [--comments] [--todos]\",\n },\n {\n description: \"Create a review session\",\n name: \"review create\",\n usage:\n \"ringi review create [--source <staged|branch|commits>] [--branch <name>] [--commits <range>]\",\n },\n {\n description: \"Export review as markdown\",\n name: \"review export\",\n usage: \"ringi review export <id|last> [--output <path>] [--stdout]\",\n },\n {\n description: \"Resolve a review session\",\n name: \"review resolve\",\n usage: \"ringi review resolve <id|last> [--all-comments] [--yes]\",\n },\n {\n description: \"Show repository and review status\",\n name: \"review status\",\n usage: \"ringi review status [--review <id|last>] [--source <type>]\",\n },\n {\n description: \"List repository sources\",\n name: \"source list\",\n usage: \"ringi source list\",\n },\n {\n description: \"Show diff for a source\",\n name: \"source diff\",\n usage:\n \"ringi source diff <staged|branch|commits> [--branch <name>] [--commits <range>] [--stat]\",\n },\n {\n description: \"List todo items\",\n name: \"todo list\",\n usage:\n \"ringi todo list [--review <id>] [--status <pending|done|all>] [--limit <n>] [--offset <n>]\",\n },\n {\n description: \"Add a todo item\",\n name: \"todo add\",\n usage: \"ringi todo add --text <text> [--review <id>] [--position <n>]\",\n },\n {\n description: \"Mark a todo as done\",\n name: \"todo done\",\n usage: \"ringi todo done <id>\",\n },\n {\n description: \"Reopen a completed todo\",\n name: \"todo undone\",\n usage: \"ringi todo undone <id>\",\n },\n {\n description: \"Move a todo to a position\",\n name: \"todo move\",\n usage: \"ringi todo move <id> --position <n>\",\n },\n {\n description: \"Remove a todo\",\n name: \"todo remove\",\n usage: \"ringi todo remove <id> [--yes]\",\n },\n {\n description: \"Clear completed todos\",\n name: \"todo clear\",\n usage: \"ringi todo clear [--review <id>] [--done-only] [--all] [--yes]\",\n },\n {\n description: \"Start the local Ringi server\",\n name: \"serve\",\n usage:\n \"ringi serve [--host <host>] [--port <port>] [--https] [--auth] [--no-open]\",\n },\n {\n description: \"Start the MCP stdio server\",\n name: \"mcp\",\n usage: \"ringi mcp [--readonly] [--log-level <level>]\",\n },\n {\n description: \"Run local diagnostics\",\n name: \"doctor\",\n usage: \"ringi doctor\",\n },\n {\n description: \"Tail server events\",\n name: \"events\",\n usage: \"ringi events [--type <reviews|comments|todos|files>]\",\n },\n {\n description: \"Run database migrations\",\n name: \"data migrate\",\n usage: \"ringi data migrate\",\n },\n {\n description: \"Reset local data\",\n name: \"data reset\",\n usage: \"ringi data reset [--yes] [--keep-exports]\",\n },\n ],\n description: \"ringi — local-first code review CLI\",\n version: CLI_VERSION,\n};\n\nconst ROOT_NEXT_ACTIONS: NextAction[] = [\n {\n command: \"ringi review list [--status <status>] [--source <type>]\",\n description: \"List review sessions\",\n params: {\n source: { enum: [\"staged\", \"branch\", \"commits\"] },\n status: { enum: [\"in_progress\", \"approved\", \"changes_requested\"] },\n },\n },\n {\n command: \"ringi source list\",\n description: \"List repository sources\",\n },\n {\n command: \"ringi review create [--source <source>]\",\n description: \"Create a new review session\",\n params: {\n source: { default: \"staged\", enum: [\"staged\", \"branch\", \"commits\"] },\n },\n },\n {\n command: \"ringi todo list [--status <status>]\",\n description: \"List todos\",\n params: {\n status: { default: \"pending\", enum: [\"pending\", \"done\", \"all\"] },\n },\n },\n {\n command: \"ringi review status\",\n description: \"Show repository and review status\",\n },\n];\n\n// ---------------------------------------------------------------------------\n// Help text (lookup-table, not switch)\n// ---------------------------------------------------------------------------\n\nconst ROOT_HELP = `ringi — local-first review CLI\n\nUsage:\n ringi [global options] <command>\n\nGlobal options:\n --json Emit structured JSON envelope to stdout\n --repo <path> Use a specific Git repository root\n --db-path <path> Override the SQLite database path\n --quiet Suppress human-readable success output\n --verbose Include stack traces on failures\n --no-color Disable ANSI color output\n --help Show help\n --version Show version\n\nCommands:\n review list [--status <status>] [--source <type>] [--limit <n>] [--page <n>]\n review show <id|last> [--comments] [--todos]\n review create [--source <staged|branch|commits>] [--branch <name>] [--commits <range>]\n review export <id|last> [--output <path>] [--stdout]\n review resolve <id|last> [--all-comments] [--yes]\n review status [--review <id|last>] [--source <type>]\n source list\n source diff <staged|branch|commits> [--branch <name>] [--commits <range>] [--stat]\n todo list [--review <id>] [--status <pending|done|all>] [--limit <n>] [--offset <n>]\n todo add --text <text> [--review <id>]\n todo done <id>\n todo undone <id>\n todo move <id> --position <n>\n todo remove <id> [--yes]\n todo clear [--review <id>] [--done-only] [--all] [--yes]\n export <id|last> [--output <path>] [--stdout]\n`;\n\nconst HELP_TOPICS: Readonly<Record<string, string>> = {\n data: `ringi data\n\nUsage:\n ringi data migrate\n ringi data reset [--yes] [--keep-exports]\n`,\n review: `ringi review\n\nUsage:\n ringi review list [--status <status>] [--source <type>] [--limit <n>] [--page <n>]\n ringi review show <id|last> [--comments] [--todos]\n ringi review create [--source <staged|branch|commits>] [--branch <name>] [--commits <range>]\n ringi review export <id|last> [--output <path>] [--stdout]\n ringi review resolve <id|last> [--all-comments] [--yes]\n ringi review status [--review <id|last>] [--source <type>]\n`,\n source: `ringi source\n\nUsage:\n ringi source list\n ringi source diff <staged|branch|commits> [--branch <name>] [--commits <range>] [--stat]\n`,\n todo: `ringi todo\n\nUsage:\n ringi todo list [--review <id>] [--status <pending|done|all>] [--limit <n>] [--offset <n>]\n ringi todo add --text <text> [--review <id>] [--position <n>]\n ringi todo done <id>\n ringi todo undone <id>\n ringi todo move <id> --position <n>\n ringi todo remove <id> [--yes]\n ringi todo clear [--review <id>] [--done-only] [--all] [--yes]\n`,\n};\n\nconst renderHelp = (command: ParsedCommand): string => {\n if (command.kind !== \"help\") {\n return ROOT_HELP;\n }\n const [topic] = command.topic;\n return (topic && HELP_TOPICS[topic]) ?? ROOT_HELP;\n};\n\n// ---------------------------------------------------------------------------\n// Output helpers\n// ---------------------------------------------------------------------------\n\nconst writeJson = (payload: unknown): void => {\n process.stdout.write(`${JSON.stringify(payload, null, 2)}\\n`);\n};\n\nconst writeHuman = (text: string | undefined): void => {\n if (text && text.length > 0) {\n process.stdout.write(`${text}\\n`);\n }\n};\n\n// ---------------------------------------------------------------------------\n// Error normalization (RFC 9457-inspired)\n// ---------------------------------------------------------------------------\n\ninterface NormalizedFailure {\n readonly category: ErrorCategory;\n readonly code: string;\n readonly exitCode: ExitCodeType;\n readonly message: string;\n readonly retryable: boolean;\n readonly verbose?: string;\n}\n\n/** Maps exit codes to error categories and retryable status. */\nconst EXIT_CODE_META: Readonly<\n Record<number, { category: ErrorCategory; code: string; retryable: boolean }>\n> = {\n [ExitCode.AuthFailure]: {\n category: \"auth\",\n code: \"AUTH_FAILURE\",\n retryable: false,\n },\n [ExitCode.ResourceNotFound]: {\n category: \"not_found\",\n code: \"RESOURCE_NOT_FOUND\",\n retryable: false,\n },\n [ExitCode.RuntimeFailure]: {\n category: \"server\",\n code: \"RUNTIME_FAILURE\",\n retryable: true,\n },\n [ExitCode.StateUnavailable]: {\n category: \"config\",\n code: \"STATE_UNAVAILABLE\",\n retryable: false,\n },\n [ExitCode.UsageError]: {\n category: \"validation\",\n code: \"USAGE_ERROR\",\n retryable: false,\n },\n};\n\nconst mapFailure = (error: unknown): NormalizedFailure => {\n if (error instanceof CliFailure) {\n const meta = EXIT_CODE_META[error.exitCode] ?? {\n category: \"server\" as const,\n code: \"UNKNOWN\",\n retryable: false,\n };\n return {\n category: meta.category,\n code: meta.code,\n exitCode: error.exitCode as ExitCodeType,\n message: error.message,\n retryable: meta.retryable,\n verbose: error.details,\n };\n }\n\n if (error instanceof ReviewNotFound || error instanceof TodoNotFound) {\n return {\n category: \"not_found\",\n code: \"RESOURCE_NOT_FOUND\",\n exitCode: ExitCode.ResourceNotFound,\n message: error.message,\n retryable: false,\n verbose: error.stack,\n };\n }\n\n if (error instanceof Error) {\n return {\n category: \"server\",\n code: \"RUNTIME_FAILURE\",\n exitCode: ExitCode.RuntimeFailure,\n message: error.message,\n retryable: true,\n verbose: error.stack,\n };\n }\n\n return {\n category: \"server\",\n code: \"UNKNOWN_FAILURE\",\n exitCode: ExitCode.RuntimeFailure,\n message: \"Unknown CLI failure.\",\n retryable: false,\n };\n};\n\n/** Actionable fix guidance based on error category. */\nconst FIX_GUIDANCE: Readonly<Record<ErrorCategory, string>> = {\n auth: \"Check authentication credentials or run 'ringi serve --auth' with valid credentials.\",\n config:\n \"Run 'ringi serve' once to initialize local state, or check --repo and --db-path flags.\",\n conflict: \"Resolve the conflict and retry the operation.\",\n connection: \"Ensure the Ringi server is running: ringi serve\",\n not_found:\n \"Verify the resource ID. Use 'ringi review list' or 'ringi todo list' to find valid IDs.\",\n server: \"Retry the command. If the error persists, check 'ringi serve' logs.\",\n validation:\n \"Check command usage with 'ringi --help'. Verify flag names and values.\",\n};\n\n/** Build recovery next_actions based on error category. */\nconst errorNextActions = (\n commandStr: string,\n normalized: NormalizedFailure\n): NextAction[] => {\n const actions: NextAction[] = [];\n\n if (normalized.retryable) {\n actions.push({\n command: commandStr,\n description: \"Retry the failed command\",\n });\n }\n\n if (\n normalized.category === \"config\" ||\n normalized.category === \"connection\"\n ) {\n actions.push({\n command: \"ringi serve\",\n description: \"Start the local Ringi server\",\n });\n }\n\n if (normalized.category === \"not_found\") {\n actions.push(\n {\n command: \"ringi review list\",\n description: \"List available reviews\",\n },\n {\n command: \"ringi todo list\",\n description: \"List available todos\",\n }\n );\n }\n\n if (normalized.category === \"validation\") {\n actions.push({\n command: `${commandStr.split(\" \").slice(0, 3).join(\" \")} --help`,\n description: \"Show command usage\",\n });\n }\n\n return actions;\n};\n\n/** Build a full error envelope from a normalized failure. */\nconst buildErrorEnvelope = (\n commandStr: string,\n normalized: NormalizedFailure\n): CliErrorEnvelope => {\n const errorDetail: CliErrorDetail = {\n category: normalized.category,\n code: normalized.code,\n message: normalized.message,\n retryable: normalized.retryable,\n type: `ringi://errors/${normalized.code}`,\n };\n\n return failure(\n commandStr,\n errorDetail,\n normalized.verbose ?? FIX_GUIDANCE[normalized.category],\n errorNextActions(commandStr, normalized)\n );\n};\n\n// ---------------------------------------------------------------------------\n// Signal handling\n// ---------------------------------------------------------------------------\n\nconst installSignalHandlers = (dispose: () => Promise<void>): (() => void) => {\n const shutdown = async () => {\n await dispose();\n process.exit(ExitCode.RuntimeFailure);\n };\n\n process.once(\"SIGINT\", shutdown);\n process.once(\"SIGTERM\", shutdown);\n\n return () => {\n process.off(\"SIGINT\", shutdown);\n process.off(\"SIGTERM\", shutdown);\n };\n};\n\n// ---------------------------------------------------------------------------\n// Serve command (long-running process, bypasses Effect runtime)\n// ---------------------------------------------------------------------------\n\n/**\n * Resolves the built Nitro server entry point.\n *\n * Lookup order (first match wins):\n * 1. **Packaged location** — `<pkg-root>/server/server/index.mjs`\n * The published npm package includes `server/` at the package root, which\n * contains `server/index.mjs` (the Nitro entry) and `public/` (static\n * assets). From the bundled CLI at `dist/cli.mjs`, the package root is\n * `import.meta.dirname/..`.\n * 2. **Monorepo development** — `apps/web/.output/server/index.mjs`\n * During local development the web build output lives inside the web\n * workspace. We resolve it relative to the CLI package root.\n * 3. **CWD fallback** — `.output/server/index.mjs` relative to the current\n * working directory, for running the server in a standalone checkout.\n */\nconst resolveServerEntry = (): string | undefined => {\n const candidates: string[] = [];\n\n if (import.meta.dirname) {\n const pkgRoot = resolve(import.meta.dirname, \"..\");\n\n // 1. Published package: <pkg>/server/server/index.mjs\n candidates.push(resolve(pkgRoot, \"server\", \"server\", \"index.mjs\"));\n\n // 2. Monorepo dev: <cli-root>/../../apps/web/.output/server/index.mjs\n candidates.push(\n resolve(pkgRoot, \"..\", \"web\", \".output\", \"server\", \"index.mjs\")\n );\n }\n\n // 3. CWD fallback (legacy / standalone)\n candidates.push(resolve(process.cwd(), \".output\", \"server\", \"index.mjs\"));\n\n return candidates.find((candidate) => existsSync(candidate));\n};\n\nconst runServe = (command: Extract<ParsedCommand, { kind: \"serve\" }>): void => {\n const serverEntry = resolveServerEntry();\n\n if (!serverEntry) {\n const isInstalledGlobally =\n import.meta.dirname && !import.meta.dirname.includes(\"apps/cli/\");\n const hint = isInstalledGlobally\n ? \"The installed package is missing its server assets. Try reinstalling: npm install -g @sanurb/ringi\"\n : \"Run 'pnpm build' at the monorepo root, then 'pnpm --filter @sanurb/ringi build:server' to copy the server assets.\";\n process.stderr.write(`No built server found.\\n${hint}\\n`);\n process.exit(ExitCode.RuntimeFailure);\n }\n\n const env: Record<string, string> = {\n ...process.env,\n NITRO_HOST: command.host,\n NITRO_PORT: String(command.port),\n };\n\n if (command.https && command.cert && command.key) {\n env.NITRO_SSL_CERT = command.cert;\n env.NITRO_SSL_KEY = command.key;\n }\n\n const protocol = command.https ? \"https\" : \"http\";\n const url = `${protocol}://${command.host === \"0.0.0.0\" ? \"localhost\" : command.host}:${command.port}`;\n process.stderr.write(`ringi server starting on ${url}\\n`);\n\n const child = fork(serverEntry, [], {\n env,\n // Clear execArgv so tsx/ts-node loaders from the parent don't interfere\n // with the built Nitro server (plain ESM).\n execArgv: [],\n stdio: \"inherit\",\n });\n\n if (!command.noOpen) {\n // Delay open slightly so the server has time to bind the port.\n setTimeout(() => {\n let openCmd = \"xdg-open\";\n if (process.platform === \"darwin\") {\n openCmd = \"open\";\n } else if (process.platform === \"win32\") {\n openCmd = \"start\";\n }\n exec(`${openCmd} ${url}`, () => {\n // Browser open is best-effort; swallow errors.\n });\n }, 1500);\n }\n\n const shutdown = () => {\n child.kill(\"SIGTERM\");\n };\n\n process.once(\"SIGINT\", shutdown);\n process.once(\"SIGTERM\", shutdown);\n\n child.on(\"exit\", (code) => {\n process.off(\"SIGINT\", shutdown);\n process.off(\"SIGTERM\", shutdown);\n process.exit(code ?? ExitCode.Success);\n });\n};\n\n// ---------------------------------------------------------------------------\n// Shared error exit (eliminates 3× duplication)\n// ---------------------------------------------------------------------------\n\ninterface FailExitOptions {\n readonly cmdStr: string;\n readonly error: unknown;\n readonly json: boolean;\n readonly verbose: boolean;\n}\n\n/** Single path for all CLI error exits. */\nconst failAndExit = (opts: FailExitOptions): never => {\n const normalized = mapFailure(opts.error);\n\n if (opts.json) {\n writeJson(buildErrorEnvelope(opts.cmdStr, normalized));\n }\n\n process.stderr.write(`${normalized.message}\\n`);\n if (opts.verbose && normalized.verbose) {\n process.stderr.write(`${normalized.verbose}\\n`);\n }\n\n return process.exit(normalized.exitCode);\n};\n\n// ---------------------------------------------------------------------------\n// Main program\n// ---------------------------------------------------------------------------\n\nconst main = async (): Promise<void> => {\n const argv = process.argv.slice(2);\n const parseResult = parseCliArgs(argv);\n\n if (Result.isFailure(parseResult)) {\n return failAndExit({\n cmdStr: \"ringi\",\n error: parseResult.failure,\n json: argv.includes(\"--json\"),\n verbose: false,\n });\n }\n\n const { command, options } = parseResult.success;\n\n if (command.kind === \"help\") {\n if (options.json) {\n writeJson(success(\"ringi\", COMMAND_TREE, ROOT_NEXT_ACTIONS));\n } else {\n writeHuman(renderHelp(command));\n }\n process.exit(ExitCode.Success);\n }\n\n if (command.kind === \"version\") {\n if (options.json) {\n writeJson(success(\"ringi --version\", { version: CLI_VERSION }));\n } else {\n writeHuman(CLI_VERSION);\n }\n process.exit(ExitCode.Success);\n }\n\n // Serve is a long-running process that bypasses the Effect runtime entirely.\n // It forks the built Nitro server as a child process and proxies signals.\n if (command.kind === \"serve\") {\n runServe(command);\n return;\n }\n\n const runtimeResources = createCliRuntimeResources(command, {\n color: options.color,\n dbPath: options.dbPath,\n quiet: options.quiet,\n repo: options.repo,\n verbose: options.verbose,\n });\n\n if (runtimeResources === null) {\n process.exit(ExitCode.Success);\n }\n\n const cmdStr = commandLabel(command);\n\n if (runtimeResources instanceof CliFailure) {\n return failAndExit({\n cmdStr,\n error: runtimeResources,\n json: options.json,\n verbose: options.verbose,\n });\n }\n\n const removeSignalHandlers = installSignalHandlers(() =>\n runtimeResources.runtime.dispose()\n );\n\n try {\n // The CommandHandler type uses `unknown` for the R (requirements) channel\n // because handlers depend on various service combinations. The managed\n // runtime provides all required services; the cast at this boundary is the\n // one place where we bridge the static Effect types to the dynamic runtime.\n const output = (await runtimeResources.runtime.runPromise(\n runCommand(command) as Effect.Effect<CommandOutput<unknown>>\n )) as CommandOutput<unknown>;\n\n if (options.json) {\n writeJson(success(cmdStr, output.data, output.nextActions ?? []));\n } else if (!options.quiet) {\n writeHuman(output.human);\n }\n\n await runtimeResources.runtime.dispose();\n removeSignalHandlers();\n process.exit(ExitCode.Success);\n } catch (error) {\n await runtimeResources.runtime.dispose();\n removeSignalHandlers();\n failAndExit({\n cmdStr,\n error,\n json: options.json,\n verbose: options.verbose,\n });\n }\n};\n\ntry {\n await main();\n} catch (error) {\n failAndExit({\n cmdStr: \"ringi\",\n error,\n json: process.argv.slice(2).includes(\"--json\"),\n verbose: false,\n });\n}\n"],"mappings":"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Aa;GACb,MAAM;GACN,OACE;GACH;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OACE;GACH;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OACE;GACH;EACD;GACE,aAAa;GACb,MAAM;GACN,OACE;GACH;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OACE;GACH;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACD;GACE,aAAa;GACb,MAAM;GACN,OAAO;GACR;EACF;CACD,aAAa;CACb,SAAS;CACV;AAED,MAAM,oBAAkC;CACtC;EACE,SAAS;EACT,aAAa;EACb,QAAQ;GACN,QAAQ,EAAE,MAAM;IAAC;IAAU;IAAU;IAAU,EAAE;GACjD,QAAQ,EAAE,MAAM;IAAC;IAAe;IAAY;IAAoB,EAAE;GACnE;EACF;CACD;EACE,SAAS;EACT,aAAa;EACd;CACD;EACE,SAAS;EACT,aAAa;EACb,QAAQ,EACN,QAAQ;GAAE,SAAS;GAAU,MAAM;IAAC;IAAU;IAAU;IAAU;GAAE,EACrE;EACF;CACD;EACE,SAAS;EACT,aAAa;EACb,QAAQ,EACN,QAAQ;GAAE,SAAS;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"}
|