@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
@@ -0,0 +1,13 @@
1
+ export class CliSourceError extends Error {
2
+ code;
3
+ cause;
4
+ constructor(code, message, options = {}) {
5
+ super(message);
6
+ this.name = "CliSourceError";
7
+ this.code = code;
8
+ this.cause = options.cause;
9
+ }
10
+ }
11
+ export function isCliSourceError(error) {
12
+ return error instanceof CliSourceError;
13
+ }
package/dist/cli.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { Command } from "commander";
2
- import { DEFAULT_PIBO_CONFIG_PATH, PIBO_CONFIG_KEYS, deletePiboConfigValue, getDisplayPiboConfigValue, loadPiboConfig, redactPiboConfig, savePiboConfig, setPiboConfigValue, } from "./config/config.js";
2
+ import { PIBO_CONFIG_KEYS, getDefaultPiboConfigPath, deletePiboConfigValue, getDisplayPiboConfigValue, loadPiboConfig, redactPiboConfig, savePiboConfig, setPiboConfigValue, } from "./config/config.js";
3
3
  import { parsePiboThinkingLevel } from "./core/thinking.js";
4
4
  async function createCliProfile(profileName) {
5
- const { createDefaultPiboPluginRegistry, createGatewayProducerPiboProfile } = await import("./plugins/builtin.js");
5
+ const { createDefaultPiboPluginRegistry, createGatewayProducerPiboProfile, createPiboProfileFromRegistryOrDefault } = await import("./plugins/builtin.js");
6
6
  if (profileName === "gateway-producer" || profileName === "pibo-gateway-producer") {
7
7
  return createGatewayProducerPiboProfile();
8
8
  }
9
- return createDefaultPiboPluginRegistry().createProfile(profileName ?? "pibo-minimal");
9
+ return createPiboProfileFromRegistryOrDefault(createDefaultPiboPluginRegistry(), profileName);
10
10
  }
11
11
  function printJson(value) {
12
12
  console.log(JSON.stringify(value, null, 2));
@@ -30,6 +30,13 @@ function parsePort(value) {
30
30
  }
31
31
  return port;
32
32
  }
