openchrome-mcp 1.0.2

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 (396) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +180 -0
  3. package/assets/demo.svg +278 -0
  4. package/assets/mascot.png +0 -0
  5. package/dist/cdp/client.d.ts +219 -0
  6. package/dist/cdp/client.d.ts.map +1 -0
  7. package/dist/cdp/client.js +804 -0
  8. package/dist/cdp/client.js.map +1 -0
  9. package/dist/cdp/connection-pool.d.ts +116 -0
  10. package/dist/cdp/connection-pool.d.ts.map +1 -0
  11. package/dist/cdp/connection-pool.js +393 -0
  12. package/dist/cdp/connection-pool.js.map +1 -0
  13. package/dist/cdp/screenshot-scheduler.d.ts +54 -0
  14. package/dist/cdp/screenshot-scheduler.d.ts.map +1 -0
  15. package/dist/cdp/screenshot-scheduler.js +87 -0
  16. package/dist/cdp/screenshot-scheduler.js.map +1 -0
  17. package/dist/chrome/launcher.d.ts +68 -0
  18. package/dist/chrome/launcher.d.ts.map +1 -0
  19. package/dist/chrome/launcher.js +523 -0
  20. package/dist/chrome/launcher.js.map +1 -0
  21. package/dist/chrome/pool.d.ts +54 -0
  22. package/dist/chrome/pool.d.ts.map +1 -0
  23. package/dist/chrome/pool.js +301 -0
  24. package/dist/chrome/pool.js.map +1 -0
  25. package/dist/chrome/profile-detector.d.ts +52 -0
  26. package/dist/chrome/profile-detector.d.ts.map +1 -0
  27. package/dist/chrome/profile-detector.js +246 -0
  28. package/dist/chrome/profile-detector.js.map +1 -0
  29. package/dist/cli/claude-session.d.ts +11 -0
  30. package/dist/cli/claude-session.js +349 -0
  31. package/dist/cli/claude-session.js.map +1 -0
  32. package/dist/cli/index.d.ts +14 -0
  33. package/dist/cli/index.js +858 -0
  34. package/dist/cli/index.js.map +1 -0
  35. package/dist/cli/install.d.ts +16 -0
  36. package/dist/cli/install.js +185 -0
  37. package/dist/cli/install.js.map +1 -0
  38. package/dist/cli/uninstall.d.ts +7 -0
  39. package/dist/cli/uninstall.js +126 -0
  40. package/dist/cli/uninstall.js.map +1 -0
  41. package/dist/cli/update-check.d.ts +9 -0
  42. package/dist/cli/update-check.js +141 -0
  43. package/dist/cli/update-check.js.map +1 -0
  44. package/dist/config/config-recovery.d.ts +69 -0
  45. package/dist/config/config-recovery.d.ts.map +1 -0
  46. package/dist/config/config-recovery.js +302 -0
  47. package/dist/config/config-recovery.js.map +1 -0
  48. package/dist/config/global.d.ts +51 -0
  49. package/dist/config/global.d.ts.map +1 -0
  50. package/dist/config/global.js +24 -0
  51. package/dist/config/global.js.map +1 -0
  52. package/dist/config/index.d.ts +7 -0
  53. package/dist/config/index.d.ts.map +1 -0
  54. package/dist/config/index.js +23 -0
  55. package/dist/config/index.js.map +1 -0
  56. package/dist/config/session-isolator.d.ts +76 -0
  57. package/dist/config/session-isolator.d.ts.map +1 -0
  58. package/dist/config/session-isolator.js +268 -0
  59. package/dist/config/session-isolator.js.map +1 -0
  60. package/dist/dashboard/activity-tracker.d.ts +76 -0
  61. package/dist/dashboard/activity-tracker.d.ts.map +1 -0
  62. package/dist/dashboard/activity-tracker.js +219 -0
  63. package/dist/dashboard/activity-tracker.js.map +1 -0
  64. package/dist/dashboard/ansi.d.ts +117 -0
  65. package/dist/dashboard/ansi.d.ts.map +1 -0
  66. package/dist/dashboard/ansi.js +199 -0
  67. package/dist/dashboard/ansi.js.map +1 -0
  68. package/dist/dashboard/index.d.ts +110 -0
  69. package/dist/dashboard/index.d.ts.map +1 -0
  70. package/dist/dashboard/index.js +412 -0
  71. package/dist/dashboard/index.js.map +1 -0
  72. package/dist/dashboard/keyboard-handler.d.ts +43 -0
  73. package/dist/dashboard/keyboard-handler.d.ts.map +1 -0
  74. package/dist/dashboard/keyboard-handler.js +230 -0
  75. package/dist/dashboard/keyboard-handler.js.map +1 -0
  76. package/dist/dashboard/operation-controller.d.ts +76 -0
  77. package/dist/dashboard/operation-controller.d.ts.map +1 -0
  78. package/dist/dashboard/operation-controller.js +167 -0
  79. package/dist/dashboard/operation-controller.js.map +1 -0
  80. package/dist/dashboard/renderer.d.ts +76 -0
  81. package/dist/dashboard/renderer.d.ts.map +1 -0
  82. package/dist/dashboard/renderer.js +193 -0
  83. package/dist/dashboard/renderer.js.map +1 -0
  84. package/dist/dashboard/types.d.ts +56 -0
  85. package/dist/dashboard/types.d.ts.map +1 -0
  86. package/dist/dashboard/types.js +12 -0
  87. package/dist/dashboard/types.js.map +1 -0
  88. package/dist/dashboard/views/main-view.d.ts +23 -0
  89. package/dist/dashboard/views/main-view.d.ts.map +1 -0
  90. package/dist/dashboard/views/main-view.js +143 -0
  91. package/dist/dashboard/views/main-view.js.map +1 -0
  92. package/dist/dashboard/views/sessions-view.d.ts +22 -0
  93. package/dist/dashboard/views/sessions-view.d.ts.map +1 -0
  94. package/dist/dashboard/views/sessions-view.js +104 -0
  95. package/dist/dashboard/views/sessions-view.js.map +1 -0
  96. package/dist/dashboard/views/tabs-view.d.ts +21 -0
  97. package/dist/dashboard/views/tabs-view.d.ts.map +1 -0
  98. package/dist/dashboard/views/tabs-view.js +92 -0
  99. package/dist/dashboard/views/tabs-view.js.map +1 -0
  100. package/dist/hints/hint-engine.d.ts +77 -0
  101. package/dist/hints/hint-engine.d.ts.map +1 -0
  102. package/dist/hints/hint-engine.js +191 -0
  103. package/dist/hints/hint-engine.js.map +1 -0
  104. package/dist/hints/index.d.ts +8 -0
  105. package/dist/hints/index.d.ts.map +1 -0
  106. package/dist/hints/index.js +11 -0
  107. package/dist/hints/index.js.map +1 -0
  108. package/dist/hints/pattern-learner.d.ts +76 -0
  109. package/dist/hints/pattern-learner.d.ts.map +1 -0
  110. package/dist/hints/pattern-learner.js +254 -0
  111. package/dist/hints/pattern-learner.js.map +1 -0
  112. package/dist/hints/rules/composite-suggestions.d.ts +6 -0
  113. package/dist/hints/rules/composite-suggestions.d.ts.map +1 -0
  114. package/dist/hints/rules/composite-suggestions.js +66 -0
  115. package/dist/hints/rules/composite-suggestions.js.map +1 -0
  116. package/dist/hints/rules/error-recovery.d.ts +7 -0
  117. package/dist/hints/rules/error-recovery.d.ts.map +1 -0
  118. package/dist/hints/rules/error-recovery.js +55 -0
  119. package/dist/hints/rules/error-recovery.js.map +1 -0
  120. package/dist/hints/rules/learned-rules.d.ts +13 -0
  121. package/dist/hints/rules/learned-rules.d.ts.map +1 -0
  122. package/dist/hints/rules/learned-rules.js +27 -0
  123. package/dist/hints/rules/learned-rules.js.map +1 -0
  124. package/dist/hints/rules/repetition-detection.d.ts +7 -0
  125. package/dist/hints/rules/repetition-detection.d.ts.map +1 -0
  126. package/dist/hints/rules/repetition-detection.js +82 -0
  127. package/dist/hints/rules/repetition-detection.js.map +1 -0
  128. package/dist/hints/rules/sequence-detection.d.ts +6 -0
  129. package/dist/hints/rules/sequence-detection.d.ts.map +1 -0
  130. package/dist/hints/rules/sequence-detection.js +89 -0
  131. package/dist/hints/rules/sequence-detection.js.map +1 -0
  132. package/dist/hints/rules/success-hints.d.ts +6 -0
  133. package/dist/hints/rules/success-hints.d.ts.map +1 -0
  134. package/dist/hints/rules/success-hints.js +62 -0
  135. package/dist/hints/rules/success-hints.js.map +1 -0
  136. package/dist/index.d.ts +10 -0
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +278 -0
  139. package/dist/index.js.map +1 -0
  140. package/dist/lightpanda/launcher.d.ts +58 -0
  141. package/dist/lightpanda/launcher.d.ts.map +1 -0
  142. package/dist/lightpanda/launcher.js +210 -0
  143. package/dist/lightpanda/launcher.js.map +1 -0
  144. package/dist/mcp-server.d.ts +129 -0
  145. package/dist/mcp-server.d.ts.map +1 -0
  146. package/dist/mcp-server.js +641 -0
  147. package/dist/mcp-server.js.map +1 -0
  148. package/dist/memory/domain-memory.d.ts +68 -0
  149. package/dist/memory/domain-memory.d.ts.map +1 -0
  150. package/dist/memory/domain-memory.js +228 -0
  151. package/dist/memory/domain-memory.js.map +1 -0
  152. package/dist/orchestration/plan-executor.d.ts +19 -0
  153. package/dist/orchestration/plan-executor.d.ts.map +1 -0
  154. package/dist/orchestration/plan-executor.js +284 -0
  155. package/dist/orchestration/plan-executor.js.map +1 -0
  156. package/dist/orchestration/plan-registry.d.ts +55 -0
  157. package/dist/orchestration/plan-registry.d.ts.map +1 -0
  158. package/dist/orchestration/plan-registry.js +255 -0
  159. package/dist/orchestration/plan-registry.js.map +1 -0
  160. package/dist/orchestration/state-manager.d.ts +127 -0
  161. package/dist/orchestration/state-manager.d.ts.map +1 -0
  162. package/dist/orchestration/state-manager.js +438 -0
  163. package/dist/orchestration/state-manager.js.map +1 -0
  164. package/dist/orchestration/workflow-engine.d.ts +162 -0
  165. package/dist/orchestration/workflow-engine.d.ts.map +1 -0
  166. package/dist/orchestration/workflow-engine.js +745 -0
  167. package/dist/orchestration/workflow-engine.js.map +1 -0
  168. package/dist/resources/usage-guide.d.ts +13 -0
  169. package/dist/resources/usage-guide.d.ts.map +1 -0
  170. package/dist/resources/usage-guide.js +101 -0
  171. package/dist/resources/usage-guide.js.map +1 -0
  172. package/dist/router/browser-router.d.ts +51 -0
  173. package/dist/router/browser-router.d.ts.map +1 -0
  174. package/dist/router/browser-router.js +178 -0
  175. package/dist/router/browser-router.js.map +1 -0
  176. package/dist/router/cookie-sync.d.ts +48 -0
  177. package/dist/router/cookie-sync.d.ts.map +1 -0
  178. package/dist/router/cookie-sync.js +106 -0
  179. package/dist/router/cookie-sync.js.map +1 -0
  180. package/dist/router/index.d.ts +5 -0
  181. package/dist/router/index.d.ts.map +1 -0
  182. package/dist/router/index.js +10 -0
  183. package/dist/router/index.js.map +1 -0
  184. package/dist/router/tool-routing-registry.d.ts +21 -0
  185. package/dist/router/tool-routing-registry.d.ts.map +1 -0
  186. package/dist/router/tool-routing-registry.js +90 -0
  187. package/dist/router/tool-routing-registry.js.map +1 -0
  188. package/dist/session-manager.d.ts +251 -0
  189. package/dist/session-manager.d.ts.map +1 -0
  190. package/dist/session-manager.js +953 -0
  191. package/dist/session-manager.js.map +1 -0
  192. package/dist/tools/batch-execute.d.ts +11 -0
  193. package/dist/tools/batch-execute.d.ts.map +1 -0
  194. package/dist/tools/batch-execute.js +226 -0
  195. package/dist/tools/batch-execute.js.map +1 -0
  196. package/dist/tools/click-element.d.ts +8 -0
  197. package/dist/tools/click-element.d.ts.map +1 -0
  198. package/dist/tools/click-element.js +455 -0
  199. package/dist/tools/click-element.js.map +1 -0
  200. package/dist/tools/computer.d.ts +6 -0
  201. package/dist/tools/computer.d.ts.map +1 -0
  202. package/dist/tools/computer.js +638 -0
  203. package/dist/tools/computer.js.map +1 -0
  204. package/dist/tools/console-capture.d.ts +6 -0
  205. package/dist/tools/console-capture.d.ts.map +1 -0
  206. package/dist/tools/console-capture.js +320 -0
  207. package/dist/tools/console-capture.js.map +1 -0
  208. package/dist/tools/cookies.d.ts +6 -0
  209. package/dist/tools/cookies.d.ts.map +1 -0
  210. package/dist/tools/cookies.js +263 -0
  211. package/dist/tools/cookies.js.map +1 -0
  212. package/dist/tools/drag-drop.d.ts +6 -0
  213. package/dist/tools/drag-drop.d.ts.map +1 -0
  214. package/dist/tools/drag-drop.js +252 -0
  215. package/dist/tools/drag-drop.js.map +1 -0
  216. package/dist/tools/emulate-device.d.ts +6 -0
  217. package/dist/tools/emulate-device.d.ts.map +1 -0
  218. package/dist/tools/emulate-device.js +221 -0
  219. package/dist/tools/emulate-device.js.map +1 -0
  220. package/dist/tools/file-upload.d.ts +6 -0
  221. package/dist/tools/file-upload.d.ts.map +1 -0
  222. package/dist/tools/file-upload.js +209 -0
  223. package/dist/tools/file-upload.js.map +1 -0
  224. package/dist/tools/fill-form.d.ts +8 -0
  225. package/dist/tools/fill-form.d.ts.map +1 -0
  226. package/dist/tools/fill-form.js +342 -0
  227. package/dist/tools/fill-form.js.map +1 -0
  228. package/dist/tools/find.d.ts +6 -0
  229. package/dist/tools/find.d.ts.map +1 -0
  230. package/dist/tools/find.js +330 -0
  231. package/dist/tools/find.js.map +1 -0
  232. package/dist/tools/form-input.d.ts +6 -0
  233. package/dist/tools/form-input.d.ts.map +1 -0
  234. package/dist/tools/form-input.js +181 -0
  235. package/dist/tools/form-input.js.map +1 -0
  236. package/dist/tools/geolocation.d.ts +6 -0
  237. package/dist/tools/geolocation.d.ts.map +1 -0
  238. package/dist/tools/geolocation.js +172 -0
  239. package/dist/tools/geolocation.js.map +1 -0
  240. package/dist/tools/http-auth.d.ts +6 -0
  241. package/dist/tools/http-auth.d.ts.map +1 -0
  242. package/dist/tools/http-auth.js +136 -0
  243. package/dist/tools/http-auth.js.map +1 -0
  244. package/dist/tools/index.d.ts +6 -0
  245. package/dist/tools/index.d.ts.map +1 -0
  246. package/dist/tools/index.js +104 -0
  247. package/dist/tools/index.js.map +1 -0
  248. package/dist/tools/javascript.d.ts +6 -0
  249. package/dist/tools/javascript.d.ts.map +1 -0
  250. package/dist/tools/javascript.js +138 -0
  251. package/dist/tools/javascript.js.map +1 -0
  252. package/dist/tools/lightweight-scroll.d.ts +11 -0
  253. package/dist/tools/lightweight-scroll.d.ts.map +1 -0
  254. package/dist/tools/lightweight-scroll.js +266 -0
  255. package/dist/tools/lightweight-scroll.js.map +1 -0
  256. package/dist/tools/memory.d.ts +10 -0
  257. package/dist/tools/memory.d.ts.map +1 -0
  258. package/dist/tools/memory.js +141 -0
  259. package/dist/tools/memory.js.map +1 -0
  260. package/dist/tools/navigate.d.ts +6 -0
  261. package/dist/tools/navigate.d.ts.map +1 -0
  262. package/dist/tools/navigate.js +241 -0
  263. package/dist/tools/navigate.js.map +1 -0
  264. package/dist/tools/network.d.ts +6 -0
  265. package/dist/tools/network.d.ts.map +1 -0
  266. package/dist/tools/network.js +215 -0
  267. package/dist/tools/network.js.map +1 -0
  268. package/dist/tools/orchestration.d.ts +6 -0
  269. package/dist/tools/orchestration.d.ts.map +1 -0
  270. package/dist/tools/orchestration.js +741 -0
  271. package/dist/tools/orchestration.js.map +1 -0
  272. package/dist/tools/page-content.d.ts +6 -0
  273. package/dist/tools/page-content.d.ts.map +1 -0
  274. package/dist/tools/page-content.js +120 -0
  275. package/dist/tools/page-content.js.map +1 -0
  276. package/dist/tools/page-pdf.d.ts +6 -0
  277. package/dist/tools/page-pdf.d.ts.map +1 -0
  278. package/dist/tools/page-pdf.js +246 -0
  279. package/dist/tools/page-pdf.js.map +1 -0
  280. package/dist/tools/page-reload.d.ts +6 -0
  281. package/dist/tools/page-reload.d.ts.map +1 -0
  282. package/dist/tools/page-reload.js +89 -0
  283. package/dist/tools/page-reload.js.map +1 -0
  284. package/dist/tools/performance-metrics.d.ts +6 -0
  285. package/dist/tools/performance-metrics.d.ts.map +1 -0
  286. package/dist/tools/performance-metrics.js +158 -0
  287. package/dist/tools/performance-metrics.js.map +1 -0
  288. package/dist/tools/read-page.d.ts +6 -0
  289. package/dist/tools/read-page.d.ts.map +1 -0
  290. package/dist/tools/read-page.js +287 -0
  291. package/dist/tools/read-page.js.map +1 -0
  292. package/dist/tools/request-intercept.d.ts +6 -0
  293. package/dist/tools/request-intercept.d.ts.map +1 -0
  294. package/dist/tools/request-intercept.js +439 -0
  295. package/dist/tools/request-intercept.js.map +1 -0
  296. package/dist/tools/selector-query.d.ts +6 -0
  297. package/dist/tools/selector-query.d.ts.map +1 -0
  298. package/dist/tools/selector-query.js +206 -0
  299. package/dist/tools/selector-query.js.map +1 -0
  300. package/dist/tools/shutdown.d.ts +12 -0
  301. package/dist/tools/shutdown.d.ts.map +1 -0
  302. package/dist/tools/shutdown.js +120 -0
  303. package/dist/tools/shutdown.js.map +1 -0
  304. package/dist/tools/storage.d.ts +6 -0
  305. package/dist/tools/storage.d.ts.map +1 -0
  306. package/dist/tools/storage.js +264 -0
  307. package/dist/tools/storage.js.map +1 -0
  308. package/dist/tools/tabs-close.d.ts +6 -0
  309. package/dist/tools/tabs-close.d.ts.map +1 -0
  310. package/dist/tools/tabs-close.js +124 -0
  311. package/dist/tools/tabs-close.js.map +1 -0
  312. package/dist/tools/tabs-context.d.ts +6 -0
  313. package/dist/tools/tabs-context.d.ts.map +1 -0
  314. package/dist/tools/tabs-context.js +92 -0
  315. package/dist/tools/tabs-context.js.map +1 -0
  316. package/dist/tools/tabs-create.d.ts +6 -0
  317. package/dist/tools/tabs-create.d.ts.map +1 -0
  318. package/dist/tools/tabs-create.js +73 -0
  319. package/dist/tools/tabs-create.js.map +1 -0
  320. package/dist/tools/user-agent.d.ts +6 -0
  321. package/dist/tools/user-agent.d.ts.map +1 -0
  322. package/dist/tools/user-agent.js +128 -0
  323. package/dist/tools/user-agent.js.map +1 -0
  324. package/dist/tools/wait-and-click.d.ts +8 -0
  325. package/dist/tools/wait-and-click.d.ts.map +1 -0
  326. package/dist/tools/wait-and-click.js +290 -0
  327. package/dist/tools/wait-and-click.js.map +1 -0
  328. package/dist/tools/wait-for.d.ts +6 -0
  329. package/dist/tools/wait-for.d.ts.map +1 -0
  330. package/dist/tools/wait-for.js +248 -0
  331. package/dist/tools/wait-for.js.map +1 -0
  332. package/dist/tools/worker-create.d.ts +7 -0
  333. package/dist/tools/worker-create.d.ts.map +1 -0
  334. package/dist/tools/worker-create.js +62 -0
  335. package/dist/tools/worker-create.js.map +1 -0
  336. package/dist/tools/worker-delete.d.ts +6 -0
  337. package/dist/tools/worker-delete.d.ts.map +1 -0
  338. package/dist/tools/worker-delete.js +80 -0
  339. package/dist/tools/worker-delete.js.map +1 -0
  340. package/dist/tools/worker-list.d.ts +6 -0
  341. package/dist/tools/worker-list.d.ts.map +1 -0
  342. package/dist/tools/worker-list.js +67 -0
  343. package/dist/tools/worker-list.js.map +1 -0
  344. package/dist/tools/xpath-query.d.ts +6 -0
  345. package/dist/tools/xpath-query.d.ts.map +1 -0
  346. package/dist/tools/xpath-query.js +230 -0
  347. package/dist/tools/xpath-query.js.map +1 -0
  348. package/dist/types/browser-backend.d.ts +30 -0
  349. package/dist/types/browser-backend.d.ts.map +1 -0
  350. package/dist/types/browser-backend.js +9 -0
  351. package/dist/types/browser-backend.js.map +1 -0
  352. package/dist/types/index.d.ts +3 -0
  353. package/dist/types/index.d.ts.map +1 -0
  354. package/dist/types/index.js +19 -0
  355. package/dist/types/index.js.map +1 -0
  356. package/dist/types/mcp.d.ts +54 -0
  357. package/dist/types/mcp.d.ts.map +1 -0
  358. package/dist/types/mcp.js +14 -0
  359. package/dist/types/mcp.js.map +1 -0
  360. package/dist/types/plan-cache.d.ts +121 -0
  361. package/dist/types/plan-cache.d.ts.map +1 -0
  362. package/dist/types/plan-cache.js +9 -0
  363. package/dist/types/plan-cache.js.map +1 -0
  364. package/dist/types/profile.d.ts +76 -0
  365. package/dist/types/profile.d.ts.map +1 -0
  366. package/dist/types/profile.js +35 -0
  367. package/dist/types/profile.js.map +1 -0
  368. package/dist/types/session.d.ts +65 -0
  369. package/dist/types/session.d.ts.map +1 -0
  370. package/dist/types/session.js +6 -0
  371. package/dist/types/session.js.map +1 -0
  372. package/dist/types/tool-manifest.d.ts +52 -0
  373. package/dist/types/tool-manifest.d.ts.map +1 -0
  374. package/dist/types/tool-manifest.js +37 -0
  375. package/dist/types/tool-manifest.js.map +1 -0
  376. package/dist/utils/atomic-file.d.ts +50 -0
  377. package/dist/utils/atomic-file.d.ts.map +1 -0
  378. package/dist/utils/atomic-file.js +217 -0
  379. package/dist/utils/atomic-file.js.map +1 -0
  380. package/dist/utils/index.d.ts +6 -0
  381. package/dist/utils/index.d.ts.map +1 -0
  382. package/dist/utils/index.js +22 -0
  383. package/dist/utils/index.js.map +1 -0
  384. package/dist/utils/json-validator.d.ts +40 -0
  385. package/dist/utils/json-validator.d.ts.map +1 -0
  386. package/dist/utils/json-validator.js +295 -0
  387. package/dist/utils/json-validator.js.map +1 -0
  388. package/dist/utils/ref-id-manager.d.ts +26 -0
  389. package/dist/utils/ref-id-manager.d.ts.map +1 -0
  390. package/dist/utils/ref-id-manager.js +81 -0
  391. package/dist/utils/ref-id-manager.js.map +1 -0
  392. package/dist/utils/request-queue.d.ts +37 -0
  393. package/dist/utils/request-queue.d.ts.map +1 -0
  394. package/dist/utils/request-queue.js +110 -0
  395. package/dist/utils/request-queue.js.map +1 -0
  396. package/package.json +78 -0
