@quenty/studio-bridge 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (689) hide show
  1. package/CHANGELOG.md +15 -39
  2. package/README.md +166 -115
  3. package/dist/src/bridge/bridge-connection-remote.test.d.ts +7 -0
  4. package/dist/src/bridge/bridge-connection-remote.test.d.ts.map +1 -0
  5. package/dist/src/bridge/bridge-connection-remote.test.js +144 -0
  6. package/dist/src/bridge/bridge-connection-remote.test.js.map +1 -0
  7. package/dist/src/bridge/bridge-connection.d.ts +112 -0
  8. package/dist/src/bridge/bridge-connection.d.ts.map +1 -0
  9. package/dist/src/bridge/bridge-connection.js +528 -0
  10. package/dist/src/bridge/bridge-connection.js.map +1 -0
  11. package/dist/src/bridge/bridge-connection.test.d.ts +6 -0
  12. package/dist/src/bridge/bridge-connection.test.d.ts.map +1 -0
  13. package/dist/src/bridge/bridge-connection.test.js +773 -0
  14. package/dist/src/bridge/bridge-connection.test.js.map +1 -0
  15. package/dist/src/bridge/bridge-session.d.ts +38 -0
  16. package/dist/src/bridge/bridge-session.d.ts.map +1 -0
  17. package/dist/src/bridge/bridge-session.js +259 -0
  18. package/dist/src/bridge/bridge-session.js.map +1 -0
  19. package/dist/src/bridge/bridge-session.test.d.ts +6 -0
  20. package/dist/src/bridge/bridge-session.test.d.ts.map +1 -0
  21. package/dist/src/bridge/bridge-session.test.js +264 -0
  22. package/dist/src/bridge/bridge-session.test.js.map +1 -0
  23. package/dist/src/bridge/index.d.ts +13 -0
  24. package/dist/src/bridge/index.d.ts.map +1 -0
  25. package/dist/src/bridge/index.js +13 -0
  26. package/dist/src/bridge/index.js.map +1 -0
  27. package/dist/src/bridge/internal/__tests__/failover-crash.test.d.ts +9 -0
  28. package/dist/src/bridge/internal/__tests__/failover-crash.test.d.ts.map +1 -0
  29. package/dist/src/bridge/internal/__tests__/failover-crash.test.js +159 -0
  30. package/dist/src/bridge/internal/__tests__/failover-crash.test.js.map +1 -0
  31. package/dist/src/bridge/internal/__tests__/failover-graceful.test.d.ts +9 -0
  32. package/dist/src/bridge/internal/__tests__/failover-graceful.test.d.ts.map +1 -0
  33. package/dist/src/bridge/internal/__tests__/failover-graceful.test.js +218 -0
  34. package/dist/src/bridge/internal/__tests__/failover-graceful.test.js.map +1 -0
  35. package/dist/src/bridge/internal/__tests__/failover-inflight.test.d.ts +9 -0
  36. package/dist/src/bridge/internal/__tests__/failover-inflight.test.d.ts.map +1 -0
  37. package/dist/src/bridge/internal/__tests__/failover-inflight.test.js +246 -0
  38. package/dist/src/bridge/internal/__tests__/failover-inflight.test.js.map +1 -0
  39. package/dist/src/bridge/internal/__tests__/host-client-integration.test.d.ts +10 -0
  40. package/dist/src/bridge/internal/__tests__/host-client-integration.test.d.ts.map +1 -0
  41. package/dist/src/bridge/internal/__tests__/host-client-integration.test.js +298 -0
  42. package/dist/src/bridge/internal/__tests__/host-client-integration.test.js.map +1 -0
  43. package/dist/src/bridge/internal/bridge-client.d.ts +70 -0
  44. package/dist/src/bridge/internal/bridge-client.d.ts.map +1 -0
  45. package/dist/src/bridge/internal/bridge-client.js +344 -0
  46. package/dist/src/bridge/internal/bridge-client.js.map +1 -0
  47. package/dist/src/bridge/internal/bridge-client.test.d.ts +7 -0
  48. package/dist/src/bridge/internal/bridge-client.test.d.ts.map +1 -0
  49. package/dist/src/bridge/internal/bridge-client.test.js +301 -0
  50. package/dist/src/bridge/internal/bridge-client.test.js.map +1 -0
  51. package/dist/src/bridge/internal/bridge-host.d.ts +78 -0
  52. package/dist/src/bridge/internal/bridge-host.d.ts.map +1 -0
  53. package/dist/src/bridge/internal/bridge-host.js +383 -0
  54. package/dist/src/bridge/internal/bridge-host.js.map +1 -0
  55. package/dist/src/bridge/internal/bridge-host.test.d.ts +7 -0
  56. package/dist/src/bridge/internal/bridge-host.test.d.ts.map +1 -0
  57. package/dist/src/bridge/internal/bridge-host.test.js +377 -0
  58. package/dist/src/bridge/internal/bridge-host.test.js.map +1 -0
  59. package/dist/src/bridge/internal/environment-detection.d.ts +44 -0
  60. package/dist/src/bridge/internal/environment-detection.d.ts.map +1 -0
  61. package/dist/src/bridge/internal/environment-detection.js +91 -0
  62. package/dist/src/bridge/internal/environment-detection.js.map +1 -0
  63. package/dist/src/bridge/internal/environment-detection.test.d.ts +7 -0
  64. package/dist/src/bridge/internal/environment-detection.test.d.ts.map +1 -0
  65. package/dist/src/bridge/internal/environment-detection.test.js +150 -0
  66. package/dist/src/bridge/internal/environment-detection.test.js.map +1 -0
  67. package/dist/src/bridge/internal/hand-off.d.ts +69 -0
  68. package/dist/src/bridge/internal/hand-off.d.ts.map +1 -0
  69. package/dist/src/bridge/internal/hand-off.js +178 -0
  70. package/dist/src/bridge/internal/hand-off.js.map +1 -0
  71. package/dist/src/bridge/internal/hand-off.test.d.ts +7 -0
  72. package/dist/src/bridge/internal/hand-off.test.d.ts.map +1 -0
  73. package/dist/src/bridge/internal/hand-off.test.js +325 -0
  74. package/dist/src/bridge/internal/hand-off.test.js.map +1 -0
  75. package/dist/src/bridge/internal/health-endpoint.d.ts +32 -0
  76. package/dist/src/bridge/internal/health-endpoint.d.ts.map +1 -0
  77. package/dist/src/bridge/internal/health-endpoint.js +73 -0
  78. package/dist/src/bridge/internal/health-endpoint.js.map +1 -0
  79. package/dist/src/bridge/internal/health-endpoint.test.d.ts +6 -0
  80. package/dist/src/bridge/internal/health-endpoint.test.d.ts.map +1 -0
  81. package/dist/src/bridge/internal/health-endpoint.test.js +122 -0
  82. package/dist/src/bridge/internal/health-endpoint.test.js.map +1 -0
  83. package/dist/src/bridge/internal/host-protocol.d.ts +60 -0
  84. package/dist/src/bridge/internal/host-protocol.d.ts.map +1 -0
  85. package/dist/src/bridge/internal/host-protocol.js +184 -0
  86. package/dist/src/bridge/internal/host-protocol.js.map +1 -0
  87. package/dist/src/bridge/internal/host-protocol.test.d.ts +6 -0
  88. package/dist/src/bridge/internal/host-protocol.test.d.ts.map +1 -0
  89. package/dist/src/bridge/internal/host-protocol.test.js +307 -0
  90. package/dist/src/bridge/internal/host-protocol.test.js.map +1 -0
  91. package/dist/src/bridge/internal/session-tracker.d.ts +67 -0
  92. package/dist/src/bridge/internal/session-tracker.d.ts.map +1 -0
  93. package/dist/src/bridge/internal/session-tracker.js +138 -0
  94. package/dist/src/bridge/internal/session-tracker.js.map +1 -0
  95. package/dist/src/bridge/internal/session-tracker.test.d.ts +6 -0
  96. package/dist/src/bridge/internal/session-tracker.test.d.ts.map +1 -0
  97. package/dist/src/bridge/internal/session-tracker.test.js +342 -0
  98. package/dist/src/bridge/internal/session-tracker.test.js.map +1 -0
  99. package/dist/src/bridge/internal/transport-client.d.ts +43 -0
  100. package/dist/src/bridge/internal/transport-client.d.ts.map +1 -0
  101. package/dist/src/bridge/internal/transport-client.js +146 -0
  102. package/dist/src/bridge/internal/transport-client.js.map +1 -0
  103. package/dist/src/bridge/internal/transport-client.test.d.ts +6 -0
  104. package/dist/src/bridge/internal/transport-client.test.d.ts.map +1 -0
  105. package/dist/src/bridge/internal/transport-client.test.js +176 -0
  106. package/dist/src/bridge/internal/transport-client.test.js.map +1 -0
  107. package/dist/src/bridge/internal/transport-server.d.ts +59 -0
  108. package/dist/src/bridge/internal/transport-server.d.ts.map +1 -0
  109. package/dist/src/bridge/internal/transport-server.js +189 -0
  110. package/dist/src/bridge/internal/transport-server.js.map +1 -0
  111. package/dist/src/bridge/internal/transport-server.test.d.ts +6 -0
  112. package/dist/src/bridge/internal/transport-server.test.d.ts.map +1 -0
  113. package/dist/src/bridge/internal/transport-server.test.js +171 -0
  114. package/dist/src/bridge/internal/transport-server.test.js.map +1 -0
  115. package/dist/src/bridge/types.d.ts +117 -0
  116. package/dist/src/bridge/types.d.ts.map +1 -0
  117. package/dist/src/bridge/types.js +68 -0
  118. package/dist/src/bridge/types.js.map +1 -0
  119. package/dist/src/cli/adapters/cli-command-adapter-handler.test.d.ts +6 -0
  120. package/dist/src/cli/adapters/cli-command-adapter-handler.test.d.ts.map +1 -0
  121. package/dist/src/cli/adapters/cli-command-adapter-handler.test.js +260 -0
  122. package/dist/src/cli/adapters/cli-command-adapter-handler.test.js.map +1 -0
  123. package/dist/src/cli/adapters/cli-command-adapter.d.ts +39 -0
  124. package/dist/src/cli/adapters/cli-command-adapter.d.ts.map +1 -0
  125. package/dist/src/cli/adapters/cli-command-adapter.js +241 -0
  126. package/dist/src/cli/adapters/cli-command-adapter.js.map +1 -0
  127. package/dist/src/cli/adapters/cli-command-adapter.test.d.ts +5 -0
  128. package/dist/src/cli/adapters/cli-command-adapter.test.d.ts.map +1 -0
  129. package/dist/src/cli/adapters/cli-command-adapter.test.js +188 -0
  130. package/dist/src/cli/adapters/cli-command-adapter.test.js.map +1 -0
  131. package/dist/src/cli/adapters/group-builder.d.ts +29 -0
  132. package/dist/src/cli/adapters/group-builder.d.ts.map +1 -0
  133. package/dist/src/cli/adapters/group-builder.js +54 -0
  134. package/dist/src/cli/adapters/group-builder.js.map +1 -0
  135. package/dist/src/cli/adapters/group-builder.test.d.ts +5 -0
  136. package/dist/src/cli/adapters/group-builder.test.d.ts.map +1 -0
  137. package/dist/src/cli/adapters/group-builder.test.js +108 -0
  138. package/dist/src/cli/adapters/group-builder.test.js.map +1 -0
  139. package/dist/src/cli/adapters/help-formatter.d.ts +11 -0
  140. package/dist/src/cli/adapters/help-formatter.d.ts.map +1 -0
  141. package/dist/src/cli/adapters/help-formatter.js +78 -0
  142. package/dist/src/cli/adapters/help-formatter.js.map +1 -0
  143. package/dist/src/cli/adapters/help-formatter.test.d.ts +5 -0
  144. package/dist/src/cli/adapters/help-formatter.test.d.ts.map +1 -0
  145. package/dist/src/cli/adapters/help-formatter.test.js +79 -0
  146. package/dist/src/cli/adapters/help-formatter.test.js.map +1 -0
  147. package/dist/src/cli/adapters/target-resolver.d.ts +54 -0
  148. package/dist/src/cli/adapters/target-resolver.d.ts.map +1 -0
  149. package/dist/src/cli/adapters/target-resolver.js +90 -0
  150. package/dist/src/cli/adapters/target-resolver.js.map +1 -0
  151. package/dist/src/cli/adapters/target-resolver.test.d.ts +5 -0
  152. package/dist/src/cli/adapters/target-resolver.test.d.ts.map +1 -0
  153. package/dist/src/cli/adapters/target-resolver.test.js +169 -0
  154. package/dist/src/cli/adapters/target-resolver.test.js.map +1 -0
  155. package/dist/src/cli/args/global-args.d.ts +2 -0
  156. package/dist/src/cli/args/global-args.d.ts.map +1 -1
  157. package/dist/src/cli/cli.d.ts +6 -3
  158. package/dist/src/cli/cli.d.ts.map +1 -1
  159. package/dist/src/cli/cli.js +82 -20
  160. package/dist/src/cli/cli.js.map +1 -1
  161. package/dist/src/cli/resolve-script-content.d.ts +19 -0
  162. package/dist/src/cli/resolve-script-content.d.ts.map +1 -0
  163. package/dist/src/cli/resolve-script-content.js +22 -0
  164. package/dist/src/cli/resolve-script-content.js.map +1 -0
  165. package/dist/src/cli/resolve-session.d.ts +21 -0
  166. package/dist/src/cli/resolve-session.d.ts.map +1 -0
  167. package/dist/src/cli/resolve-session.js +40 -0
  168. package/dist/src/cli/resolve-session.js.map +1 -0
  169. package/dist/src/cli/resolve-session.test.d.ts +5 -0
  170. package/dist/src/cli/resolve-session.test.d.ts.map +1 -0
  171. package/dist/src/cli/resolve-session.test.js +112 -0
  172. package/dist/src/cli/resolve-session.test.js.map +1 -0
  173. package/dist/src/cli/script-executor.d.ts +1 -0
  174. package/dist/src/cli/script-executor.d.ts.map +1 -1
  175. package/dist/src/cli/script-executor.js +7 -1
  176. package/dist/src/cli/script-executor.js.map +1 -1
  177. package/dist/src/cli/types.d.ts +11 -0
  178. package/dist/src/cli/types.d.ts.map +1 -0
  179. package/dist/src/cli/types.js +5 -0
  180. package/dist/src/cli/types.js.map +1 -0
  181. package/dist/src/commands/connect.d.ts +16 -0
  182. package/dist/src/commands/connect.d.ts.map +1 -0
  183. package/dist/src/commands/connect.js +15 -0
  184. package/dist/src/commands/connect.js.map +1 -0
  185. package/dist/src/commands/connect.test.d.ts +5 -0
  186. package/dist/src/commands/connect.test.d.ts.map +1 -0
  187. package/dist/src/commands/connect.test.js +46 -0
  188. package/dist/src/commands/connect.test.js.map +1 -0
  189. package/dist/src/commands/console/exec/exec.d.ts +43 -0
  190. package/dist/src/commands/console/exec/exec.d.ts.map +1 -0
  191. package/dist/src/commands/console/exec/exec.js +79 -0
  192. package/dist/src/commands/console/exec/exec.js.map +1 -0
  193. package/dist/src/commands/console/exec/exec.test.d.ts +5 -0
  194. package/dist/src/commands/console/exec/exec.test.d.ts.map +1 -0
  195. package/dist/src/commands/console/exec/exec.test.js +191 -0
  196. package/dist/src/commands/console/exec/exec.test.js.map +1 -0
  197. package/dist/src/commands/console/logs/logs.d.ts +23 -0
  198. package/dist/src/commands/console/logs/logs.d.ts.map +1 -0
  199. package/dist/src/commands/console/logs/logs.js +80 -0
  200. package/dist/src/commands/console/logs/logs.js.map +1 -0
  201. package/dist/src/commands/console/logs/logs.test.d.ts +5 -0
  202. package/dist/src/commands/console/logs/logs.test.d.ts.map +1 -0
  203. package/dist/src/commands/console/logs/logs.test.js +111 -0
  204. package/dist/src/commands/console/logs/logs.test.js.map +1 -0
  205. package/dist/src/commands/disconnect.d.ts +9 -0
  206. package/dist/src/commands/disconnect.d.ts.map +1 -0
  207. package/dist/src/commands/disconnect.js +8 -0
  208. package/dist/src/commands/disconnect.js.map +1 -0
  209. package/dist/src/commands/disconnect.test.d.ts +5 -0
  210. package/dist/src/commands/disconnect.test.d.ts.map +1 -0
  211. package/dist/src/commands/disconnect.test.js +17 -0
  212. package/dist/src/commands/disconnect.test.js.map +1 -0
  213. package/dist/src/commands/explorer/query/query.d.ts +31 -0
  214. package/dist/src/commands/explorer/query/query.d.ts.map +1 -0
  215. package/dist/src/commands/explorer/query/query.js +106 -0
  216. package/dist/src/commands/explorer/query/query.js.map +1 -0
  217. package/dist/src/commands/explorer/query/query.test.d.ts +5 -0
  218. package/dist/src/commands/explorer/query/query.test.d.ts.map +1 -0
  219. package/dist/src/commands/explorer/query/query.test.js +228 -0
  220. package/dist/src/commands/explorer/query/query.test.js.map +1 -0
  221. package/dist/src/commands/formatters.test.d.ts +6 -0
  222. package/dist/src/commands/formatters.test.d.ts.map +1 -0
  223. package/dist/src/commands/formatters.test.js +211 -0
  224. package/dist/src/commands/formatters.test.js.map +1 -0
  225. package/dist/src/commands/framework/action-loader.d.ts +25 -0
  226. package/dist/src/commands/framework/action-loader.d.ts.map +1 -0
  227. package/dist/src/commands/framework/action-loader.js +46 -0
  228. package/dist/src/commands/framework/action-loader.js.map +1 -0
  229. package/dist/src/commands/framework/action-loader.test.d.ts +5 -0
  230. package/dist/src/commands/framework/action-loader.test.d.ts.map +1 -0
  231. package/dist/src/commands/framework/action-loader.test.js +89 -0
  232. package/dist/src/commands/framework/action-loader.test.js.map +1 -0
  233. package/dist/src/commands/framework/arg-builder.d.ts +92 -0
  234. package/dist/src/commands/framework/arg-builder.d.ts.map +1 -0
  235. package/dist/src/commands/framework/arg-builder.js +137 -0
  236. package/dist/src/commands/framework/arg-builder.js.map +1 -0
  237. package/dist/src/commands/framework/arg-builder.test.d.ts +5 -0
  238. package/dist/src/commands/framework/arg-builder.test.d.ts.map +1 -0
  239. package/dist/src/commands/framework/arg-builder.test.js +246 -0
  240. package/dist/src/commands/framework/arg-builder.test.js.map +1 -0
  241. package/dist/src/commands/framework/command-registry.d.ts +23 -0
  242. package/dist/src/commands/framework/command-registry.d.ts.map +1 -0
  243. package/dist/src/commands/framework/command-registry.js +42 -0
  244. package/dist/src/commands/framework/command-registry.js.map +1 -0
  245. package/dist/src/commands/framework/command-registry.test.d.ts +5 -0
  246. package/dist/src/commands/framework/command-registry.test.d.ts.map +1 -0
  247. package/dist/src/commands/framework/command-registry.test.js +158 -0
  248. package/dist/src/commands/framework/command-registry.test.js.map +1 -0
  249. package/dist/src/commands/framework/define-command.d.ts +76 -0
  250. package/dist/src/commands/framework/define-command.d.ts.map +1 -0
  251. package/dist/src/commands/framework/define-command.js +28 -0
  252. package/dist/src/commands/framework/define-command.js.map +1 -0
  253. package/dist/src/commands/framework/define-command.test.d.ts +5 -0
  254. package/dist/src/commands/framework/define-command.test.d.ts.map +1 -0
  255. package/dist/src/commands/framework/define-command.test.js +135 -0
  256. package/dist/src/commands/framework/define-command.test.js.map +1 -0
  257. package/dist/src/commands/framework/index.d.ts +8 -0
  258. package/dist/src/commands/framework/index.d.ts.map +1 -0
  259. package/dist/src/commands/framework/index.js +8 -0
  260. package/dist/src/commands/framework/index.js.map +1 -0
  261. package/dist/src/commands/index.d.ts +20 -0
  262. package/dist/src/commands/index.d.ts.map +1 -0
  263. package/dist/src/commands/index.js +20 -0
  264. package/dist/src/commands/index.js.map +1 -0
  265. package/dist/src/commands/linux/inject-credentials/inject-credentials.d.ts +15 -0
  266. package/dist/src/commands/linux/inject-credentials/inject-credentials.d.ts.map +1 -0
  267. package/dist/src/commands/linux/inject-credentials/inject-credentials.js +88 -0
  268. package/dist/src/commands/linux/inject-credentials/inject-credentials.js.map +1 -0
  269. package/dist/src/commands/linux/setup/setup.d.ts +19 -0
  270. package/dist/src/commands/linux/setup/setup.d.ts.map +1 -0
  271. package/dist/src/commands/linux/setup/setup.js +107 -0
  272. package/dist/src/commands/linux/setup/setup.js.map +1 -0
  273. package/dist/src/commands/linux/status/status.d.ts +34 -0
  274. package/dist/src/commands/linux/status/status.d.ts.map +1 -0
  275. package/dist/src/commands/linux/status/status.js +134 -0
  276. package/dist/src/commands/linux/status/status.js.map +1 -0
  277. package/dist/src/commands/plugin/install/install.d.ts +10 -0
  278. package/dist/src/commands/plugin/install/install.d.ts.map +1 -0
  279. package/dist/src/commands/plugin/install/install.js +23 -0
  280. package/dist/src/commands/plugin/install/install.js.map +1 -0
  281. package/dist/src/commands/plugin/uninstall/uninstall.d.ts +9 -0
  282. package/dist/src/commands/plugin/uninstall/uninstall.d.ts.map +1 -0
  283. package/dist/src/commands/plugin/uninstall/uninstall.js +41 -0
  284. package/dist/src/commands/plugin/uninstall/uninstall.js.map +1 -0
  285. package/dist/src/commands/process/close/close.d.ts +22 -0
  286. package/dist/src/commands/process/close/close.d.ts.map +1 -0
  287. package/dist/src/commands/process/close/close.js +34 -0
  288. package/dist/src/commands/process/close/close.js.map +1 -0
  289. package/dist/src/commands/process/format-state.d.ts +7 -0
  290. package/dist/src/commands/process/format-state.d.ts.map +1 -0
  291. package/dist/src/commands/process/format-state.js +19 -0
  292. package/dist/src/commands/process/format-state.js.map +1 -0
  293. package/dist/src/commands/process/info/info.d.ts +17 -0
  294. package/dist/src/commands/process/info/info.d.ts.map +1 -0
  295. package/dist/src/commands/process/info/info.js +38 -0
  296. package/dist/src/commands/process/info/info.js.map +1 -0
  297. package/dist/src/commands/process/info/info.test.d.ts +5 -0
  298. package/dist/src/commands/process/info/info.test.d.ts.map +1 -0
  299. package/dist/src/commands/process/info/info.test.js +58 -0
  300. package/dist/src/commands/process/info/info.test.js.map +1 -0
  301. package/dist/src/commands/process/launch/launch.d.ts +17 -0
  302. package/dist/src/commands/process/launch/launch.d.ts.map +1 -0
  303. package/dist/src/commands/process/launch/launch.js +26 -0
  304. package/dist/src/commands/process/launch/launch.js.map +1 -0
  305. package/dist/src/commands/process/launch/launch.test.d.ts +5 -0
  306. package/dist/src/commands/process/launch/launch.test.d.ts.map +1 -0
  307. package/dist/src/commands/process/launch/launch.test.js +49 -0
  308. package/dist/src/commands/process/launch/launch.test.js.map +1 -0
  309. package/dist/src/commands/process/list/list.d.ts +16 -0
  310. package/dist/src/commands/process/list/list.d.ts.map +1 -0
  311. package/dist/src/commands/process/list/list.js +56 -0
  312. package/dist/src/commands/process/list/list.js.map +1 -0
  313. package/dist/src/commands/process/list/list.test.d.ts +5 -0
  314. package/dist/src/commands/process/list/list.test.d.ts.map +1 -0
  315. package/dist/src/commands/process/list/list.test.js +71 -0
  316. package/dist/src/commands/process/list/list.test.js.map +1 -0
  317. package/dist/src/commands/process/run/run.d.ts +31 -0
  318. package/dist/src/commands/process/run/run.d.ts.map +1 -0
  319. package/dist/src/commands/process/run/run.js +63 -0
  320. package/dist/src/commands/process/run/run.js.map +1 -0
  321. package/dist/src/commands/rgba-to-png.d.ts +17 -0
  322. package/dist/src/commands/rgba-to-png.d.ts.map +1 -0
  323. package/dist/src/commands/rgba-to-png.js +85 -0
  324. package/dist/src/commands/rgba-to-png.js.map +1 -0
  325. package/dist/src/commands/serve/serve.d.ts +17 -0
  326. package/dist/src/commands/serve/serve.d.ts.map +1 -0
  327. package/dist/src/commands/serve/serve.js +128 -0
  328. package/dist/src/commands/serve/serve.js.map +1 -0
  329. package/dist/src/commands/serve/serve.test.d.ts +5 -0
  330. package/dist/src/commands/serve/serve.test.d.ts.map +1 -0
  331. package/dist/src/commands/serve/serve.test.js +100 -0
  332. package/dist/src/commands/serve/serve.test.js.map +1 -0
  333. package/dist/src/commands/viewport/screenshot/screenshot.d.ts +17 -0
  334. package/dist/src/commands/viewport/screenshot/screenshot.d.ts.map +1 -0
  335. package/dist/src/commands/viewport/screenshot/screenshot.js +45 -0
  336. package/dist/src/commands/viewport/screenshot/screenshot.js.map +1 -0
  337. package/dist/src/commands/viewport/screenshot/screenshot.test.d.ts +5 -0
  338. package/dist/src/commands/viewport/screenshot/screenshot.test.d.ts.map +1 -0
  339. package/dist/src/commands/viewport/screenshot/screenshot.test.js +143 -0
  340. package/dist/src/commands/viewport/screenshot/screenshot.test.js.map +1 -0
  341. package/dist/src/docker/docker-delegator.d.ts +30 -0
  342. package/dist/src/docker/docker-delegator.d.ts.map +1 -0
  343. package/dist/src/docker/docker-delegator.js +201 -0
  344. package/dist/src/docker/docker-delegator.js.map +1 -0
  345. package/dist/src/docker/docker-delegator.test.d.ts +2 -0
  346. package/dist/src/docker/docker-delegator.test.d.ts.map +1 -0
  347. package/dist/src/docker/docker-delegator.test.js +132 -0
  348. package/dist/src/docker/docker-delegator.test.js.map +1 -0
  349. package/dist/src/index.d.ts +9 -2
  350. package/dist/src/index.d.ts.map +1 -1
  351. package/dist/src/index.js +6 -1
  352. package/dist/src/index.js.map +1 -1
  353. package/dist/src/index.test.d.ts +2 -0
  354. package/dist/src/index.test.d.ts.map +1 -0
  355. package/dist/src/index.test.js +51 -0
  356. package/dist/src/index.test.js.map +1 -0
  357. package/dist/src/linux/index.d.ts +12 -0
  358. package/dist/src/linux/index.d.ts.map +1 -0
  359. package/dist/src/linux/index.js +11 -0
  360. package/dist/src/linux/index.js.map +1 -0
  361. package/dist/src/linux/linux-config.d.ts +37 -0
  362. package/dist/src/linux/linux-config.d.ts.map +1 -0
  363. package/dist/src/linux/linux-config.js +70 -0
  364. package/dist/src/linux/linux-config.js.map +1 -0
  365. package/dist/src/linux/linux-config.test.d.ts +2 -0
  366. package/dist/src/linux/linux-config.test.d.ts.map +1 -0
  367. package/dist/src/linux/linux-config.test.js +54 -0
  368. package/dist/src/linux/linux-config.test.js.map +1 -0
  369. package/dist/src/linux/linux-credential-writer.d.ts +35 -0
  370. package/dist/src/linux/linux-credential-writer.d.ts.map +1 -0
  371. package/dist/src/linux/linux-credential-writer.js +300 -0
  372. package/dist/src/linux/linux-credential-writer.js.map +1 -0
  373. package/dist/src/linux/linux-display-manager.d.ts +24 -0
  374. package/dist/src/linux/linux-display-manager.d.ts.map +1 -0
  375. package/dist/src/linux/linux-display-manager.js +92 -0
  376. package/dist/src/linux/linux-display-manager.js.map +1 -0
  377. package/dist/src/linux/linux-env-guard.d.ts +13 -0
  378. package/dist/src/linux/linux-env-guard.d.ts.map +1 -0
  379. package/dist/src/linux/linux-env-guard.js +31 -0
  380. package/dist/src/linux/linux-env-guard.js.map +1 -0
  381. package/dist/src/linux/linux-env-guard.test.d.ts +2 -0
  382. package/dist/src/linux/linux-env-guard.test.d.ts.map +1 -0
  383. package/dist/src/linux/linux-env-guard.test.js +48 -0
  384. package/dist/src/linux/linux-env-guard.test.js.map +1 -0
  385. package/dist/src/linux/linux-fflags.d.ts +17 -0
  386. package/dist/src/linux/linux-fflags.d.ts.map +1 -0
  387. package/dist/src/linux/linux-fflags.js +33 -0
  388. package/dist/src/linux/linux-fflags.js.map +1 -0
  389. package/dist/src/linux/linux-fflags.test.d.ts +2 -0
  390. package/dist/src/linux/linux-fflags.test.d.ts.map +1 -0
  391. package/dist/src/linux/linux-fflags.test.js +55 -0
  392. package/dist/src/linux/linux-fflags.test.js.map +1 -0
  393. package/dist/src/linux/linux-prerequisites.d.ts +24 -0
  394. package/dist/src/linux/linux-prerequisites.d.ts.map +1 -0
  395. package/dist/src/linux/linux-prerequisites.js +118 -0
  396. package/dist/src/linux/linux-prerequisites.js.map +1 -0
  397. package/dist/src/linux/linux-shader-patcher.d.ts +17 -0
  398. package/dist/src/linux/linux-shader-patcher.d.ts.map +1 -0
  399. package/dist/src/linux/linux-shader-patcher.js +48 -0
  400. package/dist/src/linux/linux-shader-patcher.js.map +1 -0
  401. package/dist/src/linux/linux-shader-patcher.test.d.ts +2 -0
  402. package/dist/src/linux/linux-shader-patcher.test.d.ts.map +1 -0
  403. package/dist/src/linux/linux-shader-patcher.test.js +55 -0
  404. package/dist/src/linux/linux-shader-patcher.test.js.map +1 -0
  405. package/dist/src/linux/linux-studio-installer.d.ts +10 -0
  406. package/dist/src/linux/linux-studio-installer.d.ts.map +1 -0
  407. package/dist/src/linux/linux-studio-installer.js +79 -0
  408. package/dist/src/linux/linux-studio-installer.js.map +1 -0
  409. package/dist/src/linux/linux-studio-launcher.d.ts +10 -0
  410. package/dist/src/linux/linux-studio-launcher.d.ts.map +1 -0
  411. package/dist/src/linux/linux-studio-launcher.js +73 -0
  412. package/dist/src/linux/linux-studio-launcher.js.map +1 -0
  413. package/dist/src/linux/linux-version-resolver.d.ts +18 -0
  414. package/dist/src/linux/linux-version-resolver.d.ts.map +1 -0
  415. package/dist/src/linux/linux-version-resolver.js +49 -0
  416. package/dist/src/linux/linux-version-resolver.js.map +1 -0
  417. package/dist/src/linux/linux-wine-env.d.ts +11 -0
  418. package/dist/src/linux/linux-wine-env.d.ts.map +1 -0
  419. package/dist/src/linux/linux-wine-env.js +33 -0
  420. package/dist/src/linux/linux-wine-env.js.map +1 -0
  421. package/dist/src/linux/linux-wine-env.test.d.ts +2 -0
  422. package/dist/src/linux/linux-wine-env.test.d.ts.map +1 -0
  423. package/dist/src/linux/linux-wine-env.test.js +47 -0
  424. package/dist/src/linux/linux-wine-env.test.js.map +1 -0
  425. package/dist/src/plugin/persistent-plugin-installer.d.ts +21 -0
  426. package/dist/src/plugin/persistent-plugin-installer.d.ts.map +1 -0
  427. package/dist/src/plugin/persistent-plugin-installer.js +69 -0
  428. package/dist/src/plugin/persistent-plugin-installer.js.map +1 -0
  429. package/dist/src/plugin/persistent-plugin-installer.test.d.ts +5 -0
  430. package/dist/src/plugin/persistent-plugin-installer.test.d.ts.map +1 -0
  431. package/dist/src/plugin/persistent-plugin-installer.test.js +109 -0
  432. package/dist/src/plugin/persistent-plugin-installer.test.js.map +1 -0
  433. package/dist/src/plugin/plugin-discovery.d.ts +7 -0
  434. package/dist/src/plugin/plugin-discovery.d.ts.map +1 -0
  435. package/dist/src/plugin/plugin-discovery.js +18 -0
  436. package/dist/src/plugin/plugin-discovery.js.map +1 -0
  437. package/dist/src/plugin/plugin-discovery.test.d.ts +5 -0
  438. package/dist/src/plugin/plugin-discovery.test.d.ts.map +1 -0
  439. package/dist/src/plugin/plugin-discovery.test.js +55 -0
  440. package/dist/src/plugin/plugin-discovery.test.js.map +1 -0
  441. package/dist/src/plugin/plugin-injector.js +1 -1
  442. package/dist/src/plugin/plugin-injector.js.map +1 -1
  443. package/dist/src/process/studio-process-manager.d.ts +7 -3
  444. package/dist/src/process/studio-process-manager.d.ts.map +1 -1
  445. package/dist/src/process/studio-process-manager.js +38 -11
  446. package/dist/src/process/studio-process-manager.js.map +1 -1
  447. package/dist/src/process/studio-process-manager.test.js +18 -1
  448. package/dist/src/process/studio-process-manager.test.js.map +1 -1
  449. package/dist/src/server/action-dispatcher.d.ts +35 -0
  450. package/dist/src/server/action-dispatcher.d.ts.map +1 -0
  451. package/dist/src/server/action-dispatcher.js +67 -0
  452. package/dist/src/server/action-dispatcher.js.map +1 -0
  453. package/dist/src/server/action-dispatcher.test.d.ts +6 -0
  454. package/dist/src/server/action-dispatcher.test.d.ts.map +1 -0
  455. package/dist/src/server/action-dispatcher.test.js +173 -0
  456. package/dist/src/server/action-dispatcher.test.js.map +1 -0
  457. package/dist/src/server/index.d.ts +1 -1
  458. package/dist/src/server/index.d.ts.map +1 -1
  459. package/dist/src/server/pending-request-map.d.ts +33 -0
  460. package/dist/src/server/pending-request-map.d.ts.map +1 -0
  461. package/dist/src/server/pending-request-map.js +69 -0
  462. package/dist/src/server/pending-request-map.js.map +1 -0
  463. package/dist/src/server/pending-request-map.test.d.ts +2 -0
  464. package/dist/src/server/pending-request-map.test.d.ts.map +1 -0
  465. package/dist/src/server/pending-request-map.test.js +192 -0
  466. package/dist/src/server/pending-request-map.test.js.map +1 -0
  467. package/dist/src/server/plugin-detection.test.d.ts +7 -0
  468. package/dist/src/server/plugin-detection.test.d.ts.map +1 -0
  469. package/dist/src/server/plugin-detection.test.js +154 -0
  470. package/dist/src/server/plugin-detection.test.js.map +1 -0
  471. package/dist/src/server/studio-bridge-server.d.ts +44 -7
  472. package/dist/src/server/studio-bridge-server.d.ts.map +1 -1
  473. package/dist/src/server/studio-bridge-server.js +341 -91
  474. package/dist/src/server/studio-bridge-server.js.map +1 -1
  475. package/dist/src/server/studio-bridge-server.test.js +231 -207
  476. package/dist/src/server/studio-bridge-server.test.js.map +1 -1
  477. package/dist/src/server/web-socket-protocol-basic.test.d.ts +2 -0
  478. package/dist/src/server/web-socket-protocol-basic.test.d.ts.map +1 -0
  479. package/dist/src/server/web-socket-protocol-basic.test.js +98 -0
  480. package/dist/src/server/web-socket-protocol-basic.test.js.map +1 -0
  481. package/dist/src/server/web-socket-protocol.d.ts +218 -20
  482. package/dist/src/server/web-socket-protocol.d.ts.map +1 -1
  483. package/dist/src/server/web-socket-protocol.js +346 -20
  484. package/dist/src/server/web-socket-protocol.js.map +1 -1
  485. package/dist/src/server/web-socket-protocol.test.js +572 -146
  486. package/dist/src/server/web-socket-protocol.test.js.map +1 -1
  487. package/dist/src/test/e2e/hand-off.test.d.ts +9 -0
  488. package/dist/src/test/e2e/hand-off.test.d.ts.map +1 -0
  489. package/dist/src/test/e2e/hand-off.test.js +274 -0
  490. package/dist/src/test/e2e/hand-off.test.js.map +1 -0
  491. package/dist/src/test/e2e/persistent-session.test.d.ts +11 -0
  492. package/dist/src/test/e2e/persistent-session.test.d.ts.map +1 -0
  493. package/dist/src/test/e2e/persistent-session.test.js +367 -0
  494. package/dist/src/test/e2e/persistent-session.test.js.map +1 -0
  495. package/dist/src/test/e2e/split-server.test.d.ts +14 -0
  496. package/dist/src/test/e2e/split-server.test.d.ts.map +1 -0
  497. package/dist/src/test/e2e/split-server.test.js +230 -0
  498. package/dist/src/test/e2e/split-server.test.js.map +1 -0
  499. package/dist/src/test/helpers/mock-plugin-client.d.ts +69 -0
  500. package/dist/src/test/helpers/mock-plugin-client.d.ts.map +1 -0
  501. package/dist/src/test/helpers/mock-plugin-client.js +213 -0
  502. package/dist/src/test/helpers/mock-plugin-client.js.map +1 -0
  503. package/dist/tsconfig.tsbuildinfo +1 -1
  504. package/docker/.dockerignore +2 -0
  505. package/docker/Dockerfile +113 -0
  506. package/docker/docker-compose.yml +20 -0
  507. package/docker/entrypoint.sh +19 -0
  508. package/package.json +8 -6
  509. package/src/bridge/bridge-connection-remote.test.ts +189 -0
  510. package/src/bridge/bridge-connection.test.ts +1076 -0
  511. package/src/bridge/bridge-connection.ts +718 -0
  512. package/src/bridge/bridge-session.test.ts +336 -0
  513. package/src/bridge/bridge-session.ts +365 -0
  514. package/src/bridge/index.ts +42 -0
  515. package/src/bridge/internal/__tests__/failover-crash.test.ts +191 -0
  516. package/src/bridge/internal/__tests__/failover-graceful.test.ts +268 -0
  517. package/src/bridge/internal/__tests__/failover-inflight.test.ts +329 -0
  518. package/src/bridge/internal/__tests__/host-client-integration.test.ts +387 -0
  519. package/src/bridge/internal/bridge-client.test.ts +399 -0
  520. package/src/bridge/internal/bridge-client.ts +434 -0
  521. package/src/bridge/internal/bridge-host.test.ts +501 -0
  522. package/src/bridge/internal/bridge-host.ts +531 -0
  523. package/src/bridge/internal/environment-detection.test.ts +180 -0
  524. package/src/bridge/internal/environment-detection.ts +119 -0
  525. package/src/bridge/internal/hand-off.test.ts +408 -0
  526. package/src/bridge/internal/hand-off.ts +275 -0
  527. package/src/bridge/internal/health-endpoint.test.ts +147 -0
  528. package/src/bridge/internal/health-endpoint.ts +100 -0
  529. package/src/bridge/internal/host-protocol.test.ts +415 -0
  530. package/src/bridge/internal/host-protocol.ts +255 -0
  531. package/src/bridge/internal/session-tracker.test.ts +535 -0
  532. package/src/bridge/internal/session-tracker.ts +198 -0
  533. package/src/bridge/internal/transport-client.test.ts +241 -0
  534. package/src/bridge/internal/transport-client.ts +194 -0
  535. package/src/bridge/internal/transport-server.test.ts +220 -0
  536. package/src/bridge/internal/transport-server.ts +242 -0
  537. package/src/bridge/types.ts +161 -0
  538. package/src/cli/adapters/cli-command-adapter-handler.test.ts +318 -0
  539. package/src/cli/adapters/cli-command-adapter.test.ts +221 -0
  540. package/src/cli/adapters/cli-command-adapter.ts +342 -0
  541. package/src/cli/adapters/group-builder.test.ts +146 -0
  542. package/src/cli/adapters/group-builder.ts +81 -0
  543. package/src/cli/adapters/help-formatter.test.ts +97 -0
  544. package/src/cli/adapters/help-formatter.ts +86 -0
  545. package/src/cli/adapters/target-resolver.test.ts +222 -0
  546. package/src/cli/adapters/target-resolver.ts +144 -0
  547. package/src/cli/args/global-args.ts +2 -0
  548. package/src/cli/cli.ts +100 -21
  549. package/src/cli/resolve-script-content.ts +36 -0
  550. package/src/cli/resolve-session.test.ts +141 -0
  551. package/src/cli/resolve-session.ts +66 -0
  552. package/src/cli/script-executor.ts +22 -4
  553. package/src/cli/types.ts +11 -0
  554. package/src/commands/connect.test.ts +61 -0
  555. package/src/commands/connect.ts +32 -0
  556. package/src/commands/console/exec/exec.test.ts +258 -0
  557. package/src/commands/console/exec/exec.ts +130 -0
  558. package/src/commands/console/exec/execute.luau +202 -0
  559. package/src/commands/console/logs/logs.test.ts +138 -0
  560. package/src/commands/console/logs/logs.ts +115 -0
  561. package/src/commands/console/logs/query-logs.luau +76 -0
  562. package/src/commands/disconnect.test.ts +21 -0
  563. package/src/commands/disconnect.ts +12 -0
  564. package/src/commands/explorer/query/query-data-model.luau +206 -0
  565. package/src/commands/explorer/query/query.test.ts +297 -0
  566. package/src/commands/explorer/query/query.ts +157 -0
  567. package/src/commands/formatters.test.ts +237 -0
  568. package/src/commands/framework/action-loader.test.ts +118 -0
  569. package/src/commands/framework/action-loader.ts +65 -0
  570. package/src/commands/framework/arg-builder.test.ts +298 -0
  571. package/src/commands/framework/arg-builder.ts +203 -0
  572. package/src/commands/framework/command-registry.test.ts +204 -0
  573. package/src/commands/framework/command-registry.ts +51 -0
  574. package/src/commands/framework/define-command.test.ts +161 -0
  575. package/src/commands/framework/define-command.ts +114 -0
  576. package/src/commands/framework/index.ts +33 -0
  577. package/src/commands/index.ts +72 -0
  578. package/src/commands/linux/inject-credentials/inject-credentials.ts +118 -0
  579. package/src/commands/linux/setup/setup.ts +145 -0
  580. package/src/commands/linux/status/status.ts +180 -0
  581. package/src/commands/plugin/install/install.ts +31 -0
  582. package/src/commands/plugin/uninstall/uninstall.ts +54 -0
  583. package/src/commands/process/close/close.ts +52 -0
  584. package/src/commands/process/format-state.ts +21 -0
  585. package/src/commands/process/info/info.test.ts +76 -0
  586. package/src/commands/process/info/info.ts +54 -0
  587. package/src/commands/process/info/query-state.luau +48 -0
  588. package/src/commands/process/launch/launch.test.ts +65 -0
  589. package/src/commands/process/launch/launch.ts +45 -0
  590. package/src/commands/process/list/list.test.ts +82 -0
  591. package/src/commands/process/list/list.ts +75 -0
  592. package/src/commands/process/run/run.ts +98 -0
  593. package/src/commands/rgba-to-png.ts +98 -0
  594. package/src/commands/serve/serve.test.ts +139 -0
  595. package/src/commands/serve/serve.ts +161 -0
  596. package/src/commands/viewport/screenshot/capture-screenshot.luau +247 -0
  597. package/src/commands/viewport/screenshot/screenshot.test.ts +181 -0
  598. package/src/commands/viewport/screenshot/screenshot.ts +71 -0
  599. package/src/docker/docker-delegator.test.ts +159 -0
  600. package/src/docker/docker-delegator.ts +240 -0
  601. package/src/index.test.ts +58 -0
  602. package/src/index.ts +104 -3
  603. package/src/linux/README.md +130 -0
  604. package/src/linux/index.ts +25 -0
  605. package/src/linux/linux-config.test.ts +66 -0
  606. package/src/linux/linux-config.ts +102 -0
  607. package/src/linux/linux-credential-writer.ts +421 -0
  608. package/src/linux/linux-display-manager.ts +106 -0
  609. package/src/linux/linux-env-guard.test.ts +62 -0
  610. package/src/linux/linux-env-guard.ts +38 -0
  611. package/src/linux/linux-fflags.test.ts +78 -0
  612. package/src/linux/linux-fflags.ts +48 -0
  613. package/src/linux/linux-prerequisites.ts +152 -0
  614. package/src/linux/linux-shader-patcher.test.ts +76 -0
  615. package/src/linux/linux-shader-patcher.ts +56 -0
  616. package/src/linux/linux-studio-installer.ts +113 -0
  617. package/src/linux/linux-studio-launcher.ts +90 -0
  618. package/src/linux/linux-version-resolver.ts +74 -0
  619. package/src/linux/linux-wine-env.test.ts +56 -0
  620. package/src/linux/linux-wine-env.ts +38 -0
  621. package/src/linux/write-cred.c +48 -0
  622. package/src/plugin/persistent-plugin-installer.test.ts +168 -0
  623. package/src/plugin/persistent-plugin-installer.ts +90 -0
  624. package/src/plugin/plugin-discovery.test.ts +70 -0
  625. package/src/plugin/plugin-discovery.ts +21 -0
  626. package/src/plugin/plugin-injector.ts +1 -1
  627. package/src/process/studio-process-manager.test.ts +22 -1
  628. package/src/process/studio-process-manager.ts +57 -18
  629. package/src/server/action-dispatcher.test.ts +240 -0
  630. package/src/server/action-dispatcher.ts +89 -0
  631. package/src/server/index.ts +0 -3
  632. package/src/server/pending-request-map.test.ts +261 -0
  633. package/src/server/pending-request-map.ts +87 -0
  634. package/src/server/plugin-detection.test.ts +195 -0
  635. package/src/server/studio-bridge-server.test.ts +321 -283
  636. package/src/server/studio-bridge-server.ts +469 -111
  637. package/src/server/web-socket-protocol-basic.test.ts +131 -0
  638. package/src/server/web-socket-protocol.test.ts +658 -159
  639. package/src/server/web-socket-protocol.ts +668 -58
  640. package/src/test/e2e/hand-off.test.ts +338 -0
  641. package/src/test/e2e/persistent-session.test.ts +442 -0
  642. package/src/test/e2e/split-server.test.ts +290 -0
  643. package/src/test/helpers/mock-plugin-client.ts +276 -0
  644. package/templates/studio-bridge-plugin/src/Shared/ActionRouter.luau +245 -0
  645. package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.luau +203 -0
  646. package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.luau +144 -0
  647. package/templates/studio-bridge-plugin/src/Shared/Protocol.luau +132 -0
  648. package/templates/studio-bridge-plugin/src/StudioBridgePlugin.server.lua +364 -133
  649. package/templates/studio-bridge-plugin/src/Vendor/png.luau +1247 -0
  650. package/templates/studio-bridge-plugin-test/test/actions.test.luau +580 -0
  651. package/templates/studio-bridge-plugin-test/test/discovery.test.luau +622 -0
  652. package/templates/studio-bridge-plugin-test/test/execute-handler.test.luau +406 -0
  653. package/templates/studio-bridge-plugin-test/test/hash-lifecycle.test.luau +814 -0
  654. package/templates/studio-bridge-plugin-test/test/integration.test.luau +1020 -0
  655. package/templates/studio-bridge-plugin-test/test/new-actions.test.luau +339 -0
  656. package/templates/studio-bridge-plugin-test/test/plugin-entry.test.luau +493 -0
  657. package/templates/studio-bridge-plugin-test/test/protocol.test.luau +506 -0
  658. package/templates/studio-bridge-plugin-test/test/roblox-mocks.luau +108 -0
  659. package/templates/studio-bridge-plugin-test/test/test-runner.luau +112 -0
  660. package/dist/src/cli/commands/exec-command.d.ts +0 -15
  661. package/dist/src/cli/commands/exec-command.d.ts.map +0 -1
  662. package/dist/src/cli/commands/exec-command.js +0 -35
  663. package/dist/src/cli/commands/exec-command.js.map +0 -1
  664. package/dist/src/cli/commands/run-command.d.ts +0 -15
  665. package/dist/src/cli/commands/run-command.d.ts.map +0 -1
  666. package/dist/src/cli/commands/run-command.js +0 -47
  667. package/dist/src/cli/commands/run-command.js.map +0 -1
  668. package/dist/src/cli/commands/terminal/terminal-command.d.ts +0 -17
  669. package/dist/src/cli/commands/terminal/terminal-command.d.ts.map +0 -1
  670. package/dist/src/cli/commands/terminal/terminal-command.js +0 -41
  671. package/dist/src/cli/commands/terminal/terminal-command.js.map +0 -1
  672. package/dist/src/cli/commands/terminal/terminal-editor.d.ts +0 -43
  673. package/dist/src/cli/commands/terminal/terminal-editor.d.ts.map +0 -1
  674. package/dist/src/cli/commands/terminal/terminal-editor.js +0 -430
  675. package/dist/src/cli/commands/terminal/terminal-editor.js.map +0 -1
  676. package/dist/src/cli/commands/terminal/terminal-mode.d.ts +0 -13
  677. package/dist/src/cli/commands/terminal/terminal-mode.d.ts.map +0 -1
  678. package/dist/src/cli/commands/terminal/terminal-mode.js +0 -141
  679. package/dist/src/cli/commands/terminal/terminal-mode.js.map +0 -1
  680. package/dist/src/server/web-socket-protocol.smoke.test.d.ts +0 -6
  681. package/dist/src/server/web-socket-protocol.smoke.test.d.ts.map +0 -1
  682. package/dist/src/server/web-socket-protocol.smoke.test.js +0 -196
  683. package/dist/src/server/web-socket-protocol.smoke.test.js.map +0 -1
  684. package/src/cli/commands/exec-command.ts +0 -48
  685. package/src/cli/commands/run-command.ts +0 -63
  686. package/src/cli/commands/terminal/terminal-command.ts +0 -54
  687. package/src/cli/commands/terminal/terminal-editor.ts +0 -500
  688. package/src/cli/commands/terminal/terminal-mode.ts +0 -184
  689. package/src/server/web-socket-protocol.smoke.test.ts +0 -255
