@parall/daemon 1.32.1 → 1.34.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.
Files changed (46) hide show
  1. package/bundle/bb-browser-daemon.js +15628 -0
  2. package/bundle/buildDomTree.js +1501 -0
  3. package/bundle/manifest.json +19 -11
  4. package/bundle/parall-claude-agent.js +185 -25
  5. package/bundle/parall-codex-agent.js +185 -25
  6. package/bundle/parall-daemon.js +4647 -2856
  7. package/bundle/parall-openclaw-agent.js +4 -3
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +8 -2
  10. package/dist/clip-runtime/browser-dependency.d.ts +20 -0
  11. package/dist/clip-runtime/browser-dependency.d.ts.map +1 -0
  12. package/dist/clip-runtime/browser-dependency.js +52 -0
  13. package/dist/clip-runtime/browser-profile-manager.d.ts +70 -0
  14. package/dist/clip-runtime/browser-profile-manager.d.ts.map +1 -0
  15. package/dist/clip-runtime/browser-profile-manager.js +608 -0
  16. package/dist/clip-runtime/clip-provider.d.ts +10 -1
  17. package/dist/clip-runtime/clip-provider.d.ts.map +1 -1
  18. package/dist/clip-runtime/clip-provider.js +63 -21
  19. package/dist/clip-runtime/hub-client.d.ts +79 -0
  20. package/dist/clip-runtime/hub-client.d.ts.map +1 -0
  21. package/dist/clip-runtime/hub-client.js +320 -0
  22. package/dist/clip-runtime/index.d.ts +2 -0
  23. package/dist/clip-runtime/index.d.ts.map +1 -1
  24. package/dist/clip-runtime/index.js +2 -0
  25. package/dist/clip-runtime/ipc.d.ts +6 -0
  26. package/dist/clip-runtime/ipc.d.ts.map +1 -1
  27. package/dist/clip-runtime/manifest.d.ts +16 -8
  28. package/dist/clip-runtime/manifest.d.ts.map +1 -1
  29. package/dist/clip-runtime/manifest.js +13 -0
  30. package/dist/clip-runtime/process-manager.d.ts +55 -3
  31. package/dist/clip-runtime/process-manager.d.ts.map +1 -1
  32. package/dist/clip-runtime/process-manager.js +226 -48
  33. package/dist/clip-runtime/process.d.ts +15 -1
  34. package/dist/clip-runtime/process.d.ts.map +1 -1
  35. package/dist/clip-runtime/process.js +73 -10
  36. package/dist/config.d.ts +9 -0
  37. package/dist/config.d.ts.map +1 -1
  38. package/dist/config.js +12 -0
  39. package/dist/index.js +46 -5
  40. package/dist/runtime-bin-resolver.d.ts +7 -0
  41. package/dist/runtime-bin-resolver.d.ts.map +1 -0
  42. package/dist/runtime-bin-resolver.js +292 -0
  43. package/dist/supervisor.d.ts +53 -4
  44. package/dist/supervisor.d.ts.map +1 -1
  45. package/dist/supervisor.js +449 -117
  46. package/package.json +7 -6
