explorbot 0.0.1 → 0.1.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 (423) hide show
  1. package/README.md +80 -26
  2. package/bin/explorbot-cli.ts +680 -0
  3. package/boat/api-tester/src/ai/chief/styles.ts +15 -0
  4. package/boat/api-tester/src/ai/chief.ts +335 -0
  5. package/boat/api-tester/src/ai/curler-tools.ts +278 -0
  6. package/boat/api-tester/src/ai/curler.ts +306 -0
  7. package/boat/api-tester/src/api-client.ts +28 -0
  8. package/boat/api-tester/src/apibot.ts +203 -0
  9. package/boat/api-tester/src/cli.ts +301 -0
  10. package/boat/api-tester/src/config.ts +190 -0
  11. package/dist/bin/explorbot-cli.js +23 -101
  12. package/dist/boat/api-tester/bin/apibot-cli.js +0 -1
  13. package/dist/boat/api-tester/src/ai/chief/styles.js +0 -1
  14. package/dist/boat/api-tester/src/ai/chief.js +0 -1
  15. package/dist/boat/api-tester/src/ai/curler-tools.js +0 -1
  16. package/dist/boat/api-tester/src/ai/curler.js +0 -1
  17. package/dist/boat/api-tester/src/api-client.js +0 -1
  18. package/dist/boat/api-tester/src/apibot.js +0 -1
  19. package/dist/boat/api-tester/src/cli.js +0 -1
  20. package/dist/boat/api-tester/src/config.js +0 -1
  21. package/dist/src/action-result.js +0 -1
  22. package/dist/src/action.js +14 -12
  23. package/dist/src/activity.js +0 -1
  24. package/dist/src/ai/agent.js +0 -1
  25. package/dist/src/ai/bosun.js +0 -1
  26. package/dist/src/ai/captain/idle-mode.js +0 -1
  27. package/dist/src/ai/captain/mixin.js +0 -1
  28. package/dist/src/ai/captain/test-mode.js +0 -1
  29. package/dist/src/ai/captain/web-mode.js +0 -1
  30. package/dist/src/ai/captain.js +0 -1
  31. package/dist/src/ai/conversation.js +0 -1
  32. package/dist/src/ai/experience-compactor.js +0 -1
  33. package/dist/src/ai/fisherman-tools.js +0 -1
  34. package/dist/src/ai/fisherman.js +0 -1
  35. package/dist/src/ai/historian.js +0 -1
  36. package/dist/src/ai/navigator.js +0 -1
  37. package/dist/src/ai/pilot.js +0 -1
  38. package/dist/src/ai/planner/session-dedup.js +0 -1
  39. package/dist/src/ai/planner/styles.js +0 -1
  40. package/dist/src/ai/planner/subpages.js +42 -7
  41. package/dist/src/ai/planner.js +15 -4
  42. package/dist/src/ai/provider.js +0 -1
  43. package/dist/src/ai/quartermaster.js +0 -1
  44. package/dist/src/ai/researcher/cache.js +13 -9
  45. package/dist/src/ai/researcher/coordinates.js +4 -3
  46. package/dist/src/ai/researcher/deep-analysis.js +16 -20
  47. package/dist/src/ai/researcher/fingerprint-worker.js +0 -1
  48. package/dist/src/ai/researcher/focus.js +0 -1
  49. package/dist/src/ai/researcher/locators.js +1 -2
  50. package/dist/src/ai/researcher/mixin.js +0 -1
  51. package/dist/src/ai/researcher/parser.js +4 -4
  52. package/dist/src/ai/researcher/research-result.js +2 -1
  53. package/dist/src/ai/researcher.js +6 -6
  54. package/dist/src/ai/rules.js +0 -1
  55. package/dist/src/ai/task-agent.js +0 -1
  56. package/dist/src/ai/tester.js +0 -1
  57. package/dist/src/ai/tools.js +4 -1
  58. package/dist/src/api/api-client.js +0 -1
  59. package/dist/src/api/request-result.js +0 -1
  60. package/dist/src/api/request-store.js +0 -1
  61. package/dist/src/api/spec-reader.js +0 -1
  62. package/dist/src/api/xhr-capture.js +0 -1
  63. package/dist/src/browser-server.js +0 -1
  64. package/dist/src/command-handler.js +0 -1
  65. package/dist/src/commands/add-rule-command.js +0 -1
  66. package/dist/src/commands/base-command.js +0 -1
  67. package/dist/src/commands/clean-command.js +0 -1
  68. package/dist/src/commands/context-aria-command.js +0 -1
  69. package/dist/src/commands/context-command.js +2 -3
  70. package/dist/src/commands/context-data-command.js +0 -1
  71. package/dist/src/commands/context-experience-command.js +0 -1
  72. package/dist/src/commands/context-html-command.js +0 -1
  73. package/dist/src/commands/context-knowledge-command.js +0 -1
  74. package/dist/src/commands/debug-command.js +0 -1
  75. package/dist/src/commands/drill-command.js +0 -1
  76. package/dist/src/commands/exit-command.js +0 -1
  77. package/dist/src/commands/explore-command.js +3 -3
  78. package/dist/src/commands/freesail-command.js +0 -1
  79. package/dist/src/commands/help-command.js +0 -1
  80. package/dist/src/commands/index.js +0 -1
  81. package/dist/src/commands/init-command.js +117 -0
  82. package/dist/src/commands/knows-command.js +0 -1
  83. package/dist/src/commands/learn-command.js +0 -1
  84. package/dist/src/commands/navigate-command.js +0 -1
  85. package/dist/src/commands/path-command.js +0 -1
  86. package/dist/src/commands/plan-clear-command.js +0 -1
  87. package/dist/src/commands/plan-command.js +6 -2
  88. package/dist/src/commands/plan-edit-command.js +0 -1
  89. package/dist/src/commands/plan-load-command.js +0 -1
  90. package/dist/src/commands/plan-reload-command.js +0 -1
  91. package/dist/src/commands/plan-save-command.js +0 -1
  92. package/dist/src/commands/research-command.js +0 -1
  93. package/dist/src/commands/start-command.js +0 -1
  94. package/dist/src/commands/status-command.js +0 -1
  95. package/dist/src/commands/test-command.js +0 -1
  96. package/dist/src/components/ActivityPane.js +0 -1
  97. package/dist/src/components/AddKnowledge.js +0 -1
  98. package/dist/src/components/AddRule.js +0 -1
  99. package/dist/src/components/App.js +0 -1
  100. package/dist/src/components/Autocomplete.js +0 -1
  101. package/dist/src/components/InputPane.js +0 -1
  102. package/dist/src/components/InputReadline.js +0 -1
  103. package/dist/src/components/LogPane.js +0 -1
  104. package/dist/src/components/PlanEditor.js +0 -1
  105. package/dist/src/components/PlanPane.js +0 -1
  106. package/dist/src/components/SessionTimer.js +0 -1
  107. package/dist/src/components/StateTransitionPane.js +0 -1
  108. package/dist/src/components/StatusPane.js +0 -1
  109. package/dist/src/components/TaskPane.js +0 -1
  110. package/dist/src/components/Welcome.js +0 -1
  111. package/dist/src/components/WelcomeChecklist.js +0 -1
  112. package/dist/src/components/WelcomeCommands.js +0 -1
  113. package/dist/src/components/autocomplete-store.js +0 -1
  114. package/dist/src/components/parse-keypress.js +0 -1
  115. package/dist/src/config.js +0 -1
  116. package/dist/src/execution-controller.js +0 -1
  117. package/dist/src/experience-tracker.js +0 -1
  118. package/dist/src/explorbot.js +1 -2
  119. package/dist/src/explorer.js +58 -17
  120. package/dist/src/index.js +0 -1
  121. package/dist/src/knowledge-tracker.js +2 -2
  122. package/dist/src/observability.js +0 -1
  123. package/dist/src/reporter.js +0 -1
  124. package/dist/src/state-manager.js +0 -1
  125. package/dist/src/stats.js +0 -1
  126. package/dist/src/test-plan.js +0 -1
  127. package/dist/src/utils/aria.js +0 -1
  128. package/dist/src/utils/cli-name.js +16 -0
  129. package/dist/src/utils/code-extractor.js +0 -1
  130. package/dist/src/utils/context-formatter.js +0 -1
  131. package/dist/src/utils/error-page.js +0 -1
  132. package/dist/src/utils/expandable.js +0 -1
  133. package/dist/src/utils/hooks-runner.js +0 -1
  134. package/dist/src/utils/html-diff.js +0 -1
  135. package/dist/src/utils/html.js +0 -1
  136. package/dist/src/utils/logger.js +0 -1
  137. package/dist/src/utils/loop.js +0 -1
  138. package/dist/src/utils/markdown-parser.js +0 -1
  139. package/dist/src/utils/markdown-query.js +0 -1
  140. package/dist/src/utils/markdown-terminal.js +0 -1
  141. package/dist/src/utils/research-parser.js +0 -1
  142. package/dist/src/utils/retry.js +0 -1
  143. package/dist/src/utils/rules-loader.js +0 -1
  144. package/dist/src/utils/strings.js +0 -1
  145. package/dist/src/utils/test-plan-markdown.js +0 -1
  146. package/dist/src/utils/throttle.js +0 -1
  147. package/dist/src/utils/unique-names.js +0 -1
  148. package/dist/src/utils/url-matcher.js +0 -1
  149. package/dist/src/utils/web-element.js +6 -5
  150. package/dist/src/utils/xpath.js +0 -1
  151. package/package.json +28 -4
  152. package/src/action-result.ts +694 -0
  153. package/src/action.ts +449 -0
  154. package/src/activity.ts +111 -0
  155. package/src/ai/agent.ts +3 -0
  156. package/src/ai/bosun.ts +557 -0
  157. package/src/ai/captain/idle-mode.ts +116 -0
  158. package/src/ai/captain/mixin.ts +22 -0
  159. package/src/ai/captain/test-mode.ts +262 -0
  160. package/src/ai/captain/web-mode.ts +136 -0
  161. package/src/ai/captain.ts +504 -0
  162. package/src/ai/conversation.ts +205 -0
  163. package/src/ai/experience-compactor.ts +284 -0
  164. package/src/ai/fisherman-tools.ts +181 -0
  165. package/src/ai/fisherman.ts +223 -0
  166. package/src/ai/historian.ts +457 -0
  167. package/src/ai/navigator.ts +572 -0
  168. package/src/ai/pilot.ts +776 -0
  169. package/src/ai/planner/session-dedup.ts +35 -0
  170. package/src/ai/planner/styles.ts +17 -0
  171. package/src/ai/planner/subpages.ts +171 -0
  172. package/src/ai/planner.ts +549 -0
  173. package/src/ai/provider.ts +613 -0
  174. package/src/ai/quartermaster.ts +286 -0
  175. package/src/ai/researcher/cache.ts +109 -0
  176. package/src/ai/researcher/coordinates.ts +239 -0
  177. package/src/ai/researcher/deep-analysis.ts +412 -0
  178. package/src/ai/researcher/fingerprint-worker.ts +59 -0
  179. package/src/ai/researcher/focus.ts +42 -0
  180. package/src/ai/researcher/locators.ts +282 -0
  181. package/src/ai/researcher/mixin.ts +4 -0
  182. package/src/ai/researcher/parser.ts +186 -0
  183. package/src/ai/researcher/research-result.ts +116 -0
  184. package/src/ai/researcher.ts +858 -0
  185. package/src/ai/rules.ts +376 -0
  186. package/src/ai/task-agent.ts +141 -0
  187. package/src/ai/tester.ts +939 -0
  188. package/src/ai/tools.ts +1122 -0
  189. package/src/api/api-client.ts +109 -0
  190. package/src/api/request-result.ts +212 -0
  191. package/src/api/request-store.ts +130 -0
  192. package/src/api/spec-reader.ts +174 -0
  193. package/src/api/xhr-capture.ts +100 -0
  194. package/src/browser-server.ts +74 -0
  195. package/src/command-handler.ts +454 -0
  196. package/src/commands/add-rule-command.ts +63 -0
  197. package/src/commands/base-command.ts +27 -0
  198. package/src/commands/clean-command.ts +73 -0
  199. package/src/commands/context-aria-command.ts +22 -0
  200. package/src/commands/context-command.ts +67 -0
  201. package/src/commands/context-data-command.ts +30 -0
  202. package/src/commands/context-experience-command.ts +48 -0
  203. package/src/commands/context-html-command.ts +33 -0
  204. package/src/commands/context-knowledge-command.ts +43 -0
  205. package/src/commands/debug-command.ts +13 -0
  206. package/src/commands/drill-command.ts +34 -0
  207. package/src/commands/exit-command.ts +32 -0
  208. package/src/commands/explore-command.ts +129 -0
  209. package/src/commands/freesail-command.ts +95 -0
  210. package/src/commands/help-command.ts +8 -0
  211. package/src/commands/index.ts +69 -0
  212. package/src/commands/init-command.ts +131 -0
  213. package/src/commands/knows-command.ts +68 -0
  214. package/src/commands/learn-command.ts +44 -0
  215. package/src/commands/navigate-command.ts +18 -0
  216. package/src/commands/path-command.ts +83 -0
  217. package/src/commands/plan-clear-command.ts +14 -0
  218. package/src/commands/plan-command.ts +46 -0
  219. package/src/commands/plan-edit-command.ts +9 -0
  220. package/src/commands/plan-load-command.ts +18 -0
  221. package/src/commands/plan-reload-command.ts +28 -0
  222. package/src/commands/plan-save-command.ts +25 -0
  223. package/src/commands/research-command.ts +45 -0
  224. package/src/commands/start-command.ts +13 -0
  225. package/src/commands/status-command.tsx +23 -0
  226. package/src/commands/test-command.ts +84 -0
  227. package/src/components/ActivityPane.tsx +80 -0
  228. package/src/components/AddKnowledge.tsx +169 -0
  229. package/src/components/AddRule.tsx +174 -0
  230. package/src/components/App.tsx +377 -0
  231. package/src/components/Autocomplete.tsx +63 -0
  232. package/src/components/InputPane.tsx +259 -0
  233. package/src/components/InputReadline.tsx +704 -0
  234. package/src/components/LogPane.tsx +187 -0
  235. package/src/components/PlanEditor.tsx +150 -0
  236. package/src/components/PlanPane.tsx +71 -0
  237. package/src/components/SessionTimer.tsx +35 -0
  238. package/src/components/StateTransitionPane.tsx +149 -0
  239. package/src/components/StatusPane.tsx +62 -0
  240. package/src/components/TaskPane.tsx +119 -0
  241. package/src/components/Welcome.tsx +83 -0
  242. package/src/components/WelcomeChecklist.tsx +118 -0
  243. package/src/components/WelcomeCommands.tsx +102 -0
  244. package/src/components/autocomplete-store.ts +35 -0
  245. package/src/components/parse-keypress.ts +170 -0
  246. package/src/config.ts +491 -0
  247. package/src/execution-controller.ts +109 -0
  248. package/src/experience-tracker.ts +350 -0
  249. package/src/explorbot.ts +405 -0
  250. package/src/explorer.ts +760 -0
  251. package/src/index.tsx +62 -0
  252. package/src/knowledge-tracker.ts +230 -0
  253. package/src/observability.ts +150 -0
  254. package/src/reporter.ts +224 -0
  255. package/src/state-manager.ts +556 -0
  256. package/src/stats.ts +53 -0
  257. package/src/test-plan.ts +432 -0
  258. package/src/utils/aria.ts +629 -0
  259. package/src/utils/cli-name.ts +13 -0
  260. package/src/utils/code-extractor.ts +22 -0
  261. package/src/utils/context-formatter.ts +239 -0
  262. package/src/utils/error-page.ts +23 -0
  263. package/src/utils/expandable.ts +38 -0
  264. package/src/utils/hooks-runner.ts +79 -0
  265. package/src/utils/html-diff.ts +918 -0
  266. package/src/utils/html.ts +1316 -0
  267. package/src/utils/logger.ts +534 -0
  268. package/src/utils/loop.ts +176 -0
  269. package/src/utils/markdown-parser.ts +127 -0
  270. package/src/utils/markdown-query.ts +466 -0
  271. package/src/utils/markdown-terminal.ts +43 -0
  272. package/src/utils/research-parser.ts +11 -0
  273. package/src/utils/retry.ts +73 -0
  274. package/src/utils/rules-loader.ts +118 -0
  275. package/src/utils/strings.ts +13 -0
  276. package/src/utils/test-plan-markdown.ts +332 -0
  277. package/src/utils/throttle.ts +18 -0
  278. package/src/utils/unique-names.ts +14 -0
  279. package/src/utils/url-matcher.ts +45 -0
  280. package/src/utils/web-element.ts +147 -0
  281. package/src/utils/xpath.ts +129 -0
  282. package/dist/bin/explorbot-cli.js.map +0 -1
  283. package/dist/boat/api-tester/bin/apibot-cli.js.map +0 -1
  284. package/dist/boat/api-tester/example/apibot.config.js +0 -31
  285. package/dist/boat/api-tester/example/apibot.config.js.map +0 -1
  286. package/dist/boat/api-tester/src/ai/chief/styles.js.map +0 -1
  287. package/dist/boat/api-tester/src/ai/chief.js.map +0 -1
  288. package/dist/boat/api-tester/src/ai/curler-tools.js.map +0 -1
  289. package/dist/boat/api-tester/src/ai/curler.js.map +0 -1
  290. package/dist/boat/api-tester/src/api-client.js.map +0 -1
  291. package/dist/boat/api-tester/src/apibot.js.map +0 -1
  292. package/dist/boat/api-tester/src/cli.js.map +0 -1
  293. package/dist/boat/api-tester/src/config.js.map +0 -1
  294. package/dist/prompts/audit-rules.md +0 -124
  295. package/dist/src/action-result.js.map +0 -1
  296. package/dist/src/action.js.map +0 -1
  297. package/dist/src/activity.js.map +0 -1
  298. package/dist/src/ai/agent.js.map +0 -1
  299. package/dist/src/ai/bosun.js.map +0 -1
  300. package/dist/src/ai/captain/idle-mode.js.map +0 -1
  301. package/dist/src/ai/captain/mixin.js.map +0 -1
  302. package/dist/src/ai/captain/test-mode.js.map +0 -1
  303. package/dist/src/ai/captain/web-mode.js.map +0 -1
  304. package/dist/src/ai/captain.js.map +0 -1
  305. package/dist/src/ai/conversation.js.map +0 -1
  306. package/dist/src/ai/experience-compactor.js.map +0 -1
  307. package/dist/src/ai/fisherman-tools.js.map +0 -1
  308. package/dist/src/ai/fisherman.js.map +0 -1
  309. package/dist/src/ai/historian.js.map +0 -1
  310. package/dist/src/ai/navigator.js.map +0 -1
  311. package/dist/src/ai/pilot.js.map +0 -1
  312. package/dist/src/ai/planner/session-dedup.js.map +0 -1
  313. package/dist/src/ai/planner/styles.js.map +0 -1
  314. package/dist/src/ai/planner/subpages.js.map +0 -1
  315. package/dist/src/ai/planner.js.map +0 -1
  316. package/dist/src/ai/provider.js.map +0 -1
  317. package/dist/src/ai/quartermaster.js.map +0 -1
  318. package/dist/src/ai/researcher/cache.js.map +0 -1
  319. package/dist/src/ai/researcher/coordinates.js.map +0 -1
  320. package/dist/src/ai/researcher/deep-analysis.js.map +0 -1
  321. package/dist/src/ai/researcher/fingerprint-worker.js.map +0 -1
  322. package/dist/src/ai/researcher/focus.js.map +0 -1
  323. package/dist/src/ai/researcher/locators.js.map +0 -1
  324. package/dist/src/ai/researcher/mixin.js.map +0 -1
  325. package/dist/src/ai/researcher/parser.js.map +0 -1
  326. package/dist/src/ai/researcher/research-result.js.map +0 -1
  327. package/dist/src/ai/researcher.js.map +0 -1
  328. package/dist/src/ai/rules.js.map +0 -1
  329. package/dist/src/ai/task-agent.js.map +0 -1
  330. package/dist/src/ai/tester.js.map +0 -1
  331. package/dist/src/ai/tools.js.map +0 -1
  332. package/dist/src/api/api-client.js.map +0 -1
  333. package/dist/src/api/request-result.js.map +0 -1
  334. package/dist/src/api/request-store.js.map +0 -1
  335. package/dist/src/api/spec-reader.js.map +0 -1
  336. package/dist/src/api/xhr-capture.js.map +0 -1
  337. package/dist/src/browser-server.js.map +0 -1
  338. package/dist/src/command-handler.js.map +0 -1
  339. package/dist/src/commands/add-rule-command.js.map +0 -1
  340. package/dist/src/commands/base-command.js.map +0 -1
  341. package/dist/src/commands/clean-command.js.map +0 -1
  342. package/dist/src/commands/context-aria-command.js.map +0 -1
  343. package/dist/src/commands/context-command.js.map +0 -1
  344. package/dist/src/commands/context-data-command.js.map +0 -1
  345. package/dist/src/commands/context-experience-command.js.map +0 -1
  346. package/dist/src/commands/context-html-command.js.map +0 -1
  347. package/dist/src/commands/context-knowledge-command.js.map +0 -1
  348. package/dist/src/commands/debug-command.js.map +0 -1
  349. package/dist/src/commands/drill-command.js.map +0 -1
  350. package/dist/src/commands/exit-command.js.map +0 -1
  351. package/dist/src/commands/explore-command.js.map +0 -1
  352. package/dist/src/commands/freesail-command.js.map +0 -1
  353. package/dist/src/commands/help-command.js.map +0 -1
  354. package/dist/src/commands/index.js.map +0 -1
  355. package/dist/src/commands/knows-command.js.map +0 -1
  356. package/dist/src/commands/learn-command.js.map +0 -1
  357. package/dist/src/commands/navigate-command.js.map +0 -1
  358. package/dist/src/commands/path-command.js.map +0 -1
  359. package/dist/src/commands/plan-clear-command.js.map +0 -1
  360. package/dist/src/commands/plan-command.js.map +0 -1
  361. package/dist/src/commands/plan-edit-command.js.map +0 -1
  362. package/dist/src/commands/plan-load-command.js.map +0 -1
  363. package/dist/src/commands/plan-reload-command.js.map +0 -1
  364. package/dist/src/commands/plan-save-command.js.map +0 -1
  365. package/dist/src/commands/research-command.js.map +0 -1
  366. package/dist/src/commands/start-command.js.map +0 -1
  367. package/dist/src/commands/status-command.js.map +0 -1
  368. package/dist/src/commands/test-command.js.map +0 -1
  369. package/dist/src/components/ActivityPane.js.map +0 -1
  370. package/dist/src/components/AddKnowledge.js.map +0 -1
  371. package/dist/src/components/AddRule.js.map +0 -1
  372. package/dist/src/components/App.js.map +0 -1
  373. package/dist/src/components/Autocomplete.js.map +0 -1
  374. package/dist/src/components/InputPane.js.map +0 -1
  375. package/dist/src/components/InputReadline.js.map +0 -1
  376. package/dist/src/components/LogPane.js.map +0 -1
  377. package/dist/src/components/PlanEditor.js.map +0 -1
  378. package/dist/src/components/PlanPane.js.map +0 -1
  379. package/dist/src/components/SessionTimer.js.map +0 -1
  380. package/dist/src/components/StateTransitionPane.js.map +0 -1
  381. package/dist/src/components/StatusPane.js.map +0 -1
  382. package/dist/src/components/TaskPane.js.map +0 -1
  383. package/dist/src/components/Welcome.js.map +0 -1
  384. package/dist/src/components/WelcomeChecklist.js.map +0 -1
  385. package/dist/src/components/WelcomeCommands.js.map +0 -1
  386. package/dist/src/components/autocomplete-store.js.map +0 -1
  387. package/dist/src/components/parse-keypress.js.map +0 -1
  388. package/dist/src/config.js.map +0 -1
  389. package/dist/src/execution-controller.js.map +0 -1
  390. package/dist/src/experience-tracker.js.map +0 -1
  391. package/dist/src/explorbot.js.map +0 -1
  392. package/dist/src/explorer.js.map +0 -1
  393. package/dist/src/index.js.map +0 -1
  394. package/dist/src/knowledge-tracker.js.map +0 -1
  395. package/dist/src/observability.js.map +0 -1
  396. package/dist/src/reporter.js.map +0 -1
  397. package/dist/src/state-manager.js.map +0 -1
  398. package/dist/src/stats.js.map +0 -1
  399. package/dist/src/test-plan.js.map +0 -1
  400. package/dist/src/utils/aria.js.map +0 -1
  401. package/dist/src/utils/code-extractor.js.map +0 -1
  402. package/dist/src/utils/context-formatter.js.map +0 -1
  403. package/dist/src/utils/error-page.js.map +0 -1
  404. package/dist/src/utils/expandable.js.map +0 -1
  405. package/dist/src/utils/hooks-runner.js.map +0 -1
  406. package/dist/src/utils/html-diff.js.map +0 -1
  407. package/dist/src/utils/html.js.map +0 -1
  408. package/dist/src/utils/logger.js.map +0 -1
  409. package/dist/src/utils/loop.js.map +0 -1
  410. package/dist/src/utils/markdown-parser.js.map +0 -1
  411. package/dist/src/utils/markdown-query.js.map +0 -1
  412. package/dist/src/utils/markdown-terminal.js.map +0 -1
  413. package/dist/src/utils/research-parser.js.map +0 -1
  414. package/dist/src/utils/retry.js.map +0 -1
  415. package/dist/src/utils/rules-loader.js.map +0 -1
  416. package/dist/src/utils/strings.js.map +0 -1
  417. package/dist/src/utils/test-plan-markdown.js.map +0 -1
  418. package/dist/src/utils/throttle.js.map +0 -1
  419. package/dist/src/utils/unique-names.js.map +0 -1
  420. package/dist/src/utils/url-matcher.js.map +0 -1
  421. package/dist/src/utils/web-element.js.map +0 -1
  422. package/dist/src/utils/xpath.js.map +0 -1
  423. package/prompts/audit-rules.md +0 -124
