explorbot 0.1.31 → 0.2.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 (288) hide show
  1. package/README.md +14 -14
  2. package/bin/explorbot-cli.ts +4 -3
  3. package/boat/doc-collector/src/ai/documentarian.ts +22 -27
  4. package/boat/doc-collector/src/ai/tools.ts +67 -10
  5. package/boat/doc-collector/src/docbot.ts +28 -7
  6. package/boat/doc-collector/src/docs-renderer.ts +19 -24
  7. package/boat/doc-collector/src/screenshots.ts +33 -1
  8. package/boat/doc-collector/src/state-diagram.ts +281 -0
  9. package/dist/bin/explorbot-cli.js +3 -3
  10. package/dist/boat/doc-collector/src/ai/documentarian.js +16 -6
  11. package/dist/boat/doc-collector/src/ai/tools.js +47 -10
  12. package/dist/boat/doc-collector/src/docbot.js +25 -6
  13. package/dist/boat/doc-collector/src/docs-renderer.js +18 -3
  14. package/dist/boat/doc-collector/src/screenshots.js +29 -0
  15. package/dist/boat/doc-collector/src/state-diagram.js +200 -0
  16. package/dist/package.json +8 -6
  17. package/dist/src/action-result.d.ts +131 -0
  18. package/dist/src/action-result.js +82 -159
  19. package/dist/src/action.d.ts +43 -0
  20. package/dist/src/action.js +18 -106
  21. package/dist/src/activity.d.ts +26 -0
  22. package/dist/src/ai/agent.d.ts +3 -0
  23. package/dist/src/ai/captain/file-tools.d.ts +28 -0
  24. package/dist/src/ai/captain/idle-mode.d.ts +11 -0
  25. package/dist/src/ai/captain/mixin.d.ts +10 -0
  26. package/dist/src/ai/captain/test-mode.d.ts +13 -0
  27. package/dist/src/ai/captain/web-mode.d.ts +13 -0
  28. package/dist/src/ai/captain/web-mode.js +0 -7
  29. package/dist/src/ai/captain.d.ts +141 -0
  30. package/dist/src/ai/captain.js +4 -19
  31. package/dist/src/ai/conversation.d.ts +28 -0
  32. package/dist/src/ai/conversation.js +9 -28
  33. package/dist/src/ai/driller.d.ts +157 -0
  34. package/dist/src/ai/driller.js +3 -12
  35. package/dist/src/ai/experience-compactor.d.ts +53 -0
  36. package/dist/src/ai/experience-compactor.js +16 -33
  37. package/dist/src/ai/fisherman-tools.d.ts +90 -0
  38. package/dist/src/ai/fisherman-tools.js +1 -1
  39. package/dist/src/ai/fisherman.d.ts +29 -0
  40. package/dist/src/ai/fisherman.js +0 -3
  41. package/dist/src/ai/historian/codeceptjs.d.ts +17 -0
  42. package/dist/src/ai/historian/codeceptjs.js +3 -2
  43. package/dist/src/ai/historian/experience.d.ts +40 -0
  44. package/dist/src/ai/historian/mixin.d.ts +2 -0
  45. package/dist/src/ai/historian/playwright.d.ts +22 -0
  46. package/dist/src/ai/historian/playwright.js +3 -2
  47. package/dist/src/ai/historian/screencast.d.ts +32 -0
  48. package/dist/src/ai/historian/utils.d.ts +3 -0
  49. package/dist/src/ai/historian/utils.js +0 -1
  50. package/dist/src/ai/historian.d.ts +109 -0
  51. package/dist/src/ai/historian.js +1 -5
  52. package/dist/src/ai/navigator.d.ts +54 -0
  53. package/dist/src/ai/navigator.js +11 -46
  54. package/dist/src/ai/pilot.d.ts +81 -0
  55. package/dist/src/ai/pilot.js +6 -17
  56. package/dist/src/ai/planner/session-dedup.d.ts +12 -0
  57. package/dist/src/ai/planner/styles.d.ts +6 -0
  58. package/dist/src/ai/planner/subpages.d.ts +35 -0
  59. package/dist/src/ai/planner.d.ts +79 -0
  60. package/dist/src/ai/planner.js +49 -37
  61. package/dist/src/ai/provider.d.ts +53 -0
  62. package/dist/src/ai/provider.js +78 -130
  63. package/dist/src/ai/quartermaster.d.ts +56 -0
  64. package/dist/src/ai/quartermaster.js +4 -10
  65. package/dist/src/ai/rerunner.d.ts +48 -0
  66. package/dist/src/ai/rerunner.js +14 -22
  67. package/dist/src/ai/researcher/cache.d.ts +6 -0
  68. package/dist/src/ai/researcher/cache.js +11 -18
  69. package/dist/src/ai/researcher/coordinates.d.ts +56 -0
  70. package/dist/src/ai/researcher/deep-analysis.d.ts +74 -0
  71. package/dist/src/ai/researcher/deep-analysis.js +3 -6
  72. package/dist/src/ai/researcher/fingerprint-worker.d.ts +1 -0
  73. package/dist/src/ai/researcher/focus.d.ts +8 -0
  74. package/dist/src/ai/researcher/locators.d.ts +36 -0
  75. package/dist/src/ai/researcher/mixin.d.ts +2 -0
  76. package/dist/src/ai/researcher/parser.d.ts +35 -0
  77. package/dist/src/ai/researcher/parser.js +1 -1
  78. package/dist/src/ai/researcher/research-result.d.ts +15 -0
  79. package/dist/src/ai/researcher/research-result.js +0 -19
  80. package/dist/src/ai/researcher/sections.d.ts +19 -0
  81. package/dist/src/ai/researcher/sections.js +5 -1
  82. package/dist/src/ai/researcher.js +12 -53
  83. package/dist/src/ai/rules.d.ts +16 -0
  84. package/dist/src/ai/rules.js +22 -15
  85. package/dist/src/ai/session-analyst.d.ts +11 -0
  86. package/dist/src/ai/session-analyst.js +8 -5
  87. package/dist/src/ai/task-agent.d.ts +28 -0
  88. package/dist/src/ai/task-agent.js +2 -27
  89. package/dist/src/ai/tester.d.ts +101 -0
  90. package/dist/src/ai/tester.js +10 -61
  91. package/dist/src/ai/tools.d.ts +52 -0
  92. package/dist/src/ai/tools.js +119 -101
  93. package/dist/src/api/api-client.d.ts +17 -0
  94. package/dist/src/api/request-result.d.ts +44 -0
  95. package/dist/src/api/request-store.d.ts +29 -0
  96. package/dist/src/api/spec-reader.d.ts +5 -0
  97. package/dist/src/api/xhr-capture.d.ts +10 -0
  98. package/dist/src/browser-server.d.ts +10 -0
  99. package/dist/src/command-handler.d.ts +68 -0
  100. package/dist/src/commands/add-rule-command.d.ts +11 -0
  101. package/dist/src/commands/base-command.d.ts +26 -0
  102. package/dist/src/commands/clean-command.d.ts +12 -0
  103. package/dist/src/commands/compact-command.d.ts +20 -0
  104. package/dist/src/commands/compact-command.js +6 -6
  105. package/dist/src/commands/context-aria-command.d.ts +6 -0
  106. package/dist/src/commands/context-command.d.ts +11 -0
  107. package/dist/src/commands/context-command.js +1 -1
  108. package/dist/src/commands/context-data-command.d.ts +6 -0
  109. package/dist/src/commands/context-experience-command.d.ts +6 -0
  110. package/dist/src/commands/context-html-command.d.ts +6 -0
  111. package/dist/src/commands/context-knowledge-command.d.ts +6 -0
  112. package/dist/src/commands/context-knowledge-command.js +1 -1
  113. package/dist/src/commands/debug-command.d.ts +6 -0
  114. package/dist/src/commands/drill-command.d.ts +10 -0
  115. package/dist/src/commands/exit-command.d.ts +7 -0
  116. package/dist/src/commands/experience-command.d.ts +15 -0
  117. package/dist/src/commands/experience-command.js +1 -1
  118. package/dist/src/commands/explore-command.d.ts +51 -0
  119. package/dist/src/commands/freesail-command.d.ts +12 -0
  120. package/dist/src/commands/help-command.d.ts +6 -0
  121. package/dist/src/commands/index.d.ts +4 -0
  122. package/dist/src/commands/init-command.d.ts +7 -0
  123. package/dist/src/commands/knows-command.d.ts +10 -0
  124. package/dist/src/commands/knows-command.js +1 -1
  125. package/dist/src/commands/learn-command.d.ts +7 -0
  126. package/dist/src/commands/learn-command.js +3 -1
  127. package/dist/src/commands/navigate-command.d.ts +7 -0
  128. package/dist/src/commands/path-command.d.ts +10 -0
  129. package/dist/src/commands/plan-clear-command.d.ts +7 -0
  130. package/dist/src/commands/plan-command.d.ts +14 -0
  131. package/dist/src/commands/plan-edit-command.d.ts +7 -0
  132. package/dist/src/commands/plan-load-command.d.ts +7 -0
  133. package/dist/src/commands/plan-reload-command.d.ts +7 -0
  134. package/dist/src/commands/plan-save-command.d.ts +7 -0
  135. package/dist/src/commands/plans-command.d.ts +21 -0
  136. package/dist/src/commands/rerun-command.d.ts +7 -0
  137. package/dist/src/commands/research-command.d.ts +11 -0
  138. package/dist/src/commands/runs-command.d.ts +7 -0
  139. package/dist/src/commands/start-command.d.ts +7 -0
  140. package/dist/src/commands/status-command.d.ts +6 -0
  141. package/dist/src/commands/test-command.d.ts +11 -0
  142. package/dist/src/components/ActivityPane.d.ts +6 -0
  143. package/dist/src/components/AddKnowledge.d.ts +10 -0
  144. package/dist/src/components/AddKnowledge.js +3 -7
  145. package/dist/src/components/AddRule.d.ts +9 -0
  146. package/dist/src/components/App.d.ts +9 -0
  147. package/dist/src/components/App.js +2 -2
  148. package/dist/src/components/Autocomplete.d.ts +3 -0
  149. package/dist/src/components/InputPane.d.ts +13 -0
  150. package/dist/src/components/InputReadline.d.ts +17 -0
  151. package/dist/src/components/LogPane.d.ts +6 -0
  152. package/dist/src/components/PlanEditor.d.ts +9 -0
  153. package/dist/src/components/PlanPane.d.ts +13 -0
  154. package/dist/src/components/SessionTimer.d.ts +6 -0
  155. package/dist/src/components/StateTransitionPane.d.ts +8 -0
  156. package/dist/src/components/StatusPane.d.ts +4 -0
  157. package/dist/src/components/TaskPane.d.ts +9 -0
  158. package/dist/src/components/Welcome.d.ts +3 -0
  159. package/dist/src/components/WelcomeChecklist.d.ts +9 -0
  160. package/dist/src/components/WelcomeCommands.d.ts +6 -0
  161. package/dist/src/components/autocomplete-store.d.ts +10 -0
  162. package/dist/src/components/parse-keypress.d.ts +12 -0
  163. package/dist/src/config.d.ts +253 -0
  164. package/dist/src/config.js +12 -0
  165. package/dist/src/execution-controller.d.ts +25 -0
  166. package/dist/src/experience-tracker.d.ts +112 -0
  167. package/dist/src/experience-tracker.js +83 -155
  168. package/dist/src/explorbot.d.ts +106 -0
  169. package/dist/src/explorbot.js +17 -51
  170. package/dist/src/explorer.d.ts +129 -0
  171. package/dist/src/explorer.js +31 -77
  172. package/dist/src/index.d.ts +6 -0
  173. package/dist/src/index.js +2 -55
  174. package/dist/src/knowledge-tracker.d.ts +33 -0
  175. package/dist/src/knowledge-tracker.js +47 -47
  176. package/dist/src/observability.d.ts +13 -0
  177. package/dist/src/observability.js +2 -1
  178. package/dist/src/playwright-recorder.d.ts +31 -0
  179. package/dist/src/reporter.d.ts +34 -0
  180. package/dist/src/state-manager.d.ts +160 -0
  181. package/dist/src/state-manager.js +10 -136
  182. package/dist/src/stats.d.ts +24 -0
  183. package/dist/src/suite.d.ts +24 -0
  184. package/dist/src/test-plan.d.ts +166 -0
  185. package/dist/src/utils/aria.d.ts +25 -0
  186. package/dist/src/utils/aria.js +4 -1
  187. package/dist/src/utils/browser-errors.d.ts +8 -0
  188. package/dist/src/utils/cache.d.ts +15 -0
  189. package/dist/src/utils/cache.js +34 -0
  190. package/dist/src/utils/cli-name.d.ts +1 -0
  191. package/dist/src/utils/code-extractor.d.ts +1 -0
  192. package/dist/src/utils/context-formatter.d.ts +31 -0
  193. package/dist/src/utils/context-formatter.js +15 -27
  194. package/dist/src/utils/error-page.d.ts +12 -0
  195. package/dist/src/utils/expandable.d.ts +4 -0
  196. package/dist/src/utils/hooks-runner.d.ts +15 -0
  197. package/dist/src/utils/html-diff.d.ts +19 -0
  198. package/dist/src/utils/html.d.ts +129 -0
  199. package/dist/src/utils/html.js +71 -0
  200. package/dist/src/utils/log-filters.d.ts +6 -0
  201. package/dist/src/utils/logger.d.ts +35 -0
  202. package/dist/src/utils/loop.d.ts +35 -0
  203. package/dist/src/utils/markdown-files.d.ts +10 -0
  204. package/dist/src/utils/markdown-files.js +21 -0
  205. package/dist/src/utils/markdown-parser.d.ts +17 -0
  206. package/dist/src/utils/markdown-query.d.ts +46 -0
  207. package/dist/src/utils/markdown-query.js +14 -1
  208. package/dist/src/utils/markdown-terminal.d.ts +1 -0
  209. package/dist/src/utils/next-steps.d.ts +11 -0
  210. package/dist/src/utils/page-readiness.d.ts +7 -0
  211. package/dist/src/utils/page-readiness.js +1 -1
  212. package/dist/src/utils/research-parser.d.ts +1 -0
  213. package/dist/src/utils/retry.d.ts +8 -0
  214. package/dist/src/utils/rules-loader.d.ts +12 -0
  215. package/dist/src/utils/secrets.d.ts +4 -0
  216. package/dist/src/utils/secrets.js +28 -0
  217. package/dist/src/utils/step-analyzer.d.ts +11 -0
  218. package/dist/src/utils/strings.d.ts +5 -0
  219. package/dist/src/utils/strings.js +10 -0
  220. package/dist/src/utils/test-files.d.ts +3 -0
  221. package/dist/src/utils/test-plan-markdown.d.ts +9 -0
  222. package/dist/src/utils/throttle.d.ts +2 -0
  223. package/dist/src/utils/unique-names.d.ts +2 -0
  224. package/dist/src/utils/url-matcher.d.ts +6 -0
  225. package/dist/src/utils/web-element.d.ts +45 -0
  226. package/dist/src/utils/web-element.js +3 -0
  227. package/dist/src/utils/web-sandbox.d.ts +4 -0
  228. package/dist/src/utils/web-sandbox.js +37 -0
  229. package/dist/src/utils/xpath.d.ts +17 -0
  230. package/package.json +8 -6
  231. package/src/action-result.ts +80 -168
  232. package/src/action.ts +16 -123
  233. package/src/ai/captain/web-mode.ts +0 -7
  234. package/src/ai/captain.ts +5 -17
  235. package/src/ai/conversation.ts +9 -32
  236. package/src/ai/driller.ts +3 -16
  237. package/src/ai/experience-compactor.ts +16 -35
  238. package/src/ai/fisherman-tools.ts +1 -1
  239. package/src/ai/fisherman.ts +0 -4
  240. package/src/ai/historian/codeceptjs.ts +4 -2
  241. package/src/ai/historian/playwright.ts +4 -2
  242. package/src/ai/historian/utils.ts +0 -1
  243. package/src/ai/historian.ts +4 -7
  244. package/src/ai/navigator.ts +13 -49
  245. package/src/ai/pilot.ts +6 -16
  246. package/src/ai/planner.ts +56 -44
  247. package/src/ai/provider.ts +86 -139
  248. package/src/ai/quartermaster.ts +34 -41
  249. package/src/ai/rerunner.ts +17 -21
  250. package/src/ai/researcher/cache.ts +10 -16
  251. package/src/ai/researcher/deep-analysis.ts +3 -6
  252. package/src/ai/researcher/parser.ts +1 -1
  253. package/src/ai/researcher/research-result.ts +0 -18
  254. package/src/ai/researcher/sections.ts +5 -1
  255. package/src/ai/researcher.ts +11 -59
  256. package/src/ai/rules.ts +24 -13
  257. package/src/ai/session-analyst.ts +8 -5
  258. package/src/ai/task-agent.ts +3 -30
  259. package/src/ai/tester.ts +12 -73
  260. package/src/ai/tools.ts +119 -106
  261. package/src/commands/compact-command.ts +7 -8
  262. package/src/commands/context-command.ts +1 -1
  263. package/src/commands/context-knowledge-command.ts +1 -1
  264. package/src/commands/experience-command.ts +1 -1
  265. package/src/commands/knows-command.ts +1 -1
  266. package/src/commands/learn-command.ts +3 -1
  267. package/src/components/AddKnowledge.tsx +5 -7
  268. package/src/components/App.tsx +2 -2
  269. package/src/config.ts +12 -0
  270. package/src/experience-tracker.ts +90 -152
  271. package/src/explorbot.ts +17 -51
  272. package/src/explorer.ts +34 -81
  273. package/src/index.ts +9 -0
  274. package/src/knowledge-tracker.ts +49 -50
  275. package/src/observability.ts +2 -1
  276. package/src/state-manager.ts +15 -164
  277. package/src/utils/aria.ts +11 -2
  278. package/src/utils/cache.ts +40 -0
  279. package/src/utils/context-formatter.ts +12 -15
  280. package/src/utils/html.ts +79 -0
  281. package/src/utils/markdown-files.ts +30 -0
  282. package/src/utils/markdown-query.ts +15 -1
  283. package/src/utils/page-readiness.ts +1 -1
  284. package/src/utils/secrets.ts +28 -0
  285. package/src/utils/strings.ts +12 -0
  286. package/src/utils/web-element.ts +4 -0
  287. package/src/utils/web-sandbox.ts +43 -0
  288. package/src/index.tsx +0 -62
