rechrome 1.35.1 → 1.36.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.
Files changed (402) hide show
  1. package/README.md +79 -0
  2. package/extension/lib/background.mjs +28 -1
  3. package/extension/lib/ui/connect.js +29 -19
  4. package/listeners.js +17 -1
  5. package/listeners.ts +7 -2
  6. package/package.json +5 -3
  7. package/rechrome.js +101 -17
  8. package/rechrome.ts +101 -17
  9. package/scoped-upload.js +165 -0
  10. package/scoped-upload.ts +140 -0
  11. package/serve.js +140 -25
  12. package/serve.ts +140 -25
  13. package/vendor/playwright-cli/node_modules/playwright-core/lib/coreBundle.js +360 -256
  14. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/cli-client/help.json +9 -4
  15. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/cli-client/program.js +6 -1
  16. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/cli-client/session.js +10 -12
  17. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/utils/extension.js +8 -5
  18. package/vendor/playwright-cli/node_modules/playwright-core/lib/androidServerImpl.js +0 -65
  19. package/vendor/playwright-cli/node_modules/playwright-core/lib/browserServerImpl.js +0 -120
  20. package/vendor/playwright-cli/node_modules/playwright-core/lib/cli/driver.js +0 -98
  21. package/vendor/playwright-cli/node_modules/playwright-core/lib/cli/program.js +0 -597
  22. package/vendor/playwright-cli/node_modules/playwright-core/lib/cli/programWithTestStub.js +0 -74
  23. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/android.js +0 -361
  24. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/api.js +0 -137
  25. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/artifact.js +0 -79
  26. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/browser.js +0 -169
  27. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/browserContext.js +0 -583
  28. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/browserType.js +0 -153
  29. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/cdpSession.js +0 -55
  30. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/channelOwner.js +0 -194
  31. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/clientHelper.js +0 -64
  32. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/clientInstrumentation.js +0 -55
  33. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/clientStackTrace.js +0 -69
  34. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/clock.js +0 -68
  35. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/connect.js +0 -143
  36. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/connection.js +0 -322
  37. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/consoleMessage.js +0 -61
  38. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/coverage.js +0 -44
  39. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/debugger.js +0 -57
  40. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/dialog.js +0 -56
  41. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/disposable.js +0 -76
  42. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/download.js +0 -62
  43. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/electron.js +0 -138
  44. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/elementHandle.js +0 -281
  45. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/errors.js +0 -77
  46. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/eventEmitter.js +0 -314
  47. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/events.js +0 -103
  48. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/fetch.js +0 -367
  49. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/fileChooser.js +0 -46
  50. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/fileUtils.js +0 -34
  51. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/frame.js +0 -404
  52. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/harRouter.js +0 -99
  53. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/input.js +0 -84
  54. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/jsHandle.js +0 -105
  55. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/jsonPipe.js +0 -39
  56. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/localUtils.js +0 -60
  57. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/locator.js +0 -367
  58. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/network.js +0 -750
  59. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/page.js +0 -729
  60. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/platform.js +0 -77
  61. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/playwright.js +0 -71
  62. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/screencast.js +0 -48
  63. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/selectors.js +0 -57
  64. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/stream.js +0 -39
  65. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/timeoutSettings.js +0 -79
  66. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/tracing.js +0 -126
  67. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/types.js +0 -28
  68. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/video.js +0 -68
  69. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/waiter.js +0 -142
  70. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/webError.js +0 -39
  71. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/worker.js +0 -85
  72. package/vendor/playwright-cli/node_modules/playwright-core/lib/client/writableStream.js +0 -39
  73. package/vendor/playwright-cli/node_modules/playwright-core/lib/generated/bindingsControllerSource.js +0 -28
  74. package/vendor/playwright-cli/node_modules/playwright-core/lib/generated/clockSource.js +0 -28
  75. package/vendor/playwright-cli/node_modules/playwright-core/lib/generated/injectedScriptSource.js +0 -28
  76. package/vendor/playwright-cli/node_modules/playwright-core/lib/generated/pollingRecorderSource.js +0 -28
  77. package/vendor/playwright-cli/node_modules/playwright-core/lib/generated/storageScriptSource.js +0 -28
  78. package/vendor/playwright-cli/node_modules/playwright-core/lib/generated/utilityScriptSource.js +0 -28
  79. package/vendor/playwright-cli/node_modules/playwright-core/lib/generated/webSocketMockSource.js +0 -336
  80. package/vendor/playwright-cli/node_modules/playwright-core/lib/inProcessFactory.js +0 -60
  81. package/vendor/playwright-cli/node_modules/playwright-core/lib/inprocess.js +0 -3
  82. package/vendor/playwright-cli/node_modules/playwright-core/lib/mcpBundle.js +0 -81
  83. package/vendor/playwright-cli/node_modules/playwright-core/lib/mcpBundleImpl/index.js +0 -91
  84. package/vendor/playwright-cli/node_modules/playwright-core/lib/outofprocess.js +0 -76
  85. package/vendor/playwright-cli/node_modules/playwright-core/lib/protocol/serializers.js +0 -197
  86. package/vendor/playwright-cli/node_modules/playwright-core/lib/protocol/validator.js +0 -3034
  87. package/vendor/playwright-cli/node_modules/playwright-core/lib/protocol/validatorPrimitives.js +0 -193
  88. package/vendor/playwright-cli/node_modules/playwright-core/lib/remote/playwrightConnection.js +0 -131
  89. package/vendor/playwright-cli/node_modules/playwright-core/lib/remote/playwrightPipeServer.js +0 -100
  90. package/vendor/playwright-cli/node_modules/playwright-core/lib/remote/playwrightServer.js +0 -339
  91. package/vendor/playwright-cli/node_modules/playwright-core/lib/remote/playwrightWebSocketServer.js +0 -73
  92. package/vendor/playwright-cli/node_modules/playwright-core/lib/remote/serverTransport.js +0 -96
  93. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/android/android.js +0 -465
  94. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/android/backendAdb.js +0 -177
  95. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/artifact.js +0 -127
  96. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiBrowser.js +0 -571
  97. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiChromium.js +0 -162
  98. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiConnection.js +0 -213
  99. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiDeserializer.js +0 -116
  100. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiExecutionContext.js +0 -267
  101. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiFirefox.js +0 -128
  102. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiInput.js +0 -146
  103. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiNetworkManager.js +0 -411
  104. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiOverCdp.js +0 -102
  105. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiPage.js +0 -599
  106. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/bidiPdf.js +0 -106
  107. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/third_party/bidiCommands.d.js +0 -22
  108. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/third_party/bidiKeyboard.js +0 -256
  109. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/third_party/bidiProtocol.js +0 -24
  110. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/third_party/bidiProtocolCore.js +0 -180
  111. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/third_party/bidiProtocolPermissions.js +0 -42
  112. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/third_party/bidiSerializer.js +0 -148
  113. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/bidi/third_party/firefoxPrefs.js +0 -261
  114. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/browser.js +0 -223
  115. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/browserContext.js +0 -703
  116. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/browserType.js +0 -338
  117. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/callLog.js +0 -82
  118. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/chromium.js +0 -399
  119. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/chromiumSwitches.js +0 -104
  120. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crBrowser.js +0 -532
  121. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crConnection.js +0 -197
  122. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crCoverage.js +0 -235
  123. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crDevTools.js +0 -111
  124. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crDragDrop.js +0 -131
  125. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crExecutionContext.js +0 -146
  126. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crInput.js +0 -187
  127. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crNetworkManager.js +0 -708
  128. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crPage.js +0 -1004
  129. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crPdf.js +0 -121
  130. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crProtocolHelper.js +0 -145
  131. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/crServiceWorker.js +0 -137
  132. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/defaultFontFamilies.js +0 -162
  133. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/chromium/protocol.d.js +0 -16
  134. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/clock.js +0 -149
  135. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/codegen/csharp.js +0 -327
  136. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/codegen/java.js +0 -274
  137. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/codegen/javascript.js +0 -247
  138. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/codegen/jsonl.js +0 -52
  139. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/codegen/language.js +0 -132
  140. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/codegen/languages.js +0 -68
  141. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/codegen/python.js +0 -279
  142. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/codegen/types.js +0 -16
  143. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/console.js +0 -61
  144. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/cookieStore.js +0 -206
  145. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/debugController.js +0 -197
  146. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/debugger.js +0 -120
  147. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/deviceDescriptors.js +0 -39
  148. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dialog.js +0 -116
  149. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/androidDispatcher.js +0 -325
  150. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/artifactDispatcher.js +0 -118
  151. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/browserContextDispatcher.js +0 -381
  152. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/browserDispatcher.js +0 -124
  153. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/browserTypeDispatcher.js +0 -71
  154. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/cdpSessionDispatcher.js +0 -47
  155. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/debugControllerDispatcher.js +0 -78
  156. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/debuggerDispatcher.js +0 -80
  157. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/dialogDispatcher.js +0 -47
  158. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/dispatcher.js +0 -364
  159. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/disposableDispatcher.js +0 -39
  160. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/electronDispatcher.js +0 -90
  161. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/elementHandlerDispatcher.js +0 -181
  162. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/frameDispatcher.js +0 -227
  163. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/jsHandleDispatcher.js +0 -85
  164. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/jsonPipeDispatcher.js +0 -58
  165. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/localUtilsDispatcher.js +0 -185
  166. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/networkDispatchers.js +0 -214
  167. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/pageDispatcher.js +0 -434
  168. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/playwrightDispatcher.js +0 -108
  169. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/streamDispatcher.js +0 -67
  170. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/tracingDispatcher.js +0 -68
  171. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/webSocketRouteDispatcher.js +0 -164
  172. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dispatchers/writableStreamDispatcher.js +0 -79
  173. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/disposable.js +0 -41
  174. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/dom.js +0 -823
  175. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/download.js +0 -71
  176. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/electron/electron.js +0 -272
  177. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/electron/loader.js +0 -115
  178. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/errors.js +0 -69
  179. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/fetch.js +0 -621
  180. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/fileChooser.js +0 -43
  181. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/fileUploadUtils.js +0 -84
  182. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/firefox/ffBrowser.js +0 -415
  183. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/firefox/ffConnection.js +0 -142
  184. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/firefox/ffExecutionContext.js +0 -150
  185. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/firefox/ffInput.js +0 -175
  186. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/firefox/ffNetworkManager.js +0 -256
  187. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/firefox/ffPage.js +0 -495
  188. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/firefox/firefox.js +0 -114
  189. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/firefox/protocol.d.js +0 -16
  190. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/formData.js +0 -147
  191. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/frameSelectors.js +0 -160
  192. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/frames.js +0 -1495
  193. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/har/harRecorder.js +0 -147
  194. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/har/harTracer.js +0 -608
  195. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/harBackend.js +0 -157
  196. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/helper.js +0 -96
  197. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/index.js +0 -58
  198. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/input.js +0 -277
  199. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/instrumentation.js +0 -72
  200. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/javascript.js +0 -291
  201. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/launchApp.js +0 -127
  202. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/localUtils.js +0 -214
  203. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/macEditingCommands.js +0 -143
  204. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/network.js +0 -668
  205. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/page.js +0 -884
  206. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/pipeTransport.js +0 -89
  207. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/playwright.js +0 -69
  208. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/progress.js +0 -136
  209. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/protocolError.js +0 -52
  210. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/recorder/chat.js +0 -161
  211. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/recorder/recorderApp.js +0 -367
  212. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/recorder/recorderRunner.js +0 -138
  213. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/recorder/recorderSignalProcessor.js +0 -83
  214. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/recorder/recorderUtils.js +0 -157
  215. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/recorder/throttledFile.js +0 -57
  216. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/recorder.js +0 -540
  217. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/registry/browserFetcher.js +0 -177
  218. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/registry/dependencies.js +0 -371
  219. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/registry/index.js +0 -1395
  220. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/registry/nativeDeps.js +0 -1281
  221. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/registry/oopDownloadBrowserMain.js +0 -127
  222. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/screencast.js +0 -216
  223. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/screenshotter.js +0 -333
  224. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/selectors.js +0 -112
  225. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/socksClientCertificatesInterceptor.js +0 -383
  226. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/socksInterceptor.js +0 -95
  227. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/trace/recorder/snapshotter.js +0 -147
  228. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/trace/recorder/snapshotterInjected.js +0 -561
  229. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/trace/recorder/tracing.js +0 -607
  230. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/trace/viewer/traceViewer.js +0 -244
  231. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/transport.js +0 -181
  232. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/types.js +0 -28
  233. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/usKeyboardLayout.js +0 -152
  234. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/ascii.js +0 -44
  235. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/comparators.js +0 -139
  236. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/crypto.js +0 -216
  237. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/debug.js +0 -42
  238. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/debugLogger.js +0 -122
  239. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/disposable.js +0 -32
  240. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/env.js +0 -73
  241. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/eventsHelper.js +0 -41
  242. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/expectUtils.js +0 -123
  243. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/fileUtils.js +0 -191
  244. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/happyEyeballs.js +0 -207
  245. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/hostPlatform.js +0 -123
  246. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/httpServer.js +0 -205
  247. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/image_tools/colorUtils.js +0 -89
  248. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/image_tools/compare.js +0 -109
  249. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/image_tools/imageChannel.js +0 -78
  250. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/image_tools/stats.js +0 -102
  251. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/linuxUtils.js +0 -71
  252. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/network.js +0 -244
  253. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/nodePlatform.js +0 -154
  254. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/pipeTransport.js +0 -84
  255. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/processLauncher.js +0 -243
  256. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/profiler.js +0 -65
  257. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/socksProxy.js +0 -511
  258. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/spawnAsync.js +0 -41
  259. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/task.js +0 -51
  260. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/userAgent.js +0 -98
  261. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/wsServer.js +0 -121
  262. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/zipFile.js +0 -74
  263. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/utils/zones.js +0 -57
  264. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/videoRecorder.js +0 -133
  265. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/protocol.d.js +0 -16
  266. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/webkit.js +0 -108
  267. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/wkBrowser.js +0 -331
  268. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/wkConnection.js +0 -144
  269. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/wkExecutionContext.js +0 -154
  270. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/wkInput.js +0 -181
  271. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/wkInterceptableRequest.js +0 -197
  272. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/wkPage.js +0 -1164
  273. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/wkProvisionalPage.js +0 -83
  274. package/vendor/playwright-cli/node_modules/playwright-core/lib/server/webkit/wkWorkers.js +0 -106
  275. package/vendor/playwright-cli/node_modules/playwright-core/lib/third_party/pixelmatch.js +0 -255
  276. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/browserBackend.js +0 -79
  277. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/common.js +0 -63
  278. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/config.js +0 -41
  279. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/console.js +0 -66
  280. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/context.js +0 -290
  281. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/cookies.js +0 -152
  282. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/devtools.js +0 -69
  283. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/dialogs.js +0 -59
  284. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/evaluate.js +0 -64
  285. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/files.js +0 -60
  286. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/form.js +0 -64
  287. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/keyboard.js +0 -155
  288. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/logFile.js +0 -95
  289. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/mouse.js +0 -168
  290. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/navigate.js +0 -106
  291. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/network.js +0 -135
  292. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/pdf.js +0 -48
  293. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/response.js +0 -302
  294. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/route.js +0 -140
  295. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/runCode.js +0 -76
  296. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/screenshot.js +0 -88
  297. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/sessionLog.js +0 -74
  298. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/snapshot.js +0 -208
  299. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/storage.js +0 -67
  300. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/tab.js +0 -445
  301. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/tabs.js +0 -67
  302. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/tool.js +0 -47
  303. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/tools.js +0 -102
  304. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/tracing.js +0 -75
  305. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/utils.js +0 -83
  306. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/verify.js +0 -151
  307. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/video.js +0 -89
  308. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/wait.js +0 -63
  309. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/backend/webstorage.js +0 -223
  310. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/cli-daemon/command.js +0 -73
  311. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/cli-daemon/commands.js +0 -933
  312. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/cli-daemon/daemon.js +0 -178
  313. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/cli-daemon/helpGenerator.js +0 -173
  314. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/cli-daemon/program.js +0 -118
  315. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/dashboard/dashboardApp.js +0 -286
  316. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/dashboard/dashboardController.js +0 -296
  317. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/exports.js +0 -60
  318. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/browserFactory.js +0 -233
  319. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/cdpRelay.js +0 -356
  320. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/cli-stub.js +0 -7
  321. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/config.d.js +0 -16
  322. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/config.js +0 -401
  323. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/configIni.js +0 -189
  324. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/extensionContextFactory.js +0 -59
  325. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/index.js +0 -62
  326. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/log.js +0 -35
  327. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/program.js +0 -107
  328. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/protocol.js +0 -28
  329. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/mcp/watchdog.js +0 -44
  330. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/installSkill.js +0 -48
  331. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceActions.js +0 -142
  332. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceAttachments.js +0 -69
  333. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceCli.js +0 -80
  334. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceConsole.js +0 -97
  335. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceErrors.js +0 -55
  336. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceOpen.js +0 -69
  337. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceParser.js +0 -96
  338. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceRequests.js +0 -158
  339. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceScreenshot.js +0 -68
  340. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceSnapshot.js +0 -149
  341. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/trace/traceUtils.js +0 -135
  342. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/utils/connect.js +0 -32
  343. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/utils/mcp/http.js +0 -152
  344. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/utils/mcp/server.js +0 -230
  345. package/vendor/playwright-cli/node_modules/playwright-core/lib/tools/utils/mcp/tool.js +0 -47
  346. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/ariaSnapshot.js +0 -455
  347. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/assert.js +0 -31
  348. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/colors.js +0 -72
  349. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/cssParser.js +0 -245
  350. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/cssTokenizer.js +0 -1051
  351. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/formatUtils.js +0 -64
  352. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/headers.js +0 -53
  353. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/imageUtils.js +0 -141
  354. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/locatorGenerators.js +0 -689
  355. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/locatorParser.js +0 -176
  356. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/locatorUtils.js +0 -81
  357. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/lruCache.js +0 -51
  358. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/manualPromise.js +0 -114
  359. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/mimeType.js +0 -464
  360. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/multimap.js +0 -80
  361. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/protocolFormatter.js +0 -81
  362. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/protocolMetainfo.js +0 -342
  363. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/rtti.js +0 -43
  364. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/selectorParser.js +0 -386
  365. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/semaphore.js +0 -54
  366. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/stackTrace.js +0 -158
  367. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/stringUtils.js +0 -204
  368. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/time.js +0 -49
  369. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/timeoutRunner.js +0 -66
  370. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/entries.js +0 -16
  371. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/snapshotRenderer.js +0 -502
  372. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/snapshotServer.js +0 -120
  373. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/snapshotStorage.js +0 -89
  374. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/traceLoader.js +0 -131
  375. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/traceModel.js +0 -366
  376. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/traceModernizer.js +0 -401
  377. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/traceUtils.js +0 -58
  378. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV3.js +0 -16
  379. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV4.js +0 -16
  380. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV5.js +0 -16
  381. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV6.js +0 -16
  382. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV7.js +0 -16
  383. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV8.js +0 -16
  384. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/types.js +0 -16
  385. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/urlMatch.js +0 -243
  386. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/utilityScriptSerializers.js +0 -262
  387. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils/isomorphic/yaml.js +0 -84
  388. package/vendor/playwright-cli/node_modules/playwright-core/lib/utils.js +0 -113
  389. package/vendor/playwright-cli/node_modules/playwright-core/lib/utilsBundleImpl/index.js +0 -218
  390. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-BtGnd8kr.js +0 -32
  391. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-CnvO0fko.js +0 -32
  392. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-BkMbME_o.js +0 -262
  393. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-CN3cwLGD.js +0 -262
  394. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.B4dS75f0.css +0 -1
  395. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.DcQiWcKS.css +0 -1
  396. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/index.B2ffe31o.js +0 -2
  397. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/index.Df3uWWXm.js +0 -2
  398. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/uiMode.BZQ54Kgt.css +0 -1
  399. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/uiMode.CmAqMvmy.js +0 -6
  400. package/vendor/playwright-cli/node_modules/playwright-core/lib/vite/traceViewer/uiMode.u9Eas4CP.js +0 -6
  401. package/vendor/playwright-cli/node_modules/playwright-core/lib/zipBundle.js +0 -34
  402. package/vendor/playwright-cli/node_modules/playwright-core/lib/zipBundleImpl.js +0 -5
