@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.
Files changed (351) hide show
  1. package/.codex/skills/pi-agent-harness/SKILL.md +319 -0
  2. package/.codex/skills/pi-agent-harness/agents/openai.yaml +4 -0
  3. package/README.md +318 -0
  4. package/context/codex-base-prompt.md +144 -0
  5. package/context/pibo-compaction-prompt.md +100 -0
  6. package/context/pibo-system-prompt.md +17 -0
  7. package/dist/apps/chat/agent-profiles.js +26 -0
  8. package/dist/apps/chat/agent-store.js +336 -0
  9. package/dist/apps/chat/event-log.js +307 -0
  10. package/dist/apps/chat/read-model.js +218 -0
  11. package/dist/apps/chat/rooms.js +321 -0
  12. package/dist/apps/chat/session-metadata.js +14 -0
  13. package/dist/apps/chat/stream.js +122 -0
  14. package/dist/apps/chat/trace.js +1182 -0
  15. package/dist/apps/chat/web-app.js +2569 -0
  16. package/dist/apps/chat-ui/assets/apl-BxEMbctQ.js +1 -0
  17. package/dist/apps/chat-ui/assets/asciiarmor-eFjeGRuZ.js +1 -0
  18. package/dist/apps/chat-ui/assets/asn1-Cfx-0pt9.js +1 -0
  19. package/dist/apps/chat-ui/assets/asterisk-B5BHTsBr.js +1 -0
  20. package/dist/apps/chat-ui/assets/brainfuck-CAA2xofr.js +1 -0
  21. package/dist/apps/chat-ui/assets/clike-BoDCOLzN.js +1 -0
  22. package/dist/apps/chat-ui/assets/clojure-kVFSWX0o.js +1 -0
  23. package/dist/apps/chat-ui/assets/cmake-BUPAhezI.js +1 -0
  24. package/dist/apps/chat-ui/assets/cobol-BfgHZgup.js +1 -0
  25. package/dist/apps/chat-ui/assets/coffeescript-G1Pe_1AZ.js +1 -0
  26. package/dist/apps/chat-ui/assets/commonlisp-B3N0CjHn.js +1 -0
  27. package/dist/apps/chat-ui/assets/crystal-C15ndaGM.js +1 -0
  28. package/dist/apps/chat-ui/assets/css-BqOeyZOV.js +1 -0
  29. package/dist/apps/chat-ui/assets/cypher-KjIKv-wW.js +1 -0
  30. package/dist/apps/chat-ui/assets/d-BlT5AEC-.js +1 -0
  31. package/dist/apps/chat-ui/assets/diff-oF98tbqj.js +1 -0
  32. package/dist/apps/chat-ui/assets/dist--55mTWk3.js +1 -0
  33. package/dist/apps/chat-ui/assets/dist-B5rcjVCj.js +1 -0
  34. package/dist/apps/chat-ui/assets/dist-BPv5MdlL.js +1 -0
  35. package/dist/apps/chat-ui/assets/dist-BZ39rB1W.js +1 -0
  36. package/dist/apps/chat-ui/assets/dist-BsedZGJo.js +1 -0
  37. package/dist/apps/chat-ui/assets/dist-BvO6SpaM.js +9 -0
  38. package/dist/apps/chat-ui/assets/dist-C5YJOwhH.js +1 -0
  39. package/dist/apps/chat-ui/assets/dist-C5oXtFSP.js +1 -0
  40. package/dist/apps/chat-ui/assets/dist-CG_gRSwv.js +23 -0
  41. package/dist/apps/chat-ui/assets/dist-CKM5j-iy.js +1 -0
  42. package/dist/apps/chat-ui/assets/dist-CUp9us2q.js +1 -0
  43. package/dist/apps/chat-ui/assets/dist-CZ9T4Cly.js +1 -0
  44. package/dist/apps/chat-ui/assets/dist-D4HhiFWB.js +6 -0
  45. package/dist/apps/chat-ui/assets/dist-DHE-yBLH.js +1 -0
  46. package/dist/apps/chat-ui/assets/dist-DSKQpPaz.js +1 -0
  47. package/dist/apps/chat-ui/assets/dist-L1B-KWZO.js +1 -0
  48. package/dist/apps/chat-ui/assets/dist-SVPsM5Oi.js +13 -0
  49. package/dist/apps/chat-ui/assets/dist-Zqt9kNG9.js +1 -0
  50. package/dist/apps/chat-ui/assets/dist-_DPv0-QF.js +1 -0
  51. package/dist/apps/chat-ui/assets/dist-_oM7g0eh.js +11 -0
  52. package/dist/apps/chat-ui/assets/dist-laadbMWg.js +1 -0
  53. package/dist/apps/chat-ui/assets/dist-nFui3f-r.js +2 -0
  54. package/dist/apps/chat-ui/assets/dist-tGfufz3b.js +1 -0
  55. package/dist/apps/chat-ui/assets/dockerfile-CUaqzcqp.js +1 -0
  56. package/dist/apps/chat-ui/assets/dtd-VCA9yr61.js +1 -0
  57. package/dist/apps/chat-ui/assets/dylan-O-V5Dw5W.js +1 -0
  58. package/dist/apps/chat-ui/assets/ebnf-SPmdBkvT.js +1 -0
  59. package/dist/apps/chat-ui/assets/ecl-ChfCttfI.js +1 -0
  60. package/dist/apps/chat-ui/assets/eiffel-cB9EbjeN.js +1 -0
  61. package/dist/apps/chat-ui/assets/elm-BTiVflBU.js +1 -0
  62. package/dist/apps/chat-ui/assets/erlang-egf0TXFm.js +1 -0
  63. package/dist/apps/chat-ui/assets/factor-C2tAxNob.js +1 -0
  64. package/dist/apps/chat-ui/assets/fcl-BiCjh1tj.js +1 -0
  65. package/dist/apps/chat-ui/assets/forth-C4kDGW6u.js +1 -0
  66. package/dist/apps/chat-ui/assets/fortran-DzkLaPnd.js +1 -0
  67. package/dist/apps/chat-ui/assets/gas-DMOxskQF.js +1 -0
  68. package/dist/apps/chat-ui/assets/gherkin-BPxBpp-k.js +1 -0
  69. package/dist/apps/chat-ui/assets/groovy-CkEnc0ZY.js +1 -0
  70. package/dist/apps/chat-ui/assets/haskell-Dadpo9-w.js +1 -0
  71. package/dist/apps/chat-ui/assets/haxe-CDNZL9MW.js +1 -0
  72. package/dist/apps/chat-ui/assets/http-jy9Zxxt3.js +1 -0
  73. package/dist/apps/chat-ui/assets/idl-CGSB6iiy.js +1 -0
  74. package/dist/apps/chat-ui/assets/index-BdcqTugD.js +151 -0
  75. package/dist/apps/chat-ui/assets/index-Dk-opWl3.css +1 -0
  76. package/dist/apps/chat-ui/assets/javascript-DSlzRUd8.js +1 -0
  77. package/dist/apps/chat-ui/assets/julia-DTiF9v6R.js +1 -0
  78. package/dist/apps/chat-ui/assets/livescript-Ci8Xxna6.js +1 -0
  79. package/dist/apps/chat-ui/assets/lua-eVxIrt9t.js +1 -0
  80. package/dist/apps/chat-ui/assets/mathematica-Da3grj36.js +1 -0
  81. package/dist/apps/chat-ui/assets/mbox-BWBMSafM.js +1 -0
  82. package/dist/apps/chat-ui/assets/mirc-CtHu9S1B.js +1 -0
  83. package/dist/apps/chat-ui/assets/mllike-wTFlPWXS.js +1 -0
  84. package/dist/apps/chat-ui/assets/modelica-cKbQ0UXu.js +1 -0
  85. package/dist/apps/chat-ui/assets/mscgen-C5pXQCMK.js +1 -0
  86. package/dist/apps/chat-ui/assets/mumps-CKBHkOQq.js +1 -0
  87. package/dist/apps/chat-ui/assets/nginx-B00AiQel.js +1 -0
  88. package/dist/apps/chat-ui/assets/nsis-SMDwKltR.js +1 -0
  89. package/dist/apps/chat-ui/assets/ntriples-B_36EBV0.js +1 -0
  90. package/dist/apps/chat-ui/assets/octave-BXPjzAif.js +1 -0
  91. package/dist/apps/chat-ui/assets/oz-Dedpat1M.js +1 -0
  92. package/dist/apps/chat-ui/assets/pascal-CMcUg72K.js +1 -0
  93. package/dist/apps/chat-ui/assets/perl-DoVTbnzt.js +1 -0
  94. package/dist/apps/chat-ui/assets/pig-CULXT1YV.js +1 -0
  95. package/dist/apps/chat-ui/assets/powershell-Cv5Uhf6b.js +1 -0
  96. package/dist/apps/chat-ui/assets/properties-CQ1C2P-M.js +1 -0
  97. package/dist/apps/chat-ui/assets/protobuf-SRlvzrl6.js +1 -0
  98. package/dist/apps/chat-ui/assets/pug-Bo3wfL-f.js +1 -0
  99. package/dist/apps/chat-ui/assets/puppet-ClSqCGj6.js +1 -0
  100. package/dist/apps/chat-ui/assets/python-C2_X1GpX.js +1 -0
  101. package/dist/apps/chat-ui/assets/q-B_6Gdyzl.js +1 -0
  102. package/dist/apps/chat-ui/assets/r-BD07NGED.js +1 -0
  103. package/dist/apps/chat-ui/assets/rolldown-runtime-S-ySWqyJ.js +1 -0
  104. package/dist/apps/chat-ui/assets/rpm-CRu5Z2Jl.js +1 -0
  105. package/dist/apps/chat-ui/assets/ruby-dZPnOz8h.js +1 -0
  106. package/dist/apps/chat-ui/assets/sas-S2t8_sDI.js +1 -0
  107. package/dist/apps/chat-ui/assets/scheme-WcyFWLW2.js +1 -0
  108. package/dist/apps/chat-ui/assets/shell-DUelnYSh.js +1 -0
  109. package/dist/apps/chat-ui/assets/sieve-jDjlVhNh.js +1 -0
  110. package/dist/apps/chat-ui/assets/simple-mode-CL04yRVp.js +1 -0
  111. package/dist/apps/chat-ui/assets/smalltalk-ddWDYy10.js +1 -0
  112. package/dist/apps/chat-ui/assets/solr-C7rQhLuW.js +1 -0
  113. package/dist/apps/chat-ui/assets/sparql--fPCCgVd.js +1 -0
  114. package/dist/apps/chat-ui/assets/spreadsheet-DjthqD5G.js +1 -0
  115. package/dist/apps/chat-ui/assets/sql-D_dieYbr.js +1 -0
  116. package/dist/apps/chat-ui/assets/stex-rHcFYcA0.js +1 -0
  117. package/dist/apps/chat-ui/assets/stylus-DxF70RNr.js +1 -0
  118. package/dist/apps/chat-ui/assets/swift-T0hDoOb-.js +1 -0
  119. package/dist/apps/chat-ui/assets/tcl-Dlzy1mPk.js +1 -0
  120. package/dist/apps/chat-ui/assets/textile-Dy5rFZe5.js +1 -0
  121. package/dist/apps/chat-ui/assets/tiddlywiki-DQP1OymS.js +1 -0
  122. package/dist/apps/chat-ui/assets/tiki-0vOj3DB2.js +1 -0
  123. package/dist/apps/chat-ui/assets/toml-DEltN0lI.js +1 -0
  124. package/dist/apps/chat-ui/assets/troff-CRbBpEqY.js +1 -0
  125. package/dist/apps/chat-ui/assets/ttcn-M5q1nLKg.js +1 -0
  126. package/dist/apps/chat-ui/assets/ttcn-cfg-Rmw9NWq9.js +1 -0
  127. package/dist/apps/chat-ui/assets/turtle-BCDWhJK0.js +1 -0
  128. package/dist/apps/chat-ui/assets/vb-QQ7LGlOz.js +1 -0
  129. package/dist/apps/chat-ui/assets/vbscript-BiSEdUzz.js +1 -0
  130. package/dist/apps/chat-ui/assets/velocity-CzMg5_6w.js +1 -0
  131. package/dist/apps/chat-ui/assets/verilog-BJOO83gk.js +1 -0
  132. package/dist/apps/chat-ui/assets/vhdl-ed4zAZAA.js +1 -0
  133. package/dist/apps/chat-ui/assets/webidl-Ddy6hbV6.js +1 -0
  134. package/dist/apps/chat-ui/assets/xquery-Bw1zwhh6.js +1 -0
  135. package/dist/apps/chat-ui/assets/yacas-DZdTXy3s.js +1 -0
  136. package/dist/apps/chat-ui/assets/z80-DMG02_YV.js +1 -0
  137. package/dist/apps/chat-ui/index.html +15 -0
  138. package/dist/apps/context-files-ui/assets/apl-14BqhLYK.js +1 -0
  139. package/dist/apps/context-files-ui/assets/asciiarmor-WLvjqI7d.js +1 -0
  140. package/dist/apps/context-files-ui/assets/asn1-Bg4FbdCg.js +1 -0
  141. package/dist/apps/context-files-ui/assets/asterisk-B2MO-X4d.js +1 -0
  142. package/dist/apps/context-files-ui/assets/brainfuck-CV9kufud.js +1 -0
  143. package/dist/apps/context-files-ui/assets/clike-CjmcUpt6.js +1 -0
  144. package/dist/apps/context-files-ui/assets/clojure-De3QGfx6.js +1 -0
  145. package/dist/apps/context-files-ui/assets/cmake-i2VDNaRq.js +1 -0
  146. package/dist/apps/context-files-ui/assets/cobol-BwO6DF08.js +1 -0
  147. package/dist/apps/context-files-ui/assets/coffeescript-BtivDvRz.js +1 -0
  148. package/dist/apps/context-files-ui/assets/commonlisp-DFkEQdLP.js +1 -0
  149. package/dist/apps/context-files-ui/assets/crystal-CU0NkcVL.js +1 -0
  150. package/dist/apps/context-files-ui/assets/css-CbMZAQ1W.js +1 -0
  151. package/dist/apps/context-files-ui/assets/cypher-Dke5QOzv.js +1 -0
  152. package/dist/apps/context-files-ui/assets/d-TPqSVaHM.js +1 -0
  153. package/dist/apps/context-files-ui/assets/diff-B365LSoZ.js +1 -0
  154. package/dist/apps/context-files-ui/assets/dist-B5PTVnox.js +1 -0
  155. package/dist/apps/context-files-ui/assets/dist-B5ZAfwf5.js +1 -0
  156. package/dist/apps/context-files-ui/assets/dist-BJW3917N.js +11 -0
  157. package/dist/apps/context-files-ui/assets/dist-BkUONE3N.js +1 -0
  158. package/dist/apps/context-files-ui/assets/dist-CKQF1zEu.js +1 -0
  159. package/dist/apps/context-files-ui/assets/dist-CwbH_3RN.js +1 -0
  160. package/dist/apps/context-files-ui/assets/dist-CxRLRmMx.js +2 -0
  161. package/dist/apps/context-files-ui/assets/dist-D1KyNDg5.js +13 -0
  162. package/dist/apps/context-files-ui/assets/dist-DFi2YGux.js +1 -0
  163. package/dist/apps/context-files-ui/assets/dist-DKoyMSNr.js +1 -0
  164. package/dist/apps/context-files-ui/assets/dist-DLMjd26T.js +1 -0
  165. package/dist/apps/context-files-ui/assets/dist-DQXzt2Ng.js +1 -0
  166. package/dist/apps/context-files-ui/assets/dist-DotDq_kD.js +1 -0
  167. package/dist/apps/context-files-ui/assets/dist-DyfSeBMu.js +1 -0
  168. package/dist/apps/context-files-ui/assets/dist-MyZgX9K2.js +9 -0
  169. package/dist/apps/context-files-ui/assets/dist-QQuDy4KA.js +1 -0
  170. package/dist/apps/context-files-ui/assets/dist-YwR9dpb-.js +1 -0
  171. package/dist/apps/context-files-ui/assets/dist-dTBsFYAl.js +1 -0
  172. package/dist/apps/context-files-ui/assets/dockerfile-CJb2sekW.js +1 -0
  173. package/dist/apps/context-files-ui/assets/dtd-CBMymJ7O.js +1 -0
  174. package/dist/apps/context-files-ui/assets/dylan-08Azy1NK.js +1 -0
  175. package/dist/apps/context-files-ui/assets/ebnf-Dkum_1J8.js +1 -0
  176. package/dist/apps/context-files-ui/assets/ecl-dhxjHL8y.js +1 -0
  177. package/dist/apps/context-files-ui/assets/eiffel-C446m6dI.js +1 -0
  178. package/dist/apps/context-files-ui/assets/elm-po1E9de0.js +1 -0
  179. package/dist/apps/context-files-ui/assets/erlang-BD5LkVkR.js +1 -0
  180. package/dist/apps/context-files-ui/assets/factor-B2EMQZkP.js +1 -0
  181. package/dist/apps/context-files-ui/assets/fcl-DkEOamHd.js +1 -0
  182. package/dist/apps/context-files-ui/assets/forth-dCg2_HVB.js +1 -0
  183. package/dist/apps/context-files-ui/assets/fortran-3ZpXLFh1.js +1 -0
  184. package/dist/apps/context-files-ui/assets/gas-DMmxLZRI.js +1 -0
  185. package/dist/apps/context-files-ui/assets/gherkin-DUSFg2R6.js +1 -0
  186. package/dist/apps/context-files-ui/assets/groovy-Cmduloe1.js +1 -0
  187. package/dist/apps/context-files-ui/assets/haskell-Cyr255R9.js +1 -0
  188. package/dist/apps/context-files-ui/assets/haxe-BJVKtprM.js +1 -0
  189. package/dist/apps/context-files-ui/assets/http-DszHFpc-.js +1 -0
  190. package/dist/apps/context-files-ui/assets/idl-Cati9Nrv.js +1 -0
  191. package/dist/apps/context-files-ui/assets/index-BwRDoHMC.css +1 -0
  192. package/dist/apps/context-files-ui/assets/index-GwvjXytt.js +202 -0
  193. package/dist/apps/context-files-ui/assets/javascript-C5pDVaoP.js +1 -0
  194. package/dist/apps/context-files-ui/assets/julia-DlqY1cTU.js +1 -0
  195. package/dist/apps/context-files-ui/assets/livescript-C6p8-2W1.js +1 -0
  196. package/dist/apps/context-files-ui/assets/lua-BxuTHaF7.js +1 -0
  197. package/dist/apps/context-files-ui/assets/mathematica-nDHZUMJT.js +1 -0
  198. package/dist/apps/context-files-ui/assets/mbox-DAaR0Hcz.js +1 -0
  199. package/dist/apps/context-files-ui/assets/mirc-CCA0FRfl.js +1 -0
  200. package/dist/apps/context-files-ui/assets/mllike-Cw3Iccsb.js +1 -0
  201. package/dist/apps/context-files-ui/assets/modelica-Czx80fNR.js +1 -0
  202. package/dist/apps/context-files-ui/assets/mscgen-BmfuTbzG.js +1 -0
  203. package/dist/apps/context-files-ui/assets/mumps-Ds_ZaumL.js +1 -0
  204. package/dist/apps/context-files-ui/assets/nginx-D9M2PQ4U.js +1 -0
  205. package/dist/apps/context-files-ui/assets/nsis-DOo3SJmd.js +1 -0
  206. package/dist/apps/context-files-ui/assets/ntriples-DLHGTvHs.js +1 -0
  207. package/dist/apps/context-files-ui/assets/octave-8jj96JiC.js +1 -0
  208. package/dist/apps/context-files-ui/assets/oz-BmMq7iC4.js +1 -0
  209. package/dist/apps/context-files-ui/assets/pascal-BgMr6XpT.js +1 -0
  210. package/dist/apps/context-files-ui/assets/perl-D6YJObi_.js +1 -0
  211. package/dist/apps/context-files-ui/assets/pig-nx7uchs8.js +1 -0
  212. package/dist/apps/context-files-ui/assets/powershell-B4IPkVxR.js +1 -0
  213. package/dist/apps/context-files-ui/assets/properties-CoavQdLC.js +1 -0
  214. package/dist/apps/context-files-ui/assets/protobuf-D5EWhcmc.js +1 -0
  215. package/dist/apps/context-files-ui/assets/pug-QU72BPAa.js +1 -0
  216. package/dist/apps/context-files-ui/assets/puppet-B_0GFuyD.js +1 -0
  217. package/dist/apps/context-files-ui/assets/python-Cs7sNzy_.js +1 -0
  218. package/dist/apps/context-files-ui/assets/q-BIB9pPtI.js +1 -0
  219. package/dist/apps/context-files-ui/assets/r-CN5s4f3o.js +1 -0
  220. package/dist/apps/context-files-ui/assets/rpm-Ct_Ck8mQ.js +1 -0
  221. package/dist/apps/context-files-ui/assets/ruby-BVPradRk.js +1 -0
  222. package/dist/apps/context-files-ui/assets/sas-DN4j74IF.js +1 -0
  223. package/dist/apps/context-files-ui/assets/scheme-CvNgHAnh.js +1 -0
  224. package/dist/apps/context-files-ui/assets/shell-BjiMLAaM.js +1 -0
  225. package/dist/apps/context-files-ui/assets/sieve-C2U1O5Z4.js +1 -0
  226. package/dist/apps/context-files-ui/assets/simple-mode-DnMbQuKW.js +1 -0
  227. package/dist/apps/context-files-ui/assets/smalltalk-DkYwYufV.js +1 -0
  228. package/dist/apps/context-files-ui/assets/solr-BopnSD-v.js +1 -0
  229. package/dist/apps/context-files-ui/assets/sparql-Cpg3YQfd.js +1 -0
  230. package/dist/apps/context-files-ui/assets/spreadsheet-kRxtVt9J.js +1 -0
  231. package/dist/apps/context-files-ui/assets/sql-DYI2GwJR.js +1 -0
  232. package/dist/apps/context-files-ui/assets/stex-BCRT8IJ3.js +1 -0
  233. package/dist/apps/context-files-ui/assets/stylus-CARoeVE9.js +1 -0
  234. package/dist/apps/context-files-ui/assets/swift-DKNaLAK6.js +1 -0
  235. package/dist/apps/context-files-ui/assets/tcl-CQyXkgMH.js +1 -0
  236. package/dist/apps/context-files-ui/assets/textile-Yg_UWn-t.js +1 -0
  237. package/dist/apps/context-files-ui/assets/tiddlywiki-dqVbkfX4.js +1 -0
  238. package/dist/apps/context-files-ui/assets/tiki-CC_ic8g0.js +1 -0
  239. package/dist/apps/context-files-ui/assets/toml-B7gGzVkJ.js +1 -0
  240. package/dist/apps/context-files-ui/assets/troff-Bq3z6oAu.js +1 -0
  241. package/dist/apps/context-files-ui/assets/ttcn-GvRgs2AT.js +1 -0
  242. package/dist/apps/context-files-ui/assets/ttcn-cfg-CGCXz7Vo.js +1 -0
  243. package/dist/apps/context-files-ui/assets/turtle-CwIpz2yy.js +1 -0
  244. package/dist/apps/context-files-ui/assets/vb-BmcHUM2C.js +1 -0
  245. package/dist/apps/context-files-ui/assets/vbscript-Cs9dylre.js +1 -0
  246. package/dist/apps/context-files-ui/assets/velocity-CBWU0VCy.js +1 -0
  247. package/dist/apps/context-files-ui/assets/verilog-DVCHmufx.js +1 -0
  248. package/dist/apps/context-files-ui/assets/vhdl-BGDk4f1d.js +1 -0
  249. package/dist/apps/context-files-ui/assets/webidl-egXQEWlC.js +1 -0
  250. package/dist/apps/context-files-ui/assets/xquery-5f0hn7cg.js +1 -0
  251. package/dist/apps/context-files-ui/assets/yacas-DNs9XkmQ.js +1 -0
  252. package/dist/apps/context-files-ui/assets/z80-B7Dfb4UO.js +1 -0
  253. package/dist/apps/context-files-ui/index.html +14 -0
  254. package/dist/auth/better-auth.js +129 -0
  255. package/dist/auth/types.js +14 -0
  256. package/dist/bin/pibo.js +3 -0
  257. package/dist/channels/types.js +1 -0
  258. package/dist/cli-errors.js +18 -0
  259. package/dist/cli.js +264 -0
  260. package/dist/config/config.js +167 -0
  261. package/dist/core/base-prompt.js +104 -0
  262. package/dist/core/codex-compat.js +44 -0
  263. package/dist/core/compaction-prompt.js +258 -0
  264. package/dist/core/events.js +1 -0
  265. package/dist/core/profiles.js +138 -0
  266. package/dist/core/routed-session.js +538 -0
  267. package/dist/core/runtime.js +323 -0
  268. package/dist/core/session-router.js +437 -0
  269. package/dist/core/system-prompt-template.js +56 -0
  270. package/dist/core/thinking.js +9 -0
  271. package/dist/core/workspace.js +5 -0
  272. package/dist/debug/events.js +92 -0
  273. package/dist/debug/index.js +631 -0
  274. package/dist/debug/session.js +200 -0
  275. package/dist/debug/sql.js +238 -0
  276. package/dist/debug/stores.js +49 -0
  277. package/dist/debug/trace.js +245 -0
  278. package/dist/env.js +32 -0
  279. package/dist/gateway/client.js +200 -0
  280. package/dist/gateway/protocol.js +46 -0
  281. package/dist/gateway/request.js +146 -0
  282. package/dist/gateway/server.js +221 -0
  283. package/dist/gateway/tool.js +69 -0
  284. package/dist/gateway/web.js +80 -0
  285. package/dist/index.js +23 -0
  286. package/dist/local/client.js +77 -0
  287. package/dist/local/extension.js +548 -0
  288. package/dist/local/tui.js +25 -0
  289. package/dist/mcp/agent-context.js +123 -0
  290. package/dist/mcp/client.js +332 -0
  291. package/dist/mcp/commands/call.js +146 -0
  292. package/dist/mcp/commands/grep.js +145 -0
  293. package/dist/mcp/commands/info.js +71 -0
  294. package/dist/mcp/commands/list.js +94 -0
  295. package/dist/mcp/config-command.js +217 -0
  296. package/dist/mcp/config.js +440 -0
  297. package/dist/mcp/daemon-client.js +266 -0
  298. package/dist/mcp/daemon.js +327 -0
  299. package/dist/mcp/errors.js +287 -0
  300. package/dist/mcp/index.js +431 -0
  301. package/dist/mcp/output.js +171 -0
  302. package/dist/mcp/python-runtime.js +131 -0
  303. package/dist/mcp/registry.js +116 -0
  304. package/dist/mcp/version.js +5 -0
  305. package/dist/pi-packages/cli.js +92 -0
  306. package/dist/pi-packages/installer.js +70 -0
  307. package/dist/pi-packages/metadata.js +231 -0
  308. package/dist/pi-packages/runtime.js +61 -0
  309. package/dist/pi-packages/store.js +175 -0
  310. package/dist/pi-packages/types.js +1 -0
  311. package/dist/plugins/better-auth.js +11 -0
  312. package/dist/plugins/builtin.js +249 -0
  313. package/dist/plugins/chat-web.js +11 -0
  314. package/dist/plugins/codex-compat.js +72 -0
  315. package/dist/plugins/context-files-store.js +354 -0
  316. package/dist/plugins/context-files.js +999 -0
  317. package/dist/plugins/core-tools.js +94 -0
  318. package/dist/plugins/example.js +67 -0
  319. package/dist/plugins/registry.js +368 -0
  320. package/dist/plugins/remote-agent.js +9 -0
  321. package/dist/plugins/types.js +1 -0
  322. package/dist/plugins/web.js +11 -0
  323. package/dist/reliability/store.js +759 -0
  324. package/dist/remote/channel.js +176 -0
  325. package/dist/remote/client.js +92 -0
  326. package/dist/remote/examples/tui-controller.js +263 -0
  327. package/dist/remote/protocol.js +55 -0
  328. package/dist/remote/session-client.js +189 -0
  329. package/dist/runs/registry.js +323 -0
  330. package/dist/runs/tools.js +185 -0
  331. package/dist/sessions/bindings.js +41 -0
  332. package/dist/sessions/sqlite-store.js +154 -0
  333. package/dist/sessions/store.js +125 -0
  334. package/dist/shared/trace-order.js +83 -0
  335. package/dist/subagents/tool.js +63 -0
  336. package/dist/tools/browser-use-cdp.js +207 -0
  337. package/dist/tools/browser-use-leases.js +338 -0
  338. package/dist/tools/browser-use-wrapper.js +338 -0
  339. package/dist/tools/codex-compat.js +85 -0
  340. package/dist/tools/desktop-env.js +90 -0
  341. package/dist/tools/guides.js +276 -0
  342. package/dist/tools/index.js +366 -0
  343. package/dist/tools/python-runtime.js +154 -0
  344. package/dist/tools/registry.js +107 -0
  345. package/dist/tools/web-search.js +137 -0
  346. package/dist/web/auth.js +10 -0
  347. package/dist/web/channel.js +151 -0
  348. package/dist/web/http.js +110 -0
  349. package/dist/web/types.js +1 -0
  350. package/package.json +74 -0
  351. package/src/mcp/LICENSE.mcp-cli +21 -0
