@vforsh/argus 0.3.0 → 0.4.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 (412) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/argus.js +5251 -5487
  3. package/dist/cdp/resolveCdpEndpoint.d.ts.map +1 -1
  4. package/dist/cdp/resolveCdpEndpoint.js +2 -1
  5. package/dist/cdp/resolveCdpEndpoint.js.map +1 -1
  6. package/dist/cli/defineCommand.d.ts +12 -0
  7. package/dist/cli/defineCommand.d.ts.map +1 -1
  8. package/dist/cli/defineCommand.js +71 -1
  9. package/dist/cli/defineCommand.js.map +1 -1
  10. package/dist/cli/defineWatcherCommand.d.ts +12 -54
  11. package/dist/cli/defineWatcherCommand.d.ts.map +1 -1
  12. package/dist/cli/defineWatcherCommand.js +1 -1
  13. package/dist/cli/defineWatcherCommand.js.map +1 -1
  14. package/dist/cli/parse.d.ts +1 -2
  15. package/dist/cli/parse.d.ts.map +1 -1
  16. package/dist/cli/parse.js +2 -10
  17. package/dist/cli/parse.js.map +1 -1
  18. package/dist/cli/plugins/pluginHost.d.ts.map +1 -1
  19. package/dist/cli/plugins/pluginHost.js +1 -1
  20. package/dist/cli/plugins/pluginHost.js.map +1 -1
  21. package/dist/cli/plugins/registerPlugins.d.ts.map +1 -1
  22. package/dist/cli/plugins/registerPlugins.js +10 -8
  23. package/dist/cli/plugins/registerPlugins.js.map +1 -1
  24. package/dist/cli/program.d.ts.map +1 -1
  25. package/dist/cli/program.js +4 -0
  26. package/dist/cli/program.js.map +1 -1
  27. package/dist/cli/register/authCommands.d.ts.map +1 -1
  28. package/dist/cli/register/authCommands.js +8 -7
  29. package/dist/cli/register/authCommands.js.map +1 -1
  30. package/dist/cli/register/chromeCommands.d.ts.map +1 -1
  31. package/dist/cli/register/chromeCommands.js +12 -27
  32. package/dist/cli/register/chromeCommands.js.map +1 -1
  33. package/dist/cli/register/codeCommands.d.ts.map +1 -1
  34. package/dist/cli/register/codeCommands.js +7 -6
  35. package/dist/cli/register/codeCommands.js.map +1 -1
  36. package/dist/cli/register/dialogCommands.d.ts.map +1 -1
  37. package/dist/cli/register/dialogCommands.js +3 -2
  38. package/dist/cli/register/dialogCommands.js.map +1 -1
  39. package/dist/cli/register/domCommandBuilder.d.ts.map +1 -1
  40. package/dist/cli/register/domCommandBuilder.js +2 -1
  41. package/dist/cli/register/domCommandBuilder.js.map +1 -1
  42. package/dist/cli/register/domCommands.d.ts.map +1 -1
  43. package/dist/cli/register/domCommands.js +7 -6
  44. package/dist/cli/register/domCommands.js.map +1 -1
  45. package/dist/cli/register/evalCommands.d.ts.map +1 -1
  46. package/dist/cli/register/evalCommands.js +30 -49
  47. package/dist/cli/register/evalCommands.js.map +1 -1
  48. package/dist/cli/register/extensionCommands.d.ts.map +1 -1
  49. package/dist/cli/register/extensionCommands.js +1 -1
  50. package/dist/cli/register/extensionCommands.js.map +1 -1
  51. package/dist/cli/register/fillCommand.d.ts.map +1 -1
  52. package/dist/cli/register/fillCommand.js +11 -4
  53. package/dist/cli/register/fillCommand.js.map +1 -1
  54. package/dist/cli/register/hoverCommand.d.ts.map +1 -1
  55. package/dist/cli/register/hoverCommand.js +2 -1
  56. package/dist/cli/register/hoverCommand.js.map +1 -1
  57. package/dist/cli/register/keydownCommand.d.ts.map +1 -1
  58. package/dist/cli/register/keydownCommand.js +2 -1
  59. package/dist/cli/register/keydownCommand.js.map +1 -1
  60. package/dist/cli/register/locateCommands.d.ts.map +1 -1
  61. package/dist/cli/register/locateCommands.js +2 -1
  62. package/dist/cli/register/locateCommands.js.map +1 -1
  63. package/dist/cli/register/logsCommands.d.ts.map +1 -1
  64. package/dist/cli/register/logsCommands.js +8 -10
  65. package/dist/cli/register/logsCommands.js.map +1 -1
  66. package/dist/cli/register/netCommands.d.ts +0 -5
  67. package/dist/cli/register/netCommands.d.ts.map +1 -1
  68. package/dist/cli/register/netCommands.js +17 -143
  69. package/dist/cli/register/netCommands.js.map +1 -1
  70. package/dist/cli/register/pageCommands.d.ts.map +1 -1
  71. package/dist/cli/register/pageCommands.js +8 -7
  72. package/dist/cli/register/pageCommands.js.map +1 -1
  73. package/dist/cli/register/pluginCommands.d.ts.map +1 -1
  74. package/dist/cli/register/pluginCommands.js +3 -2
  75. package/dist/cli/register/pluginCommands.js.map +1 -1
  76. package/dist/cli/register/quickAccessCommands.d.ts.map +1 -1
  77. package/dist/cli/register/quickAccessCommands.js +16 -31
  78. package/dist/cli/register/quickAccessCommands.js.map +1 -1
  79. package/dist/cli/register/recordCommands.d.ts.map +1 -1
  80. package/dist/cli/register/recordCommands.js +12 -34
  81. package/dist/cli/register/recordCommands.js.map +1 -1
  82. package/dist/cli/register/scrollToCommand.d.ts.map +1 -1
  83. package/dist/cli/register/scrollToCommand.js +2 -1
  84. package/dist/cli/register/scrollToCommand.js.map +1 -1
  85. package/dist/cli/register/sharedOptions.d.ts +11 -0
  86. package/dist/cli/register/sharedOptions.d.ts.map +1 -0
  87. package/dist/cli/register/sharedOptions.js +10 -0
  88. package/dist/cli/register/sharedOptions.js.map +1 -0
  89. package/dist/cli/register/skillCommands.d.ts.map +1 -1
  90. package/dist/cli/register/skillCommands.js +2 -1
  91. package/dist/cli/register/skillCommands.js.map +1 -1
  92. package/dist/cli/register/snapshotCommands.d.ts.map +1 -1
  93. package/dist/cli/register/snapshotCommands.js +3 -2
  94. package/dist/cli/register/snapshotCommands.js.map +1 -1
  95. package/dist/cli/register/storageCommands.d.ts.map +1 -1
  96. package/dist/cli/register/storageCommands.js +2 -1
  97. package/dist/cli/register/storageCommands.js.map +1 -1
  98. package/dist/cli/register/throttleCommands.d.ts.map +1 -1
  99. package/dist/cli/register/throttleCommands.js +4 -3
  100. package/dist/cli/register/throttleCommands.js.map +1 -1
  101. package/dist/cli/register/traceCommands.d.ts.map +1 -1
  102. package/dist/cli/register/traceCommands.js +10 -30
  103. package/dist/cli/register/traceCommands.js.map +1 -1
  104. package/dist/cli/register/watcherCommands.d.ts.map +1 -1
  105. package/dist/cli/register/watcherCommands.js +12 -24
  106. package/dist/cli/register/watcherCommands.js.map +1 -1
  107. package/dist/cli/validation.d.ts +14 -0
  108. package/dist/cli/validation.d.ts.map +1 -1
  109. package/dist/cli/validation.js +17 -6
  110. package/dist/cli/validation.js.map +1 -1
  111. package/dist/commands/auth.d.ts.map +1 -1
  112. package/dist/commands/auth.js +3 -2
  113. package/dist/commands/auth.js.map +1 -1
  114. package/dist/commands/authCookieSupport.d.ts +4 -2
  115. package/dist/commands/authCookieSupport.d.ts.map +1 -1
  116. package/dist/commands/authCookieSupport.js +0 -4
  117. package/dist/commands/authCookieSupport.js.map +1 -1
  118. package/dist/commands/authCookies.d.ts +4 -4
  119. package/dist/commands/authCookies.d.ts.map +1 -1
  120. package/dist/commands/chrome/authState.d.ts +0 -12
  121. package/dist/commands/chrome/authState.d.ts.map +1 -1
  122. package/dist/commands/chrome/authState.js +0 -14
  123. package/dist/commands/chrome/authState.js.map +1 -1
  124. package/dist/commands/chrome/browser.d.ts.map +1 -1
  125. package/dist/commands/chrome/browser.js +2 -1
  126. package/dist/commands/chrome/browser.js.map +1 -1
  127. package/dist/commands/chrome/shared.d.ts.map +1 -1
  128. package/dist/commands/chrome/shared.js +3 -2
  129. package/dist/commands/chrome/shared.js.map +1 -1
  130. package/dist/commands/chrome/targets.d.ts.map +1 -1
  131. package/dist/commands/chrome/targets.js +6 -5
  132. package/dist/commands/chrome/targets.js.map +1 -1
  133. package/dist/commands/chromeStart.d.ts +10 -0
  134. package/dist/commands/chromeStart.d.ts.map +1 -1
  135. package/dist/commands/chromeStart.js +50 -41
  136. package/dist/commands/chromeStart.js.map +1 -1
  137. package/dist/commands/code.d.ts +2 -2
  138. package/dist/commands/code.d.ts.map +1 -1
  139. package/dist/commands/codeEdit.d.ts.map +1 -1
  140. package/dist/commands/codeEdit.js +3 -2
  141. package/dist/commands/codeEdit.js.map +1 -1
  142. package/dist/commands/configInit.d.ts +1 -0
  143. package/dist/commands/configInit.d.ts.map +1 -1
  144. package/dist/commands/configInit.js +17 -14
  145. package/dist/commands/configInit.js.map +1 -1
  146. package/dist/commands/dialog.d.ts +4 -4
  147. package/dist/commands/dialog.d.ts.map +1 -1
  148. package/dist/commands/doctor.d.ts.map +1 -1
  149. package/dist/commands/doctor.js +14 -10
  150. package/dist/commands/doctor.js.map +1 -1
  151. package/dist/commands/dom/shared.js +1 -1
  152. package/dist/commands/dom/shared.js.map +1 -1
  153. package/dist/commands/domAdd.d.ts +1 -1
  154. package/dist/commands/domAdd.d.ts.map +1 -1
  155. package/dist/commands/domAdd.js +10 -54
  156. package/dist/commands/domAdd.js.map +1 -1
  157. package/dist/commands/domAddScript.d.ts.map +1 -1
  158. package/dist/commands/domAddScript.js +14 -58
  159. package/dist/commands/domAddScript.js.map +1 -1
  160. package/dist/commands/domClick.d.ts +1 -2
  161. package/dist/commands/domClick.d.ts.map +1 -1
  162. package/dist/commands/domClick.js +2 -4
  163. package/dist/commands/domClick.js.map +1 -1
  164. package/dist/commands/domDrag.d.ts +1 -2
  165. package/dist/commands/domDrag.d.ts.map +1 -1
  166. package/dist/commands/domDrag.js +3 -5
  167. package/dist/commands/domDrag.js.map +1 -1
  168. package/dist/commands/domFill.d.ts +2 -1
  169. package/dist/commands/domFill.d.ts.map +1 -1
  170. package/dist/commands/domFill.js +10 -42
  171. package/dist/commands/domFill.js.map +1 -1
  172. package/dist/commands/domFocus.d.ts +1 -1
  173. package/dist/commands/domFocus.d.ts.map +1 -1
  174. package/dist/commands/domHover.d.ts +1 -1
  175. package/dist/commands/domHover.d.ts.map +1 -1
  176. package/dist/commands/domInfo.d.ts +1 -1
  177. package/dist/commands/domInfo.d.ts.map +1 -1
  178. package/dist/commands/domKeydown.d.ts +1 -1
  179. package/dist/commands/domKeydown.d.ts.map +1 -1
  180. package/dist/commands/domModify.d.ts.map +1 -1
  181. package/dist/commands/domModify.js +6 -7
  182. package/dist/commands/domModify.js.map +1 -1
  183. package/dist/commands/domRemove.d.ts +1 -1
  184. package/dist/commands/domRemove.d.ts.map +1 -1
  185. package/dist/commands/domScroll.d.ts +1 -1
  186. package/dist/commands/domScroll.d.ts.map +1 -1
  187. package/dist/commands/domScroll.js +16 -10
  188. package/dist/commands/domScroll.js.map +1 -1
  189. package/dist/commands/domScrollTo.d.ts +1 -1
  190. package/dist/commands/domScrollTo.d.ts.map +1 -1
  191. package/dist/commands/domSetFile.d.ts +1 -1
  192. package/dist/commands/domSetFile.d.ts.map +1 -1
  193. package/dist/commands/domTree.d.ts +1 -1
  194. package/dist/commands/domTree.d.ts.map +1 -1
  195. package/dist/commands/eval.d.ts +3 -32
  196. package/dist/commands/eval.d.ts.map +1 -1
  197. package/dist/commands/eval.js +14 -33
  198. package/dist/commands/eval.js.map +1 -1
  199. package/dist/commands/evalBundle.js +2 -1
  200. package/dist/commands/evalBundle.js.map +1 -1
  201. package/dist/commands/evalEmit.d.ts +35 -0
  202. package/dist/commands/evalEmit.d.ts.map +1 -0
  203. package/dist/commands/evalEmit.js +65 -0
  204. package/dist/commands/evalEmit.js.map +1 -0
  205. package/dist/commands/evalIframe.d.ts +16 -0
  206. package/dist/commands/evalIframe.d.ts.map +1 -0
  207. package/dist/commands/evalIframe.js +37 -0
  208. package/dist/commands/evalIframe.js.map +1 -0
  209. package/dist/commands/evalShared.d.ts +52 -44
  210. package/dist/commands/evalShared.d.ts.map +1 -1
  211. package/dist/commands/evalShared.js +64 -192
  212. package/dist/commands/evalShared.js.map +1 -1
  213. package/dist/commands/evalUntil.d.ts +4 -32
  214. package/dist/commands/evalUntil.d.ts.map +1 -1
  215. package/dist/commands/evalUntil.js +9 -29
  216. package/dist/commands/evalUntil.js.map +1 -1
  217. package/dist/commands/extension/attach.d.ts.map +1 -1
  218. package/dist/commands/extension/attach.js +12 -28
  219. package/dist/commands/extension/attach.js.map +1 -1
  220. package/dist/commands/extension/doctor.d.ts.map +1 -1
  221. package/dist/commands/extension/doctor.js +10 -1
  222. package/dist/commands/extension/doctor.js.map +1 -1
  223. package/dist/commands/extension/failures.d.ts +62 -0
  224. package/dist/commands/extension/failures.d.ts.map +1 -0
  225. package/dist/commands/extension/failures.js +70 -0
  226. package/dist/commands/extension/failures.js.map +1 -0
  227. package/dist/commands/extension/info.d.ts.map +1 -1
  228. package/dist/commands/extension/info.js +4 -14
  229. package/dist/commands/extension/info.js.map +1 -1
  230. package/dist/commands/extension/install.d.ts.map +1 -1
  231. package/dist/commands/extension/install.js +12 -22
  232. package/dist/commands/extension/install.js.map +1 -1
  233. package/dist/commands/extension/nativeHost.d.ts +22 -0
  234. package/dist/commands/extension/nativeHost.d.ts.map +1 -1
  235. package/dist/commands/extension/nativeHost.js +38 -7
  236. package/dist/commands/extension/nativeHost.js.map +1 -1
  237. package/dist/commands/extension/remove.d.ts.map +1 -1
  238. package/dist/commands/extension/remove.js +5 -15
  239. package/dist/commands/extension/remove.js.map +1 -1
  240. package/dist/commands/extension/resolveExtensionWatcher.d.ts.map +1 -1
  241. package/dist/commands/extension/resolveExtensionWatcher.js +3 -2
  242. package/dist/commands/extension/resolveExtensionWatcher.js.map +1 -1
  243. package/dist/commands/extension/select.js +11 -23
  244. package/dist/commands/extension/select.js.map +1 -1
  245. package/dist/commands/extension/setup.d.ts.map +1 -1
  246. package/dist/commands/extension/setup.js +8 -30
  247. package/dist/commands/extension/setup.js.map +1 -1
  248. package/dist/commands/extension/show.d.ts.map +1 -1
  249. package/dist/commands/extension/show.js +10 -17
  250. package/dist/commands/extension/show.js.map +1 -1
  251. package/dist/commands/extension/status.d.ts.map +1 -1
  252. package/dist/commands/extension/status.js +5 -14
  253. package/dist/commands/extension/status.js.map +1 -1
  254. package/dist/commands/extension/tabAttach.d.ts.map +1 -1
  255. package/dist/commands/extension/tabAttach.js +2 -2
  256. package/dist/commands/extension/tabAttach.js.map +1 -1
  257. package/dist/commands/extension/tabSelection.d.ts.map +1 -1
  258. package/dist/commands/extension/tabSelection.js +1 -1
  259. package/dist/commands/extension/tabSelection.js.map +1 -1
  260. package/dist/commands/extension/tabWatcher.d.ts +7 -1
  261. package/dist/commands/extension/tabWatcher.d.ts.map +1 -1
  262. package/dist/commands/extension/tabWatcher.js +17 -21
  263. package/dist/commands/extension/tabWatcher.js.map +1 -1
  264. package/dist/commands/extension/tabs.d.ts.map +1 -1
  265. package/dist/commands/extension/tabs.js +6 -31
  266. package/dist/commands/extension/tabs.js.map +1 -1
  267. package/dist/commands/extension/targetSelection.d.ts +10 -23
  268. package/dist/commands/extension/targetSelection.d.ts.map +1 -1
  269. package/dist/commands/extension/targetSelection.js +4 -4
  270. package/dist/commands/extension/targetSelection.js.map +1 -1
  271. package/dist/commands/extension/targets.js +2 -11
  272. package/dist/commands/extension/targets.js.map +1 -1
  273. package/dist/commands/iframeHelper.d.ts +13 -0
  274. package/dist/commands/iframeHelper.d.ts.map +1 -1
  275. package/dist/commands/iframeHelper.js +7 -1
  276. package/dist/commands/iframeHelper.js.map +1 -1
  277. package/dist/commands/inputSource.d.ts +57 -0
  278. package/dist/commands/inputSource.d.ts.map +1 -0
  279. package/dist/commands/inputSource.js +75 -0
  280. package/dist/commands/inputSource.js.map +1 -0
  281. package/dist/commands/list.d.ts.map +1 -1
  282. package/dist/commands/list.js +14 -6
  283. package/dist/commands/list.js.map +1 -1
  284. package/dist/commands/logs.d.ts +3 -3
  285. package/dist/commands/logs.d.ts.map +1 -1
  286. package/dist/commands/net.d.ts +1 -1
  287. package/dist/commands/net.d.ts.map +1 -1
  288. package/dist/commands/netClear.d.ts +1 -1
  289. package/dist/commands/netClear.d.ts.map +1 -1
  290. package/dist/commands/netExport.d.ts.map +1 -1
  291. package/dist/commands/netExport.js +9 -31
  292. package/dist/commands/netExport.js.map +1 -1
  293. package/dist/commands/netInspect.d.ts.map +1 -1
  294. package/dist/commands/netInspect.js +2 -1
  295. package/dist/commands/netInspect.js.map +1 -1
  296. package/dist/commands/netMock.d.ts +4 -4
  297. package/dist/commands/netMock.d.ts.map +1 -1
  298. package/dist/commands/netMock.js +2 -2
  299. package/dist/commands/netMock.js.map +1 -1
  300. package/dist/commands/netRequestClient.d.ts +2 -2
  301. package/dist/commands/netRequestClient.d.ts.map +1 -1
  302. package/dist/commands/netRequestClient.js.map +1 -1
  303. package/dist/commands/netShared.d.ts +22 -0
  304. package/dist/commands/netShared.d.ts.map +1 -1
  305. package/dist/commands/netShared.js +43 -16
  306. package/dist/commands/netShared.js.map +1 -1
  307. package/dist/commands/netSse.d.ts +1 -1
  308. package/dist/commands/netSse.d.ts.map +1 -1
  309. package/dist/commands/netSummary.js +6 -25
  310. package/dist/commands/netSummary.js.map +1 -1
  311. package/dist/commands/netWebSocket.d.ts +2 -2
  312. package/dist/commands/netWebSocket.d.ts.map +1 -1
  313. package/dist/commands/page.d.ts +8 -0
  314. package/dist/commands/page.d.ts.map +1 -1
  315. package/dist/commands/page.js +83 -83
  316. package/dist/commands/page.js.map +1 -1
  317. package/dist/commands/pageEmulation.d.ts +3 -3
  318. package/dist/commands/pageEmulation.d.ts.map +1 -1
  319. package/dist/commands/pageEmulation.js +17 -12
  320. package/dist/commands/pageEmulation.js.map +1 -1
  321. package/dist/commands/pluginConfig.d.ts.map +1 -1
  322. package/dist/commands/pluginConfig.js +21 -20
  323. package/dist/commands/pluginConfig.js.map +1 -1
  324. package/dist/commands/record.d.ts +3 -3
  325. package/dist/commands/record.d.ts.map +1 -1
  326. package/dist/commands/record.js +1 -1
  327. package/dist/commands/record.js.map +1 -1
  328. package/dist/commands/reload.d.ts +1 -1
  329. package/dist/commands/reload.d.ts.map +1 -1
  330. package/dist/commands/resolveTestId.d.ts.map +1 -1
  331. package/dist/commands/resolveTestId.js +2 -3
  332. package/dist/commands/resolveTestId.js.map +1 -1
  333. package/dist/commands/screenshot.d.ts +1 -1
  334. package/dist/commands/screenshot.d.ts.map +1 -1
  335. package/dist/commands/snapshot.d.ts +1 -1
  336. package/dist/commands/snapshot.d.ts.map +1 -1
  337. package/dist/commands/start.d.ts.map +1 -1
  338. package/dist/commands/start.js +6 -28
  339. package/dist/commands/start.js.map +1 -1
  340. package/dist/commands/startShared.d.ts.map +1 -1
  341. package/dist/commands/startShared.js +2 -1
  342. package/dist/commands/startShared.js.map +1 -1
  343. package/dist/commands/throttle.d.ts +3 -3
  344. package/dist/commands/throttle.d.ts.map +1 -1
  345. package/dist/commands/throttle.js +2 -3
  346. package/dist/commands/throttle.js.map +1 -1
  347. package/dist/commands/trace.d.ts.map +1 -1
  348. package/dist/commands/trace.js +2 -2
  349. package/dist/commands/trace.js.map +1 -1
  350. package/dist/commands/watcherNativeHost.d.ts.map +1 -1
  351. package/dist/commands/watcherNativeHost.js +4 -1
  352. package/dist/commands/watcherNativeHost.js.map +1 -1
  353. package/dist/commands/watcherPrune.d.ts.map +1 -1
  354. package/dist/commands/watcherPrune.js +3 -3
  355. package/dist/commands/watcherPrune.js.map +1 -1
  356. package/dist/commands/watcherSession.d.ts.map +1 -1
  357. package/dist/commands/watcherSession.js +2 -1
  358. package/dist/commands/watcherSession.js.map +1 -1
  359. package/dist/commands/watcherStatus.d.ts +1 -1
  360. package/dist/commands/watcherStatus.d.ts.map +1 -1
  361. package/dist/commands/watcherStatus.js +5 -0
  362. package/dist/commands/watcherStatus.js.map +1 -1
  363. package/dist/commands/watcherStop.d.ts.map +1 -1
  364. package/dist/commands/watcherStop.js +2 -2
  365. package/dist/commands/watcherStop.js.map +1 -1
  366. package/dist/config/configContext.d.ts +27 -0
  367. package/dist/config/configContext.d.ts.map +1 -0
  368. package/dist/config/configContext.js +57 -0
  369. package/dist/config/configContext.js.map +1 -0
  370. package/dist/config/loadConfig.d.ts.map +1 -1
  371. package/dist/config/loadConfig.js +3 -2
  372. package/dist/config/loadConfig.js.map +1 -1
  373. package/dist/eval/evalClient.d.ts.map +1 -1
  374. package/dist/eval/evalClient.js +2 -1
  375. package/dist/eval/evalClient.js.map +1 -1
  376. package/dist/extension/dist/background/service-worker.js +469 -449
  377. package/dist/extension/dist/background/service-worker.js.map +4 -4
  378. package/dist/extension/dist/popup/popup.js +279 -234
  379. package/dist/extension/dist/popup/popup.js.map +4 -4
  380. package/dist/extension/manifest.json +1 -1
  381. package/dist/internal.d.ts +22 -0
  382. package/dist/internal.d.ts.map +1 -0
  383. package/dist/internal.js +22 -0
  384. package/dist/internal.js.map +1 -0
  385. package/dist/output/io.d.ts +8 -9
  386. package/dist/output/io.d.ts.map +1 -1
  387. package/dist/output/io.js.map +1 -1
  388. package/dist/registry.d.ts +1 -4
  389. package/dist/registry.d.ts.map +1 -1
  390. package/dist/registry.js +4 -25
  391. package/dist/registry.js.map +1 -1
  392. package/dist/runtime-code/format.d.ts.map +1 -1
  393. package/dist/runtime-code/format.js +2 -1
  394. package/dist/runtime-code/format.js.map +1 -1
  395. package/dist/skill/argus/SKILL.md +7 -0
  396. package/dist/skill/argus/reference/EXTENSION.md +8 -0
  397. package/dist/watchers/queryParams.d.ts +11 -9
  398. package/dist/watchers/queryParams.d.ts.map +1 -1
  399. package/dist/watchers/queryParams.js +63 -86
  400. package/dist/watchers/queryParams.js.map +1 -1
  401. package/dist/watchers/requestWatcher.d.ts +7 -25
  402. package/dist/watchers/requestWatcher.d.ts.map +1 -1
  403. package/dist/watchers/requestWatcher.js +9 -6
  404. package/dist/watchers/requestWatcher.js.map +1 -1
  405. package/dist/watchers/resolveWatcher.d.ts.map +1 -1
  406. package/dist/watchers/resolveWatcher.js +9 -2
  407. package/dist/watchers/resolveWatcher.js.map +1 -1
  408. package/package.json +9 -5
  409. package/dist/time.d.ts +0 -3
  410. package/dist/time.d.ts.map +0 -1
  411. package/dist/time.js +0 -19
  412. package/dist/time.js.map +0 -1