@@ -1,28 +1,36 @@
1
1
  {
2
- "version": "1.32.1",
3
- "built_at": "2026-06-02T14:24:57.505Z",
2
+ "version": "1.34.0",
3
+ "built_at": "2026-06-11T05:16:27.458Z",
4
4
  "min_node_version": "20.0.0",
5
5
  "files": {
6
+ "bb-browser-daemon.js": {
7
+ "sha256": "9d80592a220f94141c57b2729e5a3ae0db8796274924612b38ce066eef54d435",
8
+ "size": 575667
9
+ },
10
+ "buildDomTree.js": {
11
+ "sha256": "485c7f690be7fd517e84cb0281de5e399404ac25630a564d9c1d2aeb2c32e064",
12
+ "size": 52306
13
+ },
6
14
  "package.json": {
7
15
  "sha256": "1239d4d885dcad42201a27ed9324f8f0f760b78700d8db9ced39a511cffe7eae",
8
16
  "size": 18
9
17
  },
10
18
  "parall-claude-agent.js": {
11
- "sha256": "eeb0e9458c678d1edc467c0e1d2dc25a0fc5d6d110ab01a5997a2de4fdce776c",
12
- "size": 1537100
19
+ "sha256": "57d99d5cef75b55e1449f3f830f018ac421720583e5cb5c802727bd679e57095",
20
+ "size": 1544820
13
21
  },
14
22
  "parall-codex-agent.js": {
15
- "sha256": "b9af840b8d787d2725540e432b416a489851d01a969b0eb45a0291dec8d70362",
16
- "size": 1568189
23
+ "sha256": "602db4f45264dd2859011744d5abdb0c115fb1ca74e722d1e4b72270ef7b48fb",
24
+ "size": 1575909
17
25
  },
18
26
  "parall-daemon.js": {
19
- "sha256": "44fcf2c6817a56243bd3391eaf49decd5ce4d8953d0bebb1cfba06a54e5719d7",
20
- "size": 1499163
27
+ "sha256": "2be2ea545d7eb22366f09818e1efeb1dbc0c9c1ee23312a279738e24ad817de6",
28
+ "size": 1566501
21
29
  },
22
30
  "parall-openclaw-agent.js": {
23
- "sha256": "657263cec61e6d26496389ec90ffe0716616a20e082e12c5a17bf6ffd5d1cdd6",
24
- "size": 9727
31
+ "sha256": "505433b4bf3a4b8dbb7b96978d8693d6c48079f4513282ff1ee59a6d13b3eddf",
32
+ "size": 9801
25
33
  }
26
34
  },
27
- "signature": "03XcA+dVTwzforsxVlxsVXHjHJMKJ/yfCHsrddoGTNN7PjK7hdmkT3fRsQqzA3M1hni+7AT++ZGKT4k25Oc6Cg=="
35
+ "signature": "0Q0fz/iU46D4TzErmojSn08ldPZNYgVquvZS730veaqKBmWwqzeG5R1kx7zPF4L8mrh/EQwMEiir77n89NyTBw=="
28
36
  }
@@ -27163,6 +27163,7 @@ var ENDPOINTS = {
27163
27163
  MACHINE_AGENT_DAEMON_CONFIG: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}/daemon-config`,
27164
27164
  MACHINE_AGENT_WORKSPACE_SETUP: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}/workspace/setup`,
27165
27165
  MACHINE_LLM_SOURCE: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/llm-source`,
27166
+ MACHINE_PROVIDER_ENABLED: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/provider-enabled`,
27166
27167
  MACHINE_RUNTIME_AUTH: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth`,
27167
27168
  MACHINE_KEYS: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys`,
