rechrome 1.35.1 → 1.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/README.md +74 -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 +11 -3
  8. package/rechrome.ts +11 -3
  9. package/scoped-upload.js +165 -0
  10. package/scoped-upload.ts +140 -0
  11. package/serve.js +30 -2
  12. package/serve.ts +30 -2
  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/README.md CHANGED
@@ -243,6 +243,7 @@ cp .env.example .env.local
243
243
  | `PLAYWRIGHT_MCP_EXTENSION_ID` | Chrome extension ID (client overrides server) | — |
244
244
  | `PLAYWRIGHT_MCP_EXTENSION_TOKEN` | Chrome extension token — profile-specific, get it from the extension's status page (client overrides server) | — |
245
245
  | `PLAYWRIGHT_MCP_USER_DATA_DIR` | Chrome user data directory — use to pin connections to a specific Chrome install (client overrides server) | — |
246
+ | `RECHROME_PROFILE` | Default profile selector for browser commands, equivalent to `--profile`. An explicit flag wins; blank values are ignored. Remote listeners still enforce their allowlist. | — |
246
247
  | `PLAYWRIGHT_MCP_PROFILE_DIRECTORY` | Chrome profile — accepts directory name (`Profile 2`), display name (`Snowstar`), or **email** (`you@example.com`) (client overrides server) | — |
247
248
 
248
249
  > **Multi-profile tip:** Each project's `.env.local` can specify a different Chrome profile via the `?profile=` query param in `RECHROME_URL`. The server resolves display names and email addresses to the actual Chrome profile directory automatically (reads `~/Library/Application Support/Google/Chrome/Local State`).
@@ -254,6 +255,57 @@ cp .env.example .env.local
254
255
  >
255
256
  > Shell-set `PLAYWRIGHT_MCP_*` variables take priority over `.env.local`, so you can always override per-command without editing files.
256
257
 
258
+ ### Small icon uploads from stdin
259
+
260
+ Uploads are disabled by default on every listener. The host owner can add an
261
+ `uploads` object to the intended listener entry in `~/.rechrome/listeners.json`:
262
+
263
+ ```json
264
+ "uploads": {
265
+ "maxBytes": 2097152,
266
+ "contentTypes": ["image/png", "image/svg+xml"]
267
+ }
268
+ ```
269
+
270
+ The object enables uploads; omitting it disables them. `uploads: {}` uses the
271
+ same defaults shown above. The owner can lower the byte limit or narrow the type
272
+ list, but cannot exceed the hard **2 MiB** limit or enable other types. Do not
273
+ replace the listener's other fields or share its key. Install the updated daemon
274
+ code before enabling this policy; configuration changes then use the usual
275
+ listener reload mechanism.
276
+
277
+ On the **client machine**, open the website's file chooser with `rech click`, then
278
+ send the icon through stdin in the same profile/session:
279
+
280
+ ```bash
281
+ rech --profile work -s=slack upload --name app-icon.png < ./app-icon.png
282
+ cat ./app-icon.svg | rech --profile work -s=slack upload --name app-icon.svg
283
+ ```
284
+
285
+ `--content-type image/png` or `--content-type image/svg+xml` may be specified;
286
+ otherwise the type is inferred from `--name`. This command is stdin-only: there
287
+ is no positional file path. The shell reads the local file; only its bytes and
288
+ metadata are sent to the listener. Client and server both enforce the byte cap.
289
+ The server checks PNG signatures or UTF-8 SVG markup (rejecting DTD/entities),
290
+ and checks the type against the listener policy. These checks identify the file
291
+ format; they do not sanitize SVG or scan for malware. The host never renders the
292
+ file or resolves anything referenced inside it.
293
+
294
+ The receiver writes a random `.png`/`.svg` filename with mode 0600 inside a private
295
+ 0700 temporary directory, outside the downloadable output tree. It passes only
296
+ that generated path to the existing file-chooser command and removes the directory
297
+ on success, error, or timeout. Neither filenames nor payload fields can select a
298
+ host file. A crash or forced process kill can interrupt cleanup; the files remain
299
+ private OS temporary files. Permission modes apply on POSIX hosts.
300
+
301
+ Each upload produces one `upload:` JSON audit record with listener, profile,
302
+ original name, byte size, SHA-256, page origin observed immediately before upload,
303
+ and result. It contains no file contents, credentials, page path, query, or fragment.
304
+ Requests rejected before inspection have null values for unavailable fields.
305
+ An HTTP(S) origin must be determined before an upload is attempted. As with other
306
+ browser commands, avoid concurrent tab navigation in the same session. Scoped
307
+ `eval`, `run-code`, host paths, and CLI option overrides remain unavailable.
308
+
257
309
  ### Remote access
258
310
 
259
311
  `rech setup --profile <profile> --listen tailscale` exposes that profile through a
@@ -345,3 +397,25 @@ PRs upstream are welcome. Once these features land in the official packages we w
345
397
  ## License
346
398
 
347
399
  MIT