@@ -1,10 +1,125 @@
1
+ // src/background/frame-table.ts
2
+ var applyFrameTreeSnapshot = (table, sessionId, node) => {
3
+ if (!node?.frame?.id) {
4
+ return;
5
+ }
6
+ const nextFrameIds = /* @__PURE__ */ new Set();
7
+ mergeFrameTree(table, sessionId, node, nextFrameIds);
8
+ for (const [frameId, frame] of table.frames.entries()) {
9
+ if (frame.sessionId === sessionId && !nextFrameIds.has(frameId)) {
10
+ table.frames.delete(frameId);
11
+ }
12
+ }
13
+ };
14
+ var mergeFrameTree = (table, sessionId, node, nextFrameIds) => {
15
+ if (!node?.frame?.id) {
16
+ return;
17
+ }
18
+ const frameId = node.frame.id;
19
+ nextFrameIds.add(frameId);
20
+ table.frames.set(frameId, toFrameRecord(node.frame, sessionId));
21
+ if (!node.frame.parentId && !sessionId) {
22
+ table.topFrameId = frameId;
23
+ }
24
+ for (const child of node.childFrames ?? []) {
25
+ mergeFrameTree(table, sessionId, child, nextFrameIds);
26
+ }
27
+ };
28
+ var applyFrameEvent = (table, sessionId, method, params) => {
29
+ if (method === "Page.frameNavigated" && params) {
30
+ const frame = params.frame;
31
+ if (!frame?.id) {
32
+ return false;
33
+ }
34
+ table.frames.set(frame.id, toFrameRecord(frame, sessionId));
35
+ if (!frame.parentId && !sessionId && frame.url) {
36
+ table.url = frame.url;
37
+ table.topFrameId = frame.id;
38
+ }
39
+ return true;
40
+ }
41
+ if (method === "Page.frameAttached" && params) {
42
+ const frame = params;
43
+ if (!frame.frameId) {
44
+ return false;
45
+ }
46
+ const existing = table.frames.get(frame.frameId);
47
+ table.frames.set(frame.frameId, {
48
+ frameId: frame.frameId,
49
+ parentFrameId: frame.parentFrameId ?? table.topFrameId,
50
+ url: existing?.url ?? "",
51
+ title: existing?.title ?? null,
52
+ sessionId: existing?.sessionId ?? sessionId
53
+ });
54
+ return true;
55
+ }
56
+ if (method === "Page.frameDetached" && params) {
57
+ const frame = params;
58
+ if (!frame.frameId) {
59
+ return false;
60
+ }
61
+ return table.frames.delete(frame.frameId);
62
+ }
63
+ return false;
64
+ };
65
+ var dropSessionFrames = (table, sessionId) => {
66
+ let removed = false;
67
+ for (const [frameId, frame] of table.frames.entries()) {
68
+ if (frame.sessionId === sessionId) {
69
+ table.frames.delete(frameId);
70
+ removed = true;
71
+ }
72
+ }
73
+ return removed;
74
+ };
75
+ var serializeFrameTable = (table) => {
76
+ const frames = [...table.frames.values()].sort((a, b) => a.frameId.localeCompare(b.frameId));
77
+ return JSON.stringify({ topFrameId: table.topFrameId, frames });
78
+ };
79
+ var toFrameRecord = (frame, sessionId) => ({
80
+ frameId: frame.id,
81
+ parentFrameId: frame.parentId ?? null,
82
+ url: frame.url ?? "",
83
+ title: frame.name ?? null,
84
+ sessionId
85
+ });
86
+
87
+ // src/background/tab-cookies.ts
88
+ var readTabCookies = async (tabId, query = {}) => {
89
+ const storeId = await findCookieStoreId(tabId);
90
+ const cookies = await chrome.cookies.getAll({
91
+ domain: query.domain,
92
+ storeId: storeId ?? void 0,
93
+ url: query.domain ? void 0 : query.url
94
+ });
95
+ return cookies.map((cookie) => ({
96
+ name: cookie.name,
97
+ value: cookie.value,
98
+ domain: cookie.domain,
99
+ path: cookie.path,
100
+ secure: cookie.secure,
101
+ httpOnly: cookie.httpOnly,
102
+ session: cookie.session,
103
+ expires: typeof cookie.expirationDate === "number" ? cookie.expirationDate : null,
104
+ sameSite: cookie.sameSite ?? null
105
+ }));
106
+ };
107
+ var findCookieStoreId = async (tabId) => {
108
+ const stores = await chrome.cookies.getAllCookieStores();
109
+ const store = stores.find((candidate) => candidate.tabIds.includes(tabId));
110
+ return store?.id ?? null;
111
+ };
112
+
1
113
  // src/background/debugger-manager.ts
