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.
- package/README.md +14 -14
- package/bin/explorbot-cli.ts +4 -3
- package/boat/doc-collector/src/ai/documentarian.ts +22 -27
- package/boat/doc-collector/src/ai/tools.ts +67 -10
- package/boat/doc-collector/src/docbot.ts +28 -7
- package/boat/doc-collector/src/docs-renderer.ts +19 -24
- package/boat/doc-collector/src/screenshots.ts +33 -1
- package/boat/doc-collector/src/state-diagram.ts +281 -0
- package/dist/bin/explorbot-cli.js +3 -3
- package/dist/boat/doc-collector/src/ai/documentarian.js +16 -6
- package/dist/boat/doc-collector/src/ai/tools.js +47 -10
- package/dist/boat/doc-collector/src/docbot.js +25 -6
- package/dist/boat/doc-collector/src/docs-renderer.js +18 -3
- package/dist/boat/doc-collector/src/screenshots.js +29 -0
- package/dist/boat/doc-collector/src/state-diagram.js +200 -0
- package/dist/package.json +8 -6
- package/dist/src/action-result.d.ts +131 -0
- package/dist/src/action-result.js +82 -159
- package/dist/src/action.d.ts +43 -0
- package/dist/src/action.js +18 -106
- package/dist/src/activity.d.ts +26 -0
- package/dist/src/ai/agent.d.ts +3 -0
- package/dist/src/ai/captain/file-tools.d.ts +28 -0
- package/dist/src/ai/captain/idle-mode.d.ts +11 -0
- package/dist/src/ai/captain/mixin.d.ts +10 -0
- package/dist/src/ai/captain/test-mode.d.ts +13 -0
- package/dist/src/ai/captain/web-mode.d.ts +13 -0
- package/dist/src/ai/captain/web-mode.js +0 -7
- package/dist/src/ai/captain.d.ts +141 -0
- package/dist/src/ai/captain.js +4 -19
- package/dist/src/ai/conversation.d.ts +28 -0
- package/dist/src/ai/conversation.js +9 -28
- package/dist/src/ai/driller.d.ts +157 -0
- package/dist/src/ai/driller.js +3 -12
- package/dist/src/ai/experience-compactor.d.ts +53 -0
- package/dist/src/ai/experience-compactor.js +16 -33
- package/dist/src/ai/fisherman-tools.d.ts +90 -0
- package/dist/src/ai/fisherman-tools.js +1 -1
- package/dist/src/ai/fisherman.d.ts +29 -0
- package/dist/src/ai/fisherman.js +0 -3
- package/dist/src/ai/historian/codeceptjs.d.ts +17 -0
- package/dist/src/ai/historian/codeceptjs.js +3 -2
- package/dist/src/ai/historian/experience.d.ts +40 -0
- package/dist/src/ai/historian/mixin.d.ts +2 -0
- package/dist/src/ai/historian/playwright.d.ts +22 -0
- package/dist/src/ai/historian/playwright.js +3 -2
- package/dist/src/ai/historian/screencast.d.ts +32 -0
- package/dist/src/ai/historian/utils.d.ts +3 -0
- package/dist/src/ai/historian/utils.js +0 -1
- package/dist/src/ai/historian.d.ts +109 -0
- package/dist/src/ai/historian.js +1 -5
- package/dist/src/ai/navigator.d.ts +54 -0
- package/dist/src/ai/navigator.js +11 -46
- package/dist/src/ai/pilot.d.ts +81 -0
- package/dist/src/ai/pilot.js +6 -17
- package/dist/src/ai/planner/session-dedup.d.ts +12 -0
- package/dist/src/ai/planner/styles.d.ts +6 -0
- package/dist/src/ai/planner/subpages.d.ts +35 -0
- package/dist/src/ai/planner.d.ts +79 -0
- package/dist/src/ai/planner.js +49 -37
- package/dist/src/ai/provider.d.ts +53 -0
- package/dist/src/ai/provider.js +78 -130
- package/dist/src/ai/quartermaster.d.ts +56 -0
- package/dist/src/ai/quartermaster.js +4 -10
- package/dist/src/ai/rerunner.d.ts +48 -0
- package/dist/src/ai/rerunner.js +14 -22
- package/dist/src/ai/researcher/cache.d.ts +6 -0
- package/dist/src/ai/researcher/cache.js +11 -18
- package/dist/src/ai/researcher/coordinates.d.ts +56 -0
- package/dist/src/ai/researcher/deep-analysis.d.ts +74 -0
- package/dist/src/ai/researcher/deep-analysis.js +3 -6
- package/dist/src/ai/researcher/fingerprint-worker.d.ts +1 -0
- package/dist/src/ai/researcher/focus.d.ts +8 -0
- package/dist/src/ai/researcher/locators.d.ts +36 -0
- package/dist/src/ai/researcher/mixin.d.ts +2 -0
- package/dist/src/ai/researcher/parser.d.ts +35 -0
- package/dist/src/ai/researcher/parser.js +1 -1
- package/dist/src/ai/researcher/research-result.d.ts +15 -0
- package/dist/src/ai/researcher/research-result.js +0 -19
- package/dist/src/ai/researcher/sections.d.ts +19 -0
- package/dist/src/ai/researcher/sections.js +5 -1
- package/dist/src/ai/researcher.js +12 -53
- package/dist/src/ai/rules.d.ts +16 -0
- package/dist/src/ai/rules.js +22 -15
- package/dist/src/ai/session-analyst.d.ts +11 -0
- package/dist/src/ai/session-analyst.js +8 -5
- package/dist/src/ai/task-agent.d.ts +28 -0
- package/dist/src/ai/task-agent.js +2 -27
- package/dist/src/ai/tester.d.ts +101 -0
- package/dist/src/ai/tester.js +10 -61
- package/dist/src/ai/tools.d.ts +52 -0
- package/dist/src/ai/tools.js +119 -101
- package/dist/src/api/api-client.d.ts +17 -0
- package/dist/src/api/request-result.d.ts +44 -0
- package/dist/src/api/request-store.d.ts +29 -0
- package/dist/src/api/spec-reader.d.ts +5 -0
- package/dist/src/api/xhr-capture.d.ts +10 -0
- package/dist/src/browser-server.d.ts +10 -0
- package/dist/src/command-handler.d.ts +68 -0
- package/dist/src/commands/add-rule-command.d.ts +11 -0
- package/dist/src/commands/base-command.d.ts +26 -0
- package/dist/src/commands/clean-command.d.ts +12 -0
- package/dist/src/commands/compact-command.d.ts +20 -0
- package/dist/src/commands/compact-command.js +6 -6
- package/dist/src/commands/context-aria-command.d.ts +6 -0
- package/dist/src/commands/context-command.d.ts +11 -0
- package/dist/src/commands/context-command.js +1 -1
- package/dist/src/commands/context-data-command.d.ts +6 -0
- package/dist/src/commands/context-experience-command.d.ts +6 -0
- package/dist/src/commands/context-html-command.d.ts +6 -0
- package/dist/src/commands/context-knowledge-command.d.ts +6 -0
- package/dist/src/commands/context-knowledge-command.js +1 -1
- package/dist/src/commands/debug-command.d.ts +6 -0
- package/dist/src/commands/drill-command.d.ts +10 -0
- package/dist/src/commands/exit-command.d.ts +7 -0
- package/dist/src/commands/experience-command.d.ts +15 -0
- package/dist/src/commands/experience-command.js +1 -1
- package/dist/src/commands/explore-command.d.ts +51 -0
- package/dist/src/commands/freesail-command.d.ts +12 -0
- package/dist/src/commands/help-command.d.ts +6 -0
- package/dist/src/commands/index.d.ts +4 -0
- package/dist/src/commands/init-command.d.ts +7 -0
- package/dist/src/commands/knows-command.d.ts +10 -0
- package/dist/src/commands/knows-command.js +1 -1
- package/dist/src/commands/learn-command.d.ts +7 -0
- package/dist/src/commands/learn-command.js +3 -1
- package/dist/src/commands/navigate-command.d.ts +7 -0
- package/dist/src/commands/path-command.d.ts +10 -0
- package/dist/src/commands/plan-clear-command.d.ts +7 -0
- package/dist/src/commands/plan-command.d.ts +14 -0
- package/dist/src/commands/plan-edit-command.d.ts +7 -0
- package/dist/src/commands/plan-load-command.d.ts +7 -0
- package/dist/src/commands/plan-reload-command.d.ts +7 -0
- package/dist/src/commands/plan-save-command.d.ts +7 -0
- package/dist/src/commands/plans-command.d.ts +21 -0
- package/dist/src/commands/rerun-command.d.ts +7 -0
- package/dist/src/commands/research-command.d.ts +11 -0
- package/dist/src/commands/runs-command.d.ts +7 -0
- package/dist/src/commands/start-command.d.ts +7 -0
- package/dist/src/commands/status-command.d.ts +6 -0
- package/dist/src/commands/test-command.d.ts +11 -0
- package/dist/src/components/ActivityPane.d.ts +6 -0
- package/dist/src/components/AddKnowledge.d.ts +10 -0
- package/dist/src/components/AddKnowledge.js +3 -7
- package/dist/src/components/AddRule.d.ts +9 -0
- package/dist/src/components/App.d.ts +9 -0
- package/dist/src/components/App.js +2 -2
- package/dist/src/components/Autocomplete.d.ts +3 -0
- package/dist/src/components/InputPane.d.ts +13 -0
- package/dist/src/components/InputReadline.d.ts +17 -0
- package/dist/src/components/LogPane.d.ts +6 -0
- package/dist/src/components/PlanEditor.d.ts +9 -0
- package/dist/src/components/PlanPane.d.ts +13 -0
- package/dist/src/components/SessionTimer.d.ts +6 -0
- package/dist/src/components/StateTransitionPane.d.ts +8 -0
- package/dist/src/components/StatusPane.d.ts +4 -0
- package/dist/src/components/TaskPane.d.ts +9 -0
- package/dist/src/components/Welcome.d.ts +3 -0
- package/dist/src/components/WelcomeChecklist.d.ts +9 -0
- package/dist/src/components/WelcomeCommands.d.ts +6 -0
- package/dist/src/components/autocomplete-store.d.ts +10 -0
- package/dist/src/components/parse-keypress.d.ts +12 -0
- package/dist/src/config.d.ts +253 -0
- package/dist/src/config.js +12 -0
- package/dist/src/execution-controller.d.ts +25 -0
- package/dist/src/experience-tracker.d.ts +112 -0
- package/dist/src/experience-tracker.js +83 -155
- package/dist/src/explorbot.d.ts +106 -0
- package/dist/src/explorbot.js +17 -51
- package/dist/src/explorer.d.ts +129 -0
- package/dist/src/explorer.js +31 -77
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +2 -55
- package/dist/src/knowledge-tracker.d.ts +33 -0
- package/dist/src/knowledge-tracker.js +47 -47
- package/dist/src/observability.d.ts +13 -0
- package/dist/src/observability.js +2 -1
- package/dist/src/playwright-recorder.d.ts +31 -0
- package/dist/src/reporter.d.ts +34 -0
- package/dist/src/state-manager.d.ts +160 -0
- package/dist/src/state-manager.js +10 -136
- package/dist/src/stats.d.ts +24 -0
- package/dist/src/suite.d.ts +24 -0
- package/dist/src/test-plan.d.ts +166 -0
- package/dist/src/utils/aria.d.ts +25 -0
- package/dist/src/utils/aria.js +4 -1
- package/dist/src/utils/browser-errors.d.ts +8 -0
- package/dist/src/utils/cache.d.ts +15 -0
- package/dist/src/utils/cache.js +34 -0
- package/dist/src/utils/cli-name.d.ts +1 -0
- package/dist/src/utils/code-extractor.d.ts +1 -0
- package/dist/src/utils/context-formatter.d.ts +31 -0
- package/dist/src/utils/context-formatter.js +15 -27
- package/dist/src/utils/error-page.d.ts +12 -0
- package/dist/src/utils/expandable.d.ts +4 -0
- package/dist/src/utils/hooks-runner.d.ts +15 -0
- package/dist/src/utils/html-diff.d.ts +19 -0
- package/dist/src/utils/html.d.ts +129 -0
- package/dist/src/utils/html.js +71 -0
- package/dist/src/utils/log-filters.d.ts +6 -0
- package/dist/src/utils/logger.d.ts +35 -0
- package/dist/src/utils/loop.d.ts +35 -0
- package/dist/src/utils/markdown-files.d.ts +10 -0
- package/dist/src/utils/markdown-files.js +21 -0
- package/dist/src/utils/markdown-parser.d.ts +17 -0
- package/dist/src/utils/markdown-query.d.ts +46 -0
- package/dist/src/utils/markdown-query.js +14 -1
- package/dist/src/utils/markdown-terminal.d.ts +1 -0
- package/dist/src/utils/next-steps.d.ts +11 -0
- package/dist/src/utils/page-readiness.d.ts +7 -0
- package/dist/src/utils/page-readiness.js +1 -1
- package/dist/src/utils/research-parser.d.ts +1 -0
- package/dist/src/utils/retry.d.ts +8 -0
- package/dist/src/utils/rules-loader.d.ts +12 -0
- package/dist/src/utils/secrets.d.ts +4 -0
- package/dist/src/utils/secrets.js +28 -0
- package/dist/src/utils/step-analyzer.d.ts +11 -0
- package/dist/src/utils/strings.d.ts +5 -0
- package/dist/src/utils/strings.js +10 -0
- package/dist/src/utils/test-files.d.ts +3 -0
- package/dist/src/utils/test-plan-markdown.d.ts +9 -0
- package/dist/src/utils/throttle.d.ts +2 -0
- package/dist/src/utils/unique-names.d.ts +2 -0
- package/dist/src/utils/url-matcher.d.ts +6 -0
- package/dist/src/utils/web-element.d.ts +45 -0
- package/dist/src/utils/web-element.js +3 -0
- package/dist/src/utils/web-sandbox.d.ts +4 -0
- package/dist/src/utils/web-sandbox.js +37 -0
- package/dist/src/utils/xpath.d.ts +17 -0
- package/package.json +8 -6
- package/src/action-result.ts +80 -168
- package/src/action.ts +16 -123
- package/src/ai/captain/web-mode.ts +0 -7
- package/src/ai/captain.ts +5 -17
- package/src/ai/conversation.ts +9 -32
- package/src/ai/driller.ts +3 -16
- package/src/ai/experience-compactor.ts +16 -35
- package/src/ai/fisherman-tools.ts +1 -1
- package/src/ai/fisherman.ts +0 -4
- package/src/ai/historian/codeceptjs.ts +4 -2
- package/src/ai/historian/playwright.ts +4 -2
- package/src/ai/historian/utils.ts +0 -1
- package/src/ai/historian.ts +4 -7
- package/src/ai/navigator.ts +13 -49
- package/src/ai/pilot.ts +6 -16
- package/src/ai/planner.ts +56 -44
- package/src/ai/provider.ts +86 -139
- package/src/ai/quartermaster.ts +34 -41
- package/src/ai/rerunner.ts +17 -21
- package/src/ai/researcher/cache.ts +10 -16
- package/src/ai/researcher/deep-analysis.ts +3 -6
- package/src/ai/researcher/parser.ts +1 -1
- package/src/ai/researcher/research-result.ts +0 -18
- package/src/ai/researcher/sections.ts +5 -1
- package/src/ai/researcher.ts +11 -59
- package/src/ai/rules.ts +24 -13
- package/src/ai/session-analyst.ts +8 -5
- package/src/ai/task-agent.ts +3 -30
- package/src/ai/tester.ts +12 -73
- package/src/ai/tools.ts +119 -106
- package/src/commands/compact-command.ts +7 -8
- package/src/commands/context-command.ts +1 -1
- package/src/commands/context-knowledge-command.ts +1 -1
- package/src/commands/experience-command.ts +1 -1
- package/src/commands/knows-command.ts +1 -1
- package/src/commands/learn-command.ts +3 -1
- package/src/components/AddKnowledge.tsx +5 -7
- package/src/components/App.tsx +2 -2
- package/src/config.ts +12 -0
- package/src/experience-tracker.ts +90 -152
- package/src/explorbot.ts +17 -51
- package/src/explorer.ts +34 -81
- package/src/index.ts +9 -0
- package/src/knowledge-tracker.ts +49 -50
- package/src/observability.ts +2 -1
- package/src/state-manager.ts +15 -164
- package/src/utils/aria.ts +11 -2
- package/src/utils/cache.ts +40 -0
- package/src/utils/context-formatter.ts +12 -15
- package/src/utils/html.ts +79 -0
- package/src/utils/markdown-files.ts +30 -0
- package/src/utils/markdown-query.ts +15 -1
- package/src/utils/page-readiness.ts +1 -1
- package/src/utils/secrets.ts +28 -0
- package/src/utils/strings.ts +12 -0
- package/src/utils/web-element.ts +4 -0
- package/src/utils/web-sandbox.ts +43 -0
- package/src/index.tsx +0 -62
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface FocusAreaResult {
|
|
2
|
+
detected: boolean;
|
|
3
|
+
type: 'dialog' | 'modal' | null;
|
|
4
|
+
name: string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare const compactAriaSnapshot: (snapshot: string | null, keepNamed?: boolean) => string;
|
|
7
|
+
export declare const diffAriaSnapshots: (previous: string | null, current: string | null) => AriaDiff;
|
|
8
|
+
export declare const detectFocusArea: (snapshot: string | null) => FocusAreaResult;
|
|
9
|
+
export declare const collectInteractiveNodes: (snapshot: string | null) => Array<Record<string, unknown>>;
|
|
10
|
+
export interface FocusedElementInfo {
|
|
11
|
+
role: string;
|
|
12
|
+
name: string;
|
|
13
|
+
value?: string;
|
|
14
|
+
attributes?: string[];
|
|
15
|
+
}
|
|
16
|
+
export declare function extractFocusedElement(ariaSnapshot: string | null): FocusedElementInfo | null;
|
|
17
|
+
export declare function parseAriaLocator(ariaStr: string): {
|
|
18
|
+
role: string;
|
|
19
|
+
text: string;
|
|
20
|
+
} | null;
|
|
21
|
+
export declare const LARGE_ARIA_CHANGE_THRESHOLD = 50;
|
|
22
|
+
export interface AriaDiff {
|
|
23
|
+
text: string | null;
|
|
24
|
+
count: number;
|
|
25
|
+
}
|
package/dist/src/utils/aria.js
CHANGED
|
@@ -490,7 +490,9 @@ export const diffAriaSnapshots = (previous, current) => {
|
|
|
490
490
|
const currTotals = countBy(curr.map((e) => e.summary));
|
|
491
491
|
const byCount = diffByCount(prevTotals, currTotals);
|
|
492
492
|
const renames = detectRenames(prev, curr, prevTotals, currTotals);
|
|
493
|
-
|
|
493
|
+
const added = [...byCount.added, ...renames.added];
|
|
494
|
+
const removed = [...byCount.removed, ...renames.removed];
|
|
495
|
+
return { text: formatDiff(added, removed, toggled), count: added.length + removed.length + toggled.length };
|
|
494
496
|
};
|
|
495
497
|
export const detectFocusArea = (snapshot) => {
|
|
496
498
|
let tree = parseSnapshot(snapshot);
|
|
@@ -543,3 +545,4 @@ export function parseAriaLocator(ariaStr) {
|
|
|
543
545
|
return null;
|
|
544
546
|
return { role: match[1], text: match[2] };
|
|
545
547
|
}
|
|
548
|
+
export const LARGE_ARIA_CHANGE_THRESHOLD = 50;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare class BrowserRecoveryError extends Error {
|
|
2
|
+
originalError: unknown;
|
|
3
|
+
recovered: boolean;
|
|
4
|
+
constructor(label: string, originalError: unknown, recovered: boolean);
|
|
5
|
+
}
|
|
6
|
+
export declare function isFatalBrowserError(error: unknown): boolean;
|
|
7
|
+
export declare function isNavigationTransitionError(error: unknown): boolean;
|
|
8
|
+
export declare function browserErrorMessage(error: unknown): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class TTLCache<T> {
|
|
2
|
+
store: Map<string, CacheEntry<T>>;
|
|
3
|
+
ttlMs: number;
|
|
4
|
+
constructor(ttlMs?: number);
|
|
5
|
+
get(key: string): T | undefined;
|
|
6
|
+
set(key: string, value: T): void;
|
|
7
|
+
fetch(key: string, compute: () => Promise<T>): Promise<T>;
|
|
8
|
+
delete(key: string): void;
|
|
9
|
+
clear(): void;
|
|
10
|
+
}
|
|
11
|
+
type CacheEntry<T> = {
|
|
12
|
+
value: T;
|
|
13
|
+
at: number;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export class TTLCache {
|
|
2
|
+
store = new Map();
|
|
3
|
+
ttlMs;
|
|
4
|
+
constructor(ttlMs = Number.POSITIVE_INFINITY) {
|
|
5
|
+
this.ttlMs = ttlMs;
|
|
6
|
+
}
|
|
7
|
+
get(key) {
|
|
8
|
+
const entry = this.store.get(key);
|
|
9
|
+
if (!entry)
|
|
10
|
+
return undefined;
|
|
11
|
+
if (Date.now() - entry.at > this.ttlMs) {
|
|
12
|
+
this.store.delete(key);
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
return entry.value;
|
|
16
|
+
}
|
|
17
|
+
set(key, value) {
|
|
18
|
+
this.store.set(key, { value, at: Date.now() });
|
|
19
|
+
}
|
|
20
|
+
async fetch(key, compute) {
|
|
21
|
+
const cached = this.get(key);
|
|
22
|
+
if (cached !== undefined)
|
|
23
|
+
return cached;
|
|
24
|
+
const value = await compute();
|
|
25
|
+
this.set(key, value);
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
delete(key) {
|
|
29
|
+
this.store.delete(key);
|
|
30
|
+
}
|
|
31
|
+
clear() {
|
|
32
|
+
this.store.clear();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getCliName(): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function extractCodeBlocks(aiResponse: string): string[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface ContextData {
|
|
2
|
+
url: string;
|
|
3
|
+
title?: string;
|
|
4
|
+
headings: {
|
|
5
|
+
h1?: string;
|
|
6
|
+
h2?: string;
|
|
7
|
+
h3?: string;
|
|
8
|
+
h4?: string;
|
|
9
|
+
};
|
|
10
|
+
experience: Array<{
|
|
11
|
+
filePath: string;
|
|
12
|
+
data: any;
|
|
13
|
+
content: string;
|
|
14
|
+
}>;
|
|
15
|
+
knowledge: Array<{
|
|
16
|
+
filePath: string;
|
|
17
|
+
url: string;
|
|
18
|
+
content: string;
|
|
19
|
+
}>;
|
|
20
|
+
ariaSnapshot: string | null;
|
|
21
|
+
combinedHtml?: string;
|
|
22
|
+
research?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function formatHeadings(headings: {
|
|
25
|
+
h1?: string;
|
|
26
|
+
h2?: string;
|
|
27
|
+
h3?: string;
|
|
28
|
+
h4?: string;
|
|
29
|
+
}): string[];
|
|
30
|
+
export type ContextMode = 'attached' | 'compact' | 'full';
|
|
31
|
+
export declare function formatContextSummary(data: ContextData, mode?: ContextMode): string;
|
|
@@ -10,6 +10,18 @@ function indent(text) {
|
|
|
10
10
|
.map((line) => chalk.gray(` ${line}`))
|
|
11
11
|
.join('\n');
|
|
12
12
|
}
|
|
13
|
+
export function formatHeadings(headings) {
|
|
14
|
+
const lines = [];
|
|
15
|
+
if (headings.h1)
|
|
16
|
+
lines.push(`H1: ${headings.h1}`);
|
|
17
|
+
if (headings.h2)
|
|
18
|
+
lines.push(`H2: ${headings.h2}`);
|
|
19
|
+
if (headings.h3)
|
|
20
|
+
lines.push(`H3: ${headings.h3}`);
|
|
21
|
+
if (headings.h4)
|
|
22
|
+
lines.push(`H4: ${headings.h4}`);
|
|
23
|
+
return lines;
|
|
24
|
+
}
|
|
13
25
|
export function formatContextSummary(data, mode = 'compact') {
|
|
14
26
|
if (mode === 'full') {
|
|
15
27
|
return formatContextFull(data);
|
|
@@ -27,15 +39,7 @@ function formatContextAttached(data) {
|
|
|
27
39
|
lines.push(indent(data.title));
|
|
28
40
|
}
|
|
29
41
|
lines.push('');
|
|
30
|
-
const headingLines =
|
|
31
|
-
if (data.headings.h1)
|
|
32
|
-
headingLines.push(`H1: ${data.headings.h1}`);
|
|
33
|
-
if (data.headings.h2)
|
|
34
|
-
headingLines.push(`H2: ${data.headings.h2}`);
|
|
35
|
-
if (data.headings.h3)
|
|
36
|
-
headingLines.push(`H3: ${data.headings.h3}`);
|
|
37
|
-
if (data.headings.h4)
|
|
38
|
-
headingLines.push(`H4: ${data.headings.h4}`);
|
|
42
|
+
const headingLines = formatHeadings(data.headings);
|
|
39
43
|
if (headingLines.length > 0) {
|
|
40
44
|
lines.push(section('HEADINGS') + chalk.gray(' (Auto-attached)'));
|
|
41
45
|
lines.push(indent(headingLines.join('\n')));
|
|
@@ -88,15 +92,7 @@ function formatContextCompact(data) {
|
|
|
88
92
|
lines.push(indent(data.title));
|
|
89
93
|
}
|
|
90
94
|
lines.push('');
|
|
91
|
-
const headingLines =
|
|
92
|
-
if (data.headings.h1)
|
|
93
|
-
headingLines.push(`H1: ${data.headings.h1}`);
|
|
94
|
-
if (data.headings.h2)
|
|
95
|
-
headingLines.push(`H2: ${data.headings.h2}`);
|
|
96
|
-
if (data.headings.h3)
|
|
97
|
-
headingLines.push(`H3: ${data.headings.h3}`);
|
|
98
|
-
if (data.headings.h4)
|
|
99
|
-
headingLines.push(`H4: ${data.headings.h4}`);
|
|
95
|
+
const headingLines = formatHeadings(data.headings);
|
|
100
96
|
if (headingLines.length > 0) {
|
|
101
97
|
lines.push(section('HEADINGS') + chalk.gray(' (Auto-attached)'));
|
|
102
98
|
lines.push(indent(headingLines.join('\n')));
|
|
@@ -144,15 +140,7 @@ function formatContextFull(data) {
|
|
|
144
140
|
lines.push(indent(data.title));
|
|
145
141
|
}
|
|
146
142
|
lines.push('');
|
|
147
|
-
const headingLines =
|
|
148
|
-
if (data.headings.h1)
|
|
149
|
-
headingLines.push(`H1: ${data.headings.h1}`);
|
|
150
|
-
if (data.headings.h2)
|
|
151
|
-
headingLines.push(`H2: ${data.headings.h2}`);
|
|
152
|
-
if (data.headings.h3)
|
|
153
|
-
headingLines.push(`H3: ${data.headings.h3}`);
|
|
154
|
-
if (data.headings.h4)
|
|
155
|
-
headingLines.push(`H4: ${data.headings.h4}`);
|
|
143
|
+
const headingLines = formatHeadings(data.headings);
|
|
156
144
|
if (headingLines.length > 0) {
|
|
157
145
|
lines.push(section('HEADINGS') + chalk.gray(' (Auto-attached)'));
|
|
158
146
|
lines.push(indent(headingLines.join('\n')));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ActionResult } from '../action-result.js';
|
|
2
|
+
import type { WebPageState } from '../state-manager.js';
|
|
3
|
+
export type PageCondition = 'ok' | 'loading' | 'error';
|
|
4
|
+
export declare function detectPageCondition(actionResult: ActionResult): PageCondition;
|
|
5
|
+
export declare function isErrorPage(actionResult: ActionResult): boolean;
|
|
6
|
+
export declare function getStateErrorPageError(state: WebPageState | null | undefined): ErrorPageError | null;
|
|
7
|
+
export declare class ErrorPageError extends Error {
|
|
8
|
+
readonly url: string;
|
|
9
|
+
readonly title?: string;
|
|
10
|
+
readonly httpStatus?: number;
|
|
11
|
+
constructor(url: string, title?: string, httpStatus?: number);
|
|
12
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const EXPANDABLE_ICON_DESCRIPTIONS: string[];
|
|
2
|
+
export declare const EXPANDABLE_XPATHS: string[];
|
|
3
|
+
export declare function buildExpandableXPath(excludeContainers?: string[]): string;
|
|
4
|
+
export declare function buildExpandableXPathInsideContainers(containers: string[]): string[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ExplorbotConfig, Hook, HookConfig } from '../config.js';
|
|
2
|
+
import type Explorer from '../explorer.js';
|
|
3
|
+
export declare class HooksRunner {
|
|
4
|
+
explorer: Explorer;
|
|
5
|
+
config: ExplorbotConfig;
|
|
6
|
+
constructor(explorer: Explorer, config: ExplorbotConfig);
|
|
7
|
+
runBeforeHook(agentName: string, url: string): Promise<void>;
|
|
8
|
+
runAfterHook(agentName: string, url: string): Promise<void>;
|
|
9
|
+
runHook(agentName: string, hookType: 'beforeHook' | 'afterHook', url: string): Promise<void>;
|
|
10
|
+
findMatchingHook(config: HookConfig, url: string): Hook | null;
|
|
11
|
+
patternSpecificity(pattern: string): number;
|
|
12
|
+
executeHook(hook: Hook, url: string): Promise<void>;
|
|
13
|
+
isSingleHook(config: HookConfig): boolean;
|
|
14
|
+
extractPath(url: string): string;
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HtmlConfig } from '../config.js';
|
|
2
|
+
export interface HtmlDiffPart {
|
|
3
|
+
container: string;
|
|
4
|
+
subtree: string;
|
|
5
|
+
added: string[];
|
|
6
|
+
removed: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface HtmlDiffResult {
|
|
9
|
+
parts: HtmlDiffPart[];
|
|
10
|
+
added: string[];
|
|
11
|
+
removed: string[];
|
|
12
|
+
similarity: number;
|
|
13
|
+
summary: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function computeHtmlFingerprint(html: string): string[];
|
|
16
|
+
/**
|
|
17
|
+
* Compares two HTML documents and returns differences along with a diff subtree.
|
|
18
|
+
*/
|
|
19
|
+
export declare function htmlDiff(originalHtml: string, modifiedHtml: string, htmlConfig?: HtmlConfig): Promise<HtmlDiffResult>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type * as parse5TreeAdapter from 'parse5/lib/tree-adapters/default';
|
|
2
|
+
import type { HtmlConfig } from '../config.js';
|
|
3
|
+
export declare const EXPLORBOT_ATTRS: {
|
|
4
|
+
readonly area: "data-explorbot-area";
|
|
5
|
+
readonly coveredBy: "data-explorbot-covered-by";
|
|
6
|
+
readonly context: "data-explorbot-context";
|
|
7
|
+
readonly eidx: "data-explorbot-eidx";
|
|
8
|
+
readonly hit: "data-explorbot-hit";
|
|
9
|
+
readonly variant: "data-explorbot-variant";
|
|
10
|
+
};
|
|
11
|
+
export declare const HTML_SELECTORS: {
|
|
12
|
+
readonly headingLabel: "h1, h2, h3, h4, h5, h6, legend, caption, label, [role=\"heading\"]";
|
|
13
|
+
readonly interactiveContent: "button, a[href], input, select, textarea, [role=\"button\"], [role=\"link\"], [role=\"option\"], [role=\"menuitem\"], [role=\"switch\"], [role=\"checkbox\"], [role=\"radio\"], [aria-label], [tabindex]";
|
|
14
|
+
readonly interactiveControl: "button, a[href], input, select, textarea, [role=\"button\"], [role=\"link\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"], [role=\"tab\"], [role=\"menuitem\"]";
|
|
15
|
+
readonly labelLike: "h1, h2, h3, h4, h5, h6, legend, caption, label, [role=\"heading\"], [class*=\"title\"], [class*=\"label\"], [class*=\"header\"], [class*=\"name\"]";
|
|
16
|
+
readonly semanticContextContainer: "section, article, form, fieldset, li, tr, td, th, [role=\"group\"], [role=\"tabpanel\"], [role=\"region\"], [class*=\"card\"], [class*=\"panel\"], [class*=\"item\"], [class*=\"usage\"], [class*=\"group\"]";
|
|
17
|
+
readonly semanticOverlays: readonly ["[role=\"dialog\"]", "[role=\"listbox\"]", "[role=\"menu\"]", "[role=\"tooltip\"]:not([style*=\"display: none\"]):not([style*=\"visibility: hidden\"])"];
|
|
18
|
+
};
|
|
19
|
+
export declare const HTML_VISIBILITY_LIMITS: {
|
|
20
|
+
readonly maxViewportOverlayRatio: 0.95;
|
|
21
|
+
readonly minOpacity: 0.1;
|
|
22
|
+
readonly minOverlayHeight: 40;
|
|
23
|
+
readonly minOverlayWidth: 80;
|
|
24
|
+
};
|
|
25
|
+
export declare const HTML_EXTRACTION_LIMITS: {
|
|
26
|
+
readonly componentScopeHtmlLength: 8000;
|
|
27
|
+
readonly maxOverlayCount: 3;
|
|
28
|
+
readonly maxScopeInteractiveCount: 16;
|
|
29
|
+
readonly overlayHtmlLength: 6000;
|
|
30
|
+
};
|
|
31
|
+
export declare const CODE_EDITOR_MARKERS: readonly ["monaco", "codemirror", "ace", "ace_editor", "code"];
|
|
32
|
+
export declare const HTML_INTERACTIVE_ROLES: Set<string>;
|
|
33
|
+
export declare const HTML_FORM_CONTROL_ROLES: Set<string>;
|
|
34
|
+
export declare const HTML_COMPOSITE_TARGET_ROLES: Set<string>;
|
|
35
|
+
export declare const HTML_COMPOSITE_AREA_HINTS: Set<string>;
|
|
36
|
+
export declare const HTML_FORM_CONTROL_TAGS: Set<string>;
|
|
37
|
+
export declare function inferHtmlRole(data: {
|
|
38
|
+
attrs: Record<string, string>;
|
|
39
|
+
role?: string;
|
|
40
|
+
tag: string;
|
|
41
|
+
variantHints?: string[];
|
|
42
|
+
}): string;
|
|
43
|
+
export declare const ELEMENT_EXTRACTION_CONFIG: {
|
|
44
|
+
readonly attrs: {
|
|
45
|
+
readonly area: "data-explorbot-area";
|
|
46
|
+
readonly coveredBy: "data-explorbot-covered-by";
|
|
47
|
+
readonly context: "data-explorbot-context";
|
|
48
|
+
readonly eidx: "data-explorbot-eidx";
|
|
49
|
+
readonly hit: "data-explorbot-hit";
|
|
50
|
+
readonly variant: "data-explorbot-variant";
|
|
51
|
+
};
|
|
52
|
+
readonly codeEditorMarkers: readonly ["monaco", "codemirror", "ace", "ace_editor", "code"];
|
|
53
|
+
readonly maxAreaDepth: 5;
|
|
54
|
+
readonly maxContextLength: 120;
|
|
55
|
+
readonly maxOuterHTMLLength: 2000;
|
|
56
|
+
readonly maxTextLength: 80;
|
|
57
|
+
readonly minOpacity: 0.1;
|
|
58
|
+
readonly selectors: {
|
|
59
|
+
readonly headingLabel: "h1, h2, h3, h4, h5, h6, legend, caption, label, [role=\"heading\"]";
|
|
60
|
+
readonly labelLike: "h1, h2, h3, h4, h5, h6, legend, caption, label, [role=\"heading\"], [class*=\"title\"], [class*=\"label\"], [class*=\"header\"], [class*=\"name\"]";
|
|
61
|
+
readonly semanticContextContainer: "section, article, form, fieldset, li, tr, td, th, [role=\"group\"], [role=\"tabpanel\"], [role=\"region\"], [class*=\"card\"], [class*=\"panel\"], [class*=\"item\"], [class*=\"usage\"], [class*=\"group\"]";
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
export type ElementExtractionConfig = typeof ELEMENT_EXTRACTION_CONFIG;
|
|
65
|
+
export type RawElementData = NonNullable<ReturnType<typeof extractElementData>>;
|
|
66
|
+
export type VisibleOverlayExtractionConfig = {
|
|
67
|
+
interactiveContentSelector: string;
|
|
68
|
+
limits: typeof HTML_EXTRACTION_LIMITS;
|
|
69
|
+
overlaySelectors: readonly string[];
|
|
70
|
+
visibilityLimits: typeof HTML_VISIBILITY_LIMITS;
|
|
71
|
+
};
|
|
72
|
+
export type ComponentScopeExtractionConfig = {
|
|
73
|
+
eidxAttr: string;
|
|
74
|
+
interactiveControlSelector: string;
|
|
75
|
+
limits: typeof HTML_EXTRACTION_LIMITS;
|
|
76
|
+
};
|
|
77
|
+
export declare function captureHtmlForSnapshot(): string;
|
|
78
|
+
export declare function extractElementData(el: Element, config?: ElementExtractionConfig): {
|
|
79
|
+
tag: string;
|
|
80
|
+
text: string;
|
|
81
|
+
allAttrs: Record<string, string>;
|
|
82
|
+
outerHTML: string;
|
|
83
|
+
x: number;
|
|
84
|
+
y: number;
|
|
85
|
+
};
|
|
86
|
+
export declare function getElementDataExtractorSource(): string;
|
|
87
|
+
export declare function extractVisibleOverlayHtml(config: VisibleOverlayExtractionConfig): string;
|
|
88
|
+
export declare function extractComponentScopeHtml(eidx: string, config: ComponentScopeExtractionConfig): string;
|
|
89
|
+
export declare function getVisibleOverlayHtmlExtractorSource(): string;
|
|
90
|
+
export declare function getComponentScopeHtmlExtractorSource(): string;
|
|
91
|
+
export declare const TRASH_HTML_CLASSES: RegExp;
|
|
92
|
+
export declare const TAILWIND_CLASS_PATTERNS: RegExp[];
|
|
93
|
+
export declare function sanitizeHtmlDocument(html: string, htmlConfig?: HtmlConfig): parse5TreeAdapter.Document;
|
|
94
|
+
export declare function sanitizeHtmlString(html: string, htmlConfig?: HtmlConfig): string;
|
|
95
|
+
/**
|
|
96
|
+
* Creates a minimal snapshot keeping only interactive elements and their structure
|
|
97
|
+
* Based on CodeceptJS HTML library
|
|
98
|
+
*/
|
|
99
|
+
export declare function htmlMinimalUISnapshot(html: string, htmlConfig?: HtmlConfig['minimal']): string;
|
|
100
|
+
export declare function minifyHtml(html: string): Promise<string>;
|
|
101
|
+
/**
|
|
102
|
+
* Creates a combined snapshot with interactive elements and meaningful text
|
|
103
|
+
* Preserves original HTML structure
|
|
104
|
+
*/
|
|
105
|
+
export declare function htmlCombinedSnapshot(html: string, htmlConfig?: HtmlConfig['combined'], opts?: {
|
|
106
|
+
keepPositions?: boolean;
|
|
107
|
+
}): string;
|
|
108
|
+
/**
|
|
109
|
+
* Creates text-only snapshot with markdown formatting
|
|
110
|
+
*/
|
|
111
|
+
export declare function htmlTextSnapshot(html: string, htmlConfig?: HtmlConfig['text']): string;
|
|
112
|
+
export interface ExtractedLink {
|
|
113
|
+
title: string;
|
|
114
|
+
url: string;
|
|
115
|
+
}
|
|
116
|
+
export declare function extractLinks(html: string): ExtractedLink[];
|
|
117
|
+
export declare function extractHeadings(html: string): {
|
|
118
|
+
h1?: string;
|
|
119
|
+
h2?: string;
|
|
120
|
+
h3?: string;
|
|
121
|
+
h4?: string;
|
|
122
|
+
};
|
|
123
|
+
export declare function codeToMarkdown(code: string): string;
|
|
124
|
+
export declare function isBodyEmpty(html: string): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Extract HTML snippet around a targeted element based on locator
|
|
127
|
+
* Used for accessibility analysis to show what element was being targeted
|
|
128
|
+
*/
|
|
129
|
+
export declare function extractTargetedHtml(html: string, locator: string): string;
|
package/dist/src/utils/html.js
CHANGED
|
@@ -67,8 +67,10 @@ const INTERACTIVE_EVENT_ATTRIBUTES = new Set(['onclick', 'onchange', 'onblur', '
|
|
|
67
67
|
const HIDDEN_CLASSES = new Set(['hidden', 'invisible', 'd-none', 'hide', 'dn', 'u-hidden', 'is-hidden', 'visually-hidden', 'sr-only', 'screen-reader-only', 'visuallyhidden', 'opacity-0']);
|
|
68
68
|
export const EXPLORBOT_ATTRS = {
|
|
69
69
|
area: 'data-explorbot-area',
|
|
70
|
+
coveredBy: 'data-explorbot-covered-by',
|
|
70
71
|
context: 'data-explorbot-context',
|
|
71
72
|
eidx: 'data-explorbot-eidx',
|
|
73
|
+
hit: 'data-explorbot-hit',
|
|
72
74
|
variant: 'data-explorbot-variant',
|
|
73
75
|
};
|
|
74
76
|
export const HTML_SELECTORS = {
|
|
@@ -139,13 +141,41 @@ export const ELEMENT_EXTRACTION_CONFIG = {
|
|
|
139
141
|
semanticContextContainer: HTML_SELECTORS.semanticContextContainer,
|
|
140
142
|
},
|
|
141
143
|
};
|
|
144
|
+
export function captureHtmlForSnapshot() {
|
|
145
|
+
const clone = document.documentElement.cloneNode(true);
|
|
146
|
+
const liveControls = Array.from(document.querySelectorAll('input, textarea, select'));
|
|
147
|
+
const clonedControls = Array.from(clone.querySelectorAll('input, textarea, select'));
|
|
148
|
+
for (let i = 0; i < liveControls.length; i++) {
|
|
149
|
+
const source = liveControls[i];
|
|
150
|
+
const target = clonedControls[i];
|
|
151
|
+
if (!target)
|
|
152
|
+
continue;
|
|
153
|
+
if (source instanceof HTMLInputElement || source instanceof HTMLTextAreaElement) {
|
|
154
|
+
target.setAttribute('data-explorbot-value', source.value);
|
|
155
|
+
}
|
|
156
|
+
if (source instanceof HTMLInputElement && (source.type === 'checkbox' || source.type === 'radio')) {
|
|
157
|
+
let checked = 'false';
|
|
158
|
+
if (source.checked)
|
|
159
|
+
checked = 'true';
|
|
160
|
+
target.setAttribute('data-explorbot-checked', checked);
|
|
161
|
+
}
|
|
162
|
+
if (source instanceof HTMLSelectElement) {
|
|
163
|
+
target.setAttribute('data-explorbot-value', Array.from(source.selectedOptions)
|
|
164
|
+
.map((option) => option.value)
|
|
165
|
+
.join(','));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return clone.outerHTML;
|
|
169
|
+
}
|
|
142
170
|
export function extractElementData(el, config) {
|
|
143
171
|
const cfg = config ||
|
|
144
172
|
{
|
|
145
173
|
attrs: {
|
|
146
174
|
area: 'data-explorbot-area',
|
|
175
|
+
coveredBy: 'data-explorbot-covered-by',
|
|
147
176
|
context: 'data-explorbot-context',
|
|
148
177
|
eidx: 'data-explorbot-eidx',
|
|
178
|
+
hit: 'data-explorbot-hit',
|
|
149
179
|
variant: 'data-explorbot-variant',
|
|
150
180
|
},
|
|
151
181
|
codeEditorMarkers: ['monaco', 'codemirror', 'ace', 'ace_editor', 'code'],
|
|
@@ -223,6 +253,43 @@ export function extractElementData(el, config) {
|
|
|
223
253
|
tokens.add('navigates');
|
|
224
254
|
return Array.from(tokens).slice(0, 8);
|
|
225
255
|
}
|
|
256
|
+
function describeOverlappingElement(target) {
|
|
257
|
+
const parts = [target.tagName.toLowerCase()];
|
|
258
|
+
const role = target.getAttribute('role');
|
|
259
|
+
const ariaLabel = target.getAttribute('aria-label');
|
|
260
|
+
const id = target.getAttribute('id');
|
|
261
|
+
const className = (target.getAttribute('class') || '').split(/\s+/).filter(Boolean).slice(0, 3).join('.');
|
|
262
|
+
if (id)
|
|
263
|
+
parts.push(`#${id.slice(0, 40)}`);
|
|
264
|
+
if (className)
|
|
265
|
+
parts.push(`.${className.slice(0, 80)}`);
|
|
266
|
+
if (role)
|
|
267
|
+
parts.push(`[role="${role.slice(0, 40)}"]`);
|
|
268
|
+
if (ariaLabel)
|
|
269
|
+
parts.push(`[aria-label="${ariaLabel.slice(0, 80)}"]`);
|
|
270
|
+
return parts.join('');
|
|
271
|
+
}
|
|
272
|
+
function inspectHitTarget(target, rect) {
|
|
273
|
+
const viewportPoints = [
|
|
274
|
+
{ x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },
|
|
275
|
+
{ x: rect.left + Math.min(rect.width - 1, Math.max(1, rect.width * 0.25)), y: rect.top + Math.min(rect.height - 1, Math.max(1, rect.height * 0.25)) },
|
|
276
|
+
{ x: rect.left + Math.min(rect.width - 1, Math.max(1, rect.width * 0.75)), y: rect.top + Math.min(rect.height - 1, Math.max(1, rect.height * 0.75)) },
|
|
277
|
+
].filter((point) => point.x >= 0 && point.y >= 0 && point.x <= window.innerWidth && point.y <= window.innerHeight);
|
|
278
|
+
if (viewportPoints.length === 0) {
|
|
279
|
+
return { hit: 'offscreen' };
|
|
280
|
+
}
|
|
281
|
+
for (const point of viewportPoints) {
|
|
282
|
+
const top = document.elementFromPoint(point.x, point.y);
|
|
283
|
+
if (!top)
|
|
284
|
+
continue;
|
|
285
|
+
if (top === target || target.contains(top)) {
|
|
286
|
+
return { hit: 'target' };
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const centerPoint = viewportPoints[0];
|
|
290
|
+
const top = document.elementFromPoint(centerPoint.x, centerPoint.y);
|
|
291
|
+
return { hit: 'covered', coveredBy: top ? describeOverlappingElement(top) : undefined };
|
|
292
|
+
}
|
|
226
293
|
function isEmbeddedCodeEditorFrame(target) {
|
|
227
294
|
const src = (target.getAttribute('src') || '').toLowerCase();
|
|
228
295
|
const markerSelector = cfg.codeEditorMarkers.map((marker) => `[class*="${marker}"]`).join(', ');
|
|
@@ -329,6 +396,10 @@ export function extractElementData(el, config) {
|
|
|
329
396
|
allAttrs[cfg.attrs.area] = areaHints.join('|');
|
|
330
397
|
allAttrs[cfg.attrs.context] = findContextLabel(el);
|
|
331
398
|
allAttrs[cfg.attrs.variant] = collectVariantHints(el).join('|');
|
|
399
|
+
const hitTarget = inspectHitTarget(el, rect);
|
|
400
|
+
allAttrs[cfg.attrs.hit] = hitTarget.hit;
|
|
401
|
+
if (hitTarget.coveredBy)
|
|
402
|
+
allAttrs[cfg.attrs.coveredBy] = hitTarget.coveredBy;
|
|
332
403
|
return {
|
|
333
404
|
tag: el.tagName.toLowerCase(),
|
|
334
405
|
text: normalizeText(el.textContent || '').slice(0, cfg.maxTextLength),
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Span } from '@opentelemetry/api';
|
|
2
|
+
export type LogType = 'info' | 'success' | 'error' | 'warning' | 'debug' | 'substep' | 'operation' | 'step' | 'multiline' | 'details' | 'html' | 'input';
|
|
3
|
+
export interface TaggedLogEntry {
|
|
4
|
+
type: LogType;
|
|
5
|
+
content: string;
|
|
6
|
+
timestamp?: Date;
|
|
7
|
+
originalArgs?: any[];
|
|
8
|
+
namespace?: string;
|
|
9
|
+
maxLines?: number;
|
|
10
|
+
}
|
|
11
|
+
type LogEntry = TaggedLogEntry;
|
|
12
|
+
export declare const tag: (type: LogType) => {
|
|
13
|
+
log: (...args: any[]) => void;
|
|
14
|
+
};
|
|
15
|
+
export declare const log: (...args: any[]) => void;
|
|
16
|
+
export declare const logSuccess: (...args: any[]) => void;
|
|
17
|
+
export declare const logError: (...args: any[]) => void;
|
|
18
|
+
export declare const logWarning: (...args: any[]) => void;
|
|
19
|
+
export declare const logSubstep: (...args: any[]) => void;
|
|
20
|
+
export declare const createDebug: (namespace: string) => (...args: any[]) => void;
|
|
21
|
+
export declare const getMethodsOfObject: (obj: any) => string[];
|
|
22
|
+
export declare const startLogCapture: () => void;
|
|
23
|
+
export declare const stopLogCapture: () => string[];
|
|
24
|
+
export declare const setVerboseMode: (enabled: boolean) => void;
|
|
25
|
+
export declare const setPreserveConsoleLogs: (enabled: boolean) => void;
|
|
26
|
+
export declare const isVerboseMode: () => boolean;
|
|
27
|
+
export declare const setDebugMode: (enabled: boolean) => void;
|
|
28
|
+
export declare const isDebugMode: () => boolean;
|
|
29
|
+
export declare const registerLogPane: (addLog: (entry: LogEntry) => void) => void;
|
|
30
|
+
export declare const unregisterLogPane: (addLog: (entry: LogEntry) => void) => void;
|
|
31
|
+
export declare const addTruncateTag: (tagName: string) => void;
|
|
32
|
+
export declare const setStepSpanParent: (span: Span | null) => void;
|
|
33
|
+
export declare const setLogCallback: (addLog: (entry: LogEntry) => void) => void;
|
|
34
|
+
export declare const pluralize: (count: number, singular: string, plural?: string) => string;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare class StopError extends Error {
|
|
2
|
+
constructor(message?: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class InterruptError extends Error {
|
|
5
|
+
userInput: string | null;
|
|
6
|
+
constructor(userInput: string | null);
|
|
7
|
+
}
|
|
8
|
+
export interface LoopContext {
|
|
9
|
+
stop: () => void;
|
|
10
|
+
iteration: number;
|
|
11
|
+
pause: (prompt?: string) => Promise<string | null>;
|
|
12
|
+
userInput: string | null;
|
|
13
|
+
setUserInput: (input: string) => void;
|
|
14
|
+
}
|
|
15
|
+
export interface CatchContext {
|
|
16
|
+
error: Error;
|
|
17
|
+
stop: () => void;
|
|
18
|
+
iteration: number;
|
|
19
|
+
}
|
|
20
|
+
export interface LoopOptions {
|
|
21
|
+
maxAttempts?: number;
|
|
22
|
+
interruptible?: boolean;
|
|
23
|
+
interruptPrompt?: string;
|
|
24
|
+
onInterrupt?: (userInput: string | null, context: LoopContext) => Promise<void> | void;
|
|
25
|
+
catch?: (context: CatchContext) => Promise<void> | void;
|
|
26
|
+
observability?: {
|
|
27
|
+
name?: string;
|
|
28
|
+
agent?: string;
|
|
29
|
+
sessionId?: string;
|
|
30
|
+
tags?: string[];
|
|
31
|
+
metadata?: Record<string, unknown>;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export declare function pause(prompt?: string): Promise<string | null>;
|
|
35
|
+
export declare function loop<T>(handler: (context: LoopContext) => Promise<T>, options?: LoopOptions): Promise<any>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function loadMarkdownFiles(dir: string, options?: {
|
|
2
|
+
recursive?: boolean;
|
|
3
|
+
onError?: (filePath: string, error: unknown) => void;
|
|
4
|
+
}): MarkdownFile[];
|
|
5
|
+
export interface MarkdownFile {
|
|
6
|
+
filePath: string;
|
|
7
|
+
content: string;
|
|
8
|
+
data: Record<string, any>;
|
|
9
|
+
mtime: Date;
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import matter from 'gray-matter';
|
|
4
|
+
export function loadMarkdownFiles(dir, options = {}) {
|
|
5
|
+
if (!existsSync(dir))
|
|
6
|
+
return [];
|
|
7
|
+
const results = [];
|
|
8
|
+
const files = readdirSync(dir, { recursive: options.recursive === true })
|
|
9
|
+
.filter((file) => typeof file === 'string' && file.endsWith('.md'))
|
|
10
|
+
.map((file) => join(dir, file));
|
|
11
|
+
for (const filePath of files) {
|
|
12
|
+
try {
|
|
13
|
+
const parsed = matter(readFileSync(filePath, 'utf8'));
|
|
14
|
+
results.push({ filePath, content: parsed.content, data: parsed.data, mtime: statSync(filePath).mtime });
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
options.onError?.(filePath, error);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return results;
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface MarkdownSection {
|
|
2
|
+
name: string;
|
|
3
|
+
depth: number;
|
|
4
|
+
rawMarkdown: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function parseSections(markdown: string, opts?: {
|
|
7
|
+
minDepth?: number;
|
|
8
|
+
maxDepth?: number;
|
|
9
|
+
}): MarkdownSection[];
|
|
10
|
+
export declare function extractLabeledCode(markdown: string, labelPattern: RegExp): string | null;
|
|
11
|
+
export declare function tableToJson(markdown: string): Record<string, string>[];
|
|
12
|
+
export declare function jsonToTable(rows: Record<string, string>[], columns?: string[]): string;
|
|
13
|
+
export declare function findTableRaw(markdown: string): string | null;
|
|
14
|
+
export declare function findTableLineRange(markdown: string): {
|
|
15
|
+
start: number;
|
|
16
|
+
end: number;
|
|
17
|
+
} | null;
|