explorbot 0.1.30 → 0.1.32-beta.1

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 (179) hide show
  1. package/dist/boat/api-tester/example/apibot.config.js +30 -0
  2. package/dist/package.json +11 -26
  3. package/dist/src/action-result.d.ts +133 -0
  4. package/dist/src/action-result.js +22 -7
  5. package/dist/src/action.d.ts +50 -0
  6. package/dist/src/action.js +10 -5
  7. package/dist/src/activity.d.ts +26 -0
  8. package/dist/src/ai/agent.d.ts +3 -0
  9. package/dist/src/ai/captain/file-tools.d.ts +28 -0
  10. package/dist/src/ai/captain/idle-mode.d.ts +11 -0
  11. package/dist/src/ai/captain/mixin.d.ts +10 -0
  12. package/dist/src/ai/captain/test-mode.d.ts +13 -0
  13. package/dist/src/ai/captain/web-mode.d.ts +13 -0
  14. package/dist/src/ai/captain.d.ts +143 -0
  15. package/dist/src/ai/conversation.d.ts +31 -0
  16. package/dist/src/ai/conversation.js +1 -1
  17. package/dist/src/ai/driller.d.ts +161 -0
  18. package/dist/src/ai/experience-compactor.d.ts +53 -0
  19. package/dist/src/ai/fisherman-tools.d.ts +90 -0
  20. package/dist/src/ai/fisherman.d.ts +30 -0
  21. package/dist/src/ai/historian/codeceptjs.d.ts +15 -0
  22. package/dist/src/ai/historian/experience.d.ts +40 -0
  23. package/dist/src/ai/historian/mixin.d.ts +2 -0
  24. package/dist/src/ai/historian/playwright.d.ts +20 -0
  25. package/dist/src/ai/historian/screencast.d.ts +32 -0
  26. package/dist/src/ai/historian/utils.d.ts +4 -0
  27. package/dist/src/ai/historian.d.ts +108 -0
  28. package/dist/src/ai/navigator.d.ts +56 -0
  29. package/dist/src/ai/pilot.d.ts +83 -0
  30. package/dist/src/ai/planner/session-dedup.d.ts +12 -0
  31. package/dist/src/ai/planner/styles.d.ts +6 -0
  32. package/dist/src/ai/planner/subpages.d.ts +35 -0
  33. package/dist/src/ai/planner.d.ts +79 -0
  34. package/dist/src/ai/provider.d.ts +50 -0
  35. package/dist/src/ai/provider.js +13 -5
  36. package/dist/src/ai/quartermaster.d.ts +57 -0
  37. package/dist/src/ai/rerunner.d.ts +49 -0
  38. package/dist/src/ai/researcher/cache.d.ts +6 -0
  39. package/dist/src/ai/researcher/coordinates.d.ts +56 -0
  40. package/dist/src/ai/researcher/deep-analysis.d.ts +74 -0
  41. package/dist/src/ai/researcher/fingerprint-worker.d.ts +1 -0
  42. package/dist/src/ai/researcher/focus.d.ts +8 -0
  43. package/dist/src/ai/researcher/locators.d.ts +36 -0
  44. package/dist/src/ai/researcher/mixin.d.ts +2 -0
  45. package/dist/src/ai/researcher/parser.d.ts +35 -0
  46. package/dist/src/ai/researcher/research-result.d.ts +16 -0
  47. package/dist/src/ai/researcher/sections.d.ts +19 -0
  48. package/dist/src/ai/rules.d.ts +15 -0
  49. package/dist/src/ai/session-analyst.d.ts +11 -0
  50. package/dist/src/ai/task-agent.d.ts +28 -0
  51. package/dist/src/ai/tester.d.ts +103 -0
  52. package/dist/src/ai/tools.d.ts +41 -0
  53. package/dist/src/api/api-client.d.ts +17 -0
  54. package/dist/src/api/request-result.d.ts +44 -0
  55. package/dist/src/api/request-store.d.ts +29 -0
  56. package/dist/src/api/spec-reader.d.ts +5 -0
  57. package/dist/src/api/xhr-capture.d.ts +10 -0
  58. package/dist/src/browser-server.d.ts +10 -0
  59. package/dist/src/command-handler.d.ts +68 -0
  60. package/dist/src/commands/add-rule-command.d.ts +11 -0
  61. package/dist/src/commands/base-command.d.ts +26 -0
  62. package/dist/src/commands/clean-command.d.ts +12 -0
  63. package/dist/src/commands/compact-command.d.ts +20 -0
  64. package/dist/src/commands/context-aria-command.d.ts +6 -0
  65. package/dist/src/commands/context-command.d.ts +11 -0
  66. package/dist/src/commands/context-data-command.d.ts +6 -0
  67. package/dist/src/commands/context-experience-command.d.ts +6 -0
  68. package/dist/src/commands/context-html-command.d.ts +6 -0
  69. package/dist/src/commands/context-knowledge-command.d.ts +6 -0
  70. package/dist/src/commands/debug-command.d.ts +6 -0
  71. package/dist/src/commands/drill-command.d.ts +10 -0
  72. package/dist/src/commands/exit-command.d.ts +7 -0
  73. package/dist/src/commands/experience-command.d.ts +15 -0
  74. package/dist/src/commands/explore-command.d.ts +51 -0
  75. package/dist/src/commands/freesail-command.d.ts +12 -0
  76. package/dist/src/commands/help-command.d.ts +6 -0
  77. package/dist/src/commands/index.d.ts +4 -0
  78. package/dist/src/commands/init-command.d.ts +7 -0
  79. package/dist/src/commands/knows-command.d.ts +10 -0
  80. package/dist/src/commands/learn-command.d.ts +7 -0
  81. package/dist/src/commands/navigate-command.d.ts +7 -0
  82. package/dist/src/commands/path-command.d.ts +10 -0
  83. package/dist/src/commands/plan-clear-command.d.ts +7 -0
  84. package/dist/src/commands/plan-command.d.ts +14 -0
  85. package/dist/src/commands/plan-edit-command.d.ts +7 -0
  86. package/dist/src/commands/plan-load-command.d.ts +7 -0
  87. package/dist/src/commands/plan-reload-command.d.ts +7 -0
  88. package/dist/src/commands/plan-save-command.d.ts +7 -0
  89. package/dist/src/commands/plans-command.d.ts +21 -0
  90. package/dist/src/commands/rerun-command.d.ts +7 -0
  91. package/dist/src/commands/research-command.d.ts +11 -0
  92. package/dist/src/commands/runs-command.d.ts +7 -0
  93. package/dist/src/commands/start-command.d.ts +7 -0
  94. package/dist/src/commands/status-command.d.ts +6 -0
  95. package/dist/src/commands/test-command.d.ts +11 -0
  96. package/dist/src/components/ActivityPane.d.ts +6 -0
  97. package/dist/src/components/AddKnowledge.d.ts +8 -0
  98. package/dist/src/components/AddRule.d.ts +9 -0
  99. package/dist/src/components/App.d.ts +9 -0
  100. package/dist/src/components/Autocomplete.d.ts +3 -0
  101. package/dist/src/components/InputPane.d.ts +13 -0
  102. package/dist/src/components/InputReadline.d.ts +17 -0
  103. package/dist/src/components/LogPane.d.ts +6 -0
  104. package/dist/src/components/PlanEditor.d.ts +9 -0
  105. package/dist/src/components/PlanPane.d.ts +13 -0
  106. package/dist/src/components/SessionTimer.d.ts +6 -0
  107. package/dist/src/components/StateTransitionPane.d.ts +8 -0
  108. package/dist/src/components/StatusPane.d.ts +4 -0
  109. package/dist/src/components/TaskPane.d.ts +9 -0
  110. package/dist/src/components/Welcome.d.ts +3 -0
  111. package/dist/src/components/WelcomeChecklist.d.ts +9 -0
  112. package/dist/src/components/WelcomeCommands.d.ts +6 -0
  113. package/dist/src/components/autocomplete-store.d.ts +10 -0
  114. package/dist/src/components/parse-keypress.d.ts +12 -0
  115. package/dist/src/config.d.ts +251 -0
  116. package/dist/src/execution-controller.d.ts +25 -0
  117. package/dist/src/experience-tracker.d.ts +107 -0
  118. package/dist/src/experience-tracker.js +2 -1
  119. package/dist/src/explorbot.d.ts +107 -0
  120. package/dist/src/explorer.d.ts +140 -0
  121. package/dist/src/explorer.js +13 -9
  122. package/dist/src/index.d.ts +6 -0
  123. package/dist/src/index.js +2 -55
  124. package/dist/src/knowledge-tracker.d.ts +33 -0
  125. package/dist/src/knowledge-tracker.js +9 -2
  126. package/dist/src/observability.d.ts +13 -0
  127. package/dist/src/observability.js +2 -1
  128. package/dist/src/playwright-recorder.d.ts +31 -0
  129. package/dist/src/reporter.d.ts +34 -0
  130. package/dist/src/state-manager.d.ts +185 -0
  131. package/dist/src/state-manager.js +0 -7
  132. package/dist/src/stats.d.ts +24 -0
  133. package/dist/src/suite.d.ts +24 -0
  134. package/dist/src/test-plan.d.ts +166 -0
  135. package/dist/src/utils/aria.d.ts +20 -0
  136. package/dist/src/utils/browser-errors.d.ts +8 -0
  137. package/dist/src/utils/cli-name.d.ts +1 -0
  138. package/dist/src/utils/code-extractor.d.ts +1 -0
  139. package/dist/src/utils/context-formatter.d.ts +25 -0
  140. package/dist/src/utils/error-page.d.ts +12 -0
  141. package/dist/src/utils/expandable.d.ts +4 -0
  142. package/dist/src/utils/hooks-runner.d.ts +15 -0
  143. package/dist/src/utils/html-diff.d.ts +19 -0
  144. package/dist/src/utils/html.d.ts +124 -0
  145. package/dist/src/utils/log-filters.d.ts +6 -0
  146. package/dist/src/utils/logger.d.ts +35 -0
  147. package/dist/src/utils/loop.d.ts +35 -0
  148. package/dist/src/utils/markdown-parser.d.ts +17 -0
  149. package/dist/src/utils/markdown-query.d.ts +40 -0
  150. package/dist/src/utils/markdown-terminal.d.ts +1 -0
  151. package/dist/src/utils/next-steps.d.ts +11 -0
  152. package/dist/src/utils/page-readiness.d.ts +6 -0
  153. package/dist/src/utils/research-parser.d.ts +1 -0
  154. package/dist/src/utils/retry.d.ts +8 -0
  155. package/dist/src/utils/rules-loader.d.ts +12 -0
  156. package/dist/src/utils/secrets.d.ts +4 -0
  157. package/dist/src/utils/secrets.js +28 -0
  158. package/dist/src/utils/step-analyzer.d.ts +11 -0
  159. package/dist/src/utils/strings.d.ts +3 -0
  160. package/dist/src/utils/test-files.d.ts +3 -0
  161. package/dist/src/utils/test-plan-markdown.d.ts +9 -0
  162. package/dist/src/utils/throttle.d.ts +2 -0
  163. package/dist/src/utils/unique-names.d.ts +2 -0
  164. package/dist/src/utils/url-matcher.d.ts +6 -0
  165. package/dist/src/utils/web-element.d.ts +44 -0
  166. package/dist/src/utils/xpath.d.ts +17 -0
  167. package/package.json +11 -26
  168. package/src/action-result.ts +22 -7
  169. package/src/action.ts +12 -5
  170. package/src/ai/conversation.ts +1 -1
  171. package/src/ai/provider.ts +13 -5
  172. package/src/experience-tracker.ts +2 -1
  173. package/src/explorer.ts +14 -9
  174. package/src/index.ts +9 -0
  175. package/src/knowledge-tracker.ts +7 -1
  176. package/src/observability.ts +2 -1
  177. package/src/state-manager.ts +0 -8
  178. package/src/utils/secrets.ts +29 -0
  179. package/src/index.tsx +0 -62
