@browserflow-ai/exploration 0.0.6

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 (58) hide show
  1. package/dist/adapters/claude-cli.d.ts +57 -0
  2. package/dist/adapters/claude-cli.d.ts.map +1 -0
  3. package/dist/adapters/claude-cli.js +195 -0
  4. package/dist/adapters/claude-cli.js.map +1 -0
  5. package/dist/adapters/claude.d.ts +54 -0
  6. package/dist/adapters/claude.d.ts.map +1 -0
  7. package/dist/adapters/claude.js +160 -0
  8. package/dist/adapters/claude.js.map +1 -0
  9. package/dist/adapters/index.d.ts +6 -0
  10. package/dist/adapters/index.d.ts.map +1 -0
  11. package/dist/adapters/index.js +4 -0
  12. package/dist/adapters/index.js.map +1 -0
  13. package/dist/adapters/types.d.ts +196 -0
  14. package/dist/adapters/types.d.ts.map +1 -0
  15. package/dist/adapters/types.js +3 -0
  16. package/dist/adapters/types.js.map +1 -0
  17. package/dist/agent-browser-session.d.ts +62 -0
  18. package/dist/agent-browser-session.d.ts.map +1 -0
  19. package/dist/agent-browser-session.js +272 -0
  20. package/dist/agent-browser-session.js.map +1 -0
  21. package/dist/evidence.d.ts +111 -0
  22. package/dist/evidence.d.ts.map +1 -0
  23. package/dist/evidence.js +144 -0
  24. package/dist/evidence.js.map +1 -0
  25. package/dist/explorer.d.ts +180 -0
  26. package/dist/explorer.d.ts.map +1 -0
  27. package/dist/explorer.js +393 -0
  28. package/dist/explorer.js.map +1 -0
  29. package/dist/index.d.ts +15 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +15 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/locator-candidates.d.ts +127 -0
  34. package/dist/locator-candidates.d.ts.map +1 -0
  35. package/dist/locator-candidates.js +358 -0
  36. package/dist/locator-candidates.js.map +1 -0
  37. package/dist/step-executor.d.ts +99 -0
  38. package/dist/step-executor.d.ts.map +1 -0
  39. package/dist/step-executor.js +646 -0
  40. package/dist/step-executor.js.map +1 -0
  41. package/package.json +34 -0
  42. package/src/adapters/claude-cli.test.ts +134 -0
  43. package/src/adapters/claude-cli.ts +240 -0
  44. package/src/adapters/claude.test.ts +195 -0
  45. package/src/adapters/claude.ts +190 -0
  46. package/src/adapters/index.ts +21 -0
  47. package/src/adapters/types.ts +207 -0
  48. package/src/agent-browser-session.test.ts +369 -0
  49. package/src/agent-browser-session.ts +349 -0
  50. package/src/evidence.test.ts +239 -0
  51. package/src/evidence.ts +203 -0
  52. package/src/explorer.test.ts +321 -0
  53. package/src/explorer.ts +565 -0
  54. package/src/index.ts +51 -0
  55. package/src/locator-candidates.test.ts +602 -0
  56. package/src/locator-candidates.ts +441 -0
  57. package/src/step-executor.test.ts +696 -0
  58. package/src/step-executor.ts +783 -0
