@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,131 @@
|
|
|
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 './errors.js';
|
|
7
|
+
function getPiboHome() {
|
|
8
|
+
return process.env.PIBO_HOME || join(homedir(), '.pibo');
|
|
9
|
+
}
|
|
10
|
+
export function getPythonRuntimePaths(name, spec) {
|
|
11
|
+
const rootDir = join(getPiboHome(), 'mcp-tools', name);
|
|
12
|
+
const venvDir = join(rootDir, '.venv');
|
|
13
|
+
const binDir = process.platform === 'win32' ? 'Scripts' : 'bin';
|
|
14
|
+
const executable = process.platform === 'win32'
|
|
15
|
+
? `${spec.executableName}.exe`
|
|
16
|
+
: spec.executableName;
|
|
17
|
+
return {
|
|
18
|
+
rootDir,
|
|
19
|
+
venvDir,
|
|
20
|
+
pythonPath: join(venvDir, binDir, process.platform === 'win32' ? 'python.exe' : 'python'),
|
|
21
|
+
executablePath: join(venvDir, binDir, executable),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function runBuffered(command, args) {
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
const child = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
27
|
+
const chunks = [];
|
|
28
|
+
child.stdout.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
|
|
29
|
+
child.stderr.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
|
|
30
|
+
child.on('error', (error) => {
|
|
31
|
+
resolve({ ok: false, output: error.message });
|
|
32
|
+
});
|
|
33
|
+
child.on('close', (code) => {
|
|
34
|
+
resolve({
|
|
35
|
+
ok: code === 0,
|
|
36
|
+
output: Buffer.concat(chunks).toString('utf-8').trim(),
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function runInherited(command, args) {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
console.log(`Running: ${command} ${args.join(' ')}`);
|
|
44
|
+
const child = spawn(command, args, {
|
|
45
|
+
stdio: 'inherit',
|
|
46
|
+
env: process.env,
|
|
47
|
+
});
|
|
48
|
+
child.on('error', (error) => {
|
|
49
|
+
reject(new Error(formatCliError({
|
|
50
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
51
|
+
type: 'PYTHON_RUNTIME_COMMAND_FAILED',
|
|
52
|
+
message: `Failed to run command: ${command}`,
|
|
53
|
+
details: error.message,
|
|
54
|
+
suggestion: 'Install uv first, then rerun the command.',
|
|
55
|
+
})));
|
|
56
|
+
});
|
|
57
|
+
child.on('close', (code) => {
|
|
58
|
+
if (code === 0) {
|
|
59
|
+
resolve();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
reject(new Error(formatCliError({
|
|
63
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
64
|
+
type: 'PYTHON_RUNTIME_COMMAND_FAILED',
|
|
65
|
+
message: `Command failed with exit code ${code ?? 'unknown'}`,
|
|
66
|
+
details: `${command} ${args.join(' ')}`,
|
|
67
|
+
suggestion: 'Fix the setup error above, then rerun the install command.',
|
|
68
|
+
})));
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export async function printPythonRuntimeDoctor(name, spec) {
|
|
73
|
+
const paths = getPythonRuntimePaths(name, spec);
|
|
74
|
+
const uv = await runBuffered('uv', ['--version']);
|
|
75
|
+
const python = uv.ok
|
|
76
|
+
? await runBuffered('uv', ['python', 'find', spec.pythonVersion])
|
|
77
|
+
: { ok: false, output: 'skipped because uv is missing' };
|
|
78
|
+
console.log(`${name}`);
|
|
79
|
+
console.log(` uv: ${uv.ok ? uv.output || 'ok' : `missing (${uv.output})`}`);
|
|
80
|
+
console.log(` python ${spec.pythonVersion}: ${python.ok ? python.output || 'ok' : `missing (${python.output})`}`);
|
|
81
|
+
console.log(` runtime: ${paths.rootDir}`);
|
|
82
|
+
console.log(` venv: ${existsSync(paths.venvDir) ? 'present' : 'missing'}`);
|
|
83
|
+
console.log(` executable: ${existsSync(paths.executablePath) ? paths.executablePath : 'missing'}`);
|
|
84
|
+
if (!uv.ok) {
|
|
85
|
+
console.log('');
|
|
86
|
+
console.log('Install uv first:');
|
|
87
|
+
console.log(' macOS/Linux: curl -LsSf https://astral.sh/uv/install.sh | sh');
|
|
88
|
+
console.log(' Windows PowerShell: irm https://astral.sh/uv/install.ps1 | iex');
|
|
89
|
+
}
|
|
90
|
+
if (uv.ok && !python.ok) {
|
|
91
|
+
console.log('');
|
|
92
|
+
console.log(`Install Python ${spec.pythonVersion}+ first:`);
|
|
93
|
+
console.log(' Ubuntu/Debian: sudo apt update && sudo apt install -y python3 python3-venv');
|
|
94
|
+
console.log(' macOS: brew install python');
|
|
95
|
+
console.log(' Windows PowerShell: winget install Python.Python.3.12');
|
|
96
|
+
console.log('');
|
|
97
|
+
console.log('Then rerun:');
|
|
98
|
+
console.log(` pibo mcp registry doctor ${name}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export async function installPythonRuntime(name, spec) {
|
|
102
|
+
const uv = await runBuffered('uv', ['--version']);
|
|
103
|
+
if (!uv.ok) {
|
|
104
|
+
throw new Error(formatCliError({
|
|
105
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
106
|
+
type: 'PYTHON_RUNTIME_UV_MISSING',
|
|
107
|
+
message: 'uv was not found on PATH',
|
|
108
|
+
details: uv.output,
|
|
109
|
+
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.',
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
const paths = getPythonRuntimePaths(name, spec);
|
|
113
|
+
await mkdir(paths.rootDir, { recursive: true });
|
|
114
|
+
await runInherited('uv', ['venv', paths.venvDir, '--python', spec.pythonVersion]);
|
|
115
|
+
await runInherited('uv', [
|
|
116
|
+
'pip',
|
|
117
|
+
'install',
|
|
118
|
+
'--python',
|
|
119
|
+
paths.pythonPath,
|
|
120
|
+
spec.packageName,
|
|
121
|
+
]);
|
|
122
|
+
if (spec.postInstallArgs?.length) {
|
|
123
|
+
await runInherited(paths.executablePath, spec.postInstallArgs);
|
|
124
|
+
}
|
|
125
|
+
return paths;
|
|
126
|
+
}
|
|
127
|
+
export async function removePythonRuntime(name, spec) {
|
|
128
|
+
const paths = getPythonRuntimePaths(name, spec);
|
|
129
|
+
await rm(paths.rootDir, { recursive: true, force: true });
|
|
130
|
+
console.log(`Removed runtime: ${paths.rootDir}`);
|
|
131
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { configCommand } from './config-command.js';
|
|
2
|
+
import { ErrorCode, formatCliError } from './errors.js';
|
|
3
|
+
import { getPythonRuntimePaths, installPythonRuntime, printPythonRuntimeDoctor, removePythonRuntime, } from './python-runtime.js';
|
|
4
|
+
const REGISTRY = [];
|
|
5
|
+
function findRegistryEntry(name) {
|
|
6
|
+
return REGISTRY.find((entry) => entry.name === name);
|
|
7
|
+
}
|
|
8
|
+
function buildServerConfig(entry) {
|
|
9
|
+
const paths = getPythonRuntimePaths(entry.name, entry.runtime);
|
|
10
|
+
return {
|
|
11
|
+
command: paths.executablePath,
|
|
12
|
+
args: entry.serverArgs,
|
|
13
|
+
...(entry.serverEnv ? { env: entry.serverEnv } : {}),
|
|
14
|
+
...(entry.agentDescription
|
|
15
|
+
? { pibo: { description: entry.agentDescription, descriptionSource: 'registry' } }
|
|
16
|
+
: {}),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function printRegistryHelp() {
|
|
20
|
+
console.log(`
|
|
21
|
+
MCP server registry
|
|
22
|
+
|
|
23
|
+
Commands:
|
|
24
|
+
pibo mcp registry list List built-in MCP server presets
|
|
25
|
+
pibo mcp registry show <name> Show one preset
|
|
26
|
+
pibo mcp registry doctor <name> Check runtime prerequisites
|
|
27
|
+
pibo mcp registry install <name> Install setup deps and add preset to mcp_servers.json
|
|
28
|
+
pibo mcp registry install <name> --no-setup Only add preset to mcp_servers.json
|
|
29
|
+
pibo mcp registry remove <name> Remove config and local runtime
|
|
30
|
+
pibo mcp registry help Show this help
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
function printEntry(entry) {
|
|
34
|
+
const paths = getPythonRuntimePaths(entry.name, entry.runtime);
|
|
35
|
+
console.log(`${entry.name}`);
|
|
36
|
+
console.log(` ${entry.description}`);
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log('Runtime:');
|
|
39
|
+
console.log(` package: ${entry.runtime.packageName}`);
|
|
40
|
+
console.log(` python: ${entry.runtime.pythonVersion}`);
|
|
41
|
+
console.log(` path: ${paths.rootDir}`);
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log('Server config:');
|
|
44
|
+
console.log(JSON.stringify(buildServerConfig(entry), null, 2));
|
|
45
|
+
if (entry.notes.length > 0) {
|
|
46
|
+
console.log('');
|
|
47
|
+
console.log('Notes:');
|
|
48
|
+
for (const note of entry.notes) {
|
|
49
|
+
console.log(` - ${note}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function installEntry(entry, options) {
|
|
54
|
+
if (options.runSetup !== false) {
|
|
55
|
+
await installPythonRuntime(entry.name, entry.runtime);
|
|
56
|
+
}
|
|
57
|
+
await configCommand({
|
|
58
|
+
action: 'add',
|
|
59
|
+
name: entry.name,
|
|
60
|
+
serverJson: JSON.stringify(buildServerConfig(entry)),
|
|
61
|
+
configPath: options.configPath,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export async function registryCommand(options) {
|
|
65
|
+
if (options.action === 'help') {
|
|
66
|
+
printRegistryHelp();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (options.action === 'list') {
|
|
70
|
+
if (REGISTRY.length === 0) {
|
|
71
|
+
console.log('No registry entries are currently bundled.');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
for (const entry of REGISTRY) {
|
|
75
|
+
console.log(`${entry.name}\t${entry.description}`);
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (!options.name) {
|
|
80
|
+
throw new Error(formatCliError({
|
|
81
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
82
|
+
type: 'MISSING_ARGUMENT',
|
|
83
|
+
message: `registry ${options.action} requires <name>`,
|
|
84
|
+
suggestion: 'Run pibo mcp registry list to see available presets.',
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
const entry = findRegistryEntry(options.name);
|
|
88
|
+
if (!entry) {
|
|
89
|
+
throw new Error(formatCliError({
|
|
90
|
+
code: ErrorCode.CLIENT_ERROR,
|
|
91
|
+
type: 'MCP_REGISTRY_ENTRY_NOT_FOUND',
|
|
92
|
+
message: `Registry entry "${options.name}" not found`,
|
|
93
|
+
details: REGISTRY.length > 0
|
|
94
|
+
? `Available entries: ${REGISTRY.map((item) => item.name).join(', ')}`
|
|
95
|
+
: 'No registry entries are currently bundled.',
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
if (options.action === 'show') {
|
|
99
|
+
printEntry(entry);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (options.action === 'doctor') {
|
|
103
|
+
await printPythonRuntimeDoctor(entry.name, entry.runtime);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (options.action === 'install') {
|
|
107
|
+
await installEntry(entry, options);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
await configCommand({
|
|
111
|
+
action: 'remove',
|
|
112
|
+
name: entry.name,
|
|
113
|
+
configPath: options.configPath,
|
|
114
|
+
});
|
|
115
|
+
await removePythonRuntime(entry.name, entry.runtime);
|
|
116
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { inspectPiPackageSource, parsePiPackageSource } from "./metadata.js";
|
|
3
|
+
import { findPiPackage, listPiPackages, removePiPackage, upsertPiPackage } from "./store.js";
|
|
4
|
+
export async function runPiPackagesCli(argv = process.argv) {
|
|
5
|
+
if (argv[2] === "--help" || argv[2] === "-h" || argv.length <= 2) {
|
|
6
|
+
printPiPackagesDiscovery();
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program.name("pibo pi-packages").description("Register Pi Coding Agent packages for Pibo profiles").helpOption(false);
|
|
11
|
+
program.command("list").description("List registered Pi packages").action(() => {
|
|
12
|
+
const packages = listPiPackages();
|
|
13
|
+
if (packages.length === 0) {
|
|
14
|
+
console.log("No Pi packages registered.");
|
|
15
|
+
console.log("Next: pibo pi-packages add <source>");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
for (const pkg of packages) {
|
|
19
|
+
console.log(`${pkg.name.padEnd(24)} ${pkg.installStatus.padEnd(10)} ${(pkg.resourceTypes.join(", ") || "unknown").padEnd(20)} ${pkg.installSpec}`);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
program.command("add").argument("<source>").description("Register a pi.dev package URL or local path").action(async (source) => {
|
|
23
|
+
const pkg = upsertPiPackage(await inspectPiPackageSource(source));
|
|
24
|
+
console.log(`Added Pi package ${pkg.name}`);
|
|
25
|
+
console.log(` source: ${pkg.source}`);
|
|
26
|
+
console.log(` install: ${pkg.installSpec}`);
|
|
27
|
+
console.log(` status: ${pkg.installStatus}`);
|
|
28
|
+
console.log(`Next: pibo pi-packages inspect ${pkg.id}`);
|
|
29
|
+
});
|
|
30
|
+
program.command("inspect").argument("<name-or-id>").description("Inspect one registered Pi package").action((nameOrId) => {
|
|
31
|
+
const pkg = findPiPackage(nameOrId);
|
|
32
|
+
if (!pkg) {
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
console.error(`Unknown Pi package "${nameOrId}"`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
console.log(JSON.stringify(pkg, null, 2));
|
|
38
|
+
});
|
|
39
|
+
program.command("remove").argument("<name-or-id>").description("Remove a registered Pi package").action((nameOrId) => {
|
|
40
|
+
const removed = removePiPackage(nameOrId);
|
|
41
|
+
if (!removed) {
|
|
42
|
+
process.exitCode = 1;
|
|
43
|
+
console.error(`Unknown Pi package "${nameOrId}"`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
console.log(`Removed Pi package ${removed.name}`);
|
|
47
|
+
});
|
|
48
|
+
program.command("doctor").description("Check registered Pi package sources").action(async () => {
|
|
49
|
+
const packages = listPiPackages();
|
|
50
|
+
if (packages.length === 0) {
|
|
51
|
+
console.log("No Pi packages registered.");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
for (const pkg of packages) {
|
|
55
|
+
const diagnostics = [];
|
|
56
|
+
try {
|
|
57
|
+
await parsePiPackageSource(pkg.source);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
diagnostics.push(error instanceof Error ? error.message : String(error));
|
|
61
|
+
}
|
|
62
|
+
if (pkg.installPath && !pkg.installPath.startsWith("npm:")) {
|
|
63
|
+
try {
|
|
64
|
+
await parsePiPackageSource(pkg.installPath);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
diagnostics.push(error instanceof Error ? error.message : String(error));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const status = diagnostics.length || pkg.installStatus === "error" || pkg.installStatus === "missing" ? "error" : "ok";
|
|
71
|
+
console.log(`${pkg.name}\t${status}\t${pkg.installSpec}`);
|
|
72
|
+
for (const diagnostic of [...pkg.diagnostics.map((item) => item.message), ...diagnostics]) {
|
|
73
|
+
console.log(` ${diagnostic}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
await program.parseAsync(argv);
|
|
78
|
+
}
|
|
79
|
+
function printPiPackagesDiscovery() {
|
|
80
|
+
console.log(`pibo pi-packages - registered Pi Coding Agent packages
|
|
81
|
+
|
|
82
|
+
Commands:
|
|
83
|
+
list List registered packages
|
|
84
|
+
add <source> Register a pi.dev URL or local path
|
|
85
|
+
inspect <name-or-id> Show package metadata
|
|
86
|
+
remove <name-or-id> Remove a registration
|
|
87
|
+
doctor Check package sources
|
|
88
|
+
|
|
89
|
+
Next:
|
|
90
|
+
pibo pi-packages list
|
|
91
|
+
`);
|
|
92
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
const execFileAsync = promisify(execFile);
|
|
6
|
+
export async function installOrResolvePiPackage(parsed, cwd = process.cwd()) {
|
|
7
|
+
if (parsed.kind === "local") {
|
|
8
|
+
if (!parsed.path || !existsSync(parsed.path)) {
|
|
9
|
+
return {
|
|
10
|
+
installStatus: "missing",
|
|
11
|
+
diagnostics: [{ type: "error", message: `Local Pi package path does not exist: ${parsed.path ?? parsed.source}` }],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
installStatus: "installed",
|
|
16
|
+
installPath: parsed.path,
|
|
17
|
+
diagnostics: [{ type: "info", message: `Resolved local Pi package path: ${parsed.path}` }],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const packageName = parsed.packageName ?? parsed.name;
|
|
21
|
+
const installRoot = npmPackageInstallRoot(cwd, packageName);
|
|
22
|
+
const installPath = resolve(installRoot, "node_modules", ...packageName.split("/"));
|
|
23
|
+
try {
|
|
24
|
+
ensureNpmInstallProject(installRoot);
|
|
25
|
+
await execFileAsync("npm", ["install", packageName, "--prefix", installRoot, "--omit=dev"], {
|
|
26
|
+
cwd: installRoot,
|
|
27
|
+
timeout: 120000,
|
|
28
|
+
maxBuffer: 1024 * 1024,
|
|
29
|
+
});
|
|
30
|
+
if (!existsSync(installPath)) {
|
|
31
|
+
return {
|
|
32
|
+
installStatus: "missing",
|
|
33
|
+
installPath,
|
|
34
|
+
diagnostics: [{ type: "error", message: `npm install completed but package path is missing: ${installPath}` }],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
installStatus: "installed",
|
|
39
|
+
installPath,
|
|
40
|
+
diagnostics: [{ type: "info", message: `Installed npm Pi package ${packageName} into ${installRoot}` }],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
return {
|
|
45
|
+
installStatus: "error",
|
|
46
|
+
installPath: existsSync(installPath) ? installPath : undefined,
|
|
47
|
+
diagnostics: [{
|
|
48
|
+
type: "error",
|
|
49
|
+
message: `Could not install npm Pi package ${packageName}: ${error instanceof Error ? error.message : String(error)}`,
|
|
50
|
+
}],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export function npmPackageInstallRoot(cwd, packageName) {
|
|
55
|
+
return resolve(cwd, ".pibo/pi-packages/npm", encodePackageName(packageName));
|
|
56
|
+
}
|
|
57
|
+
function ensureNpmInstallProject(installRoot) {
|
|
58
|
+
mkdirSync(installRoot, { recursive: true });
|
|
59
|
+
const packageJsonPath = resolve(installRoot, "package.json");
|
|
60
|
+
if (!existsSync(packageJsonPath)) {
|
|
61
|
+
writeFileSync(packageJsonPath, `${JSON.stringify({ name: "pibo-pi-package", private: true }, null, 2)}\n`, "utf-8");
|
|
62
|
+
}
|
|
63
|
+
const gitIgnorePath = resolve(dirname(packageJsonPath), ".gitignore");
|
|
64
|
+
if (!existsSync(gitIgnorePath)) {
|
|
65
|
+
writeFileSync(gitIgnorePath, "*\n!.gitignore\n", "utf-8");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function encodePackageName(packageName) {
|
|
69
|
+
return encodeURIComponent(packageName).replace(/%/g, "_");
|
|
70
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { basename, extname, resolve } from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { DefaultPackageManager, getAgentDir, SettingsManager, } from "@mariozechner/pi-coding-agent";
|
|
6
|
+
import { installOrResolvePiPackage } from "./installer.js";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
export async function inspectPiPackageSource(source, cwd = process.cwd()) {
|
|
9
|
+
const parsed = await parsePiPackageSource(source, cwd);
|
|
10
|
+
const diagnostics = [...parsed.diagnostics];
|
|
11
|
+
const install = await installOrResolvePiPackage(parsed, cwd);
|
|
12
|
+
diagnostics.push(...install.diagnostics);
|
|
13
|
+
const registryMetadata = parsed.kind === "npm"
|
|
14
|
+
? await readNpmMetadata(parsed.packageName ?? parsed.name, diagnostics)
|
|
15
|
+
: {};
|
|
16
|
+
const localMetadata = install.installPath
|
|
17
|
+
? readLocalMetadata(install.installPath, diagnostics)
|
|
18
|
+
: parsed.path ? readLocalMetadata(parsed.path, diagnostics) : {};
|
|
19
|
+
const metadata = mergePackageMetadata(registryMetadata, localMetadata, parsed.name);
|
|
20
|
+
const resolved = install.installPath
|
|
21
|
+
? await resolvePackageResources(install.installPath, cwd, diagnostics)
|
|
22
|
+
: emptyResolvedPaths();
|
|
23
|
+
const resourceTypes = mergeResourceTypes(resourceTypesFromManifest(metadata.pi), resourceTypesFromResolvedPaths(resolved));
|
|
24
|
+
if (resourceTypes.length === 0) {
|
|
25
|
+
diagnostics.push({
|
|
26
|
+
type: "warning",
|
|
27
|
+
message: "No Pi package resources were discovered from the manifest or package layout.",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
id: metadata.name ?? parsed.name,
|
|
32
|
+
name: metadata.name ?? parsed.name,
|
|
33
|
+
description: metadata.description,
|
|
34
|
+
source: parsed.source,
|
|
35
|
+
installSpec: parsed.installSpec,
|
|
36
|
+
version: metadata.version,
|
|
37
|
+
repositoryUrl: repositoryUrl(metadata.repository),
|
|
38
|
+
resourceTypes,
|
|
39
|
+
extensionPaths: pathsOrUndefined(resolved.extensions),
|
|
40
|
+
skillNames: namesOrUndefined(resolved.skills),
|
|
41
|
+
promptNames: namesOrUndefined(resolved.prompts),
|
|
42
|
+
themeNames: namesOrUndefined(resolved.themes),
|
|
43
|
+
installStatus: install.installStatus,
|
|
44
|
+
installPath: install.installPath,
|
|
45
|
+
enabled: true,
|
|
46
|
+
diagnostics,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export async function parsePiPackageSource(source, cwd = process.cwd()) {
|
|
50
|
+
const trimmed = source.trim();
|
|
51
|
+
if (!trimmed)
|
|
52
|
+
throw new Error("Pi package source is required");
|
|
53
|
+
if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
|
|
54
|
+
let url;
|
|
55
|
+
try {
|
|
56
|
+
url = new URL(trimmed);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
throw new Error("Invalid Pi package URL");
|
|
60
|
+
}
|
|
61
|
+
if (url.origin !== "https://pi.dev" || !url.pathname.startsWith("/packages/")) {
|
|
62
|
+
throw new Error("Unsupported Pi package URL.\nExpected a URL starting with https://pi.dev/packages/ or a local path.");
|
|
63
|
+
}
|
|
64
|
+
const encodedName = url.pathname.slice("/packages/".length);
|
|
65
|
+
if (!encodedName) {
|
|
66
|
+
throw new Error("Pi package URL must point to a package detail page, for example https://pi.dev/packages/pi-web-access");
|
|
67
|
+
}
|
|
68
|
+
const packageName = decodeURIComponent(encodedName).replace(/\/+$/, "");
|
|
69
|
+
validatePackageName(packageName);
|
|
70
|
+
return {
|
|
71
|
+
kind: "npm",
|
|
72
|
+
name: packageName,
|
|
73
|
+
packageName,
|
|
74
|
+
source: `https://pi.dev/packages/${packageName}`,
|
|
75
|
+
installSpec: `npm:${packageName}`,
|
|
76
|
+
diagnostics: [],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const path = resolve(cwd, trimmed);
|
|
80
|
+
if (!existsSync(path))
|
|
81
|
+
throw new Error(`Local Pi package path does not exist: ${path}`);
|
|
82
|
+
const stats = statSync(path);
|
|
83
|
+
const name = stats.isFile() ? basename(path, extname(path)) : basename(path);
|
|
84
|
+
return {
|
|
85
|
+
kind: "local",
|
|
86
|
+
name,
|
|
87
|
+
path,
|
|
88
|
+
source: path,
|
|
89
|
+
installSpec: path,
|
|
90
|
+
diagnostics: [],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async function readNpmMetadata(packageName, diagnostics) {
|
|
94
|
+
try {
|
|
95
|
+
const { stdout } = await execFileAsync("npm", ["view", packageName, "--json"], {
|
|
96
|
+
timeout: 20000,
|
|
97
|
+
maxBuffer: 1024 * 1024,
|
|
98
|
+
});
|
|
99
|
+
const parsed = JSON.parse(stdout);
|
|
100
|
+
return normalizePackageJson(parsed);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
diagnostics.push({
|
|
104
|
+
type: "warning",
|
|
105
|
+
message: `Could not read npm metadata for ${packageName}: ${error instanceof Error ? error.message : String(error)}`,
|
|
106
|
+
});
|
|
107
|
+
return { name: packageName };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function readLocalMetadata(path, diagnostics) {
|
|
111
|
+
const stats = statSync(path);
|
|
112
|
+
if (stats.isFile()) {
|
|
113
|
+
return {
|
|
114
|
+
name: basename(path, extname(path)),
|
|
115
|
+
pi: { extensions: [path] },
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const packageJsonPath = resolve(path, "package.json");
|
|
119
|
+
if (!existsSync(packageJsonPath)) {
|
|
120
|
+
diagnostics.push({ type: "info", message: "Local directory has no package.json; Pi package conventions will be used." });
|
|
121
|
+
return { name: basename(path) };
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
return normalizePackageJson(JSON.parse(readFileSync(packageJsonPath, "utf-8")));
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
diagnostics.push({
|
|
128
|
+
type: "warning",
|
|
129
|
+
message: `Could not read local package.json: ${error instanceof Error ? error.message : String(error)}`,
|
|
130
|
+
});
|
|
131
|
+
return { name: basename(path) };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function resolvePackageResources(resourceSource, cwd, diagnostics) {
|
|
135
|
+
const packageManager = new DefaultPackageManager({
|
|
136
|
+
cwd,
|
|
137
|
+
agentDir: getAgentDir(),
|
|
138
|
+
settingsManager: SettingsManager.create(cwd, getAgentDir()),
|
|
139
|
+
});
|
|
140
|
+
try {
|
|
141
|
+
return await packageManager.resolveExtensionSources([resourceSource], { temporary: true });
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
diagnostics.push({
|
|
145
|
+
type: "error",
|
|
146
|
+
message: `Could not resolve Pi package resources: ${error instanceof Error ? error.message : String(error)}`,
|
|
147
|
+
});
|
|
148
|
+
return emptyResolvedPaths();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function validatePackageName(packageName) {
|
|
152
|
+
if (!packageName)
|
|
153
|
+
throw new Error("Pi package URL must include a package name");
|
|
154
|
+
const parts = packageName.split("/");
|
|
155
|
+
if (packageName.startsWith("@")) {
|
|
156
|
+
if (parts.length !== 2 || !parts[0].slice(1) || !parts[1]) {
|
|
157
|
+
throw new Error("Scoped Pi package URLs must look like https://pi.dev/packages/@scope/package-name");
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (parts.length !== 1 || !parts[0]) {
|
|
162
|
+
throw new Error("Pi package URL must include a single package name or scoped package name");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function normalizePackageJson(value) {
|
|
166
|
+
const candidate = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
167
|
+
return {
|
|
168
|
+
name: stringField(candidate.name),
|
|
169
|
+
version: stringField(candidate.version),
|
|
170
|
+
description: stringField(candidate.description),
|
|
171
|
+
repository: candidate.repository,
|
|
172
|
+
pi: candidate.pi,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function mergePackageMetadata(primary, fallback, defaultName) {
|
|
176
|
+
return {
|
|
177
|
+
name: fallback.name ?? primary.name ?? defaultName,
|
|
178
|
+
version: fallback.version ?? primary.version,
|
|
179
|
+
description: fallback.description ?? primary.description,
|
|
180
|
+
repository: fallback.repository ?? primary.repository,
|
|
181
|
+
pi: fallback.pi ?? primary.pi,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function emptyResolvedPaths() {
|
|
185
|
+
return { extensions: [], skills: [], prompts: [], themes: [] };
|
|
186
|
+
}
|
|
187
|
+
function stringField(value) {
|
|
188
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
189
|
+
}
|
|
190
|
+
function repositoryUrl(value) {
|
|
191
|
+
if (typeof value === "string")
|
|
192
|
+
return value;
|
|
193
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
194
|
+
const url = value.url;
|
|
195
|
+
return typeof url === "string" ? url : undefined;
|
|
196
|
+
}
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
function resourceTypesFromManifest(value) {
|
|
200
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
201
|
+
return [];
|
|
202
|
+
const manifest = value;
|
|
203
|
+
const pairs = [
|
|
204
|
+
["extensions", "extension"],
|
|
205
|
+
["skills", "skill"],
|
|
206
|
+
["prompts", "prompt"],
|
|
207
|
+
["themes", "theme"],
|
|
208
|
+
];
|
|
209
|
+
return pairs.flatMap(([key, type]) => Array.isArray(manifest[key]) && manifest[key].length > 0 ? [type] : []);
|
|
210
|
+
}
|
|
211
|
+
function resourceTypesFromResolvedPaths(paths) {
|
|
212
|
+
return [
|
|
213
|
+
...(paths.extensions.length ? ["extension"] : []),
|
|
214
|
+
...(paths.skills.length ? ["skill"] : []),
|
|
215
|
+
...(paths.prompts.length ? ["prompt"] : []),
|
|
216
|
+
...(paths.themes.length ? ["theme"] : []),
|
|
217
|
+
];
|
|
218
|
+
}
|
|
219
|
+
function mergeResourceTypes(...groups) {
|
|
220
|
+
const order = ["extension", "skill", "prompt", "theme"];
|
|
221
|
+
const selected = new Set(groups.flat());
|
|
222
|
+
return order.filter((type) => selected.has(type));
|
|
223
|
+
}
|
|
224
|
+
function pathsOrUndefined(resources) {
|
|
225
|
+
const paths = [...new Set(resources.map((resource) => resource.path))];
|
|
226
|
+
return paths.length ? paths : undefined;
|
|
227
|
+
}
|
|
228
|
+
function namesOrUndefined(resources) {
|
|
229
|
+
const names = [...new Set(resources.map((resource) => basename(resource.path).replace(/\.[^.]+$/, "")))];
|
|
230
|
+
return names.length ? names : undefined;
|
|
231
|
+
}
|