@pasko70/pibo 1.1.0 → 1.2.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 (426) hide show
  1. package/README.md +106 -254
  2. package/context/codex-base-prompt.md +4 -0
  3. package/context/compute-worker.md +23 -0
  4. package/context/pibo-native-tooling.md +18 -0
  5. package/context/pibo-system-prompt.md +69 -8
  6. package/dist/api/simple-agent-api.js +136 -0
  7. package/dist/app-context.js +4 -0
  8. package/dist/apps/chat/agent-profiles.js +18 -3
  9. package/dist/apps/chat/agent-store.js +113 -16
  10. package/dist/apps/chat/chat-api-routes.js +311 -0
  11. package/dist/apps/chat/chat-capability-routes.js +90 -0
  12. package/dist/apps/chat/chat-files.js +178 -0
  13. package/dist/apps/chat/chat-request-normalizers.js +681 -0
  14. package/dist/apps/chat/chat-settings-routes.js +75 -0
  15. package/dist/apps/chat/chat-trace-helpers.js +94 -0
  16. package/dist/apps/chat/chat-user-skill-routes.js +149 -0
  17. package/dist/apps/chat/cron-api.js +213 -0
  18. package/dist/apps/chat/data/chat-data-mappers.js +74 -0
  19. package/dist/apps/chat/data/event-command-service.js +75 -0
  20. package/dist/apps/chat/data/navigation-query-service.js +11 -0
  21. package/dist/apps/chat/data/project-service.js +844 -0
  22. package/dist/apps/chat/data/read-state-service.js +42 -0
  23. package/dist/apps/chat/data/room-service.js +52 -0
  24. package/dist/apps/chat/data/session-query-service.js +63 -0
  25. package/dist/apps/chat/data/timeline-query-service.js +96 -0
  26. package/dist/apps/chat/event-log.js +1 -307
  27. package/dist/apps/chat/model-catalog.js +7 -2
  28. package/dist/apps/chat/output-compactor.js +126 -0
  29. package/dist/apps/chat/output-event-policy.js +17 -0
  30. package/dist/apps/chat/project-workflow-human-actions.js +347 -0
  31. package/dist/apps/chat/project-workflow-sessions.js +260 -0
  32. package/dist/apps/chat/provider-auth-actions.js +43 -0
  33. package/dist/apps/chat/ralph-api.js +156 -0
  34. package/dist/apps/chat/read-model.js +1 -218
  35. package/dist/apps/chat/rooms.js +1 -321
  36. package/dist/apps/chat/static-assets.js +996 -0
  37. package/dist/apps/chat/stream.js +29 -6
  38. package/dist/apps/chat/trace.js +179 -1003
  39. package/dist/apps/chat/types/event-store.js +1 -0
  40. package/dist/apps/chat/types/read-model.js +1 -0
  41. package/dist/apps/chat/types/rooms.js +36 -0
  42. package/dist/apps/chat/web-app.js +3131 -1959
  43. package/dist/apps/chat/workflow-catalog.js +572 -0
  44. package/dist/apps/chat/workflow-edge-compatibility.js +51 -0
  45. package/dist/apps/chat/workflow-json-schema-validation.js +335 -0
  46. package/dist/apps/chat/workflow-persistence-model.js +140 -0
  47. package/dist/apps/chat/workflow-persistence.js +633 -0
  48. package/dist/apps/chat/workflow-registered-ref-params.js +130 -0
  49. package/dist/apps/chat/workflow-registered-ref-pickers.js +179 -0
  50. package/dist/apps/chat/workflow-registered-ref-validation.js +210 -0
  51. package/dist/apps/chat/workflow-v2-security-validation.js +93 -0
  52. package/dist/apps/chat/workflow-validation-helpers.js +114 -0
  53. package/dist/apps/chat-ui/assets/{dist-CNLWH2qh.js → dist-B4lw9z4F.js} +1 -1
  54. package/dist/apps/chat-ui/assets/{dist-8e4L8ciw.js → dist-BbTaHWON.js} +1 -1
  55. package/dist/apps/chat-ui/assets/{dist-CMZOa5ik.js → dist-BcT_c1EJ.js} +1 -1
  56. package/dist/apps/chat-ui/assets/{dist-DNcnQRPF.js → dist-CGINd7XU.js} +1 -1
  57. package/dist/apps/chat-ui/assets/{dist-CqqUC8Ce.js → dist-CrBzZkUp.js} +1 -1
  58. package/dist/apps/chat-ui/assets/{dist-D2N4-LIc.js → dist-CyyISotB.js} +1 -1
  59. package/dist/apps/chat-ui/assets/{dist-CUqpST5w.js → dist-DFbnFNpX.js} +1 -1
  60. package/dist/apps/chat-ui/assets/{dist-CspjOeBj.js → dist-DGLWQLX8.js} +1 -1
  61. package/dist/apps/chat-ui/assets/{dist-B7bbI3Qz.js → dist-DfcIkFSN.js} +1 -1
  62. package/dist/apps/chat-ui/assets/{dist-v4pjHlB7.js → dist-sKDHTwaT.js} +1 -1
  63. package/dist/apps/chat-ui/assets/{dist-D9L4MSRF.js → dist-y9D6la48.js} +1 -1
  64. package/dist/apps/chat-ui/assets/index-C25VYnyb.css +1 -0
  65. package/dist/apps/chat-ui/assets/index-CUkuvI3v.js +165 -0
  66. package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-144x144.png +0 -0
  67. package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-192x192.png +0 -0
  68. package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-48x48.png +0 -0
  69. package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-512x512.png +0 -0
  70. package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-72x72.png +0 -0
  71. package/dist/apps/chat-ui/assets/pwa-images/android/launchericon-96x96.png +0 -0
  72. package/dist/apps/chat-ui/assets/pwa-images/ios/100.png +0 -0
  73. package/dist/apps/chat-ui/assets/pwa-images/ios/1024.png +0 -0
  74. package/dist/apps/chat-ui/assets/pwa-images/ios/114.png +0 -0
  75. package/dist/apps/chat-ui/assets/pwa-images/ios/120.png +0 -0
  76. package/dist/apps/chat-ui/assets/pwa-images/ios/128.png +0 -0
  77. package/dist/apps/chat-ui/assets/pwa-images/ios/144.png +0 -0
  78. package/dist/apps/chat-ui/assets/pwa-images/ios/152.png +0 -0
  79. package/dist/apps/chat-ui/assets/pwa-images/ios/16.png +0 -0
  80. package/dist/apps/chat-ui/assets/pwa-images/ios/167.png +0 -0
  81. package/dist/apps/chat-ui/assets/pwa-images/ios/180.png +0 -0
  82. package/dist/apps/chat-ui/assets/pwa-images/ios/192.png +0 -0
  83. package/dist/apps/chat-ui/assets/pwa-images/ios/20.png +0 -0
  84. package/dist/apps/chat-ui/assets/pwa-images/ios/256.png +0 -0
  85. package/dist/apps/chat-ui/assets/pwa-images/ios/29.png +0 -0
  86. package/dist/apps/chat-ui/assets/pwa-images/ios/32.png +0 -0
  87. package/dist/apps/chat-ui/assets/pwa-images/ios/40.png +0 -0
  88. package/dist/apps/chat-ui/assets/pwa-images/ios/50.png +0 -0
  89. package/dist/apps/chat-ui/assets/pwa-images/ios/512.png +0 -0
  90. package/dist/apps/chat-ui/assets/pwa-images/ios/57.png +0 -0
  91. package/dist/apps/chat-ui/assets/pwa-images/ios/58.png +0 -0
  92. package/dist/apps/chat-ui/assets/pwa-images/ios/60.png +0 -0
  93. package/dist/apps/chat-ui/assets/pwa-images/ios/64.png +0 -0
  94. package/dist/apps/chat-ui/assets/pwa-images/ios/72.png +0 -0
  95. package/dist/apps/chat-ui/assets/pwa-images/ios/76.png +0 -0
  96. package/dist/apps/chat-ui/assets/pwa-images/ios/80.png +0 -0
  97. package/dist/apps/chat-ui/assets/pwa-images/ios/87.png +0 -0
  98. package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-100.png +0 -0
  99. package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-125.png +0 -0
  100. package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-150.png +0 -0
  101. package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-200.png +0 -0
  102. package/dist/apps/chat-ui/assets/pwa-images/windows/LargeTile.scale-400.png +0 -0
  103. package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-100.png +0 -0
  104. package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-125.png +0 -0
  105. package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-150.png +0 -0
  106. package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-200.png +0 -0
  107. package/dist/apps/chat-ui/assets/pwa-images/windows/SmallTile.scale-400.png +0 -0
  108. package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-100.png +0 -0
  109. package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-125.png +0 -0
  110. package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-150.png +0 -0
  111. package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-200.png +0 -0
  112. package/dist/apps/chat-ui/assets/pwa-images/windows/SplashScreen.scale-400.png +0 -0
  113. package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-100.png +0 -0
  114. package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-125.png +0 -0
  115. package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-150.png +0 -0
  116. package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-200.png +0 -0
  117. package/dist/apps/chat-ui/assets/pwa-images/windows/Square150x150Logo.scale-400.png +0 -0
  118. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-16.png +0 -0
  119. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-20.png +0 -0
  120. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-24.png +0 -0
  121. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-256.png +0 -0
  122. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-30.png +0 -0
  123. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-32.png +0 -0
  124. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-36.png +0 -0
  125. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-40.png +0 -0
  126. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-44.png +0 -0
  127. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-48.png +0 -0
  128. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-60.png +0 -0
  129. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-64.png +0 -0
  130. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-72.png +0 -0
  131. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-80.png +0 -0
  132. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-lightunplated_targetsize-96.png +0 -0
  133. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-16.png +0 -0
  134. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-20.png +0 -0
  135. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-24.png +0 -0
  136. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-256.png +0 -0
  137. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-30.png +0 -0
  138. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-32.png +0 -0
  139. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-36.png +0 -0
  140. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-40.png +0 -0
  141. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-44.png +0 -0
  142. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-48.png +0 -0
  143. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-60.png +0 -0
  144. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-64.png +0 -0
  145. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-72.png +0 -0
  146. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-80.png +0 -0
  147. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.altform-unplated_targetsize-96.png +0 -0
  148. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-100.png +0 -0
  149. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-125.png +0 -0
  150. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-150.png +0 -0
  151. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-200.png +0 -0
  152. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.scale-400.png +0 -0
  153. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-16.png +0 -0
  154. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-20.png +0 -0
  155. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-24.png +0 -0
  156. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-256.png +0 -0
  157. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-30.png +0 -0
  158. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-32.png +0 -0
  159. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-36.png +0 -0
  160. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-40.png +0 -0
  161. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-44.png +0 -0
  162. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-48.png +0 -0
  163. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-60.png +0 -0
  164. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-64.png +0 -0
  165. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-72.png +0 -0
  166. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-80.png +0 -0
  167. package/dist/apps/chat-ui/assets/pwa-images/windows/Square44x44Logo.targetsize-96.png +0 -0
  168. package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-100.png +0 -0
  169. package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-125.png +0 -0
  170. package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-150.png +0 -0
  171. package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-200.png +0 -0
  172. package/dist/apps/chat-ui/assets/pwa-images/windows/StoreLogo.scale-400.png +0 -0
  173. package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-100.png +0 -0
  174. package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-125.png +0 -0
  175. package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-150.png +0 -0
  176. package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-200.png +0 -0
  177. package/dist/apps/chat-ui/assets/pwa-images/windows/Wide310x150Logo.scale-400.png +0 -0
  178. package/dist/apps/chat-ui/index.html +8 -3
  179. package/dist/apps/chat-ui/manifest.webmanifest +25 -0
  180. package/dist/apps/chat-ui/sw.js +41 -0
  181. package/dist/apps/cli-ui/InkSessionApp.js +1218 -0
  182. package/dist/apps/cli-ui/InkTerminalLine.js +53 -0
  183. package/dist/apps/cli-ui/InkTerminalRow.js +304 -0
  184. package/dist/apps/cli-ui/InkTerminalView.js +25 -0
  185. package/dist/apps/cli-ui/cliSessionsCommand.js +232 -0
  186. package/dist/apps/cli-ui/index.js +8 -0
  187. package/dist/apps/cli-ui/inkColors.js +67 -0
  188. package/dist/apps/cli-ui/inkJson.js +244 -0
  189. package/dist/apps/cli-ui/inkMarkdown.js +122 -0
  190. package/dist/apps/context-files-ui/assets/{dist-DFi2YGux.js → dist-BOiGdrG-.js} +1 -1
  191. package/dist/apps/context-files-ui/assets/{dist-DyfSeBMu.js → dist-DK01b7x4.js} +1 -1
  192. package/dist/apps/context-files-ui/assets/{dist-CwbH_3RN.js → dist-DPG9jOQ-.js} +1 -1
  193. package/dist/apps/context-files-ui/assets/{dist-dTBsFYAl.js → dist-Dp5AH00p.js} +1 -1
  194. package/dist/apps/context-files-ui/assets/{dist-CxRLRmMx.js → dist-DqYw0LH7.js} +1 -1
  195. package/dist/apps/context-files-ui/assets/{dist-MyZgX9K2.js → dist-TF5iO5ML.js} +1 -1
  196. package/dist/apps/context-files-ui/assets/{dist-DQXzt2Ng.js → dist-TbjAhles.js} +1 -1
  197. package/dist/apps/context-files-ui/assets/{dist-YwR9dpb-.js → dist-ZsBbt0uY.js} +1 -1
  198. package/dist/apps/context-files-ui/assets/{dist-CKQF1zEu.js → dist-kmsvtHkH.js} +1 -1
  199. package/dist/apps/context-files-ui/assets/{dist-BJW3917N.js → dist-vnd7PMu3.js} +1 -1
  200. package/dist/apps/context-files-ui/assets/{index-BwRDoHMC.css → index-B92tL3Pp.css} +1 -1
  201. package/dist/apps/context-files-ui/assets/{index-GwvjXytt.js → index-BhAWD3dv.js} +2 -2
  202. package/dist/apps/context-files-ui/index.html +2 -2
  203. package/dist/auth/better-auth.js +2 -1
  204. package/dist/auth/login-actions.js +251 -0
  205. package/dist/auth/openai-codex-usage.js +147 -0
  206. package/dist/bin/pibo.js +0 -0
  207. package/dist/bin/rg.js +15 -0
  208. package/dist/cli-session/fakeSessionSource.js +804 -0
  209. package/dist/cli-session/index.js +3 -0
  210. package/dist/cli-session/localSessionSource.js +1144 -0
  211. package/dist/cli-session/sessionSource.js +13 -0
  212. package/dist/cli.js +142 -14
  213. package/dist/compute/cli.js +415 -0
  214. package/dist/compute/docker.js +827 -0
  215. package/dist/compute/resource-health.js +333 -0
  216. package/dist/compute/resource-policy.js +98 -0
  217. package/dist/config/config.js +9 -5
  218. package/dist/core/context-build.js +677 -0
  219. package/dist/core/model-defaults.js +51 -9
  220. package/dist/core/pibo-home.js +8 -0
  221. package/dist/core/profiles.js +48 -0
  222. package/dist/core/provider-telemetry.js +222 -0
  223. package/dist/core/routed-session.js +441 -47
  224. package/dist/core/runtime-telemetry.js +853 -0
  225. package/dist/core/runtime.js +103 -15
  226. package/dist/core/session-errors.js +47 -0
  227. package/dist/core/session-model.js +39 -0
  228. package/dist/core/session-router.js +292 -62
  229. package/dist/core/shared-app.js +17 -0
  230. package/dist/core/skill-expansion.js +43 -0
  231. package/dist/core/system-prompt-template.js +9 -9
  232. package/dist/core/telemetry-staleness.js +128 -0
  233. package/dist/core/test-output-compaction.js +145 -0
  234. package/dist/core/user-settings.js +73 -0
  235. package/dist/cron/channel.js +28 -0
  236. package/dist/cron/cli.js +230 -0
  237. package/dist/cron/plugin.js +11 -0
  238. package/dist/cron/schedule.js +214 -0
  239. package/dist/cron/service.js +177 -0
  240. package/dist/cron/store.js +349 -0
  241. package/dist/cron/types.js +1 -0
  242. package/dist/data/cli.js +184 -0
  243. package/dist/data/event-log.js +106 -0
  244. package/dist/data/final-app-space-cutover-migration.js +728 -0
  245. package/dist/data/ingest-service.js +389 -0
  246. package/dist/data/message-store.js +62 -0
  247. package/dist/data/navigation-store.js +75 -0
  248. package/dist/data/observation-store.js +46 -0
  249. package/dist/data/payload-store.js +144 -0
  250. package/dist/data/pibo-store.js +59 -0
  251. package/dist/data/schema.js +434 -0
  252. package/dist/data/session-store.js +63 -0
  253. package/dist/data/shared-app-migration.js +757 -0
  254. package/dist/data/sqlite-schema.js +12 -0
  255. package/dist/data/telemetry-preview.js +65 -0
  256. package/dist/data/telemetry-queries.js +212 -0
  257. package/dist/data/telemetry-retention.js +50 -0
  258. package/dist/data/telemetry-rows.js +158 -0
  259. package/dist/data/telemetry.js +357 -0
  260. package/dist/debug/delta-compaction.js +99 -0
  261. package/dist/debug/detail-format.js +86 -0
  262. package/dist/debug/events.js +149 -29
  263. package/dist/debug/failures.js +162 -0
  264. package/dist/debug/index.js +655 -30
  265. package/dist/debug/messages.js +185 -0
  266. package/dist/debug/next-commands.js +6 -0
  267. package/dist/debug/payloads.js +123 -0
  268. package/dist/debug/pty.js +924 -0
  269. package/dist/debug/session.js +45 -15
  270. package/dist/debug/sql.js +1 -1
  271. package/dist/debug/stores.js +18 -13
  272. package/dist/debug/summary.js +72 -0
  273. package/dist/debug/telemetry.js +649 -0
  274. package/dist/debug/tools.js +168 -0
  275. package/dist/debug/trace-render-check.js +151 -0
  276. package/dist/debug/trace.js +152 -27
  277. package/dist/debug/web-artifacts.js +63 -0
  278. package/dist/debug/web-options.js +313 -0
  279. package/dist/debug/web-render-analysis.js +310 -0
  280. package/dist/debug/web-snapshot-browser-scripts.js +303 -0
  281. package/dist/debug/web-streaming-benchmark-analysis.js +605 -0
  282. package/dist/debug/web-streaming-browser-library.js +928 -0
  283. package/dist/debug/web-streaming-browser-scripts.js +242 -0
  284. package/dist/debug/web-streaming-provider-telemetry.js +194 -0
  285. package/dist/debug/web-streaming-report.js +493 -0
  286. package/dist/debug/web-streaming-types.js +1 -0
  287. package/dist/debug/web.js +574 -0
  288. package/dist/gateway/backup.js +83 -0
  289. package/dist/gateway/cli.js +511 -0
  290. package/dist/gateway/fallback.js +155 -0
  291. package/dist/gateway/pidfile.js +84 -0
  292. package/dist/gateway/protocol.js +16 -0
  293. package/dist/gateway/server.js +172 -17
  294. package/dist/gateway/tool.js +54 -51
  295. package/dist/gateway/web.js +74 -2
  296. package/dist/index.js +3 -1
  297. package/dist/local/client.js +3 -3
  298. package/dist/local/extension.js +8 -5
  299. package/dist/plugins/builtin.js +251 -49
  300. package/dist/plugins/chat-vscode-web.js +28 -0
  301. package/dist/plugins/codex-compat.js +0 -41
  302. package/dist/plugins/context-files.js +98 -18
  303. package/dist/plugins/dev-auth.js +124 -0
  304. package/dist/plugins/native-tooling.js +15 -0
  305. package/dist/plugins/registry.js +49 -1
  306. package/dist/plugins/web-annotations.js +27 -0
  307. package/dist/providers/minimax.js +70 -0
  308. package/dist/providers/openai-compat.js +48 -0
  309. package/dist/ralph/channel.js +8 -0
  310. package/dist/ralph/cli.js +152 -0
  311. package/dist/ralph/plugin.js +14 -0
  312. package/dist/ralph/service.js +271 -0
  313. package/dist/ralph/stopping.js +151 -0
  314. package/dist/ralph/store.js +450 -0
  315. package/dist/ralph/templates.js +200 -0
  316. package/dist/ralph/types.js +1 -0
  317. package/dist/reliability/store.js +42 -26
  318. package/dist/runs/registry.js +72 -35
  319. package/dist/session-ui/commandCatalog.js +193 -0
  320. package/dist/session-ui/commandResults.js +95 -0
  321. package/dist/session-ui/index.js +7 -0
  322. package/dist/session-ui/ownerViewModel.js +27 -0
  323. package/dist/session-ui/roomSessionViewModel.js +69 -0
  324. package/dist/session-ui/statusViewModel.js +127 -0
  325. package/dist/session-ui/terminalCards.js +210 -0
  326. package/dist/session-ui/terminalRows.js +937 -0
  327. package/dist/session-ui/terminalValue.js +45 -0
  328. package/dist/sessions/pibo-data-store.js +178 -0
  329. package/dist/sessions/sqlite-store.js +78 -12
  330. package/dist/sessions/store.js +11 -4
  331. package/dist/sessions/workflow-session-kind.js +20 -0
  332. package/dist/setup/cli.js +567 -0
  333. package/dist/shared/trace-async-agent-runs.js +127 -0
  334. package/dist/shared/trace-engine.js +96 -0
  335. package/dist/shared/trace-event-projection.js +679 -0
  336. package/dist/shared/trace-live-reducer.js +191 -0
  337. package/dist/shared/trace-nodes.js +76 -0
  338. package/dist/shared/trace-order.js +11 -10
  339. package/dist/shared/trace-patch-nodes.js +83 -0
  340. package/dist/shared/trace-run-notifications.js +69 -0
  341. package/dist/shared/trace-subagent-links.js +46 -0
  342. package/dist/shared/trace-transcript.js +303 -0
  343. package/dist/shared/trace-types.js +1 -0
  344. package/dist/shared-app.js +4 -0
  345. package/dist/signals/aggregate.js +65 -0
  346. package/dist/signals/events.js +1 -0
  347. package/dist/signals/projector.js +158 -0
  348. package/dist/signals/registry.js +513 -0
  349. package/dist/signals/store.js +1 -0
  350. package/dist/signals/types.js +1 -0
  351. package/dist/skills/cli.js +117 -0
  352. package/dist/tools/agent-browser-leases.js +219 -0
  353. package/dist/tools/agent-browser-wrapper.js +99 -0
  354. package/dist/tools/browser-pool.js +623 -0
  355. package/dist/tools/browser-use-cdp.js +56 -4
  356. package/dist/tools/browser-use-leases.js +215 -37
  357. package/dist/tools/browser-use-wrapper.js +508 -65
  358. package/dist/tools/cdp-client.js +189 -0
  359. package/dist/tools/guides.js +203 -4
  360. package/dist/tools/index.js +666 -16
  361. package/dist/tools/npm-runtime.js +136 -0
  362. package/dist/tools/registry.js +107 -8
  363. package/dist/tools/runtime/index.js +3 -0
  364. package/dist/tools/runtime/node-backend.js +225 -0
  365. package/dist/tools/runtime/node-worker-source.js +206 -0
  366. package/dist/tools/runtime/python-backend.js +227 -0
  367. package/dist/tools/runtime/python-worker-source.js +178 -0
  368. package/dist/tools/runtime/registry.js +255 -0
  369. package/dist/tools/runtime/tool.js +168 -0
  370. package/dist/tools/runtime/types.js +1 -0
  371. package/dist/tools/web-search.js +2 -1
  372. package/dist/user-skills/installer.js +39 -36
  373. package/dist/user-skills/store.js +50 -11
  374. package/dist/web/auth.js +5 -1
  375. package/dist/web/channel.js +86 -0
  376. package/dist/web/http.js +79 -14
  377. package/dist/web-annotations/api.js +348 -0
  378. package/dist/web-annotations/attachments.js +201 -0
  379. package/dist/web-annotations/cdp.js +1107 -0
  380. package/dist/web-annotations/index.js +7 -0
  381. package/dist/web-annotations/store.js +407 -0
  382. package/dist/web-annotations/tools.js +350 -0
  383. package/dist/web-annotations/types.js +34 -0
  384. package/dist/web-annotations/validation.js +288 -0
  385. package/docs/README.md +23 -0
  386. package/docs/ops/install-developer-host.md +112 -0
  387. package/docs/ops/install-user-host.md +76 -0
  388. package/docs/ops/upgrade-user-to-developer-host.md +69 -0
  389. package/package.json +24 -10
  390. package/skills/builtin/pi-agent-harness/SKILL.md +24 -24
  391. package/skills/builtin/pibo-docker-system/SKILL.md +170 -0
  392. package/skills/builtin/pibo-spec-writing/SKILL.md +330 -0
  393. package/skills/builtin/prd/SKILL.md +143 -0
  394. package/skills/builtin/ralph-loop/SKILL.md +359 -0
  395. package/skills/builtin/ralph-prd-json/SKILL.md +123 -0
  396. package/skills/builtin/skill-creator/LICENSE.txt +202 -0
  397. package/skills/builtin/skill-creator/SKILL.md +513 -0
  398. package/skills/builtin/skill-creator/agents/analyzer.md +274 -0
  399. package/skills/builtin/skill-creator/agents/comparator.md +202 -0
  400. package/skills/builtin/skill-creator/agents/grader.md +223 -0
  401. package/skills/builtin/skill-creator/assets/eval_review.html +146 -0
  402. package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -0
  403. package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -0
  404. package/skills/builtin/skill-creator/references/schemas.md +430 -0
  405. package/skills/builtin/skill-creator/scripts/__init__.py +0 -0
  406. package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -0
  407. package/skills/builtin/skill-creator/scripts/generate_report.py +326 -0
  408. package/skills/builtin/skill-creator/scripts/improve_description.py +247 -0
  409. package/skills/builtin/skill-creator/scripts/package_skill.py +136 -0
  410. package/skills/builtin/skill-creator/scripts/quick_validate.py +103 -0
  411. package/skills/builtin/skill-creator/scripts/run_eval.py +310 -0
  412. package/skills/builtin/skill-creator/scripts/run_loop.py +328 -0
  413. package/skills/builtin/skill-creator/scripts/utils.py +47 -0
  414. package/skills/builtin/web-annotations/SKILL.md +93 -0
  415. package/dist/apps/chat-ui/assets/index-D2Qxambd.js +0 -151
  416. package/dist/apps/chat-ui/assets/index-DXx368XK.css +0 -1
  417. package/dist/env.js +0 -32
  418. package/dist/plugins/core-tools.js +0 -94
  419. package/dist/plugins/example.js +0 -67
  420. package/dist/plugins/remote-agent.js +0 -9
  421. package/dist/remote/channel.js +0 -176
  422. package/dist/remote/client.js +0 -92
  423. package/dist/remote/examples/tui-controller.js +0 -263
  424. package/dist/remote/protocol.js +0 -55
  425. package/dist/remote/session-client.js +0 -189
  426. package/dist/sessions/bindings.js +0 -41