@@ -0,0 +1,57 @@
1
+ import type { AIAdapter, ExploreParams, ExplorationOutput, RetryParams, EnhancedSnapshot, FindElementResult } from './types';
2
+ /**
3
+ * Configuration options for the Claude CLI adapter
4
+ */
5
+ export interface ClaudeCliAdapterConfig {
6
+ /** Model to use (default: haiku) */
7
+ model?: string;
8
+ /** Path to claude CLI executable (default: 'claude') */
9
+ cliPath?: string;
10
+ /** Timeout in milliseconds (default: 30000) */
11
+ timeout?: number;
12
+ }
13
+ /**
14
+ * Claude CLI adapter for AI-powered browser exploration
15
+ *
16
+ * Uses the `claude` CLI tool to make LLM calls, allowing users to:
17
+ * - Use their existing Claude Code authentication
18
+ * - Leverage local CLI configuration
19
+ * - Avoid managing API keys separately
20
+ */
21
+ export declare class ClaudeCliAdapter implements AIAdapter {
22
+ readonly name = "claude-cli";
23
+ private model;
24
+ private cliPath;
25
+ private timeout;
26
+ constructor(config?: ClaudeCliAdapterConfig);
27
+ /**
28
+ * Execute claude CLI with a prompt and return the response
29
+ */
30
+ private runClaude;
31
+ /**
32
+ * Parse JSON from claude CLI response
33
+ * Handles responses wrapped in markdown code blocks
34
+ */
35
+ private parseJsonResponse;
36
+ /**
37
+ * Find element from natural language query using Claude CLI
38
+ *
39
+ * @param query - Natural language description of the element
40
+ * @param snapshot - Browser snapshot with element tree and refs
41
+ * @returns Promise resolving to element ref with reasoning
42
+ */
43
+ findElement(query: string, snapshot: EnhancedSnapshot): Promise<FindElementResult>;
44
+ /**
45
+ * Run exploration on a spec using Claude CLI
46
+ *
47
+ * Note: The primary AI method is findElement(). This explore() method is a stub
48
+ * that returns a minimal valid structure. Full exploration is orchestrated by
49
+ * the Explorer class which uses findElement() for AI-powered element discovery.
50
+ */
51
+ explore(params: ExploreParams): Promise<ExplorationOutput>;
52
+ /**
53
+ * Retry exploration with review feedback
54
+ */
55
+ retryWithFeedback(params: RetryParams): Promise<ExplorationOutput>;
56
+ }
57
+ //# sourceMappingURL=claude-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-cli.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-cli.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAeD;;;;;;;GAOG;AACH,qBAAa,gBAAiB,YAAW,SAAS;IAChD,QAAQ,CAAC,IAAI,gBAAgB;IAE7B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,GAAE,sBAA2B;IAM/C;;OAEG;YACW,SAAS;IAwDvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;;;;;OAMG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwDxF;;;;;;OAMG;IACG,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmBhE;;OAEG;IACG,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAGzE"}
@@ -0,0 +1,195 @@
1
+ // @browserflow-ai/exploration - Claude CLI Adapter
2
+ // Uses the `claude` CLI tool instead of the Anthropic SDK
3
+ // This allows users to leverage their existing Claude Code authentication
4
+ import { spawn } from 'node:child_process';
5
+ // Debug flag - set via BF_DEBUG=1 environment variable
6
+ const DEBUG = process.env.BF_DEBUG === '1';
7
+ function debug(...args) {
8
+ if (DEBUG) {
9
+ console.error('[claude-cli]', ...args);
10
+ }
11
+ }
12
+ /**
13
+ * System prompt for element finding - embedded in the user prompt
14
+ */
15
+ const ELEMENT_FINDER_PROMPT = `You are helping find UI elements based on natural language descriptions.
16
+ Given an accessibility snapshot of a web page, identify the element that best matches the user's description.
17
+
18
+ Rules:
19
+ 1. Return the ref (like "e1", "e2") of the matching element
20
+ 2. If multiple elements could match, pick the most likely based on context
21
+ 3. If no element matches, use ref "NOT_FOUND" with confidence 0
22
+ 4. Consider the element's role, name, text content, and position in the hierarchy
23
+ 5. Be precise - prefer exact matches over partial matches`;
24
+ /**
25
+ * Claude CLI adapter for AI-powered browser exploration
26
+ *
27
+ * Uses the `claude` CLI tool to make LLM calls, allowing users to:
28
+ * - Use their existing Claude Code authentication
29
+ * - Leverage local CLI configuration
30
+ * - Avoid managing API keys separately
31
+ */
32
+ export class ClaudeCliAdapter {
33
+ name = 'claude-cli';
34
+ model;
35
+ cliPath;
36
+ timeout;
37
+ constructor(config = {}) {
38
+ this.model = config.model ?? 'haiku';
39
+ this.cliPath = config.cliPath ?? 'claude';
40
+ this.timeout = config.timeout ?? 30000;
41
+ }
42
+ /**
43
+ * Execute claude CLI with a prompt and return the response
44
+ */
45
+ async runClaude(prompt) {
46
+ return new Promise((resolve, reject) => {
47
+ // Note: --dangerously-skip-permissions is required for non-interactive mode
48
+ // because the CLI may otherwise wait for trust/permission dialogs
49
+ const args = ['--model', this.model, '--dangerously-skip-permissions', '-p', prompt];
50
+ debug('Spawning CLI:', this.cliPath, args.slice(0, 2).join(' '), '...');
51
+ debug('Prompt length:', prompt.length, 'chars');
52
+ const startTime = Date.now();
53
+ const proc = spawn(this.cliPath, args, {
54
+ // stdin must be 'ignore' - otherwise claude CLI waits for input
55
+ stdio: ['ignore', 'pipe', 'pipe'],
56
+ });
57
+ let stdout = '';
58
+ let stderr = '';
59
+ proc.stdout.on('data', (data) => {
60
+ stdout += data.toString();
61
+ debug('stdout chunk:', data.toString().slice(0, 100));
62
+ });
63
+ proc.stderr.on('data', (data) => {
64
+ stderr += data.toString();
65
+ debug('stderr chunk:', data.toString().slice(0, 200));
66
+ });
67
+ proc.on('error', (err) => {
68
+ debug('spawn error:', err.message);
69
+ reject(new Error(`Failed to spawn claude CLI: ${err.message}`));
70
+ });
71
+ proc.on('close', (code) => {
72
+ const elapsed = Date.now() - startTime;
73
+ debug('CLI exited with code', code, 'after', elapsed, 'ms');
74
+ debug('stdout length:', stdout.length, 'stderr length:', stderr.length);
75
+ if (code === 0) {
76
+ resolve(stdout);
77
+ }
78
+ else {
79
+ reject(new Error(`claude CLI exited with code ${code}: ${stderr}`));
80
+ }
81
+ });
82
+ // Handle timeout
83
+ const timer = setTimeout(() => {
84
+ debug('TIMEOUT after', this.timeout, 'ms - killing process');
85
+ proc.kill('SIGTERM');
86
+ reject(new Error(`claude CLI timed out after ${this.timeout}ms`));
87
+ }, this.timeout);
88
+ proc.on('close', () => clearTimeout(timer));
89
+ });
90
+ }
91
+ /**
92
+ * Parse JSON from claude CLI response
93
+ * Handles responses wrapped in markdown code blocks
94
+ */
95
+ parseJsonResponse(response) {
96
+ // Try to extract JSON from markdown code block
97
+ const jsonBlockMatch = response.match(/```(?:json)?\s*([\s\S]*?)```/);
98
+ const jsonStr = jsonBlockMatch ? jsonBlockMatch[1].trim() : response.trim();
99
+ try {
100
+ return JSON.parse(jsonStr);
101
+ }
102
+ catch {
103
+ throw new Error(`Failed to parse JSON response: ${response}`);
104
+ }
105
+ }
106
+ /**
107
+ * Find element from natural language query using Claude CLI
108
+ *
109
+ * @param query - Natural language description of the element
110
+ * @param snapshot - Browser snapshot with element tree and refs
111
+ * @returns Promise resolving to element ref with reasoning
112
+ */
113
+ async findElement(query, snapshot) {
114
+ const availableRefs = Object.keys(snapshot.refs);
115
+ debug('findElement called with query:', query);
116
+ debug('Snapshot tree length:', snapshot.tree.length);
117
+ debug('Available refs:', availableRefs.length, availableRefs.slice(0, 5).join(', '), '...');
118
+ // If snapshot is empty, return early
119
+ if (!availableRefs.length || snapshot.tree === '(no interactive elements)') {
120
+ debug('Empty snapshot - returning NOT_FOUND immediately');
121
+ return {
122
+ ref: 'NOT_FOUND',
123
+ confidence: 0,
124
+ reasoning: 'Snapshot contains no interactive elements',
125
+ };
126
+ }
127
+ const prompt = `${ELEMENT_FINDER_PROMPT}
128
+
129
+ Find the element matching this description: "${query}"
130
+
131
+ Accessibility tree:
132
+ ${snapshot.tree}
133
+
134
+ Available refs: ${availableRefs.join(', ')}
135
+
136
+ Return ONLY a JSON object with these fields:
137
+ - ref: the element reference (e.g., "e3") or "NOT_FOUND" if no match
138
+ - confidence: a number 0-1
139
+ - reasoning: why you selected this element
140
+
141
+ JSON response:`;
142
+ try {
143
+ debug('Calling runClaude...');
144
+ const response = await this.runClaude(prompt);
145
+ debug('Got response:', response.slice(0, 200));
146
+ const parsed = this.parseJsonResponse(response);
147
+ debug('Parsed result:', parsed);
148
+ return {
149
+ ref: String(parsed.ref ?? 'NOT_FOUND'),
150
+ confidence: Number(parsed.confidence ?? 0),
151
+ reasoning: String(parsed.reasoning ?? 'No reasoning provided'),
152
+ };
153
+ }
154
+ catch (error) {
155
+ const errorMessage = error instanceof Error ? error.message : String(error);
156
+ debug('Error in findElement:', errorMessage);
157
+ return {
158
+ ref: 'NOT_FOUND',
159
+ confidence: 0,
160
+ reasoning: `CLI error: ${errorMessage}`,
161
+ };
162
+ }
163
+ }
164
+ /**
165
+ * Run exploration on a spec using Claude CLI
166
+ *
167
+ * Note: The primary AI method is findElement(). This explore() method is a stub
168
+ * that returns a minimal valid structure. Full exploration is orchestrated by
169
+ * the Explorer class which uses findElement() for AI-powered element discovery.
170
+ */
171
+ async explore(params) {
172
+ const explorationId = `exp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
173
+ return {
174
+ spec: params.spec.name,
175
+ specPath: params.specPath,
176
+ explorationId,
177
+ timestamp: new Date().toISOString(),
178
+ durationMs: 0,
179
+ browser: params.browser ?? 'chromium',
180
+ viewport: params.viewport ?? { width: 1280, height: 720 },
181
+ baseUrl: params.baseUrl,
182
+ steps: [],
183
+ outcomeChecks: [],
184
+ overallStatus: 'completed',
185
+ errors: [],
186
+ };
187
+ }
188
+ /**
189
+ * Retry exploration with review feedback
190
+ */
191
+ async retryWithFeedback(params) {
192
+ return this.explore(params);
193
+ }
194
+ }
195
+ //# sourceMappingURL=claude-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-cli.js","sourceRoot":"","sources":["../../src/adapters/claude-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import type { AIAdapter, ExploreParams, ExplorationOutput, RetryParams, EnhancedSnapshot, FindElementResult } from './types';
2
+ /**
3
+ * Configuration options for the Claude adapter
4
+ */
5
+ export interface ClaudeAdapterConfig {
6
+ apiKey?: string;
7
+ model?: string;
8
+ maxTokens?: number;
9
+ }
10
+ /**
11
+ * Claude adapter for AI-powered browser exploration
12
+ *
13
+ * Uses Claude's vision and reasoning capabilities to:
14
+ * - Interpret spec steps
15
+ * - Identify elements in browser snapshots
16
+ * - Execute exploration workflows
17
+ */
18
+ export declare class ClaudeAdapter implements AIAdapter {
19
+ readonly name = "claude";
20
+ private client;
21
+ private model;
22
+ private maxTokens;
23
+ constructor(config?: ClaudeAdapterConfig);
24
+ /**
25
+ * Find element from natural language query using Claude
26
+ *
27
+ * @param query - Natural language description of the element
28
+ * @param snapshot - Browser snapshot with element tree and refs
29
+ * @returns Promise resolving to element ref with reasoning
30
+ */
31
+ findElement(query: string, snapshot: EnhancedSnapshot): Promise<FindElementResult>;
32
+ /**
33
+ * Run exploration on a spec using Claude
34
+ *
35
+ * Note: The primary AI method is findElement(). This explore() method is a stub
36
+ * that returns a minimal valid structure. Full exploration is orchestrated by
37
+ * the Explorer class which uses findElement() for AI-powered element discovery.
38
+ *
39
+ * @param params - Exploration parameters including spec and browser config
40
+ * @returns Promise resolving to exploration output
41
+ */
42
+ explore(params: ExploreParams): Promise<ExplorationOutput>;
43
+ /**
44
+ * Retry exploration with review feedback
45
+ *
46
+ * Note: Currently delegates to explore(). Future enhancement could use
47
+ * review feedback to improve element selection accuracy.
48
+ *
49
+ * @param params - Retry parameters including previous exploration and feedback
50
+ * @returns Promise resolving to new exploration output
51
+ */
52
+ retryWithFeedback(params: RetryParams): Promise<ExplorationOutput>;
53
+ }
54
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyCD;;;;;;;GAOG;AACH,qBAAa,aAAc,YAAW,SAAS;IAC7C,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,GAAE,mBAAwB;IAQ5C;;;;;;OAMG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA0DxF;;;;;;;;;OASG;IACG,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmBhE;;;;;;;;OAQG;IACG,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAGzE"}
@@ -0,0 +1,160 @@
1
+ // @browserflow-ai/exploration - Claude AI Adapter
2
+ import Anthropic from '@anthropic-ai/sdk';
3
+ /**
4
+ * System prompt for element finding
5
+ */
6
+ const ELEMENT_FINDER_SYSTEM_PROMPT = `You are helping find UI elements based on natural language descriptions.
7
+ Given an accessibility snapshot of a web page, identify the element that best matches the user's description.
8
+
9
+ Rules:
10
+ 1. Return the ref (like "e1", "e2") of the matching element using the select_element tool
11
+ 2. If multiple elements could match, pick the most likely based on context
12
+ 3. If no element matches, use ref "NOT_FOUND" with confidence 0
13
+ 4. Consider the element's role, name, text content, and position in the hierarchy
14
+ 5. Be precise - prefer exact matches over partial matches`;
15
+ /**
16
+ * Tool definition for structured element selection
17
+ */
18
+ const SELECT_ELEMENT_TOOL = {
19
+ name: 'select_element',
20
+ description: 'Select an element by its ref from the page snapshot',
21
+ input_schema: {
22
+ type: 'object',
23
+ properties: {
24
+ ref: {
25
+ type: 'string',
26
+ description: 'Element ref like e1, e2, or NOT_FOUND if no match',
27
+ },
28
+ confidence: {
29
+ type: 'number',
30
+ description: 'Confidence score 0-1 for the selection',
31
+ },
32
+ reasoning: {
33
+ type: 'string',
34
+ description: 'Explanation for why this element was selected',
35
+ },
36
+ },
37
+ required: ['ref', 'confidence', 'reasoning'],
38
+ },
39
+ };
40
+ /**
41
+ * Claude adapter for AI-powered browser exploration
42
+ *
43
+ * Uses Claude's vision and reasoning capabilities to:
44
+ * - Interpret spec steps
45
+ * - Identify elements in browser snapshots
46
+ * - Execute exploration workflows
47
+ */
48
+ export class ClaudeAdapter {
49
+ name = 'claude';
50
+ client;
51
+ model;
52
+ maxTokens;
53
+ constructor(config = {}) {
54
+ this.client = new Anthropic({
55
+ apiKey: config.apiKey,
56
+ });
57
+ this.model = config.model ?? 'claude-haiku-4-5';
58
+ this.maxTokens = config.maxTokens ?? 8192;
59
+ }
60
+ /**
61
+ * Find element from natural language query using Claude
62
+ *
63
+ * @param query - Natural language description of the element
64
+ * @param snapshot - Browser snapshot with element tree and refs
65
+ * @returns Promise resolving to element ref with reasoning
66
+ */
67
+ async findElement(query, snapshot) {
68
+ const userMessage = `Find the element matching this description: "${query}"
69
+
70
+ Current page snapshot:
71
+ ${snapshot.tree}
72
+
73
+ Available refs: ${Object.keys(snapshot.refs).join(', ')}
74
+
75
+ Use the select_element tool to return the ref of the best matching element.`;
76
+ const response = await this.client.messages.create({
77
+ model: this.model,
78
+ max_tokens: 1024,
79
+ system: ELEMENT_FINDER_SYSTEM_PROMPT,
80
+ tools: [SELECT_ELEMENT_TOOL],
81
+ tool_choice: { type: 'tool', name: 'select_element' },
82
+ messages: [
83
+ {
84
+ role: 'user',
85
+ content: userMessage,
86
+ },
87
+ ],
88
+ });
89
+ // Handle tool_use response (preferred)
90
+ for (const block of response.content) {
91
+ if (block.type === 'tool_use' && block.name === 'select_element') {
92
+ const input = block.input;
93
+ return {
94
+ ref: input.ref,
95
+ confidence: input.confidence,
96
+ reasoning: input.reasoning,
97
+ };
98
+ }
99
+ }
100
+ // Fallback: parse text response if no tool_use
101
+ for (const block of response.content) {
102
+ if (block.type === 'text') {
103
+ const refMatch = block.text.match(/\be(\d+)\b/);
104
+ if (refMatch) {
105
+ return {
106
+ ref: refMatch[0],
107
+ confidence: 0.7, // Lower confidence for text extraction
108
+ reasoning: block.text,
109
+ };
110
+ }
111
+ }
112
+ }
113
+ // No element found
114
+ return {
115
+ ref: 'NOT_FOUND',
116
+ confidence: 0,
117
+ reasoning: 'Could not extract element ref from response',
118
+ };
119
+ }
120
+ /**
121
+ * Run exploration on a spec using Claude
122
+ *
123
+ * Note: The primary AI method is findElement(). This explore() method is a stub
124
+ * that returns a minimal valid structure. Full exploration is orchestrated by
125
+ * the Explorer class which uses findElement() for AI-powered element discovery.
126
+ *
127
+ * @param params - Exploration parameters including spec and browser config
128
+ * @returns Promise resolving to exploration output
129
+ */
130
+ async explore(params) {
131
+ const explorationId = `exp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
132
+ return {
133
+ spec: params.spec.name,
134
+ specPath: params.specPath,
135
+ explorationId,
136
+ timestamp: new Date().toISOString(),
137
+ durationMs: 0,
138
+ browser: params.browser ?? 'chromium',
139
+ viewport: params.viewport ?? { width: 1280, height: 720 },
140
+ baseUrl: params.baseUrl,
141
+ steps: [],
142
+ outcomeChecks: [],
143
+ overallStatus: 'completed',
144
+ errors: [],
145
+ };
146
+ }
147
+ /**
148
+ * Retry exploration with review feedback
149
+ *
150
+ * Note: Currently delegates to explore(). Future enhancement could use
151
+ * review feedback to improve element selection accuracy.
152
+ *
153
+ * @param params - Retry parameters including previous exploration and feedback
154
+ * @returns Promise resolving to new exploration output
155
+ */
156
+ async retryWithFeedback(params) {
157
+ return this.explore(params);
158
+ }
159
+ }
160
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { ClaudeAdapter } from './claude';
2
+ export type { ClaudeAdapterConfig } from './claude';
3
+ export { ClaudeCliAdapter } from './claude-cli';
4
+ export type { ClaudeCliAdapterConfig } from './claude-cli';
5
+ export type { AIAdapter, ExploreParams, ExplorationOutput, RetryParams, ReviewFeedback, Spec, SpecStep, StepResult, StepExecution, StepScreenshots, OutcomeCheck, } from './types';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAE3D,YAAY,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,YAAY,GACb,MAAM,SAAS,CAAC"}
@@ -0,0 +1,4 @@
1
+ // @browserflow-ai/exploration - Adapter exports
2
+ export { ClaudeAdapter } from './claude';
3
+ export { ClaudeCliAdapter } from './claude-cli';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}