@quenty/studio-bridge 0.21.0 → 0.22.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 (491) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +109 -17
  3. package/build-scripts/transform-add-session-attribute.lua +1 -0
  4. package/deploy.nevermore.json +10 -0
  5. package/dist/src/bridge/bridge-connection.d.ts +26 -2
  6. package/dist/src/bridge/bridge-connection.d.ts.map +1 -1
  7. package/dist/src/bridge/bridge-connection.js +159 -14
  8. package/dist/src/bridge/bridge-connection.js.map +1 -1
  9. package/dist/src/bridge/bridge-connection.test.js +81 -0
  10. package/dist/src/bridge/bridge-connection.test.js.map +1 -1
  11. package/dist/src/bridge/bridge-session.d.ts +35 -2
  12. package/dist/src/bridge/bridge-session.d.ts.map +1 -1
  13. package/dist/src/bridge/bridge-session.js +185 -28
  14. package/dist/src/bridge/bridge-session.js.map +1 -1
  15. package/dist/src/bridge/bridge-session.test.js +6 -4
  16. package/dist/src/bridge/bridge-session.test.js.map +1 -1
  17. package/dist/src/bridge/index.d.ts +1 -1
  18. package/dist/src/bridge/index.d.ts.map +1 -1
  19. package/dist/src/bridge/index.js.map +1 -1
  20. package/dist/src/bridge/internal/bridge-client.d.ts +4 -0
  21. package/dist/src/bridge/internal/bridge-client.d.ts.map +1 -1
  22. package/dist/src/bridge/internal/bridge-client.js +20 -7
  23. package/dist/src/bridge/internal/bridge-client.js.map +1 -1
  24. package/dist/src/bridge/internal/bridge-client.test.js +18 -0
  25. package/dist/src/bridge/internal/bridge-client.test.js.map +1 -1
  26. package/dist/src/bridge/internal/bridge-host.d.ts +13 -1
  27. package/dist/src/bridge/internal/bridge-host.d.ts.map +1 -1
  28. package/dist/src/bridge/internal/bridge-host.js +35 -0
  29. package/dist/src/bridge/internal/bridge-host.js.map +1 -1
  30. package/dist/src/bridge/internal/bridge-host.test.js +31 -0
  31. package/dist/src/bridge/internal/bridge-host.test.js.map +1 -1
  32. package/dist/src/bridge/internal/hand-off.d.ts.map +1 -1
  33. package/dist/src/bridge/internal/hand-off.js +4 -1
  34. package/dist/src/bridge/internal/hand-off.js.map +1 -1
  35. package/dist/src/bridge/internal/host-protocol.d.ts +8 -0
  36. package/dist/src/bridge/internal/host-protocol.d.ts.map +1 -1
  37. package/dist/src/bridge/internal/host-protocol.js +120 -13
  38. package/dist/src/bridge/internal/host-protocol.js.map +1 -1
  39. package/dist/src/bridge/internal/host-protocol.test.js +13 -0
  40. package/dist/src/bridge/internal/host-protocol.test.js.map +1 -1
  41. package/dist/src/bridge/internal/instance-state.d.ts +9 -0
  42. package/dist/src/bridge/internal/instance-state.d.ts.map +1 -0
  43. package/dist/src/bridge/internal/instance-state.js +28 -0
  44. package/dist/src/bridge/internal/instance-state.js.map +1 -0
  45. package/dist/src/bridge/internal/transport-client.d.ts.map +1 -1
  46. package/dist/src/bridge/internal/transport-client.js +2 -1
  47. package/dist/src/bridge/internal/transport-client.js.map +1 -1
  48. package/dist/src/bridge/internal/transport-server.d.ts.map +1 -1
  49. package/dist/src/bridge/internal/transport-server.js +5 -1
  50. package/dist/src/bridge/internal/transport-server.js.map +1 -1
  51. package/dist/src/bridge/types.d.ts +43 -4
  52. package/dist/src/bridge/types.d.ts.map +1 -1
  53. package/dist/src/bridge/types.js.map +1 -1
  54. package/dist/src/cli/adapters/cli-command-adapter-handler.test.js +24 -0
  55. package/dist/src/cli/adapters/cli-command-adapter-handler.test.js.map +1 -1
  56. package/dist/src/cli/adapters/cli-command-adapter.d.ts +6 -0
  57. package/dist/src/cli/adapters/cli-command-adapter.d.ts.map +1 -1
  58. package/dist/src/cli/adapters/cli-command-adapter.js +107 -11
  59. package/dist/src/cli/adapters/cli-command-adapter.js.map +1 -1
  60. package/dist/src/cli/adapters/group-builder.d.ts +3 -0
  61. package/dist/src/cli/adapters/group-builder.d.ts.map +1 -1
  62. package/dist/src/cli/adapters/group-builder.js +34 -15
  63. package/dist/src/cli/adapters/group-builder.js.map +1 -1
  64. package/dist/src/cli/adapters/group-builder.test.js +26 -2
  65. package/dist/src/cli/adapters/group-builder.test.js.map +1 -1
  66. package/dist/src/cli/adapters/help-formatter.d.ts.map +1 -1
  67. package/dist/src/cli/adapters/help-formatter.js +4 -3
  68. package/dist/src/cli/adapters/help-formatter.js.map +1 -1
  69. package/dist/src/cli/adapters/help-formatter.test.js +1 -1
  70. package/dist/src/cli/adapters/help-formatter.test.js.map +1 -1
  71. package/dist/src/cli/adapters/playtest-edit-guard.test.d.ts +2 -0
  72. package/dist/src/cli/adapters/playtest-edit-guard.test.d.ts.map +1 -0
  73. package/dist/src/cli/adapters/playtest-edit-guard.test.js +28 -0
  74. package/dist/src/cli/adapters/playtest-edit-guard.test.js.map +1 -0
  75. package/dist/src/cli/args/global-args.d.ts +1 -1
  76. package/dist/src/cli/args/global-args.d.ts.map +1 -1
  77. package/dist/src/cli/cli-output-context.d.ts +14 -0
  78. package/dist/src/cli/cli-output-context.d.ts.map +1 -0
  79. package/dist/src/cli/cli-output-context.js +39 -0
  80. package/dist/src/cli/cli-output-context.js.map +1 -0
  81. package/dist/src/cli/cli-output-context.test.d.ts +2 -0
  82. package/dist/src/cli/cli-output-context.test.d.ts.map +1 -0
  83. package/dist/src/cli/cli-output-context.test.js +38 -0
  84. package/dist/src/cli/cli-output-context.test.js.map +1 -0
  85. package/dist/src/cli/cli.js +40 -17
  86. package/dist/src/cli/cli.js.map +1 -1
  87. package/dist/src/cli/managed-studio-run.d.ts +21 -0
  88. package/dist/src/cli/managed-studio-run.d.ts.map +1 -0
  89. package/dist/src/cli/managed-studio-run.js +75 -0
  90. package/dist/src/cli/managed-studio-run.js.map +1 -0
  91. package/dist/src/cli/managed-studio-run.test.d.ts +2 -0
  92. package/dist/src/cli/managed-studio-run.test.d.ts.map +1 -0
  93. package/dist/src/cli/managed-studio-run.test.js +52 -0
  94. package/dist/src/cli/managed-studio-run.test.js.map +1 -0
  95. package/dist/src/cli/resolve-session.js +1 -1
  96. package/dist/src/cli/resolve-session.js.map +1 -1
  97. package/dist/src/cli/resolve-session.test.js +1 -1
  98. package/dist/src/cli/resolve-session.test.js.map +1 -1
  99. package/dist/src/cli/script-executor.d.ts +13 -1
  100. package/dist/src/cli/script-executor.d.ts.map +1 -1
  101. package/dist/src/cli/script-executor.js +77 -47
  102. package/dist/src/cli/script-executor.js.map +1 -1
  103. package/dist/src/commands/console/exec/exec.d.ts +17 -0
  104. package/dist/src/commands/console/exec/exec.d.ts.map +1 -1
  105. package/dist/src/commands/console/exec/exec.js +39 -7
  106. package/dist/src/commands/console/exec/exec.js.map +1 -1
  107. package/dist/src/commands/console/exec/exec.test.js +62 -3
  108. package/dist/src/commands/console/exec/exec.test.js.map +1 -1
  109. package/dist/src/commands/console/logs/logs.d.ts +30 -2
  110. package/dist/src/commands/console/logs/logs.d.ts.map +1 -1
  111. package/dist/src/commands/console/logs/logs.js +82 -7
  112. package/dist/src/commands/console/logs/logs.js.map +1 -1
  113. package/dist/src/commands/console/logs/logs.test.js +63 -4
  114. package/dist/src/commands/console/logs/logs.test.js.map +1 -1
  115. package/dist/src/commands/explorer/export/export.d.ts +19 -0
  116. package/dist/src/commands/explorer/export/export.d.ts.map +1 -0
  117. package/dist/src/commands/explorer/export/export.js +37 -0
  118. package/dist/src/commands/explorer/export/export.js.map +1 -0
  119. package/dist/src/commands/explorer/export/export.test.d.ts +2 -0
  120. package/dist/src/commands/explorer/export/export.test.d.ts.map +1 -0
  121. package/dist/src/commands/explorer/export/export.test.js +25 -0
  122. package/dist/src/commands/explorer/export/export.test.js.map +1 -0
  123. package/dist/src/commands/explorer/find/find.d.ts +28 -0
  124. package/dist/src/commands/explorer/find/find.d.ts.map +1 -0
  125. package/dist/src/commands/explorer/find/find.js +75 -0
  126. package/dist/src/commands/explorer/find/find.js.map +1 -0
  127. package/dist/src/commands/explorer/find/find.test.d.ts +2 -0
  128. package/dist/src/commands/explorer/find/find.test.d.ts.map +1 -0
  129. package/dist/src/commands/explorer/find/find.test.js +44 -0
  130. package/dist/src/commands/explorer/find/find.test.js.map +1 -0
  131. package/dist/src/commands/explorer/grep/grep.d.ts +24 -0
  132. package/dist/src/commands/explorer/grep/grep.d.ts.map +1 -0
  133. package/dist/src/commands/explorer/grep/grep.js +63 -0
  134. package/dist/src/commands/explorer/grep/grep.js.map +1 -0
  135. package/dist/src/commands/explorer/grep/grep.test.d.ts +2 -0
  136. package/dist/src/commands/explorer/grep/grep.test.d.ts.map +1 -0
  137. package/dist/src/commands/explorer/grep/grep.test.js +42 -0
  138. package/dist/src/commands/explorer/grep/grep.test.js.map +1 -0
  139. package/dist/src/commands/explorer/import/import.d.ts +21 -0
  140. package/dist/src/commands/explorer/import/import.d.ts.map +1 -0
  141. package/dist/src/commands/explorer/import/import.js +37 -0
  142. package/dist/src/commands/explorer/import/import.js.map +1 -0
  143. package/dist/src/commands/explorer/import/import.test.d.ts +2 -0
  144. package/dist/src/commands/explorer/import/import.test.d.ts.map +1 -0
  145. package/dist/src/commands/explorer/import/import.test.js +45 -0
  146. package/dist/src/commands/explorer/import/import.test.js.map +1 -0
  147. package/dist/src/commands/formatters.test.js +7 -1
  148. package/dist/src/commands/formatters.test.js.map +1 -1
  149. package/dist/src/commands/framework/action-loader.d.ts +5 -1
  150. package/dist/src/commands/framework/action-loader.d.ts.map +1 -1
  151. package/dist/src/commands/framework/action-loader.js +9 -2
  152. package/dist/src/commands/framework/action-loader.js.map +1 -1
  153. package/dist/src/commands/framework/action-loader.test.js +23 -0
  154. package/dist/src/commands/framework/action-loader.test.js.map +1 -1
  155. package/dist/src/commands/framework/arg-builder.d.ts +15 -2
  156. package/dist/src/commands/framework/arg-builder.d.ts.map +1 -1
  157. package/dist/src/commands/framework/arg-builder.js +22 -2
  158. package/dist/src/commands/framework/arg-builder.js.map +1 -1
  159. package/dist/src/commands/framework/define-command.d.ts +19 -3
  160. package/dist/src/commands/framework/define-command.d.ts.map +1 -1
  161. package/dist/src/commands/framework/define-command.js.map +1 -1
  162. package/dist/src/commands/framework/index.d.ts +1 -1
  163. package/dist/src/commands/framework/index.d.ts.map +1 -1
  164. package/dist/src/commands/framework/index.js.map +1 -1
  165. package/dist/src/commands/index.d.ts +11 -0
  166. package/dist/src/commands/index.d.ts.map +1 -1
  167. package/dist/src/commands/index.js +11 -0
  168. package/dist/src/commands/index.js.map +1 -1
  169. package/dist/src/commands/linux/inject-credentials/inject-credentials.d.ts.map +1 -1
  170. package/dist/src/commands/linux/inject-credentials/inject-credentials.js +1 -3
  171. package/dist/src/commands/linux/inject-credentials/inject-credentials.js.map +1 -1
  172. package/dist/src/commands/linux/setup/setup.d.ts.map +1 -1
  173. package/dist/src/commands/linux/setup/setup.js +1 -3
  174. package/dist/src/commands/linux/setup/setup.js.map +1 -1
  175. package/dist/src/commands/linux/status/status.d.ts +9 -1
  176. package/dist/src/commands/linux/status/status.d.ts.map +1 -1
  177. package/dist/src/commands/linux/status/status.js +66 -86
  178. package/dist/src/commands/linux/status/status.js.map +1 -1
  179. package/dist/src/commands/playtest/player/add/add.d.ts +17 -0
  180. package/dist/src/commands/playtest/player/add/add.d.ts.map +1 -0
  181. package/dist/src/commands/playtest/player/add/add.js +45 -0
  182. package/dist/src/commands/playtest/player/add/add.js.map +1 -0
  183. package/dist/src/commands/playtest/player/list/list.d.ts +13 -0
  184. package/dist/src/commands/playtest/player/list/list.d.ts.map +1 -0
  185. package/dist/src/commands/playtest/player/list/list.js +33 -0
  186. package/dist/src/commands/playtest/player/list/list.js.map +1 -0
  187. package/dist/src/commands/playtest/player/playtest-players.d.ts +36 -0
  188. package/dist/src/commands/playtest/player/playtest-players.d.ts.map +1 -0
  189. package/dist/src/commands/playtest/player/playtest-players.js +187 -0
  190. package/dist/src/commands/playtest/player/playtest-players.js.map +1 -0
  191. package/dist/src/commands/playtest/player/playtest-players.test.d.ts +2 -0
  192. package/dist/src/commands/playtest/player/playtest-players.test.d.ts.map +1 -0
  193. package/dist/src/commands/playtest/player/playtest-players.test.js +89 -0
  194. package/dist/src/commands/playtest/player/playtest-players.test.js.map +1 -0
  195. package/dist/src/commands/playtest/player/remove/remove.d.ts +17 -0
  196. package/dist/src/commands/playtest/player/remove/remove.d.ts.map +1 -0
  197. package/dist/src/commands/playtest/player/remove/remove.js +42 -0
  198. package/dist/src/commands/playtest/player/remove/remove.js.map +1 -0
  199. package/dist/src/commands/playtest/playtest-sessions.d.ts +49 -0
  200. package/dist/src/commands/playtest/playtest-sessions.d.ts.map +1 -0
  201. package/dist/src/commands/playtest/playtest-sessions.js +283 -0
  202. package/dist/src/commands/playtest/playtest-sessions.js.map +1 -0
  203. package/dist/src/commands/playtest/playtest-sessions.test.d.ts +2 -0
  204. package/dist/src/commands/playtest/playtest-sessions.test.d.ts.map +1 -0
  205. package/dist/src/commands/playtest/playtest-sessions.test.js +87 -0
  206. package/dist/src/commands/playtest/playtest-sessions.test.js.map +1 -0
  207. package/dist/src/commands/playtest/restart/restart.d.ts +23 -0
  208. package/dist/src/commands/playtest/restart/restart.d.ts.map +1 -0
  209. package/dist/src/commands/playtest/restart/restart.js +105 -0
  210. package/dist/src/commands/playtest/restart/restart.js.map +1 -0
  211. package/dist/src/commands/playtest/run/run.d.ts +47 -0
  212. package/dist/src/commands/playtest/run/run.d.ts.map +1 -0
  213. package/dist/src/commands/playtest/run/run.js +137 -0
  214. package/dist/src/commands/playtest/run/run.js.map +1 -0
  215. package/dist/src/commands/playtest/start/start.d.ts +42 -0
  216. package/dist/src/commands/playtest/start/start.d.ts.map +1 -0
  217. package/dist/src/commands/playtest/start/start.js +70 -0
  218. package/dist/src/commands/playtest/start/start.js.map +1 -0
  219. package/dist/src/commands/playtest/stop/stop.d.ts +15 -0
  220. package/dist/src/commands/playtest/stop/stop.d.ts.map +1 -0
  221. package/dist/src/commands/playtest/stop/stop.js +24 -0
  222. package/dist/src/commands/playtest/stop/stop.js.map +1 -0
  223. package/dist/src/commands/process/close/close.d.ts +19 -10
  224. package/dist/src/commands/process/close/close.d.ts.map +1 -1
  225. package/dist/src/commands/process/close/close.js +118 -15
  226. package/dist/src/commands/process/close/close.js.map +1 -1
  227. package/dist/src/commands/process/close/close.test.d.ts +2 -0
  228. package/dist/src/commands/process/close/close.test.d.ts.map +1 -0
  229. package/dist/src/commands/process/close/close.test.js +190 -0
  230. package/dist/src/commands/process/close/close.test.js.map +1 -0
  231. package/dist/src/commands/process/info/info.d.ts +45 -5
  232. package/dist/src/commands/process/info/info.d.ts.map +1 -1
  233. package/dist/src/commands/process/info/info.js +117 -13
  234. package/dist/src/commands/process/info/info.js.map +1 -1
  235. package/dist/src/commands/process/info/info.test.js +140 -38
  236. package/dist/src/commands/process/info/info.test.js.map +1 -1
  237. package/dist/src/commands/process/launch/launch.d.ts +11 -1
  238. package/dist/src/commands/process/launch/launch.d.ts.map +1 -1
  239. package/dist/src/commands/process/launch/launch.js +37 -7
  240. package/dist/src/commands/process/launch/launch.js.map +1 -1
  241. package/dist/src/commands/process/launch/launch.test.js +99 -20
  242. package/dist/src/commands/process/launch/launch.test.js.map +1 -1
  243. package/dist/src/commands/process/list/list.d.ts +2 -1
  244. package/dist/src/commands/process/list/list.d.ts.map +1 -1
  245. package/dist/src/commands/process/list/list.js +9 -6
  246. package/dist/src/commands/process/list/list.js.map +1 -1
  247. package/dist/src/commands/process/list/list.test.js +1 -0
  248. package/dist/src/commands/process/list/list.test.js.map +1 -1
  249. package/dist/src/commands/process/run/run.d.ts +9 -0
  250. package/dist/src/commands/process/run/run.d.ts.map +1 -1
  251. package/dist/src/commands/process/run/run.js +15 -5
  252. package/dist/src/commands/process/run/run.js.map +1 -1
  253. package/dist/src/commands/serve/serve.d.ts +2 -0
  254. package/dist/src/commands/serve/serve.d.ts.map +1 -1
  255. package/dist/src/commands/serve/serve.js +17 -4
  256. package/dist/src/commands/serve/serve.js.map +1 -1
  257. package/dist/src/commands/serve/serve.test.js +9 -2
  258. package/dist/src/commands/serve/serve.test.js.map +1 -1
  259. package/dist/src/commands/viewport/screenshot/screenshot.d.ts.map +1 -1
  260. package/dist/src/commands/viewport/screenshot/screenshot.js +4 -1
  261. package/dist/src/commands/viewport/screenshot/screenshot.js.map +1 -1
  262. package/dist/src/commands/viewport/screenshot/screenshot.test.js +5 -9
  263. package/dist/src/commands/viewport/screenshot/screenshot.test.js.map +1 -1
  264. package/dist/src/deploy/deploy-places.d.ts +39 -0
  265. package/dist/src/deploy/deploy-places.d.ts.map +1 -0
  266. package/dist/src/deploy/deploy-places.js +162 -0
  267. package/dist/src/deploy/deploy-places.js.map +1 -0
  268. package/dist/src/deploy/deploy-places.test.d.ts +2 -0
  269. package/dist/src/deploy/deploy-places.test.d.ts.map +1 -0
  270. package/dist/src/deploy/deploy-places.test.js +96 -0
  271. package/dist/src/deploy/deploy-places.test.js.map +1 -0
  272. package/dist/src/index.d.ts +2 -2
  273. package/dist/src/index.d.ts.map +1 -1
  274. package/dist/src/index.js +1 -1
  275. package/dist/src/index.js.map +1 -1
  276. package/dist/src/linux/linux-studio-launcher.d.ts.map +1 -1
  277. package/dist/src/linux/linux-studio-launcher.js +10 -0
  278. package/dist/src/linux/linux-studio-launcher.js.map +1 -1
  279. package/dist/src/linux/linux-studio-launcher.test.d.ts +2 -0
  280. package/dist/src/linux/linux-studio-launcher.test.d.ts.map +1 -0
  281. package/dist/src/linux/linux-studio-launcher.test.js +68 -0
  282. package/dist/src/linux/linux-studio-launcher.test.js.map +1 -0
  283. package/dist/src/plugin/persistent-plugin-installer.d.ts.map +1 -1
  284. package/dist/src/plugin/persistent-plugin-installer.js +2 -1
  285. package/dist/src/plugin/persistent-plugin-installer.js.map +1 -1
  286. package/dist/src/plugin/persistent-plugin-installer.test.js +3 -0
  287. package/dist/src/plugin/persistent-plugin-installer.test.js.map +1 -1
  288. package/dist/src/plugin/plugin-build-version.d.ts +7 -0
  289. package/dist/src/plugin/plugin-build-version.d.ts.map +1 -0
  290. package/dist/src/plugin/plugin-build-version.js +42 -0
  291. package/dist/src/plugin/plugin-build-version.js.map +1 -0
  292. package/dist/src/plugin/plugin-build-version.test.d.ts +2 -0
  293. package/dist/src/plugin/plugin-build-version.test.d.ts.map +1 -0
  294. package/dist/src/plugin/plugin-build-version.test.js +41 -0
  295. package/dist/src/plugin/plugin-build-version.test.js.map +1 -0
  296. package/dist/src/plugin/plugin-injector.d.ts.map +1 -1
  297. package/dist/src/plugin/plugin-injector.js +7 -1
  298. package/dist/src/plugin/plugin-injector.js.map +1 -1
  299. package/dist/src/process/studio-process-closer.d.ts +35 -0
  300. package/dist/src/process/studio-process-closer.d.ts.map +1 -0
  301. package/dist/src/process/studio-process-closer.js +129 -0
  302. package/dist/src/process/studio-process-closer.js.map +1 -0
  303. package/dist/src/process/studio-process-closer.test.d.ts +2 -0
  304. package/dist/src/process/studio-process-closer.test.d.ts.map +1 -0
  305. package/dist/src/process/studio-process-closer.test.js +80 -0
  306. package/dist/src/process/studio-process-closer.test.js.map +1 -0
  307. package/dist/src/process/studio-settings.d.ts +14 -0
  308. package/dist/src/process/studio-settings.d.ts.map +1 -0
  309. package/dist/src/process/studio-settings.js +50 -0
  310. package/dist/src/process/studio-settings.js.map +1 -0
  311. package/dist/src/process/studio-settings.test.d.ts +2 -0
  312. package/dist/src/process/studio-settings.test.d.ts.map +1 -0
  313. package/dist/src/process/studio-settings.test.js +16 -0
  314. package/dist/src/process/studio-settings.test.js.map +1 -0
  315. package/dist/src/process/studio-window-state.d.ts +13 -0
  316. package/dist/src/process/studio-window-state.d.ts.map +1 -0
  317. package/dist/src/process/studio-window-state.js +48 -0
  318. package/dist/src/process/studio-window-state.js.map +1 -0
  319. package/dist/src/server/studio-bridge-server.d.ts +3 -1
  320. package/dist/src/server/studio-bridge-server.d.ts.map +1 -1
  321. package/dist/src/server/studio-bridge-server.js +12 -4
  322. package/dist/src/server/studio-bridge-server.js.map +1 -1
  323. package/dist/src/server/web-socket-protocol.d.ts +173 -6
  324. package/dist/src/server/web-socket-protocol.d.ts.map +1 -1
  325. package/dist/src/server/web-socket-protocol.js +244 -1
  326. package/dist/src/server/web-socket-protocol.js.map +1 -1
  327. package/dist/src/server/web-socket-protocol.test.js +48 -0
  328. package/dist/src/server/web-socket-protocol.test.js.map +1 -1
  329. package/dist/src/test/e2e/persistent-session.test.js +121 -0
  330. package/dist/src/test/e2e/persistent-session.test.js.map +1 -1
  331. package/dist/src/test/e2e/split-server.test.d.ts +3 -5
  332. package/dist/src/test/e2e/split-server.test.d.ts.map +1 -1
  333. package/dist/src/test/e2e/split-server.test.js +3 -5
  334. package/dist/src/test/e2e/split-server.test.js.map +1 -1
  335. package/dist/tsconfig.tsbuildinfo +1 -1
  336. package/docker/Dockerfile +3 -0
  337. package/package.json +8 -6
  338. package/src/bridge/bridge-connection.test.ts +126 -0
  339. package/src/bridge/bridge-connection.ts +217 -22
  340. package/src/bridge/bridge-session.test.ts +6 -4
  341. package/src/bridge/bridge-session.ts +273 -28
  342. package/src/bridge/index.ts +3 -0
  343. package/src/bridge/internal/bridge-client.test.ts +23 -0
  344. package/src/bridge/internal/bridge-client.ts +25 -7
  345. package/src/bridge/internal/bridge-host.test.ts +38 -0
  346. package/src/bridge/internal/bridge-host.ts +47 -0
  347. package/src/bridge/internal/hand-off.ts +4 -1
  348. package/src/bridge/internal/host-protocol.test.ts +15 -0
  349. package/src/bridge/internal/host-protocol.ts +148 -37
  350. package/src/bridge/internal/instance-state.ts +34 -0
  351. package/src/bridge/internal/transport-client.ts +2 -1
  352. package/src/bridge/internal/transport-server.ts +5 -1
  353. package/src/bridge/types.ts +47 -2
  354. package/src/cli/adapters/cli-command-adapter-handler.test.ts +28 -0
  355. package/src/cli/adapters/cli-command-adapter.ts +150 -18
  356. package/src/cli/adapters/group-builder.test.ts +34 -2
  357. package/src/cli/adapters/group-builder.ts +52 -20
  358. package/src/cli/adapters/help-formatter.test.ts +1 -1
  359. package/src/cli/adapters/help-formatter.ts +4 -3
  360. package/src/cli/adapters/playtest-edit-guard.test.ts +54 -0
  361. package/src/cli/args/global-args.ts +1 -1
  362. package/src/cli/cli-output-context.test.ts +55 -0
  363. package/src/cli/cli-output-context.ts +50 -0
  364. package/src/cli/cli.ts +49 -17
  365. package/src/cli/managed-studio-run.test.ts +71 -0
  366. package/src/cli/managed-studio-run.ts +135 -0
  367. package/src/cli/resolve-session.test.ts +1 -1
  368. package/src/cli/resolve-session.ts +1 -1
  369. package/src/cli/script-executor.ts +99 -51
  370. package/src/commands/console/exec/exec.test.ts +96 -3
  371. package/src/commands/console/exec/exec.ts +59 -6
  372. package/src/commands/console/exec/execute.lua +356 -240
  373. package/src/commands/console/exec/execute.spec.lua +286 -0
  374. package/src/commands/console/logs/logs.test.ts +76 -4
  375. package/src/commands/console/logs/logs.ts +132 -17
  376. package/src/commands/console/logs/query-logs.lua +85 -52
  377. package/src/commands/console/logs/query-logs.spec.lua +132 -0
  378. package/src/commands/explorer/export/export-instances.lua +108 -0
  379. package/src/commands/explorer/export/export-instances.spec.lua +87 -0
  380. package/src/commands/explorer/export/export.test.ts +27 -0
  381. package/src/commands/explorer/export/export.ts +60 -0
  382. package/src/commands/explorer/find/find-instances.lua +174 -0
  383. package/src/commands/explorer/find/find-instances.spec.lua +122 -0
  384. package/src/commands/explorer/find/find.test.ts +53 -0
  385. package/src/commands/explorer/find/find.ts +113 -0
  386. package/src/commands/explorer/grep/grep-scripts.lua +214 -0
  387. package/src/commands/explorer/grep/grep-scripts.spec.lua +130 -0
  388. package/src/commands/explorer/grep/grep.test.ts +45 -0
  389. package/src/commands/explorer/grep/grep.ts +93 -0
  390. package/src/commands/explorer/import/import-instances.lua +106 -0
  391. package/src/commands/explorer/import/import-instances.spec.lua +84 -0
  392. package/src/commands/explorer/import/import.test.ts +60 -0
  393. package/src/commands/explorer/import/import.ts +66 -0
  394. package/src/commands/explorer/query/query-data-model.lua +124 -152
  395. package/src/commands/explorer/query/query-data-model.spec.lua +150 -0
  396. package/src/commands/formatters.test.ts +7 -1
  397. package/src/commands/framework/action-loader.test.ts +28 -0
  398. package/src/commands/framework/action-loader.ts +10 -2
  399. package/src/commands/framework/arg-builder.ts +26 -3
  400. package/src/commands/framework/define-command.ts +32 -3
  401. package/src/commands/framework/index.ts +1 -0
  402. package/src/commands/index.ts +50 -0
  403. package/src/commands/linux/inject-credentials/inject-credentials.ts +1 -3
  404. package/src/commands/linux/setup/setup.ts +1 -3
  405. package/src/commands/linux/status/status.ts +105 -98
  406. package/src/commands/playtest/player/add/add.ts +85 -0
  407. package/src/commands/playtest/player/list/list.ts +57 -0
  408. package/src/commands/playtest/player/playtest-players.test.ts +146 -0
  409. package/src/commands/playtest/player/playtest-players.ts +270 -0
  410. package/src/commands/playtest/player/remove/remove.ts +78 -0
  411. package/src/commands/playtest/playtest-sessions.test.ts +143 -0
  412. package/src/commands/playtest/playtest-sessions.ts +417 -0
  413. package/src/commands/playtest/restart/restart.ts +199 -0
  414. package/src/commands/playtest/run/playtest-runner.luau +264 -0
  415. package/src/commands/playtest/run/playtest-runner.spec.lua +71 -0
  416. package/src/commands/playtest/run/run-playtest-script.lua +139 -0
  417. package/src/commands/playtest/run/run-playtest-script.spec.lua +43 -0
  418. package/src/commands/playtest/run/run.ts +239 -0
  419. package/src/commands/playtest/start/start-playtest.lua +108 -0
  420. package/src/commands/playtest/start/start.ts +138 -0
  421. package/src/commands/playtest/stop/end-playtest.lua +47 -0
  422. package/src/commands/playtest/stop/stop.ts +51 -0
  423. package/src/commands/process/close/close.test.ts +250 -0
  424. package/src/commands/process/close/close.ts +183 -17
  425. package/src/commands/process/info/info.test.ts +198 -44
  426. package/src/commands/process/info/info.ts +204 -15
  427. package/src/commands/process/info/query-state.lua +42 -29
  428. package/src/commands/process/info/query-state.spec.lua +39 -0
  429. package/src/commands/process/launch/launch.test.ts +138 -21
  430. package/src/commands/process/launch/launch.ts +69 -9
  431. package/src/commands/process/list/list.test.ts +1 -0
  432. package/src/commands/process/list/list.ts +14 -6
  433. package/src/commands/process/run/run.ts +26 -5
  434. package/src/commands/serve/serve.test.ts +17 -2
  435. package/src/commands/serve/serve.ts +25 -6
  436. package/src/commands/viewport/screenshot/capture-screenshot.lua +175 -182
  437. package/src/commands/viewport/screenshot/capture-screenshot.spec.lua +129 -0
  438. package/src/commands/viewport/screenshot/screenshot.test.ts +7 -10
  439. package/src/commands/viewport/screenshot/screenshot.ts +6 -1
  440. package/src/deploy/deploy-places.test.ts +127 -0
  441. package/src/deploy/deploy-places.ts +229 -0
  442. package/src/index.ts +11 -0
  443. package/src/linux/linux-studio-launcher.test.ts +89 -0
  444. package/src/linux/linux-studio-launcher.ts +11 -0
  445. package/src/plugin/persistent-plugin-installer.test.ts +4 -0
  446. package/src/plugin/persistent-plugin-installer.ts +2 -1
  447. package/src/plugin/plugin-build-version.test.ts +55 -0
  448. package/src/plugin/plugin-build-version.ts +53 -0
  449. package/src/plugin/plugin-injector.ts +7 -1
  450. package/src/process/studio-process-closer.test.ts +107 -0
  451. package/src/process/studio-process-closer.ts +187 -0
  452. package/src/process/studio-settings.test.ts +18 -0
  453. package/src/process/studio-settings.ts +61 -0
  454. package/src/process/studio-window-state.ts +65 -0
  455. package/src/server/studio-bridge-server.ts +15 -4
  456. package/src/server/web-socket-protocol.test.ts +55 -0
  457. package/src/server/web-socket-protocol.ts +468 -8
  458. package/src/test/e2e/persistent-session.test.ts +137 -0
  459. package/src/test/e2e/split-server.test.ts +3 -5
  460. package/templates/studio-bridge-plugin/default.project.json +3 -0
  461. package/templates/studio-bridge-plugin/src/Shared/ActionRouter.lua +208 -159
  462. package/templates/studio-bridge-plugin/src/Shared/ActionRouter.spec.lua +418 -0
  463. package/templates/studio-bridge-plugin/src/Shared/BuiltInActions.lua +94 -0
  464. package/templates/studio-bridge-plugin/src/Shared/BuiltInActions.spec.lua +166 -0
  465. package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.lua +118 -137
  466. package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.spec.lua +228 -0
  467. package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.lua +80 -109
  468. package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.spec.lua +116 -0
  469. package/templates/studio-bridge-plugin/src/Shared/StudioBridgeConnection.lua +233 -0
  470. package/templates/studio-bridge-plugin/src/Shared/StudioBridgeConnection.spec.lua +239 -0
  471. package/templates/studio-bridge-plugin/src/Shared/StudioBridgeLogUtils.lua +53 -0
  472. package/templates/studio-bridge-plugin/src/Shared/StudioBridgeLogUtils.spec.lua +27 -0
  473. package/templates/studio-bridge-plugin/src/Shared/StudioBridgeSessionUtils.lua +164 -0
  474. package/templates/studio-bridge-plugin/src/Shared/StudioBridgeSessionUtils.spec.lua +159 -0
  475. package/templates/studio-bridge-plugin/src/StudioBridgePlugin.server.lua +266 -368
  476. package/templates/studio-bridge-plugin/src/Vendor/png.lua +8 -2
  477. package/test/default.project.json +41 -0
  478. package/test/jest.config.lua +3 -0
  479. package/test/scripts/Server/ServerMain.server.lua +10 -0
  480. package/tsconfig.json +1 -0
  481. package/templates/studio-bridge-plugin/src/Shared/Protocol.lua +0 -132
  482. package/templates/studio-bridge-plugin-test/test/actions.test.lua +0 -580
  483. package/templates/studio-bridge-plugin-test/test/discovery.test.lua +0 -622
  484. package/templates/studio-bridge-plugin-test/test/execute-handler.test.lua +0 -517
  485. package/templates/studio-bridge-plugin-test/test/hash-lifecycle.test.lua +0 -814
  486. package/templates/studio-bridge-plugin-test/test/integration.test.lua +0 -1020
  487. package/templates/studio-bridge-plugin-test/test/new-actions.test.lua +0 -339
  488. package/templates/studio-bridge-plugin-test/test/plugin-entry.test.lua +0 -493
  489. package/templates/studio-bridge-plugin-test/test/protocol.test.lua +0 -506
  490. package/templates/studio-bridge-plugin-test/test/roblox-mocks.lua +0 -108
  491. package/templates/studio-bridge-plugin-test/test/test-runner.lua +0 -112