@@ -1,5 +1,52 @@
1
1
  const DEFAULT_CDP_URL = 'http://127.0.0.1:56663';
2
2
  const DEFAULT_TIMEOUT_MS = 2500;
3
+ async function isCdpPortReachable(port) {
4
+ try {
5
+ const response = await fetchWithTimeout(`http://127.0.0.1:${port}/json/version`, 800);
6
+ return response.ok;
7
+ }
8
+ catch {
9
+ return false;
10
+ }
11
+ }
12
+ async function discoverCdpUrl() {
13
+ const candidates = [];
14
+ if (process.env.BROWSER_USE_HOME) {
15
+ candidates.push(join(process.env.BROWSER_USE_HOME, 'pibo-cdp'));
16
+ }
17
+ if (process.env.HOME) {
18
+ candidates.push(join(process.env.HOME, '.pibo', 'tools', 'browser-use', 'home', 'pibo-cdp'));
19
+ candidates.push(join(process.env.HOME, '.browser-use', 'pibo-cdp'));
20
+ }
21
+ for (const stateDir of candidates) {
22
+ try {
23
+ if (!existsSync(stateDir))
24
+ continue;
25
+ const entries = readdirSync(stateDir)
26
+ .filter((f) => f.endsWith('.port'))
27
+ .map((f) => {
28
+ const path = join(stateDir, f);
29
+ const portText = readFileSync(path, 'utf-8').trim();
30
+ const port = Number.parseInt(portText, 10);
31
+ const mtime = statSync(path).mtimeMs;
32
+ return { port, mtime, valid: Number.isFinite(port) && port > 0 };
33
+ })
34
+ .filter((e) => e.valid)
35
+ .sort((a, b) => b.mtime - a.mtime);
36
+ for (const entry of entries) {
37
+ if (await isCdpPortReachable(entry.port)) {
38
+ return `http://127.0.0.1:${entry.port}`;
39
+ }
40
+ }
41
+ }
42
+ catch {
43
+ // ignore discovery errors for this candidate
44
+ }
45
+ }
46
+ return DEFAULT_CDP_URL;
47
+ }
48
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
49
+ import { join } from 'node:path';
3
50
  const CHAT_TARGET_PROBE = `(() => {
4
51
  const text = String(document.body?.innerText || "");
5
52
  const textareas = [...document.querySelectorAll("textarea")].map((textarea) => ({
@@ -14,7 +61,7 @@ const CHAT_TARGET_PROBE = `(() => {
14
61
  };
15
62
  })()`;
16
63
  export async function listBrowserUseCdpTargets(options = {}) {
17
- const cdpUrl = normalizeCdpUrl(options.cdpUrl);
64
+ const cdpUrl = await normalizeCdpUrl(options.cdpUrl);
18
65
  const probe = options.probe !== false;
19
66
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
20
67
  const targets = await fetchChromeTargets(cdpUrl, timeoutMs);
@@ -48,13 +95,18 @@ export function formatBrowserUseTargets(targets) {
48
95
  return lines.join('\n');
49
96
  }
50
97
  export function printAttachChatExports(target, cdpUrl = DEFAULT_CDP_URL) {
51
- console.log(`export PIBO_CDP_URL=${shellQuote(normalizeCdpUrl(cdpUrl))}`);
98
+ console.log(`export PIBO_CDP_URL=${shellQuote(cdpUrl)}`);
52
99
  console.log(`export PIBO_CDP_TARGET_ID=${shellQuote(target.id)}`);
53
100
  console.log(`export PIBO_CDP_TARGET_WS=${shellQuote(target.webSocketDebuggerUrl ?? '')}`);
54
101
  console.log(`export PIBO_CHAT_URL=${shellQuote(target.url)}`);
55
102
  }
56
- function normalizeCdpUrl(value) {
57
- return (value || DEFAULT_CDP_URL).replace(/\/+$/, '');
103
+ export function normalizeCdpUrlSync(value) {
104
+ return value.replace(/\/+$/, '');
105
+ }
106
+ async function normalizeCdpUrl(value) {
107
+ if (value)
108
+ return normalizeCdpUrlSync(value);
109
+ return (await discoverCdpUrl()).replace(/\/+$/, '');
58
110
  }
59
111
  async function fetchChromeTargets(cdpUrl, timeoutMs) {
60
112
  const response = await fetchWithTimeout(`${cdpUrl}/json/list`, timeoutMs);
@@ -1,8 +1,10 @@
1
+ import { spawn } from 'node:child_process';
1
2
  import { existsSync, readFileSync } from 'node:fs';
2
3
  import { cp, mkdir, rm, writeFile } from 'node:fs/promises';
3
- import { join } from 'node:path';
4
+ import { join, resolve } from 'node:path';
4
5
  import { ErrorCode, formatCliError } from '../cli-errors.js';
5
6
  import { BROWSER_USE_DEFAULT_PROFILE } from './browser-use-wrapper.js';
7
+ import { browserPoolPaths, loadBrowserPoolState, releaseBrowserPoolLease, saveBrowserPoolState, withBrowserPoolLock, } from './browser-pool.js';
6
8
  const REGISTRY_VERSION = 1;
7
9
  const DEFAULT_APP = 'pibo-chat';
8
10
  const DEFAULT_TTL_MINUTES = 8 * 60;
@@ -36,6 +38,27 @@ function appPoolDir(status, app) {
36
38
  function browserUseHome(status) {
37
39
  return status.homeDir;
38
40
  }
41
+ function browserPoolWorkerId() {
42
+ return process.env.PIBO_BROWSER_POOL_WORKER_ID || process.env.PIBO_COMPUTE_WORKER_ID || process.env.HOSTNAME || 'local';
43
+ }
44
+ function browserPoolId() {
45
+ return process.env.PIBO_BROWSER_POOL_ID || 'default';
46
+ }
47
+ function browserPoolRootDir(status) {
48
+ return process.env.PIBO_BROWSER_POOL_ROOT || join(browserUseHome(status), 'pibo-browser-pool');
49
+ }
50
+ function browserPoolLeaseIdForSession(sessionName) {
51
+ return `browser-use:${safeSessionName(sessionName)}`;
52
+ }
53
+ function browserPoolIdentityForLease(status, lease) {
54
+ return {
55
+ workerId: lease.browserPoolWorkerId || browserPoolWorkerId(),
56
+ poolId: lease.browserPoolId || browserPoolId(),
57
+ };
58
+ }
59
+ function browserPoolRootForLease(status, lease) {
60
+ return lease.browserPoolRootDir || browserPoolRootDir(status);
61
+ }
39
62
  function authTemplateDir(status) {
40
63
  if (process.env.PIBO_BROWSER_USE_AUTH_TEMPLATE_DIR) {
41
64
  return process.env.PIBO_BROWSER_USE_AUTH_TEMPLATE_DIR;
@@ -46,9 +69,11 @@ function defaultTemplateDir(status) {
46
69
  const preferred = authTemplateDir(status);
47
70
  if (existsSync(preferred))
48
71
  return preferred;
49
- return join(status.homeDir, 'chrome-profiles', BROWSER_USE_DEFAULT_PROFILE);
72
+ // Never fall back to the active default profile (it may be running).
73
+ // Create an empty template directory so leases get clean profiles.
74
+ return preferred;
50
75
  }
51
- function readRegistry(status) {
76
+ export function readRegistry(status) {
52
77
  const path = registryPath(status);
53
78
  if (!existsSync(path))
54
79
  return { version: REGISTRY_VERSION, leases: [] };
@@ -92,7 +117,7 @@ async function withRegistryLock(status, action) {
92
117
  await rm(lock, { recursive: true, force: true });
93
118
  }
94
119
  }
95
- function isExpired(lease, now = new Date()) {
120
+ export function isExpired(lease, now = new Date()) {
96
121
  return new Date(lease.expiresAt).getTime() <= now.getTime();
97
122
  }
98
123
  function safeSessionName(sessionName) {
@@ -134,25 +159,92 @@ function killLeaseProcess(status, lease) {
134
159
  // Process already exited.
135
160
  }
136
161
  }
162
+ async function releaseAssociatedBrowserPoolLease(status, lease) {
163
+ if (!lease.browserPoolLeaseId)
164
+ return;
165
+ const identity = browserPoolIdentityForLease(status, lease);
166
+ const paths = browserPoolPaths(browserPoolRootForLease(status, lease), identity);
167
+ await releaseBrowserPoolLease(paths, identity, { leaseId: lease.browserPoolLeaseId });
168
+ }
169
+ async function reapAssociatedBrowserPoolLeaseProcess(status, lease) {
170
+ if (!lease.browserPoolLeaseId)
171
+ return false;
172
+ const identity = browserPoolIdentityForLease(status, lease);
173
+ const paths = browserPoolPaths(browserPoolRootForLease(status, lease), identity);
174
+ return withBrowserPoolLock(paths.lockPath, { holder: `auth-lease-reap:${lease.id}` }, async () => {
175
+ const state = await loadBrowserPoolState(paths.statePath, { ...identity, onMissing: 'empty', onMalformed: 'empty' });
176
+ if (!browserPoolStateMatchesAuthLease(state, lease))
177
+ return false;
178
+ const terminated = await terminateManagedBrowserProcess(state);
179
+ const reapedAt = nowIso();
180
+ await saveBrowserPoolState(paths.statePath, {
181
+ ...state,
182
+ state: terminated ? 'stale' : state.state,
183
+ activeLeaseId: undefined,
184
+ activeLeaseCount: 0,
185
+ holder: undefined,
186
+ lastUsedAt: reapedAt,
187
+ idleExpiresAt: undefined,
188
+ cleanupStatus: terminated ? 'success' : 'skipped',
189
+ lastError: terminated ? 'Expired auth lease reaped managed browser process' : 'No live managed browser process to reap',
190
+ });
191
+ return terminated;
192
+ });
193
+ }
194
+ function browserPoolStateMatchesAuthLease(state, lease) {
195
+ return state.state === 'leased'
196
+ && state.activeLeaseId === lease.browserPoolLeaseId
197
+ && Boolean(state.userDataDir)
198
+ && resolve(state.userDataDir) === resolve(lease.userDataDir);
199
+ }
200
+ async function terminateManagedBrowserProcess(state) {
201
+ if (!state.pid || !processIsAlive(state.pid))
202
+ return false;
203
+ const target = state.processGroupId && state.processGroupId === state.pid ? -state.processGroupId : state.pid;
204
+ try {
205
+ process.kill(target, 'SIGTERM');
206
+ }
207
+ catch {
208
+ return false;
209
+ }
210
+ if (!(await waitForProcessExit(state.pid, 1000))) {
211
+ try {
212
+ process.kill(target, 'SIGKILL');
213
+ }
214
+ catch {
215
+ // Process may have exited after TERM.
216
+ }
217
+ await waitForProcessExit(state.pid, 1000);
218
+ }
219
+ return !processIsAlive(state.pid);
220
+ }
221
+ async function waitForProcessExit(pid, timeoutMs) {
222
+ const startedAt = Date.now();
223
+ while (Date.now() - startedAt < timeoutMs) {
224
+ if (!processIsAlive(pid))
225
+ return true;
226
+ await new Promise((resolve) => setTimeout(resolve, 50));
227
+ }
228
+ return !processIsAlive(pid);
229
+ }
137
230
  async function copyTemplateProfile(templateDir, userDataDir) {
138
- if (!existsSync(templateDir)) {
139
- throw new Error(formatCliError({
140
- code: ErrorCode.CLIENT_ERROR,
141
- type: 'BROWSER_USE_AUTH_TEMPLATE_MISSING',
142
- message: `Browser-use auth template does not exist: ${templateDir}`,
143
- suggestion: 'Run `pibo tools browser-use auth-template env`, open the Chat Web App, sign in, then acquire a lease again.',
144
- }));
231
+ if (existsSync(templateDir)) {
232
+ assertTemplateIsNotRunning(templateDir);
233
+ await rm(userDataDir, { recursive: true, force: true });
234
+ await mkdir(userDataDir, { recursive: true });
235
+ await cp(templateDir, userDataDir, {
236
+ recursive: true,
237
+ filter: (source) => {
238
+ const base = source.split(/[\\/]/).pop() ?? '';
239
+ return !base.startsWith('Singleton') && base !== 'DevToolsActivePort';
240
+ },
241
+ });
242
+ return;
145
243
  }
146
- assertTemplateIsNotRunning(templateDir);
244
+ // Template does not exist yet: create a clean empty profile directory.
245
+ // Chrome will initialise a fresh profile on first start.
147
246
  await rm(userDataDir, { recursive: true, force: true });
148
247
  await mkdir(userDataDir, { recursive: true });
149
- await cp(templateDir, userDataDir, {
150
- recursive: true,
151
- filter: (source) => {
152
- const base = source.split(/[\\/]/).pop() ?? '';
153
- return !base.startsWith('Singleton') && base !== 'DevToolsActivePort';
154
- },
155
- });
156
248
  }
157
249
  function assertTemplateIsNotRunning(templateDir) {
158
250
  for (const fileName of ['SingletonLock', 'SingletonCookie', 'SingletonSocket']) {
@@ -179,20 +271,25 @@ function nextSlotNumber(leases, app) {
179
271
  }
180
272
  throw new Error(`No browser-use slots available for ${app}`);
181
273
  }
182
- function createLease(status, app, owner, ttlMinutes, profileName, leases) {
274
+ function createLease(status, app, holder, ttlMinutes, profileName, leases) {
183
275
  const slot = nextSlotNumber(leases, app);
184
276
  const slotName = `slot-${String(slot).padStart(3, '0')}`;
185
277
  const appId = sanitizeIdPart(app);
186
278
  const id = `${appId}-${slotName}`;
187
279
  const createdAt = nowIso();
280
+ const sessionName = `pibo-auth-${id}`;
188
281
  return {
189
282
  id,
190
283
  app,
191
- owner,
192
- sessionName: `pibo-auth-${id}`,
284
+ holder,
285
+ sessionName,
193
286
  userDataDir: join(appPoolDir(status, app), slotName),
194
287
  profileName,
195
288
  status: 'active',
289
+ browserPoolLeaseId: browserPoolLeaseIdForSession(sessionName),
290
+ browserPoolWorkerId: browserPoolWorkerId(),
291
+ browserPoolId: browserPoolId(),
292
+ browserPoolRootDir: browserPoolRootDir(status),
196
293
  createdAt,
197
294
  updatedAt: createdAt,
198
295
  expiresAt: addMinutes(new Date(createdAt), ttlMinutes).toISOString(),
@@ -209,6 +306,8 @@ function printLeaseEnv(status, lease) {
209
306
  console.log(`export PIBO_BROWSER_USE_SESSION=${shellQuote(lease.sessionName)}`);
210
307
  console.log(`export PIBO_BROWSER_USE_CHROME_USER_DATA_DIR=${shellQuote(lease.userDataDir)}`);
211
308
  console.log(`export PIBO_BROWSER_USE_DEFAULT_PROFILE=${shellQuote(lease.profileName)}`);
309
+ if (lease.browserPoolLeaseId)
310
+ console.log(`export PIBO_BROWSER_POOL_LEASE_ID=${shellQuote(lease.browserPoolLeaseId)}`);
212
311
  console.log(`# browser-use --session "$PIBO_BROWSER_USE_SESSION" state`);
