@quenty/studio-bridge 0.21.1 → 0.22.1
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.
- package/CHANGELOG.md +10 -0
- package/README.md +109 -17
- package/build-scripts/transform-add-session-attribute.lua +1 -0
- package/deploy.nevermore.json +10 -0
- package/dist/src/bridge/bridge-connection.d.ts +26 -2
- package/dist/src/bridge/bridge-connection.d.ts.map +1 -1
- package/dist/src/bridge/bridge-connection.js +159 -14
- package/dist/src/bridge/bridge-connection.js.map +1 -1
- package/dist/src/bridge/bridge-connection.test.js +81 -0
- package/dist/src/bridge/bridge-connection.test.js.map +1 -1
- package/dist/src/bridge/bridge-session.d.ts +35 -2
- package/dist/src/bridge/bridge-session.d.ts.map +1 -1
- package/dist/src/bridge/bridge-session.js +185 -28
- package/dist/src/bridge/bridge-session.js.map +1 -1
- package/dist/src/bridge/bridge-session.test.js +6 -4
- package/dist/src/bridge/bridge-session.test.js.map +1 -1
- package/dist/src/bridge/index.d.ts +1 -1
- package/dist/src/bridge/index.d.ts.map +1 -1
- package/dist/src/bridge/index.js.map +1 -1
- package/dist/src/bridge/internal/bridge-client.d.ts +4 -0
- package/dist/src/bridge/internal/bridge-client.d.ts.map +1 -1
- package/dist/src/bridge/internal/bridge-client.js +20 -7
- package/dist/src/bridge/internal/bridge-client.js.map +1 -1
- package/dist/src/bridge/internal/bridge-client.test.js +18 -0
- package/dist/src/bridge/internal/bridge-client.test.js.map +1 -1
- package/dist/src/bridge/internal/bridge-host.d.ts +13 -1
- package/dist/src/bridge/internal/bridge-host.d.ts.map +1 -1
- package/dist/src/bridge/internal/bridge-host.js +35 -0
- package/dist/src/bridge/internal/bridge-host.js.map +1 -1
- package/dist/src/bridge/internal/bridge-host.test.js +31 -0
- package/dist/src/bridge/internal/bridge-host.test.js.map +1 -1
- package/dist/src/bridge/internal/hand-off.d.ts.map +1 -1
- package/dist/src/bridge/internal/hand-off.js +4 -1
- package/dist/src/bridge/internal/hand-off.js.map +1 -1
- package/dist/src/bridge/internal/host-protocol.d.ts +8 -0
- package/dist/src/bridge/internal/host-protocol.d.ts.map +1 -1
- package/dist/src/bridge/internal/host-protocol.js +120 -13
- package/dist/src/bridge/internal/host-protocol.js.map +1 -1
- package/dist/src/bridge/internal/host-protocol.test.js +13 -0
- package/dist/src/bridge/internal/host-protocol.test.js.map +1 -1
- package/dist/src/bridge/internal/instance-state.d.ts +9 -0
- package/dist/src/bridge/internal/instance-state.d.ts.map +1 -0
- package/dist/src/bridge/internal/instance-state.js +28 -0
- package/dist/src/bridge/internal/instance-state.js.map +1 -0
- package/dist/src/bridge/internal/transport-client.d.ts.map +1 -1
- package/dist/src/bridge/internal/transport-client.js +2 -1
- package/dist/src/bridge/internal/transport-client.js.map +1 -1
- package/dist/src/bridge/internal/transport-server.d.ts.map +1 -1
- package/dist/src/bridge/internal/transport-server.js +5 -1
- package/dist/src/bridge/internal/transport-server.js.map +1 -1
- package/dist/src/bridge/types.d.ts +43 -4
- package/dist/src/bridge/types.d.ts.map +1 -1
- package/dist/src/bridge/types.js.map +1 -1
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.js +24 -0
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.js.map +1 -1
- package/dist/src/cli/adapters/cli-command-adapter.d.ts +6 -0
- package/dist/src/cli/adapters/cli-command-adapter.d.ts.map +1 -1
- package/dist/src/cli/adapters/cli-command-adapter.js +107 -11
- package/dist/src/cli/adapters/cli-command-adapter.js.map +1 -1
- package/dist/src/cli/adapters/group-builder.d.ts +3 -0
- package/dist/src/cli/adapters/group-builder.d.ts.map +1 -1
- package/dist/src/cli/adapters/group-builder.js +34 -15
- package/dist/src/cli/adapters/group-builder.js.map +1 -1
- package/dist/src/cli/adapters/group-builder.test.js +26 -2
- package/dist/src/cli/adapters/group-builder.test.js.map +1 -1
- package/dist/src/cli/adapters/help-formatter.d.ts.map +1 -1
- package/dist/src/cli/adapters/help-formatter.js +4 -3
- package/dist/src/cli/adapters/help-formatter.js.map +1 -1
- package/dist/src/cli/adapters/help-formatter.test.js +1 -1
- package/dist/src/cli/adapters/help-formatter.test.js.map +1 -1
- package/dist/src/cli/adapters/playtest-edit-guard.test.d.ts +2 -0
- package/dist/src/cli/adapters/playtest-edit-guard.test.d.ts.map +1 -0
- package/dist/src/cli/adapters/playtest-edit-guard.test.js +28 -0
- package/dist/src/cli/adapters/playtest-edit-guard.test.js.map +1 -0
- package/dist/src/cli/args/global-args.d.ts +1 -1
- package/dist/src/cli/args/global-args.d.ts.map +1 -1
- package/dist/src/cli/cli-output-context.d.ts +14 -0
- package/dist/src/cli/cli-output-context.d.ts.map +1 -0
- package/dist/src/cli/cli-output-context.js +39 -0
- package/dist/src/cli/cli-output-context.js.map +1 -0
- package/dist/src/cli/cli-output-context.test.d.ts +2 -0
- package/dist/src/cli/cli-output-context.test.d.ts.map +1 -0
- package/dist/src/cli/cli-output-context.test.js +38 -0
- package/dist/src/cli/cli-output-context.test.js.map +1 -0
- package/dist/src/cli/cli.js +40 -17
- package/dist/src/cli/cli.js.map +1 -1
- package/dist/src/cli/managed-studio-run.d.ts +21 -0
- package/dist/src/cli/managed-studio-run.d.ts.map +1 -0
- package/dist/src/cli/managed-studio-run.js +75 -0
- package/dist/src/cli/managed-studio-run.js.map +1 -0
- package/dist/src/cli/managed-studio-run.test.d.ts +2 -0
- package/dist/src/cli/managed-studio-run.test.d.ts.map +1 -0
- package/dist/src/cli/managed-studio-run.test.js +52 -0
- package/dist/src/cli/managed-studio-run.test.js.map +1 -0
- package/dist/src/cli/resolve-session.js +1 -1
- package/dist/src/cli/resolve-session.js.map +1 -1
- package/dist/src/cli/resolve-session.test.js +1 -1
- package/dist/src/cli/resolve-session.test.js.map +1 -1
- package/dist/src/cli/script-executor.d.ts +13 -1
- package/dist/src/cli/script-executor.d.ts.map +1 -1
- package/dist/src/cli/script-executor.js +77 -47
- package/dist/src/cli/script-executor.js.map +1 -1
- package/dist/src/commands/console/exec/exec.d.ts +17 -0
- package/dist/src/commands/console/exec/exec.d.ts.map +1 -1
- package/dist/src/commands/console/exec/exec.js +39 -7
- package/dist/src/commands/console/exec/exec.js.map +1 -1
- package/dist/src/commands/console/exec/exec.test.js +62 -3
- package/dist/src/commands/console/exec/exec.test.js.map +1 -1
- package/dist/src/commands/console/logs/logs.d.ts +30 -2
- package/dist/src/commands/console/logs/logs.d.ts.map +1 -1
- package/dist/src/commands/console/logs/logs.js +82 -7
- package/dist/src/commands/console/logs/logs.js.map +1 -1
- package/dist/src/commands/console/logs/logs.test.js +63 -4
- package/dist/src/commands/console/logs/logs.test.js.map +1 -1
- package/dist/src/commands/explorer/export/export.d.ts +19 -0
- package/dist/src/commands/explorer/export/export.d.ts.map +1 -0
- package/dist/src/commands/explorer/export/export.js +37 -0
- package/dist/src/commands/explorer/export/export.js.map +1 -0
- package/dist/src/commands/explorer/export/export.test.d.ts +2 -0
- package/dist/src/commands/explorer/export/export.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/export/export.test.js +25 -0
- package/dist/src/commands/explorer/export/export.test.js.map +1 -0
- package/dist/src/commands/explorer/find/find.d.ts +28 -0
- package/dist/src/commands/explorer/find/find.d.ts.map +1 -0
- package/dist/src/commands/explorer/find/find.js +75 -0
- package/dist/src/commands/explorer/find/find.js.map +1 -0
- package/dist/src/commands/explorer/find/find.test.d.ts +2 -0
- package/dist/src/commands/explorer/find/find.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/find/find.test.js +44 -0
- package/dist/src/commands/explorer/find/find.test.js.map +1 -0
- package/dist/src/commands/explorer/grep/grep.d.ts +24 -0
- package/dist/src/commands/explorer/grep/grep.d.ts.map +1 -0
- package/dist/src/commands/explorer/grep/grep.js +63 -0
- package/dist/src/commands/explorer/grep/grep.js.map +1 -0
- package/dist/src/commands/explorer/grep/grep.test.d.ts +2 -0
- package/dist/src/commands/explorer/grep/grep.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/grep/grep.test.js +42 -0
- package/dist/src/commands/explorer/grep/grep.test.js.map +1 -0
- package/dist/src/commands/explorer/import/import.d.ts +21 -0
- package/dist/src/commands/explorer/import/import.d.ts.map +1 -0
- package/dist/src/commands/explorer/import/import.js +37 -0
- package/dist/src/commands/explorer/import/import.js.map +1 -0
- package/dist/src/commands/explorer/import/import.test.d.ts +2 -0
- package/dist/src/commands/explorer/import/import.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/import/import.test.js +45 -0
- package/dist/src/commands/explorer/import/import.test.js.map +1 -0
- package/dist/src/commands/formatters.test.js +7 -1
- package/dist/src/commands/formatters.test.js.map +1 -1
- package/dist/src/commands/framework/action-loader.d.ts +5 -1
- package/dist/src/commands/framework/action-loader.d.ts.map +1 -1
- package/dist/src/commands/framework/action-loader.js +9 -2
- package/dist/src/commands/framework/action-loader.js.map +1 -1
- package/dist/src/commands/framework/action-loader.test.js +23 -0
- package/dist/src/commands/framework/action-loader.test.js.map +1 -1
- package/dist/src/commands/framework/arg-builder.d.ts +15 -2
- package/dist/src/commands/framework/arg-builder.d.ts.map +1 -1
- package/dist/src/commands/framework/arg-builder.js +22 -2
- package/dist/src/commands/framework/arg-builder.js.map +1 -1
- package/dist/src/commands/framework/define-command.d.ts +19 -3
- package/dist/src/commands/framework/define-command.d.ts.map +1 -1
- package/dist/src/commands/framework/define-command.js.map +1 -1
- package/dist/src/commands/framework/index.d.ts +1 -1
- package/dist/src/commands/framework/index.d.ts.map +1 -1
- package/dist/src/commands/framework/index.js.map +1 -1
- package/dist/src/commands/index.d.ts +11 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +11 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/linux/inject-credentials/inject-credentials.d.ts.map +1 -1
- package/dist/src/commands/linux/inject-credentials/inject-credentials.js +1 -3
- package/dist/src/commands/linux/inject-credentials/inject-credentials.js.map +1 -1
- package/dist/src/commands/linux/setup/setup.d.ts.map +1 -1
- package/dist/src/commands/linux/setup/setup.js +1 -3
- package/dist/src/commands/linux/setup/setup.js.map +1 -1
- package/dist/src/commands/linux/status/status.d.ts +9 -1
- package/dist/src/commands/linux/status/status.d.ts.map +1 -1
- package/dist/src/commands/linux/status/status.js +66 -86
- package/dist/src/commands/linux/status/status.js.map +1 -1
- package/dist/src/commands/playtest/player/add/add.d.ts +17 -0
- package/dist/src/commands/playtest/player/add/add.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/add/add.js +45 -0
- package/dist/src/commands/playtest/player/add/add.js.map +1 -0
- package/dist/src/commands/playtest/player/list/list.d.ts +13 -0
- package/dist/src/commands/playtest/player/list/list.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/list/list.js +33 -0
- package/dist/src/commands/playtest/player/list/list.js.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.d.ts +36 -0
- package/dist/src/commands/playtest/player/playtest-players.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.js +187 -0
- package/dist/src/commands/playtest/player/playtest-players.js.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.test.d.ts +2 -0
- package/dist/src/commands/playtest/player/playtest-players.test.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/playtest-players.test.js +89 -0
- package/dist/src/commands/playtest/player/playtest-players.test.js.map +1 -0
- package/dist/src/commands/playtest/player/remove/remove.d.ts +17 -0
- package/dist/src/commands/playtest/player/remove/remove.d.ts.map +1 -0
- package/dist/src/commands/playtest/player/remove/remove.js +42 -0
- package/dist/src/commands/playtest/player/remove/remove.js.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.d.ts +49 -0
- package/dist/src/commands/playtest/playtest-sessions.d.ts.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.js +283 -0
- package/dist/src/commands/playtest/playtest-sessions.js.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.test.d.ts +2 -0
- package/dist/src/commands/playtest/playtest-sessions.test.d.ts.map +1 -0
- package/dist/src/commands/playtest/playtest-sessions.test.js +87 -0
- package/dist/src/commands/playtest/playtest-sessions.test.js.map +1 -0
- package/dist/src/commands/playtest/restart/restart.d.ts +23 -0
- package/dist/src/commands/playtest/restart/restart.d.ts.map +1 -0
- package/dist/src/commands/playtest/restart/restart.js +105 -0
- package/dist/src/commands/playtest/restart/restart.js.map +1 -0
- package/dist/src/commands/playtest/run/run.d.ts +47 -0
- package/dist/src/commands/playtest/run/run.d.ts.map +1 -0
- package/dist/src/commands/playtest/run/run.js +137 -0
- package/dist/src/commands/playtest/run/run.js.map +1 -0
- package/dist/src/commands/playtest/start/start.d.ts +42 -0
- package/dist/src/commands/playtest/start/start.d.ts.map +1 -0
- package/dist/src/commands/playtest/start/start.js +70 -0
- package/dist/src/commands/playtest/start/start.js.map +1 -0
- package/dist/src/commands/playtest/stop/stop.d.ts +15 -0
- package/dist/src/commands/playtest/stop/stop.d.ts.map +1 -0
- package/dist/src/commands/playtest/stop/stop.js +24 -0
- package/dist/src/commands/playtest/stop/stop.js.map +1 -0
- package/dist/src/commands/process/close/close.d.ts +19 -10
- package/dist/src/commands/process/close/close.d.ts.map +1 -1
- package/dist/src/commands/process/close/close.js +118 -15
- package/dist/src/commands/process/close/close.js.map +1 -1
- package/dist/src/commands/process/close/close.test.d.ts +2 -0
- package/dist/src/commands/process/close/close.test.d.ts.map +1 -0
- package/dist/src/commands/process/close/close.test.js +190 -0
- package/dist/src/commands/process/close/close.test.js.map +1 -0
- package/dist/src/commands/process/info/info.d.ts +45 -5
- package/dist/src/commands/process/info/info.d.ts.map +1 -1
- package/dist/src/commands/process/info/info.js +117 -13
- package/dist/src/commands/process/info/info.js.map +1 -1
- package/dist/src/commands/process/info/info.test.js +140 -38
- package/dist/src/commands/process/info/info.test.js.map +1 -1
- package/dist/src/commands/process/launch/launch.d.ts +11 -1
- package/dist/src/commands/process/launch/launch.d.ts.map +1 -1
- package/dist/src/commands/process/launch/launch.js +37 -7
- package/dist/src/commands/process/launch/launch.js.map +1 -1
- package/dist/src/commands/process/launch/launch.test.js +99 -20
- package/dist/src/commands/process/launch/launch.test.js.map +1 -1
- package/dist/src/commands/process/list/list.d.ts +2 -1
- package/dist/src/commands/process/list/list.d.ts.map +1 -1
- package/dist/src/commands/process/list/list.js +9 -6
- package/dist/src/commands/process/list/list.js.map +1 -1
- package/dist/src/commands/process/list/list.test.js +1 -0
- package/dist/src/commands/process/list/list.test.js.map +1 -1
- package/dist/src/commands/process/run/run.d.ts +9 -0
- package/dist/src/commands/process/run/run.d.ts.map +1 -1
- package/dist/src/commands/process/run/run.js +15 -5
- package/dist/src/commands/process/run/run.js.map +1 -1
- package/dist/src/commands/serve/serve.d.ts +2 -0
- package/dist/src/commands/serve/serve.d.ts.map +1 -1
- package/dist/src/commands/serve/serve.js +17 -4
- package/dist/src/commands/serve/serve.js.map +1 -1
- package/dist/src/commands/serve/serve.test.js +9 -2
- package/dist/src/commands/serve/serve.test.js.map +1 -1
- package/dist/src/commands/viewport/screenshot/screenshot.d.ts.map +1 -1
- package/dist/src/commands/viewport/screenshot/screenshot.js +4 -1
- package/dist/src/commands/viewport/screenshot/screenshot.js.map +1 -1
- package/dist/src/commands/viewport/screenshot/screenshot.test.js +5 -9
- package/dist/src/commands/viewport/screenshot/screenshot.test.js.map +1 -1
- package/dist/src/deploy/deploy-places.d.ts +39 -0
- package/dist/src/deploy/deploy-places.d.ts.map +1 -0
- package/dist/src/deploy/deploy-places.js +162 -0
- package/dist/src/deploy/deploy-places.js.map +1 -0
- package/dist/src/deploy/deploy-places.test.d.ts +2 -0
- package/dist/src/deploy/deploy-places.test.d.ts.map +1 -0
- package/dist/src/deploy/deploy-places.test.js +96 -0
- package/dist/src/deploy/deploy-places.test.js.map +1 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/plugin/persistent-plugin-installer.d.ts.map +1 -1
- package/dist/src/plugin/persistent-plugin-installer.js +2 -1
- package/dist/src/plugin/persistent-plugin-installer.js.map +1 -1
- package/dist/src/plugin/persistent-plugin-installer.test.js +3 -0
- package/dist/src/plugin/persistent-plugin-installer.test.js.map +1 -1
- package/dist/src/plugin/plugin-build-version.d.ts +7 -0
- package/dist/src/plugin/plugin-build-version.d.ts.map +1 -0
- package/dist/src/plugin/plugin-build-version.js +42 -0
- package/dist/src/plugin/plugin-build-version.js.map +1 -0
- package/dist/src/plugin/plugin-build-version.test.d.ts +2 -0
- package/dist/src/plugin/plugin-build-version.test.d.ts.map +1 -0
- package/dist/src/plugin/plugin-build-version.test.js +41 -0
- package/dist/src/plugin/plugin-build-version.test.js.map +1 -0
- package/dist/src/plugin/plugin-injector.d.ts.map +1 -1
- package/dist/src/plugin/plugin-injector.js +7 -1
- package/dist/src/plugin/plugin-injector.js.map +1 -1
- package/dist/src/process/studio-process-closer.d.ts +35 -0
- package/dist/src/process/studio-process-closer.d.ts.map +1 -0
- package/dist/src/process/studio-process-closer.js +129 -0
- package/dist/src/process/studio-process-closer.js.map +1 -0
- package/dist/src/process/studio-process-closer.test.d.ts +2 -0
- package/dist/src/process/studio-process-closer.test.d.ts.map +1 -0
- package/dist/src/process/studio-process-closer.test.js +80 -0
- package/dist/src/process/studio-process-closer.test.js.map +1 -0
- package/dist/src/process/studio-settings.d.ts +14 -0
- package/dist/src/process/studio-settings.d.ts.map +1 -0
- package/dist/src/process/studio-settings.js +50 -0
- package/dist/src/process/studio-settings.js.map +1 -0
- package/dist/src/process/studio-settings.test.d.ts +2 -0
- package/dist/src/process/studio-settings.test.d.ts.map +1 -0
- package/dist/src/process/studio-settings.test.js +16 -0
- package/dist/src/process/studio-settings.test.js.map +1 -0
- package/dist/src/process/studio-window-state.d.ts +13 -0
- package/dist/src/process/studio-window-state.d.ts.map +1 -0
- package/dist/src/process/studio-window-state.js +48 -0
- package/dist/src/process/studio-window-state.js.map +1 -0
- package/dist/src/server/studio-bridge-server.d.ts +3 -1
- package/dist/src/server/studio-bridge-server.d.ts.map +1 -1
- package/dist/src/server/studio-bridge-server.js +12 -4
- package/dist/src/server/studio-bridge-server.js.map +1 -1
- package/dist/src/server/web-socket-protocol.d.ts +173 -6
- package/dist/src/server/web-socket-protocol.d.ts.map +1 -1
- package/dist/src/server/web-socket-protocol.js +244 -1
- package/dist/src/server/web-socket-protocol.js.map +1 -1
- package/dist/src/server/web-socket-protocol.test.js +48 -0
- package/dist/src/server/web-socket-protocol.test.js.map +1 -1
- package/dist/src/test/e2e/persistent-session.test.js +121 -0
- package/dist/src/test/e2e/persistent-session.test.js.map +1 -1
- package/dist/src/test/e2e/split-server.test.d.ts +3 -5
- package/dist/src/test/e2e/split-server.test.d.ts.map +1 -1
- package/dist/src/test/e2e/split-server.test.js +3 -5
- package/dist/src/test/e2e/split-server.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docker/Dockerfile +3 -0
- package/package.json +8 -6
- package/src/bridge/bridge-connection.test.ts +126 -0
- package/src/bridge/bridge-connection.ts +217 -22
- package/src/bridge/bridge-session.test.ts +6 -4
- package/src/bridge/bridge-session.ts +273 -28
- package/src/bridge/index.ts +3 -0
- package/src/bridge/internal/bridge-client.test.ts +23 -0
- package/src/bridge/internal/bridge-client.ts +25 -7
- package/src/bridge/internal/bridge-host.test.ts +38 -0
- package/src/bridge/internal/bridge-host.ts +47 -0
- package/src/bridge/internal/hand-off.ts +4 -1
- package/src/bridge/internal/host-protocol.test.ts +15 -0
- package/src/bridge/internal/host-protocol.ts +148 -37
- package/src/bridge/internal/instance-state.ts +34 -0
- package/src/bridge/internal/transport-client.ts +2 -1
- package/src/bridge/internal/transport-server.ts +5 -1
- package/src/bridge/types.ts +47 -2
- package/src/cli/adapters/cli-command-adapter-handler.test.ts +28 -0
- package/src/cli/adapters/cli-command-adapter.ts +150 -18
- package/src/cli/adapters/group-builder.test.ts +34 -2
- package/src/cli/adapters/group-builder.ts +52 -20
- package/src/cli/adapters/help-formatter.test.ts +1 -1
- package/src/cli/adapters/help-formatter.ts +4 -3
- package/src/cli/adapters/playtest-edit-guard.test.ts +54 -0
- package/src/cli/args/global-args.ts +1 -1
- package/src/cli/cli-output-context.test.ts +55 -0
- package/src/cli/cli-output-context.ts +50 -0
- package/src/cli/cli.ts +49 -17
- package/src/cli/managed-studio-run.test.ts +71 -0
- package/src/cli/managed-studio-run.ts +135 -0
- package/src/cli/resolve-session.test.ts +1 -1
- package/src/cli/resolve-session.ts +1 -1
- package/src/cli/script-executor.ts +99 -51
- package/src/commands/console/exec/exec.test.ts +96 -3
- package/src/commands/console/exec/exec.ts +59 -6
- package/src/commands/console/exec/execute.lua +356 -240
- package/src/commands/console/exec/execute.spec.lua +286 -0
- package/src/commands/console/logs/logs.test.ts +76 -4
- package/src/commands/console/logs/logs.ts +132 -17
- package/src/commands/console/logs/query-logs.lua +85 -52
- package/src/commands/console/logs/query-logs.spec.lua +132 -0
- package/src/commands/explorer/export/export-instances.lua +108 -0
- package/src/commands/explorer/export/export-instances.spec.lua +87 -0
- package/src/commands/explorer/export/export.test.ts +27 -0
- package/src/commands/explorer/export/export.ts +60 -0
- package/src/commands/explorer/find/find-instances.lua +174 -0
- package/src/commands/explorer/find/find-instances.spec.lua +122 -0
- package/src/commands/explorer/find/find.test.ts +53 -0
- package/src/commands/explorer/find/find.ts +113 -0
- package/src/commands/explorer/grep/grep-scripts.lua +214 -0
- package/src/commands/explorer/grep/grep-scripts.spec.lua +130 -0
- package/src/commands/explorer/grep/grep.test.ts +45 -0
- package/src/commands/explorer/grep/grep.ts +93 -0
- package/src/commands/explorer/import/import-instances.lua +106 -0
- package/src/commands/explorer/import/import-instances.spec.lua +84 -0
- package/src/commands/explorer/import/import.test.ts +60 -0
- package/src/commands/explorer/import/import.ts +66 -0
- package/src/commands/explorer/query/query-data-model.lua +124 -152
- package/src/commands/explorer/query/query-data-model.spec.lua +150 -0
- package/src/commands/formatters.test.ts +7 -1
- package/src/commands/framework/action-loader.test.ts +28 -0
- package/src/commands/framework/action-loader.ts +10 -2
- package/src/commands/framework/arg-builder.ts +26 -3
- package/src/commands/framework/define-command.ts +32 -3
- package/src/commands/framework/index.ts +1 -0
- package/src/commands/index.ts +50 -0
- package/src/commands/linux/inject-credentials/inject-credentials.ts +1 -3
- package/src/commands/linux/setup/setup.ts +1 -3
- package/src/commands/linux/status/status.ts +105 -98
- package/src/commands/playtest/player/add/add.ts +85 -0
- package/src/commands/playtest/player/list/list.ts +57 -0
- package/src/commands/playtest/player/playtest-players.test.ts +146 -0
- package/src/commands/playtest/player/playtest-players.ts +270 -0
- package/src/commands/playtest/player/remove/remove.ts +78 -0
- package/src/commands/playtest/playtest-sessions.test.ts +143 -0
- package/src/commands/playtest/playtest-sessions.ts +417 -0
- package/src/commands/playtest/restart/restart.ts +199 -0
- package/src/commands/playtest/run/playtest-runner.luau +264 -0
- package/src/commands/playtest/run/playtest-runner.spec.lua +71 -0
- package/src/commands/playtest/run/run-playtest-script.lua +139 -0
- package/src/commands/playtest/run/run-playtest-script.spec.lua +43 -0
- package/src/commands/playtest/run/run.ts +239 -0
- package/src/commands/playtest/start/start-playtest.lua +108 -0
- package/src/commands/playtest/start/start.ts +138 -0
- package/src/commands/playtest/stop/end-playtest.lua +47 -0
- package/src/commands/playtest/stop/stop.ts +51 -0
- package/src/commands/process/close/close.test.ts +250 -0
- package/src/commands/process/close/close.ts +183 -17
- package/src/commands/process/info/info.test.ts +198 -44
- package/src/commands/process/info/info.ts +204 -15
- package/src/commands/process/info/query-state.lua +42 -29
- package/src/commands/process/info/query-state.spec.lua +39 -0
- package/src/commands/process/launch/launch.test.ts +138 -21
- package/src/commands/process/launch/launch.ts +69 -9
- package/src/commands/process/list/list.test.ts +1 -0
- package/src/commands/process/list/list.ts +14 -6
- package/src/commands/process/run/run.ts +26 -5
- package/src/commands/serve/serve.test.ts +17 -2
- package/src/commands/serve/serve.ts +25 -6
- package/src/commands/viewport/screenshot/capture-screenshot.lua +175 -182
- package/src/commands/viewport/screenshot/capture-screenshot.spec.lua +129 -0
- package/src/commands/viewport/screenshot/screenshot.test.ts +7 -10
- package/src/commands/viewport/screenshot/screenshot.ts +6 -1
- package/src/deploy/deploy-places.test.ts +127 -0
- package/src/deploy/deploy-places.ts +229 -0
- package/src/index.ts +11 -0
- package/src/plugin/persistent-plugin-installer.test.ts +4 -0
- package/src/plugin/persistent-plugin-installer.ts +2 -1
- package/src/plugin/plugin-build-version.test.ts +55 -0
- package/src/plugin/plugin-build-version.ts +53 -0
- package/src/plugin/plugin-injector.ts +7 -1
- package/src/process/studio-process-closer.test.ts +107 -0
- package/src/process/studio-process-closer.ts +187 -0
- package/src/process/studio-settings.test.ts +18 -0
- package/src/process/studio-settings.ts +61 -0
- package/src/process/studio-window-state.ts +65 -0
- package/src/server/studio-bridge-server.ts +15 -4
- package/src/server/web-socket-protocol.test.ts +55 -0
- package/src/server/web-socket-protocol.ts +468 -8
- package/src/test/e2e/persistent-session.test.ts +137 -0
- package/src/test/e2e/split-server.test.ts +3 -5
- package/templates/studio-bridge-plugin/default.project.json +3 -0
- package/templates/studio-bridge-plugin/src/Shared/ActionRouter.lua +208 -159
- package/templates/studio-bridge-plugin/src/Shared/ActionRouter.spec.lua +418 -0
- package/templates/studio-bridge-plugin/src/Shared/BuiltInActions.lua +94 -0
- package/templates/studio-bridge-plugin/src/Shared/BuiltInActions.spec.lua +166 -0
- package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.lua +118 -137
- package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.spec.lua +228 -0
- package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.lua +80 -109
- package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.spec.lua +116 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeConnection.lua +233 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeConnection.spec.lua +239 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeLogUtils.lua +53 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeLogUtils.spec.lua +27 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeSessionUtils.lua +164 -0
- package/templates/studio-bridge-plugin/src/Shared/StudioBridgeSessionUtils.spec.lua +159 -0
- package/templates/studio-bridge-plugin/src/StudioBridgePlugin.server.lua +266 -368
- package/templates/studio-bridge-plugin/src/Vendor/png.lua +8 -2
- package/test/default.project.json +41 -0
- package/test/jest.config.lua +3 -0
- package/test/scripts/Server/ServerMain.server.lua +10 -0
- package/tsconfig.json +1 -0
- package/templates/studio-bridge-plugin/src/Shared/Protocol.lua +0 -132
- package/templates/studio-bridge-plugin-test/test/actions.test.lua +0 -580
- package/templates/studio-bridge-plugin-test/test/discovery.test.lua +0 -622
- package/templates/studio-bridge-plugin-test/test/execute-handler.test.lua +0 -517
- package/templates/studio-bridge-plugin-test/test/hash-lifecycle.test.lua +0 -814
- package/templates/studio-bridge-plugin-test/test/integration.test.lua +0 -1020
- package/templates/studio-bridge-plugin-test/test/new-actions.test.lua +0 -339
- package/templates/studio-bridge-plugin-test/test/plugin-entry.test.lua +0 -493
- package/templates/studio-bridge-plugin-test/test/protocol.test.lua +0 -506
- package/templates/studio-bridge-plugin-test/test/roblox-mocks.lua +0 -108
- package/templates/studio-bridge-plugin-test/test/test-runner.lua +0 -112
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds running Roblox Studio processes and closes them. The plugin API has
|
|
3
|
+
* no process id, so a bridge session is matched to its process by the place
|
|
4
|
+
* name Studio shows in the window title, or by the place id a cloud place was
|
|
5
|
+
* launched with.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execa } from 'execa';
|
|
9
|
+
|
|
10
|
+
const WINDOW_TITLE_SUFFIX = ' - Roblox Studio';
|
|
11
|
+
const EXIT_POLL_INTERVAL_MS = 250;
|
|
12
|
+
|
|
13
|
+
export interface RunningStudioProcess {
|
|
14
|
+
pid: number;
|
|
15
|
+
windowTitle: string;
|
|
16
|
+
commandLine?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface CloseStudioOptions {
|
|
20
|
+
force?: boolean;
|
|
21
|
+
exitTimeoutMs?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function listStudioProcessesAsync(): Promise<
|
|
25
|
+
RunningStudioProcess[]
|
|
26
|
+
> {
|
|
27
|
+
if (process.platform === 'win32') {
|
|
28
|
+
const { stdout } = await execa(
|
|
29
|
+
'powershell.exe',
|
|
30
|
+
[
|
|
31
|
+
'-NoProfile',
|
|
32
|
+
'-NonInteractive',
|
|
33
|
+
'-Command',
|
|
34
|
+
'@(Get-CimInstance Win32_Process -Filter "Name=\'RobloxStudioBeta.exe\'" | ForEach-Object { [pscustomobject]@{ Id = $_.ProcessId; MainWindowTitle = (Get-Process -Id $_.ProcessId -ErrorAction SilentlyContinue).MainWindowTitle; CommandLine = $_.CommandLine } }) | ConvertTo-Json -Compress',
|
|
35
|
+
],
|
|
36
|
+
{ reject: false }
|
|
37
|
+
);
|
|
38
|
+
return parseWindowsProcessList(stdout);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (process.platform === 'darwin') {
|
|
42
|
+
const { stdout } = await execa('ps', ['-axo', 'pid=,command='], {
|
|
43
|
+
reject: false,
|
|
44
|
+
});
|
|
45
|
+
return parseMacProcessList(stdout);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
throw new Error(`Closing Studio is not supported on ${process.platform}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function parseWindowsProcessList(
|
|
52
|
+
stdout: string
|
|
53
|
+
): RunningStudioProcess[] {
|
|
54
|
+
const trimmed = stdout.trim();
|
|
55
|
+
if (!trimmed) return [];
|
|
56
|
+
|
|
57
|
+
type Entry = {
|
|
58
|
+
Id: number;
|
|
59
|
+
MainWindowTitle: string | null;
|
|
60
|
+
CommandLine?: string | null;
|
|
61
|
+
};
|
|
62
|
+
const parsed = JSON.parse(trimmed) as Entry | Entry[];
|
|
63
|
+
const entries = Array.isArray(parsed) ? parsed : [parsed];
|
|
64
|
+
|
|
65
|
+
return entries.map((entry) => ({
|
|
66
|
+
pid: entry.Id,
|
|
67
|
+
windowTitle: entry.MainWindowTitle ?? '',
|
|
68
|
+
commandLine: entry.CommandLine ?? undefined,
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function parseMacProcessList(stdout: string): RunningStudioProcess[] {
|
|
73
|
+
const processes: RunningStudioProcess[] = [];
|
|
74
|
+
for (const line of stdout.split('\n')) {
|
|
75
|
+
const match =
|
|
76
|
+
/^\s*(\d+)\s+(.*RobloxStudio\.app\/Contents\/MacOS\/RobloxStudio.*)$/.exec(
|
|
77
|
+
line
|
|
78
|
+
);
|
|
79
|
+
if (match) {
|
|
80
|
+
processes.push({
|
|
81
|
+
pid: Number(match[1]),
|
|
82
|
+
windowTitle: match[2],
|
|
83
|
+
commandLine: match[2],
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return processes;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Processes whose window shows the given place. Studio titles a local file
|
|
92
|
+
* by its full path and a cloud place by its name on the website, which the
|
|
93
|
+
* plugin can't see, so with no title match a cloud place is found by the
|
|
94
|
+
* `placeId` Studio was launched with.
|
|
95
|
+
*/
|
|
96
|
+
export function matchStudioProcesses(
|
|
97
|
+
processes: RunningStudioProcess[],
|
|
98
|
+
placeName: string,
|
|
99
|
+
placeId?: number
|
|
100
|
+
): RunningStudioProcess[] {
|
|
101
|
+
const byTitle = processes.filter((proc) => {
|
|
102
|
+
const title = proc.windowTitle.endsWith(WINDOW_TITLE_SUFFIX)
|
|
103
|
+
? proc.windowTitle.slice(0, -WINDOW_TITLE_SUFFIX.length)
|
|
104
|
+
: proc.windowTitle;
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
title === placeName ||
|
|
108
|
+
title.endsWith(`\\${placeName}`) ||
|
|
109
|
+
title.endsWith(`/${placeName}`)
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
if (byTitle.length > 0 || !placeId) {
|
|
113
|
+
return byTitle;
|
|
114
|
+
}
|
|
115
|
+
return matchStudioProcessesByPlaceId(processes, placeId);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Processes Studio launched with `placeId`, as `process launch` and the website's "Edit in Studio" do. */
|
|
119
|
+
export function matchStudioProcessesByPlaceId(
|
|
120
|
+
processes: RunningStudioProcess[],
|
|
121
|
+
placeId: number
|
|
122
|
+
): RunningStudioProcess[] {
|
|
123
|
+
const launchedPlaceId = new RegExp(`placeId:${placeId}(\\D|$)`);
|
|
124
|
+
return processes.filter(
|
|
125
|
+
(proc) => proc.commandLine && launchedPlaceId.test(proc.commandLine)
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Close a Studio process. Without `force` Studio is asked to close its
|
|
131
|
+
* window, which it can refuse by prompting to save. Resolves whether the
|
|
132
|
+
* process exited within the timeout.
|
|
133
|
+
*/
|
|
134
|
+
export async function closeStudioProcessAsync(
|
|
135
|
+
pid: number,
|
|
136
|
+
options: CloseStudioOptions = {}
|
|
137
|
+
): Promise<boolean> {
|
|
138
|
+
const { force = false, exitTimeoutMs = 10_000 } = options;
|
|
139
|
+
|
|
140
|
+
if (process.platform === 'win32') {
|
|
141
|
+
if (force) {
|
|
142
|
+
await execa('taskkill', ['/F', '/T', '/PID', String(pid)], {
|
|
143
|
+
reject: false,
|
|
144
|
+
});
|
|
145
|
+
} else {
|
|
146
|
+
await execa(
|
|
147
|
+
'powershell.exe',
|
|
148
|
+
[
|
|
149
|
+
'-NoProfile',
|
|
150
|
+
'-NonInteractive',
|
|
151
|
+
'-Command',
|
|
152
|
+
`(Get-Process -Id ${pid} -ErrorAction SilentlyContinue).CloseMainWindow() | Out-Null`,
|
|
153
|
+
],
|
|
154
|
+
{ reject: false }
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
try {
|
|
159
|
+
process.kill(pid, force ? 'SIGKILL' : 'SIGTERM');
|
|
160
|
+
} catch {
|
|
161
|
+
return !isProcessRunning(pid);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return waitForExitAsync(pid, exitTimeoutMs);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function isProcessRunning(pid: number): boolean {
|
|
169
|
+
try {
|
|
170
|
+
process.kill(pid, 0);
|
|
171
|
+
return true;
|
|
172
|
+
} catch (err) {
|
|
173
|
+
return (err as NodeJS.ErrnoException).code === 'EPERM';
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function waitForExitAsync(
|
|
178
|
+
pid: number,
|
|
179
|
+
timeoutMs: number
|
|
180
|
+
): Promise<boolean> {
|
|
181
|
+
const deadline = Date.now() + timeoutMs;
|
|
182
|
+
while (Date.now() < deadline) {
|
|
183
|
+
if (!isProcessRunning(pid)) return true;
|
|
184
|
+
await new Promise((resolve) => setTimeout(resolve, EXIT_POLL_INTERVAL_MS));
|
|
185
|
+
}
|
|
186
|
+
return !isProcessRunning(pid);
|
|
187
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { parseBoolSetting } from './studio-settings.js';
|
|
3
|
+
|
|
4
|
+
describe('parseBoolSetting', () => {
|
|
5
|
+
const xml = `<Item class="UserSettings"><Properties>
|
|
6
|
+
<bool name="LoadAllBuiltinPluginsInRunModes">true</bool>
|
|
7
|
+
<bool name="LoadUserPluginsInRunModes">false</bool>
|
|
8
|
+
</Properties></Item>`;
|
|
9
|
+
|
|
10
|
+
it('reads the named setting, not one whose name contains it', () => {
|
|
11
|
+
expect(parseBoolSetting(xml, 'LoadUserPluginsInRunModes')).toBe(false);
|
|
12
|
+
expect(parseBoolSetting(xml, 'LoadAllBuiltinPluginsInRunModes')).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('is undefined for a setting the file does not have', () => {
|
|
16
|
+
expect(parseBoolSetting(xml, 'Missing')).toBeUndefined();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads Studio's own settings from the file it saves them to, for settings a
|
|
3
|
+
* plugin can't read.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as fs from 'fs/promises';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { findPluginsFolder } from './studio-process-manager.js';
|
|
9
|
+
|
|
10
|
+
/** The XML name of Studio's "Load user plugins on playtest" setting. */
|
|
11
|
+
const LOAD_USER_PLUGINS_ON_PLAYTEST = 'LoadUserPluginsInRunModes';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Whether Studio's "Load user plugins on playtest" setting is on. Without it,
|
|
15
|
+
* the plugin doesn't load into a playtest's DataModels, so they never connect
|
|
16
|
+
* to the bridge. Undefined when the setting can't be read, e.g. on macOS,
|
|
17
|
+
* whose settings file isn't located here.
|
|
18
|
+
*/
|
|
19
|
+
export async function tryReadLoadUserPluginsOnPlaytestAsync(): Promise<
|
|
20
|
+
boolean | undefined
|
|
21
|
+
> {
|
|
22
|
+
const settingsPath = findGlobalSettingsPath();
|
|
23
|
+
if (!settingsPath) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let xml: string;
|
|
28
|
+
try {
|
|
29
|
+
xml = await fs.readFile(settingsPath, 'utf8');
|
|
30
|
+
} catch {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return parseBoolSetting(xml, LOAD_USER_PLUGINS_ON_PLAYTEST);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Reads `<bool name="...">true|false</bool>` from a Studio settings file. */
|
|
37
|
+
export function parseBoolSetting(
|
|
38
|
+
xml: string,
|
|
39
|
+
name: string
|
|
40
|
+
): boolean | undefined {
|
|
41
|
+
const match = new RegExp(
|
|
42
|
+
`<bool name="${name}">\\s*(true|false)\\s*</bool>`
|
|
43
|
+
).exec(xml);
|
|
44
|
+
return match ? match[1] === 'true' : undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Studio keeps its settings beside the plugins folder on Windows and under Wine. */
|
|
48
|
+
function findGlobalSettingsPath(): string | undefined {
|
|
49
|
+
if (process.platform !== 'win32' && process.platform !== 'linux') {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const robloxDir =
|
|
54
|
+
process.platform === 'linux'
|
|
55
|
+
? path.posix.dirname(findPluginsFolder())
|
|
56
|
+
: path.dirname(findPluginsFolder());
|
|
57
|
+
return path.join(robloxDir, 'GlobalSettings_13.xml');
|
|
58
|
+
} catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads whether a Studio window is focused or minimized. The plugin API
|
|
3
|
+
* cannot see either, so this asks the OS about the process the session's
|
|
4
|
+
* place is showing in.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { execa } from 'execa';
|
|
8
|
+
|
|
9
|
+
export interface StudioWindowState {
|
|
10
|
+
focused: boolean;
|
|
11
|
+
minimized: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const WINDOW_STATE_SCRIPT = `
|
|
15
|
+
Add-Type -Namespace StudioBridge -Name User32 -MemberDefinition @'
|
|
16
|
+
[DllImport("user32.dll")] public static extern bool IsIconic(IntPtr hWnd);
|
|
17
|
+
[DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
|
|
18
|
+
[DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
|
|
19
|
+
'@
|
|
20
|
+
$process = Get-Process -Id $args[0] -ErrorAction Stop
|
|
21
|
+
$foregroundPid = [uint32]0
|
|
22
|
+
[void][StudioBridge.User32]::GetWindowThreadProcessId([StudioBridge.User32]::GetForegroundWindow(), [ref]$foregroundPid)
|
|
23
|
+
@{
|
|
24
|
+
minimized = [StudioBridge.User32]::IsIconic($process.MainWindowHandle)
|
|
25
|
+
focused = ($foregroundPid -eq $process.Id)
|
|
26
|
+
} | ConvertTo-Json -Compress
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
/** Undefined where the OS gives no answer, including outside Windows. */
|
|
30
|
+
export async function tryGetStudioWindowStateAsync(
|
|
31
|
+
pid: number
|
|
32
|
+
): Promise<StudioWindowState | undefined> {
|
|
33
|
+
if (process.platform !== 'win32') return undefined;
|
|
34
|
+
|
|
35
|
+
const { stdout, failed } = await execa(
|
|
36
|
+
'powershell.exe',
|
|
37
|
+
[
|
|
38
|
+
'-NoProfile',
|
|
39
|
+
'-NonInteractive',
|
|
40
|
+
'-Command',
|
|
41
|
+
`& { ${WINDOW_STATE_SCRIPT} } ${pid}`,
|
|
42
|
+
],
|
|
43
|
+
{ reject: false }
|
|
44
|
+
);
|
|
45
|
+
if (failed) return undefined;
|
|
46
|
+
|
|
47
|
+
return parseWindowState(stdout);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function parseWindowState(
|
|
51
|
+
stdout: string
|
|
52
|
+
): StudioWindowState | undefined {
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(stdout.trim()) as Partial<StudioWindowState>;
|
|
55
|
+
if (
|
|
56
|
+
typeof parsed.focused !== 'boolean' ||
|
|
57
|
+
typeof parsed.minimized !== 'boolean'
|
|
58
|
+
) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
return { focused: parsed.focused, minimized: parsed.minimized };
|
|
62
|
+
} catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
type SerializedReturnValue,
|
|
30
30
|
encodeMessage,
|
|
31
31
|
decodePluginMessage,
|
|
32
|
+
MAX_MESSAGE_BYTES,
|
|
32
33
|
} from './web-socket-protocol.js';
|
|
33
34
|
import { ActionDispatcher } from './action-dispatcher.js';
|
|
34
35
|
import {
|
|
@@ -102,6 +103,8 @@ export interface ExecuteOptions {
|
|
|
102
103
|
timeoutMs?: number;
|
|
103
104
|
/** Callback for each output message */
|
|
104
105
|
onOutput?: (level: OutputLevel, body: string) => void;
|
|
106
|
+
/** Passed to the script as `...`. */
|
|
107
|
+
args?: string[];
|
|
105
108
|
}
|
|
106
109
|
|
|
107
110
|
export interface StudioBridgeResult {
|
|
@@ -110,7 +113,7 @@ export interface StudioBridgeResult {
|
|
|
110
113
|
/**
|
|
111
114
|
* Everything the script returned, in order, marshalled by the plugin.
|
|
112
115
|
* Absent whenever no `scriptComplete` carrying a return channel arrived —
|
|
113
|
-
* a timeout, a disconnect, a plugin error
|
|
116
|
+
* a timeout, a disconnect, or a plugin error — which
|
|
114
117
|
* is what separates "we never learned what it returned" from `[]`, "it
|
|
115
118
|
* returned nothing".
|
|
116
119
|
*/
|
|
@@ -320,7 +323,10 @@ export class StudioBridgeServer {
|
|
|
320
323
|
|
|
321
324
|
// 1. Start HTTP + WebSocket server (unique path rejects wrong connections at upgrade level)
|
|
322
325
|
this._httpServer = http.createServer();
|
|
323
|
-
this._wss = new WebSocketServer({
|
|
326
|
+
this._wss = new WebSocketServer({
|
|
327
|
+
noServer: true,
|
|
328
|
+
maxPayload: MAX_MESSAGE_BYTES,
|
|
329
|
+
});
|
|
324
330
|
const port = await startHttpAndWsServerAsync(
|
|
325
331
|
this._httpServer,
|
|
326
332
|
this._wss,
|
|
@@ -402,7 +408,12 @@ export class StudioBridgeServer {
|
|
|
402
408
|
encodeMessage({
|
|
403
409
|
type: 'execute',
|
|
404
410
|
sessionId: this._sessionId,
|
|
405
|
-
payload: {
|
|
411
|
+
payload: {
|
|
412
|
+
script: options.scriptContent,
|
|
413
|
+
...(options.args && options.args.length > 0
|
|
414
|
+
? { args: options.args }
|
|
415
|
+
: {}),
|
|
416
|
+
},
|
|
406
417
|
})
|
|
407
418
|
);
|
|
408
419
|
|
|
@@ -482,7 +493,7 @@ export class StudioBridgeServer {
|
|
|
482
493
|
const syncResult = await this.performActionAsync<PluginMessage>(
|
|
483
494
|
{
|
|
484
495
|
type: 'syncActions',
|
|
485
|
-
payload: { actions },
|
|
496
|
+
payload: { actions, verbose: OutputHelper.isVerbose() },
|
|
486
497
|
},
|
|
487
498
|
10_000
|
|
488
499
|
);
|
|
@@ -325,6 +325,39 @@ describe('decodePluginMessage', () => {
|
|
|
325
325
|
});
|
|
326
326
|
});
|
|
327
327
|
|
|
328
|
+
describe('exportInstancesResult / importInstancesResult', () => {
|
|
329
|
+
it('decodes an exported model', () => {
|
|
330
|
+
const msg = {
|
|
331
|
+
type: 'exportInstancesResult',
|
|
332
|
+
sessionId: 'sess-1',
|
|
333
|
+
requestId: 'req-1',
|
|
334
|
+
payload: { data: 'PHJvYmxveCE=', paths: ['Workspace.Map'] },
|
|
335
|
+
};
|
|
336
|
+
expect(roundTripPlugin(msg)).toEqual(msg);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it('rejects an export without data', () => {
|
|
340
|
+
expect(
|
|
341
|
+
roundTripPlugin({
|
|
342
|
+
type: 'exportInstancesResult',
|
|
343
|
+
sessionId: 'sess-1',
|
|
344
|
+
requestId: 'req-1',
|
|
345
|
+
payload: { paths: ['Workspace.Map'] },
|
|
346
|
+
})
|
|
347
|
+
).toBeNull();
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it('decodes the imported paths', () => {
|
|
351
|
+
const msg = {
|
|
352
|
+
type: 'importInstancesResult',
|
|
353
|
+
sessionId: 'sess-1',
|
|
354
|
+
requestId: 'req-1',
|
|
355
|
+
payload: { paths: ['Workspace.Map'] },
|
|
356
|
+
};
|
|
357
|
+
expect(roundTripPlugin(msg)).toEqual(msg);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
|
|
328
361
|
describe('logsResult', () => {
|
|
329
362
|
it('decodes a valid logsResult', () => {
|
|
330
363
|
const msg = roundTripPlugin({
|
|
@@ -660,6 +693,28 @@ describe('encodeMessage / decodeServerMessage', () => {
|
|
|
660
693
|
});
|
|
661
694
|
});
|
|
662
695
|
|
|
696
|
+
describe('exportInstances / importInstances', () => {
|
|
697
|
+
it('round-trips exportInstances', () => {
|
|
698
|
+
const msg: ServerMessage = {
|
|
699
|
+
type: 'exportInstances',
|
|
700
|
+
sessionId: 'sess-1',
|
|
701
|
+
requestId: 'req-1',
|
|
702
|
+
payload: { paths: ['Workspace.Map', 'Lighting'] },
|
|
703
|
+
};
|
|
704
|
+
expect(roundTripServer(msg)).toEqual(msg);
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
it('round-trips importInstances', () => {
|
|
708
|
+
const msg: ServerMessage = {
|
|
709
|
+
type: 'importInstances',
|
|
710
|
+
sessionId: 'sess-1',
|
|
711
|
+
requestId: 'req-1',
|
|
712
|
+
payload: { data: 'PHJvYmxveCE=', parentPath: 'Workspace' },
|
|
713
|
+
};
|
|
714
|
+
expect(roundTripServer(msg)).toEqual(msg);
|
|
715
|
+
});
|
|
716
|
+
});
|
|
717
|
+
|
|
663
718
|
describe('queryLogs', () => {
|
|
664
719
|
it('round-trips queryLogs with all options', () => {
|
|
665
720
|
const msg: ServerMessage = {
|