@morphllm/morphsdk 0.2.93 → 0.2.94

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 (86) hide show
  1. package/dist/{chunk-IJ54DTJ3.js → chunk-4WO7PJNT.js} +11 -11
  2. package/dist/{chunk-EYGBUH2R.js → chunk-AV6YV2MH.js} +2 -2
  3. package/dist/{chunk-LMUZ3NGC.js → chunk-BVVDDTI7.js} +2 -2
  4. package/dist/chunk-ESRZJRTQ.js +359 -0
  5. package/dist/chunk-ESRZJRTQ.js.map +1 -0
  6. package/dist/{chunk-GU6DACME.js → chunk-FIA6LBW2.js} +2 -2
  7. package/dist/{chunk-4WLGDYWQ.js → chunk-FMWNVTJJ.js} +2 -2
  8. package/dist/{chunk-PBLPZ6AU.js → chunk-IH3KN4AT.js} +2 -2
  9. package/dist/{chunk-MIIJWDOQ.js → chunk-M7GFXRKL.js} +13 -3
  10. package/dist/chunk-M7GFXRKL.js.map +1 -0
  11. package/dist/{chunk-4KMBU6T3.js → chunk-R7WN43L2.js} +4 -4
  12. package/dist/{chunk-PUGIOVSP.js → chunk-TXYCM4NP.js} +2 -2
  13. package/dist/chunk-UJ7LVT5G.js +177 -0
  14. package/dist/chunk-UJ7LVT5G.js.map +1 -0
  15. package/dist/{chunk-FNLNDMIX.js → chunk-WSQMWVSD.js} +2 -2
  16. package/dist/chunk-YJ354BA2.js +46 -0
  17. package/dist/chunk-YJ354BA2.js.map +1 -0
  18. package/dist/client.cjs +546 -4
  19. package/dist/client.cjs.map +1 -1
  20. package/dist/client.d.ts +2 -0
  21. package/dist/client.js +12 -9
  22. package/dist/index.cjs +546 -4
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.js +12 -9
  26. package/dist/tools/browser/anthropic.cjs +5 -1
  27. package/dist/tools/browser/anthropic.cjs.map +1 -1
  28. package/dist/tools/browser/anthropic.js +5 -2
  29. package/dist/tools/browser/core.cjs +544 -2
  30. package/dist/tools/browser/core.cjs.map +1 -1
  31. package/dist/tools/browser/core.d.ts +6 -0
  32. package/dist/tools/browser/core.js +4 -1
  33. package/dist/tools/browser/errors.cjs +208 -0
  34. package/dist/tools/browser/errors.cjs.map +1 -0
  35. package/dist/tools/browser/errors.d.ts +158 -0
  36. package/dist/tools/browser/errors.js +22 -0
  37. package/dist/tools/browser/errors.js.map +1 -0
  38. package/dist/tools/browser/index.cjs +562 -2
  39. package/dist/tools/browser/index.cjs.map +1 -1
  40. package/dist/tools/browser/index.d.ts +3 -0
  41. package/dist/tools/browser/index.js +27 -4
  42. package/dist/tools/browser/index.js.map +1 -1
  43. package/dist/tools/browser/openai.cjs +5 -1
  44. package/dist/tools/browser/openai.cjs.map +1 -1
  45. package/dist/tools/browser/openai.js +5 -2
  46. package/dist/tools/browser/profiles/core.cjs +639 -0
  47. package/dist/tools/browser/profiles/core.cjs.map +1 -0
  48. package/dist/tools/browser/profiles/core.d.ts +179 -0
  49. package/dist/tools/browser/profiles/core.js +27 -0
  50. package/dist/tools/browser/profiles/core.js.map +1 -0
  51. package/dist/tools/browser/profiles/index.cjs +639 -0
  52. package/dist/tools/browser/profiles/index.cjs.map +1 -0
  53. package/dist/tools/browser/profiles/index.d.ts +4 -0
  54. package/dist/tools/browser/profiles/index.js +27 -0
  55. package/dist/tools/browser/profiles/index.js.map +1 -0
  56. package/dist/tools/browser/profiles/types.cjs +74 -0
  57. package/dist/tools/browser/profiles/types.cjs.map +1 -0
  58. package/dist/tools/browser/profiles/types.d.ts +176 -0
  59. package/dist/tools/browser/profiles/types.js +16 -0
  60. package/dist/tools/browser/profiles/types.js.map +1 -0
  61. package/dist/tools/browser/types.cjs.map +1 -1
  62. package/dist/tools/browser/types.d.ts +2 -0
  63. package/dist/tools/browser/vercel.cjs +5 -1
  64. package/dist/tools/browser/vercel.cjs.map +1 -1
  65. package/dist/tools/browser/vercel.js +5 -2
  66. package/dist/tools/fastapply/index.js +3 -3
  67. package/dist/tools/index.js +3 -3
  68. package/dist/tools/warp_grep/anthropic.js +4 -4
  69. package/dist/tools/warp_grep/client.js +3 -3
  70. package/dist/tools/warp_grep/gemini.js +3 -3
  71. package/dist/tools/warp_grep/harness.js +2 -2
  72. package/dist/tools/warp_grep/index.js +3 -3
  73. package/dist/tools/warp_grep/openai.js +4 -4
  74. package/dist/tools/warp_grep/providers/local.js +2 -2
  75. package/dist/tools/warp_grep/vercel.js +4 -4
  76. package/package.json +7 -2
  77. package/dist/chunk-MIIJWDOQ.js.map +0 -1
  78. /package/dist/{chunk-IJ54DTJ3.js.map → chunk-4WO7PJNT.js.map} +0 -0
  79. /package/dist/{chunk-EYGBUH2R.js.map → chunk-AV6YV2MH.js.map} +0 -0
  80. /package/dist/{chunk-LMUZ3NGC.js.map → chunk-BVVDDTI7.js.map} +0 -0
  81. /package/dist/{chunk-GU6DACME.js.map → chunk-FIA6LBW2.js.map} +0 -0
  82. /package/dist/{chunk-4WLGDYWQ.js.map → chunk-FMWNVTJJ.js.map} +0 -0
  83. /package/dist/{chunk-PBLPZ6AU.js.map → chunk-IH3KN4AT.js.map} +0 -0
  84. /package/dist/{chunk-4KMBU6T3.js.map → chunk-R7WN43L2.js.map} +0 -0
  85. /package/dist/{chunk-PUGIOVSP.js.map → chunk-TXYCM4NP.js.map} +0 -0
  86. /package/dist/{chunk-FNLNDMIX.js.map → chunk-WSQMWVSD.js.map} +0 -0
