explorbot 0.1.32-beta.1 → 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 (168) 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 +20 -3
  17. package/dist/src/action-result.d.ts +8 -10
  18. package/dist/src/action-result.js +72 -164
  19. package/dist/src/action.d.ts +3 -10
  20. package/dist/src/action.js +18 -111
  21. package/dist/src/ai/captain/web-mode.js +0 -7
  22. package/dist/src/ai/captain.d.ts +1 -3
  23. package/dist/src/ai/captain.js +4 -19
  24. package/dist/src/ai/conversation.d.ts +2 -5
  25. package/dist/src/ai/conversation.js +9 -28
  26. package/dist/src/ai/driller.d.ts +0 -4
  27. package/dist/src/ai/driller.js +3 -12
  28. package/dist/src/ai/experience-compactor.d.ts +2 -2
  29. package/dist/src/ai/experience-compactor.js +16 -33
  30. package/dist/src/ai/fisherman-tools.js +1 -1
  31. package/dist/src/ai/fisherman.d.ts +0 -1
  32. package/dist/src/ai/fisherman.js +0 -3
  33. package/dist/src/ai/historian/codeceptjs.d.ts +2 -0
  34. package/dist/src/ai/historian/codeceptjs.js +3 -2
  35. package/dist/src/ai/historian/playwright.d.ts +2 -0
  36. package/dist/src/ai/historian/playwright.js +3 -2
  37. package/dist/src/ai/historian/utils.d.ts +0 -1
  38. package/dist/src/ai/historian/utils.js +0 -1
  39. package/dist/src/ai/historian.d.ts +5 -4
  40. package/dist/src/ai/historian.js +1 -5
  41. package/dist/src/ai/navigator.d.ts +3 -5
  42. package/dist/src/ai/navigator.js +11 -46
  43. package/dist/src/ai/pilot.d.ts +1 -3
  44. package/dist/src/ai/pilot.js +6 -17
  45. package/dist/src/ai/planner.d.ts +3 -3
  46. package/dist/src/ai/planner.js +49 -37
  47. package/dist/src/ai/provider.d.ts +4 -1
  48. package/dist/src/ai/provider.js +77 -136
  49. package/dist/src/ai/quartermaster.d.ts +21 -22
  50. package/dist/src/ai/quartermaster.js +4 -10
  51. package/dist/src/ai/rerunner.d.ts +1 -2
  52. package/dist/src/ai/rerunner.js +14 -22
  53. package/dist/src/ai/researcher/cache.js +11 -18
  54. package/dist/src/ai/researcher/deep-analysis.js +3 -6
  55. package/dist/src/ai/researcher/parser.js +1 -1
  56. package/dist/src/ai/researcher/research-result.d.ts +0 -1
  57. package/dist/src/ai/researcher/research-result.js +0 -19
  58. package/dist/src/ai/researcher/sections.js +5 -1
  59. package/dist/src/ai/researcher.js +12 -53
  60. package/dist/src/ai/rules.d.ts +1 -0
  61. package/dist/src/ai/rules.js +22 -15
  62. package/dist/src/ai/session-analyst.js +8 -5
  63. package/dist/src/ai/task-agent.d.ts +1 -1
  64. package/dist/src/ai/task-agent.js +2 -27
  65. package/dist/src/ai/tester.d.ts +0 -2
  66. package/dist/src/ai/tester.js +10 -61
  67. package/dist/src/ai/tools.d.ts +18 -7
  68. package/dist/src/ai/tools.js +119 -101
  69. package/dist/src/commands/compact-command.d.ts +1 -1
  70. package/dist/src/commands/compact-command.js +6 -6
  71. package/dist/src/commands/context-command.js +1 -1
  72. package/dist/src/commands/context-knowledge-command.js +1 -1
  73. package/dist/src/commands/experience-command.js +1 -1
  74. package/dist/src/commands/knows-command.js +1 -1
  75. package/dist/src/commands/learn-command.js +3 -1
  76. package/dist/src/components/AddKnowledge.d.ts +2 -0
  77. package/dist/src/components/AddKnowledge.js +3 -7
  78. package/dist/src/components/App.js +2 -2
  79. package/dist/src/config.d.ts +2 -0
  80. package/dist/src/config.js +12 -0
  81. package/dist/src/experience-tracker.d.ts +11 -6
  82. package/dist/src/experience-tracker.js +81 -154
  83. package/dist/src/explorbot.d.ts +4 -5
  84. package/dist/src/explorbot.js +17 -51
  85. package/dist/src/explorer.d.ts +4 -15
  86. package/dist/src/explorer.js +18 -68
  87. package/dist/src/knowledge-tracker.d.ts +2 -2
  88. package/dist/src/knowledge-tracker.js +38 -45
  89. package/dist/src/state-manager.d.ts +6 -31
  90. package/dist/src/state-manager.js +10 -129
  91. package/dist/src/utils/aria.d.ts +6 -1
  92. package/dist/src/utils/aria.js +4 -1
  93. package/dist/src/utils/cache.d.ts +15 -0
  94. package/dist/src/utils/cache.js +34 -0
  95. package/dist/src/utils/context-formatter.d.ts +6 -0
  96. package/dist/src/utils/context-formatter.js +15 -27
  97. package/dist/src/utils/html.d.ts +5 -0
  98. package/dist/src/utils/html.js +71 -0
  99. package/dist/src/utils/markdown-files.d.ts +10 -0
  100. package/dist/src/utils/markdown-files.js +21 -0
  101. package/dist/src/utils/markdown-query.d.ts +6 -0
  102. package/dist/src/utils/markdown-query.js +14 -1
  103. package/dist/src/utils/page-readiness.d.ts +1 -0
  104. package/dist/src/utils/page-readiness.js +1 -1
  105. package/dist/src/utils/secrets.js +2 -2
  106. package/dist/src/utils/strings.d.ts +2 -0
  107. package/dist/src/utils/strings.js +10 -0
  108. package/dist/src/utils/web-element.d.ts +2 -1
  109. package/dist/src/utils/web-element.js +3 -0
  110. package/dist/src/utils/web-sandbox.d.ts +4 -0
  111. package/dist/src/utils/web-sandbox.js +37 -0
  112. package/package.json +20 -3
  113. package/src/action-result.ts +70 -173
  114. package/src/action.ts +16 -130
  115. package/src/ai/captain/web-mode.ts +0 -7
  116. package/src/ai/captain.ts +5 -17
  117. package/src/ai/conversation.ts +9 -32
  118. package/src/ai/driller.ts +3 -16
  119. package/src/ai/experience-compactor.ts +16 -35
  120. package/src/ai/fisherman-tools.ts +1 -1
  121. package/src/ai/fisherman.ts +0 -4
  122. package/src/ai/historian/codeceptjs.ts +4 -2
  123. package/src/ai/historian/playwright.ts +4 -2
  124. package/src/ai/historian/utils.ts +0 -1
  125. package/src/ai/historian.ts +4 -7
  126. package/src/ai/navigator.ts +13 -49
  127. package/src/ai/pilot.ts +6 -16
  128. package/src/ai/planner.ts +56 -44
  129. package/src/ai/provider.ts +85 -145
  130. package/src/ai/quartermaster.ts +34 -41
  131. package/src/ai/rerunner.ts +17 -21
  132. package/src/ai/researcher/cache.ts +10 -16
  133. package/src/ai/researcher/deep-analysis.ts +3 -6
  134. package/src/ai/researcher/parser.ts +1 -1
  135. package/src/ai/researcher/research-result.ts +0 -18
  136. package/src/ai/researcher/sections.ts +5 -1
  137. package/src/ai/researcher.ts +11 -59
  138. package/src/ai/rules.ts +24 -13
  139. package/src/ai/session-analyst.ts +8 -5
  140. package/src/ai/task-agent.ts +3 -30
  141. package/src/ai/tester.ts +12 -73
  142. package/src/ai/tools.ts +119 -106
  143. package/src/commands/compact-command.ts +7 -8
  144. package/src/commands/context-command.ts +1 -1
  145. package/src/commands/context-knowledge-command.ts +1 -1
  146. package/src/commands/experience-command.ts +1 -1
  147. package/src/commands/knows-command.ts +1 -1
  148. package/src/commands/learn-command.ts +3 -1
  149. package/src/components/AddKnowledge.tsx +5 -7
  150. package/src/components/App.tsx +2 -2
  151. package/src/config.ts +12 -0
  152. package/src/experience-tracker.ts +88 -151
  153. package/src/explorbot.ts +17 -51
  154. package/src/explorer.ts +20 -72
  155. package/src/knowledge-tracker.ts +42 -49
  156. package/src/state-manager.ts +15 -156
  157. package/src/utils/aria.ts +11 -2
  158. package/src/utils/cache.ts +40 -0
  159. package/src/utils/context-formatter.ts +12 -15
  160. package/src/utils/html.ts +79 -0
  161. package/src/utils/markdown-files.ts +30 -0
  162. package/src/utils/markdown-query.ts +15 -1
  163. package/src/utils/page-readiness.ts +1 -1
  164. package/src/utils/secrets.ts +2 -3
  165. package/src/utils/strings.ts +12 -0
  166. package/src/utils/web-element.ts +4 -0
  167. package/src/utils/web-sandbox.ts +43 -0
  168. package/dist/boat/api-tester/example/apibot.config.js +0 -30
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "explorbot",
3
- "version": "0.1.32-beta.1",
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",
@@ -16,7 +16,18 @@
16
16
  "bin": {
17
17
  "explorbot": "./dist/bin/explorbot-cli.js"
18
18
  },
