@velor/remote-mouse 6.4.8

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 (316) hide show
  1. package/.artifacts/screenshots/remote-mobile-config.png +0 -0
  2. package/.artifacts/screenshots/remote-mobile-home.png +0 -0
  3. package/.artifacts/screenshots/remote-mobile-preferences.png +0 -0
  4. package/.artifacts/screenshots/remote-mobile-server-info.png +0 -0
  5. package/.artifacts/screenshots/remote-mobile-vlc.png +0 -0
  6. package/.env.example +93 -0
  7. package/README.md +370 -0
  8. package/bin/remote-mouse.js +19 -0
  9. package/client/core/dom.js +148 -0
  10. package/client/core/init-socket-io.js +117 -0
  11. package/client/core/socket-emit.js +6 -0
  12. package/client/core/window-events.js +23 -0
  13. package/client/i18n/apply-page-translations.js +18 -0
  14. package/client/i18n/constants.js +3 -0
  15. package/client/i18n/core.js +40 -0
  16. package/client/i18n/locale-registry.js +77 -0
  17. package/client/i18n/locales/de.js +227 -0
  18. package/client/i18n/locales/en.js +389 -0
  19. package/client/i18n/locales/es.js +228 -0
  20. package/client/i18n/locales/fr.js +389 -0
  21. package/client/i18n/locales/it.js +227 -0
  22. package/client/i18n/locales/ja.js +227 -0
  23. package/client/i18n/locales/pt.js +227 -0
  24. package/client/i18n/locales/ru.js +240 -0
  25. package/client/i18n/locales/zh.js +227 -0
  26. package/client/preferences/constants.js +15 -0
  27. package/client/preferences/effects.js +24 -0
  28. package/client/preferences/load.js +19 -0
  29. package/client/preferences/render.js +26 -0
  30. package/client/preferences/rows.js +78 -0
  31. package/client/preferences/state.js +29 -0
  32. package/client/preview/create-preview-frame-receiver.js +13 -0
  33. package/client/preview/draw.js +77 -0
  34. package/client/preview/parse-preview-frame.js +39 -0
  35. package/client/preview/preview-stream.js +152 -0
  36. package/client/services/app-state/appStateKeys.js +30 -0
  37. package/client/services/app-state/createAppStateService.js +216 -0
  38. package/client/services/app-state/createPersistStoreService.js +122 -0
  39. package/client/services/app-state/createStateStoreService.js +64 -0
  40. package/client/services/app-state/localStorageBinding.js +26 -0
  41. package/client/services/app-state/normalizers.js +74 -0
  42. package/client/services/app-state/resolveEffectiveStateValue.js +58 -0
  43. package/client/services/app-state/stateDefinitions.js +107 -0
  44. package/client/services/backend/createBackendService.js +55 -0
  45. package/client/services/config/ConfigView.js +45 -0
  46. package/client/services/config/createClientConfigService.js +122 -0
  47. package/client/services/config/defaultClientConfig.js +22 -0
  48. package/client/services/createServicesContainer.js +48 -0
  49. package/client/services/createServicesRegistry.js +26 -0
  50. package/client/services/i18n/createI18nService.js +86 -0
  51. package/client/services/notifications/createNotificationService.js +56 -0
  52. package/client/services/pubsub/createPubSubService.js +20 -0
  53. package/client/services/remotes/createRemotesService.js +20 -0
  54. package/client/services/transport/createSocketIoTransportService.js +50 -0
  55. package/client/touch/bindTouchPassthrough.js +94 -0
  56. package/client/touch/createTouchList.js +18 -0
  57. package/client/touch/dispatchSyntheticTouch.js +20 -0
  58. package/client/touch/gesture-zone.js +28 -0
  59. package/client/touch/throttle.js +46 -0
  60. package/client/touch/touch-handlers.js +193 -0
  61. package/client/touch/touchpad.js +231 -0
  62. package/client/ui/config/page.js +840 -0
  63. package/client/ui/main/applyRemoteVisibilityState.js +60 -0
  64. package/client/ui/main/bind-client-notifications.js +3 -0
  65. package/client/ui/main/bindings/bindAccordion.js +121 -0
  66. package/client/ui/main/bindings/bindActionButtons.js +13 -0
  67. package/client/ui/main/bindings/bindAdminDrawer.js +137 -0
  68. package/client/ui/main/bindings/bindAdminRemoteButtons.js +77 -0
  69. package/client/ui/main/bindings/bindAdminVersion.js +27 -0
  70. package/client/ui/main/bindings/bindBrowserRemoteButtons.js +119 -0
  71. package/client/ui/main/bindings/bindRemoteAccordion.js +23 -0
  72. package/client/ui/main/bindings/bindSamsungRemoteButtons.js +320 -0
  73. package/client/ui/main/bindings/bindSystemRemoteButtons.js +41 -0
  74. package/client/ui/main/bindings/bindVlcRemoteButtons.js +64 -0
  75. package/client/ui/main/canvas-ui.js +33 -0
  76. package/client/ui/main/connection-overlay.js +57 -0
  77. package/client/ui/main/init-ui.js +54 -0
  78. package/client/ui/main/keyboard-panel.js +271 -0
  79. package/client/ui/main/mouse-buttons.js +94 -0
  80. package/client/ui/main/page.js +21 -0
  81. package/client/ui/notifications/show-toast.js +48 -0
  82. package/client/ui/preferences/bindPreferenceSwitchers.js +49 -0
  83. package/client/ui/preferences/page.js +61 -0
  84. package/client/ui/preferences/switchers.js +200 -0
  85. package/index.js +9 -0
  86. package/package.json +41 -0
  87. package/public/admin-config.css +447 -0
  88. package/public/admin-config.html +63 -0
  89. package/public/apple-touch-icon.png +0 -0
  90. package/public/brave-icon.svg +13 -0
  91. package/public/favicon.svg +30 -0
  92. package/public/icon-192.png +0 -0
  93. package/public/icon-512.png +0 -0
  94. package/public/index.html +246 -0
  95. package/public/manifest.webmanifest +45 -0
  96. package/public/preferences.html +55 -0
  97. package/public/server-info.html +574 -0
  98. package/public/styles.css +1042 -0
  99. package/public/sw.js +103 -0
  100. package/scripts/codex-commit.sh +112 -0
  101. package/scripts/generate-mobile-screenshots.mjs +244 -0
  102. package/scripts/install-linux.sh +633 -0
  103. package/scripts/install-windows.ps1 +369 -0
  104. package/server/application/createApplicationLifecycle.js +15 -0
  105. package/server/application/logger.js +216 -0
  106. package/server/application/shutdown.js +81 -0
  107. package/server/application/start.js +95 -0
  108. package/server/application/state.js +19 -0
  109. package/server/connection/api/admin-actions.router.js +65 -0
  110. package/server/connection/api/admin-configs.router.js +165 -0
  111. package/server/connection/api/admin-remotes.router.js +61 -0
  112. package/server/connection/api/admin-subs.router.js +49 -0
  113. package/server/connection/api/client.router.js +15 -0
  114. package/server/connection/api/configs.js +96 -0
  115. package/server/connection/api/qr-page.handler.js +17 -0
  116. package/server/connection/api/remotes.router.js +30 -0
  117. package/server/connection/api/server-info.router.js +149 -0
  118. package/server/connection/api/session.middleware.js +93 -0
  119. package/server/connection/api/unauthorized-response.js +73 -0
  120. package/server/connection/socket/createConnectionRegistrar.js +23 -0
  121. package/server/connection/socket/createSocketSessionAuthMiddleware.js +49 -0
  122. package/server/connection/socket/socket-action-responder.js +12 -0
  123. package/server/connection/socket/socket.timestamp-middleware.js +51 -0
  124. package/server/index.js +12 -0
  125. package/server/init/bootstrapApi.js +87 -0
  126. package/server/init/bootstrapSocket.js +79 -0
  127. package/server/init/createAdminApiRouter.js +22 -0
  128. package/server/init/createAdminUiRouter.js +21 -0
  129. package/server/init/createSocketActionRegistrars.js +52 -0
  130. package/server/init/observers/startConfigObserver.js +51 -0
  131. package/server/init/observers/startDisplaySizeObserver.js +55 -0
  132. package/server/init/observers/startNotificationObserver.js +49 -0
  133. package/server/init/observers/startQrOverlayHoverObserver.js +89 -0
  134. package/server/init/observers/startQrOverlayRefreshObserver.js +53 -0
  135. package/server/os/darwin/app.js +45 -0
  136. package/server/os/darwin/applescript.js +51 -0
  137. package/server/os/darwin/cliSocket.js +53 -0
  138. package/server/os/darwin/url.js +9 -0
  139. package/server/os/darwin/window.js +10 -0
  140. package/server/os/linux/app.js +120 -0
  141. package/server/os/linux/cliSocket.js +53 -0
  142. package/server/os/linux/process.js +69 -0
  143. package/server/os/linux/screen.js +58 -0
  144. package/server/os/linux/systemd.js +139 -0
  145. package/server/os/linux/url.js +17 -0
  146. package/server/os/linux/windows.js +144 -0
  147. package/server/os/win32/app.js +66 -0
  148. package/server/os/win32/cliSocket.js +15 -0
  149. package/server/os/win32/powershell.js +70 -0
  150. package/server/os/win32/process.js +20 -0
  151. package/server/os/win32/service.js +95 -0
  152. package/server/os/win32/url.js +9 -0
  153. package/server/os/win32/window.js +10 -0
  154. package/server/remotes/admin/createAdminEventGuardMiddleware.js +29 -0
  155. package/server/remotes/admin/createForceUpdateCheckAction.js +39 -0
  156. package/server/remotes/admin/createInstallUpdateAction.js +64 -0
  157. package/server/remotes/admin/createOpenQrBrowserAction.js +63 -0
  158. package/server/remotes/admin/createOpenServerInfoBrowserAction.js +58 -0
  159. package/server/remotes/admin/createRestartServiceAction.js +20 -0
  160. package/server/remotes/admin/createRotateEntryTokenAction.js +43 -0
  161. package/server/remotes/admin/createToggleQrOverlayAction.js +38 -0
  162. package/server/remotes/admin/index.js +32 -0
  163. package/server/remotes/admin/notifyIfRestarted.js +102 -0
  164. package/server/remotes/admin/registrar.js +94 -0
  165. package/server/remotes/browser/actions/createFocusOrLaunchBrowserAction.js +22 -0
  166. package/server/remotes/browser/actions/openUrlOnHost.js +3 -0
  167. package/server/remotes/browser/browserCatalog.js +70 -0
  168. package/server/remotes/browser/index.js +15 -0
  169. package/server/remotes/browser/listBrowsersOnHost.js +23 -0
  170. package/server/remotes/browser/registrar.js +29 -0
  171. package/server/remotes/browser/spec.js +18 -0
  172. package/server/remotes/browser/state.js +5 -0
  173. package/server/remotes/input/registrar.js +39 -0
  174. package/server/remotes/preview/bgraToRgbaBuffer.js +20 -0
  175. package/server/remotes/preview/captureAroundCursor.js +19 -0
  176. package/server/remotes/preview/createPreviewStreamer.js +85 -0
  177. package/server/remotes/preview/registrar.js +34 -0
  178. package/server/remotes/samsung/createSamsungCommandService.js +203 -0
  179. package/server/remotes/samsung/createSamsungRemote.js +26 -0
  180. package/server/remotes/samsung/createSamsungRemoteGetter.js +46 -0
  181. package/server/remotes/samsung/createSamsungTvGetter.js +102 -0
  182. package/server/remotes/samsung/device-config.js +122 -0
  183. package/server/remotes/samsung/registrar.js +59 -0
  184. package/server/remotes/samsung/utils.js +56 -0
  185. package/server/remotes/vlc/index.js +39 -0
  186. package/server/remotes/vlc/registrar.js +94 -0
  187. package/server/remotes/vlc/spec.js +15 -0
  188. package/server/remotes/vlc/state.js +5 -0
  189. package/server/remotes/window/index.js +6 -0
  190. package/server/remotes/window/registrar.js +28 -0
  191. package/server/services/application/createApplicationDaemonService.js +144 -0
  192. package/server/services/application/getDaemonServiceAdapter.js +56 -0
  193. package/server/services/application/utils.js +29 -0
  194. package/server/services/config/bootstrapConfig.js +38 -0
  195. package/server/services/config/configPaths.js +42 -0
  196. package/server/services/config/configSchema.js +297 -0
  197. package/server/services/config/configService.js +89 -0
  198. package/server/services/config/defaultConfig.js +137 -0
  199. package/server/services/config/envConfig.js +49 -0
  200. package/server/services/config/index.js +9 -0
  201. package/server/services/config/logConfig.js +54 -0
  202. package/server/services/config/system-config.js +44 -0
  203. package/server/services/createServicesContainer.js +94 -0
  204. package/server/services/createServicesRegistry.js +48 -0
  205. package/server/services/input/createInputController.js +17 -0
  206. package/server/services/input/createKeyboardController.js +146 -0
  207. package/server/services/input/createMouseController.js +182 -0
  208. package/server/services/notifier/createClientNotifier.js +23 -0
  209. package/server/services/notifier/createHostNotifier.js +41 -0
  210. package/server/services/notifier/createNotifier.js +13 -0
  211. package/server/services/notifier/createNotifierComposite.js +122 -0
  212. package/server/services/notifier/handleOpenQrBrowserEvent.js +40 -0
  213. package/server/services/notifier/handleOpenServerInfoBrowserEvent.js +40 -0
  214. package/server/services/notifier/handleRestartServiceEvent.js +37 -0
  215. package/server/services/notifier/handleRotateEntryTokenEvent.js +42 -0
  216. package/server/services/notifier/handleSessionEvent.js +24 -0
  217. package/server/services/notifier/handleToggleQrOverlayEvent.js +21 -0
  218. package/server/services/notifier/host-notifier/createLinuxHostNotifier.js +23 -0
  219. package/server/services/notifier/host-notifier/createNodeNotifierHostNotifier.js +24 -0
  220. package/server/services/notifier/host-notifier/index.js +11 -0
  221. package/server/services/notifier/mapper/handleForceUpdateCheckEvent.js +24 -0
  222. package/server/services/notifier/mapper/handleInstallUpdateEvent.js +53 -0
  223. package/server/services/notifier/mapper/handleSocketEvent.js +40 -0
  224. package/server/services/notifier/mapper/handleUpdateManagerEvent.js +24 -0
  225. package/server/services/notifier/mapper/notify.js +7 -0
  226. package/server/services/os/index.js +23 -0
  227. package/server/services/os/platforms/createFallbackAdapter.js +31 -0
  228. package/server/services/os/platforms/darwin/app.js +6 -0
  229. package/server/services/os/platforms/darwin/index.js +21 -0
  230. package/server/services/os/platforms/darwin/scripts.js +4 -0
  231. package/server/services/os/platforms/darwin/url.js +1 -0
  232. package/server/services/os/platforms/darwin/window.js +4 -0
  233. package/server/services/os/platforms/linux/app.js +6 -0
  234. package/server/services/os/platforms/linux/index.js +33 -0
  235. package/server/services/os/platforms/linux/url.js +1 -0
  236. package/server/services/os/platforms/linux/windows.js +11 -0
  237. package/server/services/os/platforms/win32/app.js +6 -0
  238. package/server/services/os/platforms/win32/index.js +21 -0
  239. package/server/services/os/platforms/win32/overlay.js +6 -0
  240. package/server/services/os/platforms/win32/powershell.js +4 -0
  241. package/server/services/os/platforms/win32/url.js +1 -0
  242. package/server/services/os/platforms/win32/window.js +4 -0
  243. package/server/services/os/shared.js +2 -0
  244. package/server/services/overlay/createNoopOverlay.js +13 -0
  245. package/server/services/overlay/createQrOverlay.js +27 -0
  246. package/server/services/overlay/createQrOverlayWin32.js +158 -0
  247. package/server/services/overlay/createQrOverlayYad.js +178 -0
  248. package/server/services/overlay/renderQrPage.js +82 -0
  249. package/server/services/persistence/createConfigDao.js +106 -0
  250. package/server/services/persistence/createDatabaseProvider.js +23 -0
  251. package/server/services/persistence/createEntryTokenDao.js +140 -0
  252. package/server/services/persistence/createRestartLogDao.js +210 -0
  253. package/server/services/persistence/index.js +19 -0
  254. package/server/services/pubsub/createEventStore.js +54 -0
  255. package/server/services/pubsub/createPubSub.js +89 -0
  256. package/server/services/pubsub/createServiceEvents.js +29 -0
  257. package/server/services/pubsub/serviceEventConstants.js +39 -0
  258. package/server/services/remotes/createRemotes.js +25 -0
  259. package/server/services/server/createHttpsServer.js +12 -0
  260. package/server/services/server/createServer.js +66 -0
  261. package/server/services/sse/createSseService.js +96 -0
  262. package/server/services/sse/utils.js +7 -0
  263. package/server/services/system/createSystemService.js +170 -0
  264. package/server/services/system/getNetworkInfo.js +18 -0
  265. package/server/services/system/getScreenInfo.js +32 -0
  266. package/server/services/system/listNetworkInterfaces.js +27 -0
  267. package/server/services/task-manager/createTaskManager.js +68 -0
  268. package/server/services/task-runner/createTaskRunner.js +114 -0
  269. package/server/services/token-manager/createTokenManager.js +244 -0
  270. package/server/services/token-manager/token-format.js +7 -0
  271. package/server/services/token-manager/token-store-utils.js +8 -0
  272. package/server/services/update-manager/CommandUpdateSource.js +70 -0
  273. package/server/services/update-manager/NpmUpdateSource.js +34 -0
  274. package/server/services/update-manager/buildNpmGlobalUpdateCommand.js +15 -0
  275. package/server/services/update-manager/chooseUpdateCheckSource.js +20 -0
  276. package/server/services/update-manager/chooseUpdateInstallSource.js +5 -0
  277. package/server/services/update-manager/createUpdateManager.js +109 -0
  278. package/server/services/update-manager/resolveInstallUpdateCommand.js +42 -0
  279. package/server/term/cli/executeLocalServiceCommand.js +42 -0
  280. package/server/term/cli/getCliSocketPath.js +5 -0
  281. package/server/term/cli/parseCliArgs.js +110 -0
  282. package/server/term/cli/printCliResult.js +18 -0
  283. package/server/term/cli/runCliCmd.js +50 -0
  284. package/server/term/cli/sendCliCommand.js +76 -0
  285. package/server/term/cliSocket.js +29 -0
  286. package/server/term/srv/commands/configCommand.js +84 -0
  287. package/server/term/srv/commands/helpCommand.js +6 -0
  288. package/server/term/srv/commands/infoCommand.js +7 -0
  289. package/server/term/srv/commands/openQrCommand.js +7 -0
  290. package/server/term/srv/commands/samsungDetectCommand.js +52 -0
  291. package/server/term/srv/commands/serviceCommand.js +25 -0
  292. package/server/term/srv/commands/systemConfigCommand.js +7 -0
  293. package/server/term/srv/commands/tasksCommand.js +24 -0
  294. package/server/term/srv/commands/tokensCommand.js +15 -0
  295. package/server/term/srv/executeCliCommand.js +44 -0
  296. package/server/term/srv/executeCliRequest.js +38 -0
  297. package/server/term/srv/startCliServer.js +140 -0
  298. package/server/utils/createRandomToken.js +11 -0
  299. package/server/utils/env.js +155 -0
  300. package/server/utils/git.js +13 -0
  301. package/server/utils/http.js +7 -0
  302. package/server/utils/network.js +45 -0
  303. package/server/utils/paths.js +10 -0
  304. package/server/utils/process.js +57 -0
  305. package/server/utils/robot.js +11 -0
  306. package/server/utils/semver.js +33 -0
  307. package/server/utils/truncateText.js +7 -0
  308. package/utils/createLazy.js +13 -0
  309. package/utils/functional.js +48 -0
  310. package/utils/math.js +26 -0
  311. package/utils/notificationSettings.js +61 -0
  312. package/utils/object.utils.js +79 -0
  313. package/utils/predicates.js +17 -0
  314. package/utils/remoteCommands.js +40 -0
  315. package/utils/sync.js +3 -0
  316. package/velor-remote-mouse-6.4.8.tgz +0 -0