@@ -0,0 +1,251 @@
1
+ interface PlaywrightConfig {
2
+ browser: 'chromium' | 'firefox' | 'webkit';
3
+ url: string;
4
+ show?: boolean;
5
+ windowSize?: string;
6
+ slowMo?: number;
7
+ chromium?: {
8
+ args?: string[];
9
+ };
10
+ firefox?: {
11
+ args?: string[];
12
+ };
13
+ webkit?: {
14
+ args?: string[];
15
+ };
16
+ timeout?: number;
17
+ waitForAction?: number;
18
+ waitForNavigation?: 'load' | 'domcontentloaded' | 'networkidle';
19
+ waitForTimeout?: number;
20
+ spinnerSelectors?: string[];
21
+ ignoreHTTPSErrors?: boolean;
22
+ userAgent?: string;
23
+ viewport?: {
24
+ width: number;
25
+ height: number;
26
+ };
27
+ args?: string[];
28
+ }
29
+ type PlaywrightHookFn = (ctx: {
30
+ page: any;
31
+ url: string;
32
+ }) => Promise<void> | void;
33
+ type CodeceptJSHookFn = (ctx: {
34
+ I: any;
35
+ url: string;
36
+ }) => Promise<void> | void;
37
+ interface PlaywrightHook {
38
+ type: 'playwright';
39
+ hook: PlaywrightHookFn;
40
+ }
41
+ interface CodeceptJSHook {
42
+ type: 'codeceptjs';
43
+ hook: CodeceptJSHookFn;
44
+ }
45
+ type Hook = PlaywrightHook | CodeceptJSHook;
46
+ type HookPatternMap = Record<string, Hook>;
47
+ type HookConfig = Hook | HookPatternMap;
48
+ interface HooksConfig {
49
+ beforeHook?: HookConfig;
50
+ afterHook?: HookConfig;
51
+ }
52
+ interface AgentConfig extends HooksConfig {
53
+ model?: any;
54
+ enabled?: boolean;
55
+ systemPrompt?: string;
56
+ rules?: RuleEntry[];
57
+ providerOptions?: Record<string, any>;
58
+ reasoning?: 'provider-default' | 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
59
+ }
60
+ interface ResearcherAgentConfig extends AgentConfig {
61
+ excludeSelectors?: string[];
62
+ includeSelectors?: string[];
63
+ stopWords?: string[];
64
+ maxElementsToExplore?: number;
65
+ maxExpandableClicks?: number;
66
+ retries?: number;
67
+ sections?: string[];
68
+ focusSections?: string[];
69
+ errorPageTimeout?: number;
70
+ }
71
+ interface TesterAgentConfig extends AgentConfig {
72
+ progressCheckInterval?: number;
73
+ }
74
+ interface PilotAgentConfig extends AgentConfig {
75
+ stepsToReview?: number;
76
+ }
77
+ interface NavigatorAgentConfig extends AgentConfig {
78
+ addHtmlOnTry?: number;
79
+ maxAttempts?: number;
80
+ verifyAttempts?: number;
81
+ verifyTimeout?: number;
82
+ }
83
+ type HealFn = (ctx: {
84
+ I: any;
85
+ }) => Promise<void> | void;
86
+ interface HealRecipe {
87
+ priority?: number;
88
+ steps?: string[];
89
+ fn: (context: {
90
+ step: any;
91
+ error: Error;
92
+ prevSteps?: any[];
93
+ }) => HealFn | Promise<HealFn | null> | null;
94
+ }
95
+ interface RerunnerAgentConfig extends AgentConfig {
96
+ healLimit?: number;
97
+ ariaSnapshotLimit?: number;
98
+ retryFailedStep?: Record<string, any>;
99
+ screenshotOnFail?: Record<string, any>;
100
+ recipes?: Record<string, HealRecipe>;
101
+ }
102
+ interface PlannerAgentConfig extends AgentConfig {
103
+ styles?: string[];
104
+ stylesDir?: string;
105
+ }
106
+ interface ScreencastConfig {
107
+ size?: {
108
+ width: number;
109
+ height: number;
110
+ };
111
+ quality?: number;
112
+ }
113
+ interface HistorianAgentConfig extends AgentConfig {
114
+ framework?: 'codeceptjs' | 'playwright';
115
+ screencast?: boolean | ScreencastConfig;
116
+ }
117
+ interface AgentsConfig {
118
+ tester?: TesterAgentConfig;
119
+ navigator?: NavigatorAgentConfig;
120
+ researcher?: ResearcherAgentConfig;
121
+ planner?: PlannerAgentConfig;
122
+ pilot?: PilotAgentConfig;
123
+ driller?: AgentConfig;
124
+ 'experience-compactor'?: AgentConfig;
125
+ captain?: AgentConfig;
126
+ quartermaster?: AgentConfig;
127
+ historian?: HistorianAgentConfig;
128
+ fisherman?: AgentConfig;
129
+ chief?: AgentConfig;
130
+ curler?: AgentConfig;
131
+ rerunner?: RerunnerAgentConfig;
132
+ analyst?: AgentConfig;
133
+ }
134
+ interface AIConfig {
135
+ model: any;
136
+ apiKey?: string;
137
+ config?: Record<string, any>;
138
+ langfuse?: {
139
+ enabled?: boolean;
140
+ publicKey?: string;
141
+ secretKey?: string;
142
+ baseUrl?: string;
143
+ };
144
+ tools?: {
145
+ enabled: boolean;
146
+ maxConcurrency: number;
147
+ timeout: number;
148
+ };
149
+ vision?: boolean;
150
+ visionModel?: any;
151
+ agenticModel?: any;
152
+ maxAttempts?: number;
153
+ retryDelay?: number;
154
+ agents?: AgentsConfig;
155
+ }
156
+ interface HtmlConfig {
157
+ minimal?: {
158
+ include?: string[];
159
+ exclude?: string[];
160
+ };
161
+ combined?: {
162
+ include?: string[];
163
+ exclude?: string[];
164
+ };
165
+ text?: {
166
+ include?: string[];
167
+ exclude?: string[];
168
+ };
169
+ }
170
+ interface ActionConfig {
171
+ delay?: number;
172
+ retries?: number;
173
+ }
174
+ interface ReporterConfig {
175
+ enabled?: boolean;
176
+ html?: boolean;
177
+ markdown?: boolean;
178
+ runGroup?: string | null;
179
+ }
180
+ type ApiHookFn = (ctx: {
181
+ headers: Record<string, string>;
182
+ baseEndpoint: string;
183
+ }) => Promise<Record<string, string> | undefined> | Record<string, string> | undefined;
184
+ interface ApiConfig {
185
+ baseEndpoint?: string;
186
+ spec?: string[];
187
+ headers?: Record<string, string>;
188
+ bootstrap?: ApiHookFn;
189
+ teardown?: ApiHookFn;
190
+ }
191
+ interface WebConfig {
192
+ url: string;
193
+ }
194
+ interface ExplorbotConfig {
195
+ web?: WebConfig;
196
+ playwright: PlaywrightConfig;
197
+ ai: AIConfig;
198
+ html?: HtmlConfig;
199
+ action?: ActionConfig;
200
+ dirs?: {
201
+ knowledge: string;
202
+ experience: string;
203
+ output: string;
204
+ };
205
+ experience?: {
206
+ maxReadLines?: number;
207
+ };
208
+ reporter?: ReporterConfig;
209
+ api?: ApiConfig;
210
+ stepsFile?: string;
211
+ files?: Record<string, string>;
212
+ dynamicPageRegex?: string;
213
+ }
214
+ type RuleEntry = string | Record<string, string>;
215
+ export declare const EXPLORBOT_CONFIG_PATHS: string[];
216
+ export type { ExplorbotConfig, PlaywrightConfig, AIConfig, HtmlConfig, ActionConfig, AgentConfig, AgentsConfig, HistorianAgentConfig, ResearcherAgentConfig, NavigatorAgentConfig, PlannerAgentConfig, RerunnerAgentConfig, HealRecipe, Hook, HookConfig, HooksConfig, PlaywrightHook, CodeceptJSHook, HookPatternMap, RuleEntry, ReporterConfig, ApiConfig, WebConfig, ApiHookFn, };
217
+ export declare class ConfigParser {
218
+ static instance: ConfigParser;
219
+ config: ExplorbotConfig | null;
220
+ configPath: string | null;
221
+ runtimeBaseUrlOverride: string | null;
222
+ constructor();
223
+ static loadEnv(filePath: string): void;
224
+ static getInstance(): ConfigParser;
225
+ loadConfig(options?: {
226
+ config?: string;
227
+ path?: string;
228
+ baseUrl?: string;
229
+ }): Promise<ExplorbotConfig>;
230
+ getConfig(): ExplorbotConfig;
231
+ getConfigPath(): string | null;
232
+ getOutputDir(): string;
233
+ getStatesDir(): string;
234
+ getPlansDir(): string;
235
+ getTestsDir(): string;
236
+ static resetForTesting(): void;
237
+ static setupTestConfig(): void;
238
+ static getTestDirectories(): string[];
239
+ static cleanupAllTestDirectories(): void;
240
+ findConfigFile(): string | null;
241
+ loadConfigModule(configPath: string): Promise<any>;
242
+ resolveConfig(config: ExplorbotConfig, options?: {
243
+ baseUrl?: string;
244
+ }): ExplorbotConfig;
245
+ validateConfig(config: ExplorbotConfig): void;
246
+ getNestedValue(obj: any, path: string): any;
247
+ mergeWithDefaults(config: Partial<ExplorbotConfig>): ExplorbotConfig;
248
+ deepMerge(target: any, source: any): any;
249
+ ensureDirectory(path: string): void;
250
+ }
251
+ export declare function outputPath(...segments: string[]): string;
@@ -0,0 +1,25 @@
1
+ import { EventEmitter } from 'node:events';
2
+ export type InputCallback = (prompt: string) => Promise<string | null>;
3
+ export declare class ExecutionController extends EventEmitter {
4
+ static instance: ExecutionController;
5
+ interrupted: boolean;
6
+ inputCallback: InputCallback | null;
7
+ interruptResolvers: Array<() => void>;
8
+ abortController: AbortController | null;
9
+ awaitingInput: boolean;
10
+ constructor();
11
+ static getInstance(): ExecutionController;
12
+ setInputCallback(callback: InputCallback): void;
13
+ startExecution(): void;
14
+ getAbortSignal(): AbortSignal | undefined;
15
+ interrupt(): void;
16
+ isAwaitingInput(): boolean;
17
+ isInterrupted(): boolean;
18
+ waitForInterrupt(): Promise<void>;
19
+ checkInterrupt(): Promise<string | null>;
20
+ handleInterrupt(prompt?: string): Promise<string | null>;
21
+ requestInput(prompt: string): Promise<string | null>;
22
+ readlineInput(prompt: string): Promise<string | null>;
23
+ reset(): void;
24
+ }
25
+ export declare const executionController: ExecutionController;
@@ -0,0 +1,107 @@
1
+ import type { ActionResult } from './action-result.js';
2
+ import { KnowledgeTracker } from './knowledge-tracker.js';
3
+ export declare const RECENT_WINDOW_DAYS = 30;
4
+ /**
5
+ * Stores and reads per-page experience files (`./experience/<stateHash>.md`).
6
+ *
7
+ * Two writers, two contracts:
8
+ *
9
+ * writeFlow(state, body, relatedUrls?) — caller hands in a fully-formatted
10
+ * `## FLOW: <imperative title>` block (multi-step,
11
+ * `*` bullets + optional ```js``` + `>` discovery,
12
+ * ends with `---`). Tracker dedups + prepends.
13
+ * writeAction(state, ActionInput) — `## ACTION: <imperative title>`, single-step,
14
+ * optional `Solution:` line + one ```js``` code block.
15
+ * Title normalized via normalizeTitle().
16
+ *
17
+ * - Always h2. Never h3 for FLOW/ACTION.
18
+ * - On read (getSuccessfulExperience), headings are rendered as
19
+ * `## HOW to <title> (multi-step|single-step)` so prompts get natural phrasing.
20
+ */
21
+ export declare class ExperienceTracker {
22
+ experienceDir: string;
23
+ disabled: boolean;
24
+ knowledgeTracker: KnowledgeTracker;
25
+ constructor(options?: {
26
+ disabled?: boolean;
27
+ });
28
+ getExperienceDirectories(): string[];
29
+ ensureDirectory(dir: string): void;
30
+ readExperienceFile(stateHash: string): {
31
+ content: string;
32
+ data: any;
33
+ };
34
+ writeExperienceFile(stateHash: string, content: string, frontmatter?: any): void;
35
+ hasRecentExperience(stateHash: string, prefix?: string): boolean;
36
+ getExperienceFilePath(stateHash: string): string;
37
+ ensureExperienceFile(state: ActionResult): string;
38
+ updateSummary(state: ActionResult, summary: string): void;
39
+ isWritingDisabled(state: ActionResult): boolean;
40
+ writeAction(state: ActionResult, action: ActionInput): void;
41
+ writeFlow(state: ActionResult, body: string, relatedUrls?: string[]): void;
42
+ getAllExperience(): ExperienceFile[];
43
+ getRelevantExperience(state: ActionResult, options?: {
44
+ includeDescendantExperience?: boolean;
45
+ }): ExperienceFile[];
46
+ /**
47
+ * Clean up experience tracker (for testing)
48
+ */
49
+ cleanup(): void;
50
+ getSuccessfulExperience(state: ActionResult, options?: {
51
+ includeDescendants?: boolean;
52
+ stripCode?: boolean;
53
+ }): string[];
54
+ getExperienceTableOfContents(state: ActionResult, options?: {
55
+ includeDescendantExperience?: boolean;
56
+ }): ExperienceTocEntry[];
57
+ getExperienceSection(fileTag: string, sectionIndex: number, state: ActionResult, options?: {
58
+ includeDescendantExperience?: boolean;
59
+ }): {
60
+ title: string;
61
+ url: string;
62
+ content: string;
63
+ } | null;
64
+ findExperienceFileByHash(fileHash: string): string | null;
65
+ listAllExperienceToc(filter?: string, options?: {
66
+ recency?: 'recent' | 'old';
67
+ }): ExperienceTocEntry[];
68
+ getExperienceSectionByTag(fileTag: string, sectionIndex: number, filter?: string): {
69
+ title: string;
70
+ url: string;
71
+ content: string;
72
+ fileHash: string;
73
+ } | null;
74
+ }
75
+ export declare function renderExperienceToc(toc: ExperienceTocEntry[]): string;
76
+ export interface ExperienceFile {
77
+ filePath: string;
78
+ data: {
79
+ url?: string;
80
+ title?: string;
81
+ [key: string]: any;
82
+ };
83
+ content: string;
84
+ mtime: Date;
85
+ }
86
+ export interface ActionInput {
87
+ title: string;
88
+ code: string;
89
+ explanation?: string;
90
+ }
91
+ export interface SessionStep {
92
+ message: string;
93
+ status: 'passed' | 'failed' | 'neutral';
94
+ tool?: string;
95
+ code?: string;
96
+ discovery?: string;
97
+ }
98
+ export interface ExperienceTocEntry {
99
+ fileTag: string;
100
+ fileHash: string;
101
+ url: string;
102
+ sections: {
103
+ index: number;
104
+ level: 2 | 3;
105
+ title: string;
106
+ }[];
107
+ }
@@ -6,6 +6,7 @@ import { ConfigParser } from './config.js';
6
6
  import { KnowledgeTracker } from './knowledge-tracker.js';