213
312
  }
214
313
  function printLeaseJson(status, lease) {
@@ -221,23 +320,29 @@ function printLeaseJson(status, lease) {
221
320
  PIBO_BROWSER_USE_SESSION: lease.sessionName,
222
321
  PIBO_BROWSER_USE_CHROME_USER_DATA_DIR: lease.userDataDir,
223
322
  PIBO_BROWSER_USE_DEFAULT_PROFILE: lease.profileName,
323
+ ...(lease.browserPoolLeaseId ? { PIBO_BROWSER_POOL_LEASE_ID: lease.browserPoolLeaseId } : {}),
224
324
  },
225
325
  }, null, 2));
226
326
  }
227
327
  export async function acquireBrowserUseLease(context, options = {}) {
228
328
  const app = options.app?.trim() || DEFAULT_APP;
229
- const owner = options.owner?.trim() || process.env.PIBO_BROWSER_USE_LEASE_OWNER || process.env.USER || 'unknown';
329
+ const holder = options.holder?.trim() || process.env.PIBO_BROWSER_USE_LEASE_HOLDER || process.env.USER || 'unknown';
230
330
  const ttlMinutes = options.ttlMinutes ?? DEFAULT_TTL_MINUTES;
231
331
  const profileName = options.profileName?.trim() || BROWSER_USE_DEFAULT_PROFILE;
232
332
  const templateDir = options.templateDir?.trim() || defaultTemplateDir(context.status);
233
333
  await withRegistryLock(context.status, async () => {
234
334
  const registry = readRegistry(context.status);
335
+ const reapedCount = await reapStaleLeasesInRegistry(context.status, registry);
235
336
  let lease = selectReusableLease(context.status, registry.leases, app);
236
337
  if (lease) {
237
338
  await copyTemplateProfile(templateDir, lease.userDataDir);
238
- lease.owner = owner;
339
+ lease.holder = holder;
239
340
  lease.status = 'active';
240
341
  lease.profileName = profileName;
342
+ lease.browserPoolLeaseId = browserPoolLeaseIdForSession(lease.sessionName);
343
+ lease.browserPoolWorkerId = browserPoolWorkerId();
344
+ lease.browserPoolId = browserPoolId();
345
+ lease.browserPoolRootDir = browserPoolRootDir(context.status);
241
346
  lease.updatedAt = nowIso();
242
347
  lease.expiresAt = addMinutes(new Date(), ttlMinutes).toISOString();
243
348
  }
@@ -254,18 +359,95 @@ export async function acquireBrowserUseLease(context, options = {}) {
254
359
  suggestion: 'Release a lease or rerun with a higher --max-slots value.',
255
360
  }));
256
361
  }