27168
27169
  MACHINE_KEY: (orgId, machineId, keyId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys/${keyId}`,
@@ -27176,8 +27177,9 @@ var ENDPOINTS = {
27176
27177
  MACHINES_ME: `${API_BASE}/machines/me`,
27177
27178
  MACHINES_ME_AGENTS: `${API_BASE}/machines/me/agents`,
27178
27179
  MACHINES_ME_HEALTH: `${API_BASE}/machines/me/health`,
27179
- MACHINES_ME_CLIP_INSTALLS: `${API_BASE}/machines/me/clip-installs`,
27180
- MACHINES_ME_CLIP_INSTALL_DONE: (clipId) => `${API_BASE}/machines/me/clip-installs/${clipId}/installed`,
27180
+ MACHINES_ME_CLIPS: `${API_BASE}/machines/me/clips`,
27181
+ MACHINES_ME_BROWSER_PROFILES: `${API_BASE}/machines/me/browser-profiles`,
27182
+ MACHINES_ME_BROWSER_PROFILE_STATUS: (profileId) => `${API_BASE}/machines/me/browser-profiles/${profileId}/status`,
27181
27183
  MACHINES_ME_AGENT_LAUNCH_CREDENTIAL: (agentId) => `${API_BASE}/machines/me/agents/${agentId}/launch-credential`,
27182
27184
  MACHINES_ME_AGENT_WORKSPACE_STATE: (agentId) => `${API_BASE}/machines/me/agents/${agentId}/workspace-state`,
27183
27185
  MACHINES_ME_WS_TICKET: `${API_BASE}/machines/me/ws/ticket`,
@@ -27276,6 +27278,7 @@ var ENDPOINTS = {
27276
27278
  DISPATCH_RECEIVED: (orgId) => `${API_BASE}/orgs/${orgId}/dispatch/received`,
27277
27279
  DISPATCH_ACK: (orgId) => `${API_BASE}/orgs/${orgId}/dispatch/ack`,
27278
27280
  DISPATCH_ACK_BY_ID: (orgId, id) => `${API_BASE}/orgs/${orgId}/dispatch/${id}/ack`,
27281
+ DISPATCH_EXPIRE: (orgId) => `${API_BASE}/orgs/${orgId}/dispatch/expire`,
27279
27282
  DISPATCH_BY_MESSAGES: (orgId) => `${API_BASE}/orgs/${orgId}/dispatch/by-messages`,
27280
27283
  // Unread
27281
27284
  UNREAD: `${API_BASE}/me/unread`,
@@ -27294,6 +27297,8 @@ var ENDPOINTS = {
27294
27297
  PUSH_VAPID_KEY: `${API_BASE}/push/vapid-key`,
27295
27298
  // Notification preferences
27296
27299
  NOTIFICATION_PREFERENCES: `${API_BASE}/notification-preferences`,
27300
+ // Unified search (messages + tasks + wiki, org-scoped)
27301
+ SEARCH: (orgId) => `${API_BASE}/orgs/${orgId}/search`,
27297
27302
  // Feature flags (org-scoped, server-evaluated)
27298
27303
  FEATURE_FLAGS: (orgId) => `${API_BASE}/orgs/${orgId}/feature-flags`,
27299
27304
  // Billing & Credits (org-scoped)
@@ -27314,6 +27319,13 @@ var ENDPOINTS = {
27314
27319
  AGENT_CLIP: (orgId, agentId, clipId) => `${CLIP_BASE}/orgs/${orgId}/agents/${agentId}/clips/${clipId}`,
27315
27320
  CLIP_INVOKE: (orgId) => `${CLIP_BASE}/orgs/${orgId}/invoke`,
27316
27321
  CLIP_ONLINE: (orgId) => `${CLIP_BASE}/orgs/${orgId}/online`,
27322
+ BROWSER_PROFILES: (orgId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles`,
27323
+ BROWSER_PROFILE: (orgId, profileId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}`,
27324
+ BROWSER_PROFILE_OPEN: (orgId, profileId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/open`,
27325
+ BROWSER_PROFILE_STOP: (orgId, profileId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/stop`,
27326
+ BROWSER_PROFILE_RESET: (orgId, profileId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/reset`,
27327
+ BROWSER_PROFILE_CONSENTS: (orgId, profileId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/consents`,
27328
+ BROWSER_PROFILE_CONSENT: (orgId, profileId, clipId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/consents/${clipId}`,
27317
27329
  // Clip registry (global, served by clip-service → Pinix Hub proxy)
27318
27330
  CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`
27319
27331
  };
@@ -27388,9 +27400,10 @@ var WS_EVENTS = {
27388
27400
  MACHINE_FILESYSTEM_BROWSE: "machine.filesystem.browse",
27389
27401
  MACHINE_UPDATE: "machine.update",
27390
27402
  MACHINE_CONFIG_UPDATED: "machine.config.updated",
27391
- MACHINE_CLIP_INSTALL: "machine.clip.install",
27403
+ MACHINE_CLIP_SYNC: "machine.clip.sync",
27404
+ MACHINE_BROWSER_PROFILE_LIFECYCLE: "machine.browser_profile.lifecycle",
27392
27405
  AGENT_NEW_SESSION: "agent.new_session",
27393
- CLIP_INSTALLED: "clip.installed",
27406
+ CLIP_CREATED: "clip.created",
27394
27407
  CLIP_REMOVED: "clip.removed",
27395
27408
  CLIP_UPDATED: "clip.updated"
27396
27409
  };
@@ -27419,8 +27432,13 @@ var ParallClient = class _ParallClient {
27419
27432
  /** Proactive refresh when token expires within this window (seconds). */
27420
27433
  static REFRESH_THRESHOLD_S = 5 * 60;
27421
27434
  static normalizeFetchError(err) {
27422
- if (typeof DOMException !== "undefined" && err instanceof DOMException && (err.name === "TimeoutError" || err.name === "AbortError")) {
27423
- return new ApiError(0, "Request timed out", "REQUEST_TIMEOUT");
27435
+ if (typeof DOMException !== "undefined" && err instanceof DOMException) {
27436
+ if (err.name === "TimeoutError") {
27437
+ return new ApiError(0, "Request timed out", "REQUEST_TIMEOUT");
27438
+ }
27439
+ if (err.name === "AbortError") {
27440
+ return new ApiError(0, "Request aborted", "REQUEST_ABORTED");
27441
+ }
27424
27442
  }
27425
27443
  const apiError = new ApiError(0, "Network request failed", "NETWORK_ERROR");
27426
27444
  if (err instanceof Error && err.message && err.message !== "Failed to fetch") {
@@ -27527,13 +27545,15 @@ var ParallClient = class _ParallClient {
27527
27545
  url += `?${qs}`;
27528
27546
  }
27529
27547
  const headers = this.buildHeaders();
27548
+ const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
27549
+ const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
27530
27550
  let res;
27531
27551
  try {
27532
27552
  res = await fetch(url, {
27533
27553
  method,
27534
27554
  headers,
27535
27555
  body: body ? JSON.stringify(body) : void 0,
27536
- signal: AbortSignal.timeout(opts?.timeoutMs ?? 15e3)
27556
+ signal
27537
27557
  });
27538
27558
  } catch (err) {
27539
27559
  throw _ParallClient.normalizeFetchError(err);
@@ -27843,8 +27863,8 @@ var ParallClient = class _ParallClient {
27843
27863
  const res = await this.request("GET", ENDPOINTS.CHAT_MEMBERS(orgId, chatId));
27844
27864
  return res.data;
27845
27865
  }
27846
- async addChatMember(orgId, chatId, userId, role) {
27847
- return this.request("POST", ENDPOINTS.CHAT_MEMBERS(orgId, chatId), { user_id: userId, role });
27866
+ async addChatMember(orgId, chatId, userId) {
27867
+ return this.request("POST", ENDPOINTS.CHAT_MEMBERS(orgId, chatId), { user_id: userId });
27848
27868
  }
27849
27869
  async removeChatMember(orgId, chatId, userId) {
27850
27870
  return this.request("DELETE", ENDPOINTS.CHAT_MEMBER(orgId, chatId, userId));
@@ -28103,6 +28123,16 @@ var ParallClient = class _ParallClient {
28103
28123
  llm_source: llmSource2
28104
28124
  });
28105
28125
  }
28126
+ /**
28127
+ * Toggle whether the machine contributes its local clips as a hub provider
28128
+ * — org-admin-gated (RequireOrgAdmin), like all machine management. See
28129
+ * docs/engineering-design/clip-provider-sharing-design.md.
28130
+ */
28131
+ async patchMachineProviderEnabled(orgId, machineId, providerEnabled) {
28132
+ return this.request("PATCH", ENDPOINTS.MACHINE_PROVIDER_ENABLED(orgId, machineId), {
28133
+ provider_enabled: providerEnabled
28134
+ });
28135
+ }
28106
28136
  /** Get machine-level runtime auth state. */
28107
28137
  async getMachineRuntimeAuth(orgId, machineId) {
28108
28138
  return this.request("GET", ENDPOINTS.MACHINE_RUNTIME_AUTH(orgId, machineId));
@@ -28136,25 +28166,39 @@ var ParallClient = class _ParallClient {
28136
28166
  const res = await this.request("GET", ENDPOINTS.MACHINES_ME_AGENTS);
28137
28167
  return res.data;
28138
28168
  }
28139
- /** `GET /machines/me/clip-installs` — registry clips this machine should
28140
- * install but hasn't yet (durable reconcile, mck_-authed). */
28141
- async listClipInstalls() {
28142
- const res = await this.request("GET", ENDPOINTS.MACHINES_ME_CLIP_INSTALLS);
28169
+ /** `GET /machines/me/clips` — executable Clip definitions assigned to this machine. */
28170
+ async listMachineClips() {
28171
+ const res = await this.request("GET", ENDPOINTS.MACHINES_ME_CLIPS);
28143
28172
  return res.data;
28144
28173
  }
28145
- /** `POST /machines/me/clip-installs/{clipId}/installed` — report a finished install. */
28146
- async reportClipInstall(clipId, version) {
28147
- return this.request("POST", ENDPOINTS.MACHINES_ME_CLIP_INSTALL_DONE(clipId), version ? { version } : void 0);
28174
+ /** `GET /machines/me/browser-profiles` — browser profiles hosted by this machine. */
28175
+ async listMachineBrowserProfiles() {
28176
+ const res = await this.request("GET", ENDPOINTS.MACHINES_ME_BROWSER_PROFILES);
28177
+ return res.data;
28178
+ }
28179
+ /** `POST /machines/me/browser-profiles/{profileId}/status` — report runtime status. */
28180
+ async reportBrowserProfileStatus(profileId, status, errorMsg) {
28181
+ await this.request("POST", ENDPOINTS.MACHINES_ME_BROWSER_PROFILE_STATUS(profileId), {
28182
+ status,
28183
+ ...errorMsg ? { error_msg: errorMsg } : {}
28184
+ });
28148
28185
  }
28149
28186
  /**
28150
- * `POST /machines/me/health` — bump the Machine's `updated_at` to now.
28151
- * Body is intentionally empty; the server ignores any payload. The
28152
- * daemon should call this on a fixed cadence (e.g. every 30s) so an
28153
- * external observer can detect a wedged supervisor.
28187
+ * `POST /machines/me/health` — bump the Machine's `updated_at` to now and
28188
+ * report daemon state. The daemon should call this on a fixed cadence (e.g.
28189
+ * every 30s) so an external observer can detect a wedged supervisor. Both
28190
+ * fields are optional and only persisted when changed:
28191
+ * - `daemonVersion` — the running bundle/launcher version.
28192
+ * - `selfUpdateCapable` — whether the daemon can act on a machine.update
28193
+ * signal (true under a service manager, false for bare `npx` foreground).
28154
28194
  */
28155
- async postMachineHeartbeat(daemonVersion) {
28156
- const body = daemonVersion ? { daemon_version: daemonVersion } : void 0;
28157
- return this.request("POST", ENDPOINTS.MACHINES_ME_HEALTH, body);
28195
+ async postMachineHeartbeat(opts) {
28196
+ const body = {};
28197
+ if (opts?.daemonVersion)
28198
+ body.daemon_version = opts.daemonVersion;
28199
+ if (opts?.selfUpdateCapable !== void 0)
28200
+ body.self_update_capable = opts.selfUpdateCapable;
28201
+ return this.request("POST", ENDPOINTS.MACHINES_ME_HEALTH, Object.keys(body).length > 0 ? body : void 0);
28158
28202
  }
28159
28203
  async reportAgentWorkspaceState(agentId, state) {
28160
28204
  const res = await this.request("PUT", ENDPOINTS.MACHINES_ME_AGENT_WORKSPACE_STATE(agentId), state);
@@ -28256,6 +28300,10 @@ var ParallClient = class _ParallClient {
28256
28300
  async ackDispatchByID(orgId, id) {
28257
28301
  return this.request("POST", ENDPOINTS.DISPATCH_ACK_BY_ID(orgId, id));
28258
28302
  }
28303
+ async expireDispatch(orgId, maxAgeHours) {
28304
+ const params = maxAgeHours !== void 0 ? { max_age_hours: String(maxAgeHours) } : void 0;
28305
+ return this.request("POST", ENDPOINTS.DISPATCH_EXPIRE(orgId), void 0, params);
28306
+ }
28259
28307
  async getDispatchByMessages(orgId, chatId, messageIds) {
28260
28308
  const params = { chat_id: chatId, message_ids: messageIds.join(",") };
28261
28309
  return this.request("GET", ENDPOINTS.DISPATCH_BY_MESSAGES(orgId), void 0, params);
@@ -28453,6 +28501,9 @@ var ParallClient = class _ParallClient {
28453
28501
  async getWikiNodeSections(orgId, wikiId, params) {
28454
28502
  return this.request("GET", ENDPOINTS.WIKI_NODE_SECTIONS(orgId, wikiId), void 0, params);
28455
28503
  }
28504
+ async search(orgId, params, opts) {
28505
+ return this.request("GET", ENDPOINTS.SEARCH(orgId), void 0, params, false, opts);
28506
+ }
28456
28507
  async searchWiki(orgId, wikiId, params) {
28457
28508
  return this.request("GET", ENDPOINTS.WIKI_SEARCH(orgId, wikiId), void 0, params);
28458
28509
  }
@@ -28736,6 +28787,41 @@ var ParallClient = class _ParallClient {
28736
28787
  const resp = await this.request("GET", ENDPOINTS.CLIP_ONLINE(orgId));
28737
28788
  return resp.data;
28738
28789
  }
28790
+ async listBrowserProfiles(orgId) {
28791
+ const resp = await this.request("GET", ENDPOINTS.BROWSER_PROFILES(orgId));
28792
+ return resp.data;
28793
+ }
28794
+ async createBrowserProfile(orgId, req) {
28795
+ return this.request("POST", ENDPOINTS.BROWSER_PROFILES(orgId), req);
28796
+ }
28797
+ async getBrowserProfile(orgId, profileId) {
28798
+ return this.request("GET", ENDPOINTS.BROWSER_PROFILE(orgId, profileId));
28799
+ }
28800
+ async updateBrowserProfile(orgId, profileId, req) {
28801
+ return this.request("PATCH", ENDPOINTS.BROWSER_PROFILE(orgId, profileId), req);
28802
+ }
28803
+ async deleteBrowserProfile(orgId, profileId) {
28804
+ await this.request("DELETE", ENDPOINTS.BROWSER_PROFILE(orgId, profileId));
28805
+ }
28806
+ async openBrowserProfile(orgId, profileId, req = {}) {
28807
+ return this.request("POST", ENDPOINTS.BROWSER_PROFILE_OPEN(orgId, profileId), req);
28808
+ }
28809
+ async stopBrowserProfile(orgId, profileId) {
28810
+ return this.request("POST", ENDPOINTS.BROWSER_PROFILE_STOP(orgId, profileId), {});
28811
+ }
28812
+ async resetBrowserProfile(orgId, profileId) {
28813
+ return this.request("POST", ENDPOINTS.BROWSER_PROFILE_RESET(orgId, profileId));
28814
+ }
28815
+ async listBrowserProfileConsents(orgId, profileId) {
28816
+ const resp = await this.request("GET", ENDPOINTS.BROWSER_PROFILE_CONSENTS(orgId, profileId));
28817
+ return resp.data;
28818
+ }
28819
+ async grantBrowserProfileConsent(orgId, profileId, req) {
28820
+ return this.request("POST", ENDPOINTS.BROWSER_PROFILE_CONSENTS(orgId, profileId), req);
28821
+ }
28822
+ async revokeBrowserProfileConsent(orgId, profileId, clipId) {
28823
+ await this.request("DELETE", ENDPOINTS.BROWSER_PROFILE_CONSENT(orgId, profileId, clipId));
28824
+ }
28739
28825
  async listRegistryClips(q) {
28740
28826
  const url = ENDPOINTS.CLIP_REGISTRY() + (q ? `?q=${encodeURIComponent(q)}` : "");
28741
28827
  const resp = await this.request("GET", url);
@@ -30719,8 +30805,28 @@ var ParallAgentGateway = class {
30719
30805
  return dispatched;
30720
30806
  }
30721
30807
  async catchUpFromDispatch() {
30808
+ const OVERFLOW_THRESHOLD = 500;
30809
+ const EXPIRE_AGE_HOURS = 24;
30810
+ const CATCHUP_MAX = 10;
30811
+ let expireSummary = null;
30812
+ let overflowMode = false;
30813
+ try {
30814
+ const { count } = await this.opts.client.getDispatchPendingCount(this.opts.config.org_id);
30815
+ if (count > OVERFLOW_THRESHOLD) {
30816
+ overflowMode = true;
30817
+ const result = await this.opts.client.expireDispatch(this.opts.config.org_id, EXPIRE_AGE_HOURS);
30818
+ if (result.total > 0) {
30819
+ this.opts.log?.warn(`dispatch catch-up overflow: ${count} pending, expired ${result.total} events older than ${EXPIRE_AGE_HOURS}h`);
30820
+ expireSummary = this.buildOfflineSummary(result.groups);
30821
+ }
30822
+ }
30823
+ } catch (err) {
30824
+ this.opts.log?.warn(`dispatch catch-up overflow check failed: ${String(err)}`);
30825
+ }
30722
30826
  let cursor;
30723
30827
  let processed = 0;
30828
+ let skipped = 0;
30829
+ const skippedByType = /* @__PURE__ */ new Map();
30724
30830
  do {
30725
30831
  const page = await this.opts.client.getDispatch(this.opts.config.org_id, {
30726
30832
  limit: 50,
@@ -30729,6 +30835,17 @@ var ParallAgentGateway = class {
30729
30835
  for (const item of page.data ?? []) {
30730
30836
  if (this.shuttingDown)
30731
30837
  break;
30838
+ if (overflowMode && processed >= CATCHUP_MAX) {
30839
+ try {
30840
+ await this.opts.client.ackDispatchByID(this.opts.config.org_id, item.id);
30841
+ skipped++;
30842
+ const key = item.event_type;
30843
+ skippedByType.set(key, (skippedByType.get(key) ?? 0) + 1);
30844
+ } catch {
30845
+ this.opts.log?.warn(`catch-up skip ack failed for ${item.id}, leaving pending`);
30846
+ }
30847
+ continue;
30848
+ }
30732
30849
  processed++;
30733
30850
  try {
30734
30851
  let dispatched = false;
@@ -30803,9 +30920,52 @@ var ParallAgentGateway = class {
30803
30920
  }
30804
30921
  cursor = !this.shuttingDown && page.has_more ? page.next_cursor : void 0;
30805
30922
  } while (cursor);
30806
- if (processed > 0) {
30807
- this.opts.log?.info(`dispatch catch-up: processed ${processed}`);
30923
+ if (expireSummary || skipped > 0) {
30924
+ const parts = [];
30925
+ if (expireSummary)
30926
+ parts.push(expireSummary);
30927
+ if (skipped > 0) {
30928
+ const recentLines = [...skippedByType.entries()].map(([type, count]) => `- ${count} recent ${type.replace(".", " ").replace("_", " ")} events`).join("\n");
30929
+ parts.push(expireSummary ? `Additionally, ${skipped} recent events exceeded the catch-up limit and were skipped:
30930
+ ${recentLines}` : `[Offline Summary] You were offline. ${skipped} pending events exceeded the catch-up limit and were skipped:
30931
+ ${recentLines}
30932
+
30933
+ Use your tools (read messages, check tasks) to review anything still relevant.`);
30934
+ }
30935
+ const fullSummary = parts.join("\n\n");
30936
+ this.pendingRestartNotification = this.pendingRestartNotification ? `${this.pendingRestartNotification}
30937
+
30938
+ ${fullSummary}` : fullSummary;
30808
30939
  }
30940
+ if (processed > 0 || skipped > 0) {
30941
+ this.opts.log?.info(`dispatch catch-up: processed ${processed}, skipped ${skipped}`);
30942
+ }
30943
+ }
30944
+ buildOfflineSummary(groups) {
30945
+ const lines = [
30946
+ "[Offline Summary] You were offline and had a large backlog of pending events. The following old events were skipped:"
30947
+ ];
30948
+ for (const g of groups) {
30949
+ const age = this.formatAge(g.oldest);
30950
+ if (g.chat_id && g.event_type === "message") {
30951
+ const name = g.chat_name ?? g.chat_id;
30952
+ lines.push(`- ${g.count} messages in "${name}" (oldest: ${age})`);
30953
+ } else {
30954
+ const label = g.event_type.replace(".", " ").replace("_", " ");
30955
+ lines.push(`- ${g.count} ${label} events (oldest: ${age})`);
30956
+ }
30957
+ }
30958
+ lines.push("");
30959
+ lines.push("These events were too old to process individually. Use your tools (read messages, check tasks) to review anything still relevant.");
30960
+ return lines.join("\n");
30961
+ }
30962
+ formatAge(iso) {
30963
+ const ms = Date.now() - new Date(iso).getTime();
30964
+ const hours = Math.floor(ms / 36e5);
30965
+ if (hours < 24)
30966
+ return `${hours}h ago`;
30967
+ const days = Math.floor(hours / 24);
30968
+ return `${days}d ago`;
30809
30969
  }
30810
30970
  async handleHello(data) {
30811
30971
  const { client, config, log: log2 } = this.opts;