33
+ function parsePositiveInteger(value) {
34
+ const parsed = Number(value);
35
+ if (!Number.isInteger(parsed) || parsed < 1) {
36
+ throw new Error("Value must be a positive integer");
37
+ }
38
+ return parsed;
39
+ }
33
40
  export async function runPiboCli(argv = process.argv) {
34
41
  if (argv[2] === "--help" || argv[2] === "-h") {
35
42
  printRootDiscovery();
@@ -55,10 +62,50 @@ export async function runPiboCli(argv = process.argv) {
55
62
  await runDebugCli([argv[0] ?? "node", "pibo debug", ...argv.slice(3)]);
56
63
  return;
57
64
  }
65
+ if (argv[2] === "data") {
66
+ const { runDataCli } = await import("./data/cli.js");
67
+ await runDataCli([argv[0] ?? "node", "pibo data", ...argv.slice(3)]);
68
+ return;
69
+ }
70
+ if (argv[2] === "gateway") {
71
+ const { runGatewayCli } = await import("./gateway/cli.js");
72
+ await runGatewayCli(argv);
73
+ return;
74
+ }
75
+ if (argv[2] === "compute") {
76
+ const { runComputeCli } = await import("./compute/cli.js");
77
+ await runComputeCli([argv[0] ?? "node", "pibo compute", ...argv.slice(3)]);
78
+ return;
79
+ }
80
+ if (argv[2] === "setup") {
81
+ const { runSetupCli } = await import("./setup/cli.js");
82
+ await runSetupCli([argv[0] ?? "node", "pibo setup", ...argv.slice(3)]);
83
+ return;
84
+ }
85
+ if (argv[2] === "skills") {
86
+ const { runSkillsCli } = await import("./skills/cli.js");
87
+ await runSkillsCli([argv[0] ?? "node", "pibo skills", ...argv.slice(3)]);
88
+ return;
89
+ }
90
+ if (argv[2] === "cron") {
91
+ const { runCronCli } = await import("./cron/cli.js");
92
+ await runCronCli([argv[0] ?? "node", "pibo cron", ...argv.slice(3)]);
93
+ return;
94
+ }
95
+ if (argv[2] === "ralph") {
96
+ const { runRalphCli } = await import("./ralph/cli.js");
97
+ await runRalphCli([argv[0] ?? "node", "pibo ralph", ...argv.slice(3)]);
98
+ return;
99
+ }
58
100
  if (argv[2] === "config" && (argv[3] === "--help" || argv[3] === "-h" || argv.length === 3)) {
59
101
  printConfigDiscovery();
60
102
  return;
61
103
  }
104
+ if (argv[2] === "tui:sessions" && (argv[3] === "--help" || argv[3] === "-h")) {
105
+ const { cliSessionsHelpText } = await import("./apps/cli-ui/index.js");
106
+ console.log(cliSessionsHelpText());
107
+ return;
108
+ }
62
109
  const program = new Command();
63
110
  program.name("pibo").description("Agent-oriented CLI for Pibo").helpOption(false).showHelpAfterError();
64
111
  program
@@ -105,7 +152,73 @@ export async function runPiboCli(argv = process.argv) {
105
152
  const { runDebugCli } = await import("./debug/index.js");
106
153
  await runDebugCli([argv[0] ?? "node", "pibo debug", ...args]);
107
154
  });
108
- const config = program.command("config").description(`Manage pibo config at ${DEFAULT_PIBO_CONFIG_PATH}`).helpOption(false);
155
+ program
156
+ .command("data")
157
+ .description("Inspect and maintain Pibo data stores")
158
+ .helpOption(false)
159
+ .allowUnknownOption(true)
160
+ .allowExcessArguments(true)
161
+ .argument("[args...]")
162
+ .action(async (args) => {
163
+ const { runDataCli } = await import("./data/cli.js");
164
+ await runDataCli([argv[0] ?? "node", "pibo data", ...args]);
165
+ });
166
+ program
167
+ .command("compute")
168
+ .description("Manage Pibo Docker compute workers")
169
+ .helpOption(false)
170
+ .allowUnknownOption(true)
171
+ .allowExcessArguments(true)
172
+ .argument("[args...]")
173
+ .action(async (args) => {
174
+ const { runComputeCli } = await import("./compute/cli.js");
175
+ await runComputeCli([argv[0] ?? "node", "pibo compute", ...args]);
176
+ });
177
+ program
178
+ .command("setup")
179
+ .description("Plan user-host installs and developer-host upgrades")
180
+ .helpOption(false)
181
+ .allowUnknownOption(true)
182
+ .allowExcessArguments(true)
183
+ .argument("[args...]")
184
+ .action(async (args) => {
185
+ const { runSetupCli } = await import("./setup/cli.js");
186
+ await runSetupCli([argv[0] ?? "node", "pibo setup", ...args]);
187
+ });
188
+ program
189
+ .command("skills")
190
+ .description("Manage Pibo user skills")
191
+ .helpOption(false)
192
+ .allowUnknownOption(true)
193
+ .allowExcessArguments(true)
194
+ .argument("[args...]")
195
+ .action(async (args) => {
196
+ const { runSkillsCli } = await import("./skills/cli.js");
197
+ await runSkillsCli([argv[0] ?? "node", "pibo skills", ...args]);
198
+ });
199
+ program
200
+ .command("cron")
201
+ .description("Manage scheduled Pibo jobs")
202
+ .helpOption(false)
203
+ .allowUnknownOption(true)
204
+ .allowExcessArguments(true)
205
+ .argument("[args...]")
206
+ .action(async (args) => {
207
+ const { runCronCli } = await import("./cron/cli.js");
208
+ await runCronCli([argv[0] ?? "node", "pibo cron", ...args]);
209
+ });
210
+ program
211
+ .command("ralph")
212
+ .description("Manage continuous Ralph jobs")
213
+ .helpOption(false)
214
+ .allowUnknownOption(true)
215
+ .allowExcessArguments(true)
216
+ .argument("[args...]")
217
+ .action(async (args) => {
218
+ const { runRalphCli } = await import("./ralph/cli.js");
219
+ await runRalphCli([argv[0] ?? "node", "pibo ralph", ...args]);
220
+ });
221
+ const config = program.command("config").description(`Manage pibo config at ${getDefaultPiboConfigPath()}`).helpOption(false);
109
222
  config.action(() => {
110
223
  printConfigDiscovery();
111
224
  });
@@ -167,6 +280,7 @@ export async function runPiboCli(argv = process.argv) {
167
280
  });
168
281
  program
169
282
  .command("tui:routed")
283
+ .helpOption("-h, --help", "Display help for command")
170
284
  .option("--show-thinking", "Show routed thinking deltas in the local TUI")
171
285
  .option("--thinking <level>", "Set routed thinking level: off, minimal, low, medium, high, xhigh", parsePiboThinkingLevel)
172
286
  .argument("[profile]")
@@ -179,6 +293,20 @@ export async function runPiboCli(argv = process.argv) {
179
293
  thinkingLevel: options.thinking,
180
294
  });
