@hasna/connectors 0.0.6 → 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/LICENSE +191 -0
- package/README.md +67 -41
- package/bin/index.js +1390 -745
- package/bin/mcp.js +184 -19
- package/bin/serve.js +1118 -0
- package/connectors/connect-anthropic/package.json +4 -4
- package/connectors/connect-aws/package.json +4 -4
- package/connectors/connect-brandsight/package.json +4 -4
- package/connectors/connect-cloudflare/.env.example +0 -5
- package/connectors/connect-cloudflare/package.json +4 -4
- package/connectors/connect-discord/package.json +4 -4
- package/connectors/connect-docker/package.json +4 -4
- package/connectors/connect-e2b/package.json +4 -4
- package/connectors/connect-elevenlabs/package.json +4 -4
- package/connectors/connect-exa/package.json +4 -4
- package/connectors/connect-figma/package.json +4 -4
- package/connectors/connect-firecrawl/package.json +4 -4
- package/connectors/connect-github/package.json +4 -4
- package/connectors/connect-gmail/package.json +4 -4
- package/connectors/connect-google/package.json +4 -4
- package/connectors/connect-googlecalendar/package.json +4 -4
- package/connectors/connect-googlecloud/package.json +4 -4
- package/connectors/connect-googlecontacts/package.json +4 -4
- package/connectors/connect-googledocs/package.json +4 -4
- package/connectors/connect-googledrive/package.json +4 -4
- package/connectors/connect-googlegemini/package.json +4 -4
- package/connectors/connect-googlemaps/package.json +2 -2
- package/connectors/connect-googlesheets/package.json +4 -4
- package/connectors/connect-googletasks/package.json +2 -2
- package/connectors/connect-hedra/package.json +4 -4
- package/connectors/connect-heygen/package.json +4 -4
- package/connectors/connect-huggingface/package.json +4 -4
- package/connectors/connect-icons8/package.json +4 -4
- package/connectors/connect-maropost/package.json +4 -4
- package/connectors/connect-mercury/package.json +4 -4
- package/connectors/connect-meta/package.json +4 -4
- package/connectors/connect-midjourney/package.json +4 -4
- package/connectors/connect-mistral/package.json +4 -4
- package/connectors/connect-mixpanel/package.json +4 -4
- package/connectors/connect-notion/.env.example +0 -5
- package/connectors/connect-notion/package.json +2 -2
- package/connectors/connect-openai/package.json +4 -4
- package/connectors/connect-openweathermap/package.json +4 -4
- package/connectors/connect-pandadoc/package.json +4 -4
- package/connectors/connect-quo/package.json +4 -4
- package/connectors/connect-reddit/package.json +4 -4
- package/connectors/connect-reducto/package.json +1 -1
- package/connectors/connect-resend/package.json +4 -4
- package/connectors/connect-revolut/package.json +4 -4
- package/connectors/connect-sedo/package.json +4 -4
- package/connectors/connect-sentry/package.json +4 -4
- package/connectors/connect-shadcn/package.json +4 -4
- package/connectors/connect-shopify/package.json +2 -2
- package/connectors/connect-snap/package.json +4 -4
- package/connectors/connect-stabilityai/package.json +4 -4
- package/connectors/connect-stripe/package.json +4 -4
- package/connectors/connect-stripeatlas/package.json +4 -4
- package/connectors/connect-substack/package.json +4 -4
- package/connectors/connect-tiktok/package.json +4 -4
- package/connectors/connect-tinker/package.json +4 -4
- package/connectors/connect-twilio/package.json +6 -6
- package/connectors/connect-uspto/package.json +4 -4
- package/connectors/connect-webflow/package.json +2 -2
- package/connectors/connect-wix/package.json +2 -2
- package/connectors/connect-x/package.json +4 -4
- package/connectors/connect-xads/package.json +4 -4
- package/connectors/connect-xai/package.json +4 -4
- package/connectors/connect-youtube/package.json +4 -4
- package/connectors/connect-zoom/package.json +4 -4
- package/dashboard/dist/assets/index-BZZ_709y.css +1 -0
- package/dashboard/dist/assets/index-CBroKWCD.js +234 -0
- package/dashboard/dist/index.html +13 -0
- package/dashboard/dist/logo.jpg +0 -0
- package/dist/cli/cli.test.d.ts +1 -0
- package/dist/cli/components/App.d.ts +6 -0
- package/dist/cli/components/CategorySelect.d.ts +6 -0
- package/dist/cli/components/ConnectorSelect.d.ts +10 -0
- package/dist/cli/components/Header.d.ts +6 -0
- package/dist/cli/components/InstallProgress.d.ts +8 -0
- package/dist/cli/components/SearchView.d.ts +8 -0
- package/dist/cli/components/components.test.d.ts +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -16
- package/dist/lib/installer.d.ts +55 -0
- package/dist/lib/installer.test.d.ts +1 -0
- package/dist/lib/registry.d.ts +18 -0
- package/dist/lib/registry.test.d.ts +1 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/mcp.test.d.ts +1 -0
- package/dist/server/auth.d.ts +70 -0
- package/dist/server/dashboard.d.ts +5 -0
- package/dist/server/index.d.ts +6 -0
- package/dist/server/serve.d.ts +12 -0
- package/dist/server/server.test.d.ts +1 -0
- package/package.json +11 -6
- package/connectors/connect-browseruse/.env.example +0 -7
- package/connectors/connect-browseruse/.npmrc.example +0 -2
- package/connectors/connect-browseruse/AGENTS.md +0 -172
- package/connectors/connect-browseruse/CLAUDE.md +0 -172
- package/connectors/connect-browseruse/GEMINI.md +0 -172
- package/connectors/connect-browseruse/README.md +0 -153
- package/connectors/connect-browseruse/package.json +0 -52
- package/connectors/connect-browseruse/src/api/billing.ts +0 -32
- package/connectors/connect-browseruse/src/api/browsers.ts +0 -50
- package/connectors/connect-browseruse/src/api/client.ts +0 -168
- package/connectors/connect-browseruse/src/api/files.ts +0 -70
- package/connectors/connect-browseruse/src/api/index.ts +0 -95
- package/connectors/connect-browseruse/src/api/profiles.ts +0 -59
- package/connectors/connect-browseruse/src/api/sessions.ts +0 -88
- package/connectors/connect-browseruse/src/api/skills.ts +0 -194
- package/connectors/connect-browseruse/src/api/tasks.ts +0 -127
- package/connectors/connect-browseruse/src/cli/index.ts +0 -888
- package/connectors/connect-browseruse/src/index.ts +0 -35
- package/connectors/connect-browseruse/src/types/index.ts +0 -312
- package/connectors/connect-browseruse/src/utils/config.ts +0 -212
- package/connectors/connect-browseruse/src/utils/output.ts +0 -119
- package/connectors/connect-browseruse/tsconfig.json +0 -16
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
// Browser Use Connector
|
|
2
|
-
// TypeScript wrapper for the Browser Use Cloud API
|
|
3
|
-
|
|
4
|
-
export { BrowserUse } from './api';
|
|
5
|
-
export * from './types';
|
|
6
|
-
|
|
7
|
-
// Re-export individual API classes for advanced usage
|
|
8
|
-
export {
|
|
9
|
-
BrowserUseClient,
|
|
10
|
-
TasksApi,
|
|
11
|
-
SessionsApi,
|
|
12
|
-
ProfilesApi,
|
|
13
|
-
BrowsersApi,
|
|
14
|
-
SkillsApi,
|
|
15
|
-
MarketplaceApi,
|
|
16
|
-
FilesApi,
|
|
17
|
-
BillingApi,
|
|
18
|
-
} from './api';
|
|
19
|
-
|
|
20
|
-
// Export config utilities
|
|
21
|
-
export {
|
|
22
|
-
getApiKey,
|
|
23
|
-
setApiKey,
|
|
24
|
-
getBaseUrl,
|
|
25
|
-
setBaseUrl,
|
|
26
|
-
getCurrentProfile,
|
|
27
|
-
setCurrentProfile,
|
|
28
|
-
listProfiles,
|
|
29
|
-
createProfile,
|
|
30
|
-
deleteProfile,
|
|
31
|
-
loadProfile,
|
|
32
|
-
saveProfile,
|
|
33
|
-
clearConfig,
|
|
34
|
-
hasApiKey,
|
|
35
|
-
} from './utils/config';
|
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Browser Use API Types
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// ============================================
|
|
6
|
-
// Common Types
|
|
7
|
-
// ============================================
|
|
8
|
-
|
|
9
|
-
export type OutputFormat = 'json' | 'pretty';
|
|
10
|
-
|
|
11
|
-
export interface PaginatedResponse<T> {
|
|
12
|
-
data: T[];
|
|
13
|
-
hasMore: boolean;
|
|
14
|
-
nextCursor?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class BrowserUseApiError extends Error {
|
|
18
|
-
constructor(
|
|
19
|
-
message: string,
|
|
20
|
-
public statusCode: number,
|
|
21
|
-
public details?: unknown
|
|
22
|
-
) {
|
|
23
|
-
super(message);
|
|
24
|
-
this.name = 'BrowserUseApiError';
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// ============================================
|
|
29
|
-
// Task Types
|
|
30
|
-
// ============================================
|
|
31
|
-
|
|
32
|
-
export type TaskStatus =
|
|
33
|
-
| 'created'
|
|
34
|
-
| 'queued'
|
|
35
|
-
| 'running'
|
|
36
|
-
| 'paused'
|
|
37
|
-
| 'stopped'
|
|
38
|
-
| 'completed'
|
|
39
|
-
| 'failed';
|
|
40
|
-
|
|
41
|
-
export interface TaskStep {
|
|
42
|
-
id: string;
|
|
43
|
-
type: string;
|
|
44
|
-
description: string;
|
|
45
|
-
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
46
|
-
result?: unknown;
|
|
47
|
-
error?: string;
|
|
48
|
-
createdAt: string;
|
|
49
|
-
completedAt?: string;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface Task {
|
|
53
|
-
id: string;
|
|
54
|
-
task: string;
|
|
55
|
-
status: TaskStatus;
|
|
56
|
-
sessionId?: string;
|
|
57
|
-
steps: TaskStep[];
|
|
58
|
-
output?: unknown;
|
|
59
|
-
error?: string;
|
|
60
|
-
liveUrl?: string;
|
|
61
|
-
createdAt: string;
|
|
62
|
-
updatedAt: string;
|
|
63
|
-
completedAt?: string;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Sensitive data configuration for secure credential handling.
|
|
68
|
-
* The LLM only sees placeholder names (e.g., 'x_user', 'x_pass'),
|
|
69
|
-
* actual values are injected directly into forms without LLM exposure.
|
|
70
|
-
*/
|
|
71
|
-
export type SensitiveData =
|
|
72
|
-
| Record<string, string> // Global: applies to all domains
|
|
73
|
-
| Record<string, Record<string, string>>; // Per-domain: 'https://*.example.com': { user: '...', pass: '...' }
|
|
74
|
-
|
|
75
|
-
export interface CreateTaskParams {
|
|
76
|
-
task: string;
|
|
77
|
-
sessionId?: string;
|
|
78
|
-
schema?: Record<string, unknown>;
|
|
79
|
-
save_browser_data?: boolean;
|
|
80
|
-
/**
|
|
81
|
-
* Sensitive data like credentials to handle securely.
|
|
82
|
-
* Can be global (applies everywhere) or per-domain.
|
|
83
|
-
* @example { 'x_user': 'email@example.com', 'x_pass': 'password123' }
|
|
84
|
-
* @example { 'https://*.mysite.com': { 'user': 'admin', 'pass': 'secret' } }
|
|
85
|
-
*/
|
|
86
|
-
sensitive_data?: SensitiveData;
|
|
87
|
-
/** Disable vision to prevent LLM from seeing sensitive data in screenshots */
|
|
88
|
-
use_vision?: boolean;
|
|
89
|
-
/** Allowed domains to restrict agent navigation (security) */
|
|
90
|
-
allowed_domains?: string[];
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export interface UpdateTaskParams {
|
|
94
|
-
action: 'stop' | 'pause' | 'resume' | 'stop-and-close-session';
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export interface ListTasksParams {
|
|
98
|
-
limit?: number;
|
|
99
|
-
cursor?: string;
|
|
100
|
-
sessionId?: string;
|
|
101
|
-
status?: TaskStatus;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// ============================================
|
|
105
|
-
// Session Types
|
|
106
|
-
// ============================================
|
|
107
|
-
|
|
108
|
-
export type SessionStatus = 'active' | 'inactive' | 'closed';
|
|
109
|
-
|
|
110
|
-
export interface Session {
|
|
111
|
-
id: string;
|
|
112
|
-
status: SessionStatus;
|
|
113
|
-
profileId?: string;
|
|
114
|
-
liveUrl?: string;
|
|
115
|
-
connectUrl?: string;
|
|
116
|
-
proxyUrl?: string;
|
|
117
|
-
keepAlive: boolean;
|
|
118
|
-
createdAt: string;
|
|
119
|
-
updatedAt: string;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export interface CreateSessionParams {
|
|
123
|
-
task?: string;
|
|
124
|
-
profileId?: string;
|
|
125
|
-
proxyUrl?: string;
|
|
126
|
-
keepAlive?: boolean;
|
|
127
|
-
save_browser_data?: boolean;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export interface ListSessionsParams {
|
|
131
|
-
limit?: number;
|
|
132
|
-
cursor?: string;
|
|
133
|
-
status?: SessionStatus;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export interface SessionPublicShare {
|
|
137
|
-
id: string;
|
|
138
|
-
sessionId: string;
|
|
139
|
-
publicUrl: string;
|
|
140
|
-
expiresAt: string;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// ============================================
|
|
144
|
-
// Profile Types
|
|
145
|
-
// ============================================
|
|
146
|
-
|
|
147
|
-
export interface Profile {
|
|
148
|
-
id: string;
|
|
149
|
-
name: string;
|
|
150
|
-
description?: string;
|
|
151
|
-
createdAt: string;
|
|
152
|
-
updatedAt: string;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export interface CreateProfileParams {
|
|
156
|
-
name: string;
|
|
157
|
-
description?: string;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
export interface UpdateProfileParams {
|
|
161
|
-
name?: string;
|
|
162
|
-
description?: string;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export interface ListProfilesParams {
|
|
166
|
-
limit?: number;
|
|
167
|
-
cursor?: string;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// ============================================
|
|
171
|
-
// Browser Session Types
|
|
172
|
-
// ============================================
|
|
173
|
-
|
|
174
|
-
export interface BrowserSession {
|
|
175
|
-
id: string;
|
|
176
|
-
status: 'active' | 'stopped';
|
|
177
|
-
liveUrl?: string;
|
|
178
|
-
connectUrl?: string;
|
|
179
|
-
wsUrl?: string;
|
|
180
|
-
createdAt: string;
|
|
181
|
-
stoppedAt?: string;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
export interface CreateBrowserSessionParams {
|
|
185
|
-
profileId?: string;
|
|
186
|
-
proxyUrl?: string;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export interface ListBrowserSessionsParams {
|
|
190
|
-
limit?: number;
|
|
191
|
-
cursor?: string;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// ============================================
|
|
195
|
-
// Skill Types
|
|
196
|
-
// ============================================
|
|
197
|
-
|
|
198
|
-
export type SkillStatus = 'draft' | 'generating' | 'ready' | 'failed';
|
|
199
|
-
|
|
200
|
-
export interface SkillParameter {
|
|
201
|
-
name: string;
|
|
202
|
-
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
|
|
203
|
-
description?: string;
|
|
204
|
-
required?: boolean;
|
|
205
|
-
default?: unknown;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export interface SkillSchema {
|
|
209
|
-
parameters: SkillParameter[];
|
|
210
|
-
output?: Record<string, unknown>;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export interface Skill {
|
|
214
|
-
id: string;
|
|
215
|
-
name: string;
|
|
216
|
-
description?: string;
|
|
217
|
-
status: SkillStatus;
|
|
218
|
-
schema?: SkillSchema;
|
|
219
|
-
isPublic: boolean;
|
|
220
|
-
version: number;
|
|
221
|
-
createdAt: string;
|
|
222
|
-
updatedAt: string;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
export interface CreateSkillParams {
|
|
226
|
-
name: string;
|
|
227
|
-
description?: string;
|
|
228
|
-
task: string;
|
|
229
|
-
exampleInputs?: Record<string, unknown>[];
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
export interface UpdateSkillParams {
|
|
233
|
-
name?: string;
|
|
234
|
-
description?: string;
|
|
235
|
-
isPublic?: boolean;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export interface ExecuteSkillParams {
|
|
239
|
-
parameters: Record<string, unknown>;
|
|
240
|
-
sessionId?: string;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
export interface RefineSkillParams {
|
|
244
|
-
feedback: string;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
export interface SkillExecution {
|
|
248
|
-
id: string;
|
|
249
|
-
skillId: string;
|
|
250
|
-
status: 'queued' | 'running' | 'completed' | 'failed';
|
|
251
|
-
input: Record<string, unknown>;
|
|
252
|
-
output?: unknown;
|
|
253
|
-
error?: string;
|
|
254
|
-
createdAt: string;
|
|
255
|
-
completedAt?: string;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export interface ListSkillsParams {
|
|
259
|
-
limit?: number;
|
|
260
|
-
cursor?: string;
|
|
261
|
-
status?: SkillStatus;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
export interface ListSkillExecutionsParams {
|
|
265
|
-
limit?: number;
|
|
266
|
-
cursor?: string;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// ============================================
|
|
270
|
-
// File Types
|
|
271
|
-
// ============================================
|
|
272
|
-
|
|
273
|
-
export interface PresignedUrl {
|
|
274
|
-
url: string;
|
|
275
|
-
expiresAt: string;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export interface UploadFileParams {
|
|
279
|
-
fileName: string;
|
|
280
|
-
contentType?: string;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// ============================================
|
|
284
|
-
// Billing Types
|
|
285
|
-
// ============================================
|
|
286
|
-
|
|
287
|
-
export interface AccountBilling {
|
|
288
|
-
accountId: string;
|
|
289
|
-
email: string;
|
|
290
|
-
credits: number;
|
|
291
|
-
plan: 'free' | 'payg' | 'business' | 'enterprise';
|
|
292
|
-
createdAt: string;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// ============================================
|
|
296
|
-
// Marketplace Types
|
|
297
|
-
// ============================================
|
|
298
|
-
|
|
299
|
-
export interface MarketplaceSkill {
|
|
300
|
-
id: string;
|
|
301
|
-
name: string;
|
|
302
|
-
description?: string;
|
|
303
|
-
author: string;
|
|
304
|
-
schema?: SkillSchema;
|
|
305
|
-
downloads: number;
|
|
306
|
-
rating?: number;
|
|
307
|
-
createdAt: string;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
export interface CloneSkillParams {
|
|
311
|
-
name?: string;
|
|
312
|
-
}
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, rmSync } from 'fs';
|
|
2
|
-
import { homedir } from 'os';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
|
|
5
|
-
const CONNECTOR_NAME = 'connect-browseruse';
|
|
6
|
-
const DEFAULT_PROFILE = 'default';
|
|
7
|
-
|
|
8
|
-
export interface ProfileConfig {
|
|
9
|
-
apiKey?: string;
|
|
10
|
-
baseUrl?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Store for --profile flag override (set by CLI before commands run)
|
|
14
|
-
let profileOverride: string | undefined;
|
|
15
|
-
|
|
16
|
-
// Config directory: ~/.connect/{connector-name}/
|
|
17
|
-
const CONFIG_DIR = join(homedir(), '.connect', CONNECTOR_NAME);
|
|
18
|
-
const PROFILES_DIR = join(CONFIG_DIR, 'profiles');
|
|
19
|
-
const CURRENT_PROFILE_FILE = join(CONFIG_DIR, 'current_profile');
|
|
20
|
-
|
|
21
|
-
// ============================================
|
|
22
|
-
// Profile Management
|
|
23
|
-
// ============================================
|
|
24
|
-
|
|
25
|
-
export function setProfileOverride(profile: string | undefined): void {
|
|
26
|
-
profileOverride = profile;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function ensureConfigDir(): void {
|
|
30
|
-
if (!existsSync(CONFIG_DIR)) {
|
|
31
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
32
|
-
}
|
|
33
|
-
if (!existsSync(PROFILES_DIR)) {
|
|
34
|
-
mkdirSync(PROFILES_DIR, { recursive: true });
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function getProfilePath(profile: string): string {
|
|
39
|
-
return join(PROFILES_DIR, `${profile}.json`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Get the current active profile name
|
|
44
|
-
*/
|
|
45
|
-
export function getCurrentProfile(): string {
|
|
46
|
-
if (profileOverride) {
|
|
47
|
-
return profileOverride;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
ensureConfigDir();
|
|
51
|
-
|
|
52
|
-
if (existsSync(CURRENT_PROFILE_FILE)) {
|
|
53
|
-
try {
|
|
54
|
-
const profile = readFileSync(CURRENT_PROFILE_FILE, 'utf-8').trim();
|
|
55
|
-
if (profile && profileExists(profile)) {
|
|
56
|
-
return profile;
|
|
57
|
-
}
|
|
58
|
-
} catch {
|
|
59
|
-
// Fall through to default
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return DEFAULT_PROFILE;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Set the current active profile
|
|
68
|
-
*/
|
|
69
|
-
export function setCurrentProfile(profile: string): void {
|
|
70
|
-
ensureConfigDir();
|
|
71
|
-
|
|
72
|
-
if (!profileExists(profile) && profile !== DEFAULT_PROFILE) {
|
|
73
|
-
throw new Error(`Profile "${profile}" does not exist`);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
writeFileSync(CURRENT_PROFILE_FILE, profile);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Check if a profile exists
|
|
81
|
-
*/
|
|
82
|
-
export function profileExists(profile: string): boolean {
|
|
83
|
-
return existsSync(getProfilePath(profile));
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* List all available profiles
|
|
88
|
-
*/
|
|
89
|
-
export function listProfiles(): string[] {
|
|
90
|
-
ensureConfigDir();
|
|
91
|
-
|
|
92
|
-
if (!existsSync(PROFILES_DIR)) {
|
|
93
|
-
return [];
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return readdirSync(PROFILES_DIR)
|
|
97
|
-
.filter(f => f.endsWith('.json'))
|
|
98
|
-
.map(f => f.replace('.json', ''))
|
|
99
|
-
.sort();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Create a new profile
|
|
104
|
-
*/
|
|
105
|
-
export function createProfile(profile: string, config: ProfileConfig = {}): boolean {
|
|
106
|
-
ensureConfigDir();
|
|
107
|
-
|
|
108
|
-
if (profileExists(profile)) {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Validate profile name
|
|
113
|
-
if (!/^[a-zA-Z0-9_-]+$/.test(profile)) {
|
|
114
|
-
throw new Error('Profile name can only contain letters, numbers, hyphens, and underscores');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
writeFileSync(getProfilePath(profile), JSON.stringify(config, null, 2));
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Delete a profile
|
|
123
|
-
*/
|
|
124
|
-
export function deleteProfile(profile: string): boolean {
|
|
125
|
-
if (profile === DEFAULT_PROFILE) {
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (!profileExists(profile)) {
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Switch to default if deleting current profile
|
|
134
|
-
if (getCurrentProfile() === profile) {
|
|
135
|
-
setCurrentProfile(DEFAULT_PROFILE);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
rmSync(getProfilePath(profile));
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Load profile config
|
|
144
|
-
*/
|
|
145
|
-
export function loadProfile(profile?: string): ProfileConfig {
|
|
146
|
-
ensureConfigDir();
|
|
147
|
-
const profileName = profile || getCurrentProfile();
|
|
148
|
-
const profilePath = getProfilePath(profileName);
|
|
149
|
-
|
|
150
|
-
if (!existsSync(profilePath)) {
|
|
151
|
-
return {};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
return JSON.parse(readFileSync(profilePath, 'utf-8'));
|
|
156
|
-
} catch {
|
|
157
|
-
return {};
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Save profile config
|
|
163
|
-
*/
|
|
164
|
-
export function saveProfile(config: ProfileConfig, profile?: string): void {
|
|
165
|
-
ensureConfigDir();
|
|
166
|
-
const profileName = profile || getCurrentProfile();
|
|
167
|
-
writeFileSync(getProfilePath(profileName), JSON.stringify(config, null, 2));
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// ============================================
|
|
171
|
-
// Browser Use Credentials Management
|
|
172
|
-
// ============================================
|
|
173
|
-
|
|
174
|
-
export function getApiKey(): string | undefined {
|
|
175
|
-
return process.env.BROWSER_USE_API_KEY || loadProfile().apiKey;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export function setApiKey(apiKey: string): void {
|
|
179
|
-
const config = loadProfile();
|
|
180
|
-
config.apiKey = apiKey;
|
|
181
|
-
saveProfile(config);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
export function getBaseUrl(): string {
|
|
185
|
-
return process.env.BROWSER_USE_BASE_URL || loadProfile().baseUrl || 'https://api.browser-use.com/api/v2';
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export function setBaseUrl(baseUrl: string): void {
|
|
189
|
-
const config = loadProfile();
|
|
190
|
-
config.baseUrl = baseUrl;
|
|
191
|
-
saveProfile(config);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// ============================================
|
|
195
|
-
// Utility Functions
|
|
196
|
-
// ============================================
|
|
197
|
-
|
|
198
|
-
export function clearConfig(): void {
|
|
199
|
-
saveProfile({});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export function getConfigDir(): string {
|
|
203
|
-
return CONFIG_DIR;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export function getActiveProfileName(): string {
|
|
207
|
-
return getCurrentProfile();
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export function hasApiKey(): boolean {
|
|
211
|
-
return !!getApiKey();
|
|
212
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
export type OutputFormat = 'json' | 'table' | 'pretty';
|
|
4
|
-
|
|
5
|
-
export function formatOutput(data: unknown, format: OutputFormat = 'pretty'): string {
|
|
6
|
-
switch (format) {
|
|
7
|
-
case 'json':
|
|
8
|
-
return JSON.stringify(data, null, 2);
|
|
9
|
-
case 'table':
|
|
10
|
-
return formatAsTable(data);
|
|
11
|
-
case 'pretty':
|
|
12
|
-
default:
|
|
13
|
-
return formatPretty(data);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function formatAsTable(data: unknown): string {
|
|
18
|
-
if (!Array.isArray(data)) {
|
|
19
|
-
data = [data];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const items = data as Record<string, unknown>[];
|
|
23
|
-
if (items.length === 0) {
|
|
24
|
-
return 'No data';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const firstItem = items[0];
|
|
28
|
-
if (!firstItem || typeof firstItem !== 'object') {
|
|
29
|
-
return 'No data';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const keys = Object.keys(firstItem);
|
|
33
|
-
const colWidths = keys.map(key => {
|
|
34
|
-
const maxValue = Math.max(
|
|
35
|
-
key.length,
|
|
36
|
-
...items.map(item => String(item[key] ?? '').length)
|
|
37
|
-
);
|
|
38
|
-
return Math.min(maxValue, 40);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const header = keys.map((key, i) => key.padEnd(colWidths[i] ?? 10)).join(' | ');
|
|
42
|
-
const separator = colWidths.map(w => '-'.repeat(w)).join('-+-');
|
|
43
|
-
|
|
44
|
-
const rows = items.map(item =>
|
|
45
|
-
keys.map((key, i) => {
|
|
46
|
-
const value = String(item[key] ?? '');
|
|
47
|
-
const width = colWidths[i] ?? 10;
|
|
48
|
-
return value.length > width
|
|
49
|
-
? value.substring(0, width - 3) + '...'
|
|
50
|
-
: value.padEnd(width);
|
|
51
|
-
}).join(' | ')
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
return [header, separator, ...rows].join('\n');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function formatPretty(data: unknown): string {
|
|
58
|
-
if (Array.isArray(data)) {
|
|
59
|
-
return data.map((item, i) => `${chalk.cyan(`[${i + 1}]`)} ${formatPrettyItem(item)}`).join('\n\n');
|
|
60
|
-
}
|
|
61
|
-
return formatPrettyItem(data);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function formatPrettyItem(item: unknown, indent = 0): string {
|
|
65
|
-
if (item === null || item === undefined) {
|
|
66
|
-
return chalk.gray('null');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (typeof item !== 'object') {
|
|
70
|
-
return String(item);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const spaces = ' '.repeat(indent);
|
|
74
|
-
const entries = Object.entries(item as Record<string, unknown>);
|
|
75
|
-
|
|
76
|
-
return entries
|
|
77
|
-
.map(([key, value]) => {
|
|
78
|
-
if (Array.isArray(value)) {
|
|
79
|
-
if (value.length === 0) {
|
|
80
|
-
return `${spaces}${chalk.blue(key)}: ${chalk.gray('[]')}`;
|
|
81
|
-
}
|
|
82
|
-
if (typeof value[0] === 'object') {
|
|
83
|
-
return `${spaces}${chalk.blue(key)}:\n${value.map(v => formatPrettyItem(v, indent + 1)).join('\n')}`;
|
|
84
|
-
}
|
|
85
|
-
return `${spaces}${chalk.blue(key)}: ${value.join(', ')}`;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (typeof value === 'object' && value !== null) {
|
|
89
|
-
return `${spaces}${chalk.blue(key)}:\n${formatPrettyItem(value, indent + 1)}`;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return `${spaces}${chalk.blue(key)}: ${chalk.white(String(value))}`;
|
|
93
|
-
})
|
|
94
|
-
.join('\n');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function success(message: string): void {
|
|
98
|
-
console.log(chalk.green('✓'), message);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export function error(message: string): void {
|
|
102
|
-
console.error(chalk.red('✗'), message);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function warn(message: string): void {
|
|
106
|
-
console.warn(chalk.yellow('⚠'), message);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export function info(message: string): void {
|
|
110
|
-
console.log(chalk.blue('ℹ'), message);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function heading(message: string): void {
|
|
114
|
-
console.log(chalk.bold.cyan(`\n${message}\n`));
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function print(data: unknown, format: OutputFormat = 'pretty'): void {
|
|
118
|
-
console.log(formatOutput(data, format));
|
|
119
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"strict": true,
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
"declaration": true,
|
|
10
|
-
"outDir": "./dist",
|
|
11
|
-
"rootDir": "./src",
|
|
12
|
-
"types": ["bun-types"]
|
|
13
|
-
},
|
|
14
|
-
"include": ["src/**/*"],
|
|
15
|
-
"exclude": ["node_modules", "dist", "bin"]
|
|
16
|
-
}
|