257
- lease = createLease(context.status, app, owner, ttlMinutes, profileName, registry.leases);
362
+ lease = createLease(context.status, app, holder, ttlMinutes, profileName, registry.leases);
258
363
  await copyTemplateProfile(templateDir, lease.userDataDir);
259
364
  registry.leases.push(lease);
260
365
  }
261
366
  await writeRegistry(context.status, registry);
367
+ if (reapedCount > 0 && !options.json) {
368
+ console.log(`Reaped ${reapedCount} stale lease${reapedCount === 1 ? '' : 's'}`);
369
+ }
262
370
  if (options.json)
263
371
  printLeaseJson(context.status, lease);
264
372
  else
265
373
  printLeaseEnv(context.status, lease);
374
+ if (!options.noWarmup) {
375
+ const warmup = await warmupBrowserUseLease(context, lease);
376
+ if (!warmup.success && !options.json) {
377
+ console.log(`Warning: Browser warm-up failed: ${warmup.error}`);
378
+ }
379
+ }
380
+ });
381
+ }
382
+ async function warmupBrowserUseLease(context, lease, timeoutMs = 15000) {
383
+ const wrapperPath = join(context.status.homeDir, 'bin', 'browser-use');
384
+ if (!existsSync(wrapperPath)) {
385
+ return { success: false, error: 'browser-use wrapper not found' };
386
+ }
387
+ const env = {
388
+ ...process.env,
389
+ BROWSER_USE_HOME: browserUseHome(context.status),
390
+ PIBO_BROWSER_USE_SESSION: lease.sessionName,
391
+ PIBO_BROWSER_USE_CHROME_USER_DATA_DIR: lease.userDataDir,
392
+ PIBO_BROWSER_USE_DEFAULT_PROFILE: lease.profileName,
393
+ ...(lease.browserPoolLeaseId ? { PIBO_BROWSER_POOL_LEASE_ID: lease.browserPoolLeaseId } : {}),
394
+ };
395
+ return new Promise((resolve) => {
396
+ const child = spawn(wrapperPath, ['--session', lease.sessionName, '--pibo-ensure-chrome'], {
397
+ env,
398
+ stdio: ['ignore', 'pipe', 'pipe'],
399
+ });
400
+ let stdout = '';
401
+ let stderr = '';
402
+ child.stdout.on('data', (chunk) => { stdout += chunk; });
403
+ child.stderr.on('data', (chunk) => { stderr += chunk; });
404
+ const timer = setTimeout(() => {
405
+ child.kill('SIGTERM');
406
+ resolve({ success: false, error: `Warm-up timed out after ${timeoutMs}ms` });
407
+ }, timeoutMs);
408
+ child.on('error', (error) => {
409
+ clearTimeout(timer);
410
+ resolve({ success: false, error: error.message });
411
+ });
412
+ child.on('close', (code) => {
413
+ clearTimeout(timer);
414
+ if (code === 0) {
415
+ const cdpUrl = stdout.trim();
416
+ resolve({ success: true, cdpUrl: cdpUrl || undefined });
417
+ }
418
+ else {
419
+ resolve({ success: false, error: stderr || `Chrome start exited with code ${code}` });
420
+ }
421
+ });
266
422
  });
267
423
  }
