@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,75 @@
1
+ import { readPiboBasePrompt, savePiboCustomBasePrompt, setPiboBasePromptMode } from "../../core/base-prompt.js";
2
+ import { readPiboCompactionPrompt, savePiboCustomCompactionPrompt, setPiboCompactionPromptMode } from "../../core/compaction-prompt.js";
3
+ import { loadPiboUserSettings, sanitizeShortcutSettings, sanitizeTimezone, updatePiboUserSettings } from "../../core/user-settings.js";
4
+ import { PiboWebHttpError, readJsonBody, responseJson } from "../../web/http.js";
5
+ import { CHAT_WEB_API_PREFIX } from "./chat-api-routes.js";
6
+ import { normalizeBasePromptMarkdown, normalizeBasePromptMode, normalizeCompactionPromptMarkdown, normalizeCompactionPromptMode, updateChatModelDefaults, } from "./chat-request-normalizers.js";
7
+ export function chatSettingsRoute(pathname, method) {
8
+ if (pathname === `${CHAT_WEB_API_PREFIX}/model-defaults` && method === "PATCH")
9
+ return { kind: "model-defaults" };
10
+ if (pathname === `${CHAT_WEB_API_PREFIX}/user-settings` && method === "GET")
11
+ return { kind: "user-settings", action: "read" };
12
+ if (pathname === `${CHAT_WEB_API_PREFIX}/user-settings` && method === "PATCH")
13
+ return { kind: "user-settings", action: "update" };
14
+ if (pathname === `${CHAT_WEB_API_PREFIX}/base-prompt` && method === "GET")
15
+ return { kind: "base-prompt", action: "read" };
16
+ if (pathname === `${CHAT_WEB_API_PREFIX}/base-prompt` && method === "PATCH")
17
+ return { kind: "base-prompt", action: "set-mode" };
18
+ if (pathname === `${CHAT_WEB_API_PREFIX}/base-prompt/custom` && method === "PUT")
19
+ return { kind: "base-prompt", action: "save-custom" };
20
+ if (pathname === `${CHAT_WEB_API_PREFIX}/compaction-prompt` && method === "GET")
21
+ return { kind: "compaction-prompt", action: "read" };
22
+ if (pathname === `${CHAT_WEB_API_PREFIX}/compaction-prompt` && method === "PATCH")
23
+ return { kind: "compaction-prompt", action: "set-mode" };
24
+ if (pathname === `${CHAT_WEB_API_PREFIX}/compaction-prompt/custom` && method === "PUT")
25
+ return { kind: "compaction-prompt", action: "save-custom" };
26
+ return undefined;
27
+ }
28
+ export function chatSettingsRouteRequiresSameOrigin(route) {
29
+ return route.kind === "model-defaults" || route.action !== "read";
30
+ }
31
+ export function chatSettingsRouteInvalidatesBootstrapCatalog(route) {
32
+ return route.kind === "model-defaults";
33
+ }
34
+ export async function handleChatSettingsRoute(input) {
35
+ const cwd = input.cwd ?? process.cwd();
36
+ const { route, request } = input;
37
+ if (route.kind === "model-defaults") {
38
+ const body = await readJsonBody(request);
39
+ return responseJson({ modelDefaults: updateChatModelDefaults(body, cwd) });
40
+ }
41
+ if (route.kind === "user-settings") {
42
+ if (route.action === "read")
43
+ return responseJson({ userSettings: loadPiboUserSettings() });
44
+ const body = await readJsonBody(request);
45
+ return responseJson({ userSettings: updatePiboUserSettings(userSettingsPatch(body)) });
46
+ }
47
+ if (route.kind === "base-prompt") {
48
+ if (route.action === "read")
49
+ return responseJson({ basePrompt: await readPiboBasePrompt(cwd) });
50
+ const body = await readJsonBody(request);
51
+ if (route.action === "set-mode") {
52
+ return responseJson({ basePrompt: setPiboBasePromptMode(normalizeBasePromptMode(body.mode), cwd) });
53
+ }
54
+ return responseJson({ basePrompt: await savePiboCustomBasePrompt(normalizeBasePromptMarkdown(body.markdown), cwd) });
55
+ }
56
+ if (route.action === "read")
57
+ return responseJson({ compactionPrompt: await readPiboCompactionPrompt(cwd) });
58
+ const body = await readJsonBody(request);
59
+ if (route.action === "set-mode") {
60
+ return responseJson({ compactionPrompt: setPiboCompactionPromptMode(normalizeCompactionPromptMode(body.mode), cwd) });
61
+ }
62
+ return responseJson({ compactionPrompt: await savePiboCustomCompactionPrompt(normalizeCompactionPromptMarkdown(body.markdown), cwd) });
63
+ }
64
+ function userSettingsPatch(body) {
65
+ const patch = {};
66
+ if (body.timezone !== undefined) {
67
+ const timezone = sanitizeTimezone(body.timezone);
68
+ if (!timezone)
69
+ throw new PiboWebHttpError("Invalid timezone", 400);
70
+ patch.timezone = timezone;
71
+ }
72
+ if (body.shortcuts !== undefined)
73
+ patch.shortcuts = sanitizeShortcutSettings(body.shortcuts);
74
+ return patch;
75
+ }
@@ -0,0 +1,94 @@
1
+ import { createHash } from "node:crypto";
2
+ import { patchTraceViewWithEvent } from "../../shared/trace-engine.js";
3
+ export const DEFAULT_TRACE_EVENTS_PAGE_SIZE = 2_000;
4
+ export const MAX_TRACE_EVENTS_PER_REQUEST = 50_000;
5
+ export function etagForVersion(version) {
6
+ return `"${version}"`;
7
+ }
8
+ export function requestMatchesVersion(request, version) {
9
+ const header = request.headers.get("if-none-match");
10
+ if (!header)
11
+ return false;
12
+ return header
13
+ .split(",")
14
+ .map((value) => value.trim())
15
+ .some((value) => value === "*" || value === etagForVersion(version) || value === `W/${etagForVersion(version)}`);
16
+ }
17
+ export function traceCacheKey(piboSessionId, version) {
18
+ return [piboSessionId, version, "structural"].join(":");
19
+ }
20
+ export function withRawTraceTail(trace, rawEvents) {
21
+ if (rawEvents.length === 0)
22
+ return trace;
23
+ return { ...trace, rawEvents };
24
+ }
25
+ export function liveSnapshotVersion(snapshots) {
26
+ if (snapshots.length === 0)
27
+ return "";
28
+ const hash = createHash("sha1");
29
+ for (const snapshot of snapshots) {
30
+ hash.update(JSON.stringify(snapshot));
31
+ hash.update("\n");
32
+ }
33
+ return hash.digest("hex").slice(0, 16);
34
+ }
35
+ export function storedLiveSnapshotEvents(input) {
36
+ const createdAt = input.now ?? new Date().toISOString();
37
+ return input.snapshots.map((snapshot, index) => ({
38
+ id: `live-snapshot:${input.piboSessionId}:${index}:${liveSnapshotVersion([snapshot])}`,
39
+ piboSessionId: input.piboSessionId,
40
+ eventSequence: input.lastEventSequence + index + 1,
41
+ eventId: "eventId" in snapshot && typeof snapshot.eventId === "string" ? snapshot.eventId : undefined,
42
+ type: snapshot.type,
43
+ createdAt,
44
+ payload: snapshot,
45
+ }));
46
+ }
47
+ export function withLiveSnapshots(trace, snapshots, input) {
48
+ if (snapshots.length === 0)
49
+ return trace;
50
+ const events = storedLiveSnapshotEvents({
51
+ piboSessionId: input.piboSessionId,
52
+ snapshots,
53
+ lastEventSequence: input.lastEventSequence,
54
+ });
55
+ let next = trace;
56
+ for (const event of events) {
57
+ next = patchTraceViewWithEvent(next, event, input.status ?? "running");
58
+ }
59
+ return {
60
+ ...next,
61
+ version: `${trace.version}:live:${liveSnapshotVersion(snapshots)}`,
62
+ rawEvents: trace.rawEvents,
63
+ };
64
+ }
65
+ export function annotateTracePage(trace, events, input) {
66
+ const sequences = events
67
+ .map((event) => event.eventSequence)
68
+ .filter((sequence) => typeof sequence === "number");
69
+ const firstEventSequence = sequences.length ? Math.min(...sequences) : undefined;
70
+ const lastEventSequence = sequences.length ? Math.max(...sequences) : undefined;
71
+ return {
72
+ ...trace,
73
+ eventCount: input.lastEventSequence,
74
+ eventLimit: input.pageSize,
75
+ pageSize: input.pageSize,
76
+ beforeSequence: input.beforeSequence,
77
+ firstEventSequence,
78
+ lastEventSequence,
79
+ nextBeforeSequence: firstEventSequence,
80
+ hasOlderEvents: firstEventSequence !== undefined ? firstEventSequence > 1 : false,
81
+ };
82
+ }
83
+ export function setTraceCache(cache, key, trace, maxEntries) {
84
+ if (trace.rawEvents.length > 0)
85
+ return;
86
+ cache.delete(key);
87
+ cache.set(key, trace);
88
+ while (cache.size > maxEntries) {
89
+ const oldestKey = cache.keys().next().value;
90
+ if (typeof oldestKey !== "string")
91
+ break;
92
+ cache.delete(oldestKey);
93
+ }
94
+ }
@@ -0,0 +1,149 @@
1
+ import { PiboWebHttpError, readJsonBody, responseJson } from "../../web/http.js";
2
+ import { CHAT_WEB_API_PREFIX, userSkillResourceId } from "./chat-api-routes.js";
3
+ import { normalizeUserSkillDescription, normalizeUserSkillEnabled, normalizeUserSkillMarkdown, normalizeUserSkillName, normalizeUserSkillUrl, } from "./chat-request-normalizers.js";
4
+ export function chatUserSkillRoute(pathname, method) {
5
+ if (pathname === `${CHAT_WEB_API_PREFIX}/user-skills` && method === "GET")
6
+ return { kind: "user-skills-list" };
7
+ if (pathname === `${CHAT_WEB_API_PREFIX}/user-skills` && method === "POST")
8
+ return { kind: "user-skills-create" };
9
+ if (pathname === `${CHAT_WEB_API_PREFIX}/user-skills/install` && method === "POST")
10
+ return { kind: "user-skills-install" };
11
+ const skillId = userSkillResourceId(pathname);
12
+ if (skillId && method === "GET")
13
+ return { kind: "user-skill-read", skillId };
14
+ if (skillId && method === "PATCH")
15
+ return { kind: "user-skill-update", skillId };
16
+ if (skillId && method === "DELETE")
17
+ return { kind: "user-skill-delete", skillId };
18
+ return undefined;
19
+ }
20
+ export function chatUserSkillRouteRequiresSameOrigin(route) {
21
+ return route.kind !== "user-skills-list" && route.kind !== "user-skill-read";
22
+ }
23
+ export function syncChatUserSkills(options) {
24
+ const { userSkillManager, channelContext, previouslySyncedNames, setSyncedUserSkillNames } = options;
25
+ const registerSkill = channelContext.registerSkill;
26
+ const unregisterSkill = channelContext.unregisterSkill;
27
+ if (!registerSkill || !unregisterSkill)
28
+ return;
29
+ const userSkills = userSkillManager.list();
30
+ const catalogSkills = channelContext.getCapabilityCatalog?.().skills ?? [];
31
+ const catalogSkillByName = new Map(catalogSkills.map((skill) => [skill.name, skill]));
32
+ const reservedSkillNames = new Set(catalogSkills.filter((skill) => skill.kind !== "user").map((skill) => skill.name));
33
+ const enabledNames = new Set(userSkills
34
+ .filter((skill) => skill.enabled && !reservedSkillNames.has(skill.name))
35
+ .map((skill) => skill.name));
36
+ const syncedNames = previouslySyncedNames ?? new Set();
37
+ // Unregister disabled, removed, or now built-in user skills. Avoid removing a
38
+ // built-in/plugin skill if a promoted user skill has the same name.
39
+ for (const name of syncedNames) {
40
+ if (!enabledNames.has(name)) {
41
+ const catalogSkill = catalogSkillByName.get(name);
42
+ if (!catalogSkill || catalogSkill.kind === "user")
43
+ unregisterSkill(name);
44
+ }
45
+ }
46
+ // Register only newly enabled user skills. Re-registering an already synced
47
+ // skill would trip the registry duplicate-skill guard and break the web UI.
48
+ for (const skill of userSkills) {
49
+ if (skill.enabled && !reservedSkillNames.has(skill.name) && !syncedNames.has(skill.name)) {
50
+ registerSkill({ name: skill.name, path: skill.path, enabled: true, kind: "user" });
51
+ }
52
+ }
53
+ setSyncedUserSkillNames(enabledNames);
54
+ }
55
+ function assertUserSkillNameIsAvailable(options) {
56
+ const { userSkillManager, channelContext, name, currentSkillId } = options;
57
+ const currentSkill = currentSkillId ? userSkillManager.get(currentSkillId) : undefined;
58
+ const conflict = (channelContext.getCapabilityCatalog?.().skills ?? []).find((skill) => (skill.name === name && (!currentSkill || currentSkill.name !== name)));
59
+ if (conflict) {
60
+ throw new PiboWebHttpError(`Skill name "${name}" conflicts with an existing registered skill`, 409);
61
+ }
62
+ }
63
+ function syncAndInvalidate(options) {
64
+ syncChatUserSkills({
65
+ userSkillManager: options.userSkillManager,
66
+ channelContext: options.channelContext,
67
+ previouslySyncedNames: options.previouslySyncedNames,
68
+ setSyncedUserSkillNames: options.setSyncedUserSkillNames,
69
+ });
70
+ options.invalidateBootstrapCatalogCache();
71
+ }
72
+ export async function handleChatUserSkillRoute(options) {
73
+ const { route, request, userSkillManager, channelContext } = options;
74
+ switch (route.kind) {
75
+ case "user-skills-list":
76
+ return responseJson({ skills: userSkillManager.list() });
77
+ case "user-skills-create": {
78
+ const body = await readJsonBody(request);
79
+ const name = normalizeUserSkillName(body.name);
80
+ assertUserSkillNameIsAvailable({ userSkillManager, channelContext, name });
81
+ const skill = userSkillManager.create({
82
+ name,
83
+ description: normalizeUserSkillDescription(body.description ?? ""),
84
+ markdown: normalizeUserSkillMarkdown(body.markdown ?? ""),
85
+ });
86
+ syncAndInvalidate(options);
87
+ return responseJson({ skill }, { status: 201 });
88
+ }
89
+ case "user-skills-install": {
90
+ const body = await readJsonBody(request);
91
+ const skill = await userSkillManager.installFromUrl(normalizeUserSkillUrl(body.url));
92
+ try {
93
+ assertUserSkillNameIsAvailable({ userSkillManager, channelContext, name: skill.name, currentSkillId: skill.id });
94
+ }
95
+ catch (error) {
96
+ userSkillManager.remove(skill.id);
97
+ throw error;
98
+ }
99
+ syncAndInvalidate(options);
100
+ return responseJson({ skill }, { status: 201 });
101
+ }
102
+ case "user-skill-read": {
103
+ const skill = userSkillManager.get(route.skillId);
104
+ if (!skill)
105
+ throw new PiboWebHttpError("Skill not found", 404);
106
+ const markdown = userSkillManager.getSkillMarkdown(skill.id);
107
+ return responseJson({ skill, markdown });
108
+ }
109
+ case "user-skill-update": {
110
+ const existing = userSkillManager.get(route.skillId);
111
+ if (!existing)
112
+ throw new PiboWebHttpError("Skill not found", 404);
113
+ const body = await readJsonBody(request);
114
+ const input = {};
115
+ if (body.name !== undefined)
116
+ input.name = normalizeUserSkillName(body.name);
117
+ if (body.description !== undefined)
118
+ input.description = normalizeUserSkillDescription(body.description);
119
+ if (body.markdown !== undefined)
120
+ input.markdown = normalizeUserSkillMarkdown(body.markdown);
121
+ if (body.enabled !== undefined)
122
+ input.enabled = normalizeUserSkillEnabled(body.enabled);
123
+ if (Object.keys(input).length === 0) {
124
+ throw new PiboWebHttpError("No skill update fields provided", 400);
125
+ }
126
+ const nextName = input.name ?? existing.name;
127
+ const nextEnabled = input.enabled ?? existing.enabled;
128
+ if (nextEnabled) {
129
+ assertUserSkillNameIsAvailable({
130
+ userSkillManager,
131
+ channelContext,
132
+ name: nextName,
133
+ currentSkillId: existing.id,
134
+ });
135
+ }
136
+ const skill = userSkillManager.update(existing.id, input);
137
+ syncAndInvalidate(options);
138
+ return responseJson({ skill });
139
+ }
140
+ case "user-skill-delete": {
141
+ const existing = userSkillManager.get(route.skillId);
142
+ if (!existing)
143
+ throw new PiboWebHttpError("Skill not found", 404);
144
+ userSkillManager.remove(existing.id);
145
+ syncAndInvalidate(options);
146
+ return responseJson({ removedSkillId: existing.id });
147
+ }
148
+ }
149
+ }
@@ -0,0 +1,213 @@
1
+ import { PiboWebHttpError, readJsonBody, responseJson } from "../../web/http.js";
2
+ import { getPiboCronService } from "../../cron/channel.js";
3
+ import { parseFriendlySchedule } from "../../cron/schedule.js";
4
+ import { isPiboRoomArchived } from "./types/rooms.js";
5
+ const CHAT_WEB_API_PREFIX = "/api/chat";
6
+ function requireSameOriginJsonRequest(request) {
7
+ const contentType = request.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase();
8
+ if (contentType !== "application/json")
9
+ throw new PiboWebHttpError("Content-Type must be application/json", 415);
10
+ const origin = request.headers.get("origin");
11
+ if (!origin)
12
+ throw new PiboWebHttpError("Origin header is required", 403);
13
+ if (origin !== new URL(request.url).origin)
14
+ throw new PiboWebHttpError("Origin is not allowed", 403);
15
+ }
16
+ function accessDenied(error) {
17
+ throw new PiboWebHttpError(error instanceof Error ? error.message : "Access denied", 403);
18
+ }
19
+ function normalizeString(value, field, options = {}) {
20
+ if (value === undefined || value === null) {
21
+ if (options.required)
22
+ throw new PiboWebHttpError(`${field} is required`, 400);
23
+ return undefined;
24
+ }
25
+ if (typeof value !== "string")
26
+ throw new PiboWebHttpError(`${field} must be a string`, 400);
27
+ const normalized = value.trim();
28
+ if (!normalized && options.required)
29
+ throw new PiboWebHttpError(`${field} is required`, 400);
30
+ if (options.max && normalized.length > options.max)
31
+ throw new PiboWebHttpError(`${field} is too long`, 400);
32
+ return normalized || undefined;
33
+ }
34
+ function normalizeEnabled(value) {
35
+ if (value === undefined)
36
+ return undefined;
37
+ if (typeof value !== "boolean")
38
+ throw new PiboWebHttpError("enabled must be a boolean", 400);
39
+ return value;
40
+ }
41
+ function normalizeTarget(value, options) {
42
+ if (!value || typeof value !== "object" || Array.isArray(value))
43
+ throw new PiboWebHttpError("target is required", 400);
44
+ const raw = value;
45
+ if (raw.kind === "room") {
46
+ const roomId = normalizeString(raw.roomId, "target.roomId", { required: true });
47
+ let room;
48
+ try {
49
+ room = options.roomService.requireRoom(roomId);
50
+ }
51
+ catch (error) {
52
+ accessDenied(error);
53
+ }
54
+ if (isPiboRoomArchived(room))
55
+ throw new PiboWebHttpError("Archived rooms are read-only", 403);
56
+ return { kind: "room", roomId };
57
+ }
58
+ if (raw.kind === "default-chat") {
59
+ options.roomService.ensureDefaultRoom({ name: "Shared Chat" });
60
+ return { kind: "default-chat" };
61
+ }
62
+ throw new PiboWebHttpError("target.kind must be room or default-chat", 400);
63
+ }
64
+ function normalizeSchedule(value) {
65
+ if (!value || typeof value !== "object" || Array.isArray(value))
66
+ throw new PiboWebHttpError("schedule is required", 400);
67
+ const raw = value;
68
+ try {
69
+ if (raw.kind === "at" && typeof raw.at === "string")
70
+ return { schedule: { kind: "at", at: raw.at } };
71
+ if (raw.kind === "at" && typeof raw.value === "string")
72
+ return parseFriendlySchedule({ kind: "at", value: raw.value, tz: typeof raw.tz === "string" ? raw.tz : undefined });
73
+ if (raw.kind === "every" && typeof raw.everyMs === "number")
74
+ return { schedule: { kind: "every", everyMs: raw.everyMs, anchorMs: typeof raw.anchorMs === "number" ? raw.anchorMs : Date.now() } };
75
+ if (raw.kind === "every" && typeof raw.value === "string")
76
+ return parseFriendlySchedule({ kind: "every", value: raw.value });
77
+ if (raw.kind === "cron" && typeof raw.expr === "string")
78
+ return { schedule: { kind: "cron", expr: raw.expr, tz: typeof raw.tz === "string" ? raw.tz : undefined } };
79
+ if (raw.kind === "in" && typeof raw.value === "string")
80
+ return parseFriendlySchedule({ kind: "in", value: raw.value });
81
+ if (raw.kind === "daily" && typeof raw.time === "string")
82
+ return parseFriendlySchedule({ kind: "daily", time: raw.time, tz: typeof raw.tz === "string" ? raw.tz : undefined });
83
+ if (raw.kind === "weekly" && typeof raw.time === "string" && (typeof raw.weekdays === "string" || Array.isArray(raw.weekdays)))
84
+ return parseFriendlySchedule({ kind: "weekly", time: raw.time, weekdays: raw.weekdays, tz: typeof raw.tz === "string" ? raw.tz : undefined });
85
+ if (raw.kind === "monthly" && typeof raw.time === "string" && typeof raw.dayOfMonth === "number")
86
+ return parseFriendlySchedule({ kind: "monthly", time: raw.time, dayOfMonth: raw.dayOfMonth, tz: typeof raw.tz === "string" ? raw.tz : undefined });
87
+ }
88
+ catch (error) {
89
+ throw new PiboWebHttpError(error instanceof Error ? error.message : String(error), 400);
90
+ }
91
+ throw new PiboWebHttpError("Unsupported schedule", 400);
92
+ }
93
+ function resolveProfile(context, fallback, value) {
94
+ const requested = normalizeString(value, "profile") ?? fallback;
95
+ const profile = context.channelContext.getProfiles?.().find((item) => item.name === requested || item.aliases.includes(requested));
96
+ if (!profile)
97
+ throw new PiboWebHttpError(`Unknown profile: ${requested}`, 400);
98
+ return profile.name;
99
+ }
100
+ function jobResource(pathname) {
101
+ const prefix = `${CHAT_WEB_API_PREFIX}/cron/jobs/`;
102
+ if (!pathname.startsWith(prefix))
103
+ return undefined;
104
+ const parts = pathname.slice(prefix.length).split("/").filter(Boolean).map((part) => decodeURIComponent(part));
105
+ if (!parts[0] || parts.length > 2)
106
+ return undefined;
107
+ if (parts[1] && parts[1] !== "run")
108
+ return undefined;
109
+ return { id: parts[0], child: parts[1] };
110
+ }
111
+ function serializeJob(job) {
112
+ return job;
113
+ }
114
+ function serializeRun(run) {
115
+ return run;
116
+ }
117
+ function createPatch(body, options) {
118
+ const patch = {};
119
+ const name = normalizeString(body.name, "name", { max: 120 });
120
+ if (body.name !== undefined && name !== undefined)
121
+ patch.name = name;
122
+ if (body.description !== undefined)
123
+ patch.description = normalizeString(body.description, "description", { max: 500 });
124
+ const enabled = normalizeEnabled(body.enabled);
125
+ if (enabled !== undefined)
126
+ patch.enabled = enabled;
127
+ if (body.target !== undefined)
128
+ patch.target = normalizeTarget(body.target, options);
129
+ if (body.profile !== undefined)
130
+ patch.profile = resolveProfile(options.context, options.defaultProfile, body.profile);
131
+ if (body.prompt !== undefined)
132
+ patch.prompt = normalizeString(body.prompt, "prompt", { required: true, max: 20_000 });
133
+ if (body.schedule !== undefined) {
134
+ const normalized = normalizeSchedule(body.schedule);
135
+ patch.schedule = normalized.schedule;
136
+ patch.scheduleUi = normalized.scheduleUi;
137
+ }
138
+ if (body.deleteAfterRun !== undefined) {
139
+ if (typeof body.deleteAfterRun !== "boolean")
140
+ throw new PiboWebHttpError("deleteAfterRun must be a boolean", 400);
141
+ patch.deleteAfterRun = body.deleteAfterRun;
142
+ }
143
+ if (Object.keys(patch).length === 0)
144
+ throw new PiboWebHttpError("No cron job update fields provided", 400);
145
+ return patch;
146
+ }
147
+ export async function handleChatCronApiRequest(options) {
148
+ const { request, cronStore } = options;
149
+ const url = new URL(request.url);
150
+ if (!url.pathname.startsWith(`${CHAT_WEB_API_PREFIX}/cron`))
151
+ return undefined;
152
+ if (url.pathname === `${CHAT_WEB_API_PREFIX}/cron/status` && request.method === "GET") {
153
+ return responseJson({ status: getPiboCronService()?.status() ?? { enabled: false, ...cronStore.status() } });
154
+ }
155
+ if (url.pathname === `${CHAT_WEB_API_PREFIX}/cron/jobs` && request.method === "GET") {
156
+ return responseJson({ jobs: cronStore.listJobs({ includeDisabled: url.searchParams.get("includeDisabled") === "true" }).map(serializeJob) });
157
+ }
158
+ if (url.pathname === `${CHAT_WEB_API_PREFIX}/cron/jobs` && request.method === "POST") {
159
+ requireSameOriginJsonRequest(request);
160
+ const body = await readJsonBody(request);
161
+ const normalized = normalizeSchedule(body.schedule);
162
+ const job = cronStore.createJob({
163
+ name: normalizeString(body.name, "name", { max: 120 }),
164
+ description: normalizeString(body.description, "description", { max: 500 }),
165
+ enabled: normalizeEnabled(body.enabled),
166
+ target: normalizeTarget(body.target, options),
167
+ profile: resolveProfile(options.context, options.defaultProfile, body.profile),
168
+ prompt: normalizeString(body.prompt, "prompt", { required: true, max: 20_000 }),
169
+ schedule: normalized.schedule,
170
+ scheduleUi: normalized.scheduleUi,
171
+ deleteAfterRun: body.deleteAfterRun === true,
172
+ });
173
+ return responseJson({ job: serializeJob(job) }, { status: 201 });
174
+ }
175
+ if (url.pathname === `${CHAT_WEB_API_PREFIX}/cron/runs` && request.method === "GET") {
176
+ const jobId = url.searchParams.get("jobId") || undefined;
177
+ const limit = Number(url.searchParams.get("limit") ?? "100");
178
+ if (jobId && !cronStore.getJob(jobId))
179
+ throw new PiboWebHttpError("Cron job not found", 404);
180
+ return responseJson({ runs: cronStore.listRuns({ jobId, limit: Number.isFinite(limit) ? limit : 100 }).map(serializeRun) });
181
+ }
182
+ const resource = jobResource(url.pathname);
183
+ if (!resource)
184
+ return undefined;
185
+ if (resource.child === "run" && request.method === "POST") {
186
+ requireSameOriginJsonRequest(request);
187
+ const service = getPiboCronService();
188
+ if (!service)
189
+ throw new PiboWebHttpError("Cron service is not running", 503);
190
+ return responseJson({ run: serializeRun(await service.runJobNow(resource.id)) }, { status: 202 });
191
+ }
192
+ if (resource.child)
193
+ return undefined;
194
+ if (request.method === "GET") {
195
+ const job = cronStore.getJob(resource.id);
196
+ if (!job)
197
+ throw new PiboWebHttpError("Cron job not found", 404);
198
+ return responseJson({ job: serializeJob(job) });
199
+ }
200
+ if (request.method === "PATCH") {
201
+ requireSameOriginJsonRequest(request);
202
+ const body = await readJsonBody(request);
203
+ const job = cronStore.updateJob(resource.id, createPatch(body, options));
204
+ if (!job)
205
+ throw new PiboWebHttpError("Cron job not found", 404);
206
+ return responseJson({ job: serializeJob(job) });
207
+ }
208
+ if (request.method === "DELETE") {
209
+ requireSameOriginJsonRequest(request);
210
+ return responseJson({ removed: cronStore.removeJob(resource.id) });
211
+ }
212
+ return undefined;
213
+ }
@@ -0,0 +1,74 @@
1
+ import { normalizeSessionErrorDetails } from "../../../core/session-errors.js";
2
+ import { roomWorkspaceFromMetadata } from "../types/rooms.js";
3
+ export function storedPiboEventFromV2Row(row) {
4
+ const attributes = parseJsonObject(row.attributes_json);
5
+ const payload = outputPayloadFromV2Row(row, attributes);
6
+ if (!payload)
7
+ return undefined;
8
+ return { id: String(row.stream_id), piboSessionId: row.session_id ?? undefined, eventSequence: row.session_sequence ?? undefined, eventId: row.event_id ?? undefined, streamId: row.stream_id, type: row.type, createdAt: row.created_at, payload };
9
+ }
10
+ export function storedChatEventFromV2Row(row) {
11
+ const attributes = parseJsonObject(row.attributes_json);
12
+ return { streamId: row.stream_id, roomId: row.room_id ?? undefined, piboSessionId: row.session_id ?? undefined, eventId: row.event_id ?? `evt_${row.stream_id}`, eventType: row.type, actorType: actorTypeValue(row.actor_type), actorId: row.actor_id ?? undefined, clientTxnId: typeof attributes.clientTxnId === "string" ? attributes.clientTxnId : undefined, createdAt: row.created_at, retentionClass: retentionClassValue(row.retention_class), payload: (outputPayloadFromV2Row(row, attributes) ?? null) };
13
+ }
14
+ function outputPayloadFromV2Row(row, attributes) {
15
+ const inlinePayload = attributes.inlinePayload;
16
+ if (inlinePayload && typeof inlinePayload === "object" && !Array.isArray(inlinePayload) && typeof inlinePayload.type === "string")
17
+ return inlinePayload;
18
+ const piboSessionId = row.session_id;
19
+ if (!piboSessionId)
20
+ return undefined;
21
+ const base = compactObject({ piboSessionId, eventId: row.event_id ?? undefined });
22
+ if (row.type === "assistant_message")
23
+ return { ...base, type: "assistant_message", text: row.preview_text ?? "" };
24
+ if (row.type === "message_queued")
25
+ return { ...base, type: "message_queued", text: stringAttribute(attributes, "inlineText") ?? row.preview_text ?? "", source: stringAttribute(attributes, "source") ?? "user", queuedMessages: numberAttribute(attributes, "queuedMessages") ?? 1 };
26
+ if (row.type === "message_started")
27
+ return { ...base, type: "message_started", text: row.preview_text ?? "" };
28
+ if (row.type === "message_finished")
29
+ return { ...base, type: "message_finished" };
30
+ if (row.type === "thinking_started")
31
+ return { ...base, type: "thinking_started" };
32
+ if (row.type === "thinking_finished")
33
+ return { ...base, type: "thinking_finished", text: row.preview_text ?? "" };
34
+ if (row.type === "tool_call")
35
+ return { ...base, type: "tool_call", toolCallId: stringAttribute(attributes, "toolCallId") ?? row.event_id ?? `tool_${row.stream_id}`, toolName: row.preview_text ?? stringAttribute(attributes, "toolName") ?? "tool", args: inlinePayload ?? null, argsComplete: booleanAttribute(attributes, "argsComplete") ?? true };
36
+ if (row.type === "tool_execution_started")
37
+ return { ...base, type: "tool_execution_started", toolCallId: stringAttribute(attributes, "toolCallId") ?? row.event_id ?? `tool_${row.stream_id}`, toolName: row.preview_text ?? stringAttribute(attributes, "toolName") ?? "tool", args: inlinePayload ?? null };
38
+ if (row.type === "tool_execution_updated")
39
+ return { ...base, type: "tool_execution_updated", toolCallId: stringAttribute(attributes, "toolCallId") ?? row.event_id ?? `tool_${row.stream_id}`, toolName: row.preview_text ?? stringAttribute(attributes, "toolName") ?? "tool", args: null, partialResult: inlinePayload ?? null };
40
+ if (row.type === "tool_execution_finished")
41
+ return { ...base, type: "tool_execution_finished", toolCallId: stringAttribute(attributes, "toolCallId") ?? row.event_id ?? `tool_${row.stream_id}`, toolName: row.preview_text ?? stringAttribute(attributes, "toolName") ?? "tool", result: inlinePayload ?? null, isError: booleanAttribute(attributes, "isError") ?? false };
42
+ if (row.type === "execution_result")
43
+ return { ...base, type: "execution_result", action: row.preview_text ?? stringAttribute(attributes, "action") ?? "execution", result: inlinePayload ?? null };
44
+ if (row.type === "session_error") {
45
+ const error = stringAttribute(attributes, "error") ?? row.preview_text ?? "Error";
46
+ return { ...base, type: "session_error", error, errorDetails: normalizeSessionErrorDetails(error, isRecord(attributes.errorDetails) ? attributes.errorDetails : undefined) };
47
+ }
48
+ if (row.type === "user.message.accepted")
49
+ return { type: "user.message.accepted", piboSessionId, roomId: row.room_id ?? undefined, text: stringAttribute(attributes, "inlineText") ?? row.preview_text ?? "", clientTxnId: stringAttribute(attributes, "clientTxnId") };
50
+ return { ...base, type: row.type };
51
+ }
52
+ export function sessionFromRow(row) { return { piboSessionId: row.id, piSessionId: row.pi_session_id ?? row.id, parentId: row.parent_id ?? undefined, profile: row.profile, channel: row.channel, kind: row.kind, createdAt: row.created_at, updatedAt: row.updated_at, lastActivityAt: row.last_activity_at, status: row.status === "running" || row.status === "error" ? row.status : "idle" }; }
53
+ export function roomFromRow(row) { const metadata = parseJsonObject(row.metadata_json); return { id: row.id, name: row.name, topic: row.topic ?? undefined, workspace: row.workspace ?? roomWorkspaceFromMetadata(metadata), type: row.type, parentRoomId: row.parent_room_id ?? undefined, createdAt: row.created_at, updatedAt: row.updated_at, retentionPolicyId: row.retention_policy_id ?? undefined, metadata }; }
54
+ export function parseJsonObject(value) { try {
55
+ const parsed = JSON.parse(value);
56
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
57
+ }
58
+ catch {
59
+ return {};
60
+ } }
61
+ export function stringAttribute(attributes, key) { const value = attributes[key]; return typeof value === "string" ? value : undefined; }
62
+ function booleanAttribute(attributes, key) { const value = attributes[key]; return typeof value === "boolean" ? value : undefined; }
63
+ function numberAttribute(attributes, key) { const value = attributes[key]; return typeof value === "number" ? value : undefined; }
64
+ function isRecord(value) { return Boolean(value) && typeof value === "object" && !Array.isArray(value); }
65
+ export function nextSessionSequence(store, sessionId) { const row = store.db.prepare("SELECT COALESCE(MAX(session_sequence), 0) + 1 AS next_sequence FROM event_log WHERE session_id = ?").get(sessionId); return row.next_sequence; }
66
+ export function compactObject(value) { return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined)); }
67
+ export function previewForPayload(payload) { if (typeof payload === "object" && payload && "text" in payload && typeof payload.text === "string")
68
+ return payload.text.slice(0, 512); if (typeof payload === "string")
69
+ return payload.slice(0, 512); return undefined; }
70
+ export function statusFromOutputEvent(event) { if (event.type === "session_error")
71
+ return "error"; if (event.type === "message_finished")
72
+ return "idle"; return "running"; }
73
+ function actorTypeValue(value) { return value === "user" || value === "assistant" || value === "system" || value === "agent" ? value : undefined; }
74
+ function retentionClassValue(value) { return value === "live_delta" || value === "chat_message" || value === "audit_event" ? value : "trace_event"; }