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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sidrit Trandafili
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# sidebar-md
|
|
2
|
+
|
|
3
|
+
A local-first markdown editor with a co-author seat for your MCP-speaking agent.
|
|
4
|
+
|
|
5
|
+
`sidebar-md` runs as a single local process. It opens a CodeMirror-based editor in your browser and exposes a local [Model Context Protocol](https://modelcontextprotocol.io) server in the same process. Any MCP-speaking agent (Claude Code, Codex, Aider, Compound, anything that speaks MCP) can join your workspace on invite and collaborate on the markdown files you're reading.
|
|
6
|
+
|
|
7
|
+
Files stay on your disk. The agent stays in your terminal. Sidebar is the connective tissue between them.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
npx sidebar-md
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## What this gives you
|
|
14
|
+
|
|
15
|
+
A browser-based markdown editor scoped to your project's `docs/` folder (configurable). Live preview, syntax highlighting, manual save. Standard editor things.
|
|
16
|
+
|
|
17
|
+
A right-side **status drawer** that shows everything happening in your workspace: pending mentions, in-progress agent claims, connected agents, and the last 50 lifecycle events.
|
|
18
|
+
|
|
19
|
+
A **Cmd-K** popover on any text selection that lets you write three kinds of co-authoring markers directly into the file:
|
|
20
|
+
|
|
21
|
+
1. **Mentions**. A scoped, lifecycle-tracked ask aimed at an invited agent. Verbs like `rephrase`, `expand`, `factcheck`, `question`. The agent picks them up via MCP, claims them, and either replaces the text inline (action verbs) or leaves a note alongside it (query verbs).
|
|
22
|
+
2. **Notes**. A persistent side annotation. Pure information, no lifecycle. Either you or an agent can leave them.
|
|
23
|
+
3. **Suggestions**. A proposed replacement for a region. The agent or you can propose; only the human can accept or reject. Accept replaces the prose verbatim.
|
|
24
|
+
|
|
25
|
+
All three are HTML comments on disk. Any other markdown tool sees them as comments. Sidebar renders them as gutter pills, side cards, and verb bubbles.
|
|
26
|
+
|
|
27
|
+
An MCP tool surface the agent uses to participate: `list_docs`, `read_doc`, `list_pending_mentions`, `mark_in_progress`, `resolve_mention`, `list_annotations`, `add_annotation`, `update_annotation`, `remove_annotation`, `list_recent_changes`. The full surface is documented in [docs/qa/README.md](docs/qa/README.md) and [docs/specs/sidebar-v1-draft.md](docs/specs/sidebar-v1-draft.md).
|
|
28
|
+
|
|
29
|
+
A skill scaffolder (`npx sidebar-md scaffold-skill`) that drops an agent-facing instruction file into `.claude/skills/sidebar-collaboration/SKILL.md` (or any path you point it at). The skill teaches the agent how to behave around mention lifecycle, optimistic concurrency, and the dirty-buffer signal.
|
|
30
|
+
|
|
31
|
+
## Why this exists
|
|
32
|
+
|
|
33
|
+
Co-authoring with an agent on a long document is friction-heavy. You either babysit a chat (and lose context with every restart) or you let the agent rewrite blindly (and chase regressions). Sidebar puts the human and the agent on the same surface, with the file as the source of truth and HTML-comment markers as the lifecycle handles.
|
|
34
|
+
|
|
35
|
+
The permission model is deliberate. The agent reads freely. The agent edits prose only in two places: inside a **mention** you placed authorizing the edit, or via a **suggestion** that you accept. Anywhere else, the agent can only leave notes. No silent rewrites.
|
|
36
|
+
|
|
37
|
+
## Quick start
|
|
38
|
+
|
|
39
|
+
You need Node 20 or later.
|
|
40
|
+
|
|
41
|
+
### Standalone editor
|
|
42
|
+
|
|
43
|
+
In any project with a `docs/` folder:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
npx sidebar-md
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
A browser tab opens at `http://127.0.0.1:5180`. The file tree on the left lists every markdown file under `docs/`. Click a file to open it.
|
|
50
|
+
|
|
51
|
+
If `docs/` does not exist, sidebar offers three options: create it for you, accept a different glob, or quit. It does not silently scan your whole project.
|
|
52
|
+
|
|
53
|
+
### Invite an MCP agent (one-time per project)
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
npx sidebar-md init claude-code
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
That writes a project-local `.mcp.json` entry pointing your agent's MCP client at sidebar over stdio. The next time you start your agent in the project, it spawns sidebar automatically and joins the workspace. No copy-paste, no MCP-config hunting.
|
|
60
|
+
|
|
61
|
+
`init` is idempotent. Re-running updates the sidebar entry and leaves unrelated entries in `.mcp.json` alone. V1 supports the Claude Code and Compound shared `.mcp.json` layout. Cursor, Codex, and Aider variants land in V1.1.
|
|
62
|
+
|
|
63
|
+
### Scaffold the agent skill (optional but recommended)
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
npx sidebar-md scaffold-skill
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Writes `.claude/skills/sidebar-collaboration/SKILL.md` with the full mention round-trip protocol, verb tables, multi-agent etiquette, and conflict-handling rules. Claude Code and Compound auto-discover the skill on next start. For other agents, pass `--into <path>` to target a different location.
|
|
70
|
+
|
|
71
|
+
## How co-authoring works in 90 seconds
|
|
72
|
+
|
|
73
|
+
1. You open a markdown file and select a paragraph you want help with.
|
|
74
|
+
2. You press **Cmd-K** (or Ctrl-K on Linux/Windows). A small popover appears anchored to the selection.
|
|
75
|
+
3. You pick a mode: `mention`, `note`, or `suggestion`. Default is `mention`.
|
|
76
|
+
4. For `mention`, you type a verb (`rephrase`, `expand`, ...). Built-in verbs autocomplete. You can add a freeform instruction.
|
|
77
|
+
5. Submit. Sidebar writes a `<!-- @sidebar mention id="m-a3f9" verb="rephrase": tighten this paragraph -->target<!-- @sidebar end id="m-a3f9" -->` pair around your selection.
|
|
78
|
+
6. The agent, connected over MCP, sees the mention via `list_pending_mentions`. It claims it with `mark_in_progress`, reads the surrounding doc with `read_doc`, does the work, and calls `resolve_mention` with the new content and a `base_hash` confirming it operated on the version it claimed.
|
|
79
|
+
7. If you edited the region while the agent was working, the `base_hash` mismatches and sidebar refuses the write. The agent re-reads via `get_mention` and retries on the new content. No silent overwrites.
|
|
80
|
+
|
|
81
|
+
The whole thing happens with the file on disk as the source of truth. If you close sidebar mid-flight, the markers stay put. Re-open later, and the lifecycle picks up where it left off.
|
|
82
|
+
|
|
83
|
+
## A typical session
|
|
84
|
+
|
|
85
|
+
A short, real-feeling slice of what the surface looks like end to end:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
$ cd my-project
|
|
89
|
+
$ npx sidebar-md init claude-code
|
|
90
|
+
sidebar init: wrote new ./.mcp.json
|
|
91
|
+
agent: claude-code
|
|
92
|
+
mcpServers: sidebar-md
|
|
93
|
+
|
|
94
|
+
Start claude-code in this project; it will spawn sidebar via stdio.
|
|
95
|
+
|
|
96
|
+
$ claude
|
|
97
|
+
# Claude Code spawns sidebar over stdio. A browser tab opens
|
|
98
|
+
# automatically. The agent says hello in the terminal.
|
|
99
|
+
|
|
100
|
+
# You select a paragraph in the editor, press Cmd-K, pick `rephrase`,
|
|
101
|
+
# and type "tighten this". A marker pair is written to disk:
|
|
102
|
+
|
|
103
|
+
<!-- @sidebar mention id="m-a3f9" verb="rephrase": tighten this -->
|
|
104
|
+
Your selected paragraph here.
|
|
105
|
+
<!-- @sidebar end id="m-a3f9" -->
|
|
106
|
+
|
|
107
|
+
# You watch the status drawer. The mention moves Pending -> In progress
|
|
108
|
+
# (with "claude-code" as the claimer). Seconds later, the marker pair
|
|
109
|
+
# disappears and the paragraph is replaced with the tightened version.
|
|
110
|
+
|
|
111
|
+
# You spot something you want to flag for later. Select another region,
|
|
112
|
+
# Cmd-K, pick `note`, type "double-check this stat". The annotation
|
|
113
|
+
# shows up as a side card on the right. Stays there forever, no
|
|
114
|
+
# lifecycle.
|
|
115
|
+
|
|
116
|
+
# You write a `suggestion` on a third region. The agent (or you) types
|
|
117
|
+
# the proposed replacement. The side card has Accept and Reject
|
|
118
|
+
# buttons. Accept replaces the prose verbatim.
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Configuration
|
|
122
|
+
|
|
123
|
+
Sidebar reads `.sidebar/config.json` (committed, team-shared) and `.sidebar/local.json` (gitignored, per-machine) from the project root. Neither file is created automatically. They appear lazily the first time you do something that needs persistence.
|
|
124
|
+
|
|
125
|
+
### `.sidebar/config.json`
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"version": 1,
|
|
130
|
+
"scope": "notes/**/*.md",
|
|
131
|
+
"rateLimit": { "agentMentions": { "maxOpen": 5 } },
|
|
132
|
+
"verbs": {
|
|
133
|
+
"human": {
|
|
134
|
+
"tighten": { "mode": "replace" },
|
|
135
|
+
"audit": { "mode": "annotation" }
|
|
136
|
+
},
|
|
137
|
+
"agent": {
|
|
138
|
+
"estimate": {}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
- `scope` overrides the default `docs/**/*.md` workspace glob.
|
|
145
|
+
- `rateLimit.agentMentions.maxOpen` caps concurrent agent-origin mentions.
|
|
146
|
+
- `verbs.human` extends Cmd-K's verb autocomplete with custom verbs in either `replace` mode (agent rewrites the region) or `annotation` mode (agent leaves a note).
|
|
147
|
+
- `verbs.agent` extends the whitelist of verbs agents can use when they originate a mention.
|
|
148
|
+
|
|
149
|
+
### `.sidebar/local.json`
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{ "version": 1, "port": 5180, "browser": "default" }
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- `port` pins the HTTP port. CLI flag `--port` takes precedence per boot.
|
|
156
|
+
- `browser` accepts `"default"`, `"none"`, or any name the [`open`](https://www.npmjs.com/package/open) package understands (`"chrome"`, `"firefox"`, ...).
|
|
157
|
+
|
|
158
|
+
Sidebar refuses to start on invalid JSON, unknown top-level keys, a `version` other than `1`, an unknown verb mode, or a port that's already in use when you set it explicitly. No silent fallbacks.
|
|
159
|
+
|
|
160
|
+
### CLI flags
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
npx sidebar-md [--scope "<glob>"] [--port <N>] [--browser <name>] [--verbose|--quiet]
|
|
164
|
+
npx sidebar-md init [agent] [--yes]
|
|
165
|
+
npx sidebar-md scaffold-skill [--into <path>]
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## How sidebar is built
|
|
169
|
+
|
|
170
|
+
One Node 20 process, written in strict TypeScript. The editor is a React 18 SPA built with Vite. The HTTP layer uses `node:http` plus `ws`. The MCP server uses the official `@modelcontextprotocol/sdk` over both stdio (the dominant agent-spawning path) and Streamable HTTP (standalone mode and additional-agent attach). State for transient runtime data (in-progress claims, dirty buffers, recent changes) lives in process memory. Persistent shared state lives in the markdown files themselves as HTML comments. There's no database, no sidecar files (aside from the optional `.sidebar/` config dir).
|
|
171
|
+
|
|
172
|
+
The full architecture, decision history, and acceptance criteria are documented in:
|
|
173
|
+
|
|
174
|
+
- [docs/index.md](docs/index.md): docs landing page.
|
|
175
|
+
- [docs/qa/README.md](docs/qa/README.md): living capabilities catalogue, written from a user's perspective.
|
|
176
|
+
- [docs/specs/sidebar-v1-draft.md](docs/specs/sidebar-v1-draft.md): the V1 design document. Every behavior in QA traces back to a section here.
|
|
177
|
+
- [docs/decisions/](docs/decisions/): architecture decision records.
|
|
178
|
+
|
|
179
|
+
## What sidebar does not do
|
|
180
|
+
|
|
181
|
+
These are deliberate, not gaps to fill later:
|
|
182
|
+
|
|
183
|
+
- No global config in `~/.sidebar/`. All configuration is project-scoped.
|
|
184
|
+
- No file logging. Logs go to stderr only.
|
|
185
|
+
- No telemetry. No phone-home, no crash reporter, no analytics.
|
|
186
|
+
- No daemon mode. Sidebar runs in the foreground. Ctrl-C cleanly shuts it down.
|
|
187
|
+
- No auto-update. Run `npx sidebar-md@latest` or `npm i -g sidebar-md` to upgrade.
|
|
188
|
+
- No file delete or out-of-glob writes by the agent.
|
|
189
|
+
- No agent-to-agent direct messaging. Sidebar mediates human-to-agent and agent-to-human only.
|
|
190
|
+
|
|
191
|
+
## Status
|
|
192
|
+
|
|
193
|
+
V1 is the current target. Slices 1 through 5 are merged (editor shell, MCP server over stdio plus HTTP, `init` and `.mcp.json` write, `.sidebar/` config, human-origin mentions, annotations). Slices 6 through 11 (agent-origin mentions with rate limiting, conflict modal, scaffold-skill, multi-agent identity, file tree CRUD, runtime polish) land in subsequent releases.
|
|
194
|
+
|
|
195
|
+
The codebase is small and the slice boundaries are documented. Contributions welcome via GitHub issues and PRs.
|
|
196
|
+
|
|
197
|
+
## Requirements
|
|
198
|
+
|
|
199
|
+
- Node 20 LTS or later.
|
|
200
|
+
- A POSIX-y filesystem (macOS, Linux, WSL). Native Windows is untested in V1.
|
|
201
|
+
- An MCP-speaking agent if you want the collaboration features. Sidebar runs perfectly well as a standalone markdown editor without one.
|
|
202
|
+
|
|
203
|
+
## License
|
|
204
|
+
|
|
205
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { type Annotation } from "../shared/markers.js";
|
|
2
|
+
import type { Workspace } from "./workspace.js";
|
|
3
|
+
export type FileAnnotation = Annotation & {
|
|
4
|
+
/** Workspace-relative POSIX path of the file the marker lives in. */
|
|
5
|
+
file: string;
|
|
6
|
+
/** ISO timestamp the annotation was first observed at runtime. */
|
|
7
|
+
created_at: string;
|
|
8
|
+
};
|
|
9
|
+
export type AnnotationCreatedAtMap = Map<string, string>;
|
|
10
|
+
/** Walk every file in scope (or one specific file) and return annotations. */
|
|
11
|
+
export declare function listAnnotations(ws: Workspace, firstSeenAt: AnnotationCreatedAtMap, options?: {
|
|
12
|
+
path?: string;
|
|
13
|
+
now?: () => Date;
|
|
14
|
+
}): Promise<FileAnnotation[]>;
|
|
15
|
+
export declare function findAnnotation(ws: Workspace, id: string, firstSeenAt: AnnotationCreatedAtMap): Promise<FileAnnotation | null>;
|
|
16
|
+
export type TargetAnchor = {
|
|
17
|
+
start: number;
|
|
18
|
+
end: number;
|
|
19
|
+
};
|
|
20
|
+
export type AddAnnotationInput = {
|
|
21
|
+
path: string;
|
|
22
|
+
target_anchor: TargetAnchor;
|
|
23
|
+
type: "note" | "suggestion";
|
|
24
|
+
content: string;
|
|
25
|
+
author: string;
|
|
26
|
+
};
|
|
27
|
+
export type AddAnnotationResult = {
|
|
28
|
+
annotation: {
|
|
29
|
+
id: string;
|
|
30
|
+
file: string;
|
|
31
|
+
type: "note" | "suggestion";
|
|
32
|
+
author: string;
|
|
33
|
+
content: string;
|
|
34
|
+
target_content: string;
|
|
35
|
+
target_anchor: TargetAnchor;
|
|
36
|
+
};
|
|
37
|
+
newContent: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Wrap the target region in a begin/end annotation pair and write the file.
|
|
41
|
+
* Markers occupy full lines; if the cut isn't at a line boundary we splice
|
|
42
|
+
* newlines the same way createMention does (slice 4 contract).
|
|
43
|
+
*/
|
|
44
|
+
export declare function addAnnotation(ws: Workspace, input: AddAnnotationInput): Promise<AddAnnotationResult>;
|
|
45
|
+
export type UpdateAnnotationResult = {
|
|
46
|
+
kind: "ok";
|
|
47
|
+
file: string;
|
|
48
|
+
type: "note" | "suggestion";
|
|
49
|
+
author: string;
|
|
50
|
+
} | {
|
|
51
|
+
kind: "not-found";
|
|
52
|
+
} | {
|
|
53
|
+
kind: "forbidden";
|
|
54
|
+
author: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Replace the begin marker's content payload in place. The author scope is
|
|
58
|
+
* enforced by the caller (the MCP tool checks `author === agentName`); we
|
|
59
|
+
* also surface the on-disk author so the caller can render the rejection
|
|
60
|
+
* message.
|
|
61
|
+
*/
|
|
62
|
+
export declare function updateAnnotation(ws: Workspace, id: string, content: string, options: {
|
|
63
|
+
requireAuthor?: string;
|
|
64
|
+
firstSeenAt: AnnotationCreatedAtMap;
|
|
65
|
+
}): Promise<UpdateAnnotationResult>;
|
|
66
|
+
export type RemoveAnnotationResult = {
|
|
67
|
+
kind: "ok";
|
|
68
|
+
file: string;
|
|
69
|
+
type: "note" | "suggestion";
|
|
70
|
+
author: string;
|
|
71
|
+
} | {
|
|
72
|
+
kind: "not-found";
|
|
73
|
+
} | {
|
|
74
|
+
kind: "forbidden";
|
|
75
|
+
author: string;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Strip the begin/end pair; leave the target prose in place. This is the
|
|
79
|
+
* `note` lifecycle's only mutation (the `reject` action for a suggestion is
|
|
80
|
+
* the same operation).
|
|
81
|
+
*/
|
|
82
|
+
export declare function removeAnnotation(ws: Workspace, id: string, options: {
|
|
83
|
+
requireAuthor?: string;
|
|
84
|
+
firstSeenAt: AnnotationCreatedAtMap;
|
|
85
|
+
}): Promise<RemoveAnnotationResult>;
|
|
86
|
+
export type AcceptSuggestionResult = {
|
|
87
|
+
kind: "ok";
|
|
88
|
+
file: string;
|
|
89
|
+
author: string;
|
|
90
|
+
replacement: string;
|
|
91
|
+
} | {
|
|
92
|
+
kind: "not-found";
|
|
93
|
+
} | {
|
|
94
|
+
kind: "not-suggestion";
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Swap the target region for the suggestion's content and remove the
|
|
98
|
+
* begin/end pair. Used by the editor's side-card Accept button (and only by
|
|
99
|
+
* the editor; the agent never accepts its own suggestion).
|
|
100
|
+
*
|
|
101
|
+
* The replacement is applied verbatim: no further markdown transformation,
|
|
102
|
+
* no escaping, no fence rewrites. That contract is explicit in the spec.
|
|
103
|
+
*/
|
|
104
|
+
export declare function acceptSuggestion(ws: Workspace, id: string, firstSeenAt: AnnotationCreatedAtMap): Promise<AcceptSuggestionResult>;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import fastGlob from "fast-glob";
|
|
3
|
+
import { decodeAnnotationContent, formatAnnotationBegin, formatAnnotationEnd, parseMarkers, } from "../shared/markers.js";
|
|
4
|
+
import { generateNoteId, generateSuggestionId } from "./marker-ids.js";
|
|
5
|
+
const SCAN_IGNORE = ["**/.git/**", "**/node_modules/**", "**/dist/**", "**/.sidebar/**"];
|
|
6
|
+
/** Walk every file in scope (or one specific file) and return annotations. */
|
|
7
|
+
export async function listAnnotations(ws, firstSeenAt, options = {}) {
|
|
8
|
+
const now = options.now ?? (() => new Date());
|
|
9
|
+
let files;
|
|
10
|
+
if (options.path) {
|
|
11
|
+
if (!ws.matches(options.path))
|
|
12
|
+
return [];
|
|
13
|
+
files = [options.path];
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
files = await fastGlob(ws.innerGlob, {
|
|
17
|
+
cwd: ws.root,
|
|
18
|
+
onlyFiles: true,
|
|
19
|
+
dot: false,
|
|
20
|
+
followSymbolicLinks: false,
|
|
21
|
+
ignore: SCAN_IGNORE,
|
|
22
|
+
});
|
|
23
|
+
files.sort();
|
|
24
|
+
}
|
|
25
|
+
const out = [];
|
|
26
|
+
for (const rel of files) {
|
|
27
|
+
let text;
|
|
28
|
+
try {
|
|
29
|
+
text = await readFile(ws.toAbs(rel), "utf8");
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const parsed = parseMarkers(text);
|
|
35
|
+
for (const a of parsed.annotations) {
|
|
36
|
+
let createdAt = firstSeenAt.get(a.id);
|
|
37
|
+
if (!createdAt) {
|
|
38
|
+
createdAt = now().toISOString();
|
|
39
|
+
firstSeenAt.set(a.id, createdAt);
|
|
40
|
+
}
|
|
41
|
+
out.push({ ...a, file: rel, created_at: createdAt });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
export async function findAnnotation(ws, id, firstSeenAt) {
|
|
47
|
+
const list = await listAnnotations(ws, firstSeenAt);
|
|
48
|
+
return list.find((a) => a.id === id) ?? null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Wrap the target region in a begin/end annotation pair and write the file.
|
|
52
|
+
* Markers occupy full lines; if the cut isn't at a line boundary we splice
|
|
53
|
+
* newlines the same way createMention does (slice 4 contract).
|
|
54
|
+
*/
|
|
55
|
+
export async function addAnnotation(ws, input) {
|
|
56
|
+
const abs = ws.toAbs(input.path);
|
|
57
|
+
const original = await readFile(abs, "utf8");
|
|
58
|
+
const { start, end } = input.target_anchor;
|
|
59
|
+
if (start < 0 || end > original.length || start > end) {
|
|
60
|
+
throw new Error(`addAnnotation: invalid target_anchor [${start}, ${end}] for file length ${original.length}`);
|
|
61
|
+
}
|
|
62
|
+
const before = original.slice(0, start);
|
|
63
|
+
const target = original.slice(start, end);
|
|
64
|
+
const after = original.slice(end);
|
|
65
|
+
const beginPrefix = before.length > 0 && !before.endsWith("\n") ? "\n" : "";
|
|
66
|
+
const endSuffix = after.length > 0 && !after.startsWith("\n") ? "\n" : "";
|
|
67
|
+
const normalizedTarget = target.length === 0 || target.endsWith("\n") ? target : `${target}\n`;
|
|
68
|
+
const id = input.type === "note" ? generateNoteId() : generateSuggestionId();
|
|
69
|
+
const begin = formatAnnotationBegin({
|
|
70
|
+
type: input.type,
|
|
71
|
+
id,
|
|
72
|
+
author: input.author,
|
|
73
|
+
instruction: input.content,
|
|
74
|
+
});
|
|
75
|
+
const endMarker = formatAnnotationEnd(id);
|
|
76
|
+
const newContent = `${before}${beginPrefix}${begin}\n${normalizedTarget}${endMarker}${endSuffix}${after}`;
|
|
77
|
+
await writeFile(abs, newContent, "utf8");
|
|
78
|
+
return {
|
|
79
|
+
annotation: {
|
|
80
|
+
id,
|
|
81
|
+
file: input.path,
|
|
82
|
+
type: input.type,
|
|
83
|
+
author: input.author,
|
|
84
|
+
content: input.content,
|
|
85
|
+
target_content: normalizedTarget,
|
|
86
|
+
target_anchor: input.target_anchor,
|
|
87
|
+
},
|
|
88
|
+
newContent,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Replace the begin marker's content payload in place. The author scope is
|
|
93
|
+
* enforced by the caller (the MCP tool checks `author === agentName`); we
|
|
94
|
+
* also surface the on-disk author so the caller can render the rejection
|
|
95
|
+
* message.
|
|
96
|
+
*/
|
|
97
|
+
export async function updateAnnotation(ws, id, content, options) {
|
|
98
|
+
const target = await findAnnotation(ws, id, options.firstSeenAt);
|
|
99
|
+
if (!target)
|
|
100
|
+
return { kind: "not-found" };
|
|
101
|
+
if (options.requireAuthor !== undefined && target.author !== options.requireAuthor) {
|
|
102
|
+
return { kind: "forbidden", author: target.author };
|
|
103
|
+
}
|
|
104
|
+
const abs = ws.toAbs(target.file);
|
|
105
|
+
const original = await readFile(abs, "utf8");
|
|
106
|
+
const beginLine = formatAnnotationBegin({
|
|
107
|
+
type: target.type,
|
|
108
|
+
id,
|
|
109
|
+
author: target.author,
|
|
110
|
+
instruction: content,
|
|
111
|
+
});
|
|
112
|
+
const newContent = original.slice(0, target.beginLineStart) +
|
|
113
|
+
`${beginLine}\n` +
|
|
114
|
+
original.slice(target.beginLineEnd);
|
|
115
|
+
await writeFile(abs, newContent, "utf8");
|
|
116
|
+
return { kind: "ok", file: target.file, type: target.type, author: target.author };
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Strip the begin/end pair; leave the target prose in place. This is the
|
|
120
|
+
* `note` lifecycle's only mutation (the `reject` action for a suggestion is
|
|
121
|
+
* the same operation).
|
|
122
|
+
*/
|
|
123
|
+
export async function removeAnnotation(ws, id, options) {
|
|
124
|
+
const target = await findAnnotation(ws, id, options.firstSeenAt);
|
|
125
|
+
if (!target)
|
|
126
|
+
return { kind: "not-found" };
|
|
127
|
+
if (options.requireAuthor !== undefined && target.author !== options.requireAuthor) {
|
|
128
|
+
return { kind: "forbidden", author: target.author };
|
|
129
|
+
}
|
|
130
|
+
const abs = ws.toAbs(target.file);
|
|
131
|
+
const original = await readFile(abs, "utf8");
|
|
132
|
+
const newContent = original.slice(0, target.beginLineStart) +
|
|
133
|
+
target.targetContent +
|
|
134
|
+
original.slice(target.endLineEnd);
|
|
135
|
+
await writeFile(abs, newContent, "utf8");
|
|
136
|
+
options.firstSeenAt.delete(id);
|
|
137
|
+
return { kind: "ok", file: target.file, type: target.type, author: target.author };
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Swap the target region for the suggestion's content and remove the
|
|
141
|
+
* begin/end pair. Used by the editor's side-card Accept button (and only by
|
|
142
|
+
* the editor; the agent never accepts its own suggestion).
|
|
143
|
+
*
|
|
144
|
+
* The replacement is applied verbatim: no further markdown transformation,
|
|
145
|
+
* no escaping, no fence rewrites. That contract is explicit in the spec.
|
|
146
|
+
*/
|
|
147
|
+
export async function acceptSuggestion(ws, id, firstSeenAt) {
|
|
148
|
+
const target = await findAnnotation(ws, id, firstSeenAt);
|
|
149
|
+
if (!target)
|
|
150
|
+
return { kind: "not-found" };
|
|
151
|
+
if (target.type !== "suggestion")
|
|
152
|
+
return { kind: "not-suggestion" };
|
|
153
|
+
const abs = ws.toAbs(target.file);
|
|
154
|
+
const original = await readFile(abs, "utf8");
|
|
155
|
+
// The decoded content is the proposed replacement (markdown source). It
|
|
156
|
+
// replaces the entire begin/end pair plus the target region between them.
|
|
157
|
+
const replacement = ensureTrailingNewline(decodeAnnotationContent(target.instruction));
|
|
158
|
+
const newContent = original.slice(0, target.beginLineStart) + replacement + original.slice(target.endLineEnd);
|
|
159
|
+
await writeFile(abs, newContent, "utf8");
|
|
160
|
+
firstSeenAt.delete(id);
|
|
161
|
+
return { kind: "ok", file: target.file, author: target.author, replacement };
|
|
162
|
+
}
|
|
163
|
+
function ensureTrailingNewline(s) {
|
|
164
|
+
return s.endsWith("\n") ? s : `${s}\n`;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=annotation-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotation-ops.js","sourceRoot":"","sources":["../../src/server/annotation-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type Subcommand = "serve" | "stdio" | "init";
|
|
2
|
+
export type ParsedArgs = {
|
|
3
|
+
subcommand: Subcommand;
|
|
4
|
+
/** Set when subcommand is `init`. */
|
|
5
|
+
initAgent: string | undefined;
|
|
6
|
+
/** Set when subcommand is `init` and the user passed `--yes`. */
|
|
7
|
+
yes: boolean;
|
|
8
|
+
port: number | undefined;
|
|
9
|
+
scope: string | undefined;
|
|
10
|
+
/** Undefined when --browser was not passed; resolves from local.json or
|
|
11
|
+
* the "default" fallback at the call site. */
|
|
12
|
+
browser: string | undefined;
|
|
13
|
+
verbose: boolean;
|
|
14
|
+
quiet: boolean;
|
|
15
|
+
helpRequested: boolean;
|
|
16
|
+
};
|
|
17
|
+
export declare class ArgsError extends Error {
|
|
18
|
+
}
|
|
19
|
+
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
20
|
+
export declare function helpText(): string;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
export class ArgsError extends Error {
|
|
2
|
+
}
|
|
3
|
+
export function parseArgs(argv) {
|
|
4
|
+
const out = {
|
|
5
|
+
subcommand: "serve",
|
|
6
|
+
initAgent: undefined,
|
|
7
|
+
yes: false,
|
|
8
|
+
port: undefined,
|
|
9
|
+
scope: undefined,
|
|
10
|
+
browser: undefined,
|
|
11
|
+
verbose: false,
|
|
12
|
+
quiet: false,
|
|
13
|
+
helpRequested: false,
|
|
14
|
+
};
|
|
15
|
+
// Subcommand detection: first non-flag positional argument selects the
|
|
16
|
+
// subcommand. `--stdio` is a flag, not a positional, so we handle it
|
|
17
|
+
// alongside other flags. Slice 01 only had `serve`; slice 02 adds
|
|
18
|
+
// `init` (and the `--stdio` invite hook).
|
|
19
|
+
let i = 0;
|
|
20
|
+
const first = argv[0];
|
|
21
|
+
if (first === "init") {
|
|
22
|
+
out.subcommand = "init";
|
|
23
|
+
i = 1;
|
|
24
|
+
// `init <agent>` is also accepted: read the next positional as the
|
|
25
|
+
// agent name.
|
|
26
|
+
if (argv[i] !== undefined && !argv[i].startsWith("--")) {
|
|
27
|
+
out.initAgent = argv[i];
|
|
28
|
+
i += 1;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
for (; i < argv.length; i++) {
|
|
32
|
+
const a = argv[i];
|
|
33
|
+
switch (a) {
|
|
34
|
+
case "--port":
|
|
35
|
+
case "-p": {
|
|
36
|
+
const v = argv[++i];
|
|
37
|
+
// parseInt silently coerces "123abc" -> 123 and "1.5" -> 1, both of
|
|
38
|
+
// which can land the user on a port they did not ask for. Match
|
|
39
|
+
// strict decimal-digit form first.
|
|
40
|
+
if (!v || !/^\d+$/.test(v)) {
|
|
41
|
+
throw new ArgsError(`--port expects a non-negative integer (got ${v ?? "<missing>"})`);
|
|
42
|
+
}
|
|
43
|
+
const n = Number.parseInt(v, 10);
|
|
44
|
+
if (n > 65_535) {
|
|
45
|
+
throw new ArgsError(`--port out of range 0-65535 (got ${n})`);
|
|
46
|
+
}
|
|
47
|
+
out.port = n;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
case "--scope": {
|
|
51
|
+
const v = argv[++i];
|
|
52
|
+
if (!v)
|
|
53
|
+
throw new ArgsError("--scope expects a glob");
|
|
54
|
+
out.scope = v;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case "--browser": {
|
|
58
|
+
const v = argv[++i];
|
|
59
|
+
if (!v)
|
|
60
|
+
throw new ArgsError("--browser expects a value (default, none, chrome, ...)");
|
|
61
|
+
out.browser = v;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case "--stdio":
|
|
65
|
+
if (out.subcommand !== "serve") {
|
|
66
|
+
throw new ArgsError("--stdio cannot be combined with a subcommand");
|
|
67
|
+
}
|
|
68
|
+
out.subcommand = "stdio";
|
|
69
|
+
break;
|
|
70
|
+
case "--yes":
|
|
71
|
+
case "-y":
|
|
72
|
+
out.yes = true;
|
|
73
|
+
break;
|
|
74
|
+
case "--verbose":
|
|
75
|
+
out.verbose = true;
|
|
76
|
+
break;
|
|
77
|
+
case "--quiet":
|
|
78
|
+
out.quiet = true;
|
|
79
|
+
break;
|
|
80
|
+
case "--help":
|
|
81
|
+
case "-h":
|
|
82
|
+
out.helpRequested = true;
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
if (a.startsWith("--")) {
|
|
86
|
+
throw new ArgsError(`unknown flag: ${a}`);
|
|
87
|
+
}
|
|
88
|
+
throw new ArgsError(`unexpected argument: ${a}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
export function helpText() {
|
|
94
|
+
return [
|
|
95
|
+
"Usage: sidebar [subcommand] [options]",
|
|
96
|
+
"",
|
|
97
|
+
"Local-first markdown editor and MCP server for human-agent doc collaboration.",
|
|
98
|
+
"",
|
|
99
|
+
"Subcommands:",
|
|
100
|
+
" (default) Run sidebar standalone (HTTP MCP + editor).",
|
|
101
|
+
" init [agent] Write a project-local .mcp.json that spawns sidebar via",
|
|
102
|
+
" stdio. Defaults to claude-code when no agent is named.",
|
|
103
|
+
" Pass --yes to skip the interactive prompt.",
|
|
104
|
+
" --stdio Internal: spawned by an MCP client. Becomes primary or",
|
|
105
|
+
" proxy depending on .sidebar/connection.json.",
|
|
106
|
+
"",
|
|
107
|
+
"Options:",
|
|
108
|
+
" --port <N> Bind a specific HTTP port. --port 0 picks any free port.",
|
|
109
|
+
" Without --port, sidebar tries 5180-5189 in order.",
|
|
110
|
+
" --scope <glob> Override the default workspace glob (docs/**/*.md).",
|
|
111
|
+
" --browser <name> default | none | <app-name>. `none` skips browser launch.",
|
|
112
|
+
" --verbose Raise log level to DEBUG.",
|
|
113
|
+
" --quiet Lower log level to WARN.",
|
|
114
|
+
" -h, --help Show this help.",
|
|
115
|
+
"",
|
|
116
|
+
].join("\n");
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/server/args.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,SAAU,SAAQ,KAAK;CAAG;AAEvC,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,GAAG,GAAe;QACtB,UAAU,EAAE,OAAO;QACnB,SAAS,EAAE,SAAS;QACpB,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,KAAK;QACZ,aAAa,EAAE,KAAK;KACrB,CAAC;IAEF,uEAAuE;IACvE,qEAAqE;IACrE,kEAAkE;IAClE,0CAA0C;IAC1C,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC;QACxB,CAAC,GAAG,CAAC,CAAC;QACN,mEAAmE;QACnE,cAAc;QACd,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC,IAAI,CAAC,CAAC;QACT,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,QAAQ,CAAC,EAAE,CAAC;YACV,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI,CAAC,CAAC,CAAC;gBACV,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpB,oEAAoE;gBACpE,gEAAgE;gBAChE,mCAAmC;gBACnC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC3B,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,IAAI,WAAW,GAAG,CAAC,CAAC;gBACzF,CAAC;gBACD,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjC,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC;oBACf,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,GAAG,CAAC,CAAC;gBAChE,CAAC;gBACD,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;gBACb,MAAM;YACR,CAAC;YACD,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpB,IAAI,CAAC,CAAC;oBAAE,MAAM,IAAI,SAAS,CAAC,wBAAwB,CAAC,CAAC;gBACtD,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;gBACd,MAAM;YACR,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpB,IAAI,CAAC,CAAC;oBAAE,MAAM,IAAI,SAAS,CAAC,wDAAwD,CAAC,CAAC;gBACtF,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC;gBAChB,MAAM;YACR,CAAC;YACD,KAAK,SAAS;gBACZ,IAAI,GAAG,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;oBAC/B,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;gBACtE,CAAC;gBACD,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC;gBACzB,MAAM;YACR,KAAK,OAAO,CAAC;YACb,KAAK,IAAI;gBACP,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC;gBACf,MAAM;YACR,KAAK,WAAW;gBACd,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;gBACnB,MAAM;YACR,KAAK,SAAS;gBACZ,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC;gBACzB,MAAM;YACR;gBACE,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBACvB,MAAM,IAAI,SAAS,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBAC5C,CAAC;gBACD,MAAM,IAAI,SAAS,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO;QACL,uCAAuC;QACvC,EAAE;QACF,+EAA+E;QAC/E,EAAE;QACF,cAAc;QACd,iEAAiE;QACjE,6EAA6E;QAC7E,4EAA4E;QAC5E,gEAAgE;QAChE,4EAA4E;QAC5E,kEAAkE;QAClE,EAAE;QACF,UAAU;QACV,8EAA8E;QAC9E,uEAAuE;QACvE,yEAAyE;QACzE,+EAA+E;QAC/E,+CAA+C;QAC/C,8CAA8C;QAC9C,qCAAqC;QACrC,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolveHumanAuthor(cwd: string, env?: Record<string, string | undefined>): string;
|