@parall/parall 1.55.4 → 1.55.5

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 (2) hide show
  1. package/dist/index.bundle.mjs +195 -17
  2. package/package.json +3 -3
@@ -51496,6 +51496,12 @@ function isForwardedMessageBody(body) {
51496
51496
  function sanitizeMeta(value) {
51497
51497
  return value.replace(/[\r\n]+/g, " ").replace(/[[\]|]/g, " ").trim();
51498
51498
  }
51499
+ function formatApprovalDecisionReason(status, reason) {
51500
+ const normalized = reason?.trim();
51501
+ if (status !== "rejected" || !normalized)
51502
+ return "";
51503
+ return `Reason (JSON): ${JSON.stringify(normalized)}`;
51504
+ }
51499
51505
  function buildEventBody(event) {
51500
51506
  const lines = [];
51501
51507
  if (event.type === "message") {
@@ -51716,6 +51722,16 @@ function browserViewerRequestOptions(command, opts) {
51716
51722
  };
51717
51723
  }
51718
51724
 
51725
+ // ../sdk/dist/attachment-endpoints.js
51726
+ function attachmentEndpoints(apiBase) {
51727
+ return {
51728
+ UPLOAD_PRESIGN: (orgId) => `${apiBase}/orgs/${orgId}/upload/presign`,
51729
+ UPLOAD_COMPLETE: (orgId) => `${apiBase}/orgs/${orgId}/upload/complete`,
51730
+ UPLOAD_ABORT: (orgId) => `${apiBase}/orgs/${orgId}/upload/abort`,
51731
+ FILE: (id) => `${apiBase}/files/${id}`
51732
+ };
51733
+ }
51734
+
51719
51735
  // ../sdk/dist/constants.js
51720
51736
  var API_BASE = "/api/v1";
51721
51737
  var WIKI_BASE = "/wiki/v1";
@@ -51788,9 +51804,7 @@ var ENDPOINTS = {
51788
51804
  MESSAGE_REACTIONS: (id) => `${API_BASE}/messages/${id}/reactions`,
51789
51805
  MESSAGE_REACTION: (id, emoji) => `${API_BASE}/messages/${id}/reactions/${encodeURIComponent(emoji)}`,
51790
51806
  // Upload (org-scoped)
51791
- UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
51792
- UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
51793
- FILE: (id) => `${API_BASE}/files/${id}`,
51807
+ ...attachmentEndpoints(API_BASE),
51794
51808
  // Approval requests (org-scoped)
51795
51809
  APPROVAL_REQUESTS: (orgId) => `${API_BASE}/orgs/${orgId}/approval-requests`,
51796
51810
  // Approvals (global)
@@ -51971,6 +51985,8 @@ var ENDPOINTS = {
51971
51985
  // backend router so `deleted` isn't captured as a {wikiId}; the SDK builder
51972
51986
  // is just a string.
51973
51987
  WIKIS_DELETED: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wikis/deleted`,
51988
+ // Org-wide changeset listing across readable wikis (Working on tab).
51989
+ WIKI_ORG_CHANGESETS: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wiki-changesets`,
51974
51990
  // Detail URL — also reused for DELETE (soft-delete) and `${WIKI}/restore`.
51975
51991
  WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
51976
51992
  WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
@@ -52000,6 +52016,10 @@ var ENDPOINTS = {
52000
52016
  // Wiki Path Restrictions (AFCS narrowing ACL — private subtrees)
52001
52017
  WIKI_RESTRICTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions`,
52002
52018
  WIKI_RESTRICTION: (orgId, wikiId, restrictionId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions/${restrictionId}`,
52019
+ WIKI_ACCESS_POLICY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy`,
52020
+ WIKI_ACCESS_POLICY_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-policy/members`,
52021
+ WIKI_MEMBERSHIP_SELF: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/membership/self`,
52022
+ WIKI_MEMBERS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/members`,
52003
52023
  WIKI_ACCESS_STATUS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-status`,
52004
52024
  WIKI_ACCESS_REQUESTS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-requests`,
52005
52025
  // Wiki History (commits, file commits, blame)
@@ -52120,6 +52140,19 @@ var ENDPOINTS = {
52120
52140
  ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
52121
52141
  ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
52122
52142
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
52143
+ ORG_EDGE_PROFILE_OPERATIONS: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations`,
52144
+ ORG_EDGE_PROFILE_OPERATION: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}`,
52145
+ ORG_EDGE_PROFILE_OPERATION_CONFIRM: (orgId, edgeId, operationId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profile-operations/${operationId}/confirm`,
52146
+ ORG_BROWSER_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/browser-aliases`,
52147
+ ORG_BROWSER_ALIAS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}`,
52148
+ ORG_BROWSER_ALIAS_READINESS_CHECKS: (orgId, aliasId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks`,
52149
+ ORG_BROWSER_ALIAS_READINESS_CHECK: (orgId, aliasId, checkId) => `/api/v1/orgs/${orgId}/browser-aliases/${aliasId}/readiness-checks/${checkId}`,
52150
+ ORG_API_KEY_BROWSER_ALIAS_GRANTS: (orgId, keyId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants`,
52151
+ ORG_API_KEY_BROWSER_ALIAS_GRANT: (orgId, keyId, aliasId) => `/api/v1/orgs/${orgId}/api-keys/${keyId}/browser-alias-grants/${aliasId}`,
52152
+ ORG_MANAGED_ALIASES: (orgId) => `/api/v1/orgs/${orgId}/aliases`,
52153
+ ORG_MANAGED_ALIAS: (orgId, aliasName) => `/api/v1/orgs/${orgId}/aliases/${encodeURIComponent(aliasName)}`,
52154
+ ORG_BROWSER_ALIAS_EXECUTIONS: (orgId) => `/api/v1/orgs/${orgId}/executions`,
52155
+ ORG_BROWSER_ALIAS_EXECUTION: (orgId, requestId) => `/api/v1/orgs/${orgId}/executions/${encodeURIComponent(requestId)}`,
52123
52156
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
52124
52157
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
52125
52158
  // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
@@ -52470,8 +52503,44 @@ var WechatClient = class extends TaskLabelClient {
52470
52503
  }
52471
52504
  };
52472
52505
 
52506
+ // ../sdk/dist/attachment-client.js
52507
+ var COMPLETION_RETRY_DELAYS_MS = [250, 750];
52508
+ function isRetryableCompletionError(error) {
52509
+ if (!error || typeof error !== "object" || !("status" in error))
52510
+ return false;
52511
+ const status = error.status;
52512
+ return status === 0 || typeof status === "number" && status >= 500;
52513
+ }
52514
+ var AttachmentClient = class extends WechatClient {
52515
+ async getUploadPresignUrl(orgId, req) {
52516
+ return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
52517
+ }
52518
+ async completeUpload(orgId, attachmentId, parts) {
52519
+ const body = {
52520
+ attachment_id: attachmentId,
52521
+ parts
52522
+ };
52523
+ for (let attempt = 0; ; attempt += 1) {
52524
+ try {
52525
+ return await this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), body);
52526
+ } catch (error) {
52527
+ const delay = COMPLETION_RETRY_DELAYS_MS[attempt];
52528
+ if (delay === void 0 || !isRetryableCompletionError(error))
52529
+ throw error;
52530
+ await new Promise((resolve3) => setTimeout(resolve3, delay));
52531
+ }
52532
+ }
52533
+ }
52534
+ async abortUpload(orgId, attachmentId) {
52535
+ return this.request("POST", ENDPOINTS.UPLOAD_ABORT(orgId), { attachment_id: attachmentId });
52536
+ }
52537
+ async getFileUrl(id, opts) {
52538
+ return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
52539
+ }
52540
+ };
52541
+
52473
52542
  // ../sdk/dist/client.js
52474
- var ParallClient = class _ParallClient extends WechatClient {
52543
+ var ParallClient = class _ParallClient extends AttachmentClient {
52475
52544
  baseUrl;
52476
52545
  wikiBaseUrl;
52477
52546
  token;
@@ -53118,16 +53187,6 @@ var ParallClient = class _ParallClient extends WechatClient {
53118
53187
  const res = await this.request("GET", ENDPOINTS.MESSAGE_REACTIONS(messageId));
53119
53188
  return res.reactions;
53120
53189
  }
53121
- // ---- File Upload ----
53122
- async getUploadPresignUrl(orgId, req) {
53123
- return this.request("POST", ENDPOINTS.UPLOAD_PRESIGN(orgId), req);
53124
- }
53125
- async completeUpload(orgId, attachmentId) {
53126
- return this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), { attachment_id: attachmentId });
53127
- }
53128
- async getFileUrl(id, opts) {
53129
- return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
53130
- }
53131
53190
  // ---- Approvals ----
53132
53191
  async getApproval(id) {
53133
53192
  return this.request("GET", ENDPOINTS.APPROVAL(id));
@@ -53135,8 +53194,14 @@ var ParallClient = class _ParallClient extends WechatClient {
53135
53194
  async requestApproval(orgId, req) {
53136
53195
  return this.request("POST", ENDPOINTS.APPROVAL_REQUESTS(orgId), req);
53137
53196
  }
53138
- async decideApproval(id, decision) {
53139
- return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), { decision });
53197
+ async decideApproval(id, decision, reason) {
53198
+ if (decision === "approve" && reason?.trim()) {
53199
+ throw new ApiError(400, "Approval reason is only allowed for rejection decisions", "INVALID_DECISION_REASON");
53200
+ }
53201
+ return this.request("POST", ENDPOINTS.APPROVAL_DECIDE(id), {
53202
+ decision,
53203
+ ...decision === "reject" && reason !== void 0 ? { reason } : {}
53204
+ });
53140
53205
  }
53141
53206
  async cancelApproval(id) {
53142
53207
  return this.request("POST", ENDPOINTS.APPROVAL_CANCEL(id));
@@ -53969,6 +54034,17 @@ var ParallClient = class _ParallClient extends WechatClient {
53969
54034
  const res = await this.request("GET", ENDPOINTS.WIKI_CHANGESETS(orgId, wikiId));
53970
54035
  return res.data.map(normalizeWikiChangeset);
53971
54036
  }
54037
+ /** Org-wide changeset listing across every wiki the caller can read.
54038
+ * Server default (no `status`) is the pending set: proposed,
54039
+ * approval_pending, approved. */
54040
+ async getOrgWikiChangesets(orgId, opts) {
54041
+ const params = new URLSearchParams();
54042
+ for (const s of opts?.status ?? [])
54043
+ params.append("status", s);
54044
+ const qs = params.toString();
54045
+ const res = await this.request("GET", `${ENDPOINTS.WIKI_ORG_CHANGESETS(orgId)}${qs ? `?${qs}` : ""}`);
54046
+ return (res.data ?? []).map(normalizeWikiChangeset);
54047
+ }
53972
54048
  async getWikiChangeset(orgId, wikiId, changesetId) {
53973
54049
  return normalizeWikiChangeset(await this.request("GET", ENDPOINTS.WIKI_CHANGESET(orgId, wikiId, changesetId)));
53974
54050
  }
@@ -54057,6 +54133,35 @@ var ParallClient = class _ParallClient extends WechatClient {
54057
54133
  async getWikiAccessStatus(orgId, wikiId, path9) {
54058
54134
  return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path9 ? { path: path9 } : void 0);
54059
54135
  }
54136
+ // ---- Wiki membership projection (who-can-access, invites, join/leave) ----
54137
+ async getWikiAccessPolicy(orgId, wikiId, path9 = "") {
54138
+ return this.request("GET", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), void 0, path9 ? { path: path9 } : void 0);
54139
+ }
54140
+ async putWikiAccessPolicy(orgId, wikiId, policy) {
54141
+ return this.request("PUT", ENDPOINTS.WIKI_ACCESS_POLICY(orgId, wikiId), policy);
54142
+ }
54143
+ /** Add-only invite (viewer/editor); allowed for managers, and for editors
54144
+ * when the library enables editors_can_invite. */
54145
+ async addWikiMember(orgId, wikiId, subject, role) {
54146
+ await this.request("POST", ENDPOINTS.WIKI_ACCESS_POLICY_MEMBERS(orgId, wikiId), {
54147
+ subject,
54148
+ role
54149
+ });
54150
+ }
54151
+ /** Join a PUBLIC library as an explicit member (lands at the library's
54152
+ * default role). Restricted libraries answer 409 JOIN_REQUIRES_REQUEST —
54153
+ * go through createWikiAccessRequest instead. */
54154
+ async joinWiki(orgId, wikiId) {
54155
+ await this.request("POST", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
54156
+ }
54157
+ /** Remove the caller's explicit membership (team-granted membership stays). */
54158
+ async leaveWiki(orgId, wikiId) {
54159
+ await this.request("DELETE", ENDPOINTS.WIKI_MEMBERSHIP_SELF(orgId, wikiId));
54160
+ }
54161
+ async getWikiMembers(orgId, wikiId) {
54162
+ const res = await this.request("GET", ENDPOINTS.WIKI_MEMBERS(orgId, wikiId));
54163
+ return res.data ?? [];
54164
+ }
54060
54165
  async createWikiAccessRequest(orgId, wikiId, data) {
54061
54166
  await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data);
54062
54167
  }
@@ -54519,6 +54624,76 @@ var ParallClient = class _ParallClient extends WechatClient {
54519
54624
  async listEdgeProfiles(orgId, edgeId) {
54520
54625
  return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
54521
54626
  }
54627
+ /** Start one durable Local BYOC Profile operation. Network-unknown callers
54628
+ * must retry with the same key or recover by operation id; a different body
54629
+ * under the same key is rejected. */
54630
+ async createEdgeProfileOperation(orgId, edgeId, request3, idempotencyKey) {
54631
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATIONS(orgId, edgeId), request3, void 0, false, { headers: { "Idempotency-Key": idempotencyKey } });
54632
+ }
54633
+ /** Strong-confirm the exact durable Delete impact. A changed impact returns
54634
+ * PROFILE_DELETE_IMPACT_CHANGED with a replacement receipt in
54635
+ * `ApiError.extras.details.operation`. */
54636
+ async confirmEdgeProfileOperation(orgId, edgeId, operationId, request3) {
54637
+ return this.request("POST", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION_CONFIRM(orgId, edgeId, operationId), request3);
54638
+ }
54639
+ /** Sole read/recovery surface. The server may reconcile an already durable
54640
+ * dispatch/finalization while returning this receipt. */
54641
+ async getEdgeProfileOperation(orgId, edgeId, operationId) {
54642
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_OPERATION(orgId, edgeId, operationId));
54643
+ }
54644
+ /** Create and atomically materialize one Local BYOC Browser Alias. A replay
54645
+ * with the same idempotency key and body returns the original stable ccn_. */
54646
+ async createBrowserAlias(orgId, request3) {
54647
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIASES(orgId), request3);
54648
+ }
54649
+ async listBrowserAliases(orgId) {
54650
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIASES(orgId));
54651
+ }
54652
+ async getBrowserAlias(orgId, aliasId) {
54653
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId));
54654
+ }
54655
+ async renameBrowserAlias(orgId, aliasId, request3) {
54656
+ return this.request("PATCH", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
54657
+ }
54658
+ async deleteBrowserAlias(orgId, aliasId, request3) {
54659
+ return this.request("DELETE", ENDPOINTS.ORG_BROWSER_ALIAS(orgId, aliasId), request3);
54660
+ }
54661
+ /** Start one durable readiness check. The key is carried as the standard
54662
+ * Idempotency-Key header; the request body is intentionally empty. */
54663
+ async createBrowserAliasReadinessCheck(orgId, aliasId, request3) {
54664
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECKS(orgId, aliasId), void 0, void 0, false, { headers: { "Idempotency-Key": request3.idempotency_key } });
54665
+ }
54666
+ /** Sole durable recovery surface for one readiness request. */
54667
+ async getBrowserAliasReadinessCheck(orgId, aliasId, checkId) {
54668
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_READINESS_CHECK(orgId, aliasId, checkId));
54669
+ }
54670
+ /** Organization Owner view. Hashes, reviewed snapshots and deltas are
54671
+ * intentionally available only on this human-JWT management surface. */
54672
+ async listBrowserAliasGrants(orgId, keyId) {
54673
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANTS(orgId, keyId));
54674
+ }
54675
+ async getBrowserAliasGrant(orgId, keyId, aliasId) {
54676
+ return this.request("GET", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId));
54677
+ }
54678
+ async replaceBrowserAliasGrant(orgId, keyId, aliasId, request3) {
54679
+ return this.request("PUT", ENDPOINTS.ORG_API_KEY_BROWSER_ALIAS_GRANT(orgId, keyId, aliasId), request3);
54680
+ }
54681
+ /** Managed-key discovery. The response is already grant-filtered and never
54682
+ * carries contract hashes, review snapshots, Edge IDs or Profile IDs. */
54683
+ async listManagedBrowserAliases(orgId) {
54684
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIASES(orgId));
54685
+ }
54686
+ async getManagedBrowserAlias(orgId, aliasName) {
54687
+ return this.request("GET", ENDPOINTS.ORG_MANAGED_ALIAS(orgId, aliasName));
54688
+ }
54689
+ /** Accept and dispatch one @alias command. request_id is generated by the
54690
+ * caller before local validation and is also the sole durable recovery key. */
54691
+ async createBrowserAliasExecution(orgId, request3) {
54692
+ return this.request("POST", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTIONS(orgId), request3);
54693
+ }
54694
+ async getBrowserAliasExecution(orgId, requestId) {
54695
+ return this.request("GET", ENDPOINTS.ORG_BROWSER_ALIAS_EXECUTION(orgId, requestId));
54696
+ }
54522
54697
  /**
54523
54698
  * Read a hosted Cloud Profile's egress-proxy status (manager-only: hosted
54524
54699
  * human maintainer or org admin). Sanitized — the password never comes back.
@@ -59305,7 +59480,10 @@ var ParallAgentGateway = class {
59305
59480
  this.opts.log?.info(`approval decided: ${approval.id} (${approval.status})`);
59306
59481
  const statusLabel = approval.status === "approved" ? "Approved" : "Rejected";
59307
59482
  const execInfo = approval.execution_status ? ` | execution: ${approval.execution_status}` : "";
59308
- const body = `${statusLabel}: ${approval.title}${execInfo}`;
59483
+ const reasonLine = formatApprovalDecisionReason(approval.status, approval.decision_reason);
59484
+ const reasonInfo = reasonLine ? `
59485
+ ${reasonLine}` : "";
59486
+ const body = `${statusLabel}: ${approval.title}${execInfo}${reasonInfo}`;
59309
59487
  const event = {
59310
59488
  type: "approval",
59311
59489
  targetId: chatId ?? approval.chat_id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/parall",
3
- "version": "1.55.4",
3
+ "version": "1.55.5",
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.4",
20
- "@parall/sdk": "1.55.4"
19
+ "@parall/agent-core": "1.55.5",
20
+ "@parall/sdk": "1.55.5"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/node": "^22.0.0",