explorbot 0.0.1

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 (329) hide show
  1. package/LICENSE +94 -0
  2. package/README.md +267 -0
  3. package/assets/sample-files/sample.docx +0 -0
  4. package/assets/sample-files/sample.mp3 +0 -0
  5. package/assets/sample-files/sample.mp4 +0 -0
  6. package/assets/sample-files/sample.pdf +21 -0
  7. package/assets/sample-files/sample.png +0 -0
  8. package/assets/sample-files/sample.xlsx +0 -0
  9. package/assets/sample-files/sample.zip +0 -0
  10. package/dist/assets/sample-files/sample.docx +0 -0
  11. package/dist/assets/sample-files/sample.mp3 +0 -0
  12. package/dist/assets/sample-files/sample.mp4 +0 -0
  13. package/dist/assets/sample-files/sample.pdf +21 -0
  14. package/dist/assets/sample-files/sample.png +0 -0
  15. package/dist/assets/sample-files/sample.xlsx +0 -0
  16. package/dist/assets/sample-files/sample.zip +0 -0
  17. package/dist/bin/explorbot-cli.js +683 -0
  18. package/dist/bin/explorbot-cli.js.map +1 -0
  19. package/dist/boat/api-tester/bin/apibot-cli.js +5 -0
  20. package/dist/boat/api-tester/bin/apibot-cli.js.map +1 -0
  21. package/dist/boat/api-tester/example/apibot.config.js +31 -0
  22. package/dist/boat/api-tester/example/apibot.config.js.map +1 -0
  23. package/dist/boat/api-tester/src/ai/chief/styles.js +13 -0
  24. package/dist/boat/api-tester/src/ai/chief/styles.js.map +1 -0
  25. package/dist/boat/api-tester/src/ai/chief.js +301 -0
  26. package/dist/boat/api-tester/src/ai/chief.js.map +1 -0
  27. package/dist/boat/api-tester/src/ai/curler-tools.js +263 -0
  28. package/dist/boat/api-tester/src/ai/curler-tools.js.map +1 -0
  29. package/dist/boat/api-tester/src/ai/curler.js +271 -0
  30. package/dist/boat/api-tester/src/ai/curler.js.map +1 -0
  31. package/dist/boat/api-tester/src/api-client.js +26 -0
  32. package/dist/boat/api-tester/src/api-client.js.map +1 -0
  33. package/dist/boat/api-tester/src/apibot.js +166 -0
  34. package/dist/boat/api-tester/src/apibot.js.map +1 -0
  35. package/dist/boat/api-tester/src/cli.js +262 -0
  36. package/dist/boat/api-tester/src/cli.js.map +1 -0
  37. package/dist/boat/api-tester/src/config.js +159 -0
  38. package/dist/boat/api-tester/src/config.js.map +1 -0
  39. package/dist/prompts/audit-rules.md +124 -0
  40. package/dist/rules/chief/general.md +11 -0
  41. package/dist/rules/chief/styles/curious.md +12 -0
  42. package/dist/rules/chief/styles/hacker.md +19 -0
  43. package/dist/rules/chief/styles/normal.md +11 -0
  44. package/dist/rules/chief/styles/psycho.md +17 -0
  45. package/dist/rules/navigator/multiple-locator.md +47 -0
  46. package/dist/rules/navigator/output.md +69 -0
  47. package/dist/rules/navigator/verification-actions.md +122 -0
  48. package/dist/rules/navigator/verification-output.md +53 -0
  49. package/dist/rules/planner/styles/curious.md +39 -0
  50. package/dist/rules/planner/styles/normal.md +21 -0
  51. package/dist/rules/planner/styles/psycho.md +14 -0
  52. package/dist/rules/researcher/list-element.md +11 -0
  53. package/dist/rules/researcher/screenshot-ui-map.md +30 -0
  54. package/dist/rules/researcher/section-ui-map.md +18 -0
  55. package/dist/rules/researcher/ui-map-table.md +18 -0
  56. package/dist/src/action-result.js +574 -0
  57. package/dist/src/action-result.js.map +1 -0
  58. package/dist/src/action.js +388 -0
  59. package/dist/src/action.js.map +1 -0
  60. package/dist/src/activity.js +86 -0
  61. package/dist/src/activity.js.map +1 -0
  62. package/dist/src/ai/agent.js +2 -0
  63. package/dist/src/ai/agent.js.map +1 -0
  64. package/dist/src/ai/bosun.js +443 -0
  65. package/dist/src/ai/bosun.js.map +1 -0
  66. package/dist/src/ai/captain/idle-mode.js +102 -0
  67. package/dist/src/ai/captain/idle-mode.js.map +1 -0
  68. package/dist/src/ai/captain/mixin.js +11 -0
  69. package/dist/src/ai/captain/mixin.js.map +1 -0
  70. package/dist/src/ai/captain/test-mode.js +251 -0
  71. package/dist/src/ai/captain/test-mode.js.map +1 -0
  72. package/dist/src/ai/captain/web-mode.js +124 -0
  73. package/dist/src/ai/captain/web-mode.js.map +1 -0
  74. package/dist/src/ai/captain.js +442 -0
  75. package/dist/src/ai/captain.js.map +1 -0
  76. package/dist/src/ai/conversation.js +176 -0
  77. package/dist/src/ai/conversation.js.map +1 -0
  78. package/dist/src/ai/experience-compactor.js +232 -0
  79. package/dist/src/ai/experience-compactor.js.map +1 -0
  80. package/dist/src/ai/fisherman-tools.js +154 -0
  81. package/dist/src/ai/fisherman-tools.js.map +1 -0
  82. package/dist/src/ai/fisherman.js +184 -0
  83. package/dist/src/ai/fisherman.js.map +1 -0
  84. package/dist/src/ai/historian.js +384 -0
  85. package/dist/src/ai/historian.js.map +1 -0
  86. package/dist/src/ai/navigator.js +493 -0
  87. package/dist/src/ai/navigator.js.map +1 -0
  88. package/dist/src/ai/pilot.js +684 -0
  89. package/dist/src/ai/pilot.js.map +1 -0
  90. package/dist/src/ai/planner/session-dedup.js +28 -0
  91. package/dist/src/ai/planner/session-dedup.js.map +1 -0
  92. package/dist/src/ai/planner/styles.js +15 -0
  93. package/dist/src/ai/planner/styles.js.map +1 -0
  94. package/dist/src/ai/planner/subpages.js +118 -0
  95. package/dist/src/ai/planner/subpages.js.map +1 -0
  96. package/dist/src/ai/planner.js +486 -0
  97. package/dist/src/ai/planner.js.map +1 -0
  98. package/dist/src/ai/provider.js +540 -0
  99. package/dist/src/ai/provider.js.map +1 -0
  100. package/dist/src/ai/quartermaster.js +210 -0
  101. package/dist/src/ai/quartermaster.js.map +1 -0
  102. package/dist/src/ai/researcher/cache.js +95 -0
  103. package/dist/src/ai/researcher/cache.js.map +1 -0
  104. package/dist/src/ai/researcher/coordinates.js +210 -0
  105. package/dist/src/ai/researcher/coordinates.js.map +1 -0
  106. package/dist/src/ai/researcher/deep-analysis.js +364 -0
  107. package/dist/src/ai/researcher/deep-analysis.js.map +1 -0
  108. package/dist/src/ai/researcher/fingerprint-worker.js +46 -0
  109. package/dist/src/ai/researcher/fingerprint-worker.js.map +1 -0
  110. package/dist/src/ai/researcher/focus.js +37 -0
  111. package/dist/src/ai/researcher/focus.js.map +1 -0
  112. package/dist/src/ai/researcher/locators.js +242 -0
  113. package/dist/src/ai/researcher/locators.js.map +1 -0
  114. package/dist/src/ai/researcher/mixin.js +3 -0
  115. package/dist/src/ai/researcher/mixin.js.map +1 -0
  116. package/dist/src/ai/researcher/parser.js +160 -0
  117. package/dist/src/ai/researcher/parser.js.map +1 -0
  118. package/dist/src/ai/researcher/research-result.js +110 -0
  119. package/dist/src/ai/researcher/research-result.js.map +1 -0
  120. package/dist/src/ai/researcher.js +776 -0
  121. package/dist/src/ai/researcher.js.map +1 -0
  122. package/dist/src/ai/rules.js +368 -0
  123. package/dist/src/ai/rules.js.map +1 -0
  124. package/dist/src/ai/task-agent.js +110 -0
  125. package/dist/src/ai/task-agent.js.map +1 -0
  126. package/dist/src/ai/tester.js +840 -0
  127. package/dist/src/ai/tester.js.map +1 -0
  128. package/dist/src/ai/tools.js +980 -0
  129. package/dist/src/ai/tools.js.map +1 -0
  130. package/dist/src/api/api-client.js +91 -0
  131. package/dist/src/api/api-client.js.map +1 -0
  132. package/dist/src/api/request-result.js +177 -0
  133. package/dist/src/api/request-result.js.map +1 -0
  134. package/dist/src/api/request-store.js +109 -0
  135. package/dist/src/api/request-store.js.map +1 -0
  136. package/dist/src/api/spec-reader.js +148 -0
  137. package/dist/src/api/spec-reader.js.map +1 -0
  138. package/dist/src/api/xhr-capture.js +91 -0
  139. package/dist/src/api/xhr-capture.js.map +1 -0
  140. package/dist/src/browser-server.js +67 -0
  141. package/dist/src/browser-server.js.map +1 -0
  142. package/dist/src/command-handler.js +363 -0
  143. package/dist/src/command-handler.js.map +1 -0
  144. package/dist/src/commands/add-rule-command.js +52 -0
  145. package/dist/src/commands/add-rule-command.js.map +1 -0
  146. package/dist/src/commands/base-command.js +14 -0
  147. package/dist/src/commands/base-command.js.map +1 -0
  148. package/dist/src/commands/clean-command.js +67 -0
  149. package/dist/src/commands/clean-command.js.map +1 -0
  150. package/dist/src/commands/context-aria-command.js +18 -0
  151. package/dist/src/commands/context-aria-command.js.map +1 -0
  152. package/dist/src/commands/context-command.js +57 -0
  153. package/dist/src/commands/context-command.js.map +1 -0
  154. package/dist/src/commands/context-data-command.js +25 -0
  155. package/dist/src/commands/context-data-command.js.map +1 -0
  156. package/dist/src/commands/context-experience-command.js +41 -0
  157. package/dist/src/commands/context-experience-command.js.map +1 -0
  158. package/dist/src/commands/context-html-command.js +26 -0
  159. package/dist/src/commands/context-html-command.js.map +1 -0
  160. package/dist/src/commands/context-knowledge-command.js +36 -0
  161. package/dist/src/commands/context-knowledge-command.js.map +1 -0
  162. package/dist/src/commands/debug-command.js +12 -0
  163. package/dist/src/commands/debug-command.js.map +1 -0
  164. package/dist/src/commands/drill-command.js +29 -0
  165. package/dist/src/commands/drill-command.js.map +1 -0
  166. package/dist/src/commands/exit-command.js +26 -0
  167. package/dist/src/commands/exit-command.js.map +1 -0
  168. package/dist/src/commands/explore-command.js +124 -0
  169. package/dist/src/commands/explore-command.js.map +1 -0
  170. package/dist/src/commands/freesail-command.js +84 -0
  171. package/dist/src/commands/freesail-command.js.map +1 -0
  172. package/dist/src/commands/help-command.js +7 -0
  173. package/dist/src/commands/help-command.js.map +1 -0
  174. package/dist/src/commands/index.js +63 -0
  175. package/dist/src/commands/index.js.map +1 -0
  176. package/dist/src/commands/knows-command.js +54 -0
  177. package/dist/src/commands/knows-command.js.map +1 -0
  178. package/dist/src/commands/learn-command.js +35 -0
  179. package/dist/src/commands/learn-command.js.map +1 -0
  180. package/dist/src/commands/navigate-command.js +16 -0
  181. package/dist/src/commands/navigate-command.js.map +1 -0
  182. package/dist/src/commands/path-command.js +70 -0
  183. package/dist/src/commands/path-command.js.map +1 -0
  184. package/dist/src/commands/plan-clear-command.js +13 -0
  185. package/dist/src/commands/plan-clear-command.js.map +1 -0
  186. package/dist/src/commands/plan-command.js +36 -0
  187. package/dist/src/commands/plan-command.js.map +1 -0
  188. package/dist/src/commands/plan-edit-command.js +8 -0
  189. package/dist/src/commands/plan-edit-command.js.map +1 -0
  190. package/dist/src/commands/plan-load-command.js +16 -0
  191. package/dist/src/commands/plan-load-command.js.map +1 -0
  192. package/dist/src/commands/plan-reload-command.js +23 -0
  193. package/dist/src/commands/plan-reload-command.js.map +1 -0
  194. package/dist/src/commands/plan-save-command.js +22 -0
  195. package/dist/src/commands/plan-save-command.js.map +1 -0
  196. package/dist/src/commands/research-command.js +38 -0
  197. package/dist/src/commands/research-command.js.map +1 -0
  198. package/dist/src/commands/start-command.js +12 -0
  199. package/dist/src/commands/start-command.js.map +1 -0
  200. package/dist/src/commands/status-command.js +19 -0
  201. package/dist/src/commands/status-command.js.map +1 -0
  202. package/dist/src/commands/test-command.js +85 -0
  203. package/dist/src/commands/test-command.js.map +1 -0
  204. package/dist/src/components/ActivityPane.js +55 -0
  205. package/dist/src/components/ActivityPane.js.map +1 -0
  206. package/dist/src/components/AddKnowledge.js +122 -0
  207. package/dist/src/components/AddKnowledge.js.map +1 -0
  208. package/dist/src/components/AddRule.js +117 -0
  209. package/dist/src/components/AddRule.js.map +1 -0
  210. package/dist/src/components/App.js +313 -0
  211. package/dist/src/components/App.js.map +1 -0
  212. package/dist/src/components/Autocomplete.js +43 -0
  213. package/dist/src/components/Autocomplete.js.map +1 -0
  214. package/dist/src/components/InputPane.js +207 -0
  215. package/dist/src/components/InputPane.js.map +1 -0
  216. package/dist/src/components/InputReadline.js +598 -0
  217. package/dist/src/components/InputReadline.js.map +1 -0
  218. package/dist/src/components/LogPane.js +123 -0
  219. package/dist/src/components/LogPane.js.map +1 -0
  220. package/dist/src/components/PlanEditor.js +126 -0
  221. package/dist/src/components/PlanEditor.js.map +1 -0
  222. package/dist/src/components/PlanPane.js +51 -0
  223. package/dist/src/components/PlanPane.js.map +1 -0
  224. package/dist/src/components/SessionTimer.js +26 -0
  225. package/dist/src/components/SessionTimer.js.map +1 -0
  226. package/dist/src/components/StateTransitionPane.js +107 -0
  227. package/dist/src/components/StateTransitionPane.js.map +1 -0
  228. package/dist/src/components/StatusPane.js +37 -0
  229. package/dist/src/components/StatusPane.js.map +1 -0
  230. package/dist/src/components/TaskPane.js +96 -0
  231. package/dist/src/components/TaskPane.js.map +1 -0
  232. package/dist/src/components/Welcome.js +52 -0
  233. package/dist/src/components/Welcome.js.map +1 -0
  234. package/dist/src/components/WelcomeChecklist.js +96 -0
  235. package/dist/src/components/WelcomeChecklist.js.map +1 -0
  236. package/dist/src/components/WelcomeCommands.js +61 -0
  237. package/dist/src/components/WelcomeCommands.js.map +1 -0
  238. package/dist/src/components/autocomplete-store.js +22 -0
  239. package/dist/src/components/autocomplete-store.js.map +1 -0
  240. package/dist/src/components/parse-keypress.js +174 -0
  241. package/dist/src/components/parse-keypress.js.map +1 -0
  242. package/dist/src/config.js +249 -0
  243. package/dist/src/config.js.map +1 -0
  244. package/dist/src/execution-controller.js +92 -0
  245. package/dist/src/execution-controller.js.map +1 -0
  246. package/dist/src/experience-tracker.js +294 -0
  247. package/dist/src/experience-tracker.js.map +1 -0
  248. package/dist/src/explorbot.js +348 -0
  249. package/dist/src/explorbot.js.map +1 -0
  250. package/dist/src/explorer.js +611 -0
  251. package/dist/src/explorer.js.map +1 -0
  252. package/dist/src/index.js +56 -0
  253. package/dist/src/index.js.map +1 -0
  254. package/dist/src/knowledge-tracker.js +184 -0
  255. package/dist/src/knowledge-tracker.js.map +1 -0
  256. package/dist/src/observability.js +126 -0
  257. package/dist/src/observability.js.map +1 -0
  258. package/dist/src/reporter.js +185 -0
  259. package/dist/src/reporter.js.map +1 -0
  260. package/dist/src/state-manager.js +427 -0
  261. package/dist/src/state-manager.js.map +1 -0
  262. package/dist/src/stats.js +44 -0
  263. package/dist/src/stats.js.map +1 -0
  264. package/dist/src/test-plan.js +343 -0
  265. package/dist/src/test-plan.js.map +1 -0
  266. package/dist/src/utils/aria.js +588 -0
  267. package/dist/src/utils/aria.js.map +1 -0
  268. package/dist/src/utils/code-extractor.js +21 -0
  269. package/dist/src/utils/code-extractor.js.map +1 -0
  270. package/dist/src/utils/context-formatter.js +205 -0
  271. package/dist/src/utils/context-formatter.js.map +1 -0
  272. package/dist/src/utils/error-page.js +19 -0
  273. package/dist/src/utils/error-page.js.map +1 -0
  274. package/dist/src/utils/expandable.js +35 -0
  275. package/dist/src/utils/expandable.js.map +1 -0
  276. package/dist/src/utils/hooks-runner.js +77 -0
  277. package/dist/src/utils/hooks-runner.js.map +1 -0
  278. package/dist/src/utils/html-diff.js +734 -0
  279. package/dist/src/utils/html-diff.js.map +1 -0
  280. package/dist/src/utils/html.js +1163 -0
  281. package/dist/src/utils/html.js.map +1 -0
  282. package/dist/src/utils/logger.js +465 -0
  283. package/dist/src/utils/logger.js.map +1 -0
  284. package/dist/src/utils/loop.js +126 -0
  285. package/dist/src/utils/loop.js.map +1 -0
  286. package/dist/src/utils/markdown-parser.js +117 -0
  287. package/dist/src/utils/markdown-parser.js.map +1 -0
  288. package/dist/src/utils/markdown-query.js +393 -0
  289. package/dist/src/utils/markdown-query.js.map +1 -0
  290. package/dist/src/utils/markdown-terminal.js +40 -0
  291. package/dist/src/utils/markdown-terminal.js.map +1 -0
  292. package/dist/src/utils/research-parser.js +2 -0
  293. package/dist/src/utils/research-parser.js.map +1 -0
  294. package/dist/src/utils/retry.js +55 -0
  295. package/dist/src/utils/retry.js.map +1 -0
  296. package/dist/src/utils/rules-loader.js +104 -0
  297. package/dist/src/utils/rules-loader.js.map +1 -0
  298. package/dist/src/utils/strings.js +14 -0
  299. package/dist/src/utils/strings.js.map +1 -0
  300. package/dist/src/utils/test-plan-markdown.js +301 -0
  301. package/dist/src/utils/test-plan-markdown.js.map +1 -0
  302. package/dist/src/utils/throttle.js +16 -0
  303. package/dist/src/utils/throttle.js.map +1 -0
  304. package/dist/src/utils/unique-names.js +13 -0
  305. package/dist/src/utils/unique-names.js.map +1 -0
  306. package/dist/src/utils/url-matcher.js +48 -0
  307. package/dist/src/utils/url-matcher.js.map +1 -0
  308. package/dist/src/utils/web-element.js +131 -0
  309. package/dist/src/utils/web-element.js.map +1 -0
  310. package/dist/src/utils/xpath.js +110 -0
  311. package/dist/src/utils/xpath.js.map +1 -0
  312. package/package.json +119 -0
  313. package/prompts/audit-rules.md +124 -0
  314. package/rules/chief/general.md +11 -0
  315. package/rules/chief/styles/curious.md +12 -0
  316. package/rules/chief/styles/hacker.md +19 -0
  317. package/rules/chief/styles/normal.md +11 -0
  318. package/rules/chief/styles/psycho.md +17 -0
  319. package/rules/navigator/multiple-locator.md +47 -0
  320. package/rules/navigator/output.md +69 -0
  321. package/rules/navigator/verification-actions.md +122 -0
  322. package/rules/navigator/verification-output.md +53 -0
  323. package/rules/planner/styles/curious.md +39 -0
  324. package/rules/planner/styles/normal.md +21 -0
  325. package/rules/planner/styles/psycho.md +14 -0
  326. package/rules/researcher/list-element.md +11 -0
  327. package/rules/researcher/screenshot-ui-map.md +30 -0
  328. package/rules/researcher/section-ui-map.md +18 -0
  329. package/rules/researcher/ui-map-table.md +18 -0