package/serve.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { receiveUpload, readRequestJson } from "./scoped-upload.js";
1
2
  import { readListeners, listenerAddress, authorizeProfileRequest, canReadProfileFile, profileOutputPrefix, normalizePrefix, resolveAllowedProfile, type Listener } from "./listeners.js";
2
3
  import { file } from "bun";
3
4
  import { createHash, X509Certificate } from "crypto";
@@ -18,6 +19,7 @@ import {
18
19
  readTokenRegistry,
19
20
  readChromeProfileCache,
20
21
  checkTailscaleServe,
22
+ chromeDataAccessHint,
21
23
  } from "./rechrome.js";
22
24
 
23
25
  const TAILSCALE_BIN = process.env.TAILSCALE_BIN || "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
@@ -121,6 +123,16 @@ export function provesRelayAlive(o: { stdout: string; stderr: string }): boolean
121
123
  return true;
122
124
  }
123
125
 
126
+ /**
127
+ * The relay checks Chrome's data folder for the installed extension before connecting. Under
128
+ * macOS TCC that read fails and it reports "Playwright Extension not found" although the
129
+ * extension is installed — name the real cause instead of sending the user to reinstall.
130
+ */
131
+ export function explainExtensionNotFound(output: string, accessProblem: string | undefined): string | undefined {
132
+ if (!accessProblem || !/Playwright Extension not found in/i.test(output)) return undefined;
133
+ return `[rech] the extension is probably installed; this daemon ${accessProblem}\n`;
134
+ }
135
+
124
136
  export function inferSilentExtensionFailure(options: {
125
137
  status: number;
126
138
  stdout: string;
@@ -255,24 +267,63 @@ export function splitCommand(cmd: string): string[] {
255
267
  t.startsWith('"') && t.endsWith('"') ? t.slice(1, -1) : t);
256
268
  }
257
269
 
258
- async function resolveProfileDirectory(nameOrEmail: string): Promise<string> {
270
+ /** Why this daemon cannot read Chrome's data folder; reported by /ping so `rech status` shows it. */
271
+ let chromeAccessProblem: string | undefined;
272
+ /** Log (once) why Chrome's data folder is unreadable — under launchd/oxmgr on macOS this is TCC. */
273
+ export function warnChromeDataAccess(path: string, error: unknown): void {
274
+ if (chromeAccessProblem) return;
275
+ const message = error instanceof Error ? error.message : String(error);
276
+ chromeAccessProblem = `cannot read ${path} (${message}). ${chromeDataAccessHint(error) ?? "Profile names and emails cannot be resolved here."}`;
277
+ log(chromeAccessProblem);
278
+ }
279
+
280
+ /** A profile name or email could not be mapped to its Chrome folder because Local State is unreadable. */
281
+ export class ProfileResolutionError extends Error {
282
+ constructor(readonly profile: string, statePath: string, cause: unknown) {
283
+ const message = cause instanceof Error ? cause.message : String(cause);
284
+ const hint = chromeDataAccessHint(cause);
285
+ super(`[rech] cannot find the Chrome folder for profile "${profile}": ${statePath} is unreadable (${message}). Refusing, so Chrome does not create a new empty profile named "${profile}".\n`
286
+ + ` Register it once (records its folder in ~/.rechrome): rech setup --profile ${JSON.stringify(profile)}\n`
287
+ + ` Or select the folder directly, e.g. rech --profile "Profile 1" …\n`
288
+ + (hint ? ` ${hint}\n` : ""));
289
+ this.name = "ProfileResolutionError";
290
+ }
291
+ }
292
+
293
+ export async function resolveProfileDirectory(
294
+ nameOrEmail: string,
295
+ registry?: Record<string, { profileDir?: string }>,
296
+ statePaths: string[] = [
297
+ join(HOME || "~", "Library/Application Support/Google/Chrome/Local State"),
298
+ join(HOME || "~", ".config/google-chrome/Local State"),
299
+ join(HOME || "~", "AppData/Local/Google/Chrome/User Data/Local State"),
300
+ ],
301
+ ): Promise<string> {
259
302
  if (/^(Default|Profile \d+)$/i.test(nameOrEmail)) return nameOrEmail;
260
- const home = HOME || "~";
261
- const candidates = [
262
- join(home, "Library/Application Support/Google/Chrome/Local State"),
263
- join(home, ".config/google-chrome/Local State"),
264
- join(home, "AppData/Local/Google/Chrome/User Data/Local State"),
265
- ];
266
- for (const statePath of candidates) {
267
- const f = file(statePath);
268
- if (!(await f.exists())) continue;
269
- const data = JSON.parse(await f.text());
270
- const cache: Record<string, any> = data?.profile?.info_cache ?? {};
271
- for (const [dir, info] of Object.entries(cache)) {
272
- if ([info.name, info.user_name, info.gaia_name].includes(nameOrEmail))
273
- return dir;
303
+ // setup recorded each registered profile's folder in ~/.rechrome, which macOS privacy (TCC)
304
+ // never guards, so a launchd/oxmgr daemon resolves it without touching Chrome's data folder.
305
+ const entry = (registry ?? await readTokenRegistry().catch(() => ({})) as Record<string, { profileDir?: string }>)[nameOrEmail];
306
+ if (entry?.profileDir) return entry.profileDir;
307
+ let unreadable: { path: string; error: unknown } | undefined;
308
+ for (const statePath of statePaths) {
309
+ try {
310
+ // Read without an exists() probe: under TCC the stat fails too, and exists() would report
311
+ // "missing" and hide the denial.
312
+ const data = JSON.parse(await file(statePath).text());
313
+ const cache: Record<string, any> = data?.profile?.info_cache ?? {};
314
+ for (const [dir, info] of Object.entries(cache)) {
315
+ if ([info.name, info.user_name, info.gaia_name].includes(nameOrEmail))
316
+ return dir;
317
+ }
318
+ } catch (error) {
319
+ if ((error as NodeJS.ErrnoException)?.code === "ENOENT") continue;
320
+ warnChromeDataAccess(statePath, error);
321
+ unreadable ??= { path: statePath, error };
274
322
  }
275
323
  }
324
+ // Passing an email or display name through would make Chrome create a NEW empty profile folder
325
+ // literally named after it (--profile-directory=me@example.com) instead of opening the real one.
326
+ if (unreadable) throw new ProfileResolutionError(nameOrEmail, unreadable.path, unreadable.error);
276
327
  return nameOrEmail;
277
328
  }
278
329
 
@@ -396,15 +447,34 @@ async function freeStalePort(port: number, host: string): Promise<void> {
396
447
  // the leak self-heals. /ping is deliberately NOT activity (the tray polls it every 2s
397
448
  // and would otherwise keep an orphan alive forever).
398
449
  const ORPHAN_POLL_INTERVAL_MS = 15_000;
399
- const ORPHAN_IDLE_EXIT_MS = Number(process.env.RECH_SERVE_IDLE_TIMEOUT_MS) || 5 * 60_000;
450
+ const ORPHAN_IDLE_EXIT_MS = parseIdleTimeout(process.env.RECH_SERVE_IDLE_TIMEOUT_MS);
451
+
452
+ // `RECH_SERVE_IDLE_TIMEOUT_MS=0` must disable self-exit; `Number(v) || default` turned 0 back into 5 min.
453
+ export function parseIdleTimeout(raw: string | undefined, fallback = 5 * 60_000): number {
454
+ if (raw === undefined || raw.trim() === "") return fallback;
455
+ const value = Number(raw);
456
+ return Number.isFinite(value) ? value : fallback;
457
+ }
458
+
459
+ // A supervisor owns this serve's lifetime, so it is never a leaked foreground serve:
460
+ // RECH_SERVE_MANAGED=1 (set by `rech setup`'s oxmgr/pm2 install), or a LaunchAgent — launchd
461
+ // starts it with ppid 1 and its job label in XPC_SERVICE_NAME. ppid 1 alone is not enough:
462
+ // `setsid rech serve` or `(rech serve &)` also starts with ppid 1 and must still self-exit.
463
+ // Terminal apps set XPC_SERVICE_NAME to "0" or "application.<bundle id>…".
464
+ export function isManagedServe(startPpid: number, env: Record<string, string | undefined> = process.env): boolean {
465
+ if (env.RECH_SERVE_MANAGED === "1") return true;
466
+ const label = env.XPC_SERVICE_NAME;
467
+ return startPpid === 1 && !!label && label !== "0" && !label.startsWith("application.");
468
+ }
400
469
 
401
470
  // Pure decision predicate (testable). idleTimeoutMs <= 0 disables orphan self-exit.
402
471
  export function shouldExitOrphanedServe(opts: {
403
472
  orphaned: boolean;
404
473
  idleMs: number;
405
474
  idleTimeoutMs: number;
475
+ managed?: boolean;
406
476
  }): boolean {
407
- return opts.idleTimeoutMs > 0 && opts.orphaned && opts.idleMs >= opts.idleTimeoutMs;
477
+ return !opts.managed && opts.idleTimeoutMs > 0 && opts.orphaned && opts.idleMs >= opts.idleTimeoutMs;
408
478
  }
409
479
 
410
480
  export const LANDING_HEADERS = {
@@ -532,14 +602,24 @@ export async function serve() {
532
602
  let orphaned = false;
533
603
  let idleSince = Date.now();
534
604
  const markActivity = () => { idleSince = Date.now(); };
605
+ const managed = isManagedServe(process.ppid);
606
+ if (managed) log("serve is supervised (launchd, a process manager, or RECH_SERVE_MANAGED=1) — idle self-exit disabled");
535
607
  setInterval(() => {
536
608
  if (process.ppid === 1) orphaned = true;
537
- if (shouldExitOrphanedServe({ orphaned, idleMs: Date.now() - idleSince, idleTimeoutMs: ORPHAN_IDLE_EXIT_MS })) {
609
+ if (shouldExitOrphanedServe({ orphaned, managed, idleMs: Date.now() - idleSince, idleTimeoutMs: ORPHAN_IDLE_EXIT_MS })) {
538
610
  log(`orphaned foreground serve idle ${Math.round((Date.now() - idleSince) / 1000)}s — exiting (spawning agent is gone)`);
539
611
  process.exit(0);
540
612
  }
541
613
  }, ORPHAN_POLL_INTERVAL_MS);
542
614
 
615
+ // Say at startup, not on the first failed open, when macOS privacy blocks Chrome's data folder.
616
+ if (process.platform === "darwin") {
617
+ const chromeDir = join(HOME, "Library/Application Support/Google/Chrome");
618
+ try { readdirSync(chromeDir); } catch (error) {
619
+ if ((error as { code?: string }).code !== "ENOENT") warnChromeDataAccess(chromeDir, error);
620
+ }
621
+ }
622
+
543
623
  // Reap idle --isolate sessions so single-shot OAuth/login drives don't leak browser contexts.
544
624
  adoptOrphanedIsoSessions();
545
625
  setInterval(() => {
@@ -614,12 +694,12 @@ export async function serve() {
614
694
  // clients / `rech status` can see trouble without an active probe.
615
695
  const degraded = consecutiveTimeouts > 0;
616
696
  if (scoped || !reqUrl.searchParams.get("deep"))
617
- return Response.json({ ok: true, bind: listenHost, listener: listener.name, profiles: listener.profiles, multiListener: true, consecutiveTimeouts, degraded });
697
+ return Response.json({ ok: true, bind: listenHost, listener: listener.name, profiles: listener.profiles, multiListener: true, consecutiveTimeouts, degraded, chromeAccessProblem });
618
698
  // Deep probe: exercise the relay read-only via `tab-list` (opens nothing) against the
619
699
  // most-recently-used session — never a fresh one, which could spawn a browser window.
620
700
  const target = [...recentSessions.entries()].sort((a, b) => b[1] - a[1])[0]?.[0];
621
701
  if (!target)
622
- return Response.json({ ok: true, bind: listenHost, relay: "idle", consecutiveTimeouts, degraded });
702
+ return Response.json({ ok: true, bind: listenHost, relay: "idle", consecutiveTimeouts, degraded, chromeAccessProblem });
623
703
  const [pbin, ...pbinArgs] = splitCommand(resolvePlaywrightCli());
624
704
  const probe = Bun.spawn([pbin, ...pbinArgs, "tab-list", `-s=${target}`], {
625
705
  cwd: workDir, stdin: "ignore", stdout: "ignore", stderr: "ignore",
@@ -633,7 +713,7 @@ export async function serve() {
633
713
  const healthy = probeStatus !== -1;
634
714
  return Response.json({
635
715
  ok: healthy, bind: listenHost, relay: healthy ? "healthy" : "degraded",
636
- consecutiveTimeouts, degraded: degraded || !healthy,
716
+ consecutiveTimeouts, degraded: degraded || !healthy, chromeAccessProblem,
637
717
  });
638
718
  }
639
719
  // A browser opening a shared URL gets copyable connect instructions. The key stays in the
@@ -645,7 +725,9 @@ export async function serve() {
645
725
  if (denied) return denied;
646
726
  markActivity(); // a real command: this serve is not idle
647
727
 
648
- const body = await req.json();
728
+ let body: any;
729
+ try { body = await readRequestJson(req); }
730
+ catch { return Response.json({ status: 1, stdout: "", stderr: "Invalid JSON or request exceeds 3 MiB\n" }, { status: 400 }); }
649
731
  let scopedProfile: string | undefined;
650
732
  let profileEnv: Record<string, string> = {};
651
733
  if (scoped) {
@@ -674,7 +756,11 @@ export async function serve() {
674
756
  };
675
757
  body.identity.key = `scoped:${body.identity.key}`;
676
758
  body.env = {}; // Server-owned profile configuration wins over every client override.
677
- } catch (error) { return Response.json({ status: 1, stdout: "", stderr: `${error instanceof Error ? error.message : String(error)}\n` }, { status: 403 }); }
759
+ } catch (error) {
760
+ if (Array.isArray(body?.args) && body.args.filter((a: unknown) => typeof a !== "string" || !/^-s=[a-zA-Z0-9_-]{1,64}$/.test(a))[0] === "upload")
761
+ log(`upload: ${JSON.stringify({ listener: listener.name, profile: scopedProfile ?? null, name: typeof body.upload?.name === "string" ? body.upload.name.slice(0, 128) : null, size: null, sha256: null, origin: null, result: "rejected" })}`);
762
+ return Response.json({ status: 1, stdout: "", stderr: `${error instanceof Error ? error.message : String(error)}\n` }, { status: 403 });
763
+ }
678
764
  }
679
765
  const outputPrefix = scopedProfile ? profileOutputPrefix(scopedProfile) : "";
680
766
  const runWorkDir = scopedProfile ? join(workDir, outputPrefix) : workDir;
@@ -758,7 +844,14 @@ export async function serve() {
758
844
 
759
845
  // Resolve profile name/email → directory name
760
846
  if (!scoped && passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY) {
761
- const resolved = await resolveProfileDirectory(passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY);
847
+ let resolved: string;
848
+ try {
849
+ resolved = await resolveProfileDirectory(passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY);
850
+ } catch (error) {
851
+ if (!(error instanceof ProfileResolutionError)) throw error;
852
+ log(`refused unresolvable profile "${error.profile}" (session=${namespacedSession})`);
853
+ return Response.json({ status: 1, stdout: "", stderr: error.message, files: [] });
854
+ }
762
855
  if (resolved !== passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY)
763
856
  log(`profile resolved: "${passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY}" → "${resolved}"`);
764
857
  passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY = resolved;
@@ -829,6 +922,27 @@ export async function serve() {
829
922
  ? { PLAYWRIGHT_MCP_EXTENSION: "1" }
830
923
  : {}),
831
924
  };
925
+ if (filteredArgs[0] === "upload") {
926
+ const result = await receiveUpload({
927
+ policy: listener.uploads, payload: body.upload, args: filteredArgs,
928
+ audit: event => log(`upload: ${JSON.stringify({ listener: listener.name, profile: scopedProfile ?? body.identity?.profile ?? null, ...event })}`),
929
+ run: async uploadArgs => {
930
+ const child = Bun.spawn([bin, ...binArgs, ...uploadArgs, `-s=${namespacedSession}`], {
931
+ cwd: runWorkDir, stdin: "ignore", stdout: "pipe", stderr: "pipe", windowsHide: true, env: playwrightCliEnv(childEnv),
932
+ });
933
+ let timer: ReturnType<typeof setTimeout> | undefined;
934
+ try {
935
+ const result = Promise.all([child.exited, new Response(child.stdout).text(), new Response(child.stderr).text()]);
936
+ const [status, stdout, stderr] = await Promise.race([result, new Promise<never>((_, reject) => {
937
+ timer = setTimeout(() => { child.kill(); reject(new Error("Upload command timed out")); }, 30_000);
938
+ })]);
939
+ return { status, stdout, stderr };
940
+ } finally { clearTimeout(timer); }
941
+ },
942
+ });
943
+ return Response.json({ ...result, files: [] });
944
+ }
945
+
832
946
  // Only a remaining open needs cleanup; a successful probe converted it to
833
947
  // goto and its live daemon socket must remain reachable.
834
948
  if (filteredArgs[0] === "open") {
@@ -879,7 +993,8 @@ export async function serve() {
879
993
  const handshakeTimeoutMs = Number.isFinite(configuredHandshakeTimeout) && configuredHandshakeTimeout > 0
880
994
  ? configuredHandshakeTimeout
881
995
  : 30_000;
882
- const stderr = inferSilentExtensionFailure({
996
+ const tccNote = explainExtensionNotFound(`${stdout}\n${rawStderr}`, chromeAccessProblem);
997
+ const stderr = (tccNote ?? "") + inferSilentExtensionFailure({
883
998
  status,
884
999
  stdout,
885
1000
  stderr: rawStderr,
package/serve.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { receiveUpload, readRequestJson } from "./scoped-upload.ts";
1
2
  import { readListeners, listenerAddress, authorizeProfileRequest, canReadProfileFile, profileOutputPrefix, normalizePrefix, resolveAllowedProfile, type Listener } from "./listeners.ts";
2
3
  import { file } from "bun";
3
4
  import { createHash, X509Certificate } from "crypto";
@@ -18,6 +19,7 @@ import {
18
19
  readTokenRegistry,
19
20
  readChromeProfileCache,
20
21
  checkTailscaleServe,
22
+ chromeDataAccessHint,
21
23
  } from "./rechrome.ts";
22
24
 
23
25
  const TAILSCALE_BIN = process.env.TAILSCALE_BIN || "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
@@ -121,6 +123,16 @@ export function provesRelayAlive(o: { stdout: string; stderr: string }): boolean
121
123
  return true;
122
124
  }
123
125
 
126
+ /**
127
+ * The relay checks Chrome's data folder for the installed extension before connecting. Under
128
+ * macOS TCC that read fails and it reports "Playwright Extension not found" although the
129
+ * extension is installed — name the real cause instead of sending the user to reinstall.
130
+ */
131
+ export function explainExtensionNotFound(output: string, accessProblem: string | undefined): string | undefined {
132
+ if (!accessProblem || !/Playwright Extension not found in/i.test(output)) return undefined;
133
+ return `[rech] the extension is probably installed; this daemon ${accessProblem}\n`;
134
+ }
135
+
124
136
  export function inferSilentExtensionFailure(options: {
125
137
  status: number;
126
138
  stdout: string;
@@ -255,24 +267,63 @@ export function splitCommand(cmd: string): string[] {
255
267
  t.startsWith('"') && t.endsWith('"') ? t.slice(1, -1) : t);
256
268
  }
257
269
 
258
- async function resolveProfileDirectory(nameOrEmail: string): Promise<string> {
270
+ /** Why this daemon cannot read Chrome's data folder; reported by /ping so `rech status` shows it. */
271
+ let chromeAccessProblem: string | undefined;
272
+ /** Log (once) why Chrome's data folder is unreadable — under launchd/oxmgr on macOS this is TCC. */
273
+ export function warnChromeDataAccess(path: string, error: unknown): void {
274
+ if (chromeAccessProblem) return;
275
+ const message = error instanceof Error ? error.message : String(error);
276
+ chromeAccessProblem = `cannot read ${path} (${message}). ${chromeDataAccessHint(error) ?? "Profile names and emails cannot be resolved here."}`;
277
+ log(chromeAccessProblem);
278
+ }
279
+
280
+ /** A profile name or email could not be mapped to its Chrome folder because Local State is unreadable. */
281
+ export class ProfileResolutionError extends Error {
282
+ constructor(readonly profile: string, statePath: string, cause: unknown) {
283
+ const message = cause instanceof Error ? cause.message : String(cause);
284
+ const hint = chromeDataAccessHint(cause);
285
+ super(`[rech] cannot find the Chrome folder for profile "${profile}": ${statePath} is unreadable (${message}). Refusing, so Chrome does not create a new empty profile named "${profile}".\n`
286
+ + ` Register it once (records its folder in ~/.rechrome): rech setup --profile ${JSON.stringify(profile)}\n`
287
+ + ` Or select the folder directly, e.g. rech --profile "Profile 1" …\n`
288
+ + (hint ? ` ${hint}\n` : ""));
289
+ this.name = "ProfileResolutionError";
290
+ }
291
+ }
292
+
293
+ export async function resolveProfileDirectory(
294
+ nameOrEmail: string,
295
+ registry?: Record<string, { profileDir?: string }>,
296
+ statePaths: string[] = [
297
+ join(HOME || "~", "Library/Application Support/Google/Chrome/Local State"),
298
+ join(HOME || "~", ".config/google-chrome/Local State"),
299
+ join(HOME || "~", "AppData/Local/Google/Chrome/User Data/Local State"),
300
+ ],
301
+ ): Promise<string> {
259
302
  if (/^(Default|Profile \d+)$/i.test(nameOrEmail)) return nameOrEmail;
260
- const home = HOME || "~";
261
- const candidates = [
262
- join(home, "Library/Application Support/Google/Chrome/Local State"),
263
- join(home, ".config/google-chrome/Local State"),
264
- join(home, "AppData/Local/Google/Chrome/User Data/Local State"),
265
- ];
266
- for (const statePath of candidates) {
267
- const f = file(statePath);
268
- if (!(await f.exists())) continue;
269
- const data = JSON.parse(await f.text());
270
- const cache: Record<string, any> = data?.profile?.info_cache ?? {};
271
- for (const [dir, info] of Object.entries(cache)) {
272
- if ([info.name, info.user_name, info.gaia_name].includes(nameOrEmail))
273
- return dir;
303
+ // setup recorded each registered profile's folder in ~/.rechrome, which macOS privacy (TCC)
304
+ // never guards, so a launchd/oxmgr daemon resolves it without touching Chrome's data folder.
305
+ const entry = (registry ?? await readTokenRegistry().catch(() => ({})) as Record<string, { profileDir?: string }>)[nameOrEmail];
306
+ if (entry?.profileDir) return entry.profileDir;
307
+ let unreadable: { path: string; error: unknown } | undefined;
308
+ for (const statePath of statePaths) {
309
+ try {
310
+ // Read without an exists() probe: under TCC the stat fails too, and exists() would report
311
+ // "missing" and hide the denial.
312
+ const data = JSON.parse(await file(statePath).text());
313
+ const cache: Record<string, any> = data?.profile?.info_cache ?? {};
314
+ for (const [dir, info] of Object.entries(cache)) {
315
+ if ([info.name, info.user_name, info.gaia_name].includes(nameOrEmail))
316
+ return dir;
317
+ }
318
+ } catch (error) {
319
+ if ((error as NodeJS.ErrnoException)?.code === "ENOENT") continue;
320
+ warnChromeDataAccess(statePath, error);
321
+ unreadable ??= { path: statePath, error };
274
322
  }
275
323
  }
324
+ // Passing an email or display name through would make Chrome create a NEW empty profile folder
325
+ // literally named after it (--profile-directory=me@example.com) instead of opening the real one.
326
+ if (unreadable) throw new ProfileResolutionError(nameOrEmail, unreadable.path, unreadable.error);
276
327
  return nameOrEmail;
277
328
  }
278
329
 
@@ -396,15 +447,34 @@ async function freeStalePort(port: number, host: string): Promise<void> {
396
447
  // the leak self-heals. /ping is deliberately NOT activity (the tray polls it every 2s
397
448
  // and would otherwise keep an orphan alive forever).
398
449
  const ORPHAN_POLL_INTERVAL_MS = 15_000;
399
- const ORPHAN_IDLE_EXIT_MS = Number(process.env.RECH_SERVE_IDLE_TIMEOUT_MS) || 5 * 60_000;
450
+ const ORPHAN_IDLE_EXIT_MS = parseIdleTimeout(process.env.RECH_SERVE_IDLE_TIMEOUT_MS);
451
+
452
+ // `RECH_SERVE_IDLE_TIMEOUT_MS=0` must disable self-exit; `Number(v) || default` turned 0 back into 5 min.
453
+ export function parseIdleTimeout(raw: string | undefined, fallback = 5 * 60_000): number {
454
+ if (raw === undefined || raw.trim() === "") return fallback;
455
+ const value = Number(raw);
456
+ return Number.isFinite(value) ? value : fallback;
457
+ }
458
+
459
+ // A supervisor owns this serve's lifetime, so it is never a leaked foreground serve:
460
+ // RECH_SERVE_MANAGED=1 (set by `rech setup`'s oxmgr/pm2 install), or a LaunchAgent — launchd
461
+ // starts it with ppid 1 and its job label in XPC_SERVICE_NAME. ppid 1 alone is not enough:
462
+ // `setsid rech serve` or `(rech serve &)` also starts with ppid 1 and must still self-exit.
463
+ // Terminal apps set XPC_SERVICE_NAME to "0" or "application.<bundle id>…".
464
+ export function isManagedServe(startPpid: number, env: Record<string, string | undefined> = process.env): boolean {
465
+ if (env.RECH_SERVE_MANAGED === "1") return true;
466
+ const label = env.XPC_SERVICE_NAME;
467
+ return startPpid === 1 && !!label && label !== "0" && !label.startsWith("application.");
468
+ }
400
469
 
401
470
  // Pure decision predicate (testable). idleTimeoutMs <= 0 disables orphan self-exit.
402
471
  export function shouldExitOrphanedServe(opts: {
403
472
  orphaned: boolean;
404
473
  idleMs: number;
405
474
  idleTimeoutMs: number;
475
+ managed?: boolean;
406
476
  }): boolean {
407
- return opts.idleTimeoutMs > 0 && opts.orphaned && opts.idleMs >= opts.idleTimeoutMs;
477
+ return !opts.managed && opts.idleTimeoutMs > 0 && opts.orphaned && opts.idleMs >= opts.idleTimeoutMs;
408
478
  }
409
479
 
410
480
  export const LANDING_HEADERS = {
@@ -532,14 +602,24 @@ export async function serve() {
532
602
  let orphaned = false;
533
603
  let idleSince = Date.now();
534
604
  const markActivity = () => { idleSince = Date.now(); };
605
+ const managed = isManagedServe(process.ppid);
606
+ if (managed) log("serve is supervised (launchd, a process manager, or RECH_SERVE_MANAGED=1) — idle self-exit disabled");
535
607
  setInterval(() => {
536
608
  if (process.ppid === 1) orphaned = true;
537
- if (shouldExitOrphanedServe({ orphaned, idleMs: Date.now() - idleSince, idleTimeoutMs: ORPHAN_IDLE_EXIT_MS })) {
609
+ if (shouldExitOrphanedServe({ orphaned, managed, idleMs: Date.now() - idleSince, idleTimeoutMs: ORPHAN_IDLE_EXIT_MS })) {
538
610
  log(`orphaned foreground serve idle ${Math.round((Date.now() - idleSince) / 1000)}s — exiting (spawning agent is gone)`);
539
611
  process.exit(0);
540
612
  }
541
613
  }, ORPHAN_POLL_INTERVAL_MS);
542
614
 
615
+ // Say at startup, not on the first failed open, when macOS privacy blocks Chrome's data folder.
616
+ if (process.platform === "darwin") {
617
+ const chromeDir = join(HOME, "Library/Application Support/Google/Chrome");
618
+ try { readdirSync(chromeDir); } catch (error) {
619
+ if ((error as { code?: string }).code !== "ENOENT") warnChromeDataAccess(chromeDir, error);
620
+ }
621
+ }
622
+
543
623
  // Reap idle --isolate sessions so single-shot OAuth/login drives don't leak browser contexts.
544
624
  adoptOrphanedIsoSessions();
545
625
  setInterval(() => {
@@ -614,12 +694,12 @@ export async function serve() {
614
694
  // clients / `rech status` can see trouble without an active probe.
615
695
  const degraded = consecutiveTimeouts > 0;
616
696
  if (scoped || !reqUrl.searchParams.get("deep"))
617
- return Response.json({ ok: true, bind: listenHost, listener: listener.name, profiles: listener.profiles, multiListener: true, consecutiveTimeouts, degraded });
697
+ return Response.json({ ok: true, bind: listenHost, listener: listener.name, profiles: listener.profiles, multiListener: true, consecutiveTimeouts, degraded, chromeAccessProblem });
618
698
  // Deep probe: exercise the relay read-only via `tab-list` (opens nothing) against the
619
699
  // most-recently-used session — never a fresh one, which could spawn a browser window.
620
700
  const target = [...recentSessions.entries()].sort((a, b) => b[1] - a[1])[0]?.[0];
621
701
  if (!target)
622
- return Response.json({ ok: true, bind: listenHost, relay: "idle", consecutiveTimeouts, degraded });
702
+ return Response.json({ ok: true, bind: listenHost, relay: "idle", consecutiveTimeouts, degraded, chromeAccessProblem });
623
703
  const [pbin, ...pbinArgs] = splitCommand(resolvePlaywrightCli());
624
704
  const probe = Bun.spawn([pbin, ...pbinArgs, "tab-list", `-s=${target}`], {
625
705
  cwd: workDir, stdin: "ignore", stdout: "ignore", stderr: "ignore",
@@ -633,7 +713,7 @@ export async function serve() {
633
713
  const healthy = probeStatus !== -1;
634
714
  return Response.json({
635
715
  ok: healthy, bind: listenHost, relay: healthy ? "healthy" : "degraded",
636
- consecutiveTimeouts, degraded: degraded || !healthy,
716
+ consecutiveTimeouts, degraded: degraded || !healthy, chromeAccessProblem,
637
717
  });
638
718
  }
639
719
  // A browser opening a shared URL gets copyable connect instructions. The key stays in the
@@ -645,7 +725,9 @@ export async function serve() {
645
725
  if (denied) return denied;
646
726
  markActivity(); // a real command: this serve is not idle
647
727
 
648
- const body = await req.json();
728
+ let body: any;
729
+ try { body = await readRequestJson(req); }
730
+ catch { return Response.json({ status: 1, stdout: "", stderr: "Invalid JSON or request exceeds 3 MiB\n" }, { status: 400 }); }
649
731
  let scopedProfile: string | undefined;
650
732
  let profileEnv: Record<string, string> = {};
651
733
  if (scoped) {
@@ -674,7 +756,11 @@ export async function serve() {
674
756
  };
675
757
  body.identity.key = `scoped:${body.identity.key}`;
676
758
  body.env = {}; // Server-owned profile configuration wins over every client override.
677
- } catch (error) { return Response.json({ status: 1, stdout: "", stderr: `${error instanceof Error ? error.message : String(error)}\n` }, { status: 403 }); }
759
+ } catch (error) {
760
+ if (Array.isArray(body?.args) && body.args.filter((a: unknown) => typeof a !== "string" || !/^-s=[a-zA-Z0-9_-]{1,64}$/.test(a))[0] === "upload")
761
+ log(`upload: ${JSON.stringify({ listener: listener.name, profile: scopedProfile ?? null, name: typeof body.upload?.name === "string" ? body.upload.name.slice(0, 128) : null, size: null, sha256: null, origin: null, result: "rejected" })}`);
762
+ return Response.json({ status: 1, stdout: "", stderr: `${error instanceof Error ? error.message : String(error)}\n` }, { status: 403 });
763
+ }
678
764
  }
679
765
  const outputPrefix = scopedProfile ? profileOutputPrefix(scopedProfile) : "";
680
766
  const runWorkDir = scopedProfile ? join(workDir, outputPrefix) : workDir;
@@ -758,7 +844,14 @@ export async function serve() {
758
844
 
759
845
  // Resolve profile name/email → directory name
760
846
  if (!scoped && passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY) {
761
- const resolved = await resolveProfileDirectory(passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY);
847
+ let resolved: string;
848
+ try {
849
+ resolved = await resolveProfileDirectory(passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY);
850
+ } catch (error) {
851
+ if (!(error instanceof ProfileResolutionError)) throw error;
852
+ log(`refused unresolvable profile "${error.profile}" (session=${namespacedSession})`);
853
+ return Response.json({ status: 1, stdout: "", stderr: error.message, files: [] });
854
+ }
762
855
  if (resolved !== passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY)
763
856
  log(`profile resolved: "${passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY}" → "${resolved}"`);
764
857
  passthroughEnv.PLAYWRIGHT_MCP_PROFILE_DIRECTORY = resolved;
@@ -829,6 +922,27 @@ export async function serve() {
829
922
  ? { PLAYWRIGHT_MCP_EXTENSION: "1" }
830
923
  : {}),
831
924
  };
925
+ if (filteredArgs[0] === "upload") {
926
+ const result = await receiveUpload({
927
+ policy: listener.uploads, payload: body.upload, args: filteredArgs,
928
+ audit: event => log(`upload: ${JSON.stringify({ listener: listener.name, profile: scopedProfile ?? body.identity?.profile ?? null, ...event })}`),
929
+ run: async uploadArgs => {
930
+ const child = Bun.spawn([bin, ...binArgs, ...uploadArgs, `-s=${namespacedSession}`], {
931
+ cwd: runWorkDir, stdin: "ignore", stdout: "pipe", stderr: "pipe", windowsHide: true, env: playwrightCliEnv(childEnv),
932
+ });
933
+ let timer: ReturnType<typeof setTimeout> | undefined;
934
+ try {
935
+ const result = Promise.all([child.exited, new Response(child.stdout).text(), new Response(child.stderr).text()]);
936
+ const [status, stdout, stderr] = await Promise.race([result, new Promise<never>((_, reject) => {
937
+ timer = setTimeout(() => { child.kill(); reject(new Error("Upload command timed out")); }, 30_000);
938
+ })]);
939
+ return { status, stdout, stderr };
940
+ } finally { clearTimeout(timer); }
941
+ },
942
+ });
943
+ return Response.json({ ...result, files: [] });
944
+ }
945
+
832
946
  // Only a remaining open needs cleanup; a successful probe converted it to
833
947
  // goto and its live daemon socket must remain reachable.
834
948
  if (filteredArgs[0] === "open") {
@@ -879,7 +993,8 @@ export async function serve() {
879
993
  const handshakeTimeoutMs = Number.isFinite(configuredHandshakeTimeout) && configuredHandshakeTimeout > 0
880
994
  ? configuredHandshakeTimeout
881
995
  : 30_000;
882
- const stderr = inferSilentExtensionFailure({
996
+ const tccNote = explainExtensionNotFound(`${stdout}\n${rawStderr}`, chromeAccessProblem);
997
+ const stderr = (tccNote ?? "") + inferSilentExtensionFailure({
883
998
  status,
884
999
  stdout,
885
1000
  stderr: rawStderr,