@farazirfan/costar-server-executor 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1067) hide show
  1. package/.env.example +53 -0
  2. package/README.md +313 -0
  3. package/costar.mjs +19 -0
  4. package/dist/agent/agent-old.d.ts +61 -0
  5. package/dist/agent/agent-old.d.ts.map +1 -0
  6. package/dist/agent/agent-old.js +282 -0
  7. package/dist/agent/agent-old.js.map +1 -0
  8. package/dist/agent/agent.d.ts +110 -0
  9. package/dist/agent/agent.d.ts.map +1 -0
  10. package/dist/agent/agent.js +349 -0
  11. package/dist/agent/agent.js.map +1 -0
  12. package/dist/agent/context-loader.d.ts +41 -0
  13. package/dist/agent/context-loader.d.ts.map +1 -0
  14. package/dist/agent/context-loader.js +166 -0
  15. package/dist/agent/context-loader.js.map +1 -0
  16. package/dist/agent/index.d.ts +13 -0
  17. package/dist/agent/index.d.ts.map +1 -0
  18. package/dist/agent/index.js +11 -0
  19. package/dist/agent/index.js.map +1 -0
  20. package/dist/agent/model-fallback.d.ts +48 -0
  21. package/dist/agent/model-fallback.d.ts.map +1 -0
  22. package/dist/agent/model-fallback.js +103 -0
  23. package/dist/agent/model-fallback.js.map +1 -0
  24. package/dist/agent/pi-embedded-runner/model.d.ts +31 -0
  25. package/dist/agent/pi-embedded-runner/model.d.ts.map +1 -0
  26. package/dist/agent/pi-embedded-runner/model.js +65 -0
  27. package/dist/agent/pi-embedded-runner/model.js.map +1 -0
  28. package/dist/agent/pi-embedded-runner/run.d.ts +10 -0
  29. package/dist/agent/pi-embedded-runner/run.d.ts.map +1 -0
  30. package/dist/agent/pi-embedded-runner/run.js +230 -0
  31. package/dist/agent/pi-embedded-runner/run.js.map +1 -0
  32. package/dist/agent/pi-embedded-runner/subscribe.d.ts +42 -0
  33. package/dist/agent/pi-embedded-runner/subscribe.d.ts.map +1 -0
  34. package/dist/agent/pi-embedded-runner/subscribe.js +237 -0
  35. package/dist/agent/pi-embedded-runner/subscribe.js.map +1 -0
  36. package/dist/agent/pi-embedded-runner/system-prompt.d.ts +52 -0
  37. package/dist/agent/pi-embedded-runner/system-prompt.d.ts.map +1 -0
  38. package/dist/agent/pi-embedded-runner/system-prompt.js +331 -0
  39. package/dist/agent/pi-embedded-runner/system-prompt.js.map +1 -0
  40. package/dist/agent/pi-embedded-runner/tools.d.ts +16 -0
  41. package/dist/agent/pi-embedded-runner/tools.d.ts.map +1 -0
  42. package/dist/agent/pi-embedded-runner/tools.js +52 -0
  43. package/dist/agent/pi-embedded-runner/tools.js.map +1 -0
  44. package/dist/agent/pi-embedded-runner/types.d.ts +176 -0
  45. package/dist/agent/pi-embedded-runner/types.d.ts.map +1 -0
  46. package/dist/agent/pi-embedded-runner/types.js +5 -0
  47. package/dist/agent/pi-embedded-runner/types.js.map +1 -0
  48. package/dist/agent/tool-executor.d.ts +44 -0
  49. package/dist/agent/tool-executor.d.ts.map +1 -0
  50. package/dist/agent/tool-executor.js +159 -0
  51. package/dist/agent/tool-executor.js.map +1 -0
  52. package/dist/api/chat.d.ts +22 -0
  53. package/dist/api/chat.d.ts.map +1 -0
  54. package/dist/api/chat.js +66 -0
  55. package/dist/api/chat.js.map +1 -0
  56. package/dist/browser/bridge-server.d.ts +18 -0
  57. package/dist/browser/bridge-server.d.ts.map +1 -0
  58. package/dist/browser/bridge-server.js +46 -0
  59. package/dist/browser/bridge-server.js.map +1 -0
  60. package/dist/browser/cdp.d.ts +124 -0
  61. package/dist/browser/cdp.d.ts.map +1 -0
  62. package/dist/browser/cdp.helpers.d.ts +10 -0
  63. package/dist/browser/cdp.helpers.d.ts.map +1 -0
  64. package/dist/browser/cdp.helpers.js +137 -0
  65. package/dist/browser/cdp.helpers.js.map +1 -0
  66. package/dist/browser/cdp.js +294 -0
  67. package/dist/browser/cdp.js.map +1 -0
  68. package/dist/browser/chrome.d.ts +21 -0
  69. package/dist/browser/chrome.d.ts.map +1 -0
  70. package/dist/browser/chrome.executables.d.ts +10 -0
  71. package/dist/browser/chrome.executables.d.ts.map +1 -0
  72. package/dist/browser/chrome.executables.js +510 -0
  73. package/dist/browser/chrome.executables.js.map +1 -0
  74. package/dist/browser/chrome.js +254 -0
  75. package/dist/browser/chrome.js.map +1 -0
  76. package/dist/browser/chrome.profile-decoration.d.ts +11 -0
  77. package/dist/browser/chrome.profile-decoration.d.ts.map +1 -0
  78. package/dist/browser/chrome.profile-decoration.js +145 -0
  79. package/dist/browser/chrome.profile-decoration.js.map +1 -0
  80. package/dist/browser/client-actions-core.d.ts +144 -0
  81. package/dist/browser/client-actions-core.d.ts.map +1 -0
  82. package/dist/browser/client-actions-core.js +101 -0
  83. package/dist/browser/client-actions-core.js.map +1 -0
  84. package/dist/browser/client-actions-observe.d.ts +69 -0
  85. package/dist/browser/client-actions-observe.d.ts.map +1 -0
  86. package/dist/browser/client-actions-observe.js +101 -0
  87. package/dist/browser/client-actions-observe.js.map +1 -0
  88. package/dist/browser/client-actions-state.d.ts +91 -0
  89. package/dist/browser/client-actions-state.d.ts.map +1 -0
  90. package/dist/browser/client-actions-state.js +170 -0
  91. package/dist/browser/client-actions-state.js.map +1 -0
  92. package/dist/browser/client-actions-types.d.ts +19 -0
  93. package/dist/browser/client-actions-types.d.ts.map +1 -0
  94. package/dist/browser/client-actions-types.js +2 -0
  95. package/dist/browser/client-actions-types.js.map +1 -0
  96. package/dist/browser/client-actions.d.ts +5 -0
  97. package/dist/browser/client-actions.d.ts.map +1 -0
  98. package/dist/browser/client-actions.js +5 -0
  99. package/dist/browser/client-actions.js.map +1 -0
  100. package/dist/browser/client-fetch.d.ts +4 -0
  101. package/dist/browser/client-fetch.d.ts.map +1 -0
  102. package/dist/browser/client-fetch.js +92 -0
  103. package/dist/browser/client-fetch.js.map +1 -0
  104. package/dist/browser/client.d.ts +148 -0
  105. package/dist/browser/client.d.ts.map +1 -0
  106. package/dist/browser/client.js +138 -0
  107. package/dist/browser/client.js.map +1 -0
  108. package/dist/browser/config.d.ts +40 -0
  109. package/dist/browser/config.d.ts.map +1 -0
  110. package/dist/browser/config.js +181 -0
  111. package/dist/browser/config.js.map +1 -0
  112. package/dist/browser/constants.d.ts +9 -0
  113. package/dist/browser/constants.d.ts.map +1 -0
  114. package/dist/browser/constants.js +9 -0
  115. package/dist/browser/constants.js.map +1 -0
  116. package/dist/browser/control-service.d.ts +6 -0
  117. package/dist/browser/control-service.d.ts.map +1 -0
  118. package/dist/browser/control-service.js +73 -0
  119. package/dist/browser/control-service.js.map +1 -0
  120. package/dist/browser/extension-relay.d.ts +15 -0
  121. package/dist/browser/extension-relay.d.ts.map +1 -0
  122. package/dist/browser/extension-relay.js +542 -0
  123. package/dist/browser/extension-relay.js.map +1 -0
  124. package/dist/browser/profiles-service.d.ts +26 -0
  125. package/dist/browser/profiles-service.d.ts.map +1 -0
  126. package/dist/browser/profiles-service.js +133 -0
  127. package/dist/browser/profiles-service.js.map +1 -0
  128. package/dist/browser/profiles.d.ts +31 -0
  129. package/dist/browser/profiles.d.ts.map +1 -0
  130. package/dist/browser/profiles.js +94 -0
  131. package/dist/browser/profiles.js.map +1 -0
  132. package/dist/browser/pw-ai-module.d.ts +7 -0
  133. package/dist/browser/pw-ai-module.d.ts.map +1 -0
  134. package/dist/browser/pw-ai-module.js +38 -0
  135. package/dist/browser/pw-ai-module.js.map +1 -0
  136. package/dist/browser/pw-ai.d.ts +3 -0
  137. package/dist/browser/pw-ai.d.ts.map +1 -0
  138. package/dist/browser/pw-ai.js +3 -0
  139. package/dist/browser/pw-ai.js.map +1 -0
  140. package/dist/browser/pw-role-snapshot.d.ts +36 -0
  141. package/dist/browser/pw-role-snapshot.d.ts.map +1 -0
  142. package/dist/browser/pw-role-snapshot.js +311 -0
  143. package/dist/browser/pw-role-snapshot.js.map +1 -0
  144. package/dist/browser/pw-session.d.ts +136 -0
  145. package/dist/browser/pw-session.d.ts.map +1 -0
  146. package/dist/browser/pw-session.js +432 -0
  147. package/dist/browser/pw-session.js.map +1 -0
  148. package/dist/browser/pw-tools-core.activity.d.ts +22 -0
  149. package/dist/browser/pw-tools-core.activity.d.ts.map +1 -0
  150. package/dist/browser/pw-tools-core.activity.js +45 -0
  151. package/dist/browser/pw-tools-core.activity.js.map +1 -0
  152. package/dist/browser/pw-tools-core.d.ts +9 -0
  153. package/dist/browser/pw-tools-core.d.ts.map +1 -0
  154. package/dist/browser/pw-tools-core.downloads.d.ts +35 -0
  155. package/dist/browser/pw-tools-core.downloads.d.ts.map +1 -0
  156. package/dist/browser/pw-tools-core.downloads.js +177 -0
  157. package/dist/browser/pw-tools-core.downloads.js.map +1 -0
  158. package/dist/browser/pw-tools-core.interactions.d.ts +113 -0
  159. package/dist/browser/pw-tools-core.interactions.d.ts.map +1 -0
  160. package/dist/browser/pw-tools-core.interactions.js +421 -0
  161. package/dist/browser/pw-tools-core.interactions.js.map +1 -0
  162. package/dist/browser/pw-tools-core.js +9 -0
  163. package/dist/browser/pw-tools-core.js.map +1 -0
  164. package/dist/browser/pw-tools-core.responses.d.ts +14 -0
  165. package/dist/browser/pw-tools-core.responses.d.ts.map +1 -0
  166. package/dist/browser/pw-tools-core.responses.js +84 -0
  167. package/dist/browser/pw-tools-core.responses.js.map +1 -0
  168. package/dist/browser/pw-tools-core.shared.d.ts +7 -0
  169. package/dist/browser/pw-tools-core.shared.d.ts.map +1 -0
  170. package/dist/browser/pw-tools-core.shared.js +49 -0
  171. package/dist/browser/pw-tools-core.shared.js.map +1 -0
  172. package/dist/browser/pw-tools-core.snapshot.d.ts +65 -0
  173. package/dist/browser/pw-tools-core.snapshot.d.ts.map +1 -0
  174. package/dist/browser/pw-tools-core.snapshot.js +143 -0
  175. package/dist/browser/pw-tools-core.snapshot.js.map +1 -0
  176. package/dist/browser/pw-tools-core.state.d.ts +47 -0
  177. package/dist/browser/pw-tools-core.state.d.ts.map +1 -0
  178. package/dist/browser/pw-tools-core.state.js +148 -0
  179. package/dist/browser/pw-tools-core.state.js.map +1 -0
  180. package/dist/browser/pw-tools-core.storage.d.ts +48 -0
  181. package/dist/browser/pw-tools-core.storage.d.ts.map +1 -0
  182. package/dist/browser/pw-tools-core.storage.js +73 -0
  183. package/dist/browser/pw-tools-core.storage.js.map +1 -0
  184. package/dist/browser/pw-tools-core.trace.d.ts +13 -0
  185. package/dist/browser/pw-tools-core.trace.d.ts.map +1 -0
  186. package/dist/browser/pw-tools-core.trace.js +26 -0
  187. package/dist/browser/pw-tools-core.trace.js.map +1 -0
  188. package/dist/browser/routes/agent.act.d.ts +4 -0
  189. package/dist/browser/routes/agent.act.d.ts.map +1 -0
  190. package/dist/browser/routes/agent.act.js +467 -0
  191. package/dist/browser/routes/agent.act.js.map +1 -0
  192. package/dist/browser/routes/agent.act.shared.d.ts +11 -0
  193. package/dist/browser/routes/agent.act.shared.d.ts.map +1 -0
  194. package/dist/browser/routes/agent.act.shared.js +39 -0
  195. package/dist/browser/routes/agent.act.shared.js.map +1 -0
  196. package/dist/browser/routes/agent.d.ts +4 -0
  197. package/dist/browser/routes/agent.d.ts.map +1 -0
  198. package/dist/browser/routes/agent.debug.d.ts +4 -0
  199. package/dist/browser/routes/agent.debug.d.ts.map +1 -0
  200. package/dist/browser/routes/agent.debug.js +134 -0
  201. package/dist/browser/routes/agent.debug.js.map +1 -0
  202. package/dist/browser/routes/agent.js +11 -0
  203. package/dist/browser/routes/agent.js.map +1 -0
  204. package/dist/browser/routes/agent.shared.d.ts +10 -0
  205. package/dist/browser/routes/agent.shared.d.ts.map +1 -0
  206. package/dist/browser/routes/agent.shared.js +46 -0
  207. package/dist/browser/routes/agent.shared.js.map +1 -0
  208. package/dist/browser/routes/agent.snapshot.d.ts +4 -0
  209. package/dist/browser/routes/agent.snapshot.d.ts.map +1 -0
  210. package/dist/browser/routes/agent.snapshot.js +270 -0
  211. package/dist/browser/routes/agent.snapshot.js.map +1 -0
  212. package/dist/browser/routes/agent.storage.d.ts +4 -0
  213. package/dist/browser/routes/agent.storage.d.ts.map +1 -0
  214. package/dist/browser/routes/agent.storage.js +387 -0
  215. package/dist/browser/routes/agent.storage.js.map +1 -0
  216. package/dist/browser/routes/basic.d.ts +4 -0
  217. package/dist/browser/routes/basic.d.ts.map +1 -0
  218. package/dist/browser/routes/basic.js +174 -0
  219. package/dist/browser/routes/basic.js.map +1 -0
  220. package/dist/browser/routes/dispatcher.d.ts +16 -0
  221. package/dist/browser/routes/dispatcher.d.ts.map +1 -0
  222. package/dist/browser/routes/dispatcher.js +87 -0
  223. package/dist/browser/routes/dispatcher.js.map +1 -0
  224. package/dist/browser/routes/index.d.ts +4 -0
  225. package/dist/browser/routes/index.d.ts.map +1 -0
  226. package/dist/browser/routes/index.js +9 -0
  227. package/dist/browser/routes/index.js.map +1 -0
  228. package/dist/browser/routes/tabs.d.ts +4 -0
  229. package/dist/browser/routes/tabs.d.ts.map +1 -0
  230. package/dist/browser/routes/tabs.js +121 -0
  231. package/dist/browser/routes/tabs.js.map +1 -0
  232. package/dist/browser/routes/types.d.ts +16 -0
  233. package/dist/browser/routes/types.d.ts.map +1 -0
  234. package/dist/browser/routes/types.js +2 -0
  235. package/dist/browser/routes/types.js.map +1 -0
  236. package/dist/browser/routes/utils.d.ts +16 -0
  237. package/dist/browser/routes/utils.d.ts.map +1 -0
  238. package/dist/browser/routes/utils.js +58 -0
  239. package/dist/browser/routes/utils.js.map +1 -0
  240. package/dist/browser/screenshot.d.ts +10 -0
  241. package/dist/browser/screenshot.d.ts.map +1 -0
  242. package/dist/browser/screenshot.js +40 -0
  243. package/dist/browser/screenshot.js.map +1 -0
  244. package/dist/browser/server-context.d.ts +4 -0
  245. package/dist/browser/server-context.d.ts.map +1 -0
  246. package/dist/browser/server-context.js +534 -0
  247. package/dist/browser/server-context.js.map +1 -0
  248. package/dist/browser/server-context.types.d.ts +79 -0
  249. package/dist/browser/server-context.types.d.ts.map +1 -0
  250. package/dist/browser/server-context.types.js +2 -0
  251. package/dist/browser/server-context.types.js.map +1 -0
  252. package/dist/browser/server.d.ts +4 -0
  253. package/dist/browser/server.d.ts.map +1 -0
  254. package/dist/browser/server.js +91 -0
  255. package/dist/browser/server.js.map +1 -0
  256. package/dist/browser/target-id.d.ts +12 -0
  257. package/dist/browser/target-id.d.ts.map +1 -0
  258. package/dist/browser/target-id.js +17 -0
  259. package/dist/browser/target-id.js.map +1 -0
  260. package/dist/browser/trash.d.ts +2 -0
  261. package/dist/browser/trash.d.ts.map +1 -0
  262. package/dist/browser/trash.js +22 -0
  263. package/dist/browser/trash.js.map +1 -0
  264. package/dist/chat-server.d.ts +2 -0
  265. package/dist/chat-server.d.ts.map +1 -0
  266. package/dist/chat-server.js +91 -0
  267. package/dist/chat-server.js.map +1 -0
  268. package/dist/cli/command-format.d.ts +2 -0
  269. package/dist/cli/command-format.d.ts.map +1 -0
  270. package/dist/cli/command-format.js +19 -0
  271. package/dist/cli/command-format.js.map +1 -0
  272. package/dist/cli/config-cmd.d.ts +6 -0
  273. package/dist/cli/config-cmd.d.ts.map +1 -0
  274. package/dist/cli/config-cmd.js +52 -0
  275. package/dist/cli/config-cmd.js.map +1 -0
  276. package/dist/cli/doctor.d.ts +6 -0
  277. package/dist/cli/doctor.d.ts.map +1 -0
  278. package/dist/cli/doctor.js +198 -0
  279. package/dist/cli/doctor.js.map +1 -0
  280. package/dist/cli/env-loader.d.ts +23 -0
  281. package/dist/cli/env-loader.d.ts.map +1 -0
  282. package/dist/cli/env-loader.js +104 -0
  283. package/dist/cli/env-loader.js.map +1 -0
  284. package/dist/cli/paths.d.ts +22 -0
  285. package/dist/cli/paths.d.ts.map +1 -0
  286. package/dist/cli/paths.js +38 -0
  287. package/dist/cli/paths.js.map +1 -0
  288. package/dist/cli/service.d.ts +11 -0
  289. package/dist/cli/service.d.ts.map +1 -0
  290. package/dist/cli/service.js +481 -0
  291. package/dist/cli/service.js.map +1 -0
  292. package/dist/cli/setup.d.ts +16 -0
  293. package/dist/cli/setup.d.ts.map +1 -0
  294. package/dist/cli/setup.js +317 -0
  295. package/dist/cli/setup.js.map +1 -0
  296. package/dist/cli/skill-cmd.d.ts +12 -0
  297. package/dist/cli/skill-cmd.d.ts.map +1 -0
  298. package/dist/cli/skill-cmd.js +297 -0
  299. package/dist/cli/skill-cmd.js.map +1 -0
  300. package/dist/cli/status.d.ts +6 -0
  301. package/dist/cli/status.d.ts.map +1 -0
  302. package/dist/cli/status.js +81 -0
  303. package/dist/cli/status.js.map +1 -0
  304. package/dist/cli.d.ts +18 -0
  305. package/dist/cli.d.ts.map +1 -0
  306. package/dist/cli.js +157 -0
  307. package/dist/cli.js.map +1 -0
  308. package/dist/config/config.d.ts +16 -0
  309. package/dist/config/config.d.ts.map +1 -0
  310. package/dist/config/config.js +64 -0
  311. package/dist/config/config.js.map +1 -0
  312. package/dist/config/paths.d.ts +58 -0
  313. package/dist/config/paths.d.ts.map +1 -0
  314. package/dist/config/paths.js +195 -0
  315. package/dist/config/paths.js.map +1 -0
  316. package/dist/config/port-defaults.d.ts +14 -0
  317. package/dist/config/port-defaults.d.ts.map +1 -0
  318. package/dist/config/port-defaults.js +31 -0
  319. package/dist/config/port-defaults.js.map +1 -0
  320. package/dist/config/types.d.ts +86 -0
  321. package/dist/config/types.d.ts.map +1 -0
  322. package/dist/config/types.js +5 -0
  323. package/dist/config/types.js.map +1 -0
  324. package/dist/cron/index.d.ts +7 -0
  325. package/dist/cron/index.d.ts.map +1 -0
  326. package/dist/cron/index.js +6 -0
  327. package/dist/cron/index.js.map +1 -0
  328. package/dist/cron/job-executor.d.ts +14 -0
  329. package/dist/cron/job-executor.d.ts.map +1 -0
  330. package/dist/cron/job-executor.js +106 -0
  331. package/dist/cron/job-executor.js.map +1 -0
  332. package/dist/cron/scheduler.d.ts +64 -0
  333. package/dist/cron/scheduler.d.ts.map +1 -0
  334. package/dist/cron/scheduler.js +220 -0
  335. package/dist/cron/scheduler.js.map +1 -0
  336. package/dist/cron/types.d.ts +75 -0
  337. package/dist/cron/types.d.ts.map +1 -0
  338. package/dist/cron/types.js +6 -0
  339. package/dist/cron/types.js.map +1 -0
  340. package/dist/heartbeat/index.d.ts +6 -0
  341. package/dist/heartbeat/index.d.ts.map +1 -0
  342. package/dist/heartbeat/index.js +5 -0
  343. package/dist/heartbeat/index.js.map +1 -0
  344. package/dist/heartbeat/runner.d.ts +94 -0
  345. package/dist/heartbeat/runner.d.ts.map +1 -0
  346. package/dist/heartbeat/runner.js +528 -0
  347. package/dist/heartbeat/runner.js.map +1 -0
  348. package/dist/heartbeat/types.d.ts +30 -0
  349. package/dist/heartbeat/types.d.ts.map +1 -0
  350. package/dist/heartbeat/types.js +5 -0
  351. package/dist/heartbeat/types.js.map +1 -0
  352. package/dist/index.d.ts +27 -0
  353. package/dist/index.d.ts.map +1 -0
  354. package/dist/index.js +183 -0
  355. package/dist/index.js.map +1 -0
  356. package/dist/infra/agent-events.d.ts +22 -0
  357. package/dist/infra/agent-events.d.ts.map +1 -0
  358. package/dist/infra/agent-events.js +58 -0
  359. package/dist/infra/agent-events.js.map +1 -0
  360. package/dist/infra/archive.d.ts +17 -0
  361. package/dist/infra/archive.d.ts.map +1 -0
  362. package/dist/infra/archive.js +98 -0
  363. package/dist/infra/archive.js.map +1 -0
  364. package/dist/infra/backoff.d.ts +9 -0
  365. package/dist/infra/backoff.d.ts.map +1 -0
  366. package/dist/infra/backoff.js +20 -0
  367. package/dist/infra/backoff.js.map +1 -0
  368. package/dist/infra/binaries.d.ts +4 -0
  369. package/dist/infra/binaries.d.ts.map +1 -0
  370. package/dist/infra/binaries.js +10 -0
  371. package/dist/infra/binaries.js.map +1 -0
  372. package/dist/infra/bonjour-ciao.d.ts +2 -0
  373. package/dist/infra/bonjour-ciao.d.ts.map +1 -0
  374. package/dist/infra/bonjour-ciao.js +11 -0
  375. package/dist/infra/bonjour-ciao.js.map +1 -0
  376. package/dist/infra/bonjour-discovery.d.ts +27 -0
  377. package/dist/infra/bonjour-discovery.d.ts.map +1 -0
  378. package/dist/infra/bonjour-discovery.js +450 -0
  379. package/dist/infra/bonjour-discovery.js.map +1 -0
  380. package/dist/infra/bonjour-errors.d.ts +2 -0
  381. package/dist/infra/bonjour-errors.d.ts.map +1 -0
  382. package/dist/infra/bonjour-errors.js +8 -0
  383. package/dist/infra/bonjour-errors.js.map +1 -0
  384. package/dist/infra/bonjour.d.ts +20 -0
  385. package/dist/infra/bonjour.d.ts.map +1 -0
  386. package/dist/infra/bonjour.js +211 -0
  387. package/dist/infra/bonjour.js.map +1 -0
  388. package/dist/infra/brew.d.ts +9 -0
  389. package/dist/infra/brew.d.ts.map +1 -0
  390. package/dist/infra/brew.js +56 -0
  391. package/dist/infra/brew.js.map +1 -0
  392. package/dist/infra/canvas-host-url.d.ts +12 -0
  393. package/dist/infra/canvas-host-url.d.ts.map +1 -0
  394. package/dist/infra/canvas-host-url.js +53 -0
  395. package/dist/infra/canvas-host-url.js.map +1 -0
  396. package/dist/infra/channel-activity.d.ts +19 -0
  397. package/dist/infra/channel-activity.d.ts.map +1 -0
  398. package/dist/infra/channel-activity.js +33 -0
  399. package/dist/infra/channel-activity.js.map +1 -0
  400. package/dist/infra/channel-summary.d.ts +8 -0
  401. package/dist/infra/channel-summary.d.ts.map +1 -0
  402. package/dist/infra/channel-summary.js +184 -0
  403. package/dist/infra/channel-summary.js.map +1 -0
  404. package/dist/infra/channels-status-issues.d.ts +3 -0
  405. package/dist/infra/channels-status-issues.d.ts.map +1 -0
  406. package/dist/infra/channels-status-issues.js +16 -0
  407. package/dist/infra/channels-status-issues.js.map +1 -0
  408. package/dist/infra/clipboard.d.ts +2 -0
  409. package/dist/infra/clipboard.d.ts.map +1 -0
  410. package/dist/infra/clipboard.js +25 -0
  411. package/dist/infra/clipboard.js.map +1 -0
  412. package/dist/infra/control-ui-assets.d.ts +12 -0
  413. package/dist/infra/control-ui-assets.d.ts.map +1 -0
  414. package/dist/infra/control-ui-assets.js +99 -0
  415. package/dist/infra/control-ui-assets.js.map +1 -0
  416. package/dist/infra/dedupe.d.ts +12 -0
  417. package/dist/infra/dedupe.d.ts.map +1 -0
  418. package/dist/infra/dedupe.js +48 -0
  419. package/dist/infra/dedupe.js.map +1 -0
  420. package/dist/infra/device-auth-store.d.ts +24 -0
  421. package/dist/infra/device-auth-store.d.ts.map +1 -0
  422. package/dist/infra/device-auth-store.js +98 -0
  423. package/dist/infra/device-auth-store.js.map +1 -0
  424. package/dist/infra/device-identity.d.ts +12 -0
  425. package/dist/infra/device-identity.d.ts.map +1 -0
  426. package/dist/infra/device-identity.js +150 -0
  427. package/dist/infra/device-identity.js.map +1 -0
  428. package/dist/infra/device-pairing.d.ts +97 -0
  429. package/dist/infra/device-pairing.d.ts.map +1 -0
  430. package/dist/infra/device-pairing.js +402 -0
  431. package/dist/infra/device-pairing.js.map +1 -0
  432. package/dist/infra/diagnostic-events.d.ts +122 -0
  433. package/dist/infra/diagnostic-events.d.ts.map +1 -0
  434. package/dist/infra/diagnostic-events.js +29 -0
  435. package/dist/infra/diagnostic-events.js.map +1 -0
  436. package/dist/infra/diagnostic-flags.d.ts +5 -0
  437. package/dist/infra/diagnostic-flags.d.ts.map +1 -0
  438. package/dist/infra/diagnostic-flags.js +67 -0
  439. package/dist/infra/diagnostic-flags.js.map +1 -0
  440. package/dist/infra/dotenv.d.ts +4 -0
  441. package/dist/infra/dotenv.d.ts.map +1 -0
  442. package/dist/infra/dotenv.js +16 -0
  443. package/dist/infra/dotenv.js.map +1 -0
  444. package/dist/infra/env-file.d.ts +10 -0
  445. package/dist/infra/env-file.d.ts.map +1 -0
  446. package/dist/infra/env-file.js +44 -0
  447. package/dist/infra/env-file.js.map +1 -0
  448. package/dist/infra/env.d.ts +12 -0
  449. package/dist/infra/env.d.ts.map +1 -0
  450. package/dist/infra/env.js +35 -0
  451. package/dist/infra/env.js.map +1 -0
  452. package/dist/infra/errors.d.ts +4 -0
  453. package/dist/infra/errors.d.ts.map +1 -0
  454. package/dist/infra/errors.js +36 -0
  455. package/dist/infra/errors.js.map +1 -0
  456. package/dist/infra/exec-approval-forwarder.d.ts +45 -0
  457. package/dist/infra/exec-approval-forwarder.d.ts.map +1 -0
  458. package/dist/infra/exec-approval-forwarder.js +213 -0
  459. package/dist/infra/exec-approval-forwarder.js.map +1 -0
  460. package/dist/infra/exec-approvals.d.ts +154 -0
  461. package/dist/infra/exec-approvals.d.ts.map +1 -0
  462. package/dist/infra/exec-approvals.js +1041 -0
  463. package/dist/infra/exec-approvals.js.map +1 -0
  464. package/dist/infra/exec-host.d.ts +38 -0
  465. package/dist/infra/exec-host.d.ts.map +1 -0
  466. package/dist/infra/exec-host.js +76 -0
  467. package/dist/infra/exec-host.js.map +1 -0
  468. package/dist/infra/exec-safety.d.ts +2 -0
  469. package/dist/infra/exec-safety.d.ts.map +1 -0
  470. package/dist/infra/exec-safety.js +32 -0
  471. package/dist/infra/exec-safety.js.map +1 -0
  472. package/dist/infra/fetch.d.ts +3 -0
  473. package/dist/infra/fetch.d.ts.map +1 -0
  474. package/dist/infra/fetch.js +59 -0
  475. package/dist/infra/fetch.js.map +1 -0
  476. package/dist/infra/format-duration.d.ts +11 -0
  477. package/dist/infra/format-duration.d.ts.map +1 -0
  478. package/dist/infra/format-duration.js +21 -0
  479. package/dist/infra/format-duration.js.map +1 -0
  480. package/dist/infra/fs-safe.d.ts +17 -0
  481. package/dist/infra/fs-safe.d.ts.map +1 -0
  482. package/dist/infra/fs-safe.js +77 -0
  483. package/dist/infra/fs-safe.js.map +1 -0
  484. package/dist/infra/gateway-lock.d.ts +19 -0
  485. package/dist/infra/gateway-lock.d.ts.map +1 -0
  486. package/dist/infra/gateway-lock.js +204 -0
  487. package/dist/infra/gateway-lock.js.map +1 -0
  488. package/dist/infra/git-commit.d.ts +5 -0
  489. package/dist/infra/git-commit.d.ts.map +1 -0
  490. package/dist/infra/git-commit.js +107 -0
  491. package/dist/infra/git-commit.js.map +1 -0
  492. package/dist/infra/heartbeat-events.d.ts +21 -0
  493. package/dist/infra/heartbeat-events.d.ts.map +1 -0
  494. package/dist/infra/heartbeat-events.js +35 -0
  495. package/dist/infra/heartbeat-events.js.map +1 -0
  496. package/dist/infra/heartbeat-runner.d.ts +45 -0
  497. package/dist/infra/heartbeat-runner.d.ts.map +1 -0
  498. package/dist/infra/heartbeat-runner.js +745 -0
  499. package/dist/infra/heartbeat-runner.js.map +1 -0
  500. package/dist/infra/heartbeat-visibility.d.ts +18 -0
  501. package/dist/infra/heartbeat-visibility.d.ts.map +1 -0
  502. package/dist/infra/heartbeat-visibility.js +46 -0
  503. package/dist/infra/heartbeat-visibility.js.map +1 -0
  504. package/dist/infra/heartbeat-wake.d.ts +21 -0
  505. package/dist/infra/heartbeat-wake.d.ts.map +1 -0
  506. package/dist/infra/heartbeat-wake.js +62 -0
  507. package/dist/infra/heartbeat-wake.js.map +1 -0
  508. package/dist/infra/is-main.d.ts +9 -0
  509. package/dist/infra/is-main.d.ts.map +1 -0
  510. package/dist/infra/is-main.js +34 -0
  511. package/dist/infra/is-main.js.map +1 -0
  512. package/dist/infra/json-file.d.ts +3 -0
  513. package/dist/infra/json-file.d.ts.map +1 -0
  514. package/dist/infra/json-file.js +22 -0
  515. package/dist/infra/json-file.js.map +1 -0
  516. package/dist/infra/machine-name.d.ts +2 -0
  517. package/dist/infra/machine-name.d.ts.map +1 -0
  518. package/dist/infra/machine-name.js +44 -0
  519. package/dist/infra/machine-name.js.map +1 -0
  520. package/dist/infra/node-pairing.d.ts +63 -0
  521. package/dist/infra/node-pairing.d.ts.map +1 -0
  522. package/dist/infra/node-pairing.js +229 -0
  523. package/dist/infra/node-pairing.js.map +1 -0
  524. package/dist/infra/node-shell.d.ts +2 -0
  525. package/dist/infra/node-shell.d.ts.map +1 -0
  526. package/dist/infra/node-shell.js +10 -0
  527. package/dist/infra/node-shell.js.map +1 -0
  528. package/dist/infra/openclaw-root.d.ts +6 -0
  529. package/dist/infra/openclaw-root.d.ts.map +1 -0
  530. package/dist/infra/openclaw-root.js +58 -0
  531. package/dist/infra/openclaw-root.js.map +1 -0
  532. package/dist/infra/os-summary.d.ts +8 -0
  533. package/dist/infra/os-summary.d.ts.map +1 -0
  534. package/dist/infra/os-summary.js +24 -0
  535. package/dist/infra/os-summary.js.map +1 -0
  536. package/dist/infra/path-env.d.ts +14 -0
  537. package/dist/infra/path-env.d.ts.map +1 -0
  538. package/dist/infra/path-env.js +95 -0
  539. package/dist/infra/path-env.js.map +1 -0
  540. package/dist/infra/ports-format.d.ts +6 -0
  541. package/dist/infra/ports-format.d.ts.map +1 -0
  542. package/dist/infra/ports-format.js +55 -0
  543. package/dist/infra/ports-format.js.map +1 -0
  544. package/dist/infra/ports-inspect.d.ts +3 -0
  545. package/dist/infra/ports-inspect.d.ts.map +1 -0
  546. package/dist/infra/ports-inspect.js +241 -0
  547. package/dist/infra/ports-inspect.js.map +1 -0
  548. package/dist/infra/ports-lsof.d.ts +3 -0
  549. package/dist/infra/ports-lsof.d.ts.map +1 -0
  550. package/dist/infra/ports-lsof.js +34 -0
  551. package/dist/infra/ports-lsof.js.map +1 -0
  552. package/dist/infra/ports-types.d.ts +18 -0
  553. package/dist/infra/ports-types.d.ts.map +1 -0
  554. package/dist/infra/ports-types.js +2 -0
  555. package/dist/infra/ports-types.js.map +1 -0
  556. package/dist/infra/ports.d.ts +15 -0
  557. package/dist/infra/ports.d.ts.map +1 -0
  558. package/dist/infra/ports.js +76 -0
  559. package/dist/infra/ports.js.map +1 -0
  560. package/dist/infra/provider-usage.auth.d.ts +12 -0
  561. package/dist/infra/provider-usage.auth.d.ts.map +1 -0
  562. package/dist/infra/provider-usage.auth.js +222 -0
  563. package/dist/infra/provider-usage.auth.js.map +1 -0
  564. package/dist/infra/provider-usage.d.ts +5 -0
  565. package/dist/infra/provider-usage.d.ts.map +1 -0
  566. package/dist/infra/provider-usage.fetch.antigravity.d.ts +3 -0
  567. package/dist/infra/provider-usage.fetch.antigravity.d.ts.map +1 -0
  568. package/dist/infra/provider-usage.fetch.antigravity.js +213 -0
  569. package/dist/infra/provider-usage.fetch.antigravity.js.map +1 -0
  570. package/dist/infra/provider-usage.fetch.claude.d.ts +3 -0
  571. package/dist/infra/provider-usage.fetch.claude.d.ts.map +1 -0
  572. package/dist/infra/provider-usage.fetch.claude.js +130 -0
  573. package/dist/infra/provider-usage.fetch.claude.js.map +1 -0
  574. package/dist/infra/provider-usage.fetch.codex.d.ts +3 -0
  575. package/dist/infra/provider-usage.fetch.codex.d.ts.map +1 -0
  576. package/dist/infra/provider-usage.fetch.codex.js +63 -0
  577. package/dist/infra/provider-usage.fetch.codex.js.map +1 -0
  578. package/dist/infra/provider-usage.fetch.copilot.d.ts +3 -0
  579. package/dist/infra/provider-usage.fetch.copilot.d.ts.map +1 -0
  580. package/dist/infra/provider-usage.fetch.copilot.js +43 -0
  581. package/dist/infra/provider-usage.fetch.copilot.js.map +1 -0
  582. package/dist/infra/provider-usage.fetch.d.ts +8 -0
  583. package/dist/infra/provider-usage.fetch.d.ts.map +1 -0
  584. package/dist/infra/provider-usage.fetch.gemini.d.ts +3 -0
  585. package/dist/infra/provider-usage.fetch.gemini.d.ts.map +1 -0
  586. package/dist/infra/provider-usage.fetch.gemini.js +58 -0
  587. package/dist/infra/provider-usage.fetch.gemini.js.map +1 -0
  588. package/dist/infra/provider-usage.fetch.js +8 -0
  589. package/dist/infra/provider-usage.fetch.js.map +1 -0
  590. package/dist/infra/provider-usage.fetch.minimax.d.ts +3 -0
  591. package/dist/infra/provider-usage.fetch.minimax.d.ts.map +1 -0
  592. package/dist/infra/provider-usage.fetch.minimax.js +333 -0
  593. package/dist/infra/provider-usage.fetch.minimax.js.map +1 -0
  594. package/dist/infra/provider-usage.fetch.shared.d.ts +2 -0
  595. package/dist/infra/provider-usage.fetch.shared.d.ts.map +1 -0
  596. package/dist/infra/provider-usage.fetch.shared.js +11 -0
  597. package/dist/infra/provider-usage.fetch.shared.js.map +1 -0
  598. package/dist/infra/provider-usage.fetch.zai.d.ts +3 -0
  599. package/dist/infra/provider-usage.fetch.zai.d.ts.map +1 -0
  600. package/dist/infra/provider-usage.fetch.zai.js +63 -0
  601. package/dist/infra/provider-usage.fetch.zai.js.map +1 -0
  602. package/dist/infra/provider-usage.format.d.ts +14 -0
  603. package/dist/infra/provider-usage.format.d.ts.map +1 -0
  604. package/dist/infra/provider-usage.format.js +97 -0
  605. package/dist/infra/provider-usage.format.js.map +1 -0
  606. package/dist/infra/provider-usage.js +4 -0
  607. package/dist/infra/provider-usage.js.map +1 -0
  608. package/dist/infra/provider-usage.load.d.ts +13 -0
  609. package/dist/infra/provider-usage.load.d.ts.map +1 -0
  610. package/dist/infra/provider-usage.load.js +66 -0
  611. package/dist/infra/provider-usage.load.js.map +1 -0
  612. package/dist/infra/provider-usage.shared.d.ts +9 -0
  613. package/dist/infra/provider-usage.shared.d.ts.map +1 -0
  614. package/dist/infra/provider-usage.shared.js +54 -0
  615. package/dist/infra/provider-usage.shared.js.map +1 -0
  616. package/dist/infra/provider-usage.types.d.ts +18 -0
  617. package/dist/infra/provider-usage.types.d.ts.map +1 -0
  618. package/dist/infra/provider-usage.types.js +2 -0
  619. package/dist/infra/provider-usage.types.js.map +1 -0
  620. package/dist/infra/restart-sentinel.d.ts +51 -0
  621. package/dist/infra/restart-sentinel.d.ts.map +1 -0
  622. package/dist/infra/restart-sentinel.js +66 -0
  623. package/dist/infra/restart-sentinel.js.map +1 -0
  624. package/dist/infra/restart.d.ts +29 -0
  625. package/dist/infra/restart.d.ts.map +1 -0
  626. package/dist/infra/restart.js +172 -0
  627. package/dist/infra/restart.js.map +1 -0
  628. package/dist/infra/retry-policy.d.ts +26 -0
  629. package/dist/infra/retry-policy.d.ts.map +1 -0
  630. package/dist/infra/retry-policy.js +72 -0
  631. package/dist/infra/retry-policy.js.map +1 -0
  632. package/dist/infra/retry.d.ts +22 -0
  633. package/dist/infra/retry.d.ts.map +1 -0
  634. package/dist/infra/retry.js +86 -0
  635. package/dist/infra/retry.js.map +1 -0
  636. package/dist/infra/runtime-guard.d.ts +21 -0
  637. package/dist/infra/runtime-guard.d.ts.map +1 -0
  638. package/dist/infra/runtime-guard.js +61 -0
  639. package/dist/infra/runtime-guard.js.map +1 -0
  640. package/dist/infra/session-cost-usage.d.ts +37 -0
  641. package/dist/infra/session-cost-usage.d.ts.map +1 -0
  642. package/dist/infra/session-cost-usage.js +191 -0
  643. package/dist/infra/session-cost-usage.js.map +1 -0
  644. package/dist/infra/shell-env.d.ts +34 -0
  645. package/dist/infra/shell-env.d.ts.map +1 -0
  646. package/dist/infra/shell-env.js +126 -0
  647. package/dist/infra/shell-env.js.map +1 -0
  648. package/dist/infra/skills-remote.d.ts +25 -0
  649. package/dist/infra/skills-remote.d.ts.map +1 -0
  650. package/dist/infra/skills-remote.js +283 -0
  651. package/dist/infra/skills-remote.js.map +1 -0
  652. package/dist/infra/ssh-config.d.ts +13 -0
  653. package/dist/infra/ssh-config.d.ts.map +1 -0
  654. package/dist/infra/ssh-config.js +85 -0
  655. package/dist/infra/ssh-config.js.map +1 -0
  656. package/dist/infra/ssh-tunnel.d.ts +22 -0
  657. package/dist/infra/ssh-tunnel.d.ts.map +1 -0
  658. package/dist/infra/ssh-tunnel.js +174 -0
  659. package/dist/infra/ssh-tunnel.js.map +1 -0
  660. package/dist/infra/state-migrations.d.ts +88 -0
  661. package/dist/infra/state-migrations.d.ts.map +1 -0
  662. package/dist/infra/state-migrations.fs.d.ts +15 -0
  663. package/dist/infra/state-migrations.fs.d.ts.map +1 -0
  664. package/dist/infra/state-migrations.fs.js +50 -0
  665. package/dist/infra/state-migrations.fs.js.map +1 -0
  666. package/dist/infra/state-migrations.js +658 -0
  667. package/dist/infra/state-migrations.js.map +1 -0
  668. package/dist/infra/system-events.d.ts +17 -0
  669. package/dist/infra/system-events.d.ts.map +1 -0
  670. package/dist/infra/system-events.js +76 -0
  671. package/dist/infra/system-events.js.map +1 -0
  672. package/dist/infra/system-presence.d.ts +46 -0
  673. package/dist/infra/system-presence.d.ts.map +1 -0
  674. package/dist/infra/system-presence.js +232 -0
  675. package/dist/infra/system-presence.js.map +1 -0
  676. package/dist/infra/tailnet.d.ts +8 -0
  677. package/dist/infra/tailnet.d.ts.map +1 -0
  678. package/dist/infra/tailnet.js +47 -0
  679. package/dist/infra/tailnet.js.map +1 -0
  680. package/dist/infra/tailscale.d.ts +35 -0
  681. package/dist/infra/tailscale.d.ts.map +1 -0
  682. package/dist/infra/tailscale.js +369 -0
  683. package/dist/infra/tailscale.js.map +1 -0
  684. package/dist/infra/transport-ready.d.ts +17 -0
  685. package/dist/infra/transport-ready.d.ts.map +1 -0
  686. package/dist/infra/transport-ready.js +39 -0
  687. package/dist/infra/transport-ready.js.map +1 -0
  688. package/dist/infra/unhandled-rejections.d.ts +16 -0
  689. package/dist/infra/unhandled-rejections.d.ts.map +1 -0
  690. package/dist/infra/unhandled-rejections.js +140 -0
  691. package/dist/infra/unhandled-rejections.js.map +1 -0
  692. package/dist/infra/update-channels.d.ts +27 -0
  693. package/dist/infra/update-channels.d.ts.map +1 -0
  694. package/dist/infra/update-channels.js +58 -0
  695. package/dist/infra/update-channels.js.map +1 -0
  696. package/dist/infra/update-check.d.ts +69 -0
  697. package/dist/infra/update-check.d.ts.map +1 -0
  698. package/dist/infra/update-check.js +294 -0
  699. package/dist/infra/update-check.js.map +1 -0
  700. package/dist/infra/update-global.d.ts +16 -0
  701. package/dist/infra/update-global.d.ts.map +1 -0
  702. package/dist/infra/update-global.js +96 -0
  703. package/dist/infra/update-global.js.map +1 -0
  704. package/dist/infra/update-runner.d.ts +59 -0
  705. package/dist/infra/update-runner.d.ts.map +1 -0
  706. package/dist/infra/update-runner.js +578 -0
  707. package/dist/infra/update-runner.js.map +1 -0
  708. package/dist/infra/update-startup.d.ts +17 -0
  709. package/dist/infra/update-startup.d.ts.map +1 -0
  710. package/dist/infra/update-startup.js +87 -0
  711. package/dist/infra/update-startup.js.map +1 -0
  712. package/dist/infra/voicewake.d.ts +8 -0
  713. package/dist/infra/voicewake.d.ts.map +1 -0
  714. package/dist/infra/voicewake.js +75 -0
  715. package/dist/infra/voicewake.js.map +1 -0
  716. package/dist/infra/warnings.d.ts +2 -0
  717. package/dist/infra/warnings.d.ts.map +1 -0
  718. package/dist/infra/warnings.js +26 -0
  719. package/dist/infra/warnings.js.map +1 -0
  720. package/dist/infra/widearea-dns.d.ts +28 -0
  721. package/dist/infra/widearea-dns.d.ts.map +1 -0
  722. package/dist/infra/widearea-dns.js +149 -0
  723. package/dist/infra/widearea-dns.js.map +1 -0
  724. package/dist/infra/ws.d.ts +3 -0
  725. package/dist/infra/ws.d.ts.map +1 -0
  726. package/dist/infra/ws.js +14 -0
  727. package/dist/infra/ws.js.map +1 -0
  728. package/dist/infra/wsl.d.ts +3 -0
  729. package/dist/infra/wsl.d.ts.map +1 -0
  730. package/dist/infra/wsl.js +26 -0
  731. package/dist/infra/wsl.js.map +1 -0
  732. package/dist/logging/config.d.ts +5 -0
  733. package/dist/logging/config.d.ts.map +1 -0
  734. package/dist/logging/config.js +20 -0
  735. package/dist/logging/config.js.map +1 -0
  736. package/dist/logging/console.d.ts +20 -0
  737. package/dist/logging/console.d.ts.map +1 -0
  738. package/dist/logging/console.js +238 -0
  739. package/dist/logging/console.js.map +1 -0
  740. package/dist/logging/diagnostic.d.ts +59 -0
  741. package/dist/logging/diagnostic.d.ts.map +1 -0
  742. package/dist/logging/diagnostic.js +237 -0
  743. package/dist/logging/diagnostic.js.map +1 -0
  744. package/dist/logging/levels.d.ts +5 -0
  745. package/dist/logging/levels.d.ts.map +1 -0
  746. package/dist/logging/levels.js +27 -0
  747. package/dist/logging/levels.js.map +1 -0
  748. package/dist/logging/logger.d.ts +43 -0
  749. package/dist/logging/logger.d.ts.map +1 -0
  750. package/dist/logging/logger.js +186 -0
  751. package/dist/logging/logger.js.map +1 -0
  752. package/dist/logging/parse-log-line.d.ts +10 -0
  753. package/dist/logging/parse-log-line.d.ts.map +1 -0
  754. package/dist/logging/parse-log-line.js +53 -0
  755. package/dist/logging/parse-log-line.js.map +1 -0
  756. package/dist/logging/redact.d.ts +10 -0
  757. package/dist/logging/redact.d.ts.map +1 -0
  758. package/dist/logging/redact.js +116 -0
  759. package/dist/logging/redact.js.map +1 -0
  760. package/dist/logging/state.d.ts +18 -0
  761. package/dist/logging/state.d.ts.map +1 -0
  762. package/dist/logging/state.js +13 -0
  763. package/dist/logging/state.js.map +1 -0
  764. package/dist/logging/subsystem.d.ts +17 -0
  765. package/dist/logging/subsystem.d.ts.map +1 -0
  766. package/dist/logging/subsystem.js +235 -0
  767. package/dist/logging/subsystem.js.map +1 -0
  768. package/dist/media/audio-tags.d.ts +11 -0
  769. package/dist/media/audio-tags.d.ts.map +1 -0
  770. package/dist/media/audio-tags.js +15 -0
  771. package/dist/media/audio-tags.js.map +1 -0
  772. package/dist/media/audio.d.ts +5 -0
  773. package/dist/media/audio.d.ts.map +1 -0
  774. package/dist/media/audio.js +16 -0
  775. package/dist/media/audio.js.map +1 -0
  776. package/dist/media/constants.d.ts +8 -0
  777. package/dist/media/constants.d.ts.map +1 -0
  778. package/dist/media/constants.js +34 -0
  779. package/dist/media/constants.js.map +1 -0
  780. package/dist/media/fetch.d.ts +20 -0
  781. package/dist/media/fetch.d.ts.map +1 -0
  782. package/dist/media/fetch.js +152 -0
  783. package/dist/media/fetch.js.map +1 -0
  784. package/dist/media/host.d.ts +12 -0
  785. package/dist/media/host.d.ts.map +1 -0
  786. package/dist/media/host.js +44 -0
  787. package/dist/media/host.js.map +1 -0
  788. package/dist/media/image-ops.d.ts +40 -0
  789. package/dist/media/image-ops.d.ts.map +1 -0
  790. package/dist/media/image-ops.js +386 -0
  791. package/dist/media/image-ops.js.map +1 -0
  792. package/dist/media/input-files.d.ts +77 -0
  793. package/dist/media/input-files.d.ts.map +1 -0
  794. package/dist/media/input-files.js +277 -0
  795. package/dist/media/input-files.js.map +1 -0
  796. package/dist/media/mime.d.ts +16 -0
  797. package/dist/media/mime.d.ts.map +1 -0
  798. package/dist/media/mime.js +151 -0
  799. package/dist/media/mime.js.map +1 -0
  800. package/dist/media/parse.d.ts +9 -0
  801. package/dist/media/parse.d.ts.map +1 -0
  802. package/dist/media/parse.js +176 -0
  803. package/dist/media/parse.js.map +1 -0
  804. package/dist/media/server.d.ts +6 -0
  805. package/dist/media/server.d.ts.map +1 -0
  806. package/dist/media/server.js +89 -0
  807. package/dist/media/server.js.map +1 -0
  808. package/dist/media/store.d.ts +19 -0
  809. package/dist/media/store.d.ts.map +1 -0
  810. package/dist/media/store.js +201 -0
  811. package/dist/media/store.js.map +1 -0
  812. package/dist/process/exec.d.ts +23 -0
  813. package/dist/process/exec.d.ts.map +1 -0
  814. package/dist/process/exec.js +99 -0
  815. package/dist/process/exec.js.map +1 -0
  816. package/dist/schema/typebox.d.ts +40 -0
  817. package/dist/schema/typebox.d.ts.map +1 -0
  818. package/dist/schema/typebox.js +796 -0
  819. package/dist/schema/typebox.js.map +1 -0
  820. package/dist/server.d.ts +52 -0
  821. package/dist/server.d.ts.map +1 -0
  822. package/dist/server.js +322 -0
  823. package/dist/server.js.map +1 -0
  824. package/dist/services/supabase.d.ts +67 -0
  825. package/dist/services/supabase.d.ts.map +1 -0
  826. package/dist/services/supabase.js +106 -0
  827. package/dist/services/supabase.js.map +1 -0
  828. package/dist/skills/index.d.ts +24 -0
  829. package/dist/skills/index.d.ts.map +1 -0
  830. package/dist/skills/index.js +26 -0
  831. package/dist/skills/index.js.map +1 -0
  832. package/dist/skills/loader.d.ts +29 -0
  833. package/dist/skills/loader.d.ts.map +1 -0
  834. package/dist/skills/loader.js +176 -0
  835. package/dist/skills/loader.js.map +1 -0
  836. package/dist/skills/manager.d.ts +85 -0
  837. package/dist/skills/manager.d.ts.map +1 -0
  838. package/dist/skills/manager.js +179 -0
  839. package/dist/skills/manager.js.map +1 -0
  840. package/dist/skills/status.d.ts +26 -0
  841. package/dist/skills/status.d.ts.map +1 -0
  842. package/dist/skills/status.js +238 -0
  843. package/dist/skills/status.js.map +1 -0
  844. package/dist/skills/types.d.ts +182 -0
  845. package/dist/skills/types.d.ts.map +1 -0
  846. package/dist/skills/types.js +9 -0
  847. package/dist/skills/types.js.map +1 -0
  848. package/dist/supabase/client.d.ts +18 -0
  849. package/dist/supabase/client.d.ts.map +1 -0
  850. package/dist/supabase/client.js +43 -0
  851. package/dist/supabase/client.js.map +1 -0
  852. package/dist/supabase/context.d.ts +25 -0
  853. package/dist/supabase/context.d.ts.map +1 -0
  854. package/dist/supabase/context.js +109 -0
  855. package/dist/supabase/context.js.map +1 -0
  856. package/dist/supabase/cron-jobs.d.ts +79 -0
  857. package/dist/supabase/cron-jobs.d.ts.map +1 -0
  858. package/dist/supabase/cron-jobs.js +396 -0
  859. package/dist/supabase/cron-jobs.js.map +1 -0
  860. package/dist/supabase/heartbeat-items.d.ts +50 -0
  861. package/dist/supabase/heartbeat-items.d.ts.map +1 -0
  862. package/dist/supabase/heartbeat-items.js +179 -0
  863. package/dist/supabase/heartbeat-items.js.map +1 -0
  864. package/dist/supabase/index.d.ts +13 -0
  865. package/dist/supabase/index.d.ts.map +1 -0
  866. package/dist/supabase/index.js +12 -0
  867. package/dist/supabase/index.js.map +1 -0
  868. package/dist/supabase/memory.d.ts +49 -0
  869. package/dist/supabase/memory.d.ts.map +1 -0
  870. package/dist/supabase/memory.js +157 -0
  871. package/dist/supabase/memory.js.map +1 -0
  872. package/dist/supabase/notifications.d.ts +35 -0
  873. package/dist/supabase/notifications.d.ts.map +1 -0
  874. package/dist/supabase/notifications.js +46 -0
  875. package/dist/supabase/notifications.js.map +1 -0
  876. package/dist/supabase/requests.d.ts +69 -0
  877. package/dist/supabase/requests.d.ts.map +1 -0
  878. package/dist/supabase/requests.js +246 -0
  879. package/dist/supabase/requests.js.map +1 -0
  880. package/dist/supabase/types.d.ts +65 -0
  881. package/dist/supabase/types.d.ts.map +1 -0
  882. package/dist/supabase/types.js +5 -0
  883. package/dist/supabase/types.js.map +1 -0
  884. package/dist/supabase/workspace-storage.d.ts +54 -0
  885. package/dist/supabase/workspace-storage.d.ts.map +1 -0
  886. package/dist/supabase/workspace-storage.js +217 -0
  887. package/dist/supabase/workspace-storage.js.map +1 -0
  888. package/dist/tools/bash-tools.shared.d.ts +26 -0
  889. package/dist/tools/bash-tools.shared.d.ts.map +1 -0
  890. package/dist/tools/bash-tools.shared.js +135 -0
  891. package/dist/tools/bash-tools.shared.js.map +1 -0
  892. package/dist/tools/browser-new.d.ts +7 -0
  893. package/dist/tools/browser-new.d.ts.map +1 -0
  894. package/dist/tools/browser-new.js +329 -0
  895. package/dist/tools/browser-new.js.map +1 -0
  896. package/dist/tools/browser-openclaw.d.ts +6 -0
  897. package/dist/tools/browser-openclaw.d.ts.map +1 -0
  898. package/dist/tools/browser-openclaw.js +597 -0
  899. package/dist/tools/browser-openclaw.js.map +1 -0
  900. package/dist/tools/browser-tool.schema.d.ts +51 -0
  901. package/dist/tools/browser-tool.schema.d.ts.map +1 -0
  902. package/dist/tools/browser-tool.schema.js +106 -0
  903. package/dist/tools/browser-tool.schema.js.map +1 -0
  904. package/dist/tools/browser.d.ts +9 -0
  905. package/dist/tools/browser.d.ts.map +1 -0
  906. package/dist/tools/browser.js +1629 -0
  907. package/dist/tools/browser.js.map +1 -0
  908. package/dist/tools/built-in-tools.d.ts +27 -0
  909. package/dist/tools/built-in-tools.d.ts.map +1 -0
  910. package/dist/tools/built-in-tools.js +86 -0
  911. package/dist/tools/built-in-tools.js.map +1 -0
  912. package/dist/tools/calendar.d.ts +16 -0
  913. package/dist/tools/calendar.d.ts.map +1 -0
  914. package/dist/tools/calendar.js +244 -0
  915. package/dist/tools/calendar.js.map +1 -0
  916. package/dist/tools/cron.d.ts +22 -0
  917. package/dist/tools/cron.d.ts.map +1 -0
  918. package/dist/tools/cron.js +273 -0
  919. package/dist/tools/cron.js.map +1 -0
  920. package/dist/tools/email.d.ts +16 -0
  921. package/dist/tools/email.d.ts.map +1 -0
  922. package/dist/tools/email.js +435 -0
  923. package/dist/tools/email.js.map +1 -0
  924. package/dist/tools/exec.d.ts +40 -0
  925. package/dist/tools/exec.d.ts.map +1 -0
  926. package/dist/tools/exec.js +446 -0
  927. package/dist/tools/exec.js.map +1 -0
  928. package/dist/tools/fetch-api-data.d.ts +9 -0
  929. package/dist/tools/fetch-api-data.d.ts.map +1 -0
  930. package/dist/tools/fetch-api-data.js +120 -0
  931. package/dist/tools/fetch-api-data.js.map +1 -0
  932. package/dist/tools/file-ops.d.ts +14 -0
  933. package/dist/tools/file-ops.d.ts.map +1 -0
  934. package/dist/tools/file-ops.js +19 -0
  935. package/dist/tools/file-ops.js.map +1 -0
  936. package/dist/tools/generate-image.d.ts +8 -0
  937. package/dist/tools/generate-image.d.ts.map +1 -0
  938. package/dist/tools/generate-image.js +99 -0
  939. package/dist/tools/generate-image.js.map +1 -0
  940. package/dist/tools/generate-video.d.ts +9 -0
  941. package/dist/tools/generate-video.d.ts.map +1 -0
  942. package/dist/tools/generate-video.js +178 -0
  943. package/dist/tools/generate-video.js.map +1 -0
  944. package/dist/tools/google-maps.d.ts +11 -0
  945. package/dist/tools/google-maps.d.ts.map +1 -0
  946. package/dist/tools/google-maps.js +285 -0
  947. package/dist/tools/google-maps.js.map +1 -0
  948. package/dist/tools/image.d.ts +9 -0
  949. package/dist/tools/image.d.ts.map +1 -0
  950. package/dist/tools/image.js +124 -0
  951. package/dist/tools/image.js.map +1 -0
  952. package/dist/tools/index.d.ts +40 -0
  953. package/dist/tools/index.d.ts.map +1 -0
  954. package/dist/tools/index.js +104 -0
  955. package/dist/tools/index.js.map +1 -0
  956. package/dist/tools/memory.d.ts +16 -0
  957. package/dist/tools/memory.d.ts.map +1 -0
  958. package/dist/tools/memory.js +118 -0
  959. package/dist/tools/memory.js.map +1 -0
  960. package/dist/tools/message.d.ts +8 -0
  961. package/dist/tools/message.d.ts.map +1 -0
  962. package/dist/tools/message.js +60 -0
  963. package/dist/tools/message.js.map +1 -0
  964. package/dist/tools/process-registry.d.ts +73 -0
  965. package/dist/tools/process-registry.d.ts.map +1 -0
  966. package/dist/tools/process-registry.js +185 -0
  967. package/dist/tools/process-registry.js.map +1 -0
  968. package/dist/tools/process.d.ts +24 -0
  969. package/dist/tools/process.d.ts.map +1 -0
  970. package/dist/tools/process.js +586 -0
  971. package/dist/tools/process.js.map +1 -0
  972. package/dist/tools/pty-dsr.d.ts +12 -0
  973. package/dist/tools/pty-dsr.d.ts.map +1 -0
  974. package/dist/tools/pty-dsr.js +20 -0
  975. package/dist/tools/pty-dsr.js.map +1 -0
  976. package/dist/tools/pty-keys.d.ts +20 -0
  977. package/dist/tools/pty-keys.d.ts.map +1 -0
  978. package/dist/tools/pty-keys.js +242 -0
  979. package/dist/tools/pty-keys.js.map +1 -0
  980. package/dist/tools/session-slug.d.ts +8 -0
  981. package/dist/tools/session-slug.d.ts.map +1 -0
  982. package/dist/tools/session-slug.js +136 -0
  983. package/dist/tools/session-slug.js.map +1 -0
  984. package/dist/tools/session-status.d.ts +7 -0
  985. package/dist/tools/session-status.d.ts.map +1 -0
  986. package/dist/tools/session-status.js +55 -0
  987. package/dist/tools/session-status.js.map +1 -0
  988. package/dist/tools/shell-utils.d.ts +13 -0
  989. package/dist/tools/shell-utils.d.ts.map +1 -0
  990. package/dist/tools/shell-utils.js +106 -0
  991. package/dist/tools/shell-utils.js.map +1 -0
  992. package/dist/tools/tts.d.ts +9 -0
  993. package/dist/tools/tts.d.ts.map +1 -0
  994. package/dist/tools/tts.js +102 -0
  995. package/dist/tools/tts.js.map +1 -0
  996. package/dist/tools/web-fetch.d.ts +9 -0
  997. package/dist/tools/web-fetch.d.ts.map +1 -0
  998. package/dist/tools/web-fetch.js +129 -0
  999. package/dist/tools/web-fetch.js.map +1 -0
  1000. package/dist/tools/web-search.d.ts +15 -0
  1001. package/dist/tools/web-search.d.ts.map +1 -0
  1002. package/dist/tools/web-search.js +119 -0
  1003. package/dist/tools/web-search.js.map +1 -0
  1004. package/dist/types/tool.d.ts +31 -0
  1005. package/dist/types/tool.d.ts.map +1 -0
  1006. package/dist/types/tool.js +5 -0
  1007. package/dist/types/tool.js.map +1 -0
  1008. package/dist/updates/checker.d.ts +51 -0
  1009. package/dist/updates/checker.d.ts.map +1 -0
  1010. package/dist/updates/checker.js +237 -0
  1011. package/dist/updates/checker.js.map +1 -0
  1012. package/dist/updates/index.d.ts +6 -0
  1013. package/dist/updates/index.d.ts.map +1 -0
  1014. package/dist/updates/index.js +6 -0
  1015. package/dist/updates/index.js.map +1 -0
  1016. package/dist/updates/notifier.d.ts +17 -0
  1017. package/dist/updates/notifier.d.ts.map +1 -0
  1018. package/dist/updates/notifier.js +44 -0
  1019. package/dist/updates/notifier.js.map +1 -0
  1020. package/dist/utils/google-oauth.d.ts +58 -0
  1021. package/dist/utils/google-oauth.d.ts.map +1 -0
  1022. package/dist/utils/google-oauth.js +161 -0
  1023. package/dist/utils/google-oauth.js.map +1 -0
  1024. package/dist/utils/log-buffer.d.ts +35 -0
  1025. package/dist/utils/log-buffer.d.ts.map +1 -0
  1026. package/dist/utils/log-buffer.js +100 -0
  1027. package/dist/utils/log-buffer.js.map +1 -0
  1028. package/dist/utils/tool-helpers.d.ts +48 -0
  1029. package/dist/utils/tool-helpers.d.ts.map +1 -0
  1030. package/dist/utils/tool-helpers.js +125 -0
  1031. package/dist/utils/tool-helpers.js.map +1 -0
  1032. package/dist/utils/utils.d.ts +44 -0
  1033. package/dist/utils/utils.d.ts.map +1 -0
  1034. package/dist/utils/utils.js +257 -0
  1035. package/dist/utils/utils.js.map +1 -0
  1036. package/dist/web-server.d.ts +30 -0
  1037. package/dist/web-server.d.ts.map +1 -0
  1038. package/dist/web-server.js +367 -0
  1039. package/dist/web-server.js.map +1 -0
  1040. package/dist/workspace/context.d.ts +23 -0
  1041. package/dist/workspace/context.d.ts.map +1 -0
  1042. package/dist/workspace/context.js +88 -0
  1043. package/dist/workspace/context.js.map +1 -0
  1044. package/dist/workspace/generator.d.ts +47 -0
  1045. package/dist/workspace/generator.d.ts.map +1 -0
  1046. package/dist/workspace/generator.js +261 -0
  1047. package/dist/workspace/generator.js.map +1 -0
  1048. package/dist/workspace/index.d.ts +9 -0
  1049. package/dist/workspace/index.d.ts.map +1 -0
  1050. package/dist/workspace/index.js +9 -0
  1051. package/dist/workspace/index.js.map +1 -0
  1052. package/dist/workspace/templates.d.ts +36 -0
  1053. package/dist/workspace/templates.d.ts.map +1 -0
  1054. package/dist/workspace/templates.js +280 -0
  1055. package/dist/workspace/templates.js.map +1 -0
  1056. package/dist/workspace/workspace.d.ts +79 -0
  1057. package/dist/workspace/workspace.d.ts.map +1 -0
  1058. package/dist/workspace/workspace.js +234 -0
  1059. package/dist/workspace/workspace.js.map +1 -0
  1060. package/package.json +98 -0
  1061. package/public/index.html +1625 -0
  1062. package/scripts/install.sh +311 -0
  1063. package/scripts/postinstall.js +135 -0
  1064. package/skills/commit/SKILL.md +69 -0
  1065. package/skills/review-pr/SKILL.md +105 -0
  1066. package/skills/skill-creator/SKILL.md +236 -0
  1067. package/skills/test/SKILL.md +57 -0