@@ -10,7 +10,10 @@
10
10
  */
11
11
 
12
12
  import { randomUUID } from 'crypto';
13
+ import * as fs from 'fs';
14
+ import * as http from 'http';
13
15
  import * as path from 'path';
16
+ import { fileURLToPath } from 'url';
14
17
  import { WebSocketServer, type WebSocket } from 'ws';
15
18
  import { OutputHelper } from '@quenty/cli-output-helpers';
16
19
  import {
@@ -20,13 +23,22 @@ import {
20
23
  } from '@quenty/nevermore-template-helpers';
21
24
  import {
22
25
  type OutputLevel,
26
+ type Capability,
27
+ type PluginMessage,
28
+ type ServerMessage,
23
29
  encodeMessage,
24
30
  decodePluginMessage,
25
31
  } from './web-socket-protocol.js';
32
+ import { ActionDispatcher } from './action-dispatcher.js';
33
+ import {
34
+ loadActionSourcesAsync,
35
+ type ActionSource,
36
+ } from '../commands/framework/action-loader.js';
26
37
  import {
27
38
  injectPluginAsync,
28
39
  type InjectedPlugin,
29
40
  } from '../plugin/plugin-injector.js';
41
+ import { isPersistentPluginInstalled } from '../plugin/plugin-discovery.js';
30
42
  import {
31
43
  launchStudioAsync,
32
44
  type StudioProcess,
@@ -43,9 +55,20 @@ const sessionAttributeTransformScript = resolvePackagePath(
43
55
  'transform-add-session-attribute.luau'
44
56
  );
45
57
 
46
- // ---------------------------------------------------------------------------
47
- // Public API types
48
- // ---------------------------------------------------------------------------
58
+ function readServerVersion(): string {
59
+ try {
60
+ const thisDir = path.dirname(fileURLToPath(import.meta.url));
61
+ // Walk up from src/server/ to package root
62
+ const pkgPath = path.resolve(thisDir, '..', '..', 'package.json');
63
+ const raw = fs.readFileSync(pkgPath, 'utf-8');
64
+ const pkg = JSON.parse(raw) as { version?: string };
65
+ return pkg.version ?? '0.0.0';
66
+ } catch {
67
+ return '0.0.0';
68
+ }
69
+ }
70
+
71
+ const SERVER_VERSION = readServerVersion();
49
72
 
50
73
  export type StudioBridgePhase =
51
74
  | 'building'
@@ -64,6 +87,11 @@ export interface StudioBridgeServerOptions {
64
87
  onPhase?: (phase: StudioBridgePhase) => void;
65
88
  /** Session ID for concurrent session isolation. Auto-generated if omitted. */
66
89
  sessionId?: string;
90
+ /** Whether to prefer the persistent plugin over temp injection (default: true).
91
+ * When true and the persistent plugin is installed, the server waits for
92
+ * the plugin to discover it via the health endpoint before falling back
93
+ * to temporary injection. Set to false in CI environments. */
94
+ preferPersistentPlugin?: boolean;
67
95
  }
68
96
 
69
97
  export interface ExecuteOptions {
@@ -80,10 +108,6 @@ export interface StudioBridgeResult {
80
108
  logs: string;
81
109
  }
82
110
 
83
- // ---------------------------------------------------------------------------
84
- // State machine
85
- // ---------------------------------------------------------------------------
86
-
87
111
  type BridgeState =
88
112
  | 'idle'
89
113
  | 'starting'
@@ -92,52 +116,156 @@ type BridgeState =
92
116
  | 'stopping'
93
117
  | 'stopped';
94
118
 
95
- // ---------------------------------------------------------------------------
96
- // Implementation
97
- // ---------------------------------------------------------------------------
119
+ /** Returns the assigned port once listening. WSS uses noServer mode (manual upgrade). */
120
+ function startHttpAndWsServerAsync(
121
+ httpServer: http.Server,
122
+ wss: WebSocketServer,
123
+ sessionId: string
124
+ ): Promise<number> {
125
+ httpServer.on(
126
+ 'request',
127
+ (req: http.IncomingMessage, res: http.ServerResponse) => {
128
+ if (req.method === 'GET' && req.url === '/health') {
129
+ const addr = httpServer.address();
130
+ const port = typeof addr === 'object' && addr !== null ? addr.port : 0;
131
+ const body = JSON.stringify({
132
+ status: 'ok',
133
+ sessionId,
134
+ port,
135
+ serverVersion: SERVER_VERSION,
136
+ });
137
+ res.writeHead(200, { 'Content-Type': 'application/json' });
138
+ res.end(body);
139
+ return;
140
+ }
141
+
142
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
143
+ res.end('Not Found');
144
+ }
145
+ );
146
+
147
+ // Handle WebSocket upgrades — only allow /${sessionId}
148
+ httpServer.on(
149
+ 'upgrade',
150
+ (
151
+ req: http.IncomingMessage,
152
+ socket: import('stream').Duplex,
153
+ head: Buffer
154
+ ) => {
155
+ const expectedPath = `/${sessionId}`;
156
+ if (req.url !== expectedPath) {
157
+ socket.write('HTTP/1.1 404 Not Found\r\n\r\n');
158
+ socket.destroy();
159
+ return;
160
+ }
161
+
162
+ wss.handleUpgrade(req, socket, head, (ws) => {
163
+ wss.emit('connection', ws, req);
164
+ });
165
+ }
166
+ );
98
167
 
99
- /**
100
- * Start a WebSocket server on a random available port and return the assigned
101
- * port number once listening.
102
- */
103
- function startWsServerAsync(wss: WebSocketServer): Promise<number> {
104
168
  return new Promise((resolve, reject) => {
105
- wss.on('error', reject);
106
- wss.on('listening', () => {
107
- const addr = wss.address();
169
+ httpServer.on('error', reject);
170
+ httpServer.listen(0, () => {
171
+ const addr = httpServer.address();
108
172
  if (typeof addr === 'object' && addr !== null) {
109
173
  resolve(addr.port);
110
174
  } else {
111
- reject(new Error('WebSocket server address is not available'));
175
+ reject(new Error('HTTP server address is not available'));
112
176
  }
113
177
  });
114
178
  });
115
179
  }
116
180
 
181
+ /** Capability required for each action type. */
182
+ const ACTION_CAPABILITIES: Record<string, Capability> = {
183
+ queryState: 'queryState',
184
+ captureScreenshot: 'captureScreenshot',
185
+ queryDataModel: 'queryDataModel',
186
+ queryLogs: 'queryLogs',
187
+ execute: 'execute',
188
+ };
189
+
117
190
  export class StudioBridgeServer {
118
191
  private _state: BridgeState = 'idle';
119
192
 
193
+ private readonly _options: StudioBridgeServerOptions;
120
194
  private readonly _sessionId: string;
121
195
  private readonly _defaultTimeoutMs: number;
122
196
  private readonly _onPhase: ((phase: StudioBridgePhase) => void) | undefined;
123
197
  private readonly _placePath: string | undefined;
124
198
 
199
+ private _httpServer: http.Server | undefined;
125
200
  private _wss: WebSocketServer | undefined;
201
+ private _port: number = 0;
126
202
  private _pluginHandle: InjectedPlugin | undefined;
127
203
  private _studioProc: StudioProcess | undefined;
128
204
  private _placeBuildContext: BuildContext | undefined;
129
205
  private _connectedClient: WebSocket | undefined;
130
206
 
207
+ private _negotiatedCapabilities: Capability[] = ['execute'];
208
+ private _lastHeartbeatTimestamp: number | undefined;
209
+ private _actionDispatcher = new ActionDispatcher();
210
+ private _actionsReady = false;
211
+ private _actionSources: ActionSource[] | undefined;
212
+
131
213
  constructor(options: StudioBridgeServerOptions = {}) {
214
+ this._options = options;
132
215
  this._sessionId = options.sessionId ?? randomUUID();
133
216
  this._defaultTimeoutMs = options.timeoutMs ?? 120_000;
134
217
  this._onPhase = options.onPhase;
135
218
  this._placePath = options.placePath;
136
219
  }
137
220
 
138
- // -----------------------------------------------------------------------
139
- // Lifecycle: startAsync
140
- // -----------------------------------------------------------------------
221
+ /** The negotiated set of capabilities shared between plugin and server. */
222
+ get capabilities(): readonly Capability[] {
223
+ return this._negotiatedCapabilities;
224
+ }
225
+
226
+ /** Timestamp of the last heartbeat received from the plugin, or undefined. */
227
+ get lastHeartbeatTimestamp(): number | undefined {
228
+ return this._lastHeartbeatTimestamp;
229
+ }
230
+
231
+ /** Requires the plugin to advertise the relevant capability. */
232
+ async performActionAsync<T extends PluginMessage>(
233
+ message: Omit<ServerMessage, 'requestId' | 'sessionId'>,
234
+ timeoutMs?: number
235
+ ): Promise<T> {
236
+ if (this._state !== 'ready') {
237
+ throw new Error(
238
+ `Cannot perform action: expected state 'ready', got '${this._state}'`
239
+ );
240
+ }
241
+ if (!this._connectedClient) {
242
+ throw new Error('Cannot perform action: no connected client');
243
+ }
244
+
245
+ const actionType = message.type;
246
+ const requiredCapability = ACTION_CAPABILITIES[actionType];
247
+ if (
248
+ requiredCapability &&
249
+ !this._negotiatedCapabilities.includes(requiredCapability)
250
+ ) {
251
+ throw new Error(
252
+ `Plugin does not support capability: ${requiredCapability}`
253
+ );
254
+ }
255
+
256
+ const { requestId, responsePromise } =
257
+ this._actionDispatcher.createRequestAsync(actionType, timeoutMs);
258
+
259
+ const fullMessage: ServerMessage = {
260
+ ...message,
261
+ requestId,
262
+ sessionId: this._sessionId,
263
+ } as ServerMessage;
264
+
265
+ this._connectedClient.send(encodeMessage(fullMessage));
266
+
267
+ return responsePromise as Promise<T>;
268
+ }
141
269
 
142
270
  /**
143
271
  * Build place (if needed) → start WS server → inject plugin → launch
@@ -181,21 +309,45 @@ export class StudioBridgeServer {
181
309
  );
182
310
  placePath = transformedPlacePath;
183
311
 
184
- // 1. Start WebSocket server (unique path rejects wrong connections at HTTP upgrade level)
185
- this._wss = new WebSocketServer({ port: 0, path: `/${this._sessionId}` });
186
- const port = await startWsServerAsync(this._wss);
312
+ // 1. Start HTTP + WebSocket server (unique path rejects wrong connections at upgrade level)
313
+ this._httpServer = http.createServer();
314
+ this._wss = new WebSocketServer({ noServer: true });
315
+ const port = await startHttpAndWsServerAsync(
316
+ this._httpServer,
317
+ this._wss,
318
+ this._sessionId
319
+ );
320
+ this._port = port;
187
321
  OutputHelper.verbose(
188
322
  `[StudioBridge] WebSocket server listening on port ${port}`
189
323
  );
190
324
 
191
- // 2. Inject plugin (no scriptContent — scripts are sent via execute messages)
192
- this._pluginHandle = await injectPluginAsync({
193
- port,
194
- sessionId: this._sessionId,
195
- });
196
- OutputHelper.verbose(
197
- `[StudioBridge] Plugin injected: ${this._pluginHandle.pluginPath}`
198
- );
325
+ // 2. Decide between persistent plugin and temp injection
326
+ const preferPersistent = this._options.preferPersistentPlugin ?? true;
327
+
328
+ if (preferPersistent && isPersistentPluginInstalled()) {
329
+ // Persistent plugin is installed. Skip injection and wait for the
330
+ // plugin to discover us via the health endpoint.
331
+ // Start a grace period timer: if the plugin does not connect within
332
+ // the grace period, fall back to temporary injection.
333
+ OutputHelper.verbose(
334
+ '[StudioBridge] Persistent plugin detected, waiting for connection'
335
+ );
336
+ const graceMs = 3_000;
337
+ const connected = await this._waitForPluginConnectionAsync(graceMs);
338
+ if (!connected) {
339
+ // Grace period expired. Plugin may not be running in Studio.
340
+ // Fall back to temporary injection.
341
+ OutputHelper.verbose(
342
+ '[StudioBridge] Grace period expired, falling back to temp injection'
343
+ );
344
+ await this._injectPluginAsync();
345
+ }
346
+ } else {
347
+ // No persistent plugin or preference disabled (CI mode).
348
+ // Use temporary injection (legacy launch-and-execute flow).
349
+ await this._injectPluginAsync();
350
+ }
199
351
 
200
352
  // 3. Launch Studio
201
353
  this._onPhase?.('launching');
@@ -204,9 +356,11 @@ export class StudioBridgeServer {
204
356
  `[StudioBridge] Studio launched (PID: ${this._studioProc.process.pid})`
205
357
  );
206
358
 
207
- // 4. Wait for handshake
359
+ // 4. Wait for handshake (only if not already connected via persistent plugin)
208
360
  this._onPhase?.('connecting');
209
- await this._waitForHandshakeAsync();
361
+ if (!this._connectedClient) {
362
+ await this._waitForHandshakeAsync();
363
+ }
210
364
 
211
365
  this._state = 'ready';
212
366
  } catch (error) {
@@ -216,14 +370,7 @@ export class StudioBridgeServer {
216
370
  }
217
371
  }
218
372
 
219
- // -----------------------------------------------------------------------
220
- // Lifecycle: executeAsync
221
- // -----------------------------------------------------------------------
222
-
223
- /**
224
- * Send a Luau script to the connected Studio instance and wait for it to
225
- * finish executing. Can be called multiple times while the bridge is ready.
226
- */
373
+ /** Can be called multiple times while the bridge is ready. */
227
374
  async executeAsync(options: ExecuteOptions): Promise<StudioBridgeResult> {
228
375
  if (this._state !== 'ready') {
229
376
  throw new Error(
@@ -234,11 +381,14 @@ export class StudioBridgeServer {
234
381
  throw new Error('Cannot execute: no connected client');
235
382
  }
236
383
 
384
+ // Sync action modules before first execute (state must still be 'ready'
385
+ // because performActionAsync checks for it).
386
+ await this._ensureActionsAsync();
387
+
237
388
  this._state = 'executing';
238
389
  this._onPhase?.('executing');
239
390
 
240
391
  try {
241
- // Send execute message
242
392
  this._connectedClient.send(
243
393
  encodeMessage({
244
394
  type: 'execute',
@@ -247,7 +397,6 @@ export class StudioBridgeServer {
247
397
  })
248
398
  );
249
399
 
250
- // Wait for result
251
400
  const result = await this._waitForScriptCompleteAsync(options);
252
401
 
253
402
  this._onPhase?.('done');
@@ -263,14 +412,7 @@ export class StudioBridgeServer {
263
412
  }
264
413
  }
265
414
 
266
- // -----------------------------------------------------------------------
267
- // Lifecycle: stopAsync
268
- // -----------------------------------------------------------------------
269
-
270
- /**
271
- * Shut down the bridge — send shutdown to client, kill Studio, clean up
272
- * all resources. Idempotent on 'stopped'.
273
- */
415
+ /** Idempotent on 'stopped'. */
274
416
  async stopAsync(): Promise<void> {
275
417
  if (this._state === 'stopped') {
276
418
  return;
@@ -278,7 +420,6 @@ export class StudioBridgeServer {
278
420
 
279
421
  this._state = 'stopping';
280
422
 
281
- // Send shutdown to connected client
282
423
  if (this._connectedClient) {
283
424
  try {
284
425
  this._connectedClient.send(
@@ -297,11 +438,195 @@ export class StudioBridgeServer {
297
438
  this._state = 'stopped';
298
439
  }
299
440
 
300
- // -----------------------------------------------------------------------
301
- // Private: _waitForHandshakeAsync
302
- // -----------------------------------------------------------------------
441
+ /**
442
+ * Ensure action modules (like `execute.luau`) are synced to the plugin
443
+ * before first use. Uses `syncActions` to check which actions the plugin
444
+ * is missing, then registers them via `registerAction`.
445
+ *
446
+ * Loads action sources and registers them with the connected plugin.
447
+ */
448
+ private async _ensureActionsAsync(): Promise<void> {
449
+ if (this._actionsReady) return;
450
+
451
+ if (!this._actionSources) {
452
+ this._actionSources = await loadActionSourcesAsync();
453
+ OutputHelper.verbose(
454
+ `[StudioBridge] Loaded ${
455
+ this._actionSources.length
456
+ } action source(s): ${
457
+ this._actionSources.map((a) => a.name).join(', ') || '(none)'
458
+ }`
459
+ );
460
+ }
461
+
462
+ if (this._actionSources.length === 0) {
463
+ this._actionsReady = true;
464
+ return;
465
+ }
466
+
467
+ const actions: Record<string, string> = {};
468
+ for (const action of this._actionSources) {
469
+ actions[action.name] = action.hash;
470
+ }
471
+
472
+ OutputHelper.verbose('[StudioBridge] Syncing actions with plugin');
473
+ const syncResult = await this.performActionAsync<PluginMessage>(
474
+ {
475
+ type: 'syncActions',
476
+ payload: { actions },
477
+ },
478
+ 10_000
479
+ );
480
+
481
+ if (syncResult.type === 'syncActionsResult') {
482
+ const needed = (syncResult.payload as Record<string, unknown>)
483
+ .needed as string[];
484
+ OutputHelper.verbose(
485
+ `[StudioBridge] ${needed.length} action(s) need registering${
486
+ needed.length > 0 ? ': ' + needed.join(', ') : ''
487
+ }`
488
+ );
489
+
490
+ for (const actionName of needed) {
491
+ const action = this._actionSources.find((a) => a.name === actionName);
492
+ if (!action) continue;
493
+
494
+ OutputHelper.verbose(
495
+ `[StudioBridge] Registering action: ${actionName}`
496
+ );
497
+ await this.performActionAsync<PluginMessage>(
498
+ {
499
+ type: 'registerAction',
500
+ payload: {
501
+ name: action.name,
502
+ source: action.source,
503
+ hash: action.hash,
504
+ },
505
+ },
506
+ 10_000
507
+ );
508
+ }
509
+ }
510
+
511
+ this._actionsReady = true;
512
+ OutputHelper.verbose('[StudioBridge] Action sync complete');
513
+ }
514
+
515
+ /**
516
+ * Inject the temporary plugin via rojo build into Studio's plugins folder.
517
+ */
518
+ private async _injectPluginAsync(): Promise<void> {
519
+ this._pluginHandle = await injectPluginAsync({
520
+ port: this._port,
521
+ sessionId: this._sessionId,
522
+ });
523
+ OutputHelper.verbose(
524
+ `[StudioBridge] Plugin injected: ${this._pluginHandle.pluginPath}`
525
+ );
526
+ }
527
+
528
+ /**
529
+ * Wait for a persistent plugin to connect via WebSocket within the grace
530
+ * period. Returns true if a plugin connected (sent hello or register),
531
+ * false if the grace period expired.
532
+ */
533
+ private _waitForPluginConnectionAsync(graceMs: number): Promise<boolean> {
534
+ return new Promise<boolean>((resolve) => {
535
+ let settled = false;
536
+
537
+ const timer = setTimeout(() => {
538
+ if (!settled) {
539
+ settled = true;
540
+ resolve(false);
541
+ }
542
+ }, graceMs);
543
+
544
+ this._wss!.on('connection', (ws: WebSocket) => {
545
+ if (settled) return;
546
+
547
+ const onMessage = (raw: Buffer | string) => {
548
+ if (settled) return;
549
+ const data = typeof raw === 'string' ? raw : raw.toString('utf-8');
550
+ const msg = decodePluginMessage(data);
551
+ if (!msg) return;
552
+
553
+ if (msg.type === 'register') {
554
+ settled = true;
555
+ clearTimeout(timer);
556
+ ws.off('message', onMessage);
557
+
558
+ this._handlePluginHandshakeMessage(ws, msg);
559
+ resolve(true);
560
+ }
561
+ };
562
+
563
+ ws.on('message', onMessage);
564
+
565
+ ws.on('error', (err) => {
566
+ OutputHelper.verbose(
567
+ `[StudioBridge] WebSocket error during grace period: ${err.message}`
568
+ );
569
+ });
570
+ });
571
+ });
572
+ }
573
+
574
+ private _handlePluginHandshakeMessage(
575
+ ws: WebSocket,
576
+ msg: PluginMessage
577
+ ): void {
578
+ if (msg.type !== 'register') return;
579
+
580
+ const serverSupportedCapabilities: Capability[] = [
581
+ 'execute',
582
+ 'queryState',
583
+ 'captureScreenshot',
584
+ 'queryDataModel',
585
+ 'queryLogs',
586
+ ];
587
+
588
+ this._negotiatedCapabilities = msg.payload.capabilities.filter((cap) =>
589
+ serverSupportedCapabilities.includes(cap)
590
+ );
591
+
592
+ OutputHelper.verbose(
593
+ '[StudioBridge] Plugin register handshake accepted (grace period)'
594
+ );
595
+
596
+ this._connectedClient = ws;
597
+
598
+ ws.on('message', (raw: Buffer | string) => {
599
+ const data = typeof raw === 'string' ? raw : raw.toString('utf-8');
600
+ const innerMsg = decodePluginMessage(data);
601
+ if (!innerMsg) return;
602
+
603
+ if (this._actionDispatcher.handleResponse(innerMsg)) {
604
+ return;
605
+ }
606
+
607
+ if (innerMsg.type === 'heartbeat') {
608
+ this._lastHeartbeatTimestamp = Date.now();
609
+ }
610
+ });
611
+
612
+ ws.on('close', () => {
613
+ OutputHelper.verbose('[StudioBridge] Plugin disconnected');
614
+ this._connectedClient = undefined;
615
+ if (this._state !== 'stopping' && this._state !== 'stopped') {
616
+ this._state = 'stopped';
617
+ }
618
+ });
619
+ }
303
620
 
304
621
  private _waitForHandshakeAsync(): Promise<void> {
622
+ const serverSupportedCapabilities: Capability[] = [
623
+ 'execute',
624
+ 'queryState',
625
+ 'captureScreenshot',
626
+ 'queryDataModel',
627
+ 'queryLogs',
628
+ ];
629
+
305
630
  return new Promise<void>((resolve, reject) => {
306
631
  let settled = false;
307
632
 
@@ -322,47 +647,23 @@ export class StudioBridgeServer {
322
647
  const onMessage = (raw: Buffer | string) => {
323
648
  const data = typeof raw === 'string' ? raw : raw.toString('utf-8');
324
649
  const msg = decodePluginMessage(data);
325
- if (!msg || msg.type !== 'hello') {
650
+ if (!msg) {
326
651
  return;
327
652
  }
328
653
 
329
- if (
330
- msg.sessionId !== this._sessionId ||
331
- msg.payload.sessionId !== this._sessionId
332
- ) {
333
- OutputHelper.verbose(
334
- `[StudioBridge] Rejecting hello with wrong session ID`
654
+ if (msg.type === 'register') {
655
+ this._negotiatedCapabilities = msg.payload.capabilities.filter(
656
+ (cap) => serverSupportedCapabilities.includes(cap)
335
657
  );
336
- ws.close();
337
- return;
338
- }
339
658
 
340
- // Handshake accepted
341
- OutputHelper.verbose('[StudioBridge] Handshake accepted');
342
- ws.send(
343
- encodeMessage({
344
- type: 'welcome',
345
- sessionId: this._sessionId,
346
- payload: { sessionId: this._sessionId },
347
- })
348
- );
349
-
350
- ws.off('message', onMessage);
351
- this._connectedClient = ws;
352
-
353
- // Listen for unexpected disconnect
354
- ws.on('close', () => {
355
- OutputHelper.verbose('[StudioBridge] Plugin disconnected');
356
- this._connectedClient = undefined;
357
- if (this._state !== 'stopping' && this._state !== 'stopped') {
358
- this._state = 'stopped';
359
- }
360
- });
659
+ OutputHelper.verbose(
660
+ '[StudioBridge] Plugin register handshake accepted'
661
+ );
361
662
 
362
- if (!settled) {
663
+ ws.off('message', onMessage);
664
+ this._finishHandshake(ws, settled, timer, resolve);
363
665
  settled = true;
364
- clearTimeout(timer);
365
- resolve();
666
+ return;
366
667
  }
367
668
  };
368
669
 
@@ -385,9 +686,46 @@ export class StudioBridgeServer {
385
686
  });
386
687
  }
387
688
 
388
- // -----------------------------------------------------------------------
389
- // Private: _waitForScriptCompleteAsync
390
- // -----------------------------------------------------------------------
689
+ /**
690
+ * Common handshake completion: store the connected client, listen for
691
+ * heartbeats and disconnect events.
692
+ */
693
+ private _finishHandshake(
694
+ ws: WebSocket,
695
+ alreadySettled: boolean,
696
+ timer: ReturnType<typeof setTimeout>,
697
+ resolve: () => void
698
+ ): void {
699
+ this._connectedClient = ws;
700
+
701
+ ws.on('message', (raw: Buffer | string) => {
702
+ const data = typeof raw === 'string' ? raw : raw.toString('utf-8');
703
+ const msg = decodePluginMessage(data);
704
+ if (!msg) return;
705
+
706
+ // Action dispatcher first — request/response correlation
707
+ if (this._actionDispatcher.handleResponse(msg)) {
708
+ return;
709
+ }
710
+
711
+ if (msg.type === 'heartbeat') {
712
+ this._lastHeartbeatTimestamp = Date.now();
713
+ }
714
+ });
715
+
716
+ ws.on('close', () => {
717
+ OutputHelper.verbose('[StudioBridge] Plugin disconnected');
718
+ this._connectedClient = undefined;
719
+ if (this._state !== 'stopping' && this._state !== 'stopped') {
720
+ this._state = 'stopped';
721
+ }
722
+ });
723
+
724
+ if (!alreadySettled) {
725
+ clearTimeout(timer);
726
+ resolve();
727
+ }
728
+ }
391
729
 
392
730
  private _waitForScriptCompleteAsync(
393
731
  options: ExecuteOptions
@@ -439,20 +777,19 @@ export class StudioBridgeServer {
439
777
  }
440
778
 
441
779
  switch (msg.type) {
442
- case 'output': {
443
- for (const entry of msg.payload.messages) {
444
- logLines.push(entry.body);
445
- options.onOutput?.(entry.level, entry.body);
446
- }
447
- break;
448
- }
449
-
450
780
  case 'scriptComplete': {
451
781
  OutputHelper.verbose(
452
782
  `[StudioBridge] Script complete: success=${msg.payload.success}` +
453
783
  (msg.payload.error ? ` error=${msg.payload.error}` : '')
454
784
  );
455
785
 
786
+ if (msg.payload.output) {
787
+ for (const entry of msg.payload.output) {
788
+ logLines.push(entry.body);
789
+ options.onOutput?.(entry.level as OutputLevel, entry.body);
790
+ }
791
+ }
792
+
456
793
  if (msg.payload.error) {
457
794
  logLines.push(msg.payload.error);
458
795
  }
@@ -463,6 +800,24 @@ export class StudioBridgeServer {
463
800
  });
464
801
  break;
465
802
  }
803
+
804
+ case 'error': {
805
+ const errorPayload = msg.payload as {
806
+ code: string;
807
+ message: string;
808
+ };
809
+ OutputHelper.verbose(
810
+ `[StudioBridge] Plugin error: ${errorPayload.code} — ${errorPayload.message}`
811
+ );
812
+ logLines.push(
813
+ `[StudioBridge] Plugin error: ${errorPayload.code} — ${errorPayload.message}`
814
+ );
815
+ finish({
816
+ success: false,
817
+ logs: logLines.join('\n'),
818
+ });
819
+ break;
820
+ }
466
821
  }
467
822
  };
468
823
 
@@ -494,31 +849,27 @@ export class StudioBridgeServer {
494
849
  });
495
850
  }
496
851
 
497
- // -----------------------------------------------------------------------
498
- // Private: _cleanupResourcesAsync
499
- // -----------------------------------------------------------------------
500
-
501
852
  private async _cleanupResourcesAsync(): Promise<void> {
502
- // Kill Studio
853
+ this._actionDispatcher.cancelAll('Server shutting down');
854
+
503
855
  if (this._studioProc) {
504
856
  await this._studioProc.killAsync();
505
857
  this._studioProc = undefined;
506
858
  }
507
859
 
508
- // Remove injected plugin
509
860
  if (this._pluginHandle) {
510
861
  await this._pluginHandle.cleanupAsync();
511
862
  this._pluginHandle = undefined;
512
863
  }
513
864
 
514
- // Remove auto-built place
515
865
  if (this._placeBuildContext) {
516
866
  await this._placeBuildContext.cleanupAsync();
517
867
  this._placeBuildContext = undefined;
518
868
  }
519
869
 
520
- // Close WebSocket server — terminate lingering connections first so
521
- // the 'close' callback fires promptly.
870
+ // Terminate lingering WebSocket connections first so close callbacks
871
+ // fire promptly, then close the HTTP server (which owns the listening
872
+ // socket) and finally close the WSS.
522
873
  if (this._wss) {
523
874
  for (const wsClient of this._wss.clients) {
524
875
  wsClient.terminate();
@@ -529,6 +880,13 @@ export class StudioBridgeServer {
529
880
  this._wss = undefined;
530
881
  }
531
882
 
883
+ if (this._httpServer) {
884
+ await new Promise<void>((resolve) => {
885
+ this._httpServer!.close(() => resolve());
886
+ });
887
+ this._httpServer = undefined;
888
+ }
889
+
532
890
  this._connectedClient = undefined;
533
891
  }
534
892
  }