19
- "files": ["dist/", "src/**/*.ts", "src/**/*.tsx", "bin/**/*.ts", "boat/api-tester/src/**/*.ts", "boat/doc-collector/src/**/*.ts", "boat/doc-collector/bin/**/*.ts", "boat/doc-collector/package.json", "rules/", "assets/sample-files/"],
19
+ "files": [
20
+ "dist/",
21
+ "src/**/*.ts",
22
+ "src/**/*.tsx",
23
+ "bin/**/*.ts",
24
+ "boat/api-tester/src/**/*.ts",
25
+ "boat/doc-collector/src/**/*.ts",
26
+ "boat/doc-collector/bin/**/*.ts",
27
+ "boat/doc-collector/package.json",
28
+ "rules/",
29
+ "assets/sample-files/"
30
+ ],
20
31
  "scripts": {
21
32
  "build": "bun run build:bin",
22
33
  "build:bin": "bun build bin/explorbot-cli.ts --outdir bin --target node --external commander --format esm",
@@ -43,7 +54,13 @@
43
54
  "check:fix": "biome check --write .",
44
55
  "langfuse:export": "bun run .claude/skills/explorbot-debug/langfuse-export.ts"
45
56
  },
46
- "keywords": ["cli", "react", "ink", "codeceptjs", "playwright"],
57
+ "keywords": [
58
+ "cli",
59
+ "react",
60
+ "ink",
61
+ "codeceptjs",
62
+ "playwright"
63
+ ],
47
64
  "repository": {
48
65
  "type": "git",
49
66
  "url": "https://github.com/testomatio/explorbot"
@@ -1,5 +1,6 @@
1
1
  import { type HtmlConfig } from './config.js';
2
2
  import type { Link, WebPageState } from './state-manager.js';
3
+ import { TTLCache } from './utils/cache.js';
3
4
  import { type HtmlDiffPart, type HtmlDiffResult } from './utils/html-diff.js';
4
5
  interface ActionResultData extends WebPageState {
5
6
  html?: string;
@@ -31,6 +32,7 @@ export interface PageDiff {
31
32
  previousUrl?: string;
32
33
  currentUrl: string;
33
34
  ariaChanges?: string | null;
35
+ ariaChangeCount?: number;
34
36
  htmlParts?: HtmlDiffPart[];
35
37
  iframes?: string;
36
38
  }
@@ -64,13 +66,12 @@ export declare class ActionResult implements ActionResultData {
64
66
  _screenshot: Buffer | undefined;
65
67
  readonly htmlFile: string | undefined;
66
68
  _html: string | undefined;
67
- snapshotCache: Map<string, string>;
69
+ snapshotCache: TTLCache<string>;
68
70
  readonly logFile: string | undefined;
69
- _browserLogs: any[] | undefined;
70
71
  readonly ariaSnapshotFile: string | undefined;
71
72
  _ariaSnapshot: string | null | undefined;
72
73
  _lastExtractedHtml: string | undefined;
73
- notes: any;
74
+ notes: string[];
74
75
  links: Link[];
75
76
  verifications?: Record<string, boolean>;
76
77
  constructor(data: ActionResultData);
@@ -78,7 +79,6 @@ export declare class ActionResult implements ActionResultData {
78
79
  get html(): string;
79
80
  set html(value: string);
80
81
  get screenshot(): Buffer | undefined;
81
- get browserLogsContent(): any[];
82
82
  get ariaSnapshot(): string | null;
83
83
  set ariaSnapshot(value: string | null);
84
84
  extractHeadings(html: string): void;
@@ -97,8 +97,8 @@ export declare class ActionResult implements ActionResultData {
97
97
  getInteractiveARIA(): string;
98
98
  getCompactARIA(): string;
99
99
  normalizeHtmlConfig(htmlConfig?: HtmlConfig): HtmlConfig | undefined;
100
- cachedSnapshot(key: string, compute: () => Promise<string>): Promise<string>;
101
100
  static fromState(state: WebPageState): ActionResult;
101
+ static loadStateFile(file: string): string | null;
102
102
  static loadHtmlFromFile(htmlFile: string): string | null;
103
103
  static loadScreenshotFromFile(screenshotFile: string): Buffer | undefined;
104
104
  static loadBrowserLogsFromFile(logFile: string): any[];
@@ -107,8 +107,6 @@ export declare class ActionResult implements ActionResultData {
107
107
  get relativeUrl(): string | null;
108
108
  get isInsideIframe(): boolean;
109
109
  getStateHash(): string;
110
- saveBrowserLogs(): void;
111
- saveHtmlOutput(): void;
112
110
  diff(previousState: ActionResult | null): Promise<Diff>;
113
111
  toToolResult(previousState: ActionResult | null, locator: string): Promise<ToolResultMetadata>;
114
112
  }
@@ -117,17 +115,17 @@ export declare class Diff {
117
115
  previous: ActionResult | null;
118
116
  _htmlDiffResult: HtmlDiffResult | null;
119
117
  _ariaDiffResult: string | null;
118
+ _ariaChangeCount: number;
120
119
  _isSameUrl: boolean;
121
- _urlChanged: boolean;
122
120
  constructor(current: ActionResult, previous: ActionResult | null);
121
+ static create(current: ActionResult, previous: ActionResult | null): Promise<Diff>;
123
122
  hasChanges(): boolean;
124
123
  isSameUrl(): boolean;
125
124
  urlHasChanged(): boolean;
126
125
  get htmlParts(): HtmlDiffPart[];
127
126
  get ariaChanged(): string | null;
128
- get ariaRemoved(): string | null;
127
+ get ariaChangeCount(): number;
129
128
  get htmlDiff(): HtmlDiffResult | null;
130
- get ariaDiff(): string | null;
131
129
  calculate(): Promise<void>;
132
130
  }
133
131
  export {};