@@ -0,0 +1,1629 @@
1
+ /**
2
+ * CoStar Server Executor - Complete Browser Tool
3
+ * Replicates OpenClaw's browser-tool.ts behavior using direct Playwright
4
+ *
5
+ * Implements all 15 actions with AI snapshots, labeled screenshots, and full automation
6
+ */
7
+ import { Type } from "@sinclair/typebox";
8
+ import { chromium } from "playwright";
9
+ import { jsonResult, readStringParam, readBooleanParam, readNumberParam, readArrayParam, } from "../utils/tool-helpers.js";
10
+ // OpenClaw exact BROWSER_ACT_KINDS (from browser-tool.schema.ts)
11
+ const BROWSER_ACT_KINDS = [
12
+ "click",
13
+ "type",
14
+ "press",
15
+ "hover",
16
+ "drag",
17
+ "select",
18
+ "fill",
19
+ "resize",
20
+ "wait",
21
+ "evaluate",
22
+ "close",
23
+ ];
24
+ // OpenClaw exact BROWSER_TOOL_ACTIONS (from browser-tool.schema.ts)
25
+ const BROWSER_TOOL_ACTIONS = [
26
+ "status",
27
+ "start",
28
+ "stop",
29
+ "profiles",
30
+ "tabs",
31
+ "open",
32
+ "focus",
33
+ "close",
34
+ "snapshot",
35
+ "screenshot",
36
+ "navigate",
37
+ "console",
38
+ "pdf",
39
+ "upload",
40
+ "dialog",
41
+ "act",
42
+ ];
43
+ // OpenClaw exact BrowserActSchema (from browser-tool.schema.ts)
44
+ const BrowserActSchema = Type.Object({
45
+ kind: Type.Union(BROWSER_ACT_KINDS.map(k => Type.Literal(k))),
46
+ // Common fields
47
+ targetId: Type.Optional(Type.String()),
48
+ ref: Type.Optional(Type.String()),
49
+ // click
50
+ doubleClick: Type.Optional(Type.Boolean()),
51
+ button: Type.Optional(Type.String()),
52
+ modifiers: Type.Optional(Type.Array(Type.String())),
53
+ // type
54
+ text: Type.Optional(Type.String()),
55
+ submit: Type.Optional(Type.Boolean()),
56
+ slowly: Type.Optional(Type.Boolean()),
57
+ // press
58
+ key: Type.Optional(Type.String()),
59
+ // drag
60
+ startRef: Type.Optional(Type.String()),
61
+ endRef: Type.Optional(Type.String()),
62
+ // select
63
+ values: Type.Optional(Type.Array(Type.String())),
64
+ // fill - use permissive array of objects
65
+ fields: Type.Optional(Type.Array(Type.Object({}, { additionalProperties: true }))),
66
+ // resize
67
+ width: Type.Optional(Type.Number()),
68
+ height: Type.Optional(Type.Number()),
69
+ // wait
70
+ timeMs: Type.Optional(Type.Number()),
71
+ textGone: Type.Optional(Type.String()),
72
+ // evaluate
73
+ fn: Type.Optional(Type.String()),
74
+ });
75
+ // OpenClaw exact BrowserToolSchema (from browser-tool.schema.ts)
76
+ const BrowserSchema = Type.Object({
77
+ action: Type.Union(BROWSER_TOOL_ACTIONS.map(a => Type.Literal(a))),
78
+ profile: Type.Optional(Type.String()),
79
+ targetUrl: Type.Optional(Type.String()),
80
+ targetId: Type.Optional(Type.String()),
81
+ limit: Type.Optional(Type.Number()),
82
+ maxChars: Type.Optional(Type.Number()),
83
+ mode: Type.Optional(Type.String()), // "efficient"
84
+ refs: Type.Optional(Type.String()), // "role" or "aria"
85
+ interactive: Type.Optional(Type.Boolean()),
86
+ compact: Type.Optional(Type.Boolean()),
87
+ depth: Type.Optional(Type.Number()),
88
+ selector: Type.Optional(Type.String()),
89
+ frame: Type.Optional(Type.String()),
90
+ labels: Type.Optional(Type.Boolean()),
91
+ fullPage: Type.Optional(Type.Boolean()),
92
+ ref: Type.Optional(Type.String()),
93
+ element: Type.Optional(Type.String()),
94
+ type: Type.Optional(Type.String()), // "png" or "jpeg"
95
+ level: Type.Optional(Type.String()),
96
+ paths: Type.Optional(Type.Array(Type.String())),
97
+ inputRef: Type.Optional(Type.String()),
98
+ timeoutMs: Type.Optional(Type.Number()),
99
+ accept: Type.Optional(Type.Boolean()),
100
+ promptText: Type.Optional(Type.String()),
101
+ request: Type.Optional(BrowserActSchema),
102
+ });
103
+ // OpenClaw's INTERACTIVE_ROLES - elements that get refs
104
+ const INTERACTIVE_ROLES = new Set([
105
+ "button",
106
+ "link",
107
+ "textbox",
108
+ "checkbox",
109
+ "radio",
110
+ "combobox",
111
+ "listbox",
112
+ "menuitem",
113
+ "menuitemcheckbox",
114
+ "menuitemradio",
115
+ "option",
116
+ "searchbox",
117
+ "slider",
118
+ "spinbutton",
119
+ "switch",
120
+ "tab",
121
+ "treeitem",
122
+ ]);
123
+ const CONTENT_ROLES = new Set([
124
+ "heading",
125
+ "cell",
126
+ "gridcell",
127
+ "columnheader",
128
+ "rowheader",
129
+ "listitem",
130
+ "article",
131
+ "region",
132
+ "main",
133
+ "navigation",
134
+ ]);
135
+ /**
136
+ * Parse Playwright's ariaSnapshot output and build refs map (OpenClaw style)
137
+ */
138
+ function buildRoleSnapshotFromAriaSnapshot(ariaSnapshot, options = {}) {
139
+ const lines = ariaSnapshot.split("\n");
140
+ const refs = {};
141
+ // Track role+name combinations for nth handling
142
+ const counts = new Map();
143
+ const refsByKey = new Map();
144
+ const getKey = (role, name) => `${role}:${name ?? ""}`;
145
+ let counter = 0;
146
+ const nextRef = () => {
147
+ counter += 1;
148
+ return `e${counter}`;
149
+ };
150
+ const getIndentLevel = (line) => {
151
+ const match = line.match(/^(\s*)/);
152
+ return match ? Math.floor(match[1].length / 2) : 0;
153
+ };
154
+ const result = [];
155
+ for (const line of lines) {
156
+ const depth = getIndentLevel(line);
157
+ if (options.maxDepth !== undefined && depth > options.maxDepth)
158
+ continue;
159
+ // Parse line: "- role "name" [other stuff]"
160
+ const match = line.match(/^(\s*-\s*)(\w+)(?:\s+"([^"]*)")?(.*)$/);
161
+ if (!match) {
162
+ if (!options.interactive)
163
+ result.push(line);
164
+ continue;
165
+ }
166
+ const [, prefix, roleRaw, name, suffix] = match;
167
+ if (roleRaw.startsWith("/")) {
168
+ if (!options.interactive)
169
+ result.push(line);
170
+ continue;
171
+ }
172
+ const role = roleRaw.toLowerCase();
173
+ const isInteractive = INTERACTIVE_ROLES.has(role);
174
+ const isContent = CONTENT_ROLES.has(role);
175
+ // If interactive-only mode, skip non-interactive
176
+ if (options.interactive && !isInteractive)
177
+ continue;
178
+ // Determine if this element should have a ref
179
+ const shouldHaveRef = isInteractive || (isContent && name);
180
+ if (!shouldHaveRef) {
181
+ if (!options.interactive)
182
+ result.push(line);
183
+ continue;
184
+ }
185
+ const ref = nextRef();
186
+ const key = getKey(role, name);
187
+ const nth = counts.get(key) ?? 0;
188
+ counts.set(key, nth + 1);
189
+ const keyRefs = refsByKey.get(key) ?? [];
190
+ keyRefs.push(ref);
191
+ refsByKey.set(key, keyRefs);
192
+ refs[ref] = { role, name, nth };
193
+ // Build enhanced line with ref
194
+ let enhanced = `${prefix}${roleRaw}`;
195
+ if (name)
196
+ enhanced += ` "${name}"`;
197
+ enhanced += ` [ref=${ref}]`;
198
+ if (nth > 0)
199
+ enhanced += ` [nth=${nth}]`;
200
+ if (suffix && suffix.includes("["))
201
+ enhanced += suffix;
202
+ result.push(enhanced);
203
+ }
204
+ // Remove nth from non-duplicates
205
+ for (const [_key, keyRefs] of refsByKey) {
206
+ if (keyRefs.length === 1) {
207
+ const ref = keyRefs[0];
208
+ if (refs[ref])
209
+ delete refs[ref].nth;
210
+ }
211
+ }
212
+ return {
213
+ snapshot: result.join("\n") || "(empty)",
214
+ refs,
215
+ };
216
+ }
217
+ // OpenClaw-style WeakMap to store state per Page object
218
+ const pageStates = new WeakMap();
219
+ // Global cache by targetId (backup for when Playwright returns different Page object)
220
+ const roleRefsByTarget = new Map();
221
+ const MAX_ROLE_REFS_CACHE = 50;
222
+ // Ensure page has a state object (OpenClaw-style)
223
+ function ensurePageState(page) {
224
+ const existing = pageStates.get(page);
225
+ if (existing)
226
+ return existing;
227
+ const newState = {
228
+ console: [],
229
+ errors: [],
230
+ requests: [],
231
+ };
232
+ pageStates.set(page, newState);
233
+ return newState;
234
+ }
235
+ // Global browser state (singleton)
236
+ const state = {
237
+ browser: null,
238
+ context: null,
239
+ pages: new Map(),
240
+ consoleLogs: new Map(),
241
+ networkRequests: new Map(),
242
+ pageErrors: new Map(),
243
+ running: false,
244
+ connectionMode: "launched",
245
+ };
246
+ /**
247
+ * Get the page to use for an action, tracking last active (OpenClaw-style)
248
+ */
249
+ function getPageForAction(targetId) {
250
+ if (targetId) {
251
+ const existingPage = state.pages.get(targetId);
252
+ if (!existingPage) {
253
+ throw new Error(`Tab ${targetId} not found. Run action=tabs to see available tabs.`);
254
+ }
255
+ state.lastActiveTargetId = targetId;
256
+ return { page: existingPage, usedTargetId: targetId };
257
+ }
258
+ if (state.pages.size === 0) {
259
+ throw new Error("No tabs open. Use action=open to open a URL first.");
260
+ }
261
+ // Prefer last active tab (the one most recently used for snapshot/action)
262
+ if (state.lastActiveTargetId && state.pages.has(state.lastActiveTargetId)) {
263
+ const page = state.pages.get(state.lastActiveTargetId);
264
+ return { page, usedTargetId: state.lastActiveTargetId };
265
+ }
266
+ // Fall back to first tab
267
+ const firstEntry = Array.from(state.pages.entries())[0];
268
+ state.lastActiveTargetId = firstEntry[0];
269
+ return { page: firstEntry[1], usedTargetId: firstEntry[0] };
270
+ }
271
+ /**
272
+ * Restore role refs for a target (OpenClaw-style)
273
+ * This ensures refs are available for the page even if they were stored under a different targetId
274
+ */
275
+ /**
276
+ * Store role refs for a target (OpenClaw-style)
277
+ * Stores BOTH on page's WeakMap state AND in global cache
278
+ */
279
+ function storeRoleRefsForTarget(opts) {
280
+ // Store on page's WeakMap state
281
+ const pageState = ensurePageState(opts.page);
282
+ pageState.roleRefs = opts.refs;
283
+ pageState.roleRefsFrameSelector = opts.frameSelector;
284
+ pageState.roleRefsMode = opts.mode;
285
+ // Store in global cache by targetId (for backup)
286
+ const targetId = opts.targetId?.trim();
287
+ if (!targetId)
288
+ return;
289
+ roleRefsByTarget.set(targetId, {
290
+ refs: opts.refs,
291
+ ...(opts.frameSelector ? { frameSelector: opts.frameSelector } : {}),
292
+ mode: opts.mode,
293
+ });
294
+ // Limit cache size
295
+ while (roleRefsByTarget.size > MAX_ROLE_REFS_CACHE) {
296
+ const first = roleRefsByTarget.keys().next();
297
+ if (first.done)
298
+ break;
299
+ roleRefsByTarget.delete(first.value);
300
+ }
301
+ console.log(`[BROWSER] Stored ${Object.keys(opts.refs).length} refs for targetId "${targetId}"`);
302
+ }
303
+ /**
304
+ * Restore role refs for a target (OpenClaw-style)
305
+ * Copies from global cache to page's WeakMap state
306
+ */
307
+ function restoreRoleRefsForTarget(page, targetId) {
308
+ const tid = targetId?.trim() || "";
309
+ if (!tid)
310
+ return;
311
+ // Check if page already has refs (no need to restore)
312
+ const pageState = ensurePageState(page);
313
+ if (pageState.roleRefs) {
314
+ console.log(`[BROWSER] Page already has ${Object.keys(pageState.roleRefs).length} refs`);
315
+ return;
316
+ }
317
+ // Try to restore from global cache
318
+ const cached = roleRefsByTarget.get(tid);
319
+ if (cached) {
320
+ pageState.roleRefs = cached.refs;
321
+ pageState.roleRefsFrameSelector = cached.frameSelector;
322
+ pageState.roleRefsMode = cached.mode;
323
+ console.log(`[BROWSER] Restored ${Object.keys(cached.refs).length} refs from cache for "${tid}"`);
324
+ return;
325
+ }
326
+ // Fallback: try any targetId that has refs
327
+ for (const [storedTargetId, storedData] of roleRefsByTarget.entries()) {
328
+ if (Object.keys(storedData.refs).length > 0) {
329
+ pageState.roleRefs = storedData.refs;
330
+ pageState.roleRefsFrameSelector = storedData.frameSelector;
331
+ pageState.roleRefsMode = storedData.mode;
332
+ console.log(`[BROWSER] Restored ${Object.keys(storedData.refs).length} refs from "${storedTargetId}" (fallback)`);
333
+ return;
334
+ }
335
+ }
336
+ console.log(`[BROWSER] No refs available to restore`);
337
+ }
338
+ function generateTargetId() {
339
+ return `page-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
340
+ }
341
+ async function startBrowser(options = {}) {
342
+ if (state.running) {
343
+ return;
344
+ }
345
+ // Check if we should run in headless mode (default true, can be overridden by env var or param)
346
+ const headlessMode = options.headless ?? process.env.BROWSER_HEADLESS !== "false";
347
+ const launchOptions = {
348
+ headless: headlessMode,
349
+ args: ["--no-sandbox", "--disable-setuid-sandbox"],
350
+ };
351
+ // Support persistent profile directory
352
+ if (options.profilePath) {
353
+ console.log(`[BROWSER] Using profile: ${options.profilePath}`);
354
+ // For persistent context, we use launchPersistentContext instead
355
+ state.context = await chromium.launchPersistentContext(options.profilePath, {
356
+ ...launchOptions,
357
+ viewport: { width: 1280, height: 720 },
358
+ userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
359
+ });
360
+ state.browser = null; // Persistent context doesn't have separate browser
361
+ state.running = true;
362
+ state.connectionMode = "launched";
363
+ console.log(`[BROWSER] Started with persistent profile (headless: ${headlessMode})`);
364
+ return;
365
+ }
366
+ console.log(`[BROWSER] Starting Chromium... (headless: ${headlessMode})`);
367
+ state.browser = await chromium.launch(launchOptions);
368
+ state.context = await state.browser.newContext({
369
+ viewport: { width: 1280, height: 720 },
370
+ userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
371
+ });
372
+ state.running = true;
373
+ state.connectionMode = "launched";
374
+ console.log("[BROWSER] Started");
375
+ }
376
+ /**
377
+ * Set up page event listeners (extracted for reuse)
378
+ */
379
+ function setupPageListeners(page, targetId) {
380
+ let nextRequestId = 0;
381
+ const requestIds = new WeakMap();
382
+ // Capture console logs
383
+ page.on("console", (msg) => {
384
+ const logs = state.consoleLogs.get(targetId) || [];
385
+ logs.push(msg);
386
+ if (logs.length > 500)
387
+ logs.shift();
388
+ state.consoleLogs.set(targetId, logs);
389
+ });
390
+ // Capture page errors
391
+ page.on("pageerror", (err) => {
392
+ const errors = state.pageErrors.get(targetId) || [];
393
+ errors.push({
394
+ message: err?.message || String(err),
395
+ name: err?.name,
396
+ stack: err?.stack,
397
+ timestamp: new Date().toISOString(),
398
+ });
399
+ if (errors.length > 200)
400
+ errors.shift();
401
+ state.pageErrors.set(targetId, errors);
402
+ });
403
+ // Capture network requests
404
+ page.on("request", (req) => {
405
+ nextRequestId += 1;
406
+ const id = `r${nextRequestId}`;
407
+ requestIds.set(req, id);
408
+ const requests = state.networkRequests.get(targetId) || [];
409
+ requests.push({
410
+ id,
411
+ timestamp: new Date().toISOString(),
412
+ method: req.method(),
413
+ url: req.url(),
414
+ resourceType: req.resourceType(),
415
+ });
416
+ if (requests.length > 500)
417
+ requests.shift();
418
+ state.networkRequests.set(targetId, requests);
419
+ });
420
+ page.on("response", (resp) => {
421
+ const req = resp.request();
422
+ const id = requestIds.get(req);
423
+ if (!id)
424
+ return;
425
+ const requests = state.networkRequests.get(targetId) || [];
426
+ const rec = requests.find((r) => r.id === id);
427
+ if (rec) {
428
+ rec.status = resp.status();
429
+ rec.ok = resp.ok();
430
+ }
431
+ });
432
+ page.on("requestfailed", (req) => {
433
+ const id = requestIds.get(req);
434
+ if (!id)
435
+ return;
436
+ const requests = state.networkRequests.get(targetId) || [];
437
+ const rec = requests.find((r) => r.id === id);
438
+ if (rec) {
439
+ rec.failureText = req.failure()?.errorText;
440
+ rec.ok = false;
441
+ }
442
+ });
443
+ }
444
+ async function stopBrowser() {
445
+ if (!state.running) {
446
+ return;
447
+ }
448
+ const isConnected = state.connectionMode === "connected";
449
+ console.log(`[BROWSER] Stopping... (mode: ${state.connectionMode})`);
450
+ // Close all pages we opened (but not pre-existing pages in CDP mode)
451
+ for (const [id, page] of state.pages.entries()) {
452
+ try {
453
+ await page.close();
454
+ }
455
+ catch (err) {
456
+ console.warn(`[BROWSER] Error closing page ${id}:`, err);
457
+ }
458
+ }
459
+ state.pages.clear();
460
+ state.consoleLogs.clear();
461
+ state.networkRequests.clear();
462
+ state.pageErrors.clear();
463
+ roleRefsByTarget.clear(); // Clear the OpenClaw-style global cache
464
+ // For CDP connections, we disconnect but don't close the browser
465
+ if (isConnected) {
466
+ if (state.browser) {
467
+ // disconnect() keeps the browser running
468
+ state.browser.close(); // This disconnects for CDP
469
+ state.browser = null;
470
+ }
471
+ state.context = null;
472
+ state.wsEndpoint = undefined;
473
+ console.log("[BROWSER] Disconnected from CDP");
474
+ }
475
+ else {
476
+ // For launched browsers, close everything
477
+ if (state.context) {
478
+ await state.context.close();
479
+ state.context = null;
480
+ }
481
+ if (state.browser) {
482
+ await state.browser.close();
483
+ state.browser = null;
484
+ }
485
+ console.log("[BROWSER] Stopped");
486
+ }
487
+ state.running = false;
488
+ state.connectionMode = "launched";
489
+ }
490
+ async function openPage(url) {
491
+ if (!state.running || !state.context) {
492
+ await startBrowser();
493
+ }
494
+ const page = await state.context.newPage();
495
+ const targetId = generateTargetId();
496
+ state.pages.set(targetId, page);
497
+ state.consoleLogs.set(targetId, []);
498
+ state.networkRequests.set(targetId, []);
499
+ state.pageErrors.set(targetId, []);
500
+ // Track as last active tab
501
+ state.lastActiveTargetId = targetId;
502
+ // Set up event listeners
503
+ setupPageListeners(page, targetId);
504
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 });
505
+ return { targetId, page };
506
+ }
507
+ /**
508
+ * Build role snapshot from Playwright's AI snapshot output (OpenClaw style)
509
+ * Preserves Playwright's own aria-ref ids (e.g. ref=e13)
510
+ */
511
+ function buildRoleSnapshotFromAiSnapshot(aiSnapshot, options = {}) {
512
+ const lines = String(aiSnapshot ?? "").split("\n");
513
+ const refs = {};
514
+ const getIndentLevel = (line) => {
515
+ const match = line.match(/^(\s*)/);
516
+ return match ? Math.floor(match[1].length / 2) : 0;
517
+ };
518
+ const parseAiSnapshotRef = (suffix) => {
519
+ const match = suffix.match(/\[ref=(e\d+)\]/i);
520
+ return match ? match[1] : null;
521
+ };
522
+ if (options.interactive) {
523
+ const out = [];
524
+ for (const line of lines) {
525
+ const depth = getIndentLevel(line);
526
+ if (options.maxDepth !== undefined && depth > options.maxDepth)
527
+ continue;
528
+ const match = line.match(/^(\s*-\s*)(\w+)(?:\s+"([^"]*)")?(.*)$/);
529
+ if (!match)
530
+ continue;
531
+ const [, , roleRaw, name, suffix] = match;
532
+ if (roleRaw.startsWith("/"))
533
+ continue;
534
+ const role = roleRaw.toLowerCase();
535
+ if (!INTERACTIVE_ROLES.has(role))
536
+ continue;
537
+ const ref = parseAiSnapshotRef(suffix);
538
+ if (!ref)
539
+ continue;
540
+ refs[ref] = { role, ...(name ? { name } : {}) };
541
+ out.push(`- ${roleRaw}${name ? ` "${name}"` : ""}${suffix}`);
542
+ }
543
+ return {
544
+ snapshot: out.join("\n") || "(no interactive elements)",
545
+ refs,
546
+ };
547
+ }
548
+ const out = [];
549
+ for (const line of lines) {
550
+ const depth = getIndentLevel(line);
551
+ if (options.maxDepth !== undefined && depth > options.maxDepth)
552
+ continue;
553
+ const match = line.match(/^(\s*-\s*)(\w+)(?:\s+"([^"]*)")?(.*)$/);
554
+ if (!match) {
555
+ out.push(line);
556
+ continue;
557
+ }
558
+ const [, , roleRaw, name, suffix] = match;
559
+ if (roleRaw.startsWith("/")) {
560
+ out.push(line);
561
+ continue;
562
+ }
563
+ const role = roleRaw.toLowerCase();
564
+ const ref = parseAiSnapshotRef(suffix);
565
+ if (ref)
566
+ refs[ref] = { role, ...(name ? { name } : {}) };
567
+ out.push(line);
568
+ }
569
+ const tree = out.join("\n") || "(empty)";
570
+ return { snapshot: tree, refs };
571
+ }
572
+ /**
573
+ * Get AI-formatted snapshot of page (OpenClaw-style)
574
+ * Uses Playwright's _snapshotForAI() for accurate role detection and ref building
575
+ * This captures the FULL accessibility tree including modals/overlays
576
+ *
577
+ * Ref modes:
578
+ * - "role" (default): Generates refs based on role+name from ariaSnapshot, requires snapshot context
579
+ * - "aria": Uses Playwright's aria-ref IDs, self-resolving across calls
580
+ */
581
+ async function getAISnapshot(page, targetId, options) {
582
+ const maxChars = options.maxChars || 50000;
583
+ const labels = options.labels || false;
584
+ const refsMode = options.refs || "role";
585
+ let ariaSnapshotText = "";
586
+ let refsMap;
587
+ let roleSnapshot;
588
+ // OpenClaw-style: Two separate modes, NO fallback
589
+ if (refsMode === "aria") {
590
+ // refs="aria" mode: Use _snapshotForAI for self-resolving refs
591
+ // This captures the FULL accessibility tree including modals/overlays
592
+ if (options.selector || options.frame) {
593
+ throw new Error("refs=aria does not support selector/frame snapshots yet.");
594
+ }
595
+ const maybePage = page;
596
+ if (!maybePage._snapshotForAI) {
597
+ throw new Error("refs=aria requires Playwright _snapshotForAI support. Upgrade playwright-core.");
598
+ }
599
+ console.log(`[BROWSER] Using _snapshotForAI for aria mode (captures modals/overlays)`);
600
+ const result = await maybePage._snapshotForAI({
601
+ timeout: 5000,
602
+ track: "response",
603
+ });
604
+ ariaSnapshotText = String(result?.full ?? "");
605
+ console.log(`[BROWSER] _snapshotForAI returned ${ariaSnapshotText.length} chars`);
606
+ // Parse AI snapshot - refs are self-resolving via aria-ref=
607
+ const built = buildRoleSnapshotFromAiSnapshot(ariaSnapshotText, {
608
+ interactive: options.interactive,
609
+ maxDepth: options.maxDepth,
610
+ compact: options.compact,
611
+ });
612
+ refsMap = built.refs;
613
+ roleSnapshot = built.snapshot;
614
+ console.log(`[BROWSER] Aria mode - refs are self-resolving via aria-ref=`);
615
+ }
616
+ else {
617
+ // refs="role" mode (default): Use locator.ariaSnapshot()
618
+ // Refs are resolved via getByRole with the stored ref map
619
+ const frameSelector = options.frame?.trim() || "";
620
+ const selector = options.selector?.trim() || "";
621
+ const locator = frameSelector
622
+ ? selector
623
+ ? page.frameLocator(frameSelector).locator(selector)
624
+ : page.frameLocator(frameSelector).locator(":root")
625
+ : selector
626
+ ? page.locator(selector)
627
+ : page.locator(":root");
628
+ console.log(`[BROWSER] Using ariaSnapshot() for role mode`);
629
+ ariaSnapshotText = await locator.ariaSnapshot();
630
+ console.log(`[BROWSER] ariaSnapshot() returned ${ariaSnapshotText.length} chars`);
631
+ // Parse aria snapshot - we generate refs that require role map for resolution
632
+ const built = buildRoleSnapshotFromAriaSnapshot(ariaSnapshotText, {
633
+ interactive: options.interactive,
634
+ maxDepth: options.maxDepth,
635
+ compact: options.compact,
636
+ });
637
+ refsMap = built.refs;
638
+ roleSnapshot = built.snapshot;
639
+ console.log(`[BROWSER] Role mode - refs require role map for resolution`);
640
+ }
641
+ // Step 2: Store refs using OpenClaw-style function (stores to BOTH WeakMap and global cache)
642
+ console.log(`[BROWSER] Snapshot generated ${Object.keys(refsMap).length} refs for targetId "${targetId}"`);
643
+ if (Object.keys(refsMap).length > 0) {
644
+ storeRoleRefsForTarget({
645
+ page,
646
+ targetId,
647
+ refs: refsMap,
648
+ frameSelector: options.frame,
649
+ mode: refsMode,
650
+ });
651
+ console.log(`[BROWSER] Stored refs with mode="${refsMode}". Sample: ${Object.keys(refsMap).slice(0, 5).join(", ")}`);
652
+ }
653
+ else {
654
+ console.log(`[BROWSER] WARNING: No refs generated from snapshot. Snapshot length: ${ariaSnapshotText.length}`);
655
+ console.log(`[BROWSER] Snapshot preview: ${ariaSnapshotText.slice(0, 500)}`);
656
+ }
657
+ // Step 4: If labels requested, create labeled screenshot using stored refs
658
+ let imagePath;
659
+ let labelsCount = 0;
660
+ if (labels && Object.keys(refsMap).length > 0) {
661
+ const maxLabels = 150;
662
+ const viewport = await page.evaluate(() => ({
663
+ scrollX: window.scrollX || 0,
664
+ scrollY: window.scrollY || 0,
665
+ width: window.innerWidth || 0,
666
+ height: window.innerHeight || 0,
667
+ }));
668
+ const refs = Object.keys(refsMap);
669
+ const boxes = [];
670
+ let skipped = 0;
671
+ // Get bounding boxes using role-based locators (OpenClaw style)
672
+ for (const ref of refs) {
673
+ if (boxes.length >= maxLabels) {
674
+ skipped += 1;
675
+ continue;
676
+ }
677
+ try {
678
+ const info = refsMap[ref];
679
+ let refLocator;
680
+ if (info.name) {
681
+ refLocator = page.getByRole(info.role, { name: info.name, exact: true });
682
+ if (info.nth !== undefined)
683
+ refLocator = refLocator.nth(info.nth);
684
+ }
685
+ else {
686
+ refLocator = page.getByRole(info.role);
687
+ if (info.nth !== undefined)
688
+ refLocator = refLocator.nth(info.nth);
689
+ }
690
+ const box = await refLocator.boundingBox();
691
+ if (!box) {
692
+ skipped += 1;
693
+ continue;
694
+ }
695
+ // Check if in viewport
696
+ const x0 = box.x;
697
+ const y0 = box.y;
698
+ const x1 = box.x + box.width;
699
+ const y1 = box.y + box.height;
700
+ const vx0 = viewport.scrollX;
701
+ const vy0 = viewport.scrollY;
702
+ const vx1 = viewport.scrollX + viewport.width;
703
+ const vy1 = viewport.scrollY + viewport.height;
704
+ if (x1 < vx0 || x0 > vx1 || y1 < vy0 || y0 > vy1) {
705
+ skipped += 1;
706
+ continue;
707
+ }
708
+ boxes.push({
709
+ ref,
710
+ x: x0 - viewport.scrollX,
711
+ y: y0 - viewport.scrollY,
712
+ w: Math.max(1, box.width),
713
+ h: Math.max(1, box.height),
714
+ });
715
+ }
716
+ catch {
717
+ skipped += 1;
718
+ }
719
+ }
720
+ labelsCount = boxes.length;
721
+ try {
722
+ if (boxes.length > 0) {
723
+ // Inject labels overlay (OpenClaw style)
724
+ await page.evaluate((labelBoxes) => {
725
+ const existing = document.querySelectorAll("[data-browser-labels]");
726
+ existing.forEach((el) => el.remove());
727
+ const root = document.createElement("div");
728
+ root.setAttribute("data-browser-labels", "1");
729
+ root.style.position = "fixed";
730
+ root.style.left = "0";
731
+ root.style.top = "0";
732
+ root.style.zIndex = "2147483647";
733
+ root.style.pointerEvents = "none";
734
+ root.style.fontFamily = '"SF Mono","SFMono-Regular",Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace';
735
+ for (const label of labelBoxes) {
736
+ const box = document.createElement("div");
737
+ box.setAttribute("data-browser-labels", "1");
738
+ box.style.position = "absolute";
739
+ box.style.left = `${label.x}px`;
740
+ box.style.top = `${label.y}px`;
741
+ box.style.width = `${label.w}px`;
742
+ box.style.height = `${label.h}px`;
743
+ box.style.border = "2px solid #ffb020";
744
+ box.style.boxSizing = "border-box";
745
+ const tag = document.createElement("div");
746
+ tag.setAttribute("data-browser-labels", "1");
747
+ tag.textContent = label.ref;
748
+ tag.style.position = "absolute";
749
+ tag.style.left = `${label.x}px`;
750
+ tag.style.top = `${Math.min(20000, Math.max(0, label.y - 18))}px`;
751
+ tag.style.background = "#ffb020";
752
+ tag.style.color = "#1a1a1a";
753
+ tag.style.fontSize = "12px";
754
+ tag.style.lineHeight = "14px";
755
+ tag.style.padding = "1px 4px";
756
+ tag.style.borderRadius = "3px";
757
+ tag.style.boxShadow = "0 1px 2px rgba(0,0,0,0.35)";
758
+ tag.style.whiteSpace = "nowrap";
759
+ root.appendChild(box);
760
+ root.appendChild(tag);
761
+ }
762
+ document.documentElement.appendChild(root);
763
+ }, boxes);
764
+ }
765
+ // Take screenshot
766
+ const screenshot = await page.screenshot({ type: "png" });
767
+ // Save to temp file
768
+ const fs = await import("fs/promises");
769
+ const path = await import("path");
770
+ const tmpDir = await import("os").then((os) => os.tmpdir());
771
+ const filename = `browser-snapshot-${Date.now()}.png`;
772
+ imagePath = path.join(tmpDir, filename);
773
+ await fs.writeFile(imagePath, screenshot);
774
+ }
775
+ finally {
776
+ // Clean up labels
777
+ await page.evaluate(() => {
778
+ const existing = document.querySelectorAll("[data-browser-labels]");
779
+ existing.forEach((el) => el.remove());
780
+ }).catch(() => { });
781
+ }
782
+ }
783
+ // Step 5: Build final snapshot text
784
+ const title = await page.title().catch(() => "");
785
+ const url = page.url();
786
+ let snapshot = `# ${title}\n\nURL: ${url}\n\n`;
787
+ if (roleSnapshot && roleSnapshot !== "(empty)") {
788
+ snapshot += "## Accessibility Tree\n";
789
+ snapshot += roleSnapshot;
790
+ snapshot += "\n\n";
791
+ }
792
+ // Truncate if needed
793
+ if (snapshot.length > maxChars) {
794
+ snapshot = snapshot.slice(0, maxChars) + "\n\n... (content truncated)";
795
+ }
796
+ return {
797
+ snapshot,
798
+ imagePath,
799
+ labelsCount,
800
+ refs: Object.keys(refsMap).length > 0 ? refsMap : undefined,
801
+ targetId,
802
+ };
803
+ }
804
+ /**
805
+ * Resolve a ref to a Playwright locator (OpenClaw-style)
806
+ * Uses stored role+name info instead of DOM attributes for stability across navigation
807
+ */
808
+ /**
809
+ * Normalize timeout to safe range (OpenClaw-style exact copy)
810
+ * From: pw-tools-core.shared.ts - uses 120s max instead of 60s
811
+ */
812
+ function normalizeTimeoutMs(timeoutMs, fallback) {
813
+ return Math.max(500, Math.min(120_000, timeoutMs ?? fallback));
814
+ }
815
+ /**
816
+ * Resolve ref to locator (OpenClaw-style)
817
+ * Reads from page's WeakMap state (restoreRoleRefsForTarget must be called first)
818
+ */
819
+ function refLocator(page, ref) {
820
+ // Normalize ref (remove @ or ref= prefix if present) - OpenClaw style
821
+ const normalized = ref.startsWith("@")
822
+ ? ref.slice(1)
823
+ : ref.startsWith("ref=")
824
+ ? ref.slice(4)
825
+ : ref;
826
+ // Check if it's an element ref (e1, e2, etc.)
827
+ if (/^e\d+$/.test(normalized)) {
828
+ // Read from page's WeakMap state (OpenClaw-style)
829
+ const pageState = pageStates.get(page);
830
+ // Handle aria mode - refs are self-resolving via aria-ref= syntax
831
+ if (pageState?.roleRefsMode === "aria") {
832
+ const scope = pageState.roleRefsFrameSelector
833
+ ? page.frameLocator(pageState.roleRefsFrameSelector)
834
+ : page;
835
+ return scope.locator(`aria-ref=${normalized}`);
836
+ }
837
+ // Role mode: Get ref info from page state
838
+ const info = pageState?.roleRefs?.[normalized];
839
+ if (!info) {
840
+ throw new Error(`Element "${normalized}" not found or not visible. ` +
841
+ `Run a new snapshot to see current page elements.`);
842
+ }
843
+ // Build locator using getByRole (OpenClaw-style)
844
+ const scope = pageState?.roleRefsFrameSelector
845
+ ? page.frameLocator(pageState.roleRefsFrameSelector)
846
+ : page;
847
+ const locAny = scope;
848
+ const locator = info.name
849
+ ? locAny.getByRole(info.role, { name: info.name, exact: true })
850
+ : locAny.getByRole(info.role);
851
+ return info.nth !== undefined ? locator.nth(info.nth) : locator;
852
+ }
853
+ // Not an element ref - treat as aria-ref (OpenClaw-style)
854
+ return page.locator(`aria-ref=${normalized}`);
855
+ }
856
+ /**
857
+ * Transform Playwright errors into AI-friendly messages (OpenClaw-style exact copy)
858
+ * From: pw-tools-core.shared.ts
859
+ */
860
+ function toAIFriendlyError(error, selector) {
861
+ const message = error instanceof Error ? error.message : String(error);
862
+ // Multiple elements matched
863
+ if (message.includes("strict mode violation")) {
864
+ const countMatch = message.match(/resolved to (\d+) elements/);
865
+ const count = countMatch ? countMatch[1] : "multiple";
866
+ return new Error(`Selector "${selector}" matched ${count} elements. ` +
867
+ `Run a new snapshot to get updated refs, or use a different ref.`);
868
+ }
869
+ // Element not found or not visible
870
+ if ((message.includes("Timeout") || message.includes("waiting for")) &&
871
+ (message.includes("to be visible") || message.includes("not visible"))) {
872
+ return new Error(`Element "${selector}" not found or not visible. ` +
873
+ `Run a new snapshot to see current page elements.`);
874
+ }
875
+ // Element covered by overlay or not interactable (OpenClaw exact)
876
+ if (message.includes("intercepts pointer events") ||
877
+ message.includes("not visible") ||
878
+ message.includes("not receive pointer events")) {
879
+ return new Error(`Element "${selector}" is not interactable (hidden or covered). ` +
880
+ `Try scrolling it into view, closing overlays, or re-snapshotting.`);
881
+ }
882
+ return error instanceof Error ? error : new Error(message);
883
+ }
884
+ /**
885
+ * Execute browser automation action (act)
886
+ */
887
+ async function executeBrowserAct(page, request, targetId = "default") {
888
+ const kind = request.kind;
889
+ // OpenClaw-style: Restore refs for this target before any action
890
+ restoreRoleRefsForTarget(page, targetId);
891
+ switch (kind) {
892
+ case "click": {
893
+ const ref = request.ref;
894
+ const doubleClick = request.doubleClick;
895
+ const button = request.button || "left";
896
+ const modifiers = request.modifiers || [];
897
+ const force = request.force;
898
+ // OpenClaw uses normalizeTimeoutMs with 8000ms default
899
+ const timeout = normalizeTimeoutMs(request.timeoutMs, 8000);
900
+ if (!ref)
901
+ throw new Error("ref is required for click action");
902
+ const locator = refLocator(page, ref);
903
+ try {
904
+ if (doubleClick) {
905
+ await locator.dblclick({
906
+ timeout,
907
+ button: button,
908
+ modifiers: modifiers,
909
+ force: force ?? false,
910
+ });
911
+ }
912
+ else {
913
+ await locator.click({
914
+ timeout,
915
+ button: button,
916
+ modifiers: modifiers,
917
+ force: force ?? false,
918
+ });
919
+ }
920
+ }
921
+ catch (err) {
922
+ throw toAIFriendlyError(err, ref);
923
+ }
924
+ return { ok: true };
925
+ }
926
+ case "type": {
927
+ const ref = request.ref;
928
+ const text = String(request.text ?? "");
929
+ const submit = request.submit;
930
+ const slowly = request.slowly;
931
+ const timeout = normalizeTimeoutMs(request.timeoutMs, 8000);
932
+ if (!ref)
933
+ throw new Error("ref is required for type action");
934
+ const locator = refLocator(page, ref);
935
+ try {
936
+ // OpenClaw: slowly mode clicks first, then types with delay
937
+ if (slowly) {
938
+ await locator.click({ timeout });
939
+ await locator.type(text, { timeout, delay: 75 });
940
+ }
941
+ else {
942
+ await locator.fill(text, { timeout });
943
+ }
944
+ if (submit) {
945
+ await locator.press("Enter", { timeout });
946
+ }
947
+ }
948
+ catch (err) {
949
+ throw toAIFriendlyError(err, ref);
950
+ }
951
+ return { ok: true };
952
+ }
953
+ case "press": {
954
+ const key = String(request.key ?? "").trim();
955
+ if (!key)
956
+ throw new Error("key is required for press action");
957
+ const delayMs = Math.max(0, Math.floor(request.delayMs ?? 0));
958
+ await page.keyboard.press(key, { delay: delayMs });
959
+ return { ok: true };
960
+ }
961
+ case "hover": {
962
+ const ref = request.ref;
963
+ const timeout = normalizeTimeoutMs(request.timeoutMs, 8000);
964
+ if (!ref)
965
+ throw new Error("ref is required for hover action");
966
+ const locator = refLocator(page, ref);
967
+ try {
968
+ await locator.hover({ timeout });
969
+ }
970
+ catch (err) {
971
+ throw toAIFriendlyError(err, ref);
972
+ }
973
+ return { ok: true };
974
+ }
975
+ case "drag": {
976
+ const startRef = request.startRef;
977
+ const endRef = request.endRef;
978
+ const timeout = normalizeTimeoutMs(request.timeoutMs, 8000);
979
+ if (!startRef)
980
+ throw new Error("startRef is required for drag action");
981
+ if (!endRef)
982
+ throw new Error("endRef is required for drag action");
983
+ const startLocator = refLocator(page, startRef);
984
+ const endLocator = refLocator(page, endRef);
985
+ try {
986
+ // OpenClaw uses dragTo() method
987
+ await startLocator.dragTo(endLocator, { timeout });
988
+ }
989
+ catch (err) {
990
+ throw toAIFriendlyError(err, `${startRef} -> ${endRef}`);
991
+ }
992
+ return { ok: true };
993
+ }
994
+ case "select": {
995
+ const ref = request.ref;
996
+ const values = request.values;
997
+ const timeout = normalizeTimeoutMs(request.timeoutMs, 8000);
998
+ if (!ref)
999
+ throw new Error("ref is required for select action");
1000
+ if (!values || !Array.isArray(values))
1001
+ throw new Error("values array is required for select action");
1002
+ const locator = refLocator(page, ref);
1003
+ try {
1004
+ await locator.selectOption(values, { timeout });
1005
+ }
1006
+ catch (err) {
1007
+ throw toAIFriendlyError(err, ref);
1008
+ }
1009
+ return { ok: true };
1010
+ }
1011
+ case "fill": {
1012
+ // OpenClaw-style form filling with checkbox/radio support
1013
+ const fields = request.fields;
1014
+ if (!fields || !Array.isArray(fields))
1015
+ throw new Error("fields array is required for fill action");
1016
+ const timeout = normalizeTimeoutMs(request.timeoutMs, 8000);
1017
+ for (const field of fields) {
1018
+ const ref = String(field.ref ?? "").trim();
1019
+ const type = String(field.type ?? "").trim();
1020
+ const rawValue = field.value;
1021
+ const value = typeof rawValue === "string"
1022
+ ? rawValue
1023
+ : typeof rawValue === "number" || typeof rawValue === "boolean"
1024
+ ? String(rawValue)
1025
+ : "";
1026
+ if (!ref)
1027
+ continue;
1028
+ const locator = refLocator(page, ref);
1029
+ try {
1030
+ // OpenClaw: handle checkbox/radio with setChecked
1031
+ if (type === "checkbox" || type === "radio") {
1032
+ const checked = rawValue === true || rawValue === 1 || rawValue === "1" || rawValue === "true";
1033
+ await locator.setChecked(checked, { timeout });
1034
+ continue;
1035
+ }
1036
+ await locator.fill(value, { timeout });
1037
+ }
1038
+ catch (err) {
1039
+ throw toAIFriendlyError(err, ref);
1040
+ }
1041
+ }
1042
+ return { ok: true };
1043
+ }
1044
+ case "resize": {
1045
+ const width = request.width;
1046
+ const height = request.height;
1047
+ await page.setViewportSize({ width, height });
1048
+ return { ok: true };
1049
+ }
1050
+ case "wait": {
1051
+ const timeMs = request.timeMs;
1052
+ const text = request.text;
1053
+ const textGone = request.textGone;
1054
+ const selector = request.selector;
1055
+ const url = request.url;
1056
+ const loadState = request.loadState;
1057
+ const fn = request.fn;
1058
+ // OpenClaw uses 20000ms default for wait (normalizeTimeoutMs uses 120s max)
1059
+ const timeout = normalizeTimeoutMs(request.timeoutMs, 20000);
1060
+ if (typeof timeMs === "number" && Number.isFinite(timeMs)) {
1061
+ // Wait for specific time
1062
+ await page.waitForTimeout(Math.max(0, timeMs));
1063
+ }
1064
+ if (text) {
1065
+ // Wait for text to appear (OpenClaw uses getByText, not waitForSelector)
1066
+ await page.getByText(text).first().waitFor({ state: "visible", timeout });
1067
+ }
1068
+ if (textGone) {
1069
+ // Wait for text to disappear
1070
+ await page.getByText(textGone).first().waitFor({ state: "hidden", timeout });
1071
+ }
1072
+ if (selector) {
1073
+ // Wait for selector
1074
+ const sel = String(selector).trim();
1075
+ if (sel) {
1076
+ await page.locator(sel).first().waitFor({ state: "visible", timeout });
1077
+ }
1078
+ }
1079
+ if (url) {
1080
+ // Wait for URL pattern
1081
+ const urlPattern = String(url).trim();
1082
+ if (urlPattern) {
1083
+ await page.waitForURL(urlPattern, { timeout });
1084
+ }
1085
+ }
1086
+ if (fn) {
1087
+ // Wait for JavaScript function to return true
1088
+ const fnStr = String(fn).trim();
1089
+ if (fnStr) {
1090
+ await page.waitForFunction(fnStr, { timeout });
1091
+ }
1092
+ }
1093
+ if (loadState) {
1094
+ // Wait for specific load state
1095
+ await page.waitForLoadState(loadState, { timeout });
1096
+ }
1097
+ return { ok: true };
1098
+ }
1099
+ case "evaluate": {
1100
+ // OpenClaw-style evaluate using Function constructor
1101
+ // This avoids esbuild adding __name helper which doesn't exist in browser
1102
+ const fnText = String(request.fn ?? "").trim();
1103
+ const ref = request.ref;
1104
+ if (!fnText)
1105
+ throw new Error("fn is required for evaluate action");
1106
+ if (ref) {
1107
+ // Evaluate with element context
1108
+ const locator = refLocator(page, ref);
1109
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
1110
+ const elementEvaluator = new Function("el", "fnBody", `
1111
+ "use strict";
1112
+ try {
1113
+ var candidate = eval("(" + fnBody + ")");
1114
+ return typeof candidate === "function" ? candidate(el) : candidate;
1115
+ } catch (err) {
1116
+ throw new Error("Invalid evaluate function: " + (err && err.message ? err.message : String(err)));
1117
+ }
1118
+ `);
1119
+ const result = await locator.evaluate(elementEvaluator, fnText);
1120
+ return { ok: true, result };
1121
+ }
1122
+ // Evaluate in page context (no element)
1123
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
1124
+ const browserEvaluator = new Function("fnBody", `
1125
+ "use strict";
1126
+ try {
1127
+ var candidate = eval("(" + fnBody + ")");
1128
+ return typeof candidate === "function" ? candidate() : candidate;
1129
+ } catch (err) {
1130
+ throw new Error("Invalid evaluate function: " + (err && err.message ? err.message : String(err)));
1131
+ }
1132
+ `);
1133
+ const result = await page.evaluate(browserEvaluator, fnText);
1134
+ return { ok: true, result };
1135
+ }
1136
+ case "close": {
1137
+ await page.close();
1138
+ return { ok: true };
1139
+ }
1140
+ default:
1141
+ throw new Error(`Unknown act kind: ${kind}`);
1142
+ }
1143
+ }
1144
+ /**
1145
+ * Create image result from file (base64 encoded)
1146
+ */
1147
+ async function imageResultFromFile(options) {
1148
+ const fs = await import("fs/promises");
1149
+ const buffer = await fs.readFile(options.path);
1150
+ const base64 = buffer.toString("base64");
1151
+ const content = [];
1152
+ if (options.extraText) {
1153
+ content.push({
1154
+ type: "text",
1155
+ text: options.extraText,
1156
+ });
1157
+ }
1158
+ content.push({
1159
+ type: "image",
1160
+ data: base64,
1161
+ mimeType: "image/png",
1162
+ });
1163
+ return {
1164
+ content,
1165
+ details: options.details,
1166
+ };
1167
+ }
1168
+ export function createBrowserTool() {
1169
+ return {
1170
+ name: "browser",
1171
+ label: "Browser",
1172
+ // OpenClaw exact description (from browser-tool.ts)
1173
+ description: [
1174
+ "Control the browser via Playwright (status/start/stop/profiles/tabs/open/snapshot/screenshot/actions).",
1175
+ "When using refs from snapshot (e.g. e12), keep the same tab: prefer passing targetId from the snapshot response into subsequent actions (act/click/type/etc).",
1176
+ 'For stable, self-resolving refs across calls, use snapshot with refs="aria" (Playwright aria-ref ids). Default refs="role" are role+name-based.',
1177
+ "Use snapshot+act for UI automation. Avoid act:wait by default; use only in exceptional cases when no reliable UI state exists.",
1178
+ ].join(" "),
1179
+ parameters: BrowserSchema,
1180
+ execute: async (_toolCallId, params) => {
1181
+ const action = readStringParam(params, "action", { required: true });
1182
+ try {
1183
+ switch (action) {
1184
+ case "status":
1185
+ return jsonResult({
1186
+ running: state.running,
1187
+ connectionMode: state.connectionMode,
1188
+ wsEndpoint: state.wsEndpoint,
1189
+ tabCount: state.pages.size,
1190
+ tabs: Array.from(state.pages.keys()),
1191
+ });
1192
+ case "start": {
1193
+ const headless = readBooleanParam(params, "headless");
1194
+ const profilePath = readStringParam(params, "profilePath");
1195
+ await startBrowser({
1196
+ headless: headless ?? undefined,
1197
+ profilePath: profilePath ?? undefined,
1198
+ });
1199
+ return jsonResult({
1200
+ running: state.running,
1201
+ connectionMode: state.connectionMode,
1202
+ message: profilePath
1203
+ ? `Browser started with profile: ${profilePath}`
1204
+ : "Browser started successfully",
1205
+ });
1206
+ }
1207
+ case "stop":
1208
+ await stopBrowser();
1209
+ return jsonResult({
1210
+ running: state.running,
1211
+ message: state.connectionMode === "connected"
1212
+ ? "Disconnected from browser"
1213
+ : "Browser stopped successfully",
1214
+ });
1215
+ case "profiles": {
1216
+ // OpenClaw has profiles - we just return a simple response
1217
+ return jsonResult({
1218
+ profiles: ["default"],
1219
+ message: "Single default profile available",
1220
+ });
1221
+ }
1222
+ case "tabs": {
1223
+ if (!state.running || state.pages.size === 0) {
1224
+ return jsonResult({ tabs: [], message: "No tabs open" });
1225
+ }
1226
+ const tabs = await Promise.all(Array.from(state.pages.entries()).map(async ([id, page]) => {
1227
+ try {
1228
+ return {
1229
+ targetId: id,
1230
+ title: await page.title(),
1231
+ url: page.url(),
1232
+ };
1233
+ }
1234
+ catch (err) {
1235
+ return {
1236
+ targetId: id,
1237
+ title: "(error)",
1238
+ url: "(error)",
1239
+ error: String(err),
1240
+ };
1241
+ }
1242
+ }));
1243
+ return jsonResult({ tabs });
1244
+ }
1245
+ case "open": {
1246
+ const targetUrl = readStringParam(params, "targetUrl", { required: true });
1247
+ const { targetId: newTargetId, page } = await openPage(targetUrl);
1248
+ return jsonResult({
1249
+ targetId: newTargetId,
1250
+ url: page.url(),
1251
+ title: await page.title(),
1252
+ message: `Opened ${targetUrl} in new tab`,
1253
+ });
1254
+ }
1255
+ case "focus": {
1256
+ const targetId = readStringParam(params, "targetId", { required: true });
1257
+ const page = state.pages.get(targetId);
1258
+ if (!page) {
1259
+ throw new Error(`Tab ${targetId} not found. Run action=tabs to see available tabs.`);
1260
+ }
1261
+ await page.bringToFront();
1262
+ return jsonResult({
1263
+ ok: true,
1264
+ targetId,
1265
+ message: `Focused tab ${targetId}`,
1266
+ });
1267
+ }
1268
+ case "navigate": {
1269
+ const targetUrl = readStringParam(params, "targetUrl", { required: true });
1270
+ const targetId = readStringParam(params, "targetId");
1271
+ let page;
1272
+ let usedTargetId;
1273
+ if (targetId) {
1274
+ const existingPage = state.pages.get(targetId);
1275
+ if (!existingPage) {
1276
+ throw new Error(`Tab ${targetId} not found. Run action=tabs to see available tabs or use action=open to create a new tab.`);
1277
+ }
1278
+ page = existingPage;
1279
+ usedTargetId = targetId;
1280
+ }
1281
+ else {
1282
+ // Use first page or create new one
1283
+ if (state.pages.size > 0) {
1284
+ const firstEntry = Array.from(state.pages.entries())[0];
1285
+ page = firstEntry[1];
1286
+ usedTargetId = firstEntry[0];
1287
+ }
1288
+ else {
1289
+ const result = await openPage(targetUrl);
1290
+ return jsonResult({
1291
+ targetId: result.targetId,
1292
+ url: result.page.url(),
1293
+ title: await result.page.title(),
1294
+ message: `Created new tab and navigated to ${targetUrl}`,
1295
+ });
1296
+ }
1297
+ }
1298
+ await page.goto(targetUrl, { waitUntil: "domcontentloaded", timeout: 30000 });
1299
+ return jsonResult({
1300
+ targetId: usedTargetId,
1301
+ url: page.url(),
1302
+ title: await page.title(),
1303
+ message: `Navigated to ${targetUrl}`,
1304
+ });
1305
+ }
1306
+ case "snapshot": {
1307
+ if (!state.running || state.pages.size === 0) {
1308
+ throw new Error("No tabs open. Use action=open to open a URL first.");
1309
+ }
1310
+ const targetId = readStringParam(params, "targetId");
1311
+ const maxChars = readNumberParam(params, "maxChars") || 50000;
1312
+ const labels = readBooleanParam(params, "labels", false);
1313
+ const refs = (readStringParam(params, "refs") || "role");
1314
+ const selector = readStringParam(params, "selector");
1315
+ const frame = readStringParam(params, "frame");
1316
+ const interactive = readBooleanParam(params, "interactive", false);
1317
+ // Use helper to get page and track last active
1318
+ const { page, usedTargetId } = getPageForAction(targetId ?? undefined);
1319
+ // OpenClaw-style: Only generate screenshot if labels explicitly requested
1320
+ const snapshotResult = await getAISnapshot(page, usedTargetId, {
1321
+ maxChars,
1322
+ labels, // Only generate screenshot when explicitly requested
1323
+ refs,
1324
+ selector,
1325
+ frame,
1326
+ interactive,
1327
+ });
1328
+ // If labels requested, return image with text
1329
+ if (labels && snapshotResult.imagePath) {
1330
+ return await imageResultFromFile({
1331
+ path: snapshotResult.imagePath,
1332
+ extraText: snapshotResult.snapshot,
1333
+ details: {
1334
+ targetId: usedTargetId,
1335
+ url: page.url(),
1336
+ title: await page.title(),
1337
+ format: "ai",
1338
+ labels: true,
1339
+ labelsCount: snapshotResult.labelsCount,
1340
+ refs: snapshotResult.refs,
1341
+ contentLength: snapshotResult.snapshot.length,
1342
+ truncated: snapshotResult.snapshot.includes("(content truncated"),
1343
+ },
1344
+ });
1345
+ }
1346
+ // Default: Return tree only (no screenshot)
1347
+ return {
1348
+ content: [
1349
+ {
1350
+ type: "text",
1351
+ text: snapshotResult.snapshot,
1352
+ },
1353
+ ],
1354
+ details: {
1355
+ targetId: usedTargetId,
1356
+ url: page.url(),
1357
+ title: await page.title(),
1358
+ format: "ai",
1359
+ refs: snapshotResult.refs,
1360
+ contentLength: snapshotResult.snapshot.length,
1361
+ truncated: snapshotResult.snapshot.includes("(content truncated"),
1362
+ },
1363
+ };
1364
+ }
1365
+ case "screenshot": {
1366
+ if (!state.running || state.pages.size === 0) {
1367
+ throw new Error("No tabs open. Use action=open to open a URL first.");
1368
+ }
1369
+ const targetId = readStringParam(params, "targetId");
1370
+ const fullPage = readBooleanParam(params, "fullPage", false);
1371
+ let page;
1372
+ let usedTargetId;
1373
+ if (targetId) {
1374
+ const existingPage = state.pages.get(targetId);
1375
+ if (!existingPage) {
1376
+ throw new Error(`Tab ${targetId} not found. Run action=tabs to see available tabs.`);
1377
+ }
1378
+ page = existingPage;
1379
+ usedTargetId = targetId;
1380
+ }
1381
+ else {
1382
+ const firstEntry = Array.from(state.pages.entries())[0];
1383
+ page = firstEntry[1];
1384
+ usedTargetId = firstEntry[0];
1385
+ }
1386
+ const screenshot = await page.screenshot({
1387
+ fullPage,
1388
+ type: "png",
1389
+ });
1390
+ // Save screenshot to temp file
1391
+ const fs = await import("fs/promises");
1392
+ const path = await import("path");
1393
+ const tmpDir = await import("os").then((os) => os.tmpdir());
1394
+ const filename = `browser-screenshot-${Date.now()}.png`;
1395
+ const filepath = path.join(tmpDir, filename);
1396
+ await fs.writeFile(filepath, screenshot);
1397
+ return await imageResultFromFile({
1398
+ path: filepath,
1399
+ details: {
1400
+ targetId: usedTargetId,
1401
+ url: page.url(),
1402
+ title: await page.title(),
1403
+ path: filepath,
1404
+ fullPage,
1405
+ },
1406
+ });
1407
+ }
1408
+ case "console": {
1409
+ const targetId = readStringParam(params, "targetId");
1410
+ const level = readStringParam(params, "level");
1411
+ let usedTargetId;
1412
+ let messages;
1413
+ if (targetId) {
1414
+ if (!state.consoleLogs.has(targetId)) {
1415
+ throw new Error(`Tab ${targetId} not found. Run action=tabs to see available tabs.`);
1416
+ }
1417
+ messages = state.consoleLogs.get(targetId);
1418
+ usedTargetId = targetId;
1419
+ }
1420
+ else {
1421
+ if (state.pages.size === 0) {
1422
+ throw new Error("No tabs open. Use action=open to open a URL first.");
1423
+ }
1424
+ const firstId = Array.from(state.pages.keys())[0];
1425
+ messages = state.consoleLogs.get(firstId) || [];
1426
+ usedTargetId = firstId;
1427
+ }
1428
+ // Filter by level if specified
1429
+ if (level) {
1430
+ messages = messages.filter((msg) => msg.type() === level);
1431
+ }
1432
+ const formattedMessages = messages.map((msg) => ({
1433
+ type: msg.type(),
1434
+ text: msg.text(),
1435
+ location: msg.location(),
1436
+ }));
1437
+ return jsonResult({
1438
+ ok: true,
1439
+ targetId: usedTargetId,
1440
+ messages: formattedMessages,
1441
+ });
1442
+ }
1443
+ case "pdf": {
1444
+ const targetId = readStringParam(params, "targetId");
1445
+ let page;
1446
+ let usedTargetId;
1447
+ if (targetId) {
1448
+ const existingPage = state.pages.get(targetId);
1449
+ if (!existingPage) {
1450
+ throw new Error(`Tab ${targetId} not found. Run action=tabs to see available tabs.`);
1451
+ }
1452
+ page = existingPage;
1453
+ usedTargetId = targetId;
1454
+ }
1455
+ else {
1456
+ if (state.pages.size === 0) {
1457
+ throw new Error("No tabs open. Use action=open to open a URL first.");
1458
+ }
1459
+ const firstEntry = Array.from(state.pages.entries())[0];
1460
+ page = firstEntry[1];
1461
+ usedTargetId = firstEntry[0];
1462
+ }
1463
+ const path = await import("path");
1464
+ const tmpDir = await import("os").then((os) => os.tmpdir());
1465
+ const filename = `browser-pdf-${Date.now()}.pdf`;
1466
+ const filepath = path.join(tmpDir, filename);
1467
+ await page.pdf({
1468
+ path: filepath,
1469
+ format: "A4",
1470
+ });
1471
+ return {
1472
+ content: [
1473
+ {
1474
+ type: "text",
1475
+ text: `PDF saved to ${filepath}`,
1476
+ },
1477
+ ],
1478
+ details: {
1479
+ ok: true,
1480
+ targetId: usedTargetId,
1481
+ path: filepath,
1482
+ },
1483
+ };
1484
+ }
1485
+ case "upload": {
1486
+ const paths = readArrayParam(params, "paths", { required: true });
1487
+ const targetId = readStringParam(params, "targetId");
1488
+ const timeoutMs = readNumberParam(params, "timeoutMs") || 30000;
1489
+ let page;
1490
+ let usedTargetId;
1491
+ if (targetId) {
1492
+ const existingPage = state.pages.get(targetId);
1493
+ if (!existingPage) {
1494
+ throw new Error(`Tab ${targetId} not found. Run action=tabs to see available tabs.`);
1495
+ }
1496
+ page = existingPage;
1497
+ usedTargetId = targetId;
1498
+ }
1499
+ else {
1500
+ if (state.pages.size === 0) {
1501
+ throw new Error("No tabs open. Use action=open to open a URL first.");
1502
+ }
1503
+ const firstEntry = Array.from(state.pages.entries())[0];
1504
+ page = firstEntry[1];
1505
+ usedTargetId = firstEntry[0];
1506
+ }
1507
+ // Set up file chooser handler
1508
+ const fileChooserPromise = page.waitForEvent("filechooser", { timeout: timeoutMs });
1509
+ // Wait for file chooser to appear (user must trigger it)
1510
+ const fileChooser = await fileChooserPromise;
1511
+ await fileChooser.setFiles(paths);
1512
+ return jsonResult({
1513
+ ok: true,
1514
+ targetId: usedTargetId,
1515
+ filesUploaded: paths.length,
1516
+ message: `File chooser armed and files uploaded: ${paths.join(", ")}`,
1517
+ });
1518
+ }
1519
+ case "dialog": {
1520
+ const accept = readBooleanParam(params, "accept", true);
1521
+ const promptText = readStringParam(params, "promptText");
1522
+ const targetId = readStringParam(params, "targetId");
1523
+ const timeoutMs = readNumberParam(params, "timeoutMs") || 30000;
1524
+ let page;
1525
+ let usedTargetId;
1526
+ if (targetId) {
1527
+ const existingPage = state.pages.get(targetId);
1528
+ if (!existingPage) {
1529
+ throw new Error(`Tab ${targetId} not found. Run action=tabs to see available tabs.`);
1530
+ }
1531
+ page = existingPage;
1532
+ usedTargetId = targetId;
1533
+ }
1534
+ else {
1535
+ if (state.pages.size === 0) {
1536
+ throw new Error("No tabs open. Use action=open to open a URL first.");
1537
+ }
1538
+ const firstEntry = Array.from(state.pages.entries())[0];
1539
+ page = firstEntry[1];
1540
+ usedTargetId = firstEntry[0];
1541
+ }
1542
+ // Set up dialog handler
1543
+ const dialogPromise = page.waitForEvent("dialog", { timeout: timeoutMs });
1544
+ // Wait for dialog to appear
1545
+ const dialog = await dialogPromise;
1546
+ if (accept) {
1547
+ await dialog.accept(promptText);
1548
+ }
1549
+ else {
1550
+ await dialog.dismiss();
1551
+ }
1552
+ return jsonResult({
1553
+ ok: true,
1554
+ targetId: usedTargetId,
1555
+ dialogType: dialog.type(),
1556
+ dialogMessage: dialog.message(),
1557
+ accepted: accept,
1558
+ });
1559
+ }
1560
+ case "close": {
1561
+ const targetId = readStringParam(params, "targetId");
1562
+ if (!targetId) {
1563
+ throw new Error("targetId is required for close action. Run action=tabs to see available targetIds.");
1564
+ }
1565
+ const page = state.pages.get(targetId);
1566
+ if (!page) {
1567
+ throw new Error(`Tab ${targetId} not found. Run action=tabs to see available tabs.`);
1568
+ }
1569
+ await page.close();
1570
+ state.pages.delete(targetId);
1571
+ state.consoleLogs.delete(targetId);
1572
+ return jsonResult({
1573
+ targetId,
1574
+ message: `Closed tab ${targetId}`,
1575
+ remainingTabs: state.pages.size,
1576
+ });
1577
+ }
1578
+ case "act": {
1579
+ // Support both OpenClaw-style (request object) and direct parameters
1580
+ const request = params.request;
1581
+ const actParams = request || params;
1582
+ // Check if we have act parameters (either kind or any act-specific param)
1583
+ if (!actParams.kind && !actParams.ref && !actParams.text && !actParams.key) {
1584
+ throw new Error("act action requires 'kind' parameter or use 'request' object with act parameters");
1585
+ }
1586
+ const targetId = readStringParam(actParams, "targetId");
1587
+ // Use helper to get page and track last active
1588
+ const { page, usedTargetId } = getPageForAction(targetId ?? undefined);
1589
+ const result = await executeBrowserAct(page, actParams, usedTargetId);
1590
+ return jsonResult({
1591
+ ok: result.ok,
1592
+ targetId: usedTargetId,
1593
+ url: page.url(),
1594
+ result: result.result,
1595
+ });
1596
+ }
1597
+ default:
1598
+ throw new Error(`Unknown action: ${action}. Valid actions: ${BROWSER_TOOL_ACTIONS.join(", ")}`);
1599
+ }
1600
+ }
1601
+ catch (error) {
1602
+ const message = error instanceof Error ? error.message : String(error);
1603
+ console.error(`[BROWSER] Error in action ${action}:`, message);
1604
+ // Return structured error
1605
+ return {
1606
+ content: [
1607
+ {
1608
+ type: "text",
1609
+ text: `Browser error in action "${action}": ${message}`,
1610
+ },
1611
+ ],
1612
+ details: {
1613
+ error: "browser_error",
1614
+ action,
1615
+ message,
1616
+ },
1617
+ };
1618
+ }
1619
+ },
1620
+ };
1621
+ }
1622
+ // Cleanup on process exit
1623
+ process.on("SIGINT", async () => {
1624
+ await stopBrowser();
1625
+ });
1626
+ process.on("SIGTERM", async () => {
1627
+ await stopBrowser();
1628
+ });
1629
+ //# sourceMappingURL=browser.js.map