@@ -0,0 +1,200 @@
1
+ import path from 'node:path';
2
+ import { normalizeUrl } from "../../../src/state-manager.js";
3
+ import { normalizeInlineText } from "../../../src/utils/strings.js";
4
+ function buildStateGraph(outputDir, pages) {
5
+ const pageIds = new Map();
6
+ const pageNodes = [];
7
+ const adjacency = new Map();
8
+ const classAssignment = new Map([
9
+ ['page', []],
10
+ ['dialog', []],
11
+ ['section', []],
12
+ ]);
13
+ for (const [index, page] of pages.entries()) {
14
+ const id = `page${index}`;
15
+ pageIds.set(normalizeUrl(page.url), id);
16
+ adjacency.set(id, new Set());
17
+ classAssignment.get('page')?.push(id);
18
+ pageNodes.push({ id, kind: 'page', label: page.title || page.url, subLabel: page.url, filePath: page.filePath });
19
+ }
20
+ const stateKeys = new Map();
21
+ const transientByPage = new Map();
22
+ const clicks = [];
23
+ const edges = [];
24
+ const drawnBack = new Set();
25
+ let stateIndex = 0;
26
+ for (const [pageIndex, page] of pages.entries()) {
27
+ const sourceId = `page${pageIndex}`;
28
+ for (const transition of page.interactions || []) {
29
+ const targetState = transition.targetState;
30
+ if (!targetState) {
31
+ continue;
32
+ }
33
+ const normalizedTarget = normalizeUrl(targetState.url);
34
+ const isPageTarget = targetState.kind === 'page';
35
+ let pageTargetId;
36
+ if (isPageTarget) {
37
+ pageTargetId = pageIds.get(normalizedTarget);
38
+ }
39
+ let targetId;
40
+ if (pageTargetId && pageTargetId !== sourceId) {
41
+ targetId = pageTargetId;
42
+ }
43
+ if (!targetId) {
44
+ const stateKey = `${sourceId}:${targetState.kind}:${normalizeInlineText(targetState.label)}:${normalizedTarget}`;
45
+ targetId = stateKeys.get(stateKey);
46
+ if (!targetId) {
47
+ targetId = `state${stateIndex++}`;
48
+ stateKeys.set(stateKey, targetId);
49
+ adjacency.set(targetId, new Set());
50
+ classAssignment.get(classForKind(targetState.kind))?.push(targetId);
51
+ const list = transientByPage.get(sourceId) ?? [];
52
+ list.push({ id: targetId, kind: targetState.kind, label: targetState.label, subLabel: targetState.kind, parentPageId: sourceId });
53
+ transientByPage.set(sourceId, list);
54
+ if (transition.screenshot) {
55
+ const screenshotPath = path.resolve(path.dirname(page.filePath), transition.screenshot.relativePath);
56
+ clicks.push({ node: targetId, target: path.relative(outputDir, screenshotPath).replaceAll('\\', '/'), tooltip: 'Open state screenshot' });
57
+ }
58
+ }
59
+ }
60
+ if (!targetId) {
61
+ continue;
62
+ }
63
+ const pairKey = `${sourceId}>${targetId}`;
64
+ if (adjacency.get(targetId)?.has(sourceId)) {
65
+ if (drawnBack.has(pairKey)) {
66
+ continue;
67
+ }
68
+ drawnBack.add(pairKey);
69
+ edges.push({ source: sourceId, target: targetId, action: transition.action, isBack: true });
70
+ continue;
71
+ }
72
+ if (adjacency.get(sourceId)?.has(targetId) || createsCycle(sourceId, targetId, adjacency)) {
73
+ continue;
74
+ }
75
+ adjacency.get(sourceId)?.add(targetId);
76
+ edges.push({ source: sourceId, target: targetId, action: transition.action, isBack: false });
77
+ }
78
+ }
79
+ const pageClicks = [];
80
+ for (const pageNode of pageNodes) {
81
+ const filePath = pageNode.filePath;
82
+ if (!filePath) {
83
+ continue;
84
+ }
85
+ const relativeFile = path.relative(outputDir, filePath).replaceAll('\\', '/');
86
+ pageClicks.push({ node: pageNode.id, target: relativeFile, tooltip: `Open ${pageNode.label}` });
87
+ }
88
+ return { pages: pageNodes, transientByPage, edges, clicks: [...pageClicks, ...clicks], classAssignment };
89
+ }
90
+ function renderMermaidBody(outputDir, pages) {
91
+ return renderMermaidFromGraph(buildStateGraph(outputDir, pages));
92
+ }
93
+ function renderMermaidFromGraph(graph) {
94
+ const lines = ['flowchart TD'];
95
+ if (graph.pages.length === 0) {
96
+ lines.push(' empty["No documented states"]');
97
+ return lines.join('\n');
98
+ }
99
+ for (const page of graph.pages) {
100
+ lines.push(` ${renderNodeLine(page)}`);
101
+ const children = graph.transientByPage.get(page.id);
102
+ if (!children || children.length === 0) {
103
+ continue;
104
+ }
105
+ lines.push(` subgraph sg_${page.id} ["${escapeMermaidLabel(page.label)} — transient states"]`);
106
+ for (const child of children) {
107
+ lines.push(` ${renderNodeLine(child)}`);
108
+ }
109
+ lines.push(' end');
110
+ }
111
+ for (const edge of graph.edges) {
112
+ let arrow = '-->';
113
+ if (edge.isBack) {
114
+ arrow = '-.->';
115
+ }
116
+ lines.push(` ${edge.source} ${arrow}|"${escapeMermaidLabel(edge.action)}"| ${edge.target}`);
117
+ }
118
+ lines.push(' classDef page fill:#dbeafe,stroke:#2563eb,color:#0f172a;');
119
+ lines.push(' classDef dialog fill:#ffedd5,stroke:#ea580c,color:#0f172a;');
120
+ lines.push(' classDef section fill:#f3e8ff,stroke:#9333ea,color:#0f172a;');
121
+ for (const [className, ids] of graph.classAssignment) {
122
+ if (ids.length === 0) {
123
+ continue;
124
+ }
125
+ lines.push(` class ${ids.join(',')} ${className};`);
126
+ }
127
+ for (const click of graph.clicks) {
128
+ lines.push(` click ${click.node} "${click.target}" "${escapeMermaidLabel(click.tooltip)}"`);
129
+ }
130
+ return lines.join('\n');
131
+ }
132
+ function renderStateMapFromGraph(graph) {
133
+ if (graph.pages.length === 0) {
134
+ return '';
135
+ }
136
+ const clickByNode = new Map(graph.clicks.map((click) => [click.node, click]));
137
+ const rows = ['| State | Type | Open |', '| --- | --- | --- |'];
138
+ for (const pageNode of graph.pages) {
139
+ const pageClick = clickByNode.get(pageNode.id);
140
+ let openCell = '—';
141
+ if (pageClick) {
142
+ openCell = `[open page](${pageClick.target})`;
143
+ }
144
+ rows.push(`| ${escapeTable(pageNode.label)} | page | ${openCell} |`);
145
+ for (const child of graph.transientByPage.get(pageNode.id) ?? []) {
146
+ const childClick = clickByNode.get(child.id);
147
+ let childCell = '—';
148
+ if (childClick) {
149
+ childCell = `[view screenshot](${childClick.target})`;
150
+ }
151
+ rows.push(`| ${escapeTable(child.label)} | ${child.kind} | ${childCell} |`);
152
+ }
153
+ }
154
+ return rows.join('\n');
155
+ }
156
+ function renderNodeLine(node) {
157
+ const label = `${escapeMermaidLabel(node.label)}<br/>${escapeMermaidLabel(node.subLabel)}`;
158
+ if (node.kind === 'dialog' || node.kind === 'modal') {
159
+ return `${node.id}{{"${label}"}}`;
160
+ }
161
+ if (node.kind === 'section') {
162
+ return `${node.id}("${label}")`;
163
+ }
164
+ return `${node.id}["${label}"]`;
165
+ }
166
+ function createsCycle(sourceId, targetId, adjacency) {
167
+ if (sourceId === targetId) {
168
+ return true;
169
+ }
170
+ const pending = [targetId];
171
+ const visited = new Set();
172
+ while (pending.length > 0) {
173
+ const nodeId = pending.pop();
174
+ if (!nodeId || visited.has(nodeId)) {
175
+ continue;
176
+ }
177
+ if (nodeId === sourceId) {
178
+ return true;
179
+ }
180
+ visited.add(nodeId);
181
+ pending.push(...(adjacency.get(nodeId) || []));
182
+ }
183
+ return false;
184
+ }
185
+ function escapeMermaidLabel(value) {
186
+ return normalizeInlineText(value).replaceAll('&', '&amp;').replaceAll('"', '&quot;').replaceAll('|', '&#124;');
187
+ }
188
+ function escapeTable(value) {
189
+ return normalizeInlineText(value).replaceAll('|', '\\|');
190
+ }
191
+ function classForKind(kind) {
192
+ if (kind === 'section') {
193
+ return 'section';
194
+ }
195
+ if (kind === 'page') {
196
+ return 'page';
197
+ }
198
+ return 'dialog';
199
+ }
200
+ export { buildStateGraph, renderMermaidBody, renderMermaidFromGraph, renderStateMapFromGraph };
package/dist/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "explorbot",
3
- "version": "0.1.31",
3
+ "version": "0.2.0",
4
4
  "description": "CLI app built with React Ink, CodeceptJS, and Playwright",