@@ -1,15 +1,15 @@
1
+ import {
2
+ createWarpGrepTool as createWarpGrepTool3
3
+ } from "./chunk-FIA6LBW2.js";
1
4
  import {
2
5
  createWarpGrepTool as createWarpGrepTool2
3
- } from "./chunk-PBLPZ6AU.js";
6
+ } from "./chunk-IH3KN4AT.js";
4
7
  import {
5
8
  createWarpGrepTool
6
- } from "./chunk-LMUZ3NGC.js";
7
- import {
8
- createWarpGrepTool as createWarpGrepTool3
9
- } from "./chunk-GU6DACME.js";
9
+ } from "./chunk-BVVDDTI7.js";
10
10
  import {
11
11
  WarpGrepClient
12
- } from "./chunk-PUGIOVSP.js";
12
+ } from "./chunk-TXYCM4NP.js";
13
13
  import {
14
14
  createCodebaseSearchTool as createCodebaseSearchTool3
15
15
  } from "./chunk-UBX7QYBD.js";
@@ -22,21 +22,21 @@ import {
22
22
  import {
23
23
  CodebaseSearchClient
24
24
  } from "./chunk-WM77HRKO.js";
25
+ import {
26
+ createEditFileTool as createEditFileTool3
27
+ } from "./chunk-QZNGKOCZ.js";
25
28
  import {
26
29
  createEditFileTool as createEditFileTool2
27
30
  } from "./chunk-IUG2FHNN.js";
28
31
  import {
29
32
  createEditFileTool
30
33
  } from "./chunk-5QIWYEHJ.js";
31
- import {
32
- createEditFileTool as createEditFileTool3
33
- } from "./chunk-QZNGKOCZ.js";
34
34
  import {
35
35
  FastApplyClient
36
36
  } from "./chunk-CKTA4AXM.js";
37
37
  import {
38
38
  BrowserClient
39
- } from "./chunk-MIIJWDOQ.js";
39
+ } from "./chunk-M7GFXRKL.js";
40
40
  import {
41
41
  MorphGit
42
42
  } from "./chunk-VJU3BRET.js";
@@ -280,4 +280,4 @@ export {
280
280
  VercelToolFactory,
281
281
  MorphClient
282
282
  };
283
- //# sourceMappingURL=chunk-IJ54DTJ3.js.map
283
+ //# sourceMappingURL=chunk-4WO7PJNT.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EI4UKP24.js";
4
4
  import {
5
5
  executeBrowserTask
6
- } from "./chunk-MIIJWDOQ.js";
6
+ } from "./chunk-M7GFXRKL.js";
7
7
  import {
8
8
  __export
9
9
  } from "./chunk-PZ5AY32C.js";
@@ -54,4 +54,4 @@ export {
54
54
  browserTool,
55
55
  vercel_exports
56
56
  };
57
- //# sourceMappingURL=chunk-EYGBUH2R.js.map
57
+ //# sourceMappingURL=chunk-AV6YV2MH.js.map
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  executeToolCall,
7
7
  formatResult
8
- } from "./chunk-PUGIOVSP.js";
8
+ } from "./chunk-TXYCM4NP.js";
9
9
  import {
10
10
  getSystemPrompt
11
11
  } from "./chunk-FMLHRJDF.js";
@@ -58,4 +58,4 @@ export {
58
58
  createWarpGrepTool,
59
59
  openai_default
60
60
  };
