explorbot 0.1.12 → 0.1.13

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 (59) hide show
  1. package/bin/explorbot-cli.ts +21 -21
  2. package/dist/bin/explorbot-cli.js +3 -3
  3. package/dist/package.json +3 -2
  4. package/dist/rules/researcher/container-rules.md +2 -0
  5. package/dist/src/action-result.js +2 -1
  6. package/dist/src/action.js +0 -6
  7. package/dist/src/ai/captain.js +0 -2
  8. package/dist/src/ai/driller.js +1108 -0
  9. package/dist/src/ai/pilot.js +31 -22
  10. package/dist/src/ai/rules.js +3 -5
  11. package/dist/src/ai/session-analyst.js +117 -0
  12. package/dist/src/ai/tester.js +13 -2
  13. package/dist/src/commands/base-command.js +6 -6
  14. package/dist/src/commands/drill-command.js +3 -2
  15. package/dist/src/commands/exit-command.js +1 -0
  16. package/dist/src/commands/explore-command.js +1 -0
  17. package/dist/src/components/AddRule.js +1 -1
  18. package/dist/src/explorbot.js +48 -8
  19. package/dist/src/explorer.js +9 -8
  20. package/dist/src/reporter.js +64 -3
  21. package/dist/src/state-manager.js +4 -3
  22. package/dist/src/stats.js +5 -0
  23. package/dist/src/utils/aria.js +354 -529
  24. package/dist/src/utils/hooks-runner.js +2 -8
  25. package/dist/src/utils/html.js +371 -0
  26. package/dist/src/utils/unique-names.js +12 -1
  27. package/dist/src/utils/url-matcher.js +6 -1
  28. package/dist/src/utils/web-element.js +27 -24
  29. package/dist/src/utils/xpath.js +1 -1
  30. package/package.json +3 -2
  31. package/rules/researcher/container-rules.md +2 -0
  32. package/src/action-result.ts +2 -1
  33. package/src/action.ts +0 -8
  34. package/src/ai/captain.ts +0 -2
  35. package/src/ai/driller.ts +1194 -0
  36. package/src/ai/pilot.ts +31 -21
  37. package/src/ai/rules.ts +3 -5
  38. package/src/ai/session-analyst.ts +133 -0
  39. package/src/ai/tester.ts +15 -2
  40. package/src/commands/base-command.ts +6 -6
  41. package/src/commands/drill-command.ts +3 -2
  42. package/src/commands/exit-command.ts +1 -0
  43. package/src/commands/explore-command.ts +1 -0
  44. package/src/components/AddRule.tsx +1 -1
  45. package/src/config.ts +4 -0
  46. package/src/explorbot.ts +55 -10
  47. package/src/explorer.ts +9 -8
  48. package/src/reporter.ts +64 -3
  49. package/src/state-manager.ts +4 -3
  50. package/src/stats.ts +7 -0
  51. package/src/utils/aria.ts +367 -537
  52. package/src/utils/hooks-runner.ts +2 -6
  53. package/src/utils/html.ts +381 -0
  54. package/src/utils/unique-names.ts +13 -0
  55. package/src/utils/url-matcher.ts +5 -1
  56. package/src/utils/web-element.ts +31 -28
  57. package/src/utils/xpath.ts +1 -1
  58. package/dist/src/ai/bosun.js +0 -456
  59. package/src/ai/bosun.ts +0 -571
@@ -586,32 +586,32 @@ addCommonOptions(program.command('research <url>').description('Research a page
586
586
  }
587
587
  );
588
588
 
589
- addCommonOptions(program.command('drill <url>').description('Drill all components on a page to learn interactions').option('--knowledge <path>', 'Save learned interactions to knowledge file at this URL path').option('--max <count>', 'Maximum number of components to drill', '20')).action(
590
- async (url, options) => {
591
- try {
592
- const explorBot = new ExplorBot(buildExplorBotOptions(url, options));
593
- await explorBot.start();
589
+ addCommonOptions(
590
+ program.command('drill <url>').alias('driller').description('Drill all components on a page to learn interactions').option('--knowledge <path>', 'Save learned interactions to knowledge file at this URL path').option('--max-components <count>', 'Maximum number of components to drill')
591
+ ).action(async (url, options) => {
592
+ try {
593
+ const explorBot = new ExplorBot(buildExplorBotOptions(url, options));
594
+ await explorBot.start();
594
595
 
595
- await explorBot.visit(url);
596
+ await explorBot.visit(url);
596
597
 
597
- const plan = await explorBot.agentBosun().drill({
598
- knowledgePath: options.knowledge,
599
- maxComponents: Number.parseInt(options.max, 10),
600
- interactive: false,
601
- });
598
+ const plan = await explorBot.agentDriller().drill({
599
+ knowledgePath: options.knowledge,
600
+ maxComponents: Number.parseInt(options.maxComponents || '30', 10),
601
+ interactive: false,
602
+ });
602
603
 
603
- console.log(`\nDrill completed: ${plan.tests.length} components`);
604
- console.log(`Successful: ${plan.tests.filter((t) => t.isSuccessful).length}`);
605
- console.log(`Failed: ${plan.tests.filter((t) => t.hasFailed).length}`);
604
+ console.log(`\nDrill completed: ${plan.tests.length} components`);
605
+ console.log(`Successful: ${plan.tests.filter((t) => t.isSuccessful).length}`);
606
+ console.log(`Failed: ${plan.tests.filter((t) => t.hasFailed).length}`);
606
607
 
607
- await explorBot.stop();
608
- await showStatsAndExit(0);
609
- } catch (error) {
610
- console.error('Failed:', error instanceof Error ? error.message : 'Unknown error');
611
- await showStatsAndExit(1);
612
- }
608
+ await explorBot.stop();
609
+ await showStatsAndExit(0);
610
+ } catch (error) {
611
+ console.error('Failed:', error instanceof Error ? error.message : 'Unknown error');
612
+ await showStatsAndExit(1);
613
613
  }
614
- );
614
+ });
615
615
 
616
616
  program
617
617
  .command('context <url>')
@@ -531,14 +531,14 @@ addCommonOptions(program.command('research <url>').description('Research a page
531
531
  await showStatsAndExit(1);
532
532
  }
533
533
  });
