@surething/cockpit 1.0.208 → 1.0.210

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 (575) hide show
  1. package/.next-prod/BUILD_ID +1 -1
  2. package/.next-prod/app-path-routes-manifest.json +12 -10
  3. package/.next-prod/build-manifest.json +4 -4
  4. package/.next-prod/diagnostics/framework.json +1 -1
  5. package/.next-prod/next-server.js.nft.json +1 -1
  6. package/.next-prod/prerender-manifest.json +3 -3
  7. package/.next-prod/react-loadable-manifest.json +25 -1
  8. package/.next-prod/routes-manifest.json +12 -0
  9. package/.next-prod/server/app/_global-error/page.js +3 -3
  10. package/.next-prod/server/app/_global-error/page.js.nft.json +1 -1
  11. package/.next-prod/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/.next-prod/server/app/_global-error.html +1 -1
  13. package/.next-prod/server/app/_global-error.rsc +1 -1
  14. package/.next-prod/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/.next-prod/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/.next-prod/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  17. package/.next-prod/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/.next-prod/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/.next-prod/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/.next-prod/server/app/_not-found/page.js +2 -2
  21. package/.next-prod/server/app/_not-found/page.js.nft.json +1 -1
  22. package/.next-prod/server/app/_not-found/page_client-reference-manifest.js +1 -1
  23. package/.next-prod/server/app/_not-found.html +1 -1
  24. package/.next-prod/server/app/_not-found.rsc +16 -17
  25. package/.next-prod/server/app/_not-found.segments/_full.segment.rsc +16 -17
  26. package/.next-prod/server/app/_not-found.segments/_head.segment.rsc +1 -1
  27. package/.next-prod/server/app/_not-found.segments/_index.segment.rsc +5 -6
  28. package/.next-prod/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  29. package/.next-prod/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  30. package/.next-prod/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  31. package/.next-prod/server/app/api/agent/test/route.js +1 -0
  32. package/.next-prod/server/app/api/agent/test/route.js.nft.json +1 -0
  33. package/.next-prod/server/app/api/agent/test/route_client-reference-manifest.js +1 -0
  34. package/.next-prod/server/app/api/bash/route.js +1 -1
  35. package/.next-prod/server/app/api/bash/route.js.nft.json +1 -1
  36. package/.next-prod/server/app/api/chat/codex/route.js +18 -18
  37. package/.next-prod/server/app/api/chat/codex/route.js.nft.json +1 -1
  38. package/.next-prod/server/app/api/chat/deepseek/route.js +4 -4
  39. package/.next-prod/server/app/api/chat/deepseek/route.js.nft.json +1 -1
  40. package/.next-prod/server/app/api/chat/kimi/route.js +18 -18
  41. package/.next-prod/server/app/api/chat/kimi/route.js.nft.json +1 -1
  42. package/.next-prod/server/app/api/chat/ollama/route.js +20 -109
  43. package/.next-prod/server/app/api/chat/ollama/route.js.nft.json +1 -1
  44. package/.next-prod/server/app/api/chat/route.js +4 -4
  45. package/.next-prod/server/app/api/chat/route.js.nft.json +1 -1
  46. package/.next-prod/server/app/api/claude-stats/route.js +1 -1
  47. package/.next-prod/server/app/api/claude-stats/route.js.nft.json +1 -1
  48. package/.next-prod/server/app/api/commands/route.js +1 -1
  49. package/.next-prod/server/app/api/commands/route.js.nft.json +1 -1
  50. package/.next-prod/server/app/api/comments/route.js +1 -1
  51. package/.next-prod/server/app/api/comments/route.js.nft.json +1 -1
  52. package/.next-prod/server/app/api/db/columns/route.js +15 -15
  53. package/.next-prod/server/app/api/db/columns/route.js.nft.json +1 -1
  54. package/.next-prod/server/app/api/db/connect/route.js +3 -1
  55. package/.next-prod/server/app/api/db/connect/route.js.nft.json +1 -1
  56. package/.next-prod/server/app/api/db/disconnect/route.js +1 -1
  57. package/.next-prod/server/app/api/db/disconnect/route.js.nft.json +1 -1
  58. package/.next-prod/server/app/api/db/export/route.js +1 -1
  59. package/.next-prod/server/app/api/db/export/route.js.nft.json +1 -1
  60. package/.next-prod/server/app/api/db/query/route.js +1 -1
  61. package/.next-prod/server/app/api/db/query/route.js.nft.json +1 -1
  62. package/.next-prod/server/app/api/db/schemas/route.js +2 -2
  63. package/.next-prod/server/app/api/db/schemas/route.js.nft.json +1 -1
  64. package/.next-prod/server/app/api/dev/spans/route.js +1 -0
  65. package/.next-prod/server/app/api/dev/spans/route.js.nft.json +1 -0
  66. package/.next-prod/server/app/api/dev/spans/route_client-reference-manifest.js +1 -0
  67. package/.next-prod/server/app/api/extension/version/route.js +1 -1
  68. package/.next-prod/server/app/api/extension/version/route.js.nft.json +1 -1
  69. package/.next-prod/server/app/api/file/route.js +1 -1
  70. package/.next-prod/server/app/api/file/route.js.nft.json +1 -1
  71. package/.next-prod/server/app/api/files/blame/route.js +1 -1
  72. package/.next-prod/server/app/api/files/blame/route.js.nft.json +1 -1
  73. package/.next-prod/server/app/api/files/clipboard/route.js +1 -1
  74. package/.next-prod/server/app/api/files/clipboard/route.js.nft.json +1 -1
  75. package/.next-prod/server/app/api/files/copy/route.js +1 -1
  76. package/.next-prod/server/app/api/files/copy/route.js.nft.json +1 -1
  77. package/.next-prod/server/app/api/files/delete/route.js +1 -1
  78. package/.next-prod/server/app/api/files/delete/route.js.nft.json +1 -1
  79. package/.next-prod/server/app/api/files/expanded/route.js +1 -1
  80. package/.next-prod/server/app/api/files/expanded/route.js.nft.json +1 -1
  81. package/.next-prod/server/app/api/files/index/route.js +1 -1
  82. package/.next-prod/server/app/api/files/index/route.js.nft.json +1 -1
  83. package/.next-prod/server/app/api/files/init/route.js +1 -1
  84. package/.next-prod/server/app/api/files/init/route.js.nft.json +1 -1
  85. package/.next-prod/server/app/api/files/paste/route.js +1 -1
  86. package/.next-prod/server/app/api/files/paste/route.js.nft.json +1 -1
  87. package/.next-prod/server/app/api/files/read/route.js +1 -1
  88. package/.next-prod/server/app/api/files/read/route.js.nft.json +1 -1
  89. package/.next-prod/server/app/api/files/readdir/route.js +1 -1
  90. package/.next-prod/server/app/api/files/readdir/route.js.nft.json +1 -1
  91. package/.next-prod/server/app/api/files/recent/route.js +1 -1
  92. package/.next-prod/server/app/api/files/recent/route.js.nft.json +1 -1
  93. package/.next-prod/server/app/api/files/save/route.js +1 -1
  94. package/.next-prod/server/app/api/files/save/route.js.nft.json +1 -1
  95. package/.next-prod/server/app/api/files/search/route.js +1 -1
  96. package/.next-prod/server/app/api/files/search/route.js.nft.json +1 -1
  97. package/.next-prod/server/app/api/files/stat/route.js +1 -1
  98. package/.next-prod/server/app/api/files/stat/route.js.nft.json +1 -1
  99. package/.next-prod/server/app/api/files/text/route.js +1 -1
  100. package/.next-prod/server/app/api/files/text/route.js.nft.json +1 -1
  101. package/.next-prod/server/app/api/git/branch-diff/route.js +1 -1
  102. package/.next-prod/server/app/api/git/branch-diff/route.js.nft.json +1 -1
  103. package/.next-prod/server/app/api/git/branches/route.js +1 -1
  104. package/.next-prod/server/app/api/git/branches/route.js.nft.json +1 -1
  105. package/.next-prod/server/app/api/git/commit-diff/route.js +1 -1
  106. package/.next-prod/server/app/api/git/commit-diff/route.js.nft.json +1 -1
  107. package/.next-prod/server/app/api/git/commits/route.js +1 -1
  108. package/.next-prod/server/app/api/git/commits/route.js.nft.json +1 -1
  109. package/.next-prod/server/app/api/git/diff/route.js +1 -1
  110. package/.next-prod/server/app/api/git/diff/route.js.nft.json +1 -1
  111. package/.next-prod/server/app/api/git/discard/route.js +1 -1
  112. package/.next-prod/server/app/api/git/discard/route.js.nft.json +1 -1
  113. package/.next-prod/server/app/api/git/stage/route.js +1 -1
  114. package/.next-prod/server/app/api/git/stage/route.js.nft.json +1 -1
  115. package/.next-prod/server/app/api/git/status/route.js +1 -1
  116. package/.next-prod/server/app/api/git/status/route.js.nft.json +1 -1
  117. package/.next-prod/server/app/api/git/unstage/route.js +1 -1
  118. package/.next-prod/server/app/api/git/unstage/route.js.nft.json +1 -1
  119. package/.next-prod/server/app/api/git/worktree/route.js +1 -1
  120. package/.next-prod/server/app/api/git/worktree/route.js.nft.json +1 -1
  121. package/.next-prod/server/app/api/global-state/route.js +1 -1
  122. package/.next-prod/server/app/api/global-state/route.js.nft.json +1 -1
  123. package/.next-prod/server/app/api/jupyter/load/route.js +1 -1
  124. package/.next-prod/server/app/api/jupyter/load/route.js.nft.json +1 -1
  125. package/.next-prod/server/app/api/jupyter/save/route.js +1 -1
  126. package/.next-prod/server/app/api/jupyter/save/route.js.nft.json +1 -1
  127. package/.next-prod/server/app/api/jupyter/shutdown/route.js +1 -1
  128. package/.next-prod/server/app/api/jupyter/shutdown/route.js.nft.json +1 -1
  129. package/.next-prod/server/app/api/lsp/definition/route.js +1 -1
  130. package/.next-prod/server/app/api/lsp/definition/route.js.nft.json +1 -1
  131. package/.next-prod/server/app/api/lsp/hover/route.js +1 -1
  132. package/.next-prod/server/app/api/lsp/hover/route.js.nft.json +1 -1
  133. package/.next-prod/server/app/api/lsp/references/route.js +1 -1
  134. package/.next-prod/server/app/api/lsp/references/route.js.nft.json +1 -1
  135. package/.next-prod/server/app/api/lsp/status/route.js +1 -1
  136. package/.next-prod/server/app/api/lsp/status/route.js.nft.json +1 -1
  137. package/.next-prod/server/app/api/lsp/warmup/route.js +1 -1
  138. package/.next-prod/server/app/api/lsp/warmup/route.js.nft.json +1 -1
  139. package/.next-prod/server/app/api/mysql/columns/route.js +9 -9
  140. package/.next-prod/server/app/api/mysql/columns/route.js.nft.json +1 -1
  141. package/.next-prod/server/app/api/mysql/connect/route.js +1 -1
  142. package/.next-prod/server/app/api/mysql/connect/route.js.nft.json +1 -1
  143. package/.next-prod/server/app/api/mysql/disconnect/route.js +1 -1
  144. package/.next-prod/server/app/api/mysql/disconnect/route.js.nft.json +1 -1
  145. package/.next-prod/server/app/api/mysql/export/route.js +1 -1
  146. package/.next-prod/server/app/api/mysql/export/route.js.nft.json +1 -1
  147. package/.next-prod/server/app/api/mysql/query/route.js +1 -1
  148. package/.next-prod/server/app/api/mysql/query/route.js.nft.json +1 -1
  149. package/.next-prod/server/app/api/mysql/schemas/route.js +2 -2
  150. package/.next-prod/server/app/api/mysql/schemas/route.js.nft.json +1 -1
  151. package/.next-prod/server/app/api/neo4j/connect/route.js +1 -1
  152. package/.next-prod/server/app/api/neo4j/connect/route.js.nft.json +1 -1
  153. package/.next-prod/server/app/api/neo4j/disconnect/route.js +1 -1
  154. package/.next-prod/server/app/api/neo4j/disconnect/route.js.nft.json +1 -1
  155. package/.next-prod/server/app/api/neo4j/query/route.js +1 -1
  156. package/.next-prod/server/app/api/neo4j/query/route.js.nft.json +1 -1
  157. package/.next-prod/server/app/api/neo4j/schema/route.js +1 -1
  158. package/.next-prod/server/app/api/neo4j/schema/route.js.nft.json +1 -1
  159. package/.next-prod/server/app/api/note/route.js +1 -1
  160. package/.next-prod/server/app/api/note/route.js.nft.json +1 -1
  161. package/.next-prod/server/app/api/ollama/models/route.js +1 -1
  162. package/.next-prod/server/app/api/ollama/models/route.js.nft.json +1 -1
  163. package/.next-prod/server/app/api/ollama/start/route.js +1 -1
  164. package/.next-prod/server/app/api/ollama/start/route.js.nft.json +1 -1
  165. package/.next-prod/server/app/api/open-cursor/route.js +1 -1
  166. package/.next-prod/server/app/api/open-cursor/route.js.nft.json +1 -1
  167. package/.next-prod/server/app/api/open-vscode/route.js +1 -1
  168. package/.next-prod/server/app/api/open-vscode/route.js.nft.json +1 -1
  169. package/.next-prod/server/app/api/pick-folder/route.js +1 -1
  170. package/.next-prod/server/app/api/pick-folder/route.js.nft.json +1 -1
  171. package/.next-prod/server/app/api/pinned-sessions/route.js +1 -1
  172. package/.next-prod/server/app/api/pinned-sessions/route.js.nft.json +1 -1
  173. package/.next-prod/server/app/api/project-settings/route.js +1 -1
  174. package/.next-prod/server/app/api/project-settings/route.js.nft.json +1 -1
  175. package/.next-prod/server/app/api/project-state/route.js +1 -1
  176. package/.next-prod/server/app/api/project-state/route.js.nft.json +1 -1
  177. package/.next-prod/server/app/api/projectGraph/file/route.js +1 -1
  178. package/.next-prod/server/app/api/projectGraph/file/route.js.nft.json +1 -1
  179. package/.next-prod/server/app/api/projectGraph/file-functions/route.js +1 -1
  180. package/.next-prod/server/app/api/projectGraph/file-functions/route.js.nft.json +1 -1
  181. package/.next-prod/server/app/api/projectGraph/search/route.js +1 -1
  182. package/.next-prod/server/app/api/projectGraph/search/route.js.nft.json +1 -1
  183. package/.next-prod/server/app/api/projects/route.js +1 -1
  184. package/.next-prod/server/app/api/projects/route.js.nft.json +1 -1
  185. package/.next-prod/server/app/api/redis/command/route.js +1 -1
  186. package/.next-prod/server/app/api/redis/command/route.js.nft.json +1 -1
  187. package/.next-prod/server/app/api/redis/connect/route.js +1 -1
  188. package/.next-prod/server/app/api/redis/connect/route.js.nft.json +1 -1
  189. package/.next-prod/server/app/api/redis/delete/route.js +1 -1
  190. package/.next-prod/server/app/api/redis/delete/route.js.nft.json +1 -1
  191. package/.next-prod/server/app/api/redis/disconnect/route.js +1 -1
  192. package/.next-prod/server/app/api/redis/disconnect/route.js.nft.json +1 -1
  193. package/.next-prod/server/app/api/redis/get/route.js +1 -1
  194. package/.next-prod/server/app/api/redis/get/route.js.nft.json +1 -1
  195. package/.next-prod/server/app/api/redis/keys/route.js +1 -1
  196. package/.next-prod/server/app/api/redis/keys/route.js.nft.json +1 -1
  197. package/.next-prod/server/app/api/redis/set/route.js +1 -1
  198. package/.next-prod/server/app/api/redis/set/route.js.nft.json +1 -1
  199. package/.next-prod/server/app/api/review/[id]/comments/route.js +1 -1
  200. package/.next-prod/server/app/api/review/[id]/comments/route.js.nft.json +1 -1
  201. package/.next-prod/server/app/api/review/[id]/replies/route.js +1 -1
  202. package/.next-prod/server/app/api/review/[id]/replies/route.js.nft.json +1 -1
  203. package/.next-prod/server/app/api/review/[id]/route.js +1 -1
  204. package/.next-prod/server/app/api/review/[id]/route.js.nft.json +1 -1
  205. package/.next-prod/server/app/api/review/identify/route.js +1 -1
  206. package/.next-prod/server/app/api/review/identify/route.js.nft.json +1 -1
  207. package/.next-prod/server/app/api/review/order/route.js +1 -1
  208. package/.next-prod/server/app/api/review/order/route.js.nft.json +1 -1
  209. package/.next-prod/server/app/api/review/route.js +1 -1
  210. package/.next-prod/server/app/api/review/route.js.nft.json +1 -1
  211. package/.next-prod/server/app/api/review/share-info/route.js +1 -1
  212. package/.next-prod/server/app/api/review/share-info/route.js.nft.json +1 -1
  213. package/.next-prod/server/app/api/review/users/route.js +1 -1
  214. package/.next-prod/server/app/api/review/users/route.js.nft.json +1 -1
  215. package/.next-prod/server/app/api/scheduled-tasks/route.js +1 -1
  216. package/.next-prod/server/app/api/scheduled-tasks/route.js.nft.json +1 -1
  217. package/.next-prod/server/app/api/services/config/route.js +1 -1
  218. package/.next-prod/server/app/api/services/config/route.js.nft.json +1 -1
  219. package/.next-prod/server/app/api/services/scripts/route.js +1 -1
  220. package/.next-prod/server/app/api/services/scripts/route.js.nft.json +1 -1
  221. package/.next-prod/server/app/api/session/[sessionId]/fork/route.js +1 -1
  222. package/.next-prod/server/app/api/session/[sessionId]/fork/route.js.nft.json +1 -1
  223. package/.next-prod/server/app/api/session/[sessionId]/history/route.js +1 -1
  224. package/.next-prod/server/app/api/session/[sessionId]/history/route.js.nft.json +1 -1
  225. package/.next-prod/server/app/api/session-by-path/route.js +1 -1
  226. package/.next-prod/server/app/api/session-by-path/route.js.nft.json +1 -1
  227. package/.next-prod/server/app/api/sessions/projects/[encodedPath]/route.js +1 -1
  228. package/.next-prod/server/app/api/sessions/projects/[encodedPath]/route.js.nft.json +1 -1
  229. package/.next-prod/server/app/api/sessions/projects/route.js +1 -1
  230. package/.next-prod/server/app/api/sessions/projects/route.js.nft.json +1 -1
  231. package/.next-prod/server/app/api/sessions/route.js +1 -1
  232. package/.next-prod/server/app/api/sessions/route.js.nft.json +1 -1
  233. package/.next-prod/server/app/api/settings/route.js +1 -1
  234. package/.next-prod/server/app/api/settings/route.js.nft.json +1 -1
  235. package/.next-prod/server/app/api/skills/[id]/route.js +1 -1
  236. package/.next-prod/server/app/api/skills/[id]/route.js.nft.json +1 -1
  237. package/.next-prod/server/app/api/skills/content/route.js +1 -1
  238. package/.next-prod/server/app/api/skills/content/route.js.nft.json +1 -1
  239. package/.next-prod/server/app/api/skills/route.js +1 -1
  240. package/.next-prod/server/app/api/skills/route.js.nft.json +1 -1
  241. package/.next-prod/server/app/api/terminal/aliases/route.js +1 -1
  242. package/.next-prod/server/app/api/terminal/aliases/route.js.nft.json +1 -1
  243. package/.next-prod/server/app/api/terminal/autocomplete/route.js +1 -1
  244. package/.next-prod/server/app/api/terminal/autocomplete/route.js.nft.json +1 -1
  245. package/.next-prod/server/app/api/terminal/bubble-order/route.js +1 -1
  246. package/.next-prod/server/app/api/terminal/bubble-order/route.js.nft.json +1 -1
  247. package/.next-prod/server/app/api/terminal/env/route.js +1 -1
  248. package/.next-prod/server/app/api/terminal/env/route.js.nft.json +1 -1
  249. package/.next-prod/server/app/api/terminal/history/route.js +1 -1
  250. package/.next-prod/server/app/api/terminal/history/route.js.nft.json +1 -1
  251. package/.next-prod/server/app/api/version/route.js +1 -1
  252. package/.next-prod/server/app/api/version/route.js.nft.json +1 -1
  253. package/.next-prod/server/app/favicon.ico/route.js +1 -1
  254. package/.next-prod/server/app/favicon.ico/route.js.nft.json +1 -1
  255. package/.next-prod/server/app/manifest.webmanifest/route.js +2 -2
  256. package/.next-prod/server/app/manifest.webmanifest/route.js.nft.json +1 -1
  257. package/.next-prod/server/app/manifest.webmanifest.body +1 -1
  258. package/.next-prod/server/app/page.js +2 -2
  259. package/.next-prod/server/app/page.js.nft.json +1 -1
  260. package/.next-prod/server/app/page_client-reference-manifest.js +1 -1
  261. package/.next-prod/server/app/project/page.js +2 -2
  262. package/.next-prod/server/app/project/page.js.nft.json +1 -1
  263. package/.next-prod/server/app/project/page_client-reference-manifest.js +1 -1
  264. package/.next-prod/server/app/review/[id]/page.js +2 -2
  265. package/.next-prod/server/app/review/[id]/page.js.nft.json +1 -1
  266. package/.next-prod/server/app/review/[id]/page_client-reference-manifest.js +1 -1
  267. package/.next-prod/server/app-paths-manifest.json +12 -10
  268. package/.next-prod/server/chunks/2728.js +1 -0
  269. package/.next-prod/server/chunks/304.js +1 -0
  270. package/.next-prod/server/chunks/3718.js +1 -0
  271. package/.next-prod/server/chunks/3863.js +1 -0
  272. package/.next-prod/server/chunks/4034.js +114 -0
  273. package/.next-prod/server/chunks/4741.js +2 -2
  274. package/.next-prod/server/chunks/5159.js +1 -0
  275. package/.next-prod/server/chunks/{6007.js → 5292.js} +2 -2
  276. package/.next-prod/server/chunks/5616.js +1 -0
  277. package/.next-prod/server/chunks/6955.js +1 -0
  278. package/.next-prod/server/chunks/7184.js +244 -0
  279. package/.next-prod/server/chunks/7973.js +15 -0
  280. package/.next-prod/server/chunks/8916.js +1 -0
  281. package/.next-prod/server/chunks/9658.js +42 -0
  282. package/.next-prod/server/functions-config-manifest.json +2 -0
  283. package/.next-prod/server/middleware-build-manifest.js +1 -1
  284. package/.next-prod/server/middleware-react-loadable-manifest.js +1 -1
  285. package/.next-prod/server/pages/404.html +1 -1
  286. package/.next-prod/server/pages/500.html +1 -1
  287. package/.next-prod/server/server-reference-manifest.json +1 -1
  288. package/.next-prod/static/LJRtmjYCuVrSA_dcelxlR/_buildManifest.js +1 -0
  289. package/.next-prod/static/chunks/2580.69af80de5bcfcefe.js +1 -0
  290. package/.next-prod/static/chunks/2708.7263182a029113c8.js +1 -0
  291. package/.next-prod/static/chunks/327-9ffab8f0b2b0b4cd.js +13 -0
  292. package/.next-prod/static/chunks/{3794-3fb4e6ee851037bb.js → 3794-ba2500baa4c52d55.js} +3 -3
  293. package/.next-prod/static/chunks/5188-6ad3d686c5e9fb28.js +29 -0
  294. package/.next-prod/static/chunks/{5204-c8293184aa55cdd5.js → 5204-babf0d0290febbec.js} +1 -1
  295. package/.next-prod/static/chunks/6345-3c06cdc8c89677b8.js +14 -0
  296. package/.next-prod/static/chunks/7562.8fdc3abdd45c77ab.js +1 -0
  297. package/.next-prod/static/chunks/9012.6ed079104670001d.js +1 -0
  298. package/.next-prod/static/chunks/9617.d038e8ea9fc93e24.js +1 -0
  299. package/.next-prod/static/chunks/96c8525a-f1e0653013503d49.js +2 -0
  300. package/.next-prod/static/chunks/app/_global-error/page-826847d169541fa9.js +1 -0
  301. package/.next-prod/static/chunks/app/api/agent/test/route-826847d169541fa9.js +1 -0
  302. package/.next-prod/static/chunks/app/api/bash/route-826847d169541fa9.js +1 -0
  303. package/.next-prod/static/chunks/app/api/chat/codex/route-826847d169541fa9.js +1 -0
  304. package/.next-prod/static/chunks/app/api/chat/deepseek/route-826847d169541fa9.js +1 -0
  305. package/.next-prod/static/chunks/app/api/chat/kimi/route-826847d169541fa9.js +1 -0
  306. package/.next-prod/static/chunks/app/api/chat/ollama/route-826847d169541fa9.js +1 -0
  307. package/.next-prod/static/chunks/app/api/chat/route-826847d169541fa9.js +1 -0
  308. package/.next-prod/static/chunks/app/api/claude-stats/route-826847d169541fa9.js +1 -0
  309. package/.next-prod/static/chunks/app/api/commands/route-826847d169541fa9.js +1 -0
  310. package/.next-prod/static/chunks/app/api/comments/route-826847d169541fa9.js +1 -0
  311. package/.next-prod/static/chunks/app/api/db/columns/route-826847d169541fa9.js +1 -0
  312. package/.next-prod/static/chunks/app/api/db/connect/route-826847d169541fa9.js +1 -0
  313. package/.next-prod/static/chunks/app/api/db/disconnect/route-826847d169541fa9.js +1 -0
  314. package/.next-prod/static/chunks/app/api/db/export/route-826847d169541fa9.js +1 -0
  315. package/.next-prod/static/chunks/app/api/db/query/route-826847d169541fa9.js +1 -0
  316. package/.next-prod/static/chunks/app/api/db/schemas/route-826847d169541fa9.js +1 -0
  317. package/.next-prod/static/chunks/app/api/dev/spans/route-826847d169541fa9.js +1 -0
  318. package/.next-prod/static/chunks/app/api/extension/version/route-826847d169541fa9.js +1 -0
  319. package/.next-prod/static/chunks/app/api/file/route-826847d169541fa9.js +1 -0
  320. package/.next-prod/static/chunks/app/api/files/blame/route-826847d169541fa9.js +1 -0
  321. package/.next-prod/static/chunks/app/api/files/clipboard/route-826847d169541fa9.js +1 -0
  322. package/.next-prod/static/chunks/app/api/files/copy/route-826847d169541fa9.js +1 -0
  323. package/.next-prod/static/chunks/app/api/files/delete/route-826847d169541fa9.js +1 -0
  324. package/.next-prod/static/chunks/app/api/files/expanded/route-826847d169541fa9.js +1 -0
  325. package/.next-prod/static/chunks/app/api/files/index/route-826847d169541fa9.js +1 -0
  326. package/.next-prod/static/chunks/app/api/files/init/route-826847d169541fa9.js +1 -0
  327. package/.next-prod/static/chunks/app/api/files/paste/route-826847d169541fa9.js +1 -0
  328. package/.next-prod/static/chunks/app/api/files/read/route-826847d169541fa9.js +1 -0
  329. package/.next-prod/static/chunks/app/api/files/readdir/route-826847d169541fa9.js +1 -0
  330. package/.next-prod/static/chunks/app/api/files/recent/route-826847d169541fa9.js +1 -0
  331. package/.next-prod/static/chunks/app/api/files/save/route-826847d169541fa9.js +1 -0
  332. package/.next-prod/static/chunks/app/api/files/search/route-826847d169541fa9.js +1 -0
  333. package/.next-prod/static/chunks/app/api/files/stat/route-826847d169541fa9.js +1 -0
  334. package/.next-prod/static/chunks/app/api/files/text/route-826847d169541fa9.js +1 -0
  335. package/.next-prod/static/chunks/app/api/git/branch-diff/route-826847d169541fa9.js +1 -0
  336. package/.next-prod/static/chunks/app/api/git/branches/route-826847d169541fa9.js +1 -0
  337. package/.next-prod/static/chunks/app/api/git/commit-diff/route-826847d169541fa9.js +1 -0
  338. package/.next-prod/static/chunks/app/api/git/commits/route-826847d169541fa9.js +1 -0
  339. package/.next-prod/static/chunks/app/api/git/diff/route-826847d169541fa9.js +1 -0
  340. package/.next-prod/static/chunks/app/api/git/discard/route-826847d169541fa9.js +1 -0
  341. package/.next-prod/static/chunks/app/api/git/stage/route-826847d169541fa9.js +1 -0
  342. package/.next-prod/static/chunks/app/api/git/status/route-826847d169541fa9.js +1 -0
  343. package/.next-prod/static/chunks/app/api/git/unstage/route-826847d169541fa9.js +1 -0
  344. package/.next-prod/static/chunks/app/api/git/worktree/route-826847d169541fa9.js +1 -0
  345. package/.next-prod/static/chunks/app/api/global-state/route-826847d169541fa9.js +1 -0
  346. package/.next-prod/static/chunks/app/api/jupyter/load/route-826847d169541fa9.js +1 -0
  347. package/.next-prod/static/chunks/app/api/jupyter/save/route-826847d169541fa9.js +1 -0
  348. package/.next-prod/static/chunks/app/api/jupyter/shutdown/route-826847d169541fa9.js +1 -0
  349. package/.next-prod/static/chunks/app/api/lsp/definition/route-826847d169541fa9.js +1 -0
  350. package/.next-prod/static/chunks/app/api/lsp/hover/route-826847d169541fa9.js +1 -0
  351. package/.next-prod/static/chunks/app/api/lsp/references/route-826847d169541fa9.js +1 -0
  352. package/.next-prod/static/chunks/app/api/lsp/status/route-826847d169541fa9.js +1 -0
  353. package/.next-prod/static/chunks/app/api/lsp/warmup/route-826847d169541fa9.js +1 -0
  354. package/.next-prod/static/chunks/app/api/mysql/columns/route-826847d169541fa9.js +1 -0
  355. package/.next-prod/static/chunks/app/api/mysql/connect/route-826847d169541fa9.js +1 -0
  356. package/.next-prod/static/chunks/app/api/mysql/disconnect/route-826847d169541fa9.js +1 -0
  357. package/.next-prod/static/chunks/app/api/mysql/export/route-826847d169541fa9.js +1 -0
  358. package/.next-prod/static/chunks/app/api/mysql/query/route-826847d169541fa9.js +1 -0
  359. package/.next-prod/static/chunks/app/api/mysql/schemas/route-826847d169541fa9.js +1 -0
  360. package/.next-prod/static/chunks/app/api/neo4j/connect/route-826847d169541fa9.js +1 -0
  361. package/.next-prod/static/chunks/app/api/neo4j/disconnect/route-826847d169541fa9.js +1 -0
  362. package/.next-prod/static/chunks/app/api/neo4j/query/route-826847d169541fa9.js +1 -0
  363. package/.next-prod/static/chunks/app/api/neo4j/schema/route-826847d169541fa9.js +1 -0
  364. package/.next-prod/static/chunks/app/api/note/route-826847d169541fa9.js +1 -0
  365. package/.next-prod/static/chunks/app/api/ollama/models/route-826847d169541fa9.js +1 -0
  366. package/.next-prod/static/chunks/app/api/ollama/start/route-826847d169541fa9.js +1 -0
  367. package/.next-prod/static/chunks/app/api/open-cursor/route-826847d169541fa9.js +1 -0
  368. package/.next-prod/static/chunks/app/api/open-vscode/route-826847d169541fa9.js +1 -0
  369. package/.next-prod/static/chunks/app/api/pick-folder/route-826847d169541fa9.js +1 -0
  370. package/.next-prod/static/chunks/app/api/pinned-sessions/route-826847d169541fa9.js +1 -0
  371. package/.next-prod/static/chunks/app/api/project-settings/route-826847d169541fa9.js +1 -0
  372. package/.next-prod/static/chunks/app/api/project-state/route-826847d169541fa9.js +1 -0
  373. package/.next-prod/static/chunks/app/api/projectGraph/file/route-826847d169541fa9.js +1 -0
  374. package/.next-prod/static/chunks/app/api/projectGraph/file-functions/route-826847d169541fa9.js +1 -0
  375. package/.next-prod/static/chunks/app/api/projectGraph/search/route-826847d169541fa9.js +1 -0
  376. package/.next-prod/static/chunks/app/api/projects/route-826847d169541fa9.js +1 -0
  377. package/.next-prod/static/chunks/app/api/redis/command/route-826847d169541fa9.js +1 -0
  378. package/.next-prod/static/chunks/app/api/redis/connect/route-826847d169541fa9.js +1 -0
  379. package/.next-prod/static/chunks/app/api/redis/delete/route-826847d169541fa9.js +1 -0
  380. package/.next-prod/static/chunks/app/api/redis/disconnect/route-826847d169541fa9.js +1 -0
  381. package/.next-prod/static/chunks/app/api/redis/get/route-826847d169541fa9.js +1 -0
  382. package/.next-prod/static/chunks/app/api/redis/keys/route-826847d169541fa9.js +1 -0
  383. package/.next-prod/static/chunks/app/api/redis/set/route-826847d169541fa9.js +1 -0
  384. package/.next-prod/static/chunks/app/api/review/[id]/comments/route-826847d169541fa9.js +1 -0
  385. package/.next-prod/static/chunks/app/api/review/[id]/replies/route-826847d169541fa9.js +1 -0
  386. package/.next-prod/static/chunks/app/api/review/[id]/route-826847d169541fa9.js +1 -0
  387. package/.next-prod/static/chunks/app/api/review/identify/route-826847d169541fa9.js +1 -0
  388. package/.next-prod/static/chunks/app/api/review/order/route-826847d169541fa9.js +1 -0
  389. package/.next-prod/static/chunks/app/api/review/route-826847d169541fa9.js +1 -0
  390. package/.next-prod/static/chunks/app/api/review/share-info/route-826847d169541fa9.js +1 -0
  391. package/.next-prod/static/chunks/app/api/review/users/route-826847d169541fa9.js +1 -0
  392. package/.next-prod/static/chunks/app/api/scheduled-tasks/route-826847d169541fa9.js +1 -0
  393. package/.next-prod/static/chunks/app/api/services/config/route-826847d169541fa9.js +1 -0
  394. package/.next-prod/static/chunks/app/api/services/scripts/route-826847d169541fa9.js +1 -0
  395. package/.next-prod/static/chunks/app/api/session/[sessionId]/fork/route-826847d169541fa9.js +1 -0
  396. package/.next-prod/static/chunks/app/api/session/[sessionId]/history/route-826847d169541fa9.js +1 -0
  397. package/.next-prod/static/chunks/app/api/session-by-path/route-826847d169541fa9.js +1 -0
  398. package/.next-prod/static/chunks/app/api/sessions/projects/[encodedPath]/route-826847d169541fa9.js +1 -0
  399. package/.next-prod/static/chunks/app/api/sessions/projects/route-826847d169541fa9.js +1 -0
  400. package/.next-prod/static/chunks/app/api/sessions/route-826847d169541fa9.js +1 -0
  401. package/.next-prod/static/chunks/app/api/settings/route-826847d169541fa9.js +1 -0
  402. package/.next-prod/static/chunks/app/api/skills/[id]/route-826847d169541fa9.js +1 -0
  403. package/.next-prod/static/chunks/app/api/skills/content/route-826847d169541fa9.js +1 -0
  404. package/.next-prod/static/chunks/app/api/skills/route-826847d169541fa9.js +1 -0
  405. package/.next-prod/static/chunks/app/api/terminal/aliases/route-826847d169541fa9.js +1 -0
  406. package/.next-prod/static/chunks/app/api/terminal/autocomplete/route-826847d169541fa9.js +1 -0
  407. package/.next-prod/static/chunks/app/api/terminal/bubble-order/route-826847d169541fa9.js +1 -0
  408. package/.next-prod/static/chunks/app/api/terminal/env/route-826847d169541fa9.js +1 -0
  409. package/.next-prod/static/chunks/app/api/terminal/history/route-826847d169541fa9.js +1 -0
  410. package/.next-prod/static/chunks/app/api/version/route-826847d169541fa9.js +1 -0
  411. package/.next-prod/static/chunks/app/layout-a0362651ba6e6e6f.js +1 -0
  412. package/.next-prod/static/chunks/app/manifest.webmanifest/route-826847d169541fa9.js +1 -0
  413. package/.next-prod/static/chunks/app/{page-db32ebfdf1ac9174.js → page-1b14cabf47df9ff7.js} +1 -1
  414. package/.next-prod/static/chunks/app/project/{page-db32ebfdf1ac9174.js → page-1b14cabf47df9ff7.js} +1 -1
  415. package/.next-prod/static/chunks/app/review/[id]/page-7db3a48a13f1840c.js +1 -0
  416. package/.next-prod/static/chunks/bc21e3dd-a78364524623b9b0.js +1 -0
  417. package/.next-prod/static/chunks/{main-5a46314a5491113b.js → main-79827b1543335b12.js} +3 -3
  418. package/.next-prod/static/chunks/next/dist/client/components/builtin/app-error-826847d169541fa9.js +1 -0
  419. package/.next-prod/static/chunks/next/dist/client/components/builtin/forbidden-826847d169541fa9.js +1 -0
  420. package/.next-prod/static/chunks/next/dist/client/components/builtin/not-found-826847d169541fa9.js +1 -0
  421. package/.next-prod/static/chunks/next/dist/client/components/builtin/unauthorized-826847d169541fa9.js +1 -0
  422. package/.next-prod/static/chunks/webpack-b618ac52d349e5ca.js +1 -0
  423. package/.next-prod/static/css/dcde719317bea028.css +1 -0
  424. package/.next-prod/trace +12 -12
  425. package/.next-prod/trace-build +1 -1
  426. package/.next-prod/types/app/api/agent/test/route.ts +351 -0
  427. package/.next-prod/types/app/api/dev/spans/route.ts +351 -0
  428. package/.next-prod/types/routes.d.ts +3 -1
  429. package/.next-prod/types/validator.ts +18 -0
  430. package/README.md +29 -8
  431. package/README.zh.md +30 -9
  432. package/dist/{chunk-VCZEGP64.mjs → chunk-FBR4KJI5.mjs} +24 -250
  433. package/dist/chunk-OWUW2O3D.mjs +28475 -0
  434. package/dist/{chunk-RSHKDWJM.mjs → chunk-TXBVUZVH.mjs} +94 -0
  435. package/dist/httpApi.mjs +239 -0
  436. package/dist/scheduledTasks.mjs +1239 -66
  437. package/dist/{server-K6XWP7DX.mjs → server-E7G55DY7.mjs} +9 -10
  438. package/dist/wsServer.mjs +867 -704
  439. package/package.json +17 -4
  440. package/server.mjs +3 -1
  441. package/.next-prod/server/chunks/240.js +0 -1
  442. package/.next-prod/server/chunks/3204.js +0 -42
  443. package/.next-prod/server/chunks/5466.js +0 -1
  444. package/.next-prod/server/chunks/7264.js +0 -5
  445. package/.next-prod/server/chunks/8465.js +0 -15
  446. package/.next-prod/server/chunks/8750.js +0 -1
  447. package/.next-prod/server/chunks/900.js +0 -1
  448. package/.next-prod/server/chunks/9255.js +0 -1
  449. package/.next-prod/server/chunks/9755.js +0 -101
  450. package/.next-prod/server/chunks/987.js +0 -139
  451. package/.next-prod/static/WsSesL2O_jRoZztt2Y5r6/_buildManifest.js +0 -1
  452. package/.next-prod/static/chunks/327.8ecab0b86d52b597.js +0 -1
  453. package/.next-prod/static/chunks/5660-3d87dfb12f95e96d.js +0 -29
  454. package/.next-prod/static/chunks/6028-1d6ced1439a3f01f.js +0 -1
  455. package/.next-prod/static/chunks/6345-6b34b0528ff833a1.js +0 -14
  456. package/.next-prod/static/chunks/app/_global-error/page-7975a2b8c7d0b214.js +0 -1
  457. package/.next-prod/static/chunks/app/api/bash/route-7975a2b8c7d0b214.js +0 -1
  458. package/.next-prod/static/chunks/app/api/chat/codex/route-7975a2b8c7d0b214.js +0 -1
  459. package/.next-prod/static/chunks/app/api/chat/deepseek/route-7975a2b8c7d0b214.js +0 -1
  460. package/.next-prod/static/chunks/app/api/chat/kimi/route-7975a2b8c7d0b214.js +0 -1
  461. package/.next-prod/static/chunks/app/api/chat/ollama/route-7975a2b8c7d0b214.js +0 -1
  462. package/.next-prod/static/chunks/app/api/chat/route-7975a2b8c7d0b214.js +0 -1
  463. package/.next-prod/static/chunks/app/api/claude-stats/route-7975a2b8c7d0b214.js +0 -1
  464. package/.next-prod/static/chunks/app/api/commands/route-7975a2b8c7d0b214.js +0 -1
  465. package/.next-prod/static/chunks/app/api/comments/route-7975a2b8c7d0b214.js +0 -1
  466. package/.next-prod/static/chunks/app/api/db/columns/route-7975a2b8c7d0b214.js +0 -1
  467. package/.next-prod/static/chunks/app/api/db/connect/route-7975a2b8c7d0b214.js +0 -1
  468. package/.next-prod/static/chunks/app/api/db/disconnect/route-7975a2b8c7d0b214.js +0 -1
  469. package/.next-prod/static/chunks/app/api/db/export/route-7975a2b8c7d0b214.js +0 -1
  470. package/.next-prod/static/chunks/app/api/db/query/route-7975a2b8c7d0b214.js +0 -1
  471. package/.next-prod/static/chunks/app/api/db/schemas/route-7975a2b8c7d0b214.js +0 -1
  472. package/.next-prod/static/chunks/app/api/extension/version/route-7975a2b8c7d0b214.js +0 -1
  473. package/.next-prod/static/chunks/app/api/file/route-7975a2b8c7d0b214.js +0 -1
  474. package/.next-prod/static/chunks/app/api/files/blame/route-7975a2b8c7d0b214.js +0 -1
  475. package/.next-prod/static/chunks/app/api/files/clipboard/route-7975a2b8c7d0b214.js +0 -1
  476. package/.next-prod/static/chunks/app/api/files/copy/route-7975a2b8c7d0b214.js +0 -1
  477. package/.next-prod/static/chunks/app/api/files/delete/route-7975a2b8c7d0b214.js +0 -1
  478. package/.next-prod/static/chunks/app/api/files/expanded/route-7975a2b8c7d0b214.js +0 -1
  479. package/.next-prod/static/chunks/app/api/files/index/route-7975a2b8c7d0b214.js +0 -1
  480. package/.next-prod/static/chunks/app/api/files/init/route-7975a2b8c7d0b214.js +0 -1
  481. package/.next-prod/static/chunks/app/api/files/paste/route-7975a2b8c7d0b214.js +0 -1
  482. package/.next-prod/static/chunks/app/api/files/read/route-7975a2b8c7d0b214.js +0 -1
  483. package/.next-prod/static/chunks/app/api/files/readdir/route-7975a2b8c7d0b214.js +0 -1
  484. package/.next-prod/static/chunks/app/api/files/recent/route-7975a2b8c7d0b214.js +0 -1
  485. package/.next-prod/static/chunks/app/api/files/save/route-7975a2b8c7d0b214.js +0 -1
  486. package/.next-prod/static/chunks/app/api/files/search/route-7975a2b8c7d0b214.js +0 -1
  487. package/.next-prod/static/chunks/app/api/files/stat/route-7975a2b8c7d0b214.js +0 -1
  488. package/.next-prod/static/chunks/app/api/files/text/route-7975a2b8c7d0b214.js +0 -1
  489. package/.next-prod/static/chunks/app/api/git/branch-diff/route-7975a2b8c7d0b214.js +0 -1
  490. package/.next-prod/static/chunks/app/api/git/branches/route-7975a2b8c7d0b214.js +0 -1
  491. package/.next-prod/static/chunks/app/api/git/commit-diff/route-7975a2b8c7d0b214.js +0 -1
  492. package/.next-prod/static/chunks/app/api/git/commits/route-7975a2b8c7d0b214.js +0 -1
  493. package/.next-prod/static/chunks/app/api/git/diff/route-7975a2b8c7d0b214.js +0 -1
  494. package/.next-prod/static/chunks/app/api/git/discard/route-7975a2b8c7d0b214.js +0 -1
  495. package/.next-prod/static/chunks/app/api/git/stage/route-7975a2b8c7d0b214.js +0 -1
  496. package/.next-prod/static/chunks/app/api/git/status/route-7975a2b8c7d0b214.js +0 -1
  497. package/.next-prod/static/chunks/app/api/git/unstage/route-7975a2b8c7d0b214.js +0 -1
  498. package/.next-prod/static/chunks/app/api/git/worktree/route-7975a2b8c7d0b214.js +0 -1
  499. package/.next-prod/static/chunks/app/api/global-state/route-7975a2b8c7d0b214.js +0 -1
  500. package/.next-prod/static/chunks/app/api/jupyter/load/route-7975a2b8c7d0b214.js +0 -1
  501. package/.next-prod/static/chunks/app/api/jupyter/save/route-7975a2b8c7d0b214.js +0 -1
  502. package/.next-prod/static/chunks/app/api/jupyter/shutdown/route-7975a2b8c7d0b214.js +0 -1
  503. package/.next-prod/static/chunks/app/api/lsp/definition/route-7975a2b8c7d0b214.js +0 -1
  504. package/.next-prod/static/chunks/app/api/lsp/hover/route-7975a2b8c7d0b214.js +0 -1
  505. package/.next-prod/static/chunks/app/api/lsp/references/route-7975a2b8c7d0b214.js +0 -1
  506. package/.next-prod/static/chunks/app/api/lsp/status/route-7975a2b8c7d0b214.js +0 -1
  507. package/.next-prod/static/chunks/app/api/lsp/warmup/route-7975a2b8c7d0b214.js +0 -1
  508. package/.next-prod/static/chunks/app/api/mysql/columns/route-7975a2b8c7d0b214.js +0 -1
  509. package/.next-prod/static/chunks/app/api/mysql/connect/route-7975a2b8c7d0b214.js +0 -1
  510. package/.next-prod/static/chunks/app/api/mysql/disconnect/route-7975a2b8c7d0b214.js +0 -1
  511. package/.next-prod/static/chunks/app/api/mysql/export/route-7975a2b8c7d0b214.js +0 -1
  512. package/.next-prod/static/chunks/app/api/mysql/query/route-7975a2b8c7d0b214.js +0 -1
  513. package/.next-prod/static/chunks/app/api/mysql/schemas/route-7975a2b8c7d0b214.js +0 -1
  514. package/.next-prod/static/chunks/app/api/neo4j/connect/route-7975a2b8c7d0b214.js +0 -1
  515. package/.next-prod/static/chunks/app/api/neo4j/disconnect/route-7975a2b8c7d0b214.js +0 -1
  516. package/.next-prod/static/chunks/app/api/neo4j/query/route-7975a2b8c7d0b214.js +0 -1
  517. package/.next-prod/static/chunks/app/api/neo4j/schema/route-7975a2b8c7d0b214.js +0 -1
  518. package/.next-prod/static/chunks/app/api/note/route-7975a2b8c7d0b214.js +0 -1
  519. package/.next-prod/static/chunks/app/api/ollama/models/route-7975a2b8c7d0b214.js +0 -1
  520. package/.next-prod/static/chunks/app/api/ollama/start/route-7975a2b8c7d0b214.js +0 -1
  521. package/.next-prod/static/chunks/app/api/open-cursor/route-7975a2b8c7d0b214.js +0 -1
  522. package/.next-prod/static/chunks/app/api/open-vscode/route-7975a2b8c7d0b214.js +0 -1
  523. package/.next-prod/static/chunks/app/api/pick-folder/route-7975a2b8c7d0b214.js +0 -1
  524. package/.next-prod/static/chunks/app/api/pinned-sessions/route-7975a2b8c7d0b214.js +0 -1
  525. package/.next-prod/static/chunks/app/api/project-settings/route-7975a2b8c7d0b214.js +0 -1
  526. package/.next-prod/static/chunks/app/api/project-state/route-7975a2b8c7d0b214.js +0 -1
  527. package/.next-prod/static/chunks/app/api/projectGraph/file/route-7975a2b8c7d0b214.js +0 -1
  528. package/.next-prod/static/chunks/app/api/projectGraph/file-functions/route-7975a2b8c7d0b214.js +0 -1
  529. package/.next-prod/static/chunks/app/api/projectGraph/search/route-7975a2b8c7d0b214.js +0 -1
  530. package/.next-prod/static/chunks/app/api/projects/route-7975a2b8c7d0b214.js +0 -1
  531. package/.next-prod/static/chunks/app/api/redis/command/route-7975a2b8c7d0b214.js +0 -1
  532. package/.next-prod/static/chunks/app/api/redis/connect/route-7975a2b8c7d0b214.js +0 -1
  533. package/.next-prod/static/chunks/app/api/redis/delete/route-7975a2b8c7d0b214.js +0 -1
  534. package/.next-prod/static/chunks/app/api/redis/disconnect/route-7975a2b8c7d0b214.js +0 -1
  535. package/.next-prod/static/chunks/app/api/redis/get/route-7975a2b8c7d0b214.js +0 -1
  536. package/.next-prod/static/chunks/app/api/redis/keys/route-7975a2b8c7d0b214.js +0 -1
  537. package/.next-prod/static/chunks/app/api/redis/set/route-7975a2b8c7d0b214.js +0 -1
  538. package/.next-prod/static/chunks/app/api/review/[id]/comments/route-7975a2b8c7d0b214.js +0 -1
  539. package/.next-prod/static/chunks/app/api/review/[id]/replies/route-7975a2b8c7d0b214.js +0 -1
  540. package/.next-prod/static/chunks/app/api/review/[id]/route-7975a2b8c7d0b214.js +0 -1
  541. package/.next-prod/static/chunks/app/api/review/identify/route-7975a2b8c7d0b214.js +0 -1
  542. package/.next-prod/static/chunks/app/api/review/order/route-7975a2b8c7d0b214.js +0 -1
  543. package/.next-prod/static/chunks/app/api/review/route-7975a2b8c7d0b214.js +0 -1
  544. package/.next-prod/static/chunks/app/api/review/share-info/route-7975a2b8c7d0b214.js +0 -1
  545. package/.next-prod/static/chunks/app/api/review/users/route-7975a2b8c7d0b214.js +0 -1
  546. package/.next-prod/static/chunks/app/api/scheduled-tasks/route-7975a2b8c7d0b214.js +0 -1
  547. package/.next-prod/static/chunks/app/api/services/config/route-7975a2b8c7d0b214.js +0 -1
  548. package/.next-prod/static/chunks/app/api/services/scripts/route-7975a2b8c7d0b214.js +0 -1
  549. package/.next-prod/static/chunks/app/api/session/[sessionId]/fork/route-7975a2b8c7d0b214.js +0 -1
  550. package/.next-prod/static/chunks/app/api/session/[sessionId]/history/route-7975a2b8c7d0b214.js +0 -1
  551. package/.next-prod/static/chunks/app/api/session-by-path/route-7975a2b8c7d0b214.js +0 -1
  552. package/.next-prod/static/chunks/app/api/sessions/projects/[encodedPath]/route-7975a2b8c7d0b214.js +0 -1
  553. package/.next-prod/static/chunks/app/api/sessions/projects/route-7975a2b8c7d0b214.js +0 -1
  554. package/.next-prod/static/chunks/app/api/sessions/route-7975a2b8c7d0b214.js +0 -1
  555. package/.next-prod/static/chunks/app/api/settings/route-7975a2b8c7d0b214.js +0 -1
  556. package/.next-prod/static/chunks/app/api/skills/[id]/route-7975a2b8c7d0b214.js +0 -1
  557. package/.next-prod/static/chunks/app/api/skills/content/route-7975a2b8c7d0b214.js +0 -1
  558. package/.next-prod/static/chunks/app/api/skills/route-7975a2b8c7d0b214.js +0 -1
  559. package/.next-prod/static/chunks/app/api/terminal/aliases/route-7975a2b8c7d0b214.js +0 -1
  560. package/.next-prod/static/chunks/app/api/terminal/autocomplete/route-7975a2b8c7d0b214.js +0 -1
  561. package/.next-prod/static/chunks/app/api/terminal/bubble-order/route-7975a2b8c7d0b214.js +0 -1
  562. package/.next-prod/static/chunks/app/api/terminal/env/route-7975a2b8c7d0b214.js +0 -1
  563. package/.next-prod/static/chunks/app/api/terminal/history/route-7975a2b8c7d0b214.js +0 -1
  564. package/.next-prod/static/chunks/app/api/version/route-7975a2b8c7d0b214.js +0 -1
  565. package/.next-prod/static/chunks/app/layout-92d5dcd25bad9196.js +0 -1
  566. package/.next-prod/static/chunks/app/manifest.webmanifest/route-7975a2b8c7d0b214.js +0 -1
  567. package/.next-prod/static/chunks/app/review/[id]/page-05cd4cb51babd64c.js +0 -1
  568. package/.next-prod/static/chunks/next/dist/client/components/builtin/app-error-7975a2b8c7d0b214.js +0 -1
  569. package/.next-prod/static/chunks/next/dist/client/components/builtin/forbidden-7975a2b8c7d0b214.js +0 -1
  570. package/.next-prod/static/chunks/next/dist/client/components/builtin/not-found-7975a2b8c7d0b214.js +0 -1
  571. package/.next-prod/static/chunks/next/dist/client/components/builtin/unauthorized-7975a2b8c7d0b214.js +0 -1
  572. package/.next-prod/static/chunks/webpack-bb0c02e3a9602d78.js +0 -1
  573. package/.next-prod/static/css/a7974d62fe853925.css +0 -1
  574. package/dist/chunk-HIRLDMCH.mjs +0 -314
  575. /package/.next-prod/static/{WsSesL2O_jRoZztt2Y5r6 → LJRtmjYCuVrSA_dcelxlR}/_ssgManifest.js +0 -0
