@xopcai/xopc 0.0.112 → 0.0.114

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 (351) hide show
  1. package/dist/browser-ext/icons/icon-128.png +0 -0
  2. package/dist/browser-ext/icons/icon-16.png +0 -0
  3. package/dist/browser-ext/icons/icon-32.png +0 -0
  4. package/dist/browser-ext/icons/icon-48.png +0 -0
  5. package/dist/browser-ext/manifest.json +1 -1
  6. package/dist/extensions/telegram/xopc.extension.json +1 -1
  7. package/dist/extensions/weixin/src/delivery-to.d.ts +3 -3
  8. package/dist/extensions/weixin/src/delivery-to.js.map +1 -1
  9. package/dist/gateway/static/root/apple-touch-icon.png +0 -0
  10. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-EhRp-ZMa.js → agent-avatar-dicebear-Fp-p7bP1.js} +1 -1
  11. package/dist/gateway/static/root/assets/agent-browser-settings-page-CWh7trjd.js +6 -0
  12. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-kC8OuLoj.js +1 -0
  13. package/dist/gateway/static/root/assets/agents-DJWG26Si.js +71 -0
  14. package/dist/gateway/static/root/assets/{app-management-settings-panel-BIy7KEsM.js → app-management-settings-panel-v24i25Oj.js} +1 -1
  15. package/dist/gateway/static/root/assets/{appearance-settings-DGQG8NwA.js → appearance-settings-ycbdJRuZ.js} +1 -1
  16. package/dist/gateway/static/root/assets/apps-page-0V3DXZ7J.js +1 -0
  17. package/dist/gateway/static/root/assets/{archive-plugin-uuQPupqx.js → archive-plugin-CJzSADJo.js} +1 -1
  18. package/dist/gateway/static/root/assets/{attachment-load-DBkv0cAv.js → attachment-load-BTAB4zGS.js} +1 -1
  19. package/dist/gateway/static/root/assets/{binary-plugins-DxxN_VAR.js → binary-plugins-DXR1-mct.js} +1 -1
  20. package/dist/gateway/static/root/assets/{block-editor-CwnUlRmO.js → block-editor-CzQri9h2.js} +44 -44
  21. package/dist/gateway/static/root/assets/channels-settings-CIKOkYdO.js +1 -0
  22. package/dist/gateway/static/root/assets/{config-api-BD-NcD5d.js → config-api-DRqjEvAx.js} +1 -1
  23. package/dist/gateway/static/root/assets/connectors-settings-ClrDS5jH.js +2 -0
  24. package/dist/gateway/static/root/assets/{cron-api-C5DoipZA.js → cron-api-BXaZXv1o.js} +1 -1
  25. package/dist/gateway/static/root/assets/cron-page-Chi_4u4P.js +3 -0
  26. package/dist/gateway/static/root/assets/dreaming-settings-B0_rs2tj.js +1 -0
  27. package/dist/gateway/static/root/assets/{extension-debug-page-BDHA9o_e.js → extension-debug-page-DSkqMYo7.js} +1 -1
  28. package/dist/gateway/static/root/assets/{extension-page-DmDLVSPE.js → extension-page-h2dGDbMN.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-settings-page-1124aHw_.js → extension-settings-page-hN99RhOi.js} +1 -1
  30. package/dist/gateway/static/root/assets/{fetch-DOe56Wmy.js → fetch-D9QqUtzZ.js} +1 -1
  31. package/dist/gateway/static/root/assets/{format-interval-label-tsMSvBSR.js → format-interval-label-D6E687rG.js} +1 -1
  32. package/dist/gateway/static/root/assets/{gateway-config-api-CsD4FC9D.js → gateway-config-api-CLt_SKTC.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-settings-HQ8FBhY2.js → gateway-settings-1PDi4lI0.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-startup-retry-C1zg7pH3.js → gateway-startup-retry-N7Z_sz7p.js} +1 -1
  35. package/dist/gateway/static/root/assets/goal-detail-page-D_wwXL-t.js +1 -0
  36. package/dist/gateway/static/root/assets/goals-page-DZ2toZ8y.js +2 -0
  37. package/dist/gateway/static/root/assets/{goals-settings-B5nI6lgz.js → goals-settings-LFlwtIKE.js} +1 -1
  38. package/dist/gateway/static/root/assets/{heartbeat-config-api-CIv42nJD.js → heartbeat-config-api-DGPadTw-.js} +1 -1
  39. package/dist/gateway/static/root/assets/{heartbeat-settings-DFcVuJ3M.js → heartbeat-settings-BHHAs8ZX.js} +1 -1
  40. package/dist/gateway/static/root/assets/index-DefIdW9q.js +122 -0
  41. package/dist/gateway/static/root/assets/index-DzmWBkq-.css +1 -0
  42. package/dist/gateway/static/root/assets/{interval-presets-DGP3S7OB.js → interval-presets-CEklPQ_r.js} +1 -1
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-fETaDYQP.js → keyboard-shortcuts-settings-Ce_aQ8Iv.js} +1 -1
  44. package/dist/gateway/static/root/assets/logs-page-j_D2QTuQ.js +2 -0
  45. package/dist/gateway/static/root/assets/{markdown-split-CgeBJMOD.js → markdown-split-BMz3xPXO.js} +1 -1
  46. package/dist/gateway/static/root/assets/{media-plugins-C30GzlV2.js → media-plugins-BalOSoz9.js} +1 -1
  47. package/dist/gateway/static/root/assets/messages-BN_WiUg0.js +3 -0
  48. package/dist/gateway/static/root/assets/models-hub-panel-CMH_TmZz.js +2 -0
  49. package/dist/gateway/static/root/assets/note-detail-page-O18BrQPq.js +2 -0
  50. package/dist/gateway/static/root/assets/{note-image-lightbox-t1g0qZYh.js → note-image-lightbox-C5D1Q5mY.js} +1 -1
  51. package/dist/gateway/static/root/assets/notes-page-B_ZYCmY9.js +1 -0
  52. package/dist/gateway/static/root/assets/{preview-open-alternatives-DeWp9x5g.js → preview-open-alternatives-CYFR5U9l.js} +1 -1
  53. package/dist/gateway/static/root/assets/remote-access-hub-CwKgWixY.js +1 -0
  54. package/dist/gateway/static/root/assets/{save-bar-controls-BOaAOJI3.js → save-bar-controls-BQ79Z5IP.js} +1 -1
  55. package/dist/gateway/static/root/assets/{schedule-field-BLWLKqgw.js → schedule-field-Bgk6Emue.js} +1 -1
  56. package/dist/gateway/static/root/assets/{schema-form-plqRFYT8.js → schema-form-DzS36TMa.js} +1 -1
  57. package/dist/gateway/static/root/assets/sessions-page-C4fcD-7B.js +1 -0
  58. package/dist/gateway/static/root/assets/settings-advanced-gate-Ad2OJ86w.js +1 -0
  59. package/dist/gateway/static/root/assets/{settings-collapsible-section-BP5zRrDI.js → settings-collapsible-section-CdjFnSAy.js} +1 -1
  60. package/dist/gateway/static/root/assets/{settings-form-section-Bv8MZplG.js → settings-form-section-DZLy_exu.js} +1 -1
  61. package/dist/gateway/static/root/assets/settings-page-D2BMY5wo.js +1 -0
  62. package/dist/gateway/static/root/assets/setup-status-panel-aWwxl_E1.js +1 -0
  63. package/dist/gateway/static/root/assets/{share-preview-page-4OX1YCgp.js → share-preview-page-_qRDr4g_.js} +1 -1
  64. package/dist/gateway/static/root/assets/shares-settings-DUE83uIf.js +1 -0
  65. package/dist/gateway/static/root/assets/skill-reload-api-mWKJcrog.js +1 -0
  66. package/dist/gateway/static/root/assets/skills-page-0Sx1Q58n.js +2 -0
  67. package/dist/gateway/static/root/assets/{system-settings-panel-CGy4f_s2.js → system-settings-panel-hqaBF5aG.js} +1 -1
  68. package/dist/gateway/static/root/assets/use-agent-defaults-form-zbVIQLOA.js +1 -0
  69. package/dist/gateway/static/root/assets/{use-channel-catalog-CjGHnDvN.js → use-channel-catalog-CbXq97rT.js} +1 -1
  70. package/dist/gateway/static/root/assets/{use-settings-tab-guard-BMMFa0oA.js → use-settings-tab-guard-DwS3drWK.js} +1 -1
  71. package/dist/gateway/static/root/assets/voice-api-key-field-D6HR0hR2.js +1 -0
  72. package/dist/gateway/static/root/assets/{voice-player-store-D5vzWwls.js → voice-player-store-DSuOd9zy.js} +1 -1
  73. package/dist/gateway/static/root/assets/workflow-page.utils-C0Uq3xyq.js +1 -0
  74. package/dist/gateway/static/root/assets/workflows-page-DW0fmWhQ.js +18 -0
  75. package/dist/gateway/static/root/favicon-16x16.png +0 -0
  76. package/dist/gateway/static/root/favicon-32x32.png +0 -0
  77. package/dist/gateway/static/root/favicon-icon.svg +1 -0
  78. package/dist/gateway/static/root/favicon.ico +0 -0
  79. package/dist/gateway/static/root/favicon.png +0 -0
  80. package/dist/gateway/static/root/favicon.svg +24 -17
  81. package/dist/gateway/static/root/index.html +5 -5
  82. package/dist/gateway/static/root/logo-dark.svg +23 -15
  83. package/dist/gateway/static/root/logo.svg +23 -16
  84. package/dist/package.js +1 -1
  85. package/dist/src/agent/agent-manager.d.ts +8 -0
  86. package/dist/src/agent/agent-manager.js +57 -22
  87. package/dist/src/agent/agent-manager.js.map +1 -1
  88. package/dist/src/agent/bootstrap/project-agents-context.d.ts +2 -0
  89. package/dist/src/agent/bootstrap/project-agents-context.js +32 -0
  90. package/dist/src/agent/bootstrap/project-agents-context.js.map +1 -0
  91. package/dist/src/agent/goals/persistent-goal-service.js +2 -4
  92. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  93. package/dist/src/agent/inbound/inbound-loop.js +5 -1
  94. package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
  95. package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -2
  96. package/dist/src/agent/inbound/turn-dispatcher.js +2 -2
  97. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  98. package/dist/src/agent/mcp/bundle-mcp-materialize.d.ts +27 -0
  99. package/dist/src/agent/mcp/bundle-mcp-materialize.js +49 -1
  100. package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
  101. package/dist/src/agent/mcp/bundle-mcp-runtime.js +78 -3
  102. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  103. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +19 -0
  104. package/dist/src/agent/service/btw-query.js +11 -3
  105. package/dist/src/agent/service/btw-query.js.map +1 -1
  106. package/dist/src/agent/service/parse-outbound-session-key.js +13 -8
  107. package/dist/src/agent/service/parse-outbound-session-key.js.map +1 -1
  108. package/dist/src/agent/service/process-direct-one-shot.d.ts +2 -2
  109. package/dist/src/agent/service/process-direct-one-shot.js +1 -1
  110. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  111. package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
  112. package/dist/src/agent/service/process-direct-streaming.js +10 -5
  113. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  114. package/dist/src/agent/service.d.ts +1 -1
  115. package/dist/src/agent/service.js +9 -5
  116. package/dist/src/agent/service.js.map +1 -1
  117. package/dist/src/agent/service.types.d.ts +5 -0
  118. package/dist/src/agent/skills/filesystem-watcher.js +4 -3
  119. package/dist/src/agent/skills/filesystem-watcher.js.map +1 -1
  120. package/dist/src/agent/skills/index.js +2 -1
  121. package/dist/src/agent/skills/index.js.map +1 -1
  122. package/dist/src/agent/skills/skill-manage-ops.js +2 -1
  123. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  124. package/dist/src/agent/skills/types.d.ts +1 -1
  125. package/dist/src/agent/skills/watcher.js +2 -5
  126. package/dist/src/agent/skills/watcher.js.map +1 -1
  127. package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
  128. package/dist/src/agent/skills/workspace-skills-dir.js +11 -0
  129. package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -0
  130. package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
  131. package/dist/src/agent/tool-manuals/browser.js +62 -3
  132. package/dist/src/agent/tool-manuals/browser.js.map +1 -1
  133. package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -1
  134. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +13 -4
  135. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  136. package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -2
  137. package/dist/src/agent/tools/browser/tool/schemas.js +1 -2
  138. package/dist/src/agent/tools/browser/tool/schemas.js.map +1 -1
  139. package/dist/src/agent/tools/factory.js +1 -10
  140. package/dist/src/agent/tools/factory.js.map +1 -1
  141. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  142. package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
  143. package/dist/src/agent/workflow/subagent-runner.js +18 -1
  144. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  145. package/dist/src/ai-assist/text-assist.d.ts +3 -0
  146. package/dist/src/ai-assist/text-assist.js +25 -7
  147. package/dist/src/ai-assist/text-assist.js.map +1 -1
  148. package/dist/src/browser/actions/extension-registry-bridge.js +91 -7
  149. package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
  150. package/dist/src/browser/actions/registry.js +383 -7
  151. package/dist/src/browser/actions/registry.js.map +1 -1
  152. package/dist/src/browser/actions/types.d.ts +11 -3
  153. package/dist/src/browser/index.js +2 -2
  154. package/dist/src/browser/pipeline/output.d.ts +18 -16
  155. package/dist/src/browser/pipeline/output.js +28 -20
  156. package/dist/src/browser/pipeline/output.js.map +1 -1
  157. package/dist/src/browser/pipeline/runner.d.ts +7 -14
  158. package/dist/src/browser/pipeline/runner.js +349 -102
  159. package/dist/src/browser/pipeline/runner.js.map +1 -1
  160. package/dist/src/browser/pipeline/schema.d.ts +1 -0
  161. package/dist/src/browser/pipeline/schema.js +35 -58
  162. package/dist/src/browser/pipeline/schema.js.map +1 -1
  163. package/dist/src/browser/pipeline/source.d.ts +2 -0
  164. package/dist/src/browser/pipeline/source.js +10 -1
  165. package/dist/src/browser/pipeline/source.js.map +1 -1
  166. package/dist/src/browser/pipeline/template.d.ts +10 -2
  167. package/dist/src/browser/pipeline/template.js +50 -8
  168. package/dist/src/browser/pipeline/template.js.map +1 -1
  169. package/dist/src/channels/plugins/types.adapters.d.ts +2 -2
  170. package/dist/src/chat-commands/builtins/config.js +3 -5
  171. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  172. package/dist/src/chat-commands/context.d.ts +5 -0
  173. package/dist/src/chat-commands/context.js +18 -9
  174. package/dist/src/chat-commands/context.js.map +1 -1
  175. package/dist/src/chat-commands/index.d.ts +1 -1
  176. package/dist/src/chat-commands/index.js +2 -2
  177. package/dist/src/chat-commands/index.js.map +1 -1
  178. package/dist/src/chat-commands/processor.js +22 -21
  179. package/dist/src/chat-commands/processor.js.map +1 -1
  180. package/dist/src/chat-commands/session-key.d.ts +3 -15
  181. package/dist/src/chat-commands/session-key.js +3 -49
  182. package/dist/src/chat-commands/session-key.js.map +1 -1
  183. package/dist/src/chat-commands/types.d.ts +4 -0
  184. package/dist/src/cli/commands/browser-cli-helpers.js +11 -5
  185. package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
  186. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  187. package/dist/src/cli/commands/doctor/checks/session-integrity.js +8 -8
  188. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  189. package/dist/src/config/rules.js +5 -0
  190. package/dist/src/config/rules.js.map +1 -1
  191. package/dist/src/connectors/builtin-catalog.js +180 -1
  192. package/dist/src/connectors/builtin-catalog.js.map +1 -1
  193. package/dist/src/connectors/health.js +18 -9
  194. package/dist/src/connectors/health.js.map +1 -1
  195. package/dist/src/connectors/types.d.ts +19 -0
  196. package/dist/src/connectors/usage.js +12 -4
  197. package/dist/src/connectors/usage.js.map +1 -1
  198. package/dist/src/cron/executor.js.map +1 -1
  199. package/dist/src/cron/types.d.ts +2 -2
  200. package/dist/src/extensions/types/tui.d.ts +2 -0
  201. package/dist/src/gateway/heartbeat/service.js +13 -1
  202. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  203. package/dist/src/gateway/hono/app.js +13 -4
  204. package/dist/src/gateway/hono/app.js.map +1 -1
  205. package/dist/src/gateway/hono/oauth-async.js +1 -1
  206. package/dist/src/gateway/hono/routes/agent-stream.js +6 -6
  207. package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
  208. package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +1 -1
  209. package/dist/src/gateway/hono/routes/config-patch/gateway.js +6 -0
  210. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  211. package/dist/src/gateway/hono/routes/goals.js +16 -3
  212. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  213. package/dist/src/gateway/hono/routes/logs.js +1 -0
  214. package/dist/src/gateway/hono/routes/logs.js.map +1 -1
  215. package/dist/src/gateway/hono/routes/mcp.js +27 -8
  216. package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
  217. package/dist/src/gateway/hono/routes/notes.js +14 -2
  218. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  219. package/dist/src/gateway/hono/routes/sessions.js +62 -4
  220. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  221. package/dist/src/gateway/hono/routes/workspace.js +3 -66
  222. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  223. package/dist/src/gateway/hono/sse.d.ts +2 -2
  224. package/dist/src/gateway/hono/sse.js +7 -15
  225. package/dist/src/gateway/hono/sse.js.map +1 -1
  226. package/dist/src/gateway/resolve-webchat-session-key.d.ts +2 -6
  227. package/dist/src/gateway/resolve-webchat-session-key.js +5 -31
  228. package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -1
  229. package/dist/src/gateway/service/agent-runner.d.ts +2 -3
  230. package/dist/src/gateway/service/agent-runner.js +9 -22
  231. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  232. package/dist/src/gateway/service/run-gateway-agent.js +9 -7
  233. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  234. package/dist/src/gateway/service/sessions-api.d.ts +9 -0
  235. package/dist/src/gateway/service/sessions-api.js +11 -0
  236. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  237. package/dist/src/gateway/service.d.ts +1 -1
  238. package/dist/src/gateway/service.js +19 -5
  239. package/dist/src/gateway/service.js.map +1 -1
  240. package/dist/src/gateway/workspace-file-search.d.ts +9 -0
  241. package/dist/src/gateway/workspace-file-search.js +76 -0
  242. package/dist/src/gateway/workspace-file-search.js.map +1 -0
  243. package/dist/src/goals/goal-notifications.d.ts +2 -0
  244. package/dist/src/goals/goal-notifications.js +16 -11
  245. package/dist/src/goals/goal-notifications.js.map +1 -1
  246. package/dist/src/goals/goal-service.js +1 -6
  247. package/dist/src/goals/goal-service.js.map +1 -1
  248. package/dist/src/project-trust/trust-store.js +2 -0
  249. package/dist/src/project-trust/trust-store.js.map +1 -1
  250. package/dist/src/session/index.d.ts +1 -1
  251. package/dist/src/session/index.js +2 -2
  252. package/dist/src/session/init-session-turn.js +6 -9
  253. package/dist/src/session/init-session-turn.js.map +1 -1
  254. package/dist/src/session/manager.d.ts +5 -1
  255. package/dist/src/session/manager.js +5 -2
  256. package/dist/src/session/manager.js.map +1 -1
  257. package/dist/src/session/reset-type.d.ts +0 -2
  258. package/dist/src/session/reset-type.js +3 -9
  259. package/dist/src/session/reset-type.js.map +1 -1
  260. package/dist/src/session/resolve-session.js +9 -20
  261. package/dist/src/session/resolve-session.js.map +1 -1
  262. package/dist/src/session/store-reader.d.ts +5 -0
  263. package/dist/src/session/store-reader.js +1 -0
  264. package/dist/src/session/store.d.ts +11 -3
  265. package/dist/src/session/store.js +29 -13
  266. package/dist/src/session/store.js.map +1 -1
  267. package/dist/src/session/types.d.ts +2 -4
  268. package/dist/src/session/types.js.map +1 -1
  269. package/dist/src/storage/sqlite/index.d.ts +2 -2
  270. package/dist/src/storage/sqlite/index.js +3 -3
  271. package/dist/src/storage/sqlite/migrations/010_session_id_identity.sql +30 -0
  272. package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
  273. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  274. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  275. package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
  276. package/dist/src/storage/sqlite/row-mappers.d.ts +4 -4
  277. package/dist/src/storage/sqlite/row-mappers.js +11 -14
  278. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  279. package/dist/src/storage/sqlite/schema.js +3 -3
  280. package/dist/src/storage/sqlite/schema.js.map +1 -1
  281. package/dist/src/storage/sqlite/schema.sql +37 -10
  282. package/dist/src/storage/sqlite/session-metadata.d.ts +2 -7
  283. package/dist/src/storage/sqlite/session-metadata.js +18 -72
  284. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  285. package/dist/src/storage/sqlite/session-repository.d.ts +6 -5
  286. package/dist/src/storage/sqlite/session-repository.js +34 -40
  287. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  288. package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -2
  289. package/dist/src/storage/sqlite/transcript-repository.js +52 -52
  290. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
  291. package/dist/src/tui/backends/embedded-backend.d.ts +11 -4
  292. package/dist/src/tui/backends/embedded-backend.js +27 -1
  293. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  294. package/dist/src/tui/backends/gateway-sse-backend.d.ts +4 -1
  295. package/dist/src/tui/backends/gateway-sse-backend.js +21 -2
  296. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  297. package/dist/src/tui/extension-host/autocomplete.js +13 -10
  298. package/dist/src/tui/extension-host/autocomplete.js.map +1 -1
  299. package/dist/src/tui/extension-host/runtime.d.ts +7 -0
  300. package/dist/src/tui/extension-host/runtime.js +6 -4
  301. package/dist/src/tui/extension-host/runtime.js.map +1 -1
  302. package/dist/src/tui/tui-backend.d.ts +9 -0
  303. package/dist/src/tui/tui-commands.js +85 -6
  304. package/dist/src/tui/tui-commands.js.map +1 -1
  305. package/dist/src/tui/tui-file-autocomplete.d.ts +5 -0
  306. package/dist/src/tui/tui-file-autocomplete.js +26 -0
  307. package/dist/src/tui/tui-file-autocomplete.js.map +1 -0
  308. package/dist/src/tui/tui-picker-overlay.js +1 -1
  309. package/dist/src/tui/tui.js +29 -11
  310. package/dist/src/tui/tui.js.map +1 -1
  311. package/dist/src/utils/logger/context.d.ts +2 -2
  312. package/dist/src/utils/logger/context.js +2 -1
  313. package/dist/src/utils/logger/context.js.map +1 -1
  314. package/dist/src/utils/logger/log-store.js +1 -0
  315. package/dist/src/utils/logger/log-store.js.map +1 -1
  316. package/dist/src/utils/logger/pino-record.js +3 -0
  317. package/dist/src/utils/logger/pino-record.js.map +1 -1
  318. package/dist/src/utils/logger/types.d.ts +5 -0
  319. package/dist/src/utils/logger/types.js.map +1 -1
  320. package/dist/src/workflows/service/workflow-session-bridge.js +13 -1
  321. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  322. package/package.json +1 -1
  323. package/dist/gateway/static/root/assets/agent-browser-settings-page-H4foVCiS.js +0 -6
  324. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-DDNw2oNU.js +0 -1
  325. package/dist/gateway/static/root/assets/agents-E_X2kzS1.js +0 -71
  326. package/dist/gateway/static/root/assets/apps-page-BZLvInLr.js +0 -1
  327. package/dist/gateway/static/root/assets/channels-settings-BHvUKlzw.js +0 -1
  328. package/dist/gateway/static/root/assets/connectors-settings-VBzXcEXL.js +0 -2
  329. package/dist/gateway/static/root/assets/cron-page-BLTpdm34.js +0 -3
  330. package/dist/gateway/static/root/assets/dreaming-settings-DSVhXTPq.js +0 -1
  331. package/dist/gateway/static/root/assets/goal-detail-page-BG3Onph0.js +0 -1
  332. package/dist/gateway/static/root/assets/goals-page-DgeKn8zL.js +0 -2
  333. package/dist/gateway/static/root/assets/index-5A_ZaABy.css +0 -1
  334. package/dist/gateway/static/root/assets/index-BTmbp2AU.js +0 -121
  335. package/dist/gateway/static/root/assets/logs-page-B1-b27lK.js +0 -2
  336. package/dist/gateway/static/root/assets/messages-BUUfPaZ9.js +0 -3
  337. package/dist/gateway/static/root/assets/models-hub-panel-DPcTS1-u.js +0 -2
  338. package/dist/gateway/static/root/assets/note-detail-page-xeGb4owe.js +0 -2
  339. package/dist/gateway/static/root/assets/notes-page-C_TdnKBe.js +0 -1
  340. package/dist/gateway/static/root/assets/remote-access-hub-BtkPmJIN.js +0 -1
  341. package/dist/gateway/static/root/assets/sessions-page-DOUjxzJm.js +0 -1
  342. package/dist/gateway/static/root/assets/settings-advanced-gate-qK_bnTrw.js +0 -1
  343. package/dist/gateway/static/root/assets/settings-page-DmDfE1ww.js +0 -1
  344. package/dist/gateway/static/root/assets/setup-status-panel-BEFwNcIZ.js +0 -1
  345. package/dist/gateway/static/root/assets/shares-settings-CbKmJZot.js +0 -1
  346. package/dist/gateway/static/root/assets/skill-reload-api-YdtnUHtK.js +0 -1
  347. package/dist/gateway/static/root/assets/skills-page-DwW1IzQ0.js +0 -2
  348. package/dist/gateway/static/root/assets/use-agent-defaults-form-BMuMvzl_.js +0 -1
  349. package/dist/gateway/static/root/assets/voice-api-key-field-DnRbhMNq.js +0 -1
  350. package/dist/gateway/static/root/assets/workflow-page.utils-tjGpRVnw.js +0 -1
  351. package/dist/gateway/static/root/assets/workflows-page-DqqHKGj2.js +0 -18