424
+ async function reapStaleLeasesInRegistry(status, registry) {
425
+ let count = 0;
426
+ for (const lease of registry.leases) {
427
+ if (lease.status !== 'active' || !isExpired(lease))
428
+ continue;
429
+ if (lease.browserPoolLeaseId) {
430
+ await reapAssociatedBrowserPoolLeaseProcess(status, lease);
431
+ }
432
+ else if (leaseProcessIsAlive(status, lease)) {
433
+ killLeaseProcess(status, lease);
434
+ }
435
+ lease.status = 'released';
436
+ lease.updatedAt = nowIso();
437
+ count += 1;
438
+ }
439
+ return count;
440
+ }
268
441
  export async function listBrowserUseLeases(context, json = false) {
442
+ let reapedCount = 0;
443
+ // Auto-reap stale leases before listing
444
+ await withRegistryLock(context.status, async () => {
445
+ const registry = readRegistry(context.status);
446
+ reapedCount = await reapStaleLeasesInRegistry(context.status, registry);
447
+ if (reapedCount > 0) {
448
+ await writeRegistry(context.status, registry);
449
+ }
450
+ });
269
451
  const registry = readRegistry(context.status);
270
452
  const rows = registry.leases.map((lease) => ({
271
453
  ...lease,
@@ -282,7 +464,7 @@ export async function listBrowserUseLeases(context, json = false) {
282
464
  }
283
465
  for (const row of rows) {
284
466
  const state = row.status === 'active' && !row.expired ? 'active' : row.expired ? 'expired' : row.status;
285
- console.log(`${row.id}\t${state}\t${row.owner}\t${row.sessionName}\t${row.userDataDir}`);
467
+ console.log(`${row.id}\t${state}\t${row.holder}\t${row.sessionName}\t${row.userDataDir}`);
286
468
  }
287
469
  }
288
470
  export async function releaseBrowserUseLease(context, id, options = {}) {
@@ -297,7 +479,12 @@ export async function releaseBrowserUseLease(context, id, options = {}) {
297
479
  suggestion: 'Run `pibo tools browser-use lease list`.',
298
480
  }));
299
481
  }
300
- killLeaseProcess(context.status, lease);
482
+ if (lease.browserPoolLeaseId) {
483
+ await releaseAssociatedBrowserPoolLease(context.status, lease);
484
+ }
485
+ else {
486
+ killLeaseProcess(context.status, lease);
487
+ }
301
488
  lease.status = 'released';
302
489
  lease.updatedAt = nowIso();
303
490
  if (options.deleteProfile) {
@@ -310,16 +497,7 @@ export async function releaseBrowserUseLease(context, id, options = {}) {
310
497
  export async function reapStaleBrowserUseLeases(context) {
311
498
  await withRegistryLock(context.status, async () => {
312
499
  const registry = readRegistry(context.status);
313
- let count = 0;
314
- for (const lease of registry.leases) {
315
- if (lease.status !== 'active' || !isExpired(lease))
316
- continue;
317
- if (leaseProcessIsAlive(context.status, lease))
318
- killLeaseProcess(context.status, lease);
319
- lease.status = 'released';
320
- lease.updatedAt = nowIso();
321
- count += 1;
322
- }
500
+ const count = await reapStaleLeasesInRegistry(context.status, registry);
323
501
  await writeRegistry(context.status, registry);
324
502
  console.log(`Reaped ${count} stale browser-use auth lease${count === 1 ? '' : 's'}`);
325
503
  });