@@ -0,0 +1,745 @@
1
+ "use strict";
2
+ /**
3
+ * Workflow Engine - Executes parallel browser workflows
4
+ * Manages worker lifecycle and result aggregation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.WorkflowEngine = void 0;
8
+ exports.getWorkflowEngine = getWorkflowEngine;
9
+ const session_manager_1 = require("../session-manager");
10
+ const state_manager_1 = require("./state-manager");
11
+ const connection_pool_1 = require("../cdp/connection-pool");
12
+ const client_1 = require("../cdp/client");
13
+ const domain_memory_1 = require("../memory/domain-memory");
14
+ class WorkflowEngine {
15
+ sessionManager = (0, session_manager_1.getSessionManager)();
16
+ stateManager = (0, state_manager_1.getOrchestrationStateManager)();
17
+ /**
18
+ * In-memory workflow state. Keyed by orchestrationId.
19
+ * This is the source of truth for completion tracking — avoids file-based race conditions.
20
+ */
21
+ workflowStates = new Map();
22
+ /**
23
+ * Per-worker runtime state for timeout and circuit breaker tracking.
24
+ * Keyed by workerName.
25
+ */
26
+ workerRuntimeStates = new Map();
27
+ /**
28
+ * Timeout handles for worker absolute timeouts. Keyed by workerName.
29
+ */
30
+ workerTimeoutHandles = new Map();
31
+ /**
32
+ * Global workflow timeout handle. Keyed by orchestrationId.
33
+ */
34
+ globalTimeoutHandles = new Map();
35
+ /**
36
+ * Promise-based mutex for serializing completeWorker operations.
37
+ * Prevents lost-update races when multiple workers complete simultaneously.
38
+ */
39
+ completionLock = Promise.resolve();
40
+ /**
41
+ * Acquire the completion lock. Returns a release function.
42
+ * All completeWorker calls are serialized through this lock.
43
+ */
44
+ async acquireLock() {
45
+ let release;
46
+ const next = new Promise(resolve => {
47
+ release = resolve;
48
+ });
49
+ const prev = this.completionLock;
50
+ this.completionLock = next;
51
+ await prev;
52
+ return release;
53
+ }
54
+ /**
55
+ * Initialize a new workflow
56
+ * Creates workers, tabs, and scratchpads
57
+ */
58
+ async initWorkflow(sessionId, workflow) {
59
+ const orchestrationId = `orch-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
60
+ // Phase 1: Create all workers (no pages yet)
61
+ const createdWorkers = await Promise.all(workflow.steps.map(async (step) => {
62
+ const worker = await this.sessionManager.createWorker(sessionId, {
63
+ id: step.workerId,
64
+ name: step.workerName,
65
+ shareCookies: step.shareCookies,
66
+ targetUrl: step.url,
67
+ });
68
+ return { worker, step };
69
+ }));
70
+ // Phase 2: Batch-acquire pages from the pool to prevent about:blank proliferation.
71
+ // acquireBatch suppresses per-page replenishment, avoiding 60-80 ghost tabs.
72
+ const pool = (0, connection_pool_1.getCDPConnectionPool)();
73
+ const batchPages = await pool.acquireBatch(createdWorkers.length);
74
+ // Phase 3: Bridge cookies, then assign pages to workers and navigate
75
+ const cdpClient = (0, client_1.getCDPClient)();
76
+ const workers = await Promise.all(createdWorkers.map(async ({ worker, step }, i) => {
77
+ const page = batchPages[i];
78
+ // Bridge cookies from an authenticated page before navigating.
79
+ // Pool pages are created with skipCookieBridge=true to avoid CDP session
80
+ // conflicts during bulk creation. We bridge here sequentially after acquisition.
81
+ if (step.url) {
82
+ try {
83
+ const targetHost = new URL(step.url).hostname;
84
+ const authTargetId = await cdpClient.findAuthenticatedPageTargetId(targetHost);
85
+ if (authTargetId) {
86
+ await cdpClient.copyCookiesViaCDP(authTargetId, page);
87
+ }
88
+ }
89
+ catch {
90
+ // Cookie bridging failure is non-fatal — page navigates without cookies
91
+ }
92
+ await page.goto(step.url, { waitUntil: 'domcontentloaded' }).catch(() => {
93
+ // Navigation may fail for some URLs; worker will retry
94
+ });
95
+ }
96
+ // Register the page as a target in the session manager
97
+ const targetId = page.target()._targetId;
98
+ this.sessionManager.registerExistingTarget(sessionId, worker.id, targetId);
99
+ return {
100
+ workerId: worker.id,
101
+ workerName: step.workerName,
102
+ tabId: targetId,
103
+ task: step.task,
104
+ };
105
+ }));
106
+ // Initialize file-based orchestration state (for scratchpads / debugging)
107
+ await this.stateManager.initOrchestration(orchestrationId, workflow.name, workers);
108
+ // Initialize in-memory state — this is the authoritative source for completion tracking
109
+ const workerStatuses = new Map();
110
+ for (const w of workers) {
111
+ workerStatuses.set(w.workerName, { status: 'INIT', resultSummary: '' });
112
+ }
113
+ const workerTimeoutMs = workflow.timeout || 60_000;
114
+ const maxStaleIterations = workflow.maxStaleIterations ?? 5;
115
+ const globalTimeoutMs = workflow.globalTimeoutMs ?? 300_000;
116
+ const memState = {
117
+ orchestrationId,
118
+ task: workflow.name,
119
+ createdAt: Date.now(),
120
+ totalWorkers: workers.length,
121
+ completedWorkers: 0,
122
+ failedWorkers: 0,
123
+ workerStatuses,
124
+ overallStatus: 'INIT',
125
+ allDone: false,
126
+ workerTimeoutMs,
127
+ maxStaleIterations,
128
+ globalTimeoutMs,
129
+ };
130
+ this.workflowStates.set(orchestrationId, memState);
131
+ // Initialize per-worker runtime state and set up timeouts
132
+ for (const w of workers) {
133
+ const runtimeState = {
134
+ workerName: w.workerName,
135
+ startTime: Date.now(),
136
+ lastDataHash: '',
137
+ staleCount: 0,
138
+ lastUpdateTime: Date.now(),
139
+ timedOut: false,
140
+ };
141
+ this.workerRuntimeStates.set(w.workerName, runtimeState);
142
+ // Set absolute timeout per worker
143
+ const timeoutHandle = setTimeout(() => {
144
+ this.forceCompleteWorker(w.workerName, 'timeout', `Worker exceeded max duration of ${workerTimeoutMs}ms`);
145
+ }, workerTimeoutMs);
146
+ timeoutHandle.unref();
147
+ this.workerTimeoutHandles.set(w.workerName, timeoutHandle);
148
+ }
149
+ // Set global workflow timeout
150
+ const globalHandle = setTimeout(() => {
151
+ this.forceCompleteAllRunningWorkers(orchestrationId, `Global workflow timeout of ${memState.globalTimeoutMs}ms exceeded`);
152
+ }, memState.globalTimeoutMs);
153
+ globalHandle.unref();
154
+ this.globalTimeoutHandles.set(orchestrationId, globalHandle);
155
+ console.error(`[WorkflowEngine] Initialized workflow ${orchestrationId} with ${workers.length} workers (timeout: ${workerTimeoutMs}ms/worker, ${memState.globalTimeoutMs}ms global)`);
156
+ return {
157
+ orchestrationId,
158
+ workers: workers.map(w => ({
159
+ workerId: w.workerId,
160
+ workerName: w.workerName,
161
+ tabId: w.tabId,
162
+ })),
163
+ };
164
+ }
165
+ /**
166
+ * Update worker progress with circuit breaker check
167
+ */
168
+ async updateWorkerProgress(workerName, update) {
169
+ if (update.status || update.iteration !== undefined || update.extractedData !== undefined) {
170
+ await this.stateManager.updateWorkerState(workerName, {
171
+ status: update.status,
172
+ iteration: update.iteration,
173
+ extractedData: update.extractedData,
174
+ });
175
+ }
176
+ if (update.action && update.result) {
177
+ await this.stateManager.addProgressEntry(workerName, update.action, update.result, update.error);
178
+ }
179
+ // Circuit breaker: check for stale data (no progress)
180
+ if (update.extractedData !== undefined) {
181
+ const runtimeState = this.workerRuntimeStates.get(workerName);
182
+ if (runtimeState && !runtimeState.timedOut) {
183
+ const newHash = this.hashData(update.extractedData);
184
+ runtimeState.lastUpdateTime = Date.now();
185
+ if (newHash === runtimeState.lastDataHash) {
186
+ runtimeState.staleCount++;
187
+ // Find max stale iterations from workflow config
188
+ let maxStale = 5;
189
+ for (const ws of this.workflowStates.values()) {
190
+ if (ws.workerStatuses.has(workerName)) {
191
+ maxStale = ws.maxStaleIterations;
192
+ break;
193
+ }
194
+ }
195
+ if (runtimeState.staleCount >= maxStale) {
196
+ console.error(`[WorkflowEngine] Circuit breaker: Worker "${workerName}" data unchanged for ${maxStale} updates`);
197
+ this.forceCompleteWorker(workerName, 'stale', `No data change for ${maxStale} consecutive updates`);
198
+ }
199
+ }
200
+ else {
201
+ runtimeState.staleCount = 0;
202
+ runtimeState.lastDataHash = newHash;
203
+ }
204
+ }
205
+ }
206
+ }
207
+ /**
208
+ * Hash extracted data for circuit breaker comparison
209
+ */
210
+ hashData(data) {
211
+ const str = JSON.stringify(data) ?? '';
212
+ return str.length.toString() + '_' + str.slice(0, 200);
213
+ }
214
+ /**
215
+ * Force-complete a single worker due to timeout or circuit breaker
216
+ */
217
+ async forceCompleteWorker(workerName, reason, message) {
218
+ // Prevent double-completion
219
+ const runtimeState = this.workerRuntimeStates.get(workerName);
220
+ if (runtimeState) {
221
+ if (runtimeState.timedOut)
222
+ return;
223
+ runtimeState.timedOut = true;
224
+ }
225
+ // Clear the timeout handle
226
+ const handle = this.workerTimeoutHandles.get(workerName);
227
+ if (handle) {
228
+ clearTimeout(handle);
229
+ this.workerTimeoutHandles.delete(workerName);
230
+ }
231
+ console.error(`[WorkflowEngine] Force-completing worker "${workerName}" (${reason}): ${message}`);
232
+ // Complete with PARTIAL status — preserves any data collected so far
233
+ await this.completeWorker(workerName, 'PARTIAL', `[${reason}] ${message}`, null);
234
+ }
235
+ /**
236
+ * Force-complete all running workers in a workflow (global timeout)
237
+ */
238
+ async forceCompleteAllRunningWorkers(orchestrationId, message) {
239
+ const memState = this.workflowStates.get(orchestrationId);
240
+ if (!memState)
241
+ return;
242
+ console.error(`[WorkflowEngine] Global timeout for workflow ${orchestrationId}: ${message}`);
243
+ const runningWorkers = [];
244
+ for (const [workerName, ws] of memState.workerStatuses) {
245
+ if (ws.status !== 'SUCCESS' && ws.status !== 'PARTIAL' && ws.status !== 'FAIL') {
246
+ runningWorkers.push(workerName);
247
+ }
248
+ }
249
+ for (const workerName of runningWorkers) {
250
+ await this.forceCompleteWorker(workerName, 'timeout', message);
251
+ }
252
+ // Clear global timeout handle
253
+ const handle = this.globalTimeoutHandles.get(orchestrationId);
254
+ if (handle) {
255
+ clearTimeout(handle);
256
+ this.globalTimeoutHandles.delete(orchestrationId);
257
+ }
258
+ }
259
+ /**
260
+ * Mark worker as complete.
261
+ *
262
+ * Race-condition safe: all concurrent calls are serialized via a promise-based mutex.
263
+ * In-memory state is the source of truth for completion counting; file writes are
264
+ * write-behind (persistence/debugging only).
265
+ */
266
+ async completeWorker(workerName, status, resultSummary, extractedData) {
267
+ // Update the worker scratchpad file (outside the lock — file writes per worker don't conflict)
268
+ await this.stateManager.updateWorkerState(workerName, {
269
+ status,
270
+ extractedData,
271
+ });
272
+ // Serialize completion accounting through the lock to prevent lost updates
273
+ const release = await this.acquireLock();
274
+ try {
275
+ // Find the in-memory workflow state that contains this worker
276
+ let memState;
277
+ for (const s of this.workflowStates.values()) {
278
+ if (s.workerStatuses.has(workerName)) {
279
+ memState = s;
280
+ break;
281
+ }
282
+ }
283
+ if (!memState) {
284
+ // Fallback: no in-memory state (e.g. engine restarted). Fall back to file-based path.
285
+ console.error(`[WorkflowEngine] No in-memory state for worker "${workerName}", falling back to file read`);
286
+ await this._completeWorkerFileFallback(workerName, status, resultSummary);
287
+ return;
288
+ }
289
+ const prev = memState.workerStatuses.get(workerName);
290
+ const previousStatus = prev.status;
291
+ const wasAlreadyCompleted = previousStatus === 'SUCCESS' || previousStatus === 'PARTIAL' || previousStatus === 'FAIL';
292
+ // Update worker entry in-memory
293
+ memState.workerStatuses.set(workerName, { status, resultSummary });
294
+ // Adjust counters — prevent double-counting on repeated calls
295
+ if (!wasAlreadyCompleted) {
296
+ if (status === 'SUCCESS' || status === 'PARTIAL') {
297
+ memState.completedWorkers++;
298
+ }
299
+ else if (status === 'FAIL') {
300
+ memState.failedWorkers++;
301
+ }
302
+ }
303
+ else {
304
+ // Status transition between completed states — adjust counters accordingly
305
+ const wasCompleted = previousStatus === 'SUCCESS' || previousStatus === 'PARTIAL';
306
+ const wasFailed = previousStatus === 'FAIL';
307
+ const isNowCompleted = status === 'SUCCESS' || status === 'PARTIAL';
308
+ const isNowFailed = status === 'FAIL';
309
+ if (wasCompleted && isNowFailed) {
310
+ memState.completedWorkers--;
311
+ memState.failedWorkers++;
312
+ }
313
+ else if (wasFailed && isNowCompleted) {
314
+ memState.failedWorkers--;
315
+ memState.completedWorkers++;
316
+ }
317
+ // Same category transition (e.g. SUCCESS→PARTIAL): no counter change needed
318
+ }
319
+ // Check if all workers are done
320
+ const allDone = Array.from(memState.workerStatuses.values()).every(w => w.status === 'SUCCESS' || w.status === 'PARTIAL' || w.status === 'FAIL');
321
+ memState.allDone = allDone;
322
+ if (allDone) {
323
+ if (memState.failedWorkers === memState.totalWorkers) {
324
+ memState.overallStatus = 'FAILED';
325
+ }
326
+ else if (memState.failedWorkers > 0) {
327
+ memState.overallStatus = 'PARTIAL';
328
+ }
329
+ else {
330
+ memState.overallStatus = 'COMPLETED';
331
+ }
332
+ }
333
+ else {
334
+ memState.overallStatus = 'RUNNING';
335
+ }
336
+ console.error(`[WorkflowEngine] Worker "${workerName}" completed with ${status}. ` +
337
+ `Progress: ${memState.completedWorkers + memState.failedWorkers}/${memState.totalWorkers} ` +
338
+ `(${memState.completedWorkers} ok, ${memState.failedWorkers} failed). ` +
339
+ `Overall: ${memState.overallStatus}`);
340
+ // Write-behind: persist to file for debugging/visibility (not for correctness)
341
+ await this._writeOrchestrationStateBehind(memState);
342
+ }
343
+ finally {
344
+ release();
345
+ }
346
+ }
347
+ /**
348
+ * Write orchestration state to file from in-memory state (write-behind).
349
+ * This is for persistence/debugging only — correctness is maintained in memory.
350
+ */
351
+ async _writeOrchestrationStateBehind(memState) {
352
+ const workers = Array.from(memState.workerStatuses.entries()).map(([workerName, ws]) => ({
353
+ workerId: workerName, // best-effort: workerId not stored separately in memState
354
+ workerName,
355
+ status: ws.status,
356
+ resultSummary: ws.resultSummary,
357
+ }));
358
+ const orchState = {
359
+ orchestrationId: memState.orchestrationId,
360
+ status: memState.overallStatus,
361
+ createdAt: memState.createdAt,
362
+ updatedAt: Date.now(),
363
+ task: memState.task,
364
+ workers,
365
+ completedWorkers: memState.completedWorkers,
366
+ failedWorkers: memState.failedWorkers,
367
+ };
368
+ try {
369
+ await this.stateManager.writeOrchestrationState(orchState);
370
+ }
371
+ catch (err) {
372
+ // Write-behind failure is non-fatal — in-memory state remains correct
373
+ console.error(`[WorkflowEngine] Write-behind failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
374
+ }
375
+ }
376
+ /**
377
+ * Fallback for completeWorker when no in-memory state exists (engine restart scenario).
378
+ * Uses the original file-based read-modify-write approach.
379
+ */
380
+ async _completeWorkerFileFallback(workerName, status, resultSummary) {
381
+ const orch = await this.stateManager.readOrchestrationState();
382
+ if (!orch)
383
+ return;
384
+ const workerIdx = orch.workers.findIndex(w => w.workerName === workerName);
385
+ if (workerIdx === -1)
386
+ return;
387
+ const previousStatus = orch.workers[workerIdx].status;
388
+ const wasAlreadyCompleted = previousStatus === 'SUCCESS' || previousStatus === 'PARTIAL' || previousStatus === 'FAIL';
389
+ orch.workers[workerIdx].status = status;
390
+ orch.workers[workerIdx].resultSummary = resultSummary;
391
+ if (!wasAlreadyCompleted) {
392
+ if (status === 'SUCCESS' || status === 'PARTIAL') {
393
+ orch.completedWorkers++;
394
+ }
395
+ else if (status === 'FAIL') {
396
+ orch.failedWorkers++;
397
+ }
398
+ }
399
+ else {
400
+ const wasCompleted = previousStatus === 'SUCCESS' || previousStatus === 'PARTIAL';
401
+ const wasFailed = previousStatus === 'FAIL';
402
+ const isNowCompleted = status === 'SUCCESS' || status === 'PARTIAL';
403
+ const isNowFailed = status === 'FAIL';
404
+ if (wasCompleted && isNowFailed) {
405
+ orch.completedWorkers--;
406
+ orch.failedWorkers++;
407
+ }
408
+ else if (wasFailed && isNowCompleted) {
409
+ orch.failedWorkers--;
410
+ orch.completedWorkers++;
411
+ }
412
+ }
413
+ const allDone = orch.workers.every(w => w.status === 'SUCCESS' || w.status === 'PARTIAL' || w.status === 'FAIL');
414
+ if (allDone) {
415
+ if (orch.failedWorkers === orch.workers.length) {
416
+ orch.status = 'FAILED';
417
+ }
418
+ else if (orch.failedWorkers > 0) {
419
+ orch.status = 'PARTIAL';
420
+ }
421
+ else {
422
+ orch.status = 'COMPLETED';
423
+ }
424
+ }
425
+ else {
426
+ orch.status = 'RUNNING';
427
+ }
428
+ await this.stateManager.writeOrchestrationState(orch);
429
+ }
430
+ /**
431
+ * Get current orchestration status.
432
+ * Returns in-memory state when available (most current); falls back to file.
433
+ */
434
+ async getOrchestrationStatus() {
435
+ // If there is exactly one active workflow in memory, return it
436
+ if (this.workflowStates.size > 0) {
437
+ // Return the most recently created workflow
438
+ let latest;
439
+ for (const s of this.workflowStates.values()) {
440
+ if (!latest || s.createdAt > latest.createdAt) {
441
+ latest = s;
442
+ }
443
+ }
444
+ if (latest) {
445
+ const workers = Array.from(latest.workerStatuses.entries()).map(([workerName, ws]) => ({
446
+ workerId: workerName,
447
+ workerName,
448
+ status: ws.status,
449
+ resultSummary: ws.resultSummary,
450
+ }));
451
+ return {
452
+ orchestrationId: latest.orchestrationId,
453
+ status: latest.overallStatus,
454
+ createdAt: latest.createdAt,
455
+ updatedAt: Date.now(),
456
+ task: latest.task,
457
+ workers,
458
+ completedWorkers: latest.completedWorkers,
459
+ failedWorkers: latest.failedWorkers,
460
+ };
461
+ }
462
+ }
463
+ // Fallback to file-based state (e.g. engine restarted)
464
+ return this.stateManager.readOrchestrationState();
465
+ }
466
+ /**
467
+ * Get all worker states
468
+ */
469
+ async getAllWorkerStates() {
470
+ return this.stateManager.getAllWorkerStates();
471
+ }
472
+ /**
473
+ * Get worker state by name
474
+ */
475
+ async getWorkerState(workerName) {
476
+ return this.stateManager.readWorkerState(workerName);
477
+ }
478
+ /**
479
+ * Collect final results from all workers.
480
+ * Uses in-memory orchestration status for correctness; reads per-worker detail from files.
481
+ */
482
+ async collectResults() {
483
+ const orch = await this.getOrchestrationStatus();
484
+ if (!orch)
485
+ return null;
486
+ const workerResults = [];
487
+ const workerStates = await this.stateManager.getAllWorkerStates();
488
+ for (const state of workerStates) {
489
+ workerResults.push({
490
+ workerId: state.workerId,
491
+ workerName: state.workerName,
492
+ tabId: state.tabId,
493
+ status: state.status === 'SUCCESS' ? 'SUCCESS'
494
+ : state.status === 'PARTIAL' ? 'PARTIAL'
495
+ : 'FAIL',
496
+ resultSummary: `${state.status}: ${state.iteration} iterations`,
497
+ dataExtracted: state.extractedData,
498
+ iterations: state.iteration,
499
+ errors: state.errors,
500
+ });
501
+ }
502
+ const completedCount = workerResults.filter(r => r.status === 'SUCCESS' || r.status === 'PARTIAL').length;
503
+ const failedCount = workerResults.filter(r => r.status === 'FAIL').length;
504
+ const duration = Date.now() - orch.createdAt;
505
+ return {
506
+ orchestrationId: orch.orchestrationId,
507
+ status: orch.status === 'COMPLETED' ? 'COMPLETED'
508
+ : orch.status === 'PARTIAL' ? 'PARTIAL'
509
+ : 'FAILED',
510
+ workerResults,
511
+ completedCount,
512
+ failedCount,
513
+ duration,
514
+ };
515
+ }
516
+ /**
517
+ * Cleanup workflow resources
518
+ */
519
+ async cleanupWorkflow(sessionId) {
520
+ // Get all workers from orchestration state
521
+ const orch = await this.getOrchestrationStatus();
522
+ if (!orch)
523
+ return;
524
+ // Delete workers (which closes tabs and contexts)
525
+ for (const worker of orch.workers) {
526
+ try {
527
+ await this.sessionManager.deleteWorker(sessionId, worker.workerId);
528
+ }
529
+ catch {
530
+ // Worker might already be deleted
531
+ }
532
+ }
533
+ // Clear all timeout handles for this workflow's workers
534
+ for (const worker of orch.workers) {
535
+ const handle = this.workerTimeoutHandles.get(worker.workerName);
536
+ if (handle) {
537
+ clearTimeout(handle);
538
+ this.workerTimeoutHandles.delete(worker.workerName);
539
+ }
540
+ this.workerRuntimeStates.delete(worker.workerName);
541
+ }
542
+ // Clear global timeout
543
+ const globalHandle = this.globalTimeoutHandles.get(orch.orchestrationId);
544
+ if (globalHandle) {
545
+ clearTimeout(globalHandle);
546
+ this.globalTimeoutHandles.delete(orch.orchestrationId);
547
+ }
548
+ // Remove in-memory state for this workflow
549
+ this.workflowStates.delete(orch.orchestrationId);
550
+ // Cleanup state files
551
+ await this.stateManager.cleanup();
552
+ console.error(`[WorkflowEngine] Cleaned up workflow resources`);
553
+ }
554
+ /**
555
+ * Generate MCP tool documentation from a ToolEntry array.
556
+ * Groups tools by category and formats each tool with its parameters.
557
+ */
558
+ generateToolDocs(tools, tabId) {
559
+ const categoryDisplayNames = {
560
+ navigation: 'Navigation',
561
+ interaction: 'Interaction',
562
+ content: 'Content Reading',
563
+ javascript: 'JavaScript Execution',
564
+ composite: 'Smart Actions',
565
+ network: 'Network',
566
+ tabs: 'Tabs',
567
+ media: 'Media',
568
+ emulation: 'Emulation',
569
+ orchestration: 'Orchestration',
570
+ worker: 'Worker',
571
+ performance: 'Performance',
572
+ lifecycle: 'Lifecycle',
573
+ };
574
+ // Group tools by category
575
+ const grouped = {};
576
+ for (const tool of tools) {
577
+ const cat = tool.category;
578
+ if (!grouped[cat])
579
+ grouped[cat] = [];
580
+ grouped[cat].push(tool);
581
+ }
582
+ const sections = [];
583
+ for (const [category, categoryTools] of Object.entries(grouped)) {
584
+ const displayName = categoryDisplayNames[category] || category;
585
+ const toolDocs = [];
586
+ for (const tool of categoryTools) {
587
+ const fullName = `mcp__openchrome__${tool.name}`;
588
+ const props = tool.inputSchema.properties;
589
+ const paramLines = [];
590
+ for (const [paramName, paramSchema] of Object.entries(props)) {
591
+ if (paramName === 'tabId')
592
+ continue; // handled separately below
593
+ const paramType = paramSchema.type ?? 'unknown';
594
+ const paramDesc = paramSchema.description ? ` — ${paramSchema.description}` : '';
595
+ paramLines.push(`- ${paramName}: ${paramType}${paramDesc}`);
596
+ }
597
+ paramLines.push(`- tabId: "${tabId}" (required, always include)`);
598
+ toolDocs.push(`**${fullName}**\n${tool.description}\nParameters:\n${paramLines.join('\n')}`);
599
+ }
600
+ sections.push(`### ${displayName}\n\n${toolDocs.join('\n\n')}`);
601
+ }
602
+ return sections.join('\n\n');
603
+ }
604
+ /**
605
+ * Generate worker agent prompt for Background Task
606
+ */
607
+ generateWorkerPrompt(workerId, workerName, tabId, task, successCriteria, manifestTools, targetUrl) {
608
+ // CE: Isolate — inject only target domain's knowledge
609
+ let domainKnowledgeSection = '';
610
+ if (targetUrl) {
611
+ const domain = (0, domain_memory_1.extractDomainFromUrl)(targetUrl);
612
+ if (domain) {
613
+ const entries = (0, domain_memory_1.getDomainMemory)().query(domain);
614
+ if (entries.length > 0) {
615
+ const lines = entries.map((e) => `- **${e.key}**: ${e.value} (confidence: ${e.confidence.toFixed(1)})`);
616
+ domainKnowledgeSection = `\n\n## Domain Knowledge (${domain})\n\nPreviously learned knowledge for this domain. Validate after use with memory_validate.\n\n${lines.join('\n')}`;
617
+ }
618
+ }
619
+ }
620
+ return `## Chrome-Sisyphus Worker Agent
621
+
622
+ You are an autonomous browser automation worker. Execute your assigned task completely before returning.
623
+
624
+ ### Configuration
625
+ - Worker ID: ${workerId}
626
+ - Worker Name: ${workerName}
627
+ - Tab ID: ${tabId}
628
+ - Scratchpad: .agent/chrome-sisyphus/worker-${workerName}.md
629
+
630
+ ### Your Task
631
+ ${task}
632
+
633
+ ### Success Criteria
634
+ ${successCriteria}
635
+
636
+ ---
637
+
638
+ ## CRITICAL RULES
639
+
640
+ 1. **ALWAYS include tabId="${tabId}" in EVERY MCP tool call**
641
+ 2. **Update scratchpad after EVERY action using Write tool**
642
+ 3. **Maximum 5 iterations**
643
+ 4. **Return compressed result only - NO screenshots or full DOM**
644
+
645
+ ---
646
+
647
+ ${manifestTools && manifestTools.length > 0
648
+ ? `## Pre-loaded MCP Tools (verified — DO NOT call ToolSearch)
649
+
650
+ The following tools are pre-loaded and ready to use immediately.
651
+ CRITICAL: Do NOT call ToolSearch. These tool schemas are verified and current.
652
+
653
+ ${this.generateToolDocs(manifestTools, tabId)}`
654
+ : `## Available MCP Tools
655
+
656
+ ### Navigation
657
+ mcp__openchrome__navigate
658
+ - url: string (required)
659
+ - tabId: "${tabId}" (required)
660
+
661
+ ### Interaction
662
+ mcp__openchrome__computer
663
+ - action: "left_click" | "type" | "screenshot" | "scroll" | "key"
664
+ - tabId: "${tabId}" (required)
665
+ - coordinate: [x, y] (for clicks)
666
+ - text: string (for typing)
667
+
668
+ ### Page Reading
669
+ mcp__openchrome__read_page
670
+ - tabId: "${tabId}" (required)
671
+ - filter: "interactive" | "all"
672
+
673
+ ### Element Finding
674
+ mcp__openchrome__find
675
+ - query: string (natural language)
676
+ - tabId: "${tabId}" (required)
677
+
678
+ ### Form Input
679
+ mcp__openchrome__form_input
680
+ - ref: string (element reference from find/read_page)
681
+ - value: string | boolean | number
682
+ - tabId: "${tabId}" (required)
683
+
684
+ ### JavaScript Execution
685
+ mcp__openchrome__javascript_tool
686
+ - action: "javascript_exec"
687
+ - text: string (JS code)
688
+ - tabId: "${tabId}" (required)`}
689
+
690
+ ---
691
+
692
+ ## Execution Algorithm (Ralph Loop)
693
+
694
+ for iteration in 1..5:
695
+ 1. Assess current state (read page or check scratchpad)
696
+ 2. Decide next action
697
+ 3. Execute MCP tool with tabId="${tabId}"
698
+ 4. Update scratchpad with Write tool
699
+ 5. Check if success criteria met -> if yes, return SUCCESS
700
+
701
+ ---
702
+
703
+ ## Final Output Format
704
+
705
+ When done, your LAST message MUST contain:
706
+
707
+ ---RESULT---
708
+ {
709
+ "status": "SUCCESS" | "PARTIAL" | "FAIL",
710
+ "workerName": "${workerName}",
711
+ "resultSummary": "Brief summary (max 100 chars)",
712
+ "dataExtracted": {
713
+ // Your extracted data here
714
+ },
715
+ "scratchpadPath": ".agent/chrome-sisyphus/worker-${workerName}.md",
716
+ "iterations": 3,
717
+ "errors": [],
718
+ "EXIT_SIGNAL": true
719
+ }
720
+ ---END---
721
+
722
+ ---
723
+
724
+ ## Error Handling
725
+
726
+ | Error | Strategy |
727
+ |-------|----------|
728
+ | Element not found | Try find with different query |
729
+ | Page timeout | Refresh and retry |
730
+ | Captcha | Report FAIL |
731
+ | Network error | Wait 2s, retry |
732
+
733
+ Now begin your task. Navigate to the target site and complete the assigned work.${domainKnowledgeSection}`;
734
+ }
735
+ }
736
+ exports.WorkflowEngine = WorkflowEngine;
737
+ // Singleton instance
738
+ let workflowEngineInstance = null;
739
+ function getWorkflowEngine() {
740
+ if (!workflowEngineInstance) {
741
+ workflowEngineInstance = new WorkflowEngine();
742
+ }
743
+ return workflowEngineInstance;
744
+ }
745
+ //# sourceMappingURL=workflow-engine.js.map