@@ -1 +1 @@
1
- {"version":3,"file":"extension-registry-bridge.js","names":["d"],"sources":["../../../../src/browser/actions/extension-registry-bridge.ts"],"sourcesContent":["/**\n * Runs browser registry actions against the Chrome Extension bridge (no Playwright page).\n */\n\nimport { assertBrowserUrlAllowed, checkPostRedirectUrl, containsApiKeyPattern } from '../url-policy.js';\nimport { checkWebsiteBlocklist } from '../../agent/tools/url-safety.js';\nimport { resolveBrowserCommandTimeoutMs } from '../browser-command-timeout.js';\nimport { truncateSnapshotAtBoundary } from '../snapshot-helpers.js';\n\nimport type { BrowserActionContext, BrowserActionResult } from './types.js';\n\nconst DEFAULT_SNAPSHOT_MAX = 30_000;\nconst AUTO_SNAPSHOT_MAX = 8_000;\n\nfunction toMs(ctx: BrowserActionContext): number {\n return resolveBrowserCommandTimeoutMs(ctx.config);\n}\n\nfunction ok(action: string, text: string, data?: unknown, artifacts?: BrowserActionResult['artifacts']): BrowserActionResult {\n return { ok: true, action, text, data, artifacts };\n}\n\nfunction fail(action: string, code: string, message: string, diagnostics?: BrowserActionResult['diagnostics']): BrowserActionResult {\n return { ok: false, action, error: { code, message }, diagnostics };\n}\n\nfunction formatAxSnapshot(data: unknown, maxLen: number): string {\n const d = data as { nodes?: Array<{ role?: string; name?: string }> } | undefined;\n const nodes = d?.nodes ?? [];\n if (nodes.length === 0) return '(empty snapshot)';\n const lines = nodes.map((n) => `${n.role ?? '?'}: ${n.name ?? ''}`);\n let text = lines.join('\\n');\n if (text.length > maxLen) text = truncateSnapshotAtBoundary(text, maxLen);\n return text;\n}\n\nexport async function runExtensionRegistryAction(\n name: string,\n ctx: BrowserActionContext,\n args: Record<string, unknown>,\n): Promise<BrowserActionResult> {\n if (ctx.signal?.aborted) {\n return fail(name, 'ABORTED', 'Operation was aborted');\n }\n const ext = ctx.manager.getExtensionProvider();\n if (!ext) {\n return fail(name, 'NO_EXTENSION', 'Extension backend not connected');\n }\n\n const timeout = toMs(ctx);\n const allowPrivate = ctx.config?.agents?.defaults?.browser?.allowPrivateUrls === true;\n\n switch (name) {\n case 'open':\n case 'navigate': {\n const url = String(args.url ?? '');\n if (!url) return fail(name, 'MISSING_URL', 'url is required');\n if (containsApiKeyPattern(url)) return fail(name, 'BLOCKED', 'URL contains API key/token');\n const block = checkWebsiteBlocklist(url, ctx.config?.tools?.web?.blocklist);\n if (block) return fail(name, 'BLOCKED', block.message);\n assertBrowserUrlAllowed(url, { allowPrivateUrls: allowPrivate });\n\n const r = await ext.sendCommand('navigate', { url }, { timeout });\n if (!r.ok) return fail(name, 'NAVIGATE_FAILED', r.error ?? 'navigate failed');\n\n const data = r.data as { url?: string; title?: string } | undefined;\n const finalUrl = data?.url ?? url;\n const title = data?.title ?? '';\n\n if (finalUrl && finalUrl !== url) {\n const redirectBlock = checkPostRedirectUrl(finalUrl, { allowPrivateUrls: allowPrivate });\n if (redirectBlock) {\n await ext.sendCommand('navigate', { url: 'about:blank' }, { timeout: Math.min(10_000, timeout) }).catch(() => {});\n return fail(name, 'REDIRECT_BLOCKED', redirectBlock);\n }\n }\n\n let snapshot = '';\n try {\n const snap = await ext.sendCommand('snapshot', {}, { timeout });\n if (snap.ok && snap.data) {\n snapshot = formatAxSnapshot(snap.data, AUTO_SNAPSHOT_MAX);\n }\n } catch {\n /* non-fatal */\n }\n\n const text = `Navigated to: ${title}\\nURL: ${finalUrl}${snapshot ? `\\n--- Page Snapshot ---\\n${snapshot}` : ''}`;\n return ok(name, text, { url: finalUrl, title });\n }\n\n case 'state':\n case 'snapshot': {\n const maxLen = typeof args.maxLength === 'number' ? args.maxLength : DEFAULT_SNAPSHOT_MAX;\n if (args.selector && String(args.selector).trim()) {\n return fail(name, 'NOT_SUPPORTED', 'selector-scoped state is not supported with the Chrome Extension backend');\n }\n const r = await ext.sendCommand('snapshot', {}, { timeout });\n if (!r.ok) return fail(name, 'SNAPSHOT_FAILED', r.error ?? 'snapshot failed');\n const body = formatAxSnapshot(r.data, maxLen);\n const data = r.data as { url?: string; title?: string } | undefined;\n const header = data?.url ? `URL: ${data.url}\\nTitle: ${data.title ?? ''}\\n\\n` : '';\n return ok(name, `${header}--- Page Snapshot ---\\n${body}`, { length: body.length });\n }\n\n case 'click': {\n const selector = args.selector as string | undefined;\n const text = args.text as string | undefined;\n const role = args.role as string | undefined;\n if (role?.trim()) {\n return fail(name, 'NOT_SUPPORTED', 'role-based click is not supported with the Chrome Extension backend; use selector or text');\n }\n const n = (Boolean(selector?.trim()) ? 1 : 0) + (Boolean(text?.trim()) ? 1 : 0);\n if (n !== 1) {\n return fail(name, 'INVALID_ARGS', 'Provide exactly one of: selector, text');\n }\n const r = await ext.sendCommand('click', { selector: selector?.trim(), text: text?.trim() }, { timeout });\n if (!r.ok) return fail(name, 'CLICK_FAILED', r.error ?? 'click failed');\n return ok(name, 'Click succeeded.');\n }\n\n case 'type':\n case 'input': {\n const selector = args.selector as string | undefined;\n const label = args.label as string | undefined;\n if (label?.trim() && !selector?.trim()) {\n return fail(name, 'NOT_SUPPORTED', 'label-based typing is not supported with the Chrome Extension backend; use selector');\n }\n const text = String(args.text ?? '');\n if (!text) return fail(name, 'MISSING_TEXT', 'text is required');\n const r = await ext.sendCommand(\n 'type',\n { selector: selector?.trim(), text, pressEnter: args.pressEnter === true },\n { timeout },\n );\n if (!r.ok) return fail(name, 'TYPE_FAILED', r.error ?? 'type failed');\n return ok(name, 'Typed into field.');\n }\n\n case 'scroll': {\n const direction = (args.direction as string) ?? 'down';\n const amount = typeof args.amount === 'number' ? args.amount : 500;\n const deltaY = direction === 'down' ? amount : -amount;\n const r = await ext.sendCommand('scroll', { deltaY }, { timeout });\n if (!r.ok) return fail(name, 'SCROLL_FAILED', r.error ?? 'scroll failed');\n return ok(name, `Scrolled ${direction} by ${amount}px.`);\n }\n\n case 'back': {\n const r = await ext.sendCommand('back', {}, { timeout });\n if (!r.ok) return fail(name, 'BACK_FAILED', r.error ?? 'back failed');\n const data = r.data as { url?: string; title?: string } | undefined;\n return ok(name, `Navigated back to: ${data?.title ?? ''}\\nURL: ${data?.url ?? ''}`, { url: data?.url, title: data?.title });\n }\n\n case 'screenshot': {\n const fullPage = args.full_page === true || args.fullPage === true;\n const path = args.path as string | undefined;\n const selector = args.selector as string | undefined;\n if (selector?.trim()) {\n return fail(name, 'NOT_SUPPORTED', 'selector-scoped screenshots are not supported with the Chrome Extension backend');\n }\n const r = await ext.sendCommand('screenshot', { fullPage }, { timeout });\n if (!r.ok) return fail(name, 'SCREENSHOT_FAILED', r.error ?? 'screenshot failed');\n const b64 = (r.data as { base64?: string } | undefined)?.base64;\n if (!b64) return fail(name, 'SCREENSHOT_FAILED', 'no image data');\n const artifact = { type: 'screenshot' as const, path, data: b64, mimeType: 'image/png' };\n const approxBytes = Math.floor((b64.length * 3) / 4);\n return ok(name, `Screenshot captured (~${approxBytes} bytes).`, { bytes: approxBytes }, [artifact]);\n }\n\n case 'keys':\n case 'press': {\n const key = String(args.key ?? '');\n if (!key) return fail(name, 'MISSING_KEY', 'key is required');\n const r = await ext.sendCommand('keys', { key }, { timeout });\n if (!r.ok) return fail(name, 'PRESS_FAILED', r.error ?? 'keys failed');\n return ok(name, `Pressed key: ${key}`);\n }\n\n case 'console':\n case 'eval':\n case 'evaluate': {\n const js =\n (args.javascript as string) ?? (args.expression as string) ?? (args.code as string) ?? '';\n if (!js.trim()) return fail(name, 'MISSING_JS', 'javascript expression is required');\n const r = await ext.sendCommand('evaluate', { expression: js }, { timeout });\n if (!r.ok) return fail(name, 'EVAL_FAILED', r.error ?? 'evaluate failed');\n const result = (r.data as { result?: unknown } | undefined)?.result;\n const serialized = result === undefined ? 'undefined' : JSON.stringify(result, null, 2);\n const text =\n serialized.length > DEFAULT_SNAPSHOT_MAX\n ? `${serialized.slice(0, DEFAULT_SNAPSHOT_MAX)}\\n... (truncated)`\n : serialized;\n return ok(name, text, result);\n }\n\n case 'images': {\n const selector = args.selector as string | undefined;\n const maxImages = typeof args.maxImages === 'number' ? args.maxImages : 20;\n const expr = `(() => {\n const sel = ${JSON.stringify(selector?.trim() || null)};\n const max = ${JSON.stringify(maxImages)};\n const d = globalThis.document;\n const root = sel ? d.querySelector(sel) : d;\n if (!root) return [];\n const imgs = Array.from(root.querySelectorAll('img'));\n return imgs.slice(0, max).map((img) => ({\n src: String(img.src ?? ''),\n alt: String(img.alt ?? ''),\n width: Number(img.naturalWidth ?? 0),\n height: Number(img.naturalHeight ?? 0),\n }));\n })()`;\n const r = await ext.sendCommand('evaluate', { expression: expr }, { timeout });\n if (!r.ok) return fail(name, 'IMAGES_FAILED', r.error ?? 'evaluate failed');\n const images = (r.data as { result?: unknown[] } | undefined)?.result as\n | Array<{ src: string; alt: string; width: number; height: number }>\n | undefined;\n if (!images || images.length === 0) return ok(name, 'No images found on the page.', []);\n const lines = images.map(\n (img, i) => `${i + 1}. ${img.alt || '(no alt)'} — ${img.width}×${img.height}\\n ${img.src}`,\n );\n return ok(name, `Found ${images.length} image(s):\\n${lines.join('\\n')}`, images);\n }\n\n case 'dialog': {\n const action = args.action as string;\n if (action !== 'accept' && action !== 'dismiss') {\n return fail(name, 'INVALID_ACTION', 'action must be \"accept\" or \"dismiss\"');\n }\n const r = await ext.sendCommand('dialog', { accept: action === 'accept' }, { timeout });\n if (!r.ok) return fail(name, 'DIALOG_FAILED', r.error ?? 'dialog failed');\n return ok(name, `Dialog ${action}ed.`);\n }\n\n case 'close': {\n return ok(name, 'Browser page closed.');\n }\n\n case 'wait': {\n const selector = args.selector as string | undefined;\n const text = args.text as string | undefined;\n const timeoutMs = typeof args.timeout_ms === 'number' ? args.timeout_ms : timeout;\n if (text?.trim()) {\n return fail(name, 'NOT_SUPPORTED', 'text-based wait is not supported with the Chrome Extension backend; use selector or ms');\n }\n const extArgs: Record<string, unknown> = {};\n if (selector?.trim()) {\n extArgs.selector = selector.trim();\n } else {\n extArgs.ms = typeof args.ms === 'number' ? args.ms : 1000;\n }\n const r = await ext.sendCommand('wait', extArgs, { timeout: timeoutMs });\n if (!r.ok) return fail(name, 'WAIT_TIMEOUT', r.error ?? 'wait failed');\n return ok(name, 'Wait completed.');\n }\n\n case 'output':\n return ok(name, 'Output captured.', args.value ?? ctx.pipelineData);\n\n case 'assert': {\n const value = String(args.value ?? ctx.pipelineData ?? '');\n const contains = args.contains as string | undefined;\n const equals = args.equals as string | undefined;\n if (contains && !value.includes(contains)) {\n return fail(name, 'ASSERTION_FAILED', `Expected value to contain \"${contains}\"`);\n }\n if (equals !== undefined && value !== equals) {\n return fail(name, 'ASSERTION_FAILED', `Expected value to equal \"${equals}\"`);\n }\n return ok(name, 'Assertion passed.');\n }\n\n case 'network_start':\n case 'network_events':\n case 'network_stop':\n case 'cdp':\n return fail(name, 'NOT_SUPPORTED', `Action \"${name}\" is not available with the Chrome Extension backend`);\n\n default:\n return fail(name, 'UNKNOWN_ACTION', `Unknown browser action: ${name}`);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extension-registry-bridge.js","names":["d"],"sources":["../../../../src/browser/actions/extension-registry-bridge.ts"],"sourcesContent":["/**\n * Runs browser registry actions against the Chrome Extension bridge (no Playwright page).\n */\n\nimport { assertBrowserUrlAllowed, checkPostRedirectUrl, containsApiKeyPattern } from '../url-policy.js';\nimport { checkWebsiteBlocklist } from '../../agent/tools/url-safety.js';\nimport { resolveBrowserCommandTimeoutMs } from '../browser-command-timeout.js';\nimport { truncateSnapshotAtBoundary } from '../snapshot-helpers.js';\nimport { isTruthyValue, resolvePath, valueContains } from '../pipeline/template.js';\n\nimport type { BrowserActionContext, BrowserActionResult } from './types.js';\n\nconst DEFAULT_SNAPSHOT_MAX = 30_000;\nconst AUTO_SNAPSHOT_MAX = 8_000;\n\nfunction toMs(ctx: BrowserActionContext): number {\n return resolveBrowserCommandTimeoutMs(ctx.config);\n}\n\nfunction ok(action: string, text: string, data?: unknown, artifacts?: BrowserActionResult['artifacts']): BrowserActionResult {\n return { ok: true, action, text, data, artifacts };\n}\n\nfunction fail(action: string, code: string, message: string, diagnostics?: BrowserActionResult['diagnostics']): BrowserActionResult {\n return { ok: false, action, error: { code, message }, diagnostics };\n}\n\nfunction pipelineLast(ctx: BrowserActionContext): unknown {\n return ctx.pipeline?.last;\n}\n\nfunction valueFromArgs(ctx: BrowserActionContext, args: Record<string, unknown>): unknown {\n if ('value' in args) return args.value;\n if (typeof args.path === 'string') return resolvePath(pipelineLast(ctx), args.path);\n return pipelineLast(ctx);\n}\n\nfunction compareValues(a: unknown, b: unknown): number {\n const av = typeof a === 'number' ? a : String(a ?? '');\n const bv = typeof b === 'number' ? b : String(b ?? '');\n if (av < bv) return -1;\n if (av > bv) return 1;\n return 0;\n}\n\nfunction formatAxSnapshot(data: unknown, maxLen: number): string {\n const d = data as { nodes?: Array<{ role?: string; name?: string }> } | undefined;\n const nodes = d?.nodes ?? [];\n if (nodes.length === 0) return '(empty snapshot)';\n const lines = nodes.map((n) => `${n.role ?? '?'}: ${n.name ?? ''}`);\n let text = lines.join('\\n');\n if (text.length > maxLen) text = truncateSnapshotAtBoundary(text, maxLen);\n return text;\n}\n\nexport async function runExtensionRegistryAction(\n name: string,\n ctx: BrowserActionContext,\n args: Record<string, unknown>,\n): Promise<BrowserActionResult> {\n if (ctx.signal?.aborted) {\n return fail(name, 'ABORTED', 'Operation was aborted');\n }\n const ext = ctx.manager.getExtensionProvider();\n if (!ext) {\n return fail(name, 'NO_EXTENSION', 'Extension backend not connected');\n }\n\n const timeout = toMs(ctx);\n const allowPrivate = ctx.config?.agents?.defaults?.browser?.allowPrivateUrls === true;\n\n switch (name) {\n case 'open':\n case 'navigate': {\n const url = String(args.url ?? '');\n if (!url) return fail(name, 'MISSING_URL', 'url is required');\n if (containsApiKeyPattern(url)) return fail(name, 'BLOCKED', 'URL contains API key/token');\n const block = checkWebsiteBlocklist(url, ctx.config?.tools?.web?.blocklist);\n if (block) return fail(name, 'BLOCKED', block.message);\n assertBrowserUrlAllowed(url, { allowPrivateUrls: allowPrivate });\n\n const r = await ext.sendCommand('navigate', { url }, { timeout });\n if (!r.ok) return fail(name, 'NAVIGATE_FAILED', r.error ?? 'navigate failed');\n\n const data = r.data as { url?: string; title?: string } | undefined;\n const finalUrl = data?.url ?? url;\n const title = data?.title ?? '';\n\n if (finalUrl && finalUrl !== url) {\n const redirectBlock = checkPostRedirectUrl(finalUrl, { allowPrivateUrls: allowPrivate });\n if (redirectBlock) {\n await ext.sendCommand('navigate', { url: 'about:blank' }, { timeout: Math.min(10_000, timeout) }).catch(() => {});\n return fail(name, 'REDIRECT_BLOCKED', redirectBlock);\n }\n }\n\n let snapshot = '';\n try {\n const snap = await ext.sendCommand('snapshot', {}, { timeout });\n if (snap.ok && snap.data) {\n snapshot = formatAxSnapshot(snap.data, AUTO_SNAPSHOT_MAX);\n }\n } catch {\n /* non-fatal */\n }\n\n const text = `Navigated to: ${title}\\nURL: ${finalUrl}${snapshot ? `\\n--- Page Snapshot ---\\n${snapshot}` : ''}`;\n return ok(name, text, { url: finalUrl, title });\n }\n\n case 'state':\n case 'snapshot': {\n const maxLen = typeof args.maxLength === 'number' ? args.maxLength : DEFAULT_SNAPSHOT_MAX;\n if (args.selector && String(args.selector).trim()) {\n return fail(name, 'NOT_SUPPORTED', 'selector-scoped state is not supported with the Chrome Extension backend');\n }\n const r = await ext.sendCommand('snapshot', {}, { timeout });\n if (!r.ok) return fail(name, 'SNAPSHOT_FAILED', r.error ?? 'snapshot failed');\n const body = formatAxSnapshot(r.data, maxLen);\n const data = r.data as { url?: string; title?: string } | undefined;\n const header = data?.url ? `URL: ${data.url}\\nTitle: ${data.title ?? ''}\\n\\n` : '';\n return ok(name, `${header}--- Page Snapshot ---\\n${body}`, { length: body.length });\n }\n\n case 'click': {\n const selector = args.selector as string | undefined;\n const text = args.text as string | undefined;\n const role = args.role as string | undefined;\n if (role?.trim()) {\n return fail(name, 'NOT_SUPPORTED', 'role-based click is not supported with the Chrome Extension backend; use selector or text');\n }\n const n = (Boolean(selector?.trim()) ? 1 : 0) + (Boolean(text?.trim()) ? 1 : 0);\n if (n !== 1) {\n return fail(name, 'INVALID_ARGS', 'Provide exactly one of: selector, text');\n }\n const r = await ext.sendCommand('click', { selector: selector?.trim(), text: text?.trim() }, { timeout });\n if (!r.ok) return fail(name, 'CLICK_FAILED', r.error ?? 'click failed');\n return ok(name, 'Click succeeded.');\n }\n\n case 'type':\n case 'input': {\n const selector = args.selector as string | undefined;\n const label = args.label as string | undefined;\n if (label?.trim() && !selector?.trim()) {\n return fail(name, 'NOT_SUPPORTED', 'label-based typing is not supported with the Chrome Extension backend; use selector');\n }\n const text = String(args.text ?? '');\n if (!text) return fail(name, 'MISSING_TEXT', 'text is required');\n const r = await ext.sendCommand(\n 'type',\n { selector: selector?.trim(), text, pressEnter: args.pressEnter === true },\n { timeout },\n );\n if (!r.ok) return fail(name, 'TYPE_FAILED', r.error ?? 'type failed');\n return ok(name, 'Typed into field.');\n }\n\n case 'scroll': {\n const direction = (args.direction as string) ?? 'down';\n const amount = typeof args.amount === 'number' ? args.amount : 500;\n const deltaY = direction === 'down' ? amount : -amount;\n const r = await ext.sendCommand('scroll', { deltaY }, { timeout });\n if (!r.ok) return fail(name, 'SCROLL_FAILED', r.error ?? 'scroll failed');\n return ok(name, `Scrolled ${direction} by ${amount}px.`);\n }\n\n case 'back': {\n const r = await ext.sendCommand('back', {}, { timeout });\n if (!r.ok) return fail(name, 'BACK_FAILED', r.error ?? 'back failed');\n const data = r.data as { url?: string; title?: string } | undefined;\n return ok(name, `Navigated back to: ${data?.title ?? ''}\\nURL: ${data?.url ?? ''}`, { url: data?.url, title: data?.title });\n }\n\n case 'screenshot': {\n const fullPage = args.full_page === true || args.fullPage === true;\n const path = args.path as string | undefined;\n const selector = args.selector as string | undefined;\n if (selector?.trim()) {\n return fail(name, 'NOT_SUPPORTED', 'selector-scoped screenshots are not supported with the Chrome Extension backend');\n }\n const r = await ext.sendCommand('screenshot', { fullPage }, { timeout });\n if (!r.ok) return fail(name, 'SCREENSHOT_FAILED', r.error ?? 'screenshot failed');\n const b64 = (r.data as { base64?: string } | undefined)?.base64;\n if (!b64) return fail(name, 'SCREENSHOT_FAILED', 'no image data');\n const artifact = { type: 'screenshot' as const, path, data: b64, mimeType: 'image/png' };\n const approxBytes = Math.floor((b64.length * 3) / 4);\n return ok(name, `Screenshot captured (~${approxBytes} bytes).`, { bytes: approxBytes }, [artifact]);\n }\n\n case 'keys':\n case 'press': {\n const key = String(args.key ?? '');\n if (!key) return fail(name, 'MISSING_KEY', 'key is required');\n const r = await ext.sendCommand('keys', { key }, { timeout });\n if (!r.ok) return fail(name, 'PRESS_FAILED', r.error ?? 'keys failed');\n return ok(name, `Pressed key: ${key}`);\n }\n\n case 'console':\n case 'eval':\n case 'evaluate': {\n const js =\n (args.javascript as string) ?? (args.expression as string) ?? (args.code as string) ?? '';\n if (!js.trim()) return fail(name, 'MISSING_JS', 'javascript expression is required');\n const r = await ext.sendCommand('evaluate', { expression: js }, { timeout });\n if (!r.ok) return fail(name, 'EVAL_FAILED', r.error ?? 'evaluate failed');\n const result = (r.data as { result?: unknown } | undefined)?.result;\n const serialized = result === undefined ? 'undefined' : JSON.stringify(result, null, 2);\n const text =\n serialized.length > DEFAULT_SNAPSHOT_MAX\n ? `${serialized.slice(0, DEFAULT_SNAPSHOT_MAX)}\\n... (truncated)`\n : serialized;\n return ok(name, text, result);\n }\n\n case 'images': {\n const selector = args.selector as string | undefined;\n const maxImages = typeof args.maxImages === 'number' ? args.maxImages : 20;\n const expr = `(() => {\n const sel = ${JSON.stringify(selector?.trim() || null)};\n const max = ${JSON.stringify(maxImages)};\n const d = globalThis.document;\n const root = sel ? d.querySelector(sel) : d;\n if (!root) return [];\n const imgs = Array.from(root.querySelectorAll('img'));\n return imgs.slice(0, max).map((img) => ({\n src: String(img.src ?? ''),\n alt: String(img.alt ?? ''),\n width: Number(img.naturalWidth ?? 0),\n height: Number(img.naturalHeight ?? 0),\n }));\n })()`;\n const r = await ext.sendCommand('evaluate', { expression: expr }, { timeout });\n if (!r.ok) return fail(name, 'IMAGES_FAILED', r.error ?? 'evaluate failed');\n const images = (r.data as { result?: unknown[] } | undefined)?.result as\n | Array<{ src: string; alt: string; width: number; height: number }>\n | undefined;\n if (!images || images.length === 0) return ok(name, 'No images found on the page.', []);\n const lines = images.map(\n (img, i) => `${i + 1}. ${img.alt || '(no alt)'} — ${img.width}×${img.height}\\n ${img.src}`,\n );\n return ok(name, `Found ${images.length} image(s):\\n${lines.join('\\n')}`, images);\n }\n\n case 'dialog': {\n const action = args.action as string;\n if (action !== 'accept' && action !== 'dismiss') {\n return fail(name, 'INVALID_ACTION', 'action must be \"accept\" or \"dismiss\"');\n }\n const r = await ext.sendCommand('dialog', { accept: action === 'accept' }, { timeout });\n if (!r.ok) return fail(name, 'DIALOG_FAILED', r.error ?? 'dialog failed');\n return ok(name, `Dialog ${action}ed.`);\n }\n\n case 'close': {\n return ok(name, 'Browser page closed.');\n }\n\n case 'wait': {\n const selector = args.selector as string | undefined;\n const text = args.text as string | undefined;\n const timeoutMs = typeof args.timeout_ms === 'number' ? args.timeout_ms : timeout;\n if (text?.trim()) {\n return fail(name, 'NOT_SUPPORTED', 'text-based wait is not supported with the Chrome Extension backend; use selector or ms');\n }\n const extArgs: Record<string, unknown> = {};\n if (selector?.trim()) {\n extArgs.selector = selector.trim();\n } else {\n extArgs.ms = typeof args.ms === 'number' ? args.ms : 1000;\n }\n const r = await ext.sendCommand('wait', extArgs, { timeout: timeoutMs });\n if (!r.ok) return fail(name, 'WAIT_TIMEOUT', r.error ?? 'wait failed');\n return ok(name, 'Wait completed.');\n }\n\n case 'wait_for_timeout': {\n const ms = typeof args.ms === 'number' ? args.ms : typeof args.timeout_ms === 'number' ? args.timeout_ms : 1000;\n const r = await ext.sendCommand('wait', { ms }, { timeout: ms + 1000 });\n if (!r.ok) return fail(name, 'WAIT_TIMEOUT', r.error ?? 'wait failed');\n return ok(name, `Waited ${ms}ms.`);\n }\n\n case 'output':\n return ok(name, 'Output captured.', valueFromArgs(ctx, args));\n\n case 'assert': {\n const actual = valueFromArgs(ctx, args);\n if ('equals' in args && JSON.stringify(actual) !== JSON.stringify(args.equals)) {\n return fail(name, 'ASSERTION_FAILED', `Expected value to equal ${JSON.stringify(args.equals)}`);\n }\n if ('contains' in args && !valueContains(actual, args.contains)) {\n return fail(name, 'ASSERTION_FAILED', `Expected value to contain ${JSON.stringify(args.contains)}`);\n }\n if (args.truthy === true && !isTruthyValue(actual)) {\n return fail(name, 'ASSERTION_FAILED', 'Expected value to be truthy');\n }\n if (args.exists === true && (actual === undefined || actual === null || actual === '')) {\n return fail(name, 'ASSERTION_FAILED', 'Expected value to exist');\n }\n return ok(name, 'Assertion passed.');\n }\n\n case 'select': {\n const source = 'from' in args ? args.from : pipelineLast(ctx);\n const path = String(args.path ?? args.value ?? '');\n const value = path ? resolvePath(source, path) : source;\n return ok(name, typeof value === 'string' ? value : JSON.stringify(value, null, 2), value);\n }\n\n case 'map': {\n const source = 'from' in args ? args.from : pipelineLast(ctx);\n if (!Array.isArray(source)) return fail(name, 'INVALID_INPUT', 'map input must be an array');\n const path = String(args.path ?? '');\n const value = path ? source.map((item) => resolvePath(item, path)) : source;\n return ok(name, JSON.stringify(value, null, 2), value);\n }\n\n case 'filter': {\n const source = 'from' in args ? args.from : pipelineLast(ctx);\n if (!Array.isArray(source)) return fail(name, 'INVALID_INPUT', 'filter input must be an array');\n const path = String(args.path ?? '');\n const value = source.filter((item) => {\n const itemValue = path ? resolvePath(item, path) : item;\n if ('equals' in args) return JSON.stringify(itemValue) === JSON.stringify(args.equals);\n if ('contains' in args) return valueContains(itemValue, args.contains);\n return isTruthyValue(itemValue);\n });\n return ok(name, JSON.stringify(value, null, 2), value);\n }\n\n case 'sort': {\n const source = 'from' in args ? args.from : pipelineLast(ctx);\n if (!Array.isArray(source)) return fail(name, 'INVALID_INPUT', 'sort input must be an array');\n const path = String(args.path ?? '');\n const direction = String(args.direction ?? 'asc');\n const value = [...source].sort((a, b) => {\n const cmp = compareValues(path ? resolvePath(a, path) : a, path ? resolvePath(b, path) : b);\n return direction === 'desc' ? -cmp : cmp;\n });\n return ok(name, JSON.stringify(value, null, 2), value);\n }\n\n case 'limit': {\n const source = 'from' in args ? args.from : pipelineLast(ctx);\n if (!Array.isArray(source)) return fail(name, 'INVALID_INPUT', 'limit input must be an array');\n const count = Math.max(0, Number(args.count ?? args.limit ?? 10));\n const offset = Math.max(0, Number(args.offset ?? 0));\n const value = source.slice(offset, offset + count);\n return ok(name, JSON.stringify(value, null, 2), value);\n }\n\n case 'network_start':\n case 'network_events':\n case 'network_stop':\n case 'cdp':\n case 'wait_for_navigation':\n case 'wait_for_function':\n case 'wait_for_network_idle':\n case 'element_text':\n case 'element_attribute':\n case 'bounding_box':\n case 'set_input_files':\n case 'cookies':\n case 'get_cookies':\n case 'add_cookies':\n case 'clear_cookies':\n case 'tabs':\n case 'list_tabs':\n case 'new_tab':\n case 'switch_tab':\n case 'fetch':\n case 'collect':\n case 'tap':\n return fail(name, 'NOT_SUPPORTED', `Action \"${name}\" is not available with the Chrome Extension backend`);\n\n default:\n return fail(name, 'UNKNOWN_ACTION', `Unknown browser action: ${name}`);\n }\n}\n"],"mappings":"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"}
@@ -5,11 +5,13 @@ import { resolveBrowserCommandTimeoutMs } from "../browser-command-timeout.js";
5
5
  import { assertBrowserUrlAllowed, checkPostRedirectUrl, containsApiKeyPattern } from "../url-policy.js";
6
6
  import { truncateSnapshotAtBoundary } from "../snapshot-helpers.js";
7
7
  import { humanizedClick, humanizedFill, humanizedScroll } from "../humanize.js";
8
+ import { isTruthyValue, resolvePath, valueContains } from "../pipeline/template.js";
8
9
  //#region src/browser/actions/registry.ts
9
10
  init_logger();
10
11
  const log = createLogger("BrowserActionRegistry");
11
12
  const DEFAULT_SNAPSHOT_MAX = 3e4;
12
13
  const AUTO_SNAPSHOT_MAX = 8e3;
14
+ const networkMonitors = /* @__PURE__ */ new WeakMap();
13
15
  function toMs(ctx) {
14
16
  return resolveBrowserCommandTimeoutMs(ctx.config);
15
17
  }
@@ -82,6 +84,28 @@ function fail(action, code, message, diagnostics) {
82
84
  diagnostics
83
85
  };
84
86
  }