2
114
  var FRAME_TREE_SYNC_DELAY_MS = 150;
3
115
  var DebuggerManager = class {
4
116
  attached = /* @__PURE__ */ new Map();
5
117
  eventHandlers = /* @__PURE__ */ new Set();
6
118
  detachHandlers = /* @__PURE__ */ new Set();
119
+ framesChangedHandlers = /* @__PURE__ */ new Set();
7
120
  frameTreeSyncTimers = /* @__PURE__ */ new Map();
121
+ /** Last published frame table per tab; publishes that change nothing are suppressed. */
122
+ lastPublishedFrames = /* @__PURE__ */ new Map();
8
123
  constructor() {
9
124
  chrome.debugger.onEvent.addListener((debuggee, method, params) => {
10
125
  this.handleCdpEvent(debuggee, method, params);
@@ -27,6 +142,13 @@ var DebuggerManager = class {
27
142
  this.detachHandlers.delete(handler);
28
143
  };
29
144
  }
145
+ /** Subscribe to authoritative frame-table changes (deduplicated; see class doc). */
146
+ onFramesChanged(handler) {
147
+ this.framesChangedHandlers.add(handler);
148
+ return () => {
149
+ this.framesChangedHandlers.delete(handler);
150
+ };
151
+ }
30
152
  emitEvent(tabId, method, params, sessionId) {
31
153
  for (const handler of this.eventHandlers) {
32
154
  handler(tabId, method, params, { sessionId });
@@ -59,6 +181,7 @@ var DebuggerManager = class {
59
181
  this.attached.set(tabId, target);
60
182
  await this.configureAutoAttach(tabId);
61
183
  await this.refreshFrameTree(tabId, null);
184
+ this.lastPublishedFrames.set(tabId, serializeFrameTable(target));
62
185
  return target;
63
186
  }
64
187
  async detach(tabId) {
@@ -69,6 +192,7 @@ var DebuggerManager = class {
69
192
  } catch {
70
193
  }
71
194
  this.attached.delete(tabId);
195
+ this.lastPublishedFrames.delete(tabId);
72
196
  }
73
197
  async sendCommand(tabId, method, params, sessionId) {
74
198
  const target = this.getRequiredTarget(tabId);
@@ -100,29 +224,35 @@ var DebuggerManager = class {
100
224
  }
101
225
  return [...target.frames.values()];
102
226
  }
227
+ /** Current authoritative frame table for a tab, in `frame_snapshot` payload shape. */
228
+ getFrameSnapshot(tabId) {
229
+ return {
230
+ topFrameId: this.attached.get(tabId)?.topFrameId ?? null,
231
+ frames: this.getFrames(tabId)
232
+ };
233
+ }
103
234
  /**
104
- * Read cookies from the attached tab's cookie store so extension-mode auth export can keep
105
- * sibling subdomain session cookies such as `auth.example.com`.
235
+ * Re-read `Page.getFrameTree` for the root and every child session, then return the
236
+ * fresh table. Serves `frame_snapshot_request { refresh: true }` (bootstrap and target
237
+ * recovery on the watcher side). Marks the result as published — the caller ships it
238
+ * as the request's reply, so no push should follow for the same state.
106
239
  */
240
+ async resyncFrames(tabId) {
241
+ const target = this.getRequiredTarget(tabId);
242
+ await this.refreshFrameTree(tabId, null);
243
+ for (const sessionId of target.childSessions.keys()) {
244
+ try {
245
+ await this.refreshFrameTree(tabId, sessionId);
246
+ } catch {
247
+ }
248
+ }
249
+ this.lastPublishedFrames.set(tabId, serializeFrameTable(target));
250
+ return this.getFrameSnapshot(tabId);
251
+ }
252
+ /** Read cookies from the attached tab's cookie store (see tab-cookies.ts). */
107
253
  async getCookies(tabId, query = {}) {
108
254
  this.getRequiredTarget(tabId);
109
- const storeId = await this.findCookieStoreId(tabId);
110
- const cookies = await chrome.cookies.getAll({
111
- domain: query.domain,
112
- storeId: storeId ?? void 0,
113
- url: query.domain ? void 0 : query.url
114
- });
115
- return cookies.map((cookie) => ({
116
- name: cookie.name,
117
- value: cookie.value,
118
- domain: cookie.domain,
119
- path: cookie.path,
120
- secure: cookie.secure,
121
- httpOnly: cookie.httpOnly,
122
- session: cookie.session,
123
- expires: typeof cookie.expirationDate === "number" ? cookie.expirationDate : null,
124
- sameSite: cookie.sameSite ?? null
125
- }));
255
+ return readTabCookies(tabId, query);
126
256
  }
127
257
  async configureAutoAttach(tabId, sessionId) {
128
258
  await this.sendCommand(
@@ -167,11 +297,6 @@ var DebuggerManager = class {
167
297
  }
168
298
  return { tabId: target.tabId, sessionId };
169
299
  }
170
- async findCookieStoreId(tabId) {
171
- const stores = await chrome.cookies.getAllCookieStores();
172
- const store = stores.find((candidate) => candidate.tabIds.includes(tabId));
173
- return store?.id ?? null;
174
- }
175
300
  handleCdpEvent(debuggee, method, params) {
176
301
  const tabId = debuggee.tabId;
177
302
  if (!tabId || !this.attached.has(tabId)) return;
@@ -210,6 +335,7 @@ var DebuggerManager = class {
210
335
  await this.configureAutoAttach(tabId, record.sessionId);
211
336
  await this.enableChildSessionDomains(tabId, record.sessionId);
212
337
  await this.refreshFrameTree(tabId, record.sessionId);
338
+ this.emitFramesChangedIfNeeded(tabId, "child_attached");
213
339
  } catch (error) {
214
340
  console.warn("[DebuggerManager] Failed to bootstrap child target:", error);
215
341
  }
@@ -229,106 +355,34 @@ var DebuggerManager = class {
229
355
  }
230
356
  async refreshFrameTree(tabId, sessionId) {
231
357
  const result = await this.sendCommand(tabId, "Page.getFrameTree", void 0, sessionId);
232
- this.replaceFrameTreeSnapshot(tabId, sessionId, result.frameTree);
233
- }
234
- /**
235
- * Each `Page.getFrameTree` result is a full snapshot for that session, so merge the refreshed
236
- * nodes and then prune frames from the same session that no longer exist after reload.
237
- */
238
- replaceFrameTreeSnapshot(tabId, sessionId, node) {
239
- if (!node?.frame?.id) {
240
- return;
241
- }
242
- const target = this.attached.get(tabId);
243
- if (!target) {
244
- return;
245
- }
246
- const nextFrameIds = /* @__PURE__ */ new Set();
247
- this.mergeFrameTree(tabId, sessionId, node, nextFrameIds);
248
- this.pruneMissingSessionFrames(tabId, sessionId, nextFrameIds);
249
- }
250
- mergeFrameTree(tabId, sessionId, node, nextFrameIds) {
251
- if (!node?.frame?.id) {
252
- return;
253
- }
254
358
  const target = this.attached.get(tabId);
255
359
  if (!target) {
256
360
  return;
257
361
  }
258
- const frameId = node.frame.id;
259
- nextFrameIds.add(frameId);
260
- target.frames.set(frameId, this.toFrameRecord(node.frame, sessionId));
261
- if (!node.frame.parentId && !sessionId) {
262
- target.topFrameId = frameId;
263
- }
264
- this.emitEvent(
265
- tabId,
266
- "Page.frameNavigated",
267
- {
268
- frame: {
269
- id: frameId,
270
- parentId: node.frame.parentId ?? null,
271
- url: node.frame.url ?? "",
272
- name: node.frame.name ?? null
273
- }
274
- },
275
- sessionId
276
- );
277
- for (const child of node.childFrames ?? []) {
278
- this.mergeFrameTree(tabId, sessionId, child, nextFrameIds);
279
- }
362
+ applyFrameTreeSnapshot(target, sessionId, result.frameTree);
280
363
  }
281
- pruneMissingSessionFrames(tabId, sessionId, nextFrameIds) {
364
+ updateStateFromEvent(tabId, sessionId, method, params) {
282
365
  const target = this.attached.get(tabId);
283
366
  if (!target) {
284
367
  return;
285
368
  }
286
- for (const [frameId, frame] of target.frames.entries()) {
287
- if (frame.sessionId !== sessionId || nextFrameIds.has(frameId)) {
288
- continue;
289
- }
290
- target.frames.delete(frameId);
291
- this.emitEvent(tabId, "Page.frameDetached", { frameId }, sessionId);
369
+ if (applyFrameEvent(target, sessionId, method, params)) {
370
+ this.lastPublishedFrames.set(tabId, serializeFrameTable(target));
292
371
  }
293
372
  }
294
- updateStateFromEvent(tabId, sessionId, method, params) {
373
+ /** Publish the tab's frame table through onFramesChanged, unless it matches the last publish. */
374
+ emitFramesChangedIfNeeded(tabId, reason) {
295
375
  const target = this.attached.get(tabId);
296
376
  if (!target) {
297
377
  return;
298
378
  }
299
- if (method === "Page.frameNavigated" && params) {
300
- const frame = params.frame;
301
- if (!frame?.id) {
302
- return;
303
- }
304
- target.frames.set(frame.id, this.toFrameRecord(frame, sessionId));
305
- if (!frame.parentId && !sessionId && frame.url) {
306
- target.url = frame.url;
307
- target.topFrameId = frame.id;
308
- }
309
- return;
310
- }
311
- if (method === "Page.frameAttached" && params) {
312
- const frame = params;
313
- if (!frame.frameId) {
314
- return;
315
- }
316
- const existing = target.frames.get(frame.frameId);
317
- target.frames.set(frame.frameId, {
318
- frameId: frame.frameId,
319
- parentFrameId: frame.parentFrameId ?? target.topFrameId,
320
- url: existing?.url ?? "",
321
- title: existing?.title ?? null,
322
- sessionId: existing?.sessionId ?? sessionId
323
- });
379
+ const serialized = serializeFrameTable(target);
380
+ if (this.lastPublishedFrames.get(tabId) === serialized) {
324
381
  return;
325
382
  }
326
- if (method === "Page.frameDetached" && params) {
327
- const frame = params;
328
- if (!frame.frameId) {
329
- return;
330
- }
331
- target.frames.delete(frame.frameId);
383
+ this.lastPublishedFrames.set(tabId, serialized);
384
+ for (const handler of this.framesChangedHandlers) {
385
+ handler(tabId, reason);
332
386
  }
333
387
  }
334
388
  /**
@@ -346,7 +400,9 @@ var DebuggerManager = class {
346
400
  }
347
401
  const timer = setTimeout(() => {
348
402
  this.frameTreeSyncTimers.delete(key);
349
- void this.refreshFrameTree(tabId, sessionId).catch((error) => {
403
+ void this.refreshFrameTree(tabId, sessionId).then(() => {
404
+ this.emitFramesChangedIfNeeded(tabId, "navigation_resync");
405
+ }).catch((error) => {
350
406
  console.warn("[DebuggerManager] Failed to refresh frame tree after navigation:", error);
351
407
  });
352
408
  }, FRAME_TREE_SYNC_DELAY_MS);
@@ -370,15 +426,6 @@ var DebuggerManager = class {
370
426
  this.frameTreeSyncTimers.delete(key);
371
427
  }
372
428
  }
373
- toFrameRecord(frame, sessionId) {
374
- return {
375
- frameId: frame.id,
376
- parentFrameId: frame.parentId ?? null,
377
- url: frame.url ?? "",
378
- title: frame.name ?? null,
379
- sessionId
380
- };
381
- }
382
429
  handleDetach(tabId, sessionId, reason) {
383
430
  const target = this.attached.get(tabId);
384
431
  if (!target) {
@@ -391,6 +438,7 @@ var DebuggerManager = class {
391
438
  }
392
439
  this.clearAllFrameTreeSync(tabId);
393
440
  this.attached.delete(tabId);
441
+ this.lastPublishedFrames.delete(tabId);
394
442
  this.emitDetach(tabId, reason);
395
443
  }
396
444
  dropChildSession(tabId, sessionId) {
@@ -399,12 +447,8 @@ var DebuggerManager = class {
399
447
  return;
400
448
  }
401
449
  target.childSessions.delete(sessionId);
402
- for (const [frameId, frame] of target.frames.entries()) {
403
- if (frame.sessionId !== sessionId) {
404
- continue;
405
- }
406
- target.frames.delete(frameId);
407
- this.emitEvent(tabId, "Page.frameDetached", { frameId }, sessionId);
450
+ if (dropSessionFrames(target, sessionId)) {
451
+ this.emitFramesChangedIfNeeded(tabId, "child_detached");
408
452
  }
409
453
  }
410
454
  };
@@ -424,7 +468,6 @@ var BridgeClient = class {
424
468
  port = null;
425
469
  hostName;
426
470
  messageHandlers = /* @__PURE__ */ new Set();
427
- connectHandler = null;
428
471
  disconnectHandler = null;
429
472
  reconnectAttempts = 0;
430
473
  maxReconnectAttempts = 5;
@@ -441,12 +484,6 @@ var BridgeClient = class {
441
484
  onMessage(handler) {
442
485
  this.messageHandlers.add(handler);
443
486
  }
444
- /**
445
- * Set handler for successful connection.
446
- */
447
- onConnect(handler) {
448
- this.connectHandler = handler;
449
- }
450
487
  /**
451
488
  * Set handler for disconnection.
452
489
  */
@@ -480,9 +517,6 @@ var BridgeClient = class {
480
517
  });
481
518
  console.log("[BridgeClient] Connected to", this.hostName);
482
519
  this.reconnectAttempts = 0;
483
- if (this.connectHandler) {
484
- this.connectHandler();
485
- }
486
520
  return true;
487
521
  } catch (err) {
488
522
  console.error("[BridgeClient] Failed to connect:", err);
@@ -542,37 +576,13 @@ var BridgeClient = class {
542
576
  }
543
577
  };
544
578
 
545
- // src/background/tab-list.ts
546
- var listBrowserTabs = async (debuggerManager2, filter, options = {}) => {
547
- const chromeTabs = await chrome.tabs.query({});
548
- const attachedTargets = debuggerManager2.listAttached();
549
- const attachedTabIds = new Set(attachedTargets.map((target) => target.tabId));
550
- let tabs = chromeTabs.filter((tab) => tab.id !== void 0 && tab.url !== void 0).filter((tab) => !tab.url.startsWith("chrome://") && !tab.url.startsWith("chrome-extension://")).map((tab) => ({
551
- tabId: tab.id,
552
- url: tab.url,
553
- title: tab.title ?? "",
554
- faviconUrl: tab.favIconUrl,
555
- attached: attachedTabIds.has(tab.id),
556
- watcherId: options.getWatcherIdForTab?.(tab.id) ?? void 0
557
- }));
558
- if (filter?.url) {
559
- const urlFilter = filter.url.toLowerCase();
560
- tabs = tabs.filter((tab) => tab.url.toLowerCase().includes(urlFilter));
561
- }
562
- if (filter?.title) {
563
- const titleFilter = filter.title.toLowerCase();
564
- tabs = tabs.filter((tab) => tab.title.toLowerCase().includes(titleFilter));
565
- }
566
- tabs.sort((left, right) => Number(right.attached) - Number(left.attached));
567
- return tabs;
568
- };
569
-
570
579
  // src/background/cdp-proxy.ts
571
580
  var CdpProxy = class {
572
581
  debuggerManager;
573
582
  bridgeClient;
574
583
  removeDebuggerEventForwarding = null;
575
584
  removeDebuggerDetachForwarding = null;
585
+ removeFramesChangedForwarding = null;
576
586
  constructor(debuggerManager2, bridgeClient) {
577
587
  this.debuggerManager = debuggerManager2;
578
588
  this.bridgeClient = bridgeClient;
@@ -599,19 +609,31 @@ var CdpProxy = class {
599
609
  reason
600
610
  });
601
611
  });
612
+ this.removeFramesChangedForwarding = this.debuggerManager.onFramesChanged((tabId, reason) => {
613
+ this.bridgeClient.send({
614
+ type: "frame_snapshot",
615
+ tabId,
616
+ reason,
617
+ ...this.debuggerManager.getFrameSnapshot(tabId)
618
+ });
619
+ });
602
620
  }
603
621
  dispose() {
604
622
  this.removeDebuggerEventForwarding?.();
605
623
  this.removeDebuggerEventForwarding = null;
606
624
  this.removeDebuggerDetachForwarding?.();
607
625
  this.removeDebuggerDetachForwarding = null;
626
+ this.removeFramesChangedForwarding?.();
627
+ this.removeFramesChangedForwarding = null;
608
628
  }
609
629
  /**
610
630
  * Handle messages from the bridge.
611
631
  */
612
632
  setupMessageHandling() {
613
633
  this.bridgeClient.onMessage((message) => {
614
- this.handleMessage(message);
634
+ void this.handleMessage(message).catch((error) => {
635
+ console.error("[CdpProxy] Failed to handle bridge message:", error);
636
+ });
615
637
  });
616
638
  }
617
639
  /**
@@ -619,9 +641,6 @@ var CdpProxy = class {
619
641
  */
620
642
  async handleMessage(message) {
621
643
  switch (message.type) {
622
- case "attach_tab":
623
- await this.handleAttachTab(message);
624
- break;
625
644
  case "detach_tab":
626
645
  await this.handleDetachTab(message);
627
646
  break;
@@ -631,8 +650,8 @@ var CdpProxy = class {
631
650
  case "cookie_query":
632
651
  await this.handleCookieQuery(message);
633
652
  break;
634
- case "enable_domain":
635
- await this.handleEnableDomain(message);
653
+ case "frame_snapshot_request":
654
+ await this.handleFrameSnapshotRequest(message);
636
655
  break;
637
656
  case "host_info":
638
657
  case "host_ready":
@@ -643,11 +662,11 @@ var CdpProxy = class {
643
662
  }
644
663
  }
645
664
  /**
646
- * Attach to a tab.
665
+ * Attach to a tab (driven by the popup; the host never requests attachment).
647
666
  */
648
- async handleAttachTab(message) {
667
+ async attachTab(tabId) {
649
668
  try {
650
- const target = await this.debuggerManager.attach(message.tabId);
669
+ const target = await this.debuggerManager.attach(tabId);
651
670
  this.bridgeClient.send({
652
671
  type: "tab_attached",
653
672
  tabId: target.tabId,
@@ -661,9 +680,10 @@ var CdpProxy = class {
661
680
  console.error("[CdpProxy] Failed to attach:", err);
662
681
  this.bridgeClient.send({
663
682
  type: "tab_detached",
664
- tabId: message.tabId,
683
+ tabId,
665
684
  reason: err instanceof Error ? err.message : "attach_failed"
666
685
  });
686
+ throw err;
667
687
  }
668
688
  }
669
689
  /**
@@ -693,6 +713,26 @@ var CdpProxy = class {
693
713
  });
694
714
  }
695
715
  }
716
+ /**
717
+ * Answer a watcher pull for the frame table. With `refresh` the table is re-read from
718
+ * Chrome first; either way the reply is the full current table, so applying it is
719
+ * idempotent on the watcher side.
720
+ */
721
+ async handleFrameSnapshotRequest(message) {
722
+ let snapshot;
723
+ try {
724
+ snapshot = message.refresh ? await this.debuggerManager.resyncFrames(message.tabId) : this.debuggerManager.getFrameSnapshot(message.tabId);
725
+ } catch {
726
+ snapshot = this.debuggerManager.getFrameSnapshot(message.tabId);
727
+ }
728
+ this.bridgeClient.send({
729
+ type: "frame_snapshot",
730
+ tabId: message.tabId,
731
+ reason: "requested",
732
+ requestId: message.requestId,
733
+ ...snapshot
734
+ });
735
+ }
696
736
  /**
697
737
  * Query browser cookies from the attached tab's cookie store.
698
738
  */
@@ -717,22 +757,6 @@ var CdpProxy = class {
717
757
  });
718
758
  }
719
759
  }
720
- /**
721
- * Enable a CDP domain for a tab.
722
- */
723
- async handleEnableDomain(message) {
724
- try {
725
- await this.debuggerManager.enableDomain(message.tabId, message.domain);
726
- } catch (err) {
727
- console.error("[CdpProxy] Failed to enable domain:", err);
728
- }
729
- }
730
- /**
731
- * Manually attach to a tab (called from popup).
732
- */
733
- async attachTab(tabId) {
734
- await this.handleAttachTab({ type: "attach_tab", tabId });
735
- }
736
760
  /**
737
761
  * Manually detach from a tab (called from popup).
738
762
  */
@@ -744,18 +768,60 @@ var CdpProxy = class {
744
768
  });
745
769
  await this.debuggerManager.detach(tabId);
746
770
  }
747
- /**
748
- * Get list of tabs for popup UI.
749
- */
750
- async getTabsForPopup() {
751
- return await listBrowserTabs(this.debuggerManager);
752
- }
753
771
  };
754
772
 
755
773
  // src/background/native-hosts.ts
756
774
  var BRIDGE_HOST_NAME = "com.vforsh.argus.bridge";
757
775
  var CONTROL_HOST_NAME = "com.vforsh.argus.control";
758
776
 
777
+ // src/background/latch.ts
778
+ var createLatch = () => {
779
+ let open = false;
780
+ let waiters = [];
781
+ return {
782
+ get isOpen() {
783
+ return open;
784
+ },
785
+ wait: (timeoutMs, timeoutMessage) => {
786
+ if (open) {
787
+ return Promise.resolve();
788
+ }
789
+ return new Promise((resolve, reject) => {
790
+ const onOpen = () => {
791
+ clearTimeout(timer);
792
+ resolve();
793
+ };
794
+ const timer = setTimeout(() => {
795
+ waiters = waiters.filter((waiter) => waiter !== onOpen);
796
+ reject(new Error(timeoutMessage));
797
+ }, timeoutMs);
798
+ waiters.push(onOpen);
799
+ });
800
+ },
801
+ signal: () => {
802
+ open = true;
803
+ const pending = waiters;
804
+ waiters = [];
805
+ for (const waiter of pending) {
806
+ waiter();
807
+ }
808
+ }
809
+ };
810
+ };
811
+
812
+ // ../argus-core/dist/protocol/native-messaging.js
813
+ var NATIVE_MESSAGING_PROTOCOL_VERSION = 2;
814
+
815
+ // src/background/protocol-handshake.ts
816
+ var checkHostProtocol = (message) => {
817
+ const hostVersion = message.protocolVersion;
818
+ if (hostVersion === NATIVE_MESSAGING_PROTOCOL_VERSION) {
819
+ return null;
820
+ }
821
+ const reported = hostVersion == null ? "none (predates the handshake)" : String(hostVersion);
822
+ return `Argus native host speaks native-messaging protocol ${reported}, extension expects ${NATIVE_MESSAGING_PROTOCOL_VERSION}. Update argus (npm i -g @vforsh/argus) and reload the extension.`;
823
+ };
824
+
759
825
  // src/background/tab-bridge-session.ts
760
826
  var TabBridgeSession = class {
761
827
  tabId;
@@ -766,10 +832,10 @@ var TabBridgeSession = class {
766
832
  targetInfo = null;
767
833
  desiredWatcherId;
768
834
  lastMessageAt = null;
769
- ready = false;
770
- readyWaiters = [];
771
- watcherInfoWaiters = [];
835
+ hostReady = createLatch();
836
+ watcherInfoReceived = createLatch();
772
837
  disposed = false;
838
+ protocolMismatch = null;
773
839
  constructor(tabId, debuggerManager2, events = {}, options = {}) {
774
840
  this.tabId = tabId;
775
841
  this.events = events;
@@ -799,27 +865,10 @@ var TabBridgeSession = class {
799
865
  if (!sent) {
800
866
  throw new Error(`Failed to initialize watcher for tab ${this.tabId}`);
801
867
  }
802
- await this.waitUntilReady();
803
- await this.waitForWatcherInfo();
868
+ await this.awaitLatch(this.hostReady, "did not become ready");
869
+ await this.awaitLatch(this.watcherInfoReceived, "did not report watcher info");
804
870
  await this.cdpProxy.attachTab(this.tabId);
805
871
  }
806
- async waitUntilReady(timeoutMs = 3e3) {
807
- this.assertOpen();
808
- if (this.ready) {
809
- return;
810
- }
811
- await new Promise((resolve, reject) => {
812
- const timer = setTimeout(() => {
813
- this.readyWaiters = this.readyWaiters.filter((waiter) => waiter !== onReady);
814
- reject(new Error(`Native host session for tab ${this.tabId} did not become ready`));
815
- }, timeoutMs);
816
- const onReady = () => {
817
- clearTimeout(timer);
818
- resolve();
819
- };
820
- this.readyWaiters.push(onReady);
821
- });
822
- }
823
872
  async detach() {
824
873
  if (this.disposed) {
825
874
  return;
@@ -861,27 +910,22 @@ var TabBridgeSession = class {
861
910
  getLastMessageAt() {
862
911
  return this.lastMessageAt;
863
912
  }
864
- async waitForWatcherInfo(timeoutMs = 3e3) {
913
+ async awaitLatch(latch, failure, timeoutMs = 3e3) {
865
914
  this.assertOpen();
866
- if (this.watcherInfo) {
867
- return;
868
- }
869
- await new Promise((resolve, reject) => {
870
- const timer = setTimeout(() => {
871
- this.watcherInfoWaiters = this.watcherInfoWaiters.filter((waiter) => waiter !== onWatcherInfo);
872
- reject(new Error(`Native host session for tab ${this.tabId} did not report watcher info`));
873
- }, timeoutMs);
874
- const onWatcherInfo = () => {
875
- clearTimeout(timer);
876
- resolve();
877
- };
878
- this.watcherInfoWaiters.push(onWatcherInfo);
879
- });
915
+ await latch.wait(timeoutMs, `Native host session for tab ${this.tabId} ${failure}`);
880
916
  }
881
917
  handleMessage(message) {
882
918
  this.lastMessageAt = Date.now();
883
919
  switch (message.type) {
884
- case "host_info":
920
+ case "host_info": {
921
+ const mismatch = checkHostProtocol(message);
922
+ if (mismatch) {
923
+ console.error(`[TabBridgeSession] ${mismatch}`);
924
+ this.protocolMismatch = mismatch;
925
+ this.dispose();
926
+ this.events.onDisconnect?.();
927
+ return;
928
+ }
885
929
  this.watcherInfo = {
886
930
  watcherId: message.watcherId,
887
931
  watcherHost: message.watcherHost,
@@ -889,10 +933,11 @@ var TabBridgeSession = class {
889
933
  pid: message.pid
890
934
  };
891
935
  this.events.onWatcherInfo?.(this.watcherInfo);
892
- this.resolveWatcherInfoWaiters();
936
+ this.watcherInfoReceived.signal();
893
937
  return;
938
+ }
894
939
  case "host_ready":
895
- this.resolveReadyWaiters();
940
+ this.hostReady.signal();
896
941
  return;
897
942
  case "target_info":
898
943
  this.targetInfo = {
@@ -905,28 +950,52 @@ var TabBridgeSession = class {
905
950
  this.events.onTargetInfo?.(this.targetInfo);
906
951
  }
907
952
  }
908
- resolveReadyWaiters() {
909
- this.ready = true;
910
- const waiters = this.readyWaiters;
911
- this.readyWaiters = [];
912
- for (const waiter of waiters) {
913
- waiter();
914
- }
915
- }
916
- resolveWatcherInfoWaiters() {
917
- const waiters = this.watcherInfoWaiters;
918
- this.watcherInfoWaiters = [];
919
- for (const waiter of waiters) {
920
- waiter();
921
- }
922
- }
923
953
  assertOpen() {
954
+ if (this.protocolMismatch) {
955
+ throw new Error(this.protocolMismatch);
956
+ }
924
957
  if (this.disposed) {
925
958
  throw new Error(`Native host session for tab ${this.tabId} is already closed`);
926
959
  }
927
960
  }
928
961
  };
929
962
 
963
+ // src/background/tab-list.ts
964
+ var listBrowserTabs = async (debuggerManager2, filter, options = {}) => {
965
+ const chromeTabs = await chrome.tabs.query({});
966
+ const attachedTargets = debuggerManager2.listAttached();
967
+ const attachedTabIds = new Set(attachedTargets.map((target) => target.tabId));
968
+ let tabs = chromeTabs.filter((tab) => tab.id !== void 0 && tab.url !== void 0).filter((tab) => !tab.url.startsWith("chrome://") && !tab.url.startsWith("chrome-extension://")).map((tab) => ({
969
+ tabId: tab.id,
970
+ url: tab.url,
971
+ title: tab.title ?? "",
972
+ faviconUrl: tab.favIconUrl,
973
+ attached: attachedTabIds.has(tab.id),
974
+ watcherId: options.getWatcherIdForTab?.(tab.id) ?? void 0
975
+ }));
976
+ if (filter?.url) {
977
+ const urlFilter = filter.url.toLowerCase();
978
+ tabs = tabs.filter((tab) => tab.url.toLowerCase().includes(urlFilter));
979
+ }
980
+ if (filter?.title) {
981
+ const titleFilter = filter.title.toLowerCase();
982
+ tabs = tabs.filter((tab) => tab.title.toLowerCase().includes(titleFilter));
983
+ }
984
+ tabs.sort((left, right) => Number(right.attached) - Number(left.attached));
985
+ return tabs;
986
+ };
987
+
988
+ // ../argus-core/dist/errorMessage.js
989
+ var formatError = (error) => {
990
+ if (!error) {
991
+ return "unknown error";
992
+ }
993
+ if (error instanceof Error) {
994
+ return error.message;
995
+ }
996
+ return String(error);
997
+ };
998
+
930
999
  // src/background/control-bridge-session.ts
931
1000
  var ControlBridgeSession = class {
932
1001
  bridgeClient;
@@ -972,7 +1041,13 @@ var ControlBridgeSession = class {
972
1041
  async handleMessage(message) {
973
1042
  this.lastMessageAt = Date.now();
974
1043
  switch (message.type) {
975
- case "host_info":
1044
+ case "host_info": {
1045
+ const mismatch = checkHostProtocol(message);
1046
+ if (mismatch) {
1047
+ console.error(`[ControlBridgeSession] ${mismatch}`);
1048
+ this.bridgeClient.disconnect();
1049
+ return;
1050
+ }
976
1051
  this.watcherInfo = {
977
1052
  watcherId: message.watcherId,
978
1053
  watcherHost: message.watcherHost,
@@ -981,6 +1056,7 @@ var ControlBridgeSession = class {
981
1056
  };
982
1057
  this.events.onWatcherInfo?.(this.watcherInfo);
983
1058
  return;
1059
+ }
984
1060
  case "attach_tab_watcher":
985
1061
  await this.handleTabAction(message.requestId, () => this.events.onAttachTabWatcher?.(message.tabId, { watcherId: message.watcherId }));
986
1062
  return;
@@ -1010,7 +1086,7 @@ var ControlBridgeSession = class {
1010
1086
  type: "tab_action_response",
1011
1087
  requestId,
1012
1088
  ok: false,
1013
- error: { message: error instanceof Error ? error.message : String(error) }
1089
+ error: { message: formatError(error) }
1014
1090
  });
1015
1091
  }
1016
1092
  }
@@ -1054,6 +1130,79 @@ var ControlBridgeSession = class {
1054
1130
  }
1055
1131
  };
1056
1132
 
1133
+ // src/background/page-keyed-store.ts
1134
+ var readStorageValue = async (storageArea, key) => new Promise((resolve, reject) => {
1135
+ storageArea.get(key, (items) => {
1136
+ const error = chrome.runtime.lastError;
1137
+ if (error) {
1138
+ reject(new Error(error.message));
1139
+ return;
1140
+ }
1141
+ resolve(items[key]);
1142
+ });
1143
+ });
1144
+ var writeStorageValue = async (storageArea, items) => new Promise((resolve, reject) => {
1145
+ storageArea.set(items, () => {
1146
+ const error = chrome.runtime.lastError;
1147
+ if (error) {
1148
+ reject(new Error(error.message));
1149
+ return;
1150
+ }
1151
+ resolve();
1152
+ });
1153
+ });
1154
+ var normalizeOptionalText = (value) => {
1155
+ if (typeof value !== "string") {
1156
+ return null;
1157
+ }
1158
+ const trimmed = value.trim();
1159
+ return trimmed === "" ? null : trimmed;
1160
+ };
1161
+ var sortByUpdatedAtDesc = (left, right) => right.updatedAt - left.updatedAt;
1162
+ var createChromeStorePersistence = (storageKey, sanitize, storageArea = chrome.storage.local) => ({
1163
+ load: async () => sanitize(await readStorageValue(storageArea, storageKey)),
1164
+ save: async (entries) => {
1165
+ await writeStorageValue(storageArea, { [storageKey]: entries });
1166
+ }
1167
+ });
1168
+ var PageKeyedStore = class {
1169
+ constructor(persistence, maxEntries, label) {
1170
+ this.persistence = persistence;
1171
+ this.maxEntries = maxEntries;
1172
+ this.label = label;
1173
+ }
1174
+ entries = [];
1175
+ loadPromise = null;
1176
+ saveChain = Promise.resolve();
1177
+ /** Load on first use; later calls await the same load. */
1178
+ async ensureLoaded() {
1179
+ if (!this.loadPromise) {
1180
+ this.loadPromise = this.persistence.load().then((entries) => {
1181
+ this.entries = entries.slice(0, this.maxEntries);
1182
+ }).catch((error) => {
1183
+ console.error(`[${this.label}] Failed to load history:`, error);
1184
+ this.entries = [];
1185
+ });
1186
+ }
1187
+ await this.loadPromise;
1188
+ }
1189
+ /** Persist the current entries, serialized behind any in-flight save. */
1190
+ async persist() {
1191
+ this.saveChain = this.saveChain.catch(() => void 0).then(() => this.persistence.save(this.entries)).catch((error) => {
1192
+ console.error(`[${this.label}] Failed to save history:`, error);
1193
+ });
1194
+ await this.saveChain;
1195
+ }
1196
+ /** Move an entry to the front, replacing any entry with the same page key. */
1197
+ upsert(entry) {
1198
+ this.entries = [entry, ...this.entries.filter((candidate) => candidate.pageKey !== entry.pageKey)].slice(0, this.maxEntries);
1199
+ }
1200
+ /** Find the entry for a page key. */
1201
+ findByPageKey(pageKey) {
1202
+ return this.entries.find((entry) => entry.pageKey === pageKey) ?? null;
1203
+ }
1204
+ };
1205
+
1057
1206
  // src/background/target-selection-history.ts
1058
1207
  var DEFAULT_STORAGE_KEY = "targetSelectionHistory";
1059
1208
  var DEFAULT_MAX_ENTRIES = 20;
@@ -1079,55 +1228,23 @@ var matchRememberedIframeTarget = (entry, targets) => {
1079
1228
  }
1080
1229
  return pickSingleTargetMatch(iframeTargets, (target) => normalizeTargetTitle(target.title) === rememberedIframe.title);
1081
1230
  };
1082
- var TargetSelectionHistoryStore = class {
1083
- persistence;
1084
- maxEntries;
1085
- entries = [];
1086
- loadPromise = null;
1087
- saveChain = Promise.resolve();
1231
+ var TargetSelectionHistoryStore = class extends PageKeyedStore {
1088
1232
  constructor(persistence = createChromeStoragePersistence(), options = {}) {
1089
- this.persistence = persistence;
1090
- this.maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
1233
+ super(persistence, options.maxEntries ?? DEFAULT_MAX_ENTRIES, "TargetSelectionHistoryStore");
1091
1234
  }
1092
1235
  async getByPageUrl(pageUrl) {
1093
1236
  await this.ensureLoaded();
1094
- const pageKey = normalizeSelectionPageKey(pageUrl);
1095
- return this.entries.find((entry) => entry.pageKey === pageKey) ?? null;
1237
+ return this.findByPageKey(normalizeSelectionPageKey(pageUrl));
1096
1238
  }
1097
1239
  async remember(pageUrl, target) {
1098
1240
  await this.ensureLoaded();
1099
1241
  const entry = buildRememberedSelection(pageUrl, target);
1100
- this.entries = [entry, ...this.entries.filter((candidate) => candidate.pageKey !== entry.pageKey)].slice(0, this.maxEntries);
1242
+ this.upsert(entry);
1101
1243
  await this.persist();
1102
1244
  return entry;
1103
1245
  }
1104
- async ensureLoaded() {
1105
- if (!this.loadPromise) {
1106
- this.loadPromise = this.persistence.load().then((entries) => {
1107
- this.entries = sanitizeRememberedSelections(entries).slice(0, this.maxEntries);
1108
- }).catch((error) => {
1109
- console.error("[TargetSelectionHistoryStore] Failed to load history:", error);
1110
- this.entries = [];
1111
- });
1112
- }
1113
- await this.loadPromise;
1114
- }
1115
- async persist() {
1116
- this.saveChain = this.saveChain.catch(() => void 0).then(() => this.persistence.save(this.entries)).catch((error) => {
1117
- console.error("[TargetSelectionHistoryStore] Failed to save history:", error);
1118
- });
1119
- await this.saveChain;
1120
- }
1121
1246
  };
1122
- var createChromeStoragePersistence = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY) => ({
1123
- load: async () => {
1124
- const stored = await readStorageValue(storageArea, storageKey);
1125
- return sanitizeRememberedSelections(Array.isArray(stored) ? stored : []);
1126
- },
1127
- save: async (entries) => {
1128
- await writeStorageValue(storageArea, { [storageKey]: entries });
1129
- }
1130
- });
1247
+ var createChromeStoragePersistence = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY) => createChromeStorePersistence(storageKey, (value) => sanitizeRememberedSelections(Array.isArray(value) ? value : []), storageArea);
1131
1248
  var buildRememberedSelection = (pageUrl, target) => {
1132
1249
  const base = {
1133
1250
  pageKey: normalizeSelectionPageKey(pageUrl),
@@ -1190,56 +1307,25 @@ var sanitizeRememberedSelection = (entry) => {
1190
1307
  };
1191
1308
  };
1192
1309
  function normalizeTargetUrl(url) {
1193
- return normalizeOptionalText(url);
1310
+ return normalizeOptionalText2(url);
1194
1311
  }
1195
1312
  function normalizeTargetTitle(title) {
1196
- return normalizeOptionalText(title);
1313
+ return normalizeOptionalText2(title);
1197
1314
  }
1198
- function normalizeOptionalText(value) {
1315
+ function normalizeOptionalText2(value) {
1199
1316
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
1200
1317
  }
1201
- var sortByUpdatedAtDesc = (left, right) => right.updatedAt - left.updatedAt;
1202
- var readStorageValue = async (storageArea, key) => {
1203
- return await new Promise((resolve, reject) => {
1204
- storageArea.get(key, (items) => {
1205
- const error = chrome.runtime.lastError;
1206
- if (error) {
1207
- reject(new Error(error.message));
1208
- return;
1209
- }
1210
- resolve(items[key]);
1211
- });
1212
- });
1213
- };
1214
- var writeStorageValue = async (storageArea, items) => {
1215
- await new Promise((resolve, reject) => {
1216
- storageArea.set(items, () => {
1217
- const error = chrome.runtime.lastError;
1218
- if (error) {
1219
- reject(new Error(error.message));
1220
- return;
1221
- }
1222
- resolve();
1223
- });
1224
- });
1225
- };
1226
1318
 
1227
1319
  // src/background/target-visibility-history.ts
1228
1320
  var DEFAULT_STORAGE_KEY2 = "hiddenTargetHistory";
1229
1321
  var DEFAULT_MAX_PAGE_ENTRIES = 20;
1230
- var TargetVisibilityHistoryStore = class {
1231
- persistence;
1232
- maxPageEntries;
1233
- entries = [];
1234
- loadPromise = null;
1235
- saveChain = Promise.resolve();
1322
+ var TargetVisibilityHistoryStore = class extends PageKeyedStore {
1236
1323
  constructor(persistence = createChromeStoragePersistence2(), options = {}) {
1237
- this.persistence = persistence;
1238
- this.maxPageEntries = options.maxPageEntries ?? DEFAULT_MAX_PAGE_ENTRIES;
1324
+ super(persistence, options.maxPageEntries ?? DEFAULT_MAX_PAGE_ENTRIES, "TargetVisibilityHistoryStore");
1239
1325
  }
1240
1326
  async getHiddenTargets(pageUrl) {
1241
1327
  await this.ensureLoaded();
1242
- return [...this.findEntry(pageUrl)?.targets ?? []];
1328
+ return [...this.findByPageKey(normalizeSelectionPageKey(pageUrl))?.targets ?? []];
1243
1329
  }
1244
1330
  async hide(pageUrl, target) {
1245
1331
  await this.ensureLoaded();
@@ -1248,10 +1334,10 @@ var TargetVisibilityHistoryStore = class {
1248
1334
  return null;
1249
1335
  }
1250
1336
  const pageKey = normalizeSelectionPageKey(pageUrl);
1251
- const existing = this.findEntry(pageUrl);
1337
+ const existing = this.findByPageKey(normalizeSelectionPageKey(pageUrl));
1252
1338
  const targets = uniqueHiddenTargets([hiddenTarget, ...existing?.targets ?? []]);
1253
1339
  const entry = { pageKey, pageUrl, updatedAt: Date.now(), targets };
1254
- this.upsertEntry(entry);
1340
+ this.upsert(entry);
1255
1341
  await this.persist();
1256
1342
  return entry;
1257
1343
  }
@@ -1261,7 +1347,7 @@ var TargetVisibilityHistoryStore = class {
1261
1347
  if (!hiddenTarget) {
1262
1348
  return;
1263
1349
  }
1264
- const existing = this.findEntry(pageUrl);
1350
+ const existing = this.findByPageKey(normalizeSelectionPageKey(pageUrl));
1265
1351
  if (!existing) {
1266
1352
  return;
1267
1353
  }
@@ -1274,44 +1360,8 @@ var TargetVisibilityHistoryStore = class {
1274
1360
  this.entries = this.entries.map((entry) => entry.pageKey === existing.pageKey ? { ...entry, targets, updatedAt: Date.now() } : entry);
1275
1361
  await this.persist();
1276
1362
  }
1277
- async isHidden(pageUrl, target) {
1278
- const hiddenTargets = await this.getHiddenTargets(pageUrl);
1279
- return hiddenTargets.some((hiddenTarget) => matchesHiddenTarget(hiddenTarget, target));
1280
- }
1281
- findEntry(pageUrl) {
1282
- const pageKey = normalizeSelectionPageKey(pageUrl);
1283
- return this.entries.find((entry) => entry.pageKey === pageKey) ?? null;
1284
- }
1285
- upsertEntry(entry) {
1286
- this.entries = [entry, ...this.entries.filter((candidate) => candidate.pageKey !== entry.pageKey)].slice(0, this.maxPageEntries);
1287
- }
1288
- async ensureLoaded() {
1289
- if (!this.loadPromise) {
1290
- this.loadPromise = this.persistence.load().then((entries) => {
1291
- this.entries = sanitizeHiddenTargetEntries(entries).slice(0, this.maxPageEntries);
1292
- }).catch((error) => {
1293
- console.error("[TargetVisibilityHistoryStore] Failed to load history:", error);
1294
- this.entries = [];
1295
- });
1296
- }
1297
- await this.loadPromise;
1298
- }
1299
- async persist() {
1300
- this.saveChain = this.saveChain.catch(() => void 0).then(() => this.persistence.save(this.entries)).catch((error) => {
1301
- console.error("[TargetVisibilityHistoryStore] Failed to save history:", error);
1302
- });
1303
- await this.saveChain;
1304
- }
1305
1363
  };
1306
- var createChromeStoragePersistence2 = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY2) => ({
1307
- load: async () => {
1308
- const stored = await readStorageValue2(storageArea, storageKey);
1309
- return sanitizeHiddenTargetEntries(Array.isArray(stored) ? stored : []);
1310
- },
1311
- save: async (entries) => {
1312
- await writeStorageValue2(storageArea, { [storageKey]: entries });
1313
- }
1314
- });
1364
+ var createChromeStoragePersistence2 = (storageArea = chrome.storage.local, storageKey = DEFAULT_STORAGE_KEY2) => createChromeStorePersistence(storageKey, (value) => sanitizeHiddenTargetEntries(Array.isArray(value) ? value : []), storageArea);
1315
1365
  function matchesHiddenTarget(hiddenTarget, target) {
1316
1366
  if (target.type !== "iframe") {
1317
1367
  return false;
@@ -1323,8 +1373,8 @@ function toHiddenTarget(target) {
1323
1373
  if (target.type !== "iframe") {
1324
1374
  return null;
1325
1375
  }
1326
- const url = normalizeOptionalText2(target.url);
1327
- const title = normalizeOptionalText2(target.title);
1376
+ const url = normalizeOptionalText(target.url);
1377
+ const title = normalizeOptionalText(target.title);
1328
1378
  if (!url && !title) {
1329
1379
  return null;
1330
1380
  }
@@ -1346,7 +1396,7 @@ function isSameHiddenTarget(left, right) {
1346
1396
  return left.title === right.title;
1347
1397
  }
1348
1398
  function sanitizeHiddenTargetEntries(entries) {
1349
- return entries.map(sanitizeHiddenTargetEntry).filter((entry) => entry !== null).sort(sortByUpdatedAtDesc2);
1399
+ return entries.map(sanitizeHiddenTargetEntry).filter((entry) => entry !== null).sort(sortByUpdatedAtDesc);
1350
1400
  }
1351
1401
  function sanitizeHiddenTargetEntry(entry) {
1352
1402
  const candidate = entry;
@@ -1369,41 +1419,13 @@ function sanitizeHiddenTarget(target) {
1369
1419
  if (candidate?.type !== "iframe") {
1370
1420
  return null;
1371
1421
  }
1372
- const url = normalizeOptionalText2(typeof candidate.url === "string" ? candidate.url : null);
1373
- const title = normalizeOptionalText2(typeof candidate.title === "string" ? candidate.title : null);
1422
+ const url = normalizeOptionalText(typeof candidate.url === "string" ? candidate.url : null);
1423
+ const title = normalizeOptionalText(typeof candidate.title === "string" ? candidate.title : null);
1374
1424
  if (!url && !title) {
1375
1425
  return null;
1376
1426
  }
1377
1427
  return { type: "iframe", url, title };
1378
1428
  }
1379
- function normalizeOptionalText2(value) {
1380
- return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
1381
- }
1382
- var sortByUpdatedAtDesc2 = (left, right) => right.updatedAt - left.updatedAt;
1383
- var readStorageValue2 = async (storageArea, key) => {
1384
- return await new Promise((resolve, reject) => {
1385
- storageArea.get(key, (items) => {
1386
- const error = chrome.runtime.lastError;
1387
- if (error) {
1388
- reject(new Error(error.message));
1389
- return;
1390
- }
1391
- resolve(items[key]);
1392
- });
1393
- });
1394
- };
1395
- var writeStorageValue2 = async (storageArea, items) => {
1396
- await new Promise((resolve, reject) => {
1397
- storageArea.set(items, () => {
1398
- const error = chrome.runtime.lastError;
1399
- if (error) {
1400
- reject(new Error(error.message));
1401
- return;
1402
- }
1403
- resolve();
1404
- });
1405
- });
1406
- };
1407
1429
 
1408
1430
  // src/background/action-badge.ts
1409
1431
  var badgeSyncChain = Promise.resolve();
@@ -1516,10 +1538,8 @@ function createWatcherStatus(debuggerManager2, tabId, session, watcherInfo, curr
1516
1538
  const readiness = buildWatcherReadiness(debuggerManager2, tabId, session, watcherInfo, currentTarget);
1517
1539
  return {
1518
1540
  tabId,
1519
- bridgeConnected: readiness.nativeHostConnected,
1520
- nativeHostConnected: readiness.nativeHostConnected,
1541
+ bridgeConnected: readiness.bridgeConnected,
1521
1542
  watcherReady: readiness.watcherReady,
1522
- targetReady: readiness.targetReady,
1523
1543
  targetState: readiness.targetState,
1524
1544
  watcherId: watcherInfo?.watcherId ?? null,
1525
1545
  watcherHost: watcherInfo?.watcherHost ?? null,
@@ -1530,13 +1550,14 @@ function createWatcherStatus(debuggerManager2, tabId, session, watcherInfo, curr
1530
1550
  };
1531
1551
  }
1532
1552
  function buildWatcherReadiness(debuggerManager2, tabId, session, watcherInfo, currentTarget) {
1533
- const nativeHostConnected = session.isConnected();
1534
- const watcherReady = nativeHostConnected && Boolean(watcherInfo?.watcherId && watcherInfo.watcherHost && watcherInfo.watcherPort != null);
1553
+ const bridgeConnected = session.isConnected();
1554
+ const watcherReady = bridgeConnected && Boolean(watcherInfo?.watcherId && watcherInfo.watcherHost && watcherInfo.watcherPort != null);
1535
1555
  const targetReady = currentTarget?.targetReady ?? getTargetReadiness(debuggerManager2, tabId, currentTarget);
1536
1556
  return {
1537
- nativeHostConnected,
1557
+ bridgeConnected,
1538
1558
  watcherReady,
1539
- targetReady,
1559
+ // targetReady is not surfaced on its own: the popup only ever renders this
1560
+ // three-state derivation of it.
1540
1561
  targetState: targetReady == null ? "not-selected" : targetReady ? "ready" : "rebinding"
1541
1562
  };
1542
1563
  }
@@ -1565,9 +1586,14 @@ var controlBridgeSession = new ControlBridgeSession(debuggerManager, {
1565
1586
  recordEvent("error", "bridge", "Control native host disconnected");
1566
1587
  }
1567
1588
  });
1568
- var bridgeSessions = /* @__PURE__ */ new Map();
1569
- var selectedFrameByTabId = /* @__PURE__ */ new Map();
1570
- var pendingRememberedTargetByTabId = /* @__PURE__ */ new Map();
1589
+ var attachments = /* @__PURE__ */ new Map();
1590
+ var bridgeSessions = {
1591
+ get: (tabId) => attachments.get(tabId)?.session,
1592
+ has: (tabId) => attachments.has(tabId),
1593
+ keys: () => attachments.keys(),
1594
+ values: () => [...attachments.values()].map((attachment) => attachment.session),
1595
+ entries: () => [...attachments.entries()].map(([tabId, attachment]) => [tabId, attachment.session])
1596
+ };
1571
1597
  var targetSelectionHistory = new TargetSelectionHistoryStore();
1572
1598
  var targetVisibilityHistory = new TargetVisibilityHistoryStore();
1573
1599
  var recentEvents = [];
@@ -1634,7 +1660,7 @@ async function attachTabFromControl(tabId, options = {}) {
1634
1660
  }
1635
1661
  return { ok: true, tab, watcherId: session.getWatcherInfo()?.watcherId };
1636
1662
  } catch (error) {
1637
- return { ok: false, error: error instanceof Error ? error.message : String(error) };
1663
+ return { ok: false, error: formatError(error) };
1638
1664
  }
1639
1665
  }
1640
1666
  async function detachTabFromControl(tabId) {
@@ -1648,16 +1674,19 @@ async function detachTabFromControl(tabId) {
1648
1674
  }
1649
1675
  return { ok: true, tab };
1650
1676
  } catch (error) {
1651
- return { ok: false, error: error instanceof Error ? error.message : String(error) };
1677
+ return { ok: false, error: formatError(error) };
1652
1678
  }
1653
1679
  }
1654
1680
  async function buildPopupResponse(message) {
1681
+ return await dispatchPopupAction(message);
1682
+ }
1683
+ async function dispatchPopupAction(message) {
1655
1684
  try {
1656
1685
  switch (message.action) {
1657
1686
  case "getTargets":
1658
1687
  return { success: true, tabs: await getTabsWithTargets() };
1659
1688
  case "attach": {
1660
- const tabId = requireTabId(message);
1689
+ const { tabId } = message;
1661
1690
  await attachBridgeSession(tabId);
1662
1691
  setSelectedFrame(tabId, null);
1663
1692
  await prepareRememberedTargetSelection(tabId);
@@ -1665,24 +1694,23 @@ async function buildPopupResponse(message) {
1665
1694
  return { success: true };
1666
1695
  }
1667
1696
  case "detach": {
1668
- const tabId = requireTabId(message);
1697
+ const { tabId } = message;
1669
1698
  await detachTab(tabId);
1670
1699
  recordEvent("info", "popup", `Detached tab ${tabId}`);
1671
1700
  return { success: true };
1672
1701
  }
1673
1702
  case "focusTab": {
1674
- const tabId = requireTabId(message);
1703
+ const { tabId } = message;
1675
1704
  await focusTab(tabId);
1676
1705
  recordEvent("info", "popup", `Focused tab ${tabId}`);
1677
1706
  return { success: true };
1678
1707
  }
1679
1708
  case "selectTarget": {
1680
- const tabId = requireTabId(message);
1709
+ const { tabId, frameId } = message;
1681
1710
  const session = bridgeSessions.get(tabId);
1682
1711
  if (!session) {
1683
1712
  return { success: false, error: `No watcher bridge for tab ${tabId}` };
1684
1713
  }
1685
- const frameId = message.frameId ?? null;
1686
1714
  const target = getPopupTarget(debuggerManager, tabId, frameId);
1687
1715
  if (!target) {
1688
1716
  return { success: false, error: `Unknown target for tab ${tabId}` };
@@ -1695,15 +1723,15 @@ async function buildPopupResponse(message) {
1695
1723
  return { success: true };
1696
1724
  }
1697
1725
  case "hideTarget": {
1698
- const tabId = requireTabId(message);
1699
- const target = getRequiredIframeTarget(debuggerManager, tabId, message.frameId ?? null);
1726
+ const { tabId, frameId } = message;
1727
+ const target = getRequiredIframeTarget(debuggerManager, tabId, frameId);
1700
1728
  await hideTarget(tabId, target);
1701
1729
  recordEvent("info", "popup", `Hid iframe ${target.frameId} on tab ${tabId}`);
1702
1730
  return { success: true };
1703
1731
  }
1704
1732
  case "showTarget": {
1705
- const tabId = requireTabId(message);
1706
- const target = getRequiredIframeTarget(debuggerManager, tabId, message.frameId ?? null);
1733
+ const { tabId, frameId } = message;
1734
+ const target = getRequiredIframeTarget(debuggerManager, tabId, frameId);
1707
1735
  await showTarget(tabId, target);
1708
1736
  recordEvent("info", "popup", `Restored iframe ${target.frameId} on tab ${tabId}`);
1709
1737
  return { success: true };
@@ -1713,8 +1741,6 @@ async function buildPopupResponse(message) {
1713
1741
  success: true,
1714
1742
  status: buildPopupStatusPayload()
1715
1743
  };
1716
- default:
1717
- return { success: false, error: `Unknown action: ${message.action}` };
1718
1744
  }
1719
1745
  } catch (err) {
1720
1746
  recordEvent("error", "popup", err instanceof Error ? err.message : "Unknown popup error");
@@ -1724,12 +1750,6 @@ async function buildPopupResponse(message) {
1724
1750
  };
1725
1751
  }
1726
1752
  }
1727
- function requireTabId(message) {
1728
- if (message.tabId !== void 0) {
1729
- return message.tabId;
1730
- }
1731
- throw new Error("No tabId provided");
1732
- }
1733
1753
  async function attachBridgeSession(tabId, options = {}) {
1734
1754
  const existing = bridgeSessions.get(tabId);
1735
1755
  if (existing) {
@@ -1756,7 +1776,7 @@ async function attachBridgeSession(tabId, options = {}) {
1756
1776
  },
1757
1777
  options
1758
1778
  );
1759
- bridgeSessions.set(tabId, session);
1779
+ attachments.set(tabId, { session });
1760
1780
  await connectBridgeSession(tabId, session);
1761
1781
  return session;
1762
1782
  }
@@ -1783,16 +1803,11 @@ async function connectBridgeSession(tabId, session) {
1783
1803
  }
1784
1804
  }
1785
1805
  function clearTabState(tabId) {
1786
- selectedFrameByTabId.delete(tabId);
1787
- clearPendingRememberedTarget(tabId);
1788
1806
  destroyBridgeSession(tabId);
1789
1807
  }
1790
1808
  function pruneStaleBridgeSessions() {
1791
- for (const [tabId, session] of bridgeSessions.entries()) {
1792
- if (debuggerManager.isAttached(tabId)) {
1793
- continue;
1794
- }
1795
- if (!session.getTargetInfo()) {
1809
+ for (const [tabId, attachment] of attachments.entries()) {
1810
+ if (debuggerManager.isAttached(tabId) || !attachment.session.getTargetInfo()) {
1796
1811
  continue;
1797
1812
  }
1798
1813
  clearTabState(tabId);
@@ -1800,12 +1815,12 @@ function pruneStaleBridgeSessions() {
1800
1815
  }
1801
1816
  }
1802
1817
  function destroyBridgeSession(tabId) {
1803
- const session = bridgeSessions.get(tabId);
1804
- if (!session) {
1818
+ const attachment = attachments.get(tabId);
1819
+ if (!attachment) {
1805
1820
  return;
1806
1821
  }
1807
- bridgeSessions.delete(tabId);
1808
- session.dispose();
1822
+ attachments.delete(tabId);
1823
+ attachment.session.dispose();
1809
1824
  }
1810
1825
  function buildPopupStatusPayload() {
1811
1826
  return {
@@ -1815,8 +1830,7 @@ function buildPopupStatusPayload() {
1815
1830
  url: target.url,
1816
1831
  title: target.title
1817
1832
  })),
1818
- watchers: getWatcherStatuses(),
1819
- recentEvents
1833
+ watchers: getWatcherStatuses()
1820
1834
  };
1821
1835
  }
1822
1836
  function buildControlDiagnostics() {
@@ -1904,10 +1918,7 @@ function syncSelectedFrameFromWatcher(targetId) {
1904
1918
  setSelectedFrame(target.tabId, target.frameId);
1905
1919
  }
1906
1920
  function getSelectedFrameId(tabId) {
1907
- if (!selectedFrameByTabId.has(tabId)) {
1908
- return void 0;
1909
- }
1910
- return selectedFrameByTabId.get(tabId) ?? null;
1921
+ return attachments.get(tabId)?.selectedFrameId;
1911
1922
  }
1912
1923
  async function rememberTargetSelection(tabId, target) {
1913
1924
  const pageUrl = getPageUrlForTab(debuggerManager, tabId);
@@ -1962,9 +1973,9 @@ async function prepareRememberedTargetSelection(tabId) {
1962
1973
  await replayRememberedTargetSelection(tabId);
1963
1974
  }
1964
1975
  async function replayRememberedTargetSelection(tabId) {
1965
- const remembered = pendingRememberedTargetByTabId.get(tabId);
1966
- const session = bridgeSessions.get(tabId);
1967
- if (!remembered || !session) {
1976
+ const attachment = attachments.get(tabId);
1977
+ const remembered = attachment?.pendingRememberedTarget;
1978
+ if (!attachment || !remembered) {
1968
1979
  return;
1969
1980
  }
1970
1981
  const target = matchRememberedIframeTarget(
@@ -1975,7 +1986,7 @@ async function replayRememberedTargetSelection(tabId) {
1975
1986
  return;
1976
1987
  }
1977
1988
  try {
1978
- session.selectTarget(target.frameId);
1989
+ attachment.session.selectTarget(target.frameId);
1979
1990
  setSelectedFrame(tabId, target.frameId);
1980
1991
  clearPendingRememberedTarget(tabId);
1981
1992
  recordEvent("info", "bridge", `Restored iframe ${target.frameId} on tab ${tabId}`);
@@ -1984,16 +1995,25 @@ async function replayRememberedTargetSelection(tabId) {
1984
1995
  }
1985
1996
  }
1986
1997
  function shouldReplayRememberedTarget(tabId, method) {
1987
- return pendingRememberedTargetByTabId.has(tabId) && REMEMBERED_TARGET_RETRY_EVENTS.has(method);
1998
+ return attachments.get(tabId)?.pendingRememberedTarget != null && REMEMBERED_TARGET_RETRY_EVENTS.has(method);
1988
1999
  }
1989
2000
  function setSelectedFrame(tabId, frameId) {
1990
- selectedFrameByTabId.set(tabId, frameId);
2001
+ const attachment = attachments.get(tabId);
2002
+ if (attachment) {
2003
+ attachment.selectedFrameId = frameId;
2004
+ }
1991
2005
  }
1992
2006
  function setPendingRememberedTarget(tabId, remembered) {
1993
- pendingRememberedTargetByTabId.set(tabId, remembered);
2007
+ const attachment = attachments.get(tabId);
2008
+ if (attachment) {
2009
+ attachment.pendingRememberedTarget = remembered;
2010
+ }
1994
2011
  }
1995
2012
  function clearPendingRememberedTarget(tabId) {
1996
- pendingRememberedTargetByTabId.delete(tabId);
2013
+ const attachment = attachments.get(tabId);
2014
+ if (attachment) {
2015
+ delete attachment.pendingRememberedTarget;
2016
+ }
1997
2017
  }
1998
2018
  console.log("[ServiceWorker] Argus CDP Bridge extension loaded");
1999
2019
  void syncActionBadge(debuggerManager);