@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,349 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { mkdirSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
+ import { DatabaseSync } from "node:sqlite";
5
+ import { piboHomePath } from "../core/pibo-home.js";
6
+ import { computeNextRunAt, validateSchedule } from "./schedule.js";
7
+ function nowIso(now = new Date()) {
8
+ return now.toISOString();
9
+ }
10
+ function parseJson(json) {
11
+ return JSON.parse(json);
12
+ }
13
+ function jobFromRow(row) {
14
+ return {
15
+ id: row.id,
16
+ name: row.name,
17
+ description: row.description ?? undefined,
18
+ enabled: row.enabled === 1,
19
+ target: parseTarget(row.target_json),
20
+ profile: row.profile,
21
+ prompt: row.prompt,
22
+ schedule: parseJson(row.schedule_json),
23
+ scheduleUi: row.schedule_ui_json ? parseJson(row.schedule_ui_json) : undefined,
24
+ deleteAfterRun: row.delete_after_run === 1,
25
+ state: parseJson(row.state_json),
26
+ createdAt: row.created_at,
27
+ updatedAt: row.updated_at,
28
+ };
29
+ }
30
+ function runFromRow(row) {
31
+ return {
32
+ id: row.id,
33
+ jobId: row.job_id,
34
+ piboSessionId: row.pibo_session_id ?? undefined,
35
+ status: row.status,
36
+ reason: row.reason ?? undefined,
37
+ error: row.error ?? undefined,
38
+ startedAt: row.started_at ?? undefined,
39
+ completedAt: row.completed_at ?? undefined,
40
+ createdAt: row.created_at,
41
+ updatedAt: row.updated_at,
42
+ };
43
+ }
44
+ function defaultName(prompt) {
45
+ const normalized = prompt.replace(/\s+/g, " ").trim();
46
+ return normalized ? normalized.slice(0, 80) : "Scheduled job";
47
+ }
48
+ function normalizeTarget(target) {
49
+ if (target.kind === "room")
50
+ return { kind: "room", roomId: String(target.roomId ?? "").trim() };
51
+ return { kind: "default-chat" };
52
+ }
53
+ function parseTarget(json) {
54
+ return normalizeTarget(parseJson(json));
55
+ }
56
+ function targetJson(target) {
57
+ return JSON.stringify(normalizeTarget(target));
58
+ }
59
+ function validateJobInput(input) {
60
+ if (!input.profile.trim())
61
+ throw new Error("profile is required");
62
+ if (!input.prompt.trim())
63
+ throw new Error("prompt is required");
64
+ if (input.target.kind === "room" && !input.target.roomId.trim())
65
+ throw new Error("target.roomId is required");
66
+ validateSchedule(input.schedule);
67
+ }
68
+ export class PiboCronStore {
69
+ db;
70
+ constructor(options = {}) {
71
+ const dbPath = options.path ?? piboHomePath("pibo-cron.sqlite");
72
+ const resolved = dbPath === ":memory:" ? dbPath : resolve(dbPath);
73
+ if (resolved !== ":memory:")
74
+ mkdirSync(dirname(resolved), { recursive: true });
75
+ this.db = new DatabaseSync(resolved);
76
+ this.db.exec("PRAGMA busy_timeout = 5000");
77
+ this.db.exec("PRAGMA foreign_keys = ON");
78
+ if (resolved !== ":memory:")
79
+ this.db.exec("PRAGMA journal_mode = WAL");
80
+ this.applySchema();
81
+ }
82
+ close() {
83
+ this.db.close();
84
+ }
85
+ createJob(input, now = new Date()) {
86
+ const target = normalizeTarget(input.target);
87
+ validateJobInput({ ...input, target });
88
+ const timestamp = nowIso(now);
89
+ const nextRunAt = input.enabled === false ? undefined : computeNextRunAt(input.schedule, now)?.toISOString();
90
+ if (input.enabled !== false && !nextRunAt)
91
+ throw new Error("schedule has no future run");
92
+ const job = {
93
+ id: `cron_${randomUUID()}`,
94
+ name: (input.name ?? defaultName(input.prompt)).trim(),
95
+ description: input.description?.trim() || undefined,
96
+ enabled: input.enabled !== false,
97
+ target,
98
+ profile: input.profile,
99
+ prompt: input.prompt,
100
+ schedule: input.schedule,
101
+ scheduleUi: input.scheduleUi,
102
+ deleteAfterRun: input.deleteAfterRun === true,
103
+ state: { nextRunAt },
104
+ createdAt: timestamp,
105
+ updatedAt: timestamp,
106
+ };
107
+ this.insertJob(job);
108
+ return this.getJob(job.id);
109
+ }
110
+ getJob(id) {
111
+ const row = this.db.prepare("SELECT * FROM pibo_cron_jobs WHERE id = ?").get(id);
112
+ return row ? jobFromRow(row) : undefined;
113
+ }
114
+ listJobs(input = {}) {
115
+ const clauses = [];
116
+ const values = [];
117
+ if (!input.includeDisabled)
118
+ clauses.push("enabled = 1");
119
+ const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
120
+ return this.db.prepare(`SELECT * FROM pibo_cron_jobs ${where} ORDER BY updated_at DESC, id ASC`).all(...values).map(jobFromRow);
121
+ }
122
+ updateJob(id, patch, now = new Date()) {
123
+ const existing = this.getJob(id);
124
+ if (!existing)
125
+ return undefined;
126
+ const nextTarget = patch.target ? normalizeTarget(patch.target) : existing.target;
127
+ const next = {
128
+ ...existing,
129
+ ...patch,
130
+ name: patch.name !== undefined ? patch.name.trim() : existing.name,
131
+ description: patch.description !== undefined ? patch.description?.trim() || undefined : existing.description,
132
+ enabled: patch.enabled ?? existing.enabled,
133
+ target: nextTarget,
134
+ profile: patch.profile ?? existing.profile,
135
+ prompt: patch.prompt ?? existing.prompt,
136
+ schedule: patch.schedule ?? existing.schedule,
137
+ scheduleUi: patch.scheduleUi ?? existing.scheduleUi,
138
+ deleteAfterRun: patch.deleteAfterRun ?? existing.deleteAfterRun,
139
+ updatedAt: nowIso(now),
140
+ };
141
+ validateJobInput(next);
142
+ next.state = {
143
+ ...existing.state,
144
+ runningAt: existing.state.runningAt,
145
+ nextRunAt: next.enabled ? computeNextRunAt(next.schedule, now)?.toISOString() : undefined,
146
+ };
147
+ if (next.enabled && !next.state.nextRunAt && next.schedule.kind !== "at")
148
+ throw new Error("schedule has no future run");
149
+ this.writeJob(next);
150
+ return this.getJob(id);
151
+ }
152
+ removeJob(id) {
153
+ const result = this.db.prepare("DELETE FROM pibo_cron_jobs WHERE id = ?").run(id);
154
+ return Number(result.changes ?? 0) > 0;
155
+ }
156
+ listRuns(input = {}) {
157
+ const clauses = [];
158
+ const values = [];
159
+ if (input.jobId) {
160
+ clauses.push("job_id = ?");
161
+ values.push(input.jobId);
162
+ }
163
+ const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
164
+ return this.db.prepare(`SELECT * FROM pibo_cron_runs ${where} ORDER BY created_at DESC LIMIT ?`).all(...values, Math.max(1, Math.min(input.limit ?? 100, 500))).map(runFromRow);
165
+ }
166
+ getRun(id) {
167
+ const row = this.db.prepare("SELECT * FROM pibo_cron_runs WHERE id = ?").get(id);
168
+ return row ? runFromRow(row) : undefined;
169
+ }
170
+ reserveDueRuns(limit, now = new Date()) {
171
+ const timestamp = nowIso(now);
172
+ const result = [];
173
+ this.db.exec("BEGIN IMMEDIATE");
174
+ try {
175
+ const rows = this.db.prepare(`
176
+ SELECT * FROM pibo_cron_jobs
177
+ WHERE enabled = 1
178
+ ORDER BY updated_at ASC
179
+ `).all();
180
+ for (const row of rows) {
181
+ if (result.length >= limit)
182
+ break;
183
+ const job = jobFromRow(row);
184
+ if (job.state.runningAt)
185
+ continue;
186
+ if (!job.state.nextRunAt || job.state.nextRunAt > timestamp)
187
+ continue;
188
+ const run = this.createRunLocked(job, timestamp, "running");
189
+ const state = { ...job.state, runningAt: timestamp, lastRunAt: timestamp, lastRunId: run.id };
190
+ this.updateJobStateLocked(job.id, state, timestamp);
191
+ result.push({ job: { ...job, state, updatedAt: timestamp }, run });
192
+ }
193
+ this.db.exec("COMMIT");
194
+ }
195
+ catch (error) {
196
+ this.db.exec("ROLLBACK");
197
+ throw error;
198
+ }
199
+ return result;
200
+ }
201
+ reserveManualRun(id, now = new Date()) {
202
+ const timestamp = nowIso(now);
203
+ this.db.exec("BEGIN IMMEDIATE");
204
+ try {
205
+ const job = this.getJob(id);
206
+ if (!job) {
207
+ this.db.exec("COMMIT");
208
+ return undefined;
209
+ }
210
+ if (job.state.runningAt)
211
+ throw new Error("Job is already running");
212
+ const run = this.createRunLocked(job, timestamp, "running", "manual");
213
+ const state = { ...job.state, runningAt: timestamp, lastRunAt: timestamp, lastRunId: run.id };
214
+ this.updateJobStateLocked(job.id, state, timestamp);
215
+ this.db.exec("COMMIT");
216
+ return { job: { ...job, state, updatedAt: timestamp }, run };
217
+ }
218
+ catch (error) {
219
+ this.db.exec("ROLLBACK");
220
+ throw error;
221
+ }
222
+ }
223
+ completeRun(input, now = new Date()) {
224
+ const timestamp = nowIso(now);
225
+ this.db.exec("BEGIN IMMEDIATE");
226
+ try {
227
+ const job = this.getJob(input.jobId);
228
+ if (!job) {
229
+ this.db.exec("COMMIT");
230
+ return;
231
+ }
232
+ const nextRunAt = job.enabled && job.schedule.kind !== "at" ? computeNextRunAt(job.schedule, now)?.toISOString() : undefined;
233
+ const enabled = job.schedule.kind === "at" && input.status === "ok" ? false : job.enabled;
234
+ const state = {
235
+ ...job.state,
236
+ runningAt: undefined,
237
+ nextRunAt: enabled ? nextRunAt : undefined,
238
+ lastRunAt: timestamp,
239
+ lastRunId: input.runId,
240
+ lastStatus: input.status === "error" ? "error" : input.status === "skipped" ? "skipped" : "ok",
241
+ lastError: input.error,
242
+ lastPiboSessionId: input.piboSessionId ?? job.state.lastPiboSessionId,
243
+ consecutiveErrors: input.status === "error" ? (job.state.consecutiveErrors ?? 0) + 1 : 0,
244
+ };
245
+ this.db.prepare(`
246
+ UPDATE pibo_cron_runs
247
+ SET status = ?, pibo_session_id = ?, reason = ?, error = ?, completed_at = ?, updated_at = ?
248
+ WHERE id = ?
249
+ `).run(input.status, input.piboSessionId ?? null, input.reason ?? null, input.error ?? null, timestamp, timestamp, input.runId);
250
+ this.db.prepare(`UPDATE pibo_cron_jobs SET enabled = ?, state_json = ?, updated_at = ? WHERE id = ?`).run(enabled ? 1 : 0, JSON.stringify(state), timestamp, job.id);
251
+ if (job.deleteAfterRun && job.schedule.kind === "at" && input.status === "ok") {
252
+ this.db.prepare("DELETE FROM pibo_cron_jobs WHERE id = ?").run(job.id);
253
+ }
254
+ this.db.exec("COMMIT");
255
+ }
256
+ catch (error) {
257
+ this.db.exec("ROLLBACK");
258
+ throw error;
259
+ }
260
+ }
261
+ recoverInterruptedRuns(cutoff = new Date(Date.now() - 5 * 60_000)) {
262
+ const cutoffIso = nowIso(cutoff);
263
+ const rows = this.db.prepare("SELECT * FROM pibo_cron_jobs WHERE json_extract(state_json, '$.runningAt') IS NOT NULL").all();
264
+ let recovered = 0;
265
+ for (const row of rows) {
266
+ const job = jobFromRow(row);
267
+ if (!job.state.runningAt || job.state.runningAt > cutoffIso)
268
+ continue;
269
+ if (job.state.lastRunId) {
270
+ this.completeRun({ jobId: job.id, runId: job.state.lastRunId, status: "error", error: "Cron run was interrupted by gateway restart", reason: "interrupted" });
271
+ }
272
+ else {
273
+ this.updateJobStateLocked(job.id, { ...job.state, runningAt: undefined }, nowIso());
274
+ }
275
+ recovered += 1;
276
+ }
277
+ return recovered;
278
+ }
279
+ status() {
280
+ const jobs = this.listJobs({ includeDisabled: false });
281
+ const running = jobs.filter((job) => job.state.runningAt).length;
282
+ const nextRunAt = jobs.map((job) => job.state.nextRunAt).filter((value) => Boolean(value)).sort()[0];
283
+ return { jobs: jobs.length, running, nextRunAt };
284
+ }
285
+ applySchema() {
286
+ this.createFreshSchema();
287
+ }
288
+ createFreshSchema() {
289
+ this.db.exec(`
290
+ CREATE TABLE IF NOT EXISTS pibo_cron_jobs (
291
+ id TEXT PRIMARY KEY,
292
+ name TEXT NOT NULL,
293
+ description TEXT,
294
+ enabled INTEGER NOT NULL,
295
+ target_json TEXT NOT NULL,
296
+ profile TEXT NOT NULL,
297
+ prompt TEXT NOT NULL,
298
+ schedule_json TEXT NOT NULL,
299
+ schedule_ui_json TEXT,
300
+ delete_after_run INTEGER NOT NULL DEFAULT 0,
301
+ state_json TEXT NOT NULL,
302
+ created_at TEXT NOT NULL,
303
+ updated_at TEXT NOT NULL
304
+ );
305
+ CREATE INDEX IF NOT EXISTS idx_pibo_cron_jobs_enabled ON pibo_cron_jobs(enabled, updated_at DESC);
306
+
307
+ CREATE TABLE IF NOT EXISTS pibo_cron_runs (
308
+ id TEXT PRIMARY KEY,
309
+ job_id TEXT NOT NULL,
310
+ pibo_session_id TEXT,
311
+ status TEXT NOT NULL,
312
+ reason TEXT,
313
+ error TEXT,
314
+ started_at TEXT,
315
+ completed_at TEXT,
316
+ created_at TEXT NOT NULL,
317
+ updated_at TEXT NOT NULL
318
+ );
319
+ CREATE INDEX IF NOT EXISTS idx_pibo_cron_runs_job_created ON pibo_cron_runs(job_id, created_at DESC);
320
+ `);
321
+ }
322
+ insertJob(job) {
323
+ this.db.prepare(`
324
+ INSERT INTO pibo_cron_jobs (id, name, description, enabled, target_json, profile, prompt, schedule_json, schedule_ui_json, delete_after_run, state_json, created_at, updated_at)
325
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
326
+ `).run(job.id, job.name, job.description ?? null, job.enabled ? 1 : 0, targetJson(job.target), job.profile, job.prompt, JSON.stringify(job.schedule), job.scheduleUi ? JSON.stringify(job.scheduleUi) : null, job.deleteAfterRun ? 1 : 0, JSON.stringify(job.state), job.createdAt, job.updatedAt);
327
+ }
328
+ writeJob(job) {
329
+ this.db.prepare(`
330
+ UPDATE pibo_cron_jobs
331
+ SET name = ?, description = ?, enabled = ?, target_json = ?, profile = ?, prompt = ?, schedule_json = ?, schedule_ui_json = ?, delete_after_run = ?, state_json = ?, updated_at = ?
332
+ WHERE id = ?
333
+ `).run(job.name, job.description ?? null, job.enabled ? 1 : 0, targetJson(job.target), job.profile, job.prompt, JSON.stringify(job.schedule), job.scheduleUi ? JSON.stringify(job.scheduleUi) : null, job.deleteAfterRun ? 1 : 0, JSON.stringify(job.state), job.updatedAt, job.id);
334
+ }
335
+ updateJobStateLocked(id, state, updatedAt) {
336
+ this.db.prepare("UPDATE pibo_cron_jobs SET state_json = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(state), updatedAt, id);
337
+ }
338
+ createRunLocked(job, timestamp, status, reason) {
339
+ const run = { id: `crun_${randomUUID()}`, jobId: job.id, status, reason, startedAt: timestamp, createdAt: timestamp, updatedAt: timestamp };
340
+ this.db.prepare(`
341
+ INSERT INTO pibo_cron_runs (id, job_id, pibo_session_id, status, reason, error, started_at, completed_at, created_at, updated_at)
342
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
343
+ `).run(run.id, run.jobId, null, run.status, run.reason ?? null, null, run.startedAt ?? null, null, run.createdAt, run.updatedAt);
344
+ return run;
345
+ }
346
+ }
347
+ export function createDefaultPiboCronStore(options = {}) {
348
+ return new PiboCronStore(options);
349
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,184 @@
1
+ import { existsSync, statSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { DatabaseSync } from "node:sqlite";
4
+ import { piboHomePath } from "../core/pibo-home.js";
5
+ import { PiboDataStore } from "./pibo-store.js";
6
+ const INVENTORY_STORES = [
7
+ { name: "v2", file: "pibo.sqlite", tables: ["sessions", "rooms", "chat_messages", "event_log", "observations", "payloads", "session_navigation"] },
8
+ { name: "v2-shadow", file: "pibo-chat-v2.sqlite", tables: ["sessions", "rooms", "chat_messages", "event_log", "observations", "payloads", "session_navigation"] },
9
+ { name: "legacy-sessions", file: "pibo-sessions.sqlite", tables: ["pibo_sessions"] },
10
+ { name: "legacy-chat", file: "web-chat.sqlite", tables: ["chat_events", "web_chat_events", "web_chat_sessions", "pibo_rooms", "chat_session_reads"] },
11
+ { name: "reliability", file: "pibo-events.sqlite", tables: ["pibo_event_stream", "pibo_jobs", "pibo_runs"] },
12
+ { name: "auth", file: "auth.sqlite", tables: [] },
13
+ ];
14
+ export async function runDataCli(argv) {
15
+ const args = argv.slice(2);
16
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
17
+ printDataHelp();
18
+ return;
19
+ }
20
+ if (args[0] === "inventory") {
21
+ const json = args.includes("--json");
22
+ const root = optionValue(args, "--root") ?? process.env.PIBO_HOME;
23
+ const inventory = collectInventory(root);
24
+ if (json)
25
+ console.log(JSON.stringify({ stores: inventory }, null, 2));
26
+ else
27
+ printInventory(inventory);
28
+ return;
29
+ }
30
+ if (args[0] === "migrate" && args[1] === "sessions-to-v2") {
31
+ const json = args.includes("--json");
32
+ const root = optionValue(args, "--root") ?? process.env.PIBO_HOME;
33
+ const from = optionValue(args, "--from") ?? dataPath(root, "pibo-sessions.sqlite");
34
+ const to = optionValue(args, "--to") ?? dataPath(root, "pibo.sqlite");
35
+ const report = migrateSessionsToV2({ from, to });
36
+ if (json)
37
+ console.log(JSON.stringify(report, null, 2));
38
+ else
39
+ printSessionMigrationReport(report);
40
+ return;
41
+ }
42
+ throw new Error(`Unknown pibo data command "${args[0]}". Run pibo data --help.`);
43
+ }
44
+ function collectInventory(root) {
45
+ return INVENTORY_STORES.map((store) => inventoryStore(store.name, store.file, store.tables, root));
46
+ }
47
+ function dataPath(root, file) {
48
+ return root ? resolve(root, file) : piboHomePath(file);
49
+ }
50
+ function hasTable(db, table) {
51
+ return Boolean(db.prepare("SELECT 1 AS found FROM sqlite_master WHERE type = 'table' AND name = ?").get(table));
52
+ }
53
+ function inventoryStore(name, file, expectedTables, root) {
54
+ const path = root ? resolve(root, file) : piboHomePath(file);
55
+ const exists = existsSync(path);
56
+ const result = {
57
+ name,
58
+ path,
59
+ exists,
60
+ bytes: exists ? statSync(path).size : 0,
61
+ walBytes: existsSync(`${path}-wal`) ? statSync(`${path}-wal`).size : 0,
62
+ tables: {},
63
+ };
64
+ if (!exists)
65
+ return result;
66
+ const db = new DatabaseSync(path, { readOnly: true });
67
+ try {
68
+ result.integrity = String(db.prepare("PRAGMA integrity_check").get()?.integrity_check ?? "unknown");
69
+ result.freelistPages = Number(db.prepare("PRAGMA freelist_count").get()?.freelist_count ?? 0);
70
+ result.pageCount = Number(db.prepare("PRAGMA page_count").get()?.page_count ?? 0);
71
+ result.pageSize = Number(db.prepare("PRAGMA page_size").get()?.page_size ?? 0);
72
+ const tables = new Set(db.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all().map((row) => row.name));
73
+ for (const table of expectedTables) {
74
+ if (!tables.has(table))
75
+ continue;
76
+ result.tables[table] = Number(db.prepare(`SELECT COUNT(*) AS count FROM ${quoteIdent(table)}`).get().count ?? 0);
77
+ }
78
+ }
79
+ finally {
80
+ db.close();
81
+ }
82
+ return result;
83
+ }
84
+ function migrateSessionsToV2(input) {
85
+ const report = { from: input.from, to: input.to, inputExists: existsSync(input.from), read: 0, inserted: 0, updated: 0, skipped: 0 };
86
+ if (!report.inputExists)
87
+ return report;
88
+ const source = new DatabaseSync(input.from, { readOnly: true });
89
+ const target = new PiboDataStore(input.to);
90
+ try {
91
+ if (!hasTable(source, "pibo_sessions"))
92
+ return report;
93
+ const rows = source.prepare("SELECT * FROM pibo_sessions ORDER BY created_at ASC").all();
94
+ report.read = rows.length;
95
+ for (const row of rows) {
96
+ const existing = target.db.prepare("SELECT updated_at FROM sessions WHERE id = ?").get(row.id);
97
+ const metadata = parseJsonObject(row.metadata_json);
98
+ const rootSessionId = row.parent_id ? (typeof metadata.rootSessionId === "string" ? metadata.rootSessionId : row.parent_id) : row.id;
99
+ if (!existing) {
100
+ const columns = [
101
+ "id", "pi_session_id", "room_id", "root_session_id", "parent_id", "origin_id",
102
+ "channel", "kind", "profile", "active_model_json", "workspace", "title", "status",
103
+ "metadata_json", "created_at", "updated_at", "last_activity_at",
104
+ ];
105
+ target.db.prepare(`
106
+ INSERT INTO sessions (${columns.join(", ")})
107
+ VALUES (${columns.map(() => "?").join(", ")})
108
+ `).run(row.id, row.pi_session_id, typeof metadata.chatRoomId === "string" ? metadata.chatRoomId : null, rootSessionId, row.parent_id, row.origin_id, row.channel, row.kind, row.profile, row.active_model_json, row.workspace, row.title ?? "Untitled Session", "idle", JSON.stringify(metadata), row.created_at, row.updated_at, row.updated_at);
109
+ report.inserted++;
110
+ }
111
+ else if (row.updated_at > existing.updated_at) {
112
+ target.db.prepare(`
113
+ UPDATE sessions SET
114
+ pi_session_id = ?, root_session_id = ?, parent_id = ?, origin_id = ?,
115
+ channel = ?, kind = ?, profile = ?, active_model_json = ?, workspace = ?, title = ?,
116
+ metadata_json = ?, updated_at = ?, last_activity_at = MAX(last_activity_at, ?)
117
+ WHERE id = ?
118
+ `).run(row.pi_session_id, rootSessionId, row.parent_id, row.origin_id, row.channel, row.kind, row.profile, row.active_model_json, row.workspace, row.title ?? "Untitled Session", JSON.stringify(metadata), row.updated_at, row.updated_at, row.id);
119
+ report.updated++;
120
+ }
121
+ else {
122
+ report.skipped++;
123
+ }
124
+ }
125
+ }
126
+ finally {
127
+ source.close();
128
+ target.close();
129
+ }
130
+ return report;
131
+ }
132
+ function parseJsonObject(json) {
133
+ if (!json)
134
+ return {};
135
+ try {
136
+ const value = JSON.parse(json);
137
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
138
+ }
139
+ catch {
140
+ return {};
141
+ }
142
+ }
143
+ function printSessionMigrationReport(report) {
144
+ console.log(`from\t${report.from}`);
145
+ console.log(`to\t${report.to}`);
146
+ console.log(`inputExists\t${report.inputExists}`);
147
+ console.log(`read\t${report.read}`);
148
+ console.log(`inserted\t${report.inserted}`);
149
+ console.log(`updated\t${report.updated}`);
150
+ console.log(`skipped\t${report.skipped}`);
151
+ }
152
+ function quoteIdent(name) {
153
+ return `"${name.replaceAll('"', '""')}"`;
154
+ }
155
+ function optionValue(args, name) {
156
+ const index = args.indexOf(name);
157
+ if (index < 0)
158
+ return undefined;
159
+ return args[index + 1];
160
+ }
161
+ function printInventory(stores) {
162
+ console.log("store\texists\tbytes\twalBytes\tintegrity\ttables\tpath");
163
+ for (const store of stores) {
164
+ const tables = Object.entries(store.tables).map(([name, count]) => `${name}:${count}`).join(",") || "-";
165
+ console.log(`${store.name}\t${store.exists}\t${store.bytes}\t${store.walBytes}\t${store.integrity ?? "-"}\t${tables}\t${store.path}`);
166
+ }
167
+ }
168
+ function printDataHelp() {
169
+ console.log(`pibo data - inspect and maintain Pibo data stores
170
+
171
+ Commands:
172
+ inventory Read-only row counts, sizes, WAL sizes, and integrity checks; legacy-* rows are archived stores
173
+ migrate sessions-to-v2 Import an explicit legacy pibo-sessions.sqlite into pibo.sqlite idempotently
174
+
175
+ Options:
176
+ --json Print machine-readable JSON
177
+ --root DIR Inspect a specific Pibo home directory instead of ~/.pibo
178
+ --to FILE Target pibo.sqlite path for migration or repair
179
+
180
+ Next:
181
+ pibo data inventory --json
182
+ pibo data migrate sessions-to-v2 --from /path/to/pibo-sessions.sqlite --json
183
+ `);
184
+ }
@@ -0,0 +1,106 @@
1
+ import { randomUUID } from "node:crypto";
2
+ export class PiboEventLogStore {
3
+ db;
4
+ constructor(db) {
5
+ this.db = db;
6
+ }
7
+ appendEvent(input) {
8
+ if (input.idempotencyKey) {
9
+ const existing = this.findByIdempotencyKey(input.idempotencyKey);
10
+ if (existing)
11
+ return existing;
12
+ }
13
+ const createdAt = input.createdAt ?? new Date().toISOString();
14
+ const eventId = input.eventId ?? `evt_${randomUUID()}`;
15
+ const result = this.db.prepare(`
16
+ INSERT OR IGNORE INTO event_log (
17
+ session_id,
18
+ session_sequence,
19
+ room_id,
20
+ topic,
21
+ type,
22
+ source,
23
+ actor_type,
24
+ actor_id,
25
+ turn_id,
26
+ event_id,
27
+ tool_call_id,
28
+ run_id,
29
+ workflow_run_id,
30
+ idempotency_key,
31
+ retention_class,
32
+ payload_ref,
33
+ preview_text,
34
+ attributes_json,
35
+ created_at,
36
+ indexed_at
37
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
38
+ `).run(input.sessionId ?? null, input.sessionSequence ?? null, input.roomId ?? null, input.topic, input.type, input.source, input.actorType ?? null, input.actorId ?? null, input.turnId ?? null, eventId, input.toolCallId ?? null, input.runId ?? null, input.workflowRunId ?? null, input.idempotencyKey ?? null, input.retentionClass, input.payloadRef ?? null, input.previewText ?? null, JSON.stringify(input.attributes ?? {}), createdAt, input.indexedAt ?? null);
39
+ if (input.idempotencyKey) {
40
+ const existing = this.findByIdempotencyKey(input.idempotencyKey);
41
+ if (existing)
42
+ return existing;
43
+ }
44
+ const stored = this.findByStreamId(Number(result.lastInsertRowid));
45
+ if (!stored)
46
+ throw new Error(`Failed to append event log row \"${eventId}\"`);
47
+ return stored;
48
+ }
49
+ listEvents(input = {}) {
50
+ const clauses = [];
51
+ const values = [];
52
+ if (input.sessionId) {
53
+ clauses.push("session_id = ?");
54
+ values.push(input.sessionId);
55
+ }
56
+ if (input.roomId) {
57
+ clauses.push("room_id = ?");
58
+ values.push(input.roomId);
59
+ }
60
+ if (input.topic) {
61
+ clauses.push("topic = ?");
62
+ values.push(input.topic);
63
+ }
64
+ if (input.afterStreamId !== undefined) {
65
+ clauses.push("stream_id > ?");
66
+ values.push(input.afterStreamId);
67
+ }
68
+ const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
69
+ const limit = Math.max(1, Math.min(input.limit ?? 100, 1000));
70
+ const rows = this.db.prepare(`SELECT * FROM event_log ${where} ORDER BY stream_id ASC LIMIT ?`).all(...values, limit);
71
+ return rows.map(eventLogFromRow);
72
+ }
73
+ findByIdempotencyKey(idempotencyKey) {
74
+ const row = this.db.prepare("SELECT * FROM event_log WHERE idempotency_key = ? LIMIT 1").get(idempotencyKey);
75
+ return row ? eventLogFromRow(row) : undefined;
76
+ }
77
+ findByStreamId(streamId) {
78
+ const row = this.db.prepare("SELECT * FROM event_log WHERE stream_id = ?").get(streamId);
79
+ return row ? eventLogFromRow(row) : undefined;
80
+ }
81
+ }
82
+ function eventLogFromRow(row) {
83
+ return {
84
+ streamId: row.stream_id,
85
+ sessionId: row.session_id ?? undefined,
86
+ sessionSequence: row.session_sequence ?? undefined,
87
+ roomId: row.room_id ?? undefined,
88
+ topic: row.topic,
89
+ type: row.type,
90
+ source: row.source,
91
+ actorType: row.actor_type ?? undefined,
92
+ actorId: row.actor_id ?? undefined,
93
+ turnId: row.turn_id ?? undefined,
94
+ eventId: row.event_id ?? undefined,
95
+ toolCallId: row.tool_call_id ?? undefined,
96
+ runId: row.run_id ?? undefined,
97
+ workflowRunId: row.workflow_run_id ?? undefined,
98
+ idempotencyKey: row.idempotency_key ?? undefined,
99
+ retentionClass: row.retention_class,
100
+ payloadRef: row.payload_ref ?? undefined,
101
+ previewText: row.preview_text ?? undefined,
102
+ attributes: JSON.parse(row.attributes_json),
103
+ createdAt: row.created_at,
104
+ indexedAt: row.indexed_at ?? undefined,
105
+ };
106
+ }