package/dist/wsServer.mjs CHANGED
@@ -1,47 +1,94 @@
1
1
  import {
2
+ AppError,
3
+ Effect_exports,
4
+ FSError,
5
+ NotFoundError,
6
+ PubSub_exports,
7
+ Queue_exports,
8
+ Schedule_exports,
9
+ Stream_exports,
10
+ ValidationError,
11
+ WSError,
2
12
  getLastUserMessage
3
- } from "./chunk-HIRLDMCH.mjs";
13
+ } from "./chunk-OWUW2O3D.mjs";
4
14
  import {
5
15
  addExitListener,
6
16
  addOutputListener,
7
- createPendingRequest,
8
17
  finalizeCommand,
9
18
  findSafeStart,
10
19
  getAllProjectCwds,
11
- getBrowserByShortId,
12
20
  getRegistrySize,
13
21
  getRunningCommand,
14
22
  getRunningCommands,
15
23
  getTerminalByShortId,
16
- listBrowsers,
17
- listTerminals,
18
24
  registerBrowser,
19
25
  registerCommand,
20
- registerTerminal,
21
26
  resolvePendingRequest,
22
- sendCommandToBrowser,
23
- unregisterBrowser,
24
- unregisterTerminal
25
- } from "./chunk-VCZEGP64.mjs";
27
+ unregisterBrowser
28
+ } from "./chunk-FBR4KJI5.mjs";
26
29
  import {
27
30
  GLOBAL_STATE_FILE,
28
31
  REVIEW_DIR,
29
32
  REVIEW_SIGNAL_FILE,
30
- getTerminalHistoryPath,
31
33
  readJsonFile
32
- } from "./chunk-RSHKDWJM.mjs";
34
+ } from "./chunk-TXBVUZVH.mjs";
33
35
 
