@parall/sdk 1.32.0 → 1.33.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/src/client.ts CHANGED
@@ -111,6 +111,7 @@ import type {
111
111
  InboxItem,
112
112
  InboxUnreadCountResponse,
113
113
  DispatchEvent,
114
+ DispatchExpireResult,
114
115
  ResolveRefsResponse,
115
116
  BacklinksResponse,
116
117
  BrokenRefsResponse,
@@ -151,7 +152,14 @@ import type {
151
152
  InvokeClipResponse,
152
153
  OnlineClipInfo,
153
154
  RegistryClipInfo,
154
- MachineClipInstall,
155
+ MachineClip,
156
+ BrowserProfile,
157
+ BrowserProfileStatus,
158
+ BrowserProfileConsent,
159
+ CreateBrowserProfileRequest,
160
+ UpdateBrowserProfileRequest,
161
+ BrowserProfileLifecycleRequest,
162
+ GrantBrowserProfileConsentRequest,
155
163
  } from './types.js';
156
164
 
157
165
  export interface ParallClientOptions {
@@ -353,22 +361,7 @@ export class ParallClient {
353
361
 
354
362
  if (!res.ok) {
355
363
  const rawErrorBody = await res.json().catch(() => ({}));
356
- const errorBody =
357
- rawErrorBody !== null && typeof rawErrorBody === 'object'
358
- ? (rawErrorBody as Record<string, unknown>)
359
- : {};
360
- const errorObj =
361
- errorBody?.error && typeof errorBody.error === 'object'
362
- ? (errorBody.error as { message?: string; code?: string })
363
- : undefined;
364
- const errMsg =
365
- errorObj?.message ?? (typeof errorBody?.error === 'string' ? errorBody.error : undefined);
366
- const errCode =
367
- errorObj?.code ?? (typeof errorBody?.code === 'string' ? errorBody.code : undefined);
368
- const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
369
- const { error: _e, code: _c, message: _m, ...extras } = errorBody;
370
- if (Object.keys(extras).length > 0) apiError.extras = extras;
371
- throw apiError;
364
+ throw buildApiError(res, rawErrorBody);
372
365
  }
373
366
 
374
367
  if (res.status === 204) return undefined as T;
@@ -430,22 +423,7 @@ export class ParallClient {
430
423
 
431
424
  if (!res.ok) {
432
425
  const rawErrorBody = await res.json().catch(() => ({}));
433
- const errorBody =
434
- rawErrorBody !== null && typeof rawErrorBody === 'object'
435
- ? (rawErrorBody as Record<string, unknown>)
436
- : {};
437
- const errorObj =
438
- errorBody?.error && typeof errorBody.error === 'object'
439
- ? (errorBody.error as { message?: string; code?: string })
440
- : undefined;
441
- const errMsg =
442
- errorObj?.message ?? (typeof errorBody?.error === 'string' ? errorBody.error : undefined);
443
- const errCode =
444
- errorObj?.code ?? (typeof errorBody?.code === 'string' ? errorBody.code : undefined);
445
- const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
446
- const { error: _e, code: _c, message: _m, ...extras } = errorBody;
447
- if (Object.keys(extras).length > 0) apiError.extras = extras;
448
- throw apiError;
426
+ throw buildApiError(res, rawErrorBody);
449
427
  }
450
428
 
451
429
  if (res.status === 204) return undefined as T;
@@ -791,6 +769,7 @@ export class ParallClient {
791
769
  | 'agent_routing_mode'
792
770
  | 'smart_routing_strategy'
793
771
  | 'smart_routing_agent_id'
772
+ | 'member_invite_policy'
794
773
  >
795
774
  >,
796
775
  ): Promise<Chat> {
@@ -841,8 +820,8 @@ export class ParallClient {
841
820
  return res.data;
842
821
  }
843
822
 
844
- async addChatMember(orgId: string, chatId: string, userId: string, role?: string): Promise<void> {
845
- return this.request('POST', ENDPOINTS.CHAT_MEMBERS(orgId, chatId), { user_id: userId, role });
823
+ async addChatMember(orgId: string, chatId: string, userId: string): Promise<void> {
824
+ return this.request('POST', ENDPOINTS.CHAT_MEMBERS(orgId, chatId), { user_id: userId });
846
825
  }
847
826
 
848
827
  async removeChatMember(orgId: string, chatId: string, userId: string): Promise<void> {
@@ -1332,6 +1311,21 @@ export class ParallClient {
1332
1311
  });
1333
1312
  }
1334
1313
 
1314
+ /**
1315
+ * Toggle whether the machine contributes its local clips as a hub provider
1316
+ * — org-admin-gated (RequireOrgAdmin), like all machine management. See
1317
+ * docs/engineering-design/clip-provider-sharing-design.md.
1318
+ */
1319
+ async patchMachineProviderEnabled(
1320
+ orgId: string,
1321
+ machineId: string,
1322
+ providerEnabled: boolean,
1323
+ ): Promise<Machine> {
1324
+ return this.request('PATCH', ENDPOINTS.MACHINE_PROVIDER_ENABLED(orgId, machineId), {
1325
+ provider_enabled: providerEnabled,
1326
+ });
1327
+ }
1328
+
1335
1329
  /** Get machine-level runtime auth state. */
1336
1330
  async getMachineRuntimeAuth(orgId: string, machineId: string): Promise<MachineRuntimeAuthState> {
1337
1331
  return this.request('GET', ENDPOINTS.MACHINE_RUNTIME_AUTH(orgId, machineId));
@@ -1385,34 +1379,54 @@ export class ParallClient {
1385
1379
  return res.data;
1386
1380
  }
1387
1381
 
1388
- /** `GET /machines/me/clip-installs` — registry clips this machine should
1389
- * install but hasn't yet (durable reconcile, mck_-authed). */
1390
- async listClipInstalls(): Promise<MachineClipInstall[]> {
1391
- const res = await this.request<{ data: MachineClipInstall[] }>(
1382
+ /** `GET /machines/me/clips` — executable Clip definitions assigned to this machine. */
1383
+ async listMachineClips(): Promise<MachineClip[]> {
1384
+ const res = await this.request<{ data: MachineClip[] }>('GET', ENDPOINTS.MACHINES_ME_CLIPS);
1385
+ return res.data;
1386
+ }
1387
+
1388
+ /** `GET /machines/me/browser-profiles` — browser profiles hosted by this machine. */
1389
+ async listMachineBrowserProfiles(): Promise<BrowserProfile[]> {
1390
+ const res = await this.request<{ data: BrowserProfile[] }>(
1392
1391
  'GET',
1393
- ENDPOINTS.MACHINES_ME_CLIP_INSTALLS,
1392
+ ENDPOINTS.MACHINES_ME_BROWSER_PROFILES,
1394
1393
  );
1395
1394
  return res.data;
1396
1395
  }
1397
1396
 
1398
- /** `POST /machines/me/clip-installs/{clipId}/installed` — report a finished install. */
1399
- async reportClipInstall(clipId: string, version?: string): Promise<void> {
1400
- return this.request(
1401
- 'POST',
1402
- ENDPOINTS.MACHINES_ME_CLIP_INSTALL_DONE(clipId),
1403
- version ? { version } : undefined,
1404
- );
1397
+ /** `POST /machines/me/browser-profiles/{profileId}/status` — report runtime status. */
1398
+ async reportBrowserProfileStatus(
1399
+ profileId: string,
1400
+ status: BrowserProfileStatus,
1401
+ errorMsg?: string,
1402
+ ): Promise<void> {
1403
+ await this.request('POST', ENDPOINTS.MACHINES_ME_BROWSER_PROFILE_STATUS(profileId), {
1404
+ status,
1405
+ ...(errorMsg ? { error_msg: errorMsg } : {}),
1406
+ });
1405
1407
  }
1406
1408
 
1407
1409
  /**
1408
- * `POST /machines/me/health` — bump the Machine's `updated_at` to now.
1409
- * Body is intentionally empty; the server ignores any payload. The
1410
- * daemon should call this on a fixed cadence (e.g. every 30s) so an
1411
- * external observer can detect a wedged supervisor.
1410
+ * `POST /machines/me/health` — bump the Machine's `updated_at` to now and
1411
+ * report daemon state. The daemon should call this on a fixed cadence (e.g.
1412
+ * every 30s) so an external observer can detect a wedged supervisor. Both
1413
+ * fields are optional and only persisted when changed:
1414
+ * - `daemonVersion` — the running bundle/launcher version.
1415
+ * - `selfUpdateCapable` — whether the daemon can act on a machine.update
1416
+ * signal (true under a service manager, false for bare `npx` foreground).
1412
1417
  */
1413
- async postMachineHeartbeat(daemonVersion?: string): Promise<void> {
1414
- const body = daemonVersion ? { daemon_version: daemonVersion } : undefined;
1415
- return this.request('POST', ENDPOINTS.MACHINES_ME_HEALTH, body);
1418
+ async postMachineHeartbeat(opts?: {
1419
+ daemonVersion?: string;
1420
+ selfUpdateCapable?: boolean;
1421
+ }): Promise<void> {
1422
+ const body: Record<string, unknown> = {};
1423
+ if (opts?.daemonVersion) body.daemon_version = opts.daemonVersion;
1424
+ if (opts?.selfUpdateCapable !== undefined) body.self_update_capable = opts.selfUpdateCapable;
1425
+ return this.request(
1426
+ 'POST',
1427
+ ENDPOINTS.MACHINES_ME_HEALTH,
1428
+ Object.keys(body).length > 0 ? body : undefined,
1429
+ );
1416
1430
  }
1417
1431
 
1418
1432
  async reportAgentWorkspaceState(
@@ -1613,6 +1627,11 @@ export class ParallClient {
1613
1627
  return this.request('POST', ENDPOINTS.DISPATCH_ACK_BY_ID(orgId, id));
1614
1628
  }
1615
1629
 
1630
+ async expireDispatch(orgId: string, maxAgeHours?: number): Promise<DispatchExpireResult> {
1631
+ const params = maxAgeHours !== undefined ? { max_age_hours: String(maxAgeHours) } : undefined;
1632
+ return this.request('POST', ENDPOINTS.DISPATCH_EXPIRE(orgId), undefined, params);
1633
+ }
1634
+
1616
1635
  async getDispatchByMessages(
1617
1636
  orgId: string,
1618
1637
  chatId: string,
@@ -1657,22 +1676,7 @@ export class ParallClient {
1657
1676
 
1658
1677
  if (!res.ok) {
1659
1678
  const rawErrorBody = await res.json().catch(() => ({}));
1660
- const errorBody =
1661
- rawErrorBody !== null && typeof rawErrorBody === 'object'
1662
- ? (rawErrorBody as Record<string, unknown>)
1663
- : {};
1664
- const errorObj =
1665
- errorBody?.error && typeof errorBody.error === 'object'
1666
- ? (errorBody.error as { message?: string; code?: string })
1667
- : undefined;
1668
- const errMsg =
1669
- errorObj?.message ?? (typeof errorBody?.error === 'string' ? errorBody.error : undefined);
1670
- const errCode =
1671
- errorObj?.code ?? (typeof errorBody?.code === 'string' ? errorBody.code : undefined);
1672
- const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
1673
- const { error: _e, code: _c, message: _m, ...extras } = errorBody;
1674
- if (Object.keys(extras).length > 0) apiError.extras = extras;
1675
- throw apiError;
1679
+ throw buildApiError(res, rawErrorBody);
1676
1680
  }
1677
1681
 
1678
1682
  return res.json() as Promise<PlatformConfigResponse>;
@@ -2530,6 +2534,80 @@ export class ParallClient {
2530
2534
  return resp.data;
2531
2535
  }
2532
2536
 
2537
+ async listBrowserProfiles(orgId: string): Promise<BrowserProfile[]> {
2538
+ const resp = await this.request<{ data: BrowserProfile[] }>(
2539
+ 'GET',
2540
+ ENDPOINTS.BROWSER_PROFILES(orgId),
2541
+ );
2542
+ return resp.data;
2543
+ }
2544
+
2545
+ async createBrowserProfile(
2546
+ orgId: string,
2547
+ req: CreateBrowserProfileRequest,
2548
+ ): Promise<BrowserProfile> {
2549
+ return this.request('POST', ENDPOINTS.BROWSER_PROFILES(orgId), req);
2550
+ }
2551
+
2552
+ async getBrowserProfile(orgId: string, profileId: string): Promise<BrowserProfile> {
2553
+ return this.request('GET', ENDPOINTS.BROWSER_PROFILE(orgId, profileId));
2554
+ }
2555
+
2556
+ async updateBrowserProfile(
2557
+ orgId: string,
2558
+ profileId: string,
2559
+ req: UpdateBrowserProfileRequest,
2560
+ ): Promise<BrowserProfile> {
2561
+ return this.request('PATCH', ENDPOINTS.BROWSER_PROFILE(orgId, profileId), req);
2562
+ }
2563
+
2564
+ async deleteBrowserProfile(orgId: string, profileId: string): Promise<void> {
2565
+ await this.request('DELETE', ENDPOINTS.BROWSER_PROFILE(orgId, profileId));
2566
+ }
2567
+
2568
+ async openBrowserProfile(
2569
+ orgId: string,
2570
+ profileId: string,
2571
+ req: BrowserProfileLifecycleRequest = {},
2572
+ ): Promise<BrowserProfile> {
2573
+ return this.request('POST', ENDPOINTS.BROWSER_PROFILE_OPEN(orgId, profileId), req);
2574
+ }
2575
+
2576
+ async stopBrowserProfile(orgId: string, profileId: string): Promise<BrowserProfile> {
2577
+ return this.request('POST', ENDPOINTS.BROWSER_PROFILE_STOP(orgId, profileId), {});
2578
+ }
2579
+
2580
+ async resetBrowserProfile(orgId: string, profileId: string): Promise<BrowserProfile> {
2581
+ return this.request('POST', ENDPOINTS.BROWSER_PROFILE_RESET(orgId, profileId));
2582
+ }
2583
+
2584
+ async listBrowserProfileConsents(
2585
+ orgId: string,
2586
+ profileId: string,
2587
+ ): Promise<BrowserProfileConsent[]> {
2588
+ const resp = await this.request<{ data: BrowserProfileConsent[] }>(
2589
+ 'GET',
2590
+ ENDPOINTS.BROWSER_PROFILE_CONSENTS(orgId, profileId),
2591
+ );
2592
+ return resp.data;
2593
+ }
2594
+
2595
+ async grantBrowserProfileConsent(
2596
+ orgId: string,
2597
+ profileId: string,
2598
+ req: GrantBrowserProfileConsentRequest,
2599
+ ): Promise<BrowserProfileConsent> {
2600
+ return this.request('POST', ENDPOINTS.BROWSER_PROFILE_CONSENTS(orgId, profileId), req);
2601
+ }
2602
+
2603
+ async revokeBrowserProfileConsent(
2604
+ orgId: string,
2605
+ profileId: string,
2606
+ clipId: string,
2607
+ ): Promise<void> {
2608
+ await this.request('DELETE', ENDPOINTS.BROWSER_PROFILE_CONSENT(orgId, profileId, clipId));
2609
+ }
2610
+
2533
2611
  async listRegistryClips(q?: string): Promise<RegistryClipInfo[]> {
2534
2612
  const url = ENDPOINTS.CLIP_REGISTRY() + (q ? `?q=${encodeURIComponent(q)}` : '');
2535
2613
  const resp = await this.request<{ data: RegistryClipInfo[] }>('GET', url);
@@ -2547,6 +2625,12 @@ function normalizeWikiChangeset(changeset: WikiChangeset): WikiChangeset {
2547
2625
 
2548
2626
  export class ApiError extends Error {
2549
2627
  extras?: Record<string, unknown>;
2628
+ /** Attempted action (authorization denials) — e.g. "chat.add_member". */
2629
+ action?: string;
2630
+ /** Target resource URI that was evaluated — e.g. "prll://cht_…". */
2631
+ resourceUri?: string;
2632
+ /** Whether the action is approval-executable (PERMISSION_DENIED only). */
2633
+ approvable?: boolean;
2550
2634
 
2551
2635
  constructor(
2552
2636
  public status: number,
@@ -2557,3 +2641,57 @@ export class ApiError extends Error {
2557
2641
  this.name = 'ApiError';
2558
2642
  }
2559
2643
  }
2644
+
2645
+ /**
2646
+ * Parse a non-2xx response body into a typed ApiError, losslessly.
2647
+ *
2648
+ * The wire envelope is `{ "error": { code, message, status, action?,
2649
+ * resource_uri?, approvable? } }`. We read message/code/anchors from the
2650
+ * nested `error` object, with a fallback to a legacy flat shape, and never
2651
+ * silently drop to HTTP status text when a real message is present.
2652
+ * See docs/engineering-design/error-contract-design.md
2653
+ */
2654
+ function buildApiError(
2655
+ res: { status: number; statusText: string },
2656
+ rawErrorBody: unknown,
2657
+ ): ApiError {
2658
+ const errorBody =
2659
+ rawErrorBody !== null && typeof rawErrorBody === 'object'
2660
+ ? (rawErrorBody as Record<string, unknown>)
2661
+ : {};
2662
+ const errorObj =
2663
+ errorBody.error && typeof errorBody.error === 'object'
2664
+ ? (errorBody.error as Record<string, unknown>)
2665
+ : undefined;
2666
+ // message/code live under `error`. Tolerate two legacy shapes from
2667
+ // not-yet-migrated services: a flat `{code, message, ...}` (read top-level
2668
+ // message/code) and a bare `{error: "text"}`. Never silently drop to
2669
+ // res.statusText when the server provided a real message.
2670
+ const errMsg =
2671
+ (typeof errorObj?.message === 'string' ? errorObj.message : undefined) ??
2672
+ (typeof errorBody.message === 'string' ? (errorBody.message as string) : undefined) ??
2673
+ (typeof errorBody.error === 'string' ? (errorBody.error as string) : undefined);
2674
+ const errCode =
2675
+ (typeof errorObj?.code === 'string' ? errorObj.code : undefined) ??
2676
+ (typeof errorBody.code === 'string' ? (errorBody.code as string) : undefined);
2677
+ const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
2678
+ // Machine anchors: present under `error`, with a legacy flat fallback.
2679
+ const anchors = errorObj ?? errorBody;
2680
+ if (typeof anchors.action === 'string') apiError.action = anchors.action;
2681
+ if (typeof anchors.resource_uri === 'string') apiError.resourceUri = anchors.resource_uri;
2682
+ if (typeof anchors.approvable === 'boolean') apiError.approvable = anchors.approvable as boolean;
2683
+ // Preserve any other fields — from both the top level and the nested `error`
2684
+ // object — so additive/unknown server fields survive (transparent mirror;
2685
+ // keeps ApiError.extras meaningful for third-party consumers).
2686
+ // The anchors (action/resource_uri/approvable) are exposed as typed fields
2687
+ // above but ALSO kept in `extras` for one compatibility window, so consumers
2688
+ // written against the old `err.extras?.action` shape don't break on upgrade.
2689
+ // Only the envelope-structural keys are excluded.
2690
+ const structural = new Set(['error', 'code', 'message', 'status']);
2691
+ const extras: Record<string, unknown> = {};
2692
+ for (const [k, v] of Object.entries(errorBody)) if (!structural.has(k)) extras[k] = v;
2693
+ if (errorObj)
2694
+ for (const [k, v] of Object.entries(errorObj)) if (!structural.has(k)) extras[k] = v;
2695
+ if (Object.keys(extras).length > 0) apiError.extras = extras;
2696
+ return apiError;
2697
+ }
package/src/constants.ts CHANGED
@@ -415,6 +415,8 @@ export const ENDPOINTS = {
415
415
  `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}/workspace/setup`,
416
416
  MACHINE_LLM_SOURCE: (orgId: string, machineId: string) =>
417
417
  `${API_BASE}/orgs/${orgId}/machines/${machineId}/llm-source`,
418
+ MACHINE_PROVIDER_ENABLED: (orgId: string, machineId: string) =>
419
+ `${API_BASE}/orgs/${orgId}/machines/${machineId}/provider-enabled`,
418
420
  MACHINE_RUNTIME_AUTH: (orgId: string, machineId: string) =>
419
421
  `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth`,
420
422
  MACHINE_KEYS: (orgId: string, machineId: string) =>
@@ -436,9 +438,10 @@ export const ENDPOINTS = {
436
438
  MACHINES_ME: `${API_BASE}/machines/me`,
437
439
  MACHINES_ME_AGENTS: `${API_BASE}/machines/me/agents`,
438
440
  MACHINES_ME_HEALTH: `${API_BASE}/machines/me/health`,
439
- MACHINES_ME_CLIP_INSTALLS: `${API_BASE}/machines/me/clip-installs`,
440
- MACHINES_ME_CLIP_INSTALL_DONE: (clipId: string) =>
441
- `${API_BASE}/machines/me/clip-installs/${clipId}/installed`,
441
+ MACHINES_ME_CLIPS: `${API_BASE}/machines/me/clips`,
442
+ MACHINES_ME_BROWSER_PROFILES: `${API_BASE}/machines/me/browser-profiles`,
443
+ MACHINES_ME_BROWSER_PROFILE_STATUS: (profileId: string) =>
444
+ `${API_BASE}/machines/me/browser-profiles/${profileId}/status`,
442
445
  MACHINES_ME_AGENT_LAUNCH_CREDENTIAL: (agentId: string) =>
443
446
  `${API_BASE}/machines/me/agents/${agentId}/launch-credential`,
444
447
  MACHINES_ME_AGENT_WORKSPACE_STATE: (agentId: string) =>
@@ -593,6 +596,7 @@ export const ENDPOINTS = {
593
596
  DISPATCH_RECEIVED: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/received`,
594
597
  DISPATCH_ACK: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/ack`,
595
598
  DISPATCH_ACK_BY_ID: (orgId: string, id: string) => `${API_BASE}/orgs/${orgId}/dispatch/${id}/ack`,
599
+ DISPATCH_EXPIRE: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/expire`,
596
600
  DISPATCH_BY_MESSAGES: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/by-messages`,
597
601
 
598
602
  // Unread
@@ -644,6 +648,19 @@ export const ENDPOINTS = {
644
648
  `${CLIP_BASE}/orgs/${orgId}/agents/${agentId}/clips/${clipId}`,
645
649
  CLIP_INVOKE: (orgId: string) => `${CLIP_BASE}/orgs/${orgId}/invoke`,
646
650
  CLIP_ONLINE: (orgId: string) => `${CLIP_BASE}/orgs/${orgId}/online`,
651
+ BROWSER_PROFILES: (orgId: string) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles`,
652
+ BROWSER_PROFILE: (orgId: string, profileId: string) =>
653
+ `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}`,
654
+ BROWSER_PROFILE_OPEN: (orgId: string, profileId: string) =>
655
+ `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/open`,
656
+ BROWSER_PROFILE_STOP: (orgId: string, profileId: string) =>
657
+ `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/stop`,
658
+ BROWSER_PROFILE_RESET: (orgId: string, profileId: string) =>
659
+ `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/reset`,
660
+ BROWSER_PROFILE_CONSENTS: (orgId: string, profileId: string) =>
661
+ `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/consents`,
662
+ BROWSER_PROFILE_CONSENT: (orgId: string, profileId: string, clipId: string) =>
663
+ `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/consents/${clipId}`,
647
664
 
648
665
  // Clip registry (global, served by clip-service → Pinix Hub proxy)
649
666
  CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`,
@@ -721,9 +738,10 @@ export const WS_EVENTS = {
721
738
  MACHINE_FILESYSTEM_BROWSE: 'machine.filesystem.browse',
722
739
  MACHINE_UPDATE: 'machine.update',
723
740
  MACHINE_CONFIG_UPDATED: 'machine.config.updated',
724
- MACHINE_CLIP_INSTALL: 'machine.clip.install',
741
+ MACHINE_CLIP_SYNC: 'machine.clip.sync',
742
+ MACHINE_BROWSER_PROFILE_LIFECYCLE: 'machine.browser_profile.lifecycle',
725
743
  AGENT_NEW_SESSION: 'agent.new_session',
726
- CLIP_INSTALLED: 'clip.installed',
744
+ CLIP_CREATED: 'clip.created',
727
745
  CLIP_REMOVED: 'clip.removed',
728
746
  CLIP_UPDATED: 'clip.updated',
729
747
  } as const;