@sparkleideas/browser 3.0.0-alpha.18

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.
@@ -0,0 +1,324 @@
1
+ /**
2
+ * @sparkleideas/browser - Domain Types
3
+ * Core type definitions for browser automation
4
+ */
5
+
6
+ import { z } from 'zod';
7
+
8
+ // ============================================================================
9
+ // Element Reference (from agent-browser snapshots)
10
+ // ============================================================================
11
+
12
+ export const ElementRefSchema = z.string().regex(/^@e\d+$/, 'Must be in format @e1, @e2, etc.');
13
+ export type ElementRef = z.infer<typeof ElementRefSchema>;
14
+
15
+ export const SelectorSchema = z.union([
16
+ ElementRefSchema,
17
+ z.string().min(1), // CSS selector, text=, xpath=, etc.
18
+ ]);
19
+ export type Selector = z.infer<typeof SelectorSchema>;
20
+
21
+ // ============================================================================
22
+ // Snapshot Types
23
+ // ============================================================================
24
+
25
+ export interface SnapshotNode {
26
+ role: string;
27
+ name?: string;
28
+ ref?: string;
29
+ value?: string;
30
+ description?: string;
31
+ level?: number;
32
+ checked?: boolean;
33
+ disabled?: boolean;
34
+ expanded?: boolean;
35
+ selected?: boolean;
36
+ children?: SnapshotNode[];
37
+ }
38
+
39
+ export interface Snapshot {
40
+ tree: SnapshotNode;
41
+ refs: Record<string, SnapshotNode>;
42
+ url: string;
43
+ title: string;
44
+ timestamp: string;
45
+ }
46
+
47
+ export interface SnapshotOptions {
48
+ interactive?: boolean; // -i: Only interactive elements
49
+ compact?: boolean; // -c: Remove empty structural elements
50
+ depth?: number; // -d: Limit tree depth
51
+ selector?: string; // -s: Scope to CSS selector
52
+ }
53
+
54
+ // ============================================================================
55
+ // Session Types
56
+ // ============================================================================
57
+
58
+ export interface BrowserSession {
59
+ id: string;
60
+ createdAt: string;
61
+ lastActivity: string;
62
+ currentUrl?: string;
63
+ cookies: Cookie[];
64
+ localStorage: Record<string, string>;
65
+ sessionStorage: Record<string, string>;
66
+ history: string[];
67
+ authState?: string; // Path to saved auth state
68
+ }
69
+
70
+ export interface Cookie {
71
+ name: string;
72
+ value: string;
73
+ domain?: string;
74
+ path?: string;
75
+ expires?: number;
76
+ httpOnly?: boolean;
77
+ secure?: boolean;
78
+ sameSite?: 'Strict' | 'Lax' | 'None';
79
+ }
80
+
81
+ // ============================================================================
82
+ // Network Types
83
+ // ============================================================================
84
+
85
+ export interface NetworkRoute {
86
+ urlPattern: string;
87
+ action: 'intercept' | 'abort' | 'mock';
88
+ mockResponse?: {
89
+ status?: number;
90
+ headers?: Record<string, string>;
91
+ body?: string | object;
92
+ };
93
+ }
94
+
95
+ export interface NetworkRequest {
96
+ url: string;
97
+ method: string;
98
+ headers: Record<string, string>;
99
+ postData?: string;
100
+ timestamp: string;
101
+ status?: number;
102
+ responseHeaders?: Record<string, string>;
103
+ }
104
+
105
+ // ============================================================================
106
+ // Viewport & Device Types
107
+ // ============================================================================
108
+
109
+ export interface Viewport {
110
+ width: number;
111
+ height: number;
112
+ }
113
+
114
+ export interface DeviceDescriptor {
115
+ name: string;
116
+ viewport: Viewport;
117
+ userAgent: string;
118
+ deviceScaleFactor: number;
119
+ isMobile: boolean;
120
+ hasTouch: boolean;
121
+ }
122
+
123
+ // ============================================================================
124
+ // Action Result Types
125
+ // ============================================================================
126
+
127
+ export interface ActionResult<T = unknown> {
128
+ success: boolean;
129
+ data?: T;
130
+ error?: string;
131
+ duration?: number;
132
+ screenshot?: string; // Base64 if captured
133
+ }
134
+
135
+ export interface ClickResult extends ActionResult {
136
+ data?: {
137
+ clicked: boolean;
138
+ position?: { x: number; y: number };
139
+ };
140
+ }
141
+
142
+ export interface FillResult extends ActionResult {
143
+ data?: {
144
+ filled: boolean;
145
+ previousValue?: string;
146
+ newValue: string;
147
+ };
148
+ }
149
+
150
+ export interface ScreenshotResult extends ActionResult<string> {
151
+ data?: string; // Base64 PNG
152
+ path?: string; // If saved to file
153
+ }
154
+
155
+ export interface EvalResult<T = unknown> extends ActionResult<T> {
156
+ data?: T;
157
+ }
158
+
159
+ // ============================================================================
160
+ // Command Input Schemas
161
+ // ============================================================================
162
+
163
+ export const OpenInputSchema = z.object({
164
+ url: z.string().url(),
165
+ session: z.string().optional(),
166
+ waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),
167
+ headers: z.record(z.string()).optional(),
168
+ timeout: z.number().positive().optional(),
169
+ });
170
+ export type OpenInput = z.infer<typeof OpenInputSchema>;
171
+
172
+ export const ClickInputSchema = z.object({
173
+ target: SelectorSchema,
174
+ button: z.enum(['left', 'right', 'middle']).optional(),
175
+ clickCount: z.number().int().positive().optional(),
176
+ delay: z.number().nonnegative().optional(),
177
+ force: z.boolean().optional(),
178
+ timeout: z.number().positive().optional(),
179
+ });
180
+ export type ClickInput = z.infer<typeof ClickInputSchema>;
181
+
182
+ export const FillInputSchema = z.object({
183
+ target: SelectorSchema,
184
+ value: z.string(),
185
+ force: z.boolean().optional(),
186
+ timeout: z.number().positive().optional(),
187
+ });
188
+ export type FillInput = z.infer<typeof FillInputSchema>;
189
+
190
+ export const TypeInputSchema = z.object({
191
+ target: SelectorSchema,
192
+ text: z.string(),
193
+ delay: z.number().nonnegative().optional(),
194
+ timeout: z.number().positive().optional(),
195
+ });
196
+ export type TypeInput = z.infer<typeof TypeInputSchema>;
197
+
198
+ export const PressInputSchema = z.object({
199
+ key: z.string(),
200
+ delay: z.number().nonnegative().optional(),
201
+ });
202
+ export type PressInput = z.infer<typeof PressInputSchema>;
203
+
204
+ export const SnapshotInputSchema = z.object({
205
+ interactive: z.boolean().optional(),
206
+ compact: z.boolean().optional(),
207
+ depth: z.number().int().positive().optional(),
208
+ selector: z.string().optional(),
209
+ });
210
+ export type SnapshotInput = z.infer<typeof SnapshotInputSchema>;
211
+
212
+ export const ScreenshotInputSchema = z.object({
213
+ path: z.string().optional(),
214
+ fullPage: z.boolean().optional(),
215
+ clip: z.object({
216
+ x: z.number(),
217
+ y: z.number(),
218
+ width: z.number(),
219
+ height: z.number(),
220
+ }).optional(),
221
+ });
222
+ export type ScreenshotInput = z.infer<typeof ScreenshotInputSchema>;
223
+
224
+ export const WaitInputSchema = z.object({
225
+ selector: z.string().optional(),
226
+ timeout: z.number().positive().optional(),
227
+ text: z.string().optional(),
228
+ url: z.string().optional(),
229
+ load: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),
230
+ fn: z.string().optional(), // JavaScript condition
231
+ });
232
+ export type WaitInput = z.infer<typeof WaitInputSchema>;
233
+
234
+ export const EvalInputSchema = z.object({
235
+ script: z.string(),
236
+ args: z.array(z.unknown()).optional(),
237
+ });
238
+ export type EvalInput = z.infer<typeof EvalInputSchema>;
239
+
240
+ export const GetInputSchema = z.object({
241
+ type: z.enum(['text', 'html', 'value', 'attr', 'title', 'url', 'count', 'box']),
242
+ target: SelectorSchema.optional(),
243
+ attribute: z.string().optional(), // For 'attr' type
244
+ });
245
+ export type GetInput = z.infer<typeof GetInputSchema>;
246
+
247
+ export const SetViewportInputSchema = z.object({
248
+ width: z.number().int().positive(),
249
+ height: z.number().int().positive(),
250
+ });
251
+ export type SetViewportInput = z.infer<typeof SetViewportInputSchema>;
252
+
253
+ export const SetDeviceInputSchema = z.object({
254
+ device: z.string(),
255
+ });
256
+ export type SetDeviceInput = z.infer<typeof SetDeviceInputSchema>;
257
+
258
+ export const NetworkRouteInputSchema = z.object({
259
+ urlPattern: z.string(),
260
+ abort: z.boolean().optional(),
261
+ body: z.union([z.string(), z.object({})]).optional(),
262
+ status: z.number().int().optional(),
263
+ headers: z.record(z.string()).optional(),
264
+ });
265
+ export type NetworkRouteInput = z.infer<typeof NetworkRouteInputSchema>;
266
+
267
+ // ============================================================================
268
+ // Domain Events
269
+ // ============================================================================
270
+
271
+ export type BrowserEvent =
272
+ | { type: 'session:created'; sessionId: string; timestamp: string }
273
+ | { type: 'session:closed'; sessionId: string; timestamp: string }
274
+ | { type: 'page:navigated'; url: string; title: string; timestamp: string }
275
+ | { type: 'page:loaded'; url: string; loadTime: number; timestamp: string }
276
+ | { type: 'element:clicked'; ref: string; selector?: string; timestamp: string }
277
+ | { type: 'element:filled'; ref: string; value: string; timestamp: string }
278
+ | { type: 'snapshot:taken'; refs: number; interactive: number; timestamp: string }
279
+ | { type: 'screenshot:captured'; path?: string; size: number; timestamp: string }
280
+ | { type: 'network:intercepted'; url: string; action: string; timestamp: string }
281
+ | { type: 'error:occurred'; message: string; stack?: string; timestamp: string };
282
+
283
+ // ============================================================================
284
+ // Integration with agentic-flow
285
+ // ============================================================================
286
+
287
+ export interface BrowserTrajectory {
288
+ id: string;
289
+ sessionId: string;
290
+ goal: string;
291
+ steps: BrowserTrajectoryStep[];
292
+ startedAt: string;
293
+ completedAt?: string;
294
+ success?: boolean;
295
+ verdict?: string;
296
+ }
297
+
298
+ export interface BrowserTrajectoryStep {
299
+ action: string;
300
+ input: Record<string, unknown>;
301
+ result: ActionResult;
302
+ snapshot?: Snapshot;
303
+ timestamp: string;
304
+ }
305
+
306
+ // ============================================================================
307
+ // Swarm Integration
308
+ // ============================================================================
309
+
310
+ export interface BrowserSwarmConfig {
311
+ topology: 'hierarchical' | 'mesh' | 'star';
312
+ maxSessions: number;
313
+ sessionPrefix: string;
314
+ sharedCookies?: boolean;
315
+ coordinatorSession?: string;
316
+ }
317
+
318
+ export interface BrowserAgentConfig {
319
+ sessionId: string;
320
+ role: 'navigator' | 'scraper' | 'validator' | 'tester' | 'monitor';
321
+ capabilities: string[];
322
+ defaultTimeout: number;
323
+ headless: boolean;
324
+ }
package/src/index.ts ADDED
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @sparkleideas/browser
3
+ * Browser automation for AI agents - integrates agent-browser with claude-flow swarms
4
+ *
5
+ * Features:
6
+ * - 50+ MCP tools for browser automation
7
+ * - AI-optimized snapshots with element refs (@e1, @e2)
8
+ * - Multi-session support for swarm coordination
9
+ * - Trajectory tracking for ReasoningBank/SONA learning
10
+ * - Integration with agentic-flow optimizations
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { createBrowserService, browserTools } from '@sparkleideas/browser';
15
+ *
16
+ * // Create a browser service
17
+ * const browser = createBrowserService({ sessionId: 'my-session' });
18
+ *
19
+ * // Start a trajectory for learning
20
+ * const trajectoryId = browser.startTrajectory('Login to dashboard');
21
+ *
22
+ * // Perform actions
23
+ * await browser.open('https://example.com/login');
24
+ * await browser.snapshot({ interactive: true });
25
+ * await browser.fill('@e1', 'user@example.com');
26
+ * await browser.fill('@e2', 'password');
27
+ * await browser.click('@e3');
28
+ *
29
+ * // End trajectory
30
+ * const trajectory = browser.endTrajectory(true, 'Login successful');
31
+ * ```
32
+ */
33
+
34
+ // Domain types
35
+ export * from './domain/types.js';
36
+
37
+ // Infrastructure
38
+ export { AgentBrowserAdapter } from './infrastructure/agent-browser-adapter.js';
39
+ export type { AgentBrowserAdapterOptions } from './infrastructure/agent-browser-adapter.js';
40
+
41
+ // ReasoningBank integration
42
+ export {
43
+ ReasoningBankAdapter,
44
+ getReasoningBank,
45
+ type BrowserPattern,
46
+ type PatternStep,
47
+ } from './infrastructure/reasoningbank-adapter.js';
48
+
49
+ // Hooks integration
50
+ export {
51
+ preBrowseHook,
52
+ postBrowseHook,
53
+ browserHooks,
54
+ type PreBrowseInput,
55
+ type PreBrowseResult,
56
+ type PostBrowseInput,
57
+ type PostBrowseResult,
58
+ } from './infrastructure/hooks-integration.js';
59
+
60
+ // Memory integration (HNSW semantic search)
61
+ export {
62
+ ClaudeFlowMemoryAdapter,
63
+ BrowserMemoryManager,
64
+ createMemoryManager,
65
+ getMemoryAdapter,
66
+ type BrowserMemoryEntry,
67
+ type MemorySearchResult,
68
+ type MemoryStats,
69
+ type MemorySearchOptions,
70
+ type MemoryFilter,
71
+ type IMemoryAdapter,
72
+ } from './infrastructure/memory-integration.js';
73
+
74
+ // Security integration (AIDefence)
75
+ export {
76
+ BrowserSecurityScanner,
77
+ getSecurityScanner,
78
+ isUrlSafe,
79
+ containsPII,
80
+ type ThreatScanResult,
81
+ type Threat,
82
+ type ThreatType,
83
+ type PIIMatch,
84
+ type PIIType,
85
+ type SecurityConfig,
86
+ } from './infrastructure/security-integration.js';
87
+
88
+ // Workflow templates
89
+ export {
90
+ WorkflowManager,
91
+ getWorkflowManager,
92
+ listWorkflows,
93
+ getWorkflow,
94
+ WORKFLOW_TEMPLATES,
95
+ type WorkflowTemplate,
96
+ type WorkflowCategory,
97
+ type WorkflowStep,
98
+ type WorkflowVariable,
99
+ type WorkflowExecution,
100
+ type WorkflowStepResult,
101
+ type BrowserAction,
102
+ } from './infrastructure/workflow-templates.js';
103
+
104
+ // Application services
105
+ export {
106
+ BrowserService,
107
+ BrowserSwarmCoordinator,
108
+ createBrowserService,
109
+ createBrowserSwarm,
110
+ type BrowserServiceConfig,
111
+ } from './application/browser-service.js';
112
+
113
+ // MCP tools
114
+ export { browserTools } from './mcp-tools/browser-tools.js';
115
+ export type { MCPTool } from './mcp-tools/browser-tools.js';
116
+
117
+ // Re-export main classes as defaults
118
+ import { BrowserService, createBrowserService, createBrowserSwarm } from './application/browser-service.js';
119
+ import { browserTools } from './mcp-tools/browser-tools.js';
120
+ import { browserHooks, preBrowseHook, postBrowseHook } from './infrastructure/hooks-integration.js';
121
+ import { getReasoningBank } from './infrastructure/reasoningbank-adapter.js';
122
+ import { getMemoryAdapter, createMemoryManager } from './infrastructure/memory-integration.js';
123
+ import { getSecurityScanner, isUrlSafe, containsPII } from './infrastructure/security-integration.js';
124
+ import { getWorkflowManager, listWorkflows, getWorkflow } from './infrastructure/workflow-templates.js';
125
+
126
+ export default {
127
+ // Services
128
+ BrowserService,
129
+ createBrowserService,
130
+ createBrowserSwarm,
131
+
132
+ // MCP tools
133
+ browserTools,
134
+
135
+ // Hooks
136
+ browserHooks,
137
+ preBrowseHook,
138
+ postBrowseHook,
139
+
140
+ // Learning
141
+ getReasoningBank,
142
+
143
+ // Memory (HNSW-indexed)
144
+ getMemoryAdapter,
145
+ createMemoryManager,
146
+
147
+ // Security (AIDefence)
148
+ getSecurityScanner,
149
+ isUrlSafe,
150
+ containsPII,
151
+
152
+ // Workflows
153
+ getWorkflowManager,
154
+ listWorkflows,
155
+ getWorkflow,
156
+ };