7
7
  import { createDebug, tag } from './utils/logger.js';
8
8
  import { mdq } from './utils/markdown-query.js';
9
+ import { redactSecrets } from './utils/secrets.js';
9
10
  import { isNonReusableCode } from "./utils/step-analyzer.js";
10
11
  import { extractStatePath } from './utils/url-matcher.js';
11
12
  const debugLog = createDebug('explorbot:experience');
@@ -93,7 +94,7 @@ export class ExperienceTracker {
93
94
  return;
94
95
  }
95
96
  const filePath = this.getExperienceFilePath(stateHash);
96
- const fileContent = matter.stringify(content, frontmatter || {});
97
+ const fileContent = matter.stringify(redactSecrets(content), frontmatter || {});
97
98
  writeFileSync(filePath, fileContent, 'utf8');
98
99
  }
99
100
  hasRecentExperience(stateHash, prefix = '') {
@@ -0,0 +1,107 @@
1
+ import { Captain } from './ai/captain.js';
2
+ import { Driller } from './ai/driller.js';
3
+ import { ExperienceCompactor } from './ai/experience-compactor.js';
4
+ import { Fisherman } from './ai/fisherman.js';
5
+ import { Historian } from './ai/historian.js';
6
+ import { Navigator } from './ai/navigator.js';
7
+ import { Pilot } from './ai/pilot.js';
8
+ import { Planner } from './ai/planner.js';
9
+ import { AIProvider } from './ai/provider.js';
10
+ import { Quartermaster } from './ai/quartermaster.js';
11
+ import { Rerunner } from './ai/rerunner.js';
12
+ import { Researcher } from './ai/researcher.js';
13
+ import { SessionAnalyst } from './ai/session-analyst.js';
14
+ import { Tester } from './ai/tester.js';
15
+ import type { ExplorbotConfig } from './config.js';
16
+ import { ConfigParser } from './config.js';
17
+ import { ExperienceTracker } from './experience-tracker.js';
18
+ import Explorer from './explorer.js';
19
+ import { KnowledgeTracker } from './knowledge-tracker.js';
20
+ import { WebPageState } from './state-manager.js';
21
+ import type { Suite } from './suite.js';
22
+ import { Plan, type Test } from './test-plan.js';
23
+ export interface ExplorBotOptions {
24
+ from?: string;
25
+ baseUrl?: string;
26
+ verbose?: boolean;
27
+ config?: string;
28
+ path?: string;
29
+ show?: boolean;
30
+ headless?: boolean;
31
+ incognito?: boolean;
32
+ session?: string;
33
+ }
34
+ export type UserResolveFunction = (error?: Error, showWelcome?: boolean) => Promise<string | null>;
35
+ export declare class ExplorBot {
36
+ configParser: ConfigParser;
37
+ explorer: Explorer;
38
+ provider: AIProvider;
39
+ config: ExplorbotConfig;
40
+ options: ExplorBotOptions;
41
+ userResolveFn: UserResolveFunction | null;
42
+ needsInput: boolean;
43
+ currentPlan?: Plan;
44
+ planFeature?: string;
45
+ lastPlanError: Error | null;
46
+ lastSavedPlanPath: string | null;
47
+ agents: Record<string, any>;
48
+ sessionPlans: Plan[];
49
+ lastReportedTestCount: number;
50
+ constructor(options?: ExplorBotOptions);
51
+ get isExploring(): boolean;
52
+ setUserResolve(fn: UserResolveFunction): void;
53
+ start(): Promise<void>;
54
+ startProviderOnly(): Promise<void>;
55
+ stop(): Promise<void>;
56
+ visitInitialState(): Promise<void>;
57
+ visit(url: string): Promise<void>;
58
+ openFreshTab(): Promise<void>;
59
+ getCurrentState(): WebPageState | null;
60
+ getExplorer(): Explorer;
61
+ getKnowledgeTracker(): KnowledgeTracker;
62
+ getExperienceTracker(): ExperienceTracker;
63
+ getConfig(): ExplorbotConfig;
64
+ getOptions(): ExplorBotOptions;
65
+ isReady(): boolean;
66
+ getConfigParser(): ConfigParser;
67
+ getProvider(): AIProvider;
68
+ createAgent<T>(factory: (deps: {
69
+ explorer: Explorer;
70
+ ai: AIProvider;
71
+ config: ExplorbotConfig;
72
+ }) => T): T;
73
+ agentResearcher(): Researcher;
74
+ agentNavigator(): Navigator;
75
+ agentPlanner(): Planner;
76
+ agentPilot(): Pilot;
77
+ agentTester(): Tester;
78
+ agentCaptain(): Captain;
79
+ agentExperienceCompactor(): ExperienceCompactor;
80
+ agentQuartermaster(): Quartermaster | null;
81
+ agentHistorian(): Historian;
82
+ agentRerunner(): Rerunner;
83
+ agentDriller(): Driller;
84
+ agentSessionAnalyst(): SessionAnalyst;
85
+ agentFisherman(): Fisherman | null;
86
+ getCurrentPlan(): Plan | undefined;
87
+ getSuite(): Suite | null;
88
+ getPlanFeature(): string | undefined;
89
+ clearPlan(): void;
90
+ plan(feature?: string, opts?: {
91
+ fresh?: boolean;
92
+ style?: string;
93
+ extend?: Plan;
94
+ completedPlans?: Plan[];
95
+ noSave?: boolean;
96
+ }): Promise<Plan>;
97
+ getPlansDir(): string;
98
+ savePlan(filename?: string): string | null;
99
+ savePlans(plans: Plan[], filename?: string): string | null;
100
+ generatePlanFilename(feature?: string): string;
101
+ resolvePlanPath(filename: string): string;
102
+ loadPlan(filename: string): Plan;
103
+ loadPlans(filename: string): Plan[];
104
+ setCurrentPlan(plan?: Plan): void;
105
+ getSessionTests(): Test[];
106
+ printSessionAnalysis(): Promise<void>;
107
+ }
@@ -0,0 +1,140 @@
1
+ import type { BrowserContextOptions } from 'playwright';
2
+ import { ActionResult } from './action-result.js';
3
+ import Action from './action.js';
4
+ import { AIProvider } from './ai/provider.js';
5
+ import { RequestStore } from './api/request-store.js';
6
+ import { XhrCapture } from './api/xhr-capture.js';
7
+ import type { ExplorbotConfig } from './config.js';
8
+ import type { UserResolveFunction } from './explorbot.js';
9
+ import { KnowledgeTracker } from './knowledge-tracker.js';
10
+ import { PlaywrightRecorder } from './playwright-recorder.js';
11
+ import { Reporter } from './reporter.js';
12
+ import { StateManager } from './state-manager.js';
13
+ import { Test } from './test-plan.js';
14
+ import { WebElement } from './utils/web-element.js';
15
+ declare global {
16
+ namespace NodeJS {
17
+ interface Global {
18
+ output_dir: string;
19
+ }
20
+ }
21
+ }
22
+ declare namespace CodeceptJS {
23
+ interface I {
24
+ [key: string]: any;
25
+ }
26
+ }
27
+ interface TabInfo {
28
+ url: string;
29
+ title: string;
30
+ }
31
+ interface BrowserExecutionErrorResult {
32
+ action: 'continue' | 'stop';
33
+ message: string;
34
+ recovered?: boolean;
35
+ }
36
+ declare class Explorer {
37
+ aiProvider: AIProvider;
38
+ playwrightHelper: any;
39
+ isStarted: boolean;
40
+ isSharedBrowser: boolean;
41
+ actor: CodeceptJS.I;
42
+ stateManager: StateManager;
43
+ knowledgeTracker: KnowledgeTracker;
44
+ config: ExplorbotConfig;
45
+ userResolveFn: UserResolveFunction | null;
46
+ options?: {
47
+ show?: boolean;
48
+ headless?: boolean;
49
+ incognito?: boolean;
50
+ session?: string;
51
+ };
52
+ reporter: Reporter;
53
+ otherTabs: TabInfo[];
54
+ _activeTest: Test | null;
55
+ xhrCapture: XhrCapture | null;
56
+ requestStore: RequestStore | null;
57
+ playwrightRecorder: PlaywrightRecorder;
58
+ observedTestPages: Set<any>;
59
+ testPageErrorHandler: ((error: Error) => void) | null;
60
+ testConsoleHandler: ((message: any) => void) | null;
61
+ testDialogHandler: ((dialog: any) => void) | null;
62
+ constructor(config: ExplorbotConfig, aiProvider: AIProvider, options?: {
63
+ show?: boolean;
64
+ headless?: boolean;
65
+ incognito?: boolean;
66
+ session?: string;
67
+ });
68
+ initializeContainer(): void;
69
+ convertToCodeceptConfig(config: ExplorbotConfig): any;
70
+ getConfig(): ExplorbotConfig;
71
+ getConfigPath(): string | null;
72
+ getAIProvider(): AIProvider;
73
+ getStateManager(): StateManager;
74
+ getCurrentUrl(): string;
75
+ getKnowledgeTracker(): KnowledgeTracker;
76
+ getReporter(): Reporter;
77
+ getRequestStore(): RequestStore | null;
78
+ extractCookies(): Promise<Record<string, string>>;
79
+ setupXhrCapture(reuseRequestStore?: boolean): void;
80
+ start(): Promise<any>;
81
+ connectOrLaunchBrowser(): Promise<void>;
82
+ createBrowserContextOptions(): BrowserContextOptions;
83
+ createAction(): Action;
84
+ runWithBrowserRecovery<T>(label: string, operation: () => Promise<T>): Promise<T>;
85
+ capturePageState(opts?: {
86
+ includeScreenshot?: boolean;
87
+ }): Promise<ActionResult>;
88
+ capturePageWithScreenshot(): Promise<ActionResult>;
89
+ executeAction(code: string): Promise<Action>;
90
+ attemptAction(code: string, originalMessage?: string, experience?: boolean): Promise<boolean>;
91
+ getPlaywrightRecorder(): PlaywrightRecorder;
92
+ visit(url: string): Promise<Action>;
93
+ visitOnce(url: string): Promise<Action>;
94
+ annotateElements(): Promise<WebElement[]>;
95
+ visuallyAnnotateElements(opts?: {
96
+ containers?: Array<{
97
+ css: string;
98
+ label: string;
99
+ }>;
100
+ }): Promise<number>;
101
+ getEidxInContainer(containerCss: string | null): Promise<string[]>;
102
+ getEidxByLocator(locator: string, container?: string | null): Promise<string | null>;
103
+ reload(): Promise<void>;
104
+ resolveBrowserUrl(url?: string): string | null;
105
+ isFatalBrowserError(error: unknown): boolean;
106
+ recoverFromBrowserError(): Promise<boolean>;
107
+ restartBrowser(): Promise<boolean>;
108
+ switchToMainFrame(): Promise<void>;
109
+ waitForPageReadiness(): Promise<boolean>;
110
+ isInsideIframe(): Promise<boolean>;
111
+ getCurrentIframeInfo(): string | null;
112
+ hasOtherTabs(): boolean;
113
+ getOtherTabsInfo(): TabInfo[];
114
+ clearOtherTabsInfo(): void;
115
+ setUserResolve(userResolveFn: UserResolveFunction): void;
116
+ listenToStateChanged(): void;
117
+ stop(): Promise<void>;
118
+ get activeTest(): Test | null;
119
+ startTest(test: Test): Promise<boolean>;
120
+ ensurePageAvailable(): Promise<boolean>;
121
+ ensureActiveTestPageAvailable(): Promise<boolean>;
122
+ handleExecutionError(error: unknown): Promise<BrowserExecutionErrorResult>;
123
+ watchActiveTestPage(page?: any): void;
124
+ stopTest(test: Test, meta?: Record<string, string>): Promise<void>;
125
+ unwatchActiveTestPages(): void;
126
+ hasPlaywrightLocator(locatorFn: (page: any) => any, opts?: {
127
+ multiple?: boolean;
128
+ contents?: boolean;
129
+ success?: (locator: any) => Promise<void> | void;
130
+ }): Promise<boolean>;
131
+ playwrightLocatorCount(locatorFn: (page: any) => any): Promise<number>;
132
+ bindFrameNavigated(page: any): void;
133
+ openFreshTab(): Promise<void>;
134
+ closeOtherTabs(): Promise<void>;
135
+ }
136
+ export declare function annotatePageElements(page: any): Promise<{
137
+ ariaSnapshot: string;
138
+ elements: WebElement[];
139
+ }>;
140
+ export default Explorer;
@@ -629,17 +629,21 @@ class Explorer {
629
629
  test.setActiveNoteScreenshot(lastScreenshot);
630
630
  };
631
631
  this.watchActiveTestPage();
632
- codeceptjs.event.dispatcher.emit('test.before', codeceptjsTest);
633
- codeceptjs.event.dispatcher.emit('test.start', codeceptjsTest);
634
- codeceptjs.event.dispatcher.on('step.passed', (step) => stepHandler(step, 'passed'));
635
- codeceptjs.event.dispatcher.on('step.failed', (step, error) => {
632
+ const onStepPassed = (step) => stepHandler(step, 'passed');
633
+ const onStepFailed = (step, error) => {
636
634
  stepHandler(step, 'failed', error?.message || String(error), error?.stack);
637
- });
638
- codeceptjs.event.dispatcher.on('test.after', () => {
639
- codeceptjs.event.dispatcher.off('step.passed', stepHandler);
640
- codeceptjs.event.dispatcher.off('step.failed', stepHandler);
635
+ };
636
+ const onTestAfter = () => {
637
+ codeceptjs.event.dispatcher.off('step.passed', onStepPassed);
638
+ codeceptjs.event.dispatcher.off('step.failed', onStepFailed);
639
+ codeceptjs.event.dispatcher.off('test.after', onTestAfter);
641
640
  this.unwatchActiveTestPages();
642
- });
641
+ };
642
+ codeceptjs.event.dispatcher.emit('test.before', codeceptjsTest);
643
+ codeceptjs.event.dispatcher.emit('test.start', codeceptjsTest);
644
+ codeceptjs.event.dispatcher.on('step.passed', onStepPassed);
645
+ codeceptjs.event.dispatcher.on('step.failed', onStepFailed);
646
+ codeceptjs.event.dispatcher.on('test.after', onTestAfter);
643
647
  return true;
644
648
  }
645
649
  async ensurePageAvailable() {
@@ -0,0 +1,6 @@
1
+ export { ExplorBot } from './explorbot.js';
2
+ export type { ExplorBotOptions, UserResolveFunction } from './explorbot.js';
3
+ export { Plan, Test, TestResult, TestStatus } from './test-plan.js';
4
+ export type { Note, StepData, TestResultType, TestStatusType } from './test-plan.js';
5
+ export type { Link, StateTransition, WebPageState } from './state-manager.js';
6
+ export type { AIConfig, ExplorbotConfig, PlaywrightConfig } from './config.js';