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,115 @@
|
|
|
1
|
+
import { type Mention, type ParseError } from "../shared/markers.js";
|
|
2
|
+
import type { Workspace } from "./workspace.js";
|
|
3
|
+
export type FileMention = Mention & {
|
|
4
|
+
/** Workspace-relative POSIX path of the file the marker lives in. */
|
|
5
|
+
file: string;
|
|
6
|
+
/** ISO timestamp the mention was first observed at runtime. */
|
|
7
|
+
created_at: string;
|
|
8
|
+
};
|
|
9
|
+
export type MentionCreatedAtMap = Map<string, string>;
|
|
10
|
+
export type ListPendingResult = {
|
|
11
|
+
mentions: FileMention[];
|
|
12
|
+
/** Files we attempted to parse, with per-file malformed-marker error counts. */
|
|
13
|
+
malformedByFile: Map<string, ParseError[]>;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Walk every file in the workspace glob, parse the markers, and return all
|
|
17
|
+
* well-formed mentions across files. Malformed markers are skipped from the
|
|
18
|
+
* returned mentions but their errors are returned per-file so callers can
|
|
19
|
+
* surface "one stderr warning per file" (spec: Failure Modes / Malformed
|
|
20
|
+
* markers).
|
|
21
|
+
*
|
|
22
|
+
* `firstSeenAt` maps mention id -> ISO timestamp; the caller (the server's
|
|
23
|
+
* mention-tracker) supplies it so re-scans don't reset created_at.
|
|
24
|
+
*/
|
|
25
|
+
export declare function listMentions(ws: Workspace, firstSeenAt: MentionCreatedAtMap, now?: () => Date): Promise<ListPendingResult>;
|
|
26
|
+
export declare function findMention(ws: Workspace, mentionId: string, firstSeenAt: MentionCreatedAtMap): Promise<FileMention | null>;
|
|
27
|
+
export type CreateMentionInput = {
|
|
28
|
+
path: string;
|
|
29
|
+
/** UTF-16 char offset where the target region begins (inclusive). */
|
|
30
|
+
startOffset: number;
|
|
31
|
+
/** UTF-16 char offset where the target region ends (exclusive). */
|
|
32
|
+
endOffset: number;
|
|
33
|
+
verb: string;
|
|
34
|
+
instruction: string;
|
|
35
|
+
/** Resolved human author (caller passes the already-resolved value). */
|
|
36
|
+
author: string;
|
|
37
|
+
};
|
|
38
|
+
export type CreateMentionResult = {
|
|
39
|
+
mention: {
|
|
40
|
+
id: string;
|
|
41
|
+
file: string;
|
|
42
|
+
verb: string;
|
|
43
|
+
author: string;
|
|
44
|
+
instruction: string;
|
|
45
|
+
targetContent: string;
|
|
46
|
+
baseHash: string;
|
|
47
|
+
};
|
|
48
|
+
/** The new file content (returned so the caller can broadcast it). */
|
|
49
|
+
newContent: string;
|
|
50
|
+
diskHash: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Wrap the target region in a begin/end pair and write the new file to disk.
|
|
54
|
+
* The id is generated server-side (ADR-0003: the agent never invents an id;
|
|
55
|
+
* the same rule applies to the editor — the parser-resident state is the
|
|
56
|
+
* only source of truth for ids).
|
|
57
|
+
*/
|
|
58
|
+
export declare function createMention(ws: Workspace, input: CreateMentionInput): Promise<CreateMentionResult>;
|
|
59
|
+
export type ResolveAction = {
|
|
60
|
+
type: "replace";
|
|
61
|
+
content: string;
|
|
62
|
+
} | {
|
|
63
|
+
type: "annotation";
|
|
64
|
+
annotation_type: "note" | "suggestion";
|
|
65
|
+
text: string;
|
|
66
|
+
};
|
|
67
|
+
export type ResolveResult = {
|
|
68
|
+
kind: "ok";
|
|
69
|
+
newContent: string;
|
|
70
|
+
} | {
|
|
71
|
+
kind: "conflict";
|
|
72
|
+
current_base_hash: string;
|
|
73
|
+
} | {
|
|
74
|
+
kind: "not-found";
|
|
75
|
+
} | {
|
|
76
|
+
kind: "orphaned";
|
|
77
|
+
} | {
|
|
78
|
+
kind: "verb-not-replaceable";
|
|
79
|
+
verb: string;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Resolve a mention. Honors ADR-0002: the begin/end pair disappears.
|
|
83
|
+
*
|
|
84
|
+
* - replace: the entire begin/end pair plus the target region is replaced by
|
|
85
|
+
* the agent's content. Authorization scope is exactly this region.
|
|
86
|
+
* - annotation (note): the mention markers go; the original target prose
|
|
87
|
+
* stays in place; a new note annotation wraps that target.
|
|
88
|
+
*
|
|
89
|
+
* The caller is responsible for verb-policy enforcement (replace requires the
|
|
90
|
+
* verb's catalog entry to be in "replace" mode; unknown or "annotation"-mode
|
|
91
|
+
* verbs are restricted to annotation actions only).
|
|
92
|
+
*/
|
|
93
|
+
export declare function resolveMention(ws: Workspace, mentionId: string, action: ResolveAction, agentBaseHash: string, options: {
|
|
94
|
+
verbMode: "replace" | "annotation" | "unknown";
|
|
95
|
+
annotationAuthor: string;
|
|
96
|
+
firstSeenAt: MentionCreatedAtMap;
|
|
97
|
+
}): Promise<ResolveResult>;
|
|
98
|
+
/**
|
|
99
|
+
* Cancel an open mention from the editor (right-click "cancel mention"
|
|
100
|
+
* action). The begin/end pair is removed; the target content stays.
|
|
101
|
+
*/
|
|
102
|
+
export declare function cancelMention(ws: Workspace, mentionId: string, firstSeenAt: MentionCreatedAtMap): Promise<{
|
|
103
|
+
kind: "ok";
|
|
104
|
+
newContent: string;
|
|
105
|
+
file: string;
|
|
106
|
+
} | {
|
|
107
|
+
kind: "not-found";
|
|
108
|
+
}>;
|
|
109
|
+
/**
|
|
110
|
+
* Emit one stderr warning per file that has malformed markers (spec: Failure
|
|
111
|
+
* Modes / Malformed markers — "one warning per affected file, not per
|
|
112
|
+
* marker"). Used by the listMentions consumer; held here so the wording is
|
|
113
|
+
* shared across MCP and editor entry points.
|
|
114
|
+
*/
|
|
115
|
+
export declare function warnOnceForMalformed(malformedByFile: Map<string, ParseError[]>): void;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { existsSync, statSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import fastGlob from "fast-glob";
|
|
4
|
+
import { computeMentionBaseHash, formatAnnotationBegin, formatAnnotationEnd, formatMentionBegin, formatMentionEnd, parseMarkers, sanitizeAttribute, } from "../shared/markers.js";
|
|
5
|
+
import { generateMentionId, generateNoteId } from "./marker-ids.js";
|
|
6
|
+
import { resolveHumanAuthor } from "./author.js";
|
|
7
|
+
import { log } from "./log.js";
|
|
8
|
+
const SCAN_IGNORE = ["**/.git/**", "**/node_modules/**", "**/dist/**", "**/.sidebar/**"];
|
|
9
|
+
/**
|
|
10
|
+
* Walk every file in the workspace glob, parse the markers, and return all
|
|
11
|
+
* well-formed mentions across files. Malformed markers are skipped from the
|
|
12
|
+
* returned mentions but their errors are returned per-file so callers can
|
|
13
|
+
* surface "one stderr warning per file" (spec: Failure Modes / Malformed
|
|
14
|
+
* markers).
|
|
15
|
+
*
|
|
16
|
+
* `firstSeenAt` maps mention id -> ISO timestamp; the caller (the server's
|
|
17
|
+
* mention-tracker) supplies it so re-scans don't reset created_at.
|
|
18
|
+
*/
|
|
19
|
+
export async function listMentions(ws, firstSeenAt, now = () => new Date()) {
|
|
20
|
+
const files = await fastGlob(ws.innerGlob, {
|
|
21
|
+
cwd: ws.root,
|
|
22
|
+
onlyFiles: true,
|
|
23
|
+
dot: false,
|
|
24
|
+
followSymbolicLinks: false,
|
|
25
|
+
ignore: SCAN_IGNORE,
|
|
26
|
+
});
|
|
27
|
+
files.sort();
|
|
28
|
+
const out = [];
|
|
29
|
+
const malformedByFile = new Map();
|
|
30
|
+
for (const rel of files) {
|
|
31
|
+
let text;
|
|
32
|
+
try {
|
|
33
|
+
text = await readFile(ws.toAbs(rel), "utf8");
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const parsed = parseMarkers(text);
|
|
39
|
+
if (parsed.errors.length > 0)
|
|
40
|
+
malformedByFile.set(rel, parsed.errors);
|
|
41
|
+
for (const m of parsed.mentions) {
|
|
42
|
+
let createdAt = firstSeenAt.get(m.id);
|
|
43
|
+
if (!createdAt) {
|
|
44
|
+
createdAt = now().toISOString();
|
|
45
|
+
firstSeenAt.set(m.id, createdAt);
|
|
46
|
+
}
|
|
47
|
+
out.push({ ...m, file: rel, created_at: createdAt });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { mentions: out, malformedByFile };
|
|
51
|
+
}
|
|
52
|
+
export async function findMention(ws, mentionId, firstSeenAt) {
|
|
53
|
+
const result = await listMentions(ws, firstSeenAt);
|
|
54
|
+
return result.mentions.find((m) => m.id === mentionId) ?? null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Wrap the target region in a begin/end pair and write the new file to disk.
|
|
58
|
+
* The id is generated server-side (ADR-0003: the agent never invents an id;
|
|
59
|
+
* the same rule applies to the editor — the parser-resident state is the
|
|
60
|
+
* only source of truth for ids).
|
|
61
|
+
*/
|
|
62
|
+
export async function createMention(ws, input) {
|
|
63
|
+
const abs = ws.toAbs(input.path);
|
|
64
|
+
const original = await readFile(abs, "utf8");
|
|
65
|
+
if (input.startOffset < 0 ||
|
|
66
|
+
input.endOffset > original.length ||
|
|
67
|
+
input.startOffset > input.endOffset) {
|
|
68
|
+
throw new Error(`createMention: invalid offsets [${input.startOffset}, ${input.endOffset}] for file length ${original.length}`);
|
|
69
|
+
}
|
|
70
|
+
const before = original.slice(0, input.startOffset);
|
|
71
|
+
const target = original.slice(input.startOffset, input.endOffset);
|
|
72
|
+
const after = original.slice(input.endOffset);
|
|
73
|
+
// Mention markers occupy full lines. Insert a newline before the begin
|
|
74
|
+
// marker if the cut isn't at a line boundary, and after the end marker
|
|
75
|
+
// if the cut isn't at the start of a line.
|
|
76
|
+
const beginPrefix = before.length > 0 && !before.endsWith("\n") ? "\n" : "";
|
|
77
|
+
const endSuffix = after.length > 0 && !after.startsWith("\n") ? "\n" : "";
|
|
78
|
+
// The target region itself should end in a newline so the end marker sits
|
|
79
|
+
// on its own line; if the user selected a partial line, normalize.
|
|
80
|
+
const normalizedTarget = target.length === 0 || target.endsWith("\n") ? target : `${target}\n`;
|
|
81
|
+
const id = generateMentionId();
|
|
82
|
+
const begin = formatMentionBegin({
|
|
83
|
+
id,
|
|
84
|
+
verb: input.verb,
|
|
85
|
+
origin: "human",
|
|
86
|
+
author: input.author,
|
|
87
|
+
instruction: input.instruction,
|
|
88
|
+
});
|
|
89
|
+
const end = formatMentionEnd(id);
|
|
90
|
+
const newContent = `${before}${beginPrefix}${begin}\n${normalizedTarget}${end}${endSuffix}${after}`;
|
|
91
|
+
await writeFile(abs, newContent, "utf8");
|
|
92
|
+
return {
|
|
93
|
+
mention: {
|
|
94
|
+
id,
|
|
95
|
+
file: input.path,
|
|
96
|
+
verb: input.verb,
|
|
97
|
+
author: sanitizeAttribute(input.author),
|
|
98
|
+
instruction: input.instruction,
|
|
99
|
+
targetContent: normalizedTarget,
|
|
100
|
+
baseHash: computeMentionBaseHash(normalizedTarget),
|
|
101
|
+
},
|
|
102
|
+
newContent,
|
|
103
|
+
diskHash: "",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Resolve a mention. Honors ADR-0002: the begin/end pair disappears.
|
|
108
|
+
*
|
|
109
|
+
* - replace: the entire begin/end pair plus the target region is replaced by
|
|
110
|
+
* the agent's content. Authorization scope is exactly this region.
|
|
111
|
+
* - annotation (note): the mention markers go; the original target prose
|
|
112
|
+
* stays in place; a new note annotation wraps that target.
|
|
113
|
+
*
|
|
114
|
+
* The caller is responsible for verb-policy enforcement (replace requires the
|
|
115
|
+
* verb's catalog entry to be in "replace" mode; unknown or "annotation"-mode
|
|
116
|
+
* verbs are restricted to annotation actions only).
|
|
117
|
+
*/
|
|
118
|
+
export async function resolveMention(ws, mentionId, action, agentBaseHash, options) {
|
|
119
|
+
// Re-scan to find the mention. We need a fresh parse so we can refuse on
|
|
120
|
+
// base_hash mismatch.
|
|
121
|
+
const result = await listMentions(ws, options.firstSeenAt);
|
|
122
|
+
const target = result.mentions.find((m) => m.id === mentionId);
|
|
123
|
+
if (!target)
|
|
124
|
+
return { kind: "not-found" };
|
|
125
|
+
if (target.orphan)
|
|
126
|
+
return { kind: "orphaned" };
|
|
127
|
+
if (target.baseHash !== agentBaseHash) {
|
|
128
|
+
return { kind: "conflict", current_base_hash: target.baseHash };
|
|
129
|
+
}
|
|
130
|
+
if (action.type === "replace") {
|
|
131
|
+
if (options.verbMode !== "replace") {
|
|
132
|
+
return { kind: "verb-not-replaceable", verb: target.verb };
|
|
133
|
+
}
|
|
134
|
+
const abs = ws.toAbs(target.file);
|
|
135
|
+
const original = await readFile(abs, "utf8");
|
|
136
|
+
const replacement = ensureTrailingNewline(action.content);
|
|
137
|
+
const newContent = original.slice(0, target.beginLineStart) + replacement + original.slice(target.endLineEnd);
|
|
138
|
+
await writeFile(abs, newContent, "utf8");
|
|
139
|
+
return { kind: "ok", newContent };
|
|
140
|
+
}
|
|
141
|
+
// Annotation resolution. Only the `note` flavor is reachable here; the
|
|
142
|
+
// MCP layer rejects `suggestion` before we run (slice 5 contract). The
|
|
143
|
+
// mention markers are stripped; the original target content stays; a fresh
|
|
144
|
+
// note annotation pair wraps the same region.
|
|
145
|
+
if (action.annotation_type !== "note") {
|
|
146
|
+
return { kind: "verb-not-replaceable", verb: target.verb };
|
|
147
|
+
}
|
|
148
|
+
const noteId = generateNoteId();
|
|
149
|
+
const noteBegin = formatAnnotationBegin({
|
|
150
|
+
type: "note",
|
|
151
|
+
id: noteId,
|
|
152
|
+
author: options.annotationAuthor,
|
|
153
|
+
instruction: action.text,
|
|
154
|
+
});
|
|
155
|
+
const noteEnd = formatAnnotationEnd(noteId);
|
|
156
|
+
const abs = ws.toAbs(target.file);
|
|
157
|
+
const original = await readFile(abs, "utf8");
|
|
158
|
+
const replacement = `${noteBegin}\n${target.targetContent}${noteEnd}\n`;
|
|
159
|
+
const newContent = original.slice(0, target.beginLineStart) + replacement + original.slice(target.endLineEnd);
|
|
160
|
+
await writeFile(abs, newContent, "utf8");
|
|
161
|
+
return { kind: "ok", newContent };
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Cancel an open mention from the editor (right-click "cancel mention"
|
|
165
|
+
* action). The begin/end pair is removed; the target content stays.
|
|
166
|
+
*/
|
|
167
|
+
export async function cancelMention(ws, mentionId, firstSeenAt) {
|
|
168
|
+
const result = await listMentions(ws, firstSeenAt);
|
|
169
|
+
const target = result.mentions.find((m) => m.id === mentionId);
|
|
170
|
+
if (!target)
|
|
171
|
+
return { kind: "not-found" };
|
|
172
|
+
const abs = ws.toAbs(target.file);
|
|
173
|
+
const original = await readFile(abs, "utf8");
|
|
174
|
+
const newContent = original.slice(0, target.beginLineStart) +
|
|
175
|
+
target.targetContent +
|
|
176
|
+
original.slice(target.endLineEnd);
|
|
177
|
+
await writeFile(abs, newContent, "utf8");
|
|
178
|
+
return { kind: "ok", newContent, file: target.file };
|
|
179
|
+
}
|
|
180
|
+
function ensureTrailingNewline(s) {
|
|
181
|
+
return s.endsWith("\n") ? s : `${s}\n`;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Emit one stderr warning per file that has malformed markers (spec: Failure
|
|
185
|
+
* Modes / Malformed markers — "one warning per affected file, not per
|
|
186
|
+
* marker"). Used by the listMentions consumer; held here so the wording is
|
|
187
|
+
* shared across MCP and editor entry points.
|
|
188
|
+
*/
|
|
189
|
+
export function warnOnceForMalformed(malformedByFile) {
|
|
190
|
+
for (const [file, errors] of malformedByFile) {
|
|
191
|
+
const kinds = Array.from(new Set(errors.map((e) => e.kind))).join(",");
|
|
192
|
+
log.warn(`malformed sidebar markers in ${file} (${errors.length} defect(s): ${kinds})`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// `existsSync` / `statSync` aren't used here but the editor's CodeMirror
|
|
196
|
+
// integration imports them transitively via @codemirror modules. Re-export
|
|
197
|
+
// nothing; this comment exists to flag the dependency awareness for future
|
|
198
|
+
// maintainers.
|
|
199
|
+
void existsSync;
|
|
200
|
+
void statSync;
|
|
201
|
+
void resolveHumanAuthor;
|
|
202
|
+
//# sourceMappingURL=mention-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-ops.js","sourceRoot":"","sources":["../../src/server/mention-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
export type ClaimRecord = {
|
|
2
|
+
mentionId: string;
|
|
3
|
+
agentName: string;
|
|
4
|
+
claimedAt: number;
|
|
5
|
+
};
|
|
6
|
+
export type RecentEvent = {
|
|
7
|
+
id: number;
|
|
8
|
+
kind: "mention-created";
|
|
9
|
+
mention_id: string;
|
|
10
|
+
file: string;
|
|
11
|
+
verb: string;
|
|
12
|
+
origin: "human" | "agent";
|
|
13
|
+
author: string;
|
|
14
|
+
at: string;
|
|
15
|
+
} | {
|
|
16
|
+
id: number;
|
|
17
|
+
kind: "mention-claimed";
|
|
18
|
+
mention_id: string;
|
|
19
|
+
file: string;
|
|
20
|
+
agent: string;
|
|
21
|
+
at: string;
|
|
22
|
+
} | {
|
|
23
|
+
id: number;
|
|
24
|
+
kind: "mention-released";
|
|
25
|
+
mention_id: string;
|
|
26
|
+
file: string;
|
|
27
|
+
agent: string;
|
|
28
|
+
reason: string;
|
|
29
|
+
at: string;
|
|
30
|
+
} | {
|
|
31
|
+
id: number;
|
|
32
|
+
kind: "mention-resolved";
|
|
33
|
+
mention_id: string;
|
|
34
|
+
file: string;
|
|
35
|
+
agent: string;
|
|
36
|
+
resolution: "replace" | "annotation";
|
|
37
|
+
at: string;
|
|
38
|
+
} | {
|
|
39
|
+
id: number;
|
|
40
|
+
kind: "mention-cancelled";
|
|
41
|
+
mention_id: string;
|
|
42
|
+
file: string;
|
|
43
|
+
at: string;
|
|
44
|
+
} | {
|
|
45
|
+
id: number;
|
|
46
|
+
kind: "file-edited";
|
|
47
|
+
file: string;
|
|
48
|
+
author: string;
|
|
49
|
+
at: string;
|
|
50
|
+
} | {
|
|
51
|
+
id: number;
|
|
52
|
+
kind: "annotation-created";
|
|
53
|
+
annotation_id: string;
|
|
54
|
+
file: string;
|
|
55
|
+
annotation_type: "note" | "suggestion";
|
|
56
|
+
author: string;
|
|
57
|
+
at: string;
|
|
58
|
+
} | {
|
|
59
|
+
id: number;
|
|
60
|
+
kind: "annotation-removed";
|
|
61
|
+
annotation_id: string;
|
|
62
|
+
file: string;
|
|
63
|
+
annotation_type: "note" | "suggestion";
|
|
64
|
+
author: string;
|
|
65
|
+
at: string;
|
|
66
|
+
} | {
|
|
67
|
+
id: number;
|
|
68
|
+
kind: "suggestion-accepted";
|
|
69
|
+
annotation_id: string;
|
|
70
|
+
file: string;
|
|
71
|
+
author: string;
|
|
72
|
+
at: string;
|
|
73
|
+
} | {
|
|
74
|
+
id: number;
|
|
75
|
+
kind: "suggestion-rejected";
|
|
76
|
+
annotation_id: string;
|
|
77
|
+
file: string;
|
|
78
|
+
author: string;
|
|
79
|
+
at: string;
|
|
80
|
+
};
|
|
81
|
+
export type ConnectedAgent = {
|
|
82
|
+
name: string;
|
|
83
|
+
connectedAt: number;
|
|
84
|
+
};
|
|
85
|
+
export type RecentEventInput = Omit<Extract<RecentEvent, {
|
|
86
|
+
kind: "mention-created";
|
|
87
|
+
}>, "id"> | Omit<Extract<RecentEvent, {
|
|
88
|
+
kind: "mention-claimed";
|
|
89
|
+
}>, "id"> | Omit<Extract<RecentEvent, {
|
|
90
|
+
kind: "mention-released";
|
|
91
|
+
}>, "id"> | Omit<Extract<RecentEvent, {
|
|
92
|
+
kind: "mention-resolved";
|
|
93
|
+
}>, "id"> | Omit<Extract<RecentEvent, {
|
|
94
|
+
kind: "mention-cancelled";
|
|
95
|
+
}>, "id"> | Omit<Extract<RecentEvent, {
|
|
96
|
+
kind: "file-edited";
|
|
97
|
+
}>, "id"> | Omit<Extract<RecentEvent, {
|
|
98
|
+
kind: "annotation-created";
|
|
99
|
+
}>, "id"> | Omit<Extract<RecentEvent, {
|
|
100
|
+
kind: "annotation-removed";
|
|
101
|
+
}>, "id"> | Omit<Extract<RecentEvent, {
|
|
102
|
+
kind: "suggestion-accepted";
|
|
103
|
+
}>, "id"> | Omit<Extract<RecentEvent, {
|
|
104
|
+
kind: "suggestion-rejected";
|
|
105
|
+
}>, "id">;
|
|
106
|
+
export type MentionStore = {
|
|
107
|
+
claim: (mentionId: string, agentName: string) => {
|
|
108
|
+
ok: true;
|
|
109
|
+
} | {
|
|
110
|
+
ok: false;
|
|
111
|
+
heldBy: string;
|
|
112
|
+
};
|
|
113
|
+
release: (mentionId: string) => ClaimRecord | null;
|
|
114
|
+
claimOf: (mentionId: string) => ClaimRecord | null;
|
|
115
|
+
/** All current claims, snapshot. */
|
|
116
|
+
claims: () => ClaimRecord[];
|
|
117
|
+
recordEvent: (e: RecentEventInput) => RecentEvent;
|
|
118
|
+
recentEvents: (since?: number) => RecentEvent[];
|
|
119
|
+
registerAgent: (name: string) => () => void;
|
|
120
|
+
connectedAgents: () => ConnectedAgent[];
|
|
121
|
+
onChange: (fn: () => void) => () => void;
|
|
122
|
+
};
|
|
123
|
+
export declare function createMentionStore(now?: () => number): MentionStore;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// In-memory state layer for slice 4. Holds:
|
|
2
|
+
//
|
|
3
|
+
// - mention claims (the transient in-progress state for each open mention,
|
|
4
|
+
// plus the claiming client's identity for conflict reporting)
|
|
5
|
+
// - the recent-changes ring buffer (last 50 events, monotonic id cursor)
|
|
6
|
+
// - connected MCP clients (for the status drawer)
|
|
7
|
+
//
|
|
8
|
+
// State is process-local and resets on restart. Persistence is out of scope
|
|
9
|
+
// for V1 (spec: Architecture / In-memory state layer).
|
|
10
|
+
const RING_CAPACITY = 50;
|
|
11
|
+
export function createMentionStore(now = Date.now) {
|
|
12
|
+
const claims = new Map();
|
|
13
|
+
const ring = [];
|
|
14
|
+
let nextEventId = 1;
|
|
15
|
+
const agents = new Map();
|
|
16
|
+
// Multiple connections from one client get a "-2", "-3" suffix while
|
|
17
|
+
// simultaneous; we track per-name counts.
|
|
18
|
+
const nameUseCounts = new Map();
|
|
19
|
+
const changeListeners = new Set();
|
|
20
|
+
const notify = () => {
|
|
21
|
+
for (const fn of changeListeners) {
|
|
22
|
+
try {
|
|
23
|
+
fn();
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
/* listener errors should not break the store */
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
claim(mentionId, agentName) {
|
|
32
|
+
const existing = claims.get(mentionId);
|
|
33
|
+
if (existing)
|
|
34
|
+
return { ok: false, heldBy: existing.agentName };
|
|
35
|
+
claims.set(mentionId, { mentionId, agentName, claimedAt: now() });
|
|
36
|
+
notify();
|
|
37
|
+
return { ok: true };
|
|
38
|
+
},
|
|
39
|
+
release(mentionId) {
|
|
40
|
+
const cur = claims.get(mentionId);
|
|
41
|
+
if (!cur)
|
|
42
|
+
return null;
|
|
43
|
+
claims.delete(mentionId);
|
|
44
|
+
notify();
|
|
45
|
+
return cur;
|
|
46
|
+
},
|
|
47
|
+
claimOf(mentionId) {
|
|
48
|
+
return claims.get(mentionId) ?? null;
|
|
49
|
+
},
|
|
50
|
+
claims() {
|
|
51
|
+
return Array.from(claims.values());
|
|
52
|
+
},
|
|
53
|
+
recordEvent(partial) {
|
|
54
|
+
const event = { ...partial, id: nextEventId++ };
|
|
55
|
+
ring.push(event);
|
|
56
|
+
if (ring.length > RING_CAPACITY)
|
|
57
|
+
ring.shift();
|
|
58
|
+
notify();
|
|
59
|
+
return event;
|
|
60
|
+
},
|
|
61
|
+
recentEvents(since) {
|
|
62
|
+
if (since === undefined || since === null)
|
|
63
|
+
return ring.slice();
|
|
64
|
+
return ring.filter((e) => e.id > since);
|
|
65
|
+
},
|
|
66
|
+
registerAgent(name) {
|
|
67
|
+
const count = (nameUseCounts.get(name) ?? 0) + 1;
|
|
68
|
+
nameUseCounts.set(name, count);
|
|
69
|
+
const effective = count === 1 ? name : `${name}-${count}`;
|
|
70
|
+
agents.set(effective, { name: effective, connectedAt: now() });
|
|
71
|
+
notify();
|
|
72
|
+
return () => {
|
|
73
|
+
agents.delete(effective);
|
|
74
|
+
const c = (nameUseCounts.get(name) ?? 0) - 1;
|
|
75
|
+
if (c <= 0)
|
|
76
|
+
nameUseCounts.delete(name);
|
|
77
|
+
else
|
|
78
|
+
nameUseCounts.set(name, c);
|
|
79
|
+
notify();
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
connectedAgents() {
|
|
83
|
+
return Array.from(agents.values()).sort((a, b) => a.connectedAt - b.connectedAt);
|
|
84
|
+
},
|
|
85
|
+
onChange(fn) {
|
|
86
|
+
changeListeners.add(fn);
|
|
87
|
+
return () => changeListeners.delete(fn);
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=mention-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-store.js","sourceRoot":"","sources":["../../src/server/mention-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function assertNodeVersion(version: string): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Per ADR-0008, sidebar targets Node 20 LTS or later. Older runtimes refuse
|
|
2
|
+
// to start with a clear error rather than failing on a missing API later.
|
|
3
|
+
export function assertNodeVersion(version) {
|
|
4
|
+
const match = version.match(/^v?(\d+)/);
|
|
5
|
+
const major = match ? Number.parseInt(match[1], 10) : Number.NaN;
|
|
6
|
+
if (!Number.isFinite(major) || major < 20) {
|
|
7
|
+
throw new Error(`sidebar requires Node 20 or newer (got ${version}). Update Node and try again.`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=runtime-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-check.js","sourceRoot":"","sources":["../../src/server/runtime-check.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,0EAA0E;AAC1E,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,0CAA0C,OAAO,+BAA+B,CACjF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type AnnotationCreatedAtMap } from "./annotation-ops.js";
|
|
2
|
+
import { type DirtyBufferTracker } from "./dirty-buffer.js";
|
|
3
|
+
import { type MentionCreatedAtMap } from "./mention-ops.js";
|
|
4
|
+
import { type MentionStore } from "./mention-store.js";
|
|
5
|
+
import type { VerbCatalog } from "./verbs/index.js";
|
|
6
|
+
import { type Workspace } from "./workspace.js";
|
|
7
|
+
export type ServerHandle = {
|
|
8
|
+
url: string;
|
|
9
|
+
port: number;
|
|
10
|
+
workspace: Workspace;
|
|
11
|
+
dirtyBuffers: DirtyBufferTracker;
|
|
12
|
+
mentionStore: MentionStore;
|
|
13
|
+
mentionCreatedAt: MentionCreatedAtMap;
|
|
14
|
+
annotationCreatedAt: AnnotationCreatedAtMap;
|
|
15
|
+
verbCatalog: VerbCatalog;
|
|
16
|
+
close: () => Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
export type StartOptions = {
|
|
19
|
+
workspace: Workspace;
|
|
20
|
+
/** 0 = let the OS pick a free port. */
|
|
21
|
+
port: number;
|
|
22
|
+
host?: string;
|
|
23
|
+
/** Absolute path to the built SPA, or null when running unbuilt. */
|
|
24
|
+
staticRoot?: string | null;
|
|
25
|
+
/** Verb catalog assembled from built-ins + custom config. */
|
|
26
|
+
verbCatalog: VerbCatalog;
|
|
27
|
+
};
|
|
28
|
+
export declare function startServer(opts: StartOptions): Promise<ServerHandle>;
|