61
- //# sourceMappingURL=chunk-LMUZ3NGC.js.map
61
+ //# sourceMappingURL=chunk-BVVDDTI7.js.map
@@ -0,0 +1,359 @@
1
+ import {
2
+ transformCreateInput,
3
+ transformProfile,
4
+ transformSaveInput,
5
+ transformSession,
6
+ transformStateResponse
7
+ } from "./chunk-YJ354BA2.js";
8
+ import {
9
+ MorphAuthenticationError,
10
+ MorphValidationError,
11
+ parseAPIError
12
+ } from "./chunk-UJ7LVT5G.js";
13
+ import {
14
+ fetchWithRetry
15
+ } from "./chunk-4VWJFZVS.js";
16
+
17
+ // tools/browser/profiles/core.ts
18
+ var DEFAULT_API_URL = process.env.MORPH_ENVIRONMENT === "DEV" ? "http://localhost:8000" : "https://browser.morphllm.com";
19
+ var ProfilesClient = class {
20
+ config;
21
+ constructor(config) {
22
+ this.config = config;
23
+ }
24
+ /**
25
+ * Create a new browser profile.
26
+ *
27
+ * @param input - Profile creation parameters
28
+ * @returns The created profile
29
+ * @throws {MorphValidationError} If input validation fails
30
+ * @throws {MorphProfileLimitError} If profile limit is exceeded
31
+ * @throws {MorphAuthenticationError} If API key is missing or invalid
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const profile = await morph.browser.profiles.createProfile({
36
+ * name: 'LinkedIn Production',
37
+ * repoId: 'repo-uuid-here'
38
+ * });
39
+ * ```
40
+ */
41
+ async createProfile(input) {
42
+ return createProfile(input, this.config);
43
+ }
44
+ /**
45
+ * List all profiles for the authenticated user.
46
+ *
47
+ * @param repoId - Optional repository ID to filter by
48
+ * @returns Array of profiles
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * // List all profiles
53
+ * const allProfiles = await morph.browser.profiles.listProfiles();
54
+ *
55
+ * // List profiles for a specific repo
56
+ * const repoProfiles = await morph.browser.profiles.listProfiles('repo-uuid');
57
+ * ```
58
+ */
59
+ async listProfiles(repoId) {
60
+ return listProfiles(this.config, repoId);
61
+ }
62
+ /**
63
+ * Get a profile by ID with convenience methods.
64
+ *
65
+ * @param id - Profile ID
66
+ * @returns Profile with attached methods
67
+ * @throws {MorphNotFoundError} If profile is not found
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const profile = await morph.browser.profiles.getProfile('profile-id');
72
+ * const state = await profile.getState();
73
+ * await profile.delete();
74
+ * ```
75
+ */
76
+ async getProfile(id) {
77
+ return getProfile(id, this.config);
78
+ }
79
+ /**
80
+ * Update a profile's name.
81
+ *
82
+ * @param id - Profile ID
83
+ * @param input - Update parameters
84
+ * @returns Updated profile
85
+ */
86
+ async updateProfile(id, input) {
87
+ return updateProfile(id, input, this.config);
88
+ }
89
+ /**
90
+ * Delete a profile.
91
+ *
92
+ * @param id - Profile ID
93
+ * @throws {MorphNotFoundError} If profile is not found
94
+ */
95
+ async deleteProfile(id) {
96
+ return deleteProfile(id, this.config);
97
+ }
98
+ /**
99
+ * Start a browser session for profile setup.
100
+ *
101
+ * Returns a live URL where the user can sign into accounts.
102
+ * After signing in, call `saveSession` to persist the state.
103
+ *
104
+ * @param input - Optional session parameters
105
+ * @returns Session with debug URL
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const session = await morph.browser.profiles.startSession();
110
+ * console.log('Sign in at:', session.debugUrl);
111
+ * // Open debugUrl in browser, user signs in...
112
+ * await morph.browser.profiles.saveSession(session.sessionId, profile.id);
113
+ * ```
114
+ */
115
+ async startSession(input) {
116
+ return startProfileSession(this.config, input);
117
+ }
118
+ /**
119
+ * Save browser state from a session to a profile.
120
+ *
121
+ * Call this after the user is done signing into accounts.
122
+ * Extracts cookies, localStorage, and sessionStorage.
123
+ *
124
+ * @param sessionId - Browser session ID from startSession
125
+ * @param profileId - Profile ID to save state to
126
+ * @returns Updated profile with cookie domains
127
+ */
128
+ async saveSession(sessionId, profileId) {
129
+ return saveProfileSession({ sessionId, profileId }, this.config);
130
+ }
131
+ /**
132
+ * Get the presigned URL for a profile's state.
133
+ *
134
+ * Use this to download the raw state JSON for debugging
135
+ * or to restore state manually.
136
+ *
137
+ * @param profileId - Profile ID
138
+ * @returns State URL with expiry information
139
+ */
140
+ async getProfileState(profileId) {
141
+ return getProfileState(profileId, this.config);
142
+ }
143
+ };
144
+ function validateCreateInput(input) {
145
+ if (!input.name || typeof input.name !== "string") {
146
+ throw new MorphValidationError("name is required", "name");
147
+ }
148
+ const trimmedName = input.name.trim();
149
+ if (trimmedName.length === 0) {
150
+ throw new MorphValidationError("name cannot be empty", "name");
151
+ }
152
+ if (trimmedName.length > 100) {
153
+ throw new MorphValidationError("name must be 100 characters or less", "name");
154
+ }
155
+ if (!input.repoId || typeof input.repoId !== "string") {
156
+ throw new MorphValidationError("repoId is required", "repoId");
157
+ }
158
+ if (input.repoId.trim().length === 0) {
159
+ throw new MorphValidationError("repoId cannot be empty", "repoId");
160
+ }
161
+ }
162
+ function validateId(id, fieldName) {
163
+ if (!id || typeof id !== "string") {
164
+ throw new MorphValidationError(`${fieldName} is required`, fieldName);
165
+ }
166
+ if (id.trim().length === 0) {
167
+ throw new MorphValidationError(`${fieldName} cannot be empty`, fieldName);
168
+ }
169
+ }
170
+ async function createProfile(input, config = {}) {
171
+ validateCreateInput(input);
172
+ const apiUrl = config.apiUrl || DEFAULT_API_URL;
173
+ const headers = buildHeaders(config);
174
+ const response = await fetchWithRetry(
175
+ `${apiUrl}/profiles`,
176
+ {
177
+ method: "POST",
178
+ headers,
179
+ body: JSON.stringify(transformCreateInput(input))
180
+ },
181
+ config.retryConfig
182
+ );
183
+ if (!response.ok) {
184
+ const errorText = await response.text().catch(() => response.statusText);
185
+ const requestId = response.headers.get("x-request-id") || void 0;
186
+ throw parseAPIError(response.status, errorText, requestId);
187
+ }
188
+ const apiProfile = await response.json();
189
+ return transformProfile(apiProfile);
190
+ }
191
+ async function listProfiles(config = {}, repoId) {
192
+ const apiUrl = config.apiUrl || DEFAULT_API_URL;
193
+ const headers = buildHeaders(config);
194
+ const url = repoId ? `${apiUrl}/profiles?repo_id=${encodeURIComponent(repoId)}` : `${apiUrl}/profiles`;
195
+ const response = await fetchWithRetry(
196
+ url,
197
+ { method: "GET", headers },
198
+ config.retryConfig
199
+ );
200
+ if (!response.ok) {
201
+ const errorText = await response.text().catch(() => response.statusText);
202
+ const requestId = response.headers.get("x-request-id") || void 0;
203
+ throw parseAPIError(response.status, errorText, requestId);
204
+ }
205
+ const data = await response.json();
206
+ return data.profiles.map(transformProfile);
207
+ }
208
+ async function getProfile(id, config = {}) {
209
+ validateId(id, "id");
210
+ const apiUrl = config.apiUrl || DEFAULT_API_URL;
211
+ const headers = buildHeaders(config);
212
+ const response = await fetchWithRetry(
213
+ `${apiUrl}/profiles/${encodeURIComponent(id)}`,
214
+ { method: "GET", headers },
215
+ config.retryConfig
216
+ );
217
+ if (!response.ok) {
218
+ const errorText = await response.text().catch(() => response.statusText);
219
+ const requestId = response.headers.get("x-request-id") || void 0;
220
+ throw parseAPIError(response.status, errorText, requestId);
221
+ }
222
+ const apiProfile = await response.json();
223
+ const profile = transformProfile(apiProfile);
224
+ return {
225
+ ...profile,
226
+ getState: () => getProfileState(id, config),
227
+ delete: () => deleteProfile(id, config)
228
+ };
229
+ }
230
+ async function updateProfile(id, input, config = {}) {
231
+ validateId(id, "id");
232
+ if (input.name !== void 0) {
233
+ if (typeof input.name !== "string") {
234
+ throw new MorphValidationError("name must be a string", "name");
235
+ }
236
+ if (input.name.trim().length === 0) {
237
+ throw new MorphValidationError("name cannot be empty", "name");
238
+ }
239
+ if (input.name.length > 100) {
240
+ throw new MorphValidationError("name must be 100 characters or less", "name");
241
+ }
242
+ }
243
+ const apiUrl = config.apiUrl || DEFAULT_API_URL;
244
+ const headers = buildHeaders(config);
245
+ const response = await fetchWithRetry(
246
+ `${apiUrl}/profiles/${encodeURIComponent(id)}`,
247
+ {
248
+ method: "PATCH",
249
+ headers,
250
+ body: JSON.stringify(input)
251
+ },
252
+ config.retryConfig
253
+ );
254
+ if (!response.ok) {
255
+ const errorText = await response.text().catch(() => response.statusText);
256
+ const requestId = response.headers.get("x-request-id") || void 0;
257
+ throw parseAPIError(response.status, errorText, requestId);
258
+ }
259
+ const apiProfile = await response.json();
260
+ return transformProfile(apiProfile);
261
+ }
262
+ async function deleteProfile(id, config = {}) {
263
+ validateId(id, "id");
264
+ const apiUrl = config.apiUrl || DEFAULT_API_URL;
265
+ const headers = buildHeaders(config);
266
+ const response = await fetchWithRetry(
267
+ `${apiUrl}/profiles/${encodeURIComponent(id)}`,
268
+ { method: "DELETE", headers },
269
+ config.retryConfig
270
+ );
271
+ if (!response.ok) {
272
+ const errorText = await response.text().catch(() => response.statusText);
273
+ const requestId = response.headers.get("x-request-id") || void 0;
274
+ throw parseAPIError(response.status, errorText, requestId);
275
+ }
276
+ }
277
+ async function startProfileSession(config = {}, input) {
278
+ if (!config.apiKey) {
279
+ throw new MorphAuthenticationError();
280
+ }
281
+ const apiUrl = config.apiUrl || DEFAULT_API_URL;
282
+ const headers = buildHeaders(config);
283
+ const body = input?.profileId ? { profile_id: input.profileId } : {};
284
+ const response = await fetchWithRetry(
285
+ `${apiUrl}/profiles/session/start`,
286
+ {
287
+ method: "POST",
288
+ headers,
289
+ body: JSON.stringify(body)
290
+ },
291
+ config.retryConfig
292
+ );
293
+ if (!response.ok) {
294
+ const errorText = await response.text().catch(() => response.statusText);
295
+ const requestId = response.headers.get("x-request-id") || void 0;
296
+ throw parseAPIError(response.status, errorText, requestId);
297
+ }
298
+ const apiSession = await response.json();
299
+ return transformSession(apiSession);
300
+ }
301
+ async function saveProfileSession(input, config = {}) {
302
+ validateId(input.sessionId, "sessionId");
303
+ validateId(input.profileId, "profileId");
304
+ const apiUrl = config.apiUrl || DEFAULT_API_URL;
305
+ const headers = buildHeaders(config);
306
+ const response = await fetchWithRetry(
307
+ `${apiUrl}/profiles/session/save`,
308
+ {
309
+ method: "POST",
310
+ headers,
311
+ body: JSON.stringify(transformSaveInput(input))
312
+ },
313
+ config.retryConfig
314
+ );
315
+ if (!response.ok) {
316
+ const errorText = await response.text().catch(() => response.statusText);
317
+ const requestId = response.headers.get("x-request-id") || void 0;
318
+ throw parseAPIError(response.status, errorText, requestId);
319
+ }
320
+ const apiProfile = await response.json();
321
+ return transformProfile(apiProfile);
322
+ }
323
+ async function getProfileState(profileId, config = {}) {
324
+ validateId(profileId, "profileId");
325
+ const apiUrl = config.apiUrl || DEFAULT_API_URL;
326
+ const headers = buildHeaders(config);
327
+ const response = await fetchWithRetry(
328
+ `${apiUrl}/profiles/${encodeURIComponent(profileId)}/state`,
329
+ { method: "GET", headers },
330
+ config.retryConfig
331
+ );
332
+ if (!response.ok) {
333
+ const errorText = await response.text().catch(() => response.statusText);
334
+ const requestId = response.headers.get("x-request-id") || void 0;
335
+ throw parseAPIError(response.status, errorText, requestId);
336
+ }
337
+ const apiState = await response.json();
338
+ return transformStateResponse(apiState);
339
+ }
340
+ function buildHeaders(config) {
341
+ const headers = { "Content-Type": "application/json" };
342
+ if (config.apiKey) {
343
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
344
+ }
345
+ return headers;
346
+ }
347
+
348
+ export {
349
+ ProfilesClient,
350
+ createProfile,
351
+ listProfiles,
352
+ getProfile,
353
+ updateProfile,
354
+ deleteProfile,
355
+ startProfileSession,
356
+ saveProfileSession,
357
+ getProfileState
358
+ };
359
+ //# sourceMappingURL=chunk-ESRZJRTQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/browser/profiles/core.ts"],"sourcesContent":["/**\n * ProfilesClient - Manage browser profiles for storing login state.\n *\n * @example\n * ```typescript\n * const morph = new MorphClient({ apiKey: '...' });\n *\n * // Create a profile\n * const profile = await morph.browser.profiles.createProfile({\n * name: 'LinkedIn',\n * repoId: 'repo-uuid'\n * });\n *\n * // Start session for user to sign in\n * const session = await morph.browser.profiles.startSession();\n * console.log('Sign in at:', session.debugUrl);\n *\n * // Save state after user signs in\n * await morph.browser.profiles.saveSession(session.sessionId, profile.id);\n *\n * // Use profile in browser tasks\n * await morph.browser.execute({\n * task: 'Check notifications',\n * url: 'https://linkedin.com',\n * profileId: profile.id\n * });\n * ```\n */\n\nimport { fetchWithRetry } from '../../utils/resilience.js';\nimport type { BrowserConfig } from '../types.js';\nimport {\n MorphValidationError,\n MorphAuthenticationError,\n parseAPIError,\n} from '../errors.js';\nimport type {\n Profile,\n ProfileWithMethods,\n CreateProfileInput,\n UpdateProfileInput,\n ProfileListResponse,\n ProfileSession,\n ProfileSessionInput,\n SaveProfileSessionInput,\n ProfileStateResponse,\n APIProfile,\n APIProfileSession,\n APIProfileStateResponse,\n} from './types.js';\nimport {\n transformProfile,\n transformCreateInput,\n transformSession,\n transformSaveInput,\n transformStateResponse,\n} from './types.js';\n\nconst DEFAULT_API_URL = process.env.MORPH_ENVIRONMENT === 'DEV'\n ? 'http://localhost:8000'\n : 'https://browser.morphllm.com';\n\n/**\n * ProfilesClient class for managing browser profiles.\n *\n * Access via `morph.browser.profiles` on a MorphClient instance.\n */\nexport class ProfilesClient {\n private config: BrowserConfig;\n\n constructor(config: BrowserConfig) {\n this.config = config;\n }\n\n /**\n * Create a new browser profile.\n *\n * @param input - Profile creation parameters\n * @returns The created profile\n * @throws {MorphValidationError} If input validation fails\n * @throws {MorphProfileLimitError} If profile limit is exceeded\n * @throws {MorphAuthenticationError} If API key is missing or invalid\n *\n * @example\n * ```typescript\n * const profile = await morph.browser.profiles.createProfile({\n * name: 'LinkedIn Production',\n * repoId: 'repo-uuid-here'\n * });\n * ```\n */\n async createProfile(input: CreateProfileInput): Promise<Profile> {\n return createProfile(input, this.config);\n }\n\n /**\n * List all profiles for the authenticated user.\n *\n * @param repoId - Optional repository ID to filter by\n * @returns Array of profiles\n *\n * @example\n * ```typescript\n * // List all profiles\n * const allProfiles = await morph.browser.profiles.listProfiles();\n *\n * // List profiles for a specific repo\n * const repoProfiles = await morph.browser.profiles.listProfiles('repo-uuid');\n * ```\n */\n async listProfiles(repoId?: string): Promise<Profile[]> {\n return listProfiles(this.config, repoId);\n }\n\n /**\n * Get a profile by ID with convenience methods.\n *\n * @param id - Profile ID\n * @returns Profile with attached methods\n * @throws {MorphNotFoundError} If profile is not found\n *\n * @example\n * ```typescript\n * const profile = await morph.browser.profiles.getProfile('profile-id');\n * const state = await profile.getState();\n * await profile.delete();\n * ```\n */\n async getProfile(id: string): Promise<ProfileWithMethods> {\n return getProfile(id, this.config);\n }\n\n /**\n * Update a profile's name.\n *\n * @param id - Profile ID\n * @param input - Update parameters\n * @returns Updated profile\n */\n async updateProfile(id: string, input: UpdateProfileInput): Promise<Profile> {\n return updateProfile(id, input, this.config);\n }\n\n /**\n * Delete a profile.\n *\n * @param id - Profile ID\n * @throws {MorphNotFoundError} If profile is not found\n */\n async deleteProfile(id: string): Promise<void> {\n return deleteProfile(id, this.config);\n }\n\n /**\n * Start a browser session for profile setup.\n *\n * Returns a live URL where the user can sign into accounts.\n * After signing in, call `saveSession` to persist the state.\n *\n * @param input - Optional session parameters\n * @returns Session with debug URL\n *\n * @example\n * ```typescript\n * const session = await morph.browser.profiles.startSession();\n * console.log('Sign in at:', session.debugUrl);\n * // Open debugUrl in browser, user signs in...\n * await morph.browser.profiles.saveSession(session.sessionId, profile.id);\n * ```\n */\n async startSession(input?: ProfileSessionInput): Promise<ProfileSession> {\n return startProfileSession(this.config, input);\n }\n\n /**\n * Save browser state from a session to a profile.\n *\n * Call this after the user is done signing into accounts.\n * Extracts cookies, localStorage, and sessionStorage.\n *\n * @param sessionId - Browser session ID from startSession\n * @param profileId - Profile ID to save state to\n * @returns Updated profile with cookie domains\n */\n async saveSession(sessionId: string, profileId: string): Promise<Profile> {\n return saveProfileSession({ sessionId, profileId }, this.config);\n }\n\n /**\n * Get the presigned URL for a profile's state.\n *\n * Use this to download the raw state JSON for debugging\n * or to restore state manually.\n *\n * @param profileId - Profile ID\n * @returns State URL with expiry information\n */\n async getProfileState(profileId: string): Promise<ProfileStateResponse> {\n return getProfileState(profileId, this.config);\n }\n}\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nfunction validateCreateInput(input: CreateProfileInput): void {\n if (!input.name || typeof input.name !== 'string') {\n throw new MorphValidationError('name is required', 'name');\n }\n\n const trimmedName = input.name.trim();\n if (trimmedName.length === 0) {\n throw new MorphValidationError('name cannot be empty', 'name');\n }\n\n if (trimmedName.length > 100) {\n throw new MorphValidationError('name must be 100 characters or less', 'name');\n }\n\n if (!input.repoId || typeof input.repoId !== 'string') {\n throw new MorphValidationError('repoId is required', 'repoId');\n }\n\n if (input.repoId.trim().length === 0) {\n throw new MorphValidationError('repoId cannot be empty', 'repoId');\n }\n}\n\nfunction validateId(id: string, fieldName: string): void {\n if (!id || typeof id !== 'string') {\n throw new MorphValidationError(`${fieldName} is required`, fieldName);\n }\n\n if (id.trim().length === 0) {\n throw new MorphValidationError(`${fieldName} cannot be empty`, fieldName);\n }\n}\n\n// ============================================================================\n// Standalone Functions\n// ============================================================================\n\n/**\n * Create a new browser profile.\n */\nexport async function createProfile(\n input: CreateProfileInput,\n config: BrowserConfig = {}\n): Promise<Profile> {\n validateCreateInput(input);\n\n const apiUrl = config.apiUrl || DEFAULT_API_URL;\n const headers = buildHeaders(config);\n\n const response = await fetchWithRetry(\n `${apiUrl}/profiles`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(transformCreateInput(input)),\n },\n config.retryConfig\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n const requestId = response.headers.get('x-request-id') || undefined;\n throw parseAPIError(response.status, errorText, requestId);\n }\n\n const apiProfile: APIProfile = await response.json();\n return transformProfile(apiProfile);\n}\n\n/**\n * List all profiles for the authenticated user.\n */\nexport async function listProfiles(\n config: BrowserConfig = {},\n repoId?: string\n): Promise<Profile[]> {\n const apiUrl = config.apiUrl || DEFAULT_API_URL;\n const headers = buildHeaders(config);\n\n const url = repoId\n ? `${apiUrl}/profiles?repo_id=${encodeURIComponent(repoId)}`\n : `${apiUrl}/profiles`;\n\n const response = await fetchWithRetry(\n url,\n { method: 'GET', headers },\n config.retryConfig\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n const requestId = response.headers.get('x-request-id') || undefined;\n throw parseAPIError(response.status, errorText, requestId);\n }\n\n const data: { profiles: APIProfile[] } = await response.json();\n return data.profiles.map(transformProfile);\n}\n\n/**\n * Get a profile by ID with convenience methods.\n */\nexport async function getProfile(\n id: string,\n config: BrowserConfig = {}\n): Promise<ProfileWithMethods> {\n validateId(id, 'id');\n\n const apiUrl = config.apiUrl || DEFAULT_API_URL;\n const headers = buildHeaders(config);\n\n const response = await fetchWithRetry(\n `${apiUrl}/profiles/${encodeURIComponent(id)}`,\n { method: 'GET', headers },\n config.retryConfig\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n const requestId = response.headers.get('x-request-id') || undefined;\n throw parseAPIError(response.status, errorText, requestId);\n }\n\n const apiProfile: APIProfile = await response.json();\n const profile = transformProfile(apiProfile);\n\n // Attach convenience methods\n return {\n ...profile,\n getState: () => getProfileState(id, config),\n delete: () => deleteProfile(id, config),\n };\n}\n\n/**\n * Update a profile.\n */\nexport async function updateProfile(\n id: string,\n input: UpdateProfileInput,\n config: BrowserConfig = {}\n): Promise<Profile> {\n validateId(id, 'id');\n\n if (input.name !== undefined) {\n if (typeof input.name !== 'string') {\n throw new MorphValidationError('name must be a string', 'name');\n }\n if (input.name.trim().length === 0) {\n throw new MorphValidationError('name cannot be empty', 'name');\n }\n if (input.name.length > 100) {\n throw new MorphValidationError('name must be 100 characters or less', 'name');\n }\n }\n\n const apiUrl = config.apiUrl || DEFAULT_API_URL;\n const headers = buildHeaders(config);\n\n const response = await fetchWithRetry(\n `${apiUrl}/profiles/${encodeURIComponent(id)}`,\n {\n method: 'PATCH',\n headers,\n body: JSON.stringify(input),\n },\n config.retryConfig\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n const requestId = response.headers.get('x-request-id') || undefined;\n throw parseAPIError(response.status, errorText, requestId);\n }\n\n const apiProfile: APIProfile = await response.json();\n return transformProfile(apiProfile);\n}\n\n/**\n * Delete a profile.\n */\nexport async function deleteProfile(\n id: string,\n config: BrowserConfig = {}\n): Promise<void> {\n validateId(id, 'id');\n\n const apiUrl = config.apiUrl || DEFAULT_API_URL;\n const headers = buildHeaders(config);\n\n const response = await fetchWithRetry(\n `${apiUrl}/profiles/${encodeURIComponent(id)}`,\n { method: 'DELETE', headers },\n config.retryConfig\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n const requestId = response.headers.get('x-request-id') || undefined;\n throw parseAPIError(response.status, errorText, requestId);\n }\n}\n\n/**\n * Start a browser session for profile setup.\n */\nexport async function startProfileSession(\n config: BrowserConfig = {},\n input?: ProfileSessionInput\n): Promise<ProfileSession> {\n if (!config.apiKey) {\n throw new MorphAuthenticationError();\n }\n\n const apiUrl = config.apiUrl || DEFAULT_API_URL;\n const headers = buildHeaders(config);\n\n // Transform input if provided\n const body = input?.profileId\n ? { profile_id: input.profileId }\n : {};\n\n const response = await fetchWithRetry(\n `${apiUrl}/profiles/session/start`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n },\n config.retryConfig\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n const requestId = response.headers.get('x-request-id') || undefined;\n throw parseAPIError(response.status, errorText, requestId);\n }\n\n const apiSession: APIProfileSession = await response.json();\n return transformSession(apiSession);\n}\n\n/**\n * Save browser state from a session to a profile.\n */\nexport async function saveProfileSession(\n input: SaveProfileSessionInput,\n config: BrowserConfig = {}\n): Promise<Profile> {\n validateId(input.sessionId, 'sessionId');\n validateId(input.profileId, 'profileId');\n\n const apiUrl = config.apiUrl || DEFAULT_API_URL;\n const headers = buildHeaders(config);\n\n const response = await fetchWithRetry(\n `${apiUrl}/profiles/session/save`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(transformSaveInput(input)),\n },\n config.retryConfig\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n const requestId = response.headers.get('x-request-id') || undefined;\n throw parseAPIError(response.status, errorText, requestId);\n }\n\n const apiProfile: APIProfile = await response.json();\n return transformProfile(apiProfile);\n}\n\n/**\n * Get the presigned URL for a profile's state.\n */\nexport async function getProfileState(\n profileId: string,\n config: BrowserConfig = {}\n): Promise<ProfileStateResponse> {\n validateId(profileId, 'profileId');\n\n const apiUrl = config.apiUrl || DEFAULT_API_URL;\n const headers = buildHeaders(config);\n\n const response = await fetchWithRetry(\n `${apiUrl}/profiles/${encodeURIComponent(profileId)}/state`,\n { method: 'GET', headers },\n config.retryConfig\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n const requestId = response.headers.get('x-request-id') || undefined;\n throw parseAPIError(response.status, errorText, requestId);\n }\n\n const apiState: APIProfileStateResponse = await response.json();\n return transformStateResponse(apiState);\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction buildHeaders(config: BrowserConfig): Record<string, string> {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (config.apiKey) {\n headers['Authorization'] = `Bearer ${config.apiKey}`;\n }\n return headers;\n}\n"],"mappings":"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","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-KW7OEGZK.js";
4
4
  import {
5
5
  executeToolCall
6
- } from "./chunk-PUGIOVSP.js";
6
+ } from "./chunk-TXYCM4NP.js";
7
7
 