@@ -0,0 +1,41 @@
1
+ import { randomUUID } from "node:crypto";
2
+ export function createPiboSessionId() {
3
+ return randomUUID();
4
+ }
5
+ export function createSessionBinding(input, now = new Date().toISOString()) {
6
+ return {
7
+ sessionKey: input.sessionKey ?? createDefaultSessionKey(input),
8
+ sessionId: input.sessionId ?? createPiboSessionId(),
9
+ parentSessionKey: input.parentSessionKey,
10
+ parentSessionId: input.parentSessionId,
11
+ channel: input.channel,
12
+ externalId: input.externalId,
13
+ originalProfile: input.defaultProfile,
14
+ workspace: input.workspace,
15
+ createdAt: now,
16
+ updatedAt: now,
17
+ };
18
+ }
19
+ export function createDefaultSessionKey(input) {
20
+ return `${input.channel}:${input.externalId}`;
21
+ }
22
+ export class InMemorySessionBindingStore {
23
+ bySessionKey = new Map();
24
+ byChannelExternalId = new Map();
25
+ get(sessionKey) {
26
+ return this.bySessionKey.get(sessionKey);
27
+ }
28
+ list() {
29
+ return [...this.bySessionKey.values()];
30
+ }
31
+ resolve(input) {
32
+ const channelExternalId = createDefaultSessionKey(input);
33
+ const existing = this.byChannelExternalId.get(channelExternalId);
34
+ if (existing)
35
+ return existing;
36
+ const binding = createSessionBinding(input);
37
+ this.bySessionKey.set(binding.sessionKey, binding);
38
+ this.byChannelExternalId.set(channelExternalId, binding);
39
+ return binding;
40
+ }
41
+ }
@@ -0,0 +1,154 @@
1
+ import { mkdirSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { DatabaseSync } from "node:sqlite";
4
+ import { createPiboSession, matchesFindInput, } from "./store.js";
5
+ export class SqlitePiboSessionStore {
6
+ db;
7
+ constructor(path) {
8
+ const resolvedPath = path === ":memory:" ? path : resolve(path);
9
+ if (resolvedPath !== ":memory:") {
10
+ mkdirSync(dirname(resolvedPath), { recursive: true });
11
+ }
12
+ this.db = new DatabaseSync(resolvedPath);
13
+ this.db.exec("PRAGMA busy_timeout = 5000");
14
+ if (resolvedPath !== ":memory:")
15
+ this.db.exec("PRAGMA journal_mode = WAL");
16
+ this.db.exec(`
17
+ CREATE TABLE IF NOT EXISTS pibo_sessions (
18
+ id TEXT PRIMARY KEY,
19
+ pi_session_id TEXT NOT NULL UNIQUE,
20
+ channel TEXT NOT NULL,
21
+ kind TEXT NOT NULL,
22
+ profile TEXT NOT NULL,
23
+ owner_scope TEXT,
24
+ parent_id TEXT,
25
+ origin_id TEXT,
26
+ workspace TEXT,
27
+ title TEXT,
28
+ metadata_json TEXT,
29
+ created_at TEXT NOT NULL,
30
+ updated_at TEXT NOT NULL,
31
+ FOREIGN KEY(parent_id) REFERENCES pibo_sessions(id),
32
+ FOREIGN KEY(origin_id) REFERENCES pibo_sessions(id)
33
+ );
34
+
35
+ CREATE INDEX IF NOT EXISTS idx_pibo_sessions_owner
36
+ ON pibo_sessions(owner_scope, updated_at);
37
+ CREATE INDEX IF NOT EXISTS idx_pibo_sessions_parent
38
+ ON pibo_sessions(parent_id, updated_at);
39
+ CREATE INDEX IF NOT EXISTS idx_pibo_sessions_origin
40
+ ON pibo_sessions(origin_id, updated_at);
41
+ CREATE INDEX IF NOT EXISTS idx_pibo_sessions_channel_kind
42
+ ON pibo_sessions(channel, kind, updated_at);
43
+ `);
44
+ }
45
+ get(id) {
46
+ const row = this.db.prepare("SELECT * FROM pibo_sessions WHERE id = ?").get(id);
47
+ return row ? sessionFromRow(row) : undefined;
48
+ }
49
+ list() {
50
+ return this.db.prepare("SELECT * FROM pibo_sessions ORDER BY updated_at DESC").all().map(sessionFromRow);
51
+ }
52
+ create(input) {
53
+ const session = createPiboSession(input);
54
+ this.db
55
+ .prepare(`
56
+ INSERT INTO pibo_sessions (
57
+ id,
58
+ pi_session_id,
59
+ channel,
60
+ kind,
61
+ profile,
62
+ owner_scope,
63
+ parent_id,
64
+ origin_id,
65
+ workspace,
66
+ title,
67
+ metadata_json,
68
+ created_at,
69
+ updated_at
70
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
71
+ `)
72
+ .run(session.id, session.piSessionId, session.channel, session.kind, session.profile, session.ownerScope ?? null, session.parentId ?? null, session.originId ?? null, session.workspace ?? null, session.title ?? null, JSON.stringify(session.metadata ?? {}), session.createdAt, session.updatedAt);
73
+ const created = this.get(session.id);
74
+ if (!created)
75
+ throw new Error(`Failed to create Pibo session "${session.id}"`);
76
+ return created;
77
+ }
78
+ update(id, input) {
79
+ const existing = this.get(id);
80
+ if (!existing)
81
+ return undefined;
82
+ const updated = {
83
+ ...existing,
84
+ piSessionId: input.piSessionId ?? existing.piSessionId,
85
+ profile: input.profile ?? existing.profile,
86
+ ownerScope: input.ownerScope ?? existing.ownerScope,
87
+ parentId: input.parentId === null ? undefined : input.parentId ?? existing.parentId,
88
+ originId: input.originId === null ? undefined : input.originId ?? existing.originId,
89
+ workspace: input.workspace === null ? undefined : input.workspace ?? existing.workspace,
90
+ title: input.title === null ? undefined : input.title ?? existing.title,
91
+ metadata: input.metadata ?? existing.metadata,
92
+ updatedAt: new Date().toISOString(),
93
+ };
94
+ this.db
95
+ .prepare(`
96
+ UPDATE pibo_sessions SET
97
+ pi_session_id = ?,
98
+ profile = ?,
99
+ owner_scope = ?,
100
+ parent_id = ?,
101
+ origin_id = ?,
102
+ workspace = ?,
103
+ title = ?,
104
+ metadata_json = ?,
105
+ updated_at = ?
106
+ WHERE id = ?
107
+ `)
108
+ .run(updated.piSessionId, updated.profile, updated.ownerScope ?? null, updated.parentId ?? null, updated.originId ?? null, updated.workspace ?? null, updated.title ?? null, JSON.stringify(updated.metadata ?? {}), updated.updatedAt, id);
109
+ return this.get(id);
110
+ }
111
+ delete(id) {
112
+ const result = this.db.prepare("DELETE FROM pibo_sessions WHERE id = ?").run(id);
113
+ return Number(result.changes ?? 0) > 0;
114
+ }
115
+ find(input) {
116
+ return this.list().filter((session) => matchesFindInput(session, input));
117
+ }
118
+ close() {
119
+ this.db.close();
120
+ }
121
+ }
122
+ export function createDefaultPiboSessionStore(cwd = process.cwd()) {
123
+ return new SqlitePiboSessionStore(resolve(cwd, ".pibo/pibo-sessions.sqlite"));
124
+ }
125
+ function sessionFromRow(row) {
126
+ return {
127
+ id: row.id,
128
+ piSessionId: row.pi_session_id,
129
+ channel: row.channel,
130
+ kind: row.kind,
131
+ profile: row.profile,
132
+ ownerScope: row.owner_scope ?? undefined,
133
+ parentId: row.parent_id ?? undefined,
134
+ originId: row.origin_id ?? undefined,
135
+ workspace: row.workspace ?? undefined,
136
+ title: row.title ?? undefined,
137
+ metadata: parseMetadata(row.metadata_json),
138
+ createdAt: row.created_at,
139
+ updatedAt: row.updated_at,
140
+ };
141
+ }
142
+ function parseMetadata(value) {
143
+ if (!value)
144
+ return {};
145
+ try {
146
+ const parsed = JSON.parse(value);
147
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
148
+ return {};
149
+ return parsed;
150
+ }
151
+ catch {
152
+ return {};
153
+ }
154
+ }
@@ -0,0 +1,125 @@
1
+ import { randomUUID } from "node:crypto";
2
+ export function createPiboSessionId() {
3
+ return `ps_${randomUUID()}`;
4
+ }
5
+ export function createPiSessionId() {
6
+ return randomUUID();
7
+ }
8
+ export function createPiboSession(input, now = new Date().toISOString()) {
9
+ return {
10
+ id: input.id ?? createPiboSessionId(),
11
+ piSessionId: input.piSessionId ?? createPiSessionId(),
12
+ channel: input.channel,
13
+ kind: input.kind,
14
+ profile: input.profile,
15
+ ownerScope: input.ownerScope,
16
+ parentId: input.parentId,
17
+ originId: input.originId,
18
+ workspace: input.workspace,
19
+ title: input.title,
20
+ metadata: input.metadata ?? {},
21
+ createdAt: now,
22
+ updatedAt: now,
23
+ };
24
+ }
25
+ export class InMemoryPiboSessionStore {
26
+ byId = new Map();
27
+ byPiSessionId = new Map();
28
+ get(id) {
29
+ return this.byId.get(id);
30
+ }
31
+ list() {
32
+ return this.sort([...this.byId.values()]);
33
+ }
34
+ create(input) {
35
+ const session = createPiboSession(input);
36
+ if (this.byId.has(session.id)) {
37
+ throw new Error(`Pibo session "${session.id}" already exists`);
38
+ }
39
+ if (this.byPiSessionId.has(session.piSessionId)) {
40
+ throw new Error(`Pi session "${session.piSessionId}" is already attached to a Pibo session`);
41
+ }
42
+ this.set(session);
43
+ return session;
44
+ }
45
+ update(id, input) {
46
+ const existing = this.byId.get(id);
47
+ if (!existing)
48
+ return undefined;
49
+ if (input.piSessionId && input.piSessionId !== existing.piSessionId) {
50
+ const attached = this.byPiSessionId.get(input.piSessionId);
51
+ if (attached && attached.id !== id) {
52
+ throw new Error(`Pi session "${input.piSessionId}" is already attached to Pibo session "${attached.id}"`);
53
+ }
54
+ }
55
+ const updated = {
56
+ ...existing,
57
+ piSessionId: input.piSessionId ?? existing.piSessionId,
58
+ profile: input.profile ?? existing.profile,
59
+ ownerScope: input.ownerScope ?? existing.ownerScope,
60
+ parentId: input.parentId === null ? undefined : input.parentId ?? existing.parentId,
61
+ originId: input.originId === null ? undefined : input.originId ?? existing.originId,
62
+ workspace: input.workspace === null ? undefined : input.workspace ?? existing.workspace,
63
+ title: input.title === null ? undefined : input.title ?? existing.title,
64
+ metadata: input.metadata ?? existing.metadata,
65
+ updatedAt: new Date().toISOString(),
66
+ };
67
+ this.set(updated, existing.piSessionId);
68
+ return updated;
69
+ }
70
+ delete(id) {
71
+ const existing = this.byId.get(id);
72
+ if (!existing)
73
+ return false;
74
+ this.byId.delete(id);
75
+ this.byPiSessionId.delete(existing.piSessionId);
76
+ return true;
77
+ }
78
+ find(input) {
79
+ return this.sort([...this.byId.values()].filter((session) => matchesFindInput(session, input)));
80
+ }
81
+ set(session, previousPiSessionId) {
82
+ this.byId.set(session.id, session);
83
+ if (previousPiSessionId && previousPiSessionId !== session.piSessionId) {
84
+ this.byPiSessionId.delete(previousPiSessionId);
85
+ }
86
+ this.byPiSessionId.set(session.piSessionId, session);
87
+ }
88
+ sort(sessions) {
89
+ return sessions.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
90
+ }
91
+ }
92
+ export function matchesFindInput(session, input) {
93
+ if (input.ids && !input.ids.includes(session.id))
94
+ return false;
95
+ if (input.channel !== undefined && session.channel !== input.channel)
96
+ return false;
97
+ if (input.kind !== undefined && session.kind !== input.kind)
98
+ return false;
99
+ if (input.ownerScope !== undefined && session.ownerScope !== input.ownerScope)
100
+ return false;
101
+ if (input.parentId !== undefined) {
102
+ if (input.parentId === null) {
103
+ if (session.parentId !== undefined)
104
+ return false;
105
+ }
106
+ else if (session.parentId !== input.parentId) {
107
+ return false;
108
+ }
109
+ }
110
+ if (input.originId !== undefined && session.originId !== input.originId)
111
+ return false;
112
+ if (input.profile !== undefined && session.profile !== input.profile)
113
+ return false;
114
+ if (input.metadata && !metadataMatches(session.metadata, input.metadata))
115
+ return false;
116
+ return true;
117
+ }
118
+ function metadataMatches(metadata, expected) {
119
+ const actual = metadata ?? {};
120
+ for (const [key, value] of Object.entries(expected)) {
121
+ if (JSON.stringify(actual[key]) !== JSON.stringify(value))
122
+ return false;
123
+ }
124
+ return true;
125
+ }
@@ -0,0 +1,83 @@
1
+ export const TRACE_SOURCE_RANK = {
2
+ transcript: 0,
3
+ "event-log": 1,
4
+ live: 2,
5
+ };
6
+ export const TRACE_PHASE_RANK = {
7
+ "user.message": 0,
8
+ "agent.turn": 1,
9
+ "model.reasoning": 2,
10
+ "tool.call": 3,
11
+ "agent.delegation": 3,
12
+ "agent.async": 4,
13
+ "tool.result": 5,
14
+ "execution.command": 6,
15
+ "yielded.run": 7,
16
+ "assistant.message": 8,
17
+ error: 9,
18
+ };
19
+ export function transcriptTraceOrder(transcriptIndex, contentPartIndex, type) {
20
+ return {
21
+ sourceRank: TRACE_SOURCE_RANK.transcript,
22
+ turnSeq: transcriptIndex,
23
+ transcriptIndex,
24
+ contentPartIndex,
25
+ phaseRank: TRACE_PHASE_RANK[type],
26
+ };
27
+ }
28
+ export function eventTraceOrder(eventSequence, type) {
29
+ return {
30
+ sourceRank: TRACE_SOURCE_RANK["event-log"],
31
+ turnSeq: eventSequence ?? Number.MAX_SAFE_INTEGER,
32
+ eventSequence,
33
+ phaseRank: TRACE_PHASE_RANK[type],
34
+ };
35
+ }
36
+ export function liveTraceOrder(streamId, streamFrameIndex, type) {
37
+ const streamOrder = streamId ?? Number.MAX_SAFE_INTEGER;
38
+ const frameIndex = streamFrameIndex ?? Number.MAX_SAFE_INTEGER;
39
+ return {
40
+ sourceRank: TRACE_SOURCE_RANK.live,
41
+ turnSeq: streamOrder,
42
+ streamId: streamOrder,
43
+ streamFrameIndex: frameIndex,
44
+ phaseRank: TRACE_PHASE_RANK[type],
45
+ };
46
+ }
47
+ export function parseTraceStreamFrameId(value) {
48
+ const [stream, frame] = value.split(":");
49
+ if (stream === undefined || frame === undefined)
50
+ return undefined;
51
+ const streamId = Number(stream);
52
+ const frameIndex = Number(frame);
53
+ if (!Number.isInteger(streamId) || streamId < 0)
54
+ return undefined;
55
+ if (!Number.isInteger(frameIndex) || frameIndex < 0)
56
+ return undefined;
57
+ return { streamId, frameIndex };
58
+ }
59
+ export function childTraceOrder(parent, type) {
60
+ if (!parent)
61
+ return undefined;
62
+ return {
63
+ ...parent,
64
+ contentPartIndex: (parent.contentPartIndex ?? 0) + 0.1,
65
+ phaseRank: TRACE_PHASE_RANK[type],
66
+ };
67
+ }
68
+ export function compareTraceOrder(left, right) {
69
+ if (!left && !right)
70
+ return 0;
71
+ if (!left)
72
+ return 1;
73
+ if (!right)
74
+ return -1;
75
+ return (left.turnSeq - right.turnSeq ||
76
+ (left.transcriptIndex ?? Number.MAX_SAFE_INTEGER) - (right.transcriptIndex ?? Number.MAX_SAFE_INTEGER) ||
77
+ (left.eventSequence ?? Number.MAX_SAFE_INTEGER) - (right.eventSequence ?? Number.MAX_SAFE_INTEGER) ||
78
+ (left.streamId ?? Number.MAX_SAFE_INTEGER) - (right.streamId ?? Number.MAX_SAFE_INTEGER) ||
79
+ (left.streamFrameIndex ?? Number.MAX_SAFE_INTEGER) - (right.streamFrameIndex ?? Number.MAX_SAFE_INTEGER) ||
80
+ (left.contentPartIndex ?? 0) - (right.contentPartIndex ?? 0) ||
81
+ left.phaseRank - right.phaseRank ||
82
+ left.sourceRank - right.sourceRank);
83
+ }
@@ -0,0 +1,63 @@
1
+ import { createHash } from "node:crypto";
2
+ import { Type } from "@mariozechner/pi-ai";
3
+ import { defineTool } from "@mariozechner/pi-coding-agent";
4
+ function hashPart(value) {
5
+ return createHash("sha256").update(value).digest("hex").slice(0, 12);
6
+ }
7
+ function toolNamePart(value) {
8
+ const normalized = value.trim().toLowerCase().replace(/[^a-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
9
+ return normalized || `subagent_${hashPart(value)}`;
10
+ }
11
+ export function createSubagentToolName(subagentName) {
12
+ return `pibo_subagent_${toolNamePart(subagentName)}`;
13
+ }
14
+ export function createSubagentToolDefinitions(subagents, runner) {
15
+ const seen = new Set();
16
+ const definitions = [];
17
+ for (const subagent of subagents) {
18
+ if (subagent.enabled === false)
19
+ continue;
20
+ const toolName = createSubagentToolName(subagent.name);
21
+ if (seen.has(toolName)) {
22
+ throw new Error(`Duplicate subagent tool name "${toolName}"`);
23
+ }
24
+ seen.add(toolName);
25
+ definitions.push(createSubagentToolDefinition(subagent, runner));
26
+ }
27
+ return definitions;
28
+ }
29
+ function createSubagentToolDefinition(subagent, runner) {
30
+ const name = createSubagentToolName(subagent.name);
31
+ return defineTool({
32
+ name,
33
+ label: `Pibo Subagent ${subagent.name}`,
34
+ description: subagent.description ??
35
+ `Send a message to the ${subagent.name} subagent. Use threadKey to continue the same subagent session.`,
36
+ promptSnippet: subagent.description ??
37
+ `Send a message to the ${subagent.name} subagent. Pass the same threadKey when you want to continue the same subagent session.`,
38
+ executionMode: "parallel",
39
+ parameters: Type.Object({
40
+ message: Type.String({ description: "Message to send to the subagent" }),
41
+ threadKey: Type.Optional(Type.String({
42
+ description: "Stable key for continuing a previous subagent conversation. Omit it to create a new subagent session.",
43
+ })),
44
+ }),
45
+ async execute(toolCallId, params) {
46
+ const result = await runner.runSubagent({
47
+ subagent,
48
+ message: params.message,
49
+ threadKey: params.threadKey,
50
+ toolCallId,
51
+ });
52
+ return {
53
+ content: [
54
+ {
55
+ type: "text",
56
+ text: result.reply.text,
57
+ },
58
+ ],
59
+ details: result,
60
+ };
61
+ },
62
+ });
63
+ }
@@ -0,0 +1,207 @@
1
+ const DEFAULT_CDP_URL = 'http://127.0.0.1:56663';
2
+ const DEFAULT_TIMEOUT_MS = 2500;
3
+ const CHAT_TARGET_PROBE = `(() => {
4
+ const text = String(document.body?.innerText || "");
5
+ const textareas = [...document.querySelectorAll("textarea")].map((textarea) => ({
6
+ placeholder: textarea.placeholder || "",
7
+ disabled: Boolean(textarea.disabled),
8
+ value: textarea.value || "",
9
+ }));
10
+ return {
11
+ title: document.title || "",
12
+ text: text.slice(0, 3000),
13
+ textareas,
14
+ };
15
+ })()`;
16
+ export async function listBrowserUseCdpTargets(options = {}) {
17
+ const cdpUrl = normalizeCdpUrl(options.cdpUrl);
18
+ const probe = options.probe !== false;
19
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
20
+ const targets = await fetchChromeTargets(cdpUrl, timeoutMs);
21
+ const rows = [];
22
+ for (const target of targets) {
23
+ const row = normalizeChromeTarget(target);
24
+ if (probe && row.url.includes('/apps/chat') && row.webSocketDebuggerUrl) {
25
+ rows.push(await probeChatTarget(row, timeoutMs));
26
+ }
27
+ else {
28
+ rows.push(row);
29
+ }
30
+ }
31
+ return rows;
32
+ }
33
+ export function selectBestChatTarget(targets) {
34
+ return targets
35
+ .filter((target) => target.url.includes('/apps/chat'))
36
+ .filter((target) => target.webSocketDebuggerUrl)
37
+ .filter((target) => target.auth !== 'unauthenticated')
38
+ .filter((target) => target.composer)
39
+ .sort((left, right) => scoreChatTarget(right) - scoreChatTarget(left))[0];
40
+ }
41
+ export function formatBrowserUseTargets(targets) {
42
+ const lines = ['id\turl\tauth\tcomposer\ttitle'];
43
+ for (const target of targets) {
44
+ const composer = target.composer ? 'yes' : 'no';
45
+ const title = target.probeError ? `${target.title} (${target.probeError})` : target.title;
46
+ lines.push(`${target.id}\t${target.url}\t${target.auth}\t${composer}\t${title}`);
47
+ }
48
+ return lines.join('\n');
49
+ }
50
+ export function printAttachChatExports(target, cdpUrl = DEFAULT_CDP_URL) {
51
+ console.log(`export PIBO_CDP_URL=${shellQuote(normalizeCdpUrl(cdpUrl))}`);
52
+ console.log(`export PIBO_CDP_TARGET_ID=${shellQuote(target.id)}`);
53
+ console.log(`export PIBO_CDP_TARGET_WS=${shellQuote(target.webSocketDebuggerUrl ?? '')}`);
54
+ console.log(`export PIBO_CHAT_URL=${shellQuote(target.url)}`);
55
+ }
56
+ function normalizeCdpUrl(value) {
57
+ return (value || DEFAULT_CDP_URL).replace(/\/+$/, '');
58
+ }
59
+ async function fetchChromeTargets(cdpUrl, timeoutMs) {
60
+ const response = await fetchWithTimeout(`${cdpUrl}/json/list`, timeoutMs);
61
+ if (!response.ok) {
62
+ throw new Error(`Chrome target discovery failed: ${response.status} ${response.statusText}`);
63
+ }
64
+ const payload = await response.json();
65
+ if (!Array.isArray(payload))
66
+ throw new Error('Chrome target discovery returned invalid JSON');
67
+ return payload;
68
+ }
69
+ async function fetchWithTimeout(url, timeoutMs) {
70
+ const controller = new AbortController();
71
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
72
+ try {
73
+ return await fetch(url, { signal: controller.signal });
74
+ }
75
+ finally {
76
+ clearTimeout(timeout);
77
+ }
78
+ }
79
+ function normalizeChromeTarget(target) {
80
+ return {
81
+ id: stringValue(target.id),
82
+ type: stringValue(target.type),
83
+ title: stringValue(target.title),
84
+ url: stringValue(target.url),
85
+ webSocketDebuggerUrl: optionalStringValue(target.webSocketDebuggerUrl),
86
+ auth: 'unknown',
87
+ composer: false,
88
+ textareaCount: 0,
89
+ };
90
+ }
91
+ async function probeChatTarget(target, timeoutMs) {
92
+ try {
93
+ const probe = await evaluateCdp(target.webSocketDebuggerUrl, CHAT_TARGET_PROBE, timeoutMs);
94
+ return applyProbe(target, probe);
95
+ }
96
+ catch (error) {
97
+ return {
98
+ ...target,
99
+ probeError: error instanceof Error ? error.message : String(error),
100
+ };
101
+ }
102
+ }
103
+ function applyProbe(target, probe) {
104
+ const text = stringValue(probe.text);
105
+ const textareas = Array.isArray(probe.textareas) ? probe.textareas : [];
106
+ const composer = textareas.some((textarea) => {
107
+ if (!isRecord(textarea))
108
+ return false;
109
+ return textarea.disabled !== true;
110
+ });
111
+ return {
112
+ ...target,
113
+ title: stringValue(probe.title) || target.title,
114
+ auth: classifyAuth(text, composer),
115
+ composer,
116
+ textareaCount: textareas.length,
117
+ };
118
+ }
119
+ function classifyAuth(text, composer) {
120
+ if (/Unauthenticated|Sign in with Google|Sign in/i.test(text))
121
+ return 'unauthenticated';
122
+ if (composer)
123
+ return 'authenticated';
124
+ if (/[^\s@]+@[^\s@]+\.[^\s@]+/.test(text))
125
+ return 'authenticated';
126
+ return 'unknown';
127
+ }
128
+ function scoreChatTarget(target) {
129
+ return ((target.auth === 'authenticated' ? 100 : 0) +
130
+ (target.composer ? 50 : 0) +
131
+ (target.url.includes('/sessions/') ? 20 : 0) +
132
+ (target.url.includes('/rooms/') ? 10 : 0));
133
+ }
134
+ async function evaluateCdp(webSocketUrl, expression, timeoutMs) {
135
+ return new Promise((resolve, reject) => {
136
+ const socket = new WebSocket(webSocketUrl);
137
+ let nextId = 0;
138
+ let settled = false;
139
+ const timer = setTimeout(() => fail(new Error('Timed out waiting for CDP target')), timeoutMs);
140
+ function settle() {
141
+ if (settled)
142
+ return false;
143
+ settled = true;
144
+ clearTimeout(timer);
145
+ try {
146
+ socket.close();
147
+ }
148
+ catch {
149
+ // The target may fail before the WebSocket reaches OPEN.
150
+ }
151
+ return true;
152
+ }
153
+ function succeed(value) {
154
+ if (settle())
155
+ resolve(value);
156
+ }
157
+ function fail(error) {
158
+ if (settle())
159
+ reject(error);
160
+ }
161
+ function send(method, params) {
162
+ const id = ++nextId;
163
+ socket.send(JSON.stringify({ id, method, params }));
164
+ return id;
165
+ }
166
+ socket.addEventListener('open', () => {
167
+ send('Runtime.evaluate', { expression, returnByValue: true });
168
+ });
169
+ socket.addEventListener('message', (event) => {
170
+ const message = parseJson(String(event.data));
171
+ if (!isRecord(message) || typeof message.id !== 'number')
172
+ return;
173
+ if (isRecord(message.error)) {
174
+ fail(new Error(JSON.stringify(message.error)));
175
+ return;
176
+ }
177
+ const result = isRecord(message.result) ? message.result : undefined;
178
+ const runtimeResult = result && isRecord(result.result) ? result.result : undefined;
179
+ const value = runtimeResult && isRecord(runtimeResult.value) ? runtimeResult.value : {};
180
+ succeed(value);
181
+ });
182
+ socket.addEventListener('error', () => {
183
+ fail(new Error('CDP WebSocket error'));
184
+ });
185
+ });
186
+ }
187
+ function stringValue(value) {
188
+ return typeof value === 'string' ? value : '';
189
+ }
190
+ function optionalStringValue(value) {
191
+ const text = stringValue(value);
192
+ return text || undefined;
193
+ }
194
+ function parseJson(value) {
195
+ try {
196
+ return JSON.parse(value);
197
+ }
198
+ catch {
199
+ return undefined;
200
+ }
201
+ }
202
+ function isRecord(value) {
203
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
204
+ }
205
+ function shellQuote(value) {
206
+ return `'${value.replace(/'/g, `'\\''`)}'`;
207
+ }