package/src/cli/cli.ts CHANGED
@@ -18,6 +18,7 @@ import { fileURLToPath } from 'url';
18
18
  import { dirname, join } from 'path';
19
19
  import { OutputHelper } from '@quenty/cli-output-helpers';
20
20
  import { VersionChecker } from '@quenty/nevermore-cli-helpers';
21
+ import { addWarning, setJsonOutput } from './cli-output-context.js';
21
22
 
22
23
  import { CommandRegistry } from '../commands/framework/command-registry.js';
23
24
  import { buildGroupCommands } from './adapters/group-builder.js';
@@ -26,12 +27,23 @@ import { buildGroupCommands } from './adapters/group-builder.js';
26
27
  import { execCommand } from '../commands/console/exec/exec.js';
27
28
  import { logsCommand } from '../commands/console/logs/logs.js';
28
29
  import { queryCommand } from '../commands/explorer/query/query.js';
30
+ import { exportCommand } from '../commands/explorer/export/export.js';
31
+ import { importCommand } from '../commands/explorer/import/import.js';
32
+ import { findCommand } from '../commands/explorer/find/find.js';
33
+ import { grepCommand } from '../commands/explorer/grep/grep.js';
29
34
  import { screenshotCommand } from '../commands/viewport/screenshot/screenshot.js';