87
+ function asObject(value) {
88
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
89
+ }
90
+ function pipelineLast(ctx) {
91
+ return ctx.pipeline?.last;
92
+ }
93
+ function valueFromArgs(ctx, args) {
94
+ if ("value" in args) return args.value;
95
+ if (typeof args.path === "string") return resolvePath(pipelineLast(ctx), args.path);
96
+ return pipelineLast(ctx);
97
+ }
98
+ function compareValues(a, b) {
99
+ const av = typeof a === "number" ? a : String(a ?? "");
100
+ const bv = typeof b === "number" ? b : String(b ?? "");
101
+ if (av < bv) return -1;
102
+ if (av > bv) return 1;
103
+ return 0;
104
+ }
105
+ function matchesNetworkPattern(url, pattern) {
106
+ if (!pattern) return true;
107
+ return url.includes(pattern);
108
+ }
85
109
  const navigateAction = async (ctx, args) => {
86
110
  const url = String(args.url ?? "");
87
111
  if (!url) return fail("navigate", "MISSING_URL", "url is required");
@@ -279,16 +303,18 @@ const dialogAction = async (ctx, args) => {
279
303
  const waitAction = async (ctx, args) => {
280
304
  const selector = args.selector;
281
305
  const text = args.text;
306
+ const state = args.state ?? "visible";
282
307
  const timeoutMs = typeof args.timeout_ms === "number" ? args.timeout_ms : toMs(ctx);
283
308
  try {
284
309
  if (selector?.trim()) await ctx.page.locator(selector.trim()).first().waitFor({
285
- state: "visible",
310
+ state,
286
311
  timeout: timeoutMs
287
312
  });
288
313
  else if (text?.trim()) await ctx.page.getByText(text.trim()).first().waitFor({
289
314
  state: "visible",
290
315
  timeout: timeoutMs
291
316
  });
317
+ else if (args.function || args.expression) await ctx.page.waitForFunction(String(args.function ?? args.expression), null, { timeout: timeoutMs });
292
318
  else {
293
319
  const ms = typeof args.ms === "number" ? args.ms : 1e3;
294
320
  await ctx.page.waitForTimeout(ms);
@@ -299,16 +325,339 @@ const waitAction = async (ctx, args) => {
299
325
  }
300
326
  };
301
327
  const outputAction = async (ctx, args) => {
302
- return ok("output", "Output captured.", args.value ?? ctx.pipelineData);
328
+ return ok("output", "Output captured.", valueFromArgs(ctx, args));
303
329
  };
304
330
  const assertAction = async (ctx, args) => {
305
- const value = String(args.value ?? ctx.pipelineData ?? "");
306
- const contains = args.contains;
307
- const equals = args.equals;
308
- if (contains && !value.includes(contains)) return fail("assert", "ASSERTION_FAILED", `Expected value to contain "${contains}"`);
309
- if (equals !== void 0 && value !== equals) return fail("assert", "ASSERTION_FAILED", `Expected value to equal "${equals}"`);
331
+ const actual = valueFromArgs(ctx, args);
332
+ if ("equals" in args && JSON.stringify(actual) !== JSON.stringify(args.equals)) return fail("assert", "ASSERTION_FAILED", `Expected value to equal ${JSON.stringify(args.equals)}, got ${JSON.stringify(actual)?.slice(0, 500)}`);
333
+ if ("contains" in args && !valueContains(actual, args.contains)) return fail("assert", "ASSERTION_FAILED", `Expected value to contain ${JSON.stringify(args.contains)}`);
334
+ if ("matches" in args) {
335
+ const pattern = new RegExp(String(args.matches));
336
+ if (!pattern.test(String(actual ?? ""))) return fail("assert", "ASSERTION_FAILED", `Expected value to match /${pattern.source}/`);
337
+ }
338
+ if (args.truthy === true && !isTruthyValue(actual)) return fail("assert", "ASSERTION_FAILED", `Expected value to be truthy, got ${JSON.stringify(actual)}`);
339
+ if (args.exists === true && (actual === void 0 || actual === null || actual === "")) return fail("assert", "ASSERTION_FAILED", "Expected value to exist");
310
340
  return ok("assert", "Assertion passed.");
311
341
  };
342
+ const waitForNavigationAction = async (ctx, args) => {
343
+ const timeout = typeof args.timeout_ms === "number" ? args.timeout_ms : toMs(ctx);
344
+ const waitUntil = args.wait_until ?? "domcontentloaded";
345
+ try {
346
+ await ctx.page.waitForLoadState(waitUntil, { timeout });
347
+ return ok("wait_for_navigation", "Navigation wait completed.");
348
+ } catch (e) {
349
+ return fail("wait_for_navigation", "WAIT_TIMEOUT", e instanceof Error ? e.message : String(e));
350
+ }
351
+ };
352
+ const waitForTimeoutAction = async (ctx, args) => {
353
+ const ms = Number(args.ms ?? args.timeout_ms ?? 1e3);
354
+ await ctx.page.waitForTimeout(Number.isFinite(ms) ? ms : 1e3);
355
+ return ok("wait_for_timeout", `Waited ${ms}ms.`);
356
+ };
357
+ const waitForFunctionAction = async (ctx, args) => {
358
+ const expression = String(args.expression ?? args.function ?? "");
359
+ if (!expression.trim()) return fail("wait_for_function", "MISSING_EXPRESSION", "expression is required");
360
+ const timeout = typeof args.timeout_ms === "number" ? args.timeout_ms : toMs(ctx);
361
+ try {
362
+ await ctx.page.waitForFunction(expression, null, { timeout });
363
+ return ok("wait_for_function", "Function wait completed.");
364
+ } catch (e) {
365
+ return fail("wait_for_function", "WAIT_TIMEOUT", e instanceof Error ? e.message : String(e));
366
+ }
367
+ };
368
+ const waitForNetworkIdleAction = async (ctx, args) => {
369
+ const timeout = typeof args.timeout_ms === "number" ? args.timeout_ms : toMs(ctx);
370
+ try {
371
+ await ctx.page.waitForLoadState("networkidle", { timeout });
372
+ return ok("wait_for_network_idle", "Network idle reached.");
373
+ } catch (e) {
374
+ return fail("wait_for_network_idle", "WAIT_TIMEOUT", e instanceof Error ? e.message : String(e));
375
+ }
376
+ };
377
+ const elementTextAction = async (ctx, args) => {
378
+ const selector = String(args.selector ?? "");
379
+ if (!selector) return fail("element_text", "MISSING_SELECTOR", "selector is required");
380
+ const timeout = toMs(ctx);
381
+ const loc = ctx.page.locator(selector).first();
382
+ await loc.waitFor({
383
+ state: "attached",
384
+ timeout
385
+ });
386
+ const text = await loc.innerText({ timeout }).catch(() => loc.textContent({ timeout }));
387
+ return ok("element_text", String(text ?? ""), text ?? "");
388
+ };
389
+ const elementAttributeAction = async (ctx, args) => {
390
+ const selector = String(args.selector ?? "");
391
+ const attribute = String(args.attribute ?? "");
392
+ if (!selector || !attribute) return fail("element_attribute", "INVALID_ARGS", "selector and attribute are required");
393
+ const timeout = toMs(ctx);
394
+ const loc = ctx.page.locator(selector).first();
395
+ await loc.waitFor({
396
+ state: "attached",
397
+ timeout
398
+ });
399
+ const value = await loc.getAttribute(attribute, { timeout });
400
+ return ok("element_attribute", value ?? "", value);
401
+ };
402
+ const boundingBoxAction = async (ctx, args) => {
403
+ const selector = String(args.selector ?? "");
404
+ if (!selector) return fail("bounding_box", "MISSING_SELECTOR", "selector is required");
405
+ const timeout = toMs(ctx);
406
+ const loc = ctx.page.locator(selector).first();
407
+ await loc.waitFor({
408
+ state: "visible",
409
+ timeout
410
+ });
411
+ const box = await loc.boundingBox({ timeout });
412
+ return ok("bounding_box", JSON.stringify(box), box);
413
+ };
414
+ const setInputFilesAction = async (ctx, args) => {
415
+ const selector = String(args.selector ?? "");
416
+ const files = Array.isArray(args.files) ? args.files.map(String) : typeof args.file === "string" ? [args.file] : [];
417
+ if (!selector || files.length === 0) return fail("set_input_files", "INVALID_ARGS", "selector and files are required");
418
+ await ctx.page.locator(selector).first().setInputFiles(files, { timeout: toMs(ctx) });
419
+ return ok("set_input_files", `Attached ${files.length} file(s).`, { files });
420
+ };
421
+ const getCookiesAction = async (ctx, args) => {
422
+ const urls = Array.isArray(args.urls) ? args.urls.map(String) : void 0;
423
+ const cookies = await ctx.page.context().cookies(urls);
424
+ return ok("cookies", JSON.stringify(cookies, null, 2), cookies);
425
+ };
426
+ const addCookiesAction = async (ctx, args) => {
427
+ const cookies = Array.isArray(args.cookies) ? args.cookies : [];
428
+ if (cookies.length === 0) return fail("add_cookies", "INVALID_ARGS", "cookies must be a non-empty array");
429
+ await ctx.page.context().addCookies(cookies);
430
+ return ok("add_cookies", `Added ${cookies.length} cookie(s).`);
431
+ };
432
+ const clearCookiesAction = async (ctx) => {
433
+ await ctx.page.context().clearCookies();
434
+ return ok("clear_cookies", "Cookies cleared.");
435
+ };
436
+ const listTabsAction = async (ctx) => {
437
+ const pages = ctx.page.context().pages();
438
+ const tabs = await Promise.all(pages.map(async (page, index) => ({
439
+ index,
440
+ url: page.url(),
441
+ title: await page.title().catch(() => "")
442
+ })));
443
+ return ok("tabs", JSON.stringify(tabs, null, 2), tabs);
444
+ };
445
+ const newTabAction = async (ctx, args) => {
446
+ const page = await ctx.page.context().newPage();
447
+ if (args.url) await page.goto(String(args.url), {
448
+ waitUntil: "domcontentloaded",
449
+ timeout: toMs(ctx)
450
+ });
451
+ return ok("new_tab", `Opened tab: ${page.url()}`, {
452
+ url: page.url(),
453
+ title: await page.title().catch(() => "")
454
+ });
455
+ };
456
+ const switchTabAction = async (ctx, args) => {
457
+ const index = Number(args.index ?? args.tab_index ?? 0);
458
+ const page = ctx.page.context().pages()[index];
459
+ if (!page) return fail("switch_tab", "TAB_NOT_FOUND", `No tab at index ${index}`);
460
+ await page.bringToFront();
461
+ return ok("switch_tab", `Switched to tab ${index}.`, {
462
+ index,
463
+ url: page.url()
464
+ });
465
+ };
466
+ const selectAction = async (ctx, args) => {
467
+ const source = "from" in args ? args.from : pipelineLast(ctx);
468
+ const path = String(args.path ?? args.value ?? "");
469
+ const value = path ? resolvePath(source, path) : source;
470
+ return ok("select", typeof value === "string" ? value : JSON.stringify(value, null, 2), value);
471
+ };
472
+ const mapAction = async (ctx, args) => {
473
+ const source = "from" in args ? args.from : pipelineLast(ctx);
474
+ if (!Array.isArray(source)) return fail("map", "INVALID_INPUT", "map input must be an array");
475
+ const path = String(args.path ?? "");
476
+ const result = path ? source.map((item) => resolvePath(item, path)) : source;
477
+ return ok("map", JSON.stringify(result, null, 2), result);
478
+ };
479
+ const filterAction = async (ctx, args) => {
480
+ const source = "from" in args ? args.from : pipelineLast(ctx);
481
+ if (!Array.isArray(source)) return fail("filter", "INVALID_INPUT", "filter input must be an array");
482
+ const path = String(args.path ?? "");
483
+ const equals = args.equals;
484
+ const contains = args.contains;
485
+ const truthy = args.truthy === true;
486
+ const result = source.filter((item) => {
487
+ const value = path ? resolvePath(item, path) : item;
488
+ if ("equals" in args) return JSON.stringify(value) === JSON.stringify(equals);
489
+ if ("contains" in args) return valueContains(value, contains);
490
+ if (truthy) return isTruthyValue(value);
491
+ return isTruthyValue(value);
492
+ });
493
+ return ok("filter", JSON.stringify(result, null, 2), result);
494
+ };
495
+ const sortAction = async (ctx, args) => {
496
+ const source = "from" in args ? args.from : pipelineLast(ctx);
497
+ if (!Array.isArray(source)) return fail("sort", "INVALID_INPUT", "sort input must be an array");
498
+ const path = String(args.path ?? "");
499
+ const direction = String(args.direction ?? "asc");
500
+ const result = [...source].sort((a, b) => {
501
+ const cmp = compareValues(path ? resolvePath(a, path) : a, path ? resolvePath(b, path) : b);
502
+ return direction === "desc" ? -cmp : cmp;
503
+ });
504
+ return ok("sort", JSON.stringify(result, null, 2), result);
505
+ };
506
+ const limitAction = async (ctx, args) => {
507
+ const source = "from" in args ? args.from : pipelineLast(ctx);
508
+ if (!Array.isArray(source)) return fail("limit", "INVALID_INPUT", "limit input must be an array");
509
+ const count = Math.max(0, Number(args.count ?? args.limit ?? 10));
510
+ const offset = Math.max(0, Number(args.offset ?? 0));
511
+ const result = source.slice(offset, offset + count);
512
+ return ok("limit", JSON.stringify(result, null, 2), result);
513
+ };
514
+ const fetchAction = async (ctx, args) => {
515
+ const url = String(args.url ?? "");
516
+ if (!url) return fail("fetch", "MISSING_URL", "url is required");
517
+ const method = String(args.method ?? "GET");
518
+ const headers = asObject(args.headers);
519
+ const body = args.body === void 0 ? void 0 : typeof args.body === "string" ? args.body : JSON.stringify(args.body);
520
+ const result = await ctx.page.evaluate(async ({ url, method, headers, body }) => {
521
+ const response = await fetch(url, {
522
+ method,
523
+ headers,
524
+ body
525
+ });
526
+ const text = await response.text();
527
+ const contentType = response.headers.get("content-type") ?? "";
528
+ let parsed = text;
529
+ if (contentType.includes("application/json")) try {
530
+ parsed = JSON.parse(text);
531
+ } catch {
532
+ parsed = text;
533
+ }
534
+ return {
535
+ ok: response.ok,
536
+ status: response.status,
537
+ url: response.url,
538
+ headers: Object.fromEntries(response.headers.entries()),
539
+ body: parsed
540
+ };
541
+ }, {
542
+ url,
543
+ method,
544
+ headers,
545
+ body
546
+ });
547
+ return ok("fetch", JSON.stringify(result, null, 2), result);
548
+ };
549
+ const networkStartAction = async (ctx, args) => {
550
+ networkMonitors.get(ctx.page)?.dispose();
551
+ const includeBody = args.include_body === true || args.includeBody === true;
552
+ const urlPattern = typeof args.url_pattern === "string" ? args.url_pattern : typeof args.urlPattern === "string" ? args.urlPattern : void 0;
553
+ const events = [];
554
+ const onRequest = (request) => {
555
+ if (!matchesNetworkPattern(request.url(), urlPattern)) return;
556
+ events.push({
557
+ type: "request",
558
+ url: request.url(),
559
+ method: request.method(),
560
+ resourceType: request.resourceType(),
561
+ postData: request.postData(),
562
+ timestamp: Date.now()
563
+ });
564
+ };
565
+ const onResponse = async (response) => {
566
+ if (!matchesNetworkPattern(response.url(), urlPattern)) return;
567
+ const event = {
568
+ type: "response",
569
+ url: response.url(),
570
+ status: response.status(),
571
+ timestamp: Date.now()
572
+ };
573
+ if (includeBody) event.body = await response.text().catch(() => void 0);
574
+ events.push(event);
575
+ };
576
+ const onRequestFailed = (request) => {
577
+ if (!matchesNetworkPattern(request.url(), urlPattern)) return;
578
+ events.push({
579
+ type: "requestfailed",
580
+ url: request.url(),
581
+ method: request.method(),
582
+ errorText: request.failure()?.errorText,
583
+ timestamp: Date.now()
584
+ });
585
+ };
586
+ ctx.page.on("request", onRequest);
587
+ ctx.page.on("response", onResponse);
588
+ ctx.page.on("requestfailed", onRequestFailed);
589
+ networkMonitors.set(ctx.page, {
590
+ events,
591
+ includeBody,
592
+ urlPattern,
593
+ dispose: () => {
594
+ ctx.page.off("request", onRequest);
595
+ ctx.page.off("response", onResponse);
596
+ ctx.page.off("requestfailed", onRequestFailed);
597
+ networkMonitors.delete(ctx.page);
598
+ }
599
+ });
600
+ return ok("network_start", "Network monitoring started.", {
601
+ includeBody,
602
+ urlPattern
603
+ });
604
+ };
605
+ const networkEventsAction = async (ctx) => {
606
+ const events = networkMonitors.get(ctx.page)?.events ?? [];
607
+ return ok("network_events", JSON.stringify(events, null, 2), events);
608
+ };
609
+ const networkStopAction = async (ctx) => {
610
+ const events = networkMonitors.get(ctx.page)?.events ?? [];
611
+ networkMonitors.get(ctx.page)?.dispose();
612
+ return ok("network_stop", JSON.stringify(events, null, 2), events);
613
+ };
614
+ const collectAction = async (ctx, args) => {
615
+ const events = networkMonitors.get(ctx.page)?.events ?? [];
616
+ if (args.parse) {
617
+ const parsed = await ctx.page.evaluate(({ events, parse }) => {
618
+ return (0, eval)(`(${parse})`)(events);
619
+ }, {
620
+ events,
621
+ parse: String(args.parse)
622
+ });
623
+ return ok("collect", JSON.stringify(parsed, null, 2), parsed);
624
+ }
625
+ return ok("collect", JSON.stringify(events, null, 2), events);
626
+ };
627
+ const tapAction = async (ctx, args) => {
628
+ const pattern = String(args.capture ?? args.url ?? args.pattern ?? "");
629
+ const timeoutMs = Number(args.timeout_ms ?? args.timeoutMs ?? 5e3);
630
+ const captured = await ctx.page.evaluate(async ({ pattern, timeoutMs }) => {
631
+ let result = null;
632
+ const g = globalThis;
633
+ const originalFetch = g.fetch;
634
+ g.fetch = async (...fetchArgs) => {
635
+ const response = await originalFetch(...fetchArgs);
636
+ try {
637
+ const url = typeof fetchArgs[0] === "string" ? fetchArgs[0] : fetchArgs[0]?.url ?? String(fetchArgs[0]);
638
+ if ((!pattern || url.includes(pattern)) && result === null) {
639
+ const text = await response.clone().text();
640
+ try {
641
+ result = JSON.parse(text);
642
+ } catch {
643
+ result = text;
644
+ }
645
+ }
646
+ } catch {}
647
+ return response;
648
+ };
649
+ try {
650
+ await new Promise((resolve) => setTimeout(resolve, timeoutMs));
651
+ } finally {
652
+ g.fetch = originalFetch;
653
+ }
654
+ return result;
655
+ }, {
656
+ pattern,
657
+ timeoutMs
658
+ });
659
+ return ok("tap", JSON.stringify(captured, null, 2), captured);
660
+ };
312
661
  function createBrowserActionRegistry() {
313
662
  const handlers = /* @__PURE__ */ new Map();
314
663
  handlers.set("open", navigateAction);
@@ -330,8 +679,35 @@ function createBrowserActionRegistry() {
330
679
  handlers.set("dialog", dialogAction);
331
680
  handlers.set("close", closeAction);
332
681
  handlers.set("wait", waitAction);
682
+ handlers.set("wait_for_navigation", waitForNavigationAction);
683
+ handlers.set("wait_for_timeout", waitForTimeoutAction);
684
+ handlers.set("wait_for_function", waitForFunctionAction);
685
+ handlers.set("wait_for_network_idle", waitForNetworkIdleAction);
333
686
  handlers.set("output", outputAction);
334
687
  handlers.set("assert", assertAction);
688
+ handlers.set("select", selectAction);
689
+ handlers.set("map", mapAction);
690
+ handlers.set("filter", filterAction);
691
+ handlers.set("sort", sortAction);
692
+ handlers.set("limit", limitAction);
693
+ handlers.set("fetch", fetchAction);
694
+ handlers.set("collect", collectAction);
695
+ handlers.set("tap", tapAction);
696
+ handlers.set("element_text", elementTextAction);
697
+ handlers.set("element_attribute", elementAttributeAction);
698
+ handlers.set("bounding_box", boundingBoxAction);
699
+ handlers.set("set_input_files", setInputFilesAction);
700
+ handlers.set("cookies", getCookiesAction);
701
+ handlers.set("get_cookies", getCookiesAction);
702
+ handlers.set("add_cookies", addCookiesAction);
703
+ handlers.set("clear_cookies", clearCookiesAction);
704
+ handlers.set("tabs", listTabsAction);
705
+ handlers.set("list_tabs", listTabsAction);
706
+ handlers.set("new_tab", newTabAction);
707
+ handlers.set("switch_tab", switchTabAction);
708
+ handlers.set("network_start", networkStartAction);
709
+ handlers.set("network_events", networkEventsAction);
710
+ handlers.set("network_stop", networkStopAction);
335
711
  return {
336
712
  get(name) {
337
713
  return handlers.get(name);