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
@@ -0,0 +1,306 @@
1
+ import dedent from 'dedent';
2
+ import { z } from 'zod';
3
+ import type { AIProvider } from '../../../../src/ai/provider.ts';
4
+ import type { Reporter } from '../../../../src/reporter.ts';
5
+ import { type Test, TestResult } from '../../../../src/test-plan.ts';
6
+ import { createDebug, tag } from '../../../../src/utils/logger.ts';
7
+ import { loop } from '../../../../src/utils/loop.ts';
8
+ import type { ApiClient } from '../api-client.ts';
9
+ import type { RequestStore } from '../../../../src/api/request-store.ts';
10
+ import { createCurlerTools } from './curler-tools.ts';
11
+
12
+ const debugLog = createDebug('explorbot:curler');
13
+
14
+ const MAX_ITERATIONS = 10;
15
+
16
+ export class Curler {
17
+ private provider: AIProvider;
18
+ private apiClient: ApiClient;
19
+ private requestState: RequestStore;
20
+ private reporter: Reporter;
21
+
22
+ constructor(provider: AIProvider, apiClient: ApiClient, requestState: RequestStore, reporter: Reporter) {
23
+ this.provider = provider;
24
+ this.apiClient = apiClient;
25
+ this.requestState = requestState;
26
+ this.reporter = reporter;
27
+ }
28
+
29
+ async test(test: Test, opts?: { specDefinition?: string; baseEndpoint?: string; searchSpec?: (query: string) => string }): Promise<{ success: boolean }> {
30
+ tag('info').log(`Testing: ${test.scenario}`);
31
+ debugLog('Starting test:', test.scenario);
32
+
33
+ this.requestState.clear();
34
+ test.start();
35
+ await this.reporter.reportTestStart(test);
36
+
37
+ const conversation = this.provider.startConversation(this.buildSystemPrompt(), 'curler', this.provider.getAgenticModel('curler'));
38
+ const tools = createCurlerTools(this.apiClient, this.requestState, test, opts?.searchSpec);
39
+
40
+ const initialPrompt = this.buildTestPrompt(test, opts?.specDefinition, opts?.baseEndpoint);
41
+ conversation.addUserText(initialPrompt);
42
+
43
+ await loop(
44
+ async ({ stop, iteration }) => {
45
+ debugLog(`Iteration ${iteration}`);
46
+
47
+ if (iteration > 1) {
48
+ const requestLog = this.requestState.toLog();
49
+ const nextStep = dedent`
50
+ <request_log>
51
+ ${requestLog || 'No requests made yet'}
52
+ </request_log>
53
+
54
+ <task>
55
+ Continue testing. Review the request log above and proceed with the next step.
56
+ </task>
57
+
58
+ <notes>
59
+ ${test.notesToString() || 'No notes yet'}
60
+ </notes>
61
+ `;
62
+ conversation.addUserText(nextStep);
63
+ }
64
+
65
+ const result = await this.provider.invokeConversation(conversation, tools, {
66
+ maxToolRoundtrips: 5,
67
+ toolChoice: 'required',
68
+ agentName: 'curler',
69
+ });
70
+
71
+ if (!result) throw new Error('Failed to get response from provider');
72
+
73
+ const toolNames = result.toolExecutions?.map((e: any) => e.toolName) || [];
74
+ debugLog('Tool calls:', toolNames.join(', '));
75
+
76
+ if (test.hasFinished) {
77
+ stop();
78
+ return;
79
+ }
80
+
81
+ if (iteration >= MAX_ITERATIONS) {
82
+ tag('warning').log('Max iterations reached, running final review...');
83
+ stop();
84
+ }
85
+ },
86
+ {
87
+ maxAttempts: MAX_ITERATIONS,
88
+ observability: {
89
+ name: `curler: ${test.scenario}`,
90
+ agent: 'curler',
91
+ sessionId: test.sessionName,
92
+ metadata: {
93
+ input: {
94
+ scenario: test.scenario,
95
+ startUrl: test.startUrl,
96
+ expected: test.expected,
97
+ },
98
+ },
99
+ },
100
+ catch: async ({ error, stop }) => {
101
+ tag('error').log(`Test execution error: ${error}`);
102
+ stop();
103
+ },
104
+ }
105
+ );
106
+
107
+ try {
108
+ await this.finalReview(test);
109
+ } catch (error) {
110
+ tag('error').log(`Final review failed: ${error}`);
111
+ }
112
+ this.finishTest(test);
113
+ const meta: Record<string, string | undefined> = {
114
+ endpoint: test.startUrl,
115
+ style: test.style,
116
+ sessionName: test.sessionName,
117
+ };
118
+ await this.reporter.reportTest(test, meta);
119
+
120
+ return { success: test.isSuccessful };
121
+ }
122
+
123
+ private finishTest(test: Test): void {
124
+ if (!test.hasFinished) {
125
+ test.finish(TestResult.FAILED);
126
+ }
127
+ tag('info').log(`Finished: ${test.scenario}`);
128
+ tag('multiline').log(test.getPrintableNotes().join('\n'));
129
+
130
+ if (test.isSuccessful) {
131
+ tag('success').log(`Passed: ${test.scenario}`);
132
+ } else if (test.isSkipped) {
133
+ tag('warning').log(`Skipped: ${test.scenario}`);
134
+ } else {
135
+ tag('error').log(`Failed: ${test.scenario}`);
136
+ }
137
+ }
138
+
139
+ private async finalReview(test: Test): Promise<void> {
140
+ const notes = test.notesToString() || 'No notes recorded.';
141
+ const requestLog = this.requestState.toLog() || 'No requests made.';
142
+ const hasFailedNotes = test.getCheckedNotes().some((n) => n.status === TestResult.FAILED);
143
+ const isUnfinished = !test.hasFinished;
144
+
145
+ if (!hasFailedNotes && !isUnfinished) return;
146
+
147
+ tag('info').log('Running final review...');
148
+
149
+ const schema = z.object({
150
+ summary: z.string().describe('One-line summary of test results'),
151
+ goalsAchieved: z.boolean().describe('Whether the main test goals were accomplished'),
152
+ failuresCritical: z.boolean().describe('Whether any assertion failures are critical enough to fail the test'),
153
+ details: z.string().describe('Brief explanation of what passed, what failed, and why failures are or are not critical'),
154
+ });
155
+
156
+ const model = this.provider.getAgenticModel('curler');
157
+ const response = await this.provider.generateObject(
158
+ [
159
+ {
160
+ role: 'system',
161
+ content: this.buildFinalReviewSystemPrompt(),
162
+ },
163
+ {
164
+ role: 'user',
165
+ content: dedent`
166
+ Scenario: ${test.scenario}
167
+
168
+ Expected outcomes:
169
+ ${test.expected.map((e) => `- ${e}`).join('\n')}
170
+
171
+ <notes>
172
+ ${notes}
173
+ </notes>
174
+
175
+ <request_log>
176
+ ${requestLog}
177
+ </request_log>
178
+
179
+ Evaluate:
180
+ 1. Were the expected outcomes achieved based on the request results?
181
+ 2. Are any assertion failures critical (wrong status codes, missing core data) or minor (optional fields, cosmetic)?
182
+ 3. Should the test pass or fail overall?
183
+ `,
184
+ },
185
+ ],
186
+ schema,
187
+ model
188
+ );
189
+
190
+ const result = response?.object;
191
+ if (!result) return;
192
+
193
+ test.summary = result.summary;
194
+ test.addNote(`Review: ${result.details}`);
195
+
196
+ if (result.goalsAchieved && !result.failuresCritical) {
197
+ test.addNote(result.summary, TestResult.PASSED);
198
+ test.finish(TestResult.PASSED);
199
+ } else {
200
+ test.addNote(result.summary, TestResult.FAILED);
201
+ test.finish(TestResult.FAILED);
202
+ }
203
+ }
204
+
205
+ private buildTestPrompt(test: Test, specDefinition?: string, baseEndpoint?: string): string {
206
+ let prompt = dedent`
207
+ <task>
208
+ SCENARIO: ${test.scenario}
209
+
210
+ EXPECTED OUTCOMES:
211
+ ${test.expected.map((e) => `- ${e}`).join('\n')}
212
+
213
+ PLANNED STEPS:
214
+ ${test.plannedSteps.map((s) => `- ${s}`).join('\n')}
215
+
216
+ ENDPOINT: ${test.startUrl}
217
+
218
+ Execute the test by making HTTP requests using the request tool.
219
+ Use verifyStructure and verifyData to check responses.
220
+ Use record to document findings.
221
+ Use finish when all goals are achieved.
222
+ Use stop only if the scenario is fundamentally impossible.
223
+ </task>
224
+ `;
225
+
226
+ if (specDefinition) {
227
+ let specBlock = `\n\n<api_spec>\n${specDefinition}\n</api_spec>`;
228
+ if (baseEndpoint) {
229
+ specBlock += dedent`
230
+
231
+ <path_mapping>
232
+ IMPORTANT: The spec shows absolute paths (e.g. /api/v2/{project_id}/suites) but the base URL is ${baseEndpoint}.
233
+ The request tool prepends the base URL automatically.
234
+ Use ONLY the relative path after the base prefix: e.g. /suites, /suites/{id} — NOT the full spec path.
235
+ </path_mapping>
236
+ `;
237
+ }
238
+ prompt += specBlock;
239
+ }
240
+
241
+ return prompt;
242
+ }
243
+
244
+ private buildSystemPrompt(): string {
245
+ return dedent`
246
+ <role>
247
+ You are a senior API test engineer. Execute HTTP requests to test API endpoints.
248
+ Validate responses against expectations.
249
+ </role>
250
+
251
+ <approach>
252
+ 1. Use the request tool to make HTTP calls — response preview shows first 500 chars
253
+ 2. If you need a related endpoint (e.g., to create prerequisite data), use schemaFor to discover it
254
+ 3. Extract IDs and key values from the response preview to chain requests
255
+ 4. After each request, use verifyStructure with a Zod schema to validate response shape
256
+ Example: schema = "z.object({ id: z.number(), name: z.string(), items: z.array(z.string()) })"
257
+ Use z.any() for fields you don't care about, z.optional() for nullable fields
258
+ 5. Use verifyData with expect() assertions to check specific values
259
+ The "response" variable is the full parsed JSON body — use the structure from verifyStructure to access nested fields correctly
260
+ Example: "expect(response.name).toBe('Test Suite')"
261
+ Example: "expect(response.data.items).toHaveLength(3)"
262
+ Example: "expect(response.status).not.toBe('deleted')"
263
+ 6. Use record to document findings and observations
264
+ 7. Use finish when all test goals are achieved and verified
265
+ 8. Use stop only if the scenario cannot be completed at all
266
+ </approach>
267
+
268
+ <rules>
269
+ - Always check HTTP status codes from the request tool result
270
+ - After each request, verify structure with a Zod schema matching the API spec
271
+ - Use verifyData with expect() for value assertions — "response" is the full parsed JSON, use the structure returned by verifyStructure to access the correct paths
272
+ - For CRUD tests: create first, extract ID from preview, then read/update/delete
273
+ - Chain requests logically — extract IDs from response preview
274
+ - Record important findings as you go
275
+ - Be precise about what you expect vs what you observe
276
+ - If a test requires data from another endpoint, use schemaFor to look it up before guessing
277
+ </rules>
278
+ `;
279
+ }
280
+
281
+ private buildFinalReviewSystemPrompt(): string {
282
+ return dedent`
283
+ You evaluate API test results.
284
+ Analyze notes and request log to determine if test goals were achieved.
285
+ Decide if assertion failures are critical (should fail the test) or minor (test still passes).
286
+
287
+
288
+ Status code rules:
289
+ - 500+ errors are always critical failures regardless of test type
290
+ - 4xx codes (400, 403, 404, 412, 422, etc.) are NOT failures by themselves — different APIs return different 4xx codes for similar situations, so do not be strict about the exact 4xx code
291
+
292
+ For positive tests (creating/updating data):
293
+ - Focus on whether the expected data was actually saved correctly
294
+ - Never trust POST/PUT/PATCH response alone — a follow-up GET must confirm the data was persisted
295
+ - The real measure of success is the data state verified via GET, not the write response or status code
296
+
297
+ For negative tests (invalid input, unauthorized access):
298
+ - PUT and PATCH methods are usually the same so do not treat them differently.
299
+ - Verify the invalid data was NOT created — check with GET to ensure nothing was saved by accident
300
+ - Any 4xx response that correctly rejects the request is acceptable
301
+
302
+ Critical failures: 500+ errors, data not saved in positive tests, invalid data accidentally created in negative tests, broken CRUD operations.
303
+ Minor failures: optional fields missing, cosmetic differences, extra fields in response, different-than-expected 4xx code.
304
+ `;
305
+ }
306
+ }
@@ -0,0 +1,28 @@
1
+ import { ApiClient as BaseApiClient } from '../../../src/api/api-client.ts';
2
+ import type { HookFn } from './config.ts';
3
+
4
+ export class ApiClient extends BaseApiClient {
5
+ private bootstrapHook?: HookFn;
6
+ private teardownHook?: HookFn;
7
+
8
+ constructor(baseEndpoint: string, defaultHeaders: Record<string, string> = {}, hooks?: { bootstrap?: HookFn; teardown?: HookFn }) {
9
+ super(baseEndpoint, defaultHeaders);
10
+ this.bootstrapHook = hooks?.bootstrap;
11
+ this.teardownHook = hooks?.teardown;
12
+ }
13
+
14
+ async bootstrap(): Promise<void> {
15
+ if (!this.bootstrapHook) return;
16
+ const ctx = { headers: this.getHeaders(), baseEndpoint: this.getBaseEndpoint() };
17
+ const result = await this.bootstrapHook(ctx);
18
+ if (result && typeof result === 'object') {
19
+ this.setHeaders(result);
20
+ }
21
+ }
22
+
23
+ async teardown(): Promise<void> {
24
+ if (!this.teardownHook) return;
25
+ const ctx = { headers: this.getHeaders(), baseEndpoint: this.getBaseEndpoint() };
26
+ await this.teardownHook(ctx);
27
+ }
28
+ }
@@ -0,0 +1,203 @@
1
+ import { existsSync, mkdirSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { AIProvider } from '../../../src/ai/provider.ts';
4
+ import { Reporter } from '../../../src/reporter.ts';
5
+ import { Plan } from '../../../src/test-plan.ts';
6
+ import { setVerboseMode, tag } from '../../../src/utils/logger.ts';
7
+ import { Chief } from './ai/chief.ts';
8
+ import { Curler } from './ai/curler.ts';
9
+ import { ApiClient } from './api-client.ts';
10
+ import { type ApibotConfig, ApibotConfigParser } from './config.ts';
11
+ import { RequestStore } from '../../../src/api/request-store.ts';
12
+ import { extractEndpointDefinition, loadSpec, searchEndpoints, validateSpecs } from '../../../src/api/spec-reader.ts';
13
+
14
+ export class ApiBot {
15
+ private configParser: ApibotConfigParser;
16
+ private provider!: AIProvider;
17
+ private config!: ApibotConfig;
18
+ private agents: Record<string, any> = {};
19
+ private currentPlan?: Plan;
20
+ private apiClient!: ApiClient;
21
+ private requestState!: RequestStore;
22
+ private reporter!: Reporter;
23
+ private options: ApibotOptions;
24
+ private apiSpec: any;
25
+
26
+ constructor(options: ApibotOptions = {}) {
27
+ this.options = options;
28
+ this.configParser = ApibotConfigParser.getInstance();
29
+ if (this.options.verbose) {
30
+ process.env.DEBUG = 'apibot:*';
31
+ setVerboseMode(true);
32
+ }
33
+ }
34
+
35
+ async start(): Promise<void> {
36
+ this.config = await this.configParser.loadConfig({ config: this.options.config, path: this.options.path });
37
+ this.provider = new AIProvider(this.config.ai);
38
+ await this.provider.validateConnection();
39
+
40
+ this.apiClient = new ApiClient(this.config.api.baseEndpoint, this.config.api.headers || {}, {
41
+ bootstrap: this.config.api.bootstrap,
42
+ teardown: this.config.api.teardown,
43
+ });
44
+ await this.apiClient.bootstrap();
45
+
46
+ const outputDir = this.configParser.getOutputDir();
47
+ this.configParser.ensureDirectory(outputDir);
48
+ this.requestState = new RequestStore(outputDir);
49
+ this.reporter = new Reporter(this.config.reporter);
50
+
51
+ validateSpecs(this.config.api.spec);
52
+ this.apiSpec = await loadSpec(this.config.api.spec!, outputDir);
53
+ tag('info').log('OpenAPI spec loaded');
54
+
55
+ await this.healthCheck();
56
+ }
57
+
58
+ private async healthCheck(): Promise<void> {
59
+ const baseUrl = this.config.api.baseEndpoint;
60
+ const headers = this.config.api.headers || {};
61
+ const headerSummary = Object.entries(headers)
62
+ .map(([k, v]) => {
63
+ const lower = k.toLowerCase();
64
+ if (lower === 'authorization' || lower === 'x-api-key') return `${k}: ${v.slice(0, 12)}...`;
65
+ return `${k}: ${v}`;
66
+ })
67
+ .join(', ');
68
+
69
+ tag('info').log(`Connecting to ${baseUrl}`);
70
+ if (headerSummary) tag('info').log(`Headers: ${headerSummary}`);
71
+
72
+ const result = await this.apiClient.request({ method: 'GET', path: '/' });
73
+
74
+ if (result.error) {
75
+ tag('error').log(`Connection failed: ${result.error}`);
76
+ throw new Error(`Cannot connect to ${baseUrl}: ${result.error}`);
77
+ }
78
+
79
+ tag('success').log(`Connected to ${baseUrl} (${result.status} ${result.statusText})`);
80
+ }
81
+
82
+ async stop(): Promise<void> {
83
+ await this.reporter?.finishRun();
84
+ await this.apiClient?.teardown();
85
+ }
86
+
87
+ createAgent<T>(factory: (deps: { ai: AIProvider; config: ApibotConfig; apiClient: ApiClient; requestState: RequestStore }) => T): T {
88
+ return factory({
89
+ ai: this.provider,
90
+ config: this.config,
91
+ apiClient: this.apiClient,
92
+ requestState: this.requestState,
93
+ });
94
+ }
95
+
96
+ agentChief(): Chief {
97
+ return (this.agents.chief ||= this.createAgent(({ ai, config, apiClient }) => new Chief(ai, config, apiClient)));
98
+ }
99
+
100
+ agentCurler(): Curler {
101
+ return (this.agents.curler ||= this.createAgent(({ ai, apiClient, requestState }) => new Curler(ai, apiClient, requestState, this.reporter)));
102
+ }
103
+
104
+ async plan(endpoint: string, opts: { style?: string; fresh?: boolean } = {}): Promise<Plan> {
105
+ if (opts.fresh) {
106
+ this.currentPlan = undefined;
107
+ this.agents.chief = undefined;
108
+ }
109
+
110
+ const chief = this.agentChief();
111
+ const specDefinition = this.getEndpointDefinition(endpoint);
112
+ this.currentPlan = await chief.plan(endpoint, { style: opts.style, specDefinition });
113
+ const savedPath = this.savePlan();
114
+ if (savedPath) {
115
+ tag('info').log(`Plan saved to: ${path.relative(process.cwd(), savedPath)}`);
116
+ }
117
+ return this.currentPlan;
118
+ }
119
+
120
+ loadPlan(filename: string): Plan {
121
+ const plansDir = this.configParser.getPlansDir();
122
+ let planPath = filename;
123
+
124
+ if (!path.isAbsolute(filename)) {
125
+ planPath = path.join(plansDir, filename);
126
+ if (!existsSync(planPath) && !filename.endsWith('.md')) {
127
+ planPath = path.join(plansDir, `${filename}.md`);
128
+ }
129
+ }
130
+
131
+ if (!existsSync(planPath)) {
132
+ throw new Error(`Plan file not found: ${planPath}`);
133
+ }
134
+
135
+ this.currentPlan = Plan.fromMarkdown(planPath);
136
+ return this.currentPlan;
137
+ }
138
+
139
+ savePlan(filename?: string): string | null {
140
+ if (!this.currentPlan) return null;
141
+
142
+ const plansDir = this.configParser.getPlansDir();
143
+ if (!existsSync(plansDir)) {
144
+ mkdirSync(plansDir, { recursive: true });
145
+ }
146
+
147
+ const planFilename = filename || this.generatePlanFilename();
148
+ const planPath = path.join(plansDir, planFilename);
149
+ this.currentPlan.saveToMarkdown(planPath);
150
+ return planPath;
151
+ }
152
+
153
+ getCurrentPlan(): Plan | undefined {
154
+ return this.currentPlan;
155
+ }
156
+
157
+ getProvider(): AIProvider {
158
+ return this.provider;
159
+ }
160
+
161
+ getConfig(): ApibotConfig {
162
+ return this.config;
163
+ }
164
+
165
+ getConfigParser(): ApibotConfigParser {
166
+ return this.configParser;
167
+ }
168
+
169
+ getRequestState(): RequestStore {
170
+ return this.requestState;
171
+ }
172
+
173
+ getEndpointDefinition(endpoint: string): string {
174
+ return extractEndpointDefinition(this.apiSpec, endpoint, this.config.api.baseEndpoint);
175
+ }
176
+
177
+ searchSpec(query: string): string {
178
+ return searchEndpoints(this.apiSpec, query, this.config.api.baseEndpoint);
179
+ }
180
+
181
+ tryGetEndpointDefinition(endpoint: string): string | undefined {
182
+ try {
183
+ return this.getEndpointDefinition(endpoint);
184
+ } catch (e) {
185
+ tag('warning').log(e instanceof Error ? e.message : 'Could not extract spec for endpoint');
186
+ return undefined;
187
+ }
188
+ }
189
+
190
+ private generatePlanFilename(): string {
191
+ const endpoint = this.currentPlan?.url || '/';
192
+ const sanitized = endpoint.replace(/^\//, '').replace(/[^a-zA-Z0-9]/g, '_') || 'root';
193
+ return `${sanitized.slice(0, 200)}.md`;
194
+ }
195
+ }
196
+
197
+ interface ApibotOptions {
198
+ verbose?: boolean;
199
+ config?: string;
200
+ path?: string;
201
+ }
202
+
203
+ export type { ApibotOptions };