30
35
  import { infoCommand } from '../commands/process/info/info.js';
31
36
  import { listCommand } from '../commands/process/list/list.js';
32
37
  import { launchCommand } from '../commands/process/launch/launch.js';
33
38
  import { processRunCommand } from '../commands/process/run/run.js';
34
39
  import { processCloseCommand } from '../commands/process/close/close.js';
40
+ import { playtestStartCommand } from '../commands/playtest/start/start.js';
41
+ import { playtestStopCommand } from '../commands/playtest/stop/stop.js';
42
+ import { playtestRunCommand } from '../commands/playtest/run/run.js';
43
+ import { playtestRestartCommand } from '../commands/playtest/restart/restart.js';
44
+ import { playtestPlayerListCommand } from '../commands/playtest/player/list/list.js';
45
+ import { playtestPlayerAddCommand } from '../commands/playtest/player/add/add.js';
46
+ import { playtestPlayerRemoveCommand } from '../commands/playtest/player/remove/remove.js';
35
47
  import { installCommand } from '../commands/plugin/install/install.js';
36
48
  import { uninstallCommand } from '../commands/plugin/uninstall/uninstall.js';
37
49
  import { serveCommand } from '../commands/serve/serve.js';
@@ -45,14 +57,25 @@ const registry = new CommandRegistry();
45
57
  registry.register(execCommand);