5
5
  "license": "Elastic-2.0",
6
6
  "type": "module",
7
7
  "main": "dist/src/index.js",
8
+ "types": "dist/src/index.d.ts",
8
9
  "exports": {
9
10
  ".": {
10
- "bun": "./src/index.tsx",
11
+ "types": "./dist/src/index.d.ts",
12
+ "bun": "./src/index.ts",
11
13
  "import": "./dist/src/index.js"
12
14
  }
13
15
  },
@@ -27,13 +29,13 @@
27
29
  "assets/sample-files/"
28
30
  ],
29
31
  "scripts": {
30
- "build": "bun run src/index.tsx build && bun run build:bin",
32
+ "build": "bun run build:bin",
31
33
  "build:bin": "bun build bin/explorbot-cli.ts --outdir bin --target node --external commander --format esm",
32
34
  "build:npm": "bash scripts/build-npm.sh",
33
35
  "prepublishOnly": "npm run build:npm",
34
- "dev": "bun run src/index.tsx",
35
- "start": "node dist/index.js",
36
- "init": "bun run src/index.tsx init",
36
+ "dev": "bun run bin/explorbot-cli.ts start",
37
+ "start": "node dist/bin/explorbot-cli.js",
38
+ "init": "bun run bin/explorbot-cli.ts init",
37
39
  "test": "codeceptjs run",
38
40
  "test:headless": "codeceptjs run --headless",
39
41
  "test:ui": "bun test tests/ui",
@@ -0,0 +1,131 @@
1
+ import { type HtmlConfig } from './config.js';
2
+ import type { Link, WebPageState } from './state-manager.js';
3
+ import { TTLCache } from './utils/cache.js';
4
+ import { type HtmlDiffPart, type HtmlDiffResult } from './utils/html-diff.js';
5
+ interface ActionResultData extends WebPageState {
6
+ html?: string;
7
+ fullUrl?: string | undefined;
8
+ screenshot?: Buffer;
9
+ screenshotFile?: string;
10
+ logFile?: string;
11
+ htmlFile?: string;
12
+ title?: string;
13
+ timestamp?: Date;
14
+ error?: string | null;
15
+ h1?: string | undefined;
16
+ h2?: string | undefined;
17
+ h3?: string | undefined;
18
+ h4?: string | undefined;
19
+ browserLogs?: any[];
20
+ iframeSnapshots?: Array<{
21
+ src: string;
22
+ html: string;
23
+ id?: string;
24
+ }>;
25
+ ariaSnapshot?: string | null;
26
+ ariaSnapshotFile?: string;
27
+ iframeURL?: string;
28
+ links?: Link[];
29
+ }
30
+ export interface PageDiff {
31
+ urlChanged: boolean;
32
+ previousUrl?: string;
33
+ currentUrl: string;
34
+ ariaChanges?: string | null;
35
+ ariaChangeCount?: number;
36
+ htmlParts?: HtmlDiffPart[];
37
+ iframes?: string;
38
+ }
39
+ export interface ToolResultMetadata {
40
+ url: string;
41
+ locator: string;
42
+ targetedHtml: string;
43
+ pageDiff: PageDiff | null;
44
+ iframeURL?: string;
45
+ }
46
+ export declare class ActionResult implements ActionResultData {
47
+ id?: number;
48
+ title: string;
49
+ httpStatus: number | undefined;
50
+ error: string | null;
51
+ timestamp: Date;
52
+ h1: string | undefined;
53
+ h2: string | undefined;
54
+ h3: string | undefined;
55
+ h4: string | undefined;
56
+ url: string;
57
+ fullUrl: string | undefined;
58
+ browserLogs: any[];
59
+ iframeSnapshots: Array<{
60
+ src: string;
61
+ html: string;
62
+ id?: string;
63
+ }>;
64
+ iframeURL: string | undefined;
65
+ readonly screenshotFile: string | undefined;
66
+ _screenshot: Buffer | undefined;
67
+ readonly htmlFile: string | undefined;
68
+ _html: string | undefined;
69
+ snapshotCache: TTLCache<string>;
70
+ readonly logFile: string | undefined;
71
+ readonly ariaSnapshotFile: string | undefined;
72
+ _ariaSnapshot: string | null | undefined;
73
+ _lastExtractedHtml: string | undefined;
74
+ notes: string[];
75
+ links: Link[];
76
+ verifications?: Record<string, boolean>;
77
+ constructor(data: ActionResultData);
78
+ get hash(): string;
79
+ get html(): string;
80
+ set html(value: string);
81
+ get screenshot(): Buffer | undefined;
82
+ get ariaSnapshot(): string | null;
83
+ set ariaSnapshot(value: string | null);
84
+ extractHeadings(html: string): void;
85
+ addVerification(assertion: string, passed: boolean): void;
86
+ getVerification(message: string | RegExp): boolean | null;
87
+ isSameUrl(state: WebPageState): boolean;
88
+ isMatchedBy(state: WebPageState): boolean;
89
+ isRelevantExperienceRecord(record: WebPageState, options?: {
90
+ includeDescendantExperience?: boolean;
91
+ }): boolean;
92
+ simplifiedHtml(htmlConfig?: HtmlConfig): Promise<string>;
93
+ combinedHtml(htmlConfig?: HtmlConfig & {
94
+ keepPositions?: boolean;
95
+ }): Promise<string>;
96
+ textHtml(htmlConfig?: HtmlConfig): Promise<string>;
97
+ getInteractiveARIA(): string;
98
+ getCompactARIA(): string;
99
+ normalizeHtmlConfig(htmlConfig?: HtmlConfig): HtmlConfig | undefined;
100
+ static fromState(state: WebPageState): ActionResult;
101
+ static loadStateFile(file: string): string | null;
102
+ static loadHtmlFromFile(htmlFile: string): string | null;
103
+ static loadScreenshotFromFile(screenshotFile: string): Buffer | undefined;
104
+ static loadBrowserLogsFromFile(logFile: string): any[];
105
+ static loadAriaSnapshotFromFile(ariaSnapshotFile: string): string | null;
106
+ toAiContext(): string;
107
+ get relativeUrl(): string | null;
108
+ get isInsideIframe(): boolean;
109
+ getStateHash(): string;
110
+ diff(previousState: ActionResult | null): Promise<Diff>;
111
+ toToolResult(previousState: ActionResult | null, locator: string): Promise<ToolResultMetadata>;
112
+ }
113
+ export declare class Diff {
114
+ current: ActionResult;
115
+ previous: ActionResult | null;
116
+ _htmlDiffResult: HtmlDiffResult | null;
117
+ _ariaDiffResult: string | null;
118
+ _ariaChangeCount: number;
119
+ _isSameUrl: boolean;
120
+ constructor(current: ActionResult, previous: ActionResult | null);
121
+ static create(current: ActionResult, previous: ActionResult | null): Promise<Diff>;
122
+ hasChanges(): boolean;
123
+ isSameUrl(): boolean;
124
+ urlHasChanged(): boolean;
125
+ get htmlParts(): HtmlDiffPart[];
126
+ get ariaChanged(): string | null;
127
+ get ariaChangeCount(): number;
128
+ get htmlDiff(): HtmlDiffResult | null;
129
+ calculate(): Promise<void>;
130
+ }
131
+ export {};