34
36
  // src/lib/wsServer.ts
35
37
  import { WebSocketServer, WebSocket } from "ws";
36
38
  import { parse } from "url";
37
- import { watch as watch2, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
39
+
40
+ // src/lib/effect/globalStateHandler.ts
41
+ import { watch, existsSync, mkdirSync } from "fs";
38
42
  import { dirname } from "path";
39
- import { spawn, execSync } from "child_process";
40
- import * as nodePty from "node-pty";
41
43
 
42
- // src/lib/fileWatcher.ts
43
- import { watch, readFileSync, statSync, existsSync, mkdirSync, writeFileSync } from "fs";
44
- import { join, resolve } from "path";
44
+ // packages/shared/effect-runtime/src/server/wsAdapter.ts
45
+ var fromWebSocket = (ws, proto) => Effect_exports.gen(function* () {
46
+ const pubsub = yield* PubSub_exports.unbounded();
47
+ yield* Effect_exports.acquireRelease(
48
+ Effect_exports.sync(() => {
49
+ const onMessage = (data) => {
50
+ let parsed;
51
+ try {
52
+ parsed = JSON.parse(String(data));
53
+ } catch {
54
+ parsed = data;
55
+ }
56
+ Effect_exports.runFork(PubSub_exports.publish(pubsub, parsed));
57
+ };
58
+ const onClose = () => {
59
+ Effect_exports.runFork(PubSub_exports.shutdown(pubsub));
60
+ };
61
+ const onError = () => {
62
+ Effect_exports.runFork(PubSub_exports.shutdown(pubsub));
63
+ };
64
+ ws.on("message", onMessage);
65
+ ws.on("close", onClose);
66
+ ws.on("error", onError);
67
+ return { onMessage, onClose, onError };
68
+ }),
69
+ (handlers) => Effect_exports.sync(() => {
70
+ ws.off("message", handlers.onMessage);
71
+ ws.off("close", handlers.onClose);
72
+ ws.off("error", handlers.onError);
73
+ })
74
+ );
75
+ const send = (msg) => Effect_exports.try({
76
+ try: () => {
77
+ if (ws.readyState === ws.OPEN) {
78
+ ws.send(JSON.stringify(msg));
79
+ }
80
+ },
81
+ catch: (cause) => new WSError({ proto, kind: "send", cause })
82
+ });
83
+ const messages = Stream_exports.fromPubSub(pubsub);
84
+ const close = Effect_exports.sync(() => {
85
+ try {
86
+ ws.close();
87
+ } catch {
88
+ }
89
+ });
90
+ return { send, messages, close };
91
+ });
45
92
 
46
93
  // packages/shared/utils/src/platform.ts
47
94
  var isMac = process.platform === "darwin";
@@ -56,7 +103,96 @@ function getDefaultPath() {
56
103
  return process.env.PATH || "/usr/local/bin:/usr/bin:/bin";
57
104
  }
58
105
 
106
+ // src/lib/effect/globalStateHandler.ts
107
+ var HEARTBEAT_INTERVAL = Schedule_exports.spaced("30 seconds");
108
+ var sendGlobalState = (conn) => Effect_exports.gen(function* () {
109
+ const state = yield* Effect_exports.tryPromise({
110
+ try: () => readJsonFile(GLOBAL_STATE_FILE, { sessions: [] }),
111
+ catch: (cause) => new FSError({ path: GLOBAL_STATE_FILE, op: "read", cause })
112
+ });
113
+ for (const s of state.sessions) {
114
+ if (!s.status) {
115
+ const legacy = s;
116
+ s.status = legacy.isLoading ? "loading" : "normal";
117
+ }
118
+ }
119
+ state.sessions.sort((a, b) => b.lastActive - a.lastActive);
120
+ const recent = state.sessions.slice(0, 15);
121
+ const sessions = yield* Effect_exports.forEach(
122
+ recent,
123
+ (session) => session.status === "loading" && session.lastUserMessage ? Effect_exports.succeed(session) : Effect_exports.tryPromise({
124
+ try: () => getLastUserMessage(session.cwd, session.sessionId),
125
+ catch: () => void 0
126
+ }).pipe(
127
+ Effect_exports.map((lastUserMessage) => ({ ...session, lastUserMessage })),
128
+ Effect_exports.orElseSucceed(() => session)
129
+ ),
130
+ { concurrency: "unbounded" }
131
+ );
132
+ yield* conn.send({ type: "global-state", data: { sessions } });
133
+ });
134
+ var watchStateFile = (trigger) => Effect_exports.acquireRelease(
135
+ Effect_exports.sync(() => {
136
+ const dir = dirname(GLOBAL_STATE_FILE);
137
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
138
+ const offer = () => Effect_exports.runFork(Queue_exports.offer(trigger, void 0));
139
+ let watcher = null;
140
+ try {
141
+ watcher = watch(GLOBAL_STATE_FILE, () => offer());
142
+ } catch {
143
+ try {
144
+ watcher = watch(dir, (_, filename) => {
145
+ if (filename === "state.json") offer();
146
+ });
147
+ } catch {
148
+ }
149
+ }
150
+ watcher?.on("error", () => {
151
+ });
152
+ return watcher;
153
+ }),
154
+ (watcher) => Effect_exports.sync(() => {
155
+ try {
156
+ watcher?.close();
157
+ } catch {
158
+ }
159
+ })
160
+ ).pipe(Effect_exports.asVoid);
161
+ var handleGlobalState = (conn) => Effect_exports.gen(function* () {
162
+ yield* Effect_exports.forkScoped(
163
+ Effect_exports.repeat(conn.send({ type: "ping" }), HEARTBEAT_INTERVAL)
164
+ );
165
+ const trigger = yield* Queue_exports.unbounded();
166
+ yield* watchStateFile(trigger);
167
+ yield* Queue_exports.offer(trigger, void 0);
168
+ yield* Stream_exports.fromQueue(trigger).pipe(
169
+ Stream_exports.debounce("50 millis"),
170
+ Stream_exports.mapEffect(
171
+ () => sendGlobalState(conn).pipe(
172
+ Effect_exports.catchAll(
173
+ (e) => Effect_exports.sync(() => console.error("[ws/global-state]", e))
174
+ )
175
+ )
176
+ ),
177
+ Stream_exports.runDrain
178
+ );
179
+ });
180
+ var runGlobalStateHandler = (ws) => {
181
+ const program = Effect_exports.scoped(
182
+ Effect_exports.gen(function* () {
183
+ const conn = yield* fromWebSocket(ws, "global-state");
184
+ yield* handleGlobalState(conn);
185
+ })
186
+ );
187
+ const fiber = Effect_exports.runFork(program);
188
+ ws.on("close", () => {
189
+ Effect_exports.runFork(fiber.interruptAsFork(fiber.id()));
190
+ });
191
+ };
192
+
59
193
  // src/lib/fileWatcher.ts
194
+ import { watch as watch2, readFileSync, statSync, existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync } from "fs";
195
+ import { join, resolve } from "path";
60
196
  var GIT_WATCH_FILES = [
61
197
  ".git/HEAD",
62
198
  // Do not watch .git/index: git status refreshes its stat cache, causing a feedback loop.
@@ -146,7 +282,7 @@ var FileWatcherManager = class {
146
282
  };
147
283
  const startCwdWatcher = () => {
148
284
  try {
149
- const cwdWatcher = watch(cwd, { recursive: true }, (_eventType, filename) => {
285
+ const cwdWatcher = watch2(cwd, { recursive: true }, (_eventType, filename) => {
150
286
  if (!filename) return;
151
287
  if (filename.startsWith(".next/") || filename.startsWith("node_modules/")) return;
152
288
  if (filename.startsWith(".git/")) {
@@ -181,7 +317,7 @@ var FileWatcherManager = class {
181
317
  const gitDir = resolveGitDir(cwd);
182
318
  const watchGitFile = (filePath) => {
183
319
  try {
184
- const w = watch(filePath, () => {
320
+ const w = watch2(filePath, () => {
185
321
  pushEvent({ type: "git" });
186
322
  try {
187
323
  w.close();
@@ -196,7 +332,7 @@ var FileWatcherManager = class {
196
332
  w.on("error", () => {
197
333
  const idx = entry.watchers.indexOf(w);
198
334
  if (idx !== -1) entry.watchers.splice(idx, 1);
199
- if (entry.listeners.size > 0 && existsSync(filePath)) {
335
+ if (entry.listeners.size > 0 && existsSync2(filePath)) {
200
336
  setTimeout(() => watchGitFile(filePath), 500);
201
337
  }
202
338
  });
@@ -211,7 +347,7 @@ var FileWatcherManager = class {
211
347
  for (const gitDirName of GIT_WATCH_DIRS) {
212
348
  const dirName = gitDirName.replace(".git/", "");
213
349
  try {
214
- const w = watch(join(gitDir, dirName), { recursive: true }, () => {
350
+ const w = watch2(join(gitDir, dirName), { recursive: true }, () => {
215
351
  pushEvent({ type: "git" });
216
352
  });
217
353
  w.on("error", () => {
@@ -259,9 +395,9 @@ var ReviewWatcher = class {
259
395
  }
260
396
  start() {
261
397
  try {
262
- if (!existsSync(REVIEW_DIR)) mkdirSync(REVIEW_DIR, { recursive: true });
263
- if (!existsSync(REVIEW_SIGNAL_FILE)) writeFileSync(REVIEW_SIGNAL_FILE, "0");
264
- this.watcher = watch(REVIEW_SIGNAL_FILE, () => {
398
+ if (!existsSync2(REVIEW_DIR)) mkdirSync2(REVIEW_DIR, { recursive: true });
399
+ if (!existsSync2(REVIEW_SIGNAL_FILE)) writeFileSync(REVIEW_SIGNAL_FILE, "0");
400
+ this.watcher = watch2(REVIEW_SIGNAL_FILE, () => {
265
401
  if (this.debounceTimer) clearTimeout(this.debounceTimer);
266
402
  this.debounceTimer = setTimeout(() => this.notify(), 300);
267
403
  });
@@ -301,178 +437,404 @@ var g_watch = globalThis;
301
437
  var fileWatcher = g_watch.__cockpitFileWatcher ?? (g_watch.__cockpitFileWatcher = new FileWatcherManager());
302
438
  var reviewWatcher = g_watch.__cockpitReviewWatcher ?? (g_watch.__cockpitReviewWatcher = new ReviewWatcher());
303
439
 
304
- // src/lib/wsServer.ts
305
- import { readFile } from "fs/promises";
306
- import { randomUUID } from "crypto";
307
- var HEARTBEAT_INTERVAL = 3e4;
308
- var g_ws = globalThis;
309
- var globalStateClients = g_ws.__cockpitGlobalStateClients ?? (g_ws.__cockpitGlobalStateClients = /* @__PURE__ */ new Set());
310
- function broadcastToGlobalState(msg) {
311
- const data = JSON.stringify(msg);
312
- for (const ws of globalStateClients) {
313
- if (ws.readyState === WebSocket.OPEN) {
314
- ws.send(data);
315
- }
440
+ // src/lib/effect/fileWatchHandler.ts
441
+ var HEARTBEAT = Schedule_exports.spaced("30 seconds");
442
+ var fileEvents = (cwd) => Stream_exports.unwrapScoped(
443
+ Effect_exports.gen(function* () {
444
+ const queue = yield* Queue_exports.unbounded();
445
+ yield* Effect_exports.acquireRelease(
446
+ Effect_exports.sync(
447
+ () => fileWatcher.subscribe(cwd, (events) => {
448
+ Effect_exports.runFork(Queue_exports.offer(queue, events));
449
+ })
450
+ ),
451
+ (unsubscribe) => Effect_exports.sync(unsubscribe)
452
+ );
453
+ return Stream_exports.fromQueue(queue);
454
+ })
455
+ );
456
+ var reviewEvents = Stream_exports.unwrapScoped(
457
+ Effect_exports.gen(function* () {
458
+ const queue = yield* Queue_exports.unbounded();
459
+ yield* Effect_exports.acquireRelease(
460
+ Effect_exports.sync(
461
+ () => reviewWatcher.subscribe(() => {
462
+ Effect_exports.runFork(Queue_exports.offer(queue, void 0));
463
+ })
464
+ ),
465
+ (unsubscribe) => Effect_exports.sync(unsubscribe)
466
+ );
467
+ return Stream_exports.fromQueue(queue);
468
+ })
469
+ );
470
+ var handleFileWatch = (conn, cwd) => Effect_exports.gen(function* () {
471
+ if (!cwd) {
472
+ return yield* Effect_exports.fail(
473
+ new ValidationError({ field: "cwd", reason: "missing" })
474
+ );
316
475
  }
317
- }
318
- var wss = g_ws.__cockpitWss ?? (() => {
319
- const server = new WebSocketServer({ noServer: true });
320
- g_ws.__cockpitWss = server;
321
- server.on("connection", (ws, req) => {
322
- const { pathname, query } = parse(req.url || "", true);
323
- if (pathname === "/ws/watch") {
324
- handleFileWatch(ws, query.cwd);
325
- } else if (pathname === "/ws/global-state") {
326
- handleGlobalState(ws);
327
- } else if (pathname === "/ws/terminal") {
328
- handleTerminal(ws, query.projectCwd);
329
- } else if (pathname === "/ws/browser") {
330
- handleBrowser(ws, query.fullId);
331
- } else if (pathname === "/ws/terminal-follow") {
332
- handleTerminalFollow(ws, query.id);
333
- } else if (pathname === "/ws/jupyter") {
334
- handleJupyter(ws, query.bubbleId, query.cwd);
335
- }
476
+ yield* Effect_exports.logInfo("ws/watch start").pipe(
477
+ Effect_exports.annotateLogs("cwd", cwd)
478
+ );
479
+ yield* Effect_exports.forkScoped(
480
+ Effect_exports.repeat(conn.send({ type: "ping" }), HEARTBEAT)
481
+ );
482
+ yield* Effect_exports.forkScoped(
483
+ reviewEvents.pipe(
484
+ Stream_exports.mapEffect(
485
+ () => conn.send({ type: "watch", data: [{ type: "review" }] })
486
+ ),
487
+ Stream_exports.runDrain
488
+ )
489
+ );
490
+ yield* fileEvents(cwd).pipe(
491
+ Stream_exports.mapEffect(
492
+ (events) => conn.send({ type: "watch", data: events })
493
+ ),
494
+ Stream_exports.runDrain
495
+ );
496
+ }).pipe(Effect_exports.withSpan("ws.handleFileWatch", { attributes: { cwd } }));
497
+ var runFileWatchHandler = (ws, cwd) => {
498
+ const program = Effect_exports.scoped(
499
+ Effect_exports.gen(function* () {
500
+ const conn = yield* fromWebSocket(ws, "watch");
501
+ yield* handleFileWatch(conn, cwd);
502
+ })
503
+ ).pipe(
504
+ Effect_exports.catchTag(
505
+ "ValidationError",
506
+ (e) => Effect_exports.sync(() => ws.close(4400, e.reason))
507
+ ),
508
+ Effect_exports.catchAll(
509
+ (e) => Effect_exports.logError("[ws/watch]").pipe(
510
+ Effect_exports.annotateLogs("error", JSON.stringify(e))
511
+ )
512
+ )
513
+ );
514
+ const fiber = Effect_exports.runFork(program);
515
+ ws.on("close", () => {
516
+ Effect_exports.runFork(fiber.interruptAsFork(fiber.id()));
336
517
  });
337
- return server;
338
- })();
339
- function handleUpgrade(req, socket, head) {
340
- const { pathname } = parse(req.url || "", true);
341
- if (pathname === "/ws/watch" || pathname === "/ws/global-state" || pathname === "/ws/terminal" || pathname === "/ws/browser" || pathname === "/ws/terminal-follow" || pathname === "/ws/jupyter") {
342
- wss.handleUpgrade(req, socket, head, (ws) => {
343
- wss.emit("connection", ws, req);
344
- });
345
- return true;
518
+ };
519
+
520
+ // src/lib/effect/terminalFollowHandler.ts
521
+ var HEARTBEAT2 = Schedule_exports.spaced("30 seconds");
522
+ var subscribeTerminal = (commandId) => Stream_exports.unwrapScoped(
523
+ Effect_exports.gen(function* () {
524
+ const queue = yield* Queue_exports.unbounded();
525
+ yield* Effect_exports.acquireRelease(
526
+ Effect_exports.sync(
527
+ () => addOutputListener(commandId, (data) => {
528
+ Effect_exports.runFork(Queue_exports.offer(queue, { _tag: "output", data }));
529
+ })
530
+ ),
531
+ (unsub) => Effect_exports.sync(unsub)
532
+ );
533
+ yield* Effect_exports.acquireRelease(
534
+ Effect_exports.sync(
535
+ () => addExitListener(commandId, (code) => {
536
+ Effect_exports.runFork(Queue_exports.offer(queue, { _tag: "exit", code }));
537
+ })
538
+ ),
539
+ (unsub) => Effect_exports.sync(unsub)
540
+ );
541
+ return Stream_exports.fromQueue(queue);
542
+ })
543
+ );
544
+ var handleTerminalFollow = (conn, shortId) => Effect_exports.gen(function* () {
545
+ if (!shortId) {
546
+ return yield* Effect_exports.fail(
547
+ new ValidationError({ field: "id", reason: "missing" })
548
+ );
346
549
  }
347
- return false;
348
- }
349
- function handleFileWatch(ws, cwd) {
350
- if (!cwd) {
351
- ws.close(4400, "Missing cwd parameter");
352
- return;
550
+ const entry = getTerminalByShortId(shortId);
551
+ if (!entry) {
552
+ return yield* Effect_exports.fail(
553
+ new NotFoundError({ resource: "terminal", id: shortId })
554
+ );
353
555
  }
354
- const send = (events) => {
355
- if (ws.readyState === WebSocket.OPEN) {
356
- ws.send(JSON.stringify({ type: "watch", data: events }));
357
- }
358
- };
359
- const unsubscribe = fileWatcher.subscribe(cwd, send);
360
- const unsubReview = reviewWatcher.subscribe(() => {
361
- if (ws.readyState === WebSocket.OPEN) {
362
- ws.send(JSON.stringify({ type: "watch", data: [{ type: "review" }] }));
556
+ yield* Effect_exports.logInfo("ws/terminal-follow start").pipe(
557
+ Effect_exports.annotateLogs("shortId", shortId),
558
+ Effect_exports.annotateLogs("commandId", entry.commandId)
559
+ );
560
+ const cmd = getRunningCommand(entry.commandId);
561
+ if (cmd) {
562
+ const buffered = cmd.outputLines.join("\n") + (cmd.outputPartial ? "\n" + cmd.outputPartial : "");
563
+ if (buffered) {
564
+ yield* conn.send({ type: "output", data: buffered });
363
565
  }
566
+ }
567
+ yield* Effect_exports.forkScoped(
568
+ Effect_exports.repeat(conn.send({ type: "ping" }), HEARTBEAT2)
569
+ );
570
+ yield* subscribeTerminal(entry.commandId).pipe(
571
+ Stream_exports.tap(
572
+ (evt) => evt._tag === "output" ? conn.send({ type: "output", data: evt.data }) : conn.send({ type: "exit", code: evt.code }).pipe(
573
+ Effect_exports.zipRight(conn.close)
574
+ )
575
+ ),
576
+ Stream_exports.takeUntil((evt) => evt._tag === "exit"),
577
+ Stream_exports.runDrain
578
+ );
579
+ }).pipe(
580
+ Effect_exports.withSpan("ws.handleTerminalFollow", {
581
+ attributes: { shortId }
582
+ })
583
+ );
584
+ var runTerminalFollowHandler = (ws, shortId) => {
585
+ const program = Effect_exports.scoped(
586
+ Effect_exports.gen(function* () {
587
+ const conn = yield* fromWebSocket(ws, "terminal-follow");
588
+ yield* handleTerminalFollow(conn, shortId);
589
+ })
590
+ ).pipe(
591
+ Effect_exports.catchTag(
592
+ "ValidationError",
593
+ (e) => Effect_exports.sync(() => ws.close(4400, e.reason))
594
+ ),
595
+ Effect_exports.catchTag(
596
+ "NotFoundError",
597
+ () => Effect_exports.sync(() => ws.close(4404, "Terminal not found"))
598
+ ),
599
+ Effect_exports.catchAll(
600
+ (e) => Effect_exports.logError("[ws/terminal-follow]").pipe(
601
+ Effect_exports.annotateLogs("error", JSON.stringify(e))
602
+ )
603
+ )
604
+ );
605
+ const fiber = Effect_exports.runFork(program);
606
+ ws.on("close", () => {
607
+ Effect_exports.runFork(fiber.interruptAsFork(fiber.id()));
364
608
  });
365
- const heartbeat = setInterval(() => {
366
- if (ws.readyState === WebSocket.OPEN) {
367
- ws.send(JSON.stringify({ type: "ping" }));
368
- }
369
- }, HEARTBEAT_INTERVAL);
609
+ };
610
+
611
+ // src/lib/effect/browserHandler.ts
612
+ var HEARTBEAT3 = Schedule_exports.spaced("30 seconds");
613
+ var handleBrowser = (conn, ws, fullId) => Effect_exports.gen(function* () {
614
+ if (!fullId) {
615
+ return yield* Effect_exports.fail(
616
+ new ValidationError({ field: "fullId", reason: "missing" })
617
+ );
618
+ }
619
+ const shortId = yield* Effect_exports.acquireRelease(
620
+ Effect_exports.sync(() => registerBrowser(fullId, ws)),
621
+ () => Effect_exports.sync(() => unregisterBrowser(fullId))
622
+ );
623
+ yield* Effect_exports.logInfo("ws/browser registered").pipe(
624
+ Effect_exports.annotateLogs("fullId", fullId),
625
+ Effect_exports.annotateLogs("shortId", shortId)
626
+ );
627
+ yield* conn.send({ type: "registered", shortId });
628
+ yield* Effect_exports.forkScoped(
629
+ Effect_exports.repeat(conn.send({ type: "ping" }), HEARTBEAT3)
630
+ );
631
+ yield* conn.messages.pipe(
632
+ Stream_exports.tap(
633
+ (raw) => Effect_exports.sync(() => {
634
+ const msg = raw;
635
+ if (msg?.type === "browser:cmd-result" && typeof msg.reqId === "string") {
636
+ resolvePendingRequest(msg.reqId, !!msg.ok, msg.data, msg.error);
637
+ }
638
+ })
639
+ ),
640
+ Stream_exports.runDrain
641
+ );
642
+ }).pipe(
643
+ Effect_exports.withSpan("ws.handleBrowser", { attributes: { fullId } })
644
+ );
645
+ var runBrowserHandler = (ws, fullId) => {
646
+ const program = Effect_exports.scoped(
647
+ Effect_exports.gen(function* () {
648
+ const conn = yield* fromWebSocket(ws, "browser");
649
+ yield* handleBrowser(conn, ws, fullId);
650
+ })
651
+ ).pipe(
652
+ Effect_exports.catchTag(
653
+ "ValidationError",
654
+ (e) => Effect_exports.sync(() => ws.close(4400, e.reason))
655
+ ),
656
+ Effect_exports.catchAll(
657
+ (e) => Effect_exports.logError("[ws/browser]").pipe(
658
+ Effect_exports.annotateLogs("error", JSON.stringify(e))
659
+ )
660
+ )
661
+ );
662
+ const fiber = Effect_exports.runFork(program);
370
663
  ws.on("close", () => {
371
- unsubscribe();
372
- unsubReview();
373
- clearInterval(heartbeat);
664
+ Effect_exports.runFork(fiber.interruptAsFork(fiber.id()));
374
665
  });
375
- }
376
- function handleGlobalState(ws) {
377
- globalStateClients.add(ws);
378
- let closed = false;
379
- const sendState = async () => {
380
- if (closed || ws.readyState !== WebSocket.OPEN) return;
381
- try {
382
- const state = await readJsonFile(GLOBAL_STATE_FILE, { sessions: [] });
383
- for (const s of state.sessions) {
384
- if (!s.status) {
385
- const legacy = s;
386
- s.status = legacy.isLoading ? "loading" : "normal";
666
+ };
667
+
668
+ // src/lib/effect/jupyterHandler.ts
669
+ var HEARTBEAT4 = Schedule_exports.spaced("30 seconds");
670
+ var handleJupyter = (conn, bubbleId, cwd) => Effect_exports.gen(function* () {
671
+ if (!bubbleId || !cwd) {
672
+ return yield* Effect_exports.fail(
673
+ new ValidationError({
674
+ field: !bubbleId ? "bubbleId" : "cwd",
675
+ reason: "missing"
676
+ })
677
+ );
678
+ }
679
+ yield* Effect_exports.logInfo("ws/jupyter start").pipe(
680
+ Effect_exports.annotateLogs("bubbleId", bubbleId),
681
+ Effect_exports.annotateLogs("cwd", cwd)
682
+ );
683
+ const { kernelManager } = yield* Effect_exports.tryPromise({
684
+ try: () => import("./server-E7G55DY7.mjs"),
685
+ catch: (cause) => new AppError({
686
+ message: "failed to import kernel manager",
687
+ cause
688
+ })
689
+ });
690
+ yield* Effect_exports.forkScoped(
691
+ Effect_exports.repeat(conn.send({ type: "ping" }), HEARTBEAT4)
692
+ );
693
+ yield* Effect_exports.tryPromise({
694
+ try: () => kernelManager.getOrCreate(bubbleId, cwd),
695
+ catch: (cause) => new AppError({ message: "kernel getOrCreate failed", cause })
696
+ }).pipe(
697
+ Effect_exports.flatMap(
698
+ (instance) => instance.errorMessage ? conn.send({
699
+ type: "kernel_error",
700
+ message: instance.errorMessage
701
+ }) : conn.send({ type: "ready" })
702
+ ),
703
+ Effect_exports.catchAll(
704
+ (e) => conn.send({
705
+ type: "kernel_error",
706
+ message: e instanceof AppError ? e.message : String(e)
707
+ })
708
+ )
709
+ );
710
+ const kernelStream = Stream_exports.unwrapScoped(
711
+ Effect_exports.gen(function* () {
712
+ const queue = yield* Queue_exports.unbounded();
713
+ yield* Effect_exports.acquireRelease(
714
+ Effect_exports.sync(
715
+ () => kernelManager.addOutputListener(bubbleId, (msg) => {
716
+ Effect_exports.runFork(Queue_exports.offer(queue, msg));
717
+ })
718
+ ),
719
+ (unsub) => Effect_exports.sync(unsub)
720
+ );
721
+ return Stream_exports.fromQueue(queue);
722
+ })
723
+ );
724
+ yield* Effect_exports.forkScoped(
725
+ kernelStream.pipe(
726
+ Stream_exports.mapEffect((msg) => {
727
+ if (msg.msg_type === "kernel_error") {
728
+ return conn.send({
729
+ type: "kernel_error",
730
+ message: msg.content.message
731
+ });
387
732
  }
733
+ if (msg.msg_type === "kernel_died") {
734
+ return conn.send({
735
+ type: "kernel_died",
736
+ exit_code: msg.content.exit_code
737
+ });
738
+ }
739
+ if (msg.msg_type === "status") {
740
+ return conn.send({
741
+ type: "status",
742
+ execution_state: msg.content.execution_state
743
+ });
744
+ }
745
+ return conn.send({
746
+ type: "output",
747
+ msg_id: msg.msg_id,
748
+ msg_type: msg.msg_type,
749
+ content: msg.content
750
+ });
751
+ }),
752
+ Stream_exports.runDrain
753
+ )
754
+ );
755
+ yield* conn.messages.pipe(
756
+ Stream_exports.mapEffect((raw) => {
757
+ const msg = raw;
758
+ const type = msg.type;
759
+ if (type === "execute") {
760
+ const msgId = msg.msg_id;
761
+ const code = msg.code;
762
+ return Effect_exports.tryPromise({
763
+ try: () => kernelManager.execute(bubbleId, code, msgId, cwd),
764
+ catch: (cause) => new AppError({ message: "kernel execute failed", cause })
765
+ }).pipe(
766
+ Effect_exports.catchAll(
767
+ (e) => conn.send({
768
+ type: "kernel_error",
769
+ message: e instanceof AppError ? e.message : String(e)
770
+ })
771
+ )
772
+ );
388
773
  }
389
- state.sessions.sort((a, b) => b.lastActive - a.lastActive);
390
- const recentSessions = state.sessions.slice(0, 15);
391
- const sessionsWithLastMessage = await Promise.all(
392
- recentSessions.map(async (session) => {
393
- if (session.status === "loading" && session.lastUserMessage) {
394
- return session;
395
- }
396
- const lastUserMessage = await getLastUserMessage(session.cwd, session.sessionId);
397
- return { ...session, lastUserMessage };
398
- })
399
- );
400
- if (closed || ws.readyState !== WebSocket.OPEN) return;
401
- ws.send(JSON.stringify({ type: "global-state", data: { sessions: sessionsWithLastMessage } }));
402
- } catch (err) {
403
- if (!closed) console.error("Global state watch error:", err);
404
- }
405
- };
406
- let sending = false;
407
- let pendingSend = false;
408
- const scheduleSend = () => {
409
- if (sending) {
410
- pendingSend = true;
411
- return;
412
- }
413
- sending = true;
414
- sendState().finally(() => {
415
- sending = false;
416
- if (pendingSend) {
417
- pendingSend = false;
418
- scheduleSend();
774
+ if (type === "interrupt") {
775
+ return Effect_exports.tryPromise({
776
+ try: () => kernelManager.interrupt(bubbleId),
777
+ catch: (cause) => new AppError({ message: "kernel interrupt failed", cause })
778
+ }).pipe(Effect_exports.catchAll(() => Effect_exports.void));
419
779
  }
420
- });
421
- };
422
- scheduleSend();
423
- const dir = dirname(GLOBAL_STATE_FILE);
424
- if (!existsSync2(dir)) {
425
- mkdirSync2(dir, { recursive: true });
426
- }
427
- let watcher = null;
428
- try {
429
- watcher = watch2(GLOBAL_STATE_FILE, () => {
430
- scheduleSend();
431
- });
432
- watcher.on("error", (error) => {
433
- console.error("Global state file watcher error:", error);
434
- });
435
- } catch {
436
- try {
437
- watcher = watch2(dir, (_, filename) => {
438
- if (filename === "state.json") {
439
- scheduleSend();
440
- }
441
- });
442
- } catch (err) {
443
- console.error("Global state dir watcher error:", err);
444
- }
445
- }
446
- const heartbeat = setInterval(() => {
447
- if (ws.readyState === WebSocket.OPEN) {
448
- ws.send(JSON.stringify({ type: "ping" }));
449
- }
450
- }, HEARTBEAT_INTERVAL);
780
+ return Effect_exports.void;
781
+ }),
782
+ Stream_exports.runDrain
783
+ );
784
+ }).pipe(
785
+ Effect_exports.withSpan("ws.handleJupyter", { attributes: { bubbleId, cwd } })
786
+ );
787
+ var runJupyterHandler = (ws, bubbleId, cwd) => {
788
+ const program = Effect_exports.scoped(
789
+ Effect_exports.gen(function* () {
790
+ const conn = yield* fromWebSocket(ws, "jupyter");
791
+ yield* handleJupyter(conn, bubbleId, cwd);
792
+ })
793
+ ).pipe(
794
+ Effect_exports.catchTag(
795
+ "ValidationError",
796
+ (e) => Effect_exports.sync(() => ws.close(4400, e.reason))
797
+ ),
798
+ Effect_exports.catchAll(
799
+ (e) => Effect_exports.logError("[ws/jupyter]").pipe(
800
+ Effect_exports.annotateLogs("error", JSON.stringify(e))
801
+ )
802
+ )
803
+ );
804
+ const fiber = Effect_exports.runFork(program);
451
805
  ws.on("close", () => {
452
- closed = true;
453
- globalStateClients.delete(ws);
454
- if (watcher) watcher.close();
455
- clearInterval(heartbeat);
806
+ Effect_exports.runFork(fiber.interruptAsFork(fiber.id()));
456
807
  });
457
- }
808
+ };
809
+
810
+ // src/lib/effect/terminalHandler.ts
811
+ import { spawn, execSync } from "child_process";
812
+ import * as nodePty from "node-pty";
813
+ var HEARTBEAT5 = Schedule_exports.spaced("30 seconds");
458
814
  function getDescendantPids(pid) {
459
815
  const descendants = [];
460
816
  function collect(parentPid) {
461
817
  try {
462
818
  let result;
463
819
  if (isWindows) {
464
- result = execSync(`wmic process where (ParentProcessId=${parentPid}) get ProcessId /format:list`, { encoding: "utf-8", timeout: 3e3 }).trim();
820
+ result = execSync(
821
+ `wmic process where (ParentProcessId=${parentPid}) get ProcessId /format:list`,
822
+ { encoding: "utf-8", timeout: 3e3 }
823
+ ).trim();
465
824
  const childPids = result.split("\n").map((l) => l.replace(/\r/, "").match(/ProcessId=(\d+)/)?.[1]).filter(Boolean).map(Number);
466
- for (const childPid of childPids) {
467
- collect(childPid);
468
- descendants.push(childPid);
825
+ for (const cp of childPids) {
826
+ collect(cp);
827
+ descendants.push(cp);
469
828
  }
470
829
  } else {
471
- result = execSync(`pgrep -P ${parentPid}`, { encoding: "utf-8", timeout: 3e3 }).trim();
830
+ result = execSync(`pgrep -P ${parentPid}`, {
831
+ encoding: "utf-8",
832
+ timeout: 3e3
833
+ }).trim();
472
834
  const childPids = result.split("\n").filter(Boolean).map(Number);
473
- for (const childPid of childPids) {
474
- collect(childPid);
475
- descendants.push(childPid);
835
+ for (const cp of childPids) {
836
+ collect(cp);
837
+ descendants.push(cp);
476
838
  }
477
839
  }
478
840
  } catch {
@@ -481,595 +843,396 @@ function getDescendantPids(pid) {
481
843
  collect(pid);
482
844
  return descendants;
483
845
  }
484
- function handleTerminal(ws, projectCwd) {
485
- if (!projectCwd) {
486
- ws.close(4400, "Missing projectCwd parameter");
487
- return;
488
- }
489
- let closed = false;
490
- const cleanupMap = /* @__PURE__ */ new Map();
491
- const send = (msg) => {
492
- if (!closed && ws.readyState === WebSocket.OPEN) {
493
- ws.send(JSON.stringify(msg));
494
- }
846
+ var makeCleanupRegistry = () => Effect_exports.gen(function* () {
847
+ const map = /* @__PURE__ */ new Map();
848
+ yield* Effect_exports.addFinalizer(
849
+ () => Effect_exports.sync(() => {
850
+ for (const f of map.values()) f();
851
+ map.clear();
852
+ })
853
+ );
854
+ return {
855
+ attach: (commandId, cleanup) => Effect_exports.sync(() => {
856
+ const old = map.get(commandId);
857
+ if (old) old();
858
+ map.set(commandId, cleanup);
859
+ }),
860
+ detach: (commandId) => Effect_exports.sync(() => {
861
+ const old = map.get(commandId);
862
+ if (old) {
863
+ old();
864
+ map.delete(commandId);
865
+ }
866
+ })
495
867
  };
496
- const heartbeat = setInterval(() => {
497
- if (ws.readyState === WebSocket.OPEN) {
498
- ws.send(JSON.stringify({ type: "ping" }));
868
+ });
869
+ var attachPipeListeners = (registry, send, commandId, child) => Effect_exports.gen(function* () {
870
+ const onStdout = (data) => {
871
+ Effect_exports.runFork(send({ type: "stdout", commandId, data: data.toString() }));
872
+ };
873
+ const onStderr = (data) => {
874
+ Effect_exports.runFork(send({ type: "stderr", commandId, data: data.toString() }));
875
+ };
876
+ const pid = child.pid;
877
+ const onClose = async (code) => {
878
+ const exitCode = code ?? 0;
879
+ Effect_exports.runFork(send({ type: "exit", commandId, code: exitCode }));
880
+ try {
881
+ await finalizeCommand(commandId, exitCode, pid);
882
+ } catch (e) {
883
+ Effect_exports.runFork(
884
+ Effect_exports.logError("[ws/terminal] finalize error").pipe(
885
+ Effect_exports.annotateLogs("error", String(e))
886
+ )
887
+ );
499
888
  }
500
- }, HEARTBEAT_INTERVAL);
501
- function attachPipeListeners(commandId, child) {
502
- const oldCleanup = cleanupMap.get(commandId);
503
- if (oldCleanup) oldCleanup();
504
- const onStdout = (data) => {
505
- send({ type: "stdout", commandId, data: data.toString() });
506
- };
507
- const onStderr = (data) => {
508
- send({ type: "stderr", commandId, data: data.toString() });
509
- };
510
- const pid = child.pid;
511
- const onClose = async (code) => {
512
- const exitCode = code ?? 0;
513
- send({ type: "exit", commandId, code: exitCode });
514
- try {
515
- await finalizeCommand(commandId, exitCode, pid);
516
- } catch (e) {
517
- console.error("[ws/terminal] finalize error:", e);
518
- }
519
- cleanupMap.delete(commandId);
520
- };
521
- const onError = async (error) => {
522
- send({ type: "error", commandId, error: error.message });
523
- try {
524
- await finalizeCommand(commandId, 1, pid);
525
- } catch (e) {
526
- console.error("[ws/terminal] finalize error:", e);
527
- }
528
- cleanupMap.delete(commandId);
529
- };
530
- child.stdout?.on("data", onStdout);
531
- child.stderr?.on("data", onStderr);
532
- child.on("close", onClose);
533
- child.on("error", onError);
534
- const cleanup = () => {
535
- child.stdout?.off("data", onStdout);
536
- child.stderr?.off("data", onStderr);
537
- child.off("close", onClose);
538
- child.off("error", onError);
539
- };
540
- cleanupMap.set(commandId, cleanup);
541
- }
542
- function attachPtyListeners(commandId, pty) {
543
- const oldCleanup = cleanupMap.get(commandId);
544
- if (oldCleanup) oldCleanup();
545
- const dataDisposable = pty.onData((data) => {
546
- send({ type: "stdout", commandId, data });
547
- });
548
- const ptyPid = pty.pid;
549
- const exitDisposable = pty.onExit(async ({ exitCode }) => {
550
- send({ type: "exit", commandId, code: exitCode });
551
- try {
552
- await finalizeCommand(commandId, exitCode, ptyPid);
553
- } catch (e) {
554
- console.error("[ws/terminal] finalize error:", e);
555
- }
556
- cleanupMap.delete(commandId);
557
- });
558
- const cleanup = () => {
559
- dataDisposable.dispose();
560
- exitDisposable.dispose();
561
- };
562
- cleanupMap.set(commandId, cleanup);
563
- }
564
- ws.on("message", (raw) => {
565
- let msg;
889
+ Effect_exports.runFork(registry.detach(commandId));
890
+ };
891
+ const onError = async (error) => {
892
+ Effect_exports.runFork(send({ type: "error", commandId, error: error.message }));
566
893
  try {
567
- msg = JSON.parse(raw.toString());
894
+ await finalizeCommand(commandId, 1, pid);
568
895
  } catch {
896
+ }
897
+ Effect_exports.runFork(registry.detach(commandId));
898
+ };
899
+ child.stdout?.on("data", onStdout);
900
+ child.stderr?.on("data", onStderr);
901
+ child.on("close", onClose);
902
+ child.on("error", onError);
903
+ yield* registry.attach(commandId, () => {
904
+ child.stdout?.off("data", onStdout);
905
+ child.stderr?.off("data", onStderr);
906
+ child.off("close", onClose);
907
+ child.off("error", onError);
908
+ });
909
+ });
910
+ var attachPtyListeners = (registry, send, commandId, pty) => Effect_exports.gen(function* () {
911
+ const dataDisposable = pty.onData((data) => {
912
+ Effect_exports.runFork(send({ type: "stdout", commandId, data }));
913
+ });
914
+ const ptyPid = pty.pid;
915
+ const exitDisposable = pty.onExit(async ({ exitCode }) => {
916
+ Effect_exports.runFork(send({ type: "exit", commandId, code: exitCode }));
917
+ try {
918
+ await finalizeCommand(commandId, exitCode, ptyPid);
919
+ } catch (e) {
920
+ Effect_exports.runFork(
921
+ Effect_exports.logError("[ws/terminal] finalize error").pipe(
922
+ Effect_exports.annotateLogs("error", String(e))
923
+ )
924
+ );
925
+ }
926
+ Effect_exports.runFork(registry.detach(commandId));
927
+ });
928
+ yield* registry.attach(commandId, () => {
929
+ dataDisposable.dispose();
930
+ exitDisposable.dispose();
931
+ });
932
+ });
933
+ var dispatchMessage = (msg, projectCwd, registry, send) => Effect_exports.sync(() => {
934
+ const type = msg.type;
935
+ if (type === "exec") {
936
+ const { commandId, command, cwd, tabId, env, usePty, cols, rows } = msg;
937
+ if (!commandId || !command || !cwd || !tabId) {
938
+ Effect_exports.runFork(
939
+ send({
940
+ type: "error",
941
+ commandId: commandId || "",
942
+ error: "Missing required parameters"
943
+ })
944
+ );
569
945
  return;
570
946
  }
571
- const type = msg.type;
572
- if (type === "exec") {
573
- const { commandId, command, cwd, tabId, env, usePty, cols, rows } = msg;
574
- if (!commandId || !command || !cwd || !tabId) {
575
- send({ type: "error", commandId: commandId || "", error: "Missing required parameters" });
576
- return;
577
- }
578
- const childEnv = {
579
- HOME: process.env.HOME,
580
- USER: process.env.USER,
581
- SHELL: process.env.SHELL,
582
- TERM: "xterm-256color",
583
- FORCE_COLOR: "1",
584
- CLICOLOR: "1",
585
- CLICOLOR_FORCE: "1",
586
- PYTHONUNBUFFERED: "1",
587
- npm_config_color: "always",
588
- ...env
589
- };
590
- try {
591
- const userShell = getDefaultShell();
592
- if (usePty) {
593
- const ptyEnv = {
594
- PATH: getDefaultPath()
595
- };
596
- for (const [k, v] of Object.entries(childEnv)) {
597
- if (v !== void 0) ptyEnv[k] = v;
598
- }
599
- const ptyProcess = nodePty.spawn(userShell, ["--login", "-c", command], {
947
+ const childEnv = {
948
+ HOME: process.env.HOME,
949
+ USER: process.env.USER,
950
+ SHELL: process.env.SHELL,
951
+ TERM: "xterm-256color",
952
+ FORCE_COLOR: "1",
953
+ CLICOLOR: "1",
954
+ CLICOLOR_FORCE: "1",
955
+ PYTHONUNBUFFERED: "1",
956
+ npm_config_color: "always",
957
+ ...env
958
+ };
959
+ try {
960
+ const userShell = getDefaultShell();
961
+ if (usePty) {
962
+ const ptyEnv = { PATH: getDefaultPath() };
963
+ for (const [k, v] of Object.entries(childEnv)) {
964
+ if (v !== void 0) ptyEnv[k] = v;
965
+ }
966
+ const ptyProcess = nodePty.spawn(
967
+ userShell,
968
+ ["--login", "-c", command],
969
+ {
600
970
  name: "xterm-256color",
601
971
  cols: cols || 120,
602
972
  rows: rows || 30,
603
973
  cwd,
604
974
  env: ptyEnv
605
- });
606
- const dummyChild = spawn("true", [], { stdio: "ignore" });
975
+ }
976
+ );
977
+ const dummyChild = spawn("true", [], { stdio: "ignore" });
978
+ registerCommand({
979
+ commandId,
980
+ command,
981
+ cwd,
982
+ projectCwd,
983
+ tabId,
984
+ pid: ptyProcess.pid,
985
+ process: dummyChild,
986
+ ptyProcess,
987
+ usePty: true,
988
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
989
+ });
990
+ Effect_exports.runFork(send({ type: "pid", commandId, pid: ptyProcess.pid }));
991
+ Effect_exports.runFork(
992
+ attachPtyListeners(registry, send, commandId, ptyProcess)
993
+ );
994
+ } else {
995
+ const child = spawn(userShell, ["--login", "-c", command], {
996
+ cwd,
997
+ env: childEnv,
998
+ stdio: ["pipe", "pipe", "pipe"],
999
+ detached: true
1000
+ });
1001
+ if (child.pid) {
607
1002
  registerCommand({
608
1003
  commandId,
609
1004
  command,
610
1005
  cwd,
611
1006
  projectCwd,
612
1007
  tabId,
613
- pid: ptyProcess.pid,
614
- process: dummyChild,
615
- ptyProcess,
616
- usePty: true,
1008
+ pid: child.pid,
1009
+ process: child,
617
1010
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
618
1011
  });
619
- send({ type: "pid", commandId, pid: ptyProcess.pid });
620
- attachPtyListeners(commandId, ptyProcess);
1012
+ Effect_exports.runFork(send({ type: "pid", commandId, pid: child.pid }));
1013
+ Effect_exports.runFork(
1014
+ attachPipeListeners(registry, send, commandId, child)
1015
+ );
621
1016
  } else {
622
- const child = spawn(userShell, ["--login", "-c", command], {
623
- cwd,
624
- env: childEnv,
625
- stdio: ["pipe", "pipe", "pipe"],
626
- detached: true
627
- });
628
- if (child.pid) {
629
- registerCommand({
630
- commandId,
631
- command,
632
- cwd,
633
- projectCwd,
634
- tabId,
635
- pid: child.pid,
636
- process: child,
637
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
638
- });
639
- send({ type: "pid", commandId, pid: child.pid });
640
- attachPipeListeners(commandId, child);
641
- } else {
642
- send({ type: "error", commandId, error: "Failed to spawn process" });
643
- }
1017
+ Effect_exports.runFork(
1018
+ send({ type: "error", commandId, error: "Failed to spawn process" })
1019
+ );
644
1020
  }
645
- } catch (e) {
646
- send({ type: "error", commandId, error: e.message });
647
1021
  }
648
- } else if (type === "stdin") {
649
- const { commandId, data } = msg;
650
- const cmd = getRunningCommand(commandId);
651
- if (!cmd) return;
652
- if (cmd.usePty && cmd.ptyProcess) {
1022
+ } catch (e) {
1023
+ Effect_exports.runFork(
1024
+ send({ type: "error", commandId, error: e.message })
1025
+ );
1026
+ }
1027
+ } else if (type === "stdin") {
1028
+ const { commandId, data } = msg;
1029
+ const cmd = getRunningCommand(commandId);
1030
+ if (!cmd) return;
1031
+ if (cmd.usePty && cmd.ptyProcess) {
1032
+ try {
1033
+ cmd.ptyProcess.write(data);
1034
+ } catch {
1035
+ }
1036
+ } else {
1037
+ if (data === "" && cmd.pid) {
653
1038
  try {
654
- cmd.ptyProcess.write(data);
1039
+ process.kill(-cmd.pid, "SIGINT");
655
1040
  } catch {
656
- }
657
- } else {
658
- if (data === "" && cmd.pid) {
659
- try {
660
- process.kill(-cmd.pid, "SIGINT");
661
- } catch {
662
- try {
663
- process.kill(cmd.pid, "SIGINT");
664
- } catch {
665
- }
666
- }
667
- } else if (data === "" && cmd.pid) {
668
- try {
669
- process.kill(cmd.pid, "SIGTSTP");
670
- } catch {
671
- }
672
- } else if (data === "") {
673
1041
  try {
674
- cmd.process.stdin?.end();
1042
+ process.kill(cmd.pid, "SIGINT");
675
1043
  } catch {
676
1044
  }
677
- } else if (cmd.process.stdin?.writable) {
678
- cmd.process.stdin.write(data);
679
1045
  }
680
- }
681
- } else if (type === "attach") {
682
- const { commandId } = msg;
683
- const cmd = getRunningCommand(commandId);
684
- if (!cmd) {
685
- send({ type: "error", commandId, error: "Command not found or already finished" });
686
- return;
687
- }
688
- send({ type: "pid", commandId, pid: cmd.pid });
689
- if (cmd.usePty && cmd.ptyRingBuffer) {
690
- const snap = cmd.ptyRingBuffer.snapshot();
691
- if (snap) {
692
- const replay = snap.slice(findSafeStart(snap));
693
- if (replay) send({ type: "stdout", commandId, data: replay });
694
- }
695
- } else {
696
- const buffered = cmd.outputLines.join("\n") + (cmd.outputPartial ? "\n" + cmd.outputPartial : "");
697
- if (buffered) {
698
- send({ type: "stdout", commandId, data: buffered });
699
- }
700
- }
701
- if (cmd.usePty && cmd.ptyProcess) {
702
- attachPtyListeners(commandId, cmd.ptyProcess);
703
- } else {
704
- attachPipeListeners(commandId, cmd.process);
705
- }
706
- } else if (type === "interrupt") {
707
- const { pid } = msg;
708
- if (!pid) return;
709
- const descendants = getDescendantPids(pid);
710
- const allPids = [...descendants, pid];
711
- for (const p of allPids) {
1046
+ } else if (data === "" && cmd.pid) {
712
1047
  try {
713
- process.kill(p, "SIGTERM");
1048
+ process.kill(cmd.pid, "SIGTSTP");
714
1049
  } catch {
715
1050
  }
716
- }
717
- setTimeout(() => {
718
- for (const p of allPids) {
719
- try {
720
- process.kill(p, 0);
721
- process.kill(p, "SIGKILL");
722
- } catch {
723
- }
724
- }
725
- }, 1e3);
726
- } else if (type === "resize") {
727
- const { commandId, cols, rows } = msg;
728
- const cmd = getRunningCommand(commandId);
729
- if (cmd?.usePty && cmd.ptyProcess) {
1051
+ } else if (data === "") {
730
1052
  try {
731
- cmd.ptyProcess.resize(cols, rows);
1053
+ cmd.process.stdin?.end();
732
1054
  } catch {
733
1055
  }
1056
+ } else if (cmd.process.stdin?.writable) {
1057
+ cmd.process.stdin.write(data);
734
1058
  }
735
- } else if (type === "running") {
736
- const commands = getRunningCommands(projectCwd);
737
- if (commands.length === 0) {
738
- const size = getRegistrySize();
739
- const cwds = getAllProjectCwds();
740
- console.warn(`[ws/terminal] running query: 0 commands for projectCwd="${projectCwd}", registry total=${size}, cwds=${JSON.stringify(cwds)}`);
741
- }
742
- send({ type: "running", commands });
743
1059
  }
744
- });
745
- ws.on("close", () => {
746
- closed = true;
747
- clearInterval(heartbeat);
748
- for (const cleanup of cleanupMap.values()) {
749
- cleanup();
1060
+ } else if (type === "attach") {
1061
+ const { commandId } = msg;
1062
+ const cmd = getRunningCommand(commandId);
1063
+ if (!cmd) {
1064
+ Effect_exports.runFork(
1065
+ send({
1066
+ type: "error",
1067
+ commandId,
1068
+ error: "Command not found or already finished"
1069
+ })
1070
+ );
1071
+ return;
750
1072
  }
751
- cleanupMap.clear();
752
- });
753
- }
754
- async function readFinishedOutput(projectCwd, tabId, commandId) {
755
- try {
756
- const historyPath = getTerminalHistoryPath(projectCwd, tabId);
757
- const content = await readFile(historyPath, "utf-8");
758
- for (const line of content.trim().split("\n").reverse()) {
759
- try {
760
- const entry = JSON.parse(line);
761
- if (entry.id === commandId) {
762
- let output = entry.output || "";
763
- if (entry.outputFile) {
764
- try {
765
- output = await readFile(entry.outputFile, "utf-8");
766
- } catch {
767
- }
768
- }
769
- return { output, exitCode: entry.exitCode ?? 0 };
770
- }
771
- } catch {
1073
+ Effect_exports.runFork(send({ type: "pid", commandId, pid: cmd.pid }));
1074
+ if (cmd.usePty && cmd.ptyRingBuffer) {
1075
+ const snap = cmd.ptyRingBuffer.snapshot();
1076
+ if (snap) {
1077
+ const replay = snap.slice(findSafeStart(snap));
1078
+ if (replay)
1079
+ Effect_exports.runFork(send({ type: "stdout", commandId, data: replay }));
772
1080
  }
773
- }
774
- } catch {
775
- }
776
- return void 0;
777
- }
778
- async function handleTerminalApi(req, res) {
779
- const { pathname } = parse(req.url || "", true);
780
- const match = pathname?.match(/^\/api\/terminal\/([a-z]+)$/);
781
- if (!match || req.method !== "POST") return false;
782
- const action = match[1];
783
- const chunks = [];
784
- for await (const chunk of req) chunks.push(chunk);
785
- let body;
786
- try {
787
- body = JSON.parse(Buffer.concat(chunks).toString());
788
- } catch {
789
- body = {};
790
- }
791
- const sendJson = (status, data) => {
792
- res.writeHead(status, { "Content-Type": "application/json" });
793
- res.end(JSON.stringify(data));
794
- };
795
- if (action === "list") {
796
- sendJson(200, { ok: true, data: listTerminals(getRunningCommand) });
797
- return true;
798
- }
799
- if (action === "register") {
800
- const { tabId, commandId, command, projectCwd } = body;
801
- if (!tabId || !commandId || !command) {
802
- sendJson(400, { ok: false, error: "Missing tabId/commandId/command" });
803
- return true;
804
- }
805
- const shortId = registerTerminal(tabId, commandId, command, projectCwd);
806
- sendJson(200, { ok: true, data: { shortId } });
807
- return true;
808
- }
809
- if (action === "unregister") {
810
- const { commandId } = body;
811
- if (!commandId) {
812
- sendJson(400, { ok: false, error: "Missing commandId" });
813
- return true;
814
- }
815
- unregisterTerminal(commandId);
816
- sendJson(200, { ok: true });
817
- return true;
818
- }
819
- const { id } = body;
820
- if (!id) {
821
- sendJson(400, { ok: false, error: "Missing terminal id" });
822
- return true;
823
- }
824
- const entry = getTerminalByShortId(id);
825
- if (!entry) {
826
- sendJson(404, { ok: false, error: `Terminal "${id}" not found` });
827
- return true;
828
- }
829
- const cmd = getRunningCommand(entry.commandId);
830
- if (action === "output") {
831
- if (cmd) {
832
- const output = cmd.outputLines.join("\n") + (cmd.outputPartial ? "\n" + cmd.outputPartial : "");
833
- sendJson(200, { ok: true, data: { output, command: entry.command, pid: cmd.pid, running: true } });
834
1081
  } else {
835
- if (!entry.projectCwd) {
836
- sendJson(404, { ok: false, error: "Command projectCwd unknown" });
837
- return true;
1082
+ const buffered = cmd.outputLines.join("\n") + (cmd.outputPartial ? "\n" + cmd.outputPartial : "");
1083
+ if (buffered) {
1084
+ Effect_exports.runFork(send({ type: "stdout", commandId, data: buffered }));
838
1085
  }
839
- const historyOutput = await readFinishedOutput(entry.projectCwd, entry.tabId, entry.commandId);
840
- if (historyOutput !== void 0) {
841
- sendJson(200, { ok: true, data: { output: historyOutput.output, command: entry.command, exitCode: historyOutput.exitCode, running: false } });
842
- } else {
843
- sendJson(404, { ok: false, error: "Command output not available" });
844
- }
845
- }
846
- return true;
847
- }
848
- if (action === "stdin") {
849
- if (!cmd) {
850
- sendJson(404, { ok: false, error: "Command no longer running" });
851
- return true;
852
- }
853
- const { data } = body;
854
- if (data === void 0) {
855
- sendJson(400, { ok: false, error: "Missing data" });
856
- return true;
857
1086
  }
858
1087
  if (cmd.usePty && cmd.ptyProcess) {
1088
+ Effect_exports.runFork(
1089
+ attachPtyListeners(registry, send, commandId, cmd.ptyProcess)
1090
+ );
1091
+ } else {
1092
+ Effect_exports.runFork(
1093
+ attachPipeListeners(registry, send, commandId, cmd.process)
1094
+ );
1095
+ }
1096
+ } else if (type === "interrupt") {
1097
+ const { pid } = msg;
1098
+ if (!pid) return;
1099
+ const descendants = getDescendantPids(pid);
1100
+ const allPids = [...descendants, pid];
1101
+ for (const p of allPids) {
859
1102
  try {
860
- cmd.ptyProcess.write(data);
1103
+ process.kill(p, "SIGTERM");
861
1104
  } catch {
862
1105
  }
863
- } else if (cmd.process.stdin?.writable) {
864
- cmd.process.stdin.write(data);
865
- } else {
866
- sendJson(500, { ok: false, error: "stdin not writable" });
867
- return true;
868
- }
869
- sendJson(200, { ok: true });
870
- return true;
871
- }
872
- sendJson(400, { ok: false, error: `Unknown action: ${action}` });
873
- return true;
874
- }
875
- function handleTerminalFollow(ws, shortId) {
876
- if (!shortId) {
877
- ws.close(4400, "Missing id parameter");
878
- return;
879
- }
880
- const entry = getTerminalByShortId(shortId);
881
- if (!entry) {
882
- ws.close(4404, "Terminal not found");
883
- return;
884
- }
885
- const cmd = getRunningCommand(entry.commandId);
886
- if (cmd) {
887
- const buffered = cmd.outputLines.join("\n") + (cmd.outputPartial ? "\n" + cmd.outputPartial : "");
888
- if (buffered) {
889
- ws.send(JSON.stringify({ type: "output", data: buffered }));
890
- }
891
- }
892
- const unsubOutput = addOutputListener(entry.commandId, (data) => {
893
- if (ws.readyState === WebSocket.OPEN) {
894
- ws.send(JSON.stringify({ type: "output", data }));
895
- }
896
- });
897
- const unsubExit = addExitListener(entry.commandId, (code) => {
898
- if (ws.readyState === WebSocket.OPEN) {
899
- ws.send(JSON.stringify({ type: "exit", code }));
900
- ws.close();
901
1106
  }
902
- });
903
- const heartbeat = setInterval(() => {
904
- if (ws.readyState === WebSocket.OPEN) {
905
- ws.send(JSON.stringify({ type: "ping" }));
906
- }
907
- }, HEARTBEAT_INTERVAL);
908
- ws.on("close", () => {
909
- unsubOutput();
910
- unsubExit();
911
- clearInterval(heartbeat);
912
- });
913
- }
914
- async function handleBrowserApi(req, res) {
915
- const { pathname } = parse(req.url || "", true);
916
- const match = pathname?.match(/^\/api\/browser\/([a-z][a-z_]*)$/);
917
- if (!match || req.method !== "POST") return false;
918
- const action = match[1];
919
- const chunks = [];
920
- for await (const chunk of req) chunks.push(chunk);
921
- let body;
922
- try {
923
- body = JSON.parse(Buffer.concat(chunks).toString());
924
- } catch {
925
- body = {};
926
- }
927
- const { id, params: cmdParams = {}, timeout = 1e4 } = body;
928
- const sendJson = (status, data) => {
929
- res.writeHead(status, { "Content-Type": "application/json" });
930
- res.end(JSON.stringify(data));
931
- };
932
- if (action === "list") {
933
- sendJson(200, { ok: true, data: listBrowsers() });
934
- return true;
935
- }
936
- if (action === "unregister") {
937
- if (!id) {
938
- sendJson(400, { ok: false, error: "Missing browser id" });
939
- return true;
940
- }
941
- const browser2 = getBrowserByShortId(id);
942
- if (browser2) {
943
- if (browser2.ws && browser2.ws.readyState === WebSocket.OPEN) {
944
- browser2.ws.close();
1107
+ setTimeout(() => {
1108
+ for (const p of allPids) {
1109
+ try {
1110
+ process.kill(p, 0);
1111
+ process.kill(p, "SIGKILL");
1112
+ } catch {
1113
+ }
1114
+ }
1115
+ }, 1e3);
1116
+ } else if (type === "resize") {
1117
+ const { commandId, cols, rows } = msg;
1118
+ const cmd = getRunningCommand(commandId);
1119
+ if (cmd?.usePty && cmd.ptyProcess) {
1120
+ try {
1121
+ cmd.ptyProcess.resize(cols, rows);
1122
+ } catch {
945
1123
  }
946
- unregisterBrowser(browser2.fullId);
947
1124
  }
948
- sendJson(200, { ok: true });
949
- return true;
950
- }
951
- if (!id) {
952
- sendJson(400, { ok: false, error: "Missing browser id" });
953
- return true;
954
- }
955
- const browser = getBrowserByShortId(id);
956
- if (!browser) {
957
- sendJson(404, { ok: false, error: `Browser "${id}" not found` });
958
- return true;
959
- }
960
- if (!browser.ws || browser.ws.readyState !== WebSocket.OPEN) {
961
- sendJson(503, { ok: false, error: `Browser "${id}" is disconnected` });
962
- return true;
963
- }
964
- const reqId = `r-${randomUUID().slice(0, 8)}`;
965
- const sent = sendCommandToBrowser(id, reqId, action, cmdParams);
966
- if (!sent) {
967
- sendJson(503, { ok: false, error: "Failed to send command" });
968
- return true;
969
- }
970
- try {
971
- const data = await createPendingRequest(reqId, timeout);
972
- sendJson(200, { ok: true, data });
973
- } catch (err) {
974
- sendJson(504, { ok: false, error: err.message });
1125
+ } else if (type === "running") {
1126
+ const commands = getRunningCommands(projectCwd);
1127
+ if (commands.length === 0) {
1128
+ const size = getRegistrySize();
1129
+ const cwds = getAllProjectCwds();
1130
+ Effect_exports.runFork(
1131
+ Effect_exports.logWarning("[ws/terminal] running query: 0 commands").pipe(
1132
+ Effect_exports.annotateLogs("projectCwd", projectCwd),
1133
+ Effect_exports.annotateLogs("registryTotal", size),
1134
+ Effect_exports.annotateLogs("cwds", cwds)
1135
+ )
1136
+ );
1137
+ }
1138
+ Effect_exports.runFork(send({ type: "running", commands }));
975
1139
  }
976
- return true;
977
- }
978
- function handleBrowser(ws, fullId) {
979
- if (!fullId) {
980
- ws.close(4400, "Missing fullId parameter");
981
- return;
1140
+ });
1141
+ var handleTerminal = (conn, projectCwd) => Effect_exports.gen(function* () {
1142
+ if (!projectCwd) {
1143
+ return yield* Effect_exports.fail(
1144
+ new ValidationError({ field: "projectCwd", reason: "missing" })
1145
+ );
982
1146
  }
983
- const shortId = registerBrowser(fullId, ws);
984
- ws.send(JSON.stringify({ type: "registered", shortId }));
985
- const heartbeat = setInterval(() => {
986
- if (ws.readyState === WebSocket.OPEN) {
987
- ws.send(JSON.stringify({ type: "ping" }));
988
- }
989
- }, HEARTBEAT_INTERVAL);
990
- ws.on("message", (raw) => {
991
- let msg;
992
- try {
993
- msg = JSON.parse(raw.toString());
994
- } catch {
995
- return;
996
- }
997
- if (msg.type === "browser:cmd-result") {
998
- const { reqId, ok, data, error } = msg;
999
- resolvePendingRequest(reqId, ok, data, error);
1000
- }
1001
- });
1147
+ yield* Effect_exports.logInfo("ws/terminal start").pipe(
1148
+ Effect_exports.annotateLogs("projectCwd", projectCwd)
1149
+ );
1150
+ const registry = yield* makeCleanupRegistry();
1151
+ yield* Effect_exports.forkScoped(
1152
+ Effect_exports.repeat(conn.send({ type: "ping" }), HEARTBEAT5)
1153
+ );
1154
+ yield* conn.messages.pipe(
1155
+ Stream_exports.mapEffect(
1156
+ (raw) => dispatchMessage(
1157
+ raw,
1158
+ projectCwd,
1159
+ registry,
1160
+ conn.send
1161
+ )
1162
+ ),
1163
+ Stream_exports.runDrain
1164
+ );
1165
+ }).pipe(
1166
+ Effect_exports.withSpan("ws.handleTerminal", { attributes: { projectCwd } })
1167
+ );
1168
+ var runTerminalHandler = (ws, projectCwd) => {
1169
+ const program = Effect_exports.scoped(
1170
+ Effect_exports.gen(function* () {
1171
+ const conn = yield* fromWebSocket(ws, "terminal");
1172
+ yield* handleTerminal(conn, projectCwd);
1173
+ })
1174
+ ).pipe(
1175
+ Effect_exports.catchTag(
1176
+ "ValidationError",
1177
+ (e) => Effect_exports.sync(() => ws.close(4400, e.reason))
1178
+ ),
1179
+ Effect_exports.catchAll(
1180
+ (e) => Effect_exports.logError("[ws/terminal]").pipe(
1181
+ Effect_exports.annotateLogs("error", JSON.stringify(e))
1182
+ )
1183
+ )
1184
+ );
1185
+ const fiber = Effect_exports.runFork(program);
1002
1186
  ws.on("close", () => {
1003
- clearInterval(heartbeat);
1004
- unregisterBrowser(fullId);
1187
+ Effect_exports.runFork(fiber.interruptAsFork(fiber.id()));
1005
1188
  });
1006
- }
1007
- async function handleJupyter(ws, bubbleId, cwd) {
1008
- if (!bubbleId || !cwd) {
1009
- ws.close(4400, "Missing bubbleId or cwd parameter");
1010
- return;
1011
- }
1012
- let closed = false;
1013
- const send = (msg) => {
1014
- if (!closed && ws.readyState === WebSocket.OPEN) {
1015
- ws.send(JSON.stringify(msg));
1016
- }
1017
- };
1018
- const heartbeat = setInterval(() => {
1189
+ };
1190
+
1191
+ // src/lib/wsServer.ts
1192
+ var g_ws = globalThis;
1193
+ var globalStateClients = g_ws.__cockpitGlobalStateClients ?? (g_ws.__cockpitGlobalStateClients = /* @__PURE__ */ new Set());
1194
+ function broadcastToGlobalState(msg) {
1195
+ const data = JSON.stringify(msg);
1196
+ for (const ws of globalStateClients) {
1019
1197
  if (ws.readyState === WebSocket.OPEN) {
1020
- ws.send(JSON.stringify({ type: "ping" }));
1021
- }
1022
- }, HEARTBEAT_INTERVAL);
1023
- const { kernelManager } = await import("./server-K6XWP7DX.mjs");
1024
- try {
1025
- const instance = await kernelManager.getOrCreate(bubbleId, cwd);
1026
- if (instance.errorMessage) {
1027
- send({ type: "kernel_error", message: instance.errorMessage });
1028
- } else {
1029
- send({ type: "ready" });
1198
+ ws.send(data);
1030
1199
  }
1031
- } catch (err) {
1032
- send({ type: "kernel_error", message: err.message });
1033
1200
  }
1034
- const unsubscribe = kernelManager.addOutputListener(bubbleId, (msg) => {
1035
- if (msg.msg_type === "kernel_error") {
1036
- send({ type: "kernel_error", message: msg.content.message });
1037
- } else if (msg.msg_type === "kernel_died") {
1038
- send({ type: "kernel_died", exit_code: msg.content.exit_code });
1039
- } else if (msg.msg_type === "status") {
1040
- send({ type: "status", execution_state: msg.content.execution_state });
1041
- } else {
1042
- send({ type: "output", msg_id: msg.msg_id, msg_type: msg.msg_type, content: msg.content });
1043
- }
1044
- });
1045
- ws.on("message", async (raw) => {
1046
- let msg;
1047
- try {
1048
- msg = JSON.parse(raw.toString());
1049
- } catch {
1050
- return;
1051
- }
1052
- const type = msg.type;
1053
- if (type === "execute") {
1054
- const { msg_id, code } = msg;
1055
- try {
1056
- await kernelManager.execute(bubbleId, code, msg_id, cwd);
1057
- } catch (err) {
1058
- send({ type: "kernel_error", message: err.message });
1059
- }
1060
- } else if (type === "interrupt") {
1061
- await kernelManager.interrupt(bubbleId);
1201
+ }
1202
+ var wss = g_ws.__cockpitWss ?? (() => {
1203
+ const server = new WebSocketServer({ noServer: true });
1204
+ g_ws.__cockpitWss = server;
1205
+ server.on("connection", (ws, req) => {
1206
+ const { pathname, query } = parse(req.url || "", true);
1207
+ if (pathname === "/ws/watch") {
1208
+ runFileWatchHandler(ws, query.cwd);
1209
+ } else if (pathname === "/ws/global-state") {
1210
+ globalStateClients.add(ws);
1211
+ ws.on("close", () => globalStateClients.delete(ws));
1212
+ runGlobalStateHandler(ws);
1213
+ } else if (pathname === "/ws/terminal") {
1214
+ runTerminalHandler(ws, query.projectCwd);
1215
+ } else if (pathname === "/ws/browser") {
1216
+ runBrowserHandler(ws, query.fullId);
1217
+ } else if (pathname === "/ws/terminal-follow") {
1218
+ runTerminalFollowHandler(ws, query.id);
1219
+ } else if (pathname === "/ws/jupyter") {
1220
+ runJupyterHandler(ws, query.bubbleId, query.cwd);
1062
1221
  }
1063
1222
  });
1064
- ws.on("close", () => {
1065
- closed = true;
1066
- clearInterval(heartbeat);
1067
- unsubscribe();
1068
- });
1223
+ return server;
1224
+ })();
1225
+ function handleUpgrade(req, socket, head) {
1226
+ const { pathname } = parse(req.url || "", true);
1227
+ if (pathname === "/ws/watch" || pathname === "/ws/global-state" || pathname === "/ws/terminal" || pathname === "/ws/browser" || pathname === "/ws/terminal-follow" || pathname === "/ws/jupyter") {
1228
+ wss.handleUpgrade(req, socket, head, (ws) => {
1229
+ wss.emit("connection", ws, req);
1230
+ });
1231
+ return true;
1232
+ }
1233
+ return false;
1069
1234
  }
1070
1235
  export {
1071
1236
  broadcastToGlobalState,
1072
- handleBrowserApi,
1073
- handleTerminalApi,
1074
1237
  handleUpgrade
1075
1238
  };