534
- addCommonOptions(program.command('drill <url>').description('Drill all components on a page to learn interactions').option('--knowledge <path>', 'Save learned interactions to knowledge file at this URL path').option('--max <count>', 'Maximum number of components to drill', '20')).action(async (url, options) => {
534
+ addCommonOptions(program.command('drill <url>').alias('driller').description('Drill all components on a page to learn interactions').option('--knowledge <path>', 'Save learned interactions to knowledge file at this URL path').option('--max-components <count>', 'Maximum number of components to drill')).action(async (url, options) => {
535
535
  try {
536
536
  const explorBot = new ExplorBot(buildExplorBotOptions(url, options));
537
537
  await explorBot.start();
538
538
  await explorBot.visit(url);
539
- const plan = await explorBot.agentBosun().drill({
539
+ const plan = await explorBot.agentDriller().drill({
540
540
  knowledgePath: options.knowledge,
541
- maxComponents: Number.parseInt(options.max, 10),
541
+ maxComponents: Number.parseInt(options.maxComponents || '30', 10),
542
542
  interactive: false,
543
543
  });
544
544
  console.log(`\nDrill completed: ${plan.tests.length} components`);
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "explorbot",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "CLI app built with React Ink, CodeceptJS, and Playwright",
5
5
  "license": "Elastic-2.0",
6
6
  "type": "module",
@@ -78,7 +78,7 @@
78
78
  "@opentelemetry/sdk-trace-base": "^2.2.0",
79
79
  "@opentelemetry/semantic-conventions": "^1.38.0",
80
80
  "@scalar/openapi-parser": "^0.25.6",
81
- "@testomatio/reporter": "^2.7.6",
81
+ "@testomatio/reporter": "^2.7.9-beta.2-markdown",
82
82
  "ai": "^6.0.6",
83
83
  "axe-core": "^4.11.1",
84
84
  "bash-tool": "^1.3.15",
@@ -109,6 +109,7 @@
109
109
  "strip-ansi": "^7.1.2",
110
110
  "turndown": "^7.2.1",
111
111
  "unique-names-generator": "^4.7.1",
112
+ "yaml": "^2.8.3",
112
113
  "yargs": "^17.7.2",
113
114
  "zod": "^4.1.8"
114
115
  },
@@ -5,6 +5,8 @@ Container CSS must be a SINGLE semantic selector — one class, one id, or one a
5
5
  - VALID: semantic class names that describe what the section IS (`.product-list`, `.sidebar-menu`, `.user-profile`, `.search-results`), semantic roles (`[role="dialog"]`), semantic ids (`#main-content`)
6
6
 
7
7
  The container must uniquely identify a semantic wrapper, not a path through the DOM.
8
+
9
+ Iframes are not sections — list each iframe as a single row of type `iframe` inside the section that contains it. Never use an iframe selector as a section's `> Container:`.
8
10
  </container_rules>
9
11
 
10
12
  <css_selector_rules>
@@ -371,8 +371,9 @@ export class ActionResult {
371
371
  try {
372
372
  const urlObj = new URL(this.url);
373
373
  const path = urlObj.pathname.replace(/\/$/, '') || '/';
374
+ const search = urlObj.search || '';
374
375
  const hash = urlObj.hash || '';
375
- return path + hash;
376
+ return path + search + hash;
376
377
  }
377
378
  catch {
378
379
  // If URL parsing fails, assume it's already a relative URL
@@ -324,12 +324,6 @@ class Action {
324
324
  }
325
325
  catch (error) {
326
326
  this.lastError = error;
327
- if (error && typeof error === 'object') {
328
- const errorObj = error;
329
- if (typeof errorObj.fetchDetails === 'function') {
330
- await errorObj.fetchDetails();
331
- }
332
- }
333
327
  debugLog(`Attempt failed: ${codeBlock}: ${errorToString(error) || this.lastError?.toString()}`);
334
328
  return false;
335
329
  }
@@ -174,8 +174,6 @@ export class Captain extends CaptainBase {
174
174
  ${knowledge}
175
175
 
176
176
  ${experience}
177
-
178
- Use runCommand("/research") if you need deeper page understanding or UI element mapping.
179
177
  `;
180
178
  }
181
179
  planSummary() {