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,46 @@
|
|
|
1
|
+
import { type Token } from 'marked';
|
|
2
|
+
export type SelectorType = 'section' | 'section1' | 'section2' | 'section3' | 'section4' | 'section5' | 'section6' | 'table' | 'heading' | 'paragraph' | 'list' | 'item' | 'code' | 'blockquote' | 'hr' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
3
|
+
export interface TextMatcher {
|
|
4
|
+
mode: 'exact' | 'contains' | 'regex';
|
|
5
|
+
value: string;
|
|
6
|
+
negated: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface QuerySegment {
|
|
9
|
+
selector: SelectorType;
|
|
10
|
+
textMatch?: TextMatcher;
|
|
11
|
+
index: number | null;
|
|
12
|
+
slice: {
|
|
13
|
+
from?: number;
|
|
14
|
+
to?: number;
|
|
15
|
+
} | null;
|
|
16
|
+
}
|
|
17
|
+
export interface MatchedRange {
|
|
18
|
+
token: Token;
|
|
19
|
+
start: number;
|
|
20
|
+
length: number;
|
|
21
|
+
innerTokens?: MatchedRange[];
|
|
22
|
+
}
|
|
23
|
+
export declare function parseQuery(input: string): QuerySegment[];
|
|
24
|
+
export declare class MarkdownQuery {
|
|
25
|
+
source: string;
|
|
26
|
+
matches: MatchedRange[];
|
|
27
|
+
constructor(source: string, matches?: MatchedRange[]);
|
|
28
|
+
query(selector: string): MarkdownQuery;
|
|
29
|
+
text(): string;
|
|
30
|
+
get(): string;
|
|
31
|
+
toJson(): Record<string, string>[];
|
|
32
|
+
replace(content: string): string;
|
|
33
|
+
replaceEach(replacer: (match: MarkdownQuery, index: number) => string): string;
|
|
34
|
+
count(): number;
|
|
35
|
+
first(): MarkdownQuery;
|
|
36
|
+
last(): MarkdownQuery;
|
|
37
|
+
before(): MarkdownQuery;
|
|
38
|
+
after(): MarkdownQuery;
|
|
39
|
+
each(): MarkdownQuery[];
|
|
40
|
+
meta(): Array<{
|
|
41
|
+
type: string;
|
|
42
|
+
depth: number | null;
|
|
43
|
+
text: string;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
export declare function mdq(source: string): MarkdownQuery;
|
|
@@ -341,6 +341,9 @@ export class MarkdownQuery {
|
|
|
341
341
|
return results;
|
|
342
342
|
}
|
|
343
343
|
replace(content) {
|
|
344
|
+
return this.replaceEach(() => content);
|
|
345
|
+
}
|
|
346
|
+
replaceEach(replacer) {
|
|
344
347
|
const sorted = [...this.matches].sort((a, b) => a.start - b.start);
|
|
345
348
|
const kept = [];
|
|
346
349
|
let lastEnd = -1;
|
|
@@ -350,10 +353,11 @@ export class MarkdownQuery {
|
|
|
350
353
|
kept.push(range);
|
|
351
354
|
lastEnd = range.start + range.length;
|
|
352
355
|
}
|
|
356
|
+
const replacements = kept.map((range, index) => replacer(new MarkdownQuery(this.source, [range]), index));
|
|
353
357
|
let result = this.source;
|
|
354
358
|
for (let i = kept.length - 1; i >= 0; i--) {
|
|
355
359
|
const range = kept[i];
|
|
356
|
-
result = result.slice(0, range.start) +
|
|
360
|
+
result = result.slice(0, range.start) + replacements[i] + result.slice(range.start + range.length);
|
|
357
361
|
}
|
|
358
362
|
return result;
|
|
359
363
|
}
|
|
@@ -386,6 +390,15 @@ export class MarkdownQuery {
|
|
|
386
390
|
each() {
|
|
387
391
|
return this.matches.map((m) => new MarkdownQuery(this.source, [m]));
|
|
388
392
|
}
|
|
393
|
+
meta() {
|
|
394
|
+
return this.matches.map((range) => {
|
|
395
|
+
const token = range.token;
|
|
396
|
+
let depth = null;
|
|
397
|
+
if (token.type === 'heading')
|
|
398
|
+
depth = token.depth;
|
|
399
|
+
return { type: token.type, depth, text: getTokenText(range.token) };
|
|
400
|
+
});
|
|
401
|
+
}
|
|
389
402
|
}
|
|
390
403
|
export function mdq(source) {
|
|
391
404
|
return new MarkdownQuery(source);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseMarkdownToTerminal(markdown: string): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface NextStepCommand {
|
|
2
|
+
label: string;
|
|
3
|
+
command: string;
|
|
4
|
+
}
|
|
5
|
+
export interface NextStepSection {
|
|
6
|
+
label: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
commands?: NextStepCommand[];
|
|
9
|
+
}
|
|
10
|
+
export declare function relativeToCwd(absPath: string): string;
|
|
11
|
+
export declare function printNextSteps(sections: NextStepSection[]): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RESEARCH_COLUMN_ORDER, type ResearchElement, type ResearchSection, extractContainerFromBlockquote, extractValidContainers, formatResearchSummary, mapRowToElement, parseResearchSections, rebuildSectionMarkdown, } from '../ai/researcher/parser.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface RetryOptions {
|
|
2
|
+
maxAttempts?: number;
|
|
3
|
+
baseDelay?: number;
|
|
4
|
+
maxDelay?: number;
|
|
5
|
+
backoffMultiplier?: number;
|
|
6
|
+
retryCondition?: (error: Error) => boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function withRetry<T>(operation: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class RulesLoader {
|
|
2
|
+
static loadRules(agentName: string, rulesConfig: RuleEntry[], currentUrl: string): string;
|
|
3
|
+
static loadStyles(agentName: string, styleNames: string[]): Record<string, string>;
|
|
4
|
+
static listStyleNames(agentName: string): string[];
|
|
5
|
+
static getActiveStyle(styles: Record<string, string>, iteration: number, override?: string): {
|
|
6
|
+
name: string;
|
|
7
|
+
approach: string;
|
|
8
|
+
};
|
|
9
|
+
static extractRules(agentName: string, targetDir: string): string[];
|
|
10
|
+
}
|
|
11
|
+
type RuleEntry = string | Record<string, string>;
|
|
12
|
+
export type { RuleEntry };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const MIN_SECRET_LENGTH = 4;
|
|
2
|
+
const SECRET_NAME_TOKENS = ['password', 'passwd', 'secret', 'token', 'apikey', 'api_key', 'credential', 'private_key', 'privatekey', 'access_key', 'jwt', 'auth', 'bearer', 'authorization', 'cert', 'certificate'];
|
|
3
|
+
const secretValues = new Set();
|
|
4
|
+
export function registerSecret(value) {
|
|
5
|
+
if (!value)
|
|
6
|
+
return;
|
|
7
|
+
if (value.length < MIN_SECRET_LENGTH)
|
|
8
|
+
return;
|
|
9
|
+
secretValues.add(value);
|
|
10
|
+
}
|
|
11
|
+
export function redactSecrets(text) {
|
|
12
|
+
if (!text)
|
|
13
|
+
return text;
|
|
14
|
+
let result = text;
|
|
15
|
+
for (const value of [...secretValues].sort((a, b) => b.length - a.length)) {
|
|
16
|
+
if (!result.includes(value))
|
|
17
|
+
continue;
|
|
18
|
+
result = result.split(value).join('***REDACTED***');
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
export function clearRegisteredSecrets() {
|
|
23
|
+
secretValues.clear();
|
|
24
|
+
}
|
|
25
|
+
export function isSecretName(name) {
|
|
26
|
+
const lower = name.toLowerCase();
|
|
27
|
+
return SECRET_NAME_TOKENS.some((token) => lower.includes(token));
|
|
28
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SessionStep } from '../experience-tracker.js';
|
|
2
|
+
import type { StepData } from '../test-plan.js';
|
|
3
|
+
export declare const CODECEPT_TOOLS: readonly ["click", "hover", "pressKey", "form"];
|
|
4
|
+
export type CodeceptToolName = (typeof CODECEPT_TOOLS)[number];
|
|
5
|
+
export declare function isCodeceptToolName(toolName: string): toolName is CodeceptToolName;
|
|
6
|
+
export declare function getCodeceptToolName(commandName: string): CodeceptToolName | null;
|
|
7
|
+
export declare function getCodeceptToolNameFromCode(code: string): CodeceptToolName | null;
|
|
8
|
+
export declare function stripComments(code: string): string;
|
|
9
|
+
export declare function isNonReusableCode(code: string): boolean;
|
|
10
|
+
export declare function toReusableSessionStep(step: StepData): SessionStep | null;
|
|
11
|
+
export declare function mergeUniqueStepsByCode(primary: SessionStep[], secondary: SessionStep[]): SessionStep[];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function truncateJson(input: any): string;
|
|
2
|
+
export declare function slugify(text: string): string;
|
|
3
|
+
export declare function normalizeInlineText(text: string): string;
|
|
4
|
+
export declare function sanitizeFilename(name: string): string;
|
|
5
|
+
export declare function safeFilename(name: string, ext?: string, maxBytes?: number): string;
|
|
@@ -5,6 +5,16 @@ export function truncateJson(input) {
|
|
|
5
5
|
const str = JSON.stringify(input);
|
|
6
6
|
return str.length <= 80 ? str : `${str.slice(0, 77)}...`;
|
|
7
7
|
}
|
|
8
|
+
export function slugify(text) {
|
|
9
|
+
return text
|
|
10
|
+
.replace(/[^a-zA-Z0-9_]/g, '_')
|
|
11
|
+
.replace(/_+/g, '_')
|
|
12
|
+
.replace(/^_|_$/g, '')
|
|
13
|
+
.toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
export function normalizeInlineText(text) {
|
|
16
|
+
return text.normalize('NFKC').replace(/\s+/g, ' ').trim();
|
|
17
|
+
}
|
|
8
18
|
export function sanitizeFilename(name) {
|
|
9
19
|
return name
|
|
10
20
|
.toLowerCase()
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Plan } from '../test-plan.js';
|
|
2
|
+
export declare function planToCompactAiContext(plan: Plan): string;
|
|
3
|
+
export declare function parsePlanFromMarkdown(filePath: string): Plan;
|
|
4
|
+
export declare function parsePlansFromMarkdown(filePath: string): Plan[];
|
|
5
|
+
export declare function savePlanToMarkdown(plan: Plan, filePath: string): void;
|
|
6
|
+
export declare function savePlansToMarkdown(plans: Plan[], filePath: string): void;
|
|
7
|
+
export declare function planToAiContext(plan: Plan, options?: {
|
|
8
|
+
skipSteps?: boolean;
|
|
9
|
+
}): string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function isDynamicSegment(segment: string): boolean;
|
|
2
|
+
export declare function hasDynamicUrlSegment(url: string): boolean;
|
|
3
|
+
export declare function generalizeSegment(segment: string): string;
|
|
4
|
+
export declare function generalizeUrl(url: string): string;
|
|
5
|
+
export declare function matchesUrl(pattern: string, path: string): boolean;
|
|
6
|
+
export declare function extractStatePath(url: string): string;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { EXPLORBOT_ATTRS, type RawElementData } from './html.js';
|
|
2
|
+
import { type XPathMatch } from './xpath.js';
|
|
3
|
+
export { extractElementData } from './html.js';
|
|
4
|
+
export declare class WebElement {
|
|
5
|
+
tag: string;
|
|
6
|
+
role: string;
|
|
7
|
+
xpath: string;
|
|
8
|
+
clickXPath: string;
|
|
9
|
+
attrs: Record<string, string>;
|
|
10
|
+
text: string;
|
|
11
|
+
outerHTML: string;
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
constructor(data: {
|
|
15
|
+
tag: string;
|
|
16
|
+
role?: string;
|
|
17
|
+
xpath: string;
|
|
18
|
+
clickXPath: string;
|
|
19
|
+
attrs: Record<string, string>;
|
|
20
|
+
text: string;
|
|
21
|
+
outerHTML?: string;
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
});
|
|
25
|
+
get description(): string;
|
|
26
|
+
get keyAttrs(): string;
|
|
27
|
+
get coordinates(): string;
|
|
28
|
+
get eidx(): string | null;
|
|
29
|
+
ourAttr(name: keyof typeof EXPLORBOT_ATTRS): string | undefined;
|
|
30
|
+
get isNavigationLink(): boolean;
|
|
31
|
+
get filteredClasses(): string[];
|
|
32
|
+
get areaHints(): string[];
|
|
33
|
+
get contextLabel(): string;
|
|
34
|
+
get variantHints(): string[];
|
|
35
|
+
static fromRawData(d: RawElementData, role?: string): WebElement;
|
|
36
|
+
static fromXPathMatch(m: XPathMatch): WebElement;
|
|
37
|
+
static fromPlaywrightLocator(locator: any): Promise<WebElement | null>;
|
|
38
|
+
static fromEidx(page: any, eidx: string): Promise<WebElement | null>;
|
|
39
|
+
static fromEidxList(page: any, eidxList: string[]): Promise<WebElement[]>;
|
|
40
|
+
static findByXPath(html: string, xpath: string): Promise<{
|
|
41
|
+
totalFound: number;
|
|
42
|
+
elements: WebElement[];
|
|
43
|
+
error?: string;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function sanitizeCodeBlock(code: string): string;
|
|
2
|
+
export declare function hasPlaywrightCommands(code: string): boolean;
|
|
3
|
+
export declare function playwrightSandbox(page: any, code: string): Promise<any>;
|
|
4
|
+
export declare function codeceptJSSandbox(actor: any, codeOrFn: string | ((...args: any[]) => void)): void;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { faker } from '@faker-js/faker';
|
|
2
|
+
import { hopeThat, retryTo, tryTo, within } from 'codeceptjs/lib/effects';
|
|
3
|
+
import step from 'codeceptjs/steps';
|
|
4
|
+
const SHADOWED_GLOBALS = ['process', 'global', 'globalThis', 'fetch', 'Bun', 'require', 'module', 'exports'];
|
|
5
|
+
const ALLOWED_COMMAND_HEADS = ['I.', 'page.', 'await page.', 'await I.'];
|
|
6
|
+
const PLAYWRIGHT_COMMAND_HEADS = ['page.', 'await page.'];
|
|
7
|
+
const PLAYWRIGHT_ARG_NAMES = ['page'];
|
|
8
|
+
const CODECEPT_ARG_NAMES = ['I', 'tryTo', 'retryTo', 'within', 'hopeThat', 'step', 'faker'];
|
|
9
|
+
export function sanitizeCodeBlock(code) {
|
|
10
|
+
return code
|
|
11
|
+
.split('\n')
|
|
12
|
+
.map((line) => line.trim())
|
|
13
|
+
.filter((line) => ALLOWED_COMMAND_HEADS.some((head) => line.startsWith(head)))
|
|
14
|
+
.join('\n');
|
|
15
|
+
}
|
|
16
|
+
export function hasPlaywrightCommands(code) {
|
|
17
|
+
return code.split('\n').some((line) => {
|
|
18
|
+
const trimmed = line.trim();
|
|
19
|
+
return PLAYWRIGHT_COMMAND_HEADS.some((head) => trimmed.startsWith(head));
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export function playwrightSandbox(page, code) {
|
|
23
|
+
const run = createSandbox(PLAYWRIGHT_ARG_NAMES, `return (async () => { ${code} })()`);
|
|
24
|
+
return run(page);
|
|
25
|
+
}
|
|
26
|
+
export function codeceptJSSandbox(actor, codeOrFn) {
|
|
27
|
+
if (typeof codeOrFn === 'function') {
|
|
28
|
+
codeOrFn(actor, tryTo, retryTo, within, hopeThat, step, faker);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const run = createSandbox(CODECEPT_ARG_NAMES, codeOrFn);
|
|
32
|
+
run(actor, tryTo, retryTo, within, hopeThat, step, faker);
|
|
33
|
+
}
|
|
34
|
+
function createSandbox(argNames, body) {
|
|
35
|
+
const fn = new Function(...argNames, ...SHADOWED_GLOBALS, `'use strict';\n${body}`);
|
|
36
|
+
return (...args) => fn(...args);
|
|
37
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface XPathMatch {
|
|
2
|
+
tag: string;
|
|
3
|
+
outerHTML: string;
|
|
4
|
+
text: string;
|
|
5
|
+
absoluteXPath: string;
|
|
6
|
+
allAttrs: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
export interface XPathResult {
|
|
9
|
+
totalFound: number;
|
|
10
|
+
matches: XPathMatch[];
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const isDynamicId: (id: string) => boolean;
|
|
14
|
+
export declare const isGenericClass: (cls: string) => boolean;
|
|
15
|
+
export declare function buildClickableXPath(el: XPathMatch): string;
|
|
16
|
+
export declare function cssToAncestorXPath(css: string): string | null;
|
|
17
|
+
export declare function evaluateXPath(html: string, xpath: string): Promise<XPathResult>;
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "explorbot",
|
|
3
|
-
"version": "0.
|
|
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
|
-
"
|
|
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
|
|
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
|
|
35
|
-
"start": "node dist/
|
|
36
|
-
"init": "bun run
|
|
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",
|