@parall/daemon 1.48.0 → 1.49.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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.48.0",
3
- "built_at": "2026-07-21T07:52:25.995Z",
2
+ "version": "1.49.0",
3
+ "built_at": "2026-07-26T04:12:18.813Z",
4
4
  "min_node_version": "20.0.0",
5
5
  "files": {
6
6
  "bb-browser-daemon.js": {
@@ -16,29 +16,29 @@
16
16
  "size": 18
17
17
  },
18
18
  "parall-browser-pod.js": {
19
- "sha256": "d35ed50bf1fc1266cb8001c9dd3e694dff9847738d125582ccaca81bc3db45d5",
20
- "size": 2894062
19
+ "sha256": "20a0ee67c5be9cd2352ed8e5a503fa60b8fe86d7dba04ecbe2345397c6e7e00f",
20
+ "size": 2899080
21
21
  },
22
22
  "parall-channel-exec.js": {
23
23
  "sha256": "7c2a6e12483a45e9eb4a42cd7d4cdd3c4fa21dd09ac1347d9a3e177b4ddee930",
24
24
  "size": 7220
25
25
  },
26
26
  "parall-claude-agent.js": {
27
- "sha256": "852f7b7d3840f243d39d5ec2f23735ee80fce6fb9c5f8ab5ff1cfb7d5281ad51",
28
- "size": 2727384
27
+ "sha256": "19203c62234b641e691de41af3444d52876beaabc3fa6abeb7907fd5276da711",
28
+ "size": 2732891
29
29
  },
30
30
  "parall-codex-agent.js": {
31
- "sha256": "c331674763f9c237d6a3ee03d9bc8f4137c154e2e576caa5fd23bbe32f0f2b49",
32
- "size": 2769124
31
+ "sha256": "8a80870d3f213ae3d36b5c46b4e4d4e6eb1d91855d5a2ce1c72be43e9cc960ba",
32
+ "size": 2774631
33
33
  },
34
34
  "parall-daemon.js": {
35
- "sha256": "0c41c7255f98339d095faf96e7b712c150d442696eefcb3965d3e59ad0f251fa",
36
- "size": 2955625
35
+ "sha256": "ef3377051a8310fb760d2ce7826a6654d83225f093a8cdade696ad6216540b3c",
36
+ "size": 2961111
37
37
  },
38
38
  "parall-openclaw-agent.js": {
39
39
  "sha256": "856a1c3a9ae0ffef8efe2481fa1171dbeb1d67cccb88616aa9bf16da96a69355",
40
40
  "size": 9923
41
41
  }
42
42
  },
43
- "signature": "u4mhCrFPCejnf/mBjQdNvKkDaQE0MjumZpTc5eHA+Qz7cbemy1WDRhy+j0A4pMvBezJqwUIoyQqn84jfjcgBDA=="
43
+ "signature": "sDr+si9wQsnB/LezX3xlTWHu2bHV5DzO5KWEtQz/5Qj2XOWfpKqvb0JjjVFGOxCG07mIGSfj9U5KpeT3GMgbDg=="
44
44
  }