@@ -0,0 +1,48 @@
1
+ import micromatch from 'micromatch';
2
+ export function matchesUrl(pattern, path) {
3
+ if (pattern === '*')
4
+ return true;
5
+ const norm = (s) => s?.replace(/\/+$/, '').toLowerCase();
6
+ if (norm(pattern) === norm(path))
7
+ return true;
8
+ if (pattern.endsWith('/*')) {
9
+ const base = pattern.slice(0, -2).replace(/\/+$/, '');
10
+ const normPath = path.replace(/\/+$/, '');
11
+ if (normPath === base || path.startsWith(`${base}/`))
12
+ return true;
13
+ }
14
+ if (pattern.startsWith('^')) {
15
+ try {
16
+ return new RegExp(pattern.slice(1)).test(path);
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ if (pattern.startsWith('~') && pattern.endsWith('~') && pattern.length > 2) {
23
+ try {
24
+ return new RegExp(pattern.slice(1, -1)).test(path);
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ try {
31
+ return micromatch.isMatch(path, pattern);
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ export function extractStatePath(url) {
38
+ if (url.startsWith('/'))
39
+ return url;
40
+ try {
41
+ const urlObj = new URL(url);
42
+ return urlObj.pathname + urlObj.hash;
43
+ }
44
+ catch {
45
+ return url;
46
+ }
47
+ }
48
+ //# sourceMappingURL=url-matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-matcher.js","sourceRoot":"","sources":["../../../src/utils/url-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,IAAY;IACtD,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACjE,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9C,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACpE,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC;YACH,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,131 @@
1
+ import { buildClickableXPath, evaluateXPath, isDynamicId, isGenericClass } from "./xpath.js";
2
+ const KEY_DISPLAY_ATTRS = ['role', 'id', 'class', 'aria-label'];
3
+ const KEY_ATTRS = ['role', 'aria-label', 'id', 'name', 'type', 'href'];
4
+ export class WebElement {
5
+ tag;
6
+ xpath;
7
+ clickXPath;
8
+ attrs;
9
+ text;
10
+ outerHTML;
11
+ x;
12
+ y;
13
+ constructor(data) {
14
+ this.tag = data.tag;
15
+ this.xpath = data.xpath;
16
+ this.clickXPath = data.clickXPath;
17
+ this.attrs = data.attrs;
18
+ this.text = data.text;
19
+ this.outerHTML = data.outerHTML || '';
20
+ this.x = data.x;
21
+ this.y = data.y;
22
+ }
23
+ get description() {
24
+ const attrParts = KEY_DISPLAY_ATTRS.map((k) => (this.attrs[k] ? `${k}="${this.attrs[k].slice(0, 40)}"` : '')).filter(Boolean);
25
+ return `<${this.tag} ${attrParts.join(' ')}> text="${this.text.slice(0, 40)}"`;
26
+ }
27
+ get keyAttrs() {
28
+ return KEY_ATTRS.map((k) => (this.attrs[k] ? `${k}="${this.attrs[k]}"` : ''))
29
+ .filter(Boolean)
30
+ .join(' ');
31
+ }
32
+ get coordinates() {
33
+ return `(${this.x}, ${this.y})`;
34
+ }
35
+ get eidx() {
36
+ const val = this.attrs['data-explorbot-eidx'] || this.attrs.eidx;
37
+ return val ? Number.parseInt(val, 10) : null;
38
+ }
39
+ get isNavigationLink() {
40
+ if (this.tag !== 'a')
41
+ return false;
42
+ const href = this.attrs.href || '';
43
+ return !!href && href !== '#' && !href.startsWith('javascript:');
44
+ }
45
+ get filteredClasses() {
46
+ const cls = this.attrs.class || '';
47
+ return cls.split(/\s+/).filter((c) => c.length > 2 && !isDynamicId(c) && !isGenericClass(c));
48
+ }
49
+ static fromRawData(d) {
50
+ return new WebElement({
51
+ tag: d.tag,
52
+ xpath: '',
53
+ clickXPath: buildClickableXPath({ tag: d.tag, allAttrs: d.allAttrs, text: d.text }),
54
+ attrs: d.allAttrs,
55
+ text: d.text,
56
+ x: d.x,
57
+ y: d.y,
58
+ });
59
+ }
60
+ static fromXPathMatch(m) {
61
+ return new WebElement({
62
+ tag: m.tag,
63
+ xpath: m.absoluteXPath,
64
+ clickXPath: buildClickableXPath(m),
65
+ attrs: m.allAttrs,
66
+ text: m.text,
67
+ outerHTML: m.outerHTML,
68
+ x: 0,
69
+ y: 0,
70
+ });
71
+ }
72
+ static async fromPlaywrightLocator(locator) {
73
+ try {
74
+ const count = await locator.count();
75
+ if (count === 0)
76
+ return null;
77
+ const data = await locator.first().evaluate(extractElementData);
78
+ if (!data)
79
+ return null;
80
+ return WebElement.fromRawData(data);
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
86
+ static async fromEidx(page, eidx) {
87
+ return WebElement.fromPlaywrightLocator(page.locator(`[data-explorbot-eidx="${eidx}"]`));
88
+ }
89
+ static async fromEidxList(page, eidxList) {
90
+ if (eidxList.length === 0)
91
+ return [];
92
+ const rawList = await page.evaluate(([list, extractFnStr]) => {
93
+ const extract = new Function(`return ${extractFnStr}`)();
94
+ const results = [];
95
+ for (const eidx of list) {
96
+ const el = document.querySelector(`[data-explorbot-eidx="${eidx}"]`);
97
+ if (!el)
98
+ continue;
99
+ const data = extract(el);
100
+ if (data)
101
+ results.push(data);
102
+ }
103
+ return results;
104
+ }, [eidxList, extractElementData.toString()]);
105
+ return rawList.map((d) => WebElement.fromRawData(d));
106
+ }
107
+ static async findByXPath(html, xpath) {
108
+ const result = await evaluateXPath(html, xpath);
109
+ if (result.error)
110
+ return { totalFound: 0, elements: [], error: result.error };
111
+ return { totalFound: result.totalFound, elements: result.matches.map((m) => WebElement.fromXPathMatch(m)) };
112
+ }
113
+ }
114
+ function extractElementData(el) {
115
+ const rect = el.getBoundingClientRect();
116
+ if (rect.width === 0 && rect.height === 0)
117
+ return null;
118
+ const allAttrs = {};
119
+ for (let i = 0; i < el.attributes.length; i++) {
120
+ const attr = el.attributes[i];
121
+ allAttrs[attr.name] = attr.value;
122
+ }
123
+ return {
124
+ tag: el.tagName.toLowerCase(),
125
+ text: (el.textContent || '').trim().slice(0, 80),
126
+ allAttrs,
127
+ x: Math.round(rect.x + rect.width / 2),
128
+ y: Math.round(rect.y + rect.height / 2),
129
+ };
130
+ }
131
+ //# sourceMappingURL=web-element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-element.js","sourceRoot":"","sources":["../../../src/utils/web-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9G,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;AAChE,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAIvE,MAAM,OAAO,UAAU;IACrB,GAAG,CAAS;IACZ,KAAK,CAAS;IACd,UAAU,CAAS;IACnB,KAAK,CAAyB;IAC9B,IAAI,CAAS;IACb,SAAS,CAAS;IAClB,CAAC,CAAS;IACV,CAAC,CAAS;IACV,YAAY,IAA+I;QACzJ,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACpB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QAChB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,WAAW;QACb,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9H,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;IACjF,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aAC1E,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;IAClC,CAAC;IAED,IAAI,IAAI;QACN,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QACjE,OAAO,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;IAED,IAAI,gBAAgB;QAClB,IAAI,IAAI,CAAC,GAAG,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QACnC,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,eAAe;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QACnC,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,CAAiB;QAC1C,OAAO,IAAI,UAAU,CAAC;YACpB,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,KAAK,EAAE,EAAE;YACT,UAAU,EAAE,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAgB,CAAC;YACjG,KAAK,EAAE,CAAC,CAAC,QAAQ;YACjB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,CAAC,EAAE,CAAC,CAAC,CAAC;YACN,CAAC,EAAE,CAAC,CAAC,CAAC;SACP,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,CAAa;QACjC,OAAO,IAAI,UAAU,CAAC;YACpB,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,KAAK,EAAE,CAAC,CAAC,aAAa;YACtB,UAAU,EAAE,mBAAmB,CAAC,CAAC,CAAC;YAClC,KAAK,EAAE,CAAC,CAAC,QAAQ;YACjB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,CAAC,EAAE,CAAC;YACJ,CAAC,EAAE,CAAC;SACL,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,OAAY;QAC7C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,KAAK,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC7B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;YAChE,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YACvB,OAAO,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAS,EAAE,IAAY;QAC3C,OAAO,UAAU,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,IAAI,IAAI,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAS,EAAE,QAAkB;QACrD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAErC,MAAM,OAAO,GAAqB,MAAM,IAAI,CAAC,QAAQ,CACnD,CAAC,CAAC,IAAI,EAAE,YAAY,CAAqB,EAAE,EAAE;YAC3C,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAC,UAAU,YAAY,EAAE,CAAC,EAA0B,CAAC;YACjF,MAAM,OAAO,GAAU,EAAE,CAAC;YAC1B,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;gBACxB,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,yBAAyB,IAAI,IAAI,CAAC,CAAC;gBACrE,IAAI,CAAC,EAAE;oBAAE,SAAS;gBAClB,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;gBACzB,IAAI,IAAI;oBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,EACD,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,CAAuB,CAChE,CAAC;QAEF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,IAAY,EAAE,KAAa;QAClD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9G,CAAC;CACF;AAED,SAAS,kBAAkB,CAAC,EAAW;IACrC,MAAM,IAAI,GAAG,EAAE,CAAC,qBAAqB,EAAE,CAAC;IACxC,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvD,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACnC,CAAC;IAED,OAAO;QACL,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE;QAC7B,IAAI,EAAE,CAAC,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QAChD,QAAQ;QACR,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACtC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;KACxC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,110 @@
1
+ const MAX_MATCHES = 30;
2
+ const MAX_OUTER_HTML = 200;
3
+ const MAX_TEXT = 80;
4
+ function truncate(str, max) {
5
+ if (str.length <= max)
6
+ return str;
7
+ return `${str.slice(0, max)}...`;
8
+ }
9
+ function getAbsoluteXPath(el) {
10
+ const parts = [];
11
+ let current = el;
12
+ while (current && current.nodeType === 1) {
13
+ const tag = current.tagName.toLowerCase();
14
+ if (tag === 'html') {
15
+ current = current.parentElement;
16
+ continue;
17
+ }
18
+ if (tag === 'body') {
19
+ parts.unshift('body');
20
+ current = current.parentElement;
21
+ continue;
22
+ }
23
+ let index = 1;
24
+ let sibling = current.previousElementSibling;
25
+ while (sibling) {
26
+ if (sibling.tagName === current.tagName)
27
+ index++;
28
+ sibling = sibling.previousElementSibling;
29
+ }
30
+ parts.unshift(`${tag}[${index}]`);
31
+ current = current.parentElement;
32
+ }
33
+ return `//${parts.join('/')}`;
34
+ }
35
+ export const isDynamicId = (id) => /^(ember|react|__next)\d|^\d+$/.test(id);
36
+ export const isGenericClass = (cls) => /^ember-view$|^ember\d|^react-|^__next/.test(cls);
37
+ export function buildClickableXPath(el) {
38
+ const a = el.allAttrs;
39
+ if (a.id && !isDynamicId(a.id))
40
+ return `//*[@id="${a.id}"]`;
41
+ const conditions = [`self::${el.tag}`];
42
+ if (a.role)
43
+ conditions.push(`@role="${a.role}"`);
44
+ if (a['aria-label'])
45
+ conditions.push(`@aria-label="${a['aria-label']}"`);
46
+ if (a.class) {
47
+ const classes = a.class.split(/\s+/).filter((c) => !isGenericClass(c) && c.length > 2);
48
+ for (const cls of classes.slice(0, 3)) {
49
+ conditions.push(`contains(@class,"${cls}")`);
50
+ }
51
+ }
52
+ if (el.text && el.text.length > 0 && el.text.length < 40) {
53
+ conditions.push(`contains(.,"${el.text.replace(/"/g, "'")}")`);
54
+ }
55
+ return `//*[${conditions.join(' and ')}]`;
56
+ }
57
+ export function cssToAncestorXPath(css) {
58
+ const trimmed = css.trim();
59
+ if (!trimmed)
60
+ return null;
61
+ const idMatch = trimmed.match(/^#([\w-]+)$/);
62
+ if (idMatch)
63
+ return `@id="${idMatch[1]}"`;
64
+ const tagClassMatch = trimmed.match(/^(\w+)\.([\w-]+)$/);
65
+ if (tagClassMatch)
66
+ return `self::${tagClassMatch[1]} and contains(@class,"${tagClassMatch[2]}")`;
67
+ const classMatch = trimmed.match(/^\.([\w-]+)$/);
68
+ if (classMatch)
69
+ return `contains(@class,"${classMatch[1]}")`;
70
+ const attrMatch = trimmed.match(/^\[([^\]]+)\]$/);
71
+ if (attrMatch)
72
+ return `@${attrMatch[1]}`;
73
+ return null;
74
+ }
75
+ export async function evaluateXPath(html, xpath) {
76
+ const { JSDOM } = await import('jsdom');
77
+ const dom = new JSDOM(html);
78
+ try {
79
+ const doc = dom.window.document;
80
+ const result = doc.evaluate(xpath, doc, null, 7, null);
81
+ const matches = [];
82
+ const totalFound = result.snapshotLength;
83
+ for (let i = 0; i < Math.min(totalFound, MAX_MATCHES); i++) {
84
+ const node = result.snapshotItem(i);
85
+ if (!node || node.nodeType !== 1)
86
+ continue;
87
+ const el = node;
88
+ const allAttrs = {};
89
+ for (let a = 0; a < el.attributes.length; a++) {
90
+ const attr = el.attributes[a];
91
+ allAttrs[attr.name] = attr.value;
92
+ }
93
+ matches.push({
94
+ tag: el.tagName.toLowerCase(),
95
+ outerHTML: truncate(el.outerHTML, MAX_OUTER_HTML),
96
+ text: truncate(el.textContent?.trim() || '', MAX_TEXT),
97
+ absoluteXPath: getAbsoluteXPath(el),
98
+ allAttrs,
99
+ });
100
+ }
101
+ return { totalFound, matches };
102
+ }
103
+ catch (err) {
104
+ return { totalFound: 0, matches: [], error: err?.message || 'XPath evaluation failed' };
105
+ }
106
+ finally {
107
+ dom.window.close();
108
+ }
109
+ }
110
+ //# sourceMappingURL=xpath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xpath.js","sourceRoot":"","sources":["../../../src/utils/xpath.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,119 @@
1
+ {
2
+ "name": "explorbot",
3
+ "version": "0.0.1",
4
+ "description": "CLI app built with React Ink, CodeceptJS, and Playwright",
5
+ "license": "Elastic-2.0",
6
+ "type": "module",
7
+ "main": "dist/src/index.js",
8
+ "bin": {
9
+ "explorbot": "./dist/bin/explorbot-cli.js"
10
+ },
11
+ "files": ["dist/", "rules/", "assets/sample-files/", "prompts/"],
12
+ "scripts": {
13
+ "build": "bun run src/index.tsx build && bun run build:bin",
14
+ "build:bin": "bun build bin/explorbot-cli.ts --outdir bin --target node --external commander --format esm",
15
+ "build:npm": "bash scripts/build-npm.sh",
16
+ "prepublishOnly": "npm run build:npm",
17
+ "dev": "bun run src/index.tsx",
18
+ "start": "node dist/index.js",
19
+ "init": "bun run src/index.tsx init",
20
+ "test": "codeceptjs run",
21
+ "test:headless": "codeceptjs run --headless",
22
+ "test:ui": "bun test tests/ui",
23
+ "test:unit": "bun test tests/unit",
24
+ "test:node": "node --test tests/node/*.mjs",
25
+ "test:unit:coverage": "bun test tests/unit --coverage && find . -name '.lcov.info*.tmp' -type f -delete 2>/dev/null || true",
26
+ "test:coverage": "bun test tests/unit --coverage --coverage-reporter=text && find . -name '.lcov.info*.tmp' -type f -delete 2>/dev/null || true",
27
+ "test:coverage:html": "echo 'Run: bun test tests/unit --coverage for detailed coverage report'",
28
+ "test:coverage:summary": "bun test tests/unit --coverage --coverage-reporter=text | tail -n 20 && find . -name '.lcov.info*.tmp' -type f -delete 2>/dev/null || true",
29
+ "test:coverage:clean": "find . -name '.lcov.info*.tmp' -type f -delete 2>/dev/null || true",
30
+ "format": "biome format --write .",
31
+ "format:check": "biome format .",
32
+ "lint": "biome lint .",
33
+ "lint:fix": "biome lint --write .",
34
+ "check": "biome check .",
35
+ "check:fix": "biome check --write .",
36
+ "langfuse:export": "bun run .claude/skills/explorbot-debug/langfuse-export.ts"
37
+ },
38
+ "keywords": ["cli", "react", "ink", "codeceptjs", "playwright"],
39
+ "author": "",
40
+ "dependencies": {
41
+ "@ai-sdk/anthropic": "^3.0",
42
+ "@ai-sdk/groq": "^3.0",
43
+ "@ai-sdk/openai": "^3.0",
44
+ "@axe-core/playwright": "^4.11.0",
45
+ "@inkjs/ui": "^2.0.0",
46
+ "@langfuse/otel": "^4.5.1",
47
+ "@openrouter/ai-sdk-provider": "^2.3.3",
48
+ "@opentelemetry/api": "^1.9.0",
49
+ "@opentelemetry/auto-instrumentations-node": "^0.67.3",
50
+ "@opentelemetry/instrumentation": "^0.208.0",
51
+ "@opentelemetry/resources": "^2.2.0",
52
+ "@opentelemetry/sdk-node": "^0.208.0",
53
+ "@opentelemetry/sdk-trace-base": "^2.2.0",
54
+ "@opentelemetry/semantic-conventions": "^1.38.0",
55
+ "@scalar/openapi-parser": "^0.25.6",
56
+ "@testomatio/reporter": "2.7.3",
57
+ "ai": "^6.0.6",
58
+ "axe-core": "^4.11.1",
59
+ "bash-tool": "^1.3.15",
60
+ "cli-highlight": "^2.1.11",
61
+ "codeceptjs": "4.0.0-rc.11",
62
+ "commander": "^14.0.1",
63
+ "debug": "^4.4.3",
64
+ "dedent": "^1.6.0",
65
+ "expect": "^30.3.0",
66
+ "figures": "^6.1.0",
67
+ "gray-matter": "^4.0.3",
68
+ "html-minifier-next": "^2.1.5",
69
+ "ink": "^6.3.1",
70
+ "ink-big-text": "^2.0.0",
71
+ "ink-select-input": "^6.2.0",
72
+ "ink-text-input": "^6.0.0",
73
+ "jsdom": "^28.0.0",
74
+ "jsonpath-plus": "^10.4.0",
75
+ "just-bash": "^2.14.0",
76
+ "langfuse": "^3.5.0",
77
+ "marked": "^16.2.0",
78
+ "marked-terminal": "^7.3.0",
79
+ "micromatch": "^4.0.8",
80
+ "ora-classic": "^5.4.2",
81
+ "parse5": "^8.0.0",
82
+ "playwright": "^1.40.0",
83
+ "react": "^19.1.1",
84
+ "strip-ansi": "^7.1.2",
85
+ "turndown": "^7.2.1",
86
+ "unique-names-generator": "^4.7.1",
87
+ "yargs": "^17.7.2",
88
+ "zod": "^4.1.8"
89
+ },
90
+ "devDependencies": {
91
+ "@biomejs/biome": "^1.5.3",
92
+ "@testing-library/react": "^16.3.0",
93
+ "@types/debug": "^4.1.12",
94
+ "@types/jsdom": "^27.0.0",
95
+ "@types/micromatch": "^4.0.9",
96
+ "@types/react": "^18.2.0",
97
+ "@types/yargs": "^17.0.24",
98
+ "bunosh": "^0.4.0",
99
+ "ink-testing-library": "^4.0.0",
100
+ "langwatch": "^0.10.0",
101
+ "msw": "^2.11.3",
102
+ "typescript": "^5.0.0",
103
+ "vitest": "^3.2.4"
104
+ },
105
+ "engines": {
106
+ "node": ">=24.0.0"
107
+ },
108
+ "overrides": {
109
+ "has-flag": "4.0.0",
110
+ "supports-color": "7.2.0"
111
+ },
112
+ "resolutions": {
113
+ "marked-terminal": {
114
+ "supports-hyperlinks": "2.3.0"
115
+ },
116
+ "has-flag": "4.0.0",
117
+ "supports-color": "7.2.0"
118
+ }
119
+ }
@@ -0,0 +1,124 @@
1
+ # Prompt Audit System for Web Navigation/Testing Rules
2
+
3
+ You are an expert prompt engineer specializing in AI-driven web testing automation. Your task is to audit the prompts and rules used for web navigation and testing in this codebase.
4
+
5
+ ## Files to Analyze
6
+
7
+ 1. **`@src/ai/rules.ts`** - Core rules and guidelines for locators, actions, and verification
8
+ 2. **`@src/ai/navigator.ts`** - Uses rules in prompts for navigation and verification
9
+ 3. **`@src/ai/tools.ts`** - Tool definitions that include locator rules and guidance
10
+
11
+ ## Audit Checklist
12
+
13
+ ### 1. Rules Analysis (`rules.ts`)
14
+
15
+ Look for:
16
+ - **Contradictions**: Rules that conflict with each other (e.g., "prefer ARIA" vs "use text first")
17
+ - **Ambiguity**: Vague guidance that could be interpreted multiple ways
18
+ - **Incomplete guidance**: Missing priority order, missing edge cases
19
+ - **Locator priority**: Is ARIA → Text → CSS → XPath clearly defined?
20
+ - **Disambiguation**: How to choose between multiple matching elements?
21
+ - **Context parameter**: When and how to use it?
22
+ - **Short vs Long locators**: Clear definitions?
23
+ - **Unused rules**: Exported but never imported anywhere
24
+
25
+ ### 2. Rule Usage Analysis (`navigator.ts`)
26
+
27
+ Check:
28
+ - **Imported but unused**: Rules imported but not used in prompts
29
+ - **Missing rules**: Prompts that should include locatorRule or actionRule but don't
30
+ - **Duplication**: Inline rules that duplicate what's in rules.ts
31
+ - **Consistency**: Do prompts follow the same structure?
32
+ - **HTML tags**: Is HTML content wrapped in `<page_html>` tags?
33
+
34
+ ### 3. Tools Analysis (`tools.ts`)
35
+
36
+ Verify:
37
+ - **locatorRule usage**: Do tools that accept locators include locatorRule?
38
+ - **Input schema descriptions**: Do they mention "ARIA, CSS or XPath"?
39
+ - **Suggestions on failure**: Do failed results provide helpful suggestions?
40
+ - **Unreachable code paths**: Logic that can never execute (like type with undefined locator)
41
+ - **Consistent error handling**: Same pattern across all tools
42
+ - **Tool differentiation**: Clear when to use click vs clickByText, type with/without locator
43
+
44
+ ## Severity Levels
45
+
46
+ | Severity | Description | Examples |
47
+ |----------|-------------|----------|
48
+ | **🔴 Critical** | Breaks functionality or causes wrong behavior | Contradictory rules, unreachable code, missing required rules |
49
+ | **🟠 High** | Significant confusion or incorrect guidance | Ambiguous priority, misleading examples, wrong format |
50
+ | **🟡 Medium** | Suboptimal but functional | Redundant rules, verbose descriptions, missing suggestions |
51
+ | **🟢 Minor** | Cosmetic or style issues | Typos, formatting, inconsistent spacing |
52
+
53
+ ## Output Format
54
+
55
+ Structure your findings as follows:
56
+
57
+ ```markdown
58
+ ## Audit Results
59
+
60
+ ### Critical Issues 🔴
61
+ 1. **[File:Line]** Issue description
62
+ - Impact: What goes wrong
63
+ - Fix: Suggested resolution
64
+
65
+ ### High Priority Issues 🟠
66
+ 1. **[File:Line]** Issue description
67
+ - Impact: What confusion this causes
68
+ - Fix: Suggested resolution
69
+
70
+ ### Medium Priority Issues 🟡
71
+ 1. **[File:Line]** Issue description
72
+ - Impact: Why this matters
73
+ - Fix: Suggested resolution
74
+
75
+ ### Minor Issues 🟢
76
+ 1. **[File:Line]** Issue description
77
+ - Fix: Suggested resolution
78
+
79
+ ### Observations
80
+ - General patterns noticed
81
+ - Recommendations for improvement
82
+ - Questions for clarification
83
+ ```
84
+
85
+ ## Specific Things to Check
86
+
87
+ ### Locator Rules
88
+ - [ ] Priority order clearly defined (ARIA → Text → CSS → XPath)
89
+ - [ ] Context parameter explained (when to use, which tools support it)
90
+ - [ ] Disambiguation strategy documented (form flow, ARIA state, proximity)
91
+ - [ ] Short vs Long locators defined
92
+ - [ ] Examples consistent with rules (single quotes vs double quotes in JSON)
93
+
94
+ ### Action Rules
95
+ - [ ] Function signatures included (I.click, I.fillField, I.see, etc.)
96
+ - [ ] Required parameters explained (context for I.see)
97
+ - [ ] Prohibited actions listed (no wait functions, no amOnPage)
98
+ - [ ] Examples match documented format
99
+
100
+ ### Verification Rules
101
+ - [ ] I.see requires context parameter
102
+ - [ ] I.seeElement prefers ARIA locators
103
+ - [ ] Strictness rules to avoid false positives
104
+ - [ ] Examples show correct usage
105
+
106
+ ### Tool Definitions
107
+ - [ ] Each tool includes relevant rules (locatorRule where needed)
108
+ - [ ] Input schemas describe all locator types
109
+ - [ ] Failed results include actionable suggestions
110
+ - [ ] Description explains when to use this tool vs alternatives
111
+
112
+ ## Run This Audit
113
+
114
+ To run this audit, execute:
115
+
116
+ ```
117
+ Please analyze the following files for prompt/rule issues:
118
+ @src/ai/rules.ts
119
+ @src/ai/navigator.ts
120
+ @src/ai/tools.ts
121
+
122
+ Follow the audit checklist and output format defined in @prompts/audit-rules.md
123
+ ```
124
+
@@ -0,0 +1,11 @@
1
+ - Each scenario must be a complete, independent test
2
+ - Steps should specify exact HTTP methods, paths, and key payload details
3
+ - Expected outcomes should be specific and verifiable (status codes, response fields, error messages)
4
+ - For CRUD operations, each test should handle its own setup and teardown
5
+ - Expect standard REST conventions: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 404 Not Found, 422 Unprocessable Entity
6
+ - NEVER propose scenarios that test the same thing. "Create a basic suite" and "Successful creation of a simple suite" are DUPLICATES. Each scenario must test a DISTINCT behavior or aspect.
7
+ - Before finalizing, review all scenarios and remove any that overlap in what they actually verify.
8
+
9
+ API Usage Notes:
10
+
11
+ - String is usually compatible with other data formats such as numbers or datetime, so do not check if number type strictly matches to number as it can be string too
@@ -0,0 +1,12 @@
1
+ Maximize coverage by using every field and endpoint the API offers.
2
+
3
+ Focus on:
4
+ - Full payload create: POST with ALL optional and required fields populated, verify every field was saved
5
+ - Field-by-field update: PATCH/PUT each field individually, verify the change persists via GET
6
+ - Mixed combinations: create with some optional fields set and others omitted, then update the missing ones
7
+ - Array fields: send multiple items in arrays, not just one — verify all items are stored
8
+ - Enum fields: try every valid enum value, verify each is accepted and returned correctly
9
+ - Related fields: if spec shows related IDs or nested objects, populate them all
10
+ - All endpoints: exercise every available endpoint for the resource, not just the main CRUD
11
+ - Multiple resources: create several items, list them, verify count and content
12
+ - Default values: omit optional fields on create, then GET to see what defaults the API assigns
@@ -0,0 +1,19 @@
1
+ Analyze the request log and API spec to discover hidden endpoints, undocumented properties, and unprotected actions — then try to exploit them.
2
+
3
+ Study previous responses carefully:
4
+ - Look at response field names and values — guess related endpoints and properties not in the spec
5
+ - If a response contains fields like "user_id", "org_id", "role" — try sending them on create/update to see if it is possible to self-promote
6
+ - If responses include URLs or paths — follow them, they may reveal internal routes
7
+ - Guess hidden endpoints by looking at response fields
8
+ - If IDs are sequential — try adjacent IDs to access other users' resources
9
+ - Try to create tests with custom ID values to see if they are accepted
10
+ - If a response shows more fields than the spec defines — those extra fields are attack surface
11
+
12
+ Use schemaFor to discover related endpoints, then try HTTP methods the spec doesn't list for them.
13
+ Derive endpoint patterns from what you've seen — if /items exists, try /items/export, /items/bulk, /items/search.
14
+ Send fields from GET responses back in POST/PUT — check which ones the server silently accepts.
15
+ Try overriding read-only or server-computed fields you observed in responses.
16
+ Strip or corrupt auth headers on sensitive operations to test enforcement.
17
+
18
+ Every unexpected finding must be recorded immediately.
19
+ Unclosed hidden exploits must be recorded as a failure.
@@ -0,0 +1,11 @@
1
+ Focus on standard CRUD operations and happy-path flows.
2
+
3
+ Test each HTTP method the endpoint supports:
4
+ - POST: Create a new resource with valid data, verify 201 and response body
5
+ - PUT/PATCH: Update the resource, verify changes persist
6
+ - DELETE: Remove the resource, verify 204/200 and subsequent GET returns 404
7
+ - GET: obtain data, list by filters, by search
8
+
9
+ Validate response schemas match expected structure.
10
+ Check that required fields are present in responses.
11
+ Verify correct HTTP status codes for each operation.
@@ -0,0 +1,17 @@
1
+ Stress-test the endpoint with invalid, malformed, and extreme inputs.
2
+
3
+ Focus on:
4
+
5
+ - Missing required fields: send partial payloads, empty objects, empty body
6
+ - Malformed JSON: trailing commas, unquoted keys, broken UTF-8
7
+ - SQL injection
8
+ - XSS payloads
9
+ - Exposed secrets: passwords, tokens, etc
10
+ - Wrong Content-Type: send form data as JSON, JSON as XML
11
+ - Invalid HTTP methods: PATCH on POST-only endpoints
12
+ - Boundary values: negative numbers, zero, MAX_INT, empty arrays, null values
13
+ - Date fields: set creation date in future, and expiring date to past
14
+
15
+ Expect proper responses with meaningful error messages if related.
16
+ If server strips broken data it is ok
17
+ Responses must be carefully validated to contain correct and secure data