181
295
  });
296
+ program
297
+ .command("tui:sessions")
298
+ .description("Start the reduced Web Chat-derived session UI")
299
+ .option("--session <id>", "Open a specific Pibo session id")
300
+ .option("--max-rows <count>", "Limit rendered transcript rows", parsePositiveInteger)
301
+ .option("--demo", "Use deterministic fake session data for smoke testing")
302
+ .action(async (options) => {
303
+ const { runCliSessionsUi } = await import("./apps/cli-ui/index.js");
304
+ await runCliSessionsUi({
305
+ initialSessionId: options.session,
306
+ maxRows: options.maxRows,
307
+ useFakeSource: options.demo === true,
308
+ });
309
+ });
182
310
  program
183
311
  .command("router")
184
312
  .argument("[piboSessionId]", "Pibo session id", "demo")
@@ -194,13 +322,6 @@ export async function runPiboCli(argv = process.argv) {
194
322
  printJson(event);
195
323
  await router.disposeAll();
196
324
  });
197
- program
198
- .command("gateway")
199
- .description("Start the local pibo gateway daemon")
200
- .action(async () => {
201
- const { runGatewayServer } = await import("./gateway/server.js");
202
- await runGatewayServer();
203
- });
204
325
  program
205
326
  .command("gateway:web")
206
327
  .description("Start the authenticated web gateway")
@@ -238,18 +359,25 @@ Commands:
238
359
  tools Install and inspect curated external CLI tools
239
360
  pi-packages Register Pi Coding Agent packages
240
361
  debug Inspect local Pibo data
362
+ data Inspect and maintain Pibo data stores
363
+ compute Manage Pibo Docker compute workers
364
+ setup Plan user-host installs and developer-host upgrades
365
+ skills Manage Pibo user skills
366
+ cron Manage scheduled Pibo jobs
367
+ ralph Manage continuous Ralph jobs
241
368
  profile Inspect a pibo profile
242
369
  tui Start the direct Pi TUI
243
370
  tui:routed Start the local routed Pibo TUI
244
- gateway Start the local gateway daemon
245
- gateway:web Start the authenticated web gateway
371
+ tui:sessions Start the reduced Web Chat-derived session UI
372
+ gateway Inspect and restart host gateways through safe CLI commands
373
+ gateway:web Start a web gateway runtime
246
374
 
247
375
  Next:
248
376
  pibo <command> --help