8
8
  // tools/warp_grep/vercel.ts
9
9
  import { tool } from "ai";
@@ -50,4 +50,4 @@ export {
50
50
  createWarpGrepTool,
51
51
  vercel_default
52
52
  };
53
- //# sourceMappingURL=chunk-GU6DACME.js.map
53
+ //# sourceMappingURL=chunk-FIA6LBW2.js.map
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-EI4UKP24.js";
5
5
  import {
6
6
  executeBrowserTask
7
- } from "./chunk-MIIJWDOQ.js";
7
+ } from "./chunk-M7GFXRKL.js";
8
8
  import {
9
9
  __export
10
10
  } from "./chunk-PZ5AY32C.js";
@@ -77,4 +77,4 @@ export {
77
77
  createBrowserTool,
78
78
  anthropic_exports
79
79
  };
80
- //# sourceMappingURL=chunk-4WLGDYWQ.js.map
80
+ //# sourceMappingURL=chunk-FMWNVTJJ.js.map
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  executeToolCall,
7
7
  formatResult
8
- } from "./chunk-PUGIOVSP.js";
8
+ } from "./chunk-TXYCM4NP.js";
9
9
  import {
10
10
  getSystemPrompt
11
11
  } from "./chunk-FMLHRJDF.js";
@@ -50,4 +50,4 @@ export {
50
50
  execute,
51
51
  createWarpGrepTool
52
52
  };
