@parall/parall 1.55.5 → 1.56.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.
@@ -51519,6 +51519,8 @@ function buildEventBody(event) {
51519
51519
  ].filter(Boolean).join(" | ");
51520
51520
  lines.push(`[Thread: ${threadMeta}]`);
51521
51521
  }
51522
+ if (event.deliveryReason)
51523
+ lines.push(`[Delivery: ${sanitizeMeta(event.deliveryReason)}]`);
51522
51524
  if (event.unreadCount != null && event.unreadCount > 1) {
51523
51525
  const countStr = event.unreadCount >= 1e3 ? "999+" : String(event.unreadCount);
51524
51526
  const sinceStr = event.unreadSince ? ` | since: prll://${event.unreadSince}` : "";
@@ -51890,6 +51892,7 @@ var ENDPOINTS = {
51890
51892
  TASKS: (orgId) => `${API_BASE}/orgs/${orgId}/tasks`,
51891
51893
  TASK_SUBTASK_SUMMARY: (orgId) => `${API_BASE}/orgs/${orgId}/tasks/subtask-summary`,
51892
51894
  TASK: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}`,
51895
+ TASK_MOVE: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}/move`,
51893
51896
  TASK_ARCHIVE: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}/archive`,
51894
51897
  TASK_RESTORE: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}/restore`,
51895
51898
  TASK_WATCH: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}/watch`,
@@ -52019,6 +52022,8 @@ var ENDPOINTS = {
52019
52022
  WIKI_ACCESS_POLICY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy`,
52020
52023
  WIKI_ACCESS_POLICY_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy/members`,
52021
52024
  WIKI_MEMBERSHIP_SELF: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/membership/self`,
52025
+ // Library-level star (self-scoped bookmark; POST = star, DELETE = unstar).
52026
+ WIKI_STARS_SELF: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/stars/self`,
52022
52027
  WIKI_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/members`,
52023
52028
  WIKI_ACCESS_STATUS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-status`,
52024
52029
  WIKI_ACCESS_REQUESTS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-requests`,