package/src/action.ts ADDED
@@ -0,0 +1,449 @@
1
+ import fs from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { context, trace } from '@opentelemetry/api';
4
+ import { highlight } from 'cli-highlight';
5
+ import { container, recorder } from 'codeceptjs';
6
+ import * as codeceptjs from 'codeceptjs';
7
+ import { hopeThat, retryTo, tryTo, within } from 'codeceptjs/lib/effects';
8
+ import step from 'codeceptjs/steps';
9
+ import dedent from 'dedent';
10
+ import { ActionResult } from './action-result.js';
11
+ import { clearActivity, setActivity } from './activity.ts';
12
+ import { ExperienceCompactor } from './ai/experience-compactor.js';
13
+ import { Navigator } from './ai/navigator.js';
14
+ import type { Provider } from './ai/provider.js';
15
+ import { ConfigParser, outputPath } from './config.js';
16
+ import type { ExplorbotConfig } from './config.js';
17
+ import type { UserResolveFunction } from './explorbot.ts';
18
+ import { Observability } from './observability.ts';
19
+ import type { StateManager } from './state-manager.js';
20
+ import { extractCodeBlocks } from './utils/code-extractor.js';
21
+ import { htmlCombinedSnapshot, minifyHtml } from './utils/html.js';
22
+ import { createDebug, log, setStepSpanParent, tag } from './utils/logger.js';
23
+ import { throttle } from './utils/throttle.ts';
24
+
25
+ const debugLog = createDebug('explorbot:action');
26
+ const FATAL_BROWSER_ERRORS = /Frame was detached|Target closed|Execution context was destroyed|Protocol error|Session closed/i;
27
+
28
+ class Action {
29
+ private actor: CodeceptJS.I;
30
+ public stateManager: StateManager;
31
+ public actionResult: ActionResult | null = null;
32
+ private config: ExplorbotConfig;
33
+
34
+ // action info
35
+ private action: string | null = null;
36
+ private expectation: string | null = null;
37
+ public lastError: Error | null = null;
38
+ public playwrightHelper: any;
39
+
40
+ constructor(actor: CodeceptJS.I, stateManager: StateManager) {
41
+ this.actor = actor;
42
+ this.stateManager = stateManager;
43
+ this.config = ConfigParser.getInstance().getConfig();
44
+ this.playwrightHelper = container.helpers('Playwright');
45
+ }
46
+
47
+ async caputrePageWithScreenshot(): Promise<ActionResult> {
48
+ return this.capturePageState({ includeScreenshot: true });
49
+ }
50
+
51
+ async saveScreenshot(): Promise<string | undefined> {
52
+ const currentState = this.stateManager.getCurrentState();
53
+ if (currentState?.screenshotFile) return currentState.screenshotFile;
54
+
55
+ const stateHash = currentState?.hash || 'screenshot';
56
+ const filename = `${stateHash}_${Date.now()}.png`;
57
+ try {
58
+ await (this.actor as any).saveScreenshot(filename);
59
+ if (currentState) currentState.screenshotFile = filename;
60
+ return filename;
61
+ } catch (err) {
62
+ debugLog('Screenshot failed:', err);
63
+ return undefined;
64
+ }
65
+ }
66
+
67
+ async capturePageState({ includeScreenshot = false, ariaSnapshot: preCapuredAria }: { includeScreenshot?: boolean; ariaSnapshot?: string } = {}): Promise<ActionResult> {
68
+ try {
69
+ const currentState = this.stateManager.getCurrentState();
70
+ const stateHash = currentState?.hash || 'screenshot';
71
+ const timestamp = Date.now();
72
+ const page = this.playwrightHelper.page;
73
+ const frame = this.playwrightHelper.frame;
74
+ const [html, title, browserLogs] = await Promise.all([(this.actor as any).grabSource(), (this.actor as any).grabTitle(), this.captureBrowserLogs()]);
75
+ const url = page?.url() || (await (this.actor as any).grabCurrentUrl?.());
76
+
77
+ let screenshotFile: string | undefined = undefined;
78
+
79
+ if (includeScreenshot) {
80
+ const filename = `${stateHash}_${timestamp}.png`;
81
+ screenshotFile = await (this.actor as any)
82
+ .saveScreenshot(filename)
83
+ .then(() => filename)
84
+ .catch((err: Error) => {
85
+ debugLog('Screenshot failed, continuing without it:', err);
86
+ return undefined;
87
+ });
88
+ }
89
+
90
+ // Save HTML to file
91
+ const statesDir = outputPath('states');
92
+ fs.mkdirSync(statesDir, { recursive: true });
93
+ const htmlFile = `${stateHash}_${timestamp}.html`;
94
+ const htmlPath = join(statesDir, htmlFile);
95
+ fs.writeFileSync(htmlPath, html, 'utf8');
96
+
97
+ debugLog('Captured page state');
98
+ // Save logs to file
99
+ const logFile = `${stateHash}_${timestamp}.log`;
100
+ const logPath = join(statesDir, logFile);
101
+ const formattedLogs = browserLogs.map((log: any) => {
102
+ const logTimestamp = new Date().toISOString();
103
+ const level = (log.type || log.level || 'LOG').toUpperCase();
104
+ const message = log.text || log.message || String(log);
105
+ return `[${logTimestamp}] ${level}: ${message}`;
106
+ });
107
+ fs.writeFileSync(logPath, `${formattedLogs.join('\n')}\n`, 'utf8');
108
+
109
+ debugLog('Page:', { url, title, size: html.length, html: html.substring(0, 100) });
110
+
111
+ // Capture iframe HTML snapshots
112
+ const iframeSnapshots = await this.captureIframeSnapshots(html);
113
+
114
+ let ariaSnapshot: string | null = preCapuredAria || null;
115
+ let ariaSnapshotFile: string | undefined = undefined;
116
+
117
+ if (!ariaSnapshot) {
118
+ try {
119
+ const page = this.playwrightHelper.page;
120
+ ariaSnapshot = await page.locator('body').ariaSnapshot();
121
+ } catch (err) {
122
+ debugLog('ARIA snapshot failed:', err instanceof Error ? `${err.message}\n${err.stack}` : err);
123
+ }
124
+ }
125
+
126
+ if (ariaSnapshot) {
127
+ const ariaFileName = `${stateHash}_${timestamp}.aria.yaml`;
128
+ const ariaPath = join(statesDir, ariaFileName);
129
+ fs.writeFileSync(ariaPath, ariaSnapshot, 'utf8');
130
+ ariaSnapshotFile = ariaFileName;
131
+ }
132
+
133
+ const result = new ActionResult({
134
+ html,
135
+ title,
136
+ url,
137
+ browserLogs,
138
+ htmlFile,
139
+ logFile,
140
+ screenshotFile,
141
+ iframeSnapshots,
142
+ ariaSnapshot,
143
+ ariaSnapshotFile,
144
+ iframeURL: frame ? frame.url?.() || 'iframe' : undefined,
145
+ });
146
+ this.stateManager.updateState(result);
147
+ return result;
148
+ } catch (err) {
149
+ const msg = err instanceof Error ? err.message : String(err);
150
+ if (FATAL_BROWSER_ERRORS.test(msg)) throw err;
151
+ debugLog('capturePageState failed with non-fatal error:', msg);
152
+ const url = this.playwrightHelper.page?.url?.() || '';
153
+ return new ActionResult({ url, error: msg });
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Capture HTML snapshots of all iframes on the page
159
+ */
160
+ private async captureIframeSnapshots(mainHtml: string): Promise<Array<{ src: string; html: string; id?: string }>> {
161
+ const iframeSnapshots: Array<{ src: string; html: string }> = [];
162
+
163
+ if (!/<iframe/i.test(mainHtml)) {
164
+ return iframeSnapshots;
165
+ }
166
+
167
+ const page = this.playwrightHelper.page;
168
+ const frames = page.frames();
169
+
170
+ for (const frame of frames) {
171
+ if (frame === page.mainFrame()) {
172
+ continue;
173
+ }
174
+
175
+ const url = frame.url();
176
+ if (url === 'about:blank') {
177
+ continue;
178
+ }
179
+
180
+ try {
181
+ const iframeHtml = await frame.evaluate(() => document.documentElement.outerHTML);
182
+ const compactedIframeHtml = await minifyHtml(htmlCombinedSnapshot(iframeHtml));
183
+
184
+ iframeSnapshots.push({
185
+ src: url,
186
+ html: compactedIframeHtml,
187
+ });
188
+
189
+ debugLog(`Captured iframe ${url}: ${compactedIframeHtml.length} characters (compacted)`);
190
+ } catch (error) {
191
+ debugLog(`Failed to capture iframe ${url}:`, error instanceof Error ? `${error.message}\n${error.stack}` : error);
192
+ }
193
+ }
194
+
195
+ return iframeSnapshots;
196
+ }
197
+
198
+ private async captureBrowserLogs(): Promise<any[]> {
199
+ try {
200
+ const logs = await (this.actor as any).grabBrowserLogs();
201
+
202
+ // Filter for important logs (info, error, warning)
203
+ const importantLogs = logs.filter((log: any) => {
204
+ const level = log.type || log.level;
205
+ return ['info', 'error', 'warning', 'warn'].includes(level);
206
+ });
207
+
208
+ return importantLogs;
209
+ } catch (error) {
210
+ debugLog('Failed to capture browser logs:', error);
211
+ return [];
212
+ }
213
+ }
214
+
215
+ async execute(code: string): Promise<Action> {
216
+ let error: Error | null = null;
217
+
218
+ setActivity('🔎 Browsing...', 'action');
219
+
220
+ let codeString = code.replace(/^\(I\) => /, '').trim();
221
+
222
+ const executedSteps: string[] = [];
223
+ registerStepLogger(executedSteps);
224
+ const activeSpan = Observability.getSpan();
225
+ const tracer = trace.getTracer('ai');
226
+ const stepSpan = activeSpan ? tracer.startSpan('codeceptjs.step', undefined, trace.setSpan(context.active(), activeSpan)) : null;
227
+ setStepSpanParent(stepSpan);
228
+ const sanitizedCode = sanitizeCodeBlock(codeString);
229
+ const isPlaywright = hasPlaywrightCommands(sanitizedCode);
230
+
231
+ try {
232
+ debugLog('Executing action:', codeString);
233
+
234
+ if (!sanitizedCode) {
235
+ throw new Error('No valid I.* or page.* commands found in code block');
236
+ }
237
+
238
+ if (isPlaywright) {
239
+ const page = this.playwrightHelper.page;
240
+ const asyncFn = new Function('page', `return (async () => { ${sanitizedCode} })()`);
241
+ await asyncFn(page);
242
+ await sleep(this.config.action?.delay || 500);
243
+ } else {
244
+ const codeFunction = new Function('I', 'tryTo', 'retryTo', 'within', 'hopeThat', 'step', sanitizedCode);
245
+ codeFunction(this.actor, tryTo, retryTo, within, hopeThat, step);
246
+ await recorder.add(() => sleep(this.config.action?.delay || 500));
247
+ await recorder.promise();
248
+ }
249
+
250
+ const pageState = await this.capturePageState();
251
+ if (executedSteps.length > 0) {
252
+ codeString = executedSteps.join('\n');
253
+ }
254
+
255
+ this.stateManager.updateState(pageState, codeString);
256
+
257
+ this.actionResult = pageState;
258
+ } catch (err) {
259
+ debugLog('Action error', errorToString(err));
260
+ error = err as Error;
261
+ if (!isPlaywright) {
262
+ await recorder.reset();
263
+ await recorder.start();
264
+ }
265
+ throw err;
266
+ } finally {
267
+ unregisterStepLogger();
268
+ if (stepSpan) {
269
+ stepSpan.end();
270
+ }
271
+ setStepSpanParent(null);
272
+ clearActivity();
273
+ }
274
+
275
+ return this;
276
+ }
277
+
278
+ async expect(codeOrFunction: string | ((I: CodeceptJS.I) => void)): Promise<Action> {
279
+ const codeString = typeof codeOrFunction === 'string' ? codeOrFunction : codeOrFunction.toString();
280
+ this.expectation = codeString.toString();
281
+ log('Expecting', highlight(codeString, { language: 'javascript' }));
282
+ try {
283
+ debugLog('Executing expectation:', codeString);
284
+
285
+ let codeFunction: any;
286
+ if (typeof codeOrFunction === 'function') {
287
+ codeFunction = codeOrFunction;
288
+ } else {
289
+ const sanitizedCode = sanitizeCodeBlock(codeString);
290
+ if (!sanitizedCode) {
291
+ throw new Error('No valid I.* commands found in code block');
292
+ }
293
+ codeFunction = new Function('I', 'tryTo', 'retryTo', 'within', 'hopeThat', 'step', sanitizedCode);
294
+ }
295
+ codeFunction(this.actor, tryTo, retryTo, within, hopeThat, step);
296
+ await recorder.promise();
297
+ debugLog('Expectation executed successfully');
298
+
299
+ // Get current state from state manager
300
+ const currentState = this.stateManager.getCurrentState();
301
+ if (currentState) {
302
+ // Create ActionResult from current state for compatibility
303
+ this.actionResult = new ActionResult({
304
+ url: currentState.fullUrl || '',
305
+ title: currentState.title,
306
+ timestamp: currentState.timestamp,
307
+ html: '', // Empty HTML for expectation state
308
+ });
309
+ }
310
+
311
+ return this;
312
+ } catch (err) {
313
+ tag('error').log('Expectation failed:', errorToString(err));
314
+ this.lastError = err as Error;
315
+ await recorder.reset();
316
+ await recorder.start();
317
+ debugLog('Expectation failed:', errorToString(err));
318
+ } finally {
319
+ clearActivity();
320
+ }
321
+
322
+ return this;
323
+ }
324
+
325
+ public async waitForInteraction(): Promise<Action> {
326
+ // start with basic approach
327
+ await this.actor.wait(0.5);
328
+ return this;
329
+ }
330
+
331
+ public async attempt(codeBlock: string, originalMessage?: string, experience = true): Promise<boolean> {
332
+ try {
333
+ debugLog('Resolution attempt...');
334
+ setActivity('🦾 Acting in browser...', 'action');
335
+
336
+ if (!this.actionResult) {
337
+ this.actionResult = ActionResult.fromState(this.stateManager.getCurrentState()!);
338
+ }
339
+ const prevActionResult = this.actionResult;
340
+ this.lastError = null;
341
+ await this.execute(codeBlock);
342
+
343
+ if (!this.expectation && originalMessage) {
344
+ this.expectation = originalMessage;
345
+ }
346
+
347
+ if (!this.expectation) {
348
+ return true;
349
+ }
350
+
351
+ debugLog('Resolved Expectation:', this.expectation);
352
+ return true;
353
+ } catch (error) {
354
+ this.lastError = error as Error;
355
+
356
+ if (error && typeof error === 'object') {
357
+ const errorObj = error as { fetchDetails?: () => Promise<void> };
358
+ if (typeof errorObj.fetchDetails === 'function') {
359
+ await errorObj.fetchDetails();
360
+ }
361
+ }
362
+
363
+ debugLog(`Attempt failed: ${codeBlock}: ${errorToString(error) || this.lastError?.toString()}`);
364
+ return false;
365
+ }
366
+ }
367
+
368
+ getActor(): CodeceptJS.I {
369
+ return this.actor;
370
+ }
371
+
372
+ setActor(actor: CodeceptJS.I): void {
373
+ this.actor = actor;
374
+ }
375
+
376
+ getCurrentState(): ActionResult | null {
377
+ return this.actionResult;
378
+ }
379
+
380
+ getActionResult(): ActionResult | null {
381
+ return this.actionResult;
382
+ }
383
+ }
384
+
385
+ export default Action;
386
+
387
+ function errorToString(error: any): string {
388
+ if (error.cliMessage) {
389
+ return error.cliMessage();
390
+ }
391
+ return error.message || error.toString();
392
+ }
393
+
394
+ function sanitizeCodeBlock(code: string): string {
395
+ return code
396
+ .split('\n')
397
+ .map((line) => line.trim())
398
+ .filter((line) => line.startsWith('I.') || line.startsWith('page.') || line.startsWith('await '))
399
+ .join('\n');
400
+ }
401
+
402
+ function hasPlaywrightCommands(code: string): boolean {
403
+ return code.split('\n').some((line) => {
404
+ const trimmed = line.trim();
405
+ return trimmed.startsWith('page.') || trimmed.startsWith('await page.');
406
+ });
407
+ }
408
+ function sleep(ms: number) {
409
+ return new Promise((resolve) => setTimeout(resolve, ms));
410
+ }
411
+
412
+ let stepLoggerRegistered = false;
413
+ let stepLoggerTarget: string[] | null = null;
414
+
415
+ const stepLogger = (step: any, error?: any) => {
416
+ if (!step?.toCode) {
417
+ return;
418
+ }
419
+ if (step.name?.startsWith('grab')) return;
420
+ const stepCode = step.toCode();
421
+ if (stepLoggerTarget) {
422
+ stepLoggerTarget.push(stepCode);
423
+ }
424
+ if (error) {
425
+ tag('step').log(step, error);
426
+ return;
427
+ }
428
+ tag('step').log(step);
429
+ };
430
+
431
+ const registerStepLogger = (target: string[]) => {
432
+ stepLoggerTarget = target;
433
+ if (stepLoggerRegistered) {
434
+ return;
435
+ }
436
+ stepLoggerRegistered = true;
437
+ codeceptjs.event.dispatcher.on(codeceptjs.event.step.passed, stepLogger);
438
+ codeceptjs.event.dispatcher.on(codeceptjs.event.step.failed, stepLogger);
439
+ };
440
+
441
+ const unregisterStepLogger = () => {
442
+ stepLoggerTarget = null;
443
+ if (!stepLoggerRegistered) {
444
+ return;
445
+ }
446
+ stepLoggerRegistered = false;
447
+ codeceptjs.event.dispatcher.off(codeceptjs.event.step.passed, stepLogger);
448
+ codeceptjs.event.dispatcher.off(codeceptjs.event.step.failed, stepLogger);
449
+ };
@@ -0,0 +1,111 @@
1
+ export interface ActivityEntry {
2
+ message: string;
3
+ timestamp: Date;
4
+ type?: 'ai' | 'action' | 'navigation' | 'general';
5
+ }
6
+
7
+ type ActivityListener = (activity: ActivityEntry | null) => void;
8
+
9
+ class Activity {
10
+ private static instance: Activity;
11
+ private currentActivity: ActivityEntry | null = null;
12
+ private listeners: ActivityListener[] = [];
13
+ private clearTimeoutId: NodeJS.Timeout | null = null;
14
+
15
+ private constructor() {}
16
+
17
+ static getInstance(): Activity {
18
+ if (!Activity.instance) {
19
+ Activity.instance = new Activity();
20
+ }
21
+ return Activity.instance;
22
+ }
23
+
24
+ setActivity(message: string, type: ActivityEntry['type'] = 'general'): void {
25
+ // Clear any pending clear timeout
26
+ if (this.clearTimeoutId) {
27
+ clearTimeout(this.clearTimeoutId);
28
+ this.clearTimeoutId = null;
29
+ }
30
+
31
+ this.currentActivity = {
32
+ message,
33
+ timestamp: new Date(),
34
+ type,
35
+ };
36
+ this.notifyListeners();
37
+ }
38
+
39
+ clearActivity(force = false): void {
40
+ if (this.clearTimeoutId) {
41
+ clearTimeout(this.clearTimeoutId);
42
+ this.clearTimeoutId = null;
43
+ }
44
+
45
+ if (force) {
46
+ this.currentActivity = null;
47
+ this.notifyListeners();
48
+ return;
49
+ }
50
+
51
+ if (this.currentActivity) {
52
+ const timeSinceActivity = Date.now() - this.currentActivity.timestamp.getTime();
53
+ const minDisplayTime = 1000;
54
+
55
+ if (timeSinceActivity < minDisplayTime) {
56
+ this.clearTimeoutId = setTimeout(() => {
57
+ this.currentActivity = null;
58
+ this.notifyListeners();
59
+ this.clearTimeoutId = null;
60
+ }, minDisplayTime - timeSinceActivity);
61
+ } else {
62
+ this.currentActivity = null;
63
+ this.notifyListeners();
64
+ }
65
+ }
66
+ }
67
+
68
+ getCurrentActivity(): ActivityEntry | null {
69
+ return this.currentActivity;
70
+ }
71
+
72
+ addListener(listener: ActivityListener): void {
73
+ this.listeners.push(listener);
74
+ listener(this.currentActivity);
75
+ }
76
+
77
+ removeListener(listener: ActivityListener): void {
78
+ const index = this.listeners.indexOf(listener);
79
+ if (index > -1) {
80
+ this.listeners.splice(index, 1);
81
+ }
82
+ }
83
+
84
+ private notifyListeners(): void {
85
+ this.listeners.forEach((listener) => listener(this.currentActivity));
86
+ }
87
+ }
88
+
89
+ const activity = Activity.getInstance();
90
+
91
+ export const setActivity = (message: string, type: ActivityEntry['type'] = 'general') => {
92
+ activity.setActivity(message, type);
93
+ };
94
+
95
+ export const clearActivity = (force = false) => {
96
+ activity?.clearActivity(force);
97
+ };
98
+
99
+ export const getCurrentActivity = () => {
100
+ return activity.getCurrentActivity();
101
+ };
102
+
103
+ export const addActivityListener = (listener: ActivityListener) => {
104
+ activity.addListener(listener);
105
+ };
106
+
107
+ export const removeActivityListener = (listener: ActivityListener) => {
108
+ activity.removeListener(listener);
109
+ };
110
+
111
+ export default Activity;
@@ -0,0 +1,3 @@
1
+ export interface Agent {
2
+ emoji?: string;
3
+ }