53
- //# sourceMappingURL=chunk-PBLPZ6AU.js.map
53
+ //# sourceMappingURL=chunk-IH3KN4AT.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ ProfilesClient
3
+ } from "./chunk-ESRZJRTQ.js";
1
4
  import {
2
5
  buildEmbedCode,
3
6
  buildLiveIframe,
@@ -18,11 +21,16 @@ var DEFAULT_CONFIG = {
18
21
  };
19
22
  var BrowserClient = class {
20
23
  config;
24
+ /**
25
+ * Profile management - create and manage browser profiles for storing login state.
26
+ */
27
+ profiles;
21
28
  constructor(config = {}) {
22
29
  this.config = {
23
30
  ...DEFAULT_CONFIG,
24
31
  ...config
25
32
  };
33
+ this.profiles = new ProfilesClient(this.config);
26
34
  }
27
35
  /**
28
36
  * Execute a browser automation task
@@ -57,7 +65,8 @@ var BrowserClient = class {
57
65
  video_height: input.video_height ?? input.viewport_height ?? 720,
58
66
  allow_resizing: input.allow_resizing ?? false,
59
67
  structured_output: "schema" in input ? stringifyStructuredOutput(input.schema) : void 0,
60
- auth: input.auth
68
+ auth: input.auth,
69
+ profile_id: input.profile_id
61
70
  })
62
71
  });
63
72
  if (!response.ok) {
@@ -156,7 +165,8 @@ async function executeBrowserTask(input, config = {}) {
156
165
  video_height: input.video_height ?? input.viewport_height ?? 720,
157
166
  allow_resizing: input.allow_resizing ?? false,
158
167
  structured_output: input.structured_output,
159
- auth: input.auth
168
+ auth: input.auth,
169
+ profile_id: input.profile_id
160
170
  })
161
171
  },
162
172
  config.retryConfig
@@ -504,4 +514,4 @@ export {
504
514
  getWebp,
505
515
  checkHealth
506
516
  };
507
- //# sourceMappingURL=chunk-MIIJWDOQ.js.map
517
+ //# sourceMappingURL=chunk-M7GFXRKL.js.map