@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,366 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { ErrorCode, formatCliError } from '../cli-errors.js';
|
|
3
|
+
import { acquireBrowserUseLease, listBrowserUseLeases, printBrowserUseAuthTemplateEnv, printBrowserUseAuthTemplatePath, reapStaleBrowserUseLeases, releaseBrowserUseLease, } from './browser-use-leases.js';
|
|
4
|
+
import { formatBrowserUseTargets, listBrowserUseCdpTargets, printAttachChatExports, selectBestChatTarget, } from './browser-use-cdp.js';
|
|
5
|
+
import { ensureBrowserUseWrapper } from './browser-use-wrapper.js';
|
|
6
|
+
import { detectDesktopEnv } from './desktop-env.js';
|
|
7
|
+
import { doctorCliTool, findCliToolEntry, findToolGuide, getCliToolStatus, installCliTool, listCliToolEntries, removeCliTool, } from './registry.js';
|
|
8
|
+
function requireEntry(name) {
|
|
9
|
+
const entry = findCliToolEntry(name);
|
|
10
|
+
if (!entry) {
|
|
11
|
+
throw new Error(formatCliError({
|
|
12
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
13
|
+
type: 'CLI_TOOL_NOT_FOUND',
|
|
14
|
+
message: `Tool "${name}" not found`,
|
|
15
|
+
details: `Available tools: ${listCliToolEntries().map((item) => item.name).join(', ')}`,
|
|
16
|
+
suggestion: 'Run pibo tools list to see curated tools.',
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
return entry;
|
|
20
|
+
}
|
|
21
|
+
function printList(installedOnly) {
|
|
22
|
+
const rows = listCliToolEntries()
|
|
23
|
+
.map((entry) => getCliToolStatus(entry))
|
|
24
|
+
.filter((status) => !installedOnly || status.installed)
|
|
25
|
+
.map((status) => ({
|
|
26
|
+
name: status.entry.name,
|
|
27
|
+
status: status.installed ? 'installed' : 'available',
|
|
28
|
+
executable: status.installed ? status.executablePath : '',
|
|
29
|
+
description: status.entry.description,
|
|
30
|
+
}));
|
|
31
|
+
if (rows.length === 0) {
|
|
32
|
+
console.log(installedOnly ? 'No cli tools are installed.' : 'No cli tools are currently bundled.');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
for (const row of rows) {
|
|
36
|
+
const executable = row.executable ? `\t${row.executable}` : '';
|
|
37
|
+
console.log(`${row.name}\t${row.status}\t${row.description}${executable}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function printShow(name) {
|
|
41
|
+
const entry = requireEntry(name);
|
|
42
|
+
const status = getCliToolStatus(entry);
|
|
43
|
+
console.log(`${entry.name}`);
|
|
44
|
+
console.log(` ${entry.description}`);
|
|
45
|
+
console.log(` package: ${entry.runtime.packageName}`);
|
|
46
|
+
console.log(` status: ${status.installed ? 'installed' : 'available'}`);
|
|
47
|
+
console.log(` runtime: ${status.rootDir}`);
|
|
48
|
+
console.log(` home: ${status.homeDir}`);
|
|
49
|
+
console.log(` executable: ${status.executablePath}`);
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log('Guides:');
|
|
52
|
+
for (const guide of entry.guides) {
|
|
53
|
+
console.log(` ${guide.name}\t${guide.description}`);
|
|
54
|
+
}
|
|
55
|
+
if (entry.notes.length > 0) {
|
|
56
|
+
console.log('');
|
|
57
|
+
console.log('Notes:');
|
|
58
|
+
for (const note of entry.notes)
|
|
59
|
+
console.log(` - ${note}`);
|
|
60
|
+
}
|
|
61
|
+
console.log('');
|
|
62
|
+
console.log('Next:');
|
|
63
|
+
console.log(` pibo tools env ${entry.name}`);
|
|
64
|
+
console.log(` pibo tools guide ${entry.name} ${entry.guides[0]?.name ?? ''}`.trimEnd());
|
|
65
|
+
if (entry.name === 'browser-use') {
|
|
66
|
+
console.log(' pibo tools browser-use');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function printGuides(name) {
|
|
70
|
+
const entry = requireEntry(name);
|
|
71
|
+
for (const guide of entry.guides) {
|
|
72
|
+
console.log(`${guide.name}\t${guide.description}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function printGuide(name, guideName) {
|
|
76
|
+
const entry = requireEntry(name);
|
|
77
|
+
const selectedGuideName = guideName ?? entry.guides[0]?.name;
|
|
78
|
+
if (!selectedGuideName) {
|
|
79
|
+
throw new Error(formatCliError({
|
|
80
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
81
|
+
type: 'CLI_TOOL_GUIDE_NOT_FOUND',
|
|
82
|
+
message: `Tool "${name}" has no guides`,
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
const guide = findToolGuide(entry, selectedGuideName);
|
|
86
|
+
if (!guide) {
|
|
87
|
+
throw new Error(formatCliError({
|
|
88
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
89
|
+
type: 'CLI_TOOL_GUIDE_NOT_FOUND',
|
|
90
|
+
message: `Guide "${selectedGuideName}" not found for tool "${name}"`,
|
|
91
|
+
details: `Available guides: ${entry.guides.map((item) => item.name).join(', ')}`,
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
console.log(guide.content);
|
|
95
|
+
}
|
|
96
|
+
function printPath(name) {
|
|
97
|
+
const entry = requireEntry(name);
|
|
98
|
+
console.log(getCliToolStatus(entry).executablePath);
|
|
99
|
+
}
|
|
100
|
+
function printEnv(name) {
|
|
101
|
+
const entry = requireEntry(name);
|
|
102
|
+
const status = getCliToolStatus(entry);
|
|
103
|
+
const desktop = detectDesktopEnv();
|
|
104
|
+
if (process.platform === 'win32') {
|
|
105
|
+
console.log(`$env:PATH = "${status.executablePath.replace(/\\[^\\]+$/, '')};$env:PATH"`);
|
|
106
|
+
if (entry.runtime.homeEnvVar)
|
|
107
|
+
console.log(`$env:${entry.runtime.homeEnvVar} = "${status.homeDir}"`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const binDir = status.executablePath.replace(/\/[^/]+$/, '');
|
|
111
|
+
const wrapperPath = ensureBrowserUseWrapper(status);
|
|
112
|
+
const wrapperBinDir = wrapperPath ? wrapperPath.replace(/\/[^/]+$/, '') : `${status.homeDir}/bin`;
|
|
113
|
+
console.log(`export PATH="${wrapperBinDir}:${binDir}:$PATH"`);
|
|
114
|
+
if (entry.runtime.homeEnvVar)
|
|
115
|
+
console.log(`export ${entry.runtime.homeEnvVar}="${status.homeDir}"`);
|
|
116
|
+
if (desktop.display)
|
|
117
|
+
console.log(`export DISPLAY="${desktop.display}"`);
|
|
118
|
+
if (desktop.waylandDisplay)
|
|
119
|
+
console.log(`export WAYLAND_DISPLAY="${desktop.waylandDisplay}"`);
|
|
120
|
+
if (desktop.xauthority)
|
|
121
|
+
console.log(`export XAUTHORITY="${desktop.xauthority}"`);
|
|
122
|
+
if (desktop.xdgRuntimeDir)
|
|
123
|
+
console.log(`export XDG_RUNTIME_DIR="${desktop.xdgRuntimeDir}"`);
|
|
124
|
+
if (desktop.dbusSessionBusAddress) {
|
|
125
|
+
console.log(`export DBUS_SESSION_BUS_ADDRESS="${desktop.dbusSessionBusAddress}"`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function parsePositiveInteger(value) {
|
|
129
|
+
const parsed = Number.parseInt(value, 10);
|
|
130
|
+
if (!Number.isFinite(parsed) || parsed < 1) {
|
|
131
|
+
throw new Error(`Expected a positive integer, got "${value}"`);
|
|
132
|
+
}
|
|
133
|
+
return parsed;
|
|
134
|
+
}
|
|
135
|
+
function printBrowserUseDiscovery() {
|
|
136
|
+
console.log(`pibo tools browser-use - browser-use helpers
|
|
137
|
+
|
|
138
|
+
Start:
|
|
139
|
+
eval "$(pibo tools env browser-use)"
|
|
140
|
+
|
|
141
|
+
Commands:
|
|
142
|
+
targets List Chrome CDP targets with Chat auth hints
|
|
143
|
+
attach-chat Export the best existing authenticated Chat target
|
|
144
|
+
auth-template path Print the default authenticated template profile path
|
|
145
|
+
auth-template env Print shell exports for preparing the auth template profile
|
|
146
|
+
lease acquire Acquire an isolated authenticated browser slot
|
|
147
|
+
lease list List authenticated browser slots
|
|
148
|
+
lease release <id> Release one browser slot
|
|
149
|
+
lease reap-stale Release expired or dead browser slots
|
|
150
|
+
|
|
151
|
+
Next:
|
|
152
|
+
pibo tools show browser-use
|
|
153
|
+
pibo tools guide browser-use browser-use
|
|
154
|
+
pibo tools browser-use targets
|
|
155
|
+
pibo tools browser-use auth-template env
|
|
156
|
+
pibo tools browser-use lease acquire`);
|
|
157
|
+
}
|
|
158
|
+
function printToolsDiscovery() {
|
|
159
|
+
console.log(`pibo tools - curated external CLI tools
|
|
160
|
+
|
|
161
|
+
Commands:
|
|
162
|
+
list List curated tools
|
|
163
|
+
installed List installed tools
|
|
164
|
+
show <name> Show one tool
|
|
165
|
+
install <name> Install one tool
|
|
166
|
+
doctor <name> Check one tool
|
|
167
|
+
guides <name> List tool guides
|
|
168
|
+
guide <name> [guide] Print one guide
|
|
169
|
+
path <name> Print executable path
|
|
170
|
+
env <name> Print shell exports
|
|
171
|
+
browser-use Browser-use auth slots and helper commands
|
|
172
|
+
|
|
173
|
+
Next:
|
|
174
|
+
pibo tools list`);
|
|
175
|
+
}
|
|
176
|
+
export async function runToolsCli(argv = process.argv) {
|
|
177
|
+
if (argv[2] === '--help' || argv[2] === '-h') {
|
|
178
|
+
printToolsDiscovery();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const program = new Command();
|
|
182
|
+
program
|
|
183
|
+
.name('pibo tools')
|
|
184
|
+
.description('Install and inspect curated external CLI tools')
|
|
185
|
+
.helpOption(false)
|
|
186
|
+
.showHelpAfterError();
|
|
187
|
+
program
|
|
188
|
+
.command('list')
|
|
189
|
+
.description('List curated CLI tools')
|
|
190
|
+
.action(() => printList(false));
|
|
191
|
+
program
|
|
192
|
+
.command('installed')
|
|
193
|
+
.description('List installed CLI tools')
|
|
194
|
+
.action(() => printList(true));
|
|
195
|
+
program
|
|
196
|
+
.command('show')
|
|
197
|
+
.argument('<name>')
|
|
198
|
+
.description('Show one CLI tool preset')
|
|
199
|
+
.action(printShow);
|
|
200
|
+
program
|
|
201
|
+
.command('install')
|
|
202
|
+
.argument('<name>')
|
|
203
|
+
.option('--no-setup', 'Only print install target without installing runtime')
|
|
204
|
+
.description('Install a CLI tool')
|
|
205
|
+
.action(async (name, options) => {
|
|
206
|
+
await installCliTool(requireEntry(name), options.setup !== false);
|
|
207
|
+
});
|
|
208
|
+
program
|
|
209
|
+
.command('remove')
|
|
210
|
+
.argument('<name>')
|
|
211
|
+
.description('Remove an installed CLI tool runtime')
|
|
212
|
+
.action(async (name) => {
|
|
213
|
+
await removeCliTool(requireEntry(name));
|
|
214
|
+
});
|
|
215
|
+
program
|
|
216
|
+
.command('doctor')
|
|
217
|
+
.argument('<name>')
|
|
218
|
+
.description('Check tool prerequisites and runtime state')
|
|
219
|
+
.action(async (name) => {
|
|
220
|
+
await doctorCliTool(requireEntry(name));
|
|
221
|
+
});
|
|
222
|
+
program
|
|
223
|
+
.command('guides')
|
|
224
|
+
.argument('<name>')
|
|
225
|
+
.description('List guides for a CLI tool')
|
|
226
|
+
.action(printGuides);
|
|
227
|
+
program
|
|
228
|
+
.command('guide')
|
|
229
|
+
.argument('<name>')
|
|
230
|
+
.argument('[guide]')
|
|
231
|
+
.description('Print a CLI tool guide')
|
|
232
|
+
.action(printGuide);
|
|
233
|
+
program
|
|
234
|
+
.command('path')
|
|
235
|
+
.argument('<name>')
|
|
236
|
+
.description('Print the installed tool executable path')
|
|
237
|
+
.action(printPath);
|
|
238
|
+
program
|
|
239
|
+
.command('env')
|
|
240
|
+
.argument('<name>')
|
|
241
|
+
.description('Print shell exports for using the tool directly')
|
|
242
|
+
.action(printEnv);
|
|
243
|
+
const browserUse = program
|
|
244
|
+
.command('browser-use')
|
|
245
|
+
.description('Browser-use auth slots and helper commands')
|
|
246
|
+
.action(printBrowserUseDiscovery);
|
|
247
|
+
browserUse
|
|
248
|
+
.command('targets')
|
|
249
|
+
.description('List Chrome CDP targets with Chat auth hints')
|
|
250
|
+
.option('--cdp-url <url>', 'Chrome DevTools HTTP URL', 'http://127.0.0.1:56663')
|
|
251
|
+
.option('--no-probe', 'Only read /json/list without page DOM probes')
|
|
252
|
+
.option('--json', 'Print machine-readable target data')
|
|
253
|
+
.action(async (options) => {
|
|
254
|
+
const targets = await listBrowserUseCdpTargets({ cdpUrl: options.cdpUrl, probe: options.probe });
|
|
255
|
+
if (options.json) {
|
|
256
|
+
console.log(JSON.stringify({ targets }, null, 2));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
console.log(formatBrowserUseTargets(targets));
|
|
260
|
+
if (targets.length === 0) {
|
|
261
|
+
console.log('');
|
|
262
|
+
console.log('Next: eval "$(pibo tools env browser-use)"');
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
browserUse
|
|
266
|
+
.command('attach-chat')
|
|
267
|
+
.description('Export the best existing authenticated Chat target')
|
|
268
|
+
.option('--cdp-url <url>', 'Chrome DevTools HTTP URL', 'http://127.0.0.1:56663')
|
|
269
|
+
.option('--json', 'Print machine-readable target data')
|
|
270
|
+
.action(async (options) => {
|
|
271
|
+
const targets = await listBrowserUseCdpTargets({ cdpUrl: options.cdpUrl });
|
|
272
|
+
const target = selectBestChatTarget(targets);
|
|
273
|
+
if (!target) {
|
|
274
|
+
throw new Error(formatCliError({
|
|
275
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
276
|
+
type: 'BROWSER_USE_CHAT_TARGET_NOT_FOUND',
|
|
277
|
+
message: 'No authenticated Chat Web target with a composer textarea was found',
|
|
278
|
+
suggestion: 'Run `pibo tools browser-use targets`, reuse an authenticated tab if present, or acquire a slot with `pibo tools browser-use lease acquire`.',
|
|
279
|
+
}));
|
|
280
|
+
}
|
|
281
|
+
if (options.json) {
|
|
282
|
+
console.log(JSON.stringify({ target }, null, 2));
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
printAttachChatExports(target, options.cdpUrl);
|
|
286
|
+
});
|
|
287
|
+
const authTemplate = browserUse
|
|
288
|
+
.command('auth-template')
|
|
289
|
+
.description('Manage the browser-use authenticated template profile')
|
|
290
|
+
.action(() => {
|
|
291
|
+
console.log(`pibo tools browser-use auth-template
|
|
292
|
+
|
|
293
|
+
Commands:
|
|
294
|
+
path Print the default authenticated template profile path
|
|
295
|
+
env Print shell exports for preparing the auth template profile`);
|
|
296
|
+
});
|
|
297
|
+
authTemplate
|
|
298
|
+
.command('path')
|
|
299
|
+
.description('Print the default authenticated template profile path')
|
|
300
|
+
.action(() => {
|
|
301
|
+
printBrowserUseAuthTemplatePath(getCliToolStatus(requireEntry('browser-use')));
|
|
302
|
+
});
|
|
303
|
+
authTemplate
|
|
304
|
+
.command('env')
|
|
305
|
+
.description('Print shell exports for preparing the auth template profile')
|
|
306
|
+
.action(async () => {
|
|
307
|
+
await printBrowserUseAuthTemplateEnv(getCliToolStatus(requireEntry('browser-use')));
|
|
308
|
+
});
|
|
309
|
+
const lease = browserUse
|
|
310
|
+
.command('lease')
|
|
311
|
+
.description('Acquire and manage isolated authenticated browser-use slots')
|
|
312
|
+
.action(() => {
|
|
313
|
+
console.log(`pibo tools browser-use lease
|
|
314
|
+
|
|
315
|
+
Commands:
|
|
316
|
+
acquire Acquire an isolated authenticated browser slot
|
|
317
|
+
list List authenticated browser slots
|
|
318
|
+
release <id> Release one browser slot
|
|
319
|
+
reap-stale Release expired or dead browser slots`);
|
|
320
|
+
});
|
|
321
|
+
lease
|
|
322
|
+
.command('acquire')
|
|
323
|
+
.description('Acquire an isolated authenticated browser slot')
|
|
324
|
+
.option('--app <name>', 'Auth pool app name', 'pibo-chat')
|
|
325
|
+
.option('--owner <owner>', 'Lease owner label')
|
|
326
|
+
.option('--ttl-minutes <minutes>', 'Lease time-to-live in minutes', parsePositiveInteger)
|
|
327
|
+
.option('--max-slots <count>', 'Maximum active slots for the app', parsePositiveInteger)
|
|
328
|
+
.option('--template-dir <path>', 'Authenticated Chrome user-data-dir template to clone')
|
|
329
|
+
.option('--profile-name <name>', 'Chrome profile name inside each slot')
|
|
330
|
+
.option('--json', 'Print machine-readable lease data')
|
|
331
|
+
.action(async (options) => {
|
|
332
|
+
await acquireBrowserUseLease({ status: getCliToolStatus(requireEntry('browser-use')) }, options);
|
|
333
|
+
});
|
|
334
|
+
lease
|
|
335
|
+
.command('list')
|
|
336
|
+
.description('List authenticated browser slots')
|
|
337
|
+
.option('--json', 'Print machine-readable lease data')
|
|
338
|
+
.action(async (options) => {
|
|
339
|
+
await listBrowserUseLeases({ status: getCliToolStatus(requireEntry('browser-use')) }, Boolean(options.json));
|
|
340
|
+
});
|
|
341
|
+
lease
|
|
342
|
+
.command('release')
|
|
343
|
+
.argument('<id>')
|
|
344
|
+
.option('--delete-profile', 'Delete the slot Chrome user-data-dir')
|
|
345
|
+
.description('Release one browser slot')
|
|
346
|
+
.action(async (id, options) => {
|
|
347
|
+
await releaseBrowserUseLease({ status: getCliToolStatus(requireEntry('browser-use')) }, id, options);
|
|
348
|
+
});
|
|
349
|
+
lease
|
|
350
|
+
.command('reap-stale')
|
|
351
|
+
.description('Release expired or dead browser slots')
|
|
352
|
+
.action(async () => {
|
|
353
|
+
await reapStaleBrowserUseLeases({ status: getCliToolStatus(requireEntry('browser-use')) });
|
|
354
|
+
});
|
|
355
|
+
if (argv.length <= 2) {
|
|
356
|
+
printList(false);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
await program.parseAsync(argv);
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
console.error(error.message);
|
|
364
|
+
process.exitCode = ErrorCode.CLIENT_ERROR;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { mkdir, rm } from 'node:fs/promises';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { ErrorCode, formatCliError } from '../cli-errors.js';
|
|
7
|
+
import { getDesktopProcessEnv, printDesktopEnvStatus } from './desktop-env.js';
|
|
8
|
+
function getPiboHome() {
|
|
9
|
+
return process.env.PIBO_HOME || join(homedir(), '.pibo');
|
|
10
|
+
}
|
|
11
|
+
export function getToolPythonRuntimePaths(name, spec) {
|
|
12
|
+
const rootDir = join(getPiboHome(), 'tools', name);
|
|
13
|
+
const homeDir = join(rootDir, 'home');
|
|
14
|
+
const venvDir = join(rootDir, '.venv');
|
|
15
|
+
const binDir = join(venvDir, process.platform === 'win32' ? 'Scripts' : 'bin');
|
|
16
|
+
const executable = process.platform === 'win32'
|
|
17
|
+
? `${spec.executableName}.exe`
|
|
18
|
+
: spec.executableName;
|
|
19
|
+
return {
|
|
20
|
+
rootDir,
|
|
21
|
+
homeDir,
|
|
22
|
+
venvDir,
|
|
23
|
+
binDir,
|
|
24
|
+
pythonPath: join(binDir, process.platform === 'win32' ? 'python.exe' : 'python'),
|
|
25
|
+
executablePath: join(binDir, executable),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function getToolPythonRuntimeEnv(paths, spec) {
|
|
29
|
+
const env = { ...process.env, ...getDesktopProcessEnv() };
|
|
30
|
+
env.PATH = `${paths.binDir}:${join(paths.homeDir, 'bin')}:${env.PATH ?? ''}`;
|
|
31
|
+
if (spec.homeEnvVar)
|
|
32
|
+
env[spec.homeEnvVar] = paths.homeDir;
|
|
33
|
+
return env;
|
|
34
|
+
}
|
|
35
|
+
function runBuffered(command, args, env = process.env) {
|
|
36
|
+
return new Promise((resolve) => {
|
|
37
|
+
const child = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'], env });
|
|
38
|
+
const chunks = [];
|
|
39
|
+
child.stdout.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
|
|
40
|
+
child.stderr.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
|
|
41
|
+
child.on('error', (error) => {
|
|
42
|
+
resolve({ ok: false, output: error.message });
|
|
43
|
+
});
|
|
44
|
+
child.on('close', (code) => {
|
|
45
|
+
resolve({
|
|
46
|
+
ok: code === 0,
|
|
47
|
+
output: Buffer.concat(chunks).toString('utf-8').trim(),
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function runInherited(command, args, env = process.env) {
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
console.log(`Running: ${command} ${args.join(' ')}`);
|
|
55
|
+
const child = spawn(command, args, {
|
|
56
|
+
stdio: 'inherit',
|
|
57
|
+
env,
|
|
58
|
+
});
|
|
59
|
+
child.on('error', (error) => {
|
|
60
|
+
reject(new Error(formatCliError({
|
|
61
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
62
|
+
type: 'CLI_TOOL_COMMAND_FAILED',
|
|
63
|
+
message: `Failed to run command: ${command}`,
|
|
64
|
+
details: error.message,
|
|
65
|
+
suggestion: 'Install uv first, then rerun the command.',
|
|
66
|
+
})));
|
|
67
|
+
});
|
|
68
|
+
child.on('close', (code) => {
|
|
69
|
+
if (code === 0) {
|
|
70
|
+
resolve();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
reject(new Error(formatCliError({
|
|
74
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
75
|
+
type: 'CLI_TOOL_COMMAND_FAILED',
|
|
76
|
+
message: `Command failed with exit code ${code ?? 'unknown'}`,
|
|
77
|
+
details: `${command} ${args.join(' ')}`,
|
|
78
|
+
suggestion: 'Fix the setup error above, then rerun the install command.',
|
|
79
|
+
})));
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
export async function printToolPythonRuntimeDoctor(name, spec) {
|
|
84
|
+
const paths = getToolPythonRuntimePaths(name, spec);
|
|
85
|
+
const uv = await runBuffered('uv', ['--version']);
|
|
86
|
+
const python = uv.ok
|
|
87
|
+
? await runBuffered('uv', ['python', 'find', spec.pythonVersion])
|
|
88
|
+
: { ok: false, output: 'skipped because uv is missing' };
|
|
89
|
+
console.log(`${name}`);
|
|
90
|
+
console.log(` uv: ${uv.ok ? uv.output || 'ok' : `missing (${uv.output})`}`);
|
|
91
|
+
console.log(` python ${spec.pythonVersion}: ${python.ok ? python.output || 'ok' : `missing (${python.output})`}`);
|
|
92
|
+
console.log(` runtime: ${paths.rootDir}`);
|
|
93
|
+
console.log(` home: ${paths.homeDir}`);
|
|
94
|
+
console.log(` venv: ${existsSync(paths.venvDir) ? 'present' : 'missing'}`);
|
|
95
|
+
console.log(` executable: ${existsSync(paths.executablePath) ? paths.executablePath : 'missing'}`);
|
|
96
|
+
printDesktopEnvStatus(' ');
|
|
97
|
+
if (existsSync(paths.executablePath)) {
|
|
98
|
+
const doctor = await runBuffered(paths.executablePath, ['doctor'], getToolPythonRuntimeEnv(paths, spec));
|
|
99
|
+
console.log(` tool doctor: ${doctor.ok ? 'ok' : 'failed'}`);
|
|
100
|
+
if (doctor.output) {
|
|
101
|
+
console.log(doctor.output.split('\n').map((line) => ` ${line}`).join('\n'));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!uv.ok) {
|
|
105
|
+
console.log('');
|
|
106
|
+
console.log('Install uv first:');
|
|
107
|
+
console.log(' macOS/Linux: curl -LsSf https://astral.sh/uv/install.sh | sh');
|
|
108
|
+
console.log(' Windows PowerShell: irm https://astral.sh/uv/install.ps1 | iex');
|
|
109
|
+
}
|
|
110
|
+
if (uv.ok && !python.ok) {
|
|
111
|
+
console.log('');
|
|
112
|
+
console.log(`Install Python ${spec.pythonVersion}+ first:`);
|
|
113
|
+
console.log(' Ubuntu/Debian: sudo apt update && sudo apt install -y python3 python3-venv');
|
|
114
|
+
console.log(' macOS: brew install python');
|
|
115
|
+
console.log(' Windows PowerShell: winget install Python.Python.3.12');
|
|
116
|
+
console.log('');
|
|
117
|
+
console.log('Then rerun:');
|
|
118
|
+
console.log(` pibo tools doctor ${name}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export async function installToolPythonRuntime(name, spec) {
|
|
122
|
+
const uv = await runBuffered('uv', ['--version']);
|
|
123
|
+
if (!uv.ok) {
|
|
124
|
+
throw new Error(formatCliError({
|
|
125
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
126
|
+
type: 'CLI_TOOL_UV_MISSING',
|
|
127
|
+
message: 'uv was not found on PATH',
|
|
128
|
+
details: uv.output,
|
|
129
|
+
suggestion: 'Install uv first. macOS/Linux: curl -LsSf https://astral.sh/uv/install.sh | sh. Windows PowerShell: irm https://astral.sh/uv/install.ps1 | iex.',
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
const paths = getToolPythonRuntimePaths(name, spec);
|
|
133
|
+
await mkdir(paths.rootDir, { recursive: true });
|
|
134
|
+
await mkdir(paths.homeDir, { recursive: true });
|
|
135
|
+
if (!existsSync(paths.venvDir)) {
|
|
136
|
+
await runInherited('uv', ['venv', paths.venvDir, '--python', spec.pythonVersion]);
|
|
137
|
+
}
|
|
138
|
+
await runInherited('uv', [
|
|
139
|
+
'pip',
|
|
140
|
+
'install',
|
|
141
|
+
'--python',
|
|
142
|
+
paths.pythonPath,
|
|
143
|
+
spec.packageName,
|
|
144
|
+
]);
|
|
145
|
+
if (spec.postInstallArgs?.length) {
|
|
146
|
+
await runInherited(paths.executablePath, spec.postInstallArgs, getToolPythonRuntimeEnv(paths, spec));
|
|
147
|
+
}
|
|
148
|
+
return paths;
|
|
149
|
+
}
|
|
150
|
+
export async function removeToolPythonRuntime(name, spec) {
|
|
151
|
+
const paths = getToolPythonRuntimePaths(name, spec);
|
|
152
|
+
await rm(paths.rootDir, { recursive: true, force: true });
|
|
153
|
+
console.log(`Removed runtime: ${paths.rootDir}`);
|
|
154
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { printDesktopEnvStatus } from './desktop-env.js';
|
|
3
|
+
import { BROWSER_USE_GUIDE, REMOTE_BROWSER_GUIDE } from './guides.js';
|
|
4
|
+
import { getToolPythonRuntimePaths, installToolPythonRuntime, printToolPythonRuntimeDoctor, removeToolPythonRuntime, } from './python-runtime.js';
|
|
5
|
+
const MAX_AGENT_CONTEXT_SNIPPET_LENGTH = 480;
|
|
6
|
+
const INSTALLED_TOOLS_CONTEXT_PATH = '.pibo/context/installed-pibo-tools.md';
|
|
7
|
+
const REGISTRY = [
|
|
8
|
+
{
|
|
9
|
+
name: 'browser-use',
|
|
10
|
+
description: 'Browser automation CLI for web interaction, screenshots, and extraction.',
|
|
11
|
+
runtime: {
|
|
12
|
+
packageName: 'browser-use[cli]==0.12.6',
|
|
13
|
+
executableName: 'browser-use',
|
|
14
|
+
pythonVersion: '3.12',
|
|
15
|
+
homeEnvVar: 'BROWSER_USE_HOME',
|
|
16
|
+
},
|
|
17
|
+
guides: [BROWSER_USE_GUIDE, REMOTE_BROWSER_GUIDE],
|
|
18
|
+
notes: [
|
|
19
|
+
'Installed on demand into an isolated Python virtual environment.',
|
|
20
|
+
'Pinned to browser-use 0.12.6 so the CLI surface matches the bundled guides.',
|
|
21
|
+
'The tool uses BROWSER_USE_HOME under the pibo tool runtime directory.',
|
|
22
|
+
'The pibo tool environment wraps browser-use so new browser sessions default to Pibo-managed persistent PIBo Chrome via CDP; pass --fresh-profile for a temporary profile.',
|
|
23
|
+
'Use pibo tools browser-use lease acquire for isolated authenticated browser slots when multiple agents need Chat Web App access.',
|
|
24
|
+
'Guides are available through pibo tools guide and are not loaded into pibo profiles automatically.',
|
|
25
|
+
],
|
|
26
|
+
agentContextSnippet: [
|
|
27
|
+
'Browser automation CLI for frontend development and web testing.',
|
|
28
|
+
'Start in one persistent shell with `eval "$(npm run --silent dev -- tools env browser-use)"`.',
|
|
29
|
+
'For authenticated Pibo Chat Web App testing, prefer `eval "$(npm run --silent dev -- tools browser-use lease acquire --app pibo-chat --owner "$USER")"`.',
|
|
30
|
+
'Discover details with `npm run dev -- tools show browser-use` and `npm run dev -- tools guide browser-use browser-use`.',
|
|
31
|
+
].join('\n'),
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
for (const entry of REGISTRY) {
|
|
35
|
+
const snippet = entry.agentContextSnippet.trim();
|
|
36
|
+
if (snippet.length === 0) {
|
|
37
|
+
throw new Error(`CLI tool "${entry.name}" is missing agentContextSnippet`);
|
|
38
|
+
}
|
|
39
|
+
if (snippet.length > MAX_AGENT_CONTEXT_SNIPPET_LENGTH) {
|
|
40
|
+
throw new Error(`CLI tool "${entry.name}" agentContextSnippet exceeds ${MAX_AGENT_CONTEXT_SNIPPET_LENGTH} characters`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export function listCliToolEntries() {
|
|
44
|
+
return REGISTRY;
|
|
45
|
+
}
|
|
46
|
+
export function findCliToolEntry(name) {
|
|
47
|
+
return REGISTRY.find((entry) => entry.name === name);
|
|
48
|
+
}
|
|
49
|
+
export function getCliToolStatus(entry) {
|
|
50
|
+
const paths = getToolPythonRuntimePaths(entry.name, entry.runtime);
|
|
51
|
+
return {
|
|
52
|
+
entry,
|
|
53
|
+
installed: existsSync(paths.executablePath),
|
|
54
|
+
executablePath: paths.executablePath,
|
|
55
|
+
rootDir: paths.rootDir,
|
|
56
|
+
homeDir: paths.homeDir,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function findToolGuide(entry, guideName) {
|
|
60
|
+
return entry.guides.find((guide) => guide.name === guideName);
|
|
61
|
+
}
|
|
62
|
+
export function listInstalledCliToolAgentContexts() {
|
|
63
|
+
return REGISTRY
|
|
64
|
+
.filter((entry) => getCliToolStatus(entry).installed)
|
|
65
|
+
.map((entry) => ({
|
|
66
|
+
name: entry.name,
|
|
67
|
+
description: entry.description,
|
|
68
|
+
snippet: entry.agentContextSnippet,
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
export function getInstalledCliToolContextFile() {
|
|
72
|
+
const installedEntries = listInstalledCliToolAgentContexts();
|
|
73
|
+
if (installedEntries.length === 0)
|
|
74
|
+
return undefined;
|
|
75
|
+
const sections = installedEntries.flatMap((entry) => [
|
|
76
|
+
`## ${entry.name}`,
|
|
77
|
+
entry.snippet,
|
|
78
|
+
'',
|
|
79
|
+
]);
|
|
80
|
+
return {
|
|
81
|
+
path: INSTALLED_TOOLS_CONTEXT_PATH,
|
|
82
|
+
content: [
|
|
83
|
+
'# Installed Pibo Tools',
|
|
84
|
+
'',
|
|
85
|
+
'These curated CLI tools are installed in this environment. The CLI remains the source of truth; use the referenced commands to discover each workflow step by step.',
|
|
86
|
+
'',
|
|
87
|
+
...sections,
|
|
88
|
+
].join('\n').trimEnd(),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export async function installCliTool(entry, runSetup) {
|
|
92
|
+
if (runSetup) {
|
|
93
|
+
await installToolPythonRuntime(entry.name, entry.runtime);
|
|
94
|
+
}
|
|
95
|
+
const status = getCliToolStatus(entry);
|
|
96
|
+
console.log(`${runSetup ? 'Installed' : 'Install target'} ${entry.name}`);
|
|
97
|
+
console.log(` executable: ${status.executablePath}`);
|
|
98
|
+
console.log(` home: ${status.homeDir}`);
|
|
99
|
+
printDesktopEnvStatus(' ');
|
|
100
|
+
console.log(` env: pibo tools env ${entry.name}`);
|
|
101
|
+
}
|
|
102
|
+
export async function removeCliTool(entry) {
|
|
103
|
+
await removeToolPythonRuntime(entry.name, entry.runtime);
|
|
104
|
+
}
|
|
105
|
+
export async function doctorCliTool(entry) {
|
|
106
|
+
await printToolPythonRuntimeDoctor(entry.name, entry.runtime);
|
|
107
|
+
}
|