400
+
401
+ ### Bridge connection diagnostics and recovery
402
+
403
+ Each connection attempt records fixed phase names (launch, retry, WebSocket
404
+ accepted, initialized, timeout/close) in its own private `.bridge.jsonl` file under
405
+ `~/.cache/ms-playwright/bridge`, or `PLAYWRIGHT_MCP_BRIDGE_LOG_DIR` when configured
406
+ for the Playwright process. Records contain an attempt ID, PID and timing only;
407
+ no URLs, tokens, page text or raw error messages. CLI startup stderr is retained
408
+ separately in a unique `.err` file for each launch and is not the sanitized log.
409
+
410
+ A failed automated connection page retires itself at its deadline only if it
411
+ still shows the original connection URL. The profile's worker can remove an older
412
+ page for the same attempt and relay; it excludes other attempts, attached tabs,
413
+ and tabs that navigated away. Automatic recovery no longer reloads the extension,
414
+ which could disconnect other working lanes. A genuinely unresponsive worker can
415
+ still require an explicit operator-approved extension reload.
416
+
417
+ This source change requires rebuilding the vendored Playwright bundle and
418
+ reloading the updated extension before use. It does not modify a running daemon
419
+ or extension. The draft PR records isolated-browser validation and negative
420
+ controls; passing recovery tests does not establish the original intermittent
421
+ timeout's root cause.
@@ -566,7 +566,10 @@ class PlaywrightExtension {
566
566
  _onMessage(message, sender, sendResponse) {
567
567
  switch (message.type) {
568
568
  case "connectionRequested":
569
- this._pendingConnections.create(sender.tab.id, message.mcpRelayUrl, message.protocolVersion).then(
569
+ (async () => {
570
+ if (message.recoveryAttempt) await this._retireSupersededPages(sender);
571
+ await this._pendingConnections.create(sender.tab.id, message.mcpRelayUrl, message.protocolVersion);
572
+ })().then(
570
573
  () => sendResponse({ success: true }),
571
574
  (error) => sendResponse({ success: false, error: error.message })
572
575
  );
@@ -606,6 +609,27 @@ class PlaywrightExtension {
606
609
  return false;
607
610
  }
608
611
  }
612
+ // The single worker coordinates recovery within this profile. It never reloads
613
+ // itself or touches live groups: only sibling connect pages for the same relay
614
+ // attempt can be retired. A different lane/attempt is outside this ownership.
615
+ async _retireSupersededPages(sender) {
616
+ var _a;
617
+ const current = new URL(sender.url || ((_a = sender.tab) == null ? void 0 : _a.url) || "about:blank");
618
+ const attempt = current.searchParams.get("attempt");
619
+ const relay = current.searchParams.get("mcpRelayUrl");
620
+ if (current.protocol !== "chrome-extension:" || current.host !== chrome.runtime.id || current.pathname !== "/connect.html" || !/^[0-9a-f-]{36}$/.test(attempt || "") || !relay) return;
621
+ const attached = new Set([...this._activeGroups].flatMap((g) => g.connectedTabIds()));
622
+ const tabs = await chrome.tabs.query({});
623
+ await Promise.all(tabs.map(async (tab) => {
624
+ var _a2;
625
+ if (tab.id === void 0 || tab.id === ((_a2 = sender.tab) == null ? void 0 : _a2.id) || attached.has(tab.id) || !tab.url) return;
626
+ const other = new URL(tab.url);
627
+ if (other.protocol !== current.protocol || other.host !== current.host || other.pathname !== current.pathname || other.searchParams.get("attempt") !== attempt || other.searchParams.get("mcpRelayUrl") !== relay) return;
628
+ const latest = await chrome.tabs.get(tab.id).catch(() => void 0);
629
+ if ((latest == null ? void 0 : latest.url) === tab.url) await chrome.tabs.remove(tab.id).catch(() => {
630
+ });
631
+ }));
632
+ }
609
633
  async _connectTab(selectorTabId, tab, clientName) {
610
634
  try {
611
635
  await Promise.race([
@@ -655,3 +679,6 @@ class PlaywrightExtension {
655
679
  }
656
680
  }
657
681
  new PlaywrightExtension();
682
+ export {
683
+ PlaywrightExtension
684
+ };
@@ -4,18 +4,12 @@
4
4
  import { c as clientExports, j as jsxRuntimeExports, r as reactExports, A as AuthTokenSection, T as TabItem, B as Button, g as getOrCreateAuthToken } from "./authToken.js";
5
5
  const SUPPORTED_PROTOCOL_VERSION = 2;
6
6
  const BACKGROUND_RESPONSE_TIMEOUT_MS = 1e4;
7
- const SELF_RELOAD_GUARD_KEY = "connect-self-reload-at";
8
- const SELF_RELOAD_MIN_INTERVAL_MS = 6e4;
9
- function attemptExtensionSelfReload() {
10
- if (new URLSearchParams(window.location.search).get("selfReload") !== "1")
11
- return false;
12
- const last = Number(localStorage.getItem(SELF_RELOAD_GUARD_KEY) || 0);
13
- const now = Date.now();
14
- if (now - last < SELF_RELOAD_MIN_INTERVAL_MS)
15
- return false;
16
- localStorage.setItem(SELF_RELOAD_GUARD_KEY, String(now));
17
- chrome.runtime.reload();
18
- return true;
7
+ async function retireExpiredAttempt(originalUrl) {
8
+ const params = new URL(originalUrl).searchParams;
9
+ if (!/^[0-9a-f-]{36}$/.test(params.get("attempt") || "")) return;
10
+ const tab = await chrome.tabs.getCurrent();
11
+ if ((tab == null ? void 0 : tab.id) !== void 0 && tab.url === originalUrl)
12
+ await chrome.tabs.remove(tab.id);
19
13
  }
20
14
  async function sendMessageWithTimeout(message, simulateHang = false) {
21
15
  let timer;
@@ -41,6 +35,17 @@ const ConnectApp = () => {
41
35
  setStatus({ type: "error", message });
42
36
  }, []);
43
37
  reactExports.useEffect(() => {
38
+ const originalUrl = window.location.href;
39
+ const expiry = Number(new URL(originalUrl).searchParams.get("expires"));
40
+ let connected = false;
41
+ const onConnected = () => {
42
+ connected = true;
43
+ };
44
+ window.addEventListener("bridge-connected", onConnected);
45
+ const expiryTimer = Number.isFinite(expiry) && expiry > 0 ? setTimeout(() => {
46
+ if (!connected) void retireExpiredAttempt(originalUrl).catch(() => {
47
+ });
48
+ }, Math.max(0, Math.min(expiry - Date.now(), 2147483647))) : void 0;
44
49
  const runAsync = async () => {
45
50
  const params = new URLSearchParams(window.location.search);
46
51
  const relayUrl = params.get("mcpRelayUrl");
@@ -89,13 +94,12 @@ const ConnectApp = () => {
89
94
  let response;
90
95
  try {
91
96
  response = await sendMessageWithTimeout(
92
- { type: "connectionRequested", mcpRelayUrl: relayUrl, protocolVersion: requestedVersion },
97
+ { type: "connectionRequested", mcpRelayUrl: relayUrl, protocolVersion: requestedVersion, recoveryAttempt },
93
98
  params.get("testHangOnce") === "1" && !recoveryAttempt
94
99
  );
95
100
  } catch (error) {
96
101
  if (hasAutomationToken && !recoveryAttempt) {
97
- const reloading = attemptExtensionSelfReload();
98
- setError(reloading ? "Extension service worker is not responding. Reloading extension and retrying…" : "Extension service worker is not responding. Retrying once…");
102
+ setError("Extension service worker is not responding. Retrying once…");
99
103
  return;
100
104
  }
101
105
  setError(`Extension service worker did not recover: ${error.message}`);
@@ -108,7 +112,7 @@ const ConnectApp = () => {
108
112
  const expectedToken = getOrCreateAuthToken();
109
113
  const token = params.get("token");
110
114
  if (token === expectedToken) {
111
- await handleConnectToTab(void 0, info);
115
+ connected = !!await handleConnectToTab(void 0, info);
112
116
  return;
113
117
  }
114
118
  if (token) {
@@ -125,7 +129,11 @@ const ConnectApp = () => {
125
129
  chrome.runtime.sendMessage({ type: "keepalive" }).catch(() => {
126
130
  });
127
131
  }, 2e4);
128
- return () => clearInterval(keepalive);
132
+ return () => {
133
+ clearInterval(keepalive);
134
+ clearTimeout(expiryTimer);
135
+ window.removeEventListener("bridge-connected", onConnected);
136
+ };
129
137
  }, []);
130
138
  const loadTabs = reactExports.useCallback(async () => {
131
139
  const response = await chrome.runtime.sendMessage({ type: "getTabs" });
@@ -144,6 +152,8 @@ const ConnectApp = () => {
144
152
  });
145
153
  if (response == null ? void 0 : response.success) {
146
154
  setStatus({ type: "connected", message: `"${clientName}" connected.` });
155
+ window.dispatchEvent(new Event("bridge-connected"));
156
+ return true;
147
157
  } else {
148
158
  setStatus({
149
159
  type: "error",
@@ -154,8 +164,7 @@ const ConnectApp = () => {
154
164
  const recoveryAttempt = new URLSearchParams(window.location.search).get("recoveryAttempt") === "1";
155
165
  const hasAutomationToken = !!new URLSearchParams(window.location.search).get("token");
156
166
  if (hasAutomationToken && !recoveryAttempt) {
157
- const reloading = attemptExtensionSelfReload();
158
- setError(reloading ? "Extension service worker stopped during connection. Reloading extension and retrying…" : "Extension service worker stopped during connection. Retrying once…");
167
+ setError("Extension service worker stopped during connection. Retrying once…");
159
168
  return;
160
169
  }
161
170
  setStatus({
@@ -163,6 +172,7 @@ const ConnectApp = () => {
163
172
  message: `"${clientName}" failed to connect: ${e}`
164
173
  });
165
174
  }
175
+ return false;
166
176
  }, [clientInfo, setError]);
167
177
  reactExports.useEffect(() => {
168
178
  const listener = (message) => {
package/listeners.js CHANGED
@@ -1,4 +1,14 @@
1
1
  // @bun
2
+ // scoped-upload.ts
3
+ var MAX_UPLOAD_BYTES = 2 * 1024 * 1024;
4
+ var MAX_REQUEST_BYTES = 3 * 1024 * 1024;
5
+ var UPLOAD_TYPES = ["image/png", "image/svg+xml"];
6
+ function validateUploadPolicy(value) {
7
+ const p = value;
8
+ if (!p || typeof p !== "object" || Array.isArray(p) || Object.keys(p).some((k) => !["maxBytes", "contentTypes"].includes(k)) || p.maxBytes !== undefined && (!Number.isSafeInteger(p.maxBytes) || p.maxBytes < 1 || p.maxBytes > MAX_UPLOAD_BYTES) || p.contentTypes !== undefined && (!Array.isArray(p.contentTypes) || !p.contentTypes.length || p.contentTypes.some((t) => !UPLOAD_TYPES.includes(t))))
9
+ throw new Error("uploads must be an object with optional maxBytes (1..2097152) and contentTypes (image/png, image/svg+xml)");
10
+ }
11
+
2
12
  // listeners.ts
3
13
  import { isIP } from "net";
4
14
  import { createHash, randomBytes } from "crypto";
@@ -54,6 +64,8 @@ function validateListeners(value) {
54
64
  } else if (!Array.isArray(l.profiles) || !l.profiles.length || l.profiles.some((p) => typeof p !== "string" || !p.trim() || p.includes("\x00") || p === "*")) {
55
65
  throw new Error("Listener profiles must be a nonempty list of registered profile keys");
56
66
  }
67
+ if (l.uploads !== undefined)
68
+ validateUploadPolicy(l.uploads);
57
69
  const address = listenerAddress(l);
58
70
  if (names.has(l.name) || addresses.has(address) || keys.has(l.key))
59
71
  throw new Error("Listener names, addresses, and credentials must be unique");
@@ -92,12 +104,16 @@ function authorizeProfileRequest(listener, body) {
92
104
  if (body.env?.PLAYWRIGHT_MCP_PROFILE_DIRECTORY && body.env.PLAYWRIGHT_MCP_PROFILE_DIRECTORY !== profile)
93
105
  throw new Error("Profile override does not match request identity");
94
106
  const args = body.args.filter((a) => /^-s=[a-zA-Z0-9_-]{1,64}$/.test(a) === false);
95
- if (!SCOPED_COMMANDS.has(args[0]))
107
+ if (!(args[0] === "upload" && listener.uploads !== undefined) && !SCOPED_COMMANDS.has(args[0]))
96
108
  throw new Error("Command is unavailable on profile-scoped listeners; use the local management listener for arbitrary code or host access");
97
109
  if (body.args.filter((a) => a.startsWith("-s=")).length > 1 || args.slice(1).some((a) => a.startsWith("-") && !(args[0] === "screenshot" && a === "--full-page")))
98
110
  throw new Error("CLI option overrides are unavailable on profile-scoped listeners");
99
111
  if (["open", "goto", "tab-new"].includes(args[0]) && args[1] && !/^https?:\/\//i.test(args[1]) && args[1] !== "about:blank")
100
112
  throw new Error("Scoped navigation accepts only HTTP(S) or about:blank");
113
+ if (args[0] === "upload" && (args.length !== 1 || !body.upload))
114
+ throw new Error("Upload requires stdin bytes; host paths are unavailable");
115
+ if (args[0] !== "upload" && body.upload !== undefined)
116
+ throw new Error("Unexpected upload payload");
101
117
  return profile;
102
118
  }
103
119
  function canReadProfileFile(listener, path) {
package/listeners.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { validateUploadPolicy, type UploadPolicy } from "./scoped-upload.ts";
1
2
  import { isIP } from "net";
2
3
  import { createHash, randomBytes } from "crypto";
3
4
  import { homedir } from "os";
@@ -5,7 +6,7 @@ import { join } from "path";
5
6
  import { mkdir, readFile, rename, writeFile } from "fs/promises";
6
7
 
7
8
  // publicUrl: where a reverse proxy (Tailscale Serve, Caddy, nginx, ...) exposes this listener.
8
- export type Listener = { name: string; host: string; port: number; key: string; profiles: string[] | "*"; prefix?: string; publicUrl?: string };
9
+ export type Listener = { name: string; host: string; port: number; key: string; profiles: string[] | "*"; prefix?: string; publicUrl?: string; uploads?: UploadPolicy };
9
10
  export type ListenerConfig = { version: 1; listeners: Listener[] };
10
11
  export const LISTENERS_FILE = join(homedir(), ".rechrome", "listeners.json");
11
12
  export const isLoopback = (host: string) => host === "::1" || /^127\./.test(host);
@@ -54,6 +55,7 @@ export function validateListeners(value: unknown): ListenerConfig {
54
55
  } else if (!Array.isArray(l.profiles) || !l.profiles.length || l.profiles.some(p => typeof p !== "string" || !p.trim() || p.includes("\0") || p === "*")) {
55
56
  throw new Error("Listener profiles must be a nonempty list of registered profile keys");
56
57
  }
58
+ if (l.uploads !== undefined) validateUploadPolicy(l.uploads);
57
59
  const address = listenerAddress(l);
58
60
  if (names.has(l.name) || addresses.has(address) || keys.has(l.key)) throw new Error("Listener names, addresses, and credentials must be unique");
59
61
  names.add(l.name); addresses.add(address); keys.add(l.key);
@@ -85,9 +87,12 @@ export function authorizeProfileRequest(listener: Listener, body: any): string {
85
87
  if (typeof profile !== "string" || listener.profiles === "*" || !listener.profiles.includes(profile)) throw new Error("Profile is not allowed on this listener");
86
88
  if (body.env?.PLAYWRIGHT_MCP_PROFILE_DIRECTORY && body.env.PLAYWRIGHT_MCP_PROFILE_DIRECTORY !== profile) throw new Error("Profile override does not match request identity");
87
89
  const args = body.args.filter((a: string) => /^-s=[a-zA-Z0-9_-]{1,64}$/.test(a) === false);
88
- if (!SCOPED_COMMANDS.has(args[0])) throw new Error("Command is unavailable on profile-scoped listeners; use the local management listener for arbitrary code or host access");
90
+ if (!(args[0] === "upload" && listener.uploads !== undefined) && !SCOPED_COMMANDS.has(args[0])) throw new Error("Command is unavailable on profile-scoped listeners; use the local management listener for arbitrary code or host access");
89
91
  if (body.args.filter((a: string) => a.startsWith("-s=")).length > 1 || args.slice(1).some((a: string) => a.startsWith("-") && !(args[0] === "screenshot" && a === "--full-page"))) throw new Error("CLI option overrides are unavailable on profile-scoped listeners");
90
92
  if (["open", "goto", "tab-new"].includes(args[0]) && args[1] && !/^https?:\/\//i.test(args[1]) && args[1] !== "about:blank") throw new Error("Scoped navigation accepts only HTTP(S) or about:blank");
93
+ // Upload is handled by the byte-only receiver; the caller cannot supply host paths.
94
+ if (args[0] === "upload" && (args.length !== 1 || !body.upload)) throw new Error("Upload requires stdin bytes; host paths are unavailable");
95
+ if (args[0] !== "upload" && body.upload !== undefined) throw new Error("Unexpected upload payload");
91
96
  return profile;
92
97
  }
93
98
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rechrome",
3
- "version": "1.35.1",
3
+ "version": "1.36.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/snomiao/rechrome.git"
@@ -25,7 +25,9 @@
25
25
  "rechrome.ts",
26
26
  "serve.js",
27
27
  "serve.ts",
28
- "vendor"
28
+ "vendor",
29
+ "scoped-upload.ts",
30
+ "scoped-upload.js"
29
31
  ],
30
32
  "type": "module",
31
33
  "scripts": {
@@ -34,7 +36,7 @@
34
36
  "vendor-cli": "bash scripts/vendor-cli.sh",
35
37
  "prepare": "bash scripts/vendor-cli.sh --prepare",
36
38
  "check-pack": "bash scripts/check-pack.sh",
37
- "prepublishOnly": "bash scripts/vendor-cli.sh && sed 's/\\.ts/\\.js/g' rechrome.ts > rechrome.js && sed 's/\\.ts/\\.js/g' serve.ts > serve.js && bun build extension-token.ts --target=bun --outfile=extension-token.js && bun build daemon-manager.ts --target=bun --outfile=daemon-manager.js && bun build listeners.ts --target=bun --outfile=listeners.js && bash scripts/check-pack.sh"
39
+ "prepublishOnly": "bash scripts/vendor-cli.sh && sed 's/\\.ts/\\.js/g' rechrome.ts > rechrome.js && sed 's/\\.ts/\\.js/g' serve.ts > serve.js && bun build extension-token.ts --target=bun --outfile=extension-token.js && bun build daemon-manager.ts --target=bun --outfile=daemon-manager.js && bun build listeners.ts --target=bun --outfile=listeners.js && bun build scoped-upload.ts --target=bun --outfile=scoped-upload.js && bash scripts/check-pack.sh"
38
40
  },
39
41
  "devDependencies": {
40
42
  "@types/bun": "latest",
package/rechrome.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bun
2
+ import { prepareStdinUpload, type UploadPayload } from "./scoped-upload.js";
2
3
  import { readListeners, writeListeners, listenerAddress, isLoopback, normalizePrefix, serviceUrl, allowProfiles, denyProfiles, rotateListenerKey, setPublicUrl, canonicalProfileKeys, planProfileRemoval, type Listener } from "./listeners.js";
3
4
 
4
5
  import { file } from "bun";
@@ -1808,6 +1809,7 @@ async function callServe(
1808
1809
  overrideEnv?: Record<string, string>,
1809
1810
  precomputedIdentity?: { key: string; label: string; profile?: string },
1810
1811
  throwOnFailure = false,
1812
+ upload?: UploadPayload,
1811
1813
  ): Promise<{ status: number; stdout: string; stderr: string; files?: string[]; existingSession?: boolean }> {
1812
1814
  const { key, host, port, protocol, extensionId, extensionToken, profileDirectory, userDataDir, loadExtension } = parseUrl(url);
1813
1815
  // Reuse the caller's identity when provided — computing it shells out to `git` several times,
@@ -1826,7 +1828,7 @@ async function callServe(
1826
1828
  method: "POST",
1827
1829
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${key}` },
1828
1830
  // dataDir is a client-local path; the daemon (possibly remote) only needs the session identity.
1829
- body: JSON.stringify({ args, identity: { key: identity.key, label: identity.label, profile: identity.profile }, env }),
1831
+ body: JSON.stringify({ args, identity: { key: identity.key, label: identity.label, profile: identity.profile }, env, ...(upload ? { upload } : {}) }),
1830
1832
  signal: AbortSignal.timeout(70_000),
1831
1833
  }).catch(async (e) => {
1832
1834
  if (throwOnFailure) throw new Error("Cannot reach the rechrome daemon. Check that it is running.");
@@ -2012,7 +2014,12 @@ async function run(url: string, args: string[], overrideEnv?: Record<string, str
2012
2014
 
2013
2015
  const resolvedEnv = await getClientEnv({ extensionId, extensionToken, profileDirectory: effectiveProfile, userDataDir, loadExtension });
2014
2016
  const effectiveEnv = { ...resolvedEnv, ...overrideEnv };
2015
- const { status, stdout, stderr, files, existingSession } = await callServe(url, args, overrideEnv, identity);
2017
+ let upload: UploadPayload | undefined;
2018
+ if (args.find(a => !/^-s=[a-zA-Z0-9_-]{1,64}$/.test(a)) === "upload") {
2019
+ if (process.stdin.isTTY) throw new Error("upload reads stdin; redirect a PNG/SVG file with < icon.png");
2020
+ ({ args, upload } = await prepareStdinUpload(args, process.stdin));
2021
+ }
2022
+ const { status, stdout, stderr, files, existingSession } = await callServe(url, args, overrideEnv, identity, false, upload);
2016
2023
 
2017
2024
  const isOpenWithUrl = args[0] === "open" && args.length > 1;
2018
2025
  if (existingSession && isOpenWithUrl) {
@@ -3658,6 +3665,7 @@ const HELP_EPILOGUE = `Browser commands (sent to this project's Chrome session):
3658
3665
 
3659
3666
  Environment:
3660
3667
  ${ENV_KEY} connection URL; read from the nearest .rechrome/.env.local or .env.local
3668
+ RECHROME_PROFILE default browser profile selector; --profile overrides it
3661
3669
  RECH_IDENTITY session key: worktree (default) | branch | cwd
3662
3670
  RECH_TOKEN extension token for \`rech setup\` (same as --token)
3663
3671
  RECH_SETUP_AGENT setup hints: codex | claude | none (auto-detected)
@@ -3848,7 +3856,7 @@ if (import.meta.main) {
3848
3856
  if (separator !== -1) args = args.slice(0, separator);
3849
3857
  try {
3850
3858
  const extracted = extractGlobalProfileArg(args);
3851
- profileSelector = extracted.selector;
3859
+ profileSelector = extracted.selector ?? (process.env.RECHROME_PROFILE?.trim() || undefined);
3852
3860
  args = extracted.args;
3853
3861
  } catch (err) {
3854
3862
  console.error(err instanceof Error ? err.message : String(err));
package/rechrome.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bun
2
+ import { prepareStdinUpload, type UploadPayload } from "./scoped-upload.ts";
2
3
  import { readListeners, writeListeners, listenerAddress, isLoopback, normalizePrefix, serviceUrl, allowProfiles, denyProfiles, rotateListenerKey, setPublicUrl, canonicalProfileKeys, planProfileRemoval, type Listener } from "./listeners.ts";
3
4
 
4
5
  import { file } from "bun";
@@ -1808,6 +1809,7 @@ async function callServe(
1808
1809
  overrideEnv?: Record<string, string>,
1809
1810
  precomputedIdentity?: { key: string; label: string; profile?: string },
1810
1811
  throwOnFailure = false,
1812
+ upload?: UploadPayload,
1811
1813
  ): Promise<{ status: number; stdout: string; stderr: string; files?: string[]; existingSession?: boolean }> {
1812
1814
  const { key, host, port, protocol, extensionId, extensionToken, profileDirectory, userDataDir, loadExtension } = parseUrl(url);
1813
1815
  // Reuse the caller's identity when provided — computing it shells out to `git` several times,
@@ -1826,7 +1828,7 @@ async function callServe(
1826
1828
  method: "POST",
1827
1829
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${key}` },
1828
1830
  // dataDir is a client-local path; the daemon (possibly remote) only needs the session identity.
1829
- body: JSON.stringify({ args, identity: { key: identity.key, label: identity.label, profile: identity.profile }, env }),
1831
+ body: JSON.stringify({ args, identity: { key: identity.key, label: identity.label, profile: identity.profile }, env, ...(upload ? { upload } : {}) }),
1830
1832
  signal: AbortSignal.timeout(70_000),
1831
1833
  }).catch(async (e) => {
1832
1834
  if (throwOnFailure) throw new Error("Cannot reach the rechrome daemon. Check that it is running.");
@@ -2012,7 +2014,12 @@ async function run(url: string, args: string[], overrideEnv?: Record<string, str
2012
2014
 
2013
2015
  const resolvedEnv = await getClientEnv({ extensionId, extensionToken, profileDirectory: effectiveProfile, userDataDir, loadExtension });
2014
2016
  const effectiveEnv = { ...resolvedEnv, ...overrideEnv };
2015
- const { status, stdout, stderr, files, existingSession } = await callServe(url, args, overrideEnv, identity);
2017
+ let upload: UploadPayload | undefined;
2018
+ if (args.find(a => !/^-s=[a-zA-Z0-9_-]{1,64}$/.test(a)) === "upload") {
2019
+ if (process.stdin.isTTY) throw new Error("upload reads stdin; redirect a PNG/SVG file with < icon.png");
2020
+ ({ args, upload } = await prepareStdinUpload(args, process.stdin));
2021
+ }
2022
+ const { status, stdout, stderr, files, existingSession } = await callServe(url, args, overrideEnv, identity, false, upload);
2016
2023
 
2017
2024
  const isOpenWithUrl = args[0] === "open" && args.length > 1;
2018
2025
  if (existingSession && isOpenWithUrl) {
@@ -3658,6 +3665,7 @@ const HELP_EPILOGUE = `Browser commands (sent to this project's Chrome session):
3658
3665
 
3659
3666
  Environment:
3660
3667
  ${ENV_KEY} connection URL; read from the nearest .rechrome/.env.local or .env.local
3668
+ RECHROME_PROFILE default browser profile selector; --profile overrides it
3661
3669
  RECH_IDENTITY session key: worktree (default) | branch | cwd
3662
3670
  RECH_TOKEN extension token for \`rech setup\` (same as --token)
3663
3671
  RECH_SETUP_AGENT setup hints: codex | claude | none (auto-detected)
@@ -3848,7 +3856,7 @@ if (import.meta.main) {
3848
3856
  if (separator !== -1) args = args.slice(0, separator);
3849
3857
  try {
3850
3858
  const extracted = extractGlobalProfileArg(args);
3851
- profileSelector = extracted.selector;
3859
+ profileSelector = extracted.selector ?? (process.env.RECHROME_PROFILE?.trim() || undefined);
3852
3860
  args = extracted.args;
3853
3861
  } catch (err) {
3854
3862
  console.error(err instanceof Error ? err.message : String(err));
@@ -0,0 +1,165 @@
1
+ // @bun
2
+ // scoped-upload.ts
3
+ import { createHash, randomBytes } from "crypto";
4
+ import { mkdtemp, writeFile, rm } from "fs/promises";
5
+ import { join } from "path";
6
+ import { tmpdir } from "os";
7
+ var MAX_UPLOAD_BYTES = 2 * 1024 * 1024;
8
+ var MAX_REQUEST_BYTES = 3 * 1024 * 1024;
9
+ var UPLOAD_TYPES = ["image/png", "image/svg+xml"];
10
+ function validateUploadPolicy(value) {
11
+ const p = value;
12
+ if (!p || typeof p !== "object" || Array.isArray(p) || Object.keys(p).some((k) => !["maxBytes", "contentTypes"].includes(k)) || p.maxBytes !== undefined && (!Number.isSafeInteger(p.maxBytes) || p.maxBytes < 1 || p.maxBytes > MAX_UPLOAD_BYTES) || p.contentTypes !== undefined && (!Array.isArray(p.contentTypes) || !p.contentTypes.length || p.contentTypes.some((t) => !UPLOAD_TYPES.includes(t))))
13
+ throw new Error("uploads must be an object with optional maxBytes (1..2097152) and contentTypes (image/png, image/svg+xml)");
14
+ }
15
+ function validName(name) {
16
+ return typeof name === "string" && name.length > 0 && name.length <= 128 && name !== "." && name !== ".." && !name.startsWith("-") && !/[\\/:\x00-\x1f\x7f]/.test(name);
17
+ }
18
+ function matchesType(bytes, type) {
19
+ if (type === "image/png")
20
+ return bytes.length >= 33 && bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])) && bytes.readUInt32BE(8) === 13 && bytes.toString("ascii", 12, 16) === "IHDR";
21
+ if (type === "image/svg+xml") {
22
+ let text;
23
+ try {
24
+ text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
25
+ } catch {
26
+ return false;
27
+ }
28
+ if (/<!DOCTYPE|<!ENTITY/i.test(text))
29
+ return false;
30
+ text = text.trim().replace(/^<\?xml\s[^?]*\?>\s*/, "").replace(/^(?:<!--[\s\S]*?-->\s*)+/, "");
31
+ return /^<svg(?:\s|\/?>)/.test(text) && /(?:<\/svg\s*>|\/>)\s*$/.test(text);
32
+ }
33
+ return false;
34
+ }
35
+ async function prepareStdinUpload(args, input) {
36
+ const sessions = args.filter((a) => /^-s=[a-zA-Z0-9_-]{1,64}$/.test(a));
37
+ const options = args.filter((a) => !sessions.includes(a));
38
+ if (options.shift() !== "upload")
39
+ throw new Error("Expected upload command");
40
+ const fields = {};
41
+ while (options.length) {
42
+ const option = options.shift();
43
+ const match = option.match(/^--(name|content-type)(?:=(.*))?$/);
44
+ if (!match || fields[match[1]] !== undefined)
45
+ throw new Error("Usage: rech upload --name icon.png [--content-type image/png] < icon.png (stdin only; no path argument)");
46
+ const value = match[2] ?? options.shift();
47
+ if (!value || value.startsWith("--"))
48
+ throw new Error(`Missing value for --${match[1]}`);
49
+ fields[match[1]] = value;
50
+ }
51
+ if (!validName(fields.name))
52
+ throw new Error("upload requires --name with a plain filename (no path)");
53
+ const contentType = fields["content-type"] ?? (fields.name.toLowerCase().endsWith(".png") ? "image/png" : fields.name.toLowerCase().endsWith(".svg") ? "image/svg+xml" : "");
54
+ if (!UPLOAD_TYPES.includes(contentType))
55
+ throw new Error("Upload content type must be image/png or image/svg+xml");
56
+ const chunks = [];
57
+ let size = 0;
58
+ for await (const chunk of input) {
59
+ size += chunk.byteLength;
60
+ if (size > MAX_UPLOAD_BYTES)
61
+ throw new Error("Upload exceeds 2 MiB");
62
+ chunks.push(Buffer.from(chunk));
63
+ }
64
+ const bytes = Buffer.concat(chunks);
65
+ if (!matchesType(bytes, contentType))
66
+ throw new Error("Upload bytes do not match the content type (PNG or UTF-8 SVG without DTD/entities required)");
67
+ return { args: ["upload", ...sessions], upload: { name: fields.name, contentType, data: bytes.toString("base64") } };
68
+ }
69
+ function currentPageOrigin(output) {
70
+ const current = output.split(`
71
+ `).filter((line) => /^- \d+: \(current\) /.test(line));
72
+ const url = current.length === 1 ? current[0].match(/\]\((.*)\)(?: \[crashed\])?$/)?.[1] : undefined;
73
+ if (!url)
74
+ throw new Error("Could not determine the upload page origin");
75
+ const parsed = new URL(url);
76
+ if (!["http:", "https:"].includes(parsed.protocol))
77
+ throw new Error("Uploads require an HTTP(S) page");
78
+ return parsed.origin;
79
+ }
80
+ async function receiveUpload(options) {
81
+ const record = { name: null, size: null, sha256: null, origin: null, result: "rejected" };
82
+ let dir;
83
+ try {
84
+ const p = options.payload;
85
+ if (validName(p?.name))
86
+ record.name = p.name;
87
+ if (options.policy === undefined)
88
+ throw new Error("Uploads are disabled on this listener");
89
+ validateUploadPolicy(options.policy);
90
+ if (options.args.length !== 1 || options.args[0] !== "upload")
91
+ throw new Error("Upload takes stdin bytes, not host paths or CLI options");
92
+ if (!p || !validName(p.name) || typeof p.contentType !== "string" || typeof p.data !== "string" || Object.keys(p).some((k) => !["name", "contentType", "data"].includes(k)))
93
+ throw new Error("Invalid upload payload");
94
+ const limit = options.policy.maxBytes ?? MAX_UPLOAD_BYTES;
95
+ if (p.data.length > 4 * Math.ceil(limit / 3) || /[^A-Za-z0-9+/=]/.test(p.data))
96
+ throw new Error("Upload exceeds maxBytes or has invalid base64");
97
+ const bytes = Buffer.from(p.data, "base64");
98
+ record.size = bytes.length;
99
+ record.sha256 = createHash("sha256").update(bytes).digest("hex");
100
+ if (!bytes.length || bytes.length > limit || bytes.toString("base64") !== p.data)
101
+ throw new Error("Upload is empty, exceeds maxBytes, or is not canonical base64");
102
+ if (!(options.policy.contentTypes ?? UPLOAD_TYPES).includes(p.contentType) || !matchesType(bytes, p.contentType))
103
+ throw new Error("Upload content type is not allowed or does not match the bytes");
104
+ const tabs = await options.run(["tab-list"]);
105
+ if (tabs.status !== 0)
106
+ throw new Error("Could not inspect the upload page");
107
+ record.origin = currentPageOrigin(tabs.stdout);
108
+ dir = await mkdtemp(join(tmpdir(), "rech-upload-"));
109
+ const path = join(dir, randomBytes(16).toString("hex") + (p.contentType === "image/png" ? ".png" : ".svg"));
110
+ await writeFile(path, bytes, { mode: 384, flag: "wx" });
111
+ record.result = "failed";
112
+ const result = await options.run(["upload", path]);
113
+ record.result = result.status === 0 && !/^### Error\b/m.test(result.stdout) ? "completed" : "failed";
114
+ return {
115
+ ...result,
116
+ status: record.result === "completed" ? 0 : 1,
117
+ stdout: result.stdout.replaceAll(path, p.name),
118
+ stderr: result.stderr.replaceAll(path, p.name)
119
+ };
120
+ } catch (error) {
121
+ return { status: 1, stdout: "", stderr: (error instanceof Error ? error.message : "Upload failed") + `
122
+ ` };
123
+ } finally {
124
+ try {
125
+ if (dir)
126
+ await rm(dir, { recursive: true, force: true });
127
+ } finally {
128
+ options.audit(record);
129
+ }
130
+ }
131
+ }
132
+ async function readRequestJson(req) {
133
+ const reader = req.body?.getReader();
134
+ if (!reader)
135
+ throw new Error("Empty request");
136
+ const chunks = [];
137
+ let size = 0;
138
+ try {
139
+ for (;; ) {
140
+ const { done, value } = await reader.read();
141
+ if (done)
142
+ break;
143
+ size += value.byteLength;
144
+ if (size > MAX_REQUEST_BYTES)
145
+ throw new Error("Request exceeds 3 MiB");
146
+ chunks.push(value);
147
+ }
148
+ } catch (error) {
149
+ await reader.cancel().catch(() => {});
150
+ throw error;
151
+ } finally {
152
+ reader.releaseLock();
153
+ }
154
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
155
+ }
156
+ export {
157
+ MAX_REQUEST_BYTES,
158
+ MAX_UPLOAD_BYTES,
159
+ UPLOAD_TYPES,
160
+ currentPageOrigin,
161
+ prepareStdinUpload,
162
+ readRequestJson,
163
+ receiveUpload,
164
+ validateUploadPolicy
165
+ };