249
377
  `;
250
378
  }
251
379
  function printConfigDiscoveryText() {
252
- return `pibo config - local config at ${DEFAULT_PIBO_CONFIG_PATH}
380
+ return `pibo config - local config at ${getDefaultPiboConfigPath()}
253
381
 
254
382
  Commands:
255
383
  keys List supported config keys
@@ -0,0 +1,415 @@
1
+ import { Command } from "commander";
2
+ import { IMAGE_NAME, imageExists, shouldRebuild, shouldRebuildDeps, dockerBuild, saveHash, saveDepHash, spawnWorker, spawnDevWorker, listWorkers, releaseWorker, planReapWorkers, applyComputeWorkerReapPlan, getComputeDiskDiagnostics, } from "./docker.js";
3
+ import { getComputeResourceHealth } from "./resource-health.js";
4
+ import { mkdir } from "node:fs/promises";
5
+ import path from "node:path";
6
+ import os from "node:os";
7
+ const WORKSPACE_DIR = process.env.PIBO_COMPUTE_WORKSPACE || process.cwd();
8
+ const HASH_FILE = path.join(os.homedir(), ".pibo", "compute-image-hash");
9
+ const DEP_HASH_FILE = path.join(os.homedir(), ".pibo", "compute-dep-hash");
10
+ function printJson(value) {
11
+ console.log(JSON.stringify(value, null, 2));
12
+ }
13
+ function parsePositiveIntegerOption(value) {
14
+ if (value === undefined || value.trim() === "")
15
+ return undefined;
16
+ const parsed = Number(value);
17
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
18
+ }
19
+ function hostPort(value) {
20
+ if (!value || value === "-")
21
+ return undefined;
22
+ const first = value.split(",")[0] ?? value;
23
+ return first.includes(":") ? first.split(":").pop() : first;
24
+ }
25
+ function formatPorts(worker, verbose = false) {
26
+ if (verbose)
27
+ return worker.ports || "-";
28
+ const preferred = [
29
+ ["gw", worker.portMap["4789/tcp"] ?? worker.portMap.gateway],
30
+ ["cdp", worker.portMap["56663/tcp"] ?? worker.portMap.cdp],
31
+ ["web", worker.portMap["4788/tcp"] ?? worker.portMap.web],
32
+ ["chat", worker.portMap["4790/tcp"] ?? worker.portMap.chatUi],
33
+ ["ctx", worker.portMap["4791/tcp"] ?? worker.portMap.contextFiles],
34
+ ];
35
+ const compact = preferred
36
+ .map(([label, value]) => {
37
+ const port = hostPort(value);
38
+ return port ? `${label}=${port}` : undefined;
39
+ })
40
+ .filter(Boolean);
41
+ if (compact.length > 0)
42
+ return compact.join(",");
43
+ const fallback = Object.entries(worker.portMap)
44
+ .slice(0, 4)
45
+ .map(([container, value]) => `${container.replace(/\/tcp$/, "")}=${hostPort(value) ?? value}`);
46
+ return fallback.length > 0 ? fallback.join(",") : worker.ports || "-";
47
+ }
48
+ function formatResourcePolicy(worker) {
49
+ const policy = worker.resourcePolicy;
50
+ if (!policy)
51
+ return "-";
52
+ const parts = [
53
+ policy.memory ? `mem=${policy.memory}` : undefined,
54
+ policy.pidsLimit !== undefined ? `pids=${policy.pidsLimit}` : undefined,
55
+ policy.shmSize ? `shm=${policy.shmSize}` : undefined,
56
+ ].filter(Boolean);
57
+ return parts.length ? parts.join(",") : "-";
58
+ }
59
+ function formatCleanup(worker) {
60
+ const prefix = worker.cleanupEligibility.eligible ? "eligible" : "skip";
61
+ return `${prefix}:${worker.cleanupEligibility.reasons.join("+") || "none"}`;
62
+ }
63
+ function formatComputeReapCommand(plan, apply) {
64
+ const args = ["pibo", "compute", "reap", apply ? "--apply" : "--dry-run", "--max-age-minutes", String(plan.options.maxAgeMinutes)];
65
+ if (plan.options.includeDev)
66
+ args.push("--include-dev");
67
+ if (!plan.options.includeStopped)
68
+ args.push("--no-stopped");
69
+ if (!plan.options.includeDirty)
70
+ args.push("--no-dirty");
71
+ return args.join(" ");
72
+ }
73
+ export function renderComputeWorkerListText(workers, options = {}) {
74
+ if (workers.length === 0) {
75
+ return [
76
+ options.all ? "No Pibo worker containers found." : "No worker containers running.",
77
+ "Next: pibo compute list --all --json",
78
+ "Next: pibo compute reap --help",
79
+ ].join("\n");
80
+ }
81
+ const lines = ["NAME\tROLE\tSTATE\tSTATUS\tOOM\tPORTS\tCREATED\tLAST_USED\tHOLDER\tWORKTREE\tRALPH_JOB\tRALPH_RUN\tRESOURCE\tCLEANUP"];
82
+ for (const w of workers) {
83
+ lines.push(`${w.name}\t${w.role}\t${w.state}\t${w.status}\t${w.oomKilled ? "yes" : "no"}\t${formatPorts(w, options.verbose === true)}\t${w.createdAt}\t${w.lastUsedAt ?? "-"}\t${w.holder ?? "-"}\t${w.worktree ?? "-"}\t${w.ralphJobId ?? "-"}\t${w.ralphRunId ?? "-"}\t${formatResourcePolicy(w)}\t${formatCleanup(w)}`);
84
+ }
85
+ lines.push(options.verbose ? "Next: pibo compute list --all --json" : "Next: pibo compute list --all --verbose for full Docker port bindings");
86
+ lines.push("Next: pibo compute list --all --json");
87
+ return lines.join("\n");
88
+ }
89
+ export function renderComputeReapPlanText(plan, options = {}) {
90
+ const mode = options.applied ? "apply" : "dry-run";
91
+ const lines = [`Compute reap ${mode}: ${plan.summary.selected} selected, ${plan.summary.skipped} skipped, ${plan.summary.worktreesPreserved} worktree(s) preserved`];
92
+ if (plan.items.length === 0) {
93
+ lines.push("No Pibo worker containers found.");
94
+ }
95
+ else {
96
+ lines.push("ACTION\tNAME\tROLE\tSTATE\tAGE_MIN\tREASONS\tSKIP_REASONS\tWORKTREE");
97
+ for (const item of plan.items) {
98
+ lines.push(`${item.action}\t${item.worker.name}\t${item.worker.role}\t${item.worker.state}\t${item.ageMinutes === undefined ? "-" : Math.floor(item.ageMinutes)}\t${item.reasons.join("+") || "-"}\t${item.skipReasons.join("+") || "-"}\t${item.preservesWorktree ? "preserve" : "-"}`);
99
+ }
100
+ }
101
+ if (plan.options.includeDev && plan.summary.selected > 0)
102
+ lines.push("WARNING: --include-dev selected dev workers. Review ports/worktrees and active Ralph jobs before applying.");
103
+ if (options.applied)
104
+ lines.push(`Removed: ${options.removed?.join(", ") || "none"}`);
105
+ else
106
+ lines.push(`Dry-run only. Apply equivalent plan with: ${formatComputeReapCommand(plan, true)}`);
107
+ lines.push(`Review equivalent dry-run with: ${formatComputeReapCommand(plan, false)}`);
108
+ lines.push("Worktrees are preserved; remove Git worktrees only with an explicit worktree cleanup command.");
109
+ lines.push(...plan.nextCommands.map((command) => `Next: ${command}`));
110
+ return lines.join("\n");
111
+ }
112
+ function formatMaybeBytes(bytes) {
113
+ return bytes === undefined ? "-" : String(bytes);
114
+ }
115
+ function severityRank(severity) {
116
+ if (severity === "critical")
117
+ return 2;
118
+ if (severity === "warning")
119
+ return 1;
120
+ return 0;
121
+ }
122
+ export function renderComputeResourceHealthText(health) {
123
+ const lines = [`Compute resource health: ${health.severity} (read-only)`];
124
+ lines.push(`Generated at: ${health.generatedAt}`);
125
+ lines.push(`Browser processes: ${health.browserProcesses.totalChromiumMainProcesses} main / ${health.browserProcesses.totalChromiumProcesses} total Chromium processes`);
126
+ if (health.browserProcesses.unassignedMainProcessDetails.length > 0) {
127
+ lines.push(`Unmanaged browser main processes: ${health.browserProcesses.unassignedMainProcessDetails.length}`);
128
+ lines.push("PID\tWORKER\tUSER_DATA_DIR\tCOMMAND");
129
+ for (const process of health.browserProcesses.unassignedMainProcessDetails.slice(0, 5)) {
130
+ lines.push(`${process.pid}\t${process.workerName ?? "-"}\t${process.userDataDir ?? "-"}\t${process.commandName}`);
131
+ }
132
+ lines.push("Inspect unmanaged browsers with: pibo compute health --json");
133
+ }
134
+ lines.push(`Active browser leases: ${health.browserLeases.active}`);
135
+ lines.push(`Stale CDP files: ${health.browserLeases.staleCdpFiles.pidFiles} pid, ${health.browserLeases.staleCdpFiles.portFiles} port`);
136
+ lines.push(`Compute workers: ${health.computeWorkers.total} total, ${health.computeWorkers.dirty} dirty, ${health.computeWorkers.oomKilled} OOM-killed, ${health.computeWorkers.cleanupEligible} cleanup-eligible`);
137
+ lines.push(`Docker disk: reclaimable=${formatMaybeBytes(health.dockerDisk.reclaimableBytes)} buildCache=${formatMaybeBytes(health.dockerDisk.buildCacheBytes)} pressure=${health.dockerDisk.pressure ? "yes" : "no"}`);
138
+ lines.push(`Reaper/timer: ${health.reaperTimers.status}${health.reaperTimers.details ? ` - ${health.reaperTimers.details}` : ""}`);
139
+ if (health.browserProcesses.perWorker.length > 0) {
140
+ lines.push("Browser pools:");
141
+ lines.push("WORKER POOL STATE PID ACTIVE_LEASES MAIN_PROCESSES SEVERITY");
142
+ for (const pool of health.browserProcesses.perWorker) {
143
+ lines.push(`${pool.workerId}\t${pool.poolId}\t${pool.state}\t${pool.pid ?? "-"}\t${pool.activeLeaseCount}\t${pool.browserMainProcessCount}\t${pool.severity}`);
144
+ }
145
+ }
146
+ lines.push("Checks:");
147
+ for (const check of [...health.checks].sort((a, b) => severityRank(b.severity) - severityRank(a.severity))) {
148
+ lines.push(`- [${check.severity}] ${check.id}: ${check.message}`);
149
+ for (const command of check.nextCommands)
150
+ lines.push(` Next: ${command}`);
151
+ }
152
+ lines.push("Next commands:");
153
+ for (const command of health.nextCommands.slice(0, 8))
154
+ lines.push(`- ${command}`);
155
+ return lines.join("\n");
156
+ }
157
+ export function renderComputeDiskDiagnosticsText(diagnostics) {
158
+ const lines = ["Compute disk diagnostics (read-only)"];
159
+ if (!diagnostics.dockerAvailable) {
160
+ lines.push(`Docker unavailable: ${diagnostics.dockerError ?? "unknown error"}`);
161
+ lines.push("Next: ensure Docker is installed and the daemon is reachable, then run pibo compute diagnostics --json");
162
+ return lines.join("\n");
163
+ }
164
+ if (diagnostics.rows.length === 0) {
165
+ lines.push("Docker reported no disk usage rows.");
166
+ }
167
+ else {
168
+ lines.push("TYPE\tCOUNT\tACTIVE\tSIZE\tSIZE_BYTES\tRECLAIMABLE\tRECLAIMABLE_BYTES");
169
+ for (const row of diagnostics.rows) {
170
+ lines.push(`${row.label}\t${row.totalCount ?? "-"}\t${row.active ?? "-"}\t${row.size || "-"}\t${formatMaybeBytes(row.sizeBytes)}\t${row.reclaimable || "-"}\t${formatMaybeBytes(row.reclaimableBytes)}`);
171
+ }
172
+ }
173
+ lines.push(`Total bytes: ${formatMaybeBytes(diagnostics.totals.sizeBytes)}`);
174
+ lines.push(`Reclaimable bytes: ${formatMaybeBytes(diagnostics.totals.reclaimableBytes)}`);
175
+ lines.push("Cleanup suggestions:");
176
+ for (const suggestion of diagnostics.suggestions) {
177
+ lines.push(`- ${suggestion.kind}: ${suggestion.reason}`);
178
+ for (const command of suggestion.nextCommands)
179
+ lines.push(` Next: ${command}`);
180
+ }
181
+ return lines.join("\n");
182
+ }
183
+ export async function runComputeCli(argv) {
184
+ const program = new Command();
185
+ program
186
+ .name("pibo compute")
187
+ .description("Manage isolated Docker workers for Pibo development and testing")
188
+ .helpOption("-h, --help", "Show help")
189
+ .showHelpAfterError()
190
+ .helpCommand("help [command]", "Show help for command")
191
+ .addHelpText("after", `
192
+ Examples:
193
+ $ pibo compute spawn
194
+ $ pibo compute dev spawn --worktree my-fix
195
+ $ pibo compute list
196
+ $ pibo compute release pibo-worker-abc123
197
+
198
+ Next:
199
+ $ pibo compute spawn --help
200
+ $ pibo compute dev --help
201
+ `);
202
+ program
203
+ .command("spawn")
204
+ .description("Create a one-time worker from the current Docker image")
205
+ .option("--name <name>", "Set the container name")
206
+ .option("--holder <holder>", "Tag the container holder")
207
+ .option("--ttl-seconds <n>", "Tag the worker TTL in seconds")
208
+ .option("--idle-seconds <n>", "Tag the worker idle retention in seconds")
209
+ .option("--ralph-job-id <id>", "Tag the Ralph job id when this worker is Ralph-owned")
210
+ .option("--ralph-run-id <id>", "Tag the Ralph run id when this worker is Ralph-owned")
211
+ .addHelpText("after", `
212
+ Creates a worker container and starts the gateway. Prints JSON with the container id and mapped ports.
213
+
214
+ Use this for quick isolated checks. For code changes, prefer:
215
+ $ pibo compute dev spawn --worktree my-fix
216
+ `)
217
+ .action(async (options) => {
218
+ await mkdir(path.dirname(HASH_FILE), { recursive: true });
219
+ const needsBuild = !(await imageExists(IMAGE_NAME)) || (await shouldRebuild(WORKSPACE_DIR, HASH_FILE));
220
+ if (needsBuild) {
221
+ console.error(`Building ${IMAGE_NAME} from ${WORKSPACE_DIR}...`);
222
+ await dockerBuild(WORKSPACE_DIR);
223
+ await saveHash(WORKSPACE_DIR, HASH_FILE);
224
+ console.error("Build complete.");
225
+ }
226
+ const worker = await spawnWorker({
227
+ workspaceDir: WORKSPACE_DIR,
228
+ name: options.name,
229
+ holder: options.holder,
230
+ ttlSeconds: parsePositiveIntegerOption(options.ttlSeconds),
231
+ idleSeconds: parsePositiveIntegerOption(options.idleSeconds),
232
+ ralphJobId: options.ralphJobId,
233
+ ralphRunId: options.ralphRunId,
234
+ });
235
+ printJson(worker);
236
+ });
237
+ const devCmd = program
238
+ .command("dev")
239
+ .description("Manage development workers with Git worktrees")
240
+ .helpCommand("help [command]", "Show help for command")
241
+ .addHelpText("after", `
242
+ Use dev workers for Pibo code changes. Each worker gets its own Git worktree and port block.
243
+
244
+ Next:
245
+ $ pibo compute dev spawn --help
246
+ `);
247
+ devCmd
248
+ .command("spawn")
249
+ .description("Create a development worker with a Git worktree")
250
+ .requiredOption("--worktree <name>", "Name the Git worktree and branch")
251
+ .option("--repo <path>", "Use this repository", WORKSPACE_DIR)
252
+ .option("--holder <holder>", "Tag the container holder")
253
+ .option("--ttl-seconds <n>", "Tag the worker TTL in seconds")
254
+ .option("--idle-seconds <n>", "Tag the worker idle retention in seconds")
255
+ .option("--ralph-job-id <id>", "Tag the Ralph job id when this worker is Ralph-owned")
256
+ .option("--ralph-run-id <id>", "Tag the Ralph run id when this worker is Ralph-owned")
257
+ .addHelpText("after", `
258
+ Creates .worktrees/<name>, starts a worker, and prints JSON with ports and the worktree path.
259
+
260
+ Example:
261
+ $ pibo compute dev spawn --worktree my-fix
262
+ `)
263
+ .action(async (options) => {
264
+ await mkdir(path.dirname(DEP_HASH_FILE), { recursive: true });
265
+ console.error("[pibo compute] Checking Docker image status...");
266
+ const needsBuild = !(await imageExists(IMAGE_NAME)) || (await shouldRebuildDeps(options.repo, DEP_HASH_FILE));
267
+ if (needsBuild) {
268
+ console.error(`[pibo compute] Dependencies changed (package.json, package-lock.json, or Dockerfile).`);
269
+ console.error(`[pibo compute] Rebuilding Docker image ${IMAGE_NAME} — this takes 1-2 minutes...`);
270
+ await dockerBuild(options.repo);
271
+ await saveDepHash(options.repo, DEP_HASH_FILE);
272
+ console.error("[pibo compute] Docker image build complete.");
273
+ }
274
+ else {
275
+ console.error("[pibo compute] Using cached Docker image (dependencies unchanged).");
276
+ }
277
+ console.error(`[pibo compute] Creating git worktree '${options.worktree}'...`);
278
+ const worker = await spawnDevWorker({
279
+ repoDir: options.repo,
280
+ worktreeName: options.worktree,
281
+ holder: options.holder,
282
+ ttlSeconds: parsePositiveIntegerOption(options.ttlSeconds),
283
+ idleSeconds: parsePositiveIntegerOption(options.idleSeconds),
284
+ ralphJobId: options.ralphJobId,
285
+ ralphRunId: options.ralphRunId,
286
+ });
287
+ console.error(`[pibo compute] Dev container '${worker.id}' started.`);
288
+ console.error(`[pibo compute] Ports: gateway=${worker.gatewayPort}, cdp=${worker.cdpPort}, web=${worker.webPort}, chat-ui=${worker.webUIPortChat}, context-files=${worker.webUIPortContext}`);
289
+ console.error(`[pibo compute] Worktree: ${worker.worktree}`);
290
+ console.error(`[pibo compute] Connect: ${worker.connect}`);
291
+ printJson(worker);
292
+ });
293
+ program
294
+ .command("rebuild")
295
+ .description("Rebuild the pibo:latest Docker image")
296
+ .addHelpText("after", `
297
+ Rebuilds from the current workspace and refreshes compute image hashes.
298
+ `)
299
+ .action(async () => {
300
+ console.error(`Rebuilding ${IMAGE_NAME} from ${WORKSPACE_DIR}...`);
301
+ await dockerBuild(WORKSPACE_DIR);
302
+ await saveHash(WORKSPACE_DIR, HASH_FILE);
303
+ await saveDepHash(WORKSPACE_DIR, DEP_HASH_FILE);
304
+ console.error("Build complete.");
305
+ });
306
+ program
307
+ .command("list")
308
+ .description("List Pibo worker and dev-worker containers")
309
+ .option("--all", "Include stopped, exited, dead, and restarting Pibo workers")
310
+ .option("--json", "Print machine-readable worker metadata")
311
+ .option("--verbose", "Show full Docker port bindings in text output")
312
+ .addHelpText("after", `
313
+ Shows each worker's name, role, status, mapped ports, creation time, holder, and Ralph labels when present.
314
+
315
+ Next:
316
+ $ pibo compute list --all --json
317
+ `)
318
+ .action(async (options) => {
319
+ const workers = await listWorkers({ all: options.all === true });
320
+ if (options.json) {
321
+ printJson({ workers });
322
+ return;
323
+ }
324
+ console.log(renderComputeWorkerListText(workers, { all: options.all === true, verbose: options.verbose === true }));
325
+ });
326
+ program
327
+ .command("health")
328
+ .alias("doctor")
329
+ .description("Show read-only compute, browser, Docker, and reaper resource health")
330
+ .option("--json", "Print machine-readable resource health")
331
+ .option("--browser-pool-root <path>", "Browser pool root directory to scan")
332
+ .option("--browser-use-home <path>", "Browser-use home directory to scan for stale CDP files")
333
+ .addHelpText("after", `
334
+ Reports browser main-process counts, active browser-pool leases, stale CDP files, dirty/OOM workers, Docker disk pressure, and reaper/timer status.
335
+ The command is read-only and never reaps, prunes, stops, or removes resources.
336
+
337
+ Next:
338
+ $ pibo compute health --json
339
+ $ pibo tools browser-use pool reap --json
340
+ $ pibo compute reap --dry-run --json
341
+ `)
342
+ .action(async (options) => {
343
+ const health = await getComputeResourceHealth({ browserPoolRoot: options.browserPoolRoot, browserUseHome: options.browserUseHome });
344
+ if (options.json) {
345
+ printJson(health);
346
+ return;
347
+ }
348
+ console.log(renderComputeResourceHealthText(health));
349
+ });
350
+ program
351
+ .command("diagnostics")
352
+ .alias("disk")
353
+ .description("Show read-only Docker disk and build-cache diagnostics")
354
+ .option("--json", "Print machine-readable disk diagnostics")
355
+ .addHelpText("after", `
356
+ Reports Docker image, container, local volume, and build-cache usage without pruning anything.
357
+ Cleanup suggestions distinguish compute containers, images, build cache, and Git worktrees.
358
+
359
+ Next:
360
+ $ pibo compute diagnostics --json
361
+ $ pibo compute reap --dry-run --json
362
+ `)
363
+ .action(async (options) => {
364
+ const diagnostics = await getComputeDiskDiagnostics();
365
+ if (options.json) {
366
+ printJson(diagnostics);
367
+ return;
368
+ }
369
+ console.log(renderComputeDiskDiagnosticsText(diagnostics));
370
+ });
371
+ program
372
+ .command("release")
373
+ .description("Stop and remove a worker container")
374
+ .argument("<id>", "Container name or ID")
375
+ .addHelpText("after", `
376
+ Use the name or id shown by:
377
+ $ pibo compute list
378
+ `)
379
+ .action(async (id) => {
380
+ await releaseWorker(id);
381
+ console.log(`Released ${id}`);
382
+ });
383
+ program
384
+ .command("reap")
385
+ .description("Preview or apply compute worker container cleanup")
386
+ .option("--max-age-minutes <n>", "Select workers older than this many minutes", "60")
387
+ .option("--include-dev", "Also select dev-worker containers; dev workers are skipped by default")
388
+ .option("--no-stopped", "Do not select stopped, dead, created, or restarting containers")
389
+ .option("--no-dirty", "Do not select dirty or OOM-killed containers")
390
+ .option("--dry-run", "Preview the cleanup plan without removing containers")
391
+ .option("--apply", "Apply the cleanup plan and remove selected containers")
392
+ .option("--json", "Print machine-readable cleanup plan/result")
393
+ .addHelpText("after", `
394
+ Defaults to a dry-run plan for one-time workers. Dev workers require --include-dev.
395
+ Stopped, dirty/OOM, and old workers are selected unless disabled by selector flags.
396
+ Worktrees are preserved; container cleanup never deletes Git worktrees.
397
+ `)
398
+ .action(async (options) => {
399
+ const maxAge = Number(options.maxAgeMinutes);
400
+ const plan = await planReapWorkers({
401
+ includeDev: options.includeDev === true,
402
+ includeStopped: options.stopped !== false,
403
+ includeDirty: options.dirty !== false,
404
+ maxAgeMinutes: Number.isFinite(maxAge) ? maxAge : 60,
405
+ });
406
+ const shouldApply = options.apply === true;
407
+ const removed = shouldApply ? await applyComputeWorkerReapPlan(plan) : [];
408
+ if (options.json) {
409
+ printJson({ dryRun: !shouldApply, applied: shouldApply, removed, plan });
410
+ return;
411
+ }
412
+ console.log(renderComputeReapPlanText(plan, { applied: shouldApply, removed }));
413
+ });
414
+ await program.parseAsync(argv);
415
+ }