@pasko70/pibo 1.0.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/.codex/skills/pi-agent-harness/SKILL.md +319 -0
- package/.codex/skills/pi-agent-harness/agents/openai.yaml +4 -0
- package/README.md +318 -0
- package/context/codex-base-prompt.md +144 -0
- package/context/pibo-compaction-prompt.md +100 -0
- package/context/pibo-system-prompt.md +17 -0
- package/dist/apps/chat/agent-profiles.js +26 -0
- package/dist/apps/chat/agent-store.js +336 -0
- package/dist/apps/chat/event-log.js +307 -0
- package/dist/apps/chat/read-model.js +218 -0
- package/dist/apps/chat/rooms.js +321 -0
- package/dist/apps/chat/session-metadata.js +14 -0
- package/dist/apps/chat/stream.js +122 -0
- package/dist/apps/chat/trace.js +1182 -0
- package/dist/apps/chat/web-app.js +2569 -0
- package/dist/apps/chat-ui/assets/apl-BxEMbctQ.js +1 -0
- package/dist/apps/chat-ui/assets/asciiarmor-eFjeGRuZ.js +1 -0
- package/dist/apps/chat-ui/assets/asn1-Cfx-0pt9.js +1 -0
- package/dist/apps/chat-ui/assets/asterisk-B5BHTsBr.js +1 -0
- package/dist/apps/chat-ui/assets/brainfuck-CAA2xofr.js +1 -0
- package/dist/apps/chat-ui/assets/clike-BoDCOLzN.js +1 -0
- package/dist/apps/chat-ui/assets/clojure-kVFSWX0o.js +1 -0
- package/dist/apps/chat-ui/assets/cmake-BUPAhezI.js +1 -0
- package/dist/apps/chat-ui/assets/cobol-BfgHZgup.js +1 -0
- package/dist/apps/chat-ui/assets/coffeescript-G1Pe_1AZ.js +1 -0
- package/dist/apps/chat-ui/assets/commonlisp-B3N0CjHn.js +1 -0
- package/dist/apps/chat-ui/assets/crystal-C15ndaGM.js +1 -0
- package/dist/apps/chat-ui/assets/css-BqOeyZOV.js +1 -0
- package/dist/apps/chat-ui/assets/cypher-KjIKv-wW.js +1 -0
- package/dist/apps/chat-ui/assets/d-BlT5AEC-.js +1 -0
- package/dist/apps/chat-ui/assets/diff-oF98tbqj.js +1 -0
- package/dist/apps/chat-ui/assets/dist--55mTWk3.js +1 -0
- package/dist/apps/chat-ui/assets/dist-B5rcjVCj.js +1 -0
- package/dist/apps/chat-ui/assets/dist-BPv5MdlL.js +1 -0
- package/dist/apps/chat-ui/assets/dist-BZ39rB1W.js +1 -0
- package/dist/apps/chat-ui/assets/dist-BsedZGJo.js +1 -0
- package/dist/apps/chat-ui/assets/dist-BvO6SpaM.js +9 -0
- package/dist/apps/chat-ui/assets/dist-C5YJOwhH.js +1 -0
- package/dist/apps/chat-ui/assets/dist-C5oXtFSP.js +1 -0
- package/dist/apps/chat-ui/assets/dist-CG_gRSwv.js +23 -0
- package/dist/apps/chat-ui/assets/dist-CKM5j-iy.js +1 -0
- package/dist/apps/chat-ui/assets/dist-CUp9us2q.js +1 -0
- package/dist/apps/chat-ui/assets/dist-CZ9T4Cly.js +1 -0
- package/dist/apps/chat-ui/assets/dist-D4HhiFWB.js +6 -0
- package/dist/apps/chat-ui/assets/dist-DHE-yBLH.js +1 -0
- package/dist/apps/chat-ui/assets/dist-DSKQpPaz.js +1 -0
- package/dist/apps/chat-ui/assets/dist-L1B-KWZO.js +1 -0
- package/dist/apps/chat-ui/assets/dist-SVPsM5Oi.js +13 -0
- package/dist/apps/chat-ui/assets/dist-Zqt9kNG9.js +1 -0
- package/dist/apps/chat-ui/assets/dist-_DPv0-QF.js +1 -0
- package/dist/apps/chat-ui/assets/dist-_oM7g0eh.js +11 -0
- package/dist/apps/chat-ui/assets/dist-laadbMWg.js +1 -0
- package/dist/apps/chat-ui/assets/dist-nFui3f-r.js +2 -0
- package/dist/apps/chat-ui/assets/dist-tGfufz3b.js +1 -0
- package/dist/apps/chat-ui/assets/dockerfile-CUaqzcqp.js +1 -0
- package/dist/apps/chat-ui/assets/dtd-VCA9yr61.js +1 -0
- package/dist/apps/chat-ui/assets/dylan-O-V5Dw5W.js +1 -0
- package/dist/apps/chat-ui/assets/ebnf-SPmdBkvT.js +1 -0
- package/dist/apps/chat-ui/assets/ecl-ChfCttfI.js +1 -0
- package/dist/apps/chat-ui/assets/eiffel-cB9EbjeN.js +1 -0
- package/dist/apps/chat-ui/assets/elm-BTiVflBU.js +1 -0
- package/dist/apps/chat-ui/assets/erlang-egf0TXFm.js +1 -0
- package/dist/apps/chat-ui/assets/factor-C2tAxNob.js +1 -0
- package/dist/apps/chat-ui/assets/fcl-BiCjh1tj.js +1 -0
- package/dist/apps/chat-ui/assets/forth-C4kDGW6u.js +1 -0
- package/dist/apps/chat-ui/assets/fortran-DzkLaPnd.js +1 -0
- package/dist/apps/chat-ui/assets/gas-DMOxskQF.js +1 -0
- package/dist/apps/chat-ui/assets/gherkin-BPxBpp-k.js +1 -0
- package/dist/apps/chat-ui/assets/groovy-CkEnc0ZY.js +1 -0
- package/dist/apps/chat-ui/assets/haskell-Dadpo9-w.js +1 -0
- package/dist/apps/chat-ui/assets/haxe-CDNZL9MW.js +1 -0
- package/dist/apps/chat-ui/assets/http-jy9Zxxt3.js +1 -0
- package/dist/apps/chat-ui/assets/idl-CGSB6iiy.js +1 -0
- package/dist/apps/chat-ui/assets/index-BdcqTugD.js +151 -0
- package/dist/apps/chat-ui/assets/index-Dk-opWl3.css +1 -0
- package/dist/apps/chat-ui/assets/javascript-DSlzRUd8.js +1 -0
- package/dist/apps/chat-ui/assets/julia-DTiF9v6R.js +1 -0
- package/dist/apps/chat-ui/assets/livescript-Ci8Xxna6.js +1 -0
- package/dist/apps/chat-ui/assets/lua-eVxIrt9t.js +1 -0
- package/dist/apps/chat-ui/assets/mathematica-Da3grj36.js +1 -0
- package/dist/apps/chat-ui/assets/mbox-BWBMSafM.js +1 -0
- package/dist/apps/chat-ui/assets/mirc-CtHu9S1B.js +1 -0
- package/dist/apps/chat-ui/assets/mllike-wTFlPWXS.js +1 -0
- package/dist/apps/chat-ui/assets/modelica-cKbQ0UXu.js +1 -0
- package/dist/apps/chat-ui/assets/mscgen-C5pXQCMK.js +1 -0
- package/dist/apps/chat-ui/assets/mumps-CKBHkOQq.js +1 -0
- package/dist/apps/chat-ui/assets/nginx-B00AiQel.js +1 -0
- package/dist/apps/chat-ui/assets/nsis-SMDwKltR.js +1 -0
- package/dist/apps/chat-ui/assets/ntriples-B_36EBV0.js +1 -0
- package/dist/apps/chat-ui/assets/octave-BXPjzAif.js +1 -0
- package/dist/apps/chat-ui/assets/oz-Dedpat1M.js +1 -0
- package/dist/apps/chat-ui/assets/pascal-CMcUg72K.js +1 -0
- package/dist/apps/chat-ui/assets/perl-DoVTbnzt.js +1 -0
- package/dist/apps/chat-ui/assets/pig-CULXT1YV.js +1 -0
- package/dist/apps/chat-ui/assets/powershell-Cv5Uhf6b.js +1 -0
- package/dist/apps/chat-ui/assets/properties-CQ1C2P-M.js +1 -0
- package/dist/apps/chat-ui/assets/protobuf-SRlvzrl6.js +1 -0
- package/dist/apps/chat-ui/assets/pug-Bo3wfL-f.js +1 -0
- package/dist/apps/chat-ui/assets/puppet-ClSqCGj6.js +1 -0
- package/dist/apps/chat-ui/assets/python-C2_X1GpX.js +1 -0
- package/dist/apps/chat-ui/assets/q-B_6Gdyzl.js +1 -0
- package/dist/apps/chat-ui/assets/r-BD07NGED.js +1 -0
- package/dist/apps/chat-ui/assets/rolldown-runtime-S-ySWqyJ.js +1 -0
- package/dist/apps/chat-ui/assets/rpm-CRu5Z2Jl.js +1 -0
- package/dist/apps/chat-ui/assets/ruby-dZPnOz8h.js +1 -0
- package/dist/apps/chat-ui/assets/sas-S2t8_sDI.js +1 -0
- package/dist/apps/chat-ui/assets/scheme-WcyFWLW2.js +1 -0
- package/dist/apps/chat-ui/assets/shell-DUelnYSh.js +1 -0
- package/dist/apps/chat-ui/assets/sieve-jDjlVhNh.js +1 -0
- package/dist/apps/chat-ui/assets/simple-mode-CL04yRVp.js +1 -0
- package/dist/apps/chat-ui/assets/smalltalk-ddWDYy10.js +1 -0
- package/dist/apps/chat-ui/assets/solr-C7rQhLuW.js +1 -0
- package/dist/apps/chat-ui/assets/sparql--fPCCgVd.js +1 -0
- package/dist/apps/chat-ui/assets/spreadsheet-DjthqD5G.js +1 -0
- package/dist/apps/chat-ui/assets/sql-D_dieYbr.js +1 -0
- package/dist/apps/chat-ui/assets/stex-rHcFYcA0.js +1 -0
- package/dist/apps/chat-ui/assets/stylus-DxF70RNr.js +1 -0
- package/dist/apps/chat-ui/assets/swift-T0hDoOb-.js +1 -0
- package/dist/apps/chat-ui/assets/tcl-Dlzy1mPk.js +1 -0
- package/dist/apps/chat-ui/assets/textile-Dy5rFZe5.js +1 -0
- package/dist/apps/chat-ui/assets/tiddlywiki-DQP1OymS.js +1 -0
- package/dist/apps/chat-ui/assets/tiki-0vOj3DB2.js +1 -0
- package/dist/apps/chat-ui/assets/toml-DEltN0lI.js +1 -0
- package/dist/apps/chat-ui/assets/troff-CRbBpEqY.js +1 -0
- package/dist/apps/chat-ui/assets/ttcn-M5q1nLKg.js +1 -0
- package/dist/apps/chat-ui/assets/ttcn-cfg-Rmw9NWq9.js +1 -0
- package/dist/apps/chat-ui/assets/turtle-BCDWhJK0.js +1 -0
- package/dist/apps/chat-ui/assets/vb-QQ7LGlOz.js +1 -0
- package/dist/apps/chat-ui/assets/vbscript-BiSEdUzz.js +1 -0
- package/dist/apps/chat-ui/assets/velocity-CzMg5_6w.js +1 -0
- package/dist/apps/chat-ui/assets/verilog-BJOO83gk.js +1 -0
- package/dist/apps/chat-ui/assets/vhdl-ed4zAZAA.js +1 -0
- package/dist/apps/chat-ui/assets/webidl-Ddy6hbV6.js +1 -0
- package/dist/apps/chat-ui/assets/xquery-Bw1zwhh6.js +1 -0
- package/dist/apps/chat-ui/assets/yacas-DZdTXy3s.js +1 -0
- package/dist/apps/chat-ui/assets/z80-DMG02_YV.js +1 -0
- package/dist/apps/chat-ui/index.html +15 -0
- package/dist/apps/context-files-ui/assets/apl-14BqhLYK.js +1 -0
- package/dist/apps/context-files-ui/assets/asciiarmor-WLvjqI7d.js +1 -0
- package/dist/apps/context-files-ui/assets/asn1-Bg4FbdCg.js +1 -0
- package/dist/apps/context-files-ui/assets/asterisk-B2MO-X4d.js +1 -0
- package/dist/apps/context-files-ui/assets/brainfuck-CV9kufud.js +1 -0
- package/dist/apps/context-files-ui/assets/clike-CjmcUpt6.js +1 -0
- package/dist/apps/context-files-ui/assets/clojure-De3QGfx6.js +1 -0
- package/dist/apps/context-files-ui/assets/cmake-i2VDNaRq.js +1 -0
- package/dist/apps/context-files-ui/assets/cobol-BwO6DF08.js +1 -0
- package/dist/apps/context-files-ui/assets/coffeescript-BtivDvRz.js +1 -0
- package/dist/apps/context-files-ui/assets/commonlisp-DFkEQdLP.js +1 -0
- package/dist/apps/context-files-ui/assets/crystal-CU0NkcVL.js +1 -0
- package/dist/apps/context-files-ui/assets/css-CbMZAQ1W.js +1 -0
- package/dist/apps/context-files-ui/assets/cypher-Dke5QOzv.js +1 -0
- package/dist/apps/context-files-ui/assets/d-TPqSVaHM.js +1 -0
- package/dist/apps/context-files-ui/assets/diff-B365LSoZ.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-B5PTVnox.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-B5ZAfwf5.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-BJW3917N.js +11 -0
- package/dist/apps/context-files-ui/assets/dist-BkUONE3N.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-CKQF1zEu.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-CwbH_3RN.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-CxRLRmMx.js +2 -0
- package/dist/apps/context-files-ui/assets/dist-D1KyNDg5.js +13 -0
- package/dist/apps/context-files-ui/assets/dist-DFi2YGux.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-DKoyMSNr.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-DLMjd26T.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-DQXzt2Ng.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-DotDq_kD.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-DyfSeBMu.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-MyZgX9K2.js +9 -0
- package/dist/apps/context-files-ui/assets/dist-QQuDy4KA.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-YwR9dpb-.js +1 -0
- package/dist/apps/context-files-ui/assets/dist-dTBsFYAl.js +1 -0
- package/dist/apps/context-files-ui/assets/dockerfile-CJb2sekW.js +1 -0
- package/dist/apps/context-files-ui/assets/dtd-CBMymJ7O.js +1 -0
- package/dist/apps/context-files-ui/assets/dylan-08Azy1NK.js +1 -0
- package/dist/apps/context-files-ui/assets/ebnf-Dkum_1J8.js +1 -0
- package/dist/apps/context-files-ui/assets/ecl-dhxjHL8y.js +1 -0
- package/dist/apps/context-files-ui/assets/eiffel-C446m6dI.js +1 -0
- package/dist/apps/context-files-ui/assets/elm-po1E9de0.js +1 -0
- package/dist/apps/context-files-ui/assets/erlang-BD5LkVkR.js +1 -0
- package/dist/apps/context-files-ui/assets/factor-B2EMQZkP.js +1 -0
- package/dist/apps/context-files-ui/assets/fcl-DkEOamHd.js +1 -0
- package/dist/apps/context-files-ui/assets/forth-dCg2_HVB.js +1 -0
- package/dist/apps/context-files-ui/assets/fortran-3ZpXLFh1.js +1 -0
- package/dist/apps/context-files-ui/assets/gas-DMmxLZRI.js +1 -0
- package/dist/apps/context-files-ui/assets/gherkin-DUSFg2R6.js +1 -0
- package/dist/apps/context-files-ui/assets/groovy-Cmduloe1.js +1 -0
- package/dist/apps/context-files-ui/assets/haskell-Cyr255R9.js +1 -0
- package/dist/apps/context-files-ui/assets/haxe-BJVKtprM.js +1 -0
- package/dist/apps/context-files-ui/assets/http-DszHFpc-.js +1 -0
- package/dist/apps/context-files-ui/assets/idl-Cati9Nrv.js +1 -0
- package/dist/apps/context-files-ui/assets/index-BwRDoHMC.css +1 -0
- package/dist/apps/context-files-ui/assets/index-GwvjXytt.js +202 -0
- package/dist/apps/context-files-ui/assets/javascript-C5pDVaoP.js +1 -0
- package/dist/apps/context-files-ui/assets/julia-DlqY1cTU.js +1 -0
- package/dist/apps/context-files-ui/assets/livescript-C6p8-2W1.js +1 -0
- package/dist/apps/context-files-ui/assets/lua-BxuTHaF7.js +1 -0
- package/dist/apps/context-files-ui/assets/mathematica-nDHZUMJT.js +1 -0
- package/dist/apps/context-files-ui/assets/mbox-DAaR0Hcz.js +1 -0
- package/dist/apps/context-files-ui/assets/mirc-CCA0FRfl.js +1 -0
- package/dist/apps/context-files-ui/assets/mllike-Cw3Iccsb.js +1 -0
- package/dist/apps/context-files-ui/assets/modelica-Czx80fNR.js +1 -0
- package/dist/apps/context-files-ui/assets/mscgen-BmfuTbzG.js +1 -0
- package/dist/apps/context-files-ui/assets/mumps-Ds_ZaumL.js +1 -0
- package/dist/apps/context-files-ui/assets/nginx-D9M2PQ4U.js +1 -0
- package/dist/apps/context-files-ui/assets/nsis-DOo3SJmd.js +1 -0
- package/dist/apps/context-files-ui/assets/ntriples-DLHGTvHs.js +1 -0
- package/dist/apps/context-files-ui/assets/octave-8jj96JiC.js +1 -0
- package/dist/apps/context-files-ui/assets/oz-BmMq7iC4.js +1 -0
- package/dist/apps/context-files-ui/assets/pascal-BgMr6XpT.js +1 -0
- package/dist/apps/context-files-ui/assets/perl-D6YJObi_.js +1 -0
- package/dist/apps/context-files-ui/assets/pig-nx7uchs8.js +1 -0
- package/dist/apps/context-files-ui/assets/powershell-B4IPkVxR.js +1 -0
- package/dist/apps/context-files-ui/assets/properties-CoavQdLC.js +1 -0
- package/dist/apps/context-files-ui/assets/protobuf-D5EWhcmc.js +1 -0
- package/dist/apps/context-files-ui/assets/pug-QU72BPAa.js +1 -0
- package/dist/apps/context-files-ui/assets/puppet-B_0GFuyD.js +1 -0
- package/dist/apps/context-files-ui/assets/python-Cs7sNzy_.js +1 -0
- package/dist/apps/context-files-ui/assets/q-BIB9pPtI.js +1 -0
- package/dist/apps/context-files-ui/assets/r-CN5s4f3o.js +1 -0
- package/dist/apps/context-files-ui/assets/rpm-Ct_Ck8mQ.js +1 -0
- package/dist/apps/context-files-ui/assets/ruby-BVPradRk.js +1 -0
- package/dist/apps/context-files-ui/assets/sas-DN4j74IF.js +1 -0
- package/dist/apps/context-files-ui/assets/scheme-CvNgHAnh.js +1 -0
- package/dist/apps/context-files-ui/assets/shell-BjiMLAaM.js +1 -0
- package/dist/apps/context-files-ui/assets/sieve-C2U1O5Z4.js +1 -0
- package/dist/apps/context-files-ui/assets/simple-mode-DnMbQuKW.js +1 -0
- package/dist/apps/context-files-ui/assets/smalltalk-DkYwYufV.js +1 -0
- package/dist/apps/context-files-ui/assets/solr-BopnSD-v.js +1 -0
- package/dist/apps/context-files-ui/assets/sparql-Cpg3YQfd.js +1 -0
- package/dist/apps/context-files-ui/assets/spreadsheet-kRxtVt9J.js +1 -0
- package/dist/apps/context-files-ui/assets/sql-DYI2GwJR.js +1 -0
- package/dist/apps/context-files-ui/assets/stex-BCRT8IJ3.js +1 -0
- package/dist/apps/context-files-ui/assets/stylus-CARoeVE9.js +1 -0
- package/dist/apps/context-files-ui/assets/swift-DKNaLAK6.js +1 -0
- package/dist/apps/context-files-ui/assets/tcl-CQyXkgMH.js +1 -0
- package/dist/apps/context-files-ui/assets/textile-Yg_UWn-t.js +1 -0
- package/dist/apps/context-files-ui/assets/tiddlywiki-dqVbkfX4.js +1 -0
- package/dist/apps/context-files-ui/assets/tiki-CC_ic8g0.js +1 -0
- package/dist/apps/context-files-ui/assets/toml-B7gGzVkJ.js +1 -0
- package/dist/apps/context-files-ui/assets/troff-Bq3z6oAu.js +1 -0
- package/dist/apps/context-files-ui/assets/ttcn-GvRgs2AT.js +1 -0
- package/dist/apps/context-files-ui/assets/ttcn-cfg-CGCXz7Vo.js +1 -0
- package/dist/apps/context-files-ui/assets/turtle-CwIpz2yy.js +1 -0
- package/dist/apps/context-files-ui/assets/vb-BmcHUM2C.js +1 -0
- package/dist/apps/context-files-ui/assets/vbscript-Cs9dylre.js +1 -0
- package/dist/apps/context-files-ui/assets/velocity-CBWU0VCy.js +1 -0
- package/dist/apps/context-files-ui/assets/verilog-DVCHmufx.js +1 -0
- package/dist/apps/context-files-ui/assets/vhdl-BGDk4f1d.js +1 -0
- package/dist/apps/context-files-ui/assets/webidl-egXQEWlC.js +1 -0
- package/dist/apps/context-files-ui/assets/xquery-5f0hn7cg.js +1 -0
- package/dist/apps/context-files-ui/assets/yacas-DNs9XkmQ.js +1 -0
- package/dist/apps/context-files-ui/assets/z80-B7Dfb4UO.js +1 -0
- package/dist/apps/context-files-ui/index.html +14 -0
- package/dist/auth/better-auth.js +129 -0
- package/dist/auth/types.js +14 -0
- package/dist/bin/pibo.js +3 -0
- package/dist/channels/types.js +1 -0
- package/dist/cli-errors.js +18 -0
- package/dist/cli.js +264 -0
- package/dist/config/config.js +167 -0
- package/dist/core/base-prompt.js +104 -0
- package/dist/core/codex-compat.js +44 -0
- package/dist/core/compaction-prompt.js +258 -0
- package/dist/core/events.js +1 -0
- package/dist/core/profiles.js +138 -0
- package/dist/core/routed-session.js +538 -0
- package/dist/core/runtime.js +323 -0
- package/dist/core/session-router.js +437 -0
- package/dist/core/system-prompt-template.js +56 -0
- package/dist/core/thinking.js +9 -0
- package/dist/core/workspace.js +5 -0
- package/dist/debug/events.js +92 -0
- package/dist/debug/index.js +631 -0
- package/dist/debug/session.js +200 -0
- package/dist/debug/sql.js +238 -0
- package/dist/debug/stores.js +49 -0
- package/dist/debug/trace.js +245 -0
- package/dist/env.js +32 -0
- package/dist/gateway/client.js +200 -0
- package/dist/gateway/protocol.js +46 -0
- package/dist/gateway/request.js +146 -0
- package/dist/gateway/server.js +221 -0
- package/dist/gateway/tool.js +69 -0
- package/dist/gateway/web.js +80 -0
- package/dist/index.js +23 -0
- package/dist/local/client.js +77 -0
- package/dist/local/extension.js +548 -0
- package/dist/local/tui.js +25 -0
- package/dist/mcp/agent-context.js +123 -0
- package/dist/mcp/client.js +332 -0
- package/dist/mcp/commands/call.js +146 -0
- package/dist/mcp/commands/grep.js +145 -0
- package/dist/mcp/commands/info.js +71 -0
- package/dist/mcp/commands/list.js +94 -0
- package/dist/mcp/config-command.js +217 -0
- package/dist/mcp/config.js +440 -0
- package/dist/mcp/daemon-client.js +266 -0
- package/dist/mcp/daemon.js +327 -0
- package/dist/mcp/errors.js +287 -0
- package/dist/mcp/index.js +431 -0
- package/dist/mcp/output.js +171 -0
- package/dist/mcp/python-runtime.js +131 -0
- package/dist/mcp/registry.js +116 -0
- package/dist/mcp/version.js +5 -0
- package/dist/pi-packages/cli.js +92 -0
- package/dist/pi-packages/installer.js +70 -0
- package/dist/pi-packages/metadata.js +231 -0
- package/dist/pi-packages/runtime.js +61 -0
- package/dist/pi-packages/store.js +175 -0
- package/dist/pi-packages/types.js +1 -0
- package/dist/plugins/better-auth.js +11 -0
- package/dist/plugins/builtin.js +249 -0
- package/dist/plugins/chat-web.js +11 -0
- package/dist/plugins/codex-compat.js +72 -0
- package/dist/plugins/context-files-store.js +354 -0
- package/dist/plugins/context-files.js +999 -0
- package/dist/plugins/core-tools.js +94 -0
- package/dist/plugins/example.js +67 -0
- package/dist/plugins/registry.js +368 -0
- package/dist/plugins/remote-agent.js +9 -0
- package/dist/plugins/types.js +1 -0
- package/dist/plugins/web.js +11 -0
- package/dist/reliability/store.js +759 -0
- package/dist/remote/channel.js +176 -0
- package/dist/remote/client.js +92 -0
- package/dist/remote/examples/tui-controller.js +263 -0
- package/dist/remote/protocol.js +55 -0
- package/dist/remote/session-client.js +189 -0
- package/dist/runs/registry.js +323 -0
- package/dist/runs/tools.js +185 -0
- package/dist/sessions/bindings.js +41 -0
- package/dist/sessions/sqlite-store.js +154 -0
- package/dist/sessions/store.js +125 -0
- package/dist/shared/trace-order.js +83 -0
- package/dist/subagents/tool.js +63 -0
- package/dist/tools/browser-use-cdp.js +207 -0
- package/dist/tools/browser-use-leases.js +338 -0
- package/dist/tools/browser-use-wrapper.js +338 -0
- package/dist/tools/codex-compat.js +85 -0
- package/dist/tools/desktop-env.js +90 -0
- package/dist/tools/guides.js +276 -0
- package/dist/tools/index.js +366 -0
- package/dist/tools/python-runtime.js +154 -0
- package/dist/tools/registry.js +107 -0
- package/dist/tools/web-search.js +137 -0
- package/dist/web/auth.js +10 -0
- package/dist/web/channel.js +151 -0
- package/dist/web/http.js +110 -0
- package/dist/web/types.js +1 -0
- package/package.json +74 -0
- package/src/mcp/LICENSE.mcp-cli +21 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdirSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { DatabaseSync } from "node:sqlite";
|
|
5
|
+
export class ChatEventLog {
|
|
6
|
+
db;
|
|
7
|
+
constructor(path) {
|
|
8
|
+
const resolvedPath = path === ":memory:" ? path : resolve(path);
|
|
9
|
+
if (resolvedPath !== ":memory:") {
|
|
10
|
+
mkdirSync(dirname(resolvedPath), { recursive: true });
|
|
11
|
+
}
|
|
12
|
+
this.db = new DatabaseSync(resolvedPath);
|
|
13
|
+
this.db.exec("PRAGMA busy_timeout = 5000");
|
|
14
|
+
if (resolvedPath !== ":memory:")
|
|
15
|
+
this.db.exec("PRAGMA journal_mode = WAL");
|
|
16
|
+
this.db.exec(`
|
|
17
|
+
CREATE TABLE IF NOT EXISTS chat_events (
|
|
18
|
+
stream_id INTEGER PRIMARY KEY,
|
|
19
|
+
room_id TEXT,
|
|
20
|
+
pibo_session_id TEXT,
|
|
21
|
+
event_id TEXT NOT NULL,
|
|
22
|
+
event_type TEXT NOT NULL,
|
|
23
|
+
actor_type TEXT,
|
|
24
|
+
actor_id TEXT,
|
|
25
|
+
client_txn_id TEXT,
|
|
26
|
+
created_at TEXT NOT NULL,
|
|
27
|
+
retention_class TEXT NOT NULL,
|
|
28
|
+
payload_json TEXT NOT NULL
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_chat_events_room_stream
|
|
32
|
+
ON chat_events(room_id, stream_id);
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_chat_events_session_stream
|
|
34
|
+
ON chat_events(pibo_session_id, stream_id);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_chat_events_event_id
|
|
36
|
+
ON chat_events(event_id);
|
|
37
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_chat_events_client_txn
|
|
38
|
+
ON chat_events(room_id, actor_id, client_txn_id)
|
|
39
|
+
WHERE client_txn_id IS NOT NULL;
|
|
40
|
+
|
|
41
|
+
CREATE TABLE IF NOT EXISTS chat_retention_policies (
|
|
42
|
+
id TEXT PRIMARY KEY,
|
|
43
|
+
delete_live_deltas_after_ms INTEGER,
|
|
44
|
+
delete_trace_events_after_ms INTEGER,
|
|
45
|
+
delete_chat_messages_after_ms INTEGER
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
CREATE TABLE IF NOT EXISTS chat_session_reads (
|
|
49
|
+
pibo_session_id TEXT NOT NULL,
|
|
50
|
+
principal_id TEXT NOT NULL,
|
|
51
|
+
last_read_stream_id INTEGER NOT NULL,
|
|
52
|
+
updated_at TEXT NOT NULL,
|
|
53
|
+
PRIMARY KEY(pibo_session_id, principal_id)
|
|
54
|
+
);
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
appendEvent(input) {
|
|
58
|
+
const eventId = input.eventId ?? `ce_${randomUUID()}`;
|
|
59
|
+
const createdAt = input.createdAt ?? new Date().toISOString();
|
|
60
|
+
const payloadJson = JSON.stringify(input.payload);
|
|
61
|
+
const result = this.db
|
|
62
|
+
.prepare(`
|
|
63
|
+
INSERT OR IGNORE INTO chat_events (
|
|
64
|
+
room_id,
|
|
65
|
+
pibo_session_id,
|
|
66
|
+
event_id,
|
|
67
|
+
event_type,
|
|
68
|
+
actor_type,
|
|
69
|
+
actor_id,
|
|
70
|
+
client_txn_id,
|
|
71
|
+
created_at,
|
|
72
|
+
retention_class,
|
|
73
|
+
payload_json
|
|
74
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
75
|
+
`)
|
|
76
|
+
.run(input.roomId ?? null, input.piboSessionId ?? null, eventId, input.eventType, input.actorType ?? null, input.actorId ?? null, input.clientTxnId ?? null, createdAt, input.retentionClass, payloadJson);
|
|
77
|
+
if (input.clientTxnId) {
|
|
78
|
+
const existing = this.findByClientTxn(input.roomId, input.actorId, input.clientTxnId);
|
|
79
|
+
if (existing)
|
|
80
|
+
return existing;
|
|
81
|
+
}
|
|
82
|
+
const streamId = Number(result.lastInsertRowid);
|
|
83
|
+
const stored = this.db.prepare("SELECT * FROM chat_events WHERE stream_id = ?").get(streamId);
|
|
84
|
+
if (!stored)
|
|
85
|
+
throw new Error(`Failed to append chat event "${eventId}"`);
|
|
86
|
+
return eventFromRow(stored);
|
|
87
|
+
}
|
|
88
|
+
appendOutputEvent(event, input = {}) {
|
|
89
|
+
return this.appendEvent({
|
|
90
|
+
roomId: input.roomId,
|
|
91
|
+
piboSessionId: event.piboSessionId,
|
|
92
|
+
eventId: "eventId" in event && event.eventId ? `pibo:${event.piboSessionId}:${event.eventId}:${event.type}` : undefined,
|
|
93
|
+
eventType: event.type,
|
|
94
|
+
actorType: actorTypeForOutputEvent(event),
|
|
95
|
+
actorId: input.actorId,
|
|
96
|
+
retentionClass: retentionClassForOutputEvent(event),
|
|
97
|
+
payload: event,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
listEvents(input = {}) {
|
|
101
|
+
const clauses = [];
|
|
102
|
+
const values = [];
|
|
103
|
+
if (input.roomId) {
|
|
104
|
+
clauses.push("room_id = ?");
|
|
105
|
+
values.push(input.roomId);
|
|
106
|
+
}
|
|
107
|
+
if (input.piboSessionId) {
|
|
108
|
+
clauses.push("pibo_session_id = ?");
|
|
109
|
+
values.push(input.piboSessionId);
|
|
110
|
+
}
|
|
111
|
+
if (input.afterStreamId !== undefined) {
|
|
112
|
+
clauses.push("stream_id > ?");
|
|
113
|
+
values.push(input.afterStreamId);
|
|
114
|
+
}
|
|
115
|
+
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
116
|
+
const limit = Math.max(1, Math.min(input.limit ?? 1000, 5000));
|
|
117
|
+
const rows = this.db
|
|
118
|
+
.prepare(`SELECT * FROM chat_events ${where} ORDER BY stream_id ASC LIMIT ?`)
|
|
119
|
+
.all(...values, limit);
|
|
120
|
+
return rows.map(eventFromRow);
|
|
121
|
+
}
|
|
122
|
+
getEvent(streamId) {
|
|
123
|
+
const row = this.db.prepare("SELECT * FROM chat_events WHERE stream_id = ?").get(streamId);
|
|
124
|
+
return row ? eventFromRow(row) : undefined;
|
|
125
|
+
}
|
|
126
|
+
findByClientTxn(roomId, actorId, clientTxnId) {
|
|
127
|
+
if (!roomId || !actorId)
|
|
128
|
+
return undefined;
|
|
129
|
+
const row = this.db
|
|
130
|
+
.prepare(`
|
|
131
|
+
SELECT * FROM chat_events
|
|
132
|
+
WHERE room_id = ? AND actor_id = ? AND client_txn_id = ?
|
|
133
|
+
ORDER BY stream_id ASC
|
|
134
|
+
LIMIT 1
|
|
135
|
+
`)
|
|
136
|
+
.get(roomId, actorId, clientTxnId);
|
|
137
|
+
return row ? eventFromRow(row) : undefined;
|
|
138
|
+
}
|
|
139
|
+
getLatestStreamId(input = {}) {
|
|
140
|
+
const clauses = [];
|
|
141
|
+
const values = [];
|
|
142
|
+
if (input.roomId) {
|
|
143
|
+
clauses.push("room_id = ?");
|
|
144
|
+
values.push(input.roomId);
|
|
145
|
+
}
|
|
146
|
+
if (input.piboSessionId) {
|
|
147
|
+
clauses.push("pibo_session_id = ?");
|
|
148
|
+
values.push(input.piboSessionId);
|
|
149
|
+
}
|
|
150
|
+
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
151
|
+
const row = this.db.prepare(`SELECT MAX(stream_id) AS stream_id FROM chat_events ${where}`).get(...values);
|
|
152
|
+
return row?.stream_id ?? undefined;
|
|
153
|
+
}
|
|
154
|
+
getSessionReadCursor(piboSessionId, principalId) {
|
|
155
|
+
const row = this.db
|
|
156
|
+
.prepare("SELECT * FROM chat_session_reads WHERE pibo_session_id = ? AND principal_id = ?")
|
|
157
|
+
.get(piboSessionId, principalId);
|
|
158
|
+
return row?.last_read_stream_id;
|
|
159
|
+
}
|
|
160
|
+
markSessionRead(piboSessionId, principalId, lastReadStreamId) {
|
|
161
|
+
this.db
|
|
162
|
+
.prepare(`
|
|
163
|
+
INSERT INTO chat_session_reads (pibo_session_id, principal_id, last_read_stream_id, updated_at)
|
|
164
|
+
VALUES (?, ?, ?, ?)
|
|
165
|
+
ON CONFLICT(pibo_session_id, principal_id) DO UPDATE SET
|
|
166
|
+
last_read_stream_id = MAX(chat_session_reads.last_read_stream_id, excluded.last_read_stream_id),
|
|
167
|
+
updated_at = excluded.updated_at
|
|
168
|
+
`)
|
|
169
|
+
.run(piboSessionId, principalId, lastReadStreamId, new Date().toISOString());
|
|
170
|
+
}
|
|
171
|
+
countUnreadMessages(input) {
|
|
172
|
+
const clauses = [
|
|
173
|
+
"retention_class = 'chat_message'",
|
|
174
|
+
"event_type IN ('user.message.accepted', 'assistant_message')",
|
|
175
|
+
"(actor_type IS NULL OR actor_type != 'user' OR actor_id IS NULL OR actor_id != ?)",
|
|
176
|
+
];
|
|
177
|
+
const values = [input.principalId];
|
|
178
|
+
if (input.roomId) {
|
|
179
|
+
clauses.push("room_id = ?");
|
|
180
|
+
values.push(input.roomId);
|
|
181
|
+
}
|
|
182
|
+
if (input.piboSessionId) {
|
|
183
|
+
clauses.push("pibo_session_id = ?");
|
|
184
|
+
values.push(input.piboSessionId);
|
|
185
|
+
}
|
|
186
|
+
if (input.afterStreamId !== undefined) {
|
|
187
|
+
clauses.push("stream_id > ?");
|
|
188
|
+
values.push(input.afterStreamId);
|
|
189
|
+
}
|
|
190
|
+
const row = this.db
|
|
191
|
+
.prepare(`SELECT COUNT(*) AS count FROM chat_events WHERE ${clauses.join(" AND ")}`)
|
|
192
|
+
.get(...values);
|
|
193
|
+
return Number(row?.count ?? 0);
|
|
194
|
+
}
|
|
195
|
+
deleteSessions(piboSessionIds) {
|
|
196
|
+
if (!piboSessionIds.length)
|
|
197
|
+
return 0;
|
|
198
|
+
const placeholders = piboSessionIds.map(() => "?").join(", ");
|
|
199
|
+
this.db.prepare(`DELETE FROM chat_session_reads WHERE pibo_session_id IN (${placeholders})`).run(...piboSessionIds);
|
|
200
|
+
const result = this.db.prepare(`DELETE FROM chat_events WHERE pibo_session_id IN (${placeholders})`).run(...piboSessionIds);
|
|
201
|
+
return Number(result.changes ?? 0);
|
|
202
|
+
}
|
|
203
|
+
deleteRooms(roomIds) {
|
|
204
|
+
if (!roomIds.length)
|
|
205
|
+
return 0;
|
|
206
|
+
const placeholders = roomIds.map(() => "?").join(", ");
|
|
207
|
+
const result = this.db.prepare(`DELETE FROM chat_events WHERE room_id IN (${placeholders})`).run(...roomIds);
|
|
208
|
+
return Number(result.changes ?? 0);
|
|
209
|
+
}
|
|
210
|
+
upsertRetentionPolicy(policy) {
|
|
211
|
+
this.db
|
|
212
|
+
.prepare(`
|
|
213
|
+
INSERT INTO chat_retention_policies (
|
|
214
|
+
id,
|
|
215
|
+
delete_live_deltas_after_ms,
|
|
216
|
+
delete_trace_events_after_ms,
|
|
217
|
+
delete_chat_messages_after_ms
|
|
218
|
+
) VALUES (?, ?, ?, ?)
|
|
219
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
220
|
+
delete_live_deltas_after_ms = excluded.delete_live_deltas_after_ms,
|
|
221
|
+
delete_trace_events_after_ms = excluded.delete_trace_events_after_ms,
|
|
222
|
+
delete_chat_messages_after_ms = excluded.delete_chat_messages_after_ms
|
|
223
|
+
`)
|
|
224
|
+
.run(policy.id, policy.deleteLiveDeltasAfterMs ?? null, policy.deleteTraceEventsAfterMs ?? null, policy.deleteChatMessagesAfterMs ?? null);
|
|
225
|
+
return this.getRetentionPolicy(policy.id) ?? policy;
|
|
226
|
+
}
|
|
227
|
+
getRetentionPolicy(id) {
|
|
228
|
+
const row = this.db.prepare("SELECT * FROM chat_retention_policies WHERE id = ?").get(id);
|
|
229
|
+
return row ? policyFromRow(row) : undefined;
|
|
230
|
+
}
|
|
231
|
+
purgeExpired(input = {}) {
|
|
232
|
+
const now = input.now ?? new Date();
|
|
233
|
+
const policy = input.policy ?? this.getRetentionPolicy("default") ?? { id: "default" };
|
|
234
|
+
const batchSize = Math.max(1, Math.min(input.batchSize ?? 500, 5000));
|
|
235
|
+
const clauses = [];
|
|
236
|
+
const values = [];
|
|
237
|
+
addRetentionClause(clauses, values, "live_delta", policy.deleteLiveDeltasAfterMs, now);
|
|
238
|
+
addRetentionClause(clauses, values, "trace_event", policy.deleteTraceEventsAfterMs, now);
|
|
239
|
+
addRetentionClause(clauses, values, "chat_message", policy.deleteChatMessagesAfterMs, now);
|
|
240
|
+
if (!clauses.length)
|
|
241
|
+
return 0;
|
|
242
|
+
const result = this.db
|
|
243
|
+
.prepare(`
|
|
244
|
+
DELETE FROM chat_events
|
|
245
|
+
WHERE stream_id IN (
|
|
246
|
+
SELECT stream_id FROM chat_events
|
|
247
|
+
WHERE ${clauses.join(" OR ")}
|
|
248
|
+
ORDER BY stream_id ASC
|
|
249
|
+
LIMIT ${batchSize}
|
|
250
|
+
)
|
|
251
|
+
`)
|
|
252
|
+
.run(...values);
|
|
253
|
+
return Number(result.changes ?? 0);
|
|
254
|
+
}
|
|
255
|
+
close() {
|
|
256
|
+
this.db.close();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
export function createDefaultChatEventLog(cwd = process.cwd()) {
|
|
260
|
+
return new ChatEventLog(resolve(cwd, ".pibo/web-chat.sqlite"));
|
|
261
|
+
}
|
|
262
|
+
function eventFromRow(row) {
|
|
263
|
+
return {
|
|
264
|
+
streamId: row.stream_id,
|
|
265
|
+
roomId: row.room_id ?? undefined,
|
|
266
|
+
piboSessionId: row.pibo_session_id ?? undefined,
|
|
267
|
+
eventId: row.event_id,
|
|
268
|
+
eventType: row.event_type,
|
|
269
|
+
actorType: row.actor_type,
|
|
270
|
+
actorId: row.actor_id ?? undefined,
|
|
271
|
+
clientTxnId: row.client_txn_id ?? undefined,
|
|
272
|
+
createdAt: row.created_at,
|
|
273
|
+
retentionClass: row.retention_class,
|
|
274
|
+
payload: JSON.parse(row.payload_json),
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
function policyFromRow(row) {
|
|
278
|
+
return {
|
|
279
|
+
id: row.id,
|
|
280
|
+
deleteLiveDeltasAfterMs: row.delete_live_deltas_after_ms ?? undefined,
|
|
281
|
+
deleteTraceEventsAfterMs: row.delete_trace_events_after_ms ?? undefined,
|
|
282
|
+
deleteChatMessagesAfterMs: row.delete_chat_messages_after_ms ?? undefined,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function retentionClassForOutputEvent(event) {
|
|
286
|
+
if (event.type === "assistant_delta" || event.type === "thinking_delta")
|
|
287
|
+
return "live_delta";
|
|
288
|
+
if (event.type === "assistant_message" || event.type === "message_started" || event.type === "message_finished") {
|
|
289
|
+
return "chat_message";
|
|
290
|
+
}
|
|
291
|
+
return "trace_event";
|
|
292
|
+
}
|
|
293
|
+
function actorTypeForOutputEvent(event) {
|
|
294
|
+
if (event.type === "assistant_delta" || event.type === "assistant_message" || event.type.startsWith("thinking_")) {
|
|
295
|
+
return "assistant";
|
|
296
|
+
}
|
|
297
|
+
if (event.type === "message_queued" || event.type === "message_started" || event.type === "message_finished") {
|
|
298
|
+
return "user";
|
|
299
|
+
}
|
|
300
|
+
return "agent";
|
|
301
|
+
}
|
|
302
|
+
function addRetentionClause(clauses, values, retentionClass, ageMs, now) {
|
|
303
|
+
if (!ageMs || ageMs <= 0)
|
|
304
|
+
return;
|
|
305
|
+
clauses.push("(retention_class = ? AND created_at < ?)");
|
|
306
|
+
values.push(retentionClass, new Date(now.getTime() - ageMs).toISOString());
|
|
307
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdirSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { DatabaseSync } from "node:sqlite";
|
|
5
|
+
export class ChatWebReadModel {
|
|
6
|
+
db;
|
|
7
|
+
constructor(path) {
|
|
8
|
+
const resolvedPath = path === ":memory:" ? path : resolve(path);
|
|
9
|
+
if (resolvedPath !== ":memory:") {
|
|
10
|
+
mkdirSync(dirname(resolvedPath), { recursive: true });
|
|
11
|
+
}
|
|
12
|
+
this.db = new DatabaseSync(resolvedPath);
|
|
13
|
+
this.db.exec("PRAGMA busy_timeout = 5000");
|
|
14
|
+
if (resolvedPath !== ":memory:")
|
|
15
|
+
this.db.exec("PRAGMA journal_mode = WAL");
|
|
16
|
+
this.dropLegacySchema();
|
|
17
|
+
this.db.exec(`
|
|
18
|
+
CREATE TABLE IF NOT EXISTS web_chat_sessions (
|
|
19
|
+
pibo_session_id TEXT PRIMARY KEY,
|
|
20
|
+
pi_session_id TEXT NOT NULL,
|
|
21
|
+
parent_id TEXT,
|
|
22
|
+
profile TEXT NOT NULL,
|
|
23
|
+
channel TEXT NOT NULL,
|
|
24
|
+
kind TEXT NOT NULL,
|
|
25
|
+
created_at TEXT NOT NULL,
|
|
26
|
+
updated_at TEXT NOT NULL,
|
|
27
|
+
last_activity_at TEXT,
|
|
28
|
+
status TEXT NOT NULL DEFAULT 'idle'
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE TABLE IF NOT EXISTS web_chat_events (
|
|
32
|
+
id TEXT PRIMARY KEY,
|
|
33
|
+
pibo_session_id TEXT NOT NULL,
|
|
34
|
+
event_sequence INTEGER,
|
|
35
|
+
event_id TEXT,
|
|
36
|
+
type TEXT NOT NULL,
|
|
37
|
+
created_at TEXT NOT NULL,
|
|
38
|
+
payload_json TEXT NOT NULL
|
|
39
|
+
);
|
|
40
|
+
`);
|
|
41
|
+
this.migrateEventSequence();
|
|
42
|
+
this.db.exec(`
|
|
43
|
+
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_web_chat_events_session_created
|
|
45
|
+
ON web_chat_events(pibo_session_id, created_at, id);
|
|
46
|
+
CREATE INDEX IF NOT EXISTS idx_web_chat_events_session_sequence
|
|
47
|
+
ON web_chat_events(pibo_session_id, event_sequence, id);
|
|
48
|
+
CREATE INDEX IF NOT EXISTS idx_web_chat_events_event_id
|
|
49
|
+
ON web_chat_events(event_id);
|
|
50
|
+
CREATE INDEX IF NOT EXISTS idx_web_chat_sessions_parent
|
|
51
|
+
ON web_chat_sessions(parent_id);
|
|
52
|
+
`);
|
|
53
|
+
this.resetInterruptedSessions();
|
|
54
|
+
}
|
|
55
|
+
upsertSession(session, status = "idle") {
|
|
56
|
+
this.db
|
|
57
|
+
.prepare(`
|
|
58
|
+
INSERT INTO web_chat_sessions (
|
|
59
|
+
pibo_session_id,
|
|
60
|
+
pi_session_id,
|
|
61
|
+
parent_id,
|
|
62
|
+
profile,
|
|
63
|
+
channel,
|
|
64
|
+
kind,
|
|
65
|
+
created_at,
|
|
66
|
+
updated_at,
|
|
67
|
+
last_activity_at,
|
|
68
|
+
status
|
|
69
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL, ?)
|
|
70
|
+
ON CONFLICT(pibo_session_id) DO UPDATE SET
|
|
71
|
+
pi_session_id = excluded.pi_session_id,
|
|
72
|
+
parent_id = excluded.parent_id,
|
|
73
|
+
profile = excluded.profile,
|
|
74
|
+
channel = excluded.channel,
|
|
75
|
+
kind = excluded.kind,
|
|
76
|
+
updated_at = excluded.updated_at,
|
|
77
|
+
status = CASE
|
|
78
|
+
WHEN web_chat_sessions.status = 'running' AND excluded.status = 'idle' THEN web_chat_sessions.status
|
|
79
|
+
ELSE excluded.status
|
|
80
|
+
END
|
|
81
|
+
`)
|
|
82
|
+
.run(session.id, session.piSessionId, session.parentId ?? null, session.profile, session.channel, session.kind, session.createdAt, session.updatedAt, status);
|
|
83
|
+
}
|
|
84
|
+
recordEvent(event, session) {
|
|
85
|
+
if (session)
|
|
86
|
+
this.upsertSession(session, statusFromEvent(event));
|
|
87
|
+
const id = randomUUID();
|
|
88
|
+
const createdAt = new Date().toISOString();
|
|
89
|
+
const eventSequence = this.nextEventSequence(event.piboSessionId);
|
|
90
|
+
const eventId = "eventId" in event && typeof event.eventId === "string" ? event.eventId : undefined;
|
|
91
|
+
this.db
|
|
92
|
+
.prepare("INSERT INTO web_chat_events (id, pibo_session_id, event_sequence, event_id, type, created_at, payload_json) VALUES (?, ?, ?, ?, ?, ?, ?)")
|
|
93
|
+
.run(id, event.piboSessionId, eventSequence, eventId ?? null, event.type, createdAt, JSON.stringify(event));
|
|
94
|
+
this.db
|
|
95
|
+
.prepare("UPDATE web_chat_sessions SET last_activity_at = ?, status = ?, updated_at = ? WHERE pibo_session_id = ?")
|
|
96
|
+
.run(createdAt, statusFromEvent(event), createdAt, event.piboSessionId);
|
|
97
|
+
return { id, piboSessionId: event.piboSessionId, eventSequence, eventId, type: event.type, createdAt, payload: event };
|
|
98
|
+
}
|
|
99
|
+
listSessions() {
|
|
100
|
+
return this.db.prepare("SELECT * FROM web_chat_sessions ORDER BY updated_at DESC").all().map(sessionFromRow);
|
|
101
|
+
}
|
|
102
|
+
listEvents(piboSessionId, limit = 1000) {
|
|
103
|
+
const rows = this.db
|
|
104
|
+
.prepare(`
|
|
105
|
+
SELECT * FROM (
|
|
106
|
+
SELECT rowid AS _rowid, * FROM web_chat_events
|
|
107
|
+
WHERE pibo_session_id = ?
|
|
108
|
+
ORDER BY event_sequence DESC, rowid DESC
|
|
109
|
+
LIMIT ?
|
|
110
|
+
)
|
|
111
|
+
ORDER BY event_sequence ASC, _rowid ASC
|
|
112
|
+
`)
|
|
113
|
+
.all(piboSessionId, limit);
|
|
114
|
+
return rows.map(eventFromRow);
|
|
115
|
+
}
|
|
116
|
+
listAllEvents(piboSessionId) {
|
|
117
|
+
const rows = this.db
|
|
118
|
+
.prepare(`
|
|
119
|
+
SELECT rowid AS _rowid, * FROM web_chat_events
|
|
120
|
+
WHERE pibo_session_id = ?
|
|
121
|
+
ORDER BY event_sequence ASC, _rowid ASC
|
|
122
|
+
`)
|
|
123
|
+
.all(piboSessionId);
|
|
124
|
+
return rows.map(eventFromRow);
|
|
125
|
+
}
|
|
126
|
+
getLatestEventSequence(piboSessionId) {
|
|
127
|
+
const row = this.db
|
|
128
|
+
.prepare("SELECT COALESCE(MAX(event_sequence), 0) AS latest_sequence FROM web_chat_events WHERE pibo_session_id = ?")
|
|
129
|
+
.get(piboSessionId);
|
|
130
|
+
return row.latest_sequence;
|
|
131
|
+
}
|
|
132
|
+
deleteSessions(piboSessionIds) {
|
|
133
|
+
if (!piboSessionIds.length)
|
|
134
|
+
return 0;
|
|
135
|
+
const placeholders = piboSessionIds.map(() => "?").join(", ");
|
|
136
|
+
this.db.prepare(`DELETE FROM web_chat_events WHERE pibo_session_id IN (${placeholders})`).run(...piboSessionIds);
|
|
137
|
+
const result = this.db
|
|
138
|
+
.prepare(`DELETE FROM web_chat_sessions WHERE pibo_session_id IN (${placeholders})`)
|
|
139
|
+
.run(...piboSessionIds);
|
|
140
|
+
return Number(result.changes ?? 0);
|
|
141
|
+
}
|
|
142
|
+
close() {
|
|
143
|
+
this.db.close();
|
|
144
|
+
}
|
|
145
|
+
dropLegacySchema() {
|
|
146
|
+
const sessionColumns = tableColumns(this.db, "web_chat_sessions");
|
|
147
|
+
const eventColumns = tableColumns(this.db, "web_chat_events");
|
|
148
|
+
if ((sessionColumns.size > 0 && !sessionColumns.has("pibo_session_id")) ||
|
|
149
|
+
(eventColumns.size > 0 && !eventColumns.has("pibo_session_id"))) {
|
|
150
|
+
this.db.exec(`
|
|
151
|
+
DROP TABLE IF EXISTS web_chat_events;
|
|
152
|
+
DROP TABLE IF EXISTS web_chat_sessions;
|
|
153
|
+
`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
migrateEventSequence() {
|
|
157
|
+
const eventColumns = tableColumns(this.db, "web_chat_events");
|
|
158
|
+
if (!eventColumns.has("event_sequence")) {
|
|
159
|
+
this.db.exec("ALTER TABLE web_chat_events ADD COLUMN event_sequence INTEGER");
|
|
160
|
+
}
|
|
161
|
+
this.db.exec("UPDATE web_chat_events SET event_sequence = rowid WHERE event_sequence IS NULL");
|
|
162
|
+
}
|
|
163
|
+
nextEventSequence(piboSessionId) {
|
|
164
|
+
const row = this.db
|
|
165
|
+
.prepare("SELECT COALESCE(MAX(event_sequence), 0) + 1 AS next_sequence FROM web_chat_events WHERE pibo_session_id = ?")
|
|
166
|
+
.get(piboSessionId);
|
|
167
|
+
return row.next_sequence;
|
|
168
|
+
}
|
|
169
|
+
resetInterruptedSessions() {
|
|
170
|
+
this.db.prepare("UPDATE web_chat_sessions SET status = 'idle' WHERE status = 'running'").run();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
export function createDefaultChatWebReadModel(cwd = process.cwd()) {
|
|
174
|
+
return new ChatWebReadModel(resolve(cwd, ".pibo/web-chat.sqlite"));
|
|
175
|
+
}
|
|
176
|
+
function statusFromEvent(event) {
|
|
177
|
+
if (event.type === "session_error")
|
|
178
|
+
return "error";
|
|
179
|
+
if (event.type === "message_started" ||
|
|
180
|
+
event.type === "assistant_delta" ||
|
|
181
|
+
event.type === "thinking_started" ||
|
|
182
|
+
event.type === "thinking_delta" ||
|
|
183
|
+
event.type === "thinking_finished" ||
|
|
184
|
+
event.type === "subagent_session" ||
|
|
185
|
+
event.type === "tool_execution_started" ||
|
|
186
|
+
event.type === "tool_execution_updated") {
|
|
187
|
+
return "running";
|
|
188
|
+
}
|
|
189
|
+
return "idle";
|
|
190
|
+
}
|
|
191
|
+
function sessionFromRow(row) {
|
|
192
|
+
return {
|
|
193
|
+
piboSessionId: row.pibo_session_id,
|
|
194
|
+
piSessionId: row.pi_session_id,
|
|
195
|
+
parentId: row.parent_id ?? undefined,
|
|
196
|
+
profile: row.profile,
|
|
197
|
+
channel: row.channel,
|
|
198
|
+
kind: row.kind,
|
|
199
|
+
createdAt: row.created_at,
|
|
200
|
+
updatedAt: row.updated_at,
|
|
201
|
+
lastActivityAt: row.last_activity_at ?? undefined,
|
|
202
|
+
status: row.status === "running" || row.status === "error" ? row.status : "idle",
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function eventFromRow(row) {
|
|
206
|
+
return {
|
|
207
|
+
id: row.id,
|
|
208
|
+
piboSessionId: row.pibo_session_id,
|
|
209
|
+
eventSequence: row.event_sequence ?? undefined,
|
|
210
|
+
eventId: row.event_id ?? undefined,
|
|
211
|
+
type: row.type,
|
|
212
|
+
createdAt: row.created_at,
|
|
213
|
+
payload: JSON.parse(row.payload_json),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function tableColumns(db, tableName) {
|
|
217
|
+
return new Set(db.prepare(`PRAGMA table_info(${tableName})`).all().map((column) => column.name));
|
|
218
|
+
}
|