@@ -63552,6 +63552,8 @@ var ENDPOINTS = {
63552
63552
  MESSAGE_WATCH: (id) => `${API_BASE}/messages/${id}/watch`,
63553
63553
  MESSAGE_WATCHERS: (id) => `${API_BASE}/messages/${id}/watchers`,
63554
63554
  MESSAGE_WATCHING: (id) => `${API_BASE}/messages/${id}/watching`,
63555
+ MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
63556
+ MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
63555
63557
  // Upload (org-scoped)
63556
63558
  UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
63557
63559
  UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
@@ -63789,11 +63791,13 @@ var ENDPOINTS = {
63789
63791
  UNREAD: `${API_BASE}/me/unread`,
63790
63792
  ORG_UNREAD: (orgId) => `${API_BASE}/orgs/${orgId}/unread`,
63791
63793
  CHAT_READ: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read`,
63794
+ CHAT_READ_ALL: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read-all`,
63792
63795
  THREAD_UNREAD: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/unread`,
63793
63796
  THREAD_READ: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/read`,
63794
63797
  // References (org-scoped)
63795
63798
  REFS_RESOLVE: (orgId) => `${API_BASE}/orgs/${orgId}/refs/resolve`,
63796
63799
  REFS_BACKLINKS: (orgId) => `${API_BASE}/orgs/${orgId}/refs/backlinks`,
63800
+ REFS_OUTBOUND: (orgId) => `${API_BASE}/orgs/${orgId}/refs/outbound`,
63797
63801
  REFS_GRAPH: (orgId) => `${API_BASE}/orgs/${orgId}/refs/graph`,
63798
63802
  REFS_CHECK: (orgId) => `${API_BASE}/orgs/${orgId}/refs/check`,
63799
63803
  // Platform config (agent-scoped, not org-scoped)
@@ -63855,7 +63859,13 @@ var ENDPOINTS = {
63855
63859
  ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
63856
63860
  ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
63857
63861
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
63862
+ // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
63863
+ ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
63858
63864
  ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
63865
+ // Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
63866
+ // Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
63867
+ // pipe. Additive: does NOT replace BROWSER_PROFILE_VIEWER_COMMAND.
63868
+ ORG_EDGE_VIEWER_COMMAND: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/viewer/command`,
63859
63869
  CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
63860
63870
  CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`,
63861
63871
  // Clip registry (v3, org-scoped, served by api-server — `crg_` entries; the
@@ -64020,7 +64030,7 @@ var ParallClient = class _ParallClient {
64020
64030
  if (qs)
64021
64031
  url += `?${qs}`;
64022
64032
  }
64023
- const headers = this.buildHeaders(path7);
64033
+ const headers = this.buildHeaders(path7, opts?.headers);
64024
64034
  const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
64025
64035
  const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
64026
64036
  let res;
@@ -64426,6 +64436,14 @@ var ParallClient = class _ParallClient {
64426
64436
  async getMessageReplies(id, params) {
64427
64437
  return this.request("GET", ENDPOINTS.MESSAGE_REPLIES(id), void 0, params);
64428
64438
  }
64439
+ // ---- Reactions ----
64440
+ async toggleReaction(messageId, emoji) {
64441
+ return this.request("PUT", ENDPOINTS.MESSAGE_REACTION(messageId, emoji));
64442
+ }
64443
+ async listReactions(messageId) {
64444
+ const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
64445
+ return res.reactions;
64446
+ }
64429
64447
  // ---- File Upload ----
64430
64448
  async getUploadPresignUrl(orgId, req) {
64431
64449
  return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
@@ -64801,6 +64819,15 @@ var ParallClient = class _ParallClient {
64801
64819
  async browserViewerCommand(orgId, profileId, req, opts) {
64802
64820
  return this.request("POST", ENDPOINTS.BROWSER_PROFILE_VIEWER_COMMAND(orgId, profileId), req, void 0, false, opts);
64803
64821
  }
64822
+ /**
64823
+ * Drive the Cloud Edge live viewer (V1b, design §6): WebRTC signaling + input +
64824
+ * tab nav for a hosted browser (Cloud Profile). Same request/reply shape as
64825
+ * browserViewerCommand, on the v3 edge pipe; additive — the v2 browser-profile
64826
+ * viewer is unchanged.
64827
+ */
64828
+ async edgeViewerCommand(orgId, edgeId, req, opts) {
64829
+ return this.request("POST", ENDPOINTS.ORG_EDGE_VIEWER_COMMAND(orgId, edgeId), req, void 0, false, opts);
64830
+ }
64804
64831
  async resizeMachine(orgId, machineId, spec) {
64805
64832
  return this.request("PATCH", ENDPOINTS.MACHINE_SPEC(orgId, machineId), spec);
64806
64833
  }
@@ -64827,14 +64854,23 @@ var ParallClient = class _ParallClient {
64827
64854
  }
64828
64855
  // Wiki mount/token methods removed — wiki-service handles all wiki endpoints.
64829
64856
  // ---- Unread ----
64830
- async getUnreadCounts(orgId) {
64857
+ async getUnreadCounts(orgId, opts) {
64831
64858
  const endpoint = orgId ? ENDPOINTS.ORG_UNREAD(orgId) : ENDPOINTS.UNREAD;
64832
- const res = await this.request("GET", endpoint);
64859
+ const res = await this.request("GET", endpoint, void 0, {
64860
+ include_thread_replies: opts?.includeThreadReplies ? "true" : void 0
64861
+ });
64833
64862
  return res.data;
64834
64863
  }
64835
64864
  async markRead(orgId, chatId, messageId) {
64836
64865
  return this.request("POST", ENDPOINTS.CHAT_READ(orgId, chatId), { message_id: messageId });
64837
64866
  }
64867
+ /** Mark everything in a chat read: the channel cursor jumps to the latest
64868
+ * top-level message and every thread cursor to its latest reply, in one
64869
+ * idempotent call. The server echoes the same per-cursor WS events the
64870
+ * single-cursor routes emit and auto-clears covered inbox items. */
64871
+ async markAllRead(orgId, chatId) {
64872
+ return this.request("POST", ENDPOINTS.CHAT_READ_ALL(orgId, chatId));
64873
+ }
64838
64874
  async getThreadUnread(orgId, chatId, threadRootId) {
64839
64875
  return this.request("GET", ENDPOINTS.THREAD_UNREAD(orgId, chatId, threadRootId));
64840
64876
  }
@@ -65509,6 +65545,16 @@ var ParallClient = class _ParallClient {
65509
65545
  async getBacklinks(orgId, params) {
65510
65546
  return this.request("GET", ENDPOINTS.REFS_BACKLINKS(orgId), void 0, params);
65511
65547
  }
65548
+ /**
65549
+ * Outbound prll:// refs authored in a set of sources, as raw ref_links rows
65550
+ * (dedupe/group client-side). Pass `{ thread_root_id }` to list a whole
65551
+ * thread's refs (root + all replies, resolved server-side — the client's
65552
+ * reply window may be partial), or `{ source_type, source_ids }` for
65553
+ * explicit sources (max 500; v1 accepts only message sources).
65554
+ */
65555
+ async listOutboundRefs(orgId, req) {
65556
+ return this.request("POST", ENDPOINTS.REFS_OUTBOUND(orgId), req);
65557
+ }
65512
65558
  /**
65513
65559
  * Bounded multi-hop walk of the prll:// reference graph around `uri`. `uri`
65514
65560
  * must be an entity-level prll:// URI — a refined URI (path/query/fragment) is
@@ -65788,6 +65834,43 @@ var ParallClient = class _ParallClient {
65788
65834
  async listEdgeProfiles(orgId, edgeId) {
65789
65835
  return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
65790
65836
  }
65837
+ /**
65838
+ * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
65839
+ * human maintainer or org admin). Sanitized — the password never comes back.
65840
+ * Typed errors: `EDGE_NOT_HOSTED` (BYOC device), `PROXY_CONFIG_CORRUPT` /
65841
+ * validation codes as 422 when a stored config no longer passes current rules.
65842
+ * `can_mutate` and `lease_status` are the authoritative idle gate; device
65843
+ * list status is not a substitute.
65844
+ */
65845
+ async getEdgeProfileProxy(orgId, edgeId, profileName) {
65846
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName));
65847
+ }
65848
+ /**
65849
+ * Set/replace the profile's egress proxy (full triple every time) — IDLE
65850
+ * ONLY: while the profile's hosted browser is running (a viewer session is
65851
+ * open or a pod is otherwise live) the server answers 409
65852
+ * `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle scale-to-zero, and
65853
+ * retry. The next cold start uses the new egress; browser login state is
65854
+ * preserved across it. Other typed errors: the validation vocabulary
65855
+ * (`INVALID_PROXY_SERVER`, `PROXY_AUTH_INCOMPLETE`,
65856
+ * `PROXY_SERVER_FORBIDDEN_TARGET`, …), `EDGE_DELETING` (409), and
65857
+ * `SECRETBOX_UNCONFIGURED` (503 — server cannot store credentials safely),
65858
+ * and `EDGE_PROFILE_PROXY_STALE` (409 — expectedVersion lost a tab race).
65859
+ */
65860
+ async setEdgeProfileProxy(orgId, edgeId, profileName, req, expectedVersion) {
65861
+ return this.request("PUT", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), req, void 0, false, {
65862
+ headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
65863
+ });
65864
+ }
65865
+ /**
65866
+ * Clear the profile's egress proxy; the next pod start egresses directly.
65867
+ * Idle-only like set — 409 `EDGE_PROFILE_IN_USE` while the browser is live.
65868
+ */
65869
+ async clearEdgeProfileProxy(orgId, edgeId, profileName, expectedVersion) {
65870
+ return this.request("DELETE", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), void 0, void 0, false, {
65871
+ headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
65872
+ });
65873
+ }
65791
65874
  /**
65792
65875
  * Execute a registry clip command on an Edge device.
65793
65876
  *
@@ -65856,6 +65939,8 @@ var ApiError = class extends Error {
65856
65939
  status;
65857
65940
  code;
65858
65941
  extras;
65942
+ /** Retry-After delta seconds when the server supplies one. */
65943
+ retryAfterSeconds;
65859
65944
  /** Attempted action (authorization denials) — e.g. "chat.add_member". */
65860
65945
  action;
65861
65946
  /** Target resource URI that was evaluated — e.g. "prll://cht_…". */
@@ -65875,6 +65960,9 @@ function buildApiError(res, rawErrorBody) {
65875
65960
  const errMsg2 = (typeof errorObj?.message === "string" ? errorObj.message : void 0) ?? (typeof errorBody.message === "string" ? errorBody.message : void 0) ?? (typeof errorBody.error === "string" ? errorBody.error : void 0);
65876
65961
  const errCode = (typeof errorObj?.code === "string" ? errorObj.code : void 0) ?? (typeof errorBody.code === "string" ? errorBody.code : void 0);
65877
65962
  const apiError = new ApiError(res.status, errMsg2 ?? res.statusText, errCode);
65963
+ const retryAfter = Number(res.headers?.get("Retry-After"));
65964
+ if (Number.isFinite(retryAfter) && retryAfter > 0)
65965
+ apiError.retryAfterSeconds = retryAfter;
65878
65966
  const anchors = errorObj ?? errorBody;
65879
65967
  if (typeof anchors.action === "string")
65880
65968
  apiError.action = anchors.action;
@@ -51351,6 +51351,8 @@ var ENDPOINTS = {
51351
51351
  MESSAGE_WATCH: (id) => `${API_BASE}/messages/${id}/watch`,
51352
51352
  MESSAGE_WATCHERS: (id) => `${API_BASE}/messages/${id}/watchers`,
51353
51353
  MESSAGE_WATCHING: (id) => `${API_BASE}/messages/${id}/watching`,
51354
+ MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
51355
+ MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
51354
51356
  // Upload (org-scoped)
51355
51357
  UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
51356
51358
  UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
@@ -51588,11 +51590,13 @@ var ENDPOINTS = {
51588
51590
  UNREAD: `${API_BASE}/me/unread`,
51589
51591
  ORG_UNREAD: (orgId) => `${API_BASE}/orgs/${orgId}/unread`,
51590
51592
  CHAT_READ: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read`,
51593
+ CHAT_READ_ALL: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read-all`,
51591
51594
  THREAD_UNREAD: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/unread`,
51592
51595
  THREAD_READ: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/read`,
51593
51596
  // References (org-scoped)
51594
51597
  REFS_RESOLVE: (orgId) => `${API_BASE}/orgs/${orgId}/refs/resolve`,
51595
51598
  REFS_BACKLINKS: (orgId) => `${API_BASE}/orgs/${orgId}/refs/backlinks`,
51599
+ REFS_OUTBOUND: (orgId) => `${API_BASE}/orgs/${orgId}/refs/outbound`,
51596
51600
  REFS_GRAPH: (orgId) => `${API_BASE}/orgs/${orgId}/refs/graph`,
51597
51601
  REFS_CHECK: (orgId) => `${API_BASE}/orgs/${orgId}/refs/check`,
51598
51602
  // Platform config (agent-scoped, not org-scoped)
@@ -51654,7 +51658,13 @@ var ENDPOINTS = {
51654
51658
  ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
51655
51659
  ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
51656
51660
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
51661
+ // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
51662
+ ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
51657
51663
  ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
51664
+ // Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
51665
+ // Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
51666
+ // pipe. Additive: does NOT replace BROWSER_PROFILE_VIEWER_COMMAND.
51667
+ ORG_EDGE_VIEWER_COMMAND: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/viewer/command`,
51658
51668
  CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
51659
51669
  CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`,
51660
51670
  // Clip registry (v3, org-scoped, served by api-server — `crg_` entries; the
@@ -51677,6 +51687,7 @@ var WS_EVENTS = {
51677
51687
  MESSAGE_PATCH: "message.patch",
51678
51688
  MESSAGE_EDIT: "message.edit",
51679
51689
  MESSAGE_DELETE: "message.delete",
51690
+ MESSAGE_REACTION_UPDATED: "message.reaction.updated",
51680
51691
  TYPING_UPDATE: "typing.update",
51681
51692
  CHAT_UPDATE: "chat.update",
51682
51693
  CHAT_DELETED: "chat.deleted",
@@ -51718,6 +51729,7 @@ var WS_EVENTS = {
51718
51729
  INBOX_UPDATE: "inbox.update",
51719
51730
  INBOX_BULK_UPDATE: "inbox.bulk_update",
51720
51731
  READ_POSITION_UPDATED: "read_position.updated",
51732
+ THREAD_READ_POSITION_UPDATED: "thread_read_position.updated",
51721
51733
  DISPATCH_NEW: "dispatch.new",
51722
51734
  DISPATCH_RECEIVED: "dispatch.received",
51723
51735
  DISPATCH_RESOLVED: "dispatch.resolved",
@@ -51903,7 +51915,7 @@ var ParallClient = class _ParallClient {
51903
51915
  if (qs)
51904
51916
  url += `?${qs}`;
51905
51917
  }
51906
- const headers = this.buildHeaders(path11);
51918
+ const headers = this.buildHeaders(path11, opts?.headers);
51907
51919
  const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
51908
51920
  const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
51909
51921
  let res;
@@ -52309,6 +52321,14 @@ var ParallClient = class _ParallClient {
52309
52321
  async getMessageReplies(id, params) {
52310
52322
  return this.request("GET", ENDPOINTS.MESSAGE_REPLIES(id), void 0, params);
52311
52323
  }
52324
+ // ---- Reactions ----
52325
+ async toggleReaction(messageId, emoji) {
52326
+ return this.request("PUT", ENDPOINTS.MESSAGE_REACTION(messageId, emoji));
52327
+ }
52328
+ async listReactions(messageId) {
52329
+ const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
52330
+ return res.reactions;
52331
+ }
52312
52332
  // ---- File Upload ----
52313
52333
  async getUploadPresignUrl(orgId, req) {
52314
52334
  return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
@@ -52684,6 +52704,15 @@ var ParallClient = class _ParallClient {
52684
52704
  async browserViewerCommand(orgId, profileId, req, opts) {
52685
52705
  return this.request("POST", ENDPOINTS.BROWSER_PROFILE_VIEWER_COMMAND(orgId, profileId), req, void 0, false, opts);
52686
52706
  }
52707
+ /**
52708
+ * Drive the Cloud Edge live viewer (V1b, design §6): WebRTC signaling + input +
52709
+ * tab nav for a hosted browser (Cloud Profile). Same request/reply shape as
52710
+ * browserViewerCommand, on the v3 edge pipe; additive — the v2 browser-profile
52711
+ * viewer is unchanged.
52712
+ */
52713
+ async edgeViewerCommand(orgId, edgeId, req, opts) {
52714
+ return this.request("POST", ENDPOINTS.ORG_EDGE_VIEWER_COMMAND(orgId, edgeId), req, void 0, false, opts);
52715
+ }
52687
52716
  async resizeMachine(orgId, machineId, spec) {
52688
52717
  return this.request("PATCH", ENDPOINTS.MACHINE_SPEC(orgId, machineId), spec);
52689
52718
  }
@@ -52710,14 +52739,23 @@ var ParallClient = class _ParallClient {
52710
52739
  }
52711
52740
  // Wiki mount/token methods removed — wiki-service handles all wiki endpoints.
52712
52741
  // ---- Unread ----
52713
- async getUnreadCounts(orgId) {
52742
+ async getUnreadCounts(orgId, opts) {
52714
52743
  const endpoint = orgId ? ENDPOINTS.ORG_UNREAD(orgId) : ENDPOINTS.UNREAD;
52715
- const res = await this.request("GET", endpoint);
52744
+ const res = await this.request("GET", endpoint, void 0, {
52745
+ include_thread_replies: opts?.includeThreadReplies ? "true" : void 0
52746
+ });
52716
52747
  return res.data;
52717
52748
  }
52718
52749
  async markRead(orgId, chatId, messageId) {
52719
52750
  return this.request("POST", ENDPOINTS.CHAT_READ(orgId, chatId), { message_id: messageId });
52720
52751
  }
52752
+ /** Mark everything in a chat read: the channel cursor jumps to the latest
52753
+ * top-level message and every thread cursor to its latest reply, in one
52754
+ * idempotent call. The server echoes the same per-cursor WS events the
52755
+ * single-cursor routes emit and auto-clears covered inbox items. */
52756
+ async markAllRead(orgId, chatId) {
52757
+ return this.request("POST", ENDPOINTS.CHAT_READ_ALL(orgId, chatId));
52758
+ }
52721
52759
  async getThreadUnread(orgId, chatId, threadRootId) {
52722
52760
  return this.request("GET", ENDPOINTS.THREAD_UNREAD(orgId, chatId, threadRootId));
52723
52761
  }
@@ -53392,6 +53430,16 @@ var ParallClient = class _ParallClient {
53392
53430
  async getBacklinks(orgId, params) {
53393
53431
  return this.request("GET", ENDPOINTS.REFS_BACKLINKS(orgId), void 0, params);
53394
53432
  }
53433
+ /**
53434
+ * Outbound prll:// refs authored in a set of sources, as raw ref_links rows
53435
+ * (dedupe/group client-side). Pass `{ thread_root_id }` to list a whole
53436
+ * thread's refs (root + all replies, resolved server-side — the client's
53437
+ * reply window may be partial), or `{ source_type, source_ids }` for
53438
+ * explicit sources (max 500; v1 accepts only message sources).
53439
+ */
53440
+ async listOutboundRefs(orgId, req) {
53441
+ return this.request("POST", ENDPOINTS.REFS_OUTBOUND(orgId), req);
53442
+ }
53395
53443
  /**
53396
53444
  * Bounded multi-hop walk of the prll:// reference graph around `uri`. `uri`
53397
53445
  * must be an entity-level prll:// URI — a refined URI (path/query/fragment) is
@@ -53671,6 +53719,43 @@ var ParallClient = class _ParallClient {
53671
53719
  async listEdgeProfiles(orgId, edgeId) {
53672
53720
  return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
53673
53721
  }
53722
+ /**
53723
+ * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
53724
+ * human maintainer or org admin). Sanitized — the password never comes back.
53725
+ * Typed errors: `EDGE_NOT_HOSTED` (BYOC device), `PROXY_CONFIG_CORRUPT` /
53726
+ * validation codes as 422 when a stored config no longer passes current rules.
53727
+ * `can_mutate` and `lease_status` are the authoritative idle gate; device
53728
+ * list status is not a substitute.
53729
+ */
53730
+ async getEdgeProfileProxy(orgId, edgeId, profileName) {
53731
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName));
53732
+ }
53733
+ /**
53734
+ * Set/replace the profile's egress proxy (full triple every time) — IDLE
53735
+ * ONLY: while the profile's hosted browser is running (a viewer session is
53736
+ * open or a pod is otherwise live) the server answers 409
53737
+ * `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle scale-to-zero, and
53738
+ * retry. The next cold start uses the new egress; browser login state is
53739
+ * preserved across it. Other typed errors: the validation vocabulary
53740
+ * (`INVALID_PROXY_SERVER`, `PROXY_AUTH_INCOMPLETE`,
53741
+ * `PROXY_SERVER_FORBIDDEN_TARGET`, …), `EDGE_DELETING` (409), and
53742
+ * `SECRETBOX_UNCONFIGURED` (503 — server cannot store credentials safely),
53743
+ * and `EDGE_PROFILE_PROXY_STALE` (409 — expectedVersion lost a tab race).
53744
+ */
53745
+ async setEdgeProfileProxy(orgId, edgeId, profileName, req, expectedVersion) {
53746
+ return this.request("PUT", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), req, void 0, false, {
53747
+ headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
53748
+ });
53749
+ }
53750
+ /**
53751
+ * Clear the profile's egress proxy; the next pod start egresses directly.
53752
+ * Idle-only like set — 409 `EDGE_PROFILE_IN_USE` while the browser is live.
53753
+ */
53754
+ async clearEdgeProfileProxy(orgId, edgeId, profileName, expectedVersion) {
53755
+ return this.request("DELETE", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), void 0, void 0, false, {
53756
+ headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
53757
+ });
53758
+ }
53674
53759
  /**
53675
53760
  * Execute a registry clip command on an Edge device.
53676
53761
  *
@@ -53739,6 +53824,8 @@ var ApiError = class extends Error {
53739
53824
  status;
53740
53825
  code;
53741
53826
  extras;
53827
+ /** Retry-After delta seconds when the server supplies one. */
53828
+ retryAfterSeconds;
53742
53829
  /** Attempted action (authorization denials) — e.g. "chat.add_member". */
53743
53830
  action;
53744
53831
  /** Target resource URI that was evaluated — e.g. "prll://cht_…". */
@@ -53758,6 +53845,9 @@ function buildApiError(res, rawErrorBody) {
53758
53845
  const errMsg = (typeof errorObj?.message === "string" ? errorObj.message : void 0) ?? (typeof errorBody.message === "string" ? errorBody.message : void 0) ?? (typeof errorBody.error === "string" ? errorBody.error : void 0);
53759
53846
  const errCode = (typeof errorObj?.code === "string" ? errorObj.code : void 0) ?? (typeof errorBody.code === "string" ? errorBody.code : void 0);
53760
53847
  const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
53848
+ const retryAfter = Number(res.headers?.get("Retry-After"));
53849
+ if (Number.isFinite(retryAfter) && retryAfter > 0)
53850
+ apiError.retryAfterSeconds = retryAfter;
53761
53851
  const anchors = errorObj ?? errorBody;
53762
53852
  if (typeof anchors.action === "string")
53763
53853
  apiError.action = anchors.action;
@@ -59332,7 +59422,7 @@ parall tasks list --assignee-id prll://usr_xxx # first page only (default 20)
59332
59422
  parall tasks subtasks prll://tsk_xxx # children of a single parent task
59333
59423
 
59334
59424
  # Create a task (add --parent-id to make it a SUBTASK of another task)
59335
- parall tasks create --title "Task title" [--assignee-id prll://usr_xxx] [--parent-id prll://tsk_xxx] [--project-id prll://prj_xxx] [--due-date 2026-08-01]
59425
+ parall tasks create --title "Task title" [--assignee-id prll://usr_xxx] [--parent-id prll://tsk_xxx] [--project-id prll://prj_xxx] [--planned-start 2026-07-20] [--due-date 2026-08-01]
59336
59426
 
59337
59427
  # Update task status \u2014 add --placement end so the task lands at the end of
59338
59428
  # its NEW status column (a bare --status keeps the old column's sort_order)
@@ -59343,6 +59433,12 @@ parall tasks update prll://tsk_xxx --status done --placement end
59343
59433
  parall tasks update prll://tsk_xxx --due-date 2026-08-01
59344
59434
  parall tasks update prll://tsk_xxx --due-date none
59345
59435
 
59436
+ # Planned start \u2014 same grammar as --due-date; must be on or before the due
59437
+ # date when both are set. This is the planned schedule's left-edge date,
59438
+ # NOT when work actually began (that stays on lifecycle timestamps)
59439
+ parall tasks update prll://tsk_xxx --planned-start 2026-07-20
59440
+ parall tasks update prll://tsk_xxx --planned-start none
59441
+
59346
59442
  # Move a task to the end of its status column
59347
59443
  parall tasks update prll://tsk_xxx --placement end
59348
59444
 
@@ -51351,6 +51351,8 @@ var ENDPOINTS = {
51351
51351
  MESSAGE_WATCH: (id) => `${API_BASE}/messages/${id}/watch`,
51352
51352
  MESSAGE_WATCHERS: (id) => `${API_BASE}/messages/${id}/watchers`,
51353
51353
  MESSAGE_WATCHING: (id) => `${API_BASE}/messages/${id}/watching`,
51354
+ MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
51355
+ MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
51354
51356
  // Upload (org-scoped)
51355
51357
  UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
51356
51358
  UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
@@ -51588,11 +51590,13 @@ var ENDPOINTS = {
51588
51590
  UNREAD: `${API_BASE}/me/unread`,
51589
51591
  ORG_UNREAD: (orgId) => `${API_BASE}/orgs/${orgId}/unread`,
51590
51592
  CHAT_READ: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read`,
51593
+ CHAT_READ_ALL: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read-all`,
51591
51594
  THREAD_UNREAD: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/unread`,
51592
51595
  THREAD_READ: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/read`,
51593
51596
  // References (org-scoped)
51594
51597
  REFS_RESOLVE: (orgId) => `${API_BASE}/orgs/${orgId}/refs/resolve`,
51595
51598
  REFS_BACKLINKS: (orgId) => `${API_BASE}/orgs/${orgId}/refs/backlinks`,
51599
+ REFS_OUTBOUND: (orgId) => `${API_BASE}/orgs/${orgId}/refs/outbound`,
51596
51600
  REFS_GRAPH: (orgId) => `${API_BASE}/orgs/${orgId}/refs/graph`,
51597
51601
  REFS_CHECK: (orgId) => `${API_BASE}/orgs/${orgId}/refs/check`,
51598
51602
  // Platform config (agent-scoped, not org-scoped)
@@ -51654,7 +51658,13 @@ var ENDPOINTS = {
51654
51658
  ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
51655
51659
  ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
51656
51660
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
51661
+ // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
51662
+ ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
51657
51663
  ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
51664
+ // Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
51665
+ // Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
51666
+ // pipe. Additive: does NOT replace BROWSER_PROFILE_VIEWER_COMMAND.
51667
+ ORG_EDGE_VIEWER_COMMAND: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/viewer/command`,
51658
51668
  CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
51659
51669
  CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`,
51660
51670
  // Clip registry (v3, org-scoped, served by api-server — `crg_` entries; the
@@ -51677,6 +51687,7 @@ var WS_EVENTS = {
51677
51687
  MESSAGE_PATCH: "message.patch",
51678
51688
  MESSAGE_EDIT: "message.edit",
51679
51689
  MESSAGE_DELETE: "message.delete",
51690
+ MESSAGE_REACTION_UPDATED: "message.reaction.updated",
51680
51691
  TYPING_UPDATE: "typing.update",
51681
51692
  CHAT_UPDATE: "chat.update",
51682
51693
  CHAT_DELETED: "chat.deleted",
@@ -51718,6 +51729,7 @@ var WS_EVENTS = {
51718
51729
  INBOX_UPDATE: "inbox.update",
51719
51730
  INBOX_BULK_UPDATE: "inbox.bulk_update",
51720
51731
  READ_POSITION_UPDATED: "read_position.updated",
51732
+ THREAD_READ_POSITION_UPDATED: "thread_read_position.updated",
51721
51733
  DISPATCH_NEW: "dispatch.new",
51722
51734
  DISPATCH_RECEIVED: "dispatch.received",
51723
51735
  DISPATCH_RESOLVED: "dispatch.resolved",
@@ -51903,7 +51915,7 @@ var ParallClient = class _ParallClient {
51903
51915
  if (qs)
51904
51916
  url += `?${qs}`;
51905
51917
  }
51906
- const headers = this.buildHeaders(path12);
51918
+ const headers = this.buildHeaders(path12, opts?.headers);
51907
51919
  const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
51908
51920
  const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
51909
51921
  let res;
@@ -52309,6 +52321,14 @@ var ParallClient = class _ParallClient {
52309
52321
  async getMessageReplies(id, params) {
52310
52322
  return this.request("GET", ENDPOINTS.MESSAGE_REPLIES(id), void 0, params);
52311
52323
  }
52324
+ // ---- Reactions ----
52325
+ async toggleReaction(messageId, emoji) {
52326
+ return this.request("PUT", ENDPOINTS.MESSAGE_REACTION(messageId, emoji));
52327
+ }
52328
+ async listReactions(messageId) {
52329
+ const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
52330
+ return res.reactions;
52331
+ }
52312
52332
  // ---- File Upload ----
52313
52333
  async getUploadPresignUrl(orgId, req) {
52314
52334
  return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
@@ -52684,6 +52704,15 @@ var ParallClient = class _ParallClient {
52684
52704
  async browserViewerCommand(orgId, profileId, req, opts) {
52685
52705
  return this.request("POST", ENDPOINTS.BROWSER_PROFILE_VIEWER_COMMAND(orgId, profileId), req, void 0, false, opts);
52686
52706
  }
52707
+ /**
52708
+ * Drive the Cloud Edge live viewer (V1b, design §6): WebRTC signaling + input +
52709
+ * tab nav for a hosted browser (Cloud Profile). Same request/reply shape as
52710
+ * browserViewerCommand, on the v3 edge pipe; additive — the v2 browser-profile
52711
+ * viewer is unchanged.
52712
+ */
52713
+ async edgeViewerCommand(orgId, edgeId, req, opts) {
52714
+ return this.request("POST", ENDPOINTS.ORG_EDGE_VIEWER_COMMAND(orgId, edgeId), req, void 0, false, opts);
52715
+ }
52687
52716
  async resizeMachine(orgId, machineId, spec) {
52688
52717
  return this.request("PATCH", ENDPOINTS.MACHINE_SPEC(orgId, machineId), spec);
52689
52718
  }
@@ -52710,14 +52739,23 @@ var ParallClient = class _ParallClient {
52710
52739
  }
52711
52740
  // Wiki mount/token methods removed — wiki-service handles all wiki endpoints.
52712
52741
  // ---- Unread ----
52713
- async getUnreadCounts(orgId) {
52742
+ async getUnreadCounts(orgId, opts) {
52714
52743
  const endpoint = orgId ? ENDPOINTS.ORG_UNREAD(orgId) : ENDPOINTS.UNREAD;
52715
- const res = await this.request("GET", endpoint);
52744
+ const res = await this.request("GET", endpoint, void 0, {
52745
+ include_thread_replies: opts?.includeThreadReplies ? "true" : void 0
52746
+ });
52716
52747
  return res.data;
52717
52748
  }
52718
52749
  async markRead(orgId, chatId, messageId) {
52719
52750
  return this.request("POST", ENDPOINTS.CHAT_READ(orgId, chatId), { message_id: messageId });
52720
52751
  }
52752
+ /** Mark everything in a chat read: the channel cursor jumps to the latest
52753
+ * top-level message and every thread cursor to its latest reply, in one
52754
+ * idempotent call. The server echoes the same per-cursor WS events the
52755
+ * single-cursor routes emit and auto-clears covered inbox items. */
52756
+ async markAllRead(orgId, chatId) {
52757
+ return this.request("POST", ENDPOINTS.CHAT_READ_ALL(orgId, chatId));
52758
+ }
52721
52759
  async getThreadUnread(orgId, chatId, threadRootId) {
52722
52760
  return this.request("GET", ENDPOINTS.THREAD_UNREAD(orgId, chatId, threadRootId));
52723
52761
  }
@@ -53392,6 +53430,16 @@ var ParallClient = class _ParallClient {
53392
53430
  async getBacklinks(orgId, params) {
53393
53431
  return this.request("GET", ENDPOINTS.REFS_BACKLINKS(orgId), void 0, params);
53394
53432
  }
53433
+ /**
53434
+ * Outbound prll:// refs authored in a set of sources, as raw ref_links rows
53435
+ * (dedupe/group client-side). Pass `{ thread_root_id }` to list a whole
53436
+ * thread's refs (root + all replies, resolved server-side — the client's
53437
+ * reply window may be partial), or `{ source_type, source_ids }` for
53438
+ * explicit sources (max 500; v1 accepts only message sources).
53439
+ */
53440
+ async listOutboundRefs(orgId, req) {
53441
+ return this.request("POST", ENDPOINTS.REFS_OUTBOUND(orgId), req);
53442
+ }
53395
53443
  /**
53396
53444
  * Bounded multi-hop walk of the prll:// reference graph around `uri`. `uri`
53397
53445
  * must be an entity-level prll:// URI — a refined URI (path/query/fragment) is
@@ -53671,6 +53719,43 @@ var ParallClient = class _ParallClient {
53671
53719
  async listEdgeProfiles(orgId, edgeId) {
53672
53720
  return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
53673
53721
  }
53722
+ /**
53723
+ * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
53724
+ * human maintainer or org admin). Sanitized — the password never comes back.
53725
+ * Typed errors: `EDGE_NOT_HOSTED` (BYOC device), `PROXY_CONFIG_CORRUPT` /
53726
+ * validation codes as 422 when a stored config no longer passes current rules.
53727
+ * `can_mutate` and `lease_status` are the authoritative idle gate; device
53728
+ * list status is not a substitute.
53729
+ */
53730
+ async getEdgeProfileProxy(orgId, edgeId, profileName) {
53731
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName));
53732
+ }
53733
+ /**
53734
+ * Set/replace the profile's egress proxy (full triple every time) — IDLE
53735
+ * ONLY: while the profile's hosted browser is running (a viewer session is
53736
+ * open or a pod is otherwise live) the server answers 409
53737
+ * `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle scale-to-zero, and
53738
+ * retry. The next cold start uses the new egress; browser login state is
53739
+ * preserved across it. Other typed errors: the validation vocabulary
53740
+ * (`INVALID_PROXY_SERVER`, `PROXY_AUTH_INCOMPLETE`,
53741
+ * `PROXY_SERVER_FORBIDDEN_TARGET`, …), `EDGE_DELETING` (409), and
53742
+ * `SECRETBOX_UNCONFIGURED` (503 — server cannot store credentials safely),
53743
+ * and `EDGE_PROFILE_PROXY_STALE` (409 — expectedVersion lost a tab race).
53744
+ */
53745
+ async setEdgeProfileProxy(orgId, edgeId, profileName, req, expectedVersion) {
53746
+ return this.request("PUT", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), req, void 0, false, {
53747
+ headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
53748
+ });
53749
+ }
53750
+ /**
53751
+ * Clear the profile's egress proxy; the next pod start egresses directly.
53752
+ * Idle-only like set — 409 `EDGE_PROFILE_IN_USE` while the browser is live.
53753
+ */
53754
+ async clearEdgeProfileProxy(orgId, edgeId, profileName, expectedVersion) {
53755
+ return this.request("DELETE", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), void 0, void 0, false, {
53756
+ headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
53757
+ });
53758
+ }
53674
53759
  /**
53675
53760
  * Execute a registry clip command on an Edge device.
53676
53761
  *
@@ -53739,6 +53824,8 @@ var ApiError = class extends Error {
53739
53824
  status;
53740
53825
  code;
53741
53826
  extras;
53827
+ /** Retry-After delta seconds when the server supplies one. */
53828
+ retryAfterSeconds;
53742
53829
  /** Attempted action (authorization denials) — e.g. "chat.add_member". */
53743
53830
  action;
53744
53831
  /** Target resource URI that was evaluated — e.g. "prll://cht_…". */
@@ -53758,6 +53845,9 @@ function buildApiError(res, rawErrorBody) {
53758
53845
  const errMsg = (typeof errorObj?.message === "string" ? errorObj.message : void 0) ?? (typeof errorBody.message === "string" ? errorBody.message : void 0) ?? (typeof errorBody.error === "string" ? errorBody.error : void 0);
53759
53846
  const errCode = (typeof errorObj?.code === "string" ? errorObj.code : void 0) ?? (typeof errorBody.code === "string" ? errorBody.code : void 0);
53760
53847
  const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
53848
+ const retryAfter = Number(res.headers?.get("Retry-After"));
53849
+ if (Number.isFinite(retryAfter) && retryAfter > 0)
53850
+ apiError.retryAfterSeconds = retryAfter;
53761
53851
  const anchors = errorObj ?? errorBody;
53762
53852
  if (typeof anchors.action === "string")
53763
53853
  apiError.action = anchors.action;
@@ -59332,7 +59422,7 @@ parall tasks list --assignee-id prll://usr_xxx # first page only (default 20)
59332
59422
  parall tasks subtasks prll://tsk_xxx # children of a single parent task
59333
59423
 
59334
59424
  # Create a task (add --parent-id to make it a SUBTASK of another task)
59335
- parall tasks create --title "Task title" [--assignee-id prll://usr_xxx] [--parent-id prll://tsk_xxx] [--project-id prll://prj_xxx] [--due-date 2026-08-01]
59425
+ parall tasks create --title "Task title" [--assignee-id prll://usr_xxx] [--parent-id prll://tsk_xxx] [--project-id prll://prj_xxx] [--planned-start 2026-07-20] [--due-date 2026-08-01]
59336
59426
 
59337
59427
  # Update task status \u2014 add --placement end so the task lands at the end of
59338
59428
  # its NEW status column (a bare --status keeps the old column's sort_order)
@@ -59343,6 +59433,12 @@ parall tasks update prll://tsk_xxx --status done --placement end
59343
59433
  parall tasks update prll://tsk_xxx --due-date 2026-08-01
59344
59434
  parall tasks update prll://tsk_xxx --due-date none
59345
59435
 
59436
+ # Planned start \u2014 same grammar as --due-date; must be on or before the due
59437
+ # date when both are set. This is the planned schedule's left-edge date,
59438
+ # NOT when work actually began (that stays on lifecycle timestamps)
59439
+ parall tasks update prll://tsk_xxx --planned-start 2026-07-20
59440
+ parall tasks update prll://tsk_xxx --planned-start none
59441
+
59346
59442
  # Move a task to the end of its status column
59347
59443
  parall tasks update prll://tsk_xxx --placement end
59348
59444
 
@@ -191,6 +191,8 @@ var init_constants = __esm({
191
191
  MESSAGE_WATCH: (id) => `${API_BASE}/messages/${id}/watch`,
192
192
  MESSAGE_WATCHERS: (id) => `${API_BASE}/messages/${id}/watchers`,
193
193
  MESSAGE_WATCHING: (id) => `${API_BASE}/messages/${id}/watching`,
194
+ MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
195
+ MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
194
196
  // Upload (org-scoped)
195
197
  UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
196
198
  UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
@@ -428,11 +430,13 @@ var init_constants = __esm({
428
430
  UNREAD: `${API_BASE}/me/unread`,
429
431
  ORG_UNREAD: (orgId) => `${API_BASE}/orgs/${orgId}/unread`,
430
432
  CHAT_READ: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read`,
433
+ CHAT_READ_ALL: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read-all`,
431
434
  THREAD_UNREAD: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/unread`,
432
435
  THREAD_READ: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/read`,
433
436
  // References (org-scoped)
434
437
  REFS_RESOLVE: (orgId) => `${API_BASE}/orgs/${orgId}/refs/resolve`,
435
438
  REFS_BACKLINKS: (orgId) => `${API_BASE}/orgs/${orgId}/refs/backlinks`,
439
+ REFS_OUTBOUND: (orgId) => `${API_BASE}/orgs/${orgId}/refs/outbound`,
436
440
  REFS_GRAPH: (orgId) => `${API_BASE}/orgs/${orgId}/refs/graph`,
437
441
  REFS_CHECK: (orgId) => `${API_BASE}/orgs/${orgId}/refs/check`,
438
442
  // Platform config (agent-scoped, not org-scoped)
@@ -494,7 +498,13 @@ var init_constants = __esm({
494
498
  ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
495
499
  ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
496
500
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
501
+ // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
502
+ ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
497
503
  ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
504
+ // Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
505
+ // Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
506
+ // pipe. Additive: does NOT replace BROWSER_PROFILE_VIEWER_COMMAND.
507
+ ORG_EDGE_VIEWER_COMMAND: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/viewer/command`,
498
508
  CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
499
509
  CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`,
500
510
  // Clip registry (v3, org-scoped, served by api-server — `crg_` entries; the
@@ -517,6 +527,7 @@ var init_constants = __esm({
517
527
  MESSAGE_PATCH: "message.patch",
518
528
  MESSAGE_EDIT: "message.edit",
519
529
  MESSAGE_DELETE: "message.delete",
530
+ MESSAGE_REACTION_UPDATED: "message.reaction.updated",
520
531
  TYPING_UPDATE: "typing.update",
521
532
  CHAT_UPDATE: "chat.update",
522
533
  CHAT_DELETED: "chat.deleted",
@@ -558,6 +569,7 @@ var init_constants = __esm({
558
569
  INBOX_UPDATE: "inbox.update",
559
570
  INBOX_BULK_UPDATE: "inbox.bulk_update",
560
571
  READ_POSITION_UPDATED: "read_position.updated",
572
+ THREAD_READ_POSITION_UPDATED: "thread_read_position.updated",
561
573
  DISPATCH_NEW: "dispatch.new",
562
574
  DISPATCH_RECEIVED: "dispatch.received",
563
575
  DISPATCH_RESOLVED: "dispatch.resolved",
@@ -604,6 +616,9 @@ function buildApiError(res, rawErrorBody) {
604
616
  const errMsg = (typeof errorObj?.message === "string" ? errorObj.message : void 0) ?? (typeof errorBody.message === "string" ? errorBody.message : void 0) ?? (typeof errorBody.error === "string" ? errorBody.error : void 0);
605
617
  const errCode = (typeof errorObj?.code === "string" ? errorObj.code : void 0) ?? (typeof errorBody.code === "string" ? errorBody.code : void 0);
606
618
  const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
619
+ const retryAfter = Number(res.headers?.get("Retry-After"));
620
+ if (Number.isFinite(retryAfter) && retryAfter > 0)
621
+ apiError.retryAfterSeconds = retryAfter;
607
622
  const anchors = errorObj ?? errorBody;
608
623
  if (typeof anchors.action === "string")
609
624
  apiError.action = anchors.action;
@@ -784,7 +799,7 @@ var init_client = __esm({
784
799
  if (qs)
785
800
  url += `?${qs}`;
786
801
  }
787
- const headers = this.buildHeaders(path23);
802
+ const headers = this.buildHeaders(path23, opts?.headers);
788
803
  const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
789
804
  const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
790
805
  let res;
@@ -1190,6 +1205,14 @@ var init_client = __esm({
1190
1205
  async getMessageReplies(id, params) {
1191
1206
  return this.request("GET", ENDPOINTS.MESSAGE_REPLIES(id), void 0, params);
1192
1207
  }
1208
+ // ---- Reactions ----
1209
+ async toggleReaction(messageId, emoji) {
1210
+ return this.request("PUT", ENDPOINTS.MESSAGE_REACTION(messageId, emoji));
1211
+ }
1212
+ async listReactions(messageId) {
1213
+ const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
1214
+ return res.reactions;
1215
+ }
1193
1216
  // ---- File Upload ----
1194
1217
  async getUploadPresignUrl(orgId, req) {
1195
1218
  return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
@@ -1565,6 +1588,15 @@ var init_client = __esm({
1565
1588
  async browserViewerCommand(orgId, profileId, req, opts) {
1566
1589
  return this.request("POST", ENDPOINTS.BROWSER_PROFILE_VIEWER_COMMAND(orgId, profileId), req, void 0, false, opts);
1567
1590
  }
1591
+ /**
1592
+ * Drive the Cloud Edge live viewer (V1b, design §6): WebRTC signaling + input +
1593
+ * tab nav for a hosted browser (Cloud Profile). Same request/reply shape as
1594
+ * browserViewerCommand, on the v3 edge pipe; additive — the v2 browser-profile
1595
+ * viewer is unchanged.
1596
+ */
1597
+ async edgeViewerCommand(orgId, edgeId, req, opts) {
1598
+ return this.request("POST", ENDPOINTS.ORG_EDGE_VIEWER_COMMAND(orgId, edgeId), req, void 0, false, opts);
1599
+ }
1568
1600
  async resizeMachine(orgId, machineId, spec) {
1569
1601
  return this.request("PATCH", ENDPOINTS.MACHINE_SPEC(orgId, machineId), spec);
1570
1602
  }
@@ -1591,14 +1623,23 @@ var init_client = __esm({
1591
1623
  }
1592
1624
  // Wiki mount/token methods removed — wiki-service handles all wiki endpoints.
1593
1625
  // ---- Unread ----
1594
- async getUnreadCounts(orgId) {
1626
+ async getUnreadCounts(orgId, opts) {
1595
1627
  const endpoint = orgId ? ENDPOINTS.ORG_UNREAD(orgId) : ENDPOINTS.UNREAD;
1596
- const res = await this.request("GET", endpoint);
1628
+ const res = await this.request("GET", endpoint, void 0, {
1629
+ include_thread_replies: opts?.includeThreadReplies ? "true" : void 0
1630
+ });
1597
1631
  return res.data;
1598
1632
  }
1599
1633
  async markRead(orgId, chatId, messageId) {
1600
1634
  return this.request("POST", ENDPOINTS.CHAT_READ(orgId, chatId), { message_id: messageId });
1601
1635
  }
1636
+ /** Mark everything in a chat read: the channel cursor jumps to the latest
1637
+ * top-level message and every thread cursor to its latest reply, in one
1638
+ * idempotent call. The server echoes the same per-cursor WS events the
1639
+ * single-cursor routes emit and auto-clears covered inbox items. */
1640
+ async markAllRead(orgId, chatId) {
1641
+ return this.request("POST", ENDPOINTS.CHAT_READ_ALL(orgId, chatId));
1642
+ }
1602
1643
  async getThreadUnread(orgId, chatId, threadRootId) {
1603
1644
  return this.request("GET", ENDPOINTS.THREAD_UNREAD(orgId, chatId, threadRootId));
1604
1645
  }
@@ -2273,6 +2314,16 @@ var init_client = __esm({
2273
2314
  async getBacklinks(orgId, params) {
2274
2315
  return this.request("GET", ENDPOINTS.REFS_BACKLINKS(orgId), void 0, params);
2275
2316
  }
2317
+ /**
2318
+ * Outbound prll:// refs authored in a set of sources, as raw ref_links rows
2319
+ * (dedupe/group client-side). Pass `{ thread_root_id }` to list a whole
2320
+ * thread's refs (root + all replies, resolved server-side — the client's
2321
+ * reply window may be partial), or `{ source_type, source_ids }` for
2322
+ * explicit sources (max 500; v1 accepts only message sources).
2323
+ */
2324
+ async listOutboundRefs(orgId, req) {
2325
+ return this.request("POST", ENDPOINTS.REFS_OUTBOUND(orgId), req);
2326
+ }
2276
2327
  /**
2277
2328
  * Bounded multi-hop walk of the prll:// reference graph around `uri`. `uri`
2278
2329
  * must be an entity-level prll:// URI — a refined URI (path/query/fragment) is
@@ -2552,6 +2603,43 @@ var init_client = __esm({
2552
2603
  async listEdgeProfiles(orgId, edgeId) {
2553
2604
  return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
2554
2605
  }
2606
+ /**
2607
+ * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
2608
+ * human maintainer or org admin). Sanitized — the password never comes back.
2609
+ * Typed errors: `EDGE_NOT_HOSTED` (BYOC device), `PROXY_CONFIG_CORRUPT` /
2610
+ * validation codes as 422 when a stored config no longer passes current rules.
2611
+ * `can_mutate` and `lease_status` are the authoritative idle gate; device
2612
+ * list status is not a substitute.
2613
+ */
2614
+ async getEdgeProfileProxy(orgId, edgeId, profileName) {
2615
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName));
2616
+ }
2617
+ /**
2618
+ * Set/replace the profile's egress proxy (full triple every time) — IDLE
2619
+ * ONLY: while the profile's hosted browser is running (a viewer session is
2620
+ * open or a pod is otherwise live) the server answers 409
2621
+ * `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle scale-to-zero, and
2622
+ * retry. The next cold start uses the new egress; browser login state is
2623
+ * preserved across it. Other typed errors: the validation vocabulary
2624
+ * (`INVALID_PROXY_SERVER`, `PROXY_AUTH_INCOMPLETE`,
2625
+ * `PROXY_SERVER_FORBIDDEN_TARGET`, …), `EDGE_DELETING` (409), and
2626
+ * `SECRETBOX_UNCONFIGURED` (503 — server cannot store credentials safely),
2627
+ * and `EDGE_PROFILE_PROXY_STALE` (409 — expectedVersion lost a tab race).
2628
+ */
2629
+ async setEdgeProfileProxy(orgId, edgeId, profileName, req, expectedVersion) {
2630
+ return this.request("PUT", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), req, void 0, false, {
2631
+ headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
2632
+ });
2633
+ }
2634
+ /**
2635
+ * Clear the profile's egress proxy; the next pod start egresses directly.
2636
+ * Idle-only like set — 409 `EDGE_PROFILE_IN_USE` while the browser is live.
2637
+ */
2638
+ async clearEdgeProfileProxy(orgId, edgeId, profileName, expectedVersion) {
2639
+ return this.request("DELETE", ENDPOINTS.ORG_EDGE_PROFILE_PROXY(orgId, edgeId, profileName), void 0, void 0, false, {
2640
+ headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
2641
+ });
2642
+ }
2555
2643
  /**
2556
2644
  * Execute a registry clip command on an Edge device.
2557
2645
  *
@@ -2613,6 +2701,8 @@ var init_client = __esm({
2613
2701
  status;
2614
2702
  code;
2615
2703
  extras;
2704
+ /** Retry-After delta seconds when the server supplies one. */
2705
+ retryAfterSeconds;
2616
2706
  /** Attempted action (authorization denials) — e.g. "chat.add_member". */
2617
2707
  action;
2618
2708
  /** Target resource URI that was evaluated — e.g. "prll://cht_…". */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/daemon",
3
- "version": "1.48.0",
3
+ "version": "1.49.0",
4
4
  "description": "Parall local agent runtime — daemon supervisor + bridge runtimes, bundled as standalone JS files",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,11 +33,11 @@
33
33
  "@aws-sdk/client-s3": "3.984.0",
34
34
  "@pinixai/bb-browser-pro": "0.15.0",
35
35
  "ws": "^8.18.0",
36
- "@parall/sdk": "1.48.0",
37
- "@parall/codex-agent": "1.48.0",
38
- "@parall/openclaw-agent": "1.48.0",
39
- "@parall/claude-agent": "1.48.0",
40
- "@parall/agent-core": "1.48.0"
36
+ "@parall/agent-core": "1.49.0",
37
+ "@parall/sdk": "1.49.0",
38
+ "@parall/codex-agent": "1.49.0",
39
+ "@parall/openclaw-agent": "1.49.0",
40
+ "@parall/claude-agent": "1.49.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^22.0.0",