codemini-cli 0.5.0 → 0.5.2
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/LICENSE +0 -0
- package/OPERATIONS.md +1 -1
- package/README.md +25 -25
- package/bin/coder.js +0 -0
- package/codemini-web/dist/assets/Geist-Italic_wght_-vKc54d3Z.woff2 +0 -0
- package/codemini-web/dist/assets/Geist-Variable-CrgPqtmy.woff2 +0 -0
- package/codemini-web/dist/assets/GeistMono-Variable-BNLlm6Cd.woff2 +0 -0
- package/codemini-web/dist/assets/abap-9R7RjkQK.js +1 -0
- package/codemini-web/dist/assets/abap-BRbAAyvE.js +0 -0
- package/codemini-web/dist/assets/actionscript-3-CNowah7a.js +1 -0
- package/codemini-web/dist/assets/actionscript-3-Cj-0sM4g.js +0 -0
- package/codemini-web/dist/assets/ada-D5HmrmpD.js +1 -0
- package/codemini-web/dist/assets/ada-DhEA_nP5.js +0 -0
- package/codemini-web/dist/assets/andromeeda-CWmR-N6V.js +0 -0
- package/codemini-web/dist/assets/andromeeda-i_b3g2bn.js +1 -0
- package/codemini-web/dist/assets/{angular-html-Cde9qVP5.js → angular-html-CHsdtmkx.js} +1 -1
- package/codemini-web/dist/assets/angular-html-DlSp9HPG.js +1 -0
- package/codemini-web/dist/assets/{angular-ts-DefScAWP.js → angular-ts-B29Ypg6B.js} +1 -1
- package/codemini-web/dist/assets/angular-ts-JNDGGWj0.js +1 -0
- package/codemini-web/dist/assets/apache-D37U8o0r.js +1 -0
- package/codemini-web/dist/assets/apache-D5R2GKIs.js +0 -0
- package/codemini-web/dist/assets/apex-CszkG4lQ.js +1 -0
- package/codemini-web/dist/assets/apex-Qu8W4hal.js +0 -0
- package/codemini-web/dist/assets/apl-BASZ7uB_.js +1 -0
- package/codemini-web/dist/assets/{apl-w753UHCW.js → apl-Byuv-g-O.js} +1 -1
- package/codemini-web/dist/assets/applescript-Ajt9gmC_.js +1 -0
- package/codemini-web/dist/assets/applescript-CBey3ErE.js +0 -0
- package/codemini-web/dist/assets/ara-CRKnUAN1.js +0 -0
- package/codemini-web/dist/assets/ara-DpGk8XWf.js +1 -0
- package/codemini-web/dist/assets/asciidoc-1KYZEB6-.js +0 -0
- package/codemini-web/dist/assets/asciidoc-BdDORSgx.js +1 -0
- package/codemini-web/dist/assets/asm-DAaViY0U.js +0 -0
- package/codemini-web/dist/assets/asm-DGLRM3OU.js +1 -0
- package/codemini-web/dist/assets/{astro-DBA9Da7s.js → astro-CTzEugGW.js} +1 -1
- package/codemini-web/dist/assets/astro-l-XABzN2.js +1 -0
- package/codemini-web/dist/assets/aurora-x-DdfqxvM_.js +1 -0
- package/codemini-web/dist/assets/aurora-x-LPpmXm4i.js +0 -0
- package/codemini-web/dist/assets/awk-B-J9te9x.js +1 -0
- package/codemini-web/dist/assets/awk-ButuPTaW.js +0 -0
- package/codemini-web/dist/assets/ayu-dark-BdNJk5qF.js +1 -0
- package/codemini-web/dist/assets/ayu-dark-Dv4ngVMP.js +0 -0
- package/codemini-web/dist/assets/ayu-light-CxeOePuA.js +0 -0
- package/codemini-web/dist/assets/ayu-light-DkLNbAkT.js +1 -0
- package/codemini-web/dist/assets/ayu-mirage-BoyGjGHX.js +1 -0
- package/codemini-web/dist/assets/ayu-mirage-i2YLXKmY.js +0 -0
- package/codemini-web/dist/assets/ballerina-CZ8CAKmi.js +1 -0
- package/codemini-web/dist/assets/ballerina-DodmBVwR.js +0 -0
- package/codemini-web/dist/assets/bat-fNtaIqKE.js +1 -0
- package/codemini-web/dist/assets/bat-jA-YqDhG.js +0 -0
- package/codemini-web/dist/assets/beancount-9imagnS2.js +1 -0
- package/codemini-web/dist/assets/beancount-BCkjWTs-.js +0 -0
- package/codemini-web/dist/assets/berry-DjEHm1kC.js +0 -0
- package/codemini-web/dist/assets/berry-QTBYpUPn.js +1 -0
- package/codemini-web/dist/assets/bibtex-CzFWvn9u.js +1 -0
- package/codemini-web/dist/assets/bibtex-aOfmXHFj.js +0 -0
- package/codemini-web/dist/assets/bicep-BZLx0b6B.js +0 -0
- package/codemini-web/dist/assets/bicep-DLWEubga.js +1 -0
- package/codemini-web/dist/assets/bird2-V7dWeQhQ.js +1 -0
- package/codemini-web/dist/assets/{bird2-Bs7YDhA3.js → bird2-VVa6lZ01.js} +0 -0
- package/codemini-web/dist/assets/blade-B3_bxlV2.js +1 -0
- package/codemini-web/dist/assets/{blade-B-u5p0Rp.js → blade-Dt6km9YT.js} +1 -1
- package/codemini-web/dist/assets/bsl-CPV9KqsG.js +0 -0
- package/codemini-web/dist/assets/bsl-D3u1l2dW.js +1 -0
- package/codemini-web/dist/assets/c-Bv0tI3pq.js +0 -0
- package/codemini-web/dist/assets/c-CgTSul4N.js +1 -0
- package/codemini-web/dist/assets/c3-BDcFIiRd.js +0 -0
- package/codemini-web/dist/assets/c3-SmmwBAzR.js +1 -0
- package/codemini-web/dist/assets/cadence-DVNAI4pJ.js +1 -0
- package/codemini-web/dist/assets/cadence-DaglWUgA.js +0 -0
- package/codemini-web/dist/assets/cairo-CoQzhJ_o.js +1 -0
- package/codemini-web/dist/assets/cairo-CyiRuu7R.js +0 -0
- package/codemini-web/dist/assets/catppuccin-frappe-CSAC76is.js +0 -0
- package/codemini-web/dist/assets/catppuccin-frappe-DXCXlnyU.js +1 -0
- package/codemini-web/dist/assets/catppuccin-latte-BXW2qYGv.js +1 -0
- package/codemini-web/dist/assets/catppuccin-latte-Jt6sqtds.js +0 -0
- package/codemini-web/dist/assets/catppuccin-macchiato--32cesHH.js +1 -0
- package/codemini-web/dist/assets/catppuccin-macchiato-HM96_05s.js +0 -0
- package/codemini-web/dist/assets/catppuccin-mocha-BBRFilGN.js +1 -0
- package/codemini-web/dist/assets/catppuccin-mocha-CXgIAGBL.js +0 -0
- package/codemini-web/dist/assets/clarity-BJs8u8xG.js +1 -0
- package/codemini-web/dist/assets/clarity-DS5YLe8G.js +0 -0
- package/codemini-web/dist/assets/clojure-BVGPdaE2.js +0 -0
- package/codemini-web/dist/assets/clojure-DpYoDXXl.js +1 -0
- package/codemini-web/dist/assets/cmake-CCC7tP43.js +0 -0
- package/codemini-web/dist/assets/cmake-CdseusyP.js +1 -0
- package/codemini-web/dist/assets/{cobol-CkQrskif.js → cobol-D_kesMA-.js} +1 -1
- package/codemini-web/dist/assets/cobol-DqhY5el-.js +1 -0
- package/codemini-web/dist/assets/codeowners-5EAeZxPo.js +1 -0
- package/codemini-web/dist/assets/codeowners-DXhoR5Ap.js +0 -0
- package/codemini-web/dist/assets/codeql-BGjlu3KC.js +0 -0
- package/codemini-web/dist/assets/codeql-OkUuMGe9.js +1 -0
- package/codemini-web/dist/assets/coffee-DF15_0rk.js +1 -0
- package/codemini-web/dist/assets/coffee-rY-gkJy7.js +0 -0
- package/codemini-web/dist/assets/common-lisp-BE6wRQeA.js +0 -0
- package/codemini-web/dist/assets/common-lisp-DCRDlc4V.js +1 -0
- package/codemini-web/dist/assets/coq-CRT8yML1.js +0 -0
- package/codemini-web/dist/assets/coq-acwo70uY.js +1 -0
- package/codemini-web/dist/assets/cpp-Bw-qV0P6.js +0 -0
- package/codemini-web/dist/assets/cpp-Cudwe5mG.js +1 -0
- package/codemini-web/dist/assets/{crystal-Dh09vXLx.js → crystal-Bw1_1hFA.js} +1 -1
- package/codemini-web/dist/assets/crystal-DV9Nijjb.js +1 -0
- package/codemini-web/dist/assets/csharp-Ca2kU4Te.js +0 -0
- package/codemini-web/dist/assets/csharp-Cqz84DXU.js +1 -0
- package/codemini-web/dist/assets/{css-BTi88BmP.js → css-Dr0v2l-V.js} +0 -0
- package/codemini-web/dist/assets/css-z2ijrDWT.js +1 -0
- package/codemini-web/dist/assets/csv-CqpUSPyF.js +1 -0
- package/codemini-web/dist/assets/csv-DUpZC5ZD.js +0 -0
- package/codemini-web/dist/assets/cue-D4-Hq7Jx.js +1 -0
- package/codemini-web/dist/assets/cue-DlXQ7arx.js +0 -0
- package/codemini-web/dist/assets/cypher-CXMVfSpG.js +1 -0
- package/codemini-web/dist/assets/cypher-D6dhuZbo.js +0 -0
- package/codemini-web/dist/assets/d-BUgyoY6k.js +0 -0
- package/codemini-web/dist/assets/d-Cc_KoyiC.js +1 -0
- package/codemini-web/dist/assets/dark-plus-C0kLyDb3.js +1 -0
- package/codemini-web/dist/assets/dark-plus-DNkJKrcZ.js +0 -0
- package/codemini-web/dist/assets/{dart-Czrjv-nr.js → dart-BIyV3H7V.js} +0 -0
- package/codemini-web/dist/assets/dart-CVd7TDni.js +1 -0
- package/codemini-web/dist/assets/dax-DtoJMuz5.js +1 -0
- package/codemini-web/dist/assets/dax-sEzq00Tq.js +0 -0
- package/codemini-web/dist/assets/desktop-3VGbzlmJ.js +0 -0
- package/codemini-web/dist/assets/desktop-BkIJ2CMP.js +1 -0
- package/codemini-web/dist/assets/diff-D4HSRbRn.js +0 -0
- package/codemini-web/dist/assets/diff-RUsawely.js +1 -0
- package/codemini-web/dist/assets/docker-CDpVZYy7.js +1 -0
- package/codemini-web/dist/assets/docker-DkLGgDMo.js +0 -0
- package/codemini-web/dist/assets/dotenv-BWp1FaLo.js +0 -0
- package/codemini-web/dist/assets/dotenv-DWnlamm2.js +1 -0
- package/codemini-web/dist/assets/dracula-Donvxzd6.js +0 -0
- package/codemini-web/dist/assets/dracula-QP8aKUFB.js +1 -0
- package/codemini-web/dist/assets/dracula-soft-BNzyYlRI.js +1 -0
- package/codemini-web/dist/assets/dracula-soft-BqL-kkUg.js +0 -0
- package/codemini-web/dist/assets/dream-maker-DtLD6KM3.js +0 -0
- package/codemini-web/dist/assets/dream-maker-MNBsfIGU.js +1 -0
- package/codemini-web/dist/assets/{edge-CCRtknu5.js → edge-BosfXYh1.js} +1 -1
- package/codemini-web/dist/assets/edge-r5NIe9Lp.js +1 -0
- package/codemini-web/dist/assets/{elixir-5EYbFEoC.js → elixir-B04apOJS.js} +1 -1
- package/codemini-web/dist/assets/elixir-Dw_vsdUl.js +1 -0
- package/codemini-web/dist/assets/elm-Cezz_HNz.js +0 -0
- package/codemini-web/dist/assets/elm-DPfFNNkG.js +1 -0
- package/codemini-web/dist/assets/emacs-lisp-BHIDiQRU.js +1 -0
- package/codemini-web/dist/assets/{emacs-lisp-D4W-_rAk.js → emacs-lisp-CVlPXEEa.js} +0 -0
- package/codemini-web/dist/assets/{erb-C6pPz4fX.js → erb-BNioEFKQ.js} +1 -1
- package/codemini-web/dist/assets/erb-DZuoCU5t.js +1 -0
- package/codemini-web/dist/assets/erlang-BC8wryba.js +0 -0
- package/codemini-web/dist/assets/erlang-CqHCISqs.js +1 -0
- package/codemini-web/dist/assets/everforest-dark-DSK976eP.js +1 -0
- package/codemini-web/dist/assets/everforest-dark-pZNhY4MK.js +0 -0
- package/codemini-web/dist/assets/everforest-light-BijKClkf.js +0 -0
- package/codemini-web/dist/assets/everforest-light-BkaBVm1r.js +1 -0
- package/codemini-web/dist/assets/fennel-BsP4yvxI.js +1 -0
- package/codemini-web/dist/assets/fennel-Cd-BhZ0S.js +0 -0
- package/codemini-web/dist/assets/fish-CimYqIk1.js +1 -0
- package/codemini-web/dist/assets/fish-CpsjJ6FK.js +0 -0
- package/codemini-web/dist/assets/fluent-D1peBFgx.js +0 -0
- package/codemini-web/dist/assets/fluent-O-Iic89O.js +1 -0
- package/codemini-web/dist/assets/fortran-fixed-form-60ZQAHDk.js +1 -0
- package/codemini-web/dist/assets/fortran-fixed-form-CyrImzNA.js +0 -0
- package/codemini-web/dist/assets/fortran-free-form-BVNtEstX.js +1 -0
- package/codemini-web/dist/assets/fortran-free-form-CIAQqF5W.js +0 -0
- package/codemini-web/dist/assets/fsharp-Ch5ZVinn.js +1 -0
- package/codemini-web/dist/assets/fsharp-OCW_PZ4J.js +0 -0
- package/codemini-web/dist/assets/gdresource-Cl3bohRI.js +0 -0
- package/codemini-web/dist/assets/gdresource-CqNLhJW1.js +1 -0
- package/codemini-web/dist/assets/gdscript-B_XVILZe.js +0 -0
- package/codemini-web/dist/assets/gdscript-D-FJCTl3.js +1 -0
- package/codemini-web/dist/assets/gdshader-BOrkFM_X.js +0 -0
- package/codemini-web/dist/assets/gdshader-Czvzt8dR.js +1 -0
- package/codemini-web/dist/assets/genie-BE7nKhIq.js +0 -0
- package/codemini-web/dist/assets/genie-Mnf_jXpg.js +1 -0
- package/codemini-web/dist/assets/gherkin-DzGJhdqS.js +0 -0
- package/codemini-web/dist/assets/gherkin-DzkYuFEO.js +1 -0
- package/codemini-web/dist/assets/git-commit-CSWECvqq.js +1 -0
- package/codemini-web/dist/assets/git-commit-DJZpdBwB.js +0 -0
- package/codemini-web/dist/assets/git-rebase-BJE30GTP.js +0 -0
- package/codemini-web/dist/assets/git-rebase-MUvuytPe.js +1 -0
- package/codemini-web/dist/assets/github-dark-BB9G20EV.js +0 -0
- package/codemini-web/dist/assets/github-dark-C98YWDhk.js +1 -0
- package/codemini-web/dist/assets/github-dark-default-CBFNEU03.js +0 -0
- package/codemini-web/dist/assets/github-dark-default-CDGuVkyn.js +1 -0
- package/codemini-web/dist/assets/github-dark-dimmed-CarTohA3.js +1 -0
- package/codemini-web/dist/assets/github-dark-dimmed-sQhEp72S.js +0 -0
- package/codemini-web/dist/assets/github-dark-high-contrast-C8GVvrcM.js +0 -0
- package/codemini-web/dist/assets/github-dark-high-contrast-CsjOICAd.js +1 -0
- package/codemini-web/dist/assets/github-light-D17m3GP4.js +1 -0
- package/codemini-web/dist/assets/github-light-default-DiMoa1ZI.js +1 -0
- package/codemini-web/dist/assets/github-light-default-iyEXWnoa.js +0 -0
- package/codemini-web/dist/assets/github-light-high-contrast-DGwHD8Ty.js +1 -0
- package/codemini-web/dist/assets/github-light-high-contrast-DLnsZL7l.js +0 -0
- package/codemini-web/dist/assets/github-light-pT7U8Cnd.js +0 -0
- package/codemini-web/dist/assets/gleam-B9ISJjDl.js +0 -0
- package/codemini-web/dist/assets/gleam-MAXpOqqF.js +1 -0
- package/codemini-web/dist/assets/{glimmer-js-C4PTXfaW.js → glimmer-js-Dn6vjgHP.js} +1 -1
- package/codemini-web/dist/assets/glimmer-js-HDDEErW7.js +1 -0
- package/codemini-web/dist/assets/glimmer-ts-Dq0_BflX.js +1 -0
- package/codemini-web/dist/assets/{glimmer-ts-Df1V6YK_.js → glimmer-ts-mq-Q_zEE.js} +1 -1
- package/codemini-web/dist/assets/glsl-C4rvog10.js +1 -0
- package/codemini-web/dist/assets/glsl-C8VPaAWs.js +0 -0
- package/codemini-web/dist/assets/gn-BNADkWgR.js +1 -0
- package/codemini-web/dist/assets/gn-RQRMslrP.js +0 -0
- package/codemini-web/dist/assets/gnuplot-BRQvwTQM.js +1 -0
- package/codemini-web/dist/assets/gnuplot-CfIGZWjt.js +0 -0
- package/codemini-web/dist/assets/{go-BTh90-YS.js → go-D6k5URxL.js} +0 -0
- package/codemini-web/dist/assets/go-iV8pwUYW.js +1 -0
- package/codemini-web/dist/assets/graphql-Dg0Ewf8Q.js +1 -0
- package/codemini-web/dist/assets/graphql-WZCiqIl-.js +0 -0
- package/codemini-web/dist/assets/groovy-CxG1cXrE.js +1 -0
- package/codemini-web/dist/assets/groovy-lvGC2zUz.js +0 -0
- package/codemini-web/dist/assets/gruvbox-dark-hard-CC38iqQ4.js +0 -0
- package/codemini-web/dist/assets/gruvbox-dark-hard-Cnb1fzry.js +1 -0
- package/codemini-web/dist/assets/gruvbox-dark-medium-Cu5j8v_d.js +1 -0
- package/codemini-web/dist/assets/gruvbox-dark-medium-DaS0IqFN.js +0 -0
- package/codemini-web/dist/assets/gruvbox-dark-soft-BghHDwrM.js +1 -0
- package/codemini-web/dist/assets/gruvbox-dark-soft-C4niJipy.js +0 -0
- package/codemini-web/dist/assets/gruvbox-light-hard-BUhLUxUB.js +1 -0
- package/codemini-web/dist/assets/gruvbox-light-hard-DTfv4LmB.js +0 -0
- package/codemini-web/dist/assets/gruvbox-light-medium-GXeiXGL9.js +1 -0
- package/codemini-web/dist/assets/gruvbox-light-medium-m1VBpvsE.js +0 -0
- package/codemini-web/dist/assets/gruvbox-light-soft-CiE1IJdk.js +0 -0
- package/codemini-web/dist/assets/gruvbox-light-soft-pTZgKx7j.js +1 -0
- package/codemini-web/dist/assets/{hack-zJL_tEH0.js → hack-DeD259o6.js} +1 -1
- package/codemini-web/dist/assets/hack-DjE76gIx.js +1 -0
- package/codemini-web/dist/assets/{haml-qjVLLTZk.js → haml-B8MRe8CS.js} +1 -1
- package/codemini-web/dist/assets/haml-DyIc_iO2.js +1 -0
- package/codemini-web/dist/assets/handlebars-DQ4X08Zf.js +1 -0
- package/codemini-web/dist/assets/{handlebars-B3RyMMk0.js → handlebars-GoJyzhp1.js} +1 -1
- package/codemini-web/dist/assets/haskell-BZ8bGMYA.js +1 -0
- package/codemini-web/dist/assets/haskell-DdaZtXdd.js +0 -0
- package/codemini-web/dist/assets/haxe-1eAUKQ0B.js +1 -0
- package/codemini-web/dist/assets/haxe-Df79h8x1.js +0 -0
- package/codemini-web/dist/assets/hcl-BibREsa1.js +0 -0
- package/codemini-web/dist/assets/hcl-DQqvKq2I.js +1 -0
- package/codemini-web/dist/assets/{highlighted-body-OFNGDK62-CJHWad2r.js → highlighted-body-OFNGDK62-CDUecv8k.js} +1 -1
- package/codemini-web/dist/assets/hjson-D-iSecYq.js +0 -0
- package/codemini-web/dist/assets/hjson-DNWMSWLN.js +1 -0
- package/codemini-web/dist/assets/hlsl-CckLjo_3.js +0 -0
- package/codemini-web/dist/assets/hlsl-Df5oFh9i.js +1 -0
- package/codemini-web/dist/assets/horizon-BCbhfxa1.js +1 -0
- package/codemini-web/dist/assets/horizon-BG-OH9yH.js +0 -0
- package/codemini-web/dist/assets/horizon-bright-B0vmEjwb.js +1 -0
- package/codemini-web/dist/assets/{horizon-bright-CpoqdULz.js → horizon-bright-CXcxBcih.js} +0 -0
- package/codemini-web/dist/assets/houston-C8DdNIgg.js +0 -0
- package/codemini-web/dist/assets/houston-DHnjBE42.js +1 -0
- package/codemini-web/dist/assets/{html-DP-V-rfg.js → html-B7kk5NVw.js} +1 -1
- package/codemini-web/dist/assets/html-GfHBuoLs.js +1 -0
- package/codemini-web/dist/assets/{html-derivative-DB9UhNDN.js → html-derivative-Ba28nVB3.js} +1 -1
- package/codemini-web/dist/assets/html-derivative-ChSmSZXY.js +1 -0
- package/codemini-web/dist/assets/http-DMTBhQm8.js +1 -0
- package/codemini-web/dist/assets/http-Deln4Vyb.js +0 -0
- package/codemini-web/dist/assets/hurl-CYSuhGkj.js +0 -0
- package/codemini-web/dist/assets/hurl-XIpACwjS.js +1 -0
- package/codemini-web/dist/assets/hxml-BmF7ngDz.js +0 -0
- package/codemini-web/dist/assets/hxml-PnV_FpS-.js +1 -0
- package/codemini-web/dist/assets/hy-6acR1htR.js +0 -0
- package/codemini-web/dist/assets/hy-DaILHjW8.js +1 -0
- package/codemini-web/dist/assets/imba-BA6_JyKt.js +1 -0
- package/codemini-web/dist/assets/imba-I9bJJvhi.js +0 -0
- package/codemini-web/dist/assets/index-Cfk9ARKs.js +426 -0
- package/codemini-web/dist/assets/index-Dqq2DCEb.css +2 -0
- package/codemini-web/dist/assets/ini-DqXMcqXm.js +1 -0
- package/codemini-web/dist/assets/ini-ovi-wMtM.js +0 -0
- package/codemini-web/dist/assets/java-Ds1cyVrp.js +1 -0
- package/codemini-web/dist/assets/java-X0I2c5Az.js +0 -0
- package/codemini-web/dist/assets/javascript-Cx8CXBJR.js +1 -0
- package/codemini-web/dist/assets/javascript-WC6XFf_S.js +0 -0
- package/codemini-web/dist/assets/{jinja-BcRTlqOI.js → jinja-8ATGhxJO.js} +1 -1
- package/codemini-web/dist/assets/jinja-Dx5IcFSt.js +1 -0
- package/codemini-web/dist/assets/jison-CSsYnr7O.js +1 -0
- package/codemini-web/dist/assets/jison-DuNOGix6.js +0 -0
- package/codemini-web/dist/assets/json-CY14kIzN.js +1 -0
- package/codemini-web/dist/assets/json-CmuSmrUv.js +0 -0
- package/codemini-web/dist/assets/json5-Cus7zL-r.js +1 -0
- package/codemini-web/dist/assets/json5-JNG5kh3j.js +0 -0
- package/codemini-web/dist/assets/jsonc-Bo6bgSpa.js +0 -0
- package/codemini-web/dist/assets/jsonc-RzqrtWTz.js +1 -0
- package/codemini-web/dist/assets/jsonl-CLcLUtvq.js +1 -0
- package/codemini-web/dist/assets/jsonl-eDmbsRcr.js +0 -0
- package/codemini-web/dist/assets/jsonnet--7yRuAzt.js +1 -0
- package/codemini-web/dist/assets/jsonnet-BrmnmEy9.js +0 -0
- package/codemini-web/dist/assets/jssm-C-QfdDgD.js +0 -0
- package/codemini-web/dist/assets/jssm-Cid5Rr2Y.js +1 -0
- package/codemini-web/dist/assets/jsx-Bl4e1-KE.js +0 -0
- package/codemini-web/dist/assets/jsx-DmH5dwMF.js +1 -0
- package/codemini-web/dist/assets/julia-Cqc1ADyw.js +0 -0
- package/codemini-web/dist/assets/julia-vjG00jwO.js +1 -0
- package/codemini-web/dist/assets/{just-O9z-zIlY.js → just-BlUYrdKb.js} +1 -1
- package/codemini-web/dist/assets/just-C7G3KFgN.js +1 -0
- package/codemini-web/dist/assets/kanagawa-dragon-BxDDNs-7.js +1 -0
- package/codemini-web/dist/assets/kanagawa-dragon-Dc8jzBf8.js +0 -0
- package/codemini-web/dist/assets/kanagawa-lotus-BQyifewU.js +1 -0
- package/codemini-web/dist/assets/kanagawa-lotus-DglQpAHb.js +0 -0
- package/codemini-web/dist/assets/kanagawa-wave-BsJGVIZT.js +1 -0
- package/codemini-web/dist/assets/kanagawa-wave-CTxJC692.js +0 -0
- package/codemini-web/dist/assets/kdl-CPujEk7a.js +0 -0
- package/codemini-web/dist/assets/kdl-D2MbAIKj.js +1 -0
- package/codemini-web/dist/assets/kotlin-GNGS6f4G.js +0 -0
- package/codemini-web/dist/assets/kotlin-fpq87Jdo.js +1 -0
- package/codemini-web/dist/assets/{kusto-ByPWIc1b.js → kusto-B1r4va-8.js} +0 -0
- package/codemini-web/dist/assets/kusto-BcKmLn2p.js +1 -0
- package/codemini-web/dist/assets/laserwave-BLDq6SCM.js +0 -0
- package/codemini-web/dist/assets/laserwave-CrjhMkHv.js +1 -0
- package/codemini-web/dist/assets/latex-BEPTKliI.js +0 -0
- package/codemini-web/dist/assets/latex-D8-NgtPj.js +1 -0
- package/codemini-web/dist/assets/lean-B9Xp-kaJ.js +1 -0
- package/codemini-web/dist/assets/lean-CQ4oht2M.js +0 -0
- package/codemini-web/dist/assets/less-BKjOc0Gl.js +1 -0
- package/codemini-web/dist/assets/less-DgluPI4Z.js +0 -0
- package/codemini-web/dist/assets/light-plus-Ce6vIMrA.js +0 -0
- package/codemini-web/dist/assets/light-plus-DFt9HI_B.js +1 -0
- package/codemini-web/dist/assets/{liquid-BK2PyMjt.js → liquid-BUh7yINm.js} +1 -1
- package/codemini-web/dist/assets/liquid-D2m0XXrV.js +1 -0
- package/codemini-web/dist/assets/llvm-C_Bk8N51.js +0 -0
- package/codemini-web/dist/assets/llvm-XDy97SdL.js +1 -0
- package/codemini-web/dist/assets/log-Cqyx7kYB.js +0 -0
- package/codemini-web/dist/assets/log-tjGJZ7jx.js +1 -0
- package/codemini-web/dist/assets/logo-BMyACSNp.js +0 -0
- package/codemini-web/dist/assets/logo-rCQwad-6.js +1 -0
- package/codemini-web/dist/assets/lua-BeSXusec.js +1 -0
- package/codemini-web/dist/assets/lua-BroxvhVt.js +0 -0
- package/codemini-web/dist/assets/luau-C0wE4YeK.js +1 -0
- package/codemini-web/dist/assets/luau-Dw3qkd4h.js +0 -0
- package/codemini-web/dist/assets/make-DRoG6w-e.js +0 -0
- package/codemini-web/dist/assets/make-DZENZd8z.js +1 -0
- package/codemini-web/dist/assets/markdown-CbgVmtS5.js +1 -0
- package/codemini-web/dist/assets/markdown-DMIvNSB1.js +0 -0
- package/codemini-web/dist/assets/marko-DPnRthJQ.js +1 -0
- package/codemini-web/dist/assets/{marko-CTEKS39A.js → marko-Dm8xPXkG.js} +1 -1
- package/codemini-web/dist/assets/material-theme-D1yzOeFY.js +0 -0
- package/codemini-web/dist/assets/material-theme-YhiuxyiP.js +1 -0
- package/codemini-web/dist/assets/material-theme-darker-CKeuyK7B.js +1 -0
- package/codemini-web/dist/assets/material-theme-darker-DhWqiNtj.js +0 -0
- package/codemini-web/dist/assets/material-theme-lighter-C56RzTfM.js +1 -0
- package/codemini-web/dist/assets/material-theme-lighter-PKoq0Soa.js +0 -0
- package/codemini-web/dist/assets/material-theme-ocean-DUos8xKe.js +1 -0
- package/codemini-web/dist/assets/material-theme-ocean-TtH-ZZAj.js +0 -0
- package/codemini-web/dist/assets/material-theme-palenight-CZBKx4B1.js +1 -0
- package/codemini-web/dist/assets/material-theme-palenight-DPEAidnA.js +0 -0
- package/codemini-web/dist/assets/matlab-BJwkjxyL.js +1 -0
- package/codemini-web/dist/assets/matlab-Buftnej6.js +0 -0
- package/codemini-web/dist/assets/mdc-BLdFHYKv.js +1 -0
- package/codemini-web/dist/assets/{mdc-BOaCYzzL.js → mdc-Dzipcsdb.js} +1 -1
- package/codemini-web/dist/assets/mdx-BvkytFG9.js +1 -0
- package/codemini-web/dist/assets/mdx-COL7Vpwq.js +0 -0
- package/codemini-web/dist/assets/mermaid-Ctx7uNrT.js +1 -0
- package/codemini-web/dist/assets/mermaid-GHXKKRXX-BWSxGKNn.js +1 -0
- package/codemini-web/dist/assets/mermaid-tvyj1ZQ2.js +0 -0
- package/codemini-web/dist/assets/min-dark-BA-rwgF3.js +1 -0
- package/codemini-web/dist/assets/min-dark-D66g901Q.js +0 -0
- package/codemini-web/dist/assets/min-light-CMnDj2iG.js +0 -0
- package/codemini-web/dist/assets/min-light-DHUVhXnm.js +1 -0
- package/codemini-web/dist/assets/mipsasm-ByaU0dEX.js +1 -0
- package/codemini-web/dist/assets/mipsasm-C6fvALrw.js +0 -0
- package/codemini-web/dist/assets/mojo-B3qnM1a8.js +0 -0
- package/codemini-web/dist/assets/mojo-CqhYERP_.js +1 -0
- package/codemini-web/dist/assets/monokai-D3MyQCxG.js +1 -0
- package/codemini-web/dist/assets/monokai-DCoxt20T.js +0 -0
- package/codemini-web/dist/assets/moonbit-C4BfwLm6.js +1 -0
- package/codemini-web/dist/assets/moonbit-Cjo3d0oi.js +0 -0
- package/codemini-web/dist/assets/move-BZSDQnwS.js +0 -0
- package/codemini-web/dist/assets/move-DOj5FawL.js +1 -0
- package/codemini-web/dist/assets/narrat-CDHYPJWr.js +1 -0
- package/codemini-web/dist/assets/narrat-DY5cg5OF.js +0 -0
- package/codemini-web/dist/assets/{nextflow-Cto1mpL3.js → nextflow-BRiWOV-p.js} +1 -1
- package/codemini-web/dist/assets/nextflow-c8YCPRRb.js +1 -0
- package/codemini-web/dist/assets/nextflow-groovy-D6rYlJlL.js +1 -0
- package/codemini-web/dist/assets/{nextflow-groovy-D1X5Yd05.js → nextflow-groovy-o7ZjyFmf.js} +0 -0
- package/codemini-web/dist/assets/nginx-Da_Uewgc.js +0 -0
- package/codemini-web/dist/assets/nginx-u-hq5m-a.js +1 -0
- package/codemini-web/dist/assets/night-owl-DuMFo77c.js +0 -0
- package/codemini-web/dist/assets/night-owl-NHZjGVLB.js +1 -0
- package/codemini-web/dist/assets/night-owl-light-DcKosvl7.js +1 -0
- package/codemini-web/dist/assets/night-owl-light-DihOYNub.js +0 -0
- package/codemini-web/dist/assets/nim-B5b6_jZr.js +1 -0
- package/codemini-web/dist/assets/{nim-BZyx58NM.js → nim-CvgRYLO2.js} +1 -1
- package/codemini-web/dist/assets/nix-C2G-gZoY.js +0 -0
- package/codemini-web/dist/assets/nix-Csr5leD-.js +1 -0
- package/codemini-web/dist/assets/nord-CqZqLQaJ.js +0 -0
- package/codemini-web/dist/assets/nord-DomFMWpF.js +1 -0
- package/codemini-web/dist/assets/nushell-IZVQdI7Z.js +1 -0
- package/codemini-web/dist/assets/nushell-S11HUHTG.js +0 -0
- package/codemini-web/dist/assets/objective-c-D9GKvYFi.js +0 -0
- package/codemini-web/dist/assets/objective-c-DD1i5sf2.js +1 -0
- package/codemini-web/dist/assets/objective-cpp-CtzOCe2w.js +1 -0
- package/codemini-web/dist/assets/objective-cpp-SqrtXFXh.js +0 -0
- package/codemini-web/dist/assets/ocaml-BlMDMjEj.js +1 -0
- package/codemini-web/dist/assets/ocaml-C_PTi_Pz.js +0 -0
- package/codemini-web/dist/assets/odin-BWpZDKBG.js +0 -0
- package/codemini-web/dist/assets/odin-CoWSDSNi.js +1 -0
- package/codemini-web/dist/assets/one-dark-pro-DWENJxB_.js +1 -0
- package/codemini-web/dist/assets/one-dark-pro-DpWTHpwg.js +0 -0
- package/codemini-web/dist/assets/one-light-CEeF6aqP.js +1 -0
- package/codemini-web/dist/assets/one-light-Cu0d64Hp.js +0 -0
- package/codemini-web/dist/assets/openscad-BM4fjXzn.js +0 -0
- package/codemini-web/dist/assets/openscad-D3gRRPUh.js +1 -0
- package/codemini-web/dist/assets/pascal-DYsRufgb.js +0 -0
- package/codemini-web/dist/assets/pascal-G3gJIkHz.js +1 -0
- package/codemini-web/dist/assets/{perl-BW8t13Xq.js → perl-BIcNvyL6.js} +1 -1
- package/codemini-web/dist/assets/perl-DdF12AsD.js +1 -0
- package/codemini-web/dist/assets/php-BP-3TkW_.js +1 -0
- package/codemini-web/dist/assets/{php-Cq5FOhfR.js → php-CyQZnE0l.js} +1 -1
- package/codemini-web/dist/assets/pierre-dark-CBqOR10c.js +1 -0
- package/codemini-web/dist/assets/pierre-light-sgwdVCEP.js +1 -0
- package/codemini-web/dist/assets/pkl-DdsryWcC.js +1 -0
- package/codemini-web/dist/assets/pkl-Djf8ANrI.js +0 -0
- package/codemini-web/dist/assets/plastic-CmjIC4JL.js +0 -0
- package/codemini-web/dist/assets/plastic-CwUA_4-2.js +1 -0
- package/codemini-web/dist/assets/plsql-B1bmZxUF.js +0 -0
- package/codemini-web/dist/assets/plsql-C2yEtnCG.js +1 -0
- package/codemini-web/dist/assets/po-BvnTR3_f.js +0 -0
- package/codemini-web/dist/assets/po-Dy7ytuR1.js +1 -0
- package/codemini-web/dist/assets/poimandres-BTndTogr.js +0 -0
- package/codemini-web/dist/assets/poimandres-u68WOWhl.js +1 -0
- package/codemini-web/dist/assets/polar-CAj5SJyd.js +0 -0
- package/codemini-web/dist/assets/polar-CjLVWIyd.js +1 -0
- package/codemini-web/dist/assets/postcss-DiNtjF5e.js +1 -0
- package/codemini-web/dist/assets/postcss-DrpvRGGG.js +0 -0
- package/codemini-web/dist/assets/powerquery-I1Ei5hrS.js +0 -0
- package/codemini-web/dist/assets/powerquery-iC4Ra9LJ.js +1 -0
- package/codemini-web/dist/assets/powershell-Ch2YpFAx.js +1 -0
- package/codemini-web/dist/assets/powershell-Coc0WruX.js +0 -0
- package/codemini-web/dist/assets/prisma-HWctQCpn.js +1 -0
- package/codemini-web/dist/assets/prisma-Ojgxt2lx.js +0 -0
- package/codemini-web/dist/assets/prolog-C1UOAv4v.js +0 -0
- package/codemini-web/dist/assets/prolog-DHAsH4Hf.js +1 -0
- package/codemini-web/dist/assets/proto-D07RTuB5.js +0 -0
- package/codemini-web/dist/assets/proto-mTghX89X.js +1 -0
- package/codemini-web/dist/assets/pug-HwoxZo9M.js +1 -0
- package/codemini-web/dist/assets/{pug-B4WHazil.js → pug-_XoIcKf3.js} +1 -1
- package/codemini-web/dist/assets/puppet-D1Zcnrr5.js +1 -0
- package/codemini-web/dist/assets/puppet-D_zyrMo2.js +0 -0
- package/codemini-web/dist/assets/purescript-CV-DVmZj.js +0 -0
- package/codemini-web/dist/assets/purescript-s82m5f0Y.js +1 -0
- package/codemini-web/dist/assets/python-BhsI1K6K.js +1 -0
- package/codemini-web/dist/assets/python-DcnbpNOV.js +0 -0
- package/codemini-web/dist/assets/qml-CysuucQ6.js +1 -0
- package/codemini-web/dist/assets/qml-DWxWu28U.js +0 -0
- package/codemini-web/dist/assets/qmldir-BBNnU9RJ.js +0 -0
- package/codemini-web/dist/assets/qmldir-Bzkc2Njy.js +1 -0
- package/codemini-web/dist/assets/qss-CC0PKRbL.js +0 -0
- package/codemini-web/dist/assets/qss-CKbozdtF.js +1 -0
- package/codemini-web/dist/assets/r-B4lG5syH.js +0 -0
- package/codemini-web/dist/assets/r-BKej5r_k.js +1 -0
- package/codemini-web/dist/assets/racket-CUDoXUwy.js +1 -0
- package/codemini-web/dist/assets/racket-Cbwns2Cq.js +0 -0
- package/codemini-web/dist/assets/raku-CeV6tH_x.js +0 -0
- package/codemini-web/dist/assets/raku-XPAjN9OU.js +1 -0
- package/codemini-web/dist/assets/{razor-CQPYUgex.js → razor-DQ6FV4WL.js} +1 -1
- package/codemini-web/dist/assets/razor-ZpEr_C9H.js +1 -0
- package/codemini-web/dist/assets/red-8aRo80UF.js +1 -0
- package/codemini-web/dist/assets/red-CVEaJbMR.js +0 -0
- package/codemini-web/dist/assets/reg-B0B_plbq.js +1 -0
- package/codemini-web/dist/assets/reg-C_WE1pkC.js +0 -0
- package/codemini-web/dist/assets/regexp-CK-1EP63.js +1 -0
- package/codemini-web/dist/assets/regexp-da3KYCEG.js +0 -0
- package/codemini-web/dist/assets/rel-CpHQF4b7.js +0 -0
- package/codemini-web/dist/assets/rel-DhoFe2Y7.js +1 -0
- package/codemini-web/dist/assets/riscv-CKx_Jisq.js +1 -0
- package/codemini-web/dist/assets/riscv-Co5eiPIZ.js +0 -0
- package/codemini-web/dist/assets/rolldown-runtime-S-ySWqyJ.js +0 -0
- package/codemini-web/dist/assets/ron-CgTit1dG.js +0 -0
- package/codemini-web/dist/assets/ron-qyvgw9vu.js +1 -0
- package/codemini-web/dist/assets/rose-pine-BDTwvYHf.js +0 -0
- package/codemini-web/dist/assets/rose-pine-R3f76h4_.js +1 -0
- package/codemini-web/dist/assets/rose-pine-dawn-BS09rtpK.js +1 -0
- package/codemini-web/dist/assets/rose-pine-dawn-CAIk_wLV.js +0 -0
- package/codemini-web/dist/assets/rose-pine-moon-B4Q4DiPG.js +1 -0
- package/codemini-web/dist/assets/rose-pine-moon-C5gdiznP.js +0 -0
- package/codemini-web/dist/assets/rosmsg-C0tpzWlc.js +0 -0
- package/codemini-web/dist/assets/rosmsg-Dy_ItAfo.js +1 -0
- package/codemini-web/dist/assets/rst-CjO4XFKz.js +1 -0
- package/codemini-web/dist/assets/{rst-B-OS2pa5.js → rst-DDrWKQ9c.js} +1 -1
- package/codemini-web/dist/assets/ruby-BOVYgV5O.js +1 -0
- package/codemini-web/dist/assets/{ruby-BM15fmxz.js → ruby-CZgIYPlP.js} +1 -1
- package/codemini-web/dist/assets/rust-BWAfVMY4.js +0 -0
- package/codemini-web/dist/assets/rust-CNEVkiWF.js +1 -0
- package/codemini-web/dist/assets/sas-DPGT0TjQ.js +1 -0
- package/codemini-web/dist/assets/sas-DYNukvU9.js +0 -0
- package/codemini-web/dist/assets/sass-D2nye32F.js +1 -0
- package/codemini-web/dist/assets/sass-MovLey2R.js +0 -0
- package/codemini-web/dist/assets/scala-B8greAnE.js +1 -0
- package/codemini-web/dist/assets/scala-C2w7y2mZ.js +0 -0
- package/codemini-web/dist/assets/scheme-Bf85FNnm.js +0 -0
- package/codemini-web/dist/assets/scheme-Ci_aquns.js +1 -0
- package/codemini-web/dist/assets/{scss-C0BQ8YVM.js → scss-CaciJ0Gl.js} +1 -1
- package/codemini-web/dist/assets/scss-YARKxu2i.js +1 -0
- package/codemini-web/dist/assets/sdbl-D4tJqBiC.js +1 -0
- package/codemini-web/dist/assets/sdbl-DoQ_zDzo.js +0 -0
- package/codemini-web/dist/assets/shaderlab-JWcsxey4.js +1 -0
- package/codemini-web/dist/assets/shaderlab-TbUUdmUb.js +0 -0
- package/codemini-web/dist/assets/shellscript-CxhArCCJ.js +1 -0
- package/codemini-web/dist/assets/shellscript-KUJZnuCi.js +0 -0
- package/codemini-web/dist/assets/shellsession-BeWGuVoR.js +0 -0
- package/codemini-web/dist/assets/shellsession-DYmuifdt.js +1 -0
- package/codemini-web/dist/assets/slack-dark-BcN7KJ02.js +1 -0
- package/codemini-web/dist/assets/slack-dark-BnOYKTBJ.js +0 -0
- package/codemini-web/dist/assets/slack-ochin-43udxtUg.js +0 -0
- package/codemini-web/dist/assets/slack-ochin-D4iInQ9w.js +1 -0
- package/codemini-web/dist/assets/smalltalk-BwSireXb.js +1 -0
- package/codemini-web/dist/assets/smalltalk-Mlf5-xbr.js +0 -0
- package/codemini-web/dist/assets/snazzy-light-B45TfPsv.js +1 -0
- package/codemini-web/dist/assets/snazzy-light-kw-pZEiM.js +0 -0
- package/codemini-web/dist/assets/solarized-dark-8yYW1wLs.js +1 -0
- package/codemini-web/dist/assets/solarized-dark-BDezFa9V.js +0 -0
- package/codemini-web/dist/assets/solarized-light-BY3Hr0Ud.js +1 -0
- package/codemini-web/dist/assets/solarized-light-CkoenhS2.js +0 -0
- package/codemini-web/dist/assets/solidity-CIUlntDs.js +1 -0
- package/codemini-web/dist/assets/solidity-DYHGECBw.js +0 -0
- package/codemini-web/dist/assets/{soy-C6D0Ibo9.js → soy-7iHZG9Jz.js} +1 -1
- package/codemini-web/dist/assets/soy-h0dQKbQs.js +1 -0
- package/codemini-web/dist/assets/sparql-BGRSvFxd.js +1 -0
- package/codemini-web/dist/assets/sparql-DIFvSn1n.js +0 -0
- package/codemini-web/dist/assets/splunk-DOdklC0I.js +0 -0
- package/codemini-web/dist/assets/splunk-DueVPk5k.js +1 -0
- package/codemini-web/dist/assets/sql-CZAMrWdL.js +0 -0
- package/codemini-web/dist/assets/sql-Q6zkgi_w.js +1 -0
- package/codemini-web/dist/assets/ssh-config-DKIMErlp.js +1 -0
- package/codemini-web/dist/assets/ssh-config-DwwFW7AS.js +0 -0
- package/codemini-web/dist/assets/stata-C5mLa_ER.js +0 -0
- package/codemini-web/dist/assets/stata-lXN9BRaz.js +1 -0
- package/codemini-web/dist/assets/stylus-BO6mlOab.js +0 -0
- package/codemini-web/dist/assets/stylus-oqceM0yt.js +1 -0
- package/codemini-web/dist/assets/surrealql-DyoUfV6n.js +0 -0
- package/codemini-web/dist/assets/surrealql-l0SGzwOs.js +1 -0
- package/codemini-web/dist/assets/svelte-BM89dRu0.js +1 -0
- package/codemini-web/dist/assets/{svelte-DJ-0FpL2.js → svelte-CijnRGul.js} +1 -1
- package/codemini-web/dist/assets/swift-D9A08YU9.js +0 -0
- package/codemini-web/dist/assets/swift-foA31xPc.js +1 -0
- package/codemini-web/dist/assets/synthwave-84-B002ZU4p.js +1 -0
- package/codemini-web/dist/assets/synthwave-84-C69NN2j9.js +0 -0
- package/codemini-web/dist/assets/system-verilog-CCSGcM60.js +1 -0
- package/codemini-web/dist/assets/system-verilog-DjR3sN6w.js +0 -0
- package/codemini-web/dist/assets/systemd-BymS_eIJ.js +1 -0
- package/codemini-web/dist/assets/systemd-CJWuVSJU.js +0 -0
- package/codemini-web/dist/assets/talonscript-CXqq0wX-.js +0 -0
- package/codemini-web/dist/assets/talonscript-Ccc0122j.js +1 -0
- package/codemini-web/dist/assets/tasl-GVNf7pB7.js +0 -0
- package/codemini-web/dist/assets/tasl-o38sfjeU.js +1 -0
- package/codemini-web/dist/assets/tcl-DISPE-5Q.js +1 -0
- package/codemini-web/dist/assets/tcl-DNlfRSl5.js +0 -0
- package/codemini-web/dist/assets/{templ-7Bvm-rei.js → templ-CNjJl440.js} +1 -1
- package/codemini-web/dist/assets/templ-D1GoDFsp.js +1 -0
- package/codemini-web/dist/assets/terraform-DUK0FOOj.js +0 -0
- package/codemini-web/dist/assets/terraform-V85Kewcz.js +1 -0
- package/codemini-web/dist/assets/tex-CxEkh6NI.js +1 -0
- package/codemini-web/dist/assets/tex-ezg8IclB.js +0 -0
- package/codemini-web/dist/assets/tokyo-night-BLn5KNCP.js +1 -0
- package/codemini-web/dist/assets/tokyo-night-DWTtuXS3.js +0 -0
- package/codemini-web/dist/assets/toml-X5n3zjEH.js +0 -0
- package/codemini-web/dist/assets/toml-uEjeW8NC.js +1 -0
- package/codemini-web/dist/assets/{ts-tags-BfuR6EQ0.js → ts-tags-B88Nbzcl.js} +1 -1
- package/codemini-web/dist/assets/ts-tags-DV6nguf9.js +1 -0
- package/codemini-web/dist/assets/tsv-Bqs_rchc.js +0 -0
- package/codemini-web/dist/assets/tsv-DjGwUc04.js +1 -0
- package/codemini-web/dist/assets/tsx-5O-M05V0.js +1 -0
- package/codemini-web/dist/assets/tsx-CfyUE2pW.js +0 -0
- package/codemini-web/dist/assets/turtle-BsUuoeVK.js +0 -0
- package/codemini-web/dist/assets/turtle-PTxTluYn.js +1 -0
- package/codemini-web/dist/assets/twig-B3Kws0Fb.js +1 -0
- package/codemini-web/dist/assets/{twig-_uxJ-QmX.js → twig-BROkIZLg.js} +1 -1
- package/codemini-web/dist/assets/typescript-C6LvTgbf.js +0 -0
- package/codemini-web/dist/assets/typescript-hRweav8r.js +1 -0
- package/codemini-web/dist/assets/typespec-CKEcF6Kw.js +1 -0
- package/codemini-web/dist/assets/{typespec-8nkhqWz6.js → typespec-N7-U_jBZ.js} +0 -0
- package/codemini-web/dist/assets/typst-CPL77SDw.js +0 -0
- package/codemini-web/dist/assets/typst-DSQh9HII.js +1 -0
- package/codemini-web/dist/assets/v-CoJD3IPx.js +0 -0
- package/codemini-web/dist/assets/v-obK6h_YW.js +1 -0
- package/codemini-web/dist/assets/vala-C42IfotU.js +0 -0
- package/codemini-web/dist/assets/vala-DXa9jSo-.js +1 -0
- package/codemini-web/dist/assets/vb-CVMKTK26.js +0 -0
- package/codemini-web/dist/assets/vb-DEPbtYq-.js +1 -0
- package/codemini-web/dist/assets/verilog-Bs-185hK.js +1 -0
- package/codemini-web/dist/assets/verilog-P63PhzSt.js +0 -0
- package/codemini-web/dist/assets/vesper-B7BneC5G.js +1 -0
- package/codemini-web/dist/assets/vesper-BGr95374.js +0 -0
- package/codemini-web/dist/assets/vhdl-2WwUdgX8.js +0 -0
- package/codemini-web/dist/assets/vhdl-CBukgB2Z.js +1 -0
- package/codemini-web/dist/assets/viml-C1cRY0x6.js +1 -0
- package/codemini-web/dist/assets/viml-CGPGWJA6.js +0 -0
- package/codemini-web/dist/assets/vitesse-black-D3_12zni.js +1 -0
- package/codemini-web/dist/assets/vitesse-black-cI0k84-I.js +0 -0
- package/codemini-web/dist/assets/vitesse-dark-B_iF7INE.js +1 -0
- package/codemini-web/dist/assets/vitesse-dark-SouM0FMW.js +0 -0
- package/codemini-web/dist/assets/vitesse-light-DbrrMtxY.js +1 -0
- package/codemini-web/dist/assets/vitesse-light-WiCy6lDO.js +0 -0
- package/codemini-web/dist/assets/{vue-DkOBu49o.js → vue-BUQP_8VF.js} +1 -1
- package/codemini-web/dist/assets/vue-CT36qSUr.js +1 -0
- package/codemini-web/dist/assets/vue-html-Bx2Sgp8M.js +0 -0
- package/codemini-web/dist/assets/vue-html-bJyjqZnI.js +1 -0
- package/codemini-web/dist/assets/vue-vine-BLqV15Pm.js +1 -0
- package/codemini-web/dist/assets/{vue-vine-veyFk6GJ.js → vue-vine-RK3AHrhp.js} +1 -1
- package/codemini-web/dist/assets/vyper-BxVot6rR.js +1 -0
- package/codemini-web/dist/assets/vyper-DP_vqZO9.js +0 -0
- package/codemini-web/dist/assets/wasm-BNTPmfEI.js +1 -0
- package/codemini-web/dist/assets/wasm-Db7VBw0n.js +0 -0
- package/codemini-web/dist/assets/wasm-DiIFv9DE.js +0 -0
- package/codemini-web/dist/assets/wasm-o5uYkU9G.js +1 -0
- package/codemini-web/dist/assets/wenyan-MnC4h24X.js +1 -0
- package/codemini-web/dist/assets/wenyan-ZEcjghA1.js +0 -0
- package/codemini-web/dist/assets/wgsl-BgfkHnVi.js +1 -0
- package/codemini-web/dist/assets/wgsl-CdusuPLe.js +0 -0
- package/codemini-web/dist/assets/wikitext-CBIB6hmW.js +0 -0
- package/codemini-web/dist/assets/wikitext-DCOnP3yk.js +1 -0
- package/codemini-web/dist/assets/wit-5UDEI7sp.js +1 -0
- package/codemini-web/dist/assets/wit-ZhUbVeze.js +0 -0
- package/codemini-web/dist/assets/wolfram-HyMOyERF.js +0 -0
- package/codemini-web/dist/assets/wolfram-vvgPlu2n.js +1 -0
- package/codemini-web/dist/assets/xml-BkdunjRC.js +0 -0
- package/codemini-web/dist/assets/xml-DyJ3D9rW.js +1 -0
- package/codemini-web/dist/assets/xsl-BOsdDgv_.js +1 -0
- package/codemini-web/dist/assets/xsl-C66i1pDH.js +0 -0
- package/codemini-web/dist/assets/yaml-C-G727Y6.js +1 -0
- package/codemini-web/dist/assets/yaml-D_uvhEF7.js +0 -0
- package/codemini-web/dist/assets/zenscript-BPjqX0BY.js +1 -0
- package/codemini-web/dist/assets/zenscript-C6ZuzgrL.js +0 -0
- package/codemini-web/dist/assets/zig-Bd91oU8r.js +1 -0
- package/codemini-web/dist/assets/zig-Do2h8XKj.js +0 -0
- package/codemini-web/dist/codemini_logo.png +0 -0
- package/codemini-web/dist/favicon.ico +0 -0
- package/codemini-web/dist/index.html +6 -3
- package/codemini-web/lib/approval-manager.js +0 -0
- package/codemini-web/lib/runtime-bridge.js +22 -1
- package/codemini-web/server.js +919 -846
- package/deployment.md +5 -5
- package/package.json +1 -1
- package/skills/brainstorm/SKILL.md +3 -1
- package/skills/grill-me/SKILL.md +0 -0
- package/skills/project-requirements/SKILL.md +293 -291
- package/skills/superpowers-lite/SKILL.md +18 -32
- package/skills/writing-plans/SKILL.md +67 -67
- package/souls/anime.md +0 -0
- package/souls/caveman.md +0 -0
- package/souls/ceo.md +0 -0
- package/souls/default.md +0 -0
- package/souls/pirate.md +0 -0
- package/souls/playful.md +0 -0
- package/souls/professional.md +0 -0
- package/src/cli.js +0 -0
- package/src/commands/chat.js +1 -1
- package/src/commands/config.js +0 -0
- package/src/commands/doctor.js +0 -0
- package/src/commands/run.js +22 -7
- package/src/commands/skill.js +0 -0
- package/src/commands/web.js +0 -0
- package/src/core/agent-loop.js +11 -7
- package/src/core/ast.js +0 -0
- package/src/core/bounded-cache.js +0 -0
- package/src/core/chat-runtime.js +427 -91
- package/src/core/checkpoint-store.js +0 -0
- package/src/core/command-evaluator.js +9 -3
- package/src/core/command-loader.js +0 -0
- package/src/core/command-policy.js +0 -0
- package/src/core/command-risk.js +9 -1
- package/src/core/config-store.js +4 -2
- package/src/core/constants.js +0 -0
- package/src/core/context-compact.js +65 -3
- package/src/core/crypto-utils.js +0 -0
- package/src/core/default-system-prompt.js +12 -4
- package/src/core/dream-audit.js +0 -0
- package/src/core/dream-consolidate.js +0 -0
- package/src/core/dream-evaluator.js +0 -0
- package/src/core/fff-adapter.js +1 -1
- package/src/core/fs-utils.js +0 -0
- package/src/core/input-history-store.js +0 -0
- package/src/core/input-parser.js +0 -0
- package/src/core/memory-policy.js +0 -0
- package/src/core/memory-prompt.js +0 -0
- package/src/core/memory-store.js +0 -0
- package/src/core/paths.js +0 -0
- package/src/core/plan-state.js +0 -0
- package/src/core/project-index.js +0 -0
- package/src/core/provider/anthropic.js +0 -0
- package/src/core/provider/index.js +0 -0
- package/src/core/provider/openai-compatible.js +0 -0
- package/src/core/reflect-skill.js +1 -1
- package/src/core/reply-language.js +16 -1
- package/src/core/session-store.js +0 -0
- package/src/core/shell-profile.js +14 -1
- package/src/core/shell.js +0 -0
- package/src/core/skill-registry.js +0 -0
- package/src/core/soul.js +1 -3
- package/src/core/string-utils.js +0 -0
- package/src/core/system-prompt-composer.js +42 -0
- package/src/core/todo-state.js +0 -0
- package/src/core/tool-args.js +0 -0
- package/src/core/tool-output.js +0 -0
- package/src/core/tool-result-store.js +0 -0
- package/src/core/tools.js +2 -2
- package/src/tui/chat-app.js +13 -3
- package/src/tui/input-escape.js +0 -0
- package/src/tui/skill-activity/index.js +0 -0
- package/src/tui/tool-activity/common.js +0 -0
- package/src/tui/tool-activity/index.js +0 -0
- package/src/tui/tool-activity/presenters/command.js +0 -0
- package/src/tui/tool-activity/presenters/files.js +0 -0
- package/src/tui/tool-activity/presenters/misc.js +0 -0
- package/src/tui/tool-activity/presenters/system.js +0 -0
- package/src/tui/tool-narration/common.js +0 -0
- package/src/tui/tool-narration/presenters/change.js +0 -0
- package/src/tui/tool-narration/presenters/edit.js +0 -0
- package/src/tui/tool-narration/presenters/generic.js +0 -0
- package/src/tui/tool-narration/presenters/glob.js +0 -0
- package/src/tui/tool-narration/presenters/grep.js +0 -0
- package/src/tui/tool-narration/presenters/list.js +0 -0
- package/src/tui/tool-narration/presenters/read.js +0 -0
- package/src/tui/tool-narration/presenters/run.js +0 -0
- package/src/tui/tool-narration/presenters/write.js +0 -0
- package/src/tui/tool-narration.js +0 -0
- package/templates/project-requirements/report-shell.html +46 -46
- package/codemini-web/dist/assets/index-BZ01DHrh.js +0 -206
- package/codemini-web/dist/assets/index-Dq1mwNaQ.css +0 -2
- package/codemini-web/dist/assets/mermaid-GHXKKRXX-BuB6-G4r.js +0 -1
package/codemini-web/server.js
CHANGED
|
@@ -1,846 +1,919 @@
|
|
|
1
|
-
import http from 'node:http';
|
|
2
|
-
import fs from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { execSync } from 'node:child_process';
|
|
6
|
-
|
|
7
|
-
import { loadConfig, saveConfig, setConfigValue, getConfigValue } from '../src/core/config-store.js';
|
|
8
|
-
import { createChatRuntime } from '../src/core/chat-runtime.js';
|
|
9
|
-
import { createSession, loadSession, listSessions, resolveSession, deleteSession } from '../src/core/session-store.js';
|
|
10
|
-
import { buildDefaultSystemPrompt } from '../src/core/default-system-prompt.js';
|
|
11
|
-
import { RuntimeBridge } from './lib/runtime-bridge.js';
|
|
12
|
-
import { listSkillEntries } from '../src/commands/skill.js';
|
|
13
|
-
import { readSkillRegistry, writeSkillRegistry, upsertSkillRegistryEntry } from '../src/core/skill-registry.js';
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
'.
|
|
31
|
-
'.
|
|
32
|
-
'.
|
|
33
|
-
'.
|
|
34
|
-
'.
|
|
35
|
-
'.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (arg === '--
|
|
44
|
-
if (arg === '--
|
|
45
|
-
if (arg === '--
|
|
46
|
-
if (arg === '--
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
req.on('
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
res.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if (req.method === '
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
:
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
'
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
jsonResponse(res, { error: true, message:
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
const
|
|
568
|
-
const
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
return;
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
const
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
await
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
const
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
});
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { execSync } from 'node:child_process';
|
|
6
|
+
|
|
7
|
+
import { loadConfig, saveConfig, setConfigValue, getConfigValue } from '../src/core/config-store.js';
|
|
8
|
+
import { createChatRuntime } from '../src/core/chat-runtime.js';
|
|
9
|
+
import { createSession, loadSession, listSessions, resolveSession, deleteSession } from '../src/core/session-store.js';
|
|
10
|
+
import { buildDefaultSystemPrompt } from '../src/core/default-system-prompt.js';
|
|
11
|
+
import { RuntimeBridge } from './lib/runtime-bridge.js';
|
|
12
|
+
import { listSkillEntries } from '../src/commands/skill.js';
|
|
13
|
+
import { readSkillRegistry, writeSkillRegistry, upsertSkillRegistryEntry } from '../src/core/skill-registry.js';
|
|
14
|
+
import { getReplyLanguage } from '../src/core/reply-language.js';
|
|
15
|
+
import { createRequire } from 'node:module';
|
|
16
|
+
const require = createRequire(import.meta.url);
|
|
17
|
+
const pkg = require('../package.json');
|
|
18
|
+
import { getSkillsDir, getBaseConfigDir } from '../src/core/paths.js';
|
|
19
|
+
|
|
20
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
const CLIENT_SOURCE_DIR = path.join(__dirname, 'client');
|
|
22
|
+
let CLIENT_DIR = CLIENT_SOURCE_DIR;
|
|
23
|
+
try {
|
|
24
|
+
const distDir = path.join(__dirname, 'dist');
|
|
25
|
+
const stat = await fs.stat(distDir);
|
|
26
|
+
if (stat.isDirectory()) CLIENT_DIR = distDir;
|
|
27
|
+
} catch {}
|
|
28
|
+
|
|
29
|
+
const MIME_TYPES = {
|
|
30
|
+
'.html': 'text/html; charset=utf-8',
|
|
31
|
+
'.css': 'text/css; charset=utf-8',
|
|
32
|
+
'.js': 'text/javascript; charset=utf-8',
|
|
33
|
+
'.json': 'application/json',
|
|
34
|
+
'.svg': 'image/svg+xml',
|
|
35
|
+
'.png': 'image/png',
|
|
36
|
+
'.ico': 'image/x-icon'
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function parseArgs(argv) {
|
|
40
|
+
const parsed = { port: 3210, session: undefined, model: undefined, project: undefined, open: true };
|
|
41
|
+
for (let i = 2; i < argv.length; i++) {
|
|
42
|
+
const arg = argv[i];
|
|
43
|
+
if (arg === '--port' || arg === '-p') { parsed.port = parseInt(argv[++i], 10) || 3210; continue; }
|
|
44
|
+
if (arg === '--session' || arg === '-s') { parsed.session = argv[++i]; continue; }
|
|
45
|
+
if (arg === '--model' || arg === '-m') { parsed.model = argv[++i]; continue; }
|
|
46
|
+
if (arg === '--project' || arg === '-d') { parsed.project = argv[++i]; continue; }
|
|
47
|
+
if (arg === '--no-open') { parsed.open = false; continue; }
|
|
48
|
+
}
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function readBody(req) {
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const chunks = [];
|
|
55
|
+
req.on('data', (c) => chunks.push(c));
|
|
56
|
+
req.on('end', () => {
|
|
57
|
+
try { resolve(JSON.parse(Buffer.concat(chunks).toString())); }
|
|
58
|
+
catch { resolve({}); }
|
|
59
|
+
});
|
|
60
|
+
req.on('error', reject);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function jsonResponse(res, data, status = 200) {
|
|
65
|
+
const body = JSON.stringify(data);
|
|
66
|
+
res.writeHead(status, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) });
|
|
67
|
+
res.end(body);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function buildCodeWikiAskPrompt({ question, reportPath, projectDir, replyLanguage }) {
|
|
71
|
+
if (getReplyLanguage(replyLanguage) === 'en') {
|
|
72
|
+
return [
|
|
73
|
+
'Answer the following question based on the current project and the CodeWiki / project-requirements HTML report.',
|
|
74
|
+
`Project path: ${projectDir}`,
|
|
75
|
+
`Report path: ${reportPath}`,
|
|
76
|
+
'',
|
|
77
|
+
'Requirements:',
|
|
78
|
+
'- Prefer reading and citing the HTML report above.',
|
|
79
|
+
'- If the report is insufficient, use read-only project inspection to gather supporting evidence.',
|
|
80
|
+
'- Do not modify files, generate a new report, or write memory.',
|
|
81
|
+
'- Respond in English unless the user explicitly asks for another language.',
|
|
82
|
+
'',
|
|
83
|
+
`Question: ${question.trim()}`
|
|
84
|
+
].join('\n');
|
|
85
|
+
}
|
|
86
|
+
return [
|
|
87
|
+
'请基于当前项目和 CodeWiki / project-requirements HTML 报告回答下面的问题。',
|
|
88
|
+
`项目路径:${projectDir}`,
|
|
89
|
+
`报告路径:${reportPath}`,
|
|
90
|
+
'',
|
|
91
|
+
'要求:',
|
|
92
|
+
'- 优先读取并参考上述 HTML 报告。',
|
|
93
|
+
'- 如果报告信息不足,可以只读检索项目文件补充证据。',
|
|
94
|
+
'- 不要修改文件,不要生成新报告,不要写入记忆。',
|
|
95
|
+
'- 除非用户明确要求其他语言,否则使用简体中文回答。',
|
|
96
|
+
'',
|
|
97
|
+
`问题:${question.trim()}`
|
|
98
|
+
].join('\n');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function serveStatic(res, filePath) {
|
|
102
|
+
const ext = path.extname(filePath);
|
|
103
|
+
const mime = MIME_TYPES[ext] || 'application/octet-stream';
|
|
104
|
+
try {
|
|
105
|
+
const data = await fs.readFile(filePath);
|
|
106
|
+
res.writeHead(200, { 'Content-Type': mime, 'Content-Length': data.length });
|
|
107
|
+
res.end(data);
|
|
108
|
+
} catch {
|
|
109
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
110
|
+
res.end('Not found');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function normalizeProjectPath(value) {
|
|
115
|
+
const raw = String(value || '').trim();
|
|
116
|
+
if (!raw) return '';
|
|
117
|
+
const win = raw.match(/^([A-Za-z]):[\\/](.*)$/);
|
|
118
|
+
if (win && process.platform !== 'win32') {
|
|
119
|
+
return path.join('/mnt', win[1].toLowerCase(), win[2].replace(/[\\/]+/g, '/'));
|
|
120
|
+
}
|
|
121
|
+
return path.resolve(raw);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function tryParseJson(value) {
|
|
125
|
+
try { return JSON.parse(String(value || '')); } catch { return null; }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function collectSessionPathHints(session) {
|
|
129
|
+
const hints = [];
|
|
130
|
+
const messages = Array.isArray(session?.messages) ? session.messages : [];
|
|
131
|
+
for (const msg of messages) {
|
|
132
|
+
if (Array.isArray(msg?.tool_calls)) {
|
|
133
|
+
for (const call of msg.tool_calls) {
|
|
134
|
+
const args = tryParseJson(call?.function?.arguments ?? call?.arguments);
|
|
135
|
+
for (const key of ['path', 'file', 'filePath', 'cwd']) {
|
|
136
|
+
if (typeof args?.[key] === 'string') hints.push(args[key]);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const content = typeof msg?.content === 'string' ? msg.content : '';
|
|
141
|
+
for (const match of content.matchAll(/[A-Za-z]:[\\/][^\n\r"'`<>|]+/g)) hints.push(match[0]);
|
|
142
|
+
for (const match of content.matchAll(/\/mnt\/[A-Za-z]\/[^\n\r"'`<>|]+/g)) hints.push(match[0]);
|
|
143
|
+
}
|
|
144
|
+
return hints;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function existingDirectoryForHint(rawHint) {
|
|
148
|
+
let candidate = normalizeProjectPath(rawHint);
|
|
149
|
+
if (!candidate) return '';
|
|
150
|
+
candidate = candidate.replace(/[),\].。;;:]+$/g, '');
|
|
151
|
+
for (let i = 0; i < 8 && candidate && candidate !== path.dirname(candidate); i += 1) {
|
|
152
|
+
try {
|
|
153
|
+
const stat = await fs.stat(candidate);
|
|
154
|
+
return stat.isDirectory() ? candidate : path.dirname(candidate);
|
|
155
|
+
} catch {
|
|
156
|
+
candidate = path.dirname(candidate);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return '';
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const CODEWIKI_REPORT_RE = /^[^/\\]+-project-requirements\.html$/;
|
|
163
|
+
|
|
164
|
+
function getRequirementsDir(projectDir) {
|
|
165
|
+
return path.join(projectDir, 'docs', 'requirements');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function isCodeWikiReportFile(fileName) {
|
|
169
|
+
return CODEWIKI_REPORT_RE.test(String(fileName || ''));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function codeWikiReportTitle(fileName) {
|
|
173
|
+
return String(fileName || '')
|
|
174
|
+
.replace(/-project-requirements\.html$/, '')
|
|
175
|
+
.replace(/-/g, ' ');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function commonPathPrefix(paths) {
|
|
179
|
+
const normalized = paths.map((p) => path.resolve(p).split(path.sep).filter(Boolean));
|
|
180
|
+
if (!normalized.length) return '';
|
|
181
|
+
const prefix = [];
|
|
182
|
+
for (let i = 0; i < normalized[0].length; i += 1) {
|
|
183
|
+
const part = normalized[0][i];
|
|
184
|
+
if (normalized.every((parts) => parts[i] === part)) prefix.push(part);
|
|
185
|
+
else break;
|
|
186
|
+
}
|
|
187
|
+
if (!prefix.length) return path.parse(paths[0]).root || '';
|
|
188
|
+
return `${path.sep}${prefix.join(path.sep)}`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function inferSessionProjectDir(session) {
|
|
192
|
+
const explicit = normalizeProjectPath(session?.projectDir);
|
|
193
|
+
if (explicit) {
|
|
194
|
+
try {
|
|
195
|
+
if ((await fs.stat(explicit)).isDirectory()) return explicit;
|
|
196
|
+
} catch {}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const dirs = [];
|
|
200
|
+
for (const hint of collectSessionPathHints(session)) {
|
|
201
|
+
const dir = await existingDirectoryForHint(hint);
|
|
202
|
+
if (dir) dirs.push(dir);
|
|
203
|
+
}
|
|
204
|
+
if (dirs.length === 0) return '';
|
|
205
|
+
|
|
206
|
+
const common = commonPathPrefix(dirs);
|
|
207
|
+
let candidate = common;
|
|
208
|
+
while (candidate && candidate !== path.dirname(candidate)) {
|
|
209
|
+
try {
|
|
210
|
+
const stat = await fs.stat(candidate);
|
|
211
|
+
if (stat.isDirectory()) return candidate;
|
|
212
|
+
} catch {}
|
|
213
|
+
candidate = path.dirname(candidate);
|
|
214
|
+
}
|
|
215
|
+
return dirs[0];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function buildRuntimeForSession({ sessionId, model, projectDir }) {
|
|
219
|
+
const config = await loadConfig();
|
|
220
|
+
const session = sessionId ? await loadSession(sessionId) : await createSession(projectDir || process.cwd());
|
|
221
|
+
const sessionProjectDir = projectDir ? normalizeProjectPath(projectDir) : await inferSessionProjectDir(session);
|
|
222
|
+
if (sessionProjectDir) {
|
|
223
|
+
try {
|
|
224
|
+
const stat = await fs.stat(sessionProjectDir);
|
|
225
|
+
if (stat.isDirectory()) process.chdir(sessionProjectDir);
|
|
226
|
+
} catch {}
|
|
227
|
+
}
|
|
228
|
+
session.projectDir = process.cwd();
|
|
229
|
+
const systemPrompt = buildDefaultSystemPrompt(config);
|
|
230
|
+
const runtime = await createChatRuntime({
|
|
231
|
+
session,
|
|
232
|
+
config,
|
|
233
|
+
model: model || config.model?.name,
|
|
234
|
+
systemPrompt
|
|
235
|
+
});
|
|
236
|
+
return { runtime, config, session, cwd: process.cwd() };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async function main() {
|
|
240
|
+
const args = parseArgs(process.argv);
|
|
241
|
+
|
|
242
|
+
// Set initial project directory
|
|
243
|
+
if (args.project) {
|
|
244
|
+
try {
|
|
245
|
+
const resolved = path.resolve(args.project);
|
|
246
|
+
process.chdir(resolved);
|
|
247
|
+
} catch {}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const { runtime: initialRuntime, config } = await buildRuntimeForSession({
|
|
251
|
+
sessionId: args.session,
|
|
252
|
+
model: args.model
|
|
253
|
+
});
|
|
254
|
+
let bridge = new RuntimeBridge(initialRuntime);
|
|
255
|
+
let currentProjectDir = process.cwd();
|
|
256
|
+
|
|
257
|
+
const server = http.createServer(async (req, res) => {
|
|
258
|
+
const url = new URL(req.url, `http://localhost:${args.port}`);
|
|
259
|
+
|
|
260
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
261
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
262
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
263
|
+
if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; }
|
|
264
|
+
|
|
265
|
+
// SSE
|
|
266
|
+
if (url.pathname === '/api/events' && req.method === 'GET') {
|
|
267
|
+
bridge.addClient(res);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Static files
|
|
272
|
+
if (req.method === 'GET' && !url.pathname.startsWith('/api/')) {
|
|
273
|
+
let filePath;
|
|
274
|
+
if (url.pathname === '/') {
|
|
275
|
+
filePath = path.join(CLIENT_DIR, 'index.html');
|
|
276
|
+
} else {
|
|
277
|
+
const relative = url.pathname.replace(/^\//, '');
|
|
278
|
+
filePath = path.extname(relative)
|
|
279
|
+
? path.join(CLIENT_DIR, relative)
|
|
280
|
+
: path.join(CLIENT_DIR, 'index.html');
|
|
281
|
+
}
|
|
282
|
+
if (!filePath.startsWith(CLIENT_DIR)) { res.writeHead(403); res.end(); return; }
|
|
283
|
+
await serveStatic(res, filePath);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// ── Submit / Abort / Approval ──
|
|
288
|
+
if (req.method === 'POST' && url.pathname === '/api/submit') {
|
|
289
|
+
const { line, readOnlyCodeWiki } = await readBody(req);
|
|
290
|
+
if (!line || typeof line !== 'string') { jsonResponse(res, { error: true, message: 'Missing "line" field' }, 400); return; }
|
|
291
|
+
const result = bridge.handleSubmit(line, { readOnlyCodeWiki: readOnlyCodeWiki === true });
|
|
292
|
+
jsonResponse(res, result);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (req.method === 'POST' && url.pathname === '/api/abort') {
|
|
296
|
+
bridge.handleAbort();
|
|
297
|
+
jsonResponse(res, { ok: true });
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (req.method === 'POST' && url.pathname === '/api/execution-mode') {
|
|
301
|
+
const { mode } = await readBody(req);
|
|
302
|
+
if (!mode || !['normal', 'auto', 'plan'].includes(mode)) {
|
|
303
|
+
jsonResponse(res, { error: true, message: 'Invalid mode' }, 400);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (bridge.isBusy()) {
|
|
307
|
+
jsonResponse(res, { error: true, message: 'Cannot switch execution mode while a request is running' }, 409);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const ok = await bridge.setExecutionMode(mode);
|
|
311
|
+
jsonResponse(res, { ok });
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (req.method === 'POST' && url.pathname === '/api/approval') {
|
|
315
|
+
const { id, approved } = await readBody(req);
|
|
316
|
+
jsonResponse(res, { ok: bridge.handleApproval(id, !!approved) });
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// ── Version ──
|
|
321
|
+
if (req.method === 'GET' && url.pathname === '/api/version') {
|
|
322
|
+
let latest = null;
|
|
323
|
+
try {
|
|
324
|
+
latest = execSync('npm view codemini-cli version', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
325
|
+
} catch {}
|
|
326
|
+
jsonResponse(res, { current: pkg.version, latest });
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (req.method === 'POST' && url.pathname === '/api/update') {
|
|
330
|
+
try {
|
|
331
|
+
const output = execSync('npm update -g codemini-cli', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 60000 });
|
|
332
|
+
jsonResponse(res, { ok: true, output: output.trim() });
|
|
333
|
+
} catch (err) {
|
|
334
|
+
jsonResponse(res, { ok: false, error: err.message }, 500);
|
|
335
|
+
}
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// ── Runtime state ──
|
|
340
|
+
if (req.method === 'GET' && url.pathname === '/api/state') {
|
|
341
|
+
jsonResponse(res, { ...bridge.getState(), cwd: currentProjectDir });
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (req.method === 'GET' && url.pathname === '/api/completions') {
|
|
345
|
+
jsonResponse(res, bridge.getCompletions(url.searchParams.get('q') || ''));
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (req.method === 'GET' && url.pathname === '/api/history') {
|
|
349
|
+
jsonResponse(res, bridge.getHistory());
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (req.method === 'GET' && url.pathname === '/api/commands') {
|
|
353
|
+
jsonResponse(res, bridge.getCommands());
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (req.method === 'GET' && url.pathname === '/api/startup-events') {
|
|
357
|
+
jsonResponse(res, await bridge.handleStartupEvents());
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (req.method === 'GET' && url.pathname === '/api/session/messages') {
|
|
361
|
+
jsonResponse(res, { messages: bridge.getSessionMessages(), compact: bridge.getSessionCompactMeta() });
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (req.method === 'GET' && url.pathname === '/api/session/ui-messages') {
|
|
365
|
+
jsonResponse(res, await bridge.getUiMessages());
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// ── CodeWiki / project requirements reports ──
|
|
370
|
+
if (req.method === 'GET' && url.pathname === '/api/codewiki/reports') {
|
|
371
|
+
const requirementsDir = getRequirementsDir(currentProjectDir);
|
|
372
|
+
try {
|
|
373
|
+
const entries = await fs.readdir(requirementsDir, { withFileTypes: true });
|
|
374
|
+
const reports = [];
|
|
375
|
+
for (const entry of entries) {
|
|
376
|
+
if (!entry.isFile() || !isCodeWikiReportFile(entry.name)) continue;
|
|
377
|
+
const reportPath = path.join(requirementsDir, entry.name);
|
|
378
|
+
const stat = await fs.stat(reportPath);
|
|
379
|
+
reports.push({
|
|
380
|
+
file: entry.name,
|
|
381
|
+
title: codeWikiReportTitle(entry.name),
|
|
382
|
+
size: stat.size,
|
|
383
|
+
mtime: stat.mtime.toISOString()
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
reports.sort((a, b) => new Date(b.mtime) - new Date(a.mtime));
|
|
387
|
+
jsonResponse(res, { reports });
|
|
388
|
+
} catch (err) {
|
|
389
|
+
if (err?.code === 'ENOENT') jsonResponse(res, { reports: [] });
|
|
390
|
+
else jsonResponse(res, { error: true, message: err.message }, 500);
|
|
391
|
+
}
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (req.method === 'GET' && url.pathname.startsWith('/api/codewiki/report/')) {
|
|
396
|
+
const fileName = decodeURIComponent(url.pathname.slice('/api/codewiki/report/'.length));
|
|
397
|
+
if (!isCodeWikiReportFile(fileName)) {
|
|
398
|
+
jsonResponse(res, { error: true, message: 'Invalid report file' }, 400);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
const requirementsDir = path.resolve(getRequirementsDir(currentProjectDir));
|
|
402
|
+
const reportPath = path.resolve(requirementsDir, fileName);
|
|
403
|
+
if (!reportPath.startsWith(`${requirementsDir}${path.sep}`)) {
|
|
404
|
+
jsonResponse(res, { error: true, message: 'Invalid report path' }, 403);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
await serveStatic(res, reportPath);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (req.method === 'DELETE' && url.pathname.startsWith('/api/codewiki/report/')) {
|
|
412
|
+
const fileName = decodeURIComponent(url.pathname.slice('/api/codewiki/report/'.length));
|
|
413
|
+
if (!isCodeWikiReportFile(fileName)) {
|
|
414
|
+
jsonResponse(res, { error: true, message: 'Invalid report file' }, 400);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
const requirementsDir = path.resolve(getRequirementsDir(currentProjectDir));
|
|
418
|
+
const reportPath = path.resolve(requirementsDir, fileName);
|
|
419
|
+
if (!reportPath.startsWith(`${requirementsDir}${path.sep}`)) {
|
|
420
|
+
jsonResponse(res, { error: true, message: 'Invalid report path' }, 403);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
try {
|
|
424
|
+
await fs.unlink(reportPath);
|
|
425
|
+
jsonResponse(res, { ok: true, file: fileName });
|
|
426
|
+
} catch (err) {
|
|
427
|
+
if (err?.code === 'ENOENT') jsonResponse(res, { error: true, message: 'Report not found' }, 404);
|
|
428
|
+
else jsonResponse(res, { error: true, message: err.message }, 500);
|
|
429
|
+
}
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (req.method === 'POST' && url.pathname === '/api/codewiki/generate') {
|
|
434
|
+
if (bridge.isBusy()) {
|
|
435
|
+
jsonResponse(res, { error: true, message: 'Runtime is busy' }, 409);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
const { depth } = await readBody(req);
|
|
439
|
+
const normalizedDepth = ['fast', 'standard', 'deep'].includes(String(depth || '').toLowerCase())
|
|
440
|
+
? String(depth).toLowerCase()
|
|
441
|
+
: 'standard';
|
|
442
|
+
const result = bridge.handleSubmit(`/project-requirements --${normalizedDepth}`);
|
|
443
|
+
jsonResponse(res, result);
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (req.method === 'POST' && url.pathname === '/api/codewiki/ask') {
|
|
448
|
+
const { question, reportFile } = await readBody(req);
|
|
449
|
+
if (!question || typeof question !== 'string') {
|
|
450
|
+
jsonResponse(res, { error: true, message: 'Missing "question" field' }, 400);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
const selectedReport = isCodeWikiReportFile(reportFile) ? reportFile : '';
|
|
454
|
+
if (bridge.isBusy()) {
|
|
455
|
+
jsonResponse(res, { error: true, message: 'Runtime is busy' }, 409);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
const reportPath = selectedReport
|
|
459
|
+
? path.join(getRequirementsDir(currentProjectDir), selectedReport)
|
|
460
|
+
: getRequirementsDir(currentProjectDir);
|
|
461
|
+
const prompt = buildCodeWikiAskPrompt({
|
|
462
|
+
question,
|
|
463
|
+
reportPath,
|
|
464
|
+
projectDir: currentProjectDir,
|
|
465
|
+
replyLanguage: bridge.getState()?.replyLanguage
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
res.writeHead(200, {
|
|
469
|
+
'Content-Type': 'application/x-ndjson; charset=utf-8',
|
|
470
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
471
|
+
'X-Accel-Buffering': 'no'
|
|
472
|
+
});
|
|
473
|
+
const writeEvent = (event) => {
|
|
474
|
+
try {
|
|
475
|
+
res.write(`${JSON.stringify(event)}\n`);
|
|
476
|
+
} catch {}
|
|
477
|
+
};
|
|
478
|
+
await bridge.handleCodeWikiAsk(prompt, writeEvent);
|
|
479
|
+
res.end();
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// ── Session management ──
|
|
484
|
+
if (req.method === 'GET' && url.pathname === '/api/sessions') {
|
|
485
|
+
const sessions = await listSessions(1000);
|
|
486
|
+
jsonResponse(res, sessions);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
if (req.method === 'POST' && url.pathname === '/api/sessions/new') {
|
|
490
|
+
try {
|
|
491
|
+
const currentMessages = bridge.getSessionMessages();
|
|
492
|
+
if (!Array.isArray(currentMessages) || currentMessages.length === 0) {
|
|
493
|
+
jsonResponse(res, {
|
|
494
|
+
ok: true,
|
|
495
|
+
reused: true,
|
|
496
|
+
sessionId: bridge.getSessionId(),
|
|
497
|
+
cwd: currentProjectDir
|
|
498
|
+
});
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
const { runtime: newRuntime, session } = await buildRuntimeForSession({
|
|
502
|
+
model: bridge.getState().model
|
|
503
|
+
});
|
|
504
|
+
await bridge.switchRuntime(newRuntime);
|
|
505
|
+
currentProjectDir = process.cwd();
|
|
506
|
+
jsonResponse(res, { ok: true, sessionId: session.id, cwd: currentProjectDir });
|
|
507
|
+
} catch (err) {
|
|
508
|
+
jsonResponse(res, { error: true, message: err.message }, 500);
|
|
509
|
+
}
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
if (req.method === 'POST' && url.pathname === '/api/sessions/switch') {
|
|
513
|
+
const { sessionId } = await readBody(req);
|
|
514
|
+
if (!sessionId) { jsonResponse(res, { error: true, message: 'Missing sessionId' }, 400); return; }
|
|
515
|
+
try {
|
|
516
|
+
const { runtime: newRuntime } = await buildRuntimeForSession({
|
|
517
|
+
sessionId,
|
|
518
|
+
model: bridge.getState().model
|
|
519
|
+
});
|
|
520
|
+
await bridge.switchRuntime(newRuntime);
|
|
521
|
+
currentProjectDir = process.cwd();
|
|
522
|
+
jsonResponse(res, { ok: true, sessionId, cwd: currentProjectDir });
|
|
523
|
+
} catch (err) {
|
|
524
|
+
jsonResponse(res, { error: true, message: err.message }, 500);
|
|
525
|
+
}
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (req.method === 'DELETE' && url.pathname.startsWith('/api/sessions/')) {
|
|
530
|
+
const sessionId = decodeURIComponent(url.pathname.slice('/api/sessions/'.length));
|
|
531
|
+
if (!sessionId) { jsonResponse(res, { error: true, message: 'Missing sessionId' }, 400); return; }
|
|
532
|
+
const deletingCurrent = sessionId === bridge.getSessionId();
|
|
533
|
+
if (deletingCurrent && bridge.isBusy()) {
|
|
534
|
+
jsonResponse(res, { error: true, message: 'Current session is busy' }, 409);
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
try {
|
|
538
|
+
const result = await deleteSession(sessionId);
|
|
539
|
+
let nextSessionId = bridge.getSessionId();
|
|
540
|
+
let cwd = currentProjectDir;
|
|
541
|
+
if (deletingCurrent) {
|
|
542
|
+
const remaining = await listSessions(1000);
|
|
543
|
+
const next = remaining.find((session) => session.id !== sessionId);
|
|
544
|
+
const built = next
|
|
545
|
+
? await buildRuntimeForSession({ sessionId: next.id, model: bridge.getState().model })
|
|
546
|
+
: await buildRuntimeForSession({ model: bridge.getState().model });
|
|
547
|
+
await bridge.switchRuntime(built.runtime);
|
|
548
|
+
currentProjectDir = process.cwd();
|
|
549
|
+
nextSessionId = built.session.id;
|
|
550
|
+
cwd = currentProjectDir;
|
|
551
|
+
}
|
|
552
|
+
jsonResponse(res, { ok: true, removed: result.removed, sessionId: nextSessionId, cwd });
|
|
553
|
+
} catch (err) {
|
|
554
|
+
jsonResponse(res, { error: true, message: err.message }, 500);
|
|
555
|
+
}
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// ── Project management ──
|
|
560
|
+
if (req.method === 'GET' && url.pathname === '/api/project') {
|
|
561
|
+
jsonResponse(res, { cwd: currentProjectDir });
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
if (req.method === 'GET' && url.pathname === '/api/git') {
|
|
565
|
+
try {
|
|
566
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD', { cwd: currentProjectDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
567
|
+
const porcelain = execSync('git status --porcelain', { cwd: currentProjectDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
568
|
+
const lines = porcelain ? porcelain.split('\n') : [];
|
|
569
|
+
let staged = 0, modified = 0, untracked = 0;
|
|
570
|
+
for (const line of lines) {
|
|
571
|
+
const x = line[0], y = line[1];
|
|
572
|
+
if (x === '?' && y === '?') { untracked++; continue; }
|
|
573
|
+
if (x !== ' ' && x !== '?') staged++;
|
|
574
|
+
if (y === 'M' || y === 'D') modified++;
|
|
575
|
+
}
|
|
576
|
+
jsonResponse(res, { isGit: true, branch, dirty: lines.length > 0, staged, modified, untracked });
|
|
577
|
+
} catch {
|
|
578
|
+
jsonResponse(res, { isGit: false, branch: null, dirty: false, staged: 0, modified: 0, untracked: 0 });
|
|
579
|
+
}
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
if (req.method === 'GET' && url.pathname === '/api/git-diff') {
|
|
583
|
+
try {
|
|
584
|
+
let patch;
|
|
585
|
+
try {
|
|
586
|
+
patch = execSync('git diff HEAD --no-color', { cwd: currentProjectDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
587
|
+
} catch {
|
|
588
|
+
patch = execSync('git diff --cached --no-color', { cwd: currentProjectDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
589
|
+
}
|
|
590
|
+
const patchFiles = [];
|
|
591
|
+
const seenPatchFiles = new Set();
|
|
592
|
+
for (const line of patch.split('\n')) {
|
|
593
|
+
const match = line.match(/^diff --git a\/(.+) b\/(.+)$/);
|
|
594
|
+
if (!match) continue;
|
|
595
|
+
const filePath = match[2] || match[1];
|
|
596
|
+
if (!filePath || seenPatchFiles.has(filePath)) continue;
|
|
597
|
+
seenPatchFiles.add(filePath);
|
|
598
|
+
patchFiles.push(filePath);
|
|
599
|
+
}
|
|
600
|
+
const porcelain = execSync('git status --porcelain', { cwd: currentProjectDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
601
|
+
const statusByPath = new Map();
|
|
602
|
+
if (porcelain) {
|
|
603
|
+
for (const line of porcelain.split('\n')) {
|
|
604
|
+
const x = line[0], y = line[1], filePath = line.slice(3);
|
|
605
|
+
let status;
|
|
606
|
+
if (x === '?' && y === '?') status = '?';
|
|
607
|
+
else if (x === 'A' || y === 'A') status = 'A';
|
|
608
|
+
else if (x === 'D' || y === 'D') status = 'D';
|
|
609
|
+
else status = 'M';
|
|
610
|
+
const staged = (x !== ' ' && x !== '?');
|
|
611
|
+
statusByPath.set(filePath, { path: filePath, status, staged });
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
const files = patchFiles.map(filePath => statusByPath.get(filePath) || { path: filePath, status: 'M', staged: false });
|
|
615
|
+
jsonResponse(res, { patch, files });
|
|
616
|
+
} catch {
|
|
617
|
+
jsonResponse(res, { patch: '', files: [] });
|
|
618
|
+
}
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
if (req.method === 'POST' && url.pathname === '/api/git-batch') {
|
|
622
|
+
const { dirs } = await readBody(req);
|
|
623
|
+
const result = {};
|
|
624
|
+
for (const dir of (Array.isArray(dirs) ? dirs : [])) {
|
|
625
|
+
try {
|
|
626
|
+
const resolved = path.resolve(dir);
|
|
627
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD', { cwd: resolved, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
628
|
+
result[dir] = { isGit: true, branch };
|
|
629
|
+
} catch {
|
|
630
|
+
result[dir] = { isGit: false, branch: null };
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
jsonResponse(res, result);
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
if (req.method === 'POST' && url.pathname === '/api/project/open') {
|
|
637
|
+
const { path: projectPath } = await readBody(req);
|
|
638
|
+
if (!projectPath) { jsonResponse(res, { error: true, message: 'Missing path' }, 400); return; }
|
|
639
|
+
try {
|
|
640
|
+
const resolved = path.resolve(projectPath);
|
|
641
|
+
const stat = await fs.stat(resolved);
|
|
642
|
+
if (!stat.isDirectory()) throw new Error('Not a directory');
|
|
643
|
+
process.chdir(resolved);
|
|
644
|
+
currentProjectDir = process.cwd();
|
|
645
|
+
// Re-init runtime in new project
|
|
646
|
+
const { runtime: newRuntime, session } = await buildRuntimeForSession({
|
|
647
|
+
model: bridge.getState().model
|
|
648
|
+
});
|
|
649
|
+
await bridge.switchRuntime(newRuntime);
|
|
650
|
+
jsonResponse(res, { ok: true, cwd: currentProjectDir, sessionId: session.id });
|
|
651
|
+
} catch (err) {
|
|
652
|
+
jsonResponse(res, { error: true, message: err.message }, 400);
|
|
653
|
+
}
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
if (req.method === 'POST' && url.pathname === '/api/project/browse') {
|
|
657
|
+
const { dir } = await readBody(req);
|
|
658
|
+
const base = dir ? path.resolve(dir) : path.resolve('/');
|
|
659
|
+
try {
|
|
660
|
+
const entries = await fs.readdir(base, { withFileTypes: true });
|
|
661
|
+
const dirs = entries
|
|
662
|
+
.filter(e => e.isDirectory() && !e.name.startsWith('.'))
|
|
663
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
664
|
+
.map(e => ({
|
|
665
|
+
name: e.name,
|
|
666
|
+
path: path.join(base, e.name),
|
|
667
|
+
isGit: false
|
|
668
|
+
}));
|
|
669
|
+
// Check for .git directories asynchronously
|
|
670
|
+
await Promise.all(dirs.map(async (d) => {
|
|
671
|
+
try { await fs.access(path.join(d.path, '.git')); d.isGit = true; } catch {}
|
|
672
|
+
}));
|
|
673
|
+
jsonResponse(res, { path: base, dirs });
|
|
674
|
+
} catch (err) {
|
|
675
|
+
jsonResponse(res, { path: base, dirs: [], error: err.message });
|
|
676
|
+
}
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// ── Config management ──
|
|
681
|
+
if (req.method === 'GET' && url.pathname === '/api/config') {
|
|
682
|
+
const config = await loadConfig();
|
|
683
|
+
jsonResponse(res, config);
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
if (req.method === 'POST' && url.pathname === '/api/config/set') {
|
|
687
|
+
const { key, value } = await readBody(req);
|
|
688
|
+
if (!key) { jsonResponse(res, { error: true, message: 'Missing key' }, 400); return; }
|
|
689
|
+
try {
|
|
690
|
+
await setConfigValue(key, value);
|
|
691
|
+
const config = await loadConfig();
|
|
692
|
+
jsonResponse(res, { ok: true, config });
|
|
693
|
+
} catch (err) {
|
|
694
|
+
jsonResponse(res, { error: true, message: err.message }, 500);
|
|
695
|
+
}
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
if (req.method === 'GET' && url.pathname.startsWith('/api/config/get/')) {
|
|
699
|
+
const key = url.pathname.slice('/api/config/get/'.length);
|
|
700
|
+
const value = await getConfigValue(key);
|
|
701
|
+
jsonResponse(res, { key, value });
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// ── Skills management ──
|
|
706
|
+
if (req.method === 'GET' && url.pathname === '/api/skills') {
|
|
707
|
+
try {
|
|
708
|
+
const skills = await listSkillEntries({ scope: 'all' });
|
|
709
|
+
jsonResponse(res, skills);
|
|
710
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
if (req.method === 'GET' && url.pathname.startsWith('/api/skills/') && url.pathname.endsWith('/content')) {
|
|
714
|
+
const name = decodeURIComponent(url.pathname.slice('/api/skills/'.length, -'/content'.length));
|
|
715
|
+
try {
|
|
716
|
+
const entries = await listSkillEntries({ scope: 'all' });
|
|
717
|
+
const skill = entries.find(s => s.name === name);
|
|
718
|
+
if (!skill) { jsonResponse(res, { error: true, message: 'Skill not found' }, 404); return; }
|
|
719
|
+
const content = await fs.readFile(skill.path, 'utf8');
|
|
720
|
+
jsonResponse(res, { name: skill.name, content, scope: skill.scope });
|
|
721
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
if (req.method === 'POST' && url.pathname === '/api/skills/create') {
|
|
725
|
+
const { name, description, content } = await readBody(req);
|
|
726
|
+
if (!name || !content) { jsonResponse(res, { error: true, message: 'Missing name or content' }, 400); return; }
|
|
727
|
+
try {
|
|
728
|
+
const skillDir = path.join(getSkillsDir(), name);
|
|
729
|
+
await fs.mkdir(skillDir, { recursive: true });
|
|
730
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
731
|
+
await fs.writeFile(skillFile, content, 'utf8');
|
|
732
|
+
const { createHash } = await import('node:crypto');
|
|
733
|
+
const hash = createHash('sha256').update(content).digest('hex');
|
|
734
|
+
await upsertSkillRegistryEntry(undefined, {
|
|
735
|
+
name, version: '0.1.0', description: description || '', enabled: true,
|
|
736
|
+
source: 'web-ui', entryFile: 'SKILL.md', sha256: hash, installedAt: new Date().toISOString()
|
|
737
|
+
});
|
|
738
|
+
const config = await loadConfig();
|
|
739
|
+
config.skills = config.skills || {};
|
|
740
|
+
config.skills.enabled = config.skills.enabled || {};
|
|
741
|
+
config.skills.enabled[name] = true;
|
|
742
|
+
await saveConfig(config);
|
|
743
|
+
jsonResponse(res, { ok: true, name });
|
|
744
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
if (req.method === 'PUT' && url.pathname.startsWith('/api/skills/') && url.pathname.endsWith('/content')) {
|
|
748
|
+
const name = decodeURIComponent(url.pathname.slice('/api/skills/'.length, -'/content'.length));
|
|
749
|
+
const { content } = await readBody(req);
|
|
750
|
+
if (!content) { jsonResponse(res, { error: true, message: 'Missing content' }, 400); return; }
|
|
751
|
+
try {
|
|
752
|
+
const entries = await listSkillEntries({ scope: 'all' });
|
|
753
|
+
const skill = entries.find(s => s.name === name);
|
|
754
|
+
if (!skill) { jsonResponse(res, { error: true, message: 'Skill not found' }, 404); return; }
|
|
755
|
+
if (skill.scope === 'builtin') { jsonResponse(res, { error: true, message: 'Cannot edit builtin skill' }, 403); return; }
|
|
756
|
+
await fs.writeFile(skill.path, content, 'utf8');
|
|
757
|
+
jsonResponse(res, { ok: true });
|
|
758
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
if (req.method === 'DELETE' && url.pathname.startsWith('/api/skills/')) {
|
|
762
|
+
const name = decodeURIComponent(url.pathname.slice('/api/skills/'.length));
|
|
763
|
+
try {
|
|
764
|
+
const entries = await listSkillEntries({ scope: 'all' });
|
|
765
|
+
const skill = entries.find(s => s.name === name);
|
|
766
|
+
if (!skill) { jsonResponse(res, { error: true, message: 'Skill not found' }, 404); return; }
|
|
767
|
+
if (skill.scope === 'builtin') { jsonResponse(res, { error: true, message: 'Cannot delete builtin skill' }, 403); return; }
|
|
768
|
+
const dir = path.dirname(skill.path);
|
|
769
|
+
await fs.rm(dir, { recursive: true, force: true });
|
|
770
|
+
const registry = await readSkillRegistry();
|
|
771
|
+
registry.skills = (registry.skills || []).filter(s => s.name !== name);
|
|
772
|
+
await writeSkillRegistry(undefined, registry);
|
|
773
|
+
const config = await loadConfig();
|
|
774
|
+
if (config.skills?.enabled) delete config.skills.enabled[name];
|
|
775
|
+
await saveConfig(config);
|
|
776
|
+
jsonResponse(res, { ok: true });
|
|
777
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
if (req.method === 'POST' && url.pathname.startsWith('/api/skills/') && url.pathname.endsWith('/toggle')) {
|
|
781
|
+
const name = decodeURIComponent(url.pathname.slice('/api/skills/'.length, -'/toggle'.length));
|
|
782
|
+
const { enabled } = await readBody(req);
|
|
783
|
+
try {
|
|
784
|
+
const entries = await listSkillEntries({ scope: 'all' });
|
|
785
|
+
const skill = entries.find(s => s.name === name);
|
|
786
|
+
if (!skill) { jsonResponse(res, { error: true, message: 'Skill not found' }, 404); return; }
|
|
787
|
+
if (skill.scope === 'builtin') { jsonResponse(res, { error: true, message: 'Cannot toggle builtin skill' }, 403); return; }
|
|
788
|
+
const config = await loadConfig();
|
|
789
|
+
config.skills = config.skills || {};
|
|
790
|
+
config.skills.enabled = config.skills.enabled || {};
|
|
791
|
+
config.skills.enabled[name] = !!enabled;
|
|
792
|
+
await saveConfig(config);
|
|
793
|
+
const registry = await readSkillRegistry();
|
|
794
|
+
const idx = registry.skills.findIndex(s => s.name === name);
|
|
795
|
+
if (idx !== -1) { registry.skills[idx].enabled = !!enabled; await writeSkillRegistry(undefined, registry); }
|
|
796
|
+
jsonResponse(res, { ok: true });
|
|
797
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// ── Souls management ──
|
|
802
|
+
const _BUNDLED_SOULS_DIR = path.resolve(__dirname, '..', 'souls');
|
|
803
|
+
const _CUSTOM_SOULS_DIR = path.join(getBaseConfigDir(), 'souls');
|
|
804
|
+
|
|
805
|
+
if (req.method === 'GET' && url.pathname === '/api/souls') {
|
|
806
|
+
try {
|
|
807
|
+
const config = await loadConfig();
|
|
808
|
+
const activePreset = config?.soul?.preset || 'default';
|
|
809
|
+
const souls = [];
|
|
810
|
+
const bundledEntries = await fs.readdir(_BUNDLED_SOULS_DIR);
|
|
811
|
+
for (const file of bundledEntries) {
|
|
812
|
+
if (!file.endsWith('.md')) continue;
|
|
813
|
+
const sname = file.slice(0, -3);
|
|
814
|
+
const scontent = await fs.readFile(path.join(_BUNDLED_SOULS_DIR, file), 'utf8');
|
|
815
|
+
souls.push({ name: sname, scope: 'builtin', preview: scontent.split('\n').slice(0, 3).join('\n').slice(0, 120), active: sname === activePreset });
|
|
816
|
+
}
|
|
817
|
+
try {
|
|
818
|
+
const customEntries = await fs.readdir(_CUSTOM_SOULS_DIR);
|
|
819
|
+
for (const file of customEntries) {
|
|
820
|
+
if (!file.endsWith('.md')) continue;
|
|
821
|
+
const sname = file.slice(0, -3);
|
|
822
|
+
const scontent = await fs.readFile(path.join(_CUSTOM_SOULS_DIR, file), 'utf8');
|
|
823
|
+
souls.push({ name: sname, scope: 'custom', preview: scontent.split('\n').slice(0, 3).join('\n').slice(0, 120), active: sname === activePreset });
|
|
824
|
+
}
|
|
825
|
+
} catch {}
|
|
826
|
+
jsonResponse(res, souls);
|
|
827
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
if (req.method === 'GET' && url.pathname.startsWith('/api/souls/') && url.pathname.endsWith('/content')) {
|
|
831
|
+
const sname = decodeURIComponent(url.pathname.slice('/api/souls/'.length, -'/content'.length));
|
|
832
|
+
try {
|
|
833
|
+
const customPath = path.join(_CUSTOM_SOULS_DIR, `${sname}.md`);
|
|
834
|
+
try { const scontent = await fs.readFile(customPath, 'utf8'); jsonResponse(res, { name: sname, content: scontent, scope: 'custom' }); return; } catch {}
|
|
835
|
+
const bundledPath = path.join(_BUNDLED_SOULS_DIR, `${sname}.md`);
|
|
836
|
+
const scontent = await fs.readFile(bundledPath, 'utf8');
|
|
837
|
+
jsonResponse(res, { name: sname, content: scontent, scope: 'builtin' });
|
|
838
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
if (req.method === 'POST' && url.pathname === '/api/souls/create') {
|
|
842
|
+
const { name: rawName, content: soulContent } = await readBody(req);
|
|
843
|
+
if (!rawName || !soulContent) { jsonResponse(res, { error: true, message: 'Missing name or content' }, 400); return; }
|
|
844
|
+
try {
|
|
845
|
+
const safeName = String(rawName).replace(/[^a-zA-Z0-9_-]/g, '');
|
|
846
|
+
if (!safeName) { jsonResponse(res, { error: true, message: 'Invalid name' }, 400); return; }
|
|
847
|
+
const bundledCheck = path.join(_BUNDLED_SOULS_DIR, `${safeName}.md`);
|
|
848
|
+
try { await fs.access(bundledCheck); jsonResponse(res, { error: true, message: 'Name conflicts with builtin soul' }, 409); return; } catch {}
|
|
849
|
+
await fs.mkdir(_CUSTOM_SOULS_DIR, { recursive: true });
|
|
850
|
+
await fs.writeFile(path.join(_CUSTOM_SOULS_DIR, `${safeName}.md`), soulContent, 'utf8');
|
|
851
|
+
jsonResponse(res, { ok: true, name: safeName });
|
|
852
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
if (req.method === 'PUT' && url.pathname.startsWith('/api/souls/') && url.pathname.endsWith('/content')) {
|
|
856
|
+
const sname = decodeURIComponent(url.pathname.slice('/api/souls/'.length, -'/content'.length));
|
|
857
|
+
const { content: soulContent } = await readBody(req);
|
|
858
|
+
if (!soulContent) { jsonResponse(res, { error: true, message: 'Missing content' }, 400); return; }
|
|
859
|
+
try {
|
|
860
|
+
const customPath = path.join(_CUSTOM_SOULS_DIR, `${sname}.md`);
|
|
861
|
+
try { await fs.access(customPath); } catch { jsonResponse(res, { error: true, message: 'Custom soul not found' }, 404); return; }
|
|
862
|
+
await fs.writeFile(customPath, soulContent, 'utf8');
|
|
863
|
+
jsonResponse(res, { ok: true });
|
|
864
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
if (req.method === 'DELETE' && url.pathname.startsWith('/api/souls/')) {
|
|
868
|
+
const sname = decodeURIComponent(url.pathname.slice('/api/souls/'.length));
|
|
869
|
+
try {
|
|
870
|
+
const bundledPath = path.join(_BUNDLED_SOULS_DIR, `${sname}.md`);
|
|
871
|
+
try { await fs.access(bundledPath); jsonResponse(res, { error: true, message: 'Cannot delete builtin soul' }, 403); return; } catch {}
|
|
872
|
+
const customPath = path.join(_CUSTOM_SOULS_DIR, `${sname}.md`);
|
|
873
|
+
await fs.unlink(customPath);
|
|
874
|
+
const config = await loadConfig();
|
|
875
|
+
if (config.soul?.preset === sname) { config.soul.preset = 'default'; await saveConfig(config); }
|
|
876
|
+
jsonResponse(res, { ok: true });
|
|
877
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
if (req.method === 'POST' && url.pathname === '/api/souls/activate') {
|
|
881
|
+
const { name: sname } = await readBody(req);
|
|
882
|
+
if (!sname) { jsonResponse(res, { error: true, message: 'Missing name' }, 400); return; }
|
|
883
|
+
try {
|
|
884
|
+
const config = await loadConfig();
|
|
885
|
+
config.soul = config.soul || {};
|
|
886
|
+
config.soul.preset = sname;
|
|
887
|
+
config.soul.custom_path = '';
|
|
888
|
+
await saveConfig(config);
|
|
889
|
+
jsonResponse(res, { ok: true });
|
|
890
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
895
|
+
res.end('Not found');
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
server.listen(args.port, () => {
|
|
899
|
+
console.log(`\n Codemini Web UI\n http://localhost:${args.port}\n Project: ${currentProjectDir}\n`);
|
|
900
|
+
if (!args.open) return;
|
|
901
|
+
const openCmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
902
|
+
import('node:child_process').then(({ exec }) => {
|
|
903
|
+
exec(`${openCmd} http://localhost:${args.port}`, (err) => { if (err) console.log(' Could not auto-open browser.'); });
|
|
904
|
+
});
|
|
905
|
+
});
|
|
906
|
+
|
|
907
|
+
const cleanup = async () => {
|
|
908
|
+
await bridge.dispose();
|
|
909
|
+
server.close();
|
|
910
|
+
process.exit(0);
|
|
911
|
+
};
|
|
912
|
+
process.on('SIGINT', cleanup);
|
|
913
|
+
process.on('SIGTERM', cleanup);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
main().catch((err) => {
|
|
917
|
+
console.error('Failed to start:', err);
|
|
918
|
+
process.exit(1);
|
|
919
|
+
});
|