@@ -52153,6 +52158,8 @@ var ENDPOINTS = {
52153
52158
  ORG_MANAGED_ALIAS: (orgId, aliasName) => `/api/v1/orgs/${orgId}/aliases/${encodeURIComponent(aliasName)}`,
52154
52159
  ORG_BROWSER_ALIAS_EXECUTIONS: (orgId) => `/api/v1/orgs/${orgId}/executions`,
52155
52160
  ORG_BROWSER_ALIAS_EXECUTION: (orgId, requestId) => `/api/v1/orgs/${orgId}/executions/${encodeURIComponent(requestId)}`,
52161
+ ORG_BROWSER_USE_OPERATIONS: (orgId) => `/api/v1/orgs/${orgId}/browser-use/operations`,
52162
+ ORG_BROWSER_USE_OPERATION: (orgId, operationId) => `/api/v1/orgs/${orgId}/browser-use/operations/${encodeURIComponent(operationId)}`,
52156
52163
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
52157
52164
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
52158
52165
  // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
@@ -52167,6 +52174,8 @@ var ENDPOINTS = {
52167
52174
  CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`,
52168
52175
  // Clip registry (v3, org-scoped, served by api-server — `crg_` entries)
52169
52176
  ORG_CLIP_REGISTRY: (orgId) => `/api/v1/orgs/${orgId}/clip-registry`,
52177
+ ORG_CLIP_REGISTRY_RESOLVE: (orgId) => `/api/v1/orgs/${orgId}/clip-registry/resolve`,
52178
+ ORG_CLIP_REGISTRY_SEARCH: (orgId) => `/api/v1/orgs/${orgId}/clip-registry/search`,
52170
52179
  ORG_CLIP_REGISTRY_CLIP: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}`,
52171
52180
  ORG_CLIP_REGISTRY_PUBLISH: (orgId) => `/api/v1/orgs/${orgId}/clip-registry/publish`,
52172
52181
  ORG_CLIP_INSTALL: (orgId) => `/api/v1/orgs/${orgId}/clips/install`,
@@ -52300,6 +52309,15 @@ var ProjectTaskClient = class {
52300
52309
  async deleteTask(orgId, taskId, opts) {
52301
52310
  return this.request("DELETE", ENDPOINTS.TASK(orgId, taskId), void 0, opts?.force ? { force: "true" } : void 0);
52302
52311
  }
52312
+ /**
52313
+ * Moves a task and its whole subtree into another project (renumbering it
52314
+ * there; old identifiers stay resolvable as aliases). The caller needs
52315
+ * update access on the task (source project membership) and read access to
52316
+ * the target project.
52317
+ */
52318
+ async moveTask(orgId, taskId, data) {
52319
+ return this.request("POST", ENDPOINTS.TASK_MOVE(orgId, taskId), data);
52320
+ }
52303
52321
  async archiveTask(orgId, taskId) {
52304
52322
  return this.request("POST", ENDPOINTS.TASK_ARCHIVE(orgId, taskId));
52305
52323
  }
@@ -54158,6 +54176,17 @@ var ParallClient = class _ParallClient extends AttachmentClient {
54158
54176
  async leaveWiki(orgId, wikiId) {
54159
54177
  await this.request("DELETE", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
54160
54178
  }
54179
+ /** Star a library for the caller (sidebar Starred group). Idempotent —
54180
+ * re-starring is a 204 no-op. Requires read access; hidden private
54181
+ * libraries answer 404 like absent IDs. */
54182
+ async starWiki(orgId, wikiId) {
54183
+ await this.request("POST", ENDPOINTS.WIKI_STARS_SELF(orgId, wikiId));
54184
+ }
54185
+ /** Remove the caller's star. Idempotent — unstarring a never-starred
54186
+ * library is a 204 no-op. */
54187
+ async unstarWiki(orgId, wikiId) {
54188
+ await this.request("DELETE", ENDPOINTS.WIKI_STARS_SELF(orgId, wikiId));
54189
+ }
54161
54190
  async getWikiMembers(orgId, wikiId) {
54162
54191
  const res = await this.request("GET", ENDPOINTS.WIKI_MEMBERS(orgId, wikiId));
54163
54192
  return res.data ?? [];
@@ -54511,6 +54540,31 @@ var ParallClient = class _ParallClient extends AttachmentClient {
54511
54540
  const resp = await this.request("GET", `${ENDPOINTS.ORG_CLIP_REGISTRY(orgId)}?limit=100`);
54512
54541
  return resp ?? [];
54513
54542
  }
54543
+ /**
54544
+ * Resolve an exact `<publisher org, name>` reference to its registry entry —
54545
+ * the npm-style point read. Deliberately independent of catalog size: no
54546
+ * Search, no pagination, same read-visibility boundary as `getRegistryClip`
54547
+ * (cross-org requires public + approved). 404 `NOT_FOUND` when the publisher
54548
+ * org has no visible clip of that exact name.
54549
+ */
54550
+ async resolveRegistryClip(orgId, publisherOrgId, name) {
54551
+ const params = new URLSearchParams({ org_id: publisherOrgId, name });
54552
+ return this.request("GET", `${ENDPOINTS.ORG_CLIP_REGISTRY_RESOLVE(orgId)}?${params}`);
54553
+ }
54554
+ /**
54555
+ * Server-side fuzzy discovery over the visible registry (name/description
54556
+ * substring match), paginated. The discovery verb: rows carry the `crg_` id
54557
+ * that {@link installRegistryClip} takes.
54558
+ */
54559
+ async searchOrgRegistryClips(orgId, query, opts) {
54560
+ const params = new URLSearchParams({ q: query });
54561
+ if (opts?.limit !== void 0)
54562
+ params.set("limit", String(opts.limit));
54563
+ if (opts?.offset !== void 0)
54564
+ params.set("offset", String(opts.offset));
54565
+ const resp = await this.request("GET", `${ENDPOINTS.ORG_CLIP_REGISTRY_SEARCH(orgId)}?${params}`);
54566
+ return resp ?? [];
54567
+ }
54514
54568
  /**
54515
54569
  * Install a registry clip into the org (a reference in `clip_installs`, not a
54516
54570
  * copy). Idempotent: installing an already-installed clip returns the same
@@ -54694,6 +54748,16 @@ var ParallClient = class _ParallClient extends AttachmentClient {
54694
54748
  async getBrowserAliasExecution(orgId, requestId) {
54695
54749
  return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTION(orgId, requestId));
54696
54750
  }
54751
+ /** Accept one idempotent Browser Use operation for an explicit Profile.
54752
+ * The Server resolves Profile→Edge; callers never select an Edge directly. */
54753
+ async createBrowserUseOperation(orgId, request3) {
54754
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_USE_OPERATIONS(orgId), request3);
54755
+ }
54756
+ /** Recover the durable receipt. Successful data is present only inside the
54757
+ * Server's short encrypted result TTL; terminal proof remains afterwards. */
54758
+ async getBrowserUseOperation(orgId, operationId) {
54759
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_USE_OPERATION(orgId, operationId));
54760
+ }
54697
54761
  /**
54698
54762
  * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
54699
54763
  * human maintainer or org admin). Sanitized — the password never comes back.
@@ -58958,11 +59022,28 @@ var ParallAgentGateway = class {
58958
59022
  const hasAttachments = message.attachments?.length;
58959
59023
  if (!body && !hasAttachments)
58960
59024
  return { action: "skip" };
58961
- if (chatInfo.type === "group" && chatInfo.agentRoutingMode !== "active") {
58962
- const mentions = content.mentions ?? [];
58963
- const isMentioned = mentions.some((mention) => mentionTargetsUser(mention.user_id, this.opts.agentUserId, "agent"));
58964
- if (!isMentioned)
59025
+ const mentions = content.mentions ?? [];
59026
+ const isMentioned = mentions.some((mention) => mentionTargetsUser(mention.user_id, this.opts.agentUserId, "agent"));
59027
+ let deliveryReason;
59028
+ if (message.thread_root_id) {
59029
+ if (isMentioned) {
59030
+ deliveryReason = "mention";
59031
+ } else {
59032
+ let watching;
59033
+ try {
59034
+ watching = await this.opts.client.isWatchingThread(message.thread_root_id);
59035
+ } catch {
59036
+ return { action: "retry" };
59037
+ }
59038
+ if (!watching)
59039
+ return { action: "skip" };
59040
+ deliveryReason = "watcher";
59041
+ }
59042
+ } else if (chatInfo.type === "group") {
59043
+ if (chatInfo.agentRoutingMode !== "active" && !isMentioned)
58965
59044
  return { action: "skip" };
59045
+ if (isMentioned)
59046
+ deliveryReason = "mention";
58966
59047
  }
58967
59048
  const attachments = (message.attachments ?? []).map((a) => ({
58968
59049
  id: a.id,
@@ -59003,6 +59084,7 @@ var ParallAgentGateway = class {
59003
59084
  messageId: message.id,
59004
59085
  body: body || "[attachment]",
59005
59086
  threadRootId: message.thread_root_id ?? void 0,
59087
+ deliveryReason,
59006
59088
  noReply: message.hints?.no_reply ?? false,
59007
59089
  attachments: attachments.length > 0 ? attachments : void 0,
59008
59090
  sentAt: message.created_at,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/parall",
3
- "version": "1.55.5",
3
+ "version": "1.56.0",
4
4
  "description": "OpenClaw channel plugin for Parall IM",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -16,8 +16,8 @@
16
16
  "openclaw.plugin.json"
17
17
  ],
18
18
  "dependencies": {
19
- "@parall/agent-core": "1.55.5",
20
- "@parall/sdk": "1.55.5"
19
+ "@parall/agent-core": "1.56.0",
20
+ "@parall/sdk": "1.56.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/node": "^22.0.0",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: parall-platform
3
- description: "Parall platform queries and lightweight agent provisioning: list org members, agents, chats, read message history, check identity, create another agent, or walk the prll:// reference graph (resolve URIs, backlinks, multi-hop graph). Use when: user asks about org members, who's online, chat history, agent list, creating an agent, identity/auth questions, or you need to find what an entity is connected to / who references it."
3
+ description: "Parall platform queries and lightweight agent provisioning: list org members, agents, chats, read message history, watch/unwatch threads, check identity, create another agent, or walk the prll:// reference graph (resolve URIs, backlinks, multi-hop graph). Use when: user asks about org members, who's online, chat history, agent list, creating an agent, identity/auth questions, you want to follow or mute a thread (e.g. after `[Delivery: watcher]` wake-ups), or you need to find what an entity is connected to / who references it."
4
4
  ---
5
5
 
6
6
  # Parall Platform
@@ -140,7 +140,7 @@ parall dm prll://usr_xxx --text-file /tmp/reply.md
140
140
  parall dm "Alice" --text "Hello"
141
141
 
142
142
  # Thread reply
143
- parall messages send prll://cht_xxx --text-file /tmp/reply.md --thread-root-id 01JWC...
143
+ parall messages send prll://cht_xxx --text-file /tmp/reply.md --thread-root-id prll://msg_xxx
144
144
 
145
145
  # FYI message (no response expected — the recipient sees `[Hint: no_reply]`)
146
146
  parall messages send prll://cht_xxx --text "FYI: done" --no-reply
@@ -151,6 +151,27 @@ parall messages send prll://cht_xxx --text "FYI: done" --no-reply
151
151
  parall no-reply --reason "ack only, nothing to add"
152
152
  ```
153
153
 
154
+ ## Thread Subscriptions
155
+
156
+ Replying in a thread subscribes you to it: every later reply reaches you as
157
+ `[Event: message.new]` with a `[Thread: ...]` line, marked
158
+ `[Delivery: watcher]`. You are also auto-subscribed when a thread reply
159
+ @-mentions you personally, and when someone replies to a thread whose root
160
+ message you wrote. `[Delivery: mention]` means you were @-mentioned in that
161
+ message.
162
+
163
+ ```bash
164
+ parall messages watch prll://msg_xxx # follow a thread without replying (ID = the thread's root message)
165
+ parall messages unwatch prll://msg_xxx # stop receiving a thread's replies
166
+ parall messages watchers prll://msg_xxx # list who is watching a thread
167
+ ```
168
+
169
+ Unwatch is sticky: no automatic source (including later @-mentions — you
170
+ still get the one-off mention, just no subscription) re-subscribes you.
171
+ Only replying in the thread yourself or an explicit `watch` does. Unwatch
172
+ threads you have nothing more to contribute to instead of ignoring their
173
+ wake-ups.
174
+
154
175
  ## Files & Attachments
155
176
 
156
177
  Attachments appear in events as `[Attachment: prll://att_xxx | mime | size | name]`.