grepmind-app 0.1.0-alpha
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 +190 -0
- package/dist/context.d.ts +43 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +230 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +120 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/secrets.d.ts +21 -0
- package/dist/middleware/secrets.d.ts.map +1 -0
- package/dist/middleware/secrets.js +38 -0
- package/dist/middleware/secrets.js.map +1 -0
- package/dist/routes/code.d.ts +61 -0
- package/dist/routes/code.d.ts.map +1 -0
- package/dist/routes/code.js +974 -0
- package/dist/routes/code.js.map +1 -0
- package/dist/routes/code.test.d.ts +7 -0
- package/dist/routes/code.test.d.ts.map +1 -0
- package/dist/routes/code.test.js +418 -0
- package/dist/routes/code.test.js.map +1 -0
- package/dist/routes/events.d.ts +30 -0
- package/dist/routes/events.d.ts.map +1 -0
- package/dist/routes/events.js +152 -0
- package/dist/routes/events.js.map +1 -0
- package/dist/routes/git.d.ts +47 -0
- package/dist/routes/git.d.ts.map +1 -0
- package/dist/routes/git.js +246 -0
- package/dist/routes/git.js.map +1 -0
- package/dist/routes/index.d.ts +6 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +6 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/notes.d.ts +38 -0
- package/dist/routes/notes.d.ts.map +1 -0
- package/dist/routes/notes.js +829 -0
- package/dist/routes/notes.js.map +1 -0
- package/dist/routes/project.d.ts +35 -0
- package/dist/routes/project.d.ts.map +1 -0
- package/dist/routes/project.js +675 -0
- package/dist/routes/project.js.map +1 -0
- package/dist/routes/sync-handler.d.ts +46 -0
- package/dist/routes/sync-handler.d.ts.map +1 -0
- package/dist/routes/sync-handler.js +178 -0
- package/dist/routes/sync-handler.js.map +1 -0
- package/dist/routes/sync.d.ts +31 -0
- package/dist/routes/sync.d.ts.map +1 -0
- package/dist/routes/sync.js +329 -0
- package/dist/routes/sync.js.map +1 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +93 -0
- package/dist/server.js.map +1 -0
- package/dist/tesst.d.ts +2 -0
- package/dist/tesst.d.ts.map +1 -0
- package/dist/tesst.js +2 -0
- package/dist/tesst.js.map +1 -0
- package/dist/web/assets/apl-B4CMkyY2.js +2 -0
- package/dist/web/assets/apl-B4CMkyY2.js.map +1 -0
- package/dist/web/assets/asciiarmor-Df11BRmG.js +2 -0
- package/dist/web/assets/asciiarmor-Df11BRmG.js.map +1 -0
- package/dist/web/assets/asn1-EdZsLKOL.js +2 -0
- package/dist/web/assets/asn1-EdZsLKOL.js.map +1 -0
- package/dist/web/assets/asterisk-B-8jnY81.js +2 -0
- package/dist/web/assets/asterisk-B-8jnY81.js.map +1 -0
- package/dist/web/assets/brainfuck-C4LP7Hcl.js +2 -0
- package/dist/web/assets/brainfuck-C4LP7Hcl.js.map +1 -0
- package/dist/web/assets/clike-B9uivgTg.js +2 -0
- package/dist/web/assets/clike-B9uivgTg.js.map +1 -0
- package/dist/web/assets/clojure-BMjYHr_A.js +2 -0
- package/dist/web/assets/clojure-BMjYHr_A.js.map +1 -0
- package/dist/web/assets/cmake-BQqOBYOt.js +2 -0
- package/dist/web/assets/cmake-BQqOBYOt.js.map +1 -0
- package/dist/web/assets/cobol-CWcv1MsR.js +2 -0
- package/dist/web/assets/cobol-CWcv1MsR.js.map +1 -0
- package/dist/web/assets/coffeescript-S37ZYGWr.js +2 -0
- package/dist/web/assets/coffeescript-S37ZYGWr.js.map +1 -0
- package/dist/web/assets/commonlisp-DBKNyK5s.js +2 -0
- package/dist/web/assets/commonlisp-DBKNyK5s.js.map +1 -0
- package/dist/web/assets/crystal-SjHAIU92.js +2 -0
- package/dist/web/assets/crystal-SjHAIU92.js.map +1 -0
- package/dist/web/assets/css-BnMrqG3P.js +2 -0
- package/dist/web/assets/css-BnMrqG3P.js.map +1 -0
- package/dist/web/assets/cypher-C_CwsFkJ.js +2 -0
- package/dist/web/assets/cypher-C_CwsFkJ.js.map +1 -0
- package/dist/web/assets/d-pRatUO7H.js +2 -0
- package/dist/web/assets/d-pRatUO7H.js.map +1 -0
- package/dist/web/assets/diff-DbItnlRl.js +2 -0
- package/dist/web/assets/diff-DbItnlRl.js.map +1 -0
- package/dist/web/assets/dockerfile-BKs6k2Af.js +2 -0
- package/dist/web/assets/dockerfile-BKs6k2Af.js.map +1 -0
- package/dist/web/assets/dtd-DF_7sFjM.js +2 -0
- package/dist/web/assets/dtd-DF_7sFjM.js.map +1 -0
- package/dist/web/assets/dylan-DwRh75JA.js +2 -0
- package/dist/web/assets/dylan-DwRh75JA.js.map +1 -0
- package/dist/web/assets/ebnf-CDyGwa7X.js +2 -0
- package/dist/web/assets/ebnf-CDyGwa7X.js.map +1 -0
- package/dist/web/assets/ecl-Cabwm37j.js +2 -0
- package/dist/web/assets/ecl-Cabwm37j.js.map +1 -0
- package/dist/web/assets/eiffel-CnydiIhH.js +2 -0
- package/dist/web/assets/eiffel-CnydiIhH.js.map +1 -0
- package/dist/web/assets/elm-vLlmbW-K.js +2 -0
- package/dist/web/assets/elm-vLlmbW-K.js.map +1 -0
- package/dist/web/assets/erlang-BNw1qcRV.js +2 -0
- package/dist/web/assets/erlang-BNw1qcRV.js.map +1 -0
- package/dist/web/assets/factor-kuTfRLto.js +2 -0
- package/dist/web/assets/factor-kuTfRLto.js.map +1 -0
- package/dist/web/assets/fcl-Kvtd6kyn.js +2 -0
- package/dist/web/assets/fcl-Kvtd6kyn.js.map +1 -0
- package/dist/web/assets/forth-Ffai-XNe.js +2 -0
- package/dist/web/assets/forth-Ffai-XNe.js.map +1 -0
- package/dist/web/assets/fortran-DYz_wnZ1.js +2 -0
- package/dist/web/assets/fortran-DYz_wnZ1.js.map +1 -0
- package/dist/web/assets/gas-Bneqetm1.js +2 -0
- package/dist/web/assets/gas-Bneqetm1.js.map +1 -0
- package/dist/web/assets/gherkin-heZmZLOM.js +2 -0
- package/dist/web/assets/gherkin-heZmZLOM.js.map +1 -0
- package/dist/web/assets/groovy-D9Dt4D0W.js +2 -0
- package/dist/web/assets/groovy-D9Dt4D0W.js.map +1 -0
- package/dist/web/assets/haskell-BWDZoCOh.js +2 -0
- package/dist/web/assets/haskell-BWDZoCOh.js.map +1 -0
- package/dist/web/assets/haxe-H-WmDvRZ.js +2 -0
- package/dist/web/assets/haxe-H-WmDvRZ.js.map +1 -0
- package/dist/web/assets/http-DBlCnlav.js +2 -0
- package/dist/web/assets/http-DBlCnlav.js.map +1 -0
- package/dist/web/assets/idl-BEugSyMb.js +2 -0
- package/dist/web/assets/idl-BEugSyMb.js.map +1 -0
- package/dist/web/assets/index-6L7rK6RK.js +2 -0
- package/dist/web/assets/index-6L7rK6RK.js.map +1 -0
- package/dist/web/assets/index-B1YTM6Ei.js +2 -0
- package/dist/web/assets/index-B1YTM6Ei.js.map +1 -0
- package/dist/web/assets/index-B7vcMomf.js +509 -0
- package/dist/web/assets/index-B7vcMomf.js.map +1 -0
- package/dist/web/assets/index-BcZ8RTQK.js +2 -0
- package/dist/web/assets/index-BcZ8RTQK.js.map +1 -0
- package/dist/web/assets/index-C7GrfZtu.js +2 -0
- package/dist/web/assets/index-C7GrfZtu.js.map +1 -0
- package/dist/web/assets/index-C7fIfqkz.js +2 -0
- package/dist/web/assets/index-C7fIfqkz.js.map +1 -0
- package/dist/web/assets/index-C9-Eilv-.js +2 -0
- package/dist/web/assets/index-C9-Eilv-.js.map +1 -0
- package/dist/web/assets/index-CC-t7RnM.js +4 -0
- package/dist/web/assets/index-CC-t7RnM.js.map +1 -0
- package/dist/web/assets/index-CLbc4ChH.js +2 -0
- package/dist/web/assets/index-CLbc4ChH.js.map +1 -0
- package/dist/web/assets/index-CMXahjWH.js +2 -0
- package/dist/web/assets/index-CMXahjWH.js.map +1 -0
- package/dist/web/assets/index-CfYzSHJA.css +1 -0
- package/dist/web/assets/index-ClDYe_wE.js +2 -0
- package/dist/web/assets/index-ClDYe_wE.js.map +1 -0
- package/dist/web/assets/index-CxykdbB_.js +2 -0
- package/dist/web/assets/index-CxykdbB_.js.map +1 -0
- package/dist/web/assets/index-D3WXxnT1.js +2 -0
- package/dist/web/assets/index-D3WXxnT1.js.map +1 -0
- package/dist/web/assets/index-D4qNbgAX.js +2 -0
- package/dist/web/assets/index-D4qNbgAX.js.map +1 -0
- package/dist/web/assets/index-DCiUPvZt.js +2 -0
- package/dist/web/assets/index-DCiUPvZt.js.map +1 -0
- package/dist/web/assets/index-DJpCPEwr.js +3 -0
- package/dist/web/assets/index-DJpCPEwr.js.map +1 -0
- package/dist/web/assets/index-EuUS3D16.js +8 -0
- package/dist/web/assets/index-EuUS3D16.js.map +1 -0
- package/dist/web/assets/index-WATjATUO.js +2 -0
- package/dist/web/assets/index-WATjATUO.js.map +1 -0
- package/dist/web/assets/javascript-qCveANmP.js +2 -0
- package/dist/web/assets/javascript-qCveANmP.js.map +1 -0
- package/dist/web/assets/julia-DuME0IfC.js +2 -0
- package/dist/web/assets/julia-DuME0IfC.js.map +1 -0
- package/dist/web/assets/livescript-BwQOo05w.js +2 -0
- package/dist/web/assets/livescript-BwQOo05w.js.map +1 -0
- package/dist/web/assets/lua-BgMRiT3U.js +2 -0
- package/dist/web/assets/lua-BgMRiT3U.js.map +1 -0
- package/dist/web/assets/mathematica-DTrFuWx2.js +2 -0
- package/dist/web/assets/mathematica-DTrFuWx2.js.map +1 -0
- package/dist/web/assets/mbox-CNhZ1qSd.js +2 -0
- package/dist/web/assets/mbox-CNhZ1qSd.js.map +1 -0
- package/dist/web/assets/mirc-CjQqDB4T.js +2 -0
- package/dist/web/assets/mirc-CjQqDB4T.js.map +1 -0
- package/dist/web/assets/mllike-CXdrOF99.js +2 -0
- package/dist/web/assets/mllike-CXdrOF99.js.map +1 -0
- package/dist/web/assets/modelica-Dc1JOy9r.js +2 -0
- package/dist/web/assets/modelica-Dc1JOy9r.js.map +1 -0
- package/dist/web/assets/mscgen-BA5vi2Kp.js +2 -0
- package/dist/web/assets/mscgen-BA5vi2Kp.js.map +1 -0
- package/dist/web/assets/mumps-BT43cFF4.js +2 -0
- package/dist/web/assets/mumps-BT43cFF4.js.map +1 -0
- package/dist/web/assets/nginx-DdIZxoE0.js +2 -0
- package/dist/web/assets/nginx-DdIZxoE0.js.map +1 -0
- package/dist/web/assets/nsis-LdVXkNf5.js +2 -0
- package/dist/web/assets/nsis-LdVXkNf5.js.map +1 -0
- package/dist/web/assets/ntriples-BfvgReVJ.js +2 -0
- package/dist/web/assets/ntriples-BfvgReVJ.js.map +1 -0
- package/dist/web/assets/octave-Ck1zUtKM.js +2 -0
- package/dist/web/assets/octave-Ck1zUtKM.js.map +1 -0
- package/dist/web/assets/oz-BzwKVEFT.js +2 -0
- package/dist/web/assets/oz-BzwKVEFT.js.map +1 -0
- package/dist/web/assets/pascal--L3eBynH.js +2 -0
- package/dist/web/assets/pascal--L3eBynH.js.map +1 -0
- package/dist/web/assets/perl-CdXCOZ3F.js +2 -0
- package/dist/web/assets/perl-CdXCOZ3F.js.map +1 -0
- package/dist/web/assets/pig-CevX1Tat.js +2 -0
- package/dist/web/assets/pig-CevX1Tat.js.map +1 -0
- package/dist/web/assets/powershell-CFHJl5sT.js +2 -0
- package/dist/web/assets/powershell-CFHJl5sT.js.map +1 -0
- package/dist/web/assets/properties-C78fOPTZ.js +2 -0
- package/dist/web/assets/properties-C78fOPTZ.js.map +1 -0
- package/dist/web/assets/protobuf-ChK-085T.js +2 -0
- package/dist/web/assets/protobuf-ChK-085T.js.map +1 -0
- package/dist/web/assets/pug-DukmZTjD.js +2 -0
- package/dist/web/assets/pug-DukmZTjD.js.map +1 -0
- package/dist/web/assets/puppet-DMA9R1ak.js +2 -0
- package/dist/web/assets/puppet-DMA9R1ak.js.map +1 -0
- package/dist/web/assets/python-BuPzkPfP.js +2 -0
- package/dist/web/assets/python-BuPzkPfP.js.map +1 -0
- package/dist/web/assets/q-pXgVlZs6.js +2 -0
- package/dist/web/assets/q-pXgVlZs6.js.map +1 -0
- package/dist/web/assets/r-DUYO_cvP.js +2 -0
- package/dist/web/assets/r-DUYO_cvP.js.map +1 -0
- package/dist/web/assets/rpm-CTu-6PCP.js +2 -0
- package/dist/web/assets/rpm-CTu-6PCP.js.map +1 -0
- package/dist/web/assets/ruby-B2Rjki9n.js +2 -0
- package/dist/web/assets/ruby-B2Rjki9n.js.map +1 -0
- package/dist/web/assets/sas-B4kiWyti.js +2 -0
- package/dist/web/assets/sas-B4kiWyti.js.map +1 -0
- package/dist/web/assets/scheme-C41bIUwD.js +2 -0
- package/dist/web/assets/scheme-C41bIUwD.js.map +1 -0
- package/dist/web/assets/shell-CjFT_Tl9.js +2 -0
- package/dist/web/assets/shell-CjFT_Tl9.js.map +1 -0
- package/dist/web/assets/sieve-C3Gn_uJK.js +2 -0
- package/dist/web/assets/sieve-C3Gn_uJK.js.map +1 -0
- package/dist/web/assets/simple-mode-GW_nhZxv.js +2 -0
- package/dist/web/assets/simple-mode-GW_nhZxv.js.map +1 -0
- package/dist/web/assets/smalltalk-CnHTOXQT.js +2 -0
- package/dist/web/assets/smalltalk-CnHTOXQT.js.map +1 -0
- package/dist/web/assets/solr-DehyRSwq.js +2 -0
- package/dist/web/assets/solr-DehyRSwq.js.map +1 -0
- package/dist/web/assets/sparql-DkYu6x3z.js +2 -0
- package/dist/web/assets/sparql-DkYu6x3z.js.map +1 -0
- package/dist/web/assets/spreadsheet-BCZA_wO0.js +2 -0
- package/dist/web/assets/spreadsheet-BCZA_wO0.js.map +1 -0
- package/dist/web/assets/sql-D0XecflT.js +2 -0
- package/dist/web/assets/sql-D0XecflT.js.map +1 -0
- package/dist/web/assets/stex-C3f8Ysf7.js +2 -0
- package/dist/web/assets/stex-C3f8Ysf7.js.map +1 -0
- package/dist/web/assets/stylus-B533Al4x.js +2 -0
- package/dist/web/assets/stylus-B533Al4x.js.map +1 -0
- package/dist/web/assets/swift-BzpIVaGY.js +2 -0
- package/dist/web/assets/swift-BzpIVaGY.js.map +1 -0
- package/dist/web/assets/tcl-DVfN8rqt.js +2 -0
- package/dist/web/assets/tcl-DVfN8rqt.js.map +1 -0
- package/dist/web/assets/textile-CnDTJFAw.js +2 -0
- package/dist/web/assets/textile-CnDTJFAw.js.map +1 -0
- package/dist/web/assets/tiddlywiki-DO-Gjzrf.js +2 -0
- package/dist/web/assets/tiddlywiki-DO-Gjzrf.js.map +1 -0
- package/dist/web/assets/tiki-DGYXhP31.js +2 -0
- package/dist/web/assets/tiki-DGYXhP31.js.map +1 -0
- package/dist/web/assets/toml-Bm5Em-hy.js +2 -0
- package/dist/web/assets/toml-Bm5Em-hy.js.map +1 -0
- package/dist/web/assets/troff-wAsdV37c.js +2 -0
- package/dist/web/assets/troff-wAsdV37c.js.map +1 -0
- package/dist/web/assets/ttcn-CfJYG6tj.js +2 -0
- package/dist/web/assets/ttcn-CfJYG6tj.js.map +1 -0
- package/dist/web/assets/ttcn-cfg-B9xdYoR4.js +2 -0
- package/dist/web/assets/ttcn-cfg-B9xdYoR4.js.map +1 -0
- package/dist/web/assets/turtle-B1tBg_DP.js +2 -0
- package/dist/web/assets/turtle-B1tBg_DP.js.map +1 -0
- package/dist/web/assets/vb-CmGdzxic.js +2 -0
- package/dist/web/assets/vb-CmGdzxic.js.map +1 -0
- package/dist/web/assets/vbscript-BuJXcnF6.js +2 -0
- package/dist/web/assets/vbscript-BuJXcnF6.js.map +1 -0
- package/dist/web/assets/velocity-D8B20fx6.js +2 -0
- package/dist/web/assets/velocity-D8B20fx6.js.map +1 -0
- package/dist/web/assets/verilog-C6RDOZhf.js +2 -0
- package/dist/web/assets/verilog-C6RDOZhf.js.map +1 -0
- package/dist/web/assets/vhdl-lSbBsy5d.js +2 -0
- package/dist/web/assets/vhdl-lSbBsy5d.js.map +1 -0
- package/dist/web/assets/webidl-ZXfAyPTL.js +2 -0
- package/dist/web/assets/webidl-ZXfAyPTL.js.map +1 -0
- package/dist/web/assets/xquery-CQfU5ijd.js +2 -0
- package/dist/web/assets/xquery-CQfU5ijd.js.map +1 -0
- package/dist/web/assets/yacas-BJ4BC0dw.js +2 -0
- package/dist/web/assets/yacas-BJ4BC0dw.js.map +1 -0
- package/dist/web/assets/z80-Hz9HOZM7.js +2 -0
- package/dist/web/assets/z80-Hz9HOZM7.js.map +1 -0
- package/dist/web/index.html +23 -0
- package/package.json +75 -0
- package/public/.gitkeep +0 -0
- package/public/assets/apl-B4CMkyY2.js +2 -0
- package/public/assets/apl-B4CMkyY2.js.map +1 -0
- package/public/assets/asciiarmor-Df11BRmG.js +2 -0
- package/public/assets/asciiarmor-Df11BRmG.js.map +1 -0
- package/public/assets/asn1-EdZsLKOL.js +2 -0
- package/public/assets/asn1-EdZsLKOL.js.map +1 -0
- package/public/assets/asterisk-B-8jnY81.js +2 -0
- package/public/assets/asterisk-B-8jnY81.js.map +1 -0
- package/public/assets/brainfuck-C4LP7Hcl.js +2 -0
- package/public/assets/brainfuck-C4LP7Hcl.js.map +1 -0
- package/public/assets/clike-B9uivgTg.js +2 -0
- package/public/assets/clike-B9uivgTg.js.map +1 -0
- package/public/assets/clojure-BMjYHr_A.js +2 -0
- package/public/assets/clojure-BMjYHr_A.js.map +1 -0
- package/public/assets/cmake-BQqOBYOt.js +2 -0
- package/public/assets/cmake-BQqOBYOt.js.map +1 -0
- package/public/assets/cobol-CWcv1MsR.js +2 -0
- package/public/assets/cobol-CWcv1MsR.js.map +1 -0
- package/public/assets/coffeescript-S37ZYGWr.js +2 -0
- package/public/assets/coffeescript-S37ZYGWr.js.map +1 -0
- package/public/assets/commonlisp-DBKNyK5s.js +2 -0
- package/public/assets/commonlisp-DBKNyK5s.js.map +1 -0
- package/public/assets/crystal-SjHAIU92.js +2 -0
- package/public/assets/crystal-SjHAIU92.js.map +1 -0
- package/public/assets/css-BnMrqG3P.js +2 -0
- package/public/assets/css-BnMrqG3P.js.map +1 -0
- package/public/assets/cypher-C_CwsFkJ.js +2 -0
- package/public/assets/cypher-C_CwsFkJ.js.map +1 -0
- package/public/assets/d-pRatUO7H.js +2 -0
- package/public/assets/d-pRatUO7H.js.map +1 -0
- package/public/assets/diff-DbItnlRl.js +2 -0
- package/public/assets/diff-DbItnlRl.js.map +1 -0
- package/public/assets/dockerfile-BKs6k2Af.js +2 -0
- package/public/assets/dockerfile-BKs6k2Af.js.map +1 -0
- package/public/assets/dtd-DF_7sFjM.js +2 -0
- package/public/assets/dtd-DF_7sFjM.js.map +1 -0
- package/public/assets/dylan-DwRh75JA.js +2 -0
- package/public/assets/dylan-DwRh75JA.js.map +1 -0
- package/public/assets/ebnf-CDyGwa7X.js +2 -0
- package/public/assets/ebnf-CDyGwa7X.js.map +1 -0
- package/public/assets/ecl-Cabwm37j.js +2 -0
- package/public/assets/ecl-Cabwm37j.js.map +1 -0
- package/public/assets/eiffel-CnydiIhH.js +2 -0
- package/public/assets/eiffel-CnydiIhH.js.map +1 -0
- package/public/assets/elm-vLlmbW-K.js +2 -0
- package/public/assets/elm-vLlmbW-K.js.map +1 -0
- package/public/assets/erlang-BNw1qcRV.js +2 -0
- package/public/assets/erlang-BNw1qcRV.js.map +1 -0
- package/public/assets/factor-kuTfRLto.js +2 -0
- package/public/assets/factor-kuTfRLto.js.map +1 -0
- package/public/assets/fcl-Kvtd6kyn.js +2 -0
- package/public/assets/fcl-Kvtd6kyn.js.map +1 -0
- package/public/assets/forth-Ffai-XNe.js +2 -0
- package/public/assets/forth-Ffai-XNe.js.map +1 -0
- package/public/assets/fortran-DYz_wnZ1.js +2 -0
- package/public/assets/fortran-DYz_wnZ1.js.map +1 -0
- package/public/assets/gas-Bneqetm1.js +2 -0
- package/public/assets/gas-Bneqetm1.js.map +1 -0
- package/public/assets/gherkin-heZmZLOM.js +2 -0
- package/public/assets/gherkin-heZmZLOM.js.map +1 -0
- package/public/assets/groovy-D9Dt4D0W.js +2 -0
- package/public/assets/groovy-D9Dt4D0W.js.map +1 -0
- package/public/assets/haskell-BWDZoCOh.js +2 -0
- package/public/assets/haskell-BWDZoCOh.js.map +1 -0
- package/public/assets/haxe-H-WmDvRZ.js +2 -0
- package/public/assets/haxe-H-WmDvRZ.js.map +1 -0
- package/public/assets/http-DBlCnlav.js +2 -0
- package/public/assets/http-DBlCnlav.js.map +1 -0
- package/public/assets/idl-BEugSyMb.js +2 -0
- package/public/assets/idl-BEugSyMb.js.map +1 -0
- package/public/assets/index-BHi_kGSi.js +8 -0
- package/public/assets/index-BHi_kGSi.js.map +1 -0
- package/public/assets/index-BMLAwwWL.js +2 -0
- package/public/assets/index-BMLAwwWL.js.map +1 -0
- package/public/assets/index-BNSDh5mD.js +2 -0
- package/public/assets/index-BNSDh5mD.js.map +1 -0
- package/public/assets/index-BR0D24wt.js +2 -0
- package/public/assets/index-BR0D24wt.js.map +1 -0
- package/public/assets/index-BdLsiQv5.js +2 -0
- package/public/assets/index-BdLsiQv5.js.map +1 -0
- package/public/assets/index-BjnJos4J.js +2 -0
- package/public/assets/index-BjnJos4J.js.map +1 -0
- package/public/assets/index-CM3gGvbH.js +509 -0
- package/public/assets/index-CM3gGvbH.js.map +1 -0
- package/public/assets/index-CV8De3J9.js +2 -0
- package/public/assets/index-CV8De3J9.js.map +1 -0
- package/public/assets/index-ChuKVzLw.js +2 -0
- package/public/assets/index-ChuKVzLw.js.map +1 -0
- package/public/assets/index-CpfmaE2d.js +2 -0
- package/public/assets/index-CpfmaE2d.js.map +1 -0
- package/public/assets/index-D90_xI0s.js +2 -0
- package/public/assets/index-D90_xI0s.js.map +1 -0
- package/public/assets/index-DR3bJemi.js +4 -0
- package/public/assets/index-DR3bJemi.js.map +1 -0
- package/public/assets/index-DlsEbLHk.css +1 -0
- package/public/assets/index-MR5aWKcm.js +2 -0
- package/public/assets/index-MR5aWKcm.js.map +1 -0
- package/public/assets/index-MrhuDMHQ.js +2 -0
- package/public/assets/index-MrhuDMHQ.js.map +1 -0
- package/public/assets/index-NbLWR4tH.js +2 -0
- package/public/assets/index-NbLWR4tH.js.map +1 -0
- package/public/assets/index-VnBXaSng.js +3 -0
- package/public/assets/index-VnBXaSng.js.map +1 -0
- package/public/assets/index-XEgqkWdk.js +2 -0
- package/public/assets/index-XEgqkWdk.js.map +1 -0
- package/public/assets/index-zHvewZlp.js +2 -0
- package/public/assets/index-zHvewZlp.js.map +1 -0
- package/public/assets/javascript-qCveANmP.js +2 -0
- package/public/assets/javascript-qCveANmP.js.map +1 -0
- package/public/assets/julia-DuME0IfC.js +2 -0
- package/public/assets/julia-DuME0IfC.js.map +1 -0
- package/public/assets/livescript-BwQOo05w.js +2 -0
- package/public/assets/livescript-BwQOo05w.js.map +1 -0
- package/public/assets/lua-BgMRiT3U.js +2 -0
- package/public/assets/lua-BgMRiT3U.js.map +1 -0
- package/public/assets/mathematica-DTrFuWx2.js +2 -0
- package/public/assets/mathematica-DTrFuWx2.js.map +1 -0
- package/public/assets/mbox-CNhZ1qSd.js +2 -0
- package/public/assets/mbox-CNhZ1qSd.js.map +1 -0
- package/public/assets/mirc-CjQqDB4T.js +2 -0
- package/public/assets/mirc-CjQqDB4T.js.map +1 -0
- package/public/assets/mllike-CXdrOF99.js +2 -0
- package/public/assets/mllike-CXdrOF99.js.map +1 -0
- package/public/assets/modelica-Dc1JOy9r.js +2 -0
- package/public/assets/modelica-Dc1JOy9r.js.map +1 -0
- package/public/assets/mscgen-BA5vi2Kp.js +2 -0
- package/public/assets/mscgen-BA5vi2Kp.js.map +1 -0
- package/public/assets/mumps-BT43cFF4.js +2 -0
- package/public/assets/mumps-BT43cFF4.js.map +1 -0
- package/public/assets/nginx-DdIZxoE0.js +2 -0
- package/public/assets/nginx-DdIZxoE0.js.map +1 -0
- package/public/assets/nsis-LdVXkNf5.js +2 -0
- package/public/assets/nsis-LdVXkNf5.js.map +1 -0
- package/public/assets/ntriples-BfvgReVJ.js +2 -0
- package/public/assets/ntriples-BfvgReVJ.js.map +1 -0
- package/public/assets/octave-Ck1zUtKM.js +2 -0
- package/public/assets/octave-Ck1zUtKM.js.map +1 -0
- package/public/assets/oz-BzwKVEFT.js +2 -0
- package/public/assets/oz-BzwKVEFT.js.map +1 -0
- package/public/assets/pascal--L3eBynH.js +2 -0
- package/public/assets/pascal--L3eBynH.js.map +1 -0
- package/public/assets/perl-CdXCOZ3F.js +2 -0
- package/public/assets/perl-CdXCOZ3F.js.map +1 -0
- package/public/assets/pig-CevX1Tat.js +2 -0
- package/public/assets/pig-CevX1Tat.js.map +1 -0
- package/public/assets/powershell-CFHJl5sT.js +2 -0
- package/public/assets/powershell-CFHJl5sT.js.map +1 -0
- package/public/assets/properties-C78fOPTZ.js +2 -0
- package/public/assets/properties-C78fOPTZ.js.map +1 -0
- package/public/assets/protobuf-ChK-085T.js +2 -0
- package/public/assets/protobuf-ChK-085T.js.map +1 -0
- package/public/assets/pug-DukmZTjD.js +2 -0
- package/public/assets/pug-DukmZTjD.js.map +1 -0
- package/public/assets/puppet-DMA9R1ak.js +2 -0
- package/public/assets/puppet-DMA9R1ak.js.map +1 -0
- package/public/assets/python-BuPzkPfP.js +2 -0
- package/public/assets/python-BuPzkPfP.js.map +1 -0
- package/public/assets/q-pXgVlZs6.js +2 -0
- package/public/assets/q-pXgVlZs6.js.map +1 -0
- package/public/assets/r-DUYO_cvP.js +2 -0
- package/public/assets/r-DUYO_cvP.js.map +1 -0
- package/public/assets/rpm-CTu-6PCP.js +2 -0
- package/public/assets/rpm-CTu-6PCP.js.map +1 -0
- package/public/assets/ruby-B2Rjki9n.js +2 -0
- package/public/assets/ruby-B2Rjki9n.js.map +1 -0
- package/public/assets/sas-B4kiWyti.js +2 -0
- package/public/assets/sas-B4kiWyti.js.map +1 -0
- package/public/assets/scheme-C41bIUwD.js +2 -0
- package/public/assets/scheme-C41bIUwD.js.map +1 -0
- package/public/assets/shell-CjFT_Tl9.js +2 -0
- package/public/assets/shell-CjFT_Tl9.js.map +1 -0
- package/public/assets/sieve-C3Gn_uJK.js +2 -0
- package/public/assets/sieve-C3Gn_uJK.js.map +1 -0
- package/public/assets/simple-mode-GW_nhZxv.js +2 -0
- package/public/assets/simple-mode-GW_nhZxv.js.map +1 -0
- package/public/assets/smalltalk-CnHTOXQT.js +2 -0
- package/public/assets/smalltalk-CnHTOXQT.js.map +1 -0
- package/public/assets/solr-DehyRSwq.js +2 -0
- package/public/assets/solr-DehyRSwq.js.map +1 -0
- package/public/assets/sparql-DkYu6x3z.js +2 -0
- package/public/assets/sparql-DkYu6x3z.js.map +1 -0
- package/public/assets/spreadsheet-BCZA_wO0.js +2 -0
- package/public/assets/spreadsheet-BCZA_wO0.js.map +1 -0
- package/public/assets/sql-D0XecflT.js +2 -0
- package/public/assets/sql-D0XecflT.js.map +1 -0
- package/public/assets/stex-C3f8Ysf7.js +2 -0
- package/public/assets/stex-C3f8Ysf7.js.map +1 -0
- package/public/assets/stylus-B533Al4x.js +2 -0
- package/public/assets/stylus-B533Al4x.js.map +1 -0
- package/public/assets/swift-BzpIVaGY.js +2 -0
- package/public/assets/swift-BzpIVaGY.js.map +1 -0
- package/public/assets/tcl-DVfN8rqt.js +2 -0
- package/public/assets/tcl-DVfN8rqt.js.map +1 -0
- package/public/assets/textile-CnDTJFAw.js +2 -0
- package/public/assets/textile-CnDTJFAw.js.map +1 -0
- package/public/assets/tiddlywiki-DO-Gjzrf.js +2 -0
- package/public/assets/tiddlywiki-DO-Gjzrf.js.map +1 -0
- package/public/assets/tiki-DGYXhP31.js +2 -0
- package/public/assets/tiki-DGYXhP31.js.map +1 -0
- package/public/assets/toml-Bm5Em-hy.js +2 -0
- package/public/assets/toml-Bm5Em-hy.js.map +1 -0
- package/public/assets/troff-wAsdV37c.js +2 -0
- package/public/assets/troff-wAsdV37c.js.map +1 -0
- package/public/assets/ttcn-CfJYG6tj.js +2 -0
- package/public/assets/ttcn-CfJYG6tj.js.map +1 -0
- package/public/assets/ttcn-cfg-B9xdYoR4.js +2 -0
- package/public/assets/ttcn-cfg-B9xdYoR4.js.map +1 -0
- package/public/assets/turtle-B1tBg_DP.js +2 -0
- package/public/assets/turtle-B1tBg_DP.js.map +1 -0
- package/public/assets/vb-CmGdzxic.js +2 -0
- package/public/assets/vb-CmGdzxic.js.map +1 -0
- package/public/assets/vbscript-BuJXcnF6.js +2 -0
- package/public/assets/vbscript-BuJXcnF6.js.map +1 -0
- package/public/assets/velocity-D8B20fx6.js +2 -0
- package/public/assets/velocity-D8B20fx6.js.map +1 -0
- package/public/assets/verilog-C6RDOZhf.js +2 -0
- package/public/assets/verilog-C6RDOZhf.js.map +1 -0
- package/public/assets/vhdl-lSbBsy5d.js +2 -0
- package/public/assets/vhdl-lSbBsy5d.js.map +1 -0
- package/public/assets/webidl-ZXfAyPTL.js +2 -0
- package/public/assets/webidl-ZXfAyPTL.js.map +1 -0
- package/public/assets/xquery-CQfU5ijd.js +2 -0
- package/public/assets/xquery-CQfU5ijd.js.map +1 -0
- package/public/assets/yacas-BJ4BC0dw.js +2 -0
- package/public/assets/yacas-BJ4BC0dw.js.map +1 -0
- package/public/assets/z80-Hz9HOZM7.js +2 -0
- package/public/assets/z80-Hz9HOZM7.js.map +1 -0
- package/public/index.html +15 -0
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project API Routes
|
|
3
|
+
*
|
|
4
|
+
* Handles project open/close/current operations.
|
|
5
|
+
* Maintains server-side state for the currently active project.
|
|
6
|
+
*/
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import fs from 'node:fs/promises';
|
|
9
|
+
import { exec } from 'node:child_process';
|
|
10
|
+
import { promisify } from 'node:util';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
import { emitEvent } from './events.js';
|
|
14
|
+
import { createProjectContext, initializeContext, disposeContext, } from '../context.js';
|
|
15
|
+
import { RAGConfigSchema, CONFIG_FILE_NAME, ALL_CONFIG_FILE_NAMES, loadRAGConfig, saveRAGConfig, findRAGConfig, createProject as createProjectUtil, } from 'grepmind-config';
|
|
16
|
+
// Server-side state: currently active project
|
|
17
|
+
let currentProject = null;
|
|
18
|
+
/**
|
|
19
|
+
* Get current project state.
|
|
20
|
+
*/
|
|
21
|
+
export function getCurrentProject() {
|
|
22
|
+
return currentProject;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get current project context or throw if no project is open.
|
|
26
|
+
*/
|
|
27
|
+
export function requireProjectContext() {
|
|
28
|
+
if (!currentProject) {
|
|
29
|
+
throw new Error('No project is currently open');
|
|
30
|
+
}
|
|
31
|
+
return currentProject.context;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Set current project state (used internally).
|
|
35
|
+
*/
|
|
36
|
+
function setCurrentProject(project) {
|
|
37
|
+
currentProject = project;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if secrets have changed and need context recreation.
|
|
41
|
+
*/
|
|
42
|
+
function secretsChanged(oldSecrets, newSecrets) {
|
|
43
|
+
return (oldSecrets.voyageApiKey !== newSecrets.voyageApiKey ||
|
|
44
|
+
oldSecrets.localaiApiKey !== newSecrets.localaiApiKey ||
|
|
45
|
+
oldSecrets.ollamaBaseUrl !== newSecrets.ollamaBaseUrl);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Update secrets and recreate context if needed.
|
|
49
|
+
* Call this before operations that use embedding provider.
|
|
50
|
+
*/
|
|
51
|
+
export async function updateSecretsIfNeeded(newSecrets) {
|
|
52
|
+
if (!currentProject)
|
|
53
|
+
return;
|
|
54
|
+
// Check if secrets relevant to embedding have changed
|
|
55
|
+
if (!secretsChanged(currentProject.secrets, newSecrets)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Dispose old context
|
|
59
|
+
await disposeContext(currentProject.context);
|
|
60
|
+
// Recreate context with new secrets
|
|
61
|
+
const newContext = await openProjectContext(currentProject.path, currentProject.config, newSecrets);
|
|
62
|
+
// Update project state
|
|
63
|
+
currentProject.context = newContext;
|
|
64
|
+
currentProject.secrets = newSecrets;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Load and validate project config from file path
|
|
68
|
+
*/
|
|
69
|
+
async function loadProjectConfig(configPath) {
|
|
70
|
+
return loadRAGConfig(configPath);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Validate project path has a config file
|
|
74
|
+
*/
|
|
75
|
+
async function validateProjectPath(projectPath) {
|
|
76
|
+
const configPath = await findRAGConfig(projectPath);
|
|
77
|
+
if (!configPath) {
|
|
78
|
+
throw new Error(`Project config not found. Expected ${CONFIG_FILE_NAME} or legacy config in: ${projectPath}`);
|
|
79
|
+
}
|
|
80
|
+
return loadProjectConfig(configPath);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create and initialize project context with core indexers.
|
|
84
|
+
*/
|
|
85
|
+
async function openProjectContext(projectPath, config, secrets) {
|
|
86
|
+
const context = createProjectContext(projectPath, config, secrets);
|
|
87
|
+
await initializeContext(context);
|
|
88
|
+
return context;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Close current project and release resources.
|
|
92
|
+
*/
|
|
93
|
+
async function closeCurrentProject() {
|
|
94
|
+
if (!currentProject)
|
|
95
|
+
return;
|
|
96
|
+
await disposeContext(currentProject.context);
|
|
97
|
+
currentProject = null;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Register project routes
|
|
101
|
+
*/
|
|
102
|
+
export async function projectRoutes(app) {
|
|
103
|
+
/**
|
|
104
|
+
* POST /api/project/open
|
|
105
|
+
* Open a project by path, validating config exists
|
|
106
|
+
*/
|
|
107
|
+
app.post('/open', {
|
|
108
|
+
schema: {
|
|
109
|
+
body: {
|
|
110
|
+
type: 'object',
|
|
111
|
+
required: ['path'],
|
|
112
|
+
properties: {
|
|
113
|
+
path: { type: 'string' },
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
}, async (request, reply) => {
|
|
118
|
+
const { path: projectPath } = request.body;
|
|
119
|
+
try {
|
|
120
|
+
// Resolve to absolute path
|
|
121
|
+
const absolutePath = path.resolve(projectPath);
|
|
122
|
+
// Check directory exists
|
|
123
|
+
const stat = await fs.stat(absolutePath);
|
|
124
|
+
if (!stat.isDirectory()) {
|
|
125
|
+
return reply.status(400).send({
|
|
126
|
+
error: 'Invalid path',
|
|
127
|
+
message: 'Path must be a directory',
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// If the same project is already open, just return current state
|
|
131
|
+
// This prevents interrupting background sync on page refresh
|
|
132
|
+
const existingProject = getCurrentProject();
|
|
133
|
+
if (existingProject && existingProject.path === absolutePath) {
|
|
134
|
+
// Update secrets if provided
|
|
135
|
+
const secrets = request.secrets || {};
|
|
136
|
+
if (Object.keys(secrets).length > 0) {
|
|
137
|
+
await updateSecretsIfNeeded(secrets);
|
|
138
|
+
}
|
|
139
|
+
// Return existing project info without reinitializing
|
|
140
|
+
return reply.send({
|
|
141
|
+
name: existingProject.config.name || path.basename(absolutePath),
|
|
142
|
+
path: absolutePath,
|
|
143
|
+
vaultPaths: existingProject.config.vaultPaths,
|
|
144
|
+
code: existingProject.config.code.enabled ? {
|
|
145
|
+
include: existingProject.config.code.include,
|
|
146
|
+
exclude: existingProject.config.code.exclude,
|
|
147
|
+
} : null,
|
|
148
|
+
embeddingProvider: existingProject.config.embedding.provider,
|
|
149
|
+
openedAt: existingProject.openedAt,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// Validate project config
|
|
153
|
+
const config = await validateProjectPath(absolutePath);
|
|
154
|
+
// Close existing project if any (different project)
|
|
155
|
+
await closeCurrentProject();
|
|
156
|
+
// Get secrets from request (via middleware)
|
|
157
|
+
const secrets = request.secrets || {};
|
|
158
|
+
// Create and initialize project context
|
|
159
|
+
const context = await openProjectContext(absolutePath, config, secrets);
|
|
160
|
+
// Set as current project
|
|
161
|
+
const projectState = {
|
|
162
|
+
path: absolutePath,
|
|
163
|
+
config,
|
|
164
|
+
context,
|
|
165
|
+
openedAt: new Date().toISOString(),
|
|
166
|
+
secrets,
|
|
167
|
+
};
|
|
168
|
+
setCurrentProject(projectState);
|
|
169
|
+
// Emit project opened event
|
|
170
|
+
emitEvent({
|
|
171
|
+
type: 'project:opened',
|
|
172
|
+
data: {
|
|
173
|
+
path: absolutePath,
|
|
174
|
+
name: config.name || path.basename(absolutePath),
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
// Return project info
|
|
178
|
+
return reply.send({
|
|
179
|
+
name: config.name || path.basename(absolutePath),
|
|
180
|
+
path: absolutePath,
|
|
181
|
+
vaultPaths: config.vaultPaths,
|
|
182
|
+
code: config.code.enabled ? {
|
|
183
|
+
include: config.code.include,
|
|
184
|
+
exclude: config.code.exclude,
|
|
185
|
+
} : null,
|
|
186
|
+
embeddingProvider: config.embedding.provider,
|
|
187
|
+
openedAt: projectState.openedAt,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
192
|
+
if (message.includes('not found')) {
|
|
193
|
+
return reply.status(404).send({
|
|
194
|
+
error: 'Project config not found',
|
|
195
|
+
message: `No ${CONFIG_FILE_NAME} found in ${projectPath}`,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (message.includes('Invalid')) {
|
|
199
|
+
return reply.status(400).send({
|
|
200
|
+
error: 'Invalid project config',
|
|
201
|
+
message,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
app.log.error(error);
|
|
205
|
+
return reply.status(500).send({
|
|
206
|
+
error: 'Failed to open project',
|
|
207
|
+
message,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
/**
|
|
212
|
+
* POST /api/project/open-config
|
|
213
|
+
* Open a project by config file path
|
|
214
|
+
*/
|
|
215
|
+
app.post('/open-config', {
|
|
216
|
+
schema: {
|
|
217
|
+
body: {
|
|
218
|
+
type: 'object',
|
|
219
|
+
required: ['configPath'],
|
|
220
|
+
properties: {
|
|
221
|
+
configPath: { type: 'string' },
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
}, async (request, reply) => {
|
|
226
|
+
const { configPath } = request.body;
|
|
227
|
+
try {
|
|
228
|
+
// Resolve to absolute path
|
|
229
|
+
const absoluteConfigPath = path.resolve(configPath);
|
|
230
|
+
// Verify it's a file and ends with .json
|
|
231
|
+
const stat = await fs.stat(absoluteConfigPath);
|
|
232
|
+
if (!stat.isFile()) {
|
|
233
|
+
return reply.status(400).send({
|
|
234
|
+
error: 'Invalid path',
|
|
235
|
+
message: 'Path must be a file',
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
const fileName = path.basename(absoluteConfigPath);
|
|
239
|
+
if (!ALL_CONFIG_FILE_NAMES.includes(fileName)) {
|
|
240
|
+
return reply.status(400).send({
|
|
241
|
+
error: 'Invalid config file',
|
|
242
|
+
message: `Expected file named: ${ALL_CONFIG_FILE_NAMES.join(' or ')}`,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
// Project directory is parent of config file
|
|
246
|
+
const projectPath = path.dirname(absoluteConfigPath);
|
|
247
|
+
// If the same project is already open, just return current state
|
|
248
|
+
// This prevents interrupting background sync on page refresh
|
|
249
|
+
const existingProject = getCurrentProject();
|
|
250
|
+
if (existingProject && existingProject.path === projectPath) {
|
|
251
|
+
// Update secrets if provided
|
|
252
|
+
const secrets = request.secrets || {};
|
|
253
|
+
if (Object.keys(secrets).length > 0) {
|
|
254
|
+
await updateSecretsIfNeeded(secrets);
|
|
255
|
+
}
|
|
256
|
+
// Return existing project info without reinitializing
|
|
257
|
+
return reply.send({
|
|
258
|
+
name: existingProject.config.name || path.basename(projectPath),
|
|
259
|
+
path: projectPath,
|
|
260
|
+
vaultPaths: existingProject.config.vaultPaths,
|
|
261
|
+
code: existingProject.config.code.enabled ? {
|
|
262
|
+
include: existingProject.config.code.include,
|
|
263
|
+
exclude: existingProject.config.code.exclude,
|
|
264
|
+
} : null,
|
|
265
|
+
embeddingProvider: existingProject.config.embedding.provider,
|
|
266
|
+
openedAt: existingProject.openedAt,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
// Load config from file
|
|
270
|
+
const config = await loadProjectConfig(absoluteConfigPath);
|
|
271
|
+
// Close existing project if any (different project)
|
|
272
|
+
await closeCurrentProject();
|
|
273
|
+
// Get secrets from request (via middleware)
|
|
274
|
+
const secrets = request.secrets || {};
|
|
275
|
+
// Create and initialize project context
|
|
276
|
+
const context = await openProjectContext(projectPath, config, secrets);
|
|
277
|
+
// Set as current project
|
|
278
|
+
const projectState = {
|
|
279
|
+
path: projectPath,
|
|
280
|
+
config,
|
|
281
|
+
context,
|
|
282
|
+
openedAt: new Date().toISOString(),
|
|
283
|
+
secrets,
|
|
284
|
+
};
|
|
285
|
+
setCurrentProject(projectState);
|
|
286
|
+
// Emit project opened event
|
|
287
|
+
emitEvent({
|
|
288
|
+
type: 'project:opened',
|
|
289
|
+
data: {
|
|
290
|
+
path: projectPath,
|
|
291
|
+
name: config.name || path.basename(projectPath),
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
// Return project info
|
|
295
|
+
return reply.send({
|
|
296
|
+
name: config.name || path.basename(projectPath),
|
|
297
|
+
path: projectPath,
|
|
298
|
+
vaultPaths: config.vaultPaths,
|
|
299
|
+
code: config.code.enabled ? {
|
|
300
|
+
include: config.code.include,
|
|
301
|
+
exclude: config.code.exclude,
|
|
302
|
+
} : null,
|
|
303
|
+
embeddingProvider: config.embedding.provider,
|
|
304
|
+
openedAt: projectState.openedAt,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
309
|
+
if (message.includes('not found')) {
|
|
310
|
+
return reply.status(404).send({
|
|
311
|
+
error: 'Config file not found',
|
|
312
|
+
message,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
if (message.includes('Invalid')) {
|
|
316
|
+
return reply.status(400).send({
|
|
317
|
+
error: 'Invalid config',
|
|
318
|
+
message,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
app.log.error(error);
|
|
322
|
+
return reply.status(500).send({
|
|
323
|
+
error: 'Failed to open project',
|
|
324
|
+
message,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
/**
|
|
329
|
+
* GET /api/project/current
|
|
330
|
+
* Get currently active project or null
|
|
331
|
+
*/
|
|
332
|
+
app.get('/current', async (request, reply) => {
|
|
333
|
+
if (!currentProject) {
|
|
334
|
+
return reply.send(null);
|
|
335
|
+
}
|
|
336
|
+
const { path: projectPath, config, openedAt } = currentProject;
|
|
337
|
+
return reply.send({
|
|
338
|
+
name: config.name || path.basename(projectPath),
|
|
339
|
+
path: projectPath,
|
|
340
|
+
vaultPaths: config.vaultPaths,
|
|
341
|
+
code: config.code.enabled ? {
|
|
342
|
+
include: config.code.include,
|
|
343
|
+
exclude: config.code.exclude,
|
|
344
|
+
} : null,
|
|
345
|
+
embeddingProvider: config.embedding.provider,
|
|
346
|
+
openedAt,
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
/**
|
|
350
|
+
* POST /api/project/close
|
|
351
|
+
* Close the current project
|
|
352
|
+
*/
|
|
353
|
+
app.post('/close', async (request, reply) => {
|
|
354
|
+
if (!currentProject) {
|
|
355
|
+
return reply.status(400).send({
|
|
356
|
+
error: 'No project open',
|
|
357
|
+
message: 'No project is currently open',
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
const closedPath = currentProject.path;
|
|
361
|
+
await closeCurrentProject();
|
|
362
|
+
// Emit project closed event
|
|
363
|
+
emitEvent({
|
|
364
|
+
type: 'project:closed',
|
|
365
|
+
data: { path: closedPath },
|
|
366
|
+
});
|
|
367
|
+
return reply.send({ success: true });
|
|
368
|
+
});
|
|
369
|
+
/**
|
|
370
|
+
* GET /api/project/stats
|
|
371
|
+
* Get index statistics for current project
|
|
372
|
+
*/
|
|
373
|
+
app.get('/stats', async (request, reply) => {
|
|
374
|
+
if (!currentProject) {
|
|
375
|
+
return reply.status(400).send({
|
|
376
|
+
error: 'No project open',
|
|
377
|
+
message: 'No project is currently open',
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
const { context, config } = currentProject;
|
|
381
|
+
try {
|
|
382
|
+
// Get notes index stats
|
|
383
|
+
let notesCount = 0;
|
|
384
|
+
let notesLastSync = null;
|
|
385
|
+
try {
|
|
386
|
+
const notesStats = await context.indexer.getStats();
|
|
387
|
+
notesCount = notesStats.totalFiles;
|
|
388
|
+
// Get last sync from git syncer if available
|
|
389
|
+
if (context.notesSyncer) {
|
|
390
|
+
const syncState = await context.notesSyncer.getState();
|
|
391
|
+
if (syncState?.lastSyncTimestamp) {
|
|
392
|
+
notesLastSync = new Date(syncState.lastSyncTimestamp).toISOString();
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
// Index might not exist yet
|
|
398
|
+
}
|
|
399
|
+
// Get code index stats if enabled
|
|
400
|
+
let codeCount = 0;
|
|
401
|
+
let codeLastSync = null;
|
|
402
|
+
const codeEnabled = (config.code.enabled || (config.code.include && config.code.include.length > 0)) && !!context.codeIndexer;
|
|
403
|
+
if (codeEnabled && context.codeIndexer) {
|
|
404
|
+
try {
|
|
405
|
+
const codeStats = await context.codeIndexer.getStats();
|
|
406
|
+
codeCount = codeStats.totalFiles;
|
|
407
|
+
// TODO: Add code git syncer state
|
|
408
|
+
}
|
|
409
|
+
catch {
|
|
410
|
+
// Index might not exist yet
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return reply.send({
|
|
414
|
+
notesCount,
|
|
415
|
+
codeCount,
|
|
416
|
+
notesLastSync,
|
|
417
|
+
codeLastSync,
|
|
418
|
+
codeEnabled,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
catch (error) {
|
|
422
|
+
app.log.error(error);
|
|
423
|
+
return reply.status(500).send({
|
|
424
|
+
error: 'Failed to get stats',
|
|
425
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
/**
|
|
430
|
+
* GET /api/project/config
|
|
431
|
+
* Get the full configuration of the current project
|
|
432
|
+
*/
|
|
433
|
+
app.get('/config', async (request, reply) => {
|
|
434
|
+
if (!currentProject) {
|
|
435
|
+
return reply.status(400).send({
|
|
436
|
+
error: 'No project open',
|
|
437
|
+
message: 'No project is currently open',
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
// Return the full config with the project path
|
|
441
|
+
return reply.send({
|
|
442
|
+
path: currentProject.path,
|
|
443
|
+
config: currentProject.config,
|
|
444
|
+
});
|
|
445
|
+
});
|
|
446
|
+
/**
|
|
447
|
+
* PUT /api/project/config
|
|
448
|
+
* Update the current project configuration
|
|
449
|
+
*/
|
|
450
|
+
app.put('/config', async (request, reply) => {
|
|
451
|
+
if (!currentProject) {
|
|
452
|
+
return reply.status(400).send({
|
|
453
|
+
error: 'No project open',
|
|
454
|
+
message: 'No project is currently open',
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
try {
|
|
458
|
+
const updates = request.body;
|
|
459
|
+
// Merge with existing config (deep merge for nested objects)
|
|
460
|
+
const newConfig = {
|
|
461
|
+
...currentProject.config,
|
|
462
|
+
...updates,
|
|
463
|
+
embedding: {
|
|
464
|
+
...currentProject.config.embedding,
|
|
465
|
+
...(updates.embedding || {}),
|
|
466
|
+
},
|
|
467
|
+
reranking: {
|
|
468
|
+
...currentProject.config.reranking,
|
|
469
|
+
...(updates.reranking || {}),
|
|
470
|
+
},
|
|
471
|
+
code: {
|
|
472
|
+
...currentProject.config.code,
|
|
473
|
+
...(updates.code || {}),
|
|
474
|
+
},
|
|
475
|
+
gitSync: {
|
|
476
|
+
...currentProject.config.gitSync,
|
|
477
|
+
...(updates.gitSync || {}),
|
|
478
|
+
},
|
|
479
|
+
lancedb: {
|
|
480
|
+
...currentProject.config.lancedb,
|
|
481
|
+
...(updates.lancedb || {}),
|
|
482
|
+
},
|
|
483
|
+
};
|
|
484
|
+
// Validate the merged config
|
|
485
|
+
const validatedConfig = RAGConfigSchema.parse(newConfig);
|
|
486
|
+
// Find the config file to update
|
|
487
|
+
const configPath = await findRAGConfig(currentProject.path);
|
|
488
|
+
if (!configPath) {
|
|
489
|
+
return reply.status(500).send({
|
|
490
|
+
error: 'Config file not found',
|
|
491
|
+
message: 'Could not find config file in project directory',
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
// Write the updated config
|
|
495
|
+
await saveRAGConfig(configPath, validatedConfig);
|
|
496
|
+
// Check if embedding provider changed - need to reinitialize context
|
|
497
|
+
const embeddingChanged = currentProject.config.embedding.provider !== validatedConfig.embedding.provider ||
|
|
498
|
+
currentProject.config.embedding.model !== validatedConfig.embedding.model;
|
|
499
|
+
const codeChanged = currentProject.config.code.enabled !== validatedConfig.code.enabled ||
|
|
500
|
+
JSON.stringify(currentProject.config.code.include) !== JSON.stringify(validatedConfig.code.include) ||
|
|
501
|
+
currentProject.config.code.graph?.enabled !== validatedConfig.code.graph?.enabled ||
|
|
502
|
+
currentProject.config.code.tree?.enabled !== validatedConfig.code.tree?.enabled;
|
|
503
|
+
// Update the in-memory config
|
|
504
|
+
currentProject.config = validatedConfig;
|
|
505
|
+
// Get secrets from request (via middleware) - may have new secrets
|
|
506
|
+
const secrets = request.secrets || currentProject.secrets;
|
|
507
|
+
// Reinitialize context if embedding or code settings changed
|
|
508
|
+
if (embeddingChanged || codeChanged) {
|
|
509
|
+
await disposeContext(currentProject.context);
|
|
510
|
+
currentProject.context = await openProjectContext(currentProject.path, validatedConfig, secrets);
|
|
511
|
+
currentProject.secrets = secrets;
|
|
512
|
+
}
|
|
513
|
+
// Emit config updated event
|
|
514
|
+
emitEvent({
|
|
515
|
+
type: 'project:config:updated',
|
|
516
|
+
data: {
|
|
517
|
+
path: currentProject.path,
|
|
518
|
+
config: validatedConfig,
|
|
519
|
+
},
|
|
520
|
+
});
|
|
521
|
+
return reply.send({
|
|
522
|
+
success: true,
|
|
523
|
+
config: validatedConfig,
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
catch (error) {
|
|
527
|
+
if (error instanceof z.ZodError) {
|
|
528
|
+
return reply.status(400).send({
|
|
529
|
+
error: 'Invalid config',
|
|
530
|
+
message: error.message,
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
app.log.error(error);
|
|
534
|
+
return reply.status(500).send({
|
|
535
|
+
error: 'Failed to update config',
|
|
536
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
/**
|
|
541
|
+
* POST /api/project/create
|
|
542
|
+
* Create a new project with full initialization
|
|
543
|
+
*/
|
|
544
|
+
app.post('/create', async (request, reply) => {
|
|
545
|
+
const { path: projectPath, config: configInput } = request.body;
|
|
546
|
+
try {
|
|
547
|
+
const absolutePath = path.resolve(projectPath);
|
|
548
|
+
// Check if project already exists
|
|
549
|
+
const existingConfig = await findRAGConfig(absolutePath);
|
|
550
|
+
if (existingConfig) {
|
|
551
|
+
return reply.status(400).send({
|
|
552
|
+
error: 'Project already exists',
|
|
553
|
+
message: `A project already exists at ${absolutePath}`,
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
// Create project using config utility
|
|
557
|
+
const configPath = await createProjectUtil(absolutePath, {
|
|
558
|
+
name: configInput.name,
|
|
559
|
+
vaultPaths: configInput.vaultPaths,
|
|
560
|
+
lancedb: configInput.lancedb,
|
|
561
|
+
embedding: configInput.embedding,
|
|
562
|
+
reranking: configInput.reranking,
|
|
563
|
+
code: configInput.code,
|
|
564
|
+
gitSync: configInput.gitSync,
|
|
565
|
+
});
|
|
566
|
+
// Load the created config
|
|
567
|
+
const config = await loadRAGConfig(configPath);
|
|
568
|
+
// Emit project created event
|
|
569
|
+
emitEvent({
|
|
570
|
+
type: 'project:created',
|
|
571
|
+
data: {
|
|
572
|
+
path: absolutePath,
|
|
573
|
+
name: config.name || path.basename(absolutePath),
|
|
574
|
+
},
|
|
575
|
+
});
|
|
576
|
+
return reply.send({
|
|
577
|
+
success: true,
|
|
578
|
+
path: absolutePath,
|
|
579
|
+
configPath,
|
|
580
|
+
config,
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
catch (error) {
|
|
584
|
+
if (error instanceof z.ZodError) {
|
|
585
|
+
return reply.status(400).send({
|
|
586
|
+
error: 'Invalid config',
|
|
587
|
+
message: error.message,
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
app.log.error(error);
|
|
591
|
+
return reply.status(500).send({
|
|
592
|
+
error: 'Failed to create project',
|
|
593
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
/**
|
|
598
|
+
* GET /api/project/validate
|
|
599
|
+
* Validate a project path without opening it
|
|
600
|
+
*/
|
|
601
|
+
app.get('/validate', {
|
|
602
|
+
schema: {
|
|
603
|
+
querystring: {
|
|
604
|
+
type: 'object',
|
|
605
|
+
required: ['path'],
|
|
606
|
+
properties: {
|
|
607
|
+
path: { type: 'string' },
|
|
608
|
+
},
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
}, async (request, reply) => {
|
|
612
|
+
const { path: projectPath } = request.query;
|
|
613
|
+
app.log.info(`Validating project path: ${projectPath}`);
|
|
614
|
+
try {
|
|
615
|
+
const absolutePath = path.resolve(projectPath);
|
|
616
|
+
app.log.info(`Resolved to: ${absolutePath}`);
|
|
617
|
+
const config = await validateProjectPath(absolutePath);
|
|
618
|
+
return reply.send({
|
|
619
|
+
valid: true,
|
|
620
|
+
name: config.name || path.basename(absolutePath),
|
|
621
|
+
path: absolutePath,
|
|
622
|
+
hasVault: config.vaultPaths.length > 0,
|
|
623
|
+
hasCode: config.code.enabled,
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
catch (error) {
|
|
627
|
+
app.log.error(`Validation error: ${error}`);
|
|
628
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
629
|
+
return reply.send({
|
|
630
|
+
valid: false,
|
|
631
|
+
error: message,
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
/**
|
|
636
|
+
* POST /api/project/browse
|
|
637
|
+
* Open native file/folder dialog and return selected path
|
|
638
|
+
*/
|
|
639
|
+
app.post('/browse', {
|
|
640
|
+
schema: {
|
|
641
|
+
body: {
|
|
642
|
+
type: 'object',
|
|
643
|
+
properties: {
|
|
644
|
+
type: { type: 'string', enum: ['file', 'folder'] },
|
|
645
|
+
},
|
|
646
|
+
},
|
|
647
|
+
},
|
|
648
|
+
}, async (request, reply) => {
|
|
649
|
+
const { type = 'folder' } = request.body || {};
|
|
650
|
+
try {
|
|
651
|
+
// Use osascript for native macOS dialog
|
|
652
|
+
const script = type === 'folder'
|
|
653
|
+
? 'osascript -e \'tell application "System Events" to activate\' -e \'POSIX path of (choose folder with prompt "Select folder")\''
|
|
654
|
+
: 'osascript -e \'tell application "System Events" to activate\' -e \'POSIX path of (choose file with prompt "Select file")\'';
|
|
655
|
+
const { stdout } = await execAsync(script);
|
|
656
|
+
const selectedPath = stdout.trim();
|
|
657
|
+
if (!selectedPath) {
|
|
658
|
+
return reply.send({ cancelled: true });
|
|
659
|
+
}
|
|
660
|
+
return reply.send({ path: selectedPath });
|
|
661
|
+
}
|
|
662
|
+
catch (error) {
|
|
663
|
+
// User cancelled dialog (error code -128)
|
|
664
|
+
if (error instanceof Error && error.message.includes('-128')) {
|
|
665
|
+
return reply.send({ cancelled: true });
|
|
666
|
+
}
|
|
667
|
+
app.log.error(error);
|
|
668
|
+
return reply.status(500).send({
|
|
669
|
+
error: 'Failed to open dialog',
|
|
670
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
//# sourceMappingURL=project.js.map
|