sidebar-md 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +205 -0
- package/dist/server/annotation-ops.d.ts +104 -0
- package/dist/server/annotation-ops.js +166 -0
- package/dist/server/annotation-ops.js.map +1 -0
- package/dist/server/args.d.ts +20 -0
- package/dist/server/args.js +118 -0
- package/dist/server/args.js.map +1 -0
- package/dist/server/author.d.ts +1 -0
- package/dist/server/author.js +45 -0
- package/dist/server/author.js.map +1 -0
- package/dist/server/cli.d.ts +2 -0
- package/dist/server/cli.js +364 -0
- package/dist/server/cli.js.map +1 -0
- package/dist/server/config/gitignore.d.ts +10 -0
- package/dist/server/config/gitignore.js +53 -0
- package/dist/server/config/gitignore.js.map +1 -0
- package/dist/server/config/index.d.ts +5 -0
- package/dist/server/config/index.js +5 -0
- package/dist/server/config/index.js.map +1 -0
- package/dist/server/config/load.d.ts +21 -0
- package/dist/server/config/load.js +106 -0
- package/dist/server/config/load.js.map +1 -0
- package/dist/server/config/paths.d.ts +9 -0
- package/dist/server/config/paths.js +26 -0
- package/dist/server/config/paths.js.map +1 -0
- package/dist/server/config/schema.d.ts +26 -0
- package/dist/server/config/schema.js +56 -0
- package/dist/server/config/schema.js.map +1 -0
- package/dist/server/config/write.d.ts +29 -0
- package/dist/server/config/write.js +74 -0
- package/dist/server/config/write.js.map +1 -0
- package/dist/server/connection-file.d.ts +22 -0
- package/dist/server/connection-file.js +72 -0
- package/dist/server/connection-file.js.map +1 -0
- package/dist/server/dirty-buffer.d.ts +7 -0
- package/dist/server/dirty-buffer.js +39 -0
- package/dist/server/dirty-buffer.js.map +1 -0
- package/dist/server/files.d.ts +19 -0
- package/dist/server/files.js +112 -0
- package/dist/server/files.js.map +1 -0
- package/dist/server/hash.d.ts +1 -0
- package/dist/server/hash.js +7 -0
- package/dist/server/hash.js.map +1 -0
- package/dist/server/init.d.ts +16 -0
- package/dist/server/init.js +53 -0
- package/dist/server/init.js.map +1 -0
- package/dist/server/log.d.ts +8 -0
- package/dist/server/log.js +19 -0
- package/dist/server/log.js.map +1 -0
- package/dist/server/marker-ids.d.ts +3 -0
- package/dist/server/marker-ids.js +31 -0
- package/dist/server/marker-ids.js.map +1 -0
- package/dist/server/mcp-server.d.ts +22 -0
- package/dist/server/mcp-server.js +469 -0
- package/dist/server/mcp-server.js.map +1 -0
- package/dist/server/mention-ops.d.ts +115 -0
- package/dist/server/mention-ops.js +202 -0
- package/dist/server/mention-ops.js.map +1 -0
- package/dist/server/mention-store.d.ts +123 -0
- package/dist/server/mention-store.js +91 -0
- package/dist/server/mention-store.js.map +1 -0
- package/dist/server/runtime-check.d.ts +1 -0
- package/dist/server/runtime-check.js +10 -0
- package/dist/server/runtime-check.js.map +1 -0
- package/dist/server/server.d.ts +28 -0
- package/dist/server/server.js +736 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/stdio.d.ts +18 -0
- package/dist/server/stdio.js +144 -0
- package/dist/server/stdio.js.map +1 -0
- package/dist/server/verbs/builtin.d.ts +16 -0
- package/dist/server/verbs/builtin.js +27 -0
- package/dist/server/verbs/builtin.js.map +1 -0
- package/dist/server/verbs/index.d.ts +2 -0
- package/dist/server/verbs/index.js +3 -0
- package/dist/server/verbs/index.js.map +1 -0
- package/dist/server/verbs/load.d.ts +7 -0
- package/dist/server/verbs/load.js +24 -0
- package/dist/server/verbs/load.js.map +1 -0
- package/dist/server/workspace.d.ts +19 -0
- package/dist/server/workspace.js +138 -0
- package/dist/server/workspace.js.map +1 -0
- package/dist/shared/backoff.d.ts +1 -0
- package/dist/shared/backoff.js +12 -0
- package/dist/shared/backoff.js.map +1 -0
- package/dist/shared/markers.d.ts +136 -0
- package/dist/shared/markers.js +497 -0
- package/dist/shared/markers.js.map +1 -0
- package/dist/shared/protocol.d.ts +201 -0
- package/dist/shared/protocol.js +4 -0
- package/dist/shared/protocol.js.map +1 -0
- package/dist/static/assets/apl-B4CMkyY2.js +2 -0
- package/dist/static/assets/apl-B4CMkyY2.js.map +1 -0
- package/dist/static/assets/asciiarmor-Df11BRmG.js +2 -0
- package/dist/static/assets/asciiarmor-Df11BRmG.js.map +1 -0
- package/dist/static/assets/asn1-EdZsLKOL.js +2 -0
- package/dist/static/assets/asn1-EdZsLKOL.js.map +1 -0
- package/dist/static/assets/asterisk-B-8jnY81.js +2 -0
- package/dist/static/assets/asterisk-B-8jnY81.js.map +1 -0
- package/dist/static/assets/brainfuck-C4LP7Hcl.js +2 -0
- package/dist/static/assets/brainfuck-C4LP7Hcl.js.map +1 -0
- package/dist/static/assets/clike-B9uivgTg.js +2 -0
- package/dist/static/assets/clike-B9uivgTg.js.map +1 -0
- package/dist/static/assets/clojure-BMjYHr_A.js +2 -0
- package/dist/static/assets/clojure-BMjYHr_A.js.map +1 -0
- package/dist/static/assets/cmake-BQqOBYOt.js +2 -0
- package/dist/static/assets/cmake-BQqOBYOt.js.map +1 -0
- package/dist/static/assets/cobol-CWcv1MsR.js +2 -0
- package/dist/static/assets/cobol-CWcv1MsR.js.map +1 -0
- package/dist/static/assets/coffeescript-S37ZYGWr.js +2 -0
- package/dist/static/assets/coffeescript-S37ZYGWr.js.map +1 -0
- package/dist/static/assets/commonlisp-DBKNyK5s.js +2 -0
- package/dist/static/assets/commonlisp-DBKNyK5s.js.map +1 -0
- package/dist/static/assets/crystal-SjHAIU92.js +2 -0
- package/dist/static/assets/crystal-SjHAIU92.js.map +1 -0
- package/dist/static/assets/css-BnMrqG3P.js +2 -0
- package/dist/static/assets/css-BnMrqG3P.js.map +1 -0
- package/dist/static/assets/cypher-C_CwsFkJ.js +2 -0
- package/dist/static/assets/cypher-C_CwsFkJ.js.map +1 -0
- package/dist/static/assets/d-pRatUO7H.js +2 -0
- package/dist/static/assets/d-pRatUO7H.js.map +1 -0
- package/dist/static/assets/diff-DbItnlRl.js +2 -0
- package/dist/static/assets/diff-DbItnlRl.js.map +1 -0
- package/dist/static/assets/dockerfile-BKs6k2Af.js +2 -0
- package/dist/static/assets/dockerfile-BKs6k2Af.js.map +1 -0
- package/dist/static/assets/dtd-DF_7sFjM.js +2 -0
- package/dist/static/assets/dtd-DF_7sFjM.js.map +1 -0
- package/dist/static/assets/dylan-DwRh75JA.js +2 -0
- package/dist/static/assets/dylan-DwRh75JA.js.map +1 -0
- package/dist/static/assets/ebnf-CDyGwa7X.js +2 -0
- package/dist/static/assets/ebnf-CDyGwa7X.js.map +1 -0
- package/dist/static/assets/ecl-Cabwm37j.js +2 -0
- package/dist/static/assets/ecl-Cabwm37j.js.map +1 -0
- package/dist/static/assets/eiffel-CnydiIhH.js +2 -0
- package/dist/static/assets/eiffel-CnydiIhH.js.map +1 -0
- package/dist/static/assets/elm-vLlmbW-K.js +2 -0
- package/dist/static/assets/elm-vLlmbW-K.js.map +1 -0
- package/dist/static/assets/erlang-BNw1qcRV.js +2 -0
- package/dist/static/assets/erlang-BNw1qcRV.js.map +1 -0
- package/dist/static/assets/factor-kuTfRLto.js +2 -0
- package/dist/static/assets/factor-kuTfRLto.js.map +1 -0
- package/dist/static/assets/fcl-Kvtd6kyn.js +2 -0
- package/dist/static/assets/fcl-Kvtd6kyn.js.map +1 -0
- package/dist/static/assets/forth-Ffai-XNe.js +2 -0
- package/dist/static/assets/forth-Ffai-XNe.js.map +1 -0
- package/dist/static/assets/fortran-DYz_wnZ1.js +2 -0
- package/dist/static/assets/fortran-DYz_wnZ1.js.map +1 -0
- package/dist/static/assets/gas-Bneqetm1.js +2 -0
- package/dist/static/assets/gas-Bneqetm1.js.map +1 -0
- package/dist/static/assets/gherkin-heZmZLOM.js +2 -0
- package/dist/static/assets/gherkin-heZmZLOM.js.map +1 -0
- package/dist/static/assets/groovy-D9Dt4D0W.js +2 -0
- package/dist/static/assets/groovy-D9Dt4D0W.js.map +1 -0
- package/dist/static/assets/haskell-BWDZoCOh.js +2 -0
- package/dist/static/assets/haskell-BWDZoCOh.js.map +1 -0
- package/dist/static/assets/haxe-H-WmDvRZ.js +2 -0
- package/dist/static/assets/haxe-H-WmDvRZ.js.map +1 -0
- package/dist/static/assets/http-DBlCnlav.js +2 -0
- package/dist/static/assets/http-DBlCnlav.js.map +1 -0
- package/dist/static/assets/idl-BEugSyMb.js +2 -0
- package/dist/static/assets/idl-BEugSyMb.js.map +1 -0
- package/dist/static/assets/index-76gOt96S.js +2 -0
- package/dist/static/assets/index-76gOt96S.js.map +1 -0
- package/dist/static/assets/index-BOQmpwuG.js +2 -0
- package/dist/static/assets/index-BOQmpwuG.js.map +1 -0
- package/dist/static/assets/index-BRr3mRH4.js +2 -0
- package/dist/static/assets/index-BRr3mRH4.js.map +1 -0
- package/dist/static/assets/index-B_hEIVV3.js +2 -0
- package/dist/static/assets/index-B_hEIVV3.js.map +1 -0
- package/dist/static/assets/index-Be89YI4R.js +2 -0
- package/dist/static/assets/index-Be89YI4R.js.map +1 -0
- package/dist/static/assets/index-BiZobR_v.js +4 -0
- package/dist/static/assets/index-BiZobR_v.js.map +1 -0
- package/dist/static/assets/index-Brumy5_9.js +8 -0
- package/dist/static/assets/index-Brumy5_9.js.map +1 -0
- package/dist/static/assets/index-BsJm14K9.js +2 -0
- package/dist/static/assets/index-BsJm14K9.js.map +1 -0
- package/dist/static/assets/index-CTGcuUyU.js +2 -0
- package/dist/static/assets/index-CTGcuUyU.js.map +1 -0
- package/dist/static/assets/index-Cvxvsst9.js +2 -0
- package/dist/static/assets/index-Cvxvsst9.js.map +1 -0
- package/dist/static/assets/index-D6ORLFAQ.js +2 -0
- package/dist/static/assets/index-D6ORLFAQ.js.map +1 -0
- package/dist/static/assets/index-DEhB0VAu.js +3 -0
- package/dist/static/assets/index-DEhB0VAu.js.map +1 -0
- package/dist/static/assets/index-DTNng05d.js +2 -0
- package/dist/static/assets/index-DTNng05d.js.map +1 -0
- package/dist/static/assets/index-DUOyyduC.js +2 -0
- package/dist/static/assets/index-DUOyyduC.js.map +1 -0
- package/dist/static/assets/index-DaO1DHpW.js +101 -0
- package/dist/static/assets/index-DaO1DHpW.js.map +1 -0
- package/dist/static/assets/index-DjRybwG9.js +2 -0
- package/dist/static/assets/index-DjRybwG9.js.map +1 -0
- package/dist/static/assets/index-MU4h_pJS.js +2 -0
- package/dist/static/assets/index-MU4h_pJS.js.map +1 -0
- package/dist/static/assets/index-PYTD2O0j.js +2 -0
- package/dist/static/assets/index-PYTD2O0j.js.map +1 -0
- package/dist/static/assets/index-SfxJH5Y4.css +1 -0
- package/dist/static/assets/javascript-qCveANmP.js +2 -0
- package/dist/static/assets/javascript-qCveANmP.js.map +1 -0
- package/dist/static/assets/julia-DuME0IfC.js +2 -0
- package/dist/static/assets/julia-DuME0IfC.js.map +1 -0
- package/dist/static/assets/livescript-BwQOo05w.js +2 -0
- package/dist/static/assets/livescript-BwQOo05w.js.map +1 -0
- package/dist/static/assets/lua-BgMRiT3U.js +2 -0
- package/dist/static/assets/lua-BgMRiT3U.js.map +1 -0
- package/dist/static/assets/mathematica-DTrFuWx2.js +2 -0
- package/dist/static/assets/mathematica-DTrFuWx2.js.map +1 -0
- package/dist/static/assets/mbox-CNhZ1qSd.js +2 -0
- package/dist/static/assets/mbox-CNhZ1qSd.js.map +1 -0
- package/dist/static/assets/mirc-CjQqDB4T.js +2 -0
- package/dist/static/assets/mirc-CjQqDB4T.js.map +1 -0
- package/dist/static/assets/mllike-CXdrOF99.js +2 -0
- package/dist/static/assets/mllike-CXdrOF99.js.map +1 -0
- package/dist/static/assets/modelica-Dc1JOy9r.js +2 -0
- package/dist/static/assets/modelica-Dc1JOy9r.js.map +1 -0
- package/dist/static/assets/mscgen-BA5vi2Kp.js +2 -0
- package/dist/static/assets/mscgen-BA5vi2Kp.js.map +1 -0
- package/dist/static/assets/mumps-BT43cFF4.js +2 -0
- package/dist/static/assets/mumps-BT43cFF4.js.map +1 -0
- package/dist/static/assets/nginx-DdIZxoE0.js +2 -0
- package/dist/static/assets/nginx-DdIZxoE0.js.map +1 -0
- package/dist/static/assets/nsis-LdVXkNf5.js +2 -0
- package/dist/static/assets/nsis-LdVXkNf5.js.map +1 -0
- package/dist/static/assets/ntriples-BfvgReVJ.js +2 -0
- package/dist/static/assets/ntriples-BfvgReVJ.js.map +1 -0
- package/dist/static/assets/octave-Ck1zUtKM.js +2 -0
- package/dist/static/assets/octave-Ck1zUtKM.js.map +1 -0
- package/dist/static/assets/oz-BzwKVEFT.js +2 -0
- package/dist/static/assets/oz-BzwKVEFT.js.map +1 -0
- package/dist/static/assets/pascal--L3eBynH.js +2 -0
- package/dist/static/assets/pascal--L3eBynH.js.map +1 -0
- package/dist/static/assets/perl-CdXCOZ3F.js +2 -0
- package/dist/static/assets/perl-CdXCOZ3F.js.map +1 -0
- package/dist/static/assets/pig-CevX1Tat.js +2 -0
- package/dist/static/assets/pig-CevX1Tat.js.map +1 -0
- package/dist/static/assets/powershell-CFHJl5sT.js +2 -0
- package/dist/static/assets/powershell-CFHJl5sT.js.map +1 -0
- package/dist/static/assets/properties-C78fOPTZ.js +2 -0
- package/dist/static/assets/properties-C78fOPTZ.js.map +1 -0
- package/dist/static/assets/protobuf-ChK-085T.js +2 -0
- package/dist/static/assets/protobuf-ChK-085T.js.map +1 -0
- package/dist/static/assets/pug-DukmZTjD.js +2 -0
- package/dist/static/assets/pug-DukmZTjD.js.map +1 -0
- package/dist/static/assets/puppet-DMA9R1ak.js +2 -0
- package/dist/static/assets/puppet-DMA9R1ak.js.map +1 -0
- package/dist/static/assets/python-BuPzkPfP.js +2 -0
- package/dist/static/assets/python-BuPzkPfP.js.map +1 -0
- package/dist/static/assets/q-pXgVlZs6.js +2 -0
- package/dist/static/assets/q-pXgVlZs6.js.map +1 -0
- package/dist/static/assets/r-DUYO_cvP.js +2 -0
- package/dist/static/assets/r-DUYO_cvP.js.map +1 -0
- package/dist/static/assets/rpm-CTu-6PCP.js +2 -0
- package/dist/static/assets/rpm-CTu-6PCP.js.map +1 -0
- package/dist/static/assets/ruby-B2Rjki9n.js +2 -0
- package/dist/static/assets/ruby-B2Rjki9n.js.map +1 -0
- package/dist/static/assets/sas-B4kiWyti.js +2 -0
- package/dist/static/assets/sas-B4kiWyti.js.map +1 -0
- package/dist/static/assets/scheme-C41bIUwD.js +2 -0
- package/dist/static/assets/scheme-C41bIUwD.js.map +1 -0
- package/dist/static/assets/shell-CjFT_Tl9.js +2 -0
- package/dist/static/assets/shell-CjFT_Tl9.js.map +1 -0
- package/dist/static/assets/sieve-C3Gn_uJK.js +2 -0
- package/dist/static/assets/sieve-C3Gn_uJK.js.map +1 -0
- package/dist/static/assets/simple-mode-GW_nhZxv.js +2 -0
- package/dist/static/assets/simple-mode-GW_nhZxv.js.map +1 -0
- package/dist/static/assets/smalltalk-CnHTOXQT.js +2 -0
- package/dist/static/assets/smalltalk-CnHTOXQT.js.map +1 -0
- package/dist/static/assets/solr-DehyRSwq.js +2 -0
- package/dist/static/assets/solr-DehyRSwq.js.map +1 -0
- package/dist/static/assets/sparql-DkYu6x3z.js +2 -0
- package/dist/static/assets/sparql-DkYu6x3z.js.map +1 -0
- package/dist/static/assets/spreadsheet-BCZA_wO0.js +2 -0
- package/dist/static/assets/spreadsheet-BCZA_wO0.js.map +1 -0
- package/dist/static/assets/sql-D0XecflT.js +2 -0
- package/dist/static/assets/sql-D0XecflT.js.map +1 -0
- package/dist/static/assets/stex-C3f8Ysf7.js +2 -0
- package/dist/static/assets/stex-C3f8Ysf7.js.map +1 -0
- package/dist/static/assets/stylus-B533Al4x.js +2 -0
- package/dist/static/assets/stylus-B533Al4x.js.map +1 -0
- package/dist/static/assets/swift-BzpIVaGY.js +2 -0
- package/dist/static/assets/swift-BzpIVaGY.js.map +1 -0
- package/dist/static/assets/tcl-DVfN8rqt.js +2 -0
- package/dist/static/assets/tcl-DVfN8rqt.js.map +1 -0
- package/dist/static/assets/textile-CnDTJFAw.js +2 -0
- package/dist/static/assets/textile-CnDTJFAw.js.map +1 -0
- package/dist/static/assets/tiddlywiki-DO-Gjzrf.js +2 -0
- package/dist/static/assets/tiddlywiki-DO-Gjzrf.js.map +1 -0
- package/dist/static/assets/tiki-DGYXhP31.js +2 -0
- package/dist/static/assets/tiki-DGYXhP31.js.map +1 -0
- package/dist/static/assets/toml-Bm5Em-hy.js +2 -0
- package/dist/static/assets/toml-Bm5Em-hy.js.map +1 -0
- package/dist/static/assets/troff-wAsdV37c.js +2 -0
- package/dist/static/assets/troff-wAsdV37c.js.map +1 -0
- package/dist/static/assets/ttcn-CfJYG6tj.js +2 -0
- package/dist/static/assets/ttcn-CfJYG6tj.js.map +1 -0
- package/dist/static/assets/ttcn-cfg-B9xdYoR4.js +2 -0
- package/dist/static/assets/ttcn-cfg-B9xdYoR4.js.map +1 -0
- package/dist/static/assets/turtle-B1tBg_DP.js +2 -0
- package/dist/static/assets/turtle-B1tBg_DP.js.map +1 -0
- package/dist/static/assets/vb-CmGdzxic.js +2 -0
- package/dist/static/assets/vb-CmGdzxic.js.map +1 -0
- package/dist/static/assets/vbscript-BuJXcnF6.js +2 -0
- package/dist/static/assets/vbscript-BuJXcnF6.js.map +1 -0
- package/dist/static/assets/velocity-D8B20fx6.js +2 -0
- package/dist/static/assets/velocity-D8B20fx6.js.map +1 -0
- package/dist/static/assets/verilog-C6RDOZhf.js +2 -0
- package/dist/static/assets/verilog-C6RDOZhf.js.map +1 -0
- package/dist/static/assets/vhdl-lSbBsy5d.js +2 -0
- package/dist/static/assets/vhdl-lSbBsy5d.js.map +1 -0
- package/dist/static/assets/webidl-ZXfAyPTL.js +2 -0
- package/dist/static/assets/webidl-ZXfAyPTL.js.map +1 -0
- package/dist/static/assets/xquery-CQfU5ijd.js +2 -0
- package/dist/static/assets/xquery-CQfU5ijd.js.map +1 -0
- package/dist/static/assets/yacas-BJ4BC0dw.js +2 -0
- package/dist/static/assets/yacas-BJ4BC0dw.js.map +1 -0
- package/dist/static/assets/z80-Hz9HOZM7.js +2 -0
- package/dist/static/assets/z80-Hz9HOZM7.js.map +1 -0
- package/dist/static/index.html +14 -0
- package/package.json +89 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/server/config/load.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const SIDEBAR_DIR = ".sidebar";
|
|
2
|
+
export declare const CONFIG_FILE = "config.json";
|
|
3
|
+
export declare const LOCAL_FILE = "local.json";
|
|
4
|
+
export declare const CONFIG_REL = ".sidebar/config.json";
|
|
5
|
+
export declare const LOCAL_REL = ".sidebar/local.json";
|
|
6
|
+
export declare function configPath(cwd: string): string;
|
|
7
|
+
export declare function localPath(cwd: string): string;
|
|
8
|
+
export declare function sidebarDir(cwd: string): string;
|
|
9
|
+
export declare function relFromCwd(cwd: string, abs: string): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { join, relative } from "node:path";
|
|
2
|
+
export const SIDEBAR_DIR = ".sidebar";
|
|
3
|
+
export const CONFIG_FILE = "config.json";
|
|
4
|
+
export const LOCAL_FILE = "local.json";
|
|
5
|
+
// Relative form used in user-visible error messages so they stay short and
|
|
6
|
+
// portable: ".sidebar/local.json" reads the same on every platform.
|
|
7
|
+
export const CONFIG_REL = `${SIDEBAR_DIR}/${CONFIG_FILE}`;
|
|
8
|
+
export const LOCAL_REL = `${SIDEBAR_DIR}/${LOCAL_FILE}`;
|
|
9
|
+
export function configPath(cwd) {
|
|
10
|
+
return join(cwd, SIDEBAR_DIR, CONFIG_FILE);
|
|
11
|
+
}
|
|
12
|
+
export function localPath(cwd) {
|
|
13
|
+
return join(cwd, SIDEBAR_DIR, LOCAL_FILE);
|
|
14
|
+
}
|
|
15
|
+
export function sidebarDir(cwd) {
|
|
16
|
+
return join(cwd, SIDEBAR_DIR);
|
|
17
|
+
}
|
|
18
|
+
// Relative form rooted at `cwd`. Used in error messages to make sure the
|
|
19
|
+
// reader can act on the path without hunting through tmp prefixes.
|
|
20
|
+
export function relFromCwd(cwd, abs) {
|
|
21
|
+
const r = relative(cwd, abs);
|
|
22
|
+
// Replace any platform separator with posix; the rest of the codebase uses
|
|
23
|
+
// posix in user-visible strings.
|
|
24
|
+
return r.split(/[\\/]/).join("/");
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/server/config/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;AACtC,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC;AAEvC,2EAA2E;AAC3E,oEAAoE;AACpE,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,WAAW,IAAI,WAAW,EAAE,CAAC;AAC1D,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,WAAW,IAAI,UAAU,EAAE,CAAC;AAExD,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;AAChC,CAAC;AAED,yEAAyE;AACzE,mEAAmE;AACnE,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,GAAW;IACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC7B,2EAA2E;IAC3E,iCAAiC;IACjC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const sidebarConfigSchema: z.ZodObject<{
|
|
3
|
+
version: z.ZodLiteral<1>;
|
|
4
|
+
scope: z.ZodOptional<z.ZodString>;
|
|
5
|
+
rateLimit: z.ZodOptional<z.ZodObject<{
|
|
6
|
+
agentMentions: z.ZodOptional<z.ZodObject<{
|
|
7
|
+
maxOpen: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
}, z.core.$strict>>;
|
|
9
|
+
}, z.core.$strict>>;
|
|
10
|
+
verbs: z.ZodOptional<z.ZodObject<{
|
|
11
|
+
human: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
12
|
+
mode: z.ZodEnum<{
|
|
13
|
+
replace: "replace";
|
|
14
|
+
annotation: "annotation";
|
|
15
|
+
}>;
|
|
16
|
+
}, z.core.$strict>>>;
|
|
17
|
+
agent: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{}, z.core.$strict>>>;
|
|
18
|
+
}, z.core.$strict>>;
|
|
19
|
+
}, z.core.$strict>;
|
|
20
|
+
export declare const sidebarLocalSchema: z.ZodObject<{
|
|
21
|
+
version: z.ZodLiteral<1>;
|
|
22
|
+
port: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
browser: z.ZodOptional<z.ZodString>;
|
|
24
|
+
}, z.core.$strict>;
|
|
25
|
+
export type SidebarConfigFile = z.infer<typeof sidebarConfigSchema>;
|
|
26
|
+
export type SidebarLocalFile = z.infer<typeof sidebarLocalSchema>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { VERB_NAME_PATTERN } from "../verbs/builtin.js";
|
|
3
|
+
// .sidebar/config.json — committed, team-shared. Spec: Configuration /
|
|
4
|
+
// `.sidebar/config.json`. Strict object schema: unknown keys reject.
|
|
5
|
+
//
|
|
6
|
+
// .sidebar/local.json — gitignored, per-machine. Spec: Configuration /
|
|
7
|
+
// `.sidebar/local.json`. Strict object schema: unknown keys reject.
|
|
8
|
+
//
|
|
9
|
+
// Built-in-verb redefinition is enforced in load.ts after schema parsing so
|
|
10
|
+
// the error message can name the offending verb in its dotted path; zod's
|
|
11
|
+
// per-record-key refinement is awkward to thread cleanly here.
|
|
12
|
+
const verbNameSchema = z
|
|
13
|
+
.string()
|
|
14
|
+
.regex(VERB_NAME_PATTERN, "verb name must match /^[a-z][a-z0-9-]*$/");
|
|
15
|
+
const humanVerbBodySchema = z
|
|
16
|
+
.object({
|
|
17
|
+
mode: z.enum(["replace", "annotation"]),
|
|
18
|
+
})
|
|
19
|
+
.strict();
|
|
20
|
+
const agentVerbBodySchema = z.object({}).strict();
|
|
21
|
+
const verbsSchema = z
|
|
22
|
+
.object({
|
|
23
|
+
human: z.record(verbNameSchema, humanVerbBodySchema).optional(),
|
|
24
|
+
agent: z.record(verbNameSchema, agentVerbBodySchema).optional(),
|
|
25
|
+
})
|
|
26
|
+
.strict();
|
|
27
|
+
export const sidebarConfigSchema = z
|
|
28
|
+
.object({
|
|
29
|
+
version: z.literal(1, {
|
|
30
|
+
message: "version must be 1 (V2 migration hook; other values rejected)",
|
|
31
|
+
}),
|
|
32
|
+
scope: z.string().min(1).optional(),
|
|
33
|
+
rateLimit: z
|
|
34
|
+
.object({
|
|
35
|
+
agentMentions: z
|
|
36
|
+
.object({
|
|
37
|
+
maxOpen: z.number().int().min(0).max(1000).optional(),
|
|
38
|
+
})
|
|
39
|
+
.strict()
|
|
40
|
+
.optional(),
|
|
41
|
+
})
|
|
42
|
+
.strict()
|
|
43
|
+
.optional(),
|
|
44
|
+
verbs: verbsSchema.optional(),
|
|
45
|
+
})
|
|
46
|
+
.strict();
|
|
47
|
+
export const sidebarLocalSchema = z
|
|
48
|
+
.object({
|
|
49
|
+
version: z.literal(1, {
|
|
50
|
+
message: "version must be 1 (V2 migration hook; other values rejected)",
|
|
51
|
+
}),
|
|
52
|
+
port: z.number().int().min(0).max(65_535).optional(),
|
|
53
|
+
browser: z.string().min(1).optional(),
|
|
54
|
+
})
|
|
55
|
+
.strict();
|
|
56
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/server/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,uEAAuE;AACvE,qEAAqE;AACrE,EAAE;AACF,uEAAuE;AACvE,oEAAoE;AACpE,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,+DAA+D;AAE/D,MAAM,cAAc,GAAG,CAAC;KACrB,MAAM,EAAE;KACR,KAAK,CAAC,iBAAiB,EAAE,0CAA0C,CAAC,CAAC;AAExE,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;CACxC,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAElD,MAAM,WAAW,GAAG,CAAC;KAClB,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,QAAQ,EAAE;IAC/D,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,QAAQ,EAAE;CAChE,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KACjC,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;QACpB,OAAO,EAAE,8DAA8D;KACxE,CAAC;IACF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACnC,SAAS,EAAE,CAAC;SACT,MAAM,CAAC;QACN,aAAa,EAAE,CAAC;aACb,MAAM,CAAC;YACN,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;SACtD,CAAC;aACD,MAAM,EAAE;aACR,QAAQ,EAAE;KACd,CAAC;SACD,MAAM,EAAE;SACR,QAAQ,EAAE;IACb,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE;CAC9B,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;QACpB,OAAO,EAAE,8DAA8D;KACxE,CAAC;IACF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IACpD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACtC,CAAC;KACD,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { CONFIG_REL, LOCAL_REL } from "./paths.js";
|
|
2
|
+
import { type SidebarConfigFile, type SidebarLocalFile } from "./schema.js";
|
|
3
|
+
export type GitignoreConsent = (info: {
|
|
4
|
+
gitignorePath: string;
|
|
5
|
+
}) => Promise<boolean> | boolean;
|
|
6
|
+
export type GitignoreAction =
|
|
7
|
+
/** No `.git/` directory at `cwd`; we don't manage gitignore in that case. */
|
|
8
|
+
"absent"
|
|
9
|
+
/** local.json is already ignored; no-op. */
|
|
10
|
+
| "already-ignored"
|
|
11
|
+
/** Consent was granted and the line was appended (or .gitignore was created). */
|
|
12
|
+
| "appended"
|
|
13
|
+
/** Consent callback returned false; we proceed without touching .gitignore. */
|
|
14
|
+
| "declined"
|
|
15
|
+
/** No consent callback provided; we proceed without prompting. */
|
|
16
|
+
| "no-prompt";
|
|
17
|
+
export type PersistLocalResult = {
|
|
18
|
+
/** True when local.json did not exist before this write. */
|
|
19
|
+
created: boolean;
|
|
20
|
+
gitignoreAction: GitignoreAction;
|
|
21
|
+
};
|
|
22
|
+
export type PersistConfigResult = {
|
|
23
|
+
created: boolean;
|
|
24
|
+
};
|
|
25
|
+
export declare function persistLocal(cwd: string, patch: Partial<Omit<SidebarLocalFile, "version">>, opts?: {
|
|
26
|
+
consent?: GitignoreConsent;
|
|
27
|
+
}): Promise<PersistLocalResult>;
|
|
28
|
+
export declare function persistConfig(cwd: string, patch: Partial<Omit<SidebarConfigFile, "version">>): Promise<PersistConfigResult>;
|
|
29
|
+
export { CONFIG_REL, LOCAL_REL };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { appendLocalToGitignore, isLocalIgnored } from "./gitignore.js";
|
|
4
|
+
import { CONFIG_REL, LOCAL_REL, configPath, localPath, sidebarDir } from "./paths.js";
|
|
5
|
+
import { sidebarConfigSchema, sidebarLocalSchema, } from "./schema.js";
|
|
6
|
+
export async function persistLocal(cwd, patch, opts = {}) {
|
|
7
|
+
const path = localPath(cwd);
|
|
8
|
+
const existed = existsSync(path);
|
|
9
|
+
const previous = existed
|
|
10
|
+
? await readAndValidate(path, sidebarLocalSchema)
|
|
11
|
+
: null;
|
|
12
|
+
const next = {
|
|
13
|
+
version: 1,
|
|
14
|
+
...(previous ?? {}),
|
|
15
|
+
...patch,
|
|
16
|
+
};
|
|
17
|
+
// Re-validate the merged result so a writer cannot create a file the
|
|
18
|
+
// loader would reject. Catches e.g. callers slipping in a bad port.
|
|
19
|
+
const validated = sidebarLocalSchema.parse(next);
|
|
20
|
+
await mkdir(sidebarDir(cwd), { recursive: true });
|
|
21
|
+
await writeFile(path, `${JSON.stringify(validated, null, 2)}\n`, "utf8");
|
|
22
|
+
// gitignore offer only fires on creation, per the spec ("On creation of
|
|
23
|
+
// .sidebar/local.json, sidebar checks for a .git/ directory ...").
|
|
24
|
+
let gitignoreAction = "no-prompt";
|
|
25
|
+
if (!existed) {
|
|
26
|
+
gitignoreAction = await runGitignoreOffer(cwd, opts.consent);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// For an update, "no-prompt" is the right answer regardless of the
|
|
30
|
+
// current ignore state — we don't re-offer.
|
|
31
|
+
gitignoreAction = "no-prompt";
|
|
32
|
+
}
|
|
33
|
+
return { created: !existed, gitignoreAction };
|
|
34
|
+
}
|
|
35
|
+
export async function persistConfig(cwd, patch) {
|
|
36
|
+
const path = configPath(cwd);
|
|
37
|
+
const existed = existsSync(path);
|
|
38
|
+
const previous = existed
|
|
39
|
+
? await readAndValidate(path, sidebarConfigSchema)
|
|
40
|
+
: null;
|
|
41
|
+
const next = {
|
|
42
|
+
version: 1,
|
|
43
|
+
...(previous ?? {}),
|
|
44
|
+
...patch,
|
|
45
|
+
};
|
|
46
|
+
const validated = sidebarConfigSchema.parse(next);
|
|
47
|
+
await mkdir(sidebarDir(cwd), { recursive: true });
|
|
48
|
+
await writeFile(path, `${JSON.stringify(validated, null, 2)}\n`, "utf8");
|
|
49
|
+
return { created: !existed };
|
|
50
|
+
}
|
|
51
|
+
async function runGitignoreOffer(cwd, consent) {
|
|
52
|
+
if (!existsSync(`${cwd}/.git`))
|
|
53
|
+
return "absent";
|
|
54
|
+
if (isLocalIgnored(cwd))
|
|
55
|
+
return "already-ignored";
|
|
56
|
+
if (!consent)
|
|
57
|
+
return "no-prompt";
|
|
58
|
+
const ok = await consent({ gitignorePath: `${cwd}/.gitignore` });
|
|
59
|
+
if (!ok)
|
|
60
|
+
return "declined";
|
|
61
|
+
await appendLocalToGitignore(cwd);
|
|
62
|
+
return "appended";
|
|
63
|
+
}
|
|
64
|
+
// Read + validate a file we are about to merge into. This is the writer-side
|
|
65
|
+
// equivalent of loadProjectConfig; using the same schema keeps writers from
|
|
66
|
+
// "fixing" a previously invalid file silently.
|
|
67
|
+
async function readAndValidate(path, schema) {
|
|
68
|
+
const raw = await readFile(path, "utf8");
|
|
69
|
+
return schema.parse(JSON.parse(raw));
|
|
70
|
+
}
|
|
71
|
+
// Re-export the file-paths constants for callers that want to surface the
|
|
72
|
+
// path in their own UI text.
|
|
73
|
+
export { CONFIG_REL, LOCAL_REL };
|
|
74
|
+
//# sourceMappingURL=write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../../src/server/config/write.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type ConnectionInfo = {
|
|
2
|
+
version: 1;
|
|
3
|
+
url: string;
|
|
4
|
+
pid: number;
|
|
5
|
+
started_at: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function connectionFilePath(cwd: string): string;
|
|
8
|
+
export declare function writeConnectionFile(cwd: string, info: ConnectionInfo): Promise<void>;
|
|
9
|
+
export declare function removeConnectionFile(cwd: string): Promise<void>;
|
|
10
|
+
export type ConnectionProbe = {
|
|
11
|
+
kind: "absent";
|
|
12
|
+
} | {
|
|
13
|
+
kind: "stale";
|
|
14
|
+
info: ConnectionInfo;
|
|
15
|
+
} | {
|
|
16
|
+
kind: "malformed";
|
|
17
|
+
} | {
|
|
18
|
+
kind: "alive";
|
|
19
|
+
info: ConnectionInfo;
|
|
20
|
+
};
|
|
21
|
+
export declare function probeConnectionFile(cwd: string): Promise<ConnectionProbe>;
|
|
22
|
+
export declare function isPidAlive(pid: number): boolean;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, readFile, unlink, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { log } from "./log.js";
|
|
5
|
+
export function connectionFilePath(cwd) {
|
|
6
|
+
return join(cwd, ".sidebar", "connection.json");
|
|
7
|
+
}
|
|
8
|
+
export async function writeConnectionFile(cwd, info) {
|
|
9
|
+
await mkdir(join(cwd, ".sidebar"), { recursive: true });
|
|
10
|
+
// `writeFile` with the default flag is fine here: the file is process-local
|
|
11
|
+
// discovery, not configuration. A stale file is intentionally overwritten.
|
|
12
|
+
await writeFile(connectionFilePath(cwd), `${JSON.stringify(info, null, 2)}\n`, "utf8");
|
|
13
|
+
}
|
|
14
|
+
export async function removeConnectionFile(cwd) {
|
|
15
|
+
try {
|
|
16
|
+
await unlink(connectionFilePath(cwd));
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
if (e.code !== "ENOENT") {
|
|
20
|
+
log.warn(`failed to remove connection.json: ${e.message}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export async function probeConnectionFile(cwd) {
|
|
25
|
+
const path = connectionFilePath(cwd);
|
|
26
|
+
if (!existsSync(path))
|
|
27
|
+
return { kind: "absent" };
|
|
28
|
+
let raw;
|
|
29
|
+
try {
|
|
30
|
+
raw = await readFile(path, "utf8");
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return { kind: "absent" };
|
|
34
|
+
}
|
|
35
|
+
let parsed;
|
|
36
|
+
try {
|
|
37
|
+
parsed = JSON.parse(raw);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return { kind: "malformed" };
|
|
41
|
+
}
|
|
42
|
+
if (!isConnectionInfo(parsed))
|
|
43
|
+
return { kind: "malformed" };
|
|
44
|
+
if (isPidAlive(parsed.pid))
|
|
45
|
+
return { kind: "alive", info: parsed };
|
|
46
|
+
return { kind: "stale", info: parsed };
|
|
47
|
+
}
|
|
48
|
+
function isConnectionInfo(v) {
|
|
49
|
+
if (!v || typeof v !== "object")
|
|
50
|
+
return false;
|
|
51
|
+
const c = v;
|
|
52
|
+
return (c.version === 1 &&
|
|
53
|
+
typeof c.url === "string" &&
|
|
54
|
+
typeof c.pid === "number" &&
|
|
55
|
+
typeof c.started_at === "string");
|
|
56
|
+
}
|
|
57
|
+
// `process.kill(pid, 0)` does not send a signal; it only checks reachability.
|
|
58
|
+
// Throws ESRCH for dead pids and EPERM if the caller lacks permission (in
|
|
59
|
+
// which case the pid is still alive — treat that as "alive" so we never race
|
|
60
|
+
// a foreign primary into a duplicate bind).
|
|
61
|
+
export function isPidAlive(pid) {
|
|
62
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
63
|
+
return false;
|
|
64
|
+
try {
|
|
65
|
+
process.kill(pid, 0);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
return e.code === "EPERM";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=connection-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-file.js","sourceRoot":"","sources":["../../src/server/connection-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type DirtyBufferTracker = {
|
|
2
|
+
setDirty: (path: string, isDirty: boolean) => void;
|
|
3
|
+
isDirty: (path: string) => boolean;
|
|
4
|
+
draftAgeSeconds: (path: string) => number;
|
|
5
|
+
clearAll: () => void;
|
|
6
|
+
};
|
|
7
|
+
export declare function createDirtyBufferTracker(now?: () => number): DirtyBufferTracker;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Tracks the editor's dirty-buffer state per workspace file path.
|
|
2
|
+
//
|
|
3
|
+
// The CodeMirror editor in the browser holds the source of truth for buffer
|
|
4
|
+
// state; it pushes a `dirty` notification over the WebSocket whenever the
|
|
5
|
+
// dirty status of a path flips. The MCP `read_doc` tool reads from this
|
|
6
|
+
// store to populate `is_draft` and `draft_age_seconds`.
|
|
7
|
+
//
|
|
8
|
+
// State is process-local and transient (Q15 / ADR-0005). Disconnect of the
|
|
9
|
+
// last editor tab clears everything: a draft only exists while an editor is
|
|
10
|
+
// holding it.
|
|
11
|
+
export function createDirtyBufferTracker(now = Date.now) {
|
|
12
|
+
// Stores the timestamp at which the path went dirty. Removing the entry
|
|
13
|
+
// means the buffer is clean.
|
|
14
|
+
const dirtyAt = new Map();
|
|
15
|
+
return {
|
|
16
|
+
setDirty(path, isDirty) {
|
|
17
|
+
if (isDirty) {
|
|
18
|
+
if (!dirtyAt.has(path))
|
|
19
|
+
dirtyAt.set(path, now());
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
dirtyAt.delete(path);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
isDirty(path) {
|
|
26
|
+
return dirtyAt.has(path);
|
|
27
|
+
},
|
|
28
|
+
draftAgeSeconds(path) {
|
|
29
|
+
const t = dirtyAt.get(path);
|
|
30
|
+
if (t === undefined)
|
|
31
|
+
return 0;
|
|
32
|
+
return Math.max(0, Math.floor((now() - t) / 1000));
|
|
33
|
+
},
|
|
34
|
+
clearAll() {
|
|
35
|
+
dirtyAt.clear();
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=dirty-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dirty-buffer.js","sourceRoot":"","sources":["../../src/server/dirty-buffer.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,wEAAwE;AACxE,wDAAwD;AACxD,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,cAAc;AASd,MAAM,UAAU,wBAAwB,CAAC,MAAoB,IAAI,CAAC,GAAG;IACnE,wEAAwE;IACxE,6BAA6B;IAC7B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,OAAO;QACL,QAAQ,CAAC,IAAI,EAAE,OAAO;YACpB,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QACD,OAAO,CAAC,IAAI;YACV,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,eAAe,CAAC,IAAI;YAClB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK,SAAS;gBAAE,OAAO,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QACrD,CAAC;QACD,QAAQ;YACN,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Workspace } from "./workspace.js";
|
|
2
|
+
export type ReadResult = {
|
|
3
|
+
content: string;
|
|
4
|
+
hash: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function readWorkspaceFile(ws: Workspace, relPath: string): Promise<ReadResult>;
|
|
7
|
+
export type SaveOutcome = {
|
|
8
|
+
kind: "saved";
|
|
9
|
+
hash: string;
|
|
10
|
+
} | {
|
|
11
|
+
kind: "conflict";
|
|
12
|
+
diskHash: string;
|
|
13
|
+
content: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function saveWorkspaceFile(ws: Workspace, relPath: string, content: string, baseHash: string): Promise<SaveOutcome>;
|
|
16
|
+
export declare function createFile(ws: Workspace, parent: string, name: string): Promise<string>;
|
|
17
|
+
export declare function createFolder(ws: Workspace, parent: string, name: string): Promise<string>;
|
|
18
|
+
export declare function renamePath(ws: Workspace, from: string, to: string): Promise<void>;
|
|
19
|
+
export declare function deletePath(ws: Workspace, relPath: string): Promise<void>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, posix } from "node:path";
|
|
3
|
+
import { sha256 } from "./hash.js";
|
|
4
|
+
export async function readWorkspaceFile(ws, relPath) {
|
|
5
|
+
const safe = assertSafeRel(relPath);
|
|
6
|
+
assertInScope(ws, safe);
|
|
7
|
+
const content = await readFile(ws.toAbs(safe), "utf8");
|
|
8
|
+
return { content, hash: sha256(content) };
|
|
9
|
+
}
|
|
10
|
+
export async function saveWorkspaceFile(ws, relPath, content, baseHash) {
|
|
11
|
+
const safe = assertSafeRel(relPath);
|
|
12
|
+
assertInScope(ws, safe);
|
|
13
|
+
const abs = ws.toAbs(safe);
|
|
14
|
+
try {
|
|
15
|
+
const onDisk = await readFile(abs, "utf8");
|
|
16
|
+
const diskHash = sha256(onDisk);
|
|
17
|
+
if (diskHash !== baseHash) {
|
|
18
|
+
return { kind: "conflict", diskHash, content: onDisk };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
if (e.code !== "ENOENT")
|
|
23
|
+
throw e;
|
|
24
|
+
// First save of a file the editor just created in-memory: only accept
|
|
25
|
+
// if the editor declared an empty base.
|
|
26
|
+
if (baseHash !== sha256("")) {
|
|
27
|
+
return { kind: "conflict", diskHash: sha256(""), content: "" };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
await mkdir(dirname(abs), { recursive: true });
|
|
31
|
+
await writeFile(abs, content, "utf8");
|
|
32
|
+
return { kind: "saved", hash: sha256(content) };
|
|
33
|
+
}
|
|
34
|
+
export async function createFile(ws, parent, name) {
|
|
35
|
+
validateName(name);
|
|
36
|
+
if (!name.endsWith(".md")) {
|
|
37
|
+
throw new Error(`new file must end in .md (got ${name})`);
|
|
38
|
+
}
|
|
39
|
+
const rel = joinRel(parent, name);
|
|
40
|
+
assertInScope(ws, rel);
|
|
41
|
+
const abs = ws.toAbs(rel);
|
|
42
|
+
await mkdir(dirname(abs), { recursive: true });
|
|
43
|
+
await writeFile(abs, "", { encoding: "utf8", flag: "wx" });
|
|
44
|
+
return rel;
|
|
45
|
+
}
|
|
46
|
+
export async function createFolder(ws, parent, name) {
|
|
47
|
+
validateName(name);
|
|
48
|
+
const rel = joinRel(parent, name);
|
|
49
|
+
await mkdir(ws.toAbs(rel), { recursive: false });
|
|
50
|
+
return rel;
|
|
51
|
+
}
|
|
52
|
+
export async function renamePath(ws, from, to) {
|
|
53
|
+
const safeFrom = assertSafeRel(from);
|
|
54
|
+
const safeTo = assertSafeRel(to);
|
|
55
|
+
// node:fs/promises rename silently clobbers an existing destination on
|
|
56
|
+
// POSIX. Stat first and refuse rather than destroying the user's content.
|
|
57
|
+
// (A concurrent write between this stat and the rename below would surface
|
|
58
|
+
// via the editor's conflict modal on next save anyway, but for tree CRUD
|
|
59
|
+
// we want the clearer "destination already exists" failure.)
|
|
60
|
+
const toAbs = ws.toAbs(safeTo);
|
|
61
|
+
try {
|
|
62
|
+
await stat(toAbs);
|
|
63
|
+
throw new Error(`destination already exists: ${to}`);
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
if (e.code !== "ENOENT")
|
|
67
|
+
throw e;
|
|
68
|
+
}
|
|
69
|
+
await mkdir(dirname(toAbs), { recursive: true });
|
|
70
|
+
await rename(ws.toAbs(safeFrom), toAbs);
|
|
71
|
+
}
|
|
72
|
+
export async function deletePath(ws, relPath) {
|
|
73
|
+
const safe = assertSafeRel(relPath);
|
|
74
|
+
await rm(ws.toAbs(safe), { recursive: true, force: false });
|
|
75
|
+
}
|
|
76
|
+
function assertSafeRel(rel) {
|
|
77
|
+
if (rel === "")
|
|
78
|
+
throw new Error("path is empty");
|
|
79
|
+
// The protocol declares POSIX paths. Backslashes are directory separators
|
|
80
|
+
// on Windows after we hand the string to node:path, so posix.normalize
|
|
81
|
+
// would let "sub\\..\\..\\outside.md" pass while the filesystem treats it
|
|
82
|
+
// as a parent-directory traversal. Reject up front.
|
|
83
|
+
if (rel.includes("\\"))
|
|
84
|
+
throw new Error(`path uses backslash separators: ${rel}`);
|
|
85
|
+
if (rel.includes("\0"))
|
|
86
|
+
throw new Error(`path contains NUL: ${rel}`);
|
|
87
|
+
const norm = posix.normalize(rel);
|
|
88
|
+
if (norm.startsWith("..") || norm.startsWith("/") || norm === ".") {
|
|
89
|
+
throw new Error(`path escapes workspace: ${rel}`);
|
|
90
|
+
}
|
|
91
|
+
return norm;
|
|
92
|
+
}
|
|
93
|
+
function assertInScope(ws, safeRel) {
|
|
94
|
+
if (!ws.matches(safeRel)) {
|
|
95
|
+
throw new Error(`path is outside workspace scope (${ws.scope}): ${safeRel}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function joinRel(parent, name) {
|
|
99
|
+
validateName(name);
|
|
100
|
+
if (!parent)
|
|
101
|
+
return name;
|
|
102
|
+
return assertSafeRel(posix.join(parent, name));
|
|
103
|
+
}
|
|
104
|
+
function validateName(name) {
|
|
105
|
+
if (!name || name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
|
106
|
+
throw new Error(`invalid name: ${JSON.stringify(name)}`);
|
|
107
|
+
}
|
|
108
|
+
if (name === "." || name === "..") {
|
|
109
|
+
throw new Error(`invalid name: ${JSON.stringify(name)}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/server/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sha256(content: string): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
// Stable content hash used for optimistic concurrency on save and as the
|
|
3
|
+
// `diskHash` value exposed to the editor.
|
|
4
|
+
export function sha256(content) {
|
|
5
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/server/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,yEAAyE;AACzE,0CAA0C;AAC1C,MAAM,UAAU,MAAM,CAAC,OAAe;IACpC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const SUPPORTED_AGENTS: readonly ["claude-code"];
|
|
2
|
+
export type SupportedAgent = (typeof SUPPORTED_AGENTS)[number];
|
|
3
|
+
export declare function isSupportedAgent(name: string): name is SupportedAgent;
|
|
4
|
+
export type InitOutcome = {
|
|
5
|
+
path: string;
|
|
6
|
+
/** "created" when the file was new, "updated" when an existing entry changed. */
|
|
7
|
+
action: "created" | "updated" | "unchanged";
|
|
8
|
+
/** The full set of mcpServers keys after the write. */
|
|
9
|
+
agents: string[];
|
|
10
|
+
};
|
|
11
|
+
export type SidebarEntry = {
|
|
12
|
+
command: string;
|
|
13
|
+
args: string[];
|
|
14
|
+
};
|
|
15
|
+
export declare function sidebarMcpEntry(): SidebarEntry;
|
|
16
|
+
export declare function runInit(cwd: string, _agent: SupportedAgent): Promise<InitOutcome>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
// `npx sidebar-md init [agent]` writes a project-local `.mcp.json` entry that
|
|
5
|
+
// spawns `npx sidebar-md --stdio`. V1 supports the Claude Code / Compound
|
|
6
|
+
// shared `.mcp.json` layout (one entry under `mcpServers`). See ADR-0007.
|
|
7
|
+
//
|
|
8
|
+
// Existing unrelated entries in `.mcp.json` are preserved. Re-running is
|
|
9
|
+
// idempotent: the sidebar entry is overwritten rather than duplicated.
|
|
10
|
+
export const SUPPORTED_AGENTS = ["claude-code"];
|
|
11
|
+
export function isSupportedAgent(name) {
|
|
12
|
+
return SUPPORTED_AGENTS.includes(name);
|
|
13
|
+
}
|
|
14
|
+
export function sidebarMcpEntry() {
|
|
15
|
+
// `npx sidebar-md --stdio` is the locked invite shape (ADR-0007). Anyone
|
|
16
|
+
// wanting a different command (e.g. a globally installed `sidebar-md` bin)
|
|
17
|
+
// can edit the file by hand; sidebar's own init writes the npx form.
|
|
18
|
+
return { command: "npx", args: ["sidebar-md", "--stdio"] };
|
|
19
|
+
}
|
|
20
|
+
export async function runInit(cwd, _agent) {
|
|
21
|
+
// Slice 02 ships the Claude Code / Compound layout only. The agent
|
|
22
|
+
// parameter is reserved for V1.1 when Cursor and Aider variants land.
|
|
23
|
+
const path = join(cwd, ".mcp.json");
|
|
24
|
+
let existing = null;
|
|
25
|
+
if (existsSync(path)) {
|
|
26
|
+
const raw = await readFile(path, "utf8");
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(raw);
|
|
29
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
30
|
+
existing = parsed;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
throw new Error(`.mcp.json is not a JSON object (got ${typeof parsed})`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
throw new Error(`failed to parse existing .mcp.json: ${e.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const base = existing ?? {};
|
|
41
|
+
const servers = (base.mcpServers && typeof base.mcpServers === "object"
|
|
42
|
+
? { ...base.mcpServers }
|
|
43
|
+
: {});
|
|
44
|
+
const before = JSON.stringify(servers["sidebar-md"] ?? null);
|
|
45
|
+
const entry = sidebarMcpEntry();
|
|
46
|
+
servers["sidebar-md"] = entry;
|
|
47
|
+
const after = JSON.stringify(servers["sidebar-md"]);
|
|
48
|
+
const next = { ...base, mcpServers: servers };
|
|
49
|
+
const action = existing === null ? "created" : before === after ? "unchanged" : "updated";
|
|
50
|
+
await writeFile(path, `${JSON.stringify(next, null, 2)}\n`, "utf8");
|
|
51
|
+
return { path, action, agents: Object.keys(servers).sort() };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=init.js.map
|