@@ -0,0 +1,52 @@
1
+ import {createControlEventRegistrar} from '../remotes/input/registrar.js';
2
+ import {createAdminEventRegistrar} from '../remotes/admin/registrar.js';
3
+ import {createPreviewEventRegistrar} from '../remotes/preview/registrar.js';
4
+ import {createConnectionRegistrar} from '../connection/socket/createConnectionRegistrar.js';
5
+ import {createBrowserRegistrar} from '../remotes/browser/registrar.js';
6
+ import {createSamsungRegistrar} from '../remotes/samsung/registrar.js';
7
+ import {createVlcRegistrar} from '../remotes/vlc/registrar.js';
8
+ import {createWindowRegistrar} from '../remotes/window/registrar.js';
9
+
10
+ export function createSocketActionRegistrars(services) {
11
+ return [
12
+ (socket) => {
13
+ const {
14
+ mouse,
15
+ keyboard,
16
+ updateConfig,
17
+ } = services.getInputController();
18
+ updateConfig();
19
+ return createControlEventRegistrar({mouse, keyboard})(socket);
20
+ },
21
+ (socket) => {
22
+ const {browser} = services.getRemotes();
23
+ return createBrowserRegistrar({browser, getConfig: services.getConfig})(socket);
24
+ },
25
+ (socket) => {
26
+ const {adminActions} = services.getRemotes();
27
+ return createAdminEventRegistrar({adminActions, getSystemConfig: services.getSystemConfig})(socket);
28
+ },
29
+ (socket) => {
30
+ const {preview} = services.getRemotes();
31
+ return createPreviewEventRegistrar({preview, getConfig: services.getConfig})(socket);
32
+ },
33
+ (socket) => {
34
+ const {samsung} = services.getRemotes();
35
+ return createSamsungRegistrar({samsung})(socket);
36
+ },
37
+ (socket) => {
38
+ const {vlc} = services.getRemotes();
39
+ return createVlcRegistrar({
40
+ vlc,
41
+ keyboard: services.getInputController().keyboard,
42
+ getConfig: services.getConfig,
43
+ })(socket);
44
+ },
45
+ (socket) => {
46
+ const {windowActions} = services.getRemotes();
47
+ return createWindowRegistrar({windowActions})(socket);
48
+ },
49
+ (socket) => createConnectionRegistrar({events: services.getEvents()})(socket)
50
+ ];
51
+
52
+ }
@@ -0,0 +1,51 @@
1
+ import {PUBSUB_SERVICE_CONFIG} from '../../services/pubsub/serviceEventConstants.js';
2
+ import {createLogger} from '../../application/logger.js';
3
+
4
+ let log;
5
+ function getModuleLog() {
6
+ log ??= createLogger('config:observer');
7
+ return log;
8
+ }
9
+
10
+ function getValueAtPath(source, dottedPath) {
11
+ return String(dottedPath || '')
12
+ .split('.')
13
+ .filter(Boolean)
14
+ .reduce((cursor, segment) => (cursor == null ? undefined : cursor[segment]), source);
15
+ }
16
+
17
+ export function startConfigObserver(services) {
18
+ const log = getModuleLog();
19
+ const bus = services.getPubSub();
20
+
21
+ return bus.subscribe((event) => {
22
+ const sse = services.getSseService();
23
+ const config = services.getConfig();
24
+ const changedKeys = Array.isArray(event.payload?.changedKeys) ? event.payload.changedKeys : [];
25
+ log.debug({
26
+ type: event.type,
27
+ changeType: event.payload?.changeType || '',
28
+ changedKeys,
29
+ }, 'Configuration persistante changee');
30
+ sse.emit({
31
+ name: 'config.changed',
32
+ service: event.service,
33
+ type: event.type,
34
+ payload: {
35
+ sequence: event.sequence,
36
+ at: event.at,
37
+ type: event.type,
38
+ changeType: event.payload?.changeType || '',
39
+ changedKeys,
40
+ entries: changedKeys.map((path) => ({
41
+ path,
42
+ value: getValueAtPath(config, path),
43
+ })),
44
+ config,
45
+ sysConfig: services.getSystemConfig(),
46
+ },
47
+ });
48
+ }, {
49
+ service: PUBSUB_SERVICE_CONFIG,
50
+ });
51
+ }
@@ -0,0 +1,55 @@
1
+ const DEFAULT_DISPLAY_SIZE_POLL_MS = 1000;
2
+
3
+ function hasDisplaySizeChanged(previous, next) {
4
+ return Boolean(previous && next && (previous.width !== next.width || previous.height !== next.height));
5
+ }
6
+
7
+ export function startDisplaySizeObserver(services, options = {}) {
8
+ const intervalMs = Math.max(250, Number(options.intervalMs) || DEFAULT_DISPLAY_SIZE_POLL_MS);
9
+ const getScreenInfo = options.getScreenInfo || (() => services.getSystem?.()?.getScreenInfo?.() || null);
10
+ let previousSize = null;
11
+ let polling = false;
12
+
13
+ async function poll() {
14
+ if (polling) {
15
+ return;
16
+ }
17
+
18
+ let nextSize = null;
19
+ try {
20
+ polling = true;
21
+ nextSize = await getScreenInfo();
22
+ } finally {
23
+ polling = false;
24
+ }
25
+ if (!nextSize) {
26
+ return;
27
+ }
28
+
29
+ const mouse = services.getInputController?.().mouse;
30
+ if (!previousSize) {
31
+ previousSize = nextSize;
32
+ mouse?.setScreenSizeOverride?.(nextSize);
33
+ return;
34
+ }
35
+
36
+ if (!hasDisplaySizeChanged(previousSize, nextSize)) {
37
+ mouse?.setScreenSizeOverride?.(nextSize);
38
+ return;
39
+ }
40
+
41
+ const changedFrom = previousSize;
42
+ previousSize = nextSize;
43
+ mouse?.remapToScreenSize?.(changedFrom, nextSize);
44
+ void services.getQrOverlay?.()?.update?.();
45
+ }
46
+
47
+ void poll();
48
+ const interval = setInterval(() => {
49
+ void poll();
50
+ }, intervalMs);
51
+
52
+ interval.unref?.();
53
+
54
+ return () => clearInterval(interval);
55
+ }
@@ -0,0 +1,49 @@
1
+ import {handleSocketEvent} from "../../services/notifier/mapper/handleSocketEvent.js";
2
+ import {handleUpdateManagerEvent} from "../../services/notifier/mapper/handleUpdateManagerEvent.js";
3
+ import {handleForceUpdateCheckEvent} from "../../services/notifier/mapper/handleForceUpdateCheckEvent.js";
4
+ import {handleInstallUpdateEvent} from "../../services/notifier/mapper/handleInstallUpdateEvent.js";
5
+ import {handleOpenQrBrowserEvent} from "../../services/notifier/handleOpenQrBrowserEvent.js";
6
+ import {handleOpenServerInfoBrowserEvent} from "../../services/notifier/handleOpenServerInfoBrowserEvent.js";
7
+ import {handleRestartServiceEvent} from "../../services/notifier/handleRestartServiceEvent.js";
8
+ import {handleToggleQrOverlayEvent} from "../../services/notifier/handleToggleQrOverlayEvent.js";
9
+ import {handleRotateEntryTokenEvent} from "../../services/notifier/handleRotateEntryTokenEvent.js";
10
+ import {handleSessionEvent} from "../../services/notifier/handleSessionEvent.js";
11
+ import {
12
+ PUBSUB_SERVICE_ADMIN_FORCE_UPDATE_CHECK,
13
+ PUBSUB_SERVICE_ADMIN_INSTALL_UPDATE,
14
+ PUBSUB_SERVICE_ADMIN_OPEN_QR_BROWSER,
15
+ PUBSUB_SERVICE_ADMIN_OPEN_SERVER_INFO_BROWSER,
16
+ PUBSUB_SERVICE_ADMIN_RESTART_SERVICE,
17
+ PUBSUB_SERVICE_ADMIN_ROTATE_ENTRY_TOKEN,
18
+ PUBSUB_SERVICE_ADMIN_TOGGLE_QR_OVERLAY,
19
+ PUBSUB_SERVICE_SESSION,
20
+ PUBSUB_SERVICE_SOCKET,
21
+ PUBSUB_SERVICE_UPDATE_MANAGER,
22
+ } from "../../services/pubsub/serviceEventConstants.js";
23
+
24
+ const NOTIFICATION_HANDLERS = {
25
+ [PUBSUB_SERVICE_SOCKET]: handleSocketEvent,
26
+ [PUBSUB_SERVICE_UPDATE_MANAGER]: handleUpdateManagerEvent,
27
+ [PUBSUB_SERVICE_ADMIN_FORCE_UPDATE_CHECK]: handleForceUpdateCheckEvent,
28
+ [PUBSUB_SERVICE_ADMIN_INSTALL_UPDATE]: handleInstallUpdateEvent,
29
+ [PUBSUB_SERVICE_ADMIN_OPEN_QR_BROWSER]: handleOpenQrBrowserEvent,
30
+ [PUBSUB_SERVICE_ADMIN_OPEN_SERVER_INFO_BROWSER]: handleOpenServerInfoBrowserEvent,
31
+ [PUBSUB_SERVICE_ADMIN_RESTART_SERVICE]: handleRestartServiceEvent,
32
+ [PUBSUB_SERVICE_ADMIN_TOGGLE_QR_OVERLAY]: handleToggleQrOverlayEvent,
33
+ [PUBSUB_SERVICE_ADMIN_ROTATE_ENTRY_TOKEN]: handleRotateEntryTokenEvent,
34
+ [PUBSUB_SERVICE_SESSION]: handleSessionEvent,
35
+ };
36
+
37
+ export function startNotificationObserver(services) {
38
+ const bus = services.getPubSub();
39
+ const notifier = services.getNotifier();
40
+
41
+ return bus.subscribe((event) => {
42
+ const handleEvent = NOTIFICATION_HANDLERS[event.service];
43
+ if (!handleEvent) {
44
+ return;
45
+ }
46
+
47
+ handleEvent(notifier, event);
48
+ }, (event) => Boolean(event?.service && event?.type));
49
+ }
@@ -0,0 +1,89 @@
1
+ function expandBounds(bounds, marginPx) {
2
+ return {
3
+ x: bounds.x - marginPx,
4
+ y: bounds.y - marginPx,
5
+ width: bounds.width + (marginPx * 2),
6
+ height: bounds.height + (marginPx * 2),
7
+ };
8
+ }
9
+
10
+ function shrinkBounds(bounds, marginPx) {
11
+ const width = Math.max(1, bounds.width - (marginPx * 2));
12
+ const height = Math.max(1, bounds.height - (marginPx * 2));
13
+ return {
14
+ x: bounds.x + marginPx,
15
+ y: bounds.y + marginPx,
16
+ width,
17
+ height,
18
+ };
19
+ }
20
+
21
+ function isPointInsideBounds(point, bounds) {
22
+ if (!point || !bounds) {
23
+ return false;
24
+ }
25
+
26
+ return point.x >= bounds.x
27
+ && point.x <= (bounds.x + bounds.width)
28
+ && point.y >= bounds.y
29
+ && point.y <= (bounds.y + bounds.height);
30
+ }
31
+
32
+ export function startQrOverlayHoverObserver(services) {
33
+ const robot = services.getRobot();
34
+ const qrOverlay = services.getQrOverlay();
35
+ let suppressedAt = 0;
36
+
37
+ if (!robot?.getMousePos || !qrOverlay?.getBounds || !qrOverlay?.setSuppressed) {
38
+ return () => {};
39
+ }
40
+
41
+ const timer = setInterval(() => {
42
+ const overlayConfig = services.getConfig()?.qrOverlay || {};
43
+ if (!overlayConfig.autoHideOnHover) {
44
+ qrOverlay.setSuppressed(false);
45
+ return;
46
+ }
47
+
48
+ if (!qrOverlay.isVisible?.()) {
49
+ qrOverlay.setSuppressed(false);
50
+ return;
51
+ }
52
+
53
+ const bounds = qrOverlay.getBounds();
54
+ if (!bounds) {
55
+ qrOverlay.setSuppressed(false);
56
+ return;
57
+ }
58
+
59
+ const cursor = robot.getMousePos();
60
+ const entryMarginPx = Math.max(0, Number(overlayConfig.hoverEntryMarginPx) || 10);
61
+ const exitMarginPx = Math.max(0, Number(overlayConfig.hoverExitMarginPx) || 18);
62
+ const showDelayMs = Math.max(0, Number(overlayConfig.hoverShowDelayMs) || 1200);
63
+ const isSuppressed = qrOverlay.isSuppressed?.();
64
+
65
+ let nextSuppressed = false;
66
+ if (isSuppressed) {
67
+ const stillInsideExitZone = isPointInsideBounds(cursor, expandBounds(bounds, exitMarginPx));
68
+ const delayElapsed = (Date.now() - suppressedAt) >= showDelayMs;
69
+ nextSuppressed = stillInsideExitZone || !delayElapsed;
70
+ } else {
71
+ nextSuppressed = isPointInsideBounds(cursor, shrinkBounds(bounds, entryMarginPx));
72
+ }
73
+
74
+ if (nextSuppressed && !isSuppressed) {
75
+ suppressedAt = Date.now();
76
+ }
77
+
78
+ if (!nextSuppressed) {
79
+ suppressedAt = 0;
80
+ }
81
+
82
+ qrOverlay.setSuppressed(nextSuppressed);
83
+ }, 80);
84
+
85
+ return () => {
86
+ clearInterval(timer);
87
+ qrOverlay.setSuppressed(false);
88
+ };
89
+ }
@@ -0,0 +1,53 @@
1
+ import {
2
+ PUBSUB_EVENT_CONFIG_DELETED,
3
+ PUBSUB_EVENT_CONFIG_UPDATED,
4
+ PUBSUB_EVENT_TOKEN_CHANGED,
5
+ PUBSUB_SERVICE_CONFIG,
6
+ PUBSUB_SERVICE_TOKEN_MANAGER
7
+ } from "../../services/pubsub/serviceEventConstants.js";
8
+
9
+ function isQrOverlayConfigEvent(event) {
10
+ if (event?.type !== PUBSUB_EVENT_CONFIG_UPDATED && event?.type !== PUBSUB_EVENT_CONFIG_DELETED) {
11
+ return false;
12
+ }
13
+
14
+ const changedKeys = Array.isArray(event?.payload?.changedKeys) ? event.payload.changedKeys : [];
15
+ return changedKeys.some((key) => String(key || '').startsWith('qrOverlay.'));
16
+ }
17
+
18
+ function isQrOverlayRefreshEvent(event) {
19
+ if (event?.service === PUBSUB_SERVICE_TOKEN_MANAGER && event?.type === PUBSUB_EVENT_TOKEN_CHANGED) {
20
+ return true;
21
+ }
22
+
23
+ return event?.service === PUBSUB_SERVICE_CONFIG && isQrOverlayConfigEvent(event);
24
+ }
25
+
26
+ export function startQrOverlayRefreshObserver(services) {
27
+ const bus = services.getPubSub();
28
+ const qrOverlay = services.getQrOverlay();
29
+
30
+ return bus.subscribe((event) => {
31
+ if (event.service === PUBSUB_SERVICE_TOKEN_MANAGER) {
32
+ void qrOverlay.update();
33
+ return;
34
+ }
35
+
36
+ if (!isQrOverlayConfigEvent(event)) {
37
+ return;
38
+ }
39
+
40
+ const changedKeys = Array.isArray(event?.payload?.changedKeys) ? event.payload.changedKeys : [];
41
+ if (changedKeys.includes('qrOverlay.enabled')) {
42
+ if (services.getConfig().qrOverlay?.enabled) {
43
+ void qrOverlay.show?.();
44
+ return;
45
+ }
46
+
47
+ qrOverlay.hide?.();
48
+ return;
49
+ }
50
+
51
+ void qrOverlay.update();
52
+ }, isQrOverlayRefreshEvent);
53
+ }
@@ -0,0 +1,45 @@
1
+ import fs from 'node:fs';
2
+ import {execFileAsync} from '../../utils/process.js';
3
+ import {buildAppWindowScript} from './applescript.js';
4
+
5
+ export function findInstalledDarwinApp(apps = []) {
6
+ for (const appName of apps) {
7
+ const locations = [
8
+ `/Applications/${appName}.app`,
9
+ `/System/Applications/${appName}.app`,
10
+ ];
11
+ if (locations.some((path) => fs.existsSync(path))) {
12
+ return appName;
13
+ }
14
+ }
15
+ return '';
16
+ }
17
+
18
+ export async function resolveDarwinApp(spec = {}) {
19
+ const appName = findInstalledDarwinApp(spec.darwin?.apps ?? []);
20
+ return appName ? {appName} : null;
21
+ }
22
+
23
+ export async function openOrFocusDarwinApp(spec) {
24
+ const resolved = await resolveDarwinApp(spec);
25
+ if (!resolved) {
26
+ return false;
27
+ }
28
+ return (await execFileAsync('open', ['-a', resolved.appName])).ok;
29
+ }
30
+
31
+ export async function toggleDarwinAppWindow(spec) {
32
+ const resolved = await resolveDarwinApp(spec);
33
+ if (!resolved) {
34
+ return false;
35
+ }
36
+ return (await execFileAsync('osascript', ['-e', buildAppWindowScript(resolved.appName, 'toggle')])).ok;
37
+ }
38
+
39
+ export async function closeDarwinAppWindow(spec) {
40
+ const resolved = await resolveDarwinApp(spec);
41
+ if (!resolved) {
42
+ return false;
43
+ }
44
+ return (await execFileAsync('osascript', ['-e', buildAppWindowScript(resolved.appName, 'close')])).ok;
45
+ }
@@ -0,0 +1,51 @@
1
+ export function buildAppWindowScript(appName, mode) {
2
+ if (mode === 'toggle') {
3
+ return `
4
+ tell application "${appName}" to activate
5
+ tell application "System Events"
6
+ tell process "${appName}"
7
+ if (count of windows) is 0 then return false
8
+ set frontWindow to first window
9
+ click (first button of frontWindow whose subrole is "AXZoomButton")
10
+ end tell
11
+ end tell
12
+ return true
13
+ `.trim();
14
+ }
15
+
16
+ return `
17
+ tell application "${appName}" to activate
18
+ tell application "System Events"
19
+ tell process "${appName}"
20
+ if (count of windows) is 0 then return false
21
+ click (first button of first window whose subrole is "AXCloseButton")
22
+ end tell
23
+ end tell
24
+ return true
25
+ `.trim();
26
+ }
27
+
28
+ export function buildActiveWindowScript(mode) {
29
+ if (mode === 'toggle') {
30
+ return `
31
+ tell application "System Events"
32
+ tell (first application process whose frontmost is true)
33
+ if (count of windows) is 0 then return false
34
+ set frontWindow to first window
35
+ click (first button of frontWindow whose subrole is "AXZoomButton")
36
+ end tell
37
+ end tell
38
+ return true
39
+ `.trim();
40
+ }
41
+
42
+ return `
43
+ tell application "System Events"
44
+ tell (first application process whose frontmost is true)
45
+ if (count of windows) is 0 then return false
46
+ click (first button of first window whose subrole is "AXCloseButton")
47
+ end tell
48
+ end tell
49
+ return true
50
+ `.trim();
51
+ }
@@ -0,0 +1,53 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+
5
+ function getSocketName() {
6
+ const uid = typeof process.getuid === 'function' ? process.getuid() : 'default';
7
+ return `remote-mouse-${uid}.sock`;
8
+ }
9
+
10
+ function removeStaleSocket(socketPath) {
11
+ try {
12
+ fs.unlinkSync(socketPath);
13
+ } catch (_error) {
14
+ // Ignore missing or stale socket cleanup issues.
15
+ }
16
+ }
17
+
18
+ export function getCliSocketPath() {
19
+ return path.join(os.tmpdir(), getSocketName());
20
+ }
21
+
22
+ export function prepareCliServerSocket(socketPath) {
23
+ removeStaleSocket(socketPath);
24
+ }
25
+
26
+ export function cleanupCliServerSocket(socketPath) {
27
+ removeStaleSocket(socketPath);
28
+ }
29
+
30
+ export function secureCliServerSocket(socketPath) {
31
+ try {
32
+ fs.chmodSync(socketPath, 0o600);
33
+ } catch (_error) {
34
+ // Best effort.
35
+ }
36
+ }
37
+
38
+ export function cleanupCliClientConnectionError(socketPath, error) {
39
+ if (error?.code !== 'ECONNREFUSED') {
40
+ return false;
41
+ }
42
+
43
+ try {
44
+ if (!fs.existsSync(socketPath)) {
45
+ return false;
46
+ }
47
+
48
+ fs.unlinkSync(socketPath);
49
+ return true;
50
+ } catch (_cleanupError) {
51
+ return false;
52
+ }
53
+ }
@@ -0,0 +1,9 @@
1
+ import {execFileAsync} from '../../utils/process.js';
2
+
3
+ export async function openDarwinUrl(url) {
4
+ const safeUrl = String(url || '').trim();
5
+ if (!safeUrl) {
6
+ return false;
7
+ }
8
+ return (await execFileAsync('open', [safeUrl])).ok;
9
+ }
@@ -0,0 +1,10 @@
1
+ import {execFileAsync} from '../../utils/process.js';
2
+ import {buildActiveWindowScript} from './applescript.js';
3
+
4
+ export async function toggleDarwinActiveWindow() {
5
+ return (await execFileAsync('osascript', ['-e', buildActiveWindowScript('toggle')])).ok;
6
+ }
7
+
8
+ export async function closeDarwinActiveWindow() {
9
+ return (await execFileAsync('osascript', ['-e', buildActiveWindowScript('close')])).ok;
10
+ }
@@ -0,0 +1,120 @@
1
+ import {execFileAsync, spawnDetached} from '../../utils/process.js';
2
+ import {activateWindow, closeWindow, findWindows, toggleWindow} from './windows.js';
3
+ import {resolveLinuxCommand} from './process.js';
4
+ import {sleep} from "../../../utils/sync.js";
5
+
6
+ export async function isAnyProcessRunning(processNames = []) {
7
+ const checks = [];
8
+
9
+ for (const processName of processNames) {
10
+ checks.push(await execFileAsync('pgrep', ['-x', processName]));
11
+ checks.push(await execFileAsync('pgrep', ['-f', processName]));
12
+ }
13
+
14
+ return checks.some((result) => result.ok);
15
+ }
16
+
17
+ export async function resolveLinuxApp(spec = {}) {
18
+ const linux = spec.linux || {};
19
+ let launchCommand = '';
20
+
21
+ for (const command of linux.commands || []) {
22
+ launchCommand = await resolveLinuxCommand(command);
23
+ if (launchCommand) {
24
+ break;
25
+ }
26
+ }
27
+
28
+ if (launchCommand) {
29
+ return {
30
+ launchCommand,
31
+ launchArgs: [],
32
+ processNames: linux.processNames ?? linux.commands ?? [],
33
+ windowQuery: {
34
+ classes: linux.windowClasses ?? [],
35
+ names: linux.windowNames ?? [],
36
+ },
37
+ };
38
+ }
39
+
40
+ const flatpakCommand = linux.flatpakAppId ? await resolveLinuxCommand('flatpak') : '';
41
+ if (linux.flatpakAppId && flatpakCommand) {
42
+ return {
43
+ launchCommand: flatpakCommand,
44
+ launchArgs: ['run', linux.flatpakAppId],
45
+ processNames: linux.processNames ?? [],
46
+ windowQuery: {
47
+ classes: linux.windowClasses ?? [],
48
+ names: linux.windowNames ?? [],
49
+ },
50
+ };
51
+ }
52
+
53
+ return null;
54
+ }
55
+
56
+ export async function openOrFocusLinuxApp(spec, {maximize = false} = {}) {
57
+ const resolved = await resolveLinuxApp(spec);
58
+ if (!resolved) {
59
+ return false;
60
+ }
61
+
62
+ const windowIds = await findWindows(resolved.windowQuery);
63
+ if (windowIds.length > 0) {
64
+ return activateWindow(windowIds[0], {maximize});
65
+ }
66
+
67
+ const running = await isAnyProcessRunning(resolved.processNames);
68
+ if (running) {
69
+ for (let attempt = 0; attempt < 8; attempt += 1) {
70
+ const ids = await findWindows(resolved.windowQuery);
71
+ if (ids.length > 0) {
72
+ return activateWindow(ids[0], {maximize});
73
+ }
74
+ await sleep(250);
75
+ }
76
+ }
77
+
78
+ const launched = await spawnDetached(resolved.launchCommand, resolved.launchArgs);
79
+ if (!launched) {
80
+ return false;
81
+ }
82
+
83
+ for (let attempt = 0; attempt < 10; attempt += 1) {
84
+ const ids = await findWindows(resolved.windowQuery);
85
+ if (ids.length > 0) {
86
+ return activateWindow(ids[0], {maximize});
87
+ }
88
+ await sleep(350);
89
+ }
90
+
91
+ return true;
92
+ }
93
+
94
+ export async function toggleLinuxAppWindow(spec) {
95
+ const resolved = await resolveLinuxApp(spec);
96
+ if (!resolved) {
97
+ return false;
98
+ }
99
+
100
+ const ids = await findWindows(resolved.windowQuery);
101
+ if (ids.length === 0) {
102
+ return openOrFocusLinuxApp(spec, {maximize: true});
103
+ }
104
+
105
+ return toggleWindow(ids[0]);
106
+ }
107
+
108
+ export async function closeLinuxAppWindow(spec) {
109
+ const resolved = await resolveLinuxApp(spec);
110
+ if (!resolved) {
111
+ return false;
112
+ }
113
+
114
+ const ids = await findWindows(resolved.windowQuery);
115
+ if (ids.length === 0) {
116
+ return false;
117
+ }
118
+
119
+ return closeWindow(ids[0]);
120
+ }