46
58
  registry.register(logsCommand);
47
59
  registry.register(queryCommand);
60
+ registry.register(exportCommand);
61
+ registry.register(importCommand);
62
+ registry.register(findCommand);
63
+ registry.register(grepCommand);
48
64
  registry.register(screenshotCommand);
49
- registry.register(processRunCommand);
65
+ registry.register(launchCommand);
66
+ registry.register(playtestStartCommand);
67
+ registry.register(playtestStopCommand);
68
+ registry.register(playtestRunCommand);
69
+ registry.register(playtestRestartCommand);
70
+ registry.register(playtestPlayerListCommand);
71
+ registry.register(playtestPlayerAddCommand);
72
+ registry.register(playtestPlayerRemoveCommand);
50
73
 
51
74
  // Infrastructure commands
52
- registry.register(infoCommand);
53
75
  registry.register(listCommand);
54
- registry.register(launchCommand);
76
+ registry.register(infoCommand);
55
77
  registry.register(processCloseCommand);
78
+ registry.register(processRunCommand);
56
79
  registry.register(installCommand);
57
80
  registry.register(uninstallCommand);
58
81
  registry.register(serveCommand);
@@ -64,10 +87,13 @@ registry.register(linuxStatusCommand);
64
87
 
65
88
  const { groups, topLevel } = buildGroupCommands(registry);
66
89
 
67
- const formatArg = process.argv.includes('--format')
68
- ? process.argv[process.argv.indexOf('--format') + 1]
69
- : undefined;
70
- const isMachineReadable = formatArg === 'json';
90
+ OutputHelper.setDiagnosticsToStderr(true);
91
+
92
+ const formatIndex = process.argv.indexOf('--format');
93
+ const isMachineReadable =
94
+ process.argv.includes('--format=json') ||
95
+ (formatIndex !== -1 && process.argv[formatIndex + 1] === 'json');
96
+ setJsonOutput(isMachineReadable);
71
97
 
72
98
  const versionData = await VersionChecker.checkForUpdatesAsync({
73
99
  humanReadableName: 'Studio Bridge',
@@ -80,15 +106,13 @@ const versionData = await VersionChecker.checkForUpdatesAsync({
80
106
  silent: isMachineReadable,
81
107
  });
82
108
 
83
- // Expose version metadata so the adapter can inject it into JSON output
84
109
  if (isMachineReadable && versionData) {
85
- const warnings: string[] = [];
86
110
  if (versionData.isLocalDev) {
87
- warnings.push(
111
+ addWarning(
88
112
  `Studio Bridge is running in local development mode. Run 'npm install -g @quenty/studio-bridge@latest' to switch to production copy.`
89
113
  );
90
114
  } else if (versionData.updateAvailable) {
91
- warnings.push(
115
+ addWarning(
92
116
  `Studio Bridge update available: ${VersionChecker.getVersionDisplayName(
93
117
  versionData
94
118
  )} → ${
@@ -96,9 +120,6 @@ if (isMachineReadable && versionData) {
96
120
  }. Run 'npm install -g @quenty/studio-bridge@latest' to update.`
97
121
  );
98
122
  }
99
- if (warnings.length > 0) {
100
- (globalThis as any).__studioBridgeWarnings = warnings;
101
- }
102
123
  }
103
124
 
104
125
  const cli = yargs(hideBin(process.argv))
@@ -109,9 +130,9 @@ const cli = yargs(hideBin(process.argv))
109
130
  : undefined) as any
110
131
  )
111
132
  .option('timeout', {
112
- description: 'Timeout in milliseconds',
133
+ description:
134
+ 'How long to wait for a Studio session to connect, in milliseconds',
113
135
  type: 'number',
114
- default: 120_000,
115
136
  global: true,
116
137
  })
117
138
  .option('verbose', {
@@ -135,7 +156,17 @@ const cli = yargs(hideBin(process.argv))
135
156
  .middleware((argv) => {
136
157
  OutputHelper.setVerbose(argv.verbose as boolean);
137
158
  })
138
- .usage(OutputHelper.formatInfo('Usage: $0 <command> [options]'));
159
+ .usage(OutputHelper.formatInfo('Usage: $0 <command> [options]'))
160
+ .example(
161
+ '$0 process launch',
162
+ "Open the place of the nearest deploy.nevermore.json's default target in Studio"
163
+ )
164
+ .example('$0 process list', 'List the connected Studio sessions')
165
+ .example(
166
+ "$0 console exec 'return workspace:GetChildren()'",
167
+ 'Run Luau in Studio and print what it returns'
168
+ )
169
+ .example('$0 playtest start', 'Start a playtest');
139
170
 
140
171
  // Register grouped commands (console, explorer, viewport, process, plugin)
141
172
  for (const group of groups) {
@@ -154,4 +185,5 @@ cli
154
185
  OutputHelper.formatHint("Hint: See 'studio-bridge help' for more help")
155
186
  )
156
187
  .wrap(null)
188
+ .parserConfiguration({ 'populate--': true })
157
189
  .strict().argv;
@@ -0,0 +1,71 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { EventEmitter } from 'events';
3
+ import { waitForLaunchedSessionAsync } from './managed-studio-run.js';
4
+
5
+ function createConnection() {
6
+ const emitter = new EventEmitter();
7
+ const sessions: Array<{
8
+ sessionId: string;
9
+ launchId?: string;
10
+ context: string;
11
+ }> = [];
12
+ const connection = Object.assign(emitter, {
13
+ listSessions: () => sessions,
14
+ getSession: (id: string) =>
15
+ sessions.some((s) => s.sessionId === id) ? { id } : undefined,
16
+ });
17
+ return {
18
+ connection: connection as any,
19
+ addSession(session: {
20
+ sessionId: string;
21
+ launchId?: string;
22
+ context: string;
23
+ }) {
24
+ sessions.push(session);
25
+ emitter.emit('session-connected');
26
+ },
27
+ };
28
+ }
29
+
30
+ describe('waitForLaunchedSessionAsync', () => {
31
+ it('resolves with the edit session carrying the launch id', async () => {
32
+ const { connection, addSession } = createConnection();
33
+ const promise = waitForLaunchedSessionAsync(connection, 'launch-1', 1_000);
34
+
35
+ addSession({ sessionId: 'other-edit', context: 'edit' });
36
+ addSession({
37
+ sessionId: 'run-server',
38
+ launchId: 'launch-1',
39
+ context: 'server',
40
+ });
41
+ addSession({
42
+ sessionId: 'run-edit',
43
+ launchId: 'launch-1',
44
+ context: 'edit',
45
+ });
46
+
47
+ await expect(promise).resolves.toEqual({ id: 'run-edit' });
48
+ });
49
+
50
+ it('resolves right away when the session already connected', async () => {
51
+ const { connection, addSession } = createConnection();
52
+ addSession({
53
+ sessionId: 'run-edit',
54
+ launchId: 'launch-1',
55
+ context: 'edit',
56
+ });
57
+
58
+ await expect(
59
+ waitForLaunchedSessionAsync(connection, 'launch-1', 1_000)
60
+ ).resolves.toEqual({ id: 'run-edit' });
61
+ });
62
+
63
+ it('rejects when the launched Studio never connects', async () => {
64
+ const { connection, addSession } = createConnection();
65
+ const promise = waitForLaunchedSessionAsync(connection, 'launch-1', 50);
66
+
67
+ addSession({ sessionId: 'other-edit', context: 'edit' });
68
+
69
+ await expect(promise).rejects.toThrow(/did not connect/);
70
+ });
71
+ });
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Runs a script in a Studio launched for the run, through the regular bridge.
3
+ * The place copy carries a launch id that the persistent plugin reports when
4
+ * it registers, so the script runs in that Studio and no other. While the run
5
+ * lasts, the launched Studio is an ordinary session other commands can target.
6
+ */
7
+
8
+ import { randomUUID } from 'crypto';
9
+ import * as path from 'path';
10
+ import {
11
+ BuildContext,
12
+ resolvePackagePath,
13
+ resolveTemplatePath,
14
+ } from '@quenty/nevermore-template-helpers';
15
+ import { BridgeConnection } from '../bridge/index.js';
16
+ import type { BridgeSession, ExecResult } from '../bridge/index.js';
17
+ import type { StudioBridgePhase } from '../server/studio-bridge-server.js';
18
+ import { launchStudioAsync } from '../process/studio-process-manager.js';
19
+
20
+ const DEFAULT_LAUNCH_TIMEOUT_MS = 120_000;
21
+
22
+ const defaultProjectPath = resolveTemplatePath(
23
+ import.meta.url,
24
+ path.join('default-test-place', 'default.project.json')
25
+ );
26
+
27
+ const launchIdTransformScript = resolvePackagePath(
28
+ import.meta.url,
29
+ 'build-scripts',
30
+ 'transform-add-session-attribute.lua'
31
+ );
32
+
33
+ export interface ManagedStudioRunOptions {
34
+ scriptContent: string;
35
+ placePath?: string;
36
+ timeoutMs: number;
37
+ launchTimeoutMs?: number;
38
+ onPhase?: (phase: StudioBridgePhase) => void;
39
+ /** Passed to the script as `...`. */
40
+ args?: string[];
41
+ }
42
+
43
+ export async function runInManagedStudioAsync(
44
+ options: ManagedStudioRunOptions
45
+ ): Promise<ExecResult> {
46
+ const launchId = randomUUID();
47
+ const buildContext = await BuildContext.createAsync({
48
+ prefix: 'studio-bridge-run-',
49
+ });
50
+ // Kept alive while Studio boots, which takes longer than the idle shutdown
51
+ const connection = await BridgeConnection.connectAsync({ keepAlive: true });
52
+ let killStudioAsync: (() => Promise<void>) | undefined;
53
+
54
+ try {
55
+ let sourcePlacePath = options.placePath;
56
+ if (!sourcePlacePath) {
57
+ options.onPhase?.('building');
58
+ sourcePlacePath = buildContext.resolvePath('minimal.rbxl');
59
+ await buildContext.rojoBuildAsync({
60
+ projectPath: defaultProjectPath,
61
+ output: sourcePlacePath,
62
+ });
63
+ }
64
+
65
+ // Keep the place's file name, which is what its session id is made from
66
+ const launchedPlacePath = buildContext.resolvePath(
67
+ options.placePath ? path.basename(options.placePath) : 'place.rbxl'
68
+ );
69
+ await buildContext.executeLuneTransformScriptAsync(
70
+ launchIdTransformScript,
71
+ sourcePlacePath,
72
+ launchedPlacePath,
73
+ launchId
74
+ );
75
+
76
+ options.onPhase?.('launching');
77
+ const sessionPromise = waitForLaunchedSessionAsync(
78
+ connection,
79
+ launchId,
80
+ options.launchTimeoutMs ?? DEFAULT_LAUNCH_TIMEOUT_MS
81
+ );
82
+ const studio = await launchStudioAsync(launchedPlacePath);
83
+ killStudioAsync = studio.killAsync;
84
+
85
+ options.onPhase?.('connecting');
86
+ const session = await sessionPromise;
87
+
88
+ options.onPhase?.('executing');
89
+ return await session.execAsync(
90
+ options.scriptContent,
91
+ options.timeoutMs,
92
+ options.args
93
+ );
94
+ } finally {
95
+ await killStudioAsync?.();
96
+ await connection.disconnectAsync();
97
+ await buildContext.cleanupAsync();
98
+ }
99
+ }
100
+
101
+ export function waitForLaunchedSessionAsync(
102
+ connection: BridgeConnection,
103
+ launchId: string,
104
+ timeoutMs: number
105
+ ): Promise<BridgeSession> {
106
+ return new Promise((resolve, reject) => {
107
+ const findSession = (): BridgeSession | undefined => {
108
+ const info = connection
109
+ .listSessions()
110
+ .find((s) => s.launchId === launchId && s.context === 'edit');
111
+ return info ? connection.getSession(info.sessionId) : undefined;
112
+ };
113
+
114
+ const onSession = (): void => {
115
+ const session = findSession();
116
+ if (session) {
117
+ clearTimeout(timer);
118
+ connection.off('session-connected', onSession);
119
+ resolve(session);
120
+ }
121
+ };
122
+
123
+ const timer = setTimeout(() => {
124
+ connection.off('session-connected', onSession);
125
+ reject(
126
+ new Error(
127
+ `The launched Studio did not connect within ${timeoutMs}ms. Is the studio-bridge plugin installed?`
128
+ )
129
+ );
130
+ }, timeoutMs);
131
+
132
+ connection.on('session-connected', onSession);
133
+ onSession();
134
+ });
135
+ }
@@ -71,7 +71,7 @@ describe('resolveSessionAsync', () => {
71
71
  const conn = createMockConnection(sessions);
72
72
 
73
73
  await expect(resolveSessionAsync(conn)).rejects.toThrow(
74
- /Multiple sessions found.*--session.*--instance/s
74
+ /Multiple sessions found.*--target/s
75
75
  );
76
76
  });
77
77
 
@@ -61,6 +61,6 @@ export async function resolveSessionAsync(
61
61
  .join('\n');
62
62
 
63
63
  throw new Error(
64
- `Multiple sessions found. Use --session or --instance to select one:\n${listing}`
64
+ `Multiple sessions found. Use --target <id> to select one:\n${listing}`
65
65
  );
66
66
  }
@@ -14,8 +14,15 @@ import {
14
14
  } from '@quenty/cli-output-helpers/reporting';
15
15
  import {
16
16
  StudioBridgeServer,
17
+ type StudioBridgeResult,
17
18
  type StudioBridgePhase,
18
19
  } from '../server/studio-bridge-server.js';
20
+ import type {
21
+ OutputLevel,
22
+ SerializedReturnValue,
23
+ } from '../server/web-socket-protocol.js';
24
+ import { isPersistentPluginInstalled } from '../plugin/plugin-discovery.js';
25
+ import { runInManagedStudioAsync } from './managed-studio-run.js';
19
26
 
20
27
  export interface ExecuteScriptOptions {
21
28
  scriptContent: string;
@@ -25,6 +32,18 @@ export interface ExecuteScriptOptions {
25
32
  verbose: boolean;
26
33
  showLogs: boolean;
27
34
  filePath?: string;
35
+ /** Skip the progress reporter, for when stdout carries JSON. */
36
+ quiet?: boolean;
37
+ /** Passed to the script as `...`. */
38
+ args?: string[];
39
+ }
40
+
41
+ export interface ExecuteScriptResult {
42
+ success: boolean;
43
+ output: string[];
44
+ error?: string;
45
+ returnValues?: SerializedReturnValue[];
46
+ durationMs: number;
28
47
  }
29
48
 
30
49
  /**
@@ -52,7 +71,7 @@ export async function resolvePlacePathAsync(
52
71
  */
53
72
  export async function executeScriptAsync(
54
73
  options: ExecuteScriptOptions
55
- ): Promise<void> {
74
+ ): Promise<ExecuteScriptResult> {
56
75
  const { shouldDelegateToDockerAsync, delegateToDockerAsync } = await import(
57
76
  '../docker/docker-delegator.js'
58
77
  );
@@ -62,7 +81,7 @@ export async function executeScriptAsync(
62
81
  '[StudioBridge] No Wine detected, delegating to Docker'
63
82
  );
64
83
  await delegateToDockerAsync(options);
65
- return; // unreachable — delegateToDockerAsync calls process.exit
84
+ throw new Error('delegateToDockerAsync returned without exiting');
66
85
  }
67
86
 
68
87
  const {
@@ -72,9 +91,10 @@ export async function executeScriptAsync(
72
91
  timeoutMs,
73
92
  verbose,
74
93
  showLogs,
94
+ quiet = false,
75
95
  } = options;
76
96
 
77
- const useSpinner = !!process.stdout.isTTY && !verbose;
97
+ const useSpinner = !quiet && !!process.stdout.isTTY && !verbose;
78
98
 
79
99
  const reporter = new CompositeReporter(
80
100
  [packageName],
@@ -85,15 +105,17 @@ export async function executeScriptAsync(
85
105
  actionVerb: 'Running',
86
106
  })
87
107
  : new SimpleReporter(state, {
88
- alwaysShowLogs: showLogs,
108
+ alwaysShowLogs: false,
89
109
  successMessage: 'Script completed successfully.',
90
110
  failureMessage: 'Script failed.',
91
111
  }),
92
112
  ]
93
113
  );
94
114
 
95
- await reporter.startAsync();
96
- reporter.onPackageStart(packageName);
115
+ if (!quiet) {
116
+ await reporter.startAsync();
117
+ reporter.onPackageStart(packageName);
118
+ }
97
119
 
98
120
  const startTime = performance.now();
99
121
 
@@ -103,45 +125,63 @@ export async function executeScriptAsync(
103
125
  }
104
126
 
105
127
  const outputLines: string[] = [];
128
+ const onOutput = (level: OutputLevel, body: string): void => {
129
+ // Filter internal plugin messages that leak through LogService
130
+ if (body.startsWith('[StudioBridge]')) {
131
+ return;
132
+ }
133
+
134
+ // Collect output for the result logs
135
+ outputLines.push(body);
136
+
137
+ // In verbose/simple mode, print output in real-time
138
+ if (!useSpinner && !quiet) {
139
+ switch (level) {
140
+ case 'Warning':
141
+ OutputHelper.warn(body);
142
+ break;
143
+ case 'Error':
144
+ OutputHelper.error(body);
145
+ break;
146
+ default:
147
+ console.log(body);
148
+ break;
149
+ }
150
+ }
151
+ };
152
+ const onPhase = (phase: StudioBridgePhase): void => {
153
+ if (phase === 'done' || quiet) return;
154
+ reporter.onPackagePhaseChange(packageName, phase);
155
+ };
156
+
106
157
  let server: StudioBridgeServer | undefined;
107
- let result;
158
+ let result: StudioBridgeResult;
108
159
  try {
109
- server = new StudioBridgeServer({
110
- placePath,
111
- timeoutMs,
112
- onPhase: (phase: StudioBridgePhase) => {
113
- if (phase === 'done') return;
114
- reporter.onPackagePhaseChange(packageName, phase);
115
- },
116
- });
117
- await server.startAsync();
118
- result = await server.executeAsync({
119
- scriptContent,
120
- onOutput: (level, body) => {
121
- // Filter internal plugin messages that leak through LogService
122
- if (body.startsWith('[StudioBridge]')) {
123
- return;
124
- }
125
-
126
- // Collect output for the result logs
127
- outputLines.push(body);
128
-
129
- // In verbose/simple mode, print output in real-time
130
- if (!useSpinner) {
131
- switch (level) {
132
- case 'Warning':
133
- OutputHelper.warn(body);
134
- break;
135
- case 'Error':
136
- OutputHelper.error(body);
137
- break;
138
- default:
139
- console.log(body);
140
- break;
141
- }
142
- }
143
- },
144
- });
160
+ if (isPersistentPluginInstalled()) {
161
+ const execResult = await runInManagedStudioAsync({
162
+ scriptContent,
163
+ placePath,
164
+ timeoutMs,
165
+ onPhase,
166
+ args: options.args,
167
+ });
168
+ for (const entry of execResult.output) {
169
+ onOutput(entry.level, entry.body);
170
+ }
171
+ result = {
172
+ success: execResult.success,
173
+ logs: execResult.error ?? '',
174
+ returnValues: execResult.returnValues,
175
+ };
176
+ } else {
177
+ server = new StudioBridgeServer({ placePath, timeoutMs, onPhase });
178
+ await server.startAsync();
179
+ result = await server.executeAsync({
180
+ scriptContent,
181
+ onOutput,
182
+ args: options.args,
183
+ });
184
+ }
145
185
  } catch (error) {
146
186
  const errorMessage = error instanceof Error ? error.message : String(error);
147
187
  result = {
@@ -154,14 +194,22 @@ export async function executeScriptAsync(
154
194
 
155
195
  const elapsed = performance.now() - startTime;
156
196
 
157
- reporter.onPackageResult({
158
- packageName,
159
- success: result.success,
160
- logs: outputLines.length > 0 ? outputLines.join('\n') : result.logs,
161
- durationMs: elapsed,
162
- });
197
+ if (!quiet) {
198
+ reporter.onPackageResult({
199
+ packageName,
200
+ success: result.success,
201
+ logs: outputLines.length > 0 ? outputLines.join('\n') : result.logs,
202
+ durationMs: elapsed,
203
+ });
163
204
 
164
- await reporter.stopAsync();
205
+ await reporter.stopAsync();
206
+ }
165
207
 
166
- process.exit(result.success ? 0 : 1);
208
+ return {
209
+ success: result.success,
210
+ output: outputLines,
211
+ error: result.success || !result.logs ? undefined : result.logs,
212
+ returnValues: result.returnValues,
213
+ durationMs: elapsed,
214
+ };
167
215
  }